From 9befc7662c73c9a8f1608aef796b8ccb477526d3 Mon Sep 17 00:00:00 2001 From: =?utf8?q?IOhannes=20m=20zm=C3=B6lnig?= Date: Wed, 13 Jan 2021 10:22:02 +0100 Subject: [PATCH] New upstream version 6.0.5~ds0 --- BREAKING-CHANGES.txt | 257 +- CMakeLists.txt | 138 + ChangeList.txt | 67 + LICENSE.md | 45 +- README.md | 52 +- docs/CMake API.md | 689 + .../JUCE Module Format.md | 198 +- docs/README.md | 34 + {doxygen => docs/doxygen}/Doxyfile | 40 +- {doxygen => docs/doxygen}/Makefile | 4 +- docs/doxygen/make.bat | 2 + .../doxygen}/process_source_files.py | 0 doxygen/README.txt | 23 - doxygen/make.bat | 2 - examples/Assets/AudioLiveScrollingDisplay.h | 2 +- examples/Assets/Box2DTests/ApplyForce.h | 3 + examples/Assets/DSPDemos_Common.h | 6 +- examples/Assets/DemoUtilities.h | 21 +- examples/Assets/Impulse1.wav | Bin 90246 -> 0 bytes examples/Assets/Impulse2.wav | Bin 37902 -> 0 bytes examples/Assets/WavefrontObjParser.h | 2 +- examples/Assets/reverb_ir.wav | Bin 0 -> 648404 bytes examples/Audio/AudioAppDemo.h | 12 +- examples/Audio/AudioLatencyDemo.h | 2 +- examples/Audio/AudioPlaybackDemo.h | 8 +- examples/Audio/AudioRecordingDemo.h | 4 +- examples/Audio/AudioSettingsDemo.h | 2 +- examples/Audio/AudioSynthesiserDemo.h | 4 +- examples/Audio/CMakeLists.txt | 24 + examples/Audio/MPEDemo.h | 18 +- examples/Audio/MidiDemo.h | 6 +- examples/Audio/PluckedStringsDemo.h | 10 +- examples/Audio/SimpleFFTDemo.h | 4 +- examples/BLOCKS/BlocksDrawingDemo.h | 10 +- examples/BLOCKS/BlocksMonitorDemo.h | 103 +- examples/BLOCKS/BlocksSynthDemo.h | 16 +- examples/BLOCKS/CMakeLists.txt | 24 + examples/CMake/AudioPlugin/CMakeLists.txt | 110 + examples/CMake/AudioPlugin/PluginEditor.cpp | 33 + examples/CMake/AudioPlugin/PluginEditor.h | 22 + .../CMake/AudioPlugin/PluginProcessor.cpp | 186 + examples/CMake/AudioPlugin/PluginProcessor.h | 48 + examples/CMake/CMakeLists.txt | 26 + examples/CMake/ConsoleApp/CMakeLists.txt | 88 + examples/CMake/ConsoleApp/Main.cpp | 10 + examples/CMake/GuiApp/CMakeLists.txt | 102 + .../CMake/GuiApp/Main.cpp | 48 +- examples/CMake/GuiApp/MainComponent.cpp | 25 + examples/CMake/GuiApp/MainComponent.h | 29 + examples/CMakeLists.txt | 58 + examples/DSP/CMakeLists.txt | 24 + examples/DSP/ConvolutionDemo.h | 109 +- examples/DSP/FIRFilterDemo.h | 2 +- examples/DSP/GainDemo.h | 2 +- examples/DSP/IIRFilterDemo.h | 2 +- examples/DSP/OscillatorDemo.h | 2 +- examples/DSP/OverdriveDemo.h | 2 +- examples/DSP/SIMDRegisterDemo.h | 2 +- examples/DSP/StateVariableFilterDemo.h | 23 +- examples/DSP/WaveShaperTanhDemo.h | 2 +- .../Builds/Android/app/CMakeLists.txt | 655 +- .../Builds/Android/app/build.gradle | 17 +- .../Android/app/src/main/AndroidManifest.xml | 17 +- .../main/assets/AudioLiveScrollingDisplay.h | 2 +- .../src/main/assets/Box2DTests/ApplyForce.h | 3 + .../app/src/main/assets/DSPDemos_Common.h | 6 +- .../app/src/main/assets/DemoUtilities.h | 21 +- .../Android/app/src/main/assets/Impulse1.wav | Bin 90246 -> 0 bytes .../Android/app/src/main/assets/Impulse2.wav | Bin 37902 -> 0 bytes .../app/src/main/assets/WavefrontObjParser.h | 2 +- .../Android/app/src/main/assets/reverb_ir.wav | Bin 0 -> 648404 bytes .../app/src/main/res/drawable-hdpi/icon.png | Bin 34761 -> 40234 bytes .../app/src/main/res/drawable-ldpi/icon.png | Bin 15111 -> 19490 bytes .../app/src/main/res/drawable-mdpi/icon.png | Bin 18428 -> 21536 bytes .../app/src/main/res/drawable-xhdpi/icon.png | Bin 44823 -> 43286 bytes .../DemoRunner/Builds/Android/build.gradle | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../DemoRunner/Builds/LinuxMakefile/Makefile | 14 +- .../DemoRunner/Builds/MacOSX/App.entitlements | 6 - .../DemoRunner.xcodeproj/project.pbxproj | 117 +- .../xcshareddata/WorkspaceSettings.xcsettings | 2 + examples/DemoRunner/Builds/MacOSX/Icon.icns | Bin 89670 -> 86596 bytes .../DemoRunner/Builds/MacOSX/Info-App.plist | 8 +- .../VisualStudio2015/DemoRunner_App.vcxproj | 473 +- .../DemoRunner_App.vcxproj.filters | 836 +- .../Builds/VisualStudio2015/icon.ico | Bin 33530 -> 36638 bytes .../Builds/VisualStudio2015/resources.rc | 12 +- .../VisualStudio2017/DemoRunner_App.vcxproj | 473 +- .../DemoRunner_App.vcxproj.filters | 836 +- .../Builds/VisualStudio2017/icon.ico | Bin 33530 -> 36638 bytes .../Builds/VisualStudio2017/resources.rc | 12 +- .../VisualStudio2019/DemoRunner_App.vcxproj | 473 +- .../DemoRunner_App.vcxproj.filters | 836 +- .../Builds/VisualStudio2019/icon.ico | Bin 33530 -> 36638 bytes .../Builds/VisualStudio2019/resources.rc | 12 +- .../iOS/DemoRunner.xcodeproj/project.pbxproj | 143 +- .../xcshareddata/WorkspaceSettings.xcsettings | 2 + .../AppIcon.appiconset/Icon-29.png | Bin 1650 -> 1984 bytes .../AppIcon.appiconset/Icon-29@2x.png | Bin 4395 -> 5386 bytes .../AppIcon.appiconset/Icon-29@3x.png | Bin 6732 -> 7835 bytes .../AppIcon.appiconset/Icon-60@2x.png | Bin 10478 -> 13588 bytes .../AppIcon.appiconset/Icon-72.png | Bin 4708 -> 5792 bytes .../AppIcon.appiconset/Icon-72@2x.png | Bin 9823 -> 12292 bytes .../AppIcon.appiconset/Icon-76.png | Bin 5368 -> 6314 bytes .../AppIcon.appiconset/Icon-76@2x.png | Bin 10888 -> 13724 bytes .../AppIcon.appiconset/Icon-83.5@2x.png | Bin 12870 -> 15722 bytes .../AppIcon.appiconset/Icon-@3x.png | Bin 14731 -> 17617 bytes .../AppIcon.appiconset/Icon-AppStore-1024.png | Bin 49618 -> 49797 bytes .../Icon-Notification-20@2x.png | Bin 2303 -> 2931 bytes .../Icon-Notification-20@3x.png | Bin 4687 -> 5643 bytes .../Icon-Notifications-20.png | Bin 912 -> 1111 bytes .../Icon-Notifications-20@2x.png | Bin 2303 -> 2931 bytes .../AppIcon.appiconset/Icon-Small-1.png | Bin 1650 -> 1984 bytes .../AppIcon.appiconset/Icon-Small-50.png | Bin 3433 -> 4143 bytes .../AppIcon.appiconset/Icon-Small-50@2x.png | Bin 8292 -> 9998 bytes .../AppIcon.appiconset/Icon-Small@2x-1.png | Bin 4395 -> 5386 bytes .../AppIcon.appiconset/Icon-Spotlight-40.png | Bin 2303 -> 2931 bytes .../Icon-Spotlight-40@2x-1.png | Bin 5235 -> 6745 bytes .../Icon-Spotlight-40@2x.png | Bin 5235 -> 6745 bytes .../Icon-Spotlight-40@3x.png | Bin 10478 -> 13588 bytes .../AppIcon.appiconset/Icon.png | Bin 4180 -> 5315 bytes .../AppIcon.appiconset/Icon@2x.png | Bin 9928 -> 12343 bytes examples/DemoRunner/Builds/iOS/Icon.icns | Bin 89670 -> 86596 bytes examples/DemoRunner/Builds/iOS/Info-App.plist | 8 +- examples/DemoRunner/CMakeLists.txt | 71 + examples/DemoRunner/DemoRunner.jucer | 13 +- .../DemoRunner/JuceLibraryCode/AppConfig.h | 324 - .../DemoRunner/JuceLibraryCode/JuceHeader.h | 7 +- .../include_juce_analytics.cpp | 1 - .../include_juce_audio_basics.cpp | 1 - .../include_juce_audio_basics.mm | 1 - .../include_juce_audio_devices.cpp | 1 - .../include_juce_audio_devices.mm | 1 - .../include_juce_audio_formats.cpp | 1 - .../include_juce_audio_formats.mm | 1 - .../include_juce_audio_processors.cpp | 1 - .../include_juce_audio_processors.mm | 1 - .../include_juce_audio_utils.cpp | 1 - .../include_juce_audio_utils.mm | 1 - .../include_juce_blocks_basics.cpp | 1 - .../JuceLibraryCode/include_juce_box2d.cpp | 1 - .../JuceLibraryCode/include_juce_core.cpp | 1 - .../JuceLibraryCode/include_juce_core.mm | 1 - .../include_juce_cryptography.cpp | 1 - .../include_juce_cryptography.mm | 1 - .../include_juce_data_structures.cpp | 1 - .../include_juce_data_structures.mm | 1 - .../JuceLibraryCode/include_juce_dsp.cpp | 1 - .../JuceLibraryCode/include_juce_dsp.mm | 1 - .../JuceLibraryCode/include_juce_events.cpp | 1 - .../JuceLibraryCode/include_juce_events.mm | 1 - .../JuceLibraryCode/include_juce_graphics.cpp | 1 - .../JuceLibraryCode/include_juce_graphics.mm | 1 - .../include_juce_gui_basics.cpp | 1 - .../include_juce_gui_basics.mm | 1 - .../include_juce_gui_extra.cpp | 1 - .../JuceLibraryCode/include_juce_gui_extra.mm | 1 - .../JuceLibraryCode/include_juce_opengl.cpp | 1 - .../JuceLibraryCode/include_juce_opengl.mm | 1 - .../JuceLibraryCode/include_juce_osc.cpp | 1 - .../include_juce_product_unlocking.cpp | 1 - .../include_juce_product_unlocking.mm | 1 - .../JuceLibraryCode/include_juce_video.cpp | 1 - .../JuceLibraryCode/include_juce_video.mm | 1 - .../DemoRunner/Source/Demos/DemoPIPs1.cpp | 48 +- .../DemoRunner/Source/Demos/DemoPIPs2.cpp | 17 +- .../DemoRunner/Source/Demos/IntroScreen.h | 19 +- .../DemoRunner/Source/Demos/JUCEDemos.cpp | 15 +- examples/DemoRunner/Source/Demos/JUCEDemos.h | 14 +- examples/DemoRunner/Source/JUCEAppIcon.png | Bin 45854 -> 42953 bytes examples/DemoRunner/Source/Main.cpp | 19 +- .../Source/UI/DemoContentComponent.cpp | 13 +- .../Source/UI/DemoContentComponent.h | 15 +- .../DemoRunner/Source/UI/MainComponent.cpp | 13 +- examples/DemoRunner/Source/UI/MainComponent.h | 11 +- .../DemoRunner/Source/UI/SettingsContent.h | 15 +- examples/GUI/AnimationAppDemo.h | 10 +- examples/GUI/AnimationDemo.h | 12 +- examples/GUI/BouncingBallWavetableDemo.h | 12 +- examples/GUI/CMakeLists.txt | 24 + examples/GUI/CameraDemo.h | 6 +- examples/GUI/CodeEditorDemo.h | 2 +- examples/GUI/ComponentDemo.h | 2 +- examples/GUI/ComponentTransformsDemo.h | 2 +- examples/GUI/DialogsDemo.h | 22 +- examples/GUI/FlexBoxDemo.h | 9 +- examples/GUI/FontsDemo.h | 129 +- examples/GUI/GraphicsDemo.h | 46 +- examples/GUI/GridDemo.h | 2 +- examples/GUI/HelloWorldDemo.h | 2 +- examples/GUI/ImagesDemo.h | 2 +- examples/GUI/KeyMappingsDemo.h | 2 +- examples/GUI/LookAndFeelDemo.h | 48 +- examples/GUI/MDIDemo.h | 2 +- examples/GUI/MenusDemo.h | 4 +- examples/GUI/MultiTouchDemo.h | 2 +- examples/GUI/OpenGLAppDemo.h | 6 +- examples/GUI/OpenGLDemo.h | 21 +- examples/GUI/OpenGLDemo2D.h | 2 +- examples/GUI/PropertiesDemo.h | 2 +- examples/GUI/VideoDemo.h | 2 +- examples/GUI/WebBrowserDemo.h | 2 +- examples/GUI/WidgetsDemo.h | 179 +- examples/GUI/WindowsDemo.h | 16 +- examples/Plugins/AUv3SynthPluginDemo.h | 69 +- examples/Plugins/ArpeggiatorPluginDemo.h | 44 +- examples/Plugins/AudioPluginDemo.h | 123 +- examples/Plugins/CMakeLists.txt | 24 + examples/Plugins/DSPModulePluginDemo.h | 2172 ++- examples/Plugins/GainPluginDemo.h | 9 +- .../Plugins/InterAppAudioEffectPluginDemo.h | 81 +- examples/Plugins/MidiLoggerPluginDemo.h | 345 + examples/Plugins/MultiOutSynthPluginDemo.h | 51 +- examples/Plugins/NoiseGatePluginDemo.h | 6 +- examples/Plugins/SamplerPluginDemo.h | 632 +- examples/Plugins/SurroundPluginDemo.h | 4 +- examples/Utilities/AnalyticsCollectionDemo.h | 2 +- examples/Utilities/Box2DDemo.h | 8 +- examples/Utilities/CMakeLists.txt | 24 + examples/Utilities/ChildProcessDemo.h | 2 +- examples/Utilities/CryptographyDemo.h | 2 +- examples/Utilities/InAppPurchasesDemo.h | 24 +- examples/Utilities/JavaScriptDemo.h | 2 +- examples/Utilities/LiveConstantDemo.h | 2 +- examples/Utilities/MultithreadingDemo.h | 6 +- examples/Utilities/NetworkingDemo.h | 2 +- examples/Utilities/OSCDemo.h | 2 +- examples/Utilities/PushNotificationsDemo.h | 11 +- examples/Utilities/SystemInfoDemo.h | 3 +- examples/Utilities/TimersAndEventsDemo.h | 2 +- examples/Utilities/UnitTestsDemo.h | 2 +- examples/Utilities/ValueTreesDemo.h | 2 +- examples/Utilities/XMLandJSONDemo.h | 6 +- .../AudioPerformanceTest.jucer | 11 +- .../Builds/Android/app/CMakeLists.txt | 571 +- .../Builds/Android/app/build.gradle | 9 +- .../Android/app/src/main/AndroidManifest.xml | 9 +- .../vending/billing/IInAppBillingService.java | 971 -- .../AudioPerformanceTest.java | 3166 ---- .../SharingContentProvider.java | 138 - .../Builds/Android/build.gradle | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../Builds/LinuxMakefile/Makefile | 14 +- .../Builds/MacOSX/App.entitlements | 6 - .../project.pbxproj | 75 +- .../xcshareddata/WorkspaceSettings.xcsettings | 2 + .../Builds/MacOSX/Info-App.plist | 2 +- .../AudioPerformanceTest_App.vcxproj | 401 +- .../AudioPerformanceTest_App.vcxproj.filters | 729 +- .../Builds/VisualStudio2019/resources.rc | 6 +- .../Builds/iOS/App.entitlements | 6 - .../project.pbxproj | 101 +- .../xcshareddata/WorkspaceSettings.xcsettings | 2 + .../Builds/iOS/Info-App.plist | 2 +- extras/AudioPerformanceTest/CMakeLists.txt | 38 + .../JuceLibraryCode/AppConfig.h | 281 - .../JuceLibraryCode/JuceHeader.h | 3 +- .../include_juce_audio_basics.cpp | 1 - .../include_juce_audio_basics.mm | 1 - .../include_juce_audio_devices.cpp | 1 - .../include_juce_audio_devices.mm | 1 - .../include_juce_audio_formats.cpp | 1 - .../include_juce_audio_formats.mm | 1 - .../include_juce_audio_processors.cpp | 1 - .../include_juce_audio_processors.mm | 1 - .../include_juce_audio_utils.cpp | 1 - .../include_juce_audio_utils.mm | 1 - .../JuceLibraryCode/include_juce_core.cpp | 1 - .../JuceLibraryCode/include_juce_core.mm | 1 - .../include_juce_data_structures.cpp | 1 - .../include_juce_data_structures.mm | 1 - .../JuceLibraryCode/include_juce_events.cpp | 1 - .../JuceLibraryCode/include_juce_events.mm | 1 - .../JuceLibraryCode/include_juce_graphics.cpp | 1 - .../JuceLibraryCode/include_juce_graphics.mm | 1 - .../include_juce_gui_basics.cpp | 1 - .../include_juce_gui_basics.mm | 1 - .../include_juce_gui_extra.cpp | 1 - .../JuceLibraryCode/include_juce_gui_extra.mm | 1 - extras/AudioPerformanceTest/Source/Main.cpp | 18 +- .../Source/MainComponent.h | 19 +- extras/AudioPluginHost/AudioPluginHost.jucer | 41 +- .../Builds/Android/app/CMakeLists.txt | 777 +- .../Builds/Android/app/build.gradle | 15 +- .../Android/app/src/main/AndroidManifest.xml | 11 +- .../app/src/main/res/drawable-hdpi/icon.png | Bin 34761 -> 45427 bytes .../app/src/main/res/drawable-ldpi/icon.png | Bin 15111 -> 22104 bytes .../app/src/main/res/drawable-mdpi/icon.png | Bin 18428 -> 23363 bytes .../app/src/main/res/drawable-xhdpi/icon.png | Bin 44823 -> 47612 bytes .../Builds/Android/build.gradle | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../Builds/LinuxMakefile/Makefile | 26 +- .../Builds/MacOSX/App.entitlements | 6 - .../AudioPluginHost.xcodeproj/project.pbxproj | 199 +- .../xcshareddata/WorkspaceSettings.xcsettings | 2 + .../AudioPluginHost/Builds/MacOSX/Icon.icns | Bin 89670 -> 95248 bytes .../Builds/MacOSX/Info-App.plist | 6 +- .../AudioPluginHost_App.vcxproj | 577 +- .../AudioPluginHost_App.vcxproj.filters | 1065 +- .../Builds/VisualStudio2015/icon.ico | Bin 33530 -> 38465 bytes .../Builds/VisualStudio2015/resources.rc | 6 +- .../AudioPluginHost_App.vcxproj | 577 +- .../AudioPluginHost_App.vcxproj.filters | 1065 +- .../Builds/VisualStudio2017/icon.ico | Bin 33530 -> 38465 bytes .../Builds/VisualStudio2017/resources.rc | 6 +- .../AudioPluginHost_App.vcxproj | 577 +- .../AudioPluginHost_App.vcxproj.filters | 1065 +- .../Builds/VisualStudio2019/icon.ico | Bin 33530 -> 38465 bytes .../Builds/VisualStudio2019/resources.rc | 6 +- .../Builds/iOS/App.entitlements | 6 - .../AudioPluginHost.xcodeproj/project.pbxproj | 214 +- .../xcshareddata/WorkspaceSettings.xcsettings | 2 + .../AppIcon.appiconset/Icon-29.png | Bin 1650 -> 2143 bytes .../AppIcon.appiconset/Icon-29@2x.png | Bin 4395 -> 6043 bytes .../AppIcon.appiconset/Icon-29@3x.png | Bin 6732 -> 9140 bytes .../AppIcon.appiconset/Icon-60@2x.png | Bin 10478 -> 15603 bytes .../AppIcon.appiconset/Icon-72.png | Bin 4708 -> 6689 bytes .../AppIcon.appiconset/Icon-72@2x.png | Bin 9823 -> 14216 bytes .../AppIcon.appiconset/Icon-76.png | Bin 5368 -> 7327 bytes .../AppIcon.appiconset/Icon-76@2x.png | Bin 10888 -> 15931 bytes .../AppIcon.appiconset/Icon-83.5@2x.png | Bin 12870 -> 18225 bytes .../AppIcon.appiconset/Icon-@3x.png | Bin 14731 -> 20798 bytes .../AppIcon.appiconset/Icon-AppStore-1024.png | Bin 49618 -> 54232 bytes .../Icon-Notification-20@2x.png | Bin 2303 -> 3232 bytes .../Icon-Notification-20@3x.png | Bin 4687 -> 6366 bytes .../Icon-Notifications-20.png | Bin 912 -> 1189 bytes .../Icon-Notifications-20@2x.png | Bin 2303 -> 3232 bytes .../AppIcon.appiconset/Icon-Small-1.png | Bin 1650 -> 2143 bytes .../AppIcon.appiconset/Icon-Small-50.png | Bin 3433 -> 4691 bytes .../AppIcon.appiconset/Icon-Small-50@2x.png | Bin 8292 -> 11577 bytes .../AppIcon.appiconset/Icon-Small@2x-1.png | Bin 4395 -> 6043 bytes .../AppIcon.appiconset/Icon-Spotlight-40.png | Bin 2303 -> 3232 bytes .../Icon-Spotlight-40@2x-1.png | Bin 5235 -> 7785 bytes .../Icon-Spotlight-40@2x.png | Bin 5235 -> 7785 bytes .../Icon-Spotlight-40@3x.png | Bin 10478 -> 15603 bytes .../AppIcon.appiconset/Icon.png | Bin 4180 -> 5972 bytes .../AppIcon.appiconset/Icon@2x.png | Bin 9928 -> 14348 bytes extras/AudioPluginHost/Builds/iOS/Icon.icns | Bin 89670 -> 95248 bytes .../AudioPluginHost/Builds/iOS/Info-App.plist | 10 +- extras/AudioPluginHost/CMakeLists.txt | 65 + .../JuceLibraryCode/AppConfig.h | 297 - .../JuceLibraryCode/BinaryData.cpp | 1315 +- .../JuceLibraryCode/BinaryData.h | 2 +- .../JuceLibraryCode/JuceHeader.h | 5 +- .../include_juce_audio_basics.cpp | 1 - .../include_juce_audio_basics.mm | 1 - .../include_juce_audio_devices.cpp | 1 - .../include_juce_audio_devices.mm | 1 - .../include_juce_audio_formats.cpp | 1 - .../include_juce_audio_formats.mm | 1 - .../include_juce_audio_processors.cpp | 1 - .../include_juce_audio_processors.mm | 1 - .../include_juce_audio_utils.cpp | 1 - .../include_juce_audio_utils.mm | 1 - .../JuceLibraryCode/include_juce_core.cpp | 1 - .../JuceLibraryCode/include_juce_core.mm | 1 - .../include_juce_cryptography.cpp | 1 - .../include_juce_cryptography.mm | 1 - .../include_juce_data_structures.cpp | 1 - .../include_juce_data_structures.mm | 1 - ...ude_juce_video.mm => include_juce_dsp.cpp} | 3 +- ...ude_juce_video.cpp => include_juce_dsp.mm} | 3 +- .../JuceLibraryCode/include_juce_events.cpp | 1 - .../JuceLibraryCode/include_juce_events.mm | 1 - .../JuceLibraryCode/include_juce_graphics.cpp | 1 - .../JuceLibraryCode/include_juce_graphics.mm | 1 - .../include_juce_gui_basics.cpp | 1 - .../include_juce_gui_basics.mm | 1 - .../include_juce_gui_extra.cpp | 1 - .../JuceLibraryCode/include_juce_gui_extra.mm | 1 - .../JuceLibraryCode/include_juce_opengl.cpp | 1 - .../JuceLibraryCode/include_juce_opengl.mm | 1 - extras/AudioPluginHost/Source/HostStartup.cpp | 17 +- extras/AudioPluginHost/Source/JUCEAppIcon.png | Bin 45854 -> 47266 bytes .../Source/Plugins/IOConfigurationWindow.cpp | 11 +- .../Source/Plugins/IOConfigurationWindow.h | 11 +- .../Source/Plugins/InternalPlugins.cpp | 290 +- .../Source/Plugins/InternalPlugins.h | 36 +- .../Source/Plugins/PluginGraph.cpp | 23 +- .../Source/Plugins/PluginGraph.h | 11 +- .../Source/UI/GraphEditorPanel.cpp | 34 +- .../Source/UI/GraphEditorPanel.h | 11 +- .../Source/UI/MainHostWindow.cpp | 27 +- .../Source/UI/MainHostWindow.h | 13 +- .../AudioPluginHost/Source/UI/PluginWindow.h | 16 +- .../examples/BlockFinder/BlockFinder.cpp | 2 +- .../examples/BlockFinder/BlockFinder.h | 2 +- .../examples/BlockFinder/Linux/main.cpp | 2 +- .../examples/BlockFinder/MacOS/main.mm | 2 +- .../examples/BlockFinder/Windows/main.cpp | 2 +- extras/BinaryBuilder/BinaryBuilder.jucer | 12 +- .../Builds/LinuxMakefile/Makefile | 12 +- .../BinaryBuilder.xcodeproj/project.pbxproj | 59 +- .../xcshareddata/WorkspaceSettings.xcsettings | 2 + .../Builds/MacOSX/ConsoleApp.entitlements | 6 - .../BinaryBuilder_ConsoleApp.vcxproj | 19 +- .../BinaryBuilder_ConsoleApp.vcxproj.filters | 18 +- .../Builds/VisualStudio2019/resources.rc | 6 +- extras/BinaryBuilder/CMakeLists.txt | 36 + .../BinaryBuilder/JuceLibraryCode/AppConfig.h | 107 - .../JuceLibraryCode/JuceHeader.h | 3 +- .../JuceLibraryCode/include_juce_core.cpp | 1 - .../JuceLibraryCode/include_juce_core.mm | 1 - extras/BinaryBuilder/Source/Main.cpp | 11 +- extras/Build/CMake/JUCECheckAtomic.cmake | 83 + extras/Build/CMake/JUCEConfig.cmake.in | 90 + extras/Build/CMake/JUCEHelperTargets.cmake | 62 + extras/Build/CMake/JUCEUtils.cmake | 2296 +++ extras/Build/CMake/LaunchScreen.storyboard | 16 + extras/Build/CMake/PIPAudioProcessor.cpp.in | 16 + extras/Build/CMake/PIPComponent.cpp.in | 68 + extras/Build/CMake/PIPConsole.cpp.in | 10 + .../CMake}/RecentFilesMenuTemplate.nib | Bin .../CMake/UnityPluginGUIScript.cs.in} | 32 +- extras/Build/CMake/copyDir.cmake | 24 + .../CMake/juce_runtime_arch_detection.cpp | 57 + extras/Build/CMakeLists.txt | 27 + .../juce_build_tools/juce_build_tools.cpp | 47 + .../Build/juce_build_tools/juce_build_tools.h | 67 + .../utils/juce_BinaryResourceFile.cpp | 287 + .../utils/juce_BinaryResourceFile.h | 74 + .../utils/juce_BuildHelperFunctions.cpp | 351 + .../utils/juce_BuildHelperFunctions.h | 86 + .../utils/juce_CppTokeniserFunctions.cpp | 206 + .../utils/juce_Entitlements.cpp | 116 + .../utils/juce_Entitlements.h | 55 + .../juce_build_tools/utils/juce_Icons.cpp | 505 + .../Build/juce_build_tools/utils/juce_Icons.h | 49 + .../utils/juce_PlistOptions.cpp | 352 + .../utils/juce_PlistOptions.h | 103 + .../juce_build_tools/utils/juce_ProjectType.h | 275 + .../utils/juce_RelativePath.h | 129 + .../utils/juce_ResourceFileHelpers.cpp | 91 + .../utils/juce_ResourceFileHelpers.h | 38 + .../utils/juce_ResourceRc.cpp | 97 + .../juce_build_tools/utils/juce_ResourceRc.h | 43 + .../utils/juce_VersionNumbers.cpp | 57 + .../utils/juce_VersionNumbers.h} | 22 +- extras/Build/juceaide/CMakeLists.txt | 107 + extras/Build/juceaide/Main.cpp | 512 + extras/CMakeLists.txt | 30 + .../Builds/Android/app/CMakeLists.txt | 571 +- .../Builds/Android/app/build.gradle | 9 +- .../Android/app/src/main/AndroidManifest.xml | 9 +- .../vending/billing/IInAppBillingService.java | 971 -- .../JUCENetworkGraphicsDemo.java | 1889 --- .../SharingContentProvider.java | 129 - .../Builds/Android/build.gradle | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../Builds/LinuxMakefile/Makefile | 14 +- .../Builds/MacOSX/App.entitlements | 6 - .../Builds/MacOSX/Info-App.plist | 2 +- .../project.pbxproj | 81 +- .../xcshareddata/WorkspaceSettings.xcsettings | 2 + .../NetworkGraphicsDemo_App.vcxproj | 401 +- .../NetworkGraphicsDemo_App.vcxproj.filters | 729 +- .../Builds/VisualStudio2019/resources.rc | 6 +- .../Builds/iOS/App.entitlements | 6 - .../Builds/iOS/Info-App.plist | 2 +- .../project.pbxproj | 107 +- .../xcshareddata/WorkspaceSettings.xcsettings | 2 + extras/NetworkGraphicsDemo/CMakeLists.txt | 40 + .../JuceLibraryCode/AppConfig.h | 284 - .../JuceLibraryCode/JuceHeader.h | 3 +- .../include_juce_audio_basics.cpp | 1 - .../include_juce_audio_basics.mm | 1 - .../include_juce_audio_devices.cpp | 1 - .../include_juce_audio_devices.mm | 1 - .../include_juce_audio_formats.cpp | 1 - .../include_juce_audio_formats.mm | 1 - .../include_juce_audio_processors.cpp | 1 - .../include_juce_audio_processors.mm | 1 - .../include_juce_audio_utils.cpp | 1 - .../include_juce_audio_utils.mm | 1 - .../JuceLibraryCode/include_juce_core.cpp | 1 - .../JuceLibraryCode/include_juce_core.mm | 1 - .../include_juce_cryptography.cpp | 1 - .../include_juce_cryptography.mm | 1 - .../include_juce_data_structures.cpp | 1 - .../include_juce_data_structures.mm | 1 - .../JuceLibraryCode/include_juce_events.cpp | 1 - .../JuceLibraryCode/include_juce_events.mm | 1 - .../JuceLibraryCode/include_juce_graphics.cpp | 1 - .../JuceLibraryCode/include_juce_graphics.mm | 1 - .../include_juce_gui_basics.cpp | 1 - .../include_juce_gui_basics.mm | 1 - .../include_juce_gui_extra.cpp | 1 - .../JuceLibraryCode/include_juce_gui_extra.mm | 1 - .../JuceLibraryCode/include_juce_opengl.cpp | 1 - .../JuceLibraryCode/include_juce_opengl.mm | 1 - .../JuceLibraryCode/include_juce_osc.cpp | 1 - .../NetworkGraphicsDemo.jucer | 9 +- extras/NetworkGraphicsDemo/Source/Demos.h | 15 +- extras/NetworkGraphicsDemo/Source/Main.cpp | 17 +- .../Source/MasterComponent.h | 21 +- .../NetworkGraphicsDemo/Source/SharedCanvas.h | 25 +- .../Source/SlaveComponent.h | 29 +- extras/Projucer/Builds/LinuxMakefile/Makefile | 72 +- .../Projucer/Builds/MacOSX/App.entitlements | 6 - extras/Projucer/Builds/MacOSX/Icon.icns | Bin 44839 -> 89670 bytes extras/Projucer/Builds/MacOSX/Info-App.plist | 6 +- .../MacOSX/Projucer.xcodeproj/project.pbxproj | 712 +- .../xcshareddata/WorkspaceSettings.xcsettings | 2 + .../VisualStudio2015/Projucer_App.vcxproj | 157 +- .../Projucer_App.vcxproj.filters | 320 +- .../Builds/VisualStudio2015/resources.rc | 12 +- .../VisualStudio2017/Projucer_App.vcxproj | 157 +- .../Projucer_App.vcxproj.filters | 320 +- .../Builds/VisualStudio2017/resources.rc | 12 +- .../VisualStudio2019/Projucer_App.vcxproj | 157 +- .../Projucer_App.vcxproj.filters | 320 +- .../Builds/VisualStudio2019/resources.rc | 12 +- extras/Projucer/CMakeLists.txt | 171 + extras/Projucer/JuceLibraryCode/AppConfig.h | 197 - .../Projucer/JuceLibraryCode/BinaryData.cpp | 13085 ++++++++-------- extras/Projucer/JuceLibraryCode/BinaryData.h | 96 +- extras/Projucer/JuceLibraryCode/JuceHeader.h | 9 +- ...ytics.cpp => include_juce_build_tools.cpp} | 3 +- .../JuceLibraryCode/include_juce_core.cpp | 1 - .../JuceLibraryCode/include_juce_core.mm | 1 - .../include_juce_cryptography.cpp | 1 - .../include_juce_cryptography.mm | 1 - .../include_juce_data_structures.cpp | 1 - .../include_juce_data_structures.mm | 1 - .../JuceLibraryCode/include_juce_events.cpp | 1 - .../JuceLibraryCode/include_juce_events.mm | 1 - .../JuceLibraryCode/include_juce_graphics.cpp | 1 - .../JuceLibraryCode/include_juce_graphics.mm | 1 - .../include_juce_gui_basics.cpp | 1 - .../include_juce_gui_basics.mm | 1 - .../include_juce_gui_extra.cpp | 1 - .../JuceLibraryCode/include_juce_gui_extra.mm | 1 - extras/Projucer/Projucer.jucer | 290 +- .../StartPage/jucer_ContentComponents.h | 312 + .../StartPage/jucer_NewProjectTemplates.h | 251 + .../StartPage/jucer_NewProjectWizard.cpp | 282 + .../StartPage/jucer_NewProjectWizard.h | 38 + .../StartPage/jucer_StartPageComponent.cpp | 272 + .../StartPage/jucer_StartPageComponent.h | 50 + .../StartPage/jucer_StartPageTreeHolder.h | 174 + .../UserAccount/jucer_LicenseController.h | 224 + .../UserAccount/jucer_LicenseQueryThread.h | 369 + .../UserAccount/jucer_LicenseState.h | 91 + .../UserAccount/jucer_LoginFormComponent.h | 278 + .../Windows/jucer_AboutWindowComponent.h | 55 +- ...ucer_ApplicationUsageDataWindowComponent.h | 164 - .../jucer_EditorColourSchemeWindowComponent.h | 11 +- .../Windows/jucer_FloatingToolWindow.h | 11 +- .../jucer_GlobalPathsWindowComponent.h | 62 +- .../Windows/jucer_PIPCreatorWindowComponent.h | 31 +- .../jucer_SVGPathDataWindowComponent.h | 13 +- .../jucer_TranslationToolWindowComponent.h | 11 +- .../Windows/jucer_UTF8WindowComponent.h | 11 +- .../Source/Application/jucer_Application.cpp | 650 +- .../Source/Application/jucer_Application.h | 210 +- .../Source/Application/jucer_AutoUpdater.cpp | 75 +- .../Source/Application/jucer_AutoUpdater.h | 18 +- .../Source/Application/jucer_CommandIDs.h | 19 +- .../Source/Application/jucer_CommandLine.cpp | 78 +- .../Source/Application/jucer_CommandLine.h | 11 +- .../Source/Application/jucer_CommonHeaders.h | 20 +- .../Source/Application/jucer_Headers.h | 11 +- .../Source/Application/jucer_Main.cpp | 13 +- .../Source/Application/jucer_MainWindow.cpp | 382 +- .../Source/Application/jucer_MainWindow.h | 45 +- .../Application/jucer_ProjucerAnalytics.cpp | 254 - .../Application/jucer_ProjucerAnalytics.h | 69 - .../Source/BinaryData/Icons/gpl_logo.svg | 23 + .../BinaryData/Icons/huckleberry_icon.svg | 50 - .../jucer_AnimatedComponentSimpleTemplate.h | 16 +- .../jucer_AnimatedComponentTemplate.cpp | 12 +- .../jucer_AnimatedComponentTemplate.h | 14 +- .../jucer_AudioComponentSimpleTemplate.h | 26 +- .../jucer_AudioComponentTemplate.cpp | 22 +- .../Templates/jucer_AudioComponentTemplate.h | 16 +- .../jucer_AudioPluginEditorTemplate.cpp | 14 +- .../jucer_AudioPluginEditorTemplate.h | 12 +- .../jucer_AudioPluginFilterTemplate.cpp | 30 +- .../jucer_AudioPluginFilterTemplate.h | 20 +- .../Templates/jucer_ComponentTemplate.cpp | 2 +- .../Templates/jucer_ComponentTemplate.h | 2 +- .../jucer_ContentCompSimpleTemplate.h | 22 +- .../Templates/jucer_ContentCompTemplate.cpp | 18 +- .../Templates/jucer_ContentCompTemplate.h | 14 +- .../Templates/jucer_InlineComponentTemplate.h | 14 +- .../jucer_MainConsoleAppTemplate.cpp | 4 +- .../Templates/jucer_MainTemplate_NoWindow.cpp | 16 +- .../Templates/jucer_MainTemplate_Window.cpp | 27 +- .../Templates/jucer_NewComponentTemplate.cpp | 10 +- .../Templates/jucer_NewComponentTemplate.h | 6 +- .../jucer_NewInlineComponentTemplate.h | 14 +- .../jucer_OpenGLComponentSimpleTemplate.h | 16 +- .../jucer_OpenGLComponentTemplate.cpp | 12 +- .../Templates/jucer_OpenGLComponentTemplate.h | 14 +- .../jucer_PIPAudioProcessorTemplate.h | 40 +- .../BinaryData/Templates/jucer_PIPMain.cpp | 77 - .../Source/BinaryData/nothingtoseehere.txt | 1 - .../Source/BinaryData/offlinepage.html | 42 - .../Source/BinaryData/projucer_EULA.txt | 142 - .../jucer_DocumentEditorComponent.cpp | 13 +- .../jucer_DocumentEditorComponent.h | 17 +- .../CodeEditor/jucer_ItemPreviewComponent.h | 13 +- .../CodeEditor/jucer_LiveBuildCodeEditor.h | 19 +- .../CodeEditor/jucer_OpenDocumentManager.cpp | 23 +- .../CodeEditor/jucer_OpenDocumentManager.h | 23 +- .../CodeEditor/jucer_SourceCodeEditor.cpp | 15 +- .../CodeEditor/jucer_SourceCodeEditor.h | 11 +- .../Components/jucer_ButtonHandler.h | 23 +- .../Components/jucer_ComboBoxHandler.h | 17 +- .../Components/jucer_ComponentNameProperty.h | 11 +- .../Components/jucer_ComponentTypeHandler.cpp | 15 +- .../Components/jucer_ComponentTypeHandler.h | 19 +- .../jucer_ComponentUndoableAction.h | 11 +- .../jucer_GenericComponentHandler.h | 17 +- .../Components/jucer_GroupComponentHandler.h | 29 +- .../Components/jucer_HyperlinkButtonHandler.h | 15 +- .../Components/jucer_ImageButtonHandler.h | 31 +- .../Components/jucer_JucerComponentHandler.h | 25 +- .../Components/jucer_LabelHandler.h | 89 +- .../Components/jucer_SliderHandler.h | 39 +- .../Components/jucer_TabbedComponentHandler.h | 51 +- .../Components/jucer_TextButtonHandler.h | 21 +- .../Components/jucer_TextEditorHandler.h | 25 +- .../Components/jucer_ToggleButtonHandler.h | 15 +- .../Components/jucer_TreeViewHandler.h | 19 +- .../Components/jucer_ViewportHandler.h | 36 +- .../Documents/jucer_ButtonDocument.cpp | 21 +- .../Documents/jucer_ButtonDocument.h | 11 +- .../Documents/jucer_ComponentDocument.cpp | 11 +- .../Documents/jucer_ComponentDocument.h | 11 +- .../PaintElements/jucer_ColouredElement.cpp | 19 +- .../PaintElements/jucer_ColouredElement.h | 11 +- .../jucer_ElementSiblingComponent.h | 19 +- .../PaintElements/jucer_FillType.h | 21 +- .../jucer_GradientPointComponent.h | 11 +- .../jucer_ImageResourceProperty.h | 13 +- .../PaintElements/jucer_PaintElement.cpp | 11 +- .../PaintElements/jucer_PaintElement.h | 30 +- .../PaintElements/jucer_PaintElementEllipse.h | 11 +- .../PaintElements/jucer_PaintElementGroup.cpp | 11 +- .../PaintElements/jucer_PaintElementGroup.h | 11 +- .../PaintElements/jucer_PaintElementImage.cpp | 35 +- .../PaintElements/jucer_PaintElementImage.h | 11 +- .../PaintElements/jucer_PaintElementPath.cpp | 43 +- .../PaintElements/jucer_PaintElementPath.h | 11 +- .../jucer_PaintElementRectangle.h | 11 +- .../jucer_PaintElementRoundedRectangle.h | 23 +- .../PaintElements/jucer_PaintElementText.h | 1345 +- .../jucer_PaintElementUndoableAction.h | 13 +- .../PaintElements/jucer_PointComponent.h | 15 +- .../PaintElements/jucer_StrokeType.h | 25 +- .../jucer_ColourPropertyComponent.h | 36 +- .../jucer_ComponentBooleanProperty.h | 11 +- .../jucer_ComponentChoiceProperty.h | 11 +- .../jucer_ComponentColourProperty.h | 11 +- .../Properties/jucer_ComponentTextProperty.h | 11 +- .../Properties/jucer_FilePropertyComponent.h | 19 +- .../Properties/jucer_FontPropertyComponent.h | 29 +- .../Properties/jucer_JustificationProperty.h | 11 +- .../Properties/jucer_PositionPropertyBase.h | 11 +- .../UI/jucer_ComponentLayoutEditor.cpp | 11 +- .../UI/jucer_ComponentLayoutEditor.h | 18 +- .../UI/jucer_ComponentLayoutPanel.h | 27 +- .../UI/jucer_ComponentOverlayComponent.cpp | 11 +- .../UI/jucer_ComponentOverlayComponent.h | 33 +- .../UI/jucer_EditingPanelBase.cpp | 15 +- .../UI/jucer_EditingPanelBase.h | 11 +- .../UI/jucer_JucerCommandIDs.h | 11 +- .../UI/jucer_JucerDocumentEditor.cpp | 51 +- .../UI/jucer_JucerDocumentEditor.h | 16 +- .../UI/jucer_PaintRoutineEditor.cpp | 11 +- .../UI/jucer_PaintRoutineEditor.h | 15 +- .../UI/jucer_PaintRoutinePanel.cpp | 27 +- .../UI/jucer_PaintRoutinePanel.h | 11 +- .../UI/jucer_RelativePositionedRectangle.h | 25 +- .../UI/jucer_ResourceEditorPanel.cpp | 13 +- .../UI/jucer_ResourceEditorPanel.h | 11 +- .../UI/jucer_SnapGridPainter.h | 11 +- .../UI/jucer_TestComponent.cpp | 11 +- .../ComponentEditor/UI/jucer_TestComponent.h | 11 +- .../ComponentEditor/jucer_BinaryResources.cpp | 15 +- .../ComponentEditor/jucer_BinaryResources.h | 11 +- .../ComponentEditor/jucer_ComponentLayout.cpp | 27 +- .../ComponentEditor/jucer_ComponentLayout.h | 11 +- .../ComponentEditor/jucer_GeneratedCode.cpp | 697 +- .../ComponentEditor/jucer_GeneratedCode.h | 11 +- .../ComponentEditor/jucer_JucerDocument.cpp | 109 +- .../ComponentEditor/jucer_JucerDocument.h | 11 +- .../ComponentEditor/jucer_ObjectTypes.cpp | 11 +- .../ComponentEditor/jucer_ObjectTypes.h | 11 +- .../ComponentEditor/jucer_PaintRoutine.cpp | 13 +- .../ComponentEditor/jucer_PaintRoutine.h | 11 +- .../ComponentEditor/jucer_UtilityFunctions.h | 11 +- .../Licenses/jucer_LicenseController.cpp | 54 +- .../Source/Licenses/jucer_LicenseController.h | 124 - .../Source/Licenses/jucer_LicenseThread.h | 466 - .../Source/Licenses/jucer_LicenseWebview.h | 283 - .../UI/jucer_ActivityListComponent.h | 13 +- .../UI/jucer_BuildTabStatusComponent.h | 11 +- .../UI/jucer_ComponentListComponent.h | 11 +- .../UI/jucer_ErrorListComponent.h | 11 +- .../LiveBuildEngine/jucer_ActivityList.h | 11 +- .../LiveBuildEngine/jucer_ClassDatabase.h | 17 +- .../jucer_ClientServerMessages.h | 16 +- .../jucer_CompileEngineClient.cpp | 74 +- .../jucer_CompileEngineClient.h | 11 +- .../LiveBuildEngine/jucer_CompileEngineDLL.h | 11 +- .../jucer_CompileEngineServer.cpp | 19 +- .../jucer_CompileEngineServer.h | 11 +- .../jucer_CompileEngineSettings.h | 11 +- .../Source/LiveBuildEngine/jucer_CppHelpers.h | 13 +- .../LiveBuildEngine/jucer_DiagnosticMessage.h | 12 +- .../jucer_DownloadCompileEngineThread.cpp | 11 +- .../jucer_DownloadCompileEngineThread.h | 11 +- .../Source/LiveBuildEngine/jucer_ErrorList.h | 11 +- .../jucer_LiveCodeBuilderDLL.h | 11 +- .../Source/LiveBuildEngine/jucer_MessageIDs.h | 18 +- .../LiveBuildEngine/jucer_ProjectBuildInfo.h | 11 +- .../LiveBuildEngine/jucer_SourceCodeRange.h | 11 +- .../Modules/jucer_AvailableModulesList.h | 207 + .../Project/Modules/jucer_ModuleDescription.h | 93 + .../jucer_Modules.cpp} | 385 +- .../jucer_Modules.h} | 112 +- .../UI/Sidebar/jucer_ExporterTreeItems.h | 26 +- .../Project/UI/Sidebar/jucer_FileTreeItems.h | 69 +- .../Project/UI/Sidebar/jucer_LiveBuildTab.h | 28 +- .../UI/Sidebar/jucer_ModuleTreeItems.h | 166 +- .../Project/UI/Sidebar/jucer_ProjectTab.h | 15 +- .../UI/Sidebar/jucer_ProjectTreeItemBase.h | 11 +- .../Project/UI/Sidebar/jucer_TabComponents.h | 25 +- .../Project/UI/Sidebar/jucer_TreeItemTypes.h | 13 +- .../Project/UI/jucer_ContentViewComponents.h | 25 +- .../UI/jucer_FileGroupInformationComponent.h | 54 +- .../Project/UI/jucer_HeaderComponent.cpp | 314 +- .../Source/Project/UI/jucer_HeaderComponent.h | 57 +- .../UI/jucer_ModulesInformationComponent.h | 36 +- .../UI/jucer_ProjectContentComponent.cpp | 362 +- .../UI/jucer_ProjectContentComponent.h | 93 +- .../UI/jucer_ProjectMessagesComponent.h | 555 + .../Project/UI/jucer_UserAvatarComponent.h | 157 + .../Projucer/Source/Project/jucer_Project.cpp | 1091 +- .../Projucer/Source/Project/jucer_Project.h | 264 +- .../Source/Project/jucer_ProjectType.h | 212 - .../jucer_ProjectExport_Android.h | 587 +- .../ProjectSaving/jucer_ProjectExport_CLion.h | 236 +- .../jucer_ProjectExport_CodeBlocks.h | 234 +- .../ProjectSaving/jucer_ProjectExport_MSVC.h | 804 +- .../ProjectSaving/jucer_ProjectExport_Make.h | 329 +- .../ProjectSaving/jucer_ProjectExport_Xcode.h | 1681 +- .../ProjectSaving/jucer_ProjectExporter.cpp | 588 +- .../ProjectSaving/jucer_ProjectExporter.h | 202 +- .../ProjectSaving/jucer_ProjectSaver.cpp | 839 +- .../Source/ProjectSaving/jucer_ProjectSaver.h | 802 +- .../ProjectSaving/jucer_ResourceFile.cpp | 274 +- .../Source/ProjectSaving/jucer_ResourceFile.h | 53 +- .../ProjectSaving/jucer_XcodeProjectParser.h | 15 +- .../Settings/jucer_AppearanceSettings.cpp | 11 +- .../Settings/jucer_AppearanceSettings.h | 11 +- .../Source/Settings/jucer_StoredSettings.cpp | 45 +- .../Source/Settings/jucer_StoredSettings.h | 17 +- .../Utility/Helpers/jucer_CodeHelpers.cpp | 248 +- .../Utility/Helpers/jucer_CodeHelpers.h | 20 +- .../Source/Utility/Helpers/jucer_Colours.h | 11 +- .../Utility/Helpers/jucer_FileHelpers.cpp | 113 +- .../Utility/Helpers/jucer_FileHelpers.h | 38 +- .../Utility/Helpers/jucer_MiscUtilities.cpp | 209 +- .../Utility/Helpers/jucer_MiscUtilities.h | 28 +- .../Helpers}/jucer_NewFileWizard.cpp | 43 +- .../Helpers}/jucer_NewFileWizard.h | 13 +- .../Source/Utility/Helpers/jucer_PresetIDs.h | 33 +- .../Utility/Helpers/jucer_RelativePath.h | 129 - .../Helpers/jucer_TranslationHelpers.h | 21 +- .../Helpers/jucer_ValueSourceHelpers.h | 11 +- .../Helpers/jucer_ValueWithDefaultWrapper.h | 73 + .../Utility/Helpers/jucer_VersionInfo.cpp | 26 +- .../Utility/Helpers/jucer_VersionInfo.h | 13 +- .../Utility/PIPs/jucer_PIPGenerator.cpp | 208 +- .../Source/Utility/PIPs/jucer_PIPGenerator.h | 27 +- .../jucer_ColourPropertyComponent.h | 31 +- .../jucer_FilePathPropertyComponent.h | 61 +- .../jucer_LabelPropertyComponent.h | 11 +- .../jucer_PropertyComponentsWithEnablement.h | 11 +- .../Source/Utility/UI/jucer_IconButton.h | 121 +- .../Source/Utility/UI/jucer_Icons.cpp | 34 +- .../Projucer/Source/Utility/UI/jucer_Icons.h | 27 +- .../Utility/UI/jucer_JucerTreeViewBase.cpp | 15 +- .../Utility/UI/jucer_JucerTreeViewBase.h | 13 +- .../Utility/UI/jucer_ProjucerLookAndFeel.cpp | 56 +- .../Utility/UI/jucer_ProjucerLookAndFeel.h | 11 +- .../UI/jucer_SlidingPanelComponent.cpp | 11 +- .../Utility/UI/jucer_SlidingPanelComponent.h | 11 +- .../Utility/UI/jucer_UserSettingsPopup.h | 161 - .../Source/Wizards/jucer_NewProjectWizard.h | 204 - .../Wizards/jucer_NewProjectWizardClasses.cpp | 90 - .../Wizards/jucer_NewProjectWizardComponent.h | 515 - .../Wizards/jucer_ProjectWizard_Animated.h | 120 - .../Wizards/jucer_ProjectWizard_AudioApp.h | 129 - .../Wizards/jucer_ProjectWizard_AudioPlugin.h | 113 - .../Wizards/jucer_ProjectWizard_Blank.h | 50 - .../Wizards/jucer_ProjectWizard_Console.h | 89 - .../Source/Wizards/jucer_ProjectWizard_DLL.h | 50 - .../Wizards/jucer_ProjectWizard_GUIApp.h | 131 - .../jucer_ProjectWizard_StaticLibrary.h | 50 - .../Wizards/jucer_ProjectWizard_openGL.h | 120 - .../Source/Wizards/jucer_StartPageComponent.h | 60 - .../jucer_TemplateThumbnailsComponent.h | 266 - .../Builds/LinuxMakefile/Makefile | 14 +- .../Builds/MacOSX/ConsoleApp.entitlements | 6 - .../UnitTestRunner.xcodeproj/project.pbxproj | 101 +- .../xcshareddata/WorkspaceSettings.xcsettings | 2 + .../UnitTestRunner_ConsoleApp.vcxproj | 473 +- .../UnitTestRunner_ConsoleApp.vcxproj.filters | 836 +- .../Builds/VisualStudio2017/resources.rc | 6 +- .../UnitTestRunner_ConsoleApp.vcxproj | 473 +- .../UnitTestRunner_ConsoleApp.vcxproj.filters | 836 +- .../Builds/VisualStudio2019/resources.rc | 6 +- extras/UnitTestRunner/CMakeLists.txt | 46 + .../JuceLibraryCode/AppConfig.h | 323 - .../JuceLibraryCode/JuceHeader.h | 3 +- .../include_juce_analytics.cpp | 1 - .../include_juce_audio_basics.cpp | 1 - .../include_juce_audio_basics.mm | 1 - .../include_juce_audio_devices.cpp | 1 - .../include_juce_audio_devices.mm | 1 - .../include_juce_audio_formats.cpp | 1 - .../include_juce_audio_formats.mm | 1 - .../include_juce_audio_processors.cpp | 1 - .../include_juce_audio_processors.mm | 1 - .../include_juce_audio_utils.cpp | 1 - .../include_juce_audio_utils.mm | 1 - .../include_juce_blocks_basics.cpp | 1 - .../JuceLibraryCode/include_juce_core.cpp | 1 - .../JuceLibraryCode/include_juce_core.mm | 1 - .../include_juce_cryptography.cpp | 1 - .../include_juce_cryptography.mm | 1 - .../include_juce_data_structures.cpp | 1 - .../include_juce_data_structures.mm | 1 - .../JuceLibraryCode/include_juce_dsp.cpp | 1 - .../JuceLibraryCode/include_juce_dsp.mm | 1 - .../JuceLibraryCode/include_juce_events.cpp | 1 - .../JuceLibraryCode/include_juce_events.mm | 1 - .../JuceLibraryCode/include_juce_graphics.cpp | 1 - .../JuceLibraryCode/include_juce_graphics.mm | 1 - .../include_juce_gui_basics.cpp | 1 - .../include_juce_gui_basics.mm | 1 - .../include_juce_gui_extra.cpp | 1 - .../JuceLibraryCode/include_juce_gui_extra.mm | 1 - .../JuceLibraryCode/include_juce_opengl.cpp | 1 - .../JuceLibraryCode/include_juce_opengl.mm | 1 - .../JuceLibraryCode/include_juce_osc.cpp | 1 - .../include_juce_product_unlocking.cpp | 1 - .../include_juce_product_unlocking.mm | 1 - .../JuceLibraryCode/include_juce_video.cpp | 1 - .../JuceLibraryCode/include_juce_video.mm | 1 - extras/UnitTestRunner/Source/Main.cpp | 27 +- extras/UnitTestRunner/UnitTestRunner.jucer | 15 +- .../WindowsDLL_StaticLibrary.vcxproj | 401 +- .../WindowsDLL_StaticLibrary.vcxproj.filters | 729 +- extras/WindowsDLL/JuceLibraryCode/AppConfig.h | 295 - .../WindowsDLL/JuceLibraryCode/JuceHeader.h | 3 +- .../include_juce_audio_basics.cpp | 1 - .../include_juce_audio_basics.mm | 1 - .../include_juce_audio_devices.cpp | 1 - .../include_juce_audio_devices.mm | 1 - .../include_juce_audio_formats.cpp | 1 - .../include_juce_audio_formats.mm | 1 - .../include_juce_audio_processors.cpp | 1 - .../include_juce_audio_processors.mm | 1 - .../include_juce_audio_utils.cpp | 1 - .../include_juce_audio_utils.mm | 1 - .../JuceLibraryCode/include_juce_core.cpp | 1 - .../JuceLibraryCode/include_juce_core.mm | 1 - .../include_juce_cryptography.cpp | 1 - .../include_juce_cryptography.mm | 1 - .../include_juce_data_structures.cpp | 1 - .../include_juce_data_structures.mm | 1 - .../JuceLibraryCode/include_juce_events.cpp | 1 - .../JuceLibraryCode/include_juce_events.mm | 1 - .../JuceLibraryCode/include_juce_graphics.cpp | 1 - .../JuceLibraryCode/include_juce_graphics.mm | 1 - .../include_juce_gui_basics.cpp | 1 - .../include_juce_gui_basics.mm | 1 - .../include_juce_gui_extra.cpp | 1 - .../JuceLibraryCode/include_juce_gui_extra.mm | 1 - .../JuceLibraryCode/include_juce_opengl.cpp | 1 - .../JuceLibraryCode/include_juce_opengl.mm | 1 - .../JuceLibraryCode/include_juce_video.cpp | 1 - .../JuceLibraryCode/include_juce_video.mm | 1 - extras/WindowsDLL/WindowsDLL.jucer | 7 +- modules/CMakeLists.txt | 47 + .../analytics/juce_Analytics.cpp | 11 +- .../juce_analytics/analytics/juce_Analytics.h | 11 +- .../analytics/juce_ButtonTracker.cpp | 11 +- .../analytics/juce_ButtonTracker.h | 11 +- .../destinations/juce_AnalyticsDestination.h | 11 +- .../juce_ThreadedAnalyticsDestination.cpp | 11 +- .../juce_ThreadedAnalyticsDestination.h | 11 +- modules/juce_analytics/juce_analytics.cpp | 11 +- modules/juce_analytics/juce_analytics.h | 16 +- .../audio_play_head/juce_AudioPlayHead.h | 35 +- .../buffers/juce_AudioChannelSet.cpp | 71 +- .../buffers/juce_AudioChannelSet.h | 4 +- .../buffers/juce_AudioDataConverters.cpp | 50 +- .../buffers/juce_AudioDataConverters.h | 32 +- .../buffers/juce_AudioProcessLoadMeasurer.cpp | 16 +- .../buffers/juce_AudioProcessLoadMeasurer.h | 16 +- .../buffers/juce_AudioSampleBuffer.h | 67 +- .../buffers/juce_FloatVectorOperations.cpp | 4 +- .../buffers/juce_FloatVectorOperations.h | 2 +- .../juce_audio_basics/juce_audio_basics.cpp | 5 +- modules/juce_audio_basics/juce_audio_basics.h | 10 +- .../juce_audio_basics/juce_audio_basics.mm | 2 +- .../midi/juce_MidiBuffer.cpp | 81 +- .../juce_audio_basics/midi/juce_MidiBuffer.h | 146 +- .../juce_audio_basics/midi/juce_MidiFile.cpp | 514 +- .../juce_audio_basics/midi/juce_MidiFile.h | 2 +- .../midi/juce_MidiKeyboardState.cpp | 37 +- .../midi/juce_MidiKeyboardState.h | 92 +- .../midi/juce_MidiMessage.cpp | 217 +- .../juce_audio_basics/midi/juce_MidiMessage.h | 42 +- .../midi/juce_MidiMessageSequence.cpp | 2 +- .../midi/juce_MidiMessageSequence.h | 2 +- .../juce_audio_basics/midi/juce_MidiRPN.cpp | 9 +- modules/juce_audio_basics/midi/juce_MidiRPN.h | 2 +- .../mpe/juce_MPEInstrument.cpp | 38 +- .../mpe/juce_MPEInstrument.h | 2 +- .../mpe/juce_MPEMessages.cpp | 11 +- .../juce_audio_basics/mpe/juce_MPEMessages.h | 2 +- .../juce_audio_basics/mpe/juce_MPENote.cpp | 2 +- modules/juce_audio_basics/mpe/juce_MPENote.h | 2 +- .../mpe/juce_MPESynthesiser.cpp | 2 +- .../mpe/juce_MPESynthesiser.h | 2 +- .../mpe/juce_MPESynthesiserBase.cpp | 260 +- .../mpe/juce_MPESynthesiserBase.h | 9 +- .../mpe/juce_MPESynthesiserVoice.cpp | 2 +- .../mpe/juce_MPESynthesiserVoice.h | 2 +- .../juce_audio_basics/mpe/juce_MPEUtils.cpp | 2 +- modules/juce_audio_basics/mpe/juce_MPEUtils.h | 2 +- .../juce_audio_basics/mpe/juce_MPEValue.cpp | 2 +- modules/juce_audio_basics/mpe/juce_MPEValue.h | 2 +- .../mpe/juce_MPEZoneLayout.cpp | 10 +- .../mpe/juce_MPEZoneLayout.h | 2 +- .../native/juce_mac_CoreAudioLayouts.h | 2 +- .../sources/juce_AudioSource.h | 2 +- .../sources/juce_BufferingAudioSource.cpp | 2 +- .../sources/juce_BufferingAudioSource.h | 2 +- .../juce_ChannelRemappingAudioSource.cpp | 2 +- .../juce_ChannelRemappingAudioSource.h | 2 +- .../sources/juce_IIRFilterAudioSource.cpp | 2 +- .../sources/juce_IIRFilterAudioSource.h | 2 +- .../sources/juce_MemoryAudioSource.cpp | 33 +- .../sources/juce_MemoryAudioSource.h | 23 +- .../sources/juce_MixerAudioSource.cpp | 2 +- .../sources/juce_MixerAudioSource.h | 2 +- .../sources/juce_PositionableAudioSource.h | 2 +- .../sources/juce_ResamplingAudioSource.cpp | 2 +- .../sources/juce_ResamplingAudioSource.h | 2 +- .../sources/juce_ReverbAudioSource.cpp | 2 +- .../sources/juce_ReverbAudioSource.h | 2 +- .../sources/juce_ToneGeneratorAudioSource.cpp | 2 +- .../sources/juce_ToneGeneratorAudioSource.h | 2 +- .../synthesisers/juce_Synthesiser.cpp | 25 +- .../synthesisers/juce_Synthesiser.h | 2 +- .../juce_audio_basics/utilities/juce_ADSR.h | 2 +- .../utilities/juce_CatmullRomInterpolator.cpp | 75 - .../utilities/juce_CatmullRomInterpolator.h | 146 - .../utilities/juce_Decibels.h | 2 +- .../utilities/juce_GenericInterpolator.h | 500 + .../utilities/juce_IIRFilter.cpp | 2 +- .../utilities/juce_IIRFilter.h | 2 +- .../utilities/juce_Interpolators.cpp | 191 + .../utilities/juce_Interpolators.h | 245 + .../utilities/juce_LagrangeInterpolator.cpp | 441 +- .../utilities/juce_LagrangeInterpolator.h | 146 - .../juce_audio_basics/utilities/juce_Reverb.h | 2 +- .../utilities/juce_SmoothedValue.cpp | 2 +- .../utilities/juce_SmoothedValue.h | 8 +- .../juce_WindowedSincInterpolator.cpp | 10033 ++++++++++++ .../audio_io/juce_AudioDeviceManager.cpp | 38 +- .../audio_io/juce_AudioDeviceManager.h | 2 +- .../audio_io/juce_AudioIODevice.cpp | 2 +- .../audio_io/juce_AudioIODevice.h | 2 +- .../audio_io/juce_AudioIODeviceType.cpp | 103 +- .../audio_io/juce_AudioIODeviceType.h | 9 +- .../audio_io/juce_SystemAudioVolume.h | 2 +- .../juce_audio_devices/juce_audio_devices.cpp | 139 +- .../juce_audio_devices/juce_audio_devices.h | 59 +- .../juce_audio_devices/juce_audio_devices.mm | 2 +- .../midi_io/juce_MidiDevices.cpp | 19 +- .../midi_io/juce_MidiDevices.h | 20 +- .../midi_io/juce_MidiMessageCollector.cpp | 34 +- .../midi_io/juce_MidiMessageCollector.h | 14 +- .../{roli => rmsl}/juce/JuceMidiSupport.java | 24 +- .../native/juce_MidiDataConcatenator.h | 2 +- .../native/juce_android_Audio.cpp | 17 +- ...juce_android_HighPerformanceAudioHelpers.h | 131 + .../native/juce_android_Midi.cpp | 652 +- .../native/juce_android_Oboe.cpp | 406 +- .../native/juce_android_OpenSL.cpp | 171 +- .../native/juce_ios_Audio.cpp | 10 +- .../native/juce_ios_Audio.h | 2 +- .../native/juce_linux_ALSA.cpp | 9 +- .../native/juce_linux_Bela.cpp | 57 +- .../native/juce_linux_JackAudio.cpp | 370 +- .../native/juce_linux_Midi.cpp | 48 +- .../native/juce_mac_CoreAudio.cpp | 46 +- .../native/juce_mac_CoreMidi.cpp | 64 +- .../native/juce_win32_ASIO.cpp | 23 +- .../native/juce_win32_DirectSound.cpp | 16 +- .../native/juce_win32_Midi.cpp | 98 +- .../native/juce_win32_WASAPI.cpp | 610 +- .../native/oboe/CMakeLists.txt | 91 + .../juce_audio_devices/native/oboe/LICENSE | 202 + .../native/oboe/include/oboe/AudioStream.h | 543 + .../oboe/include/oboe/AudioStreamBase.h | 202 + .../oboe/include/oboe/AudioStreamBuilder.h | 438 + .../oboe/include/oboe/AudioStreamCallback.h | 123 + .../native/oboe/include/oboe/Definitions.h | 519 + .../native/oboe/include/oboe/LatencyTuner.h | 118 + .../native/oboe/include/oboe/Oboe.h | 37 + .../oboe/include/oboe/ResultWithValue.h | 155 + .../oboe/include/oboe/StabilizedCallback.h | 75 + .../native/oboe/include/oboe/Utilities.h | 87 + .../native/oboe/include/oboe/Version.h | 92 + .../juce_audio_devices/native/oboe/readme.md | 10 + .../native/oboe/src/aaudio/AAudioLoader.cpp | 348 + .../native/oboe/src/aaudio/AAudioLoader.h | 229 + .../oboe/src/aaudio/AudioStreamAAudio.cpp | 643 + .../oboe/src/aaudio/AudioStreamAAudio.h | 123 + .../native/oboe/src/common/AudioClock.h | 75 + .../oboe/src/common/AudioSourceCaller.cpp | 38 + .../oboe/src/common/AudioSourceCaller.h | 83 + .../native/oboe/src/common/AudioStream.cpp | 211 + .../oboe/src/common/AudioStreamBuilder.cpp | 201 + .../src/common/DataConversionFlowGraph.cpp | 215 + .../oboe/src/common/DataConversionFlowGraph.h | 84 + .../oboe/src/common/FilterAudioStream.cpp | 92 + .../oboe/src/common/FilterAudioStream.h | 214 + .../oboe/src/common/FixedBlockAdapter.cpp | 38 + .../oboe/src/common/FixedBlockAdapter.h | 67 + .../oboe/src/common/FixedBlockReader.cpp | 73 + .../native/oboe/src/common/FixedBlockReader.h | 60 + .../oboe/src/common/FixedBlockWriter.cpp | 73 + .../native/oboe/src/common/FixedBlockWriter.h | 54 + .../native/oboe/src/common/LatencyTuner.cpp | 102 + .../native/oboe/src/common/MonotonicCounter.h | 112 + .../native/oboe/src/common/OboeDebug.h | 41 + .../native/oboe/src/common/QuirksManager.cpp | 138 + .../native/oboe/src/common/QuirksManager.h | 110 + .../oboe/src/common/SourceFloatCaller.cpp | 30 + .../oboe/src/common/SourceFloatCaller.h | 44 + .../oboe/src/common/SourceI16Caller.cpp | 47 + .../native/oboe/src/common/SourceI16Caller.h | 48 + .../oboe/src/common/StabilizedCallback.cpp | 112 + .../native/oboe/src/common/Trace.cpp | 75 + .../native/oboe/src/common/Trace.h | 31 + .../native/oboe/src/common/Utilities.cpp | 305 + .../native/oboe/src/common/Version.cpp | 28 + .../native/oboe/src/fifo/FifoBuffer.cpp | 182 + .../native/oboe/src/fifo/FifoBuffer.h | 99 + .../native/oboe/src/fifo/FifoController.cpp | 31 + .../native/oboe/src/fifo/FifoController.h | 61 + .../oboe/src/fifo/FifoControllerBase.cpp | 71 + .../native/oboe/src/fifo/FifoControllerBase.h | 93 + .../oboe/src/fifo/FifoControllerIndirect.cpp | 31 + .../oboe/src/fifo/FifoControllerIndirect.h | 64 + .../native/oboe/src/flowgraph/ClipToRange.cpp | 38 + .../native/oboe/src/flowgraph/ClipToRange.h | 68 + .../oboe/src/flowgraph/FlowGraphNode.cpp | 111 + .../native/oboe/src/flowgraph/FlowGraphNode.h | 422 + .../src/flowgraph/ManyToMultiConverter.cpp | 47 + .../oboe/src/flowgraph/ManyToMultiConverter.h | 49 + .../src/flowgraph/MonoToMultiConverter.cpp | 43 + .../oboe/src/flowgraph/MonoToMultiConverter.h | 49 + .../native/oboe/src/flowgraph/RampLinear.cpp | 77 + .../native/oboe/src/flowgraph/RampLinear.h | 96 + .../src/flowgraph/SampleRateConverter.cpp | 64 + .../oboe/src/flowgraph/SampleRateConverter.h | 56 + .../native/oboe/src/flowgraph/SinkFloat.cpp | 50 + .../native/oboe/src/flowgraph/SinkFloat.h | 44 + .../native/oboe/src/flowgraph/SinkI16.cpp | 58 + .../native/oboe/src/flowgraph/SinkI16.h | 43 + .../native/oboe/src/flowgraph/SinkI24.cpp | 67 + .../native/oboe/src/flowgraph/SinkI24.h | 44 + .../native/oboe/src/flowgraph/SourceFloat.cpp | 43 + .../native/oboe/src/flowgraph/SourceFloat.h | 43 + .../native/oboe/src/flowgraph/SourceI16.cpp | 54 + .../native/oboe/src/flowgraph/SourceI16.h | 42 + .../native/oboe/src/flowgraph/SourceI24.cpp | 65 + .../native/oboe/src/flowgraph/SourceI24.h | 43 + .../resampler/HyperbolicCosineWindow.h | 68 + .../src/flowgraph/resampler/IntegerRatio.cpp | 50 + .../src/flowgraph/resampler/IntegerRatio.h | 52 + .../src/flowgraph/resampler/KaiserWindow.h | 87 + .../flowgraph/resampler/LinearResampler.cpp | 42 + .../src/flowgraph/resampler/LinearResampler.h | 44 + .../resampler/MultiChannelResampler.cpp | 171 + .../resampler/MultiChannelResampler.h | 271 + .../resampler/PolyphaseResampler.cpp | 61 + .../flowgraph/resampler/PolyphaseResampler.h | 51 + .../resampler/PolyphaseResamplerMono.cpp | 62 + .../resampler/PolyphaseResamplerMono.h | 39 + .../resampler/PolyphaseResamplerStereo.cpp | 78 + .../resampler/PolyphaseResamplerStereo.h | 39 + .../src/flowgraph/resampler/SincResampler.cpp | 76 + .../src/flowgraph/resampler/SincResampler.h | 47 + .../resampler/SincResamplerStereo.cpp | 80 + .../flowgraph/resampler/SincResamplerStereo.h | 39 + .../src/opensles/AudioInputStreamOpenSLES.cpp | 352 + .../src/opensles/AudioInputStreamOpenSLES.h | 65 + .../opensles/AudioOutputStreamOpenSLES.cpp | 448 + .../src/opensles/AudioOutputStreamOpenSLES.h | 77 + .../oboe/src/opensles/AudioStreamBuffered.cpp | 266 + .../oboe/src/opensles/AudioStreamBuffered.h | 92 + .../oboe/src/opensles/AudioStreamOpenSLES.cpp | 396 + .../oboe/src/opensles/AudioStreamOpenSLES.h | 132 + .../oboe/src/opensles/EngineOpenSLES.cpp | 101 + .../native/oboe/src/opensles/EngineOpenSLES.h | 65 + .../oboe/src/opensles/OpenSLESUtilities.cpp | 93 + .../oboe/src/opensles/OpenSLESUtilities.h | 44 + .../oboe/src/opensles/OutputMixerOpenSLES.cpp | 74 + .../oboe/src/opensles/OutputMixerOpenSLES.h | 58 + .../sources/juce_AudioSourcePlayer.cpp | 2 +- .../sources/juce_AudioSourcePlayer.h | 2 +- .../sources/juce_AudioTransportSource.cpp | 2 +- .../sources/juce_AudioTransportSource.h | 2 +- .../codecs/juce_AiffAudioFormat.cpp | 26 +- .../codecs/juce_AiffAudioFormat.h | 11 +- .../codecs/juce_CoreAudioFormat.cpp | 13 +- .../codecs/juce_CoreAudioFormat.h | 11 +- .../codecs/juce_FlacAudioFormat.cpp | 50 +- .../codecs/juce_FlacAudioFormat.h | 11 +- .../codecs/juce_LAMEEncoderAudioFormat.cpp | 25 +- .../codecs/juce_LAMEEncoderAudioFormat.h | 11 +- .../codecs/juce_MP3AudioFormat.cpp | 129 +- .../codecs/juce_MP3AudioFormat.h | 15 +- .../codecs/juce_OggVorbisAudioFormat.cpp | 111 +- .../codecs/juce_OggVorbisAudioFormat.h | 11 +- .../codecs/juce_WavAudioFormat.cpp | 23 +- .../codecs/juce_WavAudioFormat.h | 11 +- .../codecs/juce_WindowsMediaAudioFormat.cpp | 32 +- .../codecs/juce_WindowsMediaAudioFormat.h | 11 +- .../format/juce_AudioFormat.cpp | 11 +- .../format/juce_AudioFormat.h | 11 +- .../format/juce_AudioFormatManager.cpp | 28 +- .../format/juce_AudioFormatManager.h | 15 +- .../format/juce_AudioFormatReader.cpp | 19 +- .../format/juce_AudioFormatReader.h | 11 +- .../format/juce_AudioFormatReaderSource.cpp | 11 +- .../format/juce_AudioFormatReaderSource.h | 11 +- .../format/juce_AudioFormatWriter.cpp | 15 +- .../format/juce_AudioFormatWriter.h | 11 +- .../format/juce_AudioSubsectionReader.cpp | 11 +- .../format/juce_AudioSubsectionReader.h | 11 +- .../juce_BufferingAudioFormatReader.cpp | 11 +- .../format/juce_BufferingAudioFormatReader.h | 11 +- .../juce_MemoryMappedAudioFormatReader.h | 11 +- .../juce_audio_formats/juce_audio_formats.cpp | 11 +- .../juce_audio_formats/juce_audio_formats.h | 19 +- .../juce_audio_formats/juce_audio_formats.mm | 11 +- .../sampler/juce_Sampler.cpp | 11 +- .../juce_audio_formats/sampler/juce_Sampler.h | 11 +- .../AAX/juce_AAX_Modifier_Injector.h | 11 +- .../AAX/juce_AAX_Wrapper.cpp | 146 +- .../RTAS/juce_RTAS_DigiCode1.cpp | 32 +- .../RTAS/juce_RTAS_DigiCode2.cpp | 30 +- .../RTAS/juce_RTAS_DigiCode3.cpp | 24 +- .../RTAS/juce_RTAS_DigiCode_Header.h | 11 +- .../RTAS/juce_RTAS_MacUtilities.mm | 13 +- .../RTAS/juce_RTAS_WinUtilities.cpp | 13 +- .../RTAS/juce_RTAS_Wrapper.cpp | 41 +- .../Standalone/juce_StandaloneFilterApp.cpp | 17 +- .../Standalone/juce_StandaloneFilterWindow.h | 64 +- .../Unity/juce_UnityPluginInterface.h | 15 +- .../Unity/juce_Unity_Wrapper.cpp | 32 +- .../VST/juce_VSTCallbackHandler.h | 11 +- .../VST/juce_VST_Wrapper.cpp | 481 +- .../VST/juce_VST_Wrapper.mm | 13 +- .../VST3/juce_VST3_Wrapper.cpp | 774 +- .../juce_audio_plugin_client.h | 18 +- .../juce_audio_plugin_client_AAX.cpp | 11 +- .../juce_audio_plugin_client_AAX.mm | 11 +- .../juce_audio_plugin_client_AU.r | 17 +- .../juce_audio_plugin_client_AU_1.mm | 11 +- .../juce_audio_plugin_client_AU_2.mm | 60 +- .../juce_audio_plugin_client_AUv3.mm | 11 +- .../juce_audio_plugin_client_RTAS_1.cpp | 11 +- .../juce_audio_plugin_client_RTAS_2.cpp | 11 +- .../juce_audio_plugin_client_RTAS_3.cpp | 11 +- .../juce_audio_plugin_client_RTAS_4.cpp | 11 +- .../juce_audio_plugin_client_RTAS_utils.cpp | 11 +- .../juce_audio_plugin_client_RTAS_utils.mm | 11 +- .../juce_audio_plugin_client_Standalone.cpp | 13 +- .../juce_audio_plugin_client_Unity.cpp | 11 +- .../juce_audio_plugin_client_VST2.cpp | 11 +- .../juce_audio_plugin_client_VST3.cpp | 11 +- .../juce_audio_plugin_client_VST_utils.mm | 11 +- .../juce_audio_plugin_client_utils.cpp | 11 +- .../utility/juce_CarbonVisibility.h | 11 +- .../utility/juce_CheckSettingMacros.h | 13 +- .../utility/juce_CreatePluginFilter.h | 48 + .../utility/juce_FakeMouseMoveGenerator.h | 27 +- .../utility/juce_IncludeModuleHeaders.h | 16 +- .../utility/juce_IncludeSystemHeaders.h | 23 +- .../utility/juce_PluginHostType.h | 18 +- .../utility/juce_PluginUtilities.cpp | 208 +- .../utility/juce_WindowsHooks.h | 11 +- .../format/juce_AudioPluginFormat.cpp | 11 +- .../format/juce_AudioPluginFormat.h | 13 +- .../format/juce_AudioPluginFormatManager.cpp | 15 +- .../format/juce_AudioPluginFormatManager.h | 13 +- .../VST3_SDK/base/source/fstring.cpp | 10 +- .../VST3_SDK/pluginterfaces/base/funknown.cpp | 1 - .../format_types/juce_AU_Shared.h | 11 +- .../format_types/juce_AudioUnitPluginFormat.h | 11 +- .../juce_AudioUnitPluginFormat.mm | 88 +- .../format_types/juce_LADSPAPluginFormat.cpp | 14 +- .../format_types/juce_LADSPAPluginFormat.h | 11 +- .../juce_LegacyAudioParameter.cpp | 32 +- .../format_types/juce_VST3Common.h | 502 +- .../format_types/juce_VST3Headers.h | 126 +- .../format_types/juce_VST3PluginFormat.cpp | 726 +- .../format_types/juce_VST3PluginFormat.h | 13 +- .../format_types/juce_VSTCommon.h | 123 +- .../format_types/juce_VSTMidiEventList.h | 11 +- .../format_types/juce_VSTPluginFormat.cpp | 493 +- .../format_types/juce_VSTPluginFormat.h | 11 +- .../juce_audio_processors.cpp | 35 +- .../juce_audio_processors.h | 25 +- .../juce_audio_processors.mm | 11 +- .../processors/juce_AudioPluginInstance.cpp | 11 +- .../processors/juce_AudioPluginInstance.h | 25 +- .../processors/juce_AudioProcessor.cpp | 68 +- .../processors/juce_AudioProcessor.h | 16 +- .../processors/juce_AudioProcessorEditor.cpp | 33 +- .../processors/juce_AudioProcessorEditor.h | 12 +- .../processors/juce_AudioProcessorGraph.cpp | 75 +- .../processors/juce_AudioProcessorGraph.h | 38 +- .../processors/juce_AudioProcessorListener.h | 11 +- .../processors/juce_AudioProcessorParameter.h | 11 +- .../juce_AudioProcessorParameterGroup.cpp | 11 +- .../juce_AudioProcessorParameterGroup.h | 11 +- .../juce_GenericAudioProcessorEditor.cpp | 13 +- .../juce_GenericAudioProcessorEditor.h | 11 +- .../processors/juce_PluginDescription.cpp | 11 +- .../processors/juce_PluginDescription.h | 11 +- .../scanning/juce_KnownPluginList.cpp | 13 +- .../scanning/juce_KnownPluginList.h | 11 +- .../scanning/juce_PluginDirectoryScanner.cpp | 13 +- .../scanning/juce_PluginDirectoryScanner.h | 11 +- .../scanning/juce_PluginListComponent.cpp | 15 +- .../scanning/juce_PluginListComponent.h | 11 +- .../utilities/juce_AudioParameterBool.cpp | 15 +- .../utilities/juce_AudioParameterBool.h | 19 +- .../utilities/juce_AudioParameterChoice.cpp | 23 +- .../utilities/juce_AudioParameterChoice.h | 19 +- .../utilities/juce_AudioParameterFloat.cpp | 17 +- .../utilities/juce_AudioParameterFloat.h | 19 +- .../utilities/juce_AudioParameterInt.cpp | 21 +- .../utilities/juce_AudioParameterInt.h | 19 +- .../juce_AudioProcessorParameterWithID.cpp | 11 +- .../juce_AudioProcessorParameterWithID.h | 11 +- .../juce_AudioProcessorValueTreeState.cpp | 374 +- .../juce_AudioProcessorValueTreeState.h | 60 +- .../utilities/juce_ParameterAttachments.cpp | 271 + .../utilities/juce_ParameterAttachments.h | 251 + .../utilities/juce_RangedAudioParameter.cpp | 11 +- .../utilities/juce_RangedAudioParameter.h | 11 +- .../audio_cd/juce_AudioCDBurner.h | 11 +- .../audio_cd/juce_AudioCDReader.cpp | 11 +- .../audio_cd/juce_AudioCDReader.h | 13 +- .../gui/juce_AudioAppComponent.cpp | 11 +- .../gui/juce_AudioAppComponent.h | 11 +- .../gui/juce_AudioDeviceSelectorComponent.cpp | 27 +- .../gui/juce_AudioDeviceSelectorComponent.h | 11 +- .../gui/juce_AudioThumbnail.cpp | 19 +- .../gui/juce_AudioThumbnail.h | 11 +- .../gui/juce_AudioThumbnailBase.h | 11 +- .../gui/juce_AudioThumbnailCache.cpp | 13 +- .../gui/juce_AudioThumbnailCache.h | 11 +- .../gui/juce_AudioVisualiserComponent.cpp | 13 +- .../gui/juce_AudioVisualiserComponent.h | 11 +- .../juce_BluetoothMidiDevicePairingDialogue.h | 11 +- .../gui/juce_MidiKeyboardComponent.cpp | 43 +- .../gui/juce_MidiKeyboardComponent.h | 13 +- modules/juce_audio_utils/juce_audio_utils.cpp | 11 +- modules/juce_audio_utils/juce_audio_utils.h | 17 +- modules/juce_audio_utils/juce_audio_utils.mm | 11 +- ...oid_BluetoothMidiDevicePairingDialogue.cpp | 18 +- ..._ios_BluetoothMidiDevicePairingDialogue.mm | 11 +- .../native/juce_linux_AudioCDReader.cpp | 11 +- ...nux_BluetoothMidiDevicePairingDialogue.cpp | 11 +- .../native/juce_mac_AudioCDBurner.mm | 55 +- .../native/juce_mac_AudioCDReader.mm | 17 +- ..._mac_BluetoothMidiDevicePairingDialogue.mm | 31 +- .../native/juce_win32_AudioCDBurner.cpp | 11 +- .../native/juce_win32_AudioCDReader.cpp | 11 +- ...win_BluetoothMidiDevicePairingDialogue.cpp | 11 +- .../players/juce_AudioProcessorPlayer.cpp | 24 +- .../players/juce_AudioProcessorPlayer.h | 11 +- .../players/juce_SoundPlayer.cpp | 15 +- .../players/juce_SoundPlayer.h | 11 +- .../juce_blocks_basics/blocks/juce_Block.cpp | 9 +- .../juce_blocks_basics/blocks/juce_Block.h | 88 +- .../blocks/juce_BlockConfigManager.h | 32 +- .../blocks/juce_BlocksVersion.cpp | 6 +- .../blocks/juce_BlocksVersion.h | 7 +- .../blocks/juce_ControlButton.h | 2 +- .../juce_blocks_basics/blocks/juce_LEDGrid.h | 2 +- .../juce_blocks_basics/blocks/juce_LEDRow.h | 2 +- .../blocks/juce_StatusLight.h | 2 +- .../blocks/juce_TouchList.h | 2 +- .../blocks/juce_TouchSurface.h | 2 +- .../juce_blocks_basics/juce_blocks_basics.cpp | 10 +- .../juce_blocks_basics/juce_blocks_basics.h | 16 +- .../littlefoot/juce_LittleFootCompiler.h | 59 +- .../littlefoot/juce_LittleFootRemoteHeap.h | 2 +- .../littlefoot/juce_LittleFootRunner.h | 13 +- .../protocol/juce_BitPackingUtilities.h | 10 +- .../protocol/juce_BlockModels.h | 20 +- .../protocol/juce_BlocksProtocolDefinitions.h | 2 +- .../protocol/juce_HostPacketBuilder.h | 2 +- .../protocol/juce_HostPacketDecoder.h | 2 +- .../internal/juce_BandwidthStatsLogger.cpp | 8 +- .../internal/juce_BlockImplementation.cpp | 150 +- .../internal/juce_BlockSerialReader.cpp | 2 +- .../internal/juce_ConnectedDeviceGroup.cpp | 8 +- .../juce_DepreciatedVersionReader.cpp | 2 +- .../topology/internal/juce_Detector.cpp | 27 +- .../topology/internal/juce_DetectorHolder.cpp | 2 +- .../topology/internal/juce_DeviceInfo.cpp | 2 +- .../internal/juce_MIDIDeviceDetector.cpp | 2 +- .../internal/juce_MidiDeviceConnection.cpp | 2 +- .../topology/juce_BlockGraph.cpp | 4 +- .../topology/juce_BlockGraph.h | 6 +- .../topology/juce_PhysicalTopologySource.cpp | 4 +- .../topology/juce_PhysicalTopologySource.h | 6 +- .../topology/juce_RuleBasedTopologySource.cpp | 2 +- .../topology/juce_RuleBasedTopologySource.h | 4 +- .../topology/juce_Topology.h | 2 +- .../topology/juce_TopologySource.h | 11 +- .../visualisers/juce_BitmapLEDProgram.cpp | 2 +- .../visualisers/juce_BitmapLEDProgram.h | 2 +- .../visualisers/juce_DrumPadLEDProgram.cpp | 12 +- .../visualisers/juce_DrumPadLEDProgram.h | 2 +- .../box2d/Collision/b2DynamicTree.cpp | 1 + modules/juce_box2d/box2d/Dynamics/b2Body.cpp | 1 + modules/juce_box2d/juce_box2d.cpp | 39 +- modules/juce_box2d/juce_box2d.h | 43 +- .../juce_box2d/utils/juce_Box2DRenderer.cpp | 11 +- modules/juce_box2d/utils/juce_Box2DRenderer.h | 11 +- .../containers/juce_AbstractFifo.cpp | 2 +- .../juce_core/containers/juce_AbstractFifo.h | 2 +- modules/juce_core/containers/juce_Array.h | 2 +- .../containers/juce_ArrayAllocationBase.h | 2 +- .../juce_core/containers/juce_ArrayBase.cpp | 10 +- modules/juce_core/containers/juce_ArrayBase.h | 2 +- .../containers/juce_DynamicObject.cpp | 2 +- .../juce_core/containers/juce_DynamicObject.h | 2 +- .../containers/juce_ElementComparator.h | 2 +- modules/juce_core/containers/juce_HashMap.h | 4 +- .../containers/juce_HashMap_test.cpp | 2 +- .../containers/juce_LinkedListPointer.h | 2 +- .../juce_core/containers/juce_ListenerList.h | 2 +- .../containers/juce_NamedValueSet.cpp | 2 +- .../juce_core/containers/juce_NamedValueSet.h | 2 +- .../juce_core/containers/juce_OwnedArray.cpp | 2 +- .../juce_core/containers/juce_OwnedArray.h | 2 +- .../juce_core/containers/juce_PropertySet.cpp | 6 +- .../juce_core/containers/juce_PropertySet.h | 10 +- .../containers/juce_ReferenceCountedArray.cpp | 2 +- .../containers/juce_ReferenceCountedArray.h | 2 +- .../containers/juce_ScopedValueSetter.h | 2 +- modules/juce_core/containers/juce_SortedSet.h | 13 +- .../juce_core/containers/juce_SparseSet.cpp | 2 +- modules/juce_core/containers/juce_SparseSet.h | 2 +- modules/juce_core/containers/juce_Variant.cpp | 6 +- modules/juce_core/containers/juce_Variant.h | 4 +- .../files/juce_DirectoryIterator.cpp | 12 +- .../juce_core/files/juce_DirectoryIterator.h | 24 +- modules/juce_core/files/juce_File.cpp | 45 +- modules/juce_core/files/juce_File.h | 19 +- modules/juce_core/files/juce_FileFilter.cpp | 2 +- modules/juce_core/files/juce_FileFilter.h | 2 +- .../juce_core/files/juce_FileInputStream.cpp | 107 +- .../juce_core/files/juce_FileInputStream.h | 2 +- .../juce_core/files/juce_FileOutputStream.cpp | 4 +- .../juce_core/files/juce_FileOutputStream.h | 2 +- .../juce_core/files/juce_FileSearchPath.cpp | 2 +- modules/juce_core/files/juce_FileSearchPath.h | 2 +- .../juce_core/files/juce_MemoryMappedFile.h | 2 +- .../files/juce_RangedDirectoryIterator.cpp | 77 + .../files/juce_RangedDirectoryIterator.h | 181 + .../juce_core/files/juce_TemporaryFile.cpp | 2 +- modules/juce_core/files/juce_TemporaryFile.h | 2 +- .../files/juce_WildcardFileFilter.cpp | 2 +- .../juce_core/files/juce_WildcardFileFilter.h | 2 +- modules/juce_core/javascript/juce_JSON.cpp | 4 +- modules/juce_core/javascript/juce_JSON.h | 2 +- .../juce_core/javascript/juce_Javascript.cpp | 17 +- .../juce_core/javascript/juce_Javascript.h | 2 +- modules/juce_core/juce_core.cpp | 9 +- modules/juce_core/juce_core.h | 36 +- modules/juce_core/juce_core.mm | 2 +- modules/juce_core/logging/juce_FileLogger.cpp | 2 +- modules/juce_core/logging/juce_FileLogger.h | 2 +- modules/juce_core/logging/juce_Logger.cpp | 2 +- modules/juce_core/logging/juce_Logger.h | 2 +- modules/juce_core/maths/juce_BigInteger.cpp | 4 +- modules/juce_core/maths/juce_BigInteger.h | 2 +- modules/juce_core/maths/juce_Expression.cpp | 4 +- modules/juce_core/maths/juce_Expression.h | 2 +- modules/juce_core/maths/juce_MathsFunctions.h | 121 +- .../juce_core/maths/juce_NormalisableRange.h | 2 +- modules/juce_core/maths/juce_Random.cpp | 6 +- modules/juce_core/maths/juce_Random.h | 2 +- modules/juce_core/maths/juce_Range.h | 52 +- .../maths/juce_StatisticsAccumulator.h | 2 +- .../juce_core/memory/juce_AllocationHooks.cpp | 104 + .../juce_core/memory/juce_AllocationHooks.h | 73 + modules/juce_core/memory/juce_Atomic.h | 2 +- modules/juce_core/memory/juce_ByteOrder.h | 62 +- .../memory/juce_ContainerDeletePolicy.h | 2 +- modules/juce_core/memory/juce_HeapBlock.h | 2 +- .../juce_HeavyweightLeakedObjectDetector.h | 2 +- .../memory/juce_LeakedObjectDetector.h | 4 +- modules/juce_core/memory/juce_Memory.h | 56 +- modules/juce_core/memory/juce_MemoryBlock.cpp | 4 +- modules/juce_core/memory/juce_MemoryBlock.h | 2 +- .../memory/juce_OptionalScopedPointer.h | 50 +- .../memory/juce_ReferenceCountedObject.h | 2 +- modules/juce_core/memory/juce_ScopedPointer.h | 2 +- .../memory/juce_SharedResourcePointer.h | 8 +- modules/juce_core/memory/juce_Singleton.h | 2 +- modules/juce_core/memory/juce_WeakReference.h | 4 +- .../misc/juce_ConsoleApplication.cpp | 20 +- .../juce_core/misc/juce_ConsoleApplication.h | 4 +- modules/juce_core/misc/juce_Result.cpp | 2 +- modules/juce_core/misc/juce_Result.h | 2 +- .../misc/juce_RuntimePermissions.cpp | 2 +- .../juce_core/misc/juce_RuntimePermissions.h | 4 +- modules/juce_core/misc/juce_Uuid.cpp | 2 +- modules/juce_core/misc/juce_Uuid.h | 2 +- modules/juce_core/misc/juce_WindowsRegistry.h | 2 +- modules/juce_core/native/java/README.txt | 23 +- .../{roli => rmsl}/juce/FragmentOverlay.java | 24 +- .../{roli => rmsl}/juce/JuceHTTPStream.java | 24 +- .../com/rmsl/juce/JuceInvocationHandler.java | 60 + .../javacore/app/com/rmsl/juce/JuceApp.java | 37 + .../javacore/app/com/roli/juce/JuceApp.java | 15 - .../javacore/init/com/rmsl/juce/Java.java | 35 + .../javacore/init/com/roli/juce/Java.java | 13 - .../native/juce_BasicNativeHeaders.h | 10 +- .../juce_core/native/juce_android_Files.cpp | 5 +- .../native/juce_android_JNIHelpers.cpp | 152 +- .../native/juce_android_JNIHelpers.h | 6 +- .../juce_core/native/juce_android_Misc.cpp | 17 +- .../juce_core/native/juce_android_Network.cpp | 315 +- .../juce_android_RuntimePermissions.cpp | 22 +- .../native/juce_android_SystemStats.cpp | 8 +- .../juce_core/native/juce_android_Threads.cpp | 6 +- .../juce_core/native/juce_curl_Network.cpp | 4 +- .../native/juce_linux_CommonFile.cpp | 2 +- modules/juce_core/native/juce_linux_Files.cpp | 6 +- .../juce_core/native/juce_linux_Network.cpp | 8 +- .../native/juce_linux_SystemStats.cpp | 10 +- .../juce_core/native/juce_linux_Threads.cpp | 2 +- .../native/juce_mac_ClangBugWorkaround.h | 2 +- modules/juce_core/native/juce_mac_Files.mm | 18 +- modules/juce_core/native/juce_mac_Network.mm | 25 +- modules/juce_core/native/juce_mac_Strings.mm | 2 +- .../juce_core/native/juce_mac_SystemStats.mm | 37 +- modules/juce_core/native/juce_mac_Threads.mm | 2 +- .../juce_core/native/juce_osx_ObjCHelpers.h | 117 +- .../juce_core/native/juce_posix_IPAddress.h | 10 +- .../juce_core/native/juce_posix_NamedPipe.cpp | 20 +- .../juce_core/native/juce_posix_SharedCode.h | 20 +- .../juce_core/native/juce_win32_ComSmartPtr.h | 17 +- modules/juce_core/native/juce_win32_Files.cpp | 117 +- .../juce_core/native/juce_win32_Network.cpp | 66 +- .../juce_core/native/juce_win32_Registry.cpp | 12 +- .../native/juce_win32_SystemStats.cpp | 51 +- .../juce_core/native/juce_win32_Threads.cpp | 68 +- modules/juce_core/network/juce_IPAddress.cpp | 10 +- modules/juce_core/network/juce_IPAddress.h | 2 +- modules/juce_core/network/juce_MACAddress.cpp | 2 +- modules/juce_core/network/juce_MACAddress.h | 2 +- modules/juce_core/network/juce_NamedPipe.cpp | 21 +- modules/juce_core/network/juce_NamedPipe.h | 2 +- modules/juce_core/network/juce_Socket.cpp | 83 +- modules/juce_core/network/juce_Socket.h | 2 +- modules/juce_core/network/juce_URL.cpp | 61 +- modules/juce_core/network/juce_URL.h | 38 +- .../juce_core/network/juce_WebInputStream.cpp | 2 +- .../juce_core/network/juce_WebInputStream.h | 2 +- .../streams/juce_BufferedInputStream.cpp | 4 +- .../streams/juce_BufferedInputStream.h | 2 +- .../streams/juce_FileInputSource.cpp | 6 +- .../juce_core/streams/juce_FileInputSource.h | 2 +- modules/juce_core/streams/juce_InputSource.h | 2 +- .../juce_core/streams/juce_InputStream.cpp | 2 +- modules/juce_core/streams/juce_InputStream.h | 2 +- .../streams/juce_MemoryInputStream.cpp | 3 +- .../streams/juce_MemoryInputStream.h | 2 +- .../streams/juce_MemoryOutputStream.cpp | 2 +- .../streams/juce_MemoryOutputStream.h | 2 +- .../juce_core/streams/juce_OutputStream.cpp | 2 +- modules/juce_core/streams/juce_OutputStream.h | 2 +- .../streams/juce_SubregionStream.cpp | 2 +- .../juce_core/streams/juce_SubregionStream.h | 2 +- .../juce_core/streams/juce_URLInputSource.cpp | 6 +- .../juce_core/streams/juce_URLInputSource.h | 2 +- .../juce_core/system/juce_CompilerSupport.h | 18 +- .../juce_core/system/juce_CompilerWarnings.h | 200 + modules/juce_core/system/juce_PlatformDefs.h | 30 +- .../juce_core/system/juce_StandardHeader.h | 42 +- modules/juce_core/system/juce_SystemStats.cpp | 2 +- modules/juce_core/system/juce_SystemStats.h | 7 +- .../juce_core/system/juce_TargetPlatform.h | 6 +- modules/juce_core/text/juce_Base64.cpp | 2 +- modules/juce_core/text/juce_Base64.h | 2 +- .../juce_core/text/juce_CharPointer_ASCII.h | 4 +- .../juce_core/text/juce_CharPointer_UTF16.h | 2 +- .../juce_core/text/juce_CharPointer_UTF32.h | 4 +- .../juce_core/text/juce_CharPointer_UTF8.h | 34 +- .../text/juce_CharacterFunctions.cpp | 11 +- .../juce_core/text/juce_CharacterFunctions.h | 29 +- modules/juce_core/text/juce_Identifier.cpp | 2 +- modules/juce_core/text/juce_Identifier.h | 2 +- .../juce_core/text/juce_LocalisedStrings.cpp | 2 +- .../juce_core/text/juce_LocalisedStrings.h | 2 +- modules/juce_core/text/juce_NewLine.h | 2 +- modules/juce_core/text/juce_String.cpp | 65 +- modules/juce_core/text/juce_String.h | 51 +- modules/juce_core/text/juce_StringArray.cpp | 2 +- modules/juce_core/text/juce_StringArray.h | 2 +- .../juce_core/text/juce_StringPairArray.cpp | 2 +- modules/juce_core/text/juce_StringPairArray.h | 2 +- modules/juce_core/text/juce_StringPool.cpp | 2 +- modules/juce_core/text/juce_StringPool.h | 2 +- modules/juce_core/text/juce_StringRef.h | 2 +- modules/juce_core/text/juce_TextDiff.cpp | 2 +- modules/juce_core/text/juce_TextDiff.h | 2 +- .../juce_core/threads/juce_ChildProcess.cpp | 2 +- modules/juce_core/threads/juce_ChildProcess.h | 2 +- .../juce_core/threads/juce_CriticalSection.h | 2 +- .../juce_core/threads/juce_DynamicLibrary.h | 2 +- .../threads/juce_HighResolutionTimer.cpp | 2 +- .../threads/juce_HighResolutionTimer.h | 2 +- .../juce_core/threads/juce_InterProcessLock.h | 2 +- modules/juce_core/threads/juce_Process.h | 2 +- .../juce_core/threads/juce_ReadWriteLock.cpp | 2 +- .../juce_core/threads/juce_ReadWriteLock.h | 2 +- modules/juce_core/threads/juce_ScopedLock.h | 2 +- .../juce_core/threads/juce_ScopedReadLock.h | 2 +- .../juce_core/threads/juce_ScopedWriteLock.h | 2 +- modules/juce_core/threads/juce_SpinLock.h | 5 +- modules/juce_core/threads/juce_Thread.cpp | 4 +- modules/juce_core/threads/juce_Thread.h | 6 +- .../juce_core/threads/juce_ThreadLocalValue.h | 2 +- modules/juce_core/threads/juce_ThreadPool.cpp | 2 +- modules/juce_core/threads/juce_ThreadPool.h | 2 +- .../threads/juce_TimeSliceThread.cpp | 2 +- .../juce_core/threads/juce_TimeSliceThread.h | 2 +- .../juce_core/threads/juce_WaitableEvent.cpp | 2 +- .../juce_core/threads/juce_WaitableEvent.h | 2 +- .../time/juce_PerformanceCounter.cpp | 6 +- .../juce_core/time/juce_PerformanceCounter.h | 2 +- modules/juce_core/time/juce_RelativeTime.cpp | 6 +- modules/juce_core/time/juce_RelativeTime.h | 2 +- modules/juce_core/time/juce_Time.cpp | 18 +- modules/juce_core/time/juce_Time.h | 2 +- .../juce_core/unit_tests/juce_UnitTest.cpp | 14 +- modules/juce_core/unit_tests/juce_UnitTest.h | 19 +- .../unit_tests/juce_UnitTestCategories.h | 3 +- modules/juce_core/xml/juce_XmlDocument.cpp | 2 +- modules/juce_core/xml/juce_XmlDocument.h | 9 +- modules/juce_core/xml/juce_XmlElement.cpp | 8 +- modules/juce_core/xml/juce_XmlElement.h | 2 +- .../zip/juce_GZIPCompressorOutputStream.cpp | 4 +- .../zip/juce_GZIPCompressorOutputStream.h | 2 +- .../zip/juce_GZIPDecompressorInputStream.cpp | 53 +- .../zip/juce_GZIPDecompressorInputStream.h | 2 +- modules/juce_core/zip/juce_ZipFile.cpp | 6 +- modules/juce_core/zip/juce_ZipFile.h | 2 +- .../encryption/juce_BlowFish.cpp | 13 +- .../encryption/juce_BlowFish.h | 11 +- .../encryption/juce_Primes.cpp | 11 +- .../encryption/juce_Primes.h | 11 +- .../encryption/juce_RSAKey.cpp | 11 +- .../encryption/juce_RSAKey.h | 11 +- .../juce_cryptography/hashing/juce_MD5.cpp | 21 +- modules/juce_cryptography/hashing/juce_MD5.h | 11 +- .../juce_cryptography/hashing/juce_SHA256.cpp | 25 +- .../juce_cryptography/hashing/juce_SHA256.h | 11 +- .../hashing/juce_Whirlpool.cpp | 20 +- .../hashing/juce_Whirlpool.h | 11 +- .../juce_cryptography/juce_cryptography.cpp | 11 +- modules/juce_cryptography/juce_cryptography.h | 15 +- .../juce_cryptography/juce_cryptography.mm | 11 +- .../juce_ApplicationProperties.cpp | 11 +- .../juce_ApplicationProperties.h | 11 +- .../app_properties/juce_PropertiesFile.cpp | 23 +- .../app_properties/juce_PropertiesFile.h | 11 +- .../juce_data_structures.cpp | 11 +- .../juce_data_structures.h | 15 +- .../juce_data_structures.mm | 11 +- .../undomanager/juce_UndoManager.cpp | 11 +- .../undomanager/juce_UndoManager.h | 11 +- .../undomanager/juce_UndoableAction.h | 11 +- .../values/juce_CachedValue.cpp | 11 +- .../values/juce_CachedValue.h | 11 +- .../values/juce_Value.cpp | 11 +- .../juce_data_structures/values/juce_Value.h | 11 +- .../values/juce_ValueTree.cpp | 11 +- .../values/juce_ValueTree.h | 12 +- .../values/juce_ValueTreeSynchroniser.cpp | 14 +- .../values/juce_ValueTreeSynchroniser.h | 11 +- .../values/juce_ValueWithDefault.cpp | 11 +- .../values/juce_ValueWithDefault.h | 15 +- modules/juce_dsp/containers/juce_AudioBlock.h | 28 +- .../containers/juce_AudioBlock_test.cpp | 18 +- .../containers/juce_FixedSizeFunction.h | 243 + .../juce_FixedSizeFunction_test.cpp | 352 + .../juce_dsp/containers/juce_SIMDRegister.h | 49 +- .../containers/juce_SIMDRegister_Impl.h | 43 +- .../containers/juce_SIMDRegister_test.cpp | 13 +- .../filter_design/juce_FilterDesign.cpp | 43 +- .../filter_design/juce_FilterDesign.h | 11 +- .../juce_dsp/frequency/juce_Convolution.cpp | 1763 ++- modules/juce_dsp/frequency/juce_Convolution.h | 284 +- .../frequency/juce_Convolution_test.cpp | 521 + modules/juce_dsp/frequency/juce_FFT.cpp | 168 +- modules/juce_dsp/frequency/juce_FFT.h | 11 +- modules/juce_dsp/frequency/juce_FFT_test.cpp | 11 +- modules/juce_dsp/frequency/juce_Windowing.cpp | 38 +- modules/juce_dsp/frequency/juce_Windowing.h | 11 +- modules/juce_dsp/juce_dsp.cpp | 44 +- modules/juce_dsp/juce_dsp.h | 52 +- modules/juce_dsp/juce_dsp.mm | 11 +- .../maths/juce_FastMathApproximations.h | 11 +- modules/juce_dsp/maths/juce_LogRampedValue.h | 11 +- .../maths/juce_LogRampedValue_test.cpp | 11 +- modules/juce_dsp/maths/juce_LookupTable.cpp | 19 +- modules/juce_dsp/maths/juce_LookupTable.h | 23 +- modules/juce_dsp/maths/juce_Matrix.cpp | 11 +- modules/juce_dsp/maths/juce_Matrix.h | 13 +- modules/juce_dsp/maths/juce_Matrix_test.cpp | 11 +- modules/juce_dsp/maths/juce_Phase.h | 11 +- modules/juce_dsp/maths/juce_Polynomial.h | 11 +- .../juce_dsp/maths/juce_SpecialFunctions.cpp | 11 +- .../juce_dsp/maths/juce_SpecialFunctions.h | 11 +- .../native/juce_avx_SIMDNativeOps.cpp | 11 +- .../juce_dsp/native/juce_avx_SIMDNativeOps.h | 20 +- .../native/juce_fallback_SIMDNativeOps.h | 13 +- .../native/juce_neon_SIMDNativeOps.cpp | 11 +- .../juce_dsp/native/juce_neon_SIMDNativeOps.h | 20 +- .../native/juce_sse_SIMDNativeOps.cpp | 11 +- .../juce_dsp/native/juce_sse_SIMDNativeOps.h | 20 +- .../processors/juce_BallisticsFilter.cpp | 130 + .../processors/juce_BallisticsFilter.h | 150 + .../juce_dsp/processors/juce_DelayLine.cpp | 128 + modules/juce_dsp/processors/juce_DelayLine.h | 324 + .../juce_dsp/processors/juce_DryWetMixer.cpp | 179 + .../juce_dsp/processors/juce_DryWetMixer.h | 118 + .../juce_dsp/processors/juce_FIRFilter.cpp | 11 +- modules/juce_dsp/processors/juce_FIRFilter.h | 11 +- .../processors/juce_FIRFilter_test.cpp | 11 +- .../processors/juce_FirstOrderTPTFilter.cpp | 121 + .../processors/juce_FirstOrderTPTFilter.h | 151 + .../juce_dsp/processors/juce_IIRFilter.cpp | 11 +- modules/juce_dsp/processors/juce_IIRFilter.h | 17 +- .../juce_dsp/processors/juce_IIRFilter_Impl.h | 11 +- .../juce_dsp/processors/juce_LadderFilter.cpp | 170 - .../processors/juce_LinkwitzRileyFilter.cpp | 149 + .../processors/juce_LinkwitzRileyFilter.h | 143 + .../juce_dsp/processors/juce_Oversampling.cpp | 85 +- .../juce_dsp/processors/juce_Oversampling.h | 126 +- modules/juce_dsp/processors/juce_Panner.cpp | 143 + modules/juce_dsp/processors/juce_Panner.h | 122 + .../juce_dsp/processors/juce_ProcessContext.h | 11 +- .../juce_dsp/processors/juce_ProcessorChain.h | 181 +- .../processors/juce_ProcessorChain_test.cpp | 141 + .../processors/juce_ProcessorDuplicator.h | 11 +- .../processors/juce_ProcessorWrapper.h | 11 +- .../processors/juce_StateVariableFilter.h | 56 +- .../juce_StateVariableTPTFilter.cpp | 137 + .../processors/juce_StateVariableTPTFilter.h | 166 + .../{processors => widgets}/juce_Bias.h | 15 +- modules/juce_dsp/widgets/juce_Chorus.cpp | 138 + modules/juce_dsp/widgets/juce_Chorus.h | 164 + modules/juce_dsp/widgets/juce_Compressor.cpp | 121 + modules/juce_dsp/widgets/juce_Compressor.h | 110 + .../{processors => widgets}/juce_Gain.h | 11 +- .../juce_dsp/widgets/juce_LadderFilter.cpp | 176 + .../juce_LadderFilter.h | 95 +- modules/juce_dsp/widgets/juce_Limiter.cpp | 98 + modules/juce_dsp/widgets/juce_Limiter.h | 105 + modules/juce_dsp/widgets/juce_NoiseGate.cpp | 129 + modules/juce_dsp/widgets/juce_NoiseGate.h | 110 + .../{processors => widgets}/juce_Oscillator.h | 17 +- modules/juce_dsp/widgets/juce_Phaser.cpp | 154 + modules/juce_dsp/widgets/juce_Phaser.h | 206 + .../{processors => widgets}/juce_Reverb.h | 13 +- .../{processors => widgets}/juce_WaveShaper.h | 13 +- .../broadcasters/juce_ActionBroadcaster.cpp | 2 +- .../broadcasters/juce_ActionBroadcaster.h | 2 +- .../broadcasters/juce_ActionListener.h | 2 +- .../broadcasters/juce_AsyncUpdater.cpp | 2 +- .../broadcasters/juce_AsyncUpdater.h | 2 +- .../broadcasters/juce_ChangeBroadcaster.cpp | 2 +- .../broadcasters/juce_ChangeBroadcaster.h | 2 +- .../broadcasters/juce_ChangeListener.h | 2 +- .../juce_ConnectedChildProcess.cpp | 4 +- .../interprocess/juce_ConnectedChildProcess.h | 2 +- .../juce_InterprocessConnection.cpp | 151 +- .../juce_InterprocessConnection.h | 30 +- .../juce_InterprocessConnectionServer.cpp | 4 +- .../juce_InterprocessConnectionServer.h | 2 +- .../juce_NetworkServiceDiscovery.cpp | 21 +- .../juce_NetworkServiceDiscovery.h | 2 +- modules/juce_events/juce_events.cpp | 13 +- modules/juce_events/juce_events.h | 8 +- modules/juce_events/juce_events.mm | 2 +- .../messages/juce_ApplicationBase.cpp | 6 +- .../messages/juce_ApplicationBase.h | 2 +- .../messages/juce_CallbackMessage.h | 2 +- .../messages/juce_DeletedAtShutdown.cpp | 15 +- .../messages/juce_DeletedAtShutdown.h | 2 +- .../messages/juce_Initialisation.h | 2 +- modules/juce_events/messages/juce_Message.h | 2 +- .../messages/juce_MessageListener.cpp | 2 +- .../messages/juce_MessageListener.h | 2 +- .../messages/juce_MessageManager.cpp | 4 +- .../messages/juce_MessageManager.h | 7 +- .../juce_MountedVolumeListChangeDetector.h | 2 +- .../messages/juce_NotificationType.h | 2 +- .../native/juce_android_Messaging.cpp | 2 +- .../native/juce_ios_MessageManager.mm | 2 +- .../juce_events/native/juce_linux_EventLoop.h | 4 +- .../native/juce_linux_Messaging.cpp | 65 +- .../native/juce_mac_MessageManager.mm | 8 +- .../native/juce_osx_MessageQueue.h | 2 +- .../native/juce_win32_HiddenMessageWindow.h | 11 +- .../native/juce_win32_Messaging.cpp | 14 +- .../native/juce_win32_WinRTWrapper.cpp | 2 +- .../native/juce_win32_WinRTWrapper.h | 3 +- .../juce_events/timers/juce_MultiTimer.cpp | 2 +- modules/juce_events/timers/juce_MultiTimer.h | 2 +- modules/juce_events/timers/juce_Timer.cpp | 18 +- modules/juce_events/timers/juce_Timer.h | 2 +- modules/juce_graphics/colour/juce_Colour.cpp | 439 +- modules/juce_graphics/colour/juce_Colour.h | 81 +- .../colour/juce_ColourGradient.cpp | 11 +- .../colour/juce_ColourGradient.h | 11 +- modules/juce_graphics/colour/juce_Colours.cpp | 11 +- modules/juce_graphics/colour/juce_Colours.h | 11 +- .../juce_graphics/colour/juce_FillType.cpp | 11 +- modules/juce_graphics/colour/juce_FillType.h | 11 +- .../juce_graphics/colour/juce_PixelFormats.h | 11 +- .../contexts/juce_GraphicsContext.cpp | 21 +- .../contexts/juce_GraphicsContext.h | 11 +- .../contexts/juce_LowLevelGraphicsContext.h | 11 +- ...uce_LowLevelGraphicsPostScriptRenderer.cpp | 15 +- .../juce_LowLevelGraphicsPostScriptRenderer.h | 11 +- .../juce_LowLevelGraphicsSoftwareRenderer.cpp | 11 +- .../juce_LowLevelGraphicsSoftwareRenderer.h | 11 +- .../effects/juce_DropShadowEffect.cpp | 23 +- .../effects/juce_DropShadowEffect.h | 11 +- .../juce_graphics/effects/juce_GlowEffect.cpp | 11 +- .../juce_graphics/effects/juce_GlowEffect.h | 11 +- .../effects/juce_ImageEffectFilter.h | 11 +- .../fonts/juce_AttributedString.cpp | 11 +- .../fonts/juce_AttributedString.h | 11 +- .../fonts/juce_CustomTypeface.cpp | 11 +- .../juce_graphics/fonts/juce_CustomTypeface.h | 11 +- modules/juce_graphics/fonts/juce_Font.cpp | 41 +- modules/juce_graphics/fonts/juce_Font.h | 13 +- .../fonts/juce_GlyphArrangement.cpp | 19 +- .../fonts/juce_GlyphArrangement.h | 11 +- .../juce_graphics/fonts/juce_TextLayout.cpp | 15 +- modules/juce_graphics/fonts/juce_TextLayout.h | 11 +- modules/juce_graphics/fonts/juce_Typeface.cpp | 13 +- modules/juce_graphics/fonts/juce_Typeface.h | 11 +- .../geometry/juce_AffineTransform.cpp | 52 +- .../geometry/juce_AffineTransform.h | 27 +- .../juce_graphics/geometry/juce_BorderSize.h | 11 +- .../juce_graphics/geometry/juce_EdgeTable.cpp | 11 +- .../juce_graphics/geometry/juce_EdgeTable.h | 11 +- modules/juce_graphics/geometry/juce_Line.h | 11 +- .../geometry/juce_Parallelogram.h | 16 +- modules/juce_graphics/geometry/juce_Path.cpp | 21 +- modules/juce_graphics/geometry/juce_Path.h | 11 +- .../geometry/juce_PathIterator.cpp | 15 +- .../geometry/juce_PathIterator.h | 11 +- .../geometry/juce_PathStrokeType.cpp | 11 +- .../geometry/juce_PathStrokeType.h | 11 +- modules/juce_graphics/geometry/juce_Point.h | 105 +- .../juce_graphics/geometry/juce_Rectangle.h | 64 +- .../geometry/juce_RectangleList.h | 11 +- .../image_formats/juce_GIFLoader.cpp | 11 +- .../image_formats/juce_JPEGLoader.cpp | 61 +- .../image_formats/juce_PNGLoader.cpp | 65 +- modules/juce_graphics/images/juce_Image.cpp | 20 +- modules/juce_graphics/images/juce_Image.h | 11 +- .../juce_graphics/images/juce_ImageCache.cpp | 11 +- .../juce_graphics/images/juce_ImageCache.h | 11 +- .../images/juce_ImageConvolutionKernel.cpp | 11 +- .../images/juce_ImageConvolutionKernel.h | 11 +- .../images/juce_ImageFileFormat.cpp | 11 +- .../images/juce_ImageFileFormat.h | 11 +- modules/juce_graphics/juce_graphics.cpp | 24 +- modules/juce_graphics/juce_graphics.h | 19 +- modules/juce_graphics/juce_graphics.mm | 11 +- .../native/juce_RenderingHelpers.h | 44 +- .../native/juce_android_Fonts.cpp | 13 +- .../native/juce_android_GraphicsContext.cpp | 11 +- .../native/juce_android_IconHelpers.cpp | 11 +- .../native/juce_freetype_Fonts.cpp | 39 +- .../juce_graphics/native/juce_linux_Fonts.cpp | 11 +- .../native/juce_linux_IconHelpers.cpp | 11 +- .../native/juce_mac_CoreGraphicsContext.h | 56 +- .../native/juce_mac_CoreGraphicsContext.mm | 351 +- .../native/juce_mac_CoreGraphicsHelpers.h | 11 +- .../juce_graphics/native/juce_mac_Fonts.mm | 85 +- .../native/juce_mac_IconHelpers.cpp | 11 +- .../juce_win32_Direct2DGraphicsContext.cpp | 13 +- .../juce_win32_Direct2DGraphicsContext.h | 11 +- .../juce_win32_DirectWriteTypeLayout.cpp | 16 +- .../native/juce_win32_DirectWriteTypeface.cpp | 11 +- .../juce_graphics/native/juce_win32_Fonts.cpp | 49 +- .../native/juce_win32_IconHelpers.cpp | 11 +- .../placement/juce_Justification.h | 11 +- .../placement/juce_RectanglePlacement.cpp | 11 +- .../placement/juce_RectanglePlacement.h | 11 +- .../application/juce_Application.cpp | 11 +- .../application/juce_Application.h | 13 +- .../buttons/juce_ArrowButton.cpp | 13 +- .../buttons/juce_ArrowButton.h | 11 +- .../juce_gui_basics/buttons/juce_Button.cpp | 11 +- modules/juce_gui_basics/buttons/juce_Button.h | 11 +- .../buttons/juce_DrawableButton.cpp | 11 +- .../buttons/juce_DrawableButton.h | 11 +- .../buttons/juce_HyperlinkButton.cpp | 13 +- .../buttons/juce_HyperlinkButton.h | 11 +- .../buttons/juce_ImageButton.cpp | 19 +- .../buttons/juce_ImageButton.h | 11 +- .../buttons/juce_ShapeButton.cpp | 11 +- .../buttons/juce_ShapeButton.h | 11 +- .../buttons/juce_TextButton.cpp | 11 +- .../juce_gui_basics/buttons/juce_TextButton.h | 11 +- .../buttons/juce_ToggleButton.cpp | 11 +- .../buttons/juce_ToggleButton.h | 11 +- .../buttons/juce_ToolbarButton.cpp | 11 +- .../buttons/juce_ToolbarButton.h | 11 +- .../commands/juce_ApplicationCommandID.h | 11 +- .../commands/juce_ApplicationCommandInfo.cpp | 11 +- .../commands/juce_ApplicationCommandInfo.h | 11 +- .../juce_ApplicationCommandManager.cpp | 11 +- .../commands/juce_ApplicationCommandManager.h | 11 +- .../juce_ApplicationCommandTarget.cpp | 11 +- .../commands/juce_ApplicationCommandTarget.h | 11 +- .../commands/juce_KeyPressMappingSet.cpp | 11 +- .../commands/juce_KeyPressMappingSet.h | 13 +- .../components/juce_CachedComponentImage.h | 11 +- .../components/juce_Component.cpp | 98 +- .../components/juce_Component.h | 33 +- .../components/juce_ComponentListener.cpp | 11 +- .../components/juce_ComponentListener.h | 11 +- .../components/juce_ModalComponentManager.cpp | 17 +- .../components/juce_ModalComponentManager.h | 13 +- .../juce_gui_basics/desktop/juce_Desktop.cpp | 16 +- .../juce_gui_basics/desktop/juce_Desktop.h | 19 +- .../juce_gui_basics/desktop/juce_Displays.cpp | 161 +- .../juce_gui_basics/desktop/juce_Displays.h | 43 +- .../drawables/juce_Drawable.cpp | 11 +- .../juce_gui_basics/drawables/juce_Drawable.h | 17 +- .../drawables/juce_DrawableComposite.cpp | 11 +- .../drawables/juce_DrawableComposite.h | 11 +- .../drawables/juce_DrawableImage.cpp | 11 +- .../drawables/juce_DrawableImage.h | 11 +- .../drawables/juce_DrawablePath.cpp | 11 +- .../drawables/juce_DrawablePath.h | 11 +- .../drawables/juce_DrawableRectangle.cpp | 11 +- .../drawables/juce_DrawableRectangle.h | 11 +- .../drawables/juce_DrawableShape.cpp | 11 +- .../drawables/juce_DrawableShape.h | 11 +- .../drawables/juce_DrawableText.cpp | 11 +- .../drawables/juce_DrawableText.h | 11 +- .../drawables/juce_SVGParser.cpp | 147 +- .../filebrowser/juce_ContentSharer.cpp | 43 +- .../filebrowser/juce_ContentSharer.h | 27 +- ...juce_DirectoryContentsDisplayComponent.cpp | 11 +- .../juce_DirectoryContentsDisplayComponent.h | 11 +- .../juce_DirectoryContentsList.cpp | 36 +- .../filebrowser/juce_DirectoryContentsList.h | 13 +- .../filebrowser/juce_FileBrowserComponent.cpp | 30 +- .../filebrowser/juce_FileBrowserComponent.h | 11 +- .../filebrowser/juce_FileBrowserListener.h | 11 +- .../filebrowser/juce_FileChooser.cpp | 15 +- .../filebrowser/juce_FileChooser.h | 15 +- .../filebrowser/juce_FileChooserDialogBox.cpp | 13 +- .../filebrowser/juce_FileChooserDialogBox.h | 11 +- .../filebrowser/juce_FileListComponent.cpp | 11 +- .../filebrowser/juce_FileListComponent.h | 11 +- .../filebrowser/juce_FilePreviewComponent.h | 11 +- .../juce_FileSearchPathListComponent.cpp | 13 +- .../juce_FileSearchPathListComponent.h | 11 +- .../filebrowser/juce_FileTreeComponent.cpp | 16 +- .../filebrowser/juce_FileTreeComponent.h | 11 +- .../filebrowser/juce_FilenameComponent.cpp | 11 +- .../filebrowser/juce_FilenameComponent.h | 11 +- .../juce_ImagePreviewComponent.cpp | 11 +- .../filebrowser/juce_ImagePreviewComponent.h | 11 +- modules/juce_gui_basics/juce_gui_basics.cpp | 97 +- modules/juce_gui_basics/juce_gui_basics.h | 74 +- modules/juce_gui_basics/juce_gui_basics.mm | 11 +- .../keyboard/juce_CaretComponent.cpp | 11 +- .../keyboard/juce_CaretComponent.h | 11 +- .../keyboard/juce_KeyListener.cpp | 11 +- .../keyboard/juce_KeyListener.h | 11 +- .../keyboard/juce_KeyPress.cpp | 11 +- .../juce_gui_basics/keyboard/juce_KeyPress.h | 15 +- .../keyboard/juce_KeyboardFocusTraverser.cpp | 11 +- .../keyboard/juce_KeyboardFocusTraverser.h | 11 +- .../keyboard/juce_ModifierKeys.cpp | 11 +- .../keyboard/juce_ModifierKeys.h | 11 +- .../keyboard/juce_SystemClipboard.h | 11 +- .../keyboard/juce_TextEditorKeyMapper.h | 11 +- .../keyboard/juce_TextInputTarget.h | 11 +- .../layout/juce_AnimatedPosition.h | 11 +- .../layout/juce_AnimatedPositionBehaviours.h | 11 +- .../layout/juce_ComponentAnimator.cpp | 17 +- .../layout/juce_ComponentAnimator.h | 11 +- .../juce_ComponentBoundsConstrainer.cpp | 13 +- .../layout/juce_ComponentBoundsConstrainer.h | 11 +- .../layout/juce_ComponentBuilder.cpp | 11 +- .../layout/juce_ComponentBuilder.h | 11 +- .../layout/juce_ComponentMovementWatcher.cpp | 11 +- .../layout/juce_ComponentMovementWatcher.h | 11 +- .../layout/juce_ConcertinaPanel.cpp | 11 +- .../layout/juce_ConcertinaPanel.h | 11 +- .../juce_gui_basics/layout/juce_FlexBox.cpp | 11 +- modules/juce_gui_basics/layout/juce_FlexBox.h | 11 +- .../juce_gui_basics/layout/juce_FlexItem.h | 11 +- modules/juce_gui_basics/layout/juce_Grid.cpp | 29 +- modules/juce_gui_basics/layout/juce_Grid.h | 11 +- .../juce_gui_basics/layout/juce_GridItem.cpp | 11 +- .../juce_gui_basics/layout/juce_GridItem.h | 11 +- .../layout/juce_GroupComponent.cpp | 11 +- .../layout/juce_GroupComponent.h | 11 +- .../layout/juce_MultiDocumentPanel.cpp | 11 +- .../layout/juce_MultiDocumentPanel.h | 11 +- .../layout/juce_ResizableBorderComponent.cpp | 11 +- .../layout/juce_ResizableBorderComponent.h | 13 +- .../layout/juce_ResizableCornerComponent.cpp | 11 +- .../layout/juce_ResizableCornerComponent.h | 11 +- .../layout/juce_ResizableEdgeComponent.cpp | 11 +- .../layout/juce_ResizableEdgeComponent.h | 13 +- .../juce_gui_basics/layout/juce_ScrollBar.cpp | 11 +- .../juce_gui_basics/layout/juce_ScrollBar.h | 11 +- .../juce_gui_basics/layout/juce_SidePanel.cpp | 11 +- .../juce_gui_basics/layout/juce_SidePanel.h | 13 +- .../layout/juce_StretchableLayoutManager.cpp | 11 +- .../layout/juce_StretchableLayoutManager.h | 11 +- .../juce_StretchableLayoutResizerBar.cpp | 11 +- .../layout/juce_StretchableLayoutResizerBar.h | 11 +- .../layout/juce_StretchableObjectResizer.cpp | 11 +- .../layout/juce_StretchableObjectResizer.h | 11 +- .../layout/juce_TabbedButtonBar.cpp | 11 +- .../layout/juce_TabbedButtonBar.h | 11 +- .../layout/juce_TabbedComponent.cpp | 12 +- .../layout/juce_TabbedComponent.h | 11 +- .../juce_gui_basics/layout/juce_Viewport.cpp | 13 +- .../juce_gui_basics/layout/juce_Viewport.h | 11 +- .../lookandfeel/juce_LookAndFeel.cpp | 11 +- .../lookandfeel/juce_LookAndFeel.h | 11 +- .../lookandfeel/juce_LookAndFeel_V1.cpp | 151 +- .../lookandfeel/juce_LookAndFeel_V1.h | 11 +- .../lookandfeel/juce_LookAndFeel_V2.cpp | 413 +- .../lookandfeel/juce_LookAndFeel_V2.h | 45 +- .../lookandfeel/juce_LookAndFeel_V3.cpp | 66 +- .../lookandfeel/juce_LookAndFeel_V3.h | 11 +- .../lookandfeel/juce_LookAndFeel_V4.cpp | 127 +- .../lookandfeel/juce_LookAndFeel_V4.h | 11 +- .../menus/juce_BurgerMenuComponent.cpp | 20 +- .../menus/juce_BurgerMenuComponent.h | 14 +- .../menus/juce_MenuBarComponent.cpp | 11 +- .../menus/juce_MenuBarComponent.h | 11 +- .../menus/juce_MenuBarModel.cpp | 11 +- .../juce_gui_basics/menus/juce_MenuBarModel.h | 11 +- .../juce_gui_basics/menus/juce_PopupMenu.cpp | 472 +- .../juce_gui_basics/menus/juce_PopupMenu.h | 93 +- .../misc/juce_BubbleComponent.cpp | 11 +- .../misc/juce_BubbleComponent.h | 11 +- .../misc/juce_DropShadower.cpp | 11 +- .../juce_gui_basics/misc/juce_DropShadower.h | 11 +- .../misc/juce_JUCESplashScreen.cpp | 190 +- .../misc/juce_JUCESplashScreen.h | 17 +- .../mouse/juce_ComponentDragger.cpp | 11 +- .../mouse/juce_ComponentDragger.h | 11 +- .../mouse/juce_DragAndDropContainer.cpp | 13 +- .../mouse/juce_DragAndDropContainer.h | 11 +- .../mouse/juce_DragAndDropTarget.h | 11 +- .../mouse/juce_FileDragAndDropTarget.h | 11 +- .../mouse/juce_LassoComponent.h | 11 +- .../mouse/juce_MouseCursor.cpp | 11 +- .../juce_gui_basics/mouse/juce_MouseCursor.h | 11 +- .../juce_gui_basics/mouse/juce_MouseEvent.cpp | 11 +- .../juce_gui_basics/mouse/juce_MouseEvent.h | 11 +- .../mouse/juce_MouseInactivityDetector.cpp | 11 +- .../mouse/juce_MouseInactivityDetector.h | 11 +- .../mouse/juce_MouseInputSource.cpp | 15 +- .../mouse/juce_MouseInputSource.h | 11 +- .../mouse/juce_MouseListener.cpp | 11 +- .../mouse/juce_MouseListener.h | 11 +- .../mouse/juce_SelectedItemSet.h | 11 +- .../mouse/juce_TextDragAndDropTarget.h | 11 +- .../mouse/juce_TooltipClient.h | 11 +- .../juce/ComponentPeerView.java | 27 +- .../rmsl/juce/JuceContentProviderCursor.java | 53 + .../juce/JuceContentProviderFileObserver.java | 49 + .../app/com/rmsl/juce/JuceActivity.java | 45 + .../juce/JuceSharingContentProvider.java | 73 +- .../app/com/roli/juce/JuceActivity.java | 20 - .../native/juce_MultiTouchMapper.h | 24 +- .../native/juce_android_ContentSharer.cpp | 177 +- .../native/juce_android_FileChooser.cpp | 11 +- .../native/juce_android_Windowing.cpp | 337 +- .../native/juce_common_MimeTypes.cpp | 53 +- .../native/juce_ios_ContentSharer.cpp | 14 +- .../native/juce_ios_FileChooser.mm | 139 +- .../native/juce_ios_UIViewComponentPeer.mm | 469 +- .../native/juce_ios_Windowing.mm | 97 +- .../native/juce_linux_FileChooser.cpp | 32 +- .../native/juce_linux_Windowing.cpp | 696 + .../juce_gui_basics/native/juce_linux_X11.cpp | 339 - .../juce_gui_basics/native/juce_linux_X11.h | 177 - .../native/juce_linux_X11_Clipboard.cpp | 280 - .../native/juce_linux_X11_Windowing.cpp | 4174 ----- .../native/juce_mac_FileChooser.mm | 116 +- .../native/juce_mac_MainMenu.mm | 60 +- .../native/juce_mac_MouseCursor.mm | 12 +- .../native/juce_mac_NSViewComponentPeer.mm | 149 +- .../native/juce_mac_Windowing.mm | 13 +- .../native/juce_win32_DragAndDrop.cpp | 45 +- .../native/juce_win32_FileChooser.cpp | 274 +- .../native/juce_win32_Windowing.cpp | 377 +- .../native/x11/juce_linux_X11_DragAndDrop.cpp | 550 + .../native/x11/juce_linux_X11_Symbols.cpp | 238 + .../native/x11/juce_linux_X11_Symbols.h | 612 + .../native/x11/juce_linux_XWindowSystem.cpp | 3489 ++++ .../native/x11/juce_linux_XWindowSystem.h | 257 + .../positioning/juce_MarkerList.cpp | 11 +- .../positioning/juce_MarkerList.h | 11 +- .../positioning/juce_RelativeCoordinate.cpp | 11 +- .../positioning/juce_RelativeCoordinate.h | 11 +- .../juce_RelativeCoordinatePositioner.cpp | 25 +- .../juce_RelativeCoordinatePositioner.h | 11 +- .../juce_RelativeParallelogram.cpp | 11 +- .../positioning/juce_RelativeParallelogram.h | 11 +- .../positioning/juce_RelativePoint.cpp | 11 +- .../positioning/juce_RelativePoint.h | 11 +- .../positioning/juce_RelativePointPath.cpp | 11 +- .../positioning/juce_RelativePointPath.h | 11 +- .../positioning/juce_RelativeRectangle.cpp | 20 +- .../positioning/juce_RelativeRectangle.h | 11 +- .../juce_BooleanPropertyComponent.cpp | 11 +- .../juce_BooleanPropertyComponent.h | 11 +- .../juce_ButtonPropertyComponent.cpp | 11 +- .../properties/juce_ButtonPropertyComponent.h | 11 +- .../juce_ChoicePropertyComponent.cpp | 11 +- .../properties/juce_ChoicePropertyComponent.h | 11 +- .../juce_MultiChoicePropertyComponent.cpp | 71 +- .../juce_MultiChoicePropertyComponent.h | 26 +- .../properties/juce_PropertyComponent.cpp | 11 +- .../properties/juce_PropertyComponent.h | 11 +- .../properties/juce_PropertyPanel.cpp | 21 +- .../properties/juce_PropertyPanel.h | 11 +- .../juce_SliderPropertyComponent.cpp | 11 +- .../properties/juce_SliderPropertyComponent.h | 11 +- .../properties/juce_TextPropertyComponent.cpp | 13 +- .../properties/juce_TextPropertyComponent.h | 11 +- .../juce_gui_basics/widgets/juce_ComboBox.cpp | 11 +- .../juce_gui_basics/widgets/juce_ComboBox.h | 16 +- .../widgets/juce_ImageComponent.cpp | 11 +- .../widgets/juce_ImageComponent.h | 11 +- .../juce_gui_basics/widgets/juce_Label.cpp | 11 +- modules/juce_gui_basics/widgets/juce_Label.h | 11 +- .../juce_gui_basics/widgets/juce_ListBox.cpp | 27 +- .../juce_gui_basics/widgets/juce_ListBox.h | 13 +- .../widgets/juce_ProgressBar.cpp | 11 +- .../widgets/juce_ProgressBar.h | 11 +- .../juce_gui_basics/widgets/juce_Slider.cpp | 21 +- modules/juce_gui_basics/widgets/juce_Slider.h | 15 +- .../widgets/juce_TableHeaderComponent.cpp | 11 +- .../widgets/juce_TableHeaderComponent.h | 11 +- .../widgets/juce_TableListBox.cpp | 25 +- .../widgets/juce_TableListBox.h | 13 +- .../widgets/juce_TextEditor.cpp | 293 +- .../juce_gui_basics/widgets/juce_TextEditor.h | 42 +- .../juce_gui_basics/widgets/juce_Toolbar.cpp | 60 +- .../juce_gui_basics/widgets/juce_Toolbar.h | 13 +- .../widgets/juce_ToolbarItemComponent.cpp | 11 +- .../widgets/juce_ToolbarItemComponent.h | 11 +- .../widgets/juce_ToolbarItemFactory.h | 11 +- .../widgets/juce_ToolbarItemPalette.cpp | 11 +- .../widgets/juce_ToolbarItemPalette.h | 11 +- .../juce_gui_basics/widgets/juce_TreeView.cpp | 19 +- .../juce_gui_basics/widgets/juce_TreeView.h | 15 +- .../windows/juce_AlertWindow.cpp | 27 +- .../windows/juce_AlertWindow.h | 11 +- .../windows/juce_CallOutBox.cpp | 49 +- .../juce_gui_basics/windows/juce_CallOutBox.h | 27 +- .../windows/juce_ComponentPeer.cpp | 25 +- .../windows/juce_ComponentPeer.h | 17 +- .../windows/juce_DialogWindow.cpp | 11 +- .../windows/juce_DialogWindow.h | 11 +- .../windows/juce_DocumentWindow.cpp | 11 +- .../windows/juce_DocumentWindow.h | 11 +- .../windows/juce_NativeMessageBox.h | 11 +- .../windows/juce_ResizableWindow.cpp | 17 +- .../windows/juce_ResizableWindow.h | 11 +- .../windows/juce_ThreadWithProgressWindow.cpp | 11 +- .../windows/juce_ThreadWithProgressWindow.h | 11 +- .../windows/juce_TooltipWindow.cpp | 13 +- .../windows/juce_TooltipWindow.h | 11 +- .../windows/juce_TopLevelWindow.cpp | 11 +- .../windows/juce_TopLevelWindow.h | 11 +- .../juce_CPlusPlusCodeTokeniser.cpp | 11 +- .../code_editor/juce_CPlusPlusCodeTokeniser.h | 11 +- .../juce_CPlusPlusCodeTokeniserFunctions.h | 13 +- .../code_editor/juce_CodeDocument.cpp | 13 +- .../code_editor/juce_CodeDocument.h | 11 +- .../code_editor/juce_CodeEditorComponent.cpp | 32 +- .../code_editor/juce_CodeEditorComponent.h | 13 +- .../code_editor/juce_CodeTokeniser.h | 11 +- .../code_editor/juce_LuaCodeTokeniser.cpp | 11 +- .../code_editor/juce_LuaCodeTokeniser.h | 11 +- .../code_editor/juce_XMLCodeTokeniser.cpp | 11 +- .../code_editor/juce_XMLCodeTokeniser.h | 11 +- .../documents/juce_FileBasedDocument.cpp | 87 +- .../documents/juce_FileBasedDocument.h | 21 +- .../embedding/juce_ActiveXControlComponent.h | 11 +- .../embedding/juce_AndroidViewComponent.h | 13 +- .../embedding/juce_HWNDComponent.h | 83 + .../embedding/juce_NSViewComponent.h | 16 +- .../juce_ScopedDPIAwarenessDisabler.h | 11 +- .../embedding/juce_UIViewComponent.h | 16 +- .../embedding/juce_XEmbedComponent.h | 14 +- modules/juce_gui_extra/juce_gui_extra.cpp | 112 +- modules/juce_gui_extra/juce_gui_extra.h | 35 +- modules/juce_gui_extra/juce_gui_extra.mm | 11 +- .../misc/juce_AnimatedAppComponent.cpp | 11 +- .../misc/juce_AnimatedAppComponent.h | 11 +- .../juce_gui_extra/misc/juce_AppleRemote.h | 11 +- .../misc/juce_BubbleMessageComponent.cpp | 13 +- .../misc/juce_BubbleMessageComponent.h | 17 +- .../misc/juce_ColourSelector.cpp | 25 +- .../juce_gui_extra/misc/juce_ColourSelector.h | 11 +- .../misc/juce_KeyMappingEditorComponent.cpp | 17 +- .../misc/juce_KeyMappingEditorComponent.h | 11 +- .../misc/juce_LiveConstantEditor.cpp | 15 +- .../misc/juce_LiveConstantEditor.h | 11 +- .../misc/juce_PreferencesPanel.cpp | 11 +- .../misc/juce_PreferencesPanel.h | 11 +- .../misc/juce_PushNotifications.cpp | 11 +- .../misc/juce_PushNotifications.h | 11 +- .../misc/juce_RecentlyOpenedFilesList.cpp | 11 +- .../misc/juce_RecentlyOpenedFilesList.h | 11 +- .../juce_gui_extra/misc/juce_SplashScreen.cpp | 13 +- .../juce_gui_extra/misc/juce_SplashScreen.h | 11 +- .../misc/juce_SystemTrayIconComponent.cpp | 11 +- .../misc/juce_SystemTrayIconComponent.h | 11 +- .../misc/juce_WebBrowserComponent.h | 85 +- .../com/{roli => rmsl}/juce/JuceWebView.java | 27 +- .../java/app/com/rmsl/juce/JuceWebView21.java | 132 + .../juce/JuceFirebaseInstanceIdService.java | 41 + .../juce/JuceFirebaseMessagingService.java | 60 + .../juce/JuceFirebaseInstanceIdService.java | 16 - .../juce/JuceFirebaseMessagingService.java | 35 - .../native/juce_AndroidViewComponent.cpp | 13 +- .../native/juce_android_PushNotifications.cpp | 15 +- .../juce_android_WebBrowserComponent.cpp | 231 +- .../native/juce_ios_PushNotifications.cpp | 11 +- .../native/juce_ios_UIViewComponent.mm | 11 +- .../native/juce_linux_X11_SystemTrayIcon.cpp | 62 +- .../juce_linux_X11_WebBrowserComponent.cpp | 436 +- .../native/juce_linux_XEmbedComponent.cpp | 175 +- .../native/juce_mac_AppleRemote.mm | 11 +- .../juce_mac_CarbonViewWrapperComponent.h | 11 +- .../native/juce_mac_NSViewComponent.mm | 11 +- .../native/juce_mac_PushNotifications.cpp | 15 +- .../native/juce_mac_SystemTrayIcon.cpp | 19 +- .../native/juce_mac_WebBrowserComponent.mm | 475 +- .../native/juce_win32_ActiveXComponent.cpp | 35 +- .../native/juce_win32_HWNDComponent.cpp | 172 + .../native/juce_win32_SystemTrayIcon.cpp | 11 +- .../native/juce_win32_WebBrowserComponent.cpp | 631 +- .../geometry/juce_Draggable3DOrientation.h | 11 +- modules/juce_opengl/geometry/juce_Matrix3D.h | 11 +- .../juce_opengl/geometry/juce_Quaternion.h | 11 +- modules/juce_opengl/geometry/juce_Vector3D.h | 11 +- modules/juce_opengl/juce_opengl.cpp | 21 +- modules/juce_opengl/juce_opengl.h | 25 +- modules/juce_opengl/juce_opengl.mm | 11 +- .../{roli => rmsl}/juce/JuceOpenGLView.java | 27 +- .../native/juce_MissingGLDefinitions.h | 11 +- .../native/juce_OpenGLExtensions.h | 17 +- .../juce_opengl/native/juce_OpenGL_android.h | 60 +- modules/juce_opengl/native/juce_OpenGL_ios.h | 23 +- .../native/juce_OpenGL_linux_X11.h | 122 +- modules/juce_opengl/native/juce_OpenGL_osx.h | 22 +- .../juce_opengl/native/juce_OpenGL_win32.h | 48 +- .../juce_opengl/opengl/juce_OpenGLContext.cpp | 99 +- .../juce_opengl/opengl/juce_OpenGLContext.h | 14 +- .../opengl/juce_OpenGLFrameBuffer.cpp | 11 +- .../opengl/juce_OpenGLFrameBuffer.h | 11 +- .../opengl/juce_OpenGLGraphicsContext.cpp | 29 +- .../opengl/juce_OpenGLGraphicsContext.h | 22 +- .../juce_opengl/opengl/juce_OpenGLHelpers.cpp | 11 +- .../juce_opengl/opengl/juce_OpenGLHelpers.h | 11 +- .../juce_opengl/opengl/juce_OpenGLImage.cpp | 11 +- modules/juce_opengl/opengl/juce_OpenGLImage.h | 11 +- .../opengl/juce_OpenGLPixelFormat.cpp | 11 +- .../opengl/juce_OpenGLPixelFormat.h | 11 +- .../juce_opengl/opengl/juce_OpenGLRenderer.h | 11 +- .../opengl/juce_OpenGLShaderProgram.cpp | 11 +- .../opengl/juce_OpenGLShaderProgram.h | 11 +- .../juce_opengl/opengl/juce_OpenGLTexture.cpp | 12 +- .../juce_opengl/opengl/juce_OpenGLTexture.h | 11 +- .../utils/juce_OpenGLAppComponent.cpp | 11 +- .../utils/juce_OpenGLAppComponent.h | 11 +- modules/juce_osc/juce_osc.cpp | 11 +- modules/juce_osc/juce_osc.h | 17 +- modules/juce_osc/osc/juce_OSCAddress.cpp | 12 +- modules/juce_osc/osc/juce_OSCAddress.h | 11 +- modules/juce_osc/osc/juce_OSCArgument.cpp | 11 +- modules/juce_osc/osc/juce_OSCArgument.h | 11 +- modules/juce_osc/osc/juce_OSCBundle.cpp | 11 +- modules/juce_osc/osc/juce_OSCBundle.h | 11 +- modules/juce_osc/osc/juce_OSCMessage.cpp | 11 +- modules/juce_osc/osc/juce_OSCMessage.h | 11 +- modules/juce_osc/osc/juce_OSCReceiver.cpp | 11 +- modules/juce_osc/osc/juce_OSCReceiver.h | 13 +- modules/juce_osc/osc/juce_OSCSender.cpp | 11 +- modules/juce_osc/osc/juce_OSCSender.h | 11 +- modules/juce_osc/osc/juce_OSCTimeTag.cpp | 15 +- modules/juce_osc/osc/juce_OSCTimeTag.h | 11 +- modules/juce_osc/osc/juce_OSCTypes.cpp | 11 +- modules/juce_osc/osc/juce_OSCTypes.h | 11 +- .../in_app_purchases/juce_InAppPurchases.cpp | 13 +- .../in_app_purchases/juce_InAppPurchases.h | 17 +- .../juce_product_unlocking.cpp | 11 +- .../juce_product_unlocking.h | 17 +- .../juce_product_unlocking.mm | 15 +- .../marketplace/juce_KeyFileGeneration.h | 13 +- .../marketplace/juce_OnlineUnlockForm.cpp | 11 +- .../marketplace/juce_OnlineUnlockForm.h | 11 +- .../marketplace/juce_OnlineUnlockStatus.cpp | 11 +- .../marketplace/juce_OnlineUnlockStatus.h | 11 +- .../juce_TracktionMarketplaceStatus.cpp | 11 +- .../juce_TracktionMarketplaceStatus.h | 11 +- .../juce/JuceBillingClient.java | 27 +- .../native/juce_android_InAppPurchases.cpp | 17 +- .../native/juce_ios_InAppPurchases.cpp | 20 +- .../juce_video/capture/juce_CameraDevice.cpp | 24 +- .../juce_video/capture/juce_CameraDevice.h | 17 +- modules/juce_video/juce_video.cpp | 11 +- modules/juce_video/juce_video.h | 15 +- modules/juce_video/juce_video.mm | 11 +- .../CameraCaptureSessionCaptureCallback.java | 27 +- .../CameraCaptureSessionStateCallback.java | 27 +- .../juce/CameraDeviceStateCallback.java | 27 +- .../juce/JuceOrientationEventListener.java | 49 + .../juce/MediaControllerCallback.java | 27 +- .../juce/MediaSessionCallback.java | 27 +- .../juce/SystemVolumeObserver.java | 27 +- .../juce/JuceOrientationEventListener.java | 24 - .../native/juce_android_CameraDevice.h | 150 +- .../juce_video/native/juce_android_Video.h | 165 +- .../juce_video/native/juce_ios_CameraDevice.h | 95 +- .../juce_video/native/juce_mac_CameraDevice.h | 562 +- modules/juce_video/native/juce_mac_Video.h | 61 +- .../native/juce_win32_CameraDevice.h | 136 +- modules/juce_video/native/juce_win32_Video.h | 15 +- .../playback/juce_VideoComponent.cpp | 13 +- .../juce_video/playback/juce_VideoComponent.h | 15 +- 2288 files changed, 105389 insertions(+), 60036 deletions(-) create mode 100644 CMakeLists.txt create mode 100644 docs/CMake API.md rename modules/JUCE Module Format.txt => docs/JUCE Module Format.md (51%) create mode 100644 docs/README.md rename {doxygen => docs/doxygen}/Doxyfile (98%) rename {doxygen => docs/doxygen}/Makefile (56%) create mode 100644 docs/doxygen/make.bat rename {doxygen => docs/doxygen}/process_source_files.py (100%) delete mode 100644 doxygen/README.txt delete mode 100644 doxygen/make.bat delete mode 100644 examples/Assets/Impulse1.wav delete mode 100644 examples/Assets/Impulse2.wav create mode 100644 examples/Assets/reverb_ir.wav create mode 100644 examples/Audio/CMakeLists.txt create mode 100644 examples/BLOCKS/CMakeLists.txt create mode 100644 examples/CMake/AudioPlugin/CMakeLists.txt create mode 100644 examples/CMake/AudioPlugin/PluginEditor.cpp create mode 100644 examples/CMake/AudioPlugin/PluginEditor.h create mode 100644 examples/CMake/AudioPlugin/PluginProcessor.cpp create mode 100644 examples/CMake/AudioPlugin/PluginProcessor.h create mode 100644 examples/CMake/CMakeLists.txt create mode 100644 examples/CMake/ConsoleApp/CMakeLists.txt create mode 100644 examples/CMake/ConsoleApp/Main.cpp create mode 100644 examples/CMake/GuiApp/CMakeLists.txt rename extras/Projucer/Source/BinaryData/Templates/jucer_MainTemplate_SimpleWindow.cpp => examples/CMake/GuiApp/Main.cpp (64%) create mode 100644 examples/CMake/GuiApp/MainComponent.cpp create mode 100644 examples/CMake/GuiApp/MainComponent.h create mode 100644 examples/CMakeLists.txt create mode 100644 examples/DSP/CMakeLists.txt delete mode 100644 examples/DemoRunner/Builds/Android/app/src/main/assets/Impulse1.wav delete mode 100644 examples/DemoRunner/Builds/Android/app/src/main/assets/Impulse2.wav create mode 100644 examples/DemoRunner/Builds/Android/app/src/main/assets/reverb_ir.wav delete mode 100644 examples/DemoRunner/Builds/MacOSX/App.entitlements create mode 100644 examples/DemoRunner/CMakeLists.txt delete mode 100644 examples/DemoRunner/JuceLibraryCode/AppConfig.h create mode 100644 examples/GUI/CMakeLists.txt create mode 100644 examples/Plugins/CMakeLists.txt create mode 100644 examples/Plugins/MidiLoggerPluginDemo.h create mode 100644 examples/Utilities/CMakeLists.txt delete mode 100644 extras/AudioPerformanceTest/Builds/Android/app/src/main/java/com/android/vending/billing/IInAppBillingService.java delete mode 100644 extras/AudioPerformanceTest/Builds/Android/app/src/main/java/com/juce/audioperformancetest/AudioPerformanceTest.java delete mode 100644 extras/AudioPerformanceTest/Builds/Android/app/src/main/java/com/juce/audioperformancetest/SharingContentProvider.java delete mode 100644 extras/AudioPerformanceTest/Builds/MacOSX/App.entitlements delete mode 100644 extras/AudioPerformanceTest/Builds/iOS/App.entitlements create mode 100644 extras/AudioPerformanceTest/CMakeLists.txt delete mode 100644 extras/AudioPerformanceTest/JuceLibraryCode/AppConfig.h delete mode 100644 extras/AudioPluginHost/Builds/MacOSX/App.entitlements delete mode 100644 extras/AudioPluginHost/Builds/iOS/App.entitlements create mode 100644 extras/AudioPluginHost/CMakeLists.txt delete mode 100644 extras/AudioPluginHost/JuceLibraryCode/AppConfig.h rename extras/AudioPluginHost/JuceLibraryCode/{include_juce_video.mm => include_juce_dsp.cpp} (68%) rename extras/AudioPluginHost/JuceLibraryCode/{include_juce_video.cpp => include_juce_dsp.mm} (68%) delete mode 100644 extras/BinaryBuilder/Builds/MacOSX/ConsoleApp.entitlements create mode 100644 extras/BinaryBuilder/CMakeLists.txt delete mode 100644 extras/BinaryBuilder/JuceLibraryCode/AppConfig.h create mode 100644 extras/Build/CMake/JUCECheckAtomic.cmake create mode 100644 extras/Build/CMake/JUCEConfig.cmake.in create mode 100644 extras/Build/CMake/JUCEHelperTargets.cmake create mode 100644 extras/Build/CMake/JUCEUtils.cmake create mode 100644 extras/Build/CMake/LaunchScreen.storyboard create mode 100644 extras/Build/CMake/PIPAudioProcessor.cpp.in create mode 100644 extras/Build/CMake/PIPComponent.cpp.in create mode 100644 extras/Build/CMake/PIPConsole.cpp.in rename extras/{Projucer/Source/BinaryData => Build/CMake}/RecentFilesMenuTemplate.nib (100%) rename extras/{Projucer/Source/BinaryData/Templates/jucer_UnityPluginGUIScript.cs => Build/CMake/UnityPluginGUIScript.cs.in} (78%) create mode 100644 extras/Build/CMake/copyDir.cmake create mode 100644 extras/Build/CMake/juce_runtime_arch_detection.cpp create mode 100644 extras/Build/CMakeLists.txt create mode 100644 extras/Build/juce_build_tools/juce_build_tools.cpp create mode 100644 extras/Build/juce_build_tools/juce_build_tools.h create mode 100644 extras/Build/juce_build_tools/utils/juce_BinaryResourceFile.cpp create mode 100644 extras/Build/juce_build_tools/utils/juce_BinaryResourceFile.h create mode 100644 extras/Build/juce_build_tools/utils/juce_BuildHelperFunctions.cpp create mode 100644 extras/Build/juce_build_tools/utils/juce_BuildHelperFunctions.h create mode 100644 extras/Build/juce_build_tools/utils/juce_CppTokeniserFunctions.cpp create mode 100644 extras/Build/juce_build_tools/utils/juce_Entitlements.cpp create mode 100644 extras/Build/juce_build_tools/utils/juce_Entitlements.h create mode 100644 extras/Build/juce_build_tools/utils/juce_Icons.cpp create mode 100644 extras/Build/juce_build_tools/utils/juce_Icons.h create mode 100644 extras/Build/juce_build_tools/utils/juce_PlistOptions.cpp create mode 100644 extras/Build/juce_build_tools/utils/juce_PlistOptions.h create mode 100644 extras/Build/juce_build_tools/utils/juce_ProjectType.h create mode 100644 extras/Build/juce_build_tools/utils/juce_RelativePath.h create mode 100644 extras/Build/juce_build_tools/utils/juce_ResourceFileHelpers.cpp create mode 100644 extras/Build/juce_build_tools/utils/juce_ResourceFileHelpers.h create mode 100644 extras/Build/juce_build_tools/utils/juce_ResourceRc.cpp create mode 100644 extras/Build/juce_build_tools/utils/juce_ResourceRc.h create mode 100644 extras/Build/juce_build_tools/utils/juce_VersionNumbers.cpp rename extras/{Projucer/Source/Wizards/jucer_NewProjectWizardClasses.h => Build/juce_build_tools/utils/juce_VersionNumbers.h} (50%) create mode 100644 extras/Build/juceaide/CMakeLists.txt create mode 100644 extras/Build/juceaide/Main.cpp create mode 100644 extras/CMakeLists.txt delete mode 100644 extras/NetworkGraphicsDemo/Builds/Android/app/src/main/java/com/android/vending/billing/IInAppBillingService.java delete mode 100644 extras/NetworkGraphicsDemo/Builds/Android/app/src/main/java/com/juce/networkgraphicsdemo/JUCENetworkGraphicsDemo.java delete mode 100644 extras/NetworkGraphicsDemo/Builds/Android/app/src/main/java/com/juce/networkgraphicsdemo/SharingContentProvider.java delete mode 100644 extras/NetworkGraphicsDemo/Builds/MacOSX/App.entitlements delete mode 100644 extras/NetworkGraphicsDemo/Builds/iOS/App.entitlements create mode 100644 extras/NetworkGraphicsDemo/CMakeLists.txt delete mode 100644 extras/NetworkGraphicsDemo/JuceLibraryCode/AppConfig.h delete mode 100644 extras/Projucer/Builds/MacOSX/App.entitlements create mode 100644 extras/Projucer/CMakeLists.txt delete mode 100644 extras/Projucer/JuceLibraryCode/AppConfig.h rename extras/Projucer/JuceLibraryCode/{include_juce_analytics.cpp => include_juce_build_tools.cpp} (66%) create mode 100644 extras/Projucer/Source/Application/StartPage/jucer_ContentComponents.h create mode 100644 extras/Projucer/Source/Application/StartPage/jucer_NewProjectTemplates.h create mode 100644 extras/Projucer/Source/Application/StartPage/jucer_NewProjectWizard.cpp create mode 100644 extras/Projucer/Source/Application/StartPage/jucer_NewProjectWizard.h create mode 100644 extras/Projucer/Source/Application/StartPage/jucer_StartPageComponent.cpp create mode 100644 extras/Projucer/Source/Application/StartPage/jucer_StartPageComponent.h create mode 100644 extras/Projucer/Source/Application/StartPage/jucer_StartPageTreeHolder.h create mode 100644 extras/Projucer/Source/Application/UserAccount/jucer_LicenseController.h create mode 100644 extras/Projucer/Source/Application/UserAccount/jucer_LicenseQueryThread.h create mode 100644 extras/Projucer/Source/Application/UserAccount/jucer_LicenseState.h create mode 100644 extras/Projucer/Source/Application/UserAccount/jucer_LoginFormComponent.h delete mode 100644 extras/Projucer/Source/Application/Windows/jucer_ApplicationUsageDataWindowComponent.h delete mode 100644 extras/Projucer/Source/Application/jucer_ProjucerAnalytics.cpp delete mode 100644 extras/Projucer/Source/Application/jucer_ProjucerAnalytics.h create mode 100644 extras/Projucer/Source/BinaryData/Icons/gpl_logo.svg delete mode 100644 extras/Projucer/Source/BinaryData/Icons/huckleberry_icon.svg delete mode 100644 extras/Projucer/Source/BinaryData/Templates/jucer_PIPMain.cpp delete mode 100644 extras/Projucer/Source/BinaryData/nothingtoseehere.txt delete mode 100644 extras/Projucer/Source/BinaryData/offlinepage.html delete mode 100644 extras/Projucer/Source/BinaryData/projucer_EULA.txt delete mode 100644 extras/Projucer/Source/Licenses/jucer_LicenseController.h delete mode 100644 extras/Projucer/Source/Licenses/jucer_LicenseThread.h delete mode 100644 extras/Projucer/Source/Licenses/jucer_LicenseWebview.h create mode 100644 extras/Projucer/Source/Project/Modules/jucer_AvailableModulesList.h create mode 100644 extras/Projucer/Source/Project/Modules/jucer_ModuleDescription.h rename extras/Projucer/Source/Project/{jucer_Module.cpp => Modules/jucer_Modules.cpp} (62%) rename extras/Projucer/Source/Project/{jucer_Module.h => Modules/jucer_Modules.h} (54%) create mode 100644 extras/Projucer/Source/Project/UI/jucer_ProjectMessagesComponent.h create mode 100644 extras/Projucer/Source/Project/UI/jucer_UserAvatarComponent.h delete mode 100644 extras/Projucer/Source/Project/jucer_ProjectType.h rename extras/Projucer/Source/{Wizards => Utility/Helpers}/jucer_NewFileWizard.cpp (83%) rename extras/Projucer/Source/{Wizards => Utility/Helpers}/jucer_NewFileWizard.h (82%) delete mode 100644 extras/Projucer/Source/Utility/Helpers/jucer_RelativePath.h create mode 100644 extras/Projucer/Source/Utility/Helpers/jucer_ValueWithDefaultWrapper.h delete mode 100644 extras/Projucer/Source/Utility/UI/jucer_UserSettingsPopup.h delete mode 100644 extras/Projucer/Source/Wizards/jucer_NewProjectWizard.h delete mode 100644 extras/Projucer/Source/Wizards/jucer_NewProjectWizardClasses.cpp delete mode 100644 extras/Projucer/Source/Wizards/jucer_NewProjectWizardComponent.h delete mode 100644 extras/Projucer/Source/Wizards/jucer_ProjectWizard_Animated.h delete mode 100644 extras/Projucer/Source/Wizards/jucer_ProjectWizard_AudioApp.h delete mode 100644 extras/Projucer/Source/Wizards/jucer_ProjectWizard_AudioPlugin.h delete mode 100644 extras/Projucer/Source/Wizards/jucer_ProjectWizard_Blank.h delete mode 100644 extras/Projucer/Source/Wizards/jucer_ProjectWizard_Console.h delete mode 100644 extras/Projucer/Source/Wizards/jucer_ProjectWizard_DLL.h delete mode 100644 extras/Projucer/Source/Wizards/jucer_ProjectWizard_GUIApp.h delete mode 100644 extras/Projucer/Source/Wizards/jucer_ProjectWizard_StaticLibrary.h delete mode 100644 extras/Projucer/Source/Wizards/jucer_ProjectWizard_openGL.h delete mode 100644 extras/Projucer/Source/Wizards/jucer_StartPageComponent.h delete mode 100644 extras/Projucer/Source/Wizards/jucer_TemplateThumbnailsComponent.h delete mode 100644 extras/UnitTestRunner/Builds/MacOSX/ConsoleApp.entitlements create mode 100644 extras/UnitTestRunner/CMakeLists.txt delete mode 100644 extras/UnitTestRunner/JuceLibraryCode/AppConfig.h delete mode 100644 extras/WindowsDLL/JuceLibraryCode/AppConfig.h create mode 100644 modules/CMakeLists.txt delete mode 100644 modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.cpp delete mode 100644 modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.h create mode 100644 modules/juce_audio_basics/utilities/juce_GenericInterpolator.h create mode 100644 modules/juce_audio_basics/utilities/juce_Interpolators.cpp create mode 100644 modules/juce_audio_basics/utilities/juce_Interpolators.h delete mode 100644 modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.h create mode 100644 modules/juce_audio_basics/utilities/juce_WindowedSincInterpolator.cpp rename modules/juce_audio_devices/native/java/app/com/{roli => rmsl}/juce/JuceMidiSupport.java (94%) create mode 100644 modules/juce_audio_devices/native/juce_android_HighPerformanceAudioHelpers.h mode change 100644 => 100755 modules/juce_audio_devices/native/juce_win32_WASAPI.cpp create mode 100644 modules/juce_audio_devices/native/oboe/CMakeLists.txt create mode 100755 modules/juce_audio_devices/native/oboe/LICENSE create mode 100644 modules/juce_audio_devices/native/oboe/include/oboe/AudioStream.h create mode 100644 modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamBase.h create mode 100644 modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamBuilder.h create mode 100644 modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamCallback.h create mode 100644 modules/juce_audio_devices/native/oboe/include/oboe/Definitions.h create mode 100644 modules/juce_audio_devices/native/oboe/include/oboe/LatencyTuner.h create mode 100644 modules/juce_audio_devices/native/oboe/include/oboe/Oboe.h create mode 100644 modules/juce_audio_devices/native/oboe/include/oboe/ResultWithValue.h create mode 100644 modules/juce_audio_devices/native/oboe/include/oboe/StabilizedCallback.h create mode 100644 modules/juce_audio_devices/native/oboe/include/oboe/Utilities.h create mode 100644 modules/juce_audio_devices/native/oboe/include/oboe/Version.h create mode 100644 modules/juce_audio_devices/native/oboe/readme.md create mode 100644 modules/juce_audio_devices/native/oboe/src/aaudio/AAudioLoader.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/aaudio/AAudioLoader.h create mode 100644 modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.h create mode 100644 modules/juce_audio_devices/native/oboe/src/common/AudioClock.h create mode 100644 modules/juce_audio_devices/native/oboe/src/common/AudioSourceCaller.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/common/AudioSourceCaller.h create mode 100644 modules/juce_audio_devices/native/oboe/src/common/AudioStream.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/common/AudioStreamBuilder.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/common/DataConversionFlowGraph.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/common/DataConversionFlowGraph.h create mode 100644 modules/juce_audio_devices/native/oboe/src/common/FilterAudioStream.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/common/FilterAudioStream.h create mode 100644 modules/juce_audio_devices/native/oboe/src/common/FixedBlockAdapter.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/common/FixedBlockAdapter.h create mode 100644 modules/juce_audio_devices/native/oboe/src/common/FixedBlockReader.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/common/FixedBlockReader.h create mode 100644 modules/juce_audio_devices/native/oboe/src/common/FixedBlockWriter.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/common/FixedBlockWriter.h create mode 100644 modules/juce_audio_devices/native/oboe/src/common/LatencyTuner.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/common/MonotonicCounter.h create mode 100644 modules/juce_audio_devices/native/oboe/src/common/OboeDebug.h create mode 100644 modules/juce_audio_devices/native/oboe/src/common/QuirksManager.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/common/QuirksManager.h create mode 100644 modules/juce_audio_devices/native/oboe/src/common/SourceFloatCaller.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/common/SourceFloatCaller.h create mode 100644 modules/juce_audio_devices/native/oboe/src/common/SourceI16Caller.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/common/SourceI16Caller.h create mode 100644 modules/juce_audio_devices/native/oboe/src/common/StabilizedCallback.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/common/Trace.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/common/Trace.h create mode 100644 modules/juce_audio_devices/native/oboe/src/common/Utilities.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/common/Version.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.h create mode 100644 modules/juce_audio_devices/native/oboe/src/fifo/FifoController.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/fifo/FifoController.h create mode 100644 modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.h create mode 100644 modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.h create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/ClipToRange.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/ClipToRange.h create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.h create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.h create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.h create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/RampLinear.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/RampLinear.h create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/SampleRateConverter.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/SampleRateConverter.h create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/SinkFloat.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/SinkFloat.h create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI16.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI16.h create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI24.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI24.h create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/SourceFloat.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/SourceFloat.h create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI16.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI16.h create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI24.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI24.h create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/HyperbolicCosineWindow.h create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/IntegerRatio.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/IntegerRatio.h create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/KaiserWindow.h create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/LinearResampler.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/LinearResampler.h create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/MultiChannelResampler.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/MultiChannelResampler.h create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResampler.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResampler.h create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.h create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.h create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.h create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResamplerStereo.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResamplerStereo.h create mode 100644 modules/juce_audio_devices/native/oboe/src/opensles/AudioInputStreamOpenSLES.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/opensles/AudioInputStreamOpenSLES.h create mode 100644 modules/juce_audio_devices/native/oboe/src/opensles/AudioOutputStreamOpenSLES.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/opensles/AudioOutputStreamOpenSLES.h create mode 100644 modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamBuffered.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamBuffered.h create mode 100644 modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamOpenSLES.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamOpenSLES.h create mode 100644 modules/juce_audio_devices/native/oboe/src/opensles/EngineOpenSLES.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/opensles/EngineOpenSLES.h create mode 100644 modules/juce_audio_devices/native/oboe/src/opensles/OpenSLESUtilities.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/opensles/OpenSLESUtilities.h create mode 100644 modules/juce_audio_devices/native/oboe/src/opensles/OutputMixerOpenSLES.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/opensles/OutputMixerOpenSLES.h create mode 100644 modules/juce_audio_plugin_client/utility/juce_CreatePluginFilter.h create mode 100644 modules/juce_audio_processors/utilities/juce_ParameterAttachments.cpp create mode 100644 modules/juce_audio_processors/utilities/juce_ParameterAttachments.h create mode 100644 modules/juce_core/files/juce_RangedDirectoryIterator.cpp create mode 100644 modules/juce_core/files/juce_RangedDirectoryIterator.h create mode 100644 modules/juce_core/memory/juce_AllocationHooks.cpp create mode 100644 modules/juce_core/memory/juce_AllocationHooks.h rename modules/juce_core/native/java/app/com/{roli => rmsl}/juce/FragmentOverlay.java (62%) rename modules/juce_core/native/java/app/com/{roli => rmsl}/juce/JuceHTTPStream.java (90%) create mode 100644 modules/juce_core/native/java/app/com/rmsl/juce/JuceInvocationHandler.java create mode 100644 modules/juce_core/native/javacore/app/com/rmsl/juce/JuceApp.java delete mode 100644 modules/juce_core/native/javacore/app/com/roli/juce/JuceApp.java create mode 100644 modules/juce_core/native/javacore/init/com/rmsl/juce/Java.java delete mode 100644 modules/juce_core/native/javacore/init/com/roli/juce/Java.java create mode 100644 modules/juce_core/system/juce_CompilerWarnings.h create mode 100644 modules/juce_dsp/containers/juce_FixedSizeFunction.h create mode 100644 modules/juce_dsp/containers/juce_FixedSizeFunction_test.cpp create mode 100644 modules/juce_dsp/frequency/juce_Convolution_test.cpp create mode 100644 modules/juce_dsp/processors/juce_BallisticsFilter.cpp create mode 100644 modules/juce_dsp/processors/juce_BallisticsFilter.h create mode 100644 modules/juce_dsp/processors/juce_DelayLine.cpp create mode 100644 modules/juce_dsp/processors/juce_DelayLine.h create mode 100644 modules/juce_dsp/processors/juce_DryWetMixer.cpp create mode 100644 modules/juce_dsp/processors/juce_DryWetMixer.h create mode 100644 modules/juce_dsp/processors/juce_FirstOrderTPTFilter.cpp create mode 100644 modules/juce_dsp/processors/juce_FirstOrderTPTFilter.h delete mode 100644 modules/juce_dsp/processors/juce_LadderFilter.cpp create mode 100644 modules/juce_dsp/processors/juce_LinkwitzRileyFilter.cpp create mode 100644 modules/juce_dsp/processors/juce_LinkwitzRileyFilter.h create mode 100644 modules/juce_dsp/processors/juce_Panner.cpp create mode 100644 modules/juce_dsp/processors/juce_Panner.h create mode 100644 modules/juce_dsp/processors/juce_ProcessorChain_test.cpp create mode 100644 modules/juce_dsp/processors/juce_StateVariableTPTFilter.cpp create mode 100644 modules/juce_dsp/processors/juce_StateVariableTPTFilter.h rename modules/juce_dsp/{processors => widgets}/juce_Bias.h (88%) create mode 100644 modules/juce_dsp/widgets/juce_Chorus.cpp create mode 100644 modules/juce_dsp/widgets/juce_Chorus.h create mode 100644 modules/juce_dsp/widgets/juce_Compressor.cpp create mode 100644 modules/juce_dsp/widgets/juce_Compressor.h rename modules/juce_dsp/{processors => widgets}/juce_Gain.h (91%) create mode 100644 modules/juce_dsp/widgets/juce_LadderFilter.cpp rename modules/juce_dsp/{processors => widgets}/juce_LadderFilter.h (55%) create mode 100644 modules/juce_dsp/widgets/juce_Limiter.cpp create mode 100644 modules/juce_dsp/widgets/juce_Limiter.h create mode 100644 modules/juce_dsp/widgets/juce_NoiseGate.cpp create mode 100644 modules/juce_dsp/widgets/juce_NoiseGate.h rename modules/juce_dsp/{processors => widgets}/juce_Oscillator.h (91%) create mode 100644 modules/juce_dsp/widgets/juce_Phaser.cpp create mode 100644 modules/juce_dsp/widgets/juce_Phaser.h rename modules/juce_dsp/{processors => widgets}/juce_Reverb.h (87%) rename modules/juce_dsp/{processors => widgets}/juce_WaveShaper.h (85%) rename modules/juce_gui_basics/native/java/app/com/{roli => rmsl}/juce/ComponentPeerView.java (90%) create mode 100644 modules/juce_gui_basics/native/java/app/com/rmsl/juce/JuceContentProviderCursor.java create mode 100644 modules/juce_gui_basics/native/java/app/com/rmsl/juce/JuceContentProviderFileObserver.java create mode 100644 modules/juce_gui_basics/native/javaopt/app/com/rmsl/juce/JuceActivity.java rename modules/juce_gui_basics/native/{javacore/app/com/roli => javaopt/app/com/rmsl}/juce/JuceSharingContentProvider.java (62%) delete mode 100644 modules/juce_gui_basics/native/javaopt/app/com/roli/juce/JuceActivity.java create mode 100644 modules/juce_gui_basics/native/juce_linux_Windowing.cpp delete mode 100644 modules/juce_gui_basics/native/juce_linux_X11.cpp delete mode 100644 modules/juce_gui_basics/native/juce_linux_X11.h delete mode 100644 modules/juce_gui_basics/native/juce_linux_X11_Clipboard.cpp delete mode 100644 modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp create mode 100644 modules/juce_gui_basics/native/x11/juce_linux_X11_DragAndDrop.cpp create mode 100644 modules/juce_gui_basics/native/x11/juce_linux_X11_Symbols.cpp create mode 100644 modules/juce_gui_basics/native/x11/juce_linux_X11_Symbols.h create mode 100644 modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.cpp create mode 100644 modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.h create mode 100644 modules/juce_gui_extra/embedding/juce_HWNDComponent.h rename modules/juce_gui_extra/native/java/app/com/{roli => rmsl}/juce/JuceWebView.java (74%) create mode 100644 modules/juce_gui_extra/native/java/app/com/rmsl/juce/JuceWebView21.java create mode 100644 modules/juce_gui_extra/native/javaopt/app/com/rmsl/juce/JuceFirebaseInstanceIdService.java create mode 100644 modules/juce_gui_extra/native/javaopt/app/com/rmsl/juce/JuceFirebaseMessagingService.java delete mode 100644 modules/juce_gui_extra/native/javaopt/app/com/roli/juce/JuceFirebaseInstanceIdService.java delete mode 100644 modules/juce_gui_extra/native/javaopt/app/com/roli/juce/JuceFirebaseMessagingService.java create mode 100644 modules/juce_gui_extra/native/juce_win32_HWNDComponent.cpp rename modules/juce_opengl/native/java/app/com/{roli => rmsl}/juce/JuceOpenGLView.java (55%) rename modules/juce_product_unlocking/native/javaopt/app/com/{roli => rmsl}/juce/JuceBillingClient.java (87%) rename modules/juce_video/native/java/app/com/{roli => rmsl}/juce/CameraCaptureSessionCaptureCallback.java (75%) rename modules/juce_video/native/java/app/com/{roli => rmsl}/juce/CameraCaptureSessionStateCallback.java (59%) rename modules/juce_video/native/java/app/com/{roli => rmsl}/juce/CameraDeviceStateCallback.java (52%) create mode 100644 modules/juce_video/native/java/app/com/rmsl/juce/JuceOrientationEventListener.java rename modules/juce_video/native/java/app/com/{roli => rmsl}/juce/MediaControllerCallback.java (59%) rename modules/juce_video/native/java/app/com/{roli => rmsl}/juce/MediaSessionCallback.java (61%) rename modules/juce_video/native/java/app/com/{roli => rmsl}/juce/SystemVolumeObserver.java (52%) delete mode 100644 modules/juce_video/native/java/app/com/roli/juce/JuceOrientationEventListener.java diff --git a/BREAKING-CHANGES.txt b/BREAKING-CHANGES.txt index 93754f71..51ef929c 100644 --- a/BREAKING-CHANGES.txt +++ b/BREAKING-CHANGES.txt @@ -1,6 +1,261 @@ JUCE breaking changes ===================== +Version 6.0.5 +============= + +Change +------ +New pure virtual methods accepting `PopupMenu::Options` arguments have been +added to `PopupMenu::LookAndFeelMethods`. + +Possible Issues +--------------- +Classes derived from `PopupMenu::LookAndFeelMethods`, such as custom +LookAndFeel classes, will not compile unless these pure virtual methods are +implemented. + +Workaround +---------- +The old LookAndFeel methods still exist, so if the new Options parameter is not +useful in your application, your implementation of +`PopupMenu::LookAndFeelMethods` can simply forward to the old methods. For +example, your implementation of `drawPopupMenuBackgroundWithOptions` can +internally call your existing `drawPopupMenuBackground` implementation. + +Rationale +--------- +Allowing the LookAndFeelMethods to access the popup menu's options allows for +more flexible styling. For example, a theme may wish to query the menu's target +component or parent for colours to use. + + +Change +------ +A typo in the JUCEUtils CMake script that caused the wrong manufacturer code to +be set in the compile definitions for a plugin was fixed. + +Possible Issues +--------------- +The manufacturer code for plugins built under CMake with this version of JUCE +will differ from the manufacturer code that was generated previously. + +Workaround +---------- +If you have released plugins that used the old, incorrect manufacturer code and +wish to continue using this code for backwards compatibility, add the following +to your `juce_add_plugin` call: + + USE_LEGACY_COMPATIBILITY_PLUGIN_CODE TRUE + +In most cases, this should not be necessary, and we recommend using the fixed +behaviour. + +Rationale +--------- +This change ensures that the manufacturer codes used by CMake projects match +the codes that would be generated by the Projucer, improving compatibility +when transitioning from the Projucer to CMake. + + +Version 6.0.2 +============= + +Change +------ +The JUCE_WASAPI_EXCLUSIVE flag has been removed from juce_audio_devices and all +available WASAPI audio device modes (shared, shared low latency and exclusive) +are available by default when JUCE_WASAPI is enabled. The +AudioIODeviceType::createAudioIODeviceType_WASAPI() method which takes a single +boolean argument has also been deprecated in favour of a new method which takes +a WASAPIDeviceMode enum. + +Possible Issues +--------------- +Code that relied on the JUCE_WASAPI_EXCLUSIVE flag to disable WASAPI exclusive +mode will no longer work. + +Workaround +---------- +Override the AudioDeviceManager::createAudioDeviceTypes() method to omit the +WASAPI exclusive mode device if you do not want it to be available. + +Rationale +--------- +JUCE now supports shared low latency WASAPI audio devices via the AudioClient3 +interface and instead of adding an additional compile time config flag to +enable this functionality, which adds complexity to the build process when not +using the Projucer, JUCE makes all WASAPI device modes available by default. + + +Change +------ +The fields representing Mac OS X 10.4 to 10.6 inclusive have been removed from +the `OperatingSystemType` enum. + +Possible Issues +--------------- +Code that uses these fields will fail to build. + +Workaround +---------- +Remove references to these fields from user code. + +Rationale +--------- +JUCE is not supported on Mac OS X versions lower than 10.7, so it is a given +that `getOperatingSystemType` will always return an OS version greater than or +equal to 10.7. Code that changes behaviours depending on the OS version can +assume that this version is at least 10.7. + + +Change +------ +The JUCE_DISABLE_COREGRAPHICS_FONT_SMOOTHING flag in juce_graphics is no +longer used on iOS. + +Possible Issues +--------------- +Projects with this flag enabled may render differently on iOS. + +Workaround +---------- +There is no workaround. + +Rationale +--------- +When using a cached image to render Components with `setBufferedToImage (true)` +the result now matches the default behaviour on iOS where fonts are not +smoothed. + + +Change +------ +Space, return and escape key events on the native macOS menu bar are no longer +passed to the currently focused JUCE Component. + +Possible Issues +--------------- +Code relying on receiving these keyboard events will no longer work. + +Workaround +---------- +There is no workaround. + +Rationale +--------- +It should be possible for users with a keyboard or assistive device to navigate +the menu, invoking the currently highlighted menu item with the space or return +key and dismissing the menu with the escape key. These key events should not be +passed to the application and doing so interferes with the accessibility of +JUCE apps. Only passing these events to the native macOS menu means that JUCE +apps behave as expected for users. + + +Version 6.0.0 +============= + +Change +------ +The Convolution class interface was changed: +- `loadImpulseResponse` member functions now take `enum class` parameters + instead of `bool`. +- `copyAndLoadImpulseResponseFromBlock` and + `copyAndLoadImpulseResponseFromBuffer` were replaced by a new + `loadImpulseResponse` overload. + +Possible Issues +--------------- +Code using the old interface will no longer compile, and will need to be +updated. + +Workaround +---------- +Code that was previously loading impulse responses from binary data or from +files can substitute old `bool` parameters with the newer `enum class` +equivalents. Code that was previously passing buffers or blocks will need +reworking so that the Convolution instance can take ownership of the buffer +containing the impulse response. + +Rationale +--------- +The newer `enum class` parameters make user code much more readable, e.g. +`loadImpulseResponse (file, Stereo::yes, Trim::yes, 0, Normalise::yes)` rather +than `loadImpulseResponse (file, true, true, 0, true);`. By taking ownership of +the passed buffer, the Convolution can avoid preallocating a large internal +buffer, reducing memory usage when short impulse responses are used. Changing +the ownership semantics of the buffer also makes it easier for users to avoid +copies/allocations on the audio thread, and gives more flexibility to the +implementation to run initialisation tasks on a background thread. + + +Change +------ +All references to ROLI Ltd. (ROLI) have been changed to Raw Material Software +Limited. + +Possible Issues +--------------- +Exising projects, particularly Android, may need to be resaved by the Projucer +and have the old build artifacts deleted before they will build. + +Workaround +---------- +In Android projects any explicit mention of paths with the from "com.roli.*" +should be changed to the form "com.rmsl.*". + +Rationale +--------- +This change reflects the change in ownership from ROLI to RMSL. + + +Change +------ +The Windows DPI handling in the VST wrapper and hosting code has been +refactored to be more stable. + +Possible Issues +--------------- +The new code uses a top-level AffineTransform to scale the JUCE editor window +instead of native methods. Therefore any AudioProcessorEditors which have their +own AffineTransform applied will no longer work correctly. + +Workaround +---------- +If you are using an AffineTransform to scale the entire plug-in window then +consider putting the component you want to transform in a child of +the editor and transform that instead. Alternatively, if you don't need a +separate scale factor for each plug-in instance you can use +Desktop::setGlobalScaleFactor(). + +Rationale +--------- +The old code had some bugs when using OpenGL and when moving between monitors +with different scale factors. The new code should fix these and DPI-aware +plug-ins will scale correctly. + + +Change +------ +Relative Xcode subproject paths specified in the Projucer are now relative to +the build directory rather than the project directory. + +Possible Issues +--------------- +After being re-saved in the Projucer existing Xcode projects will fail to find +any subprojects specified using a relative path. + +Workaround +---------- +Update the subproject path in the Projucer. + +Rationale +--------- +Most other Xcode specific paths are specified reltive to the build directory. +This change brings the Xcode subproject path in line with the rest of the +configuration. + + Version 5.4.6 ============= @@ -1066,7 +1321,7 @@ or 2. Override the Look&Feel method PopupMenu::LookAndFeelMethods::shouldPopupMenuScaleWithTargetComponent and return false. See - https://github.com/WeAreROLI/JUCE/blob/c288c94c2914af20f36c03ca9c5401fcb555e4e9/modules/juce_gui_basics/menus/juce_PopupMenu.h#725 + https://github.com/juce-framework/JUCE/blob/c288c94c2914af20f36c03ca9c5401fcb555e4e9/modules/juce_gui_basics/menus/juce_PopupMenu.h#725 Rationale --------- diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..f4b68732 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,138 @@ +# ============================================================================== +# +# This file is part of the JUCE library. +# Copyright (c) 2020 - Raw Material Software Limited +# +# JUCE is an open source library subject to commercial or open-source +# licensing. +# +# By using JUCE, you agree to the terms of both the JUCE 6 End-User License +# Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). +# +# End User License Agreement: www.juce.com/juce-6-licence +# Privacy Policy: www.juce.com/juce-privacy-policy +# +# Or: You may also use this code under the terms of the GPL v3 (see +# www.gnu.org/licenses). +# +# JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER +# EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE +# DISCLAIMED. +# +# ============================================================================== + +cmake_minimum_required(VERSION 3.12) + +project(JUCE VERSION 6.0.5 LANGUAGES C CXX) + +set_property(GLOBAL PROPERTY USE_FOLDERS YES) + +set(JUCE_MODULES_DIR "${JUCE_SOURCE_DIR}/modules" CACHE INTERNAL + "The path to JUCE modules") + +include(extras/Build/CMake/JUCEUtils.cmake) + +juce_disable_default_flags() + +set_directory_properties(PROPERTIES + JUCE_COMPANY_NAME "JUCE" + JUCE_COMPANY_WEBSITE "juce.com" + JUCE_COMPANY_EMAIL "info@juce.com" + JUCE_COMPANY_COPYRIGHT "Copyright (c) 2020 - Raw Material Software Limited") + +option(JUCE_COPY_PLUGIN_AFTER_BUILD + "Whether or not plugins should be installed to the system after building" OFF) +set_property(GLOBAL PROPERTY JUCE_COPY_PLUGIN_AFTER_BUILD ${JUCE_COPY_PLUGIN_AFTER_BUILD}) + +set(CMAKE_CXX_EXTENSIONS FALSE) + +# This option controls whether dummy targets are added to the build, where these targets contain all +# of the source files for each JUCE module. If you're planning to use an IDE and want to be able to +# browse all of JUCE's source files, this may be useful. However, it will increase the size of +# generated IDE projects and might slow down configuration a bit. If you enable this, you should +# probably also add `set_property(GLOBAL PROPERTY USE_FOLDERS YES)` to your top level CMakeLists, +# otherwise the module sources will be added directly to the top level of the project, instead of in +# a nice 'Modules' subfolder. + +option(JUCE_ENABLE_MODULE_SOURCE_GROUPS "Show all module sources in IDE projects" OFF) + +add_subdirectory(modules) +add_subdirectory(extras/Build) + +# If you want to build the JUCE examples with VST2/AAX support, you'll need to make the VST2/AAX +# headers visible to the juce_audio_processors module. You can either set the paths on the command +# line, (e.g. -DJUCE_GLOBAL_AAX_SDK_PATH=/path/to/sdk) if you're just building the JUCE examples, or +# you can call the `juce_set_*_sdk_path` functions in your own CMakeLists after importing JUCE. + +if(JUCE_GLOBAL_AAX_SDK_PATH) + juce_set_aax_sdk_path("${JUCE_GLOBAL_AAX_SDK_PATH}") +endif() + +if(JUCE_GLOBAL_VST2_SDK_PATH) + juce_set_vst2_sdk_path("${JUCE_GLOBAL_VST2_SDK_PATH}") +endif() + +# We don't build anything other than the juceaide by default, because we want to keep configuration +# speedy and the number of targets low. If you want to add targets for the extra projects and +# example PIPs (there's a lot of them!), specify -DJUCE_BUILD_EXAMPLES=ON and/or +# -DJUCE_BUILD_EXTRAS=ON when initially generating your build tree. + +option(JUCE_BUILD_EXTRAS "Add build targets for the Projucer and other tools" OFF) + +if(JUCE_BUILD_EXTRAS) + add_subdirectory(extras) +endif() + +option(JUCE_BUILD_EXAMPLES "Add build targets for the DemoRunner and PIPs" OFF) + +if(JUCE_BUILD_EXAMPLES) + add_subdirectory(examples) +endif() + +# ================================================================================================== +# Install configuration + +if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.14") + set(extra_version_arg ARCH_INDEPENDENT) +endif() + +include(CMakePackageConfigHelpers) +write_basic_package_version_file("${JUCE_BINARY_DIR}/JUCEConfigVersion.cmake" + VERSION ${JUCE_VERSION} + COMPATIBILITY ExactVersion + ${extra_version_arg}) + +set(JUCE_INSTALL_DESTINATION "lib/cmake/JUCE-${JUCE_VERSION}" CACHE STRING + "The location, relative to the install prefix, where the JUCE config file will be installed") + +set(JUCE_MODULE_PATH "include/JUCE-${JUCE_VERSION}/modules") +set(UTILS_INSTALL_DIR "${JUCE_INSTALL_DESTINATION}") +set(JUCEAIDE_PATH "${JUCE_TOOL_INSTALL_DIR}/${JUCE_JUCEAIDE_NAME}") +configure_package_config_file("${JUCE_CMAKE_UTILS_DIR}/JUCEConfig.cmake.in" + "${JUCE_BINARY_DIR}/JUCEConfig.cmake" + PATH_VARS UTILS_INSTALL_DIR JUCEAIDE_PATH JUCE_MODULE_PATH + INSTALL_DESTINATION "${JUCE_INSTALL_DESTINATION}") + +set(JUCE_MODULE_PATH "${JUCE_MODULES_DIR}") +set(UTILS_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/extras/Build/CMake") +get_target_property(JUCEAIDE_PATH juceaide IMPORTED_LOCATION) +configure_package_config_file("${JUCE_CMAKE_UTILS_DIR}/JUCEConfig.cmake.in" + "${JUCE_BINARY_DIR}/JUCEExportConfig.cmake" + PATH_VARS UTILS_INSTALL_DIR JUCEAIDE_PATH JUCE_MODULE_PATH + INSTALL_PREFIX "${CMAKE_CURRENT_BINARY_DIR}" + INSTALL_DESTINATION "${CMAKE_CURRENT_BINARY_DIR}") + +install(FILES "${JUCE_BINARY_DIR}/JUCEConfigVersion.cmake" + "${JUCE_BINARY_DIR}/JUCEConfig.cmake" + "${JUCE_CMAKE_UTILS_DIR}/JUCEHelperTargets.cmake" + "${JUCE_CMAKE_UTILS_DIR}/JUCECheckAtomic.cmake" + "${JUCE_CMAKE_UTILS_DIR}/JUCEUtils.cmake" + "${JUCE_CMAKE_UTILS_DIR}/LaunchScreen.storyboard" + "${JUCE_CMAKE_UTILS_DIR}/PIPAudioProcessor.cpp.in" + "${JUCE_CMAKE_UTILS_DIR}/PIPComponent.cpp.in" + "${JUCE_CMAKE_UTILS_DIR}/PIPConsole.cpp.in" + "${JUCE_CMAKE_UTILS_DIR}/RecentFilesMenuTemplate.nib" + "${JUCE_CMAKE_UTILS_DIR}/UnityPluginGUIScript.cs.in" + "${JUCE_CMAKE_UTILS_DIR}/copyDir.cmake" + "${JUCE_CMAKE_UTILS_DIR}/juce_runtime_arch_detection.cpp" + DESTINATION "${JUCE_INSTALL_DESTINATION}") diff --git a/ChangeList.txt b/ChangeList.txt index 867532c2..3ba03f38 100644 --- a/ChangeList.txt +++ b/ChangeList.txt @@ -3,6 +3,73 @@ This file just lists the more notable headline features. For more detailed info about minor changes and bugfixes, please see the git log! +Version 6.0.5 + - Added more support for styling PopupMenus + - Fixed some race conditions in the IPC and name named pipe classes + - Implemented multiple FileChooser improvements + - Added compatibility with the latest Android SDK + - Prevented CoreAudio glitches before accepting audio access permissions + - Made reading MIDI and audio files more robust + +Version 6.0.4 + - Improved the Projucer update mechanism + - Fixed an AUv3 parameter normalisation issue + - Fixed WASAPI exclusive mode sample rate selection bug + - Fixed a Linux build issue when omitting ALSA + +Version 6.0.3 + - Fixed version numbers in project files + +Version 6.0.2 + - Added support for macOS 11 and arm64 + - Added Windows IAudioClient3 support for low latency audio drivers + - Added Windows and macOS precompiled header support in the Projucer + - Improved accessibility support in the macOS menu bar + - Fixed VST3 hosting for plug-ins requiring persistent DLL loads + - Updated macOS camera capture API + - Improved resave diffs in Projucer project files + - Fixed some Linux JACK issues + +Version 6.0.1 + - Fixed a bug in the Projucer GUI editor causing existing code to be overwritten + - Updated Android Oboe to 1.4.2 + - Bumped default Android Studio gradle and plugin versions to the latest + - Fixed some Android Oboe and OpenSL issues + - Fixed some Doxygen parsing issues + - Fixed MIDI input/output bus enablement in VST3 plug-ins + - Improved Windows Clang compatibility + - Fixed GCC 4.8 and 5.0 compatibility + - Fixed some VST3 build errors and warnings on Linux + - Fixed dynamically loaded X11 library names on Linux + - Fixed Projucer CLion exporter generated CMakeLists.txt + - Fixed drag and drop for non-DPI aware plug-ins on Windows + +Version 6.0.0 + - Added support for building JUCE projects with CMake + - Revamped the DSP module + - Added VST3 support on Linux + - Added support for the latest webview components on macOS/iOS and Windows + - Removed the sign-in requirement, app reporting and analytics from the Projucer + - Added support for running headlessly on Linux + - Bundled Oboe source in JUCE and made it the default audio device on Android + - Various Oboe stability improvements + - Various Projucer UI improvements + - Added HWNDComponent for embedding native HWNDs on Windows + - Added support for all camera names on macOS + - Added support for building with Clang on Windows + - Modified MidiMessageCollector to preallocate storage + - Modified AudioProcessorGraph to allow extracting nodes + - Refactored the APVTS parameter attachment classes and added a new ParameterAttachment class + - Added IPP FFT implementation + - Added all example plugins as internal nodes in AudioPluginHost project + - Removed JuceHeader requirement from Projucer projects + - Added support for legacy CC output events + - Added MidiBuffer::Iterator class compatible with C++11 range-for + - Added RangedDirectoryIterator class compatible with C++11 range-for + - Provided range-for comaptibility for String class + - Windows and Linux hiDPI scaling improvements + - Various bug-fixes, improvements and documentation updates + Version 5.4.7 - Fixed a macOS focus bug causing Components to not receive mouse events - Fixed a potential NullPointerException in the Android IAP code diff --git a/LICENSE.md b/LICENSE.md index c60278be..7c7554bd 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,31 +1,24 @@ -# The JUCE 5 Library +# The JUCE Library **BY DOWNLOADING, INSTALLING OR USING ANY PART OF THE JUCE LIBRARY, YOU AGREE -TO THE [JUCE 5 END-USER LICENSE AGREEMENT](https://www.juce.com/juce-5-licence) -AND [JUCE 5 PRIVACY POLICY](https://www.juce.com/juce-5-privacy-policy), WHICH -ARE BINDING AGREEMENTS BETWEEN YOU AND ROLI, LTD. IF YOU DO NOT AGREE TO THE -TERMS, DO NOT USE THE JUCE LIBRARY.** +TO THE [JUCE 6 END-USER LICENSE AGREEMENT](https://www.juce.com/juce-6-licence) +AND THE [JUCE PRIVACY POLICY](https://www.juce.com/juce-privacy-policy), WHICH +ARE BINDING AGREEMENTS BETWEEN YOU AND RAW MATERIAL SOFTWARE LIMITED. IF YOU DO +NOT AGREE TO THE TERMS, DO NOT USE THE JUCE LIBRARY.** -We now have tier-leveled license terms for JUCE 5, with different terms for -each available license: JUCE Personal (for developers or startup businesses -with revenue under 50K USD "Revenue Limit"; free), JUCE Indie (for small -businesses with under 200K Revenue Limit; $35/month), JUCE Pro (no Revenue -Limit; $65/month), and JUCE Educational (no Revenue Limit; free for bona fide -educational institutes). All licenses allow you to commercially release -applications so long as you do not exceed the Revenue Limit and pay applicable -Fees. Once your business hits the Revenue Limit for your JUCE license, you will -either have to upgrade your JUCE license or release your Applications under the +JUCE has tier-leveled license terms, with different terms for each available +license: JUCE Personal (for developers or startup businesses with revenue under +the 50K USD Revenue Limit; free), JUCE Indie (for small businesses with under +500K USD Revenue Limit; $40/month), JUCE Pro (no Revenue Limit; $130/month), +and JUCE Educational (no Revenue Limit; free for bona fide educational +institutions). All licenses allow you to commercially release applications as +long as you do not exceed the Revenue Limit and pay the applicable Fees. Once +your business hits the Revenue Limit for your JUCE license tier, to continue +distributing your Applications you will either have to upgrade your JUCE +license, or instead release your Applications under the [GNU General Public License v.3](https://www.gnu.org/licenses/gpl-3.0.en.html), -which means, among other things, that your code can be freely copied and -distributed. - -You agree to give notice to the end-users of your Applications that we may -track the IP addresses associated with their use of the Applications using JUCE -solely for our internal purposes in providing JUCE, unless you are a paying -JUCE customer and opt-out of such tracking. You agree to fully comply with all -laws, including relating to the collection of information from children and the -[Children’s Online Privacy Protection Act -(COPPA)](https://www.ftc.gov/enforcement/rules/rulemaking-regulatory-reform-proceedings/childrens-online-privacy-protection-rule). +which means, amongst other things, that you must make the source code of your +Applications available. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF MERCHANTABILITY AND FITNESS FOR A @@ -39,5 +32,5 @@ For more information, visit the website: [www.juce.com](https://www.juce.com) FULL JUCE TERMS: -- [JUCE 5 END-USER LICENSE AGREEMENT](https://www.juce.com/juce-5-licence) -- [JUCE 5 PRIVACY POLICY](https://www.juce.com/juce-5-privacy-policy) \ No newline at end of file +- [JUCE 6 END-USER LICENSE AGREEMENT](https://www.juce.com/juce-6-licence) +- [JUCE PRIVACY POLICY](https://www.juce.com/juce-privacy-policy) diff --git a/README.md b/README.md index c585655c..60af0f08 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![alt text](https://d30pueezughrda.cloudfront.net/juce/JUCE_banner.png "JUCE") +![alt text](https://assets.juce.com/juce/JUCE_banner.png "JUCE") JUCE is an open-source cross-platform C++ application framework used for rapidly developing high quality desktop and mobile applications, including VST, AU (and AUv3), @@ -9,12 +9,18 @@ Code::Blocks, CLion and Linux Makefiles as well as containing a source code edit live-coding engine which can be used for rapid prototyping. ## Getting Started -The JUCE repository contains a [master](https://github.com/weareroli/JUCE/tree/master) -and [develop](https://github.com/weareroli/JUCE/tree/develop) branch. The develop branch + +The JUCE repository contains a [master](https://github.com/juce-framework/JUCE/tree/master) +and [develop](https://github.com/juce-framework/JUCE/tree/develop) branch. The develop branch contains the latest bugfixes and features and is periodically merged into the master -branch in stable [tagged releases](https://github.com/WeAreROLI/JUCE/releases) +branch in stable [tagged releases](https://github.com/juce-framework/JUCE/releases) (the latest release containing pre-built binaries can be also downloaded from the -[JUCE website](https://shop.juce.com/get-juce)). +[JUCE website](https://juce.com/get-juce)). + +JUCE projects can be managed with either the Projucer (JUCE's own project-configuration +tool) or with CMake. + +### The Projucer The repository doesn't contain a pre-built Projucer so you will need to build it for your platform - Xcode, Visual Studio and Linux Makefile projects are located in @@ -28,18 +34,45 @@ For further help getting started, please refer to the JUCE [documentation](https://juce.com/learn/documentation) and [tutorials](https://juce.com/learn/tutorials). +### CMake + +Version 3.15 or higher is required for plugin projects, and strongly +recommended for other project types. To use CMake, you will need to install it, +either from your system package manager or from the [official download +page](https://cmake.org/download/). For comprehensive documentation on JUCE's +CMake API, see the [JUCE CMake documentation](/docs/CMake API.md). For examples +which may be useful as starting points for new CMake projects, see the [CMake +examples directory](/examples/CMake). + +#### Building Examples + +To use CMake to build the examples and extras bundled with JUCE, simply clone +JUCE and then run the following commands, replacing "DemoRunner" with the name +of the target you wish to build. + + cd /path/to/JUCE + cmake . -B cmake-build -DJUCE_BUILD_EXAMPLES=ON -DJUCE_BUILD_EXTRAS=ON + cmake --build cmake-build --target DemoRunner + ## Minimum System Requirements + #### Building JUCE Projects -- __macOS__: macOS 10.11 and Xcode 7.3.1 + +- __macOS/iOS__: macOS 10.11 and Xcode 7.3.1 - __Windows__: Windows 8.1 and Visual Studio 2015 64-bit - __Linux__: GCC 4.8 +- __Android__: Android Studio on Windows, macOS or Linux #### Deployment Targets + - __macOS__: macOS 10.7 - __Windows__: Windows Vista - __Linux__: Mainstream Linux distributions +- __iOS__: iOS 9.0 +- __Android__: Jelly Bean (API 16) ## Contributing + For bug reports and features requests, please visit the [JUCE Forum](https://forum.juce.com/) - the JUCE developers are active there and will read every post and respond accordingly. When submitting a bug report, please ensure that it follows the @@ -48,16 +81,17 @@ We don't accept third party GitHub pull requests directly due to copyright restr but if you would like to contribute any changes please contact us. ## License + The core JUCE modules (juce_audio_basics, juce_audio_devices, juce_blocks_basics, juce_core and juce_events) are permissively licensed under the terms of the [ISC license](http://www.isc.org/downloads/software-support-policy/isc-license/). Other modules are covered by a [GPL/Commercial license](https://www.gnu.org/licenses/gpl-3.0.en.html). -There are multiple commercial licensing tiers for JUCE 5, with different terms for each: +There are multiple commercial licensing tiers for JUCE, with different terms for each: - JUCE Personal (developers or startup businesses with revenue under 50K USD) - free -- JUCE Indie (small businesses with revenue under 200K USD) - $35/month -- JUCE Pro (no revenue limit) - $65/month +- JUCE Indie (small businesses with revenue under 500K USD) - $40/month +- JUCE Pro (no revenue limit) - $130/month - JUCE Educational (no revenue limit) - free for bona fide educational institutes For full terms see [LICENSE.md](LICENSE.md). diff --git a/docs/CMake API.md b/docs/CMake API.md new file mode 100644 index 00000000..5328f44c --- /dev/null +++ b/docs/CMake API.md @@ -0,0 +1,689 @@ +# The JUCE CMake API + +## System Requirements + +- Console and GUI projects require CMake 3.12 or higher. +- Plugin projects require CMake 3.15 or higher. +- All iOS targets require CMake 3.14 or higher (3.15 or higher for plugins targeting iOS). +- Android targets are not currently supported. +- WebView2 on Windows via JUCE_USE_WIN_WEBVIEW2 flag in juce_gui_extra is not currently supported. + +Most system package managers have packages for CMake, but we recommend using the most recent release +from https://cmake.org/download. You should always use a CMake that's newer than your build +toolchain, so that CMake can identify your build tools and understand how to invoke them. + +In addition to CMake you'll need a build toolchain for your platform, such as Xcode or MSVC. + +## Getting Started + +### Using `add_subdirectory` + +The simplest way to include JUCE in your project is to add JUCE as a +subdirectory of your project, and to include the line `add_subdirectory(JUCE)` +in your project CMakeLists.txt. This will make the JUCE targets and helper +functions available for use by your custom targets. + +### Using `find_package` + +To install JUCE globally on your system, you'll need to tell CMake where to +place the installed files. + + # Go to JUCE directory + cd /path/to/clone/JUCE + # Configure build with library components only + cmake -B cmake-build-install -DCMAKE_INSTALL_PREFIX=/path/to/JUCE/install + # Run the installation + cmake --build cmake-build-install --target install + +In your project which consumes JUCE, make sure the project CMakeLists.txt contains the line +`find_package(JUCE CONFIG REQUIRED)`. This will make the JUCE modules and CMake helper functions +available for use in the rest of your build. Then, run the build like so: + + # Go to project directory + cd /path/to/my/project + # Configure build, passing the JUCE install path you used earlier + cmake -B cmake-build -DCMAKE_PREFIX_PATH=/path/to/JUCE/install + # Build the project + cmake --build cmake-build + +### Example projects + +In the JUCE/examples/CMake directory, you'll find example projects for a GUI app, a console app, +and an audio plugin. You can simply copy one of these subdirectories out of the JUCE repo, add JUCE +as a submodule, and uncomment the call to `add_subdirectory` where indicated in the CMakeLists.txt. +Alternatively, if you've installed JUCE using a package manager or the CMake install target, you can +uncomment the call to `find_package`. + +Once your project is set up, you can generate a build tree for it in the normal way. To get started, +you might invoke CMake like this, from the new directory you created. + + cmake -Bbuild (-GgeneratorName) (-DJUCE_BUILD_EXTRAS=ON) (-DJUCE_BUILD_EXAMPLES=ON) + +This will create a build tree in a directory named 'build', using the CMakeLists in the current +working directory, using the default generator (makefiles on mac/linux, and the most recent Visual +Studio on Windows). You can choose a specific generator to use with the `-G` flag (call `cmake -G` +to see a full list of generators on your platform). If you included JUCE as a subdirectory, you can +enable the Extras and Examples targets by including the last two arguments (they're off by default). +There's quite a lot of example projects, and generating project files might take a bit longer when +these options are on, so you probably won't want to include them most of the time. + +Then, to build the project: + + cmake --build build (--target targetNameFromCMakeLists) (--config Release/Debug/...) + +This tells cmake to build the target named `targetNameFromCMakeLists`, in the specified +configuration, using the appropriate tool. Of course, if you generated makefiles or ninja files, you +could call `make` or `ninja` in the build directory. If you generated an IDE project, like an Xcode +or Visual Studio project, then you could open the generated project in your IDE. + +### Building for iOS + +To build for iOS, you'll need CMake 3.14 or higher. Using the Xcode generator is highly recommended, +as other generators may not automatically find the correct SDK for the iPhone simulator, and may +fail to run certain parts of the build, such as compiling icons and processing the app's plist. By +default, CMake will build for the same system that originally configured the project, so to enable +cross-compilation for iOS, a few extra flags must be passed to the initial CMake invocation: + + cmake -Bbuild-ios -GXcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_DEPLOYMENT_TARGET=9.3 + +Here we create a build tree in the directory named 'build-ios', using the Xcode generator. The +`-DCMAKE_SYSTEM_NAME=iOS` option tells CMake to enable cross-compiling for iOS. The +`-DCMAKE_OSX_DEPLOYMENT_TARGET=9.3` option sets the minimum deployment target (it applies to iOS +despite the 'OSX' in the variable name!). + +Once the project has generated, we can open it as normal in Xcode (look for the project file in the +build directory). Alternatively, to build from the command-line, we could run this command: + + cmake --build build-ios --target -- -sdk iphonesimulator + +Here, we're building the target named `` from the build tree in the directory +`build-ios`. All the arguments after `--` are ignored by CMake, and are passed through to the +underlying build tool. In this case, the build tool will be `xcodebuild` because we used the Xcode +generator above. We tell xcodebuild that we're building the app for the iOS simulator, which doesn't +require special code signing. + +If we wanted to build for a real device, we would need to pass some extra signing details to the +initial CMake configuration command: + + cmake -Bbuild-ios -GXcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_DEPLOYMENT_TARGET=9.3 \ + -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY="iPhone Developer" + -DCMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM=<10 character id> + +The `CODE_SIGN_IDENTITY` is the kind of certificate you want to use (iPhone Developer is appropriate +for development) and `DEVELOPMENT_TEAM` is the 10-character ID that can be found by opening the +Keychain Access app, finding your development certificate, and checking its 'Organizational Unit' +info field. + +When building the target, you may also need to tell Xcode that it can automatically update +provisioning profiles, which is achieved by passing the `-allowProvisioningUpdates` flag: + + cmake --build build-ios --target -- -allowProvisioningUpdates + +#### Archiving for iOS + +CMake's out-of-the-box archiving behaviour doesn't always work as expected, especially for targets +that depend on static libraries (such as targets added with `juce_add_binary_data`). Xcode may +generate these libraries into a 'DerivedData' directory, but then omit this directory from the +library search paths later in the build. + +If the "Product -> Archive" action isn't working, the following steps may help correct the issue: + +- On your static library, explicitly set the `ARCHIVE_OUTPUT_DIRECTORY` property. + ``` + set_target_properties(my_static_lib_target PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "./") + ``` +- Now, the Archive build should complete without linker errors, but the archived product may still + be hidden in the Organizer window. To fix this issue, set the following properties on the target + representing the actual iOS app. If your target was added with `juce_add_gui_app`, pass the same + target name. Otherwise, if your target was added with `juce_add_plugin` you may need to append + `_Standalone` to the target name, to specify the standalone plugin target. + ``` + set_target_properties(my_ios_app_target PROPERTIES + XCODE_ATTRIBUTE_INSTALL_PATH "$(LOCAL_APPS_DIR)" + XCODE_ATTRIBUTE_SKIP_INSTALL "NO") + ``` + +### Building universal binaries for macOS + +Building universal binaries that will run on both arm64 and x86_64 can be achieved by +configuring the CMake project with `"-DCMAKE_OSX_ARCHITECTURES=arm64;x86_64"`. + +### A note about compile definitions + +Module options and plugin options that would previously have been set in the Projucer can be set on +a target-by-target basis in CMake, via `target_compile_definitions`. To find the options exposed by +a particular module, check its module header for sections with the following structure: + + /** Config: NAME_OF_KEY + Docs go here... + */ + #ifndef NAME_OF_KEY + #define NAME_OF_KEY ... + #endif + +To override the default config option, use the following CMake code, replacing `` as +appropriate: + + target_compile_definitions(my_target PUBLIC NAME_OF_KEY=) + +The `JucePlugin_PreferredChannelConfig` preprocessor definition for plugins is difficult to specify +in a portable way due to its use of curly braces, which may be misinterpreted in Linux/Mac builds +using the Ninja/Makefile generators. It is recommended to avoid this option altogether, and to use +the newer buses API to specify the desired plugin inputs and outputs. + +## API Reference + +### Options + +These flags can be enabled or disabled to change the behaviour of parts of the JUCE build. + +These options would normally be configured by either: +- Supplying an option in the form `-DNAME_OF_OPTION=ON/OFF` to the initial CMake configuration call, + or +- Calling `set(NAME_OF_OPTION ON/OFF)` before including JUCE in your project via `add_subdirectory` + or `find_package`. + +#### `JUCE_BUILD_EXTRAS` + +This controls whether targets are added for the projects in the 'extras' folder, such as the +Projucer and AudioPluginHost. This is off by default, because you probably won't need these targets +if you've included JUCE in your own project. + +#### `JUCE_BUILD_EXAMPLES` + +This controls whether targets are added for the projects in the 'examples' folder, such as the +DemoRunner and PIPs. This is off by default, because you probably won't need these targets if you've +included JUCE in your own project. + +#### `JUCE_ENABLE_MODULE_SOURCE_GROUPS` + +This option controls whether dummy targets are added to the build, where these targets contain all +of the source files for each module added with `juce_add_module(s)`. If you're planning to use an +IDE and want to be able to browse all of JUCE's source files, this may be useful. However, it will +increase the size of generated IDE projects and might slow down configuration a bit. If you enable +this, you should probably also add `set_property(GLOBAL PROPERTY USE_FOLDERS YES)` to your top level +CMakeLists, otherwise the module sources will be added directly to the top level of the project, +instead of in a nice 'Modules' subfolder. + +#### `JUCE_COPY_PLUGIN_AFTER_BUILD` + +Controls whether plugin targets should be installed to the system after building. Note that the +plugin folders may be protected, so the build may require elevated permissions in order for the +installation to work correctly, or you may need to adjust the permissions of the destination +folders. + +### Functions + +#### `juce_add_` + + juce_add_gui_app( [KEY value]...) + juce_add_console_app( [KEY value]...) + juce_add_plugin( [KEY value]...) + +`juce_add_gui_app` and `juce_add_console_app` add an executable target with name ``. +`juce_add_plugin` adds a 'shared code' static library target with name ``, along with extra +targets for each of the specified plugin formats. Each of these functions also takes a number of +optional arguments in the form of a `KEY` followed by one or more `value`s which can be used to set +additional attributes of the target. If these optional arguments aren't specified, their values will +fall back to sensible defaults. + +Each of these arguments adds a property to the resulting target in the form `JUCE_paramName`, where +`paramName` is one of the parameter keys below. For example, after a call to +`juce_add_gui_app(my_target PRODUCT_NAME "Target")`, the target `my_target` will have a property +named `JUCE_PRODUCT_NAME` with the value `"Target"`. After creating a target with one of these +commands, properties beginning with `JUCE_` can be _queried_, but changing their values might not +have any effect (or might even break things in unexpected ways!), so always pass JUCE target +attributes directly to these creation functions, rather than adding them later. + +- `PRODUCT_NAME` + - The name of the output built by this target, similar to CMake's `OUTPUT_NAME` property. If not + specified, this will default to the target name. + +- `VERSION` + - A version number string in the format "major.minor.bugfix". If not specified, the `VERSION` of + the project containing the target will be used instead. + +- `BUNDLE_ID` + - An identifier string in the form "com.yourcompany.productname" which should uniquely identify + this target. Mainly used for macOS builds. If not specified, a default will be generated using + the target's `COMPANY_NAME` and `PRODUCT_NAME`. + +- `MICROPHONE_PERMISSION_ENABLED` + - May be either TRUE or FALSE. Adds the appropriate entries to an app's Info.plist. + +- `MICROPHONE_PERMISSION_TEXT` + - The text your app will display when it requests microphone permissions. + +- `CAMERA_PERMISSION_ENABLED` + - May be either TRUE or FALSE. Adds the appropriate entries to an app's Info.plist. + +- `CAMERA_PERMISSION_TEXT` + - The text your app will display when it requests camera permissions. + +- `BLUETOOTH_PERMISSION_ENABLED` + - May be either TRUE or FALSE. Adds the appropriate entries to an app's Info.plist. + +- `BLUETOOTH_PERMISSION_TEXT` + - The text your app will display when it requests bluetooth permissions. + +- `SEND_APPLE_EVENTS_PERMISSION_ENABLED` + - May be either TRUE or FALSE. Enable this to allow your app to send Apple events. + +- `SEND_APPLE_EVENTS_PERMISSION_TEXT` + - The text your app will display when it requests permission to send Apple events. + +- `FILE_SHARING_ENABLED` + - May be either TRUE or FALSE. Adds the appropriate entries to an iOS app's Info.plist. + +- `DOCUMENT_BROWSER_ENABLED` + - May be either TRUE or FALSE. Adds the appropriate entries to an iOS app's Info.plist. + +- `STATUS_BAR_HIDDEN` + - May be either TRUE or FALSE. Adds the appropriate entries to an iOS app's Info.plist. + +- `BACKGROUND_AUDIO_ENABLED` + - May be either TRUE or FALSE. Adds the appropriate entries to an iOS app's Info.plist. + +- `BACKGROUND_BLE_ENABLED` + - May be either TRUE or FALSE. Adds the appropriate entries to an iOS app's Info.plist. + +- `APP_GROUPS_ENABLED` + - May be either TRUE or FALSE. Adds the appropriate entries to an iOS app's entitlements. + +- `APP_GROUP_IDS` + - The app groups to which your iOS app belongs. These will be added to your app's entitlements. + +- `ICLOUD_PERMISSIONS_ENABLED` + - May be either TRUE or FALSE. Adds the appropriate entries to an iOS app's entitlements. + +- `IPHONE_SCREEN_ORIENTATIONS` + - May be one or more of `UIInterfaceOrientationUnknown`, `UIInterfaceOrientationPortrait`, + `UIInterfaceOrientationPortraitUpsideDown`, `UIInterfaceOrientationLandscapeLeft`, or + `UIInterfaceOrientationLandscapeRight`. Adds appropriate entries to an iOS app's plist. + +- `IPAD_SCREEN_ORIENTATIONS` + - May be one or more of `UIInterfaceOrientationUnknown`, `UIInterfaceOrientationPortrait`, + `UIInterfaceOrientationPortraitUpsideDown`, `UIInterfaceOrientationLandscapeLeft`, or + `UIInterfaceOrientationLandscapeRight`. Adds appropriate entries to an iOS app's plist. + +- `LAUNCH_STORYBOARD_FILE` + - A custom launch storyboard file to use on iOS. If not supplied, a default storyboard will be + used. + +- `CUSTOM_XCASSETS_FOLDER` + - A path to an xcassets directory, containing icons and/or launch images for this target. If this + is specified, the ICON_BIG and ICON_SMALL arguments will not have an effect on iOS, and a launch + storyboard will not be used. + +- `ICON_BIG`, `ICON_SMALL` + - Paths to image files that will be used to generate app icons. If only one of these parameters + is specified, then that image will be used for all icon resolutions. If both arguments are + specified, then the appropriate image will be picked for each icon resolution. + +- `COMPANY_COPYRIGHT` + - Copyright text which will be added to the app/plugin's Info.plist. The value of this argument + will be inherited from the `JUCE_COMPANY_COPYRIGHT` property, so if you want to use the same + `COMPANY_COPYRIGHT` for several targets in a build tree, you can call + `set_directory_properties(PROPERTIES JUCE_COMPANY_COPYRIGHT ...)` after including JUCE but + before adding the targets, and then omit the `COMPANY_COPYRIGHT` argument when creating the + individual targets. + +- `COMPANY_NAME` + - The name of this target's author. Will be added to the app/plugin's Info.plist, and may be used + to generate part of the `BUNDLE_ID` if no ID was given explicitly. The value of this argument + will be inherited from the `JUCE_COMPANY_NAME` property, so if you want to use the same + `COMPANY_NAME` for several targets in a build tree, you can call + `set_directory_properties(PROPERTIES JUCE_COMPANY_NAME ...)` after including JUCE but before + adding the targets, and then omit the `COMPANY_NAME` argument when creating the individual + targets. + +- `COMPANY_WEBSITE` + - The address of a website related to this target in some way. The value of this argument will be + inherited from the `JUCE_COMPANY_WEBSITE` property, so if you want to use the same + `COMPANY_WEBSITE` for several targets in a build tree, you can call + `set_directory_properties(PROPERTIES JUCE_COMPANY_WEBSITE ...)` after including JUCE but before + adding the targets, and then omit the `COMPANY_WEBSITE` argument when creating the individual + targets. + +- `COMPANY_EMAIL` + - An email address for this target's author. The value of this argument will be inherited from the + `JUCE_COMPANY_EMAIL` property, so if you want to use the same `COMPANY_EMAIL` for several + targets in a build tree, you can call `set_directory_properties(PROPERTIES JUCE_COMPANY_EMAIL + ...)` after including JUCE but before adding the targets, and then omit the `COMPANY_EMAIL` + argument when creating the individual targets. + +- `DOCUMENT_EXTENSIONS` + - File extensions that should be associated with this target. For example, the Projucer passes + the string `jucer` because it wants to open `.jucer` files. If your target has several different + document types, you can pass them as multiple arguments, e.g. `DOCUMENT_EXTENSIONS wav mp3 aif`. + +- `NEEDS_CURL` + - On Linux, JUCE may or may not need to link to Curl depending on the compile definitions that are + set on a JUCE target. By default, we don't link Curl because you might not need it, but if you + get linker or include errors that reference Curl, just set this argument to `TRUE`. + +- `NEEDS_WEB_BROWSER` + - On Linux, JUCE may or may not need to link to Webkit depending on the compile definitions that + are set on a JUCE target. By default, we don't link Webkit because you might not need it, but + if you get linker or include errors that reference Webkit, just set this argument to `TRUE`. + +- `NEEDS_STORE_KIT` + - On macOS, JUCE may or may not need to link to StoreKit depending on the compile definitions that + are set on a JUCE target. By default, we don't link StoreKit because you might not need it, but + if you get linker or include errors that reference StoreKit, just set this argument to `TRUE`. + +- `PUSH_NOTIFICATIONS_ENABLED` + - Sets app entitlements to allow push notifications. False by default. + +- `HARDENED_RUNTIME_ENABLED` + - Enables macOS' hardened runtime for this target. Required for notarisation. False by default. + +- `HARDENED_RUNTIME_OPTIONS` + - A set of space-separated entitlement keys that will be added to this target's entitlements + plist if `HARDENED_RUNTIME_ENABLED` is `TRUE`. Each key should be in the form + `com.apple.security.*` where `*` is a specific entitlement. + +- `APP_SANDBOX_ENABLED` + - Enables macOS' app sandbox for this target. False by default. + +- `APP_SANDBOX_INHERIT` + - Allows child processes to inherit the static entitlements of their parent process. If this + is set to `TRUE`, no other app sandbox entitlements will be set on this target. + +- `APP_SANDBOX_OPTIONS` + - A set of space-separated entitlement keys that will be added to this target's entitlements + plist if `APP_SANDBOX_ENABLED` is `TRUE`. Each key should be in the form `com.apple.security.*` + where `*` is a specific entitlement. + +- `PLIST_TO_MERGE` + - A string to insert into an app/plugin's Info.plist. + +- `FORMATS` + - For plugin targets, specifies the plugin targets to build. Should be provided as a + space-separated list. Valid values are `Standalone Unity VST3 AU AUv3 AAX VST`. `AU` and `AUv3` + plugins will only be enabled when building on macOS. It is an error to pass `AAX` or `VST` + without first calling `juce_set_aax_sdk_path` or `juce_set_vst2_sdk_path` respectively. + +- `PLUGIN_NAME` + - The name of the plugin. In a DAW environment, this is the name that will be displayed to the + user when they go to load a plugin. This name may differ from the name of the physical plugin + file (to set the name of the plugin file, use the `PRODUCT_NAME` option). If not specified, + the `PLUGIN_NAME` will default to match the `PRODUCT_NAME`. + +- `PLUGIN_MANUFACTURER_CODE` + - A four-character unique ID for your company. For AU compatibility, this must contain at least + one upper-case letter. + +- `PLUGIN_CODE` + - A four-character unique ID for your plugin. For AU compatibility, this must contain at least + one upper-case letter. + +- `DESCRIPTION` + - A short description of your plugin. + +- `IS_SYNTH` + - Whether the plugin is a synth. Will be used to set sensible plugin category values if they + are not provided explicitly. + +- `NEEDS_MIDI_INPUT` + - Whether the plugin should provide a midi input. + +- `NEEDS_MIDI_OUTPUT` + - Whether the plugin should provide a midi output. + +- `IS_MIDI_EFFECT` + - Whether the plugin is a MIDI effect (some hosts provide a special channel-strip location for + MIDI effect plugins). + +- `EDITOR_WANTS_KEYBOARD_FOCUS` + - Whether the plugin requires keyboard focus, or should defer all keyboard handling to the host. + +- `DISABLE_AAX_BYPASS` + - Whether the AAX bypass function should be disabled. + +- `DISABLE_AAX_MULTI_MONO` + - Whether the AAX multi mono bus layout should be disabled. + +- `AAX_IDENTIFIER` + - The bundle ID for the AAX plugin target. Matches the `BUNDLE_ID` by default. + +- `VST_NUM_MIDI_INS` + - For VST2 and VST3 plugins that accept midi, this allows you to configure the number of inputs. + +- `VST_NUM_MIDI_OUTS` + - For VST2 and VST3 plugins that produce midi, this allows you to configure the number of outputs. + +- `VST2_CATEGORY` + - Should be one of: `kPlugCategUnknown`, `kPlugCategEffect`, `kPlugCategSynth`, + `kPlugCategAnalysis`, `kPlugCategMatering`, `kPlugCategSpacializer`, `kPlugCategRoomFx`, + `kPlugSurroundFx`, `kPlugCategRestoration`, `kPlugCategOfflineProcess`, `kPlugCategShell`, + `kPlugCategGenerator`. + +- `VST3_CATEGORIES` + - Should be one or more, separated by spaces, of the following: `Fx`, `Instrument`, `Analyzer`, + `Delay`, `Distortion`, `Drum`, `Dynamics`, `EQ`, `External`, `Filter`, `Generator`, `Mastering`, + `Modulation`, `Mono`, `Network`, `NoOfflineProcess`, `OnlyOfflineProcess`, `OnlyRT`, + `Pitch Shift`, `Restoration`, `Reverb`, `Sampler`, `Spatial`, `Stereo`, `Surround`, `Synth`, + `Tools`, `Up-Downmix` + +- `AU_MAIN_TYPE` + - Should be one of: `kAudioUnitType_Effect`, `kAudioUnitType_FormatConverter`, + `kAudioUnitType_Generator`, `kAudioUnitType_MIDIProcessor`, `kAudioUnitType_Mixer`, + `kAudioUnitType_MusicDevice`, `kAudioUnitType_MusicEffect`, `kAudioUnitType_OfflineEffect`, + `kAudioUnitType_Output`, `kAudioUnitType_Panner` + +- `AU_EXPORT_PREFIX` + - A prefix for the names of entry-point functions that your component exposes. Typically this + will be a version of your plugin's name that can be used as part of a C++ token. Defaults + to your plugin's name with the suffix 'AU'. + +- `AU_SANDBOX_SAFE` + - May be either TRUE or FALSE. Adds the appropriate entries to an AU plugin's Info.plist. + +- `SUPPRESS_AU_PLIST_RESOURCE_USAGE` + - May be either TRUE or FALSE. Defaults to FALSE. Set this to TRUE to disable the `resourceUsage` + key in the target's plist. This is useful for AU plugins that must access resources which cannot + be declared in the resourceUsage block, such as UNIX domain sockets. In particular, + PACE-protected AU plugins may require this option to be enabled in order for the plugin to load + in GarageBand. + +- `AAX_CATEGORY` + - Should be one of: `AAX_ePlugInCategory_None`, `AAX_ePlugInCategory_EQ`, + `AAX_ePlugInCategory_Dynamics`, `AAX_ePlugInCategory_PitchShift`, `AAX_ePlugInCategory_Reverb`, + `AAX_ePlugInCategory_Delay`, `AAX_ePlugInCategory_Modulation`, `AAX_ePlugInCategory_Harmonic`, + `AAX_ePlugInCategory_NoiseReduction`, `AAX_ePlugInCategory_Dither`, + `AAX_ePlugInCategory_SoundField`, `AAX_ePlugInCategory_HWGenerators`, + `AAX_ePlugInCategory_SWGenerators`, `AAX_ePlugInCategory_WrappedPlugin`, + `AAX_ePlugInCategory_Effect` + +- `PLUGINHOST_AU` + - May be either TRUE or FALSE (defaults to FALSE). If TRUE, will add the preprocessor definition + `JUCE_PLUGINHOST_AU=1` to the new target, and will link the macOS frameworks necessary for + hosting plugins. Using this parameter should be preferred over using + `target_compile_definitions` to manually set the `JUCE_PLUGINHOST_AU` preprocessor definition. + +- `USE_LEGACY_COMPATIBILITY_PLUGIN_CODE` + - May be either TRUE or FALSE (defaults to FALSE). If TRUE, will override the value of the + preprocessor definition "JucePlugin_ManufacturerCode" with the hex equivalent of "proj". This + option exists to maintain compatiblity with a previous, buggy version of JUCE's CMake support + which mishandled the manufacturer code property. Most projects should leave this option set to + its default value. + +- `COPY_PLUGIN_AFTER_BUILD` + - Whether or not to install the plugin to the current system after building. False by default. + If you want all of the plugins in a subdirectory to be installed automatically after building, + you can set the property `JUCE_COPY_PLUGIN_AFTER_BUILD` on the directory before adding the + plugins, rather than setting this argument on each individual target. Note that on Windows, + the default install locations may not be writable by normal user accounts. + +- `VST_COPY_DIR` + - The location to which VST2 (legacy) plugins will be copied after building if + `COPY_PLUGIN_AFTER_BUILD` is set on this target. If you want to install all of the VST2 plugins + in a subdirectory to a non-default location, you can set the `JUCE_VST_COPY_DIR` property on + the directory before adding the plugin targets, rather than setting this argument on each + individual target. + +- `VST3_COPY_DIR` + - The location to which VST3 plugins will be copied after building if `COPY_PLUGIN_AFTER_BUILD` + is set on this target. If you want to install all of the VST3 plugins in a subdirectory to a + non-default location, you can set the `JUCE_VST3_COPY_DIR` property on the directory before + adding the plugin targets, rather than setting this argument on each individual target. + +- `AAX_COPY_DIR` + - The location to which AAX plugins will be copied after building if `COPY_PLUGIN_AFTER_BUILD` + is set on this target. If you want to install all of the AAX plugins in a subdirectory to a + non-default location, you can set the `JUCE_AAX_COPY_DIR` property on the directory before + adding the plugin targets, rather than setting this argument on each individual target. + +- `AU_COPY_DIR` + - The location to which AU plugins will be copied after building if `COPY_PLUGIN_AFTER_BUILD` + is set on this target. If you want to install all of the AU plugins in a subdirectory to a + non-default location, you can set the `JUCE_AU_COPY_DIR` property on the directory before + adding the plugin targets, rather than setting this argument on each individual target. + +- `UNITY_COPY_DIR` + - The location to which Unity plugins will be copied after building if `COPY_PLUGIN_AFTER_BUILD` + is set on this target. If you want to install all of the Unity plugins in a subdirectory to a + non-default location, you can set the `JUCE_UNITY_COPY_DIR` property on the directory before + adding the plugin targets, rather than setting this argument on each individual target. + Unlike the other `COPY_DIR` arguments, this argument does not have a default value so be sure + to set it if you have enabled `COPY_PLUGIN_AFTER_BUILD` and the `Unity` format. + +#### `juce_add_binary_data` + + juce_add_binary_data( + [HEADER_NAME ...] + [NAMESPACE ...] + SOURCES ...) + +Create a static library that embeds the contents of the files passed as arguments to this function. +Adds a library target called `` which can be linked into other targets using +`target_link_libraries`. + +The `HEADER_NAME` argument is optional. If provided, the generated header will be given the +requested name, otherwise the generated header will be named "BinaryData.h". In completely new +projects, you should provide a unique name here, so that projects containing more than one binary +data target are able to include the binary data headers without ambiguity. + +The `NAMESPACE` argument is also optional. If not provided, the generated files will use the default +namespace `BinaryData`. Each of the files located at the paths following `SOURCES` will be encoded +and embedded in the resulting static library. This library can be linked as normal using +`target_link_libraries( PRIVATE )`, and the header can be included using +`#include `. + +#### `juce_add_bundle_resources_directory` + + juce_add_bundle_resources_directory( ) + +Copy the entire directory at the location `` into an Apple bundle's resource directory, i.e. +the `Resources` directory for a macOS bundle, and the top-level directory of an iOS bundle. + +#### `juce_generate_juce_header` + + juce_generate_juce_header() + +Introspects the JUCE modules that have been linked to `` and generates a `JuceHeader.h` +which contains `#include` statements for each of the module headers. This header also contains an +optional `using namespace juce` statement, and an optional `ProjectInfo` block, each of which can be +disabled by setting the compile definitions `DONT_SET_USING_JUCE_NAMESPACE` and +`JUCE_DONT_DECLARE_PROJECTINFO` respectively. The resulting header can be included with `#include +`. In plain CMake projects which don't require Projucer compatibility, the use of +JuceHeader.h is optional. Instead, module headers can be included directly in source files that +require them. + +#### `juce_set__sdk_path` + + juce_set_aax_sdk_path() + juce_set_vst2_sdk_path() + +Call these functions from your CMakeLists to set up your local AAX and/or VST2 SDKs. These functions +should be called *before* adding any targets that may depend on the AAX/VST2 SDKs (plugin +hosts, VST2/AAX plugins etc.). + +#### `juce_add_module` + + juce_add_module() + juce_add_modules(...) + +`juce_add_module` adds a library target for the JUCE module located at the provided path. `` +must be the path to a module directory (e.g. /Users/me/JUCE/modules/juce_core). This will add an +interface library with a name matching the directory name of the module. The resulting library can +be linked to other targets as normal, using `target_link_libraries`. + +Due to the way that `INTERFACE` libraries work in CMake, linking to a module added in this way +*must* be done using `PRIVATE` visibility. Using `PUBLIC` will cause the module sources to be added +both to the target's `SOURCES` and `INTERFACE_SOURCES`, which may result in many copies of the +module being built into a single target, which would cause build failures in the best case and +silent ODR violations in the worst case. Scary stuff! + +This command has a few optional arguments: `INSTALL_PATH` is a path, relative to the install prefix, +to which the module sources will be copied during installation of the module. ALIAS_NAMESPACE will +add an alias for the module target(s) with the provided namespace. For example, the following +invocation will add a module target named `my_module`, along with an alias named +`company::my_module`. ``` juce_add_module(my_module ALIAS_NAMESPACE company)` ``` + +`juce_add_modules` is a convenience function that can be used to add multiple JUCE modules at once. +This version accepts many module paths, rather than just one. For an example of usage, see the +CMakeLists in the `modules` directory. + +#### `juce_add_pip` + + juce_add_pip(
) + +This function parses the PIP metadata block in the provided header, and adds appropriate build +targets for a console app, GUI app, or audio plugin. For audio plugin targets, it builds as many +plugin formats as possible. To build AAX or VST2 targets, call `juce_set_aax_sdk_path` and/or +`juce_set_vst2_sdk_path` *before* calling `juce_add_pip`. + +This is mainly provided to build the built-in example projects in the JUCE repo, and for building +quick proof-of-concept demo apps with minimal set-up. For any use-case more complex than a +proof-of-concept, you should prefer the `juce_add_gui_app`, `juce_add_plugin`, or +`juce_add_console_app` functions, which provide more fine-grained control over the properties of +your target. + +#### `juce_disable_default_flags` + + juce_disable_default_flags() + +This function sets the `CMAKE__FLAGS_` to empty in the current directory and below, +allowing alternative optimisation/debug flags to be supplied without conflicting with the +CMake-supplied defaults. + +### Targets + +#### `juce::juce_recommended_warning_flags` + + target_link_libraries(myTarget PUBLIC juce::juce_recommended_warning_flags) + +This is a target which can be linked to other targets using `target_link_libraries`, in order to +enable the recommended JUCE warnings when building them. + +This target just sets compiler and linker flags, and doesn't have any associated libraries or +include directories. When building plugins, it's probably desirable to link this to the shared code +target with `PUBLIC` visibility, so that all the plugin wrappers inherit the same compile/link +flags. + +#### `juce::juce_recommended_config_flags` + + target_link_libraries(myTarget PUBLIC juce::juce_recommended_config_flags) + +This is a target which can be linked to other targets using `target_link_libraries`, in order to +enable the recommended JUCE optimisation and debug flags. + +This target just sets compiler and linker flags, and doesn't have any associated libraries or +include directories. When building plugins, it's probably desirable to link this to the shared code +target with `PUBLIC` visibility, so that all the plugin wrappers inherit the same compile/link +flags. + +#### `juce::juce_recommended_lto_flags` + + target_link_libraries(myTarget PUBLIC juce::juce_recommended_lto_flags) + +This is a target which can be linked to other targets using `target_link_libraries`, in order to +enable the recommended JUCE link time optimisation settings. + +This target just sets compiler and linker flags, and doesn't have any associated libraries or +include directories. When building plugins, it's probably desirable to link this to the shared code +target with `PUBLIC` visibility, so that all the plugin wrappers inherit the same compile/link +flags. + diff --git a/modules/JUCE Module Format.txt b/docs/JUCE Module Format.md similarity index 51% rename from modules/JUCE Module Format.txt rename to docs/JUCE Module Format.md index ebe41e9f..911b3e2d 100644 --- a/modules/JUCE Module Format.txt +++ b/docs/JUCE Module Format.md @@ -1,6 +1,4 @@ - - The JUCE Module Format - ====================== +# The JUCE Module Format A JUCE module is a collection of header and source files which can be added to a project to provide a set of classes and libraries or related functionality. @@ -10,15 +8,14 @@ user projects on many platforms, either via automated tools, or by manual inclus Each module may have dependencies on other modules, but should be otherwise self-contained. - File structure - ============== +## File structure Each module lives inside a folder whose name is the same as the name of the module. The JUCE convention for naming modules is lower-case with underscores, e.g. -juce_core -juce_events -juce_graphics + juce_core + juce_events + juce_graphics But any name that is a valid C++ identifer is OK. @@ -27,14 +24,13 @@ the user's' project will include. The module may have as many other internal sou it needs, but these must all be inside sub-folders! -Master header file ------------------- +### Master header file In this root folder there must be ONE master header file, which includes all the necessary header files for the module. This header must have the same name as the module, with a .h/.hpp/.hxx suffix. E.g. -juce_core/juce_core.h + juce_core/juce_core.h IMPORTANT! All code within a module that includes other files from within its own subfolders must do so using RELATIVE paths! @@ -47,8 +43,7 @@ This master header file must also contain a comment with a BEGIN_JUCE_MODULE_DEC block which defines the module's requirements - the syntax for this is described later on.. -Module CPP files ----------------- +### Module CPP files A module consists of a single header file and zero or more .cpp files. Fewer is better! @@ -73,17 +68,18 @@ a number or other suffix if there is more than one. In order to specify that a source file should only be compiled on a specific platform, then the filename can be suffixed with one of the following strings: -_OSX -_Windows -_Linux -_Android -_iOS + _OSX + _Windows + _Linux + _Android + _iOS e.g. -juce_mymodule/juce_mymodule_1.cpp <- compiled on all platforms -juce_mymodule/juce_mymodule_2.cpp <- compiled on all platforms -juce_mymodule/juce_mymodule_OSX.cpp <- compiled only on OSX -juce_mymodule/juce_mymodule_Windows.cpp <- compiled only on Windows + + juce_mymodule/juce_mymodule_1.cpp <- compiled on all platforms + juce_mymodule/juce_mymodule_2.cpp <- compiled on all platforms + juce_mymodule/juce_mymodule_OSX.cpp <- compiled only on OSX + juce_mymodule/juce_mymodule_Windows.cpp <- compiled only on Windows Often this isn't necessary, as in most cases you can easily add checks inside the files to do different things depending on the platform, but this may be handy just to avoid @@ -94,8 +90,7 @@ both a .mm and a .cpp file whose names are otherwise identical, then on OSX/iOS will be used and the cpp ignored. (And vice-versa for other platforms, of course). -Precompiled libraries ---------------------- +### Precompiled libraries Precompiled libraries can be included in a module by placing them in a libs/ subdirectory. The following directories are automatically added to the library search paths, and libraries @@ -103,36 +98,35 @@ placed in these directories can be linked with projects via the OSXLibs, iOSLibs windowsLibs, linuxLibs and mingwLibs keywords in the module declaration (see the following section). -OS X: - libs/MacOSX/{arch}, where {arch} is the architecture you are targeting in Xcode ("x86_64" or +- OS X + - libs/MacOSX/{arch}, where {arch} is the architecture you are targeting in Xcode ("x86_64" or "i386", for example). -Visual Studio: - libs/VisualStudio{year}/{arch}/{run-time}, where {year} is the four digit year of the Visual Studio +- 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"). -Linux: - libs/Linux/{arch}, where {arch} is the architecture you are targeting with the compiler. Some +- Linux + - libs/Linux/{arch}, where {arch} is the architecture you are targeting with the compiler. Some common examples of {arch} are "x86_64", "i386" and "armv6". -MinGW: - libs/MinGW/{arch}, where {arch} can take the same values as Linux. +- MinGW + - libs/MinGW/{arch}, where {arch} can take the same values as Linux. -iOS: - libs/iOS/{arch}, where {arch} is the architecture you are targeting in Xcode ("arm64" or +- iOS + - libs/iOS/{arch}, where {arch} is the architecture you are targeting in Xcode ("arm64" or "x86_64", for example). -Android: - libs/Android/{arch}, where {arch} is the architecture provided by the Android Studio variable +- Android + - libs/Android/{arch}, where {arch} is the architecture provided by the Android Studio variable "${ANDROID_ABI}" ("x86", "armeabi-v7a", "mips", for example). - The BEGIN_JUCE_MODULE_DECLARATION block - ======================================= +## The BEGIN_JUCE_MODULE_DECLARATION block This block of text needs to go inside the module's main header file. It should be commented-out -and perhaps inside an #if 0 block too, but the Introjucer will just scan the whole file for the +and perhaps inside an `#if 0` block too, but the Introjucer will just scan the whole file for the string BEGIN_JUCE_MODULE_DECLARATION, and doesn't care about its context in terms of C++ syntax. The block needs a corresponding END_JUCE_MODULE_DECLARATION to finish the block. @@ -141,7 +135,7 @@ These should both be on a line of their own. Inside the block, the parser will expect to find a list of value definitions, one-per-line, with the very simple syntax - value_name: value + value_name: value The value_name must be one of the items listed below, and is case-sensitive. Whitespace on the line is ignored. Some values are compulsory and must be supplied, but others are optional. @@ -149,55 +143,89 @@ The order in which they're declared doesn't matter. Possible values: - ID: (Compulsory) This ID must match the name of the file and folder, e.g. juce_core. - The main reason for also including it here is as a sanity-check - vendor: (Compulsory) A unique ID for the vendor, e.g. "juce". This should be short - and shouldn't contain any spaces - version: (Compulsory) A version number for the module - name: (Compulsory) A short description of the module - description: (Compulsory) A longer description (but still only one line of text, please!) - - dependencies: (Optional) A list (space or comma-separated) of other modules that are required by - this one. The Introjucer can use this to auto-resolve dependencies. - website: (Optional) A URL linking to useful info about the module] - license: (Optional) A description of the type of software license that applies - minimumCppStandard: (Optional) A number indicating the minimum C++ language standard that is required for this module. - This must be just the standard number with no prefix e.g. 14 for C++14 - searchpaths: (Optional) A space-separated list of internal include paths, relative to the module's - parent folder, which need to be added to a project's header search path - OSXFrameworks: (Optional) A list (space or comma-separated) of OSX frameworks that are needed - by this module - iOSFrameworks: (Optional) Like OSXFrameworks, but for iOS targets - linuxPackages: (Optional) A list (space or comma-separated) pkg-config packages that should be used to pass - compiler (CFLAGS) and linker (LDFLAGS) flags - linuxLibs: (Optional) A list (space or comma-separated) of static or dynamic libs that should be linked in a - linux build (these are passed to the linker via the -l flag) - mingwLibs: (Optional) A list (space or comma-separated) of static libs that should be linked in a - win32 mingw build (these are passed to the linker via the -l flag) - OSXLibs: (Optional) A list (space or comma-separated) of static or dynamic libs that should be linked in an - OS X build (these are passed to the linker via the -l flag) - iOSLibs: (Optional) A list (space or comma-separated) of static or dynamic libs that should be linked in an - iOS build (these are passed to the linker via the -l flag) - windowsLibs: (Optional) A list (space or comma-separated) of static or dynamic libs that should be linked in a - Visual Studio build (without the .lib suffixes) +- ID + - (Compulsory) This ID must match the name of the file and folder, e.g. juce_core. + The main reason for also including it here is as a sanity-check + +- vendor + - (Compulsory) A unique ID for the vendor, e.g. "juce". This should be short + and shouldn't contain any spaces + +- version + - (Compulsory) A version number for the module + +- name + - (Compulsory) A short description of the module + +- description + - (Compulsory) A longer description (but still only one line of text, please!) + +- dependencies + - (Optional) A list (space or comma-separated) of other modules that are required by + this one. The Introjucer can use this to auto-resolve dependencies. + +- website + - (Optional) A URL linking to useful info about the module] + +- license + - (Optional) A description of the type of software license that applies + +- minimumCppStandard + - (Optional) A number indicating the minimum C++ language standard that is required for this module. + This must be just the standard number with no prefix e.g. 14 for C++14 + +- searchpaths + - (Optional) A space-separated list of internal include paths, relative to the module's + parent folder, which need to be added to a project's header search path + +- OSXFrameworks + - (Optional) A list (space or comma-separated) of OSX frameworks that are needed + by this module + +- iOSFrameworks + - (Optional) Like OSXFrameworks, but for iOS targets + +- linuxPackages + - (Optional) A list (space or comma-separated) pkg-config packages that should be used to pass + compiler (CFLAGS) and linker (LDFLAGS) flags + +- linuxLibs + - (Optional) A list (space or comma-separated) of static or dynamic libs that should be linked in a + linux build (these are passed to the linker via the -l flag) + +- mingwLibs + - (Optional) A list (space or comma-separated) of static libs that should be linked in a + win32 mingw build (these are passed to the linker via the -l flag) + +- OSXLibs + - (Optional) A list (space or comma-separated) of static or dynamic libs that should be linked in an + OS X build (these are passed to the linker via the -l flag) + +- iOSLibs + - (Optional) A list (space or comma-separated) of static or dynamic libs that should be linked in an + iOS build (these are passed to the linker via the -l flag) + +- windowsLibs + - (Optional) A list (space or comma-separated) of static or dynamic libs that should be linked in a + Visual Studio build (without the .lib suffixes) Here's an example block: - BEGIN_JUCE_MODULE_DECLARATION + BEGIN_JUCE_MODULE_DECLARATION - ID: juce_audio_devices - vendor: juce - version: 4.1.0 - 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 - license: GPL/Commercial + ID: juce_audio_devices + vendor: juce + version: 4.1.0 + 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 + license: GPL/Commercial - dependencies: juce_audio_basics, juce_audio_formats, juce_events - OSXFrameworks: CoreAudio CoreMIDI DiscRecording - iOSFrameworks: CoreAudio CoreMIDI AudioToolbox AVFoundation - linuxLibs: asound - mingwLibs: winmm + dependencies: juce_audio_basics, juce_audio_formats, juce_events + OSXFrameworks: CoreAudio CoreMIDI DiscRecording + iOSFrameworks: CoreAudio CoreMIDI AudioToolbox AVFoundation + linuxLibs: asound + mingwLibs: winmm - END_JUCE_MODULE_DECLARATION + END_JUCE_MODULE_DECLARATION diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 00000000..79b073a4 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,34 @@ +# JUCE Documentation + +This directory contains files documenting the JUCE Module Format, and the JUCE +CMake API. + +The JUCE modules themselves can be found in the `modules` subdirectory of the +JUCE repository. + +CMake example projects are located in the `examples/CMake` directory. + +The JUCE API itself is documented inline, but HTML docs can be generated from +the source code using the `doxygen` tool. These HTML docs can be [found +online](https://juce.com/learn/documentation), or you can generate a local copy +which can be used without an internet connection. For instructions on generating +offline docs, see below. + +# Generating Offline HTML Documentation + +## Dependencies + +- doxygen +- python +- make +- graphviz (to generate inheritance diagrams) + +Make sure that all the dependencies can be found on your PATH. + +## Building + +- cd into the `doxygen` directory on the command line +- run `make` + +Doxygen will create a new subdirectory "doc". Open doc/index.html in your browser +to access the generated HTML documentation. diff --git a/doxygen/Doxyfile b/docs/doxygen/Doxyfile similarity index 98% rename from doxygen/Doxyfile rename to docs/doxygen/Doxyfile index 1c0b6796..c7d11a83 100644 --- a/doxygen/Doxyfile +++ b/docs/doxygen/Doxyfile @@ -302,7 +302,7 @@ OPTIMIZE_OUTPUT_VHDL = NO # Note that for custom extensions you also need to set FILE_PATTERNS otherwise # the files are not read by doxygen. -EXTENSION_MAPPING = +EXTENSION_MAPPING = txt=md # If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments # according to the Markdown format, which allows for more readable @@ -801,7 +801,9 @@ WARN_LOGFILE = # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. -INPUT = build +INPUT = build \ + "../JUCE Module Format.md" \ + "../CMake API.md" # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses @@ -1056,25 +1058,6 @@ USE_HTAGS = NO VERBATIM_HEADERS = NO -# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the -# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the -# cost of reduced performance. This can be particularly helpful with template -# rich C++ code for which doxygen's built-in parser lacks the necessary type -# information. -# Note: The availability of this option depends on whether or not doxygen was -# compiled with the --with-libclang option. -# The default value is: NO. - -CLANG_ASSISTED_PARSING = NO - -# If clang assisted parsing is enabled you can provide the compiler with command -# line options that you would normally use when invoking the compiler. Note that -# the include paths will already be set by doxygen for the files and directories -# specified with INPUT and INCLUDE_PATH. -# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. - -CLANG_OPTIONS = - #--------------------------------------------------------------------------- # Configuration options related to the alphabetical class index #--------------------------------------------------------------------------- @@ -2166,12 +2149,6 @@ EXTERNAL_GROUPS = YES EXTERNAL_PAGES = YES -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of 'which perl'). -# The default file (with absolute path) is: /usr/bin/perl. - -PERL_PATH = /usr/bin/perl - #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- @@ -2185,15 +2162,6 @@ PERL_PATH = /usr/bin/perl CLASS_DIAGRAMS = YES -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see: -# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the -# default search path. - -MSCGEN_PATH = - # You can include diagrams made with dia in doxygen documentation. Doxygen will # then run dia to produce the diagram and insert it in the documentation. The # DIA_PATH tag allows you to specify the directory where the dia binary resides. diff --git a/doxygen/Makefile b/docs/doxygen/Makefile similarity index 56% rename from doxygen/Makefile rename to docs/doxygen/Makefile index d4f5d3eb..82604faf 100644 --- a/doxygen/Makefile +++ b/docs/doxygen/Makefile @@ -1,6 +1,6 @@ SHELL := /bin/bash -SOURCE_FILES := $(shell find ../modules -type f -name "juce_*.h" -or -name "juce_*.dox" | sed 's/ /\\ /g') +SOURCE_FILES := $(shell find ../../modules -type f -name "juce_*.h" -or -name "juce_*.dox" | sed 's/ /\\ /g') .PHONEY: clean @@ -8,7 +8,7 @@ doc/index.html: build/juce_modules.dox Doxyfile doxygen build/juce_modules.dox: process_source_files.py $(SOURCE_FILES) - python $< ../modules build + python $< ../../modules build clean: rm -rf build doc diff --git a/docs/doxygen/make.bat b/docs/doxygen/make.bat new file mode 100644 index 00000000..667edbe7 --- /dev/null +++ b/docs/doxygen/make.bat @@ -0,0 +1,2 @@ +python process_source_files.py ..\..\modules build +doxygen diff --git a/doxygen/process_source_files.py b/docs/doxygen/process_source_files.py similarity index 100% rename from doxygen/process_source_files.py rename to docs/doxygen/process_source_files.py diff --git a/doxygen/README.txt b/doxygen/README.txt deleted file mode 100644 index ec537aec..00000000 --- a/doxygen/README.txt +++ /dev/null @@ -1,23 +0,0 @@ -The JUCE API Reference -====================== - -From here, you can generate an offline HTML version of the JUCE API Reference. - -Dependencies ------------- - -- doxygen -- python -- graphviz (to generate inheritance diagrams) - -Make sure that all the dependencies can be found on your PATH. - -Building --------- - -- cd into this directory on the command line -- run `make` - -Doxygen will create a new subfolder "doc". Open doc/index.html in your browser -to access the generated HTML documentation. - diff --git a/doxygen/make.bat b/doxygen/make.bat deleted file mode 100644 index 1239654b..00000000 --- a/doxygen/make.bat +++ /dev/null @@ -1,2 +0,0 @@ -python process_source_files.py ..\modules build -doxygen diff --git a/examples/Assets/AudioLiveScrollingDisplay.h b/examples/Assets/AudioLiveScrollingDisplay.h index c68f062e..463dfc85 100644 --- a/examples/Assets/AudioLiveScrollingDisplay.h +++ b/examples/Assets/AudioLiveScrollingDisplay.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 diff --git a/examples/Assets/Box2DTests/ApplyForce.h b/examples/Assets/Box2DTests/ApplyForce.h index 5b5cd25d..57b90260 100644 --- a/examples/Assets/Box2DTests/ApplyForce.h +++ b/examples/Assets/Box2DTests/ApplyForce.h @@ -166,6 +166,9 @@ public: m_body->ApplyTorque(-50.0f); } break; + + default: + break; } } diff --git a/examples/Assets/DSPDemos_Common.h b/examples/Assets/DSPDemos_Common.h index 33a54ea6..589d597b 100644 --- a/examples/Assets/DSPDemos_Common.h +++ b/examples/Assets/DSPDemos_Common.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -312,8 +312,8 @@ struct DSPDemo : public AudioSource, inputSource->getNextAudioBlock (bufferToFill); - dsp::AudioBlock block (*bufferToFill.buffer, - (size_t) bufferToFill.startSample); + AudioBlock block (*bufferToFill.buffer, + (size_t) bufferToFill.startSample); ScopedLock audioLock (audioCallbackLock); this->process (ProcessContextReplacing (block)); diff --git a/examples/Assets/DemoUtilities.h b/examples/Assets/DemoUtilities.h index 0893cfc0..2901ac4d 100644 --- a/examples/Assets/DemoUtilities.h +++ b/examples/Assets/DemoUtilities.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -58,6 +58,8 @@ inline File getExamplesDirectory() noexcept jassert (success); return mo.toString(); + #elif defined PIP_JUCE_EXAMPLES_DIRECTORY_STRING + return File { PIP_JUCE_EXAMPLES_DIRECTORY_STRING }; #else auto currentFile = File::getSpecialLocation (File::SpecialLocationType::currentApplicationFile); auto exampleDir = currentFile.getParentDirectory().getChildFile ("examples"); @@ -65,20 +67,29 @@ inline File getExamplesDirectory() noexcept if (exampleDir.exists()) return exampleDir; - int numTries = 0; // keep track of the number of parent directories so we don't go on endlessly + // keep track of the number of parent directories so we don't go on endlessly + for (int numTries = 0; numTries < 15; ++numTries) + { + if (currentFile.getFileName() == "examples") + return currentFile; + + const auto sibling = currentFile.getSiblingFile ("examples"); + + if (sibling.exists()) + return sibling; - while (currentFile.getFileName() != "examples" && numTries++ < 15) currentFile = currentFile.getParentDirectory(); + } return currentFile; #endif } -inline InputStream* createAssetInputStream (const char* resourcePath) +inline std::unique_ptr createAssetInputStream (const char* resourcePath) { #if JUCE_ANDROID ZipFile apkZip (File::getSpecialLocation (File::invokedExecutableFile)); - return apkZip.createStreamForEntry (apkZip.getIndexOfFileName ("assets/" + String (resourcePath))); + return std::unique_ptr (apkZip.createStreamForEntry (apkZip.getIndexOfFileName ("assets/" + String (resourcePath)))); #else #if JUCE_IOS auto assetsDir = File::getSpecialLocation (File::currentExecutableFile) diff --git a/examples/Assets/Impulse1.wav b/examples/Assets/Impulse1.wav deleted file mode 100644 index 98d402cd04dacc98ae3386075de99995f3bf9c37..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 90246 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 diff --git a/examples/Assets/Impulse2.wav b/examples/Assets/Impulse2.wav deleted file mode 100644 index c548b22cdde8c51043aaf157de895583ff985847..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37902 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≻ynz0_3y9-O!1pgZY8eITJD(qbh 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 z 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� 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�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Ⓢ0oyshj|L_@pdVuX>Q0w1U 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

;6r*{C_+>IW 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 F{|5))HK70i literal 0 HcmV?d00001 diff --git a/examples/DemoRunner/Builds/Android/app/src/main/res/drawable-hdpi/icon.png b/examples/DemoRunner/Builds/Android/app/src/main/res/drawable-hdpi/icon.png index e551340cfb9cec7af90a789f6a24997379f37e46..3c54e0a5ba7c68eba81cf728b4ab8489f9608b11 100644 GIT binary patch literal 40234 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 UsHKwt+5i9m07*qoM6N<$f(3br=Kufz literal 34761 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 diff --git a/examples/DemoRunner/Builds/Android/app/src/main/res/drawable-ldpi/icon.png b/examples/DemoRunner/Builds/Android/app/src/main/res/drawable-ldpi/icon.png index 475d142e3535e0e8609f31fc4ecdf93c0ce81189..fb4d6f9e93342fd30954394ca328f5dbaaad2411 100644 GIT binary patch literal 19490 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 z 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 diff --git a/examples/DemoRunner/Builds/Android/app/src/main/res/drawable-mdpi/icon.png b/examples/DemoRunner/Builds/Android/app/src/main/res/drawable-mdpi/icon.png index eb13005911312450beed323cdc7498410e9ac661..c286139d3ca4d6dfa6d88ef5b091d05228ada6a3 100644 GIT binary patch literal 21536 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 ZfN^A+W{bp& diff --git a/examples/DemoRunner/Builds/Android/app/src/main/res/drawable-xhdpi/icon.png b/examples/DemoRunner/Builds/Android/app/src/main/res/drawable-xhdpi/icon.png index dddc79015e7f57a6cafaaedc9fc0d978a64b94fb..6c50b7d72fcd36b5e3a0296aad33b346e179fbd1 100644 GIT binary patch literal 43286 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 VDEUAsP}%^bEdNHXT;^lY{{dUgK=l9s literal 44823 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 Um%~c~?fXHJqH^D=g!Kdd2bwhvF8}}l diff --git a/examples/DemoRunner/Builds/Android/build.gradle b/examples/DemoRunner/Builds/Android/build.gradle index cfd3a2f8..0fe5b4aa 100644 --- a/examples/DemoRunner/Builds/Android/build.gradle +++ b/examples/DemoRunner/Builds/Android/build.gradle @@ -4,7 +4,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.5.3' + classpath 'com.android.tools.build:gradle:4.0.0' } } diff --git a/examples/DemoRunner/Builds/Android/gradle/wrapper/gradle-wrapper.properties b/examples/DemoRunner/Builds/Android/gradle/wrapper/gradle-wrapper.properties index b66802c7..49479605 100644 --- a/examples/DemoRunner/Builds/Android/gradle/wrapper/gradle-wrapper.properties +++ b/examples/DemoRunner/Builds/Android/gradle/wrapper/gradle-wrapper.properties @@ -1 +1 @@ -distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip \ No newline at end of file +distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip \ No newline at end of file diff --git a/examples/DemoRunner/Builds/LinuxMakefile/Makefile b/examples/DemoRunner/Builds/LinuxMakefile/Makefile index c9d711eb..25af0ad2 100644 --- a/examples/DemoRunner/Builds/LinuxMakefile/Makefile +++ b/examples/DemoRunner/Builds/LinuxMakefile/Makefile @@ -35,13 +35,13 @@ ifeq ($(CONFIG),Debug) TARGET_ARCH := 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.7 -DJUCE_APP_VERSION_HEX=0x50407 $(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_CPPFLAGS := $(DEPFLAGS) "-DLINUX=1" "-DDEBUG=1" "-D_DEBUG=1" "-DJUCE_DISPLAY_SPLASH_SCREEN=0" "-DJUCE_USE_DARK_SPLASH_SCREEN=1" "-DJUCE_PROJUCER_VERSION=0x60005" "-DJUCE_MODULE_AVAILABLE_juce_analytics=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_devices=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_formats=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_processors=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_utils=1" "-DJUCE_MODULE_AVAILABLE_juce_blocks_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_box2d=1" "-DJUCE_MODULE_AVAILABLE_juce_core=1" "-DJUCE_MODULE_AVAILABLE_juce_cryptography=1" "-DJUCE_MODULE_AVAILABLE_juce_data_structures=1" "-DJUCE_MODULE_AVAILABLE_juce_dsp=1" "-DJUCE_MODULE_AVAILABLE_juce_events=1" "-DJUCE_MODULE_AVAILABLE_juce_graphics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_extra=1" "-DJUCE_MODULE_AVAILABLE_juce_opengl=1" "-DJUCE_MODULE_AVAILABLE_juce_osc=1" "-DJUCE_MODULE_AVAILABLE_juce_product_unlocking=1" "-DJUCE_MODULE_AVAILABLE_juce_video=1" "-DJUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1" "-DJUCE_USE_MP3AUDIOFORMAT=1" "-DJUCE_ALLOW_STATIC_NULL_VARIABLES=0" "-DJUCE_STRICT_REFCOUNTEDPOINTER=1" "-DJUCE_USE_CAMERA=1" "-DJUCE_STANDALONE_APPLICATION=1" "-DJUCE_DEMO_RUNNER=1" "-DJUCE_UNIT_TESTS=1" "-DJUCER_LINUX_MAKE_6D53C8B4=1" "-DJUCE_APP_VERSION=6.0.5" "-DJUCE_APP_VERSION_HEX=0x60005" $(shell pkg-config --cflags alsa freetype2 libcurl 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 := DemoRunner JUCE_CFLAGS += $(JUCE_CPPFLAGS) $(TARGET_ARCH) -g -ggdb -O0 $(CFLAGS) JUCE_CXXFLAGS += $(JUCE_CFLAGS) -std=c++14 $(CXXFLAGS) - JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) $(shell pkg-config --libs alsa x11 xinerama xext freetype2 webkit2gtk-4.0 gtk+-x11-3.0 libcurl) -lrt -ldl -lpthread -lGL $(LDFLAGS) + JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) $(shell pkg-config --libs alsa freetype2 libcurl) -fvisibility=hidden -lrt -ldl -lpthread -lGL $(LDFLAGS) CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(TARGET) $(JUCE_OBJDIR) endif @@ -56,13 +56,13 @@ ifeq ($(CONFIG),Release) TARGET_ARCH := 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.7 -DJUCE_APP_VERSION_HEX=0x50407 $(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_CPPFLAGS := $(DEPFLAGS) "-DLINUX=1" "-DNDEBUG=1" "-DJUCE_DISPLAY_SPLASH_SCREEN=0" "-DJUCE_USE_DARK_SPLASH_SCREEN=1" "-DJUCE_PROJUCER_VERSION=0x60005" "-DJUCE_MODULE_AVAILABLE_juce_analytics=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_devices=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_formats=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_processors=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_utils=1" "-DJUCE_MODULE_AVAILABLE_juce_blocks_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_box2d=1" "-DJUCE_MODULE_AVAILABLE_juce_core=1" "-DJUCE_MODULE_AVAILABLE_juce_cryptography=1" "-DJUCE_MODULE_AVAILABLE_juce_data_structures=1" "-DJUCE_MODULE_AVAILABLE_juce_dsp=1" "-DJUCE_MODULE_AVAILABLE_juce_events=1" "-DJUCE_MODULE_AVAILABLE_juce_graphics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_extra=1" "-DJUCE_MODULE_AVAILABLE_juce_opengl=1" "-DJUCE_MODULE_AVAILABLE_juce_osc=1" "-DJUCE_MODULE_AVAILABLE_juce_product_unlocking=1" "-DJUCE_MODULE_AVAILABLE_juce_video=1" "-DJUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1" "-DJUCE_USE_MP3AUDIOFORMAT=1" "-DJUCE_ALLOW_STATIC_NULL_VARIABLES=0" "-DJUCE_STRICT_REFCOUNTEDPOINTER=1" "-DJUCE_USE_CAMERA=1" "-DJUCE_STANDALONE_APPLICATION=1" "-DJUCE_DEMO_RUNNER=1" "-DJUCE_UNIT_TESTS=1" "-DJUCER_LINUX_MAKE_6D53C8B4=1" "-DJUCE_APP_VERSION=6.0.5" "-DJUCE_APP_VERSION_HEX=0x60005" $(shell pkg-config --cflags alsa freetype2 libcurl 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 := DemoRunner JUCE_CFLAGS += $(JUCE_CPPFLAGS) $(TARGET_ARCH) -O3 $(CFLAGS) JUCE_CXXFLAGS += $(JUCE_CFLAGS) -std=c++14 $(CXXFLAGS) - JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) $(shell pkg-config --libs alsa x11 xinerama xext freetype2 webkit2gtk-4.0 gtk+-x11-3.0 libcurl) -fvisibility=hidden -lrt -ldl -lpthread -lGL $(LDFLAGS) + JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) $(shell pkg-config --libs alsa freetype2 libcurl) -fvisibility=hidden -lrt -ldl -lpthread -lGL $(LDFLAGS) CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(TARGET) $(JUCE_OBJDIR) endif @@ -101,7 +101,7 @@ all : $(JUCE_OUTDIR)/$(JUCE_TARGET_APP) $(JUCE_OUTDIR)/$(JUCE_TARGET_APP) : $(OBJECTS_APP) $(RESOURCES) @command -v pkg-config >/dev/null 2>&1 || { echo >&2 "pkg-config not installed. Please, install it."; exit 1; } - @pkg-config --print-errors alsa x11 xinerama xext freetype2 webkit2gtk-4.0 gtk+-x11-3.0 libcurl + @pkg-config --print-errors alsa freetype2 libcurl @echo Linking "DemoRunner - App" -$(V_AT)mkdir -p $(JUCE_BINDIR) -$(V_AT)mkdir -p $(JUCE_LIBDIR) diff --git a/examples/DemoRunner/Builds/MacOSX/App.entitlements b/examples/DemoRunner/Builds/MacOSX/App.entitlements deleted file mode 100644 index 6631ffa6..00000000 --- a/examples/DemoRunner/Builds/MacOSX/App.entitlements +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/examples/DemoRunner/Builds/MacOSX/DemoRunner.xcodeproj/project.pbxproj b/examples/DemoRunner/Builds/MacOSX/DemoRunner.xcodeproj/project.pbxproj index c7c730f1..3119b616 100644 --- a/examples/DemoRunner/Builds/MacOSX/DemoRunner.xcodeproj/project.pbxproj +++ b/examples/DemoRunner/Builds/MacOSX/DemoRunner.xcodeproj/project.pbxproj @@ -53,6 +53,10 @@ isa = PBXBuildFile; fileRef = 3DC90DA86565B0356B6E5E0B; }; + 5E4310B3F6BB639875D3E9B8 = { + isa = PBXBuildFile; + fileRef = 49ECA8B998B339A083674A22; + }; 8584640341100008744861A5 = { isa = PBXBuildFile; fileRef = 71A91516AFD980FEE694C0E1; @@ -380,6 +384,13 @@ path = "../../../../modules/juce_audio_formats"; sourceTree = "SOURCE_ROOT"; }; + 49ECA8B998B339A083674A22 = { + isa = PBXFileReference; + lastKnownFileType = wrapper.framework; + name = Foundation.framework; + path = System/Library/Frameworks/Foundation.framework; + sourceTree = SDKROOT; + }; 4DF215D350FFE5E119CBA7E5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; @@ -499,13 +510,6 @@ path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; }; - 72129757D2A553B90A7157C6 = { - isa = PBXFileReference; - lastKnownFileType = sourcecode.c.h; - name = AppConfig.h; - path = ../../JuceLibraryCode/AppConfig.h; - sourceTree = "SOURCE_ROOT"; - }; 7A5AAE9EE573FC6105CC4AAC = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; @@ -831,7 +835,6 @@ 61F3057D838D7DABB0FA3D34 = { isa = PBXGroup; children = ( - 72129757D2A553B90A7157C6, 5965349393850F41DF76F350, 03B0F9318FD583525AB195A9, 03A63C3CA6F24977F19C316D, @@ -887,6 +890,7 @@ 1CFE3935A3B810D5D68A2504, 61AE09C749B007B70A265D9B, 3DC90DA86565B0356B6E5E0B, + 49ECA8B998B339A083674A22, 71A91516AFD980FEE694C0E1, 40BD06D4AB0D2C73E936A2F1, 23CD1A3F9067C3A0ECE7BB67, @@ -931,11 +935,40 @@ GCC_PREPROCESSOR_DEFINITIONS = ( "_DEBUG=1", "DEBUG=1", + "JUCE_DISPLAY_SPLASH_SCREEN=0", + "JUCE_USE_DARK_SPLASH_SCREEN=1", + "JUCE_PROJUCER_VERSION=0x60005", + "JUCE_MODULE_AVAILABLE_juce_analytics=1", + "JUCE_MODULE_AVAILABLE_juce_audio_basics=1", + "JUCE_MODULE_AVAILABLE_juce_audio_devices=1", + "JUCE_MODULE_AVAILABLE_juce_audio_formats=1", + "JUCE_MODULE_AVAILABLE_juce_audio_processors=1", + "JUCE_MODULE_AVAILABLE_juce_audio_utils=1", + "JUCE_MODULE_AVAILABLE_juce_blocks_basics=1", + "JUCE_MODULE_AVAILABLE_juce_box2d=1", + "JUCE_MODULE_AVAILABLE_juce_core=1", + "JUCE_MODULE_AVAILABLE_juce_cryptography=1", + "JUCE_MODULE_AVAILABLE_juce_data_structures=1", + "JUCE_MODULE_AVAILABLE_juce_dsp=1", + "JUCE_MODULE_AVAILABLE_juce_events=1", + "JUCE_MODULE_AVAILABLE_juce_graphics=1", + "JUCE_MODULE_AVAILABLE_juce_gui_basics=1", + "JUCE_MODULE_AVAILABLE_juce_gui_extra=1", + "JUCE_MODULE_AVAILABLE_juce_opengl=1", + "JUCE_MODULE_AVAILABLE_juce_osc=1", + "JUCE_MODULE_AVAILABLE_juce_product_unlocking=1", + "JUCE_MODULE_AVAILABLE_juce_video=1", + "JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1", + "JUCE_USE_MP3AUDIOFORMAT=1", + "JUCE_ALLOW_STATIC_NULL_VARIABLES=0", + "JUCE_STRICT_REFCOUNTEDPOINTER=1", + "JUCE_USE_CAMERA=1", + "JUCE_STANDALONE_APPLICATION=1", "JUCE_DEMO_RUNNER=1", "JUCE_UNIT_TESTS=1", "JUCER_XCODE_MAC_F6D2F4CF=1", - "JUCE_APP_VERSION=5.4.7", - "JUCE_APP_VERSION_HEX=0x50407", + "JUCE_APP_VERSION=6.0.5", + "JUCE_APP_VERSION_HEX=0x60005", "JucePlugin_Build_VST=0", "JucePlugin_Build_VST3=0", "JucePlugin_Build_AU=0", @@ -955,10 +988,15 @@ INFOPLIST_PREPROCESS = NO; INSTALL_PATH = "$(HOME)/Applications"; MACOSX_DEPLOYMENT_TARGET = 10.11; - OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow-all -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wunreachable-code -Wzero-as-null-pointer-constant -Wcast-align -Winconsistent-missing-destructor-override -Wshift-sign-overflow -Wnullable-to-nonnull-conversion -Wno-missing-field-initializers -Wno-ignored-qualifiers"; - PRODUCT_BUNDLE_IDENTIFIER = com.juce.demorunner; + MTL_HEADER_SEARCH_PATHS = ( + "../../JuceLibraryCode", + "../../../../modules", + ); + OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow-all -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wunreachable-code -Wzero-as-null-pointer-constant -Wcast-align -Winconsistent-missing-destructor-override -Wshift-sign-overflow -Wnullable-to-nonnull-conversion -Wno-missing-field-initializers -Wno-ignored-qualifiers -Wswitch-enum"; + PRODUCT_BUNDLE_IDENTIFIER = com.rmsl.juce.demorunner; PRODUCT_NAME = "DemoRunner"; USE_HEADERMAP = NO; + VALID_ARCHS = "i386 x86_64 arm64 arm64e"; }; name = Debug; }; @@ -977,11 +1015,40 @@ GCC_PREPROCESSOR_DEFINITIONS = ( "_NDEBUG=1", "NDEBUG=1", + "JUCE_DISPLAY_SPLASH_SCREEN=0", + "JUCE_USE_DARK_SPLASH_SCREEN=1", + "JUCE_PROJUCER_VERSION=0x60005", + "JUCE_MODULE_AVAILABLE_juce_analytics=1", + "JUCE_MODULE_AVAILABLE_juce_audio_basics=1", + "JUCE_MODULE_AVAILABLE_juce_audio_devices=1", + "JUCE_MODULE_AVAILABLE_juce_audio_formats=1", + "JUCE_MODULE_AVAILABLE_juce_audio_processors=1", + "JUCE_MODULE_AVAILABLE_juce_audio_utils=1", + "JUCE_MODULE_AVAILABLE_juce_blocks_basics=1", + "JUCE_MODULE_AVAILABLE_juce_box2d=1", + "JUCE_MODULE_AVAILABLE_juce_core=1", + "JUCE_MODULE_AVAILABLE_juce_cryptography=1", + "JUCE_MODULE_AVAILABLE_juce_data_structures=1", + "JUCE_MODULE_AVAILABLE_juce_dsp=1", + "JUCE_MODULE_AVAILABLE_juce_events=1", + "JUCE_MODULE_AVAILABLE_juce_graphics=1", + "JUCE_MODULE_AVAILABLE_juce_gui_basics=1", + "JUCE_MODULE_AVAILABLE_juce_gui_extra=1", + "JUCE_MODULE_AVAILABLE_juce_opengl=1", + "JUCE_MODULE_AVAILABLE_juce_osc=1", + "JUCE_MODULE_AVAILABLE_juce_product_unlocking=1", + "JUCE_MODULE_AVAILABLE_juce_video=1", + "JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1", + "JUCE_USE_MP3AUDIOFORMAT=1", + "JUCE_ALLOW_STATIC_NULL_VARIABLES=0", + "JUCE_STRICT_REFCOUNTEDPOINTER=1", + "JUCE_USE_CAMERA=1", + "JUCE_STANDALONE_APPLICATION=1", "JUCE_DEMO_RUNNER=1", "JUCE_UNIT_TESTS=1", "JUCER_XCODE_MAC_F6D2F4CF=1", - "JUCE_APP_VERSION=5.4.7", - "JUCE_APP_VERSION_HEX=0x50407", + "JUCE_APP_VERSION=6.0.5", + "JUCE_APP_VERSION_HEX=0x60005", "JucePlugin_Build_VST=0", "JucePlugin_Build_VST3=0", "JucePlugin_Build_AU=0", @@ -991,7 +1058,6 @@ "JucePlugin_Build_Standalone=0", "JucePlugin_Build_Unity=0", ); - GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; HEADER_SEARCH_PATHS = ( "../../JuceLibraryCode", @@ -1003,10 +1069,15 @@ INSTALL_PATH = "$(HOME)/Applications"; LLVM_LTO = YES; MACOSX_DEPLOYMENT_TARGET = 10.11; - OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow-all -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wunreachable-code -Wzero-as-null-pointer-constant -Wcast-align -Winconsistent-missing-destructor-override -Wshift-sign-overflow -Wnullable-to-nonnull-conversion -Wno-missing-field-initializers -Wno-ignored-qualifiers"; - PRODUCT_BUNDLE_IDENTIFIER = com.juce.demorunner; + MTL_HEADER_SEARCH_PATHS = ( + "../../JuceLibraryCode", + "../../../../modules", + ); + OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow-all -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wunreachable-code -Wzero-as-null-pointer-constant -Wcast-align -Winconsistent-missing-destructor-override -Wshift-sign-overflow -Wnullable-to-nonnull-conversion -Wno-missing-field-initializers -Wno-ignored-qualifiers -Wswitch-enum"; + PRODUCT_BUNDLE_IDENTIFIER = com.rmsl.juce.demorunner; PRODUCT_NAME = "DemoRunner"; USE_HEADERMAP = NO; + VALID_ARCHS = "i386 x86_64 arm64 arm64e"; }; name = Release; }; @@ -1035,11 +1106,12 @@ CODE_SIGN_IDENTITY = ""; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; + ENABLE_TESTABILITY = NO; GCC_C_LANGUAGE_STANDARD = c11; GCC_INLINES_ARE_PRIVATE_EXTERN = YES; GCC_MODEL_TUNING = G5; GCC_NO_COMMON_BLOCKS = YES; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; @@ -1083,10 +1155,12 @@ CODE_SIGN_IDENTITY = ""; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = NO; GCC_C_LANGUAGE_STANDARD = c11; GCC_INLINES_ARE_PRIVATE_EXTERN = YES; GCC_MODEL_TUNING = G5; GCC_NO_COMMON_BLOCKS = YES; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; @@ -1104,10 +1178,6 @@ }; name = Release; }; - D87BAF6D1A7451B7A733B5F1 = { - isa = PBXTargetDependency; - target = 291E01DCBE746A376DBFA4D1; - }; 80E8AD1971F52B06F4D28891 = { isa = XCConfigurationList; buildConfigurations = ( @@ -1189,6 +1259,7 @@ 46071CE2B98B562B7BF27CB1, 6A61CBB4E39BFD392D97528F, 9BEA1428416CE06BF72FBAB8, + 5E4310B3F6BB639875D3E9B8, 8584640341100008744861A5, 028383D0577D0236899D8CA5, B1981F62F6A91FD2F579A198, @@ -1214,7 +1285,7 @@ AC6F0E9A0809A184B2C2B7DE = { isa = PBXProject; buildConfigurationList = 80E8AD1971F52B06F4D28891; - attributes = { LastUpgradeCheck = 1100; ORGANIZATIONNAME = "ROLI Ltd."; TargetAttributes = { 291E01DCBE746A376DBFA4D1 = { SystemCapabilities = {com.apple.ApplicationGroups.iOS = { enabled = 0; }; com.apple.InAppPurchase = { enabled = 0; }; com.apple.InterAppAudio = { enabled = 0; }; com.apple.Push = { enabled = 0; }; com.apple.Sandbox = { enabled = 0; }; com.apple.HardenedRuntime = { enabled = 0; }; }; }; }; }; + attributes = { LastUpgradeCheck = 1200; ORGANIZATIONNAME = "Raw Material Software Limited"; TargetAttributes = { 291E01DCBE746A376DBFA4D1 = { SystemCapabilities = {com.apple.ApplicationGroups.iOS = { enabled = 0; }; com.apple.InAppPurchase = { enabled = 0; }; com.apple.InterAppAudio = { enabled = 0; }; com.apple.Push = { enabled = 0; }; com.apple.Sandbox = { enabled = 0; }; com.apple.HardenedRuntime = { enabled = 0; }; }; }; }; }; compatibilityVersion = "Xcode 3.2"; hasScannedForEncodings = 0; mainGroup = 91A9A0FE9DF4F4E10009EEC7; diff --git a/examples/DemoRunner/Builds/MacOSX/DemoRunner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/examples/DemoRunner/Builds/MacOSX/DemoRunner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings index 949b6789..f2e3cbe8 100644 --- a/examples/DemoRunner/Builds/MacOSX/DemoRunner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ b/examples/DemoRunner/Builds/MacOSX/DemoRunner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -4,5 +4,7 @@ BuildSystemType Original + DisableBuildSystemDeprecationWarning + diff --git a/examples/DemoRunner/Builds/MacOSX/Icon.icns b/examples/DemoRunner/Builds/MacOSX/Icon.icns index 6ab6915802b8cc41702a02e8527aec517d379e77..52f40fef1039ef1c4890e481085bd003b0759197 100644 GIT binary patch literal 86596 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

)zIf>+%W#_ZSNefRdI{!UXoEVBYS~PC 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 literal 89670 zcmd3NWm{D57w#~0Bhrnuh_rNfH%NE4fOLaMNQrcJOLsTYCEfh!?igmy_J5u89S$#M zcr(w6z3REwy=~2%+(2+f(zfPod?3(o%1BjZ8B8=1G!O`cDJLtb4g!IJf59LWB;f1T zYyKJdLU0q8(?kLO{7@{ugFsXuIY}{1ugueR&s2lKUp!mJ>%IaH1KHV`1@!U-nebr5 zkjQr==DU(EAkqWF&_&xtTgPO>-~9(+{rsegY)F#via5k{s*|%eUk+U)wEP2aQP5+= zj=RVYI;LpQFF8Hp`rNbhJ&y52QK-Xk#Q#70pp7aL0Ex?9%P|o{p|9236WtFifWORR zA~gr4QRJ}YK`5i(v1FDxEEz0cbY=s@^gO(0g$~4xFV3}ibt7kLXbO7Q=(OgD>VN!( z;tyEwygCLyHsj5X(Q1xvna5**3d685{)h-lzQY*$fHX?`86iFyOlKzP?f%%~g^;Ku zJHjqyYTl15PP1+5kAe2B%GJ%qX6muDFSDSSn1p!4S?P48Q9Wo&(7kOT_gF2eGYZ{7Mm^^%un@&TeRy2U zC2-~-4OljwD0l`4v|Cj#h0Ugf60B~nmfFCv%bQSS8kt#gX6m#kT#&fYlo~hB(hOUP zm#vh_)%6ZP%t0lgLR$^aNzR3{DJJLS<#zcy6Gr(^F0UB_!7Zwr`=03Gf4i$P6atW) z=>nOi@N7yUQN(XynWCtmwCku0p@oI|KLiWojKUQi?Jf!3OY6n__(LqjzWoPWtJVd9 zvM56_1@P_k+5C??Jrc+{M}d&(`uhbk;ieh7aGcMA7SXTDE8d$U# z&HAJ+s+Ic&Y+rGZT**{VG%L9FI_GHN5mE&=wsrtxb*z0a=+eb zzk6wJ9x?Q7mi!&{s5B~Q)N=BE0sn?1MW?HvuH?`maC#jM$weY4qv2Wss;tJKgRF^| zz+P~%)U+-0;K&Od&Wghp6m)erqguaulZcT7iqF*OZgDVLjjBVpCrr*dV0HBn1t(A1 zvgTys7PHw@k6M__9||=2Klb{Q#=*XB!oN_EQViL&?a~Z<{P%0sWpW#PeJxkD*S@Vm zM6C^7Ma!Ce4gc8`XGY7^4xX(XNOH}hFeVgQ+p}?bp@FGE#8m>8(qMBH{IYea(Erf! ze7U`O>T|e+qzXqp`bFbGAj6`w<4=d^>Tz9T6*F@++WY~_;#yS3No#8d>zfm9Dr%z_ zT}3FymWMwIUU5)xuo4slsZ=qv4^MOm8W?W-=vzb+8U`XH=rJ>QwavO!L}ePZ7oqv& zQ|Y$3=Y}`1@?5tV5c?xT0q>WXTUk6v8cV68!Py+<{8i9>%TvaPVl&}<2_;g-$v+~I zDbLpSD8$yjyt+J1-zTqmT6a_l%jtWiQ?0Mr7kqV5SuA$G8Tg=b8`U(VlH(BlyPhha z?FGoCo%ba_ec)e+i@k6QH|ttC;l~BUlAUi7u3{QoHc{~J=cuUj>Xy25{N}~vQ8f;E z6EITOg5t^AzW3oFVNgiTM~NPoN_r8Q+JmXxFy1iVu87EZ6YH($yb;iz<}e{-<1 zIcgn+lOO!;C@CFkj%P>GIEdG68elC73Ie5&iGPu0%40*s8btiPAG)a<1hxiARa2oE zis7|~jCkS~^yp&b&`?rLAjchNWcF|(rx3VPNDZWmE~WRRvd5^IqtHBqz7-6!S7Mt; zQueg)h176kh02≦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 N(-HnBW#udDa{=M)M_ge~C`hbK&c`jI)N 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 Icon.icns CFBundleIdentifier - com.juce.demorunner + com.rmsl.juce.demorunner CFBundleName DemoRunner CFBundleDisplayName @@ -22,11 +22,11 @@ CFBundleSignature ???? CFBundleShortVersionString - 5.4.7 + 6.0.5 CFBundleVersion - 5.4.7 + 6.0.5 NSHumanReadableCopyright - Copyright (c) 2018 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited NSHighResolutionCapable diff --git a/examples/DemoRunner/Builds/VisualStudio2015/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2015/DemoRunner_App.vcxproj index 2fd74b72..d0bb5195 100644 --- a/examples/DemoRunner/Builds/VisualStudio2015/DemoRunner_App.vcxproj +++ b/examples/DemoRunner/Builds/VisualStudio2015/DemoRunner_App.vcxproj @@ -64,10 +64,10 @@ 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.7;JUCE_APP_VERSION_HEX=0x50407;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_DISPLAY_SPLASH_SCREEN=0;JUCE_USE_DARK_SPLASH_SCREEN=1;JUCE_PROJUCER_VERSION=0x60005;JUCE_MODULE_AVAILABLE_juce_analytics=1;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_audio_formats=1;JUCE_MODULE_AVAILABLE_juce_audio_processors=1;JUCE_MODULE_AVAILABLE_juce_audio_utils=1;JUCE_MODULE_AVAILABLE_juce_blocks_basics=1;JUCE_MODULE_AVAILABLE_juce_box2d=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_dsp=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_MODULE_AVAILABLE_juce_opengl=1;JUCE_MODULE_AVAILABLE_juce_osc=1;JUCE_MODULE_AVAILABLE_juce_product_unlocking=1;JUCE_MODULE_AVAILABLE_juce_video=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_USE_MP3AUDIOFORMAT=1;JUCE_ALLOW_STATIC_NULL_VARIABLES=0;JUCE_STRICT_REFCOUNTEDPOINTER=1;JUCE_USE_CAMERA=1;JUCE_STANDALONE_APPLICATION=1;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCER_VS2015_78A5022=1;JUCE_APP_VERSION=6.0.5;JUCE_APP_VERSION_HEX=0x60005;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 - + NotUsing $(IntDir)\ $(IntDir)\ $(IntDir)\ @@ -106,10 +106,10 @@ 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.7;JUCE_APP_VERSION_HEX=0x50407;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_DISPLAY_SPLASH_SCREEN=0;JUCE_USE_DARK_SPLASH_SCREEN=1;JUCE_PROJUCER_VERSION=0x60005;JUCE_MODULE_AVAILABLE_juce_analytics=1;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_audio_formats=1;JUCE_MODULE_AVAILABLE_juce_audio_processors=1;JUCE_MODULE_AVAILABLE_juce_audio_utils=1;JUCE_MODULE_AVAILABLE_juce_blocks_basics=1;JUCE_MODULE_AVAILABLE_juce_box2d=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_dsp=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_MODULE_AVAILABLE_juce_opengl=1;JUCE_MODULE_AVAILABLE_juce_osc=1;JUCE_MODULE_AVAILABLE_juce_product_unlocking=1;JUCE_MODULE_AVAILABLE_juce_video=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_USE_MP3AUDIOFORMAT=1;JUCE_ALLOW_STATIC_NULL_VARIABLES=0;JUCE_STRICT_REFCOUNTEDPOINTER=1;JUCE_USE_CAMERA=1;JUCE_STANDALONE_APPLICATION=1;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCER_VS2015_78A5022=1;JUCE_APP_VERSION=6.0.5;JUCE_APP_VERSION_HEX=0x60005;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 - + NotUsing $(IntDir)\ $(IntDir)\ $(IntDir)\ @@ -132,6 +132,7 @@ true true true + UseLinkTimeCodeGeneration true @@ -242,10 +243,10 @@ true - + true - + true @@ -254,6 +255,9 @@ true + + true + true @@ -272,6 +276,153 @@ true + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + true @@ -371,70 +522,73 @@ true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + + true + + true @@ -629,6 +783,9 @@ true + + true + true @@ -926,6 +1083,9 @@ true + + true + true @@ -953,6 +1113,9 @@ true + + true + true @@ -1232,6 +1395,9 @@ true + + true + true @@ -1241,6 +1407,9 @@ true + + true + true @@ -1274,21 +1443,60 @@ true + + true + + + true + + + true + true true + + true + true - + true true + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + true @@ -1901,6 +2109,15 @@ true + + true + + + true + + + true + true @@ -1919,13 +2136,7 @@ true - - true - - - true - - + true @@ -2129,6 +2340,9 @@ true + + true + true @@ -2291,10 +2505,10 @@ - + - + @@ -2304,6 +2518,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2341,50 +2615,51 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2473,6 +2748,7 @@ + @@ -2499,6 +2775,7 @@ + @@ -2611,6 +2888,7 @@ + @@ -2624,6 +2902,7 @@ + @@ -2666,6 +2945,7 @@ + @@ -2741,6 +3021,7 @@ + @@ -2758,21 +3039,33 @@ - + + + - + - - + + - - + + + + + + + + + + + + @@ -2956,7 +3249,8 @@ - + + @@ -3008,6 +3302,7 @@ + @@ -3073,12 +3368,14 @@ - + + + diff --git a/examples/DemoRunner/Builds/VisualStudio2015/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2015/DemoRunner_App.vcxproj.filters index 8bdd409c..b6b19dd2 100644 --- a/examples/DemoRunner/Builds/VisualStudio2015/DemoRunner_App.vcxproj.filters +++ b/examples/DemoRunner/Builds/VisualStudio2015/DemoRunner_App.vcxproj.filters @@ -56,6 +56,36 @@ {092EFC17-7C95-7E04-0ACA-0D61A462EE81} + + {285118C6-8FDA-7DCE-BEF4-FFB2120876C5} + + + {69ED6B61-9B8D-D47E-E4A6-2E9F9A94A75A} + + + {7CDB7CD1-BB96-F593-3C78-1E06182B5839} + + + {B0A708DE-B4CF-196B-14FB-DC8221509B8E} + + + {34F46ADE-EE31-227A-A69E-7732E70145F1} + + + {BB9B3C77-17FB-E994-8B75-88F1727E4655} + + + {C0971D77-2F14-190A-E2AE-89D6285F4D5A} + + + {AABEA333-6524-8891-51C7-6DAEB5700628} + + + {F2D29337-983E-BAD7-7B5C-E0AB3D53D404} + + + {C674B0FB-1FC0-2986-94B1-083845018994} + {0AFC1CE8-F6E6-9817-8C21-8432B2A375DA} @@ -80,26 +110,26 @@ {9EB3EC7F-2AB7-DDAA-3C05-DF382B728D3F} - - {02D37B85-7DE2-C8E7-A274-A5A0FBE99D69} + + {6B9FBFDC-1D10-6246-356D-00FF4535CECB} - - {DAF3BAAF-5207-4C34-61B9-A97DDC930D50} + + {D6FCFC8E-7136-9109-78C0-91A3EB4C443F} - - {C7885588-8436-4C21-DC1E-58879BF53BDC} + + {EBF18AC1-F0ED-937A-2824-4307CE2ADAF7} - - {E4ECEA39-0EFF-2443-91B3-1E5DA7AD5AE4} + + {5A0F7922-2EFB-6465-57E4-A445B804EFB5} - - {210B8D25-68E0-32C3-1449-6A40F109C5E9} + + {4EC45416-0E7C-7567-6F75-D0C8CEE7DC4F} - - {378AD911-E8E4-D230-E76B-34542849509D} + + {C2985031-0496-55B5-41A8-BAB99E53D89D} - - {F6CED5B6-0A8C-56D2-C1AC-DED6BE774A13} + + {FB4AB426-7009-0036-BB75-E34256AA7C89} {E684D858-09E8-0251-8E86-5657129641E1} @@ -344,6 +374,9 @@ {DDF4BA73-8578-406D-21F8-06B9BC70BFEA} + + {73374573-0194-9A6E-461A-A81EEB511C26} + {5DD60D0E-B16A-0BED-EDC4-C56E6960CA9E} @@ -440,6 +473,9 @@ {FE3CB19C-EF43-5CF5-DAF0-09D4E43D0AB9} + + {FE7E6CD5-C7A0-DB20-4E7E-D6E7F08C4578} + {895C2D33-E08D-B1BA-BB36-FC4CA65090C8} @@ -643,10 +679,10 @@ JUCE Modules\juce_audio_basics\synthesisers - + JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities @@ -655,6 +691,9 @@ JUCE Modules\juce_audio_basics\utilities + + JUCE Modules\juce_audio_basics\utilities + JUCE Modules\juce_audio_basics @@ -676,6 +715,153 @@ JUCE Modules\juce_audio_devices\midi_io + + JUCE Modules\juce_audio_devices\native\oboe\src\aaudio + + + JUCE Modules\juce_audio_devices\native\oboe\src\aaudio + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\fifo + + + JUCE Modules\juce_audio_devices\native\oboe\src\fifo + + + JUCE Modules\juce_audio_devices\native\oboe\src\fifo + + + JUCE Modules\juce_audio_devices\native\oboe\src\fifo + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + JUCE Modules\juce_audio_devices\native @@ -778,71 +964,74 @@ JUCE Modules\juce_audio_formats\codecs\flac\libFLAC - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib + + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib JUCE Modules\juce_audio_formats\codecs\oggvorbis @@ -1042,6 +1231,9 @@ JUCE Modules\juce_audio_processors\utilities + + JUCE Modules\juce_audio_processors\utilities + JUCE Modules\juce_audio_processors\utilities @@ -1357,6 +1549,9 @@ JUCE Modules\juce_core\files + + JUCE Modules\juce_core\files + JUCE Modules\juce_core\files @@ -1384,6 +1579,9 @@ JUCE Modules\juce_core\maths + + JUCE Modules\juce_core\memory + JUCE Modules\juce_core\memory @@ -1687,6 +1885,9 @@ JUCE Modules\juce_dsp\containers + + JUCE Modules\juce_dsp\containers + JUCE Modules\juce_dsp\containers @@ -1696,6 +1897,9 @@ JUCE Modules\juce_dsp\frequency + + JUCE Modules\juce_dsp\frequency + JUCE Modules\juce_dsp\frequency @@ -1729,21 +1933,60 @@ JUCE Modules\juce_dsp\native + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\processors + JUCE Modules\juce_dsp\processors JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\processors + JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + JUCE Modules\juce_dsp @@ -2377,6 +2620,15 @@ JUCE Modules\juce_gui_basics\mouse + + JUCE Modules\juce_gui_basics\native\x11 + + + JUCE Modules\juce_gui_basics\native\x11 + + + JUCE Modules\juce_gui_basics\native\x11 + JUCE Modules\juce_gui_basics\native @@ -2404,13 +2656,7 @@ JUCE Modules\juce_gui_basics\native - - JUCE Modules\juce_gui_basics\native - - - JUCE Modules\juce_gui_basics\native - - + JUCE Modules\juce_gui_basics\native @@ -2644,6 +2890,9 @@ JUCE Modules\juce_gui_extra\native + + JUCE Modules\juce_gui_extra\native + JUCE Modules\juce_gui_extra\native @@ -2946,16 +3195,16 @@ JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities @@ -2985,6 +3234,186 @@ JUCE Modules\juce_audio_devices\midi_io + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\src\aaudio + + + JUCE Modules\juce_audio_devices\native\oboe\src\aaudio + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\fifo + + + JUCE Modules\juce_audio_devices\native\oboe\src\fifo + + + JUCE Modules\juce_audio_devices\native\oboe\src\fifo + + + JUCE Modules\juce_audio_devices\native\oboe\src\fifo + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + + + JUCE Modules\juce_audio_devices\native + JUCE Modules\juce_audio_devices\native @@ -3096,131 +3525,131 @@ JUCE Modules\juce_audio_formats\codecs\flac - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\floor + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\floor - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\uncoupled + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\uncoupled - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib JUCE Modules\juce_audio_formats\codecs\oggvorbis @@ -3228,6 +3657,9 @@ JUCE Modules\juce_audio_formats\codecs\oggvorbis + + JUCE Modules\juce_audio_formats\codecs\oggvorbis + JUCE Modules\juce_audio_formats\codecs\oggvorbis @@ -3492,6 +3924,9 @@ JUCE Modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst + + JUCE Modules\juce_audio_processors\format_types + JUCE Modules\juce_audio_processors\format_types @@ -3570,6 +4005,9 @@ JUCE Modules\juce_audio_processors\utilities + + JUCE Modules\juce_audio_processors\utilities + JUCE Modules\juce_audio_processors\utilities @@ -3906,6 +4344,9 @@ JUCE Modules\juce_core\files + + JUCE Modules\juce_core\files + JUCE Modules\juce_core\files @@ -3945,6 +4386,9 @@ JUCE Modules\juce_core\maths + + JUCE Modules\juce_core\memory + JUCE Modules\juce_core\memory @@ -4071,6 +4515,9 @@ JUCE Modules\juce_core\system + + JUCE Modules\juce_core\system + JUCE Modules\juce_core\system @@ -4296,6 +4743,9 @@ JUCE Modules\juce_dsp\containers + + JUCE Modules\juce_dsp\containers + JUCE Modules\juce_dsp\containers @@ -4347,13 +4797,19 @@ JUCE Modules\juce_dsp\native - + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\processors JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors @@ -4362,13 +4818,13 @@ JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors @@ -4383,15 +4839,45 @@ JUCE Modules\juce_dsp\processors - - JUCE Modules\juce_dsp\processors - JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + JUCE Modules\juce_dsp @@ -4941,8 +5427,11 @@ JUCE Modules\juce_gui_basics\mouse - - JUCE Modules\juce_gui_basics\native + + JUCE Modules\juce_gui_basics\native\x11 + + + JUCE Modules\juce_gui_basics\native\x11 JUCE Modules\juce_gui_basics\native @@ -5097,6 +5586,9 @@ JUCE Modules\juce_gui_extra\embedding + + JUCE Modules\juce_gui_extra\embedding + JUCE Modules\juce_gui_extra\embedding @@ -5292,9 +5784,6 @@ JUCE Modules\juce_video - - JUCE Library Code - JUCE Library Code @@ -5303,9 +5792,18 @@ DemoRunner\Source + + JUCE Modules\juce_audio_devices\native\oboe + + + JUCE Modules\juce_audio_devices\native\oboe + JUCE Modules\juce_audio_formats\codecs\flac + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7 + JUCE Modules\juce_audio_formats\codecs\oggvorbis diff --git a/examples/DemoRunner/Builds/VisualStudio2015/icon.ico b/examples/DemoRunner/Builds/VisualStudio2015/icon.ico index 09d32ad703e414097a17e969e7d765325e912c77..27c4228e128bfab98bccc5e39de61de6a8faa39a 100644 GIT binary patch literal 36638 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

7jRK$!qvEJzocG(cKfP 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 literal 33530 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

(u1;L6(cQ?)GnM#vbq;}_8j8w4Fi2^0KYHDQh@ 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 VS_VERSION_INFO VERSIONINFO -FILEVERSION 5,4,7,0 +FILEVERSION 6,0,5,0 BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904E4" BEGIN - VALUE "CompanyName", "ROLI Ltd.\0" - VALUE "LegalCopyright", "Copyright (c) 2018 - ROLI Ltd.\0" + VALUE "CompanyName", "Raw Material Software Limited\0" + VALUE "LegalCopyright", "Copyright (c) 2020 - Raw Material Software Limited\0" VALUE "FileDescription", "DemoRunner\0" - VALUE "FileVersion", "5.4.7\0" + VALUE "FileVersion", "6.0.5\0" VALUE "ProductName", "DemoRunner\0" - VALUE "ProductVersion", "5.4.7\0" + VALUE "ProductVersion", "6.0.5\0" END END diff --git a/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj index 952d10f7..847d9cc2 100644 --- a/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj +++ b/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj @@ -64,10 +64,10 @@ 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.7;JUCE_APP_VERSION_HEX=0x50407;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_DISPLAY_SPLASH_SCREEN=0;JUCE_USE_DARK_SPLASH_SCREEN=1;JUCE_PROJUCER_VERSION=0x60005;JUCE_MODULE_AVAILABLE_juce_analytics=1;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_audio_formats=1;JUCE_MODULE_AVAILABLE_juce_audio_processors=1;JUCE_MODULE_AVAILABLE_juce_audio_utils=1;JUCE_MODULE_AVAILABLE_juce_blocks_basics=1;JUCE_MODULE_AVAILABLE_juce_box2d=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_dsp=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_MODULE_AVAILABLE_juce_opengl=1;JUCE_MODULE_AVAILABLE_juce_osc=1;JUCE_MODULE_AVAILABLE_juce_product_unlocking=1;JUCE_MODULE_AVAILABLE_juce_video=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_USE_MP3AUDIOFORMAT=1;JUCE_ALLOW_STATIC_NULL_VARIABLES=0;JUCE_STRICT_REFCOUNTEDPOINTER=1;JUCE_USE_CAMERA=1;JUCE_STANDALONE_APPLICATION=1;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCER_VS2017_78A5024=1;JUCE_APP_VERSION=6.0.5;JUCE_APP_VERSION_HEX=0x60005;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 - + NotUsing $(IntDir)\ $(IntDir)\ $(IntDir)\ @@ -106,10 +106,10 @@ 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.7;JUCE_APP_VERSION_HEX=0x50407;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_DISPLAY_SPLASH_SCREEN=0;JUCE_USE_DARK_SPLASH_SCREEN=1;JUCE_PROJUCER_VERSION=0x60005;JUCE_MODULE_AVAILABLE_juce_analytics=1;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_audio_formats=1;JUCE_MODULE_AVAILABLE_juce_audio_processors=1;JUCE_MODULE_AVAILABLE_juce_audio_utils=1;JUCE_MODULE_AVAILABLE_juce_blocks_basics=1;JUCE_MODULE_AVAILABLE_juce_box2d=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_dsp=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_MODULE_AVAILABLE_juce_opengl=1;JUCE_MODULE_AVAILABLE_juce_osc=1;JUCE_MODULE_AVAILABLE_juce_product_unlocking=1;JUCE_MODULE_AVAILABLE_juce_video=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_USE_MP3AUDIOFORMAT=1;JUCE_ALLOW_STATIC_NULL_VARIABLES=0;JUCE_STRICT_REFCOUNTEDPOINTER=1;JUCE_USE_CAMERA=1;JUCE_STANDALONE_APPLICATION=1;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCER_VS2017_78A5024=1;JUCE_APP_VERSION=6.0.5;JUCE_APP_VERSION_HEX=0x60005;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 - + NotUsing $(IntDir)\ $(IntDir)\ $(IntDir)\ @@ -132,6 +132,7 @@ true true true + UseLinkTimeCodeGeneration true @@ -242,10 +243,10 @@ true - + true - + true @@ -254,6 +255,9 @@ true + + true + true @@ -272,6 +276,153 @@ true + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + true @@ -371,70 +522,73 @@ true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + + true + + true @@ -629,6 +783,9 @@ true + + true + true @@ -926,6 +1083,9 @@ true + + true + true @@ -953,6 +1113,9 @@ true + + true + true @@ -1232,6 +1395,9 @@ true + + true + true @@ -1241,6 +1407,9 @@ true + + true + true @@ -1274,21 +1443,60 @@ true + + true + + + true + + + true + true true + + true + true - + true true + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + true @@ -1901,6 +2109,15 @@ true + + true + + + true + + + true + true @@ -1919,13 +2136,7 @@ true - - true - - - true - - + true @@ -2129,6 +2340,9 @@ true + + true + true @@ -2291,10 +2505,10 @@ - + - + @@ -2304,6 +2518,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2341,50 +2615,51 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2473,6 +2748,7 @@ + @@ -2499,6 +2775,7 @@ + @@ -2611,6 +2888,7 @@ + @@ -2624,6 +2902,7 @@ + @@ -2666,6 +2945,7 @@ + @@ -2741,6 +3021,7 @@ + @@ -2758,21 +3039,33 @@ - + + + - + - - + + - - + + + + + + + + + + + + @@ -2956,7 +3249,8 @@ - + + @@ -3008,6 +3302,7 @@ + @@ -3073,12 +3368,14 @@ - + + + diff --git a/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj.filters index 4b163b6d..defaafed 100644 --- a/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj.filters +++ b/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj.filters @@ -56,6 +56,36 @@ {092EFC17-7C95-7E04-0ACA-0D61A462EE81} + + {285118C6-8FDA-7DCE-BEF4-FFB2120876C5} + + + {69ED6B61-9B8D-D47E-E4A6-2E9F9A94A75A} + + + {7CDB7CD1-BB96-F593-3C78-1E06182B5839} + + + {B0A708DE-B4CF-196B-14FB-DC8221509B8E} + + + {34F46ADE-EE31-227A-A69E-7732E70145F1} + + + {BB9B3C77-17FB-E994-8B75-88F1727E4655} + + + {C0971D77-2F14-190A-E2AE-89D6285F4D5A} + + + {AABEA333-6524-8891-51C7-6DAEB5700628} + + + {F2D29337-983E-BAD7-7B5C-E0AB3D53D404} + + + {C674B0FB-1FC0-2986-94B1-083845018994} + {0AFC1CE8-F6E6-9817-8C21-8432B2A375DA} @@ -80,26 +110,26 @@ {9EB3EC7F-2AB7-DDAA-3C05-DF382B728D3F} - - {02D37B85-7DE2-C8E7-A274-A5A0FBE99D69} + + {6B9FBFDC-1D10-6246-356D-00FF4535CECB} - - {DAF3BAAF-5207-4C34-61B9-A97DDC930D50} + + {D6FCFC8E-7136-9109-78C0-91A3EB4C443F} - - {C7885588-8436-4C21-DC1E-58879BF53BDC} + + {EBF18AC1-F0ED-937A-2824-4307CE2ADAF7} - - {E4ECEA39-0EFF-2443-91B3-1E5DA7AD5AE4} + + {5A0F7922-2EFB-6465-57E4-A445B804EFB5} - - {210B8D25-68E0-32C3-1449-6A40F109C5E9} + + {4EC45416-0E7C-7567-6F75-D0C8CEE7DC4F} - - {378AD911-E8E4-D230-E76B-34542849509D} + + {C2985031-0496-55B5-41A8-BAB99E53D89D} - - {F6CED5B6-0A8C-56D2-C1AC-DED6BE774A13} + + {FB4AB426-7009-0036-BB75-E34256AA7C89} {E684D858-09E8-0251-8E86-5657129641E1} @@ -344,6 +374,9 @@ {DDF4BA73-8578-406D-21F8-06B9BC70BFEA} + + {73374573-0194-9A6E-461A-A81EEB511C26} + {5DD60D0E-B16A-0BED-EDC4-C56E6960CA9E} @@ -440,6 +473,9 @@ {FE3CB19C-EF43-5CF5-DAF0-09D4E43D0AB9} + + {FE7E6CD5-C7A0-DB20-4E7E-D6E7F08C4578} + {895C2D33-E08D-B1BA-BB36-FC4CA65090C8} @@ -643,10 +679,10 @@ JUCE Modules\juce_audio_basics\synthesisers - + JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities @@ -655,6 +691,9 @@ JUCE Modules\juce_audio_basics\utilities + + JUCE Modules\juce_audio_basics\utilities + JUCE Modules\juce_audio_basics @@ -676,6 +715,153 @@ JUCE Modules\juce_audio_devices\midi_io + + JUCE Modules\juce_audio_devices\native\oboe\src\aaudio + + + JUCE Modules\juce_audio_devices\native\oboe\src\aaudio + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\fifo + + + JUCE Modules\juce_audio_devices\native\oboe\src\fifo + + + JUCE Modules\juce_audio_devices\native\oboe\src\fifo + + + JUCE Modules\juce_audio_devices\native\oboe\src\fifo + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + JUCE Modules\juce_audio_devices\native @@ -778,71 +964,74 @@ JUCE Modules\juce_audio_formats\codecs\flac\libFLAC - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib + + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib JUCE Modules\juce_audio_formats\codecs\oggvorbis @@ -1042,6 +1231,9 @@ JUCE Modules\juce_audio_processors\utilities + + JUCE Modules\juce_audio_processors\utilities + JUCE Modules\juce_audio_processors\utilities @@ -1357,6 +1549,9 @@ JUCE Modules\juce_core\files + + JUCE Modules\juce_core\files + JUCE Modules\juce_core\files @@ -1384,6 +1579,9 @@ JUCE Modules\juce_core\maths + + JUCE Modules\juce_core\memory + JUCE Modules\juce_core\memory @@ -1687,6 +1885,9 @@ JUCE Modules\juce_dsp\containers + + JUCE Modules\juce_dsp\containers + JUCE Modules\juce_dsp\containers @@ -1696,6 +1897,9 @@ JUCE Modules\juce_dsp\frequency + + JUCE Modules\juce_dsp\frequency + JUCE Modules\juce_dsp\frequency @@ -1729,21 +1933,60 @@ JUCE Modules\juce_dsp\native + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\processors + JUCE Modules\juce_dsp\processors JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\processors + JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + JUCE Modules\juce_dsp @@ -2377,6 +2620,15 @@ JUCE Modules\juce_gui_basics\mouse + + JUCE Modules\juce_gui_basics\native\x11 + + + JUCE Modules\juce_gui_basics\native\x11 + + + JUCE Modules\juce_gui_basics\native\x11 + JUCE Modules\juce_gui_basics\native @@ -2404,13 +2656,7 @@ JUCE Modules\juce_gui_basics\native - - JUCE Modules\juce_gui_basics\native - - - JUCE Modules\juce_gui_basics\native - - + JUCE Modules\juce_gui_basics\native @@ -2644,6 +2890,9 @@ JUCE Modules\juce_gui_extra\native + + JUCE Modules\juce_gui_extra\native + JUCE Modules\juce_gui_extra\native @@ -2946,16 +3195,16 @@ JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities @@ -2985,6 +3234,186 @@ JUCE Modules\juce_audio_devices\midi_io + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\src\aaudio + + + JUCE Modules\juce_audio_devices\native\oboe\src\aaudio + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\fifo + + + JUCE Modules\juce_audio_devices\native\oboe\src\fifo + + + JUCE Modules\juce_audio_devices\native\oboe\src\fifo + + + JUCE Modules\juce_audio_devices\native\oboe\src\fifo + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + + + JUCE Modules\juce_audio_devices\native + JUCE Modules\juce_audio_devices\native @@ -3096,131 +3525,131 @@ JUCE Modules\juce_audio_formats\codecs\flac - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\floor + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\floor - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\uncoupled + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\uncoupled - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib JUCE Modules\juce_audio_formats\codecs\oggvorbis @@ -3228,6 +3657,9 @@ JUCE Modules\juce_audio_formats\codecs\oggvorbis + + JUCE Modules\juce_audio_formats\codecs\oggvorbis + JUCE Modules\juce_audio_formats\codecs\oggvorbis @@ -3492,6 +3924,9 @@ JUCE Modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst + + JUCE Modules\juce_audio_processors\format_types + JUCE Modules\juce_audio_processors\format_types @@ -3570,6 +4005,9 @@ JUCE Modules\juce_audio_processors\utilities + + JUCE Modules\juce_audio_processors\utilities + JUCE Modules\juce_audio_processors\utilities @@ -3906,6 +4344,9 @@ JUCE Modules\juce_core\files + + JUCE Modules\juce_core\files + JUCE Modules\juce_core\files @@ -3945,6 +4386,9 @@ JUCE Modules\juce_core\maths + + JUCE Modules\juce_core\memory + JUCE Modules\juce_core\memory @@ -4071,6 +4515,9 @@ JUCE Modules\juce_core\system + + JUCE Modules\juce_core\system + JUCE Modules\juce_core\system @@ -4296,6 +4743,9 @@ JUCE Modules\juce_dsp\containers + + JUCE Modules\juce_dsp\containers + JUCE Modules\juce_dsp\containers @@ -4347,13 +4797,19 @@ JUCE Modules\juce_dsp\native - + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\processors JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors @@ -4362,13 +4818,13 @@ JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors @@ -4383,15 +4839,45 @@ JUCE Modules\juce_dsp\processors - - JUCE Modules\juce_dsp\processors - JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + JUCE Modules\juce_dsp @@ -4941,8 +5427,11 @@ JUCE Modules\juce_gui_basics\mouse - - JUCE Modules\juce_gui_basics\native + + JUCE Modules\juce_gui_basics\native\x11 + + + JUCE Modules\juce_gui_basics\native\x11 JUCE Modules\juce_gui_basics\native @@ -5097,6 +5586,9 @@ JUCE Modules\juce_gui_extra\embedding + + JUCE Modules\juce_gui_extra\embedding + JUCE Modules\juce_gui_extra\embedding @@ -5292,9 +5784,6 @@ JUCE Modules\juce_video - - JUCE Library Code - JUCE Library Code @@ -5303,9 +5792,18 @@ DemoRunner\Source + + JUCE Modules\juce_audio_devices\native\oboe + + + JUCE Modules\juce_audio_devices\native\oboe + JUCE Modules\juce_audio_formats\codecs\flac + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7 + JUCE Modules\juce_audio_formats\codecs\oggvorbis diff --git a/examples/DemoRunner/Builds/VisualStudio2017/icon.ico b/examples/DemoRunner/Builds/VisualStudio2017/icon.ico index 09d32ad703e414097a17e969e7d765325e912c77..27c4228e128bfab98bccc5e39de61de6a8faa39a 100644 GIT binary patch literal 36638 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

7jRK$!qvEJzocG(cKfP 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 literal 33530 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

(u1;L6(cQ?)GnM#vbq;}_8j8w4Fi2^0KYHDQh@ z%Z**7)Vu}~8yK6?QzTnHSdIk!d@9{Rn67f>2^LE{LmU}37%onKZL7TQrDrlMy7@Vb zJZA^K_|#=!w9IE!nWYmQ>M{9W%r@WPsDJ-8=w2l`Uit}zhcL&yyDRsD)hp7I`nqB= z@tA_uGBAqnJjUWfyUFF*`oi6q*oOOA77WxlKXjIoM3yG38Pfh-5%7q>S<046MJMp$ zD%IaB~4Co(N)hiAH{=4jse0HY#VpFW-b89&sggu8FMGR)pQQ zSo4hIBwyz3ad7XqUmabS04t@Sr{}(>4<_8;+Ef$mxIVZMp`PukW*94!9D-&l3aX8N zavADAV~v^cox+#xTCdtk+t|EQYA)F5uUwmyrwX_bBPqSx*G$fwmDe5CozjA&YN+E`)4QNE(Gm~I#cHSAh~ zD{VoUIDD~O5}!AhE`kec<}La0`Q4X?GYV8B*qc|?HZ6j)3twDmHt5nJx11W(KkJ*! zl%(M?q-6g(aKHNGt~nCRH= z-W`_JozR8h@+DCjG?sAncfg1>)?SZi!W1b^Zz2fKi}lTT~@KQ`7MY5yh$$ z1aqwh~-;cpi0`W{frsQD*#1w6wJ5QnunO)jY813cQ}+k5CBvLvkfQJIqrcbXI!!u&6?zl=HH@4fx!gMu7vER(MkyTmB>P>T)|hOd zs2O-lq(0y#^^*f{>G>Ps<4)+W`(YUL2M3Yd*<;dVQejA{pr>_3Xy>OS*>rKc`sgUE zMn$)T_s)7P7JE3AOJcCuCi{7^w@FsxyW`~Fzq*Qg&V%#0cd{!5HUVc?V{6OT8HhrU zn7&nI$LT4i%*Mn*^7+*>4N#@OiWVolJ?kBLBO?)4`g2uvMMnjChqwaT(C0?kP6y%% zPx~E@?Sre7uokL)7sj<%A>^cJGI{PW%4lUnYa&yiErF6h#5a9yE_*6+CG{=U zeM0vLSGWnMLRYq(m~uyHIMO*zv{t_*qmQU@+TOH$WV3wvBbALv|A-U&UZ4UoUKU*^4VAz4J{4$Qgf;?udr zQ7>Yz_{1m8oCD#ZI9J~LYp-2tVNk7}UzAe%&~=N!O6;r(su_50H#0MvzFKJ9Yq1s_W2MlcL9PxL5iqWbh)^iCO_MY~ATt)B4!n=q z0ut4iXehQ*kQ!)vHP^N2&Fd4D_&$ffgIQvKVc1c0s(sv(E24dunql7WY4X`#UckJS zcqv3UmY;&8GXo>P8m4EMrQoh{;?W0Y>4kbM6)82C7o8P7D;bY^b5?V&+^$L6Ut59!LQVT7c%2Rt7uglIcy8a$Rbrq6q@cLpcQ@d-APJaaQvO}1y| zfVH3D-?_rS%N)-taKEC3r?bQiXIEhRgcwsKqy2$?I|w=E>>AB`^Oidv*G5V97#QLc zZQeR-9+kbJ`k~0jbs|v#i;*UHYgKhwoJs?X8ls!IN>J}-=FTQkUn@Xk@!s$(zGva> zA|%q%SJ^SR!(!q`!RV;d$-45QtZzavb-**fk|OcRMkt^YHSDHdU`x{J<*l3zB>#yI{?%!Hj1JAG<`f0V800cPJD^v}1bjqU&z%jW3gRZ8&7Q?H zTBnPwpxF963?rqx8iVUWuCq8zfiAABxE=`e&~`bg)k%qtRtI{A_k)~%m(bV6sTHGg zW8WrmPKmu$juK9J@ZsGpGBmy|^+pzX2^e2ZN;T6B@n;{Jt;E3*D;u&2F*{%Y%tOHVhpax?59s| znifW7L)+LLk2~Y+Ct-hE$*kvjhUO{&jV3W8Hah}yK(+Bh%s(rr2z|W@3rXqdf zbQrqPf-sx2U?1h9kdss{Zp2J6cp^KZ9jxVE4+=&rZuf@{nNej+8tcnH2~B@oMN^8K zsmp`MW_y7Xc5Q3bSMxNI;3OmFSX0LR{*-9g(j$9Eo|jqVb!2omO21|yv}1%#r|K~3 z@_Sy%92I7}6K3i?)E|vzzhf455;lS9#iVJQ+ucI9j5*eo*DGS7c8yM}%DGI(%?8HR zeuFSn!UI+}i6E-Ir&&ICmWwZfJLr;qX3^kCh5R)f52~=nv~?aqIsYipzAvufJ+{DIM)0us_Q zF0LV#m^z`AIcc|JPQdqPV}!}Xza+kt!No1Icg-8{bNYIdoWYq;XT=f6Cww__7-s3NR33JO`fEljM%z5MP5P|r~F8Rlfq1O zM>^NEKAL@Yde2>PL)Rk2#m53pHc&P{@7l6CNA+2N(LIq9nf*|WixKnn4dFZa&%E{5 zi!U4UGUVNHod;$BekKjf3n!Mc8{HjBds|<1F^TYrjQTXJzmLI(&rqHoML#1T<%!|P zIUuaOTx&fbeg8F&Kpoj&fAAqE(EzIYL#8_KQaax2dSEwnu@ zfsr{JAi~7ON_~}28bkCf6&Id9dqy*fz`ODjE-rY;P7#qg2}|EAfT!u^i3~4?1iZLR z%Rs}$cwz@A=$+nJse&hIyEfwAAH-&sh80y=WeRqZJ!EtkrnT1glilOH!hKpx(A4V5 zMeK#g?s9efv{I5JnHOx~2KR)fdKb(U3Bopae0N+e8|_~*#OzAlS0AaQ0EC^i*XU&# z(C=NV0tbBCc@&!jTeUudNnH0J{5H!fp<)A93BP9Huwibiz70SUEVAXVz*K!g#G3gw z?4GdQRIa6BST12{hC{&uiS{KCFNT-YKO?9}niBKy(W z3(_aPMVQL4+{W2hqPR+?dV{fvgpM9Oe3jfbpMmDHAfrYRAIg6=u?!`BZa4#Dj}SjQnQsSpJh@4%H*)C1 zguCTSS1s@Jp=dRSSp)XyiGBMSM$KK1Av^GR>tYHn(WlZ0F@{raQ&Fl1S0?X{Du(BE zp|wyM^is5@)$=ugM_>8|+1=OtxE*~77*zRuSkXrwI}(!K z5khZMji`AtlU4gbMj)@p4b@K1InRck=A@pfh~ci-G?f9*!t@YWV_lZi7(|^3cZI~1ba5i$>C*siZ9ZbR2VaIiky~RWBn;q zxRQ?YL&eG4bQjITb)_)1IpF}P-`oC%Aq}u2AV!9eF znH@@a77hzy@9@u_n>EErz+?^IB7>F3dFm$!es~aG4ww-5gMZeL?Y`_5sx%W>HZpDT z+(Z&yv_*h>N;7v^XJrjc0s%ku!duzP;L%zYf$c_WT*3Dx2bV6I-_dEp z)Y{3pI9wSYnoPOYJMPZNkTrGVDz4>_%XVk#$-vg-ucOH3v-e1-vQz3J(5^I6*6Q3P zd|;^MxCa;3n>~aP&z-D79Ih6d^$ti}e<}z5``Be0=T+^X?G}w4pC{{XlY!YNDnq%a z=lU6IN(U3b6F^E6Vi{O=FBe!5jE^uKM z%hIRuK=P3nduP(XE7U$aTtDlpT1enWFBjWl_e`n6dAL`ze)f%S#`7NfICL-F56Iwy zw8$Ml2Xoc8sX2^bU9fj6p36Hj+5;>O8aihWZN{{F+&-G&(C}*Hx_${&!>Otq5avj& zvGw5AdUBi5T1Cbc177wVkg#|si{NKub{v~58vO8q^Yqh)FvOb$#K+ezRkM1*C&-A+ z7LWvG&eyUL`i~sZ+eTwDhVL@O^H!}Oh|bgs(l*&dabFC;5RN;fD0i5;)&J7HhQ#p( z2GQGc!wl=Za%Qe6bQr8-7?__-a#Je0&!*rgP`o4Lll6o=bu!Wve!ZvmlFH}d!w-5N z(=mLAV+9Ju3O~`q1gciuxO_!;FK~ZFWb6#Rc&B8=#ewc|64zmAvFt_obtV{09)p(e;I zH7NSSFcej$;HgSZ+2(@dkIFv+jP>SK;33!jtzq^a%8IbMcaZ&Y%$UYT-(oM^n_Usk zxpxX1b`ZkpmE?9~#1>>|!3SD4#pcIP-UT+_kHN{TbsZ&SF* z336a>4hQp|ju?#6TA!~&ODq8xB6$UJMxx*U%4`XFQ>cfMam^kZ*c(vz>Uz4TJ-qH6Xp;nNc35|O%C-BOScBIbGsc~05Sg!T zPHxz|*!(&uA}2BZ6kPJPDs1%}5}Y$2;j6rmU0)uaahG9KTgm+EnWY*~$yIGpSvPMK z2^Jo(^n40ydxsCZ#xPVlyeUkhpf}8b?$u~NlocaH03#r4I141~)TjwFl3wDFexY_- z8olPMPxgr^L8PQwWNh}ps})2BC%3;y{K?sPE{gh+Yl;mb)EF3WD({=r?+e=0E@zzX zIk!-DJ3>hye=!92g3pIdbiX`rSK%{xzEy88BdN)Qt(yb!569SwMq2bf9bA#%PBB8e zl(4p#c|g8HFJZKJsq+yppECu4-K19LnKLRnFLWQfV^{2DNm)&t%t*5CjS_vky0A5| z<(}s!sx1@w*wSb0a{;UN$p6#HS-&;)hkblBNDM?^N=Yb4NPPvQbAYrU22z5AFh&Rr zkQ^|OmQZR)DBTFs9fG9NF-kf%a^#-Fb3K2-vmefnJLg>2UFZJ1UvK`SB{tCTA5OKj ze(C^&kdfA$RtIIPm`9sIl^0kE#4@&}wLjySN2y$-al1l7K{LXs_Cdn?fU&Z)y%&ck zn-T~TDev;F5Ep#*rFE2tUiZc5pPWsj{DNQuBc>|h9=)Tt!wZ}RGzj96k4k#U4+?jh z+9qcj$l#CUgcb2bfmzlwMHFQbTjW}ncwh>jY6%FyV(SMZsq}3$*!2-Wz`+Z<)ETYr zMt}A%6mbuKD?=}`Yaqojhohhm&dJ0!BEKb%p7rNSs^H-GT=Y`k-ggl_ekP4v2e_}Y8c~)MsDttS1iRm_o!7wW<@RbJ+E0d zhl5vFZ#1Wmj$yL!;lu7bac;z*Kv=+W>sy^Sl^z|Glt78@YB`b5 zozkss{>iNH`NMFSo-KVczyEo&=Twb?z0d8;+Gbk4?=_qt`WVEFRNbH>W*Y4Vej#uJ zm^IwXbKW}ck+Jc$JObKnW=&%Rlg3p7_Oktop00S7q)v`ZCZ#L2+kAV=1oPCy8bBe0 zWU=5bbw#~};ie(?IYFrs3>r(Dp!5XDkw%}(>7jbCue0GR@InMoWI4OK2la2(f8H|S zYgh1_SN!w>lQ?cY?21)fa3^ zdF+C4o8YX#2>aH*ND7?EyrZu1K8!Sm{{8uq$j?7a_FW{V{@?1!nU1v`6`D?ahnB7t zQKLY$?1y8#lWrxh{K@C8l)w&;W4=xm`MbG@(wJCpCbIw0l8F+V)WwCi{#2d&X?LLe z5%mESXgFTIa}?%&yobpgEq&WZt+W+pfmGY@;4iBoyLmW*NDyb8}T}miIsDpQB+^A(P z1}gb3K!J>uu(>I(UxE`QhC>dYiE~4NPOd%SUs307fgyW>3InyW9(Ud&mUxJ!Xmir+ zg=YLki7gBo^>8KAa+a;P`K7_3ktgNT3#ct6LbQm*(WyAC4*Si~>j>`>G!celcABB3 z!|Nclfyh-Q&Q461qS*W83&hq<$a{v~7t$&&dmD_RkHTsLI(J&A2If`!kePhzu*1uZ zDNcW%GUggOCO|p}!Y(ltacsd3ubw*i(u2-A{O|#+0b$I0S^4LKtVZE`7aJc|j8|26 zjkER6+8_q@5=-AWbvkN$itKRgt?ZlKb7{^70S5=9ml;7l=&QCq3kRz`gKYFPFWFRm z@#29iUlOFG?)&MJ$P;c_YuL<eiPh;$A1Eg zP{b+OPA_up$ORIi>sJ1l`jswNB#lN8DTR}}4y~qD)NLK)pRdx&#k4pn=r!VIM88Cz zEm@|vGX!JMuaO#qsUc48hYfPkm*?0#+KD#y?XagG6c;H~6mUPl0n;v2plHFrG_(#I zL^S0ap{jejGDV{fl~nGDwYb}o@BL|tEPL!VV1F-V``rxumJo*=8&C^J__QwxPZvoX ze+NET=)!%&CS49H4>Xmj@g{OGtci)Mu+dLnIyg@1;&>mkr?7_|?{M%97AgT^PqN8n zea>DjFwhd^$ljPu!RYoK$A7a)&h$XSa;-J1zJW*@M;shcJDq(bZ|=>lJs#-a!& zC6GAniF0omPWewi!e?l%kPg$D7I3=fl{r!UU27&MR8?o18br?!RKdrTR($&XRL6=L zN{LeSYj7!tvj8+zNPMiqfws8^SK(T$hJ~ZZtgyVp2CYpcC_K^XO+0&ShFR<%M{4Uc zI&RwKx~7xmxo#GlelOZq9BJFta3rUh7rybJ)e#$kq--_(z{s)iLht1`qm%F!a@K(j0D zA#}s~!xpgnz%A5R0LARpKVx&e+YbWn9;f-PTV0s&=ayufC?KQMDd84j~G;cT&pqe|HtyTO)AKs8`~7og~0nJ zh~|m2zK(j+SnDORJLe`*Ph9eG?KDU;F1BInyeBWYw2{N%=d_3h^nd4_<=(K58;?zQ zx|092eZ|XIS^|LBZJ*!_NTviWG0Wu>F%c|3+Bjx}FA6#IFSOxT(*C^CcS@x%;=hH4 zx{=!Vm)Z-yl|v2lmx~Ob6^)Cx<*L>=!v8D&IY0qQSIXVJL|e$YkK_etcJ3PUE|Y>l zp2F~XBQg0kKhvNi8kMhzO(Z>CH2U)TuJ0rRyOFe=dGMx`=rGo6_N1no*2YzIob-uc# zFNDf#0$;NGJ>VnV5CB>Ai9W=H&FJ4onYKJb7P1{}${}&;Jt&0z418n*9`O#?Ij2s0 z*6aIiY(C=b^62>Qt~C(#bfr!nzI2BQrV3R6s(D|>c$y1h`Fx0cdv`88b=zl>rXmAE z0x}I^w`TsEo!d-&#UUbBvKtP_}bf4ZqZ!s z$N3PVVezpj^qHA|JA+9!@&8{Ir)Y%lo|wj&xu1xDg>^Mz2Y2S(=?w;Ad(u*#!hk;}#x17px~4hd+U^LufnxOvhUmr}RMEdX-$F^w&$?hru7fG!U z&WsaXMs+dKD+-VhKQo2&;}w>Ur+0*e#1bcUrE8lZYh$0k{$;T6KobES31PK&IXPCP z<>9*r2|+Y~4=)cx`xOJYv(oYyc%A^?bjL$I$-3sRkD`9vPgnc49(?hDf0bFJ8<6UE zIEO1ZTN*%A*U*yN1be=iV#N@H0Qz*%|1`w&HC@jvnqvVxNItOnYxv^;3tES8J(aKr z$gWl^|7Q;e%S7554IfiQ>Kp7YH+2UrU-F0qiBpZpErsyVtB#iPq`h8iO3I${P3Q_| z49uZqk*{6&{P^EE;aj455-2dJt#&2*`!{92D zEKdp{FWjA^53VAa^0+VoRuYmw4(|`d_pePNt{a-ww;6%_@l4`mq} zf~KkM;aGSxk#vx10E!U*;{*ms36e4{saQYRMi~RFeY(dL)okufXs;@ex@N&xIJ$UbDa~F|o7m9QMbZzQ%C%-D( zT57sRD(kH_&uf$n!y%~>r4s%xsVpyGKah6q3ouEBG7MYN`X_z*JP+xznMuGfonwIx zOX(UOsCGLy=cSh;b){&F0EN4NyMaYInKfIDpzBY#l)3C7FRw8>uWfGOD|hM- znD*cAGLp6KXa8&!g#eJKZQmHhigJZDLoRYSD4bIHn;+X?emyDUfo-9)SQiP?y+aPy ztaBv_nUm`5b4$KPGe3Hgc%JnTzDieW@X>s^@3H5 zTr(<2oV=}>G-_I z*S#|qg543dme|9AVX_6m#NYfCXt(~K7P8vKQcok)GZn}gxcK|;M0YW@~;qat^$Mc4I80y36U*PNA1j_I@MOb+^G2KM75ff9wvm8 z&@!Q;v!*f5T_Dw~s-mJ%(#)opCiV{>k|n*Tcuk&yQQ^dY8O9R#UYmw###1m@i1Hoqra_)Bt}iC z^5yS)oeeI>Z`?s9)%im!Z^#nToQw*6jcI z?w(fk|KM<(HnH^DgNEcP{f3_tNuxE*pJOo;Cbe@l`?0boj!y5O+0;r=zv~*`8SiZ5 z1iTd#CD13PESEeG5Tha=3;7=f>(g|MzKTVwACv(2GaO8*cCO~O^AKJNDS z9|wx6PQqX(ANj0zv~Skx9xoY?)sb`ZtQAeZ?5RztyJBKj%3!wWh`UzsJVH{K{ldoPOvD)TXHBAIpq6?{IF=mGSgXd6RvaiWptz9hC zHdgaJ(Qr7<{b0L?VAHNX{bMxgC=yKM}EOTIZ8DX+lt!<$# zwWN^CG7qr_T^le=%*t}H5m7Q+mbRkgb+3SBn*EWRpRE41EeLl)%X2enZ--MdTh!uB z?HC6c#@i8otYVT72qfq0S5RcG>@p=7O}Rh?Ml;4-o)#J0XJ^0Q<`qzRvm_Qz#2xWe zTIE043tnm>M3CxNkw&R)TEzy~%L9q6%o#7yIw|(Lbz)Jq-&Z*NSv~wSTI5AY)qrOQ zseo7$F%G0b;a9FWduw02tlDYa`)W>BvP7Ny8%FOLVBO)TebE=8Dgw4>FC|JMKKgLw0+C@Bb78VvubSqu{oU_*Cp%&00p629w1wsuA;r!^ za0!mg%tLF@v&1>-((^V_iQ>#!>+zBuyf@R`tAk4?nYO`Yd~B!Hu4WT_4T>%>&6D8N zl#qv@0$PjO>JRVdY6ZSO))tm{U~QyhlBHLEw(|yryC?lHnZ8`Q^ z@XOwRWN(OxTDg0WZGnW+h*oU$0A+C5_EeR1K`*zdYkbQ$t2=Zk``C3xQ}uYsn<{h> z{`C#l2iwbhuyaqpzvDDYI-9i VS_VERSION_INFO VERSIONINFO -FILEVERSION 5,4,7,0 +FILEVERSION 6,0,5,0 BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904E4" BEGIN - VALUE "CompanyName", "ROLI Ltd.\0" - VALUE "LegalCopyright", "Copyright (c) 2018 - ROLI Ltd.\0" + VALUE "CompanyName", "Raw Material Software Limited\0" + VALUE "LegalCopyright", "Copyright (c) 2020 - Raw Material Software Limited\0" VALUE "FileDescription", "DemoRunner\0" - VALUE "FileVersion", "5.4.7\0" + VALUE "FileVersion", "6.0.5\0" VALUE "ProductName", "DemoRunner\0" - VALUE "ProductVersion", "5.4.7\0" + VALUE "ProductVersion", "6.0.5\0" END END diff --git a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj index 74bb1dbb..24f24df2 100644 --- a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj +++ b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj @@ -64,10 +64,10 @@ 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.7;JUCE_APP_VERSION_HEX=0x50407;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_DISPLAY_SPLASH_SCREEN=0;JUCE_USE_DARK_SPLASH_SCREEN=1;JUCE_PROJUCER_VERSION=0x60005;JUCE_MODULE_AVAILABLE_juce_analytics=1;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_audio_formats=1;JUCE_MODULE_AVAILABLE_juce_audio_processors=1;JUCE_MODULE_AVAILABLE_juce_audio_utils=1;JUCE_MODULE_AVAILABLE_juce_blocks_basics=1;JUCE_MODULE_AVAILABLE_juce_box2d=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_dsp=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_MODULE_AVAILABLE_juce_opengl=1;JUCE_MODULE_AVAILABLE_juce_osc=1;JUCE_MODULE_AVAILABLE_juce_product_unlocking=1;JUCE_MODULE_AVAILABLE_juce_video=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_USE_MP3AUDIOFORMAT=1;JUCE_ALLOW_STATIC_NULL_VARIABLES=0;JUCE_STRICT_REFCOUNTEDPOINTER=1;JUCE_USE_CAMERA=1;JUCE_STANDALONE_APPLICATION=1;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=6.0.5;JUCE_APP_VERSION_HEX=0x60005;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 - + NotUsing $(IntDir)\ $(IntDir)\ $(IntDir)\ @@ -106,10 +106,10 @@ 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.7;JUCE_APP_VERSION_HEX=0x50407;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_DISPLAY_SPLASH_SCREEN=0;JUCE_USE_DARK_SPLASH_SCREEN=1;JUCE_PROJUCER_VERSION=0x60005;JUCE_MODULE_AVAILABLE_juce_analytics=1;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_audio_formats=1;JUCE_MODULE_AVAILABLE_juce_audio_processors=1;JUCE_MODULE_AVAILABLE_juce_audio_utils=1;JUCE_MODULE_AVAILABLE_juce_blocks_basics=1;JUCE_MODULE_AVAILABLE_juce_box2d=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_dsp=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_MODULE_AVAILABLE_juce_opengl=1;JUCE_MODULE_AVAILABLE_juce_osc=1;JUCE_MODULE_AVAILABLE_juce_product_unlocking=1;JUCE_MODULE_AVAILABLE_juce_video=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_USE_MP3AUDIOFORMAT=1;JUCE_ALLOW_STATIC_NULL_VARIABLES=0;JUCE_STRICT_REFCOUNTEDPOINTER=1;JUCE_USE_CAMERA=1;JUCE_STANDALONE_APPLICATION=1;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=6.0.5;JUCE_APP_VERSION_HEX=0x60005;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 - + NotUsing $(IntDir)\ $(IntDir)\ $(IntDir)\ @@ -132,6 +132,7 @@ true true true + UseLinkTimeCodeGeneration true @@ -242,10 +243,10 @@ true - + true - + true @@ -254,6 +255,9 @@ true + + true + true @@ -272,6 +276,153 @@ true + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + true @@ -371,70 +522,73 @@ true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + true - + + true + + true @@ -629,6 +783,9 @@ true + + true + true @@ -926,6 +1083,9 @@ true + + true + true @@ -953,6 +1113,9 @@ true + + true + true @@ -1232,6 +1395,9 @@ true + + true + true @@ -1241,6 +1407,9 @@ true + + true + true @@ -1274,21 +1443,60 @@ true + + true + + + true + + + true + true true + + true + true - + true true + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + true @@ -1901,6 +2109,15 @@ true + + true + + + true + + + true + true @@ -1919,13 +2136,7 @@ true - - true - - - true - - + true @@ -2129,6 +2340,9 @@ true + + true + true @@ -2291,10 +2505,10 @@ - + - + @@ -2304,6 +2518,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2341,50 +2615,51 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2473,6 +2748,7 @@ + @@ -2499,6 +2775,7 @@ + @@ -2611,6 +2888,7 @@ + @@ -2624,6 +2902,7 @@ + @@ -2666,6 +2945,7 @@ + @@ -2741,6 +3021,7 @@ + @@ -2758,21 +3039,33 @@ - + + + - + - - + + - - + + + + + + + + + + + + @@ -2956,7 +3249,8 @@ - + + @@ -3008,6 +3302,7 @@ + @@ -3073,12 +3368,14 @@ - + + + diff --git a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters index 334070cb..9decf190 100644 --- a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters +++ b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters @@ -56,6 +56,36 @@ {092EFC17-7C95-7E04-0ACA-0D61A462EE81} + + {285118C6-8FDA-7DCE-BEF4-FFB2120876C5} + + + {69ED6B61-9B8D-D47E-E4A6-2E9F9A94A75A} + + + {7CDB7CD1-BB96-F593-3C78-1E06182B5839} + + + {B0A708DE-B4CF-196B-14FB-DC8221509B8E} + + + {34F46ADE-EE31-227A-A69E-7732E70145F1} + + + {BB9B3C77-17FB-E994-8B75-88F1727E4655} + + + {C0971D77-2F14-190A-E2AE-89D6285F4D5A} + + + {AABEA333-6524-8891-51C7-6DAEB5700628} + + + {F2D29337-983E-BAD7-7B5C-E0AB3D53D404} + + + {C674B0FB-1FC0-2986-94B1-083845018994} + {0AFC1CE8-F6E6-9817-8C21-8432B2A375DA} @@ -80,26 +110,26 @@ {9EB3EC7F-2AB7-DDAA-3C05-DF382B728D3F} - - {02D37B85-7DE2-C8E7-A274-A5A0FBE99D69} + + {6B9FBFDC-1D10-6246-356D-00FF4535CECB} - - {DAF3BAAF-5207-4C34-61B9-A97DDC930D50} + + {D6FCFC8E-7136-9109-78C0-91A3EB4C443F} - - {C7885588-8436-4C21-DC1E-58879BF53BDC} + + {EBF18AC1-F0ED-937A-2824-4307CE2ADAF7} - - {E4ECEA39-0EFF-2443-91B3-1E5DA7AD5AE4} + + {5A0F7922-2EFB-6465-57E4-A445B804EFB5} - - {210B8D25-68E0-32C3-1449-6A40F109C5E9} + + {4EC45416-0E7C-7567-6F75-D0C8CEE7DC4F} - - {378AD911-E8E4-D230-E76B-34542849509D} + + {C2985031-0496-55B5-41A8-BAB99E53D89D} - - {F6CED5B6-0A8C-56D2-C1AC-DED6BE774A13} + + {FB4AB426-7009-0036-BB75-E34256AA7C89} {E684D858-09E8-0251-8E86-5657129641E1} @@ -344,6 +374,9 @@ {DDF4BA73-8578-406D-21F8-06B9BC70BFEA} + + {73374573-0194-9A6E-461A-A81EEB511C26} + {5DD60D0E-B16A-0BED-EDC4-C56E6960CA9E} @@ -440,6 +473,9 @@ {FE3CB19C-EF43-5CF5-DAF0-09D4E43D0AB9} + + {FE7E6CD5-C7A0-DB20-4E7E-D6E7F08C4578} + {895C2D33-E08D-B1BA-BB36-FC4CA65090C8} @@ -643,10 +679,10 @@ JUCE Modules\juce_audio_basics\synthesisers - + JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities @@ -655,6 +691,9 @@ JUCE Modules\juce_audio_basics\utilities + + JUCE Modules\juce_audio_basics\utilities + JUCE Modules\juce_audio_basics @@ -676,6 +715,153 @@ JUCE Modules\juce_audio_devices\midi_io + + JUCE Modules\juce_audio_devices\native\oboe\src\aaudio + + + JUCE Modules\juce_audio_devices\native\oboe\src\aaudio + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\fifo + + + JUCE Modules\juce_audio_devices\native\oboe\src\fifo + + + JUCE Modules\juce_audio_devices\native\oboe\src\fifo + + + JUCE Modules\juce_audio_devices\native\oboe\src\fifo + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + JUCE Modules\juce_audio_devices\native @@ -778,71 +964,74 @@ JUCE Modules\juce_audio_formats\codecs\flac\libFLAC - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib + + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib JUCE Modules\juce_audio_formats\codecs\oggvorbis @@ -1042,6 +1231,9 @@ JUCE Modules\juce_audio_processors\utilities + + JUCE Modules\juce_audio_processors\utilities + JUCE Modules\juce_audio_processors\utilities @@ -1357,6 +1549,9 @@ JUCE Modules\juce_core\files + + JUCE Modules\juce_core\files + JUCE Modules\juce_core\files @@ -1384,6 +1579,9 @@ JUCE Modules\juce_core\maths + + JUCE Modules\juce_core\memory + JUCE Modules\juce_core\memory @@ -1687,6 +1885,9 @@ JUCE Modules\juce_dsp\containers + + JUCE Modules\juce_dsp\containers + JUCE Modules\juce_dsp\containers @@ -1696,6 +1897,9 @@ JUCE Modules\juce_dsp\frequency + + JUCE Modules\juce_dsp\frequency + JUCE Modules\juce_dsp\frequency @@ -1729,21 +1933,60 @@ JUCE Modules\juce_dsp\native + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\processors + JUCE Modules\juce_dsp\processors JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\processors + JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + JUCE Modules\juce_dsp @@ -2377,6 +2620,15 @@ JUCE Modules\juce_gui_basics\mouse + + JUCE Modules\juce_gui_basics\native\x11 + + + JUCE Modules\juce_gui_basics\native\x11 + + + JUCE Modules\juce_gui_basics\native\x11 + JUCE Modules\juce_gui_basics\native @@ -2404,13 +2656,7 @@ JUCE Modules\juce_gui_basics\native - - JUCE Modules\juce_gui_basics\native - - - JUCE Modules\juce_gui_basics\native - - + JUCE Modules\juce_gui_basics\native @@ -2644,6 +2890,9 @@ JUCE Modules\juce_gui_extra\native + + JUCE Modules\juce_gui_extra\native + JUCE Modules\juce_gui_extra\native @@ -2946,16 +3195,16 @@ JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities JUCE Modules\juce_audio_basics\utilities - + JUCE Modules\juce_audio_basics\utilities @@ -2985,6 +3234,186 @@ JUCE Modules\juce_audio_devices\midi_io + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\src\aaudio + + + JUCE Modules\juce_audio_devices\native\oboe\src\aaudio + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\fifo + + + JUCE Modules\juce_audio_devices\native\oboe\src\fifo + + + JUCE Modules\juce_audio_devices\native\oboe\src\fifo + + + JUCE Modules\juce_audio_devices\native\oboe\src\fifo + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + + + JUCE Modules\juce_audio_devices\native\oboe\src\opensles + + + JUCE Modules\juce_audio_devices\native + JUCE Modules\juce_audio_devices\native @@ -3096,131 +3525,131 @@ JUCE Modules\juce_audio_formats\codecs\flac - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\floor + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\floor - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\uncoupled + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\uncoupled - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib - - JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib JUCE Modules\juce_audio_formats\codecs\oggvorbis @@ -3228,6 +3657,9 @@ JUCE Modules\juce_audio_formats\codecs\oggvorbis + + JUCE Modules\juce_audio_formats\codecs\oggvorbis + JUCE Modules\juce_audio_formats\codecs\oggvorbis @@ -3492,6 +3924,9 @@ JUCE Modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst + + JUCE Modules\juce_audio_processors\format_types + JUCE Modules\juce_audio_processors\format_types @@ -3570,6 +4005,9 @@ JUCE Modules\juce_audio_processors\utilities + + JUCE Modules\juce_audio_processors\utilities + JUCE Modules\juce_audio_processors\utilities @@ -3906,6 +4344,9 @@ JUCE Modules\juce_core\files + + JUCE Modules\juce_core\files + JUCE Modules\juce_core\files @@ -3945,6 +4386,9 @@ JUCE Modules\juce_core\maths + + JUCE Modules\juce_core\memory + JUCE Modules\juce_core\memory @@ -4071,6 +4515,9 @@ JUCE Modules\juce_core\system + + JUCE Modules\juce_core\system + JUCE Modules\juce_core\system @@ -4296,6 +4743,9 @@ JUCE Modules\juce_dsp\containers + + JUCE Modules\juce_dsp\containers + JUCE Modules\juce_dsp\containers @@ -4347,13 +4797,19 @@ JUCE Modules\juce_dsp\native - + + JUCE Modules\juce_dsp\processors + + + JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\processors JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors @@ -4362,13 +4818,13 @@ JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors @@ -4383,15 +4839,45 @@ JUCE Modules\juce_dsp\processors - - JUCE Modules\juce_dsp\processors - JUCE Modules\juce_dsp\processors - + JUCE Modules\juce_dsp\processors + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + + + JUCE Modules\juce_dsp\widgets + JUCE Modules\juce_dsp @@ -4941,8 +5427,11 @@ JUCE Modules\juce_gui_basics\mouse - - JUCE Modules\juce_gui_basics\native + + JUCE Modules\juce_gui_basics\native\x11 + + + JUCE Modules\juce_gui_basics\native\x11 JUCE Modules\juce_gui_basics\native @@ -5097,6 +5586,9 @@ JUCE Modules\juce_gui_extra\embedding + + JUCE Modules\juce_gui_extra\embedding + JUCE Modules\juce_gui_extra\embedding @@ -5292,9 +5784,6 @@ JUCE Modules\juce_video - - JUCE Library Code - JUCE Library Code @@ -5303,9 +5792,18 @@ DemoRunner\Source + + JUCE Modules\juce_audio_devices\native\oboe + + + JUCE Modules\juce_audio_devices\native\oboe + JUCE Modules\juce_audio_formats\codecs\flac + + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7 + JUCE Modules\juce_audio_formats\codecs\oggvorbis diff --git a/examples/DemoRunner/Builds/VisualStudio2019/icon.ico b/examples/DemoRunner/Builds/VisualStudio2019/icon.ico index 09d32ad703e414097a17e969e7d765325e912c77..27c4228e128bfab98bccc5e39de61de6a8faa39a 100644 GIT binary patch literal 36638 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

7jRK$!qvEJzocG(cKfP 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 literal 33530 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

(u1;L6(cQ?)GnM#vbq;}_8j8w4Fi2^0KYHDQh@ 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 VS_VERSION_INFO VERSIONINFO -FILEVERSION 5,4,7,0 +FILEVERSION 6,0,5,0 BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904E4" BEGIN - VALUE "CompanyName", "ROLI Ltd.\0" - VALUE "LegalCopyright", "Copyright (c) 2018 - ROLI Ltd.\0" + VALUE "CompanyName", "Raw Material Software Limited\0" + VALUE "LegalCopyright", "Copyright (c) 2020 - Raw Material Software Limited\0" VALUE "FileDescription", "DemoRunner\0" - VALUE "FileVersion", "5.4.7\0" + VALUE "FileVersion", "6.0.5\0" VALUE "ProductName", "DemoRunner\0" - VALUE "ProductVersion", "5.4.7\0" + VALUE "ProductVersion", "6.0.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 1a569bd1..549c57a0 100644 --- a/examples/DemoRunner/Builds/iOS/DemoRunner.xcodeproj/project.pbxproj +++ b/examples/DemoRunner/Builds/iOS/DemoRunner.xcodeproj/project.pbxproj @@ -49,6 +49,10 @@ isa = PBXBuildFile; fileRef = 61AE09C749B007B70A265D9B; }; + 6658EEC5F9D63D3419EB7098 = { + isa = PBXBuildFile; + fileRef = E07FC48041C3E9F9721F3BCE; + }; 0B0CE6D5062E5C02A41F24BC = { isa = PBXBuildFile; fileRef = 873F9DD54978E601102353B4; @@ -61,10 +65,6 @@ isa = PBXBuildFile; fileRef = 7983C452610C1638B7E78F12; }; - 1FB200F4AE3E4E7CDFF629BB = { - isa = PBXBuildFile; - fileRef = 24D74AF1C95BEF957DC4FA77; - }; AC783ECD84496E0B77911EEE = { isa = PBXBuildFile; fileRef = 34F1320BC5C23702C08DF9F0; @@ -77,6 +77,10 @@ isa = PBXBuildFile; fileRef = F90C8B0233A54F1445343F67; }; + 89AD16514B1F4133FFEA1DF9 = { + isa = PBXBuildFile; + fileRef = 96D99A08027CA35D6A4E5CFD; + }; 47ED2C78B05B8A6A00E36C46 = { isa = PBXBuildFile; fileRef = 685A261BE78585293F3EAD36; @@ -267,13 +271,6 @@ path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; - 24D74AF1C95BEF957DC4FA77 = { - isa = PBXFileReference; - lastKnownFileType = wrapper.framework; - name = MobileCoreServices.framework; - path = System/Library/Frameworks/MobileCoreServices.framework; - sourceTree = SDKROOT; - }; 25E5ED33876A2C752378C859 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; @@ -463,13 +460,6 @@ path = "../../JuceLibraryCode/include_juce_cryptography.mm"; sourceTree = "SOURCE_ROOT"; }; - 72129757D2A553B90A7157C6 = { - isa = PBXFileReference; - lastKnownFileType = sourcecode.c.h; - name = AppConfig.h; - path = ../../JuceLibraryCode/AppConfig.h; - sourceTree = "SOURCE_ROOT"; - }; 76A157A111866670A4678F04 = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; @@ -554,6 +544,13 @@ path = "../../JuceLibraryCode/include_juce_opengl.mm"; sourceTree = "SOURCE_ROOT"; }; + 96D99A08027CA35D6A4E5CFD = { + isa = PBXFileReference; + lastKnownFileType = wrapper.framework; + name = WebKit.framework; + path = System/Library/Frameworks/WebKit.framework; + sourceTree = SDKROOT; + }; 979F23EA9E5E76131299E886 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; @@ -659,6 +656,13 @@ path = "../../JuceLibraryCode/include_juce_audio_formats.mm"; sourceTree = "SOURCE_ROOT"; }; + E07FC48041C3E9F9721F3BCE = { + isa = PBXFileReference; + lastKnownFileType = wrapper.framework; + name = CoreServices.framework; + path = System/Library/Frameworks/CoreServices.framework; + sourceTree = SDKROOT; + }; E0A3F113BC27B7B4D6F1D693 = { isa = PBXFileReference; lastKnownFileType = file.icns; @@ -816,7 +820,6 @@ 61F3057D838D7DABB0FA3D34 = { isa = PBXGroup; children = ( - 72129757D2A553B90A7157C6, 5965349393850F41DF76F350, 03B0F9318FD583525AB195A9, 03A63C3CA6F24977F19C316D, @@ -867,13 +870,14 @@ B28EFB9D1DF0B6D6499A7DEF, 1CFE3935A3B810D5D68A2504, 61AE09C749B007B70A265D9B, + E07FC48041C3E9F9721F3BCE, 873F9DD54978E601102353B4, 49ECA8B998B339A083674A22, 7983C452610C1638B7E78F12, - 24D74AF1C95BEF957DC4FA77, 34F1320BC5C23702C08DF9F0, 23CD1A3F9067C3A0ECE7BB67, F90C8B0233A54F1445343F67, + 96D99A08027CA35D6A4E5CFD, ); name = Frameworks; sourceTree = ""; @@ -916,11 +920,41 @@ GCC_PREPROCESSOR_DEFINITIONS = ( "_DEBUG=1", "DEBUG=1", + "JUCE_CONTENT_SHARING=1", + "JUCE_DISPLAY_SPLASH_SCREEN=0", + "JUCE_USE_DARK_SPLASH_SCREEN=1", + "JUCE_PROJUCER_VERSION=0x60005", + "JUCE_MODULE_AVAILABLE_juce_analytics=1", + "JUCE_MODULE_AVAILABLE_juce_audio_basics=1", + "JUCE_MODULE_AVAILABLE_juce_audio_devices=1", + "JUCE_MODULE_AVAILABLE_juce_audio_formats=1", + "JUCE_MODULE_AVAILABLE_juce_audio_processors=1", + "JUCE_MODULE_AVAILABLE_juce_audio_utils=1", + "JUCE_MODULE_AVAILABLE_juce_blocks_basics=1", + "JUCE_MODULE_AVAILABLE_juce_box2d=1", + "JUCE_MODULE_AVAILABLE_juce_core=1", + "JUCE_MODULE_AVAILABLE_juce_cryptography=1", + "JUCE_MODULE_AVAILABLE_juce_data_structures=1", + "JUCE_MODULE_AVAILABLE_juce_dsp=1", + "JUCE_MODULE_AVAILABLE_juce_events=1", + "JUCE_MODULE_AVAILABLE_juce_graphics=1", + "JUCE_MODULE_AVAILABLE_juce_gui_basics=1", + "JUCE_MODULE_AVAILABLE_juce_gui_extra=1", + "JUCE_MODULE_AVAILABLE_juce_opengl=1", + "JUCE_MODULE_AVAILABLE_juce_osc=1", + "JUCE_MODULE_AVAILABLE_juce_product_unlocking=1", + "JUCE_MODULE_AVAILABLE_juce_video=1", + "JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1", + "JUCE_USE_MP3AUDIOFORMAT=1", + "JUCE_ALLOW_STATIC_NULL_VARIABLES=0", + "JUCE_STRICT_REFCOUNTEDPOINTER=1", + "JUCE_USE_CAMERA=1", + "JUCE_STANDALONE_APPLICATION=1", "JUCE_DEMO_RUNNER=1", "JUCE_UNIT_TESTS=1", "JUCER_XCODE_IPHONE_5BC26AE3=1", - "JUCE_APP_VERSION=5.4.7", - "JUCE_APP_VERSION_HEX=0x50407", + "JUCE_APP_VERSION=6.0.5", + "JUCE_APP_VERSION_HEX=0x60005", "JucePlugin_Build_VST=0", "JucePlugin_Build_VST3=0", "JucePlugin_Build_AU=0", @@ -939,8 +973,12 @@ INFOPLIST_FILE = Info-App.plist; INFOPLIST_PREPROCESS = NO; INSTALL_PATH = "$(HOME)/Applications"; - OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow-all -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wunreachable-code -Wzero-as-null-pointer-constant -Wcast-align -Winconsistent-missing-destructor-override -Wshift-sign-overflow -Wnullable-to-nonnull-conversion -Wno-missing-field-initializers -Wno-ignored-qualifiers"; - PRODUCT_BUNDLE_IDENTIFIER = com.juce.demorunner; + MTL_HEADER_SEARCH_PATHS = ( + "../../JuceLibraryCode", + "../../../../modules", + ); + OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow-all -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wunreachable-code -Wzero-as-null-pointer-constant -Wcast-align -Winconsistent-missing-destructor-override -Wshift-sign-overflow -Wnullable-to-nonnull-conversion -Wno-missing-field-initializers -Wno-ignored-qualifiers -Wswitch-enum"; + PRODUCT_BUNDLE_IDENTIFIER = com.rmsl.juce.demorunner; PRODUCT_NAME = "DemoRunner"; USE_HEADERMAP = NO; }; @@ -963,11 +1001,41 @@ GCC_PREPROCESSOR_DEFINITIONS = ( "_NDEBUG=1", "NDEBUG=1", + "JUCE_CONTENT_SHARING=1", + "JUCE_DISPLAY_SPLASH_SCREEN=0", + "JUCE_USE_DARK_SPLASH_SCREEN=1", + "JUCE_PROJUCER_VERSION=0x60005", + "JUCE_MODULE_AVAILABLE_juce_analytics=1", + "JUCE_MODULE_AVAILABLE_juce_audio_basics=1", + "JUCE_MODULE_AVAILABLE_juce_audio_devices=1", + "JUCE_MODULE_AVAILABLE_juce_audio_formats=1", + "JUCE_MODULE_AVAILABLE_juce_audio_processors=1", + "JUCE_MODULE_AVAILABLE_juce_audio_utils=1", + "JUCE_MODULE_AVAILABLE_juce_blocks_basics=1", + "JUCE_MODULE_AVAILABLE_juce_box2d=1", + "JUCE_MODULE_AVAILABLE_juce_core=1", + "JUCE_MODULE_AVAILABLE_juce_cryptography=1", + "JUCE_MODULE_AVAILABLE_juce_data_structures=1", + "JUCE_MODULE_AVAILABLE_juce_dsp=1", + "JUCE_MODULE_AVAILABLE_juce_events=1", + "JUCE_MODULE_AVAILABLE_juce_graphics=1", + "JUCE_MODULE_AVAILABLE_juce_gui_basics=1", + "JUCE_MODULE_AVAILABLE_juce_gui_extra=1", + "JUCE_MODULE_AVAILABLE_juce_opengl=1", + "JUCE_MODULE_AVAILABLE_juce_osc=1", + "JUCE_MODULE_AVAILABLE_juce_product_unlocking=1", + "JUCE_MODULE_AVAILABLE_juce_video=1", + "JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1", + "JUCE_USE_MP3AUDIOFORMAT=1", + "JUCE_ALLOW_STATIC_NULL_VARIABLES=0", + "JUCE_STRICT_REFCOUNTEDPOINTER=1", + "JUCE_USE_CAMERA=1", + "JUCE_STANDALONE_APPLICATION=1", "JUCE_DEMO_RUNNER=1", "JUCE_UNIT_TESTS=1", "JUCER_XCODE_IPHONE_5BC26AE3=1", - "JUCE_APP_VERSION=5.4.7", - "JUCE_APP_VERSION_HEX=0x50407", + "JUCE_APP_VERSION=6.0.5", + "JUCE_APP_VERSION_HEX=0x60005", "JucePlugin_Build_VST=0", "JucePlugin_Build_VST3=0", "JucePlugin_Build_AU=0", @@ -977,7 +1045,6 @@ "JucePlugin_Build_Standalone=0", "JucePlugin_Build_Unity=0", ); - GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; HEADER_SEARCH_PATHS = ( "../../JuceLibraryCode", @@ -988,8 +1055,12 @@ INFOPLIST_PREPROCESS = NO; INSTALL_PATH = "$(HOME)/Applications"; LLVM_LTO = YES; - OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow-all -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wunreachable-code -Wzero-as-null-pointer-constant -Wcast-align -Winconsistent-missing-destructor-override -Wshift-sign-overflow -Wnullable-to-nonnull-conversion -Wno-missing-field-initializers -Wno-ignored-qualifiers"; - PRODUCT_BUNDLE_IDENTIFIER = com.juce.demorunner; + MTL_HEADER_SEARCH_PATHS = ( + "../../JuceLibraryCode", + "../../../../modules", + ); + OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow-all -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wunreachable-code -Wzero-as-null-pointer-constant -Wcast-align -Winconsistent-missing-destructor-override -Wshift-sign-overflow -Wnullable-to-nonnull-conversion -Wno-missing-field-initializers -Wno-ignored-qualifiers -Wswitch-enum"; + PRODUCT_BUNDLE_IDENTIFIER = com.rmsl.juce.demorunner; PRODUCT_NAME = "DemoRunner"; USE_HEADERMAP = NO; }; @@ -1020,11 +1091,12 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; + ENABLE_TESTABILITY = NO; GCC_C_LANGUAGE_STANDARD = c11; GCC_INLINES_ARE_PRIVATE_EXTERN = YES; GCC_MODEL_TUNING = G5; GCC_NO_COMMON_BLOCKS = YES; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; @@ -1070,10 +1142,12 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = NO; GCC_C_LANGUAGE_STANDARD = c11; GCC_INLINES_ARE_PRIVATE_EXTERN = YES; GCC_MODEL_TUNING = G5; GCC_NO_COMMON_BLOCKS = YES; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; @@ -1093,10 +1167,6 @@ }; name = Release; }; - D87BAF6D1A7451B7A733B5F1 = { - isa = PBXTargetDependency; - target = 291E01DCBE746A376DBFA4D1; - }; 80E8AD1971F52B06F4D28891 = { isa = XCConfigurationList; buildConfigurations = ( @@ -1173,13 +1243,14 @@ 7F57DB52C3CEFDC26DDD38FC, 46071CE2B98B562B7BF27CB1, 6A61CBB4E39BFD392D97528F, + 6658EEC5F9D63D3419EB7098, 0B0CE6D5062E5C02A41F24BC, 5E4310B3F6BB639875D3E9B8, AE7FB2AC3885F4BF53A5DDA1, - 1FB200F4AE3E4E7CDFF629BB, AC783ECD84496E0B77911EEE, B1981F62F6A91FD2F579A198, ECA44A41DA8A935178C1A1F4, + 89AD16514B1F4133FFEA1DF9, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1201,7 +1272,7 @@ AC6F0E9A0809A184B2C2B7DE = { isa = PBXProject; buildConfigurationList = 80E8AD1971F52B06F4D28891; - attributes = { LastUpgradeCheck = 1100; ORGANIZATIONNAME = "ROLI Ltd."; TargetAttributes = { 291E01DCBE746A376DBFA4D1 = { SystemCapabilities = {com.apple.ApplicationGroups.iOS = { enabled = 0; }; com.apple.InAppPurchase = { enabled = 0; }; com.apple.InterAppAudio = { enabled = 0; }; com.apple.Push = { enabled = 0; }; com.apple.Sandbox = { enabled = 0; }; com.apple.HardenedRuntime = { enabled = 0; }; com.apple.iCloud = { enabled = 1; }; }; }; }; }; + attributes = { LastUpgradeCheck = 1200; ORGANIZATIONNAME = "Raw Material Software Limited"; TargetAttributes = { 291E01DCBE746A376DBFA4D1 = { SystemCapabilities = {com.apple.ApplicationGroups.iOS = { enabled = 0; }; com.apple.InAppPurchase = { enabled = 0; }; com.apple.InterAppAudio = { enabled = 0; }; com.apple.Push = { enabled = 0; }; com.apple.Sandbox = { enabled = 0; }; com.apple.HardenedRuntime = { enabled = 0; }; com.apple.iCloud = { enabled = 1; }; }; }; }; }; compatibilityVersion = "Xcode 3.2"; hasScannedForEncodings = 0; mainGroup = 91A9A0FE9DF4F4E10009EEC7; diff --git a/examples/DemoRunner/Builds/iOS/DemoRunner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/examples/DemoRunner/Builds/iOS/DemoRunner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings index 949b6789..f2e3cbe8 100644 --- a/examples/DemoRunner/Builds/iOS/DemoRunner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ b/examples/DemoRunner/Builds/iOS/DemoRunner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -4,5 +4,7 @@ BuildSystemType Original + DisableBuildSystemDeprecationWarning + diff --git a/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon-29.png b/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon-29.png index 9344000d603583145f6345e3fde84ab3f1653174..74c4136e077278a10b4bebe0db4b2769c0214d95 100644 GIT binary patch delta 1955 zcmV;U2VD5_48RYNGk*tnNkl43q8HS&`%)Z*Qd7IerGIks{&C&=ID|+fAE)J2u&gB+7uWuBNaS)WD#uDJ1hVj3v%8wS0+?b0c9_ zJAP{jmo0$F>_*knb>g`jG<$pK3hu%02xFFQ2y4JsL3N`-x|m>mVUU^B z7-4sWP0lWCWq%bdd7Vmn2FX>2xp^B}Y7kwyg=7ySx+4@sD`V+#rZd-QbVuk6^y0OJ z5Cv&{XvNT&&rC9!cn_0krrXhlJG+cJJ%kz`#n8$C$o>wj9Xru7r>SJdSA;|hlD7vr z@Hi>6pDXDxG+m`T_&9a$HY7o=LaT4OQQ=l*f-Cc9@P9cPiAW*D>t`v%hA>oRRRdO@ zyGHa9+R{f<(xbQnyLl|QpK&G0$ov@q>fPaH_lTS>#q)(&1U-g`uOQfze8&{ z#Lxa-W+V}&(tMbu`4=e_hPi)dmy09Vgd%mWjZ7>JBgaysgq>}aZ$>fH;yS%r-9)$B z&2xv3F!|&`jvYJ3xv8JfyKRzCP{wY%_kU+#=q1Xvn)f0o?tisb z64^ffP*vM(HlBIr3!FOTPk? zp`ePQ@WzRgoWF7%N5fu*r+n49M!&?y`VuD5jO?`3kSi=;o{Lk8URzU4PiG$pGYo_N z{(k=P+6k@`0K(X(uHb{%YSYrQ!L=J)F1~OVHV2sv@|z9R5ka<s z9Mo?)fV(z`#cErX=XID_Dqbbv3L}TT-OQw-M7sJAEM|;Sd9|{z`XbI`GW_MQf8*HO zgM@cK#m}F8f@mzw+){p3t}KZJJa#T7$7pg#5ZnCQiRW)n@|mzax_K4Mx_|u-$#>C6Bdyxmw$E<{O`=?d;)CV!25XASm!y@(zc zw%t3BzxX+ZUb~1ZYvVUB{hAlP`9mthIi8LjB;*aOs%S8l;>G?OG}LDrLbd~G1aZH~* zKq6HkF*b*;Rggr9=9(r^-rteKDamE)0nN44%(Gj6V-incyNKPb3&n@E$x_|NXc5rew%XCViwbo8g z$VIJ9A*Fo4t?bHqj696*y%SZ3UzlMm{ytNw5kiiQ)Z03!H8PJnVm;D$lP&?u@|CKiW@rJ^MBF><9PDu#w6$T%!D1e_aa p@^sPe+m6-bLL3rgg!Q&K@IO_GPJlGIG3EdO002ovPDHLkV1kma&~X3& delta 1618 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 delta 4385 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 b@8$mizPF}$l(Dos00000NkvXXu0mjfk!q^X diff --git a/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon-29@3x.png b/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon-29@3x.png index 6021b1d0c734a46b941ffc26f44358570479745e..aace636392df8b4ab104cfc2fe661bb70095b46b 100644 GIT binary patch literal 7835 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 YN-Zszhe0LXT=%m4rY literal 10478 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 diff --git a/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon-72.png b/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon-72.png index 52ec77a646f593f384468a65115d5b52b17a87fe..af1016a27d8fc6cbc37f4fd81dbf08d3f25565e2 100644 GIT binary patch literal 5792 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 e;B$h8!T$n3J`1Q*iylt^0000Lk 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 diff --git a/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon-76.png b/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon-76.png index 1d84eb4b92262eaa900e9f22355e4b736e3e0411..9546f1de5555828e7684ff6715bd60fac640f6f6 100644 GIT binary patch literal 6314 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 delta 5365 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 T(X=g$00000NkvXXu0mjf(Kvh& diff --git a/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon-76@2x.png b/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon-76@2x.png index 4324c82b122b18b8717ec04292a78389759bb99e..df42b467b960581746207c5d7420c944ac461db9 100644 GIT binary patch literal 13724 zcmW-oV|b*^5{6^jwr$(q*qkIA+qSi_%`dj?Y-~H(SR4Dyp1B6s{Fv$Yt?KUTdg`ty zWhH4uI6OEI5D-LJ83|S3XU4x53>5GkXOM&x_yOS}CaVqueE7ncMS_5kfXGUSs(a>K z<$Cz4YwUarw<*j{m1r%hSGCTLkAe_0#h7-yy*ifq)dy;xUj%#HNW4R2G_n z7bHTHiJ(H{vSE0e<1Dces9k%$DSHt@yB2o5_2x+Q?!(x`Dm6bi< zkajl69nx9hC?F6=_98D5aRdmQH9_GpKq{qocC$ZzLQ+MORVt2**9ZnLjN0PZaJgpBzv|u*?F5EOWy{mjn%_5y61GEke)f9~jV^v#gOSZh>q0 zqpF@AZPL67Zh%1~&JLq4Nh;_oP#a?a!dra#_xVDxmM=&H=iagRFGwTZ^WcnEn~c_^ zE6nmRnL2t*eV}%z)d6ZzR8Z3LOKBa~Of28M`BH|wiYc8`%`w~gRJw^fhu0$kZ`I&j z#o2gdMyQNklF{2ab1hsDEE#f04HCcecUaL|6H$QDC{00BtCN*%ji1?3qO&3Z0+0*gf6C9nW$oSzU7rtyGbK{e|3WQ|!xnfWke@^;{xKAr0uA)t zqYHDFbUx<4zmb;X-WOXIy(NO7m&y-su5XY*A`COuP)B~4d*;xlPt@`OOSeuaYG&

Hm1BNfK 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�+^~r^Vic$Xd=-IG}I-ZM*+`vmnn*N>^!j;?c1Y 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 literal 10888 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 diff --git a/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon-83.5@2x.png b/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon-83.5@2x.png index c2cfbef3f20d48558f0ef8b62c59a2e69066fea5..d6439722207b070320861f52dc9d07681dcb98c2 100644 GIT binary patch literal 15722 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 literal 12870 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 IGG;;l0~$)J1^@s6 diff --git a/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon-@3x.png b/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon-@3x.png index 15deee7ec5b04b061e5d44138e9e1eb8cce1b2b2..e6f0d363795b296b7193f64b504480f508e1e48d 100644 GIT binary patch literal 17617 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�jCczTY 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

<O$gxL8i%HMNcJRzaxa}11QgO1~%I6Z+H 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 literal 49618 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 diff --git a/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon-Notification-20@2x.png b/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon-Notification-20@2x.png index 2a865c6fe6162e2b5c909b87eba9a5a5eb94398f..7782ff99f57bdb7584b7e42bdfd1b515081d92af 100644 GIT binary patch delta 2909 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 Hu0mjfOvk%j delta 2276 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 diff --git a/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon-Notification-20@3x.png b/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon-Notification-20@3x.png index ad988c8094c4553d451cf1f806ba34f835a4b99b..caf3d2bc85ba7784ba482cd9e29e1e198ace07ef 100644 GIT binary patch literal 5643 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 delta 4679 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 JPDHLkV1jWBED8Vs diff --git a/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon-Notifications-20.png b/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon-Notifications-20.png index 737b345d9b874f81846ed796af12901455de306e..f7906935fcd1bd3f647b582010b1a5619b6a24a5 100644 GIT binary patch delta 1075 zcmV-31kC%82iFLYGk*jQNkl<ZIE{UkZ)_7~9LGP`yLQ*>?m9PGItn;gw}LSK1x;Y% zUksuqMhymoz7PyCkr!&>D>ZR3Au+~86QhF4jK)Av0wIDrAR?HJ5K$(}pfI`#b7d{X zt=FyHwb$$UqEI&&eqTP%@A>3+&-Z@cN3d<%<_=}^I<a&wLx1Tgx{<^vWB{m;6slxD zwOWXv)`;Tr-gy*ZBGASrlIWx>c9hj~H&cTfd$0?aFANnHrXE44Ud~M`&#C^sEDLU6 z{`6)9gu8)x%i#3Y11L_71qBuB$_dP5FBC20&^pBX4D#{gAc%<Gc?f|GTqqc1%rwpS zZ^S9e061=Uc7OWX0cLnZEE+9hbbNxDh(OUQ_g<E5VWlomxby*wZG#zF1D#h7VBe~7 z07Md<D3VIxauh)cAgTdOtH?kyd)FP^mcv~O-dW5Lui|lOL=v5)^=w|JE7ndp<znR6 zE^dDRA@agayx%^=Y1bp{>$Vt3W+uaAKd$grQp2B-PJgx$R%On`+R5g1gx=(Dwk&yY z9{iNtwetW-RRMPVDe}?oZ^-3x?Eh{b*Ux{=_9r|zJptTHTDci-#WE8BxZDdF*S2Ap zV@N~kD9h9b8UDMc+(97~CmZQQ5CkeKE7|(uHu|D#*?*)BpU=&T>8%tCiE_PZM5vzT z;@n6-j(?PK1M~73?6Lt<t3DLsrPtmiwCHJGe=EwsV4h;JWQ1*76tZX0vq_{}A&Wd~ zHN~ZmO)}GY_VAS8rluyo{OT7vJC1Ys*lspI+X4v4?)eynqeuWk$_1CaFmY%`od4T# z!B+T7Uqg3t695g)($q*5lEQfRWyXFwG3kIg5PzEz)YH?$8*lHR<;g8HEPt5Z*a!fc zB2pnLNL8{QXY*2o&-Y<l6YfzECV`^SC_DH6Ky}SDo`3Zn#tgH(=MV&fKAF*fd^l>g z5F_e1t_9(8ffVrLZg~jXw#j5Nw0+UWGp!%<W5r@lNsX*pJR8;RD%bm~6mrEO0+n-d z1b?+gPWA7_{nWY=EEvG`%FB$za_ri<i`Fe~GEG-`{DtiZ4w1pM!IpzP)YtjYloGTd z=;37F9)en9DI6{)IvC3hGq1zK42Aji+b&YqhZ)YM@Kx3jT0M^=b7per;(!0%>?$|! zt#3fcn;6m=JWekQ0;@{1Jb!vKS#y-3^?$X*Z{!$_>xd2!UuDfbT^>k{^ZU>!vf58J zuk%2lrSydW0s<@RHkRURk;;ndHT3^{h2)huMXOly=oUzH2rQ{p+0;~nU+Lnyo@Qm; z#&RZ38L)rE+F4uw97?8|*ttRc^#KM{58ZK{wR1FNDZ$CUJuC}8dhdXpsBAvXpe%l= t`~>8!QjAqd3YzSvR;_2IH$3GN@GlkjxCa%}0<8c5002ovPDHLkV1kP646FbE delta 874 zcmV-w1C{*O2#^PmGk*g|Nkl<ZIE{tWOKenC9LMqRxpVKlI@5Nh)6#ZI2WbT*hSV`A zaiHC{DH4O2m~J#7YFLQ67M9@7bYVhpDJct5ZH&cI0YyrSQ71}hFl}0D)S(X<O6UE! z_Z}BRXF8ou`d^*o{LUx;^FO&)NGT=Tltdz>L=nn%QPgT1hJR@=xj066`6d}N1%Tb+ zB-qqLsHG28+4`v1++i{wV`_1noS9{}bmLD;ob|g9c9T?Mo`|9{uP0FzjZkwRE^BRd zFr~*Cni=HCj-%Aw{SN(~FaTQM6+~kWedSi+S`7zS4IF1Q@+|{<KB7i*7s29ClKB`z zGlLxKc$d0Au74D<txAvnO8sA#d86ZfF3k**$j2(dJ4@sA`}z^XpP}q{5#jVy1%=g% zy7MsB_~#r6yvEex)pF1<4RS^n$Mwr(XYa6f^$Q%K4-t+^R9HROyFMY686uzl1$Sl` z-OQm&y#!7!juFT>$jnRvV8$O2y>uG2v$qTtRu9^qH-Aa2eTr#30wACMjomdhOhiUY zV0if^%};V=otW_`u^%qtI9%vdv3ap~ohF_C8q<iDWm~N};q?cTNHS&$m#>4=zV3=E zrhdPM>(E=^5M+`gsJ7=SGFIC&=<+8_X`o6eL4bH-L)@>goLPgL{7Y8i78i3%uanH` z6`8$l9)HBswW<gOyW%9V@POQpQ)NNLTaV-18K%GglkxUej_+$?e)?Zhn^13^f<<U3 z!cv%Fu&IZocBKL{-g%qr=WmmGoMa`D<;2J|4b2{$Hmxk1RU-r&dkW_OLM?qP_~O_O z2A^Uc9OusP^NqhruO^EJ|4ZgLJF&ol7yL!k?|*ag*qEi;-(Lb%MMYIK(jOef_Hq}T ze2*LFZ<k>k(Gw%nwC(iL=5z6Ur@$gKR7ER+0HNkSuEf4Uo;}I^dr?wbU>nhk_m()g z-^sOyUlMBREsbh@;j-2;u=iuWn!CWRflgZXw^s#U4R|<p$i?v71qPlyh09u3+^hI~ zC1dh2rXG%=%RIidR-8+<G&DEypx(`FbQQ0A8BLqVA~ZrRy=B;z;Cks&XCg96c;yy` zEPO>4p%HBCq1)eIoZ0583T`Y@8UQH5vR#z_0le={dI?*aQ~&?~07*qoM6N<$f*<^- A^8f$< diff --git a/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon-Notifications-20@2x.png b/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon-Notifications-20@2x.png index 2a865c6fe6162e2b5c909b87eba9a5a5eb94398f..7782ff99f57bdb7584b7e42bdfd1b515081d92af 100644 GIT binary patch delta 2909 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 Hu0mjfOvk%j delta 2276 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 diff --git a/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon-Small-1.png b/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon-Small-1.png index 9344000d603583145f6345e3fde84ab3f1653174..74c4136e077278a10b4bebe0db4b2769c0214d95 100644 GIT binary patch delta 1955 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 delta 1618 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 QV*mgE07*qoM6N<$f-c%A=l}o! diff --git a/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon-Small-50.png b/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon-Small-50.png index 3328c84262e0e2cf2a308574a2e629805b9aed10..0d2e072d0e98bbd8847147ec65e40c591b7d59c4 100644 GIT binary patch delta 4131 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 delta 3415 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 diff --git a/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon-Small-50@2x.png b/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon-Small-50@2x.png index 66506473afdf2bab8d5742dd1259c48ba550253d..2d6b6e616e1718e6d8435defdec35cff2b88a4eb 100644 GIT binary patch literal 9998 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 Y0d8MVtZ@6MB>(^b07*qoM6N<$g643;0{{R3 literal 8292 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 diff --git a/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon-Small@2x-1.png b/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon-Small@2x-1.png index 84a06c0479f40f8a0f1fbc9f77b3c3fa99f6ff8f..37e6f16c473525fff76b18fb42feee40bf00b3af 100644 GIT binary patch delta 5384 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 delta 4385 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 b@8$mizPF}$l(Dos00000NkvXXu0mjfk!q^X diff --git a/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon-Spotlight-40.png b/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon-Spotlight-40.png index 2a865c6fe6162e2b5c909b87eba9a5a5eb94398f..7782ff99f57bdb7584b7e42bdfd1b515081d92af 100644 GIT binary patch delta 2909 zcmV-j3!?P@5%U(1Gk*&zNkl<ZScR>bdvsLQy~jW2%$Zj*lVtLokdP-$ASU$EC{+}b zNYQ|A(Of~L<*L0}?YdG{h1R;Xw#!;qExzqVmdh%yi<VXpp@=5PQ#90@WRyhmBCpBh zF_}kZCNt;JKO%v^BoO7h*7@h`-|x3Sd+*=g=bYaWG)>c(qJM%BAA^Bzdi`y5c^c^- z?!Xi5XG94AVARDBZ%!sDHj~V_Lei|cB*sj`thY|JD}<>4hLsT2C*G#9?+9Tzh$!mF zPADcbp^(Iwj4^;<*vCMyi!M(i?d}FtRly*cDNMPXiW&D{(3vhS;9#(aW1YKcaMloK zOraokE;+W@*nh2gNTLBP><3jrFvSC)MTS7oAxKtaHH_2OO1ry`#=cMS1YMM*ms6U# z7@OJt-2hchq21lUcE|HbIs;{SODRq(LsP=2!vl=8)DUhxfa32%kc`AH{sV$uW4QKz z(3B9ODGhyE8G8Fd1Y-(<XrQ6@6ZW-iLRP}uRP+ehiGRh2g6`V^?rB<2eNQ!)PQRYg zj73=VaRk5ILAdn*vZo7F`HV;caSI+pFv$e!9)~l-iW0h*=}4*N7_*k(k9eu=+|B2m zJ1Mc3b8W$W69P)nZiZw(?|=C+PG1X)W<JQQ)GLs?>liw^9>wRHFc?fQR#isvx1#u4 ziFEJ6RDbX@uFkC@C3ZR=pLh#TsE-?qevV19oZ~7+i?_q^5^e5!ZlArHqSSc=j=q7n z`q}fqU6|C6lR(2$jC}nnMXB?+efDZjx*OQxcqyv=I6zfX*weJ0UVkfh&v^>FH6JY! zBHUR!emTE0rHtJF8JZHnZq4VeAN-D9e=B>M)_<d@%EW-}ZU^-})m$@UId)49YRHcu z88KvD3PRM${&o^Xq~y5>IuoiojNO{UH8Yk|-%~@!kYk+bSPr^_J#2TZ<<jZbGb`l^ z20vI!py@C%h4Zjo`!htNg+Tq^K~w4I53uW4H<feJ$x4ZxGMq813PW}kp1!{j@*lxy znSaZy)Q9LB?%+MgTJ9-*n#7oN;EWlp?c9x|Gf<kbh*0xU{Kq~(@wo7PwjIy@jhKpV z##FEnZ%Ad)(+B8?yMhNdb+YcmW?Y`o1;Xhtq*r3duEIaGmEobCC~_Y`&p#On)KZ#R ziKH`ftZVm}iwL7nhz4g3WqC`9m8=ZzTz`wEL`E$%70)Mc<KFWsF_--Wf966o$;{fd zYuQtM0I|4=#ZMpLy`x>6@5nbyzZFx#gLntl;~UrlsH0tIG9K3}#OmWH%Ueo=vxcw| zJPlZV;%(xLDHNxb;XAYi+1)cfvZms%eV?Jd>oDY8IXW4FKwMlLt5>gK$A|kl9Dka{ z(ubeqqmOG))hIKUbvwqKJMj+um4IjW7~Cl-5hug$cPX}CO`Iu(niCsG0fP}AjeSQb zNSTW!k1$-nH|pp$RmOX8GegyHp3_!bT+HjQujkjld7NMV_DvrClLMDK{0*FlA-xh) z-jDIQx8NV#il#+B5rV#IG<Af+lz+K=<vK(#;zJw^bQ6|?<Rs2U_PB`jpN#4}7UcLR z6SkF>mU8IuVQ#(m&#ZX1mnUBTnsD;17-!szr|&NeySGgmTMl=i$S$&Nvx%r727}#* zPG2jcsKai}WB7|*r*m&YO`d2Li-jdimau)-egykXEP3c{{%`Z|7<BEJaDV2;B5N{1 z?}yl}d5D5Uudfxc+uKBTLNStPm~eT&jchg>&pr1XTeoiI{oQRWy6q5OHTur$7x2~~ zi3YN5m(cC~8nMrRl8l5x)Swr6$a&EKVRR#<rKR!an{V;_i|_E_>sHo0`6VrFfeC#S z*@dcj$&8;#pRWVa8yX<VoPU9)DhLKM2*TtS!jwTJNusi{lJ~a%lgb<Z$g=xd*!)fx znszGQ=}QnzfJ#!#H2fn2NFz!Bv%!ik)<*hI*P(b^OqOTf)|2qg&!-G|O3RilqpYlq z<;$zMd&Q$9#K)a(6a;iqGNLX4v))Qj4xaV8HLL@-aZ*6MhHnjbrhgRGM1Qb=h#}!j zK4Oe|Yz8>BQj$>@Lon<^aeL@_U=3PmWYWL`LH~CG+q`)*kFH+Lf+hEI_=Fol7#i2E z6Gi^>>H>lhA7;sn6mL#uAlOB|Z5CSa0-mW;{|H2uW%lmf%S*4k%CKhUfhS)hEh9T> zI9X8<1%ZJ;7gkd;Qh!oRCS5~~h*`HF*;A06eNzUQNSdbMa=G}$s#Vk+IKusFo+UH4 zU{W88S&vb#qtkPoWJ@MuX2ML`-Sx<7nAinZT{Jki+s&#~tEj4~;)hpX%i}L^Jue(U zzC9jU4b$#!Al*6xG0l>Ls;M}AEyPw<AV^U^Q%*~m{Fw3k{eNuRwvBl|TEvFBUT%Kk zHGaC{E=uz3i0APYMS<^4v*Gl$qG}3h);y%dm}wX!Gi`%)WK6pmeRc-n=JpALn6H`( z?O#M~`~36I`N@hE^jNY;y5(0STN8Pseh@#cJXW5MUeZz5I&lgm#2T@f^*B1}(2FLL zVx}RP^;QZ~E`O)7?^CYKxr5jR^P>U^k`C(~HxjyX4s2XEuC1Y=fft^Cf&Tt}mack| zO+zVY-y9RFrtxlrlNh~@hc3?=wQuW3jk4MD?Fr~afyTa1nUy*Zv)(%TK3Fm19=xGG z>Ye+r-gy&JdfM4@kLCIwk#OHKnh!SvqZ`2M_43R!&wsFR{sPQR0x$pe1<ER}K{)IC zMOHQ5sO{vHBPS`HkxF5v?VL=pnhliXCgJGak0<D&e8yd)T>}_&CQ8!F+267Wzw9CL zk$VyJ(imL)-M10{;Ey@F;UJyWEhr(Gl`B_LF~0)G-;VL?YgTeu)|~UDCvW|$i{Do_ zQ~JF$zJH&WI%Y450`q326Nn74uVoV@>E#%7=F@-xKgd{wtVXEq`~cHs|AA%k0(2=! zSZ`d2b=hsy@BDw7K5}3Zjr^+o5xhtHSeAPW3k%ALH^oH-I$N@;@lJ!2b)R)ooSnqX z%tT^MdI~aZWF%WS*0~#58KE?D@tDuJ(ns519e;nT|0CBG{x`)bSD^-j2qqJsZ8%8d zM-DV~;zL>x1QtAcJuUH89{7hNYL1<fC<s)Q*m<lxA4O5oOCn#n4zcU_Yur}yOL7yx zf7<p;$1K|=l-Mh%Y2HB3a5JJMmPlBk<5=6Ia8s44Y1Fh1G8|Db=ymk^Tlx6JUn#bi zk$;s?Jbp0aN2cT2!uv?G<g)Q!Ptff>f!?GiV@@`rG;sxLs?zHO%5oBkHRy2qTG(*x zandZgTvvEMI&pkIQOgB46g^C~Z8qELpT*(&gt^P-Q?arVYwCsN+GNUzGx6dLMf|2B zpGMa~-mQCv?1W-&D0(=mebmQ>S#RZz*?();)3l!5$N!i9;Z81{wTPSlw2UuzenIQu zukmybp~}iRzR@<aUMG@kGqbobh5steBorCqVA~dso_wE@^m48%ynn(0O<EsRRE3Tq z2k$x7B8dj(=iNz(y&NU1Fg)O+dEaqbkDOq*--l$>v-qhc^qWoGx#bH25ruTCk$=U7 zDcn+IXPVWBNfL1M?*FEMIl@hsJVI7N@j1(S!GNda4mzpr+(m=42CFfd!jvD9lX$uW zJmL?bsT!uZ(X(qH5J4vjB$%YJ5^$TljwaWqctRJk1bntelpy<>H}X~QAtGuB5gl2! zOUO)^Nm5J(F?uT+qkjPg0^M|Zj#ks|cA#o9deKBt+C0kh??!*Ii|A)781XR}?55Y( zN|&dRK7R+^k%6&#ia}>4&X`29WjdMhGfA~%lXS*kfT`%;4HL{&+Zx^X00000NkvXX Hu0mjfOvk%j delta 2276 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 diff --git a/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x-1.png b/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x-1.png index 680ebe06bf95967d1430693b306bd5b6a4009a61..aa039bb59ce2457285e6ee031d23b5796ef9ff16 100644 GIT binary patch literal 6745 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 delta 5231 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 diff --git a/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x.png b/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x.png index 680ebe06bf95967d1430693b306bd5b6a4009a61..aa039bb59ce2457285e6ee031d23b5796ef9ff16 100644 GIT binary patch literal 6745 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 delta 5231 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 diff --git a/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon-Spotlight-40@3x.png b/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon-Spotlight-40@3x.png index 635a47187aac9b4a1a18568cd7e534c6e54d398d..a702b40c55eea6cc9b098afffe7b805330be28e2 100644 GIT binary patch literal 13588 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 YN-Zszhe<AA%n3?XQc0px%sBA>0LXT=%m4rY literal 10478 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 diff --git a/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon.png b/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon.png index 3ce58cfebe877876235e7431bfe82d49db187c60..d6501a4cce2c63db3323480c6e68503ce596948a 100644 GIT binary patch delta 5312 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 ShB<El0000<MNUMnLSTX$E@T}5 delta 4168 zcmV-O5V!BcDbyg4Gk*{ZNkl<ZXo2OMX^>pib;o~i?R}e>o_&!<AdnD}&;mkeMr>NZ zm{=eKa$-}7v7JhsRBXp_@+D4{Q*p&k#g&A_l?s$&I}TzeU_e3wSu55qA!)SFXr^cH zS-N|AdHc(Uk%Y#YRWsnK<o~VT>v!(`y}s|9^UggjxUTE+e}7!!Z+ilthU8CcAlG%V zUF+&+Nsti);Zqs=6M-~slZ??%O7COHOp`N*(5(U%2CnNOARvn>9?6Ga2@+DGL_H-$ zJ;lhPGUM}^F-Y678Pt<pN}r)Ucafyl#h}(p#z>*rIV3?wl~qI}9M{2cbZpzgEBgtl zQDUArabFcxfq&V|4$q_5SBfY|Gcq?}x{k-irE92_qkVh0m^n#bp$o&&Df3rT6{x4w zUqw_cMwPrsqKt@$gM;l@7`8^*7@)V%PDi$do<cjapiu0sU{3fpmc$#V49!AdddqrR zkVAT!9UZT8yni1<MvADnggZ)BF*mx9h^GXf<VTgfD1V{?qfXStax8SafM(}O8~vP5 zo#06CZU*%vAvMB+*j?OT^B56N(WedRay<DVZ?^oDe!Yt#Zz*eQp5(UT<@lrkk|5z` zy0E%VU?<Pxq}oC8;92+>a^+&|!Q&X0{u`_uVxR^wd@E9HF@nDa+qKc`JWT_KcrWo1 zeT8m{Jb!T>ne{Yx#8=&rvzij5i%Z_jvaR)H_IAI6BRH(7-pB*hkE4hRu9n719Ktxa z9edysIQEF^l{t<0R(=ir+_RWn+kk6^79_;rY?R9N$R#Tg)F_r~v!mk;wzj<pF5F$d zj&-$95>UfaTEdfdJdW#-EOfH9bu%Xi4p1GM!+(bQXQ&O%!O12u+74oz-HMax8pntY zjs>nY5)i<(afU9SpM4gy?NyYjhmqo|SX2Et^J2?*qxm@w^lT@i53sIo6Xn4g#7Tzv zNkKZULr1oS_YyC1F@2JyrK?$6`vg(ESZxO}n%=_dJqt6GJUN9f^b5};CikM&JVsS) zF@L{z>o?h+c!eXqyD={rtgqcfRj3|m5*~QMTjAo8EOhc-;ze3AO{}bVi1l@wh&l?! zskbQX`B$u-GcyKwt(^23^wU4WY<-!C3+rm0qM`CLB(fLS()I$q`F7mjToI#aLdd+C zWozqZE~ZbiqI@llm5&fni?F&+VVv25Yk%fv1ZXU|b^){FZS28ggw!ajDj(*aiifx~ zbe65HFOW6T6WW*n(q&ug%bXlIz@n0sG*mu9Sd9%|=!+pp>P&D<EKxyFheJq6iE>ZH zLo6+A<aFu?Tiae_BHuYK<niQ(?CpMss^Dza);>YV0PVyF7?+MA#%l2_{}O`y$$x?h zqJn46mk}d#vGh|I`Ck!`Y#yxHNNw<D_V;Y#aL=xBZHx&yq^Eha<v(!*hYj`55OKWZ ze*Frmw|>arOW#F1vk$rEPJE4j`iX%GqJrnvZy}Yh#?p_H>-#?WfqzCHdYzCgvtiCN z2nf90`ZH2m|I{E|Ty}K4PQTvGnt$qz)CTG?T8@(6{~E5A#mNqke)9+D=l2hTuKGHH z;+<hY51w1Ufn2s4TR%Z=;2&}9K3pe{p8X}Zc8p4YE$izxF{mebKk@3APH0rfu525} z`}a}gE#rae$FWmA<o3OYqvt-p5vES+)$gI5+KE)L2=9t7Bl@F^p1w^HP=AS{-u#D1 z@fDcb0kZvnhwBtR9^28-hF-<7yIEcND5ZfaP7ds+J<~inNZYYFlHA3Rkz#G_6DWd= zc4jw5;^cJ~yQWU+jqjs1?Lw+pjA!u^h{2L+fC`A7IO^=*MJ~M?Q$Iki{~tyGUXi7r z!^rPO5(L)OK1I&TaHMY+wtr(?_ucCt2lXTu)2E1eOIT2JCr&O!{^0+N83$dXKxW&& zqn+A?RB;FD?Z1N<ir)aJfaonnsogjXXdI+4_&lzY9rFq!`!0?%z`WQJioF%IWSZ#H zx+jKg$(*KN>tb=qD!h^(?d)Ex{=~S`bFu?ucmEgK={?AmOHda)ihmd^o)V(yDMqPz z47qG2rg4Zu`UM<&Y-a*sTRoWhJ*c9WrKOD|3thCNPmd32+9n;@W(-GXZge4%AW=B{ z)+DCrVyAn^?%j-bdM|R-GCT_(NAQLx1t=(Cl)5L8%T{3;M<`@o!LhozF25Z`dUh+4 zC^9Fq02hb$Y%`{<kADrBG5SerU6lE&iFit|`x2Pl7bZ1PTo*glMRxZu(9V2_RJ|PU z@~0;ZFM_Dxx#`Qu<&Bu;Q3{#OI9BJR00C^X4ac}dL@lBsP)AbhWKbWu0!BcljeZ8T zUaEri_#{6@%Mo1r`UiPj&~z_D@Bat-x&6qscj9XpJC0tBgMVeKv5b!>q<(^9^-LOY zSPqtc46p2`Dp*fSOOn$2#)ixoDKbWiGG8^S<Q>(cPAnHEH%R)eAEKW>fLwRisGx$V z;+gkN<nnv5^b_O;euQHWOc8KcmfnO%@>1rjCS#_^nyC@zM?mJxAv8Nj#8ZqSDp<)& zQy%b&M#j;Fcz^HyDuQn~jtXiF&)h#oDp`S9I6$ud`=f@5$;vhpNP<jQjbS<lIdf>l z`K#}fuIr*(h2g52=)F7{{|yfemqB0qTOyzRbG-8#k*k-2;zOx>3M3g*J4k-upQZ%} zAc#Hy6w!l6_MllgEZahshViaK+OCC#fhw!W;_%^M<9`<^L`ttKV@y?M*Lgg*tVHw; zds{&X<GML);~a`_`Lt|<gz8@nfGo-=q6fn<aIm?8_i<%F7|vNmq^tE4&rNrt)-3|d zyzx1>fFK}vN3IG%2;d2Si5qzaM@mAxT#yzJ5fO25M&z*{L%JX!;J6=u!8mdP?Y*72 z<`g{aD1Q=T5rSXZh!754J!V)AM=uUi(5Gn|fjN~Cs!D>mI5;>6f;ghkbrn()WMo0b zaCEH8dltE$zKnkK<g`i~f~pYyv#;RD3QpcY@vCGF3t1G21-&%2c4FDiG%z8R*QqKA zVmTJ3qoXifslTGD-c=9;JdzLF9<FSIi<8Yw4}VZmh<xYks1G#Ie!QKNuOCL&EPnj! z1Y6JbQBxY?-i6i3()2dhbaU8en2wHaX?PX?Ri^{L5kmY*5U=bfZ46*J7E)dH4G%0R z3X#A16TE90=sDZNf#-ITAIRdmF3Ft1-)uk6u1kZ=DhqS(qUnJ~10HPGB4Z4qh$;bP zWPdt2!g5H75>lh|=G)Qj0_tsZZ)i|45+eM~ucEHHlg?vp?0t3{re<6{?*awO<~#46 zVcUg1DvE=wT2P5ky|MkLvZx>3)<_mQ2q`f_N@V1GuKf`8lo0d8>BzO9*?H6@3qhK~ z&XOP?#fu64!6uYdD`-F7ei?9d@2pu4e}D1r8MdD5qr51{vbkjheN)@I69lL%4xm|i z+Oy5XJaM9)lJOvmiTkSP$tOq~{YbN_Q0nU@4_H=0VAJQ28}BCZQ3r>AzGqCpYeD~h z=SAK<*GE}#fJOCjLjK9uj3NOKMPV-)bC9llD{+6t_>i)wP!*Vsgv|NW32fKK_kYNP zlNwBl7ZZ5mQRLP4kT}uBiPsKMNKdXNJ6JIJ@%~n}obRWsILN};C4?sVi{4Tl!@;IG z-2^UF1?o{H&)ARvvm^6}`ztxpyBpmu;BB}IxvG5Jfy7vZz!x?k-@A&$scxFyI!dl@ zXwq@s1-gfHo<Ede>xF*Gi-Rnh6Mx6=8UGm#`c&%6!x*;4;ohB;cq^z6&%1tpzj>h8 zTS|RsK7)Farh!9<MG<_Dt{rnA!J`s-<_jqIH_+bH&8at!knPP(SnwSUv?HzY{J{j< zF7{Jd5@Pu+<tXylUiX&jD1NWP+0-$Tg$`zg=TYLXm>5zNB$k#o5>g|)mw$K(OK|Wu zu0WZ8y{8ovg~+%62=##mI!|}=(JKeZCWodBcr9pWM&sEJTlt`Qfa-XN#@nk#4KKxE zFZC4>TpZqOdlA1JVoAIKNx1&kAN4j>1ZS}zwt{57lN}vzAXStSc=AyM-^aDpD{;`X zrh)D=JskYWZt?@!X>a_vKz}l4@VyT%j2TB|No3LNIANd4p3b-F%C#~-wv5{F&7;~J z6;eRp{+bQMym7X+ZKl1@in{c6{GVHo;P)X$!-T)}HPptt==vzZzJJ?}k=I8vb;HV= zHh;P04DVkUpsF}X!-7hD9vMXzxwR%nWl4Zut(|vTe?dekVomMm$A8?I9dp4)JViWG z_cXZhM)PxId<Oo{KSKB$Um^O}-#}e`H|@s~?EROq<KT3qSq|TR_cUA1_fb(2;{HW7 ztejuT?XycT$?!(=b6AeaXX?I4%o`um&bYbMlF|lNmaii*bb;-OSI9>seCzK+UA~xs zjx<MpzV{OYyduqV_<zC9W=`}BQCS>dZdDYdJny%^PIJ16yUHG9S^0hA+8EbI3xdGf z+9yft103nyO;8SVPvygelqmWB>?aO*MS07nGc)`+<jf2oc5mfS&j;KbS;YF<O^Cwy zdGCZ-aX<~Tu5J^vLbtHDYYTfj-(|>1Q97@Zo9>^F?3wuvs()+cl|?q*R?gkEQL<*5 zecfBw)$umfftz@!?hAxG(Ftu#m=OyIlm)6;U$==ZtuL^<^OxkT3=h_9Wd3ItQ#8AT zGw*yve{=7QKwYbOr9pmwX*KuMMN#A&+Y_&GuxAI=!8trsyNSwR-K4reCYAO}f<#rY zp3lyHnk}s_aDSlZeY*2)Y^Z;RnmgxEG%HTqfo3l5I88R0nKoQS$jinBWjuUKoSLYQ zKCPXX&OJv<x{0~b#jL*!IN7$eDfjW@j0{`aHnYEH8v+9B>o&2v@=*j=L`&sqJ8+Ta zU!5V{nZk8OzVXjmc{9tuav$H_ago<gb&tsUL_uIy%zww@3(8nOH%?j5gCIEU>3o}a zT7QA%nA}zNAnR*45%NT*)W>r}9a*mHa=3RFZ(sTugL;zEKo#q1pJHBY399HtbS2V> z0lH7M(|5jyOvfOyPhr7^WmMf!$DY<fp550<Mz^Rh^0Bxw%!-;Ax5oV-I2g9Z+0-$% zwr!?6*MCMtDdIDAUu0SNeG@vF8H2o{l-AGo#H*Yf*iYWdQ0%Q>X=x)jMHUcNi}1>R zJd$_RRO^at*Fv{7G%HWW9Hcqj#NpnZBnut*<q-2@%UDzU`EldmM4FK<$wa1^qkX$* z$uyBHbm8Jq5vZdoP*0h^ny?x}5k1JFjBvSRcz>nnlraYBEp*V4ZKf;V3NDm*E0`6Y z$C7vhwc(q8yIqpk%62UJv~F6`r)keN)2DSZs3*x7DNM(}BYRLp&(&7YD@7+oR0%1u z;eJ<t1yzB1>My@djJE=&q8Wp{R;H~psP&OD`WP}(<jo-pRvy#QaRnE_6_5oLzY@Tw zgh2=^Q6g$FF>n037v7oBCjvQ|EZf4t#$~uYTSOXBHvA;@sX_iW_5b286aNb-ZW#T} SetOIR0000<MNUMnLSTZ(BqoIb diff --git a/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon@2x.png b/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon@2x.png index 21c396fa5b47fad71849dfd5f89f0eebb50d412a..7543d4cdf491b8c603be44a254f8b22dc3f8e144 100644 GIT binary patch literal 12343 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 Kkb}rrMf?vvNi}Ey literal 9928 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 GLSTYJ3XabJ diff --git a/examples/DemoRunner/Builds/iOS/Icon.icns b/examples/DemoRunner/Builds/iOS/Icon.icns index 6ab6915802b8cc41702a02e8527aec517d379e77..52f40fef1039ef1c4890e481085bd003b0759197 100644 GIT binary patch literal 86596 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 literal 89670 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 S)d9x$gS6E2RqK#;(f<d)_aL<Z diff --git a/examples/DemoRunner/Builds/iOS/Info-App.plist b/examples/DemoRunner/Builds/iOS/Info-App.plist index f0906a66..5391e621 100644 --- a/examples/DemoRunner/Builds/iOS/Info-App.plist +++ b/examples/DemoRunner/Builds/iOS/Info-App.plist @@ -20,7 +20,7 @@ <key>CFBundleExecutable</key> <string>${EXECUTABLE_NAME}</string> <key>CFBundleIdentifier</key> - <string>com.juce.demorunner</string> + <string>com.rmsl.juce.demorunner</string> <key>CFBundleName</key> <string>DemoRunner</string> <key>CFBundleDisplayName</key> @@ -30,11 +30,11 @@ <key>CFBundleSignature</key> <string>????</string> <key>CFBundleShortVersionString</key> - <string>5.4.7</string> + <string>6.0.5</string> <key>CFBundleVersion</key> - <string>5.4.7</string> + <string>6.0.5</string> <key>NSHumanReadableCopyright</key> - <string>Copyright (c) 2018 - ROLI Ltd.</string> + <string>Copyright (c) 2020 - Raw Material Software Limited</string> <key>NSHighResolutionCapable</key> <true/> <key>UIFileSharingEnabled</key> diff --git a/examples/DemoRunner/CMakeLists.txt b/examples/DemoRunner/CMakeLists.txt new file mode 100644 index 00000000..0261c51c --- /dev/null +++ b/examples/DemoRunner/CMakeLists.txt @@ -0,0 +1,71 @@ +# ============================================================================== +# +# This file is part of the JUCE library. +# Copyright (c) 2020 - Raw Material Software Limited +# +# JUCE is an open source library subject to commercial or open-source +# licensing. +# +# By using JUCE, you agree to the terms of both the JUCE 6 End-User License +# Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). +# +# End User License Agreement: www.juce.com/juce-6-licence +# Privacy Policy: www.juce.com/juce-privacy-policy +# +# Or: You may also use this code under the terms of the GPL v3 (see +# www.gnu.org/licenses). +# +# JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER +# EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE +# DISCLAIMED. +# +# ============================================================================== + +juce_add_gui_app(DemoRunner + BUNDLE_ID com.juce.demorunner + ICON_BIG ${CMAKE_CURRENT_SOURCE_DIR}/Source/JUCEAppIcon.png + NEEDS_CURL TRUE + NEEDS_WEB_BROWSER TRUE + MICROPHONE_PERMISSION_ENABLED TRUE + CAMERA_PERMISSION_ENABLED TRUE + BLUETOOTH_PERMISSION_ENABLED TRUE + FILE_SHARING_ENABLED TRUE + DOCUMENT_BROWSER_ENABLED TRUE) + +juce_generate_juce_header(DemoRunner) + +target_sources(DemoRunner PRIVATE + Source/Demos/DemoPIPs1.cpp + Source/Demos/DemoPIPs2.cpp + Source/Demos/JUCEDemos.cpp + Source/Main.cpp + Source/UI/DemoContentComponent.cpp + Source/UI/MainComponent.cpp) + +target_compile_definitions(DemoRunner PRIVATE + PIP_JUCE_EXAMPLES_DIRECTORY_STRING="${JUCE_SOURCE_DIR}/examples" + JUCE_ALLOW_STATIC_NULL_VARIABLES=0 + JUCE_DEMO_RUNNER=1 + JUCE_JACK=1 + JUCE_STRICT_REFCOUNTEDPOINTER=1 + JUCE_UNIT_TESTS=1 + JUCE_USE_CAMERA=1 + JUCE_USE_CURL=1 + JUCE_USE_MP3AUDIOFORMAT=1 + JUCE_WEB_BROWSER=1) + +target_link_libraries(DemoRunner PRIVATE + juce::juce_analytics + juce::juce_audio_utils + juce::juce_blocks_basics + juce::juce_box2d + juce::juce_dsp + juce::juce_opengl + juce::juce_osc + juce::juce_product_unlocking + juce::juce_video + juce::juce_recommended_config_flags + juce::juce_recommended_lto_flags + juce::juce_recommended_warning_flags) + +juce_add_bundle_resources_directory(DemoRunner ../Assets) diff --git a/examples/DemoRunner/DemoRunner.jucer b/examples/DemoRunner/DemoRunner.jucer index 64eb8169..2f2a0262 100644 --- a/examples/DemoRunner/DemoRunner.jucer +++ b/examples/DemoRunner/DemoRunner.jucer @@ -1,9 +1,11 @@ <?xml version="1.0" encoding="UTF-8"?> -<JUCERPROJECT name="DemoRunner" projectType="guiapp" jucerVersion="5.4.7" defines="JUCE_DEMO_RUNNER=1&#10;JUCE_UNIT_TESTS=1" - bundleIdentifier="com.juce.demorunner" version="5.4.7" companyName="ROLI Ltd." - companyCopyright="Copyright (c) 2018 - ROLI Ltd." companyWebsite="https://www.juce.com/" - companyEmail="info@juce.com" id="yj7xMM" reportAppUsage="0"> +<JUCERPROJECT name="DemoRunner" projectType="guiapp" defines="JUCE_DEMO_RUNNER=1&#10;JUCE_UNIT_TESTS=1" + bundleIdentifier="com.rmsl.juce.demorunner" version="6.0.5" companyName="Raw Material Software Limited" + companyCopyright="Copyright (c) 2020 - Raw Material Software Limited" + companyWebsite="https://www.juce.com/" companyEmail="info@juce.com" + id="yj7xMM" reportAppUsage="0" useAppConfig="0" addUsingNamespaceToJuceHeader="1" + jucerFormatVersion="1"> <MAINGROUP id="G8kbr7" name="DemoRunner"> <GROUP id="{20E3F84A-29E9-D5FF-4559-1A9E4A70CD60}" name="Source"> <GROUP id="{272A692A-6AFE-68BD-C8E8-63B3D62245B1}" name="Demos"> @@ -92,8 +94,7 @@ androidEnableContentSharing="1" androidExtraAssetsFolder="../Assets" smallIcon="YyqWd2" bigIcon="YyqWd2" cameraPermissionNeeded="1"> <CONFIGURATIONS> - <CONFIGURATION isDebug="1" name="Debug" androidArchitectures="armeabi-v7a x86" - recommendedWarnings="LLVM"/> + <CONFIGURATION isDebug="1" name="Debug" recommendedWarnings="LLVM"/> <CONFIGURATION isDebug="0" name="Release" recommendedWarnings="LLVM"/> </CONFIGURATIONS> <MODULEPATHS> diff --git a/examples/DemoRunner/JuceLibraryCode/AppConfig.h b/examples/DemoRunner/JuceLibraryCode/AppConfig.h deleted file mode 100644 index f33cd6f4..00000000 --- a/examples/DemoRunner/JuceLibraryCode/AppConfig.h +++ /dev/null @@ -1,324 +0,0 @@ -/* - - IMPORTANT! This file is auto-generated each time you save your - project - if you alter its contents, your changes may be overwritten! - - There's a section below where you can add your own custom code safely, and the - Projucer will preserve the contents of that block, but the best way to change - any of these definitions is by using the Projucer's project settings. - - Any commented-out settings will assume their default values. - -*/ - -#pragma once - -//============================================================================== -// [BEGIN_USER_CODE_SECTION] - -// (You can add your own code in this section, and the Projucer will not overwrite it) - -// [END_USER_CODE_SECTION] - -/* - ============================================================================== - - In accordance with the terms of the JUCE 5 End-Use License Agreement, the - JUCE Code in SECTION A cannot be removed, changed or otherwise rendered - ineffective unless you have a JUCE Indie or Pro license, or are using JUCE - under the GPL v3 license. - - End User License Agreement: www.juce.com/juce-5-licence - - ============================================================================== -*/ - -// BEGIN SECTION A - -#ifndef JUCE_DISPLAY_SPLASH_SCREEN - #define JUCE_DISPLAY_SPLASH_SCREEN 0 -#endif - -#ifndef JUCE_REPORT_APP_USAGE - #define JUCE_REPORT_APP_USAGE 0 -#endif - -// END SECTION A - -#define JUCE_USE_DARK_SPLASH_SCREEN 1 - -#define JUCE_PROJUCER_VERSION 0x50407 - -//============================================================================== -#define JUCE_MODULE_AVAILABLE_juce_analytics 1 -#define JUCE_MODULE_AVAILABLE_juce_audio_basics 1 -#define JUCE_MODULE_AVAILABLE_juce_audio_devices 1 -#define JUCE_MODULE_AVAILABLE_juce_audio_formats 1 -#define JUCE_MODULE_AVAILABLE_juce_audio_processors 1 -#define JUCE_MODULE_AVAILABLE_juce_audio_utils 1 -#define JUCE_MODULE_AVAILABLE_juce_blocks_basics 1 -#define JUCE_MODULE_AVAILABLE_juce_box2d 1 -#define JUCE_MODULE_AVAILABLE_juce_core 1 -#define JUCE_MODULE_AVAILABLE_juce_cryptography 1 -#define JUCE_MODULE_AVAILABLE_juce_data_structures 1 -#define JUCE_MODULE_AVAILABLE_juce_dsp 1 -#define JUCE_MODULE_AVAILABLE_juce_events 1 -#define JUCE_MODULE_AVAILABLE_juce_graphics 1 -#define JUCE_MODULE_AVAILABLE_juce_gui_basics 1 -#define JUCE_MODULE_AVAILABLE_juce_gui_extra 1 -#define JUCE_MODULE_AVAILABLE_juce_opengl 1 -#define JUCE_MODULE_AVAILABLE_juce_osc 1 -#define JUCE_MODULE_AVAILABLE_juce_product_unlocking 1 -#define JUCE_MODULE_AVAILABLE_juce_video 1 - -#define JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED 1 - -//============================================================================== -// juce_audio_devices flags: - -#ifndef JUCE_USE_WINRT_MIDI - //#define JUCE_USE_WINRT_MIDI 0 -#endif - -#ifndef JUCE_ASIO - //#define JUCE_ASIO 0 -#endif - -#ifndef JUCE_WASAPI - //#define JUCE_WASAPI 1 -#endif - -#ifndef JUCE_WASAPI_EXCLUSIVE - //#define JUCE_WASAPI_EXCLUSIVE 0 -#endif - -#ifndef JUCE_DIRECTSOUND - //#define JUCE_DIRECTSOUND 1 -#endif - -#ifndef JUCE_ALSA - //#define JUCE_ALSA 1 -#endif - -#ifndef JUCE_JACK - //#define JUCE_JACK 0 -#endif - -#ifndef JUCE_BELA - //#define JUCE_BELA 0 -#endif - -#ifndef JUCE_USE_ANDROID_OBOE - //#define JUCE_USE_ANDROID_OBOE 0 -#endif - -#ifndef JUCE_USE_ANDROID_OPENSLES - //#define JUCE_USE_ANDROID_OPENSLES 0 -#endif - -#ifndef JUCE_DISABLE_AUDIO_MIXING_WITH_OTHER_APPS - //#define JUCE_DISABLE_AUDIO_MIXING_WITH_OTHER_APPS 0 -#endif - -//============================================================================== -// juce_audio_formats flags: - -#ifndef JUCE_USE_FLAC - //#define JUCE_USE_FLAC 1 -#endif - -#ifndef JUCE_USE_OGGVORBIS - //#define JUCE_USE_OGGVORBIS 1 -#endif - -#ifndef JUCE_USE_MP3AUDIOFORMAT - #define JUCE_USE_MP3AUDIOFORMAT 1 -#endif - -#ifndef JUCE_USE_LAME_AUDIO_FORMAT - //#define JUCE_USE_LAME_AUDIO_FORMAT 0 -#endif - -#ifndef JUCE_USE_WINDOWS_MEDIA_FORMAT - //#define JUCE_USE_WINDOWS_MEDIA_FORMAT 1 -#endif - -//============================================================================== -// juce_audio_processors flags: - -#ifndef JUCE_PLUGINHOST_VST - //#define JUCE_PLUGINHOST_VST 0 -#endif - -#ifndef JUCE_PLUGINHOST_VST3 - //#define JUCE_PLUGINHOST_VST3 0 -#endif - -#ifndef JUCE_PLUGINHOST_AU - //#define JUCE_PLUGINHOST_AU 0 -#endif - -#ifndef JUCE_PLUGINHOST_LADSPA - //#define JUCE_PLUGINHOST_LADSPA 0 -#endif - -//============================================================================== -// juce_audio_utils flags: - -#ifndef JUCE_USE_CDREADER - //#define JUCE_USE_CDREADER 0 -#endif - -#ifndef JUCE_USE_CDBURNER - //#define JUCE_USE_CDBURNER 0 -#endif - -//============================================================================== -// juce_core flags: - -#ifndef JUCE_FORCE_DEBUG - //#define JUCE_FORCE_DEBUG 0 -#endif - -#ifndef JUCE_LOG_ASSERTIONS - //#define JUCE_LOG_ASSERTIONS 0 -#endif - -#ifndef JUCE_CHECK_MEMORY_LEAKS - //#define JUCE_CHECK_MEMORY_LEAKS 1 -#endif - -#ifndef JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES - //#define JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES 0 -#endif - -#ifndef JUCE_INCLUDE_ZLIB_CODE - //#define JUCE_INCLUDE_ZLIB_CODE 1 -#endif - -#ifndef JUCE_USE_CURL - //#define JUCE_USE_CURL 1 -#endif - -#ifndef JUCE_LOAD_CURL_SYMBOLS_LAZILY - //#define JUCE_LOAD_CURL_SYMBOLS_LAZILY 0 -#endif - -#ifndef JUCE_CATCH_UNHANDLED_EXCEPTIONS - //#define JUCE_CATCH_UNHANDLED_EXCEPTIONS 0 -#endif - -#ifndef JUCE_ALLOW_STATIC_NULL_VARIABLES - #define JUCE_ALLOW_STATIC_NULL_VARIABLES 0 -#endif - -#ifndef JUCE_STRICT_REFCOUNTEDPOINTER - #define JUCE_STRICT_REFCOUNTEDPOINTER 1 -#endif - -//============================================================================== -// juce_dsp flags: - -#ifndef JUCE_ASSERTION_FIRFILTER - //#define JUCE_ASSERTION_FIRFILTER 1 -#endif - -#ifndef JUCE_DSP_USE_INTEL_MKL - //#define JUCE_DSP_USE_INTEL_MKL 0 -#endif - -#ifndef JUCE_DSP_USE_SHARED_FFTW - //#define JUCE_DSP_USE_SHARED_FFTW 0 -#endif - -#ifndef JUCE_DSP_USE_STATIC_FFTW - //#define JUCE_DSP_USE_STATIC_FFTW 0 -#endif - -#ifndef JUCE_DSP_ENABLE_SNAP_TO_ZERO - //#define JUCE_DSP_ENABLE_SNAP_TO_ZERO 1 -#endif - -//============================================================================== -// juce_events flags: - -#ifndef JUCE_EXECUTE_APP_SUSPEND_ON_BACKGROUND_TASK - //#define JUCE_EXECUTE_APP_SUSPEND_ON_BACKGROUND_TASK 0 -#endif - -//============================================================================== -// juce_graphics flags: - -#ifndef JUCE_USE_COREIMAGE_LOADER - //#define JUCE_USE_COREIMAGE_LOADER 1 -#endif - -#ifndef JUCE_USE_DIRECTWRITE - //#define JUCE_USE_DIRECTWRITE 1 -#endif - -#ifndef JUCE_DISABLE_COREGRAPHICS_FONT_SMOOTHING - //#define JUCE_DISABLE_COREGRAPHICS_FONT_SMOOTHING 0 -#endif - -//============================================================================== -// juce_gui_basics flags: - -#ifndef JUCE_ENABLE_REPAINT_DEBUGGING - //#define JUCE_ENABLE_REPAINT_DEBUGGING 0 -#endif - -#ifndef JUCE_USE_XRANDR - //#define JUCE_USE_XRANDR 1 -#endif - -#ifndef JUCE_USE_XINERAMA - //#define JUCE_USE_XINERAMA 1 -#endif - -#ifndef JUCE_USE_XSHM - //#define JUCE_USE_XSHM 1 -#endif - -#ifndef JUCE_USE_XRENDER - //#define JUCE_USE_XRENDER 0 -#endif - -#ifndef JUCE_USE_XCURSOR - //#define JUCE_USE_XCURSOR 1 -#endif - -#ifndef JUCE_WIN_PER_MONITOR_DPI_AWARE - //#define JUCE_WIN_PER_MONITOR_DPI_AWARE 1 -#endif - -//============================================================================== -// juce_gui_extra flags: - -#ifndef JUCE_WEB_BROWSER - //#define JUCE_WEB_BROWSER 1 -#endif - -#ifndef JUCE_ENABLE_LIVE_CONSTANT_EDITOR - //#define JUCE_ENABLE_LIVE_CONSTANT_EDITOR 0 -#endif - -//============================================================================== -// juce_video flags: - -#ifndef JUCE_USE_CAMERA - #define JUCE_USE_CAMERA 1 -#endif - -#ifndef JUCE_SYNC_VIDEO_VOLUME_WITH_OS_MEDIA_VOLUME - //#define JUCE_SYNC_VIDEO_VOLUME_WITH_OS_MEDIA_VOLUME 1 -#endif - -//============================================================================== -#ifndef JUCE_STANDALONE_APPLICATION - #if defined(JucePlugin_Name) && defined(JucePlugin_Build_Standalone) - #define JUCE_STANDALONE_APPLICATION JucePlugin_Build_Standalone - #else - #define JUCE_STANDALONE_APPLICATION 1 - #endif -#endif diff --git a/examples/DemoRunner/JuceLibraryCode/JuceHeader.h b/examples/DemoRunner/JuceLibraryCode/JuceHeader.h index 4878fe63..8fd3ed49 100644 --- a/examples/DemoRunner/JuceLibraryCode/JuceHeader.h +++ b/examples/DemoRunner/JuceLibraryCode/JuceHeader.h @@ -12,7 +12,6 @@ #pragma once -#include "AppConfig.h" #include <juce_analytics/juce_analytics.h> #include <juce_audio_basics/juce_audio_basics.h> @@ -55,8 +54,8 @@ namespace ProjectInfo { const char* const projectName = "DemoRunner"; - const char* const companyName = "ROLI Ltd."; - const char* const versionString = "5.4.7"; - const int versionNumber = 0x50407; + const char* const companyName = "Raw Material Software Limited"; + const char* const versionString = "6.0.5"; + const int versionNumber = 0x60005; } #endif diff --git a/examples/DemoRunner/JuceLibraryCode/include_juce_analytics.cpp b/examples/DemoRunner/JuceLibraryCode/include_juce_analytics.cpp index 3dfd4d21..cda0f939 100644 --- a/examples/DemoRunner/JuceLibraryCode/include_juce_analytics.cpp +++ b/examples/DemoRunner/JuceLibraryCode/include_juce_analytics.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_analytics/juce_analytics.cpp> diff --git a/examples/DemoRunner/JuceLibraryCode/include_juce_audio_basics.cpp b/examples/DemoRunner/JuceLibraryCode/include_juce_audio_basics.cpp index 41869487..e5c3ae92 100644 --- a/examples/DemoRunner/JuceLibraryCode/include_juce_audio_basics.cpp +++ b/examples/DemoRunner/JuceLibraryCode/include_juce_audio_basics.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_basics/juce_audio_basics.cpp> diff --git a/examples/DemoRunner/JuceLibraryCode/include_juce_audio_basics.mm b/examples/DemoRunner/JuceLibraryCode/include_juce_audio_basics.mm index e0e6c577..c7f36c64 100644 --- a/examples/DemoRunner/JuceLibraryCode/include_juce_audio_basics.mm +++ b/examples/DemoRunner/JuceLibraryCode/include_juce_audio_basics.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_basics/juce_audio_basics.mm> diff --git a/examples/DemoRunner/JuceLibraryCode/include_juce_audio_devices.cpp b/examples/DemoRunner/JuceLibraryCode/include_juce_audio_devices.cpp index fb5c2219..29b774fd 100644 --- a/examples/DemoRunner/JuceLibraryCode/include_juce_audio_devices.cpp +++ b/examples/DemoRunner/JuceLibraryCode/include_juce_audio_devices.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_devices/juce_audio_devices.cpp> diff --git a/examples/DemoRunner/JuceLibraryCode/include_juce_audio_devices.mm b/examples/DemoRunner/JuceLibraryCode/include_juce_audio_devices.mm index e58b67ea..287da26e 100644 --- a/examples/DemoRunner/JuceLibraryCode/include_juce_audio_devices.mm +++ b/examples/DemoRunner/JuceLibraryCode/include_juce_audio_devices.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_devices/juce_audio_devices.mm> diff --git a/examples/DemoRunner/JuceLibraryCode/include_juce_audio_formats.cpp b/examples/DemoRunner/JuceLibraryCode/include_juce_audio_formats.cpp index a3c61170..8dac3325 100644 --- a/examples/DemoRunner/JuceLibraryCode/include_juce_audio_formats.cpp +++ b/examples/DemoRunner/JuceLibraryCode/include_juce_audio_formats.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_formats/juce_audio_formats.cpp> diff --git a/examples/DemoRunner/JuceLibraryCode/include_juce_audio_formats.mm b/examples/DemoRunner/JuceLibraryCode/include_juce_audio_formats.mm index f325b8fb..79e6a22f 100644 --- a/examples/DemoRunner/JuceLibraryCode/include_juce_audio_formats.mm +++ b/examples/DemoRunner/JuceLibraryCode/include_juce_audio_formats.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_formats/juce_audio_formats.mm> diff --git a/examples/DemoRunner/JuceLibraryCode/include_juce_audio_processors.cpp b/examples/DemoRunner/JuceLibraryCode/include_juce_audio_processors.cpp index bfe172ed..217d330a 100644 --- a/examples/DemoRunner/JuceLibraryCode/include_juce_audio_processors.cpp +++ b/examples/DemoRunner/JuceLibraryCode/include_juce_audio_processors.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_processors/juce_audio_processors.cpp> diff --git a/examples/DemoRunner/JuceLibraryCode/include_juce_audio_processors.mm b/examples/DemoRunner/JuceLibraryCode/include_juce_audio_processors.mm index b80ae901..1f7cc419 100644 --- a/examples/DemoRunner/JuceLibraryCode/include_juce_audio_processors.mm +++ b/examples/DemoRunner/JuceLibraryCode/include_juce_audio_processors.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_processors/juce_audio_processors.mm> diff --git a/examples/DemoRunner/JuceLibraryCode/include_juce_audio_utils.cpp b/examples/DemoRunner/JuceLibraryCode/include_juce_audio_utils.cpp index 97bd2c56..046bf31d 100644 --- a/examples/DemoRunner/JuceLibraryCode/include_juce_audio_utils.cpp +++ b/examples/DemoRunner/JuceLibraryCode/include_juce_audio_utils.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_utils/juce_audio_utils.cpp> diff --git a/examples/DemoRunner/JuceLibraryCode/include_juce_audio_utils.mm b/examples/DemoRunner/JuceLibraryCode/include_juce_audio_utils.mm index 8eae7c6e..a3f746dc 100644 --- a/examples/DemoRunner/JuceLibraryCode/include_juce_audio_utils.mm +++ b/examples/DemoRunner/JuceLibraryCode/include_juce_audio_utils.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_utils/juce_audio_utils.mm> diff --git a/examples/DemoRunner/JuceLibraryCode/include_juce_blocks_basics.cpp b/examples/DemoRunner/JuceLibraryCode/include_juce_blocks_basics.cpp index 6ab147fb..fb50ac3c 100644 --- a/examples/DemoRunner/JuceLibraryCode/include_juce_blocks_basics.cpp +++ b/examples/DemoRunner/JuceLibraryCode/include_juce_blocks_basics.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_blocks_basics/juce_blocks_basics.cpp> diff --git a/examples/DemoRunner/JuceLibraryCode/include_juce_box2d.cpp b/examples/DemoRunner/JuceLibraryCode/include_juce_box2d.cpp index 2f1e1f81..d8ddd0f1 100644 --- a/examples/DemoRunner/JuceLibraryCode/include_juce_box2d.cpp +++ b/examples/DemoRunner/JuceLibraryCode/include_juce_box2d.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_box2d/juce_box2d.cpp> diff --git a/examples/DemoRunner/JuceLibraryCode/include_juce_core.cpp b/examples/DemoRunner/JuceLibraryCode/include_juce_core.cpp index d0ce1636..84fe988c 100644 --- a/examples/DemoRunner/JuceLibraryCode/include_juce_core.cpp +++ b/examples/DemoRunner/JuceLibraryCode/include_juce_core.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_core/juce_core.cpp> diff --git a/examples/DemoRunner/JuceLibraryCode/include_juce_core.mm b/examples/DemoRunner/JuceLibraryCode/include_juce_core.mm index 72b10bf8..9ee67bf6 100644 --- a/examples/DemoRunner/JuceLibraryCode/include_juce_core.mm +++ b/examples/DemoRunner/JuceLibraryCode/include_juce_core.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_core/juce_core.mm> diff --git a/examples/DemoRunner/JuceLibraryCode/include_juce_cryptography.cpp b/examples/DemoRunner/JuceLibraryCode/include_juce_cryptography.cpp index 10b3401d..ee7d9085 100644 --- a/examples/DemoRunner/JuceLibraryCode/include_juce_cryptography.cpp +++ b/examples/DemoRunner/JuceLibraryCode/include_juce_cryptography.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_cryptography/juce_cryptography.cpp> diff --git a/examples/DemoRunner/JuceLibraryCode/include_juce_cryptography.mm b/examples/DemoRunner/JuceLibraryCode/include_juce_cryptography.mm index 9311ea0f..03ee05f4 100644 --- a/examples/DemoRunner/JuceLibraryCode/include_juce_cryptography.mm +++ b/examples/DemoRunner/JuceLibraryCode/include_juce_cryptography.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_cryptography/juce_cryptography.mm> diff --git a/examples/DemoRunner/JuceLibraryCode/include_juce_data_structures.cpp b/examples/DemoRunner/JuceLibraryCode/include_juce_data_structures.cpp index 9315aa16..152980ae 100644 --- a/examples/DemoRunner/JuceLibraryCode/include_juce_data_structures.cpp +++ b/examples/DemoRunner/JuceLibraryCode/include_juce_data_structures.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_data_structures/juce_data_structures.cpp> diff --git a/examples/DemoRunner/JuceLibraryCode/include_juce_data_structures.mm b/examples/DemoRunner/JuceLibraryCode/include_juce_data_structures.mm index 695ec439..02b9711c 100644 --- a/examples/DemoRunner/JuceLibraryCode/include_juce_data_structures.mm +++ b/examples/DemoRunner/JuceLibraryCode/include_juce_data_structures.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_data_structures/juce_data_structures.mm> diff --git a/examples/DemoRunner/JuceLibraryCode/include_juce_dsp.cpp b/examples/DemoRunner/JuceLibraryCode/include_juce_dsp.cpp index 430d943f..0f0af659 100644 --- a/examples/DemoRunner/JuceLibraryCode/include_juce_dsp.cpp +++ b/examples/DemoRunner/JuceLibraryCode/include_juce_dsp.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_dsp/juce_dsp.cpp> diff --git a/examples/DemoRunner/JuceLibraryCode/include_juce_dsp.mm b/examples/DemoRunner/JuceLibraryCode/include_juce_dsp.mm index 1dea5d08..a5cb956c 100644 --- a/examples/DemoRunner/JuceLibraryCode/include_juce_dsp.mm +++ b/examples/DemoRunner/JuceLibraryCode/include_juce_dsp.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_dsp/juce_dsp.mm> diff --git a/examples/DemoRunner/JuceLibraryCode/include_juce_events.cpp b/examples/DemoRunner/JuceLibraryCode/include_juce_events.cpp index 1bba110a..39268e2b 100644 --- a/examples/DemoRunner/JuceLibraryCode/include_juce_events.cpp +++ b/examples/DemoRunner/JuceLibraryCode/include_juce_events.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_events/juce_events.cpp> diff --git a/examples/DemoRunner/JuceLibraryCode/include_juce_events.mm b/examples/DemoRunner/JuceLibraryCode/include_juce_events.mm index 4cc34fc4..191a9987 100644 --- a/examples/DemoRunner/JuceLibraryCode/include_juce_events.mm +++ b/examples/DemoRunner/JuceLibraryCode/include_juce_events.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_events/juce_events.mm> diff --git a/examples/DemoRunner/JuceLibraryCode/include_juce_graphics.cpp b/examples/DemoRunner/JuceLibraryCode/include_juce_graphics.cpp index 319c76de..8ccabef9 100644 --- a/examples/DemoRunner/JuceLibraryCode/include_juce_graphics.cpp +++ b/examples/DemoRunner/JuceLibraryCode/include_juce_graphics.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_graphics/juce_graphics.cpp> diff --git a/examples/DemoRunner/JuceLibraryCode/include_juce_graphics.mm b/examples/DemoRunner/JuceLibraryCode/include_juce_graphics.mm index b28e6dd0..6bb7456d 100644 --- a/examples/DemoRunner/JuceLibraryCode/include_juce_graphics.mm +++ b/examples/DemoRunner/JuceLibraryCode/include_juce_graphics.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_graphics/juce_graphics.mm> diff --git a/examples/DemoRunner/JuceLibraryCode/include_juce_gui_basics.cpp b/examples/DemoRunner/JuceLibraryCode/include_juce_gui_basics.cpp index 216c76bb..71d04b24 100644 --- a/examples/DemoRunner/JuceLibraryCode/include_juce_gui_basics.cpp +++ b/examples/DemoRunner/JuceLibraryCode/include_juce_gui_basics.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_gui_basics/juce_gui_basics.cpp> diff --git a/examples/DemoRunner/JuceLibraryCode/include_juce_gui_basics.mm b/examples/DemoRunner/JuceLibraryCode/include_juce_gui_basics.mm index 6a9726fa..e449e0b7 100644 --- a/examples/DemoRunner/JuceLibraryCode/include_juce_gui_basics.mm +++ b/examples/DemoRunner/JuceLibraryCode/include_juce_gui_basics.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_gui_basics/juce_gui_basics.mm> diff --git a/examples/DemoRunner/JuceLibraryCode/include_juce_gui_extra.cpp b/examples/DemoRunner/JuceLibraryCode/include_juce_gui_extra.cpp index 7226e198..a33ece00 100644 --- a/examples/DemoRunner/JuceLibraryCode/include_juce_gui_extra.cpp +++ b/examples/DemoRunner/JuceLibraryCode/include_juce_gui_extra.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_gui_extra/juce_gui_extra.cpp> diff --git a/examples/DemoRunner/JuceLibraryCode/include_juce_gui_extra.mm b/examples/DemoRunner/JuceLibraryCode/include_juce_gui_extra.mm index c9b6c3bf..6dacee3a 100644 --- a/examples/DemoRunner/JuceLibraryCode/include_juce_gui_extra.mm +++ b/examples/DemoRunner/JuceLibraryCode/include_juce_gui_extra.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_gui_extra/juce_gui_extra.mm> diff --git a/examples/DemoRunner/JuceLibraryCode/include_juce_opengl.cpp b/examples/DemoRunner/JuceLibraryCode/include_juce_opengl.cpp index d9895bce..e6541a42 100644 --- a/examples/DemoRunner/JuceLibraryCode/include_juce_opengl.cpp +++ b/examples/DemoRunner/JuceLibraryCode/include_juce_opengl.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_opengl/juce_opengl.cpp> diff --git a/examples/DemoRunner/JuceLibraryCode/include_juce_opengl.mm b/examples/DemoRunner/JuceLibraryCode/include_juce_opengl.mm index 6c2c32d0..793619ea 100644 --- a/examples/DemoRunner/JuceLibraryCode/include_juce_opengl.mm +++ b/examples/DemoRunner/JuceLibraryCode/include_juce_opengl.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_opengl/juce_opengl.mm> diff --git a/examples/DemoRunner/JuceLibraryCode/include_juce_osc.cpp b/examples/DemoRunner/JuceLibraryCode/include_juce_osc.cpp index 0c3b9ae9..7eadead5 100644 --- a/examples/DemoRunner/JuceLibraryCode/include_juce_osc.cpp +++ b/examples/DemoRunner/JuceLibraryCode/include_juce_osc.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_osc/juce_osc.cpp> diff --git a/examples/DemoRunner/JuceLibraryCode/include_juce_product_unlocking.cpp b/examples/DemoRunner/JuceLibraryCode/include_juce_product_unlocking.cpp index f3fcd328..ebb62e21 100644 --- a/examples/DemoRunner/JuceLibraryCode/include_juce_product_unlocking.cpp +++ b/examples/DemoRunner/JuceLibraryCode/include_juce_product_unlocking.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_product_unlocking/juce_product_unlocking.cpp> diff --git a/examples/DemoRunner/JuceLibraryCode/include_juce_product_unlocking.mm b/examples/DemoRunner/JuceLibraryCode/include_juce_product_unlocking.mm index 25aa7eaf..12010f18 100644 --- a/examples/DemoRunner/JuceLibraryCode/include_juce_product_unlocking.mm +++ b/examples/DemoRunner/JuceLibraryCode/include_juce_product_unlocking.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_product_unlocking/juce_product_unlocking.mm> diff --git a/examples/DemoRunner/JuceLibraryCode/include_juce_video.cpp b/examples/DemoRunner/JuceLibraryCode/include_juce_video.cpp index bdf22ee1..29c12835 100644 --- a/examples/DemoRunner/JuceLibraryCode/include_juce_video.cpp +++ b/examples/DemoRunner/JuceLibraryCode/include_juce_video.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_video/juce_video.cpp> diff --git a/examples/DemoRunner/JuceLibraryCode/include_juce_video.mm b/examples/DemoRunner/JuceLibraryCode/include_juce_video.mm index 3da705bc..082e1adb 100644 --- a/examples/DemoRunner/JuceLibraryCode/include_juce_video.mm +++ b/examples/DemoRunner/JuceLibraryCode/include_juce_video.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_video/juce_video.mm> diff --git a/examples/DemoRunner/Source/Demos/DemoPIPs1.cpp b/examples/DemoRunner/Source/Demos/DemoPIPs1.cpp index f030078e..ec6f561c 100644 --- a/examples/DemoRunner/Source/Demos/DemoPIPs1.cpp +++ b/examples/DemoRunner/Source/Demos/DemoPIPs1.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -41,26 +40,23 @@ #include "../../../Audio/MidiDemo.h" #include "../../../Audio/MPEDemo.h" #include "../../../Audio/PluckedStringsDemo.h" - -#if JUCE_HAS_CONSTEXPR - #include "../../../Audio/SimpleFFTDemo.h" - #include "../../../BLOCKS/BlocksDrawingDemo.h" - #include "../../../BLOCKS/BlocksMonitorDemo.h" - #include "../../../BLOCKS/BlocksSynthDemo.h" - - - #include "../../../DSP/ConvolutionDemo.h" - #include "../../../DSP/FIRFilterDemo.h" - #include "../../../DSP/GainDemo.h" - #include "../../../DSP/IIRFilterDemo.h" - #include "../../../DSP/OscillatorDemo.h" - #include "../../../DSP/OverdriveDemo.h" - #if JUCE_USE_SIMD - #include "../../../DSP/SIMDRegisterDemo.h" - #endif - #include "../../../DSP/StateVariableFilterDemo.h" - #include "../../../DSP/WaveShaperTanhDemo.h" +#include "../../../Audio/SimpleFFTDemo.h" + +#include "../../../BLOCKS/BlocksDrawingDemo.h" +#include "../../../BLOCKS/BlocksMonitorDemo.h" +#include "../../../BLOCKS/BlocksSynthDemo.h" + +#include "../../../DSP/ConvolutionDemo.h" +#include "../../../DSP/FIRFilterDemo.h" +#include "../../../DSP/GainDemo.h" +#include "../../../DSP/IIRFilterDemo.h" +#include "../../../DSP/OscillatorDemo.h" +#include "../../../DSP/OverdriveDemo.h" +#if JUCE_USE_SIMD + #include "../../../DSP/SIMDRegisterDemo.h" #endif +#include "../../../DSP/StateVariableFilterDemo.h" +#include "../../../DSP/WaveShaperTanhDemo.h" #include "../../../Utilities/Box2DDemo.h" #if JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX @@ -90,7 +86,6 @@ void registerDemos_One() noexcept REGISTER_DEMO (MPEDemo, Audio, false) REGISTER_DEMO (PluckedStringsDemo, Audio, false) - #if JUCE_HAS_CONSTEXPR REGISTER_DEMO (SimpleFFTDemo, Audio, false) REGISTER_DEMO (BlocksDrawingDemo, BLOCKS, false) REGISTER_DEMO (BlocksMonitorDemo, BLOCKS, false) @@ -107,7 +102,6 @@ void registerDemos_One() noexcept #endif REGISTER_DEMO (StateVariableFilterDemo, DSP, false) REGISTER_DEMO (WaveShaperTanhDemo, DSP, false) - #endif REGISTER_DEMO (Box2DDemo, Utilities, false) #if JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX diff --git a/examples/DemoRunner/Source/Demos/DemoPIPs2.cpp b/examples/DemoRunner/Source/Demos/DemoPIPs2.cpp index d2584529..c468c74a 100644 --- a/examples/DemoRunner/Source/Demos/DemoPIPs2.cpp +++ b/examples/DemoRunner/Source/Demos/DemoPIPs2.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -46,9 +45,7 @@ #include "../../../GUI/FlexBoxDemo.h" #include "../../../GUI/FontsDemo.h" #include "../../../GUI/GraphicsDemo.h" -#if JUCE_HAS_CONSTEXPR - #include "../../../GUI/GridDemo.h" -#endif +#include "../../../GUI/GridDemo.h" #include "../../../GUI/ImagesDemo.h" #include "../../../GUI/KeyMappingsDemo.h" #include "../../../GUI/LookAndFeelDemo.h" @@ -85,9 +82,7 @@ void registerDemos_Two() noexcept REGISTER_DEMO (FlexBoxDemo, GUI, false) REGISTER_DEMO (FontsDemo, GUI, false) REGISTER_DEMO (GraphicsDemo, GUI, false) - #if JUCE_HAS_CONSTEXPR REGISTER_DEMO (GridDemo, GUI, false) - #endif REGISTER_DEMO (ImagesDemo, GUI, false) REGISTER_DEMO (KeyMappingsDemo, GUI, false) REGISTER_DEMO (LookAndFeelDemo, GUI, false) diff --git a/examples/DemoRunner/Source/Demos/IntroScreen.h b/examples/DemoRunner/Source/Demos/IntroScreen.h index ef1e6b9f..270e2c15 100644 --- a/examples/DemoRunner/Source/Demos/IntroScreen.h +++ b/examples/DemoRunner/Source/Demos/IntroScreen.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -81,13 +80,13 @@ private: Path wavePath; auto waveStep = 10.0f; - auto waveY = getHeight() * 0.44f; + auto waveY = (float) getHeight() * 0.44f; int i = 0; - for (auto x = waveStep * 0.5f; x < getWidth(); x += waveStep) + for (auto x = waveStep * 0.5f; x < (float) getWidth(); x += waveStep) { - auto y1 = waveY + getHeight() * 0.05f * std::sin (i * 0.38f + elapsed); - auto y2 = waveY + getHeight() * 0.10f * std::sin (i * 0.20f + elapsed * 2.0f); + auto y1 = waveY + (float) getHeight() * 0.05f * std::sin ((float) i * 0.38f + elapsed); + auto y2 = waveY + (float) getHeight() * 0.10f * std::sin ((float) i * 0.20f + elapsed * 2.0f); wavePath.addLineSegment ({ x, y1, x, y2 }, 2.0f); wavePath.addEllipse (x - waveStep * 0.3f, y1 - waveStep * 0.3f, waveStep * 0.6f, waveStep * 0.6f); diff --git a/examples/DemoRunner/Source/Demos/JUCEDemos.cpp b/examples/DemoRunner/Source/Demos/JUCEDemos.cpp index 9c7f5132..3fbd5834 100644 --- a/examples/DemoRunner/Source/Demos/JUCEDemos.cpp +++ b/examples/DemoRunner/Source/Demos/JUCEDemos.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -170,10 +169,6 @@ AudioDeviceManager& getSharedAudioDeviceManager (int numInputChannels, int numOu } //============================================================================== -// need to split this into two files otherwise VS will fall over -void registerDemos_One() noexcept; -void registerDemos_Two() noexcept; - void registerAllDemos() noexcept { registerDemos_One(); diff --git a/examples/DemoRunner/Source/Demos/JUCEDemos.h b/examples/DemoRunner/Source/Demos/JUCEDemos.h index a7bc07c1..4faf1c61 100644 --- a/examples/DemoRunner/Source/Demos/JUCEDemos.h +++ b/examples/DemoRunner/Source/Demos/JUCEDemos.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -58,6 +57,9 @@ struct JUCEDemos static File findExamplesDirectoryFromExecutable (File exec); }; +void registerDemos_One() noexcept; +void registerDemos_Two() noexcept; + //============================================================================== // used by child-process demo bool invokeChildProcessDemo (const String& commandLine); diff --git a/examples/DemoRunner/Source/JUCEAppIcon.png b/examples/DemoRunner/Source/JUCEAppIcon.png index 2564a24f7846d841e57b35b191bd8fa82ce648aa..978ec36faeb4b2aa3c7c7b8880a940a3228d95f8 100644 GIT binary patch literal 42953 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 F{s$5J?qmP} literal 45854 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 A=Kufz diff --git a/examples/DemoRunner/Source/Main.cpp b/examples/DemoRunner/Source/Main.cpp index 537d8307..b0fafe31 100644 --- a/examples/DemoRunner/Source/Main.cpp +++ b/examples/DemoRunner/Source/Main.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -132,10 +131,10 @@ private: setFullScreen (true); Desktop::getInstance().setOrientationsEnabled (Desktop::rotatedClockwise | Desktop::rotatedAntiClockwise); #else - setBounds ((int) (0.1f * getParentWidth()), - (int) (0.1f * getParentHeight()), - jmax (850, (int) (0.5f * getParentWidth())), - jmax (600, (int) (0.7f * getParentHeight()))); + setBounds ((int) (0.1f * (float) getParentWidth()), + (int) (0.1f * (float) getParentHeight()), + jmax (850, (int) (0.5f * (float) getParentWidth())), + jmax (600, (int) (0.7f * (float) getParentHeight()))); #endif setContentOwned (new MainComponent(), false); diff --git a/examples/DemoRunner/Source/UI/DemoContentComponent.cpp b/examples/DemoRunner/Source/UI/DemoContentComponent.cpp index c00b8165..98c7aa17 100644 --- a/examples/DemoRunner/Source/UI/DemoContentComponent.cpp +++ b/examples/DemoRunner/Source/UI/DemoContentComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -101,7 +100,7 @@ struct CodeContent : public Component #endif //============================================================================== -DemoContentComponent::DemoContentComponent (Component& mainComponent, std::function<void(bool)> callback) +DemoContentComponent::DemoContentComponent (Component& mainComponent, std::function<void (bool)> callback) : TabbedComponent (TabbedButtonBar::Orientation::TabsAtTop), demoChangedCallback (std::move (callback)) { diff --git a/examples/DemoRunner/Source/UI/DemoContentComponent.h b/examples/DemoRunner/Source/UI/DemoContentComponent.h index 7a15f537..03f68c73 100644 --- a/examples/DemoRunner/Source/UI/DemoContentComponent.h +++ b/examples/DemoRunner/Source/UI/DemoContentComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -36,7 +35,7 @@ struct CodeContent; class DemoContentComponent : public TabbedComponent { public: - DemoContentComponent (Component& mainComponent, std::function<void(bool)> demoChangedCallback); + DemoContentComponent (Component& mainComponent, std::function<void (bool)> demoChangedCallback); ~DemoContentComponent() override; void resized() override; @@ -51,7 +50,7 @@ public: void setTabBarIndent (int indent) noexcept { tabBarIndent = indent; } private: - std::function<void(bool)> demoChangedCallback; + std::function<void (bool)> demoChangedCallback; std::unique_ptr<DemoContent> demoContent; diff --git a/examples/DemoRunner/Source/UI/MainComponent.cpp b/examples/DemoRunner/Source/UI/MainComponent.cpp index e7b54fc9..c0f56b6c 100644 --- a/examples/DemoRunner/Source/UI/MainComponent.cpp +++ b/examples/DemoRunner/Source/UI/MainComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -207,7 +206,7 @@ public: demos.deselectAllRows(); demos.setHeaderComponent (categoryName.isEmpty() ? nullptr - : new Header (*this)); + : std::make_unique<Header> (*this)); demos.updateContent(); } diff --git a/examples/DemoRunner/Source/UI/MainComponent.h b/examples/DemoRunner/Source/UI/MainComponent.h index 24863830..f079c972 100644 --- a/examples/DemoRunner/Source/UI/MainComponent.h +++ b/examples/DemoRunner/Source/UI/MainComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/examples/DemoRunner/Source/UI/SettingsContent.h b/examples/DemoRunner/Source/UI/SettingsContent.h index 138dc4b3..c02cf5af 100644 --- a/examples/DemoRunner/Source/UI/SettingsContent.h +++ b/examples/DemoRunner/Source/UI/SettingsContent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -120,8 +119,8 @@ private: graphicsTitleLabel.setBounds (bounds.removeFromTop (30)); bounds.removeFromTop (space); - auto xPos = bounds.getX() + (bounds.getWidth() * 0.35f); - auto width = bounds.getWidth() * 0.6f; + auto xPos = (float) bounds.getX() + ((float) bounds.getWidth() * 0.35f); + auto width = (float) bounds.getWidth() * 0.6f; lookAndFeelSelector.setBounds (bounds.removeFromTop (itemHeight).withWidth ((int) width).withX ((int) xPos)); diff --git a/examples/GUI/AnimationAppDemo.h b/examples/GUI/AnimationAppDemo.h index d7e7b14f..67a76efc 100644 --- a/examples/GUI/AnimationAppDemo.h +++ b/examples/GUI/AnimationAppDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -80,13 +80,13 @@ public: for (auto i = 0; i < fishLength; ++i) { - auto radius = 100 + 10 * std::sin (getFrameCounter() * 0.1f + i * 0.5f); + auto radius = 100 + 10 * std::sin ((float) getFrameCounter() * 0.1f + (float) i * 0.5f); - Point<float> p (getWidth() / 2.0f + 1.5f * radius * std::sin (getFrameCounter() * 0.02f + i * 0.12f), - getHeight() / 2.0f + 1.0f * radius * std::cos (getFrameCounter() * 0.04f + i * 0.12f)); + Point<float> p ((float) getWidth() / 2.0f + 1.5f * radius * std::sin ((float) getFrameCounter() * 0.02f + (float) i * 0.12f), + (float) getHeight() / 2.0f + 1.0f * radius * std::cos ((float) getFrameCounter() * 0.04f + (float) i * 0.12f)); // draw the circles along the fish - g.fillEllipse (p.x - i, p.y - i, 2.0f + 2.0f * i, 2.0f + 2.0f * i); + g.fillEllipse (p.x - (float) i, p.y - (float) i, 2.0f + 2.0f * (float) i, 2.0f + 2.0f * (float) i); if (i == 0) spinePath.startNewSubPath (p); // if this is the first point, start a new path.. diff --git a/examples/GUI/AnimationDemo.h b/examples/GUI/AnimationDemo.h index 0d0a9512..29b24518 100644 --- a/examples/GUI/AnimationDemo.h +++ b/examples/GUI/AnimationDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -123,10 +123,10 @@ struct BallComponent : public Component void paint (Graphics& g) override { g.setColour (colour); - g.fillEllipse (2.0f, 2.0f, getWidth() - 4.0f, getHeight() - 4.0f); + g.fillEllipse (2.0f, 2.0f, (float) getWidth() - 4.0f, (float) getHeight() - 4.0f); g.setColour (Colours::darkgrey); - g.drawEllipse (2.0f, 2.0f, getWidth() - 4.0f, getHeight() - 4.0f, 1.0f); + g.drawEllipse (2.0f, 2.0f, (float) getWidth() - 4.0f, (float) getHeight() - 4.0f, 1.0f); } Point<float> position, speed; @@ -262,10 +262,10 @@ private: auto newIndex = (componentsToAnimate.indexOf (component) + 3 * cycleCount) % componentsToAnimate.size(); - auto angle = newIndex * MathConstants<float>::twoPi / componentsToAnimate.size(); + auto angle = (float) newIndex * MathConstants<float>::twoPi / (float) componentsToAnimate.size(); - auto radius = useWidth ? width * 0.35f - : height * 0.35f; + auto radius = useWidth ? (float) width * 0.35f + : (float) height * 0.35f; Rectangle<int> r (getWidth() / 2 + (int) (radius * std::sin (angle)) - 50, getHeight() / 2 + (int) (radius * std::cos (angle)) - 50, diff --git a/examples/GUI/BouncingBallWavetableDemo.h b/examples/GUI/BouncingBallWavetableDemo.h index ad186515..f8319edf 100644 --- a/examples/GUI/BouncingBallWavetableDemo.h +++ b/examples/GUI/BouncingBallWavetableDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -125,13 +125,13 @@ public: auto nextPos = pos + delta; - if (nextPos.x < 10 || nextPos.x + 10 > getWidth()) + if (nextPos.x < 10 || nextPos.x + 10 > (float) getWidth()) { delta.x = -delta.x; nextPos.x = pos.x + delta.x; } - if (nextPos.y < 50 || nextPos.y + 10 > getHeight()) + if (nextPos.y < 50 || nextPos.y + 10 > (float) getHeight()) { delta.y = -delta.y; nextPos.y = pos.y + delta.y; @@ -234,17 +234,17 @@ public: float amplitudeToY (float amp) const noexcept { - return getHeight() - (amp + 1.0f) * getHeight() / 2.0f; + return (float) getHeight() - (amp + 1.0f) * (float) getHeight() / 2.0f; } float xToAmplitude (float x) const noexcept { - return jlimit (-1.0f, 1.0f, 2.0f * (getWidth() - x) / getWidth() - 1.0f); + return jlimit (-1.0f, 1.0f, 2.0f * ((float) getWidth() - x) / (float) getWidth() - 1.0f); } float yToAmplitude (float y) const noexcept { - return jlimit (-1.0f, 1.0f, 2.0f * (getHeight() - y) / getHeight() - 1.0f); + return jlimit (-1.0f, 1.0f, 2.0f * ((float) getHeight() - y) / (float) getHeight() - 1.0f); } void timerCallback() override diff --git a/examples/GUI/CMakeLists.txt b/examples/GUI/CMakeLists.txt new file mode 100644 index 00000000..272e8475 --- /dev/null +++ b/examples/GUI/CMakeLists.txt @@ -0,0 +1,24 @@ +# ============================================================================== +# +# This file is part of the JUCE library. +# Copyright (c) 2020 - Raw Material Software Limited +# +# JUCE is an open source library subject to commercial or open-source +# licensing. +# +# By using JUCE, you agree to the terms of both the JUCE 6 End-User License +# Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). +# +# End User License Agreement: www.juce.com/juce-6-licence +# Privacy Policy: www.juce.com/juce-privacy-policy +# +# Or: You may also use this code under the terms of the GPL v3 (see +# www.gnu.org/licenses). +# +# JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER +# EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE +# DISCLAIMED. +# +# ============================================================================== + +_juce_add_pips() diff --git a/examples/GUI/CameraDemo.h b/examples/GUI/CameraDemo.h index 34a8e03a..0891fadc 100644 --- a/examples/GUI/CameraDemo.h +++ b/examples/GUI/CameraDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -303,7 +303,7 @@ private: snapshotButton.setEnabled (true); #endif - #if JUCE_ANDROID || JUCE_IOS + #if JUCE_CONTENT_SHARING URL url (recordingFile); snapshotButton .setEnabled (false); @@ -337,7 +337,7 @@ private: lastSnapshot.setImage (image); - #if JUCE_ANDROID || JUCE_IOS + #if JUCE_CONTENT_SHARING auto imageFile = File::getSpecialLocation (File::tempDirectory).getNonexistentChildFile ("JuceCameraPhotoDemo", ".jpg"); FileOutputStream stream (imageFile); diff --git a/examples/GUI/CodeEditorDemo.h b/examples/GUI/CodeEditorDemo.h index c2be5ffb..2ef7c488 100644 --- a/examples/GUI/CodeEditorDemo.h +++ b/examples/GUI/CodeEditorDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 diff --git a/examples/GUI/ComponentDemo.h b/examples/GUI/ComponentDemo.h index 5b80e50a..300ca43b 100644 --- a/examples/GUI/ComponentDemo.h +++ b/examples/GUI/ComponentDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 diff --git a/examples/GUI/ComponentTransformsDemo.h b/examples/GUI/ComponentTransformsDemo.h index 7395aa7b..052d0c1e 100644 --- a/examples/GUI/ComponentTransformsDemo.h +++ b/examples/GUI/ComponentTransformsDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 diff --git a/examples/GUI/DialogsDemo.h b/examples/GUI/DialogsDemo.h index cfa22eb9..1ac6f4cc 100644 --- a/examples/GUI/DialogsDemo.h +++ b/examples/GUI/DialogsDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -144,7 +144,7 @@ public: StringArray windowNames { "Plain Alert Window", "Alert Window With Warning Icon", "Alert Window With Info Icon", "Alert Window With Question Icon", "OK Cancel Alert Window", "Alert Window With Extra Components", "CalloutBox", "Thread With Progress Window", "'Load' File Browser", "'Load' File Browser With Image Preview", "'Choose Directory' File Browser", "'Save' File Browser", - "Share Text", "Share Files", "Share Images" }; + "Share Text", "Share Files", "Share Images" }; // warn in case we add any windows jassert (windowNames.size() == numDialogs); @@ -219,13 +219,9 @@ private: { AlertWindow::AlertIconType icon = AlertWindow::NoIcon; - switch (type) - { - case warningAlertWindow: icon = AlertWindow::WarningIcon; break; - case infoAlertWindow: icon = AlertWindow::InfoIcon; break; - case questionAlertWindow: icon = AlertWindow::QuestionIcon; break; - default: break; - } + if (type == warningAlertWindow) icon = AlertWindow::WarningIcon; + if (type == infoAlertWindow) icon = AlertWindow::InfoIcon; + if (type == questionAlertWindow) icon = AlertWindow::QuestionIcon; AlertWindow::showMessageBoxAsync (icon, "This is an AlertWindow", "And this is the AlertWindow's message. Blah blah blah blah blah blah blah blah blah blah blah blah blah.", @@ -240,14 +236,14 @@ private: } else if (type == calloutBoxWindow) { - auto* colourSelector = new ColourSelector(); + auto colourSelector = std::make_unique<ColourSelector>(); colourSelector->setName ("background"); colourSelector->setCurrentColour (findColour (TextButton::buttonColourId)); colourSelector->setColour (ColourSelector::backgroundColourId, Colours::transparentBlack); colourSelector->setSize (300, 400); - CallOutBox::launchAsynchronously (colourSelector, button.getScreenBounds(), nullptr); + CallOutBox::launchAsynchronously (std::move (colourSelector), button.getScreenBounds(), nullptr); } else if (type == extraComponentsAlertWindow) { @@ -339,7 +335,7 @@ private: FileOutputStream outStream (fileToSave); if (outStream.openedOk()) - if (auto inStream = std::unique_ptr<InputStream> (createAssetInputStream ("juce_icon.png"))) + if (auto inStream = createAssetInputStream ("juce_icon.png")) outStream.writeFromInputStream (*inStream, -1); } @@ -419,7 +415,7 @@ private: fileToSave.replaceWithText ("Make it fast!"); Array<URL> urls; - urls.add ({ fileToSave.getFullPathName() }); + urls.add (URL (fileToSave)); ContentSharer::getInstance()->shareFiles (urls, [] (bool success, const String& error) diff --git a/examples/GUI/FlexBoxDemo.h b/examples/GUI/FlexBoxDemo.h index 7560c23c..eda1feb7 100644 --- a/examples/GUI/FlexBoxDemo.h +++ b/examples/GUI/FlexBoxDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -49,9 +49,9 @@ #include "../Assets/DemoUtilities.h" //============================================================================== -struct DemoFlexPanel : public juce::Component +struct DemoFlexPanel : public Component { - DemoFlexPanel (juce::Colour col, FlexItem& item) + DemoFlexPanel (Colour col, FlexItem& item) : flexItem (item), colour (col) { int x = 70; @@ -118,6 +118,7 @@ struct DemoFlexPanel : public juce::Component case 3: flexItem.alignSelf = FlexItem::AlignSelf::flexEnd; break; case 4: flexItem.alignSelf = FlexItem::AlignSelf::center; break; case 5: flexItem.alignSelf = FlexItem::AlignSelf::stretch; break; + default: break; } refreshLayout(); @@ -154,7 +155,7 @@ struct DemoFlexPanel : public juce::Component TextEditor flexOrderEditor, flexGrowEditor, flexShrinkEditor, flexBasisEditor; ComboBox alignSelfCombo; - juce::Colour colour; + Colour colour; OwnedArray<Label> labels; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DemoFlexPanel) diff --git a/examples/GUI/FontsDemo.h b/examples/GUI/FontsDemo.h index 035fd8c5..60053be6 100644 --- a/examples/GUI/FontsDemo.h +++ b/examples/GUI/FontsDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -65,23 +65,32 @@ public: addAndMakeVisible (kerningLabel); addAndMakeVisible (kerningSlider); addAndMakeVisible (scaleLabel); + addAndMakeVisible (horizontalJustificationLabel); + addAndMakeVisible (verticalJustificationLabel); addAndMakeVisible (scaleSlider); addAndMakeVisible (boldToggle); addAndMakeVisible (italicToggle); + addAndMakeVisible (underlineToggle); addAndMakeVisible (styleBox); + addAndMakeVisible (horizontalJustificationBox); + addAndMakeVisible (verticalJustificationBox); + addAndMakeVisible (resetButton); - kerningLabel.attachToComponent (&kerningSlider, true); - heightLabel .attachToComponent (&heightSlider, true); - scaleLabel .attachToComponent (&scaleSlider, true); - styleLabel .attachToComponent (&styleBox, true); + kerningLabel .attachToComponent (&kerningSlider, true); + heightLabel .attachToComponent (&heightSlider, true); + scaleLabel .attachToComponent (&scaleSlider, true); + styleLabel .attachToComponent (&styleBox, true); + horizontalJustificationLabel.attachToComponent (&horizontalJustificationBox, true); + verticalJustificationLabel .attachToComponent (&verticalJustificationBox, true); heightSlider .addListener (this); kerningSlider.addListener (this); scaleSlider .addListener (this); - boldToggle .onClick = [this] { refreshPreviewBoxFont(); }; - italicToggle.onClick = [this] { refreshPreviewBoxFont(); }; - styleBox .onChange = [this] { refreshPreviewBoxFont(); }; + boldToggle .onClick = [this] { refreshPreviewBoxFont(); }; + italicToggle .onClick = [this] { refreshPreviewBoxFont(); }; + underlineToggle.onClick = [this] { refreshPreviewBoxFont(); }; + styleBox .onChange = [this] { refreshPreviewBoxFont(); }; Font::findFonts (fonts); // Generate the list of fonts @@ -94,10 +103,6 @@ public: scaleSlider .setRange (0.2, 3.0, 0.01); kerningSlider.setRange (-2.0, 2.0, 0.01); - scaleSlider .setValue (1.0); // Set some initial values for the sliders. - heightSlider .setValue (20.0); - kerningSlider.setValue (0); - // set up the layout and resizer bars.. verticalLayout.setItemLayout (0, -0.2, -0.8, -0.35); // width of the font list must be // between 20% and 80%, preferably 50% @@ -127,6 +132,13 @@ public: demoTextBox.setColour (TextEditor::textColourId, Colours::black); demoTextBox.setColour (TextEditor::backgroundColourId, Colours::white); + demoTextBox.setWhitespaceUnderlined (false); + + resetButton.onClick = [this] { resetToDefaultParameters(); }; + + setupJustificationOptions(); + resetToDefaultParameters(); + setSize (750, 750); } @@ -151,7 +163,10 @@ public: r.removeFromLeft (verticalDividerBar->getRight()); - int labelWidth = 60; + resetButton.setBounds (r.removeFromBottom (30).reduced (jmax (20, r.getWidth() / 5), 0)); + r.removeFromBottom (8); + + const int labelWidth = 60; auto styleArea = r.removeFromBottom (26); styleArea.removeFromLeft (labelWidth); @@ -160,9 +175,15 @@ public: auto row = r.removeFromBottom (30); row.removeFromLeft (labelWidth); - boldToggle.setBounds (row.removeFromLeft (row.getWidth() / 2)); - italicToggle.setBounds (row); + auto toggleWidth = row.getWidth() / 3; + boldToggle .setBounds (row.removeFromLeft (toggleWidth)); + italicToggle .setBounds (row.removeFromLeft (toggleWidth)); + underlineToggle.setBounds (row); + r.removeFromBottom (8); + horizontalJustificationBox.setBounds (r.removeFromBottom (30).withTrimmedLeft (labelWidth * 3)); + r.removeFromBottom (8); + verticalJustificationBox.setBounds (r.removeFromBottom (30).withTrimmedLeft (labelWidth * 3)); r.removeFromBottom (8); scaleSlider.setBounds (r.removeFromBottom (30).withTrimmedLeft (labelWidth)); r.removeFromBottom (8); @@ -175,9 +196,9 @@ public: void sliderValueChanged (Slider* sliderThatWasMoved) override { - if (sliderThatWasMoved == &heightSlider) refreshPreviewBoxFont(); - else if (sliderThatWasMoved == &kerningSlider) refreshPreviewBoxFont(); - else if (sliderThatWasMoved == &scaleSlider) refreshPreviewBoxFont(); + if (sliderThatWasMoved == &heightSlider) refreshPreviewBoxFont(); + else if (sliderThatWasMoved == &kerningSlider) refreshPreviewBoxFont(); + else if (sliderThatWasMoved == &scaleSlider) refreshPreviewBoxFont(); } // The following methods implement the ListBoxModel virtual methods: @@ -197,8 +218,8 @@ public: AttributedString s; s.setWordWrap (AttributedString::none); s.setJustification (Justification::centredLeft); - s.append (font.getTypefaceName(), font.withHeight (height * 0.7f), Colours::black); - s.append (" " + font.getTypefaceName(), Font (height * 0.5f, Font::italic), Colours::grey); + s.append (font.getTypefaceName(), font.withHeight ((float) height * 0.7f), Colours::black); + s.append (" " + font.getTypefaceName(), Font ((float) height * 0.5f, Font::italic), Colours::grey); s.draw (g, Rectangle<int> (width, height).expanded (-4, 50).toFloat()); } @@ -215,21 +236,71 @@ private: ListBox listBox; TextEditor demoTextBox; - Label heightLabel { {}, "Height:" }, - kerningLabel { {}, "Kerning:" }, - scaleLabel { {}, "Scale:" }, - styleLabel { {}, "Style:" }; + const double defaultScale = 1.0, defaultHeight = 20.0, defaultKerning = 0.0; + const bool defaultBold = false, defaultItalic = false, defaultUnderlined = false; + const int defaultStyle = 0, defaultHorizontalJustification = 0, defaultVerticalJustification = 0; + + Label heightLabel { {}, "Height:" }, + kerningLabel { {}, "Kerning:" }, + scaleLabel { {}, "Scale:" }, + styleLabel { {}, "Style:" }, + horizontalJustificationLabel { {}, "Justification (horizontal):" }, + verticalJustificationLabel { {}, "Justification (vertical):" }; + + ToggleButton boldToggle { "Bold" }, + italicToggle { "Italic" }, + underlineToggle { "Underlined" }; - ToggleButton boldToggle { "Bold" }, - italicToggle { "Italic" }; + TextButton resetButton { "Reset" }; Slider heightSlider, kerningSlider, scaleSlider; - ComboBox styleBox; + ComboBox styleBox, horizontalJustificationBox, verticalJustificationBox; StretchableLayoutManager verticalLayout; std::unique_ptr<StretchableLayoutResizerBar> verticalDividerBar; + StringArray horizontalJustificationStrings { "Left", "Centred", "Right" }, + verticalJustificationStrings { "Top", "Centred", "Bottom" }; + + Array<int> horizontalJustificationFlags { Justification::left, Justification::horizontallyCentred, Justification::right }, + verticalJustificationFlags { Justification::top, Justification::verticallyCentred, Justification::bottom}; + //============================================================================== + void resetToDefaultParameters() + { + scaleSlider .setValue (defaultScale); + heightSlider .setValue (defaultHeight); + kerningSlider.setValue (defaultKerning); + + boldToggle .setToggleState (defaultBold, sendNotificationSync); + italicToggle .setToggleState (defaultItalic, sendNotificationSync); + underlineToggle.setToggleState (defaultUnderlined, sendNotificationSync); + + styleBox.setSelectedItemIndex (defaultStyle); + horizontalJustificationBox.setSelectedItemIndex (defaultHorizontalJustification); + verticalJustificationBox .setSelectedItemIndex (defaultVerticalJustification); + } + + void setupJustificationOptions() + { + horizontalJustificationBox.addItemList (horizontalJustificationStrings, 1); + verticalJustificationBox .addItemList (verticalJustificationStrings, 1); + + auto updateJustification = [this]() + { + auto horizontalIndex = horizontalJustificationBox.getSelectedItemIndex(); + auto verticalIndex = verticalJustificationBox.getSelectedItemIndex(); + + auto horizontalJustification = horizontalJustificationFlags[horizontalIndex]; + auto verticalJustification = verticalJustificationFlags[verticalIndex]; + + demoTextBox.setJustification (horizontalJustification | verticalJustification); + }; + + horizontalJustificationBox.onChange = updateJustification; + verticalJustificationBox .onChange = updateJustification; + } + void refreshPreviewBoxFont() { auto bold = boldToggle .getToggleState(); @@ -252,6 +323,8 @@ private: if (useStyle) font = font.withTypefaceStyle (styleBox.getText()); + font.setUnderline (underlineToggle.getToggleState()); + demoTextBox.applyFontToAllText (font); } @@ -265,7 +338,7 @@ private: styleBox.clear(); styleBox.addItemList (newStyles, 1); - styleBox.setSelectedItemIndex (0); + styleBox.setSelectedItemIndex (defaultStyle); } } diff --git a/examples/GUI/GraphicsDemo.h b/examples/GUI/GraphicsDemo.h index d5fecd46..4ad44682 100644 --- a/examples/GUI/GraphicsDemo.h +++ b/examples/GUI/GraphicsDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -125,8 +125,8 @@ public: AffineTransform getTransform() { - auto hw = 0.5f * getWidth(); - auto hh = 0.5f * getHeight(); + auto hw = 0.5f * (float) getWidth(); + auto hh = 0.5f * (float) getHeight(); AffineTransform t; @@ -197,7 +197,7 @@ public: "Time: " + String (averageTimeMs, 2) + " ms\nEffective FPS: " + String (effectiveFPS, 1) + "\nActual FPS: " + String (averageActualFPS, 1), - 0, 10.0f, getWidth() - 10.0f, (float) getHeight(), Justification::topRight, 3); + 0, 10.0f, (float) getWidth() - 10.0f, (float) getHeight(), Justification::topRight, 3); g.setColour (Colours::white.withAlpha (0.5f)); g.fillRect (ga.getBoundingBox (0, ga.getNumGlyphs(), true).getSmallestIntegerContainer().expanded (4)); @@ -213,8 +213,8 @@ public: auto w = getWidth() / 2; auto h = getHeight() / 2; - auto x = (int) (w * clipRectX.getValue()); - auto y = (int) (h * clipRectY.getValue()); + auto x = (int) ((float) w * clipRectX.getValue()); + auto y = (int) ((float) h * clipRectY.getValue()); g.reduceClipRegion (x, y, w, h); } @@ -239,12 +239,12 @@ public: if (! clipImage.isValid()) createClipImage(); - AffineTransform transform (AffineTransform::translation (clipImage.getWidth() / -2.0f, - clipImage.getHeight() / -2.0f) + AffineTransform transform (AffineTransform::translation ((float) clipImage.getWidth() / -2.0f, + (float) clipImage.getHeight() / -2.0f) .rotated (clipImageAngle.getValue() * MathConstants<float>::twoPi) .scaled (2.0f + clipImageSize.getValue() * 3.0f) - .translated (getWidth() * 0.5f, - getHeight() * 0.5f)); + .translated ((float) getWidth() * 0.5f, + (float) getHeight() * 0.5f)); g.reduceClipRegion (clipImage, transform); } @@ -297,17 +297,17 @@ public: g.fillRect (-rectSize, -rectSize, rectSize, rectSize); g.setGradientFill (ColourGradient (colour1, 10.0f, (float) -rectSize, - colour2, 10.0f + rectSize, 0.0f, false)); + colour2, 10.0f + (float) rectSize, 0.0f, false)); g.setOpacity (getAlpha()); g.fillRect (10, -rectSize, rectSize, rectSize); - g.setGradientFill (ColourGradient (colour1, rectSize * -0.5f, 10.0f + rectSize * 0.5f, - colour2, 0, 10.0f + rectSize, true)); + g.setGradientFill (ColourGradient (colour1, (float) rectSize * -0.5f, 10.0f + (float) rectSize * 0.5f, + colour2, 0, 10.0f + (float) rectSize, true)); g.setOpacity (getAlpha()); g.fillRect (-rectSize, 10, rectSize, rectSize); g.setGradientFill (ColourGradient (colour1, 10.0f, 10.0f, - colour2, 10.0f + rectSize, 10.0f + rectSize, false)); + colour2, 10.0f + (float) rectSize, 10.0f + (float) rectSize, false)); g.setOpacity (getAlpha()); g.drawRect (10, 10, rectSize, rectSize, 5); } @@ -349,10 +349,10 @@ public: Colour c2 (gradientColours[3].getValue(), gradientColours[4].getValue(), gradientColours[5].getValue(), 1.0f); Colour c3 (gradientColours[6].getValue(), gradientColours[7].getValue(), gradientColours[8].getValue(), 1.0f); - auto x1 = gradientPositions[0].getValue() * getWidth() * 0.25f; - auto y1 = gradientPositions[1].getValue() * getHeight() * 0.25f; - auto x2 = gradientPositions[2].getValue() * getWidth() * 0.75f; - auto y2 = gradientPositions[3].getValue() * getHeight() * 0.75f; + auto x1 = gradientPositions[0].getValue() * (float) getWidth() * 0.25f; + auto y1 = gradientPositions[1].getValue() * (float) getHeight() * 0.25f; + auto x2 = gradientPositions[2].getValue() * (float) getWidth() * 0.75f; + auto y2 = gradientPositions[3].getValue() * (float) getHeight() * 0.75f; ColourGradient gradient (c1, x1, y1, c2, x2, y2, @@ -489,7 +489,7 @@ public: { lastSVGLoadTime = Time::getCurrentTime(); - ZipFile icons (createAssetInputStream ("icons.zip"), true); + ZipFile icons (createAssetInputStream ("icons.zip").release(), true); // Load a random SVG file from our embedded icons.zip file. const std::unique_ptr<InputStream> svgFileStream (icons.createStreamForEntry (Random::getSystemRandom().nextInt (icons.getNumEntries()))); @@ -530,8 +530,8 @@ public: for (int x = 0; x < getWidth(); ++x) { - auto y = getHeight() * 0.3f; - auto length = y * std::abs (std::sin (x / 100.0f + 2.0f * pos)); + auto y = (float) getHeight() * 0.3f; + auto length = y * std::abs (std::sin ((float) x / 100.0f + 2.0f * pos)); verticalLines.addWithoutMerging (Rectangle<float> ((float) x, y - length * 0.5f, 1.0f, length)); } @@ -547,8 +547,8 @@ public: for (int y = 0; y < getHeight(); ++y) { - auto x = getWidth() * 0.3f; - auto length = x * std::abs (std::sin (y / 100.0f + 2.0f * pos)); + auto x = (float) getWidth() * 0.3f; + auto length = x * std::abs (std::sin ((float) y / 100.0f + 2.0f * pos)); horizontalLines.addWithoutMerging (Rectangle<float> (x - length * 0.5f, (float) y, length, 1.0f)); } diff --git a/examples/GUI/GridDemo.h b/examples/GUI/GridDemo.h index 9f599f64..c5d74cf5 100644 --- a/examples/GUI/GridDemo.h +++ b/examples/GUI/GridDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 diff --git a/examples/GUI/HelloWorldDemo.h b/examples/GUI/HelloWorldDemo.h index 8acc465b..79754bbd 100644 --- a/examples/GUI/HelloWorldDemo.h +++ b/examples/GUI/HelloWorldDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 diff --git a/examples/GUI/ImagesDemo.h b/examples/GUI/ImagesDemo.h index 478bf494..574372ff 100644 --- a/examples/GUI/ImagesDemo.h +++ b/examples/GUI/ImagesDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 diff --git a/examples/GUI/KeyMappingsDemo.h b/examples/GUI/KeyMappingsDemo.h index 19cdb975..1fc66eca 100644 --- a/examples/GUI/KeyMappingsDemo.h +++ b/examples/GUI/KeyMappingsDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 diff --git a/examples/GUI/LookAndFeelDemo.h b/examples/GUI/LookAndFeelDemo.h index f76807b5..99ce15c0 100644 --- a/examples/GUI/LookAndFeelDemo.h +++ b/examples/GUI/LookAndFeelDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -90,8 +90,8 @@ struct CustomLookAndFeel : public LookAndFeel_V4 auto flatOnTop = button.isConnectedOnTop(); auto flatOnBottom = button.isConnectedOnBottom(); - auto width = button.getWidth() - 1.0f; - auto height = button.getHeight() - 1.0f; + auto width = (float) button.getWidth() - 1.0f; + auto height = (float) button.getHeight() - 1.0f; if (width > 0 && height > 0) { @@ -168,13 +168,13 @@ struct CustomLookAndFeel : public LookAndFeel_V4 if (style == Slider::LinearVertical) { - kx = x + width * 0.5f; + kx = (float) x + (float) width * 0.5f; ky = sliderPos; } else { kx = sliderPos; - ky = y + height * 0.5f; + ky = (float) y + (float) height * 0.5f; } auto outlineThickness = slider.isEnabled() ? 0.8f : 0.3f; @@ -203,9 +203,9 @@ struct CustomLookAndFeel : public LookAndFeel_V4 Path p; if (style == Slider::LinearBarVertical) - p.addRectangle ((float) x, sliderPos, (float) width, 1.0f + height - sliderPos); + p.addRectangle ((float) x, sliderPos, (float) width, 1.0f + (float) height - sliderPos); else - p.addRectangle ((float) x, (float) y, sliderPos - x, (float) height); + p.addRectangle ((float) x, (float) y, sliderPos - (float) x, (float) height); auto baseColour = slider.findColour (Slider::rotarySliderFillColourId) .withMultipliedSaturation (slider.isEnabled() ? 1.0f : 0.5f) @@ -214,7 +214,7 @@ struct CustomLookAndFeel : public LookAndFeel_V4 g.setColour (baseColour); g.fillPath (p); - auto lineThickness = jmin (15.0f, jmin (width, height) * 0.45f) * 0.1f; + auto lineThickness = jmin (15.0f, (float) jmin (width, height) * 0.45f) * 0.1f; g.drawRect (slider.getLocalBounds().toFloat(), lineThickness); } else @@ -230,13 +230,13 @@ struct CustomLookAndFeel : public LookAndFeel_V4 float /*maxSliderPos*/, const Slider::SliderStyle /*style*/, Slider& slider) override { - auto sliderRadius = getSliderThumbRadius (slider) - 5.0f; + auto sliderRadius = (float) getSliderThumbRadius (slider) - 5.0f; Path on, off; if (slider.isHorizontal()) { - auto iy = y + height * 0.5f - sliderRadius * 0.5f; - Rectangle<float> r (x - sliderRadius * 0.5f, iy, width + sliderRadius, sliderRadius); + auto iy = (float) y + (float) height * 0.5f - sliderRadius * 0.5f; + Rectangle<float> r ((float) x - sliderRadius * 0.5f, iy, (float) width + sliderRadius, sliderRadius); auto onW = r.getWidth() * ((float) slider.valueToProportionOfLength (slider.getValue())); on.addRectangle (r.removeFromLeft (onW)); @@ -244,8 +244,8 @@ struct CustomLookAndFeel : public LookAndFeel_V4 } else { - auto ix = x + width * 0.5f - sliderRadius * 0.5f; - Rectangle<float> r (ix, y - sliderRadius * 0.5f, sliderRadius, height + sliderRadius); + auto ix = (float) x + (float) width * 0.5f - sliderRadius * 0.5f; + Rectangle<float> r (ix, (float) y - sliderRadius * 0.5f, sliderRadius, (float) height + sliderRadius); auto onH = r.getHeight() * ((float) slider.valueToProportionOfLength (slider.getValue())); on.addRectangle (r.removeFromBottom (onH)); @@ -262,9 +262,9 @@ struct CustomLookAndFeel : public LookAndFeel_V4 void drawRotarySlider (Graphics& g, int x, int y, int width, int height, float sliderPos, float rotaryStartAngle, float rotaryEndAngle, Slider& slider) override { - auto radius = jmin (width / 2, height / 2) - 2.0f; - auto centreX = x + width * 0.5f; - auto centreY = y + height * 0.5f; + auto radius = (float) jmin (width / 2, height / 2) - 2.0f; + auto centreX = (float) x + (float) width * 0.5f; + auto centreY = (float) y + (float) height * 0.5f; auto rx = centreX - radius; auto ry = centreY - radius; auto rw = radius * 2.0f; @@ -283,7 +283,7 @@ struct CustomLookAndFeel : public LookAndFeel_V4 } { - auto lineThickness = jmin (15.0f, jmin (width, height) * 0.45f) * 0.1f; + auto lineThickness = jmin (15.0f, (float) jmin (width, height) * 0.45f) * 0.1f; Path outlineArc; outlineArc.addPieSegment (rx, ry, rw, rw, rotaryStartAngle, rotaryEndAngle, 0.0); g.strokePath (outlineArc, PathStrokeType (lineThickness)); @@ -307,8 +307,8 @@ struct SquareLookAndFeel : public CustomLookAndFeel if (isButtonDown || isMouseOverButton) baseColour = baseColour.contrasting (isButtonDown ? 0.2f : 0.1f); - auto width = button.getWidth() - 1.0f; - auto height = button.getHeight() - 1.0f; + auto width = (float) button.getWidth() - 1.0f; + auto height = (float) button.getHeight() - 1.0f; if (width > 0 && height > 0) { @@ -372,14 +372,14 @@ struct SquareLookAndFeel : public CustomLookAndFeel if (style == Slider::LinearVertical) { - kx = x + width * 0.5f; + kx = (float) x + (float) width * 0.5f; ky = sliderPos; g.fillRect (Rectangle<float> (kx - sliderRadius, ky - 2.5f, sliderRadius * 2.0f, 5.0f)); } else { kx = sliderPos; - ky = y + height * 0.5f; + ky = (float) y + (float) height * 0.5f; g.fillRect (Rectangle<float> (kx - 2.5f, ky - sliderRadius, 5.0f, sliderRadius * 2.0f)); } } @@ -393,10 +393,10 @@ struct SquareLookAndFeel : public CustomLookAndFeel void drawRotarySlider (Graphics& g, int x, int y, int width, int height, float sliderPos, float rotaryStartAngle, float rotaryEndAngle, Slider& slider) override { - auto diameter = jmin (width, height) - 4.0f; + auto diameter = (float) jmin (width, height) - 4.0f; auto radius = (diameter / 2.0f) * std::cos (MathConstants<float>::pi / 4.0f); - auto centreX = x + width * 0.5f; - auto centreY = y + height * 0.5f; + auto centreX = (float) x + (float) width * 0.5f; + auto centreY = (float) y + (float) height * 0.5f; auto rx = centreX - radius; auto ry = centreY - radius; auto rw = radius * 2.0f; diff --git a/examples/GUI/MDIDemo.h b/examples/GUI/MDIDemo.h index 7b3c0632..3818dd6e 100644 --- a/examples/GUI/MDIDemo.h +++ b/examples/GUI/MDIDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 diff --git a/examples/GUI/MenusDemo.h b/examples/GUI/MenusDemo.h index 2304b7c5..aa905b96 100644 --- a/examples/GUI/MenusDemo.h +++ b/examples/GUI/MenusDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -102,7 +102,7 @@ private: burgerButton.setBounds (r.removeFromRight (40).withSizeKeepingCentre (20, 20)); - titleLabel.setFont (Font (getHeight() * 0.5f, Font::plain)); + titleLabel.setFont (Font ((float) getHeight() * 0.5f, Font::plain)); titleLabel.setBounds (r); } diff --git a/examples/GUI/MultiTouchDemo.h b/examples/GUI/MultiTouchDemo.h index d507ab13..36f97bd0 100644 --- a/examples/GUI/MultiTouchDemo.h +++ b/examples/GUI/MultiTouchDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 diff --git a/examples/GUI/OpenGLAppDemo.h b/examples/GUI/OpenGLAppDemo.h index 5caff532..f32029e5 100644 --- a/examples/GUI/OpenGLAppDemo.h +++ b/examples/GUI/OpenGLAppDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -92,7 +92,7 @@ public: Matrix3D<float> getViewMatrix() const { Matrix3D<float> viewMatrix ({ 0.0f, 0.0f, -10.0f }); - Matrix3D<float> rotationMatrix = viewMatrix.rotation ({ -0.3f, 5.0f * std::sin (getFrameCounter() * 0.01f), 0.0f }); + Matrix3D<float> rotationMatrix = viewMatrix.rotation ({ -0.3f, 5.0f * std::sin ((float) getFrameCounter() * 0.01f), 0.0f }); return rotationMatrix * viewMatrix; } @@ -107,7 +107,7 @@ public: glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glViewport (0, 0, roundToInt (desktopScale * getWidth()), roundToInt (desktopScale * getHeight())); + glViewport (0, 0, roundToInt (desktopScale * (float) getWidth()), roundToInt (desktopScale * (float) getHeight())); shader->use(); diff --git a/examples/GUI/OpenGLDemo.h b/examples/GUI/OpenGLDemo.h index 065d40fa..639131f3 100644 --- a/examples/GUI/OpenGLDemo.h +++ b/examples/GUI/OpenGLDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -655,7 +655,10 @@ struct OpenGLUtils g.drawRect (0, 0, size, size, 2); g.setColour (Colours::green); - g.fillEllipse (x.getValue() * size * 0.9f, y.getValue() * size * 0.9f, size * 0.1f, size * 0.1f); + g.fillEllipse (x.getValue() * (float) size * 0.9f, + y.getValue() * (float) size * 0.9f, + (float) size * 0.1f, + (float) size * 0.1f); g.setColour (Colours::black); g.setFont (40); @@ -827,7 +830,7 @@ public: openGLContext.extensions.glActiveTexture (GL_TEXTURE0); glEnable (GL_TEXTURE_2D); - glViewport (0, 0, roundToInt (desktopScale * getWidth()), roundToInt (desktopScale * getHeight())); + glViewport (0, 0, roundToInt (desktopScale * (float) getWidth()), roundToInt (desktopScale * (float) getHeight())); texture.bind(); @@ -913,8 +916,8 @@ private: { // Create an OpenGLGraphicsContext that will draw into this GL window.. std::unique_ptr<LowLevelGraphicsContext> glRenderer (createOpenGLGraphicsContext (openGLContext, - roundToInt (desktopScale * getWidth()), - roundToInt (desktopScale * getHeight()))); + roundToInt (desktopScale * (float) getWidth()), + roundToInt (desktopScale * (float) getHeight()))); if (glRenderer.get() != nullptr) { @@ -927,11 +930,11 @@ private: // This stuff just creates a spinning star shape and fills it.. Path p; - p.addStar ({ getWidth() * s.x.getValue(), - getHeight() * s.y.getValue() }, + p.addStar ({ (float) getWidth() * s.x.getValue(), + (float) getHeight() * s.y.getValue() }, 7, - getHeight() * size * 0.5f, - getHeight() * size, + (float) getHeight() * size * 0.5f, + (float) getHeight() * size, s.angle.getValue()); auto hue = s.hue.getValue(); diff --git a/examples/GUI/OpenGLDemo2D.h b/examples/GUI/OpenGLDemo2D.h index 24ae12b5..8ab52524 100644 --- a/examples/GUI/OpenGLDemo2D.h +++ b/examples/GUI/OpenGLDemo2D.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 diff --git a/examples/GUI/PropertiesDemo.h b/examples/GUI/PropertiesDemo.h index 64672110..71c09925 100644 --- a/examples/GUI/PropertiesDemo.h +++ b/examples/GUI/PropertiesDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 diff --git a/examples/GUI/VideoDemo.h b/examples/GUI/VideoDemo.h index 7f9ce3c2..12dadc04 100644 --- a/examples/GUI/VideoDemo.h +++ b/examples/GUI/VideoDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 diff --git a/examples/GUI/WebBrowserDemo.h b/examples/GUI/WebBrowserDemo.h index ba63e420..e07250a5 100644 --- a/examples/GUI/WebBrowserDemo.h +++ b/examples/GUI/WebBrowserDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 diff --git a/examples/GUI/WidgetsDemo.h b/examples/GUI/WidgetsDemo.h index 9ee29bcc..79645da2 100644 --- a/examples/GUI/WidgetsDemo.h +++ b/examples/GUI/WidgetsDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -87,11 +87,11 @@ public: void clicked() override { - auto* colourSelector = new ColourSelector (ColourSelector::showAlphaChannel - | ColourSelector::showColourAtTop - | ColourSelector::editableColour - | ColourSelector::showSliders - | ColourSelector::showColourspace); + auto colourSelector = std::make_unique<ColourSelector> (ColourSelector::showAlphaChannel + | ColourSelector::showColourAtTop + | ColourSelector::editableColour + | ColourSelector::showSliders + | ColourSelector::showColourspace); colourSelector->setName ("background"); colourSelector->setCurrentColour (findColour (TextButton::buttonColourId)); @@ -99,7 +99,7 @@ public: colourSelector->setColour (ColourSelector::backgroundColourId, Colours::transparentBlack); colourSelector->setSize (300, 400); - CallOutBox::launchAsynchronously (colourSelector, getScreenBounds(), nullptr); + CallOutBox::launchAsynchronously (std::move (colourSelector), getScreenBounds(), nullptr); } using TextButton::clicked; @@ -496,6 +496,166 @@ struct MiscPage : public Component ComboBox comboBox { "Combo" }; }; +//============================================================================== +struct MenuPage : public Component +{ + MenuPage() + { + addAndMakeVisible (shortMenuButton); + shortMenuButton.onClick = [&] + { + PopupMenu menu; + menu.addItem ("Single Item", nullptr); + menu.showMenuAsync (PopupMenu::Options{}.withTargetComponent (shortMenuButton)); + }; + + addAndMakeVisible (longMenuButton); + longMenuButton.onClick = [&] + { + PopupMenu menu; + + for (auto i = 0; i < 40; ++i) + menu.addItem ("Item " + String (i), nullptr); + + menu.showMenuAsync (PopupMenu::Options{}.withTargetComponent (longMenuButton)); + }; + + addAndMakeVisible (multiColumnMenuButton); + multiColumnMenuButton.onClick = [&] + { + PopupMenu menu; + + for (auto i = 0; i < 200; ++i) + menu.addItem ("Item " + String (i), nullptr); + + menu.showMenuAsync (PopupMenu::Options{}.withTargetComponent (multiColumnMenuButton) + .withMinimumNumColumns (2) + .withMaximumNumColumns (4)); + }; + + addAndMakeVisible (customItemButton); + customItemButton.onClick = [&] + { + struct CustomComponent : public PopupMenu::CustomComponent + { + CustomComponent (int widthIn, int heightIn, Colour backgroundIn) + : idealWidth (widthIn), idealHeight (heightIn), background (backgroundIn) + {} + + void getIdealSize (int& width, int& height) override + { + width = idealWidth; + height = idealHeight; + } + + void paint (Graphics& g) override { g.fillAll (background); } + + int idealWidth = 0; + int idealHeight = 0; + Colour background; + }; + + PopupMenu menu; + + menu.addCustomItem (-1, std::make_unique<CustomComponent> (100, 20, Colours::darkred)); + menu.addCustomItem (-1, std::make_unique<CustomComponent> (20, 100, Colours::darkgreen)); + menu.addCustomItem (-1, std::make_unique<CustomComponent> (100, 100, Colours::darkblue)); + menu.addCustomItem (-1, std::make_unique<CustomComponent> (100, 50, Colours::darkcyan)); + menu.addCustomItem (-1, std::make_unique<CustomComponent> (50, 100, Colours::darkmagenta)); + + menu.showMenuAsync (PopupMenu::Options{}.withTargetComponent (customItemButton) + .withMinimumNumColumns (5)); + }; + + addAndMakeVisible (fancyThemeButton); + fancyThemeButton.setLookAndFeel (&popupLookAndFeel); + fancyThemeButton.onClick = [&] + { + const auto colour = Colour::fromHSL (randomColourGenerator.nextFloat(), 0.5f, 0.5f, 1.0f); + fancyThemeButton.setColour (TextButton::buttonColourId, colour); + + const int columnLengths[] { 5, 10, 7, 3 }; + + PopupMenu menu; + menu.setLookAndFeel (&popupLookAndFeel); + + for (auto length : columnLengths) + { + for (auto i = 0; i < length; ++i) + menu.addItem ("Item " + String (i), nullptr); + + menu.addColumnBreak(); + } + + menu.showMenuAsync (PopupMenu::Options{}.withTargetComponent (&fancyThemeButton)); + }; + } + + void resized() override + { + const auto makeItem = [] (Component& comp) + { + return FlexItem { comp }.withWidth (200).withHeight (24).withMargin ({ 4 }); + }; + + FlexBox box; + box.flexDirection = FlexBox::Direction::column; + box.items = { makeItem (shortMenuButton), + makeItem (longMenuButton), + makeItem (multiColumnMenuButton), + makeItem (customItemButton), + makeItem (fancyThemeButton) }; + + box.performLayout (getLocalBounds()); + } + + struct PopupMenuLookAndFeel : public LookAndFeel_V4 + { + void drawPopupMenuColumnSeparatorWithOptions (Graphics& g, + const Rectangle<int>& bounds, + const PopupMenu::Options& opt) + { + if (auto* target = opt.getTargetComponent()) + { + const auto baseColour = target->findColour (TextButton::buttonColourId); + g.setColour (baseColour.brighter (0.4f)); + + const float dashes[] { 5.0f, 5.0f }; + const auto centre = bounds.toFloat().getCentre(); + + g.drawDashedLine ({ centre.withY ((float) bounds.getY()), + centre.withY ((float) bounds.getBottom()) }, + dashes, + numElementsInArray (dashes), + 3.0f); + } + } + + void drawPopupMenuBackgroundWithOptions (Graphics& g, int, int, const PopupMenu::Options& opt) + { + if (auto* target = opt.getTargetComponent()) + { + g.fillAll (target->findColour (TextButton::buttonColourId)); + } + } + + // Return the amount of space that should be left between popup menu columns. + int getPopupMenuColumnSeparatorWidthWithOptions (const PopupMenu::Options&) + { + return 10; + } + }; + + Random randomColourGenerator; + PopupMenuLookAndFeel popupLookAndFeel; + + TextButton shortMenuButton { "Short" }, + longMenuButton { "Long" }, + multiColumnMenuButton { "Multi Column" }, + customItemButton { "Custom Items" }, + fancyThemeButton { "Fancy Theme with Column Breaks" }; +}; + //============================================================================== class ToolbarDemoComp : public Component, private Slider::Listener @@ -667,7 +827,7 @@ private: if (iconsFromZipFile.size() == 0) { // If we've not already done so, load all the images from the zip file.. - ZipFile icons (createAssetInputStream ("icons.zip"), true); + ZipFile icons (createAssetInputStream ("icons.zip").release(), true); for (int i = 0; i < icons.getNumEntries(); ++i) { @@ -1106,7 +1266,7 @@ private: g.fillAll (Colours::lightblue); g.setColour (LookAndFeel::getDefaultLookAndFeel().findColour (Label::textColourId)); - g.setFont (height * 0.7f); + g.setFont ((float) height * 0.7f); g.drawText ("Draggable Thing #" + String (rowNumber + 1), 5, 0, width, height, @@ -1282,6 +1442,7 @@ struct DemoTabbedComponent : public TabbedComponent addTab ("Sliders", colour, new SlidersPage(), true); addTab ("Toolbars", colour, new ToolbarDemoComp(), true); addTab ("Misc", colour, new MiscPage(), true); + addTab ("Menus", colour, new MenuPage(), true); addTab ("Tables", colour, new TableDemoComponent(), true); addTab ("Drag & Drop", colour, new DragAndDropDemo(), true); diff --git a/examples/GUI/WindowsDemo.h b/examples/GUI/WindowsDemo.h index 3e7deb0c..307f3866 100644 --- a/examples/GUI/WindowsDemo.h +++ b/examples/GUI/WindowsDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -116,7 +116,7 @@ public: Random random; - auto size = 10.0f + random.nextInt (30); + auto size = 10.0f + (float) random.nextInt (30); ballBounds.setBounds (random.nextFloat() * 100.0f, random.nextFloat() * 100.0f, @@ -142,10 +142,10 @@ public: { ballBounds += direction; - if (ballBounds.getX() < 0) direction.x = std::abs (direction.x); - if (ballBounds.getY() < 0) direction.y = std::abs (direction.y); - if (ballBounds.getRight() > getParentWidth()) direction.x = -std::abs (direction.x); - if (ballBounds.getBottom() > getParentHeight()) direction.y = -std::abs (direction.y); + if (ballBounds.getX() < 0) direction.x = std::abs (direction.x); + if (ballBounds.getY() < 0) direction.y = std::abs (direction.y); + if (ballBounds.getRight() > (float) getParentWidth()) direction.x = -std::abs (direction.x); + if (ballBounds.getBottom() > (float) getParentHeight()) direction.y = -std::abs (direction.y); setBounds (ballBounds.getSmallestIntegerContainer()); } @@ -334,7 +334,7 @@ private: | RectanglePlacement::doNotResize); auto result = placement.appliedTo (area, Desktop::getInstance().getDisplays() - .getMainDisplay().userArea.reduced (20)); + .getPrimaryDisplay()->userArea.reduced (20)); dw->setBounds (result); dw->setResizable (true, ! native); @@ -355,7 +355,7 @@ private: | RectanglePlacement::doNotResize); auto result = placement.appliedTo (area, Desktop::getInstance().getDisplays() - .getMainDisplay().userArea.reduced (20)); + .getPrimaryDisplay()->userArea.reduced (20)); balls->setBounds (result); balls->setVisible (true); diff --git a/examples/Plugins/AUv3SynthPluginDemo.h b/examples/Plugins/AUv3SynthPluginDemo.h index 1dc74234..8b58bd22 100644 --- a/examples/Plugins/AUv3SynthPluginDemo.h +++ b/examples/Plugins/AUv3SynthPluginDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -23,24 +23,27 @@ BEGIN_JUCE_PIP_METADATA - name: AUv3SynthPlugin - version: 1.0.0 - vendor: JUCE - website: http://juce.com - description: AUv3 synthesiser audio plugin. + name: AUv3SynthPlugin + version: 1.0.0 + vendor: JUCE + website: http://juce.com + description: AUv3 synthesiser audio plugin. - dependencies: juce_audio_basics, juce_audio_devices, juce_audio_formats, - juce_audio_plugin_client, juce_audio_processors, - juce_audio_utils, juce_core, juce_data_structures, - juce_events, juce_graphics, juce_gui_basics, juce_gui_extra - exporters: xcode_mac, xcode_iphone + dependencies: juce_audio_basics, juce_audio_devices, juce_audio_formats, + juce_audio_plugin_client, juce_audio_processors, + juce_audio_utils, juce_core, juce_data_structures, + juce_events, juce_graphics, juce_gui_basics, juce_gui_extra + exporters: xcode_mac, xcode_iphone - moduleFlags: JUCE_STRICT_REFCOUNTEDPOINTER=1 + moduleFlags: JUCE_STRICT_REFCOUNTEDPOINTER=1 - type: AudioProcessor - mainClass: AUv3SynthProcessor + type: AudioProcessor + mainClass: AUv3SynthProcessor - useLocalCopy: 1 + useLocalCopy: 1 + + pluginCharacteristics: pluginIsSynth, pluginWantsMidiIn + extraPluginFormats: AUv3 END_JUCE_PIP_METADATA @@ -112,7 +115,7 @@ public: sliderPos = (sliderPos - minSliderPos) / static_cast<float> (width); - auto knobPos = static_cast<int> (sliderPos * r.getWidth()); + auto knobPos = static_cast<int> (sliderPos * (float) r.getWidth()); g.setColour (sliderActivePart); g.fillRect (backgroundBar.removeFromLeft (knobPos)); @@ -180,11 +183,11 @@ class AUv3SynthEditor : public AudioProcessorEditor, { public: //============================================================================== - AUv3SynthEditor (AudioProcessor& processor) - : AudioProcessorEditor (processor), - roomSizeSlider (Slider::LinearHorizontal, Slider::NoTextBox) + AUv3SynthEditor (AudioProcessor& processorIn) + : AudioProcessorEditor (processorIn), + roomSizeSlider (Slider::LinearHorizontal, Slider::NoTextBox) { - LookAndFeel::setDefaultLookAndFeel (&materialLookAndFeel); + setLookAndFeel (&materialLookAndFeel); roomSizeSlider.setValue (getParameterValue ("roomSize"), NotificationType::dontSendNotification); @@ -195,10 +198,8 @@ public: roomSizeSlider.setRange (0.0, 1.0); addAndMakeVisible (roomSizeSlider); - if (auto* assetStream = createAssetInputStream ("proaudio.path")) + if (auto fileStream = createAssetInputStream ("proaudio.path")) { - std::unique_ptr<InputStream> fileStream (assetStream); - Path proAudioPath; proAudioPath.loadPathFromStream (*fileStream); proAudioIcon.setPath (proAudioPath); @@ -212,6 +213,11 @@ public: startTimer (100); } + ~AUv3SynthEditor() override + { + setLookAndFeel (nullptr); + } + //============================================================================== void paint (Graphics& g) override { @@ -258,9 +264,9 @@ private: //============================================================================== AudioProcessorParameter* getParameter (const String& paramId) { - if (auto* processor = getAudioProcessor()) + if (auto* audioProcessor = getAudioProcessor()) { - auto& params = processor->getParameters(); + auto& params = audioProcessor->getParameters(); for (auto p : params) { @@ -355,13 +361,14 @@ public: reverb.processStereo (buffer.getWritePointer (0), buffer.getWritePointer (1), buffer.getNumSamples()); } + using AudioProcessor::processBlock; + //============================================================================== void releaseResources() override { currentRecording.setSize (1, 1); } //============================================================================== bool acceptsMidi() const override { return true; } bool producesMidi() const override { return false; } - bool silenceInProducesSilenceOut() const override { return false; } double getTailLengthSeconds() const override { return 0.0; } //============================================================================== @@ -382,6 +389,7 @@ public: case 1: return "Singing"; case 2: return "Pinched Balloon"; case 3: return "Gazeebo"; + default: break; } return "<Unknown>"; @@ -407,17 +415,18 @@ public: roomSizeParam->setValueNotifyingHost (stream.readFloat()); } + private: //============================================================================== void loadNewSampleBinary (const void* data, int dataSize, const char* format) { - auto* soundBuffer = new MemoryInputStream (data, static_cast<std::size_t> (dataSize), false); - loadNewSample (soundBuffer, format); + auto soundBuffer = std::make_unique<MemoryInputStream> (data, static_cast<std::size_t> (dataSize), false); + loadNewSample (std::move (soundBuffer), format); } - void loadNewSample (InputStream* soundBuffer, const char* format) + void loadNewSample (std::unique_ptr<InputStream> soundBuffer, const char* format) { - std::unique_ptr<AudioFormatReader> formatReader (formatManager.findFormatForFileExtension (format)->createReaderFor (soundBuffer, true)); + std::unique_ptr<AudioFormatReader> formatReader (formatManager.findFormatForFileExtension (format)->createReaderFor (soundBuffer.release(), true)); BigInteger midiNotes; midiNotes.setRange (0, 126, true); diff --git a/examples/Plugins/ArpeggiatorPluginDemo.h b/examples/Plugins/ArpeggiatorPluginDemo.h index 132e1b2c..6232e157 100644 --- a/examples/Plugins/ArpeggiatorPluginDemo.h +++ b/examples/Plugins/ArpeggiatorPluginDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -23,24 +23,26 @@ BEGIN_JUCE_PIP_METADATA - name: ArpeggiatorPlugin - version: 1.0.0 - vendor: JUCE - website: http://juce.com - description: Arpeggiator audio plugin. + name: ArpeggiatorPlugin + version: 1.0.0 + vendor: JUCE + website: http://juce.com + description: Arpeggiator audio plugin. - dependencies: juce_audio_basics, juce_audio_devices, juce_audio_formats, - juce_audio_plugin_client, juce_audio_processors, - juce_audio_utils, juce_core, juce_data_structures, - juce_events, juce_graphics, juce_gui_basics, juce_gui_extra - exporters: xcode_mac, vs2019 + dependencies: juce_audio_basics, juce_audio_devices, juce_audio_formats, + juce_audio_plugin_client, juce_audio_processors, + juce_audio_utils, juce_core, juce_data_structures, + juce_events, juce_graphics, juce_gui_basics, juce_gui_extra + exporters: xcode_mac, vs2019 - moduleFlags: JUCE_STRICT_REFCOUNTEDPOINTER=1 + moduleFlags: JUCE_STRICT_REFCOUNTEDPOINTER=1 - type: AudioProcessor - mainClass: Arpeggiator + type: AudioProcessor + mainClass: Arpeggiator - useLocalCopy: 1 + useLocalCopy: 1 + + pluginCharacteristics: pluginWantsMidiIn, pluginProducesMidiOut, pluginIsMidiEffectPlugin END_JUCE_PIP_METADATA @@ -61,8 +63,6 @@ public: addParameter (speed = new AudioParameterFloat ("speed", "Arpeggiator Speed", 0.0, 1.0, 0.5)); } - ~Arpeggiator() {} - //============================================================================== void prepareToPlay (double sampleRate, int samplesPerBlock) override { @@ -71,7 +71,7 @@ public: notes.clear(); currentNote = 0; lastNoteValue = -1; - time = 0.0; + time = 0; rate = static_cast<float> (sampleRate); } @@ -88,11 +88,9 @@ public: // get note duration auto noteDuration = static_cast<int> (std::ceil (rate * 0.25f * (0.1f + (1.0f - (*speed))))); - MidiMessage msg; - int ignore; - - for (MidiBuffer::Iterator it (midi); it.getNextEvent (msg, ignore);) + for (const auto metadata : midi) { + const auto msg = metadata.getMessage(); if (msg.isNoteOn()) notes.add (msg.getNoteNumber()); else if (msg.isNoteOff()) notes.removeValue (msg.getNoteNumber()); } @@ -121,6 +119,8 @@ public: time = (time + numSamples) % noteDuration; } + using AudioProcessor::processBlock; + //============================================================================== bool isMidiEffect() const override { return true; } diff --git a/examples/Plugins/AudioPluginDemo.h b/examples/Plugins/AudioPluginDemo.h index 4937219b..365e0ab0 100644 --- a/examples/Plugins/AudioPluginDemo.h +++ b/examples/Plugins/AudioPluginDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -23,24 +23,28 @@ BEGIN_JUCE_PIP_METADATA - name: AudioPluginDemo - version: 1.0.0 - vendor: JUCE - website: http://juce.com - description: Synthesiser audio plugin. + name: AudioPluginDemo + version: 1.0.0 + vendor: JUCE + website: http://juce.com + description: Synthesiser audio plugin. - dependencies: juce_audio_basics, juce_audio_devices, juce_audio_formats, - juce_audio_plugin_client, juce_audio_processors, - juce_audio_utils, juce_core, juce_data_structures, - juce_events, juce_graphics, juce_gui_basics, juce_gui_extra - exporters: xcode_mac, vs2017, vs2019, linux_make, xcode_iphone, androidstudio + dependencies: juce_audio_basics, juce_audio_devices, juce_audio_formats, + juce_audio_plugin_client, juce_audio_processors, + juce_audio_utils, juce_core, juce_data_structures, + juce_events, juce_graphics, juce_gui_basics, juce_gui_extra + exporters: xcode_mac, vs2017, vs2019, linux_make, xcode_iphone, androidstudio - moduleFlags: JUCE_STRICT_REFCOUNTEDPOINTER=1 + moduleFlags: JUCE_STRICT_REFCOUNTEDPOINTER=1 - type: AudioProcessor - mainClass: JuceDemoPluginAudioProcessor + type: AudioProcessor + mainClass: JuceDemoPluginAudioProcessor - useLocalCopy: 1 + useLocalCopy: 1 + + pluginCharacteristics: pluginIsSynth, pluginWantsMidiIn, pluginProducesMidiOut, + pluginEditorRequiresKeys + extraPluginFormats: AUv3 END_JUCE_PIP_METADATA @@ -177,12 +181,10 @@ public: //============================================================================== JuceDemoPluginAudioProcessor() : AudioProcessor (getBusesProperties()), - state (*this, nullptr, "state", - { std::make_unique<AudioParameterFloat> ("gain", "Gain", NormalisableRange<float> (0.0f, 1.0f), 0.9f), - std::make_unique<AudioParameterFloat> ("delay", "Delay Feedback", NormalisableRange<float> (0.0f, 1.0f), 0.5f) }) + state (*this, nullptr, "state", + { std::make_unique<AudioParameterFloat> ("gain", "Gain", NormalisableRange<float> (0.0f, 1.0f), 0.9f), + std::make_unique<AudioParameterFloat> ("delay", "Delay Feedback", NormalisableRange<float> (0.0f, 1.0f), 0.5f) }) { - lastPosInfo.resetToDefault(); - // Add a sub-tree to store the state of our UI state.state.addChild ({ "uiState", { { "width", 400 }, { "height", 200 } }, {} }, -1, nullptr); @@ -271,7 +273,7 @@ public: } //============================================================================== - const String getName() const override { return JucePlugin_Name; } + const String getName() const override { return "AudioPluginDemo"; } bool acceptsMidi() const override { return true; } bool producesMidi() const override { return true; } double getTailLengthSeconds() const override { return 0.0; } @@ -302,12 +304,51 @@ public: //============================================================================== void updateTrackProperties (const TrackProperties& properties) override { - trackProperties = properties; + { + const ScopedLock sl (trackPropertiesLock); + trackProperties = properties; + } - if (auto* editor = dynamic_cast<JuceDemoPluginAudioProcessorEditor*> (getActiveEditor())) - editor->updateTrackProperties (); + MessageManager::callAsync ([this] + { + if (auto* editor = dynamic_cast<JuceDemoPluginAudioProcessorEditor*> (getActiveEditor())) + editor->updateTrackProperties(); + }); + } + + TrackProperties getTrackProperties() const + { + const ScopedLock sl (trackPropertiesLock); + return trackProperties; } + class SpinLockedPosInfo + { + public: + SpinLockedPosInfo() { info.resetToDefault(); } + + // Wait-free, but setting new info may fail if the main thread is currently + // calling `get`. This is unlikely to matter in practice because + // we'll be calling `set` much more frequently than `get`. + void set (const AudioPlayHead::CurrentPositionInfo& newInfo) + { + const juce::SpinLock::ScopedTryLockType lock (mutex); + + if (lock.isLocked()) + info = newInfo; + } + + AudioPlayHead::CurrentPositionInfo get() const noexcept + { + const juce::SpinLock::ScopedLockType lock (mutex); + return info; + } + + private: + juce::SpinLock mutex; + AudioPlayHead::CurrentPositionInfo info; + }; + //============================================================================== // These properties are public so that our editor component can access them // A bit of a hacky way to do it, but it's only a demo! Obviously in your own @@ -319,14 +360,11 @@ public: // this keeps a copy of the last set of time info that was acquired during an audio // callback - the UI component will read this and display it. - AudioPlayHead::CurrentPositionInfo lastPosInfo; + SpinLockedPosInfo lastPosInfo; // Our plug-in's current state AudioProcessorValueTreeState state; - // Current track colour and name - TrackProperties trackProperties; - private: //============================================================================== /** This is the editor component that our filter will display. */ @@ -409,7 +447,7 @@ private: void timerCallback() override { - updateTimecodeDisplay (getProcessor().lastPosInfo); + updateTimecodeDisplay (getProcessor().lastPosInfo.get()); } void hostMIDIControllerIsAvailable (bool controllerIsAvailable) override @@ -430,7 +468,7 @@ private: void updateTrackProperties() { - auto trackColour = getProcessor().trackProperties.colour; + auto trackColour = getProcessor().getTrackProperties().colour; auto& lf = getLookAndFeel(); backgroundColour = (trackColour == Colour() ? lf.findColour (ResizableWindow::backgroundColourId) @@ -592,6 +630,9 @@ private: Synthesiser synth; + CriticalSection trackPropertiesLock; + TrackProperties trackProperties; + void initialiseSynth() { auto numVoices = 8; @@ -606,19 +647,23 @@ private: void updateCurrentTimeInfoFromHost() { - if (auto* ph = getPlayHead()) + const auto newInfo = [&] { - AudioPlayHead::CurrentPositionInfo newTime; - - if (ph->getCurrentPosition (newTime)) + if (auto* ph = getPlayHead()) { - lastPosInfo = newTime; // Successfully got the current time from the host.. - return; + AudioPlayHead::CurrentPositionInfo result; + + if (ph->getCurrentPosition (result)) + return result; } - } - // If the host fails to provide the current time, we'll just reset our copy to a default.. - lastPosInfo.resetToDefault(); + // If the host fails to provide the current time, we'll just use default values + AudioPlayHead::CurrentPositionInfo result; + result.resetToDefault(); + return result; + }(); + + lastPosInfo.set (newInfo); } static BusesProperties getBusesProperties() diff --git a/examples/Plugins/CMakeLists.txt b/examples/Plugins/CMakeLists.txt new file mode 100644 index 00000000..272e8475 --- /dev/null +++ b/examples/Plugins/CMakeLists.txt @@ -0,0 +1,24 @@ +# ============================================================================== +# +# This file is part of the JUCE library. +# Copyright (c) 2020 - Raw Material Software Limited +# +# JUCE is an open source library subject to commercial or open-source +# licensing. +# +# By using JUCE, you agree to the terms of both the JUCE 6 End-User License +# Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). +# +# End User License Agreement: www.juce.com/juce-6-licence +# Privacy Policy: www.juce.com/juce-privacy-policy +# +# Or: You may also use this code under the terms of the GPL v3 (see +# www.gnu.org/licenses). +# +# JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER +# EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE +# DISCLAIMED. +# +# ============================================================================== + +_juce_add_pips() diff --git a/examples/Plugins/DSPModulePluginDemo.h b/examples/Plugins/DSPModulePluginDemo.h index 43d4f2ef..afb0d72e 100644 --- a/examples/Plugins/DSPModulePluginDemo.h +++ b/examples/Plugins/DSPModulePluginDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -27,13 +27,13 @@ version: 1.0.0 vendor: JUCE website: http://juce.com - description: Audio plugin using the DSP module. + description: An audio plugin using the DSP module. dependencies: juce_audio_basics, juce_audio_devices, juce_audio_formats, juce_audio_plugin_client, juce_audio_processors, juce_audio_utils, juce_core, juce_data_structures, juce_dsp, juce_events, juce_graphics, juce_gui_basics, juce_gui_extra - exporters: xcode_mac, vs2019 + exporters: xcode_mac, vs2019, linux_make moduleFlags: JUCE_STRICT_REFCOUNTEDPOINTER=1 @@ -50,520 +50,1988 @@ #include "../Assets/DemoUtilities.h" +namespace ID +{ + #define PARAMETER_ID(str) constexpr const char* str { #str }; + + PARAMETER_ID (inputGain) + PARAMETER_ID (outputGain) + PARAMETER_ID (pan) + PARAMETER_ID (distortionEnabled) + PARAMETER_ID (distortionType) + PARAMETER_ID (distortionOversampler) + PARAMETER_ID (distortionLowpass) + PARAMETER_ID (distortionHighpass) + PARAMETER_ID (distortionInGain) + PARAMETER_ID (distortionCompGain) + PARAMETER_ID (distortionMix) + PARAMETER_ID (convolutionCabEnabled) + PARAMETER_ID (convolutionReverbEnabled) + PARAMETER_ID (convolutionReverbMix) + PARAMETER_ID (multiBandEnabled) + PARAMETER_ID (multiBandFreq) + PARAMETER_ID (multiBandLowVolume) + PARAMETER_ID (multiBandHighVolume) + PARAMETER_ID (compressorEnabled) + PARAMETER_ID (compressorThreshold) + PARAMETER_ID (compressorRatio) + PARAMETER_ID (compressorAttack) + PARAMETER_ID (compressorRelease) + PARAMETER_ID (noiseGateEnabled) + PARAMETER_ID (noiseGateThreshold) + PARAMETER_ID (noiseGateRatio) + PARAMETER_ID (noiseGateAttack) + PARAMETER_ID (noiseGateRelease) + PARAMETER_ID (limiterEnabled) + PARAMETER_ID (limiterThreshold) + PARAMETER_ID (limiterRelease) + PARAMETER_ID (directDelayEnabled) + PARAMETER_ID (directDelayType) + PARAMETER_ID (directDelayValue) + PARAMETER_ID (directDelaySmoothing) + PARAMETER_ID (directDelayMix) + PARAMETER_ID (delayEffectEnabled) + PARAMETER_ID (delayEffectType) + PARAMETER_ID (delayEffectValue) + PARAMETER_ID (delayEffectSmoothing) + PARAMETER_ID (delayEffectLowpass) + PARAMETER_ID (delayEffectFeedback) + PARAMETER_ID (delayEffectMix) + PARAMETER_ID (phaserEnabled) + PARAMETER_ID (phaserRate) + PARAMETER_ID (phaserDepth) + PARAMETER_ID (phaserCentreFrequency) + PARAMETER_ID (phaserFeedback) + PARAMETER_ID (phaserMix) + PARAMETER_ID (chorusEnabled) + PARAMETER_ID (chorusRate) + PARAMETER_ID (chorusDepth) + PARAMETER_ID (chorusCentreDelay) + PARAMETER_ID (chorusFeedback) + PARAMETER_ID (chorusMix) + PARAMETER_ID (ladderEnabled) + PARAMETER_ID (ladderCutoff) + PARAMETER_ID (ladderResonance) + PARAMETER_ID (ladderDrive) + PARAMETER_ID (ladderMode) + + #undef PARAMETER_ID +} + +template <typename Func, typename... Items> +constexpr void forEach (Func&& func, Items&&... items) + noexcept (noexcept (std::initializer_list<int> { (func (std::forward<Items> (items)), 0)... })) +{ + (void) std::initializer_list<int> { ((void) func (std::forward<Items> (items)), 0)... }; +} + +template <typename... Components> +void addAllAndMakeVisible (Component& target, Components&... children) +{ + forEach ([&] (Component& child) { target.addAndMakeVisible (child); }, children...); +} + +template <typename... Processors> +void prepareAll (const dsp::ProcessSpec& spec, Processors&... processors) +{ + forEach ([&] (auto& proc) { proc.prepare (spec); }, processors...); +} + +template <typename... Processors> +void resetAll (Processors&... processors) +{ + forEach ([] (auto& proc) { proc.reset(); }, processors...); +} + //============================================================================== -struct ParameterSlider : public Slider, - public Timer +class DspModulePluginDemo : public AudioProcessor, + private ValueTree::Listener { - ParameterSlider (AudioProcessorParameter& p) - : Slider (p.getName (256)), param (p) +public: + DspModulePluginDemo() + : DspModulePluginDemo (AudioProcessorValueTreeState::ParameterLayout{}) {} + + //============================================================================== + void prepareToPlay (double sampleRate, int samplesPerBlock) override { - setRange (0.0, 1.0, 0.0); - startTimerHz (30); - updateSliderPos(); + const auto channels = jmax (getTotalNumInputChannels(), getTotalNumOutputChannels()); + + if (channels == 0) + return; + + chain.prepare ({ sampleRate, (uint32) samplesPerBlock, (uint32) channels }); + + reset(); } - void valueChanged() override + void reset() override { - if (isMouseButtonDown()) - param.setValueNotifyingHost ((float) Slider::getValue()); - else - param.setValue ((float) Slider::getValue()); + chain.reset(); + update(); } - void timerCallback() override { updateSliderPos(); } + void releaseResources() override {} + + void processBlock (AudioBuffer<float>& buffer, MidiBuffer&) override + { + if (jmax (getTotalNumInputChannels(), getTotalNumOutputChannels()) == 0) + return; - void startedDragging() override { param.beginChangeGesture(); } - void stoppedDragging() override { param.endChangeGesture(); } + ScopedNoDenormals noDenormals; - double getValueFromText (const String& text) override { return param.getValueForText (text); } - String getTextFromValue (double value) override { return param.getText ((float) value, 1024) + " " + param.getLabel(); } + if (requiresUpdate.load()) + update(); - void updateSliderPos() - { - auto newValue = param.getValue(); + irSize = dsp::get<convolutionIndex> (chain).reverb.getCurrentIRSize(); + + const auto totalNumInputChannels = getTotalNumInputChannels(); + const auto totalNumOutputChannels = getTotalNumOutputChannels(); - if (newValue != (float) Slider::getValue() && ! isMouseButtonDown()) - Slider::setValue (newValue); + setLatencySamples (dsp::get<convolutionIndex> (chain).getLatency() + + (dsp::isBypassed<distortionIndex> (chain) ? 0 : roundToInt (dsp::get<distortionIndex> (chain).getLatency()))); + + const auto numChannels = jmax (totalNumInputChannels, totalNumOutputChannels); + + auto inoutBlock = dsp::AudioBlock<float> (buffer).getSubsetChannelBlock (0, (size_t) numChannels); + chain.process (dsp::ProcessContextReplacing<float> (inoutBlock)); } - AudioProcessorParameter& param; -}; + void processBlock (AudioBuffer<double>&, MidiBuffer&) override {} -//============================================================================== -/** - This class handles the audio processing for the DSP module plugin demo. -*/ -class DspModulePluginDemoAudioProcessor : public AudioProcessor -{ -public: //============================================================================== - DspModulePluginDemoAudioProcessor() - : AudioProcessor (BusesProperties().withInput ("Input", AudioChannelSet::stereo(), true) - .withOutput ("Output", AudioChannelSet::stereo(), true)), - lowPassFilter (dsp::IIR::Coefficients<float>::makeFirstOrderLowPass (48000.0, 20000.0f)), - highPassFilter (dsp::IIR::Coefficients<float>::makeFirstOrderHighPass (48000.0, 20.0f)), - waveShapers { { std::tanh }, { dsp::FastMathApproximations::tanh } }, - clipping { clip } - { - // Oversampling 2 times with IIR filtering - oversampling.reset (new dsp::Oversampling<float> (2, 1, dsp::Oversampling<float>::filterHalfBandPolyphaseIIR, false)); + AudioProcessorEditor* createEditor() override { return nullptr; } + bool hasEditor() const override { return false; } + + //============================================================================== + const String getName() const override { return "DSPModulePluginDemo"; } - addParameter (inputVolumeParam = new AudioParameterFloat ("INPUT", "Input Volume", { 0.0f, 60.0f, 0.0f, 1.0f }, 0.0f, "dB")); - addParameter (highPassFilterFreqParam = new AudioParameterFloat ("HPFREQ", "Pre Highpass Freq.", { 20.0f, 20000.0f, 0.0f, 0.5f }, 20.0f, "Hz")); - addParameter (lowPassFilterFreqParam = new AudioParameterFloat ("LPFREQ", "Post Lowpass Freq.", { 20.0f, 20000.0f, 0.0f, 0.5f }, 20000.0f, "Hz")); + bool acceptsMidi() const override { return false; } + bool producesMidi() const override { return false; } + bool isMidiEffect() const override { return false; } - addParameter (stereoParam = new AudioParameterChoice ("STEREO", "Stereo Processing", { "Always mono", "Yes" }, 1)); - addParameter (slopeParam = new AudioParameterChoice ("SLOPE", "Slope", { "-6 dB / octave", "-12 dB / octave" }, 0)); - addParameter (waveshaperParam = new AudioParameterChoice ("WVSHP", "Waveshaper", { "std::tanh", "Fast tanh approx." }, 0)); + double getTailLengthSeconds() const override { return 0.0; } - addParameter (cabinetTypeParam = new AudioParameterChoice ("CABTYPE", "Cabinet Type", { "Guitar amplifier 8'' cabinet ", - "Cassette recorder cabinet" }, 0)); + //============================================================================== + int getNumPrograms() override { return 1; } + int getCurrentProgram() override { return 0; } + void setCurrentProgram (int) override {} + const String getProgramName (int) override { return {}; } - addParameter (cabinetSimParam = new AudioParameterBool ("CABSIM", "Cabinet Sim", false)); - addParameter (oversamplingParam = new AudioParameterBool ("OVERS", "Oversampling", false)); + void changeProgramName (int, const String&) override {} - addParameter (outputVolumeParam = new AudioParameterFloat ("OUTPUT", "Output Volume", { -40.0f, 40.0f, 0.0f, 1.0f }, 0.0f, "dB")); + //============================================================================== + void getStateInformation (MemoryBlock& destData) override + { + copyXmlToBinary (*apvts.copyState().createXml(), destData); + } - cabinetType.set (0); + void setStateInformation (const void* data, int sizeInBytes) override + { + apvts.replaceState (ValueTree::fromXml (*getXmlFromBinary (data, sizeInBytes))); } - ~DspModulePluginDemoAudioProcessor() {} + int getCurrentIRSize() const { return irSize; } + + using Parameter = AudioProcessorValueTreeState::Parameter; + + // This struct holds references to the raw parameters, so that we don't have to search + // the APVTS (involving string comparisons and map lookups!) every time a parameter + // changes. + struct ParameterReferences + { + template <typename Param> + static Param& addToLayout (AudioProcessorValueTreeState::ParameterLayout& layout, + std::unique_ptr<Param> param) + { + auto& ref = *param; + layout.add (std::move (param)); + return ref; + } + + static String valueToTextFunction (float x) { return String (x, 2); } + static float textToValueFunction (const String& str) { return str.getFloatValue(); } + + static String valueToTextPanFunction (float x) { return getPanningTextForValue ((x + 100.0f) / 200.0f); } + static float textToValuePanFunction (const String& str) { return getPanningValueForText (str) * 200.0f - 100.0f; } + + // Creates parameters, adds them to the layout, and stores references to the parameters + // in this struct. + explicit ParameterReferences (AudioProcessorValueTreeState::ParameterLayout& layout) + : inputGain (addToLayout (layout, + std::make_unique<Parameter> (ID::inputGain, + "Input", + "dB", + NormalisableRange<float> (-40.0f, 40.0f), + 0.0f, + valueToTextFunction, + textToValueFunction))), + outputGain (addToLayout (layout, + std::make_unique<Parameter> (ID::outputGain, + "Output", + "dB", + NormalisableRange<float> (-40.0f, 40.0f), + 0.0f, + valueToTextFunction, + textToValueFunction))), + pan (addToLayout (layout, + std::make_unique<Parameter> (ID::pan, + "Panning", + "", + NormalisableRange<float> (-100.0f, 100.0f), + 0.0f, + valueToTextPanFunction, + textToValuePanFunction))), + distortionEnabled (addToLayout (layout, + std::make_unique<AudioParameterBool> (ID::distortionEnabled, + "Distortion", + true, + ""))), + distortionType (addToLayout (layout, + std::make_unique<AudioParameterChoice> (ID::distortionType, + "Waveshaper", + StringArray { "std::tanh", "Approx. tanh" }, + 0))), + distortionInGain (addToLayout (layout, + std::make_unique<Parameter> (ID::distortionInGain, + "Gain", + "dB", + NormalisableRange<float> (-40.0f, 40.0f), + 0.0f, + valueToTextFunction, + textToValueFunction))), + distortionLowpass (addToLayout (layout, + std::make_unique<Parameter> (ID::distortionLowpass, + "Post Low-pass", + "Hz", + NormalisableRange<float> (20.0f, 22000.0f, 0.0f, 0.25f), + 22000.0f, + valueToTextFunction, + textToValueFunction))), + distortionHighpass (addToLayout (layout, + std::make_unique<Parameter> (ID::distortionHighpass, + "Pre High-pass", + "Hz", + NormalisableRange<float> (20.0f, 22000.0f, 0.0f, 0.25f), + 20.0f, + valueToTextFunction, + textToValueFunction))), + distortionCompGain (addToLayout (layout, + std::make_unique<Parameter> (ID::distortionCompGain, + "Compensat.", + "dB", + NormalisableRange<float> (-40.0f, 40.0f), + 0.0f, + valueToTextFunction, + textToValueFunction))), + distortionMix (addToLayout (layout, + std::make_unique<Parameter> (ID::distortionMix, + "Mix", + "%", + NormalisableRange<float> (0.0f, 100.0f), + 100.0f, + valueToTextFunction, + textToValueFunction))), + distortionOversampler (addToLayout (layout, + std::make_unique<AudioParameterChoice> (ID::distortionOversampler, + "Oversampling", + StringArray { "2X", "4X", "8X", "2X compensated", "4X compensated", "8X compensated" }, + 1))), + multiBandEnabled (addToLayout (layout, + std::make_unique<AudioParameterBool> (ID::multiBandEnabled, + "Multi-band", + false, + ""))), + multiBandFreq (addToLayout (layout, + std::make_unique<Parameter> (ID::multiBandFreq, + "Sep. Freq.", + "Hz", + NormalisableRange<float> (20.0f, 22000.0f, 0.0f, 0.25f), + 2000.0f, + valueToTextFunction, + textToValueFunction))), + multiBandLowVolume (addToLayout (layout, + std::make_unique<Parameter> (ID::multiBandLowVolume, + "Low volume", + "dB", + NormalisableRange<float> (-40.0f, 40.0f), + 0.0f, + valueToTextFunction, + textToValueFunction))), + multiBandHighVolume (addToLayout (layout, + std::make_unique<Parameter> (ID::multiBandHighVolume, + "High volume", + "dB", + NormalisableRange<float> (-40.0f, 40.0f), + 0.0f, + valueToTextFunction, + textToValueFunction))), + convolutionCabEnabled (addToLayout (layout, + std::make_unique<AudioParameterBool> (ID::convolutionCabEnabled, + "Cabinet", + false, + ""))), + convolutionReverbEnabled (addToLayout (layout, + std::make_unique<AudioParameterBool> (ID::convolutionReverbEnabled, + "Reverb", + false, + ""))), + convolutionReverbMix (addToLayout (layout, + std::make_unique<Parameter> (ID::convolutionReverbMix, + "Reverb Mix", + "%", + NormalisableRange<float> (0.0f, 100.0f), + 50.0f, + valueToTextFunction, + textToValueFunction))), + compressorEnabled (addToLayout (layout, + std::make_unique<AudioParameterBool> (ID::compressorEnabled, + "Comp.", + false, + ""))), + compressorThreshold (addToLayout (layout, + std::make_unique<Parameter> (ID::compressorThreshold, + "Threshold", + "dB", + NormalisableRange<float> (-100.0f, 0.0f), + 0.0f, + valueToTextFunction, + textToValueFunction))), + compressorRatio (addToLayout (layout, + std::make_unique<Parameter> (ID::compressorRatio, + "Ratio", + ":1", + NormalisableRange<float> (1.0f, 100.0f, 0.0f, 0.25f), + 1.0f, + valueToTextFunction, + textToValueFunction))), + compressorAttack (addToLayout (layout, + std::make_unique<Parameter> (ID::compressorAttack, + "Attack", + "ms", + NormalisableRange<float> (0.01f, 1000.0f, 0.0f, 0.25f), + 1.0f, + valueToTextFunction, + textToValueFunction))), + compressorRelease (addToLayout (layout, + std::make_unique<Parameter> (ID::compressorRelease, + "Release", + "ms", + NormalisableRange<float> (10.0f, 10000.0f, 0.0f, 0.25f), + 100.0f, + valueToTextFunction, + textToValueFunction))), + noiseGateEnabled (addToLayout (layout, + std::make_unique<AudioParameterBool> (ID::noiseGateEnabled, + "Gate", + false, + ""))), + noiseGateThreshold (addToLayout (layout, + std::make_unique<Parameter> (ID::noiseGateThreshold, + "Threshold", + "dB", + NormalisableRange<float> (-100.0f, 0.0f), + -100.0f, + valueToTextFunction, + textToValueFunction))), + noiseGateRatio (addToLayout (layout, + std::make_unique<Parameter> (ID::noiseGateRatio, + "Ratio", + ":1", + NormalisableRange<float> (1.0f, 100.0f, 0.0f, 0.25f), + 10.0f, + valueToTextFunction, + textToValueFunction))), + noiseGateAttack (addToLayout (layout, + std::make_unique<Parameter> (ID::noiseGateAttack, + "Attack", + "ms", + NormalisableRange<float> (0.01f, 1000.0f, 0.0f, 0.25f), + 1.0f, + valueToTextFunction, + textToValueFunction))), + noiseGateRelease (addToLayout (layout, + std::make_unique<Parameter> (ID::noiseGateRelease, + "Release", + "ms", + NormalisableRange<float> (10.0f, 10000.0f, 0.0f, 0.25f), + 100.0f, + valueToTextFunction, + textToValueFunction))), + limiterEnabled (addToLayout (layout, + std::make_unique<AudioParameterBool> (ID::limiterEnabled, + "Limiter", + false, + ""))), + limiterThreshold (addToLayout (layout, + std::make_unique<Parameter> (ID::limiterThreshold, + "Threshold", + "dB", + NormalisableRange<float> (-40.0f, 0.0f), + 0.0f, + valueToTextFunction, + textToValueFunction))), + limiterRelease (addToLayout (layout, + std::make_unique<Parameter> (ID::limiterRelease, + "Release", + "ms", + NormalisableRange<float> (10.0f, 10000.0f, 0.0f, 0.25f), + 100.0f, + valueToTextFunction, + textToValueFunction))), + directDelayEnabled (addToLayout (layout, + std::make_unique<AudioParameterBool> (ID::directDelayEnabled, + "DL Dir.", + false, + ""))), + directDelayType (addToLayout (layout, + std::make_unique<AudioParameterChoice> (ID::directDelayType, + "DL Type", + StringArray { "None", "Linear", "Lagrange", "Thiran" }, + 1))), + directDelayValue (addToLayout (layout, + std::make_unique<Parameter> (ID::directDelayValue, + "Delay", + "smps", + NormalisableRange<float> (0.0f, 44100.0f), + 0.0f, + valueToTextFunction, + textToValueFunction))), + directDelaySmoothing (addToLayout (layout, + std::make_unique<Parameter> (ID::directDelaySmoothing, + "Smooth", + "ms", + NormalisableRange<float> (20.0f, 10000.0f, 0.0f, 0.25f), + 200.0f, + valueToTextFunction, + textToValueFunction))), + directDelayMix (addToLayout (layout, + std::make_unique<Parameter> (ID::directDelayMix, + "Delay Mix", + "%", + NormalisableRange<float> (0.0f, 100.0f), + 50.0f, + valueToTextFunction, + textToValueFunction))), + delayEffectEnabled (addToLayout (layout, + std::make_unique<AudioParameterBool> (ID::delayEffectEnabled, + "DL Effect", + false, + ""))), + delayEffectType (addToLayout (layout, + std::make_unique<AudioParameterChoice> (ID::delayEffectType, + "DL Type", + StringArray { "None", "Linear", "Lagrange", "Thiran" }, + 1))), + delayEffectValue (addToLayout (layout, + std::make_unique<Parameter> (ID::delayEffectValue, + "Delay", + "ms", + NormalisableRange<float> (0.01f, 1000.0f), + 100.0f, + valueToTextFunction, + textToValueFunction))), + delayEffectSmoothing (addToLayout (layout, + std::make_unique<Parameter> (ID::delayEffectSmoothing, + "Smooth", + "ms", + NormalisableRange<float> (20.0f, 10000.0f, 0.0f, 0.25f), + 400.0f, + valueToTextFunction, + textToValueFunction))), + delayEffectLowpass (addToLayout (layout, + std::make_unique<Parameter> (ID::delayEffectLowpass, + "Low-pass", + "Hz", + NormalisableRange<float> (20.0f, 22000.0f, 0.0f, 0.25f), + 22000.0f, + valueToTextFunction, + textToValueFunction))), + delayEffectMix (addToLayout (layout, + std::make_unique<Parameter> (ID::delayEffectMix, + "Delay Mix", + "%", + NormalisableRange<float> (0.0f, 100.0f), + 50.0f, + valueToTextFunction, + textToValueFunction))), + delayEffectFeedback (addToLayout (layout, + std::make_unique<Parameter> (ID::delayEffectFeedback, + "Feedback", + "dB", + NormalisableRange<float> (-100.0f, 0.0f), + -100.0f, + valueToTextFunction, + textToValueFunction))), + phaserEnabled (addToLayout (layout, + std::make_unique<AudioParameterBool> (ID::phaserEnabled, + "Phaser", + false, + ""))), + phaserRate (addToLayout (layout, + std::make_unique<Parameter> (ID::phaserRate, + "Rate", + "Hz", + NormalisableRange<float> (0.05f, 20.0f, 0.0f, 0.25f), + 1.0f, + valueToTextFunction, + textToValueFunction))), + phaserDepth (addToLayout (layout, + std::make_unique<Parameter> (ID::phaserDepth, + "Depth", + "%", + NormalisableRange<float> (0.0f, 100.0f), + 50.0f, + valueToTextFunction, + textToValueFunction))), + phaserCentreFrequency (addToLayout (layout, + std::make_unique<Parameter> (ID::phaserCentreFrequency, + "Center", + "Hz", + NormalisableRange<float> (20.0f, 20000.0f, 0.0f, 0.25f), + 600.0f, + valueToTextFunction, + textToValueFunction))), + phaserFeedback (addToLayout (layout, + std::make_unique<Parameter> (ID::phaserFeedback, + "Feedback", + "%", + NormalisableRange<float> (0.0f, 100.0f), + 50.0f, + valueToTextFunction, + textToValueFunction))), + phaserMix (addToLayout (layout, + std::make_unique<Parameter> (ID::phaserMix, + "Mix", + "%", + NormalisableRange<float> (0.0f, 100.0f), + 50.0f, + valueToTextFunction, + textToValueFunction))), + chorusEnabled (addToLayout (layout, + std::make_unique<AudioParameterBool> (ID::chorusEnabled, + "Chorus", + false, + ""))), + chorusRate (addToLayout (layout, + std::make_unique<Parameter> (ID::chorusRate, + "Rate", + "Hz", + NormalisableRange<float> (0.05f, 20.0f, 0.0f, 0.25f), + 1.0f, + valueToTextFunction, + textToValueFunction))), + chorusDepth (addToLayout (layout, + std::make_unique<Parameter> (ID::chorusDepth, + "Depth", + "%", + NormalisableRange<float> (0.0f, 100.0f), + 50.0f, + valueToTextFunction, + textToValueFunction))), + chorusCentreDelay (addToLayout (layout, + std::make_unique<Parameter> (ID::chorusCentreDelay, + "Center", + "ms", + NormalisableRange<float> (1.0f, 100.0f, 0.0f, 0.25f), + 7.0f, + valueToTextFunction, + textToValueFunction))), + chorusFeedback (addToLayout (layout, + std::make_unique<Parameter> (ID::chorusFeedback, + "Feedback", + "%", + NormalisableRange<float> (0.0f, 100.0f), + 50.0f, + valueToTextFunction, + textToValueFunction))), + chorusMix (addToLayout (layout, + std::make_unique<Parameter> (ID::chorusMix, + "Mix", + "%", + NormalisableRange<float> (0.0f, 100.0f), + 50.0f, + valueToTextFunction, + textToValueFunction))), + ladderEnabled (addToLayout (layout, + std::make_unique<AudioParameterBool> (ID::ladderEnabled, + "Ladder", + false, + ""))), + ladderMode (addToLayout (layout, + std::make_unique<AudioParameterChoice> (ID::ladderMode, + "Mode", + StringArray { "LP12", "LP24", "HP12", "HP24", "BP12", "BP24" }, + 1))), + ladderCutoff (addToLayout (layout, + std::make_unique<Parameter> (ID::ladderCutoff, + "Frequency", + "Hz", + NormalisableRange<float> (10.0f, 22000.0f, 0.0f, 0.25f), + 1000.0f, + valueToTextFunction, + textToValueFunction))), + ladderResonance (addToLayout (layout, + std::make_unique<Parameter> (ID::ladderResonance, + "Resonance", + "%", + NormalisableRange<float> (0.0f, 100.0f), + 0.0f, + valueToTextFunction, + textToValueFunction))), + ladderDrive (addToLayout (layout, + std::make_unique<Parameter> (ID::ladderDrive, + "Drive", + "dB", + NormalisableRange<float> (0.0f, 40.0f), + 0.0f, + valueToTextFunction, + textToValueFunction))) + {} + + Parameter& inputGain; + Parameter& outputGain; + Parameter& pan; + + AudioParameterBool& distortionEnabled; + AudioParameterChoice& distortionType; + Parameter& distortionInGain; + Parameter& distortionLowpass; + Parameter& distortionHighpass; + Parameter& distortionCompGain; + Parameter& distortionMix; + AudioParameterChoice& distortionOversampler; + + AudioParameterBool& multiBandEnabled; + Parameter& multiBandFreq; + Parameter& multiBandLowVolume; + Parameter& multiBandHighVolume; + + AudioParameterBool& convolutionCabEnabled; + AudioParameterBool& convolutionReverbEnabled; + Parameter& convolutionReverbMix; + + AudioParameterBool& compressorEnabled; + Parameter& compressorThreshold; + Parameter& compressorRatio; + Parameter& compressorAttack; + Parameter& compressorRelease; + + AudioParameterBool& noiseGateEnabled; + Parameter& noiseGateThreshold; + Parameter& noiseGateRatio; + Parameter& noiseGateAttack; + Parameter& noiseGateRelease; + + AudioParameterBool& limiterEnabled; + Parameter& limiterThreshold; + Parameter& limiterRelease; + + AudioParameterBool& directDelayEnabled; + AudioParameterChoice& directDelayType; + Parameter& directDelayValue; + Parameter& directDelaySmoothing; + Parameter& directDelayMix; + + AudioParameterBool& delayEffectEnabled; + AudioParameterChoice& delayEffectType; + Parameter& delayEffectValue; + Parameter& delayEffectSmoothing; + Parameter& delayEffectLowpass; + Parameter& delayEffectMix; + Parameter& delayEffectFeedback; + + AudioParameterBool& phaserEnabled; + Parameter& phaserRate; + Parameter& phaserDepth; + Parameter& phaserCentreFrequency; + Parameter& phaserFeedback; + Parameter& phaserMix; + + AudioParameterBool& chorusEnabled; + Parameter& chorusRate; + Parameter& chorusDepth; + Parameter& chorusCentreDelay; + Parameter& chorusFeedback; + Parameter& chorusMix; + + AudioParameterBool& ladderEnabled; + AudioParameterChoice& ladderMode; + Parameter& ladderCutoff; + Parameter& ladderResonance; + Parameter& ladderDrive; + }; + + const ParameterReferences& getParameterValues() const noexcept { return parameters; } //============================================================================== - bool isBusesLayoutSupported (const BusesLayout& layouts) const override + // We store this here so that the editor retains its state if it is closed and reopened + int indexTab = 0; + +private: + struct LayoutAndReferences + { + AudioProcessorValueTreeState::ParameterLayout layout; + ParameterReferences references; + }; + + explicit DspModulePluginDemo (AudioProcessorValueTreeState::ParameterLayout layout) + : AudioProcessor (BusesProperties().withInput ("In", AudioChannelSet::stereo()) + .withOutput ("Out", AudioChannelSet::stereo())), + parameters { layout }, + apvts { *this, nullptr, "state", std::move (layout) } { - // This is the place where you check if the layout is supported. - // In this template code we only support mono or stereo. - if (layouts.getMainOutputChannelSet() != AudioChannelSet::mono() && layouts.getMainOutputChannelSet() != AudioChannelSet::stereo()) - return false; + apvts.state.addListener (this); - // This checks if the input layout matches the output layout - if (layouts.getMainOutputChannelSet() != layouts.getMainInputChannelSet()) - return false; + forEach ([] (dsp::Gain<float>& gain) { gain.setRampDurationSeconds (0.05); }, + dsp::get<inputGainIndex> (chain), + dsp::get<outputGainIndex> (chain)); - return true; + dsp::get<pannerIndex> (chain).setRule (dsp::PannerRule::linear); } - void prepareToPlay (double sampleRate, int samplesPerBlock) override + //============================================================================== + void valueTreePropertyChanged (ValueTree&, const Identifier&) override { - auto channels = static_cast<uint32> (jmin (getMainBusNumInputChannels(), getMainBusNumOutputChannels())); - dsp::ProcessSpec spec { sampleRate, static_cast<uint32> (samplesPerBlock), channels }; + requiresUpdate.store (true); + } + + //============================================================================== + void update() + { + { + DistortionProcessor& distortion = dsp::get<distortionIndex> (chain); - lowPassFilter .prepare (spec); - highPassFilter.prepare (spec); + if (distortion.currentIndexOversampling != parameters.distortionOversampler.getIndex()) + { + distortion.currentIndexOversampling = parameters.distortionOversampler.getIndex(); + prepareToPlay (getSampleRate(), getBlockSize()); + return; + } - inputVolume .prepare (spec); - outputVolume.prepare (spec); + distortion.currentIndexWaveshaper = parameters.distortionType.getIndex(); + distortion.lowpass .setCutoffFrequency (parameters.distortionLowpass.get()); + distortion.highpass.setCutoffFrequency (parameters.distortionHighpass.get()); + distortion.distGain.setGainDecibels (parameters.distortionInGain.get()); + distortion.compGain.setGainDecibels (parameters.distortionCompGain.get()); + distortion.mixer.setWetMixProportion (parameters.distortionMix.get() / 100.0f); + dsp::setBypassed<distortionIndex> (chain, ! parameters.distortionEnabled); + } - convolution.prepare (spec); - cabinetType.set (-1); + { + ConvolutionProcessor& convolution = dsp::get<convolutionIndex> (chain); + convolution.cabEnabled = parameters.convolutionCabEnabled; + convolution.reverbEnabled = parameters.convolutionReverbEnabled; + convolution.mixer.setWetMixProportion (parameters.convolutionReverbMix.get() / 100.0f); + } - oversampling->initProcessing (static_cast<size_t> (samplesPerBlock)); + dsp::get<inputGainIndex> (chain).setGainDecibels (parameters.inputGain.get()); + dsp::get<outputGainIndex> (chain).setGainDecibels (parameters.outputGain.get()); + dsp::get<pannerIndex> (chain).setPan (parameters.pan.get() / 100.0f); - updateParameters(); - reset(); - } + { + MultiBandProcessor& multiband = dsp::get<multiBandIndex> (chain); + const auto multibandFreq = parameters.multiBandFreq.get(); + multiband.lowpass .setCutoffFrequency (multibandFreq); + multiband.highpass.setCutoffFrequency (multibandFreq); + const bool enabled = parameters.multiBandEnabled; + multiband.lowVolume .setGainDecibels (enabled ? parameters.multiBandLowVolume .get() : 0.0f); + multiband.highVolume.setGainDecibels (enabled ? parameters.multiBandHighVolume.get() : 0.0f); + dsp::setBypassed<multiBandIndex> (chain, ! enabled); + } - void releaseResources() override {} + { + dsp::Compressor<float>& compressor = dsp::get<compressorIndex> (chain); + compressor.setThreshold (parameters.compressorThreshold.get()); + compressor.setRatio (parameters.compressorRatio.get()); + compressor.setAttack (parameters.compressorAttack.get()); + compressor.setRelease (parameters.compressorRelease.get()); + dsp::setBypassed<compressorIndex> (chain, ! parameters.compressorEnabled); + } - void processBlock (AudioBuffer<float>& inoutBuffer, MidiBuffer&) override - { - auto totalNumInputChannels = getTotalNumInputChannels(); - auto totalNumOutputChannels = getTotalNumOutputChannels(); + { + dsp::NoiseGate<float>& noiseGate = dsp::get<noiseGateIndex> (chain); + noiseGate.setThreshold (parameters.noiseGateThreshold.get()); + noiseGate.setRatio (parameters.noiseGateRatio.get()); + noiseGate.setAttack (parameters.noiseGateAttack.get()); + noiseGate.setRelease (parameters.noiseGateRelease.get()); + dsp::setBypassed<noiseGateIndex> (chain, ! parameters.noiseGateEnabled); + } + + { + dsp::Limiter<float>& limiter = dsp::get<limiterIndex> (chain); + limiter.setThreshold (parameters.limiterThreshold.get()); + limiter.setRelease (parameters.limiterRelease.get()); + dsp::setBypassed<limiterIndex> (chain, ! parameters.limiterEnabled); + } + + { + DirectDelayProcessor& delay = dsp::get<directDelayIndex> (chain); + delay.delayLineDirectType = parameters.directDelayType.getIndex(); + + std::fill (delay.delayDirectValue.begin(), + delay.delayDirectValue.end(), + (double) parameters.directDelayValue.get()); + + delay.smoothFilter.setCutoffFrequency (1000.0 / parameters.directDelaySmoothing.get()); + delay.mixer.setWetMixProportion (parameters.directDelayMix.get() / 100.0f); + dsp::setBypassed<directDelayIndex> (chain, ! parameters.directDelayEnabled); + } + + { + DelayEffectProcessor& delay = dsp::get<delayEffectIndex> (chain); + delay.delayEffectType = parameters.delayEffectType.getIndex(); - auto numSamples = inoutBuffer.getNumSamples(); + std::fill (delay.delayEffectValue.begin(), + delay.delayEffectValue.end(), + (double) parameters.delayEffectValue.get() / 1000.0 * getSampleRate()); - for (auto i = jmin (2, totalNumInputChannels); i < totalNumOutputChannels; ++i) - inoutBuffer.clear (i, 0, numSamples); + const auto feedbackGain = Decibels::decibelsToGain (parameters.delayEffectFeedback.get(), -100.0f); - updateParameters(); + for (auto& volume : delay.delayFeedbackVolume) + volume.setTargetValue (feedbackGain); - dsp::AudioBlock<float> block (inoutBuffer); + delay.smoothFilter.setCutoffFrequency (1000.0 / parameters.delayEffectSmoothing.get()); + delay.lowpass.setCutoffFrequency (parameters.delayEffectLowpass.get()); + delay.mixer.setWetMixProportion (parameters.delayEffectMix.get() / 100.0f); + dsp::setBypassed<delayEffectIndex> (chain, ! parameters.delayEffectEnabled); + } - if (stereoParam->getIndex() == 1) { - // Stereo processing mode: - if (block.getNumChannels() > 2) - block = block.getSubsetChannelBlock (0, 2); + dsp::Phaser<float>& phaser = dsp::get<phaserIndex> (chain); + phaser.setRate (parameters.phaserRate.get()); + phaser.setDepth (parameters.phaserDepth.get() / 100.0f); + phaser.setCentreFrequency (parameters.phaserCentreFrequency.get()); + phaser.setFeedback (parameters.phaserFeedback.get() / 100.0f * 0.95f); + phaser.setMix (parameters.phaserMix.get() / 100.0f); + dsp::setBypassed<phaserIndex> (chain, ! parameters.phaserEnabled); + } - process (dsp::ProcessContextReplacing<float> (block)); + { + dsp::Chorus<float>& chorus = dsp::get<chorusIndex> (chain); + chorus.setRate (parameters.chorusRate.get()); + chorus.setDepth (parameters.chorusDepth.get() / 100.0f); + chorus.setCentreDelay (parameters.chorusCentreDelay.get()); + chorus.setFeedback (parameters.chorusFeedback.get() / 100.0f * 0.95f); + chorus.setMix (parameters.chorusMix.get() / 100.0f); + dsp::setBypassed<chorusIndex> (chain, ! parameters.chorusEnabled); } - else + { - // Mono processing mode: - auto firstChan = block.getSingleChannelBlock (0); + dsp::LadderFilter<float>& ladder = dsp::get<ladderIndex> (chain); + + ladder.setCutoffFrequencyHz (parameters.ladderCutoff.get()); + ladder.setResonance (parameters.ladderResonance.get() / 100.0f); + ladder.setDrive (Decibels::decibelsToGain (parameters.ladderDrive.get())); + + ladder.setMode ([&] + { + switch (parameters.ladderMode.getIndex()) + { + case 0: return dsp::LadderFilterMode::LPF12; + case 1: return dsp::LadderFilterMode::LPF24; + case 2: return dsp::LadderFilterMode::HPF12; + case 3: return dsp::LadderFilterMode::HPF24; + case 4: return dsp::LadderFilterMode::BPF12; + + default: break; + } - process (dsp::ProcessContextReplacing<float> (firstChan)); + return dsp::LadderFilterMode::BPF24; + }()); - for (size_t chan = 1; chan < block.getNumChannels(); ++chan) - block.getSingleChannelBlock (chan).copyFrom (firstChan); + dsp::setBypassed<ladderIndex> (chain, ! parameters.ladderEnabled); } - } - void reset() override - { - lowPassFilter .reset(); - highPassFilter.reset(); - convolution .reset(); - oversampling->reset(); + requiresUpdate.store (false); } //============================================================================== - bool hasEditor() const override { return true; } + static String getPanningTextForValue (float value) + { + if (value == 0.5f) + return "center"; - AudioProcessorEditor* createEditor() override + if (value < 0.5f) + return String (roundToInt ((0.5f - value) * 200.0f)) + "%L"; + + return String (roundToInt ((value - 0.5f) * 200.0f)) + "%R"; + } + + static float getPanningValueForText (String strText) { - return new DspModulePluginDemoAudioProcessorEditor (*this); + if (strText.compareIgnoreCase ("center") == 0 || strText.compareIgnoreCase ("c") == 0) + return 0.5f; + + strText = strText.trim(); + + if (strText.indexOfIgnoreCase ("%L") != -1) + { + auto percentage = (float) strText.substring (0, strText.indexOf ("%")).getDoubleValue(); + return (100.0f - percentage) / 100.0f * 0.5f; + } + + if (strText.indexOfIgnoreCase ("%R") != -1) + { + auto percentage = (float) strText.substring (0, strText.indexOf ("%")).getDoubleValue(); + return percentage / 100.0f * 0.5f + 0.5f; + } + + return 0.5f; } //============================================================================== - bool acceptsMidi() const override { return false; } - bool producesMidi() const override { return false; } - const String getName() const override { return JucePlugin_Name; } - double getTailLengthSeconds() const override { return 0.0; } + struct DistortionProcessor + { + DistortionProcessor() + { + forEach ([] (dsp::Gain<float>& gain) { gain.setRampDurationSeconds (0.05); }, + distGain, + compGain); - //============================================================================== - int getNumPrograms() override { return 1; } - int getCurrentProgram() override { return 0; } - void setCurrentProgram (int) override {} - const String getProgramName (int) override { return {}; } - void changeProgramName (int, const String&) override {} + lowpass.setType (dsp::FirstOrderTPTFilterType::lowpass); + highpass.setType (dsp::FirstOrderTPTFilterType::highpass); + mixer.setMixingRule (dsp::DryWetMixingRule::linear); + } - //============================================================================== - void getStateInformation (MemoryBlock&) override {} - void setStateInformation (const void*, int) override {} + void prepare (const dsp::ProcessSpec& spec) + { + for (auto& oversampler : oversamplers) + oversampler.initProcessing (spec.maximumBlockSize); - //============================================================================== - void updateParameters() + prepareAll (spec, lowpass, highpass, distGain, compGain, mixer); + } + + void reset() + { + for (auto& oversampler : oversamplers) + oversampler.reset(); + + resetAll (lowpass, highpass, distGain, compGain, mixer); + } + + float getLatency() const + { + return oversamplers[size_t (currentIndexOversampling)].getLatencyInSamples(); + } + + template <typename Context> + void process (Context& context) + { + if (context.isBypassed) + return; + + const auto& inputBlock = context.getInputBlock(); + + mixer.setWetLatency (getLatency()); + mixer.pushDrySamples (inputBlock); + + distGain.process (context); + highpass.process (context); + + auto ovBlock = oversamplers[size_t (currentIndexOversampling)].processSamplesUp (inputBlock); + + dsp::ProcessContextReplacing<float> waveshaperContext (ovBlock); + + if (isPositiveAndBelow (currentIndexWaveshaper, waveShapers.size())) + { + waveShapers[size_t (currentIndexWaveshaper)].process (waveshaperContext); + + if (currentIndexWaveshaper == 1) + clipping.process (waveshaperContext); + + waveshaperContext.getOutputBlock() *= 0.7f; + } + + auto& outputBlock = context.getOutputBlock(); + oversamplers[size_t (currentIndexOversampling)].processSamplesDown (outputBlock); + + lowpass.process (context); + compGain.process (context); + mixer.mixWetSamples (outputBlock); + } + + std::array<dsp::Oversampling<float>, 6> oversamplers + { { + { 2, 1, dsp::Oversampling<float>::filterHalfBandPolyphaseIIR, true, false }, + { 2, 2, dsp::Oversampling<float>::filterHalfBandPolyphaseIIR, true, false }, + { 2, 3, dsp::Oversampling<float>::filterHalfBandPolyphaseIIR, true, false }, + + { 2, 1, dsp::Oversampling<float>::filterHalfBandPolyphaseIIR, true, true }, + { 2, 2, dsp::Oversampling<float>::filterHalfBandPolyphaseIIR, true, true }, + { 2, 3, dsp::Oversampling<float>::filterHalfBandPolyphaseIIR, true, true }, + } }; + + static float clip (float in) { return juce::jlimit (-1.0f, 1.0f, in); } + + dsp::FirstOrderTPTFilter<float> lowpass, highpass; + dsp::Gain<float> distGain, compGain; + dsp::DryWetMixer<float> mixer { 10 }; + std::array<dsp::WaveShaper<float>, 2> waveShapers { { { std::tanh }, + { dsp::FastMathApproximations::tanh } } }; + dsp::WaveShaper<float> clipping { clip }; + int currentIndexOversampling = 0; + int currentIndexWaveshaper = 0; + }; + + struct ConvolutionProcessor { - auto newOversampling = oversamplingParam->get(); - if (newOversampling != audioCurrentlyOversampled) + ConvolutionProcessor() + { + loadImpulseResponse (cabinet, "guitar_amp.wav"); + loadImpulseResponse (reverb, "reverb_ir.wav"); + mixer.setMixingRule (dsp::DryWetMixingRule::balanced); + } + + void prepare (const dsp::ProcessSpec& spec) { - audioCurrentlyOversampled = newOversampling; - oversampling->reset(); + prepareAll (spec, cabinet, reverb, mixer); } - //============================================================================== - auto inputdB = Decibels::decibelsToGain (inputVolumeParam->get()); - auto outputdB = Decibels::decibelsToGain (outputVolumeParam->get()); + void reset() + { + resetAll (cabinet, reverb, mixer); + } + + template <typename Context> + void process (Context& context) + { + auto contextConv = context; + contextConv.isBypassed = (! cabEnabled) || context.isBypassed; + cabinet.process (contextConv); + + if (cabEnabled) + context.getOutputBlock().multiplyBy (4.0f); + + if (reverbEnabled) + mixer.pushDrySamples (context.getInputBlock()); + + contextConv.isBypassed = (! reverbEnabled) || context.isBypassed; + reverb.process (contextConv); + + if (reverbEnabled) + { + const auto& outputBlock = context.getOutputBlock(); + outputBlock.multiplyBy (4.0f); + mixer.mixWetSamples (outputBlock); + } + } + + int getLatency() const + { + auto latency = 0; + + if (cabEnabled) + latency += cabinet.getLatency(); + + if (reverbEnabled) + latency += reverb.getLatency(); + + return latency; + } + + dsp::ConvolutionMessageQueue queue; + dsp::Convolution cabinet { dsp::Convolution::NonUniform { 512 }, queue }; + dsp::Convolution reverb { dsp::Convolution::NonUniform { 512 }, queue }; + dsp::DryWetMixer<float> mixer; + bool cabEnabled = false, reverbEnabled = false; + + private: + static void loadImpulseResponse (dsp::Convolution& convolution, const char* filename) + { + auto stream = createAssetInputStream (filename); + + if (stream == nullptr) + { + jassertfalse; + return; + } - if (inputVolume .getGainLinear() != inputdB) inputVolume.setGainLinear (inputdB); - if (outputVolume.getGainLinear() != outputdB) outputVolume.setGainLinear (outputdB); + AudioFormatManager manager; + manager.registerBasicFormats(); + std::unique_ptr<AudioFormatReader> reader { manager.createReaderFor (std::move (stream)) }; - auto newSlopeType = slopeParam->getIndex(); + if (reader == nullptr) + { + jassertfalse; + return; + } + + AudioBuffer<float> buffer (static_cast<int> (reader->numChannels), + static_cast<int> (reader->lengthInSamples)); + reader->read (buffer.getArrayOfWritePointers(), buffer.getNumChannels(), 0, buffer.getNumSamples()); + + convolution.loadImpulseResponse (std::move (buffer), + reader->sampleRate, + dsp::Convolution::Stereo::yes, + dsp::Convolution::Trim::yes, + dsp::Convolution::Normalise::yes); + } + }; - if (newSlopeType == 0) + struct MultiBandProcessor + { + MultiBandProcessor() { - *lowPassFilter .state = *dsp::IIR::Coefficients<float>::makeFirstOrderLowPass (getSampleRate(), lowPassFilterFreqParam->get()); - *highPassFilter.state = *dsp::IIR::Coefficients<float>::makeFirstOrderHighPass (getSampleRate(), highPassFilterFreqParam->get()); + forEach ([] (dsp::Gain<float>& gain) { gain.setRampDurationSeconds (0.05); }, + lowVolume, + highVolume); + + lowpass .setType (dsp::LinkwitzRileyFilterType::lowpass); + highpass.setType (dsp::LinkwitzRileyFilterType::highpass); } - else + + void prepare (const dsp::ProcessSpec& spec) { - *lowPassFilter .state = *dsp::IIR::Coefficients<float>::makeLowPass (getSampleRate(), lowPassFilterFreqParam->get()); - *highPassFilter.state = *dsp::IIR::Coefficients<float>::makeHighPass (getSampleRate(), highPassFilterFreqParam->get()); + prepareAll (spec, lowpass, highpass, lowVolume, highVolume); + bufferSeparation.setSize (4, int (spec.maximumBlockSize), false, false, true); } - //============================================================================== - auto type = cabinetTypeParam->getIndex(); - auto currentType = cabinetType.get(); + void reset() + { + resetAll (lowpass, highpass, lowVolume, highVolume); + } - if (type != currentType) + template <typename Context> + void process (Context& context) { - cabinetType.set (type); + const auto& inputBlock = context.getInputBlock(); + + const auto numSamples = inputBlock.getNumSamples(); + const auto numChannels = inputBlock.getNumChannels(); - auto maxSize = static_cast<size_t> (roundToInt (getSampleRate() * (8192.0 / 44100.0))); - auto assetName = (type == 0 ? "Impulse1.wav" : "Impulse2.wav"); + auto sepBlock = dsp::AudioBlock<float> (bufferSeparation).getSubBlock (0, (size_t) numSamples); - std::unique_ptr<InputStream> assetInputStream (createAssetInputStream (assetName)); + auto sepLowBlock = sepBlock.getSubsetChannelBlock (0, (size_t) numChannels); + auto sepHighBlock = sepBlock.getSubsetChannelBlock (2, (size_t) numChannels); - if (assetInputStream != nullptr) + sepLowBlock .copyFrom (inputBlock); + sepHighBlock.copyFrom (inputBlock); + + auto contextLow = dsp::ProcessContextReplacing<float> (sepLowBlock); + contextLow.isBypassed = context.isBypassed; + lowpass .process (contextLow); + lowVolume.process (contextLow); + + auto contextHigh = dsp::ProcessContextReplacing<float> (sepHighBlock); + contextHigh.isBypassed = context.isBypassed; + highpass .process (contextHigh); + highVolume.process (contextHigh); + + if (! context.isBypassed) { - currentCabinetData.reset(); - assetInputStream->readIntoMemoryBlock (currentCabinetData); + sepLowBlock.add (sepHighBlock); + context.getOutputBlock().copyFrom (sepLowBlock); + } + } + + dsp::LinkwitzRileyFilter<float> lowpass, highpass; + dsp::Gain<float> lowVolume, highVolume; + AudioBuffer<float> bufferSeparation; + }; + + struct DirectDelayProcessor + { + DirectDelayProcessor() + { + smoothFilter.setType (dsp::FirstOrderTPTFilterType::lowpass); + mixer.setMixingRule (dsp::DryWetMixingRule::linear); + } - convolution.loadImpulseResponse (currentCabinetData.getData(), currentCabinetData.getSize(), - false, true, maxSize); + void prepare (const dsp::ProcessSpec& spec) + { + prepareAll (spec, noInterpolation, linear, lagrange, thiran, smoothFilter, mixer); + } + + void reset() + { + resetAll (noInterpolation, linear, lagrange, thiran, smoothFilter, mixer); + } + + template <typename Context> + void process (Context& context) + { + if (context.isBypassed) + return; + + const auto& inputBlock = context.getInputBlock(); + const auto& outputBlock = context.getOutputBlock(); + + mixer.pushDrySamples (inputBlock); + + const auto numChannels = inputBlock.getNumChannels(); + const auto numSamples = inputBlock.getNumSamples(); + + for (size_t channel = 0; channel < numChannels; ++channel) + { + auto* samplesIn = inputBlock .getChannelPointer (channel); + auto* samplesOut = outputBlock.getChannelPointer (channel); + + for (size_t i = 0; i < numSamples; ++i) + { + const auto delay = smoothFilter.processSample (int (channel), delayDirectValue[channel]); + + samplesOut[i] = [&] + { + switch (delayLineDirectType) + { + case 0: + noInterpolation.pushSample (int (channel), samplesIn[i]); + noInterpolation.setDelay ((float) delay); + return noInterpolation.popSample (int (channel)); + + case 1: + linear.pushSample (int (channel), samplesIn[i]); + linear.setDelay ((float) delay); + return linear.popSample (int (channel)); + + case 2: + lagrange.pushSample (int (channel), samplesIn[i]); + lagrange.setDelay ((float) delay); + return lagrange.popSample (int (channel)); + + case 3: + thiran.pushSample (int (channel), samplesIn[i]); + thiran.setDelay ((float) delay); + return thiran.popSample (int (channel)); + + default: + break; + } + + jassertfalse; + return 0.0f; + }(); + } } + + mixer.mixWetSamples (outputBlock); } - cabinetIsBypassed = ! cabinetSimParam->get(); + static constexpr auto directDelayBufferSize = 44100; + dsp::DelayLine<float, dsp::DelayLineInterpolationTypes::None> noInterpolation { directDelayBufferSize }; + dsp::DelayLine<float, dsp::DelayLineInterpolationTypes::Linear> linear { directDelayBufferSize }; + dsp::DelayLine<float, dsp::DelayLineInterpolationTypes::Lagrange3rd> lagrange { directDelayBufferSize }; + dsp::DelayLine<float, dsp::DelayLineInterpolationTypes::Thiran> thiran { directDelayBufferSize }; - } + // Double precision to avoid some approximation issues + dsp::FirstOrderTPTFilter<double> smoothFilter; + + dsp::DryWetMixer<float> mixer; + std::array<double, 2> delayDirectValue { {} }; + + int delayLineDirectType = 1; + }; + + struct DelayEffectProcessor + { + DelayEffectProcessor() + { + smoothFilter.setType (dsp::FirstOrderTPTFilterType::lowpass); + lowpass.setType (dsp::FirstOrderTPTFilterType::lowpass); + mixer.setMixingRule (dsp::DryWetMixingRule::linear); + } + + void prepare (const dsp::ProcessSpec& spec) + { + prepareAll (spec, noInterpolation, linear, lagrange, thiran, smoothFilter, lowpass, mixer); + + for (auto& volume : delayFeedbackVolume) + volume.reset (spec.sampleRate, 0.05); + } + + void reset() + { + resetAll (noInterpolation, linear, lagrange, thiran, smoothFilter, lowpass, mixer); + std::fill (lastDelayEffectOutput.begin(), lastDelayEffectOutput.end(), 0.0f); + } + + template <typename Context> + void process (Context& context) + { + if (context.isBypassed) + return; + + const auto& inputBlock = context.getInputBlock(); + const auto& outputBlock = context.getOutputBlock(); + const auto numSamples = inputBlock.getNumSamples(); + const auto numChannels = inputBlock.getNumChannels(); + + mixer.pushDrySamples (inputBlock); + + for (size_t channel = 0; channel < numChannels; ++channel) + { + auto* samplesIn = inputBlock .getChannelPointer (channel); + auto* samplesOut = outputBlock.getChannelPointer (channel); + + for (size_t i = 0; i < numSamples; ++i) + { + auto input = samplesIn[i] - lastDelayEffectOutput[channel]; + + auto delay = smoothFilter.processSample (int (channel), delayEffectValue[channel]); + + const auto output = [&] + { + switch (delayEffectType) + { + case 0: + noInterpolation.pushSample (int (channel), input); + noInterpolation.setDelay ((float) delay); + return noInterpolation.popSample (int (channel)); + + case 1: + linear.pushSample (int (channel), input); + linear.setDelay ((float) delay); + return linear.popSample (int (channel)); + + case 2: + lagrange.pushSample (int (channel), input); + lagrange.setDelay ((float) delay); + return lagrange.popSample (int (channel)); + + case 3: + thiran.pushSample (int (channel), input); + thiran.setDelay ((float) delay); + return thiran.popSample (int (channel)); + + default: + break; + } + + jassertfalse; + return 0.0f; + }(); + + const auto processed = lowpass.processSample (int (channel), output); + + samplesOut[i] = processed; + lastDelayEffectOutput[channel] = processed * delayFeedbackVolume[channel].getNextValue(); + } + } + + mixer.mixWetSamples (outputBlock); + } + + static constexpr auto effectDelaySamples = 192000; + dsp::DelayLine<float, dsp::DelayLineInterpolationTypes::None> noInterpolation { effectDelaySamples }; + dsp::DelayLine<float, dsp::DelayLineInterpolationTypes::Linear> linear { effectDelaySamples }; + dsp::DelayLine<float, dsp::DelayLineInterpolationTypes::Lagrange3rd> lagrange { effectDelaySamples }; + dsp::DelayLine<float, dsp::DelayLineInterpolationTypes::Thiran> thiran { effectDelaySamples }; + + // Double precision to avoid some approximation issues + dsp::FirstOrderTPTFilter<double> smoothFilter; + + std::array<double, 2> delayEffectValue; + + std::array<LinearSmoothedValue<float>, 2> delayFeedbackVolume; + dsp::FirstOrderTPTFilter<float> lowpass; + dsp::DryWetMixer<float> mixer; + std::array<float, 2> lastDelayEffectOutput; + + int delayEffectType = 1; + }; + + ParameterReferences parameters; + AudioProcessorValueTreeState apvts; + + using Chain = dsp::ProcessorChain<dsp::NoiseGate<float>, + dsp::Gain<float>, + DirectDelayProcessor, + MultiBandProcessor, + dsp::Compressor<float>, + dsp::Phaser<float>, + dsp::Chorus<float>, + DistortionProcessor, + dsp::LadderFilter<float>, + DelayEffectProcessor, + ConvolutionProcessor, + dsp::Limiter<float>, + dsp::Gain<float>, + dsp::Panner<float>>; + Chain chain; + + // We use this enum to index into the chain above + enum ProcessorIndices + { + noiseGateIndex, + inputGainIndex, + directDelayIndex, + multiBandIndex, + compressorIndex, + phaserIndex, + chorusIndex, + distortionIndex, + ladderIndex, + delayEffectIndex, + convolutionIndex, + limiterIndex, + outputGainIndex, + pannerIndex + }; + + //============================================================================== + std::atomic<bool> requiresUpdate { true }; + std::atomic<int> irSize { 0 }; + + //============================================================================== + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DspModulePluginDemo) +}; - static inline float clip (float x) { return jmax (-1.0f, jmin (1.0f, x)); } +//============================================================================== +class DspModulePluginDemoEditor : public AudioProcessorEditor +{ +public: + explicit DspModulePluginDemoEditor (DspModulePluginDemo& p) + : AudioProcessorEditor (&p), + proc (p) + { + comboEffect.addSectionHeading ("Main"); + comboEffect.addItem ("Distortion", TabDistortion); + comboEffect.addItem ("Convolution", TabConvolution); + comboEffect.addItem ("Multi-band", TabMultiBand); + + comboEffect.addSectionHeading ("Dynamics"); + comboEffect.addItem ("Compressor", TabCompressor); + comboEffect.addItem ("Noise gate", TabNoiseGate); + comboEffect.addItem ("Limiter", TabLimiter); + + comboEffect.addSectionHeading ("Delay"); + comboEffect.addItem ("Delay line direct", TabDelayLineDirect); + comboEffect.addItem ("Delay line effect", TabDelayLineEffect); + + comboEffect.addSectionHeading ("Others"); + comboEffect.addItem ("Phaser", TabPhaser); + comboEffect.addItem ("Chorus", TabChorus); + comboEffect.addItem ("Ladder filter", TabLadder); + + comboEffect.setSelectedId (proc.indexTab + 1, dontSendNotification); + comboEffect.onChange = [this] + { + proc.indexTab = comboEffect.getSelectedId() - 1; + updateVisibility(); + }; + + addAllAndMakeVisible (*this, + comboEffect, + labelEffect, + basicControls, + distortionControls, + convolutionControls, + multibandControls, + compressorControls, + noiseGateControls, + limiterControls, + directDelayControls, + delayEffectControls, + phaserControls, + chorusControls, + ladderControls); + labelEffect.setJustificationType (Justification::centredRight); + labelEffect.attachToComponent (&comboEffect, true); + + updateVisibility(); + + setSize (800, 430); + } //============================================================================== - AudioParameterFloat* inputVolumeParam; - AudioParameterFloat* outputVolumeParam; - AudioParameterFloat* lowPassFilterFreqParam; - AudioParameterFloat* highPassFilterFreqParam; + void paint (Graphics& g) override + { + auto rect = getLocalBounds(); + + auto rectTop = rect.removeFromTop (topSize); + auto rectBottom = rect.removeFromBottom (bottomSize); + + auto rectEffects = rect.removeFromBottom (tabSize); + auto rectChoice = rect.removeFromBottom (midSize); + + g.setColour (getLookAndFeel().findColour (ResizableWindow::backgroundColourId)); + g.fillRect (rect); - AudioParameterChoice* stereoParam; - AudioParameterChoice* slopeParam; - AudioParameterChoice* waveshaperParam; - AudioParameterChoice* cabinetTypeParam; + g.setColour (getLookAndFeel().findColour (ResizableWindow::backgroundColourId).brighter (0.2f)); + g.fillRect (rectEffects); - AudioParameterBool* cabinetSimParam; - AudioParameterBool* oversamplingParam; + g.setColour (getLookAndFeel().findColour (ResizableWindow::backgroundColourId).darker (0.2f)); + g.fillRect (rectTop); + g.fillRect (rectBottom); + g.fillRect (rectChoice); + + g.setColour (Colours::white); + g.setFont (Font (20.0f).italicised().withExtraKerningFactor (0.1f)); + g.drawFittedText ("DSP MODULE DEMO", rectTop.reduced (10, 0), Justification::centredLeft, 1); + + g.setFont (Font (14.0f)); + String strText = "IR length (reverb): " + String (proc.getCurrentIRSize()) + " samples"; + g.drawFittedText (strText, rectBottom.reduced (10, 0), Justification::centredRight, 1); + } + + void resized() override + { + auto rect = getLocalBounds(); + rect.removeFromTop (topSize); + rect.removeFromBottom (bottomSize); + + auto rectEffects = rect.removeFromBottom (tabSize); + auto rectChoice = rect.removeFromBottom (midSize); + + comboEffect.setBounds (rectChoice.withSizeKeepingCentre (200, 24)); + + rect.reduce (80, 0); + rectEffects.reduce (20, 0); + + basicControls.setBounds (rect); + + forEach ([&] (Component& comp) { comp.setBounds (rectEffects); }, + distortionControls, + convolutionControls, + multibandControls, + compressorControls, + noiseGateControls, + limiterControls, + directDelayControls, + delayEffectControls, + phaserControls, + chorusControls, + ladderControls); + } private: - //============================================================================== - /** - This is the editor component that will be displayed. - */ - class DspModulePluginDemoAudioProcessorEditor : public AudioProcessorEditor + class AttachedSlider : public Component { public: - //============================================================================== - DspModulePluginDemoAudioProcessorEditor (DspModulePluginDemoAudioProcessor& p) - : AudioProcessorEditor (&p), - processor (p), - inputVolumeLabel ({}, processor.inputVolumeParam->name), - outputVolumeLabel ({}, processor.outputVolumeParam->name), - lowPassFilterFreqLabel ({}, processor.lowPassFilterFreqParam->name), - highPassFilterFreqLabel ({}, processor.highPassFilterFreqParam->name), - stereoLabel ({}, processor.stereoParam->name), - slopeLabel ({}, processor.slopeParam->name), - waveshaperLabel ({}, processor.waveshaperParam->name), - cabinetTypeLabel ({}, processor.cabinetTypeParam->name) + explicit AttachedSlider (RangedAudioParameter& param) + : label ("", param.name), + attachment (param, slider) { - //============================================================================== - inputVolumeSlider .reset (new ParameterSlider (*processor.inputVolumeParam)); - outputVolumeSlider .reset (new ParameterSlider (*processor.outputVolumeParam)); - lowPassFilterFreqSlider .reset (new ParameterSlider (*processor.lowPassFilterFreqParam)); - highPassFilterFreqSlider.reset (new ParameterSlider (*processor.highPassFilterFreqParam)); + addAllAndMakeVisible (*this, slider, label); - addAndMakeVisible (inputVolumeSlider .get()); - addAndMakeVisible (outputVolumeSlider .get()); - addAndMakeVisible (lowPassFilterFreqSlider .get()); - addAndMakeVisible (highPassFilterFreqSlider.get()); + slider.setTextValueSuffix (" " + param.label); - addAndMakeVisible (inputVolumeLabel); - inputVolumeLabel.setJustificationType (Justification::centredLeft); - inputVolumeLabel.attachToComponent (inputVolumeSlider.get(), true); + label.attachToComponent (&slider, false); + label.setJustificationType (Justification::centred); + } - addAndMakeVisible (outputVolumeLabel); - outputVolumeLabel.setJustificationType (Justification::centredLeft); - outputVolumeLabel.attachToComponent (outputVolumeSlider.get(), true); + void resized() override { slider.setBounds (getLocalBounds().reduced (0, 40)); } - addAndMakeVisible (lowPassFilterFreqLabel); - lowPassFilterFreqLabel.setJustificationType (Justification::centredLeft); - lowPassFilterFreqLabel.attachToComponent (lowPassFilterFreqSlider.get(), true); + private: + Slider slider { Slider::RotaryVerticalDrag, Slider::TextBoxBelow }; + Label label; + SliderParameterAttachment attachment; + }; - addAndMakeVisible (highPassFilterFreqLabel); - highPassFilterFreqLabel.setJustificationType (Justification::centredLeft); - highPassFilterFreqLabel.attachToComponent (highPassFilterFreqSlider.get(), true); + class AttachedToggle : public Component + { + public: + explicit AttachedToggle (RangedAudioParameter& param) + : toggle (param.name), + attachment (param, toggle) + { + addAndMakeVisible (toggle); + } - //============================================================================== - addAndMakeVisible (stereoBox); + void resized() override { toggle.setBounds (getLocalBounds()); } - auto i = 1; - for (auto choice : processor.stereoParam->choices) - stereoBox.addItem (choice, i++); + private: + ToggleButton toggle; + ButtonParameterAttachment attachment; + }; - stereoBox.onChange = [this] { processor.stereoParam->operator= (stereoBox.getSelectedItemIndex()); }; - stereoBox.setSelectedId (processor.stereoParam->getIndex() + 1); + class AttachedCombo : public Component + { + public: + explicit AttachedCombo (RangedAudioParameter& param) + : combo (param), + label ("", param.name), + attachment (param, combo) + { + addAllAndMakeVisible (*this, combo, label); - addAndMakeVisible (stereoLabel); - stereoLabel.setJustificationType (Justification::centredLeft); - stereoLabel.attachToComponent (&stereoBox, true); + label.attachToComponent (&combo, false); + label.setJustificationType (Justification::centred); + } - //============================================================================== - addAndMakeVisible(slopeBox); + void resized() override + { + combo.setBounds (getLocalBounds().withSizeKeepingCentre (jmin (getWidth(), 150), 24)); + } - i = 1; - for (auto choice : processor.slopeParam->choices) - slopeBox.addItem(choice, i++); + private: + struct ComboWithItems : public ComboBox + { + explicit ComboWithItems (RangedAudioParameter& param) + { + // Adding the list here in the constructor means that the combo + // is already populated when we construct the attachment below + addItemList (dynamic_cast<AudioParameterChoice&> (param).choices, 1); + } + }; - slopeBox.onChange = [this] { processor.slopeParam->operator= (slopeBox.getSelectedItemIndex()); }; - slopeBox.setSelectedId(processor.slopeParam->getIndex() + 1); + ComboWithItems combo; + Label label; + ComboBoxParameterAttachment attachment; + }; - addAndMakeVisible(slopeLabel); - slopeLabel.setJustificationType(Justification::centredLeft); - slopeLabel.attachToComponent(&slopeBox, true); + //============================================================================== + void updateVisibility() + { + const auto indexEffect = comboEffect.getSelectedId(); - //============================================================================== - addAndMakeVisible (waveshaperBox); + const auto op = [&] (const std::tuple<Component&, int>& tup) + { + Component& comp = std::get<0> (tup); + const int tabIndex = std::get<1> (tup); + comp.setVisible (tabIndex == indexEffect); + }; + + forEach (op, + std::forward_as_tuple (distortionControls, TabDistortion), + std::forward_as_tuple (convolutionControls, TabConvolution), + std::forward_as_tuple (multibandControls, TabMultiBand), + std::forward_as_tuple (compressorControls, TabCompressor), + std::forward_as_tuple (noiseGateControls, TabNoiseGate), + std::forward_as_tuple (limiterControls, TabLimiter), + std::forward_as_tuple (directDelayControls, TabDelayLineDirect), + std::forward_as_tuple (delayEffectControls, TabDelayLineEffect), + std::forward_as_tuple (phaserControls, TabPhaser), + std::forward_as_tuple (chorusControls, TabChorus), + std::forward_as_tuple (ladderControls, TabLadder)); + } - i = 1; - for (auto choice : processor.waveshaperParam->choices) - waveshaperBox.addItem (choice, i++); + enum EffectsTabs + { + TabDistortion = 1, + TabConvolution, + TabMultiBand, + TabCompressor, + TabNoiseGate, + TabLimiter, + TabDelayLineDirect, + TabDelayLineEffect, + TabPhaser, + TabChorus, + TabLadder + }; - waveshaperBox.onChange = [this] { processor.waveshaperParam->operator= (waveshaperBox.getSelectedItemIndex()); }; - waveshaperBox.setSelectedId (processor.waveshaperParam->getIndex() + 1); + //============================================================================== + ComboBox comboEffect; + Label labelEffect { "Audio effect: " }; - addAndMakeVisible (waveshaperLabel); - waveshaperLabel.setJustificationType (Justification::centredLeft); - waveshaperLabel.attachToComponent (&waveshaperBox, true); + struct GetTrackInfo + { + // Combo boxes need a lot of room + Grid::TrackInfo operator() (AttachedCombo&) const { return 120_px; } - //============================================================================== - addAndMakeVisible (cabinetTypeBox); + // Toggles are a bit smaller + Grid::TrackInfo operator() (AttachedToggle&) const { return 80_px; } - i = 1; - for (auto choice : processor.cabinetTypeParam->choices) - cabinetTypeBox.addItem (choice, i++); + // Sliders take up as much room as they can + Grid::TrackInfo operator() (AttachedSlider&) const { return 1_fr; } + }; + + template <typename... Components> + static void performLayout (const Rectangle<int>& bounds, Components&... components) + { + Grid grid; + using Track = Grid::TrackInfo; - cabinetTypeBox.onChange = [this] { processor.cabinetTypeParam->operator= (cabinetTypeBox.getSelectedItemIndex()); }; - cabinetTypeBox.setSelectedId (processor.cabinetTypeParam->getIndex() + 1); + grid.autoColumns = Track (1_fr); + grid.autoRows = Track (1_fr); + grid.columnGap = Grid::Px (10); + grid.rowGap = Grid::Px (0); + grid.autoFlow = Grid::AutoFlow::column; - addAndMakeVisible (cabinetTypeLabel); - cabinetTypeLabel.setJustificationType (Justification::centredLeft); - cabinetTypeLabel.attachToComponent (&cabinetTypeBox, true); + grid.templateColumns = { GetTrackInfo{} (components)... }; + grid.items = { GridItem (components)... }; - //============================================================================== - addAndMakeVisible (cabinetSimButton); - cabinetSimButton.onClick = [this] { processor.cabinetSimParam->operator= (cabinetSimButton.getToggleState()); }; - cabinetSimButton.setButtonText (processor.cabinetSimParam->name); - cabinetSimButton.setToggleState (processor.cabinetSimParam->get(), NotificationType::dontSendNotification); + grid.performLayout (bounds); + } - addAndMakeVisible (oversamplingButton); - oversamplingButton.onClick = [this] { processor.oversamplingParam->operator= (oversamplingButton.getToggleState()); }; - oversamplingButton.setButtonText (processor.oversamplingParam->name); - oversamplingButton.setToggleState (processor.oversamplingParam->get(), NotificationType::dontSendNotification); + struct BasicControls : public Component + { + explicit BasicControls (const DspModulePluginDemo::ParameterReferences& state) + : pan (state.pan), + input (state.inputGain), + output (state.outputGain) + { + addAllAndMakeVisible (*this, pan, input, output); + } - //============================================================================== - setSize (600, 400); + void resized() override + { + performLayout (getLocalBounds(), input, output, pan); } - ~DspModulePluginDemoAudioProcessorEditor() {} + AttachedSlider pan, input, output; + }; - //============================================================================== - void paint (Graphics& g) override + struct DistortionControls : public Component + { + explicit DistortionControls (const DspModulePluginDemo::ParameterReferences& state) + : toggle (state.distortionEnabled), + lowpass (state.distortionLowpass), + highpass (state.distortionHighpass), + mix (state.distortionMix), + gain (state.distortionInGain), + compv (state.distortionCompGain), + type (state.distortionType), + oversampling (state.distortionOversampler) { - g.setColour (getLookAndFeel().findColour (ResizableWindow::backgroundColourId)); - g.fillAll(); + addAllAndMakeVisible (*this, toggle, type, lowpass, highpass, mix, gain, compv, oversampling); } void resized() override { - auto bounds = getLocalBounds().reduced (10); - bounds.removeFromTop (10); - bounds.removeFromLeft (125); - - //============================================================================== - inputVolumeSlider->setBounds (bounds.removeFromTop (30)); - bounds.removeFromTop (5); + performLayout (getLocalBounds(), toggle, type, gain, highpass, lowpass, compv, mix, oversampling); + } - outputVolumeSlider->setBounds (bounds.removeFromTop (30)); - bounds.removeFromTop (15); + AttachedToggle toggle; + AttachedSlider lowpass, highpass, mix, gain, compv; + AttachedCombo type, oversampling; + }; - highPassFilterFreqSlider->setBounds (bounds.removeFromTop (30)); - bounds.removeFromTop (5); + struct ConvolutionControls : public Component + { + explicit ConvolutionControls (const DspModulePluginDemo::ParameterReferences& state) + : cab (state.convolutionCabEnabled), + reverb (state.convolutionReverbEnabled), + mix (state.convolutionReverbMix) + { + addAllAndMakeVisible (*this, cab, reverb, mix); + } - lowPassFilterFreqSlider->setBounds (bounds.removeFromTop (30)); - bounds.removeFromTop (15); + void resized() override + { + performLayout (getLocalBounds(), cab, reverb, mix); + } - //============================================================================== - stereoBox.setBounds (bounds.removeFromTop(30)); - bounds.removeFromTop (5); + AttachedToggle cab, reverb; + AttachedSlider mix; + }; - slopeBox.setBounds (bounds.removeFromTop (30)); - bounds.removeFromTop (5); + struct MultiBandControls : public Component + { + explicit MultiBandControls (const DspModulePluginDemo::ParameterReferences& state) + : toggle (state.multiBandEnabled), + low (state.multiBandLowVolume), + high (state.multiBandHighVolume), + lRFreq (state.multiBandFreq) + { + addAllAndMakeVisible (*this, toggle, low, high, lRFreq); + } - waveshaperBox.setBounds (bounds.removeFromTop (30)); - bounds.removeFromTop (5); + void resized() override + { + performLayout (getLocalBounds(), toggle, lRFreq, low, high); + } - cabinetTypeBox.setBounds (bounds.removeFromTop (30)); - bounds.removeFromTop (15); + AttachedToggle toggle; + AttachedSlider low, high, lRFreq; + }; - //============================================================================== - auto buttonSlice = bounds.removeFromTop (30); - cabinetSimButton.setSize (200, buttonSlice.getHeight()); - cabinetSimButton.setCentrePosition (buttonSlice.getCentre()); - bounds.removeFromTop(5); + struct CompressorControls : public Component + { + explicit CompressorControls (const DspModulePluginDemo::ParameterReferences& state) + : toggle (state.compressorEnabled), + threshold (state.compressorThreshold), + ratio (state.compressorRatio), + attack (state.compressorAttack), + release (state.compressorRelease) + { + addAllAndMakeVisible (*this, toggle, threshold, ratio, attack, release); + } - buttonSlice = bounds.removeFromTop (30); - oversamplingButton.setSize(200, buttonSlice.getHeight()); - oversamplingButton.setCentrePosition(buttonSlice.getCentre()); + void resized() override + { + performLayout (getLocalBounds(), toggle, threshold, ratio, attack, release); } - private: - //============================================================================== - DspModulePluginDemoAudioProcessor& processor; + AttachedToggle toggle; + AttachedSlider threshold, ratio, attack, release; + }; - std::unique_ptr<ParameterSlider> inputVolumeSlider, outputVolumeSlider, - lowPassFilterFreqSlider, highPassFilterFreqSlider; - ComboBox stereoBox, slopeBox, waveshaperBox, cabinetTypeBox; - ToggleButton cabinetSimButton, oversamplingButton; + struct NoiseGateControls : public Component + { + explicit NoiseGateControls (const DspModulePluginDemo::ParameterReferences& state) + : toggle (state.noiseGateEnabled), + threshold (state.noiseGateThreshold), + ratio (state.noiseGateRatio), + attack (state.noiseGateAttack), + release (state.noiseGateRelease) + { + addAllAndMakeVisible (*this, toggle, threshold, ratio, attack, release); + } - Label inputVolumeLabel, outputVolumeLabel, lowPassFilterFreqLabel, - highPassFilterFreqLabel, stereoLabel, slopeLabel, waveshaperLabel, - cabinetTypeLabel; + void resized() override + { + performLayout (getLocalBounds(), toggle, threshold, ratio, attack, release); + } - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DspModulePluginDemoAudioProcessorEditor) + AttachedToggle toggle; + AttachedSlider threshold, ratio, attack, release; }; - //============================================================================== - void process (dsp::ProcessContextReplacing<float> context) noexcept + struct LimiterControls : public Component { - ScopedNoDenormals noDenormals; - - // Input volume applied with a SmoothedValue - inputVolume.process (context); + explicit LimiterControls (const DspModulePluginDemo::ParameterReferences& state) + : toggle (state.limiterEnabled), + threshold (state.limiterThreshold), + release (state.limiterRelease) + { + addAllAndMakeVisible (*this, toggle, threshold, release); + } - // Pre-highpass filtering, very useful for distortion audio effects - // Note : try frequencies around 700 Hz - highPassFilter.process (context); + void resized() override + { + performLayout (getLocalBounds(), toggle, threshold, release); + } - // Upsampling - dsp::AudioBlock<float> oversampledBlock; + AttachedToggle toggle; + AttachedSlider threshold, release; + }; - setLatencySamples (audioCurrentlyOversampled ? roundToInt (oversampling->getLatencyInSamples()) : 0); + struct DirectDelayControls : public Component + { + explicit DirectDelayControls (const DspModulePluginDemo::ParameterReferences& state) + : toggle (state.directDelayEnabled), + type (state.directDelayType), + delay (state.directDelayValue), + smooth (state.directDelaySmoothing), + mix (state.directDelayMix) + { + addAllAndMakeVisible (*this, toggle, type, delay, smooth, mix); + } - if (audioCurrentlyOversampled) - oversampledBlock = oversampling->processSamplesUp (context.getOutputBlock()); + void resized() override + { + performLayout (getLocalBounds(), toggle, type, delay, smooth, mix); + } - auto waveshaperContext = audioCurrentlyOversampled ? dsp::ProcessContextReplacing<float> (oversampledBlock) - : context; + AttachedToggle toggle; + AttachedCombo type; + AttachedSlider delay, smooth, mix; + }; - // Waveshaper processing, for distortion generation, thanks to the input gain - // The fast tanh can be used instead of std::tanh to reduce the CPU load - auto waveshaperIndex = waveshaperParam->getIndex(); + struct DelayEffectControls : public Component + { + explicit DelayEffectControls (const DspModulePluginDemo::ParameterReferences& state) + : toggle (state.delayEffectEnabled), + type (state.delayEffectType), + value (state.delayEffectValue), + smooth (state.delayEffectSmoothing), + lowpass (state.delayEffectLowpass), + feedback (state.delayEffectFeedback), + mix (state.delayEffectMix) + { + addAllAndMakeVisible (*this, toggle, type, value, smooth, lowpass, feedback, mix); + } - if (isPositiveAndBelow (waveshaperIndex, numWaveShapers) ) + void resized() override { - waveShapers[waveshaperIndex].process (waveshaperContext); + performLayout (getLocalBounds(), toggle, type, value, smooth, lowpass, feedback, mix); + } - if (waveshaperIndex == 1) - clipping.process (waveshaperContext); + AttachedToggle toggle; + AttachedCombo type; + AttachedSlider value, smooth, lowpass, feedback, mix; + }; - waveshaperContext.getOutputBlock() *= 0.7f; + struct PhaserControls : public Component + { + explicit PhaserControls (const DspModulePluginDemo::ParameterReferences& state) + : toggle (state.phaserEnabled), + rate (state.phaserRate), + depth (state.phaserDepth), + centre (state.phaserCentreFrequency), + feedback (state.phaserFeedback), + mix (state.phaserMix) + { + addAllAndMakeVisible (*this, toggle, rate, depth, centre, feedback, mix); } - // Downsampling - if (audioCurrentlyOversampled) - oversampling->processSamplesDown (context.getOutputBlock()); + void resized() override + { + performLayout (getLocalBounds(), toggle, rate, depth, centre, feedback, mix); + } - // Post-lowpass filtering - lowPassFilter.process (context); + AttachedToggle toggle; + AttachedSlider rate, depth, centre, feedback, mix; + }; - // Convolution with the impulse response of a guitar cabinet - auto wasBypassed = context.isBypassed; - context.isBypassed = context.isBypassed || cabinetIsBypassed; - convolution.process (context); - context.isBypassed = wasBypassed; + struct ChorusControls : public Component + { + explicit ChorusControls (const DspModulePluginDemo::ParameterReferences& state) + : toggle (state.chorusEnabled), + rate (state.chorusRate), + depth (state.chorusDepth), + centre (state.chorusCentreDelay), + feedback (state.chorusFeedback), + mix (state.chorusMix) + { + addAllAndMakeVisible (*this, toggle, rate, depth, centre, feedback, mix); + } - // Output volume applied with a SmoothedValue - outputVolume.process (context); - } + void resized() override + { + performLayout (getLocalBounds(), toggle, rate, depth, centre, feedback, mix); + } - //============================================================================== - dsp::ProcessorDuplicator<dsp::IIR::Filter<float>, dsp::IIR::Coefficients<float>> lowPassFilter, highPassFilter; - dsp::Convolution convolution; - MemoryBlock currentCabinetData; + AttachedToggle toggle; + AttachedSlider rate, depth, centre, feedback, mix; + }; - static constexpr size_t numWaveShapers = 2; - dsp::WaveShaper<float> waveShapers[numWaveShapers]; - dsp::WaveShaper<float> clipping; + struct LadderControls : public Component + { + explicit LadderControls (const DspModulePluginDemo::ParameterReferences& state) + : toggle (state.ladderEnabled), + mode (state.ladderMode), + freq (state.ladderCutoff), + resonance (state.ladderResonance), + drive (state.ladderDrive) + { + addAllAndMakeVisible (*this, toggle, mode, freq, resonance, drive); + } - dsp::Gain<float> inputVolume, outputVolume; + void resized() override + { + performLayout (getLocalBounds(), toggle, mode, freq, resonance, drive); + } - std::unique_ptr<dsp::Oversampling<float>> oversampling; - bool audioCurrentlyOversampled = false; + AttachedToggle toggle; + AttachedCombo mode; + AttachedSlider freq, resonance, drive; + }; + + //============================================================================== + static constexpr auto topSize = 40, + bottomSize = 40, + midSize = 40, + tabSize = 155; - Atomic<int> cabinetType; - bool cabinetIsBypassed = false; + //============================================================================== + DspModulePluginDemo& proc; + + BasicControls basicControls { proc.getParameterValues() }; + DistortionControls distortionControls { proc.getParameterValues() }; + ConvolutionControls convolutionControls { proc.getParameterValues() }; + MultiBandControls multibandControls { proc.getParameterValues() }; + CompressorControls compressorControls { proc.getParameterValues() }; + NoiseGateControls noiseGateControls { proc.getParameterValues() }; + LimiterControls limiterControls { proc.getParameterValues() }; + DirectDelayControls directDelayControls { proc.getParameterValues() }; + DelayEffectControls delayEffectControls { proc.getParameterValues() }; + PhaserControls phaserControls { proc.getParameterValues() }; + ChorusControls chorusControls { proc.getParameterValues() }; + LadderControls ladderControls { proc.getParameterValues() }; //============================================================================== - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DspModulePluginDemoAudioProcessor) + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DspModulePluginDemoEditor) +}; + +struct DspModulePluginDemoAudioProcessor : public DspModulePluginDemo +{ + AudioProcessorEditor* createEditor() override + { + return new DspModulePluginDemoEditor (*this); + } + + bool hasEditor() const override { return true; } }; diff --git a/examples/Plugins/GainPluginDemo.h b/examples/Plugins/GainPluginDemo.h index 850c7de3..8cee85e1 100644 --- a/examples/Plugins/GainPluginDemo.h +++ b/examples/Plugins/GainPluginDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -62,8 +62,6 @@ public: addParameter (gain = new AudioParameterFloat ("gain", "Gain", 0.0f, 1.0f, 0.5f)); } - ~GainProcessor() {} - //============================================================================== void prepareToPlay (double, int) override {} void releaseResources() override {} @@ -73,6 +71,11 @@ public: buffer.applyGain (*gain); } + void processBlock (AudioBuffer<double>& buffer, MidiBuffer&) override + { + buffer.applyGain ((float) *gain); + } + //============================================================================== AudioProcessorEditor* createEditor() override { return new GenericAudioProcessorEditor (*this); } bool hasEditor() const override { return true; } diff --git a/examples/Plugins/InterAppAudioEffectPluginDemo.h b/examples/Plugins/InterAppAudioEffectPluginDemo.h index 4b750e86..76f5fb4e 100644 --- a/examples/Plugins/InterAppAudioEffectPluginDemo.h +++ b/examples/Plugins/InterAppAudioEffectPluginDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -23,24 +23,26 @@ BEGIN_JUCE_PIP_METADATA - name: InterAppAudioEffectPlugin - version: 1.0.0 - vendor: JUCE - website: http://juce.com - description: Inter-app audio effect plugin. + name: InterAppAudioEffectPlugin + version: 1.0.0 + vendor: JUCE + website: http://juce.com + description: Inter-app audio effect plugin. - dependencies: juce_audio_basics, juce_audio_devices, juce_audio_formats, - juce_audio_plugin_client, juce_audio_processors, - juce_audio_utils, juce_core, juce_data_structures, - juce_events, juce_graphics, juce_gui_basics, juce_gui_extra - exporters: xcode_iphone + dependencies: juce_audio_basics, juce_audio_devices, juce_audio_formats, + juce_audio_plugin_client, juce_audio_processors, + juce_audio_utils, juce_core, juce_data_structures, + juce_events, juce_graphics, juce_gui_basics, juce_gui_extra + exporters: xcode_iphone - moduleFlags: JUCE_STRICT_REFCOUNTEDPOINTER=1 + moduleFlags: JUCE_STRICT_REFCOUNTEDPOINTER=1 - type: AudioProcessor - mainClass: IAAEffectProcessor + type: AudioProcessor + mainClass: IAAEffectProcessor - useLocalCopy: 1 + useLocalCopy: 1 + + extraPluginFormats: IAA END_JUCE_PIP_METADATA @@ -77,8 +79,6 @@ public: g.fillRoundedRectangle (area.toFloat(), 6.0); } - void resized() override {} - //============================================================================== // Called from the audio thread. void update (float newLevel) @@ -157,8 +157,6 @@ public: { } - ~IAAEffectProcessor() {} - //============================================================================== void prepareToPlay (double, int) override { @@ -215,7 +213,7 @@ public: bool hasEditor() const override { return true; } //============================================================================== - const String getName() const override { return JucePlugin_Name; } + const String getName() const override { return "InterAppAudioEffectPlugin"; } bool acceptsMidi() const override { return false; } bool producesMidi() const override { return false; } double getTailLengthSeconds() const override { return 0.0; } @@ -284,11 +282,11 @@ private: IAAEffectEditor (IAAEffectProcessor& p, AudioProcessorValueTreeState& vts) : AudioProcessorEditor (p), - processor (p), + iaaEffectProcessor (p), parameters (vts) { // Register for meter value updates. - processor.addMeterListener (*this); + iaaEffectProcessor.addMeterListener (*this); gainSlider.setSliderStyle (Slider::SliderStyle::LinearVertical); gainSlider.setTextBoxStyle (Slider::TextEntryBoxPosition::TextBoxAbove, false, 60, 20); @@ -305,12 +303,12 @@ private: Path rewindShape; rewindShape.addRectangle (0.0, 0.0, 5.0, buttonSize); - rewindShape.addTriangle (0.0, buttonSize / 2, buttonSize, 0.0, buttonSize, buttonSize); + rewindShape.addTriangle (0.0, buttonSize * 0.5f, buttonSize, 0.0, buttonSize, buttonSize); rewindButton.setShape (rewindShape, true, true, false); rewindButton.onClick = [this] { if (transportControllable()) - processor.getPlayHead()->transportRewind(); + iaaEffectProcessor.getPlayHead()->transportRewind(); }; addChildComponent (rewindButton); @@ -320,7 +318,7 @@ private: playButton.onClick = [this] { if (transportControllable()) - processor.getPlayHead()->transportPlay (! lastPosInfo.isPlaying); + iaaEffectProcessor.getPlayHead()->transportPlay (! lastPosInfo.isPlaying); }; addChildComponent (playButton); @@ -330,7 +328,7 @@ private: recordButton.onClick = [this] { if (transportControllable()) - processor.getPlayHead()->transportRecord (! lastPosInfo.isRecording); + iaaEffectProcessor.getPlayHead()->transportRecord (! lastPosInfo.isRecording); }; addChildComponent (recordButton); @@ -351,7 +349,7 @@ private: }; addChildComponent (switchToHostButton); - auto screenSize = Desktop::getInstance().getDisplays().getMainDisplay().userArea; + auto screenSize = Desktop::getInstance().getDisplays().getPrimaryDisplay()->userArea; setSize (screenSize.getWidth(), screenSize.getHeight()); resized(); @@ -359,9 +357,9 @@ private: startTimerHz (60); } - ~IAAEffectEditor() + ~IAAEffectEditor() override { - processor.removeMeterListener (*this); + iaaEffectProcessor.removeMeterListener (*this); } //============================================================================== @@ -385,19 +383,19 @@ private: area.removeFromLeft (20); transportText.setBounds (area.removeFromTop (120)); - auto navigationArea = area.removeFromTop (buttonSize); + auto navigationArea = area.removeFromTop ((int) buttonSize); rewindButton.setTopLeftPosition (navigationArea.getPosition()); - navigationArea.removeFromLeft (buttonSize + 10); + navigationArea.removeFromLeft ((int) buttonSize + 10); playButton.setTopLeftPosition (navigationArea.getPosition()); - navigationArea.removeFromLeft (buttonSize + 10); + navigationArea.removeFromLeft ((int) buttonSize + 10); recordButton.setTopLeftPosition (navigationArea.getPosition()); area.removeFromTop (30); - auto appSwitchArea = area.removeFromTop (buttonSize); + auto appSwitchArea = area.removeFromTop ((int) buttonSize); switchToHostButtonLabel.setBounds (appSwitchArea.removeFromLeft (100)); appSwitchArea.removeFromLeft (5); - switchToHostButton.setBounds (appSwitchArea.removeFromLeft (buttonSize)); + switchToHostButton.setBounds (appSwitchArea.removeFromLeft ((int) buttonSize)); } private: @@ -411,7 +409,7 @@ private: //============================================================================== void timerCallback () override { - auto timeInfoSuccess = processor.updateCurrentTimeInfoFromHost (lastPosInfo); + auto timeInfoSuccess = iaaEffectProcessor.updateCurrentTimeInfoFromHost (lastPosInfo); transportText.setVisible (timeInfoSuccess); if (timeInfoSuccess) @@ -425,7 +423,7 @@ private: //============================================================================== bool transportControllable() { - auto playHead = processor.getPlayHead(); + auto playHead = iaaEffectProcessor.getPlayHead(); return playHead != nullptr && playHead->canControlTransport(); } @@ -481,8 +479,8 @@ private: void updateTransportButtonsDisplay() { - auto visible = processor.getPlayHead() != nullptr - && processor.getPlayHead()->canControlTransport(); + auto visible = iaaEffectProcessor.getPlayHead() != nullptr + && iaaEffectProcessor.getPlayHead()->canControlTransport(); if (rewindButton.isVisible() != visible) { @@ -515,7 +513,7 @@ private: if (visible) { - auto icon = hostType.getHostIcon (buttonSize); + auto icon = hostType.getHostIcon ((int) buttonSize); switchToHostButton.setImages(false, true, true, icon, 1.0, Colours::transparentBlack, icon, 1.0, Colours::transparentBlack, @@ -524,10 +522,10 @@ private: } } - IAAEffectProcessor& processor; + IAAEffectProcessor& iaaEffectProcessor; AudioProcessorValueTreeState& parameters; - const int buttonSize = 30; + const float buttonSize = 30.0f; const Colour defaultButtonColour = Colours::darkgrey; ShapeButton rewindButton {"Rewind", defaultButtonColour, defaultButtonColour, defaultButtonColour}; ShapeButton playButton {"Play", defaultButtonColour, defaultButtonColour, defaultButtonColour}; @@ -549,7 +547,6 @@ private: //============================================================================== AudioProcessorValueTreeState parameters; float previousGain = 0.0f; - std::array<float, 2> meterValues = { { 0, 0 } }; // This keeps a copy of the last set of timing info that was acquired during an // audio callback - the UI component will display this. diff --git a/examples/Plugins/MidiLoggerPluginDemo.h b/examples/Plugins/MidiLoggerPluginDemo.h new file mode 100644 index 00000000..89db564e --- /dev/null +++ b/examples/Plugins/MidiLoggerPluginDemo.h @@ -0,0 +1,345 @@ +/* + ============================================================================== + + This file is part of the JUCE examples. + Copyright (c) 2020 - Raw Material Software Limited + + 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. + + THE SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, + WHETHER EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR + PURPOSE, ARE DISCLAIMED. + + ============================================================================== +*/ + +/******************************************************************************* + The block below describes the properties of this PIP. A PIP is a short snippet + of code that can be read by the Projucer and used to generate a JUCE project. + + BEGIN_JUCE_PIP_METADATA + + name: MIDILogger + version: 1.0.0 + vendor: JUCE + website: http://juce.com + description: Logs incoming MIDI messages. + + dependencies: juce_audio_basics, juce_audio_devices, juce_audio_formats, + juce_audio_plugin_client, juce_audio_processors, + juce_audio_utils, juce_core, juce_data_structures, + juce_events, juce_graphics, juce_gui_basics, juce_gui_extra + exporters: xcode_mac, vs2019, linux_make + + moduleFlags: JUCE_STRICT_REFCOUNTEDPOINTER=1 + + type: AudioProcessor + mainClass: MidiLoggerPluginDemoProcessor + + useLocalCopy: 1 + + pluginCharacteristics: pluginWantsMidiIn, pluginProducesMidiOut + + END_JUCE_PIP_METADATA + +*******************************************************************************/ + +#pragma once + +#include <iterator> + +class MidiQueue +{ +public: + void push (const MidiBuffer& buffer) + { + for (const auto metadata : buffer) + fifo.write (1).forEach ([&] (int dest) { messages[(size_t) dest] = metadata.getMessage(); }); + } + + template <typename OutputIt> + void pop (OutputIt out) + { + fifo.read (fifo.getNumReady()).forEach ([&] (int source) { *out++ = messages[(size_t) source]; }); + } + +private: + static constexpr auto queueSize = 1 << 14; + AbstractFifo fifo { queueSize }; + std::vector<MidiMessage> messages = std::vector<MidiMessage> (queueSize); +}; + +// Stores the last N messages. Safe to access from the message thread only. +class MidiListModel +{ +public: + template <typename It> + void addMessages (It begin, It end) + { + const auto numNewMessages = (int) std::distance (begin, end); + const auto numToAdd = juce::jmin (numToStore, numNewMessages); + const auto numToRemove = jmax (0, (int) messages.size() + numToAdd - numToStore); + messages.erase (messages.begin(), std::next (messages.begin(), numToRemove)); + messages.insert (messages.end(), std::prev (end, numToAdd), end); + + if (onChange != nullptr) + onChange(); + } + + void clear() + { + messages.clear(); + + if (onChange != nullptr) + onChange(); + } + + const MidiMessage& operator[] (size_t ind) const { return messages[ind]; } + + size_t size() const { return messages.size(); } + + std::function<void()> onChange; + +private: + static constexpr auto numToStore = 1000; + std::vector<MidiMessage> messages; +}; + +//============================================================================== +class MidiTable : public Component, + private TableListBoxModel +{ +public: + MidiTable (MidiListModel& m) + : messages (m) + { + addAndMakeVisible (table); + + table.setModel (this); + table.setClickingTogglesRowSelection (false); + table.setHeader ([&] + { + auto header = std::make_unique<TableHeaderComponent>(); + header->addColumn ("Message", messageColumn, 200, 30, -1, TableHeaderComponent::notSortable); + header->addColumn ("Channel", channelColumn, 100, 30, -1, TableHeaderComponent::notSortable); + header->addColumn ("Data", dataColumn, 200, 30, -1, TableHeaderComponent::notSortable); + return header; + }()); + + messages.onChange = [&] { table.updateContent(); }; + } + + ~MidiTable() override { messages.onChange = nullptr; } + + void resized() override { table.setBounds (getLocalBounds()); } + +private: + enum + { + messageColumn = 1, + channelColumn, + dataColumn + }; + + int getNumRows() override { return (int) messages.size(); } + + void paintRowBackground (Graphics&, int, int, int, bool) override {} + void paintCell (Graphics&, int, int, int, int, bool) override {} + + Component* refreshComponentForCell (int rowNumber, + int columnId, + bool, + Component* existingComponentToUpdate) override + { + delete existingComponentToUpdate; + + const auto index = (int) messages.size() - 1 - rowNumber; + const auto message = messages[(size_t) index]; + + return new Label ({}, [&] + { + switch (columnId) + { + case messageColumn: return getEventString (message); + case channelColumn: return String (message.getChannel()); + case dataColumn: return getDataString (message); + default: break; + } + + jassertfalse; + return String(); + }()); + } + + static String getEventString (const MidiMessage& m) + { + if (m.isNoteOn()) return "Note on"; + if (m.isNoteOff()) return "Note off"; + if (m.isProgramChange()) return "Program change"; + if (m.isPitchWheel()) return "Pitch wheel"; + if (m.isAftertouch()) return "Aftertouch"; + if (m.isChannelPressure()) return "Channel pressure"; + if (m.isAllNotesOff()) return "All notes off"; + if (m.isAllSoundOff()) return "All sound off"; + if (m.isMetaEvent()) return "Meta event"; + + if (m.isController()) + { + const auto* name = MidiMessage::getControllerName (m.getControllerNumber()); + return "Controller " + (name == nullptr ? String (m.getControllerNumber()) : String (name)); + } + + return String::toHexString (m.getRawData(), m.getRawDataSize()); + } + + static String getDataString (const MidiMessage& m) + { + if (m.isNoteOn()) return MidiMessage::getMidiNoteName (m.getNoteNumber(), true, true, 3) + " Velocity " + String (m.getVelocity()); + if (m.isNoteOff()) return MidiMessage::getMidiNoteName (m.getNoteNumber(), true, true, 3) + " Velocity " + String (m.getVelocity()); + if (m.isProgramChange()) return String (m.getProgramChangeNumber()); + if (m.isPitchWheel()) return String (m.getPitchWheelValue()); + if (m.isAftertouch()) return MidiMessage::getMidiNoteName (m.getNoteNumber(), true, true, 3) + ": " + String (m.getAfterTouchValue()); + if (m.isChannelPressure()) return String (m.getChannelPressureValue()); + if (m.isController()) return String (m.getControllerValue()); + + return {}; + } + + MidiListModel& messages; + TableListBox table; +}; + +//============================================================================== +class MidiLoggerPluginDemoProcessor : public AudioProcessor, + private Timer +{ +public: + MidiLoggerPluginDemoProcessor() + : AudioProcessor (getBusesLayout()) + { + state.addChild ({ "uiState", { { "width", 500 }, { "height", 300 } }, {} }, -1, nullptr); + startTimerHz (60); + } + + ~MidiLoggerPluginDemoProcessor() override { stopTimer(); } + + void processBlock (AudioBuffer<float>& audio, MidiBuffer& midi) override { process (audio, midi); } + void processBlock (AudioBuffer<double>& audio, MidiBuffer& midi) override { process (audio, midi); } + + bool isBusesLayoutSupported (const BusesLayout&) const override { return true; } + bool isMidiEffect() const override { return true; } + bool hasEditor() const override { return true; } + AudioProcessorEditor* createEditor() override { return new Editor (*this); } + + const String getName() const override { return "MIDI Logger"; } + bool acceptsMidi() const override { return true; } + bool producesMidi() const override { return true; } + double getTailLengthSeconds() const override { return 0.0; } + + int getNumPrograms() override { return 0; } + int getCurrentProgram() override { return 0; } + void setCurrentProgram (int) override {} + const String getProgramName (int) override { return {}; } + void changeProgramName (int, const String&) override {} + + void prepareToPlay (double, int) override {} + void releaseResources() override {} + + void getStateInformation (MemoryBlock& destData) override + { + if (auto xmlState = state.createXml()) + copyXmlToBinary (*xmlState, destData); + } + + void setStateInformation (const void* data, int size) override + { + if (auto xmlState = getXmlFromBinary (data, size)) + state = ValueTree::fromXml (*xmlState); + } + +private: + class Editor : public AudioProcessorEditor, + private Value::Listener + { + public: + explicit Editor (MidiLoggerPluginDemoProcessor& ownerIn) + : AudioProcessorEditor (ownerIn), + owner (ownerIn), + table (owner.model) + { + addAndMakeVisible (table); + addAndMakeVisible (clearButton); + + setResizable (true, true); + lastUIWidth .referTo (owner.state.getChildWithName ("uiState").getPropertyAsValue ("width", nullptr)); + lastUIHeight.referTo (owner.state.getChildWithName ("uiState").getPropertyAsValue ("height", nullptr)); + setSize (lastUIWidth.getValue(), lastUIHeight.getValue()); + + lastUIWidth. addListener (this); + lastUIHeight.addListener (this); + + clearButton.onClick = [&] { owner.model.clear(); }; + } + + void paint (Graphics& g) override + { + g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId)); + } + + void resized() override + { + auto bounds = getLocalBounds(); + + clearButton.setBounds (bounds.removeFromBottom (30).withSizeKeepingCentre (50, 24)); + table.setBounds (bounds); + + lastUIWidth = getWidth(); + lastUIHeight = getHeight(); + } + + private: + void valueChanged (Value&) override + { + setSize (lastUIWidth.getValue(), lastUIHeight.getValue()); + } + + MidiLoggerPluginDemoProcessor& owner; + + MidiTable table; + TextButton clearButton { "Clear" }; + + Value lastUIWidth, lastUIHeight; + }; + + void timerCallback() override + { + std::vector<MidiMessage> messages; + queue.pop (std::back_inserter (messages)); + model.addMessages (messages.begin(), messages.end()); + } + + template <typename Element> + void process (AudioBuffer<Element>& audio, MidiBuffer& midi) + { + audio.clear(); + queue.push (midi); + } + + static BusesProperties getBusesLayout() + { + // Live doesn't like to load midi-only plugins, so we add an audio output there. + return PluginHostType().isAbletonLive() ? BusesProperties().withOutput ("out", AudioChannelSet::stereo()) + : BusesProperties(); + } + + ValueTree state { "state" }; + MidiQueue queue; + MidiListModel model; // The data to show in the UI. We keep it around in the processor so that + // the view is persistent even when the plugin UI is closed and reopened. + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiLoggerPluginDemoProcessor) +}; diff --git a/examples/Plugins/MultiOutSynthPluginDemo.h b/examples/Plugins/MultiOutSynthPluginDemo.h index 0424acc2..a7ecd7a9 100644 --- a/examples/Plugins/MultiOutSynthPluginDemo.h +++ b/examples/Plugins/MultiOutSynthPluginDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -23,24 +23,26 @@ BEGIN_JUCE_PIP_METADATA - name: MultiOutSynthPlugin - version: 1.0.0 - vendor: JUCE - website: http://juce.com - description: Multi-out synthesiser audio plugin. + name: MultiOutSynthPlugin + version: 1.0.0 + vendor: JUCE + website: http://juce.com + description: Multi-out synthesiser audio plugin. - dependencies: juce_audio_basics, juce_audio_devices, juce_audio_formats, - juce_audio_plugin_client, juce_audio_processors, - juce_audio_utils, juce_core, juce_data_structures, - juce_events, juce_graphics, juce_gui_basics, juce_gui_extra - exporters: xcode_mac, vs2019 + dependencies: juce_audio_basics, juce_audio_devices, juce_audio_formats, + juce_audio_plugin_client, juce_audio_processors, + juce_audio_utils, juce_core, juce_data_structures, + juce_events, juce_graphics, juce_gui_basics, juce_gui_extra + exporters: xcode_mac, vs2019 - moduleFlags: JUCE_STRICT_REFCOUNTEDPOINTER=1 + moduleFlags: JUCE_STRICT_REFCOUNTEDPOINTER=1 - type: AudioProcessor - mainClass: MultiOutSynth + type: AudioProcessor + mainClass: MultiOutSynth - useLocalCopy: 1 + useLocalCopy: 1 + + pluginCharacteristics: pluginIsSynth, pluginWantsMidiIn END_JUCE_PIP_METADATA @@ -94,8 +96,6 @@ public: loadNewSample (createAssetInputStream ("singing.ogg"), "ogg"); } - ~MultiOutSynth() {} - //============================================================================== bool canAddBus (bool isInput) const override { return (! isInput && getBusCount (false) < maxMidiChannel); } bool canRemoveBus (bool isInput) const override { return (! isInput && getBusCount (false) > 1); } @@ -124,6 +124,8 @@ public: } } + using AudioProcessor::processBlock; + //============================================================================== AudioProcessorEditor* createEditor() override { return new GenericAudioProcessorEditor (*this); } bool hasEditor() const override { return true; } @@ -147,19 +149,22 @@ private: //============================================================================== static MidiBuffer filterMidiMessagesForChannel (const MidiBuffer& input, int channel) { - MidiMessage msg; - int samplePosition; MidiBuffer output; - for (MidiBuffer::Iterator it (input); it.getNextEvent (msg, samplePosition);) - if (msg.getChannel() == channel) output.addEvent (msg, samplePosition); + for (const auto metadata : input) + { + const auto message = metadata.getMessage(); + + if (message.getChannel() == channel) + output.addEvent (message, metadata.samplePosition); + } return output; } - void loadNewSample (InputStream* soundBuffer, const char* format) + void loadNewSample (std::unique_ptr<InputStream> soundBuffer, const char* format) { - std::unique_ptr<AudioFormatReader> formatReader (formatManager.findFormatForFileExtension (format)->createReaderFor (soundBuffer, true)); + std::unique_ptr<AudioFormatReader> formatReader (formatManager.findFormatForFileExtension (format)->createReaderFor (soundBuffer.release(), true)); BigInteger midiNotes; midiNotes.setRange (0, 126, true); diff --git a/examples/Plugins/NoiseGatePluginDemo.h b/examples/Plugins/NoiseGatePluginDemo.h index 620e0936..6ce226a0 100644 --- a/examples/Plugins/NoiseGatePluginDemo.h +++ b/examples/Plugins/NoiseGatePluginDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -63,8 +63,6 @@ public: addParameter (alpha = new AudioParameterFloat ("alpha", "Alpha", 0.0f, 1.0f, 0.8f)); } - ~NoiseGate() {} - //============================================================================== bool isBusesLayoutSupported (const BusesLayout& layouts) const override { @@ -107,6 +105,8 @@ public: } } + using AudioProcessor::processBlock; + //============================================================================== AudioProcessorEditor* createEditor() override { return new GenericAudioProcessorEditor (*this); } bool hasEditor() const override { return true; } diff --git a/examples/Plugins/SamplerPluginDemo.h b/examples/Plugins/SamplerPluginDemo.h index 107fb664..05405d87 100644 --- a/examples/Plugins/SamplerPluginDemo.h +++ b/examples/Plugins/SamplerPluginDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -95,53 +95,73 @@ enum class LoopMode pingpong }; -template <typename Movable> -class MoveOnlyFifo final +// We want to send type-erased commands to the audio thread, but we also +// want those commands to contain move-only resources, so that we can +// construct resources on the gui thread, and then transfer ownership +// cheaply to the audio thread. We can't do this with std::function +// because it enforces that functions are copy-constructible. +// Therefore, we use a very simple templated type-eraser here. +template <typename Proc> +struct Command +{ + virtual ~Command() noexcept = default; + virtual void run (Proc& proc) = 0; +}; + +template <typename Proc, typename Func> +class TemplateCommand : public Command<Proc>, + private Func { public: - explicit MoveOnlyFifo (int size) + template <typename FuncPrime> + explicit TemplateCommand (FuncPrime&& funcPrime) + : Func (std::forward<FuncPrime> (funcPrime)) + {} + + void run (Proc& proc) override { (*this) (proc); } +}; + +template <typename Proc> +class CommandFifo final +{ +public: + explicit CommandFifo (int size) : buffer ((size_t) size), abstractFifo (size) {} - MoveOnlyFifo() - : MoveOnlyFifo (1024) + CommandFifo() + : CommandFifo (1024) {} - template <typename Convertible> - Convertible push (Convertible item) noexcept + template <typename Item> + void push (Item&& item) noexcept { - auto writer = abstractFifo.write (1); + auto command = makeCommand (std::forward<Item> (item)); - if (writer.blockSize1 == 1) - { - buffer[(size_t) writer.startIndex1] = move (item); - item = {}; - } - else if (writer.blockSize2 == 1) + abstractFifo.write (1).forEach ([&] (int index) { - buffer[(size_t) writer.startIndex2] = move (item); - item = {}; - } - - return item; + buffer[size_t (index)] = std::move (command); + }); } - Movable pop() noexcept + void call (Proc& proc) noexcept { - auto reader = abstractFifo.read (1); - - if (reader.blockSize1 == 1) - return move (buffer[(size_t) reader.startIndex1]); - - if (reader.blockSize2 == 1) - return move (buffer[(size_t) reader.startIndex2]); - - return {}; + abstractFifo.read (abstractFifo.getNumReady()).forEach ([&] (int index) + { + buffer[size_t (index)]->run (proc); + }); } private: - std::vector<Movable> buffer; + template <typename Func> + static std::unique_ptr<Command<Proc>> makeCommand (Func&& func) + { + using Decayed = typename std::decay<Func>::type; + return std::make_unique<TemplateCommand<Proc, Decayed>> (std::forward<Func> (func)); + } + + std::vector<std::unique_ptr<Command<Proc>>> buffer; AbstractFifo abstractFifo; }; @@ -239,7 +259,7 @@ class MPESamplerVoice : public MPESynthesiserVoice { public: explicit MPESamplerVoice (std::shared_ptr<const MPESamplerSound> sound) - : samplerSound (move (sound)) + : samplerSound (std::move (sound)) { jassert (samplerSound != nullptr); } @@ -290,6 +310,25 @@ public: void renderNextBlock (AudioBuffer<float>& outputBuffer, int startSample, int numSamples) override + { + render (outputBuffer, startSample, numSamples); + } + + void renderNextBlock (AudioBuffer<double>& outputBuffer, + int startSample, + int numSamples) override + { + render (outputBuffer, startSample, numSamples); + } + + double getCurrentSamplePosition() const + { + return currentSamplePos; + } + +private: + template <typename Element> + void render (AudioBuffer<Element>& outputBuffer, int startSample, int numSamples) { jassert (samplerSound->getSample() != nullptr); @@ -316,16 +355,11 @@ public: writePos += 1; } - double getCurrentSamplePosition() const - { - return currentSamplePos; - } - -private: + template <typename Element> bool renderNextSample (const float* inL, const float* inR, - float* outL, - float* outR, + Element* outL, + Element* outR, size_t writePos) { auto currentLevel = level.getNextValue(); @@ -347,13 +381,13 @@ private: auto pos = (int) currentSamplePos; auto nextPos = pos + 1; - auto alpha = (float) (currentSamplePos - pos); + auto alpha = (Element) (currentSamplePos - pos); auto invAlpha = 1.0f - alpha; // just using a very simple linear interpolation here.. - auto l = static_cast<float> (currentLevel * (inL[pos] * invAlpha + inL[nextPos] * alpha)); - auto r = static_cast<float> ((inR != nullptr) ? currentLevel * (inR[pos] * invAlpha + inR[nextPos] * alpha) - : l); + auto l = static_cast<Element> (currentLevel * (inL[pos] * invAlpha + inL[nextPos] * alpha)); + auto r = static_cast<Element> ((inR != nullptr) ? currentLevel * (inR[pos] * invAlpha + inR[nextPos] * alpha) + : l); if (outR != nullptr) { @@ -416,6 +450,9 @@ private: case Direction::backward: nextSamplePos -= nextPitchRatio; break; + + default: + break; } // Update current sample position, taking loop mode into account @@ -426,11 +463,11 @@ private: nextSamplePos = begin; nextDirection = Direction::forward; - return { nextSamplePos, nextDirection }; + return std::tuple<double, Direction> (nextSamplePos, nextDirection); } if (samplerSound->getLoopMode() == LoopMode::none) - return { nextSamplePos, nextDirection }; + return std::tuple<double, Direction> (nextSamplePos, nextDirection); if (nextDirection == Direction::forward && end < nextSamplePos && !isTailingOff()) { @@ -442,7 +479,7 @@ private: nextDirection = Direction::backward; } } - return { nextSamplePos, nextDirection }; + return std::tuple<double, Direction> (nextSamplePos, nextDirection); } std::shared_ptr<const MPESamplerSound> samplerSound; @@ -492,9 +529,9 @@ inline std::unique_ptr<AudioFormatReader> makeAudioFormatReader (AudioFormatMana const void* sampleData, size_t dataSize) { - return std::unique_ptr<AudioFormatReader> (manager.createReaderFor (new MemoryInputStream (sampleData, - dataSize, - false))); + return std::unique_ptr<AudioFormatReader> (manager.createReaderFor (std::make_unique<MemoryInputStream> (sampleData, + dataSize, + false))); } inline std::unique_ptr<AudioFormatReader> makeAudioFormatReader (AudioFormatManager& manager, @@ -516,12 +553,12 @@ public: class MemoryAudioFormatReaderFactory : public AudioFormatReaderFactory { public: - MemoryAudioFormatReaderFactory (const void* sampleData, size_t dataSize) - : sampleData (sampleData), - dataSize (dataSize) + MemoryAudioFormatReaderFactory (const void* sampleDataIn, size_t dataSizeIn) + : sampleData (sampleDataIn), + dataSize (dataSizeIn) {} - std::unique_ptr<AudioFormatReader> make (AudioFormatManager&manager ) const override + std::unique_ptr<AudioFormatReader> make (AudioFormatManager& manager) const override { return makeAudioFormatReader (manager, sampleData, dataSize); } @@ -540,8 +577,8 @@ private: class FileAudioFormatReaderFactory : public AudioFormatReaderFactory { public: - explicit FileAudioFormatReaderFactory (File file) - : file (std::move (file)) + explicit FileAudioFormatReaderFactory (File fileIn) + : file (std::move (fileIn)) {} std::unique_ptr<AudioFormatReader> make (AudioFormatManager& manager) const override @@ -621,7 +658,7 @@ struct VariantConverter<std::shared_ptr<AudioFormatReaderFactory>> } // namespace juce //============================================================================== -class VisibleRangeDataModel : public ValueTree::Listener +class VisibleRangeDataModel : private ValueTree::Listener { public: class Listener @@ -722,7 +759,7 @@ private: }; //============================================================================== -class MPESettingsDataModel : public ValueTree::Listener +class MPESettingsDataModel : private ValueTree::Listener { public: class Listener @@ -912,7 +949,7 @@ private: }; //============================================================================== -class DataModel : public ValueTree::Listener +class DataModel : private ValueTree::Listener { public: class Listener @@ -925,12 +962,12 @@ public: virtual void loopPointsSecondsChanged (Range<double>) {} }; - explicit DataModel (AudioFormatManager& audioFormatManager) - : DataModel (audioFormatManager, ValueTree (IDs::DATA_MODEL)) + explicit DataModel (AudioFormatManager& audioFormatManagerIn) + : DataModel (audioFormatManagerIn, ValueTree (IDs::DATA_MODEL)) {} - DataModel (AudioFormatManager& audioFormatManager, const ValueTree& vt) - : audioFormatManager (&audioFormatManager), + DataModel (AudioFormatManager& audioFormatManagerIn, const ValueTree& vt) + : audioFormatManager (&audioFormatManagerIn), valueTree (vt), sampleReader (valueTree, IDs::sampleReader, nullptr), centreFrequencyHz (valueTree, IDs::centreFrequencyHz, nullptr), @@ -968,7 +1005,7 @@ public: double getSampleLengthSeconds() const { if (auto r = getSampleReader()) - return r->lengthInSamples / r->sampleRate; + return (double) r->lengthInSamples / r->sampleRate; return 1.0; } @@ -1098,7 +1135,7 @@ constexpr int controlSeparation = 6; //============================================================================== class MPELegacySettingsComponent final : public Component, - public MPESettingsDataModel::Listener + private MPESettingsDataModel::Listener { public: explicit MPELegacySettingsComponent (const MPESettingsDataModel& model, @@ -1220,7 +1257,7 @@ private: //============================================================================== class MPENewSettingsComponent final : public Component, - public MPESettingsDataModel::Listener + private MPESettingsDataModel::Listener { public: MPENewSettingsComponent (const MPESettingsDataModel& model, @@ -1316,7 +1353,7 @@ private: //============================================================================== class MPESettingsComponent final : public Component, - public MPESettingsDataModel::Listener + private MPESettingsDataModel::Listener { public: MPESettingsComponent (const MPESettingsDataModel& model, @@ -1415,13 +1452,13 @@ public: using MouseCallback = std::function<void (LoopPointMarker&, const MouseEvent&)>; LoopPointMarker (String marker, - MouseCallback onMouseDown, - MouseCallback onMouseDrag, - MouseCallback onMouseUp) + MouseCallback onMouseDownIn, + MouseCallback onMouseDragIn, + MouseCallback onMouseUpIn) : text (std::move (marker)), - onMouseDown (move (onMouseDown)), - onMouseDrag (move (onMouseDrag)), - onMouseUp (move (onMouseUp)) + onMouseDown (std::move (onMouseDownIn)), + onMouseDrag (std::move (onMouseDragIn)), + onMouseUp (std::move (onMouseUpIn)) { setMouseCursor (MouseCursor::LeftRightResizeCursor); } @@ -1487,7 +1524,7 @@ private: //============================================================================== class Ruler : public Component, - public VisibleRangeDataModel::Listener + private VisibleRangeDataModel::Listener { public: explicit Ruler (const VisibleRangeDataModel& model) @@ -1501,7 +1538,7 @@ private: void paint (Graphics& g) override { auto minDivisionWidth = 50.0f; - auto maxDivisions = getWidth() / minDivisionWidth; + auto maxDivisions = (float) getWidth() / minDivisionWidth; auto lookFeel = dynamic_cast<LookAndFeel_V4*> (&getLookAndFeel()); auto bg = lookFeel->getCurrentColourScheme() @@ -1533,14 +1570,13 @@ private: auto xPos = (time - visibleRange.getVisibleRange().getStart()) * getWidth() / visibleRange.getVisibleRange().getLength(); - std::ostringstream out_stream; - out_stream << std::setprecision (roundToInt (precision)) << roundToInt (time); + std::ostringstream outStream; + outStream << std::setprecision (roundToInt (precision)) << time; - g.drawText (out_stream.str(), - Rectangle<int> (Point<int> (roundToInt (xPos) + 3, 0), - Point<int> (roundToInt (xPos + minDivisionWidth), getHeight())), - Justification::centredLeft, - false); + const auto bounds = Rectangle<int> (Point<int> (roundToInt (xPos) + 3, 0), + Point<int> (roundToInt (xPos + minDivisionWidth), getHeight())); + + g.drawText (outStream.str(), bounds, Justification::centredLeft, false); g.drawVerticalLine (roundToInt (xPos), 2.0f, (float) getHeight()); } @@ -1557,7 +1593,7 @@ private: { // Work out the scale of the new range auto unitDistance = 100.0f; - auto scaleFactor = 1.0 / std::pow (2, e.getDistanceFromDragStartY() / unitDistance); + auto scaleFactor = 1.0 / std::pow (2, (float) e.getDistanceFromDragStartY() / unitDistance); // Now position it so that the mouse continues to point at the same // place on the ruler. @@ -1579,13 +1615,13 @@ private: //============================================================================== class LoopPointsOverlay : public Component, - public DataModel::Listener, - public VisibleRangeDataModel::Listener + private DataModel::Listener, + private VisibleRangeDataModel::Listener { public: LoopPointsOverlay (const DataModel& dModel, const VisibleRangeDataModel& vModel, - UndoManager& undoManager) + UndoManager& undoManagerIn) : dataModel (dModel), visibleRange (vModel), beginMarker ("B", @@ -1596,7 +1632,7 @@ public: [this] (LoopPointMarker& m, const MouseEvent& e) { this->loopPointMouseDown (m, e); }, [this] (LoopPointMarker& m, const MouseEvent& e) { this->loopPointDragged (m, e); }, [this] (LoopPointMarker& m, const MouseEvent& e) { this->loopPointMouseUp (m, e); }), - undoManager (&undoManager) + undoManager (&undoManagerIn) { dataModel .addListener (*this); visibleRange.addListener (*this); @@ -1680,15 +1716,15 @@ private: //============================================================================== class PlaybackPositionOverlay : public Component, - public Timer, - public VisibleRangeDataModel::Listener + private Timer, + private VisibleRangeDataModel::Listener { public: using Provider = std::function<std::vector<float>()>; PlaybackPositionOverlay (const VisibleRangeDataModel& model, - Provider provider) + Provider providerIn) : visibleRange (model), - provider (move (provider)) + provider (std::move (providerIn)) { visibleRange.addListener (*this); startTimer (16); @@ -1727,9 +1763,9 @@ private: //============================================================================== class WaveformView : public Component, - public ChangeListener, - public DataModel::Listener, - public VisibleRangeDataModel::Listener + private ChangeListener, + private DataModel::Listener, + private VisibleRangeDataModel::Listener { public: WaveformView (const DataModel& model, @@ -1775,14 +1811,18 @@ private: void sampleReaderChanged (std::shared_ptr<AudioFormatReaderFactory> value) override { - if (value == nullptr) - thumbnail.clear(); - else + if (value != nullptr) { - auto reader = value->make (dataModel.getAudioFormatManager()); - thumbnail.setReader (reader.release(), currentHashCode); - currentHashCode += 1; + if (auto reader = value->make (dataModel.getAudioFormatManager())) + { + thumbnail.setReader (reader.release(), currentHashCode); + currentHashCode += 1; + + return; + } } + + thumbnail.clear(); } void visibleRangeChanged (Range<double>) override @@ -1814,7 +1854,7 @@ private: //============================================================================== class WaveformEditor : public Component, - public DataModel::Listener + private DataModel::Listener { public: WaveformEditor (const DataModel& model, @@ -1853,7 +1893,7 @@ private: loopPoints.setVisible (value != LoopMode::none); } - void sampleReaderChanged (std::shared_ptr<AudioFormatReaderFactory> value) override + void sampleReaderChanged (std::shared_ptr<AudioFormatReaderFactory>) override { auto lengthInSeconds = dataModel.getSampleLengthSeconds(); visibleRange.setTotalRange (Range<double> (0, lengthInSeconds), nullptr); @@ -1870,7 +1910,8 @@ private: //============================================================================== class MainSamplerView : public Component, - public DataModel::Listener + private DataModel::Listener, + private ChangeListener { public: MainSamplerView (const DataModel& model, @@ -1878,19 +1919,26 @@ public: UndoManager& um) : dataModel (model), waveformEditor (dataModel, move (provider), um), - undoManager (&um) + undoManager (um) { dataModel.addListener (*this); addAndMakeVisible (waveformEditor); addAndMakeVisible (loadNewSampleButton); + addAndMakeVisible (undoButton); + addAndMakeVisible (redoButton); auto setReader = [this] (const FileChooser& fc) { - undoManager->beginNewTransaction(); - auto readerFactory = new FileAudioFormatReaderFactory (fc.getResult()); - dataModel.setSampleReader (std::unique_ptr<AudioFormatReaderFactory> (readerFactory), - undoManager); + const auto result = fc.getResult(); + + if (result != File()) + { + undoManager.beginNewTransaction(); + auto readerFactory = new FileAudioFormatReaderFactory (result); + dataModel.setSampleReader (std::unique_ptr<AudioFormatReaderFactory> (readerFactory), + &undoManager); + } }; loadNewSampleButton.onClick = [this, setReader] @@ -1903,9 +1951,9 @@ public: addAndMakeVisible (centreFrequency); centreFrequency.onValueChange = [this] { - undoManager->beginNewTransaction(); + undoManager.beginNewTransaction(); dataModel.setCentreFrequencyHz (centreFrequency.getValue(), - centreFrequency.isMouseButtonDown() ? nullptr : undoManager); + centreFrequency.isMouseButtonDown() ? nullptr : &undoManager); }; centreFrequency.setRange (20, 20000, 1); @@ -1925,8 +1973,8 @@ public: { if (loopKindNone.getToggleState()) { - undoManager->beginNewTransaction(); - dataModel.setLoopMode (LoopMode::none, undoManager); + undoManager.beginNewTransaction(); + dataModel.setLoopMode (LoopMode::none, &undoManager); } }; @@ -1934,8 +1982,8 @@ public: { if (loopKindForward.getToggleState()) { - undoManager->beginNewTransaction(); - dataModel.setLoopMode (LoopMode::forward, undoManager); + undoManager.beginNewTransaction(); + dataModel.setLoopMode (LoopMode::forward, &undoManager); } }; @@ -1943,16 +1991,36 @@ public: { if (loopKindPingpong.getToggleState()) { - undoManager->beginNewTransaction(); - dataModel.setLoopMode (LoopMode::pingpong, undoManager); + undoManager.beginNewTransaction(); + dataModel.setLoopMode (LoopMode::pingpong, &undoManager); } }; + undoButton.onClick = [this] { undoManager.undo(); }; + redoButton.onClick = [this] { undoManager.redo(); }; + addAndMakeVisible (centreFrequencyLabel); addAndMakeVisible (loopKindLabel); + + changeListenerCallback (&undoManager); + undoManager.addChangeListener (this); + } + + ~MainSamplerView() override + { + undoManager.removeChangeListener (this); } private: + void changeListenerCallback (ChangeBroadcaster* source) override + { + if (source == &undoManager) + { + undoButton.setEnabled (undoManager.canUndo()); + redoButton.setEnabled (undoManager.canRedo()); + } + } + void resized() override { auto bounds = getLocalBounds(); @@ -1960,6 +2028,8 @@ private: auto topBar = bounds.removeFromTop (50); auto padding = 4; loadNewSampleButton .setBounds (topBar.removeFromRight (100).reduced (padding)); + redoButton .setBounds (topBar.removeFromRight (100).reduced (padding)); + undoButton .setBounds (topBar.removeFromRight (100).reduced (padding)); centreFrequencyLabel.setBounds (topBar.removeFromLeft (100).reduced (padding)); centreFrequency .setBounds (topBar.removeFromLeft (100).reduced (padding)); @@ -1985,6 +2055,9 @@ private: case LoopMode::pingpong: loopKindPingpong.setToggleState (true, dontSendNotification); break; + + default: + break; } } @@ -1996,6 +2069,8 @@ private: DataModel dataModel; WaveformEditor waveformEditor; TextButton loadNewSampleButton { "Load New Sample" }; + TextButton undoButton { "Undo" }; + TextButton redoButton { "Redo" }; Slider centreFrequency; TextButton loopKindNone { "None" }, @@ -2009,7 +2084,7 @@ private: FileChooser fileChooser { "Select a file to load...", File(), dataModel.getAudioFormatManager().getWildcardForAllFormats() }; - UndoManager* undoManager; + UndoManager& undoManager; }; //============================================================================== @@ -2027,34 +2102,6 @@ struct ProcessorState LoopMode loopMode; }; -//============================================================================== -// We store the current sampler sound in a shared_ptr. Although we never -// call mutating member functions on this shared_ptr, we do read from it on -// both the audio and gui threads. Such concurrent reads should be safe -// without using atomic methods, but we use a tiny wrapper to enforce atomic -// accesses anyway - if nothing else, this wrapper enforces and documents that -// we never mutate the shared_ptr in a way which could cause a data race. -template <typename Contents> -class AtomicSharedPtr final -{ -public: - AtomicSharedPtr() = default; - explicit AtomicSharedPtr (std::shared_ptr<Contents> contents) - : contents (move (contents)) - {} - - AtomicSharedPtr (const AtomicSharedPtr& other) = delete; - AtomicSharedPtr& operator= (const AtomicSharedPtr& other) = delete; - - std::shared_ptr<Contents> load() const - { - return atomic_load (&contents); - } - -private: - std::shared_ptr<Contents> contents; -}; - //============================================================================== class SamplerAudioProcessor : public AudioProcessor { @@ -2062,11 +2109,9 @@ public: SamplerAudioProcessor() : AudioProcessor (BusesProperties().withOutput ("Output", AudioChannelSet::stereo(), true)) { - if (auto* asset = createAssetInputStream ("cello.wav")) + if (auto inputStream = createAssetInputStream ("cello.wav")) { - std::unique_ptr<InputStream> inputStream (asset); inputStream->readIntoMemoryBlock (mb); - readerFactory.reset (new MemoryAudioFormatReaderFactory (mb.getData(), mb.getSize())); } @@ -2074,7 +2119,9 @@ public: AudioFormatManager manager; manager.registerBasicFormats(); auto reader = readerFactory->make (manager); - auto sound = samplerSound.load(); + jassert (reader != nullptr); // Failed to load resource! + + auto sound = samplerSound; auto sample = std::unique_ptr<Sample> (new Sample (*reader, 10.0)); auto lengthInSeconds = sample->getLength() / sample->getSampleRate(); sound->setLoopPointsInSeconds ({lengthInSeconds * 0.1, lengthInSeconds * 0.9 }); @@ -2104,7 +2151,7 @@ public: // This function will be called from the message thread. We lock the command // queue to ensure that no messages are processed for the duration of this // call. - std::lock_guard<std::mutex> lock (commandQueueMutex); + SpinLock::ScopedLockType lock (commandQueueMutex); ProcessorState state; state.synthVoices = synthesiser.getNumVoices(); @@ -2115,7 +2162,7 @@ public: state.mpeZoneLayout = synthesiser.getZoneLayout(); state.readerFactory = readerFactory == nullptr ? nullptr : readerFactory->clone(); - auto sound = samplerSound.load(); + auto sound = samplerSound; state.loopPointsSeconds = sound->getLoopPointsInSeconds(); state.centreFrequencyHz = sound->getCentreFrequencyInHz(); state.loopMode = sound->getLoopMode(); @@ -2126,7 +2173,7 @@ public: bool hasEditor() const override { return true; } //============================================================================== - const String getName() const override { return JucePlugin_Name; } + const String getName() const override { return "SamplerPlugin"; } bool acceptsMidi() const override { return true; } bool producesMidi() const override { return false; } bool isMidiEffect() const override { return false; } @@ -2144,49 +2191,14 @@ public: void setStateInformation (const void*, int) override {} //============================================================================== - void processBlock (AudioBuffer<float>& buffer, MidiBuffer& midiMessages) override + void processBlock (AudioBuffer<float>& buffer, MidiBuffer& midi) override { - // Try to acquire a lock on the command queue. - // If we were successful, we pop all pending commands off the queue and - // apply them to the processor. - // If we weren't able to acquire the lock, it's because someone called - // createEditor, which requires that the processor data model stays in - // a valid state for the duration of the call. - std::unique_lock<std::mutex> lock (commandQueueMutex, std::try_to_lock); - - if (lock.owns_lock()) - { - while (auto command = incomingCommands.pop()) - { - command->run (*this); - // We push the command onto the outgoing buffer, as long as it has - // room. If it doesn't have room for some reason, we'll delete - // the command right here on this thread, which might take a while - // and cause the audio to glitch, so I hope the buffer size is big - // enough! - outgoingCommands.push (move (command)); - } - } - - synthesiser.renderNextBlock (buffer, midiMessages, 0, buffer.getNumSamples()); - - auto loadedSamplerSound = samplerSound.load(); - - if (loadedSamplerSound->getSample() == nullptr) - return; - - auto numVoices = synthesiser.getNumVoices(); - - // Update the current playback positions - for (auto i = 0; i < maxVoices; ++i) - { - auto* voicePtr = dynamic_cast<MPESamplerVoice*> (synthesiser.getVoice (i)); + process (buffer, midi); + } - if (i < numVoices && voicePtr != nullptr) - playbackPositions[(size_t) i] = static_cast<float> (voicePtr->getCurrentSamplePosition() / loadedSamplerSound->getSample()->getSampleRate()); - else - playbackPositions[(size_t) i] = 0.0f; - } + void processBlock (AudioBuffer<double>& buffer, MidiBuffer& midi) override + { + process (buffer, midi); } // These should be called from the GUI thread, and will block until the @@ -2197,18 +2209,18 @@ public: { public: SetSampleCommand (std::unique_ptr<AudioFormatReaderFactory> r, - std::unique_ptr<Sample> sample, - std::vector<std::unique_ptr<MPESamplerVoice>> newVoices) - : readerFactory (move (r)), - sample (move (sample)), - newVoices (move (newVoices)) + std::unique_ptr<Sample> sampleIn, + std::vector<std::unique_ptr<MPESamplerVoice>> newVoicesIn) + : readerFactory (std::move (r)), + sample (std::move (sampleIn)), + newVoices (std::move (newVoicesIn)) {} void operator() (SamplerAudioProcessor& proc) { proc.readerFactory = move (readerFactory); - auto sound = proc.samplerSound.load(); - sound->setSample (move (sample)); + auto sound = proc.samplerSound; + sound->setSample (std::move (sample)); auto numberOfVoices = proc.synthesiser.getNumVoices(); proc.synthesiser.clearVoices(); @@ -2226,7 +2238,7 @@ public: // Note that all allocation happens here, on the main message thread. Then, // we transfer ownership across to the audio thread. - auto loadedSamplerSound = samplerSound.load(); + auto loadedSamplerSound = samplerSound; std::vector<std::unique_ptr<MPESamplerVoice>> newSamplerVoices; newSamplerVoices.reserve (maxVoices); @@ -2235,75 +2247,74 @@ public: if (fact == nullptr) { - pushCommand (SetSampleCommand (move (fact), - nullptr, - move (newSamplerVoices))); + commands.push (SetSampleCommand (move (fact), + nullptr, + move (newSamplerVoices))); } - else + else if (auto reader = fact->make (formatManager)) { - auto reader = fact->make (formatManager); - pushCommand (SetSampleCommand (move (fact), - std::unique_ptr<Sample> (new Sample (*reader, 10.0)), - move (newSamplerVoices))); + commands.push (SetSampleCommand (move (fact), + std::unique_ptr<Sample> (new Sample (*reader, 10.0)), + move (newSamplerVoices))); } } void setCentreFrequency (double centreFrequency) { - pushCommand ([centreFrequency] (SamplerAudioProcessor& proc) - { - auto loaded = proc.samplerSound.load(); - if (loaded != nullptr) - loaded->setCentreFrequencyInHz (centreFrequency); - }); + commands.push ([centreFrequency] (SamplerAudioProcessor& proc) + { + auto loaded = proc.samplerSound; + if (loaded != nullptr) + loaded->setCentreFrequencyInHz (centreFrequency); + }); } void setLoopMode (LoopMode loopMode) { - pushCommand ([loopMode] (SamplerAudioProcessor& proc) - { - auto loaded = proc.samplerSound.load(); - if (loaded != nullptr) - loaded->setLoopMode (loopMode); - }); + commands.push ([loopMode] (SamplerAudioProcessor& proc) + { + auto loaded = proc.samplerSound; + if (loaded != nullptr) + loaded->setLoopMode (loopMode); + }); } void setLoopPoints (Range<double> loopPoints) { - pushCommand ([loopPoints] (SamplerAudioProcessor& proc) - { - auto loaded = proc.samplerSound.load(); - if (loaded != nullptr) - loaded->setLoopPointsInSeconds (loopPoints); - }); + commands.push ([loopPoints] (SamplerAudioProcessor& proc) + { + auto loaded = proc.samplerSound; + if (loaded != nullptr) + loaded->setLoopPointsInSeconds (loopPoints); + }); } void setMPEZoneLayout (MPEZoneLayout layout) { - pushCommand ([layout] (SamplerAudioProcessor& proc) - { - // setZoneLayout will lock internally, so we don't care too much about - // ensuring that the layout doesn't get copied or destroyed on the - // audio thread. If the audio glitches while updating midi settings - // it doesn't matter too much. - proc.synthesiser.setZoneLayout (layout); - }); + commands.push ([layout] (SamplerAudioProcessor& proc) + { + // setZoneLayout will lock internally, so we don't care too much about + // ensuring that the layout doesn't get copied or destroyed on the + // audio thread. If the audio glitches while updating midi settings + // it doesn't matter too much. + proc.synthesiser.setZoneLayout (layout); + }); } void setLegacyModeEnabled (int pitchbendRange, Range<int> channelRange) { - pushCommand ([pitchbendRange, channelRange] (SamplerAudioProcessor& proc) - { - proc.synthesiser.enableLegacyMode (pitchbendRange, channelRange); - }); + commands.push ([pitchbendRange, channelRange] (SamplerAudioProcessor& proc) + { + proc.synthesiser.enableLegacyMode (pitchbendRange, channelRange); + }); } void setVoiceStealingEnabled (bool voiceStealingEnabled) { - pushCommand ([voiceStealingEnabled] (SamplerAudioProcessor& proc) - { - proc.synthesiser.setVoiceStealingEnabled (voiceStealingEnabled); - }); + commands.push ([voiceStealingEnabled] (SamplerAudioProcessor& proc) + { + proc.synthesiser.setVoiceStealingEnabled (voiceStealingEnabled); + }); } void setNumberOfVoices (int numberOfVoices) @@ -2316,13 +2327,13 @@ public: class SetNumVoicesCommand { public: - SetNumVoicesCommand (std::vector<std::unique_ptr<MPESamplerVoice>> newVoices) - : newVoices (move (newVoices)) + SetNumVoicesCommand (std::vector<std::unique_ptr<MPESamplerVoice>> newVoicesIn) + : newVoices (std::move (newVoicesIn)) {} void operator() (SamplerAudioProcessor& proc) { - if (newVoices.size() < (size_t) proc.synthesiser.getNumVoices()) + if ((int) newVoices.size() < proc.synthesiser.getNumVoices()) proc.synthesiser.reduceNumVoices (int (newVoices.size())); else for (auto it = begin (newVoices); (size_t) proc.synthesiser.getNumVoices() < newVoices.size(); ++it) @@ -2334,14 +2345,14 @@ public: }; numberOfVoices = std::min (maxVoices, numberOfVoices); - auto loadedSamplerSound = samplerSound.load(); + auto loadedSamplerSound = samplerSound; std::vector<std::unique_ptr<MPESamplerVoice>> newSamplerVoices; newSamplerVoices.reserve ((size_t) numberOfVoices); for (auto i = 0; i != numberOfVoices; ++i) newSamplerVoices.emplace_back (new MPESamplerVoice (loadedSamplerSound)); - pushCommand (SetNumVoicesCommand (move (newSamplerVoices))); + commands.push (SetNumVoicesCommand (move (newSamplerVoices))); } // These accessors are just for an 'overview' and won't give the exact @@ -2357,13 +2368,13 @@ private: //============================================================================== class SamplerAudioProcessorEditor : public AudioProcessorEditor, public FileDragAndDropTarget, - public DataModel::Listener, - public MPESettingsDataModel::Listener + private DataModel::Listener, + private MPESettingsDataModel::Listener { public: SamplerAudioProcessorEditor (SamplerAudioProcessor& p, ProcessorState state) : AudioProcessorEditor (&p), - processor (p), + samplerAudioProcessor (p), mainSamplerView (dataModel, [&p] { @@ -2453,33 +2464,33 @@ private: void sampleReaderChanged (std::shared_ptr<AudioFormatReaderFactory> value) override { - processor.setSample (value == nullptr ? nullptr : value->clone(), - dataModel.getAudioFormatManager()); + samplerAudioProcessor.setSample (value == nullptr ? nullptr : value->clone(), + dataModel.getAudioFormatManager()); } void centreFrequencyHzChanged (double value) override { - processor.setCentreFrequency (value); + samplerAudioProcessor.setCentreFrequency (value); } void loopPointsSecondsChanged (Range<double> value) override { - processor.setLoopPoints (value); + samplerAudioProcessor.setLoopPoints (value); } void loopModeChanged (LoopMode value) override { - processor.setLoopMode (value); + samplerAudioProcessor.setLoopMode (value); } void synthVoicesChanged (int value) override { - processor.setNumberOfVoices (value); + samplerAudioProcessor.setNumberOfVoices (value); } void voiceStealingEnabledChanged (bool value) override { - processor.setVoiceStealingEnabled (value); + samplerAudioProcessor.setVoiceStealingEnabled (value); } void legacyModeEnabledChanged (bool value) override @@ -2512,21 +2523,22 @@ private: void setProcessorLegacyMode() { - processor.setLegacyModeEnabled (mpeSettings.getLegacyPitchbendRange(), - Range<int> (mpeSettings.getLegacyFirstChannel(), - mpeSettings.getLegacyLastChannel())); + samplerAudioProcessor.setLegacyModeEnabled (mpeSettings.getLegacyPitchbendRange(), + Range<int> (mpeSettings.getLegacyFirstChannel(), + mpeSettings.getLegacyLastChannel())); } void setProcessorMPEMode() { - processor.setMPEZoneLayout (mpeSettings.getMPEZoneLayout()); + samplerAudioProcessor.setMPEZoneLayout (mpeSettings.getMPEZoneLayout()); } - SamplerAudioProcessor& processor; + SamplerAudioProcessor& samplerAudioProcessor; AudioFormatManager formatManager; DataModel dataModel { formatManager }; UndoManager undoManager; MPESettingsDataModel mpeSettings { dataModel.mpeSettings() }; + TabbedComponent tabbedComponent { TabbedButtonBar::Orientation::TabsAtTop }; MPESettingsComponent settingsComponent { dataModel.mpeSettings(), undoManager }; MainSamplerView mainSamplerView; @@ -2535,91 +2547,55 @@ private: }; //============================================================================== - // We want to send type-erased commands to the audio thread, but we also - // want those commands to contain move-only resources, so that we can - // construct resources on the gui thread, and then transfer ownership - // cheaply to the audio thread. We can't do this with std::function - // because it enforces that functions are copy-constructible. - // Therefore, we use a very simple templated type-eraser here. - struct Command - { - virtual ~Command() noexcept = default; - virtual void run (SamplerAudioProcessor& proc) = 0; - }; - - template <typename Func> - class TemplateCommand : public Command, - public Func + template <typename Element> + void process (AudioBuffer<Element>& buffer, MidiBuffer& midiMessages) { - public: - template <typename FuncPrime> - explicit TemplateCommand (FuncPrime&& funcPrime) - : Func (std::forward<FuncPrime> (funcPrime)) - {} + // Try to acquire a lock on the command queue. + // If we were successful, we pop all pending commands off the queue and + // apply them to the processor. + // If we weren't able to acquire the lock, it's because someone called + // createEditor, which requires that the processor data model stays in + // a valid state for the duration of the call. + const GenericScopedTryLock<SpinLock> lock (commandQueueMutex); - void run (SamplerAudioProcessor& proc) override - { - (*this) (proc); - } - }; + if (lock.isLocked()) + commands.call (*this); - template <typename Func> - static std::unique_ptr<Command> make_command (Func&& func) - { - return std::unique_ptr<TemplateCommand<Func>> (new TemplateCommand<Func> (std::forward<Func> (func))); - } + synthesiser.renderNextBlock (buffer, midiMessages, 0, buffer.getNumSamples()); - using CommandFifo = MoveOnlyFifo<std::unique_ptr<Command>>; + auto loadedSamplerSound = samplerSound; - class OutgoingBufferCleaner : public Timer - { - public: - explicit OutgoingBufferCleaner (CommandFifo& bufferToEmpty) - : buffer (bufferToEmpty) - { - startTimer (500); - } + if (loadedSamplerSound->getSample() == nullptr) + return; - private: - void timerCallback() override + auto numVoices = synthesiser.getNumVoices(); + + // Update the current playback positions + for (auto i = 0; i < maxVoices; ++i) { - while (auto command = buffer.pop()) - command = {}; - } + auto* voicePtr = dynamic_cast<MPESamplerVoice*> (synthesiser.getVoice (i)); - CommandFifo& buffer; - }; + if (i < numVoices && voicePtr != nullptr) + playbackPositions[(size_t) i] = static_cast<float> (voicePtr->getCurrentSamplePosition() / loadedSamplerSound->getSample()->getSampleRate()); + else + playbackPositions[(size_t) i] = 0.0f; + } - // Spin, trying to post a command to the sampler sound, until there's - // enough room in the command buffer to accept the new command. - template <typename Func> - void pushCommand (Func&& func) - { - auto command = make_command (std::forward<Func> (func)); - while (command) - command = incomingCommands.push (move (command)); } - // We have an incoming and an outgoing command queue. The incoming commands - // are used to update the sampler sound in a thread-safe way, without - // blocking. Once we've consumed a command, we push it back onto the - // outgoing command queue, which is cleaned up periodically by the - // outgoingBufferCleaner. - CommandFifo incomingCommands; - CommandFifo outgoingCommands; - OutgoingBufferCleaner outgoingBufferCleaner { outgoingCommands }; + CommandFifo<SamplerAudioProcessor> commands; MemoryBlock mb; std::unique_ptr<AudioFormatReaderFactory> readerFactory; - AtomicSharedPtr<MPESamplerSound> samplerSound { std::make_shared<MPESamplerSound>() }; + std::shared_ptr<MPESamplerSound> samplerSound = std::make_shared<MPESamplerSound>(); MPESynthesiser synthesiser; // This mutex is used to ensure we don't modify the processor state during // a call to createEditor, which would cause the UI to become desynched // with the real state of the processor. - std::mutex commandQueueMutex; + SpinLock commandQueueMutex; - static const int maxVoices { 20 }; + static constexpr auto maxVoices { 20 }; // This is used for visualising the current playback position of each voice. std::array<std::atomic<float>, maxVoices> playbackPositions; diff --git a/examples/Plugins/SurroundPluginDemo.h b/examples/Plugins/SurroundPluginDemo.h index e15d3cc1..0796b825 100644 --- a/examples/Plugins/SurroundPluginDemo.h +++ b/examples/Plugins/SurroundPluginDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -270,6 +270,8 @@ public: } } + using AudioProcessor::processBlock; + //============================================================================== AudioProcessorEditor* createEditor() override { return new SurroundEditor (*this); } bool hasEditor() const override { return true; } diff --git a/examples/Utilities/AnalyticsCollectionDemo.h b/examples/Utilities/AnalyticsCollectionDemo.h index 9537221f..eff858d8 100644 --- a/examples/Utilities/AnalyticsCollectionDemo.h +++ b/examples/Utilities/AnalyticsCollectionDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 diff --git a/examples/Utilities/Box2DDemo.h b/examples/Utilities/Box2DDemo.h index c5086f23..991730f4 100644 --- a/examples/Utilities/Box2DDemo.h +++ b/examples/Utilities/Box2DDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -88,11 +88,15 @@ struct Test std::unique_ptr<b2World> m_world { new b2World (b2Vec2 (0.0f, -10.0f)) }; }; +JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wimplicit-int-float-conversion") + #include "../Assets/Box2DTests/AddPair.h" #include "../Assets/Box2DTests/ApplyForce.h" #include "../Assets/Box2DTests/Dominos.h" #include "../Assets/Box2DTests/Chain.h" +JUCE_END_IGNORE_WARNINGS_GCC_LIKE + //============================================================================== /** This list box just displays a StringArray and broadcasts a change message when the selected row changes. @@ -118,7 +122,7 @@ public: lf.findColour (ListBox::backgroundColourId))); g.setColour (lf.findColour (ListBox::textColourId)); - g.setFont (h * 0.7f); + g.setFont ((float) h * 0.7f); g.drawText (tests[row], Rectangle<int> (0, 0, w, h).reduced (2), Justification::centredLeft, true); } diff --git a/examples/Utilities/CMakeLists.txt b/examples/Utilities/CMakeLists.txt new file mode 100644 index 00000000..272e8475 --- /dev/null +++ b/examples/Utilities/CMakeLists.txt @@ -0,0 +1,24 @@ +# ============================================================================== +# +# This file is part of the JUCE library. +# Copyright (c) 2020 - Raw Material Software Limited +# +# JUCE is an open source library subject to commercial or open-source +# licensing. +# +# By using JUCE, you agree to the terms of both the JUCE 6 End-User License +# Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). +# +# End User License Agreement: www.juce.com/juce-6-licence +# Privacy Policy: www.juce.com/juce-privacy-policy +# +# Or: You may also use this code under the terms of the GPL v3 (see +# www.gnu.org/licenses). +# +# JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER +# EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE +# DISCLAIMED. +# +# ============================================================================== + +_juce_add_pips() diff --git a/examples/Utilities/ChildProcessDemo.h b/examples/Utilities/ChildProcessDemo.h index d2651bcc..dc00846a 100644 --- a/examples/Utilities/ChildProcessDemo.h +++ b/examples/Utilities/ChildProcessDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 diff --git a/examples/Utilities/CryptographyDemo.h b/examples/Utilities/CryptographyDemo.h index 74727074..a8f4b826 100644 --- a/examples/Utilities/CryptographyDemo.h +++ b/examples/Utilities/CryptographyDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 diff --git a/examples/Utilities/InAppPurchasesDemo.h b/examples/Utilities/InAppPurchasesDemo.h index 7937857d..53fa863f 100644 --- a/examples/Utilities/InAppPurchasesDemo.h +++ b/examples/Utilities/InAppPurchasesDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -38,6 +38,7 @@ exporters: xcode_mac, xcode_iphone, androidstudio moduleFlags: JUCE_STRICT_REFCOUNTEDPOINTER=1 + JUCE_IN_APP_PURCHASES=1 type: Component mainClass: InAppPurchasesDemo @@ -55,7 +56,7 @@ /* To finish the setup of this demo, do the following in the Projucer project: - 1. In the project settings, set the "Bundle Identifier" to com.roli.juceInAppPurchaseSample + 1. In the project settings, set the "Bundle Identifier" to com.rmsl.juceInAppPurchaseSample 2. In the Android exporter settings, change the following settings: - "In-App Billing" - Enabled - "Key Signing: key.store" - path to InAppPurchase.keystore file in examples/Assets/Signing @@ -91,7 +92,7 @@ public: VoiceProduct {"jb", "JB", false, false, false, "Retrieving price..." } }); } - ~VoicePurchases() + ~VoicePurchases() override { InAppPurchases::getInstance()->removeListener (this); } @@ -274,7 +275,7 @@ public: Rectangle<int> r (0, 0, w, h); auto& lf = Desktop::getInstance().getDefaultLookAndFeel(); - g.setColour (lf.findColour (isSelected ? TextEditor::highlightColourId : ListBox::backgroundColourId)); + g.setColour (lf.findColour (isSelected ? (int) TextEditor::highlightColourId : (int) ListBox::backgroundColourId)); g.fillRect (r); g.setColour (lf.findColour (ListBox::textColourId)); @@ -395,11 +396,8 @@ public: setInterceptsMouseClicks (! hasBeenPurchased, ! hasBeenPurchased); - if (auto* assetStream = createAssetInputStream (String ("Purchases/" + String (imageResourceName)).toRawUTF8())) - { - std::unique_ptr<InputStream> fileStream (assetStream); + if (auto fileStream = createAssetInputStream (String ("Purchases/" + String (imageResourceName)).toRawUTF8())) avatar = PNGImageFormat().decodeImage (*fileStream); - } } } private: @@ -463,7 +461,7 @@ public: auto r = Rectangle<int> (0, 0, w, h).reduced (4); auto& lf = Desktop::getInstance().getDefaultLookAndFeel(); - g.setColour (lf.findColour (isSelected ? TextEditor::highlightColourId : ListBox::backgroundColourId)); + g.setColour (lf.findColour (isSelected ? (int) TextEditor::highlightColourId : (int) ListBox::backgroundColourId)); g.fillRect (r); } @@ -512,14 +510,14 @@ public: soundNames = purchases.getVoiceNames(); #if JUCE_ANDROID || JUCE_IOS - auto screenBounds = Desktop::getInstance().getDisplays().getMainDisplay().userArea; + auto screenBounds = Desktop::getInstance().getDisplays().getPrimaryDisplay()->userArea; setSize (screenBounds.getWidth(), screenBounds.getHeight()); #else setSize (800, 600); #endif } - ~InAppPurchasesDemo() + ~InAppPurchasesDemo() override { dm.closeAudioDevice(); dm.removeAudioCallback (&player); @@ -569,10 +567,8 @@ private: { auto assetName = "Purchases/" + soundNames[idx] + String (phraseListBox.getSelectedRow()) + ".ogg"; - if (auto* assetStream = createAssetInputStream (assetName.toRawUTF8())) + if (auto fileStream = createAssetInputStream (assetName.toRawUTF8())) { - std::unique_ptr<InputStream> fileStream (assetStream); - currentPhraseData.reset(); fileStream->readIntoMemoryBlock (currentPhraseData); diff --git a/examples/Utilities/JavaScriptDemo.h b/examples/Utilities/JavaScriptDemo.h index 5a5031f6..7655c033 100644 --- a/examples/Utilities/JavaScriptDemo.h +++ b/examples/Utilities/JavaScriptDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 diff --git a/examples/Utilities/LiveConstantDemo.h b/examples/Utilities/LiveConstantDemo.h index 8705ef4a..9ae148e9 100644 --- a/examples/Utilities/LiveConstantDemo.h +++ b/examples/Utilities/LiveConstantDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 diff --git a/examples/Utilities/MultithreadingDemo.h b/examples/Utilities/MultithreadingDemo.h index 1f69967f..e682f1f7 100644 --- a/examples/Utilities/MultithreadingDemo.h +++ b/examples/Utilities/MultithreadingDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -121,8 +121,8 @@ private: { const ScopedLock lock (drawing); - parentWidth = comp.getWidth() - size; - parentHeight = comp.getHeight() - size; + parentWidth = (float) comp.getWidth() - size; + parentHeight = (float) comp.getHeight() - size; } float x = 0.0f, y = 0.0f, diff --git a/examples/Utilities/NetworkingDemo.h b/examples/Utilities/NetworkingDemo.h index c4e11fd8..3677e461 100644 --- a/examples/Utilities/NetworkingDemo.h +++ b/examples/Utilities/NetworkingDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 diff --git a/examples/Utilities/OSCDemo.h b/examples/Utilities/OSCDemo.h index 56548a4a..1618f516 100644 --- a/examples/Utilities/OSCDemo.h +++ b/examples/Utilities/OSCDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 diff --git a/examples/Utilities/PushNotificationsDemo.h b/examples/Utilities/PushNotificationsDemo.h index 7de0da76..8d3445dc 100644 --- a/examples/Utilities/PushNotificationsDemo.h +++ b/examples/Utilities/PushNotificationsDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -34,9 +34,10 @@ juce_audio_processors, juce_audio_utils, juce_core, juce_data_structures, juce_events, juce_graphics, juce_gui_basics, juce_gui_extra - exporters: xcode_mac, vs2019, xcode_iphone, androidstudio + exporters: xcode_mac, xcode_iphone, androidstudio moduleFlags: JUCE_STRICT_REFCOUNTEDPOINTER=1 + JUCE_PUSH_NOTIFICATIONS=1 type: Component mainClass: PushNotificationsDemo @@ -96,7 +97,7 @@ The following steps are only necessary if you have a custom activity defined: 6. Ensure that you override onNewIntent() function in the same way as it is done in JuceActivity.java: -package com.roli.juce; +package com.rmsl.juce; import android.app.Activity; import android.content.Intent; @@ -161,7 +162,7 @@ public: mainTabs.addTab ("Local", colour, &localNotificationsTabs, false); mainTabs.addTab ("Remote", colour, &remoteView, false); - auto userArea = Desktop::getInstance().getDisplays().getMainDisplay().userArea; + auto userArea = Desktop::getInstance().getDisplays().getPrimaryDisplay()->userArea; #if JUCE_ANDROID || JUCE_IOS setSize (userArea.getWidth(), userArea.getHeight()); #else @@ -238,7 +239,7 @@ public: #endif } - ~PushNotificationsDemo() + ~PushNotificationsDemo() override { PushNotifications::getInstance()->removeListener (this); diff --git a/examples/Utilities/SystemInfoDemo.h b/examples/Utilities/SystemInfoDemo.h index 5e6294e4..233a0166 100644 --- a/examples/Utilities/SystemInfoDemo.h +++ b/examples/Utilities/SystemInfoDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -89,6 +89,7 @@ static const char* getDisplayOrientation() case Desktop::upsideDown: return "Upside-down"; case Desktop::rotatedClockwise: return "Rotated Clockwise"; case Desktop::rotatedAntiClockwise: return "Rotated Anti-clockwise"; + case Desktop::allOrientations: return "All"; default: jassertfalse; break; } diff --git a/examples/Utilities/TimersAndEventsDemo.h b/examples/Utilities/TimersAndEventsDemo.h index 56ca48e3..d44b59e0 100644 --- a/examples/Utilities/TimersAndEventsDemo.h +++ b/examples/Utilities/TimersAndEventsDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 diff --git a/examples/Utilities/UnitTestsDemo.h b/examples/Utilities/UnitTestsDemo.h index 783296f2..44a878af 100644 --- a/examples/Utilities/UnitTestsDemo.h +++ b/examples/Utilities/UnitTestsDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 diff --git a/examples/Utilities/ValueTreesDemo.h b/examples/Utilities/ValueTreesDemo.h index 1d42397a..00ba0209 100644 --- a/examples/Utilities/ValueTreesDemo.h +++ b/examples/Utilities/ValueTreesDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 diff --git a/examples/Utilities/XMLandJSONDemo.h b/examples/Utilities/XMLandJSONDemo.h index b780a1de..76528267 100644 --- a/examples/Utilities/XMLandJSONDemo.h +++ b/examples/Utilities/XMLandJSONDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -75,7 +75,7 @@ public: // use a "colour" attribute in the xml tag for this node to set the text colour.. g.setColour (Colour::fromString (xml.getStringAttribute ("colour", "ff000000"))); - g.setFont (height * 0.7f); + g.setFont ((float) height * 0.7f); // draw the xml element's tag name.. g.drawText (xml.getTagName(), @@ -145,7 +145,7 @@ public: g.fillAll (Colours::blue.withAlpha (0.3f)); g.setColour (Colours::black); - g.setFont (height * 0.7f); + g.setFont ((float) height * 0.7f); // draw the element's tag name.. g.drawText (getText(), diff --git a/extras/AudioPerformanceTest/AudioPerformanceTest.jucer b/extras/AudioPerformanceTest/AudioPerformanceTest.jucer index 89732ea0..36cee64b 100644 --- a/extras/AudioPerformanceTest/AudioPerformanceTest.jucer +++ b/extras/AudioPerformanceTest/AudioPerformanceTest.jucer @@ -1,9 +1,10 @@ <?xml version="1.0" encoding="UTF-8"?> <JUCERPROJECT id="AKfc5m" name="AudioPerformanceTest" projectType="guiapp" - bundleIdentifier="com.juce.AudioPerformanceTest" jucerVersion="5.4.7" - displaySplashScreen="0" reportAppUsage="0" companyName="ROLI Ltd." - companyCopyright="ROLI Ltd."> + bundleIdentifier="com.juce.AudioPerformanceTest" displaySplashScreen="0" + reportAppUsage="0" companyName="Raw Material Software Limited" + companyCopyright="Raw Material Software Limited" useAppConfig="0" + addUsingNamespaceToJuceHeader="1" jucerFormatVersion="1"> <MAINGROUP id="b1eVTe" name="AudioPerformanceTest"> <GROUP id="{AB66118C-9D88-1C3A-D95C-42892D828E4B}" name="Source"> <FILE id="SqGU9p" name="Main.cpp" compile="1" resource="0" file="Source/Main.cpp"/> @@ -70,8 +71,8 @@ </VS2019> <LINUX_MAKE targetFolder="Builds/LinuxMakefile"> <CONFIGURATIONS> - <CONFIGURATION name="Debug" libraryPath="/usr/X11R6/lib/" isDebug="1" targetName="AudioPerformanceTest"/> - <CONFIGURATION name="Release" libraryPath="/usr/X11R6/lib/" isDebug="0" targetName="AudioPerformanceTest"/> + <CONFIGURATION name="Debug" isDebug="1" targetName="AudioPerformanceTest"/> + <CONFIGURATION name="Release" isDebug="0" targetName="AudioPerformanceTest"/> </CONFIGURATIONS> <MODULEPATHS> <MODULEPATH id="juce_core" path="../../modules"/> diff --git a/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt b/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt index 762bb07f..8fe7c02d 100644 --- a/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt +++ b/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt @@ -3,12 +3,16 @@ cmake_minimum_required(VERSION 3.4.1) -SET(BINARY_NAME "juce_jni") +set(BINARY_NAME "juce_jni") + +set(OBOE_DIR "../../../../../modules/juce_audio_devices/native/oboe") + +add_subdirectory (${OBOE_DIR} ./oboe) 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" "-DJUCER_ANDROIDSTUDIO_7F0E4A25=1" "-DJUCE_APP_VERSION=1.0.0" "-DJUCE_APP_VERSION_HEX=0x10000") +add_definitions("-DJUCE_ANDROID=1" "-DJUCE_ANDROID_API_VERSION=23" "-DJUCE_PUSH_NOTIFICATIONS=1" "-DJUCE_PUSH_NOTIFICATIONS_ACTIVITY=\"com/rmsl/juce/JuceActivity\"" "-DJUCE_ANDROID_GL_ES_VERSION_3_0=1" "-DJUCER_ANDROIDSTUDIO_7F0E4A25=1" "-DJUCE_APP_VERSION=1.0.0" "-DJUCE_APP_VERSION_HEX=0x10000") include_directories( AFTER "../../../JuceLibraryCode" @@ -18,13 +22,13 @@ include_directories( AFTER enable_language(ASM) -IF(JUCE_BUILD_CONFIGURATION MATCHES "DEBUG") - add_definitions("-DDEBUG=1" "-D_DEBUG=1") -ELSEIF(JUCE_BUILD_CONFIGURATION MATCHES "RELEASE") - add_definitions("-DNDEBUG=1") -ELSE(JUCE_BUILD_CONFIGURATION MATCHES "DEBUG") - MESSAGE( FATAL_ERROR "No matching build-configuration found." ) -ENDIF(JUCE_BUILD_CONFIGURATION MATCHES "DEBUG") +if(JUCE_BUILD_CONFIGURATION MATCHES "DEBUG") + add_definitions("-DJUCE_DISPLAY_SPLASH_SCREEN=0" "-DJUCE_USE_DARK_SPLASH_SCREEN=1" "-DJUCE_PROJUCER_VERSION=0x60005" "-DJUCE_MODULE_AVAILABLE_juce_audio_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_devices=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_formats=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_processors=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_utils=1" "-DJUCE_MODULE_AVAILABLE_juce_core=1" "-DJUCE_MODULE_AVAILABLE_juce_data_structures=1" "-DJUCE_MODULE_AVAILABLE_juce_events=1" "-DJUCE_MODULE_AVAILABLE_juce_graphics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_extra=1" "-DJUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1" "-DJUCE_STANDALONE_APPLICATION=1" "-DJUCER_ANDROIDSTUDIO_7F0E4A25=1" "-DJUCE_APP_VERSION=1.0.0" "-DJUCE_APP_VERSION_HEX=0x10000" "-DDEBUG=1" "-D_DEBUG=1") +elseif(JUCE_BUILD_CONFIGURATION MATCHES "RELEASE") + add_definitions("-DJUCE_DISPLAY_SPLASH_SCREEN=0" "-DJUCE_USE_DARK_SPLASH_SCREEN=1" "-DJUCE_PROJUCER_VERSION=0x60005" "-DJUCE_MODULE_AVAILABLE_juce_audio_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_devices=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_formats=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_processors=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_utils=1" "-DJUCE_MODULE_AVAILABLE_juce_core=1" "-DJUCE_MODULE_AVAILABLE_juce_data_structures=1" "-DJUCE_MODULE_AVAILABLE_juce_events=1" "-DJUCE_MODULE_AVAILABLE_juce_graphics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_extra=1" "-DJUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1" "-DJUCE_STANDALONE_APPLICATION=1" "-DJUCER_ANDROIDSTUDIO_7F0E4A25=1" "-DJUCE_APP_VERSION=1.0.0" "-DJUCE_APP_VERSION_HEX=0x10000" "-DNDEBUG=1") +else() + message( FATAL_ERROR "No matching build-configuration found." ) +endif() add_library( ${BINARY_NAME} @@ -94,16 +98,17 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp" "../../../../../modules/juce_audio_basics/synthesisers/juce_Synthesiser.h" "../../../../../modules/juce_audio_basics/utilities/juce_ADSR.h" - "../../../../../modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.cpp" - "../../../../../modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.h" "../../../../../modules/juce_audio_basics/utilities/juce_Decibels.h" + "../../../../../modules/juce_audio_basics/utilities/juce_GenericInterpolator.h" "../../../../../modules/juce_audio_basics/utilities/juce_IIRFilter.cpp" "../../../../../modules/juce_audio_basics/utilities/juce_IIRFilter.h" + "../../../../../modules/juce_audio_basics/utilities/juce_Interpolators.cpp" + "../../../../../modules/juce_audio_basics/utilities/juce_Interpolators.h" "../../../../../modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.cpp" - "../../../../../modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.h" "../../../../../modules/juce_audio_basics/utilities/juce_Reverb.h" "../../../../../modules/juce_audio_basics/utilities/juce_SmoothedValue.cpp" "../../../../../modules/juce_audio_basics/utilities/juce_SmoothedValue.h" + "../../../../../modules/juce_audio_basics/utilities/juce_WindowedSincInterpolator.cpp" "../../../../../modules/juce_audio_basics/juce_audio_basics.cpp" "../../../../../modules/juce_audio_basics/juce_audio_basics.mm" "../../../../../modules/juce_audio_basics/juce_audio_basics.h" @@ -118,7 +123,118 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_devices/midi_io/juce_MidiDevices.h" "../../../../../modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.cpp" "../../../../../modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStream.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamBase.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamBuilder.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamCallback.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Definitions.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/LatencyTuner.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Oboe.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/ResultWithValue.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/StabilizedCallback.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Utilities.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Version.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AAudioLoader.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AAudioLoader.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioClock.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioSourceCaller.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioSourceCaller.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioStream.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioStreamBuilder.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/DataConversionFlowGraph.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/DataConversionFlowGraph.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/FilterAudioStream.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/FilterAudioStream.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockAdapter.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockAdapter.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockReader.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockReader.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockWriter.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockWriter.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/LatencyTuner.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/MonotonicCounter.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/OboeDebug.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/QuirksManager.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/QuirksManager.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceFloatCaller.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceFloatCaller.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceI16Caller.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceI16Caller.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/StabilizedCallback.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/Trace.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/Trace.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/Utilities.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/Version.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoController.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoController.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/HyperbolicCosineWindow.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/IntegerRatio.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/IntegerRatio.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/KaiserWindow.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/LinearResampler.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/LinearResampler.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/MultiChannelResampler.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/MultiChannelResampler.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResampler.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResampler.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResamplerStereo.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResamplerStereo.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ClipToRange.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ClipToRange.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/RampLinear.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/RampLinear.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SampleRateConverter.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SampleRateConverter.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkFloat.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkFloat.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI16.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI16.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI24.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI24.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceFloat.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceFloat.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI16.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI16.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI24.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI24.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioInputStreamOpenSLES.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioInputStreamOpenSLES.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioOutputStreamOpenSLES.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioOutputStreamOpenSLES.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamBuffered.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamBuffered.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamOpenSLES.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamOpenSLES.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/EngineOpenSLES.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/EngineOpenSLES.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/OpenSLESUtilities.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/OpenSLESUtilities.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/OutputMixerOpenSLES.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/OutputMixerOpenSLES.h" + "../../../../../modules/juce_audio_devices/native/oboe/CMakeLists.txt" + "../../../../../modules/juce_audio_devices/native/oboe/readme.md" "../../../../../modules/juce_audio_devices/native/juce_android_Audio.cpp" + "../../../../../modules/juce_audio_devices/native/juce_android_HighPerformanceAudioHelpers.h" "../../../../../modules/juce_audio_devices/native/juce_android_Midi.cpp" "../../../../../modules/juce_audio_devices/native/juce_android_Oboe.cpp" "../../../../../modules/juce_audio_devices/native/juce_android_OpenSL.cpp" @@ -190,73 +306,76 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_formats/codecs/flac/stream_decoder.h" "../../../../../modules/juce_audio_formats/codecs/flac/stream_encoder.h" "../../../../../modules/juce_audio_formats/codecs/flac/win_utf8_io.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/books/coupled/res_books_51.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/books/coupled/res_books_stereo.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/books/floor/floor_books.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/books/uncoupled/res_books_uncoupled.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/floor_all.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/psych_8.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/psych_11.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/psych_16.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/psych_44.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_8.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_16.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_44.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_44p51.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_44u.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_8.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_11.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_16.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_22.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_32.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_44.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_44p51.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_44u.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_X.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/analysis.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/backends.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/bitrate.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/bitrate.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/block.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/codebook.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/codebook.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/codec_internal.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/envelope.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/envelope.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/floor0.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/floor1.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/highlevel.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/info.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lookup.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lookup.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lookup_data.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lpc.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lpc.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lsp.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lsp.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/mapping0.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/masking.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/mdct.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/mdct.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/misc.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/os.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/psy.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/psy.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/registry.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/registry.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/res0.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/scales.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/sharedbook.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/smallft.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/smallft.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/synthesis.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/vorbisenc.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/vorbisfile.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/window.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/window.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/books/coupled/res_books_51.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/books/coupled/res_books_stereo.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/books/floor/floor_books.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/books/uncoupled/res_books_uncoupled.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/floor_all.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/psych_8.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/psych_11.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/psych_16.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/psych_44.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/residue_8.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/residue_16.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/residue_44.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/residue_44p51.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/residue_44u.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_8.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_11.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_16.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_22.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_32.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_44.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_44p51.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_44u.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_X.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/analysis.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/backends.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/bitrate.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/bitrate.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/block.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/codebook.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/codebook.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/codec_internal.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/envelope.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/envelope.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/floor0.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/floor1.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/highlevel.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/info.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lookup.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lookup.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lookup_data.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lpc.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lpc.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lsp.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lsp.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/mapping0.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/masking.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/mdct.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/mdct.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/misc.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/misc.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/os.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/psy.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/psy.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/registry.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/registry.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/res0.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/scales.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/sharedbook.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/smallft.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/smallft.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/synthesis.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/vorbisenc.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/vorbisfile.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/window.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/window.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/README.md" "../../../../../modules/juce_audio_formats/codecs/oggvorbis/bitwise.c" "../../../../../modules/juce_audio_formats/codecs/oggvorbis/codec.h" "../../../../../modules/juce_audio_formats/codecs/oggvorbis/config_types.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/crctable.h" "../../../../../modules/juce_audio_formats/codecs/oggvorbis/framing.c" "../../../../../modules/juce_audio_formats/codecs/oggvorbis/Ogg Vorbis Licence.txt" "../../../../../modules/juce_audio_formats/codecs/oggvorbis/ogg.h" @@ -446,6 +565,8 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.h" "../../../../../modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp" "../../../../../modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h" + "../../../../../modules/juce_audio_processors/utilities/juce_ParameterAttachments.cpp" + "../../../../../modules/juce_audio_processors/utilities/juce_ParameterAttachments.h" "../../../../../modules/juce_audio_processors/utilities/juce_RangedAudioParameter.cpp" "../../../../../modules/juce_audio_processors/utilities/juce_RangedAudioParameter.h" "../../../../../modules/juce_audio_processors/juce_audio_processors.cpp" @@ -525,6 +646,8 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_core/files/juce_FileSearchPath.cpp" "../../../../../modules/juce_core/files/juce_FileSearchPath.h" "../../../../../modules/juce_core/files/juce_MemoryMappedFile.h" + "../../../../../modules/juce_core/files/juce_RangedDirectoryIterator.cpp" + "../../../../../modules/juce_core/files/juce_RangedDirectoryIterator.h" "../../../../../modules/juce_core/files/juce_TemporaryFile.cpp" "../../../../../modules/juce_core/files/juce_TemporaryFile.h" "../../../../../modules/juce_core/files/juce_WildcardFileFilter.cpp" @@ -547,6 +670,8 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_core/maths/juce_Random.h" "../../../../../modules/juce_core/maths/juce_Range.h" "../../../../../modules/juce_core/maths/juce_StatisticsAccumulator.h" + "../../../../../modules/juce_core/memory/juce_AllocationHooks.cpp" + "../../../../../modules/juce_core/memory/juce_AllocationHooks.h" "../../../../../modules/juce_core/memory/juce_Atomic.h" "../../../../../modules/juce_core/memory/juce_ByteOrder.h" "../../../../../modules/juce_core/memory/juce_ContainerDeletePolicy.h" @@ -633,6 +758,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_core/streams/juce_URLInputSource.cpp" "../../../../../modules/juce_core/streams/juce_URLInputSource.h" "../../../../../modules/juce_core/system/juce_CompilerSupport.h" + "../../../../../modules/juce_core/system/juce_CompilerWarnings.h" "../../../../../modules/juce_core/system/juce_PlatformDefs.h" "../../../../../modules/juce_core/system/juce_StandardHeader.h" "../../../../../modules/juce_core/system/juce_SystemStats.cpp" @@ -1142,6 +1268,11 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_gui_basics/mouse/juce_SelectedItemSet.h" "../../../../../modules/juce_gui_basics/mouse/juce_TextDragAndDropTarget.h" "../../../../../modules/juce_gui_basics/mouse/juce_TooltipClient.h" + "../../../../../modules/juce_gui_basics/native/x11/juce_linux_X11_DragAndDrop.cpp" + "../../../../../modules/juce_gui_basics/native/x11/juce_linux_X11_Symbols.cpp" + "../../../../../modules/juce_gui_basics/native/x11/juce_linux_X11_Symbols.h" + "../../../../../modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.cpp" + "../../../../../modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.h" "../../../../../modules/juce_gui_basics/native/juce_android_ContentSharer.cpp" "../../../../../modules/juce_gui_basics/native/juce_android_FileChooser.cpp" "../../../../../modules/juce_gui_basics/native/juce_android_Windowing.cpp" @@ -1151,10 +1282,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm" "../../../../../modules/juce_gui_basics/native/juce_ios_Windowing.mm" "../../../../../modules/juce_gui_basics/native/juce_linux_FileChooser.cpp" - "../../../../../modules/juce_gui_basics/native/juce_linux_X11.cpp" - "../../../../../modules/juce_gui_basics/native/juce_linux_X11.h" - "../../../../../modules/juce_gui_basics/native/juce_linux_X11_Clipboard.cpp" - "../../../../../modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp" + "../../../../../modules/juce_gui_basics/native/juce_linux_Windowing.cpp" "../../../../../modules/juce_gui_basics/native/juce_mac_FileChooser.mm" "../../../../../modules/juce_gui_basics/native/juce_mac_MainMenu.mm" "../../../../../modules/juce_gui_basics/native/juce_mac_MouseCursor.mm" @@ -1259,6 +1387,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.h" "../../../../../modules/juce_gui_extra/embedding/juce_ActiveXControlComponent.h" "../../../../../modules/juce_gui_extra/embedding/juce_AndroidViewComponent.h" + "../../../../../modules/juce_gui_extra/embedding/juce_HWNDComponent.h" "../../../../../modules/juce_gui_extra/embedding/juce_NSViewComponent.h" "../../../../../modules/juce_gui_extra/embedding/juce_ScopedDPIAwarenessDisabler.h" "../../../../../modules/juce_gui_extra/embedding/juce_UIViewComponent.h" @@ -1300,12 +1429,12 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_gui_extra/native/juce_mac_SystemTrayIcon.cpp" "../../../../../modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm" "../../../../../modules/juce_gui_extra/native/juce_win32_ActiveXComponent.cpp" + "../../../../../modules/juce_gui_extra/native/juce_win32_HWNDComponent.cpp" "../../../../../modules/juce_gui_extra/native/juce_win32_SystemTrayIcon.cpp" "../../../../../modules/juce_gui_extra/native/juce_win32_WebBrowserComponent.cpp" "../../../../../modules/juce_gui_extra/juce_gui_extra.cpp" "../../../../../modules/juce_gui_extra/juce_gui_extra.mm" "../../../../../modules/juce_gui_extra/juce_gui_extra.h" - "../../../JuceLibraryCode/AppConfig.h" "../../../JuceLibraryCode/include_juce_audio_basics.cpp" "../../../JuceLibraryCode/include_juce_audio_devices.cpp" "../../../JuceLibraryCode/include_juce_audio_formats.cpp" @@ -1383,16 +1512,17 @@ set_source_files_properties("../../../../../modules/juce_audio_basics/sources/ju set_source_files_properties("../../../../../modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/synthesisers/juce_Synthesiser.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_ADSR.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_Decibels.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_GenericInterpolator.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_IIRFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_IIRFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_Interpolators.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_Interpolators.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_Reverb.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_SmoothedValue.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_SmoothedValue.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_WindowedSincInterpolator.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/juce_audio_basics.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/juce_audio_basics.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/juce_audio_basics.h" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -1407,7 +1537,118 @@ set_source_files_properties("../../../../../modules/juce_audio_devices/midi_io/j set_source_files_properties("../../../../../modules/juce_audio_devices/midi_io/juce_MidiDevices.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStream.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamBase.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamBuilder.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamCallback.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Definitions.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/LatencyTuner.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Oboe.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/ResultWithValue.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/StabilizedCallback.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Utilities.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Version.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AAudioLoader.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AAudioLoader.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioClock.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioSourceCaller.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioSourceCaller.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioStream.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioStreamBuilder.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/DataConversionFlowGraph.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/DataConversionFlowGraph.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/FilterAudioStream.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/FilterAudioStream.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockAdapter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockAdapter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockReader.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockReader.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockWriter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockWriter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/LatencyTuner.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/MonotonicCounter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/OboeDebug.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/QuirksManager.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/QuirksManager.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceFloatCaller.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceFloatCaller.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceI16Caller.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceI16Caller.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/StabilizedCallback.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/Trace.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/Trace.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/Utilities.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/Version.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoController.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoController.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/HyperbolicCosineWindow.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/IntegerRatio.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/IntegerRatio.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/KaiserWindow.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/LinearResampler.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/LinearResampler.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/MultiChannelResampler.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/MultiChannelResampler.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResampler.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResampler.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResamplerStereo.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResamplerStereo.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ClipToRange.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ClipToRange.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/RampLinear.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/RampLinear.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SampleRateConverter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SampleRateConverter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkFloat.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkFloat.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI16.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI16.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI24.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI24.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceFloat.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceFloat.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI16.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI16.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI24.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI24.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioInputStreamOpenSLES.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioInputStreamOpenSLES.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioOutputStreamOpenSLES.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioOutputStreamOpenSLES.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamBuffered.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamBuffered.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamOpenSLES.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamOpenSLES.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/EngineOpenSLES.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/EngineOpenSLES.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/OpenSLESUtilities.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/OpenSLESUtilities.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/OutputMixerOpenSLES.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/OutputMixerOpenSLES.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/CMakeLists.txt" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/readme.md" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_android_Audio.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_android_HighPerformanceAudioHelpers.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_android_Midi.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_android_Oboe.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_android_OpenSL.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -1479,73 +1720,76 @@ set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/fl set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/stream_decoder.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/stream_encoder.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/win_utf8_io.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/books/coupled/res_books_51.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/books/coupled/res_books_stereo.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/books/floor/floor_books.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/books/uncoupled/res_books_uncoupled.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/floor_all.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/psych_8.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/psych_11.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/psych_16.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/psych_44.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_8.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_16.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_44.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_44p51.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_44u.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_8.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_11.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_16.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_22.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_32.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_44.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_44p51.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_44u.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_X.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/analysis.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/backends.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/bitrate.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/bitrate.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/block.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/codebook.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/codebook.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/codec_internal.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/envelope.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/envelope.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/floor0.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/floor1.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/highlevel.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/info.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lookup.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lookup.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lookup_data.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lpc.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lpc.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lsp.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lsp.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/mapping0.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/masking.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/mdct.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/mdct.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/misc.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/os.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/psy.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/psy.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/registry.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/registry.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/res0.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/scales.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/sharedbook.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/smallft.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/smallft.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/synthesis.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/vorbisenc.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/vorbisfile.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/window.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/window.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/books/coupled/res_books_51.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/books/coupled/res_books_stereo.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/books/floor/floor_books.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/books/uncoupled/res_books_uncoupled.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/floor_all.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/psych_8.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/psych_11.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/psych_16.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/psych_44.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/residue_8.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/residue_16.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/residue_44.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/residue_44p51.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/residue_44u.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_8.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_11.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_16.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_22.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_32.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_44.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_44p51.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_44u.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_X.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/analysis.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/backends.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/bitrate.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/bitrate.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/block.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/codebook.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/codebook.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/codec_internal.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/envelope.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/envelope.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/floor0.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/floor1.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/highlevel.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/info.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lookup.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lookup.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lookup_data.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lpc.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lpc.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lsp.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lsp.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/mapping0.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/masking.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/mdct.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/mdct.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/misc.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/misc.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/os.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/psy.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/psy.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/registry.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/registry.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/res0.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/scales.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/sharedbook.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/smallft.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/smallft.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/synthesis.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/vorbisenc.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/vorbisfile.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/window.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/window.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/README.md" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/bitwise.c" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/codec.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/config_types.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/crctable.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/framing.c" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/Ogg Vorbis Licence.txt" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/ogg.h" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -1735,6 +1979,8 @@ set_source_files_properties("../../../../../modules/juce_audio_processors/utilit set_source_files_properties("../../../../../modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_processors/utilities/juce_ParameterAttachments.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_processors/utilities/juce_ParameterAttachments.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_processors/utilities/juce_RangedAudioParameter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_processors/utilities/juce_RangedAudioParameter.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_processors/juce_audio_processors.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -1814,6 +2060,8 @@ set_source_files_properties("../../../../../modules/juce_core/files/juce_FileOut set_source_files_properties("../../../../../modules/juce_core/files/juce_FileSearchPath.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/files/juce_FileSearchPath.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/files/juce_MemoryMappedFile.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_core/files/juce_RangedDirectoryIterator.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_core/files/juce_RangedDirectoryIterator.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/files/juce_TemporaryFile.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/files/juce_TemporaryFile.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/files/juce_WildcardFileFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -1836,6 +2084,8 @@ set_source_files_properties("../../../../../modules/juce_core/maths/juce_Random. set_source_files_properties("../../../../../modules/juce_core/maths/juce_Random.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/maths/juce_Range.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/maths/juce_StatisticsAccumulator.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_core/memory/juce_AllocationHooks.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_core/memory/juce_AllocationHooks.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/memory/juce_Atomic.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/memory/juce_ByteOrder.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/memory/juce_ContainerDeletePolicy.h" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -1922,6 +2172,7 @@ set_source_files_properties("../../../../../modules/juce_core/streams/juce_Subre set_source_files_properties("../../../../../modules/juce_core/streams/juce_URLInputSource.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/streams/juce_URLInputSource.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/system/juce_CompilerSupport.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_core/system/juce_CompilerWarnings.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/system/juce_PlatformDefs.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/system/juce_StandardHeader.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/system/juce_SystemStats.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -2431,6 +2682,11 @@ set_source_files_properties("../../../../../modules/juce_gui_basics/mouse/juce_M set_source_files_properties("../../../../../modules/juce_gui_basics/mouse/juce_SelectedItemSet.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/mouse/juce_TextDragAndDropTarget.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/mouse/juce_TooltipClient.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_gui_basics/native/x11/juce_linux_X11_DragAndDrop.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_gui_basics/native/x11/juce_linux_X11_Symbols.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_gui_basics/native/x11/juce_linux_X11_Symbols.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_android_ContentSharer.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_android_FileChooser.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_android_Windowing.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -2440,10 +2696,7 @@ set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_ set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_ios_Windowing.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_linux_FileChooser.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_linux_X11.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_linux_X11.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_linux_X11_Clipboard.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_linux_Windowing.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_mac_FileChooser.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_mac_MainMenu.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_mac_MouseCursor.mm" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -2548,6 +2801,7 @@ set_source_files_properties("../../../../../modules/juce_gui_extra/documents/juc set_source_files_properties("../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/embedding/juce_ActiveXControlComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/embedding/juce_AndroidViewComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_gui_extra/embedding/juce_HWNDComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/embedding/juce_NSViewComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/embedding/juce_ScopedDPIAwarenessDisabler.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/embedding/juce_UIViewComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -2589,14 +2843,24 @@ set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_m set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_mac_SystemTrayIcon.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_win32_ActiveXComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_win32_HWNDComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_win32_SystemTrayIcon.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_win32_WebBrowserComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/juce_gui_extra.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/juce_gui_extra.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/juce_gui_extra.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../JuceLibraryCode/AppConfig.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../JuceLibraryCode/JuceHeader.h" PROPERTIES HEADER_FILE_ONLY TRUE) +target_compile_options( ${BINARY_NAME} PRIVATE "-fsigned-char" "-mfpu=neon" "-mfloat-abi=hard" "-ffast-math" "-funroll-loops" "--param" "max-unroll-times=8" "-mhard-float" "-D_NDK_MATH_NO_SOFTFP=1" "-DJUCE_DISABLE_ASSERTIONS=1" ) + +if( JUCE_BUILD_CONFIGURATION MATCHES "DEBUG" ) + target_compile_options( ${BINARY_NAME} PRIVATE) +endif() + +if( JUCE_BUILD_CONFIGURATION MATCHES "RELEASE" ) + target_compile_options( ${BINARY_NAME} PRIVATE) +endif() + find_library(log "log") find_library(android "android") find_library(glesv3 "GLESv3") @@ -2609,4 +2873,5 @@ target_link_libraries( ${BINARY_NAME} ${glesv3} ${egl} "cpufeatures" + "oboe" ) diff --git a/extras/AudioPerformanceTest/Builds/Android/app/build.gradle b/extras/AudioPerformanceTest/Builds/Android/app/build.gradle index d89fa680..4cfe43f0 100644 --- a/extras/AudioPerformanceTest/Builds/Android/app/build.gradle +++ b/extras/AudioPerformanceTest/Builds/Android/app/build.gradle @@ -1,7 +1,7 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 28 + compileSdkVersion 29 externalNativeBuild { cmake { path "CMakeLists.txt" @@ -20,12 +20,10 @@ android { defaultConfig { applicationId "com.juce.audioperformancetest" minSdkVersion 23 - targetSdkVersion 28 + targetSdkVersion 29 externalNativeBuild { cmake { - arguments "-DANDROID_TOOLCHAIN=clang", "-DANDROID_PLATFORM=android-23", "-DANDROID_STL=c++_static", "-DANDROID_CPP_FEATURES=exceptions rtti", "-DANDROID_ARM_MODE=arm", "-DANDROID_ARM_NEON=TRUE" - cFlags "-fsigned-char", "-mfpu=neon", "-mfloat-abi=hard", "-ffast-math", "-funroll-loops", "--param", "max-unroll-times=8", "-mhard-float", "-D_NDK_MATH_NO_SOFTFP=1", "-DJUCE_DISABLE_ASSERTIONS=1" - cppFlags "-fsigned-char", "-std=c++14", "-mfpu=neon", "-mfloat-abi=hard", "-ffast-math", "-funroll-loops", "--param", "max-unroll-times=8", "-mhard-float", "-D_NDK_MATH_NO_SOFTFP=1", "-DJUCE_DISABLE_ASSERTIONS=1" + arguments "-DANDROID_TOOLCHAIN=clang", "-DANDROID_PLATFORM=android-23", "-DANDROID_STL=c++_static", "-DANDROID_CPP_FEATURES=exceptions rtti", "-DANDROID_ARM_MODE=arm", "-DANDROID_ARM_NEON=TRUE", "-DCMAKE_CXX_STANDARD=14", "-DCMAKE_CXX_EXTENSIONS=OFF" } } } @@ -89,7 +87,6 @@ android { main.java.srcDirs += ["../../../../../modules/juce_core/native/javacore/init", "../../../../../modules/juce_core/native/javacore/app", - "../../../../../modules/juce_gui_basics/native/javacore/app", "../../../../../modules/juce_gui_basics/native/javaopt/app"] main.res.srcDirs += diff --git a/extras/AudioPerformanceTest/Builds/Android/app/src/main/AndroidManifest.xml b/extras/AudioPerformanceTest/Builds/Android/app/src/main/AndroidManifest.xml index 6a6b1118..ef742b75 100644 --- a/extras/AudioPerformanceTest/Builds/Android/app/src/main/AndroidManifest.xml +++ b/extras/AudioPerformanceTest/Builds/Android/app/src/main/AndroidManifest.xml @@ -2,16 +2,17 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0.0" package="com.juce.AudioPerformanceTest"> - <supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:anyDensity="true"/> + <supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:anyDensity="true" + android:xlargeScreens="true"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> - <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> + <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/> <uses-permission android:name="android.permission.BLUETOOTH"/> <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/> <uses-permission android:name="android.permission.INTERNET"/> - <application android:label="@string/app_name" android:name="com.roli.juce.JuceApp" android:hardwareAccelerated="false"> - <activity android:name="com.roli.juce.JuceActivity" android:label="@string/app_name" android:configChanges="keyboardHidden|orientation|screenSize" + <application android:label="@string/app_name" android:name="com.rmsl.juce.JuceApp" android:hardwareAccelerated="false"> + <activity android:name="com.rmsl.juce.JuceActivity" android:label="@string/app_name" android:configChanges="keyboardHidden|orientation|screenSize" android:screenOrientation="unspecified" android:launchMode="singleTask" android:hardwareAccelerated="true"> <intent-filter> <action android:name="android.intent.action.MAIN"/> diff --git a/extras/AudioPerformanceTest/Builds/Android/app/src/main/java/com/android/vending/billing/IInAppBillingService.java b/extras/AudioPerformanceTest/Builds/Android/app/src/main/java/com/android/vending/billing/IInAppBillingService.java deleted file mode 100644 index 0bb31cb5..00000000 --- a/extras/AudioPerformanceTest/Builds/Android/app/src/main/java/com/android/vending/billing/IInAppBillingService.java +++ /dev/null @@ -1,971 +0,0 @@ -/* - ============================================================================== - - 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. - - 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. - - ============================================================================== -*/ - -package com.android.vending.billing; -/** - * InAppBillingService is the service that provides in-app billing version 3 and beyond. - * This service provides the following features: - * 1. Provides a new API to get details of in-app items published for the app including - * price, type, title and description. - * 2. The purchase flow is synchronous and purchase information is available immediately - * after it completes. - * 3. Purchase information of in-app purchases is maintained within the Google Play system - * till the purchase is consumed. - * 4. An API to consume a purchase of an inapp item. All purchases of one-time - * in-app items are consumable and thereafter can be purchased again. - * 5. An API to get current purchases of the user immediately. This will not contain any - * consumed purchases. - * - * All calls will give a response code with the following possible values - * RESULT_OK = 0 - success - * RESULT_USER_CANCELED = 1 - User pressed back or canceled a dialog - * RESULT_SERVICE_UNAVAILABLE = 2 - The network connection is down - * RESULT_BILLING_UNAVAILABLE = 3 - This billing API version is not supported for the type requested - * RESULT_ITEM_UNAVAILABLE = 4 - Requested SKU is not available for purchase - * RESULT_DEVELOPER_ERROR = 5 - Invalid arguments provided to the API - * RESULT_ERROR = 6 - Fatal error during the API action - * RESULT_ITEM_ALREADY_OWNED = 7 - Failure to purchase since item is already owned - * RESULT_ITEM_NOT_OWNED = 8 - Failure to consume since item is not owned - */ -public interface IInAppBillingService extends android.os.IInterface - { - /** Local-side IPC implementation stub class. */ - public static abstract class Stub extends android.os.Binder implements com.android.vending.billing.IInAppBillingService - { - private static final java.lang.String DESCRIPTOR = "com.android.vending.billing.IInAppBillingService"; - /** Construct the stub at attach it to the interface. */ - public Stub() - { - this.attachInterface(this, DESCRIPTOR); - } - /** - * Cast an IBinder object into an com.android.vending.billing.IInAppBillingService interface, - * generating a proxy if needed. - */ - public static com.android.vending.billing.IInAppBillingService asInterface(android.os.IBinder obj) - { - if ((obj==null)) { - return null; - } - android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); - if (((iin!=null)&&(iin instanceof com.android.vending.billing.IInAppBillingService))) { - return ((com.android.vending.billing.IInAppBillingService)iin); - } - return new com.android.vending.billing.IInAppBillingService.Stub.Proxy(obj); - } - @Override public android.os.IBinder asBinder() - { - return this; - } - @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException - { - switch (code) - { - case INTERFACE_TRANSACTION: - { - reply.writeString(DESCRIPTOR); - return true; - } - case TRANSACTION_isBillingSupported: - { - data.enforceInterface(DESCRIPTOR); - int _arg0; - _arg0 = data.readInt(); - java.lang.String _arg1; - _arg1 = data.readString(); - java.lang.String _arg2; - _arg2 = data.readString(); - int _result = this.isBillingSupported(_arg0, _arg1, _arg2); - reply.writeNoException(); - reply.writeInt(_result); - return true; - } - case TRANSACTION_getSkuDetails: - { - data.enforceInterface(DESCRIPTOR); - int _arg0; - _arg0 = data.readInt(); - java.lang.String _arg1; - _arg1 = data.readString(); - java.lang.String _arg2; - _arg2 = data.readString(); - android.os.Bundle _arg3; - if ((0!=data.readInt())) { - _arg3 = android.os.Bundle.CREATOR.createFromParcel(data); - } - else { - _arg3 = null; - } - android.os.Bundle _result = this.getSkuDetails(_arg0, _arg1, _arg2, _arg3); - reply.writeNoException(); - if ((_result!=null)) { - reply.writeInt(1); - _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE); - } - else { - reply.writeInt(0); - } - return true; - } - case TRANSACTION_getBuyIntent: - { - data.enforceInterface(DESCRIPTOR); - int _arg0; - _arg0 = data.readInt(); - java.lang.String _arg1; - _arg1 = data.readString(); - java.lang.String _arg2; - _arg2 = data.readString(); - java.lang.String _arg3; - _arg3 = data.readString(); - java.lang.String _arg4; - _arg4 = data.readString(); - android.os.Bundle _result = this.getBuyIntent(_arg0, _arg1, _arg2, _arg3, _arg4); - reply.writeNoException(); - if ((_result!=null)) { - reply.writeInt(1); - _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE); - } - else { - reply.writeInt(0); - } - return true; - } - case TRANSACTION_getPurchases: - { - data.enforceInterface(DESCRIPTOR); - int _arg0; - _arg0 = data.readInt(); - java.lang.String _arg1; - _arg1 = data.readString(); - java.lang.String _arg2; - _arg2 = data.readString(); - java.lang.String _arg3; - _arg3 = data.readString(); - android.os.Bundle _result = this.getPurchases(_arg0, _arg1, _arg2, _arg3); - reply.writeNoException(); - if ((_result!=null)) { - reply.writeInt(1); - _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE); - } - else { - reply.writeInt(0); - } - return true; - } - case TRANSACTION_consumePurchase: - { - data.enforceInterface(DESCRIPTOR); - int _arg0; - _arg0 = data.readInt(); - java.lang.String _arg1; - _arg1 = data.readString(); - java.lang.String _arg2; - _arg2 = data.readString(); - int _result = this.consumePurchase(_arg0, _arg1, _arg2); - reply.writeNoException(); - reply.writeInt(_result); - return true; - } - case TRANSACTION_stub: - { - data.enforceInterface(DESCRIPTOR); - int _arg0; - _arg0 = data.readInt(); - java.lang.String _arg1; - _arg1 = data.readString(); - java.lang.String _arg2; - _arg2 = data.readString(); - int _result = this.stub(_arg0, _arg1, _arg2); - reply.writeNoException(); - reply.writeInt(_result); - return true; - } - case TRANSACTION_getBuyIntentToReplaceSkus: - { - data.enforceInterface(DESCRIPTOR); - int _arg0; - _arg0 = data.readInt(); - java.lang.String _arg1; - _arg1 = data.readString(); - java.util.List<java.lang.String> _arg2; - _arg2 = data.createStringArrayList(); - java.lang.String _arg3; - _arg3 = data.readString(); - java.lang.String _arg4; - _arg4 = data.readString(); - java.lang.String _arg5; - _arg5 = data.readString(); - android.os.Bundle _result = this.getBuyIntentToReplaceSkus(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5); - reply.writeNoException(); - if ((_result!=null)) { - reply.writeInt(1); - _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE); - } - else { - reply.writeInt(0); - } - return true; - } - case TRANSACTION_getBuyIntentExtraParams: - { - data.enforceInterface(DESCRIPTOR); - int _arg0; - _arg0 = data.readInt(); - java.lang.String _arg1; - _arg1 = data.readString(); - java.lang.String _arg2; - _arg2 = data.readString(); - java.lang.String _arg3; - _arg3 = data.readString(); - java.lang.String _arg4; - _arg4 = data.readString(); - android.os.Bundle _arg5; - if ((0!=data.readInt())) { - _arg5 = android.os.Bundle.CREATOR.createFromParcel(data); - } - else { - _arg5 = null; - } - android.os.Bundle _result = this.getBuyIntentExtraParams(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5); - reply.writeNoException(); - if ((_result!=null)) { - reply.writeInt(1); - _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE); - } - else { - reply.writeInt(0); - } - return true; - } - case TRANSACTION_getPurchaseHistory: - { - data.enforceInterface(DESCRIPTOR); - int _arg0; - _arg0 = data.readInt(); - java.lang.String _arg1; - _arg1 = data.readString(); - java.lang.String _arg2; - _arg2 = data.readString(); - java.lang.String _arg3; - _arg3 = data.readString(); - android.os.Bundle _arg4; - if ((0!=data.readInt())) { - _arg4 = android.os.Bundle.CREATOR.createFromParcel(data); - } - else { - _arg4 = null; - } - android.os.Bundle _result = this.getPurchaseHistory(_arg0, _arg1, _arg2, _arg3, _arg4); - reply.writeNoException(); - if ((_result!=null)) { - reply.writeInt(1); - _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE); - } - else { - reply.writeInt(0); - } - return true; - } - case TRANSACTION_isBillingSupportedExtraParams: - { - data.enforceInterface(DESCRIPTOR); - int _arg0; - _arg0 = data.readInt(); - java.lang.String _arg1; - _arg1 = data.readString(); - java.lang.String _arg2; - _arg2 = data.readString(); - android.os.Bundle _arg3; - if ((0!=data.readInt())) { - _arg3 = android.os.Bundle.CREATOR.createFromParcel(data); - } - else { - _arg3 = null; - } - int _result = this.isBillingSupportedExtraParams(_arg0, _arg1, _arg2, _arg3); - reply.writeNoException(); - reply.writeInt(_result); - return true; - } - } - return super.onTransact(code, data, reply, flags); - } - private static class Proxy implements com.android.vending.billing.IInAppBillingService - { - private android.os.IBinder mRemote; - Proxy(android.os.IBinder remote) - { - mRemote = remote; - } - @Override public android.os.IBinder asBinder() - { - return mRemote; - } - public java.lang.String getInterfaceDescriptor() - { - return DESCRIPTOR; - } - @Override public int isBillingSupported(int apiVersion, java.lang.String packageName, java.lang.String type) throws android.os.RemoteException - { - android.os.Parcel _data = android.os.Parcel.obtain(); - android.os.Parcel _reply = android.os.Parcel.obtain(); - int _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeInt(apiVersion); - _data.writeString(packageName); - _data.writeString(type); - mRemote.transact(Stub.TRANSACTION_isBillingSupported, _data, _reply, 0); - _reply.readException(); - _result = _reply.readInt(); - } - finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - /** - * Provides details of a list of SKUs - * Given a list of SKUs of a valid type in the skusBundle, this returns a bundle - * with a list JSON strings containing the productId, price, title and description. - * This API can be called with a maximum of 20 SKUs. - * @param apiVersion billing API version that the app is using - * @param packageName the package name of the calling app - * @param type of the in-app items ("inapp" for one-time purchases - * and "subs" for subscriptions) - * @param skusBundle bundle containing a StringArrayList of SKUs with key "ITEM_ID_LIST" - * @return Bundle containing the following key-value pairs - * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes - * on failures. - * "DETAILS_LIST" with a StringArrayList containing purchase information - * in JSON format similar to: - * '{ "productId" : "exampleSku", - * "type" : "inapp", - * "price" : "$5.00", - * "price_currency": "USD", - * "price_amount_micros": 5000000, - * "title : "Example Title", - * "description" : "This is an example description" }' - */ - @Override public android.os.Bundle getSkuDetails(int apiVersion, java.lang.String packageName, java.lang.String type, android.os.Bundle skusBundle) throws android.os.RemoteException - { - android.os.Parcel _data = android.os.Parcel.obtain(); - android.os.Parcel _reply = android.os.Parcel.obtain(); - android.os.Bundle _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeInt(apiVersion); - _data.writeString(packageName); - _data.writeString(type); - if ((skusBundle!=null)) { - _data.writeInt(1); - skusBundle.writeToParcel(_data, 0); - } - else { - _data.writeInt(0); - } - mRemote.transact(Stub.TRANSACTION_getSkuDetails, _data, _reply, 0); - _reply.readException(); - if ((0!=_reply.readInt())) { - _result = android.os.Bundle.CREATOR.createFromParcel(_reply); - } - else { - _result = null; - } - } - finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - /** - * Returns a pending intent to launch the purchase flow for an in-app item by providing a SKU, - * the type, a unique purchase token and an optional developer payload. - * @param apiVersion billing API version that the app is using - * @param packageName package name of the calling app - * @param sku the SKU of the in-app item as published in the developer console - * @param type of the in-app item being purchased ("inapp" for one-time purchases - * and "subs" for subscriptions) - * @param developerPayload optional argument to be sent back with the purchase information - * @return Bundle containing the following key-value pairs - * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes - * on failures. - * "BUY_INTENT" - PendingIntent to start the purchase flow - * - * The Pending intent should be launched with startIntentSenderForResult. When purchase flow - * has completed, the onActivityResult() will give a resultCode of OK or CANCELED. - * If the purchase is successful, the result data will contain the following key-value pairs - * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response - * codes on failures. - * "INAPP_PURCHASE_DATA" - String in JSON format similar to - * '{"orderId":"12999763169054705758.1371079406387615", - * "packageName":"com.example.app", - * "productId":"exampleSku", - * "purchaseTime":1345678900000, - * "purchaseToken" : "122333444455555", - * "developerPayload":"example developer payload" }' - * "INAPP_DATA_SIGNATURE" - String containing the signature of the purchase data that - * was signed with the private key of the developer - */ - @Override public android.os.Bundle getBuyIntent(int apiVersion, java.lang.String packageName, java.lang.String sku, java.lang.String type, java.lang.String developerPayload) throws android.os.RemoteException - { - android.os.Parcel _data = android.os.Parcel.obtain(); - android.os.Parcel _reply = android.os.Parcel.obtain(); - android.os.Bundle _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeInt(apiVersion); - _data.writeString(packageName); - _data.writeString(sku); - _data.writeString(type); - _data.writeString(developerPayload); - mRemote.transact(Stub.TRANSACTION_getBuyIntent, _data, _reply, 0); - _reply.readException(); - if ((0!=_reply.readInt())) { - _result = android.os.Bundle.CREATOR.createFromParcel(_reply); - } - else { - _result = null; - } - } - finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - /** - * Returns the current SKUs owned by the user of the type and package name specified along with - * purchase information and a signature of the data to be validated. - * This will return all SKUs that have been purchased in V3 and managed items purchased using - * V1 and V2 that have not been consumed. - * @param apiVersion billing API version that the app is using - * @param packageName package name of the calling app - * @param type of the in-app items being requested ("inapp" for one-time purchases - * and "subs" for subscriptions) - * @param continuationToken to be set as null for the first call, if the number of owned - * skus are too many, a continuationToken is returned in the response bundle. - * This method can be called again with the continuation token to get the next set of - * owned skus. - * @return Bundle containing the following key-value pairs - * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes - on failures. - * "INAPP_PURCHASE_ITEM_LIST" - StringArrayList containing the list of SKUs - * "INAPP_PURCHASE_DATA_LIST" - StringArrayList containing the purchase information - * "INAPP_DATA_SIGNATURE_LIST"- StringArrayList containing the signatures - * of the purchase information - * "INAPP_CONTINUATION_TOKEN" - String containing a continuation token for the - * next set of in-app purchases. Only set if the - * user has more owned skus than the current list. - */ - @Override public android.os.Bundle getPurchases(int apiVersion, java.lang.String packageName, java.lang.String type, java.lang.String continuationToken) throws android.os.RemoteException - { - android.os.Parcel _data = android.os.Parcel.obtain(); - android.os.Parcel _reply = android.os.Parcel.obtain(); - android.os.Bundle _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeInt(apiVersion); - _data.writeString(packageName); - _data.writeString(type); - _data.writeString(continuationToken); - mRemote.transact(Stub.TRANSACTION_getPurchases, _data, _reply, 0); - _reply.readException(); - if ((0!=_reply.readInt())) { - _result = android.os.Bundle.CREATOR.createFromParcel(_reply); - } - else { - _result = null; - } - } - finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - @Override public int consumePurchase(int apiVersion, java.lang.String packageName, java.lang.String purchaseToken) throws android.os.RemoteException - { - android.os.Parcel _data = android.os.Parcel.obtain(); - android.os.Parcel _reply = android.os.Parcel.obtain(); - int _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeInt(apiVersion); - _data.writeString(packageName); - _data.writeString(purchaseToken); - mRemote.transact(Stub.TRANSACTION_consumePurchase, _data, _reply, 0); - _reply.readException(); - _result = _reply.readInt(); - } - finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - @Override public int stub(int apiVersion, java.lang.String packageName, java.lang.String type) throws android.os.RemoteException - { - android.os.Parcel _data = android.os.Parcel.obtain(); - android.os.Parcel _reply = android.os.Parcel.obtain(); - int _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeInt(apiVersion); - _data.writeString(packageName); - _data.writeString(type); - mRemote.transact(Stub.TRANSACTION_stub, _data, _reply, 0); - _reply.readException(); - _result = _reply.readInt(); - } - finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - /** - * Returns a pending intent to launch the purchase flow for upgrading or downgrading a - * subscription. The existing owned SKU(s) should be provided along with the new SKU that - * the user is upgrading or downgrading to. - * @param apiVersion billing API version that the app is using, must be 5 or later - * @param packageName package name of the calling app - * @param oldSkus the SKU(s) that the user is upgrading or downgrading from, - * if null or empty this method will behave like {@link #getBuyIntent} - * @param newSku the SKU that the user is upgrading or downgrading to - * @param type of the item being purchased, currently must be "subs" - * @param developerPayload optional argument to be sent back with the purchase information - * @return Bundle containing the following key-value pairs - * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes - * on failures. - * "BUY_INTENT" - PendingIntent to start the purchase flow - * - * The Pending intent should be launched with startIntentSenderForResult. When purchase flow - * has completed, the onActivityResult() will give a resultCode of OK or CANCELED. - * If the purchase is successful, the result data will contain the following key-value pairs - * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response - * codes on failures. - * "INAPP_PURCHASE_DATA" - String in JSON format similar to - * '{"orderId":"12999763169054705758.1371079406387615", - * "packageName":"com.example.app", - * "productId":"exampleSku", - * "purchaseTime":1345678900000, - * "purchaseToken" : "122333444455555", - * "developerPayload":"example developer payload" }' - * "INAPP_DATA_SIGNATURE" - String containing the signature of the purchase data that - * was signed with the private key of the developer - */ - @Override public android.os.Bundle getBuyIntentToReplaceSkus(int apiVersion, java.lang.String packageName, java.util.List<java.lang.String> oldSkus, java.lang.String newSku, java.lang.String type, java.lang.String developerPayload) throws android.os.RemoteException - { - android.os.Parcel _data = android.os.Parcel.obtain(); - android.os.Parcel _reply = android.os.Parcel.obtain(); - android.os.Bundle _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeInt(apiVersion); - _data.writeString(packageName); - _data.writeStringList(oldSkus); - _data.writeString(newSku); - _data.writeString(type); - _data.writeString(developerPayload); - mRemote.transact(Stub.TRANSACTION_getBuyIntentToReplaceSkus, _data, _reply, 0); - _reply.readException(); - if ((0!=_reply.readInt())) { - _result = android.os.Bundle.CREATOR.createFromParcel(_reply); - } - else { - _result = null; - } - } - finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - /** - * Returns a pending intent to launch the purchase flow for an in-app item. This method is - * a variant of the {@link #getBuyIntent} method and takes an additional {@code extraParams} - * parameter. This parameter is a Bundle of optional keys and values that affect the - * operation of the method. - * @param apiVersion billing API version that the app is using, must be 6 or later - * @param packageName package name of the calling app - * @param sku the SKU of the in-app item as published in the developer console - * @param type of the in-app item being purchased ("inapp" for one-time purchases - * and "subs" for subscriptions) - * @param developerPayload optional argument to be sent back with the purchase information - * @extraParams a Bundle with the following optional keys: - * "skusToReplace" - List<String> - an optional list of SKUs that the user is - * upgrading or downgrading from. - * Pass this field if the purchase is upgrading or downgrading - * existing subscriptions. - * The specified SKUs are replaced with the SKUs that the user is - * purchasing. Google Play replaces the specified SKUs at the start of - * the next billing cycle. - * "replaceSkusProration" - Boolean - whether the user should be credited for any unused - * subscription time on the SKUs they are upgrading or downgrading. - * If you set this field to true, Google Play swaps out the old SKUs - * and credits the user with the unused value of their subscription - * time on a pro-rated basis. - * Google Play applies this credit to the new subscription, and does - * not begin billing the user for the new subscription until after - * the credit is used up. - * If you set this field to false, the user does not receive credit for - * any unused subscription time and the recurrence date does not - * change. - * Default value is true. Ignored if you do not pass skusToReplace. - * "accountId" - String - an optional obfuscated string that is uniquely - * associated with the user's account in your app. - * If you pass this value, Google Play can use it to detect irregular - * activity, such as many devices making purchases on the same - * account in a short period of time. - * Do not use the developer ID or the user's Google ID for this field. - * In addition, this field should not contain the user's ID in - * cleartext. - * We recommend that you use a one-way hash to generate a string from - * the user's ID, and store the hashed string in this field. - * "vr" - Boolean - an optional flag indicating whether the returned intent - * should start a VR purchase flow. The apiVersion must also be 7 or - * later to use this flag. - */ - @Override public android.os.Bundle getBuyIntentExtraParams(int apiVersion, java.lang.String packageName, java.lang.String sku, java.lang.String type, java.lang.String developerPayload, android.os.Bundle extraParams) throws android.os.RemoteException - { - android.os.Parcel _data = android.os.Parcel.obtain(); - android.os.Parcel _reply = android.os.Parcel.obtain(); - android.os.Bundle _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeInt(apiVersion); - _data.writeString(packageName); - _data.writeString(sku); - _data.writeString(type); - _data.writeString(developerPayload); - if ((extraParams!=null)) { - _data.writeInt(1); - extraParams.writeToParcel(_data, 0); - } - else { - _data.writeInt(0); - } - mRemote.transact(Stub.TRANSACTION_getBuyIntentExtraParams, _data, _reply, 0); - _reply.readException(); - if ((0!=_reply.readInt())) { - _result = android.os.Bundle.CREATOR.createFromParcel(_reply); - } - else { - _result = null; - } - } - finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - /** - * Returns the most recent purchase made by the user for each SKU, even if that purchase is - * expired, canceled, or consumed. - * @param apiVersion billing API version that the app is using, must be 6 or later - * @param packageName package name of the calling app - * @param type of the in-app items being requested ("inapp" for one-time purchases - * and "subs" for subscriptions) - * @param continuationToken to be set as null for the first call, if the number of owned - * skus is too large, a continuationToken is returned in the response bundle. - * This method can be called again with the continuation token to get the next set of - * owned skus. - * @param extraParams a Bundle with extra params that would be appended into http request - * query string. Not used at this moment. Reserved for future functionality. - * @return Bundle containing the following key-value pairs - * "RESPONSE_CODE" with int value: RESULT_OK(0) if success, - * {@link IabHelper#BILLING_RESPONSE_RESULT_*} response codes on failures. - * - * "INAPP_PURCHASE_ITEM_LIST" - ArrayList<String> containing the list of SKUs - * "INAPP_PURCHASE_DATA_LIST" - ArrayList<String> containing the purchase information - * "INAPP_DATA_SIGNATURE_LIST"- ArrayList<String> containing the signatures - * of the purchase information - * "INAPP_CONTINUATION_TOKEN" - String containing a continuation token for the - * next set of in-app purchases. Only set if the - * user has more owned skus than the current list. - */ - @Override public android.os.Bundle getPurchaseHistory(int apiVersion, java.lang.String packageName, java.lang.String type, java.lang.String continuationToken, android.os.Bundle extraParams) throws android.os.RemoteException - { - android.os.Parcel _data = android.os.Parcel.obtain(); - android.os.Parcel _reply = android.os.Parcel.obtain(); - android.os.Bundle _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeInt(apiVersion); - _data.writeString(packageName); - _data.writeString(type); - _data.writeString(continuationToken); - if ((extraParams!=null)) { - _data.writeInt(1); - extraParams.writeToParcel(_data, 0); - } - else { - _data.writeInt(0); - } - mRemote.transact(Stub.TRANSACTION_getPurchaseHistory, _data, _reply, 0); - _reply.readException(); - if ((0!=_reply.readInt())) { - _result = android.os.Bundle.CREATOR.createFromParcel(_reply); - } - else { - _result = null; - } - } - finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - @Override public int isBillingSupportedExtraParams(int apiVersion, java.lang.String packageName, java.lang.String type, android.os.Bundle extraParams) throws android.os.RemoteException - { - android.os.Parcel _data = android.os.Parcel.obtain(); - android.os.Parcel _reply = android.os.Parcel.obtain(); - int _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeInt(apiVersion); - _data.writeString(packageName); - _data.writeString(type); - if ((extraParams!=null)) { - _data.writeInt(1); - extraParams.writeToParcel(_data, 0); - } - else { - _data.writeInt(0); - } - mRemote.transact(Stub.TRANSACTION_isBillingSupportedExtraParams, _data, _reply, 0); - _reply.readException(); - _result = _reply.readInt(); - } - finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - } - static final int TRANSACTION_isBillingSupported = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); - static final int TRANSACTION_getSkuDetails = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1); - static final int TRANSACTION_getBuyIntent = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2); - static final int TRANSACTION_getPurchases = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3); - static final int TRANSACTION_consumePurchase = (android.os.IBinder.FIRST_CALL_TRANSACTION + 4); - static final int TRANSACTION_stub = (android.os.IBinder.FIRST_CALL_TRANSACTION + 5); - static final int TRANSACTION_getBuyIntentToReplaceSkus = (android.os.IBinder.FIRST_CALL_TRANSACTION + 6); - static final int TRANSACTION_getBuyIntentExtraParams = (android.os.IBinder.FIRST_CALL_TRANSACTION + 7); - static final int TRANSACTION_getPurchaseHistory = (android.os.IBinder.FIRST_CALL_TRANSACTION + 8); - static final int TRANSACTION_isBillingSupportedExtraParams = (android.os.IBinder.FIRST_CALL_TRANSACTION + 9); - } - public int isBillingSupported(int apiVersion, java.lang.String packageName, java.lang.String type) throws android.os.RemoteException; - /** - * Provides details of a list of SKUs - * Given a list of SKUs of a valid type in the skusBundle, this returns a bundle - * with a list JSON strings containing the productId, price, title and description. - * This API can be called with a maximum of 20 SKUs. - * @param apiVersion billing API version that the app is using - * @param packageName the package name of the calling app - * @param type of the in-app items ("inapp" for one-time purchases - * and "subs" for subscriptions) - * @param skusBundle bundle containing a StringArrayList of SKUs with key "ITEM_ID_LIST" - * @return Bundle containing the following key-value pairs - * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes - * on failures. - * "DETAILS_LIST" with a StringArrayList containing purchase information - * in JSON format similar to: - * '{ "productId" : "exampleSku", - * "type" : "inapp", - * "price" : "$5.00", - * "price_currency": "USD", - * "price_amount_micros": 5000000, - * "title : "Example Title", - * "description" : "This is an example description" }' - */ - public android.os.Bundle getSkuDetails(int apiVersion, java.lang.String packageName, java.lang.String type, android.os.Bundle skusBundle) throws android.os.RemoteException; - /** - * Returns a pending intent to launch the purchase flow for an in-app item by providing a SKU, - * the type, a unique purchase token and an optional developer payload. - * @param apiVersion billing API version that the app is using - * @param packageName package name of the calling app - * @param sku the SKU of the in-app item as published in the developer console - * @param type of the in-app item being purchased ("inapp" for one-time purchases - * and "subs" for subscriptions) - * @param developerPayload optional argument to be sent back with the purchase information - * @return Bundle containing the following key-value pairs - * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes - * on failures. - * "BUY_INTENT" - PendingIntent to start the purchase flow - * - * The Pending intent should be launched with startIntentSenderForResult. When purchase flow - * has completed, the onActivityResult() will give a resultCode of OK or CANCELED. - * If the purchase is successful, the result data will contain the following key-value pairs - * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response - * codes on failures. - * "INAPP_PURCHASE_DATA" - String in JSON format similar to - * '{"orderId":"12999763169054705758.1371079406387615", - * "packageName":"com.example.app", - * "productId":"exampleSku", - * "purchaseTime":1345678900000, - * "purchaseToken" : "122333444455555", - * "developerPayload":"example developer payload" }' - * "INAPP_DATA_SIGNATURE" - String containing the signature of the purchase data that - * was signed with the private key of the developer - */ - public android.os.Bundle getBuyIntent(int apiVersion, java.lang.String packageName, java.lang.String sku, java.lang.String type, java.lang.String developerPayload) throws android.os.RemoteException; - /** - * Returns the current SKUs owned by the user of the type and package name specified along with - * purchase information and a signature of the data to be validated. - * This will return all SKUs that have been purchased in V3 and managed items purchased using - * V1 and V2 that have not been consumed. - * @param apiVersion billing API version that the app is using - * @param packageName package name of the calling app - * @param type of the in-app items being requested ("inapp" for one-time purchases - * and "subs" for subscriptions) - * @param continuationToken to be set as null for the first call, if the number of owned - * skus are too many, a continuationToken is returned in the response bundle. - * This method can be called again with the continuation token to get the next set of - * owned skus. - * @return Bundle containing the following key-value pairs - * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes - on failures. - * "INAPP_PURCHASE_ITEM_LIST" - StringArrayList containing the list of SKUs - * "INAPP_PURCHASE_DATA_LIST" - StringArrayList containing the purchase information - * "INAPP_DATA_SIGNATURE_LIST"- StringArrayList containing the signatures - * of the purchase information - * "INAPP_CONTINUATION_TOKEN" - String containing a continuation token for the - * next set of in-app purchases. Only set if the - * user has more owned skus than the current list. - */ - public android.os.Bundle getPurchases(int apiVersion, java.lang.String packageName, java.lang.String type, java.lang.String continuationToken) throws android.os.RemoteException; - public int consumePurchase(int apiVersion, java.lang.String packageName, java.lang.String purchaseToken) throws android.os.RemoteException; - public int stub(int apiVersion, java.lang.String packageName, java.lang.String type) throws android.os.RemoteException; - /** - * Returns a pending intent to launch the purchase flow for upgrading or downgrading a - * subscription. The existing owned SKU(s) should be provided along with the new SKU that - * the user is upgrading or downgrading to. - * @param apiVersion billing API version that the app is using, must be 5 or later - * @param packageName package name of the calling app - * @param oldSkus the SKU(s) that the user is upgrading or downgrading from, - * if null or empty this method will behave like {@link #getBuyIntent} - * @param newSku the SKU that the user is upgrading or downgrading to - * @param type of the item being purchased, currently must be "subs" - * @param developerPayload optional argument to be sent back with the purchase information - * @return Bundle containing the following key-value pairs - * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes - * on failures. - * "BUY_INTENT" - PendingIntent to start the purchase flow - * - * The Pending intent should be launched with startIntentSenderForResult. When purchase flow - * has completed, the onActivityResult() will give a resultCode of OK or CANCELED. - * If the purchase is successful, the result data will contain the following key-value pairs - * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response - * codes on failures. - * "INAPP_PURCHASE_DATA" - String in JSON format similar to - * '{"orderId":"12999763169054705758.1371079406387615", - * "packageName":"com.example.app", - * "productId":"exampleSku", - * "purchaseTime":1345678900000, - * "purchaseToken" : "122333444455555", - * "developerPayload":"example developer payload" }' - * "INAPP_DATA_SIGNATURE" - String containing the signature of the purchase data that - * was signed with the private key of the developer - */ - public android.os.Bundle getBuyIntentToReplaceSkus(int apiVersion, java.lang.String packageName, java.util.List<java.lang.String> oldSkus, java.lang.String newSku, java.lang.String type, java.lang.String developerPayload) throws android.os.RemoteException; - /** - * Returns a pending intent to launch the purchase flow for an in-app item. This method is - * a variant of the {@link #getBuyIntent} method and takes an additional {@code extraParams} - * parameter. This parameter is a Bundle of optional keys and values that affect the - * operation of the method. - * @param apiVersion billing API version that the app is using, must be 6 or later - * @param packageName package name of the calling app - * @param sku the SKU of the in-app item as published in the developer console - * @param type of the in-app item being purchased ("inapp" for one-time purchases - * and "subs" for subscriptions) - * @param developerPayload optional argument to be sent back with the purchase information - * @extraParams a Bundle with the following optional keys: - * "skusToReplace" - List<String> - an optional list of SKUs that the user is - * upgrading or downgrading from. - * Pass this field if the purchase is upgrading or downgrading - * existing subscriptions. - * The specified SKUs are replaced with the SKUs that the user is - * purchasing. Google Play replaces the specified SKUs at the start of - * the next billing cycle. - * "replaceSkusProration" - Boolean - whether the user should be credited for any unused - * subscription time on the SKUs they are upgrading or downgrading. - * If you set this field to true, Google Play swaps out the old SKUs - * and credits the user with the unused value of their subscription - * time on a pro-rated basis. - * Google Play applies this credit to the new subscription, and does - * not begin billing the user for the new subscription until after - * the credit is used up. - * If you set this field to false, the user does not receive credit for - * any unused subscription time and the recurrence date does not - * change. - * Default value is true. Ignored if you do not pass skusToReplace. - * "accountId" - String - an optional obfuscated string that is uniquely - * associated with the user's account in your app. - * If you pass this value, Google Play can use it to detect irregular - * activity, such as many devices making purchases on the same - * account in a short period of time. - * Do not use the developer ID or the user's Google ID for this field. - * In addition, this field should not contain the user's ID in - * cleartext. - * We recommend that you use a one-way hash to generate a string from - * the user's ID, and store the hashed string in this field. - * "vr" - Boolean - an optional flag indicating whether the returned intent - * should start a VR purchase flow. The apiVersion must also be 7 or - * later to use this flag. - */ - public android.os.Bundle getBuyIntentExtraParams(int apiVersion, java.lang.String packageName, java.lang.String sku, java.lang.String type, java.lang.String developerPayload, android.os.Bundle extraParams) throws android.os.RemoteException; - /** - * Returns the most recent purchase made by the user for each SKU, even if that purchase is - * expired, canceled, or consumed. - * @param apiVersion billing API version that the app is using, must be 6 or later - * @param packageName package name of the calling app - * @param type of the in-app items being requested ("inapp" for one-time purchases - * and "subs" for subscriptions) - * @param continuationToken to be set as null for the first call, if the number of owned - * skus is too large, a continuationToken is returned in the response bundle. - * This method can be called again with the continuation token to get the next set of - * owned skus. - * @param extraParams a Bundle with extra params that would be appended into http request - * query string. Not used at this moment. Reserved for future functionality. - * @return Bundle containing the following key-value pairs - * "RESPONSE_CODE" with int value: RESULT_OK(0) if success, - * {@link IabHelper#BILLING_RESPONSE_RESULT_*} response codes on failures. - * - * "INAPP_PURCHASE_ITEM_LIST" - ArrayList<String> containing the list of SKUs - * "INAPP_PURCHASE_DATA_LIST" - ArrayList<String> containing the purchase information - * "INAPP_DATA_SIGNATURE_LIST"- ArrayList<String> containing the signatures - * of the purchase information - * "INAPP_CONTINUATION_TOKEN" - String containing a continuation token for the - * next set of in-app purchases. Only set if the - * user has more owned skus than the current list. - */ - public android.os.Bundle getPurchaseHistory(int apiVersion, java.lang.String packageName, java.lang.String type, java.lang.String continuationToken, android.os.Bundle extraParams) throws android.os.RemoteException; - public int isBillingSupportedExtraParams(int apiVersion, java.lang.String packageName, java.lang.String type, android.os.Bundle extraParams) throws android.os.RemoteException; - } diff --git a/extras/AudioPerformanceTest/Builds/Android/app/src/main/java/com/juce/audioperformancetest/AudioPerformanceTest.java b/extras/AudioPerformanceTest/Builds/Android/app/src/main/java/com/juce/audioperformancetest/AudioPerformanceTest.java deleted file mode 100644 index 3a402c1d..00000000 --- a/extras/AudioPerformanceTest/Builds/Android/app/src/main/java/com/juce/audioperformancetest/AudioPerformanceTest.java +++ /dev/null @@ -1,3166 +0,0 @@ -/* - ============================================================================== - - 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. - - 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. - - ============================================================================== -*/ - -package com.juce.audioperformancetest; - -import android.app.Activity; -import android.app.AlertDialog; -import android.content.DialogInterface; -import android.content.Context; -import android.content.Intent; -import android.content.res.Configuration; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.hardware.camera2.*; -import android.database.ContentObserver; -import android.media.session.*; -import android.media.MediaMetadata; -import android.net.http.SslError; -import android.net.Uri; -import android.os.Bundle; -import android.os.Looper; -import android.os.Handler; -import android.os.Message; -import android.os.ParcelUuid; -import android.os.Environment; -import android.view.*; -import android.view.inputmethod.BaseInputConnection; -import android.view.inputmethod.EditorInfo; -import android.view.inputmethod.InputConnection; -import android.view.inputmethod.InputMethodManager; -import android.graphics.*; -import android.text.ClipboardManager; -import android.text.InputType; -import android.util.DisplayMetrics; -import android.util.Log; -import android.util.Pair; -import android.webkit.SslErrorHandler; -import android.webkit.WebChromeClient; -import android.webkit.WebResourceError; -import android.webkit.WebResourceRequest; -import android.webkit.WebResourceResponse; -import android.webkit.WebView; -import android.webkit.WebViewClient; -import java.lang.Runnable; -import java.lang.ref.WeakReference; -import java.lang.reflect.*; -import java.util.*; -import java.io.*; -import java.net.URL; -import java.net.HttpURLConnection; -import android.media.AudioManager; -import android.Manifest; -import java.util.concurrent.CancellationException; -import java.util.concurrent.Future; -import java.util.concurrent.Executors; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.Callable; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.locks.ReentrantLock; -import java.util.concurrent.atomic.*; - -import android.media.midi.*; -import android.bluetooth.*; -import android.bluetooth.le.*; - - -//============================================================================== -public class AudioPerformanceTest extends Activity -{ - //============================================================================== - static - { - System.loadLibrary ("juce_jni"); - } - - //============================================================================== - public boolean isPermissionDeclaredInManifest (int permissionID) - { - return isPermissionDeclaredInManifest (getAndroidPermissionName (permissionID)); - } - - public boolean isPermissionDeclaredInManifest (String permissionToCheck) - { - try - { - PackageInfo info = getPackageManager().getPackageInfo(getApplicationContext().getPackageName(), PackageManager.GET_PERMISSIONS); - - if (info.requestedPermissions != null) - for (String permission : info.requestedPermissions) - if (permission.equals (permissionToCheck)) - return true; - } - catch (PackageManager.NameNotFoundException e) - { - Log.d ("JUCE", "isPermissionDeclaredInManifest: PackageManager.NameNotFoundException = " + e.toString()); - } - - Log.d ("JUCE", "isPermissionDeclaredInManifest: could not find requested permission " + permissionToCheck); - return false; - } - - //============================================================================== - // these have to match the values of enum PermissionID in C++ class RuntimePermissions: - private static final int JUCE_PERMISSIONS_RECORD_AUDIO = 1; - private static final int JUCE_PERMISSIONS_BLUETOOTH_MIDI = 2; - private static final int JUCE_PERMISSIONS_READ_EXTERNAL_STORAGE = 3; - private static final int JUCE_PERMISSIONS_WRITE_EXTERNAL_STORAGE = 4; - private static final int JUCE_PERMISSIONS_CAMERA = 5; - - private static String getAndroidPermissionName (int permissionID) - { - switch (permissionID) - { - case JUCE_PERMISSIONS_RECORD_AUDIO: return Manifest.permission.RECORD_AUDIO; - case JUCE_PERMISSIONS_BLUETOOTH_MIDI: return Manifest.permission.ACCESS_COARSE_LOCATION; - // use string value as this is not defined in SDKs < 16 - case JUCE_PERMISSIONS_READ_EXTERNAL_STORAGE: return "android.permission.READ_EXTERNAL_STORAGE"; - case JUCE_PERMISSIONS_WRITE_EXTERNAL_STORAGE: return Manifest.permission.WRITE_EXTERNAL_STORAGE; - case JUCE_PERMISSIONS_CAMERA: return Manifest.permission.CAMERA; - } - - // unknown permission ID! - assert false; - return new String(); - } - - public boolean isPermissionGranted (int permissionID) - { - return getApplicationContext().checkCallingOrSelfPermission (getAndroidPermissionName (permissionID)) == PackageManager.PERMISSION_GRANTED; - } - - private Map<Integer, Long> permissionCallbackPtrMap; - - public void requestRuntimePermission (int permissionID, long ptrToCallback) - { - String permissionName = getAndroidPermissionName (permissionID); - - if (getApplicationContext().checkCallingOrSelfPermission (permissionName) != PackageManager.PERMISSION_GRANTED) - { - // remember callbackPtr, request permissions, and let onRequestPermissionResult call callback asynchronously - permissionCallbackPtrMap.put (permissionID, ptrToCallback); - requestPermissionsCompat (new String[]{permissionName}, permissionID); - } - else - { - // permissions were already granted before, we can call callback directly - androidRuntimePermissionsCallback (true, ptrToCallback); - } - } - - private native void androidRuntimePermissionsCallback (boolean permissionWasGranted, long ptrToCallback); - - @Override - public void onRequestPermissionsResult (int permissionID, String permissions[], int[] grantResults) - { - boolean permissionsGranted = (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED); - - if (! permissionsGranted) - Log.d ("JUCE", "onRequestPermissionsResult: runtime permission was DENIED: " + getAndroidPermissionName (permissionID)); - - Long ptrToCallback = permissionCallbackPtrMap.get (permissionID); - permissionCallbackPtrMap.remove (permissionID); - androidRuntimePermissionsCallback (permissionsGranted, ptrToCallback); - } - - //============================================================================== - public interface JuceMidiPort - { - boolean isInputPort(); - - // start, stop does nothing on an output port - void start(); - void stop(); - - void close(); - - // send will do nothing on an input port - void sendMidi (byte[] msg, int offset, int count); - } - - //============================================================================== - //============================================================================== - public class BluetoothManager extends ScanCallback - { - BluetoothManager() - { - } - - public String[] getMidiBluetoothAddresses() - { - return bluetoothMidiDevices.toArray (new String[bluetoothMidiDevices.size()]); - } - - public String getHumanReadableStringForBluetoothAddress (String address) - { - BluetoothDevice btDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice (address); - return btDevice.getName(); - } - - public int getBluetoothDeviceStatus (String address) - { - return getAndroidMidiDeviceManager().getBluetoothDeviceStatus (address); - } - - public void startStopScan (boolean shouldStart) - { - BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); - - if (bluetoothAdapter == null) - { - Log.d ("JUCE", "BluetoothManager error: could not get default Bluetooth adapter"); - return; - } - - BluetoothLeScanner bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner(); - - if (bluetoothLeScanner == null) - { - Log.d ("JUCE", "BluetoothManager error: could not get Bluetooth LE scanner"); - return; - } - - if (shouldStart) - { - ScanFilter.Builder scanFilterBuilder = new ScanFilter.Builder(); - scanFilterBuilder.setServiceUuid (ParcelUuid.fromString (bluetoothLEMidiServiceUUID)); - - ScanSettings.Builder scanSettingsBuilder = new ScanSettings.Builder(); - scanSettingsBuilder.setCallbackType (ScanSettings.CALLBACK_TYPE_ALL_MATCHES) - .setScanMode (ScanSettings.SCAN_MODE_LOW_POWER) - .setScanMode (ScanSettings.MATCH_MODE_STICKY); - - bluetoothLeScanner.startScan (Arrays.asList (scanFilterBuilder.build()), - scanSettingsBuilder.build(), - this); - } - else - { - bluetoothLeScanner.stopScan (this); - } - } - - public boolean pairBluetoothMidiDevice(String address) - { - BluetoothDevice btDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice (address); - - if (btDevice == null) - { - Log.d ("JUCE", "failed to create buletooth device from address"); - return false; - } - - return getAndroidMidiDeviceManager().pairBluetoothDevice (btDevice); - } - - public void unpairBluetoothMidiDevice (String address) - { - getAndroidMidiDeviceManager().unpairBluetoothDevice (address); - } - - public void onScanFailed (int errorCode) - { - } - - public void onScanResult (int callbackType, ScanResult result) - { - if (callbackType == ScanSettings.CALLBACK_TYPE_ALL_MATCHES - || callbackType == ScanSettings.CALLBACK_TYPE_FIRST_MATCH) - { - BluetoothDevice device = result.getDevice(); - - if (device != null) - bluetoothMidiDevices.add (device.getAddress()); - } - - if (callbackType == ScanSettings.CALLBACK_TYPE_MATCH_LOST) - { - Log.d ("JUCE", "ScanSettings.CALLBACK_TYPE_MATCH_LOST"); - BluetoothDevice device = result.getDevice(); - - if (device != null) - { - bluetoothMidiDevices.remove (device.getAddress()); - unpairBluetoothMidiDevice (device.getAddress()); - } - } - } - - public void onBatchScanResults (List<ScanResult> results) - { - for (ScanResult result : results) - onScanResult (ScanSettings.CALLBACK_TYPE_ALL_MATCHES, result); - } - - private BluetoothLeScanner scanner; - private static final String bluetoothLEMidiServiceUUID = "03B80E5A-EDE8-4B33-A751-6CE34EC4C700"; - - private HashSet<String> bluetoothMidiDevices = new HashSet<String>(); - } - - public static class JuceMidiInputPort extends MidiReceiver implements JuceMidiPort - { - private native void handleReceive (long host, byte[] msg, int offset, int count, long timestamp); - - public JuceMidiInputPort (MidiDeviceManager mm, MidiOutputPort actualPort, MidiPortPath portPathToUse, long hostToUse) - { - owner = mm; - androidPort = actualPort; - portPath = portPathToUse; - juceHost = hostToUse; - isConnected = false; - } - - @Override - protected void finalize() throws Throwable - { - close(); - super.finalize(); - } - - @Override - public boolean isInputPort() - { - return true; - } - - @Override - public void start() - { - if (owner != null && androidPort != null && ! isConnected) { - androidPort.connect(this); - isConnected = true; - } - } - - @Override - public void stop() - { - if (owner != null && androidPort != null && isConnected) { - androidPort.disconnect(this); - isConnected = false; - } - } - - @Override - public void close() - { - if (androidPort != null) { - try { - androidPort.close(); - } catch (IOException exception) { - Log.d("JUCE", "IO Exception while closing port"); - } - } - - if (owner != null) - owner.removePort (portPath); - - owner = null; - androidPort = null; - } - - @Override - public void onSend (byte[] msg, int offset, int count, long timestamp) - { - if (count > 0) - handleReceive (juceHost, msg, offset, count, timestamp); - } - - @Override - public void onFlush() - {} - - @Override - public void sendMidi (byte[] msg, int offset, int count) - { - } - - MidiDeviceManager owner; - MidiOutputPort androidPort; - MidiPortPath portPath; - long juceHost; - boolean isConnected; - } - - public static class JuceMidiOutputPort implements JuceMidiPort - { - public JuceMidiOutputPort (MidiDeviceManager mm, MidiInputPort actualPort, MidiPortPath portPathToUse) - { - owner = mm; - androidPort = actualPort; - portPath = portPathToUse; - } - - @Override - protected void finalize() throws Throwable - { - close(); - super.finalize(); - } - - @Override - public boolean isInputPort() - { - return false; - } - - @Override - public void start() - { - } - - @Override - public void stop() - { - } - - @Override - public void sendMidi (byte[] msg, int offset, int count) - { - if (androidPort != null) - { - try { - androidPort.send(msg, offset, count); - } catch (IOException exception) - { - Log.d ("JUCE", "send midi had IO exception"); - } - } - } - - @Override - public void close() - { - if (androidPort != null) { - try { - androidPort.close(); - } catch (IOException exception) { - Log.d("JUCE", "IO Exception while closing port"); - } - } - - if (owner != null) - owner.removePort (portPath); - - owner = null; - androidPort = null; - } - - MidiDeviceManager owner; - MidiInputPort androidPort; - MidiPortPath portPath; - } - - private static class MidiPortPath extends Object - { - public MidiPortPath (int deviceIdToUse, boolean direction, int androidIndex) - { - deviceId = deviceIdToUse; - isInput = direction; - portIndex = androidIndex; - - } - - public int deviceId; - public int portIndex; - public boolean isInput; - - @Override - public int hashCode() - { - Integer i = new Integer ((deviceId * 128) + (portIndex < 128 ? portIndex : 127)); - return i.hashCode() * (isInput ? -1 : 1); - } - - @Override - public boolean equals (Object obj) - { - if (obj == null) - return false; - - if (getClass() != obj.getClass()) - return false; - - MidiPortPath other = (MidiPortPath) obj; - return (portIndex == other.portIndex && isInput == other.isInput && deviceId == other.deviceId); - } - } - - //============================================================================== - public class MidiDeviceManager extends MidiManager.DeviceCallback implements MidiManager.OnDeviceOpenedListener - { - //============================================================================== - private class DummyBluetoothGattCallback extends BluetoothGattCallback - { - public DummyBluetoothGattCallback (MidiDeviceManager mm) - { - super(); - owner = mm; - } - - public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) - { - if (newState == BluetoothProfile.STATE_CONNECTED) - { - gatt.requestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_HIGH); - owner.pairBluetoothDeviceStepTwo (gatt.getDevice()); - } - } - public void onServicesDiscovered(BluetoothGatt gatt, int status) {} - public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {} - public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {} - public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {} - public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {} - public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {} - public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {} - public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {} - public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {} - - private MidiDeviceManager owner; - } - - //============================================================================== - private class MidiDeviceOpenTask extends java.util.TimerTask - { - public MidiDeviceOpenTask (MidiDeviceManager deviceManager, MidiDevice device, BluetoothGatt gattToUse) - { - owner = deviceManager; - midiDevice = device; - btGatt = gattToUse; - } - - @Override - public boolean cancel() - { - synchronized (MidiDeviceOpenTask.class) - { - owner = null; - boolean retval = super.cancel(); - - if (btGatt != null) - { - btGatt.disconnect(); - btGatt.close(); - - btGatt = null; - } - - if (midiDevice != null) - { - try - { - midiDevice.close(); - } - catch (IOException e) - {} - - midiDevice = null; - } - - return retval; - } - } - - public String getBluetoothAddress() - { - synchronized (MidiDeviceOpenTask.class) - { - if (midiDevice != null) - { - MidiDeviceInfo info = midiDevice.getInfo(); - if (info.getType() == MidiDeviceInfo.TYPE_BLUETOOTH) - { - BluetoothDevice btDevice = (BluetoothDevice) info.getProperties().get (info.PROPERTY_BLUETOOTH_DEVICE); - if (btDevice != null) - return btDevice.getAddress(); - } - } - } - - return ""; - } - - public BluetoothGatt getGatt() { return btGatt; } - - public int getID() - { - return midiDevice.getInfo().getId(); - } - - @Override - public void run() - { - synchronized (MidiDeviceOpenTask.class) - { - if (owner != null && midiDevice != null) - owner.onDeviceOpenedDelayed (midiDevice); - } - } - - private MidiDeviceManager owner; - private MidiDevice midiDevice; - private BluetoothGatt btGatt; - } - - //============================================================================== - public MidiDeviceManager() - { - manager = (MidiManager) getSystemService (MIDI_SERVICE); - - if (manager == null) - { - Log.d ("JUCE", "MidiDeviceManager error: could not get MidiManager system service"); - return; - } - - openPorts = new HashMap<MidiPortPath, WeakReference<JuceMidiPort>> (); - midiDevices = new ArrayList<Pair<MidiDevice,BluetoothGatt>>(); - openTasks = new HashMap<Integer, MidiDeviceOpenTask>(); - btDevicesPairing = new HashMap<String, BluetoothGatt>(); - - MidiDeviceInfo[] foundDevices = manager.getDevices(); - for (MidiDeviceInfo info : foundDevices) - onDeviceAdded (info); - - manager.registerDeviceCallback (this, null); - } - - protected void finalize() throws Throwable - { - manager.unregisterDeviceCallback (this); - - synchronized (MidiDeviceManager.class) - { - btDevicesPairing.clear(); - - for (Integer deviceID : openTasks.keySet()) - openTasks.get (deviceID).cancel(); - - openTasks = null; - } - - for (MidiPortPath key : openPorts.keySet()) - openPorts.get (key).get().close(); - - openPorts = null; - - for (Pair<MidiDevice, BluetoothGatt> device : midiDevices) - { - if (device.second != null) - { - device.second.disconnect(); - device.second.close(); - } - - device.first.close(); - } - - midiDevices.clear(); - - super.finalize(); - } - - public String[] getJuceAndroidMidiInputDevices() - { - return getJuceAndroidMidiDevices (MidiDeviceInfo.PortInfo.TYPE_OUTPUT); - } - - public String[] getJuceAndroidMidiOutputDevices() - { - return getJuceAndroidMidiDevices (MidiDeviceInfo.PortInfo.TYPE_INPUT); - } - - private String[] getJuceAndroidMidiDevices (int portType) - { - // only update the list when JUCE asks for a new list - synchronized (MidiDeviceManager.class) - { - deviceInfos = getDeviceInfos(); - } - - ArrayList<String> portNames = new ArrayList<String>(); - - int index = 0; - for (MidiPortPath portInfo = getPortPathForJuceIndex (portType, index); portInfo != null; portInfo = getPortPathForJuceIndex (portType, ++index)) - portNames.add (getPortName (portInfo)); - - String[] names = new String[portNames.size()]; - return portNames.toArray (names); - } - - private JuceMidiPort openMidiPortWithJuceIndex (int index, long host, boolean isInput) - { - synchronized (MidiDeviceManager.class) - { - int portTypeToFind = (isInput ? MidiDeviceInfo.PortInfo.TYPE_OUTPUT : MidiDeviceInfo.PortInfo.TYPE_INPUT); - MidiPortPath portInfo = getPortPathForJuceIndex (portTypeToFind, index); - - if (portInfo != null) - { - // ports must be opened exclusively! - if (openPorts.containsKey (portInfo)) - return null; - - Pair<MidiDevice,BluetoothGatt> devicePair = getMidiDevicePairForId (portInfo.deviceId); - - if (devicePair != null) - { - MidiDevice device = devicePair.first; - if (device != null) - { - JuceMidiPort juceMidiPort = null; - - if (isInput) - { - MidiOutputPort outputPort = device.openOutputPort(portInfo.portIndex); - - if (outputPort != null) - juceMidiPort = new JuceMidiInputPort(this, outputPort, portInfo, host); - } - else - { - MidiInputPort inputPort = device.openInputPort(portInfo.portIndex); - - if (inputPort != null) - juceMidiPort = new JuceMidiOutputPort(this, inputPort, portInfo); - } - - if (juceMidiPort != null) - { - openPorts.put(portInfo, new WeakReference<JuceMidiPort>(juceMidiPort)); - - return juceMidiPort; - } - } - } - } - } - - return null; - } - - public JuceMidiPort openMidiInputPortWithJuceIndex (int index, long host) - { - return openMidiPortWithJuceIndex (index, host, true); - } - - public JuceMidiPort openMidiOutputPortWithJuceIndex (int index) - { - return openMidiPortWithJuceIndex (index, 0, false); - } - - /* 0: unpaired, 1: paired, 2: pairing */ - public int getBluetoothDeviceStatus (String address) - { - synchronized (MidiDeviceManager.class) - { - if (! address.isEmpty()) - { - if (findMidiDeviceForBluetoothAddress (address) != null) - return 1; - - if (btDevicesPairing.containsKey (address)) - return 2; - - if (findOpenTaskForBluetoothAddress (address) != null) - return 2; - } - } - - return 0; - } - - public boolean pairBluetoothDevice (BluetoothDevice btDevice) - { - String btAddress = btDevice.getAddress(); - if (btAddress.isEmpty()) - return false; - - synchronized (MidiDeviceManager.class) - { - if (getBluetoothDeviceStatus (btAddress) != 0) - return false; - - - btDevicesPairing.put (btDevice.getAddress(), null); - BluetoothGatt gatt = btDevice.connectGatt (getApplicationContext(), true, new DummyBluetoothGattCallback (this)); - - if (gatt != null) - { - btDevicesPairing.put (btDevice.getAddress(), gatt); - } - else - { - pairBluetoothDeviceStepTwo (btDevice); - } - } - - return true; - } - - public void pairBluetoothDeviceStepTwo (BluetoothDevice btDevice) - { - manager.openBluetoothDevice(btDevice, this, null); - } - - public void unpairBluetoothDevice (String address) - { - if (address.isEmpty()) - return; - - synchronized (MidiDeviceManager.class) - { - if (btDevicesPairing.containsKey (address)) - { - BluetoothGatt gatt = btDevicesPairing.get (address); - if (gatt != null) - { - gatt.disconnect(); - gatt.close(); - } - - btDevicesPairing.remove (address); - } - - MidiDeviceOpenTask openTask = findOpenTaskForBluetoothAddress (address); - if (openTask != null) - { - int deviceID = openTask.getID(); - openTask.cancel(); - openTasks.remove (deviceID); - } - - Pair<MidiDevice, BluetoothGatt> midiDevicePair = findMidiDeviceForBluetoothAddress (address); - if (midiDevicePair != null) - { - MidiDevice midiDevice = midiDevicePair.first; - onDeviceRemoved (midiDevice.getInfo()); - - try { - midiDevice.close(); - } - catch (IOException exception) - { - Log.d ("JUCE", "IOException while closing midi device"); - } - } - } - } - - private Pair<MidiDevice, BluetoothGatt> findMidiDeviceForBluetoothAddress (String address) - { - for (Pair<MidiDevice,BluetoothGatt> midiDevice : midiDevices) - { - MidiDeviceInfo info = midiDevice.first.getInfo(); - if (info.getType() == MidiDeviceInfo.TYPE_BLUETOOTH) - { - BluetoothDevice btDevice = (BluetoothDevice) info.getProperties().get (info.PROPERTY_BLUETOOTH_DEVICE); - if (btDevice != null && btDevice.getAddress().equals (address)) - return midiDevice; - } - } - - return null; - } - - private MidiDeviceOpenTask findOpenTaskForBluetoothAddress (String address) - { - for (Integer deviceID : openTasks.keySet()) - { - MidiDeviceOpenTask openTask = openTasks.get (deviceID); - if (openTask.getBluetoothAddress().equals (address)) - return openTask; - } - - return null; - } - - public void removePort (MidiPortPath path) - { - openPorts.remove (path); - } - - public String getInputPortNameForJuceIndex (int index) - { - MidiPortPath portInfo = getPortPathForJuceIndex (MidiDeviceInfo.PortInfo.TYPE_OUTPUT, index); - if (portInfo != null) - return getPortName (portInfo); - - return ""; - } - - public String getOutputPortNameForJuceIndex (int index) - { - MidiPortPath portInfo = getPortPathForJuceIndex (MidiDeviceInfo.PortInfo.TYPE_INPUT, index); - if (portInfo != null) - return getPortName (portInfo); - - return ""; - } - - public void onDeviceAdded (MidiDeviceInfo info) - { - // only add standard midi devices - if (info.getType() == info.TYPE_BLUETOOTH) - return; - - manager.openDevice (info, this, null); - } - - public void onDeviceRemoved (MidiDeviceInfo info) - { - synchronized (MidiDeviceManager.class) - { - Pair<MidiDevice, BluetoothGatt> devicePair = getMidiDevicePairForId (info.getId()); - - if (devicePair != null) - { - MidiDevice midiDevice = devicePair.first; - BluetoothGatt gatt = devicePair.second; - - // close all ports that use this device - boolean removedPort = true; - - while (removedPort == true) - { - removedPort = false; - for (MidiPortPath key : openPorts.keySet()) - { - if (key.deviceId == info.getId()) - { - openPorts.get(key).get().close(); - removedPort = true; - break; - } - } - } - - if (gatt != null) - { - gatt.disconnect(); - gatt.close(); - } - - midiDevices.remove (devicePair); - } - } - } - - public void onDeviceStatusChanged (MidiDeviceStatus status) - { - } - - @Override - public void onDeviceOpened (MidiDevice theDevice) - { - synchronized (MidiDeviceManager.class) - { - MidiDeviceInfo info = theDevice.getInfo(); - int deviceID = info.getId(); - BluetoothGatt gatt = null; - boolean isBluetooth = false; - - if (! openTasks.containsKey (deviceID)) - { - if (info.getType() == MidiDeviceInfo.TYPE_BLUETOOTH) - { - isBluetooth = true; - BluetoothDevice btDevice = (BluetoothDevice) info.getProperties().get (info.PROPERTY_BLUETOOTH_DEVICE); - if (btDevice != null) - { - String btAddress = btDevice.getAddress(); - if (btDevicesPairing.containsKey (btAddress)) - { - gatt = btDevicesPairing.get (btAddress); - btDevicesPairing.remove (btAddress); - } - else - { - // unpair was called in the mean time - try - { - Pair<MidiDevice, BluetoothGatt> midiDevicePair = findMidiDeviceForBluetoothAddress (btDevice.getAddress()); - if (midiDevicePair != null) - { - gatt = midiDevicePair.second; - - if (gatt != null) - { - gatt.disconnect(); - gatt.close(); - } - } - - theDevice.close(); - } - catch (IOException e) - {} - - return; - } - } - } - - MidiDeviceOpenTask openTask = new MidiDeviceOpenTask (this, theDevice, gatt); - openTasks.put (deviceID, openTask); - - new java.util.Timer().schedule (openTask, (isBluetooth ? 2000 : 100)); - } - } - } - - public void onDeviceOpenedDelayed (MidiDevice theDevice) - { - synchronized (MidiDeviceManager.class) - { - int deviceID = theDevice.getInfo().getId(); - - if (openTasks.containsKey (deviceID)) - { - if (! midiDevices.contains(theDevice)) - { - BluetoothGatt gatt = openTasks.get (deviceID).getGatt(); - openTasks.remove (deviceID); - midiDevices.add (new Pair<MidiDevice,BluetoothGatt> (theDevice, gatt)); - } - } - else - { - // unpair was called in the mean time - MidiDeviceInfo info = theDevice.getInfo(); - BluetoothDevice btDevice = (BluetoothDevice) info.getProperties().get (info.PROPERTY_BLUETOOTH_DEVICE); - if (btDevice != null) - { - String btAddress = btDevice.getAddress(); - Pair<MidiDevice, BluetoothGatt> midiDevicePair = findMidiDeviceForBluetoothAddress (btDevice.getAddress()); - if (midiDevicePair != null) - { - BluetoothGatt gatt = midiDevicePair.second; - - if (gatt != null) - { - gatt.disconnect(); - gatt.close(); - } - } - } - - try - { - theDevice.close(); - } - catch (IOException e) - {} - } - } - } - - public String getPortName(MidiPortPath path) - { - int portTypeToFind = (path.isInput ? MidiDeviceInfo.PortInfo.TYPE_INPUT : MidiDeviceInfo.PortInfo.TYPE_OUTPUT); - - synchronized (MidiDeviceManager.class) - { - for (MidiDeviceInfo info : deviceInfos) - { - int localIndex = 0; - if (info.getId() == path.deviceId) - { - for (MidiDeviceInfo.PortInfo portInfo : info.getPorts()) - { - int portType = portInfo.getType(); - if (portType == portTypeToFind) - { - int portIndex = portInfo.getPortNumber(); - if (portIndex == path.portIndex) - { - String portName = portInfo.getName(); - if (portName.isEmpty()) - portName = (String) info.getProperties().get(info.PROPERTY_NAME); - - return portName; - } - } - } - } - } - } - - return ""; - } - - public MidiPortPath getPortPathForJuceIndex (int portType, int juceIndex) - { - int portIdx = 0; - for (MidiDeviceInfo info : deviceInfos) - { - for (MidiDeviceInfo.PortInfo portInfo : info.getPorts()) - { - if (portInfo.getType() == portType) - { - if (portIdx == juceIndex) - return new MidiPortPath (info.getId(), - (portType == MidiDeviceInfo.PortInfo.TYPE_INPUT), - portInfo.getPortNumber()); - - portIdx++; - } - } - } - - return null; - } - - private MidiDeviceInfo[] getDeviceInfos() - { - synchronized (MidiDeviceManager.class) - { - MidiDeviceInfo[] infos = new MidiDeviceInfo[midiDevices.size()]; - - int idx = 0; - for (Pair<MidiDevice,BluetoothGatt> midiDevice : midiDevices) - infos[idx++] = midiDevice.first.getInfo(); - - return infos; - } - } - - private Pair<MidiDevice, BluetoothGatt> getMidiDevicePairForId (int deviceId) - { - synchronized (MidiDeviceManager.class) - { - for (Pair<MidiDevice,BluetoothGatt> midiDevice : midiDevices) - if (midiDevice.first.getInfo().getId() == deviceId) - return midiDevice; - } - - return null; - } - - private MidiManager manager; - private HashMap<String, BluetoothGatt> btDevicesPairing; - private HashMap<Integer, MidiDeviceOpenTask> openTasks; - private ArrayList<Pair<MidiDevice, BluetoothGatt>> midiDevices; - private MidiDeviceInfo[] deviceInfos; - private HashMap<MidiPortPath, WeakReference<JuceMidiPort>> openPorts; - } - - public MidiDeviceManager getAndroidMidiDeviceManager() - { - if (getSystemService (MIDI_SERVICE) == null) - return null; - - synchronized (AudioPerformanceTest.class) - { - if (midiDeviceManager == null) - midiDeviceManager = new MidiDeviceManager(); - } - - return midiDeviceManager; - } - - public BluetoothManager getAndroidBluetoothManager() - { - BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); - - if (adapter == null) - return null; - - if (adapter.getBluetoothLeScanner() == null) - return null; - - synchronized (AudioPerformanceTest.class) - { - if (bluetoothManager == null) - bluetoothManager = new BluetoothManager(); - } - - return bluetoothManager; - } - - //============================================================================== - @Override - public void onCreate (Bundle savedInstanceState) - { - super.onCreate (savedInstanceState); - - isScreenSaverEnabled = true; - hideActionBar(); - viewHolder = new ViewHolder (this); - setContentView (viewHolder); - - setVolumeControlStream (AudioManager.STREAM_MUSIC); - - permissionCallbackPtrMap = new HashMap<Integer, Long>(); - appPausedResumedListeners = new HashMap<Long, AppPausedResumedListener>(); - } - - @Override - protected void onDestroy() - { - quitApp(); - super.onDestroy(); - - clearDataCache(); - } - - @Override - protected void onPause() - { - suspendApp(); - - Long[] keys = appPausedResumedListeners.keySet().toArray (new Long[appPausedResumedListeners.keySet().size()]); - - for (Long k : keys) - appPausedResumedListeners.get (k).appPaused(); - - try - { - Thread.sleep (1000); // This is a bit of a hack to avoid some hard-to-track-down - // openGL glitches when pausing/resuming apps.. - } catch (InterruptedException e) {} - - super.onPause(); - } - - @Override - protected void onResume() - { - super.onResume(); - resumeApp(); - - Long[] keys = appPausedResumedListeners.keySet().toArray (new Long[appPausedResumedListeners.keySet().size()]); - - for (Long k : keys) - appPausedResumedListeners.get (k).appResumed(); - } - - @Override - public void onConfigurationChanged (Configuration cfg) - { - super.onConfigurationChanged (cfg); - setContentView (viewHolder); - } - - private void callAppLauncher() - { - launchApp (getApplicationInfo().publicSourceDir, - getApplicationInfo().dataDir); - } - - // Need to override this as the default implementation always finishes the activity. - @Override - public void onBackPressed() - { - ComponentPeerView focusedView = getViewWithFocusOrDefaultView(); - - if (focusedView == null) - return; - - focusedView.backButtonPressed(); - } - - private ComponentPeerView getViewWithFocusOrDefaultView() - { - for (int i = 0; i < viewHolder.getChildCount(); ++i) - { - if (viewHolder.getChildAt (i).hasFocus()) - return (ComponentPeerView) viewHolder.getChildAt (i); - } - - if (viewHolder.getChildCount() > 0) - return (ComponentPeerView) viewHolder.getChildAt (0); - - return null; - } - - //============================================================================== - private void hideActionBar() - { - // get "getActionBar" method - java.lang.reflect.Method getActionBarMethod = null; - try - { - getActionBarMethod = this.getClass().getMethod ("getActionBar"); - } - catch (SecurityException e) { return; } - catch (NoSuchMethodException e) { return; } - if (getActionBarMethod == null) return; - - // invoke "getActionBar" method - Object actionBar = null; - try - { - actionBar = getActionBarMethod.invoke (this); - } - catch (java.lang.IllegalArgumentException e) { return; } - catch (java.lang.IllegalAccessException e) { return; } - catch (java.lang.reflect.InvocationTargetException e) { return; } - if (actionBar == null) return; - - // get "hide" method - java.lang.reflect.Method actionBarHideMethod = null; - try - { - actionBarHideMethod = actionBar.getClass().getMethod ("hide"); - } - catch (SecurityException e) { return; } - catch (NoSuchMethodException e) { return; } - if (actionBarHideMethod == null) return; - - // invoke "hide" method - try - { - actionBarHideMethod.invoke (actionBar); - } - catch (java.lang.IllegalArgumentException e) {} - catch (java.lang.IllegalAccessException e) {} - catch (java.lang.reflect.InvocationTargetException e) {} - } - - void requestPermissionsCompat (String[] permissions, int requestCode) - { - Method requestPermissionsMethod = null; - try - { - requestPermissionsMethod = this.getClass().getMethod ("requestPermissions", - String[].class, int.class); - } - catch (SecurityException e) { return; } - catch (NoSuchMethodException e) { return; } - if (requestPermissionsMethod == null) return; - - try - { - requestPermissionsMethod.invoke (this, permissions, requestCode); - } - catch (java.lang.IllegalArgumentException e) {} - catch (java.lang.IllegalAccessException e) {} - catch (java.lang.reflect.InvocationTargetException e) {} - } - - //============================================================================== - private native void launchApp (String appFile, String appDataDir); - private native void quitApp(); - private native void suspendApp(); - private native void resumeApp(); - private native void setScreenSize (int screenWidth, int screenHeight, int dpi); - private native void appActivityResult (int requestCode, int resultCode, Intent data); - private native void appNewIntent (Intent intent); - - //============================================================================== - private ViewHolder viewHolder; - private MidiDeviceManager midiDeviceManager = null; - private BluetoothManager bluetoothManager = null; - private boolean isScreenSaverEnabled; - private java.util.Timer keepAliveTimer; - - public final ComponentPeerView createNewView (boolean opaque, long host) - { - ComponentPeerView v = new ComponentPeerView (this, opaque, host); - viewHolder.addView (v); - addAppPausedResumedListener (v, host); - return v; - } - - public final void deleteView (ComponentPeerView view) - { - removeAppPausedResumedListener (view, view.host); - - view.host = 0; - - ViewGroup group = (ViewGroup) (view.getParent()); - - if (group != null) - group.removeView (view); - } - - public final void deleteNativeSurfaceView (NativeSurfaceView view) - { - ViewGroup group = (ViewGroup) (view.getParent()); - - if (group != null) - group.removeView (view); - } - - final class ViewHolder extends ViewGroup - { - public ViewHolder (Context context) - { - super (context); - setDescendantFocusability (ViewGroup.FOCUS_AFTER_DESCENDANTS); - setFocusable (false); - } - - protected final void onLayout (boolean changed, int left, int top, int right, int bottom) - { - setScreenSize (getWidth(), getHeight(), getDPI()); - - if (isFirstResize) - { - isFirstResize = false; - callAppLauncher(); - } - } - - private final int getDPI() - { - DisplayMetrics metrics = new DisplayMetrics(); - getWindowManager().getDefaultDisplay().getMetrics (metrics); - return metrics.densityDpi; - } - - private boolean isFirstResize = true; - } - - public final void excludeClipRegion (android.graphics.Canvas canvas, float left, float top, float right, float bottom) - { - canvas.clipRect (left, top, right, bottom, android.graphics.Region.Op.DIFFERENCE); - } - - //============================================================================== - public final void setScreenSaver (boolean enabled) - { - if (isScreenSaverEnabled != enabled) - { - isScreenSaverEnabled = enabled; - - if (keepAliveTimer != null) - { - keepAliveTimer.cancel(); - keepAliveTimer = null; - } - - if (enabled) - { - getWindow().clearFlags (WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); - } - else - { - getWindow().addFlags (WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); - - // If no user input is received after about 3 seconds, the OS will lower the - // task's priority, so this timer forces it to be kept active. - keepAliveTimer = new java.util.Timer(); - - keepAliveTimer.scheduleAtFixedRate (new TimerTask() - { - @Override - public void run() - { - android.app.Instrumentation instrumentation = new android.app.Instrumentation(); - - try - { - instrumentation.sendKeyDownUpSync (KeyEvent.KEYCODE_UNKNOWN); - } - catch (Exception e) - { - } - } - }, 2000, 2000); - } - } - } - - public final boolean getScreenSaver() - { - return isScreenSaverEnabled; - } - - //============================================================================== - public final String getClipboardContent() - { - ClipboardManager clipboard = (ClipboardManager) getSystemService (CLIPBOARD_SERVICE); - - CharSequence content = clipboard.getText(); - return content != null ? content.toString() : new String(); - } - - public final void setClipboardContent (String newText) - { - ClipboardManager clipboard = (ClipboardManager) getSystemService (CLIPBOARD_SERVICE); - clipboard.setText (newText); - } - - //============================================================================== - public final void showMessageBox (String title, String message, final long callback) - { - AlertDialog.Builder builder = new AlertDialog.Builder (this); - builder.setTitle (title) - .setMessage (message) - .setCancelable (true) - .setOnCancelListener (new DialogInterface.OnCancelListener() - { - public void onCancel (DialogInterface dialog) - { - AudioPerformanceTest.this.alertDismissed (callback, 0); - } - }) - .setPositiveButton ("OK", new DialogInterface.OnClickListener() - { - public void onClick (DialogInterface dialog, int id) - { - dialog.dismiss(); - AudioPerformanceTest.this.alertDismissed (callback, 0); - } - }); - - builder.create().show(); - } - - public final void showOkCancelBox (String title, String message, final long callback, - String okButtonText, String cancelButtonText) - { - AlertDialog.Builder builder = new AlertDialog.Builder (this); - builder.setTitle (title) - .setMessage (message) - .setCancelable (true) - .setOnCancelListener (new DialogInterface.OnCancelListener() - { - public void onCancel (DialogInterface dialog) - { - AudioPerformanceTest.this.alertDismissed (callback, 0); - } - }) - .setPositiveButton (okButtonText.isEmpty() ? "OK" : okButtonText, new DialogInterface.OnClickListener() - { - public void onClick (DialogInterface dialog, int id) - { - dialog.dismiss(); - AudioPerformanceTest.this.alertDismissed (callback, 1); - } - }) - .setNegativeButton (cancelButtonText.isEmpty() ? "Cancel" : cancelButtonText, new DialogInterface.OnClickListener() - { - public void onClick (DialogInterface dialog, int id) - { - dialog.dismiss(); - AudioPerformanceTest.this.alertDismissed (callback, 0); - } - }); - - builder.create().show(); - } - - public final void showYesNoCancelBox (String title, String message, final long callback) - { - AlertDialog.Builder builder = new AlertDialog.Builder (this); - builder.setTitle (title) - .setMessage (message) - .setCancelable (true) - .setOnCancelListener (new DialogInterface.OnCancelListener() - { - public void onCancel (DialogInterface dialog) - { - AudioPerformanceTest.this.alertDismissed (callback, 0); - } - }) - .setPositiveButton ("Yes", new DialogInterface.OnClickListener() - { - public void onClick (DialogInterface dialog, int id) - { - dialog.dismiss(); - AudioPerformanceTest.this.alertDismissed (callback, 1); - } - }) - .setNegativeButton ("No", new DialogInterface.OnClickListener() - { - public void onClick (DialogInterface dialog, int id) - { - dialog.dismiss(); - AudioPerformanceTest.this.alertDismissed (callback, 2); - } - }) - .setNeutralButton ("Cancel", new DialogInterface.OnClickListener() - { - public void onClick (DialogInterface dialog, int id) - { - dialog.dismiss(); - AudioPerformanceTest.this.alertDismissed (callback, 0); - } - }); - - builder.create().show(); - } - - public native void alertDismissed (long callback, int id); - - //============================================================================== - public interface AppPausedResumedListener - { - void appPaused(); - void appResumed(); - } - - private Map<Long, AppPausedResumedListener> appPausedResumedListeners; - - public void addAppPausedResumedListener (AppPausedResumedListener l, long listenerHost) - { - appPausedResumedListeners.put (new Long (listenerHost), l); - } - - public void removeAppPausedResumedListener (AppPausedResumedListener l, long listenerHost) - { - appPausedResumedListeners.remove (new Long (listenerHost)); - } - - //============================================================================== - public final class ComponentPeerView extends ViewGroup - implements View.OnFocusChangeListener, AppPausedResumedListener - { - public ComponentPeerView (Context context, boolean opaque_, long host) - { - super (context); - this.host = host; - setWillNotDraw (false); - opaque = opaque_; - - setFocusable (true); - setFocusableInTouchMode (true); - setOnFocusChangeListener (this); - - // swap red and blue colours to match internal opengl texture format - ColorMatrix colorMatrix = new ColorMatrix(); - - float[] colorTransform = { 0, 0, 1.0f, 0, 0, - 0, 1.0f, 0, 0, 0, - 1.0f, 0, 0, 0, 0, - 0, 0, 0, 1.0f, 0 }; - - colorMatrix.set (colorTransform); - paint.setColorFilter (new ColorMatrixColorFilter (colorMatrix)); - - java.lang.reflect.Method method = null; - - try - { - method = getClass().getMethod ("setLayerType", int.class, Paint.class); - } - catch (SecurityException e) {} - catch (NoSuchMethodException e) {} - - if (method != null) - { - try - { - int layerTypeNone = 0; - method.invoke (this, layerTypeNone, null); - } - catch (java.lang.IllegalArgumentException e) {} - catch (java.lang.IllegalAccessException e) {} - catch (java.lang.reflect.InvocationTargetException e) {} - } - } - - //============================================================================== - private native void handlePaint (long host, Canvas canvas, Paint paint); - - @Override - public void onDraw (Canvas canvas) - { - if (host == 0) - return; - - handlePaint (host, canvas, paint); - } - - @Override - public boolean isOpaque() - { - return opaque; - } - - private boolean opaque; - private long host; - private Paint paint = new Paint(); - - //============================================================================== - private native void handleMouseDown (long host, int index, float x, float y, long time); - private native void handleMouseDrag (long host, int index, float x, float y, long time); - private native void handleMouseUp (long host, int index, float x, float y, long time); - - @Override - public boolean onTouchEvent (MotionEvent event) - { - if (host == 0) - return false; - - int action = event.getAction(); - long time = event.getEventTime(); - - switch (action & MotionEvent.ACTION_MASK) - { - case MotionEvent.ACTION_DOWN: - handleMouseDown (host, event.getPointerId(0), event.getX(), event.getY(), time); - return true; - - case MotionEvent.ACTION_CANCEL: - case MotionEvent.ACTION_UP: - handleMouseUp (host, event.getPointerId(0), event.getX(), event.getY(), time); - return true; - - case MotionEvent.ACTION_MOVE: - { - int n = event.getPointerCount(); - for (int i = 0; i < n; ++i) - handleMouseDrag (host, event.getPointerId(i), event.getX(i), event.getY(i), time); - - return true; - } - - case MotionEvent.ACTION_POINTER_UP: - { - int i = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; - handleMouseUp (host, event.getPointerId(i), event.getX(i), event.getY(i), time); - return true; - } - - case MotionEvent.ACTION_POINTER_DOWN: - { - int i = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; - handleMouseDown (host, event.getPointerId(i), event.getX(i), event.getY(i), time); - return true; - } - - default: - break; - } - - return false; - } - - //============================================================================== - private native void handleKeyDown (long host, int keycode, int textchar); - private native void handleKeyUp (long host, int keycode, int textchar); - private native void handleBackButton (long host); - private native void handleKeyboardHidden (long host); - - public void showKeyboard (String type) - { - InputMethodManager imm = (InputMethodManager) getSystemService (Context.INPUT_METHOD_SERVICE); - - if (imm != null) - { - if (type.length() > 0) - { - imm.showSoftInput (this, android.view.inputmethod.InputMethodManager.SHOW_IMPLICIT); - imm.setInputMethod (getWindowToken(), type); - keyboardDismissListener.startListening(); - } - else - { - imm.hideSoftInputFromWindow (getWindowToken(), 0); - keyboardDismissListener.stopListening(); - } - } - } - - public void backButtonPressed() - { - if (host == 0) - return; - - handleBackButton (host); - } - - @Override - public boolean onKeyDown (int keyCode, KeyEvent event) - { - if (host == 0) - return false; - - switch (keyCode) - { - case KeyEvent.KEYCODE_VOLUME_UP: - case KeyEvent.KEYCODE_VOLUME_DOWN: - return super.onKeyDown (keyCode, event); - case KeyEvent.KEYCODE_BACK: - { - ((Activity) getContext()).onBackPressed(); - return true; - } - - default: - break; - } - - handleKeyDown (host, keyCode, event.getUnicodeChar()); - return true; - } - - @Override - public boolean onKeyUp (int keyCode, KeyEvent event) - { - if (host == 0) - return false; - - handleKeyUp (host, keyCode, event.getUnicodeChar()); - return true; - } - - @Override - public boolean onKeyMultiple (int keyCode, int count, KeyEvent event) - { - if (host == 0) - return false; - - if (keyCode != KeyEvent.KEYCODE_UNKNOWN || event.getAction() != KeyEvent.ACTION_MULTIPLE) - return super.onKeyMultiple (keyCode, count, event); - - if (event.getCharacters() != null) - { - int utf8Char = event.getCharacters().codePointAt (0); - handleKeyDown (host, utf8Char, utf8Char); - return true; - } - - return false; - } - - //============================================================================== - private final class KeyboardDismissListener - { - public KeyboardDismissListener (ComponentPeerView viewToUse) - { - view = viewToUse; - } - - private void startListening() - { - view.getViewTreeObserver().addOnGlobalLayoutListener(viewTreeObserver); - } - - private void stopListening() - { - view.getViewTreeObserver().removeGlobalOnLayoutListener(viewTreeObserver); - } - - private class TreeObserver implements ViewTreeObserver.OnGlobalLayoutListener - { - TreeObserver() - { - keyboardShown = false; - } - - @Override - public void onGlobalLayout() - { - Rect r = new Rect(); - - ViewGroup parentView = (ViewGroup) getParent(); - - if (parentView == null) - return; - - parentView.getWindowVisibleDisplayFrame (r); - - int diff = parentView.getHeight() - (r.bottom - r.top); - - // Arbitrary threshold, surely keyboard would take more than 20 pix. - if (diff < 20 && keyboardShown) - { - keyboardShown = false; - handleKeyboardHidden (view.host); - } - - if (! keyboardShown && diff > 20) - keyboardShown = true; - }; - - private boolean keyboardShown; - }; - - private ComponentPeerView view; - private TreeObserver viewTreeObserver = new TreeObserver(); - } - - private KeyboardDismissListener keyboardDismissListener = new KeyboardDismissListener(this); - - // this is here to make keyboard entry work on a Galaxy Tab2 10.1 - @Override - public InputConnection onCreateInputConnection (EditorInfo outAttrs) - { - outAttrs.actionLabel = ""; - outAttrs.hintText = ""; - outAttrs.initialCapsMode = 0; - outAttrs.initialSelEnd = outAttrs.initialSelStart = -1; - outAttrs.label = ""; - outAttrs.imeOptions = EditorInfo.IME_ACTION_DONE | EditorInfo.IME_FLAG_NO_EXTRACT_UI; - outAttrs.inputType = InputType.TYPE_NULL; - - return new BaseInputConnection (this, false); - } - - //============================================================================== - @Override - protected void onSizeChanged (int w, int h, int oldw, int oldh) - { - if (host == 0) - return; - - super.onSizeChanged (w, h, oldw, oldh); - viewSizeChanged (host); - } - - @Override - protected void onLayout (boolean changed, int left, int top, int right, int bottom) - { - for (int i = getChildCount(); --i >= 0;) - requestTransparentRegion (getChildAt (i)); - } - - private native void viewSizeChanged (long host); - - @Override - public void onFocusChange (View v, boolean hasFocus) - { - if (host == 0) - return; - - if (v == this) - focusChanged (host, hasFocus); - } - - private native void focusChanged (long host, boolean hasFocus); - - public void setViewName (String newName) {} - - public void setSystemUiVisibilityCompat (int visibility) - { - Method systemUIVisibilityMethod = null; - try - { - systemUIVisibilityMethod = this.getClass().getMethod ("setSystemUiVisibility", int.class); - } - catch (SecurityException e) { return; } - catch (NoSuchMethodException e) { return; } - if (systemUIVisibilityMethod == null) return; - - try - { - systemUIVisibilityMethod.invoke (this, visibility); - } - catch (java.lang.IllegalArgumentException e) {} - catch (java.lang.IllegalAccessException e) {} - catch (java.lang.reflect.InvocationTargetException e) {} - } - - public boolean isVisible() { return getVisibility() == VISIBLE; } - public void setVisible (boolean b) { setVisibility (b ? VISIBLE : INVISIBLE); } - - public boolean containsPoint (int x, int y) - { - return true; //xxx needs to check overlapping views - } - - //============================================================================== - private native void handleAppPaused (long host); - private native void handleAppResumed (long host); - - @Override - public void appPaused() - { - if (host == 0) - return; - - handleAppPaused (host); - } - - @Override - public void appResumed() - { - if (host == 0) - return; - - // Ensure that navigation/status bar visibility is correctly restored. - handleAppResumed (host); - } - } - - //============================================================================== - public static class NativeSurfaceView extends SurfaceView - implements SurfaceHolder.Callback - { - private long nativeContext = 0; - private boolean forVideo; - - NativeSurfaceView (Context context, long nativeContextPtr, boolean createdForVideo) - { - super (context); - nativeContext = nativeContextPtr; - forVideo = createdForVideo; - } - - public Surface getNativeSurface() - { - Surface retval = null; - - SurfaceHolder holder = getHolder(); - if (holder != null) - retval = holder.getSurface(); - - return retval; - } - - //============================================================================== - @Override - public void surfaceChanged (SurfaceHolder holder, int format, int width, int height) - { - if (forVideo) - surfaceChangedNativeVideo (nativeContext, holder, format, width, height); - else - surfaceChangedNative (nativeContext, holder, format, width, height); - } - - @Override - public void surfaceCreated (SurfaceHolder holder) - { - if (forVideo) - surfaceCreatedNativeVideo (nativeContext, holder); - else - surfaceCreatedNative (nativeContext, holder); - } - - @Override - public void surfaceDestroyed (SurfaceHolder holder) - { - if (forVideo) - surfaceDestroyedNativeVideo (nativeContext, holder); - else - surfaceDestroyedNative (nativeContext, holder); - } - - @Override - protected void dispatchDraw (Canvas canvas) - { - super.dispatchDraw (canvas); - - if (forVideo) - dispatchDrawNativeVideo (nativeContext, canvas); - else - dispatchDrawNative (nativeContext, canvas); - } - - //============================================================================== - @Override - protected void onAttachedToWindow() - { - super.onAttachedToWindow(); - getHolder().addCallback (this); - } - - @Override - protected void onDetachedFromWindow() - { - super.onDetachedFromWindow(); - getHolder().removeCallback (this); - } - - //============================================================================== - private native void dispatchDrawNative (long nativeContextPtr, Canvas canvas); - private native void surfaceCreatedNative (long nativeContextptr, SurfaceHolder holder); - private native void surfaceDestroyedNative (long nativeContextptr, SurfaceHolder holder); - private native void surfaceChangedNative (long nativeContextptr, SurfaceHolder holder, - int format, int width, int height); - - private native void dispatchDrawNativeVideo (long nativeContextPtr, Canvas canvas); - private native void surfaceCreatedNativeVideo (long nativeContextptr, SurfaceHolder holder); - private native void surfaceDestroyedNativeVideo (long nativeContextptr, SurfaceHolder holder); - private native void surfaceChangedNativeVideo (long nativeContextptr, SurfaceHolder holder, - int format, int width, int height); - } - - public NativeSurfaceView createNativeSurfaceView (long nativeSurfacePtr, boolean forVideo) - { - return new NativeSurfaceView (this, nativeSurfacePtr, forVideo); - } - - //============================================================================== - public final int[] renderGlyph (char glyph1, char glyph2, Paint paint, android.graphics.Matrix matrix, Rect bounds) - { - Path p = new Path(); - - char[] str = { glyph1, glyph2 }; - paint.getTextPath (str, 0, (glyph2 != 0 ? 2 : 1), 0.0f, 0.0f, p); - - RectF boundsF = new RectF(); - p.computeBounds (boundsF, true); - matrix.mapRect (boundsF); - - boundsF.roundOut (bounds); - bounds.left--; - bounds.right++; - - final int w = bounds.width(); - final int h = Math.max (1, bounds.height()); - - Bitmap bm = Bitmap.createBitmap (w, h, Bitmap.Config.ARGB_8888); - - Canvas c = new Canvas (bm); - matrix.postTranslate (-bounds.left, -bounds.top); - c.setMatrix (matrix); - c.drawPath (p, paint); - - final int sizeNeeded = w * h; - if (cachedRenderArray.length < sizeNeeded) - cachedRenderArray = new int [sizeNeeded]; - - bm.getPixels (cachedRenderArray, 0, w, 0, 0, w, h); - bm.recycle(); - return cachedRenderArray; - } - - private int[] cachedRenderArray = new int [256]; - - //============================================================================== - public static class NativeInvocationHandler implements InvocationHandler - { - public NativeInvocationHandler (Activity activityToUse, long nativeContextRef) - { - activity = activityToUse; - nativeContext = nativeContextRef; - } - - public void nativeContextDeleted() - { - nativeContext = 0; - } - - @Override - public void finalize() - { - activity.runOnUiThread (new Runnable() - { - @Override - public void run() - { - if (nativeContext != 0) - dispatchFinalize (nativeContext); - } - }); - } - - @Override - public Object invoke (Object proxy, Method method, Object[] args) throws Throwable - { - return dispatchInvoke (nativeContext, proxy, method, args); - } - - //============================================================================== - Activity activity; - private long nativeContext = 0; - - private native void dispatchFinalize (long nativeContextRef); - private native Object dispatchInvoke (long nativeContextRef, Object proxy, Method method, Object[] args); - } - - public InvocationHandler createInvocationHandler (long nativeContextRef) - { - return new NativeInvocationHandler (this, nativeContextRef); - } - - public void invocationHandlerContextDeleted (InvocationHandler handler) - { - ((NativeInvocationHandler) handler).nativeContextDeleted(); - } - - //============================================================================== - public static class HTTPStream - { - public HTTPStream (String address, boolean isPostToUse, byte[] postDataToUse, - String headersToUse, int timeOutMsToUse, - int[] statusCodeToUse, StringBuffer responseHeadersToUse, - int numRedirectsToFollowToUse, String httpRequestCmdToUse) throws IOException - { - isPost = isPostToUse; - postData = postDataToUse; - headers = headersToUse; - timeOutMs = timeOutMsToUse; - statusCode = statusCodeToUse; - responseHeaders = responseHeadersToUse; - totalLength = -1; - numRedirectsToFollow = numRedirectsToFollowToUse; - httpRequestCmd = httpRequestCmdToUse; - - connection = createConnection (address, isPost, postData, headers, timeOutMs, httpRequestCmd); - } - - private final HttpURLConnection createConnection (String address, boolean isPost, byte[] postData, - String headers, int timeOutMs, String httpRequestCmdToUse) throws IOException - { - HttpURLConnection newConnection = (HttpURLConnection) (new URL(address).openConnection()); - - try - { - newConnection.setInstanceFollowRedirects (false); - newConnection.setConnectTimeout (timeOutMs); - newConnection.setReadTimeout (timeOutMs); - - // headers - if not empty, this string is appended onto the headers that are used for the request. It must therefore be a valid set of HTML header directives, separated by newlines. - // So convert headers string to an array, with an element for each line - String headerLines[] = headers.split("\\n"); - - // Set request headers - for (int i = 0; i < headerLines.length; ++i) - { - int pos = headerLines[i].indexOf (":"); - - if (pos > 0 && pos < headerLines[i].length()) - { - String field = headerLines[i].substring (0, pos); - String value = headerLines[i].substring (pos + 1); - - if (value.length() > 0) - newConnection.setRequestProperty (field, value); - } - } - - newConnection.setRequestMethod (httpRequestCmd); - - if (isPost) - { - newConnection.setDoOutput (true); - - if (postData != null) - { - OutputStream out = newConnection.getOutputStream(); - out.write(postData); - out.flush(); - } - } - - return newConnection; - } - catch (Throwable e) - { - newConnection.disconnect(); - throw new IOException ("Connection error"); - } - } - - private final InputStream getCancellableStream (final boolean isInput) throws ExecutionException - { - synchronized (createFutureLock) - { - if (hasBeenCancelled.get()) - return null; - - streamFuture = executor.submit (new Callable<BufferedInputStream>() - { - @Override - public BufferedInputStream call() throws IOException - { - return new BufferedInputStream (isInput ? connection.getInputStream() - : connection.getErrorStream()); - } - }); - } - - try - { - return streamFuture.get(); - } - catch (InterruptedException e) - { - return null; - } - catch (CancellationException e) - { - return null; - } - } - - public final boolean connect() - { - boolean result = false; - int numFollowedRedirects = 0; - - while (true) - { - result = doConnect(); - - if (! result) - return false; - - if (++numFollowedRedirects > numRedirectsToFollow) - break; - - int status = statusCode[0]; - - if (status == 301 || status == 302 || status == 303 || status == 307) - { - // Assumes only one occurrence of "Location" - int pos1 = responseHeaders.indexOf ("Location:") + 10; - int pos2 = responseHeaders.indexOf ("\n", pos1); - - if (pos2 > pos1) - { - String currentLocation = connection.getURL().toString(); - String newLocation = responseHeaders.substring (pos1, pos2); - - try - { - // Handle newLocation whether it's absolute or relative - URL baseUrl = new URL (currentLocation); - URL newUrl = new URL (baseUrl, newLocation); - String transformedNewLocation = newUrl.toString(); - - if (transformedNewLocation != currentLocation) - { - // Clear responseHeaders before next iteration - responseHeaders.delete (0, responseHeaders.length()); - - synchronized (createStreamLock) - { - if (hasBeenCancelled.get()) - return false; - - connection.disconnect(); - - try - { - connection = createConnection (transformedNewLocation, isPost, - postData, headers, timeOutMs, - httpRequestCmd); - } - catch (Throwable e) - { - return false; - } - } - } - else - { - break; - } - } - catch (Throwable e) - { - return false; - } - } - else - { - break; - } - } - else - { - break; - } - } - - return result; - } - - private final boolean doConnect() - { - synchronized (createStreamLock) - { - if (hasBeenCancelled.get()) - return false; - - try - { - try - { - inputStream = getCancellableStream (true); - } - catch (ExecutionException e) - { - if (connection.getResponseCode() < 400) - { - statusCode[0] = connection.getResponseCode(); - connection.disconnect(); - return false; - } - } - finally - { - statusCode[0] = connection.getResponseCode(); - } - - try - { - if (statusCode[0] >= 400) - inputStream = getCancellableStream (false); - else - inputStream = getCancellableStream (true); - } - catch (ExecutionException e) - {} - - for (java.util.Map.Entry<String, java.util.List<String>> entry : connection.getHeaderFields().entrySet()) - { - if (entry.getKey() != null && entry.getValue() != null) - { - responseHeaders.append(entry.getKey() + ": " - + android.text.TextUtils.join(",", entry.getValue()) + "\n"); - - if (entry.getKey().compareTo ("Content-Length") == 0) - totalLength = Integer.decode (entry.getValue().get (0)); - } - } - - return true; - } - catch (IOException e) - { - return false; - } - } - } - - static class DisconnectionRunnable implements Runnable - { - public DisconnectionRunnable (HttpURLConnection theConnection, - InputStream theInputStream, - ReentrantLock theCreateStreamLock, - Object theCreateFutureLock, - Future<BufferedInputStream> theStreamFuture) - { - connectionToDisconnect = theConnection; - inputStream = theInputStream; - createStreamLock = theCreateStreamLock; - createFutureLock = theCreateFutureLock; - streamFuture = theStreamFuture; - } - - public void run() - { - try - { - if (! createStreamLock.tryLock()) - { - synchronized (createFutureLock) - { - if (streamFuture != null) - streamFuture.cancel (true); - } - - createStreamLock.lock(); - } - - if (connectionToDisconnect != null) - connectionToDisconnect.disconnect(); - - if (inputStream != null) - inputStream.close(); - } - catch (IOException e) - {} - finally - { - createStreamLock.unlock(); - } - } - - private HttpURLConnection connectionToDisconnect; - private InputStream inputStream; - private ReentrantLock createStreamLock; - private Object createFutureLock; - Future<BufferedInputStream> streamFuture; - } - - public final void release() - { - DisconnectionRunnable disconnectionRunnable = new DisconnectionRunnable (connection, - inputStream, - createStreamLock, - createFutureLock, - streamFuture); - - synchronized (createStreamLock) - { - hasBeenCancelled.set (true); - - connection = null; - } - - Thread disconnectionThread = new Thread(disconnectionRunnable); - disconnectionThread.start(); - } - - public final int read (byte[] buffer, int numBytes) - { - int num = 0; - - try - { - synchronized (createStreamLock) - { - if (inputStream != null) - num = inputStream.read (buffer, 0, numBytes); - } - } - catch (IOException e) - {} - - if (num > 0) - position += num; - - return num; - } - - public final long getPosition() { return position; } - public final long getTotalLength() { return totalLength; } - public final boolean isExhausted() { return false; } - public final boolean setPosition (long newPos) { return false; } - - private boolean isPost; - private byte[] postData; - private String headers; - private int timeOutMs; - String httpRequestCmd; - private HttpURLConnection connection; - private int[] statusCode; - private StringBuffer responseHeaders; - private int totalLength; - private int numRedirectsToFollow; - private InputStream inputStream; - private long position; - private final ReentrantLock createStreamLock = new ReentrantLock(); - private final Object createFutureLock = new Object(); - private AtomicBoolean hasBeenCancelled = new AtomicBoolean(); - - private final ExecutorService executor = Executors.newCachedThreadPool (Executors.defaultThreadFactory()); - Future<BufferedInputStream> streamFuture; - } - - public static final HTTPStream createHTTPStream (String address, boolean isPost, byte[] postData, - String headers, int timeOutMs, int[] statusCode, - StringBuffer responseHeaders, int numRedirectsToFollow, - String httpRequestCmd) - { - // timeout parameter of zero for HttpUrlConnection is a blocking connect (negative value for juce::URL) - if (timeOutMs < 0) - timeOutMs = 0; - else if (timeOutMs == 0) - timeOutMs = 30000; - - for (;;) - { - try - { - HTTPStream httpStream = new HTTPStream (address, isPost, postData, headers, - timeOutMs, statusCode, responseHeaders, - numRedirectsToFollow, httpRequestCmd); - - return httpStream; - } - catch (Throwable e) {} - - return null; - } - } - - public final void launchURL (String url) - { - startActivity (new Intent (Intent.ACTION_VIEW, Uri.parse (url))); - } - - private native boolean webViewPageLoadStarted (long host, WebView view, String url); - private native void webViewPageLoadFinished (long host, WebView view, String url); - private native void webViewReceivedError (long host, WebView view, WebResourceRequest request, WebResourceError error); private native void webViewReceivedHttpError (long host, WebView view, WebResourceRequest request, WebResourceResponse errorResponse); private native void webViewReceivedSslError (long host, WebView view, SslErrorHandler handler, SslError error); - private native void webViewCloseWindowRequest (long host, WebView view); - private native void webViewCreateWindowRequest (long host, WebView view); - - //============================================================================== - public class JuceWebViewClient extends WebViewClient - { - public JuceWebViewClient (long hostToUse) - { - host = hostToUse; - } - - public void hostDeleted() - { - synchronized (hostLock) - { - host = 0; - } - } - - @Override - public void onPageFinished (WebView view, String url) - { - if (host == 0) - return; - - webViewPageLoadFinished (host, view, url); - } - - @Override - public void onReceivedSslError (WebView view, SslErrorHandler handler, SslError error) - { - if (host == 0) - return; - - webViewReceivedSslError (host, view, handler, error); - } - - @Override - public void onReceivedError (WebView view, WebResourceRequest request, WebResourceError error) - { - if (host == 0) - return; - - webViewReceivedError (host, view, request, error); - } - - @Override - public void onReceivedHttpError (WebView view, WebResourceRequest request, WebResourceResponse errorResponse) - { - if (host == 0) - return; - - webViewReceivedHttpError (host, view, request, errorResponse); - } - - @Override - public WebResourceResponse shouldInterceptRequest (WebView view, WebResourceRequest request) - { - synchronized (hostLock) - { - if (host != 0) - { - boolean shouldLoad = webViewPageLoadStarted (host, view, request.getUrl().toString()); - - if (shouldLoad) - return null; - } - } - - return new WebResourceResponse ("text/html", null, null); - } - - private long host; - private final Object hostLock = new Object(); - } - - public class JuceWebChromeClient extends WebChromeClient - { - public JuceWebChromeClient (long hostToUse) - { - host = hostToUse; - } - - @Override - public void onCloseWindow (WebView window) - { - webViewCloseWindowRequest (host, window); - } - - @Override - public boolean onCreateWindow (WebView view, boolean isDialog, - boolean isUserGesture, Message resultMsg) - { - webViewCreateWindowRequest (host, view); - return false; - } - - private long host; - private final Object hostLock = new Object(); - } - - - //============================================================================== - public class CameraDeviceStateCallback extends CameraDevice.StateCallback - { - private native void cameraDeviceStateClosed (long host, CameraDevice camera); - private native void cameraDeviceStateDisconnected (long host, CameraDevice camera); - private native void cameraDeviceStateError (long host, CameraDevice camera, int error); - private native void cameraDeviceStateOpened (long host, CameraDevice camera); - - CameraDeviceStateCallback (long hostToUse) - { - host = hostToUse; - } - - @Override - public void onClosed (CameraDevice camera) - { - cameraDeviceStateClosed (host, camera); - } - - @Override - public void onDisconnected (CameraDevice camera) - { - cameraDeviceStateDisconnected (host, camera); - } - - @Override - public void onError (CameraDevice camera, int error) - { - cameraDeviceStateError (host, camera, error); - } - - @Override - public void onOpened (CameraDevice camera) - { - cameraDeviceStateOpened (host, camera); - } - - private long host; - } - - //============================================================================== - public class CameraCaptureSessionStateCallback extends CameraCaptureSession.StateCallback - { - private native void cameraCaptureSessionActive (long host, CameraCaptureSession session); - private native void cameraCaptureSessionClosed (long host, CameraCaptureSession session); - private native void cameraCaptureSessionConfigureFailed (long host, CameraCaptureSession session); - private native void cameraCaptureSessionConfigured (long host, CameraCaptureSession session); - private native void cameraCaptureSessionReady (long host, CameraCaptureSession session); - - CameraCaptureSessionStateCallback (long hostToUse) - { - host = hostToUse; - } - - @Override - public void onActive (CameraCaptureSession session) - { - cameraCaptureSessionActive (host, session); - } - - @Override - public void onClosed (CameraCaptureSession session) - { - cameraCaptureSessionClosed (host, session); - } - - @Override - public void onConfigureFailed (CameraCaptureSession session) - { - cameraCaptureSessionConfigureFailed (host, session); - } - - @Override - public void onConfigured (CameraCaptureSession session) - { - cameraCaptureSessionConfigured (host, session); - } - - @Override - public void onReady (CameraCaptureSession session) - { - cameraCaptureSessionReady (host, session); - } - - private long host; - } - - //============================================================================== - public class CameraCaptureSessionCaptureCallback extends CameraCaptureSession.CaptureCallback - { - private native void cameraCaptureSessionCaptureCompleted (long host, boolean isPreview, CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result); - private native void cameraCaptureSessionCaptureFailed (long host, boolean isPreview, CameraCaptureSession session, CaptureRequest request, CaptureFailure failure); - private native void cameraCaptureSessionCaptureProgressed (long host, boolean isPreview, CameraCaptureSession session, CaptureRequest request, CaptureResult partialResult); - private native void cameraCaptureSessionCaptureStarted (long host, boolean isPreview, CameraCaptureSession session, CaptureRequest request, long timestamp, long frameNumber); - private native void cameraCaptureSessionCaptureSequenceAborted (long host, boolean isPreview, CameraCaptureSession session, int sequenceId); - private native void cameraCaptureSessionCaptureSequenceCompleted (long host, boolean isPreview, CameraCaptureSession session, int sequenceId, long frameNumber); - - CameraCaptureSessionCaptureCallback (long hostToUse, boolean shouldBePreview) - { - host = hostToUse; - preview = shouldBePreview; - } - - @Override - public void onCaptureCompleted (CameraCaptureSession session, CaptureRequest request, - TotalCaptureResult result) - { - cameraCaptureSessionCaptureCompleted (host, preview, session, request, result); - } - - @Override - public void onCaptureFailed (CameraCaptureSession session, CaptureRequest request, CaptureFailure failure) - { - cameraCaptureSessionCaptureFailed (host, preview, session, request, failure); - } - - @Override - public void onCaptureProgressed (CameraCaptureSession session, CaptureRequest request, - CaptureResult partialResult) - { - cameraCaptureSessionCaptureProgressed (host, preview, session, request, partialResult); - } - - @Override - public void onCaptureSequenceAborted (CameraCaptureSession session, int sequenceId) - { - cameraCaptureSessionCaptureSequenceAborted (host, preview, session, sequenceId); - } - - @Override - public void onCaptureSequenceCompleted (CameraCaptureSession session, int sequenceId, long frameNumber) - { - cameraCaptureSessionCaptureSequenceCompleted (host, preview, session, sequenceId, frameNumber); - } - - @Override - public void onCaptureStarted (CameraCaptureSession session, CaptureRequest request, long timestamp, - long frameNumber) - { - cameraCaptureSessionCaptureStarted (host, preview, session, request, timestamp, frameNumber); - } - - private long host; - private boolean preview; - } - - //============================================================================== - public class JuceOrientationEventListener extends OrientationEventListener - { - private native void deviceOrientationChanged (long host, int orientation); - - public JuceOrientationEventListener (long hostToUse, Context context, int rate) - { - super (context, rate); - - host = hostToUse; - } - - @Override - public void onOrientationChanged (int orientation) - { - deviceOrientationChanged (host, orientation); - } - - private long host; - } - - - //============================================================================== - public class MediaControllerCallback extends MediaController.Callback - { - private native void mediaControllerAudioInfoChanged (long host, MediaController.PlaybackInfo info); - private native void mediaControllerMetadataChanged (long host, MediaMetadata metadata); - private native void mediaControllerPlaybackStateChanged (long host, PlaybackState state); - private native void mediaControllerSessionDestroyed (long host); - - MediaControllerCallback (long hostToUse) - { - host = hostToUse; - } - - @Override - public void onAudioInfoChanged (MediaController.PlaybackInfo info) - { - mediaControllerAudioInfoChanged (host, info); - } - - @Override - public void onMetadataChanged (MediaMetadata metadata) - { - mediaControllerMetadataChanged (host, metadata); - } - - @Override - public void onPlaybackStateChanged (PlaybackState state) - { - mediaControllerPlaybackStateChanged (host, state); - } - - @Override - public void onQueueChanged (List<MediaSession.QueueItem> queue) {} - - @Override - public void onSessionDestroyed() - { - mediaControllerSessionDestroyed (host); - } - - private long host; - } - - //============================================================================== - public class MediaSessionCallback extends MediaSession.Callback - { - private native void mediaSessionPause (long host); - private native void mediaSessionPlay (long host); - private native void mediaSessionPlayFromMediaId (long host, String mediaId, Bundle extras); - private native void mediaSessionSeekTo (long host, long pos); - private native void mediaSessionStop (long host); - - - MediaSessionCallback (long hostToUse) - { - host = hostToUse; - } - - @Override - public void onPause() - { - mediaSessionPause (host); - } - - @Override - public void onPlay() - { - mediaSessionPlay (host); - } - - @Override - public void onPlayFromMediaId (String mediaId, Bundle extras) - { - mediaSessionPlayFromMediaId (host, mediaId, extras); - } - - @Override - public void onSeekTo (long pos) - { - mediaSessionSeekTo (host, pos); - } - - @Override - public void onStop() - { - mediaSessionStop (host); - } - - @Override - public void onFastForward() {} - - @Override - public boolean onMediaButtonEvent (Intent mediaButtonIntent) - { - return true; - } - - @Override - public void onRewind() {} - - @Override - public void onSkipToNext() {} - - @Override - public void onSkipToPrevious() {} - - @Override - public void onSkipToQueueItem (long id) {} - - private long host; - } - - //============================================================================== - public class SystemVolumeObserver extends ContentObserver - { - private native void mediaSessionSystemVolumeChanged (long host); - - SystemVolumeObserver (Activity activityToUse, long hostToUse) - { - super (null); - - activity = activityToUse; - host = hostToUse; - } - - void setEnabled (boolean shouldBeEnabled) - { - if (shouldBeEnabled) - activity.getApplicationContext().getContentResolver().registerContentObserver (android.provider.Settings.System.CONTENT_URI, true, this); - else - activity.getApplicationContext().getContentResolver().unregisterContentObserver (this); - } - - @Override - public void onChange (boolean selfChange, Uri uri) - { - if (uri.toString().startsWith ("content://settings/system/volume_music")) - mediaSessionSystemVolumeChanged (host); - } - - private Activity activity; - private long host; - } - - - //============================================================================== - public static final String getLocaleValue (boolean isRegion) - { - java.util.Locale locale = java.util.Locale.getDefault(); - - return isRegion ? locale.getCountry() - : locale.getLanguage(); - } - - private static final String getFileLocation (String type) - { - return Environment.getExternalStoragePublicDirectory (type).getAbsolutePath(); - } - - public static final String getDocumentsFolder() - { - if (getAndroidSDKVersion() >= 19) - return getFileLocation ("Documents"); - - return Environment.getDataDirectory().getAbsolutePath(); - } - - public static final String getPicturesFolder() { return getFileLocation (Environment.DIRECTORY_PICTURES); } - public static final String getMusicFolder() { return getFileLocation (Environment.DIRECTORY_MUSIC); } - public static final String getMoviesFolder() { return getFileLocation (Environment.DIRECTORY_MOVIES); } - public static final String getDownloadsFolder() { return getFileLocation (Environment.DIRECTORY_DOWNLOADS); } - - //============================================================================== - @Override - protected void onActivityResult (int requestCode, int resultCode, Intent data) - { - appActivityResult (requestCode, resultCode, data); - } - - @Override - protected void onNewIntent (Intent intent) - { - super.onNewIntent(intent); - setIntent(intent); - - appNewIntent (intent); - } - - //============================================================================== - public final Typeface getTypeFaceFromAsset (String assetName) - { - try - { - return Typeface.createFromAsset (this.getResources().getAssets(), assetName); - } - catch (Throwable e) {} - - return null; - } - - final protected static char[] hexArray = "0123456789ABCDEF".toCharArray(); - - public static String bytesToHex (byte[] bytes) - { - char[] hexChars = new char[bytes.length * 2]; - - for (int j = 0; j < bytes.length; ++j) - { - int v = bytes[j] & 0xff; - hexChars[j * 2] = hexArray[v >>> 4]; - hexChars[j * 2 + 1] = hexArray[v & 0x0f]; - } - - return new String (hexChars); - } - - final private java.util.Map dataCache = new java.util.HashMap(); - - synchronized private final File getDataCacheFile (byte[] data) - { - try - { - java.security.MessageDigest digest = java.security.MessageDigest.getInstance ("MD5"); - digest.update (data); - - String key = bytesToHex (digest.digest()); - - if (dataCache.containsKey (key)) - return (File) dataCache.get (key); - - File f = new File (this.getCacheDir(), "bindata_" + key); - f.delete(); - FileOutputStream os = new FileOutputStream (f); - os.write (data, 0, data.length); - dataCache.put (key, f); - return f; - } - catch (Throwable e) {} - - return null; - } - - private final void clearDataCache() - { - java.util.Iterator it = dataCache.values().iterator(); - - while (it.hasNext()) - { - File f = (File) it.next(); - f.delete(); - } - } - - public final Typeface getTypeFaceFromByteArray (byte[] data) - { - try - { - File f = getDataCacheFile (data); - - if (f != null) - return Typeface.createFromFile (f); - } - catch (Exception e) - { - Log.e ("JUCE", e.toString()); - } - - return null; - } - - public static final int getAndroidSDKVersion() - { - return android.os.Build.VERSION.SDK_INT; - } - - public final String audioManagerGetProperty (String property) - { - Object obj = getSystemService (AUDIO_SERVICE); - if (obj == null) - return null; - - java.lang.reflect.Method method; - - try - { - method = obj.getClass().getMethod ("getProperty", String.class); - } - catch (SecurityException e) { return null; } - catch (NoSuchMethodException e) { return null; } - - if (method == null) - return null; - - try - { - return (String) method.invoke (obj, property); - } - catch (java.lang.IllegalArgumentException e) {} - catch (java.lang.IllegalAccessException e) {} - catch (java.lang.reflect.InvocationTargetException e) {} - - return null; - } - - public final boolean hasSystemFeature (String property) - { - return getPackageManager().hasSystemFeature (property); - } -} diff --git a/extras/AudioPerformanceTest/Builds/Android/app/src/main/java/com/juce/audioperformancetest/SharingContentProvider.java b/extras/AudioPerformanceTest/Builds/Android/app/src/main/java/com/juce/audioperformancetest/SharingContentProvider.java deleted file mode 100644 index 5b7d4d4a..00000000 --- a/extras/AudioPerformanceTest/Builds/Android/app/src/main/java/com/juce/audioperformancetest/SharingContentProvider.java +++ /dev/null @@ -1,138 +0,0 @@ -package com.juce.audioperformancetest; - -import android.content.ContentProvider; -import android.content.ContentValues; -import android.content.res.AssetFileDescriptor; -import android.content.res.Resources; -import android.database.Cursor; -import android.database.MatrixCursor; -import android.net.Uri; -import android.os.FileObserver; -import android.os.ParcelFileDescriptor; -import java.lang.String; - -public final class SharingContentProvider extends ContentProvider -{ - private Object lock = new Object(); - - private native void contentSharerFileObserverEvent (long host, int event, String path); - - private native Cursor contentSharerQuery (Uri uri, String[] projection, String selection, - String[] selectionArgs, String sortOrder); - - private native void contentSharerCursorClosed (long host); - - private native AssetFileDescriptor contentSharerOpenFile (Uri uri, String mode); - private native String[] contentSharerGetStreamTypes (Uri uri, String mimeTypeFilter); - - public final class ProviderFileObserver extends FileObserver - { - public ProviderFileObserver (long hostToUse, String path, int mask) - { - super (path, mask); - - host = hostToUse; - } - - public void onEvent (int event, String path) - { - contentSharerFileObserverEvent (host, event, path); - } - - private long host; - } - - public final class ProviderCursor extends MatrixCursor - { - ProviderCursor (long hostToUse, String[] columnNames) - { - super (columnNames); - - host = hostToUse; - } - - @Override - public void close() - { - super.close(); - - contentSharerCursorClosed (host); - } - - private long host; - } - - @Override - public boolean onCreate() - { - return true; - } - - @Override - public Cursor query (Uri url, String[] projection, String selection, - String[] selectionArgs, String sortOrder) - { - synchronized (lock) - { - return contentSharerQuery (url, projection, selection, selectionArgs, sortOrder); - } - } - - @Override - public Uri insert (Uri uri, ContentValues values) - { - return null; - } - - @Override - public int update (Uri uri, ContentValues values, String selection, - String[] selectionArgs) - { - return 0; - } - - @Override - public int delete (Uri uri, String selection, String[] selectionArgs) - { - return 0; - } - - @Override - public String getType (Uri uri) - { - return null; - } - - @Override - public AssetFileDescriptor openAssetFile (Uri uri, String mode) - { - synchronized (lock) - { - return contentSharerOpenFile (uri, mode); - } - } - - @Override - public ParcelFileDescriptor openFile (Uri uri, String mode) - { - synchronized (lock) - { - AssetFileDescriptor result = contentSharerOpenFile (uri, mode); - - if (result != null) - return result.getParcelFileDescriptor(); - - return null; - } - } - - @Override - public String[] getStreamTypes (Uri uri, String mimeTypeFilter) - { - synchronized (lock) - { - return contentSharerGetStreamTypes (uri, mimeTypeFilter); - } - } - -} diff --git a/extras/AudioPerformanceTest/Builds/Android/build.gradle b/extras/AudioPerformanceTest/Builds/Android/build.gradle index cfd3a2f8..0fe5b4aa 100644 --- a/extras/AudioPerformanceTest/Builds/Android/build.gradle +++ b/extras/AudioPerformanceTest/Builds/Android/build.gradle @@ -4,7 +4,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.5.3' + classpath 'com.android.tools.build:gradle:4.0.0' } } diff --git a/extras/AudioPerformanceTest/Builds/Android/gradle/wrapper/gradle-wrapper.properties b/extras/AudioPerformanceTest/Builds/Android/gradle/wrapper/gradle-wrapper.properties index b66802c7..49479605 100644 --- a/extras/AudioPerformanceTest/Builds/Android/gradle/wrapper/gradle-wrapper.properties +++ b/extras/AudioPerformanceTest/Builds/Android/gradle/wrapper/gradle-wrapper.properties @@ -1 +1 @@ -distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip \ No newline at end of file +distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip \ No newline at end of file diff --git a/extras/AudioPerformanceTest/Builds/LinuxMakefile/Makefile b/extras/AudioPerformanceTest/Builds/LinuxMakefile/Makefile index 6e877bd0..6815873c 100644 --- a/extras/AudioPerformanceTest/Builds/LinuxMakefile/Makefile +++ b/extras/AudioPerformanceTest/Builds/LinuxMakefile/Makefile @@ -35,13 +35,13 @@ ifeq ($(CONFIG),Debug) TARGET_ARCH := endif - JUCE_CPPFLAGS := $(DEPFLAGS) -DLINUX=1 -DDEBUG=1 -D_DEBUG=1 -DJUCER_LINUX_MAKE_6D53C8B4=1 -DJUCE_APP_VERSION=1.0.0 -DJUCE_APP_VERSION_HEX=0x10000 $(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_CPPFLAGS := $(DEPFLAGS) "-DLINUX=1" "-DDEBUG=1" "-D_DEBUG=1" "-DJUCE_DISPLAY_SPLASH_SCREEN=0" "-DJUCE_USE_DARK_SPLASH_SCREEN=1" "-DJUCE_PROJUCER_VERSION=0x60005" "-DJUCE_MODULE_AVAILABLE_juce_audio_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_devices=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_formats=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_processors=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_utils=1" "-DJUCE_MODULE_AVAILABLE_juce_core=1" "-DJUCE_MODULE_AVAILABLE_juce_data_structures=1" "-DJUCE_MODULE_AVAILABLE_juce_events=1" "-DJUCE_MODULE_AVAILABLE_juce_graphics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_extra=1" "-DJUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1" "-DJUCE_STANDALONE_APPLICATION=1" "-DJUCER_LINUX_MAKE_6D53C8B4=1" "-DJUCE_APP_VERSION=1.0.0" "-DJUCE_APP_VERSION_HEX=0x10000" $(shell pkg-config --cflags alsa freetype2 libcurl 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 := AudioPerformanceTest JUCE_CFLAGS += $(JUCE_CPPFLAGS) $(TARGET_ARCH) -g -ggdb -O0 $(CFLAGS) JUCE_CXXFLAGS += $(JUCE_CFLAGS) -std=c++14 $(CXXFLAGS) - JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) -L/usr/X11R6/lib/ $(shell pkg-config --libs alsa x11 xinerama xext freetype2 webkit2gtk-4.0 gtk+-x11-3.0 libcurl) -lrt -ldl -lpthread $(LDFLAGS) + JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) $(shell pkg-config --libs alsa freetype2 libcurl) -fvisibility=hidden -lrt -ldl -lpthread $(LDFLAGS) CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(TARGET) $(JUCE_OBJDIR) endif @@ -56,13 +56,13 @@ ifeq ($(CONFIG),Release) TARGET_ARCH := endif - JUCE_CPPFLAGS := $(DEPFLAGS) -DLINUX=1 -DNDEBUG=1 -DJUCER_LINUX_MAKE_6D53C8B4=1 -DJUCE_APP_VERSION=1.0.0 -DJUCE_APP_VERSION_HEX=0x10000 $(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_CPPFLAGS := $(DEPFLAGS) "-DLINUX=1" "-DNDEBUG=1" "-DJUCE_DISPLAY_SPLASH_SCREEN=0" "-DJUCE_USE_DARK_SPLASH_SCREEN=1" "-DJUCE_PROJUCER_VERSION=0x60005" "-DJUCE_MODULE_AVAILABLE_juce_audio_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_devices=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_formats=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_processors=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_utils=1" "-DJUCE_MODULE_AVAILABLE_juce_core=1" "-DJUCE_MODULE_AVAILABLE_juce_data_structures=1" "-DJUCE_MODULE_AVAILABLE_juce_events=1" "-DJUCE_MODULE_AVAILABLE_juce_graphics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_extra=1" "-DJUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1" "-DJUCE_STANDALONE_APPLICATION=1" "-DJUCER_LINUX_MAKE_6D53C8B4=1" "-DJUCE_APP_VERSION=1.0.0" "-DJUCE_APP_VERSION_HEX=0x10000" $(shell pkg-config --cflags alsa freetype2 libcurl 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 := AudioPerformanceTest JUCE_CFLAGS += $(JUCE_CPPFLAGS) $(TARGET_ARCH) -O3 $(CFLAGS) JUCE_CXXFLAGS += $(JUCE_CFLAGS) -std=c++14 $(CXXFLAGS) - JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) -L/usr/X11R6/lib/ $(shell pkg-config --libs alsa x11 xinerama xext freetype2 webkit2gtk-4.0 gtk+-x11-3.0 libcurl) -fvisibility=hidden -lrt -ldl -lpthread $(LDFLAGS) + JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) $(shell pkg-config --libs alsa freetype2 libcurl) -fvisibility=hidden -lrt -ldl -lpthread $(LDFLAGS) CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(TARGET) $(JUCE_OBJDIR) endif @@ -87,7 +87,7 @@ all : $(JUCE_OUTDIR)/$(JUCE_TARGET_APP) $(JUCE_OUTDIR)/$(JUCE_TARGET_APP) : $(OBJECTS_APP) $(RESOURCES) @command -v pkg-config >/dev/null 2>&1 || { echo >&2 "pkg-config not installed. Please, install it."; exit 1; } - @pkg-config --print-errors alsa x11 xinerama xext freetype2 webkit2gtk-4.0 gtk+-x11-3.0 libcurl + @pkg-config --print-errors alsa freetype2 libcurl @echo Linking "AudioPerformanceTest - App" -$(V_AT)mkdir -p $(JUCE_BINDIR) -$(V_AT)mkdir -p $(JUCE_LIBDIR) diff --git a/extras/AudioPerformanceTest/Builds/MacOSX/App.entitlements b/extras/AudioPerformanceTest/Builds/MacOSX/App.entitlements deleted file mode 100644 index 6631ffa6..00000000 --- a/extras/AudioPerformanceTest/Builds/MacOSX/App.entitlements +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> -</dict> -</plist> diff --git a/extras/AudioPerformanceTest/Builds/MacOSX/AudioPerformanceTest.xcodeproj/project.pbxproj b/extras/AudioPerformanceTest/Builds/MacOSX/AudioPerformanceTest.xcodeproj/project.pbxproj index 776ea1e1..eb7bf237 100644 --- a/extras/AudioPerformanceTest/Builds/MacOSX/AudioPerformanceTest.xcodeproj/project.pbxproj +++ b/extras/AudioPerformanceTest/Builds/MacOSX/AudioPerformanceTest.xcodeproj/project.pbxproj @@ -41,6 +41,10 @@ isa = PBXBuildFile; fileRef = EE758AD71415EB31BD3E82F3; }; + CC782AABFA20787BABBCED90 = { + isa = PBXBuildFile; + fileRef = E1BB9D521BF6C055F5B88628; + }; 9031C69145EE085B60904363 = { isa = PBXBuildFile; fileRef = 43775DC3D9F7917846EA5327; @@ -308,13 +312,6 @@ path = "../../../../modules/juce_audio_devices"; sourceTree = "SOURCE_ROOT"; }; - A65BB8D452A2A4859FA41F8B = { - isa = PBXFileReference; - lastKnownFileType = sourcecode.c.h; - name = AppConfig.h; - path = ../../JuceLibraryCode/AppConfig.h; - sourceTree = "SOURCE_ROOT"; - }; AD134CACB71BED6A22743C18 = { isa = PBXFileReference; lastKnownFileType = file; @@ -357,6 +354,13 @@ path = "../../../../modules/juce_audio_processors"; sourceTree = "SOURCE_ROOT"; }; + E1BB9D521BF6C055F5B88628 = { + isa = PBXFileReference; + lastKnownFileType = wrapper.framework; + name = Foundation.framework; + path = System/Library/Frameworks/Foundation.framework; + sourceTree = SDKROOT; + }; E575FE2AD2F19FA6AEB536C2 = { isa = PBXFileReference; lastKnownFileType = file; @@ -423,7 +427,6 @@ 0B8996A5E2671A4628476CFB = { isa = PBXGroup; children = ( - A65BB8D452A2A4859FA41F8B, 89B3243200BAA6BD72905DBB, 322D3066DCD98A8D0542236A, 9E05B63699A307598B66F829, @@ -460,6 +463,7 @@ 24D90B40648CC05A9B1AA55B, 12C680C68A15B9A590264B18, EE758AD71415EB31BD3E82F3, + E1BB9D521BF6C055F5B88628, 43775DC3D9F7917846EA5327, 0A58FDDF6FB9253F51939A52, 3058871156B921B9E5946C4F, @@ -503,6 +507,22 @@ GCC_PREPROCESSOR_DEFINITIONS = ( "_DEBUG=1", "DEBUG=1", + "JUCE_DISPLAY_SPLASH_SCREEN=0", + "JUCE_USE_DARK_SPLASH_SCREEN=1", + "JUCE_PROJUCER_VERSION=0x60005", + "JUCE_MODULE_AVAILABLE_juce_audio_basics=1", + "JUCE_MODULE_AVAILABLE_juce_audio_devices=1", + "JUCE_MODULE_AVAILABLE_juce_audio_formats=1", + "JUCE_MODULE_AVAILABLE_juce_audio_processors=1", + "JUCE_MODULE_AVAILABLE_juce_audio_utils=1", + "JUCE_MODULE_AVAILABLE_juce_core=1", + "JUCE_MODULE_AVAILABLE_juce_data_structures=1", + "JUCE_MODULE_AVAILABLE_juce_events=1", + "JUCE_MODULE_AVAILABLE_juce_graphics=1", + "JUCE_MODULE_AVAILABLE_juce_gui_basics=1", + "JUCE_MODULE_AVAILABLE_juce_gui_extra=1", + "JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1", + "JUCE_STANDALONE_APPLICATION=1", "JUCER_XCODE_MAC_F6D2F4CF=1", "JUCE_APP_VERSION=1.0.0", "JUCE_APP_VERSION_HEX=0x10000", @@ -525,9 +545,14 @@ INFOPLIST_PREPROCESS = NO; INSTALL_PATH = "$(HOME)/Applications"; MACOSX_DEPLOYMENT_TARGET = 10.11; + MTL_HEADER_SEARCH_PATHS = ( + "../../JuceLibraryCode", + "../../../../modules", + ); PRODUCT_BUNDLE_IDENTIFIER = com.juce.AudioPerformanceTest; PRODUCT_NAME = "AudioPerformanceTest"; USE_HEADERMAP = NO; + VALID_ARCHS = "i386 x86_64 arm64 arm64e"; }; name = Debug; }; @@ -546,6 +571,22 @@ GCC_PREPROCESSOR_DEFINITIONS = ( "_NDEBUG=1", "NDEBUG=1", + "JUCE_DISPLAY_SPLASH_SCREEN=0", + "JUCE_USE_DARK_SPLASH_SCREEN=1", + "JUCE_PROJUCER_VERSION=0x60005", + "JUCE_MODULE_AVAILABLE_juce_audio_basics=1", + "JUCE_MODULE_AVAILABLE_juce_audio_devices=1", + "JUCE_MODULE_AVAILABLE_juce_audio_formats=1", + "JUCE_MODULE_AVAILABLE_juce_audio_processors=1", + "JUCE_MODULE_AVAILABLE_juce_audio_utils=1", + "JUCE_MODULE_AVAILABLE_juce_core=1", + "JUCE_MODULE_AVAILABLE_juce_data_structures=1", + "JUCE_MODULE_AVAILABLE_juce_events=1", + "JUCE_MODULE_AVAILABLE_juce_graphics=1", + "JUCE_MODULE_AVAILABLE_juce_gui_basics=1", + "JUCE_MODULE_AVAILABLE_juce_gui_extra=1", + "JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1", + "JUCE_STANDALONE_APPLICATION=1", "JUCER_XCODE_MAC_F6D2F4CF=1", "JUCE_APP_VERSION=1.0.0", "JUCE_APP_VERSION_HEX=0x10000", @@ -558,7 +599,6 @@ "JucePlugin_Build_Standalone=0", "JucePlugin_Build_Unity=0", ); - GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; HEADER_SEARCH_PATHS = ( "../../JuceLibraryCode", @@ -570,9 +610,14 @@ INSTALL_PATH = "$(HOME)/Applications"; LLVM_LTO = YES; MACOSX_DEPLOYMENT_TARGET = 10.11; + MTL_HEADER_SEARCH_PATHS = ( + "../../JuceLibraryCode", + "../../../../modules", + ); PRODUCT_BUNDLE_IDENTIFIER = com.juce.AudioPerformanceTest; PRODUCT_NAME = "AudioPerformanceTest"; USE_HEADERMAP = NO; + VALID_ARCHS = "i386 x86_64 arm64 arm64e"; }; name = Release; }; @@ -601,11 +646,12 @@ CODE_SIGN_IDENTITY = ""; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; + ENABLE_TESTABILITY = NO; GCC_C_LANGUAGE_STANDARD = c11; GCC_INLINES_ARE_PRIVATE_EXTERN = YES; GCC_MODEL_TUNING = G5; GCC_NO_COMMON_BLOCKS = YES; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; @@ -649,10 +695,12 @@ CODE_SIGN_IDENTITY = ""; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = NO; GCC_C_LANGUAGE_STANDARD = c11; GCC_INLINES_ARE_PRIVATE_EXTERN = YES; GCC_MODEL_TUNING = G5; GCC_NO_COMMON_BLOCKS = YES; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; @@ -670,10 +718,6 @@ }; name = Release; }; - AA3837ADCB1CEB3B0E2D20B3 = { - isa = PBXTargetDependency; - target = E9FD2656EC625C9C8DE30219; - }; 7097CF6AC086DAC346ACCCD9 = { isa = XCConfigurationList; buildConfigurations = ( @@ -731,6 +775,7 @@ 71863EE98034AB7C3CBCAA81, 5923A711C0020F2CDD598714, 3825E8984D8F6AA00DDC6BAC, + CC782AABFA20787BABBCED90, 9031C69145EE085B60904363, F8099BB77DC0D01DCCC6AFB9, 537E779F6008999191B2920A, @@ -755,7 +800,7 @@ 9CE2A44801B5B4BE7A9667DA = { isa = PBXProject; buildConfigurationList = 7097CF6AC086DAC346ACCCD9; - attributes = { LastUpgradeCheck = 1100; ORGANIZATIONNAME = "ROLI Ltd."; TargetAttributes = { E9FD2656EC625C9C8DE30219 = { SystemCapabilities = {com.apple.ApplicationGroups.iOS = { enabled = 0; }; com.apple.InAppPurchase = { enabled = 0; }; com.apple.InterAppAudio = { enabled = 0; }; com.apple.Push = { enabled = 0; }; com.apple.Sandbox = { enabled = 0; }; com.apple.HardenedRuntime = { enabled = 0; }; }; }; }; }; + attributes = { LastUpgradeCheck = 1200; ORGANIZATIONNAME = "Raw Material Software Limited"; TargetAttributes = { E9FD2656EC625C9C8DE30219 = { SystemCapabilities = {com.apple.ApplicationGroups.iOS = { enabled = 0; }; com.apple.InAppPurchase = { enabled = 0; }; com.apple.InterAppAudio = { enabled = 0; }; com.apple.Push = { enabled = 0; }; com.apple.Sandbox = { enabled = 0; }; com.apple.HardenedRuntime = { enabled = 0; }; }; }; }; }; compatibilityVersion = "Xcode 3.2"; hasScannedForEncodings = 0; mainGroup = 3BA1BA0CAFE969E99950C06B; diff --git a/extras/AudioPerformanceTest/Builds/MacOSX/AudioPerformanceTest.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/extras/AudioPerformanceTest/Builds/MacOSX/AudioPerformanceTest.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings index 949b6789..f2e3cbe8 100644 --- a/extras/AudioPerformanceTest/Builds/MacOSX/AudioPerformanceTest.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ b/extras/AudioPerformanceTest/Builds/MacOSX/AudioPerformanceTest.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -4,5 +4,7 @@ <dict> <key>BuildSystemType</key> <string>Original</string> + <key>DisableBuildSystemDeprecationWarning</key> + <true/> </dict> </plist> diff --git a/extras/AudioPerformanceTest/Builds/MacOSX/Info-App.plist b/extras/AudioPerformanceTest/Builds/MacOSX/Info-App.plist index 53522f9b..c10bab44 100644 --- a/extras/AudioPerformanceTest/Builds/MacOSX/Info-App.plist +++ b/extras/AudioPerformanceTest/Builds/MacOSX/Info-App.plist @@ -22,7 +22,7 @@ <key>CFBundleVersion</key> <string>1.0.0</string> <key>NSHumanReadableCopyright</key> - <string>ROLI Ltd.</string> + <string>Raw Material Software Limited</string> <key>NSHighResolutionCapable</key> <true/> </dict> diff --git a/extras/AudioPerformanceTest/Builds/VisualStudio2019/AudioPerformanceTest_App.vcxproj b/extras/AudioPerformanceTest/Builds/VisualStudio2019/AudioPerformanceTest_App.vcxproj index 8531b492..fc08d1ab 100644 --- a/extras/AudioPerformanceTest/Builds/VisualStudio2019/AudioPerformanceTest_App.vcxproj +++ b/extras/AudioPerformanceTest/Builds/VisualStudio2019/AudioPerformanceTest_App.vcxproj @@ -64,10 +64,10 @@ <Optimization>Disabled</Optimization> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=1.0.0;JUCE_APP_VERSION_HEX=0x10000;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCE_DISPLAY_SPLASH_SCREEN=0;JUCE_USE_DARK_SPLASH_SCREEN=1;JUCE_PROJUCER_VERSION=0x60005;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_audio_formats=1;JUCE_MODULE_AVAILABLE_juce_audio_processors=1;JUCE_MODULE_AVAILABLE_juce_audio_utils=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_STANDALONE_APPLICATION=1;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=1.0.0;JUCE_APP_VERSION_HEX=0x10000;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> <RuntimeTypeInfo>true</RuntimeTypeInfo> - <PrecompiledHeader/> + <PrecompiledHeader>NotUsing</PrecompiledHeader> <AssemblerListingLocation>$(IntDir)\</AssemblerListingLocation> <ObjectFileName>$(IntDir)\</ObjectFileName> <ProgramDataBaseFileName>$(IntDir)\</ProgramDataBaseFileName> @@ -105,10 +105,10 @@ <ClCompile> <Optimization>Full</Optimization> <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=1.0.0;JUCE_APP_VERSION_HEX=0x10000;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCE_DISPLAY_SPLASH_SCREEN=0;JUCE_USE_DARK_SPLASH_SCREEN=1;JUCE_PROJUCER_VERSION=0x60005;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_audio_formats=1;JUCE_MODULE_AVAILABLE_juce_audio_processors=1;JUCE_MODULE_AVAILABLE_juce_audio_utils=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_STANDALONE_APPLICATION=1;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=1.0.0;JUCE_APP_VERSION_HEX=0x10000;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> <RuntimeTypeInfo>true</RuntimeTypeInfo> - <PrecompiledHeader/> + <PrecompiledHeader>NotUsing</PrecompiledHeader> <AssemblerListingLocation>$(IntDir)\</AssemblerListingLocation> <ObjectFileName>$(IntDir)\</ObjectFileName> <ProgramDataBaseFileName>$(IntDir)\</ProgramDataBaseFileName> @@ -130,6 +130,7 @@ <OptimizeReferences>true</OptimizeReferences> <EnableCOMDATFolding>true</EnableCOMDATFolding> <LargeAddressAware>true</LargeAddressAware> + <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> </Link> <Bscmake> <SuppressStartupBanner>true</SuppressStartupBanner> @@ -223,10 +224,10 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_basics\synthesisers\juce_Synthesiser.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_CatmullRomInterpolator.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Interpolators.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_LagrangeInterpolator.cpp"> @@ -235,6 +236,9 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_SmoothedValue.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_WindowedSincInterpolator.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_basics\juce_audio_basics.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -253,6 +257,153 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_devices\midi_io\juce_MidiMessageCollector.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AAudioLoader.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AudioStreamAAudio.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioSourceCaller.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioStream.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioStreamBuilder.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\DataConversionFlowGraph.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FilterAudioStream.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockAdapter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockReader.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockWriter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\LatencyTuner.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\QuirksManager.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceFloatCaller.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceI16Caller.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\StabilizedCallback.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Trace.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Utilities.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Version.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoBuffer.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoController.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerBase.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerIndirect.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\IntegerRatio.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\LinearResampler.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\MultiChannelResampler.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResampler.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerMono.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerStereo.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResampler.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResamplerStereo.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ClipToRange.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\FlowGraphNode.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ManyToMultiConverter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\MonoToMultiConverter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\RampLinear.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SampleRateConverter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkFloat.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI16.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI24.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceFloat.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI16.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI24.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioInputStreamOpenSLES.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioOutputStreamOpenSLES.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamBuffered.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamOpenSLES.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\EngineOpenSLES.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OpenSLESUtilities.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OutputMixerOpenSLES.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_android_Audio.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -352,70 +503,73 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\libFLAC\window_flac.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\analysis.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\analysis.c"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\bitrate.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\bitrate.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\block.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\block.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codebook.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codebook.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\envelope.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\envelope.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\floor0.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\floor0.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\floor1.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\floor1.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\info.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\info.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lpc.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lpc.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lsp.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lsp.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mapping0.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mapping0.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mdct.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mdct.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\misc.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\psy.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\psy.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\registry.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\registry.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\res0.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\res0.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\sharedbook.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\sharedbook.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\smallft.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\smallft.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\synthesis.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\synthesis.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\vorbisenc.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\vorbisenc.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\vorbisfile.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\vorbisfile.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\window.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\window.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\bitwise.c"> @@ -610,6 +764,9 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioProcessorValueTreeState.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_ParameterAttachments.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_RangedAudioParameter.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -712,6 +869,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_FileSearchPath.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -739,6 +899,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_MemoryBlock.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -1603,6 +1766,15 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_MouseListener.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_DragAndDrop.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_android_ContentSharer.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -1621,13 +1793,7 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_FileChooser.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.cpp"> - <ExcludedFromBuild>true</ExcludedFromBuild> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Clipboard.cpp"> - <ExcludedFromBuild>true</ExcludedFromBuild> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Windowing.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_Windowing.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_win32_DragAndDrop.cpp"> @@ -1831,6 +1997,9 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_ActiveXComponent.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_HWNDComponent.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_SystemTrayIcon.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -1888,10 +2057,10 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_basics\sources\juce_ToneGeneratorAudioSource.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\synthesisers\juce_Synthesiser.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_ADSR.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_CatmullRomInterpolator.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Decibels.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_GenericInterpolator.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_LagrangeInterpolator.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Interpolators.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Reverb.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_SmoothedValue.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\juce_audio_basics.h"/> @@ -1901,6 +2070,66 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_devices\audio_io\juce_SystemAudioVolume.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\midi_io\juce_MidiDevices.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\midi_io\juce_MidiMessageCollector.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStream.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamBase.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamBuilder.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamCallback.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Definitions.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\LatencyTuner.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Oboe.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\ResultWithValue.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\StabilizedCallback.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Utilities.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Version.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AAudioLoader.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AudioStreamAAudio.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioClock.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioSourceCaller.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\DataConversionFlowGraph.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FilterAudioStream.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockAdapter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockReader.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockWriter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\MonotonicCounter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\OboeDebug.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\QuirksManager.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceFloatCaller.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceI16Caller.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Trace.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoBuffer.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoController.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerBase.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerIndirect.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\HyperbolicCosineWindow.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\IntegerRatio.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\KaiserWindow.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\LinearResampler.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\MultiChannelResampler.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResampler.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerMono.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerStereo.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResampler.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResamplerStereo.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ClipToRange.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\FlowGraphNode.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ManyToMultiConverter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\MonoToMultiConverter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\RampLinear.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SampleRateConverter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkFloat.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI16.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI24.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceFloat.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI16.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI24.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioInputStreamOpenSLES.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioOutputStreamOpenSLES.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamBuffered.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamOpenSLES.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\EngineOpenSLES.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OpenSLESUtilities.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OutputMixerOpenSLES.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\juce_android_HighPerformanceAudioHelpers.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\juce_ios_Audio.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\juce_MidiDataConcatenator.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\sources\juce_AudioSourcePlayer.h"/> @@ -1938,50 +2167,51 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\stream_decoder.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\stream_encoder.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\win_utf8_io.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled\res_books_51.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled\res_books_stereo.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\floor\floor_books.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\uncoupled\res_books_uncoupled.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\floor_all.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_8.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_11.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_16.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_44.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_8.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_16.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44p51.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44u.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_8.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_11.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_16.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_22.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_32.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44p51.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44u.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_X.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\backends.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\bitrate.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codebook.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codec_internal.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\envelope.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\highlevel.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup_data.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lpc.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lsp.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\masking.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mdct.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\misc.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\os.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\psy.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\registry.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\scales.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\smallft.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\window.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled\res_books_51.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled\res_books_stereo.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\floor\floor_books.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\uncoupled\res_books_uncoupled.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\floor_all.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_8.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_11.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_16.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_44.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_8.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_16.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44p51.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44u.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_8.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_11.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_16.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_22.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_32.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44p51.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44u.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_X.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\backends.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\bitrate.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codebook.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codec_internal.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\envelope.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\highlevel.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup_data.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lpc.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lsp.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\masking.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mdct.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\misc.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\os.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\psy.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\registry.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\scales.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\smallft.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\window.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\codec.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\config_types.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\crctable.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\ogg.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\os_types.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\vorbisenc.h"/> @@ -2070,6 +2300,7 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst\vsteditcontroller.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst\vstparameters.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst\vstpresetfile.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_AU_Shared.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_AudioUnitPluginFormat.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LADSPAPluginFormat.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_VST3Common.h"/> @@ -2096,6 +2327,7 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioParameterInt.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioProcessorParameterWithID.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioProcessorValueTreeState.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_ParameterAttachments.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_RangedAudioParameter.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\juce_audio_processors.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_utils\audio_cd\juce_AudioCDBurner.h"/> @@ -2135,6 +2367,7 @@ <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_FileOutputStream.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_FileSearchPath.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_MemoryMappedFile.h"/> + <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_WildcardFileFilter.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\javascript\juce_Javascript.h"/> @@ -2148,6 +2381,7 @@ <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_Random.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_Range.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_StatisticsAccumulator.h"/> + <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_Atomic.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_ByteOrder.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_ContainerDeletePolicy.h"/> @@ -2190,6 +2424,7 @@ <ClInclude Include="..\..\..\..\modules\juce_core\streams\juce_SubregionStream.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\streams\juce_URLInputSource.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerSupport.h"/> + <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerWarnings.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_PlatformDefs.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_StandardHeader.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_SystemStats.h"/> @@ -2439,7 +2674,8 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_SelectedItemSet.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_TextDragAndDropTarget.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_TooltipClient.h"/> - <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.h"/> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.h"/> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_MultiTouchMapper.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\positioning\juce_MarkerList.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\positioning\juce_RelativeCoordinate.h"/> @@ -2491,6 +2727,7 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ActiveXControlComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"/> + <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_HWNDComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_NSViewComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ScopedDPIAwarenessDisabler.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_UIViewComponent.h"/> @@ -2509,11 +2746,13 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_mac_CarbonViewWrapperComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\juce_gui_extra.h"/> - <ClInclude Include="..\..\JuceLibraryCode\AppConfig.h"/> <ClInclude Include="..\..\JuceLibraryCode\JuceHeader.h"/> </ItemGroup> <ItemGroup> + <None Include="..\..\..\..\modules\juce_audio_devices\native\oboe\CMakeLists.txt"/> + <None Include="..\..\..\..\modules\juce_audio_devices\native\oboe\readme.md"/> <None Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\Flac Licence.txt"/> + <None Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\README.md"/> <None Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\Ogg Vorbis Licence.txt"/> <None Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\base\LICENSE.txt"/> <None Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\base\README.md"/> diff --git a/extras/AudioPerformanceTest/Builds/VisualStudio2019/AudioPerformanceTest_App.vcxproj.filters b/extras/AudioPerformanceTest/Builds/VisualStudio2019/AudioPerformanceTest_App.vcxproj.filters index 12212e51..19182a52 100644 --- a/extras/AudioPerformanceTest/Builds/VisualStudio2019/AudioPerformanceTest_App.vcxproj.filters +++ b/extras/AudioPerformanceTest/Builds/VisualStudio2019/AudioPerformanceTest_App.vcxproj.filters @@ -41,6 +41,36 @@ <Filter Include="JUCE Modules\juce_audio_devices\midi_io"> <UniqueIdentifier>{092EFC17-7C95-7E04-0ACA-0D61A462EE81}</UniqueIdentifier> </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\include\oboe"> + <UniqueIdentifier>{285118C6-8FDA-7DCE-BEF4-FFB2120876C5}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\include"> + <UniqueIdentifier>{69ED6B61-9B8D-D47E-E4A6-2E9F9A94A75A}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\aaudio"> + <UniqueIdentifier>{7CDB7CD1-BB96-F593-3C78-1E06182B5839}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\common"> + <UniqueIdentifier>{B0A708DE-B4CF-196B-14FB-DC8221509B8E}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\fifo"> + <UniqueIdentifier>{34F46ADE-EE31-227A-A69E-7732E70145F1}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler"> + <UniqueIdentifier>{BB9B3C77-17FB-E994-8B75-88F1727E4655}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph"> + <UniqueIdentifier>{C0971D77-2F14-190A-E2AE-89D6285F4D5A}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\opensles"> + <UniqueIdentifier>{AABEA333-6524-8891-51C7-6DAEB5700628}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src"> + <UniqueIdentifier>{F2D29337-983E-BAD7-7B5C-E0AB3D53D404}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe"> + <UniqueIdentifier>{C674B0FB-1FC0-2986-94B1-083845018994}</UniqueIdentifier> + </Filter> <Filter Include="JUCE Modules\juce_audio_devices\native"> <UniqueIdentifier>{0AFC1CE8-F6E6-9817-8C21-8432B2A375DA}</UniqueIdentifier> </Filter> @@ -65,26 +95,26 @@ <Filter Include="JUCE Modules\juce_audio_formats\codecs\flac"> <UniqueIdentifier>{9EB3EC7F-2AB7-DDAA-3C05-DF382B728D3F}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled"> - <UniqueIdentifier>{02D37B85-7DE2-C8E7-A274-A5A0FBE99D69}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled"> + <UniqueIdentifier>{6B9FBFDC-1D10-6246-356D-00FF4535CECB}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\floor"> - <UniqueIdentifier>{DAF3BAAF-5207-4C34-61B9-A97DDC930D50}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\floor"> + <UniqueIdentifier>{D6FCFC8E-7136-9109-78C0-91A3EB4C443F}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\uncoupled"> - <UniqueIdentifier>{C7885588-8436-4C21-DC1E-58879BF53BDC}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\uncoupled"> + <UniqueIdentifier>{EBF18AC1-F0ED-937A-2824-4307CE2ADAF7}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books"> - <UniqueIdentifier>{E4ECEA39-0EFF-2443-91B3-1E5DA7AD5AE4}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books"> + <UniqueIdentifier>{5A0F7922-2EFB-6465-57E4-A445B804EFB5}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes"> - <UniqueIdentifier>{210B8D25-68E0-32C3-1449-6A40F109C5E9}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes"> + <UniqueIdentifier>{4EC45416-0E7C-7567-6F75-D0C8CEE7DC4F}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib"> - <UniqueIdentifier>{378AD911-E8E4-D230-E76B-34542849509D}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib"> + <UniqueIdentifier>{C2985031-0496-55B5-41A8-BAB99E53D89D}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2"> - <UniqueIdentifier>{F6CED5B6-0A8C-56D2-C1AC-DED6BE774A13}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7"> + <UniqueIdentifier>{FB4AB426-7009-0036-BB75-E34256AA7C89}</UniqueIdentifier> </Filter> <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis"> <UniqueIdentifier>{E684D858-09E8-0251-8E86-5657129641E1}</UniqueIdentifier> @@ -344,6 +374,9 @@ <Filter Include="JUCE Modules\juce_gui_basics\mouse"> <UniqueIdentifier>{FE3CB19C-EF43-5CF5-DAF0-09D4E43D0AB9}</UniqueIdentifier> </Filter> + <Filter Include="JUCE Modules\juce_gui_basics\native\x11"> + <UniqueIdentifier>{FE7E6CD5-C7A0-DB20-4E7E-D6E7F08C4578}</UniqueIdentifier> + </Filter> <Filter Include="JUCE Modules\juce_gui_basics\native"> <UniqueIdentifier>{895C2D33-E08D-B1BA-BB36-FC4CA65090C8}</UniqueIdentifier> </Filter> @@ -475,10 +508,10 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_basics\synthesisers\juce_Synthesiser.cpp"> <Filter>JUCE Modules\juce_audio_basics\synthesisers</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_CatmullRomInterpolator.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.cpp"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Interpolators.cpp"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_LagrangeInterpolator.cpp"> @@ -487,6 +520,9 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_SmoothedValue.cpp"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_WindowedSincInterpolator.cpp"> + <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_basics\juce_audio_basics.cpp"> <Filter>JUCE Modules\juce_audio_basics</Filter> </ClCompile> @@ -508,6 +544,153 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_devices\midi_io\juce_MidiMessageCollector.cpp"> <Filter>JUCE Modules\juce_audio_devices\midi_io</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AAudioLoader.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\aaudio</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AudioStreamAAudio.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\aaudio</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioSourceCaller.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioStream.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioStreamBuilder.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\DataConversionFlowGraph.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FilterAudioStream.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockAdapter.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockReader.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockWriter.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\LatencyTuner.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\QuirksManager.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceFloatCaller.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceI16Caller.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\StabilizedCallback.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Trace.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Utilities.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Version.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoBuffer.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoController.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerBase.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerIndirect.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\IntegerRatio.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\LinearResampler.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\MultiChannelResampler.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResampler.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerMono.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerStereo.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResampler.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResamplerStereo.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ClipToRange.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\FlowGraphNode.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ManyToMultiConverter.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\MonoToMultiConverter.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\RampLinear.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SampleRateConverter.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkFloat.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI16.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI24.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceFloat.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI16.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI24.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioInputStreamOpenSLES.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioOutputStreamOpenSLES.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamBuffered.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamOpenSLES.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\EngineOpenSLES.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OpenSLESUtilities.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OutputMixerOpenSLES.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_android_Audio.cpp"> <Filter>JUCE Modules\juce_audio_devices\native</Filter> </ClCompile> @@ -610,71 +793,74 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\libFLAC\window_flac.c"> <Filter>JUCE Modules\juce_audio_formats\codecs\flac\libFLAC</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\analysis.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\analysis.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\bitrate.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\bitrate.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\block.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\block.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codebook.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codebook.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\envelope.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\envelope.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\floor0.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\floor0.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\floor1.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\floor1.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\info.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\info.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lpc.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lpc.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lsp.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lsp.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mapping0.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mapping0.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mdct.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mdct.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\misc.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\psy.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\psy.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\registry.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\registry.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\res0.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\res0.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\sharedbook.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\sharedbook.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\smallft.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\smallft.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\synthesis.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\synthesis.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\vorbisenc.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\vorbisenc.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\vorbisfile.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\vorbisfile.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\window.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\window.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\bitwise.c"> <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> @@ -874,6 +1060,9 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioProcessorValueTreeState.cpp"> <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_ParameterAttachments.cpp"> + <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_RangedAudioParameter.cpp"> <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> </ClCompile> @@ -994,6 +1183,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_FileSearchPath.cpp"> <Filter>JUCE Modules\juce_core\files</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.cpp"> + <Filter>JUCE Modules\juce_core\files</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.cpp"> <Filter>JUCE Modules\juce_core\files</Filter> </ClCompile> @@ -1021,6 +1213,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> <Filter>JUCE Modules\juce_core\maths</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.cpp"> + <Filter>JUCE Modules\juce_core\memory</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_MemoryBlock.cpp"> <Filter>JUCE Modules\juce_core\memory</Filter> </ClCompile> @@ -1924,6 +2119,15 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_MouseListener.cpp"> <Filter>JUCE Modules\juce_gui_basics\mouse</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_DragAndDrop.cpp"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.cpp"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.cpp"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_android_ContentSharer.cpp"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> </ClCompile> @@ -1951,13 +2155,7 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_FileChooser.cpp"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.cpp"> - <Filter>JUCE Modules\juce_gui_basics\native</Filter> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Clipboard.cpp"> - <Filter>JUCE Modules\juce_gui_basics\native</Filter> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Windowing.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_Windowing.cpp"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_mac_FileChooser.mm"> @@ -2191,6 +2389,9 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_ActiveXComponent.cpp"> <Filter>JUCE Modules\juce_gui_extra\native</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_HWNDComponent.cpp"> + <Filter>JUCE Modules\juce_gui_extra\native</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_SystemTrayIcon.cpp"> <Filter>JUCE Modules\juce_gui_extra\native</Filter> </ClCompile> @@ -2343,16 +2544,16 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_ADSR.h"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_CatmullRomInterpolator.h"> + <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Decibels.h"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Decibels.h"> + <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_GenericInterpolator.h"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.h"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_LagrangeInterpolator.h"> + <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Interpolators.h"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Reverb.h"> @@ -2382,6 +2583,186 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_devices\midi_io\juce_MidiMessageCollector.h"> <Filter>JUCE Modules\juce_audio_devices\midi_io</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStream.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamBase.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamBuilder.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamCallback.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Definitions.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\LatencyTuner.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Oboe.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\ResultWithValue.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\StabilizedCallback.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Utilities.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Version.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AAudioLoader.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\aaudio</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AudioStreamAAudio.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\aaudio</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioClock.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioSourceCaller.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\DataConversionFlowGraph.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FilterAudioStream.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockAdapter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockReader.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockWriter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\MonotonicCounter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\OboeDebug.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\QuirksManager.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceFloatCaller.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceI16Caller.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Trace.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoBuffer.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoController.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerBase.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerIndirect.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\HyperbolicCosineWindow.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\IntegerRatio.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\KaiserWindow.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\LinearResampler.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\MultiChannelResampler.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResampler.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerMono.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerStereo.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResampler.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResamplerStereo.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ClipToRange.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\FlowGraphNode.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ManyToMultiConverter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\MonoToMultiConverter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\RampLinear.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SampleRateConverter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkFloat.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI16.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI24.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceFloat.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI16.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI24.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioInputStreamOpenSLES.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioOutputStreamOpenSLES.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamBuffered.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamOpenSLES.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\EngineOpenSLES.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OpenSLESUtilities.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OutputMixerOpenSLES.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\juce_android_HighPerformanceAudioHelpers.h"> + <Filter>JUCE Modules\juce_audio_devices\native</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\juce_ios_Audio.h"> <Filter>JUCE Modules\juce_audio_devices\native</Filter> </ClInclude> @@ -2493,131 +2874,131 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\win_utf8_io.h"> <Filter>JUCE Modules\juce_audio_formats\codecs\flac</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled\res_books_51.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled\res_books_51.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled\res_books_stereo.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled\res_books_stereo.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\floor\floor_books.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\floor</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\floor\floor_books.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\floor</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\uncoupled\res_books_uncoupled.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\uncoupled</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\uncoupled\res_books_uncoupled.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\uncoupled</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\floor_all.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\floor_all.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_8.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_8.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_11.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_11.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_16.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_16.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_44.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_44.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_8.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_8.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_16.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_16.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44p51.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44p51.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44u.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44u.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_8.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_8.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_11.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_11.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_16.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_16.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_22.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_22.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_32.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_32.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44p51.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44p51.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44u.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44u.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_X.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_X.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\backends.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\backends.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\bitrate.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\bitrate.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codebook.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codebook.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codec_internal.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codec_internal.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\envelope.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\envelope.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\highlevel.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\highlevel.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup_data.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup_data.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lpc.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lpc.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lsp.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lsp.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\masking.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\masking.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mdct.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mdct.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\misc.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\misc.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\os.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\os.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\psy.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\psy.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\registry.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\registry.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\scales.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\scales.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\smallft.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\smallft.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\window.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\window.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\codec.h"> <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> @@ -2625,6 +3006,9 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\config_types.h"> <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\crctable.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\ogg.h"> <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> </ClInclude> @@ -2889,6 +3273,9 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst\vstpresetfile.h"> <Filter>JUCE Modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_AU_Shared.h"> + <Filter>JUCE Modules\juce_audio_processors\format_types</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_AudioUnitPluginFormat.h"> <Filter>JUCE Modules\juce_audio_processors\format_types</Filter> </ClInclude> @@ -2967,6 +3354,9 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioProcessorValueTreeState.h"> <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_ParameterAttachments.h"> + <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_RangedAudioParameter.h"> <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> </ClInclude> @@ -3084,6 +3474,9 @@ <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_MemoryMappedFile.h"> <Filter>JUCE Modules\juce_core\files</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.h"> + <Filter>JUCE Modules\juce_core\files</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.h"> <Filter>JUCE Modules\juce_core\files</Filter> </ClInclude> @@ -3123,6 +3516,9 @@ <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_StatisticsAccumulator.h"> <Filter>JUCE Modules\juce_core\maths</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.h"> + <Filter>JUCE Modules\juce_core\memory</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_Atomic.h"> <Filter>JUCE Modules\juce_core\memory</Filter> </ClInclude> @@ -3249,6 +3645,9 @@ <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerSupport.h"> <Filter>JUCE Modules\juce_core\system</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerWarnings.h"> + <Filter>JUCE Modules\juce_core\system</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_PlatformDefs.h"> <Filter>JUCE Modules\juce_core\system</Filter> </ClInclude> @@ -3996,8 +4395,11 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_TooltipClient.h"> <Filter>JUCE Modules\juce_gui_basics\mouse</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.h"> - <Filter>JUCE Modules\juce_gui_basics\native</Filter> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.h"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.h"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_MultiTouchMapper.h"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> @@ -4152,6 +4554,9 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"> <Filter>JUCE Modules\juce_gui_extra\embedding</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_HWNDComponent.h"> + <Filter>JUCE Modules\juce_gui_extra\embedding</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_NSViewComponent.h"> <Filter>JUCE Modules\juce_gui_extra\embedding</Filter> </ClInclude> @@ -4206,17 +4611,23 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_extra\juce_gui_extra.h"> <Filter>JUCE Modules\juce_gui_extra</Filter> </ClInclude> - <ClInclude Include="..\..\JuceLibraryCode\AppConfig.h"> - <Filter>JUCE Library Code</Filter> - </ClInclude> <ClInclude Include="..\..\JuceLibraryCode\JuceHeader.h"> <Filter>JUCE Library Code</Filter> </ClInclude> </ItemGroup> <ItemGroup> + <None Include="..\..\..\..\modules\juce_audio_devices\native\oboe\CMakeLists.txt"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe</Filter> + </None> + <None Include="..\..\..\..\modules\juce_audio_devices\native\oboe\readme.md"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe</Filter> + </None> <None Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\Flac Licence.txt"> <Filter>JUCE Modules\juce_audio_formats\codecs\flac</Filter> </None> + <None Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\README.md"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7</Filter> + </None> <None Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\Ogg Vorbis Licence.txt"> <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> </None> diff --git a/extras/AudioPerformanceTest/Builds/VisualStudio2019/resources.rc b/extras/AudioPerformanceTest/Builds/VisualStudio2019/resources.rc index 2dec1429..3509c791 100644 --- a/extras/AudioPerformanceTest/Builds/VisualStudio2019/resources.rc +++ b/extras/AudioPerformanceTest/Builds/VisualStudio2019/resources.rc @@ -1,3 +1,5 @@ +#pragma code_page(65001) + #ifdef JUCE_USER_DEFINED_RC_FILE #include JUCE_USER_DEFINED_RC_FILE #else @@ -13,8 +15,8 @@ BEGIN BEGIN BLOCK "040904E4" BEGIN - VALUE "CompanyName", "ROLI Ltd.\0" - VALUE "LegalCopyright", "ROLI Ltd.\0" + VALUE "CompanyName", "Raw Material Software Limited\0" + VALUE "LegalCopyright", "Raw Material Software Limited\0" VALUE "FileDescription", "AudioPerformanceTest\0" VALUE "FileVersion", "1.0.0\0" VALUE "ProductName", "AudioPerformanceTest\0" diff --git a/extras/AudioPerformanceTest/Builds/iOS/App.entitlements b/extras/AudioPerformanceTest/Builds/iOS/App.entitlements deleted file mode 100644 index 6631ffa6..00000000 --- a/extras/AudioPerformanceTest/Builds/iOS/App.entitlements +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> -</dict> -</plist> diff --git a/extras/AudioPerformanceTest/Builds/iOS/AudioPerformanceTest.xcodeproj/project.pbxproj b/extras/AudioPerformanceTest/Builds/iOS/AudioPerformanceTest.xcodeproj/project.pbxproj index 54933a53..59acc882 100644 --- a/extras/AudioPerformanceTest/Builds/iOS/AudioPerformanceTest.xcodeproj/project.pbxproj +++ b/extras/AudioPerformanceTest/Builds/iOS/AudioPerformanceTest.xcodeproj/project.pbxproj @@ -41,6 +41,10 @@ isa = PBXBuildFile; fileRef = 12C680C68A15B9A590264B18; }; + 06735FD618809C6823B18CFA = { + isa = PBXBuildFile; + fileRef = 5622D2E05ACA8C4395206C56; + }; F749F6DA494103257C9874CC = { isa = PBXBuildFile; fileRef = 6406C6755E61B1DC93071FF0; @@ -49,10 +53,6 @@ isa = PBXBuildFile; fileRef = E1BB9D521BF6C055F5B88628; }; - FA27764C3CB8C061B1B787CC = { - isa = PBXBuildFile; - fileRef = 418405DCE48C1B4926143469; - }; F8099BB77DC0D01DCCC6AFB9 = { isa = PBXBuildFile; fileRef = 0A58FDDF6FB9253F51939A52; @@ -61,6 +61,10 @@ isa = PBXBuildFile; fileRef = 60795BF638A7024B62C0DF09; }; + 537E779F6008999191B2920A = { + isa = PBXBuildFile; + fileRef = 3058871156B921B9E5946C4F; + }; A783F6E198806332E7FB9744 = { isa = PBXBuildFile; fileRef = 8693552B5FA53C2003A66302; @@ -194,6 +198,13 @@ path = ../../JuceLibraryCode/JuceHeader.h; sourceTree = "SOURCE_ROOT"; }; + 3058871156B921B9E5946C4F = { + isa = PBXFileReference; + lastKnownFileType = wrapper.framework; + name = WebKit.framework; + path = System/Library/Frameworks/WebKit.framework; + sourceTree = SDKROOT; + }; 322D3066DCD98A8D0542236A = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; @@ -201,13 +212,6 @@ path = "../../JuceLibraryCode/include_juce_audio_devices.mm"; sourceTree = "SOURCE_ROOT"; }; - 418405DCE48C1B4926143469 = { - isa = PBXFileReference; - lastKnownFileType = wrapper.framework; - name = MobileCoreServices.framework; - path = System/Library/Frameworks/MobileCoreServices.framework; - sourceTree = SDKROOT; - }; 429C7CD0E88FC64E9A72514D = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; @@ -222,6 +226,13 @@ path = "../../../../modules/juce_gui_basics"; sourceTree = "SOURCE_ROOT"; }; + 5622D2E05ACA8C4395206C56 = { + isa = PBXFileReference; + lastKnownFileType = wrapper.framework; + name = CoreServices.framework; + path = System/Library/Frameworks/CoreServices.framework; + sourceTree = SDKROOT; + }; 60795BF638A7024B62C0DF09 = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; @@ -327,13 +338,6 @@ path = "../../../../modules/juce_audio_devices"; sourceTree = "SOURCE_ROOT"; }; - A65BB8D452A2A4859FA41F8B = { - isa = PBXFileReference; - lastKnownFileType = sourcecode.c.h; - name = AppConfig.h; - path = ../../JuceLibraryCode/AppConfig.h; - sourceTree = "SOURCE_ROOT"; - }; AD134CACB71BED6A22743C18 = { isa = PBXFileReference; lastKnownFileType = file; @@ -456,7 +460,6 @@ 0B8996A5E2671A4628476CFB = { isa = PBXGroup; children = ( - A65BB8D452A2A4859FA41F8B, 89B3243200BAA6BD72905DBB, 322D3066DCD98A8D0542236A, 9E05B63699A307598B66F829, @@ -494,11 +497,12 @@ 6B887CEE009353C410AB4F63, F40C1815F7E7E4FBAF3A3091, 12C680C68A15B9A590264B18, + 5622D2E05ACA8C4395206C56, 6406C6755E61B1DC93071FF0, E1BB9D521BF6C055F5B88628, - 418405DCE48C1B4926143469, 0A58FDDF6FB9253F51939A52, 60795BF638A7024B62C0DF09, + 3058871156B921B9E5946C4F, ); name = Frameworks; sourceTree = "<group>"; @@ -540,6 +544,23 @@ GCC_PREPROCESSOR_DEFINITIONS = ( "_DEBUG=1", "DEBUG=1", + "JUCE_CONTENT_SHARING=1", + "JUCE_DISPLAY_SPLASH_SCREEN=0", + "JUCE_USE_DARK_SPLASH_SCREEN=1", + "JUCE_PROJUCER_VERSION=0x60005", + "JUCE_MODULE_AVAILABLE_juce_audio_basics=1", + "JUCE_MODULE_AVAILABLE_juce_audio_devices=1", + "JUCE_MODULE_AVAILABLE_juce_audio_formats=1", + "JUCE_MODULE_AVAILABLE_juce_audio_processors=1", + "JUCE_MODULE_AVAILABLE_juce_audio_utils=1", + "JUCE_MODULE_AVAILABLE_juce_core=1", + "JUCE_MODULE_AVAILABLE_juce_data_structures=1", + "JUCE_MODULE_AVAILABLE_juce_events=1", + "JUCE_MODULE_AVAILABLE_juce_graphics=1", + "JUCE_MODULE_AVAILABLE_juce_gui_basics=1", + "JUCE_MODULE_AVAILABLE_juce_gui_extra=1", + "JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1", + "JUCE_STANDALONE_APPLICATION=1", "JUCER_XCODE_IPHONE_5BC26AE3=1", "JUCE_APP_VERSION=1.0.0", "JUCE_APP_VERSION_HEX=0x10000", @@ -561,6 +582,10 @@ INFOPLIST_FILE = Info-App.plist; INFOPLIST_PREPROCESS = NO; INSTALL_PATH = "$(HOME)/Applications"; + MTL_HEADER_SEARCH_PATHS = ( + "../../JuceLibraryCode", + "../../../../modules", + ); PRODUCT_BUNDLE_IDENTIFIER = com.juce.AudioPerformanceTest; PRODUCT_NAME = "AudioPerformanceTest"; USE_HEADERMAP = NO; @@ -583,6 +608,23 @@ GCC_PREPROCESSOR_DEFINITIONS = ( "_NDEBUG=1", "NDEBUG=1", + "JUCE_CONTENT_SHARING=1", + "JUCE_DISPLAY_SPLASH_SCREEN=0", + "JUCE_USE_DARK_SPLASH_SCREEN=1", + "JUCE_PROJUCER_VERSION=0x60005", + "JUCE_MODULE_AVAILABLE_juce_audio_basics=1", + "JUCE_MODULE_AVAILABLE_juce_audio_devices=1", + "JUCE_MODULE_AVAILABLE_juce_audio_formats=1", + "JUCE_MODULE_AVAILABLE_juce_audio_processors=1", + "JUCE_MODULE_AVAILABLE_juce_audio_utils=1", + "JUCE_MODULE_AVAILABLE_juce_core=1", + "JUCE_MODULE_AVAILABLE_juce_data_structures=1", + "JUCE_MODULE_AVAILABLE_juce_events=1", + "JUCE_MODULE_AVAILABLE_juce_graphics=1", + "JUCE_MODULE_AVAILABLE_juce_gui_basics=1", + "JUCE_MODULE_AVAILABLE_juce_gui_extra=1", + "JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1", + "JUCE_STANDALONE_APPLICATION=1", "JUCER_XCODE_IPHONE_5BC26AE3=1", "JUCE_APP_VERSION=1.0.0", "JUCE_APP_VERSION_HEX=0x10000", @@ -595,7 +637,6 @@ "JucePlugin_Build_Standalone=0", "JucePlugin_Build_Unity=0", ); - GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; HEADER_SEARCH_PATHS = ( "../../JuceLibraryCode", @@ -606,6 +647,10 @@ INFOPLIST_PREPROCESS = NO; INSTALL_PATH = "$(HOME)/Applications"; LLVM_LTO = YES; + MTL_HEADER_SEARCH_PATHS = ( + "../../JuceLibraryCode", + "../../../../modules", + ); PRODUCT_BUNDLE_IDENTIFIER = com.juce.AudioPerformanceTest; PRODUCT_NAME = "AudioPerformanceTest"; USE_HEADERMAP = NO; @@ -637,11 +682,12 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; + ENABLE_TESTABILITY = NO; GCC_C_LANGUAGE_STANDARD = c11; GCC_INLINES_ARE_PRIVATE_EXTERN = YES; GCC_MODEL_TUNING = G5; GCC_NO_COMMON_BLOCKS = YES; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; @@ -687,10 +733,12 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = NO; GCC_C_LANGUAGE_STANDARD = c11; GCC_INLINES_ARE_PRIVATE_EXTERN = YES; GCC_MODEL_TUNING = G5; GCC_NO_COMMON_BLOCKS = YES; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; @@ -710,10 +758,6 @@ }; name = Release; }; - AA3837ADCB1CEB3B0E2D20B3 = { - isa = PBXTargetDependency; - target = E9FD2656EC625C9C8DE30219; - }; 7097CF6AC086DAC346ACCCD9 = { isa = XCConfigurationList; buildConfigurations = ( @@ -772,11 +816,12 @@ BF3ECEF0623C9B67C4CEAAF2, 893A86EF99F57B81286E58A1, 5923A711C0020F2CDD598714, + 06735FD618809C6823B18CFA, F749F6DA494103257C9874CC, CC782AABFA20787BABBCED90, - FA27764C3CB8C061B1B787CC, F8099BB77DC0D01DCCC6AFB9, AA0C9E035BB509F01A09310B, + 537E779F6008999191B2920A, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -798,7 +843,7 @@ 9CE2A44801B5B4BE7A9667DA = { isa = PBXProject; buildConfigurationList = 7097CF6AC086DAC346ACCCD9; - attributes = { LastUpgradeCheck = 1100; ORGANIZATIONNAME = "ROLI Ltd."; TargetAttributes = { E9FD2656EC625C9C8DE30219 = { SystemCapabilities = {com.apple.ApplicationGroups.iOS = { enabled = 0; }; com.apple.InAppPurchase = { enabled = 0; }; com.apple.InterAppAudio = { enabled = 0; }; com.apple.Push = { enabled = 0; }; com.apple.Sandbox = { enabled = 0; }; com.apple.HardenedRuntime = { enabled = 0; }; }; }; }; }; + attributes = { LastUpgradeCheck = 1200; ORGANIZATIONNAME = "Raw Material Software Limited"; TargetAttributes = { E9FD2656EC625C9C8DE30219 = { SystemCapabilities = {com.apple.ApplicationGroups.iOS = { enabled = 0; }; com.apple.InAppPurchase = { enabled = 0; }; com.apple.InterAppAudio = { enabled = 0; }; com.apple.Push = { enabled = 0; }; com.apple.Sandbox = { enabled = 0; }; com.apple.HardenedRuntime = { enabled = 0; }; }; }; }; }; compatibilityVersion = "Xcode 3.2"; hasScannedForEncodings = 0; mainGroup = 3BA1BA0CAFE969E99950C06B; diff --git a/extras/AudioPerformanceTest/Builds/iOS/AudioPerformanceTest.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/extras/AudioPerformanceTest/Builds/iOS/AudioPerformanceTest.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings index 949b6789..f2e3cbe8 100644 --- a/extras/AudioPerformanceTest/Builds/iOS/AudioPerformanceTest.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ b/extras/AudioPerformanceTest/Builds/iOS/AudioPerformanceTest.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -4,5 +4,7 @@ <dict> <key>BuildSystemType</key> <string>Original</string> + <key>DisableBuildSystemDeprecationWarning</key> + <true/> </dict> </plist> diff --git a/extras/AudioPerformanceTest/Builds/iOS/Info-App.plist b/extras/AudioPerformanceTest/Builds/iOS/Info-App.plist index 0834f3fb..a04e08ba 100644 --- a/extras/AudioPerformanceTest/Builds/iOS/Info-App.plist +++ b/extras/AudioPerformanceTest/Builds/iOS/Info-App.plist @@ -26,7 +26,7 @@ <key>CFBundleVersion</key> <string>1.0.0</string> <key>NSHumanReadableCopyright</key> - <string>ROLI Ltd.</string> + <string>Raw Material Software Limited</string> <key>NSHighResolutionCapable</key> <true/> <key>UIRequiresFullScreen</key> diff --git a/extras/AudioPerformanceTest/CMakeLists.txt b/extras/AudioPerformanceTest/CMakeLists.txt new file mode 100644 index 00000000..e575c295 --- /dev/null +++ b/extras/AudioPerformanceTest/CMakeLists.txt @@ -0,0 +1,38 @@ +# ============================================================================== +# +# This file is part of the JUCE library. +# Copyright (c) 2020 - Raw Material Software Limited +# +# JUCE is an open source library subject to commercial or open-source +# licensing. +# +# By using JUCE, you agree to the terms of both the JUCE 6 End-User License +# Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). +# +# End User License Agreement: www.juce.com/juce-6-licence +# Privacy Policy: www.juce.com/juce-privacy-policy +# +# Or: You may also use this code under the terms of the GPL v3 (see +# www.gnu.org/licenses). +# +# JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER +# EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE +# DISCLAIMED. +# +# ============================================================================== + +juce_add_gui_app(AudioPerformanceTest BUNDLE_ID com.juce.AudioPerformanceTest) + +juce_generate_juce_header(AudioPerformanceTest) + +target_sources(AudioPerformanceTest PRIVATE + Source/Main.cpp) + +target_compile_definitions(AudioPerformanceTest PRIVATE + JUCE_USE_CURL=0 JUCE_WEB_BROWSER=0) + +target_link_libraries(AudioPerformanceTest PRIVATE + juce::juce_audio_utils + juce::juce_recommended_config_flags + juce::juce_recommended_lto_flags + juce::juce_recommended_warning_flags) diff --git a/extras/AudioPerformanceTest/JuceLibraryCode/AppConfig.h b/extras/AudioPerformanceTest/JuceLibraryCode/AppConfig.h deleted file mode 100644 index 140961ca..00000000 --- a/extras/AudioPerformanceTest/JuceLibraryCode/AppConfig.h +++ /dev/null @@ -1,281 +0,0 @@ -/* - - IMPORTANT! This file is auto-generated each time you save your - project - if you alter its contents, your changes may be overwritten! - - There's a section below where you can add your own custom code safely, and the - Projucer will preserve the contents of that block, but the best way to change - any of these definitions is by using the Projucer's project settings. - - Any commented-out settings will assume their default values. - -*/ - -#pragma once - -//============================================================================== -// [BEGIN_USER_CODE_SECTION] - -// (You can add your own code in this section, and the Projucer will not overwrite it) - -// [END_USER_CODE_SECTION] - -/* - ============================================================================== - - In accordance with the terms of the JUCE 5 End-Use License Agreement, the - JUCE Code in SECTION A cannot be removed, changed or otherwise rendered - ineffective unless you have a JUCE Indie or Pro license, or are using JUCE - under the GPL v3 license. - - End User License Agreement: www.juce.com/juce-5-licence - - ============================================================================== -*/ - -// BEGIN SECTION A - -#ifndef JUCE_DISPLAY_SPLASH_SCREEN - #define JUCE_DISPLAY_SPLASH_SCREEN 0 -#endif - -#ifndef JUCE_REPORT_APP_USAGE - #define JUCE_REPORT_APP_USAGE 0 -#endif - -// END SECTION A - -#define JUCE_USE_DARK_SPLASH_SCREEN 1 - -#define JUCE_PROJUCER_VERSION 0x50407 - -//============================================================================== -#define JUCE_MODULE_AVAILABLE_juce_audio_basics 1 -#define JUCE_MODULE_AVAILABLE_juce_audio_devices 1 -#define JUCE_MODULE_AVAILABLE_juce_audio_formats 1 -#define JUCE_MODULE_AVAILABLE_juce_audio_processors 1 -#define JUCE_MODULE_AVAILABLE_juce_audio_utils 1 -#define JUCE_MODULE_AVAILABLE_juce_core 1 -#define JUCE_MODULE_AVAILABLE_juce_data_structures 1 -#define JUCE_MODULE_AVAILABLE_juce_events 1 -#define JUCE_MODULE_AVAILABLE_juce_graphics 1 -#define JUCE_MODULE_AVAILABLE_juce_gui_basics 1 -#define JUCE_MODULE_AVAILABLE_juce_gui_extra 1 - -#define JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED 1 - -//============================================================================== -// juce_audio_devices flags: - -#ifndef JUCE_USE_WINRT_MIDI - //#define JUCE_USE_WINRT_MIDI 0 -#endif - -#ifndef JUCE_ASIO - //#define JUCE_ASIO 0 -#endif - -#ifndef JUCE_WASAPI - //#define JUCE_WASAPI 1 -#endif - -#ifndef JUCE_WASAPI_EXCLUSIVE - //#define JUCE_WASAPI_EXCLUSIVE 0 -#endif - -#ifndef JUCE_DIRECTSOUND - //#define JUCE_DIRECTSOUND 1 -#endif - -#ifndef JUCE_ALSA - //#define JUCE_ALSA 1 -#endif - -#ifndef JUCE_JACK - //#define JUCE_JACK 0 -#endif - -#ifndef JUCE_BELA - //#define JUCE_BELA 0 -#endif - -#ifndef JUCE_USE_ANDROID_OBOE - //#define JUCE_USE_ANDROID_OBOE 0 -#endif - -#ifndef JUCE_USE_ANDROID_OPENSLES - //#define JUCE_USE_ANDROID_OPENSLES 0 -#endif - -#ifndef JUCE_DISABLE_AUDIO_MIXING_WITH_OTHER_APPS - //#define JUCE_DISABLE_AUDIO_MIXING_WITH_OTHER_APPS 0 -#endif - -//============================================================================== -// juce_audio_formats flags: - -#ifndef JUCE_USE_FLAC - //#define JUCE_USE_FLAC 1 -#endif - -#ifndef JUCE_USE_OGGVORBIS - //#define JUCE_USE_OGGVORBIS 1 -#endif - -#ifndef JUCE_USE_MP3AUDIOFORMAT - //#define JUCE_USE_MP3AUDIOFORMAT 0 -#endif - -#ifndef JUCE_USE_LAME_AUDIO_FORMAT - //#define JUCE_USE_LAME_AUDIO_FORMAT 0 -#endif - -#ifndef JUCE_USE_WINDOWS_MEDIA_FORMAT - //#define JUCE_USE_WINDOWS_MEDIA_FORMAT 1 -#endif - -//============================================================================== -// juce_audio_processors flags: - -#ifndef JUCE_PLUGINHOST_VST - //#define JUCE_PLUGINHOST_VST 0 -#endif - -#ifndef JUCE_PLUGINHOST_VST3 - //#define JUCE_PLUGINHOST_VST3 0 -#endif - -#ifndef JUCE_PLUGINHOST_AU - //#define JUCE_PLUGINHOST_AU 0 -#endif - -#ifndef JUCE_PLUGINHOST_LADSPA - //#define JUCE_PLUGINHOST_LADSPA 0 -#endif - -//============================================================================== -// juce_audio_utils flags: - -#ifndef JUCE_USE_CDREADER - //#define JUCE_USE_CDREADER 0 -#endif - -#ifndef JUCE_USE_CDBURNER - //#define JUCE_USE_CDBURNER 0 -#endif - -//============================================================================== -// juce_core flags: - -#ifndef JUCE_FORCE_DEBUG - //#define JUCE_FORCE_DEBUG 0 -#endif - -#ifndef JUCE_LOG_ASSERTIONS - //#define JUCE_LOG_ASSERTIONS 0 -#endif - -#ifndef JUCE_CHECK_MEMORY_LEAKS - //#define JUCE_CHECK_MEMORY_LEAKS 1 -#endif - -#ifndef JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES - //#define JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES 0 -#endif - -#ifndef JUCE_INCLUDE_ZLIB_CODE - //#define JUCE_INCLUDE_ZLIB_CODE 1 -#endif - -#ifndef JUCE_USE_CURL - //#define JUCE_USE_CURL 1 -#endif - -#ifndef JUCE_LOAD_CURL_SYMBOLS_LAZILY - //#define JUCE_LOAD_CURL_SYMBOLS_LAZILY 0 -#endif - -#ifndef JUCE_CATCH_UNHANDLED_EXCEPTIONS - //#define JUCE_CATCH_UNHANDLED_EXCEPTIONS 0 -#endif - -#ifndef JUCE_ALLOW_STATIC_NULL_VARIABLES - //#define JUCE_ALLOW_STATIC_NULL_VARIABLES 0 -#endif - -#ifndef JUCE_STRICT_REFCOUNTEDPOINTER - //#define JUCE_STRICT_REFCOUNTEDPOINTER 0 -#endif - -//============================================================================== -// juce_events flags: - -#ifndef JUCE_EXECUTE_APP_SUSPEND_ON_BACKGROUND_TASK - //#define JUCE_EXECUTE_APP_SUSPEND_ON_BACKGROUND_TASK 0 -#endif - -//============================================================================== -// juce_graphics flags: - -#ifndef JUCE_USE_COREIMAGE_LOADER - //#define JUCE_USE_COREIMAGE_LOADER 1 -#endif - -#ifndef JUCE_USE_DIRECTWRITE - //#define JUCE_USE_DIRECTWRITE 1 -#endif - -#ifndef JUCE_DISABLE_COREGRAPHICS_FONT_SMOOTHING - //#define JUCE_DISABLE_COREGRAPHICS_FONT_SMOOTHING 0 -#endif - -//============================================================================== -// juce_gui_basics flags: - -#ifndef JUCE_ENABLE_REPAINT_DEBUGGING - //#define JUCE_ENABLE_REPAINT_DEBUGGING 0 -#endif - -#ifndef JUCE_USE_XRANDR - //#define JUCE_USE_XRANDR 1 -#endif - -#ifndef JUCE_USE_XINERAMA - //#define JUCE_USE_XINERAMA 1 -#endif - -#ifndef JUCE_USE_XSHM - //#define JUCE_USE_XSHM 1 -#endif - -#ifndef JUCE_USE_XRENDER - //#define JUCE_USE_XRENDER 0 -#endif - -#ifndef JUCE_USE_XCURSOR - //#define JUCE_USE_XCURSOR 1 -#endif - -#ifndef JUCE_WIN_PER_MONITOR_DPI_AWARE - //#define JUCE_WIN_PER_MONITOR_DPI_AWARE 1 -#endif - -//============================================================================== -// juce_gui_extra flags: - -#ifndef JUCE_WEB_BROWSER - //#define JUCE_WEB_BROWSER 1 -#endif - -#ifndef JUCE_ENABLE_LIVE_CONSTANT_EDITOR - //#define JUCE_ENABLE_LIVE_CONSTANT_EDITOR 0 -#endif - -//============================================================================== -#ifndef JUCE_STANDALONE_APPLICATION - #if defined(JucePlugin_Name) && defined(JucePlugin_Build_Standalone) - #define JUCE_STANDALONE_APPLICATION JucePlugin_Build_Standalone - #else - #define JUCE_STANDALONE_APPLICATION 1 - #endif -#endif diff --git a/extras/AudioPerformanceTest/JuceLibraryCode/JuceHeader.h b/extras/AudioPerformanceTest/JuceLibraryCode/JuceHeader.h index 1368bac8..82a4fc48 100644 --- a/extras/AudioPerformanceTest/JuceLibraryCode/JuceHeader.h +++ b/extras/AudioPerformanceTest/JuceLibraryCode/JuceHeader.h @@ -12,7 +12,6 @@ #pragma once -#include "AppConfig.h" #include <juce_audio_basics/juce_audio_basics.h> #include <juce_audio_devices/juce_audio_devices.h> @@ -46,7 +45,7 @@ namespace ProjectInfo { const char* const projectName = "AudioPerformanceTest"; - const char* const companyName = "ROLI Ltd."; + const char* const companyName = "Raw Material Software Limited"; const char* const versionString = "1.0.0"; const int versionNumber = 0x10000; } diff --git a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_audio_basics.cpp b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_audio_basics.cpp index 41869487..e5c3ae92 100644 --- a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_audio_basics.cpp +++ b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_audio_basics.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_basics/juce_audio_basics.cpp> diff --git a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_audio_basics.mm b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_audio_basics.mm index e0e6c577..c7f36c64 100644 --- a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_audio_basics.mm +++ b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_audio_basics.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_basics/juce_audio_basics.mm> diff --git a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_audio_devices.cpp b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_audio_devices.cpp index fb5c2219..29b774fd 100644 --- a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_audio_devices.cpp +++ b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_audio_devices.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_devices/juce_audio_devices.cpp> diff --git a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_audio_devices.mm b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_audio_devices.mm index e58b67ea..287da26e 100644 --- a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_audio_devices.mm +++ b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_audio_devices.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_devices/juce_audio_devices.mm> diff --git a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_audio_formats.cpp b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_audio_formats.cpp index a3c61170..8dac3325 100644 --- a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_audio_formats.cpp +++ b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_audio_formats.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_formats/juce_audio_formats.cpp> diff --git a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_audio_formats.mm b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_audio_formats.mm index f325b8fb..79e6a22f 100644 --- a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_audio_formats.mm +++ b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_audio_formats.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_formats/juce_audio_formats.mm> diff --git a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_audio_processors.cpp b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_audio_processors.cpp index bfe172ed..217d330a 100644 --- a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_audio_processors.cpp +++ b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_audio_processors.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_processors/juce_audio_processors.cpp> diff --git a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_audio_processors.mm b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_audio_processors.mm index b80ae901..1f7cc419 100644 --- a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_audio_processors.mm +++ b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_audio_processors.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_processors/juce_audio_processors.mm> diff --git a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_audio_utils.cpp b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_audio_utils.cpp index 97bd2c56..046bf31d 100644 --- a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_audio_utils.cpp +++ b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_audio_utils.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_utils/juce_audio_utils.cpp> diff --git a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_audio_utils.mm b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_audio_utils.mm index 8eae7c6e..a3f746dc 100644 --- a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_audio_utils.mm +++ b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_audio_utils.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_utils/juce_audio_utils.mm> diff --git a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_core.cpp b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_core.cpp index d0ce1636..84fe988c 100644 --- a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_core.cpp +++ b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_core.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_core/juce_core.cpp> diff --git a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_core.mm b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_core.mm index 72b10bf8..9ee67bf6 100644 --- a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_core.mm +++ b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_core.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_core/juce_core.mm> diff --git a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_data_structures.cpp b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_data_structures.cpp index 9315aa16..152980ae 100644 --- a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_data_structures.cpp +++ b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_data_structures.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_data_structures/juce_data_structures.cpp> diff --git a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_data_structures.mm b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_data_structures.mm index 695ec439..02b9711c 100644 --- a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_data_structures.mm +++ b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_data_structures.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_data_structures/juce_data_structures.mm> diff --git a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_events.cpp b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_events.cpp index 1bba110a..39268e2b 100644 --- a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_events.cpp +++ b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_events.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_events/juce_events.cpp> diff --git a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_events.mm b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_events.mm index 4cc34fc4..191a9987 100644 --- a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_events.mm +++ b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_events.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_events/juce_events.mm> diff --git a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_graphics.cpp b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_graphics.cpp index 319c76de..8ccabef9 100644 --- a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_graphics.cpp +++ b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_graphics.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_graphics/juce_graphics.cpp> diff --git a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_graphics.mm b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_graphics.mm index b28e6dd0..6bb7456d 100644 --- a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_graphics.mm +++ b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_graphics.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_graphics/juce_graphics.mm> diff --git a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_gui_basics.cpp b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_gui_basics.cpp index 216c76bb..71d04b24 100644 --- a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_gui_basics.cpp +++ b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_gui_basics.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_gui_basics/juce_gui_basics.cpp> diff --git a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_gui_basics.mm b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_gui_basics.mm index 6a9726fa..e449e0b7 100644 --- a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_gui_basics.mm +++ b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_gui_basics.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_gui_basics/juce_gui_basics.mm> diff --git a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_gui_extra.cpp b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_gui_extra.cpp index 7226e198..a33ece00 100644 --- a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_gui_extra.cpp +++ b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_gui_extra.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_gui_extra/juce_gui_extra.cpp> diff --git a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_gui_extra.mm b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_gui_extra.mm index c9b6c3bf..6dacee3a 100644 --- a/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_gui_extra.mm +++ b/extras/AudioPerformanceTest/JuceLibraryCode/include_juce_gui_extra.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_gui_extra/juce_gui_extra.mm> diff --git a/extras/AudioPerformanceTest/Source/Main.cpp b/extras/AudioPerformanceTest/Source/Main.cpp index 76c3337f..b99329a1 100644 --- a/extras/AudioPerformanceTest/Source/Main.cpp +++ b/extras/AudioPerformanceTest/Source/Main.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -27,8 +26,6 @@ #include <JuceHeader.h> #include "MainComponent.h" -Component* createMainContentComponent(); - //============================================================================== class AudioPerformanceTestApplication : public JUCEApplication { @@ -61,9 +58,8 @@ public: class MainWindow : public DocumentWindow { public: - MainWindow (String name) : DocumentWindow (name, - Colours::lightgrey, - DocumentWindow::allButtons) + explicit MainWindow (String name) + : DocumentWindow (name, Colours::lightgrey, DocumentWindow::allButtons) { setUsingNativeTitleBar (true); setContentOwned (createMainContentComponent(), true); diff --git a/extras/AudioPerformanceTest/Source/MainComponent.h b/extras/AudioPerformanceTest/Source/MainComponent.h index 73dc3a18..542ccab6 100644 --- a/extras/AudioPerformanceTest/Source/MainComponent.h +++ b/extras/AudioPerformanceTest/Source/MainComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -45,7 +44,7 @@ public: startTimer (1000); } - ~MainContentComponent() + ~MainContentComponent() override { shutdownAudio(); } @@ -54,7 +53,7 @@ public: void prepareToPlay (int bufferSize, double sampleRate) override { currentSampleRate = sampleRate; - allocateBuffers (bufferSize); + allocateBuffers (static_cast<size_t> (bufferSize)); printHeader(); } @@ -246,13 +245,13 @@ private: //============================================================================== static double getPreciseTimeMs() noexcept { - return 1000.0 * Time::getHighResolutionTicks() / (double) Time::getHighResolutionTicksPerSecond(); + return 1000.0 * (double) Time::getHighResolutionTicks() / (double) Time::getHighResolutionTicksPerSecond(); } //============================================================================== double getPhysicalTimeLimitMs() const noexcept { - return 1000.0 * a.size() / currentSampleRate; + return 1000.0 * (double) a.size() / currentSampleRate; } //============================================================================== diff --git a/extras/AudioPluginHost/AudioPluginHost.jucer b/extras/AudioPluginHost/AudioPluginHost.jucer index 523a5805..d46374c5 100644 --- a/extras/AudioPluginHost/AudioPluginHost.jucer +++ b/extras/AudioPluginHost/AudioPluginHost.jucer @@ -1,19 +1,21 @@ <?xml version="1.0" encoding="UTF-8"?> <JUCERPROJECT id="NTe0XB0ij" name="AudioPluginHost" projectType="guiapp" version="1.0.0" - juceFolder="../../../juce" bundleIdentifier="com.roli.juce.pluginhost" - jucerVersion="5.4.7" companyName="ROLI Ltd." displaySplashScreen="0" - reportAppUsage="0" companyCopyright="ROLI Ltd."> + juceFolder="../../../juce" bundleIdentifier="com.juce.pluginhost" + companyName="Raw Material Software Limited" displaySplashScreen="0" + reportAppUsage="0" companyCopyright="Raw Material Software Limited" + useAppConfig="0" addUsingNamespaceToJuceHeader="1" jucerFormatVersion="1"> <EXPORTFORMATS> <XCODE_MAC targetFolder="Builds/MacOSX" rtasFolder="~/SDKs/PT_80_SDK" objCExtraSuffix="M73TRi" - smallIcon="c97aUr" bigIcon="c97aUr" microphonePermissionNeeded="1"> + smallIcon="c97aUr" bigIcon="c97aUr" microphonePermissionNeeded="1" + sendAppleEventsPermissionNeeded="1" sendAppleEventsPermissionText="This is required for some third-party plug-ins to function correctly." + customXcodeResourceFolders="../../examples/Assets"> <CONFIGURATIONS> <CONFIGURATION name="Debug" isDebug="1" targetName="AudioPluginHost" recommendedWarnings="LLVM"/> <CONFIGURATION name="Release" isDebug="0" optimisation="2" targetName="AudioPluginHost" recommendedWarnings="LLVM"/> </CONFIGURATIONS> <MODULEPATHS> - <MODULEPATH id="juce_video" path="../../modules"/> <MODULEPATH id="juce_opengl" path="../../modules"/> <MODULEPATH id="juce_gui_extra" path="../../modules"/> <MODULEPATH id="juce_gui_basics" path="../../modules"/> @@ -27,16 +29,15 @@ <MODULEPATH id="juce_audio_formats" path="../../modules"/> <MODULEPATH id="juce_audio_devices" path="../../modules"/> <MODULEPATH id="juce_audio_basics" path="../../modules"/> + <MODULEPATH id="juce_dsp" path="../../modules"/> </MODULEPATHS> </XCODE_MAC> <LINUX_MAKE targetFolder="Builds/LinuxMakefile" smallIcon="c97aUr" bigIcon="c97aUr"> <CONFIGURATIONS> - <CONFIGURATION name="Debug" isDebug="1" targetName="AudioPluginHost" libraryPath="/usr/X11R6/lib/"/> - <CONFIGURATION name="Release" isDebug="0" optimisation="2" targetName="AudioPluginHost" - libraryPath="/usr/X11R6/lib/"/> + <CONFIGURATION name="Debug" isDebug="1" targetName="AudioPluginHost"/> + <CONFIGURATION name="Release" isDebug="0" optimisation="2" targetName="AudioPluginHost"/> </CONFIGURATIONS> <MODULEPATHS> - <MODULEPATH id="juce_video" path="../../modules"/> <MODULEPATH id="juce_opengl" path="../../modules"/> <MODULEPATH id="juce_gui_extra" path="../../modules"/> <MODULEPATH id="juce_gui_basics" path="../../modules"/> @@ -50,6 +51,7 @@ <MODULEPATH id="juce_audio_formats" path="../../modules"/> <MODULEPATH id="juce_audio_devices" path="../../modules"/> <MODULEPATH id="juce_audio_basics" path="../../modules"/> + <MODULEPATH id="juce_dsp" path="../../modules"/> </MODULEPATHS> </LINUX_MAKE> <VS2015 targetFolder="Builds/VisualStudio2015" smallIcon="c97aUr" bigIcon="c97aUr" @@ -59,7 +61,6 @@ <CONFIGURATION name="Release" isDebug="0" targetName="AudioPluginHost" debugInformationFormat="ProgramDatabase"/> </CONFIGURATIONS> <MODULEPATHS> - <MODULEPATH id="juce_video" path="../../modules"/> <MODULEPATH id="juce_opengl" path="../../modules"/> <MODULEPATH id="juce_gui_extra" path="../../modules"/> <MODULEPATH id="juce_gui_basics" path="../../modules"/> @@ -73,6 +74,7 @@ <MODULEPATH id="juce_audio_formats" path="../../modules"/> <MODULEPATH id="juce_audio_devices" path="../../modules"/> <MODULEPATH id="juce_audio_basics" path="../../modules"/> + <MODULEPATH id="juce_dsp" path="../../modules"/> </MODULEPATHS> </VS2015> <VS2017 targetFolder="Builds/VisualStudio2017" smallIcon="c97aUr" bigIcon="c97aUr" @@ -82,7 +84,6 @@ <CONFIGURATION name="Release" isDebug="0" targetName="AudioPluginHost" debugInformationFormat="ProgramDatabase"/> </CONFIGURATIONS> <MODULEPATHS> - <MODULEPATH id="juce_video" path="../../modules"/> <MODULEPATH id="juce_opengl" path="../../modules"/> <MODULEPATH id="juce_gui_extra" path="../../modules"/> <MODULEPATH id="juce_gui_basics" path="../../modules"/> @@ -96,6 +97,7 @@ <MODULEPATH id="juce_audio_formats" path="../../modules"/> <MODULEPATH id="juce_audio_devices" path="../../modules"/> <MODULEPATH id="juce_audio_basics" path="../../modules"/> + <MODULEPATH id="juce_dsp" path="../../modules"/> </MODULEPATHS> </VS2017> <VS2019 targetFolder="Builds/VisualStudio2019" smallIcon="c97aUr" bigIcon="c97aUr" @@ -105,7 +107,6 @@ <CONFIGURATION name="Release" isDebug="0" targetName="AudioPluginHost" debugInformationFormat="ProgramDatabase"/> </CONFIGURATIONS> <MODULEPATHS> - <MODULEPATH id="juce_video" path="../../modules"/> <MODULEPATH id="juce_opengl" path="../../modules"/> <MODULEPATH id="juce_gui_extra" path="../../modules"/> <MODULEPATH id="juce_gui_basics" path="../../modules"/> @@ -119,12 +120,12 @@ <MODULEPATH id="juce_audio_formats" path="../../modules"/> <MODULEPATH id="juce_audio_devices" path="../../modules"/> <MODULEPATH id="juce_audio_basics" path="../../modules"/> + <MODULEPATH id="juce_dsp" path="../../modules"/> </MODULEPATHS> </VS2019> - <XCODE_IPHONE targetFolder="Builds/iOS" iosScreenOrientation="portraitlandscape" - iPadScreenOrientation="portraitlandscape" iosDeviceFamily="1,2" - microphonePermissionNeeded="1" iosBackgroundAudio="1" iosBackgroundBle="1" - smallIcon="c97aUr" bigIcon="c97aUr"> + <XCODE_IPHONE targetFolder="Builds/iOS" iosScreenOrientation="" iPadScreenOrientation="" + iosDeviceFamily="1,2" microphonePermissionNeeded="1" iosBackgroundAudio="1" + iosBackgroundBle="1" smallIcon="c97aUr" bigIcon="c97aUr" customXcodeResourceFolders="../../examples/Assets"> <CONFIGURATIONS> <CONFIGURATION name="Debug" enablePluginBinaryCopyStep="1" isDebug="1" optimisation="1" linkTimeOptimisation="0" targetName="Plugin Host" recommendedWarnings="LLVM"/> @@ -132,7 +133,6 @@ linkTimeOptimisation="1" targetName="Plugin Host" recommendedWarnings="LLVM"/> </CONFIGURATIONS> <MODULEPATHS> - <MODULEPATH id="juce_video" path="../../modules"/> <MODULEPATH id="juce_opengl" path="../../modules"/> <MODULEPATH id="juce_gui_extra" path="../../modules"/> <MODULEPATH id="juce_gui_basics" path="../../modules"/> @@ -146,6 +146,7 @@ <MODULEPATH id="juce_audio_formats" path="../../modules"/> <MODULEPATH id="juce_audio_devices" path="../../modules"/> <MODULEPATH id="juce_audio_basics" path="../../modules"/> + <MODULEPATH id="juce_dsp" path="../../modules"/> </MODULEPATHS> </XCODE_IPHONE> <ANDROIDSTUDIO targetFolder="Builds/Android" androidMinimumSDK="23" androidInternetNeeded="1" @@ -159,7 +160,6 @@ targetName="Plugin Host" recommendedWarnings="LLVM"/> </CONFIGURATIONS> <MODULEPATHS> - <MODULEPATH id="juce_video" path="../../modules"/> <MODULEPATH id="juce_opengl" path="../../modules"/> <MODULEPATH id="juce_gui_extra" path="../../modules"/> <MODULEPATH id="juce_gui_basics" path="../../modules"/> @@ -173,6 +173,7 @@ <MODULEPATH id="juce_audio_formats" path="../../modules"/> <MODULEPATH id="juce_audio_devices" path="../../modules"/> <MODULEPATH id="juce_audio_basics" path="../../modules"/> + <MODULEPATH id="juce_dsp" path="../../modules"/> </MODULEPATHS> </ANDROIDSTUDIO> </EXPORTFORMATS> @@ -206,7 +207,7 @@ </GROUP> </MAINGROUP> <JUCEOPTIONS JUCE_WASAPI="1" JUCE_DIRECTSOUND="1" JUCE_ALSA="1" JUCE_USE_FLAC="0" - JUCE_USE_OGGVORBIS="0" JUCE_USE_CDBURNER="0" JUCE_USE_CDREADER="0" + JUCE_USE_OGGVORBIS="1" JUCE_USE_CDBURNER="0" JUCE_USE_CDREADER="0" JUCE_USE_CAMERA="0" JUCE_PLUGINHOST_AU="1" JUCE_WEB_BROWSER="0" JUCE_PLUGINHOST_VST3="1" JUCE_PLUGINHOST_LADSPA="1"/> <MODULES> @@ -218,12 +219,12 @@ <MODULE id="juce_core" showAllCode="1"/> <MODULE id="juce_cryptography" showAllCode="1"/> <MODULE id="juce_data_structures" showAllCode="1"/> + <MODULE id="juce_dsp" showAllCode="1"/> <MODULE id="juce_events" showAllCode="1"/> <MODULE id="juce_graphics" showAllCode="1"/> <MODULE id="juce_gui_basics" showAllCode="1"/> <MODULE id="juce_gui_extra" showAllCode="1"/> <MODULE id="juce_opengl" showAllCode="1"/> - <MODULE id="juce_video" showAllCode="1"/> </MODULES> <LIVE_SETTINGS> <OSX/> diff --git a/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt b/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt index eded0ed7..5811c3db 100644 --- a/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt +++ b/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt @@ -3,12 +3,16 @@ cmake_minimum_required(VERSION 3.4.1) -SET(BINARY_NAME "juce_jni") +set(BINARY_NAME "juce_jni") + +set(OBOE_DIR "../../../../../modules/juce_audio_devices/native/oboe") + +add_subdirectory (${OBOE_DIR} ./oboe) 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" "-DJUCER_ANDROIDSTUDIO_7F0E4A25=1" "-DJUCE_APP_VERSION=1.0.0" "-DJUCE_APP_VERSION_HEX=0x10000") +add_definitions("-DJUCE_ANDROID=1" "-DJUCE_ANDROID_API_VERSION=23" "-DJUCE_PUSH_NOTIFICATIONS=1" "-DJUCE_PUSH_NOTIFICATIONS_ACTIVITY=\"com/rmsl/juce/JuceActivity\"" "-DJUCE_ANDROID_GL_ES_VERSION_3_0=1" "-DJUCER_ANDROIDSTUDIO_7F0E4A25=1" "-DJUCE_APP_VERSION=1.0.0" "-DJUCE_APP_VERSION_HEX=0x10000") include_directories( AFTER "../../../../../modules/juce_audio_processors/format_types/VST3_SDK" @@ -19,18 +23,18 @@ include_directories( AFTER enable_language(ASM) -IF(JUCE_BUILD_CONFIGURATION MATCHES "DEBUG") - add_definitions("-DDEBUG=1" "-D_DEBUG=1") -ELSEIF(JUCE_BUILD_CONFIGURATION MATCHES "RELEASE") - add_definitions("-DNDEBUG=1") +if(JUCE_BUILD_CONFIGURATION MATCHES "DEBUG") + add_definitions("-DJUCE_DISPLAY_SPLASH_SCREEN=0" "-DJUCE_USE_DARK_SPLASH_SCREEN=1" "-DJUCE_PROJUCER_VERSION=0x60005" "-DJUCE_MODULE_AVAILABLE_juce_audio_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_devices=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_formats=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_processors=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_utils=1" "-DJUCE_MODULE_AVAILABLE_juce_core=1" "-DJUCE_MODULE_AVAILABLE_juce_cryptography=1" "-DJUCE_MODULE_AVAILABLE_juce_data_structures=1" "-DJUCE_MODULE_AVAILABLE_juce_dsp=1" "-DJUCE_MODULE_AVAILABLE_juce_events=1" "-DJUCE_MODULE_AVAILABLE_juce_graphics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_extra=1" "-DJUCE_MODULE_AVAILABLE_juce_opengl=1" "-DJUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1" "-DJUCE_WASAPI=1" "-DJUCE_DIRECTSOUND=1" "-DJUCE_ALSA=1" "-DJUCE_USE_FLAC=0" "-DJUCE_USE_OGGVORBIS=1" "-DJUCE_PLUGINHOST_VST3=1" "-DJUCE_PLUGINHOST_AU=1" "-DJUCE_PLUGINHOST_LADSPA=1" "-DJUCE_USE_CDREADER=0" "-DJUCE_USE_CDBURNER=0" "-DJUCE_WEB_BROWSER=0" "-DJUCE_STANDALONE_APPLICATION=1" "-DJUCER_ANDROIDSTUDIO_7F0E4A25=1" "-DJUCE_APP_VERSION=1.0.0" "-DJUCE_APP_VERSION_HEX=0x10000" "-DDEBUG=1" "-D_DEBUG=1") +elseif(JUCE_BUILD_CONFIGURATION MATCHES "RELEASE") + add_definitions("-DJUCE_DISPLAY_SPLASH_SCREEN=0" "-DJUCE_USE_DARK_SPLASH_SCREEN=1" "-DJUCE_PROJUCER_VERSION=0x60005" "-DJUCE_MODULE_AVAILABLE_juce_audio_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_devices=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_formats=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_processors=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_utils=1" "-DJUCE_MODULE_AVAILABLE_juce_core=1" "-DJUCE_MODULE_AVAILABLE_juce_cryptography=1" "-DJUCE_MODULE_AVAILABLE_juce_data_structures=1" "-DJUCE_MODULE_AVAILABLE_juce_dsp=1" "-DJUCE_MODULE_AVAILABLE_juce_events=1" "-DJUCE_MODULE_AVAILABLE_juce_graphics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_extra=1" "-DJUCE_MODULE_AVAILABLE_juce_opengl=1" "-DJUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1" "-DJUCE_WASAPI=1" "-DJUCE_DIRECTSOUND=1" "-DJUCE_ALSA=1" "-DJUCE_USE_FLAC=0" "-DJUCE_USE_OGGVORBIS=1" "-DJUCE_PLUGINHOST_VST3=1" "-DJUCE_PLUGINHOST_AU=1" "-DJUCE_PLUGINHOST_LADSPA=1" "-DJUCE_USE_CDREADER=0" "-DJUCE_USE_CDBURNER=0" "-DJUCE_WEB_BROWSER=0" "-DJUCE_STANDALONE_APPLICATION=1" "-DJUCER_ANDROIDSTUDIO_7F0E4A25=1" "-DJUCE_APP_VERSION=1.0.0" "-DJUCE_APP_VERSION_HEX=0x10000" "-DNDEBUG=1") if(NOT (ANDROID_ABI STREQUAL "mips" OR ANDROID_ABI STREQUAL "mips64")) - SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -flto") - SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -flto") - SET(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} -flto") - ENDIF(NOT (ANDROID_ABI STREQUAL "mips" OR ANDROID_ABI STREQUAL "mips64")) -ELSE(JUCE_BUILD_CONFIGURATION MATCHES "DEBUG") - MESSAGE( FATAL_ERROR "No matching build-configuration found." ) -ENDIF(JUCE_BUILD_CONFIGURATION MATCHES "DEBUG") + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -flto") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -flto") + set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} -flto") + endif() +else() + message( FATAL_ERROR "No matching build-configuration found." ) +endif() add_library( ${BINARY_NAME} @@ -111,16 +115,17 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp" "../../../../../modules/juce_audio_basics/synthesisers/juce_Synthesiser.h" "../../../../../modules/juce_audio_basics/utilities/juce_ADSR.h" - "../../../../../modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.cpp" - "../../../../../modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.h" "../../../../../modules/juce_audio_basics/utilities/juce_Decibels.h" + "../../../../../modules/juce_audio_basics/utilities/juce_GenericInterpolator.h" "../../../../../modules/juce_audio_basics/utilities/juce_IIRFilter.cpp" "../../../../../modules/juce_audio_basics/utilities/juce_IIRFilter.h" + "../../../../../modules/juce_audio_basics/utilities/juce_Interpolators.cpp" + "../../../../../modules/juce_audio_basics/utilities/juce_Interpolators.h" "../../../../../modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.cpp" - "../../../../../modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.h" "../../../../../modules/juce_audio_basics/utilities/juce_Reverb.h" "../../../../../modules/juce_audio_basics/utilities/juce_SmoothedValue.cpp" "../../../../../modules/juce_audio_basics/utilities/juce_SmoothedValue.h" + "../../../../../modules/juce_audio_basics/utilities/juce_WindowedSincInterpolator.cpp" "../../../../../modules/juce_audio_basics/juce_audio_basics.cpp" "../../../../../modules/juce_audio_basics/juce_audio_basics.mm" "../../../../../modules/juce_audio_basics/juce_audio_basics.h" @@ -135,7 +140,118 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_devices/midi_io/juce_MidiDevices.h" "../../../../../modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.cpp" "../../../../../modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStream.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamBase.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamBuilder.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamCallback.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Definitions.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/LatencyTuner.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Oboe.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/ResultWithValue.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/StabilizedCallback.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Utilities.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Version.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AAudioLoader.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AAudioLoader.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioClock.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioSourceCaller.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioSourceCaller.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioStream.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioStreamBuilder.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/DataConversionFlowGraph.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/DataConversionFlowGraph.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/FilterAudioStream.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/FilterAudioStream.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockAdapter.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockAdapter.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockReader.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockReader.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockWriter.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockWriter.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/LatencyTuner.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/MonotonicCounter.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/OboeDebug.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/QuirksManager.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/QuirksManager.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceFloatCaller.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceFloatCaller.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceI16Caller.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceI16Caller.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/StabilizedCallback.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/Trace.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/Trace.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/Utilities.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/Version.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoController.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoController.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/HyperbolicCosineWindow.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/IntegerRatio.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/IntegerRatio.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/KaiserWindow.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/LinearResampler.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/LinearResampler.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/MultiChannelResampler.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/MultiChannelResampler.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResampler.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResampler.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResamplerStereo.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResamplerStereo.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ClipToRange.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ClipToRange.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/RampLinear.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/RampLinear.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SampleRateConverter.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SampleRateConverter.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkFloat.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkFloat.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI16.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI16.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI24.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI24.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceFloat.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceFloat.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI16.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI16.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI24.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI24.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioInputStreamOpenSLES.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioInputStreamOpenSLES.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioOutputStreamOpenSLES.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioOutputStreamOpenSLES.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamBuffered.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamBuffered.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamOpenSLES.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamOpenSLES.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/EngineOpenSLES.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/EngineOpenSLES.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/OpenSLESUtilities.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/OpenSLESUtilities.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/OutputMixerOpenSLES.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/OutputMixerOpenSLES.h" + "../../../../../modules/juce_audio_devices/native/oboe/CMakeLists.txt" + "../../../../../modules/juce_audio_devices/native/oboe/readme.md" "../../../../../modules/juce_audio_devices/native/juce_android_Audio.cpp" + "../../../../../modules/juce_audio_devices/native/juce_android_HighPerformanceAudioHelpers.h" "../../../../../modules/juce_audio_devices/native/juce_android_Midi.cpp" "../../../../../modules/juce_audio_devices/native/juce_android_Oboe.cpp" "../../../../../modules/juce_audio_devices/native/juce_android_OpenSL.cpp" @@ -207,73 +323,76 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_formats/codecs/flac/stream_decoder.h" "../../../../../modules/juce_audio_formats/codecs/flac/stream_encoder.h" "../../../../../modules/juce_audio_formats/codecs/flac/win_utf8_io.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/books/coupled/res_books_51.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/books/coupled/res_books_stereo.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/books/floor/floor_books.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/books/uncoupled/res_books_uncoupled.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/floor_all.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/psych_8.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/psych_11.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/psych_16.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/psych_44.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_8.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_16.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_44.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_44p51.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_44u.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_8.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_11.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_16.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_22.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_32.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_44.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_44p51.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_44u.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_X.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/analysis.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/backends.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/bitrate.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/bitrate.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/block.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/codebook.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/codebook.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/codec_internal.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/envelope.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/envelope.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/floor0.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/floor1.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/highlevel.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/info.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lookup.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lookup.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lookup_data.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lpc.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lpc.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lsp.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lsp.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/mapping0.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/masking.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/mdct.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/mdct.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/misc.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/os.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/psy.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/psy.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/registry.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/registry.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/res0.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/scales.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/sharedbook.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/smallft.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/smallft.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/synthesis.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/vorbisenc.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/vorbisfile.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/window.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/window.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/books/coupled/res_books_51.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/books/coupled/res_books_stereo.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/books/floor/floor_books.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/books/uncoupled/res_books_uncoupled.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/floor_all.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/psych_8.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/psych_11.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/psych_16.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/psych_44.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/residue_8.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/residue_16.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/residue_44.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/residue_44p51.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/residue_44u.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_8.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_11.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_16.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_22.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_32.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_44.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_44p51.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_44u.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_X.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/analysis.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/backends.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/bitrate.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/bitrate.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/block.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/codebook.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/codebook.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/codec_internal.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/envelope.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/envelope.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/floor0.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/floor1.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/highlevel.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/info.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lookup.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lookup.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lookup_data.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lpc.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lpc.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lsp.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lsp.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/mapping0.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/masking.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/mdct.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/mdct.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/misc.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/misc.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/os.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/psy.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/psy.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/registry.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/registry.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/res0.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/scales.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/sharedbook.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/smallft.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/smallft.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/synthesis.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/vorbisenc.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/vorbisfile.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/window.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/window.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/README.md" "../../../../../modules/juce_audio_formats/codecs/oggvorbis/bitwise.c" "../../../../../modules/juce_audio_formats/codecs/oggvorbis/codec.h" "../../../../../modules/juce_audio_formats/codecs/oggvorbis/config_types.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/crctable.h" "../../../../../modules/juce_audio_formats/codecs/oggvorbis/framing.c" "../../../../../modules/juce_audio_formats/codecs/oggvorbis/Ogg Vorbis Licence.txt" "../../../../../modules/juce_audio_formats/codecs/oggvorbis/ogg.h" @@ -463,6 +582,8 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.h" "../../../../../modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp" "../../../../../modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h" + "../../../../../modules/juce_audio_processors/utilities/juce_ParameterAttachments.cpp" + "../../../../../modules/juce_audio_processors/utilities/juce_ParameterAttachments.h" "../../../../../modules/juce_audio_processors/utilities/juce_RangedAudioParameter.cpp" "../../../../../modules/juce_audio_processors/utilities/juce_RangedAudioParameter.h" "../../../../../modules/juce_audio_processors/juce_audio_processors.cpp" @@ -542,6 +663,8 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_core/files/juce_FileSearchPath.cpp" "../../../../../modules/juce_core/files/juce_FileSearchPath.h" "../../../../../modules/juce_core/files/juce_MemoryMappedFile.h" + "../../../../../modules/juce_core/files/juce_RangedDirectoryIterator.cpp" + "../../../../../modules/juce_core/files/juce_RangedDirectoryIterator.h" "../../../../../modules/juce_core/files/juce_TemporaryFile.cpp" "../../../../../modules/juce_core/files/juce_TemporaryFile.h" "../../../../../modules/juce_core/files/juce_WildcardFileFilter.cpp" @@ -564,6 +687,8 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_core/maths/juce_Random.h" "../../../../../modules/juce_core/maths/juce_Range.h" "../../../../../modules/juce_core/maths/juce_StatisticsAccumulator.h" + "../../../../../modules/juce_core/memory/juce_AllocationHooks.cpp" + "../../../../../modules/juce_core/memory/juce_AllocationHooks.h" "../../../../../modules/juce_core/memory/juce_Atomic.h" "../../../../../modules/juce_core/memory/juce_ByteOrder.h" "../../../../../modules/juce_core/memory/juce_ContainerDeletePolicy.h" @@ -650,6 +775,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_core/streams/juce_URLInputSource.cpp" "../../../../../modules/juce_core/streams/juce_URLInputSource.h" "../../../../../modules/juce_core/system/juce_CompilerSupport.h" + "../../../../../modules/juce_core/system/juce_CompilerWarnings.h" "../../../../../modules/juce_core/system/juce_PlatformDefs.h" "../../../../../modules/juce_core/system/juce_StandardHeader.h" "../../../../../modules/juce_core/system/juce_SystemStats.cpp" @@ -781,6 +907,90 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_data_structures/juce_data_structures.cpp" "../../../../../modules/juce_data_structures/juce_data_structures.mm" "../../../../../modules/juce_data_structures/juce_data_structures.h" + "../../../../../modules/juce_dsp/containers/juce_AudioBlock.h" + "../../../../../modules/juce_dsp/containers/juce_AudioBlock_test.cpp" + "../../../../../modules/juce_dsp/containers/juce_FixedSizeFunction.h" + "../../../../../modules/juce_dsp/containers/juce_FixedSizeFunction_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" + "../../../../../modules/juce_dsp/filter_design/juce_FilterDesign.cpp" + "../../../../../modules/juce_dsp/filter_design/juce_FilterDesign.h" + "../../../../../modules/juce_dsp/frequency/juce_Convolution.cpp" + "../../../../../modules/juce_dsp/frequency/juce_Convolution.h" + "../../../../../modules/juce_dsp/frequency/juce_Convolution_test.cpp" + "../../../../../modules/juce_dsp/frequency/juce_FFT.cpp" + "../../../../../modules/juce_dsp/frequency/juce_FFT.h" + "../../../../../modules/juce_dsp/frequency/juce_FFT_test.cpp" + "../../../../../modules/juce_dsp/frequency/juce_Windowing.cpp" + "../../../../../modules/juce_dsp/frequency/juce_Windowing.h" + "../../../../../modules/juce_dsp/maths/juce_FastMathApproximations.h" + "../../../../../modules/juce_dsp/maths/juce_LogRampedValue.h" + "../../../../../modules/juce_dsp/maths/juce_LogRampedValue_test.cpp" + "../../../../../modules/juce_dsp/maths/juce_LookupTable.cpp" + "../../../../../modules/juce_dsp/maths/juce_LookupTable.h" + "../../../../../modules/juce_dsp/maths/juce_Matrix.cpp" + "../../../../../modules/juce_dsp/maths/juce_Matrix.h" + "../../../../../modules/juce_dsp/maths/juce_Matrix_test.cpp" + "../../../../../modules/juce_dsp/maths/juce_Phase.h" + "../../../../../modules/juce_dsp/maths/juce_Polynomial.h" + "../../../../../modules/juce_dsp/maths/juce_SpecialFunctions.cpp" + "../../../../../modules/juce_dsp/maths/juce_SpecialFunctions.h" + "../../../../../modules/juce_dsp/native/juce_avx_SIMDNativeOps.cpp" + "../../../../../modules/juce_dsp/native/juce_avx_SIMDNativeOps.h" + "../../../../../modules/juce_dsp/native/juce_fallback_SIMDNativeOps.h" + "../../../../../modules/juce_dsp/native/juce_neon_SIMDNativeOps.cpp" + "../../../../../modules/juce_dsp/native/juce_neon_SIMDNativeOps.h" + "../../../../../modules/juce_dsp/native/juce_sse_SIMDNativeOps.cpp" + "../../../../../modules/juce_dsp/native/juce_sse_SIMDNativeOps.h" + "../../../../../modules/juce_dsp/processors/juce_BallisticsFilter.cpp" + "../../../../../modules/juce_dsp/processors/juce_BallisticsFilter.h" + "../../../../../modules/juce_dsp/processors/juce_DelayLine.cpp" + "../../../../../modules/juce_dsp/processors/juce_DelayLine.h" + "../../../../../modules/juce_dsp/processors/juce_DryWetMixer.cpp" + "../../../../../modules/juce_dsp/processors/juce_DryWetMixer.h" + "../../../../../modules/juce_dsp/processors/juce_FIRFilter.cpp" + "../../../../../modules/juce_dsp/processors/juce_FIRFilter.h" + "../../../../../modules/juce_dsp/processors/juce_FIRFilter_test.cpp" + "../../../../../modules/juce_dsp/processors/juce_FirstOrderTPTFilter.cpp" + "../../../../../modules/juce_dsp/processors/juce_FirstOrderTPTFilter.h" + "../../../../../modules/juce_dsp/processors/juce_IIRFilter.cpp" + "../../../../../modules/juce_dsp/processors/juce_IIRFilter.h" + "../../../../../modules/juce_dsp/processors/juce_IIRFilter_Impl.h" + "../../../../../modules/juce_dsp/processors/juce_LinkwitzRileyFilter.cpp" + "../../../../../modules/juce_dsp/processors/juce_LinkwitzRileyFilter.h" + "../../../../../modules/juce_dsp/processors/juce_Oversampling.cpp" + "../../../../../modules/juce_dsp/processors/juce_Oversampling.h" + "../../../../../modules/juce_dsp/processors/juce_Panner.cpp" + "../../../../../modules/juce_dsp/processors/juce_Panner.h" + "../../../../../modules/juce_dsp/processors/juce_ProcessContext.h" + "../../../../../modules/juce_dsp/processors/juce_ProcessorChain.h" + "../../../../../modules/juce_dsp/processors/juce_ProcessorChain_test.cpp" + "../../../../../modules/juce_dsp/processors/juce_ProcessorDuplicator.h" + "../../../../../modules/juce_dsp/processors/juce_ProcessorWrapper.h" + "../../../../../modules/juce_dsp/processors/juce_StateVariableFilter.h" + "../../../../../modules/juce_dsp/processors/juce_StateVariableTPTFilter.cpp" + "../../../../../modules/juce_dsp/processors/juce_StateVariableTPTFilter.h" + "../../../../../modules/juce_dsp/widgets/juce_Bias.h" + "../../../../../modules/juce_dsp/widgets/juce_Chorus.cpp" + "../../../../../modules/juce_dsp/widgets/juce_Chorus.h" + "../../../../../modules/juce_dsp/widgets/juce_Compressor.cpp" + "../../../../../modules/juce_dsp/widgets/juce_Compressor.h" + "../../../../../modules/juce_dsp/widgets/juce_Gain.h" + "../../../../../modules/juce_dsp/widgets/juce_LadderFilter.cpp" + "../../../../../modules/juce_dsp/widgets/juce_LadderFilter.h" + "../../../../../modules/juce_dsp/widgets/juce_Limiter.cpp" + "../../../../../modules/juce_dsp/widgets/juce_Limiter.h" + "../../../../../modules/juce_dsp/widgets/juce_NoiseGate.cpp" + "../../../../../modules/juce_dsp/widgets/juce_NoiseGate.h" + "../../../../../modules/juce_dsp/widgets/juce_Oscillator.h" + "../../../../../modules/juce_dsp/widgets/juce_Phaser.cpp" + "../../../../../modules/juce_dsp/widgets/juce_Phaser.h" + "../../../../../modules/juce_dsp/widgets/juce_Reverb.h" + "../../../../../modules/juce_dsp/widgets/juce_WaveShaper.h" + "../../../../../modules/juce_dsp/juce_dsp.cpp" + "../../../../../modules/juce_dsp/juce_dsp.mm" + "../../../../../modules/juce_dsp/juce_dsp.h" "../../../../../modules/juce_events/broadcasters/juce_ActionBroadcaster.cpp" "../../../../../modules/juce_events/broadcasters/juce_ActionBroadcaster.h" "../../../../../modules/juce_events/broadcasters/juce_ActionListener.h" @@ -1174,6 +1384,11 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_gui_basics/mouse/juce_SelectedItemSet.h" "../../../../../modules/juce_gui_basics/mouse/juce_TextDragAndDropTarget.h" "../../../../../modules/juce_gui_basics/mouse/juce_TooltipClient.h" + "../../../../../modules/juce_gui_basics/native/x11/juce_linux_X11_DragAndDrop.cpp" + "../../../../../modules/juce_gui_basics/native/x11/juce_linux_X11_Symbols.cpp" + "../../../../../modules/juce_gui_basics/native/x11/juce_linux_X11_Symbols.h" + "../../../../../modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.cpp" + "../../../../../modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.h" "../../../../../modules/juce_gui_basics/native/juce_android_ContentSharer.cpp" "../../../../../modules/juce_gui_basics/native/juce_android_FileChooser.cpp" "../../../../../modules/juce_gui_basics/native/juce_android_Windowing.cpp" @@ -1183,10 +1398,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm" "../../../../../modules/juce_gui_basics/native/juce_ios_Windowing.mm" "../../../../../modules/juce_gui_basics/native/juce_linux_FileChooser.cpp" - "../../../../../modules/juce_gui_basics/native/juce_linux_X11.cpp" - "../../../../../modules/juce_gui_basics/native/juce_linux_X11.h" - "../../../../../modules/juce_gui_basics/native/juce_linux_X11_Clipboard.cpp" - "../../../../../modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp" + "../../../../../modules/juce_gui_basics/native/juce_linux_Windowing.cpp" "../../../../../modules/juce_gui_basics/native/juce_mac_FileChooser.mm" "../../../../../modules/juce_gui_basics/native/juce_mac_MainMenu.mm" "../../../../../modules/juce_gui_basics/native/juce_mac_MouseCursor.mm" @@ -1291,6 +1503,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.h" "../../../../../modules/juce_gui_extra/embedding/juce_ActiveXControlComponent.h" "../../../../../modules/juce_gui_extra/embedding/juce_AndroidViewComponent.h" + "../../../../../modules/juce_gui_extra/embedding/juce_HWNDComponent.h" "../../../../../modules/juce_gui_extra/embedding/juce_NSViewComponent.h" "../../../../../modules/juce_gui_extra/embedding/juce_ScopedDPIAwarenessDisabler.h" "../../../../../modules/juce_gui_extra/embedding/juce_UIViewComponent.h" @@ -1332,6 +1545,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_gui_extra/native/juce_mac_SystemTrayIcon.cpp" "../../../../../modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm" "../../../../../modules/juce_gui_extra/native/juce_win32_ActiveXComponent.cpp" + "../../../../../modules/juce_gui_extra/native/juce_win32_HWNDComponent.cpp" "../../../../../modules/juce_gui_extra/native/juce_win32_SystemTrayIcon.cpp" "../../../../../modules/juce_gui_extra/native/juce_win32_WebBrowserComponent.cpp" "../../../../../modules/juce_gui_extra/juce_gui_extra.cpp" @@ -1370,21 +1584,6 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_opengl/juce_opengl.cpp" "../../../../../modules/juce_opengl/juce_opengl.mm" "../../../../../modules/juce_opengl/juce_opengl.h" - "../../../../../modules/juce_video/capture/juce_CameraDevice.cpp" - "../../../../../modules/juce_video/capture/juce_CameraDevice.h" - "../../../../../modules/juce_video/native/juce_android_CameraDevice.h" - "../../../../../modules/juce_video/native/juce_android_Video.h" - "../../../../../modules/juce_video/native/juce_ios_CameraDevice.h" - "../../../../../modules/juce_video/native/juce_mac_CameraDevice.h" - "../../../../../modules/juce_video/native/juce_mac_Video.h" - "../../../../../modules/juce_video/native/juce_win32_CameraDevice.h" - "../../../../../modules/juce_video/native/juce_win32_Video.h" - "../../../../../modules/juce_video/playback/juce_VideoComponent.cpp" - "../../../../../modules/juce_video/playback/juce_VideoComponent.h" - "../../../../../modules/juce_video/juce_video.cpp" - "../../../../../modules/juce_video/juce_video.mm" - "../../../../../modules/juce_video/juce_video.h" - "../../../JuceLibraryCode/AppConfig.h" "../../../JuceLibraryCode/BinaryData.cpp" "../../../JuceLibraryCode/BinaryData.h" "../../../JuceLibraryCode/include_juce_audio_basics.cpp" @@ -1395,12 +1594,12 @@ add_library( ${BINARY_NAME} "../../../JuceLibraryCode/include_juce_core.cpp" "../../../JuceLibraryCode/include_juce_cryptography.cpp" "../../../JuceLibraryCode/include_juce_data_structures.cpp" + "../../../JuceLibraryCode/include_juce_dsp.cpp" "../../../JuceLibraryCode/include_juce_events.cpp" "../../../JuceLibraryCode/include_juce_graphics.cpp" "../../../JuceLibraryCode/include_juce_gui_basics.cpp" "../../../JuceLibraryCode/include_juce_gui_extra.cpp" "../../../JuceLibraryCode/include_juce_opengl.cpp" - "../../../JuceLibraryCode/include_juce_video.cpp" "../../../JuceLibraryCode/JuceHeader.h" ) @@ -1473,16 +1672,17 @@ set_source_files_properties("../../../../../modules/juce_audio_basics/sources/ju set_source_files_properties("../../../../../modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/synthesisers/juce_Synthesiser.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_ADSR.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_Decibels.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_GenericInterpolator.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_IIRFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_IIRFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_Interpolators.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_Interpolators.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_Reverb.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_SmoothedValue.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_SmoothedValue.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_WindowedSincInterpolator.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/juce_audio_basics.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/juce_audio_basics.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/juce_audio_basics.h" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -1497,7 +1697,118 @@ set_source_files_properties("../../../../../modules/juce_audio_devices/midi_io/j set_source_files_properties("../../../../../modules/juce_audio_devices/midi_io/juce_MidiDevices.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStream.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamBase.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamBuilder.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamCallback.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Definitions.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/LatencyTuner.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Oboe.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/ResultWithValue.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/StabilizedCallback.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Utilities.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Version.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AAudioLoader.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AAudioLoader.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioClock.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioSourceCaller.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioSourceCaller.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioStream.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioStreamBuilder.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/DataConversionFlowGraph.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/DataConversionFlowGraph.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/FilterAudioStream.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/FilterAudioStream.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockAdapter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockAdapter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockReader.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockReader.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockWriter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockWriter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/LatencyTuner.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/MonotonicCounter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/OboeDebug.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/QuirksManager.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/QuirksManager.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceFloatCaller.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceFloatCaller.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceI16Caller.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceI16Caller.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/StabilizedCallback.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/Trace.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/Trace.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/Utilities.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/Version.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoController.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoController.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/HyperbolicCosineWindow.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/IntegerRatio.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/IntegerRatio.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/KaiserWindow.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/LinearResampler.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/LinearResampler.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/MultiChannelResampler.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/MultiChannelResampler.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResampler.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResampler.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResamplerStereo.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResamplerStereo.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ClipToRange.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ClipToRange.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/RampLinear.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/RampLinear.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SampleRateConverter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SampleRateConverter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkFloat.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkFloat.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI16.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI16.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI24.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI24.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceFloat.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceFloat.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI16.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI16.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI24.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI24.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioInputStreamOpenSLES.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioInputStreamOpenSLES.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioOutputStreamOpenSLES.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioOutputStreamOpenSLES.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamBuffered.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamBuffered.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamOpenSLES.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamOpenSLES.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/EngineOpenSLES.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/EngineOpenSLES.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/OpenSLESUtilities.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/OpenSLESUtilities.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/OutputMixerOpenSLES.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/OutputMixerOpenSLES.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/CMakeLists.txt" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/readme.md" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_android_Audio.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_android_HighPerformanceAudioHelpers.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_android_Midi.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_android_Oboe.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_android_OpenSL.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -1569,73 +1880,76 @@ set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/fl set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/stream_decoder.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/stream_encoder.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/win_utf8_io.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/books/coupled/res_books_51.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/books/coupled/res_books_stereo.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/books/floor/floor_books.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/books/uncoupled/res_books_uncoupled.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/floor_all.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/psych_8.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/psych_11.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/psych_16.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/psych_44.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_8.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_16.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_44.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_44p51.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_44u.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_8.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_11.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_16.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_22.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_32.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_44.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_44p51.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_44u.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_X.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/analysis.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/backends.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/bitrate.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/bitrate.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/block.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/codebook.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/codebook.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/codec_internal.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/envelope.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/envelope.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/floor0.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/floor1.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/highlevel.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/info.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lookup.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lookup.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lookup_data.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lpc.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lpc.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lsp.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lsp.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/mapping0.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/masking.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/mdct.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/mdct.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/misc.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/os.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/psy.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/psy.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/registry.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/registry.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/res0.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/scales.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/sharedbook.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/smallft.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/smallft.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/synthesis.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/vorbisenc.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/vorbisfile.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/window.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/window.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/books/coupled/res_books_51.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/books/coupled/res_books_stereo.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/books/floor/floor_books.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/books/uncoupled/res_books_uncoupled.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/floor_all.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/psych_8.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/psych_11.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/psych_16.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/psych_44.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/residue_8.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/residue_16.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/residue_44.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/residue_44p51.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/residue_44u.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_8.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_11.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_16.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_22.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_32.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_44.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_44p51.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_44u.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_X.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/analysis.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/backends.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/bitrate.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/bitrate.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/block.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/codebook.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/codebook.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/codec_internal.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/envelope.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/envelope.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/floor0.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/floor1.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/highlevel.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/info.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lookup.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lookup.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lookup_data.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lpc.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lpc.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lsp.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lsp.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/mapping0.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/masking.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/mdct.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/mdct.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/misc.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/misc.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/os.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/psy.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/psy.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/registry.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/registry.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/res0.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/scales.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/sharedbook.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/smallft.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/smallft.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/synthesis.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/vorbisenc.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/vorbisfile.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/window.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/window.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/README.md" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/bitwise.c" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/codec.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/config_types.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/crctable.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/framing.c" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/Ogg Vorbis Licence.txt" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/ogg.h" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -1825,6 +2139,8 @@ set_source_files_properties("../../../../../modules/juce_audio_processors/utilit set_source_files_properties("../../../../../modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_processors/utilities/juce_ParameterAttachments.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_processors/utilities/juce_ParameterAttachments.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_processors/utilities/juce_RangedAudioParameter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_processors/utilities/juce_RangedAudioParameter.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_processors/juce_audio_processors.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -1904,6 +2220,8 @@ set_source_files_properties("../../../../../modules/juce_core/files/juce_FileOut set_source_files_properties("../../../../../modules/juce_core/files/juce_FileSearchPath.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/files/juce_FileSearchPath.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/files/juce_MemoryMappedFile.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_core/files/juce_RangedDirectoryIterator.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_core/files/juce_RangedDirectoryIterator.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/files/juce_TemporaryFile.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/files/juce_TemporaryFile.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/files/juce_WildcardFileFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -1926,6 +2244,8 @@ set_source_files_properties("../../../../../modules/juce_core/maths/juce_Random. set_source_files_properties("../../../../../modules/juce_core/maths/juce_Random.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/maths/juce_Range.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/maths/juce_StatisticsAccumulator.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_core/memory/juce_AllocationHooks.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_core/memory/juce_AllocationHooks.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/memory/juce_Atomic.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/memory/juce_ByteOrder.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/memory/juce_ContainerDeletePolicy.h" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -2012,6 +2332,7 @@ set_source_files_properties("../../../../../modules/juce_core/streams/juce_Subre set_source_files_properties("../../../../../modules/juce_core/streams/juce_URLInputSource.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/streams/juce_URLInputSource.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/system/juce_CompilerSupport.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_core/system/juce_CompilerWarnings.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/system/juce_PlatformDefs.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/system/juce_StandardHeader.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/system/juce_SystemStats.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -2143,6 +2464,90 @@ set_source_files_properties("../../../../../modules/juce_data_structures/values/ set_source_files_properties("../../../../../modules/juce_data_structures/juce_data_structures.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_data_structures/juce_data_structures.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_data_structures/juce_data_structures.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/containers/juce_AudioBlock.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/containers/juce_AudioBlock_test.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/containers/juce_FixedSizeFunction.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/containers/juce_FixedSizeFunction_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) +set_source_files_properties("../../../../../modules/juce_dsp/filter_design/juce_FilterDesign.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/filter_design/juce_FilterDesign.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/frequency/juce_Convolution.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/frequency/juce_Convolution.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/frequency/juce_Convolution_test.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/frequency/juce_FFT.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/frequency/juce_FFT.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/frequency/juce_FFT_test.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/frequency/juce_Windowing.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/frequency/juce_Windowing.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/maths/juce_FastMathApproximations.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/maths/juce_LogRampedValue.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/maths/juce_LogRampedValue_test.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/maths/juce_LookupTable.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/maths/juce_LookupTable.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/maths/juce_Matrix.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/maths/juce_Matrix.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/maths/juce_Matrix_test.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/maths/juce_Phase.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/maths/juce_Polynomial.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/maths/juce_SpecialFunctions.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/maths/juce_SpecialFunctions.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/native/juce_avx_SIMDNativeOps.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/native/juce_avx_SIMDNativeOps.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/native/juce_fallback_SIMDNativeOps.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/native/juce_neon_SIMDNativeOps.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/native/juce_neon_SIMDNativeOps.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/native/juce_sse_SIMDNativeOps.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/native/juce_sse_SIMDNativeOps.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_BallisticsFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_BallisticsFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_DelayLine.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_DelayLine.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_DryWetMixer.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_DryWetMixer.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_FIRFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_FIRFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_FIRFilter_test.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_FirstOrderTPTFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_FirstOrderTPTFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_IIRFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_IIRFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_IIRFilter_Impl.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_LinkwitzRileyFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_LinkwitzRileyFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_Oversampling.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_Oversampling.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_Panner.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_Panner.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_ProcessContext.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_ProcessorChain.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_ProcessorChain_test.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_ProcessorDuplicator.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_ProcessorWrapper.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_StateVariableFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_StateVariableTPTFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_StateVariableTPTFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Bias.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Chorus.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Chorus.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Compressor.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Compressor.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Gain.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_LadderFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_LadderFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Limiter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Limiter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_NoiseGate.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_NoiseGate.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Oscillator.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Phaser.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Phaser.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Reverb.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_WaveShaper.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/juce_dsp.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/juce_dsp.mm" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/juce_dsp.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_events/broadcasters/juce_ActionBroadcaster.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_events/broadcasters/juce_ActionBroadcaster.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_events/broadcasters/juce_ActionListener.h" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -2536,6 +2941,11 @@ set_source_files_properties("../../../../../modules/juce_gui_basics/mouse/juce_M set_source_files_properties("../../../../../modules/juce_gui_basics/mouse/juce_SelectedItemSet.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/mouse/juce_TextDragAndDropTarget.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/mouse/juce_TooltipClient.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_gui_basics/native/x11/juce_linux_X11_DragAndDrop.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_gui_basics/native/x11/juce_linux_X11_Symbols.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_gui_basics/native/x11/juce_linux_X11_Symbols.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_android_ContentSharer.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_android_FileChooser.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_android_Windowing.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -2545,10 +2955,7 @@ set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_ set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_ios_Windowing.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_linux_FileChooser.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_linux_X11.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_linux_X11.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_linux_X11_Clipboard.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_linux_Windowing.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_mac_FileChooser.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_mac_MainMenu.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_mac_MouseCursor.mm" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -2653,6 +3060,7 @@ set_source_files_properties("../../../../../modules/juce_gui_extra/documents/juc set_source_files_properties("../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/embedding/juce_ActiveXControlComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/embedding/juce_AndroidViewComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_gui_extra/embedding/juce_HWNDComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/embedding/juce_NSViewComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/embedding/juce_ScopedDPIAwarenessDisabler.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/embedding/juce_UIViewComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -2694,6 +3102,7 @@ set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_m set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_mac_SystemTrayIcon.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_win32_ActiveXComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_win32_HWNDComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_win32_SystemTrayIcon.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_win32_WebBrowserComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/juce_gui_extra.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -2732,24 +3141,19 @@ set_source_files_properties("../../../../../modules/juce_opengl/utils/juce_OpenG set_source_files_properties("../../../../../modules/juce_opengl/juce_opengl.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_opengl/juce_opengl.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_opengl/juce_opengl.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_video/capture/juce_CameraDevice.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_video/capture/juce_CameraDevice.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_video/native/juce_android_CameraDevice.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_video/native/juce_android_Video.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_video/native/juce_ios_CameraDevice.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_video/native/juce_mac_CameraDevice.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_video/native/juce_mac_Video.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_video/native/juce_win32_CameraDevice.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_video/native/juce_win32_Video.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_video/playback/juce_VideoComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_video/playback/juce_VideoComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_video/juce_video.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_video/juce_video.mm" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_video/juce_video.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../JuceLibraryCode/AppConfig.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../JuceLibraryCode/BinaryData.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../JuceLibraryCode/JuceHeader.h" PROPERTIES HEADER_FILE_ONLY TRUE) +target_compile_options( ${BINARY_NAME} PRIVATE "-fsigned-char" ) + +if( JUCE_BUILD_CONFIGURATION MATCHES "DEBUG" ) + target_compile_options( ${BINARY_NAME} PRIVATE -Wall -Wshadow-all -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wunreachable-code -Wzero-as-null-pointer-constant -Wcast-align -Winconsistent-missing-destructor-override -Wshift-sign-overflow -Wnullable-to-nonnull-conversion -Wno-missing-field-initializers -Wno-ignored-qualifiers -Wswitch-enum) +endif() + +if( JUCE_BUILD_CONFIGURATION MATCHES "RELEASE" ) + target_compile_options( ${BINARY_NAME} PRIVATE -Wall -Wshadow-all -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wunreachable-code -Wzero-as-null-pointer-constant -Wcast-align -Winconsistent-missing-destructor-override -Wshift-sign-overflow -Wnullable-to-nonnull-conversion -Wno-missing-field-initializers -Wno-ignored-qualifiers -Wswitch-enum) +endif() + find_library(log "log") find_library(android "android") find_library(glesv3 "GLESv3") @@ -2762,4 +3166,5 @@ target_link_libraries( ${BINARY_NAME} ${glesv3} ${egl} "cpufeatures" + "oboe" ) diff --git a/extras/AudioPluginHost/Builds/Android/app/build.gradle b/extras/AudioPluginHost/Builds/Android/app/build.gradle index 838821bb..5138ef7d 100644 --- a/extras/AudioPluginHost/Builds/Android/app/build.gradle +++ b/extras/AudioPluginHost/Builds/Android/app/build.gradle @@ -1,7 +1,7 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 28 + compileSdkVersion 29 externalNativeBuild { cmake { path "CMakeLists.txt" @@ -18,14 +18,12 @@ android { } defaultConfig { - applicationId "com.roli.juce.pluginhost" + applicationId "com.juce.pluginhost" minSdkVersion 23 - targetSdkVersion 28 + targetSdkVersion 29 externalNativeBuild { cmake { - arguments "-DANDROID_TOOLCHAIN=clang", "-DANDROID_PLATFORM=android-23", "-DANDROID_STL=c++_static", "-DANDROID_CPP_FEATURES=exceptions rtti", "-DANDROID_ARM_MODE=arm", "-DANDROID_ARM_NEON=TRUE" - cFlags "-fsigned-char" - cppFlags "-fsigned-char", "-std=c++14" + arguments "-DANDROID_TOOLCHAIN=clang", "-DANDROID_PLATFORM=android-23", "-DANDROID_STL=c++_static", "-DANDROID_CPP_FEATURES=exceptions rtti", "-DANDROID_ARM_MODE=arm", "-DANDROID_ARM_NEON=TRUE", "-DCMAKE_CXX_STANDARD=14", "-DCMAKE_CXX_EXTENSIONS=OFF" } } } @@ -53,7 +51,7 @@ android { } externalNativeBuild { cmake { - arguments "-DJUCE_BUILD_CONFIGURATION=DEBUG", "-DCMAKE_CXX_FLAGS_DEBUG=-O0 -Wall -Wshadow-all -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wunreachable-code -Wzero-as-null-pointer-constant -Wcast-align -Winconsistent-missing-destructor-override -Wshift-sign-overflow -Wnullable-to-nonnull-conversion -Wno-missing-field-initializers -Wno-ignored-qualifiers", "-DCMAKE_C_FLAGS_DEBUG=-O0" + arguments "-DJUCE_BUILD_CONFIGURATION=DEBUG", "-DCMAKE_CXX_FLAGS_DEBUG=-O0", "-DCMAKE_C_FLAGS_DEBUG=-O0" } } @@ -62,7 +60,7 @@ android { release_ { externalNativeBuild { cmake { - arguments "-DJUCE_BUILD_CONFIGURATION=RELEASE", "-DCMAKE_CXX_FLAGS_RELEASE=-O3 -Wall -Wshadow-all -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wunreachable-code -Wzero-as-null-pointer-constant -Wcast-align -Winconsistent-missing-destructor-override -Wshift-sign-overflow -Wnullable-to-nonnull-conversion -Wno-missing-field-initializers -Wno-ignored-qualifiers", "-DCMAKE_C_FLAGS_RELEASE=-O3" + arguments "-DJUCE_BUILD_CONFIGURATION=RELEASE", "-DCMAKE_CXX_FLAGS_RELEASE=-O3", "-DCMAKE_C_FLAGS_RELEASE=-O3" } } @@ -86,7 +84,6 @@ android { main.java.srcDirs += ["../../../../../modules/juce_core/native/javacore/init", "../../../../../modules/juce_core/native/javacore/app", - "../../../../../modules/juce_gui_basics/native/javacore/app", "../../../../../modules/juce_gui_basics/native/javaopt/app"] main.res.srcDirs += diff --git a/extras/AudioPluginHost/Builds/Android/app/src/main/AndroidManifest.xml b/extras/AudioPluginHost/Builds/Android/app/src/main/AndroidManifest.xml index bc704681..336146a9 100644 --- a/extras/AudioPluginHost/Builds/Android/app/src/main/AndroidManifest.xml +++ b/extras/AudioPluginHost/Builds/Android/app/src/main/AndroidManifest.xml @@ -1,19 +1,20 @@ <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0.0" - package="com.roli.juce.pluginhost"> - <supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:anyDensity="true"/> + package="com.juce.pluginhost"> + <supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:anyDensity="true" + android:xlargeScreens="true"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> - <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> + <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/> <uses-permission android:name="android.permission.BLUETOOTH"/> <uses-permission android:name="android.permission.RECORD_AUDIO"/> <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/> <uses-permission android:name="android.permission.INTERNET"/> <uses-feature android:glEsVersion="0x00030000" android:required="true"/> - <application android:label="@string/app_name" android:name="com.roli.juce.JuceApp" android:icon="@drawable/icon" android:hardwareAccelerated="false"> - <activity android:name="com.roli.juce.JuceActivity" android:label="@string/app_name" android:configChanges="keyboardHidden|orientation|screenSize" + <application android:label="@string/app_name" android:name="com.rmsl.juce.JuceApp" android:icon="@drawable/icon" android:hardwareAccelerated="false"> + <activity android:name="com.rmsl.juce.JuceActivity" android:label="@string/app_name" android:configChanges="keyboardHidden|orientation|screenSize" android:screenOrientation="unspecified" android:launchMode="singleTask" android:hardwareAccelerated="true"> <intent-filter> <action android:name="android.intent.action.MAIN"/> diff --git a/extras/AudioPluginHost/Builds/Android/app/src/main/res/drawable-hdpi/icon.png b/extras/AudioPluginHost/Builds/Android/app/src/main/res/drawable-hdpi/icon.png index e551340cfb9cec7af90a789f6a24997379f37e46..f5caa4ef2a925c36a3669a84663d1230e66c71ae 100644 GIT binary patch literal 45427 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 literal 34761 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 T_1RS5>@tI=tDnm{r-UW|Hmul6 diff --git a/extras/AudioPluginHost/Builds/Android/app/src/main/res/drawable-ldpi/icon.png b/extras/AudioPluginHost/Builds/Android/app/src/main/res/drawable-ldpi/icon.png index 475d142e3535e0e8609f31fc4ecdf93c0ce81189..8caa9bb885b83d007ee6f5e3b51fa00bb6fad1a2 100644 GIT binary patch literal 22104 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 literal 15111 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 diff --git a/extras/AudioPluginHost/Builds/Android/app/src/main/res/drawable-mdpi/icon.png b/extras/AudioPluginHost/Builds/Android/app/src/main/res/drawable-mdpi/icon.png index eb13005911312450beed323cdc7498410e9ac661..b87302b4f970642ddfff2ea5c97b2ff7e2dae1df 100644 GIT binary patch literal 23363 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 literal 18428 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 ZfN^A+W{bp<Z~(0Y5xj_=^&X+je*mDxBFX>& diff --git a/extras/AudioPluginHost/Builds/Android/app/src/main/res/drawable-xhdpi/icon.png b/extras/AudioPluginHost/Builds/Android/app/src/main/res/drawable-xhdpi/icon.png index dddc79015e7f57a6cafaaedc9fc0d978a64b94fb..1895bc1c732ea44ef7957164975764bd8d7bfaa0 100644 GIT binary patch literal 47612 zcmX_nWn5I<7w!xU-92<S(%l^*-5}i|A)P~a2`_>OQc5Wx-6f?o(p?JD-2-zE|NFal zzMT0mv-dtLp0(Dq)=tpYRKdZdzyyInIBKejx*!k|@D&M!jtV?317_}l2gF-mO&=Zj zgrM8SgFtj3HAOl7fV{(1e;@tXYqZmoF8`M-okT(Co&H!a7*2`5C`6(+868qT>Rgha zB}6k^--nR)%d>INy`Trnp`a+zgCizg<%9S$op0bzJ#1|D{NBea?7Q`IW_2O04{i$l z!Rx_V^yrZr)BNYUzCrB5y;j+T#Hu*ZS||Jgd}BdmB_jM3Zx}A)pu8M0Y7Z!u4fQ94 zG&D>SHJa$%QzUFCCqH~2t2=cVEE=zk(SthZ0)6+P#|6aUC@U6`C7>+^<z!U;OZcCF zaHsCdPI5JyRA{Z<l}9Qax;tYP5q`AQ^;T|!ahay`4?98I#F_sHa*>?mWo>!i|BNT> zO_%*++5I&+B0~FBG6~-#Ild;L?GQ*@GvjS?o+yXJ=j}|7*RLymt0VEh!S@xE@ZmVN zg}dG4>-|=aRnS^PY$qkF7jm~p6U3#yskt`gsI~IER3OiAHBr!aWL!0)+skmJp@g0W zO&xrsEGG~oB6IP;-TCvsEL^K^j9}^>V-?hW`DpYi?+X>|?}XaubOn6GAg+QQOs;jG zB>~$(Y^4J@q<1|5RTh7rosq}DQFm*ZUt0?#h4HT^J_sNGtFOCUL=lCROcYxI7)5cx zUG85KIkHUUthkWeDQhtpKbkXuJ~)KZM7P?(%1B^xmd=Nzr`*@#2QAbJrH>nF`DJ01 zrqYsl=+EL%(_Lotu2+JfNY78nfBWPWe!Q9wpTz4C0#%dxUx$5#SecPKef>PiV$QbA z-#THFG^d6US%Z%gjz6<golm^OyHFkT<DS6S67(obT<mKRi3z2mgJTcAg=Ti)ysP?1 zLwRe^I_HcLX{d-y2gyqA(9e$$YB9BOLq}JL-{ipe0rqza@9jmG38(*9_^n>m5thT} zS)y>z0O>V*{!53+qOC67h(dxjdOQw<P4^%VQlQ@p9mzyrOw=<Gc=NL^%9ND}-GvZ1 zl4o7r?>|2Re31J*8L*Kj^?=`Y`=s+V5oR<n2r~q2OLeX_y5^_Toib5?=;=nyCD=!u zzvIUIP>ytB3m2{OCPaFP0X4%(=&I8<F&u-|{{H4GAGyIk1ws$ww7vU2nLarwmu^hK zmyAmP`XDcwuE+QV@?Ve}AN%F(41E%3gQgn(3Oxm=w`O!rl0m+fLYasyp8z%K>NfIy z*fNaH45`klAx!Mc`Z))%7sLqA?`fckiSt`)BpirsbCN`8ujAvHot4}hj8GxQ&{~ay z{~()h0U_Le8|`QaJA6Gwi&hM+x*&iU@fH3T&a62ZSynx9Z+H*_*|d57*?+qtsqSnN zzI*+rc=+P3`Dt_ksYkZS($l?ny_r$(si(v#<;oc;Kyu#XCeEmONXp^0?a+UyNOo1; z=So3~=$X<;ETItjt9QJ6jMl&7`aY-0#&cuWeU8&1!~EdG`|s7H8tT8W2Y*PUoMWV7 zHezlmztNKecY)-f6((Ng$v<?0SljugRMkn*nCgwFU-+tXP%c;1c|0-uUA!N1mt-BD z37z9D#<O88$xgD5iJSut?ZhG=QAM8VDH0CDr&l`&X^>Y$7f@vU4NXJ0<zkTELfqE# z;l88y0*+LeiEUc8PZ(#TlGO+in&a0uohV*1P33UKsQmV&yeX@w?wSku2FjVMaEay1 zLp_zzJv{~#ljf42hMx!Q6=0yO9Ba4V{eY_KLyNph{L25~-JocHw6MIJlR|%tu(F#I zV}DKtJ~<(5K;lAnTl<i$IZye+U%}zg?#Jo36!!1+%In^T*KRoBLN_3%LW~{utCQBN z$>ajWfI=hV09UX1X)MI|+wS`lHK7!QPU#?IhS)k;!6ty8LXnA4`Ww5A0wu%T40@2s zH)Ed|z1oug5W<03746sF#7e+JKNKR=)Fa&-7eSIC&oiRAji$Bs{k!r(NOTV?pf&^V zxipUo*+BIEW6TDr+XN=y%<?t?=N>5CC=}7GfW9Wh8^i6IjEc+e(Gy{==$ZyJvK4>r zdZb=h$+AP&GMGD_V8~<zbK<o0o`Cgf4;-#E=ntMk<8jbbe~Z)7yt+phOmvH4(Rni^ zTKOV_LAT$$bMPCkfTrQ`P{lB^s7Wg=E9Xt04PJ6*K-jXKQ_&AzL`82BR>Qaox+H)* zEx&&LOqbX7$3rWrQ1nTey9<cLCtE^KDOoD?(w7iSb%|=3RL1Y-@2VMni^<A~x1l&- zLB&3zQgQcrjy*7%kC&k-m)Lpjzh09-(_Kag?wK=702d?Y7=A{$S<!a{WAU}=?sj!~ zI)rJ+NA6-_+=*ryqv$?7$d;g?vdUgmw~JC`*l*iu(OrLr)HOe28M=Tw==8~e!&K6C zLpg5l4*f|3K)PlAy5HDEXNLvJ)*SJ<F8NxaG5>x{a+MNg*orfXH3`_f!fDi0JB>_S zVgL>|^sdfaRR6x-vWwrUhoF>h+BETI;C)|YJ77>VX37?o<NbsuRz2MqPSw8BS5tHy zD5e89@*^$Bs)?##l)+0#uSPPvs7@<w46}r`aUJr&Y*>>Ht!*4w((zrQ45=0*`X0cp zjk@GyY<4@@Cu0UlJZ;LV3on#+(Sz@*rue(amRMdhAD_pJRMr}7Xzytfzd!8h&B*^Q z_QJI655*v^K(Wb-i7nXPUQ)hk8RIP)09Qu;y?aOh0hKt})@tIuPa>>jJo>+dV<(bz z$`{*hz2#Wb;>^8xi}{9B9IFYPO6%LQzx)>R4XgCtDuHbe7c1s@Oyr6C&0b(~6X1k< zn$(~FMvG#v$Cyz#c+IWCx;G_RinYXS5!Hk-AOANH$q08KweL%}mB-o5f+f6ULWbN* zRvP+|o&x+o@OrK9FuqWf{CPKiQXTle5(D|KTJuTzS{_r@%UC&K=ll$O$e|`Drn;Y% z$J7lQ*CIG>YsC9>Aq{g%U>c3vqQsXa^5pp(5sPAbQqWp5xfV@eozzLD$`|5-|C0O? zLi?+OBTE4@y(SG!GcOYXtg6Pe%-cEnuPF0gZ5gV=(VRF*uYWwMEC?i7kU3|}x=D@- z?<2$ehasR?;;qZkCP)zt)tjWDV!QpWd%;eex0t+ICQ@A7q<Y}P9m$S;nJ|7Fu=R_w z>vRBu!b5~3n?CYW9ZQ7o75G#%T)XN*jP@NMU-y4YPWYySSLkg-7Z5~$PGp~b`}c=S z)I-iEFz!IL?@KaK|2a@_lOac#Iu|vzdodW@rvB~kxXgYFw8>WougA%(la+>0AE&C$ z*6~R)3Vp>RH-x|TB?E6{^>8)|K+%+VzKrz)C@5tADye%;oJfumSVO*kuFM~$b{_p- zjW0Kht|9&?(n7;sK54<7j!-67e#0tx(`rv^!OP|aZr1T-1rauR-^)_f%rZQa2CakF zkQ2g!I=MezI^In+CWfI#9HYsV`AYY+{tbRZR5KtnrpzEcdg4b!8Xd&hoYy<S>V0}q z@w#9!Hiypv?Ua=La`b<JZ(QXRcM1dn56XJKoo3<NP{I${`VeHNiWDT+1vaO|k&j;} z-{r|EAx&(>_FR&?$4_TRWjbio91$7?511mc35VOI)1xxIcY2Chbyj-%pmBS)fcamp zmUI5N#{xOZ<<H9lGM?YS3x@(P>{&08>^w$%_XafYnvVq%OmIoE(C|<`xLxa&sz?(n zn)$EC#20mZUqHKZyvM}+a#>~~+~g|{Jc!}vCQhN&J|wh$jaP6V^>$PY6+5-ga)a%O zG_@{Yn~N3fx9Q&SIW3$x1M+JIKZ6~E`0a54@W|i;qi+?U3_`C99>Hd5+(W;HA5F`U zH&$H18B{kK)VBj(Ro(<Mj1=LZtMR7xt1nshX+*XYk!*?wA-Rf;O5LP;08*J8=yxRX ziGH2vF$p6cKi~FzPaRXT1<4~B0uMZ5Ea)0b%C{#+)z11Zk!THC@eD^@O_l+NT1jKv zql*)cAzs4P4dDOteJA}#t^%erI%M&6`Zh^$?cbk9&raji9Z~QBJkcnb6u1=<(L?;Y z+g#4Z!9B?GL+y>MQ`sAq=()4bN!CE@3<gt|kBK5|nxeyLJzh=tsTuO3>Ug~-VN|0P zYnondEyU3`!RT-GiDm~|paX9)-%DL=d}Gu0!2ji0O^)t?Ayy~!Ctf(cFB5#8u*X@+ zQ7slro64=y`(aEwXRtB5)`NZoksGvHEVabKaLNLR<b2EDnWa6(p0}8_VP!NfKAmtG z`O)liiJT%<)o*R`sQN7?s)2_Mw!5m0Y-+G~5Nu3jFBzTolnq;>qu#Z?<j~RB4}mtS zvz>LuO}9rMS0<b46nYGMcSIK>q*NI8pTXRx0lXnYtKDBzqCzWL;d~CPR$aeL^Ur>2 zxWc#enKp-!E}B`;$Hq0(4SJqb=*HX|nKP!?ok7*k(j2F$tM-^w_9`2q^=Q`uD4xVe z5xQm-zJ@S541#%$*rGjyO5AO>Rq#bMcAACdsq#JB&#C;vq+^I!o4}v%q|$;ik!f#7 z$U}kyFwQ63kZcqE5_p>^GcIc?kn5YAvZH&FoIvoEmB!2;d2LIJ*gi7v3}FS)*9r5* zu;E(}2OK-~H{<sLIC*L@(n8X8<l?9)tFH+YCBE-8R=REOS3*lZT9vVDl^!bTr_jk5 zxzv4-xsT(|S}FRtX4%4!nXFu`&E-Dz?`2N)vB4O;D9IL?)PrT8I;@LO(;^@iNZZW} zs-5ZiYi1c)F`&jNj=29?j-lyqu_&S+5G7$>nh3A;x_iRjvL3R+Vr|&x#lHk)mV9Ig zTA-5Mf`7^r)2V;d5&epLnsR_*7azghgyvH#Rg`oD{;dMQ_Rz~w*3+Y+fdw;or$Y(| zIV?-{gP{G!?>D(jbOAs`5f;y<?O?Ig2N?xhO)|tOzpHwe`<63zz-PuLKod&kh-EEt z&3MS_|3fDT{j`XBX@z9zLO4e}b%SEsFGS4crh7oBlqH@nu33B@yWbL7tPTf$XM6f; zmi`YZch6K^$Qwc{PhKmB5kk1iH{w&7r-w}1&;0e%xqKK{@#&QVw;0xAyma<RKr{w6 zoZv%A-3t9qb4Sy}XjYV?-Y_07!5_=$aA-zHT{c^gNNupb4tC(&CYp##m&R;sv6y7N zjN@)%MX<73=o;5iQ)0^WE>fhtKN4{Je(-r2k>B<&M;HVB7^sA3KV*HBCbc>t#6LKy z)woB$RHI4yl;Q!oTZC}#H1vkqu)3)<|L_Zu$a!&UX%=f9j3;l3w?jA*79_<LyyKPd zcSMy8*Bm}OIdl`jT}?*keC|2+CYkR~!5u2Ft6Yjk=DZOJ<htj-gY1yvferb`1k@h9 z=L#coG5G?ta&%M+m~-dZ`egS&0Mu97*Yxx+AIkM~yR}pcMpKDd?;&ZGz&S@~-*`OL zId-=3P5}Z(#o4oShuNIX=Pb0)gBQOIYPsZlHVj1JrUK)r6Fi=%v5H?4k2Z{p$6;<8 zMo%IMEI;E>dxii@@~dL9r4J|eNL%HvmZ<jdMFSGrz+k6lv5~aipi@d?ED`xy$Qq+- zwwieV+Bv<d<0V(BjmqCruifh_Jl)S}(b7dcmugXTD!$>}A#R2y>goO)wukKZ;|I0^ z-{nz-z3#8nn}b3<d+ndjGO41U3%aPYLucNgrDfKefmq=mg@*og%+>88alRjIxT6|* z@#cQucpBah7jY~lQHT?@K_*D!MLA(gfYXTC|3NV6G5*U$?VCLHptH@J+iUrwy2x#J z5=_hNfY;>ehZcq0<IT<-AomLYQll7rDkspbrk+lHOJyP5qryWuRih*xB-Hxr25;XQ z(~UJO(iai5ka}`EvMGRszji_o)k6&+?h9kVdmky5$B#+JBu6$+85=7iPd2~2izo1w z0~a3P#@r=QN9<RYEpl$l1td?bl6<H2^=s6|Ere5`+noR9H0<hf{~eBbnGIg`tS`Zl z-_c8ZnVvGU@8}xig+(oe9u(@6x#p*8VI72$$uF({(ZOD><<SY=pw=WuVd3xpkuHdS zudG0ScdKk{FsJJ#dCPvT1>2tWBJcB39u_@&+0zUtFV3!7>w%21LpeN-$K9OFJ-&BC z*uUt_51}=R-#FOUdhOcnjwEiZevp3CP!IGYK8#XLMyW(=i8g3s%!&6fTMvO8*)mov z3*)o@TRsIy8MhHFK0L(%;CF&E3>3mryl*CL&XE5yhTO0U#&^{1E0>5d!G(|>M}kWT z#aXU~HVpk46lsq;tq&r^j=obr;l7Xj3&g-#aq4cOC0mA9`O1OBeL+lEb5XRO!)yVn zrGvbJ<fx&2lyY@DWnPy5Db#K*D<sukEnwDs;^_%b!=Z0+d|NQk+bB4M1{5>49|B80 z%1*riZ@PG-e88W>7HR0DOeqmumb<MZ_9l0^aV+sWq2P7Rn%ld5F$Ho;^C_BS#fd1| zb5f<pY0%s)elBwMJ3Rt@iRe+AkeSl*g*~UNYj8N=F-{;sK?(muy1~yAvZupI{t0%k zmqW1cnbOXFsfCT#m3%*ZLYnJaPf`n|dX{uLBy<Y|&HaM#6Mg65#o_lH9GYm%aR=19 zgR$8%h}-OkH@->MV6**iW$or{8R$oK#UPJla@skFNHYwiMv$9N8lsl^JL>!4Js|*C zp!l1I4q$1KUpmxQZeGi+II$tGysikoEj^HG8c|;k2Vi?51-R_@40y-)^K>@@2r<I{ z9uEr#Lm*T!+G`D(7C+g($9w7Fh2@iB6oiv4mU#W6?m>Ma)ni^fD;%Ih)>#0LtThq$ zIWy|bmQEzu>3`2?xdnulj$6TSdvf`IntVJx?IF8m+~}htAMsDL4=p3hYeWW<Fx7fA zj!snSoz}%`C;V*CxFqT~*w|-)Raq!N2s)L9*xCW6e_PeR#j~*TD!KZHrD}?24)ezv zp{G&BKN&w!z+1_(Ss)@)pnzY8IJTyons=@Y4Tdm5`DW!P-tV(Vytk9sb}CaAIsRd| z56&s6+&KJzr}DhDlYo9)M>6l2-$Ax~r%-FHu*td*7Sd=mXp0@E`riH1a|&WX&ifOP z1(w6^XFUD*7mV@^OST^_30hhok)6or6^@Et?})b3zPEgzsPbs>d|oCMUs=`R{PYqD z*Zkp=YZ8xvT+8*Cf$FD9D%Ag8_T;e7^Q@KMTgi>zlt!ZEm>dkP;$oO6qU!~JE1ja| z?ON`BN4$CE9mPGY;|CR5@5Z^fj<HD#!}&+)7a?7nufmr{a_9N}=+A%eHZUDt#6J26 z=NUZE#|XvQ#ZQSd_s0mym3=<&oC~3{e?MKBsuYgVQx$c57!dHNg3?_sZk$ep6aEs4 z{6Tlf9(2iH5t4)VF1qX2wx?eEL&(-oiveBKi))nf#dAwhPA!*w%}JoHgz0gyTFJCh zB;KL_`PoF5zkh?DZJ(|%St}<4^<kmn<k1ekpd-gFL0g~dZ4Hx)@V|M1%dkZfj`>_8 zmj=MedX8MuNF3sSj2+P`CM{IE;Q1<zIx8G~GWdRIit0d?8Q92T0fyjar0@#TfECUm z>2ANpsq?Bi`m@`2ON!^PcD;B*phP6zH_znTR~chZ0xgheFuRAHp!^pS$oXOBJjyS= ze7>&bX;o}3!{BmGtMAl{k(C`{yL0E9xG5I|pfd<vAunql3Cj0^aqusepPMhhzmK0@ ztU!}e)sVGchw5J$A<_BN&&*wu`xzblb(OhqG+gbC1QIXN;ZaT39VW4C*~;o&`V3F= z5i>7^Wms?F*=qRqVVM4#oVX<^%c#ZC+#QD3s)8W!Pv?jdJ5DNQ8ChKQ*w34L`9X{E zxH$I_@t)u0SJfUARlWF~7dG0Ls(;=&d3>piLLry}dGd35gzyuLpcL+-KG5HLChuKB z#F@XykBEql8X{k$YH8R1HD}u)96QJ72H1y)q{WxkGFdoZu8Do7sD&gv<Kri}+8A?{ zeS3<2=YN-|a>0H7lP-nY$8jj@K!$_Oz@u=3-Z@{EF6V<tDK($H0LY+hoi$cuh+4|g z8QxXUYuZBa*HSuiN$M+z=Mw`9`j0#4VcC31(1?t+#M773?xZmr@vT&g4^C9GhO=Ji zPMVm)W25RPpZ8_u<R!tUlizS`+tm~Eu;epxw|$%@@odErv_G(QTyVWjQtSH4mrfa6 zZmLne%NO>rUdOY7<m796b=s&?GiaYPasENqj94AA#8e#A!a<8v0fRVw$~g2*NHS$e zaM|G%*7-nn1PzcQp;`RYJkd}*h%a37pn4ZQ^S;?e`>O<<dSx|B2h+~?Pr)mQ)n#p$ z4&DQ!4S7LOZ_KlhI&nvJaKtJFRHG)a5||niPhvc6v4J8MqPG`9i}VAu!vC)+b^RNn zr6+h7iUvKy?9r(A{*CsMaD<u8u!;{LvyxBl1*@Hfb*t#Bf9f=lk#H6$zUh7GrC39E zD_+{;cc?xC_vE3X5O!asz!_}e*0a|4IzeJk%#3cV_ny`@pk(R+&;#d#m~9+Ke-}Xd zR`J=qQp=gymT{sf8T(q@*8Y^(I1z6Sko6O6jb+wrV$_Y@U6?zQ4!)Xzue6lRa{&yU z;TvoQMYf)$#e-?(a$!{vz#mAB4Xe?PGwoq9ls7$9tLdAq%z3i_nN)>Pzx|@tQ}THY zO_cpjHi$^Y2P+b0^F9A{%6=6ha{G`}gFl{+d9&#gPkE3q23T3yIPXLDP8Q=FazYNW zHXgv#un?S*6JWcfOtG_*l!$A@%I!X0J&wA|jm_Oytu=v0Ew-=DP`di5Kw!{DLytuR zL1H7c?O!#W+R5yuZwAc~VU1E%32GS!Ub#>*b}XO5@u4U0Zb_uM3l5=EKM{y*%%Z@L zlJA;8e|f&(IpbVec>-&&Jcy0c$PUcwSxKd1l?!^Q;6siUw5k-w(r$W9x|R=Y)tPKn z54yMS4Vx7jAJx&tQMq!mvW3<1!ANNVNE?xhfqNy;K2|#2zYomnLD;S^nIOSdos`q; zp}g;ZcvP--jCx%LP|YF~CBgVl$zm>6GW9f`rbS7|*y;W!U`mxnIr#tqD$#bFM2-hi zd@xk(&vk0BH!1O-ue`Fd0N_;92{;~V4=yk?9>WzbH*+SB$N^Kg1UC4hPgY`cRL^^I z3(@Y!hRLC0zKXc|XEOsABu~7Ho{#hR=qWVl`vJA&WsMj{y4>w;Oot%OaXB177jE0< z@|tDJMmFF7$vW2Q)xY;e_s1q=wo>VF=Ome%Y)c1MwJ36vpX%Szx->~a9x56wXxjr{ zvA#MylVnKta>22tLm6@So6@OS1xAVh7Tk<ksWnnhu3|~&z%nV3C*-Rg@>a$6s8+sJ zx6!1m?1oX!u6MGh9+E`U4dsy<Uw2`v_fqke`ODxD{>Zh_P21HsV^M_=L90eb)ep*s zL10-y5E-9q-@<YKXCcLSZN@Nwh;}~^BjRH*@W*??a{Q~N|1B5w;OWYO+6W)A?jVyH zm-_}!p+f9%){9YrkQdnBiR#NZxeEj{>c{&D(}L>1U=C?@K@jX*{`yw<^P~%d;#Y!h zHJ{*>rAL#RlRXcKHWHGrrM)J8GheqcBR6P?FTC_Uf+5#>t{vjXt<+kGls^mH``EI? z3Ra5(-oM4m1;P=8I6Z+o-)Pq}>>O!iac1Jz`Kwt6{X;R8&C4k^c@o8r%J0sQ0kB4M zn08R%mBWWe+eF!)aDG4hfL6LQ)defgPJzw`Vww)!7&?OFBe|?sza8>bep=Y~P((ic zh;XA?pHUkQLaL~Hw1`6u<tx1)npCSiqQ4|dY$eWeeF{BZu#m%tkS%J}#03s*Ykyml zfUCd1gf5=(HK?_`tfHq-$nfUBP!`c~1;K#s35fhFi}F78@I0iPpRp#?h8A!EIn{kP zMo*pbM51zIDF7VhYf{+J<u^PHX%)w=hYDu`P8y52_IN9|xBvb3dHhaV(Ft5?_Mp3_ zYG848|FO^mw6^Hiyk^(HjZ#!kakk8QJ@6eDFR<~JbB9oWM-uN#X}_y2W+Z+<P9tQe zpdeD$>`x<K0@KROv9yn~sCE^-xG_l|8PL>O3#K|KiEIN~Ve6af+*{(~7&1P!Zk?=3 zz<60Jy8_8yj+vZ1pR7mso1^uw0u0```9Y=(-iFoAe~WhIFOfIe(gQlGG(8anGdMkm z9bOaoQ`9c~$9X=~vHk%I?E|#o%&;#DD}aAj=Vd)uNwxKlln|mecM+{pt{3Y1tYm%o zc>Nzo@1x?RFz7?zw!3vQ|4jVqmrYshH~zHo`r?;cg#RtQH1^}U*w2ZigP<+H<Ki{@ zkgdWDuNqsQs(QzP=iCc@5(o}mdQ%CxL6%ztjgG6)qASx9oXNbe^zMsjsXgkn;CTXB ztu||NT@gX#NJgC_j{4^*l3(4LeS{S&M0LR#iB##~{&V-2;FYL{h(cEozeuvjgsKT9 z$@Pr~^*W_UQ>R(x79Q`+@x+wXYdQSLn4=jAC$HC{@1m`bXyx1cUGIialj*Jp4zHZo zWd2jKm74`UC%t%ObySLc9k#4PK7&6~(}EuJVbm&n^n3@F_z(j=SByLZG(qzAY78K? z%!Iko8G;QbMq8D#G&VvECIvw}Vc8CKoYy3D4O`UhI(Dwf$8aV)wF!xa5h}<2ei=FZ znO&}lc{ewc-_|~5L+=QeQ-a+X8q%4E5`n&KN3+4#!N_7juXgoTU;^_#2|vJ<f46JK z$>DBNw^;xrq9C;;e)Pu1<#~i0j72>td0)`vi|tHBGyCXe7iL7LuC^ec5od%-v{%RW zU`|H*ny+|rV6EVn|2GRDZlH->O*Wug?TZO$2JA5XR9||02r@_|WJ#VF)d<dmS*;VD z0#>n78wDEuLoM<f8fVrf6~!Cname<IO1Mf7A3~4LTjudi5OXSyvGc$unzB`E4+-ip zF-#dujp*rOE~E^9_QwDC_5_ex#zzJAUqR>XIT#eS0%Nbxf5~-!{X&OsAzP<*KpaL! zo)Laot#tvzRG*AcOG0|wC=7oCvM}*2(K+$qMxl>ze4SvIye~?Qv00f%`A7KIA4)9- zh#b0`o%UwxGBSp>#<QQVuv!zPqboK4$ubb3XhprI2QPz+lL=~&`|muRe@yz_Fo-o_ zt$(Nbsl(BM1sKyUk=VD2Id-^G{lC=bA_0D5MgRH@1_tbdhxR%_I!@2Gm4<e?Th^17 zN7K(0ey_fi`6L`QXv*P7(*caeZ}FHUmx2W}1yh81%ugQ=2lpizee`dw;eZ8t|E@+l z<v3}{&#YEh|5Mx1_qHTSJ%X6<i!TKrZC-vwg;b|1UyAIR&NH0-Ji4C?2la2KZ%<@D z*M_@*EPm3EpxGp$Z`_ZUn)s-!OkTT(Bc{Ocbcn)BSXDhB_wYTU8swkNBZB}vQfU9$ zze_Gb9^F`&$0PD&6u#5bj9@vS2L=gPf8BH8GhZZA0)?inxD1BL?=$SLn0gN%!7@Jq z^~op_Vr#@Y=MRt&s6pp8t@~qz|4_Gm$QP3y8-6+M(CtqGd4-H$%p{Go5me3RYYm;g zQ-k_G)e3wjCQVD9i)zqRz>fymIR!8>Wx`$w<4(m`yX~^0Z+1wghts2N^JTee<DdYT zEbkZO5w5XIo*B>kt*<Yh&+CN2fMh8Y>9h8_X(=OmB#co3JDJ_zC11G{IKmIW*Un@L zQ#KbzJA96phh2M5D8rLG8ay)=SQYzy37lMptKjR5fnf3<_-hCq*%Cbr6ghNWrrsHA zOjX(<UzV%)RLdyHW~+lDY;r?6b)MHd1Wz|OcSPMVYd4z!WJvY2?lQ~kl&>FCHpqW} zy~Gix>o|EVf4cS!4@4Zg%bl_$%_dNH8(NK2zde-FO;KPS6Ac?gO45+CZ$uXVfbWt) zKwheF!9=7>5m)RzqI$VU7<K*P2mP6a1dTR2{TrHS?$WPw2`yDdnIE-vy^$oe9K4g% z3g3@91dxYY^59(_pl-yhG@OClcgY3#B*_5=0AE^admUx)Kd{xc>5N+_UbqudbdOD~ zc<s)E4c9NJm^|7<9alZ>yGCKOsH&H8fmzflT4vv!9rsQUmLUz`65Y&n;d1)wJtm9% zM-$brupg7EG4{R|!k@?1bzXZzSUIk}l3&6mM%B%vd^fh3siK0i)(u-nJEk<C(~qxY zxoUENIRN*QJEUR_oPd~_Jb?Go_Xt#x#6XuXl4AKW<NTir-#3*yE2&#>S+b;&y`R<Q zK2gBkMU<$y&0mUk+m{fUms-k8h02q^!XBo6rttmchJGw_%|{h6m?I3i-6qaC%387E zkA15<>ARmkpwfzR#n2t1lb4mnlAZgxCVujh(JO`@3*(5m&+)_-^r4a5+$e9IxZGHq zT=Nq*?C)dE3vWE*R2`M1^Xw%6nol~0FXU4wq4Tt#)j+90d6Q^sn$By7zTq(?<12Fl z@lwS?wc-=1pzSvihH!9CIhIn?sU0!#n=R5zboy5|tM|-hp&ee^%H8cF=Ob$2F=sjQ zkm}&`YiDWPF<bEq>^*_xDl~d{ZZPPqTJKb$o2Ei}zjJ+iZPc8tLL0Gguo`2~a`vt& z0R9)r_#2!O$C505pj-2;8`-4>&5#gF1ZuACMZpHej5@p;oRjr&E;Aha6W>Q=|I@uU zVS)G>;Tvhv7NJxXH(_a(*B8NV2bhE5h!--6y?E}u5!*r*)Mn}tui*!mz;W2~i~{&# zcVWx1Yc;n9$h`hXpLvlUh{Gd{MtK#8mHk49|7<UtozvxldM$ZTNALfEX!6?4rrS?} zBSJ5GNZrPG=DE;3Fk-jx;7vp74`>9=$=l?56HHt=?S6#o`EmL?Mg|i__2b}joSJ~$ zFnk*M9Qs@%)dE&v#d$H3*awFb`5hIs22B)@wuSvrIV-F`_K4ZEtT@+-{mJ*a<k}bf za6ozjY4H75HQ|l*4<$?w#bLMf3;*}mpICJOfy9Nq=(tpvfV!34^acGPTS&x}uV9a| z`HHfqKo>V8Tab=zTR+Y#?1rVfe`9asE4y(qWB~FVfazST)uilkWa<oNdk3Seyp^jV zf$c<(wc!b?OH(zKc#6LS?||OXWN?!PDez+#<rj%GMK`~kP8%|0xamQ1KZ9=AY2Ryh zhwT}<%NhJ3djQ#S(UJ~B*S7ESo>qckU72#+gC=^hm9$;5SE*T^hNPBf2Y<gqqkYLE z<G&8ck(I0o_Yba*V?XPQGY_**sy?iD>#D3l^KUViAuEeyC-T913n_cb<90|o=b7@E z|B_Zw8=TXa!@Ee7v-<X`jvHL0qd-6^g`M&3m|(Z_<61J%Aol$Jhn4#bJv~7UG4}K2 z!SmS9y?~+AAF>fp+*AF*Ykc=Dl8Mi0Jug;2>D;8#4kRRw6>PZ836#Hp6O6j}?eRO* z#9RePSB4p*erbaYmgdU^RhLmBG`R?{-JTk-Co6bYWP-`+-iFlQ&es}~xIMKJH?K`X zgYqpq<sPvble)LQ$t#^nu*nF}`l*AV-fz}XOLMI2;mNs)HFD`z=+0$Z1pU!FQ~5wA zTUnG?^D1{z)+18NQLa}c1gUap*Am<TGzDJ#T2Q3=nDvgDRsqPK0%IPqR0hcN#)iYM z0=kB3|C}24r;W&}Cecvww~L;M)A8PoaDvKyczWz`+x-oAT99F8MnOi!mMzoFpZu&w z6df1Wx9M5f)<zMBOa0^eX!&eRWWBJV;c~c_d;8PW7~d|v`*M0f{?fp@%UVL+^apJ! zdzvBs9C3!yO`o4_0k|K`SDxx+Y!<6qSGM?iD%t*>&1?*ytVCA!lu?Eo8Lm1tKpFia zHx}QF28s*+OS7h?*&;dSIaG@C+}ZxcEp_bwfr;MzHWU4%Xw77$7z17MX%ciAu<Id6 z!RP#&X$6LO{5Q2doKiRD(6>MPl@In55^|9eEaFT^FxMT36VzaEL(oVu!~L|AILjt; z!4a<RG4a~6j+?+s!$IEBY4F8PLDk{|ZkTlACrjDbvG*S0pT~3fqSi$s1q#Aq?J+P4 zhU;%tptgK1W9$Eur4qq7S3sV}85&4Q?$^0k`BK||9xE5|v*5_)Gqxv@6;I^zi;J_h z;FDH;0N$*4t^WLcx6tCn*mb*wCFn9!zP8PgY<)h05;o8C)g10R+%13i!KkPH7CC%c zCpu$$dc()_$xUjaaL%7WxZz0#D_ilOBZamnUUxYB&JCG2xG!hUDrcCJhG28&8jnG- zY@A<X=X=rZbcLs3z5%l|RAF!5NRfyR65ZzibW93U%iwh!r}}2mN%6w0$wwkhr$pI$ zcRXKJqY5!tED=`KQ+blOLbJTwp#$ekT#Gb~OB17Z)CpohPOcDW*5sk&>*(uC51{#? z$#o$^IVAFzES;yo4FpBzQwpP0r0=k~c6&>dJLL1MvzJDlkmbF{$^o=f6{7D-oqc7% zIm)Z5Z(+v{XChGSTlmGq*`G|UNKtqm3lo#o(NZInulPwNy!&!dE^X)rbv6k$FkeZE z5chMX=SW=Be-Wmuh`Bp!O<dtGzP<rX=LB}<_a0hB-3YQc+mfeb6tYLE@r3ErbE3^I z8v%brN-pvl`&x{F56{rE4zL<`PfJ7;D<!4Be?KV1Q!*8=ltgOX6Ar#=J06OB3%@+b z%5HN0#W{c&bv>P{-3Ba#*T~^3DI#~LM3fd&rB7hK?CuY@y7W9~bjimRJ7VW7k@a0N zV4=~PTTQ{ID1eb_*M&53)bi}zuvpc)D8#eKZfIEVCL$aUG+TT-Eoz2<-FaR9b0nhV zVP;~2n3$NTzI<6Z@2mbc)PK*WkOU!4;%E`IS~)&VmSDHCa7?pSgJcoP?(uozjo5)V z4rtL00j7^I>R1D2Ds-bCPSAPc7P;8QgHT5ezrKWz;Eijy?Fdal(8GG?lVJI%I20RM zMiv$GLL<U?hU}CR5EsBq2fwjN2ob&VdIQV4cfnsnG7|ZU;4D%vL2VrExx$yA38@6< ze8^tIpmVQh0eFrnkq;*&KQ6Mqg%DhC^;HgZGd!;^YmJRJzM7&nA7ltuNuwDPt4~tb z(i)mIvOGGUFW{<H+Vt|peAkZDdOPp6kXiyC9jP2R`6!8dW)0stA?S<pemm&5Nt%va z;0)M~8fGwcziY6~kCdb12n$0;vd;Y@PMwPjQv;j%krR#Z93r~gPi<R>Ulcb<h}{C% zapRWd?%5D+&HOy9d89riCg6P74VIDwqgJ0)&fzrtN@xa91WU&jVG@%>KALJl`F!h( zupvi^@KGFRq6BS3qiFUdQ1=3ZYC9yyNU6Vx*vuYsIcirKb|C1|s=%vxu|3%iCU52~ zX5r9EQ*CZ;a>E{Z9ykp~2Yn;>m%F7o64zt<{9b1*q%fG37!kR*Pez45)q9IgSY3r{ z34-cH(&9n3D-OS7C~bf?$(xQJ=Bi#>hrf3VTUwgC=i}$Wk$BeF&nXF)PyOvkT`~$5 zsgo`M4|e=T9_wAeW}AAXB=uezypq@5(9)UWLmw8XcR67<Ea@y>SZD+KZfwL@dX!Z& z^Bicd)l!t<$1jt<idu%7H{!sCFV^C&TGHH4xPY_(jV*bzD6svkH__JJ-124|@!rgR zGtcDl@^EqbZ;e#Q%VkQWtL7W?znKHwshxf@mFm(u%uN=;TOMzoe(})h=;;Og%!DJg zX<eYw33&JrF-Q(_S^(2LP9Hb!A)oHQ)2zlMj$s)jjHNgsL2%fUH#Y<CZUY*F)9kK- zq@*7&^^&P2-g`S-%@-?SWp_8#Dd)Fq83mNw7A!BXivT8C`Fp~u9$x(NkhIo(D%RHA zx+k-Ke)Wgfy7i6I8i=<v7!1lDq8I-aE?0H3L9ox0GZtBI*#Tmc4zBK_1>nRfoX-jX zPj@ny$@{Y@6<X^R(N7Y!tvvkvzyH=$)ruO7{`swVCPS;RSRtmJH(RMlJ9DoIwUhoh zO~{tKM}^oV97WC*26><VZX;Mwv^WFCPB3-o699!3`pl|({#Pk5rAPt*NXN5Pbhl8R zwBIdQmQ8QgPe}JgW9%O-m{^MEA7EurX`Ya&o=_cb^9&%U%1WSF10G)qC4eg2^`p0W z%G=#<D}wXu0u{2;s67={G(C<fN_MJ})h^<BD&^hZ57#623ua7Qia7?g+wKkY-3@nF zp+K6r`T7jz6DCdi?QM<R+@8<v<+N6-$H_rOZZ1W3xA17c*SsiMz~B7tw6SadtX6)? z#@Y3+gzf&*oAFq0M%gLUKp#igbIb&vE8Ia`<{xwxX8;?do+X4xY()LSDflRHZftVB z47{DbjuBkue(4c#G1h|H*Jo(q+e79Ek8=lPI+_Pd6QwCvZQ`dIBs;aCE7d?GoDh1R zBV~8+fm%IkxZ3af4jbknKRLiCo~7ot`q5MWcH&(@HbX8bLS!&pWtS}AHGFzH^gNH4 zn7E~Dsmx2VIZB;JoftMRO3hr(^;E!7n`tXvV!qY5vPIB$2+Ue)xYV*ljgPC-D)ksh z+WgAERWQ9c_&IJA?1Wa?T%*n0L<*?>^au3xpZeYHKi8Y}JD%4qla5I;Ah)H4Uw>=f zOc_7guNL3Vr?uJ$ecL&z?C<KDJzDuBN;EkjSSXwMp~k}FIcAkgj&NF>u!t}U|A%nF zbf{4R0{E`<9#TAD%v!S~2s|SI-iFd>C&UE8n%*qOGODDuz^~rqwsyG|N+_QBqbWSc zYT~Dlf=bZs=O!+Y$)1KNTX2-UIW^zCLbWoqFcp_I5A4UBRoTkj**_#Ue1CyU_2u}; zX6In|?Ha*XWJohFs^pnV#PWdUd;5^v%{XauICuldslLt6TP}+!e|goxw+sseks`eF zt_8{^ABs3?YutqiH&LZwCyGwgk<k*ZkgsSp!XRK+ou6;;NVOm6I$F(q2#9&eKbn!& zfBc>t{JMbN5Dnek3OnHNZ%D_@tWI-vwmmr(8Fznw!iwQjrOkR*sBz2W6;AgnW%AYK zwk}86&;Z9K#7Ff0Ez7b}IOl>3>@UqcU0k6DR+!eYTCYIOw>F*p=>zWGuQ)wLqAM>I zj{^G>g@t72m7@Zq+wk?Y+unA;+-|q&&%|XtXIncTFILyqjDR<UpAF@DoCGr`7H@Pt z97nCX``_jE8V&RnZX<L!XdW(pXzN^xgPscZ%qel@k!l#D5_0EaqY+VByz>E7;Ge@U zGf95vb!?f>zh$sXKyYSO9&uVpeVUM}uHhI7qa^t_v%F?32!2WfV1X0G-Q!%(2p;O3 zS)l$w%$wz{xA%ds#?lo|>n?qwjOF!GXgT|CcQ)2@&kO#^i7&QdEd+C;5w(yvVpU1j zj0U(Q(4=eM4I6kJaejpW1Tdeq+rbF<Wiiw?2mTWL)V%UI^n^vqb(*x*ZPklpXE$?# zV=vzT7I{75f1{%VpVcuqmnL=;yJ>l`9YhDvSp`;#8ZQRXecv~lM;lRu`!}st#mP?x z4zzRIGk~53K65?1VB5hw_Iiu}NCg?&<jpfjnalE97+@DIS94}!j)Uu414(CTFgWtJ zPhZ21DL*FTBX_4gZ&f1t)nJ*@%4%d;c13!5LC`}A<@6=8wuQ+(4?{~>!<_wdkIsRQ z8c<L8RX+`4<v5!Wh~&Od+kn$vw6i%C*Oj)eW2*wSOct;4<n9R>1Qij>tMERZZlcFx z#>?AXRm~F^ePXvr4rjf!(1i>iFJFh)67%IIQF6I+3jG$hbT7Bo6)GJt5#9qWJ&#vn zq8Cz%X~!rn^cj#0M|tY+=47`-aC3A|=)UN3LJFa^#m19?dv<33n0;qYP8)I>F)?wC zHokhd?zjBLQ~UsyyDormN-6i0%9iZcmGQ7H=L*Aed4+zsY(o`4F(pigp|`&1CsIIL zJ)+$S<{hX_pxgS*(yVnDb^Dz~Qr^5UXqRF^^Jtr9o`)~CPN*h<6)cy?7aK<tgkIDA z)Mhq6FLm90)U+%L$P~!RJP)dx=N`ssL2b<`Kl1x-S00nTgss^((?qx0P~Wt86{So8 zW6{~h5J8?Q4!zKNYy(Qrplq@ef10skwCgR+06NIZkCWqkCXnaPME^nfMjy0~F-<a3 zWG$et>cHM)@ZqHUge>hbo695;5OJ#kyzdqNTK*hL-JiRO>VU(Vl;L{XNOp%~uZJep zD8)S7SltDm#tC$7q1!y1Jw}X;^B-M6J0tAi#e`n%U1qrGp$ZOA{m}TPJz54I2{l*O z1Rug4j+(sz-F^GU)x35$ANco7(`lM(bX!vKY(901OTl-M@Yu`tmD<0_LfUL&#Tn_# zwp9@?3_pxYVGyRR)_J`5@o@p-efRjVjegh-`AtiNq98b;=6HO4b?7OBY4h=B{U&MX zN&P)nZ+`;OD)-a$iCavA+^3ocvH{EB*)QrFKBwJx2OlL<m-RrUs(LMuHpnbRxXHmZ z8h($xsa<=tt3m4nk0rvA*X#wby0RcR+t9godwjlYs7L@lL34vT2&D<V)M-9}Gpn6{ zlt2t5kp=tgA|~FA@&3IwqygNv+rw(Ka###JRf_uWzyF3=p+)PXD?ZXhSlsfBsNp>{ zyM%G*p&3Kx=)U0P3V<jKeBP*1a+kVRd_#-lh2Q6i)#$8c&5fN8l;2P6zRa=Ds+*s| zu4au^0qY-Mr%gos{-Q3`cG3ODiD)!*;lg}$zzw!;Q!yIT`5pl|mHuVhDut3RI{Q0m z$gp=M#rXv^V#Flj4N<jR2Zul6B+(vr#bk&EFRH%v;N(I95gW|d=<kSxO+!vOp8Qw5 z&~`^}&Dwm}SzhI6*E~K>_%Bbg1Y9Mgrc1(GiR&Lj2^8#qsjQSJ$1r(*!~$9U0h(p( z9g+E3S*SgGJ&X`fCm4FDe!z`~R1@X<N3)h89Mmn}9!nteg}ES=YJ6l#?8bsu+$KrD zZj4=<D(b{04aStihf*6MKhyu9NlyH$X%YFq*(o1)JM>GxuY!DlH%$>Ye)7ZP1@Wjx z&zD4CDJP^-&HTj0ddGI(7X+I?EV=~n&25oi2ab}hpB3^`%0b>(uOazhoO7j{-%#UE z*pA>0YWQL@0x4d-*hq+aoN*Mz1<xHA;h|pHM*V2zhE%N&Ke&BMwBdXP1N_W$Lh8nI zJh9t;<oza)j}i=6dM1oz;JJ<oAA13@EmEC|K`}?(&HpWiA5Aq*kH<$+&p`d>%Nx&y zCBZ(@-&UJxT8qdE49~{f`Lh8QtEC2Kn)N$0g|h-5TU#A?l(zk^xQ)k7H;Pp-kf2{+ z44&ejq(ro!3g9kyGlIA?Nvd525y$IwClbbKM>{kkIVcK5+Ur}EL)p3E&eNsz0s_-j zt_O*T&YQInG0vv|V#NHXL#9L+e%<`B%9|_ymF@E&OprY1cKB-49Yi9|6<OBm<}98F zxJ~p-u>c6$@?fMw$3x)Ld^^uxSw65J_EB(^)$07uFCbG@%Qyw-fIFo##8whdWbrKk zH2W1CchHXRnyT#@`PWXi+_mWaUk2wk=Rl+8GNoeZ3W5FmtCtR85A2A+w^m<8PgRt5 z-=l|pGYxr>3(^A8Xgzz<v1^PR=}_^ViGq{4M#X3VcaUL-hjlT>f%SPy*wIvUcS4vh zd_Y&mcd;r?+pIpz^%aABO{vI50t&_Z4<fnC2>~k<AlA?Afn1M3^XK31(;yml^TKn= ztHexC&A{<?@c(Ssw;_N!{cKo%G*@WkSw`J5D|a=fjhMDWsWG!Iz6bXSBEo|Q&pYLJ z-&d;Ndf=@C)7<ixo1f4a{^b-ul<h{0Z~g|^*?l30#*e&_2NDMBnV56*D~W@%kQti0 z53a8^w~&f3Hq7A%0reOGVQ226p&k`x^K&GKhvV)01|5>GhE+du_-t3WpKNP9;^#l% z4_MwtRr&GUgo1rCz(5mcn<#mq`}t<8q`Vif_tt_c15+SP!erGH{zM;KZ9w@+LJA{$ zXF?;~6sUSca>GBU`)&Wt3SMm!UPwg1%7Vkb)v!H9l(k)YAM>?~JW<B?Ig&<D#1w<G z^Zo8Rkm$DR&a{#ixPj)#KgMxe2|YHy$LVkxVXzAsLfl0dERcOTsLr{<^Yk2OEQt}b zUyYKsc*+M|*2W)`!=ZYFru{yD3DvDbgqJT`zyZ>%Rea&yUO!P*DZMegBZf6-kzc{j zoq7v$!#Q{WO29=BESZP^z<1&WZR0a@Q=*b~U4Gjwp+OAWJg<C7=9RWs@(btn7Ji?` zga_5pS?dgq2&gVvBH+~%mdGH`a>CQ<d)=cGMj><;_}UipO7GJJ5Qn!BN&0arMB2`^ zjAKay-MACXkrVbu=fJ{`*UMo#aHDU=5db^XY7X}x|Ba5wUqcaJY)<Mn-Y@H1+V|M} zp1(mMz}$oebRi`16estn+7dp+p0$AKVwWXTz#w2~XS3_F#^pd)mVouixytS6K>C5H zXIcW0lLP$*7)-u|zu!R+jXK2AI5*9x`)L-irepX?*MocW(9L^5WQ;Ff;0S*lt2!9M zc8eEzs;ReJxdU9KE4&CuNUI4FZpXZBA!$a)0W%=GoiA6&MfpQ&>B-eNXn_<vNTU`> z`vrzxDeNs1WR__9fdRX;L_|@(2Xof{CX0-_!#bBW!dYvOEr7l6Ms8Y!s%50EE$bap zR8HW)cK^uypSEhdJ@|~Oql#xdQx*ZT;2%@x5HO+j@k4f43M-$a3kYi49Q-ykAGo=J z@1DF#u<t)BQx$776^3QFiPtsrjQ5>ES4bcxCZ>Q+jGVvLXRxEjd3fn<8jTc1V`HPc zxy*eV69B2ryaPz;1LD<uz<7E?YImYKS1E7Wr=IrJ|2av#bslTf{N7Uh!Sx`>w*0=g zQ)n`>E#&_@NKT_5El-d!oHjr<i*c}ZO9#FlT=|vlDRQ}Tq#M+8WAJu2cHS$o|2L2< zH7}<Tt+<2aiT<(R2Zk)u09TscCI{2zWZSUA0dj{CunoA=BBa~^aJ>=?{DF0$Cp|b| zx+i_lrAO6HyOihKS7eG5+mfjYif7Cuf8Dh>Jlnxm$*cRvjk^aqf*{4$6HM~6@0nk3 zW5AuKAmxA)moGvBOyQQHR|Y!pgI<XN1WEkX$+F9E_XY(p_)6~#Dlqo!CT%webo8Jh z=!Lc%D$W$i!Dy_*cG)CQM!;RGxrMkM!r(QIC*K(-B>wC`3pkK0$~9Ntls3A~CvNfF z5`VpO6m?T+9h7Vq;*CogjZYc=sqTGH2yVV6auD8zGUTkZUWcd=u&biG?mOpT>7N*5 z@YY^VSpK)$fdz`+pRgC&vxJ)A$=f%QJMZ}e2EV<vm7bXy<-XcBd(ajg4f*ru&&K^h zjY?QpSm#jHGON{HgMLWYovOCv^=|F2G}z&3ndX_lC^T%*Jb~8#KkM}f3Mw&&!C%vc z`i4u^jU4H|kP<n0yJ%dEk2#Ya&TQgMX+5)@Hj{1k(D~O$DXlg*3`DmtvQu#0#1HDc z@htw)$=u<KPVAt|i_}wg)j8MMzmi$@|7HPDLC^_X<T*{X3aa8f6|dr;U6(FCl-Y_! zh`ynrP5&d0)p7)3bG1JZdemOMQgnB(Ue@TT;KxFh&WzeOjWgSR&^x>FsVG1ko(?tN zE+1hEyK(fAaca>^G(#PdF6t~TQ8wHXaM18Rg5hVu?{cjAPm6GPgNzk?PACSLn`LdP zN0k-f=5*&F7?%0KDFCeLR*R#=k?n-(0arYVbCLxh(1YNkJEn{?*>!*X%Ct+SQ53Fj zcjc+F>6QVa4$h#{)z=@xhlgLTc=q8e)D3jj(-oJLyvxr&I=4lPuyb<{7Rp6^cb(@> zvu#a`KON?**(i#mIbX^-Hf?sNR!*hbyS7E>RH)sqPxoFebPpc(JF07L<lo?J|6#xB z^2q*O8wxq@suxqn^FUwhJ8`B<aK0seMG&&KiX1*`JxIB}irhZkS$gB2JZsAI61dXt z)!9T+bwdRz?eo+ENCY6Y>2174mYr=P0StM~;2AEvHU(IFvJ+)C?()L#F-x~(_<ttK z*!E=bXcbRvX#C7+%?<`=6S$N?fZeb=Hg!A7au~-h&AR0W&RchGM<Bv2A{DUp|Mc_@ z<@xH5EQ@WsA3QeT^J+`tZo<TXfdzpQetz{y1pJ8<(b6LN=kH%H&L`jf9f;52!aLU$ znTxWmZoeZ_fWH2BkZ~G@Pl8|^;)058qDk`Gi;TZ-X=Z*K`sbwL$3HVzzuv@A#4N{- zp~;xU=J$dviuyN^Dj)A2HIW9}yiyLHC(ltf&b*X?=~>{~>8IG%=Z;$V+dF^DNZ9FT zj13*QRNyX*+1DFs#sw)Jou?aKw@!=z0zty!6SryCzMwnwN~$UNF7@^Q;pr>mqUyeI z&(Pg1Dbms)%@7hwN-8ZN-HpTyf}}_*4bmkcAR$PHN=kQ0cQeGyJ-qk+?+3s5gMD_a zz1Fjy^{mYc8rj=_G~sbe(TXYqW(;$e0x!8IJz}SYDzOPXaN@MZhE1hP&4eX(CxFz4 z>S7R_uZGX5LG28~+nKcn9O@E8+M#)LF0XGoV9pO-ZU?lTXjB(5bU?I{Zt|<~=8I#d z6grb0)Vdh)DzXnIuU{XKB=6t9r2Bql+qlNc_Pve76`JRpCw`TSBY%_&y4{;th`jqJ z+a@;Oy%h!2J4&wCJ>8wj5z;3mRx)Nlz%Ri{LCpP$V%(C_(hd!=g@31D&^u&@M;`rE z;|I~$@X*jj;}!NFDVWmhR9P$Hjh`OC0QPr$PM!v<+pM|jZK+Fx2@JI2wZ~3WKa>3D z*e+JcBd7bX1DpO3${84>tA{<<%^7{~mB`48@RDjPpGg@M&0dx=u}6DMg|Ga9Cd9Sv zZt|-jXz4XJgLGA3V2_H5>i_d+O-Rsfvf`EBzXTO=>%z*tJ*N-!5@b{{JzsZK2<%8i ze32g@S}0q7+3WEJ7ncDlj)P_xNANspOA`8EN|VW2RsiAh@uVd4hz7_2eJeLV^g!39 zQ3-<hwfMV(jix3@MOZPXz~RQtXO^o^e?%b$<&+?|E$>np07ZAuxbmcoiwfayJtHep zPwN!q@jl{29zqug-<mE{gBx+x2HU(bIj*v*5qF;of@1Dx!e@6hECz;n7n>efF_uH( z-I%fXm_)Zc(B--to$mhJ9Jj5HJP|Knm|M{}Vxo3L%hcp>X+1Zncvai`HFYs~55|?< zLX--H$=)Y=l;2i)I5<=&VANcAUCFk1N8799w`98VubLQqp|_sel|&$ETRrKtMpw&F zJgb_x`v+pWh#N2X<b#R0?VX49vj_v}=FHPn*sm2jts~R*UD%wUTYJ;sJ4XM1q>qii z4}5+3Q|ETKvDRw&7IAt!Z53CVnYQWS;UQqzjnfc=Izo2n-=YqeFt41VHhbFK*Lqbo zG?ea3oh|;JTj!fT)xsHroR1%OYeDbAG%}ui$?Lp(7K9m4ezaF%F1R~$!MM5W`dGgS z2e<8$aZ7TeXVRL?B1NPCefwBtP$~Ysa8ie59j@|hWgcc>L>(-3E*L@BxA_sSW8B4C zw0x6?y%5{b28}A!EpGO11#RM#l9IA%9HZrGHO3F5%370CZYHbD<5s#N0`zX7SH4FS zD2^Py_D!_~exzg;(f0OsBMNylTCBxnvRyRjP`|oc)z%9xbs<}k^;sA{bU!wGA%CHH z(VUcaBzJu?{!y?k=VQd1CwOY#0~q_GHgqE%|6JWx;%i0IP8AwI{Qx&`4_vA>x^N}! zf#L)mot&mV8EjSl`#A=>Ji80`Ki#;$D1(FNSNEwhOap<J!->4Rx$GOtk~#*t<6N+M zVfYwS0D{$6n*kc9#THt%&wNT<;e@*~m3ac{Fc)Hq9_&wCexz1UUY0KydwX%2Y(M~u zZ;s>_rVc=A7)y4cr{*8=pG?ggG7p-1$pe=ztWr|H-2$l(9P=!#tb&@arkYI11zZ=U z)w88vg;wlvh>1~mMG!~K>@7a3S-HE-zsle-$j{p%1W`xMQSKEvX}13cE$C7GMbf+m zQU#}*JUMi9cVVh?2k*EmhWI=JoM3NCeGW^171n(?gz%|g2v0d&P~NMU^cWzFOmoys zlN1RoxY^+d22V+gnM;`lzjudH`u07oF_)bi6{v#ztu4C><A$M4FcFIpg?Mfb5k{{< zE6mXYk3PUCV2r*<EooD@k_**+jRJXd2;M&0_&1*oVWv8kmJh+JA4<xqJbp7fwJ7oL z_zKx;R7?25|7r*+4ZeTzC`{~BoG66Q<Bh~J<pY46tO~MxJQLqCg*1-a3$rX;rPDn! zttY~~wBDC@_rAM?#zjW9m+6;})Y@uM3h53bG}`BzJdeA{wd}I~Qm%u$U~&s3$XkUX zN&~@Y(#Hh*Aa&R>wolIoR$wt=sCdgRli;R^6!``*z{=pIqmNtcuQz$pF9teZnjE7a z{;mQjWaCi&hj*@vr-V~}?_4v!uL8jmud0&xAi$R|UtZQ&Vpg_(T5>XVeXg$F9S22j ziS@vyt6#fNqcU#TS3_-^u{4fhfp2BMeaiCMeVe5j@gASrvNH_VWz$W91vR|rA7QA^ z>wIf^b9NT?D0w76m-I0wbJ)W{GdpgdJ)AtW%UXBdDM$I%i^Uh@BudrHxo}P#?$%2( zRV`Jipdc7C&Lfu1J<*$gnbyI>o;jQ8dv^yczh;CTCkGz?V4$U?wfkG}O#3oO^z%h- zrfU1MRzf*_Y-a0Ns}M&bAnYw*Au171wIr{<!Bp@Rv0=V-mRfDon-d`rV0v^DV^jNT z>N)$on>Y@(Ep0bQkyh;8LjCF<RBYrDbIOFMdLYwk&!te{s%i3-WB)oUG8YsTt%4<3 z+?{NHsC7h7|El)tV`C!K=FqM5?s}DEeTi)%Quv|ldhvc+n+X|yRINUteVP}Yx=}kT zwnMkK1$khE=dZKWqc@&Dw8*<VP1DPt7qgCyTMrWv`U70r-pH<@D(KMCW>TuS{vZN& z@{1!}3YBjXj9A}V_~F|=wYkw$;~j96)~wol$P*HC<OHx_7_nz-ei=VKBo8cKPtFm~ z>6^rVc=TF+LOu&wHLZ~0@wzifsDapbXr7>0>?*HKh0!0QVexG_#6Ymma~$zGW!tfj z!6%qoHt_Ln7F4M`XV}+z9eT=hH-s9~g7)+$uzJtsMp)o$8CGzM^d}zmyi%ScntoWr z^ZvsG<G%R1Ux#k+PFOc4g+bkO$xww28p=7t_#MHOU#v^}?L)WA0sU327e>+-(^h9# zf*jR;$E$BwZn=!^0%fCaipr!=q^uuqd=2`lUw6fWspQf5gC`Sht4=#L?N1?q!_IQ~ zc2aSRfBLdrq<Fx$vH`){^&U5-dF7(MFb=58uf7V=j>8+@!$k(yp9mW{MQxh9+mk>1 z&xc?m5?trp`>>_9Cl(u1*O_g<tUDu^f?x80lyHRs&-K|h`O*20%gHwMcP$4&NB%?! z+dXr-B(7S8@sjHgf6i(xowk|nlfX~5e%j!I!VAq@%Nsno$+j+z9dg7QM)kA@xBs?# zV;@)zWlBUwORj&X&hJlTQxmZ6CrSRaGq=m&VTNZT?auD>>3ZdsL-SQt-3e;1c31%P zq6<&7N!0Q87lW?Zp~{j&9`8th_KiM#fzmF9#mg|=ZNClhUix}LzE#=o4^))JxoR>3 zx0+>rVNAN4&MLvL+*F*6z8VA~)<3JNsR{RUV*#J|OrybwvTKGQmf*)^lJT)=eTC4< z{Ki<jvE>+B`||M>_+>Yc6W#qD68(wS7%R~ES?QFxVkeCuturu^Y5717=Lh=w1mC}M z6a^lJ*|k5OsxY9_*_7l{^&Xdhqhh${b`T-IbO{zL^KG?e^NZ5RUxB1&IN^h$fOTl& zCh4ZRxdD=#y<7rCD{Qk|R$lqn8J+F;IHaL4C1tF>TZydlq>Y))^l0p1ND&bb{AwSm zQJ?da<%_fg+t4I%9JU5qn3-GQ!CjOPNa%Q7OdU5&9Gtnu_SxheE;&1m1*s<m-X`j} z?t1O^Fsp^pJUIXR2{H91F>{GvSFpLv1B@fFzve`7p2BHnA9zWhz33pcEW_h^TF;Zu z4UN@NPz~|aV^UA-6erreNGW)$?svTO{zoX|`5XueTEK8?a%Riic6*}M>W0+&8hoi~ z7B>?;gaXr)apzD{jME=+(FV{YW*yuy7x*$7+?L98!3=m-rd7xXcpaE&fG0x?JK*oI zg<%;gmD|(F-X1AFV&g)U3Qgqh-119{31vd{%a^XOr?@0gppTK>%Y*`Z3&v}sCw-A0 z^B!DN*=rMFpuvkU$h|P*uXC8H>`W&v%Wm|ztB{aYG`TjW%Ah)^3A^;sA66Mu2O~%D zVe4g{d0TM!bT{zl6K@xIbF_8xs;UA&lfU}6lmOl?1LPW$NkrAgjw7bj&TUoWD&E2q znqS~~q5XXF)xBP6)0;8Q6MuUfuCY3sw1qRM_l7F>w^k8~f-6)m>RT^s$Eddc2F=0V z{*lz~ROGMg&d-juHAoA$wmHo#$rTV7i1a_SnfdmHM$)S!@f3A-3>tZ>Y*YZFwkOg& z@K|YD61LnwQY>db(}MiI@_aj_uj#!yf5#}vD8?q5oZkKz;U7TcqjNsDJ6a~PDkC`{ z(9dTyJNG~^P5o*)l=$Ile5UHt2?Vh;N7G`({m93}6<t%O<C&=S&*qhLSoyD-JlHPw zaBqcYf11{XOol-#qt6T8##+vCJE|_vm;E%`Ccn1poiM=3EV^#*b>C5DigO$`(ve}8 z_Vb*9SbxSayz<@5@?FjJRP`xMO}aXtGEe!7yc>SrTZ}p&`cZ!%1<TR0T>W?cd<e?Q z%36^H1zN6m%H>UAnsM!YSW`;#>va%0ax`=90_nR!{k6v&u-3oDB9fR{m=?N0%=Q2? zn@NBKP~!OSv;WbBEB3o)4v_xRl0FWTr<!mLzS$QeV34GUAZD8MMzwn;9?y`UcOe3T z$b6UDG=0l+CLENMm9hAK><KMA33~@ByDUJA0Wo)Na1_sX%nYG=4|Um8{_78Dtm5tf zVbz-{6#8YH6=%=R5u;hl_65d3c1!C~%0wG^(T=3+Z8Ot)_HuamJqV4ADPQ8JVZGXK zSh{yr3q!E>nS`1Xex7u-wOfv_U74=uUvF7^5I1+h^WIaYM}BBIza?^A@hYNW=m{Us z4BOXc<%^~sRq}>uqtepvzWuFfNzunl9zM`;E9iV3rJo`Z?#Sf){C#PVhuXrGwZ2<< z@!8o~HQh%Y!(2C{Fe5Q+6IL*BNU1H3a{a06iTrH#w$$Z;LJt^eVnN`5<vm>3^?=q| z!+OQt<>A=3bb8f~I!x|-N&o~Nzg2Y2yn`lpDc@Z796ZOhDfE&fjNp=_B6~k1Vw140 zB=}n(!h>yd302YWj-=p0{Wvf#|92}aEX>-8u(h^cUWs5L+R09~=E1ti&$y-g)tF`c z>|FKxc%isAaI}>l=Ky~TjBtK@0=O~cKB(#+m&IIX45a(F1KXRf5kFO5|3~3TUp547 zRY4!{yB&DDe!Cf*^L014d?Gqc*mgBhjc?RhvE*u}yvl9Cd#dA*_+We@qwhO>(4cJ$ zrE*My4R8taCW}5A(RiLIAaowKWT1|U<z*(xzh?eT06+6z{zZhed&wS%uv?cGZw+ZP zp(nzoM$)zyJWJ9xF{#)!OJYCz$H1^sT^bt{i?ex{(&(877Pi1s^`0Z){&~H_bDwCs z__}3DMB!4+3lycv8z?cFT?Sv>d3ieO<WHajEb&L(i3u8Us99VHeCe=Q98U9V)C-1_ zy_Xfgxco8vO(%8nR9u_^R>SpuE%hqZ9R0ub%-UZ|1_uR4{b4eB&l_;o_U~Z_f+=mk zjp#IZ<nUHlNa$fFVmL#L7(_{Uvk3I|f4I)14~$_dfT42dS^*D+I$J*gz<W5fXodqU z0cO#4fVnqa)fh<a*+w;YSBOe*auQ4D#zaSV{`-{#o+L6cG4UNJqRLgH4r035L!;&k zu%Pr|<RrdcRCPm|Rdq9vPwiwM+1AboI8IhXPM_w;1U%tuyY*-^>4>Y5X;q`|{a|Nw z`u?2YcNE-5jlj}*$2MElKN<jZd~|~3JP4fW`UfF$S@LLpzW#1OsD`CrDLT>B-<J7c zzSsknkG-%VulzL$a;^fj<>d;*QBsG-<pJxi;P*T?)J?obm71M#D9wWrY#@6@tM_B+ zMP9zTAEIf@Lg?5&lVi=@nRP-f%0-jKvlIKSAe!(?CL~uKg$}=A-X~5dmHBkY*E@6@ z4X<jLak|g<2<svt3J)-zKFvWb@xUlIq4$e&N8V%3bx=K0sv`BpdG}i8x<OJ}a}|JF zfbm){3ldMJ05Iq?#nWq~;w1+AoxIB+9}eReM&j_Lyaf&L3z+?4z3QUZa&X`dzTW0o z5dCjSO};%`j%W|_hL?EUZ^A^ce16VmqmEX(?rq3sFum~KZQs%;ouTPu*mPNQ=#(eU z-@`{^YEfVMfquR|Uo?7rAp51zH!dY?IS&d`tajs6%<ZBZh)}(Xd=oa*X^8mhEei&_ zW~N=P(!ej8SL7sI_NY0IiVk1s##Zx^P3`N8y&2Nc9Wlqr#~&DFj2cecu20zgj?89H z&2|{c%r0ex>h%(N0n*EXxcrY_%RXWPHdSp5A>#H}?OC-k>M^CJKTR^w8~BeV+g^8t ze*u#-QS<(I%Wj|hQ<^)__eFxq=@@tqQzbl$5>MOq@|69MzxYU6_RU!tFI|Mb7L>3* zVh#D?|M7eqmCv3_Kh!gmXdyh7g}J{1<PIIJ&n}x)_%3*Vmj5ImD&NFF@@xoogL$2a z8pVYvMi5Qhk1Xm)1-j$>IfS`%9jV#d@E9ao&u-pa=M#IX?pZp{T~(Hkh-(-cfV;je zL&$lF>VU|ZzE&~Ae8R|$e{~IR@=7N@zsShLB6b}eoocrgg#~#zpAdX%Xd|Q4pA;>s zs!wk2$ONH(D&Fg`;}K=Qb;Ov3%_ft8nV2)7abjozYgse^XGV`-wkrVx=s{){h-vnZ z&aaovDnVe+qt0HB>-j<Qx4fJS>GkDdoJPhLk+KBd`_oIm+w<Ru@`_u2+TI~^V#X;K zoz`y7Xh2S{1`{|3m>09lxQ~g0nOYEDm=x;!g0?|s?NjOM?DJk@8dyeM7@-cYm%k`R z2-uA<J1uF74Q1p_46hwq&HLRAEx9z@BVp2&duNbrfHXAwOH(D?2YyA?m9GGLCI4z7 zK`sG8qHhg^J$2MK1sz_4c!mlv1$px3^J`!E<yI8PeMn!34QPMG6?a<(K!C28h?{G7 zF7@riJO&Zt;k^LfzWB7XsE$zV-R~@V1DO)!Qzo8-EoN1fH~h4dIAb{nzXOoX2}f_g z^^YggKXM-Bzyh@H{9d6)Q?+AY-`lF{rJ|KX9Hue;yXN4ttx>F3oh7-=3~pN^EbIF~ za~;a)wptrj4=Yf=`ZF-ly)~NeErn8x5bONYa$?xKOLVZ8q${5Y0alsrF4D!94}o^4 z@9`ps93(CfKYVeZ1RsMOn09(%;@(3EZdZwRhP+&(I7&6`=rcHNL91R)2^31^&rl9p zP6QvI>Ln7!yw&D4ojC|^LkDo%JP<z@$j~#=TpkrPL>@%+juZL6VXXMWjeB(sE}4~u zr9&=;M&BWy9o~ufu@F4(F-*5Gw6x-8alh|^D~G4UP(u$ScyTfKYfm}4c1L|v_4Kvt z(G>C|-0HC8@YYEcaeZcq0Ag3jQ)#FxKO7qA>+>ixy|;uIU-Ev(&v&V{N#xdVT^ZW2 z@Pq$0Y#zFaAA!I~<*DNisM7toTlqut7eWhGhJT14UuCU;0CK|ka$_Hd0i1PS;P)L2 z-T>^N{qdo~4*XhVPb#PsE1|%Nht6eur<aM!l<>T_8xYP!gMvV|P1yF4^4={WTnHV2 z|9fcxxg`hWp0D%5#f`s}b>q5`TKuaG)LMqL&)DV+_92yNlqWH?B~b2bQ(Ki6(4AXs zBKnfKaP5SIgfDvguo<P;qmx?cm0_H~Y$w&y!%H1XK@14sc1r~(`K=<UG`Dr(QuqT6 z8Qo?5R()$G#XKZ5!W3dYT#oARj!cJt%kzI^kIFbOGUd-ife(x(U)-vgjD}^keYsk> z#F`@X=C=I01A$}Eq4#|Ua$7=}tP1ggz(OzR<079cZ{Ou|7(gRn0S7&Xvf?XpZ37YF z9tnQM3B*$1rNd(*`YWJpEeZ^6VoQPKf<yOU;s_Dge8A+cL@tf8rnaM#g0UXoMEBQ4 z3IT*6u<t-JI^3=kkh}H+v<qq-T$gDxOG-F1gDz%3tD+%P(vUk`+_ac*)l!t$haJ+f zZ9;8_G9z(RK_q~00=qkJ&O-I`j7=jVaBzd#^2>5dAn>Q$;2S*1@u|lc$&~px=)mim zBzwX7t{vuC6nN3l%O@OiMb$aAWu=&Zkg)bvc7JCGVWRhzW*km%Krwk2-LVcLKvhzG z^B9t~O1;Zd%L{Zz55uYx>=Q5mG%i|N!wiv_PswN{OhW2Sm=@8_fL$PsdV$XBiKQ0F z8tmp`-|>F@7hiGve|f$hk1ekb&~iH+Gv$N2v{==H3B*Q*D~KTO>5k`^uzYap^hxh4 z)eicp;IoICK#_B7e8H<boAt9ccJ=Cv6b@V_#ni{uBFwa!{o`nkwa-I$P=_<M#qPZV zEGpho%i7=ZKgZ!ple>xRqsDaVWl$icx!Vj)4m|FmZanUN;9Y#DVwx6iJA;UzNRpsU zSKeeAOvilUncN(&B{F_1TTrs|)OhV#FF9jetG+LoG<a1EauZ$|X^f5Js}Q4qeeD1$ zQqWAm**D(tF9ac9ym*l+<?HfP{GKU#X}=D==Jr9>hwzp?Xe#Q;W7JL!QXRcbzed99 zL|@FLCPnQG*srL*anxMip8Lok^^lKmNX{{JwsT7zJ{M%YjymN>G@r#)f*RW~?**pk zvZ!0ndk_4a2W87>yJ`Ml+Uo77BboJl;SrkyUBStQjFO0l(8VX)&Urb1SyEkmr$6}8 zfcS1jEkRvasq=^581yrzQ*9@4A3yfC_@6$sTt|VzYA(v#*rs$tWc~YJnFIl6P5+u7 z$r{>4rH5$~0jd|Qn#wqj&RP@9J_}N`VfbudngP@Gj)vgUJ0Uyj?V~eDZXT3`=SD7= zhBhA%vz76nMhy#B+E6x|=EmKRVj&no@;|bcmt}C%av_n1lpv7*-K(brn%Zl}%EQ8r zaiW{(OwLOT<hPyqrrMB6ft7a-F&3KH_@ME1hHJ1ju4jwByz*RFI=v@N+`vLRw**Y{ zW{Q!@*!XD=@sp=>n(+`465Mp4Qy3ip6ckS=iREj@7=#CC)C9_5aCG=JMvqT>JkO_H zALQuh=+(iG!-tl`s8C{AZ4czsN2h4poMjeh{rizURi|6#Fo6eoS~}>!BRl32hyXV@ z;zl>SD(yK%*e}azVH!yy3MurTPb4Mjc#Y}=M(Eh*wHY4l5f`<ciCbD)9)Y>k>N|YC z5pNhL0!&`rP6x%h4lj3`QL`^Jj?e0bm|X@e(UcV}*GdJ9V*?rz#sSqw4nT5>lg%0$ zu&k<Pu_KClZ?mQ@*I3)ed4vuJi=u=Yy4mtQPie|TAsrrG!%(tJ6sR|>0<oD%Ryay} zHYy9o%MwQTOoK5*W_EgpokA2qiySSW_>BnY`VM^TTHJ6Fp}VB2h@E?Ye5?$;3GD}t zcG{46M&u-%;CB3Htp#^WFjUaI#~<G3Lpk_J2jbeVY&z*E;)~Q%0@$aXrviND?O){O z{1J>GYz7|x8XWbTH&&&40x6<NBu}8RB%;91hAacQ!TCny+T?<Qf~2*ZC{PFmvK+h0 zqFusqr`a&)+_Y8F&q738gXZsNCWRgii#YDs7OS?urXnNisp$-#1oRYySuW;zNXOPJ zlfN2Ao}A+^&$rV3-6hH*RIdl~bY#FX0GBW#A8CWZoTjTo)Wx1Wp;`*Q;eC5~piyK` z0SZj`KpL)i4iU$&K%nJ53oXET9WpUW`EmNETlYDK%pM2H0Q)&02fVQ1A}PG~wPJ}> zey5cBHB!Qp({hL&Z~MGGtCeB#_U`C2wc=ZJ^Y=n^6w<8^mmM>ntjlW=1d(XxWTJS* zOe434=by?(XO(^!sTipfPpyc3T~i-IQt$h&G_B|dxFQ|p((sSzHtOYyxj40$-|IB1 z3%$$qrFNuxdV1WNWgzA`>Cb%?sK{sNc?swREC8@3T5QZADLF2l1^b^CfX;JcAPVPy z+i2|CN(s`M>{6(=I7(Q6j<P*myOMomT#MXh2WV>QIJYe>;LK6%8E4URL<5T{$6&Sf zX?Iwg@1j5UJ;Up=37azYtvRjg(;f%txzNJ&%zkDN(D}4KrRu-}G9eb4%7>Zo>FJk& zmkYjI6EVnTN{7YZ8|QgYvHN`Jo@xQFa~umUz&wy1)_h5YH6Us8Fb*uvV0#C7czgrn zU4nYGyqt*%{ZBB70a@L9wT};yKt281LYnLKU*-Z2q}dt(hiDrZoY#ESUvU$+c;dMc zS(+{vfvKdTvX<fcvjef2!}Rda*(rEKS1;yVBa*L+Xg@v>BLcN<sA+_-067?81RR<B zfmDYkoOoQ~cep@azJD33r-K6>6$JwWgWy`wlK&<{;k&jummh?#Eyq|=uy6w0R1uah zErFW^06I`uSO_uy0|Cf!CNLrH?(Q$EE#$k!VJUSe=Z1xFP)(PW1y%eY;z&jh2#APh zbueIb3xv3N_};H9_-Y0FY|nnL#T#!i@KmEP1$A}2HiHmOi63c*^^#U-fBLtr50*{< z&;7`^eg|Wx`8bJjwll$FnTeWnZHonqF}j!8D9}ZGq&5#s$b#z9X2Enhtf=6`@V|4@ z#6hFHT>|R41qB7mpUs0yorTd>LB!Q(>bp=lhgb?YZ1r1tPYrH^zQPK!Fia~6Erfrr zj1tTN<+b^xf@=i5Q^3^qf$vgKgUcrLbti@yLReIe6b+~9!WT<!kb($EWnTIGK$qGd zbfL+3NH8&rq&D*lndS~J{Qv}}Cxfsi2OYrb*x&tO5@<oL+u(QqgCLj7q1k=5Jr?!V za_1q15}fSF0qt)&_rK4-1u=B7-NezLRLw0d^Kxo5>~$@mkbUnqEndE6iwaGakmNT6 z9(O-v{RO75NaX9zG|&{)>^qsHVC*kjWTOen&K%$bE&g-bR;j8H=s?lWj-i}VLg`?% z9G(}iKPe=af3ixT$%lJ2tt|e;Uqp{s=8+`uOG%>pK-4`e3Nbf+@dEPs4`#-oO|BAw z6+NhD5IShRGy|EeJzn3{>wqH5!OCULQELb6BzB92R8s0UN;(w`HtB+r%}3ggo8NPa zDds77C&u+{8i=v07L2|BhN<@A`w?~Hr1QJ8>ai+kb+-5Nra7NKN7U7cgjT$!S@Q!O zdP*iLm!~&xSl`!TebUMDPpWpVJz6YT{%Fw)=~<DF#Qp+uWB@>EgTrZP<*%3uiD%@0 zZZo8K{9)#Zi4S+iGcDcT0@p<}CnMwD4&7T28ySsjAElBrQIYP%B*r~qWNqdTdD<vm zAqrnM?UM}IrM%-Cd>}WbFt)gNUe4dlCYJ)i(EyegYq0&}+JNE8AQpc{a(cpw4s3vc z{8<Z#YM!qJ@wc43H3{0i>oyRqj~d(Wisp@|K9?i?tK}M9@bbsXaKTX%TFFRQ{BK&g zHU_Y+2J8DGRaAXSY(<}rOT>E=`sLfVZv=JWukHM|3qON%i!XPz+%%8idhBgE6rDAl z<T-t0`+^eU0H8s;>gi0(tazGvK7D<9z&fnZtYGfgj-e7QdbH(xd9ct++bIxsPdKKE zyXS#v_{l~TIH{HJsm;E36F1djQ`7tQ{PGJ~7|%tyl-yE`^_N8ifTO+Hn0Z(mutop% zSJ<bbixPO%IslKt(91$Cm%CViz9?SDax^`N^RfOxbrls}4i5&N2;>z7QLo<nv+MZF ze<<cGX<KF;I~(Fas`g6LA0PmFJub0xdoFZU_P}j|HwlN=@*$*ZI4);uKO$#qdNHZ= zsKl1$k#z!Ah^0PDabGHs>$Qm1*ie%c`6wMT0W$sFIV0qgzy~`1mZNuxr%aM3Ha^Jn z)Y~pir<tluiz+fOd6uKFCsU9>w@@X7FU76K*^cfCg_EgcG4t@?BM=A>vI|__3wc5R zCcAJ+{J<Z-ve6ywi<0`Ilc|sNir)YV2vG2NoVm~=QfEcKlC`3u3Dm%O%t$<?bI!92 zZ4O>&_68Hx|2qh~#@{v%rYAcFCc$g1VN`+%&zt_l1YuEN82E7pRz98#(;Ehoe{9b& z{{CFaJZ1f%*i`Sa`op6RvfZgFu@Sm(Tq6BVD7Y8y2*Nd7a4)hJX3mfa*7$Pic%ocS zKbC2y{lH-s&$;r;gw<F@K6OgR<=qp6n4>@+Noz;gg)!tgEK~gNHX@EOqTFS)&AEMC z;~U;qLqCu7j{JLypY($T&(>d$2XC|TVkGm4wL~PZkrjQ~B4MCDss~l5_gkrMp`Ihl z0Fr$$=|j-GI^Rq!DcX_h8ghERUB0;PKMM>do|iqRQmnNZoctZ1gsr;Hej^m;A>1L@ z(u9C7rC#9n`bqY5V+Zbog)HrtcIt(XyD$`#lrTZ$A+vBf$1u7jeD+)+Cbe1F{(Xdc zj5W%<)A+>m2F=;%+LFIOyYf4a?-(ZFcG}&hx-l?a0Ixc~xqDgjZdWFC7HouHF3t(= zv@gyo+6}f<qRme8k|8=+c;-Z_Yj||Mg*B7Xs2aWIS*($<fx013Ja>lch^=rBITVgr zDh#E$M~%D_f9>!qk?sD_MU(zVVSeUoKH%pY=sGKHc*x<%U-L%Y6n>H{mk7x9(*q-b zoB}5{5Rv7@8&Fh$A;imm)}8v;j+((wYPs`0J|TD;(O5-A^|{EklXJS#fTHJ4pW2C^ zl}B0HGKTyn&8dRG;nF4CD#@P!!0rW+T}_B#qVS5!Wn+5-1bMYa4EE^J+@BnlEgFqO z7)j*!SN&(tO?M8TbH!cVveE)9$-~n!>SQUmp-s;e!BnR%lRAg&s9rXQ7!(f(-J4A2 z__*F<qdHYz5^x5gwoHu)p#T;@V$~4u0-=!doKV8JKvNM0$bLhBH{jnu8i<tuBCX$Y zJRv9}vRG{Kzu$|FjyVVcrTdFIQD=&u2K}rtNLC1ZgZKvloGlg|uFC$)lF)&%9n6o> ztEL=5w@yya#l`iq(e29tb8e#m@vzp<v{3k4&5F<`fcW0Sqk4tgB*@W?#&3vRQ!xf3 z(?U&aCL}WO`cV;B*$fVr1?!<;K1)C@O^+c^rfmb<{*4fd{uHo1M|{fwyp++A0Dwo) znO<WzjabYl&$JvU#?L`2w-CfLAA%bN;$N_Q5&$^e*A>f#_Z8p&K@L;37qFyZ#%nY3 z>*=|x>aWt=e{CpAOF5AZd<q++GyJ5z$ZKiB@hWjG&d5|6F}1ZT=c}=~UWhnP7e|DE z><$2rm(qKW{|6Tx9{!7js(BKZ{VX+14pq<#!a`7)ia6bTU`N`u714lBBcl!OYqIT& zekbTP42cW;gPM=4B_#0y@Lw37wd`JR)xQdeOEfO6s4xXt$FmXS6JbNt1-hqst5fUK z`3XqCq@n~HNTvmV>hBK9V0AKEHmWpIFb(}@Fvt{1Q$*rAHnPKUle=l8N*R>^=BJbp z`1m+F{2ku;UDR4lox^>tnem5BXLWKB#Qe}p@?PU|Kf97HQHVP8quyE7bJf6#<UZsU z$j+u~=~hC-_XZ;748L%D5~!&S0ppmJPBbRWm!QJ7>#$f#Cg$}AcmsNBdhP(=7s!{# zBKIwt0RF31;}tEL|C^hMH^|=EbYZ|d#B()ibe@sn=v>NYul;ff<_cPZB04r?pj7q4 zmp=f70sXsVomYKU$A&}z`(;Lu-1Fp;=uL7gV566i#VJt4t$-CUVYH@NF8pjJ)Jqf2 z67GnWT1JAV8d(I&g7JVD)Zx3CzUXss)(UcXEMnzlx;8*A?jlwR>j(RJJR4F!(Y<?B z87QKm0hc?{AqpAz)h$^ekg+8RL<a6Ev$#Eub$jQnW0_y})=c6x0JP6mQkF96N{Q6X z3YN$(3xm%*rrBl-_S1!b0Z%e@&7NeFdEyTr+trWwX}4QgHbr(Mq4uMO<R`Ij_D90? z;!0&I9l>Y$c5MgK-+wi3ptC0I8tIyY47|{ZM2BbomHACa#=&=@g#(BTwmmzCuvG@8 zci|y>Cu?}qsC0j1evW_V^CBdNWa|`hbhQ?De?}uo>FLqnGYH#6XwfI0M|<dE9wa0y z1>K;_qs%5tB==>zov;N&G<1gmKu&Yp1&<bh7kcC4@Wf$M;^P1fB7}Uo8G=?=po+=r zgFJy1i3xeTNMybvWPtsoG`Lis2}tJKX^F@qhyQ*Fkl2t{I2$Ey3)cThA<W2+;^ki6 zy$gokYxU51EorQl)8W@@3U!1AwNdJE)-QP9tSF)j6Vsy#$<glHauArgE%U#*W(q+P z+XP$NR{)<-3_A@oRoIpY^zAnB_wWw%1AYfhn_f%iCaDosvVmzM57{Xmkr$yL%s;Ff znj=YIS+|AHW$?&Ov?ey`^N0XR4?z1f%|gi=?LG|jb`Y!kOEQzYgK9-AkSvZpxG}EV z{jkfS$yyhQi<x|b0^)U_FYB^75COU1<7@8<`~7h=UDH6BiBs0xJw>LK{Of~p#&`Uk zY$)oM{JyJE5KHg_<bFJKY@(-T**{mmQteBw{Y16ImZY}h+ol~ci^?8352YVnFK}`i zLeb?MUIv{^abp9)U=sQ~3cbf`-}uvpy#QNp61Z{0vG&fR(^MwO(%w6I6x3thsRAEf zRG(J0rE1XGLzX+bq?SL+zF}x1PWg6|f(8_SYK7=X>NEM|zVt6yhT=fx?6W{glTlw~ znwxDck^Dju=uAMF%QSNgO?WuibYTTPhtZq`+x=K<^>^&>+i9FO9s5&x@^|Woa>rC} z2)SOYJXzN>N-@L(iVFEJo=2XS5zlK`oE=YVZUVWLg3az~b#55JswDqazh8c{j*_Pm z{6Ghmr#e7McYIFO;rRFa<u7uWMX*YSPYbc@i99b*L!q~abnVP|K`OF7{hSUsnJTB( zd(3QDB73yFvVVl&k<k*n5S9e@cO~SNonQ5vsoaC(o4fmt*cUJ4efLDVwA*=LSO6Ux zRzrz|DA_BKx$QsY*OsCXILJ=51dDy+;-*IR&VFaBqxsGBn4E|}>sgmSE|>g5t@o}$ zHeq`hWy^^z&|ZN1mk9puB$V@#-eB?=UH|&5ERI_UQTBoA-FwT!Rho1x<EiC~4{7}t zMsvazL>|LVAQ>wC0FH~_xEv?({COb7HZELGR?lwMRX?cpxf;{n&AJa);mPvr9Z4WS zEU30V?Wib7k6u}f=wMu>Z7I&!r3q8B*rS!ZYs=<*X9CQMtl|$*<OL|Ucwy1Im<9cy zsvTYc!i5oR7$jiN0RT6zZ11H~Axva%elG7SJ#k(9z>)3O3B=G8+300K4-r!`>Fi@J zEA-;()sdf0rgnbnJ69@@jYE=~VqUxiW6=i9<agfJ4)Ll*edDshs?yc#T7hX_5C7F} zj}_-vSI2{io`k4MR@<TsYLY<<)J!e?lR-&_^;EEkhVY?luW-o+BSO;oD?)T9&cF^> zyWko<#4qMbbP}`+#^N#1K!3m3gz^|KNldXP;U2b}5|NQha9S%wl$~zAYioXH6iV|K ziIRE0%TlN}c^tJ9<X;bgOFZZM3|Bi}xrwoBfY5Jxu})YyVC!$XKFK%++5Fd_X0!W~ zp!&IX#jV7?xtRSd{7LSdZlmTa#pin6;>1;D2R9Q~K+@1~1&NM9fK~1ucZo>wOWZz* z1t6C1x1|Dc&+mI#c{lhriG~wxmmYD|ZJKU^ato?0gBgsoe-0Tgg6i=R>DQE0<+7-1 zo*ZkYHBO^I`igxc@Wy?45Aw`sqbi_*D1argO$Su-y^E^(xU4BIL#aeL!&%mEK%Kan zY^AHk0N})0Z|n>OuAjcwgf~DQlKUXlA9aH1D(=n>$`sS_nU@HcW>X~e4WP~PPe_$> z_>_$pc$)=Ef@p}rbeHV)<}ijrjNa_hVYWgd&~9pG7W~`gr!E#S_E%VqtwS0f)RVD% zF-quE<L!j+=^&KGX!RI08r85YC^^oP7+gYJY~a~;Uv?fLhQgKiESu*aE$?T8!uV{# zdi7nKmzJ(99ndXK1ve^Y1&ht$rw_s3m9tNvQ<+8jmRNISX6w9R;BvTF5XAz5S&~5% zGW|;K2O$aQD0O7Q8UNo}aItpIP(*pWp4;U!zEd<nqtXQ)&{Ni{Jq4K_+Ct;~IA`BU z`Tu{m_L-s)`mC-)!zP#S61oo6civ>!q}QuhNPFE`kD2Oig@aa&@aH-P?Nkl7vpxBu zzL5^a;8a!Xi86h#L;?^aUZWMg@*vpWhDBug_wy}$tzg9rrWbrTW;o^zdBxaorog;6 zP|Scw;oZ?x@b-hG^uLIxr(iS)4?)My%gvRWx|9A_9ITLqgnqj=WJ1LNK|XR2_)M7V zM1=&JHv@ca{$M1}KF-|wtjiuefLATx3vNUV(W{n0Qdu%@&*XadT>aL~hXw4>26e5T zi8ic%)tihb(`mm9VxGdH0HjC6JgMQa&kZ2c#*HBb&BvUb4l9=J0wH7I!3zakI1$ha zVX(2WH6MWW1`aA-qcG3rI^{z?jmWQ7ooO4T?$zlU)^GV-B`zpkbtXyMceu7|FR?wG zmoun!g7fF{+K$zjo`rczkB0IwPguQ+096y<V^rYas{Wun&mH{NwLLDDUtl|&4L%XT zL_!TpF_&uW$*>{kk>6w2o}K$p-D2jL`yVhC#CxK*J~;y9$RRP=(Ss6gFZ$`b7Vo@L z6O&X$)7n>LVC;Y6byjQo7`qmHmk4vJdL>J_w@34_e}dhBRzoOGdW>;mCo1xEcJgAB zCvF)EqT25tV)nod7?GrIgNzt52GIY&pZe07&%a>6mM*8)b_xa>_(~m=+&=m9XRGm& z7pYI2(_Lco?NQy`-QY6-@^TBs`dxmhI9i40h}P+6ZXT5w9wsqAurh6k#Q_@djIp`e z#%w2{SB1pJo+-unIdTN9=wb9AWtGqiR%k{WT+OYmt+ysiT-ISi;PjklY2uN-{(m?N zHbANVAk$V)hp2$V>Td2}={pUHHXU%mvo*Yr2N7LV+<xoBPwDQZ>0mcrwL=P0#PM*k zRjcU)N=t;c!#?VRPsjF`2sM+eu|_V+vVq|pBtUJLtQW|`lG2sjs`Nm6!+?>`4{enC z0(4eo;fCO8vlMo#@wbLS(6N}oj)n$J@JS7HBSa1XHpDy5M}tgG{F;d|2Y>FAs|fXF z+$jl);i;w#X-`Oc|5Tf}1dr=(Iz8aGE?y|R%@u&t`H7%N=-htY{N>A+bL;}qpn82J zFNP0PNs})h`+4o&3rem)lui1eylN{Z6yB_KQ`ase7xGQ?&=-WvZy0a~vb=(Almsp@ zWV*Cf2k<Vk%W@a71lZWxgI#=eG&Y!abj!_cY}o(){d+W`NZhfmgR&6%V!P7$Ui@@G z_;|m;L3jXEszkl2wdrta;MsN~(H2v6BnfTg<SE@K+A~-63ZrUqC6WcIn|_8QU(?yf zS;3Cklbh`fU)4|(KAN!lsGai{DQr8`Ejncq8Xb)%jrf<ewb&|UP?0-mAlM65z(Tlm zi<UuMLpSmcGN@4c>3FU0UKn3(WN&swkMUHNA^mS9GAmnWkI$sIf|ZS1-NkrB=~^Be zND3I{N+7|1*LrAOkUX9E!$f}rgI?xG*StWQUhPj^@VjYgX*A&F#ob<weIS-+SY_t7 z9D=R=f>h5Z7FY0I0ZD6{8G=GywjJG|^MzH0jfhC2ZcqI{4lCE*3%eBnKQHtoCMxg( zRg}4;8jg}%{(+4JBl8N%u55E599dHFq<`@3vv&V&Xc5a>Rmrb5GDSZN@A^K_qE|JX zM2v2pt~70C|M!tXwa=69ya!6}TS)G?V|>0wVD7uK?q4z+o^+ENoK-#=d27=*;y97& zv&C$Q7fAH>qRcmsBo+GAWiGezU7ahdfaKlgOK~E`#gI&$prJxZ%Wz_h$oz|I94XXq zr@8Nhch~1#GMDrDH_J5PL|kk(1F0eRn#->Zi#kT<=x_;HOx^>3On2LhzB6;5l`MS+ zW1Ql5q455EboXQP8e!}kTpN^PUR_={t=`Sj3orlQzgjnw<rEN30Pr%YuqDF{Z6o}b z+u1)$Im(^2Y?ub<3WD31s#;F)z^?mHP>=WQlJk{vtbVz{7qGb3xRLG{pOy8sV$*I0 z^XowX{>Kf5xS-fjV1rX5F)x9{igm&y;D|%DH2AEFA~mQ$k>AgYKc(;pR&=?zHWS~P zT!6Xiw^~WBTxOV4au|RNNzBQK12w(5poe?;{R4Y!-}t~{Yk>Qp=+tti=TJu?n}~5F z?k15+%nu~Cr%CAZr8Q<a1kT56=lG}K%<8Tq=UH8tc^m&E10a4{cPQuf1pdcZ(~Q6l zx=ZlVsDXK+g4k^q>SyrP=sh^>8mP(ZX!hQjXi=ZAe)DD}JK#VbEJlM;41&azB%AvD zUt6Vi(hfplGdla;pvQ5wWH1oXiej0VPe4%<{YYNmU`_x#Jmq}pOnm_X=ch#va?^0D z*&SKl58!s2$%dKK@^uZF$AUE)ERdz^s-H580n@m|?MYvdNEL8jeOhNfhIPNSGbUKZ z`Je10jy1Y-ghg_9C2&gGyzEDTcOGX<@Oo@&Qm$Vg=7!#?T_*F?J4l4Yr5vC#?s_s3 z48O-I?9d2OU%aPM2{5rTeV+v-1Wzj`_?k=7dnXL+Gg$@|#gAahL9fBr_8M2hAB>dg z^W5{UZjvb~arCTTHr?tnuc(}2jWE5Lz$ii-^Gfli4nt>9$d}aTA9?G8f-BW^pF+Um z`P&Wt`00u~cZ%l7Eu2ml#epM8LAp1o5Ay8lF4)?}CQl`fkw)520E{2T>v-qa@TuJ% zkQR&uwJG_=4K7zlUBoLsKYpDJ);zQG`2!pA`)6%u5R`N$j#FaprK%Q|;@5rK9188= zpNNTItA72vUA-{h8~1v>KnKGk`8?uN`|cF9>Ib(aKNDW+RUmxFV$)UnbaS{5l%|dT z3<|iv(VU!|INPVJAu<6M%Lyus@*qRyHUr9skhh3O0k?hRQ@jjcIbdO_e67j#3ZxjB zQ>8VpuhlJZAYLwJO#*s^QT0!IVDLb5eR&ChMD{d-Oq<A-TbgY;y_{k|uXA32c656) z$zhTb)E|6ekn&juJ+g|C5#4>SUz6wNWSLC8hM5_o8SKvcY=4d#Jn7!GIOs?4b(WLO z)HU6avtEvPpF5G%yzQb!S_TX+`$f1gq+b2cxcEsEDgbXPzj`(I+sEX;YnK_&7ZWU{ zPJVAk^-qB>^8r&}H-)lyKv-vim7mX{%494#0Nsy%nD}~=i4p8LvFwf{Z3NpI+&eI- z+nt_FeSa4I4TcIH$daNqhuw)%@tKr(DVWFF(Ivh$4@v$ardT_cy$~#YdG7Mwc*wya z6}fSTdG!W8$fA3E;LT>eyhmoJp66t<ZM96?zpbUJVuJn_b^Y*-Sk~^Fcrd}bpm33M znUO7cDwbc32Uyt8P<+gm(LUzsAZ{gUAA-8Qt(U|mib01u8{_2^EOib4`qjZx)$-2J z%pa4GPNZFl+B7VNuNenyBU91QAw!%h#ExxuM^o}t+l@XP07arOB!a`=p^clKS2BMz zh1|k*vSuTOG7b5M4-j~avo(FzzXZXCd?~c|AZR+}uMiJoK)~YdaF=BsGI%eVhz{wv zHCi;lwTE71O^P#gNiNF2o)k2B(6BPXpsOm%3R-N)*bi^5d5?p75(Nv`3o2OzD|yB@ z#j!<Op|p|K0AB(+5uBjwvkuUy$8<lP6)aHJe)%#IEQT}i7*w=__vyp>pU)9z0Gpbn zVu6|0gViB=H*0jUFgNyG7s1;-1G~(p84^a-`$4xg&@J>EZWfl>#MMNjvN{yQ`#s&0 zocD%M77V18z6v?}eDESqWc?_Wx%JWwPG-4Syn`~?-Yxp3-zH3&=Mo8a(3rCni^O#f zz)2NyL3!a8h$@@Ccf-Nj#VXirq4NCsbJczE=;6&S@PDeoSCgIQ8%cL3zjpmj;YlH0 z9gVSxQx1h#jpQEU;Nb5!PFgH8=eoqx9k#Q{%*8u22T}U%PtC2I=wNi8)NtL|YO<0% zoCP%pqK>ZVK}aq%ZSEhJYD`FJ0j411xFR7!fW&t{<@^a?vB@MpAprx#e<0Gf7SFsM zFCO#!G(#~&b1Qf<$0w6zh`IJ|408C)7Znxdnf~yxTWA(F`tB43y4^2eXR+OMHH(g} zZbD`z!4H{6AF+nH*p?P)5cIG}Nj+$4YP#3=`5Z0=?ZKpc4<7CRnToOTWUjfSw2PNb zuWQ%hZ(-0D+nQugG4a%xRG{1BUpaq%{IPk2RQ1$ai@(`{h?&n|q9!BXy$?~<<?wf^ z+?WB|HG|-CW4|DMg-8n3E|GEyrEQpsWoqE-_06El?ba{b_5adtQ_I55jaO4sQ*HD$ zGA<5!(faM1P~(D&pEP6gr%!nW1&<!buxTmR&L+4a3so822-OAa6pc7jr_0$~WHKs0 zZd*Uu8|-t<80Yzw_WM!Kta}f_`I%_p+1gji%e)eWyAf{OK#6+TMhb=vgn0nue9awP z?G!-fN7I#dlF=lrHvKQ-PLkW0>ObkLN2NC6UB%a!n!{8wZl_IC7}6(W4&N=s61MLC zrv>oal&6^&WN6zn`B*gti+gvXU^@JS3@m+q{`0=G^Qe~h<$z$6>XtWc;<X7x*DG*P zY@Ce$@f;x#jtMbM7lS_|&%_mgGdgb@qUKHv62)NvNpOq&!!xl0U5~d7%?=TTZw|bH zWS&oWziUVGw@Loe4ty$#UAcCYX_;xVPG7;BC=CV`$Pd4NV2n;dHJ(;Ru)kx9`GQNx zo0M*4af2UEmh~a??|k(T&eMnAd%q?~2GXa0NQ>UOknz$w#%KF;N!j7>cZ78?RgO(! zD1`F|ZGfj5!Dv<7qdtj|TGl(Di0S*!*e=cUW)`j*=il&wo1%n0BvXh8@Uq3PhF;)% zErkMxPiHTeoByA9`UQetVZ0%L#WTkbe-G{Yh$0?<`u;fCYtDz6P>>IpJnh}_K=$Q> zlS@p0Eq8<OW;1JlbS2#{8OZs_+0~o$^>^ljv!8Z;2tSdQE28O)`iPN-j%6I!kOZZr zvGhb@<S)q<LN(tY`8>8qjJsnttlM?cCt7-k<wjKvFL@i#BXuUYeKzuplR_{I?n0Yh z<C*L}=?aKvXCrqx`VDo{Ge8zU>>vdnPHq08wR^fOFqdF%2KVsYnq7HFs}eJ0CtyL4 zZgNVpI!s647|PD#x}6^eVz%5DmJ~w{Q}HI35xlNns#oK|@WAPj?sm6IEcTb-BLp1{ z-jm~ePC!2=!KiTdVuIV7I#0>cuzSvaE~|n!J<p5rj<ma;kop!=Qveh8*8Sz))_AoH zmiJb~5TTSDIi1II&z18C*cVgI8c~O+0$IZ^$NktNxhNWOBd>6qFQ!ow?DQC6&>$_x z=$F|0OC}&8{CKuf`YScSjA0hs2-}b*t63AUz9^a63+VYLtVIU*&^?H5^&ENph5Y@i zzG@#Q{62qgM@i=U8B}A!%5ZSJRGnjpN}b&oUa?k-`eGv`tBKk`xoFQ&7fTIG1qt1r z#vDu0DI#*;Lw0Xaa{RkexRuvy<_4UdV$j_qMwoyr@5{#khB2JXj6ATa3}3&uT5NeN zrt&Q{iP#G})2X#*B2kViEZzi{A7#Y-{@lqih!>?8B16cdQ((DQg-pgC->sY{u_~Z- zv^RLfayl&nog`{HtWO*EKbH6`kdAH7S68lzk-3l(@P`3>`_G`K(6(D(@$ODGk&YQR zO|Tv{kbq&M-`O~(Qjp2V;zFSy)Bo~254mB^F+X1U$JfqdXo6kW`CbQTIt$ueU^MLf zg+N!q!<G_tiqj;Vvw8&Y8X|KVSbV23V_YNSO8qUGxWl!b79%|0zFO1?qH;RqR<{$q z^?l*BeS6;=+WbQrmpbQ6xdTw<->_hwNC~Lr_$53o!6OJF*U2Ko0YFu?@=wZTp2y0Q zqP`vGRB4z-U;yEm&xA3H%V_QmEQK;4e$+I$K`*G^u>5$`7atmRmN%1U;W$k{sr=Q# zb)N3RhT*mAEMs~sve4+WfFyalRj6aH(_c6JL!ZbRV^!}M?r+Bz(YQxyInAlv!@5}3 zMdkSVv0paho^xeWE8Hc^0atH)v6OuSl0hh1)a}<D+f1Nz7_40O0B;(Bt@%h222>mG zZOxaUONw3F#?9|uJ}kc?Az~a-c6lZ1p>~>Jm>x0z4UIydqGO$nmn?k3Cc>+`BQqXN zO~>kGB3(!NIL@bn-s++!p=>pz+owDDCgj>TnTtYc^I#*%NvruN=(*yNwsv7<y+>lJ zFe=mY2>6!f7t!Xqe7o%F_u!=dt}9P^udzCalYq`YN^i4@x?wm}$B-*Ji%nIk4U<f& zxO3kpzn}mEY{pNqxibE0@Ki;Gm5-0e=LZ9*TZ@d1RRVh??ju%B6Ui{&g1#Cmy_wh+ z%>g@N;sa^WY?oz`Glb7)V|kyFe3^CYETMgtYddWrOrTPre}n+6yS97b#-AxXo;jDO z)CkN3XVht<)X8fFDiYKRnw2{yK=a&jK)JO$d}HR~2Ky7Ewt{<`w%$fL>@gr%!@6jP zFvf{&8(dXEE3o)AG^`3X2&zUE$9f?FITX2gR9IsH0T94dM?~S;G4yVNLWhGyri8eH z!JZf{fL4YJ1M_T_?;o<kCL~LcTs`tTWAI<7RU)4EK@$E`45kTBr~b6xJI8ZLTXfGQ z4efR-rK&uOuFp3mU$;L`>E~Jq1?iMTyJu0Re7qb<PxmNjkUlN@6%Ep8CvAFf)xf_6 znYj4-|CDsqaZ!CwdnpO&?v$2J=|(!GySuwvQV{q`cS|?YrHIl?FWt3t$MRl(@4x%m zJv(>KoH;YkJTrG22OfiA4b5(|OS3floCtM7oQDSwm|QgveGY6tje|_~0qiC`F5>?M zzM!5iUM^+vRKa>nOX(OT_N5PzF4yh-VDJnPnHbmmcdoyIXKF7)9F^NDO3ho$zeA3m zMb#5-lO1zgZXD7EQaHCG%jJS9vM5?$kXvNft$kb!`pc4OH;M4&YjG;%cx(t++oFQ@ z9bCV&ZO<;;IpTk7GsdRG9={d0IvmXvW9b$?0hnF*KM-(cle%9JK)NPe)WpxIK!j(R zl9dbv+5EI=ZFv=>Qn%$!X~|gh4bf7p6<%2LwjAXtLU3&CZ&0`E=odb1CIuUQfKq{S zZ*7mz$PtN$mY}4A=4JJP>wwI+M6TsHX&$Ds`F;g*H8xVWZU2x=WXTL9y{2uRj^JyA zAd8rr&pl+$)kSC-75wtu`lj_q0K<S3$3E2M#xfIclRE5Mx*xL8^D2&HTsp3jPq1qF zeg>^obtrWd90=4h`qNhPj|#p)*{RfX+deB=6&?<}0-j4a=jV~7?IdT+=k{PM<2y=0 zx3ERh0Kdrs^Y1Z{Akrx8gVhh?DT95jp9yK&wM}E%&~D|rl%(1ok)_B%iNs$I@vxIM z4r^ELFwj^JuzDL>9KI~Feoi|+vi|6SXEfd5KXs>)Cq&@5P{-F#OZsnJRg89&@8B|j zT+-pCQSa4WwD+qINO^_n$*aOAfkb&`<5AD!AAW?|Fi<b3+dVv+JS!UnU0|UKB**-) zzYpRpZ~cIv0@aXQ-S+qav_NMng4YM(0Hz=w@d|Baf!=2V(Pa{?`*x=VWuUMTJG(QF z#&%~(+ZcxW0MSDENYgS>dEK^G*MAEC_^GZz|EtJNenS=pwqu)Fz~^Q&H16b9^Px8) z*HhAO^vkf=?=3SoHlU#3>(d!TLcEv2;!0YwQ1bhHWi_cMU8YBvTDi_zVH%jHH?{vv zJK$}5=ttlCLHET@ABmGP>EGTr9;!jyzxbS~t^q#PIXnRJT7}6D3<bi_ORzBEBTBTI z-<9&ka>)b^v|(*r9UJy*4^U~%@bs4AzKt<3ltS%$<zlJrZVJ{5oFYcf@O$#+6hJM& zn`CG`iQ=({B(prcd*bpr(fdctu=-@?wp?I7yFpFOSqvo{3V`_%)C_zH>NNKXIeg8S z=6S6ynO`f_dNc8e*&oExQzqO8z#Ve*zUb!dMFR-!LjZJ5kr^GcFPw|?nb0U>5J1T} zT~-7mYrc~J+Wl8N=L1(Lk=DHN@^~o25_f)$RaO6k^h(N^FoyL;skT=oSV}npakN+d z$3EvbXud4XC)B_@Fg8z67|n8k9T`Cab8Xj~;B}zfc|OYc4w>f-62Pr2ita-AUJ-0S zo6SI$_W0`gdiR^H<l%=BvnXfQue8|1Ql0h6*Npr|6L?pR!<WWaVXF*cPappoQGtP( z_d&&5jVjB9p_=E0cmQot;P!;(*svBz+R!c0S18o809)Ai=4EjEaPntl#+bw_LaJM+ zY@O(xr~9?$vFoR5WGsZ=6;qc=RK2Uu*)&Mu08()|gg0m-kpen*`b_z;Z8@T|zN3S9 z!6c9^NbIp-dbHunme_I=8WxHT-%;pD`rgKJjp%J#uRMRS4m{G#K21(yb%w#6&6W6) z9@qIJyDCVU`TEbw&xWjGU~ojZ)G4C!s6tq}Tiu#OUF~P4G!lRjm6_8eUiox;x|#qq zW?Y}HLa6`R{d)Q$d=}sXL*qSN#;>B7)se2oqWo1KSQU^*LZ{bTkD`+nLur2zbHF(A z0oz)@($yu7=21I$iGctLj$lo}OlSMSdVYMGWfdT0F*6%(%1(nftDx6y%qlbCnBpP& z-x^03kGl3(6?$Lziv?p;L!!qGDUQgr95btuZ$N8)=<8jmA5hoA7)3mH3XMT!yAj1p zA>Z%Ma@Itj_VH(Ja3ed6T1z4@n1G~51fV8>%m6-A{cKB|b^riluRHrAa27WYT1f%Q zER+>KX!X9d%K=Z%;22FO0NH2X>x=94*?PhC80hrMHgmbC_YIs)TFf;#M~deluhDNG zJ-y?=pz>u#ypcZ!rY)<72m*2PiCV(F+tWCNvaN)9BZro!3d4DBYrp%__Y>P$R3?k< zeq(yXyb&?fVFMVPFjZ?PFqTsRE7=zfjj1v|vh?kL$Rni_6Y4Oil=$H1C#+-p@{##N z7e551%22b`0-uQ(cEU6)D=a3L)s?Auif9pYEj>2nCEXG!h4OCIlkQP9KMWYdbCe2< zWE%QOWSWRf=_k>CwRh2rjz>9LaT>;-w1ok=1M=Tq$n%@h>$C%f{xSt994;5_;E}Vi zzr-FP^99;}`CzShB*<DxYPHPFuzN$Bvwdbr(lhiqIp63X<W&OTn4P7i>HkOyZa^0@ zFgBAya`mr0umc=NLp~BgEf_srr6lFA$EO@$4cju5)j%8~f*T1ytKJ(t9l*se^4)FY z{w|t<<X(}r?bj9qN-}SzeP~o@)xvU1y+Q^xFD0spJs<*UYp1m?0BfGEc5NqczzgrC zf&u@TKf6oa?=-{NVCXqy0K@$6WY{$jW#meU9A9Ta%PWF6YSqx!;&DM%>USVB-@a?` zLJHRa0O`ylD%`D`$NIEtZ$2l_l&g@5+^u*jUIP8-zbZ9KI05$r)Od6QDS*?C>U!jW zJyq?A_wE;Q^V!)=Ag3$1y7bDb6#Gv3RFv`Lk!k31T$nz1Zyz^Px=eTL&xmi%dLf`L zuUC`U9<K)TM@Bca{m^uv8+8+ykE#<g`)^2%Nl$<|fMfjEI|BGsJd)W~>OxEKyB5b( zvrO2GaRFVj-3kW~1O3o?vL)uJF!|aL{N!K)rU3nBxo_L4>wlC^sM=xq>NlCx;A3Z* zDHhh3_o`Ci1(P5B{Tm>C99fnFRe~f+(STgH7|_`RkFu49ZYKii@G?g5MEDk)-jC!O z5{xjB_q?vLTEpR5$7!Hy%Yl(&r8g!EW%%$zmArTOb<!iV`EGjGXJ2(cb7o<Cn_#8C zK9fCL&sB`yh;LM0VV#Va^XG7R9jF5{-EhQV_jE?=8K?4Ht1e^tqGW-0r?T$uT))0h z{KbROg7Oi6lP6E(A!u!vm^EiNh}X|zzu0vl4NbTp<@_XW-@W*e(zwU0?RUU^gKP0T z3u_Lc#e2t4vpz_mB;5BV&b0D+MU1g`>0VrV0uA&f5luB1hLcIgfcG|MYGXhc!3Q?N z<1ouqW89_V>)U_vZ>B{D?D5!tcajrFk;wq@$xDImHF0E-jW|F@Nd^*G;El^94!tLi zCO}3d*i8k3S#z$7dZ9snphlcP#PRLWva1Fgz8$4sxk&$rB`PdtFV2{0hs8WTS=uXr zql4c$l7msrxL%T0vmiU7Qf&Wd{^Q4w{TKo(AOPwCAjwZl45DrWrU#qoAT5G_K!C;h z5*)ymZWOP_Hz^3f3Lc7LLO-0wb=S~=KmKkb4>Q$kd7%@MWX^-P@H?9)o68FekMah( zP7=hHGldTxCm1BIOJ+pWyOG%N)TDFs{K{Yg2I&Y~kx!DIi<@gL7&Ca!@%ou6u{~Ct znv|iSZ-gpy&NIB|<bv4$aCv~#1@KBdzki~3TkiAO0EJaymPCdDHw{HL!yxpgq;R;( zk*RCWNh-MwW4b~KPY*-!2|*q+<*(7xI}tI)taALVX=ViOK3Y89*aj>RsBqz&y)Uc8 zEgGcBeEsenfS2~$CxOl9(G{8PNu4UZWya3Kr;5qXDFyM>ox_;9C>x2eq%NiLutg8x zQOKNUA&r*uK=U&xt8U$JZ}6`&_~b$4r&&s%`=Da*;NNkc5}_w_eyv;Ns5(bX#{sf5 zH-o?U*TQTV_M==ey~3sG_Z~0Jr3j(ajqJ=~7mq(&UnF^?rX*<hYM*C|StkjmzM&2l zmN}O660aSyv;5GaqhEpe47B>-t#sWE>Z&6idPwVyandsm%!pvLfrSR<8!-w=`ZU*g zL)l>7ui8O9FyW8({Y45JEuqffU@JARp3<(=Ur(VYBh5;_IQqj;ba(-+!yU~zBrx*6 z^xv#?5<VIq;{O;i`TB3(DP{78Gv$!Pary8nCdx$$c5SwiTQ8j|KR2<ascSsGh)qA4 zMskPJ;q#%V2H&Wk*Tb51o^3Zj)k~q=thM#&huU!&2pq(yR`pcAtCmO6gS5xA20LyS zd_piJa_Rq*95S$5fg%5Sw$1Nq0ZT($GSCJda8q&UCPr;!AapEvUYe9_?C9AjCg}n^ zrl)v*izS!k+aTtj317FK!#U631xcD0U>p)U`HCg|cRA})As<%VJ2ofgqsbbcUw)3L zDxR)1AW%{X5mfM<%G{#=i&FKwJDdd8xEqA2S1QlbH*%6*>4XoEL8a+Axz+?&X{a$_ zu>sQJocC$ms9bNN7~cTE>%GTnvzx!PF21f|?#Xj9u5I$q(h%Rxcrb^i&$7s7vN>(q zBOc<%psok+^bWKG{IctheLgQON_(W7h`$7BPuWBPB#|oRl1p(s;_`h^`vaf$WukZN zQSPfo6n00;vAT%Y=DT<D0#i5W|8C^p<zk3%thW<1;?$}V&&Pm*byDL2vEBmKYN3$v z3a=+q^@H9QN#}%KIE1>Ua`b^pE$0o}#bOHbG+V8s`s7B7_|PoIkq34|g&PIo*>j?{ zmg4(5y%~R@D!bU&SpNPrfJ@Ox?kD|O7Izr~o?1A;S8X}~z+#eR<mp&O4H${{L-BK# z;`7-irCRvVa+=x)O^3utgkR62ARv++;#FEbGIF22tpq-`{%x>0VGph*VZeC#TdJPT zPs=Pv*f@=@C;!M22o~gJ<>|Pd{Jl{YwwPs3wT%y-y(NJeSSTn)i!>Bi#)7C-Tyt2; z7W<Q&-f2V`&|k=*^GWdb_3M#K#|4aeSD}dRPeZ|dv5Q^`GJUNTx09LlWzQ*^;6vu0 zC*G4o$BflHH3UBIS0mQNO}-n=Pq9>efQfps1hgG!90r~|la#w$ouuad)|3B0)#sDh zcSAwWvZU~xnPxqoo0=z5n|D~|IR{b|*Ht#muQ+}(W2^@h0u)D6Jluvto*(CFo3iCT z|NJ5xuo~sQpA<b8WW`MbSZCGKM^G}ya`^5OtuL9~9L%-xl=>n(2p7Uv9f(_NcMx~q ze%Eq6rdbr%m@?%nW6W1GY7onZOr)t8gQ#2eR>{;DbXaj_cQAKkBqCym%YGC@)Beb% zEIPnQPkHac6Q5UFznIccZ-*DM4C898F|>nC17-E1H8qqE-dh-A^rDs@!a}u<VI4Qd zCv3|SY>rH!*6%+zFLvn6?!~FNd$%k7m`gT4!g<)G>~479Bqv2A?0G&HbGS3or?l~P z^sw3P3B@r^2nQgI9tVlg(|^o35$hvrUJxbXN`qJOz_f%+<~TsmW6Y1Jo9AsU)ikWo zl|2F6_Q#$$lP{QXUui>le`{hgHGZDfo8f<45ZfEGsB~%!t-LjEt2%!)>*3Ikat**% zry%aT@}LjpCaNh0bqZCtjaTCIU2j(3fJcd3a2G9c_8P(ED%Ct3OG0=6|Mnj*n*l@j zBkBxi>ta?ymSaIVl!{*N@p<uv^^gk{eTb9s9Qw`Z9=(#IcxR;c%-nZV$UuWRFWc0} zJ@nDmzh$shDGv<<+8DSVn<I52YdtMWrMM3mN+|s-ub$e@N;EO_^=rN*F#|Vq<++)( zs=afL23sHW0k^t2<lVx5*&UXb{fXkE(T-U{M1VLua9LDJzuT+4eRp2N3w(m4*p#GB z=cQYn;fFYH!o)G7_I(caUR}>7woBemMkl|XW+^Z{^@0@i25|?A-x~<vOAT(td_woA zS<Y|s`LKU~3$6O&p*>8{3O%$4bbva}DMll@RcR6tN>+C?oTWsuVK<$PD%<S+SQA&r z`XosWa6SIMyaYXKKaB(%*A9s+tV{-*>aHSp2bxu_FA(^7m}opShnNbYL|Mauu=kHT zq&Mh7>z^*ZE-Y%l#PnrATjwpubt($&4G=3G(0cQJ9nJT2_dY4eJU<0UZ3OEg(1fnP zY7e%7?nghlcJ%l_l2C47CV`)R7A&n}8$}j$s&qeA*k|8n#nf#ar7lnTN9{tWh8+E# zyPIYo(QVjrKT#UJM!qmPy#<8@GO~-(azfTsB4ncappO`Q&i}!T+H`|Nixx_y!7Wo@ z=*3yj<C>lKT%*^qbcYB`G=rL!()#0}DE)4cJMuGmv^N}xv%VuJsXr*R{`lgDe&-F1 zgK$L2hnOJ}Yj3pda@nx^gAHO@$gX{f(=nY_$II)Z7PI$$ZtCvYWAG+5-YpWSe`R!6 zoX9+@Z^1isnXa(v@1r?M<7h}ue2sm!k0Octv`$4B1oCr+4QqOK_q7+1_I<wak7t2@ zDwLIhE5yg8`0Lz{3^VC!uK17Mkg_2t%FV+iyX=BbB>`QUXNxWAj4wd1_l4_72=g)6 zIXu}YZ#9I1hiZ(r7zDasD%)Mf+|3ME-#lxDtR}r*x-4Wi)UajgDy+9|1Xds?+IeS4 zXgIv#+7<HmE1{M_zU~K+HAkWeKQ;?hZFyy2z=7>_0>+{<5B9}VT4!0;H$a5Kzu>*I zvdNFjVai)GxbNd??G3CBat=zV!PyiboX7<q@zLH#EEPRN()4kGmpXe6{jUGW%y2#d zjT?C_UhQU2<zeejkNiFq)}!B$UqWba5}AmFsyNTx0fC6iN}kMqlB)yD+&$+Tx1MD+ z1|_RFHSZ}KG_EK9jMN_{0D-RJ|IV}0uj34ysni||V`}t5H3EXdUB78?TH|YQJ@SW@ z+ru&ryf_`bHca{AQCRPuv4oTB1<ajgXx8(zG~4FS5<Z8;z6V;c3E2!IwnBL3#pc@z zb|I7_j)-lcGRm6oOX|s}rZR#3jiCymOKw^0hxH3yoWF_+f2rrO4o14#S2k%|O#dk@ zF-!;oc_#d!lJT2QY{hCnDRnv?>gWkyMJ4vXA?E&ki)yE=0v?2PgeU|B8mWerpt(Yy z((JK9abW8!TbHus?<r|%J3;Db3M#5E;bE^M@^JD7KFwBt5xfGI$Ms;W%w0*Wr<vce z5FN7jh=TF*p0~bBov@_1zD5h&!A8?ZLqN2b<$rbV=(Gs2XmE@{py%@l@c;|$$@k%T zHZ`H$J*mKkp&vlQ?ynKc$9leXXgi)AJ7g0sH{s=q1ivsf;lVFF%MY9Fp1yLOZDK); zT=r|CWshllLj#5ZcO%XgQ1;WY-8k;IB+q>PvEXl00X7u7g0P)j?K&gDw3cuZxP&Tu zgL|ei#f_g!`)LJ)L=Bl@Lw{L?Lx0|GpJg`nQvb(a|MDkVm#uBD*C%BfslVbhuj4uv zBQTB{cE&au#~Q)m)cN__sR7ToSH+7%R3raaWweSsV43Xl=w6a&{rCCaV!^n%a0!RN z`D=V}znypGv<}AkPT|96JuypP9yIcq))<t#bGlXb-&QkGc;;ogi}zf!A2^uTi;~Oo zq24OF$#c^gFY|mGSCsQ3xCI>VzUb%nN1afGmHHP>$4DduBD*yIxyoVLLKReGvgE9F zmaRug4u(WTv4eWeVCiK~PBF>^cHEXPU-E5CRxUx_6racRVCk2P=-Wr1UEaw~qEGQc zS<w}ftVd6{#>hz)4P}f)Yr8xAY36DJmGw=d2ph@3d#VNwimw~$<!{64-F!zcofWI9 zag^;37v{i!5)277!8-Q8E-TVkIR2|9oUocIlSUxb1-ESYjGw>%<4XCr0fhBv?<vsa zcLk3(@?9y1*x{&K;jcgrK6U9K{09CW;eXER#Wt~Ke`G^4Dk6#6SJY&O7;WB%Dt^gi zVt>73HVO#D!Cd822h$n^wd8%SK;OPNL>iV|LLlubYR>+dbINC3dREaX<FqhQpn2P< z4=0t!4pOyLRai0@;IwuD1qB>fk4!G<z4-Ec6R)L7L(6JBU}%atWRA!tjFY=luv!|o z{1Ia1({D-Tur}~E=d^5m&P*qkQd;}4dyD(^4hxg66Le2{m5|YAt>wTU!R#w1i>?EG z<*B}XCBYd=#I8tB$r^46tg~D>QEFJak(UGpIT|zfhDx$0*yc@!r7wn!th)zM0H<^S z3gxv9hAW6&;qL2jDr1HljD^jMBY4LDG0{0U<~&2~X?#5EZrLXC3o3Ww&rNND5PL)Q z%GZ5G<Cf;fALe<-gI-c|MFO|&V4j22<ZTj@H+V32H<J1@n5fuL4W)?1Vv6e|tBH<_ zW>`b<+b|y9ijHTFm`cO3WmM4O`Z*Ve%a4MIe4S>gT+Lr8PIdkr=>xjxSbk0_;IXnW zGC7;8KWy711$g&T>)2GTr@`5GnCaoKpBo0_J_Q%{l8p`pPkdtsO$<J7T@uO8V#Icg z#cP0dMosxADjJU~^=VX@S@^U6h6rY*eptXRsIx`2GZ6e8pS(9pLg#1qhjXh0A#e(- zaAaZp5}Mq+yU3z7#KdJYo@WHh&5|5U0#=^sPHpNVS+vRa76z&Eq6e67i;}zWTZ;@V z9Qm4r+KBMy4BGD(!3%*HEDX9qAQE2%8A)v!FmI?vf6a8T-wT8YXv1?+z*I5j6L}pC z`cA6S6TN`s@M~pjmvsys_lp;t8|EHSMr})+e=t1AXifD`o9NiQW%W3kyMadIw2>bK zv3&JOCH1jfFEz5<exE^rImXuJ%N}g2=-cxVa;3w{*j4$Njbcu0r^o3|lYk03ZX2-X zm%a4#+E4r?D0aN8F_Y()zt$@JobS^7k|>)8b9HniO#w|`54%Y8V_^VSC;y4!1=RgR zcL2nX{ZDh9+iPh6{ogimn`MPikW98loBiYW^&em)363#l16Z7jMufVnO>W-E!qwof zKzr}GERwx+@(CvPZfAI1ac#xDss1+9IbP^k;<H!4dM@iF!t%(gmC4Z1aaZWb(aU6Z zP_4cLlHv49F}EiJvMh=*=z3;VcGob7f1Q9<JBOsAZ5uQh%$<y&VmOZOX<(1Q-Qh8S zVRTz!ksHVLZMVpN`Bl+FC{uu|fc}*`Mq?@N+wSzKi`7N>)1rG&-jDDoQknRDf(-pT zYhs2P{}1>!^CInC=F9E!eJsR0>VH~-1?s1V>N-Qs+GW4y81=_liounu;=@ZbCiS1+ z+toDL=t?~W1k3NHewyl1O*V8`_Iq_pDBzxXR&cj)Iy<vX+}VOLFTNLP2(0uMR%#cK z@w{`_+D6fg8y9n5+qrxxe-n@02|7<}FIZm^xd<%LU6d(j`OVFd>IQuOCQqI?SB$W0 zJUayT#SZzy{$0h{Z=-BX{;AbvYX!>XszZ3{AOaiu^L1S!kK;vh3xt)SS1Z~#uYw(k z0=Ht(Beu)XgUMp&R(}e5Po-~fT=D}l!AN0LwZT5NkXgv*XW5`HTxiM^KNc3f(}QoQ zxT(GI-KXch&l4s;S{>}*l<t*-)in|-AlXCl%Nf9*JzM>h_go-&c+W&BrJCAWzu76` z+}*uR<W#L6sXrbpMt9zJSyjEK%EsgDC-H6uDXgG2z{Yj5MwlV}hf$pfzU5fr9Q4p^ z|H4<{%P1{RQD0V(suHuTq6_IzygV)enToV5TZ}-1Cq@egU_tk>?u+*m9poYY-ZYj^ z^!lBvSg&2XrVH-Buk|8Cpqe)V>xSJkEo-b_71xisr%N0aLyJ>PBe-80cF${+GIh>@ zgfl#E|K(F>w(wHhmgQ|<Ga1*|i*;e%az_rk&1|B3kHPjNS+)O`akEXUqp3Wc)@K{H zh24j1B@cr<Oll{=XO`n?6W(CIEEISVARc`V(L#{r>_IRChND3r8}5bas>7-Y1c8T| z(jU+7#5zdh%`DAC=aCMstz5M87{Pewx*{P&CTv%a@$7`4at4a({EJ+E`L`PFhqV)C zoT^rz*u+P9H6GSB@e6xT?zFdoI2lad$AEuY&mv=LI)v}HsxE-EI{$Hwc0{bxQv8`k z@)ruV8oBWH3wC*|_#%_lcj0Ex$b7M5%AXjrzdNn5E+-${RrVl5Y7B}hcYjIs^D=-F zf0PU5-Y%(CMGot^p=xr1l<<0G2S7+b;S3GNJbfKT$ya<?AxPNN$u(>g#ppUL)~B2O zlh-PwgROL@)O>BeSfJ4F5W}JJGO|jDp`|wqj$|J^3R}t3yUP;S>k20E@gr@q{ac?a z)m_su${o)p7J4JTijE-HLU=ju9t3P^;2Gw$gN_^eSgiZ-qYoKxg;rFY>h<NFv}uEJ zuf{Qb<+gZmNjzj}>=AhEM3*C!OeuK(TZ2Qv7~<L1*W*s_VxP2Ccc_^=3_7(t7W?P( z2KJzEag4NN<R+%0t6JZvFh5GD5P`y59ytO#Il8z)tLT=ww2S1jDJB_BSjYrsX1&wH z?MvJjBg}*~Bt81H(G=xoe6`v0Fetoc+x7E4>CGTXxREVz#0AF3aN1gkMQW-93;XE= z#eBZ`!~yt2@r}z&{<D(=*iqBZ^>b5trR(q_&`dq(J#|EYlgi;_n7qawCFZkoF;5cn zQ18f8;#&lq)0$amt@+40zgEv~;h}8;Z5*KE++R0JTY*G7NOL-`wm{}^v3$x{h1Gu} z2Ew^0oHf2;$aoc^hHDMAc$uC-DaD816%X~gsY%Ax|Bhd-wrKAw&}i|5hptLB*%AR! z@Om?up$52T2BPb-Lo)=3>C*4b<ZA5c|H25xoY2ZK$9HbudN7YEHVEZ$T#!=olLusB zd^R1l^+UkZu0-Yw1pE(QIBI3^*EP6?Md@lq&lAOO%w_DD+R7Dl`3jMJKQlvqB5unU z_S7Z4IQlfXj<W{{t?E?ZHC<zd-E5UWjf_)9oh?0otG&&4hNXRKKiy0cRhwS)<~8Gz zy_X>w%M~s&>N{&s5koL*<eNNmDB$XPeM=eWm8yAEEHQjdLJ4e*N2N96k5QyyIeh`i zlWM{3ylaa8<OkBH-&rwCn=Hh4t)7T&Z^{?IHK>|+ps)9FCNq{3aXQ;ER5i|zod{C2 zw<q|rm~PYthZg_EoAMM4_2To`?&0~90}oK-n>L;vhz2MPjRSy}EP)VDDk6pm$7NsY zw^QL3EZdRx$!Ksk5B8)_LOjX%gsX2pg!Aya+|nm@`Z(3k`}u%1C{0awD-s8D;MxBu zZO%7-P$o~0VT<iEW+mmnyzLdA-g7}WQpd?Cgaw<pKk$UV{hp_a9V$Zywsf>Lp|&u@ z+%qK*(f1jot|N!hHQ^y6ai8crR@)a@th%twLkH%{4I>LCqT5vp-Io1(3@k6^Ek(N9 zX4FWcE8bN^9u9GLJUoY>|83|cxI1k5ainj2LH=|kj%H_sgSqIu;^wRI@Gb1kys8or zNb+Fc@s%FP#Z6?YQYC)1G7E2eRPdN@Bnd{EmG>VKn?%y(U^aw~vpe``A4^A?nhz!` z{Vw3F(RJ+ZZO`w5^^O34ij@<g^i<)oT`7jYTY+bdby}}kzqwg5RNu6D{?{)EPE41s z8)tXZP&}uu{W(&_E!2TdPhY>Phue6Mc{W1AnBZ9%IL{ea+2erKd~3%O!=t!?YS%zi zb{|E(_}`qYc}#U(!pMG;FL%9VfF!qjf^lC;pgcf8Xr!AtjzQPVMl}*x&O$0??)}rV z#cSaWZ(Xb({!#Dg4IQN^FfM=+i!{m$4ts~vKX5+!4?_aNoYcM5q5B7A%17r*uyUTm ziEa||QB{C12eQ~A)pR|I6DC=60Zi=6!P?vxQL)Gb*gnDvj>y`F>BB-M@uXw4<{urQ ziob*G`F*KuZ(z1nPAmB5i?rm}k*?zfnlQ=!NJrcE+G2lkppADn@8Tg3Wccfiw6KOT zS9RWd9ZieoT9i;#^!kBm=g%L`lY_~Zys%Bx!cO^-<9g{lv$#WJOy?ih;-Nv<<^pgQ z<oxlM;2$=A40vx!kzNR2M+1UZgWL}2#l$WRHcqb#WKt?9@-qw8_@L1fVaN*;iU&d8 z`3P(C{UezmU^Mu(pCjcbiQ`#+b|Y=Jy%5#<E_pWH{VUhJQiiB>-Mt{@-R#M8%vq<Y zXKEI9(<ps4troUycilac9F9oM9ZbS_Z^|{f1@nrZy|zlEkH59hh_%ht?Dim7d)*@T zn&B16F71qXCVXQ<^>c&f9>7x%i*%fpcQe&rh{P-C3@0Zk?#zVqkQDHUzMDV}`Z~E? z;^K-imxJkXK7`h3IOt0Km1kgdY<(qW=&+z`-=$u1l!t11ksu^m%Of!|E^>zHkJ|oa zc-63M^t|*d4*>?5zSf1v`06*6WutAr4rqSrWxqGxOaS1)X+9#h+BqM-YMcw2jYbtD z-ixr4`OytEvomOm%UPfR?<&{mIi!|vr!2p*Yo23%_<5hhVZAd46K%&)rGP`O`04)8 zug$Pq!6U|q+J!bg$<g1~_EJ+D6n^w=_1iEJ4pybS(XqTpA=YDb{?yBkW5F%DdV=K5 zX`L>|wF3DVpx&<qYh5us1BK0vk(LllPbY}EgAaLG1?%-PcEwJ)`}k0E!-wZC;q41l z0hl+>6Pff`t4lF>fZm_kh@bO6R0Pe#oP!pjG84yx8XMy|3l>s-gN&#K`IBGcR}5^x zt2S^AT>mLp^kR?g!sPQYPT4(HgNvFN<Bzbv$g9I)vl=>O8@gLOmGzaoi(lwwPle>9 zt=YtqCy!cG0aM)ggKU$Uo#FE5@rhI@tH<hX9d#ehhSwtTe|f(JJkowRNwDnSDGXDN zIX_HDSuSX-iFf3#dY{o*jQ1hK6-b4ES2sItHxm~I&nOHKQIo|9NRxYcJm1GWrb*qn zJSuVQG7z~v6fRw>QP^9PhU{Mf5$^XApF1vxyLt7#`ZsFW6b#z@KTBVQ^SUqgd_0V_ zmVT?5K$19ONjZMXLr5S3aTgy(jZ)Hv55(eRAkt?+e-3$lD0U;IIU1{PMgLMhgHRwC z)+=J6mzP+zN>W!uK$!BiLhM0OTg&h&6#gxNUgzWoPH$e_o!7U)X)$_PG4{i@Q(l$f zkMRbi)kk)f-%Fr+3G@`G6cbE!_sPsVU&x44{2Z&ZJFd<G58BM+hs({>9mq?X@QCLa zzg|7P)6C4m=I=Z2WAdYX-ol-=tdpbE7p(3c>6GCOMVl1o!*Q7w79iNV5>3*~(9emp zaC;PFKN64ZPM31jLIoxNl?I0gkYdeFtLw{ehX)89L9mCqi>aN>-r$88Nh!LRxyGEj zo>-mcJS`gAn(WKwM6B%S$=T57`fb=Ua?`TX?9}b&CB#h7b%(kk1s<(qMer{)t(`Bq z7KmHh->)Mjadv`Gv<lYnJB(@6!W5f?3QnRVjZ%CG=$aVKv^HOnU?ir=831t0OJ!eN z_Bd=>E1z>v>3TNT>0Wh_2;1|EAx!GGnf7U4!2SjmoS+gDQ8u<c3&Fot^5A~QmS05T zj;@ew`!Rq#61)|Aab^C?40w0$XN=D#4=sTOb66n;NQ52pN%ys4n^gILbKRpf@C`QY zn!G5DAgh@`qW-{;#`Qsq1mcROD&JpDiA(_~<mp0Z`Pjg|-m#>lF6nkzXW0>Q;B+Jr zWD4s|Qc9|r{B88cC{yip5w4Qje-g?Q<%`LC;UkMcMQLBuw*B{Km@)GsgV3nTm!eQb zbpO%D9r}@!407q$^u^fwPoXTdQr6oHVuCFZmd;N=zzV`Kxe{`E^*I|ZldqYO<w<4- z(GC~43QWk|6I2!+?2~QB+A2?I|Jqk&q!F4s@`{Mx<T-FTE$yl$LmwctW~AZydeAY| z(K~;7>(Mf<l04a8PR+)jT@z(TZvL1LGy2i93ZyRMjB~8^o_u<F6R1*2Ox`2iqt<_G zRb_b!V0a{wut2CcGdrC_k<^P}AtQQz{3_wk-zTU>nZ6h#7yddGCHCcxr*-Ckr$0H> z>H{+w$=eSQR}^=2|14dd=c3l%p1!0Las#>zC+yJ@BBknU{GNBNtA+lN;^)IlJjpkA z8lRld<wXYrPR?O@*&(?$^1vJf6$nbi-BSVH*9_?5S$CJ8ec9X(yYRBNVJNo;-}M(P z($-ms&AizeJ%zTI$2z0jKY)KLqkNy`h1Pi8wluul3-MD0C-Cd`%pE@Sm}6Ny@2{lp zhPDe4jFWbPV%^lb{gt{o{&-jP8>11pdW)H+=ZNH9JrVGT9OIJnEB&IhTh_<H!Q^wb z{oDBI#Pyz7I-)wVG?tfXHuxdw*?qp|azjz|Et4_G4kU6re-g5F&W3%TA5kcr3iTS+ z%=9L)d{m(ko?dbB&Gum@?fTNxbsOwMZYp10J#pmKt9)MU_p6Bf)f>RKB|VPRn^W0A zEuok9%QIXt=WorL=6>WVu9prZj`c=Fj3p?z9g!hsdv}ULPre5y=d~VJ*}vV=Js2bt z%Q>rf{nTQSJXd8mAWZ~X)-`Bx*!zzOGQ<?&GghD(zp^8R*34c;eMP%foK~x<kN`3% z`TYIY_=#X|{`d0nd-VD_=Dbvt0w#0VO6p~M?S$-Gu};vGsseBWjVB4P{FK)DLN11< z$n23Cqmkl`8m*s!Q=b4gp4=^mg`CsYTmeG>f|XxTXq!+O81ELvV|``x?>A-w8C}el z!s53es3V)6@HCF2)k}4Mu;N!oK+nJ>j;>5Getx3#Z{Jnrr}CU<rGOfQ3Sjd9y1F3& zCKM5CpJNVY3zt^3G7l*UFrhjJ_kIBs#B+Q6A2@GyI<7szLX`<0-mQ3A{WTp2U6D*W z<dJx0+oMKR;jIPql;L|ezt(ia*GLt^3(^6e%LhktesoH2fs4fa`HDPdV9#uwCH3vS zlsm_C6xl$RwG;bJ??$Y+nV>;$O262sFB9i}(W};)dH>Er9pau6ACsib@3Q0f1Q$`I zFi9f#{#+>|KG4B@+LOIHZCWY;kj(S{C7T#Ni?>j1;KLKb^D)Ht9~~k|7mImrX|x*t zJX{_#uLM1n!{l`?`|i$zoYRi1BD~hD9o<mb^>zQ6BLr%62rqHm`oDWX$??ib@>H%$ zLucQ!F4cmYBt3xg2lLRV0y~h20zr;_$kd+8&c`cN%=VM5kAK;-yOIs_W<KEEqkJvE za?xhJ77nRx_kt^Ym@95A!{fAqQ~XaaPs#PCJR_LV9p&FjD(r=>TV|pq)QDakIaMyJ zLq&T~?e^26qUPnJ^Z*5PoL1bN$D8irrcXMyCDB-b%F6Xx+PorA#F6UW{+fu`r~PwU zs<vfzsfjkKKq{x|0jDaTJ7+J;3&6kGw~7wSES2{4JAQ`r6rw=AZI_CcJw3n#wJ%r8 zsCVJWtL41pEofX@t%j9i=W3Lq|4xElKQCFFx$I-yC<CiGC=2yvG?7X|XAlI0m{XxG z&y%~*(%x;(5eRFQeRXMhPXqwjSA#FR)B<l_*G_L>r$C(t$z08x&FH|DnT?t<&{eK@ zdi$CEHw7Bs;!)5TzH>4So!A+8&<vDy@iMA-Q2&IJTSQrq@N2^1NEiz|rLQ8rk3%Yy zJay{QB*do`*RWo`qial2XZx=h^-hh!p-7epWFWz&*U(QW?0$zY6Y@UZad7vhKkH-s zD6lCURgJ+Plc3UyPW)Bwj4-ho28zy})t1g9yTiJdXK_O#Z(bkDvbj%cvBp1zeHq_e zKaXQ?W1ZfV=&%`eOf?A6vw0lAOEixaw=V2k2)Yo_uj^KZ=<HjTbsSiw<{rKi0s~ml zJ7$JR8CxOLY35-$#;@3UxZJ`htNA`cfd+>s_C?JVSrhsELIK%!zI-#6heN#(u#0!L zjxft$LC_%hE<K&9RfvR*8?dtG6|I72>hEPeyAC+pU9p|G(L+bM5nopcWsS6PFQ!L_ zW$3ZDV_%;+Y_;LJz6cgW8yC~_h~)v~HqS2bJ*FY=moyg+nWenfpd3lWjP|Rm&}-t; zN#qsct&)-bK`69%1QHEdP)Tmjp)?h6aV27RWfWa=0g&3|RTVFPgUA5EFJ*}JOga%4 ziAsFky$yE2v<t=Nbl@Bn{&Rt1Vw()n&#aYKwG;B-0F_0$cw1=v{wX^P)+z&{!QwPh z7-0*gf7dl`PM%@7zC`ETgWYl#?$<Z!*2RhY`)VezqJN+0{`=lF@Xl7~e_7vAzCy5j ztMKD=_Dk(e-$@BHknTLR?6hQr`VCM?+oYxtW&x)qI-PN?n|>|UBN!|(u1Tw<!Sd@U zx8=9@RuP9Q+V`>5rI+~L-il~k;4sh}6P;!Jy7j8Ub<+Iq`=&+W!(m3qkH63$|IJSc zkeUev@I*B5I1O&a#AZT@by}6x>Q)AMX@qi70g^hjNB<oNuKlk%s#8&F-vi8AXFGZS z&$4*j7xbbW|Jx$P`Ndo&e!Q#?iT=GlY-6}vd`l7RtoBymQAy)%V8R+Zl*6Z-^=nnX zRk~uU5F^_?3NKBK#`(7q^T6%3IHhF0ytMKx1;Aism|0m{b*+erm^8G~E#gr!n98mb z*MHB_4I(RE@V{~07ia{oGLM2e1$%=+zyK5M-kS6<u=8{I<f3FSf5nwFF2`@w*)Mx2 zi1ka?gkbB_TReTPW^~9C>#vaI1{ATZ5Ypq(2_~R;#Tc^bGNK`Rdqj(*5BwreG+f9m z5_c&~rH2f%3cFCN3m9_tHpwP@4`|xnbo*jX0E2M1OHZ8$)u>cv0{ns;kr=C#zFfW` z9fe_W&p(#aRQ%_tg_kW8Fj(-!OhhXlMWdWtc%fVvDQcpw+t=OzVy2mx24gciMW}YX z@#8{Id7daBQFejI<LP+SpJNi{K@=G|7Gk)gAY<ZOR(ph2Q!}ClJZY#@xA6YA8o@$* z3vZun!lQrkFa(~|F1?_4aUoj8O1(+2K;e`rdV?^kvu{g}V~}2~nW9Lq4I)r19mKQN zUg5bYBdxvyx3~dQ*HoIPBK})fjQ8%mL_a}DPc=gFmk2Gyk}?ff#?L}K(b*5+M+`!_ zVLHMmNB;8G14X-)JCTkFleJ?1UtH8?m{(mc%K}Jkkb)=q@?3k&6Ifi*L@vfH`=F`O zrY)(7&w}(-Te7S$_7kl_ak`cyxs*t}9W@CKWdFFxqStRuBg!SZL+q6!ojXh?iV{B$ z-dJ&%O|g~6tHe%ciuU8%;%oxB1l+)8CeyrC$JzA{H)R1mD)sgQ&{u>lnav31^*?d| P3lXFst143`Wft*&1|_Uh literal 44823 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 Um%~c~?fXHJqH^D=g!Kdd2bwhvF8}}l diff --git a/extras/AudioPluginHost/Builds/Android/build.gradle b/extras/AudioPluginHost/Builds/Android/build.gradle index cfd3a2f8..0fe5b4aa 100644 --- a/extras/AudioPluginHost/Builds/Android/build.gradle +++ b/extras/AudioPluginHost/Builds/Android/build.gradle @@ -4,7 +4,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.5.3' + classpath 'com.android.tools.build:gradle:4.0.0' } } diff --git a/extras/AudioPluginHost/Builds/Android/gradle/wrapper/gradle-wrapper.properties b/extras/AudioPluginHost/Builds/Android/gradle/wrapper/gradle-wrapper.properties index b66802c7..49479605 100644 --- a/extras/AudioPluginHost/Builds/Android/gradle/wrapper/gradle-wrapper.properties +++ b/extras/AudioPluginHost/Builds/Android/gradle/wrapper/gradle-wrapper.properties @@ -1 +1 @@ -distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip \ No newline at end of file +distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip \ No newline at end of file diff --git a/extras/AudioPluginHost/Builds/LinuxMakefile/Makefile b/extras/AudioPluginHost/Builds/LinuxMakefile/Makefile index 1ee6149e..54bb46b6 100644 --- a/extras/AudioPluginHost/Builds/LinuxMakefile/Makefile +++ b/extras/AudioPluginHost/Builds/LinuxMakefile/Makefile @@ -35,13 +35,13 @@ ifeq ($(CONFIG),Debug) TARGET_ARCH := endif - JUCE_CPPFLAGS := $(DEPFLAGS) -DLINUX=1 -DDEBUG=1 -D_DEBUG=1 -DJUCER_LINUX_MAKE_6D53C8B4=1 -DJUCE_APP_VERSION=1.0.0 -DJUCE_APP_VERSION_HEX=0x10000 $(shell pkg-config --cflags alsa x11 xinerama xext freetype2 libcurl) -pthread -I../../../../modules/juce_audio_processors/format_types/VST3_SDK -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_CPPFLAGS := $(DEPFLAGS) "-DLINUX=1" "-DDEBUG=1" "-D_DEBUG=1" "-DJUCE_DISPLAY_SPLASH_SCREEN=0" "-DJUCE_USE_DARK_SPLASH_SCREEN=1" "-DJUCE_PROJUCER_VERSION=0x60005" "-DJUCE_MODULE_AVAILABLE_juce_audio_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_devices=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_formats=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_processors=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_utils=1" "-DJUCE_MODULE_AVAILABLE_juce_core=1" "-DJUCE_MODULE_AVAILABLE_juce_cryptography=1" "-DJUCE_MODULE_AVAILABLE_juce_data_structures=1" "-DJUCE_MODULE_AVAILABLE_juce_dsp=1" "-DJUCE_MODULE_AVAILABLE_juce_events=1" "-DJUCE_MODULE_AVAILABLE_juce_graphics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_extra=1" "-DJUCE_MODULE_AVAILABLE_juce_opengl=1" "-DJUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1" "-DJUCE_WASAPI=1" "-DJUCE_DIRECTSOUND=1" "-DJUCE_ALSA=1" "-DJUCE_USE_FLAC=0" "-DJUCE_USE_OGGVORBIS=1" "-DJUCE_PLUGINHOST_VST3=1" "-DJUCE_PLUGINHOST_AU=1" "-DJUCE_PLUGINHOST_LADSPA=1" "-DJUCE_USE_CDREADER=0" "-DJUCE_USE_CDBURNER=0" "-DJUCE_WEB_BROWSER=0" "-DJUCE_STANDALONE_APPLICATION=1" "-DJUCER_LINUX_MAKE_6D53C8B4=1" "-DJUCE_APP_VERSION=1.0.0" "-DJUCE_APP_VERSION_HEX=0x10000" $(shell pkg-config --cflags alsa freetype2 libcurl) -pthread -I../../../../modules/juce_audio_processors/format_types/VST3_SDK -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 := AudioPluginHost JUCE_CFLAGS += $(JUCE_CPPFLAGS) $(TARGET_ARCH) -g -ggdb -O0 $(CFLAGS) JUCE_CXXFLAGS += $(JUCE_CFLAGS) -std=c++14 $(CXXFLAGS) - JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) -L/usr/X11R6/lib/ $(shell pkg-config --libs alsa x11 xinerama xext freetype2 libcurl) -lrt -ldl -lpthread -lGL $(LDFLAGS) + JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) $(shell pkg-config --libs alsa freetype2 libcurl) -fvisibility=hidden -lrt -ldl -lpthread -lGL $(LDFLAGS) CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(TARGET) $(JUCE_OBJDIR) endif @@ -56,13 +56,13 @@ ifeq ($(CONFIG),Release) TARGET_ARCH := endif - JUCE_CPPFLAGS := $(DEPFLAGS) -DLINUX=1 -DNDEBUG=1 -DJUCER_LINUX_MAKE_6D53C8B4=1 -DJUCE_APP_VERSION=1.0.0 -DJUCE_APP_VERSION_HEX=0x10000 $(shell pkg-config --cflags alsa x11 xinerama xext freetype2 libcurl) -pthread -I../../../../modules/juce_audio_processors/format_types/VST3_SDK -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_CPPFLAGS := $(DEPFLAGS) "-DLINUX=1" "-DNDEBUG=1" "-DJUCE_DISPLAY_SPLASH_SCREEN=0" "-DJUCE_USE_DARK_SPLASH_SCREEN=1" "-DJUCE_PROJUCER_VERSION=0x60005" "-DJUCE_MODULE_AVAILABLE_juce_audio_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_devices=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_formats=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_processors=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_utils=1" "-DJUCE_MODULE_AVAILABLE_juce_core=1" "-DJUCE_MODULE_AVAILABLE_juce_cryptography=1" "-DJUCE_MODULE_AVAILABLE_juce_data_structures=1" "-DJUCE_MODULE_AVAILABLE_juce_dsp=1" "-DJUCE_MODULE_AVAILABLE_juce_events=1" "-DJUCE_MODULE_AVAILABLE_juce_graphics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_extra=1" "-DJUCE_MODULE_AVAILABLE_juce_opengl=1" "-DJUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1" "-DJUCE_WASAPI=1" "-DJUCE_DIRECTSOUND=1" "-DJUCE_ALSA=1" "-DJUCE_USE_FLAC=0" "-DJUCE_USE_OGGVORBIS=1" "-DJUCE_PLUGINHOST_VST3=1" "-DJUCE_PLUGINHOST_AU=1" "-DJUCE_PLUGINHOST_LADSPA=1" "-DJUCE_USE_CDREADER=0" "-DJUCE_USE_CDBURNER=0" "-DJUCE_WEB_BROWSER=0" "-DJUCE_STANDALONE_APPLICATION=1" "-DJUCER_LINUX_MAKE_6D53C8B4=1" "-DJUCE_APP_VERSION=1.0.0" "-DJUCE_APP_VERSION_HEX=0x10000" $(shell pkg-config --cflags alsa freetype2 libcurl) -pthread -I../../../../modules/juce_audio_processors/format_types/VST3_SDK -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 := AudioPluginHost JUCE_CFLAGS += $(JUCE_CPPFLAGS) $(TARGET_ARCH) -Os $(CFLAGS) JUCE_CXXFLAGS += $(JUCE_CFLAGS) -std=c++14 $(CXXFLAGS) - JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) -L/usr/X11R6/lib/ $(shell pkg-config --libs alsa x11 xinerama xext freetype2 libcurl) -fvisibility=hidden -lrt -ldl -lpthread -lGL $(LDFLAGS) + JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) $(shell pkg-config --libs alsa freetype2 libcurl) -fvisibility=hidden -lrt -ldl -lpthread -lGL $(LDFLAGS) CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(TARGET) $(JUCE_OBJDIR) endif @@ -83,12 +83,12 @@ OBJECTS_APP := \ $(JUCE_OBJDIR)/include_juce_core_f26d17db.o \ $(JUCE_OBJDIR)/include_juce_cryptography_8cb807a8.o \ $(JUCE_OBJDIR)/include_juce_data_structures_7471b1e3.o \ + $(JUCE_OBJDIR)/include_juce_dsp_aeb2060f.o \ $(JUCE_OBJDIR)/include_juce_events_fd7d695.o \ $(JUCE_OBJDIR)/include_juce_graphics_f817e147.o \ $(JUCE_OBJDIR)/include_juce_gui_basics_e3f79785.o \ $(JUCE_OBJDIR)/include_juce_gui_extra_6dee1c1a.o \ $(JUCE_OBJDIR)/include_juce_opengl_a8a032b.o \ - $(JUCE_OBJDIR)/include_juce_video_be78589.o \ .PHONY: clean all strip @@ -96,7 +96,7 @@ all : $(JUCE_OUTDIR)/$(JUCE_TARGET_APP) $(JUCE_OUTDIR)/$(JUCE_TARGET_APP) : $(OBJECTS_APP) $(RESOURCES) @command -v pkg-config >/dev/null 2>&1 || { echo >&2 "pkg-config not installed. Please, install it."; exit 1; } - @pkg-config --print-errors alsa x11 xinerama xext freetype2 libcurl + @pkg-config --print-errors alsa freetype2 libcurl @echo Linking "AudioPluginHost - App" -$(V_AT)mkdir -p $(JUCE_BINDIR) -$(V_AT)mkdir -p $(JUCE_LIBDIR) @@ -178,6 +178,11 @@ $(JUCE_OBJDIR)/include_juce_data_structures_7471b1e3.o: ../../JuceLibraryCode/in @echo "Compiling include_juce_data_structures.cpp" $(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<" +$(JUCE_OBJDIR)/include_juce_dsp_aeb2060f.o: ../../JuceLibraryCode/include_juce_dsp.cpp + -$(V_AT)mkdir -p $(JUCE_OBJDIR) + @echo "Compiling include_juce_dsp.cpp" + $(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<" + $(JUCE_OBJDIR)/include_juce_events_fd7d695.o: ../../JuceLibraryCode/include_juce_events.cpp -$(V_AT)mkdir -p $(JUCE_OBJDIR) @echo "Compiling include_juce_events.cpp" @@ -203,11 +208,6 @@ $(JUCE_OBJDIR)/include_juce_opengl_a8a032b.o: ../../JuceLibraryCode/include_juce @echo "Compiling include_juce_opengl.cpp" $(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<" -$(JUCE_OBJDIR)/include_juce_video_be78589.o: ../../JuceLibraryCode/include_juce_video.cpp - -$(V_AT)mkdir -p $(JUCE_OBJDIR) - @echo "Compiling include_juce_video.cpp" - $(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<" - clean: @echo Cleaning AudioPluginHost $(V_AT)$(CLEANCMD) diff --git a/extras/AudioPluginHost/Builds/MacOSX/App.entitlements b/extras/AudioPluginHost/Builds/MacOSX/App.entitlements deleted file mode 100644 index 6631ffa6..00000000 --- a/extras/AudioPluginHost/Builds/MacOSX/App.entitlements +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> -</dict> -</plist> diff --git a/extras/AudioPluginHost/Builds/MacOSX/AudioPluginHost.xcodeproj/project.pbxproj b/extras/AudioPluginHost/Builds/MacOSX/AudioPluginHost.xcodeproj/project.pbxproj index 9afcda35..be04d35d 100644 --- a/extras/AudioPluginHost/Builds/MacOSX/AudioPluginHost.xcodeproj/project.pbxproj +++ b/extras/AudioPluginHost/Builds/MacOSX/AudioPluginHost.xcodeproj/project.pbxproj @@ -21,14 +21,6 @@ isa = PBXBuildFile; fileRef = D4EBC17BDB7F88CCBC76730B; }; - 851C1165C9E4ACDD19C56A96 = { - isa = PBXBuildFile; - fileRef = 942A0F04EFB8D0B2FF9780BA; - }; - AF42316D915057E930A5624E = { - isa = PBXBuildFile; - fileRef = A4B568E26157FC282214976F; - }; 2B4B9CF71F94BDD1E3AC89AE = { isa = PBXBuildFile; fileRef = B0935EBBA4F6E2B05F3D1C0A; @@ -45,10 +37,6 @@ isa = PBXBuildFile; fileRef = E68018DE199135B7F738FB17; }; - 3470F40DA5D68EC217872906 = { - isa = PBXBuildFile; - fileRef = 31D55A751C790CB81F58DDB7; - }; E092A70431B046BF1F50A482 = { isa = PBXBuildFile; fileRef = 5AF0CA7CDFCA90B4DE1F55C3; @@ -57,6 +45,10 @@ isa = PBXBuildFile; fileRef = B8774D8AD307D798831C0DF7; }; + 9056B642BEF870098DE344E5 = { + isa = PBXBuildFile; + fileRef = 03FA420AACDD03D50AA16E4A; + }; 68FBFDA1FE637B3EDA09A592 = { isa = PBXBuildFile; fileRef = 4DF6E6E41E10965AD169143B; @@ -73,6 +65,10 @@ isa = PBXBuildFile; fileRef = B457EE687507BF1DEEA7581F; }; + FE22E1AF24FA9ED43E983B81 = { + isa = PBXBuildFile; + fileRef = 5F0ADA39C70C892758A941F6; + }; D92C7BF86C9CCF6B4D14F809 = { isa = PBXBuildFile; fileRef = 7DA35787B5F6F7440D667CC8; @@ -141,6 +137,10 @@ isa = PBXBuildFile; fileRef = 5EF1D381F42AA8764597F189; }; + A5F0B3B7175766C8AF1D6C3E = { + isa = PBXBuildFile; + fileRef = 36689CA4EFC2AF183A0848AE; + }; 7DE202DC1D876F49266D9E7D = { isa = PBXBuildFile; fileRef = 8290D7BAC160B3A56B66891A; @@ -161,9 +161,12 @@ isa = PBXBuildFile; fileRef = 37E4D5C341406B7072120006; }; - 84BAFE82A102D9C350672689 = { - isa = PBXBuildFile; - fileRef = 29D746FC68F69751796671A2; + 03FA420AACDD03D50AA16E4A = { + isa = PBXFileReference; + lastKnownFileType = wrapper.framework; + name = Foundation.framework; + path = System/Library/Frameworks/Foundation.framework; + sourceTree = SDKROOT; }; 04AABCD3491318FB32E844B4 = { isa = PBXFileReference; @@ -193,13 +196,6 @@ path = ../../JuceLibraryCode/BinaryData.h; sourceTree = "SOURCE_ROOT"; }; - 29D746FC68F69751796671A2 = { - isa = PBXFileReference; - lastKnownFileType = sourcecode.cpp.objcpp; - name = "include_juce_video.mm"; - path = "../../JuceLibraryCode/include_juce_video.mm"; - sourceTree = "SOURCE_ROOT"; - }; 2A6983F82B13F9E8B10299AE = { isa = PBXFileReference; lastKnownFileType = file.icns; @@ -214,20 +210,13 @@ path = "../../JuceLibraryCode/include_juce_gui_extra.mm"; sourceTree = "SOURCE_ROOT"; }; - 30F22843EFEBF7AA841EB4D6 = { + 36689CA4EFC2AF183A0848AE = { isa = PBXFileReference; - lastKnownFileType = sourcecode.c.h; - name = AppConfig.h; - path = ../../JuceLibraryCode/AppConfig.h; + lastKnownFileType = sourcecode.cpp.objcpp; + name = "include_juce_dsp.mm"; + path = "../../JuceLibraryCode/include_juce_dsp.mm"; sourceTree = "SOURCE_ROOT"; }; - 31D55A751C790CB81F58DDB7 = { - isa = PBXFileReference; - lastKnownFileType = wrapper.framework; - name = CoreMedia.framework; - path = System/Library/Frameworks/CoreMedia.framework; - sourceTree = SDKROOT; - }; 37E4D5C341406B7072120006 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; @@ -326,6 +315,13 @@ path = "../../JuceLibraryCode/include_juce_data_structures.mm"; sourceTree = "SOURCE_ROOT"; }; + 5F0ADA39C70C892758A941F6 = { + isa = PBXFileReference; + lastKnownFileType = folder; + name = Assets; + path = ../../../../examples/Assets; + sourceTree = "<group>"; + }; 5FBD6C402617272052BB4D81 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; @@ -424,6 +420,13 @@ path = "../../JuceLibraryCode/include_juce_gui_basics.mm"; sourceTree = "SOURCE_ROOT"; }; + 9320A145F2A8ACD687D6608E = { + isa = PBXFileReference; + lastKnownFileType = file; + name = "juce_dsp"; + path = "../../../../modules/juce_dsp"; + sourceTree = "SOURCE_ROOT"; + }; 938AE72315C6C93949F6220E = { isa = PBXFileReference; lastKnownFileType = file; @@ -431,13 +434,6 @@ path = "../../../../modules/juce_gui_basics"; sourceTree = "SOURCE_ROOT"; }; - 942A0F04EFB8D0B2FF9780BA = { - isa = PBXFileReference; - lastKnownFileType = wrapper.framework; - name = AVFoundation.framework; - path = System/Library/Frameworks/AVFoundation.framework; - sourceTree = SDKROOT; - }; 94CB96C8E4B51F52776C2638 = { isa = PBXFileReference; lastKnownFileType = file; @@ -466,13 +462,6 @@ path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; }; - A4B568E26157FC282214976F = { - isa = PBXFileReference; - lastKnownFileType = wrapper.framework; - name = AVKit.framework; - path = System/Library/Frameworks/AVKit.framework; - sourceTree = SDKROOT; - }; A5DFC13E4F09134B0D226A3E = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; @@ -571,13 +560,6 @@ path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; - DDE115D3084ACA6DD6AA4471 = { - isa = PBXFileReference; - lastKnownFileType = file; - name = "juce_video"; - path = "../../../../modules/juce_video"; - sourceTree = "SOURCE_ROOT"; - }; E68018DE199135B7F738FB17 = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; @@ -675,12 +657,12 @@ 3D57FE2A8877F12A61054726, FA21631C5536EA3DF55C7FA6, B86B918291E1090C6A720971, + 9320A145F2A8ACD687D6608E, 59842A98E5EBBC54B50C04CD, 94CB96C8E4B51F52776C2638, 938AE72315C6C93949F6220E, F299BECFB2AEA6105F014848, 81C1A7770E082F56FE5A90A7, - DDE115D3084ACA6DD6AA4471, ); name = "JUCE Modules"; sourceTree = "<group>"; @@ -688,7 +670,6 @@ 7E30376DDAD775FEFE64944C = { isa = PBXGroup; children = ( - 30F22843EFEBF7AA841EB4D6, 6D107D7946DC5976B766345B, 1DADAD8E34AAF4AFF1C69DC4, 4C7D82F9274A4F9DBF11235C, @@ -699,12 +680,12 @@ 683CEE986A2467C850FE99E6, B8E24A5CEE6B7055537725CF, 5EF1D381F42AA8764597F189, + 36689CA4EFC2AF183A0848AE, 8290D7BAC160B3A56B66891A, 82800DBA287EF4BAB13B42FB, 8FE7B37CDE0818DB27BDDEBD, 2BE6C2DFD6EBB9A89109AEB5, 37E4D5C341406B7072120006, - 29D746FC68F69751796671A2, A5E7CA8A71D049BE2BD33861, ); name = "JUCE Library Code"; @@ -713,6 +694,7 @@ A97EE73C79DA3F729D46AF48 = { isa = PBXGroup; children = ( + 5F0ADA39C70C892758A941F6, 57DF618F1DE781556B7AFC32, 7DA35787B5F6F7440D667CC8, 2A6983F82B13F9E8B10299AE, @@ -726,15 +708,13 @@ 5ACC21AA45BBF48C3C64D56D, 86CA337014D3F67E906FFD28, D4EBC17BDB7F88CCBC76730B, - 942A0F04EFB8D0B2FF9780BA, - A4B568E26157FC282214976F, B0935EBBA4F6E2B05F3D1C0A, 9794142D24966F93FFDE51A1, 9F9B445E6755CAA19E4344ED, E68018DE199135B7F738FB17, - 31D55A751C790CB81F58DDB7, 5AF0CA7CDFCA90B4DE1F55C3, B8774D8AD307D798831C0DF7, + 03FA420AACDD03D50AA16E4A, 4DF6E6E41E10965AD169143B, D313CF37B25D7FD313C4F336, 89309C0C5F3269BD06BE7F27, @@ -779,6 +759,36 @@ GCC_PREPROCESSOR_DEFINITIONS = ( "_DEBUG=1", "DEBUG=1", + "JUCE_DISPLAY_SPLASH_SCREEN=0", + "JUCE_USE_DARK_SPLASH_SCREEN=1", + "JUCE_PROJUCER_VERSION=0x60005", + "JUCE_MODULE_AVAILABLE_juce_audio_basics=1", + "JUCE_MODULE_AVAILABLE_juce_audio_devices=1", + "JUCE_MODULE_AVAILABLE_juce_audio_formats=1", + "JUCE_MODULE_AVAILABLE_juce_audio_processors=1", + "JUCE_MODULE_AVAILABLE_juce_audio_utils=1", + "JUCE_MODULE_AVAILABLE_juce_core=1", + "JUCE_MODULE_AVAILABLE_juce_cryptography=1", + "JUCE_MODULE_AVAILABLE_juce_data_structures=1", + "JUCE_MODULE_AVAILABLE_juce_dsp=1", + "JUCE_MODULE_AVAILABLE_juce_events=1", + "JUCE_MODULE_AVAILABLE_juce_graphics=1", + "JUCE_MODULE_AVAILABLE_juce_gui_basics=1", + "JUCE_MODULE_AVAILABLE_juce_gui_extra=1", + "JUCE_MODULE_AVAILABLE_juce_opengl=1", + "JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1", + "JUCE_WASAPI=1", + "JUCE_DIRECTSOUND=1", + "JUCE_ALSA=1", + "JUCE_USE_FLAC=0", + "JUCE_USE_OGGVORBIS=1", + "JUCE_PLUGINHOST_VST3=1", + "JUCE_PLUGINHOST_AU=1", + "JUCE_PLUGINHOST_LADSPA=1", + "JUCE_USE_CDREADER=0", + "JUCE_USE_CDBURNER=0", + "JUCE_WEB_BROWSER=0", + "JUCE_STANDALONE_APPLICATION=1", "JUCER_XCODE_MAC_F6D2F4CF=1", "JUCE_APP_VERSION=1.0.0", "JUCE_APP_VERSION_HEX=0x10000", @@ -802,10 +812,16 @@ INFOPLIST_PREPROCESS = NO; INSTALL_PATH = "$(HOME)/Applications"; MACOSX_DEPLOYMENT_TARGET = 10.11; - OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow-all -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wunreachable-code -Wzero-as-null-pointer-constant -Wcast-align -Winconsistent-missing-destructor-override -Wshift-sign-overflow -Wnullable-to-nonnull-conversion -Wno-missing-field-initializers -Wno-ignored-qualifiers"; - PRODUCT_BUNDLE_IDENTIFIER = com.roli.juce.pluginhost; + MTL_HEADER_SEARCH_PATHS = ( + "../../../../modules/juce_audio_processors/format_types/VST3_SDK", + "../../JuceLibraryCode", + "../../../../modules", + ); + OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow-all -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wunreachable-code -Wzero-as-null-pointer-constant -Wcast-align -Winconsistent-missing-destructor-override -Wshift-sign-overflow -Wnullable-to-nonnull-conversion -Wno-missing-field-initializers -Wno-ignored-qualifiers -Wswitch-enum"; + PRODUCT_BUNDLE_IDENTIFIER = com.juce.pluginhost; PRODUCT_NAME = "AudioPluginHost"; USE_HEADERMAP = NO; + VALID_ARCHS = "i386 x86_64 arm64 arm64e"; }; name = Debug; }; @@ -824,6 +840,36 @@ GCC_PREPROCESSOR_DEFINITIONS = ( "_NDEBUG=1", "NDEBUG=1", + "JUCE_DISPLAY_SPLASH_SCREEN=0", + "JUCE_USE_DARK_SPLASH_SCREEN=1", + "JUCE_PROJUCER_VERSION=0x60005", + "JUCE_MODULE_AVAILABLE_juce_audio_basics=1", + "JUCE_MODULE_AVAILABLE_juce_audio_devices=1", + "JUCE_MODULE_AVAILABLE_juce_audio_formats=1", + "JUCE_MODULE_AVAILABLE_juce_audio_processors=1", + "JUCE_MODULE_AVAILABLE_juce_audio_utils=1", + "JUCE_MODULE_AVAILABLE_juce_core=1", + "JUCE_MODULE_AVAILABLE_juce_cryptography=1", + "JUCE_MODULE_AVAILABLE_juce_data_structures=1", + "JUCE_MODULE_AVAILABLE_juce_dsp=1", + "JUCE_MODULE_AVAILABLE_juce_events=1", + "JUCE_MODULE_AVAILABLE_juce_graphics=1", + "JUCE_MODULE_AVAILABLE_juce_gui_basics=1", + "JUCE_MODULE_AVAILABLE_juce_gui_extra=1", + "JUCE_MODULE_AVAILABLE_juce_opengl=1", + "JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1", + "JUCE_WASAPI=1", + "JUCE_DIRECTSOUND=1", + "JUCE_ALSA=1", + "JUCE_USE_FLAC=0", + "JUCE_USE_OGGVORBIS=1", + "JUCE_PLUGINHOST_VST3=1", + "JUCE_PLUGINHOST_AU=1", + "JUCE_PLUGINHOST_LADSPA=1", + "JUCE_USE_CDREADER=0", + "JUCE_USE_CDBURNER=0", + "JUCE_WEB_BROWSER=0", + "JUCE_STANDALONE_APPLICATION=1", "JUCER_XCODE_MAC_F6D2F4CF=1", "JUCE_APP_VERSION=1.0.0", "JUCE_APP_VERSION_HEX=0x10000", @@ -836,7 +882,6 @@ "JucePlugin_Build_Standalone=0", "JucePlugin_Build_Unity=0", ); - GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; HEADER_SEARCH_PATHS = ( "../../../../modules/juce_audio_processors/format_types/VST3_SDK", @@ -849,10 +894,16 @@ INSTALL_PATH = "$(HOME)/Applications"; LLVM_LTO = YES; MACOSX_DEPLOYMENT_TARGET = 10.11; - OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow-all -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wunreachable-code -Wzero-as-null-pointer-constant -Wcast-align -Winconsistent-missing-destructor-override -Wshift-sign-overflow -Wnullable-to-nonnull-conversion -Wno-missing-field-initializers -Wno-ignored-qualifiers"; - PRODUCT_BUNDLE_IDENTIFIER = com.roli.juce.pluginhost; + MTL_HEADER_SEARCH_PATHS = ( + "../../../../modules/juce_audio_processors/format_types/VST3_SDK", + "../../JuceLibraryCode", + "../../../../modules", + ); + OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow-all -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wunreachable-code -Wzero-as-null-pointer-constant -Wcast-align -Winconsistent-missing-destructor-override -Wshift-sign-overflow -Wnullable-to-nonnull-conversion -Wno-missing-field-initializers -Wno-ignored-qualifiers -Wswitch-enum"; + PRODUCT_BUNDLE_IDENTIFIER = com.juce.pluginhost; PRODUCT_NAME = "AudioPluginHost"; USE_HEADERMAP = NO; + VALID_ARCHS = "i386 x86_64 arm64 arm64e"; }; name = Release; }; @@ -881,11 +932,12 @@ CODE_SIGN_IDENTITY = ""; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; + ENABLE_TESTABILITY = NO; GCC_C_LANGUAGE_STANDARD = c11; GCC_INLINES_ARE_PRIVATE_EXTERN = YES; GCC_MODEL_TUNING = G5; GCC_NO_COMMON_BLOCKS = YES; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; @@ -929,10 +981,12 @@ CODE_SIGN_IDENTITY = ""; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = NO; GCC_C_LANGUAGE_STANDARD = c11; GCC_INLINES_ARE_PRIVATE_EXTERN = YES; GCC_MODEL_TUNING = G5; GCC_NO_COMMON_BLOCKS = YES; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; @@ -950,10 +1004,6 @@ }; name = Release; }; - B9D79D85AC7DE5BED1B6547C = { - isa = PBXTargetDependency; - target = DE12B7643D374BFF7E4FEB1C; - }; 493C2C5E457692E5149C5525 = { isa = XCConfigurationList; buildConfigurations = ( @@ -976,6 +1026,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + FE22E1AF24FA9ED43E983B81, D92C7BF86C9CCF6B4D14F809, 443244451A0F2064D4767337, ); @@ -1000,12 +1051,12 @@ 76A80851698FC773D2479B4E, E4A926EF695823F0F13268FF, A09E93F1B354E1FF8B3E9ABE, + A5F0B3B7175766C8AF1D6C3E, 7DE202DC1D876F49266D9E7D, 075C54DDDBDEA5AAD2F60154, 2C3D221D2AA87F07B3F1044D, C38D14DC58F1941DD5E4BF60, 2727A191DB1BAAC9C04B9081, - 84BAFE82A102D9C350672689, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1016,15 +1067,13 @@ B288A89F96704F142ED8E939, 73E371F1B912FCCAE0CD7E5D, 21D330A5B13178B12BEAFC3C, - 851C1165C9E4ACDD19C56A96, - AF42316D915057E930A5624E, 2B4B9CF71F94BDD1E3AC89AE, AC3BED74AC7C6D9F5739F38B, E3CB85BA817BC9E3942A8AB0, 70580743C3D5695F065FF698, - 3470F40DA5D68EC217872906, E092A70431B046BF1F50A482, E2BAA7CFC729809530FD71EE, + 9056B642BEF870098DE344E5, 68FBFDA1FE637B3EDA09A592, BBA1733CF8B064A5FD0B4CF4, A02C9F4C4B840C27B6CAFEBD, @@ -1050,7 +1099,7 @@ ADE6E539DB98A302483A82D0 = { isa = PBXProject; buildConfigurationList = 493C2C5E457692E5149C5525; - attributes = { LastUpgradeCheck = 1100; ORGANIZATIONNAME = "ROLI Ltd."; TargetAttributes = { DE12B7643D374BFF7E4FEB1C = { SystemCapabilities = {com.apple.ApplicationGroups.iOS = { enabled = 0; }; com.apple.InAppPurchase = { enabled = 0; }; com.apple.InterAppAudio = { enabled = 0; }; com.apple.Push = { enabled = 0; }; com.apple.Sandbox = { enabled = 0; }; com.apple.HardenedRuntime = { enabled = 0; }; }; }; }; }; + attributes = { LastUpgradeCheck = 1200; ORGANIZATIONNAME = "Raw Material Software Limited"; TargetAttributes = { DE12B7643D374BFF7E4FEB1C = { SystemCapabilities = {com.apple.ApplicationGroups.iOS = { enabled = 0; }; com.apple.InAppPurchase = { enabled = 0; }; com.apple.InterAppAudio = { enabled = 0; }; com.apple.Push = { enabled = 0; }; com.apple.Sandbox = { enabled = 0; }; com.apple.HardenedRuntime = { enabled = 0; }; }; }; }; }; compatibilityVersion = "Xcode 3.2"; hasScannedForEncodings = 0; mainGroup = 65BEFC705A89E5C8A9E35C97; diff --git a/extras/AudioPluginHost/Builds/MacOSX/AudioPluginHost.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/extras/AudioPluginHost/Builds/MacOSX/AudioPluginHost.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings index 949b6789..f2e3cbe8 100644 --- a/extras/AudioPluginHost/Builds/MacOSX/AudioPluginHost.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ b/extras/AudioPluginHost/Builds/MacOSX/AudioPluginHost.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -4,5 +4,7 @@ <dict> <key>BuildSystemType</key> <string>Original</string> + <key>DisableBuildSystemDeprecationWarning</key> + <true/> </dict> </plist> diff --git a/extras/AudioPluginHost/Builds/MacOSX/Icon.icns b/extras/AudioPluginHost/Builds/MacOSX/Icon.icns index 6ab6915802b8cc41702a02e8527aec517d379e77..f207907bcc6e8f34af7435566a26e177fb8b2c83 100644 GIT binary patch literal 95248 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 V<XRb01a={UloizFt7I)A{|}PSUd#Xh literal 89670 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 S)d9x$gS6E2RqK#;(f<d)_aL<Z diff --git a/extras/AudioPluginHost/Builds/MacOSX/Info-App.plist b/extras/AudioPluginHost/Builds/MacOSX/Info-App.plist index ef1b5254..66bb28f5 100644 --- a/extras/AudioPluginHost/Builds/MacOSX/Info-App.plist +++ b/extras/AudioPluginHost/Builds/MacOSX/Info-App.plist @@ -5,12 +5,14 @@ <dict> <key>NSMicrophoneUsageDescription</key> <string>This app requires audio input. If you do not have an audio interface connected it will use the built-in microphone.</string> + <key>NSAppleEventsUsageDescription</key> + <string>This is required for some third-party plug-ins to function correctly.</string> <key>CFBundleExecutable</key> <string>${EXECUTABLE_NAME}</string> <key>CFBundleIconFile</key> <string>Icon.icns</string> <key>CFBundleIdentifier</key> - <string>com.roli.juce.pluginhost</string> + <string>com.juce.pluginhost</string> <key>CFBundleName</key> <string>AudioPluginHost</string> <key>CFBundleDisplayName</key> @@ -24,7 +26,7 @@ <key>CFBundleVersion</key> <string>1.0.0</string> <key>NSHumanReadableCopyright</key> - <string>ROLI Ltd.</string> + <string>Raw Material Software Limited</string> <key>NSHighResolutionCapable</key> <true/> </dict> diff --git a/extras/AudioPluginHost/Builds/VisualStudio2015/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2015/AudioPluginHost_App.vcxproj index 8436bc80..23802851 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2015/AudioPluginHost_App.vcxproj +++ b/extras/AudioPluginHost/Builds/VisualStudio2015/AudioPluginHost_App.vcxproj @@ -64,10 +64,10 @@ <Optimization>Disabled</Optimization> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <AdditionalIncludeDirectories>..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK;..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCER_VS2015_78A5022=1;JUCE_APP_VERSION=1.0.0;JUCE_APP_VERSION_HEX=0x10000;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCE_DISPLAY_SPLASH_SCREEN=0;JUCE_USE_DARK_SPLASH_SCREEN=1;JUCE_PROJUCER_VERSION=0x60005;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_audio_formats=1;JUCE_MODULE_AVAILABLE_juce_audio_processors=1;JUCE_MODULE_AVAILABLE_juce_audio_utils=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_dsp=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_MODULE_AVAILABLE_juce_opengl=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_WASAPI=1;JUCE_DIRECTSOUND=1;JUCE_ALSA=1;JUCE_USE_FLAC=0;JUCE_USE_OGGVORBIS=1;JUCE_PLUGINHOST_VST3=1;JUCE_PLUGINHOST_AU=1;JUCE_PLUGINHOST_LADSPA=1;JUCE_USE_CDREADER=0;JUCE_USE_CDBURNER=0;JUCE_WEB_BROWSER=0;JUCE_STANDALONE_APPLICATION=1;JUCER_VS2015_78A5022=1;JUCE_APP_VERSION=1.0.0;JUCE_APP_VERSION_HEX=0x10000;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> <RuntimeTypeInfo>true</RuntimeTypeInfo> - <PrecompiledHeader/> + <PrecompiledHeader>NotUsing</PrecompiledHeader> <AssemblerListingLocation>$(IntDir)\</AssemblerListingLocation> <ObjectFileName>$(IntDir)\</ObjectFileName> <ProgramDataBaseFileName>$(IntDir)\</ProgramDataBaseFileName> @@ -106,10 +106,10 @@ <ClCompile> <Optimization>Full</Optimization> <AdditionalIncludeDirectories>..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK;..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCER_VS2015_78A5022=1;JUCE_APP_VERSION=1.0.0;JUCE_APP_VERSION_HEX=0x10000;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCE_DISPLAY_SPLASH_SCREEN=0;JUCE_USE_DARK_SPLASH_SCREEN=1;JUCE_PROJUCER_VERSION=0x60005;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_audio_formats=1;JUCE_MODULE_AVAILABLE_juce_audio_processors=1;JUCE_MODULE_AVAILABLE_juce_audio_utils=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_dsp=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_MODULE_AVAILABLE_juce_opengl=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_WASAPI=1;JUCE_DIRECTSOUND=1;JUCE_ALSA=1;JUCE_USE_FLAC=0;JUCE_USE_OGGVORBIS=1;JUCE_PLUGINHOST_VST3=1;JUCE_PLUGINHOST_AU=1;JUCE_PLUGINHOST_LADSPA=1;JUCE_USE_CDREADER=0;JUCE_USE_CDBURNER=0;JUCE_WEB_BROWSER=0;JUCE_STANDALONE_APPLICATION=1;JUCER_VS2015_78A5022=1;JUCE_APP_VERSION=1.0.0;JUCE_APP_VERSION_HEX=0x10000;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> <RuntimeTypeInfo>true</RuntimeTypeInfo> - <PrecompiledHeader/> + <PrecompiledHeader>NotUsing</PrecompiledHeader> <AssemblerListingLocation>$(IntDir)\</AssemblerListingLocation> <ObjectFileName>$(IntDir)\</ObjectFileName> <ProgramDataBaseFileName>$(IntDir)\</ProgramDataBaseFileName> @@ -132,6 +132,7 @@ <OptimizeReferences>true</OptimizeReferences> <EnableCOMDATFolding>true</EnableCOMDATFolding> <LargeAddressAware>true</LargeAddressAware> + <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> </Link> <Bscmake> <SuppressStartupBanner>true</SuppressStartupBanner> @@ -230,10 +231,10 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_basics\synthesisers\juce_Synthesiser.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_CatmullRomInterpolator.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Interpolators.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_LagrangeInterpolator.cpp"> @@ -242,6 +243,9 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_SmoothedValue.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_WindowedSincInterpolator.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_basics\juce_audio_basics.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -260,6 +264,153 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_devices\midi_io\juce_MidiMessageCollector.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AAudioLoader.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AudioStreamAAudio.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioSourceCaller.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioStream.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioStreamBuilder.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\DataConversionFlowGraph.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FilterAudioStream.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockAdapter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockReader.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockWriter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\LatencyTuner.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\QuirksManager.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceFloatCaller.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceI16Caller.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\StabilizedCallback.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Trace.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Utilities.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Version.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoBuffer.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoController.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerBase.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerIndirect.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\IntegerRatio.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\LinearResampler.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\MultiChannelResampler.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResampler.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerMono.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerStereo.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResampler.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResamplerStereo.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ClipToRange.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\FlowGraphNode.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ManyToMultiConverter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\MonoToMultiConverter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\RampLinear.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SampleRateConverter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkFloat.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI16.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI24.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceFloat.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI16.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI24.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioInputStreamOpenSLES.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioOutputStreamOpenSLES.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamBuffered.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamOpenSLES.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\EngineOpenSLES.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OpenSLESUtilities.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OutputMixerOpenSLES.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_android_Audio.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -359,70 +510,73 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\libFLAC\window_flac.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\analysis.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\analysis.c"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\bitrate.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\bitrate.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\block.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\block.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codebook.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codebook.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\envelope.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\envelope.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\floor0.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\floor0.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\floor1.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\floor1.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\info.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\info.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lpc.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lpc.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lsp.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lsp.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mapping0.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mapping0.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mdct.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mdct.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\misc.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\psy.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\psy.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\registry.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\registry.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\res0.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\res0.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\sharedbook.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\sharedbook.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\smallft.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\smallft.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\synthesis.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\synthesis.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\vorbisenc.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\vorbisenc.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\vorbisfile.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\vorbisfile.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\window.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\window.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\bitwise.c"> @@ -617,6 +771,9 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioProcessorValueTreeState.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_ParameterAttachments.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_RangedAudioParameter.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -719,6 +876,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_FileSearchPath.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -746,6 +906,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_MemoryBlock.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -1022,6 +1185,114 @@ <ClCompile Include="..\..\..\..\modules\juce_data_structures\juce_data_structures.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_AudioBlock_test.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_FixedSizeFunction_test.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_SIMDRegister_test.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\filter_design\juce_FilterDesign.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_Convolution.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_Convolution_test.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_FFT.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_FFT_test.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_Windowing.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\maths\juce_LogRampedValue_test.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\maths\juce_LookupTable.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\maths\juce_Matrix.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\maths\juce_Matrix_test.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\maths\juce_SpecialFunctions.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\native\juce_avx_SIMDNativeOps.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\native\juce_neon_SIMDNativeOps.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\native\juce_sse_SIMDNativeOps.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_BallisticsFilter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_DelayLine.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_DryWetMixer.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_FIRFilter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_FIRFilter_test.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_FirstOrderTPTFilter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_IIRFilter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_LinkwitzRileyFilter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_Oversampling.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_Panner.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessorChain_test.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_StateVariableTPTFilter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_Chorus.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_Compressor.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_LadderFilter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_Limiter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_NoiseGate.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_Phaser.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\juce_dsp.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_events\broadcasters\juce_ActionBroadcaster.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -1631,6 +1902,15 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_MouseListener.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_DragAndDrop.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_android_ContentSharer.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -1649,13 +1929,7 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_FileChooser.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.cpp"> - <ExcludedFromBuild>true</ExcludedFromBuild> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Clipboard.cpp"> - <ExcludedFromBuild>true</ExcludedFromBuild> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Windowing.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_Windowing.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_win32_DragAndDrop.cpp"> @@ -1859,6 +2133,9 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_ActiveXComponent.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_HWNDComponent.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_SystemTrayIcon.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -1898,15 +2175,6 @@ <ClCompile Include="..\..\..\..\modules\juce_opengl\juce_opengl.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_video\capture\juce_CameraDevice.cpp"> - <ExcludedFromBuild>true</ExcludedFromBuild> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_video\playback\juce_VideoComponent.cpp"> - <ExcludedFromBuild>true</ExcludedFromBuild> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_video\juce_video.cpp"> - <ExcludedFromBuild>true</ExcludedFromBuild> - </ClCompile> <ClCompile Include="..\..\JuceLibraryCode\BinaryData.cpp"/> <ClCompile Include="..\..\JuceLibraryCode\include_juce_audio_basics.cpp"/> <ClCompile Include="..\..\JuceLibraryCode\include_juce_audio_devices.cpp"/> @@ -1916,12 +2184,12 @@ <ClCompile Include="..\..\JuceLibraryCode\include_juce_core.cpp"/> <ClCompile Include="..\..\JuceLibraryCode\include_juce_cryptography.cpp"/> <ClCompile Include="..\..\JuceLibraryCode\include_juce_data_structures.cpp"/> + <ClCompile Include="..\..\JuceLibraryCode\include_juce_dsp.cpp"/> <ClCompile Include="..\..\JuceLibraryCode\include_juce_events.cpp"/> <ClCompile Include="..\..\JuceLibraryCode\include_juce_graphics.cpp"/> <ClCompile Include="..\..\JuceLibraryCode\include_juce_gui_basics.cpp"/> <ClCompile Include="..\..\JuceLibraryCode\include_juce_gui_extra.cpp"/> <ClCompile Include="..\..\JuceLibraryCode\include_juce_opengl.cpp"/> - <ClCompile Include="..\..\JuceLibraryCode\include_juce_video.cpp"/> </ItemGroup> <ItemGroup> <ClInclude Include="..\..\Source\Plugins\InternalPlugins.h"/> @@ -1964,10 +2232,10 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_basics\sources\juce_ToneGeneratorAudioSource.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\synthesisers\juce_Synthesiser.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_ADSR.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_CatmullRomInterpolator.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Decibels.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_GenericInterpolator.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_LagrangeInterpolator.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Interpolators.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Reverb.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_SmoothedValue.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\juce_audio_basics.h"/> @@ -1977,6 +2245,66 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_devices\audio_io\juce_SystemAudioVolume.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\midi_io\juce_MidiDevices.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\midi_io\juce_MidiMessageCollector.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStream.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamBase.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamBuilder.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamCallback.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Definitions.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\LatencyTuner.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Oboe.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\ResultWithValue.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\StabilizedCallback.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Utilities.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Version.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AAudioLoader.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AudioStreamAAudio.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioClock.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioSourceCaller.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\DataConversionFlowGraph.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FilterAudioStream.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockAdapter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockReader.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockWriter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\MonotonicCounter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\OboeDebug.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\QuirksManager.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceFloatCaller.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceI16Caller.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Trace.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoBuffer.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoController.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerBase.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerIndirect.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\HyperbolicCosineWindow.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\IntegerRatio.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\KaiserWindow.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\LinearResampler.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\MultiChannelResampler.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResampler.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerMono.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerStereo.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResampler.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResamplerStereo.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ClipToRange.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\FlowGraphNode.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ManyToMultiConverter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\MonoToMultiConverter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\RampLinear.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SampleRateConverter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkFloat.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI16.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI24.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceFloat.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI16.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI24.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioInputStreamOpenSLES.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioOutputStreamOpenSLES.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamBuffered.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamOpenSLES.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\EngineOpenSLES.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OpenSLESUtilities.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OutputMixerOpenSLES.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\juce_android_HighPerformanceAudioHelpers.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\juce_ios_Audio.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\juce_MidiDataConcatenator.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\sources\juce_AudioSourcePlayer.h"/> @@ -2014,50 +2342,51 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\stream_decoder.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\stream_encoder.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\win_utf8_io.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled\res_books_51.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled\res_books_stereo.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\floor\floor_books.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\uncoupled\res_books_uncoupled.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\floor_all.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_8.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_11.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_16.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_44.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_8.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_16.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44p51.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44u.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_8.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_11.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_16.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_22.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_32.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44p51.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44u.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_X.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\backends.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\bitrate.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codebook.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codec_internal.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\envelope.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\highlevel.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup_data.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lpc.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lsp.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\masking.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mdct.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\misc.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\os.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\psy.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\registry.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\scales.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\smallft.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\window.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled\res_books_51.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled\res_books_stereo.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\floor\floor_books.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\uncoupled\res_books_uncoupled.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\floor_all.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_8.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_11.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_16.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_44.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_8.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_16.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44p51.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44u.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_8.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_11.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_16.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_22.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_32.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44p51.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44u.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_X.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\backends.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\bitrate.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codebook.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codec_internal.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\envelope.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\highlevel.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup_data.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lpc.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lsp.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\masking.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mdct.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\misc.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\os.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\psy.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\registry.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\scales.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\smallft.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\window.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\codec.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\config_types.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\crctable.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\ogg.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\os_types.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\vorbisenc.h"/> @@ -2146,6 +2475,7 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst\vsteditcontroller.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst\vstparameters.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst\vstpresetfile.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_AU_Shared.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_AudioUnitPluginFormat.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LADSPAPluginFormat.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_VST3Common.h"/> @@ -2172,6 +2502,7 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioParameterInt.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioProcessorParameterWithID.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioProcessorValueTreeState.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_ParameterAttachments.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_RangedAudioParameter.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\juce_audio_processors.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_utils\audio_cd\juce_AudioCDBurner.h"/> @@ -2211,6 +2542,7 @@ <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_FileOutputStream.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_FileSearchPath.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_MemoryMappedFile.h"/> + <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_WildcardFileFilter.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\javascript\juce_Javascript.h"/> @@ -2224,6 +2556,7 @@ <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_Random.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_Range.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_StatisticsAccumulator.h"/> + <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_Atomic.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_ByteOrder.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_ContainerDeletePolicy.h"/> @@ -2266,6 +2599,7 @@ <ClInclude Include="..\..\..\..\modules\juce_core\streams\juce_SubregionStream.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\streams\juce_URLInputSource.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerSupport.h"/> + <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerWarnings.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_PlatformDefs.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_StandardHeader.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_SystemStats.h"/> @@ -2340,6 +2674,53 @@ <ClInclude Include="..\..\..\..\modules\juce_data_structures\values\juce_ValueTreeSynchroniser.h"/> <ClInclude Include="..\..\..\..\modules\juce_data_structures\values\juce_ValueWithDefault.h"/> <ClInclude Include="..\..\..\..\modules\juce_data_structures\juce_data_structures.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\containers\juce_AudioBlock.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\containers\juce_FixedSizeFunction.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\containers\juce_SIMDRegister.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\containers\juce_SIMDRegister_Impl.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\filter_design\juce_FilterDesign.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\frequency\juce_Convolution.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\frequency\juce_FFT.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\frequency\juce_Windowing.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_FastMathApproximations.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_LogRampedValue.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_LookupTable.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_Matrix.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_Phase.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_Polynomial.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_SpecialFunctions.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\native\juce_avx_SIMDNativeOps.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\native\juce_fallback_SIMDNativeOps.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\native\juce_neon_SIMDNativeOps.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\native\juce_sse_SIMDNativeOps.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_BallisticsFilter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_DelayLine.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_DryWetMixer.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_FIRFilter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_FirstOrderTPTFilter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_IIRFilter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_IIRFilter_Impl.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_LinkwitzRileyFilter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_Oversampling.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_Panner.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessContext.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessorChain.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessorDuplicator.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessorWrapper.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_StateVariableFilter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_StateVariableTPTFilter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Bias.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Chorus.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Compressor.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Gain.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_LadderFilter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Limiter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_NoiseGate.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Oscillator.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Phaser.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Reverb.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_WaveShaper.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\juce_dsp.h"/> <ClInclude Include="..\..\..\..\modules\juce_events\broadcasters\juce_ActionBroadcaster.h"/> <ClInclude Include="..\..\..\..\modules\juce_events\broadcasters\juce_ActionListener.h"/> <ClInclude Include="..\..\..\..\modules\juce_events\broadcasters\juce_AsyncUpdater.h"/> @@ -2522,7 +2903,8 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_SelectedItemSet.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_TextDragAndDropTarget.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_TooltipClient.h"/> - <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.h"/> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.h"/> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_MultiTouchMapper.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\positioning\juce_MarkerList.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\positioning\juce_RelativeCoordinate.h"/> @@ -2574,6 +2956,7 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ActiveXControlComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"/> + <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_HWNDComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_NSViewComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ScopedDPIAwarenessDisabler.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_UIViewComponent.h"/> @@ -2614,23 +2997,15 @@ <ClInclude Include="..\..\..\..\modules\juce_opengl\opengl\juce_OpenGLTexture.h"/> <ClInclude Include="..\..\..\..\modules\juce_opengl\utils\juce_OpenGLAppComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_opengl\juce_opengl.h"/> - <ClInclude Include="..\..\..\..\modules\juce_video\capture\juce_CameraDevice.h"/> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_android_CameraDevice.h"/> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_android_Video.h"/> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_ios_CameraDevice.h"/> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_mac_CameraDevice.h"/> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_mac_Video.h"/> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_win32_CameraDevice.h"/> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_win32_Video.h"/> - <ClInclude Include="..\..\..\..\modules\juce_video\playback\juce_VideoComponent.h"/> - <ClInclude Include="..\..\..\..\modules\juce_video\juce_video.h"/> - <ClInclude Include="..\..\JuceLibraryCode\AppConfig.h"/> <ClInclude Include="..\..\JuceLibraryCode\BinaryData.h"/> <ClInclude Include="..\..\JuceLibraryCode\JuceHeader.h"/> </ItemGroup> <ItemGroup> <None Include="..\..\Source\JUCEAppIcon.png"/> + <None Include="..\..\..\..\modules\juce_audio_devices\native\oboe\CMakeLists.txt"/> + <None Include="..\..\..\..\modules\juce_audio_devices\native\oboe\readme.md"/> <None Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\Flac Licence.txt"/> + <None Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\README.md"/> <None Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\Ogg Vorbis Licence.txt"/> <None Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\base\LICENSE.txt"/> <None Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\base\README.md"/> diff --git a/extras/AudioPluginHost/Builds/VisualStudio2015/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2015/AudioPluginHost_App.vcxproj.filters index f60af172..dae2e654 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2015/AudioPluginHost_App.vcxproj.filters +++ b/extras/AudioPluginHost/Builds/VisualStudio2015/AudioPluginHost_App.vcxproj.filters @@ -47,6 +47,36 @@ <Filter Include="JUCE Modules\juce_audio_devices\midi_io"> <UniqueIdentifier>{092EFC17-7C95-7E04-0ACA-0D61A462EE81}</UniqueIdentifier> </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\include\oboe"> + <UniqueIdentifier>{285118C6-8FDA-7DCE-BEF4-FFB2120876C5}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\include"> + <UniqueIdentifier>{69ED6B61-9B8D-D47E-E4A6-2E9F9A94A75A}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\aaudio"> + <UniqueIdentifier>{7CDB7CD1-BB96-F593-3C78-1E06182B5839}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\common"> + <UniqueIdentifier>{B0A708DE-B4CF-196B-14FB-DC8221509B8E}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\fifo"> + <UniqueIdentifier>{34F46ADE-EE31-227A-A69E-7732E70145F1}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler"> + <UniqueIdentifier>{BB9B3C77-17FB-E994-8B75-88F1727E4655}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph"> + <UniqueIdentifier>{C0971D77-2F14-190A-E2AE-89D6285F4D5A}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\opensles"> + <UniqueIdentifier>{AABEA333-6524-8891-51C7-6DAEB5700628}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src"> + <UniqueIdentifier>{F2D29337-983E-BAD7-7B5C-E0AB3D53D404}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe"> + <UniqueIdentifier>{C674B0FB-1FC0-2986-94B1-083845018994}</UniqueIdentifier> + </Filter> <Filter Include="JUCE Modules\juce_audio_devices\native"> <UniqueIdentifier>{0AFC1CE8-F6E6-9817-8C21-8432B2A375DA}</UniqueIdentifier> </Filter> @@ -71,26 +101,26 @@ <Filter Include="JUCE Modules\juce_audio_formats\codecs\flac"> <UniqueIdentifier>{9EB3EC7F-2AB7-DDAA-3C05-DF382B728D3F}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled"> - <UniqueIdentifier>{02D37B85-7DE2-C8E7-A274-A5A0FBE99D69}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled"> + <UniqueIdentifier>{6B9FBFDC-1D10-6246-356D-00FF4535CECB}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\floor"> - <UniqueIdentifier>{DAF3BAAF-5207-4C34-61B9-A97DDC930D50}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\floor"> + <UniqueIdentifier>{D6FCFC8E-7136-9109-78C0-91A3EB4C443F}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\uncoupled"> - <UniqueIdentifier>{C7885588-8436-4C21-DC1E-58879BF53BDC}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\uncoupled"> + <UniqueIdentifier>{EBF18AC1-F0ED-937A-2824-4307CE2ADAF7}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books"> - <UniqueIdentifier>{E4ECEA39-0EFF-2443-91B3-1E5DA7AD5AE4}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books"> + <UniqueIdentifier>{5A0F7922-2EFB-6465-57E4-A445B804EFB5}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes"> - <UniqueIdentifier>{210B8D25-68E0-32C3-1449-6A40F109C5E9}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes"> + <UniqueIdentifier>{4EC45416-0E7C-7567-6F75-D0C8CEE7DC4F}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib"> - <UniqueIdentifier>{378AD911-E8E4-D230-E76B-34542849509D}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib"> + <UniqueIdentifier>{C2985031-0496-55B5-41A8-BAB99E53D89D}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2"> - <UniqueIdentifier>{F6CED5B6-0A8C-56D2-C1AC-DED6BE774A13}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7"> + <UniqueIdentifier>{FB4AB426-7009-0036-BB75-E34256AA7C89}</UniqueIdentifier> </Filter> <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis"> <UniqueIdentifier>{E684D858-09E8-0251-8E86-5657129641E1}</UniqueIdentifier> @@ -266,6 +296,30 @@ <Filter Include="JUCE Modules\juce_data_structures"> <UniqueIdentifier>{911F0159-A7A8-4A43-3FD4-154F62F4A44B}</UniqueIdentifier> </Filter> + <Filter Include="JUCE Modules\juce_dsp\containers"> + <UniqueIdentifier>{53CF03D3-988B-CD28-9130-CE08FDCEF7E9}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_dsp\filter_design"> + <UniqueIdentifier>{29C6FE02-507E-F3FE-16CD-74D84842C1EA}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_dsp\frequency"> + <UniqueIdentifier>{8001BD68-125B-E392-8D3B-1F9C9520A65A}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_dsp\maths"> + <UniqueIdentifier>{EDC17061-CFA0-8EA0-0ADA-90F31C2FB0F2}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_dsp\native"> + <UniqueIdentifier>{B813BD14-6565-2525-9AC3-E3AA48EDDA85}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_dsp\processors"> + <UniqueIdentifier>{DDF4BA73-8578-406D-21F8-06B9BC70BFEA}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_dsp\widgets"> + <UniqueIdentifier>{73374573-0194-9A6E-461A-A81EEB511C26}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_dsp"> + <UniqueIdentifier>{5DD60D0E-B16A-0BED-EDC4-C56E6960CA9E}</UniqueIdentifier> + </Filter> <Filter Include="JUCE Modules\juce_events\broadcasters"> <UniqueIdentifier>{9D5816C2-E2B2-2E3F-B095-AC8BD1100D29}</UniqueIdentifier> </Filter> @@ -359,6 +413,9 @@ <Filter Include="JUCE Modules\juce_gui_basics\mouse"> <UniqueIdentifier>{FE3CB19C-EF43-5CF5-DAF0-09D4E43D0AB9}</UniqueIdentifier> </Filter> + <Filter Include="JUCE Modules\juce_gui_basics\native\x11"> + <UniqueIdentifier>{FE7E6CD5-C7A0-DB20-4E7E-D6E7F08C4578}</UniqueIdentifier> + </Filter> <Filter Include="JUCE Modules\juce_gui_basics\native"> <UniqueIdentifier>{895C2D33-E08D-B1BA-BB36-FC4CA65090C8}</UniqueIdentifier> </Filter> @@ -410,18 +467,6 @@ <Filter Include="JUCE Modules\juce_opengl"> <UniqueIdentifier>{9FBFF5E5-56F1-34A1-2C85-F760DA2B1EB7}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_video\capture"> - <UniqueIdentifier>{CB8DF3B2-0409-6D59-C5D4-A034EBB7F973}</UniqueIdentifier> - </Filter> - <Filter Include="JUCE Modules\juce_video\native"> - <UniqueIdentifier>{7774F72F-C951-B8AB-E927-E34AD23C52C8}</UniqueIdentifier> - </Filter> - <Filter Include="JUCE Modules\juce_video\playback"> - <UniqueIdentifier>{658BADF8-7095-C722-F9EC-9F36E8818187}</UniqueIdentifier> - </Filter> - <Filter Include="JUCE Modules\juce_video"> - <UniqueIdentifier>{2C58F450-CD01-0231-2F16-0D4D68565164}</UniqueIdentifier> - </Filter> <Filter Include="JUCE Modules"> <UniqueIdentifier>{FE955B6B-68AC-AA07-70D8-2413F6DB65C8}</UniqueIdentifier> </Filter> @@ -532,10 +577,10 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_basics\synthesisers\juce_Synthesiser.cpp"> <Filter>JUCE Modules\juce_audio_basics\synthesisers</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_CatmullRomInterpolator.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.cpp"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Interpolators.cpp"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_LagrangeInterpolator.cpp"> @@ -544,6 +589,9 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_SmoothedValue.cpp"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_WindowedSincInterpolator.cpp"> + <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_basics\juce_audio_basics.cpp"> <Filter>JUCE Modules\juce_audio_basics</Filter> </ClCompile> @@ -565,6 +613,153 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_devices\midi_io\juce_MidiMessageCollector.cpp"> <Filter>JUCE Modules\juce_audio_devices\midi_io</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AAudioLoader.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\aaudio</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AudioStreamAAudio.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\aaudio</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioSourceCaller.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioStream.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioStreamBuilder.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\DataConversionFlowGraph.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FilterAudioStream.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockAdapter.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockReader.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockWriter.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\LatencyTuner.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\QuirksManager.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceFloatCaller.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceI16Caller.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\StabilizedCallback.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Trace.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Utilities.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Version.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoBuffer.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoController.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerBase.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerIndirect.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\IntegerRatio.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\LinearResampler.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\MultiChannelResampler.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResampler.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerMono.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerStereo.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResampler.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResamplerStereo.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ClipToRange.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\FlowGraphNode.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ManyToMultiConverter.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\MonoToMultiConverter.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\RampLinear.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SampleRateConverter.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkFloat.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI16.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI24.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceFloat.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI16.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI24.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioInputStreamOpenSLES.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioOutputStreamOpenSLES.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamBuffered.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamOpenSLES.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\EngineOpenSLES.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OpenSLESUtilities.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OutputMixerOpenSLES.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_android_Audio.cpp"> <Filter>JUCE Modules\juce_audio_devices\native</Filter> </ClCompile> @@ -667,71 +862,74 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\libFLAC\window_flac.c"> <Filter>JUCE Modules\juce_audio_formats\codecs\flac\libFLAC</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\analysis.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\analysis.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\bitrate.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\bitrate.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\block.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\block.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codebook.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codebook.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\envelope.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\envelope.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\floor0.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\floor0.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\floor1.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\floor1.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\info.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\info.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lpc.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lpc.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lsp.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lsp.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mapping0.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mapping0.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mdct.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mdct.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\misc.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\psy.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\psy.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\registry.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\registry.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\res0.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\res0.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\sharedbook.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\sharedbook.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\smallft.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\smallft.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\synthesis.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\synthesis.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\vorbisenc.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\vorbisenc.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\vorbisfile.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\vorbisfile.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\window.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\window.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\bitwise.c"> <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> @@ -931,6 +1129,9 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioProcessorValueTreeState.cpp"> <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_ParameterAttachments.cpp"> + <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_RangedAudioParameter.cpp"> <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> </ClCompile> @@ -1051,6 +1252,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_FileSearchPath.cpp"> <Filter>JUCE Modules\juce_core\files</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.cpp"> + <Filter>JUCE Modules\juce_core\files</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.cpp"> <Filter>JUCE Modules\juce_core\files</Filter> </ClCompile> @@ -1078,6 +1282,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> <Filter>JUCE Modules\juce_core\maths</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.cpp"> + <Filter>JUCE Modules\juce_core\memory</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_MemoryBlock.cpp"> <Filter>JUCE Modules\juce_core\memory</Filter> </ClCompile> @@ -1378,6 +1585,117 @@ <ClCompile Include="..\..\..\..\modules\juce_data_structures\juce_data_structures.mm"> <Filter>JUCE Modules\juce_data_structures</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_AudioBlock_test.cpp"> + <Filter>JUCE Modules\juce_dsp\containers</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_FixedSizeFunction_test.cpp"> + <Filter>JUCE Modules\juce_dsp\containers</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_SIMDRegister_test.cpp"> + <Filter>JUCE Modules\juce_dsp\containers</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\filter_design\juce_FilterDesign.cpp"> + <Filter>JUCE Modules\juce_dsp\filter_design</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_Convolution.cpp"> + <Filter>JUCE Modules\juce_dsp\frequency</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_Convolution_test.cpp"> + <Filter>JUCE Modules\juce_dsp\frequency</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_FFT.cpp"> + <Filter>JUCE Modules\juce_dsp\frequency</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_FFT_test.cpp"> + <Filter>JUCE Modules\juce_dsp\frequency</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_Windowing.cpp"> + <Filter>JUCE Modules\juce_dsp\frequency</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\maths\juce_LogRampedValue_test.cpp"> + <Filter>JUCE Modules\juce_dsp\maths</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\maths\juce_LookupTable.cpp"> + <Filter>JUCE Modules\juce_dsp\maths</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\maths\juce_Matrix.cpp"> + <Filter>JUCE Modules\juce_dsp\maths</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\maths\juce_Matrix_test.cpp"> + <Filter>JUCE Modules\juce_dsp\maths</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\maths\juce_SpecialFunctions.cpp"> + <Filter>JUCE Modules\juce_dsp\maths</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\native\juce_avx_SIMDNativeOps.cpp"> + <Filter>JUCE Modules\juce_dsp\native</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\native\juce_neon_SIMDNativeOps.cpp"> + <Filter>JUCE Modules\juce_dsp\native</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\native\juce_sse_SIMDNativeOps.cpp"> + <Filter>JUCE Modules\juce_dsp\native</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_BallisticsFilter.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_DelayLine.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_DryWetMixer.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_FIRFilter.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_FIRFilter_test.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_FirstOrderTPTFilter.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_IIRFilter.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_LinkwitzRileyFilter.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_Oversampling.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_Panner.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessorChain_test.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_StateVariableTPTFilter.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_Chorus.cpp"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_Compressor.cpp"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_LadderFilter.cpp"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_Limiter.cpp"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_NoiseGate.cpp"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_Phaser.cpp"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\juce_dsp.cpp"> + <Filter>JUCE Modules\juce_dsp</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\juce_dsp.mm"> + <Filter>JUCE Modules\juce_dsp</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_events\broadcasters\juce_ActionBroadcaster.cpp"> <Filter>JUCE Modules\juce_events\broadcasters</Filter> </ClCompile> @@ -2005,6 +2323,15 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_MouseListener.cpp"> <Filter>JUCE Modules\juce_gui_basics\mouse</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_DragAndDrop.cpp"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.cpp"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.cpp"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_android_ContentSharer.cpp"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> </ClCompile> @@ -2032,13 +2359,7 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_FileChooser.cpp"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.cpp"> - <Filter>JUCE Modules\juce_gui_basics\native</Filter> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Clipboard.cpp"> - <Filter>JUCE Modules\juce_gui_basics\native</Filter> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Windowing.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_Windowing.cpp"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_mac_FileChooser.mm"> @@ -2272,6 +2593,9 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_ActiveXComponent.cpp"> <Filter>JUCE Modules\juce_gui_extra\native</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_HWNDComponent.cpp"> + <Filter>JUCE Modules\juce_gui_extra\native</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_SystemTrayIcon.cpp"> <Filter>JUCE Modules\juce_gui_extra\native</Filter> </ClCompile> @@ -2317,18 +2641,6 @@ <ClCompile Include="..\..\..\..\modules\juce_opengl\juce_opengl.mm"> <Filter>JUCE Modules\juce_opengl</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_video\capture\juce_CameraDevice.cpp"> - <Filter>JUCE Modules\juce_video\capture</Filter> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_video\playback\juce_VideoComponent.cpp"> - <Filter>JUCE Modules\juce_video\playback</Filter> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_video\juce_video.cpp"> - <Filter>JUCE Modules\juce_video</Filter> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_video\juce_video.mm"> - <Filter>JUCE Modules\juce_video</Filter> - </ClCompile> <ClCompile Include="..\..\JuceLibraryCode\BinaryData.cpp"> <Filter>JUCE Library Code</Filter> </ClCompile> @@ -2356,6 +2668,9 @@ <ClCompile Include="..\..\JuceLibraryCode\include_juce_data_structures.cpp"> <Filter>JUCE Library Code</Filter> </ClCompile> + <ClCompile Include="..\..\JuceLibraryCode\include_juce_dsp.cpp"> + <Filter>JUCE Library Code</Filter> + </ClCompile> <ClCompile Include="..\..\JuceLibraryCode\include_juce_events.cpp"> <Filter>JUCE Library Code</Filter> </ClCompile> @@ -2371,9 +2686,6 @@ <ClCompile Include="..\..\JuceLibraryCode\include_juce_opengl.cpp"> <Filter>JUCE Library Code</Filter> </ClCompile> - <ClCompile Include="..\..\JuceLibraryCode\include_juce_video.cpp"> - <Filter>JUCE Library Code</Filter> - </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="..\..\Source\Plugins\InternalPlugins.h"> @@ -2496,16 +2808,16 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_ADSR.h"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_CatmullRomInterpolator.h"> + <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Decibels.h"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Decibels.h"> + <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_GenericInterpolator.h"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.h"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_LagrangeInterpolator.h"> + <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Interpolators.h"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Reverb.h"> @@ -2535,6 +2847,186 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_devices\midi_io\juce_MidiMessageCollector.h"> <Filter>JUCE Modules\juce_audio_devices\midi_io</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStream.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamBase.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamBuilder.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamCallback.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Definitions.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\LatencyTuner.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Oboe.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\ResultWithValue.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\StabilizedCallback.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Utilities.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Version.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AAudioLoader.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\aaudio</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AudioStreamAAudio.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\aaudio</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioClock.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioSourceCaller.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\DataConversionFlowGraph.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FilterAudioStream.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockAdapter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockReader.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockWriter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\MonotonicCounter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\OboeDebug.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\QuirksManager.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceFloatCaller.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceI16Caller.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Trace.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoBuffer.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoController.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerBase.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerIndirect.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\HyperbolicCosineWindow.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\IntegerRatio.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\KaiserWindow.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\LinearResampler.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\MultiChannelResampler.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResampler.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerMono.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerStereo.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResampler.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResamplerStereo.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ClipToRange.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\FlowGraphNode.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ManyToMultiConverter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\MonoToMultiConverter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\RampLinear.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SampleRateConverter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkFloat.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI16.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI24.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceFloat.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI16.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI24.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioInputStreamOpenSLES.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioOutputStreamOpenSLES.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamBuffered.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamOpenSLES.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\EngineOpenSLES.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OpenSLESUtilities.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OutputMixerOpenSLES.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\juce_android_HighPerformanceAudioHelpers.h"> + <Filter>JUCE Modules\juce_audio_devices\native</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\juce_ios_Audio.h"> <Filter>JUCE Modules\juce_audio_devices\native</Filter> </ClInclude> @@ -2646,131 +3138,131 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\win_utf8_io.h"> <Filter>JUCE Modules\juce_audio_formats\codecs\flac</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled\res_books_51.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled\res_books_51.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled\res_books_stereo.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled\res_books_stereo.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\floor\floor_books.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\floor</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\floor\floor_books.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\floor</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\uncoupled\res_books_uncoupled.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\uncoupled</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\uncoupled\res_books_uncoupled.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\uncoupled</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\floor_all.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\floor_all.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_8.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_8.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_11.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_11.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_16.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_16.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_44.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_44.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_8.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_8.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_16.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_16.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44p51.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44p51.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44u.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44u.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_8.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_8.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_11.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_11.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_16.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_16.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_22.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_22.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_32.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_32.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44p51.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44p51.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44u.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44u.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_X.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_X.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\backends.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\backends.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\bitrate.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\bitrate.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codebook.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codebook.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codec_internal.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codec_internal.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\envelope.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\envelope.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\highlevel.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\highlevel.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup_data.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup_data.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lpc.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lpc.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lsp.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lsp.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\masking.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\masking.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mdct.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mdct.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\misc.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\misc.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\os.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\os.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\psy.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\psy.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\registry.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\registry.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\scales.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\scales.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\smallft.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\smallft.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\window.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\window.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\codec.h"> <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> @@ -2778,6 +3270,9 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\config_types.h"> <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\crctable.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\ogg.h"> <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> </ClInclude> @@ -3042,6 +3537,9 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst\vstpresetfile.h"> <Filter>JUCE Modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_AU_Shared.h"> + <Filter>JUCE Modules\juce_audio_processors\format_types</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_AudioUnitPluginFormat.h"> <Filter>JUCE Modules\juce_audio_processors\format_types</Filter> </ClInclude> @@ -3120,6 +3618,9 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioProcessorValueTreeState.h"> <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_ParameterAttachments.h"> + <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_RangedAudioParameter.h"> <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> </ClInclude> @@ -3237,6 +3738,9 @@ <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_MemoryMappedFile.h"> <Filter>JUCE Modules\juce_core\files</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.h"> + <Filter>JUCE Modules\juce_core\files</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.h"> <Filter>JUCE Modules\juce_core\files</Filter> </ClInclude> @@ -3276,6 +3780,9 @@ <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_StatisticsAccumulator.h"> <Filter>JUCE Modules\juce_core\maths</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.h"> + <Filter>JUCE Modules\juce_core\memory</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_Atomic.h"> <Filter>JUCE Modules\juce_core\memory</Filter> </ClInclude> @@ -3402,6 +3909,9 @@ <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerSupport.h"> <Filter>JUCE Modules\juce_core\system</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerWarnings.h"> + <Filter>JUCE Modules\juce_core\system</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_PlatformDefs.h"> <Filter>JUCE Modules\juce_core\system</Filter> </ClInclude> @@ -3624,6 +4134,147 @@ <ClInclude Include="..\..\..\..\modules\juce_data_structures\juce_data_structures.h"> <Filter>JUCE Modules\juce_data_structures</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\containers\juce_AudioBlock.h"> + <Filter>JUCE Modules\juce_dsp\containers</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\containers\juce_FixedSizeFunction.h"> + <Filter>JUCE Modules\juce_dsp\containers</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\containers\juce_SIMDRegister.h"> + <Filter>JUCE Modules\juce_dsp\containers</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\containers\juce_SIMDRegister_Impl.h"> + <Filter>JUCE Modules\juce_dsp\containers</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\filter_design\juce_FilterDesign.h"> + <Filter>JUCE Modules\juce_dsp\filter_design</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\frequency\juce_Convolution.h"> + <Filter>JUCE Modules\juce_dsp\frequency</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\frequency\juce_FFT.h"> + <Filter>JUCE Modules\juce_dsp\frequency</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\frequency\juce_Windowing.h"> + <Filter>JUCE Modules\juce_dsp\frequency</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_FastMathApproximations.h"> + <Filter>JUCE Modules\juce_dsp\maths</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_LogRampedValue.h"> + <Filter>JUCE Modules\juce_dsp\maths</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_LookupTable.h"> + <Filter>JUCE Modules\juce_dsp\maths</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_Matrix.h"> + <Filter>JUCE Modules\juce_dsp\maths</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_Phase.h"> + <Filter>JUCE Modules\juce_dsp\maths</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_Polynomial.h"> + <Filter>JUCE Modules\juce_dsp\maths</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_SpecialFunctions.h"> + <Filter>JUCE Modules\juce_dsp\maths</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\native\juce_avx_SIMDNativeOps.h"> + <Filter>JUCE Modules\juce_dsp\native</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\native\juce_fallback_SIMDNativeOps.h"> + <Filter>JUCE Modules\juce_dsp\native</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\native\juce_neon_SIMDNativeOps.h"> + <Filter>JUCE Modules\juce_dsp\native</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\native\juce_sse_SIMDNativeOps.h"> + <Filter>JUCE Modules\juce_dsp\native</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_BallisticsFilter.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_DelayLine.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_DryWetMixer.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_FIRFilter.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_FirstOrderTPTFilter.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_IIRFilter.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_IIRFilter_Impl.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_LinkwitzRileyFilter.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_Oversampling.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_Panner.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessContext.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessorChain.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessorDuplicator.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessorWrapper.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_StateVariableFilter.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_StateVariableTPTFilter.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Bias.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Chorus.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Compressor.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Gain.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_LadderFilter.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Limiter.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_NoiseGate.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Oscillator.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Phaser.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Reverb.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_WaveShaper.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\juce_dsp.h"> + <Filter>JUCE Modules\juce_dsp</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_events\broadcasters\juce_ActionBroadcaster.h"> <Filter>JUCE Modules\juce_events\broadcasters</Filter> </ClInclude> @@ -4170,8 +4821,11 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_TooltipClient.h"> <Filter>JUCE Modules\juce_gui_basics\mouse</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.h"> - <Filter>JUCE Modules\juce_gui_basics\native</Filter> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.h"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.h"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_MultiTouchMapper.h"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> @@ -4326,6 +4980,9 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"> <Filter>JUCE Modules\juce_gui_extra\embedding</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_HWNDComponent.h"> + <Filter>JUCE Modules\juce_gui_extra\embedding</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_NSViewComponent.h"> <Filter>JUCE Modules\juce_gui_extra\embedding</Filter> </ClInclude> @@ -4446,39 +5103,6 @@ <ClInclude Include="..\..\..\..\modules\juce_opengl\juce_opengl.h"> <Filter>JUCE Modules\juce_opengl</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_video\capture\juce_CameraDevice.h"> - <Filter>JUCE Modules\juce_video\capture</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_android_CameraDevice.h"> - <Filter>JUCE Modules\juce_video\native</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_android_Video.h"> - <Filter>JUCE Modules\juce_video\native</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_ios_CameraDevice.h"> - <Filter>JUCE Modules\juce_video\native</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_mac_CameraDevice.h"> - <Filter>JUCE Modules\juce_video\native</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_mac_Video.h"> - <Filter>JUCE Modules\juce_video\native</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_win32_CameraDevice.h"> - <Filter>JUCE Modules\juce_video\native</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_win32_Video.h"> - <Filter>JUCE Modules\juce_video\native</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_video\playback\juce_VideoComponent.h"> - <Filter>JUCE Modules\juce_video\playback</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_video\juce_video.h"> - <Filter>JUCE Modules\juce_video</Filter> - </ClInclude> - <ClInclude Include="..\..\JuceLibraryCode\AppConfig.h"> - <Filter>JUCE Library Code</Filter> - </ClInclude> <ClInclude Include="..\..\JuceLibraryCode\BinaryData.h"> <Filter>JUCE Library Code</Filter> </ClInclude> @@ -4490,9 +5114,18 @@ <None Include="..\..\Source\JUCEAppIcon.png"> <Filter>AudioPluginHost\Source</Filter> </None> + <None Include="..\..\..\..\modules\juce_audio_devices\native\oboe\CMakeLists.txt"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe</Filter> + </None> + <None Include="..\..\..\..\modules\juce_audio_devices\native\oboe\readme.md"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe</Filter> + </None> <None Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\Flac Licence.txt"> <Filter>JUCE Modules\juce_audio_formats\codecs\flac</Filter> </None> + <None Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\README.md"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7</Filter> + </None> <None Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\Ogg Vorbis Licence.txt"> <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> </None> diff --git a/extras/AudioPluginHost/Builds/VisualStudio2015/icon.ico b/extras/AudioPluginHost/Builds/VisualStudio2015/icon.ico index 09d32ad703e414097a17e969e7d765325e912c77..a2d5c802ee695781308dca425c215c9178a12601 100644 GIT binary patch literal 38465 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 U(2xRcuq!t3UPeW_TGBZ9f3W%PlK=n! literal 33530 zcmeFZ2Ur!!);7AyAV`*=L_t770Tn?cqhv{nfQsY{l9S{l5(ET9KynU(A_9^(ISWdV zoO6zwv^RabnZq2%qchHY=lh@g-23<Q6xH2y)q1OH)mp3GDuBVzV3;ssVi=e+z>F|q zFbNn8#=!8~b0+vc4}8bP^{?l1Fxb6Q;0NFZeUFrc!4COhFgEZR{1kli+j}sBiGbz) zx360zW{mnxo?+30Z$@$^$_}9f-jC`vdxguE8K3<#`FE@B^s)y_5RJK=K!$ArP~cYy zbmi#-tqD@VP{Rx0&2YhvO0Av2kLrNRep=}R-g=e+k@wS%(p!&Gpfl?MQ2m_sD0O70 z0UfLT!1r}XRv9v+4U{7sjhBI{ycr-?FZ(~r*N0yL=6Z^O;l_L*cdTUR+qUR7dxoYb zt^tYyvw*t9-0yW9%ResLTbc-T6~zG411$j5AII&89?Tgsf4F#5{<sb}h@&u|3g~`o za3uG*EL47=Ivarc^tgQXcp1vuZWVZ9y8L_cvRwgY$F>2)>J%{6_7NCqD)>E(wH5== zxcs|(Das~!1u%ZS^n0>NUIs=Mk-+E<3UFE21gz#Zeos%p=Wolu>dzU{2wwmMTxX7w zq|YqyrVRo3lx_nqojbsr`8_~+autvqUpY#8GwTrkkz@I~%^o3fRjYp}`!IC_a4y^i ztlJTQB7Ex)btJ8B0+5a!mzSw9p-&wy-!_e1I+6>Oy_2y1dwGe9&EM;=0o##2UV(u0 z^te2f-+^1}w6F96E=Ai%Wxp>E)nNs;>C?(r0MfN@%O2lDb)=7!Z)bLH0hVvKerx~d z9T4j_kTik-(niY>KP!7&2h<j*KcGI%9xp{fV+-jAq+^ht9)I`W$^ifdTO)$O#&BRT zI0g*nf%fMK`Ud(IDg%{;><k1-1Wb_qfi4fo@ce)1lKo&z0;T^GO%krs#FeTrR*|eU zNs_EI?pLa{KG1A(1E2)mgYO5VDvgsR%8XU{vaRs`TbNY9x+E)%oo-iKEco`s0q})3 zU}<+1`2JejTLY>W+5x}bcmVu%NwUJkMee=9iT?=>$ufiMGF7HSVFMWeRR6-rGEkq= z4rDtO0Wq4HKyT#`XanB@wJ$CKZOQV$P?ayRG5Z-<-dhJE1~LJ#?1)sEiNHU>0QTdf z2Mtg5y4D7P#jzD2->3X{|8eX`8q+&~(YoN@{m8LD>CAcvY|eKBJ?q23!v^Pli3$^) zzk>nnI}OkepccV??x`3AqBJu8LpFrrXYwH&H6iT4bVuq@zZtZ6AO0!^sZt|8sNIlk z=qh<p`$O4(B_G1jlW%%d2Q+q2Km65LKsqiBHy!-4HUNBlw+;9@t^z9ydq5uOuaEou z+x*Yk-;t&Q>}@Rp<L#xu@_5hDSU~#lXF4fSZtM`+p9YK$9RPPl=8pWXjqcJ<G5k#a zvFzc7cSnA`yEqouSzkQTNoZdDNEf7v%yDGl=JQa$yIHRM?(-qP|1%6flK;JIC@z2! z<maJz0nN=H*$2r|V`cB2*TBfY!5?Hp@_&Zmd-*?;eT)IIws2%0ARG04AAmM3u5!Kw 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 diff --git a/extras/AudioPluginHost/Builds/VisualStudio2015/resources.rc b/extras/AudioPluginHost/Builds/VisualStudio2015/resources.rc index 8af2d396..9a16db85 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2015/resources.rc +++ b/extras/AudioPluginHost/Builds/VisualStudio2015/resources.rc @@ -1,3 +1,5 @@ +#pragma code_page(65001) + #ifdef JUCE_USER_DEFINED_RC_FILE #include JUCE_USER_DEFINED_RC_FILE #else @@ -13,8 +15,8 @@ BEGIN BEGIN BLOCK "040904E4" BEGIN - VALUE "CompanyName", "ROLI Ltd.\0" - VALUE "LegalCopyright", "ROLI Ltd.\0" + VALUE "CompanyName", "Raw Material Software Limited\0" + VALUE "LegalCopyright", "Raw Material Software Limited\0" VALUE "FileDescription", "AudioPluginHost\0" VALUE "FileVersion", "1.0.0\0" VALUE "ProductName", "AudioPluginHost\0" diff --git a/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj index 2a305ff4..bff43a32 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj +++ b/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj @@ -64,10 +64,10 @@ <Optimization>Disabled</Optimization> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <AdditionalIncludeDirectories>..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK;..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCER_VS2017_78A5024=1;JUCE_APP_VERSION=1.0.0;JUCE_APP_VERSION_HEX=0x10000;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCE_DISPLAY_SPLASH_SCREEN=0;JUCE_USE_DARK_SPLASH_SCREEN=1;JUCE_PROJUCER_VERSION=0x60005;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_audio_formats=1;JUCE_MODULE_AVAILABLE_juce_audio_processors=1;JUCE_MODULE_AVAILABLE_juce_audio_utils=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_dsp=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_MODULE_AVAILABLE_juce_opengl=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_WASAPI=1;JUCE_DIRECTSOUND=1;JUCE_ALSA=1;JUCE_USE_FLAC=0;JUCE_USE_OGGVORBIS=1;JUCE_PLUGINHOST_VST3=1;JUCE_PLUGINHOST_AU=1;JUCE_PLUGINHOST_LADSPA=1;JUCE_USE_CDREADER=0;JUCE_USE_CDBURNER=0;JUCE_WEB_BROWSER=0;JUCE_STANDALONE_APPLICATION=1;JUCER_VS2017_78A5024=1;JUCE_APP_VERSION=1.0.0;JUCE_APP_VERSION_HEX=0x10000;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> <RuntimeTypeInfo>true</RuntimeTypeInfo> - <PrecompiledHeader/> + <PrecompiledHeader>NotUsing</PrecompiledHeader> <AssemblerListingLocation>$(IntDir)\</AssemblerListingLocation> <ObjectFileName>$(IntDir)\</ObjectFileName> <ProgramDataBaseFileName>$(IntDir)\</ProgramDataBaseFileName> @@ -106,10 +106,10 @@ <ClCompile> <Optimization>Full</Optimization> <AdditionalIncludeDirectories>..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK;..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCER_VS2017_78A5024=1;JUCE_APP_VERSION=1.0.0;JUCE_APP_VERSION_HEX=0x10000;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCE_DISPLAY_SPLASH_SCREEN=0;JUCE_USE_DARK_SPLASH_SCREEN=1;JUCE_PROJUCER_VERSION=0x60005;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_audio_formats=1;JUCE_MODULE_AVAILABLE_juce_audio_processors=1;JUCE_MODULE_AVAILABLE_juce_audio_utils=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_dsp=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_MODULE_AVAILABLE_juce_opengl=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_WASAPI=1;JUCE_DIRECTSOUND=1;JUCE_ALSA=1;JUCE_USE_FLAC=0;JUCE_USE_OGGVORBIS=1;JUCE_PLUGINHOST_VST3=1;JUCE_PLUGINHOST_AU=1;JUCE_PLUGINHOST_LADSPA=1;JUCE_USE_CDREADER=0;JUCE_USE_CDBURNER=0;JUCE_WEB_BROWSER=0;JUCE_STANDALONE_APPLICATION=1;JUCER_VS2017_78A5024=1;JUCE_APP_VERSION=1.0.0;JUCE_APP_VERSION_HEX=0x10000;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> <RuntimeTypeInfo>true</RuntimeTypeInfo> - <PrecompiledHeader/> + <PrecompiledHeader>NotUsing</PrecompiledHeader> <AssemblerListingLocation>$(IntDir)\</AssemblerListingLocation> <ObjectFileName>$(IntDir)\</ObjectFileName> <ProgramDataBaseFileName>$(IntDir)\</ProgramDataBaseFileName> @@ -132,6 +132,7 @@ <OptimizeReferences>true</OptimizeReferences> <EnableCOMDATFolding>true</EnableCOMDATFolding> <LargeAddressAware>true</LargeAddressAware> + <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> </Link> <Bscmake> <SuppressStartupBanner>true</SuppressStartupBanner> @@ -230,10 +231,10 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_basics\synthesisers\juce_Synthesiser.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_CatmullRomInterpolator.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Interpolators.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_LagrangeInterpolator.cpp"> @@ -242,6 +243,9 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_SmoothedValue.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_WindowedSincInterpolator.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_basics\juce_audio_basics.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -260,6 +264,153 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_devices\midi_io\juce_MidiMessageCollector.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AAudioLoader.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AudioStreamAAudio.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioSourceCaller.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioStream.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioStreamBuilder.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\DataConversionFlowGraph.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FilterAudioStream.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockAdapter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockReader.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockWriter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\LatencyTuner.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\QuirksManager.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceFloatCaller.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceI16Caller.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\StabilizedCallback.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Trace.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Utilities.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Version.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoBuffer.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoController.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerBase.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerIndirect.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\IntegerRatio.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\LinearResampler.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\MultiChannelResampler.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResampler.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerMono.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerStereo.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResampler.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResamplerStereo.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ClipToRange.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\FlowGraphNode.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ManyToMultiConverter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\MonoToMultiConverter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\RampLinear.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SampleRateConverter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkFloat.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI16.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI24.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceFloat.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI16.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI24.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioInputStreamOpenSLES.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioOutputStreamOpenSLES.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamBuffered.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamOpenSLES.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\EngineOpenSLES.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OpenSLESUtilities.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OutputMixerOpenSLES.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_android_Audio.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -359,70 +510,73 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\libFLAC\window_flac.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\analysis.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\analysis.c"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\bitrate.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\bitrate.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\block.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\block.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codebook.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codebook.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\envelope.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\envelope.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\floor0.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\floor0.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\floor1.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\floor1.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\info.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\info.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lpc.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lpc.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lsp.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lsp.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mapping0.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mapping0.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mdct.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mdct.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\misc.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\psy.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\psy.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\registry.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\registry.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\res0.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\res0.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\sharedbook.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\sharedbook.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\smallft.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\smallft.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\synthesis.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\synthesis.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\vorbisenc.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\vorbisenc.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\vorbisfile.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\vorbisfile.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\window.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\window.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\bitwise.c"> @@ -617,6 +771,9 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioProcessorValueTreeState.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_ParameterAttachments.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_RangedAudioParameter.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -719,6 +876,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_FileSearchPath.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -746,6 +906,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_MemoryBlock.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -1022,6 +1185,114 @@ <ClCompile Include="..\..\..\..\modules\juce_data_structures\juce_data_structures.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_AudioBlock_test.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_FixedSizeFunction_test.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_SIMDRegister_test.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\filter_design\juce_FilterDesign.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_Convolution.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_Convolution_test.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_FFT.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_FFT_test.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_Windowing.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\maths\juce_LogRampedValue_test.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\maths\juce_LookupTable.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\maths\juce_Matrix.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\maths\juce_Matrix_test.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\maths\juce_SpecialFunctions.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\native\juce_avx_SIMDNativeOps.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\native\juce_neon_SIMDNativeOps.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\native\juce_sse_SIMDNativeOps.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_BallisticsFilter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_DelayLine.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_DryWetMixer.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_FIRFilter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_FIRFilter_test.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_FirstOrderTPTFilter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_IIRFilter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_LinkwitzRileyFilter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_Oversampling.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_Panner.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessorChain_test.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_StateVariableTPTFilter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_Chorus.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_Compressor.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_LadderFilter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_Limiter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_NoiseGate.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_Phaser.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\juce_dsp.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_events\broadcasters\juce_ActionBroadcaster.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -1631,6 +1902,15 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_MouseListener.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_DragAndDrop.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_android_ContentSharer.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -1649,13 +1929,7 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_FileChooser.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.cpp"> - <ExcludedFromBuild>true</ExcludedFromBuild> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Clipboard.cpp"> - <ExcludedFromBuild>true</ExcludedFromBuild> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Windowing.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_Windowing.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_win32_DragAndDrop.cpp"> @@ -1859,6 +2133,9 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_ActiveXComponent.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_HWNDComponent.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_SystemTrayIcon.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -1898,15 +2175,6 @@ <ClCompile Include="..\..\..\..\modules\juce_opengl\juce_opengl.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_video\capture\juce_CameraDevice.cpp"> - <ExcludedFromBuild>true</ExcludedFromBuild> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_video\playback\juce_VideoComponent.cpp"> - <ExcludedFromBuild>true</ExcludedFromBuild> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_video\juce_video.cpp"> - <ExcludedFromBuild>true</ExcludedFromBuild> - </ClCompile> <ClCompile Include="..\..\JuceLibraryCode\BinaryData.cpp"/> <ClCompile Include="..\..\JuceLibraryCode\include_juce_audio_basics.cpp"/> <ClCompile Include="..\..\JuceLibraryCode\include_juce_audio_devices.cpp"/> @@ -1916,12 +2184,12 @@ <ClCompile Include="..\..\JuceLibraryCode\include_juce_core.cpp"/> <ClCompile Include="..\..\JuceLibraryCode\include_juce_cryptography.cpp"/> <ClCompile Include="..\..\JuceLibraryCode\include_juce_data_structures.cpp"/> + <ClCompile Include="..\..\JuceLibraryCode\include_juce_dsp.cpp"/> <ClCompile Include="..\..\JuceLibraryCode\include_juce_events.cpp"/> <ClCompile Include="..\..\JuceLibraryCode\include_juce_graphics.cpp"/> <ClCompile Include="..\..\JuceLibraryCode\include_juce_gui_basics.cpp"/> <ClCompile Include="..\..\JuceLibraryCode\include_juce_gui_extra.cpp"/> <ClCompile Include="..\..\JuceLibraryCode\include_juce_opengl.cpp"/> - <ClCompile Include="..\..\JuceLibraryCode\include_juce_video.cpp"/> </ItemGroup> <ItemGroup> <ClInclude Include="..\..\Source\Plugins\InternalPlugins.h"/> @@ -1964,10 +2232,10 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_basics\sources\juce_ToneGeneratorAudioSource.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\synthesisers\juce_Synthesiser.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_ADSR.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_CatmullRomInterpolator.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Decibels.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_GenericInterpolator.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_LagrangeInterpolator.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Interpolators.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Reverb.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_SmoothedValue.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\juce_audio_basics.h"/> @@ -1977,6 +2245,66 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_devices\audio_io\juce_SystemAudioVolume.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\midi_io\juce_MidiDevices.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\midi_io\juce_MidiMessageCollector.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStream.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamBase.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamBuilder.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamCallback.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Definitions.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\LatencyTuner.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Oboe.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\ResultWithValue.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\StabilizedCallback.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Utilities.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Version.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AAudioLoader.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AudioStreamAAudio.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioClock.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioSourceCaller.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\DataConversionFlowGraph.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FilterAudioStream.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockAdapter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockReader.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockWriter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\MonotonicCounter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\OboeDebug.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\QuirksManager.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceFloatCaller.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceI16Caller.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Trace.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoBuffer.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoController.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerBase.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerIndirect.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\HyperbolicCosineWindow.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\IntegerRatio.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\KaiserWindow.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\LinearResampler.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\MultiChannelResampler.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResampler.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerMono.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerStereo.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResampler.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResamplerStereo.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ClipToRange.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\FlowGraphNode.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ManyToMultiConverter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\MonoToMultiConverter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\RampLinear.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SampleRateConverter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkFloat.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI16.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI24.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceFloat.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI16.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI24.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioInputStreamOpenSLES.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioOutputStreamOpenSLES.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamBuffered.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamOpenSLES.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\EngineOpenSLES.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OpenSLESUtilities.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OutputMixerOpenSLES.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\juce_android_HighPerformanceAudioHelpers.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\juce_ios_Audio.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\juce_MidiDataConcatenator.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\sources\juce_AudioSourcePlayer.h"/> @@ -2014,50 +2342,51 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\stream_decoder.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\stream_encoder.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\win_utf8_io.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled\res_books_51.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled\res_books_stereo.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\floor\floor_books.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\uncoupled\res_books_uncoupled.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\floor_all.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_8.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_11.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_16.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_44.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_8.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_16.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44p51.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44u.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_8.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_11.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_16.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_22.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_32.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44p51.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44u.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_X.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\backends.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\bitrate.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codebook.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codec_internal.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\envelope.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\highlevel.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup_data.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lpc.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lsp.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\masking.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mdct.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\misc.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\os.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\psy.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\registry.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\scales.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\smallft.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\window.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled\res_books_51.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled\res_books_stereo.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\floor\floor_books.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\uncoupled\res_books_uncoupled.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\floor_all.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_8.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_11.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_16.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_44.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_8.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_16.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44p51.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44u.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_8.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_11.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_16.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_22.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_32.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44p51.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44u.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_X.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\backends.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\bitrate.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codebook.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codec_internal.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\envelope.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\highlevel.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup_data.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lpc.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lsp.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\masking.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mdct.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\misc.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\os.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\psy.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\registry.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\scales.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\smallft.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\window.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\codec.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\config_types.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\crctable.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\ogg.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\os_types.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\vorbisenc.h"/> @@ -2146,6 +2475,7 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst\vsteditcontroller.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst\vstparameters.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst\vstpresetfile.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_AU_Shared.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_AudioUnitPluginFormat.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LADSPAPluginFormat.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_VST3Common.h"/> @@ -2172,6 +2502,7 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioParameterInt.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioProcessorParameterWithID.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioProcessorValueTreeState.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_ParameterAttachments.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_RangedAudioParameter.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\juce_audio_processors.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_utils\audio_cd\juce_AudioCDBurner.h"/> @@ -2211,6 +2542,7 @@ <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_FileOutputStream.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_FileSearchPath.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_MemoryMappedFile.h"/> + <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_WildcardFileFilter.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\javascript\juce_Javascript.h"/> @@ -2224,6 +2556,7 @@ <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_Random.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_Range.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_StatisticsAccumulator.h"/> + <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_Atomic.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_ByteOrder.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_ContainerDeletePolicy.h"/> @@ -2266,6 +2599,7 @@ <ClInclude Include="..\..\..\..\modules\juce_core\streams\juce_SubregionStream.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\streams\juce_URLInputSource.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerSupport.h"/> + <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerWarnings.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_PlatformDefs.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_StandardHeader.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_SystemStats.h"/> @@ -2340,6 +2674,53 @@ <ClInclude Include="..\..\..\..\modules\juce_data_structures\values\juce_ValueTreeSynchroniser.h"/> <ClInclude Include="..\..\..\..\modules\juce_data_structures\values\juce_ValueWithDefault.h"/> <ClInclude Include="..\..\..\..\modules\juce_data_structures\juce_data_structures.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\containers\juce_AudioBlock.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\containers\juce_FixedSizeFunction.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\containers\juce_SIMDRegister.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\containers\juce_SIMDRegister_Impl.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\filter_design\juce_FilterDesign.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\frequency\juce_Convolution.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\frequency\juce_FFT.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\frequency\juce_Windowing.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_FastMathApproximations.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_LogRampedValue.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_LookupTable.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_Matrix.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_Phase.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_Polynomial.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_SpecialFunctions.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\native\juce_avx_SIMDNativeOps.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\native\juce_fallback_SIMDNativeOps.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\native\juce_neon_SIMDNativeOps.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\native\juce_sse_SIMDNativeOps.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_BallisticsFilter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_DelayLine.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_DryWetMixer.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_FIRFilter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_FirstOrderTPTFilter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_IIRFilter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_IIRFilter_Impl.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_LinkwitzRileyFilter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_Oversampling.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_Panner.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessContext.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessorChain.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessorDuplicator.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessorWrapper.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_StateVariableFilter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_StateVariableTPTFilter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Bias.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Chorus.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Compressor.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Gain.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_LadderFilter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Limiter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_NoiseGate.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Oscillator.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Phaser.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Reverb.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_WaveShaper.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\juce_dsp.h"/> <ClInclude Include="..\..\..\..\modules\juce_events\broadcasters\juce_ActionBroadcaster.h"/> <ClInclude Include="..\..\..\..\modules\juce_events\broadcasters\juce_ActionListener.h"/> <ClInclude Include="..\..\..\..\modules\juce_events\broadcasters\juce_AsyncUpdater.h"/> @@ -2522,7 +2903,8 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_SelectedItemSet.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_TextDragAndDropTarget.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_TooltipClient.h"/> - <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.h"/> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.h"/> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_MultiTouchMapper.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\positioning\juce_MarkerList.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\positioning\juce_RelativeCoordinate.h"/> @@ -2574,6 +2956,7 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ActiveXControlComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"/> + <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_HWNDComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_NSViewComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ScopedDPIAwarenessDisabler.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_UIViewComponent.h"/> @@ -2614,23 +2997,15 @@ <ClInclude Include="..\..\..\..\modules\juce_opengl\opengl\juce_OpenGLTexture.h"/> <ClInclude Include="..\..\..\..\modules\juce_opengl\utils\juce_OpenGLAppComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_opengl\juce_opengl.h"/> - <ClInclude Include="..\..\..\..\modules\juce_video\capture\juce_CameraDevice.h"/> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_android_CameraDevice.h"/> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_android_Video.h"/> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_ios_CameraDevice.h"/> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_mac_CameraDevice.h"/> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_mac_Video.h"/> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_win32_CameraDevice.h"/> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_win32_Video.h"/> - <ClInclude Include="..\..\..\..\modules\juce_video\playback\juce_VideoComponent.h"/> - <ClInclude Include="..\..\..\..\modules\juce_video\juce_video.h"/> - <ClInclude Include="..\..\JuceLibraryCode\AppConfig.h"/> <ClInclude Include="..\..\JuceLibraryCode\BinaryData.h"/> <ClInclude Include="..\..\JuceLibraryCode\JuceHeader.h"/> </ItemGroup> <ItemGroup> <None Include="..\..\Source\JUCEAppIcon.png"/> + <None Include="..\..\..\..\modules\juce_audio_devices\native\oboe\CMakeLists.txt"/> + <None Include="..\..\..\..\modules\juce_audio_devices\native\oboe\readme.md"/> <None Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\Flac Licence.txt"/> + <None Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\README.md"/> <None Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\Ogg Vorbis Licence.txt"/> <None Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\base\LICENSE.txt"/> <None Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\base\README.md"/> diff --git a/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj.filters index a94fc227..8f53d51f 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj.filters +++ b/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj.filters @@ -47,6 +47,36 @@ <Filter Include="JUCE Modules\juce_audio_devices\midi_io"> <UniqueIdentifier>{092EFC17-7C95-7E04-0ACA-0D61A462EE81}</UniqueIdentifier> </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\include\oboe"> + <UniqueIdentifier>{285118C6-8FDA-7DCE-BEF4-FFB2120876C5}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\include"> + <UniqueIdentifier>{69ED6B61-9B8D-D47E-E4A6-2E9F9A94A75A}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\aaudio"> + <UniqueIdentifier>{7CDB7CD1-BB96-F593-3C78-1E06182B5839}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\common"> + <UniqueIdentifier>{B0A708DE-B4CF-196B-14FB-DC8221509B8E}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\fifo"> + <UniqueIdentifier>{34F46ADE-EE31-227A-A69E-7732E70145F1}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler"> + <UniqueIdentifier>{BB9B3C77-17FB-E994-8B75-88F1727E4655}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph"> + <UniqueIdentifier>{C0971D77-2F14-190A-E2AE-89D6285F4D5A}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\opensles"> + <UniqueIdentifier>{AABEA333-6524-8891-51C7-6DAEB5700628}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src"> + <UniqueIdentifier>{F2D29337-983E-BAD7-7B5C-E0AB3D53D404}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe"> + <UniqueIdentifier>{C674B0FB-1FC0-2986-94B1-083845018994}</UniqueIdentifier> + </Filter> <Filter Include="JUCE Modules\juce_audio_devices\native"> <UniqueIdentifier>{0AFC1CE8-F6E6-9817-8C21-8432B2A375DA}</UniqueIdentifier> </Filter> @@ -71,26 +101,26 @@ <Filter Include="JUCE Modules\juce_audio_formats\codecs\flac"> <UniqueIdentifier>{9EB3EC7F-2AB7-DDAA-3C05-DF382B728D3F}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled"> - <UniqueIdentifier>{02D37B85-7DE2-C8E7-A274-A5A0FBE99D69}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled"> + <UniqueIdentifier>{6B9FBFDC-1D10-6246-356D-00FF4535CECB}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\floor"> - <UniqueIdentifier>{DAF3BAAF-5207-4C34-61B9-A97DDC930D50}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\floor"> + <UniqueIdentifier>{D6FCFC8E-7136-9109-78C0-91A3EB4C443F}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\uncoupled"> - <UniqueIdentifier>{C7885588-8436-4C21-DC1E-58879BF53BDC}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\uncoupled"> + <UniqueIdentifier>{EBF18AC1-F0ED-937A-2824-4307CE2ADAF7}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books"> - <UniqueIdentifier>{E4ECEA39-0EFF-2443-91B3-1E5DA7AD5AE4}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books"> + <UniqueIdentifier>{5A0F7922-2EFB-6465-57E4-A445B804EFB5}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes"> - <UniqueIdentifier>{210B8D25-68E0-32C3-1449-6A40F109C5E9}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes"> + <UniqueIdentifier>{4EC45416-0E7C-7567-6F75-D0C8CEE7DC4F}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib"> - <UniqueIdentifier>{378AD911-E8E4-D230-E76B-34542849509D}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib"> + <UniqueIdentifier>{C2985031-0496-55B5-41A8-BAB99E53D89D}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2"> - <UniqueIdentifier>{F6CED5B6-0A8C-56D2-C1AC-DED6BE774A13}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7"> + <UniqueIdentifier>{FB4AB426-7009-0036-BB75-E34256AA7C89}</UniqueIdentifier> </Filter> <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis"> <UniqueIdentifier>{E684D858-09E8-0251-8E86-5657129641E1}</UniqueIdentifier> @@ -266,6 +296,30 @@ <Filter Include="JUCE Modules\juce_data_structures"> <UniqueIdentifier>{911F0159-A7A8-4A43-3FD4-154F62F4A44B}</UniqueIdentifier> </Filter> + <Filter Include="JUCE Modules\juce_dsp\containers"> + <UniqueIdentifier>{53CF03D3-988B-CD28-9130-CE08FDCEF7E9}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_dsp\filter_design"> + <UniqueIdentifier>{29C6FE02-507E-F3FE-16CD-74D84842C1EA}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_dsp\frequency"> + <UniqueIdentifier>{8001BD68-125B-E392-8D3B-1F9C9520A65A}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_dsp\maths"> + <UniqueIdentifier>{EDC17061-CFA0-8EA0-0ADA-90F31C2FB0F2}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_dsp\native"> + <UniqueIdentifier>{B813BD14-6565-2525-9AC3-E3AA48EDDA85}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_dsp\processors"> + <UniqueIdentifier>{DDF4BA73-8578-406D-21F8-06B9BC70BFEA}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_dsp\widgets"> + <UniqueIdentifier>{73374573-0194-9A6E-461A-A81EEB511C26}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_dsp"> + <UniqueIdentifier>{5DD60D0E-B16A-0BED-EDC4-C56E6960CA9E}</UniqueIdentifier> + </Filter> <Filter Include="JUCE Modules\juce_events\broadcasters"> <UniqueIdentifier>{9D5816C2-E2B2-2E3F-B095-AC8BD1100D29}</UniqueIdentifier> </Filter> @@ -359,6 +413,9 @@ <Filter Include="JUCE Modules\juce_gui_basics\mouse"> <UniqueIdentifier>{FE3CB19C-EF43-5CF5-DAF0-09D4E43D0AB9}</UniqueIdentifier> </Filter> + <Filter Include="JUCE Modules\juce_gui_basics\native\x11"> + <UniqueIdentifier>{FE7E6CD5-C7A0-DB20-4E7E-D6E7F08C4578}</UniqueIdentifier> + </Filter> <Filter Include="JUCE Modules\juce_gui_basics\native"> <UniqueIdentifier>{895C2D33-E08D-B1BA-BB36-FC4CA65090C8}</UniqueIdentifier> </Filter> @@ -410,18 +467,6 @@ <Filter Include="JUCE Modules\juce_opengl"> <UniqueIdentifier>{9FBFF5E5-56F1-34A1-2C85-F760DA2B1EB7}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_video\capture"> - <UniqueIdentifier>{CB8DF3B2-0409-6D59-C5D4-A034EBB7F973}</UniqueIdentifier> - </Filter> - <Filter Include="JUCE Modules\juce_video\native"> - <UniqueIdentifier>{7774F72F-C951-B8AB-E927-E34AD23C52C8}</UniqueIdentifier> - </Filter> - <Filter Include="JUCE Modules\juce_video\playback"> - <UniqueIdentifier>{658BADF8-7095-C722-F9EC-9F36E8818187}</UniqueIdentifier> - </Filter> - <Filter Include="JUCE Modules\juce_video"> - <UniqueIdentifier>{2C58F450-CD01-0231-2F16-0D4D68565164}</UniqueIdentifier> - </Filter> <Filter Include="JUCE Modules"> <UniqueIdentifier>{FE955B6B-68AC-AA07-70D8-2413F6DB65C8}</UniqueIdentifier> </Filter> @@ -532,10 +577,10 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_basics\synthesisers\juce_Synthesiser.cpp"> <Filter>JUCE Modules\juce_audio_basics\synthesisers</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_CatmullRomInterpolator.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.cpp"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Interpolators.cpp"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_LagrangeInterpolator.cpp"> @@ -544,6 +589,9 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_SmoothedValue.cpp"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_WindowedSincInterpolator.cpp"> + <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_basics\juce_audio_basics.cpp"> <Filter>JUCE Modules\juce_audio_basics</Filter> </ClCompile> @@ -565,6 +613,153 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_devices\midi_io\juce_MidiMessageCollector.cpp"> <Filter>JUCE Modules\juce_audio_devices\midi_io</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AAudioLoader.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\aaudio</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AudioStreamAAudio.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\aaudio</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioSourceCaller.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioStream.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioStreamBuilder.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\DataConversionFlowGraph.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FilterAudioStream.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockAdapter.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockReader.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockWriter.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\LatencyTuner.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\QuirksManager.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceFloatCaller.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceI16Caller.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\StabilizedCallback.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Trace.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Utilities.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Version.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoBuffer.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoController.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerBase.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerIndirect.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\IntegerRatio.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\LinearResampler.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\MultiChannelResampler.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResampler.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerMono.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerStereo.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResampler.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResamplerStereo.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ClipToRange.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\FlowGraphNode.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ManyToMultiConverter.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\MonoToMultiConverter.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\RampLinear.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SampleRateConverter.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkFloat.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI16.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI24.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceFloat.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI16.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI24.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioInputStreamOpenSLES.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioOutputStreamOpenSLES.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamBuffered.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamOpenSLES.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\EngineOpenSLES.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OpenSLESUtilities.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OutputMixerOpenSLES.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_android_Audio.cpp"> <Filter>JUCE Modules\juce_audio_devices\native</Filter> </ClCompile> @@ -667,71 +862,74 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\libFLAC\window_flac.c"> <Filter>JUCE Modules\juce_audio_formats\codecs\flac\libFLAC</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\analysis.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\analysis.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\bitrate.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\bitrate.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\block.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\block.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codebook.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codebook.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\envelope.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\envelope.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\floor0.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\floor0.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\floor1.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\floor1.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\info.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\info.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lpc.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lpc.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lsp.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lsp.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mapping0.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mapping0.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mdct.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mdct.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\misc.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\psy.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\psy.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\registry.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\registry.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\res0.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\res0.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\sharedbook.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\sharedbook.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\smallft.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\smallft.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\synthesis.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\synthesis.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\vorbisenc.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\vorbisenc.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\vorbisfile.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\vorbisfile.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\window.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\window.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\bitwise.c"> <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> @@ -931,6 +1129,9 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioProcessorValueTreeState.cpp"> <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_ParameterAttachments.cpp"> + <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_RangedAudioParameter.cpp"> <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> </ClCompile> @@ -1051,6 +1252,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_FileSearchPath.cpp"> <Filter>JUCE Modules\juce_core\files</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.cpp"> + <Filter>JUCE Modules\juce_core\files</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.cpp"> <Filter>JUCE Modules\juce_core\files</Filter> </ClCompile> @@ -1078,6 +1282,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> <Filter>JUCE Modules\juce_core\maths</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.cpp"> + <Filter>JUCE Modules\juce_core\memory</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_MemoryBlock.cpp"> <Filter>JUCE Modules\juce_core\memory</Filter> </ClCompile> @@ -1378,6 +1585,117 @@ <ClCompile Include="..\..\..\..\modules\juce_data_structures\juce_data_structures.mm"> <Filter>JUCE Modules\juce_data_structures</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_AudioBlock_test.cpp"> + <Filter>JUCE Modules\juce_dsp\containers</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_FixedSizeFunction_test.cpp"> + <Filter>JUCE Modules\juce_dsp\containers</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_SIMDRegister_test.cpp"> + <Filter>JUCE Modules\juce_dsp\containers</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\filter_design\juce_FilterDesign.cpp"> + <Filter>JUCE Modules\juce_dsp\filter_design</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_Convolution.cpp"> + <Filter>JUCE Modules\juce_dsp\frequency</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_Convolution_test.cpp"> + <Filter>JUCE Modules\juce_dsp\frequency</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_FFT.cpp"> + <Filter>JUCE Modules\juce_dsp\frequency</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_FFT_test.cpp"> + <Filter>JUCE Modules\juce_dsp\frequency</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_Windowing.cpp"> + <Filter>JUCE Modules\juce_dsp\frequency</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\maths\juce_LogRampedValue_test.cpp"> + <Filter>JUCE Modules\juce_dsp\maths</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\maths\juce_LookupTable.cpp"> + <Filter>JUCE Modules\juce_dsp\maths</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\maths\juce_Matrix.cpp"> + <Filter>JUCE Modules\juce_dsp\maths</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\maths\juce_Matrix_test.cpp"> + <Filter>JUCE Modules\juce_dsp\maths</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\maths\juce_SpecialFunctions.cpp"> + <Filter>JUCE Modules\juce_dsp\maths</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\native\juce_avx_SIMDNativeOps.cpp"> + <Filter>JUCE Modules\juce_dsp\native</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\native\juce_neon_SIMDNativeOps.cpp"> + <Filter>JUCE Modules\juce_dsp\native</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\native\juce_sse_SIMDNativeOps.cpp"> + <Filter>JUCE Modules\juce_dsp\native</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_BallisticsFilter.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_DelayLine.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_DryWetMixer.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_FIRFilter.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_FIRFilter_test.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_FirstOrderTPTFilter.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_IIRFilter.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_LinkwitzRileyFilter.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_Oversampling.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_Panner.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessorChain_test.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_StateVariableTPTFilter.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_Chorus.cpp"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_Compressor.cpp"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_LadderFilter.cpp"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_Limiter.cpp"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_NoiseGate.cpp"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_Phaser.cpp"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\juce_dsp.cpp"> + <Filter>JUCE Modules\juce_dsp</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\juce_dsp.mm"> + <Filter>JUCE Modules\juce_dsp</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_events\broadcasters\juce_ActionBroadcaster.cpp"> <Filter>JUCE Modules\juce_events\broadcasters</Filter> </ClCompile> @@ -2005,6 +2323,15 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_MouseListener.cpp"> <Filter>JUCE Modules\juce_gui_basics\mouse</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_DragAndDrop.cpp"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.cpp"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.cpp"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_android_ContentSharer.cpp"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> </ClCompile> @@ -2032,13 +2359,7 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_FileChooser.cpp"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.cpp"> - <Filter>JUCE Modules\juce_gui_basics\native</Filter> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Clipboard.cpp"> - <Filter>JUCE Modules\juce_gui_basics\native</Filter> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Windowing.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_Windowing.cpp"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_mac_FileChooser.mm"> @@ -2272,6 +2593,9 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_ActiveXComponent.cpp"> <Filter>JUCE Modules\juce_gui_extra\native</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_HWNDComponent.cpp"> + <Filter>JUCE Modules\juce_gui_extra\native</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_SystemTrayIcon.cpp"> <Filter>JUCE Modules\juce_gui_extra\native</Filter> </ClCompile> @@ -2317,18 +2641,6 @@ <ClCompile Include="..\..\..\..\modules\juce_opengl\juce_opengl.mm"> <Filter>JUCE Modules\juce_opengl</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_video\capture\juce_CameraDevice.cpp"> - <Filter>JUCE Modules\juce_video\capture</Filter> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_video\playback\juce_VideoComponent.cpp"> - <Filter>JUCE Modules\juce_video\playback</Filter> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_video\juce_video.cpp"> - <Filter>JUCE Modules\juce_video</Filter> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_video\juce_video.mm"> - <Filter>JUCE Modules\juce_video</Filter> - </ClCompile> <ClCompile Include="..\..\JuceLibraryCode\BinaryData.cpp"> <Filter>JUCE Library Code</Filter> </ClCompile> @@ -2356,6 +2668,9 @@ <ClCompile Include="..\..\JuceLibraryCode\include_juce_data_structures.cpp"> <Filter>JUCE Library Code</Filter> </ClCompile> + <ClCompile Include="..\..\JuceLibraryCode\include_juce_dsp.cpp"> + <Filter>JUCE Library Code</Filter> + </ClCompile> <ClCompile Include="..\..\JuceLibraryCode\include_juce_events.cpp"> <Filter>JUCE Library Code</Filter> </ClCompile> @@ -2371,9 +2686,6 @@ <ClCompile Include="..\..\JuceLibraryCode\include_juce_opengl.cpp"> <Filter>JUCE Library Code</Filter> </ClCompile> - <ClCompile Include="..\..\JuceLibraryCode\include_juce_video.cpp"> - <Filter>JUCE Library Code</Filter> - </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="..\..\Source\Plugins\InternalPlugins.h"> @@ -2496,16 +2808,16 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_ADSR.h"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_CatmullRomInterpolator.h"> + <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Decibels.h"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Decibels.h"> + <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_GenericInterpolator.h"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.h"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_LagrangeInterpolator.h"> + <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Interpolators.h"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Reverb.h"> @@ -2535,6 +2847,186 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_devices\midi_io\juce_MidiMessageCollector.h"> <Filter>JUCE Modules\juce_audio_devices\midi_io</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStream.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamBase.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamBuilder.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamCallback.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Definitions.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\LatencyTuner.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Oboe.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\ResultWithValue.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\StabilizedCallback.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Utilities.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Version.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AAudioLoader.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\aaudio</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AudioStreamAAudio.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\aaudio</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioClock.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioSourceCaller.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\DataConversionFlowGraph.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FilterAudioStream.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockAdapter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockReader.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockWriter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\MonotonicCounter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\OboeDebug.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\QuirksManager.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceFloatCaller.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceI16Caller.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Trace.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoBuffer.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoController.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerBase.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerIndirect.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\HyperbolicCosineWindow.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\IntegerRatio.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\KaiserWindow.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\LinearResampler.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\MultiChannelResampler.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResampler.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerMono.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerStereo.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResampler.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResamplerStereo.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ClipToRange.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\FlowGraphNode.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ManyToMultiConverter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\MonoToMultiConverter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\RampLinear.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SampleRateConverter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkFloat.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI16.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI24.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceFloat.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI16.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI24.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioInputStreamOpenSLES.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioOutputStreamOpenSLES.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamBuffered.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamOpenSLES.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\EngineOpenSLES.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OpenSLESUtilities.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OutputMixerOpenSLES.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\juce_android_HighPerformanceAudioHelpers.h"> + <Filter>JUCE Modules\juce_audio_devices\native</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\juce_ios_Audio.h"> <Filter>JUCE Modules\juce_audio_devices\native</Filter> </ClInclude> @@ -2646,131 +3138,131 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\win_utf8_io.h"> <Filter>JUCE Modules\juce_audio_formats\codecs\flac</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled\res_books_51.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled\res_books_51.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled\res_books_stereo.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled\res_books_stereo.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\floor\floor_books.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\floor</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\floor\floor_books.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\floor</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\uncoupled\res_books_uncoupled.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\uncoupled</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\uncoupled\res_books_uncoupled.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\uncoupled</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\floor_all.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\floor_all.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_8.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_8.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_11.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_11.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_16.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_16.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_44.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_44.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_8.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_8.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_16.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_16.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44p51.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44p51.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44u.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44u.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_8.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_8.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_11.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_11.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_16.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_16.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_22.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_22.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_32.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_32.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44p51.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44p51.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44u.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44u.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_X.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_X.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\backends.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\backends.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\bitrate.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\bitrate.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codebook.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codebook.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codec_internal.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codec_internal.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\envelope.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\envelope.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\highlevel.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\highlevel.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup_data.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup_data.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lpc.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lpc.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lsp.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lsp.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\masking.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\masking.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mdct.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mdct.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\misc.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\misc.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\os.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\os.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\psy.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\psy.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\registry.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\registry.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\scales.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\scales.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\smallft.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\smallft.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\window.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\window.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\codec.h"> <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> @@ -2778,6 +3270,9 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\config_types.h"> <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\crctable.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\ogg.h"> <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> </ClInclude> @@ -3042,6 +3537,9 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst\vstpresetfile.h"> <Filter>JUCE Modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_AU_Shared.h"> + <Filter>JUCE Modules\juce_audio_processors\format_types</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_AudioUnitPluginFormat.h"> <Filter>JUCE Modules\juce_audio_processors\format_types</Filter> </ClInclude> @@ -3120,6 +3618,9 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioProcessorValueTreeState.h"> <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_ParameterAttachments.h"> + <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_RangedAudioParameter.h"> <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> </ClInclude> @@ -3237,6 +3738,9 @@ <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_MemoryMappedFile.h"> <Filter>JUCE Modules\juce_core\files</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.h"> + <Filter>JUCE Modules\juce_core\files</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.h"> <Filter>JUCE Modules\juce_core\files</Filter> </ClInclude> @@ -3276,6 +3780,9 @@ <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_StatisticsAccumulator.h"> <Filter>JUCE Modules\juce_core\maths</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.h"> + <Filter>JUCE Modules\juce_core\memory</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_Atomic.h"> <Filter>JUCE Modules\juce_core\memory</Filter> </ClInclude> @@ -3402,6 +3909,9 @@ <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerSupport.h"> <Filter>JUCE Modules\juce_core\system</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerWarnings.h"> + <Filter>JUCE Modules\juce_core\system</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_PlatformDefs.h"> <Filter>JUCE Modules\juce_core\system</Filter> </ClInclude> @@ -3624,6 +4134,147 @@ <ClInclude Include="..\..\..\..\modules\juce_data_structures\juce_data_structures.h"> <Filter>JUCE Modules\juce_data_structures</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\containers\juce_AudioBlock.h"> + <Filter>JUCE Modules\juce_dsp\containers</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\containers\juce_FixedSizeFunction.h"> + <Filter>JUCE Modules\juce_dsp\containers</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\containers\juce_SIMDRegister.h"> + <Filter>JUCE Modules\juce_dsp\containers</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\containers\juce_SIMDRegister_Impl.h"> + <Filter>JUCE Modules\juce_dsp\containers</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\filter_design\juce_FilterDesign.h"> + <Filter>JUCE Modules\juce_dsp\filter_design</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\frequency\juce_Convolution.h"> + <Filter>JUCE Modules\juce_dsp\frequency</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\frequency\juce_FFT.h"> + <Filter>JUCE Modules\juce_dsp\frequency</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\frequency\juce_Windowing.h"> + <Filter>JUCE Modules\juce_dsp\frequency</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_FastMathApproximations.h"> + <Filter>JUCE Modules\juce_dsp\maths</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_LogRampedValue.h"> + <Filter>JUCE Modules\juce_dsp\maths</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_LookupTable.h"> + <Filter>JUCE Modules\juce_dsp\maths</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_Matrix.h"> + <Filter>JUCE Modules\juce_dsp\maths</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_Phase.h"> + <Filter>JUCE Modules\juce_dsp\maths</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_Polynomial.h"> + <Filter>JUCE Modules\juce_dsp\maths</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_SpecialFunctions.h"> + <Filter>JUCE Modules\juce_dsp\maths</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\native\juce_avx_SIMDNativeOps.h"> + <Filter>JUCE Modules\juce_dsp\native</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\native\juce_fallback_SIMDNativeOps.h"> + <Filter>JUCE Modules\juce_dsp\native</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\native\juce_neon_SIMDNativeOps.h"> + <Filter>JUCE Modules\juce_dsp\native</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\native\juce_sse_SIMDNativeOps.h"> + <Filter>JUCE Modules\juce_dsp\native</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_BallisticsFilter.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_DelayLine.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_DryWetMixer.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_FIRFilter.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_FirstOrderTPTFilter.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_IIRFilter.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_IIRFilter_Impl.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_LinkwitzRileyFilter.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_Oversampling.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_Panner.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessContext.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessorChain.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessorDuplicator.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessorWrapper.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_StateVariableFilter.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_StateVariableTPTFilter.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Bias.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Chorus.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Compressor.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Gain.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_LadderFilter.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Limiter.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_NoiseGate.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Oscillator.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Phaser.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Reverb.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_WaveShaper.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\juce_dsp.h"> + <Filter>JUCE Modules\juce_dsp</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_events\broadcasters\juce_ActionBroadcaster.h"> <Filter>JUCE Modules\juce_events\broadcasters</Filter> </ClInclude> @@ -4170,8 +4821,11 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_TooltipClient.h"> <Filter>JUCE Modules\juce_gui_basics\mouse</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.h"> - <Filter>JUCE Modules\juce_gui_basics\native</Filter> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.h"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.h"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_MultiTouchMapper.h"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> @@ -4326,6 +4980,9 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"> <Filter>JUCE Modules\juce_gui_extra\embedding</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_HWNDComponent.h"> + <Filter>JUCE Modules\juce_gui_extra\embedding</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_NSViewComponent.h"> <Filter>JUCE Modules\juce_gui_extra\embedding</Filter> </ClInclude> @@ -4446,39 +5103,6 @@ <ClInclude Include="..\..\..\..\modules\juce_opengl\juce_opengl.h"> <Filter>JUCE Modules\juce_opengl</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_video\capture\juce_CameraDevice.h"> - <Filter>JUCE Modules\juce_video\capture</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_android_CameraDevice.h"> - <Filter>JUCE Modules\juce_video\native</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_android_Video.h"> - <Filter>JUCE Modules\juce_video\native</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_ios_CameraDevice.h"> - <Filter>JUCE Modules\juce_video\native</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_mac_CameraDevice.h"> - <Filter>JUCE Modules\juce_video\native</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_mac_Video.h"> - <Filter>JUCE Modules\juce_video\native</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_win32_CameraDevice.h"> - <Filter>JUCE Modules\juce_video\native</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_win32_Video.h"> - <Filter>JUCE Modules\juce_video\native</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_video\playback\juce_VideoComponent.h"> - <Filter>JUCE Modules\juce_video\playback</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_video\juce_video.h"> - <Filter>JUCE Modules\juce_video</Filter> - </ClInclude> - <ClInclude Include="..\..\JuceLibraryCode\AppConfig.h"> - <Filter>JUCE Library Code</Filter> - </ClInclude> <ClInclude Include="..\..\JuceLibraryCode\BinaryData.h"> <Filter>JUCE Library Code</Filter> </ClInclude> @@ -4490,9 +5114,18 @@ <None Include="..\..\Source\JUCEAppIcon.png"> <Filter>AudioPluginHost\Source</Filter> </None> + <None Include="..\..\..\..\modules\juce_audio_devices\native\oboe\CMakeLists.txt"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe</Filter> + </None> + <None Include="..\..\..\..\modules\juce_audio_devices\native\oboe\readme.md"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe</Filter> + </None> <None Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\Flac Licence.txt"> <Filter>JUCE Modules\juce_audio_formats\codecs\flac</Filter> </None> + <None Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\README.md"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7</Filter> + </None> <None Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\Ogg Vorbis Licence.txt"> <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> </None> diff --git a/extras/AudioPluginHost/Builds/VisualStudio2017/icon.ico b/extras/AudioPluginHost/Builds/VisualStudio2017/icon.ico index 09d32ad703e414097a17e969e7d765325e912c77..a2d5c802ee695781308dca425c215c9178a12601 100644 GIT binary patch literal 38465 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 U(2xRcuq!t3UPeW_TGBZ9f3W%PlK=n! literal 33530 zcmeFZ2Ur!!);7AyAV`*=L_t770Tn?cqhv{nfQsY{l9S{l5(ET9KynU(A_9^(ISWdV zoO6zwv^RabnZq2%qchHY=lh@g-23<Q6xH2y)q1OH)mp3GDuBVzV3;ssVi=e+z>F|q zFbNn8#=!8~b0+vc4}8bP^{?l1Fxb6Q;0NFZeUFrc!4COhFgEZR{1kli+j}sBiGbz) zx360zW{mnxo?+30Z$@$^$_}9f-jC`vdxguE8K3<#`FE@B^s)y_5RJK=K!$ArP~cYy zbmi#-tqD@VP{Rx0&2YhvO0Av2kLrNRep=}R-g=e+k@wS%(p!&Gpfl?MQ2m_sD0O70 z0UfLT!1r}XRv9v+4U{7sjhBI{ycr-?FZ(~r*N0yL=6Z^O;l_L*cdTUR+qUR7dxoYb zt^tYyvw*t9-0yW9%ResLTbc-T6~zG411$j5AII&89?Tgsf4F#5{<sb}h@&u|3g~`o za3uG*EL47=Ivarc^tgQXcp1vuZWVZ9y8L_cvRwgY$F>2)>J%{6_7NCqD)>E(wH5== zxcs|(Das~!1u%ZS^n0>NUIs=Mk-+E<3UFE21gz#Zeos%p=Wolu>dzU{2wwmMTxX7w zq|YqyrVRo3lx_nqojbsr`8_~+autvqUpY#8GwTrkkz@I~%^o3fRjYp}`!IC_a4y^i ztlJTQB7Ex)btJ8B0+5a!mzSw9p-&wy-!_e1I+6>Oy_2y1dwGe9&EM;=0o##2UV(u0 z^te2f-+^1}w6F96E=Ai%Wxp>E)nNs;>C?(r0MfN@%O2lDb)=7!Z)bLH0hVvKerx~d z9T4j_kTik-(niY>KP!7&2h<j*KcGI%9xp{fV+-jAq+^ht9)I`W$^ifdTO)$O#&BRT zI0g*nf%fMK`Ud(IDg%{;><k1-1Wb_qfi4fo@ce)1lKo&z0;T^GO%krs#FeTrR*|eU zNs_EI?pLa{KG1A(1E2)mgYO5VDvgsR%8XU{vaRs`TbNY9x+E)%oo-iKEco`s0q})3 zU}<+1`2JejTLY>W+5x}bcmVu%NwUJkMee=9iT?=>$ufiMGF7HSVFMWeRR6-rGEkq= z4rDtO0Wq4HKyT#`XanB@wJ$CKZOQV$P?ayRG5Z-<-dhJE1~LJ#?1)sEiNHU>0QTdf z2Mtg5y4D7P#jzD2->3X{|8eX`8q+&~(YoN@{m8LD>CAcvY|eKBJ?q23!v^Pli3$^) zzk>nnI}OkepccV??x`3AqBJu8LpFrrXYwH&H6iT4bVuq@zZtZ6AO0!^sZt|8sNIlk z=qh<p`$O4(B_G1jlW%%d2Q+q2Km65LKsqiBHy!-4HUNBlw+;9@t^z9ydq5uOuaEou z+x*Yk-;t&Q>}@Rp<L#xu@_5hDSU~#lXF4fSZtM`+p9YK$9RPPl=8pWXjqcJ<G5k#a zvFzc7cSnA`yEqouSzkQTNoZdDNEf7v%yDGl=JQa$yIHRM?(-qP|1%6flK;JIC@z2! z<maJz0nN=H*$2r|V`cB2*TBfY!5?Hp@_&Zmd-*?;eT)IIws2%0ARG04AAmM3u5!Kw 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 diff --git a/extras/AudioPluginHost/Builds/VisualStudio2017/resources.rc b/extras/AudioPluginHost/Builds/VisualStudio2017/resources.rc index 8af2d396..9a16db85 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2017/resources.rc +++ b/extras/AudioPluginHost/Builds/VisualStudio2017/resources.rc @@ -1,3 +1,5 @@ +#pragma code_page(65001) + #ifdef JUCE_USER_DEFINED_RC_FILE #include JUCE_USER_DEFINED_RC_FILE #else @@ -13,8 +15,8 @@ BEGIN BEGIN BLOCK "040904E4" BEGIN - VALUE "CompanyName", "ROLI Ltd.\0" - VALUE "LegalCopyright", "ROLI Ltd.\0" + VALUE "CompanyName", "Raw Material Software Limited\0" + VALUE "LegalCopyright", "Raw Material Software Limited\0" VALUE "FileDescription", "AudioPluginHost\0" VALUE "FileVersion", "1.0.0\0" VALUE "ProductName", "AudioPluginHost\0" diff --git a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj index 81848a76..0728d3b2 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj +++ b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj @@ -64,10 +64,10 @@ <Optimization>Disabled</Optimization> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <AdditionalIncludeDirectories>..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK;..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=1.0.0;JUCE_APP_VERSION_HEX=0x10000;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCE_DISPLAY_SPLASH_SCREEN=0;JUCE_USE_DARK_SPLASH_SCREEN=1;JUCE_PROJUCER_VERSION=0x60005;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_audio_formats=1;JUCE_MODULE_AVAILABLE_juce_audio_processors=1;JUCE_MODULE_AVAILABLE_juce_audio_utils=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_dsp=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_MODULE_AVAILABLE_juce_opengl=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_WASAPI=1;JUCE_DIRECTSOUND=1;JUCE_ALSA=1;JUCE_USE_FLAC=0;JUCE_USE_OGGVORBIS=1;JUCE_PLUGINHOST_VST3=1;JUCE_PLUGINHOST_AU=1;JUCE_PLUGINHOST_LADSPA=1;JUCE_USE_CDREADER=0;JUCE_USE_CDBURNER=0;JUCE_WEB_BROWSER=0;JUCE_STANDALONE_APPLICATION=1;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=1.0.0;JUCE_APP_VERSION_HEX=0x10000;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> <RuntimeTypeInfo>true</RuntimeTypeInfo> - <PrecompiledHeader/> + <PrecompiledHeader>NotUsing</PrecompiledHeader> <AssemblerListingLocation>$(IntDir)\</AssemblerListingLocation> <ObjectFileName>$(IntDir)\</ObjectFileName> <ProgramDataBaseFileName>$(IntDir)\</ProgramDataBaseFileName> @@ -106,10 +106,10 @@ <ClCompile> <Optimization>Full</Optimization> <AdditionalIncludeDirectories>..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK;..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=1.0.0;JUCE_APP_VERSION_HEX=0x10000;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCE_DISPLAY_SPLASH_SCREEN=0;JUCE_USE_DARK_SPLASH_SCREEN=1;JUCE_PROJUCER_VERSION=0x60005;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_audio_formats=1;JUCE_MODULE_AVAILABLE_juce_audio_processors=1;JUCE_MODULE_AVAILABLE_juce_audio_utils=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_dsp=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_MODULE_AVAILABLE_juce_opengl=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_WASAPI=1;JUCE_DIRECTSOUND=1;JUCE_ALSA=1;JUCE_USE_FLAC=0;JUCE_USE_OGGVORBIS=1;JUCE_PLUGINHOST_VST3=1;JUCE_PLUGINHOST_AU=1;JUCE_PLUGINHOST_LADSPA=1;JUCE_USE_CDREADER=0;JUCE_USE_CDBURNER=0;JUCE_WEB_BROWSER=0;JUCE_STANDALONE_APPLICATION=1;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=1.0.0;JUCE_APP_VERSION_HEX=0x10000;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> <RuntimeTypeInfo>true</RuntimeTypeInfo> - <PrecompiledHeader/> + <PrecompiledHeader>NotUsing</PrecompiledHeader> <AssemblerListingLocation>$(IntDir)\</AssemblerListingLocation> <ObjectFileName>$(IntDir)\</ObjectFileName> <ProgramDataBaseFileName>$(IntDir)\</ProgramDataBaseFileName> @@ -132,6 +132,7 @@ <OptimizeReferences>true</OptimizeReferences> <EnableCOMDATFolding>true</EnableCOMDATFolding> <LargeAddressAware>true</LargeAddressAware> + <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> </Link> <Bscmake> <SuppressStartupBanner>true</SuppressStartupBanner> @@ -230,10 +231,10 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_basics\synthesisers\juce_Synthesiser.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_CatmullRomInterpolator.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Interpolators.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_LagrangeInterpolator.cpp"> @@ -242,6 +243,9 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_SmoothedValue.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_WindowedSincInterpolator.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_basics\juce_audio_basics.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -260,6 +264,153 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_devices\midi_io\juce_MidiMessageCollector.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AAudioLoader.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AudioStreamAAudio.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioSourceCaller.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioStream.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioStreamBuilder.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\DataConversionFlowGraph.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FilterAudioStream.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockAdapter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockReader.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockWriter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\LatencyTuner.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\QuirksManager.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceFloatCaller.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceI16Caller.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\StabilizedCallback.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Trace.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Utilities.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Version.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoBuffer.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoController.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerBase.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerIndirect.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\IntegerRatio.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\LinearResampler.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\MultiChannelResampler.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResampler.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerMono.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerStereo.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResampler.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResamplerStereo.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ClipToRange.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\FlowGraphNode.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ManyToMultiConverter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\MonoToMultiConverter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\RampLinear.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SampleRateConverter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkFloat.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI16.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI24.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceFloat.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI16.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI24.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioInputStreamOpenSLES.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioOutputStreamOpenSLES.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamBuffered.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamOpenSLES.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\EngineOpenSLES.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OpenSLESUtilities.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OutputMixerOpenSLES.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_android_Audio.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -359,70 +510,73 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\libFLAC\window_flac.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\analysis.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\analysis.c"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\bitrate.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\bitrate.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\block.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\block.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codebook.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codebook.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\envelope.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\envelope.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\floor0.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\floor0.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\floor1.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\floor1.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\info.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\info.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lpc.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lpc.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lsp.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lsp.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mapping0.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mapping0.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mdct.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mdct.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\misc.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\psy.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\psy.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\registry.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\registry.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\res0.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\res0.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\sharedbook.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\sharedbook.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\smallft.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\smallft.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\synthesis.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\synthesis.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\vorbisenc.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\vorbisenc.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\vorbisfile.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\vorbisfile.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\window.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\window.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\bitwise.c"> @@ -617,6 +771,9 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioProcessorValueTreeState.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_ParameterAttachments.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_RangedAudioParameter.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -719,6 +876,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_FileSearchPath.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -746,6 +906,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_MemoryBlock.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -1022,6 +1185,114 @@ <ClCompile Include="..\..\..\..\modules\juce_data_structures\juce_data_structures.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_AudioBlock_test.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_FixedSizeFunction_test.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_SIMDRegister_test.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\filter_design\juce_FilterDesign.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_Convolution.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_Convolution_test.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_FFT.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_FFT_test.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_Windowing.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\maths\juce_LogRampedValue_test.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\maths\juce_LookupTable.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\maths\juce_Matrix.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\maths\juce_Matrix_test.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\maths\juce_SpecialFunctions.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\native\juce_avx_SIMDNativeOps.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\native\juce_neon_SIMDNativeOps.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\native\juce_sse_SIMDNativeOps.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_BallisticsFilter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_DelayLine.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_DryWetMixer.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_FIRFilter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_FIRFilter_test.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_FirstOrderTPTFilter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_IIRFilter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_LinkwitzRileyFilter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_Oversampling.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_Panner.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessorChain_test.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_StateVariableTPTFilter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_Chorus.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_Compressor.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_LadderFilter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_Limiter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_NoiseGate.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_Phaser.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\juce_dsp.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_events\broadcasters\juce_ActionBroadcaster.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -1631,6 +1902,15 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_MouseListener.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_DragAndDrop.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_android_ContentSharer.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -1649,13 +1929,7 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_FileChooser.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.cpp"> - <ExcludedFromBuild>true</ExcludedFromBuild> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Clipboard.cpp"> - <ExcludedFromBuild>true</ExcludedFromBuild> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Windowing.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_Windowing.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_win32_DragAndDrop.cpp"> @@ -1859,6 +2133,9 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_ActiveXComponent.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_HWNDComponent.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_SystemTrayIcon.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -1898,15 +2175,6 @@ <ClCompile Include="..\..\..\..\modules\juce_opengl\juce_opengl.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_video\capture\juce_CameraDevice.cpp"> - <ExcludedFromBuild>true</ExcludedFromBuild> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_video\playback\juce_VideoComponent.cpp"> - <ExcludedFromBuild>true</ExcludedFromBuild> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_video\juce_video.cpp"> - <ExcludedFromBuild>true</ExcludedFromBuild> - </ClCompile> <ClCompile Include="..\..\JuceLibraryCode\BinaryData.cpp"/> <ClCompile Include="..\..\JuceLibraryCode\include_juce_audio_basics.cpp"/> <ClCompile Include="..\..\JuceLibraryCode\include_juce_audio_devices.cpp"/> @@ -1916,12 +2184,12 @@ <ClCompile Include="..\..\JuceLibraryCode\include_juce_core.cpp"/> <ClCompile Include="..\..\JuceLibraryCode\include_juce_cryptography.cpp"/> <ClCompile Include="..\..\JuceLibraryCode\include_juce_data_structures.cpp"/> + <ClCompile Include="..\..\JuceLibraryCode\include_juce_dsp.cpp"/> <ClCompile Include="..\..\JuceLibraryCode\include_juce_events.cpp"/> <ClCompile Include="..\..\JuceLibraryCode\include_juce_graphics.cpp"/> <ClCompile Include="..\..\JuceLibraryCode\include_juce_gui_basics.cpp"/> <ClCompile Include="..\..\JuceLibraryCode\include_juce_gui_extra.cpp"/> <ClCompile Include="..\..\JuceLibraryCode\include_juce_opengl.cpp"/> - <ClCompile Include="..\..\JuceLibraryCode\include_juce_video.cpp"/> </ItemGroup> <ItemGroup> <ClInclude Include="..\..\Source\Plugins\InternalPlugins.h"/> @@ -1964,10 +2232,10 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_basics\sources\juce_ToneGeneratorAudioSource.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\synthesisers\juce_Synthesiser.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_ADSR.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_CatmullRomInterpolator.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Decibels.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_GenericInterpolator.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_LagrangeInterpolator.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Interpolators.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Reverb.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_SmoothedValue.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\juce_audio_basics.h"/> @@ -1977,6 +2245,66 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_devices\audio_io\juce_SystemAudioVolume.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\midi_io\juce_MidiDevices.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\midi_io\juce_MidiMessageCollector.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStream.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamBase.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamBuilder.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamCallback.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Definitions.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\LatencyTuner.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Oboe.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\ResultWithValue.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\StabilizedCallback.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Utilities.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Version.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AAudioLoader.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AudioStreamAAudio.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioClock.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioSourceCaller.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\DataConversionFlowGraph.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FilterAudioStream.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockAdapter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockReader.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockWriter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\MonotonicCounter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\OboeDebug.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\QuirksManager.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceFloatCaller.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceI16Caller.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Trace.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoBuffer.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoController.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerBase.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerIndirect.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\HyperbolicCosineWindow.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\IntegerRatio.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\KaiserWindow.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\LinearResampler.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\MultiChannelResampler.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResampler.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerMono.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerStereo.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResampler.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResamplerStereo.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ClipToRange.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\FlowGraphNode.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ManyToMultiConverter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\MonoToMultiConverter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\RampLinear.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SampleRateConverter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkFloat.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI16.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI24.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceFloat.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI16.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI24.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioInputStreamOpenSLES.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioOutputStreamOpenSLES.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamBuffered.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamOpenSLES.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\EngineOpenSLES.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OpenSLESUtilities.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OutputMixerOpenSLES.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\juce_android_HighPerformanceAudioHelpers.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\juce_ios_Audio.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\juce_MidiDataConcatenator.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\sources\juce_AudioSourcePlayer.h"/> @@ -2014,50 +2342,51 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\stream_decoder.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\stream_encoder.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\win_utf8_io.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled\res_books_51.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled\res_books_stereo.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\floor\floor_books.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\uncoupled\res_books_uncoupled.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\floor_all.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_8.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_11.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_16.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_44.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_8.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_16.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44p51.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44u.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_8.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_11.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_16.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_22.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_32.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44p51.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44u.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_X.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\backends.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\bitrate.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codebook.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codec_internal.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\envelope.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\highlevel.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup_data.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lpc.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lsp.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\masking.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mdct.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\misc.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\os.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\psy.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\registry.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\scales.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\smallft.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\window.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled\res_books_51.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled\res_books_stereo.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\floor\floor_books.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\uncoupled\res_books_uncoupled.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\floor_all.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_8.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_11.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_16.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_44.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_8.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_16.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44p51.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44u.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_8.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_11.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_16.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_22.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_32.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44p51.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44u.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_X.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\backends.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\bitrate.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codebook.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codec_internal.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\envelope.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\highlevel.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup_data.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lpc.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lsp.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\masking.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mdct.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\misc.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\os.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\psy.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\registry.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\scales.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\smallft.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\window.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\codec.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\config_types.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\crctable.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\ogg.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\os_types.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\vorbisenc.h"/> @@ -2146,6 +2475,7 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst\vsteditcontroller.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst\vstparameters.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst\vstpresetfile.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_AU_Shared.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_AudioUnitPluginFormat.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LADSPAPluginFormat.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_VST3Common.h"/> @@ -2172,6 +2502,7 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioParameterInt.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioProcessorParameterWithID.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioProcessorValueTreeState.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_ParameterAttachments.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_RangedAudioParameter.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\juce_audio_processors.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_utils\audio_cd\juce_AudioCDBurner.h"/> @@ -2211,6 +2542,7 @@ <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_FileOutputStream.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_FileSearchPath.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_MemoryMappedFile.h"/> + <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_WildcardFileFilter.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\javascript\juce_Javascript.h"/> @@ -2224,6 +2556,7 @@ <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_Random.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_Range.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_StatisticsAccumulator.h"/> + <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_Atomic.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_ByteOrder.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_ContainerDeletePolicy.h"/> @@ -2266,6 +2599,7 @@ <ClInclude Include="..\..\..\..\modules\juce_core\streams\juce_SubregionStream.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\streams\juce_URLInputSource.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerSupport.h"/> + <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerWarnings.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_PlatformDefs.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_StandardHeader.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_SystemStats.h"/> @@ -2340,6 +2674,53 @@ <ClInclude Include="..\..\..\..\modules\juce_data_structures\values\juce_ValueTreeSynchroniser.h"/> <ClInclude Include="..\..\..\..\modules\juce_data_structures\values\juce_ValueWithDefault.h"/> <ClInclude Include="..\..\..\..\modules\juce_data_structures\juce_data_structures.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\containers\juce_AudioBlock.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\containers\juce_FixedSizeFunction.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\containers\juce_SIMDRegister.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\containers\juce_SIMDRegister_Impl.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\filter_design\juce_FilterDesign.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\frequency\juce_Convolution.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\frequency\juce_FFT.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\frequency\juce_Windowing.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_FastMathApproximations.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_LogRampedValue.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_LookupTable.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_Matrix.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_Phase.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_Polynomial.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_SpecialFunctions.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\native\juce_avx_SIMDNativeOps.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\native\juce_fallback_SIMDNativeOps.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\native\juce_neon_SIMDNativeOps.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\native\juce_sse_SIMDNativeOps.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_BallisticsFilter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_DelayLine.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_DryWetMixer.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_FIRFilter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_FirstOrderTPTFilter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_IIRFilter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_IIRFilter_Impl.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_LinkwitzRileyFilter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_Oversampling.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_Panner.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessContext.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessorChain.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessorDuplicator.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessorWrapper.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_StateVariableFilter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_StateVariableTPTFilter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Bias.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Chorus.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Compressor.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Gain.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_LadderFilter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Limiter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_NoiseGate.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Oscillator.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Phaser.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Reverb.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_WaveShaper.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\juce_dsp.h"/> <ClInclude Include="..\..\..\..\modules\juce_events\broadcasters\juce_ActionBroadcaster.h"/> <ClInclude Include="..\..\..\..\modules\juce_events\broadcasters\juce_ActionListener.h"/> <ClInclude Include="..\..\..\..\modules\juce_events\broadcasters\juce_AsyncUpdater.h"/> @@ -2522,7 +2903,8 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_SelectedItemSet.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_TextDragAndDropTarget.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_TooltipClient.h"/> - <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.h"/> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.h"/> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_MultiTouchMapper.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\positioning\juce_MarkerList.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\positioning\juce_RelativeCoordinate.h"/> @@ -2574,6 +2956,7 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ActiveXControlComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"/> + <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_HWNDComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_NSViewComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ScopedDPIAwarenessDisabler.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_UIViewComponent.h"/> @@ -2614,23 +2997,15 @@ <ClInclude Include="..\..\..\..\modules\juce_opengl\opengl\juce_OpenGLTexture.h"/> <ClInclude Include="..\..\..\..\modules\juce_opengl\utils\juce_OpenGLAppComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_opengl\juce_opengl.h"/> - <ClInclude Include="..\..\..\..\modules\juce_video\capture\juce_CameraDevice.h"/> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_android_CameraDevice.h"/> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_android_Video.h"/> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_ios_CameraDevice.h"/> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_mac_CameraDevice.h"/> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_mac_Video.h"/> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_win32_CameraDevice.h"/> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_win32_Video.h"/> - <ClInclude Include="..\..\..\..\modules\juce_video\playback\juce_VideoComponent.h"/> - <ClInclude Include="..\..\..\..\modules\juce_video\juce_video.h"/> - <ClInclude Include="..\..\JuceLibraryCode\AppConfig.h"/> <ClInclude Include="..\..\JuceLibraryCode\BinaryData.h"/> <ClInclude Include="..\..\JuceLibraryCode\JuceHeader.h"/> </ItemGroup> <ItemGroup> <None Include="..\..\Source\JUCEAppIcon.png"/> + <None Include="..\..\..\..\modules\juce_audio_devices\native\oboe\CMakeLists.txt"/> + <None Include="..\..\..\..\modules\juce_audio_devices\native\oboe\readme.md"/> <None Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\Flac Licence.txt"/> + <None Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\README.md"/> <None Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\Ogg Vorbis Licence.txt"/> <None Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\base\LICENSE.txt"/> <None Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\base\README.md"/> diff --git a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters index adc0637e..07c82862 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters +++ b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters @@ -47,6 +47,36 @@ <Filter Include="JUCE Modules\juce_audio_devices\midi_io"> <UniqueIdentifier>{092EFC17-7C95-7E04-0ACA-0D61A462EE81}</UniqueIdentifier> </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\include\oboe"> + <UniqueIdentifier>{285118C6-8FDA-7DCE-BEF4-FFB2120876C5}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\include"> + <UniqueIdentifier>{69ED6B61-9B8D-D47E-E4A6-2E9F9A94A75A}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\aaudio"> + <UniqueIdentifier>{7CDB7CD1-BB96-F593-3C78-1E06182B5839}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\common"> + <UniqueIdentifier>{B0A708DE-B4CF-196B-14FB-DC8221509B8E}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\fifo"> + <UniqueIdentifier>{34F46ADE-EE31-227A-A69E-7732E70145F1}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler"> + <UniqueIdentifier>{BB9B3C77-17FB-E994-8B75-88F1727E4655}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph"> + <UniqueIdentifier>{C0971D77-2F14-190A-E2AE-89D6285F4D5A}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\opensles"> + <UniqueIdentifier>{AABEA333-6524-8891-51C7-6DAEB5700628}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src"> + <UniqueIdentifier>{F2D29337-983E-BAD7-7B5C-E0AB3D53D404}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe"> + <UniqueIdentifier>{C674B0FB-1FC0-2986-94B1-083845018994}</UniqueIdentifier> + </Filter> <Filter Include="JUCE Modules\juce_audio_devices\native"> <UniqueIdentifier>{0AFC1CE8-F6E6-9817-8C21-8432B2A375DA}</UniqueIdentifier> </Filter> @@ -71,26 +101,26 @@ <Filter Include="JUCE Modules\juce_audio_formats\codecs\flac"> <UniqueIdentifier>{9EB3EC7F-2AB7-DDAA-3C05-DF382B728D3F}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled"> - <UniqueIdentifier>{02D37B85-7DE2-C8E7-A274-A5A0FBE99D69}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled"> + <UniqueIdentifier>{6B9FBFDC-1D10-6246-356D-00FF4535CECB}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\floor"> - <UniqueIdentifier>{DAF3BAAF-5207-4C34-61B9-A97DDC930D50}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\floor"> + <UniqueIdentifier>{D6FCFC8E-7136-9109-78C0-91A3EB4C443F}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\uncoupled"> - <UniqueIdentifier>{C7885588-8436-4C21-DC1E-58879BF53BDC}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\uncoupled"> + <UniqueIdentifier>{EBF18AC1-F0ED-937A-2824-4307CE2ADAF7}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books"> - <UniqueIdentifier>{E4ECEA39-0EFF-2443-91B3-1E5DA7AD5AE4}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books"> + <UniqueIdentifier>{5A0F7922-2EFB-6465-57E4-A445B804EFB5}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes"> - <UniqueIdentifier>{210B8D25-68E0-32C3-1449-6A40F109C5E9}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes"> + <UniqueIdentifier>{4EC45416-0E7C-7567-6F75-D0C8CEE7DC4F}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib"> - <UniqueIdentifier>{378AD911-E8E4-D230-E76B-34542849509D}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib"> + <UniqueIdentifier>{C2985031-0496-55B5-41A8-BAB99E53D89D}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2"> - <UniqueIdentifier>{F6CED5B6-0A8C-56D2-C1AC-DED6BE774A13}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7"> + <UniqueIdentifier>{FB4AB426-7009-0036-BB75-E34256AA7C89}</UniqueIdentifier> </Filter> <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis"> <UniqueIdentifier>{E684D858-09E8-0251-8E86-5657129641E1}</UniqueIdentifier> @@ -266,6 +296,30 @@ <Filter Include="JUCE Modules\juce_data_structures"> <UniqueIdentifier>{911F0159-A7A8-4A43-3FD4-154F62F4A44B}</UniqueIdentifier> </Filter> + <Filter Include="JUCE Modules\juce_dsp\containers"> + <UniqueIdentifier>{53CF03D3-988B-CD28-9130-CE08FDCEF7E9}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_dsp\filter_design"> + <UniqueIdentifier>{29C6FE02-507E-F3FE-16CD-74D84842C1EA}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_dsp\frequency"> + <UniqueIdentifier>{8001BD68-125B-E392-8D3B-1F9C9520A65A}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_dsp\maths"> + <UniqueIdentifier>{EDC17061-CFA0-8EA0-0ADA-90F31C2FB0F2}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_dsp\native"> + <UniqueIdentifier>{B813BD14-6565-2525-9AC3-E3AA48EDDA85}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_dsp\processors"> + <UniqueIdentifier>{DDF4BA73-8578-406D-21F8-06B9BC70BFEA}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_dsp\widgets"> + <UniqueIdentifier>{73374573-0194-9A6E-461A-A81EEB511C26}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_dsp"> + <UniqueIdentifier>{5DD60D0E-B16A-0BED-EDC4-C56E6960CA9E}</UniqueIdentifier> + </Filter> <Filter Include="JUCE Modules\juce_events\broadcasters"> <UniqueIdentifier>{9D5816C2-E2B2-2E3F-B095-AC8BD1100D29}</UniqueIdentifier> </Filter> @@ -359,6 +413,9 @@ <Filter Include="JUCE Modules\juce_gui_basics\mouse"> <UniqueIdentifier>{FE3CB19C-EF43-5CF5-DAF0-09D4E43D0AB9}</UniqueIdentifier> </Filter> + <Filter Include="JUCE Modules\juce_gui_basics\native\x11"> + <UniqueIdentifier>{FE7E6CD5-C7A0-DB20-4E7E-D6E7F08C4578}</UniqueIdentifier> + </Filter> <Filter Include="JUCE Modules\juce_gui_basics\native"> <UniqueIdentifier>{895C2D33-E08D-B1BA-BB36-FC4CA65090C8}</UniqueIdentifier> </Filter> @@ -410,18 +467,6 @@ <Filter Include="JUCE Modules\juce_opengl"> <UniqueIdentifier>{9FBFF5E5-56F1-34A1-2C85-F760DA2B1EB7}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_video\capture"> - <UniqueIdentifier>{CB8DF3B2-0409-6D59-C5D4-A034EBB7F973}</UniqueIdentifier> - </Filter> - <Filter Include="JUCE Modules\juce_video\native"> - <UniqueIdentifier>{7774F72F-C951-B8AB-E927-E34AD23C52C8}</UniqueIdentifier> - </Filter> - <Filter Include="JUCE Modules\juce_video\playback"> - <UniqueIdentifier>{658BADF8-7095-C722-F9EC-9F36E8818187}</UniqueIdentifier> - </Filter> - <Filter Include="JUCE Modules\juce_video"> - <UniqueIdentifier>{2C58F450-CD01-0231-2F16-0D4D68565164}</UniqueIdentifier> - </Filter> <Filter Include="JUCE Modules"> <UniqueIdentifier>{FE955B6B-68AC-AA07-70D8-2413F6DB65C8}</UniqueIdentifier> </Filter> @@ -532,10 +577,10 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_basics\synthesisers\juce_Synthesiser.cpp"> <Filter>JUCE Modules\juce_audio_basics\synthesisers</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_CatmullRomInterpolator.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.cpp"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Interpolators.cpp"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_LagrangeInterpolator.cpp"> @@ -544,6 +589,9 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_SmoothedValue.cpp"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_WindowedSincInterpolator.cpp"> + <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_basics\juce_audio_basics.cpp"> <Filter>JUCE Modules\juce_audio_basics</Filter> </ClCompile> @@ -565,6 +613,153 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_devices\midi_io\juce_MidiMessageCollector.cpp"> <Filter>JUCE Modules\juce_audio_devices\midi_io</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AAudioLoader.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\aaudio</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AudioStreamAAudio.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\aaudio</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioSourceCaller.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioStream.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioStreamBuilder.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\DataConversionFlowGraph.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FilterAudioStream.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockAdapter.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockReader.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockWriter.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\LatencyTuner.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\QuirksManager.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceFloatCaller.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceI16Caller.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\StabilizedCallback.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Trace.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Utilities.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Version.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoBuffer.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoController.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerBase.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerIndirect.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\IntegerRatio.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\LinearResampler.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\MultiChannelResampler.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResampler.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerMono.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerStereo.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResampler.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResamplerStereo.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ClipToRange.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\FlowGraphNode.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ManyToMultiConverter.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\MonoToMultiConverter.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\RampLinear.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SampleRateConverter.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkFloat.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI16.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI24.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceFloat.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI16.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI24.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioInputStreamOpenSLES.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioOutputStreamOpenSLES.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamBuffered.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamOpenSLES.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\EngineOpenSLES.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OpenSLESUtilities.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OutputMixerOpenSLES.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_android_Audio.cpp"> <Filter>JUCE Modules\juce_audio_devices\native</Filter> </ClCompile> @@ -667,71 +862,74 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\libFLAC\window_flac.c"> <Filter>JUCE Modules\juce_audio_formats\codecs\flac\libFLAC</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\analysis.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\analysis.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\bitrate.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\bitrate.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\block.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\block.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codebook.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codebook.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\envelope.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\envelope.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\floor0.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\floor0.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\floor1.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\floor1.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\info.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\info.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lpc.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lpc.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lsp.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lsp.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mapping0.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mapping0.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mdct.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mdct.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\misc.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\psy.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\psy.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\registry.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\registry.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\res0.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\res0.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\sharedbook.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\sharedbook.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\smallft.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\smallft.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\synthesis.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\synthesis.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\vorbisenc.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\vorbisenc.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\vorbisfile.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\vorbisfile.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\window.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\window.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\bitwise.c"> <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> @@ -931,6 +1129,9 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioProcessorValueTreeState.cpp"> <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_ParameterAttachments.cpp"> + <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_RangedAudioParameter.cpp"> <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> </ClCompile> @@ -1051,6 +1252,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_FileSearchPath.cpp"> <Filter>JUCE Modules\juce_core\files</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.cpp"> + <Filter>JUCE Modules\juce_core\files</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.cpp"> <Filter>JUCE Modules\juce_core\files</Filter> </ClCompile> @@ -1078,6 +1282,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> <Filter>JUCE Modules\juce_core\maths</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.cpp"> + <Filter>JUCE Modules\juce_core\memory</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_MemoryBlock.cpp"> <Filter>JUCE Modules\juce_core\memory</Filter> </ClCompile> @@ -1378,6 +1585,117 @@ <ClCompile Include="..\..\..\..\modules\juce_data_structures\juce_data_structures.mm"> <Filter>JUCE Modules\juce_data_structures</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_AudioBlock_test.cpp"> + <Filter>JUCE Modules\juce_dsp\containers</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_FixedSizeFunction_test.cpp"> + <Filter>JUCE Modules\juce_dsp\containers</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_SIMDRegister_test.cpp"> + <Filter>JUCE Modules\juce_dsp\containers</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\filter_design\juce_FilterDesign.cpp"> + <Filter>JUCE Modules\juce_dsp\filter_design</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_Convolution.cpp"> + <Filter>JUCE Modules\juce_dsp\frequency</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_Convolution_test.cpp"> + <Filter>JUCE Modules\juce_dsp\frequency</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_FFT.cpp"> + <Filter>JUCE Modules\juce_dsp\frequency</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_FFT_test.cpp"> + <Filter>JUCE Modules\juce_dsp\frequency</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_Windowing.cpp"> + <Filter>JUCE Modules\juce_dsp\frequency</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\maths\juce_LogRampedValue_test.cpp"> + <Filter>JUCE Modules\juce_dsp\maths</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\maths\juce_LookupTable.cpp"> + <Filter>JUCE Modules\juce_dsp\maths</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\maths\juce_Matrix.cpp"> + <Filter>JUCE Modules\juce_dsp\maths</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\maths\juce_Matrix_test.cpp"> + <Filter>JUCE Modules\juce_dsp\maths</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\maths\juce_SpecialFunctions.cpp"> + <Filter>JUCE Modules\juce_dsp\maths</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\native\juce_avx_SIMDNativeOps.cpp"> + <Filter>JUCE Modules\juce_dsp\native</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\native\juce_neon_SIMDNativeOps.cpp"> + <Filter>JUCE Modules\juce_dsp\native</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\native\juce_sse_SIMDNativeOps.cpp"> + <Filter>JUCE Modules\juce_dsp\native</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_BallisticsFilter.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_DelayLine.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_DryWetMixer.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_FIRFilter.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_FIRFilter_test.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_FirstOrderTPTFilter.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_IIRFilter.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_LinkwitzRileyFilter.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_Oversampling.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_Panner.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessorChain_test.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_StateVariableTPTFilter.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_Chorus.cpp"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_Compressor.cpp"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_LadderFilter.cpp"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_Limiter.cpp"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_NoiseGate.cpp"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_Phaser.cpp"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\juce_dsp.cpp"> + <Filter>JUCE Modules\juce_dsp</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\juce_dsp.mm"> + <Filter>JUCE Modules\juce_dsp</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_events\broadcasters\juce_ActionBroadcaster.cpp"> <Filter>JUCE Modules\juce_events\broadcasters</Filter> </ClCompile> @@ -2005,6 +2323,15 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_MouseListener.cpp"> <Filter>JUCE Modules\juce_gui_basics\mouse</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_DragAndDrop.cpp"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.cpp"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.cpp"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_android_ContentSharer.cpp"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> </ClCompile> @@ -2032,13 +2359,7 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_FileChooser.cpp"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.cpp"> - <Filter>JUCE Modules\juce_gui_basics\native</Filter> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Clipboard.cpp"> - <Filter>JUCE Modules\juce_gui_basics\native</Filter> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Windowing.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_Windowing.cpp"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_mac_FileChooser.mm"> @@ -2272,6 +2593,9 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_ActiveXComponent.cpp"> <Filter>JUCE Modules\juce_gui_extra\native</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_HWNDComponent.cpp"> + <Filter>JUCE Modules\juce_gui_extra\native</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_SystemTrayIcon.cpp"> <Filter>JUCE Modules\juce_gui_extra\native</Filter> </ClCompile> @@ -2317,18 +2641,6 @@ <ClCompile Include="..\..\..\..\modules\juce_opengl\juce_opengl.mm"> <Filter>JUCE Modules\juce_opengl</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_video\capture\juce_CameraDevice.cpp"> - <Filter>JUCE Modules\juce_video\capture</Filter> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_video\playback\juce_VideoComponent.cpp"> - <Filter>JUCE Modules\juce_video\playback</Filter> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_video\juce_video.cpp"> - <Filter>JUCE Modules\juce_video</Filter> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_video\juce_video.mm"> - <Filter>JUCE Modules\juce_video</Filter> - </ClCompile> <ClCompile Include="..\..\JuceLibraryCode\BinaryData.cpp"> <Filter>JUCE Library Code</Filter> </ClCompile> @@ -2356,6 +2668,9 @@ <ClCompile Include="..\..\JuceLibraryCode\include_juce_data_structures.cpp"> <Filter>JUCE Library Code</Filter> </ClCompile> + <ClCompile Include="..\..\JuceLibraryCode\include_juce_dsp.cpp"> + <Filter>JUCE Library Code</Filter> + </ClCompile> <ClCompile Include="..\..\JuceLibraryCode\include_juce_events.cpp"> <Filter>JUCE Library Code</Filter> </ClCompile> @@ -2371,9 +2686,6 @@ <ClCompile Include="..\..\JuceLibraryCode\include_juce_opengl.cpp"> <Filter>JUCE Library Code</Filter> </ClCompile> - <ClCompile Include="..\..\JuceLibraryCode\include_juce_video.cpp"> - <Filter>JUCE Library Code</Filter> - </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="..\..\Source\Plugins\InternalPlugins.h"> @@ -2496,16 +2808,16 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_ADSR.h"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_CatmullRomInterpolator.h"> + <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Decibels.h"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Decibels.h"> + <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_GenericInterpolator.h"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.h"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_LagrangeInterpolator.h"> + <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Interpolators.h"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Reverb.h"> @@ -2535,6 +2847,186 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_devices\midi_io\juce_MidiMessageCollector.h"> <Filter>JUCE Modules\juce_audio_devices\midi_io</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStream.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamBase.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamBuilder.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamCallback.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Definitions.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\LatencyTuner.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Oboe.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\ResultWithValue.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\StabilizedCallback.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Utilities.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Version.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AAudioLoader.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\aaudio</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AudioStreamAAudio.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\aaudio</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioClock.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioSourceCaller.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\DataConversionFlowGraph.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FilterAudioStream.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockAdapter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockReader.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockWriter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\MonotonicCounter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\OboeDebug.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\QuirksManager.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceFloatCaller.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceI16Caller.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Trace.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoBuffer.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoController.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerBase.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerIndirect.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\HyperbolicCosineWindow.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\IntegerRatio.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\KaiserWindow.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\LinearResampler.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\MultiChannelResampler.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResampler.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerMono.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerStereo.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResampler.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResamplerStereo.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ClipToRange.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\FlowGraphNode.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ManyToMultiConverter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\MonoToMultiConverter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\RampLinear.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SampleRateConverter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkFloat.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI16.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI24.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceFloat.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI16.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI24.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioInputStreamOpenSLES.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioOutputStreamOpenSLES.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamBuffered.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamOpenSLES.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\EngineOpenSLES.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OpenSLESUtilities.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OutputMixerOpenSLES.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\juce_android_HighPerformanceAudioHelpers.h"> + <Filter>JUCE Modules\juce_audio_devices\native</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\juce_ios_Audio.h"> <Filter>JUCE Modules\juce_audio_devices\native</Filter> </ClInclude> @@ -2646,131 +3138,131 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\win_utf8_io.h"> <Filter>JUCE Modules\juce_audio_formats\codecs\flac</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled\res_books_51.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled\res_books_51.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled\res_books_stereo.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled\res_books_stereo.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\floor\floor_books.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\floor</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\floor\floor_books.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\floor</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\uncoupled\res_books_uncoupled.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\uncoupled</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\uncoupled\res_books_uncoupled.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\uncoupled</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\floor_all.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\floor_all.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_8.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_8.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_11.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_11.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_16.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_16.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_44.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_44.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_8.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_8.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_16.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_16.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44p51.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44p51.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44u.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44u.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_8.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_8.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_11.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_11.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_16.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_16.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_22.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_22.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_32.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_32.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44p51.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44p51.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44u.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44u.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_X.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_X.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\backends.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\backends.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\bitrate.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\bitrate.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codebook.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codebook.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codec_internal.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codec_internal.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\envelope.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\envelope.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\highlevel.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\highlevel.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup_data.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup_data.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lpc.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lpc.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lsp.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lsp.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\masking.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\masking.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mdct.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mdct.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\misc.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\misc.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\os.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\os.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\psy.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\psy.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\registry.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\registry.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\scales.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\scales.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\smallft.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\smallft.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\window.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\window.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\codec.h"> <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> @@ -2778,6 +3270,9 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\config_types.h"> <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\crctable.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\ogg.h"> <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> </ClInclude> @@ -3042,6 +3537,9 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst\vstpresetfile.h"> <Filter>JUCE Modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_AU_Shared.h"> + <Filter>JUCE Modules\juce_audio_processors\format_types</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_AudioUnitPluginFormat.h"> <Filter>JUCE Modules\juce_audio_processors\format_types</Filter> </ClInclude> @@ -3120,6 +3618,9 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioProcessorValueTreeState.h"> <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_ParameterAttachments.h"> + <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_RangedAudioParameter.h"> <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> </ClInclude> @@ -3237,6 +3738,9 @@ <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_MemoryMappedFile.h"> <Filter>JUCE Modules\juce_core\files</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.h"> + <Filter>JUCE Modules\juce_core\files</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.h"> <Filter>JUCE Modules\juce_core\files</Filter> </ClInclude> @@ -3276,6 +3780,9 @@ <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_StatisticsAccumulator.h"> <Filter>JUCE Modules\juce_core\maths</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.h"> + <Filter>JUCE Modules\juce_core\memory</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_Atomic.h"> <Filter>JUCE Modules\juce_core\memory</Filter> </ClInclude> @@ -3402,6 +3909,9 @@ <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerSupport.h"> <Filter>JUCE Modules\juce_core\system</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerWarnings.h"> + <Filter>JUCE Modules\juce_core\system</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_PlatformDefs.h"> <Filter>JUCE Modules\juce_core\system</Filter> </ClInclude> @@ -3624,6 +4134,147 @@ <ClInclude Include="..\..\..\..\modules\juce_data_structures\juce_data_structures.h"> <Filter>JUCE Modules\juce_data_structures</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\containers\juce_AudioBlock.h"> + <Filter>JUCE Modules\juce_dsp\containers</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\containers\juce_FixedSizeFunction.h"> + <Filter>JUCE Modules\juce_dsp\containers</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\containers\juce_SIMDRegister.h"> + <Filter>JUCE Modules\juce_dsp\containers</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\containers\juce_SIMDRegister_Impl.h"> + <Filter>JUCE Modules\juce_dsp\containers</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\filter_design\juce_FilterDesign.h"> + <Filter>JUCE Modules\juce_dsp\filter_design</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\frequency\juce_Convolution.h"> + <Filter>JUCE Modules\juce_dsp\frequency</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\frequency\juce_FFT.h"> + <Filter>JUCE Modules\juce_dsp\frequency</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\frequency\juce_Windowing.h"> + <Filter>JUCE Modules\juce_dsp\frequency</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_FastMathApproximations.h"> + <Filter>JUCE Modules\juce_dsp\maths</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_LogRampedValue.h"> + <Filter>JUCE Modules\juce_dsp\maths</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_LookupTable.h"> + <Filter>JUCE Modules\juce_dsp\maths</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_Matrix.h"> + <Filter>JUCE Modules\juce_dsp\maths</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_Phase.h"> + <Filter>JUCE Modules\juce_dsp\maths</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_Polynomial.h"> + <Filter>JUCE Modules\juce_dsp\maths</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\maths\juce_SpecialFunctions.h"> + <Filter>JUCE Modules\juce_dsp\maths</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\native\juce_avx_SIMDNativeOps.h"> + <Filter>JUCE Modules\juce_dsp\native</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\native\juce_fallback_SIMDNativeOps.h"> + <Filter>JUCE Modules\juce_dsp\native</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\native\juce_neon_SIMDNativeOps.h"> + <Filter>JUCE Modules\juce_dsp\native</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\native\juce_sse_SIMDNativeOps.h"> + <Filter>JUCE Modules\juce_dsp\native</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_BallisticsFilter.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_DelayLine.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_DryWetMixer.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_FIRFilter.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_FirstOrderTPTFilter.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_IIRFilter.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_IIRFilter_Impl.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_LinkwitzRileyFilter.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_Oversampling.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_Panner.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessContext.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessorChain.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessorDuplicator.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessorWrapper.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_StateVariableFilter.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_StateVariableTPTFilter.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Bias.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Chorus.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Compressor.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Gain.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_LadderFilter.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Limiter.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_NoiseGate.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Oscillator.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Phaser.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Reverb.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_WaveShaper.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\juce_dsp.h"> + <Filter>JUCE Modules\juce_dsp</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_events\broadcasters\juce_ActionBroadcaster.h"> <Filter>JUCE Modules\juce_events\broadcasters</Filter> </ClInclude> @@ -4170,8 +4821,11 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_TooltipClient.h"> <Filter>JUCE Modules\juce_gui_basics\mouse</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.h"> - <Filter>JUCE Modules\juce_gui_basics\native</Filter> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.h"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.h"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_MultiTouchMapper.h"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> @@ -4326,6 +4980,9 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"> <Filter>JUCE Modules\juce_gui_extra\embedding</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_HWNDComponent.h"> + <Filter>JUCE Modules\juce_gui_extra\embedding</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_NSViewComponent.h"> <Filter>JUCE Modules\juce_gui_extra\embedding</Filter> </ClInclude> @@ -4446,39 +5103,6 @@ <ClInclude Include="..\..\..\..\modules\juce_opengl\juce_opengl.h"> <Filter>JUCE Modules\juce_opengl</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_video\capture\juce_CameraDevice.h"> - <Filter>JUCE Modules\juce_video\capture</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_android_CameraDevice.h"> - <Filter>JUCE Modules\juce_video\native</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_android_Video.h"> - <Filter>JUCE Modules\juce_video\native</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_ios_CameraDevice.h"> - <Filter>JUCE Modules\juce_video\native</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_mac_CameraDevice.h"> - <Filter>JUCE Modules\juce_video\native</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_mac_Video.h"> - <Filter>JUCE Modules\juce_video\native</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_win32_CameraDevice.h"> - <Filter>JUCE Modules\juce_video\native</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_win32_Video.h"> - <Filter>JUCE Modules\juce_video\native</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_video\playback\juce_VideoComponent.h"> - <Filter>JUCE Modules\juce_video\playback</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_video\juce_video.h"> - <Filter>JUCE Modules\juce_video</Filter> - </ClInclude> - <ClInclude Include="..\..\JuceLibraryCode\AppConfig.h"> - <Filter>JUCE Library Code</Filter> - </ClInclude> <ClInclude Include="..\..\JuceLibraryCode\BinaryData.h"> <Filter>JUCE Library Code</Filter> </ClInclude> @@ -4490,9 +5114,18 @@ <None Include="..\..\Source\JUCEAppIcon.png"> <Filter>AudioPluginHost\Source</Filter> </None> + <None Include="..\..\..\..\modules\juce_audio_devices\native\oboe\CMakeLists.txt"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe</Filter> + </None> + <None Include="..\..\..\..\modules\juce_audio_devices\native\oboe\readme.md"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe</Filter> + </None> <None Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\Flac Licence.txt"> <Filter>JUCE Modules\juce_audio_formats\codecs\flac</Filter> </None> + <None Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\README.md"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7</Filter> + </None> <None Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\Ogg Vorbis Licence.txt"> <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> </None> diff --git a/extras/AudioPluginHost/Builds/VisualStudio2019/icon.ico b/extras/AudioPluginHost/Builds/VisualStudio2019/icon.ico index 09d32ad703e414097a17e969e7d765325e912c77..a2d5c802ee695781308dca425c215c9178a12601 100644 GIT binary patch literal 38465 zcmc${2Ut|e(my-|5flX!1p`@>Ac!DABxevL2LnkFMFd0yR5GFjK@>qiB<CCjlnf#g zBudUX=bWbhr^h>9b=BQ_-}^n^dA8{@XHIwhs=B(ms=CKTp>R<6C{j`sQq!Vt;-gSf zC=`m8_Uq?3<arA6jDzD}pBYgojRVLF$OYdQzl=hm`B5k)<TLUr^5pAtq(X@x?f&l4 z%5yz!_~B)M&zFpjh|YoySl~T;riy&`yY}iIy@-rHz6yNXTZL{YYy;U|g`hmT2K1DA zfaZ+bV4yJ`<n&db;XCl%@B4wDt*Syx+B*9{lz9s9yA+No8Bg*+Q}Q)X>dlNPRUuNK zZ>R>`N8bIu57=i-%OuE(sRjBHH^9q_p}%Zj;m-$V`l`U-WFLTSAO^@&W={?Jmevpu z<#h!E0|UTB%N)3>_yFrmw&2-4QSkQ3aRA#+c9nsaf(X!FitsW}g;sp$!U5%yn>h<q zg!+K8U^h^|;D+fVDJco8udjoZl@$;j@dl(ucwyQ$<pu#*#s`{#!AD;|C|kFO6PWg} z4>`VSkd&AVe!l!)`GKMsPfT0bzQ6W8c-frM0>>xZZw5Hs9mf<6`5+A4pW8dySc2BF z6wq6pjVYsTpFns=!3u2e`)&r@2_MIl^S6UBn6d3^Yiq&92ezQEuMgOGdI8JsVQ_zF z3cQ|}$F%op$>?|xGXVtb`!I#issRLt$6}j<ix&1EcVZQ2JoU!(al!KikZK<W4#U$J z{7`<WHM8H^%efAK$8U0hk6!?|Y5f?}M#IS$(}$veFc6B*z_ibtoyW)zGk$%a(VEYP z0BoE4Wd-QP%>a3yX7Dg`0@%1e!}Ou#9tm<M*MMr*DA4U02bqJP(dx+fK^=g)P&qIO zN;+0CZPmi304&aV3&6T+8Ynuw0>ZEIfO^>iD4AIU)$>!|^ar+wx_G}jw4`=)8r)8q z#k9q?e^9>+WD4goMZaPZR8P$S`0n@mi|qsA$m;)$&TU@;?u82=qGlNcb*%xX#ubn? zv;r~*KL2w5!1mbdm-81Hqu<TnIT94A7!QSV#Q9pV{rs-Rz6aaDw$RSdB1Hr#(Eh;7 z5gMNV@>0)pBT+AKyQE&=`bNFbtp=&5k$MYLkbAWP*Uy;m;5*2>|0S8fG`m>r&Ztr7 z7L1e?yU$S|ska=|O?QKll^L+Gv4Sb^zHYh)B=?mA``Rb~-&I4}s32|s(&0aR0QEp4 z-}ULG;-?#-9r<8<bq;K8ZiB(55m24d0E&V>g87L>usS~oI`Zs6|EE`Aw*MnQZ>?kA z4eKlbu&o->$Im+TcMvoSJQxtUHa@D4!}PT{wFJt-tH7J<vEOVkw8gcVU%+5Z@HaaQ z?eWJ~JfN${1*|QMfC&V%OMN_meZfBejxPKj&OJna6N$Yaz}D6_hSxy7s2}KJ*MZs$ zgnsp#ALwJ(gbyz{Ff!TR-bBXbBhV;to50TN-{F85;d}3g>o9ieolnUx>HZV?SRAcy z%`tuDkJMu@{7w#VjG&w#-`Fe9w+!5qvIAZkfxpD@C;qYY+j8z<yTix<()g7=Ks|xu zy}5-3o(_}1+j$Z^aq$2u$|`_^feU!4{}sdE(f^Wa2)2+pGT2ZE2I>m{8odo3Bl-Yo zeLn_po?I$=x&d`OA$$(A=814519f#x4EFN!a==0VR}6omkEPvLllyILoam~>=p>vM z-_K1rSK%C+9Nz+368#wZ7tS>U+M}WX(uNlX10n}cb$@VO&;;<&3jkq05g;yb3Mic; z1J8`8zv<zxXv4L+`F#l3SX~5gZbF(EeMf8+v=@-~;1|>1)_b_-f5jm71BMffC&063 z&%o&DC<Yh&)7jYx92^{g00#vq2-d;K{CmE!z6GpDT0UZA0BOo(JM4uv7237U4K&b} z8~B0#uP|(HZ-1lv^G!!b2M`ev0i_w?-(>zhZFmp;B=q(cutV&mYQd9>&}KuM+EBCl z7ut|MEDHRM;1~l7_!Dg`7U-v)<KqU|p-+B`VR32*W2@DR+yd1KT|YzHo%k=k!_xe| z=3@!K$Q(=KPc`)GWM!m5h{wI((uaBoX(GH=!gUO;AO25&9Q*I-(@?7YFy4QnucxO6 zT<+=rmNp!N;V)&F^$S@u$JGklw&6N9KC%hYV&*|=^j{0_8JRzk#C(TFqcJt~2hZ`H z0ab-*V6vy-ucfyEtgkF!)=ky?C+k@HBeR<z`olbkD*J2U<d^;<eJFEjX=xA<5%CQJ z)WfjG77#zP_(MrRK96o}eWQ<+zemROH(wL$vtsK*XS6|ASJy8wK-vll3P2||1yHGJ zf$;Ef%zOR){eVS45C|4jVEj_(+hU9N*zCXM|1bRuE1vr;{gYRsfTN@1U+6=bL%wwa zGr<yKw`~w#^;Z}~KQ(=$4KYMbEqt$kZ;}wdrMi3dxAdVLj+~SLaDM-ML77v_UI8|B zi{D|m2*Sd`Ft3J&h5~jkzaQv-US9h)|FHIF1Hmu*WZ<_LZu!(<Yzv&<Q07q2p{~IT z%A870`v(lvnwNp0p&>YhjDb)|%{Tfgh@ZcK$nBf``Of}6&;GRzSVWA2r8P9Lj&1;K z+(JM?S`Khu_XVuT{r4ECzsE3y^!2_Rh}U*}qYY*6H$L}+{e^1)VvB>}nlLuE1;m{D ze~^Ji<X75{^A|AjgY459Ap9U5bN@W66(bWY1}JkHc|Bl@#1<HRKrmo+4%YG=BVc@U z3$y+}n%FfMv;G!)Za{zSdp-P_Ha7mj)@ff>L3m{cU^y!cpuWQk%3LV2?w1&#-a#6d z5L(c$#?t>P1NW!USKQo2#wKABI3-PjrFAsG@{OhWeGTa+^sfWqm`1?DCk&vjo#Gb) zl5dAGaTQh$uA?)+Wn>0yBIEwJAs#@#`g_{&9_xQWA0B(XC|mp%vwcq&dyl0L<2bR@ z9&pMw7>LBTe2eSgbGPOdY<GY3zaR$94~YMX_`c9rgx9l@e@-78Oa5FxM&e$0{hj{_ z>B9@-e<MCHl*1M>7D){&;8N7|FXiw(|3A~cP`m)5d)F{B$N1j}U+V8XFmd%)O27Y$ zjX$71Kz*59+6Ez2%Ro2wM;z(M_$MOc|2=KB(gpAeiPtAq(U`VyyfN_yBHQ0n{OdPR zA2bSK{N=d;=O*;eknjsMj%<KLL?!_hOJIC)8;q@PgBNY9AO_*JZe|N?An#!2(ZAv^ z*vGH@?Y~m|^^=S5e~drjxIo|Gckw5*YtXm*zs8?Gqxn_*4cBg1;2H}3DD?vOH<%dx zKZw6UF&+RY6xc$cgx63gnmH7Tqz{GKS&TyA!QzOd4`4z4hZnY8@xS`%L;8e$LmH44 zqzP%mJOxxrJ*0fgQ~Y3=kT3oR*QGL7GL<q{dX<7Fa)`_xBQncIN{4!(`y3)OM21Mg z+#}E6cZKdxGz#41U>n%>e*odX>Ov#mg;TxA-4el^fs_%=B6o1>qd#z{jRw!Yq=A68 z91z@*2SShn@8L7}oiXx`R*?td<GPI?B?I=MTI~7TJn?@8?hlPLOFXII8mC_9I*82w z4U>uh5Yt@(+UABZ^K*V<8LS|=l653Mu!+PYu)urx41Ndaa69sDTu%uw{S*jo$ObYl zgR1$iA;?^y{sZa%(^nUZJjoF{=15u4EA>Y5NzvfbL_1<vHj(%T4OSP|!2I|k80(w_ z9pyb>yn71s9L7`&V~t><EekA+G=SB)K_u3k#l%`0$aj?!9l)_R2I!SOhrG;d6uI4j zwEj<Ee`<`#MF8rqMxpzLdt(wpvmKG?2H0HN1OpAj;8T1p$Z*XA;kOgPt1A(hoJQ2$ zRIo6)gvl3Ghst1L=(6XmpfX4lG^H4TzH)CQH(!Q{Y2o-(O?Ci}#$<r#AsmlvB!(0C z3C4f*QN74R53!kJ*UDa?3laG(ZmweD&EA>;knE5Rf(_%qtIJ<8WAi_-4%CYVGsAOW zWu^y|zdZdd2Y}7LKwdr~djxf{T41UxAIX7ifhDBxlF=`~pv(siX(IDV|Gxr_G?K|S z*{M<FYJ%jg7VlQR0bgeOG5RnwGzZ?lECv4Bk-y9xVR`sF{8&C<UG{<vw7$IymZ!Tg zxttb6$1Ey?VP0!dqrlZfCi}(C|CA5d4$+sXCk+W;U}+L;u5W=a1?>Rp1s3C<>i+~k zmKUgJBaLxj8ySb8<tgBX=qkhjvHU0a5x(^y@2(ArU~+XH<7f3FdLC+&@Q<+n6aB$r z{<;1XD1ez4km&T<!dD&;EdNxO;JiWX@~AnYGf?i>3+9)@ZY2P3jn}|k)ff0)4ErN5 z|Bd`1FP~lug4uxzELqGrKwX0K;qT`3#SDy%%!YFn>iaqpo7GjWfJP*Tw6?qjl6^D4 zxnm-L<uE&VDChD&$6xMu1`O9lAvS3hEKUuB#mPa$&TfKMWIn(-4eipOY^xe#d!dai z9BIVN)%WR(;Hu&vxTZ7+o;sHUb~X;6tE&sFtgHadL0aIT;PG1?{!{rw>=Uh-V0&u= zO!qf~)}m<8S{MbU2U?LijmFp|Xj|d>@T<81*HyTFK>NOk@ITnM0gNvVWAb#0=UM<Q zr3Ns%X@nWqwY4>1W@d)r;i0U{FLmiZ!4LNqpxhz$xsfi=oFDcr&(&U<0M-^~F}BsC z3CSHJ7=N`+s~5Sxf$J(<o8Wr-%yANf9p>BQ&(;FU{UV6mtpUUiFIYP|IAZe8KkE|Q z3%-Be2_(m)g6y<N5O)6r$aOvOmo)(D`@eN&1ta&C@33QYq+fI7Xv`W1*J<d(e?JBq z`R<&EZVlRhj>fF3RUcM>y6D$@_1Ao1FA(R-1>|I`z|_?A8xPCN%NQQM>XJLKmT?4U zX!!s+@j*bbj}ox6vjY}pCWLoFKz(p0P!rk*Vr&?`@$s|HwB-Lfzx(A~FjyGx!}w9q z*Fb!)A&42v1Hz9L^rN6ZvxdZH4{nWqll}MkPAQ&Z3=a;7+#z=CI6z(6PqH7-(a?h% zH*R3^;@EM5@6621fb{fqprWDzj?qwpJF17kJI~X<)fueZzpuMLr6c<F)z5%f)e1eV zAb#B<Z&KuQ2J|DLFIHEz3UuZFnlH!l0mp&%s2G4eU@^ivFfb5QRaGH-TU!{ue)VT# zV*}*p=L1<;8K59`5_GgS{Z?nb#}4mdejVB)=<`9p6_I&{Vvz%>N}ek{^u?hMjC=*6 zU(W(n;jj61Eao5Uf9sNoiODw}uzB8J;r{vA<m4nUFfafz;zFQ2+4tLA{TcHQpWnR! zV;$8P{~{Lgy%Cv@D3m;+(=2wAg|P>;u?zFt!1><zFLmcf9{PY3cM;gThXNz_{{%ah zm)Y4_aQX6OASJ{N$`ZW)5f8o9Imp_uhKV0w45Xa*L`I{?<1vhzU|a!n?S^VY{|LVr zX9l3AI)>31ET;doZf|b~jEsyxOF;zGzYY9b9@>gyFgbdN6=FtWduL=WXT!K|etj8q zwypy;kw59qzrUk8sEEl4{z>2e#1EVco}Qk7frbhsy|M?5Ij{c~e-olZD|6$RIL-mF zLojwl^r#)irYoCk;6vf^KaxE>bF-U>=G*?;pK$)}yOfj^Ku3K9#J#lrd)&zU#m)t| zzQI`3`wNom&3FHT?A6S}_!`DQoo(xwHCIb=0Q{*)@}vVYQW~(jy81hKfBPKTQ$B7^ z@brNpXwD1$M+KgPTA7=`U=3``h5Nlzi0#>iIRY4GL;Ev1wh4v@Ho$QI?@LT%HnKKx z{4K_xUx4!*yH^PH4xYK9L-Z%)^((NpH21d!?$N?NAXd09td{?H4dRD+4)_c?mVo5y zH$ng82I%`kiB5h8n3!3AhWE$MP~Tx5AMS6AjEsDHH$FZd96NRlM8w8{{*^T_u#Uvk zzbWI${uZ*Gg25W{FZ|!@PwVhH(0VZp#2*d(vGCl=1-r?P0%!yO$p!aiyu7@?0fc7? zQAwb2@e&vs8v52WIXM}y2?zo1=K(;WbL6*0zjqw8t#16NKi|#Yf~Msk_DHb%bU)W; zt-pX><i{{R!8Z`Uxxv~QW@cs(@v#!fA$w+rWaNREm>3uw9K^JOx&(QkprZ$DPknya zTls#U1>P4ftbCilss*mi-`mfYp>-hS@bz5W&zOJye1!KZ#-D-ses@7#g*tP9kqv|u zRwHslgY?-Ypw!Zj;Xz&N;t#r%n3#y+;gnAhkZc|N3m-BF{?^s6c`&T~{C@p{d$lTF zL;q+D&fG2rho~7b{><<2!?~)buMa5C%7F7}T_AmM9kYK0c{pFyjM>wKJYdHG_7fW$ z3uq;zfk;K;U+`b*9>eVM!u1R0A=QfAoi&iWEA$^={%?L|8{9?q^nRB0?>--sa|SZ9 zasc`>zq{ah3{6De4+$#*<$@^;4{#ic5IulA9FkQ4qN1YTcz}C$Y+@2XsHo~M_#YtW zDCZF)1M`ns2xjO%eDA+O`|~<~_8;qznB5n^A*2efUAy*eE<=5SYg1ZU8ra<2#IObD zs<^l~h6nkK9#A+6=iqm`B&Pu6m6SkXVIeTTYXJ@`C<C#Y)*tXoBf1kZIghbFvE8MZ z{4ez1E@ioref6IMF}`VK=PEew_WS)_>{v)W9so(77C>W5C*TxO!1!X&pMiE}{}Bej z!gUTnea2pp2Mt75;9e}`;d@<@uW12{ckcrVWM0$g83O*dML%GN^A?^1tw#2zq5o|1 z={58}G5#}*0Wk4Pf!hYmrLH39Wo`zI{!xb@_V*1-V0{w}a*#bDjn`d(hF1|VFff1v zRE$8}sQ~a92LnnfdJq>Ehh+gXS0N9-(j`S?zKVTr0}@TWf58s%n;~ZaR*^A-c~S&B z62G`%;unY?8$Uun4*C&gZ7V>;@yGpUtlVXgy?7{hh`p?59q7b--Fv&>*9jQJuK|fi z#h5+8OVQK7Gaw4X6I^Gpejc2w7+n%k0t#7upm6Npx}@AW`b+Gx9mAk}X%&MF+8r3{ zejh(#cqnp5;`iqm{^0(kL*nFL#sI4`aL*pf9g7{iZ>t(Q4%EUXzu_N3_T3|6;{n@Q zVT^sp4g};uUQr1gzh)1V3a5Y2C8b~R@EF-+-Uk1U-@o5uhuGnz2=gaMZXf2bVICOz z4{$BU%Kc}Z`FYP1%LBHC@`v~b7B>KoV;G>IVE_pU30M|DQBe_~6jlNfnS($T*&BuP z0nTZ-K7G%FK63WCAMqz3rmy)E*9DmC`HK3-zsNqHxh9goDjID9+sN9JR=o%=cnku? zr-LB5@~=9B#rmrni+^x=8z`160QQGL7#?C`VlZbbpq-&rzYV0`O<?wURgibS*Cj2) z)@yc;g12)^7}=K~m>@Pp#^yhw{`V)$9t#rBz+4^7VXq-`xw3Nw)F5YImXR|Dxxdhv zUtx#Oe#Q^?qE9<T0$QQ-fK5me92Qpx0wI+@>`_A=;5aNJPFgKuYoNVZL*xi!+w1=z ze+W7Gn!j}&g*kti!^U24fBJgD%rE!rf5pSE@Jl0Wi&#oG5Q%HX=*{>0>)88?ACNOd z$bL8Wf*35S{#pJOI}*s6tdIEBi*5}`U<%1$!>fLH0~q`t@nbRmsfPG#roXOxkTzxy z0JD$rpY6q9_b*_3D1&umO!L~;fJy4V&-?#M?$~F)lK-D@!|$#lzZZCm`0#6pAMpMD z1(NSH#me@d*6Lpz2p|t|9H1`2`GA-Qj7{+_T?CquUw`v}#rt#ppWr`VG!I;n^C$zz zT!%FNx_@NyAMYPw`TVL&uA^{HL%Rg+7^G1>unuf;=72u(+Yj}Kzw+{T_+=5y8p!WE z%s(%Iib-S-7U}cr{$118Tz{e4D3UAxulMh;_+gEi(}-Py`FFTJz%?AM)5!KIW?sb9 zE&~_jw<kA}W`V}Pc!7Eb&&Nz4=TNSFTEy5HIRvwI`694E&Vhw>uVM6j6`88v_D_-g zIHUn%lE2$)`5xatx&Lwh`Z?w-0L-;Re+tTO5m}SrxtY$XO;Fyu4!V#UK8NvY$HEpU z8Q%bHNDa@`EFg9nK8J0gETG@=|K<Mm_xxeb4`9x-Am;}VpU<Qs@W=B5NFHou^B3m_ zko*$Nk-^vl#u~9mzSRWD!$MyS`ZI9<;dkrm_w@f)_t1ZWJ|HFs_QUy&7|dA>n4f`p z8Cc*w_WTCS`+YmVf%w3%kDq<9{}sl6(vKpNe}^%UDv}3A_FTW7pFwg0Fs}h~Gq7Op zk!Kja#-5)++Q8W3pV0WzJD5XC*n>*2hKGq@U5p$sg0&-ZehAjE6XXwa#t1oO^zRxu zcZ8fgLVg<sYvk8SeXvHX9kwoppON2AVQWYD89DWYt>MT2KQBi}{5w3w@bh<g`{3vA z_`&jt<@;xOVCD2pZpHtSBUY~84rw9cL|%4Rx*)x0*Wq0Vl|8aD5-J!l2p~cN<jIx0 zafV2RZy_eDMu=Rtga&RX6fH_tLR9Vko2g*y`)cK_6-5@-yzNUa<YI)+>o4Do5I%rI z=SUyHbc`p8(D}e_Ha$_D$4crRVmIjtadFf<B1GuJ?nSR2lyf}xJmhxKA{ytZh}CRO z%arNLqJU6okHwAS`gMU^!*9g<%9Gbw7TcBf%*QhxmSGE|{Yc3a&mMWkW1obITq)|X z93c?_DXQ38Wo^IG*&PNhq&rYba+dfUN~D5>RYYO9N>a>h1Tu7VS&m9WhnOlE!_N8= zYVJ5xFm?W|zwp@7dHrZKZhjkn{1nc8eXhaQ6L#uo(LL^NG4ztSghnX0Wl?32eOL3i zq;I1IE#G;!JFlEW!d;H4-n4z@Z9CwaAx9lVL7;=zch&RqYF3f%bKN6K0uoLdVOiWb zM#Q)eu6utLBM#%kb7mknAfdbGoglG1yLN-eS97H}f6KKMrN-IBsq0a%Y;sPi@esZ@ zncSt^@QlR>ygLC(3%pKi{v>{84n@@-Z>p%()IS=d-qb9q%i6yuY{c=kipJL_lEjrc zux%X{=G#Xo0-h_szi6e}c3R-9wt9P6f}GmtQz0({eFDkZJjRInh~(<MP@;Z<$NgPY zxEVju`fi;h)Dlim-B_-o_K6+jM(rJV$|lRb1E*j|*a^oAC<ElxRc8<1s}xMKyr@Ls z8J`gCc7_Fse1hU<@*Qu;aSv^vWC)%UrZ#pGv8c$QkK^~2IW{wEH$7#skqB{aMYVm( zH6L^-uC1WqrK}HiUO7&SgLEl|&oqoPr-@&tNQSTbPMDlim&u^;`EKODU7uWRRu3&l z?0u-byP&@XSQ2o5*-(kQ7p*iY7vAD88udhO!yWxdB@VTPt7k7asvhV<da3=|-5UrZ zx#OlY2QC;a;Gho4ITF-PU1nz@ouKf#11McKBpI|0Innms!QXtsAaiK1u;laZ)dS2- zRc|Gk8ipbzUV5u22<=io%cP_&?KHu^OT9Im!qRH`rQq>5I5!V-k5PC}Z!9XrTFubi z-{bfg;oMhbN4~U(E)Jbs#flU{#XYW=PmRP=T21dLJ?=HKfg?m>_!U+rbmZic30H>v zv?WZ(8HZl!NSGQO+@=0ZcsSD019hIL+&^-Elj7NYagtJF)Ee#noRt|CQvG9&?9V17 z=oTft!ZzX#HIj0R9}YLXBhGZd>Dfdrv+tybdGZ=@%E3@ktA;~Y*o5{3iw?%kNbI_e zVr;57meMg3cR_$C73aBLSFX8pMp=3ftqdKl$y9fth(R3L6&iDWBDcgA+|wm{Xi4jO zc+a>!MEZDi{;{-qdLL89(+lSe%$#s-a5yCkk}DMlE4(SDdz@VRxKS~5@s~p!UK3{2 z;bdjqC@Z|{@MVvgm(&Xq2BD-KwnO$Sw|l1R$EwZg04e(rP3d~jPNf94Gz*d?Ql{;q zhTzsM3Bvp%PgeW6QLCqo&Z}t3al9bSdaD_P_Ru@y@sQFhl3Mh(%r)=O;pE3EWSSlq z2Gn|}-&A!zQc)-ryxhC<`8;!Q6K_Yla!!RY%9M+lYy9-BVgvd<Wt*%~)>Y|9<R{g# z%T{swJGzE>rms-RNnT;+cN#qF&~GrqesjsngDzsp%<-9=?3K(Wp*`<;)q7C#HS!6k zl;rX2ck%!s!ds7dM5_-6H!w};f7(G~L!4d}N%5BNWe$mJ>WzV`C1gss@=hp<YLZ>0 z3~3yXWwoM==v2ABr#QDJN+jBioYa%nF_q1P`GC_+vTh=_Tld87izF3187s$^oDewr z2~FjidR;7<H9ek9E}Y&)Uc>K|Vse6hm3kvezT>s8ywkW#@o^I`LO03D*NU`s8|F*~ zJnf`;BFndm!|>*b@ZAc45p!H2IqhB2i^FDDCM4M|jLdu}tS+L@IaB?yW$e1!P?<0L zc;fVF9_t9XLyqy6byFfwyg!RSW_teITd|<N2L3vRluNt$HZ^7TT%z<yDOS3(-U7~B z(7qZfReFt=z`O%R`i^8sSt0Cp+X11sG#N&o8%OfO3pQAZA4`kunYcX7>P*WNNw?PQ z*hjIaq=?7Gk^lLQFSz)lM@o0EyQZx+@*5mDnjTNJE2&AfEKPA=t4>x^{gn_FebmPW zbLZZcYh|?0iBMa~CMOCnofkM5>JrfR#Oi49gE$?$vd@e4y#m&w!s4=fMb^FF9yrZL z`UP!As#{I}Jid@TVNf-!=$$uUq!*b>#JQ-1_sRKi58A;_WTbER%ba&Qcd2dIx1CiV z<e9XeV2UV~o-k1uReQXNM{R~WZXndFC3XENO5m!=k!6OC2s>NO2;9LbUXJ}r1&24@ z4Au`Hb!8vLC+4kt<nb`5)6cb8^v>!jk)bypOt+L)W@RYlYTLSa-HvAT5j=N2<9agd ztU)-@UR|*vU&H>?-HCTrKH6V?-7d<cv$~X6PHloZe*G9pw6DD+VbaFO=3OSv&z5yW z6?WFHJ#l_oZ%E@fGeI|Iq1YkWuMmEF>liNe;SY?7LO}%6!=Y51dkOD;5`QhGGmY~p zQIL?1qv!NCDp%+3-p<-n(i(-$=O5j5qZH&ny?sQnKw{_xfnMoKl#HmWq)VTXaSsVe zoO|u^Mx^O|RvVH%VdNY6FY9%BNT#C&bFMtRLHmhxWs8?|t1Q|z_Oo<l3fl1zvGQa6 zbty6G_Pri)6|}pJc1hbZ){WA9$hN3{e)(2+V~EOa()inR($oP(^@GI4QEUZyj|g{* zDwQ=_Z<9OSr11A_;m#9HTP&v%?`OPOYw~EMRF|}R`azjjsN>F^BJEMGQJyPR{Bd<P z=8bMMl5<{;0ttBJ&F91p8tA4zRUwm3H7g4p^^d$_EGb0hA)u7*Am`6r)NZNg=UGAN zn6)iVzC&_{Dh_ex8Ojh+oMdAw@y%R=JgHt~1)?*f*`jtlcuz{Jt&CeQ*$#Fxq-}G^ z9%`PCuOBwxGm;n~!@X4&`*FXL#0h66v8k4nOS(^}Mm772n?Hvgyd8s^>-T{?K$-2> z?JxD&i*JIqibe0c;H=&4WaZ8xn3h9Lv)Sc5R1yfeeFnclba{%0+OC!;uI~1el>t+w zN0YXS<fqxlx`waG1}=!xh=zjHmr@^`!W`)b^w+*j5na6L-2M79TY;NGY~!8ewWQ%w zsv9{v#xfhZn~JSdJYjOB(|d}2J%_C5qsL#p-`W+pZ+hV2V96!L&J%pnU&LR&-9NFv zNX%jJ&GhtHl%&@|!kG>CDEal0^m>Y;cN*PJiXWsT32nO(9@j&ZR>p0-%flgM>&f(} zLl(U>&gXD78LQQNJW~^t3YSk0LA356<F0uX)-2|SXCCaPt6~bOK+H*;;x^9m{4%L} ziuUok?mdoV1N#X=Ukmo{@7yn8y6Kaw<o5_-Pw$J9oK=>ybmXv=A4s^!LlWV0=RDr? zYzH^`qFh=p6dv0HMRun8@R{>BFDJTwKD!tfLq4(pNVw4QISDTl>&D>6v6LtV32Id6 zYsIoy4Kvcm$<YUy(4WzG4k4F!1&bPwCq7l@J$=vi?)%55G=xlVpbD#|XcEGQ$J02t zHJ8KQkF_spyKJ^*#XBUZirOt`#yv~k+5BE}`n)0+O3JN^Mu<DqNpV_;_HL&S=cvDK z`TJ|S3>6D&&cwPA)6=HSKHXKQD8oWh>9|}n5mj^!VaG?SioxX#4VlL#WD(R8szG7= z`7I`fTbuK0czP~O&i$9q5ecQ&;W|qumfCPA30l3;bt>?0y?ie^0JmcJ%iI?kUJu4Q zNANi2>xOpjP`*O)d?J4q@nOb#))dZo+J1^DeCxj&z7-nHL7ul7lNx&j#o(O5Z#%ii znZ9a3JluxQVG+giCSZqOiti?soVhlsfuOYYCH*ErgB$$^-^C+#Ls(Q|;|L+qpxp`n zICh;|i-)c{Co8s_F;z*8ubc|!-&hQmIcF_(P>rf^nP0AIEXC|`oYkz4t(q=@UC&<1 zT_oZMuh4vO-88l!(MNOF^GzrlP=t<LP?RFXW&WVKZ|9j!>&exMWWH<n*xAicDmljl zr3p34oHw_K8oUSJx%AIv-o55F(X2#u#VMnx$h=2g`-GA@u_Kvs@b2kmg|Ll%pTu4} zYo(u5s=})mc#l_QS&kT|kVz`s0ddEn4^E$-nP}T?MU@Bhllk+YUS=OJkSBcg$Z@h> zla})s52Yhw2(veC>sl|<dgRDEvTr&{>gUXesB@um!Z^r7U4%~TcXl|5&&uPpgI;{w zZ6|5perIG^5m_H_Hjt2*txe?-EV3Lo@7#BQkJO(V6@Phy_&EMkk+n1Jnls)#M3MDb z8`m_JrQb#~b!L(dZ~8k<2ymTKYd(W?zj1f$E+<_=iYWDK)Ky7>*uy2uq(>SlM@`YY z3qF|-NYj!!Elo5Q8P&d;^#<3<)2N=Ek4XsjeR0N<l+&Bn&(w``S8De9fYlS~>IQ8= zw^Cgpmyz4Uy-uqGTKCQ#V(Q*JzQntFY1uwFZDee-n1XQe>4=>qiqS%aYct<i-F5HB zVF5?k%P)0y&h4312oC5YxF6pfOE{l7pb;wSn&I#&;&v~+QgGG6YPV;?6i(M8(H+{g zJWAShL;7quSKH^)Lg@(=5^~ChORq6C-y!Fuqs1Sp{DA(PVq$q(u{c`5(H-d<x8$hK zus7n=oyy+8M+?1@etO6wLpj&{%$E~9xK=V;)8*Y^^@e65?Pz_{>Wq{2ow{V6{+H~Y zyzftbpiAe{cs4#z){bqa#wphmC*VzB*Ll<{$0k;zealQ6Su#$g9<~;*cRPgNyykJ< zW$a=672@muN-K4n_1c?d1J(yPb(bzsJ~nKiTGOGGprtQ7-|e&Xrabs8p+5&|KiA8U zD0*!oTz1_g%g-re?NfrEPTuRLolwrUp_a3*$@LTKd`f}(66Q29q^T6VwU3l-cke+r zV!_w>UK*$0@HP<*Nfdj(<n#$myBcQ|+qkEANcdq6qi@QH;DoX2BGEl#zP1HDYGv1f z<anjfp4*=}3e<4!wem!6&BY!(f`jXP;_x2P&bHY5y7N1tjbqV)TVdsovbg+iAvRLi zZU6Pshq$E&O6EmwTi-KTJDl{c<jP7N=U56=_L|@+_1$(QqH%R>X%pQa2=L~LI_l<# z_ODIux!3(Axvn)mf$N;I5kX&K4LUq*fIzI+GNdtEgXEqO2WbmaQTP!5msp;QTOs}l z?mRYl9~N#W_Sog?=$a}zl1fa{ZCYL#$qd)9G~CHjj*6P5iKurQP9&=LlrEI?s+CFV zt(!ofxxt0gptroKlR&BFGV^}<d^rN5o+XCW|0Lbb1adnK@5_E_%zg%}<tTFU12uS} z^xn4z<D};dBI(lN^VMgF5_^|bxEm;_Gsm}0y$B*7WGw~nW^kcxICa#B$MPoQ1zu!u ze4aSzp}cQ*-%6gl*JS<R6#nb-W>w1v=7Mo6F$%N$N$;6$5jdC-Ipf41k~Qo65`TcN z86{sO|Iky3-%FYYu~QGZLH$Cc(0;A`J4T{CuDM1<;=Tyi%<M<vjL_K~az(FwUUb!t zJYy?1BG6l)IrUNG14{^g2(lO@o>~tOJ9ta=z@1a-q!&d@^0FeIuSY08C0AR#aU%J+ z3llM^rd|5<*{4rCw4SOGi*%srcCm0J4as&V`|hNTm)wPGJC$=fA+G(SsmX)*!=K7b zs_89xkx*jE=moCuvj{HyV^S&psdAmdADB%Okq$(aOVmg?2Ja#EC3U2Xj9RbvP$%z< zvY~>&DIHJ3!hW9E{du7rMThUlwC}Wiz(PpP%2XSAyA>y(q@O@fMQUL``STQM%b*L( zx{}CDU!if4cXD*yS>~le`!N0tq3@nv9Q^9V9cga6&x>4rgtjg9%@=0m8kfx@84$YN ztN&7OVzy555Usr;q5dtM#j$6vu0&^1hPGuB-cJ**T4A%&qS2XQ<kfu?nlq}m=@i6g zA5PwC8W-N;Hm6yo#3ko`aQRVvyb1n8Aq}b$oW0vDcO#Ql4-b)%oJ-o~;SQD18NYrs zzbf~JhzK!#VNjZ2e7Q7L<Kj_nYS--+<{g1=m@gN<EYFd;BPh@?W+}aAcyHBlL6n?w zHn4GBRrjl`Y}FeW$kamH@MOLBFlv@lfB5FTmWL|E`4@%Dhox!-o;e8`>n|lPvo@2i zeO!HnEWCSXW6wXr`NVwI+nBMDafnbfE3AwjRfn>D@abf^K9Q*Hxs?Y`9c_z!U+(Pk z7}vx<cZ+G2*84W0Xg^7Jv-pMaI=?$oV$ZJ!Wi*@^rkN7dA$;^{HMn`4d4-zwgU4sh zh6H_%ThbPz4sVYX&Tsb}S@luf*yl!U-h635tJcc!)@iZ&Gz$>(?sAcEVIAEybBW0P zoVvH<nfm!>9TMh)tl}GP5LLw}GK8^>UaHwmL0+7@9y{OS%fO^Qo_uStV-I%-RXPbP zukPE~K1x2-buSkthK9(>bA4J=;;2CW2gWK4(w=2A)FO=u$1W-e&r^tz*7=wm*(9e< zYA%advE)4!Y0xT1zP(Q6VSQ4vQg|}FmY;C!jFQ9`0<tyxsDv>hzAC&hlvEwRlUZYC z5>1y05}kJiK8-OKy{T5QQW|>lq`JM_TO~h(urol~cL+FUI3u5C97V17a7vQnA97&X zxP|5p<GT4=`<@450xF!XqnwegJ=-Km+aK3T_s(0Q3Jy|%QlF>0Jj(``*D@KD3l2UG z8Vxg;RSa9*u`+hIHgfAGfx+cby8H^)IpZ4tLt5=iMyR<NqBck6^(K3tlqUyhXuL;0 z2QhGPkV;BQ^4;k}rD$_$8_AM0_XOBdDh$v_KDw0Myz#PBWmwaHMof9;HsuoUj9pmX zuH*?Oxm_A`97~7rC5ds(N+wq3Pthm#5#E(!=Qt+2vv;M!6%|k|sJD0OJ-$r$maVqf z+>Y}Xjx#|UlWV-JT(I|DwN&{1)rnnI4!lnW1cp*5pAH1G=2lE;@6{sN!SOIVYhiV) z0dI44wqkv8G~KkD|D<l=(IdR35>{3`JZ3$fJSOtGjV!8%=1MfPcMQqs$1nIFOp-!3 z&mZsurg1pYJA~<kH}@-5`Kw7B|J0CK$-%_e=(`*DxLrD9W%fk&YK~FeN7|R43Hs{x zO)9NQN?f|r%;_-buM|2eA0x-S%N`JvJFtzK_8Q}#bj6hkw8J$roY33l>^R;Od#&ur zp8I`HJ6QxyxP+beXKyR8;U(C6Mtj(<qQur<Du<1!g1m*v!Mw+I&h&$E6-gMAHIMaX zKMwbUf_~DoCA?jGEcAHsIE;){IC0)*4k1~Gl1FbtMoe?2>W}-P^GXKh$!~`|8Yp^Y zUTx#$cs;5{$myM-Zz!qrS&NarG7@2f>_{c1G`$ksrHSV1p~W3VZ8`NR!&OBi*$bDY z9yA>HrC2<1*hDq+NG~Iw^NkZGvKgHhqqT{Pzw~YrDCzN^zrem0W;4i}ySP4n_f+4= zL&Ho%<~D&=WBj8cRlK){X*dlCt!<oX^?LFj5bjO6Po95$c2C@y73K!R;Dx%(_eBw1 z?e)f5#x@N2iadv_-jX{yo~pQhy#2cC7j}Z;uzFj0!T^f3&his<HQuM{-6yy|U0!C6 ztIeJ&&|%Qi{b*}}YtbUZ3hKkf*-UvkIrpU&ZrplY$IVZ+^TL6PT|L`cqbrwFw@@OI zdlpg^@S_j2uPYTzj3Hx0-Eav_e$C`?m&t7&=vGWTavq;lC-JBdKbVW&QRJ{&Tjv#< z_+~0wDp}fYn$Kt5%@}<hR;JoDn2TPdXe-1v@LNaMOz_~0zT1weH$HXoOA8)%o`qi) zg%gRYwSaExt8^SI4wTDPPS$8%I$R|DbIH4!I#EOIJGEKa65jo&m9Xujw8e$1*?|`J zkqbr3Eth$g$!N?rCS>f>uN%Fe{irg0Dzjmlx81P+VO;gfoyvXmVa8=8q?8xa2>W&? z*NnJ{1`%UoKm7Y4jI9w;CnR<@58hH$J1{s>x1UNSB~fqj3i+&7727N~ZVqL&656bA z{iEUVPSfcf0b*GTd3s)*x&}9fc~yKD4@iig_P>2kNkCIYS*-qsilL9?aGKe*mpG*H zpRz>cBx(6u>;m&XZ}l1?xgE3Wv}4R|oFtN+{&%W1Eg3khYGpHdw>-H(kXfOTe_=+Z zLhQg^qAUU4Czf1Ac3t+WluJ99ss@Y7nhIy0&aLWKR492cr_t4R-@@a7OB!iujcyAa zddC{`T8eZ+?UYn|cyBV*KHkTdM{T@NI}zEJtJ&MsY)NIC^_ng$u2GIO``DyOty6I? z_If4UXI)hhVI~oAeLofIgz}Cul^yB5l1GwAjEbfuAPdbLqQ|}3;KL=%-<)vAVq4Al z$+ZKpV}HDTwgRi<hOt3HrSvX(BQ=3m>h^wekISD@Xs%r$CG0pekcys?Gc98FxNGR_ zF?=P1E#jQHb^rtJ_EjVesxh9SeoCQIW<r**BV!1P=Ut$F6o&;FvE;iJ;)+}O)lMEt zT`K5{i8ZVs>0;(w?YY^ux4r4tDh4K+J(L~2kGs$vdp=v0n~10n$Cz2z&<M$u3>U&N zwb02YdQTnqRy@4SMg4RSD%w{`40tnYvStxYNOPFrqeT2|s2OcEF7uP;Ddk!Ud1TM; z#C!0bY|UUrNOm~%ti|yj`_97g$)fd<BevVit;a)`XO*8O?$NZ|R9Mko<67MjzIH2_ zR5zJX^}?~C{l@vIr@8^YFTU)g^&}$`&`BML-fJ;rwsrW6o;LA2L8cllNBY^js7NWV zQqA2t0k%?vC7y@4ri2z9Hm7s$uXbB22pL~FL0V^h)&JQ&%N$_O#2r@etmSms2B*fZ z5dV6`{<@3&2dn*2_{=9?JR~zAExSk@zO}{^m$_F<fY?Sg_qvYX3ci##wO72V!fXkp zU+<fUOVw}AT0nt0zUCWwNrbO!S5JI5aEYRq3elyT>eAsXrwhg(2semYHaM0A9S^&v z*YEBqNubvlDyvOI$W@8HW^S9l>r0q;$%q--A!l*s8Z9M8ui~+W$kW%W$Y0hG(yeVw zrcy<0nH6nk%MR~!G=Fqtpy8mtk4f&!PBRamBTsY7o*))y{zJXM^Vfkj>K09I*Qp(G zBDLt3OFQrAZZNlJ5^UIx#yDJ64oF8yc4}Wct4GS*6Ieu2M8grxS4JHb6~*D_(8iIH zG}BcRd`?qky;s(w%;uEb3E#WCIlbf$ySaT2plcW}3v%q;Lx0x8&&@YJ(z?t96=Qgu zcQk&i^O?m81^4xX%&)nayDqI)<2;g?H|)?!TAQRNsO@>Iuye|csp1*c)5@0$y~Fe_ zeTk`scik{H#Ly2U3z-MZ8D6X8>1v+ll{7-jxzXz;l`&YhowpUMzb<CTX>Gp86fcZo zd{Zy!)PxK7D7%YRh6SU<f!^j%Rbia|cv8c<d7GRlkwl95j;U@dZd@9Nt<x&1s-J~I z`7K#`Y-R=XmUp6zjEv-m7453gRkOFaK)2hIeZB|gf*mDyHY5Hl{wvBC%2nGW71vS6 zP3^hgI2M-r*u-flrd*IzKkZ?iJm8Zo&r(L%mAWN0WrQ!ZKD1vxfTLt;(Wog#e{HUx zXVroi>Hq%XXWq}O4zv8~7uLOe4{qT%6jLm0A#oGOb*6IGCSFGMK_l;K6ruA&TEZ76 zn~#u@R%`DrxIenf?Qo}<K=5O(Rs0&}BC<%bwCjp}gWkd)DRcuAJNfK3?&Yz9t@XwB zDqyw0l1D)Qv)Nvj1f@%9PtNlo$z){L<)tqjzCAw;ai5X55z17TU60^FuiRp}kP|8Q zb*6UXUL{@WK~F)PR|`iPCL|MA@r6QjF5De~;?X>O>bzF&9lD<TgL^WogqI#{vKFzX zu76h6$qlhN)#r3cfN^O|Nv?fY<rx&3%G(OpX{b~uo=~D`!dBUxans&8j(yn2lJV%f zqkZc33@s;j9#0m0VwAWVWG7@fq2@_>+Br{<`XKuiH#+erBIF9OOAiY)P2}w>kYQkl z!*KO%)$UgFN*?!zzL8(}jQGauD59Q<IF_N@)Hs4Omf813oD*Z08NtW7!<ysZek5u8 zv$^qEz1}vQ^M1W<4TM|f&kK&qXj>3B*`L*4S<f<Rno8N)eemRSH8fpabIBL$Ah`?5 zAyX?s5m|jFQkL}Zmh43KCJcFH%3HPQeV88}H@UEj4)-96<H&ObkvTOaoi1iyy?6Ur zMww?q9Q(74(jr=C;wrwv?Y;54Bu)<dR}X7t7!WZ<^F3IIs$6ZIt&_^^po`NjTbgxf z>=+Cvtj%9IcXdQJ>*kB71rq!06}DmjdUQhHN-s(D;ZFye!<8~rogZ(gR}{4e9lK6g zA2u44e8cS0oexRsFP2bD;j(%|>#0;NN1M0S_u0Lgx-jZvVL6q4v`-m5T<t&Tr>Rp? z<;ObTWf4>782t+GWh-?>mhQ74s#afS)uRzxsYU4bQ45Mk3>}88M+1TB{Zj-8E$LvT zkr!b_a?vk6_xYYdNzm4)39;Q0sNIKyLadsY&Gt$Eq;q;t$@<jMQBlWGId?}d-@-qh zD)=m(c$ntw-D9h358{pv>rS4oB0=#h96U2@n|_)|;Qa{|St_19{D4Bn_!vTd@dVp= z?;4WsBSj_Z1BrJQuZ-P&U=fwK6Hy2WQTLM2&%B9SyB^~Tqt^zhhI#2<R?clL)(w7o z!C>f*cVy)TL-++IjoJ58cdNj|Q_{>1hy8EMx>MT#=Hh3;>urUL$5&{WN&_vTnb^2! zBVLn`?{X!t%HFHIr-*h0O;x%TId8UdoKnL5KCUyrwysgSUUg$6V+?gr^Oa;rA^gU6 zfy0v9-ignhv~=7SUfRA;oRQN1h>H@DkzRRLRH9crx!=K{cFS%fpzuO6;#=NoX33u` z-Muy*>meO~slZM1#*~ZbnNW!)vMSJR-Fy0m{buTVdzBd}v;DRpg>X{7r*_ksv&cUx z{q-z>&8`}>jx9MZwHeK`!c!k2EGlFw&H3>x+fCh`;1Y6<>oL9Sd-PG+yRW`ES>-CH za?I==y;t$Bh6moDYKR#=N49J1LdlV!_a@{Bz0FK4%RI_KNj%n>b4nwLLpxV3TuFun zbl+vwOgVE|?!4Uk3B`~p(qS5b`)L=4X@)p*bT6&1(lCA4Utl%pwMx>Ts=e-0M3H>q z1I?iaW4ueKjr{i{qwH!kjNEd|Os57qPnumS5OgI!omhPwNzB(o-Be-;oZ~7!LH<@O zs_u@LmTG5R_j68Mfhx1AX<pZc{Tw&&<xf9YFz`HlT{(<$|0}5EJTaQi3w7E7k4JUe zUH8YzKP>Q>>d|zZshj<n>cGb<*uCvbaej90Nc@3DN++RkA5Q$NZ5Osv8obLjQ8=WM zOZYFWz!52-4~RnEObyPy{Fp|w!k3Ixk_?Z4m?LpZDyPWWtXk#$Auq>wUL|>feC83| zeh%{k<&9i`%a3c(L1_4lQ0U#m1do<28LO)H+#f6u*IIl!SekZm>}`8}yyEF$Lb7^} z3H_Mo@*Dv*M{i3#V&+PSRX!Hk)S0{at|+?81fMDT{-77{Tp3BsOA!|GT}fK$&f_aV zkKP_dIez(~hIkMk6IMQ_-=DuqeE7_#q=ljtc{X{6y7ekyp=I(B_L>1x)m_Mv*WVV| z_BN-OefpyK16cz9D}$e;12}zEgzz}*ZuroM92-P$lZ(b3sOm?ndMrfx93iK6Zy@wM z!n=2IG^p^+)q9(4!RrcdubG~G{`$3tFS#KB@6$E(=4`ZI(G51+bser)R&XOemcuN4 zU1gx5p@CBH;Tay24i^ULXMJ=1Wm-9=R6Ta9+Ab~u7tW=$s^)VI5X#B1p3secZ*T;K zr^?Qgb$ZK=GQNrE{j=&RUAnMTXPo+Y*`1{0)xywEXkKr+!cS~xPOVzIUp7bxC)C08 z{XORbUof*W!;8EB#D%Q9g;N(ZT#~nDJ2ltO?`}!+a~NQ*@mE6Ymp$p9YR?QfW3(^i z{s7S#v!0_wL_}llnI{Zu-?(SqsC&H}kun;0+G6Ix%zVfGM}?@@3k>pSah=~cM|npO z$vEyy*oAZMfIrHYll1|zr~dgUIm$P*tAugXXe#fDr?-RPjfFt@<7JJ}=ci+~q-J<< z_aB!}%j+yMsN9#o(qYU&DPJdpM-{epeTQ-2WBv*Sfye8;L8)2-79;XC0jKeBaBvJe z-Q3)YUvnFC+zA^`^PlzCjTbl-wq(Zs?qPq8S}-j^$27W*<uD3Y7LS$`XI`Hzmq6V< zV&afvmkL|Y70Z46;^h~8NS$}=KG^q|Lg$W5FJjD$TarrJ(yf@O99*N%`^&Ka$5`Wj z)}2hk#v|ZfsqD$;O6ZH3hUO=@4&dV;-oeeLm<W15zwvY<i{UrB;?7(5YrH#XG?4h# zK<88B@q3%pcpUmRD#w_PouaJ3=XLZs<Ux2dHS}>|@!Ng&{D<+P@0(3CcQG}+wiVJZ z#V4lZC=S2Ip{d_`=@q-ShZEjTgnlaxU+Z-2(yN72SMF90SzPNDJHI=CiF}v*>ob)@ znI;asS#fMO`t_rtu|j3Oi+-C7$8+h<Ck=o2Tu?fT?h7${8g_z8>z(T$UxF{napR;e znS|oiT3yXF*6Mq=Vi6J@-E7ups$a3aR72Y<mUn2cUo;htF6Mi(Q1_a<dgA?K?f3UY z@7*iEdaUAtmVIoo4iW~MS2hzFA76h%N*dTT8WJSFdVxZ1s(2#G>ZWQ+NnAnz4xd#4 zF;{jFT19AMEHZ%W#<Q2w21gJY;>bUC@tMT|P^Sl+&3~ubjXuW(R2HkiXWrg6wfCN+ z&MnETGv?X_G1>1GE;slFDGuG`eJkEx=_vW4$HHz^2Tz1Hutl1kNr@qVDpCF|%T0Ew z>s1eS5xlrM^uDP+FxPe;8JUwGt7d7dKNVL$OPX&{uWI_*hWIEeIHCLI13l3&Sm`vI z9|<zMyK3~TzTSg(QjKNB{7qzif}$vS`^BuQ&PO<|SrEQkeKJdhYzzV;2Ql}d867WV zqkOla#iK6KU`x_3eebNn?2U$yL_Yh1fo*d!!h>v=T-w^&<S6|tk(ADx_${s{ysmvi z+!&(P!boP|h*^F~cPu$0<AH8F-Rq1}yH)VAh7ato>hhL<9(nv4jiXA|>q3^wy0z7F z!p&Y{y*ou}q<7-><!#}KSiBI_Qlv{&dzzXPh`ze_@EJlun}ujO>m9F7={~dH-Uw7j zYvy(8u0LqmqH(YnQ&}Ia3B1OO1QZO?EFlHb(z3_Pt@th-*c3vcKDfvnL5aDQlFsWs zC^|<Va-5JP<M1fk29oFd#5hVMU!Cv9X(IX9-OH=oU)TO35ktl^#Oqd8S>LqsF0Ub5 z(X<Z<beQLC>Ti-7rs4Mu%z7PUx4F_kQ0^i9RN-*CV&PGDsq&ntXZ;r=_CJjM*ydor zXUF1kQ7_tToG^awtkyPB;*jEZM_7`CZf@A#N1|QAT~|kC@9ntn>+mYrFSKGBjDecE zEhJAf)AbICgi&itO^OQkJu~_#{73eR$DXb5<Jo$J^Zde1T9vN$;jKCpsf^C-ZVf3~ zN6TJH$CU|YCGp{|*LQiivUQzHBnmg#wcp>79Dj$)s*xm8WWOEO8ieMZ+>F}(7p)6@ zo5L|Tki-YcAx@V(Md}#E&}RxkEKmAb$Z;PE=ySeqd7wnbzibo}fNWRk+c#cg^zA`T z>Fhv-zxZ;Vn~xQJD@8+IbJ*QrI5Dli&1+ZaZcH*wv()Y6jm~V7`^(Lmh_+wtB&<2y zP%~}{+U9Q$J0RikyUiheBok#Q9%CbX8IP=gDr@!GlM@1zs0d2GN2ta&O3Gs>M-5gU z0tU(Z26|K}wQt+i%TOoV><&b@w+o*=dx-7QoVH)eZECwEWr6LiN+xAg@iX!DwQGu! z3^zU?4h`}@OeprD2~OPl*myn0`3)}K5an4<v)Sr~n`Z@3D7UNQEKUN&VMc^qJSeqe zHJySlaNg$fx9Ti!Ejy%N^5%BE%VNt;=-kd7#adc*GOF2qY_%O{t1$1XL@YzgR#Koa z8{6lZs?b-jo`j3LzV^EFX3prEgr>FExug7hHsv@_5(F)VRb%eqhwgNuJ`w7N%u3#& zL?twdXg>c;9Uhdqa)(;&y@zf<h@ee`?Eb<?6-}q>_-FXZ>?){=W3<5`9O<O>3R|ly zcSjV@pD*hxc?9K!Xhfsrd0lVmP@U6O(@h77-(OLB=2iR&m5oD6_!>87k0X=V!kiL3 z8>cyMzqCDOYJg*SGX6yRM4#o$P=~paofoLx?ewB4xE|sbO;=gEb%t`z@V!dOy}Iy@ zmN0<VEJWNFB<J*SCT`*B#6M0iYnQ%ND;0Y>bhTK<O_w}VjV3y0!mfvZ2krB&{@sgD zpA^3UbxjNCpaFTEca@hNypHfnx$dn|+U5UP-4;pQH_T?1t!<~R=WcBFtD|W&UTdP? zS&Uw-4-@UOTPRjRqffP#QiPs~Us~!zGI#9+j*hgx=KD}xCMYJqu3<ubUIJA8aQe>C znIzuyMUt-f%O{k@%h~iaXdB00ym{lfJlV?CIdE~&8?AO}eY7srY?T`z35#QX4tl*E z0dw)jEW*V%P>z>h@;tgsKx<i1t?%+&kGWE*h^eq-*ap4fuo&-Q-tSD?S5Bdu<kHYa z6LTW0Axtq;NGqq-mf1Lj+o39VP%FDCe<3zHy8mr!K)DIq)!H{_?;{x(#%^?-u<29= z5;{C&(~TM6a4^CXArw0SmgS$*Hr))!vk8~GKoS<V(8zS|QDXVwH#PBNXyJuV45kO> z%AEa7v=W=?5hX@4-$`?x71K1!?n^aAclyQhQrEroOGkVil!`joCs%sCbSh%63GgR2 zFx}c6LCdj6#LcG(Z*GoQ#3A(5nZP%d!MOJK^-YLxojEK3wiZ|KBMz<bM$@2Hh^fvx z1=}Tq)g;+o`%O0JK2-)fY-zQItb0-3Yb|+6fAW*Ro#jP#!ngQhgqhjaVX61LIQumA zqLkHZd@XKRy{=qoDzLFW;r-#P)&S95(z>+0ZB0_=sh5>$Hyh}eX6sVYZxSIM(8qJL z`PVeocdlAbbAxTA1gD#NlNV`SacCnb8I<G#3&l{8OQeo0WS|JBl<V3`NZ{|=7hu`Z zeNad-j6x$dKregGU=0|&)np^V8A!aFf*o<jU`mUU=XQY0LTkxdy4Q3^ELWH>m2uf1 zj?(i9T$C)Hh)AxpBmQ+#H*Xr%TJ6eHt^IQP<ylJ8ojKN<-3|w9nsAb-#e0QaJ|8+@ zMy%0N0~c4B+O5>p)JOBz7|V38>=Pq@UfI4sqezi3)5=wZlv&9`hM6v!{&^yD{@IE1 z!h1faa~4aN0xSJm#YqGW22|@FnczzhKbS>w-D>vnfesB3l4Gr@q1qMvHY>L)xxpmf zL?0KgnmuZ6-gvK6+g``Z`+3jV@Vb){Iz^qGSDmZK+WFS*)#a9MzL%Ov>U1ad{o+c7 zc!86raeZ+aC^6yJS&8-NE;Jp|QReBH_$}oBRn++Ca*JYZZkD7`fC#hS8C2ojN*4W9 ztF}0*t-}ik_E_@Pc5#@XUh@oB`%E#X@e)W9AF?8}(*+c)NRJbVsU4QLGYvocXrP@e zIcmN9dRvS3_=@^Gu$gr#!y`O^l3|~-GkBFe$?(wok(uYFNm5$w6(#d+nxjWO5r0yn z^d<{MNSl+ebwJ^1W@OlrAOXqNAR)sXl6jJ4b@13^DJsojFTLf7!-@n`Ov8-?jw**) z97!vgd-fq`^zpCLCKT};De*q`=u_Jvm+r@`k_YyPT)FaQapwU2obT}>n#hIK>CV=a zYwJiBaK2<GO@KN&9B;5oW1Z*)1MSj9i7y+woaGlvO?TKDG`h>XqlC|*Dw#u?-723P zC?vF5(8kZPAsVhg{&C_eBDdkkD9c`%k}e<Z144<~K~z@bm6U=`Lqi5zNIdS7@&7uy z%BVP+B|5lUaQCpdOK^wa7WjfY1cJM}dmy-bf(3VXhX6r>Ymne>`zG(4-GAFNJ>4}` zUH8_l1#L?)m8Ex_z5DYbr!N?kh(vu`KJEqFRY}K^_D^^m>te%75WrGe&_duSLzE~? zK5$n?imTm^ql9&*==3rPK*CrcuoBSYkbLOJwNOPh4Gq{2&>Ci6!%lDdgD4jm&)7hx zeUGNg1R_pY%`%ln+q~1z?5!Zp9@YH7V!TD1{0Nt;(!;()b#-5zViEFh#Wc>XWZ;x) z+kZp%(u}}EE{GXaG+e?3#(u>O6sN`>Dkv1MyaR;8ern8FWCVw>>Lq(|mGU9RwZFut zKgh)rnP@*mU{S_1YL+fFs(MHd{WL&r6(>d%-@gIW4DBD0Ij91~-pPL0JdKlR)sLt2 zzc0|Rd<Aj6<wn&z8A0nvfa~`9bh%l-l_QN$ui!je6Vu1!8s7bMH7cH5sLtre|2eVU zk)$tUXE_hh5OQv0WcWlDAB8o~gLTEdd^JdR^)uM-!Emo8umL4MP$C~4j>;PY*ma(Z z|Dtm6fRk9=bA32RzxeM*^2*9?m*x7DF5NXk*nbdU<^5wYOcx+m^kLoIhvRA%7AJU< zhM#x9?HP!~p`8%DW9s(0F4Vq!S1>cmDDe(vVx4$CilhR`c%(h*(yl%KofCnn`bE__ z2fwtYmi6UTpX6MgPc7D5sd7KKjFX~g3my=`Yl`TNTdQ{tYEyxLKk7Rg$!BaM5h56c z<J(ME#7}GVfeM)7^z_A6Jf^7MHHxVIBBfMA;k4LW`yA0=rRT(?3=IeGJ=kx1TlV>f zHQCW+6S~f*o=OjCbyYV{8YNFe{K%C}E4F&W7pT)}HLo@>#^C^oR<e{-#XYH?Buwi; zX_72V5>rTd5<YC>g?IYIViJe}8Dx8RA4Iym7wTQ8v<Z?KRAm(uqL&Xu3`v3wUpCyf zBbl(&iv`>d-&PZ*Y<)x8*{awSOSSR>v_ciALggQ8NjedZ^%au%UlkKH{AoG6@TK0? z)zxK-VPjeSEPnrG3_2fEqeHycos~szV@}3pAUH`z(s}sAEQ?GX23x|Bb9l*TgN82t zaJ!}kbxGG-&nYjd^gKN13qxB^286gi{iOSc37lM&8Bs(ZAfmf$N9xC%WR<ie(tfMH z%m4Y6gU&ig9GNxIJ~SZiLz_Q$b7i~wbhoJ`U7T#lT-k#HpHI?TUfvHH4?Z0{@YA<G z!%?)($|{DbT8lo$B!DC;f+WId4ohP-9?jm;2rlD%gsLOf)SC6K!{a&_AzqJnlRPQF zW-UZQ?v=|2s@=j33T-c?Erx1CqF_ECQSeJqbv=|yH9vH}j)ZBk_9`)ko<5&ssJe)B zj%UVozhSN2L&%FRHw+TJ)a;PAd=N|}rQg4=LY8D}hRvv@dmHL&yPeuKASbhnqE-B^ za!7%f%sv8(_8~B9PJoK&^{pfWNNpLS6kU+POC&1sFhwIy<ZzHhxI+(DgIYOY<$P6Y zhg^}LI%mivs9>*HDng4mdsR`WBfo~u_$A>4|B}FGrXv?}M_;V=a#xm?>sMeeUHru9 z(dS6Ee$3nCoB@<z35C~4+X*u4tVI@XWr|y*cr~d_%n|`3X2L>JD(yd_#VAYW&6AYa zQ+pM7zJr4gpzFg01{o?88MZjP!v~+PJb{!Ec9gF9yiY*%yf6Pc9)&%y5|J?l42(q_ zgkgb)n8meA_}kAemm~TSQ~{!JYK11ME6yeRb>|XgXJ{~o?LZjQK3{JYqR1-1gN4rP zMQwexKiT3GGOc(?gE5CYbIfsYh4sCX0ej*Q1~0`ZjUXRF^s>|j!dQ@!13FSoPLlSx zLKT*@>~=}OH74@gd8>BCU^G5+wip%G;4w-%1J6vFB3pNMZKIqc0T9{_HI0{CaH}4m ziuRmVO<rRjyPi%@wd~?)A{@W)hAl<e;Q&&iC*EgiWW&WG27ckz=<`;OfQ`2Z1aCt1 zA3^P|eFG{gw-@s{$Q+GKRO%YZ%I)01GxeDP(Y*Zmge5iQXrZ|<_N0IU<O+3T(s^z# z=PdmGQCyunlkwoRLxXmG_uzvFMkDRHH!KwAPg!6>HaSMR&JZR^p|k)dm;g9S#@8B- zuy&46Py>0gH!ZuX8S4wjJ<|gv`N~;*UNwk90Gq1uHgZBY12)ctP8oMIT@0fc2hl4x zz-5$ex`#NyXu*%Fg#m|6qq7<IM-X4MEM>bWLG*hlj+f}V53D#{8I17}Q<$ilo;zxb z9S|;-Sq(eL_|3yvk<HQV^!L&g1^{$W{02}poVv|GFE%nVQvPo&2*!+#j#}m&-v~Zm zr5(r?%Z56710_lZA{XnLSv-MGxYz)-^iK~~je`QE@pzfrPyb;JC=nQ_7M9kCeNpm+ z0nS03Evt%tbI|)&wL#3kT-k5ENs1r+{@jHje#8q~5}UZMdcNvcTA}=4ON*Ri&;4+F zDTjAY%E_8J;d?=p<`wP7zA|-#(rgBfN_R6zSacSbTs+x7@{!3zI(K}f(e`3HhCNfc z=h8TW;r#IrBer?&$5AF>c@)ZbPob>sf6yTn6u_XwP9D@Y$(X(3f?0+k1C+j5jF;*= zpQ<#}P$CZVaXg&NsfrC|aDOSQFcjEQf9)+|@Tt6n6L%%@xkU=B5KiU^6&VuS-~_(E zS?EsD810v$0FM~H6_GGNV6!d1WJA<(@7~^?=ikOfs_6ATrY11GXd-X(>iGXPjL65B z(aB3vj<kX=r<|ejFhtOaaA(O#bII=PpJ*pq{Xhz9RuDuufD!=e7WO#OM`tb<jRLmX z&$?VLBZVV)ZGVB_v=n)}Ps4AAQ0(AzM=<012D7L@$9@AFN=CGC_$2hL>&!q4`<ecx zT4H`jx7K{Ar^@m<<=k#P9kju0R`y=S2oEY%TR}H(@MW8=w^C(D7~}r0-V(#m`;h+1 zK46%E(^~8MFtZpS9d_?z0JQ1)h8GbbzdW6GZ`cCTNnXh`6@l!>H5*b@pnc+}Uh>=i zLf31ym(fZ&#5QH$H(?C;jk(6*IbY0F03IGmd(*5BKygcHtOVZa?1c|{pak`au^qKx zi<jEb1$he8c9Q-e{u~k@D;uu!P!%ZmP!aq)fWMK3c_=r1Te9nVSBVi)utM$;;GO_; zUoPcML7&J&yQnx_lzkv7-YEcbA|Nj|4CZyw@DO}`oxnzK{Azr~8YqgR<LAY^v-kK~ zTgFKm@`fdaDch2-)cb)z541J{oH|0yr4VM#Wmc(5%AxD^olC(c2e+S?jLcfKF#s=_ z?!h>HaK#Gu{2Q8}I7JQ;L=zKAHJ5t5pnoame-?iJl7Q#5@POX4OuDaGL5dT3FBdj_ z3e6Y1_>G7<T4+jmiRFxscA;#I?qx2ZIkm90{C9d}MBLoGI9YE0l|{D!8H8(iE1uaq z&SCdib@l1LZcOXMlaLVxN;7S*Dj!0$6x6?KrF{_Ct1t!--5(8=QJUm=OMiad*63B= z?-56S#-%hHZ{;v--f&XN7QhKX!V2#-_U3x8qB2xxF+TI%kmq%A<myUkRdwwTHg?q5 znrt;*j(O@iEqqoSjJSu{r88&2QqR$~^eNkZ4?vZ#=)?9-Cv@@e-PChx!K^ih<EFUp z^{kxbxIR4tgW1F7UgBEr1MW7>_iP-Hj&tSx{`4+qxML8@Mz&0u1d!<Q=D38*?y4n3 z9E<n7`h<-o<I7r_U9ko3jpN=JzU#>nP7EPCAM@21bIoeev+VaTILIjHGIVnH>?JfR zwG3t<`iJ8VfUKKBH|C~;=5%biTgk|nm60$I*h68^va64fddWaXw`A~eb$R&%%uo~J z$^QZJx{WqrB0jh2Ux@`>A*n1MH6$M5wD4(Xepn7NX_dD8=ZRjTYkAo9m-hFIaUEj0 zmhTpcb_IirN1ZeP1g!}M-$Po=nMrdox>@y_z>DMJ;&OVP8w-Op8U>-ue_C3hAg!9O zQv;gooYEkPB!~T~07&2y!qV1OmXX2)Ve?du9=zs_BxRSu0ELl_mQP%F;_Rjv%!K!c zq&@}Q>Dnnif+#4?F|-o785`@Q{<3>w&bz7njb_7`4WF0a%$2F$MHbT>9v)h+G%)Ui z;DLLm>MrWMCno}LF3G@JH3MnTin_%4PC2xU&`lu6YCWqhPGbIWQf1!~qi5LQXT8Ko zo(8M!4O8~!HEeLMU$A0zUHL@DM)|X>78AZ~EKv}Mh_={y*TNxT{;MXF2km2_Vn0S} zB&1*c;4d+<U%8Ow$%N#Jp}VXeZLSS`=C5rbL9v`>BpbhsVsr#9(bL!D<)g+*JlgS( zAp)*$%!=?mRb()t82a3riOdtvr2<ad@NaN&XTdDJd6duh`QGUtxo7>miM7f8>#IFH zk9EjB4%!ys;`5Z%hc)C-1g2KW02t9V+LTwwjs6Ni^n)a^3(vLj9{o~4GaTv0KU#4r z;~WD0Ri&51b(Qrm4E?)UuJ;jR8jGkTql~O9qWA4dRA?xCrEa5wGk5X`UgXh*piTD! z{jS6UlW@(LY`zzH*K)VG8+jU9g5sE3zEa7>*VXZ49^jvD6f&q<*-O?jbbtU)CyMxy zw`&r^Y7=wJAygw8#3(RwKoNwbB&_9R=7&Rs_w0rpk)z2BMNT_I@=8hr;TWXpWkh33 z;gL`dj4cC01SRtie5P?Yo+FcSfq4mJH)i+OJLiq)mZxH{mBi5bI#Whs%T(|<9`hg9 zaLt+VTN(h^E)sXFv!xqxl-a{lM=Z(|dqQ)({-cgg%7+d*c<BTRk$=^9`t6qP8CLw# z>I1zYNJ$`HB}d@}e{pdk|Neb1SS6TohB^jlo!zi)i^+#LDEU>tvhc#PuCC%*Ycr5> z1^Hd6vfH$-2H0R{9G0hdsw<2Z$L?x|_PE}T|Nd7&jy2$Jg{i=zLoM_PGN5rdi6*xV z=2wKVDFb)dr$!j0@h|bp49$|ZiPdNB{Gr%9ppPdPbnOAl17pE`DN-+zRfALt`In^7 z2nmsbl_&jT(B}~FJ={F&hVli(TG{IdqZeS^iSH(dP@!!L{qD-UqloLDiMVG^CLe7J z5-Gc9(rrf-b%tSg|2**Z;o!Wn>i#cX1re)=NSmg&nPg;fRu3OPSVRAa&OkL+Y%clo z-E0JE87SZ4CW}h=99dXW;nmh8R9*SZ*$bUCMA!?vfB56D<m69?P9t<ah9@d28W|HK z<?AbKYHEs&j~|wph<*R`)IU9qg%|=u5{C!|X$T{ugrOmYv$M0~#kP#Og+)Pe@xXU~ zm_TIMU_Az!!r#EX^s+y$>r#=EXFn{hqrfrZZCetK^+*0USbUq~d9~JOj+QTC3Kv`H z1J^bG**OshMr9dc5W+9uV;81;IbL{{;)(W6U(WqcKl&tX-MNjh$7SB?jK>hf#@enp z=Fz{ITzUn4$0kj%8@jy`DwwUut<&ZUPN0;e@P4x(NY~52^{d(r%clWz-7~TqzO&sE z7PU2yP>?5Bqc``Z9u?DUua}+90unYR7qPUZT6$2wvJ+jq+IIbe$w|C^1>RF!q53~R zI99Va8Gmt%D8*|c9sxP&f*eP=JtROZ><z1FW`S*y3i1a;+M1KM3cO#NeYqmIny6{o zI-*I~<0Kr%;}a3i2W$2Ea>r#7QQ+-t!yQL;ux=tG*}(kMwOHR`j!X1S<GVTk7k}@6 z(&nF%DQpxAb~jA9w=FInF$3pcW5*DsOn1(0E{OFR1*4X*-DNj7i_6qIENKU5j@Oh7 zJ*B*J4sVf|Lzr4#G$4Cje^&lDx!PR|Ol?f`oyI&}oPDJoVXmr724FWxE|3+h6B3cy z`aa}WSOWmb_P@RW4AB9WO<@^A4&?8yykSwCaDdIa+`t;i@KAxSqHfzktHi;PCnQv+ zJ8Gk=+vyw&>YXQC{<dp}TOd$Y!<qhw)S6-~X_-PDB5uxAes^I(SVyp~C^}_$m2h|| z+I+d8njQdoW5XlUESodaW(i9JM+3m7lq(iAJ9h`7P@hMYNA+0##eVhVD$EO@+={B9 z%9kJ=fxWjh_c4iMpz=^x&9@6Viu^W|c5|07hn8r>=C>jx0VP`d#Ow0cVW9AcJmt$_ z=!{jdc^zu}rt_B5JgS8b5~_EXkV3!%c^h;5yFTYM3^BdP3T;xS1)H5i%QY%cx{O-0 zrO|7l&)61iJNRydxic!u;z8|rdAI?fx>A=UcmpHTXnh|#+*9UF=3BIrA8Uu4(fzXK zZCg8!YmGw)1G{($AN=As)4;cJlBeg5b6|hIib$`?LJYU~c5_W>WyOje*-K5KRNGp! zWA%}{`gW}OOk$mZATA?jEb`#M>B%nR!A`<<rnknOO7|v!2z-}jY#i($Ah8dRh)6?4 z1>oS|ctR7<?w@G5JLWAM58`?UQX8=;Cl3ZIMFjD!F4MiBw<WGB%@Ew0y_<G;E(E+o z4I0o_(^hP9Z1?GMWL=$|i$V1Gn~%e(&cgHRtzKtyB0fZes8oVdQ27se&>vN5JbK{$ zIzds(|CxYX5%J){3|-is6CT4-bNW)UV@$cSG5lv(rwRtb&3+$$#oYS4^7hpjyVcJI zMO$`|A~z$i@%P!Fx8-R^WUCLm)40xUoJ0_IgDpuvYxm!5bKz-LNPKw{KXiG!_P<A1 z>d-d|q86hDpo|@q0k^Jb4J=4HUe2Xr4$`@><vH6N*{@@Wf#*pA#W-;bL~Py)+<2Ry zFFH1-j-pU1Hhc;*G>zwt`->e`6$Xo1FjY{`nOoG1eqm{ys8?+Ljshnx4>cdDko%82 z+vmRA9!>f&{dLc#QTP7oYT@HSkjH)vOLO;klQ<klcR)Q*BZ%+j;VqSd%(K@i62++0 zcXH)P%a^1+CJ^~ASL$J4X{B+axHZ(BUM&4dxFFl{X|QRxQ%m#S*twtYZ5CMNjV^k> z3HMvD1>?-V+hgB@t-6cMdXWbal{jyOyrT`ltK=jv4EwQ`w_eP+<o}cX$seR)DOtCc z<}dp#+=~{crz*NHNY%Z`UEbr5J}ZfznGyr##~;QpU}&(?d|K!2w%z$Y9)!qQu*&}m z_EtD)>8VYSJ=`b~sxm3P;Ez}UyM4eD6OW=Q{37OAa?j29?+>QQ8G0bgYFl}2JFy-= z%*`|NYaL?=k+3I+vop~m<7AId|8&Lk*O&@cq-Vc9&lXOo$94_cq1s`w!>9%-)5wUt z-jGEy4AG6}BO5kHGbF)aqgUrWav(NQU?k@mEE&Ff@j0$}`s}>~M9DmTa(ui$Um|4U z?KhqXorg6v9bL=@2W{LgvR+ZZv2#}#(;PZQ+vYpJbLfljJz<;-0{}VN@&)-{W*PDD zy7O|UJE_Zkf6xc#Ssf4<&kA$koh{g#UM>&CkzRltjw2}yxUfFksN+GUjs5B|b2o(F z{^@n86c~09A!B|J+24YES<Gyfua1>1icm{uSl2IKG!GRdOg7ud;DNDUC=jSE`#>K} z*3cp!9hr|`5HmkB;-tBy<#taH+@D`nS-XdUWfRY!;HZ4jkShi5SapBf8AoWLT}VBn z7S1H7OaAjmG+4P(N?<9#f;Qf8V~F<gp`7hdyXGZs=>*)-HZ5KZU~b~HvjL{H<fFdb z8%hKkF;dLlgtLx$vMq<}{yODu8iA#2kz2RpUj^WIsn#rF^q^zW$H3sBLhx%XS>ian ztGzm!^OOOU#*NKge=~Y}QsZ8NO9G4C{ab6t-{HA7Hn>a!m_!zOISHrET{7MIKLcOi z$rF&Ed)>&VI9L&galBt5t)aOuF+@f~lTuPb_kUf!mie~5ZOUTMh6l`a`8^5Ye-yFU z=hyfk0?<xPG0b#%DbL4l##|TW|L0>)f~rLp<fKK$^L@u=ylyPB*Is6^**D<X)3m#^ z3Yq%LC=ly50aml7y=f0o?G)r#WeL2!_KF!Y)AFaS(ruLV_ZPiA<u!Q!0Z-=n;UI6R z(U!2y?HKW^!k!a%zz2RH@G2E9&a{7~jRG1s2dbc>Lv)&dATavBf3GhxRoE+UoJJpr zQ^?tY7T9XN;dj9R2Dsie`^G!O{u(>QDGBV*&IKsN9zPdYBEzEBG;!h#0RMy~+Euy* zX2bDp#0v+5?qr>0<-`<`a#`maH{Bm|Cp|VOAvB1~djFSjfVe^vi_phaH}QH&;0xgs zBZLi~OinUxn3{0uqivK@V8DTUJ`-<4*%Yj$`{`cNR^+`k5o~)_w^B-CVj##koGjJC zE!JekBQvwI@@Bbg<T%`Wi3CD_4B;YU-AbvLymR%Q6S{__{&!*|&m49xxkCit7R+w8 z-a~%<;1<H!?3^{wei>chU~uOJfEhNnLnE)8j;YZ6_>^o}qwqJ%q9n4HVeGgWKzD>L zEmf@ue1I4>wm4e^OCd>0RVMZBo?$uPHU?ySIm4{tLq#|Y9OCB5>zsghD(%cR-{~Ka zRa^vCV@hPHczOtxZ6jy}dI*EX#l<&i39$*vrC-w38XOF9Z)`#(e{5nZ?zfhJ>5unE zZ~he1;XhLq>*Qko!XCecmlzQ5*oG1)*;UpvuiNCE0<rJkk5Y^;$KRh5SZjB}c|2V% zks$lMSY!=**&n00*8IX*5DGQvJuQLEDQJt=3q<4*-u3+Sh2;v$H&KF+IBTCLZJ)%w zECoF1G*QXC!w>7NB!m7kUIdNsUn><Hn0_zw05M+5*6c=vzk?S>Sf<cAy$^A}2by}I zZj>R2NjDQ??N1YDG9-$3@Fx<r`-uJ`?~sgB?%F0JYYlYj#@RmxNudKkv8zHJS|G7o z5x4dE-0UZ{<DBFl7xsJnZ*bHw%-(EBC6pSRk-?B$Og(>qvm${BDes?_E8{+Ugab;J z62GL2E~=Y3rNaQ?7|!UWcoVCNVc*Fr#YB@op3G>+L%qv`FG-V7xagXX!nP8+!;JT; zY_m??r_KiX{)N1-ry7BdJTVpafyQl@&l1tL&Yk|)0&DQLj>RxN|Ac+zkwL<ley{ry zClk*4tv|-0`aQ3E6Mrn|=B=aIb4g;5Y@2VH0`PaoyV<CAvMp|~ShvJ)DFu94Lm1^4 zA;`o6mr;4n<a|T|OJFmsrRu{h2uFzA?OEl5K!&ZRWAb}+LAYC%^(i|!sgz#NgW6t@ zy$MzWplMzNHr#T4O^)9-Ax*gk6GHLqnu0aks3;8x5u^Z6?#}laPrSK)7gDn1Y03uz z8g;hNkL^>1!W%bZpS+xuofR9GTm`4A?e;;%zN%bVKh=@ffJbOVXk6_vFtLdT$Km=% zI7cIeAtcyq_9OezkJ}MEyz-N@riU?!gIq38r+_Ad&2iH~sn%+u!w3e+s)NkXI)vce z0=t8Y#qeeru;&2a3HC`M3reI@V7x*Cz4nhsN2WzKMl2bfwX&Ho!o^MBt}(X1f6z%P z-w6|kF;$mz5NIh;EHJKpl0nM``&$`n9efCY^Sy(+9Ir8%Od6db`P}{W?NQ4r8@u6Y zKIf95nR+qev+rj?u>H=KPtf*D$^dU^!Z)%|O%R)n1)Wa}uyHYBNtiRVLaSLoXm=I< zED877dqZ)7mZ@j4^o|k2N0t|M#s3h!p@FkeLRUIn`%RPCu?=+lGn+pO@|VVFeQGz6 z{og&(OWSnH#M|tyP2QOjV>u2XrJIc($_ONl3uVl)9{F~dXhvvjFd`aT|Mn96n*SFr zkXiH3au#&84Kgs6Y#HuNP7>lMYvpx8gNvMNYvXrQ&T7@w-|hQeL?Xzni;n7(ud|?0 zpOTO!BN*<7JRVCD-xM%RD@y<Z8SQA@xzDLNEVJ;vv((nBti9WJ9a_qUpYTIg3cfgf zwj33B5_xUCB(1sUHSN))bbaia0cAkqCBy(gH229Ol`2w%vByo+`TEhlQs}nv!*~!M zyJ#@Uq$#WawBo{c(n`VoIrO*CReAXo50;n_tJ+CB3#x(|w%VwT&o);bJ*T^AVUo3} zV8#^PZT6|?VFn$o`H7T})#o%NhQr(m*HZ4ewdK;HQ1k3-bK6;KQ&R$K9ax&k!jmj2 zJhgeh11$RF9Z2g3JT-)y?EbC1Csw4cr}jJlji=Z3uqc(rHJ3|^uJR{JgGJPzw2pHA z_OnZt)CNN>s6bEn#5TK(6IO7wPX1VGNE#m^xsMrFW}LZ5YxZs>Puc#V#kPxwH&3@= zQhdT}?X(O|+#ORuKcU;Bk~hL5n4?N)tAFFZa;4v41Dg<A5Ogvqj7!b98S1QQ%g!dT zE|Ce-@MOlZczQCT1ti9e-u=#r>`=mFc?$<k&zjg@HTQKDyvHmUrE*AvM)!L^KLeo> z=#_p<?e}mDrAN-Ik^q2O7wy4VLh-YG&ZBfkKnT;po#{WwCnwZq2VI#z^Nta}y)*us zh&{I&UOE0RgW|8FURGz`c9H7w#$Uo&Jl`7QPqTWMSbPdCaRBgnWaS|f`S@lZAy3F? zl-Yvx<|Ct#thKMeIDgICo2FRk0nDbwc2Qs>aqWq|4|zQe89VU?_sl3I=1Xj5li0Bx zP2s$e!wB2Yz1MfzEnfiuZ@1&(ELgZy2VT&d)U(8u_8?oH3S7O_>mJFvJpFj1@|~ET z7^^q<oBcI9#aD9^8UHE8Z@~WTyy?(rQ#Vq9%D~^hm(ZSdAfx!4;v@tU7&9A8b6LJV z4O3B-wTSf+GWTu3i5R7FsVlXZzCV@coC~If+YPmyq9vC;YRd05=Tu;*!h-bOMj5xV zk+jr*d3hhMnadE#Ec8!NPnZ-8+1SUuI9}+Yg=RTbm3dSe{KF%$DO25Nd6!^fMc=-$ zSE94g=213UFsqMO)E_G6$}k8r3-Ns@v#9sFAM#{*dywjPxa{$;qcd$*e|Kz4g&zE9 z=<hzOsDdGY*ir=mC;qL^*0*qn!)mJ~u7X61ZmDxK2Fe-(Zt3Wvm<hyq<dV+XB!wtd z3zL{>*dA7Ii-2_WXtza`z1F>N6Va}03<K56p52!+q9QM;{=WrH#6x}1oTH<&NnB$c zZ9!7atF?pXso<JDs2%@LTai#@oK_PV9W_r5Kso$33*#+qt;<fvYYv^@@yg*RH)Y*R zPwr*-&7p79!U0w!%s&gsMb}BUeT}$f<eJphv`f2_93`aMkH2N}U&|oG(b}^E06qKH zypFvmmv!7Ye1(FF71Ir4tl_L%oL$n<lpYh?6n%WfL`rU`Dc{x{?WY>M5@@j122rvM zP>QIxlp+$tkV^OF@a$f16Z=Dzk(#SHbIz}~FL9xW>Z^}hx1^LpBIiWgIIzHvr@LWN zXDF9NgmKG<plT%y<rA$&f0c;FAYv02x3ARgZ>XJ2=&Z`NaIFifN)es{tsc>oTw#!F z)9+`44?nlFhNYAPNFG72SncSSCN~u+TAjOU1K%Ra`i&<TM^?UdpYI9maQ?ebNp$t9 z+hI*q5GkI1=a*rNhU@Htjt4W-kYwa0X+hp5E~3axd?^JL!MBvSe;Zks>}dJph!o#` z2jK6C9$qmngk7FK6VQboRgZhnuXs<@U7b&Vvw697HrS93{URD-x2(z?GdwXljPIH9 zZ}&?&#Lk9e49||6RS?{A*4<x1I>{VXBi_1iOKGZ)wK_-^Ez7&wkkxa|ab(82&Nq6+ zVk_~$AYbxcY~E;kSw4JDeH*@WJdp8<9jxYkOYTk{5P#|~XV<&e>}Pk>rM%%cx07up zA_#9kp1UBXb&f8`j}#G!(iX0#NkRYiPbSWE?=K<oy;HN4ZlClnw#ECAID%T2(j+~{ zgCC2+m%lhMv)vuA29X1}?<@vt`Do+S#z)5W+;y|OnlBNiT>sRS-IL(d7R+zpnd85V zM>24#cs77ug7u?YJ)~a+L6iKGm71)5w9!=IfN)tn8vC$)z01)Y6Vtkwq|e{xG;azl zVFSQY_P+jfMc`B^&Ydav%$a8vBJzYunX^&={TzT?029~oyh@X>bka^j0ovR2UqjqA zs~?0gG30inM}(7gDU^xWsi$=hJQQMb7NeX;3aSNhl0hg|QCWnlQ{h74o#20l3Jwi7 zp3(wuLrh0w9e)`R4hP>S>Fkmh*0zV=F&h=v>Ujv9@h857yxj7VrgiRlzKPD_q=pAJ zH@bZ1S7#TxFx17Ic+k}f<YPWg{Ior#omq4v4)!z9{(h&UcC)49${U+?IKD`?o;|Tm zxsUEM8Ggs))o!X)p?*liIg#+e#q_@<66MhDV~ysjCi~mPj;XEiHxaD+(%1;op*iTx z|8@I+_I;AeLZJnuKCdNvR75@-GLo?!*z!HrQEjp9GpufXnGSaNY4}^=X87y8ziwD# z{bGsV@m?tsL6Z0H4wD+M8#NIz=uAf0_DB@^xyeUoyzwuzt$ch-C4Mp1WHw8aa=b#> z75vmZR4e@t?*`jmx`cyJ7yuw^<0H96!#QQo`B}RT^$34($@{xxg3ggaZn)Xd(rE7^ z1>1Le?$M|FY-tHj^ysp1%z1hd0r%%lT9br`BQI+QODATyu;k=_6ty+rn<rv7hdxmg z$x-vRw^haZEkNHZCM2Kg(KwK@-gbLCZ~Y-SBEx!H44~J#O^Y1M%-1VyrSzM9K37Vm zt2U9nKUbYhnsNUg<`SW*8BiSmD_Pn4c6OON-EUlfU##3A#{6pC#!yIKjOmJl1do_g zf+dq;XnVl%XDNLA3QgtNcT=NDO0xAeC}JmUfKK9v>zY{8sM8B`Ni?9R>B|CRa7Unq zV$NS$QJ$|d+?V=o>Ynt7-cO%cYRXy*bHQg_QEjGK8Cf*Azm~UW?$B$-$Xu{Ic+H9U zW=;H1+ccY>PEOntHz(O*VuQSqK_HoUHj;1}UIdyDT%%0(XV(6QC+%BX_Z?c*y;Fg$ zvDQ{nTtfhmmbP2Vx{D0{8#sqgX&E|cVX|#g8WtPp5I89)ZmY~~$2-}u&@iJrr=+Ua zEM+U`KE;#zd{5vD$BG%Zw#+}WbLKl(W_9gg$VA1r)R)Z|G!cbquA+qPQW%1KO`PRf zKXht?IZxnH*O-DM{9`&~#dt04al2GGYxMxxDkU8cmSdm^>(@Zk=&P{fo%~}IhJvYo zA32>IYtN>+bV2=6C7f%nUH839b;xPymA>_9VSDTGF&RS9=txS+e_!h7GDO8j521Ac zrB-9zjy0UcK^sxawU;R;aXNu1wdg>?JvQ2VoY#rya|TA5z<kcO<?i=(PdK7N^)V~) zMYPBAOJThSat|3bIc}2^t9kF~{~37uBgL$zHlwT-gle8WGiy7IoBu6ty_0$4u57IM z1_Cozxe3aJ6tO<DlDo2X^9lzsUV;C<laWBk3b3b)bYFOy&~Q5+SI!<Zr_j(nInCxj zCo^|NH1q@&uow2THVEu&6r&u(g^>A(b)m;FCN`wYOvH@R368WDzA?O>HL=^BJ`mls z-if$gW{YiTHw>~9CCK%E-lw^X-vOOs6=<HFyX$lqc4*N)j=dYSY@P&H+ja6eb=Z_U zk*<T|^q+Ob81xk0{Z#8aj5m8U@Tv}{f_SY}eq*4VW)wWg{OJ8Q*$@a{>SAyxAYZQD zwA8siFuSCE=PX)ZwyI=$ua9oy>e0nO60ElPajJIc1&qk%#xuNF);RC-(Zd-oxjiUc z-$ziy>i}$K<ELLeAQr2!eHIJSe#+oFXRCT&)4b{X$q7jq@1wxwnJqtlj{g2@`rYg$ z@!HE@Hn1B8bNlDjM7_!y|3$i9W<V$Z$B!B8AH}9$OB-Otn-2mho+l*e!mSdCa(iRX z(P4AWS+eEPm#VUD#3bGH7#Hj;t}$EqxHL9fG@d6OO;)m!xBi<}?||h%4+{%J>>k`> z=1jy|-8_2zsv(VJ*w2fz$VK~^qPF)v+q8ru|4C-tV|DVp8^wXv6V6fl_w4Vt&vua` z5=H8EXUkbl<32k^<Tbz_bH(@TZ&E&MCH6yJ)?yKHHDRqdSk3w7B(1nv1rP!#%XU&% zgV%$ucwBYnmOe}_U*TsT3vPLycG^qBz3L5|f0nqNdMV-=3GHJBFfXsyJKnh`4a1-6 z2&9>9BKM}s7s9?te<P4n-UD9<TZ(&1dF=j#OhZEc>#eTOk@eqiMGt+SNZKk6k8FuU zYHNdU>#R$y-g^J3uDC!AOn%-@Uf609rGWj2#pJ~@%tt&C`Z$QaPpDjOgif6b31&@# zf0BK(NgCb#ZfOs;ASx#}=;|8X)!8IJ<m#8D;8Q01i+y2H^DH%zK^m2_q#FDElIP*Y z?`Zv2Gl5U%s6EIyIE|ovl@NKU@q7%MYC|ZB(m;)2#1?bGCeQ>3TmZ`ug!)-R@KeN9 zkkV((5rQ0&iGhKkOgg~kj)>@U*sMoP)bLYmDP+MN=GeHoUF-c3LbS}M?nxuv4%Kf_ z872JMo(Mf*&zGAoz1kIa_%ycgbzhO%*xKo7GV?JZA&)r=Hf-yzPqt=eg&Zj0j3Bjt zLwKD`n`)&0qfR`;heN`dg%?F|Ujh~AO7Kt-j{#=DtY?4CwlEIy$pa@9Wwj7bVn>9b zS^5wDQpgA!#@z3KysI`i-qsF*5FKDBy{{8X_xYqVhBJ{_k}a`-tja=E0$U<wI}tgc zFaLE{jQ6o<_zTplVG6lZKj?ky`D#?(opywtl1%}Zbq0+Mr+m1^m>XY<eQ4woI4B>J zNJg|a>Qna}qgWUCV3YTQ3>7aYen;NzBhQMa9CFh8UYQW&C44O!GMS53n465+4`US5 zS=pbOPos4J;lRGmu(x7*gDjlyGv8z|B=!w%mvetL?MOxulrBe9AxY8tlqncA>bW{R zY{>c1<wOLf2JjT<7WND{N2p-!E!PsxB#0QnQ=1j1Q|N=oM-7D}0V$Wby++iQYKZeC znbCbcGX2gLn$d>Rm4#YZjuge3QAdETM5fwzV&#fv(m1yu|9$QR)^mzcFD@wB?@3|R U(2xRcuq!t3UPeW_TGBZ9f3W%PlK=n! literal 33530 zcmeFZ2Ur!!);7AyAV`*=L_t770Tn?cqhv{nfQsY{l9S{l5(ET9KynU(A_9^(ISWdV zoO6zwv^RabnZq2%qchHY=lh@g-23<Q6xH2y)q1OH)mp3GDuBVzV3;ssVi=e+z>F|q zFbNn8#=!8~b0+vc4}8bP^{?l1Fxb6Q;0NFZeUFrc!4COhFgEZR{1kli+j}sBiGbz) zx360zW{mnxo?+30Z$@$^$_}9f-jC`vdxguE8K3<#`FE@B^s)y_5RJK=K!$ArP~cYy zbmi#-tqD@VP{Rx0&2YhvO0Av2kLrNRep=}R-g=e+k@wS%(p!&Gpfl?MQ2m_sD0O70 z0UfLT!1r}XRv9v+4U{7sjhBI{ycr-?FZ(~r*N0yL=6Z^O;l_L*cdTUR+qUR7dxoYb zt^tYyvw*t9-0yW9%ResLTbc-T6~zG411$j5AII&89?Tgsf4F#5{<sb}h@&u|3g~`o za3uG*EL47=Ivarc^tgQXcp1vuZWVZ9y8L_cvRwgY$F>2)>J%{6_7NCqD)>E(wH5== zxcs|(Das~!1u%ZS^n0>NUIs=Mk-+E<3UFE21gz#Zeos%p=Wolu>dzU{2wwmMTxX7w zq|YqyrVRo3lx_nqojbsr`8_~+autvqUpY#8GwTrkkz@I~%^o3fRjYp}`!IC_a4y^i ztlJTQB7Ex)btJ8B0+5a!mzSw9p-&wy-!_e1I+6>Oy_2y1dwGe9&EM;=0o##2UV(u0 z^te2f-+^1}w6F96E=Ai%Wxp>E)nNs;>C?(r0MfN@%O2lDb)=7!Z)bLH0hVvKerx~d z9T4j_kTik-(niY>KP!7&2h<j*KcGI%9xp{fV+-jAq+^ht9)I`W$^ifdTO)$O#&BRT zI0g*nf%fMK`Ud(IDg%{;><k1-1Wb_qfi4fo@ce)1lKo&z0;T^GO%krs#FeTrR*|eU zNs_EI?pLa{KG1A(1E2)mgYO5VDvgsR%8XU{vaRs`TbNY9x+E)%oo-iKEco`s0q})3 zU}<+1`2JejTLY>W+5x}bcmVu%NwUJkMee=9iT?=>$ufiMGF7HSVFMWeRR6-rGEkq= z4rDtO0Wq4HKyT#`XanB@wJ$CKZOQV$P?ayRG5Z-<-dhJE1~LJ#?1)sEiNHU>0QTdf z2Mtg5y4D7P#jzD2->3X{|8eX`8q+&~(YoN@{m8LD>CAcvY|eKBJ?q23!v^Pli3$^) zzk>nnI}OkepccV??x`3AqBJu8LpFrrXYwH&H6iT4bVuq@zZtZ6AO0!^sZt|8sNIlk z=qh<p`$O4(B_G1jlW%%d2Q+q2Km65LKsqiBHy!-4HUNBlw+;9@t^z9ydq5uOuaEou z+x*Yk-;t&Q>}@Rp<L#xu@_5hDSU~#lXF4fSZtM`+p9YK$9RPPl=8pWXjqcJ<G5k#a zvFzc7cSnA`yEqouSzkQTNoZdDNEf7v%yDGl=JQa$yIHRM?(-qP|1%6flK;JIC@z2! z<maJz0nN=H*$2r|V`cB2*TBfY!5?Hp@_&Zmd-*?;eT)IIws2%0ARG04AAmM3u5!Kw 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 diff --git a/extras/AudioPluginHost/Builds/VisualStudio2019/resources.rc b/extras/AudioPluginHost/Builds/VisualStudio2019/resources.rc index 8af2d396..9a16db85 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2019/resources.rc +++ b/extras/AudioPluginHost/Builds/VisualStudio2019/resources.rc @@ -1,3 +1,5 @@ +#pragma code_page(65001) + #ifdef JUCE_USER_DEFINED_RC_FILE #include JUCE_USER_DEFINED_RC_FILE #else @@ -13,8 +15,8 @@ BEGIN BEGIN BLOCK "040904E4" BEGIN - VALUE "CompanyName", "ROLI Ltd.\0" - VALUE "LegalCopyright", "ROLI Ltd.\0" + VALUE "CompanyName", "Raw Material Software Limited\0" + VALUE "LegalCopyright", "Raw Material Software Limited\0" VALUE "FileDescription", "AudioPluginHost\0" VALUE "FileVersion", "1.0.0\0" VALUE "ProductName", "AudioPluginHost\0" diff --git a/extras/AudioPluginHost/Builds/iOS/App.entitlements b/extras/AudioPluginHost/Builds/iOS/App.entitlements deleted file mode 100644 index 6631ffa6..00000000 --- a/extras/AudioPluginHost/Builds/iOS/App.entitlements +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> -</dict> -</plist> diff --git a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost.xcodeproj/project.pbxproj b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost.xcodeproj/project.pbxproj index 9cfd7dea..bdebe197 100644 --- a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost.xcodeproj/project.pbxproj +++ b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost.xcodeproj/project.pbxproj @@ -21,10 +21,6 @@ isa = PBXBuildFile; fileRef = 942A0F04EFB8D0B2FF9780BA; }; - AF42316D915057E930A5624E = { - isa = PBXBuildFile; - fileRef = A4B568E26157FC282214976F; - }; E3CB85BA817BC9E3942A8AB0 = { isa = PBXBuildFile; fileRef = 9F9B445E6755CAA19E4344ED; @@ -41,14 +37,14 @@ isa = PBXBuildFile; fileRef = CFFA8E9A7820C5A27B4393C9; }; - 3470F40DA5D68EC217872906 = { - isa = PBXBuildFile; - fileRef = 31D55A751C790CB81F58DDB7; - }; E092A70431B046BF1F50A482 = { isa = PBXBuildFile; fileRef = 5AF0CA7CDFCA90B4DE1F55C3; }; + C81D59C798F9F1F1A549FF07 = { + isa = PBXBuildFile; + fileRef = 7D924E83DABA5B54205C52F4; + }; 92EE84159C7027A137F06204 = { isa = PBXBuildFile; fileRef = 66643EDF46AE8C5B7956B91D; @@ -57,10 +53,6 @@ isa = PBXBuildFile; fileRef = 03FA420AACDD03D50AA16E4A; }; - 7DE81C004B0FBC563040CC5F = { - isa = PBXBuildFile; - fileRef = B1CD9599EB12D77E8AF9241D; - }; 2AB9A26C9359C40CA0A937ED = { isa = PBXBuildFile; fileRef = D0026F0A29B486D87E92BB8B; @@ -73,6 +65,14 @@ isa = PBXBuildFile; fileRef = F9EDC54DFBCF3A63E0AA5D73; }; + 4DB15177DDC357F4503F88CF = { + isa = PBXBuildFile; + fileRef = B457EE687507BF1DEEA7581F; + }; + FE22E1AF24FA9ED43E983B81 = { + isa = PBXBuildFile; + fileRef = 5F0ADA39C70C892758A941F6; + }; 59F4F23BFFDAB414B4801F85 = { isa = PBXBuildFile; fileRef = 29E0972229FB44D969035B4E; @@ -145,6 +145,10 @@ isa = PBXBuildFile; fileRef = 5EF1D381F42AA8764597F189; }; + A5F0B3B7175766C8AF1D6C3E = { + isa = PBXBuildFile; + fileRef = 36689CA4EFC2AF183A0848AE; + }; 7DE202DC1D876F49266D9E7D = { isa = PBXBuildFile; fileRef = 8290D7BAC160B3A56B66891A; @@ -165,10 +169,6 @@ isa = PBXBuildFile; fileRef = 37E4D5C341406B7072120006; }; - 84BAFE82A102D9C350672689 = { - isa = PBXBuildFile; - fileRef = 29D746FC68F69751796671A2; - }; 03FA420AACDD03D50AA16E4A = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; @@ -204,13 +204,6 @@ path = ../../JuceLibraryCode/BinaryData.h; sourceTree = "SOURCE_ROOT"; }; - 29D746FC68F69751796671A2 = { - isa = PBXFileReference; - lastKnownFileType = sourcecode.cpp.objcpp; - name = "include_juce_video.mm"; - path = "../../JuceLibraryCode/include_juce_video.mm"; - sourceTree = "SOURCE_ROOT"; - }; 29E0972229FB44D969035B4E = { isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; @@ -239,20 +232,13 @@ path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; - 30F22843EFEBF7AA841EB4D6 = { + 36689CA4EFC2AF183A0848AE = { isa = PBXFileReference; - lastKnownFileType = sourcecode.c.h; - name = AppConfig.h; - path = ../../JuceLibraryCode/AppConfig.h; + lastKnownFileType = sourcecode.cpp.objcpp; + name = "include_juce_dsp.mm"; + path = "../../JuceLibraryCode/include_juce_dsp.mm"; sourceTree = "SOURCE_ROOT"; }; - 31D55A751C790CB81F58DDB7 = { - isa = PBXFileReference; - lastKnownFileType = wrapper.framework; - name = CoreMedia.framework; - path = System/Library/Frameworks/CoreMedia.framework; - sourceTree = SDKROOT; - }; 37E4D5C341406B7072120006 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; @@ -337,6 +323,13 @@ path = "../../JuceLibraryCode/include_juce_data_structures.mm"; sourceTree = "SOURCE_ROOT"; }; + 5F0ADA39C70C892758A941F6 = { + isa = PBXFileReference; + lastKnownFileType = folder; + name = Assets; + path = ../../../../examples/Assets; + sourceTree = "<group>"; + }; 5FBD6C402617272052BB4D81 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; @@ -379,6 +372,13 @@ path = ../../JuceLibraryCode/BinaryData.cpp; sourceTree = "SOURCE_ROOT"; }; + 7D924E83DABA5B54205C52F4 = { + isa = PBXFileReference; + lastKnownFileType = wrapper.framework; + name = CoreServices.framework; + path = System/Library/Frameworks/CoreServices.framework; + sourceTree = SDKROOT; + }; 81C1A7770E082F56FE5A90A7 = { isa = PBXFileReference; lastKnownFileType = file; @@ -435,6 +435,13 @@ path = "../../JuceLibraryCode/include_juce_gui_basics.mm"; sourceTree = "SOURCE_ROOT"; }; + 9320A145F2A8ACD687D6608E = { + isa = PBXFileReference; + lastKnownFileType = file; + name = "juce_dsp"; + path = "../../../../modules/juce_dsp"; + sourceTree = "SOURCE_ROOT"; + }; 938AE72315C6C93949F6220E = { isa = PBXFileReference; lastKnownFileType = file; @@ -470,13 +477,6 @@ path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; }; - A4B568E26157FC282214976F = { - isa = PBXFileReference; - lastKnownFileType = wrapper.framework; - name = AVKit.framework; - path = System/Library/Frameworks/AVKit.framework; - sourceTree = SDKROOT; - }; A5DFC13E4F09134B0D226A3E = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; @@ -498,13 +498,6 @@ path = ../../Source/HostStartup.cpp; sourceTree = "SOURCE_ROOT"; }; - B1CD9599EB12D77E8AF9241D = { - isa = PBXFileReference; - lastKnownFileType = wrapper.framework; - name = MobileCoreServices.framework; - path = System/Library/Frameworks/MobileCoreServices.framework; - sourceTree = SDKROOT; - }; B285CAB91AE928C476CA4F9C = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; @@ -519,6 +512,13 @@ path = ../../Source/JUCEAppIcon.png; sourceTree = "SOURCE_ROOT"; }; + B457EE687507BF1DEEA7581F = { + isa = PBXFileReference; + lastKnownFileType = wrapper.framework; + name = WebKit.framework; + path = System/Library/Frameworks/WebKit.framework; + sourceTree = SDKROOT; + }; B86B918291E1090C6A720971 = { isa = PBXFileReference; lastKnownFileType = file; @@ -568,13 +568,6 @@ path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; - DDE115D3084ACA6DD6AA4471 = { - isa = PBXFileReference; - lastKnownFileType = file; - name = "juce_video"; - path = "../../../../modules/juce_video"; - sourceTree = "SOURCE_ROOT"; - }; E68018DE199135B7F738FB17 = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; @@ -686,12 +679,12 @@ 3D57FE2A8877F12A61054726, FA21631C5536EA3DF55C7FA6, B86B918291E1090C6A720971, + 9320A145F2A8ACD687D6608E, 59842A98E5EBBC54B50C04CD, 94CB96C8E4B51F52776C2638, 938AE72315C6C93949F6220E, F299BECFB2AEA6105F014848, 81C1A7770E082F56FE5A90A7, - DDE115D3084ACA6DD6AA4471, ); name = "JUCE Modules"; sourceTree = "<group>"; @@ -699,7 +692,6 @@ 7E30376DDAD775FEFE64944C = { isa = PBXGroup; children = ( - 30F22843EFEBF7AA841EB4D6, 6D107D7946DC5976B766345B, 1DADAD8E34AAF4AFF1C69DC4, 4C7D82F9274A4F9DBF11235C, @@ -710,12 +702,12 @@ 683CEE986A2467C850FE99E6, B8E24A5CEE6B7055537725CF, 5EF1D381F42AA8764597F189, + 36689CA4EFC2AF183A0848AE, 8290D7BAC160B3A56B66891A, 82800DBA287EF4BAB13B42FB, 8FE7B37CDE0818DB27BDDEBD, 2BE6C2DFD6EBB9A89109AEB5, 37E4D5C341406B7072120006, - 29D746FC68F69751796671A2, A5E7CA8A71D049BE2BD33861, ); name = "JUCE Library Code"; @@ -724,6 +716,7 @@ A97EE73C79DA3F729D46AF48 = { isa = PBXGroup; children = ( + 5F0ADA39C70C892758A941F6, 57DF618F1DE781556B7AFC32, 29E0972229FB44D969035B4E, F58EBA72DA53F75945B91321, @@ -738,19 +731,18 @@ 86CA337014D3F67E906FFD28, D4EBC17BDB7F88CCBC76730B, 942A0F04EFB8D0B2FF9780BA, - A4B568E26157FC282214976F, 9F9B445E6755CAA19E4344ED, E68018DE199135B7F738FB17, 2F7D965A1284CEF0B20EB657, CFFA8E9A7820C5A27B4393C9, - 31D55A751C790CB81F58DDB7, 5AF0CA7CDFCA90B4DE1F55C3, + 7D924E83DABA5B54205C52F4, 66643EDF46AE8C5B7956B91D, 03FA420AACDD03D50AA16E4A, - B1CD9599EB12D77E8AF9241D, D0026F0A29B486D87E92BB8B, 89309C0C5F3269BD06BE7F27, F9EDC54DFBCF3A63E0AA5D73, + B457EE687507BF1DEEA7581F, ); name = Frameworks; sourceTree = "<group>"; @@ -792,6 +784,37 @@ GCC_PREPROCESSOR_DEFINITIONS = ( "_DEBUG=1", "DEBUG=1", + "JUCE_CONTENT_SHARING=1", + "JUCE_DISPLAY_SPLASH_SCREEN=0", + "JUCE_USE_DARK_SPLASH_SCREEN=1", + "JUCE_PROJUCER_VERSION=0x60005", + "JUCE_MODULE_AVAILABLE_juce_audio_basics=1", + "JUCE_MODULE_AVAILABLE_juce_audio_devices=1", + "JUCE_MODULE_AVAILABLE_juce_audio_formats=1", + "JUCE_MODULE_AVAILABLE_juce_audio_processors=1", + "JUCE_MODULE_AVAILABLE_juce_audio_utils=1", + "JUCE_MODULE_AVAILABLE_juce_core=1", + "JUCE_MODULE_AVAILABLE_juce_cryptography=1", + "JUCE_MODULE_AVAILABLE_juce_data_structures=1", + "JUCE_MODULE_AVAILABLE_juce_dsp=1", + "JUCE_MODULE_AVAILABLE_juce_events=1", + "JUCE_MODULE_AVAILABLE_juce_graphics=1", + "JUCE_MODULE_AVAILABLE_juce_gui_basics=1", + "JUCE_MODULE_AVAILABLE_juce_gui_extra=1", + "JUCE_MODULE_AVAILABLE_juce_opengl=1", + "JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1", + "JUCE_WASAPI=1", + "JUCE_DIRECTSOUND=1", + "JUCE_ALSA=1", + "JUCE_USE_FLAC=0", + "JUCE_USE_OGGVORBIS=1", + "JUCE_PLUGINHOST_VST3=1", + "JUCE_PLUGINHOST_AU=1", + "JUCE_PLUGINHOST_LADSPA=1", + "JUCE_USE_CDREADER=0", + "JUCE_USE_CDBURNER=0", + "JUCE_WEB_BROWSER=0", + "JUCE_STANDALONE_APPLICATION=1", "JUCER_XCODE_IPHONE_5BC26AE3=1", "JUCE_APP_VERSION=1.0.0", "JUCE_APP_VERSION_HEX=0x10000", @@ -814,8 +837,13 @@ INFOPLIST_FILE = Info-App.plist; INFOPLIST_PREPROCESS = NO; INSTALL_PATH = "$(HOME)/Applications"; - OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow-all -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wunreachable-code -Wzero-as-null-pointer-constant -Wcast-align -Winconsistent-missing-destructor-override -Wshift-sign-overflow -Wnullable-to-nonnull-conversion -Wno-missing-field-initializers -Wno-ignored-qualifiers"; - PRODUCT_BUNDLE_IDENTIFIER = com.roli.juce.pluginhost; + MTL_HEADER_SEARCH_PATHS = ( + "../../../../modules/juce_audio_processors/format_types/VST3_SDK", + "../../JuceLibraryCode", + "../../../../modules", + ); + OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow-all -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wunreachable-code -Wzero-as-null-pointer-constant -Wcast-align -Winconsistent-missing-destructor-override -Wshift-sign-overflow -Wnullable-to-nonnull-conversion -Wno-missing-field-initializers -Wno-ignored-qualifiers -Wswitch-enum"; + PRODUCT_BUNDLE_IDENTIFIER = com.juce.pluginhost; PRODUCT_NAME = "Plugin Host"; USE_HEADERMAP = NO; }; @@ -837,6 +865,37 @@ GCC_PREPROCESSOR_DEFINITIONS = ( "_NDEBUG=1", "NDEBUG=1", + "JUCE_CONTENT_SHARING=1", + "JUCE_DISPLAY_SPLASH_SCREEN=0", + "JUCE_USE_DARK_SPLASH_SCREEN=1", + "JUCE_PROJUCER_VERSION=0x60005", + "JUCE_MODULE_AVAILABLE_juce_audio_basics=1", + "JUCE_MODULE_AVAILABLE_juce_audio_devices=1", + "JUCE_MODULE_AVAILABLE_juce_audio_formats=1", + "JUCE_MODULE_AVAILABLE_juce_audio_processors=1", + "JUCE_MODULE_AVAILABLE_juce_audio_utils=1", + "JUCE_MODULE_AVAILABLE_juce_core=1", + "JUCE_MODULE_AVAILABLE_juce_cryptography=1", + "JUCE_MODULE_AVAILABLE_juce_data_structures=1", + "JUCE_MODULE_AVAILABLE_juce_dsp=1", + "JUCE_MODULE_AVAILABLE_juce_events=1", + "JUCE_MODULE_AVAILABLE_juce_graphics=1", + "JUCE_MODULE_AVAILABLE_juce_gui_basics=1", + "JUCE_MODULE_AVAILABLE_juce_gui_extra=1", + "JUCE_MODULE_AVAILABLE_juce_opengl=1", + "JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1", + "JUCE_WASAPI=1", + "JUCE_DIRECTSOUND=1", + "JUCE_ALSA=1", + "JUCE_USE_FLAC=0", + "JUCE_USE_OGGVORBIS=1", + "JUCE_PLUGINHOST_VST3=1", + "JUCE_PLUGINHOST_AU=1", + "JUCE_PLUGINHOST_LADSPA=1", + "JUCE_USE_CDREADER=0", + "JUCE_USE_CDBURNER=0", + "JUCE_WEB_BROWSER=0", + "JUCE_STANDALONE_APPLICATION=1", "JUCER_XCODE_IPHONE_5BC26AE3=1", "JUCE_APP_VERSION=1.0.0", "JUCE_APP_VERSION_HEX=0x10000", @@ -849,7 +908,6 @@ "JucePlugin_Build_Standalone=0", "JucePlugin_Build_Unity=0", ); - GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; HEADER_SEARCH_PATHS = ( "../../../../modules/juce_audio_processors/format_types/VST3_SDK", @@ -861,8 +919,13 @@ INFOPLIST_PREPROCESS = NO; INSTALL_PATH = "$(HOME)/Applications"; LLVM_LTO = YES; - OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow-all -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wunreachable-code -Wzero-as-null-pointer-constant -Wcast-align -Winconsistent-missing-destructor-override -Wshift-sign-overflow -Wnullable-to-nonnull-conversion -Wno-missing-field-initializers -Wno-ignored-qualifiers"; - PRODUCT_BUNDLE_IDENTIFIER = com.roli.juce.pluginhost; + MTL_HEADER_SEARCH_PATHS = ( + "../../../../modules/juce_audio_processors/format_types/VST3_SDK", + "../../JuceLibraryCode", + "../../../../modules", + ); + OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow-all -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wunreachable-code -Wzero-as-null-pointer-constant -Wcast-align -Winconsistent-missing-destructor-override -Wshift-sign-overflow -Wnullable-to-nonnull-conversion -Wno-missing-field-initializers -Wno-ignored-qualifiers -Wswitch-enum"; + PRODUCT_BUNDLE_IDENTIFIER = com.juce.pluginhost; PRODUCT_NAME = "Plugin Host"; USE_HEADERMAP = NO; }; @@ -893,11 +956,12 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; + ENABLE_TESTABILITY = NO; GCC_C_LANGUAGE_STANDARD = c11; GCC_INLINES_ARE_PRIVATE_EXTERN = YES; GCC_MODEL_TUNING = G5; GCC_NO_COMMON_BLOCKS = YES; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; @@ -943,10 +1007,12 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = NO; GCC_C_LANGUAGE_STANDARD = c11; GCC_INLINES_ARE_PRIVATE_EXTERN = YES; GCC_MODEL_TUNING = G5; GCC_NO_COMMON_BLOCKS = YES; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; @@ -966,10 +1032,6 @@ }; name = Release; }; - B9D79D85AC7DE5BED1B6547C = { - isa = PBXTargetDependency; - target = DE12B7643D374BFF7E4FEB1C; - }; 493C2C5E457692E5149C5525 = { isa = XCConfigurationList; buildConfigurations = ( @@ -992,6 +1054,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + FE22E1AF24FA9ED43E983B81, 59F4F23BFFDAB414B4801F85, E283262A07376A7EDFCEAF6F, 443244451A0F2064D4767337, @@ -1017,12 +1080,12 @@ 76A80851698FC773D2479B4E, E4A926EF695823F0F13268FF, A09E93F1B354E1FF8B3E9ABE, + A5F0B3B7175766C8AF1D6C3E, 7DE202DC1D876F49266D9E7D, 075C54DDDBDEA5AAD2F60154, 2C3D221D2AA87F07B3F1044D, C38D14DC58F1941DD5E4BF60, 2727A191DB1BAAC9C04B9081, - 84BAFE82A102D9C350672689, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1033,19 +1096,18 @@ 73E371F1B912FCCAE0CD7E5D, 21D330A5B13178B12BEAFC3C, 851C1165C9E4ACDD19C56A96, - AF42316D915057E930A5624E, E3CB85BA817BC9E3942A8AB0, 70580743C3D5695F065FF698, 1570FCC5CDB7A44DF0077E39, B0D5475F716126465FCE1586, - 3470F40DA5D68EC217872906, E092A70431B046BF1F50A482, + C81D59C798F9F1F1A549FF07, 92EE84159C7027A137F06204, 9056B642BEF870098DE344E5, - 7DE81C004B0FBC563040CC5F, 2AB9A26C9359C40CA0A937ED, A02C9F4C4B840C27B6CAFEBD, 50AFD116DCA6EC228EFB322D, + 4DB15177DDC357F4503F88CF, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1067,7 +1129,7 @@ ADE6E539DB98A302483A82D0 = { isa = PBXProject; buildConfigurationList = 493C2C5E457692E5149C5525; - attributes = { LastUpgradeCheck = 1100; ORGANIZATIONNAME = "ROLI Ltd."; TargetAttributes = { DE12B7643D374BFF7E4FEB1C = { SystemCapabilities = {com.apple.ApplicationGroups.iOS = { enabled = 0; }; com.apple.InAppPurchase = { enabled = 0; }; com.apple.InterAppAudio = { enabled = 0; }; com.apple.Push = { enabled = 0; }; com.apple.Sandbox = { enabled = 0; }; com.apple.HardenedRuntime = { enabled = 0; }; }; }; }; }; + attributes = { LastUpgradeCheck = 1200; ORGANIZATIONNAME = "Raw Material Software Limited"; TargetAttributes = { DE12B7643D374BFF7E4FEB1C = { SystemCapabilities = {com.apple.ApplicationGroups.iOS = { enabled = 0; }; com.apple.InAppPurchase = { enabled = 0; }; com.apple.InterAppAudio = { enabled = 0; }; com.apple.Push = { enabled = 0; }; com.apple.Sandbox = { enabled = 0; }; com.apple.HardenedRuntime = { enabled = 0; }; }; }; }; }; compatibilityVersion = "Xcode 3.2"; hasScannedForEncodings = 0; mainGroup = 65BEFC705A89E5C8A9E35C97; diff --git a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings index 949b6789..f2e3cbe8 100644 --- a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -4,5 +4,7 @@ <dict> <key>BuildSystemType</key> <string>Original</string> + <key>DisableBuildSystemDeprecationWarning</key> + <true/> </dict> </plist> diff --git a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-29.png b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-29.png index 9344000d603583145f6345e3fde84ab3f1653174..64686e41e64de056157eabffeb303cc84f463343 100644 GIT binary patch delta 2115 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 delta 1618 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 QV*mgE07*qoM6N<$g83OL2mk;8 diff --git a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-29@2x.png b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-29@2x.png index 84a06c0479f40f8a0f1fbc9f77b3c3fa99f6ff8f..e48be2d3ffc53e74e6fb5b742185333e2a84a352 100644 GIT binary patch literal 6043 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 Vjy=V3u6h6f002ovPDHLkV1fe_i5dU^ delta 4385 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 b@8$mizPF}$l(Dos00000NkvXXu0mjf3R$Y< diff --git a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-29@3x.png b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-29@3x.png index 6021b1d0c734a46b941ffc26f44358570479745e..5b71bf3d3da3757e9d18496edb35e75061329b9a 100644 GIT binary patch literal 9140 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 literal 6732 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 diff --git a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-60@2x.png b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-60@2x.png index 635a47187aac9b4a1a18568cd7e534c6e54d398d..c07c472f62b12a0a5e84beaf0271e3ceffc2be37 100644 GIT binary patch literal 15603 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 E2j@xDl>h($ literal 10478 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 diff --git a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-72.png b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-72.png index 52ec77a646f593f384468a65115d5b52b17a87fe..29c57add7a14bab63e1c9f822ed96dbaecf1691c 100644 GIT binary patch literal 6689 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 delta 4700 zcmV-i5~J;*G~^_ZGk+2rNkl<Zc%1E=d3co7y~jWAGW(X5n1nz`f)D~4Kt(IiKI-jt z0c%lft<_purLDEM)z+ojM_R?L_M#OREJdyMQPh@JZM`m7uT;HOS%So12w@LNCYi}h zW_{;f?jLWM0GTY4O!VI8@%udUN6ve4&hLEZyub53=l44!7=MOg@HqyB_*on9e;uC_ zGz>l`Xc)+!MW;$ip(DN@fBX=^L?;n7L{dwj3n~B-G8Vyx$KoT;UQDsQjN_aYSS_|s z-PTWqAXQ7z89zvCPZL}G8)=Drgr=)mwIPZU)y_I*Pgp>8UL6yh6R}8^ak97{!g#G> zhGC#+N#1YUz<-PT*OE|U{hbOTk{}@p5<Y7oW$wx3SqpK<Za^TRM(9xj9E$FtC)tH= z=xBzDZs_SYY?7UGCtkt)iDzS#?Fb0tF^uscD3T2ET+1Ug1wSONMFB7{nB<wt7t0n? z?VE{Hc4L#A$l}nGSTj@-YK*uVr8WF9Z@0b7?r>9@5P!SmVp?83U#s~6K6^o~hmu=@ z;;9%f?S7npb-qbLGiOY>dkPE7&S!dlJ%#q;a?(#A*-3M-fsJi1v$wYy0Gs4sPSHXx zsQL~rt0yP@K#mB~4V?!6yFAzOFukcD05y5DICJ6>W)+^=U(qnoBOPdgz35#nXkEL| zLkB<*v45ZbedMwe0nmE3llb`8U?_;rNl4zQh@NSP?kYrQDMv289|tzE;lK+t2OBUj zaLOJouKGT6OBN!E(pZN!c7l>xoOPc(#J~I-0PtE1xP01As4X}tUB^iFq8-{!vf+8O z;J(a;h!UP}{t*O`=-U@!Xt9j-L{|mY%FB=n=6@hqeChI?J==J4$G!9<1Asw&;e0Ne z_G26t*I0%(Hi8s2!R;SjMKIX~z{0Y{EUCT<Su|G{Lrsu)?=ez)-UBT)bYq5&=dz~| zWSPiYix^g-i5BFdQ?O0H9zixq&<vHA_xyp^_dO4Q&sxAOb64ZEx<@<2(G#>M)XXE> ze}6$#4db$SSz3ED)AH-hhq_AQ!>35?`frS6WMmCyOVHr~$S&lPFJYbfJp|DTz^+gu zYn$#QlnmgITr8_wPEG#IQH*kw1T}SSX6+|;5?7;CxNBHC<7SE-Wq^TtU<-+Vtwj&F zXV>T`2|5hHJ^|a*Wyr;+0|J3WCy(#An}6M*Caj{JrL{LRv*?uUY|7dSU~j0I-}jL- z$upJzsK3V~M@yk>`!lf(cV$mb4qzlYNqlq%O6!xLCn>N`;M!StQthil(G#p~x{IB` z?OC^*6+w!c;Nk7RAkjz84Rd~rU2+1D+VdWX&CkGRdU|4@?0E+D&>H|)B|AT<zkiQv z-%J!e!DAmUC#sC_mG8rd2}){lZvXIVqH355cMU%}@t&hiON6rOcs!vi!K41ZX4dUg z`(_YVqpa9;6|vOFNg5GBx}me~lZOZ<{iZ{naWi(waa0|-@>E1e-iSLMF9;Sd@^NPz zRc4j!Tv>Y~K3gGSrH7|?tUPMlGJh0CL{NkO-L%d*?2rvLMZDoPqVGJ5*3*vYD#p3! zE`-mJB*EgvF?S`RqYPc^CfU0lCHgvsp^$Hzz;|cd0>HMwyL{08j}f&wEJ1N4%5yCb z1E$WImRAoLMBjauo<H4A_|=E#ery?9PY0r_826F~5nY9&ALS?^So3ktTYrP-oQR<X z=<T?kSa3Db?%$9I{Sh#j;;rSJ$=^Ug;Dud}5J`rIZFg9LUflfzy{RBxTLDX|uL2<1 z{64)KewVJJMFMm`whTQPL$Ek-o&ReDhi|YZa}GiF;5>O1g4G8`ig3qI(AEBxG!cG| zRP3JsoIUv)<lBphYf;v>u74S}?I8(@Dq%kGzX`zQ$6tpmS}?Q};lJNMV71aB-E=+p zP4s9Fg3XKToZAr{`B@J(TL=~}jyd-s*owf25ju1=y4rC}ErVEaHHMKu5+tsyy%9kW z*wXbjfvA7T_6H@%Fbvi;KSV-{QIj`|+Jd<N^uGEqYT#hT|IxyJ{C}&iK<(a-=q<x} z&acLGCJC|!$LwDtx+~GuPC|#ihpryVSXbA&hzCtqQRSUMZT?&oJ;}OV4`ML5G#Qkj zl%AxiXA=NtPP`BRLx~e_cy&ml^=Od5@2~A6sTB7GE62qrnLg*yG&#MUH=wJXL;jBv z+lZl?OZ-_C7b76h5`W%KB9(b#3_}p~{=qkiYf;MGQ<zma4}kDX_o2sohc#Y{bkn`& z8uVz$eBCa%Kc}mkVDaKSWi^7W2t$w2+xgR@e9mAn^f=M(y8$>p?*yuRbtJVoZ|(c* zp#PJRAXQ88mwl!KTUfRj06i8W-uTvt2cbuUbUpIze#gD&u78~9By%ahzuzIZUo-5? zITESFR&>o2lJm>X1>m(q>rm80#`+lv>Wm*Gsl_ocn4Uiy0A=@P3{}Z$Fk0A;|A9;U zb<)|t91}@`#fxM1y@<|o3@t$D(02#*IfKGbNyXm>;P^cAfG(vew8sx*te%me)?gC= zlRZ<-V^YH)@_*J7*%{IYy-xzDUHcGy<)appX%Xn2g08j`?zk?)YBe$>!_NRZK5Iex zh^D!FYsR`63EI-N5r73{ivZAqZKOJOjmj7>by8sMk47yf1#3ReQ;!gVoi~lh=L~9( z+JTnZ55U55(}isIZ_HSC06|Jhp(XMWf*?}kn*~6sy?+J97*^3D-J=qdX%T42ECNSu zPs;qlD_qrxg2ev#PGZUEfO-Q6>Wm*i(^Vuv>WfoBs%^)Z4T9{&<j6$e=%6M|H{y`p zNP>)E7_`R+o|k7JsLgyJi0K`B>R@gNf{}|!LH6L7Gcpl4Dm#>&fEg}29GmNm4HUow z2<l0i(tq1$EleN2tNy(?GYm3|NhyCa2qGXNx++Z(=o+~Q%oc}zkSK_hI4b}MCI@ai z1`rfUnFn8GuFC#GA@@lj1I6S@1d9Vi3(k4JGheGLL}2#lAJgHnhLgb|YV{$h#{tN* z^{+C%3vNP?WH9uce)LE;-H-op&>{48-q=Tuo`2JiAc(jMuTS?=U@HbdG2#Pk7!VlO z(ExDB{Q);y^+}Z6`Z`7`v)UXBgdt|9d&0fYXHRbXw1Lo{8Dc*iS7Ttt$q<<XM=$Gw zD1l(jjfF=-99%x=*vBOZAPVA$Mauw!1jGDB<7&SqP_{J@ym19ac=(NKwveYxqUh-d zGk-q&>wB$qg$7RhvBD}#e0lC9$_mYylhDjQL}TE588E-Cq8)&c(w!~~-SGfMBnqOK z(~s!$Qm}IQpaVJg<jFYgGJ-%(KPgRP!`A)jeu4>eg|zjJeMo{l7IUA}7Twcdm>MRo zJ_?9l4+X1MAQl&riYxrrtuLS^QYf0iSAU=0Ody`ZZk1U)uL`Fv_nBmx-XGOC6f<Rv z*EUeJ4j?GsZhG{dL>HRTmoqrIJg3Hq9ybN6?m(`ZM6|1yzumZw?p>YenvQN5G<HN- z{NyI~1mpNzRu;{hg2R^EY{5L2neV6@I)|dBg3hxQ4Yc*x0yD-AI(j;7&N8hgXMcu? z1$h)bc|Y<Llbj7JUL@8%Fp$?BQ@H%OhBQeR&7X?Pp1YY;<TG~(NiB}1n{UVj$H0j& zfS?k`L_|?UGc;nVX}G0!YEFz2eIAOQd?5W=y>a_rh;$AfdhtgUE?d{o_qs`3ykIKM z9L=PXJTqh-SEHzgiXaLc=bSXq=6_=gtQH$p&Y2j7PHWiQ&{?V{kJ%v6>!I+GyAkue z=qZg?e*QesuHi$#-7$r)KDC*MqG6FmzH(Z1PJB|K*L28j(cS2VM!CHPmu+C`UPhHR zyLbTr8{1w6Kq@aqo-}$tBzip*{PtH!6=fuPV!ZUzXNH_P$D$*W<m|^k;D2B^f!kr> zym^&lBFSa9kmoji(A#}uoLw|Ov+bD*YYOTB*d1;nnCt{mz<uS{MrDlX^HBKc-N@CI zMEzl2TfUxXSN3|UE2?nGGh1m5#L08n_{wRcU)}1fixCBZ-c%1w0W)$ly|6yB{h10& z922ogX72Hhpm`K&J^4fgYkzhIi3NESJ-sSDb2hAak%)ifGv`=zMHRmFd;@LaByNX= zix+0^xJ6N*vcwBObB~$$DT|i$j($M>Oog&!;k=4(0r1bZznK;DeAvElQl{#e8}_&< zT6168=e&B`pNaU#uEhOOg-f2<LPXK9$|6fnug*#W9GCA*JNkFpUVj1L%+ian%Z`lo z2i+;2KJjeql8e2)%`^qgY3RG@hlp<Hutpp!0$;x2*-^b#gTWtFSoFk)S&K<o5;?Qp zT&Y^ajqL2%hE=q4#-y(fK9<2ASVdc3CI`H+{{;X9mlOM$3x+h}SP}U58`ov!kVlI4 zNHS|NSy|%6ZZ&hKUw_~CJO&0+Jhek+!4680AP8Jia}74hL36Nyojo4`;JJ1w(s9L^ z8_OU9qZveCu8@tGblPN2uQNsP{zwarfe)~VR=z&<+9B_G40%-OwdXUZ=!+N_Jh9^* zG($zOS@B%E)ZFzQ*-(}uFjp9<n4CAg6ss(v8yagGSD+g@Cw~-vfnrzbknIn9mU=<e zQe3i!P%^;Fd!7QozF;2iD=zA9WRxN>R~SxA&a5n?y3`B|ym??ffkX#Z(awccR}b6v zu<qYw^>9(u_j$7UUS8k#95V|}q1so6>+*|`iVM-YdvJVtA=1QB5<M|qz3tCAb;u*d zVKKSx(t66hc7M)4t%{bm9;_CLY2|qcg86FwrFAV}aADOly!PSqmqv6NKeuEd^@XO= zT-$UffkX#_&5GkI|Bid<B}fxXi3g*+w*0dp=P(Y7$%Ekp9*2e5)y33JDnOP*LP|Gl z8dm@YwRtCTYUx=cYI8&ciK4`1(|(N4T0kfn;PD;zpnqsbpHJ`opItf8Ib%gvRN=25 z9~~k}=?Z_?@f*4m?YJynuAFfL(lGbb4r9de9EZilEpu1nkX-BzHL>cWTaS8fb$$Bx zNe6?^e)Qm1Z(q(Q!7bP%2e-~yjmt9f`(#-Kyqs1y%j%Y6745W!8d<sZr|FqA`P6D= zES^2q5P$xdAOM%oE@w$y31H5gRoi~fj^I{g!NPZIZ^dKJF0&--h+s|rOujSYW~`!} zU7<!+ZM%g)q7%s~bK)iQSa9u^aTbjJ`q5}n<g#+_In%lMOI0{55+S9VN4MX`j^Gw7 zqJ=A_{fyeeIa#+ms*q`2;VJxJ<{da>7p>us`G3vU>&$zkf<VQ*Y8KshDb-)9#gfAl zz`@|KNSt3=!YkiCiN&=O5CwsKy*v5OE!Xo&a4R;^&ebz+V@}D?JAlD3rVDj3CCVL} zt|HubH{zVhmvZ*x%a8<9&MVO*?>_Vf?TrV~)u97`hHh~2n(v_7ES&JbKZgpJ0br2? zW`CFZcwliY`401o&<%|@53Elw<t~etU(9_Bw{7&9wqw4M8CRn`y<;T}-R~eEkY_96 z+qE}Q<(rYNlL*B)xMeTf*KZnB1_+|SC68YPlE~au?-EaCCbYzDW7)h4{;j5nVpo44 zbAP0THH~)=NOWRgFeCqDzE%6PtQ>MiyMJ<ZsrQ5SfAFW)M~SHs1VNxSe=cWLT$IiO z1ap>z+kyo5cH!UIL2$R9P+Jf|5IF67XHY(;5`g#i^>E$an^07pssbl<C2nSy`j}qq zqPozDe8lwH6>j8>eb3Vv_yFC|u}Kb=Ou3p<OV1kdQa%)NdM!MX470v<4O_b2Mt{+h z2nba9W-!0(JdV#h5uY_T_u6|?Jv8?;@J`z+?CjZwfq_M|azf!3xUl-_jPb3}VqAV$ zAQ1JluH`{mdbg9*`a{Rl^6ObxzL*MEH4fR0O>!U(lUk!2I!P@~T#eEe-NV~$FVPg( zl+KQ~igu=WYx#Q3k0^HK=3f4h7=OQ?robSPit*O|7kRDiSyEbm3b80iNP>(k%9J=O zD05X(V4HwlHV@+xYK%bAPkVGPhhqEC^c1S0q8t5wNfs@fQF0+?RxZJ1HGk4#JTPtq z9f_oxpd)^O=I*U*_HSf=d?(p<D~JN+_8Mjv&1ZUHJtfYHL61puiBE-~V^tATqO`~M z;*YlxOmq=W21y!m^uGKY5eci{z-P<HXDg!EQAVkAQpUK|c;ho6=>HQw{{^aH@Hs)l e;B$h8!T$n3J`1Q*iylt^0000<MNUMnLSTZ*CjH$2 diff --git a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-72@2x.png b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-72@2x.png index 54b2c964e80fb690f0bbce56197dcc227dc04293..c45a6e86326e5af895f190df8fa7ba5275fa89b8 100644 GIT binary patch literal 14216 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 literal 9823 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 diff --git a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-76.png b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-76.png index 1d84eb4b92262eaa900e9f22355e4b736e3e0411..7494cb731eae4ee264ab849b670ad0d3b59df78a 100644 GIT binary patch literal 7327 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 FV1oEaP6Yq} delta 5365 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 T(X=g$00000NkvXXu0mjfl2LpP diff --git a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-76@2x.png b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-76@2x.png index 4324c82b122b18b8717ec04292a78389759bb99e..88b8868496e97740e13d5aa026e4e78c3b1624c5 100644 GIT binary patch literal 15931 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 literal 10888 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 Z!CWym!iUu?2P-WFe34KPuM#y3{69s{<(2>d diff --git a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-83.5@2x.png b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-83.5@2x.png index c2cfbef3f20d48558f0ef8b62c59a2e69066fea5..640134b6477ae269f4895f9e163ccee41fd48361 100644 GIT binary patch literal 18225 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 D`Q)0d literal 12870 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 IGG;;l0~$)J1^@s6 diff --git a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-@3x.png b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-@3x.png index 15deee7ec5b04b061e5d44138e9e1eb8cce1b2b2..4b608c00a0b3dd7363eef3cde1c34bcdd9691564 100644 GIT binary patch literal 20798 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 a+WZ%-iJvl+)ixRc0000<MNUMnLSTYzrFt3w literal 14731 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 I)HwM60C?AiCIA2c diff --git a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-AppStore-1024.png b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-AppStore-1024.png index 467fc9cf7ee13ad447e884fc270cf3f4f7c5b449..a35af3124b8e8a4905f08d3971ee87eeeaeff3be 100644 GIT binary patch literal 54232 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 X_->S$^b{El&A6(fCgQXFlfeH0QDN=1 literal 49618 zcmeEu^;cBy7w(~?OF&R5MMO$4kdl%TknRQv=^l_AL=go6X{AG&p(G@SknZm8&H)A{ z?!nK!f5H9r%UY}%Sg_w6&wh5iXU$hN6?t-!J0t)AkSn~F(EtE^@GU+-bOU^WGI4*r z{>lB7f))|@<ws=s1prt91sN%=_sP3+UdhIg4_NFuXSFil&(nEgPMKd`GNF$`3Cdtr zyxf_Eg@%oWjoZanR|WQl=Y?0=T3SZjM2Z~@A6P#GN)l~BhI@J+{B-NdhfD0^mjU<O z_Zyy_c#E+d|43i=6DOuzUq2B^I}z4l>?i}Z0Dz`E>j@v+e{a)|iT=F;41xc>2IBnh z7uTNnpFjTL;eT-WFD?EDhyTF=0REQ^|H}r@1OFp~|B=D}CmA%s5MY1UbVAyy7W`HU zFE{{kexAR$7DstwH0?lhh~@h>9v!Nl#Ka^!oi$g=ZJV9%5oZLOx4MD`kHT?F^l~$c zgl@M=PZgs=nUN^(OnF?@GmXW(Q5vq5^;qS#Sfz=s$2oBta^#S3yUyoa78|2#3wfU} zZ>*I=6mv($(BxqE*U=Zca-oWS0LHQ)v${lgE~L(*^eWKjm=Kb89(deO&9psNlHQp9 zYPK*_jJ58u#*@w-H(p^*!#k*ph%AYE6WaFBtWV<8yj`w)637FdLexj0P`dXS!zwye z2i;u1#*!W5M$$Bua*PqKh0{A7`B}F0(@7$uL*p6iIk##apR)i!9>H}RN*B+!3dy@l zKVzECLO0Yw@+#!TmT=<S<j3flb&L);znhv&a_c<*lNTA3SKkzAA*;@#^zr;SWQe2M zDlXSTKi;83gHb8MUZIM;Cz@wQgRx!1vg_z+x2$sasbB%Gm=y2!;NSTCI}0xqR;D@f zva_?t;fw$vCvbf@@z>1PgcN%d#psl2|Mzti??uOG4m8Dm_1Zj2?sI(Kn+(l5HooNl zl4d-sbVrBuO0m>IDV}$#*qGvmlQ;c`S4vK0DpPM`rUle3b`=tbMU-MX-i&=Ziiz!6 zw-bYar~EUK!)D<_!*rEzm<XlwxHz<qBKIu+hiK8Gy`J*yN72jt%=IxWVXCtmPyT2& zc}AeExFamu*p(pWg^7w50^^A}`Qg6>{AYQTQ~9-jzR4N?eFHH2dk@s!h4C1P<G4_% zY)I*(_6{ot$@MCbn1MaoQ#dON4nXpW8^pNoQsd54TGg$|lVnE2jPhk2F%QD4t!?@z zV+7of86g#3qdv6&K<0ZruwcGnFyfBWWl~9$Vp(&|)(A^4d)6^t4lC}^U!9S9yAy#{ z3h^gbkJ9zr!h{9ZI_&+PYyO_OWrwMV5eS(5WS~k11e%9{f&w2boL72xJcKP={qlUj zGnz7$|LQEyL7wEJUWVy>yTo+b2+LQVndlXRa?LftTa#@SiG&YrLd8r^L{)}Rw@Jr_ zdvU;-i3$|eK3xZm9Cv_f+>LyhFAbR)O%r|~YQ;&me9VOT9@!bS8TnDNYBcW*<<Zy4 zGujmsZ`c3LyWH_gwip*^+LQ(*FtCN*cbu&<vG<fHc5JqTY<O~Y$J5GcYzD6pNTh{k zMOYcS4S$Rz!;imn)nT7lDalctmJ|FtA+ND9V_Xv-Naq5FqCoY&lb5imi&&ile;H9t z`!PefZoEC`>8oHVB*c&Z3%hVJ=qIK4*nRuqRhLE;CvoH4USVSxFRU^Z3>DqABHu(( zH*EWII4Um(*`~LO)t%1*Efq58IZv|;R4H4(?2+wLxHx2oBJPOtE0NwE7|lQF*YGv; zh2;_gl9~T>SjmT|ZhjTxu6TC-&FA-3wjPP%y@BJEKYCT{g3lQ6NDzr?$+?;a17pL& zx%v6|HRB_AfLZ7DzfwEyMDY4}%%G>=iWRp)>a2w0gEF_mFc*;#Pak3DPW+b*$A3!< zvtT+eN3g%|fw4)dvZ|{Z_76|o<{i&p8JOsyPi@8t0wslA`_$Ek;(T+6oVz0D;yZ<9 z^&=HR5~VD6Uucn@D<ikg>F$KhVc`R@bBoz32mNwO@_;yY;dt(u^6Wn-_)L7^LYjvS zr_L{ak_Ux;Fn)^EXVyhR5vk~c<1uZFsyCxy6;DqzVt3*gB2P0@wrb7T7M*z6Ztvt* z+n?wkWv!BAypxXu97bQ`gRMQro@FA-HvraOo4dAlNqd>`iqB_WbcU_DtPMgdAG)kI zwD`(2nsFx1qDE2lwpB`Uxk}3R?2WOS@B$_B0La}~$W9z&Cl<0D>-to2Mn8M^o6$_1 zeeSAW@!K}HqT>aLb8SLb#-2z;kz07EK~35aE?HS*6bBzq0RycT$qCmd@3oHs<QENG z_;>@DKMd>IB&1xy1O)185k#&i2Zl!>gueW0-*)RZRJtFh-KP3;XF@_=>F(p<sjvZE zV`G0<?hT+R>^^A9=gQPpF@rMepQ&GU@(P{mKqr`z&_$N=Vq6(HHGc6^(6wbO3&lH5 zDNfxUt3lYk7AzE=D;|FnV(^s7uE!&fb0lZoBWYVxxw{6@EsXd`da=az4KJ=GlSB%B zECu&zXcgH;Y`)G{3JD{G{29$=%YKYN%EwY(t_I5zsIw}R^U6o8byhJ>#b-xVxHpwQ z;MnU_&@Z@aGtoPoFXDV=l_+N6^iSQBf9hsKlG28xQ_gLC&xpMtXp+#SFO$pA-G~5& zkb!w(F9&)3T$S)Gol2{AI|rxe_Hktmd8g><-z%fZPMXpM-jlrhF*mt~0~d0|v0rLQ z2}iYOb3X=)iTqfA6)y)cA$+tBujphjiz)>25qsTLjQVV>B$E;Bf;*jGHSRz?8ddBY zWZv-#tLBexqBe*DhMH@fo3jz&!u&3!#D?8VD4siO{c@RH*o$0#ZH~HfJm3_Ceb$PZ zE?;@x=v44<Ty^5t=iA$z${Jvm($6g(*JRcS>eMZP>V=T_Rzl5k&nR{W8$YNpaqVk6 z=gVj32{EX5M@kFD!_4b6o1$mGv2|3APD)6H!AL!tTY9`xSOK$1Rxpls`!)yabJ$Zc zpJBt|#&v%Z^lK^3B18qI2n?ZIV~bF%qi}($K!KR3Nz5H<8-rFOW!q$!YfYD3cSZP@ zx`|e8@y&^h7L&cLg`5<0Qe`2ukYfEjZ$Oks;@Hx#icysP-H-j7rN)N&MKF&H1$Xo_ zNOP~Q?RtfNW$G=U$pxfx$-Z6DQr(_$l*Y~oTswbhvvhWyr7a_<nE-BIXQx<g`wIPB z**Q7)wlasUTPsiHyN<4^WCK;m=njIy-n3COrQvR6gI9wm!dYGQ=)0o1`Q#0pp0e0( zk@AnR*0k~4vq!piT?%}Khzbz4*I+1cGThKX`<(Dqz|7<7Jxl_`)t<kpLUx4G%6tgw zOt28XK2)QXtk1z9eTtV<pvJr^am2AQ_2GlKmY}mWFT1ND#I%QHrRSNWhU!*&ed&V^ zx7F!<a~f+NCAZ&eLQjgX9;8TM1Vrq&y#HCre{JQM!)%pQ&x`qjJ>E!8MdUGQ#&X^n zi?lf-*O!;FuD@!vK0X{(9@&kTO<X9~(!9Ho$Nns5T=TE%qZ{6P%##Jm@~PuFt*W-V zSRI6qSSVdjrG}eB^;sQWsu)Mp_#ce0$nPb^6zFzaWeN?@#BhCLo8x4a3VaGuST!bA ztS05XWV#ZW#(GTmw~=ScuIt;-w;ZHM{+?E!qkiUB$cUvr+m%1!dqiw)1!B_xw&QJ- z6e$h^L4GW)TAUJXpKHgAmt4Us=vbKL72ogV6W%X@pc6=;1k6s^K&Nt9k5q*lRGnBm z7DC^c8<|{8Xiy=K*;I@73fKhI-3{Yy%&%@I&egwG-WpHrCy!eTmW7--k5BJw8%&)1 zIU{q>1-rH~<Lq4zWs9aVD*hbjs(xEPa#67J`B#u0ICT{7)!OexR>ExKUQHyJl4alV zpZ?^k7VvP^Q{b_nK1XH48>RMSn0_CrH+x#fTiNNcYHfR8ovp2X`HDj4Fp}m#kSh&a z8Pq6nBHA}LwovO6Ti@C?MlG3vz@h6x@w&IU7_Zj7PqpG+^{Yn1qN!&Xb;j;6#d6C+ zHbE({(iXE@^p7X6%XSOZ6buly&g^4gJ_S4X#O4rRJkOoAIeECOa@VHw6MH+9XUdHY zX?$*N4s$w>M-$Ww0Kj)L&=j-I%d0EMRhGoi$duJ_Ir{i`%=DrobS;EE*flS{m!Z$u z|EG!g8E&7wae+v6MuB^CCoT7IRn`u|a)Lx`u2SRbM3k;AYS=U9p)<|vHAdm8!rKkG zTcP^S<Gr@O3&jb+KH?Q<N^+@C1Z02>KFT#$Jbx<X9W3b@XSzZE_XDc*S5eYPZw`S7 zWH;F0>AFLuwMc;o<+sP#rRm`zX`=-ndn$`JyhIGPi~HDc<H0O)YyGD3*yNWkU!#u2 zv^O^au=w}7mT_2)ZHH8%I#nTg=7p$Nd3m9vSPQQ!HrYE#Nx!n0HnuBVO9oHdy|t6@ zdWVc(rsvi&4;SF|j7?RmOKo!RX?f`eS{W*?F|LL3itsjSl!)(yyBSy8t>6K2grK7q z*|%mJq^q6l6=o83IZxSwO|&Y@T7_ciZ^gNmC(f0>eisRU6V{R3cMGZ|Tl6|9;w3EZ zYJY5GE|P4Y<Ta;NZs7|;upF;5R-P-5$o5Ta?q+Z3IywMNo${daj0vyG(r1`48L8cK z90RxWwz<)$PE9JLU7v@IZAXoWeT!A%R7E<d4Ya84y<{YlUa>p{O40YSTA@7F^QpG) z%O-^xH;t+sCUNbO6s(GJ+S4qq6<k2>#kK0PViy-~=o~D^w&OI1GizQq4z%N%UY?f) z<n*Vy{8V8%CrRDwC|#Cihiw_;(_QV4wzn3p$+Ktg6*=@2cVBFY=;o)ZD1{|#ZU0`# zdGk;+&J_n>qrm}y!+Otyne4O@bcAQc%i_T>+RM0weHQL``de0p5!QlyqsSPOtZa*Z z?ddKZzg>e+bkMR!+VY3TvUqc$my}%0n>t3@2|Qih&%2!%`Eo5HlF#&`HIsBl#dMz! z=I41yBki|JX|KwYlZ)Qe73~U5O_h~DWhx)$E!R-4Om%8=6t0z{+^;cKg@_g5z;$go zxN}K1@b#*)JyHtS8x?Ac_Vz?9j)du0XaN4F)S#oG;{z<HjDUn1Y41AK0P(zw_pXfj zv~=JQC{ly=Fn+#OX)x$%(AEK~`ZJnqldj}?5D+Zy#l1b3o96{z_N!igTk;m3Cv^JD zf@NTQG5)w2UOii}yWXYP_fmJuJE5z<9(K&fs^MZ*gA()N+MP?EJV>A|G~x`9Q0<Dg zs*8?^i?fT4bBam1%ONVLpo7+$g2Y(9<LK<JP%P-5JGPq=ES09*Z;&pe;F*ZhNElX; zi_k{mT_wlz3R>8!9Mt%<W_lG`^iGCGf<;^Zx@b$32J{%rm7UA&IZtZE?STvtM|tM% zZZPdy{5aL4()vZ3(a@7Z_WtunBDL~MODe%)DWMU&8l%wHu19&R^mHBS-g6GZ(R;7s z#r`ZpGd4OcILT;3Qg_>3yLlRPwvY+BYZElg#@x;$Q0|xI2GP7zTgS<!HpQ+yoYBi_ z;D}eEAJ4;KOo8{40<^_Su=o22zmiU?$J9@Xu3|JrNXGVK=0Rx?Qmt3}>bmC8u~(9{ z{o2KonJ1dg<5uq)YnNAW067W}r;^dD-l+j+gI<-jOD5pJE|p&%f@*X9^;S>KxIl{U z;Ex);a-#uQiL^X=6+t9rX8F=VoV6z_Wz7f9j#JQYOO^+*S;37bSE5(a)R&=brd!@6 zTKl^@531b;pjUO!{NbDu1#>AkH)5kF@yl)uUsfbTSB?)<3#2@)i*`TXE>BwTv`yxy zGp{Z3FvPVOmn)gb3OSq4COn_dkPdE86uw<UM}bpi!D)P8cO1p;(^`LS+x<76j)@XP z*EI(jG+-3aZVS~OzpN7KF_Lj8n=f>QwCiz@ZOHUw*l8%I^Wf@deY(3P8p|5+%+?eV zaP)L>$;wP+T7#jb)T1r+i&x3!$4WN44$Hv5(0DeWIVTG>j3Qd}!u+Yfs2<VCJ}{HG zOMr5tE!8X^hL!K+cH1WM)mddEx7U=HvpM_vrg_P5pUppEz&#^NrB<6-7|`lhe{47W zvw5s`dsa}}g9m6jyk?w_$i@;Di9<)2Q?0Jls_tnq6fDPT)BT%P76TL9x%CPocQ&*g z>i-6(wxp^AUrlgLV!yTQ@2zc|;i;B8=tm^Yrl4u45-#J!w@B9du{$y)cXzRsq4wgu zQ$Oja_DwlIiW1y6b!F@>XVl-iHH8>ieV)dXyGJ{vd}5hxV8>rgGqS-lgsy{T5T0W+ z#M(Y~3kgrrz2q5m>kh$J5ii$sPR0g!;sJrpAjr+~uDfN&I%hSnle5qT#Cc05PtW-B zlXu(4w$5WkIZ;R7ptI1|%^x5nXT>`2%|2!}qC?Tk2lS|_tnT?aDCgTY6B7tMCS1ea z^k*ksR*MOp4q6+T4qrNb6Tqmbo-RaTIaOTL%OD)?zE+XKm5ZRAA|L5_V*NwZNaUC4 zL9Hz1UY(NvJhjzaauEshmml521z|}L6O^@az`8cwT|$804`i1n$?Bqu56nGtId9d9 zHjSYY$F%Jq)+>`UxpNw{NoNM~CiS|$&>?o!O5armiK%k!PG{!1$Y^+T*E&>NdtF2- zZT1w{YqpM=M#VWYAFqWD_{lZT*RfaM`_QGW#z?kL^~JIV0mi(`(U9w1?`^k46~)co zpl;#s3)#M&7`?(XK21(8&K*nb{8CHNcnwH#j%ULgXI~`Z&d7_L`zv6#$pNMrgXKWu z+~v?Ew$Q)Ner>HaH06+`{X>1}uP*XukhY5I?Qcg3TBrT%-~UFn6!(#MO5~eOtdRJ6 zJ~}&&cI<I8*^Rwg;&_bU_FXsS`fX`5;4ANM7z^DMi8DPCj1Hh&b|d@Zr|+rgIrl&q zrnKgn%v)y_Rb<ZitO`*)k|OFfoLDUXphsi6cs3&ftSjMCA&>hSH8*$~(%)WdNPn&2 zTcpMLw(k77_8X=+)4X0|tX^5DlnL)o&xW_%cRh|)C%AV;wJnP>Nb0J&HjT2)CM-yN ztGLg?%9FLc3$I)nd$4a`se0~c3DlqUM7uA~oGB$WK6LJ&3_%1T+uGLT3GSEpc}hBE z&Yo$mMTnWI^kkaXJzMOO=Jx1_NUF&4l9n}PvZ;&Lu$2!Zd^}+|;0@QvH$VMB2&CT! z(a7ITrzDFuYn!NSL<At)B-Pb^I$xRS#ah&fxX*G!*1mb!yzzV`+kQI~tQkT5@~d9O zS|CZ4C9p7sVI-)O)blPU{7h6jW@+kVR=MHZc%hfo391+t-epNwJ+MfW@8oncx#uL8 z(RbPk>$h(3ggoWr+WH^{A8ZhXX12CTch^G7xt_=?b&uvg&++<P{PW1XFHu|+`2+x3 zZ-7Nvu1tAGaQj^fHaoRFg$r>-cY9^h6I;WpbXxoKV5ojPo9_08Oxt{5(41=L!ew9! z+MbRsqPv`_OCd5-7RwUaQ17-8@Oq0tH+66z^0+P*dWxs98u>?_HDbWs^M=sv>nw?= zliZ&?v08gL?&Ahc2YV8)-HS$@eYmbVE!UnU_tS_Z*Vx~8J)-7|l~kb+*>(UJWxiG| z-<JiMz3&x}_iEBK>LVt?@!Yv5VvKHNzJT<hvG$QyBAnKI;ug}7MXhv&I=I1?T_N7E zP<KjOcXuOB|3buSzz0i=MwM>3(xno<E4%amo&~s&L5@MQOn78dmmhskaf%x8ESM!u z=yH^B)N4SRwJvdZ%v3qspF|1J`SL7I?%-~))JQ^I`w`uiZ!R_{0c&v0)bwb@JGJp@ z5o#;l1J2_anfyrSlK`#g2PwiB4P$|oIlF-fCBJVp)K|gBx3GP1^-?J8Eu6JSIYIS6 z@bxZzZ0ZTg+GA7_%_XuKv&L17{Pq0JfOFmtq3F!a2Zo-lZ)#RdGe$4MLi&mWS<fo{ zCI%p?8<b-^Eb8N3`8OjU|JpGQ-%84;?!C;jev|U^0)Ycmf}5{Eb<2%Z6|~EVu1B70 zm?EAO5;(^P=QE8T6S3{WKIq<a+oK=9qnQ@*WgC3goJ}4>XGntOJ(c3wd%C_&^J4gN z7=gz+`z?`ag9DUjbA>I>(xR*kfcM3nnvBTu5ty4uzmDB<;cCU>d_>U$1;XPx#EGNe z=GTvuon=Nfbd&ju)=Xn<%C$TQW@DFa_OGTafZAPfnqy#R4%n8O(?;c7!q`YcyPT0A zD;tTz!gA|PbX9!o+?@QEE$X$FJ|K=?%(6i@vO-Da2@lRF(;R0ipPm9PX(R)vq$!-m zA40J$(W}2!D|mG5hU45s`(wCHc`!;xn;5HF$V|0IUTO9H5d7)lY_0aOe00f>A)lXV z=EMzP^s~P2eH^pcTI7d=ouSW$+9XO}(~eCWcT5L+*9mH^&mf5-<w8R{a7));W*c1I zI|n+Y=Ud15`%XGKwP#YeS>M-QJEi>6GarZ{@d@C_HP;cw{|3!2@=)r_@oc|PdJcEY z4`@W(fXzZn9H!i8{OqM^{~o_Gh1=H}6UOh2`l?_*B_<`()QJP>my;m0+4Rb^M!lFX zqpK>#GBwgle!;U?>UN-8qxPo-Th6+*@gXe)si-~5E<<QS%g4L4N^;I8(0jW;UTJ5{ zeN!E$Obr@7UAy5zE31xi4@J1>d$`m5B{@^?L4K!GphrVt{09Y}p3z8Ka7Fvo<Sw8l zb{&L_v;Bpv1K3r4twB}cXu>Wx=B+FjzIUI4h{8l~jfuPc`w59N(&Orvtj_2ZkS@E* z9lF*$j_F?kdC@{@jJK@bb#ya9zYc2_7jJ#|Am89LSHE`G#}eyLCw#Z5PpCjM#w5-k z-Y>S+B2z*R<XyLE-y~IGzOSm!FbO^|>0_FJ`Gv@r3d3zNrX>^oe%0lb2Kbk<-bqki z=eZQHYIM38btyRcp4i9%dF4V{jJGV`O|Pl^DO$g0wuZU#=oxngmulQcP^jaC2G`zp z@^TX5@?<`Kvl0i0>$nY)Z3~a@>0@4ZCoS<_Zjwxy5@Vtp&x@VPi&L)5d7Vmzh_M-b z&>l3Gn0r#@{$6xUbe#3QQ1f0l%Np{~kM;FT5?ZAP%-Ii(GDb%Q$5)2}f47?!O!bi> zvXo87wu?i+;jNsPBg&pdl-|s0M0E_ZAl`5u4Ucl1`Dz6E*n9VS{kxh=>8H!>F35d) zU)J1hp%EPWSmHdujt;UnyEB&Tq`EuZ!5gvW?5mb7P|fwSLLt772}{#P5qKv|nv<uy z+w+kCk}Lb6sc}pzu0>mI^+`vqf5-W%yvg#r_m+1w5@)MlLy_fhO_~rq+@>#**GIC3 z-k&So4V!-H8LZgwAsRJqOcK^zD{L%w(op;Uc!#ELUx|7*;8k{RK!Mr9vyTH8zYkeR zaGUt43D>C91ogLUCmsnLbtl$~yPOQ=A|&p@GgJJNv^U0;h?%K=6u6JQ;MYF*iG@G6 zMXmlVCI#}YcL8MXNK{}W;$mZL>d>+!1l<NMWfRArs~-F~ckQzg;cT{NNh|fW_g;dp zP`9~0>Vcu_#^gbb`Du`$Y^o|FFSFm(EARgaD-;g~XEBMXV*#=H1E=iWqU2A^#NU5` zjp#=SIp?j5Pq%uFe@sGffG%)P)5PzYx0Bw8T!k0bL6Yh}u$Jw}x#nqT4cE{V4<>CG zm55Z|E3;>b6k5m{-cDL`tXC~F{T|oN)m0ar!v>IPsw;%D3Gd}{i=7y|85F?vFn#+o z9z9jg-K1e(#cwYDau~}^Je}S}h*%5>e>J8DzVlGv;0Kx)xSxB@RcyF#JI(V#S!-f2 z=)7OCDMK^s0b2B`jUr_`%n6TTtCyVObQUu6oZ&@UDmq-cbHYI7(?5$8b-MX37o6D- zjWbTa!N13C<xSH*PDF_)J0`;p94~^-PMtOTVXCXO87%n{;su69d|R8{Y_+FF+%z?h z0aks+84{p%uvXa~0ZU2K(5*KNxL4B#y~m&iZg??1T^j|B7nEnk<4sK1^cHDTT_YhL zZeu=uKeA>?6_sdq=M7l5#HH@B*Sv<fP^qG|0N?0B<1V)ka*|Y==#q~6XZ2SZsiL=K z>2-V9TvN<h?pGrk&}z?XSD*a7>^P0t=PTGe<>X;MAv}41=#AAB=^r!gz4~MD)Z%8% zzH7MHAZ$5CA{uV{la`=<nDYCBp7^zK?z70eKTAC%6tg9#yXW1u#u{-;cQtu07c*6N z&i0-`z`n^+Ki-I2V0A~%yhw<mGV=(kW%MN7zTeji_csCXAQ+rET02_{Sw@+bCbTQA zXnnePFs(vbRNl33rwtL8`Uk3~hb8nYV1TnZ0-pbwgR8h9Cvh-=Yu#?f!Sbm(OJ5_o z1(21B11M7ce7ky`fnj^=dL^2>IXi@R8?T4|E&O>6D)}-Jc`=w>tv1pM&u4;tf`eZd zki0qROANIBJ=Q+orpG`F_!bHWRo@;tcSS0?@yH(}W2=2eb}4lnk64)YwJ`Ilg@=o} zslVsaq%naTYq69qry|gzmVzBx#y@a7>9lFr4DqT{(!@!A<6tuot+#yr#YO_sFjvI` z9G=QR(;zqqnlW6Ab=P?$ps`wyZqbHx)hB1uu8$?&E{x<s7WJp-W#iQ>tIa1G3b<S? z^eogA_)RRV7fZMp@fgO>r013Dw&hCXFF#9DHxki`%gBAvJG78|%+7n;y$ZaEc*}m` zpEtQ-e=<pT*^W-5;Y-C0oCXs~GJFox#9PaOAdd@WmnG)KkTwTezu+6}NC;4HH!L`L z<2u=(jOT^^O~UQ0#uzI!$0DTeY2fzs_<TMK1zNXjsuO3PGz_~OTprkr)13dMp{GX6 zQA)!ZU;jZeDJh`vF7rcNKoSPdIq9FBpo_QAIs3lHVFCBOFcxjyglHe+A5z2+dz!Ai z(_7r%en;v`_D<TEer&ecLE`Z}s3)TTHXz4Q==a(z->^*pYcNl~2+{S^>TpBE*RTu; z{4N16he%dfqjqjx`8oEAzrhCr@BA}s7BuTpdB2WCQ3^aOOGx7h&*pHx^EjajCf3bK z8aylNN#wpZCRH{6&v8;Ho~n-BCgB&H_Y|V+!c)z20E>o;jjZ<P29NC|#C!}^pHq}q z;`nBbb^gM{=QrLQpgAwVrd|!NV;@Cm@}qNE;u{`8S&6+hRBfWa#-vIc>3o1$H??1k zfXBdhjzCjp5rkZpE`pLrfuV(1+3axBxRzIK^8R1~LeR_DEbtmhkvM#V9Dn*d8rF!M z87QX#uQdWe{A-^T#(8ZC)*N)JZuUc|kmXi8a~$Z8kCS{Hai95_yXLC~6T&l5Xj2WN z?G1fsy1{ORW$qdTBZKUa$Sn1eZVO4CDc55WTay4cceSDB;!*ZK=npTfp@q)H7Y_F) z@Bl^$kjJ%#u90qXeuKc|N7FOx+62mKPQ>432)<o(l<@Fr2mMWEz1$C?7^(TszCAN& z;U$*5r-i7Tz<FgZ)PB~n7rK6#O{FNUI5Op!pwHGMcG4bK2|Q-JWOU+S*%f^B0K@^H z)pecA4gKU?anVA13mTj}dBSr!lzd1DgUJB7`|f`C<`ZY0yPRWnJl?<a?tvG98>>Zc zA$?8~Eh8*D-2|%eE!IXh#2#Gxha~u&O-<lGY~DGqbZl`(q+DU1MeX1KCX8TLRj~LK z61f$zY0pJ_{B;(|7wjG0r#vhl?`QHmQANcvVu0iESwSgELQ4;+%t^s6s5x{5Fmm)n zt&R6Ac$JVuLS>eQD(RSt`yB^Oc~KSpjM(nK_a)0FCTb&0cS6n=zIP%3fbSa^9lEN3 z69aU`M%bN4ryR$<&?k)7%bLp_P4QfCGN$>lbV5q$INX$iedOG8e7u9^p}55Re7DC@ zZFC{Og@z>oenn5m#Jy*Enm~$Cr&p;}M5ddT-MmO0-`M$@GXt6FW?|=-2AW90QA3gd zvOiyp6~54?OBN3fc)q$r*IIA=yl(=uOUJ@J<|cU9i6GVhS%;M!TIz4+#R8vsIoM<y z6?fq2!=L#SqfBcucytebV2O=I5O?T4q6XO{dFZbEVV$VgUSe8Pfj9tI9RbN;4+zV! zvafhyK(2g-;OTXh8QfhDzU+)1$QKxiY9dQBwM7iXLKk~NKi)LNe28jsW9Q&--r(gb z!n|uEW|};I7ZROqzu~8spxp4HjA)S@-ypR{9qzyV!SW$7a6tq1pm~9Q0g_nsUwFaH zbXI!o-xMrPpRN8cO5RH^fgFQ>ri{-QFJ}pMyA3BFQ+^YQ=c!h2Zl>cBKRM7~)bgmX zUpLAv1i8G;Ws{mU;;lEks+SBFHnx-Y#^y5+xN#q}qb2jva5XbFnWB3CyD3qKU&AY* z^r^nE(~LH3al3~VJ$9*4fJ^++Q9u8i<q<W`H!Yn4_2v&(YmN<N%N7lu>%Jair(W#k zG^`{R<g{0(F~xi~8>#)Dtcd`j&k}Puk}XbpXR?qNFWH^VHofLamIBuq4N<xm{qUe@ zlE_(B*?S>qoUA|)Q#&Zvwgn1Sa=F0U2O#Fj#BeX7NVc*r_s_7ZA(4zKpvJ&g5KLb$ zx9}Fm;>#%WM+Hyu{)C!0)?b*O{_N(%uzM#ZaKEhh`4018sHHr+Gp2ekr-1By8l246 zM&>hL@$;_|Ez(OfsT>RmLeFn|rzQ-N;Q*kYUw4*kd+kK+@^YO~K#rWne5bJ?x1e(2 zTjMh8=RuijnD#46;r#AMf^?tcqL$PJ&g~haxTSfaoe~e^VsqdfJN!qVL?&zX7YvSq zEgupBte{_SrkY@5<AoP=7DGZ;GEf;48l1iMimg1x)tk@k-e{X2@p0}><&?e)kpV~d z+lH<`bX_*9weKD!3bPCc$C&2&;X2=Ygg{PDUw#QdHF@3qaT^E(t(UGiXfm1eTkYwl zCk<`Mm^<Q<B?yNl746(Y8@8Du&W)Bnkgw@tx(cR$00ph(M#1tE+K}GrfvX?=KV52$ zrLf;i)(}@d75h58h7d2@XL!JGu<V!-g=S|u8C~fkrshI}G8*;=A{FfvB8MQPSY@Uf z1>(NLi%;^Nzt0HexO>!%Ci#N1x5+t`!20gxqu+t#B6H=CWK=Te9DTYY2b-&Sm~k67 z@aOe92Y<nPGi=*w>K<IEVggMNRg!F2Lird~@lc@mwT)*7-(y55F7QnwK3j-~E24lN zc+gd;>2uJ9{e^@nX_K8u*Xq!=b6wzF9yRk76xMNH%k>83x&%1|96ofkHxyW<!L|y0 zw-EI?2!alQ!zpp!e)gT|EK=Ze-84!x6|#N$AvkR~_Omef=mR<X^UndlFj@&tMkm6- zOM{u*z>iSSr5t8!+aaemtpnQIcc*vqGleu5LVP;vRl!@#t!sI|H4yi4fh;YaE|sqG zxkR#sSf?>UdVd3p@|88&wtL1se4nQmD%1rr>xIO96hQAQaLP!q0XKoQVpvEV2|M{( z6S!qlRF`u8fd~LM9&ugDhxn7qG|zvTk_DRc#HQFLBpdZv^S=;OV9`6}1RtRwS<cu? z1h-2D6XizdMJTIRzwrQfu=!bJKYXdWuyDcBJ<|Y&iT4NCh&)bl3%@RNuYQZVs&qK$ zt2pjc;N}$xkyr}$X~G7OKjwu@4}`Z^thzL4Da}ctJOpiOJ$ncCt>fE`b0G9Yz=~6k zFDQPPwrw|CZ1yDtLl=aT@?!sfgY6k1P2$v`5R<!=U_?S@`nV>}cm5u?)v7f09oyH@ zw<3j=Ci;=3;BDH=PaP4NrS%`TIj-QDjg5`??}&h`yI_fl81avs&j^QcYu#a(J{x<h zcTJH#6DW9sqcCxwlTDFUipI!*I-}NktP4PQD-P5-YNYnp_%rWuf|%lAFl$9tC-6R- z{L0$$zudPlRkX1N_%A`gE($s9%@(blozu~Nyq6NUA<rJ(6)|$9f_b+#d%61XN8o6X zZdb8=+<lda8**Vn$8o8b54%(*e7K;Ch-V9h&pM2sf?TkMw`YS+aWXv0`ec3MKaEXf z%JfDltNr!cTqM=sFBf9@DPqf?UG@-Qe?6)BO5D$X+p|^AD!yK!%rp<71w3G-ICh&E z_%4cxHc(wt)r*ID^<qDP%^}0_4o*XWDdjt8PG!=>13@W(Asa;Q;r&MJ;DpC7+v*?< zkCurqblhM38m#u^pXXY+2K`pj@mbPV>=QC96RfCn1MGN?!I3^rc*|m#-+Od3a&6Y9 z!K+!Kko}pQl*e);OIwr{iDIocR(EV+z#EkP>iPiOeJDzIdh#q#5iRYz52qsAEYF|V zPA1lU@ccJP86$Y1kT+X)GD!@4(~9DovbCZ|$L!W}R;Kom-q97*KM>zKu+p!}y!gvz zzbPw{I8$-}L)iuW#tR&}et>Sk0(@eyHur)F8Jv;w&6Mbdhhj%ft<U(?%|v}G{i%m* zkC7b0d(XZCO|NN?(J309Lmc4JUuS2EF@eA_cZ>YDc)Etxpc;k#(G6Tjd#D!N0P@Z) z1}{(@<aS_Sg>b-6HrpdD(~Jnp8m@T9R6-l17-Hd8kGuP67J?pmm|?6kJ|Guu5r%C` zi=A=xguOe7HhQ`iF5=u0CoN7pI6!E?yztA|*Yn}?X8?oowLjjW{MxWK(4HH}U>XT( ziEq-`dlmEk!xCUmmAbfF&}z4-HfM%UMGY{_r@C(}Fg+{3h3zmBJ#S5%s&_e5YoehE zE(_Ix2bAt}hpybKFDC%xIKh-bMTO72*c{q*JU*75x@74I3-wvqrL^-rY5BXZ<JjSe zJGqMwd@k8|jFF#A!ESVmKzz;>pe3KReg|Frg<~&+)#fa!w%6$d*@Z*_2BvFG8KtN; z!OgNRcs(y9a#SaeG?Uy={-Z&!;^P?fyO6vvLmHCcAKifyxMUN{gNgj9Ct>WIa-|-u zp8lR_11I+KrC2;V_=SUU+Tt!?wtBq)a7S%ooOfJKR0y(Z7A_BDWtE*1a|H()#G8MP z#T!d}eg?|2j^)Kf3Omlq)>?Mo{p`Uk$(R7A$9i-?yUs(-ZqWk_%CiQl;O#+}z+Ii4 z{G7Tq^5hGaTUkO{?fqLRCs-ZfT=C{9F|Y5E^Qq*=UgBAcYPp#$>YNc)R(Dsclr^@o z?+zM2?$+*$HbV!<`Mml&Spi(u=42T~txTEe)yZ;p;fTGm3W0fq!&JOiwOxny@A3ZK zeur@Dy`ym(NBdm?_S`3N3i`iZE4}^BAay?q_(Jylt)R%cl3>bjsE6QWAcM<+*!kSK z2~>hhOM$21BtTmR9<bpxfW(X&h4fDE+$;B4fO68LUyj11`Mnui`t6O=zPx(vcTz(2 zM}A3^km`MI`YKua12bAPz1GsFhUQi!ANfUYzIR@XNeUq4*q~V2+}-I+91^$plYd*a zLB{NTW{#Tf2vBklmXU#dB?s=`2a0!=lip#-q`Kt4sgJr?F=737u%8f2h6uXq*WM5< zQ#3_Ei8u*#S18sHj}?&S!LW?Bu#9{jtGiRf#3FT6tlGS541;~neiKNN1juaZr=FFF z9;(*3aH+O%N_=P%BVngkMSW?L&Qiot3*<M~lkTJy4>aoFFxR^je+M+ZczO};h$Y3W z6fb<B88r*FG1Z?74G~LGU94g|=s4q@u!lu`$)h_W0jQ}1OVAhGKX%0EcQ&DYC5!#d zSBFt!61ipN1pPz0{71QIZM)SNyn6Q#9COK4MXH+nGC8G(9EL_0?>uic_j<=dFLeK0 z<ifumyF)+f8HaPbhyd!LH{V>HZ;L+hS~AUedPH#1F9qPXJbH|xMg~jBnIAzn(oqVd z?^v2=kqdJE`_!;XkRM#d0$fkvK^$|P-hd)*<LP1e2=vB6B+ag(%qa6Dz?w;SFnA<b zmb*gyXN@6$WVlVuoIC(Iy)dRX71Vu#CD)|HGS`#JKXyF4_qPt-S#j@}Nv-nfdgF=w zkINnG?eeEE*u$*nfy;QLBRG@ztajh=BheG@uy@wVpyUf;wSSriaNkD`+%}hDV1J}7 z3)zOJyB#gO>M9to-M@|GoPBmYl6N&Ufk**H=CUr<PoRZmPw!`r|GfcF!)!DZ{p?Sb z4sivKdpEN=G~qsb2N};svVOmeO$%W79T|W_h1=2}Y}!=8dd!puKYIQUyX{5QYc!~n z^vDf#SL=g6$PyJO_1G34PRl1MYVmiagG6AgGyIMyGh*ilKAO&=W*9h&LpV}8?f=lR zl+ZPX(PVWz*O8MM_4((Ty)qVwps)QFWs#VL>NCyBA+Ln??!f8&jwk1<Skfq7;PY*J z-l&5>uXP}&@%YLh3B0(%4nu$!IA3l?AFjj2uPCYHh+W~gNV4!u_GGm<uzITC4TvXw z0A%MtswwbQ#m*Z=u0Q3UOB#{y4D8wN+X*-TR70VVfL%tD{+A@VH_@ALZYGD_*$7n! z)VKC-;9ys(SNxLY-kU4fA?$}t716=0`JQs%+E2g%m&$hhdmohgz<U<UMVy7Ff+QZ@ zz)1D@C>8I3@Hf1&9ery=aJY^0_>84Jh7T%lVFe~uFql{dWz19O>_XNAigKctd~u)H zc~IMxaC+}IV>88uDQ&$I7_Zm4BtLvYD!(|~i+UK?{1Au==o!J#Oraz)At!Jd2Jg`v z?9BkQHf#se+rIF(z2DL0qtB|qY(eBkkUYPDSoXiDHeW~eHQ%leMOH)IqE40s+AD~Q zSr5xSIhyTNF}iDE8tAp}QXz`f&7f8WZs6T)i#3~uLhQD>pg6UHSkgDZ&A6|8k~dbS zb@~#8QQehr(w<I9*<^?Nc)<qNw@m%__$tR_WkwbM1+T-E(a-s;g!<2r{7Q`!(}ag{ zB;f?sJv<I4js+`bSH~RE8COy4oBgX8k0*_yDF%?CX7}EOZinR!Y>Ay=t7L9SxiF7) zN#Ih6S*$50)j2hFOki;Bq)rO~r?HNq{f)BoMJGoHHFYJ)3*d`Q8xllsnBv6y)f<5t zH{;D$5~@)Y4s2Pl$6lw9UNK}Y)ouR?;`yHj4!Dfq_cvQZZ*vi#1dmEK`ZNVA=YXLn zR{vz^&y3J-SUG2&J+z;ktYLB*%?C&h(ZGW6IaaEBGu-Tcrp~|Ic=T={tvR*je6gJf zQ%Ima3!>8?64NvN(z@{oDv4Ct{fjNkWi8Kcd)Tz`T$PYPGU_KFvs9tCxG+W~hg10z zKAuSUUBLY!n-|MQ#*oln`gu(hC&yRr=&#bkxDGwFI=2~K;1``(=UpuKA8RqU!!!=2 zqMgZaAumw1<F)IJR~&}}99{?56iyXFR=XPo=oeU0GJqtm3rj}VYh#F*-cLGQ5=fKm zE0Hm2EhM;bJtXh#-7XCKk~dX`BPqk(Ztq+lq$yU?62^eay_F{5?{nhJ_U=~2nDz`B zzd#h8a?ybGim~KpRmG)hAl$;qL=0m}5<6KB<<(O#d<F^VpXBhbQ7t0xhr>^Owv>dB z!hY@>x)tMK^n3qBUrO=ofidbXzSAjxL9J<<SSzKO{6Wg}Hp#;Qv$HxVnfcV~y&h!d zuS6hd1n0}VzEUpQRP0`;OE(t38uh12Ak33cyk@JKRU440Cs`cBW#kbLTgi>Ey*A<J zKNDIs`LJv`BC5@i45$rmmWCQBzvaY%ZEi)y-j`<tok)eI3Iyz~G+Pc{DY0Zl9@8*J zno8~lNJdhZ?<!#4Gm9ZEJ57Y@l$rj;kMb7{nH&9AODe`>{;vU5x-gx?pvznJKBtQk zd@hHBpH1aeJtYl|<LH?`xF5<>O=VUItkgZF2?W)@S=IvjpXar3c=sq4Ptx=f!y$-P zqJ{Oh#Q;m*0xa+9Ogajk>x*Cy?`K-KfmvAD&|z}P#Z{y5T4I`7og;4rjF-znK}f~e zs;N*Y@&KAI#fEJ$5Wj!uPGpTxA$&B8^?re4V`ZPE4mBrM57hN1Mj)N-4BhieZ=IK1 z$qG@c;z;6rU|G!n3je4v6rf7=UsmM7l;4>A-QSHlydQzqR4XMTO`ARCGbd3}Re##F zYk?&$f3eUM1vTdtB|fy8`w5_vDI~dd??zmbDlrI;S~JTnri@mtcZ>(zu@|k9p};>i z{@T?abJ47{Frq_4t^VvS2-4|k3tudAKr!xZ*Im=Ol4bwaa|@;O@M*h(`a`1RtP)8} zg!0YTiqY5gDV^?}?a4y1EmpVhQ}jumvOjfgF|K9bOYyR!-%%wvK%gn*p~K#e%bble zKA37v*RFy++fZ3C!wCPO?!XXmNqSXLO8j0Dy!O<~ugC+eYz#9R>Kkr@%g^wAdVYCb zB28u*>v8f6ZOVI(#KoSk^(XYrOky>eA0UWW_~@e+etOvylZSY-n6C@Z`WKMaf2VM_ z-2y*2;J?oWa6Ula#jhfzJHm;f89gkkga^*geoqaGZJG7L;+Mae`74iIFad#e_yDMc zS#@Cg9^hgP7ALVY)N;2fe}>#cpG=RVrtHN(7X1wQcF}yGBUZmD@mVqZKLE5`pO+1S zd0FP1`_OJE72`YHHa+~%&!ca^zA(QQyw8`oFp9~>nDT<j9cn3?1KL9R^v5g6rP8#H zk?wR5<+qna9Lt=*7Wb&q$a}wy>VLR>bDelqr+<&2ffYfWs#v_Ol?-xtL{a`mUSo3F zUz8@4!rZE&C?SG72XFHwu^QtwDUCYmxJ+ZmZpz^}A#C4|ZB)RJBX<Mn#HMiYx!&Ua zxn)*;MBBaQ?I=J^EkFwLY~CKDur~vTh)Fo=bb)w#a@zfw6AS7~RpL4v%Z@*?0gQ}S zS&J0EBu;l10Y2j7hx6}&)sW~%UO$Q;cGP{hQFJ8o3dEC>TI4_C$ku;(wyaw@DlIem zpZ+JKU*)M@vwWdKm86>yeSlUi37Qd!u|(~EHO_0i)C;?gw!#g(W6<?4bI>7dPl;w} z@&?ciRqPV=mo$3Xvw*5kl*z%E-)<#55{VT4r#arW<}gN4Z+s3>&*nney98_akl9Hn zW!3q7PHuWr$Lx6{5gmS@O$^^oShO83kqTkDPJ0FR^(S>n|NSJQdJBW`9z)q#_<q7- zj}068SIMH6&SAp@^Oy!DwfgUCuAc5*A!L>cw2{ZsJ$Nd2gR&Sa;E2%j47j`hb&l$1 za+N?5aV{PeZ)*jXfeh@#954AQVeiim(UXHUbg3Tq8|DiyCmmn5eFbDjb^Zm?b^BBy zc{hOEL|}Uad&lW6it2@@(}+eSk7@?$w3W(Jr^lynEA&mEKBy~Qs4cb(<OM@toZ=iw z$)3)|4-j~eq}){sD;`1a^RR=1%i?&SFJBUI?t=1Pq`tg>u&zkwA0}YqqC0=ezAW8O zs2tM_Snnaq8K{yvT=3O@!L-;z{D#nsCNOa>yAR9qbWh?T4h`aGNQPDg0Oy_)zqseH zJ&z;U&KWpy_<&JxdgtqxMDlCtx7r_@G?n!yEa_x1VM}`M>@!|I8jpQpo8JL<p^ejR z9Mfrr9z1T|0%SqOALhhMAffQ_>=|wlCtu0@&WVz}#k>y4&6hC{IMHp_hec$xTy4ZJ z8%`8>5meOK;b6aHN2<E#PaDuK^(h3a_WjWhc0a#8KAXaK7(yt{niilOgKr@FAKm1z ziAg>X-Y)3_t5-C?Ti$>_9oLV+@_Ak~OVfJs4qF=TVG6)EmKqp4lt?5a(`RYr|BOAe zO6&2!isZWfdv)+qPGI)QDfKs6L7V&z;WH9D=a=MBoHqI;W6v{*o3?=1+BIA3R|m|@ zvpwv#-ggYcwtJ+Fejn9C@x~XIoPkYoKMsV$5=@~cN@6lHw%2rNFi&~@5~o`0Gui!F zbjYiIuEi{S@%&r{_9xhnaQs+@x-zKw0}-Z0Oz;-iQ>xkhI7<^Ur&UYCKE`#{>hTez z{3}X8b#Zeb!u0_wb*1<<u(Oekk-90lixX@Qu~*u&B8O6rUf3OH6xDv&1nX08-kr)~ z{9L@)8*1+tPwFWow_fw_!K+?@E{VWl-%wAx66G!Y+49%lUV=P76J1P{4AA>VEG`bA z4Yu#yS0ufT>9EP{6`Ph%JN5geNKdXumc5MohF6@tm5&zMP|r+p$TWL=U<ch>z-1!X zfv2(I<{#Z;M(D1rW1qHkw!%<UAADc;_*9=lfgRD}V2-)L5^WN-SIb*8F9{@NVE;mD zJ79`(`qd`^{E=c3z1;u%IRa*2m%rzKbAAi`59@p8NClvQ4Of^c@Qxz;AEc>y7N$5A zhn;EE8mrS|2R3|cg;0vd)9XySA*4SYenjlw_vU`4oW-@%$Cp-|mzSG{UUy*WXvxg& z>aI#=?{p8KdCjH_#_a{cvd0^4i_NE&V>a0%xQIy2I`<;;r)6tH9BN-Y4AdZzs)}IQ zy^`mx1R?n08iM)*j8~6izj>yO#86au%mu>4s%`SKtFBzZhry)vZi7B&1K}P2w*nhW z{AkU-2e&iPdsg(AwVu_0Azhc;WiWs_f@Ti^g5sZk!@av?5o?|;UYP>Gujq@xZB<E| zi(we3Bj3xGKCJel2Vlqf=E|Am)#{?QY0yD^hE+qIJhP;#6P45_Ny*!fv`FZWhIb@} zHAtz|v#$Fi-mNJy?5A|S@aLBU36IBPi<|or8wV%O#EG#e>Ok_q!crcFLvDDanU2Ln zAQ$hu3Naz(s2|FJOCtUc!?0%~VWKxAa0T<^ef$@>>z^Zk#T$J2a_3*PgcUh=V+NYS zgf0hSnD=jEY$xSVrQ&O%dG#0C^Jq$0DN7|%4xC2R73kPLjx7u9EGp!o46_MB_M#t$ zcW16{JMEq`T?Uo7%(xfsH!qg9uR|*acK7bvJ-Ej6+OFsy!jbHes9|h2$zaT0hjA;* zh=vk6oTWwd>fxuhRjkWs`I|uef1RB=I5easVHxmgjf752C(5S_mTwp>co8N)(g#Qa z=@zG2Rc-QvzvM+-lWP14YKx=nkeuhG{J87RBH>WnR=DXGGBxid`#|${Q~O{=9)|DA zK<NE03#^hYHYf?3_o=fP))?3{a<Yn^j|wr9L3u5W`7xH6%E9^v=<nO{f&-(v($AEn zw)~dVf9NWgqc~te+VWNkg_s74)>5|g+v+=KE0z<ht$F~p24E0zZp0Qf{lr$qk5wV& zKSP)d7Zn6g?XA+)`1;H?F!U9puVh9a{gdnMiv4{Urv2zP20xHqXmZ$}ZQRRYOhaj{ zt;AM8Bsz(LRfs9D_{Ipv@H4-g3-^HJjicYvJmyPa57rtv2re6Mzuv9CXq|*mQ48F> zPGpTUtu(1cIYu<$S6{gRMJ1;BEx|>`xvpI7bY4#qFrACX^Bm_rQ(!>L@H$p52VH%G z=IM{1XV^dSV_=yls{M`komvjpM<tNd*m)T>>3y9L0=U<bpQ?Og?s$JB<R|ENVVdqo zwywL<-dI;Ts^N{itJa7|6p%mhPM>D6r_1=ds65sW*oA{((<yTyS>$}AAJL!#Hg<w% z3rvm=((x_ZTTciBsOl)d^fkXu-*%;r0HVpK8kn@ZLVqBOA3F`(CLv(Ap(b(2lZN4V z#U4-0s)+XpZ1k0WoGrBQ;LqRwGxn~c=&W%mvh}%x403I`4rl(ak{Xu*Kkxrb5O741 zw&TF%czcl+*OAhCZkwNdIW6%jKKCakE&Xp0juHr78_8)2L97BzOOR#&qhtlQd5_~( zt@#tOK~l8Amcko)dDqR!q_Q2>`*!%($Yrm0wP9IT++al?c3>NtnsfSh%8D!4J(;>; znN=GKM51?nd40UTMi8xf1jZHKvjy{lL&cIxh;V7*yxpXm>LKW4mtXvn*}#vcu#Vd| zUdzD#u?=xaa=;D#TX2V9+B^VcCM_i<#7BwG&?9`aX@l`Buj=o_E{~#OfMkkN+$VeR zaH2<aJgK-}4yu~LP0QA2E$YNx1i-O7cj#}b#497Ca9xNJQ#ZUB`VKytQbI>H3xK() zfZ5R!4phnIv=`7E+25{CHKhU0X5s@|0Jm&V2gaTZr4-CxerU%heR(87f9cLPIqm=K z<<_SF*eQE=ip3<<!*o~V%a`bO=Q5em(|MtC`ZbhnCo5_Nsw*-%?|ZlQsejqdVL#Jn z-?#Lw*gKEAwyx)m(wh(doBCZ((r$ua`(QZcj>4QZM@q^n{3HN~cSX)EctQNKU#}qT zeCi&fgfxyN03xDU@e6Za$mrQiu;vS2^3j3OqUHn<`|O^>pE#DsDBlQM`30uU9&$Fd zrO4wer@)wTllLa5YYneQcmaV4h->#Wp~S08C<xb8T?@kj-m)Dv6@p5%>N6Cd6(}#` zH6<08ulD!x7Q}80Owst}2aSE$@o^5JzelEaNpceG$|!Uu_s{5mA}i7IXBkG|MJ7~! zA*J(Y@FWD}fLHvkiAzxB#bL-bW6=sTrTe>#E|A=8;)R;_C{~mEQGNdMVp*GLaZGc- zHvi+7N1WHGuQ?-d>9<OAo>S_gguSX9Ri8T%3m9;|vwge;B!0vJrI5Rvz%z-Wg8vUy zZygqO)U=Q9(jc{TN=k@IOT!X^bV-PGh%`z{?V_}#v^0{6lyt}f64HVKA}P`hN(k)! z&hotP^L~H+<>hs8JZIvbnR{kFm@E*}YV}yUfSQY;zbeL;43#9wf6PJDm1hbFEgGy@ zI^ioK4KpPcWtRFx&IY>mLd5U->_l1h{dwNRYx%O;|DxmhEp0-{ItEh761SD&4M-dL zSmA4(^R?9u;><+!y{3A4+o}}tqv?4s=2`X&F(jy<ysbVjQAgTNDXOIW=l@`pd(MzL z@)XZ9ta&K()lPdOmtC*!b`_gHL9Hwq!`Jw51B0{#qKoX~4M;j6?z4|mR2jz|&xonr zR~T<=&dKhFWJJ)`lWt30zD~pH2wVG!e~^1C2vw~+MGRJZdSM8~9u(*WE=M96cLv#S zxH(Cq3hYa8%}EF<oFAoAaZ+oY=h@C6K2ig9{YXGD$F)zURWb`DTH#x%W)XOP`^nl$ zz*$&S4T7WgRz@RzC_Va4ag{7q^@dYEH7@&iSi=2Q*~3z!+v#rbezAt@5I%vbFPs4> z;4|pel2#orPYXB<%QpO-#j(1VL9nPkls2+B8~zdN{~A{yn9|!TX#GxzY2&m*P|kJd z6XQcswpQ{rl$V|kBjrVtt8cUpK)?Lww^`3Sl0p#zIh1s5o7W(PIV_KM0a|i!UdWh` z=ruzE<M(1MaAEpXr*UafZ^l2_wdNnnKRCTqz{7K2ZxslEiNG%xy^sL5KPcXq#G_<^ zO=qX&UM!qG&$yhusPe}e><g3}U10gJh0Itovr2wfo>KCs&q*RxP)dETEB7Do%$&-% zKP{Csz+WFBxAr<A10on<i||7eC14s;1XS^!NyE?0Lbk1rR`Z-NA2i@!NMy+-AThqY zcYQ1<bR#+l7F((8n(fLaGgy^Wh9j~53BIvlBa2}9#Eky(ir2z?qM7wZtAH=-NCAER zEE9VZ^vUf(RlJZDFF@5QfK1LH>30qS_^cT4*?N=wWhT_$c0bMmVX+&u&drQ%&$r>* zOi@wZ*c9o_ND_6V{uhfd(!y*=VpHYG@##Ij=zj%k(82f)x?<}yA8d9g2$)13c=wIA zGsi`%SJaGnyZU(ZU#2zPc0LjJXz_9@-G$PyYvB_1`u0?YM%|adddJ4LLhH2%x3Cc8 zTXy|w&8CL)l4<eNWnQ{?OqMI8t~MMNN~}$|sE+K_l-<F=+|iHb$HkE*wpHKq*g7|V ziSHNF|EnKQW+3y&0oSC!219S1fOFWX{x~K$mS)nftm&>V*+`N}{-zejgD_f~kgr{w z71@a-OZ>BnIA&vy#c4Y82v*84V}jt|JZkk&WxpJ&O3nTJ08Ls_Qi^r4BI=GGRQiVH z#sV1waZ0Kzn8xOF0tP1enN2lI2&w3?^f%JidF0mB#EBISP8gQIYJ2MTpzXu{^7M@D zXMlUC!!%JKx3&g;rl05H^rvZYO4!B~V5KVeQ55FpC3s^ND0v!AW|>+Eq$J4qhO)p# z1-|GK3i-3LGY(2%w9ZT4+rkM%_qPJ=s_H83t_9TMCiOx|h*;iWYu`6lMZyE}xDN7e zBFsJWcMywA%Zk0LXMbr=T;b1!Jdx3yfYQB$I%3%@5eB`Eo?(Q1s6GO~E5g#vaa;V* zm>63e&~p&7@8e|mEd4*1oIrEn!QwH21Kn@N#n*@a^j3Dty>kqs5r6A21^ra<TpFG< z0j)FekUNveJl5qP<^ujtQTz*Y%YCC6cC$+og)+$yv_$>>W`AW(*o@+h>Ichi?_I5; zbBqB&Q_0r9X>q=VP%mde>%&vTxj{Dh*me<NR1ZpFP8Xed+@X{KN;{mB``f8^{pOGr znJ-CxFc=$f^vg&FZCd}|p}hx&eR_jK>|HPEOe4a9>)B2%Ca|gr`4Du~*;d^fzForu zkJd(-W*qC95%H~bRqaK$kH6~*__G?pZglDdp+wcF$K!Gru40*b@wm5kgzO@me+=o$ zal9V~)HKvd`H}%PK~IN_a+ak651^>?b(p_`8eRlwJSgN{R55ggm2waX*{xPL)DefI zJVk!$a!Qv1_9%-@eoLOd3nGHONLv!1cpt+&mb4LX@zN`Z-g^J-(-l(^0&`cKC!_@C z8RYws+2o$}O=rBrVbw7IzJeF0e)|%@;~AIy-~8cTjiJ|je<TV-h}*FOY*J6dM#M|n z0AkIK>$*Nm*AWrGIDghn*@o%py5)is^zg(R3DqHNVgmh&WTK1ZRYbT5$4jTv-LKOE zZtJu0v6+g~NK<~=%}mB@*<e{;G8Gl+D}=Ujy}-G7MqI`o^zReD7C;g?U$Xh|w~1cM z$S(&70o|?%Xa@2A2oR;Z0W@gs@AP0S&D2}biAeTsVR3whhoRKVZ3J+Y;j8?Kq;G^J zbSOYiWcv~k{bDXuyjZ)&#Z%2H@{q;zZS^x@hU!l2LDW1!j)-lC7-K?JlC8oO$bIWN z77PszEQ$OoBuh&9aF6@_fuF69lD*}Xp=>1ptp)hL-P2+_>U_oDkFchqtNySbDv3|4 z)o1Bq(N~`cd*NJE>ZzX{bBP8o+t0cK6AwR{j|P<j?uwny1``A4d`<Am<f4@%j?Isn z$%5m=b#EkLnl7PfLDs}d7KS_b;%G#{!d3}il&B4>2ygdrSb_Sj;OMhi$;WGt?WW)= zH1q&-Qd-!FgtD3;8{r-hzT)ancADEv7t#87AD59fJ(jO#I#Va0Vvabn`)55H5F@v( zhFHK{%w8Dc@~w3Gk@s3U8a?GYG=`BZbvdU#*nj4eEk9}qPQ?-od_MHNefq<?imH-O z>nz5K+dUo-|F!wBXD-OalF+nU;!twC&A|X{_YL6y0^E#3u_D9%oN`V2#voaN%uhCX zB1)tUPAN}37IgXUTpd|DnrB7?d0>MJ!A;q|LrORKxw2D+8nZ!J|8`{p`p1&c^eNEr zu`WNXn$n*aYLrkP?`AJ#ZW_t1M44|u;`sOnFzG+oO1GRjN1B|gEBOSDzdlS}(7hY~ zF!Y5VS||ZCA)`l15G(Md4g(Uyi9kxaA_OcHA%AS(qA>-3=V=1w*Zz?hKE62N<&1d+ z!k5NeMj(mE?^6Y94v1$_(;Wl8iD%D3NIJhgBuXZO1ULegIiEEPqF#DAD!h|7{|aef zgy(+2jtU?9@k9~1vW>^m7mW?uELd~dEcu2HvR`W2Vj5#wiQW(d!j`611ef9BevzNw znKx3{ZHuWGO0$PiX4sj;yDzen=ZEGeEe5b{D<}%y3AkgWrjq*CB;tW|%hdnmC8DAV z7aJ`&HH<!3DvL`HuS6<9t(ka?X{Y)sJK1DNR$3Q%Ud(5iP2!zq&u>7$(brGAfv(-g z@JvZAG@ZY(?Ohl$beZ=<qsk>@qT;nE?EBe4rIAYP=^G@5b-bro$17*bV^Efpp`bk^ zLB3EKxn(WXAq_n5?5!52RPRn6dHw-6{As>i3GOY;a|x-<gf~cJG)e}SR+LD{gZ67W zbIe_06s4rZAV9F<E17<8J`mL_QR#<55;Y1%CtmKlBDR^@Uh&dB7K2&T16|9P21~<h zQeQ%ou^DGxAtg^r_KQQoUQ1`84km*LV9w=2OF6Hw4)mWJwg~wVL@?UmAW6rPSyd*7 z`T`I}d1^wz&==GYzPjHfxKYMA<fuA?vl&5A1?T?gXG<rbOm6~6^%x|>TZ$MNHI8k< z6gzjx(f>PDfZWG3i^rUc(z6Rp$U@;sPo+_X#i$NuV0<8C615rDq%#gxh4Ob{Mu>u< zooxsdDbar*u%tU!Ex#+d5H71;!_){tt;?!;j?W2`9YLxi3gJr|EX7@S!>Rl1jVw~T zJeXG4U=K?pfFnW}7)9wrsE|0$y|*4ecC^JhFfG=BnTlyP&mQ81oWhV1LLhCWZ6yFE z6Xltny#8$SkO$dojVj3_PyAh`;Eq-opdL>^5OxSmL>A7$z-bSNYJFmLH(jWxVBuGf zD>3JPd#e<7e6#q)3pe|(S<EpOFA+~ubTR5#jU~82<ejm=NWux_7lJY&g9(>jN4nZN zsIWhRO6ATKJ|M@F7Hv<wX@6t}?V`%aU{3h^U+HINv_$2v!wGB>^fhR<saie;*SG-M z_z<n&ROc#<GWnxJC=_!!EY8aQMFyKVa1-Hbj3}KM9;AiBb$!|Y5Q8s^DOtNlBm-cP z!-~+km$#37DKaD{Oy$e2%Gb@<zvzJv92u?s1Q4eNoDy8__Ora@)x6j2`SxTYQ5d{W zf)X_R9jZ6OABw}yFQcOhvFWUVs1akN6LUco<UV7*zy#r7wOxBhg_g2$2?uA96m@%g zqYe(Y1S@+g4_tX1-FybF#kaz>zl@PRUWwp}!wJJF*=oaqt88Gi0|QZEww?I8FcolL zpiwVs5ORf@zUFh6*_YzVCU!-^ub-Eu@z&!(kL?L<qV}!c77H%X4c08=Me*IlqMNvb z9g~47GjuwcIrb9Wxy|rk@kJJyM!Xp*ftIy2`~bL57#UydMbByUTdAN!-5oeXV#o#W z{#<j2X#^{p28pxU?&P0Kk1bgEu(A7_){q*8YBG5z0US4k5AXfK4YMFi1+n7SxHrV_ zVQuqX*E&OdTV;P$D3bVAc(yvdkn8W{nTw+@3gWR)M)TNqjncWeip*;{xcNBv56kR6 z$+G?5>8If&MQpyfmDWsjEh0=jkfC@lJa+N>&nBRse|bY(?EAXZAyot}J3IZ`r$72# z-poyP&hHCcBZG9{ByA||_KtS{u0c3I#o>7%gv%!}DSfXM_xXFGaL<nJ6odU+gcG6% zJTOYwJ%?foFoB?@NSXg`RhbZS6H-z=mbnpU@$%hpXcoD1Ht?7~=vNrhk23!Z|E;Jv zL3#)=au-KcxJoFdd1%H{B@z7EM`*%nWwy|YgwE|2a;5I_tQBWqWDkHg;rtXz_MBC( zMX&LhvSz%q3S&I1stQZUJoNs3!owN!k{2k3wmyIiga?vLXnu-P?@*zAA2alRN?MUB zURRyXhi2Nz%}2KG=mlF4WyMbwcd{^>f9Umr@tI|CXwmFcjxj<sppSb$yQX3fW5rtU z&71WiD#Any5Tw$`5SIt7?G*cA4!nOkOGTPnoHd_ze?*~JQ!&c5q7<Vky?v*@I6Kz! zhP7<~=kYl;>>f7JD=sv@(|ypLAZVz;=}4C-{;I~M`rlN<rx)-dHK2hvj1riXyWx-s zaY)o@slBwwT+|;;6{rIOfX#nTST(W^YnO};r-tCS;-<kcgIVnXGGRHmt&o&>0El8- z1Za?|L5GI!-quXrz7xiRQ?2*HpzN9sl)cdV3iivM(=s#=U9PC#jBYa;uMO_6m?3eo zmRt0?E?Rt}c>^+BG=NfYCL!tSM~y5LJJd@)6q`6Ag>wJTk7ra3-IJB#*RRtEh^ZFo zU$}sztgSyx;G;@47qX@XDS`O4ViwcPEo+Cr*$_U{93hp{s&S2*l7$t;z{abwHvZt- zrStD8x@~edADZ1$sf^(Fq3rWoPYRo6YKZl6Y_Uh+!#Sq@YC^Pb3()P1+v2jDOFSYV z;X5;PX6Gci3O3<41N2}xr>O>f8E<sJWOj_)`YCAhtu$NHL5e@*l;A!nJ^P*aCh|3{ zJqcTA4hGpEeq>A>A;fjLS|&~F26(3M|EOd)JP%S0=P0$oTYMJ&6G0a)gScMXtH-19 z^H2+E?1sbl4I3Vm;pI$Pfm|`|9dCVBKv}?lOU3E>RNKu5DR_#Ug&9|`QgMe6g|^Wm z@D@{B<PSPH5#4<p@4cdEwzP_p`stQ(f~hAk`yTnTWy7`JpqD{V|Dyv$!8b2n(`HNx zX}rXccWqC!`1THUiENK`h@{{IO@ybw;yYom9&8C$T)3(_2obVociEH!lgM2og=;2g zxfnkL)4&I%vmv~EG5#oXV$eMG)ZI~U&3IqB={cwikCJUVEA>|AlcEr4r7i9hMAb<+ zBM2Ya+Yn#7`I{I*%V*z$XP*-2siGo$m0?v&e^a6~xQ~PLP&5mE@0vDpSNGCm{j3;6 zZ9Gc!AUMQE3DQxd?~F&u;UIf^(+$n6zsv`J4mcB((x<JdG2uVFLOXw>+p^pq+c5bS zO$CI$f)l(E;N%SOFrLAu{5oJy2N8d()WAU-CX^`brJjlp0iP9Mul=cj9rn`yc_img zAFn8t8t#>)gw(xT4olf%Z~S}ResUqjm)}G?ilw$VPu1t2E_6i@-9~vs-J+%8h6+K1 zI8LjlL~Su4_4Cb+>>IA8Fi}X*#u1nfEPjDa_QIK;Zs$_sG$aiXBUfUBcw<g3L}L6f zR2MaOV+QvAcNW0TbF`fpalvi>oND0Y2X4N-I`Mly@ffyKBO;j}5$W#Dl~$2L=ZjN* zf@o@VwVnYD1h;ED%q9*s;2N6wqt+k)#`6*(o2<-mp^ikvFz$--fj1+p7>T{Wy%a%t zl4~ZATd<ve2W~9Jk-GSMEzc*H6%*TQQgA#9;M-A(qPh`=<R7|Um3niL82dw8=C`;D z8-8i<j&G6Lbcsy2a&s1X-@cF^P~x~ywY>R-63(fCkIg4u^Ksaa5XAP#q^p2IvoAvT z1Xcp6^qH5`C}8#3)m-UOfLWoY>}SZ_w}Yg<NCmtp`VLoNFP3aESR#N`LikXW1X`9* zcFsZ`_AuCA_|Nfu9L~ast8fcj87b=O%F+Co#DN6ItEjkL$y7c2t96j8680Zx=)fiZ z^G5*k|NrYZ0~#6{M_y_e_!HiXwc@V3A_Z1lc%bp0>rGt-ZdRuFxoc1Cf7*8jHbfy8 zlra4*13gb%LeAehmPG9P+$p2vph~{p5lXFpvv5Sg_!WkOlT+hS-GUlUC|4*vP)bE* z4@(+r-0K}u^-qQ82l<DVwqNJuEEGyHNW2M8scEp$B?DB5?SI13(@z(8?+y~QU(^ue zt@W{&Iu<zBM|3EB5Yp&0Yh^l)`#Dj`{kr+xtD23QMFy}2RTUF8s1O-$b8NK1h^iU~ z?!=SX1<7)p)A8`A{l;0bTMQAIa3gSs`2XC22!R6!DR5V6+z;e=pPD`fov_$ecMZMq zG4Y5NwY-7r3@L_m!#5=4<Kh=C_r@!EQVi{mPSLsg-{z262xlS=Jdw0e+xg!6y09!` z9~*51|G`OWB4D4&3*3laK9p2R!4AUlv3`PaKp#RhZph=aODaShTA?Mrp*N(;nne<8 z*l#g+i9oa1vc9n^A`cgWuQi`5;069%t$W{m)8J;?vr`-v33%_X)d(iuL=sU4!elQW z7D>5qqxO5V4bLfE2wuD3;f+TMz7-F@-5p`G?-&-vl(1kQ%||<u5@y3#pq$9fJ)57a zr4QL$z`$0~dkSivOPngg6kqkVw%eoTQ=M>p2s_UX(wrctp(@`Gm;*?&h)nNKN`yE4 z@!Q+BXIv}2+4R&-VZJe#K^4buS8k)rM841-GW|Hh1RK0v<*4*;)*8!?Z_#jXDvFpu zZX!;!wJ@ESaO(hHo8{3`(G<>=CLzLqiOuMlI?ZP11~=QXR)}DtQ@WBswi}aB7^?E^ zvj1ki{weWA&Yz->p7`wcxNrs>MOu*ftCTPDQoxEi9o1YReE5A;&XojZ^2gk(==Bbz zX*!kO$xrh73<F2(wT#}ES)-i{+q$jU?|C3Wi~o!mw(p>he&FSM6GQFYsMSV?7dP4+ zITP}NdENEY0Gl`UBMjOfV~w@+7kRQODKS9}ln1Fe_4$SMbbE`iAxx=4WdF>yzRKwF z-_I!<;&L(jRY~n9BX#eIKcqAsEV43>Eu`9kSq!DgyHD4L#C+LW%X}<&Jr@Ni^eZ7W zwKsCH@pC^pGRlC%**A<5g>PhKhl`>R!hn8vtr_mE-a@?rS&F8*vkrkBXU<1Ya9mXo zCb`-WXOad7+o>dBt>LY~#BxGfyqhz1uawfxL{w79vBpHpnEL8)3{Q#ZLHlzzpKo~~ z*GF8=*-5@ua#K2a{Yb`4&RqyT-{OYnW<pY=l_BwhHCtt$3?W7xq{ZA_Xc6iN<dS{e zcSRK%0xTlM#M?R+O%W44xU9|POi}uqr7N_ZFy46jyQ5Y6E=Kc?I8^#M6>{7$i$EuC z)TZ*CV~T4}UL>i^00Gj5#Pn}P8X$wael=PGm*y~h@p_3mGfb#X983_dEwW0ICaokh zXy|9LoFjPCbMQcu(SRFI&o3yOY04|6;@5~OIo<Z1zs}`=fw*<`G^zJUlu>~fgcRK8 zIo{0+!*qe>st#f)t5sr%Mx67}Fox<bwCo`fhi8a^E_L(v@VyW>$I3^Vpi;Iucq9ly z?*qQhyWI&tsk^|OC5p@$@aMYmO6TT$h3~&V_CqgRE5+3l6(SA&@$Opj(nrL6R%le> zV*%38SgR{GNdGGD;-l51%q6o4Bh`I@r2bZ?g_D>p8uU+h!<0i8UG*7EnB0Y;{^H#3 zOgY*mRY|ED$64Rn1x0|0ivE5U_6~`HU1h6X5|FT(X-E_z%<wE^TRcih)AMLg=6aCY z!h%aVQYvl>3c6W4iu~cV64#W&FgI@pNAKc@V!?tXKwG7}+Kt&F+<l0BHaQ52N|s-p z+n5$-IFqe{=-Giu3-B>%6VE>zFDY@R|19k^EgAZSxmVvld1;q?y3Ce?Qu*F9%$0N6 z$hPoe>2>b!!(txPvW%{+Z3Ds2Uq?jFEXq;$)lSmA99U@)^4_>`BKR5H#80;Z%elmK zJdNfPUk$q6MRI;ai(OCt@!Xf`J&!*pwNQARm(vl3a7F?n!xlo`iay4Fz`Ls7ESWHc z{?{jY{HL>jD{kc5LGvEV=lN?#85IHk+l!Luo~h%d+3dF;9>)_EiQUJy7o~F*oi|yG zkw|!B6$(F9RqE|8Xw3R=?(W<o(w>yt#aAq}qxCri;pGo0=%b{(=lOgFlVdhDf41*6 zjak2AAM=o*;rYhs*_5uDrPs-sl-76i6cL_V%K0*mHW*XJyt9Au*;!Mwcuiio|1yZ- zWQF;9Lp=(RN5`v+ct%l)yb#hs<eS0#_sND>iC>kx8c~zjD!4`d`uXMX5){<{xsH?1 zeIw%-;dErxzgSC{q@)rc()>A{q_;Lt8$UlqxCYS{I~wH1HZuJEEq!pf!F;bW&?#AA ziV{Ct2+nZo<2iNz@mGHgC!PGb(g&}IwySU;9vrTy(hrQQU<D5;JVuc;2#v`i*SHTD zGC%nXu5E;?gh=@I&pi9+r%fw4mNPZq@J@TTh|LMHBPV#FBSAdJHz!8!;f<?Jvx#+! zSP#?Nb|}E~A6z|yphcDa<$l5fnT_>iCQ_*_?#0)iWN$y(EgA47xktOB^SVR(ER}ik zqU*m>XxbDIds<h3M{s3oA?3kz3?4Dmo934UglCJMlMeFdH-X*%o%~Olkeyq}!<y8_ zdL&D+=amG>*g9X=_FgE-3)3yi%dn!n3x$?zzVbiEhB2=-r=V2MII^Fu;Tlmm)>#D7 zV%d<43X3T3@L?f5X&PKe^#3po1ObHBEzM(6K@mcFf7gWfdRXxJ@P<GNLk1bYf8*je z0%KQo`}+A*i#MMpFBA*{%KG;aSQ4`Dq!{#1m!wgm_#IhFgt*#$t6hw?uPhiF+qF#` zC7y+-tv_7BA(%yVro^+O#JK>OFjJ<Ahc5o}8>5jf4t<?L?nwydY%DdPJ=t*;tW{7w z3g-+T9-A;X2*_q`{L@sfnFsvA73_+qIdGWlgxQ2+_zsIBqi4=e#Vf2PXtMa7ah-}T zODlx0mObQ(9<1N8x79`Dc$MlMuUUs_)zIQl=EfDEll<{1VLjLuYVo@%rg$;Hx%4`J zUCS1%nfwsZ|CsJN8SGx_VhzRw_|`dFaC#kvCvn>w>`mOKz|U{Zh-)8t5KJ0xb#J=r zYZqmIE9?5!#w#qbd8PGtEyElPs;3E@${7q*xp9~1)qZvrM?&`I=KLrsw!c$B0JywY zypbP)eQMu_tn&l9ICg5JE8TLPO}(3@|GP}maBmfW;VY`dh|9vIfKxVDB0T!bKm612 zSAWr}9uh+ZP#v87C$GsbG=+B*DzGf!;0EMd*sTe8V*~-}Y=EyYn~}N%UM0nXrGS26 zyHEz=;~$xBcFq5!<as>DKhy(a07LcU2ZErx5Wb?%6KFq)%VdneC78l#&jcNAxW0OE z;;7mBt<P*wNn;sSc?ck>8P>(0WAgr&AN04T-8Q=(!RVfDM-=+bWRe=M$w`hEs>c_d z@GsDtUgT_Y=0dPJNE#vvEt9%W>`mipzw_knd7A%tkNu8P5e%upAM0HKUIduSt2%0P zdt2qxJQ=JO3L)|z=n3C^vdy%8n;9xPpRQ!4XbiS3z?wYaX$yJ_JNsv9!2gHFt7a<G zhgWz@>z*_;Kgik$GlT7n^;}h{8bqP)v0?I{?o)!U4e;7dS-Y8Ed;1a4x&a<!QpXEz zP8b`|YP4n>;d#oMFG`WF4QbK1v^bk~i8UI{r%O>zfQV^@YPCmwSAKuhNFc;U=@vy7 zGE&hlZb)}m^JY1~V{)=vcu)~S@Og)>EDUZ!{ca7$uQo^;<(SL>^I!X=4gtP=Vx5T- zoO7TH$^MXy6a@WCpq#H8_sYM)uq>106^Hd<qlL$yuoiT4Dsq&Et3C^$YOO6klJ9pT z%HPs*9>`!?AMyN0*{_KRfSLjX4fubHrlk=>90&V2IJ3uuwQ$>C=whPzg0bkcIZ5u0 ze8=@?wU3f#HJjhOBJY*O%l6=FRgkftnitcEt%Wm$V7e}$wGg{_S_;Wr@vUdVxDZ<I z5fhzG8sqgTrV><QyZj^|Q8unT#r^xfGtGrN5!WpFeK;z~C;NLMuC>Pkj=d}VDHEjq z#zq}@{H{`ocHV{62CpjK$VXy$97pQ-GYq0P^RtTF3?8JMX7a>62J0#2S2uk2gGG9d zBf~f>fxB2p8X@URHYvVkb9@YG)6~*rN<8*xJOd_a;mf+{0-Pm|BMhbI$8ju8|L$#> z|HlGe2oZ<%H`fa0dC+R&ENsFGu|$Y_vb&md_PyAx>^p40`BZi3E67~(GjQSXm+_a4 zy1<06#PbL?0ZKE3)HXzikU^1ekJLEvAxvrTg2|Vip#@hagr$ka!|PeIxOT#C+1RuN z&>hWd0ejqP6d_7vN;&QjiNEYf2Cnyd5U>BKG(=G&d_;*LCtPd0UT1`rL=H^>0vo)l zgCL@_Y7TUYLa1Q+hSNfAjQhhxib#UhS*Pr(&uoMl%^T9FSbC~^x8t2KWXXR(duwmH ze*=QYPfO5pnDqKQ{ix{G$JAw^xP2(H3(t7XA2{F}TwsacXeLRk?v;!acaxsq&_*TS z(HUuHY$XWX;$e`p7=oIXQ!QLHBEW-z?9>e*ssXQRrkYJ<UX}mzFCvEMp~P_?VXeC8 zKWEkcxb^QsT!<47%G8C5Zhl$gB1CX*<7VENc%dVpG46!9mW7Z%L&yNE{xo6@A6F|6 zKgTG`9pFNAM_5(m%9O$`IOrmf4+m|QH-~Fn*g40qT8m6vzuw$eM3&erd!I36v!h|Z zhP0=kA(Vlv&KzX-&)1SMettjzl39?Vga;&ZJ-1p&eoVWt=KW;b@QJuFrq8To<zaQz zLcZ#x_oj7j(fQ(VfPvf;(fDiMzfOzWySKusGjXeJ!PsuOH)yJ6Yd?`j4)UO4VE4ld za+S8(6v}b3vt?+&)QJ-#LvJq@{GG1)`*Fit4V~}S*kcpbZgDK0if3nFyOx3HbQ!q8 zviM;1s_6`o>V!!$e?u;0+3QF>fXA@tjigm3vi3pn13PqC6SkCL=7&%cRM*%A{$Hb8 z)k9ZM`aPErmpLwF7b+=p%5KWq+Xpq@5H1DT89Aa3I>d0bb=G0}?_`lD_WJ;UFeOgG zA$iE$Exn5w?TCJ-K*9BU>M;l2BGYusF=)PnDjd5OA)adUoNS0lZU1(6@0T-W&lhIf zOtpUVq<FH>u?AU+>JNB(7ahGa7-0(%0v0PKSics8gg222*FuV>7M43>wX{E!dmjru zk)l!Gxm>Wlm7@R5CRFaU!fq;2BKftnzV~`IJOiEP%%2`%e6&zTjzr`evqL9LYvys) zmlZA?P{(<KZx_wcV@^A&f>`q8hy(^M5kFCheq>t7%_9HXO|Nz9{!8h@tQy7wF_D&( z{U`yPJHqGMG9=g%_lW@L5i0c7A?Bv>^2=N&KEDY)B|~0IHGFk~*%_-6*9z4xX1%hZ ztEsk|FL9OE-&MS@iNyGeghxx1zGeO17Q})3L&hD){4Qihm1`XRd`$s{HO)^HYhdPc zUYVUXK)QB)r@zN?Ykx@o+vQD_el~Xw2#jI6Ap#^N&R5;3iHDA^3Ev>qq|Bv*YQk$e zJ(V1RqdSz0fgI{FW{<kE!0ZjL2k1qPg7wz+Nchc)4Z+Sap^&5D4GTcfE~rH~<Vz|< z)xQTVMldbI3(BUl4OiwisqtPAWC7-~<jjFC!uh`sLQ|E$BvHocV3!1~<_AU)75}UG zC-fy8)$Y|`NX5Z}9PAl)iij+^^fNFVG@yh|jk3V-h(ap%*o7wC21Avw$UBJ|zfj*s zrp2So>41t}Je!+#(br&leLOmh;1cJdX7A&HU%OVM<S6{IU>9t8#E<Uu)p@~6h}eGd zhM|tpkFK=NjKvS{7U|Y8s~-?iYP4p$+hb4v$855Uh~?bYlRHEu5{=wo@~A3r2=D$P zH&|79WXw)G`6tyn^PuC`Zr&_$c~>3|H39oOM)Sr4Fc1VR6w6eJ7sq8XTbse2LBhfh zW*D>ID6q6f4BeKouDot3sjBmV3q%RE%;UTUO>N{;5Elm-m8_RNFP1T%4n3bdrr74| z!?@wLfA?WnXO6NUgeAFS<Ah<0(<Q5(VhU>-lD=tL;Y?$jNrfX}D5r6s2`-?1@da~7 z{>+04pq$BTgM#-Not_@T$7TT1g^cCMCaRS>ChN3a#WK;lD#KUiq>(l0q3RR@d0gZK zp(EGoASwTacsjap5`q$wBFm>0<J<w0w<Y7%*ad?+Jgb`(%-hHhOQ#s-WWjE-?6GAG z1Rg*lQ8jhWsPaGVlS0~!3fM+wMvp`K7q!kLM~rknS9X8e2r%86f}gb!i~%;h!`4EI zb@7%c)cDo}Wz*v(fn#X{^)}&VYU8j{3_!YvY@gHO03d^b!K+zWr=9f<YJFdG92}pH z7>N=wbKHK1q}CH1)RH)|B=yM*CIO7{;-py-p1M+HLj1rm+DD*u4>j^`x$tS1ocGzN z9|H&XmoXI;(MG$zrpBkMP?$c~)$E8%Us{&+XsUI_lAmRXjm^U6S9(zhZ-tYZK#pfp zz&lmd+0NH;Flh(WnUEu<EQnMt-V@)@2h)<X#NAPt?iP>3d!QFlw2aY1kzLAS<%(@C zIGgn-!CYSMBvnGERSAIjJwH7Y@nt<ezFpnu_L#x?qq_9|UX4X{=JA5TmGwtqCkRzZ z;JqT%PTc4NL^1cVb{hjgX(7DYdY#$2ziHUP>>Jn>U}xtkzXkkmFuj?-YEr%S>*(N> z5b1AuU%@`;-DK6+f6L&u-uw)S6Hwz=_C$tF{=!Bs`oIqpD|QSy3QPy59ic`ecWGV~ z|33#dy0>35u7|*uOiLZ6r$rB50M@Pfe4gTMBQw!yv4YPlT{J*E-979797|A+y#0Pz z;gS$3N39S+{f(0qBXKK~b#8CMfDoo{aFu&Ze*Y2PdHC2gsRTMLX(%7_^{l&QODK{s zseQ|sPi;Z<1?PR)9fZUL`sZhd2`E)Fc{MD!jXY7hoJRWa?p<<F2b_-g%}3K)GyASj zktm}oem@<o_xoH4hF;aNelXEmuyvhCW=0$WRwC<PjXIZeVa9@y5lH@+GB7ONcC?^# zXAtkcwKPiE&r=#ca{;&M*5iG~D0*zhyGjlW6K{x!3?krS-Be3EXEAp*mw7ez{%5ys z_Yy1^PCq6H<h4W!EF%s^=bwsJ3^OwlWZ?AFA!62fL8IA|3aO3!V;X^)6qhrboRLC{ z1#PHGqXln;W(Dqj$I9XLl^mw#zQ-ATcdM?2RYHlF>2JQ36l>=V;b3G2{dCeM%ZvK; zcjZO67+}B0U@Q*>3w7GZjV{Q=AqXU?nR<6d+a`ZTCGz<0AD3{B#PT%HzT?&_w-CeP z>y6pjKtWQ08MU;q&jNM}QwD0grShb28zXIyab0zY@!#X#SYUZVZvg!{dF*_45Nvno z021n#{9Or{kF`9L(lTRTzZMiwaTeNRYmVDX@jH7j#Z6+xsD$k7YY>}8Lz2}0qqUPe zWi6kEaob-OC0vT`AbOU(k;fdVN+!ZDT_XM#VLD`wU*1>4K;aCi+gLBSjivaViF<5` zw{n<m9J&eR7`r}Kh=Pw|=7IH$rM2tG{%NEEm`86+0`BXjb#B$kB+QDOg1%lOBza`) z!)4cpxhZ2T7uPKsXwAHofMHI9SI)kC)VRQSHR_K|fXsR=-tRq{_EMX!%Zvy&=?x(Q z;Ke^W>&+@6v4?!dK#&oIE#-uF5aF5u(x|It|JMaHi66CHAHC<j*h{Tp%l|dpNeO%Q zxR&ScStDoqpc7dC;B&&-*I<*=&kuaVWL>eIWZ-KOl2Ru;@xz~B9h4k;r@vngLGQys z8h8$z;uY{;Fh{C+fD`>!IcNQ51i}_^15B|?p|y%iF_e%Z)cNE*{r~MJL^wR0jySp3 zLcq?xs7^1Kjmb?jd&U;PRsm|ec)V{VFeeP?@(<on;7rs;a%V)K;>m)6fhjaouL<zl zF#4WKyW+~N)Hm(UuwJdfTmfWp8)ha!@sv&_Oxt{N$Y$^NE3+<0(s2I%kpg~C5;8z& zC(od31M;DVf_w5$x=@A9A2x_A0)5b5RbR`~@G6kK@InbRM2NAG(BN*xTvTZDZ6VRG zT@c4?^)}gK+}riP*)I5o#JP}rE)P9=K!de-n-`Q09yp%T$m=BFj+bVW(vPG<B})Cc z>>@fk1o5n;9|o=WCb(c1YV@(LkmeP*re>q671BV)ENJOZl^cujURd9TFFEc;zT1+y z+xE*`;~axqa%uSPzmOO;m`>6ycMn7zu!(oHcD1C=gmGNas<>m75c)~+YNvz*d+TSr zpAKI3r?pyVfLo8IB`n8%Ne3Gxr)PODgvSW+Leu^lrwopx|Hh962<#{Lp*J>#sq>rp z%RRdz<QbSkN(Sd|S+WK)F^ZZc<_nR{%Kd>~D1jBGSgaXKg$F^i=45Qvx~*_c54V5p zJt^;DIK}*E-Q#N=IGSHxnA6FcFV+`)dxwLVI}r~jjFfK98b#LEyZHLEZ+26U#7VEt zvm8qgb59mOnG$*vSD`3p6xF6uS-O5^$wukUGYo?|jbV}KdA8`v$-}{GgjLT^xQr#e z<`+U1*2+1a_T0exvL8>HKybEmjKTZ)ZO7`_pLeiOKaXFY2};NU)L-1qo4>S}AHfC! zMp*;Hj=$;O>Xu*5t9MPV-6fzKeMqHoo0BuV2m)7$D1P<WJbvk+l-oY1aV%?&V0B|) zAYVPVdkfRY5{*)bj>&xMWmWgrRV#ueBMy|snG~_!Tgt`Q(-71Je|-i=8`|%ZRQEbs zs)6y##@bHCmmsej4Z*8RAmgh6seh7<(`J#AnD@v~Fn50XYRxL4Qh5)Pq3*AN#tj<O zhF&9rk;hV;buo9p6xY0915!GCgzG$Lr{zJqwu9+yaFiTty~Y~}z8y<e@gVlv+9$ab zGZhsQZ74E|^wFU6r1ebm&L2+WY<jc2q8rcoQp~9K#`%$r-oK_1#VwbELQkEgQPI7~ z;Wy-ZG`V|Tli#FWUG}XW;o@9(31KhoML=|hYz-DTH=VZ#EM7(37v{s>cxx74fN#qQ zRXcj|c1TR?U#*4g<b^d~y{X-%x_NN94zw-Fa1MR+chzbReM7+#<SleyDqC`jqO3}5 zOsrBQ<*%jmr_gk1iPhPQ1k~a$ev@#6{~kX0lx3v$PH+6mB&m>dkN@#{xA)^2<?_<s za(k$ERrn^Q5X%)KaJn~GhezK?AQ5GS^Fl3k7YT1=n?=&9ZXp(vluv%)Te`o+6w>*~ zO=M1pDPUz1qllG>%X>QW&>XGbVpL;duF?}9WMPvk$Qfs<y*4FqFh|E6TGt&7E`GRY z6bIe=(&vrj|CYAJjS^_i9nILJDhc;KL0FBxa&^bt))z>d7|m+vtUVMj_{Pa;aEk<@ zVsHAsqRjqrz{8PJ2(T93gp2HXR};R!-0p2mF1E|4M|=8r`U4vgZs_9b!w@R#a#g%f zlRvcoW~fSHUSs~DEbK3}bUZM(`-<usLus!Gk`&Xyl5F)M?3~^6H$*Et`)8zr3m-;k zKRV>oWkEmWtIwcyNSP0kQ<SD22<T1&8YTMsj&d<K$bxXp8(Fa?TJtGZ{jWnog<qMU z1oKQTr*n_jzvnWKYx>*p`kpG4tEm*3(m<m6t0kPe?0I<UmwpRTfidaA3b&9%`9_(P zfL|t7F`}(be<C2y<&Ue}F$S(xWKc0y_MkK;&ym=OvB~qlovrs<FQwWqCERdZ--l_^ zSzb4j<K*lq1iqshX0*Hz>a<D+nU2tQsm<)mLNICERu$9O_^`*A!v+1mlcbU1`M<LO zR;tk^5s)|Jl$Eht6JnJy5d$iGTjD1>HWq_sg}&|{n4FB^wne3Z!S0QF?3@N#Sb3{t z$k@r(f6$hcI>zy=m`3p<T_sB)w)BF$Ef*{=(Dr;=WQ3tWEPRGh8(;{cLO7odE^GT# z$1wPb3;G!*LH+q9gH+ItxE8Je^-As89?^&EK;Q;I;9R{omMcN&b8ag0oMiFq>UlSR zuMpq)`nhmnQm98AmpRzNa5Dt%SqR*doq_{JtI3=2ZUgdg)Uh+gY=AmRZ}R8D5!II2 z^}*&N1h>0r`?>7qR#$8M|6cvGX^S-@Fwknw=HR+}I@vhu1Kwc<38H=k2k!;B*7qnJ z+Bx1s=FqHeXa}M}KO!Ns5?ucfxc0+Xe8VlJM@RJMi2J>|Ysbe6LhNow$IW}BS9dqW z-hJR~Wy*SOnsiLWRobA>|8#M#;JcykR%=b~H;UOfw&=r|{XJrz^K_f#dJg!<65MQI z1tL@Fx1smrd7CX=9M^d6)~(K;Ekr-k(!Fi->r}nq8yBYt4c7T#4n2j}$~WG`<}C9g z%V^i4yA_JXpG&3$49z%ecs!r#&n8M-8^$ycPHjwgkP7fBBi(Md&psRFA$O5RISn?+ zCo>OZPBIw3ZAa$qoXcA-u6{dX!@bqLw4*H%@gO0pe=HwsI5gctrVpR88jCe1NK90( zfAKzib*Vt|q2#m7B&AfKyrM|kF#PLE`%g>&_7(gP4c$1Rp;2$-8<;OEI}!V)X|{}u z))N=^CxLH1u#T>wj};yZ*RQdZXl2uxX>)QahvGnBj8BbkwIps<@=HZRgk?rN63}lh z<pjeG6W#RD(G)h4<fmMVnyoFDuiDB@v<aJdDdM2%u@$)x#?iG3{`zkzE0bk=^|S1Q zqsPH)-TenHmCy#(m7NK9l44*(1u6h;VkIMNJZ*Y>rjup^pbQ!I7c>e#&U40`pV1BR z9E=DM{fjs;MX^`)p}+4~sm3ob!={t-av|Mvc%JRZmP3YXrIAyod*$67*1A)7IUkFa z<|TY~E2-Ps>4=K`kM&C<4(@$B(Hd<AOlHi-njOZw^$OHx+Qp6Sgn<KiFNXHF2^079 z5u3+?T*L2~aOYDaHy~W>ctXe(uijs#OF=hw27QkPFEKCeR_>~f36YUbExr4(M|Sl9 zRqO*y-@o%f)p`BYW@2E7=zJOYNqdsQvD-Z@9V?>HH45_pR-MD9Gt3-V>1{a@<kFj0 z!y{j&WM2*#dSf~q)>1n*8MKZ{a8keCbvHXZWL|xGXxp+g?0{PNy}F7$9~RlTCSRWo zK6#QAPCdFq1OFUb+ZZU5Afdourv3F*I(0`7t)dm;iOZ@*Zo;KUuwEb9!9LK4D6w<{ z(tR6m{{k7KlH%ofH>_cG=~FNWLlAv|q=`{x9?49Gsaumj5irJPEWkzi_M~LhXvwVQ zC723_)L;;jx$a~iN)B~{h+JkfLgW7GrLVbTeqQ%ioI^W2@b|Gp1!)mx$X1l#o+_da zrR<{Byf8r_9|(^xBre?rAIA@4IEl0HGrx;{3zvw4tJs%ay=0~>^IFEYdIsLypXpkI z)l#|cE4+an%x2n;-NaY&+EP(Ik;g_z9Pe{KkdUatv<Vp!p9VjUtFqmkjv1Sr9XqDk zdX&eVwmhvcArkc`?db}q51KwH2^-C0{Y}K@Vpr6JhGu==2+MR%sD*sd%*j%E&wt#I z`gzJ+#J&or>}SXQkXWz*h^vO-%9aRped1Em&V90Xwi+#gX$~$^(O?-7uPP~&ZPQZ% z!oNbf`QOoo8B+*Yl1il=l<WevJU`dCOt8fIQxKE<sD@XJ%06P!2;y^2|D{Svi;&^n z6!<l{#zQXLuwP#>R;*1gaphV)hi0WQk6_9Efvo9yffi51qoYWTu;Bcl>G8q2=f6Rr z4=fAh4~2bw-B)XrPa=(z9~#~}bCf4QQ@$b5OLWIb9}6Cy$3fN5K1lCLyWJw^60wv> ztU}u_HWw|V*e(e@ZRygD+avFDH$oIu>?N_neye2UKs(q(C({=VfxrX?MvpI%lfRe7 zHe)P3@7$2E&>oY)tHhzH_}Sr$;oLu$gT7JQ_l8VeD|;X1HNP#yyp2EGzO}_YC$GiT zIO;3&SbyPe^0g65T3ZVM59wHV5U(`#Wlf!1#sc&o5Oj4Lk^_Agt~*;eAWjJ-j~uDE zyU!01y@#_qh%MYL;KILs+C=c0Zs<-xV_0$Upr$3A;n#YpYrH6IthUOzC~C?tGZot} z8{HyZO6IAqU?}J6|8f1fTDzH5lRc~O&(`>b&uy3IpH{w(ZHiDmz4>XMI97#4R<O=T z_Yt(^^8Hd?Kl311`mv1!fyVC35JB&Q8z2_=x5S;F1c|N%Vjy1)A|K|^3wh0Kk8M)H z7&o!jU-oSGp+Lsir>Og!Cj<}DY`jKye{PJhP<*)K=u5qVxKMmy?{9UX8ws$El#I(q z8s7UiQ>5fY_{64?#R)Koi6rMv5v=>xk#UxbR6e>0)!X{-*<RfjKda|VN9>?(69x4c zp_5&-YMIXs_qLeRmG?ve=Onc@#*K)if)#tB>e~quP!dKQ5XPQ!c7-4Hh5r+-u5`HF zA@@&6SmuNpUuX6){*=Cj5v#2O&_W(oIzGJ;I@V7&pK;!3&cliNL7Xdns5#jv53_a9 zL;pyy(an2}Nrs%wUno@PM(tj_%C3R%eOdNKDuqLM3A4=WtYvT1%+8N@<W_1C`tAH< zO0%)~eG0Wx(|(tryL#vV0{$IX(vlL^!!)Ko_zSMg*?H{}T3cH)^7!ps+?4w<0u&)I zP<}C}&=Ym9bJ$P;*>?RL@xqN_bGoD7y1j)LwGUW$AGx%lC)P?9PGwv3AGdtXk|S$| zS(Nc{S$MnZsolH9{)(HbsImngM)#M|M5~w@UP7~<?3O}YMU^ybGh2OwZ+{*@WlAI; z>IP@9=Y*Vzo0%TY>|lr+<f?V%(D#(~H+zxKL5`lA2cY$zmPf_!?UH|bQ^B8B^mC>D zQ64C=Tqf|iKK3<7%`zS-S7@o&pXy<KWO5vTFk{kZKED#@^A6r9%k!wUcsVLthr}j# zvS{Wip7o7u9$(x1&aFyiFq|9%=ibO-TwbUMM+C60(vn-fz<$FUc;IU9!e#tI@CWO@ z{8jF))21qCa+ltl)N`SRG3s2|m+x{H1+{jXomum)8QHCg)sY;lVmTkNZ!-g!KX(i1 zbJfNsWY+6nc&mcPL=*rZ0bZC)yfl!sb;eyt?(s-A$&~xV`tRQh|2528uDKUEc2ful z@8eqOWBGxBfvX4kUpc**whtM-%-;2H{E(lX>qB)1-RbB!<bM1%a}tq}6<W5&NPws% z5H-4U+hS}g;h~Y@cLlTuKrhA!op8u)UL|CrE{^&0U7Fshw4{*$sRikQrulMsL5VD# zSumtS%A0M=Y?7)`<C$eQ$bB}Yv#yOkyt2ja1gtIoy(71$!6dV~^!Y>fRMbP_yAATg zRphh47Ohj#^!`#H6hUGORbXG&&GofHvgdHD@9+l9+d6j~P^gSPVsUm8^gB;@awPcL z@eB}mQ8VUGcWLN!t9Y#!$uS!Q&|EeU4tOThy@qR@zM1qYzrVH!AJy6Yd8y55yj$?X ziScuri2EDNS4sgO_*@|PD9GNMbG6SG<BI0^*kr7;eZfZeq=8ZZ*EOp)VL|DyNr#qq z&+Ab3{Kf?KOwRttgeCY**X=D{JP24sXcj+xQ=)ffl2`Iiz^eC+nEbcbmUBB+t%xM0 z(@RSBwhc&wQ+3dYX{Ef!O~bwvJBGwB0rqliqZIousWAt*=A*pJ|Lo=R-i<T7A9;gH z)hyM^jS4fSfX`?iUb13T2DbV{o>4sEBF;)}dlk_l%wf#SDIyylsHmx8pW)0R8o$!& zzF70wPyNK+%dA^WOT_ZcUi)c6knaH^v3gMHgK+JW>)&6kCe1Y@|4ANw{o{gjK8fzd zHxv)blVzxdDf{6>)E$|~bt%VCYINU4`BfA#@T|%q-{0AyA2Yp9=5|^0ow(Onx1?RB z2c333-uKVfxjc@oGfKRS5=G8UJwuqCtpy|X=0Nq(MG)m|>v_lYTzy<v&N-hVue)eT z@Ew<VU+t(=5X`JVFjLWK+Pv6$zLB)>w9HlXhrK&l4X1I+OS#r2yET*3#qH5Z^CgI* z4)sVj4>D8&y&;BYEqPZ}eRsJ=r?1=&Gjs8ZX4pj+CyW&b@-3xLXLhBk`{<?NGLAMi zr|+)EvhI{u-}NPl$lV+6Yax3J)ug{H`N1y$I=E8xyf^re&u`j!(Y@uDpGYVhHT^gD z1x*7_J1GSMgH><EJk*bW_|OtLjG+dJo`}lDybqGH6t^wSf$1|RT}_lx;xHx&je9Yw zi3xR(W_Wp89nI}(%(PeXRLd^vJ9wW5_I;K%uF72WjC(!mq^ro3P`i80E^AX=dxU!2 zxN~TqZ7X}evvyc0$6bP3X?5wpWPW0D=UwR=lFrvWxot$t1BE>l_BJWs1H(jP4YRG+ zVa>89Z1UbqCbB1tbc_nYo3FM#kDp;n-+K{ng20+`1c1HNoSdvEvu0gtA-81HmKP^O zn73CiX1qEh{zUMS`$nd-Rv=}c?l9kQd*B&59>Kxhw={F__@Xh-dg~=f9Yj(t(dx*3 z@bQOn>PW<Z-7p2|=DY%uy3sWGl(Jsjhr@`6Q{)+_U0}~yzZ-ow&uyaRwWV-gW(IOZ zPkWsH__P;pVjh~keOx7h;Z$BIr_3)-r<iZgT($9~vNoBb+nqk6<$Ua|cY=QFKrT9C z{H*iWE9D9u75m><j6EbsyWNI7Yfq=T?Lz?i4m$hE?F$aUTgx0qX$bIZO^F+vzvcB; z9}ZA1DxbKP6bl+|zt+)oY>D&mIDb?d!Zgv}{w1HazHI$^-?_==dPh`0GZyI%dFBJr zYGs?*VXT9fn&qL<HW@*f9>l8N-Y(_)!Gz%x+0jYDNtn7y-5EXOW1M_3+nTc{5_$ff z%;nU}=MnEJ@|GU`#H86>MuPNAjghHDaVY-jM3^pR!pgh?NLY)ob>blpOW#uPgu=a8 zs#wKXf;zHD%f>7Z_jBfe+8hpJhDxq1irS@k$EUwwLUjN`D+dbix}5m#kLqsU_T~53 z9I>!+&^-70yxkcm9G5n8OLyTj_@&ay??Cvm$0nDDbUeD*12=llqe-2`*j0uZ2m}3& zcH9t=^i3Q_^w$NKYj*>6sZOC0<-;BQo+fnlXOk_;6$-N!+Xj|X-GqC;fIl#MPjuXm z9xjUaY6|Ef`;RUGZ3dGf^LP}1FDhd~4vvP;-n3EvX*k<_^q#|rF1KBGJ3n|zczb;j z9m^>qmO)Ttkymx$i>T2&lVkpw`)hZuk($+hLSaytUpIaUS5tx3)`ydm3!C&MP5dDg zkk>JqTKoq^q3n^76m!E>6!VM*4ln8b<z?9BW1Pr#M|n7vHM?s3ZTFs9y6y=0@|Uu# z|M=3_h>^o1eYcTk1Kf_-o#luagf68DJzytTVLW?N_?2%j@673!BI7FiKPUqO5QyJi zOODS67v%~ezdnk(iJB@hfx<=%Cs(u++@p78$-=GY4n8ve!L>$@OR7tEiUz4BVu2*8 ztkexZ(Nd?7`@nf)gRss!f+{*lZkBz<tTS}|L4xc=wGe6Yo;!xn*Vm1_3dK_Y$(u$Z z)o2Ql1na*`7UEa-e%c|?`~0+bvg4O2Mv-%sUHUH}<!!Ggo2H$#0+rXQ;IJfpILL|m z8C$FmZql8Ys~35DdQ`b~^XwF#_NECwEyBR>e_tut(o@sV6XZOz%OZ$uF}%l0ypDfo zVFul}y*;Zkq#-0!EhM4SRoLPp!e)NPyF|;!DWZXO#4nwJf@q;-X*x<)dqa3%?0Ba8 z@>UjxB4^_l>sM_*-tT8t_F*DqFF(bqiEPn+h+x}2m6)urU<Dr(AH1vHlp5rDycVTe z$YBIRO2E~DUq5InXg;^%^7R&CD~9R|=y)wye)_cX>Q8HX!FNAZBbvRQ{3seY%6h(; zVk9^a{i=SLBC%SNus+@f&dszmQ>#$&bf_uu9l$ROEcW~^Yir9s(f%j)bU<jQvt2IX zAu%Xleq}wvyot>tFYlUg>~njOZ~7A#_N9~^(kB*0vy?KbOt`z~cpd_GP4qxRZC79; zx*b_Jjz+H)h`^G*s$<2;u9Y?WIkhI?mrAyxIDS~@0TPgMs{l-|EAVaW&yD|!`PF`% zCaLZ41+wKe(T%TNI%obD;2YkKQ&Z6y!m*0J3~{MaV)Y+>zo7+eNlsM%I+migPc**O z7DZdm9BrgR&~DsyXQfdMF-+lmArL;BG^OK#s{SLOXwN+mAb-R(KqCEnx!I252z)*; z#z8uxcTxTk;M+4QrGnON#V^78Zw3FPh7ouA(6{}6?S1uERAJXPA*CQC(kUr5fD#g; z5{jgtgp{-(-9v*)hk$g9N-7-!(j`Nq4Bd@%%K!uO-NW;}|G@j(yVi4->#W6E<2m=) zXUDa#z3+XJ*AYT&uO6Tz>`3ZAA<|gqV=_%hzEmK!C9;Et>O|2T9wfAJ=rYxW$o!F8 zTd++7)-`G2%R3>aX7r<<M=P>#kIZ^GNS_au7qu31ad2Q2^|9;J2Gr8<M1~{0H5A9W z{yjE_l=k$y|GsB7Eg?+QX2NaSt(t9+I<D>MPr1s?XL{o06>Ni3LzhgL#_e8IP^=~C zPUUYG)kOy>iC7F1%?b_sOQ2SDSf4-=Zj<Kg)lFNlkr_zMI-PzO|6PhvoBVk|AHGi$ zjn)T8htagkFx|v?p9chNqFNR*aD!xZHmfxZ|6EecTCLwE?Y=Lq&&TwD_IqK7#c9n8 zK5mT^Dy<J-PYaMTr$TP7rSF@6n6G`szg!4UD5WXzIK7;9J+D*YeHu<IpAX@x<;%pQ zpeOMjVkyiYbD5bAX@I^34syEbG}5Axw0fP?R<J$r>GW!RpP)ciC1=icMTKivZF^th z+$TBv@`V0bhN$XWC;J)zR?n|f<MkQ4-bU&Sa3FP2&);)U-NgSp=&f25wZEcb{hG`} zq1!<6bQQWu?te%Qj8_usO6@4Udq4q{I8GPqa^i_x(^g&V(bOGg&QXxZIQ*>||NN5c zJ^f^JuFw57C0z5{qUwapDzXQ5K}M2~3xva+&VL-znNap_R#sO*d$$dmZuO)G1Oop% zU0t&uv$9L}<pCunOppMKtA|y%&ARAVJGOcVkh<=%KOBxY1QcE0xf>48j?*7&A?veW zmEA}AB<Qy2JGbIm*Oh(xiUb#YB(i=5ms`U8M$bkOr;|y|oSXUbK8Mh3YXVl^DTI81 zIzS>=tQ{v)=QcrOxIC*`)Mr{IU#lTbh#m=IJp|BF_2FgO@q|d|ArwZhaygF|%+}KD z1@lP?Bh6yH=9X_%lJOD|JJ%Q{b({<Ho2^8!tfo(03LDRxF)lQm!hgHpt|>;V5(D4) zpGX^TJyuj3=UP`vPmD{rZb7^^{^k61w7U7%u^9UcROhO(k9eV608MzBRz){jPDNoL z12@Nrbubj#?8H#hY|e5&yft97Ar(Q6c@ILmbZ`r~^&!0M+vc0aJH1VTmShgW5daTK zVP!_(gzPa$8T02WKX6h98JQL~nRS>u;L<V<kW_36>ihsULX?(5M`$1F;wgm0>{KDf z4|wMq{N-3p<oI?6eE^kq+8T)own@=@$8=1D4|dRIDWmr*gsEbG$rorUD9lD-Wrug# zvH`W4j5`eHB*f&>vzaDWG#!&%x*}=+4!FIqSY_lZ<~JXKoBaCfDST%Szac7pY%RPi z{SX}p?r14y`}15jvewJieHISe&B82}7@4$--vO>-Zg}c><SR!GRs)nGHZQxnBl!3Z zxZ~OQ3fxj@Fha8gAE#rR%2?(S4^y{a$)v(^-LhZ8EQQc|#!aa368)@);cnN_=Ci=3 zBAk_SV3$*~P+Cub2^8LWfc7{$!Ak~7fCk!a_ay8UfTw#VtlI^O(a;!!yi0=nBR|+* z@NsbD%L7;XG{|rH>!8S;pBYbWBzbTFZvwD5s)kmse|Bg4OVOzn1FiaEMKg>C*birV z-(vmgTP0o&;Tw2=)$99;_!o#IGJmlOrr#T9RCMH9|95aKXtE57Z%@Z_>DXod#Jqap zWB${9(nK`R-;VfYL|E54)}XXrg9R_pz^!#`3F6}S9tZw&yMbxiceS(gdGP7}oN9w; zD*@bFx)-xY#lb~+pZHdHWz|~3fv=p?Kd&ACL5`%D(ynu{DQyJmBpPn**ZYdfLsFYy zt3WZ;pqEwk%p}VG4XLFXC8d-f)>lR>SFga$b-W4w3_(ipuPOBL^3}jg9Zxylrn8co z_ScM7c?%_9981&Jyb+zaByGw^;&7N=56r4kG1rfpD$VRo7S4PG6Udm~>)+a)Xl-^t ziFvr&bF+-DLam-B6|W?PV?vdectR`k!oo7>vHGcKMn_m9h+z`b?v=le+ak_PI!`2h z`2nzA>JKla|LH~*njM=Mw#So~bi|BXBuq3wwJq*-dC7Gb4MyMSbeTK9efW>wodC8I zQq6N(Lk9oCHKE#fm&CF^$Q%>x`{uwz)N*lHbMzKvoLD~as5xQkAvj`Z$sb0kTkZ*f zdKrB89CvQ~Ko=Xei_Y^%Q(TWZgw6{$>1&+6s^f=|KBgdTIA%4ty~3|MxL{J6qUL9l z!!~$%+$w!~mLweKb`F9hF}s4y#NKYTjfus<d%kzVS_%p-dDxqEk+#p@p+!rnA#_5- znOj=e9Fh;F%R{m2T+qX`YL5Exzf5?mf6-jJFg+#25g+z(d+>dE00sShtrCsNL)dPc z^R(yTgyH@ACbmKM3jwI_y2($F{6R#@`kmw=Gv2G=Cty`(V*p@y3Tzd_A`Atr!c={V ztD~p=bdd~XZWB|DnE~Dl8WTg8c5gPD_}X8Ou2}E?!}#DQ==QbrTkKaDn`Q}$s>1vq zdQMs@*^^-WE_^Rd`&Bnot{;vz-<jzNutUqlGBuoZq(J#Uxr6k2GOOFyYnArLDJ>;E z2R53Jvey`%Dc|-ql5(PA%Q-a$Xvj0~U8&vW4S&DA0jJxtWGm+UKlhMtYxgw9G{y6R zRZY@b#+-5Dbgu_CMTMHD`r7`wwc|HuCX}k9UADHnHQfPi-s7ug#u&XZzr^9-5_d<W zqfk--@@g;bdEWx#m|tm*E&@svcVc*CO4Tg56h4GuN3Mlb*m(32`_J!#{wihHUE|r2 zBSgoRQ<_g>qH=FKUFB;$gIxneB)L8J6udP&)U)T2MeVbCIR}a|Z*M_()9dT5jBV@H z0d=F|&@Q9;CZ$mg>Po6F#f*ZkDZq=f>YoxUmV3R~#4Z3E{^^5DWOrv2;LrBb$336s zBCpNP%i|!+!VI`%{89P$PPSL@E1|u$@ojEPF-e_zzK7Sji{F?n#lly9*EQ1R1=0K| zWvBNugnou@id2@ohw96Hc)NOQH4CF`Bix-?-_$d?O61(f8$(ZKZE6nYkw@*UOxGQV z>FG%7k|-!}%GBYpafm7u>pPQ;jl(|+Jdd#qJ#o$~Q<)gM;J`FoYRh<T#r+<YWxlVy zsek;TQ18_GZ9#^nd^I$B*Y;Il)XmHAol7pt$ibqF9()P7(Oy6JYF;C{H$>y`@0auN zSI$Krcg`6JJ9?N_S(`t_8XmzwDy<O0+vrV6N#8bL;wF+ib+@*1*W_=k`(j?3O&;x! zMb1XKrk}@-<H*L$&HS0$vj#0l2n<HOM5|$i5SA$4wr2e6xY-(`2<iLCzzP%x_cwe$ zY?50-@Xhj4FONv>_q``e0X|z})B8iZfBQY+%i8N5UZ)Vo)%G7Os~MhDpM+GG0QjPT z#kLeRP6KA&Z(iJ=n>smh>$n+5#&@lZln7aIIuay3K3Dnfq#t!_>DdieE}WJaslLX4 zcHD62J9{WB$f$WjDNiDr*%LxafGaA>S&7eMD3qnsj!0HB>qbQckA3_XKV5mwDC7Ot zUjWH%`+-(YFGg7=?e)u5e8W04D4ozy#-Sm>Y?>-olyRn?m%NDPd>0&TzD+**F3q?x zX(O!sO}q6N32i$y7bbV#MvlNfXBMB7n$L;VJ0XQY&LpWTU@ef|BWk}QFo0RkmAXJT z8pQ5*!|k#;znV|~eD+f=i`8iWbzRP5M?uK`t~w9ePgeM#of*@)Q&QZq9sj!yjX(Z8 zlBzU#vrw*kQA$PLKvzNG;0abPkoay3)Mx^xZy>_D>&TMikb3%tVTFIvin;Jo$U19w z-#1dneX-wXL(i*cn`7iR|1H$Bc-(7<3(Nk17r3ZgFGnvtUsP^6U1uRP*5}Z2cW5Lj zlzg`Tolmpc&^C|lug6AH;rhd8)G*H_xQP2umF5`e89-w>1X0op)V|}s-IiQKR48lP z`@m!Z&KdvCB-KSDHCAh5wf)%*=Bd#>z#|~hZT`N4i0}=C77*w(z4*ou$M~zm$p@{K z2-leg!mm2c-hwsxF)oM!jD^wWl0u)}o9IjRh$N|~&9q*@NazzwMd#qhl$71k-dGPL zzxxVy<Hun1!opuqWh<Zk3RCwXiLfcIDsJ*aczSaS*HY=)1|KW&@xb1?ZHib-h}4o~ z-5*Pr=>O>jSfQ8-Xo_1sKHn47-zvzq3KF%*klBDbs?tjc+b%P^c2amoNLZ{-n3KDn zluUs_8@of|`?_k=hea}vwWprRx$VOXkiZW^uJWUlSB*z5490fLJJp!a(xX(bTp!{f zqA2D;=@Yv6YiaZ6xAoZ6=P;c&oA7Xv!%i`)S+5v-XkUzp-SY1`KZ|p*aS_J$;d=&r z4Qzoq(tEp8i=EdUjEB2kR&IvhT91Z41ayv%XTUq_m`jG<vM~K{%`pl4gg5tkP8%hh z`!~`b8ySG6od0Npc);jmhRMsAUHem>m`}}5>m;Nht^(Hxxt;4jy=$z;B7>Fq{oUn= z?p^*K8=Sz9iRgQM4msu;{L=nEQt_K-)G7+er59gMUdQ9aG_bLy9*4i;=FflOdf4V% zlx3`4C4I>wJ9fahGjmJ^$`Iib;hKyWxRTD1TBT`)9ITe>QoZt5%TbX97()qX@DMd% zj)^U%iJi}D+qr?`Kc8@LmZ~L}?x~L9tt`A9TIVn19ph1c{%3m&W=16Y<bjAib#M6y zgyI;7*kJU=)1NGf&Y>@nwqA2>&Kc5Q_Lk7bg?HSed^|C<gVi#@A3oSW_yWE2YE^Se zHW7T^ihc>9PVDDLNy#UGg&cRfgtK6QKUT?=&-}bn%g*o`1eWqe$RckbjDEdLnA5O{ z<0feMo;Q2zJZrXl=SdB+x{zS*P{|LDLxA&+_L}hAF8l?}Qjh-eG$cR(`L<2=6}*t= zCMJsL#6L7<xV)j^SVHyP(>5!mH3HxHU=50B1$iSAfUV?pu}}Z;es78C(7?B8<N-}g z^1Xz0S9v3-nG(q!4AnAYXCDv)Ds^q~XD`3VEk(V(8!fUlbb7Bi3lXPAG;uNRano^J z<2!%&x}M$u?@Y%{GpM9@Hnr15pvCAND+2*~lUC`q=!I>uje;oh=u%ZcemT$WV9d17 z9n1TPou#Lh0&sLXI9ZgP{5OmYVco}HN`*n+Og1%EDw>`e5_3M6a}x%qGO2ROE##Q& z*<&%UAjD!_qM`J$e3W47turx~5!b3nKaE`rFpEv9shMo<u>6j=5@mW7jh1+-=|Ezn zo=a~}hW}-p(YEhimKvv$vezQfM-SNs9ERSnKv{Z!xH9TJXhI>-8qZ)CGH&w-8J9hl zvzgi7>FCT`eC6L%#a+O3a1qDO;076aAhjzMCia+1z_dGNdnUMO!+uiX;PMG8hieaP zknAqoQ#*7`b#l@+Z8}>ZAN`a4nb6L7f}HykYD%vcBm1?K7}%0P<2HwtN!HYIh#<oI z=MK>(1Oid|3(dpns+FT3%)e(_SzDe_Xe|Li0GT^ioLTb8-A#kBgZbHAr!s5W=ln4? z?^*lk@*Y(UTe%>pW}A-^J|!oHUXlWhlDpEV>CWv<*ynAJ2TP&y%~VeDtX?^doYXyO zwYCSWP97H@V6cJLM>QudZ)W8FK`SGxGoN%H<pQNfmP3@rg~ocl4gckC7Qkmxkb@^y zGP9T4Yf?iAo%D|$DYrb7Z?4*;ELXD{PTH$p|522xkC;9i0!#F{`EO?x)cV^)MtMX? zsS$k|5K~3fMfKp7bw)s3M#Eqsz%7ztVZBmNR+d8(W=nV6=z?^@U*d=lm&fvgR8H=O zZIbiI@`>0_UmfEtF}+NpDJc}%_-65x3L;Bq`h`cwd)%f?Z7qYIM9dLOhS!eK0`ziT zd}qodYRGh!cyBmw?$BBFopPeHP{ynNsdQT@YhQvmb}zvkY1a%B)`kQ?d1XoNu=1E> z(towQnJByTvuU3kw8sex4^n`J6>L`3#d}b==HFv}8T&MC#v;KuD@)W#kj?6szMKbH zvYIdL{qhhQ*|&R>o;AN4{8{^jx7JXX;uRP4q`e(3MW!${He|Bt&dAR>40Iikm%e*D z{p~JP4=EmYGD^;}maB5V1Xn7LP|>hE3$-m+IMdIPJP`ADpTGI)EM0@?WKiRw=_EJk zIMhKXHk_bi<HN`^3#B<Y;-Ob^OZ6i<aaoHg9nz|N=N7Bd<WGhQ(wJ1yqA4~XL3uj; zLA_NTm)}h}=6BzEyVRA3&*X0kW%e;pcIUyx?=6Q2x^~qd$k8}R(VysD$FF9FBcDeB zB{qiHBM@g<=awT)!}Y#wG4LNG=M5iMEmSTu)1sl(D7IP{KVWCID01}6FxkRT`qWh~ zq)^(4ogf(<x#G)|ExvmhY?0UQZK)jmV*)_T8;iiBv^-@mLBopNQ|_lrd57){I1M1= z<=P0Oc5IMHl=*I1O0NEf^Ub;zMJCyYN`X?Fy)bijX)&Yl5*e7;-On!doDG?7H7h-^ znn7+z(c_I}-7o9KDSxPjOqvoyiMzaU=?4*_WVY0ltM@-u_-fJcbH5ZRY;w~(6873h zd4mp@Cw7~9p{8^S2dLc;8+u8S^zIpJS7bx1mWi~R#%fsDQ-3URO8=|6sVepS=FGr; z559%>p(g_lVT^?JJJN(+E9dnNMm??OyTUVlhwM}EFXkrvPimMJ$N#mvvAp3KN#xu^ zvr`jWXzSbN4Lh%!7(L;noaH`HiQQU!JIL}`)GD;vN=V%SRmr3DD(Q)R-V22Ov|ejP zc%p!<fVJJkZ}KGdN#u`c6Xu3@WW^c_1VYdGmE>YmK%}ZQ892R+Hf%yqHpo6vPzVvn znsv4zcf!H|qPf4b!X%!o0wzm_^YIvo3K|@a_*s<YBx^lp^r^;Y;B;tiRs}Ju1LC*p zd5O6j^8@wo^{j)(B5L@D3T&DMA;AuJRg{hB3o(lfcRO`M!R)8Q(`=&ZeI%_x0k0-8 z#kKj&@xA({SR1+*9d_J0ovF~gD6S=bJ;~|}zL(BLrh7@4#G6MA9i=yCyU&sk-6)%{ zI!t$B88Hct7YO&hrH~0$%eLBZEFTp{dX>jt3+xwmnCA&?R`Xdg7WESfg3p<d(?ivq z?h<?PSdSGmiSytY7dB_d4&ZNBZ9h;t&$?ZA)8qHt9~JRL0%%JascLTrq~D402H{8L zyl+e<?H}Mx8Q+!fFBD%~?=C{XFVKoRQx70CY<+4c-Th6Q<Y*pZw$+qjZYFMBu9Pv& zp0AxQtKwkB0f+dOIGTs~FDx9CHQK@ALH8qU4uvo2oc<n&yp^m-Kd<KUKWwLhaqFSX z4(#B(C>E3P;&*I%&#n!Qmpet7Em~T#ey6QL{2~7}iNxHR-1H@)$@OvMv$a+afD_`j zw(g|&QF+PHHQc==nf;m#M`GzQ1!TWrJ;P`7Lr3AWgA*bKFHX$<k$=;_Eq`w<mhiA} zcS0T}^y_)LW>2&1T_W5(QwmSj?~6C7`IqjEe1g<BeVRDtQvLQ!Gl6av6M$1z@52u= z;7~Ptjf8`EP(@M7(r8Gj4r2b1GFktA(|WFFJfyQhP6KETIaYHHd^~pi!p}W15>E<i z61F|}8_}5WT__uLi@DYWsSuOreU%Me%9_LaZ-O~?cU3AHlXtQ+-B|v9KHqcpj&c73 z6zV(AhxERApUW2YDLUe7s>nd<^er}GVqey)i2Fm$JjHM2F?Xg!<L7{wVubhUnJbZ( zo2N8$w?L99n3#}fN@{2d-B-daTd}r?k}bw4Dh}s;5$Hih&>_E5-y7jf(aL=73ya#I zESm_(wP$W#0{x~Flb6%s*_R@u2fib}=>G1RWR<M7b*ULPEDxct9*+6y;X?fP`z~bq z8;_(A-ADEK=}4L0Gx`R$-johbohYOB3Xx<j`r>}fyGTwXoO>iSr?fb9cGThQRo%M% zHa#(6T|%u5Eq>WoajyHh!>W#-ofkMatfK{OXM7%<>DSl1TO)TbZx&Pb?BT+(Lw>%y zqiI5AYN#0HyduK=vh$5V>>o{r+y^_FpGS!al8?pg-uT7;2n}c(7*O*H@-$n5W1wZs zKb-7BQxU?;nJUnSmWr0MaKPbR^;1y7w6~e<ryDN~8eW{<%GzAay9kyUJFc|2AbnZ> zVBlMG7>)TD<V#hVV|`?QZ>?8JC~itj^a^P|3yCoW$W%#)%ShkFcl|CBGpQ3}mhsu5 z#5Tha`FNPVp4a;mY=_nmKP}wO=%k6>wQem^garVi>p#W(<*K5&GiesvQ#tz;pYA+E z-x^4>Ttmy9rCgAt^nEi1iQ*Wf#)>5A`E<D(2S9H7eQ}{E(1$#!{iIxt2oZH_b%7`5 z9Dz*Cpfzky<S!8(A0`3bzX|L8yKHU*2f}4tg$Ge52~qCxYThvTZKsV1ltsh65L40e zs&H3?VcUc|?Q`Zr;jTkP98u$l{_VkozCWSBci#XlX&gFLpMyRzSBB|PTDidoe^}3` z+N&A0W`R8k?dgDSrIa$?X5N-TwUJM}I-tu+Wl!(JR0ZnxoY5OXRV=HLPVcWd@1%_M z70BFpn-W9$>C3LuoLrV8?9;K}TdC<9R^l+dKWK@6J_P(`W={k=S>XL?B)jH2QKtkx z)gXG2V#6(`we-o>{MxyHN7K;pwXE25KGlH01T>IQemPk>i6v61{*vSNnDIkDGv7y> zALG6aZkwu{SIPuzNi+=qjBBzZkD=#7r94B5hjH3Hi;Z3RdcauwH)DjruL<0O3405R z-&r$9_hMO^BS(j3YHi4c4aV8n*jkP&YyFcdo)V}f-jK|{G+TWEmru=h`0H{u-D2sv zX5~Ltmn677IFu$6j0-r?kmt2E7dRm{6v}!E=XdpO4O>^%jGu67eP+Su;1K1&5<_vn z(Pydf!xtO4-u$s2*M$wUTXYZb;YDz6w$I$7Eg2iGdM`Y2)o5;jmrqdoB%~=Y@M1=K z9JFJmPX_cZ%r=6q{MOxnaElZ|^=XccBnY%J;{FYX&)+M)&%1;7-IWc<K844L>iMw0 zp5%M=^T|hClU>}A)Yovlf>cHa!Q4;xawYH_{lSwf_g)V0SaC&YC6JQ&&m*U6fEybu z`*~3VO2~?nDrV_7tJiN?yr0_@VWX-Msid?zE}lO)mG~oRWw@{j9)(f`z_hSsMMp>S zX4H(I9fXzrrAx!-Y<!bg#@bqALS$7ztb}N`3;W^Q0ZZ={Un6Qdt_uGUd|7EgISLp^ zXXXEN6y~d8ovJGDf9foLfkP-Masv?|x`Lt-dRrItEg_F4|2EL%KUhtEYV7Xmd5B!w zF;iI<8R9ZhB*&XqpqsabK)%I{h~)a-bS)e-Ra$w>F#OO-VZGa}BHxD*++rzrAew0t zs?e!Id!mLR39)&N5MW};I~KGYS>Ak;CX@Z<7%Md_1*~xWYh__Vs0oUMvG~bf;dS1P zkwD!8Jo2$Y3JOiLWRViL>tc6lMJsLDsa4W>oqHmUzGmQ#4Z74ivP##B@0%fR0BZY@ zbsZUWudJUq$%fV)NiICMFM+(Nmg@S`qDMNVB)T~)42*mQR>M~SkT=T&%2k}9`HQs2 zEs3QC8ZX~@#(jKNiLS*{q3U%_fF;fJse$ID7>mSq#&;_edzJTo(%r*{Cs~M{`xsjw z_M^A9XVpR1-lwTpn-u(X|Mt5csW>U4EuC}SNswY6zCvrG-cRA$kwyRjL|qj<b9lAZ zZ#Ba%*+;GY`}ZU8y-H%!|Gn-)>s(jQxY@NxBnOa>dr{DSE;2<&B$;oek}e_T={N1? zTaTY4M#1xPn^QqwdU=fx<9VIu?|8esxoyDBXRz-BB%(USG>-C278Ta({yw3Ll*}t1 zw*-YPUM%gQ5V5mP_7?X2*qVuN?k2Z|HcJq+%3qe?npaaKZ7nFJnkyEB4MW65;z%sj zRE5%&&ATmZ&Bzpr^vZjgDe>@P@(rXWJp=I@r6=YZ->o(^y5+oj3cJA33yHQLrwh?v zwl!(Tkv21%<fie9?lb2q9H=u~LW51s1y^41V>t|=lqHFB{g>Pj$f!(qM6wsMTKX*z z2fC;J9*-r@l&VIhAZm1o0^ahz!X}D8^_jex%t*O6m4|-03d@kFe_Dx~v|zVYn$L+- zfhYNsbMoIw4<4I<odttt4BSbk<Ub|QrC5{f<JdE`!w3xU>Gu;v>MTgAm#cu;hgbrP zLw+#MJXF7ao83cF14#po*d>(T@^0C@fyXMmr=Cd#AxkKr$rsR4Rx1iRLwR*_a%;lr zG>q&7R{q#N%Zy;JPwfx=G^OGBPjb6EyDIOdYtAkX;*5MK>%lYKyv&@b(9L?f5RtM8 z34uO#mrzW<UQ9TRi1QE$_p$IYn&hn><gICWFBPbm(qKcis70=rP1fWd-DVxjir(o> zyeY2qqmZp{fn%;4IS=O-zy}T~Uen*E<W~yUR)XcEeSgDzznl=fkr#@a1rejq8NTHV z^YPeng{V^3*HFzT><=AT)vvqOudCJ|QysDeVeey(L>_1fy5&x-_j>>q$N544C(kr< z@^8BQHZLX}LW(bK1uAigjY}!!S%U<XI!H}u-gs^}C{GGqEl^-<vL+$l<08T+Zf#w7 zz2(Gr`V+$GLQtH76oo1!Cd3P-&fH}FsuPv+@^KqqZXa0Cx6k08fau;FwFf<y2Ol7@ z!f5W;Dq?wZnqT5u+Ue^Fj)NL&pB_DYNP)`VIKYbqZg<JL%Zm@Z;7?Oenx|Aus?$NV zkev|nu0X8!yZuSu{yMnLzWy)H<Ged7r2q#%eI<d>51$$dc`cdc3u&oP+bZ~w87|i3 zD6}?g*auo%%ZnB$hk;A^n~PQZkVK2S-L3{%i=NxDLt6V(B?+BsK3*lz<x=8|lAvg> zhk=-bkc^<`;XDEM<aRr1r0s3uc6Laq5!^XZI}WRBNG8-<91vN6hBmCS#s`6=cd8s7 zEWabwhemE%@8i*qc{;z_3J)iq{g$R)VoBE-u67Zg27#!f-E$!J_|mpPME5TeQf)F2 z5fg=UQ;_N_8E0IjF`{<&S*1FV!g8JJOHz|m=PlQrwB?#MY3r--U@&Ru-lmM?v8Q?# zFWpl`Lh(~a55qQyy2EI6P;|Ys%eg}aTDtViCp*ZLVf;CDJLKun7-Yn#Bfj%SD%8O9 zTv5To3tOh-xYJghY2f9tYrYk0ms5Yldu`rI##gs_b@?cB`Y1g~nNz>>eV^gLcf(dd zRfi)Me+dDwY@vB&wqc8PLg^-xEg|NEPA#(vx?8+-^Ok5zceRIY=6Zx49UWDq85VqG zeqxe^wo;MSSt<b1mG=UJBZ<cPSo(4>3C6&~Vfn*q{>0$zy588=dh?ck=pv{cBXJKK z{p(lY8XP!_->x%gi=`UCgsjz|p&Q>f%yfA{qECAT3tsH`!ME$HD^|J=w+0+?vX|K& z4gVTE!w+hKFbMKm4?xHS5FIY6XuF5{--GriCi)7EdV=#ld`e29saK$+jBCL5wsB++ zwXWjZ&DO+ZUNG83Z+{V<1Y*Mv3S^`}ogGUSWzvmVD-x!m^t*XSy2DkgSIb|wQCX>` zez2eVRRW5JIiIh@QIM?quhQ>Cr@E%01=mp;vD9B%&WY2sxnxO0OzIwj8)9iDMVM!4 z<}J=8`y;Ab-P)?3V^tlXA|v_o-diB%+{IcJN9mu*(YAkn1``uasaD2cCH@36Y6Rmp zG0t22`9d}2TRB8k@sZ+XcGRShirXuxgbWqhsjnU+(=V-x!rDHWB?HJTnuAT)DPcE? zw~M!A_BebVR69c|6S6v<pWVsSqfBTa-!o)286!OCgpjGeeckT(iZF=W<E}dFdyt5# zrOSjsT4%o%*vmy1@_frh5tzvp|H@%qP+FSo*MB}fc1A^X?(xT#DMw=R8TVwQ4db=e z@C3XPu(dKx+^LQfqK4o8pnL&ZJ|TgmT<pI4eMYJCSDr|&6}NV$T7Gq2^*Bu=z}NiP zSE%sVso_vEG=_Qp;grM8<E@oiSjy}h#tU^?NtO`Hc^~}zYlOkLO55SM?e`$65W&M? zlXq-vPVDhQxtuT6q9>ldlMN?%shuimC2G#lxv>o(V;371%29SFym+Aa*5F2eF_F}? zdtkMl*mmlj94ezD`b@7s_d;aL*l#w>cXZ>z*}yr7y7_D9AIFUZAGdZ<5mI2Ar1;2t zfjEO?WtEg16Iy27F18uvFGNE+Bf{^EMp@e#-C0?oQM?cXBXXl&Ts_G3zC)Q9PnP`L z3%YGtK_=N*RdVJk@Nwa!qd!Y5h{*i?Em9%<qA(I%pq<^SY{Yvr$pIgTaIa;NH_RFw zAZtTj2ksL>rT027S1{YlnP_dOH60HF=h?NAN5f(AvGV#kRE0e1Ao^=Hr-k$=**@E_ zDPUG{x4d7jx21Yn4t(?fe{gy;(Nxk#zec9rjn9>9k~7^)RUTEp*F2DpZpewLM``}N zy+iPgJE`04m6eh!ACD`%f+9ETy@H-lpi+{8m@8-ZID<?BlaHOn<Z!Cj!KW?2DgEZ7 zp$-j(j!Y`5Ki6~~L?lLNJ%6R9*bwow`u$|jtGg<;ypg(^+Arl{`ULx44S|?p@M@Qf zuk?_974+Sl_@P_c5B+@Sc!<%|0fPugtJ5s%R-oy_d4_AVEvLB1DhL@h@*dG;y-n6x zGf+AU)Rlt*7QrEUowtV;JEIsl4FasKT^&()S7OIbHdeyDG9B!1v#;<Q_NV{pOT7AN z7caKResx&f!nWdG9pJK9J;5ITr!ISn*&Yu9-;~4&WDD4QBoy`fA@+}!K<qgX7Yw1p z!NJGFo(ZpE&!oiIGaUu?3}M5b|N9^QE2aOc2G$b(YY%}~G5lZl8Yzo=`#3nbkCYW2 gz4)&e{NKBNyhO<uc7_@B238@I71b3=9={I$e@#HpGXMYp diff --git a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Notification-20@2x.png b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Notification-20@2x.png index 2a865c6fe6162e2b5c909b87eba9a5a5eb94398f..3191f397806fba3f80e1b84a4e77a7ac6ccfc8ab 100644 GIT binary patch delta 3213 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 delta 2276 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 diff --git a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Notification-20@3x.png b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Notification-20@3x.png index ad988c8094c4553d451cf1f806ba34f835a4b99b..ac3045dabcc352530ccf50a542d5e7368d09e247 100644 GIT binary patch literal 6366 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 delta 4679 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 JPDHLkV1l{HEMfov diff --git a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Notifications-20.png b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Notifications-20.png index 737b345d9b874f81846ed796af12901455de306e..3bf42a834978fce2d7e707229031764aab5d82f8 100644 GIT binary patch delta 1153 zcmV-{1b+LF2c-#+Gk*kJNkl<ZIE{6cYiyHc6vuz>rR}?}m$6INZot^sER)GC_(29_ zAOz6(#mN*C3<SPt3|>GcF-E})B8d<JC?RTs0)l}MBw>>Xnrwu~WO0FZH+BK)RyVe` z+q(9B`}Xxip>jPRpa1jxbI$WW=YIslFbp1us2U~^X{RsJNq;ytKrAr^fJL^FrMU1o zN-1<afz|AM@F~K*ga!uwU?a_edKQ+fB8Lo&Tg{mBykODM!hVG8xeV$me{>yTPT?}j z^D7Y$9wt=v7#Dj^U^O|Ip0J~LoJSjIhop{Dx(I1P47L9p2ojQW8iIQn*Ag+tv<Q_& z)tDp&0P${S7k_(CP~a?O#z>M_!#=d2ACh`HcYvf}plKR<=o*REub64XC~%a~*mDBo z&K(iJA8f=b+i|ybB3Ru>cK1Vn6W5aLJUYmM^Et%SBw~gKoRcV!ddM_8@CO@Hgi$q2 zbD$1y$jtDs-!OQ37fMA9k}VHSPZAnaiN{rrUl?NDmVaXul`mpc&&KRsOK9i-k%4dV z+7+$@>WHdgg!X|y4MonxbaFrO-oF8mv)tsb{*ry4Z=$IyM20cS`@4?f^Z5w-5Aw>J zyJ@|;1*>u!i$%noQNg%lJuz(*xi8Ym9Q)G@-MpGEFA?hJ>)Q3qT>T;I=FTM;4ARls zLfHR3)qiW=;LxGBF<GCd`}zf5TRDgz_{q*Sb7i;-F%<h3t?d#<S^yXv(}<TWpsK10 zo6SZ^NeOjlj`Q4_9UMKmpWK4=RL);QB-D;1i5P}XB6^u{bO1S?h@wndNOJayyJFIL zJ;17(wg2~)An?JqJ#78tEtaoXgV$R@{n>+T+JE>m7PANlC>iC%67|RcLdXoQPPp6S zfe@l7-=}hJZZ5la|44UtHydg{Vngl6w1q8cyv&rE8rdRS8E<K0^z8XGXp4_?>ew+} z-}vtRV<iZ<TrR|<im#`iOq(N(Ijj;E$%>ezxG+`DMv$a5sA6!lx0gqZIZaJX6nkf& zD1X-UnJ5Sp<|$-l<{^6=r3}mCn5TP*xA+)JsGKg#XX_W++5FCCCKpZOrJ9wfNuBS0 zILx_##?PN^q@m>|BjYLnt}H9@WFKx@3Bp)BWSqRZlNW{;Gq`mxd&N;|e>%jcTeeX= z>_HYJY~>SZD9ERASVFdEQ|M6GzND0{-hTliQI!Q1E-nZ6@M6V#DRb}z8yJlbF|9$T z;dY24ztr=LV>Wh+9e~n>(>PN+kyE~4y3EO08SGeEhM;Q1<V$3loJ@BwNX>G2ekD<D zgubO7ii&6PY))mG>~V1;G)`0B2#URns2b);_xzN~00IK@rc|fwYlfZq*^BA=t$Krj zj((DQGNtexB1sgO<*`%qR1Pj{GyjAm%$ri3_QXdT>|cR8s;0h*bu62}m0P%`y18M` zq@_PhRj~s_4)Xi;!^|mM{&<7EH==5UTjAF93Q+YZkXiu_#f8T{m5EO8BUiwGKlR>+ T^S~;#00000NkvXXu0mjfqC_!v delta 874 zcmV-w1C{)x36KYnGk*g|Nkl<ZIE{tWOKenC9LMqRxpVKlI@5Nh)6#ZI2WbT*hSV`A zaiHC{DH4O2m~J#7YFLQ67M9@7bYVhpDJct5ZH&cI0YyrSQ71}hFl}0D)S(X<O6UE! z_Z}BRXF8ou`d^*o{LUx;^FO&)NGT=Tltdz>L=nn%QPgT1hJR@=xj066`6d}N1%Tb+ zB-qqLsHG28+4`v1++i{wV`_1noS9{}bmLD;ob|g9c9T?Mo`|9{uP0FzjZkwRE^BRd zFr~*Cni=HCj-%Aw{SN(~FaTQM6+~kWedSi+S`7zS4IF1Q@+|{<KB7i*7s29ClKB`z zGlLxKc$d0Au74D<txAvnO8sA#d86ZfF3k**$j2(dJ4@sA`}z^XpP}q{5#jVy1%=g% zy7MsB_~#r6yvEex)pF1<4RS^n$Mwr(XYa6f^$Q%K4-t+^R9HROyFMY686uzl1$Sl` z-OQm&y#!7!juFT>$jnRvV8$O2y>uG2v$qTtRu9^qH-Aa2eTr#30wACMjomdhOhiUY zV0if^%};V=otW_`u^%qtI9%vdv3ap~ohF_C8q<iDWm~N};q?cTNHS&$m#>4=zV3=E zrhdPM>(E=^5M+`gsJ7=SGFIC&=<+8_X`o6eL4bH-L)@>goLPgL{7Y8i78i3%uanH` z6`8$l9)HBswW<gOyW%9V@POQpQ)NNLTaV-18K%GglkxUej_+$?e)?Zhn^13^f<<U3 z!cv%Fu&IZocBKL{-g%qr=WmmGoMa`D<;2J|4b2{$Hmxk1RU-r&dkW_OLM?qP_~O_O z2A^Uc9OusP^NqhruO^EJ|4ZgLJF&ol7yL!k?|*ag*qEi;-(Lb%MMYIK(jOef_Hq}T ze2*LFZ<k>k(Gw%nwC(iL=5z6Ur@$gKR7ER+0HNkSuEf4Uo;}I^dr?wbU>nhk_m()g z-^sOyUlMBREsbh@;j-2;u=iuWn!CWRflgZXw^s#U4R|<p$i?v71qPlyh09u3+^hI~ zC1dh2rXG%=%RIidR-8+<G&DEypx(`FbQQ0A8BLqVA~ZrRy=B;z;Cks&XCg96c;yy` zEPO>4p%HBCq1)eIoZ0583T`Y@8UQH5vR#z_0le={dI?*aQ~&?~07*qoM6N<$f_S2+ A!T<mO diff --git a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Notifications-20@2x.png b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Notifications-20@2x.png index 2a865c6fe6162e2b5c909b87eba9a5a5eb94398f..3191f397806fba3f80e1b84a4e77a7ac6ccfc8ab 100644 GIT binary patch delta 3213 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 delta 2276 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 diff --git a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Small-1.png b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Small-1.png index 9344000d603583145f6345e3fde84ab3f1653174..64686e41e64de056157eabffeb303cc84f463343 100644 GIT binary patch delta 2115 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 delta 1618 zcmV-Y2Cezu5b_L=Gk*ptNkl<ZNQs@7OKh826~}+~d)c2Izv4&YIL)I;o1|@8hAAUj z*o-P9)Fnu>n9WG+7zu<B>_)7R5DPX4iCqN}Xv7L3$^r>SEzFb7bcR+<(@yJ<CUz3r zas0Nw=VjqEoit7p%~@XE^Z(s*?sv~QpO8{YzJy6B5kh<!SAVo)0gzZ;58LZvdp4eQ z@qHJesA!6gE_4E_NkB6Z9DR@@ppv@1L%Ca|(9BcrZcw+k@uZ8UXn4{^K_eO%CLJ6j zH#9}s%n>sZ2%#LRDh^9;&+W3>TxO-QOw}rp)6z_c1S!Ip!30V)jkGuE+EprEhbK;* zwO*M-AkB1ifq&`fJV7mVd}!0I@!!h(Y<1Q+5g23M3Sw-p;%(>g8(XN+Ec)q-xQ%!5 zJ8LLr79}!^J#>=$(&0&WlhM!#7L#8m78pJn+O%uj+IokM+v2=FNoxH8{`#l*t@7R; zH8F`cdmgXz5q|UW-ntUZAd(lU#22~KEfQ2rE{?o<0DrtM@jbW8o$U|kcx_%8y~0SX zhL?YLAMi!y_e%I%H^}tLyfShH%kS&;+|FT8$!c?%&CVK&a*WXJe<92aN@5a@@kQ<l zhNn>D6AU@;u^7)$>J(UMEc3;L?m_ETm3;j^<64H;z0YXh_&v=Vf515RUDVXcV*%Bn z8I03!(0}dy8LRO&3I8q=L!+!T?o+q7_d_L;N^g@LyUeMYhW+qEe5;MUdYAg&enaq^ zKSWJV9|1f`@WNYk+P}lK?jrp*UhfujA&t7dO}Se{BA-DmuScPkXG}?=tv|x6ZSG1* zoZ<tjZ~u(I#qXhJ=HU7FClu7^JjU4{(AxPWu7AA@yW+lEMspuC9!gPYt?b>c0$_Vx zN}U2H+$c_Q`9Kuz#zSh?e~o_nD(c7rsQsEEgoYYBi$41roz^v6`@sQU&w0d&P>gc7 zh~@Qw-HK#;HZ^;jBr{mm;=uGdg(aH*{uAM^T}AXt2qTOdJdcRy=-JnCt@{K0d}o7H z*ngzq?BMv;GpHwBeCZMj4dW%pk&%NB8bI1zoMN8POW#Hq3K%|?bpz?NQH_a#K0*Wu zY6(E%c)L(3CBAgg6dg4(hB<x(zfl_~03e(QvL{f}Q*?S2YStpIck0mnnr5PlX*8kZ zNw2>qgg^)t*LU&OD)g@3Ms~V~DPVl%EPwWy0Hw_aelSd-Ho<1Kjqm$|T~vjyp3-rp zgDTYi8qkkY(df3SxK9fBJN1L!ih{AYKzC-2jgM9-jV8IP8N56aMpXpmy2YU05!6-M zRvRSfYM?I#pbMR-o}dzJqmGRZJh47E1Fyfvz1w9r?-glxY(8A8aqY7WMze7;aes55 zUnFGE@=HXFVKl{f1`Vht88gRvq}CUIK1DN=1b+M`xBro6bE$~$_V32=d_FGJ`PKVR zI5U$W6+H+}#Z0Q+3TZP-P&K~*)l9~Qrdd}?c;_ZjN7BzCoSh=_i??|1kDpL_uz`H; z?mS=eX|c{v|Nc4OI6qD*_6!^j>VG7nQ0nE$g{Lrg`>O&V5Twm4i9ni%Q$6%cFCjuE z`nh@ZAHB)V-`-?9UmBRcr*^;8<okbFV*X@?kwh3>Qy5Q&sVU3Ej3j9@$J55KH?G8t zVWy)CEbV;E=(iR~j%ILX=eYIPB`QY%pW0HX$<J@*`N`!;CY&&8sLI3EBY(~ezf3%k z+S|8RNQF?Cj?Ob;=C~JKr~92tY*ZYotCgpv^hlGya=FE=jRxamKI_&eq|Gc-(fNIo z<G$)0)Iyw3T_&KI{AcSOnDLpoG(#vkbS&uTP=Kp*DP}VbZf*S&T^L+QU&hqJ`}Pf- zk?K~JJCzS8bqkD&36dLGntz|ysjif1Z8eBw<0!A5<=SS4{C0=&xXIbf5Q|xz_|RkO z&STPMmJ8|2#Ej&D!@Xb{?6A^U-fO@anIqZF60s75LlM-mIFH&cJG~aZsNgHBwA}v@ zGm@N)Eie_GKM>)OQ0PzbPaANdwL-aDq+#!XkZ7V`+K>=2hDn=Qa!cX<+#3(1UO4@~ z5V{9PVtHM9ZWqV5a6B7ddMH9gR}FL}KtK)dzQd#EsbfJ8JIHZ<AqLt10et_<A*q$a QV*mgE07*qoM6N<$g83OL2mk;8 diff --git a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Small-50.png b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Small-50.png index 3328c84262e0e2cf2a308574a2e629805b9aed10..807dfb4c10f89b252873861c38d277442e706500 100644 GIT binary patch delta 4683 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 N002ovPDHLkV1ge36<GiP delta 3415 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 diff --git a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Small-50@2x.png b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Small-50@2x.png index 66506473afdf2bab8d5742dd1259c48ba550253d..de626e8952222295e72d5d948f22f89e7e94015e 100644 GIT binary patch literal 11577 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 Sr556ahLV$3mii@O68Jv@Pm(JD literal 8292 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 diff --git a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Small@2x-1.png b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Small@2x-1.png index 84a06c0479f40f8a0f1fbc9f77b3c3fa99f6ff8f..e48be2d3ffc53e74e6fb5b742185333e2a84a352 100644 GIT binary patch literal 6043 zcmV;M7i8#(P)<h;3K|Lk000e1NJLTq0024w0024&1^@s6;k!yG00004b3#c}2nYxW zd<bNS000+KNkl<ZXo1C>d3apandX0Ysa>^7rKL)nWy=e)k!1_KkTeFourvvV1Ze1n zuw*)ci67hv6EX>4%#5cU2wNHm1WW=BnLxAj7zgk|92PGa%Q6-=k}O%WRi(Y8Qth|y z(tngK+p#bbOV9g{AFJ*;_j~U--#PF1o$m;SVHkWxFbo~d&`@=SNHRotq?O)SCqwCO zV(CFr*%(<(0l*}gv74OaS$ueHCHV8oDRoW5XAdAt79>GJ5X7&_G=wip)G!PbEk#<5 z6OOjhI<T9g(Ssy1!$_hDSu`PuCPYC(6hs6;7;UE;I=Z2u=_;zOpcz^0CO2iCv#2hp zC+MDvRnEgK*+$#_mlHKGNGT%>Cd0H1HqhL^lW4jRyUB&!>?Y6bBi|mtXAj`E`f*s? zSR@CsXa+#l6*6jqxDsU~-A^PLW-u8ht_+b>hDl~)xGe=tD_p?j{5j-10@zG01il#I zFGMt>Ch3W_(>Az==KfuzvvEAOVhS8(1l>~!x~lQngP0@>7&?ZU23<!m+u`_hG;|Ct z0f-2a6$FW_mLZZ16CP<H6m4N3ag?D{4_4X1RR27t6x37ftimGOzh0t-p);KB<v{Ot zTKab~obJQ#D5JtVi*ip5LHAT-!Gxj2(MGz_<9+DKLG)A<Lsu~cW@8S{20)GML5=JI zK|(Zp5iI$L)?!3^0Kw!!)w6_0TIn2WqI0N;{`e6*wnC;AE?~NUK3-e#gnW41M0G=> zbEt{Ep-mheK7hmQVVZwFRrz%kIV+I`8Ex<|*}j9Qk;CY*9<;;&MtTH8R{@ayQ*kZ1 z2SF4_G~R_4J$TFt8PV)UuoNQNOOWy=BY9>b<xNI4G<xG5v=8p3xqlZ)WtdXWS<DG6 zrOZ=<Bue8VDv$SzeBAvP8bWUoP4!dhn?-HlA_A_dSVb#pe+!Au?WhBX&|*CpnfTZr zD;mm8Swlci9zF4cp`vF7Av1_JauC(D8?mnh$ytr5a1lZG4D#(kO5M|F3~!}#Xg|ZL z9_9ouW_DolS3^`cG`4rVLSuLfnx18D>BZCrF2ZTa$B6fnY<UGGv==?rhjDD{_-vds zdCoAAjBE@o8$*kCpbqWFlwXfIco`MmS@`S$_J!YJZ|H5_Kl~E$OoWA%S0M^#9@#Sz z)eVimw*8UD@FoO7<iaU8GQDsCW<f^jY9Q70I$ERyL(85@;;VwLpeK)_q<c}L2e6cX z7k9zA%&)itudRr!hn{Em(KpCy8P1=4-5JTA(VMq-zQW${CNx9i@|qRQDp`cd5J<Of zA+h~8sQoR+M)7MPISK<q&!CNbN~-x0l<-DOz|4|Ge5+;!x}nh+-puxnSI*eWm_&1p zx6l~cf+&bwIrGO%_RT>+K#%p1X@3trGxBw?IwOp1jBL*~^i&7|fhu1e%V*t*Ac#48 z!&}e|ZOpc(5j70`*y{Q=nx5stDK{`FzwX2Xk{QwJI<X&q1;}J|dImFebf@TxWYF}_ zm?46gTb)JA=$|I}YPqQTMl?N3L+CAz41I!O=%+P3%}0mRz3dHbW;oTy+|rAgUbq0V z8I-{;1lfY@_G77DjGm034t0V)_7@y4Vo8;4dj@%PSCsw{0l!n_AC?sHjanb4s6IhL za#Ug}xfsD(fU0z17z(mEz%>5?hLXKBgx+FrXcI1L0X}=+l=qx6EEzS)!M+_F9sXo= z3o#)RZ`erWjRzUp^f>AEJ(vn-V4HOnvbPe(xsQ#7cv9s*{@TOS8)H~YE@0X6+eq8% zS@rB;`iC;7lFXZgx$;^h?<_K@Mn(pHOSJDXlF_#@i88f;i>UC<;%M{$pZ4t_qb5&z z*XW2E81%;4Y3|#B!|b89B)5g6nzu8&?K$*h6hskiqz|`tBi70F*f2=#e-$;-0b@*; zGa;GLc<rw}{ApW?MHgSk4}S0i0)YS*Uwko(7cZu<WrU^k{UC@)j!MiG*CP97lSwra zi@ZoS-45ueN(f0V!0DLJ?7&3~CPRGMw}YU28s*-aQEfarqA6vBLxX!5PW3U(KaYT` z8hxmnk@sIjPaa!%bRDI)o#=ZnkZ#+Jsdy%~v%ib%DTN6{7n)}9>O0-MusL=L$=q)_ zR}e%25D@KUSSDRRN-`e#BiYPhAopQ)ZG?E_CG>0$C9Z0w`R5VM^wT=9n^ZP7`c4sY zAyXvPO>_S){CQ<m<=0`6Y{Yi|2TD&Xr)(d(hSGD0=({hFYHz?)RD*r)KOs4bPa~vi zI$7=Xk$z$QA9>={qb$Ar25!Io_ED0Zot>;*yOvU)%A9F#L|ZY|$+seTXOl^POf2#u zN~RtDW@XK0+DSw=Vv(#=<=5eNlyhicH-m{Tjw@UdK+#gP4K|R@#;Nekq{ul5<!BSB z)}0vHG1QK(q4XYNc<VEyJNF?M&LD5$4-xIY(MQ^Q<J|vp6R++(N+x@P?7DU9xaZz` zS$_2`+;PVp6crVXl3cZF70r!Xx&OaaQQ$AaI(;RQcNR+K0I`AJ<)-Tx+lOIf$s~4@ zO&_2ruaXMyOj6l6Z37KtwB!k*X*JHLeLL{jiYfQbL_#9b^bYD!n9mdgx=yzLFp)n$ zLZ<5=azQn&3-3a-`v^x;{PMK}Jpb+y9)9BxZ#IO<sygep9^`-A^)qg|=_Y>mv!CJf z<vvVTR~Pr+e?N^oH*(*t70j!v!hZHDWcOKQGp$7X9w(dW<oI+w9R^yqhg57Ek|0sx zor%|8O!L4lGHOnDi-w^Sinb6<_vPYA*Hp6Ittg>`80zO}SHnP!gc$hu`%rq?kbIS> z^*>_uYb~@Uz5M=#7g>J&t*m*yl{=o>!>T{+=k_1n!RpnkvDs_@ba!{NX3ZLQY<q?K zZk@z8>ZjnWy%)(jg{;!SQ275a(AUAX_xjnoZGip(WlWiD7z#?d1vPVsfUBAUM;Xy{ zKV8GE7>16l85*tqA7MASa`B{SVx)5)*+}TjBu|1C8=&vSyRdwF6+ii3578R6^S}cS zuw=;+&OiTr6h+~smtNxbJMQEczxc&5!wf>95D!1}E4IJ$f4S%8DJ)tr6Z?!GAv&wb zW)9JR<X(0+v~mC1cDlk6f*=qmKEnU}@g&Zj>p_xET>!OgH%e+h4(n8cu4!~c_R}8O z!?ePA$XPAJ(dYr}CO1J>HF|0UrKc4=H8F`7i}Z5uE#G1HfQg46ewZaomH^=M`MCS; zyIHnu8RwmM9%i$7l;p1;dxULoy}(bdtKyOi>#<kggyf!1Hhq9d_yIoL-NyY7bTVzm z64w3hE@WBeo_p@$<=1yJxynvqf#nn%bS;LGX~U+C5O7uFFuOT2d;nF;AV-p6l1h}q zymEZ@AlYy$>I6m;a$fxB1A}ZhIK;m_{shaGEj#7+{QP__x#W`3|95wH^Vp-0uyy0_ zSaEd)moJ-#t?GIt&rFomeujFV;=K=A_}>p6rnc@<?z`_kDl01iSh#Q@Z@#gYRBCL0 z)s!%*(uL1Hg*>yD{=^XmlOe?LNDGo^8qM*j!#$|OJrg1tj%IjzM;ABT_&u(=>Z&t7 ztLr+CJ@y!Xc>XE=d3hPjFIj-S>K~AOwPaHJ80uZe<}LfUcTFpE&-oUsSFau=84iaz zc<>-TuYuJvw$|3veza^aCdq=&5kMBqbjJ=M_QgAqMN>{2>KfWeKYDU_LPXy@I0$)u zR<2x$Bz?Xlv|6p0O=c8)2qjk_`|8M~8X4~Y0~_Dm&98pl&iNNy!+rPNM@2;ikedZh zKm9b#2e+|!kqeK<H1>zoqG;*>7#coX07){@pE!aXNp&NMCfrs(x{^kVM=&&X+$1xq z&R<$1Ec^R^Bp3{S?(?E3vSP&wBvIhGSO0{y;s94&DUgZ1#)da`@Z>X{T(I~bx%1AS zjtYsszCNCM>M6EtUeEH&to+@1`B=<jkEmg&Xxb3Ek;ZNHBMT;m5<STAOaxJoaF{({ zXrqa&@#4r(n(mPdmtK15xZC)AKK}U!KSY#dp8U;khz*rsmLsfNf0T=s-oT0#D@REV z4Gr<c6HoBxjlbjSEAqJf;v(|$J|_cYs9<O~EN(<mBA$sLr?N5ZCKndjj%dxpHf0`4 z=pbr;C*#Q+bj6csqKTTCnd2r3;P?Ca{`bF+uB$xy#A9R?g=??7l@%*iQd(LHKq{5u z(MKQU<(GcTEjI+Y;_pka+s@<~0<x(TtD_!K%EKb15CxH>5=YKz3W8b4WzYo?+vIbw zR?f!I#~F>RUyo<s<D&v#ybuHdzu(VoxBYi?9g@i;D^{!^5D1JOKdfE5mS>-RmV57A z#f>*yhb)gL*cTB56CfgsCO|;ZGGisj1kgo<aq?6Z9a$cC*7Vdj2?F`~`P_Z?-8mD* z91%rPShHpg4?prKYuB#j#+z=*y=xq)DFKj#<H6YpK_Q!@+y<`d3g|ki4;zU-|1xT4 z=!_}J<H&Y*G7=7>suT0=lX09NKr9yH!3Q7Y;YT0i%9~bVpYl!qxUG479SPuZSg5P= zQ(EB6al*hXS&(feC%U1NQIqJ|B&pqvWIkybw~-}+L?#yF$dMxy7oQ%gO%xw|@Bz;} z^9(c3`8(z>z8poJSgNLPI7!z)oI;PCjFvz*bnK=)M5o1vZfGQwC`cm0IQGGlQDt+I zZ?dp?)20cv`z)Mu&N*Ct_0@DXe@x>CTT#af6F&!nARq_=iA)q-*Kk_$5q<UmnyxaE z?nks*k$fJ63HY2_HZkAr=e3vro#Ek$35~IE+-I-9_PcCY{{*|=eH(28ZXt>SHj9ib z2}INVXhs%~qX^OOC`Z*529qI>M5F>AqQ^BM<Gx*3Mqg_i>(;HCD6cW$^Z8h~a3Rr1 zKS$d>Wg<tSR+EgwA|na{kyIE}S17QTAqL&k(DW>W$q-pBgIrRGT;!jSVR^EQ3~bo2 z;Y%$_$FXJ07FMrbP0cyqWYJ|;BT3_*VR=>)PMbM*)|v>T>RAG=YDBNC1iRTyA~Vcj zGK8tL1UWeVMWs8F;+Kb;$SW^p&6+ji(z<8DrcIl;^Ugc5`+|JumVcozSTUjYF1rc0 z!%XDZ>AAz~A>STEG)Wf9JZF)}MhTC!BD$QIt0y74oS)likCNhF4>!?~@8p^1f6u&m z^AH3fw_QzeWOZHV<(FS(<;s=Jnl+2(pM8p8Y1xGOu$UzBT{bLcnQ*L?gc7C9Jp);? zAWDM7RR1}ovN1x@X0p11_3Rm#f<<TSv`<O%%fp{=$ZO}f&pk(deLbQmqU$=lcI{&6 z(xp7~&_m-|phBS#KmF-Xx$XAbiIvP`#XbMZq>2Db=T>01j2)$n1((fCvDbm7D}<uW zB(oz-DVU2SNXUX95^z=HvJ^0o=psDQN_q8Jn5S2xv>m}vPF>y&pgWV~iLO=-7kc>h zqmMB6B$5pc4SfIRTj}rWqv@mltbcwzSAFM7mM&XHd3pJ$ib|zYG&MD`apRxa@aCKJ zBs6@BZ^1tM0)FzBqde|(G2QRr!rC(4ZR#SHRL-cpB~hTjZKuFx<!JN(1Bou&RzE@a zR0KiH9qnh-Bs)7_ry=wfb4xE_VdYh5O>GSR>M63FU84#~#~_?ev970`Py9~qS-qO2 zOP3<cGMc8*(9pom-@6${!ot<FzfC%uVSC4ieA?SeEEC6?XQLqCM^!c2dIrcE0wzx( zd1o!aS$jSvZxP3r*g}Vy2QQhy*(G`O4JFyt+{17p!)H|@cpMhas|nzDo7ma;8oQ5f zq%N?O`IXDD%8s1YHA^-o=htzd?|nLlKA|dq4#AqK*yh!tcK2dra-$kkv;3i_oxLtI zcmMq7ELpMyS(Z^%mG|F&pWA+T8?KatYwNDSXZHed_3SH1C`o!o`WRM6sQFGEn9V%6 zXAsR@gxMEBFquy?yf2~f^UW>%;)2PX6LeEwUBuqDJ|eL+`rnY1M3FMTlOm6u?pP}w zLrqv^2UP`gut>QI77=nv!e<XKwcuO^5=Uqs+)GAJ;r!N8%u^~y_pyww6Uw9sl$B9a zQ-jH5LRD2ZZ{EzxJ67UNJ5M2b91gRc$pw`xm{iYAH{HxX-EafmS?6IXsvMK#adeHO zc<{Z$d~jrlLa&|KRepR<E8^cAf8;wYOfU1HXi3@!8|jZ9q1t~g`Suf$(5RZWnO#gN zsK;$9q`7}5p^+BEU?HySmXEH$`4$`3&zeg*7U#()pX9)S18mr^fmQdc!k2P#%@`!V z3=9L>BT1gvd4%^mhA8wpM#&y0U@=M5PV(clNpz32(%iojkFAiY1?ONlyGQ#P-H8PR zik($V_b=e1u8r&qZz10i#65owp6^{lV)MI*9v6!i%_kc^!n)r-&yWA*$8?9gDc15? zHsb<3Huve)eo1JCLCau*r+4S7SiV{5WsV^5X(&QEqcJ()q0H|jmKk7Qcq>U|nEKMo zC~{VvQe}3E<gmzgW)v=@Cw7?5q5U+5wy?1BO7bqf5X-FT2o?)sVFC3Y713GJ&Ko=5 zBxo<>!YSXt=lJSI@-(u#LGwU@r#?K2NfKCC?!oOaqiRO(Un9fE-S5ybw4ZWM4bux3 zoK{_Snzr)TikK5z%5bWO#_$$Awjyc+7h$fR1i(o5FyURD1f@c*ty_*slChiYU${nZ zB4k?z61?2hOQqM&ByTRGVPJ5udj}0&Z{f7$Qx{x@*LJ$HJ1sXM2qI;k8s?T>f-IWY z*0!FufjuW)m{m!~k_d)?$L7Xic6{l|%ke@p42Dt)>62pA!;yV#J@h=1Xkt!q8Redu zF-zyhOu|T_L~Y<AYD*Sl7&@<i@(`^9A7NnNEOIkx;Z!V6>(|HVGvKzGxNKS>l^z=g z2JMkXUfuryx~@_iSWI1T>1USAoiW>V-lVIj4J<(tWHuiBH$Dz;MVB?EUU(J@Z@mEj zlp-Ya7t0ro7Xo0BMb0jEa{uBfTr;Z}NzBsJy^a6($)kvf%nmH!yvj455S-CUQIJ?P z`8v$9mB!F!{?fLdp;RxkgNq5yEyq*lqh;$SbTxJo?;AnOez^*jzlB*6DRo=<W~G;F z&n}_NZ6=l(<m2wGG<3a<ESjh-y@d0=Y>6D?$bO^pyEx5W_8cp3i6q0+1}-A#n@Zg^ z^C_KENym;u47B$V?~9U&XU6XABws$0U%Ra`Wo|1qMNTf8=BKX2MOIJJIn>0y@D@6T z_T#kVGbgx=y5Q2!qcA?A$1$tq0$kQY_J%gm6+OUUGBjGoT0C_Ug;R?e>=>Z$(=d^a z0b;#T;)8KAu@t(R%bmId9t1%^6a*%Dt?cX00$>sayfzahE(>LD8#4+W)Cb(0RhWlC zmfm<PZG(-p^zS603{&o@VNP%vWuBVxn*Rj~lT*DM?AuOr|4xQeeH7%CQQ?_Mg?A<a zS2eO|CKJyv(mhPPe}rTtK`NTW&~yT4mlLcl#}MGXjv?Of7|KN*4l_l0W=dUFD!ewl zRuh_`5RSHTWVnfrlM9pm^O;__;Oi?)J{cJ`NpJixE&U(TI<Wh+QuBbTn*3wOkcO_4 zO{*BXj@fQGR#pSLVK9=>kOZ)sBqUKdQEDD*B@}IDAbz6MyxM;*)dlqwJ12krrRFEY zz#x^4F_7q@ZLoos{#``V{n$;;W0wcK`0N4l?EzfYLL6pyE?g2#7=Wf{NvlZ`%5d)T zK&qQaB1~L~kWiu|vm<z{ex~{7QI$UjpFM!x?EbI4Ja7u(ldgk=qOBYn+|AM910*uh z+;tGij3mg%?y*RxTn8}>4b9Nd3>8(&T?cWPJ(Rg;Fgd@Tpt~BI$@%~HI>=Z!alt3U zU?N0!>=1pi4kF2JVoHRx8b?ucE3#R(V3qQ4T6}ozB@{U;DREVkZx0}gU;PE2{{&Jt Vjy=V3u6h6f002ovPDHLkV1fe_i5dU^ delta 4385 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 b@8$mizPF}$l(Dos00000NkvXXu0mjf3R$Y< diff --git a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Spotlight-40.png b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Spotlight-40.png index 2a865c6fe6162e2b5c909b87eba9a5a5eb94398f..3191f397806fba3f80e1b84a4e77a7ac6ccfc8ab 100644 GIT binary patch delta 3213 zcmV;8407}T5uh26Gk*+MNkl<ZScR>bd302Dmd8K!-m5jK>?;XLAT%MX3Iqg!1kh%e z7J)|D6cyCbM*HBQXP}#IJw4NUWYAWTVZd&~(hLJFvI!^>j37b-4M_#UmW3>pttyqO zR3%k!nLpAUiCL7<?>Y5Pz5BcO^ZVW3`@MJX(`lNfahLK1+<!Q{wbXkmsBx9i)OH(} zuZa%D3xH9y5NeJhGANP6kThbggNU#Uz^u34Z76hi1L#-UIdNkfWsPU>%RU4_BsnaL z#IQ6XED2ozKEIo0Ukx>`GAf-VsH%cNGLsg4KNE*6#vq!0TtJ7fjtkXCD6tn3VvJ^J z%qUXAbBMDJMt>3vXnqf<3OZ9L09v30bRs&*imdvvyUVF`UZ$+^Yh1ntvg7j^kvN@j zbKDODR5gW4X9@dlZy|{W@&-RfR%{-c;zw<3rsGy2{_-zTJdNliBcap(1D#%@?fgnK zr5(W(i#|3FecVInjM3->110reaPrnpWW~?J8849>k$;7t6aRmJ$F6Omxb6fa2hLzb z!Zd>QA^1uU;4l9Y*;NCoe1|6;A(PjjGs$=_{~GReD@cfzfk-j=7?U2w6KLgp^%4G7 zeTeM1e11Cg={^Ca-u`TtJsd237rXlw(}q1qddwK)+RL<@-Gbt7=+hbWF;`Va@sy)@ z$_dndf`4h~^Gp~tpXi{0e14+<S9>F~GG4?a1@{;#^ycq??Hwwd#mvoFO-9UEyk|e4 z^~4+B0r&l+w%hTRyh_LQjby}(Wp2)Ds+=Vpu)Wi(eK$Z=Q#f{Q3-z9I7TxzMan@9{ zKs)~G^WD?=gDGX?rgLbDmpE%G3x~f(y{DXG*MGL4s7l{}l};PQbtjlKWC?M>DX8rp zbdnK6;z-c-y4ZcnA5hu4zl!;5FSF~@T2%Fp^y>tqs8Q%d6RO%qoHd0>LzYlnSIF%a zTkn8QUmg2x8yGoo2I<jba2(!1?Z%}zK6wkv@P$~iAGs^YRevm{%r~BOZ|>pq8$-BI z)_>XsXH1%pG4&~2jhkq!SV2p}yQIgAVdTIWd~Dl*!&}!A@O<?VB+<Z#glV+jJd5YT zVH8&b?sNNb745*3F&op+hd}82NC0T_$^2ry4fDX6Y}&MmF=NIs>A@*nsc?f%#1KCf zL-Kq)ExT!JIfNoN;&UCP!+V|)iBpk8BYziaj&uj~EA5on3&|V&7(tR1$Ds{qN}$t1 zQ*nK<4d=0qSaP4hoH4UIP)GN@x$3u@v8K%8?YG|sptQ7<^{=mE%IIhe10TUO^f_9a zx8QEx1*n}NG#OXJdj#o2$Q%3^CH6x6itii16F0UIVvHs$HV^mdUC7S5Zb8vhJb&j8 z((>76%$bj1&iWY$B3nPZ$+)#AC@O8hA5eMr#a|*x2G+0tPYebF#l^)uwd7G=e=dc@ zdlq6$SwL&^hj?8_y5RmPC19t`xreN{351xUDZH_x6VMlMQ`UHfq0ytz<PO@3KkGGh znkv(J>MyjMEWngApAT(8{PmiFqkn~8@vnQz`Q@L_qmLfS`|rQs1^3{@vAp(V1XE`% z#FV-ew__I-*SE84PbC*Gxw_vtfX{sbP3<5pdK6b0PU8!>5gguH{IZXfh#X{B1A(Th zzBd@){%SXy*F3|?(kAxp+ednOIt72(OYHF3tY5z#fGbz7u>8sS?D$<a<A0_t$2g?( zhB$oaznQz_DnXIIpkPk|A04oF^DX;tqsR>;hvyJb+j016k?ihr1VJRuIvCIAfBI(c z^`Xl(E&So=O};4llDN3ehkb5tF1fk609?Fyk)O|<$?MM!WZZ*~VN9Nn+qs*flRJ59 zql=IBeMV+xCfV89{N~^0@_*>;_;0eL$@p47B`#tyf=;5|U5-@SdX40;EF{6uXL|3{ z)-$zi{a`0aNl87fDT=~^1q*n6#Q>%~@(iZbrMMb5QB=5-WiJ$S{P<}yGcy4wC@5g! zgwP&7ysd>;qn;u;Jd@hi>j;gWDiXrdP<^e)E%qJ*?o@}Y;t5M-@_*#Xy<QhZk?q^J zvt~;@r^;h!ZTgVIhqm+Dn@)}&KTURaHh#aK=bwL`*5-peJ};r?B;^KFrIp0cVKlmL zBek|S6KPIBQx$XuGg_d%Pr$QPZZd~Y>UR>kxw(AuX%SPWjAz~ISl0b}4Il46PI`Je ze!rhpt5(s{cz`#5pMTlwc%5JbR3a?{@N_gIbtqoU1}kDvIPuFjqqrLA>#gMW<^mF9 z68i-NNKQ_sVB206En3L`>^?+#dO83rSFS`3_<48Z9)c{r9QZmNq7;Q7hGEuQ@yWh# zy>7LM;57CL*x>?8g8n-Jp>rimORpe`B5iGLyz<H`*c~3;d4KPHynxr&D<2l4o^S(z z4gkq0TJZVZC{7o3&;AOny`#^d(T&yAME2a+eMuBMS82_fHC(!0!{V2I%h3xJ{f`j@ zem-F+zJMFEWJU-zN73x7K_`i5zV^;H;XZ!j!(zB}?r+~4@Sj?^a3S@TW!xya(4TuW z4P-?{(CKLQ)_-6%MIl655~*n^L$C%T#YOiUC{)rTUn<3Bv-NBDZRO_Xa^T~S*!I>s zI(*)KZG+8vjCzr3*Hxl|6A==_hEeG(Mppd<O&<51!3LRvShHpgcT-N=?RJ(eTgHQP zmSQwp`n64s3q@A_R60wDw+=yw4NgJTRP63s1WlcYPJimPOhMLEcGp*MBXs~fckV=| z(|s?<s;VkhtXRSLhh{N(_T&B93WAQG3<$^WE=ScAVy%M_A}j+iNM<S=myu$l&?omi zJOTFBSFzI&VE5j=SS%L2UN3Xz%%P;Dq|boIj~{3J_z47M=kfdBtR^cZs$amcAS1zM zJ(bSO=zj$hk(L2SX1$fP==&*a{F(<+<`Fb`JpP-NU4v9jqoD2<UnWLyeD5A2A|h}& z9L$?L4^zF!6EhYQofgY|BZm_c6N4<vR99DX=Hg|pwn;?HT}w&KFy8*EihsGk^YK_x z(S+K|>ZitqAqqOm8owqzW-MmCweuXDIAk&Joqt+RvHc|33m(RO;8WzfdH{|(YB>}l zQF!Pe7K;Uk!@;D9lNe#nBJbX@0JQnN*ov+q=lF41tsLn{!ZLFf1M~&}WL4vX^VI;n z{6Go;S>bB6qg&~0H5<qt6p5|A2$!#cMZ;eM{!tejL=)NZ`4rvS$)JcFB3^om#<g#t z1%G6m{s8xm8QzuFd2{D6!koppL8H5z2N^7kP9DMJ6*IUMYUR{ETdylraIuCqzryMX zgD@H-F5PNC(>nLw*z|b3ffi2Q+DUeNJ_gYY+)<MZPnd?R1~^}R7*p=O1W%ug7#+#d zC!e6D$-&YkOUcj6C%!e3ywtIX-%*?NCVyGg_}>yco6l8~l^n^i#0Y{+dWI&1lMofm zh3X^7N(Unnr+1C%x@99Q@yyPAnZ3oY6BU$1*2<>|TfPvT$;69W)A{oUe`2)x9!4bI zbJt*ZO4T$rpSw*<dw@0hspS477QG~JrQtN^ZXaS!_AA|*O5N(nr0`6#<0evgbALN^ zZ8s5ug9!K)8f>-X4S9gvf%hTYWqsTiWMR33wt#{`FH-L*=kpsMk`<RnQdm|u+iuYW zoybqqo+dVU5IZieqqg-1dXt`n`;rl)yH9Cf(u+FsQX&X4h}hk?*nZ*H#0C#yO4>6$ zwob3hF*D-@lEZWOYw;V{8oprEl7I0`e0eI?n2;X~mk?s&k25n^J292AhEwdh{0EZ5 zvY46iLa+9{J~qsHEAw)G#j$H!ICAyBXlkowWcoB_zxg<&hyG6aSJ!dXwxG&NkFmO5 z{OLu3LE&bmr$w`DL?Z2h7EV>{;%wDHvg7lalJ-oW6Y94=sHh6JTWox6+kb#07#Kfz z0oif+D1L>uW;ZuaUZwoZ4ceOANJc%=UwxD&vxx<}{*E`G5N|ayJuRA_WyCSSYQ!Yz zu+<m+qk-AM!<jFU6qeQRiSWHzz)qi?^VOeFVlTvMj3O<1G$|3^w17K2?P#ioDWvo4 zYW4;Y1s!1~sjCHC;k?YXhJUYdwf~4M;BTu#@p1Cz4zARnCZM(>Ad(cGNn+SAA}tA6 z^j0)FzXCLSYpHQvrP66b)nxR7iHz8><fkq||6@1Nzb#+Djl)+<y}O(mR~e0-+q8Bx zclA>YqL~n5BvHWwNemrEOmH%hcYFo78~q<jnQUAVBnMsq0000<MFvhpu0mjfK50Ho delta 2276 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 diff --git a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x-1.png b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x-1.png index 680ebe06bf95967d1430693b306bd5b6a4009a61..c6e2c9cf6b296f380bb36f855d5140f1a56e1e55 100644 GIT binary patch literal 7785 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 delta 5231 zcmV-#6p-ubJo6}!Gk+8+Nkl<Zc%1E=cXV9UoyR}-y*Ir{qb^wm+p;B7jIlA`LtC&3 z#eof-VAv%jB!PuZ!csQmY)Ce+0X6|PkT@jS5VEEiI4K4bnlarm#vofR*s`r+tGAIx z)85Rx`^S^VWk!9*PR`-`hmLgX?|pUe{oeAsS4b%(pJUQcj(@fRfA9F5z$xN$0;dS= zXd7@iq?CkXA)-bYDH2F2QP8jnI}W=GfjHVG9)hDrU^E_~H_|~*q?5e^4YUMz(H?H0 zC)`e4#6U>)%bOVfsTvx2j$(?P6_mNBQ{ky5&t8b%QG{J{9F^}7M_Prug6+KC{5<u6 zbwm?kbR&u(jekj%B@kE?8+Ogf9Nz*KmtR4#XIh3W9>azsL116Fn~yu!QrG<<jYHcw zxJtX~pvYN4p|gxUdm&z{AD6|8O|_#53m}L~ome8mkUqdbtdHJE2OZ&kbcC7-$3q7` zMhGgLvzVK|h?5G>B;Q$_?N7@dff7kb5As&?A9;P>N`DeE4uB#QY^sy#zFN*GSxSw6 z-Y`)UM?%Kg(O<{AtuNCM*i0lI#*hiK9u&?gy_Ch3m*cW}vo>~Sg+RkFc%|_f)^)r} zf2<pcS;hRqGdZpJe9Bx^c&xb@tuv?xXdP-~UHj{N)VU_v%6-;678Wk%qN-(RYUYRh zj1nl3G=KEfvvTL-w1t}ha9h08`WJ9v<+T(zN)JsP8N>*7U<6u8bbdynXAj0e8*1J$ z*cW{R#ZzRajCK*-{wRroZ77aX6!#2NUoFB_fnqO4SaaZ@7S<c-WOdX3v8CrD2K9ab z@@*wtU41LF{c{l_bF;UM5tuL%{Gs93yx0CRaet`;FvouqS6AOguC3q@qZ8c?#5TQ1 zykk2u9)X0OQl6SK4c8?<1tAD;_!fzQ?WvV27KCa?_0?dhyav@bhy6rKB!OrT&o?Zm zuKRreG-2VC!o^%U>t<9XGp#Wr1a^g5d7)uBTl+soN`oS2IZLaqV_v}-$uu%DfWG@} z^ncy&ljzwEV<@k%xp7~<9HFWVeQ+%@78v786cqP#EJbIb6)#3u{mH1!J?nU>@hSEN z_aG2ddr#oXSvOPcs+iJu!xRaWQqmvk=8?KP>4~<Z2!%QR1>8929xRI0OcalzH?1T5 z!Sb{%ZA8N+O5njzG;FhOK`S~3q1sI|41b;9ZGVuu?hi3!f*fl;w;lfg1@4k53CxrT zZ0M`!f4AMwfZm5HG%lNY6N`$^M^j8yO|)+%vf+0mx_1K;t7b|B4ny(Gz&8B`)Vz~T zdt{uycD%vLoj)gT=(sFiZm7AN8vncrmz}h8G6YH~+10m&C${~NP<#-NC5J1kZ+~H4 z!Rcna9wAo$N1}BvOx~~z5IAft*2*ifR9=J7TmWqC-N1^^9wrd$#jZN}>YVQ}+kfJu zTH>VSs6W!pZ?@l0C_ab~g0CKX&jIqHK|-tVA-d_s$rPOh2x3hy5Z-VbGG;3B9RC8o ze%!q%ib^CA;<wv>OxIA`q)MMKfqz}0RvxLllR>=?k2QyH&3%v=zT=Yd@zy#Lea-MU zwNEQCLVJmKuS<qhc&fSM#E0=&^BB?xcy!a9v<90dT=IknOc)7XXjo29v>jDwTsiZW zL&!62l}vQJJ90Qw`O7`kESvppG({s2>*0llUyv~36Do1s1WF`-X!tc-`+q-15ek>h zyeZjj4~AAY7d7vg2^n!Dpg1eg@=r?%ul3L8>grojgv!pqCZ65#*n~DW#!cYPzRkSf zu^K52=J*$|sQ7#UjPL-F&2JLf{02rSfUtRRUhto&g*D?gBHK_svv4eU7-7vt8bS2X zyXc{{NW&ZxPcAx#c?G8<k$-&DwTA7z8^>MtxTfQVVX$)N<LE|=B4;@_&bbFou^?k% zdVhNxddF^%U@4hN-i<#;SnW8^y^EpM_h1BCC->DEf?_MgKKBO*%?&b6u<QH8qg%~5 zODW!>M^P0w*Ui42&d^?3g1dNb=VN@&_XHNrI(GSEC6Gv7X?%wEaDOuZOOLrOIY|z_ z_w+D%=D4S~?WFgq+mkKPb>V%eMMtkCs-9UmPJR?&^&^cC!LI)x9^HaDMoSF6mB_%; z0BDMZrN>+kKu@%Tml~f!j-xA&Nnl71vaaJ*0Ot7TGcVs<p2ZqJCAjv<6t#^tZ=&Z{ z-^2(FnB95F_fY*+<A49^3_)?0W1sh5N%97}?m~|o-ZdqWffv!ke+A%J|3c;$o(;hI zjx_{h17p`SR)V*h|44tV8@I*F)z!C|)#?!jUVVJTJn^0u`kwxGWGsTv>^K*H_lT0H zILmRIcz?3n4t4*CM0Do}sRiNw-y&rgfJ<k54X@SDV7!mjdw-rDyROk9`@&tkzHcQG zNv(eYxwd=&B3s`<-}l+51;?5<(evwXk{IkpIQ=*;{Lv8+7E>@DLD&nCMu5T2bS>{t zB=kmN!PfxrT5~x*{}ce;>v)OIp?#y~9hJb1UGFA$k}s^h79kXjP(Oh`J-~S8dU|^U zeZRl+KubLLE`JnX>6rN@i&Vk*;qaI@HbVVRU?jQ_2rjBzh9XoXk`0|}N3V0V$WOb> zeYE+7XC*g7!=Ju}jK{`h6oB4-WQ1j8!5AlGg4oa-0C=r_PAfhSfKA;Wj+$*m0=t6k zG!AV;5elaje<2wj+5E=%jT%O_g=Kt#F%CP2*0R56Eq^RJ2UTe74ez44uVLi6M~Zl( z<$0u(*i<KFt||cZecOn&jXw5`glq}R!~|n>B=lzV$R_}lxT<hyPLS|g%gT}KPZt=C zN7&qNF1)9EYljbjB*Axn560xqa3S-;G8w@b9g=9^SwP~{+|>FP0MHQJL`V;&&5@SC zo=7{<gnudPXOu1lz!(Y;YpR=qaV9b)EK?DT(Gb^nV<dV2IJ4}F07MgEdcy7L?MN5c z8}39mqS#eOa<?|o*NTiqrfeWgU09|p7^6VS2u9o_tI9JQx5bBU=yZnC?-!;euw`%; zhBPR0RU{9+<K4{@Qs1#KSz*bPV2lVEC!y~KOn=vr5?3W4X&&5>-kx-UErX`&6gtY1 zVX>C_%o#b1i3&?51!GjZB3qNc@8_Upa94Vp(gk)z_5$Fy7al0IE%S!Leqp(J1YtQa zS<k#+jEsbSfUG>bdAQ#mYEGLrg+M7~a=`Q*bhaAr*_%-#4~E{pGeuaevz8!KD<~S4 z(tnGxA{ZmV90P}4Lu@7oLD^3<8cj)?LSQ%+GX3)am&Kb5x0F<8!`37Y7Z%(6Ye7)~ zfpz*nWkoPXf@(R2{T>cZ%>#hMU?AF`k~U>SHEM)GNRR^C@S!w-?~*&|U2!+YU=P`H z5{-8^GW7m)c$VChHa<4Ans{s{Lh)qB0DnMHeYo=PNd9eChaER1L<yy&Pa)8Bt2H?~ z*zHWsEv4X=Cy{!TY#tg3%{F43&2uSM*F{;Y8$c*F4(^!hu#<q45<{dOIHeMJ2swu} zHKBm8kkwPSQ9P$43I_HO<1+zug54{HKt*cFBKCV(0VF!R>A&|UBwDh2#^Jp93xBx3 z_T{v3^?Q2wbaz))>-RXUoI9@^k7L+9Wq3PJ2!SHil=LYC+Jv3`EiaZhu<{sq=ojdl z)3}&r5SE&mI4`?k#Q5rIIW%?*(B3zcH5($aIB(UpaPg_r&A;R3k`@6roGIy3`isNv zLN!cYhx7wy0{WKpGx1D8t0=?&(|>zW{JH4i7~5X@6ls{A`cHnmkN$8RyG7-KlPk&d zX4fOXI}lDD^@QSs00=4Y+Ecx1QwS6Y@*Jjf_CTyJ8LpOP&tY4uC?oeL-$!^{81V$} zKJqGCR((P|7DqP>p7^MRoBy<hu%19u70zFfT@u|6D`I#Y3q*SXa49}))_+uiOFLp0 zIm!X(jdUc#wCe158(3;)lDGT;)Zzl717Y60Zx!wJsgw4NtpToiwvNtV45v-w;!}^I zDA$!0oASH|gsL}ca!~9{?~Iw2z-gWt0Ca>89H>~2o1HNO_d_kpC-;HxCR^S+5C4U( z9V2^5ZSM;5^*_`nTjF{1D}V60MxORe7DYJ+#=5SsDVpW(8EMm|C9uLh6M>*3)SOfy zt#TT|GP&yr>0qguN!}9=Cda(DA6iY<j`VwO2V+}TkQ-mDr$4M?x2Rlv+H{ID*b)^X z4r+mt)}cl~P~n-CK7G2tJZBLW#YQ+DVn_cb0MwEqgd;O^u)_u8&42q=(Uzv$j)aY^ z0j_?wE-S*KsR~}F>3Pu-+{Iw54~t@<&{dW;eOdzj_9E<>*^J+9eaTFi>%%%H{eNLX z1|B9D?>+J=y?Z(*Tux(OC@aE}>#^aqnLX{D)>VMOs@m}n@5&sGv;^8U2esb$05k+P z6VwAB1g`5Z17-3H;eT|3F_D&cII<xuC(bB92nffAsPA46z;ySqxUK2e-y^P@mXu$C z5Q0cNJUkA7<+vIwGbX3T6BUf{B9p?B<FZj+U=r09Y9gEnf`BDuSB#ivL;{Pw<y5$4 zVaNpQ+Fv&Vg}}Zz)v0nU94;7ZA9`h6f-zoXN?2x;`jX4okAFMY5;x+M*sGYHS36>! zQ9Tpp<}U)^qs}$-Ma*%^asJr|ZTz=<4i}6y_x+jn`j&C$A20TI=gA6-A_UcC=1L=| z5Aa^=D*&93m+IAeNWRe`PbxSQMJPxqS>3b(iA3?|;{8tg{kp@EZiUgaCwrR#d!`^P z3uYJLaac@$$bY64BxD>#5iBS?Yt($B5}5BS<{wHf1)#onJ%OlsUTR-*CYG6_kA<m% z@#nNFj7(!P!jj{*F{gZZ>s}8~*Zlzi3-ivS#8WwH-ZA|HmsDPk&zi?zte@u_mIEN{ zHr(I1Zp5n$=>;QmW8PSpsIbhRS%gJ1saUn=N&2JRxPLVtUz~CMn01Xwpv&rIVc}u` z>bl=&bC2orVLN3Wt}lOy<f?lZlU-qC8sim~ITe1UmzZZi+xtG@gErF}cYeWHc*k+4 zc}xNYf{Ut_k#8#j;HAc=h#TfctNZ%P(aI0FWoVVtQUqfv^Sr5ItQCvLVP$@`d32kQ zab9kG3V$#!X<stqD+n?6oOj%J<+k-~<d<9SB`$U56`a98*WQULG>pD}qVI1&8V2^$ z7ozxcFyaZ`e&`k2rl7V~x1CEKU52!%oc*iy^oAzy6>(CjkKbH&91e?0B$lA5a{wu! zyugjiZo!ZVp4ss~eAxaPn$Y-4?LC}OaO$|q9)I^ek=eO(Sy;FjfuOGY1J-xEX%>*1 zgJbDpoEM*m;?E&A6lKl*tENO=rm?X#z?Yw^qc5yux2nvZmP<`}E-t&dWZT&FF6%qi z05CW2bdJqGdE8}>n?OZTxoXzURC`arkO`jK`8Zp9H>9L%-@KR346HCRjcuJl*6iv@ z34h-;u!R+$JxoHzsq)lvUG43tBK7QJBuwb8oT_MCIqPO}tog(ZofV%wO!MHOE+57e z{0Fm*#9^kj4K?xPwg=IT7;cM?t7hJUHo>O=CVX47*j2%8$3K9};w2F4<-b4uHZ2E{ zSbW?xJVm~&9llQn0+{BtbJp|&s@gWx#D9Yu|CPQ-Cl1ZUt;hYCa&P)g)6p=g`@#k8 z5^kuu8@uYnFcK`U{{h>2KL)_=b?}8BUPjINbN?nTZA#$kxg|V*?L3Oy=3H>sz!rX9 z{~zc^6pLcx`q_6->K%Q;JQ5~Fpg>ULpT}2g@4=;c2*i5$<(41tVf$+&WE`u@#(zo6 z7ID_UT|iE`f9wLYgz0`K4==6d`{!1Z>#$%*gAJW)d93cc$(DCR&D|WIf6AoaO_<uF z6G*y-T6uKST?Ar1C_-gk!RcH#`}X9!3Gs-|uD7@I$%+p!4j+U@!BnO(st|np^eV2I zTZ+qS3PM80d1lAY_^4wI2^q(&`G2_e_#ad1tvq^<PV7hPU=uIw`UN`!n~+G#-7{Ev z%=H}WUzki2>It&v-Op(Juz|q7-Z8tk)ote=A6<qqP67o`<#%x5>_WaYr-*631IG{B z`#$02#;4db{Ps+hr<SX#Z=u{X@i8x@-poC`6X%)Fe#VCGw~{NB`Gsc>-+w*JJ@8+a zlD7K2Z28kh`kQ))NA<KV(_5UwMGsvKLU7rNjcn~q^^(^Vfy1IQGtbFQr&MrOl|Q** zE|CQF0IT*qnOvS}LgU2zGgwyhoe8V$NXY2ZPlhzu-unqF8y=%OVy=I^RzJt*pUOp* z*Wx|MVN*&;xGzMobAbNlZhyLVwA0_zL$GUrobo(Q`{ucLOLG9&8;EenU$#@<9;D1` zr>4NgyizZ<g>K4yc8c6ql!KOCL4AN%npRNP{Q>>aZUB6iJg%z#7mm$8c|!BNv5=L= z$MkrNml~g9edihmb<?{+5h{y{&*S8xb189E;?&$}^GYd4T!W4l7k`cq(H3gr<IcBv zuXT0uIM${4SWs{l7f-(do0fUcuIxR3Ck=wJ0aovRn)kb2PQF8+3Jr(mWR8CUXOu0a z%2P9iL0r-j+{HWlR#D%xo^T>aeE87_p$JaRJCCI^t~ZB}acm4s21n!p#?GOAY#4rk zabI}XAp+vI_$YBzQh(?uBhOxh&*sOed9bU_<O5*|BTgg{CKMke5bdQm(m`jWmA0Wq z24e@g-3lnNS1~t#5%UYq9CI@?6FA~efHwCv@Y>#$Gz@MUegafy@-uFMMX_L2?M!za z%aUnVjCuf+4IFU-_ameS=?S;f6>6hta0e~H20DgX7?k};3}}!fA5j#-{2`>kt>jST zET`N(gG%3Q3LK^6*^6+EaBiDz95n(*LNpp>Al6Sr4ke#KR?)CZ2R?^Ct&7>w#NQl& pe{cBwCG#oba{{M`&k39&{vWFTXb-!L_>2Gm002ovPDHLkV1hJJ0Sy2E diff --git a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x.png b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x.png index 680ebe06bf95967d1430693b306bd5b6a4009a61..c6e2c9cf6b296f380bb36f855d5140f1a56e1e55 100644 GIT binary patch literal 7785 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 delta 5231 zcmV-#6p-ubJo6}!Gk+8+Nkl<Zc%1E=cXV9UoyR}-y*Ir{qb^wm+p;B7jIlA`LtC&3 z#eof-VAv%jB!PuZ!csQmY)Ce+0X6|PkT@jS5VEEiI4K4bnlarm#vofR*s`r+tGAIx z)85Rx`^S^VWk!9*PR`-`hmLgX?|pUe{oeAsS4b%(pJUQcj(@fRfA9F5z$xN$0;dS= zXd7@iq?CkXA)-bYDH2F2QP8jnI}W=GfjHVG9)hDrU^E_~H_|~*q?5e^4YUMz(H?H0 zC)`e4#6U>)%bOVfsTvx2j$(?P6_mNBQ{ky5&t8b%QG{J{9F^}7M_Prug6+KC{5<u6 zbwm?kbR&u(jekj%B@kE?8+Ogf9Nz*KmtR4#XIh3W9>azsL116Fn~yu!QrG<<jYHcw zxJtX~pvYN4p|gxUdm&z{AD6|8O|_#53m}L~ome8mkUqdbtdHJE2OZ&kbcC7-$3q7` zMhGgLvzVK|h?5G>B;Q$_?N7@dff7kb5As&?A9;P>N`DeE4uB#QY^sy#zFN*GSxSw6 z-Y`)UM?%Kg(O<{AtuNCM*i0lI#*hiK9u&?gy_Ch3m*cW}vo>~Sg+RkFc%|_f)^)r} zf2<pcS;hRqGdZpJe9Bx^c&xb@tuv?xXdP-~UHj{N)VU_v%6-;678Wk%qN-(RYUYRh zj1nl3G=KEfvvTL-w1t}ha9h08`WJ9v<+T(zN)JsP8N>*7U<6u8bbdynXAj0e8*1J$ z*cW{R#ZzRajCK*-{wRroZ77aX6!#2NUoFB_fnqO4SaaZ@7S<c-WOdX3v8CrD2K9ab z@@*wtU41LF{c{l_bF;UM5tuL%{Gs93yx0CRaet`;FvouqS6AOguC3q@qZ8c?#5TQ1 zykk2u9)X0OQl6SK4c8?<1tAD;_!fzQ?WvV27KCa?_0?dhyav@bhy6rKB!OrT&o?Zm zuKRreG-2VC!o^%U>t<9XGp#Wr1a^g5d7)uBTl+soN`oS2IZLaqV_v}-$uu%DfWG@} z^ncy&ljzwEV<@k%xp7~<9HFWVeQ+%@78v786cqP#EJbIb6)#3u{mH1!J?nU>@hSEN z_aG2ddr#oXSvOPcs+iJu!xRaWQqmvk=8?KP>4~<Z2!%QR1>8929xRI0OcalzH?1T5 z!Sb{%ZA8N+O5njzG;FhOK`S~3q1sI|41b;9ZGVuu?hi3!f*fl;w;lfg1@4k53CxrT zZ0M`!f4AMwfZm5HG%lNY6N`$^M^j8yO|)+%vf+0mx_1K;t7b|B4ny(Gz&8B`)Vz~T zdt{uycD%vLoj)gT=(sFiZm7AN8vncrmz}h8G6YH~+10m&C${~NP<#-NC5J1kZ+~H4 z!Rcna9wAo$N1}BvOx~~z5IAft*2*ifR9=J7TmWqC-N1^^9wrd$#jZN}>YVQ}+kfJu zTH>VSs6W!pZ?@l0C_ab~g0CKX&jIqHK|-tVA-d_s$rPOh2x3hy5Z-VbGG;3B9RC8o ze%!q%ib^CA;<wv>OxIA`q)MMKfqz}0RvxLllR>=?k2QyH&3%v=zT=Yd@zy#Lea-MU zwNEQCLVJmKuS<qhc&fSM#E0=&^BB?xcy!a9v<90dT=IknOc)7XXjo29v>jDwTsiZW zL&!62l}vQJJ90Qw`O7`kESvppG({s2>*0llUyv~36Do1s1WF`-X!tc-`+q-15ek>h zyeZjj4~AAY7d7vg2^n!Dpg1eg@=r?%ul3L8>grojgv!pqCZ65#*n~DW#!cYPzRkSf zu^K52=J*$|sQ7#UjPL-F&2JLf{02rSfUtRRUhto&g*D?gBHK_svv4eU7-7vt8bS2X zyXc{{NW&ZxPcAx#c?G8<k$-&DwTA7z8^>MtxTfQVVX$)N<LE|=B4;@_&bbFou^?k% zdVhNxddF^%U@4hN-i<#;SnW8^y^EpM_h1BCC->DEf?_MgKKBO*%?&b6u<QH8qg%~5 zODW!>M^P0w*Ui42&d^?3g1dNb=VN@&_XHNrI(GSEC6Gv7X?%wEaDOuZOOLrOIY|z_ z_w+D%=D4S~?WFgq+mkKPb>V%eMMtkCs-9UmPJR?&^&^cC!LI)x9^HaDMoSF6mB_%; z0BDMZrN>+kKu@%Tml~f!j-xA&Nnl71vaaJ*0Ot7TGcVs<p2ZqJCAjv<6t#^tZ=&Z{ z-^2(FnB95F_fY*+<A49^3_)?0W1sh5N%97}?m~|o-ZdqWffv!ke+A%J|3c;$o(;hI zjx_{h17p`SR)V*h|44tV8@I*F)z!C|)#?!jUVVJTJn^0u`kwxGWGsTv>^K*H_lT0H zILmRIcz?3n4t4*CM0Do}sRiNw-y&rgfJ<k54X@SDV7!mjdw-rDyROk9`@&tkzHcQG zNv(eYxwd=&B3s`<-}l+51;?5<(evwXk{IkpIQ=*;{Lv8+7E>@DLD&nCMu5T2bS>{t zB=kmN!PfxrT5~x*{}ce;>v)OIp?#y~9hJb1UGFA$k}s^h79kXjP(Oh`J-~S8dU|^U zeZRl+KubLLE`JnX>6rN@i&Vk*;qaI@HbVVRU?jQ_2rjBzh9XoXk`0|}N3V0V$WOb> zeYE+7XC*g7!=Ju}jK{`h6oB4-WQ1j8!5AlGg4oa-0C=r_PAfhSfKA;Wj+$*m0=t6k zG!AV;5elaje<2wj+5E=%jT%O_g=Kt#F%CP2*0R56Eq^RJ2UTe74ez44uVLi6M~Zl( z<$0u(*i<KFt||cZecOn&jXw5`glq}R!~|n>B=lzV$R_}lxT<hyPLS|g%gT}KPZt=C zN7&qNF1)9EYljbjB*Axn560xqa3S-;G8w@b9g=9^SwP~{+|>FP0MHQJL`V;&&5@SC zo=7{<gnudPXOu1lz!(Y;YpR=qaV9b)EK?DT(Gb^nV<dV2IJ4}F07MgEdcy7L?MN5c z8}39mqS#eOa<?|o*NTiqrfeWgU09|p7^6VS2u9o_tI9JQx5bBU=yZnC?-!;euw`%; zhBPR0RU{9+<K4{@Qs1#KSz*bPV2lVEC!y~KOn=vr5?3W4X&&5>-kx-UErX`&6gtY1 zVX>C_%o#b1i3&?51!GjZB3qNc@8_Upa94Vp(gk)z_5$Fy7al0IE%S!Leqp(J1YtQa zS<k#+jEsbSfUG>bdAQ#mYEGLrg+M7~a=`Q*bhaAr*_%-#4~E{pGeuaevz8!KD<~S4 z(tnGxA{ZmV90P}4Lu@7oLD^3<8cj)?LSQ%+GX3)am&Kb5x0F<8!`37Y7Z%(6Ye7)~ zfpz*nWkoPXf@(R2{T>cZ%>#hMU?AF`k~U>SHEM)GNRR^C@S!w-?~*&|U2!+YU=P`H z5{-8^GW7m)c$VChHa<4Ans{s{Lh)qB0DnMHeYo=PNd9eChaER1L<yy&Pa)8Bt2H?~ z*zHWsEv4X=Cy{!TY#tg3%{F43&2uSM*F{;Y8$c*F4(^!hu#<q45<{dOIHeMJ2swu} zHKBm8kkwPSQ9P$43I_HO<1+zug54{HKt*cFBKCV(0VF!R>A&|UBwDh2#^Jp93xBx3 z_T{v3^?Q2wbaz))>-RXUoI9@^k7L+9Wq3PJ2!SHil=LYC+Jv3`EiaZhu<{sq=ojdl z)3}&r5SE&mI4`?k#Q5rIIW%?*(B3zcH5($aIB(UpaPg_r&A;R3k`@6roGIy3`isNv zLN!cYhx7wy0{WKpGx1D8t0=?&(|>zW{JH4i7~5X@6ls{A`cHnmkN$8RyG7-KlPk&d zX4fOXI}lDD^@QSs00=4Y+Ecx1QwS6Y@*Jjf_CTyJ8LpOP&tY4uC?oeL-$!^{81V$} zKJqGCR((P|7DqP>p7^MRoBy<hu%19u70zFfT@u|6D`I#Y3q*SXa49}))_+uiOFLp0 zIm!X(jdUc#wCe158(3;)lDGT;)Zzl717Y60Zx!wJsgw4NtpToiwvNtV45v-w;!}^I zDA$!0oASH|gsL}ca!~9{?~Iw2z-gWt0Ca>89H>~2o1HNO_d_kpC-;HxCR^S+5C4U( z9V2^5ZSM;5^*_`nTjF{1D}V60MxORe7DYJ+#=5SsDVpW(8EMm|C9uLh6M>*3)SOfy zt#TT|GP&yr>0qguN!}9=Cda(DA6iY<j`VwO2V+}TkQ-mDr$4M?x2Rlv+H{ID*b)^X z4r+mt)}cl~P~n-CK7G2tJZBLW#YQ+DVn_cb0MwEqgd;O^u)_u8&42q=(Uzv$j)aY^ z0j_?wE-S*KsR~}F>3Pu-+{Iw54~t@<&{dW;eOdzj_9E<>*^J+9eaTFi>%%%H{eNLX z1|B9D?>+J=y?Z(*Tux(OC@aE}>#^aqnLX{D)>VMOs@m}n@5&sGv;^8U2esb$05k+P z6VwAB1g`5Z17-3H;eT|3F_D&cII<xuC(bB92nffAsPA46z;ySqxUK2e-y^P@mXu$C z5Q0cNJUkA7<+vIwGbX3T6BUf{B9p?B<FZj+U=r09Y9gEnf`BDuSB#ivL;{Pw<y5$4 zVaNpQ+Fv&Vg}}Zz)v0nU94;7ZA9`h6f-zoXN?2x;`jX4okAFMY5;x+M*sGYHS36>! zQ9Tpp<}U)^qs}$-Ma*%^asJr|ZTz=<4i}6y_x+jn`j&C$A20TI=gA6-A_UcC=1L=| z5Aa^=D*&93m+IAeNWRe`PbxSQMJPxqS>3b(iA3?|;{8tg{kp@EZiUgaCwrR#d!`^P z3uYJLaac@$$bY64BxD>#5iBS?Yt($B5}5BS<{wHf1)#onJ%OlsUTR-*CYG6_kA<m% z@#nNFj7(!P!jj{*F{gZZ>s}8~*Zlzi3-ivS#8WwH-ZA|HmsDPk&zi?zte@u_mIEN{ zHr(I1Zp5n$=>;QmW8PSpsIbhRS%gJ1saUn=N&2JRxPLVtUz~CMn01Xwpv&rIVc}u` z>bl=&bC2orVLN3Wt}lOy<f?lZlU-qC8sim~ITe1UmzZZi+xtG@gErF}cYeWHc*k+4 zc}xNYf{Ut_k#8#j;HAc=h#TfctNZ%P(aI0FWoVVtQUqfv^Sr5ItQCvLVP$@`d32kQ zab9kG3V$#!X<stqD+n?6oOj%J<+k-~<d<9SB`$U56`a98*WQULG>pD}qVI1&8V2^$ z7ozxcFyaZ`e&`k2rl7V~x1CEKU52!%oc*iy^oAzy6>(CjkKbH&91e?0B$lA5a{wu! zyugjiZo!ZVp4ss~eAxaPn$Y-4?LC}OaO$|q9)I^ek=eO(Sy;FjfuOGY1J-xEX%>*1 zgJbDpoEM*m;?E&A6lKl*tENO=rm?X#z?Yw^qc5yux2nvZmP<`}E-t&dWZT&FF6%qi z05CW2bdJqGdE8}>n?OZTxoXzURC`arkO`jK`8Zp9H>9L%-@KR346HCRjcuJl*6iv@ z34h-;u!R+$JxoHzsq)lvUG43tBK7QJBuwb8oT_MCIqPO}tog(ZofV%wO!MHOE+57e z{0Fm*#9^kj4K?xPwg=IT7;cM?t7hJUHo>O=CVX47*j2%8$3K9};w2F4<-b4uHZ2E{ zSbW?xJVm~&9llQn0+{BtbJp|&s@gWx#D9Yu|CPQ-Cl1ZUt;hYCa&P)g)6p=g`@#k8 z5^kuu8@uYnFcK`U{{h>2KL)_=b?}8BUPjINbN?nTZA#$kxg|V*?L3Oy=3H>sz!rX9 z{~zc^6pLcx`q_6->K%Q;JQ5~Fpg>ULpT}2g@4=;c2*i5$<(41tVf$+&WE`u@#(zo6 z7ID_UT|iE`f9wLYgz0`K4==6d`{!1Z>#$%*gAJW)d93cc$(DCR&D|WIf6AoaO_<uF z6G*y-T6uKST?Ar1C_-gk!RcH#`}X9!3Gs-|uD7@I$%+p!4j+U@!BnO(st|np^eV2I zTZ+qS3PM80d1lAY_^4wI2^q(&`G2_e_#ad1tvq^<PV7hPU=uIw`UN`!n~+G#-7{Ev z%=H}WUzki2>It&v-Op(Juz|q7-Z8tk)ote=A6<qqP67o`<#%x5>_WaYr-*631IG{B z`#$02#;4db{Ps+hr<SX#Z=u{X@i8x@-poC`6X%)Fe#VCGw~{NB`Gsc>-+w*JJ@8+a zlD7K2Z28kh`kQ))NA<KV(_5UwMGsvKLU7rNjcn~q^^(^Vfy1IQGtbFQr&MrOl|Q** zE|CQF0IT*qnOvS}LgU2zGgwyhoe8V$NXY2ZPlhzu-unqF8y=%OVy=I^RzJt*pUOp* z*Wx|MVN*&;xGzMobAbNlZhyLVwA0_zL$GUrobo(Q`{ucLOLG9&8;EenU$#@<9;D1` zr>4NgyizZ<g>K4yc8c6ql!KOCL4AN%npRNP{Q>>aZUB6iJg%z#7mm$8c|!BNv5=L= z$MkrNml~g9edihmb<?{+5h{y{&*S8xb189E;?&$}^GYd4T!W4l7k`cq(H3gr<IcBv zuXT0uIM${4SWs{l7f-(do0fUcuIxR3Ck=wJ0aovRn)kb2PQF8+3Jr(mWR8CUXOu0a z%2P9iL0r-j+{HWlR#D%xo^T>aeE87_p$JaRJCCI^t~ZB}acm4s21n!p#?GOAY#4rk zabI}XAp+vI_$YBzQh(?uBhOxh&*sOed9bU_<O5*|BTgg{CKMke5bdQm(m`jWmA0Wq z24e@g-3lnNS1~t#5%UYq9CI@?6FA~efHwCv@Y>#$Gz@MUegafy@-uFMMX_L2?M!za z%aUnVjCuf+4IFU-_ameS=?S;f6>6hta0e~H20DgX7?k};3}}!fA5j#-{2`>kt>jST zET`N(gG%3Q3LK^6*^6+EaBiDz95n(*LNpp>Al6Sr4ke#KR?)CZ2R?^Ct&7>w#NQl& pe{cBwCG#oba{{M`&k39&{vWFTXb-!L_>2Gm002ovPDHLkV1hJJ0Sy2E diff --git a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Spotlight-40@3x.png b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon-Spotlight-40@3x.png index 635a47187aac9b4a1a18568cd7e534c6e54d398d..c07c472f62b12a0a5e84beaf0271e3ceffc2be37 100644 GIT binary patch literal 15603 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 E2j@xDl>h($ literal 10478 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 diff --git a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon.png b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon.png index 3ce58cfebe877876235e7431bfe82d49db187c60..deb4a6cac1d3ba878d41daebbb1fc2180660dffd 100644 GIT binary patch literal 5972 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 CRD(kR delta 4168 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 SetOIR0000<MNUMnLSTX}Z6=!l diff --git a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon@2x.png b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost/Images.xcassets/AppIcon.appiconset/Icon@2x.png index 21c396fa5b47fad71849dfd5f89f0eebb50d412a..19a9694ee66a3f35a7ae1a315c80e3fb3e1d7899 100644 GIT binary patch literal 14348 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 BIeq{D literal 9928 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 GLSTYJ3XabJ diff --git a/extras/AudioPluginHost/Builds/iOS/Icon.icns b/extras/AudioPluginHost/Builds/iOS/Icon.icns index 6ab6915802b8cc41702a02e8527aec517d379e77..f207907bcc6e8f34af7435566a26e177fb8b2c83 100644 GIT binary patch literal 95248 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 V<XRb01a={UloizFt7I)A{|}PSUd#Xh literal 89670 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 S)d9x$gS6E2RqK#;(f<d)_aL<Z diff --git a/extras/AudioPluginHost/Builds/iOS/Info-App.plist b/extras/AudioPluginHost/Builds/iOS/Info-App.plist index 6d0ce749..72fec6e8 100644 --- a/extras/AudioPluginHost/Builds/iOS/Info-App.plist +++ b/extras/AudioPluginHost/Builds/iOS/Info-App.plist @@ -14,7 +14,7 @@ <key>CFBundleExecutable</key> <string>${EXECUTABLE_NAME}</string> <key>CFBundleIdentifier</key> - <string>com.roli.juce.pluginhost</string> + <string>com.juce.pluginhost</string> <key>CFBundleName</key> <string>AudioPluginHost</string> <key>CFBundleDisplayName</key> @@ -28,7 +28,7 @@ <key>CFBundleVersion</key> <string>1.0.0</string> <key>NSHumanReadableCopyright</key> - <string>ROLI Ltd.</string> + <string>Raw Material Software Limited</string> <key>NSHighResolutionCapable</key> <true/> <key>UIRequiresFullScreen</key> @@ -36,11 +36,7 @@ <key>UIStatusBarHidden</key> <true/> <key>UISupportedInterfaceOrientations</key> - <array> - <string>UIInterfaceOrientationPortrait</string> - <string>UIInterfaceOrientationLandscapeLeft</string> - <string>UIInterfaceOrientationLandscapeRight</string> - </array> + <array/> <key>UIBackgroundModes</key> <array> <string>audio</string> diff --git a/extras/AudioPluginHost/CMakeLists.txt b/extras/AudioPluginHost/CMakeLists.txt new file mode 100644 index 00000000..7fc47b55 --- /dev/null +++ b/extras/AudioPluginHost/CMakeLists.txt @@ -0,0 +1,65 @@ +# ============================================================================== +# +# This file is part of the JUCE library. +# Copyright (c) 2020 - Raw Material Software Limited +# +# JUCE is an open source library subject to commercial or open-source +# licensing. +# +# By using JUCE, you agree to the terms of both the JUCE 6 End-User License +# Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). +# +# End User License Agreement: www.juce.com/juce-6-licence +# Privacy Policy: www.juce.com/juce-privacy-policy +# +# Or: You may also use this code under the terms of the GPL v3 (see +# www.gnu.org/licenses). +# +# JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER +# EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE +# DISCLAIMED. +# +# ============================================================================== + +juce_add_gui_app(AudioPluginHost + BUNDLE_ID com.juce.pluginhost + ICON_BIG "${CMAKE_CURRENT_SOURCE_DIR}/Source/JUCEAppIcon.png" + MICROPHONE_PERMISSION_ENABLED TRUE + PLUGINHOST_AU TRUE) + +juce_generate_juce_header(AudioPluginHost) + +target_sources(AudioPluginHost PRIVATE + Source/HostStartup.cpp + Source/Plugins/IOConfigurationWindow.cpp + Source/Plugins/InternalPlugins.cpp + Source/Plugins/PluginGraph.cpp + Source/UI/GraphEditorPanel.cpp + Source/UI/MainHostWindow.cpp) + +target_compile_definitions(AudioPluginHost PRIVATE + PIP_JUCE_EXAMPLES_DIRECTORY_STRING="${JUCE_SOURCE_DIR}/examples" + JUCE_ALSA=1 + JUCE_DIRECTSOUND=1 + JUCE_PLUGINHOST_LADSPA=1 + JUCE_PLUGINHOST_VST=0 + JUCE_PLUGINHOST_VST3=1 + JUCE_USE_CAMERA=0 + JUCE_USE_CDBURNER=0 + JUCE_USE_CDREADER=0 + JUCE_USE_CURL=0 + JUCE_USE_FLAC=0 + JUCE_USE_OGGVORBIS=1 + JUCE_WASAPI=1 + JUCE_WEB_BROWSER=0) + +target_link_libraries(AudioPluginHost PRIVATE + juce::juce_audio_utils + juce::juce_cryptography + juce::juce_dsp + juce::juce_opengl + juce::juce_recommended_config_flags + juce::juce_recommended_lto_flags + juce::juce_recommended_warning_flags) + +juce_add_bundle_resources_directory(AudioPluginHost ../../examples/Assets) diff --git a/extras/AudioPluginHost/JuceLibraryCode/AppConfig.h b/extras/AudioPluginHost/JuceLibraryCode/AppConfig.h deleted file mode 100644 index 3c4df580..00000000 --- a/extras/AudioPluginHost/JuceLibraryCode/AppConfig.h +++ /dev/null @@ -1,297 +0,0 @@ -/* - - IMPORTANT! This file is auto-generated each time you save your - project - if you alter its contents, your changes may be overwritten! - - There's a section below where you can add your own custom code safely, and the - Projucer will preserve the contents of that block, but the best way to change - any of these definitions is by using the Projucer's project settings. - - Any commented-out settings will assume their default values. - -*/ - -#pragma once - -//============================================================================== -// [BEGIN_USER_CODE_SECTION] - -#ifndef JUCE_ANDROID - #define JUCE_MODAL_LOOPS_PERMITTED (! JUCE_IOS) -#endif - -// [END_USER_CODE_SECTION] - -/* - ============================================================================== - - In accordance with the terms of the JUCE 5 End-Use License Agreement, the - JUCE Code in SECTION A cannot be removed, changed or otherwise rendered - ineffective unless you have a JUCE Indie or Pro license, or are using JUCE - under the GPL v3 license. - - End User License Agreement: www.juce.com/juce-5-licence - - ============================================================================== -*/ - -// BEGIN SECTION A - -#ifndef JUCE_DISPLAY_SPLASH_SCREEN - #define JUCE_DISPLAY_SPLASH_SCREEN 0 -#endif - -#ifndef JUCE_REPORT_APP_USAGE - #define JUCE_REPORT_APP_USAGE 0 -#endif - -// END SECTION A - -#define JUCE_USE_DARK_SPLASH_SCREEN 1 - -#define JUCE_PROJUCER_VERSION 0x50407 - -//============================================================================== -#define JUCE_MODULE_AVAILABLE_juce_audio_basics 1 -#define JUCE_MODULE_AVAILABLE_juce_audio_devices 1 -#define JUCE_MODULE_AVAILABLE_juce_audio_formats 1 -#define JUCE_MODULE_AVAILABLE_juce_audio_processors 1 -#define JUCE_MODULE_AVAILABLE_juce_audio_utils 1 -#define JUCE_MODULE_AVAILABLE_juce_core 1 -#define JUCE_MODULE_AVAILABLE_juce_cryptography 1 -#define JUCE_MODULE_AVAILABLE_juce_data_structures 1 -#define JUCE_MODULE_AVAILABLE_juce_events 1 -#define JUCE_MODULE_AVAILABLE_juce_graphics 1 -#define JUCE_MODULE_AVAILABLE_juce_gui_basics 1 -#define JUCE_MODULE_AVAILABLE_juce_gui_extra 1 -#define JUCE_MODULE_AVAILABLE_juce_opengl 1 -#define JUCE_MODULE_AVAILABLE_juce_video 1 - -#define JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED 1 - -//============================================================================== -// juce_audio_devices flags: - -#ifndef JUCE_USE_WINRT_MIDI - //#define JUCE_USE_WINRT_MIDI 0 -#endif - -#ifndef JUCE_ASIO - //#define JUCE_ASIO 0 -#endif - -#ifndef JUCE_WASAPI - #define JUCE_WASAPI 1 -#endif - -#ifndef JUCE_WASAPI_EXCLUSIVE - //#define JUCE_WASAPI_EXCLUSIVE 0 -#endif - -#ifndef JUCE_DIRECTSOUND - #define JUCE_DIRECTSOUND 1 -#endif - -#ifndef JUCE_ALSA - #define JUCE_ALSA 1 -#endif - -#ifndef JUCE_JACK - //#define JUCE_JACK 0 -#endif - -#ifndef JUCE_BELA - //#define JUCE_BELA 0 -#endif - -#ifndef JUCE_USE_ANDROID_OBOE - //#define JUCE_USE_ANDROID_OBOE 0 -#endif - -#ifndef JUCE_USE_ANDROID_OPENSLES - //#define JUCE_USE_ANDROID_OPENSLES 0 -#endif - -#ifndef JUCE_DISABLE_AUDIO_MIXING_WITH_OTHER_APPS - //#define JUCE_DISABLE_AUDIO_MIXING_WITH_OTHER_APPS 0 -#endif - -//============================================================================== -// juce_audio_formats flags: - -#ifndef JUCE_USE_FLAC - #define JUCE_USE_FLAC 0 -#endif - -#ifndef JUCE_USE_OGGVORBIS - #define JUCE_USE_OGGVORBIS 0 -#endif - -#ifndef JUCE_USE_MP3AUDIOFORMAT - //#define JUCE_USE_MP3AUDIOFORMAT 0 -#endif - -#ifndef JUCE_USE_LAME_AUDIO_FORMAT - //#define JUCE_USE_LAME_AUDIO_FORMAT 0 -#endif - -#ifndef JUCE_USE_WINDOWS_MEDIA_FORMAT - //#define JUCE_USE_WINDOWS_MEDIA_FORMAT 1 -#endif - -//============================================================================== -// juce_audio_processors flags: - -#ifndef JUCE_PLUGINHOST_VST - //#define JUCE_PLUGINHOST_VST 0 -#endif - -#ifndef JUCE_PLUGINHOST_VST3 - #define JUCE_PLUGINHOST_VST3 1 -#endif - -#ifndef JUCE_PLUGINHOST_AU - #define JUCE_PLUGINHOST_AU 1 -#endif - -#ifndef JUCE_PLUGINHOST_LADSPA - #define JUCE_PLUGINHOST_LADSPA 1 -#endif - -//============================================================================== -// juce_audio_utils flags: - -#ifndef JUCE_USE_CDREADER - #define JUCE_USE_CDREADER 0 -#endif - -#ifndef JUCE_USE_CDBURNER - #define JUCE_USE_CDBURNER 0 -#endif - -//============================================================================== -// juce_core flags: - -#ifndef JUCE_FORCE_DEBUG - //#define JUCE_FORCE_DEBUG 0 -#endif - -#ifndef JUCE_LOG_ASSERTIONS - //#define JUCE_LOG_ASSERTIONS 0 -#endif - -#ifndef JUCE_CHECK_MEMORY_LEAKS - //#define JUCE_CHECK_MEMORY_LEAKS 1 -#endif - -#ifndef JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES - //#define JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES 0 -#endif - -#ifndef JUCE_INCLUDE_ZLIB_CODE - //#define JUCE_INCLUDE_ZLIB_CODE 1 -#endif - -#ifndef JUCE_USE_CURL - //#define JUCE_USE_CURL 1 -#endif - -#ifndef JUCE_LOAD_CURL_SYMBOLS_LAZILY - //#define JUCE_LOAD_CURL_SYMBOLS_LAZILY 0 -#endif - -#ifndef JUCE_CATCH_UNHANDLED_EXCEPTIONS - //#define JUCE_CATCH_UNHANDLED_EXCEPTIONS 0 -#endif - -#ifndef JUCE_ALLOW_STATIC_NULL_VARIABLES - //#define JUCE_ALLOW_STATIC_NULL_VARIABLES 0 -#endif - -#ifndef JUCE_STRICT_REFCOUNTEDPOINTER - //#define JUCE_STRICT_REFCOUNTEDPOINTER 0 -#endif - -//============================================================================== -// juce_events flags: - -#ifndef JUCE_EXECUTE_APP_SUSPEND_ON_BACKGROUND_TASK - //#define JUCE_EXECUTE_APP_SUSPEND_ON_BACKGROUND_TASK 0 -#endif - -//============================================================================== -// juce_graphics flags: - -#ifndef JUCE_USE_COREIMAGE_LOADER - //#define JUCE_USE_COREIMAGE_LOADER 1 -#endif - -#ifndef JUCE_USE_DIRECTWRITE - //#define JUCE_USE_DIRECTWRITE 1 -#endif - -#ifndef JUCE_DISABLE_COREGRAPHICS_FONT_SMOOTHING - //#define JUCE_DISABLE_COREGRAPHICS_FONT_SMOOTHING 0 -#endif - -//============================================================================== -// juce_gui_basics flags: - -#ifndef JUCE_ENABLE_REPAINT_DEBUGGING - //#define JUCE_ENABLE_REPAINT_DEBUGGING 0 -#endif - -#ifndef JUCE_USE_XRANDR - //#define JUCE_USE_XRANDR 1 -#endif - -#ifndef JUCE_USE_XINERAMA - //#define JUCE_USE_XINERAMA 1 -#endif - -#ifndef JUCE_USE_XSHM - //#define JUCE_USE_XSHM 1 -#endif - -#ifndef JUCE_USE_XRENDER - //#define JUCE_USE_XRENDER 0 -#endif - -#ifndef JUCE_USE_XCURSOR - //#define JUCE_USE_XCURSOR 1 -#endif - -#ifndef JUCE_WIN_PER_MONITOR_DPI_AWARE - //#define JUCE_WIN_PER_MONITOR_DPI_AWARE 1 -#endif - -//============================================================================== -// juce_gui_extra flags: - -#ifndef JUCE_WEB_BROWSER - #define JUCE_WEB_BROWSER 0 -#endif - -#ifndef JUCE_ENABLE_LIVE_CONSTANT_EDITOR - //#define JUCE_ENABLE_LIVE_CONSTANT_EDITOR 0 -#endif - -//============================================================================== -// juce_video flags: - -#ifndef JUCE_USE_CAMERA - #define JUCE_USE_CAMERA 0 -#endif - -#ifndef JUCE_SYNC_VIDEO_VOLUME_WITH_OS_MEDIA_VOLUME - //#define JUCE_SYNC_VIDEO_VOLUME_WITH_OS_MEDIA_VOLUME 1 -#endif - -//============================================================================== -#ifndef JUCE_STANDALONE_APPLICATION - #if defined(JucePlugin_Name) && defined(JucePlugin_Build_Standalone) - #define JUCE_STANDALONE_APPLICATION JucePlugin_Build_Standalone - #else - #define JUCE_STANDALONE_APPLICATION 1 - #endif -#endif diff --git a/extras/AudioPluginHost/JuceLibraryCode/BinaryData.cpp b/extras/AudioPluginHost/JuceLibraryCode/BinaryData.cpp index de10104f..b2c91fe7 100644 --- a/extras/AudioPluginHost/JuceLibraryCode/BinaryData.cpp +++ b/extras/AudioPluginHost/JuceLibraryCode/BinaryData.cpp @@ -9,650 +9,675 @@ namespace BinaryData //================== JUCEAppIcon.png ================== static const unsigned char temp_binary_data_0[] = -{ 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,2,0,0,0,2,0,8,6,0,0,0,244,120,212,250,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101,60,0,0,3,40,105,84,88,116,88,77,76,58, -99,111,109,46,97,100,111,98,101,46,120,109,112,0,0,0,0,0,60,63,120,112,97,99,107,101,116,32,98,101,103,105,110,61,34,239,187,191,34,32,105,100,61,34,87,53,77,48,77,112,67,101,104,105,72,122,114,101,83,122,78,84,99,122,107,99,57,100,34,63,62,32,60,120, -58,120,109,112,109,101,116,97,32,120,109,108,110,115,58,120,61,34,97,100,111,98,101,58,110,115,58,109,101,116,97,47,34,32,120,58,120,109,112,116,107,61,34,65,100,111,98,101,32,88,77,80,32,67,111,114,101,32,53,46,54,45,99,48,54,55,32,55,57,46,49,53,55, -55,52,55,44,32,50,48,49,53,47,48,51,47,51,48,45,50,51,58,52,48,58,52,50,32,32,32,32,32,32,32,32,34,62,32,60,114,100,102,58,82,68,70,32,120,109,108,110,115,58,114,100,102,61,34,104,116,116,112,58,47,47,119,119,119,46,119,51,46,111,114,103,47,49,57,57, -57,47,48,50,47,50,50,45,114,100,102,45,115,121,110,116,97,120,45,110,115,35,34,62,32,60,114,100,102,58,68,101,115,99,114,105,112,116,105,111,110,32,114,100,102,58,97,98,111,117,116,61,34,34,32,120,109,108,110,115,58,120,109,112,61,34,104,116,116,112, -58,47,47,110,115,46,97,100,111,98,101,46,99,111,109,47,120,97,112,47,49,46,48,47,34,32,120,109,108,110,115,58,120,109,112,77,77,61,34,104,116,116,112,58,47,47,110,115,46,97,100,111,98,101,46,99,111,109,47,120,97,112,47,49,46,48,47,109,109,47,34,32,120, -109,108,110,115,58,115,116,82,101,102,61,34,104,116,116,112,58,47,47,110,115,46,97,100,111,98,101,46,99,111,109,47,120,97,112,47,49,46,48,47,115,84,121,112,101,47,82,101,115,111,117,114,99,101,82,101,102,35,34,32,120,109,112,58,67,114,101,97,116,111, -114,84,111,111,108,61,34,65,100,111,98,101,32,80,104,111,116,111,115,104,111,112,32,67,67,32,50,48,49,53,32,40,77,97,99,105,110,116,111,115,104,41,34,32,120,109,112,77,77,58,73,110,115,116,97,110,99,101,73,68,61,34,120,109,112,46,105,105,100,58,53,52, -53,66,70,48,69,70,55,66,48,54,49,49,69,53,66,51,49,53,69,69,54,51,67,65,56,68,70,50,56,48,34,32,120,109,112,77,77,58,68,111,99,117,109,101,110,116,73,68,61,34,120,109,112,46,100,105,100,58,53,52,53,66,70,48,70,48,55,66,48,54,49,49,69,53,66,51,49,53,69, -69,54,51,67,65,56,68,70,50,56,48,34,62,32,60,120,109,112,77,77,58,68,101,114,105,118,101,100,70,114,111,109,32,115,116,82,101,102,58,105,110,115,116,97,110,99,101,73,68,61,34,120,109,112,46,105,105,100,58,53,52,53,66,70,48,69,68,55,66,48,54,49,49,69, -53,66,51,49,53,69,69,54,51,67,65,56,68,70,50,56,48,34,32,115,116,82,101,102,58,100,111,99,117,109,101,110,116,73,68,61,34,120,109,112,46,100,105,100,58,53,52,53,66,70,48,69,69,55,66,48,54,49,49,69,53,66,51,49,53,69,69,54,51,67,65,56,68,70,50,56,48,34, -47,62,32,60,47,114,100,102,58,68,101,115,99,114,105,112,116,105,111,110,62,32,60,47,114,100,102,58,82,68,70,62,32,60,47,120,58,120,109,112,109,101,116,97,62,32,60,63,120,112,97,99,107,101,116,32,101,110,100,61,34,114,34,63,62,115,115,54,90,0,0,175,140, -73,68,65,84,120,218,236,157,7,128,92,117,181,255,207,45,211,251,236,204,246,94,179,61,189,247,144,70,11,45,244,14,74,81,154,20,17,241,1,239,161,40,54,44,207,191,138,138,62,124,2,250,176,32,85,233,32,37,72,9,9,73,72,239,61,219,119,218,109,255,223,239, -55,155,80,4,201,220,123,103,167,157,79,24,118,179,73,238,220,185,237,124,207,249,157,194,105,154,6,8,130,32,8,130,20,22,60,30,2,4,65,16,4,65,1,128,32,8,130,32,8,10,0,4,65,16,4,65,80,0,32,8,130,32,8,130,2,0,65,16,4,65,16,20,0,8,130,32,8,130,160,0,64,16, -4,65,16,4,5,0,130,32,8,130,32,40,0,16,4,65,16,4,65,1,128,32,8,130,32,8,10,0,4,65,16,4,65,80,0,32,8,130,32,8,130,2,0,65,16,4,65,16,20,0,8,130,32,8,130,160,0,64,16,4,65,16,4,5,0,130,32,8,130,32,40,0,16,4,65,16,4,65,1,128,32,8,130,32,40,0,16,4,65,16,4,65, -1,128,32,8,130,32,8,10,0,4,65,16,4,65,80,0,32,8,130,32,8,130,2,0,65,16,4,65,16,20,0,8,130,32,8,130,160,0,64,16,4,65,16,4,5,0,130,32,8,130,32,40,0,16,4,65,16,4,65,1,128,32,8,130,32,8,10,0,4,65,16,4,65,204,70,204,228,155,39,18,9,60,3,8,242,41,104,154,70, -254,207,129,166,210,175,26,249,10,160,42,90,242,207,200,207,52,250,61,151,252,187,28,207,125,228,223,90,28,2,136,86,129,254,171,195,63,226,224,200,223,102,247,61,247,9,111,41,147,151,58,242,103,106,242,31,113,228,61,85,136,15,201,255,186,111,201,221, -98,239,205,9,220,200,126,16,175,66,224,217,31,28,222,39,186,141,79,124,55,4,65,64,20,69,224,249,204,248,226,25,19,0,146,36,193,130,5,11,96,231,206,157,120,5,32,5,13,51,234,228,63,85,86,129,218,85,250,123,142,163,134,52,105,53,109,30,11,8,22,94,180,186, -69,167,59,108,247,17,227,239,119,23,59,124,158,18,71,144,124,31,176,216,5,127,184,217,235,35,127,213,71,254,185,151,124,245,120,74,236,14,103,192,102,39,127,238,36,191,23,200,203,245,33,163,79,191,255,164,39,78,100,68,4,208,191,23,165,223,115,28,23,149, -98,74,172,103,219,16,253,253,16,121,13,240,60,55,208,187,125,184,47,210,19,31,32,6,191,55,62,40,31,234,217,58,216,79,12,126,127,124,64,234,27,58,24,31,34,251,31,143,13,74,160,74,42,168,106,82,188,80,113,64,182,199,62,23,21,12,60,143,194,0,65,238,186, -235,46,56,243,204,51,11,75,0,80,15,98,243,230,205,176,123,247,110,188,2,144,2,119,1,136,53,182,130,215,95,233,12,19,207,189,44,212,228,173,180,58,197,202,80,163,183,130,220,41,85,254,74,23,253,121,88,180,11,1,135,207,234,34,247,142,155,23,121,142,136, -2,96,138,129,69,4,134,142,184,249,148,65,101,16,6,134,52,115,246,143,108,84,168,251,168,94,8,212,2,4,57,203,72,132,194,2,85,9,43,48,177,16,149,135,163,253,210,0,177,243,251,251,119,69,14,202,49,101,119,223,206,200,174,72,111,124,199,240,193,248,142,129, -61,145,61,145,158,196,190,200,65,169,15,18,32,227,201,71,10,157,190,190,190,76,62,122,50,135,213,106,197,179,143,20,4,212,163,119,4,108,78,95,133,179,212,225,183,214,16,35,223,20,168,118,53,187,66,182,6,242,179,42,209,42,148,147,159,7,136,23,109,103, -134,29,52,226,57,143,68,8,104,100,64,101,170,153,121,211,28,36,163,239,144,248,136,141,254,8,212,229,55,53,195,71,249,183,250,0,172,34,93,110,0,135,197,99,117,184,253,92,136,236,106,125,113,93,128,236,3,199,62,59,93,14,160,75,22,170,162,41,137,136,220, -79,94,123,7,118,69,118,70,251,19,27,15,109,26,220,60,180,63,182,190,111,199,240,150,222,29,195,187,162,125,137,94,37,161,226,69,131,20,4,130,32,20,166,0,64,144,124,196,234,18,121,111,153,163,140,24,246,70,226,197,183,133,155,188,157,158,18,71,139,167, -212,81,103,243,136,101,196,192,219,233,58,57,91,199,39,47,69,214,152,113,87,228,164,209,147,227,202,191,221,190,150,133,159,121,36,16,193,34,123,138,170,141,8,151,79,121,222,89,248,160,51,96,13,186,195,246,54,142,227,22,53,31,83,206,142,131,42,107,74, -108,80,58,56,124,48,182,131,8,130,181,68,24,172,233,221,54,188,234,224,166,129,13,228,247,59,134,14,196,162,120,117,33,8,10,0,4,201,10,44,78,17,136,177,175,40,170,115,183,21,143,241,141,35,6,127,188,191,202,213,78,60,251,26,171,67,244,208,117,111,234, -201,51,239,151,122,242,228,171,36,43,255,222,165,206,115,180,145,156,0,85,86,62,30,74,16,44,14,161,36,88,235,46,9,53,120,38,214,207,44,97,130,66,142,41,82,124,88,222,49,176,59,178,238,208,150,161,119,14,174,31,120,107,207,234,222,213,253,187,34,91,163, -125,137,56,94,133,8,130,2,0,65,210,14,241,226,93,129,42,87,115,89,87,96,2,49,246,83,194,77,158,241,174,176,189,145,24,123,47,13,185,39,13,125,242,149,136,224,18,119,106,202,32,121,252,20,250,98,63,72,254,159,227,192,98,115,137,245,37,173,254,250,178, -206,192,177,116,73,65,138,169,82,164,55,190,109,96,119,116,21,17,3,43,14,172,31,120,125,255,218,190,247,250,118,70,246,107,170,134,199,18,65,80,0,32,136,97,131,239,41,110,241,117,86,116,7,166,149,118,4,102,4,106,220,227,236,94,177,150,174,211,83,207, -158,101,185,163,177,79,175,46,24,17,6,170,66,4,193,136,191,79,69,129,51,96,109,116,19,241,85,57,33,120,50,21,15,241,65,233,16,17,0,171,247,173,233,123,109,247,202,158,151,247,174,233,127,171,127,231,240,238,195,165,147,8,130,160,0,64,144,79,197,225,179, -90,66,77,158,182,154,41,225,217,229,221,193,185,129,26,215,68,135,223,86,205,11,192,214,234,21,98,240,229,4,121,197,49,73,45,227,162,128,69,90,62,88,70,224,69,190,40,220,232,153,83,210,234,155,211,117,106,205,151,227,67,82,127,255,142,200,187,251,214, -246,189,176,107,101,239,243,68,24,188,213,179,117,168,23,143,30,130,160,0,64,16,98,52,56,8,84,187,43,171,38,21,205,168,28,87,180,176,180,195,63,195,85,100,107,33,30,62,71,13,62,245,240,165,40,122,247,57,33,10,84,141,136,51,162,12,70,42,8,120,129,247, -133,26,61,179,138,91,125,179,58,79,169,185,53,62,40,237,57,184,113,240,181,157,111,31,122,122,199,138,131,47,238,93,219,191,70,138,200,168,228,16,20,0,8,82,40,208,44,125,226,221,119,86,79,14,45,168,28,31,92,66,4,192,100,155,91,244,209,144,190,146,80, -208,195,207,87,65,32,242,101,101,93,129,147,43,198,7,79,158,116,126,163,210,191,43,178,234,192,250,254,167,55,191,180,239,137,237,111,28,92,49,124,48,62,132,71,13,65,1,128,32,121,6,241,234,173,229,93,129,201,213,147,195,75,171,38,135,150,248,43,156,99, -137,65,224,169,193,167,158,254,199,91,221,34,121,42,8,98,35,75,6,28,8,222,50,199,216,64,181,107,108,243,194,242,27,134,246,199,182,31,218,52,248,236,150,87,246,63,178,245,213,3,47,244,110,27,234,193,35,134,160,0,64,144,92,53,250,33,155,181,106,98,104, -74,195,156,210,19,43,186,3,199,186,66,246,54,218,181,134,54,153,145,98,133,93,138,135,106,0,88,62,7,125,81,236,94,75,117,245,148,208,133,181,211,139,47,140,13,36,246,237,93,211,247,252,150,151,247,255,105,235,43,251,159,233,221,62,124,16,15,24,130,2, -0,65,178,28,171,75,132,138,238,224,148,230,99,202,78,174,153,86,124,2,17,1,109,244,97,79,155,235,96,166,62,242,105,208,74,1,53,154,20,133,188,200,151,84,79,10,157,81,59,181,248,140,88,63,17,3,107,251,254,78,196,192,31,54,60,179,231,133,161,3,177,126, -60,90,8,10,0,4,201,18,232,112,153,146,86,127,203,152,37,21,167,212,78,15,159,234,43,119,78,160,195,102,104,184,55,49,92,200,70,95,251,88,215,192,145,185,1,159,82,21,199,29,233,39,252,65,99,97,238,99,191,47,136,163,166,106,32,29,22,3,22,34,6,38,134,206, -37,98,224,220,73,231,55,108,223,181,178,247,209,13,207,238,249,253,214,127,236,127,41,129,9,132,8,10,0,4,201,12,129,106,87,81,211,130,178,165,228,117,78,176,214,51,87,180,243,118,37,126,56,188,159,127,166,156,118,197,35,126,234,145,175,234,200,215,164, -81,255,192,170,243,28,207,70,240,114,35,95,217,48,31,78,36,63,23,152,6,160,163,71,121,78,132,15,154,10,115,108,59,10,237,221,203,141,180,243,213,228,15,189,39,253,170,30,249,154,28,240,155,220,238,225,247,161,191,232,164,63,238,200,215,252,16,14,76,12, -140,44,23,217,60,150,234,230,5,101,87,146,235,237,202,254,157,195,43,183,188,178,255,247,239,63,185,235,255,246,174,233,95,143,205,135,16,20,0,8,146,102,104,136,191,114,124,209,180,214,165,21,231,84,79,14,159,236,240,91,203,21,73,97,235,250,137,161,220, -117,200,14,27,87,149,189,20,106,222,143,24,117,129,23,153,1,183,10,54,176,11,14,242,114,130,83,116,147,151,7,156,150,145,175,228,247,118,209,69,94,78,246,231,54,242,119,173,188,29,44,188,13,68,242,239,69,222,194,182,65,223,135,126,165,191,255,240,84, -1,250,94,146,26,63,34,6,36,37,193,246,35,174,198,200,207,19,144,80,98,16,147,163,16,87,34,16,37,175,136,60,4,195,210,0,68,229,225,35,223,199,200,207,227,74,148,189,36,34,38,152,136,208,180,35,194,128,10,147,195,47,14,248,156,59,71,116,153,224,240,50, -146,167,196,209,61,238,140,186,238,174,147,107,110,221,255,126,255,51,235,158,220,245,155,141,207,237,125,98,232,64,108,24,239,82,4,5,0,130,152,136,159,120,251,205,243,203,78,110,59,190,234,34,127,149,115,58,53,42,82,156,24,168,33,41,183,12,61,53,240, -212,219,166,70,158,188,168,129,164,6,145,26,106,106,196,221,86,31,248,172,69,16,176,133,193,79,94,65,242,242,218,130,228,103,65,112,89,188,224,32,70,222,33,184,70,12,120,246,64,141,125,156,136,132,40,17,3,84,16,12,36,122,161,63,209,3,125,241,131,208, -27,219,15,189,228,43,253,126,80,234,35,127,62,200,4,133,60,50,45,136,70,38,4,242,226,217,139,203,137,200,193,225,4,66,178,187,142,146,86,255,241,229,93,129,227,39,95,212,180,113,203,203,251,126,191,246,137,93,191,221,245,78,207,90,140,10,32,40,0,16,68, -39,116,132,108,221,244,240,216,214,99,43,47,172,158,28,90,238,8,216,202,233,186,126,114,125,54,55,60,122,106,232,15,123,194,2,47,48,239,220,111,13,16,195,94,12,197,142,10,40,118,86,64,152,124,45,178,151,48,35,239,182,248,178,206,184,31,13,52,170,144, -140,74,184,161,232,83,143,137,10,195,210,32,19,1,135,162,251,224,96,108,15,236,143,238,130,253,145,157,228,251,189,76,48,68,165,33,34,12,164,145,72,133,192,162,31,84,24,112,89,42,10,180,145,4,83,57,14,96,115,139,141,29,39,85,223,66,68,234,151,246,172, -234,125,226,189,191,238,248,229,166,23,246,254,45,54,32,73,120,55,35,40,0,16,228,40,176,185,45,98,219,241,149,75,90,22,149,127,190,180,221,191,132,120,251,22,230,237,15,102,239,115,84,101,198,254,131,176,183,133,183,18,99,238,133,32,49,236,165,206,106, -40,119,213,66,133,187,142,25,123,191,173,136,9,129,130,19,116,192,51,129,67,95,101,206,154,143,252,25,53,250,3,82,47,28,136,238,134,189,195,219,97,247,240,86,216,51,188,13,14,196,118,195,64,188,7,98,106,116,68,68,37,151,67,4,58,102,49,203,68,1,91,34, -24,102,121,20,118,218,112,168,114,124,240,228,254,221,205,239,110,120,102,207,47,222,125,120,219,3,125,59,177,156,16,65,1,128,32,159,136,183,220,233,239,62,181,230,204,134,185,165,159,11,214,184,199,43,172,13,111,118,122,251,204,179,39,70,139,126,165, -30,170,203,226,33,94,124,13,51,242,53,238,102,168,242,52,66,137,163,146,133,239,185,2,203,162,215,245,32,226,45,44,42,66,95,45,254,177,71,126,78,151,19,168,40,216,53,180,25,182,15,109,128,29,67,155,96,127,100,23,12,38,122,89,110,2,93,62,17,88,126,67, -22,69,9,104,84,32,166,0,93,224,112,6,109,93,19,207,171,255,97,251,9,85,55,111,123,253,192,253,111,63,184,229,87,123,86,245,174,199,51,142,160,0,64,16,66,105,135,191,178,109,105,229,197,77,11,202,46,118,133,237,53,244,225,153,109,107,251,116,189,94,30, -49,248,52,169,206,107,13,66,153,171,6,106,61,45,80,231,109,133,74,119,3,11,227,179,76,123,196,52,232,146,66,141,167,153,189,166,195,18,246,51,154,95,176,39,178,13,182,13,188,15,91,6,214,18,81,176,17,122,98,7,88,18,98,182,9,2,85,86,201,181,172,130,96, -227,203,91,22,149,127,185,97,78,201,23,247,174,238,123,248,173,7,54,255,100,211,11,251,94,199,51,140,160,0,64,10,211,240,183,251,155,198,159,93,127,69,195,236,146,243,45,78,177,72,138,200,89,19,230,167,235,213,52,73,141,26,125,106,76,168,193,167,222, -125,189,183,13,26,253,29,196,224,55,178,53,123,100,244,241,90,3,236,117,56,82,64,171,14,246,68,182,195,150,254,181,176,190,111,37,108,31,92,15,61,241,253,144,80,226,236,220,209,232,66,166,133,153,54,178,60,192,113,224,170,24,23,60,159,188,206,221,249, -86,207,99,171,255,188,253,135,155,95,218,247,52,54,169,66,80,0,32,5,65,205,212,112,71,251,241,85,95,32,222,208,121,162,93,112,209,48,127,54,24,126,133,121,249,9,182,158,79,203,235,106,60,245,196,216,119,194,24,255,56,168,246,52,129,223,22,194,147,151, -133,216,4,7,139,196,208,215,188,202,147,32,38,71,96,231,240,38,34,6,222,133,245,189,239,176,101,131,129,68,15,75,44,20,57,11,203,35,200,84,116,128,38,13,178,101,45,14,120,34,2,78,168,158,20,58,225,208,230,193,103,222,249,195,214,123,214,60,182,243,81, -9,133,0,50,138,112,154,150,153,82,149,68,34,1,45,45,45,176,117,235,86,60,11,5,66,195,220,210,174,241,103,213,93,91,49,54,120,54,199,113,54,250,32,204,212,245,119,24,234,225,203,154,196,18,212,168,129,175,243,142,129,214,224,4,104,246,119,67,185,179,134, -53,185,65,114,27,90,126,184,169,255,61,88,211,243,79,216,208,255,46,171,60,160,125,14,104,100,128,190,50,189,84,32,88,121,16,201,235,208,166,161,23,222,249,195,150,239,172,121,124,23,10,129,2,226,231,63,255,57,124,238,115,159,195,8,0,146,159,148,119, -7,219,102,92,209,114,35,241,120,206,38,191,181,102,58,177,143,26,125,154,64,70,215,242,195,142,114,102,236,59,138,166,64,163,175,147,133,150,145,252,130,10,187,9,197,115,216,139,246,31,216,54,180,1,222,59,180,130,9,130,93,195,91,88,51,35,26,21,160,149, -27,153,16,3,180,137,21,125,249,170,156,115,22,220,220,57,167,251,244,186,231,87,254,97,235,119,215,62,182,243,81,92,26,64,48,2,128,228,36,165,29,254,134,241,103,213,95,223,48,187,228,2,226,229,56,89,75,213,12,57,252,180,60,143,173,9,147,7,61,205,206, -111,13,142,135,238,208,116,104,240,117,20,100,73,30,146,204,243,216,49,184,9,222,235,89,1,239,30,122,141,124,191,145,137,129,100,231,68,107,198,34,3,201,136,128,0,135,182,12,254,253,173,223,109,254,214,170,63,109,127,6,207,22,70,0,48,2,128,228,4,197, -99,124,165,147,206,111,184,174,126,86,201,101,162,93,240,81,143,63,19,94,63,205,220,79,168,113,22,222,15,59,202,160,189,104,50,51,250,77,196,211,167,235,198,72,129,123,63,228,186,160,185,29,244,181,180,230,28,216,57,180,9,222,57,248,50,188,123,240,53, -246,125,76,137,177,168,192,104,55,102,58,28,17,240,87,56,23,30,243,149,174,133,99,22,87,252,133,8,129,187,54,189,136,85,3,8,10,0,36,75,241,150,59,61,99,151,215,94,209,177,172,234,58,187,215,82,154,136,140,254,52,62,154,232,37,17,79,159,38,244,209,208, -239,184,192,108,152,88,60,7,90,2,227,88,73,25,130,124,26,180,148,147,190,142,171,61,15,54,247,175,133,183,15,190,68,196,192,171,176,55,178,157,37,134,90,121,219,168,86,19,200,68,4,16,5,11,21,227,130,203,42,199,23,29,183,253,141,131,247,255,227,255,173, -251,230,222,213,125,216,71,0,49,71,4,227,18,0,98,20,155,91,228,186,79,171,61,103,252,57,245,95,117,6,108,99,18,81,153,149,61,141,38,178,38,51,195,111,23,29,172,84,111,66,241,92,230,237,211,158,250,8,162,23,90,98,248,126,239,219,176,98,255,179,176,166, -231,77,232,143,31,202,204,18,1,121,43,139,93,160,145,129,193,141,47,236,253,241,171,63,93,255,253,190,157,195,7,240,12,229,62,184,4,128,228,166,122,228,57,104,154,95,58,119,218,101,45,183,23,213,185,231,176,114,190,81,108,224,115,216,219,167,195,117, -104,95,253,113,225,153,48,169,100,1,43,7,67,16,83,196,173,224,128,46,34,36,233,235,80,108,31,91,34,88,177,239,89,216,54,248,62,200,138,196,38,52,142,74,84,96,164,124,144,220,115,158,49,139,43,190,82,51,37,124,206,170,63,109,187,235,141,223,108,250,69, -98,88,198,76,65,4,35,0,200,232,81,214,17,168,159,126,69,203,127,84,79,14,93,192,38,163,37,70,111,20,47,13,239,211,108,110,155,96,103,117,250,211,75,23,179,7,52,134,248,145,209,17,158,42,235,49,240,234,158,167,88,242,96,50,42,96,97,249,2,163,5,47,112, -32,58,4,232,219,54,252,218,235,247,109,188,109,237,99,59,254,166,225,240,65,140,0,96,4,0,73,39,142,128,213,49,229,162,166,171,59,78,170,190,73,180,241,193,209,92,227,167,165,123,180,132,143,134,245,103,150,45,133,105,101,139,89,184,31,65,70,213,107,2, -158,117,33,164,47,26,21,120,99,223,179,240,218,190,191,179,121,5,244,79,105,84,32,221,203,3,108,240,208,144,12,158,50,199,212,197,183,117,63,53,102,113,249,111,95,253,217,250,219,247,172,238,221,132,103,8,65,1,128,152,251,208,35,207,179,182,227,171,142, -157,114,73,211,157,254,42,215,56,106,248,71,35,179,255,112,152,159,122,93,229,174,122,152,78,140,254,228,146,5,184,182,143,100,5,116,254,195,146,154,179,96,126,213,41,176,234,224,171,240,210,158,199,224,253,222,149,68,172,198,193,202,219,217,108,130, -116,114,184,98,160,102,74,248,220,242,238,224,177,171,254,180,237,155,43,126,181,241,135,209,254,68,28,207,14,130,2,0,49,76,121,87,160,102,234,231,155,255,139,60,100,206,163,15,155,209,104,219,75,13,63,13,243,211,245,213,38,127,23,204,174,56,1,198,133, -102,18,239,202,158,215,199,90,147,162,160,197,7,65,27,62,8,234,240,33,80,135,246,147,239,15,145,159,13,177,68,48,206,230,1,222,83,10,66,184,9,132,162,6,0,193,146,241,125,86,135,183,129,58,176,46,249,53,222,75,63,4,112,130,131,236,107,17,112,116,64,146, -189,152,124,31,6,206,234,7,206,226,205,203,243,70,43,4,104,226,41,125,109,236,95,5,47,238,250,43,188,115,240,21,24,150,6,216,53,43,164,57,79,128,54,12,226,120,46,56,225,156,134,187,27,102,151,158,241,218,47,215,223,180,230,177,157,207,2,46,11,32,40,0, -16,61,216,189,22,24,127,78,253,149,19,206,174,191,77,176,9,197,163,17,238,215,52,34,48,212,24,123,160,142,13,207,132,121,21,203,160,45,56,41,255,12,61,49,242,42,49,242,218,192,94,80,250,119,18,3,186,135,188,246,130,22,33,198,62,54,64,108,104,12,52,37, -145,108,30,127,56,4,147,60,64,201,223,138,86,224,125,149,96,169,39,162,168,101,49,112,206,81,238,96,72,206,147,188,239,89,144,118,61,6,10,49,254,154,52,4,201,46,79,28,251,239,200,126,211,96,56,79,30,51,196,8,82,227,207,89,131,192,59,136,40,112,84,0,231, -170,6,222,89,65,4,66,25,17,8,116,255,243,163,237,50,237,40,73,95,123,134,183,194,139,187,31,101,73,131,180,29,49,93,26,16,56,49,141,167,68,99,73,184,238,98,251,132,37,183,143,125,166,101,81,197,207,94,188,103,205,109,135,54,15,238,195,167,25,242,73,96, -18,32,242,137,212,207,44,233,158,117,117,235,119,138,26,60,199,80,195,79,31,46,105,245,34,137,65,97,137,125,162,131,101,243,207,175,56,25,234,125,237,249,97,236,35,61,160,246,239,2,165,119,27,40,61,196,75,238,219,65,60,251,3,196,208,247,3,80,67,79,62, -59,179,155,212,75,228,5,90,94,49,98,240,185,127,27,35,1,69,102,34,129,247,148,128,109,220,153,96,29,179,100,84,62,143,210,255,30,36,214,255,63,80,250,86,38,141,54,77,126,251,183,161,110,109,68,16,168,116,44,30,19,15,236,51,83,113,32,88,147,194,192,22, -38,98,160,18,120,119,29,8,238,6,224,220,181,192,211,101,30,222,146,243,231,159,230,9,188,188,231,49,120,101,207,147,112,48,186,55,237,66,224,72,84,194,41,66,180,47,177,253,205,255,221,124,243,91,15,108,126,96,52,19,117,145,163,39,147,73,128,40,0,144, -143,123,253,214,233,151,183,220,216,121,114,205,45,228,183,78,57,158,222,117,126,106,8,98,74,148,77,223,155,24,158,11,243,42,79,102,157,217,114,214,216,75,81,98,236,119,131,122,104,19,40,7,55,18,131,191,37,233,217,83,175,94,145,62,102,232,133,15,60,123, -67,22,89,34,54,85,2,107,203,66,112,76,191,18,64,180,165,237,243,73,59,31,129,248,250,255,38,239,25,37,94,189,25,221,20,53,38,8,168,48,208,52,153,9,5,118,124,200,245,192,219,138,153,32,224,189,77,32,120,90,200,247,181,44,130,144,171,208,137,132,47,239, -126,156,69,5,14,68,119,131,133,8,1,49,205,66,128,86,11,88,93,34,236,124,187,231,15,47,222,179,230,166,61,171,122,241,129,139,2,0,5,0,242,137,94,255,100,226,245,255,128,120,253,83,105,134,113,58,175,13,186,198,31,87,34,96,23,92,48,169,120,30,44,168,58, -149,117,97,203,57,131,31,31,2,149,122,246,251,215,129,188,255,125,80,123,182,38,67,251,114,44,121,131,209,7,188,48,226,213,167,53,51,92,99,251,98,169,159,5,206,121,55,166,69,4,72,219,30,76,26,127,230,241,167,217,131,61,34,10,164,164,40,160,83,251,172, -1,224,93,213,32,120,199,0,239,239,32,162,160,25,56,123,113,206,93,51,131,137,62,120,137,136,128,164,16,216,53,146,35,144,222,227,105,113,8,32,199,213,253,111,254,118,211,87,87,220,183,241,23,180,116,23,65,1,128,2,0,1,187,207,98,153,126,89,203,87,70,188, -126,91,58,189,254,164,225,143,178,53,254,241,197,179,97,97,213,114,168,201,165,198,61,74,130,133,241,149,189,239,129,188,119,53,40,135,182,36,215,237,229,4,51,242,156,32,154,231,217,235,20,36,214,214,165,224,152,125,141,169,219,149,247,62,3,177,85,119, -16,227,111,251,140,112,127,250,174,28,38,10,84,137,232,1,133,69,9,104,82,33,239,170,1,193,215,14,66,112,44,240,222,22,224,44,254,220,17,2,82,31,60,191,243,47,68,8,60,2,61,177,253,172,233,80,58,155,10,113,52,26,224,20,97,247,59,61,15,191,112,207,154,27, -48,26,128,2,0,5,64,129,83,55,163,120,236,236,107,218,126,72,188,254,89,233,246,250,233,26,63,71,140,71,87,104,42,44,169,57,27,26,188,185,177,198,175,13,29,0,121,223,26,144,119,175,4,101,223,58,80,7,247,178,36,189,35,6,159,134,243,51,60,83,254,35,18,43, -17,1,231,220,47,129,165,121,161,41,91,84,163,187,33,186,226,242,100,162,95,54,173,201,211,124,2,85,102,75,7,52,209,144,179,133,88,84,64,8,78,0,33,48,150,45,25,192,40,246,238,215,75,111,252,0,60,179,227,97,120,121,207,227,44,58,64,219,89,115,105,76,136, -28,137,6,236,253,231,253,155,110,124,237,222,245,191,197,167,96,225,10,0,172,2,40,80,68,27,15,51,174,28,115,245,184,51,234,190,78,108,190,59,157,165,125,180,129,15,29,199,75,27,167,44,37,134,191,163,104,74,182,155,124,22,202,151,119,173,36,175,183,217, -90,190,26,237,99,63,167,161,104,160,198,198,154,173,35,132,147,137,117,177,55,127,7,98,245,100,224,236,62,227,194,109,211,175,64,139,31,34,23,77,150,117,90,164,198,93,16,200,39,78,46,119,104,137,94,144,15,188,12,210,254,23,129,19,93,44,58,32,6,199,129, -16,154,2,130,183,213,164,156,5,243,161,61,45,78,107,188,28,102,149,31,7,79,110,127,16,86,236,125,26,98,106,20,236,172,228,213,124,97,73,251,119,240,2,87,58,253,242,150,251,203,58,252,139,94,184,103,205,245,61,91,134,112,174,64,33,218,1,60,4,133,71,73, -171,175,122,254,151,59,127,76,110,254,19,232,196,190,116,101,248,83,163,159,80,226,80,233,174,103,134,127,74,233,49,105,245,108,140,217,124,149,24,250,13,32,239,124,27,228,29,255,4,133,8,0,234,73,3,207,143,100,170,231,208,248,96,193,194,202,10,19,239, -255,13,108,221,203,141,121,255,131,27,65,38,6,21,68,103,246,127,110,150,111,33,142,152,76,34,226,6,55,64,188,127,13,112,219,126,207,202,13,133,192,56,16,195,211,129,247,119,146,191,154,125,109,163,75,156,85,112,193,152,27,153,16,120,108,235,253,176,234, -224,107,108,41,137,46,151,153,13,237,36,72,69,127,237,180,226,243,74,59,2,211,94,250,193,154,47,174,126,100,199,83,248,116,68,1,128,228,49,227,207,170,63,101,202,165,77,63,178,185,197,242,248,80,122,234,250,233,58,127,76,142,128,223,86,4,39,212,93,0, -243,43,79,33,222,76,118,26,16,229,208,38,144,183,173,32,70,255,13,150,177,79,67,251,28,109,174,195,146,206,156,57,123,158,105,159,0,105,211,11,96,235,56,201,80,179,32,105,207,83,160,201,195,89,105,48,63,43,18,66,147,21,57,214,159,159,136,129,200,110, -80,134,182,178,42,6,206,81,14,98,209,4,16,139,103,131,64,196,64,182,69,6,104,123,235,171,186,238,130,183,15,188,4,143,18,33,176,117,96,93,218,74,7,105,3,33,209,198,55,46,188,181,235,137,170,201,161,187,158,251,246,123,183,199,250,19,18,32,40,0,144,252, -193,225,183,218,231,223,216,241,141,150,197,21,215,73,177,244,181,241,165,235,252,2,47,194,236,242,227,225,184,186,243,32,100,47,203,186,99,65,203,242,228,109,175,129,180,237,85,22,222,167,158,254,7,70,223,149,31,39,156,70,1,250,118,50,81,35,132,155, -117,30,40,137,252,251,55,71,140,104,46,195,37,207,237,72,254,130,22,223,15,137,29,127,6,105,215,163,192,19,175,91,12,77,5,161,120,14,17,3,237,144,61,185,28,0,227,194,179,160,189,104,50,188,176,235,47,240,212,246,135,160,55,118,0,236,162,211,244,57,3, -170,76,187,110,42,92,235,146,202,91,194,77,222,25,79,127,227,221,203,118,175,236,125,31,159,154,40,0,144,60,160,118,122,113,251,220,47,181,221,27,172,245,76,75,215,184,222,195,225,254,102,127,55,156,84,127,49,180,4,198,101,213,49,208,18,195,32,239,124, -139,121,197,52,131,95,141,246,19,131,64,215,144,173,249,99,244,63,102,244,104,101,130,114,96,131,110,1,160,198,246,146,227,180,55,253,37,127,163,31,30,33,255,137,35,145,129,93,16,223,250,0,112,59,254,200,18,8,197,146,57,44,50,64,163,4,217,0,13,255,47, -172,58,29,198,135,231,192,163,91,255,7,94,221,251,20,168,170,98,126,75,108,13,88,23,193,64,181,123,206,169,255,61,245,229,21,247,109,188,122,197,125,27,30,208,176,90,16,5,0,146,187,76,185,164,233,28,242,250,33,199,113,193,116,24,255,195,225,254,160,189, -24,150,54,158,13,115,42,78,28,149,46,103,71,45,76,136,135,79,141,190,188,245,53,80,6,118,143,60,255,109,57,29,222,79,197,241,165,29,8,117,159,219,216,62,114,0,35,201,210,191,124,61,64,71,34,3,26,185,62,214,130,220,183,10,248,45,191,101,149,4,98,217,98, -16,139,38,101,69,229,3,29,58,68,243,3,166,148,44,128,63,111,254,37,108,32,251,153,142,101,1,90,2,204,9,92,104,198,149,99,126,87,60,198,55,245,239,119,190,123,83,12,7,11,161,0,64,114,11,135,223,106,157,119,99,199,183,90,22,149,95,43,199,20,80,20,243,165, -60,157,120,70,153,89,126,44,156,88,119,17,123,72,101,133,183,47,69,147,33,254,13,207,129,76,188,125,250,123,186,38,158,83,137,124,102,69,1,232,16,33,221,81,147,129,100,169,93,129,28,43,42,116,56,242,210,148,56,155,115,32,239,123,30,120,119,61,136,165, -11,192,82,58,63,43,162,2,99,2,227,225,134,241,157,240,236,142,63,194,147,219,126,7,3,82,31,216,89,14,131,121,203,2,218,72,130,96,227,220,210,171,3,213,174,113,79,127,99,213,37,187,87,246,108,192,167,42,10,0,36,7,168,24,27,172,59,230,150,174,95,21,213, -187,231,198,233,0,31,147,147,252,105,223,126,218,197,175,202,211,4,167,212,127,14,186,66,211,178,226,115,171,196,195,151,54,60,11,210,230,151,64,233,219,201,50,168,57,161,64,188,253,127,19,163,49,160,164,14,143,247,41,48,221,196,3,140,36,173,170,195, -91,33,190,225,167,32,109,123,8,132,240,116,176,16,177,43,4,186,51,251,208,230,44,176,168,250,12,232,14,205,128,63,110,190,23,222,218,255,2,139,4,136,38,71,42,232,12,144,64,141,123,214,41,63,156,242,210,63,254,223,186,207,191,253,224,150,71,240,233,138, -2,0,201,98,58,150,85,47,154,115,93,219,175,68,187,80,145,142,44,127,154,228,39,242,86,88,90,123,46,28,87,115,46,56,196,204,175,159,43,251,214,66,98,221,147,32,109,127,29,52,186,182,95,144,222,126,154,188,226,66,103,164,146,64,83,162,32,239,122,28,228, -189,127,7,193,223,5,150,138,227,64,12,207,98,83,14,51,69,137,179,18,174,232,184,3,94,223,251,52,252,105,243,47,216,124,1,179,147,4,105,244,144,23,185,146,185,215,183,255,185,168,222,243,181,231,190,189,250,235,216,70,24,5,0,146,109,207,41,145,135,89, -95,28,115,237,248,115,234,239,150,227,138,133,222,184,230,123,253,81,168,247,181,193,233,141,87,66,19,121,8,102,214,177,85,65,222,190,2,18,107,159,0,121,247,187,44,108,203,137,246,60,77,232,67,50,175,133,132,145,94,8,26,40,61,111,131,220,243,38,155,90, -200,132,64,233,66,214,150,56,83,208,254,26,99,130,227,224,143,155,238,101,73,130,60,249,37,154,88,185,65,171,4,36,69,230,186,78,173,185,51,80,227,234,122,234,246,149,151,13,236,137,244,225,69,129,2,0,201,2,188,101,14,251,130,155,59,127,84,63,171,228, -82,186,118,103,118,55,223,195,94,63,173,233,63,150,120,254,214,76,38,133,201,9,144,182,188,76,12,255,227,108,0,15,11,81,211,48,191,197,137,23,2,50,58,81,17,226,245,83,31,91,29,222,6,241,117,63,128,196,182,63,128,165,124,9,17,3,199,103,108,56,145,207, -90,4,23,181,222,12,93,69,83,225,255,54,253,12,246,71,118,153,26,13,160,207,20,250,108,169,28,95,116,250,242,159,78,107,122,250,27,239,158,187,237,245,3,107,240,122,64,1,128,100,144,146,86,95,213,226,219,198,222,31,106,242,206,137,13,152,155,229,175,129, -10,81,57,2,245,222,86,56,189,233,139,208,156,65,175,159,38,242,73,27,95,32,134,255,49,80,14,109,102,51,5,64,180,99,144,26,201,28,212,203,166,203,3,137,67,16,223,244,75,144,118,253,21,68,226,141,91,171,78,206,88,194,224,132,226,185,208,232,239,132,255, -219,248,51,120,109,239,223,76,207,13,160,121,1,238,98,251,184,19,190,61,241,185,127,252,100,221,69,111,63,184,229,113,188,16,80,0,32,25,128,120,252,83,150,220,49,246,119,86,167,88,111,118,47,127,218,191,159,178,184,250,76,88,86,127,81,230,58,249,73,49, -72,108,120,6,18,107,30,99,237,121,233,240,29,92,223,71,178,43,40,32,178,78,137,154,52,8,137,173,191,3,121,207,83,172,132,48,83,66,128,70,3,46,105,187,5,218,130,19,225,225,77,63,131,190,248,65,83,239,95,90,42,200,139,92,241,156,235,218,30,241,150,57,174, -123,233,135,107,127,68,91,11,35,40,0,144,209,82,250,231,212,47,159,117,85,235,47,21,89,243,72,38,175,247,71,229,97,150,96,116,102,243,85,208,85,148,161,12,127,69,34,30,255,243,16,95,253,103,80,15,109,97,157,237,10,59,155,31,201,126,33,32,36,133,128,28, -25,17,2,79,130,165,108,41,88,170,79,203,200,210,192,180,210,69,208,232,235,128,7,214,255,16,86,30,124,5,108,130,221,180,113,195,52,47,64,83,20,97,210,249,141,63,116,6,109,245,207,222,189,250,122,226,132,96,118,32,10,0,36,189,207,24,14,230,94,215,126, -67,247,242,154,111,43,9,21,204,84,222,138,166,176,218,254,201,37,11,136,241,255,34,243,36,70,29,77,3,105,243,139,16,95,245,39,80,14,172,103,99,94,1,13,63,146,147,66,32,202,132,128,180,247,239,96,169,60,145,188,78,30,245,100,193,176,163,28,174,234,190, -11,158,218,246,32,252,117,235,111,32,65,238,111,179,114,120,104,94,64,180,63,1,173,75,43,175,13,84,187,106,30,185,225,159,23,13,29,136,245,227,5,128,2,0,73,3,118,175,133,159,127,83,231,247,91,143,171,184,58,62,64,231,160,155,103,252,227,74,140,205,33, -95,222,120,57,27,222,147,9,104,171,222,248,59,191,39,158,211,106,182,198,143,137,125,72,174,11,1,16,93,160,73,3,144,216,248,11,144,118,63,9,214,154,211,193,82,126,220,168,150,15,210,68,192,37,53,103,65,131,191,29,254,247,253,123,96,251,224,6,112,178, -242,93,115,50,104,104,135,209,226,86,255,201,167,253,116,90,249,223,239,92,121,250,174,183,123,182,227,201,207,13,120,60,4,185,129,59,108,119,157,242,227,169,15,142,89,90,113,117,172,95,50,209,248,107,16,149,135,160,202,211,0,95,26,251,221,140,24,127, -58,145,47,242,204,93,16,121,234,14,144,247,18,227,111,33,15,71,209,138,39,29,201,19,33,64,252,44,26,17,136,29,128,216,218,239,67,228,141,47,176,78,131,163,77,147,175,11,110,28,119,15,235,220,25,83,34,44,226,103,22,82,68,6,127,165,115,202,9,119,79,124, -174,122,82,104,44,158,116,20,0,136,73,132,155,188,37,203,190,63,249,177,146,86,223,114,51,147,253,84,242,0,136,42,81,242,64,56,14,110,32,15,134,58,111,235,168,126,46,45,210,3,177,87,127,14,195,127,253,50,72,155,95,78,206,114,23,237,120,194,145,60,125, -218,90,200,245,237,2,117,104,19,196,222,189,29,162,111,221,0,74,223,234,81,221,5,151,197,11,23,183,126,5,206,105,254,18,155,218,153,80,205,107,243,79,39,140,210,132,228,147,238,153,252,247,238,229,181,199,224,9,207,126,112,9,32,203,169,28,23,108,56,225, -219,19,255,100,243,88,58,105,9,142,105,55,43,185,241,45,188,141,60,8,174,37,94,255,201,163,251,161,84,5,18,235,158,128,248,202,135,65,29,220,203,178,250,49,179,31,41,28,33,144,92,131,87,14,173,128,104,239,59,96,169,88,10,214,186,243,129,179,133,71,109, -23,230,85,158,4,213,158,70,248,205,186,239,192,174,161,205,166,117,244,164,93,2,121,145,11,205,187,161,227,17,14,224,194,119,254,176,245,247,120,194,49,2,128,232,160,98,92,81,55,49,254,127,183,186,44,157,84,93,155,5,205,242,15,59,42,224,154,238,111,141, -186,241,151,119,175,132,225,71,111,134,232,203,63,1,45,218,155,236,220,199,225,101,136,20,32,35,67,124,18,219,255,4,145,215,47,7,105,251,195,163,58,124,169,193,215,1,55,142,191,7,38,22,207,101,203,128,180,239,135,41,250,94,214,64,73,40,142,57,215,183, -63,48,235,170,214,203,56,108,214,129,17,0,36,53,58,150,85,205,156,117,117,219,195,22,135,80,76,235,110,205,64,99,235,253,195,48,54,60,19,206,111,185,30,252,182,208,168,125,30,109,248,16,196,222,126,0,164,245,79,211,39,4,150,244,33,8,133,38,187,178,68, -193,62,136,173,251,62,155,64,104,109,188,116,212,6,14,121,44,126,184,162,243,14,248,235,150,122,120,116,235,253,192,17,107,77,135,13,25,22,1,10,121,218,104,42,63,229,226,166,159,218,125,22,223,223,191,254,238,221,128,173,2,80,0,32,159,77,247,242,218, -197,243,111,236,120,72,145,84,31,45,245,51,3,154,240,35,171,9,88,90,115,54,156,210,240,121,16,76,170,7,62,26,18,239,255,13,226,111,61,48,18,238,39,134,95,196,203,14,65,62,42,4,104,254,139,8,74,223,187,16,125,235,122,176,84,46,3,107,253,249,228,126,241, -141,198,155,195,9,117,23,66,185,187,22,126,75,68,200,176,52,0,86,19,170,20,52,85,99,101,130,93,167,212,124,139,24,127,239,211,223,120,247,86,13,69,0,10,0,228,223,26,255,147,231,221,208,254,91,41,174,56,53,83,106,252,57,144,212,88,114,189,127,204,141, -44,225,111,180,80,123,183,65,108,197,175,217,148,62,78,176,226,160,30,4,249,44,168,225,213,84,72,108,123,16,148,131,175,129,181,241,115,32,150,204,29,149,183,158,16,158,203,150,6,127,181,230,27,176,99,112,147,105,121,1,180,69,121,215,169,53,95,37,143, -34,247,211,223,88,117,45,21,6,72,118,128,139,175,217,101,252,151,207,163,158,127,66,53,201,248,211,250,254,8,4,108,197,112,117,247,55,71,207,248,107,10,36,86,253,41,153,221,191,125,69,210,235,231,81,107,34,200,209,105,118,158,53,18,82,163,187,33,246, -238,109,16,91,125,39,104,241,3,163,242,214,213,238,38,248,210,216,239,65,119,104,58,68,88,94,128,57,207,161,216,160,68,71,149,95,115,242,15,38,255,212,25,176,98,86,0,10,0,228,99,198,255,2,98,252,31,160,163,124,205,234,238,71,215,251,233,248,222,235,199, -125,15,154,253,163,179,166,72,7,245,12,63,126,43,68,95,189,23,52,57,142,217,253,8,162,251,233,108,5,16,108,172,129,80,100,197,149,32,239,125,122,84,222,214,107,13,192,23,186,238,132,133,85,203,217,8,112,58,10,220,184,83,144,28,36,84,55,189,248,178,19, -191,59,233,94,103,192,134,34,0,5,0,242,33,227,255,43,37,174,8,102,120,254,84,181,83,245,62,177,100,46,92,219,125,55,107,7,58,10,110,63,107,223,27,121,236,43,32,239,94,149,76,242,227,5,60,185,8,98,44,28,144,76,18,140,31,130,216,170,255,76,70,3,18,135, -210,254,174,116,138,224,89,205,87,195,233,141,87,178,126,33,138,102,78,9,50,141,4,148,119,5,47,57,241,187,19,239,117,96,36,0,5,0,26,127,98,252,111,104,167,198,159,55,195,243,167,106,61,70,84,251,162,234,51,224,178,246,219,193,33,186,211,254,25,212,254, -221,16,121,242,118,214,212,71,147,19,201,78,126,8,130,152,248,164,182,176,252,128,100,52,224,11,32,31,120,105,84,222,150,62,71,46,109,191,21,44,188,245,200,132,80,163,208,214,193,101,157,129,75,150,125,119,18,21,1,120,110,81,0,20,184,231,159,80,77,49, -254,84,165,203,154,68,84,251,21,112,102,211,23,129,31,133,250,122,105,195,51,48,252,232,77,32,237,248,103,50,201,15,189,126,4,73,111,52,32,182,15,98,43,191,6,241,247,127,72,110,250,104,218,223,149,246,9,248,98,215,93,224,179,6,217,146,128,25,208,229, -128,178,46,38,2,126,225,12,226,114,0,10,128,194,51,254,203,169,231,47,155,228,249,203,170,68,78,38,15,23,181,222,12,139,171,207,76,251,254,107,241,65,136,190,120,15,68,158,255,30,249,126,8,215,250,17,100,212,158,218,86,246,74,108,123,8,34,255,188,26, -148,129,117,105,127,203,102,127,23,92,59,246,219,80,238,170,101,115,4,76,17,1,67,50,148,19,17,112,252,55,39,220,43,88,208,20,161,0,40,28,227,127,242,188,27,58,126,75,61,127,227,107,254,28,107,235,107,23,157,112,69,231,127,178,25,224,233,70,217,183,134, -117,243,75,172,123,42,25,238,199,12,127,4,201,64,52,192,13,234,192,122,136,190,121,45,72,59,254,152,246,119,164,198,255,186,177,223,129,38,95,39,75,48,54,131,56,17,1,21,227,139,46,153,255,229,142,31,112,216,50,16,5,64,1,24,255,197,243,110,236,248,173, -156,80,172,170,9,198,159,134,228,104,104,142,206,252,238,40,154,146,246,253,79,172,250,51,12,63,241,31,160,246,110,31,169,235,199,155,22,65,50,6,237,27,160,202,16,91,251,61,150,36,168,73,253,105,125,59,218,61,244,170,238,111,30,41,19,52,39,18,32,209, -102,65,87,31,115,75,231,93,40,2,80,0,228,45,237,39,84,205,156,127,83,199,239,21,83,154,252,112,172,198,191,216,81,1,87,119,223,13,13,222,246,180,238,187,22,27,128,232,179,223,134,232,171,63,79,246,43,23,109,120,66,17,36,43,130,1,2,203,13,144,246,60,5, -81,186,36,208,255,94,90,223,206,41,186,225,242,142,59,96,106,233,66,211,68,192,72,179,160,155,137,8,248,42,138,0,20,0,121,71,197,184,96,215,156,107,219,30,86,18,170,215,140,53,255,152,50,12,149,238,6,184,102,236,183,200,215,250,180,238,187,114,96,61, -12,63,118,11,36,54,62,155,44,239,227,48,209,15,65,178,78,7,208,37,129,161,109,172,149,176,180,243,47,105,125,47,171,96,131,75,218,110,129,185,21,39,154,214,48,136,150,8,118,157,82,115,231,130,175,116,94,133,103,19,5,64,62,25,255,134,19,191,61,241,17, -209,33,20,211,113,153,198,141,127,4,234,188,99,88,119,63,26,1,72,39,52,203,63,242,196,215,88,91,95,108,229,139,32,89,14,49,204,160,74,16,95,251,29,136,175,251,46,251,62,109,111,197,137,112,222,152,27,96,81,245,233,16,147,35,198,69,0,249,231,177,33,22, -9,248,225,184,51,235,206,193,147,137,2,32,231,41,170,247,20,19,227,255,103,171,75,172,49,99,176,15,77,190,105,244,117,16,227,255,45,8,164,121,126,120,124,229,31,32,242,194,247,89,71,63,12,249,35,72,206,132,2,216,168,225,196,246,135,33,186,242,86,114, -255,14,167,239,173,200,175,51,155,174,98,149,71,102,137,0,90,34,56,231,186,182,95,117,47,175,93,130,39,19,5,64,206,226,14,219,93,75,254,115,220,255,217,60,150,14,57,110,134,231,63,12,77,254,78,248,66,231,215,217,24,207,116,146,120,239,175,16,123,253, -62,54,196,7,179,252,17,36,231,84,0,209,1,30,144,247,191,4,177,213,95,39,134,85,78,235,187,157,222,116,37,156,88,119,33,139,78,26,21,1,116,88,16,113,150,172,243,110,236,120,176,110,102,241,100,60,151,40,0,114,14,98,244,249,101,223,155,244,235,226,22,239, -44,41,170,24,247,252,21,234,249,19,227,223,69,140,191,53,189,198,95,217,179,138,24,255,95,2,103,177,177,193,36,8,130,228,168,12,176,16,17,176,239,121,72,108,186,47,237,239,181,172,254,98,56,177,246,66,83,34,1,52,79,138,142,67,95,124,219,216,135,43,198, -21,213,227,153,68,1,144,51,208,166,22,243,191,220,241,253,146,54,255,105,52,156,101,134,241,111,58,108,252,211,236,249,131,28,135,232,107,247,210,59,16,147,253,16,36,31,68,128,232,74,142,23,78,115,117,192,17,17,80,119,33,43,79,54,44,2,36,21,236,30,75, -229,177,119,142,251,163,167,196,17,196,51,137,2,32,39,152,117,77,235,245,237,199,85,93,29,31,52,158,128,67,67,106,204,248,119,222,153,126,227,79,72,108,120,22,148,3,27,112,205,31,65,242,70,1,144,199,188,154,128,196,230,251,71,229,237,168,8,88,82,115, -22,203,87,50,42,2,164,152,2,174,144,173,251,196,239,76,124,192,21,182,227,224,0,20,0,217,205,248,179,235,79,27,123,90,237,183,105,93,171,193,187,246,72,182,63,29,205,233,177,6,210,191,243,196,235,151,222,255,27,113,252,45,120,34,17,36,159,16,236,160, -244,188,9,234,224,134,81,121,187,211,26,46,135,37,35,137,129,96,84,4,68,21,40,105,243,47,90,116,107,215,127,243,34,246,8,64,1,144,165,212,205,40,158,52,251,154,214,251,20,73,229,52,205,200,69,159,108,242,83,229,110,128,43,153,231,31,24,149,253,87,122, -54,147,215,86,186,134,129,39,19,65,242,236,81,175,145,103,138,124,224,31,163,246,142,167,55,125,1,230,86,158,4,17,19,170,16,104,52,181,110,102,201,165,243,111,234,188,25,207,37,10,128,172,35,220,226,173,88,250,95,227,126,175,72,154,219,104,163,159,184, -26,133,98,103,37,49,254,255,149,246,82,191,143,8,128,125,235,146,37,127,216,222,23,65,242,14,142,19,65,233,95,51,170,239,121,110,203,117,48,163,108,137,41,29,3,105,203,224,142,147,170,239,162,81,86,60,155,40,0,178,6,79,137,195,190,244,142,113,15,88,157, -98,173,42,27,43,247,163,131,125,252,214,16,92,217,241,95,16,78,115,147,159,127,17,0,125,59,209,246,35,72,222,42,0,1,180,232,94,114,163,199,71,239,45,201,175,11,198,220,4,227,195,179,13,15,16,162,65,85,37,174,192,172,171,90,127,89,59,45,60,14,79,40,10, -128,140,35,218,4,56,230,150,206,31,135,154,188,179,104,194,138,17,232,72,95,135,232,130,43,58,238,128,10,119,221,168,127,22,45,62,128,222,63,130,228,111,8,0,52,37,6,154,26,31,213,183,21,121,11,92,218,254,85,24,19,24,103,120,148,48,141,174,106,170,230, -93,124,251,216,223,251,43,93,97,60,169,40,0,50,202,244,43,90,174,169,159,85,122,137,209,140,127,69,147,65,224,5,184,180,237,107,80,239,107,203,208,167,209,240,132,34,72,94,147,153,123,220,46,56,225,178,142,219,161,202,221,196,74,4,141,56,26,180,157,186, -195,103,109,60,225,238,137,247,219,125,86,172,85,70,1,144,25,218,79,168,58,102,226,185,13,223,137,15,38,140,169,90,77,37,2,64,129,243,90,110,128,142,162,204,53,190,226,44,46,20,1,8,146,207,182,159,120,227,92,134,58,123,122,173,1,184,162,243,14,8,217, -75,33,161,198,12,109,139,70,91,195,45,222,197,243,110,104,255,22,158,88,20,0,163,78,121,87,160,122,238,245,237,247,75,49,89,52,146,240,79,235,100,105,210,223,169,13,159,103,227,53,51,122,49,120,203,146,11,109,8,130,228,33,10,240,182,34,54,39,32,83,208, -225,101,151,117,222,14,78,209,5,178,102,44,106,26,31,146,96,204,146,138,235,39,158,223,112,54,158,91,20,0,163,134,221,103,177,46,188,181,251,126,209,46,148,170,178,49,131,73,19,99,22,85,157,206,134,105,100,26,33,220,8,156,128,125,255,17,36,47,3,0,170, -76,68,126,11,100,58,207,167,214,51,6,46,110,189,133,37,8,170,154,129,188,41,242,232,149,99,10,76,191,172,229,167,181,51,138,187,240,12,163,0,24,21,230,223,212,249,237,162,122,207,108,217,96,210,31,53,254,147,74,230,193,242,198,43,178,226,115,9,225,102, -224,61,165,0,170,140,39,25,65,242,12,142,19,64,44,154,146,21,251,210,21,154,198,166,8,74,106,194,80,183,64,86,114,205,129,103,209,215,186,255,215,87,225,244,226,89,70,1,144,86,38,95,220,116,86,203,162,138,171,227,195,198,194,87,49,37,202,198,250,94,56, -230,203,192,103,73,207,125,206,226,4,75,237,140,145,94,0,8,130,228,13,106,156,120,255,77,32,4,186,179,102,151,230,84,156,8,75,106,206,54,92,30,72,199,172,187,130,182,142,133,183,118,255,183,96,69,147,134,2,32,77,212,76,13,143,153,122,105,211,79,228,152, -108,40,87,142,214,250,135,236,37,240,185,246,91,89,217,95,54,97,105,59,22,120,103,32,57,12,8,65,144,188,64,83,37,176,86,47,39,79,252,236,106,167,127,74,253,165,48,181,228,24,195,34,32,17,145,161,122,74,232,220,105,159,111,190,2,207,54,10,0,211,113,248, -172,246,121,55,118,252,134,227,192,111,164,211,31,45,247,179,240,54,184,164,237,171,16,114,148,103,223,5,225,46,6,91,247,114,208,164,40,158,116,4,201,7,227,47,71,88,232,95,44,61,38,235,246,141,227,120,56,111,204,13,172,244,217,104,121,32,237,20,56,241, -220,134,239,54,206,45,29,143,103,29,5,128,169,204,187,169,227,174,96,141,123,178,28,215,223,233,143,174,117,209,102,63,103,53,95,13,77,254,236,205,89,177,118,156,8,150,186,233,160,37,134,241,196,35,72,46,163,38,88,230,191,173,245,186,172,29,239,77,163, -160,151,182,221,10,126,91,136,60,31,245,47,63,106,228,209,172,170,154,131,58,106,238,176,221,131,39,31,5,128,41,140,61,163,110,217,152,37,21,215,210,178,19,35,208,48,23,205,246,159,81,182,52,187,63,48,121,80,56,102,95,11,98,113,11,70,2,16,36,103,141, -191,196,66,254,246,206,175,2,239,172,202,234,93,45,113,86,194,69,173,95,102,17,1,218,23,69,47,52,31,192,93,108,239,88,112,115,231,247,104,231,67,4,5,128,33,194,77,222,138,105,159,111,254,169,20,53,150,25,79,141,255,216,240,76,56,185,225,115,57,241,185, -57,187,23,28,199,124,21,132,162,122,20,1,8,146,147,198,223,66,140,255,109,32,4,39,229,196,46,183,145,253,60,181,225,50,214,23,197,72,146,85,98,88,134,134,185,165,151,78,190,176,225,12,188,16,80,0,232,134,102,148,30,243,213,174,159,217,220,162,161,122, -255,132,26,135,82,87,53,92,48,230,6,16,184,220,233,92,201,187,195,224,90,244,31,40,2,16,36,23,141,127,215,109,32,134,167,231,212,174,31,83,117,26,204,42,59,206,112,82,160,20,145,105,197,214,143,75,90,125,181,120,65,160,0,208,197,140,43,199,92,85,214, -17,56,78,138,234,207,136,167,45,126,173,188,21,46,106,189,25,124,214,162,156,59,6,28,17,1,206,17,17,0,40,2,16,36,103,60,127,49,52,61,39,63,194,153,205,87,65,189,175,99,36,41,80,231,97,80,52,16,173,124,104,254,151,59,127,110,117,137,184,22,128,2,32,53, -106,166,134,59,198,159,89,127,23,45,47,209,143,198,122,94,159,214,120,5,171,249,207,217,139,100,36,18,192,99,36,0,65,114,195,248,135,167,231,236,199,160,131,131,104,62,128,219,226,3,89,211,255,252,165,142,91,121,87,112,225,244,203,91,174,197,139,3,5, -192,81,99,243,88,196,185,215,183,255,92,211,52,151,166,234,15,253,71,228,97,22,206,154,91,177,44,231,143,9,139,4,44,190,13,151,3,16,4,141,127,218,41,119,213,194,217,205,215,130,162,202,134,58,5,210,65,109,221,167,213,222,89,61,57,212,137,23,9,10,128, -163,130,40,198,175,20,213,123,166,201,113,253,161,127,234,249,215,122,91,224,140,230,47,230,207,197,226,10,97,78,0,130,160,241,31,21,104,155,244,99,170,78,53,148,15,144,156,109,166,57,169,67,103,115,91,44,120,177,124,20,156,252,242,49,106,167,134,39, -116,157,90,115,107,194,64,171,95,58,224,194,198,59,224,130,49,55,130,67,72,83,167,63,162,140,19,187,214,129,180,125,53,200,7,182,129,26,237,103,87,59,103,119,131,24,172,0,75,101,27,88,171,218,129,179,153,251,254,135,115,2,34,127,251,79,80,14,109,6,206, -226,192,139,6,65,242,214,248,107,160,36,54,130,28,95,3,138,180,13,52,181,47,89,112,207,59,129,23,75,65,180,182,128,104,107,3,142,79,79,217,253,41,13,159,135,173,3,239,195,198,254,85,96,211,57,197,144,246,110,9,53,122,167,78,251,124,243,77,207,127,239, -189,175,227,69,131,2,224,19,177,123,45,214,57,95,106,255,41,185,230,173,6,74,81,153,247,127,78,203,151,160,198,211,98,254,237,40,197,32,242,207,191,146,215,95,64,222,183,25,180,196,72,247,44,158,251,64,242,210,151,96,97,66,192,222,49,15,92,83,78,5,129, -124,111,90,36,96,36,39,96,24,69,0,130,100,222,248,119,165,33,225,79,75,64,124,248,41,136,15,61,193,4,128,166,142,68,252,56,254,67,174,181,198,122,134,240,98,9,88,157,51,193,238,57,133,124,95,97,234,110,88,120,43,156,63,230,6,248,214,91,87,177,164,64, -129,211,103,178,168,67,215,189,188,246,107,155,95,222,247,232,246,21,7,87,226,197,51,242,44,199,67,240,1,211,46,107,185,161,168,193,51,209,72,232,159,134,171,38,23,47,128,121,21,39,153,190,127,241,141,43,224,224,79,46,134,254,63,125,3,164,221,235,217, -205,72,61,126,206,238,2,206,234,76,190,136,199,207,126,102,177,129,210,183,7,134,158,253,21,28,248,201,133,48,244,226,253,73,229,110,114,36,0,171,3,16,36,195,158,191,201,198,95,138,189,1,3,123,175,132,225,131,119,19,239,121,45,115,48,56,222,149,124,113, -142,228,139,119,142,252,222,14,154,124,8,98,253,15,193,192,158,43,32,54,240,144,233,31,181,204,85,3,167,55,94,105,104,114,224,200,163,207,54,247,250,246,159,216,220,22,116,124,81,0,124,148,154,105,225,14,22,250,31,50,144,117,74,46,80,218,209,234,204, -230,171,77,223,191,225,127,60,0,61,247,93,3,210,222,13,71,12,252,103,118,186,18,44,192,57,60,160,69,135,96,224,175,223,133,158,255,185,30,212,225,94,115,35,1,139,147,213,1,40,2,16,36,3,198,223,228,176,127,172,255,127,96,104,223,205,32,19,175,63,105,224, -109,240,153,253,249,137,87,206,241,110,208,180,8,68,122,126,4,195,7,238,32,6,55,98,234,126,77,47,91,66,94,75,33,38,235,223,46,117,236,66,141,222,233,211,46,107,190,6,47,34,20,0,71,176,185,69,126,238,117,237,63,34,226,210,161,105,58,21,230,136,50,61,155, -92,91,94,107,192,212,253,27,122,238,62,232,255,203,221,204,224,115,22,123,234,27,16,68,38,4,98,171,159,131,67,191,186,10,148,190,189,230,69,2,92,88,29,128,32,249,96,252,35,189,63,38,175,159,177,176,62,245,236,83,39,41,4,226,195,127,131,161,3,255,65,4, -129,185,207,131,211,27,175,96,209,0,201,192,188,0,218,37,176,251,180,218,219,202,187,2,77,120,49,161,0,96,76,56,167,254,243,161,6,207,92,163,161,255,5,85,167,66,71,209,20,83,247,45,250,246,227,48,240,212,127,3,103,115,146,179,101,172,139,32,21,1,210, -206,53,208,243,155,235,76,21,1,180,58,192,137,213,1,8,146,211,198,63,214,255,32,51,224,70,205,2,77,8,148,162,175,66,228,208,247,76,221,71,218,23,224,236,150,107,128,35,251,167,129,190,229,76,90,214,77,252,40,207,236,107,218,126,32,88,208,252,21,252,17, -40,105,245,87,78,56,183,241,206,248,176,254,208,63,109,245,91,231,109,133,101,117,23,153,186,111,210,174,181,196,243,255,22,17,228,150,15,146,111,140,122,236,54,23,203,31,48,91,4,124,56,39,0,69,0,130,228,162,241,167,21,67,230,52,205,163,34,128,38,16, -198,6,30,52,117,95,219,2,19,89,187,224,168,129,165,0,41,166,64,197,216,224,210,73,23,52,158,131,2,160,144,63,188,192,193,140,47,180,124,75,180,241,69,122,27,254,208,201,85,34,39,178,208,191,222,50,149,79,220,110,164,31,250,254,112,59,168,241,8,11,225, -155,9,141,38,164,67,4,240,40,2,16,36,125,198,191,43,93,198,255,33,83,141,255,7,34,192,1,209,222,95,128,28,251,167,169,219,61,161,238,66,226,112,141,129,132,18,211,239,180,69,100,24,127,118,221,55,131,53,238,162,66,190,180,10,90,0,140,89,92,177,168,102, -106,248,108,35,237,126,227,74,4,22,215,156,5,13,190,118,83,247,173,255,145,187,153,145,214,181,230,159,37,34,0,19,3,17,196,68,207,223,228,108,255,72,207,97,207,223,105,186,241,79,66,151,44,85,86,77,160,42,251,77,219,170,77,176,195,89,205,87,131,200,91, -65,211,89,217,68,103,5,216,60,150,202,233,87,182,220,129,2,160,0,113,248,172,182,169,151,53,127,151,206,143,214,173,34,137,2,173,39,134,255,216,26,115,35,73,195,47,255,14,162,111,61,206,178,253,211,73,186,150,3,62,92,29,128,145,0,4,49,193,248,135,211, -96,252,7,30,76,139,231,255,209,135,140,21,20,101,15,68,14,125,151,252,70,49,109,179,141,190,78,88,88,181,28,162,138,254,165,0,234,248,53,205,43,187,188,97,78,233,100,20,0,5,198,228,139,27,175,241,87,186,58,244,10,0,170,60,69,114,115,158,217,116,21,107, -86,97,22,137,237,171,96,224,169,159,144,251,102,52,154,235,104,35,34,224,253,17,17,176,207,188,251,158,85,7,224,114,0,130,100,157,241,239,29,37,227,127,248,89,192,185,136,177,253,7,196,250,127,107,234,118,143,173,61,151,229,94,37,244,86,5,104,44,18,32, -204,184,162,229,123,22,135,80,144,182,176,32,63,116,73,171,175,186,235,148,154,175,36,12,36,254,81,229,73,179,254,205,12,253,171,209,65,232,123,248,191,64,147,227,134,51,254,83,19,1,238,17,17,112,173,201,213,1,97,156,29,128,32,217,102,252,251,71,207, -248,31,17,1,188,19,162,125,255,99,106,62,0,93,10,56,163,233,11,196,136,241,186,27,4,177,222,0,77,222,25,19,206,109,56,31,5,64,1,192,241,52,241,175,245,78,193,38,248,245,38,254,209,58,212,106,79,35,28,87,123,158,169,251,54,240,216,61,32,239,73,223,186, -255,103,71,2,176,58,0,65,50,138,150,127,198,255,3,83,163,193,240,161,239,131,166,244,153,182,213,102,127,55,204,173,92,102,104,96,16,29,27,60,246,244,218,59,189,165,142,64,161,93,110,5,39,0,26,231,150,206,172,153,26,58,71,210,153,248,167,141,104,205, -211,26,175,96,115,171,205,34,250,246,19,16,121,227,207,105,95,247,255,183,198,58,141,137,129,24,9,64,144,163,240,252,185,220,203,246,63,250,7,140,21,20,121,59,217,151,31,153,186,217,19,106,47,132,50,103,53,235,196,170,235,176,203,42,56,252,214,138,233, -87,180,220,140,2,32,143,161,235,60,228,36,127,83,77,168,186,63,55,109,69,57,189,116,49,116,4,205,203,27,81,14,237,132,254,199,190,7,156,104,201,220,205,153,102,17,128,179,3,16,228,51,140,127,206,102,251,167,240,28,224,92,16,31,250,59,36,134,30,55,109, -155,46,139,135,77,13,164,83,88,65,231,82,0,141,2,52,47,40,255,98,121,119,160,25,5,64,158,210,189,188,246,204,162,58,207,12,89,103,226,159,172,201,16,180,23,195,178,250,139,77,188,241,85,232,123,228,110,80,7,15,177,222,253,217,192,104,84,7,160,8,64,144, -79,48,254,185,154,237,159,202,243,133,183,178,150,195,170,188,211,180,109,78,40,158,3,227,195,179,33,166,232,123,174,208,229,96,222,202,59,103,92,57,166,160,198,5,23,140,0,240,20,219,93,19,207,107,184,67,138,25,24,246,163,196,217,186,127,192,22,54,109, -191,134,95,121,8,226,107,95,98,70,55,123,248,120,78,0,86,7,32,8,26,127,179,16,137,223,211,11,195,61,63,160,7,192,180,173,158,210,240,57,112,137,222,145,72,128,158,40,128,12,149,227,138,78,109,61,182,114,54,10,128,60,99,236,25,117,87,56,131,182,70,85, -214,23,34,138,43,49,150,112,50,171,252,56,211,246,73,222,187,17,6,159,254,217,40,149,252,233,21,1,35,213,1,253,230,86,7,56,23,225,0,33,4,141,127,190,148,250,165,236,8,112,78,144,34,175,65,108,240,143,166,109,179,196,89,5,139,170,79,39,207,106,157,207, -20,141,229,3,112,147,47,106,252,186,197,33,114,133,112,9,22,132,0,8,55,121,139,59,79,169,185,73,26,214,159,248,39,242,34,83,152,2,103,82,91,94,85,129,254,71,190,205,74,255,70,175,228,207,64,36,224,215,102,231,4,224,0,33,4,141,127,254,101,251,167,240, -12,224,237,16,237,187,15,20,105,171,105,219,164,115,2,170,60,77,186,19,2,233,242,112,81,189,103,102,235,146,138,83,80,0,228,9,19,47,104,184,222,238,17,195,170,206,178,63,154,248,55,181,116,17,52,249,187,76,219,39,22,250,223,184,34,57,229,47,203,193,217, -1,8,146,6,227,159,175,217,254,71,141,0,154,58,8,209,158,31,131,89,75,1,116,30,203,178,186,139,117,47,3,48,17,16,83,96,194,249,245,183,59,131,54,107,190,95,138,121,47,0,138,91,124,53,141,115,74,175,212,219,239,95,33,23,146,223,86,4,39,212,154,215,39,66, -62,176,21,6,159,190,55,75,67,255,153,19,1,152,24,136,20,138,241,119,164,35,219,191,55,123,178,253,143,250,185,194,57,33,17,125,29,226,131,143,152,182,205,113,225,153,208,77,142,109,76,103,155,96,69,82,33,88,227,233,24,119,70,221,121,249,126,57,230,189, -0,152,112,94,253,205,162,93,112,235,156,25,193,214,147,142,169,90,14,65,123,137,57,59,164,105,172,225,143,26,237,207,226,208,255,167,137,0,156,29,128,32,134,61,127,98,252,133,112,186,74,253,114,193,243,255,216,115,133,183,177,165,0,85,222,99,218,54,79, -172,191,136,69,3,84,157,15,254,68,68,130,246,101,85,183,184,66,25,108,204,130,2,192,24,165,29,254,230,198,185,165,23,208,236,78,61,208,117,164,42,119,3,204,175,60,217,188,27,245,173,71,33,182,246,197,44,203,250,63,106,245,130,213,1,8,98,208,248,23,78, -182,255,209,34,130,170,244,176,210,64,179,168,118,55,193,204,178,99,217,180,86,93,167,75,214,192,29,182,215,143,61,189,230,226,124,190,44,243,86,0,208,150,191,179,190,216,122,139,96,21,28,122,189,127,69,149,89,217,31,85,146,166,60,3,6,15,193,224,223, -126,10,156,152,203,75,75,31,171,14,192,217,1,8,146,57,227,223,155,235,198,255,240,243,218,73,188,238,231,64,138,188,104,218,54,151,214,158,205,74,182,21,77,167,3,24,85,160,253,196,234,47,17,33,224,65,1,144,99,212,78,15,183,85,140,15,158,165,215,251,167, -101,127,45,129,177,48,177,120,158,105,251,68,75,254,148,222,221,89,211,240,199,188,72,0,206,14,64,144,140,24,255,254,220,55,254,35,119,62,249,37,64,164,239,94,208,212,33,83,182,232,183,134,96,65,213,105,108,108,187,190,40,128,74,163,0,53,221,167,213, -92,142,2,32,151,62,20,241,254,39,158,219,240,101,98,167,172,122,58,67,210,178,63,158,227,224,248,218,243,201,87,115,14,81,98,203,91,16,249,231,35,57,26,250,255,148,91,22,103,7,32,200,103,27,255,130,207,246,63,218,7,138,21,148,196,22,136,13,252,206,180, -77,206,173,88,6,229,174,90,144,232,185,208,21,5,144,161,99,89,245,181,238,144,221,139,2,32,71,168,156,80,52,134,120,255,103,208,16,142,94,239,191,43,52,29,90,131,19,204,217,33,69,134,129,39,127,12,154,162,208,180,215,188,58,214,56,59,0,65,62,221,248, -99,182,127,138,247,61,249,76,177,129,63,130,34,109,50,101,123,14,209,5,139,170,207,0,89,247,160,32,13,92,97,123,121,247,233,53,23,162,0,200,17,218,79,172,186,142,227,56,155,158,127,171,129,10,86,222,10,199,214,156,107,218,254,12,191,241,103,72,108,121, -155,8,92,123,62,30,110,172,14,64,144,79,242,252,49,219,95,151,73,210,180,8,68,123,127,97,218,22,167,149,46,130,90,111,11,27,227,174,43,10,16,145,161,131,230,2,228,97,69,64,222,9,128,226,22,95,125,227,220,178,243,164,136,94,239,63,202,6,75,212,121,199, -152,243,44,24,234,129,161,231,238,3,206,98,131,252,229,99,57,1,253,88,29,128,160,241,199,108,127,157,247,60,235,13,240,10,36,76,74,8,20,137,67,183,184,250,44,80,84,125,54,65,85,88,20,160,166,123,121,237,57,40,0,178,156,9,231,214,95,101,177,243,14,77, -75,125,241,95,211,84,176,11,46,114,177,156,105,218,254,12,61,255,107,80,122,119,229,65,226,223,209,138,128,247,161,231,215,105,168,14,64,17,128,228,140,241,255,15,204,246,55,42,2,64,128,88,223,125,228,153,28,51,101,123,19,137,83,215,224,239,128,132,129, -40,0,141,44,187,66,246,188,242,228,242,74,0,148,140,241,149,53,206,45,189,80,111,215,191,152,26,133,201,37,243,161,210,221,96,202,254,208,97,63,195,43,254,148,87,137,127,41,69,2,204,204,9,112,97,117,0,146,205,151,254,135,61,255,25,230,27,255,254,194, -49,254,201,27,222,10,114,98,3,196,7,255,98,142,161,227,4,54,40,72,111,99,32,26,5,112,23,219,91,154,230,149,230,213,140,128,188,18,0,109,199,87,93,106,113,138,126,77,87,230,191,10,78,193,13,11,171,150,155,182,63,131,207,220,11,90,124,152,102,182,20,212, -179,16,103,7,32,5,231,249,115,233,44,245,123,168,176,140,255,225,231,8,111,135,216,192,239,65,83,14,154,178,189,113,161,153,208,232,107,215,29,5,144,227,10,116,157,86,123,157,197,33,228,205,3,61,111,62,136,167,212,225,105,94,88,246,121,73,175,247,47, -71,97,82,201,60,40,115,213,154,178,63,241,77,43,32,186,250,57,34,100,157,80,136,224,236,0,164,96,140,255,225,108,255,48,102,251,155,139,8,170,188,143,136,128,135,76,139,2,44,172,210,31,5,80,18,42,132,26,60,147,90,151,86,30,131,2,32,203,232,58,165,230, -44,87,200,94,73,67,53,169,123,255,26,216,69,39,204,175,52,41,186,67,46,176,193,103,126,193,190,230,91,217,95,106,34,192,149,214,62,1,60,138,0,36,11,140,63,102,251,167,51,10,224,132,216,224,99,160,72,219,77,217,222,216,176,177,40,128,34,171,208,122,92, -229,181,180,211,44,10,128,44,193,230,22,197,166,5,101,95,160,99,28,117,121,235,114,4,198,135,103,155,182,246,31,91,253,44,36,54,189,153,83,211,254,210,67,26,171,3,104,36,96,241,109,184,28,128,100,220,248,155,237,249,71,123,10,43,225,239,179,76,20,29, -25,28,27,248,95,83,182,38,112,2,235,14,168,119,92,176,18,87,160,172,195,191,176,110,70,113,55,10,128,44,161,97,110,233,194,96,173,187,139,142,113,212,227,253,91,5,59,185,40,78,53,199,228,201,9,24,124,254,55,57,55,233,47,253,34,224,112,117,128,121,34, -128,119,133,176,68,16,201,43,227,79,61,255,40,26,255,143,69,1,28,144,24,126,22,148,196,251,166,108,143,230,2,212,120,154,217,176,183,148,159,102,26,155,51,35,118,44,171,186,18,5,64,54,124,0,145,167,77,26,190,168,199,248,83,104,159,232,142,162,201,80, -235,105,49,71,189,175,124,10,164,29,239,229,121,221,191,145,72,192,181,88,29,128,228,240,165,140,131,125,50,19,5,136,67,180,255,183,166,108,77,36,231,111,94,197,73,32,235,109,15,28,81,160,122,114,248,140,112,179,183,20,5,64,134,169,158,84,212,81,62,46, -184,72,79,248,63,217,243,95,48,109,237,95,75,68,97,232,69,114,145,138,22,188,103,63,201,88,99,117,0,146,235,158,63,102,251,103,44,10,32,69,95,1,57,254,158,41,219,155,84,50,31,202,92,53,32,107,169,139,0,218,99,198,234,18,124,173,199,86,158,143,2,32,195, -180,29,87,117,9,167,129,168,75,201,17,85,217,228,235,132,150,192,56,115,188,255,183,31,7,121,207,250,28,31,247,155,251,34,0,19,3,145,180,24,127,204,246,207,228,147,131,24,94,217,180,92,0,58,226,125,86,217,177,32,41,122,27,3,41,48,102,113,197,37,206,128, -45,167,67,189,57,45,0,188,101,142,64,205,212,240,217,180,62,83,215,61,173,169,48,167,98,25,27,68,105,138,247,255,202,67,104,252,143,74,4,96,117,0,146,123,198,31,179,253,51,252,220,224,236,196,240,190,6,114,124,181,41,219,155,86,182,24,2,246,98,80,116, -36,4,178,198,64,97,91,115,227,252,210,69,40,0,50,68,243,194,242,83,156,1,107,177,158,210,63,58,29,170,210,93,15,99,77,186,161,233,218,191,188,103,3,0,10,128,163,145,75,31,36,6,178,234,0,147,167,8,98,117,0,146,6,227,143,189,253,179,32,10,0,178,105,125, -1,188,214,32,76,42,158,199,242,192,244,160,200,26,180,46,169,184,44,151,75,2,115,86,0,88,157,34,215,113,98,245,231,36,157,165,127,116,62,244,244,210,165,96,225,141,71,112,52,57,14,195,175,254,30,215,254,83,22,1,238,100,36,224,215,215,97,117,0,146,181, -198,223,129,9,127,89,20,5,112,128,20,121,21,228,248,26,83,182,55,171,252,120,54,50,152,118,130,77,217,137,140,43,80,210,30,56,166,172,35,208,132,2,96,148,41,31,27,156,228,175,118,77,214,147,253,79,107,64,3,182,16,76,41,53,167,161,19,173,251,151,118,173, -3,78,196,204,255,212,69,128,51,125,213,1,40,2,16,19,60,127,1,141,127,150,69,1,18,16,31,252,63,115,236,136,171,22,218,139,38,65,92,79,46,128,70,3,190,188,173,245,184,138,243,80,0,140,50,109,199,85,94,192,233,188,123,226,106,12,198,23,207,6,159,53,104, -194,131,66,129,225,87,254,128,117,255,70,110,233,116,37,6,162,8,64,12,26,255,180,101,251,115,104,252,245,71,1,236,144,136,188,2,138,180,217,156,40,64,217,113,196,16,234,59,23,82,84,134,250,89,37,231,56,131,182,156,236,250,150,147,2,192,87,238,244,87, -79,9,157,42,233,44,253,179,241,118,152,81,182,212,148,125,137,175,127,5,18,219,223,5,206,98,199,59,51,75,69,128,11,171,3,144,20,141,63,102,251,103,183,217,210,212,97,136,15,254,217,148,173,141,9,78,128,106,79,147,174,198,64,52,255,204,83,236,168,111, -154,95,186,0,5,192,40,209,188,176,252,56,103,192,86,162,169,169,39,255,209,178,143,38,127,23,212,152,212,248,103,248,213,63,224,253,104,154,8,72,211,40,97,172,14,64,82,244,252,49,219,63,203,159,21,196,137,75,12,63,79,12,176,241,220,33,145,19,97,106,233, -34,150,24,174,235,178,81,84,104,156,91,118,65,46,158,214,156,19,0,180,243,95,243,49,101,23,40,9,157,165,127,228,215,244,178,37,166,236,139,180,99,53,196,55,190,129,222,191,105,124,124,118,128,217,213,1,73,17,128,203,1,200,167,26,255,46,204,246,207,13, -4,98,120,123,32,62,248,184,41,91,155,88,60,15,252,182,176,174,25,1,82,92,129,242,238,192,226,226,102,95,5,10,128,52,19,110,242,54,6,235,61,179,229,68,234,201,127,138,38,67,177,163,2,186,138,166,153,227,253,191,254,48,171,0,40,228,137,127,105,21,1,191, -78,223,114,0,138,0,228,227,198,159,133,253,67,104,252,115,43,10,240,55,208,212,33,195,219,242,219,138,160,43,52,77,95,73,32,49,69,22,135,232,105,152,83,114,50,10,128,52,211,118,92,197,105,162,77,176,65,234,209,127,114,114,227,108,234,31,45,251,48,138, -210,187,27,98,107,94,64,239,63,109,34,192,153,182,229,0,108,27,140,252,139,231,143,217,254,57,136,8,138,180,19,18,145,231,77,217,218,212,210,133,32,240,22,246,252,73,21,57,161,208,165,233,179,45,14,33,167,78,116,78,9,0,139,83,224,107,166,21,159,174,196, -117,38,255,137,14,152,108,82,174,70,228,205,71,65,29,234,197,236,255,116,42,252,116,182,13,198,234,0,36,237,217,254,104,252,211,254,140,224,68,136,15,209,101,0,197,240,182,104,91,248,100,50,160,164,227,82,82,33,80,229,154,92,218,17,232,64,1,144,38,202, -58,2,227,253,149,206,110,85,78,61,252,79,147,255,26,188,237,80,237,54,222,179,65,75,68,32,250,206,83,56,241,47,151,69,128,11,103,7,160,241,79,119,182,63,26,255,244,63,32,172,160,196,215,130,28,91,105,252,153,192,9,48,177,120,174,174,100,64,58,38,152, -23,121,161,97,78,201,105,40,0,210,68,203,226,138,229,28,207,241,154,142,240,63,237,247,76,39,64,153,65,108,237,203,32,31,216,2,32,96,231,191,209,17,1,31,106,27,140,179,3,16,19,61,127,204,246,207,249,167,3,49,190,202,72,20,192,56,19,138,231,128,219,234, -103,115,98,82,118,50,99,10,237,9,112,138,221,103,21,115,229,232,229,140,0,112,6,108,150,186,233,197,39,233,25,251,75,51,59,253,182,16,116,135,204,73,254,139,188,249,87,154,129,130,247,222,168,241,161,182,193,105,154,29,128,213,1,133,103,252,205,246,252, -163,152,240,151,25,9,192,219,136,126,127,29,84,217,248,115,33,100,47,131,22,255,88,54,41,54,229,75,75,86,193,87,225,236,168,158,84,52,1,5,128,201,84,77,42,154,228,10,217,154,245,12,254,73,144,147,217,26,156,0,62,107,145,225,253,160,70,40,177,229,45,76, -254,203,136,8,72,87,117,64,8,171,3,10,200,248,59,210,52,216,39,138,198,63,67,208,146,192,62,72,68,158,53,101,107,180,36,80,211,147,101,206,174,49,128,134,57,165,57,83,13,144,51,2,160,97,46,57,168,58,207,9,29,247,75,215,118,76,81,249,239,60,1,90,60,130, -165,127,25,19,1,88,29,128,232,185,116,48,219,63,175,163,0,156,5,18,195,207,38,207,179,65,58,138,38,65,145,189,148,149,141,167,10,173,6,168,28,95,116,162,195,103,205,137,245,225,156,16,0,206,160,205,90,49,54,120,130,172,35,251,159,158,196,176,163,2,198, -4,198,25,127,134,196,135,33,250,222,115,152,252,151,233,155,29,171,3,144,84,61,127,14,179,253,243,251,161,96,37,198,119,19,72,241,119,140,219,27,209,3,109,193,137,250,90,3,203,26,184,139,237,173,85,147,67,227,81,0,152,68,121,87,96,130,59,108,111,209, -27,254,239,40,154,12,118,193,105,120,63,226,235,95,3,229,224,14,76,254,203,10,17,224,194,217,1,200,209,25,127,44,245,43,16,20,72,12,61,109,202,150,38,132,103,179,170,0,125,209,8,128,234,137,161,147,80,0,152,68,245,164,208,9,122,35,238,2,39,194,184,208, -12,115,110,248,119,158,196,251,60,107,208,62,90,29,208,143,179,3,16,52,254,5,237,20,112,54,144,98,111,128,166,244,24,222,22,157,23,19,118,148,235,91,6,136,171,80,49,46,120,172,197,46,100,125,147,152,172,23,0,22,135,40,84,79,13,31,75,15,106,202,39,66, -147,160,196,81,1,13,62,227,189,25,148,222,61,144,216,242,38,112,34,134,255,179,75,4,184,147,34,128,37,6,238,51,239,97,50,82,29,128,203,1,104,252,63,78,20,75,253,178,20,1,84,249,0,36,162,175,24,222,146,77,112,64,107,96,2,235,30,155,178,173,144,84,240, -87,187,218,203,58,3,237,40,0,12,82,49,54,216,230,175,116,117,208,131,154,42,146,146,128,214,224,68,176,10,198,51,246,99,107,158,199,206,127,89,45,2,232,114,192,181,166,87,7,124,52,49,16,31,246,185,100,252,49,219,191,16,195,0,2,155,18,104,6,99,195,51, -64,224,245,149,244,11,34,47,212,207,41,93,154,237,135,43,235,5,64,213,164,162,69,188,160,111,49,70,36,39,111,108,104,166,41,70,38,186,250,89,122,86,241,6,203,90,17,224,76,75,179,32,238,35,137,129,17,60,212,57,228,249,11,56,213,175,240,236,63,77,6,140, -191,71,188,240,237,134,183,69,91,3,211,101,0,89,213,87,13,80,222,21,56,150,207,242,209,0,89,45,0,232,232,223,202,241,69,75,21,41,245,236,127,26,254,15,179,240,127,155,225,253,144,246,110,4,105,231,90,224,68,43,222,97,217,124,243,167,49,49,16,171,3,114, -203,248,139,88,234,87,160,240,108,58,160,20,125,217,240,150,232,50,0,173,30,147,53,29,213,0,146,10,69,117,238,137,225,102,111,21,10,0,157,248,43,157,101,193,90,247,100,61,225,127,153,60,12,104,71,39,122,18,141,18,95,243,34,104,241,33,236,254,87,224,34, -192,133,34,32,235,141,191,163,11,19,254,48,10,32,130,20,161,121,0,154,225,109,209,209,241,156,142,115,78,219,213,91,156,162,179,122,114,104,46,10,0,157,84,77,10,205,180,185,45,30,29,109,153,217,73,235,44,154,98,194,131,69,129,216,218,23,1,4,244,254,115, -3,45,109,34,128,195,18,193,236,246,252,137,241,23,66,104,252,81,1,208,158,0,27,64,73,108,50,188,169,70,95,7,4,236,197,108,150,76,202,151,165,172,66,213,132,208,98,46,139,155,198,101,183,0,24,95,180,88,83,83,87,113,201,222,255,97,104,244,119,26,222,7, -105,207,122,242,218,128,225,255,156,20,1,135,115,2,176,58,32,239,141,63,13,251,135,48,219,31,73,186,127,154,58,76,52,186,241,106,0,151,197,11,13,190,118,93,77,129,228,132,10,225,22,239,44,103,145,205,153,173,71,42,107,5,128,221,107,181,148,118,6,102, -209,100,138,148,141,54,57,89,245,222,86,112,91,124,134,247,35,254,254,43,160,37,162,216,250,55,39,69,192,72,137,32,171,14,48,79,4,252,107,117,0,146,113,227,143,217,254,200,135,37,0,109,13,28,93,1,102,44,3,180,7,39,147,205,164,30,134,166,206,171,195,111, -173,14,55,123,187,81,0,164,72,81,131,167,205,85,100,109,212,211,253,143,142,114,164,173,28,141,219,16,21,98,239,255,3,64,196,206,127,185,29,9,48,191,68,144,195,182,193,121,109,252,49,225,47,215,21,128,21,148,196,70,80,164,173,134,55,213,226,239,6,151, -213,11,42,164,40,2,52,90,149,200,67,221,140,226,249,217,122,152,178,86,0,212,78,13,205,17,44,228,232,105,169,30,115,21,156,22,55,52,251,141,139,46,121,255,150,100,248,31,91,255,230,246,179,32,93,179,3,92,56,64,40,239,140,63,203,246,127,8,141,127,238, -223,245,35,203,0,43,12,111,41,228,40,131,10,87,61,75,44,79,253,82,85,161,180,221,63,143,23,179,243,90,202,74,1,64,147,237,203,199,6,231,41,178,158,236,127,25,202,156,53,80,226,50,94,125,17,223,176,2,180,24,102,255,231,135,8,112,165,109,128,208,225,234, -0,76,12,204,3,227,207,214,252,157,104,252,243,225,158,231,4,83,4,0,77,40,167,21,101,138,142,126,0,106,178,43,224,120,111,137,163,40,27,143,81,86,90,54,87,145,221,21,172,117,79,84,117,150,255,209,228,63,222,132,143,22,219,240,10,118,254,203,27,210,95, -29,128,179,3,70,201,248,99,169,31,114,84,55,38,93,6,216,0,170,98,60,255,135,246,3,16,121,11,164,154,83,160,170,26,216,61,150,64,73,155,127,98,54,30,162,172,20,0,197,45,222,46,71,192,86,169,103,253,159,78,112,106,13,24,159,196,168,14,236,7,105,231,58, -204,254,207,75,17,144,190,234,0,30,151,3,210,111,252,49,219,31,57,74,243,166,42,125,32,199,86,26,222,82,181,167,9,2,182,176,174,114,64,26,65,40,31,27,156,141,2,224,40,33,7,107,58,207,167,126,35,210,242,63,159,53,8,53,158,102,195,251,16,223,186,18,212, -161,30,140,0,228,165,8,248,208,236,128,126,115,171,3,176,89,80,250,140,191,35,13,165,126,152,237,159,255,72,209,55,12,111,195,33,186,153,93,145,116,228,1,208,78,182,165,237,254,153,217,216,22,56,235,4,0,173,182,43,235,12,204,212,53,252,71,147,160,210, -93,15,94,34,2,140,146,216,104,78,9,9,146,205,145,0,34,2,126,125,173,233,203,1,88,29,96,230,169,250,80,147,31,204,246,71,82,189,31,249,228,108,0,77,51,126,47,54,5,186,200,118,82,183,75,138,172,65,160,218,213,233,41,115,134,80,0,124,6,174,34,187,35,88, -235,30,175,103,253,95,85,21,168,247,25,159,192,168,201,113,136,111,91,137,221,255,242,94,4,96,117,64,214,123,254,92,122,154,252,96,182,127,161,64,71,4,239,99,185,0,70,105,244,117,130,77,176,147,39,71,106,142,33,237,7,96,243,88,2,165,109,190,172,235,7, -144,117,2,192,95,237,106,177,123,45,149,122,218,255,210,233,127,180,117,163,81,228,125,155,65,233,217,9,28,78,255,203,127,15,33,93,34,192,141,34,192,176,241,199,108,127,196,248,29,78,188,246,4,200,177,119,12,111,169,220,89,3,65,123,9,168,154,172,103, -55,104,100,123,42,10,128,207,58,200,221,129,137,188,149,231,83,85,89,116,253,159,134,254,171,220,141,134,247,33,177,229,109,208,226,216,253,175,112,68,128,43,45,163,132,89,137,32,206,14,200,82,227,143,158,127,225,220,224,2,72,38,36,2,90,137,247,95,229, -110,208,53,30,88,149,53,218,220,14,5,192,103,17,110,242,77,213,145,104,201,198,255,150,187,106,193,99,245,27,222,135,248,230,183,200,145,193,218,255,194,225,195,109,131,175,51,53,49,240,112,199,64,172,14,64,227,143,100,200,254,115,22,80,164,205,160,41, -135,12,111,139,206,5,80,117,132,167,217,120,224,122,79,151,51,104,115,100,211,177,201,42,43,103,177,139,92,168,201,51,94,79,2,160,162,42,80,235,29,99,220,20,196,134,216,0,32,14,215,255,11,87,4,252,218,236,234,0,28,37,156,138,241,119,164,171,189,47,26, -255,2,69,0,85,233,5,57,177,209,240,150,106,189,173,96,101,182,33,245,126,0,14,175,165,50,80,237,106,66,1,240,41,120,203,29,101,158,98,123,147,166,163,254,95,224,4,54,0,200,40,210,222,141,172,7,0,8,88,254,87,152,34,32,141,213,1,152,19,240,111,14,61,102, -251,35,233,188,190,20,144,227,171,12,111,166,204,85,3,94,107,81,234,253,0,136,73,19,108,60,95,222,21,28,139,2,224,83,40,170,247,180,91,156,162,59,213,17,192,52,36,227,180,120,160,210,221,96,120,31,18,219,87,145,103,81,28,31,20,5,12,38,6,102,192,243,199, -108,127,36,173,55,181,192,202,1,141,226,18,61,80,230,172,214,151,7,160,2,132,154,188,89,213,17,48,171,4,64,184,217,59,78,207,61,170,104,50,132,236,165,172,83,147,25,2,0,123,255,35,40,2,70,209,248,167,189,189,47,102,251,23,252,253,204,242,0,182,129,166, -244,26,222,86,181,167,153,37,157,167,126,169,107,16,172,115,143,203,166,193,64,89,101,233,66,141,222,241,122,194,255,84,0,84,184,235,89,27,96,35,104,137,40,200,123,55,0,135,227,127,17,72,115,117,192,71,6,8,21,168,113,74,99,123,95,76,248,67,62,138,64, -140,127,31,75,6,52,74,173,183,133,216,154,212,77,167,42,171,224,45,177,183,184,195,14,127,182,28,149,172,17,0,22,135,40,4,170,93,109,84,37,165,108,184,53,13,106,60,198,115,43,228,131,219,65,233,223,79,142,10,214,255,35,236,202,250,88,117,128,217,29,3, -15,207,14,136,20,174,241,239,68,227,143,140,210,221,172,73,32,199,215,26,222,78,185,171,14,28,162,139,141,158,79,233,253,85,13,172,94,107,40,80,227,170,71,1,240,49,124,229,206,18,87,216,86,167,103,0,144,69,176,66,149,219,184,0,144,118,175,99,81,0,172, -255,71,254,85,4,208,196,64,115,69,64,193,206,14,192,108,127,36,19,16,175,93,78,188,111,120,51,69,246,18,240,219,66,186,6,3,9,2,199,133,155,189,29,217,114,72,178,71,0,84,58,27,89,2,160,150,122,3,32,183,197,7,197,206,74,227,2,96,231,90,188,73,144,79,17, -1,174,15,68,0,86,7,24,56,148,152,237,143,100,200,254,131,8,138,180,149,214,122,27,218,142,133,183,66,169,179,26,20,29,137,128,212,190,249,43,93,89,211,18,56,107,4,64,176,222,221,206,235,240,188,169,10,11,218,74,192,99,49,186,172,162,177,250,127,12,255, -35,159,46,2,48,49,208,176,231,159,174,108,255,30,204,246,71,62,75,1,136,160,202,7,64,145,247,24,222,20,29,58,167,171,33,144,172,65,168,193,211,158,45,147,1,179,70,0,20,55,123,59,85,85,95,2,96,153,171,90,87,82,198,71,78,204,96,15,40,61,187,176,255,63, -242,239,159,33,163,32,2,242,178,109,112,186,179,253,7,48,219,31,249,236,24,128,166,69,64,73,24,79,4,76,38,157,235,75,4,244,148,58,26,109,30,139,13,5,192,225,157,16,121,240,150,58,199,168,74,234,138,138,134,84,104,82,134,81,104,2,160,58,220,135,45,128, -145,163,16,1,31,174,14,48,177,99,224,200,236,0,62,223,68,64,58,179,253,113,205,31,73,205,96,152,50,25,144,46,1,216,4,135,222,201,128,21,222,50,71,25,10,128,17,236,30,139,195,83,98,175,211,100,29,29,0,121,129,8,128,26,227,2,96,223,70,208,228,4,62,68,144, -163,185,141,63,36,2,174,53,183,58,32,223,102,7,28,78,248,75,87,169,31,174,249,35,41,221,96,66,50,15,192,32,65,91,49,120,172,129,148,251,1,208,20,55,209,46,216,189,229,206,172,168,4,200,10,1,224,173,112,148,217,188,150,178,84,59,0,210,50,12,187,224,132, -98,71,133,225,125,144,246,108,196,236,127,36,197,72,192,135,171,3,112,118,192,167,26,255,206,219,64,192,82,63,36,27,238,89,160,2,96,39,49,196,198,18,1,105,25,32,173,6,208,83,9,192,243,28,109,8,212,130,2,96,4,103,192,86,43,88,4,91,138,5,0,44,9,195,75, -84,24,45,201,48,44,0,14,108,33,71,3,251,255,35,122,34,1,233,153,29,224,202,229,196,192,116,103,251,163,241,71,116,70,0,52,181,7,52,249,128,225,77,81,199,83,85,83,23,0,212,209,45,170,243,160,0,56,76,81,189,167,81,79,86,36,157,0,24,176,21,179,181,24,67, -207,170,216,32,40,189,123,201,3,5,19,0,17,61,34,32,61,137,129,92,174,86,7,96,182,63,146,181,240,196,104,71,64,145,119,26,222,18,77,62,79,53,7,224,176,0,32,78,111,19,199,115,89,112,52,178,128,96,173,187,89,211,81,1,160,130,98,74,248,95,38,15,109,117,184, -23,35,0,136,126,99,141,213,1,31,24,255,195,29,254,48,219,31,201,74,205,174,176,185,0,198,35,0,149,108,10,109,202,142,43,109,9,92,225,168,177,56,50,63,114,54,43,4,128,43,100,111,72,181,1,16,59,143,228,223,148,152,208,0,72,57,180,19,59,0,34,38,136,128, -52,206,14,200,133,234,128,81,25,236,131,158,63,98,244,70,229,76,17,0,33,71,41,88,5,123,234,149,0,228,175,91,157,98,153,35,96,11,20,180,0,96,109,127,45,192,249,42,156,213,84,21,165,188,243,28,15,97,71,185,241,8,192,193,237,116,103,240,198,64,140,186,22, -31,21,1,38,38,6,102,125,117,0,14,246,65,114,6,1,84,121,183,225,173,248,172,69,224,178,120,82,175,4,160,165,128,110,209,239,10,217,202,51,125,36,50,27,1,208,232,51,131,115,139,54,190,44,213,165,20,170,186,44,188,13,130,246,18,227,2,224,192,118,244,254, -17,19,35,1,238,15,37,6,154,91,29,64,7,8,101,93,78,0,14,246,65,114,233,254,100,2,224,0,107,10,100,4,151,197,11,94,107,48,245,142,128,26,235,125,195,23,213,186,43,51,125,44,50,27,1,32,94,191,175,194,81,108,247,91,131,169,14,1,210,200,65,119,90,220,224, -183,21,25,222,15,165,119,23,174,255,35,105,136,4,172,79,246,9,232,51,121,128,80,54,37,6,166,115,205,31,179,253,145,180,40,0,158,120,225,253,160,201,61,6,133,4,7,1,91,56,229,8,0,251,183,196,225,180,121,44,181,5,31,1,160,107,33,60,207,165,220,22,81,37, -191,220,68,129,185,68,175,177,93,72,68,65,25,56,128,2,0,73,131,8,200,243,234,128,116,27,127,108,242,131,164,41,6,160,169,81,80,149,253,134,183,68,123,1,232,201,95,83,201,191,41,106,240,212,100,250,72,100,84,0,40,10,29,140,224,174,20,44,60,164,186,4,64, -235,47,233,26,140,72,30,64,134,158,97,195,189,236,197,113,40,0,144,52,60,106,142,68,2,242,108,128,208,168,100,251,163,241,71,210,36,0,52,25,20,217,248,253,88,100,47,213,85,10,72,255,137,205,37,86,23,180,0,160,203,238,54,183,69,215,58,8,141,0,208,240, -139,97,17,50,112,16,180,120,148,102,20,226,125,129,164,41,18,144,198,234,128,197,25,40,17,196,176,63,146,243,168,166,36,2,210,62,52,122,135,2,249,171,93,44,9,80,79,9,124,206,11,0,26,53,161,205,127,138,26,61,149,122,166,0,210,176,75,192,94,108,92,0,244, -239,3,77,193,25,0,72,186,69,128,59,61,213,1,174,207,168,14,208,49,178,244,35,110,202,199,189,27,244,252,145,188,8,2,240,196,8,27,95,2,240,219,67,44,10,173,165,158,197,78,19,1,75,129,214,193,21,106,4,96,228,64,232,238,228,19,48,161,5,48,243,200,84,21, -111,8,100,148,68,64,122,170,3,92,135,171,3,18,31,202,108,150,19,192,123,74,245,63,35,29,149,44,99,26,14,39,57,169,137,35,189,253,177,206,31,201,109,136,0,80,140,183,3,246,90,252,96,163,189,0,82,204,3,208,20,218,13,208,26,180,20,129,71,149,11,50,2,64, -199,34,90,193,95,229,42,81,83,238,1,160,129,192,139,44,7,192,120,4,96,63,150,0,34,163,40,2,210,83,29,192,141,84,7,136,101,29,201,72,0,121,137,85,19,193,218,113,162,238,109,10,254,54,176,212,158,149,20,0,242,48,112,86,31,246,246,71,242,35,0,64,132,173, -166,244,209,44,112,67,219,161,125,0,232,96,32,58,152,46,85,251,39,216,120,15,103,129,160,158,36,66,179,200,92,243,123,141,206,101,224,4,209,46,132,116,68,79,64,224,68,86,131,105,120,55,162,3,248,208,65,70,89,4,124,80,29,16,188,224,251,196,208,150,154, -178,101,90,29,224,58,246,235,32,239,89,197,68,173,88,218,65,110,20,35,17,70,14,108,77,151,131,165,100,30,168,177,125,32,248,218,200,190,135,76,61,26,81,204,246,71,50,36,1,52,45,78,94,18,185,85,172,186,183,66,167,209,58,69,15,244,196,14,64,170,227,108, -104,245,27,141,2,104,25,12,64,103,46,2,160,106,96,247,138,46,139,67,8,164,60,6,152,40,38,171,96,99,101,128,8,146,147,143,159,52,149,8,82,131,47,86,142,7,177,98,156,65,227,255,161,135,132,183,5,196,226,217,166,27,127,26,246,143,162,241,71,114,24,158,19, -192,101,241,233,106,7,44,88,5,26,1,47,214,148,2,92,2,160,141,127,220,97,187,207,225,183,186,83,22,0,228,151,93,112,128,67,116,26,127,16,59,168,136,192,28,0,36,19,34,32,61,213,1,185,0,174,249,35,153,69,35,158,191,205,144,247,127,24,15,17,0,122,154,1,81, -205,160,72,106,56,147,71,33,179,125,0,36,213,71,140,127,202,86,156,118,1,164,161,23,155,224,50,188,15,98,168,10,64,195,219,1,201,208,67,40,77,213,1,104,252,17,228,223,221,121,10,240,98,152,141,173,54,44,0,172,126,0,157,189,0,124,101,142,112,38,199,2, -103,116,9,192,87,238,244,11,34,207,167,126,220,52,112,90,60,134,155,0,81,44,21,173,228,26,176,3,170,0,36,179,34,192,252,234,128,172,52,254,152,240,135,100,197,109,167,128,96,29,99,202,166,220,116,9,64,143,253,39,255,200,87,225,12,101,242,54,200,168,0, -240,148,56,130,188,133,75,249,224,209,225,11,14,209,109,202,113,179,150,183,128,24,174,1,144,37,188,41,144,12,138,128,244,84,7,100,157,241,199,53,127,36,27,238,55,222,10,22,199,20,147,4,128,254,92,52,69,82,139,50,233,123,102,122,9,32,160,47,114,162,130, -139,8,0,83,16,173,224,24,187,24,52,41,142,247,5,146,97,17,144,166,196,192,44,0,179,253,145,172,185,211,180,56,121,236,183,129,104,51,39,2,224,20,189,186,186,1,82,39,216,225,183,6,5,107,230,204,112,70,5,128,213,37,250,117,31,116,139,199,180,253,112,78, -58,9,132,162,10,162,72,18,120,119,32,25,37,31,69,0,245,252,49,219,31,201,22,161,77,95,118,223,25,228,171,57,243,95,92,22,247,136,0,72,205,155,165,137,240,222,114,151,215,234,204,220,28,154,140,9,0,154,248,16,106,242,250,245,212,64,210,181,19,167,224, -54,239,32,184,2,224,57,230,50,208,164,4,96,46,0,146,121,17,144,63,213,1,216,222,23,201,42,243,175,14,131,213,57,15,44,142,153,166,109,147,46,71,211,114,64,77,215,254,104,30,173,80,151,0,8,58,23,79,136,130,51,161,4,240,35,81,128,137,39,130,115,242,201, -160,70,7,241,46,65,50,238,165,164,107,138,224,104,126,134,40,102,251,35,217,35,171,137,227,24,5,193,82,7,174,224,85,166,110,153,182,2,166,141,233,244,56,143,196,248,187,105,83,192,66,21,0,250,226,248,28,199,218,47,154,141,111,217,151,193,209,185,16,212, -200,0,128,134,145,0,36,11,34,1,187,214,65,239,131,183,130,150,136,230,212,190,71,251,239,39,175,223,161,241,71,178,198,243,23,196,82,112,23,255,39,112,66,145,169,219,166,77,233,216,64,160,84,59,218,146,191,111,113,8,46,171,83,176,102,234,184,100,78,0, -104,201,240,135,190,157,230,137,234,114,154,190,75,156,197,6,129,179,190,14,174,105,167,177,161,42,154,140,57,1,72,134,35,1,118,55,36,182,188,5,137,109,239,228,208,110,199,32,49,244,4,209,233,14,52,254,72,134,81,137,157,25,4,209,214,66,140,255,221,44, -2,96,54,22,142,8,0,78,76,189,27,160,162,129,171,200,106,245,20,59,108,5,39,0,44,78,1,188,101,14,151,170,163,13,34,71,123,148,11,233,57,102,84,4,248,79,253,26,4,206,184,19,196,64,25,121,150,13,38,43,4,52,236,22,136,100,44,22,192,198,151,230,142,108,249, -215,239,16,100,116,189,75,137,60,178,135,128,142,187,113,248,206,5,79,201,61,196,248,215,164,199,150,17,91,36,232,236,73,67,103,226,105,154,102,207,212,145,202,216,48,32,209,198,131,51,96,179,15,12,105,41,202,16,218,194,145,7,171,144,222,99,230,24,127, -44,216,90,103,66,244,237,199,33,250,206,147,32,237,221,4,90,124,56,25,183,97,211,3,209,179,65,70,225,81,38,199,193,222,50,29,172,53,221,185,35,87,56,59,216,220,75,33,210,251,19,250,1,112,218,38,50,74,70,95,27,185,254,172,192,139,101,196,201,156,70,174, -195,99,211,226,245,127,196,150,113,22,22,1,208,41,120,173,35,175,194,18,0,90,114,9,192,161,239,1,195,129,133,79,127,212,132,119,120,193,53,253,76,112,77,59,3,228,125,155,32,177,123,29,200,251,183,130,58,116,136,60,215,254,63,123,231,1,47,71,89,245,255, -179,51,179,237,246,126,211,147,155,222,72,2,161,6,233,72,145,162,2,214,191,149,87,254,250,250,250,170,20,11,254,241,125,21,21,21,20,17,20,72,40,210,91,66,73,40,161,164,87,82,110,239,189,238,189,119,123,239,51,187,255,231,121,54,137,160,160,185,179,51, -91,207,55,159,225,134,36,187,59,59,237,252,206,121,78,17,81,3,32,234,18,139,129,80,49,19,10,63,241,229,99,221,42,179,7,67,233,87,217,90,171,24,106,252,123,20,3,65,212,50,254,196,139,212,240,37,204,240,11,186,69,192,147,45,177,4,165,62,188,134,7,45,175, -99,213,105,50,46,115,33,47,5,192,241,99,39,231,84,211,37,0,65,163,77,221,94,178,209,170,11,217,134,32,200,73,221,52,196,251,186,138,109,8,146,211,87,58,177,15,84,4,36,97,131,243,48,9,48,241,217,178,82,249,105,205,165,192,9,120,229,33,8,130,32,105,37, -97,143,244,172,67,173,28,39,56,30,139,167,205,152,165,59,179,72,70,92,48,206,170,0,18,107,46,8,130,32,8,146,165,226,129,215,128,177,52,125,189,128,185,108,61,112,113,204,48,70,16,4,65,210,238,197,106,64,199,233,166,94,6,24,143,131,96,224,161,108,78,81, -81,186,246,61,157,2,128,186,240,83,95,2,160,69,3,26,14,120,92,2,64,16,4,65,50,65,4,208,50,93,89,189,128,19,67,129,242,81,0,208,240,191,172,36,64,186,230,194,167,50,9,16,65,16,4,65,114,140,116,47,1,196,211,242,82,4,65,16,4,65,1,128,32,8,130,32,8,10,0, -4,65,16,4,65,80,0,100,34,52,219,50,142,189,249,17,4,65,16,36,43,5,128,72,182,192,84,95,68,219,138,75,49,17,162,49,156,212,135,32,8,130,100,49,26,214,11,32,109,125,178,211,41,0,104,22,159,132,87,0,130,32,8,146,173,208,136,116,68,10,179,150,192,83,118, -102,163,49,240,89,67,193,124,20,0,199,244,143,188,3,142,141,128,16,4,65,144,76,17,1,114,204,159,20,142,129,103,60,16,206,215,8,128,95,214,65,139,139,16,149,162,120,213,33,8,130,32,233,53,254,241,56,196,226,146,60,127,86,3,113,13,159,190,73,153,233,108, -167,151,212,18,128,20,79,253,234,129,100,182,129,52,97,134,152,211,13,241,96,16,175,124,68,237,39,11,8,179,103,130,118,213,178,172,220,125,79,32,2,102,103,128,60,28,227,56,12,24,81,213,144,240,28,7,6,29,15,69,6,45,20,23,232,200,255,167,238,138,163,198, -95,140,69,88,75,96,25,80,79,54,148,127,2,64,195,198,40,6,101,188,140,28,240,24,68,98,169,49,192,226,192,8,132,182,237,133,240,251,13,32,142,154,32,230,245,147,83,134,209,7,36,53,2,0,200,131,173,232,107,55,64,241,247,255,35,171,118,125,216,236,133,109, -77,228,222,137,72,104,252,145,212,152,20,141,6,116,2,7,133,70,45,76,47,47,132,5,51,74,97,86,149,250,109,246,99,228,151,24,139,78,57,7,224,184,95,9,137,132,248,252,18,0,113,49,14,209,144,20,158,250,49,211,176,7,163,218,85,0,212,211,247,61,250,60,4,223, -219,3,113,143,15,200,149,5,26,65,75,54,30,64,139,115,8,144,20,33,73,224,123,246,85,48,92,118,1,104,151,46,204,138,93,142,197,226,112,184,103,18,194,196,248,211,7,50,130,164,236,118,33,215,158,203,23,6,187,39,4,29,163,14,152,81,81,8,107,23,214,192,172, -234,34,21,63,83,100,2,64,38,212,144,165,45,7,32,109,150,44,236,19,193,49,236,11,112,117,220,148,23,2,168,226,138,72,234,69,77,168,199,239,249,195,195,32,77,90,65,83,104,4,77,113,33,222,89,72,122,224,137,224,12,133,137,32,181,100,141,0,16,165,24,4,194, -98,74,195,176,8,146,136,2,144,91,134,252,231,248,181,103,178,251,96,194,225,135,85,117,85,112,246,178,105,192,169,80,113,71,157,81,49,46,130,156,28,0,13,167,9,211,45,93,199,43,221,242,220,39,43,122,64,4,64,72,82,103,9,192,255,236,43,224,188,253,183,32, -57,221,9,195,207,161,7,131,164,143,120,56,2,124,117,37,232,86,44,206,154,125,214,106,121,168,45,43,128,168,132,205,186,144,52,95,139,60,199,140,126,67,159,5,222,173,31,97,226,84,121,1,16,78,44,1,76,81,0,16,195,15,33,79,52,18,116,69,210,150,3,144,110, -235,230,145,245,80,140,199,33,44,6,20,223,153,192,150,119,192,243,199,13,160,209,10,160,209,225,180,65,36,205,198,63,74,30,42,122,29,148,222,241,67,224,106,170,178,199,11,35,219,39,86,204,128,26,42,2,68,20,1,72,250,163,2,122,34,74,251,198,93,176,179, -121,140,165,214,40,9,141,70,211,101,128,169,6,23,232,4,225,16,49,254,1,71,56,109,93,237,210,42,0,56,94,227,145,121,74,33,40,249,21,221,151,104,103,47,120,239,121,152,60,112,181,137,176,43,130,164,19,106,252,181,90,40,191,235,167,160,63,239,204,172,219, -253,34,163,22,62,117,198,60,168,42,53,160,8,64,50,2,42,2,186,199,156,208,216,111,85,244,125,195,82,24,196,120,20,100,46,1,120,201,150,182,36,192,244,9,0,162,194,156,35,126,183,220,37,153,128,168,160,0,16,37,240,222,187,1,98,129,32,128,128,9,126,72,250, -141,63,156,48,254,103,101,237,215,72,136,128,58,34,2,140,40,2,144,140,64,43,240,208,208,107,6,135,87,185,168,123,136,56,163,180,44,93,142,41,99,2,64,147,190,174,118,105,19,0,52,140,239,183,132,220,178,122,39,144,35,22,136,122,149,59,129,59,247,67,184, -190,5,52,5,70,188,67,144,12,242,252,207,202,250,175,243,247,72,128,17,115,2,144,180,67,115,3,195,68,140,54,244,41,23,5,8,136,190,99,195,233,166,158,3,16,116,134,189,98,36,125,247,69,122,151,0,180,156,67,206,235,104,178,5,61,232,10,41,17,8,188,178,21, -147,253,144,140,241,252,203,114,196,248,255,147,8,40,193,72,0,146,1,81,0,158,131,97,139,135,53,170,82,2,191,232,133,152,140,158,118,28,175,1,207,68,192,25,13,164,111,36,78,218,172,30,245,226,195,222,168,51,30,139,203,120,45,167,152,0,144,70,199,33,218, -209,195,146,173,16,36,221,198,191,60,199,140,255,71,70,2,80,4,32,105,132,46,59,135,194,34,17,1,202,68,145,253,17,183,236,196,66,34,2,236,233,236,148,149,62,1,64,212,143,125,208,227,20,35,177,248,84,243,0,56,22,1,240,42,210,14,56,210,218,5,49,175,15,35, -0,72,218,136,231,184,241,71,17,128,100,158,8,208,192,132,93,25,39,210,23,245,200,126,173,20,141,217,210,121,28,210,92,5,192,121,104,32,64,78,4,32,40,250,33,162,64,47,0,113,104,4,20,175,11,65,144,41,120,254,154,60,48,254,255,44,2,176,58,0,73,163,237,225, -52,224,14,68,88,46,90,178,120,163,46,89,109,128,105,14,128,185,203,99,139,75,233,179,63,233,139,0,112,108,9,192,21,9,74,126,205,20,59,134,209,28,128,48,49,254,74,84,2,196,236,46,244,254,145,180,25,127,200,35,227,255,97,17,128,213,1,72,26,35,0,100,139, -68,37,69,18,83,189,17,34,0,228,152,210,132,217,179,228,101,4,128,38,64,120,205,33,111,208,21,117,77,89,0,104,184,99,2,32,249,16,78,92,20,241,110,64,114,202,248,139,225,40,217,148,187,174,105,154,142,39,172,236,125,130,213,1,72,46,64,35,8,190,168,27,56, -205,212,77,105,140,136,95,191,61,108,213,164,209,255,76,107,209,187,134,215,68,136,16,160,107,32,11,166,42,156,162,49,145,40,47,103,242,66,196,104,196,37,0,36,103,140,127,203,198,195,208,183,179,147,37,58,45,184,112,25,156,114,253,25,160,73,162,39,255, -246,126,59,220,187,119,16,108,129,8,172,153,94,2,191,252,228,34,152,86,164,87,84,4,188,117,100,8,108,238,32,104,113,112,16,146,74,39,148,220,36,154,36,103,3,68,98,33,86,5,48,85,1,64,63,86,138,198,36,247,88,192,78,243,225,242,46,2,64,31,74,17,111,20,220, -99,126,171,70,152,234,1,208,128,20,23,193,29,177,39,127,0,170,42,80,0,32,105,48,254,183,43,110,252,143,252,109,15,52,60,115,0,2,54,47,248,173,94,168,127,106,31,244,19,49,32,151,17,87,8,126,248,122,39,52,79,122,193,30,136,194,150,78,11,124,125,99,11,140, -123,148,155,93,130,37,130,72,58,160,81,45,189,78,96,37,129,201,224,143,122,89,62,154,70,70,42,127,60,30,247,145,87,57,210,121,28,210,42,185,165,72,12,162,1,113,92,142,10,163,161,23,103,56,249,4,74,126,90,53,128,6,167,150,33,234,243,225,108,127,101,219, -251,82,227,223,190,185,1,116,133,122,224,180,252,137,109,162,117,84,246,123,54,78,120,192,17,140,64,145,142,7,129,8,246,50,131,0,237,102,31,124,115,19,17,1,94,133,69,192,153,243,160,18,115,2,144,84,221,139,228,87,161,33,249,0,56,173,0,8,75,1,182,44,61, -37,195,43,112,224,183,69,92,17,43,184,120,109,250,204,112,26,251,0,80,21,22,7,247,120,208,36,43,131,146,188,198,25,74,62,127,130,9,0,173,0,128,65,0,68,101,207,95,173,108,255,19,198,191,64,247,225,102,100,52,196,153,68,145,177,72,220,164,15,142,79,165, -183,8,21,3,237,22,34,2,88,36,64,185,118,170,84,4,92,133,213,1,72,170,4,0,177,61,244,154,75,22,26,133,142,178,73,128,50,246,33,22,55,199,99,16,74,231,113,72,107,4,128,118,79,244,219,66,163,26,89,9,148,156,34,17,0,174,186,10,52,6,67,98,103,16,68,37,227, -15,170,25,255,189,208,190,165,145,24,127,253,71,71,178,146,8,110,125,220,75,139,143,139,128,151,91,85,88,14,192,234,0,36,37,46,40,148,24,147,111,254,230,12,91,217,36,192,169,222,104,52,2,224,26,241,79,178,61,225,242,48,7,32,241,197,1,2,206,200,104,76, -70,29,36,77,186,112,19,1,16,135,228,30,20,92,69,25,112,37,197,137,69,33,4,201,42,227,191,7,58,182,212,131,206,168,131,84,118,19,139,31,19,1,29,116,57,224,101,117,114,2,42,177,58,0,81,211,246,144,251,165,184,32,121,1,96,15,77,202,86,215,209,160,56,146, -238,227,144,222,70,64,180,25,131,41,48,17,151,98,83,30,165,68,5,128,39,234,2,127,52,185,82,64,174,184,16,248,170,114,136,75,18,222,21,72,118,121,254,155,27,64,107,212,67,58,90,137,158,88,14,80,73,4,92,133,137,129,136,138,215,46,77,254,43,86,32,2,96,15, -78,202,170,36,160,182,207,214,231,25,206,107,1,192,166,33,185,162,230,72,64,154,242,88,96,142,205,3,240,130,55,154,100,41,32,249,96,126,122,45,0,10,0,68,201,135,140,202,158,127,59,245,252,11,210,99,252,255,49,18,208,174,98,36,0,151,3,16,197,175,219,120, -28,116,90,94,145,36,64,71,216,2,188,134,151,245,218,136,95,204,115,1,192,107,32,64,51,33,253,162,121,234,221,0,57,136,72,97,112,40,145,8,56,107,58,46,1,32,138,26,127,213,19,254,140,233,53,254,31,41,2,212,168,14,56,3,171,3,16,165,5,0,16,227,175,5,189, -54,57,1,16,146,130,224,14,219,137,51,58,69,1,64,123,0,144,235,217,214,239,195,37,0,144,64,244,140,7,70,57,25,77,64,196,88,20,108,193,137,164,247,67,152,59,43,35,30,166,72,14,144,142,108,255,12,16,1,234,87,7,160,8,64,148,33,70,156,189,18,114,15,37,91, -253,237,137,56,192,39,122,100,53,1,138,134,36,127,192,25,49,229,181,0,96,15,49,242,244,8,58,35,253,114,219,33,154,131,163,73,239,134,48,103,102,98,28,48,54,4,66,146,52,254,106,133,253,143,50,227,255,47,178,253,51,0,117,171,3,80,4,32,202,9,214,178,194, -228,187,89,58,66,102,8,139,129,41,155,209,99,77,240,38,189,230,160,53,191,5,192,49,236,131,222,62,78,198,64,30,26,122,177,4,146,23,81,252,244,26,208,176,74,0,124,184,32,153,103,252,19,165,126,153,231,249,127,212,131,245,131,213,1,38,172,14,64,50,16,122, -11,149,43,208,206,218,18,52,177,40,244,84,111,73,54,7,199,18,26,147,194,82,56,221,199,34,35,4,0,57,24,189,114,198,50,210,228,11,90,134,65,79,66,82,7,161,162,12,248,218,106,172,4,64,50,208,248,239,73,107,182,191,28,17,112,188,58,224,70,172,14,64,50,16, -129,231,160,76,1,1,48,225,31,145,213,63,142,230,190,5,29,145,62,41,154,254,107,56,35,4,128,115,216,55,40,137,177,41,91,95,26,1,112,71,28,224,73,182,18,128,227,216,50,0,136,40,0,144,12,51,254,172,201,143,46,171,114,84,254,185,58,64,217,156,0,92,14,64, -228,66,187,207,26,245,2,203,1,72,22,186,252,204,201,168,0,160,209,110,251,160,183,59,19,142,71,70,8,0,183,41,48,22,241,68,237,220,20,167,34,209,54,165,129,168,79,153,68,192,5,115,177,18,0,153,154,161,75,129,231,159,234,38,63,170,136,128,77,152,19,128, -100,136,0,136,209,6,64,180,2,128,79,234,125,162,177,8,235,1,32,167,4,144,205,177,25,241,161,0,56,78,200,29,117,251,109,225,145,169,143,69,212,64,52,30,129,201,64,242,213,20,218,69,117,0,60,143,119,8,114,210,158,127,190,101,251,203,17,1,39,170,3,54,97, -159,0,36,51,34,0,229,133,134,228,157,214,136,29,220,97,135,172,8,0,29,3,236,26,245,247,163,0,56,134,24,150,226,30,115,176,139,147,49,23,89,67,158,50,227,190,193,228,35,0,117,179,129,43,41,196,68,64,228,164,140,191,250,97,127,125,206,76,169,252,123,117, -0,77,12,84,97,57,160,196,8,17,20,1,200,73,66,69,99,178,152,3,99,16,148,124,83,46,1,164,54,46,236,137,90,220,166,224,72,38,28,11,46,83,78,138,99,200,215,206,201,152,205,204,113,2,140,7,146,111,168,68,147,0,89,34,32,230,1,32,105,52,254,29,91,178,55,236, -255,175,34,1,199,171,3,110,84,163,68,240,204,99,145,0,172,14,64,254,157,163,71,12,112,101,73,242,17,0,147,127,16,68,54,4,104,138,14,43,249,124,191,53,52,24,242,68,188,40,0,62,44,0,218,228,172,192,211,53,24,107,112,28,130,162,63,201,43,67,0,97,254,28, -0,81,196,187,4,73,143,231,191,185,49,107,178,253,229,136,128,34,21,19,3,177,58,0,249,119,176,4,64,157,160,72,5,128,201,55,32,111,6,0,113,114,61,230,96,135,20,201,140,235,52,99,4,128,173,215,219,45,6,197,232,212,135,2,241,224,9,59,192,26,26,79,122,31, -180,203,22,225,18,0,146,30,227,191,37,251,215,252,79,54,18,144,16,1,152,24,136,164,88,0,196,226,204,248,27,146,76,0,164,19,104,39,252,195,196,249,156,122,43,97,186,4,96,237,245,182,100,202,49,201,24,1,224,53,7,71,195,62,113,108,234,51,1,52,16,142,133, -136,34,75,62,15,128,9,0,157,22,59,2,34,31,190,225,213,14,251,103,80,111,255,212,138,0,117,102,7,160,8,64,62,46,2,160,196,250,191,43,108,7,91,72,94,5,0,221,7,107,143,7,5,192,63,18,116,134,67,158,137,96,23,47,99,38,0,53,216,35,222,158,164,247,65,152,63, -23,248,138,114,0,92,75,68,62,224,249,171,157,237,175,205,113,207,255,163,68,192,137,229,128,141,88,29,128,164,6,26,178,175,45,43,72,250,125,104,213,153,63,234,158,114,5,0,253,252,168,79,244,57,6,189,189,40,0,254,217,134,131,99,192,219,200,9,114,102,43, -11,48,234,235,75,254,96,148,151,130,48,111,22,196,49,15,0,57,102,252,213,15,251,231,78,182,255,84,249,96,117,0,54,11,66,212,22,157,180,246,191,74,129,4,192,17,98,191,229,36,0,82,219,230,179,134,6,60,147,193,73,20,0,31,129,165,199,211,32,231,89,40,104, -4,54,19,192,27,117,37,189,15,218,21,75,48,17,16,73,81,182,191,62,175,167,80,126,120,118,128,90,57,1,6,172,14,64,78,76,0,84,162,3,224,144,167,123,202,229,127,9,1,192,129,115,196,223,34,134,50,231,130,204,40,1,96,235,243,180,73,209,184,140,68,64,14,60, -17,39,75,204,72,22,221,234,229,216,16,8,141,63,102,251,167,80,4,20,169,218,54,184,14,171,3,16,38,0,170,75,141,178,50,247,63,244,104,136,69,192,228,31,0,158,155,122,2,32,93,49,176,245,122,142,102,210,113,201,44,1,208,235,25,242,89,67,35,156,156,142,128, -228,196,12,121,186,146,143,0,44,89,192,150,2,48,15,0,141,63,118,248,75,109,36,0,171,3,16,53,175,177,233,21,133,73,191,143,53,104,2,71,200,34,171,2,128,238,4,141,114,163,0,248,24,66,222,104,216,61,30,104,230,4,57,163,129,57,24,244,116,38,127,64,106,170, -64,168,155,147,200,252,70,242,235,33,145,18,227,143,158,255,191,21,1,216,54,24,81,242,218,138,39,214,255,107,203,147,79,0,28,242,244,64,72,10,176,234,179,41,185,168,156,6,66,158,168,131,56,185,157,153,116,108,184,76,59,89,147,173,206,195,114,18,1,121, -78,11,163,190,126,8,75,201,135,16,217,50,0,118,4,204,59,207,31,123,251,167,95,4,224,236,0,68,105,104,233,93,89,161,30,74,11,146,111,0,52,224,105,151,103,104,137,77,243,76,4,59,137,131,107,67,1,240,47,176,244,184,15,201,25,178,76,107,50,29,97,139,34,131, -129,116,107,87,17,79,16,243,0,242,201,248,99,182,127,230,80,252,1,17,96,82,169,58,0,103,7,228,15,82,44,206,188,255,100,111,191,88,92,98,9,128,114,194,255,180,188,221,222,239,61,28,207,176,137,179,25,39,0,172,221,158,214,176,55,234,144,213,16,72,12,194, -160,167,35,233,125,160,13,129,248,234,74,140,2,160,241,79,138,163,152,237,47,59,18,192,170,3,44,42,205,14,32,34,160,26,171,3,242,6,106,248,103,86,21,37,111,155,130,19,96,9,154,100,37,0,82,75,107,106,178,31,200,180,99,147,113,2,192,109,10,216,93,99,129, -86,94,198,50,128,70,195,65,175,171,53,249,131,82,90,12,218,165,139,48,15,32,231,141,191,168,162,231,191,23,218,48,219,63,41,17,80,164,106,78,0,86,7,228,197,117,68,46,164,2,189,22,166,41,177,254,239,237,130,128,232,37,70,115,106,102,147,86,30,136,33,41, -108,238,112,215,163,0,248,55,196,164,56,76,182,59,15,242,50,66,240,2,167,37,39,169,27,194,82,48,233,253,208,159,185,6,64,194,8,64,110,123,254,130,138,107,254,245,184,230,175,80,36,224,239,205,130,48,39,0,153,26,82,44,198,162,61,5,122,33,233,247,234,113, -53,201,139,64,208,9,128,246,112,55,113,110,71,50,237,248,112,153,120,210,198,155,156,123,227,50,18,1,88,30,64,208,204,234,52,147,69,119,250,42,208,20,21,210,133,31,188,139,114,205,176,164,160,206,31,179,253,21,22,1,102,20,1,136,12,135,50,30,135,153,149, -201,135,255,197,184,8,3,238,78,214,116,110,202,118,73,203,209,254,255,7,195,190,104,198,121,148,25,41,0,204,29,174,6,114,176,60,156,140,60,128,72,44,76,148,90,115,210,251,32,204,155,147,40,7,20,113,25,32,215,60,127,13,78,245,67,17,128,34,32,47,208,242, -60,204,170,78,94,0,76,250,135,143,173,255,107,167,110,100,121,13,140,55,59,118,103,226,241,201,72,1,224,158,8,76,186,70,3,205,156,118,234,187,71,163,0,93,206,166,228,119,130,231,64,127,198,106,128,8,10,128,92,50,254,170,103,251,227,154,191,250,34,96, -147,122,179,3,176,58,32,119,160,217,255,229,197,122,168,40,78,190,255,127,143,171,5,66,162,140,250,127,242,207,165,168,20,158,104,113,30,70,1,112,146,196,196,56,152,219,93,187,228,8,0,129,245,3,232,3,79,196,145,244,126,232,215,157,14,26,28,15,140,198, -255,36,140,63,102,251,167,78,4,116,88,212,235,24,136,213,1,185,37,0,102,85,21,1,167,64,249,109,151,179,65,118,255,127,151,41,208,97,235,247,14,102,226,49,226,50,245,228,153,154,29,187,228,24,94,58,162,209,19,118,64,159,187,61,233,125,160,131,129,248, -217,51,176,28,48,235,141,191,186,217,254,108,164,47,26,255,148,137,128,34,85,151,3,176,58,32,87,224,57,13,204,169,41,73,250,125,124,81,15,171,255,23,184,169,15,18,226,117,28,76,182,185,246,68,252,153,121,65,101,172,0,152,108,119,53,132,188,81,139,12, -209,5,177,120,12,58,28,71,146,222,7,141,65,15,186,211,87,67,60,18,193,187,41,171,61,127,181,179,253,209,248,167,35,18,160,110,78,128,1,69,64,150,123,255,37,133,58,168,45,51,38,253,94,180,251,159,51,108,101,203,203,83,182,33,26,13,76,180,56,183,103,234, -113,202,88,1,224,30,243,187,108,189,222,131,188,110,234,7,93,203,235,216,154,13,29,16,148,44,6,98,52,52,56,29,48,59,13,5,102,251,231,135,8,80,171,79,0,38,6,102,181,0,152,85,89,4,2,159,188,137,107,183,31,97,93,0,167,108,252,201,71,135,60,17,215,200,17, -219,33,20,0,83,189,193,201,29,62,214,96,223,198,203,24,12,68,75,53,44,193,49,24,246,246,36,189,31,186,83,87,2,63,115,90,34,140,140,100,149,231,143,189,253,243,68,4,96,159,0,228,31,13,27,241,188,235,166,37,31,254,23,227,81,232,118,53,129,86,78,248,95, -203,129,99,200,127,196,51,17,176,160,0,144,193,200,17,235,118,73,140,201,176,188,26,136,74,17,162,220,146,79,188,212,20,24,65,119,230,169,184,12,144,101,198,31,167,250,229,107,36,0,171,3,242,157,24,241,254,75,11,117,48,77,129,241,191,35,222,94,48,7,70, -101,181,255,165,205,236,70,143,218,222,165,73,237,40,0,100,96,237,246,116,187,77,254,118,94,86,53,128,0,29,206,163,44,31,32,89,140,151,156,75,206,38,143,213,0,104,252,19,217,254,104,252,51,82,4,168,94,29,128,34,32,43,16,137,0,152,83,83,12,90,5,194,255, -109,246,67,16,145,194,83,46,255,163,72,209,88,140,8,128,247,50,58,82,146,201,59,71,51,39,205,157,238,247,104,38,229,212,5,128,14,198,124,3,48,238,79,190,250,66,187,122,5,8,115,103,65,92,196,101,128,204,54,254,152,237,159,207,34,224,131,213,1,38,204,9, -200,91,104,246,255,252,105,165,201,71,18,136,243,216,102,63,194,156,201,41,27,86,65,3,126,107,168,139,216,175,246,76,62,86,92,166,159,204,129,61,150,183,228,60,113,169,98,163,141,27,218,28,10,44,3,24,244,96,56,239,76,128,48,46,3,100,182,231,47,168,104, -252,49,219,63,91,34,1,84,4,220,168,70,78,192,153,88,29,144,233,208,228,63,218,248,71,137,225,63,212,121,164,109,229,229,148,255,9,122,158,150,178,191,23,246,102,118,242,88,198,11,128,209,35,182,195,62,75,112,140,182,83,156,186,18,20,160,197,118,16,228, -204,21,248,71,12,151,158,71,132,128,1,151,1,50,214,248,171,24,246,199,53,255,172,20,1,44,39,192,171,160,8,48,96,36,32,27,4,0,77,254,155,106,27,249,143,162,197,126,80,86,247,191,227,23,98,223,174,201,55,50,253,120,101,188,0,8,56,195,126,91,159,119,155, -156,101,0,154,185,73,147,56,38,252,67,73,239,135,118,217,34,208,46,93,136,201,128,121,102,252,105,123,95,45,102,251,103,167,8,176,168,85,34,136,213,1,153,122,222,117,2,7,11,166,39,31,254,143,199,99,204,121,148,19,254,215,16,241,17,116,69,76,227,205,206, -247,81,0,40,192,224,126,203,102,186,166,50,229,19,65,126,5,69,63,52,89,247,43,112,164,56,22,5,192,114,192,204,50,254,170,151,250,225,154,127,86,139,128,14,172,14,200,31,239,95,138,65,109,121,161,34,189,255,71,125,253,196,121,236,147,25,254,231,192,220, -233,222,230,183,133,124,40,0,20,17,0,230,93,33,119,212,170,145,17,214,161,179,1,154,108,7,20,169,6,48,92,114,46,112,21,101,52,206,132,119,91,134,120,254,101,152,237,143,252,11,17,80,132,213,1,121,3,157,220,190,104,102,169,34,239,213,100,219,7,97,41,40, -43,252,79,157,213,254,61,147,175,102,195,49,203,10,1,224,54,5,92,147,237,174,93,130,78,222,112,160,49,95,31,81,115,201,55,5,226,167,213,128,254,172,211,32,30,14,227,221,150,86,227,175,118,182,127,35,102,251,231,152,8,80,179,99,96,37,46,7,100,128,241, -143,67,49,57,31,117,181,201,11,0,218,122,166,153,56,141,90,25,163,127,19,225,255,168,109,232,128,117,15,10,0,5,25,216,107,222,164,209,202,91,6,8,75,33,168,183,42,51,142,217,120,213,37,180,205,20,222,113,105,245,252,213,206,246,199,53,255,92,19,1,106, -118,12,188,10,103,7,164,29,81,138,195,188,218,18,48,232,146,111,219,62,232,233,32,78,227,32,240,50,4,0,13,255,79,182,185,182,121,38,2,78,20,0,10,50,184,223,242,158,220,101,0,58,27,128,42,186,72,44,249,27,95,127,198,26,16,22,214,97,50,96,58,30,228,152, -237,143,36,43,2,84,157,29,128,34,32,93,8,196,46,44,153,85,174,204,179,192,178,19,196,88,68,86,248,95,147,8,255,191,152,45,199,45,107,4,128,219,20,112,154,219,93,239,81,133,53,229,139,67,163,133,73,255,8,116,59,155,146,223,17,157,22,10,46,191,16,32,18, -197,187,46,197,198,95,131,217,254,136,82,145,0,28,32,148,67,222,63,77,254,43,128,26,5,106,255,105,210,120,171,253,125,208,241,250,169,27,127,34,66,66,174,168,121,232,128,117,7,10,0,21,232,223,99,126,145,19,228,237,114,140,252,58,108,222,166,200,126,24, -174,184,16,184,138,114,76,6,76,21,152,237,143,40,44,2,58,44,88,29,144,43,208,228,191,165,179,43,20,185,125,105,235,95,107,112,28,120,205,212,203,255,104,243,159,201,118,215,155,158,137,128,7,5,128,10,244,237,152,216,225,179,4,77,114,74,2,117,156,30,218, -29,71,193,21,182,37,189,31,44,25,144,24,162,120,40,132,119,95,10,140,63,246,246,71,148,22,1,88,29,144,43,198,63,49,248,71,137,214,191,148,67,230,237,242,26,255,64,98,252,111,215,214,177,23,178,233,248,101,149,0,240,219,195,62,83,163,99,11,85,90,83,254, -162,26,30,220,97,59,52,40,148,156,89,240,153,203,65,163,211,98,103,64,85,141,191,168,242,84,63,204,246,207,119,17,160,110,78,0,46,7,168,13,77,254,91,52,163,12,116,218,228,77,25,157,250,215,195,70,255,78,61,252,79,157,82,175,37,52,48,120,192,178,23,5, -128,138,244,108,159,120,142,217,92,25,15,109,218,26,248,176,121,135,34,61,1,116,171,151,131,110,205,74,136,227,124,0,21,61,127,65,213,193,62,152,237,143,34,64,205,234,0,236,24,168,242,249,35,39,208,160,229,97,233,108,101,146,255,14,19,239,223,31,245, -16,103,81,70,158,25,237,253,95,111,127,37,228,142,102,85,88,56,235,4,192,208,1,235,251,238,49,127,27,47,99,25,128,182,6,30,242,116,65,191,187,45,249,29,209,104,160,224,186,79,97,30,128,26,55,182,218,237,125,49,219,31,249,71,17,96,70,17,144,117,62,2,121, -246,206,173,45,129,210,66,125,210,239,69,43,196,142,88,118,201,242,254,233,115,36,38,197,165,246,55,70,159,203,182,99,152,117,2,32,26,20,197,193,125,150,231,229,44,3,208,181,157,104,44,2,7,38,222,86,100,95,12,23,156,13,194,162,58,114,245,96,20,64,73, -227,175,118,182,63,122,254,200,199,138,0,156,29,144,53,208,177,191,43,231,85,42,242,94,237,246,35,108,102,140,32,163,246,159,215,114,224,26,241,31,153,104,85,162,204,12,5,192,191,165,115,235,216,139,98,36,22,210,200,120,136,235,121,3,52,219,15,42,146, -12,8,122,29,20,124,246,10,136,99,73,160,66,234,14,179,253,145,244,138,0,172,14,200,14,104,233,223,172,170,34,69,198,254,82,246,79,188,37,251,181,212,25,237,126,111,252,153,104,80,202,186,132,176,172,20,0,214,94,111,191,185,211,189,157,215,201,75,6,116, -133,237,44,219,83,9,140,159,186,24,248,89,211,201,21,137,67,130,146,53,254,152,237,143,164,91,4,124,184,58,64,121,17,128,213,1,202,157,171,149,243,170,20,121,47,147,127,16,186,156,141,160,227,167,62,68,136,58,161,17,191,232,238,223,51,185,41,27,143,99, -86,10,128,24,185,129,186,182,154,30,231,101,102,126,210,30,207,7,39,223,97,203,1,73,31,192,146,98,40,184,230,50,136,135,112,62,128,124,227,127,60,219,255,118,204,246,71,50,66,4,36,114,2,90,177,58,32,19,189,255,88,156,120,254,133,48,167,166,88,33,239, -127,43,107,0,36,167,252,79,48,240,96,106,118,188,110,237,246,152,81,0,164,144,222,29,19,111,251,172,161,33,142,151,151,12,104,242,13,176,166,15,74,64,151,1,184,234,74,58,143,18,239,78,89,158,255,241,108,255,51,85,48,254,184,230,143,76,93,4,96,78,64,6, -159,31,34,0,78,153,87,169,200,72,22,95,212,13,71,205,59,101,117,254,99,17,0,158,131,206,55,199,30,203,214,99,153,181,2,32,224,8,7,6,246,154,159,211,26,229,15,127,216,109,122,93,153,131,72,140,127,193,85,151,64,60,136,141,129,166,116,35,171,26,246,223, -139,189,253,145,228,69,192,241,156,0,47,138,128,76,241,254,171,201,113,91,48,93,153,198,63,180,244,207,30,154,148,213,249,143,23,56,112,143,249,91,6,247,89,246,161,0,72,3,29,111,142,61,41,69,99,97,57,15,120,186,222,211,237,106,132,65,79,167,50,81,128, -47,92,11,92,101,57,70,1,166,224,249,171,155,237,95,15,90,52,254,136,82,34,96,163,58,145,0,28,37,60,53,98,212,251,175,171,2,78,1,247,159,14,252,217,55,254,22,8,156,78,214,235,5,3,7,61,219,198,31,11,251,162,89,155,0,150,213,2,96,178,205,217,51,209,234, -122,71,118,73,160,20,134,93,166,205,138,236,11,109,15,92,112,245,39,49,10,144,9,198,31,179,253,17,133,69,64,199,137,102,65,202,38,6,94,133,213,1,39,141,68,140,127,85,137,1,22,206,80,198,251,111,182,29,132,17,95,31,91,18,158,178,253,32,2,36,236,19,157, -109,175,141,190,144,205,199,52,171,5,64,76,138,67,235,107,35,15,201,153,13,144,136,2,24,161,209,186,15,44,193,49,101,162,0,95,196,40,192,201,24,127,26,246,47,195,108,127,36,139,68,0,171,14,56,150,24,104,194,234,128,52,9,128,24,172,158,95,13,2,207,41, -112,78,227,204,249,147,219,247,95,107,224,97,228,176,109,163,107,204,111,65,1,144,70,6,246,154,183,123,198,131,109,188,140,41,129,180,229,163,63,234,38,23,194,22,229,162,0,215,94,134,81,128,143,53,254,216,219,31,201,110,17,64,19,3,111,196,234,128,148, -67,215,254,107,202,10,96,209,204,50,69,222,175,199,217,4,61,174,102,217,201,127,177,88,92,106,223,50,250,112,182,31,215,172,23,0,97,111,52,218,179,109,124,61,45,199,144,3,109,12,116,104,114,27,184,34,118,69,246,167,240,203,159,5,190,166,138,118,170,192, -187,246,159,60,127,65,229,246,190,152,237,143,168,43,2,212,175,14,192,72,192,71,30,123,34,0,214,16,239,159,231,148,185,193,183,143,189,2,82,92,146,87,250,167,231,193,214,231,221,53,116,208,210,136,2,32,3,104,122,105,232,217,160,59,98,145,83,18,200,105, -4,112,133,173,176,87,169,138,128,170,10,40,184,225,42,140,2,124,240,230,197,222,254,72,174,137,128,227,57,1,94,21,34,1,37,24,9,248,144,247,47,197,96,90,69,33,44,80,104,237,127,200,219,5,173,246,247,153,243,39,235,25,47,104,160,245,213,225,251,99,82,246, -79,130,205,9,1,224,157,12,58,135,14,88,158,148,27,5,160,21,1,251,38,222,98,53,161,74,80,240,249,107,129,159,51,35,225,245,162,241,79,65,111,127,52,254,72,14,69,2,206,196,18,193,127,100,237,162,26,226,172,41,115,147,191,55,178,145,53,129,147,227,253,211, -230,115,158,137,96,123,215,86,211,214,92,56,174,92,174,92,32,13,207,13,60,44,134,99,65,57,223,136,214,128,218,130,147,176,119,252,77,101,14,106,105,49,20,125,245,122,28,21,140,217,254,72,62,136,0,21,167,8,230,123,117,0,157,248,71,59,254,205,85,168,235, -223,152,175,31,154,108,251,137,247,111,148,245,122,234,100,118,189,109,122,48,18,16,115,194,187,203,25,1,96,233,242,12,76,180,58,55,105,245,242,162,0,90,94,15,187,77,91,192,47,122,20,217,31,227,181,151,129,118,217,162,252,21,1,216,219,31,201,51,17,128, -213,1,202,67,215,252,79,95,92,171,216,251,189,55,186,17,194,98,64,150,247,79,67,255,62,75,104,188,121,227,208,179,185,114,124,115,70,0,196,227,113,104,120,118,224,62,208,104,100,101,223,9,26,1,172,65,19,236,49,189,161,200,254,104,244,122,40,250,214,151, -243,179,36,16,179,253,145,60,20,1,88,29,160,44,52,250,177,104,102,57,212,150,41,51,241,207,228,31,128,122,203,110,208,11,242,188,127,173,65,128,193,125,150,13,62,107,200,157,43,199,152,203,165,11,102,240,128,165,97,172,222,254,182,214,32,55,10,96,72, -68,1,162,202,68,1,12,23,173,3,253,186,211,33,30,8,230,207,3,17,179,253,145,124,142,4,168,84,29,80,153,103,137,129,49,114,80,141,228,152,158,190,168,70,177,247,124,123,248,5,8,73,212,251,159,186,217,163,141,127,34,1,209,213,244,210,224,250,92,58,206,57, -37,0,104,169,72,203,166,225,123,56,65,222,215,58,30,5,216,105,122,77,153,29,210,104,160,248,59,95,3,141,94,151,184,162,243,192,248,171,185,230,143,189,253,145,140,23,1,22,117,68,192,85,52,49,48,143,68,0,93,251,95,85,87,5,37,5,58,69,222,111,216,219,67, -188,255,93,178,51,255,117,70,129,14,160,251,155,181,215,51,137,2,32,131,25,58,104,217,109,31,240,238,226,117,242,190,154,238,88,20,192,29,113,40,178,63,218,21,139,193,120,237,229,16,15,4,114,252,142,85,63,219,31,123,251,35,249,44,2,242,165,58,128,182, -252,173,44,54,192,170,249,213,138,189,231,214,225,103,33,194,198,198,200,240,254,53,204,251,247,55,60,51,240,64,174,29,235,156,19,0,228,68,65,227,11,131,119,11,50,147,1,105,69,128,35,100,134,109,163,155,20,219,167,226,111,125,137,117,9,132,236,157,25, -241,111,141,191,154,83,253,48,219,31,201,86,17,96,194,234,128,41,19,139,199,225,204,197,181,160,19,148,49,79,189,174,22,104,178,202,207,252,167,19,103,199,26,237,207,90,251,60,131,40,0,178,128,206,183,198,222,182,247,123,247,9,50,163,0,244,66,217,59, -254,6,88,131,227,202,28,228,170,10,40,186,241,139,185,89,17,160,246,72,223,45,245,24,246,71,178,82,4,208,1,66,55,170,48,64,40,151,171,3,168,176,153,87,91,162,88,211,31,122,54,222,28,122,26,164,184,40,175,239,191,134,37,152,135,154,94,28,252,99,46,94, -171,57,41,0,162,33,41,222,248,194,224,93,188,94,222,215,227,52,60,120,35,46,216,58,252,156,98,251,84,240,217,43,65,183,246,148,220,234,16,168,122,182,127,3,102,251,35,89,43,2,138,78,148,8,170,83,29,144,107,163,132,137,227,15,122,45,15,103,45,157,166, -216,123,54,217,14,64,187,227,136,124,239,223,192,195,232,81,251,179,67,7,173,61,40,0,178,41,10,176,213,244,182,173,223,183,79,174,8,48,8,70,120,127,242,61,150,60,162,8,2,15,37,223,255,15,182,78,14,177,28,184,105,49,219,31,65,78,42,18,160,86,179,160,227, -163,132,115,69,4,68,164,24,172,174,171,98,235,255,74,32,198,163,204,251,215,104,100,154,57,13,243,6,67,71,159,238,191,59,87,175,209,156,21,0,209,160,24,111,122,97,240,46,65,199,203,60,247,28,68,98,33,120,125,240,9,197,246,73,187,106,89,98,78,128,63,187, -203,2,213,238,237,143,217,254,72,78,138,128,77,106,204,14,200,13,17,32,74,113,168,46,49,192,154,133,202,37,254,237,31,223,10,3,238,14,208,113,242,38,254,209,204,255,129,221,147,79,142,28,178,245,228,234,245,201,229,242,205,215,185,117,108,171,125,192, -187,83,110,66,32,13,27,53,219,14,66,139,253,160,114,55,237,77,95,6,161,110,54,196,35,217,153,15,16,199,108,127,4,145,39,2,104,98,224,70,245,218,6,103,179,8,160,183,251,186,229,211,65,203,43,99,146,104,47,151,183,135,159,39,239,39,175,140,144,214,253, -71,195,146,255,192,67,221,191,163,77,230,80,0,100,101,20,64,130,163,79,245,223,73,91,56,202,187,40,53,172,4,100,203,192,223,216,240,8,69,14,120,73,49,91,10,0,41,150,88,244,202,170,3,170,158,241,63,138,189,253,145,124,17,1,155,80,4,124,144,136,40,193, -210,57,21,48,187,186,88,177,247,124,103,228,5,176,4,199,64,208,104,101,189,94,91,32,64,239,246,137,13,182,126,239,80,46,95,151,92,174,223,120,29,111,140,237,26,171,183,191,65,75,57,228,64,195,71,131,158,78,216,99,218,162,216,62,233,47,90,7,198,79,93, -12,113,127,22,245,6,80,123,164,47,246,246,71,242,73,4,168,84,29,144,109,34,128,214,252,151,146,251,254,172,37,202,245,251,31,247,15,193,46,211,102,208,243,242,90,8,211,148,129,104,64,116,214,63,51,112,79,174,95,147,57,47,0,104,248,134,156,200,95,16,79, -94,118,17,62,109,14,180,117,248,121,112,134,173,138,237,23,141,2,240,51,167,101,199,200,96,149,179,253,59,176,183,63,146,111,34,64,181,234,128,121,89,85,29,64,107,254,105,232,223,168,23,20,123,207,205,3,143,65,64,244,1,39,51,249,79,87,192,186,254,221, -103,235,243,76,160,0,200,1,6,15,88,234,71,142,216,158,211,26,229,93,100,180,57,16,53,254,175,15,62,169,220,129,175,170,128,146,31,124,11,226,162,152,217,75,1,41,200,246,215,98,182,63,146,183,34,32,127,171,3,104,205,255,210,89,229,48,127,122,169,98,239, -73,71,253,54,88,247,129,65,102,217,31,199,107,192,111,11,143,29,92,223,115,127,62,92,139,121,33,0,232,140,128,189,15,116,222,41,69,99,126,154,220,33,7,131,80,0,7,38,222,134,30,87,139,98,251,101,248,228,249,96,188,242,146,140,93,10,192,108,127,4,73,129, -8,200,195,234,128,68,232,95,7,103,47,155,174,216,123,134,165,32,188,54,240,232,49,207,95,222,67,69,87,168,133,182,205,163,191,241,76,4,92,40,0,114,8,75,151,187,191,111,231,196,3,186,2,185,101,129,26,136,197,37,120,165,127,61,171,47,85,138,146,31,126, -11,132,217,51,32,30,201,172,165,0,204,246,71,144,20,137,0,21,171,3,50,117,57,128,6,61,207,93,57,3,10,20,12,253,191,59,242,34,140,120,251,64,203,201,203,252,167,243,99,236,131,222,214,250,231,6,30,207,151,107,144,203,167,27,110,255,131,93,247,4,156,145, -113,26,230,145,165,14,121,3,244,186,90,97,215,216,107,202,157,128,202,114,40,249,209,127,38,154,3,101,202,82,64,74,178,253,49,236,143,32,255,156,24,152,251,203,1,225,168,4,43,230,86,64,93,109,137,98,239,57,238,31,132,119,71,55,202,14,253,83,104,215,191, -134,103,7,110,15,185,35,145,124,185,254,242,74,0,120,38,130,142,230,77,195,191,20,100,86,4,36,68,128,30,222,28,122,70,177,57,1,20,106,100,11,191,112,45,196,125,25,176,20,144,178,108,127,180,254,8,242,33,17,112,44,39,192,148,195,213,1,172,225,15,217,151, -179,151,77,83,244,8,110,234,123,24,130,162,159,181,113,151,131,64,140,255,120,179,115,107,231,91,99,111,230,211,181,199,229,219,205,86,255,116,255,227,174,17,127,189,220,113,193,52,33,208,27,117,193,203,253,235,21,221,175,226,239,126,29,180,167,44,73, -239,172,0,236,237,143,32,105,23,1,55,170,84,29,144,110,17,64,3,156,60,167,129,11,86,205,2,157,192,43,246,190,251,39,222,97,205,218,146,241,254,53,188,38,242,254,163,61,63,137,134,164,188,186,238,242,78,0,68,2,162,248,254,35,61,63,230,181,242,191,186, -129,47,128,122,203,110,56,98,217,169,216,126,105,10,140,80,250,179,239,179,159,32,165,225,34,76,73,111,127,52,254,8,114,178,145,128,92,19,1,81,242,92,59,99,73,45,76,43,47,80,236,61,157,97,27,75,252,147,187,238,79,209,23,105,161,111,219,196,131,131,7, -44,173,249,118,205,113,249,120,163,117,189,109,218,49,124,208,250,60,173,247,148,11,141,4,208,40,128,39,226,84,108,191,180,203,22,65,201,247,190,9,241,96,56,165,199,3,179,253,17,36,3,69,64,14,85,7,208,146,191,186,105,165,176,102,65,181,162,239,75,147, -178,29,33,11,121,30,203,235,248,71,187,196,6,221,145,241,253,15,119,255,26,226,249,119,189,229,165,0,160,161,168,125,15,118,221,30,13,73,110,185,101,129,2,167,5,107,96,156,92,128,27,20,221,183,130,207,95,147,232,18,232,243,167,196,96,98,182,63,130,100, -166,8,232,200,145,217,1,180,228,175,164,64,7,23,156,50,83,209,199,0,141,194,190,63,185,141,149,104,203,118,186,140,2,52,60,55,112,135,115,216,103,207,199,107,141,203,215,155,204,210,229,30,110,121,101,248,215,186,66,249,81,0,122,225,237,159,120,27,26, -172,123,21,221,183,146,31,255,39,8,11,235,212,143,4,168,109,252,177,183,63,130,200,22,1,133,42,86,7,164,74,4,28,47,108,186,112,213,44,40,52,104,21,123,95,119,196,1,27,251,30,34,158,63,207,74,180,101,57,113,122,14,172,61,238,61,13,207,41,216,225,13,5, -64,246,112,248,241,222,251,93,163,254,38,185,249,0,244,194,227,53,28,108,236,125,144,37,6,42,118,82,74,75,160,236,127,111,1,141,65,79,211,102,85,51,254,234,133,253,247,66,7,246,246,71,144,164,249,112,78,64,246,85,7,68,201,243,235,140,197,181,48,187,186, -72,209,247,125,185,111,61,171,196,162,145,88,153,15,111,224,4,46,122,224,161,238,155,163,193,44,159,165,140,2,64,30,33,79,52,114,240,225,238,155,5,61,47,123,245,71,224,116,96,9,154,152,26,85,18,237,202,37,80,114,243,255,133,120,56,172,124,127,0,85,179, -253,137,241,223,92,143,217,254,8,162,80,36,64,237,217,1,85,37,234,136,0,186,238,191,112,70,25,172,93,84,163,236,51,198,178,19,14,78,190,3,198,36,66,255,250,2,1,58,223,26,187,191,127,143,185,33,159,175,47,46,223,111,176,174,119,199,119,13,238,183,60,154, -204,82,0,189,16,15,78,188,3,135,205,219,21,221,183,130,235,174,132,130,207,95,11,113,175,95,97,207,95,205,108,255,122,92,243,71,16,213,68,128,10,203,1,103,38,34,1,17,5,69,64,84,138,65,101,177,1,46,88,53,83,209,99,65,19,254,94,234,253,43,240,156,0,114, -31,50,196,243,135,128,51,50,176,255,161,238,59,243,253,218,202,123,1,64,231,4,236,250,99,219,207,130,174,136,73,110,135,64,122,33,210,11,242,165,222,7,193,30,154,84,116,255,74,110,185,9,244,23,156,77,68,128,47,249,239,26,142,96,182,63,130,100,187,8,80, -169,58,160,154,137,128,228,151,28,69,98,252,11,244,90,248,228,105,115,192,160,19,20,61,14,47,244,62,0,142,176,5,4,141,252,124,2,173,129,131,3,15,119,255,208,59,25,244,160,0,64,192,57,226,183,29,125,170,255,182,100,162,0,244,130,116,69,108,240,108,207, -125,228,102,85,46,100,175,209,233,152,193,54,92,124,46,196,61,222,68,203,96,57,15,16,127,0,184,242,82,40,191,231,231,152,237,143,32,217,44,2,44,199,68,128,194,145,128,171,207,170,131,89,85,197,172,85,175,220,85,71,42,32,78,204,33,40,49,40,250,253,119, -140,189,202,50,255,141,124,161,124,227,111,228,97,172,193,241,124,235,107,195,175,227,21,133,2,224,4,77,47,14,189,96,106,116,188,170,77,162,77,48,109,16,212,108,61,192,134,82,40,137,166,168,16,202,239,190,3,138,190,245,101,58,64,27,226,129,224,73,231, -5,80,175,159,182,24,214,159,125,26,84,109,184,155,253,84,220,248,99,111,127,4,73,125,36,64,225,229,0,58,152,231,42,34,2,78,91,88,195,62,135,46,9,156,172,16,160,165,126,244,223,207,169,41,129,79,159,179,0,106,202,140,138,126,239,17,111,47,188,218,255, -40,155,199,34,219,216,241,26,136,134,36,203,174,123,219,111,141,199,240,90,66,1,240,1,196,136,4,59,255,208,254,3,49,28,179,201,95,10,0,208,243,70,216,50,248,4,12,120,58,148,221,65,65,128,226,255,190,17,42,30,188,11,244,231,158,145,16,2,62,63,107,29,204, -26,249,208,208,29,221,162,34,196,67,225,196,223,145,159,218,69,117,80,118,231,109,80,241,215,187,128,159,59,75,97,227,255,193,108,127,180,254,8,146,30,17,160,92,117,128,192,105,96,221,242,233,112,237,217,243,97,254,180,18,118,91,71,162,18,91,211,167, -70,62,22,63,182,145,223,211,80,63,53,250,244,239,202,139,12,112,241,234,217,112,245,153,117,172,230,95,73,232,152,223,167,187,255,0,33,41,192,202,254,228,66,27,191,29,121,162,255,86,75,151,123,2,175,162,99,231,27,15,193,223,49,119,186,70,143,60,217,255, -147,115,191,187,228,177,176,87,222,120,94,58,139,58,34,133,225,169,174,123,224,199,167,221,15,5,66,177,162,251,168,59,117,37,84,144,45,218,209,11,225,125,135,32,210,218,5,210,132,133,24,251,196,67,128,214,245,115,213,149,160,93,186,0,244,231,156,14,250, -211,87,179,164,63,165,57,145,237,143,97,127,4,73,179,8,104,133,191,93,191,10,102,148,232,21,123,255,233,21,5,100,155,7,118,34,46,134,45,94,152,116,248,193,19,136,48,99,79,195,2,28,17,10,116,157,191,178,212,0,115,170,139,97,54,217,120,78,157,7,193,43, -253,143,64,191,187,131,60,75,229,151,18,210,134,63,99,13,142,205,245,207,244,63,131,87,15,10,128,143,165,254,233,190,199,235,206,173,190,118,218,138,178,79,71,131,242,18,98,232,196,192,81,111,31,188,216,251,87,248,230,178,159,170,178,159,218,229,139, -216,198,30,6,212,227,103,229,130,84,0,8,160,41,44,80,245,24,97,111,127,4,201,188,72,128,210,34,128,66,215,241,19,107,249,213,44,2,112,188,92,144,227,64,209,129,62,31,7,173,172,218,49,246,10,24,5,249,235,254,26,94,3,98,72,180,236,252,67,219,247,164,40, -198,254,63,228,176,226,33,248,48,98,36,70,151,2,190,151,236,82,0,189,96,247,143,111,133,221,227,91,84,223,103,218,48,136,54,15,226,202,74,82,96,252,247,98,182,63,130,100,168,8,80,178,58,224,31,161,30,190,129,124,22,221,82,97,252,39,2,35,240,124,207,253, -228,115,181,178,187,253,49,135,172,64,128,195,79,244,221,98,233,118,143,225,21,131,2,224,223,98,238,112,141,29,121,178,239,7,218,130,100,2,36,26,208,242,122,216,216,251,144,242,249,0,105,34,145,237,143,97,127,4,201,88,17,160,112,117,64,186,8,75,33,120, -162,243,247,224,139,186,65,208,200,127,14,83,227,111,106,114,188,80,255,204,192,179,120,165,160,0,56,105,14,63,222,251,220,224,62,243,179,201,148,6,210,132,149,72,44,124,226,66,206,122,227,143,189,253,17,36,59,34,1,89,46,2,54,246,61,8,189,174,22,150, -84,45,219,184,9,28,157,244,55,186,237,174,150,31,96,232,31,5,192,212,110,40,114,71,237,250,99,251,15,66,158,232,16,29,25,41,91,129,114,122,48,249,6,225,233,238,123,21,237,15,144,90,227,191,151,213,249,99,216,31,65,178,41,18,16,202,202,239,177,119,252, -13,216,101,218,156,212,186,63,133,150,116,31,120,168,235,59,246,126,175,5,175,14,20,0,83,198,57,226,183,239,190,183,253,38,65,199,199,146,49,124,244,66,62,98,222,1,111,14,61,149,149,198,159,102,251,163,231,143,32,89,36,2,88,179,160,86,48,101,89,36,160, -207,221,198,146,167,169,227,148,204,186,191,190,88,11,29,111,142,221,215,242,202,200,91,120,85,160,0,144,13,185,136,182,117,189,99,250,189,190,40,185,81,150,116,94,192,235,131,79,66,131,117,79,118,121,254,88,234,135,32,89,43,2,254,227,229,86,176,248, -35,89,177,223,174,176,13,254,214,241,91,136,198,194,192,37,81,239,47,232,121,234,188,213,239,189,191,243,103,120,53,160,0,72,154,157,247,180,253,175,173,207,187,95,48,200,191,40,53,228,80,107,52,28,60,221,245,71,24,243,245,103,252,119,110,125,249,8,51, -254,186,2,236,240,135,32,217,40,2,138,136,8,104,157,244,192,247,183,116,64,40,195,39,222,70,99,17,120,188,243,183,96,14,140,129,150,147,95,202,168,225,52,180,121,145,111,251,111,91,190,225,183,133,130,120,37,160,0,72,154,144,39,26,125,239,215,205,223, -136,137,49,135,38,137,210,64,58,47,192,39,122,224,209,142,95,131,55,234,202,216,239,59,209,58,10,77,47,30,2,45,107,239,139,214,31,65,178,149,98,189,0,187,7,29,240,199,189,131,25,189,159,47,245,61,8,109,246,195,96,16,146,43,99,214,23,9,112,228,169,254, -91,70,14,219,218,240,236,163,0,80,208,40,58,251,14,61,214,251,93,93,65,114,189,147,244,156,1,70,125,253,240,183,142,223,129,20,23,51,238,123,74,17,17,234,159,218,199,166,36,106,56,52,254,8,146,11,34,224,241,250,49,104,24,207,204,225,119,219,70,55,178, -65,63,201,38,253,209,138,173,161,131,214,167,223,127,164,231,17,60,235,40,0,20,231,200,147,125,47,246,238,152,120,32,153,210,64,10,157,102,213,100,219,207,198,7,103,26,131,123,187,193,222,103,6,65,143,77,34,17,36,39,30,242,68,199,135,197,24,252,245,253, -225,140,219,183,102,242,28,220,212,191,158,56,70,201,37,253,241,90,14,124,214,80,251,123,119,181,96,183,63,20,0,234,64,39,72,189,123,103,243,143,236,3,190,131,201,228,3,48,17,64,212,238,182,177,77,240,222,232,75,153,243,253,164,24,244,110,107,7,142,231, -241,100,35,72,14,81,160,229,97,239,160,19,186,172,254,140,217,39,58,225,239,111,157,191,103,9,11,201,36,253,209,72,37,39,112,254,237,191,107,253,170,199,20,240,224,217,70,1,160,26,97,111,52,252,222,175,155,191,34,69,98,214,100,90,5,83,181,75,151,3,54, -245,173,135,122,235,238,140,248,110,206,17,59,56,134,108,192,235,208,251,71,144,92,139,2,248,34,34,108,235,179,101,196,254,56,66,22,88,223,254,75,8,136,94,16,184,228,42,172,104,68,246,224,134,238,239,13,236,49,55,226,153,70,1,160,58,19,173,206,129,125, -127,233,252,166,96,224,227,201,228,200,81,213,75,43,3,158,236,188,27,122,221,173,105,255,94,214,158,73,16,67,81,204,250,71,144,28,132,142,250,61,58,150,254,142,164,65,209,15,27,218,239,4,115,96,20,116,156,252,78,127,52,114,64,235,253,123,119,76,60,120, -232,241,222,39,240,12,163,0,72,25,77,47,13,189,217,242,202,240,255,232,146,236,15,64,251,92,211,190,215,27,218,126,201,134,95,164,19,247,152,3,79,44,130,228,176,0,24,243,132,210,90,18,72,19,159,105,185,31,109,243,107,224,11,18,86,92,38,218,2,30,108,253, -222,125,59,126,223,118,75,150,54,89,69,1,144,205,236,190,183,227,215,163,71,237,155,244,73,38,5,210,186,87,218,4,227,225,214,255,97,63,211,69,216,19,196,204,127,4,201,213,135,189,70,3,254,136,4,193,168,148,182,125,120,182,251,62,168,183,236,78,58,227, -159,23,56,136,248,37,211,187,191,108,250,178,223,22,10,227,217,69,1,144,114,196,176,4,239,252,162,233,91,238,137,96,179,160,79,230,80,198,217,208,11,147,127,16,30,110,251,5,4,68,95,90,190,79,28,147,103,17,36,167,137,39,229,115,39,199,171,3,143,192,110, -211,102,40,16,138,146,122,31,186,236,202,235,184,200,206,63,180,253,159,201,118,215,40,158,85,20,0,105,195,51,17,112,191,251,171,230,47,74,209,184,45,153,161,65,20,26,18,163,161,177,71,219,127,197,166,8,166,26,193,40,64,60,142,177,52,4,201,73,227,31, -167,209,70,13,232,210,16,229,123,103,228,69,120,115,232,25,48,36,233,249,179,231,100,137,142,54,251,249,126,231,91,99,187,241,172,162,0,72,59,163,71,108,93,251,254,210,249,53,94,203,75,201,54,206,163,161,177,38,219,1,54,66,56,22,79,109,168,174,168,166, -20,112,45,13,65,114,19,137,40,128,234,66,29,20,166,184,199,199,158,241,55,224,229,190,135,137,240,48,36,85,235,207,140,63,29,242,179,117,236,190,131,235,187,215,227,25,69,1,144,49,52,189,52,180,181,225,249,129,155,13,165,186,164,223,139,134,200,222,159, -124,15,158,233,254,19,164,210,34,87,45,172,5,13,143,151,4,130,228,34,81,41,6,43,107,139,83,90,228,115,216,188,13,158,35,207,49,158,211,2,167,73,238,217,66,199,251,78,116,184,222,216,241,251,214,219,176,217,15,10,128,140,99,223,95,187,30,104,127,125,244, -207,180,31,181,18,34,128,206,196,166,163,49,83,69,245,226,90,40,170,46,134,152,136,55,23,130,228,26,60,199,193,69,11,42,83,246,121,116,242,233,19,93,247,176,82,103,94,147,92,115,49,58,225,47,232,138,180,188,249,211,250,175,134,220,105,204,98,68,1,128, -124,28,49,162,74,183,255,182,245,150,201,118,215,230,100,103,6,80,232,114,192,187,35,47,178,65,25,169,128,142,253,157,123,206,66,16,195,81,60,153,8,146,67,208,210,191,101,213,133,112,206,156,178,148,124,30,29,236,243,88,199,93,16,139,199,136,241,79,238, -89,72,219,252,70,2,226,196,27,63,173,191,222,109,10,184,240,108,162,0,200,88,200,133,26,219,114,219,209,175,186,70,253,135,105,200,42,25,232,122,25,77,154,121,103,248,5,216,60,240,120,74,246,127,233,149,171,193,88,94,8,49,9,163,0,8,146,51,207,37,114, -63,127,235,204,217,228,121,162,254,35,191,205,113,24,214,183,255,2,164,152,200,250,156,36,245,12,228,52,52,227,63,176,231,190,142,207,155,26,29,125,120,38,81,0,100,60,62,107,200,251,206,157,205,55,132,189,209,1,170,94,147,23,1,5,176,101,240,137,148,136, -128,194,234,98,88,245,185,51,18,29,1,17,4,201,122,188,97,9,46,93,88,5,215,173,168,77,137,231,191,190,245,23,16,149,34,73,183,248,165,9,213,196,137,138,239,188,167,237,27,237,175,143,238,195,51,137,2,32,107,24,111,118,140,190,241,211,250,235,136,253,182, -39,51,51,224,67,34,96,40,53,34,96,217,149,171,97,193,249,75,33,226,199,254,26,8,146,173,208,167,78,32,42,193,156,50,3,220,117,217,98,224,53,234,166,255,29,247,252,163,177,228,141,63,133,182,249,109,121,121,248,135,77,47,13,109,196,179,137,2,32,235,24, -61,106,111,222,125,111,251,231,121,29,31,212,40,33,2,248,2,120,125,232,73,216,212,247,176,202,79,14,13,156,253,159,151,192,172,181,117,40,2,16,36,75,241,19,227,95,83,168,131,245,159,89,9,179,74,13,42,123,254,135,96,125,219,47,21,241,252,41,116,192,15, -49,254,119,237,184,187,237,126,60,147,40,0,178,150,230,77,195,59,118,254,161,237,27,188,150,139,37,219,102,151,77,16,228,141,176,117,248,89,213,171,3,180,70,45,92,248,163,79,193,194,139,150,65,36,16,134,120,12,27,4,32,72,182,64,195,254,75,170,10,225, -169,207,175,134,85,211,139,85,253,44,154,237,255,80,219,255,18,207,63,172,152,231,63,124,200,246,200,182,187,90,254,31,62,119,80,0,100,191,8,216,56,244,82,253,51,3,223,165,77,44,146,45,194,61,158,24,248,238,200,11,240,116,247,31,33,14,234,37,235,9,6, -45,124,226,7,151,195,25,95,63,143,117,8,148,34,88,125,131,32,153,76,140,220,167,158,176,8,87,47,173,134,23,190,116,42,44,175,41,82,245,243,14,153,183,193,163,29,191,97,67,126,4,141,50,158,255,120,179,99,211,219,255,211,248,159,216,148,20,5,64,206,176, -255,161,174,245,205,155,134,126,202,68,64,146,28,23,1,187,198,94,131,199,59,126,11,98,44,162,234,190,175,248,204,90,184,248,167,215,64,65,101,17,68,131,17,60,153,8,146,97,80,191,34,44,198,128,22,239,220,126,193,2,88,255,217,149,80,89,160,85,245,51,247, -140,191,14,127,235,248,29,113,14,98,202,24,255,2,129,142,90,127,119,243,173,71,190,22,112,132,209,219,64,1,144,59,196,165,56,108,187,171,245,247,45,47,15,255,198,80,162,76,36,192,40,20,193,254,137,183,217,218,91,72,10,168,186,255,51,214,204,129,203,127, -117,253,137,188,0,12,205,33,72,230,224,33,246,114,122,137,30,30,189,254,20,248,239,117,115,85,255,188,119,70,94,128,103,186,238,101,221,253,146,173,243,63,110,252,29,67,190,3,91,110,61,250,185,160,51,18,196,51,138,2,32,247,68,64,156,137,128,59,90,94, -25,254,179,18,141,130,40,180,99,96,131,117,47,252,165,229,103,224,137,56,84,221,127,218,37,240,226,219,175,129,83,191,116,14,19,0,82,68,196,147,138,32,105,68,138,197,153,241,191,124,113,21,108,250,242,169,112,209,252,10,213,63,243,149,129,71,96,99,223, -67,32,112,58,34,0,248,164,223,143,118,249,11,56,195,245,239,252,162,233,51,228,167,7,207,42,10,128,220,22,1,191,105,249,225,240,251,214,13,74,44,7,80,104,199,192,46,103,35,252,169,249,199,96,14,142,169,186,255,52,145,113,245,23,206,34,66,224,106,40,174, -45,133,72,0,151,4,16,36,29,4,163,49,208,104,52,240,255,46,156,15,143,17,207,127,70,137,186,153,254,116,157,255,169,174,63,192,27,131,79,177,100,228,100,123,251,31,55,254,33,79,164,117,243,173,71,62,61,217,225,178,226,89,69,1,144,7,34,0,224,237,255,109, -250,142,169,217,241,152,174,72,153,72,0,45,17,28,245,246,193,125,141,183,193,160,167,83,245,239,48,99,205,92,184,252,215,55,192,130,243,151,64,52,24,197,249,1,8,146,194,231,7,77,244,91,82,93,8,207,124,97,53,252,215,57,115,85,31,240,19,20,125,240,112, -219,47,216,124,18,26,117,212,40,240,137,204,248,187,35,237,196,248,127,106,178,205,101,194,51,139,2,32,111,8,56,194,113,114,225,127,107,162,197,249,24,205,124,85,74,4,216,195,22,248,115,243,79,160,217,118,64,245,239,96,44,43,128,243,110,190,2,214,125, -247,18,208,21,234,48,65,16,65,84,38,44,197,32,68,182,111,172,157,197,66,254,103,206,42,85,253,51,237,33,51,121,166,252,20,26,44,187,153,241,87,130,99,158,127,223,230,219,142,92,75,140,255,24,158,89,20,0,121,71,208,25,1,34,2,110,154,104,117,62,166,47, -82,98,57,32,14,58,78,15,33,49,192,212,250,110,211,150,148,124,143,69,151,174,128,203,127,117,3,204,60,117,30,68,3,17,156,35,128,32,74,123,253,64,107,251,69,152,81,108,128,245,159,89,193,58,251,149,24,4,213,63,119,216,219,13,127,106,186,21,250,220,173, -44,233,88,17,227,111,96,158,127,31,121,246,93,73,140,255,0,158,93,20,0,249,44,2,226,91,110,61,122,211,120,139,67,33,17,0,172,25,7,13,208,61,211,125,47,188,220,191,158,60,60,212,207,216,47,157,89,14,151,222,241,105,56,227,155,231,131,160,19,216,178,0, -130,32,201,67,7,249,208,245,254,207,175,154,14,175,126,229,52,184,98,113,117,74,62,183,201,182,15,238,107,250,17,88,130,38,48,240,133,202,121,254,238,72,219,230,219,142,94,65,140,63,14,247,65,1,128,4,156,97,34,2,142,220,52,214,104,87,44,39,128,102,231, -234,120,3,188,53,244,12,108,104,187,19,2,162,79,253,47,66,84,199,242,107,79,133,203,239,188,30,102,174,153,131,209,0,4,73,198,235,143,39,188,254,233,197,122,248,235,181,203,225,79,87,45,131,154,34,93,74,62,251,189,209,151,224,225,182,95,66,80,12,128, -142,51,28,139,65,40,96,252,19,9,127,196,243,119,246,227,25,70,1,128,156,16,1,145,248,43,223,123,255,91,109,175,141,254,89,169,234,128,227,189,2,14,155,183,49,37,111,14,140,166,228,187,148,207,171,130,75,127,254,105,56,235,166,11,65,87,160,99,66,0,176, -109,0,130,156,52,33,49,198,214,251,255,207,154,153,240,234,87,215,194,53,203,106,82,242,185,98,44,10,207,246,252,137,181,26,231,200,243,67,137,214,190,20,109,129,64,141,255,209,99,9,127,184,230,143,2,0,249,167,155,47,28,131,109,191,105,254,97,203,43, -195,191,99,205,130,20,130,138,0,90,25,240,135,198,91,216,208,142,148,160,209,192,210,79,173,134,43,126,243,57,152,119,238,98,16,35,81,144,162,216,220,11,65,254,21,137,186,126,17,22,87,21,178,210,190,187,175,92,194,6,250,164,2,71,216,10,247,55,255,20, -182,143,190,114,172,204,143,87,228,125,89,147,159,65,239,62,52,254,40,0,144,127,3,13,251,189,119,87,203,237,68,4,252,92,137,217,1,199,161,55,52,109,20,244,215,214,59,88,120,47,85,148,76,47,131,11,110,187,18,46,184,229,74,40,158,86,138,93,4,17,228,163, -238,123,178,249,35,18,104,121,14,110,62,183,14,94,249,202,105,112,201,130,202,148,125,126,175,171,5,254,216,120,51,116,56,143,42,86,230,199,140,127,161,0,19,109,206,119,55,126,231,224,213,196,248,99,157,127,134,33,224,33,200,204,167,193,182,223,180,252, -154,136,1,247,170,235,230,222,31,241,139,138,24,77,45,167,131,88,92,130,23,122,255,2,38,223,32,124,113,209,247,216,76,129,84,48,119,221,34,152,182,106,54,180,191,90,15,93,239,180,178,101,1,58,113,16,65,242,29,218,195,95,36,55,251,165,11,171,224,182,243, -234,96,69,109,81,74,63,159,86,11,209,206,126,116,154,31,45,37,86,10,58,213,143,14,246,161,189,253,177,189,47,10,0,100,138,145,0,34,2,30,112,12,120,29,231,255,112,249,99,98,36,166,167,243,4,146,133,134,245,140,124,33,236,25,127,3,76,254,65,248,198,178, -31,195,204,194,249,41,249,78,250,34,3,156,246,213,115,97,238,185,139,160,249,133,67,48,86,63,200,58,11,242,58,188,12,145,252,67,36,162,62,16,149,88,67,159,31,174,171,131,79,47,175,73,233,231,135,165,32,188,212,247,32,19,0,90,78,207,54,69,208,36,194,254, -195,7,45,27,182,254,188,233,187,196,248,227,218,95,134,130,75,0,25,78,195,243,131,207,238,252,67,251,117,130,158,119,241,130,114,167,139,134,249,134,60,93,240,199,134,155,225,176,121,123,74,191,83,229,252,26,184,248,103,215,192,249,183,94,9,101,179,43, -33,26,8,99,39,65,36,111,136,29,203,238,47,212,241,240,163,243,231,195,230,175,174,77,185,241,31,39,226,255,222,166,219,96,231,216,107,108,121,144,87,104,189,95,67,140,63,93,186,108,123,109,228,174,87,126,112,248,219,1,39,78,245,195,8,0,146,20,205,27, -135,222,242,154,131,87,92,118,199,234,141,250,18,237,108,49,164,204,61,69,111,252,160,228,135,71,219,127,13,3,158,78,184,126,193,77,202,121,1,39,193,188,117,139,96,214,105,243,160,251,237,22,232,120,179,9,2,54,47,8,6,29,139,10,32,72,174,65,227,119,1, -226,12,235,137,144,255,194,170,25,108,106,95,93,185,49,229,251,241,190,249,61,120,177,231,175,224,139,186,20,235,236,199,140,63,185,111,181,70,62,222,180,113,248,230,29,191,107,249,115,28,83,125,80,0,32,202,48,176,199,124,232,245,159,28,189,232,83,191, -62,109,83,97,165,126,77,84,33,17,192,107,180,192,241,2,188,59,242,34,235,250,245,149,197,55,195,204,162,249,169,187,0,13,90,88,241,153,181,48,239,19,139,161,227,245,70,232,219,209,1,17,95,24,4,163,150,13,58,65,144,92,128,54,242,161,92,180,160,18,254, -251,156,185,112,70,10,90,248,254,35,52,228,255,114,255,6,230,245,243,156,192,28,0,165,224,181,28,221,252,59,239,105,187,177,233,165,161,151,240,140,103,7,184,4,144,69,152,26,29,253,47,126,107,255,165,214,94,207,219,74,150,9,210,140,95,234,9,244,185,90, -225,15,141,55,195,190,137,183,82,254,221,10,171,138,89,23,193,43,127,243,57,88,120,209,50,230,46,177,110,130,232,70,32,89,12,173,231,167,217,253,167,205,44,129,71,174,91,9,79,125,110,85,90,140,255,144,183,139,221,219,219,70,55,129,142,215,131,160,81, -206,247,163,13,126,196,144,100,122,239,55,205,87,162,241,71,1,128,168,136,103,34,104,223,124,203,145,79,15,236,53,111,160,173,131,149,116,146,169,71,16,146,2,240,68,231,221,240,120,231,111,193,27,117,165,252,251,149,205,169,132,115,191,127,25,92,246, -203,235,96,238,217,11,32,38,197,201,195,37,138,141,132,144,172,130,102,246,123,195,18,44,175,41,130,63,95,179,140,13,238,185,108,81,85,90,246,133,26,253,123,27,111,133,33,79,183,162,37,126,20,173,129,117,247,107,220,114,219,145,139,219,54,143,238,197, -51,159,93,224,18,64,22,226,179,134,34,175,221,114,228,219,151,252,244,148,193,149,215,206,249,173,68,60,140,152,164,140,133,228,137,103,192,243,60,236,31,223,10,3,238,14,248,226,162,255,134,149,149,103,166,252,59,86,47,158,6,23,254,248,42,48,119,152, -160,125,115,3,152,26,135,89,91,97,173,94,0,192,165,1,36,131,61,126,154,221,79,13,255,55,215,206,130,235,86,214,18,97,157,30,63,203,30,154,132,23,123,255,2,245,214,61,172,157,175,158,55,40,250,254,180,204,207,220,238,218,242,214,29,13,223,112,142,248, -157,120,246,81,0,32,41,130,150,4,110,251,77,203,239,156,195,190,254,79,252,215,178,71,52,92,188,84,138,42,149,73,79,91,8,23,130,53,56,14,127,105,253,25,92,50,235,122,184,182,238,27,138,174,25,158,44,181,203,103,178,109,178,109,12,58,223,106,6,83,195, -16,72,145,40,8,122,45,38,11,34,25,101,248,105,23,191,149,211,138,225,171,167,206,128,207,46,159,6,70,109,250,2,172,135,204,219,96,83,223,122,112,134,45,172,236,87,73,88,166,127,137,14,58,182,142,221,183,235,158,182,219,2,88,230,135,2,0,73,15,245,207, -12,108,116,12,250,6,47,251,249,234,103,140,101,186,37,74,37,7,82,104,227,160,56,196,224,237,225,231,160,203,217,0,95,88,244,61,88,92,182,58,45,223,115,218,202,89,108,51,119,142,67,247,214,102,24,171,31,98,205,132,4,131,64,132,0,174,100,33,105,16,225, -113,128,160,152,184,223,78,155,81,202,12,63,237,217,175,227,211,119,61,186,194,54,120,165,127,3,28,156,124,143,149,246,41,217,216,135,194,9,28,240,58,46,124,232,241,222,31,238,251,107,215,195,216,213,19,5,0,146,102,6,247,91,142,190,120,211,129,11,174, -249,253,218,191,85,47,41,189,50,236,83,110,205,92,3,28,155,37,48,234,235,131,63,55,255,24,46,153,117,3,92,53,239,43,105,137,6,176,136,192,178,25,108,115,12,88,161,251,221,86,24,121,191,31,130,110,63,8,58,45,123,56,33,136,218,72,196,242,211,172,126,26, -218,63,191,174,2,190,186,102,38,92,186,176,18,248,52,71,164,14,91,118,192,43,125,27,88,228,206,32,20,40,186,214,207,28,2,35,15,17,191,56,178,253,119,45,223,232,120,99,108,39,94,9,40,0,144,12,193,53,234,55,111,250,238,251,215,92,120,219,138,223,45,189, -124,230,109,180,87,128,82,121,1,20,186,134,24,139,199,224,141,161,167,160,221,113,4,110,88,248,29,88,86,126,90,218,190,111,197,252,106,56,231,59,23,195,202,207,172,133,254,157,157,48,176,183,27,188,19,174,132,135,162,21,0,112,117,0,81,152,40,185,159, -66,196,227,47,51,106,225,138,197,213,240,21,98,248,207,154,93,154,246,253,114,132,204,196,235,127,4,14,89,182,3,79,126,25,85,104,239,77,215,251,109,253,222,221,219,126,221,252,245,241,22,231,48,94,13,40,0,144,12,35,232,138,72,91,239,104,252,145,189,207, -219,124,246,77,139,255,194,243,154,82,41,162,92,135,61,78,195,177,44,226,68,52,224,39,112,193,204,107,224,154,121,95,131,34,109,89,218,190,51,29,48,180,230,75,103,195,242,107,214,192,208,129,94,38,6,108,125,22,34,126,36,204,19,64,146,134,134,249,143, -175,239,207,45,55,192,213,75,107,224,115,167,76,135,133,149,5,25,177,127,123,199,223,132,45,131,79,48,17,160,134,215,79,239,31,218,214,183,111,231,228,95,119,220,221,122,171,207,18,10,227,85,129,2,0,201,96,14,63,209,247,140,109,192,219,126,233,237,171, -254,86,88,165,95,77,135,9,41,137,142,211,179,220,128,109,35,155,160,221,126,24,62,61,255,70,56,163,230,226,180,126,103,93,145,1,22,95,118,10,44,186,116,37,76,180,140,66,255,174,78,24,111,26,134,144,59,8,156,150,248,69,90,62,63,47,6,77,90,94,154,245,208, -76,254,96,84,34,70,149,103,117,251,55,172,156,198,188,254,50,99,102,60,50,169,8,127,149,120,253,45,246,247,65,224,116,170,120,253,188,142,3,142,215,120,15,172,239,254,225,161,199,122,30,143,99,183,110,20,0,72,118,48,176,199,220,184,113,232,192,5,151, -220,190,234,254,57,103,86,125,77,169,137,130,127,55,14,28,123,232,216,130,19,176,161,237,78,56,90,189,11,62,51,255,63,96,122,225,220,244,218,59,226,177,204,88,51,135,109,222,73,55,139,10,12,147,205,57,108,99,101,132,130,78,0,13,159,39,185,2,196,125,165, -3,152,228,82,162,23,242,170,226,146,222,30,97,81,2,186,114,54,163,88,15,151,18,79,255,51,43,106,225,204,89,165,25,179,143,180,79,199,59,35,47,192,246,209,151,33,32,250,20,79,242,59,33,168,11,5,32,222,126,203,206,63,180,221,72,188,255,122,124,162,162, -0,64,178,12,231,136,223,253,234,15,14,125,125,221,119,150,28,90,251,229,249,247,196,98,241,2,37,151,4,216,5,68,188,15,1,226,80,111,221,13,93,174,70,184,116,246,13,240,201,217,159,83,237,193,52,21,232,242,192,41,215,157,14,43,174,61,149,69,5,134,246,245, -194,120,243,48,4,28,126,34,2,52,44,87,32,167,151,8,136,33,43,154,38,223,120,213,18,35,104,16,56,22,6,207,85,33,64,37,113,68,140,65,132,136,195,34,34,120,214,205,45,135,107,151,213,178,164,190,234,66,93,70,237,107,3,185,199,104,184,127,212,219,199,146, -112,213,184,199,232,253,160,47,18,96,232,160,245,201,237,191,107,253,129,107,212,239,198,39,41,10,0,36,75,161,6,127,239,253,157,15,78,182,187,234,47,188,121,197,250,162,90,131,226,75,2,52,30,64,31,70,81,41,12,175,245,63,10,245,150,221,112,205,188,175, -195,218,154,11,50,226,24,112,2,15,51,79,155,199,182,128,221,199,74,8,135,15,246,129,173,119,18,34,254,48,75,28,164,203,4,185,54,123,128,126,167,202,186,106,217,175,159,87,110,132,154,34,61,76,120,195,160,205,161,99,67,141,62,77,232,163,222,190,142,156, -251,197,213,133,240,201,133,85,112,229,146,106,88,81,83,148,113,251,59,234,235,135,215,137,225,111,178,238,35,215,104,162,42,71,13,88,200,159,211,120,15,61,222,123,219,193,13,61,27,148,118,22,16,20,0,72,154,232,221,62,113,104,178,205,121,254,197,63,57, -229,158,5,23,76,251,191,209,128,168,104,149,0,51,56,26,158,61,156,38,252,195,240,112,251,47,96,213,228,57,44,73,112,94,201,210,140,57,14,5,149,69,176,248,178,149,108,115,141,218,97,244,200,32,17,4,131,172,172,48,26,140,228,140,24,160,227,149,139,170, -139,161,124,158,124,1,80,164,227,225,212,233,37,48,228,52,131,86,151,221,57,20,39,140,62,237,38,73,188,220,185,101,70,184,96,126,5,92,177,168,10,78,159,85,154,214,218,253,143,195,19,113,194,123,163,47,193,110,211,150,99,225,126,35,168,149,153,65,179, -252,157,35,190,195,59,239,110,251,54,241,254,155,240,137,137,2,0,201,49,188,230,144,103,243,45,71,190,125,214,127,44,218,117,198,215,23,222,167,53,242,53,209,160,242,77,188,104,3,33,250,200,109,182,237,135,110,103,3,172,155,126,37,92,62,231,139,80,105, -168,205,168,227,81,54,187,146,109,116,153,192,222,111,97,93,6,105,203,97,154,47,64,155,12,209,92,1,154,60,152,141,203,4,98,88,132,89,107,235,64,107,76,110,104,20,157,83,255,90,135,57,59,141,62,177,250,52,180,79,55,106,224,231,150,27,97,221,156,114,214, -147,159,26,253,162,12,21,53,98,44,10,123,39,222,100,19,58,45,1,147,106,225,126,38,218,137,224,165,253,252,59,223,28,187,119,239,3,157,63,247,89,67,1,124,82,162,0,64,114,152,67,143,245,62,63,114,216,118,248,194,91,87,60,48,99,85,249,149,97,175,72,30,150, -74,119,244,74,44,11,208,222,1,52,97,169,193,178,7,46,158,245,89,184,112,214,103,20,157,65,174,20,149,11,106,216,182,234,115,103,130,99,200,6,19,45,35,48,78,196,128,99,208,10,33,79,144,125,31,42,6,56,234,41,102,184,30,160,201,158,250,34,61,44,190,252, -148,164,223,235,130,186,10,56,117,70,9,52,79,120,192,152,5,149,20,180,92,143,122,249,244,103,161,78,128,165,53,69,112,238,220,114,184,136,120,251,107,166,151,144,63,203,236,239,208,96,221,3,91,135,159,99,115,56,180,42,101,247,31,135,150,247,5,221,145, -161,189,127,238,248,126,211,198,161,215,241,201,152,127,104,226,105,26,183,26,137,68,96,201,146,37,48,52,52,132,103,33,77,208,100,159,117,223,89,114,203,170,235,230,253,138,78,4,22,195,234,181,244,150,226,34,241,196,194,48,163,112,46,92,58,251,115,176, -110,250,229,228,1,167,207,130,168,137,27,44,29,227,48,78,4,129,173,199,12,126,155,7,232,240,37,22,29,32,222,83,38,86,20,68,124,97,88,249,217,181,112,250,55,206,83,228,253,118,15,58,224,107,27,91,88,231,187,76,11,134,196,200,243,139,134,246,169,151,79, -59,241,85,21,232,96,101,109,17,75,230,163,134,159,10,0,109,22,68,112,104,171,109,106,248,59,28,245,108,249,73,167,226,189,193,241,26,208,18,227,111,106,180,63,183,243,158,182,91,45,221,158,73,124,26,166,143,13,27,54,192,77,55,221,132,2,0,73,15,243,214, -213,156,122,254,15,150,61,80,181,176,228,220,136,79,141,104,192,223,161,225,205,104,60,2,243,138,151,194,101,115,62,199,250,7,208,220,129,108,128,46,11,56,134,172,108,48,17,157,73,224,26,177,179,62,3,113,98,124,50,69,16,68,67,81,150,248,119,217,157,215, -17,15,79,57,35,242,203,237,125,240,208,161,17,40,51,164,55,104,120,220,224,71,143,149,180,210,82,197,186,10,35,235,197,127,206,156,50,22,173,152,94,172,207,154,123,143,122,250,239,142,190,8,77,214,253,76,36,39,38,246,169,39,88,104,59,223,104,72,154,60, -250,84,255,79,142,60,217,255,20,205,21,65,80,0,160,0,200,247,104,64,177,86,183,238,255,46,254,241,170,235,231,254,140,184,32,70,53,163,1,204,80,197,194,108,121,96,126,233,10,184,116,246,245,176,182,250,66,214,105,48,155,160,21,5,116,137,128,138,1,123, -159,25,220,99,78,8,121,2,32,145,135,42,71,188,78,238,152,32,72,85,66,161,72,140,127,97,117,49,92,122,199,167,161,116,86,133,178,247,43,17,57,255,181,185,3,222,232,178,64,105,138,68,0,125,52,73,199,12,190,24,35,199,148,28,71,250,217,115,202,140,112,202, -180,98,214,160,135,134,245,235,202,141,105,239,195,63,85,70,188,61,196,240,191,196,150,198,34,228,94,160,235,252,26,21,13,255,9,175,191,193,254,202,238,251,58,110,157,108,119,225,131,23,5,0,10,0,228,159,162,1,167,159,255,253,101,127,172,90,84,114,190, -210,205,131,62,242,58,32,15,191,248,9,33,112,3,17,2,231,103,77,68,224,159,4,129,195,207,162,2,54,34,6,236,3,22,112,143,58,200,159,249,152,87,78,187,204,208,222,3,52,135,128,78,47,84,52,177,144,38,187,5,195,80,54,171,18,46,184,237,83,80,62,183,82,149, -239,71,59,227,221,250,86,23,188,218,110,102,9,116,74,26,221,227,198,158,118,224,163,27,253,127,131,150,131,170,2,45,204,43,47,96,97,125,234,221,175,168,45,134,57,165,134,172,51,248,31,52,252,219,198,18,57,49,180,169,143,218,134,63,225,245,11,228,26,20, -39,234,159,238,255,201,225,39,250,159,70,175,31,5,0,10,0,228,95,69,3,248,117,223,94,124,243,170,235,230,222,65,172,113,169,24,82,127,220,247,7,133,0,77,22,92,91,125,1,8,156,54,171,143,35,245,200,125,22,15,56,137,40,160,101,134,180,236,144,118,39,12,186, -252,16,13,70,217,210,1,125,246,127,80,20,76,73,24,144,91,87,140,136,204,122,206,57,123,33,156,245,173,11,192,88,94,168,234,119,162,79,139,251,15,12,195,67,135,134,193,75,174,139,2,29,7,252,20,34,28,84,79,210,48,190,116,204,208,211,223,83,207,222,72,140, -125,185,81,203,188,251,69,149,133,176,172,166,136,108,133,196,187,47,128,202,2,109,214,223,83,253,158,118,150,12,219,98,59,64,12,127,16,244,156,129,213,244,171,9,39,104,64,208,243,96,106,114,60,179,231,79,29,183,79,118,184,198,240,233,134,2,0,5,0,114, -82,204,60,181,114,217,39,190,183,244,247,51,215,84,92,163,70,223,128,143,19,2,177,184,4,115,139,23,195,5,51,175,101,57,2,106,102,66,167,26,26,13,8,218,125,224,153,116,129,107,196,1,158,113,39,75,52,164,203,9,33,111,8,196,96,132,181,44,102,150,86,147, -16,4,116,57,225,120,43,62,122,191,198,99,177,19,109,141,171,22,77,131,101,87,175,129,185,68,0,164,146,118,179,15,30,62,60,2,59,251,137,184,33,98,134,138,0,129,238,43,221,79,77,66,41,80,143,254,184,177,167,80,175,157,86,18,148,234,5,214,101,112,22,241, -228,23,84,20,16,131,95,0,117,228,231,172,18,3,84,228,128,177,255,32,29,142,163,176,211,244,26,155,153,145,8,245,27,88,27,109,117,159,234,199,50,252,157,145,158,131,143,244,252,164,245,149,225,215,82,113,239,34,40,0,80,0,228,24,212,131,56,253,107,11,190, -118,218,151,234,238,212,23,107,231,70,2,98,194,56,169,109,40,99,17,98,64,162,48,173,96,46,156,59,253,74,56,103,218,101,80,166,175,202,217,227,28,9,132,33,228,10,130,223,230,5,159,213,3,126,139,135,252,244,38,132,129,39,200,234,250,169,93,229,137,241, -44,172,44,130,202,133,181,48,99,205,92,168,89,58,61,173,251,61,224,8,176,42,129,35,99,110,24,38,251,239,9,137,236,242,160,98,128,122,244,53,133,58,152,73,12,253,76,98,220,231,150,25,96,6,249,89,91,164,135,10,242,119,185,218,94,152,94,187,180,107,223, -238,241,215,161,215,213,66,174,99,233,152,225,215,164,228,126,229,120,77,164,115,171,233,254,131,27,186,239,114,155,2,78,124,138,161,0,64,1,128,36,69,213,130,226,234,115,190,189,248,127,23,92,56,253,59,113,41,198,139,225,212,172,35,178,170,1,242,64,45, -55,84,195,233,53,23,50,49,48,187,104,97,94,29,123,41,34,130,36,74,204,124,112,90,33,99,39,27,82,143,63,16,137,17,1,16,103,17,129,66,93,126,77,96,244,68,28,112,200,188,29,14,78,190,195,250,245,83,131,175,229,245,41,49,252,199,147,252,172,61,158,157,196, -240,255,180,111,231,228,97,124,106,161,0,64,1,128,40,202,162,139,167,175,35,66,224,174,170,5,37,23,68,137,183,23,19,83,115,253,80,47,42,34,133,216,114,192,242,138,51,224,19,68,8,172,168,60,131,24,26,236,101,133,164,23,58,154,247,224,196,59,112,212,178, -27,236,161,73,150,187,146,232,134,153,138,39,120,34,220,31,114,71,71,27,95,28,252,101,195,115,3,143,71,252,34,198,251,81,0,156,20,248,244,68,166,68,239,142,137,3,195,135,172,23,157,254,149,5,223,92,117,195,220,255,49,150,233,230,210,118,194,106,87,11, -240,108,206,64,33,241,45,99,208,104,221,3,77,182,125,48,167,104,17,156,53,237,18,86,66,88,97,168,193,147,131,164,206,129,33,98,180,213,126,136,121,251,93,206,70,8,138,126,208,17,111,63,149,249,42,130,129,167,249,33,225,222,237,19,15,30,220,208,243,59, -251,128,215,130,103,6,65,1,128,168,251,240,35,30,198,129,245,221,143,183,191,62,186,101,221,119,150,220,182,240,226,105,223,19,244,124,161,26,115,5,254,217,225,225,88,233,212,113,207,107,176,167,19,222,30,126,1,78,169,60,155,136,129,75,97,113,217,106, -38,22,16,68,13,198,253,67,112,196,178,19,26,136,183,63,238,31,6,154,16,147,106,195,79,167,246,209,181,254,137,22,199,235,71,158,232,255,69,223,238,201,6,60,51,136,172,231,41,46,1,32,201,50,235,180,202,229,68,8,252,124,198,234,138,47,210,210,54,49,197, -99,68,105,213,0,205,176,22,52,2,204,46,94,8,107,107,46,132,211,170,206,131,154,130,89,120,114,144,164,241,139,94,104,35,222,254,17,243,14,232,113,53,131,63,234,101,33,254,84,151,169,210,178,62,26,238,183,15,250,26,27,95,24,252,69,251,150,145,45,169,202, -197,65,212,3,115,0,144,156,96,197,53,179,47,62,253,107,11,126,94,89,87,124,33,237,36,40,69,83,251,112,162,201,103,52,105,144,110,197,186,82,88,84,182,10,78,175,185,8,150,87,156,14,197,218,50,60,65,200,73,35,198,69,232,119,181,194,81,235,110,102,252,173, -193,9,150,202,71,123,244,107,82,220,177,146,150,130,234,10,120,240,217,194,67,29,111,140,221,93,255,108,255,99,65,39,121,128,34,40,0,146,4,151,0,16,197,104,127,125,116,71,239,246,137,29,203,175,154,245,185,83,191,84,119,123,197,188,162,83,105,217,96, -170,18,5,89,214,53,241,204,232,22,145,34,172,191,122,163,117,31,27,67,76,69,192,169,213,231,193,162,210,85,57,213,87,0,81,86,64,14,123,186,161,201,182,31,90,236,239,195,184,111,144,85,160,208,16,191,225,216,178,83,170,13,63,235,221,31,148,108,29,111, -154,30,56,248,72,207,95,220,99,126,7,158,41,4,5,0,146,145,80,131,223,180,113,104,99,207,246,137,45,167,125,185,238,235,203,175,158,125,107,81,181,97,113,52,152,58,33,64,161,115,5,142,231,10,120,34,78,216,59,254,38,236,159,120,27,170,13,51,136,24,88,11, -171,170,214,193,162,178,83,84,155,179,142,100,7,116,30,133,201,63,0,45,182,131,208,74,140,254,136,183,15,194,82,144,133,247,143,111,169,183,252,0,58,214,190,87,242,118,110,29,219,208,248,252,224,159,205,157,238,81,60,91,136,226,151,26,46,1,32,106,82, -60,205,88,188,250,250,185,55,18,33,240,125,34,4,230,167,178,116,240,163,160,161,93,81,138,0,199,241,80,99,156,1,139,203,214,192,41,149,103,193,66,34,6,112,153,32,63,160,94,253,136,183,151,133,246,219,29,71,136,0,24,132,144,24,32,198,94,32,155,46,37,117, -251,31,103,248,181,6,158,118,125,12,14,236,49,63,121,232,177,158,123,137,225,239,197,51,150,219,96,14,0,146,15,66,160,116,245,13,243,190,189,226,234,89,223,45,172,50,204,77,183,16,56,33,6,136,49,160,149,5,21,134,106,168,43,89,14,43,42,78,103,162,160, -22,19,8,115,10,111,196,5,3,158,14,98,240,15,179,68,62,115,96,12,34,82,248,132,151,159,54,163,15,137,80,63,45,233,131,88,60,56,86,111,127,166,254,249,193,251,6,247,153,59,240,172,161,0,64,1,128,228,154,16,40,95,125,253,220,175,46,191,102,246,127,23,85, -27,22,166,122,105,224,227,160,141,134,168,24,160,235,192,133,66,49,204,44,170,99,66,96,73,249,26,214,111,160,80,91,130,39,47,139,160,137,160,180,100,175,215,221,2,93,142,70,24,246,118,131,43,108,99,21,35,212,203,231,137,183,159,78,163,127,220,240,211, -53,254,72,64,244,142,55,57,158,109,222,56,252,192,0,26,126,20,0,40,0,144,60,16,2,37,171,111,152,251,229,229,87,207,254,175,162,42,195,74,49,34,129,20,201,140,146,38,186,46,44,198,163,32,197,68,230,29,150,235,171,97,78,241,34,86,85,176,176,116,37,204, -40,156,119,34,191,0,129,140,57,103,150,160,137,24,250,46,232,118,54,195,160,167,147,253,63,13,237,211,124,16,102,244,51,164,63,4,107,219,203,12,191,100,239,219,57,249,100,195,243,3,15,89,186,220,125,120,22,81,0,160,0,64,242,75,8,212,26,13,11,47,154,118, -253,170,207,206,249,110,229,130,146,117,146,72,140,111,88,74,201,192,161,147,35,126,44,58,16,101,70,134,14,117,169,48,212,194,172,162,5,176,160,116,5,212,149,44,133,105,5,115,160,72,91,138,39,51,149,207,143,88,24,44,1,106,240,123,136,177,239,128,33,79, -55,51,248,196,153,102,127,47,104,180,25,225,229,127,200,240,11,28,51,252,62,75,112,116,232,128,245,177,166,141,67,143,17,195,143,35,122,81,0,96,25,32,146,159,120,205,193,80,227,11,131,207,182,111,25,125,118,249,85,179,174,88,122,197,204,255,154,182,162, -236,83,26,226,182,69,67,234,183,24,62,9,141,204,230,13,240,188,112,76,14,196,193,22,156,0,115,96,148,53,134,209,242,58,40,213,85,194,116,34,2,102,23,47,130,121,197,75,88,132,128,150,30,234,136,88,64,148,144,96,113,112,134,173,48,233,31,129,17,95,47,43, -213,163,137,123,142,144,5,66,82,128,253,27,122,142,104,35,168,140,171,234,32,250,67,208,113,204,248,123,38,130,205,221,239,152,30,109,222,52,252,28,185,238,177,156,15,73,59,40,0,144,204,240,232,18,229,131,111,55,109,26,122,123,193,249,211,78,95,113,237, -236,155,230,156,81,121,131,190,72,91,193,242,4,50,100,158,57,245,40,89,226,24,104,79,24,39,58,5,206,73,140,17,237,13,79,195,205,180,207,0,29,93,92,107,156,77,68,193,2,152,89,56,159,37,21,210,121,5,5,66,49,158,236,127,227,217,187,195,118,230,205,155,124, -3,48,70,182,201,192,8,216,66,19,172,3,31,141,196,208,99,204,68,25,39,100,108,25,39,91,223,55,240,16,139,197,99,246,126,239,123,173,175,141,172,39,198,255,141,144,39,26,197,179,140,160,0,64,144,143,118,247,160,127,247,228,81,186,77,91,81,246,171,37,151, -207,252,210,146,79,206,248,122,97,181,126,5,77,22,204,172,229,129,132,32,248,96,132,128,66,115,7,104,120,122,194,63,12,13,214,61,39,122,18,20,235,202,88,100,160,198,56,11,166,21,204,102,173,138,171,13,211,161,68,95,193,150,16,50,41,92,173,54,116,109, -222,19,117,130,61,56,9,214,208,56,57,86,35,44,170,66,167,233,185,35,118,54,92,71,36,199,81,163,57,118,124,53,252,137,38,79,153,12,175,229,88,175,254,176,79,180,145,107,248,229,246,55,198,30,27,220,111,57,18,19,177,101,47,130,2,0,65,78,154,201,118,215, -24,217,238,57,250,84,223,253,139,46,158,254,169,37,151,205,252,70,237,242,210,203,4,29,103,160,131,135,50,37,42,240,79,162,128,38,157,209,13,180,31,208,53,113,150,133,110,15,153,217,244,56,154,123,67,141,26,93,38,40,212,22,67,137,174,130,37,27,82,129, -64,55,250,123,186,21,17,209,80,164,45,33,2,162,32,107,134,28,209,137,141,180,196,206,23,245,128,95,244,144,239,109,103,223,157,46,157,56,194,102,22,186,167,94,62,253,123,26,194,167,94,61,133,35,223,143,126,71,142,25,123,61,219,178,1,42,82,4,3,199,188, -126,183,41,208,208,187,115,226,201,246,45,163,27,29,131,190,9,188,139,17,20,0,8,146,4,126,91,56,220,244,210,208,171,205,155,134,95,157,177,186,98,233,178,43,102,126,121,254,121,53,95,44,170,49,46,138,209,225,67,52,87,32,195,39,160,159,136,20,104,132, -127,48,150,116,9,193,197,140,228,144,167,139,9,3,250,43,145,185,174,101,73,135,6,190,16,10,180,69,172,81,17,141,20,208,173,88,151,248,61,93,82,40,20,138,192,72,54,42,38,244,124,194,112,106,201,79,186,38,206,49,131,202,177,159,199,247,227,223,27,112,242, -43,30,99,73,143,180,108,142,38,65,70,99,97,136,196,34,108,12,46,13,211,135,136,135,30,16,125,224,167,70,62,234,5,111,212,77,54,39,248,34,110,98,216,221,108,128,14,245,226,195,196,211,143,30,171,168,56,110,44,143,27,122,218,127,65,75,190,99,166,123,245, -31,115,66,129,23,18,83,249,34,1,209,49,114,196,246,70,231,155,99,79,15,236,179,236,12,123,163,18,222,181,8,10,0,4,81,210,179,140,197,193,212,104,239,34,219,255,20,62,98,248,237,162,139,166,125,114,193,133,211,190,50,99,85,249,101,58,163,80,202,6,16,209, -80,107,60,123,190,83,66,24,240,31,233,221,83,67,76,103,26,132,137,209,117,133,173,9,131,12,137,80,242,241,234,157,132,113,39,222,39,121,61,53,248,44,63,225,88,6,60,21,27,58,98,92,57,46,241,147,190,130,14,179,161,255,62,254,15,7,137,238,71,226,243,194, -240,247,202,135,8,49,252,137,225,74,18,107,154,36,178,242,200,68,69,132,116,66,36,28,127,47,106,220,169,81,63,177,79,244,23,249,169,211,16,79,62,75,188,249,127,7,157,200,71,141,126,92,138,199,157,35,254,3,61,219,39,94,24,216,61,249,170,185,203,109,194, -59,20,65,1,128,32,41,137,10,132,130,77,27,135,182,208,173,118,121,217,156,249,231,213,126,122,241,165,211,63,95,54,187,240,28,242,144,230,197,16,49,78,89,190,238,154,48,160,212,99,231,224,95,59,238,9,19,124,220,128,71,32,116,194,40,31,143,40,36,84,81, -194,200,255,171,112,73,226,243,78,124,58,253,131,99,31,173,57,254,39,199,146,240,56,128,60,201,89,96,157,250,244,28,59,54,62,107,168,119,172,97,242,53,226,237,191,100,106,118,28,165,75,81,8,130,2,0,65,210,132,185,195,53,66,182,7,142,62,213,247,192,140, -213,21,107,136,24,184,110,254,39,106,62,93,50,163,96,21,181,119,180,201,80,38,116,27,84,87,42,252,163,1,63,241,87,72,18,70,159,227,57,8,186,34,227,227,205,142,173,93,239,140,111,28,58,104,217,19,176,135,131,120,132,16,20,0,8,146,65,80,111,108,248,125, -107,19,221,222,127,84,119,231,156,51,170,206,92,112,193,180,107,103,174,169,184,170,168,218,176,146,26,67,218,109,48,219,150,9,144,20,25,125,94,147,168,217,39,63,131,238,168,217,212,228,216,62,184,215,188,105,232,160,117,151,107,204,239,196,35,132,160, -0,64,144,44,32,232,140,136,221,239,142,31,160,91,65,185,238,231,179,207,168,58,131,8,130,171,103,172,174,184,162,108,78,225,26,242,144,215,72,209,24,196,200,22,71,49,144,167,22,63,209,150,87,208,241,76,15,134,92,145,81,83,3,49,250,251,204,155,135,222, -183,238,117,141,250,237,120,144,16,20,0,8,146,197,4,156,145,232,113,49,160,53,242,119,204,88,85,177,122,193,5,181,159,156,190,170,252,138,138,185,69,103,234,10,132,66,42,4,152,32,144,80,13,228,180,205,231,52,137,90,125,178,145,243,29,247,89,67,29,19, -45,206,247,250,247,76,190,57,222,236,60,228,53,7,189,120,148,16,20,0,8,146,131,68,131,82,108,248,144,181,145,110,196,251,187,187,122,113,233,188,185,103,85,157,63,107,109,229,39,171,23,151,156,107,44,211,213,81,35,193,4,129,24,207,128,86,196,72,178,94, -62,45,215,163,205,121,104,126,68,200,19,113,216,7,188,71,71,143,218,223,29,61,106,219,110,238,112,181,133,60,81,17,15,20,130,2,0,65,242,8,234,237,155,59,93,67,116,59,252,68,223,83,197,53,134,130,234,37,165,107,230,173,171,190,104,218,242,178,11,203,102, -23,158,170,47,214,86,178,127,43,210,8,1,10,130,140,183,247,180,112,129,167,30,190,134,37,240,17,47,63,228,54,249,59,38,219,93,251,198,91,156,59,136,225,63,228,26,245,79,226,121,68,16,20,0,8,114,2,175,37,20,32,219,129,129,189,230,3,26,78,243,155,178,89, -5,181,181,203,203,78,155,177,186,226,188,218,229,165,231,150,207,42,92,161,47,33,130,64,3,172,170,128,70,9,98,212,144,160,45,73,159,193,231,52,172,54,159,122,249,244,188,136,97,41,24,176,135,186,173,189,222,131,19,45,142,61,227,173,174,163,214,30,119, -95,196,143,78,62,130,160,0,64,144,147,128,122,136,206,17,191,153,108,91,187,222,54,109,165,225,227,210,89,5,53,181,203,74,87,17,65,112,118,229,252,162,179,43,235,138,79,33,130,96,182,160,227,53,244,223,211,234,130,24,46,27,168,107,236,249,132,193,167, -63,227,49,128,144,55,98,115,141,132,58,109,3,222,195,227,77,142,131,230,78,87,163,219,20,24,12,121,162,120,18,16,4,5,0,130,40,32,8,226,113,112,141,250,45,100,219,214,253,238,248,54,250,103,69,53,134,162,178,217,133,11,103,172,42,95,93,181,176,120,109, -249,220,226,53,197,181,134,197,134,98,109,45,53,82,180,186,128,69,10,136,48,160,162,0,171,13,78,214,210,3,112,196,216,211,178,60,142,255,187,177,39,94,188,199,109,14,14,146,115,208,102,235,243,28,181,116,121,26,172,189,158,78,207,120,192,138,201,155, -8,130,2,0,65,82,134,207,18,242,145,173,105,172,222,222,68,254,247,73,106,244,139,170,141,21,21,117,133,117,53,139,75,87,150,204,44,56,165,106,126,241,138,226,233,198,133,250,98,237,76,157,158,55,82,163,70,141,21,21,4,9,97,0,121,27,49,160,30,61,109,40, -72,215,234,143,255,164,66,75,138,198,164,176,55,106,38,199,118,208,103,13,117,90,123,60,45,150,110,119,171,99,200,215,235,157,12,142,71,131,104,237,17,4,5,0,130,100,16,212,219,247,76,4,28,116,27,58,96,173,63,254,231,5,21,122,67,201,116,227,180,226,105, -198,186,202,249,197,75,43,235,138,150,24,203,117,139,74,103,22,206,209,26,249,25,250,34,109,57,17,15,26,106,16,227,82,252,88,228,32,209,159,32,17,57,56,102,239,178,105,198,193,177,14,132,52,33,143,254,158,138,35,250,27,234,217,179,89,3,116,180,115,72, -242,134,60,81,139,215,28,26,11,185,34,189,182,126,111,47,241,238,187,220,166,192,128,115,196,63,26,116,133,221,185,221,193,17,65,80,0,32,72,78,19,112,132,67,100,27,154,108,119,13,245,110,159,216,121,252,207,245,197,90,222,88,170,171,40,172,54,204,168, -152,91,56,147,252,127,93,213,130,226,217,186,66,97,94,217,156,194,105,188,150,155,110,44,211,149,11,122,190,152,136,3,3,45,101,75,180,242,255,123,226,33,253,253,7,141,36,251,43,137,206,64,248,168,30,192,39,177,12,161,249,184,137,129,241,99,30,187,230, -67,30,60,13,207,159,120,29,75,193,63,81,49,33,17,241,226,241,91,67,110,242,211,236,28,245,155,137,231,62,108,235,245,140,68,2,226,144,173,207,75,12,124,196,228,179,4,109,33,111,52,132,137,148,8,146,103,2,192,235,197,158,27,72,254,66,199,198,146,205,234, -26,243,91,77,141,246,230,143,248,39,58,190,2,138,180,70,168,48,148,232,42,202,231,20,86,199,164,120,109,113,141,161,178,100,102,65,53,49,177,85,134,18,109,25,249,125,105,92,130,98,242,239,139,5,3,103,44,252,255,236,221,75,106,194,64,0,128,225,104,226, -139,90,104,233,190,208,131,120,75,47,215,19,20,173,90,84,218,196,81,155,206,152,62,20,234,174,208,133,223,7,1,5,31,193,133,243,79,72,50,119,189,126,28,232,211,26,187,157,163,173,125,184,235,93,63,63,123,36,33,141,223,233,102,72,187,240,189,136,82,136, -91,90,237,38,196,193,61,196,125,173,226,140,61,45,23,184,110,229,217,186,92,132,213,122,82,46,227,27,103,241,125,207,211,199,229,60,126,196,244,117,182,153,174,158,222,94,222,247,217,60,76,178,101,124,189,123,231,195,25,33,132,203,11,128,162,40,178,241, -120,44,2,224,183,249,118,115,121,97,136,3,254,34,62,94,52,51,251,250,103,182,253,57,19,79,119,180,235,118,138,172,46,234,230,105,63,239,12,175,6,131,56,213,79,235,239,118,143,182,162,119,221,105,223,222,15,135,231,206,57,72,231,39,196,25,123,21,7,245, -144,53,153,80,197,45,93,63,183,137,223,183,41,119,161,42,55,135,127,171,109,154,237,239,110,246,217,182,191,255,58,64,144,213,15,205,145,137,195,145,130,188,217,209,188,104,157,236,47,112,106,52,26,253,219,119,183,106,167,38,3,192,197,105,251,9,0,64, -0,0,0,2,0,0,16,0,0,128,0,0,0,4,0,0,32,0,0,0,1,0,0,8,0,0,64,0,0,0,2,0,0,16,0,0,128,0,0,0,4,0,0,32,0,0,0,1,0,0,8,0,0,64,0,0,128,0,0,0,4,0,0,32,0,0,0,1,0,0,8,0,0,64,0,0,0,2,0,0,16,0,0,128,0,0,0,4,0,0,32,0,0,128,191,246,33,192,0,100,235,173,153,70,62,64, -37,0,0,0,0,73,69,78,68,174,66,96,130,0,0 }; +{ 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,2,0,0,0,2,0,8,6,0,0,0,244,120,212,250,0,0,0,9,112,72,89,115,0,0,14,195,0,0,14,195,1,199,111,168,100,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,119,119,119,46,105,110,107,115,99,97,112,101, +46,111,114,103,155,238,60,26,0,0,0,20,116,69,88,116,84,105,116,108,101,0,74,85,67,69,32,83,76,73,67,69,32,82,71,66,103,97,100,162,0,0,32,0,73,68,65,84,120,156,236,221,119,120,21,85,250,7,240,239,153,185,53,189,19,122,8,189,132,142,34,29,1,21,233,37,1, +68,20,221,93,123,69,93,138,174,230,231,170,16,96,81,177,187,174,74,177,16,138,5,36,148,20,154,10,10,136,66,2,2,161,183,36,164,39,183,223,57,191,63,98,20,148,114,203,153,153,91,206,231,121,124,220,135,205,188,231,53,36,247,125,103,230,20,2,142,227,124, +90,122,222,32,141,86,140,137,215,217,72,188,4,161,129,68,104,20,8,137,38,160,81,20,66,20,1,141,34,160,81,18,72,40,1,66,8,65,40,165,208,1,136,4,32,2,136,250,83,200,48,0,218,63,253,153,29,64,205,159,254,172,2,20,14,16,84,17,2,27,165,168,165,128,73,0,173, +165,32,21,20,164,130,64,170,160,32,21,160,180,92,160,164,66,128,84,100,211,209,146,214,23,196,226,180,180,149,78,121,190,35,28,199,177,64,212,78,128,227,130,217,162,13,169,49,78,141,212,132,138,164,153,36,145,166,148,144,166,0,109,66,128,198,4,72,160, +64,2,128,120,248,223,239,42,5,80,66,128,98,10,20,81,224,28,1,61,13,74,206,8,2,61,77,156,244,148,232,16,206,204,184,109,101,153,218,137,114,92,176,242,183,15,21,142,243,43,148,130,188,188,109,114,19,173,93,106,69,9,90,129,160,21,64,91,2,104,245,219,63, +161,42,167,168,182,26,0,133,0,142,18,74,143,74,2,142,2,56,234,20,52,133,207,14,248,252,12,33,160,42,231,199,113,1,139,55,0,28,199,72,198,166,201,141,36,173,212,129,128,118,36,20,29,0,116,164,64,103,0,225,106,231,230,167,172,0,10,9,33,249,146,132,2,64, +202,39,132,22,88,182,165,28,76,79,79,151,212,78,142,227,252,29,111,0,56,206,77,233,121,131,52,6,26,219,22,32,61,40,208,131,128,116,0,208,29,64,140,218,185,5,137,26,2,252,12,32,159,18,20,0,216,99,65,232,238,244,193,31,91,212,78,140,227,252,9,111,0,56, +238,58,94,201,158,212,70,36,210,141,148,208,27,1,114,35,128,20,0,122,181,243,226,46,99,5,176,31,160,187,8,37,187,156,84,216,53,103,232,138,195,106,39,197,113,190,140,55,0,28,119,137,244,181,163,66,244,33,134,222,132,160,31,8,122,131,226,70,240,59,123, +127,85,74,128,93,20,216,69,36,178,93,27,66,119,206,232,179,210,172,118,82,28,231,43,120,3,192,5,181,5,27,167,133,58,116,214,155,32,161,31,33,180,47,128,126,0,12,106,231,197,201,194,1,224,103,66,105,54,133,240,173,94,176,109,127,114,240,151,21,106,39, +197,113,106,225,13,0,23,84,210,243,6,105,116,52,225,70,66,49,140,16,58,12,192,13,0,52,106,231,197,169,194,1,224,7,74,201,102,2,105,147,69,184,248,67,250,224,45,14,181,147,226,56,165,240,6,128,11,120,115,179,39,36,19,81,28,14,74,135,1,24,12,32,66,237, +156,56,159,84,9,138,60,66,232,102,73,162,27,102,15,93,125,76,237,132,56,78,78,188,1,224,2,78,102,102,170,88,24,135,174,160,100,20,33,116,36,128,30,106,231,196,249,165,99,20,116,29,136,176,54,38,60,106,235,253,61,223,183,171,157,16,199,177,196,27,0,46, +32,44,216,56,45,84,210,89,134,83,137,142,1,33,195,1,196,170,157,19,23,80,74,65,105,22,17,200,87,230,26,203,250,244,81,107,77,106,39,196,113,222,226,13,0,231,183,210,215,142,10,49,132,24,135,80,66,83,9,48,14,117,123,220,115,156,220,44,148,34,155,16,186, +18,78,242,213,172,97,43,43,213,78,136,227,60,193,27,0,206,175,100,236,24,29,78,109,186,113,0,73,3,48,20,124,61,62,167,46,43,165,216,44,0,153,208,91,191,156,217,239,235,106,181,19,226,56,87,241,6,128,243,121,153,153,169,98,97,60,25,12,74,239,226,119,250, +156,15,179,80,138,108,128,46,181,150,146,175,210,211,86,218,212,78,136,227,174,133,55,0,156,207,154,151,151,218,15,148,222,5,144,137,0,162,213,206,135,227,220,80,70,128,85,78,144,165,115,110,206,252,86,237,100,56,238,74,120,3,192,249,148,151,183,141, +111,40,58,197,52,72,248,27,8,82,212,206,135,227,24,56,76,41,249,76,11,199,71,79,15,89,115,82,237,100,56,174,30,111,0,56,213,165,103,166,234,140,241,24,13,138,123,40,112,43,0,81,237,156,124,145,86,212,195,168,13,135,81,27,142,16,109,4,140,218,8,24,181, +97,48,106,195,97,208,132,66,20,180,208,107,66,32,18,13,116,26,35,52,130,14,154,223,254,140,128,64,167,49,66,32,215,254,214,218,157,22,56,37,7,236,146,181,238,223,78,43,156,212,241,251,159,219,156,22,88,236,53,176,56,234,254,49,219,107,96,113,212,194, +98,175,255,223,53,176,58,248,4,249,171,112,2,216,64,65,62,138,137,136,250,154,47,43,228,212,198,27,0,78,53,243,54,167,54,163,2,238,35,4,127,3,144,168,118,62,106,33,132,32,84,23,133,8,125,28,194,245,49,8,55,196,253,241,191,245,177,136,48,196,194,168,13, +135,70,208,169,157,170,75,28,146,29,213,214,82,212,90,203,81,101,189,136,26,107,5,170,173,165,168,182,150,161,198,86,142,42,203,69,84,91,203,0,80,181,83,85,211,5,74,241,63,34,225,253,89,195,86,158,82,59,25,46,56,241,6,128,83,84,122,122,186,96,232,127, +224,86,8,228,65,80,220,142,32,186,219,143,208,199,34,58,164,17,98,66,26,34,54,164,49,98,66,26,33,218,152,136,8,67,220,117,239,204,3,141,67,178,163,194,124,1,229,230,11,40,55,253,246,111,243,5,148,155,207,163,218,90,10,74,131,166,57,112,82,224,27,16,188, +99,221,218,113,83,122,122,186,164,118,66,92,240,224,13,0,167,136,244,245,83,35,140,122,235,189,148,144,71,1,36,171,157,143,156,194,245,177,72,8,75,66,131,240,36,196,133,54,69,76,72,67,196,24,27,65,43,242,21,139,174,112,74,118,148,154,206,161,164,230, +36,74,106,79,161,184,230,36,138,107,78,162,214,22,240,231,246,20,18,138,215,4,135,225,163,103,110,93,86,171,118,50,92,224,227,13,0,39,171,249,57,147,90,74,144,30,5,193,61,8,176,61,248,9,17,16,27,210,8,9,97,73,191,21,252,22,104,16,150,4,163,54,92,237, +212,2,146,201,94,133,226,154,147,40,249,173,33,56,95,117,20,101,230,115,129,248,180,160,140,82,188,35,10,120,243,159,131,87,94,80,59,25,46,112,241,6,128,147,197,252,220,212,129,18,240,36,128,81,0,4,181,243,97,193,168,13,71,163,136,54,104,18,217,22,141, +35,219,34,49,60,153,223,213,171,204,234,48,225,92,213,17,156,175,58,138,115,85,71,112,174,234,8,204,246,128,217,139,199,10,96,185,36,97,209,156,161,43,11,212,78,134,11,60,188,1,224,152,73,79,79,23,12,3,14,140,2,200,44,0,189,213,206,199,59,4,177,33,141, +208,56,178,13,26,71,182,67,227,200,54,136,13,105,4,254,43,227,251,202,205,231,113,174,234,40,206,86,30,194,201,242,124,148,153,206,169,157,146,183,40,1,178,32,145,133,51,135,102,230,169,157,12,23,56,248,167,25,231,181,244,204,84,157,62,30,119,16,9,255, +4,65,123,181,243,241,84,164,33,30,73,209,157,209,60,38,5,205,163,59,33,68,27,80,111,44,130,86,141,181,28,39,43,14,224,100,249,1,156,42,63,128,74,75,137,218,41,121,99,47,165,100,161,85,40,94,153,62,120,139,67,237,100,56,255,198,27,0,206,99,233,153,169, +58,99,28,253,59,64,102,81,160,169,218,249,184,203,160,9,69,179,232,78,72,138,78,65,82,76,10,162,141,13,213,78,137,83,64,165,165,24,39,203,243,113,178,124,63,142,151,253,236,151,175,12,40,112,18,148,204,179,150,210,15,249,150,195,156,167,120,3,192,185, +45,61,111,144,198,136,248,187,37,138,127,17,160,185,218,249,184,163,65,88,11,180,138,235,137,150,177,221,144,24,158,12,66,2,98,122,2,231,33,74,37,156,173,58,130,194,210,189,40,44,221,139,146,26,191,219,168,239,4,161,244,69,179,112,113,25,127,34,192,185, +139,55,0,156,203,210,211,211,5,125,255,3,19,8,33,47,1,104,163,118,62,174,32,68,64,227,136,214,104,25,215,19,109,227,111,224,119,249,220,53,213,218,42,113,188,108,31,10,75,247,226,88,233,62,216,156,102,181,83,114,213,9,10,204,109,121,17,255,75,75,91,233, +84,59,25,206,63,240,6,128,187,174,186,201,125,5,19,65,105,186,63,188,227,215,107,140,72,142,233,134,86,113,189,208,50,182,43,244,154,80,181,83,226,252,144,221,105,197,241,178,125,56,84,252,61,142,150,238,129,221,105,85,59,37,87,20,80,74,211,103,221,188, +106,21,33,193,189,213,34,119,125,188,1,224,174,105,110,94,218,80,66,105,6,128,238,106,231,114,45,26,65,139,230,209,157,209,46,161,55,218,198,247,230,203,243,56,166,28,146,29,39,202,126,193,161,146,239,113,164,228,71,127,120,50,144,79,41,253,63,222,8, +112,215,194,27,0,238,138,230,229,76,28,14,66,94,4,208,83,237,92,174,70,32,34,146,98,58,163,67,66,95,180,142,239,5,157,104,84,59,37,46,8,216,157,86,20,150,238,197,161,226,239,81,88,186,23,14,201,135,231,224,17,252,72,129,231,103,15,94,185,65,237,84,56, +223,195,27,0,238,50,243,115,38,117,151,136,244,31,0,131,212,206,229,202,8,154,68,182,69,135,6,125,209,46,161,15,223,117,143,83,149,213,97,194,161,226,239,177,255,194,22,156,173,252,85,237,116,174,37,219,73,132,39,159,29,188,226,128,218,137,112,190,131, +55,0,28,0,224,165,156,212,198,90,130,231,41,240,55,248,224,1,61,161,186,40,164,36,14,68,231,70,67,16,109,12,218,131,3,57,31,86,102,58,143,130,162,29,56,112,97,43,42,45,197,106,167,115,37,18,5,62,209,216,29,79,63,115,235,23,62,153,32,167,44,222,0,4,185, +244,188,212,48,3,200,76,80,58,3,64,136,218,249,92,138,16,1,201,49,93,209,165,209,16,180,140,237,30,116,39,230,113,254,137,82,9,39,202,247,227,192,133,45,56,92,242,3,28,146,93,237,148,254,172,12,148,166,91,132,139,239,240,165,131,193,141,55,0,65,108,94, +78,218,40,16,250,38,128,102,106,231,114,169,112,125,12,58,54,232,143,174,141,111,65,164,33,94,237,116,56,206,99,86,135,9,251,47,108,193,158,51,89,168,48,23,169,157,206,159,29,6,48,99,214,205,43,191,81,59,17,78,29,188,1,8,66,243,114,39,117,161,68,122, +131,80,244,87,59,151,63,16,180,136,233,140,158,77,110,71,139,152,174,32,132,255,104,114,129,131,82,138,99,101,63,97,239,217,141,56,94,182,207,167,78,48,164,20,235,40,21,158,154,51,116,197,97,181,115,225,148,197,63,101,131,200,171,121,99,163,44,84,243, +127,4,228,33,0,26,181,243,1,234,150,239,181,77,184,9,189,155,141,65,92,168,223,237,38,204,113,110,171,48,23,225,231,115,217,248,249,124,174,47,109,67,108,167,160,239,16,39,121,126,214,176,149,149,106,39,195,41,131,55,0,65,128,82,144,249,185,169,119,82, +130,255,0,240,137,103,234,17,134,120,116,111,124,43,186,52,26,2,3,223,168,231,47,168,195,2,201,84,14,56,237,32,90,3,136,49,26,68,212,170,157,150,107,168,3,146,181,20,144,108,0,17,65,116,209,32,124,137,230,95,216,157,86,228,23,109,199,143,167,215,162, +204,116,94,237,116,234,21,81,130,199,103,15,94,185,66,237,68,56,249,241,6,32,192,205,223,58,161,181,228,20,222,5,112,179,218,185,0,64,147,200,182,232,217,116,4,90,199,245,10,238,73,125,212,9,169,182,20,206,234,34,56,107,138,32,85,23,193,89,83,252,219, +191,139,64,173,53,151,127,61,33,16,195,26,64,155,216,9,218,102,189,160,107,212,21,240,153,115,12,40,28,229,191,192,81,242,45,28,229,251,32,153,207,1,244,242,221,104,137,54,28,130,33,17,130,177,33,4,99,34,136,161,238,223,130,49,17,130,62,30,8,226,159, +5,74,41,142,92,252,1,187,78,125,141,115,85,71,212,78,7,64,221,107,1,65,112,62,56,115,240,154,51,106,231,194,201,135,55,0,1,234,189,221,247,105,203,170,43,102,16,74,211,1,24,212,206,167,73,100,91,244,107,145,134,230,209,41,106,167,162,44,74,225,172,41, +130,179,226,20,156,21,103,224,44,63,5,71,229,89,56,43,207,0,146,231,19,176,133,208,56,132,116,158,8,125,171,65,234,21,79,74,97,47,206,131,245,248,167,144,204,103,61,143,35,104,32,134,52,133,16,210,12,66,88,18,196,208,230,16,66,155,67,48,52,4,130,108, +46,200,153,202,67,216,121,242,43,20,150,238,5,212,223,192,207,68,9,121,177,101,9,93,200,207,23,8,76,193,245,219,21,36,94,201,77,235,43,128,126,0,160,157,186,153,16,180,142,235,137,62,73,227,145,24,222,82,221,84,148,32,57,225,168,56,9,199,197,66,56,74, +11,225,44,59,14,103,197,25,80,167,124,59,197,105,98,147,17,214,239,81,136,145,77,100,27,227,74,36,243,121,152,15,46,132,179,178,64,190,65,4,93,93,51,16,214,18,98,68,107,136,225,109,32,134,37,1,196,39,166,175,200,170,164,246,52,126,56,245,53,10,138,118, +64,162,234,214,94,2,124,11,81,248,199,204,129,43,14,170,154,8,199,28,111,0,2,200,162,239,82,141,118,51,125,129,18,242,52,84,220,204,135,16,130,228,152,238,232,223,34,13,13,194,91,168,149,134,204,40,156,149,231,224,40,57,12,71,233,111,5,191,252,36,168, +83,249,53,223,68,163,71,216,128,39,160,107,162,204,174,205,142,242,159,97,62,240,111,80,71,173,34,227,93,70,208,66,12,75,134,24,222,186,238,159,136,118,16,66,155,34,80,63,202,170,44,23,241,195,233,181,216,119,46,27,78,117,247,19,176,19,74,23,25,173,181, +47,60,118,123,150,95,156,138,196,93,95,96,254,214,4,161,249,185,169,3,37,224,127,0,84,187,213,22,136,136,78,137,3,208,187,249,216,192,59,118,151,74,112,148,159,132,163,232,32,236,69,5,112,20,31,132,100,169,82,59,171,63,16,1,225,131,158,130,174,233,13, +178,14,227,40,219,11,211,254,23,188,122,125,193,26,209,70,66,140,234,4,77,84,39,136,81,41,16,67,91,248,208,252,8,54,42,204,69,248,246,196,42,228,23,109,7,165,146,106,121,16,224,0,136,240,143,153,131,87,236,84,45,9,142,25,222,0,248,185,5,27,167,133,58, +181,230,12,212,45,237,83,233,239,147,160,125,194,77,232,159,60,41,128,10,63,133,163,236,36,236,231,126,134,163,184,0,246,226,67,160,54,147,218,73,93,19,17,117,136,188,253,21,136,209,205,101,137,47,153,206,160,118,207,227,160,14,31,255,62,104,66,33,70, +118,128,38,42,5,98,76,15,136,97,45,16,40,31,117,101,166,243,248,246,196,42,28,44,222,161,230,94,2,18,40,222,16,29,134,103,159,185,117,153,10,143,129,56,86,2,227,183,34,72,205,205,158,212,139,8,210,114,0,109,212,202,33,57,182,27,6,36,79,70,131,48,255, +127,212,47,89,170,96,63,255,11,236,231,246,193,126,238,103,72,230,10,181,83,114,155,24,213,20,81,35,231,3,2,227,247,228,212,137,218,61,79,192,89,125,148,109,92,5,16,93,52,52,49,221,161,137,233,1,77,76,119,16,109,164,218,41,121,173,212,116,22,223,30,95, +137,67,37,223,171,217,8,252,74,136,116,231,204,193,171,119,171,149,0,231,29,222,0,248,33,74,65,50,182,164,62,6,138,249,0,116,106,228,208,40,162,53,6,38,223,129,102,209,29,213,24,158,17,10,199,197,66,216,78,255,8,251,185,125,112,148,29,7,124,104,135,54, +79,133,244,152,6,99,199,209,76,99,218,206,124,13,203,145,119,152,198,84,5,33,16,195,90,213,53,3,113,189,33,70,180,129,63,127,12,22,85,31,71,110,225,82,156,42,207,87,43,5,7,165,228,229,150,165,244,223,124,165,128,255,241,223,159,252,32,53,111,115,106, +51,42,98,41,1,6,170,49,126,124,104,51,12,72,158,130,86,113,61,212,24,222,123,84,130,163,228,48,172,39,191,135,237,228,46,72,166,82,181,51,98,142,232,195,16,61,225,29,16,13,163,213,159,146,29,213,223,223,13,106,43,103,19,207,135,16,109,36,52,177,61,161, +141,239,15,77,76,15,246,79,78,20,82,88,186,7,91,10,63,193,197,90,213,150,237,111,113,136,226,93,207,13,252,252,180,90,9,112,238,227,13,128,31,153,155,155,54,129,128,190,15,32,70,233,177,141,218,112,244,73,154,128,30,141,111,3,241,179,9,86,212,105,131, +253,236,62,216,78,237,130,237,204,30,80,91,224,191,182,12,189,233,126,24,90,15,101,18,203,126,33,7,230,131,11,153,196,242,101,68,19,6,77,220,141,208,198,245,129,38,182,39,32,168,242,112,205,99,148,82,228,23,109,195,150,194,79,80,107,83,229,245,85,37, +33,244,225,153,131,87,125,162,198,224,156,251,120,3,224,7,50,118,140,14,135,77,191,144,2,247,41,61,182,64,68,116,107,124,11,250,183,152,4,189,198,167,78,11,190,54,42,193,126,225,0,172,199,182,195,118,106,23,168,221,172,118,70,138,210,54,76,65,196,176, +231,153,196,50,253,252,47,56,202,130,235,53,47,209,132,64,19,215,7,218,6,131,161,137,246,165,93,23,175,207,238,180,98,207,217,13,248,254,196,26,216,156,202,255,220,19,66,86,234,96,187,239,201,193,95,250,223,36,154,32,195,27,0,31,247,74,118,234,77,130, +128,229,0,146,149,30,187,101,108,55,220,220,234,110,196,132,52,82,122,104,143,57,43,78,195,122,108,27,172,133,91,33,153,3,239,145,181,203,4,13,98,38,127,12,162,209,123,23,71,178,163,106,251,196,186,125,253,131,20,209,70,64,27,223,23,218,196,33,16,35, +59,192,95,62,54,171,173,165,200,59,186,12,7,139,191,83,99,248,66,9,210,212,57,55,175,222,165,198,224,156,107,252,227,39,57,8,101,102,166,138,199,227,233,115,148,146,231,160,240,201,125,49,33,141,48,164,213,221,72,142,237,166,228,176,30,147,76,229,176, +22,230,193,90,184,5,206,42,159,57,84,69,117,145,195,95,134,38,222,187,5,34,206,170,95,81,187,231,9,70,25,249,63,193,216,8,218,196,161,208,53,188,5,68,31,171,118,58,46,57,89,190,31,155,15,127,136,82,147,23,219,53,123,198,65,64,94,108,113,145,190,194,39, +8,250,38,222,0,248,160,87,182,165,198,11,14,124,14,133,15,240,209,138,122,244,107,145,134,158,77,110,247,253,131,122,168,4,219,217,159,96,61,146,3,219,153,189,127,57,124,134,3,194,250,61,10,125,242,0,175,98,216,139,242,96,46,152,207,40,163,0,66,4,104, +98,123,65,215,240,54,104,98,123,249,252,97,70,78,201,129,31,79,175,195,119,39,87,195,238,84,124,35,191,108,13,209,76,121,122,240,103,23,149,30,152,187,54,222,0,248,152,249,57,147,186,75,68,90,13,32,73,201,113,91,198,118,199,45,109,254,134,8,131,79,156, +22,124,85,146,169,12,214,99,219,96,57,188,9,82,77,137,218,233,248,180,208,94,247,192,208,254,118,175,98,216,78,127,9,203,209,247,24,101,20,152,136,46,6,186,196,33,208,54,26,14,193,199,55,194,170,182,150,97,235,177,79,145,127,97,155,210,67,159,145,32, +77,228,175,4,124,11,111,0,124,200,188,156,180,127,128,208,55,0,120,249,226,214,117,97,186,104,12,109,115,15,218,198,247,86,106,72,15,80,216,207,239,135,229,224,122,216,206,238,13,136,181,250,74,8,233,126,39,140,157,198,120,21,195,118,106,37,44,133,31, +50,202,40,192,17,2,77,76,79,232,154,140,129,38,166,59,124,249,227,245,88,217,62,108,62,252,63,84,152,139,148,28,214,66,65,30,158,125,115,38,255,129,242,17,190,251,19,26,68,22,175,31,174,55,25,66,223,0,200,63,148,27,149,160,99,98,127,12,109,53,29,6,109, +152,114,195,186,129,58,237,176,157,248,14,230,130,175,225,44,63,165,118,58,126,39,164,251,84,24,59,141,245,42,134,245,100,38,172,199,62,98,148,81,240,16,140,141,161,107,50,18,218,134,183,129,136,170,159,198,125,69,14,201,134,111,143,175,196,174,211,107, +21,61,95,128,2,203,244,6,220,63,163,207,202,224,90,154,227,131,120,3,160,178,140,188,241,77,40,21,87,1,184,81,169,49,227,67,155,225,214,182,247,161,113,164,106,59,8,95,147,100,42,135,229,200,102,88,14,109,0,181,86,171,157,142,223,226,13,128,250,136,38, +4,218,196,97,208,53,29,7,193,208,64,237,116,174,232,92,213,17,100,29,122,71,233,77,132,246,82,34,78,152,61,248,243,19,74,14,202,93,142,55,0,42,202,200,157,56,132,130,124,6,64,145,23,239,2,17,113,83,243,241,232,147,52,222,39,39,249,57,203,79,193,124,224, +11,88,79,124,207,39,245,49,192,27,0,31,66,4,104,19,6,64,215,44,237,183,195,137,124,139,83,178,227,219,19,171,176,235,212,215,144,148,251,221,43,38,18,153,60,115,104,102,158,82,3,114,151,227,13,128,10,46,217,203,127,1,0,173,18,99,198,133,54,193,136,246, +15,35,49,92,181,211,130,175,202,81,118,12,230,253,95,194,118,114,39,0,254,126,159,21,222,0,248,38,49,178,3,244,45,166,213,109,48,228,99,74,106,78,98,253,161,119,112,161,250,152,82,67,58,41,33,207,206,26,148,57,159,16,254,203,175,52,222,0,40,44,125,237, +168,16,67,136,97,9,8,38,42,49,30,33,4,189,154,142,68,255,22,147,161,17,20,233,53,92,230,40,62,4,243,129,47,97,59,179,71,237,84,2,18,111,0,124,155,24,217,1,250,102,105,208,196,221,0,95,250,40,150,168,19,59,79,126,137,111,79,172,82,240,105,0,205,212,25, +200,116,62,47,64,89,190,243,83,23,4,22,230,77,137,115,82,199,151,20,232,171,196,120,145,134,120,220,222,254,33,52,139,242,173,19,251,108,103,247,194,188,47,19,142,210,66,181,83,9,104,188,1,240,15,98,120,107,232,91,220,9,77,236,13,106,167,114,153,243, +85,133,88,119,112,49,202,76,138,109,174,245,131,83,210,140,126,118,232,103,138,46,77,8,102,188,1,80,200,252,173,19,90,75,14,225,27,16,180,150,127,52,130,174,141,134,96,112,171,187,160,243,161,25,200,142,226,67,48,237,251,28,246,11,170,29,93,26,84,120, +3,224,95,196,136,118,208,55,159,12,77,156,98,243,129,175,203,33,217,176,165,240,19,236,57,147,165,212,144,199,137,40,140,152,57,112,197,65,165,6,12,102,188,1,80,64,70,118,218,96,42,208,53,0,162,228,30,203,168,13,199,136,246,15,163,101,108,119,185,135, +114,153,227,226,17,152,127,89,205,31,245,43,140,55,0,254,73,140,236,0,67,242,116,136,81,41,106,167,242,187,195,37,187,176,225,215,247,97,182,43,178,42,167,76,0,198,255,243,230,149,91,149,24,44,152,249,222,84,240,0,51,47,119,226,93,32,200,4,16,42,247, +88,77,163,58,96,82,215,127,33,49,92,241,115,131,174,200,81,126,2,181,223,191,11,211,158,229,124,143,126,21,104,27,118,134,54,161,157,87,49,156,149,249,112,150,239,99,148,17,231,10,106,45,129,253,194,102,56,171,143,64,8,109,14,65,23,173,118,74,136,13, +109,130,78,137,131,112,209,116,6,229,230,11,114,15,103,164,192,29,67,167,119,58,145,189,36,255,23,185,7,11,102,188,1,144,9,165,32,33,131,38,190,0,144,215,32,243,97,62,132,8,232,155,52,17,183,183,123,208,39,142,236,149,204,229,48,237,89,138,218,157,255, +133,179,234,156,218,233,4,45,222,0,248,55,201,124,22,246,115,89,144,76,39,33,70,180,5,209,200,126,15,113,77,58,209,128,142,13,250,65,167,49,226,116,69,129,220,155,7,137,0,198,13,189,171,131,51,123,105,129,226,251,22,7,11,254,10,64,6,233,153,169,58,67, +28,249,47,64,239,146,123,172,80,93,36,70,180,127,4,45,98,186,200,61,212,117,81,167,13,150,131,235,97,222,191,6,212,206,39,243,170,141,191,2,8,28,68,212,67,215,120,52,116,73,83,64,68,163,218,233,224,66,117,33,190,60,176,8,149,22,5,206,227,160,248,56,58, +50,250,190,251,123,190,111,151,127,176,224,194,159,0,48,246,106,222,216,40,18,42,174,5,224,221,39,175,11,146,162,83,48,169,235,115,72,8,75,146,123,168,235,160,176,157,220,137,234,188,249,117,107,249,37,135,202,249,112,0,127,2,16,80,168,19,206,202,2,216, +47,100,131,136,70,136,97,45,1,162,222,253,91,152,62,6,29,19,7,160,164,230,148,252,175,4,8,186,90,172,150,62,35,166,183,249,122,227,146,67,22,121,7,11,46,188,1,96,104,222,230,212,102,78,34,230,2,144,117,61,15,33,2,6,181,188,3,183,182,253,7,116,42,223, +13,56,46,30,65,245,150,133,176,28,252,6,212,102,82,53,23,238,114,188,1,8,64,78,51,28,165,187,224,40,253,1,98,104,18,4,21,79,239,212,138,122,116,104,208,15,132,16,156,174,148,125,210,126,178,4,113,228,176,233,237,214,102,47,57,88,37,247,96,193,130,55, +0,140,204,205,155,156,68,8,205,5,32,235,6,251,6,109,24,198,119,122,26,157,18,7,66,205,55,56,212,86,11,211,222,79,80,187,243,125,72,166,82,213,242,224,174,142,55,0,129,139,218,202,96,63,191,25,146,229,60,52,81,29,85,59,112,136,16,130,102,81,29,209,52, +178,3,142,151,237,131,221,105,149,115,184,4,10,97,194,208,233,29,215,229,44,41,40,147,115,160,96,33,168,157,64,32,120,37,111,66,59,66,157,59,0,200,58,253,62,33,172,57,238,238,49,87,229,247,253,20,214,194,173,168,248,242,113,88,14,174,7,20,60,69,140,227, +184,75,81,216,47,228,160,102,231,223,97,59,243,165,170,191,139,205,162,59,226,238,158,243,208,56,178,173,172,227,16,160,57,161,216,254,114,222,164,78,178,14,20,36,248,19,0,47,205,221,58,161,155,32,9,185,0,18,229,28,167,67,131,126,24,159,242,79,132,234, +34,229,28,230,154,28,229,39,80,189,229,63,176,28,202,2,117,200,218,233,115,12,240,39,0,65,66,178,193,81,182,7,142,210,31,33,134,37,67,208,199,169,146,134,94,19,130,142,13,6,160,214,94,129,162,234,227,114,14,21,38,128,78,28,122,119,202,230,236,37,249, +124,215,64,47,240,6,192,11,115,179,39,245,34,192,38,0,178,253,198,17,34,96,96,203,59,48,164,213,221,16,5,89,87,19,94,21,117,88,235,30,247,127,247,46,164,90,5,102,253,114,76,240,6,32,184,80,91,25,236,23,54,129,58,106,32,70,166,128,168,240,121,33,16,1, +173,226,122,34,76,31,141,227,101,251,64,229,59,223,39,20,160,147,111,158,214,113,91,206,210,2,69,207,49,14,36,252,21,128,135,50,178,211,6,19,65,202,5,16,35,215,24,70,109,56,38,117,121,14,189,155,141,145,107,136,235,114,20,31,66,229,186,103,96,41,88,199, +143,232,229,56,95,71,37,216,78,127,137,218,31,30,128,67,197,198,173,107,163,161,152,216,121,22,244,242,238,93,16,37,8,216,56,63,55,117,160,156,131,4,50,222,0,120,96,94,206,196,225,84,160,223,0,8,147,107,140,104,99,34,238,236,254,111,52,143,86,231,85, +87,253,93,127,229,198,231,249,46,126,28,231,103,36,203,5,152,246,205,129,229,215,197,160,14,117,86,231,180,136,233,130,187,123,206,69,108,72,99,57,135,9,151,128,141,25,185,169,163,229,28,36,80,241,6,192,77,243,114,210,70,129,144,47,0,200,182,254,174, +73,100,91,76,235,241,50,98,66,26,201,53,196,53,217,207,253,140,138,175,158,132,249,192,151,0,229,71,116,115,156,127,162,176,157,203,66,205,174,127,192,113,113,167,42,25,68,27,19,49,173,199,43,114,159,77,162,167,192,202,140,188,84,69,142,88,15,36,124, +14,128,27,230,229,165,221,9,208,207,0,232,228,26,163,83,226,64,140,237,244,20,116,26,229,215,247,83,187,25,181,187,62,128,105,247,82,80,123,173,226,227,115,108,241,57,0,28,0,192,105,134,189,120,43,36,107,9,52,81,93,64,4,173,162,195,107,4,45,218,37,220, +4,139,163,22,231,171,142,202,53,140,8,96,252,176,233,29,142,101,47,41,216,47,215,32,129,134,63,1,112,81,70,78,234,52,80,186,4,178,237,235,79,208,191,197,36,140,104,255,176,42,147,253,28,23,143,162,242,155,153,176,30,205,5,228,155,184,195,113,156,74,236, +231,55,161,246,199,7,225,172,56,160,248,216,2,17,49,172,245,189,184,185,213,93,144,113,255,18,13,165,100,105,221,141,26,231,10,254,4,192,5,25,121,105,99,41,240,9,100,250,126,137,130,22,35,219,63,132,238,77,110,147,35,252,181,81,39,204,249,95,163,102, +199,98,80,11,223,96,43,144,240,39,0,220,159,81,71,45,236,69,57,128,211,10,77,84,10,64,148,189,7,108,28,217,6,241,97,205,112,244,226,110,72,242,236,91,64,0,140,25,122,119,167,67,217,75,242,243,229,24,32,144,240,39,0,215,49,47,103,226,112,74,233,10,200, +116,231,111,208,134,97,74,215,231,209,161,65,127,57,194,95,147,84,83,130,202,141,233,48,237,253,4,144,248,12,127,142,11,10,84,130,245,212,74,212,254,244,20,36,211,89,197,135,111,27,127,35,38,118,158,13,189,124,175,57,69,128,46,155,155,151,170,194,29, +149,127,225,13,192,53,188,146,155,214,23,132,172,132,76,239,252,67,117,81,152,210,245,5,217,119,207,186,18,235,209,60,84,172,125,10,142,226,67,138,143,205,113,156,250,156,85,135,81,187,251,81,216,207,111,84,124,236,230,209,157,48,181,251,75,8,215,199, +202,53,132,142,80,172,153,155,55,113,144,92,3,4,2,222,0,92,197,43,185,19,110,20,64,179,0,200,178,144,53,210,144,128,169,221,95,68,66,88,115,57,194,95,21,117,218,80,243,253,187,168,249,238,109,126,100,47,199,5,57,234,52,195,124,232,53,152,11,230,131,58, +149,253,60,136,15,109,138,59,187,191,40,231,50,65,35,161,100,221,188,188,212,126,114,13,224,239,120,3,112,5,115,183,78,232,38,64,216,0,32,92,142,248,9,97,73,152,214,227,101,68,27,101,221,61,248,47,156,85,231,80,185,126,54,172,71,114,20,29,151,227,56, +223,102,47,202,67,237,238,199,32,213,158,80,116,220,8,67,60,166,118,127,17,141,35,101,59,67,45,20,20,95,207,203,157,164,230,1,42,62,139,55,0,127,242,74,246,164,54,196,41,100,1,136,146,35,126,147,168,246,184,163,91,186,226,123,250,219,78,237,66,229,250, +217,112,150,159,82,116,92,142,227,252,131,100,58,131,154,221,143,195,126,126,131,162,227,214,237,120,250,47,36,197,116,150,107,136,104,64,218,252,74,118,106,7,185,6,240,87,188,1,184,196,252,156,73,45,5,65,202,3,208,64,142,248,45,99,123,96,82,151,103, +161,215,132,200,17,254,138,168,211,142,218,31,63,66,245,150,133,160,54,117,118,4,227,56,206,79,72,54,152,15,189,14,243,193,133,160,242,30,237,123,25,173,168,199,196,148,153,104,29,215,75,174,33,226,5,1,155,230,102,79,144,245,196,86,127,195,27,128,223, +188,180,117,114,83,39,145,114,0,200,178,253,94,135,6,125,49,62,229,105,104,4,217,246,16,250,11,201,84,134,170,13,255,170,59,182,151,227,56,206,69,246,11,57,48,237,157,1,201,170,220,225,95,162,160,197,152,142,79,162,77,252,13,114,13,209,152,8,66,118,70, +222,248,38,114,13,224,111,120,3,0,32,125,253,212,8,141,195,249,13,1,100,153,145,215,62,161,15,70,180,127,4,2,81,110,219,5,103,229,89,84,102,205,129,163,180,80,177,49,57,142,11,28,206,154,99,168,221,243,36,164,90,229,94,27,138,130,6,99,59,206,64,167,68, +217,206,247,105,65,169,184,241,213,188,177,178,188,226,245,55,65,223,0,188,183,251,62,173,193,96,91,13,130,20,57,226,183,79,232,139,145,29,30,85,180,248,75,166,82,84,101,191,4,169,182,84,177,49,57,142,11,60,212,90,10,211,207,207,66,178,20,43,54,38,33, +2,110,111,247,32,58,55,28,44,215,16,29,172,84,251,69,122,102,170,114,143,99,125,84,80,55,0,148,130,148,85,149,253,23,192,80,57,226,215,21,127,101,239,252,65,157,168,222,246,26,164,218,139,202,141,201,113,92,192,146,172,23,97,206,127,25,160,14,197,198, +36,68,192,240,118,15,160,71,147,225,114,13,49,200,16,71,222,149,43,184,191,8,234,6,96,254,150,137,207,19,144,187,229,136,157,146,56,8,163,58,60,166,108,241,7,96,206,95,199,55,247,225,56,142,41,103,213,97,88,79,173,82,120,84,130,161,173,167,163,91,227, +91,101,138,79,239,201,200,75,125,86,166,224,126,33,104,27,128,121,121,19,39,83,74,94,144,35,118,231,134,131,49,188,221,131,32,68,182,67,47,174,72,178,84,193,124,96,141,162,99,114,28,23,28,108,39,51,65,109,229,10,143,74,112,75,155,123,209,181,145,44,15, +105,65,41,254,157,145,147,58,77,150,224,126,32,40,27,128,140,236,180,193,160,100,9,100,56,150,42,165,225,96,220,214,246,1,197,139,63,0,88,15,111,226,75,253,56,142,147,5,117,154,97,59,251,141,10,35,19,220,210,230,239,232,208,160,175,44,193,41,193,127, +231,229,164,13,144,35,184,175,11,186,6,32,99,235,164,246,84,160,171,33,195,254,254,173,227,122,225,182,182,247,169,82,252,1,10,203,145,108,21,198,229,56,46,88,216,206,111,128,26,199,133,19,34,96,100,251,71,209,46,225,38,57,194,235,65,232,23,25,185,169, +202,31,202,162,178,160,106,0,22,230,77,137,163,78,233,107,0,209,172,99,39,69,167,96,76,199,39,20,127,231,95,207,81,118,156,207,250,231,56,78,86,212,90,10,103,245,81,85,198,174,111,2,90,198,246,144,35,124,12,5,178,94,206,158,34,203,38,112,190,42,104,26, +128,69,223,165,26,29,212,177,22,64,43,214,177,27,69,180,198,184,148,103,32,10,90,214,161,93,230,40,226,19,255,56,142,147,159,179,34,95,181,177,69,65,131,113,157,102,32,57,166,171,28,225,91,136,162,99,109,250,218,81,202,109,213,170,178,160,104,0,40,5, +177,153,177,20,64,111,214,177,19,194,146,144,214,101,14,116,162,129,117,104,183,56,43,79,171,58,62,199,113,193,193,169,240,129,65,127,38,10,90,140,237,244,148,60,199,168,83,244,50,134,26,62,100,31,216,55,5,69,3,48,111,75,218,63,65,48,145,117,220,104, +99,34,210,186,204,129,94,35,203,137,193,110,145,204,21,106,167,192,113,92,16,160,54,245,63,107,234,207,14,144,227,40,97,10,76,154,151,155,58,131,121,96,31,20,240,13,64,70,238,196,33,132,210,151,89,199,141,208,199,98,114,215,231,17,170,243,141,29,37,169, +195,166,118,10,28,199,5,1,234,244,141,149,70,6,109,24,210,186,204,65,152,158,249,148,46,0,200,152,155,55,113,144,28,129,125,73,64,55,207,250,105,202,0,0,32,0,73,68,65,84,0,47,109,157,220,148,130,124,6,128,233,204,60,189,198,136,137,157,103,33,194,16, +199,50,172,87,136,24,244,187,90,114,28,167,0,34,26,213,78,225,119,17,134,120,164,117,121,78,142,167,176,26,66,201,138,64,63,56,40,96,27,128,197,235,135,235,53,146,115,53,128,120,150,113,5,34,98,108,199,167,16,31,38,203,185,65,30,19,140,190,241,36,130, +227,184,192,70,116,178,220,113,123,44,62,180,41,198,167,60,45,199,36,236,4,74,197,85,139,215,15,215,179,14,236,43,2,182,1,48,235,195,223,4,5,227,195,165,9,134,183,123,0,73,49,157,217,134,101,64,140,100,255,46,140,227,56,238,207,196,208,166,106,167,240, +23,205,162,58,98,68,251,135,229,216,131,229,70,179,49,244,53,214,65,125,69,64,54,0,115,115,83,239,163,132,254,157,117,220,126,45,82,229,60,166,210,43,154,132,118,106,167,192,113,92,16,16,35,59,169,157,194,21,181,79,232,131,97,173,239,101,30,151,82,242, +64,70,94,234,223,152,7,246,1,1,215,0,100,228,164,222,64,128,197,172,227,166,36,14,66,223,164,9,172,195,50,163,137,77,134,96,136,84,59,13,142,227,2,24,209,69,65,12,111,173,118,26,87,213,173,241,173,178,156,32,72,41,222,156,155,155,42,203,14,68,106,10, +168,6,224,149,236,113,177,148,96,5,0,166,239,108,154,69,117,196,173,109,239,131,12,71,7,176,67,4,232,146,251,171,157,5,199,113,1,76,155,48,8,32,190,93,54,134,180,186,27,45,99,187,177,14,107,32,192,154,133,121,83,124,103,230,55,3,190,253,55,233,134,244, +188,65,26,65,208,100,2,72,98,25,55,46,180,9,198,167,60,3,81,208,176,12,43,11,99,251,17,128,31,228,201,113,156,31,34,2,116,77,70,170,157,197,117,17,34,96,100,135,199,16,19,210,144,117,232,102,14,56,62,205,204,76,85,103,191,119,25,4,76,3,160,151,18,158, +3,112,51,203,152,6,77,40,198,167,60,3,189,198,63,118,134,20,66,227,96,104,61,68,237,52,56,142,11,64,186,134,183,65,48,250,199,100,99,131,38,20,19,82,102,194,192,122,121,32,197,176,227,241,152,197,54,168,122,2,162,1,152,155,61,169,23,33,116,14,203,152, +132,16,140,236,240,24,162,141,204,187,72,89,133,116,155,2,33,196,183,150,233,112,28,231,223,136,46,26,250,228,233,106,167,225,150,152,144,70,24,211,241,73,230,7,180,81,138,244,140,188,73,204,183,149,87,131,223,55,0,233,121,169,97,132,72,159,0,96,186, +8,116,96,242,29,114,188,71,146,29,209,133,34,172,255,19,128,74,167,18,114,28,23,96,136,0,99,135,153,32,218,112,181,51,113,91,82,76,103,12,110,53,141,117,88,13,165,210,242,140,29,163,253,239,27,242,39,126,255,194,216,64,201,91,32,148,233,180,212,182,241, +55,226,198,102,163,89,134,84,148,182,65,7,132,245,125,8,53,223,190,9,80,229,207,238,230,56,37,153,173,78,236,253,181,18,59,247,87,224,208,201,26,28,63,103,194,153,34,51,204,54,9,85,53,14,104,68,130,16,163,136,136,80,13,154,39,26,145,220,56,4,41,45,35, +208,167,115,52,218,183,8,131,192,126,237,120,0,33,48,180,121,4,154,232,46,106,39,226,177,158,77,110,71,105,237,89,236,59,183,153,101,216,150,212,166,123,13,128,95,47,15,244,235,6,96,110,94,234,36,80,122,23,203,152,9,97,73,24,209,254,17,248,244,140,127, +23,232,147,7,128,218,45,168,221,245,1,0,222,4,112,129,197,108,117,98,195,247,37,88,149,123,30,217,63,148,192,98,147,174,250,181,54,7,133,173,90,66,69,181,29,167,46,152,177,125,95,217,239,255,95,92,148,14,99,7,38,34,117,72,67,244,238,196,95,157,253,153, +161,213,223,161,107,196,126,89,157,210,134,181,185,23,37,181,39,113,182,242,48,195,168,228,222,140,188,212,172,153,131,87,174,98,24,84,81,126,91,229,50,242,198,55,161,84,252,25,64,12,171,152,70,109,56,238,234,241,10,162,140,13,88,133,84,157,245,72,14, +106,118,190,199,159,4,4,161,144,238,83,97,236,52,214,171,24,214,147,153,176,30,251,136,81,70,222,171,54,57,176,60,235,44,94,251,252,24,46,148,90,153,198,238,152,28,142,71,211,146,144,58,164,17,52,162,223,126,52,50,163,79,190,7,250,230,105,106,167,193, +76,181,181,20,31,255,56,19,38,123,21,203,176,21,112,162,203,172,97,43,79,177,12,170,20,191,124,81,156,153,153,42,150,133,8,95,17,160,61,171,152,132,16,76,72,249,39,18,195,147,89,133,244,9,154,216,100,136,33,49,176,157,221,163,118,42,156,194,180,13,59, +67,235,229,14,145,206,202,124,56,203,247,49,202,200,115,18,165,248,124,243,57,164,206,222,139,181,219,139,80,99,118,50,31,163,164,220,134,117,59,138,177,254,187,98,116,76,14,71,147,4,223,57,244,70,105,129,86,252,1,64,175,9,65,131,176,36,20,20,111,103, +25,214,0,17,93,251,181,72,91,182,101,203,22,191,187,203,242,203,73,128,199,226,200,76,2,48,221,147,183,79,243,137,104,30,157,194,50,164,207,208,183,30,130,176,222,247,3,252,93,39,231,135,126,61,89,131,129,15,124,143,7,230,237,71,105,165,252,199,94,31, +40,172,198,109,143,239,194,140,215,10,96,182,178,111,52,124,93,32,22,255,122,73,49,157,209,55,105,34,219,160,20,131,13,3,14,60,205,54,168,50,252,174,1,168,219,142,145,190,192,50,102,211,168,14,62,189,205,47,11,188,9,224,252,209,178,172,51,24,248,192, +247,248,229,8,211,199,182,215,69,41,240,191,175,79,97,232,35,59,113,244,76,173,162,99,171,41,144,139,127,189,62,205,39,34,153,249,10,47,242,82,70,78,234,13,140,131,202,206,175,26,128,5,27,167,133,18,224,83,0,58,86,49,67,117,145,24,211,241,9,16,31,223, +222,146,5,222,4,112,254,130,82,96,238,146,163,120,100,193,1,85,239,194,15,20,86,99,200,195,59,177,43,191,66,181,28,148,18,12,197,31,248,109,143,151,246,143,32,66,31,203,50,172,150,18,44,93,176,113,26,227,157,135,228,229,87,85,207,161,181,206,7,208,134, +85,188,186,31,132,71,17,170,139,98,21,210,231,241,38,128,243,117,78,137,226,193,140,253,152,183,228,168,218,169,0,0,42,170,237,24,251,204,143,216,178,167,84,237,84,100,19,44,197,191,158,81,27,142,177,157,158,98,189,197,123,91,167,206,250,18,203,128,114, +243,155,42,48,63,55,117,160,4,228,130,97,211,210,55,105,34,250,181,80,232,135,158,82,216,46,28,129,245,228,47,176,21,31,131,84,91,14,201,102,1,209,26,32,134,69,67,27,159,4,125,179,20,232,27,182,5,4,249,251,50,190,58,32,240,249,227,42,128,250,226,191, +98,243,57,197,198,116,149,81,47,226,203,5,61,3,110,185,160,98,197,159,58,97,179,30,134,205,156,15,135,237,20,156,142,50,128,58,64,136,22,130,38,6,90,93,18,116,33,41,208,234,91,66,169,210,244,227,233,117,200,61,186,148,101,72,167,4,169,239,156,155,87, +239,98,25,84,46,126,177,15,64,250,218,81,33,18,240,1,24,22,255,186,247,254,140,39,131,92,129,179,182,28,213,63,124,129,154,189,235,224,172,42,185,238,215,139,161,209,8,237,60,12,225,55,78,132,38,90,190,109,136,245,191,157,25,192,155,0,206,87,56,37,138, +251,231,254,130,149,57,231,213,78,229,138,204,86,39,166,60,183,23,57,111,221,132,228,198,254,113,62,200,245,40,81,252,157,246,243,168,169,248,10,230,170,92,72,206,202,235,126,189,168,137,71,72,228,112,132,70,141,132,32,202,123,196,121,175,166,35,112, +162,124,63,142,149,254,196,42,164,40,80,225,191,233,153,169,61,211,211,86,202,63,99,213,75,126,177,12,240,182,191,119,89,0,130,219,89,197,51,106,195,49,185,235,243,242,30,242,35,57,81,185,227,19,92,204,124,30,150,194,31,65,173,38,151,46,163,118,11,172, +103,242,81,253,195,26,72,53,165,208,55,77,1,209,50,61,221,248,119,124,137,96,96,243,167,101,128,78,137,226,161,140,253,200,204,246,205,226,95,207,108,149,176,227,231,50,220,113,107,99,104,53,126,245,6,245,47,228,46,254,146,179,26,149,37,239,161,162,104, +17,236,230,2,80,234,218,190,13,84,50,193,102,254,25,181,149,223,128,64,128,206,208,78,198,35,136,9,154,71,117,194,129,11,91,225,144,24,213,107,130,6,218,16,98,207,94,146,191,141,77,64,249,248,252,43,128,87,178,83,111,18,4,108,7,195,102,101,76,199,39, +209,46,225,38,86,225,254,194,81,89,132,139,153,47,192,122,38,223,235,88,98,88,12,226,38,190,0,67,139,238,12,50,187,50,254,58,32,48,249,203,43,0,167,68,241,192,188,253,200,204,246,254,177,127,114,114,50,6,12,24,128,78,157,58,161,73,147,38,8,11,11,131, +195,225,64,77,77,13,142,31,63,142,61,123,246,96,219,182,109,40,43,43,187,126,176,107,184,127,92,115,204,127,148,217,54,36,138,147,187,248,91,77,251,80,126,97,30,36,71,185,215,177,116,198,142,136,110,56,7,162,38,142,65,102,87,118,228,226,143,88,179,127, +1,203,144,86,73,66,247,57,67,87,22,176,12,202,154,79,55,0,139,215,15,215,155,12,97,251,0,120,119,27,115,137,142,13,250,99,100,135,71,89,133,251,11,123,241,113,20,45,123,202,165,199,253,46,19,4,196,142,122,6,97,221,229,59,139,155,55,1,129,199,31,26,0, +22,239,252,245,122,61,238,188,243,78,60,244,208,67,232,222,253,250,141,178,205,102,67,86,86,22,22,45,90,132,109,219,60,187,73,19,8,65,206,219,189,209,189,173,188,143,168,229,32,119,241,55,85,102,161,162,104,49,128,171,111,207,236,46,81,147,128,216,38, +47,67,163,107,198,44,230,159,109,56,244,30,126,62,159,195,50,228,14,203,182,142,3,211,211,211,217,125,35,24,243,233,103,88,102,99,232,44,48,44,254,225,250,24,12,109,115,47,171,112,127,225,168,44,70,209,210,25,108,139,63,0,72,18,74,191,158,143,234,93, +171,217,198,189,4,95,29,192,41,141,69,241,191,245,214,91,145,159,159,143,15,62,248,192,165,226,15,0,58,157,14,99,198,140,193,214,173,91,241,197,23,95,160,81,163,70,110,143,43,81,138,167,94,43,240,187,126,89,238,226,95,91,241,21,42,138,94,7,203,226,15, +0,78,71,49,74,207,204,134,211,193,248,179,245,18,67,90,79,71,76,136,251,63,11,215,208,207,208,63,255,126,150,1,89,243,217,6,96,254,214,9,173,41,37,179,88,197,35,132,96,68,251,71,96,208,200,179,76,147,58,108,40,249,116,22,156,213,23,101,137,15,74,81,150, +245,58,111,2,184,128,80,255,206,223,211,226,47,8,2,230,207,159,143,172,172,44,180,108,217,210,227,60,198,142,29,139,125,251,246,97,224,64,247,55,22,221,251,107,37,214,127,87,236,241,216,74,83,162,248,87,22,191,3,185,14,31,115,58,46,162,236,236,11,160, +84,158,185,117,90,81,143,81,29,30,131,192,242,40,117,130,121,47,109,157,220,148,93,64,182,124,178,1,160,20,68,114,10,239,2,48,176,138,217,163,201,237,104,30,221,137,85,184,191,40,91,255,42,108,23,142,200,22,31,192,31,77,192,78,249,14,159,226,77,0,39, +183,250,226,255,185,135,197,95,167,211,225,243,207,63,199,51,207,60,3,194,224,231,52,62,62,30,27,55,110,196,232,209,238,31,1,254,234,103,199,188,30,95,9,178,23,255,202,111,100,45,254,245,236,214,66,84,22,191,45,91,252,196,240,100,214,171,195,34,52,146, +243,45,150,1,89,242,201,6,32,35,111,226,52,0,55,179,138,23,27,210,24,3,147,167,176,10,247,23,181,251,179,81,179,103,157,108,241,47,67,41,202,54,44,230,77,0,231,151,156,18,197,195,243,15,120,85,252,87,172,88,129,212,212,84,166,121,233,245,122,172,88,177, +2,3,6,12,112,235,186,31,11,42,240,211,175,215,95,218,166,38,69,138,127,209,27,80,234,216,113,83,101,22,76,85,155,101,139,223,187,249,88,182,135,194,81,140,154,151,155,230,147,187,44,249,92,3,48,119,251,29,209,0,89,200,42,158,64,68,140,236,240,8,52,2, +179,221,131,47,99,47,62,142,210,175,51,100,137,125,85,191,55,1,43,101,27,130,55,1,28,107,18,173,43,254,159,109,58,235,209,245,90,173,22,43,86,172,192,216,177,222,77,108,188,26,131,193,128,204,204,76,36,38,38,186,117,221,170,92,223,93,186,24,104,197,191, +94,101,209,27,176,91,229,121,250,34,16,17,183,181,187,159,237,171,0,208,197,175,230,141,245,185,45,103,125,174,1,32,118,219,191,1,196,179,138,215,171,233,8,36,134,123,254,142,240,90,168,205,140,146,204,231,65,109,22,89,226,95,123,112,138,178,13,111,240, +38,128,243,11,190,94,252,235,53,104,208,0,175,191,254,186,91,215,172,217,114,65,166,108,188,19,168,197,31,0,40,181,162,252,252,203,160,146,107,251,171,184,171,65,88,11,220,216,204,253,87,66,215,10,105,133,142,233,33,118,44,248,84,3,240,114,222,164,78, +0,97,54,107,50,210,144,128,190,73,108,31,21,94,170,116,221,127,96,47,57,33,91,252,235,226,77,0,231,7,36,74,241,200,130,3,248,116,163,119,197,127,220,184,113,140,51,187,178,180,180,52,220,120,227,141,46,127,253,185,18,11,10,207,200,83,136,60,21,200,197, +191,158,195,118,6,21,69,175,201,22,191,111,210,68,196,133,50,156,191,71,233,35,11,178,39,116,102,23,208,123,62,211,0,80,10,34,80,233,77,48,219,158,152,224,182,118,247,67,43,202,179,139,94,205,158,117,168,253,121,163,44,177,221,242,123,19,192,231,4,112, +190,167,190,248,127,178,193,243,226,255,249,231,159,43,86,252,235,205,152,49,195,173,175,255,110,191,119,27,11,177,164,200,108,127,149,139,127,61,115,245,86,152,42,179,100,137,45,10,90,12,111,247,0,203,147,98,53,14,81,120,147,82,223,217,127,199,103,26, +128,140,45,105,83,9,224,254,90,156,171,232,220,112,48,146,162,83,88,133,187,140,163,236,44,202,55,190,33,75,108,143,240,57,1,156,15,146,40,197,163,12,138,255,248,241,227,25,103,118,125,163,70,141,66,88,88,152,203,95,255,203,145,42,25,179,113,93,160,204, +246,119,71,101,201,187,112,216,206,200,18,187,81,68,107,244,108,194,108,23,122,16,138,254,25,121,105,242,61,150,118,147,79,52,0,25,59,70,135,131,82,102,51,233,194,116,209,24,220,106,26,171,112,151,147,156,184,184,250,69,72,46,238,237,175,24,254,58,128, +243,33,148,2,51,94,43,192,114,15,139,191,40,138,88,186,116,169,42,197,31,0,140,70,35,250,246,237,235,242,215,159,56,111,150,49,27,215,4,195,99,255,43,161,146,5,229,23,230,129,82,135,44,241,251,183,152,132,40,99,3,102,241,8,232,194,244,181,163,124,226, +52,41,159,104,0,36,171,126,38,0,102,91,48,13,109,115,175,108,27,254,84,228,125,8,235,25,31,221,222,153,55,1,156,15,144,40,197,163,11,15,224,163,181,167,61,186,190,254,157,255,228,201,147,25,103,230,158,30,61,122,184,252,181,39,206,171,123,67,32,255,246, +190,235,125,178,248,215,179,91,142,160,166,244,19,89,98,107,69,61,110,105,243,119,102,241,40,208,212,24,166,127,134,89,64,47,168,222,0,100,228,141,111,66,8,158,100,21,175,117,92,47,180,141,119,125,2,143,59,172,167,246,163,114,199,114,89,98,51,195,155, +0,78,69,18,165,120,108,97,62,150,101,121,246,72,86,171,213,226,211,79,63,197,132,9,19,24,103,230,190,22,45,90,184,252,181,85,181,242,220,125,186,66,137,226,95,183,183,191,111,22,255,122,213,101,159,193,102,254,69,150,216,45,98,186,160,13,195,186,66,41, +121,38,99,211,100,166,251,14,123,66,245,6,64,162,226,43,0,152,60,14,209,8,58,12,105,125,55,139,80,127,65,109,102,92,252,226,21,64,242,217,115,29,254,192,155,0,78,5,148,2,79,189,86,224,113,241,23,69,17,75,150,44,193,196,137,76,119,98,243,88,68,68,132, +203,95,91,107,118,202,152,201,213,241,226,127,41,138,242,243,243,33,57,107,100,137,62,164,245,116,232,68,102,155,211,134,82,141,227,223,172,130,121,74,213,6,96,126,94,106,87,2,76,101,21,175,119,243,177,136,52,36,176,10,119,153,178,245,175,194,81,38,207, +68,19,89,240,38,128,83,144,68,41,30,251,207,1,124,232,225,99,127,141,70,131,207,62,251,12,83,166,200,183,99,167,187,52,26,215,23,36,57,156,202,23,72,101,14,246,241,151,226,95,199,233,40,65,85,201,187,178,196,142,208,199,226,166,230,44,87,163,144,233, +115,115,83,93,127,207,36,3,85,27,0,137,98,33,171,28,34,12,113,184,161,233,40,22,161,254,194,124,100,39,106,126,146,103,169,137,172,40,69,89,214,98,84,237,144,231,221,24,192,155,0,174,174,248,63,177,40,31,75,215,123,214,32,107,52,26,124,250,233,167,204, +183,247,245,86,109,109,173,203,95,27,106,100,185,107,220,245,41,242,206,223,199,102,251,187,202,84,181,25,150,154,239,101,137,221,171,233,40,196,134,52,102,21,78,32,4,11,88,5,243,40,1,181,6,158,151,51,113,56,128,33,172,226,13,109,125,143,44,107,254,37, +107,45,202,214,170,250,119,228,181,242,205,239,242,38,128,147,69,125,241,95,242,141,231,197,255,147,79,62,241,185,226,15,0,103,206,184,254,223,164,100,3,192,31,251,95,95,101,241,27,144,36,246,175,2,68,65,195,246,72,121,138,193,115,243,82,111,99,23,208, +61,234,61,1,32,36,157,85,168,164,152,206,104,29,215,139,85,184,203,148,111,122,27,142,74,255,57,242,243,106,120,19,192,177,70,41,240,196,162,2,175,139,127,154,111,158,147,130,130,2,215,87,251,52,142,99,246,110,248,154,120,241,119,141,211,81,138,170,146, +255,201,18,59,41,58,5,237,18,110,98,23,144,34,35,61,61,93,149,90,172,202,160,25,121,105,99,1,220,192,34,150,40,104,48,172,53,195,142,236,18,150,227,123,81,179,103,173,44,177,213,192,155,0,142,21,74,129,39,94,205,199,146,111,60,127,231,191,124,249,114, +159,45,254,0,176,125,251,118,151,191,182,69,99,249,151,117,243,226,239,30,83,101,22,172,166,61,178,196,190,185,213,93,204,158,56,19,160,179,97,64,129,42,51,95,21,111,0,40,5,161,148,166,179,138,215,171,201,8,196,132,176,95,77,65,237,22,148,126,61,191, +238,147,46,128,240,38,128,243,86,125,241,255,120,157,119,197,127,210,164,73,140,51,99,103,247,238,221,56,121,242,164,203,95,223,166,153,235,187,6,122,130,23,127,79,80,84,20,189,14,42,177,223,164,41,92,31,139,94,77,71,178,11,72,233,75,233,121,131,24,109, +131,239,58,197,27,128,121,91,82,211,0,116,97,17,43,68,27,129,222,205,229,217,41,172,60,251,61,56,202,60,219,197,204,215,149,103,191,199,87,7,112,30,161,20,120,122,113,129,199,197,95,20,69,124,252,241,199,62,93,252,1,224,237,183,223,118,235,235,111,74, +137,150,41,19,37,102,251,127,29,128,197,191,142,211,94,132,170,139,31,203,18,251,198,102,99,16,166,99,244,247,78,208,90,143,184,233,108,130,185,78,209,6,32,51,51,85,36,18,152,29,137,216,55,105,34,244,26,35,171,112,191,179,157,63,140,234,31,214,48,143, +235,51,248,234,0,206,3,148,2,79,190,150,143,15,190,58,229,209,245,162,40,98,249,242,229,152,58,149,217,202,95,89,28,62,124,24,203,151,187,190,225,151,81,47,162,91,91,215,247,12,112,135,50,179,253,223,70,32,22,255,122,181,21,95,193,102,249,149,121,92, +157,104,64,223,22,236,158,220,11,148,60,191,120,253,112,121,78,175,187,218,152,74,14,118,60,22,119,128,160,61,139,88,81,198,6,232,210,104,40,139,80,151,163,18,202,214,45,242,143,13,127,188,196,95,7,112,174,170,219,219,63,223,227,237,125,69,81,196,178, +101,203,84,223,222,247,122,36,73,194,131,15,62,8,187,221,238,242,53,67,111,136,131,78,195,254,163,148,63,246,103,133,162,178,248,77,0,236,63,211,187,52,28,130,120,70,71,6,83,160,169,217,16,250,55,38,193,92,164,88,3,144,153,153,42,82,130,103,89,197,27, +212,114,42,68,129,253,43,147,234,61,107,97,61,147,207,60,174,175,42,223,252,46,42,183,203,183,189,49,111,2,252,31,165,192,83,175,23,120,188,201,79,125,241,247,165,77,126,174,230,229,151,95,70,110,110,174,91,215,164,222,220,144,121,30,188,248,179,101, +183,28,70,109,5,251,189,92,8,17,48,176,37,203,39,90,100,150,146,79,1,20,107,0,10,227,233,61,0,218,178,136,213,48,162,149,44,251,253,75,166,74,84,228,252,151,121,92,95,87,145,253,30,111,2,184,43,162,148,226,169,215,11,240,191,175,61,127,236,191,116,233, +82,191,40,254,75,151,46,197,11,47,184,247,134,50,62,74,135,91,111,98,187,251,40,47,254,242,168,46,253,16,146,179,130,121,220,150,177,221,145,20,211,153,73,44,10,52,53,233,195,228,89,214,118,5,138,52,0,239,237,190,79,75,40,153,195,42,222,160,228,169,0, +216,23,147,242,205,239,64,50,85,50,143,235,15,120,19,192,253,25,165,20,51,210,63,246,170,248,127,252,241,199,184,227,142,59,24,103,198,222,202,149,43,241,183,191,253,13,212,205,85,63,15,78,72,130,65,199,238,99,148,23,127,249,72,206,26,217,246,6,24,220, +114,26,8,163,207,54,66,48,91,169,167,0,138,52,0,21,85,101,255,0,224,250,209,90,215,208,42,174,39,154,69,119,100,17,234,50,214,179,7,253,115,187,95,134,120,19,192,213,163,148,226,145,71,30,193,59,75,54,120,116,125,253,193,62,119,222,121,39,227,204,216, +251,252,243,207,49,101,202,20,56,28,238,157,232,23,21,174,197,223,199,176,121,255,11,240,226,175,4,83,213,102,88,77,236,79,12,76,8,107,142,118,241,125,152,196,162,64,211,90,125,248,61,76,130,93,135,236,13,64,122,102,170,14,32,179,88,196,34,68,192,192, +100,25,238,38,168,132,178,181,11,1,26,248,19,255,174,167,34,231,125,84,125,159,41,91,124,222,4,248,62,74,41,30,123,236,49,183,151,194,213,19,69,17,31,125,244,145,207,207,246,7,234,238,252,167,77,155,6,167,211,253,211,252,158,255,91,107,68,134,105,153, +228,193,151,250,41,133,162,170,228,29,200,49,33,176,111,139,137,32,132,81,73,37,116,214,123,187,239,99,243,195,117,13,178,55,0,198,88,58,149,2,76,218,228,246,9,125,16,23,218,132,69,168,203,212,236,219,0,219,249,195,204,227,250,37,74,81,190,225,13,254, +36,32,72,81,74,241,232,163,143,226,205,55,223,244,232,250,250,199,254,211,166,77,99,156,25,123,43,86,172,192,29,119,220,225,246,157,63,0,116,107,27,137,233,35,217,220,253,243,165,126,202,178,91,143,193,84,185,137,121,220,216,144,198,232,144,208,151,73, +44,2,52,47,175,174,144,125,179,12,89,27,0,74,65,40,33,79,177,136,69,8,65,111,166,71,49,214,161,118,43,42,243,228,121,47,228,207,248,235,128,224,67,41,197,227,143,63,142,183,222,122,203,163,235,69,81,196,135,31,126,232,23,143,253,87,173,90,133,59,239, +188,211,163,226,31,106,20,241,254,236,206,16,5,239,127,118,249,99,127,117,84,93,252,24,84,50,49,143,219,183,69,42,4,194,232,96,40,137,206,145,251,140,0,89,131,207,223,146,54,6,0,147,23,246,237,19,250,48,91,111,121,169,202,29,159,4,196,97,63,114,224,77, +64,240,168,127,236,255,198,27,111,120,116,125,253,99,255,187,238,186,139,113,102,236,101,102,102,122,244,206,191,222,235,51,58,161,77,179,80,175,243,224,197,95,61,146,179,28,53,229,171,152,199,141,54,38,162,67,131,126,108,130,17,180,15,25,120,224,118, +54,193,174,76,230,39,0,244,25,22,113,234,238,254,217,111,249,235,172,42,65,213,119,159,49,143,27,72,120,19,16,248,234,239,252,61,125,236,47,8,2,62,252,240,67,191,120,236,191,106,213,42,76,157,58,213,227,226,63,103,122,43,164,14,241,126,221,63,47,254, +234,171,41,91,5,167,131,253,205,95,223,164,137,204,158,2,72,148,204,100,18,232,42,100,107,0,230,229,164,13,0,192,100,90,100,187,248,155,100,185,251,175,200,249,47,168,205,194,60,110,160,225,77,192,213,85,153,237,152,254,198,247,56,94,196,254,236,113, +37,80,74,241,196,19,79,120,124,231,47,8,130,223,220,249,175,92,185,210,171,59,255,191,143,105,134,153,119,181,242,58,15,94,252,125,3,165,86,89,206,9,136,50,54,64,167,196,129,172,194,245,123,37,55,141,205,196,130,43,144,239,9,0,161,51,152,132,33,4,125, +146,38,176,8,117,25,219,249,35,168,249,121,35,243,184,129,170,34,251,61,190,58,224,79,170,204,118,164,45,216,142,117,187,207,98,196,203,91,112,248,92,149,218,41,185,165,190,248,47,94,188,216,163,235,235,239,252,253,161,248,175,94,189,218,171,59,255,105, +195,155,96,193,99,222,239,98,206,103,251,251,22,115,85,46,236,22,246,19,192,251,36,77,96,246,20,64,0,155,90,122,229,216,50,88,176,53,181,5,0,38,103,37,182,141,239,141,56,89,238,254,223,231,203,254,220,196,87,7,252,161,190,248,239,46,44,3,0,20,87,90,48, +118,222,54,191,105,2,88,21,255,187,239,190,155,113,102,236,173,94,189,26,83,166,76,113,107,127,255,75,77,27,222,4,139,159,238,8,193,203,159,75,62,219,223,23,81,84,149,46,97,30,53,210,16,207,110,46,0,48,102,110,246,132,100,86,193,46,37,75,3,224,116,224, +113,0,12,218,31,130,62,50,188,251,183,158,62,0,243,145,157,204,227,6,3,254,58,224,175,197,191,158,63,53,1,179,103,207,230,197,223,5,254,84,252,249,157,191,103,172,181,187,101,217,28,232,134,102,163,193,104,199,90,145,8,194,195,44,2,253,25,243,6,32,99, +199,232,112,16,48,217,197,40,57,182,43,226,195,154,179,8,117,153,96,220,239,159,165,96,110,2,174,86,252,235,249,67,19,48,107,214,44,100,100,100,120,116,45,33,4,111,191,253,182,95,20,255,53,107,214,240,226,207,185,164,186,244,99,230,49,227,67,155,162, +101,108,55,86,225,254,145,190,126,42,243,51,167,153,55,0,212,166,255,7,0,38,137,222,208,116,20,139,48,151,177,28,219,13,203,241,189,204,227,6,155,96,108,2,174,87,252,235,249,114,19,224,109,241,127,231,157,119,112,255,253,247,51,206,138,189,53,107,214, +96,242,228,201,188,248,115,46,177,153,243,97,173,221,205,60,238,141,205,70,179,10,21,110,52,216,167,179,10,86,143,105,3,240,219,166,5,76,30,85,52,8,107,129,230,209,157,88,132,186,76,69,46,223,244,135,149,96,106,2,92,45,254,245,124,177,9,152,61,123,182, +215,119,254,193,80,252,239,188,173,49,47,254,65,168,170,244,99,176,254,94,54,141,234,128,70,17,173,153,196,162,160,143,178,222,24,136,105,48,221,128,130,219,0,48,153,172,112,67,51,246,119,255,230,195,223,193,122,250,0,243,184,193,44,24,154,0,119,139, +127,61,95,106,2,102,207,158,141,121,243,230,121,116,109,125,241,127,224,129,7,24,103,197,30,139,226,255,198,51,157,120,241,15,66,118,203,17,88,106,190,99,30,151,225,83,128,86,250,254,7,134,178,10,6,48,110,0,8,165,15,178,136,19,174,143,69,187,132,155, +88,132,186,12,191,251,151,71,32,47,17,244,180,248,215,43,174,180,96,194,252,237,170,238,19,240,212,83,79,121,92,252,5,65,192,7,31,124,224,23,197,255,139,47,190,8,138,226,207,151,250,201,167,186,116,25,88,127,95,91,199,221,128,216,144,198,76,98,17,16, +38,53,182,30,179,6,96,97,206,248,230,132,96,56,139,88,189,154,142,96,183,159,242,111,204,71,119,241,3,127,100,84,183,68,112,153,108,241,213,104,2,188,45,254,245,206,151,155,85,219,39,96,206,156,57,88,180,104,145,71,215,18,66,240,214,91,111,225,222,123, +239,101,156,21,123,223,124,243,141,87,19,254,166,250,73,241,231,75,253,228,101,183,30,135,165,118,23,211,152,132,16,244,108,58,130,81,48,140,204,200,27,207,236,68,60,102,13,128,131,8,247,129,193,210,63,189,198,136,206,13,111,102,144,209,229,170,182,201, +87,156,184,58,21,217,239,7,76,19,192,170,248,215,83,227,117,192,11,175,47,199,220,185,115,61,186,182,190,248,251,195,157,255,250,245,235,49,97,194,4,88,173,86,143,174,159,122,91,99,188,233,39,197,159,223,249,203,175,166,148,253,246,240,157,18,7,192,160, +13,99,17,74,35,73,154,191,179,8,4,48,106,0,210,51,83,117,0,97,114,155,208,165,209,80,232,53,33,44,66,253,206,122,38,31,150,147,63,51,141,201,93,89,32,52,1,172,139,127,61,37,155,128,151,86,30,192,130,15,86,123,116,109,125,241,127,240,65,166,79,27,101, +177,126,253,122,140,31,63,222,227,226,63,225,230,134,120,227,105,94,252,185,63,216,44,135,152,239,11,160,17,116,72,73,28,196,36,22,33,244,31,233,121,131,52,44,98,49,105,0,244,177,116,12,128,68,239,35,17,116,109,52,204,251,48,127,82,185,149,253,78,79, +220,213,249,115,19,32,87,241,175,167,68,19,240,242,170,3,120,109,221,33,143,174,13,182,226,255,223,57,222,31,235,203,139,127,224,169,41,251,156,121,204,110,141,111,1,97,243,153,213,200,136,4,38,59,237,50,105,0,136,64,152,108,252,211,34,166,51,162,141, +12,250,136,75,216,138,10,249,174,127,42,240,199,38,64,238,226,95,79,206,38,224,229,85,7,240,234,90,207,139,255,155,111,190,233,23,197,63,43,43,139,23,127,78,54,86,211,30,230,103,4,68,27,19,209,34,186,11,147,88,18,165,76,106,174,215,13,192,75,57,169,141, +65,113,11,139,100,186,53,102,18,230,50,85,219,151,1,148,255,242,168,193,159,154,128,106,133,138,127,61,57,154,0,22,197,255,161,135,30,98,150,143,92,178,178,178,48,110,220,56,175,138,255,251,179,121,241,231,174,173,186,108,5,243,152,221,155,220,202,36, +14,1,110,127,121,219,120,175,207,165,246,186,1,208,16,114,55,24,76,254,11,211,71,163,101,108,119,111,195,92,198,81,113,1,181,249,121,76,99,114,238,169,200,126,31,85,223,177,255,69,170,199,162,9,168,50,219,145,170,96,241,175,199,114,137,224,139,153,251, +189,42,254,239,190,251,174,95,20,255,181,107,215,98,236,216,177,30,23,255,201,195,26,225,191,115,58,67,35,250,118,241,231,75,253,212,103,169,249,22,14,219,89,166,49,147,99,186,35,202,216,128,69,40,141,104,215,76,245,54,8,131,87,0,116,154,247,49,128,174, +141,134,49,95,250,87,189,107,53,32,241,19,255,212,86,190,241,77,159,125,18,224,237,157,127,116,116,52,214,175,95,143,148,148,20,143,174,103,177,68,240,149,213,249,88,252,205,175,30,93,91,127,231,127,223,125,247,121,60,190,82,178,178,178,144,154,154,10, +155,205,230,209,245,227,7,55,196,91,255,76,241,139,59,127,190,212,207,23,80,212,86,124,197,52,34,33,12,231,185,17,234,245,106,0,175,26,128,121,121,169,253,0,180,243,58,9,34,162,75,195,33,222,134,185,12,181,91,80,243,211,122,166,49,57,207,249,226,235, +128,106,47,239,252,163,163,163,177,105,211,38,12,31,62,28,57,57,57,30,55,1,222,188,14,120,101,117,62,22,125,125,208,163,113,253,233,177,255,134,13,27,188,122,231,63,126,112,67,191,184,243,231,143,253,125,139,169,106,19,36,169,150,105,204,206,13,7,67, +35,104,89,132,106,155,145,55,169,183,55,1,188,123,2,64,233,93,94,93,255,155,214,113,61,17,166,143,102,17,234,119,53,63,101,65,50,171,191,5,43,247,7,95,106,2,88,21,255,158,61,123,2,0,226,227,227,21,111,2,230,122,89,252,223,120,227,13,191,41,254,227,198, +141,131,197,98,241,232,250,113,131,18,121,241,231,60,66,37,51,204,149,155,152,198,52,106,195,209,58,238,6,38,177,36,234,221,19,120,143,27,128,223,214,254,79,244,102,240,122,93,26,49,221,222,24,160,20,213,63,120,182,6,154,147,151,47,52,1,172,139,127,61, +37,155,128,185,171,243,241,31,47,139,255,195,15,203,114,196,56,83,44,138,255,7,207,118,225,197,159,243,88,77,197,23,0,216,190,74,78,105,56,136,73,28,2,154,246,222,238,251,60,126,156,224,113,3,96,140,39,183,3,240,250,182,61,92,31,131,164,104,207,62,48, +175,198,92,248,35,236,37,39,153,198,228,216,81,179,9,144,171,248,215,83,162,9,224,197,223,53,254,83,252,179,120,241,247,97,78,123,17,44,53,108,183,7,78,138,238,140,8,125,44,139,80,113,165,85,21,30,79,42,240,230,21,192,29,94,92,251,187,142,137,3,64,8, +211,51,137,80,189,115,21,211,120,28,123,106,52,1,114,23,255,122,114,54,1,222,22,255,197,139,23,243,226,239,6,101,138,255,235,224,197,223,183,213,86,124,193,52,30,33,4,29,18,7,176,137,229,69,45,246,168,242,102,236,24,29,78,41,101,178,19,81,135,6,253,89, +132,249,157,163,252,60,204,71,217,118,107,156,60,148,108,2,148,42,254,245,228,104,2,230,173,241,190,248,63,242,200,35,30,93,175,164,141,27,55,242,226,207,249,20,171,233,103,56,108,167,152,198,172,219,26,216,251,61,76,8,232,216,244,188,84,143,14,26,240, +108,63,97,187,97,60,64,141,30,93,123,137,196,240,100,196,135,54,245,54,204,101,106,246,174,3,40,95,250,231,47,42,178,223,7,0,68,246,103,178,154,244,47,244,173,135,160,170,198,132,212,180,123,60,46,254,177,177,177,200,206,206,70,215,174,93,221,186,46, +62,62,30,217,217,217,184,249,230,155,145,159,159,239,246,184,245,251,4,124,61,123,32,62,223,113,50,40,30,251,179,216,228,199,63,118,248,147,167,248,59,28,20,191,28,168,194,143,123,203,113,248,104,45,78,158,54,225,220,5,43,170,170,236,176,90,37,136,26, +2,189,78,64,68,184,6,77,155,24,209,188,105,8,58,182,15,199,141,61,163,209,186,101,40,211,92,2,141,169,114,3,34,226,217,45,151,141,9,105,136,198,145,109,112,182,210,179,37,188,151,8,53,80,140,6,240,169,187,23,122,212,0,80,208,73,158,92,247,103,157,18, +7,178,8,243,7,201,137,154,125,89,108,99,114,178,147,179,9,168,170,170,194,232,135,94,193,238,163,165,30,93,239,105,241,175,151,144,144,128,220,220,92,143,155,128,243,229,102,12,126,62,27,53,22,135,71,227,251,83,241,247,118,169,159,255,236,240,199,182, +248,219,237,18,182,108,47,197,23,235,206,99,115,110,9,76,102,231,53,191,190,26,192,197,82,27,142,157,48,1,248,227,247,34,33,94,143,81,195,27,96,220,200,134,232,214,37,146,73,110,129,196,84,181,25,225,113,247,128,16,38,75,248,0,212,213,64,6,13,0,0,164, +193,131,6,192,237,223,148,121,155,83,35,33,162,8,242,17,191,124,0,0,32,0,73,68,65,84,128,222,221,107,47,37,16,17,15,247,125,15,33,218,8,111,194,92,198,252,235,14,20,127,58,155,89,60,78,89,81,67,239,99,218,4,84,85,85,225,214,91,111,197,206,157,158,157, +5,17,21,21,133,205,155,55,187,252,216,255,90,74,74,74,48,100,200,16,236,223,191,223,235,88,174,34,132,224,245,215,95,199,163,143,62,170,216,152,158,218,180,105,19,198,140,25,227,241,99,255,177,3,19,241,191,231,130,235,177,127,173,201,137,207,86,157,197, +123,31,158,192,185,243,158,125,223,174,166,99,251,112,220,55,189,57,198,141,106,8,209,203,239,105,32,137,110,248,44,140,225,108,222,221,3,128,213,97,194,91,223,221,15,187,211,179,166,247,18,22,11,65,124,250,224,149,110,109,43,234,254,28,0,13,25,5,47, +139,63,0,180,140,237,206,180,248,3,64,245,238,181,76,227,113,202,170,200,126,31,149,219,216,204,9,240,165,226,15,120,63,39,192,93,193,84,252,199,4,89,241,167,20,88,245,229,57,244,25,186,29,47,188,124,136,121,241,7,128,252,131,213,120,124,230,1,12,159, +176,19,187,127,170,96,30,223,95,153,42,217,110,46,167,215,132,176,218,2,223,160,7,70,184,123,145,7,147,0,233,120,247,175,249,171,142,137,108,39,255,57,171,75,249,228,191,0,80,145,227,125,19,224,109,241,143,141,141,69,94,94,30,179,226,95,175,126,78,64, +199,142,29,153,198,253,51,127,42,254,27,55,110,244,170,248,143,27,148,136,15,131,168,248,159,60,109,198,152,41,63,224,241,153,7,112,177,212,179,45,145,221,145,127,176,26,227,238,248,17,207,190,120,16,86,43,159,91,101,53,237,131,195,126,158,105,204,182, +241,94,109,230,247,59,1,100,130,251,215,184,33,125,237,168,16,80,120,125,156,145,86,212,35,57,166,155,183,97,46,83,179,119,29,32,93,251,221,23,231,31,188,105,2,88,20,127,111,222,249,95,79,253,156,0,185,154,0,66,8,94,123,237,53,191,41,254,99,199,142,229, +179,253,93,244,245,250,11,184,117,236,247,216,163,240,29,185,36,81,124,252,201,105,140,154,180,11,199,79,154,20,29,219,247,80,152,43,55,50,141,216,50,182,59,116,162,193,235,56,148,210,17,11,54,78,115,107,38,167,91,13,128,49,204,112,59,128,16,183,178, +186,130,228,152,110,208,138,94,191,69,184,76,237,207,108,255,82,56,117,121,210,4,248,122,241,175,39,87,19,80,95,252,31,123,236,49,166,113,229,176,105,211,38,175,138,255,216,129,193,85,252,95,123,251,24,30,154,241,11,170,107,60,155,12,202,66,254,193,106, +140,74,219,133,189,251,42,85,203,193,23,152,170,54,131,229,234,13,173,168,71,114,44,147,27,226,16,135,198,114,139,59,23,184,213,0,72,148,140,117,47,159,43,107,155,192,230,145,71,61,235,153,2,216,75,79,51,141,201,169,207,157,38,160,182,182,22,183,223, +126,187,207,23,255,122,172,155,0,66,8,94,125,245,85,191,40,254,155,55,111,246,186,248,7,203,59,127,73,162,152,243,127,7,177,224,245,163,160,62,176,93,64,121,133,29,147,166,239,198,246,239,60,91,85,19,8,156,142,139,176,153,217,78,230,109,151,208,135,77, +32,66,199,184,243,229,46,55,0,153,153,169,34,1,189,205,253,140,46,167,17,180,104,201,166,219,249,93,237,254,205,76,227,113,190,195,149,38,192,108,54,99,244,232,209,248,246,219,111,61,26,35,42,42,10,27,54,108,80,172,248,215,75,72,72,64,94,94,30,147,137, +129,115,231,206,197,227,143,63,206,32,43,121,109,222,188,25,99,198,140,129,217,108,246,232,250,209,3,26,4,205,157,63,165,192,115,255,62,132,37,159,250,214,205,141,201,236,196,61,15,237,195,143,123,131,119,114,160,169,42,151,105,188,186,215,0,94,111,173, +3,2,114,123,102,102,170,232,234,215,187,220,0,28,139,37,125,1,120,189,121,113,139,152,174,76,254,67,127,39,73,48,29,96,251,151,193,249,150,107,53,1,86,171,21,227,199,143,71,110,174,103,63,3,114,77,248,115,21,139,137,129,175,190,250,42,102,206,156,201, +48,43,121,176,40,254,31,62,215,21,90,77,224,23,127,73,162,248,231,191,242,125,174,248,215,51,155,157,184,231,193,159,130,118,78,128,165,102,59,40,181,51,139,87,119,99,204,100,53,64,252,209,24,184,124,212,160,203,13,0,33,108,182,254,101,253,248,223,124, +124,55,156,53,158,237,240,198,249,143,43,53,1,78,167,19,119,220,113,7,54,108,216,224,81,76,165,31,251,95,141,55,175,3,22,45,90,132,39,158,120,66,134,172,216,202,206,206,230,197,223,69,146,68,49,243,249,2,124,186,242,44,187,196,100,80,94,97,199,125,143, +253,28,148,171,3,36,103,13,172,181,187,153,198,108,199,168,54,18,226,250,114,64,151,119,2,164,20,35,189,221,182,88,20,52,104,197,166,203,249,157,233,151,108,166,241,56,223,85,145,243,219,142,129,3,234,54,11,122,252,241,199,177,102,205,26,143,98,249,74, +241,175,231,201,142,129,139,22,45,194,147,79,62,41,115,102,222,203,206,206,198,232,209,163,61,46,254,163,250,7,87,241,255,231,191,10,240,217,42,239,139,127,227,198,141,49,112,224,64,116,234,212,9,205,155,55,135,86,91,183,131,157,201,100,66,97,97,33,126, +250,233,39,108,223,190,29,149,149,158,79,234,43,56,84,141,244,185,191,98,110,122,123,175,243,245,55,230,234,92,24,194,110,98,22,47,57,182,110,114,188,215,155,2,17,140,2,240,156,107,95,234,130,249,57,147,90,74,68,58,234,85,82,168,251,15,76,237,204,110, +167,62,234,176,225,204,130,209,144,44,181,204,98,114,190,47,106,200,125,120,247,251,115,152,53,107,150,71,215,251,90,241,191,84,113,113,177,75,77,192,127,254,243,31,204,152,49,67,161,172,60,151,147,147,131,81,163,70,121,85,252,63,250,87,240,20,255,103, +158,43,192,231,171,61,47,254,26,141,6,105,105,105,120,232,161,135,208,167,79,31,144,43,28,137,125,41,171,213,138,111,190,249,6,139,22,45,242,120,14,141,32,16,124,249,105,47,244,232,22,229,209,245,254,138,16,29,26,180,252,28,130,192,238,12,133,85,191, +100,160,176,116,143,247,129,156,104,62,107,216,202,235,158,94,228,210,43,0,10,105,184,247,25,1,173,98,217,190,103,53,31,217,201,139,127,16,250,232,181,151,48,123,182,103,141,164,47,23,127,192,181,215,1,11,23,46,244,139,226,159,155,155,235,245,157,191, +63,20,255,218,138,181,62,81,252,251,247,239,143,125,251,246,225,147,79,62,65,223,190,125,175,91,252,1,64,175,215,99,252,248,241,216,177,99,7,86,175,94,141,134,13,27,186,61,174,36,81,204,121,241,32,36,201,7,150,41,40,136,82,27,172,53,158,173,58,186,26, +70,243,0,64,69,184,52,97,223,165,6,64,34,24,230,93,58,117,90,198,178,253,208,53,29,220,202,52,30,231,251,246,156,174,194,204,175,143,130,122,176,38,42,38,38,198,167,139,127,189,107,53,1,11,23,46,196,83,79,61,165,66,86,238,201,205,205,197,168,81,163,96, +50,121,54,73,108,84,63,255,40,254,166,202,44,84,22,191,5,111,139,255,211,94,20,127,66,8,158,127,254,121,228,229,229,121,53,153,116,252,248,241,216,183,111,31,6,14,116,255,144,182,3,5,213,200,218,92,236,241,216,254,202,92,227,217,83,147,171,105,25,215, +29,76,142,8,166,174,213,236,235,54,0,233,121,131,52,4,240,250,216,190,184,208,166,136,48,196,123,27,230,119,212,233,128,249,240,247,204,226,113,190,239,124,149,21,15,172,60,4,155,211,253,73,71,81,81,81,216,180,105,147,207,23,255,122,87,106,2,22,44,88, +16,20,197,127,100,191,6,248,232,121,255,40,254,44,238,252,159,126,174,0,43,60,44,254,162,40,226,195,15,63,196,255,253,223,255,65,20,93,94,253,117,85,9,9,9,216,176,97,3,70,143,30,237,246,181,111,188,119,220,235,241,253,141,181,118,55,40,245,250,32,159, +223,69,232,99,17,31,214,204,251,64,4,67,92,89,14,120,221,6,192,128,248,222,0,188,62,27,146,245,218,127,235,201,125,144,204,213,76,99,114,190,203,226,144,112,127,230,65,148,212,184,191,255,121,120,120,56,214,175,95,143,30,61,122,200,144,153,124,46,109, +2,22,44,88,128,167,159,126,90,237,148,174,43,47,47,207,235,226,255,113,16,21,255,167,158,205,247,170,248,47,91,182,12,211,167,79,247,56,135,43,49,24,12,88,177,98,133,219,79,2,246,231,87,5,221,222,0,148,90,97,173,221,203,52,38,163,137,242,209,199,99,113, +221,15,188,235,191,2,112,241,81,194,245,176,222,251,223,116,112,27,211,120,156,111,155,189,246,40,126,57,231,214,73,151,0,128,144,144,16,172,93,187,22,55,221,196,110,182,174,146,18,18,18,240,227,143,63,250,77,241,31,57,114,164,199,197,127,68,223,4,124, +244,124,151,160,41,254,51,230,228,35,115,205,57,143,174,215,104,52,88,190,124,57,166,76,153,226,113,14,215,98,48,24,144,153,153,137,70,141,26,185,117,221,151,235,216,30,148,227,15,44,172,95,3,176,154,7,0,122,221,109,129,175,219,0,16,6,239,255,117,162, +17,141,35,219,122,27,230,15,148,194,116,104,7,187,120,156,79,251,116,239,5,124,177,223,253,247,139,26,141,198,163,59,25,95,99,52,50,220,56,75,38,91,182,108,241,186,248,127,252,66,87,232,52,30,28,80,122,9,127,42,254,43,191,240,188,248,47,91,182,12,147, +39,79,246,56,7,87,36,36,36,224,205,55,223,116,235,154,111,54,22,249,196,150,197,74,178,212,238,4,40,187,131,232,26,69,180,65,136,206,235,135,238,0,33,215,173,221,215,252,109,203,216,49,58,156,82,244,242,54,143,164,152,20,136,130,203,91,14,92,151,245, +236,65,56,171,74,152,197,227,124,215,161,162,90,188,184,225,152,71,215,190,253,246,219,24,57,146,201,254,85,220,53,120,91,252,111,239,19,60,197,223,233,164,120,114,182,119,197,127,249,242,229,178,23,255,122,227,198,141,67,191,126,253,92,254,250,146,139, +54,28,62,234,254,147,58,127,38,57,171,97,101,120,54,0,33,4,73,209,157,89,132,234,157,190,118,212,53,15,239,187,230,111,156,100,215,247,133,27,155,5,93,13,235,199,255,230,95,217,62,114,225,124,83,173,205,249,255,236,157,119,120,21,229,242,199,191,187, +167,167,39,36,129,16,122,175,138,96,65,1,33,20,105,118,165,138,88,193,142,160,34,112,127,234,141,215,114,173,216,175,138,5,43,72,2,168,84,69,64,4,105,130,74,239,189,4,210,123,78,63,239,239,15,8,2,73,224,156,221,217,83,114,230,243,60,247,121,174,201,238, +119,135,36,103,103,222,121,103,230,197,195,179,119,193,230,242,189,232,239,185,231,158,195,152,49,99,52,176,138,57,155,74,231,95,94,174,172,29,119,208,53,201,248,50,61,248,157,63,69,171,159,219,125,106,229,63,251,7,229,206,255,219,111,191,197,176,97, +195,20,219,160,4,95,11,79,215,111,44,212,200,146,224,197,86,78,219,14,216,56,190,3,133,140,209,20,97,190,224,120,193,11,127,234,132,116,45,133,21,77,19,46,165,144,57,131,117,223,122,82,61,38,56,121,110,241,126,28,200,247,189,135,124,212,168,81,72,79, +79,167,55,136,57,135,223,126,251,45,44,156,63,69,171,159,219,45,240,196,20,245,206,127,232,80,237,254,157,53,49,104,208,32,196,199,199,123,125,253,246,157,225,87,156,77,61,22,152,40,0,128,36,93,184,131,239,130,159,60,9,66,245,230,105,156,165,46,98,204, +137,106,101,206,224,169,40,134,227,196,94,50,61,38,56,249,101,119,62,230,108,246,125,223,191,115,231,206,248,248,227,143,189,26,130,194,40,231,247,223,127,87,229,252,251,93,153,20,86,105,255,39,254,181,29,179,127,84,230,252,117,58,29,190,252,242,203, +128,56,127,0,48,26,141,232,209,163,135,215,215,31,58,18,126,7,4,185,28,71,225,118,158,36,211,139,53,39,33,214,156,76,33,117,193,69,124,141,159,190,169,107,134,88,0,168,30,221,215,48,174,157,90,137,115,176,238,91,15,136,240,59,124,34,156,200,47,119,98, +242,2,223,39,79,167,164,164,96,222,188,121,136,136,184,224,182,23,163,146,149,43,87,98,192,128,1,40,43,83,182,215,59,224,234,36,204,120,241,50,152,12,225,225,252,39,76,222,166,106,229,63,115,230,76,140,28,57,82,177,13,20,248,210,66,123,228,168,178,201, +143,161,142,173,130,96,132,239,89,52,142,87,62,212,233,44,186,166,255,122,183,185,166,111,214,248,9,180,91,113,53,0,163,218,167,55,34,15,0,254,32,213,99,130,143,41,11,247,33,191,220,183,163,54,141,70,35,230,206,157,139,212,212,84,141,172,98,0,96,213, +170,85,24,60,120,176,226,149,255,128,171,147,240,85,250,101,97,179,242,159,48,121,27,230,204,83,214,26,103,48,24,48,115,230,76,12,25,50,68,177,13,84,52,105,210,196,235,107,75,203,92,218,25,18,196,216,203,105,3,128,70,52,219,0,102,51,202,107,92,200,215, +248,41,148,36,120,95,250,121,1,72,51,0,66,192,118,128,118,175,133,9,46,230,109,203,197,146,93,249,62,223,247,202,43,175,160,107,87,218,163,166,153,115,89,181,106,21,6,13,26,164,120,229,223,191,235,41,231,31,46,43,255,241,147,212,57,255,25,51,102,224, +246,219,111,87,108,3,37,177,177,222,183,165,149,87,208,181,196,133,18,246,138,191,33,4,93,240,211,56,142,168,14,64,136,26,247,111,106,14,0,0,213,147,83,98,76,117,16,75,56,254,215,145,189,15,238,82,223,157,3,19,26,148,216,92,120,97,137,239,227,68,111, +188,241,70,140,31,63,94,3,139,152,74,40,156,255,215,207,135,143,243,127,124,210,54,204,157,175,110,229,31,44,206,31,128,79,99,134,61,238,48,27,4,112,26,225,169,128,211,182,139,76,47,202,20,143,132,8,223,6,49,85,135,7,82,141,43,163,106,63,141,66,64,18, +192,149,106,31,76,148,194,56,131,109,223,6,82,61,38,184,120,117,217,33,159,71,253,54,106,212,8,211,167,79,231,162,63,13,249,253,247,223,195,194,249,83,181,250,61,62,105,27,190,87,233,252,111,187,237,54,197,54,104,129,47,191,251,136,72,245,103,18,132, +42,193,216,13,32,1,190,5,0,175,253,58,164,21,128,4,181,15,166,46,0,180,29,218,68,170,199,4,15,127,29,43,197,204,191,124,171,162,149,101,25,95,126,249,37,18,18,84,255,169,50,53,160,214,249,95,119,85,104,56,127,170,86,191,113,79,111,85,229,252,191,251, +238,187,160,115,254,0,112,228,200,69,143,150,63,67,100,4,221,208,183,80,131,114,32,16,0,52,160,153,160,155,252,223,165,183,53,171,238,27,213,127,42,133,250,213,63,64,92,0,232,241,192,126,148,246,135,203,4,7,30,113,170,231,223,215,227,196,31,127,252,113, +244,234,213,75,19,155,24,96,245,234,213,24,52,104,16,74,75,149,245,117,247,187,50,9,223,252,39,52,156,63,197,202,127,220,211,91,241,195,2,101,173,96,149,206,255,214,91,111,85,108,131,150,108,223,190,221,235,107,83,83,106,44,58,175,245,56,109,187,73,79, +7,172,31,211,138,68,71,146,229,106,179,0,213,126,50,61,82,205,123,6,222,18,97,140,69,156,165,174,90,153,51,56,178,247,193,99,11,175,17,147,225,194,220,45,217,216,118,194,183,223,109,219,182,109,241,210,75,47,105,100,17,179,122,245,106,12,28,56,80,149, +243,255,246,133,240,112,254,46,183,192,99,19,213,57,255,89,179,102,5,173,243,7,78,13,125,242,150,38,141,194,183,13,87,8,39,156,182,221,100,122,113,150,186,136,164,56,23,160,134,58,128,106,63,157,18,132,234,12,64,74,116,115,181,18,231,192,233,255,218, +73,133,211,141,215,151,31,246,233,30,157,78,135,47,190,248,34,36,14,201,9,69,212,58,255,190,87,38,134,205,202,223,229,22,24,55,113,43,126,92,168,206,249,223,114,203,45,138,109,208,154,13,27,54,224,240,97,239,63,163,173,90,70,106,104,77,240,99,183,110, +35,213,171,23,221,130,64,69,92,85,221,87,171,124,66,211,51,134,24,1,116,84,251,184,148,24,10,163,255,193,126,120,11,169,30,19,28,124,188,250,56,178,75,125,43,252,123,248,225,135,113,229,149,36,187,84,204,121,172,89,179,70,85,218,191,247,229,137,248,246, +63,157,97,54,214,126,231,239,118,11,76,152,180,77,149,243,207,200,200,8,106,231,15,0,31,124,240,129,79,215,95,217,197,251,177,193,181,17,71,5,109,0,80,159,198,151,94,242,241,198,177,134,243,191,88,229,83,26,145,132,118,0,76,106,159,70,26,0,8,1,251,17, +14,0,106,27,249,229,78,124,178,246,184,79,247,164,166,166,226,197,23,95,212,200,162,240,102,237,218,181,24,56,112,32,74,74,74,20,221,223,247,202,68,204,124,49,60,156,191,203,45,240,232,83,91,21,183,250,25,141,70,100,100,100,224,230,155,111,86,108,131, +63,216,189,123,55,102,204,152,225,245,245,102,179,140,75,59,196,104,104,81,240,227,176,237,32,157,7,80,63,150,164,14,192,156,87,90,92,165,162,176,202,39,213,45,164,206,234,159,37,145,110,1,56,243,142,192,93,30,126,39,76,213,118,62,90,115,12,21,78,223, +134,134,188,253,246,219,136,137,9,239,23,140,22,172,93,187,22,3,6,12,80,236,252,251,92,17,26,43,255,242,162,5,52,206,255,201,173,152,183,72,217,202,63,84,156,191,199,227,193,35,143,60,2,167,211,251,169,156,125,122,38,193,168,242,111,32,212,17,30,43,156, +246,253,100,122,245,99,90,64,146,212,255,76,245,30,79,149,99,121,171,170,74,66,245,217,189,113,150,100,88,12,209,106,101,206,96,63,74,155,82,97,2,79,110,153,3,223,108,244,109,245,148,150,150,22,84,195,81,106,11,20,206,127,198,11,193,239,252,79,181,250, +189,15,10,231,63,127,177,58,231,127,211,77,55,41,182,193,95,188,242,202,43,88,182,108,153,79,247,220,52,184,158,70,214,132,22,78,219,78,50,45,163,206,130,196,8,245,35,206,69,53,190,189,202,39,86,18,232,164,246,65,212,5,128,142,19,116,85,149,76,112,240, +209,154,227,176,58,189,63,212,73,150,101,188,249,230,155,26,90,20,158,172,91,183,78,149,243,239,125,121,232,56,127,138,149,255,35,79,108,81,229,252,51,51,51,67,194,249,103,100,100,224,217,103,159,245,233,158,164,68,35,250,246,162,155,252,26,202,56,108, +123,72,245,104,182,212,165,11,7,0,233,233,233,50,160,62,0,168,23,67,27,0,216,143,211,141,87,100,2,79,65,133,19,223,250,184,250,31,61,122,52,46,187,76,117,114,138,57,11,181,206,63,173,75,29,204,120,225,178,176,114,254,11,126,202,86,116,191,209,104,196, +236,217,179,113,227,141,55,42,182,193,95,252,240,195,15,184,243,206,59,225,241,248,118,234,234,125,163,27,195,100,10,239,244,127,37,78,226,0,32,41,170,49,133,76,39,33,112,206,200,212,115,126,91,145,105,219,27,3,136,82,251,20,202,12,128,112,59,225,204, +246,253,104,88,38,120,249,106,195,9,216,92,222,191,92,44,22,11,23,254,105,192,147,79,62,137,226,226,98,69,247,234,100,9,47,61,212,6,22,147,186,177,175,33,225,252,93,2,15,79,80,239,252,111,184,225,6,197,54,248,139,31,126,248,1,195,134,13,131,195,225,91, +103,78,124,156,1,119,143,108,168,145,85,161,135,203,113,12,30,15,221,220,154,228,72,146,0,32,238,165,149,195,27,156,253,133,115,2,0,225,17,36,7,16,39,70,210,253,33,56,179,15,64,184,124,59,26,150,9,94,108,46,15,190,218,224,219,234,255,129,7,30,224,99, +126,53,224,135,31,126,64,199,142,202,58,126,221,30,129,91,158,222,136,221,135,149,191,228,66,193,249,159,154,237,191,21,11,127,86,238,252,51,50,50,66,194,249,47,92,184,16,195,135,15,247,217,249,3,192,164,241,45,16,29,29,190,35,128,171,34,224,180,209, +21,2,38,211,100,0,160,119,123,206,25,207,123,78,0,224,134,172,58,0,136,50,198,211,22,0,102,113,250,191,54,49,103,115,14,10,42,188,15,232,34,34,34,48,105,210,36,13,45,10,95,146,146,146,176,116,233,82,180,111,175,236,99,159,93,96,199,205,19,55,226,192, +241,10,159,239,13,5,231,239,114,9,60,52,97,139,226,9,127,38,147,9,115,230,204,9,137,61,255,239,191,255,30,183,220,114,11,236,118,223,199,216,94,210,62,6,35,135,54,184,248,133,97,6,229,68,64,179,33,10,209,38,245,103,158,8,160,230,0,0,194,211,86,237,3, +18,163,104,211,64,14,14,0,106,13,2,192,103,235,124,235,251,127,240,193,7,81,175,30,87,22,107,69,114,114,50,150,47,95,174,56,8,200,202,179,97,240,132,63,124,10,2,66,197,249,63,252,196,22,197,43,127,147,201,132,217,179,103,227,250,235,175,87,108,131,191, +152,59,119,46,134,13,27,230,83,187,95,37,145,17,58,188,247,70,71,232,116,124,26,231,249,56,237,123,73,245,146,34,27,169,214,144,112,110,150,95,62,247,155,146,234,12,0,101,250,31,0,28,39,104,127,136,76,224,88,119,168,24,7,242,173,94,95,111,50,153,240, +212,83,79,105,104,17,3,248,55,8,8,137,62,255,211,43,127,53,206,127,206,156,57,33,227,252,135,15,31,174,200,249,3,192,203,255,110,139,22,205,194,123,244,111,77,56,109,196,1,0,193,54,128,36,213,144,1,56,93,29,216,70,237,3,18,35,9,83,65,194,3,103,158,111, +115,226,153,224,101,198,159,190,165,82,239,188,243,78,164,164,164,104,100,13,115,54,201,201,201,248,245,215,95,21,215,4,100,229,217,48,224,241,245,23,172,9,8,137,62,127,151,192,131,227,55,99,209,18,117,123,254,131,7,15,86,108,131,191,152,51,103,142,42, +231,63,238,161,102,184,253,230,250,196,86,213,30,92,206,147,16,30,27,153,94,82,148,250,12,128,16,104,127,118,39,192,153,0,224,116,117,160,234,14,128,196,8,186,12,128,171,48,11,194,65,247,3,100,2,71,65,133,19,63,239,202,247,250,122,73,146,48,97,194,4, +13,45,98,206,71,203,154,128,80,73,251,63,56,126,51,22,255,146,163,232,126,147,201,132,239,191,255,62,36,90,253,230,204,153,131,17,35,70,40,118,254,67,110,169,143,167,31,167,61,239,165,246,33,224,114,28,37,83,75,38,216,2,0,16,243,218,47,195,207,172,170, +206,4,0,58,151,187,165,122,109,137,52,3,224,200,57,72,166,197,4,150,185,91,114,224,112,123,223,250,55,104,208,32,180,107,215,238,226,23,50,164,104,177,29,16,42,206,255,129,199,213,59,255,65,131,6,41,182,193,95,204,158,61,91,149,243,191,249,250,122,120, +243,165,246,144,120,219,255,162,56,29,135,200,180,18,34,234,147,140,4,150,100,215,153,62,253,127,212,36,168,14,231,98,76,9,48,233,233,206,130,118,114,0,80,107,152,187,197,183,23,235,35,143,60,162,145,37,204,197,160,220,14,8,37,231,255,211,82,101,206, +191,114,194,223,192,129,3,21,219,224,47,230,204,153,131,145,35,71,42,118,254,55,12,172,135,119,94,227,162,63,111,113,217,233,182,176,117,178,1,209,166,58,170,117,196,89,190,254,76,0,32,65,82,61,189,167,14,229,254,63,56,0,168,45,236,207,179,98,199,201, +114,175,175,111,216,176,33,174,187,238,58,13,45,98,46,70,82,82,18,150,45,91,166,56,8,200,46,176,227,134,167,183,225,64,133,234,147,197,107,36,88,156,127,168,12,249,81,187,242,191,97,96,61,188,255,102,71,232,217,249,123,141,203,65,91,195,150,96,81,223, +17,85,109,0,0,8,213,25,128,56,75,93,181,18,231,224,200,57,64,170,199,4,134,31,183,249,246,114,29,51,102,12,116,58,117,19,230,24,245,168,14,2,114,139,208,187,119,111,236,220,73,119,48,74,37,20,206,223,233,244,132,149,243,87,179,242,191,113,16,59,127,37, +56,237,135,72,245,226,35,212,7,0,103,47,246,255,233,2,128,250,45,128,88,115,178,90,137,127,240,184,225,202,167,43,160,96,2,199,188,109,121,94,95,171,211,233,112,239,189,247,106,104,13,227,11,106,11,3,79,158,60,137,126,253,250,97,223,62,186,113,222,20, +173,126,78,167,7,99,199,41,119,254,102,179,25,243,230,205,11,9,231,159,145,145,161,106,229,127,219,141,41,120,255,13,118,254,74,112,187,114,33,60,190,15,202,170,137,56,138,12,0,170,221,2,64,51,181,194,148,25,0,87,113,54,143,0,174,5,236,204,46,199,161, +2,239,123,255,211,210,210,120,236,111,144,161,182,38,224,248,241,227,232,209,163,7,73,38,128,162,213,239,212,202,127,11,150,44,207,85,116,191,201,100,66,102,102,38,250,247,239,175,216,6,127,49,123,246,108,220,113,199,29,112,185,92,138,238,191,113,80, +61,76,125,165,3,239,249,43,70,192,229,204,34,83,75,176,144,180,69,159,27,0,188,188,244,150,58,32,104,1,140,179,208,101,0,92,133,116,63,52,38,112,44,221,83,224,211,245,35,70,140,208,200,18,70,13,106,183,3,78,158,60,169,122,59,128,46,237,191,5,63,47,83, +94,237,31,42,19,254,50,51,51,49,98,196,8,197,206,255,166,193,245,240,30,175,252,85,227,114,248,118,246,201,133,160,200,0,0,136,77,95,116,71,12,112,58,0,208,235,244,36,205,251,113,132,91,0,174,2,14,0,106,3,190,4,0,38,147,9,183,222,122,171,134,214,48,106, +8,100,16,16,44,206,63,84,38,252,101,102,102,98,228,200,145,170,156,255,187,175,179,243,167,192,237,164,11,0,226,45,117,33,17,244,95,154,205,182,134,192,153,45,0,161,186,124,223,108,136,130,73,79,55,18,210,85,68,247,67,99,2,67,94,185,19,91,179,74,189, +190,190,127,255,254,136,139,139,211,208,34,70,45,129,168,9,160,112,254,14,135,7,247,63,182,89,177,243,183,88,44,152,55,111,94,72,76,248,251,238,187,239,84,57,255,219,111,174,143,247,216,249,147,225,114,42,59,76,170,58,168,90,1,33,164,70,192,233,0,64, +8,168,30,49,20,103,166,237,0,112,242,22,64,200,179,98,95,1,60,62,188,179,67,225,212,52,70,253,176,160,227,199,143,163,87,175,94,94,5,1,84,206,127,204,184,205,88,250,171,178,61,127,139,197,130,31,127,252,49,36,90,83,191,251,238,59,220,121,231,157,170, +156,255,212,151,219,243,158,63,33,110,194,26,0,0,68,179,0,164,127,50,0,149,255,161,6,202,253,127,128,183,0,106,3,171,15,20,123,125,173,44,203,33,49,69,141,57,133,63,10,3,41,91,253,212,56,255,121,243,230,161,95,191,126,138,109,240,23,25,25,25,170,156, +255,77,131,235,177,243,215,0,202,12,0,0,146,99,129,165,179,3,0,120,212,111,1,196,152,18,213,74,156,3,23,1,134,62,235,14,123,31,0,92,113,197,21,124,236,111,136,161,101,77,0,149,243,31,59,110,179,226,106,255,74,231,223,183,111,95,197,54,248,139,140,140, +12,85,213,254,55,95,95,15,239,189,206,19,254,180,192,237,204,134,16,202,126,47,213,17,69,16,0,224,116,214,255,84,0,32,73,170,143,116,138,52,209,237,221,10,135,21,30,107,9,153,30,227,127,14,230,91,113,162,196,238,245,245,188,250,15,77,180,168,9,40,47, +90,72,146,246,191,247,145,77,97,225,252,103,204,152,161,106,207,127,232,173,245,217,249,107,138,7,30,151,111,221,80,23,34,218,72,16,0,72,34,5,248,103,14,128,234,13,252,40,35,93,0,224,46,163,251,97,49,129,97,205,33,239,87,255,0,208,167,79,31,141,44,97, +180,134,178,38,160,188,104,33,138,115,222,131,90,231,127,223,163,155,176,252,55,239,7,80,157,77,68,68,4,230,207,159,31,50,206,127,244,232,209,112,187,221,138,238,31,122,107,125,188,249,82,123,200,50,59,127,45,241,184,139,200,180,40,50,0,66,156,242,249, +100,1,64,36,97,0,32,220,60,0,40,212,217,120,196,251,12,78,68,68,4,174,184,226,10,13,173,97,180,134,162,38,160,123,247,43,177,113,237,43,80,157,246,127,124,179,42,231,63,111,222,188,144,8,72,103,205,154,133,187,238,186,75,177,243,31,118,91,42,59,127,63, +33,160,236,119,84,29,36,53,0,64,50,0,200,233,191,246,210,3,80,173,24,65,24,0,72,6,51,153,22,19,24,54,249,208,254,215,163,71,15,24,141,70,13,173,97,252,129,234,179,3,178,11,49,116,244,6,236,221,239,253,193,81,103,227,116,158,170,246,255,69,97,218,63,212, +156,255,168,81,163,20,167,253,135,221,150,138,55,94,108,199,206,223,79,72,146,137,76,139,34,0,0,144,148,145,49,68,39,27,116,9,73,56,231,80,32,101,80,110,1,232,162,235,0,50,31,6,19,170,148,218,93,56,236,195,248,223,158,61,123,106,104,13,227,79,212,214, +4,228,228,217,49,252,158,141,56,116,216,183,249,233,118,187,7,247,60,180,73,149,243,159,63,127,126,72,56,255,111,190,249,70,85,193,223,112,118,254,126,71,103,160,235,146,59,181,5,160,250,119,167,219,87,15,9,178,193,173,83,157,254,151,37,29,204,122,213, +147,132,207,32,233,12,48,212,33,25,78,200,4,128,45,89,101,62,245,255,119,237,218,85,59,99,24,191,163,118,59,224,100,182,29,183,140,244,62,19,80,153,246,255,117,149,186,61,255,222,189,123,43,186,223,159,204,154,53,11,247,220,115,143,226,180,255,240,219, +82,241,58,59,127,191,162,211,39,66,150,233,252,163,94,54,192,164,143,80,173,35,220,114,93,89,184,145,164,86,40,210,24,75,50,158,240,108,204,77,59,147,234,49,254,99,75,86,153,215,215,202,178,140,46,93,186,104,104,13,19,8,252,149,9,176,219,61,184,251,193, +191,21,247,249,71,68,68,96,193,130,5,33,225,252,191,254,250,107,85,43,255,17,183,179,243,15,4,166,136,78,228,154,22,131,250,128,66,239,22,73,178,71,167,126,255,63,210,24,175,218,152,243,137,104,199,105,225,80,101,79,142,247,233,219,54,109,218,32,38,38, +70,67,107,152,64,161,117,38,192,225,56,181,242,95,241,123,190,34,253,202,149,127,90,90,154,162,251,253,201,119,223,125,135,123,239,189,87,213,202,255,181,23,216,249,7,2,115,84,55,122,77,138,140,187,236,137,151,37,8,213,155,247,20,209,200,249,152,155, +92,6,125,29,213,243,137,152,0,176,55,207,251,0,224,242,203,47,215,208,18,38,208,104,149,9,56,181,231,175,124,229,31,25,25,137,133,11,23,134,196,202,255,171,175,190,82,85,240,55,114,8,175,252,3,133,78,159,8,115,228,85,228,186,36,62,87,146,226,101,1,89, +117,0,64,177,31,81,5,73,66,92,207,123,232,117,25,77,241,8,224,64,158,247,5,128,29,58,116,208,208,26,38,24,160,206,4,84,206,246,87,179,242,159,55,111,30,122,245,234,165,232,126,127,162,118,229,63,226,246,84,188,250,31,118,254,129,34,42,97,36,32,209,23, +180,155,9,14,222,243,64,196,201,16,136,85,43,100,212,89,84,27,83,29,145,151,244,133,169,145,178,151,6,19,24,142,22,217,80,225,244,254,101,213,174,93,59,13,173,97,130,5,181,45,130,57,121,118,12,29,189,17,219,119,150,226,254,199,54,99,217,138,218,191,231, +63,115,230,76,140,26,53,74,149,243,231,180,127,224,48,152,90,32,34,182,191,38,218,102,130,12,128,4,57,142,100,11,64,147,12,0,0,72,50,18,111,125,6,178,153,238,152,97,70,91,124,89,253,3,28,0,132,19,20,219,1,3,110,93,167,216,249,71,70,70,98,241,226,197, +33,177,231,255,197,23,95,168,114,254,163,134,53,192,235,47,242,144,159,64,33,201,102,196,167,60,13,73,210,107,162,79,81,3,32,32,104,2,0,173,50,0,0,160,143,175,143,164,225,47,67,210,25,52,123,6,67,199,241,98,155,215,215,70,70,70,162,113,227,198,26,90, +195,4,27,106,199,6,123,124,233,47,61,139,168,168,40,44,90,180,8,215,94,123,173,162,251,253,201,23,95,124,129,251,238,187,15,30,143,71,209,253,163,134,55,192,43,207,183,3,113,99,22,227,53,50,226,83,166,64,111,212,238,221,70,82,3,32,164,120,89,72,146,106, +37,147,94,187,0,0,56,213,18,152,124,199,171,144,77,156,9,8,118,142,21,121,127,0,80,179,102,205,32,203,170,103,80,49,33,134,218,154,0,95,169,220,243,15,5,231,63,125,250,116,85,206,127,228,144,84,252,247,223,109,217,249,7,8,73,50,33,161,254,115,48,71,106, +59,219,132,162,6,64,130,136,146,33,160,58,127,175,217,22,192,89,152,155,95,129,122,99,167,193,152,210,74,243,103,49,202,57,230,67,6,128,87,255,225,139,218,154,0,111,137,140,140,196,130,5,11,66,34,237,63,125,250,116,220,127,255,253,170,156,63,23,252,5, +14,189,169,9,146,26,189,11,115,212,213,154,63,203,160,35,25,151,111,145,1,168,94,190,251,35,0,0,0,67,98,35,164,140,157,134,132,65,227,161,139,34,153,135,204,16,115,188,216,251,12,0,7,0,225,141,218,154,128,139,17,21,21,21,50,123,254,159,127,254,185,42, +231,127,231,240,134,120,237,5,222,243,15,4,178,46,22,49,73,99,145,212,232,3,232,77,77,252,242,76,189,172,254,236,20,33,193,162,135,128,69,237,88,97,45,107,0,170,32,235,16,125,213,109,136,234,114,3,202,183,46,67,197,182,165,176,29,218,4,225,114,248,207, +6,166,70,178,75,189,255,61,112,0,192,84,214,4,244,238,221,27,219,183,111,39,211,141,142,142,198,162,69,139,208,189,123,119,50,77,173,248,236,179,207,48,118,236,88,197,206,127,244,136,134,120,153,211,254,126,69,146,12,48,90,58,192,18,221,19,150,152,222, +164,135,253,120,131,94,167,62,0,144,4,34,244,144,212,111,1,24,8,162,17,95,145,244,70,68,93,54,16,81,151,13,132,112,57,225,200,222,7,87,254,49,120,42,138,33,92,222,175,66,25,90,10,94,89,239,245,181,13,26,240,160,39,134,62,8,8,39,231,127,255,189,215,97, +234,107,247,146,143,98,103,170,34,201,70,200,114,12,116,198,20,24,76,205,33,73,129,59,193,84,79,211,93,96,209,75,64,132,242,211,183,79,33,203,218,180,58,120,139,164,55,192,148,218,22,166,212,182,1,181,35,220,41,46,46,134,205,225,244,250,250,228,100,186, +19,178,152,208,166,178,48,176,79,159,62,216,186,117,171,98,157,200,200,72,204,155,55,47,36,156,255,231,159,127,174,202,249,143,25,51,6,31,127,252,49,59,255,48,132,34,3,0,32,66,22,128,234,106,2,89,226,74,110,6,200,205,245,173,63,59,41,73,245,57,84,76, +45,66,109,77,64,116,116,52,126,254,249,231,144,152,240,247,233,167,159,98,204,152,49,138,157,255,35,143,60,194,206,63,140,161,168,1,192,233,34,64,213,203,119,157,70,195,14,152,208,194,215,0,128,51,0,204,249,40,157,19,16,29,29,141,197,139,23,163,91,55, +250,131,87,168,249,228,147,79,240,192,3,15,168,114,254,239,189,247,30,59,255,48,134,40,0,208,147,4,0,146,6,179,142,153,208,163,164,164,196,167,235,19,19,19,53,178,85,83,108,32,0,0,32,0,73,68,65,84,132,9,101,124,13,2,98,98,98,240,211,79,63,133,133,243, +127,244,209,71,217,249,51,208,201,36,131,241,116,50,0,213,249,123,153,3,0,6,64,121,121,245,199,182,86,135,197,98,129,94,207,153,35,166,122,188,29,22,20,25,25,137,249,243,231,227,154,107,174,241,147,101,202,249,236,179,207,240,224,131,15,66,8,101,85,87, +99,199,142,197,187,239,190,203,206,159,129,158,38,0,160,201,0,232,2,92,4,200,4,7,190,4,0,145,145,60,213,145,185,48,23,27,22,20,25,25,25,50,227,125,63,253,244,83,85,5,127,15,60,240,0,62,250,232,35,118,254,12,37,58,25,128,234,229,59,103,0,24,0,40,43,43, +243,250,90,14,0,24,111,168,41,8,136,137,137,193,210,165,75,67,198,249,171,73,251,63,240,192,3,248,240,195,15,217,249,51,212,232,57,0,96,200,176,217,124,59,8,136,97,188,225,252,238,128,152,152,24,252,252,243,207,232,218,85,219,121,235,20,124,252,241,199, +170,86,254,227,198,141,99,231,207,84,65,64,109,243,62,128,211,25,0,213,240,159,38,3,192,167,163,75,121,255,159,241,133,202,154,128,110,221,186,133,140,243,255,228,147,79,240,240,195,15,43,222,243,127,240,193,7,241,246,219,111,179,243,103,170,162,240, +111,234,124,244,0,220,80,89,7,224,129,178,232,150,97,24,198,91,146,146,146,240,251,239,191,7,218,12,175,248,240,195,15,241,200,35,143,40,118,254,143,63,254,56,222,122,235,45,118,254,76,181,208,184,127,184,101,156,10,0,84,33,4,7,0,12,124,122,217,241,139, +141,169,173,124,242,201,39,120,244,209,71,21,59,255,241,227,199,243,202,159,185,8,36,33,128,139,3,0,38,32,240,203,141,169,141,252,239,127,255,83,85,240,55,97,194,4,188,245,214,91,196,86,49,76,181,208,100,0,60,28,0,48,240,109,95,223,110,231,3,155,152, +218,197,255,254,247,63,85,43,255,9,19,38,96,234,212,169,196,86,49,181,17,162,34,64,151,12,192,165,86,197,35,84,199,16,76,45,192,98,241,254,88,232,138,138,10,13,45,97,24,255,50,109,218,52,118,254,140,223,32,90,116,187,73,2,0,55,7,0,12,124,107,237,243, +101,104,16,195,4,51,211,166,77,83,53,225,143,157,63,227,43,46,55,73,6,213,37,75,128,247,205,219,218,26,195,132,56,28,0,48,225,6,59,127,38,16,56,61,36,62,215,170,23,128,234,92,44,145,49,138,17,118,7,28,251,14,194,117,252,36,220,69,37,128,75,117,82,131, +81,128,180,101,179,215,215,90,173,86,216,237,118,152,76,38,13,45,98,24,237,120,239,189,247,240,248,227,143,43,118,254,163,239,127,24,119,61,54,5,155,15,250,118,138,38,19,24,116,178,4,179,65,143,152,8,35,18,162,205,208,211,140,209,81,132,147,102,209,93, +161,7,96,85,171,226,116,59,8,108,241,13,97,179,163,124,233,42,148,47,251,29,246,173,59,33,156,236,244,3,141,174,180,208,167,235,243,242,242,144,154,154,170,145,53,12,163,29,31,127,252,177,42,231,223,239,214,209,232,113,251,67,216,176,39,155,216,50,198, +31,200,178,132,122,241,145,104,94,47,22,205,83,98,253,30,12,16,5,0,86,61,8,50,0,46,63,102,0,132,211,133,210,217,11,81,60,227,123,120,74,74,253,246,92,230,226,212,49,248,182,154,207,205,205,229,0,128,9,57,62,254,248,99,60,244,208,67,170,156,255,208,177, +19,137,173,98,252,137,199,35,144,149,95,134,172,252,50,108,216,123,18,151,54,77,66,251,70,117,32,203,254,105,111,118,121,212,47,186,133,68,150,1,240,79,0,224,216,127,24,121,47,188,5,231,193,163,126,121,30,227,27,117,140,190,7,0,12,19,74,124,244,209,71, +170,198,251,94,119,219,93,24,50,230,41,98,171,152,64,98,115,184,177,126,247,73,236,57,94,132,180,75,26,32,33,218,172,249,51,41,124,174,36,96,149,33,17,212,0,248,33,0,168,88,245,7,78,62,52,153,157,127,16,99,145,117,176,200,222,31,12,149,149,149,165,161, +53,12,67,203,59,239,188,163,202,249,15,24,114,47,59,255,90,76,97,153,13,243,214,31,192,225,156,18,205,159,69,85,4,40,75,66,120,127,134,107,13,216,93,218,86,116,91,87,111,64,238,115,175,67,216,253,95,107,192,248,70,146,209,251,232,247,208,161,67,218,25, +194,48,132,188,253,246,219,152,48,97,130,42,231,127,219,125,19,136,173,98,130,13,151,219,131,165,155,142,226,72,174,182,219,211,46,130,186,59,1,169,76,246,64,246,173,114,171,26,108,26,6,0,206,131,71,144,251,159,183,0,133,163,53,25,255,210,192,28,225, +245,181,28,0,48,161,128,90,231,223,255,246,187,217,249,135,17,66,8,44,223,124,20,133,101,170,59,236,107,132,194,231,74,64,129,44,193,83,20,12,198,84,135,112,185,145,247,210,187,16,54,158,51,16,42,52,52,123,63,11,224,224,193,131,26,90,194,48,234,169,116, +254,74,233,127,251,221,184,253,254,39,9,45,98,66,1,151,219,131,21,91,143,193,67,116,108,239,249,88,157,234,51,12,2,158,34,25,64,177,90,33,155,83,155,0,160,108,225,82,56,246,178,147,8,37,26,250,144,1,216,187,119,175,134,150,48,140,58,222,122,235,45,85, +206,127,224,176,251,216,249,135,49,249,37,54,236,62,166,58,193,94,45,20,1,128,4,169,72,22,144,84,103,0,52,169,1,240,120,80,252,245,28,122,93,70,83,124,201,0,100,101,101,33,63,63,95,67,107,24,70,25,83,167,78,197,19,79,60,161,248,254,65,195,238,199,173, +247,140,39,180,136,9,69,254,222,159,163,73,22,128,36,0,16,162,80,134,16,170,67,20,171,75,117,29,97,85,205,245,127,195,157,203,206,33,212,104,30,17,237,211,245,91,183,110,213,200,18,134,81,198,212,169,83,241,228,147,202,87,238,131,134,143,193,45,247,60, +78,104,17,19,170,84,216,93,56,170,65,65,160,213,73,224,115,37,20,203,178,80,159,1,168,112,208,183,61,84,172,90,79,174,201,104,79,203,136,104,232,36,239,135,97,108,219,182,77,67,107,24,198,55,212,58,255,254,183,223,131,91,238,30,71,104,17,19,234,28,202, +166,247,143,20,25,0,120,228,66,89,200,114,142,90,157,114,71,17,64,115,62,241,25,108,127,179,99,8,69,76,178,14,141,205,81,94,95,255,247,223,127,107,104,13,195,120,207,27,111,188,161,202,249,15,30,49,22,183,223,175,124,219,128,169,157,100,21,208,111,145, +91,157,234,131,10,33,187,115,100,89,242,168,30,70,237,17,110,210,66,64,97,119,192,117,82,117,92,194,4,136,214,145,49,94,95,187,118,237,90,13,45,97,24,239,152,58,117,42,38,78,84,62,158,119,192,144,123,113,243,93,143,17,90,196,212,22,202,109,78,56,92,110, +50,61,183,199,9,135,91,125,139,161,94,50,102,203,21,200,205,3,160,186,201,190,220,169,186,153,224,12,174,220,124,192,163,77,251,4,163,61,109,163,98,189,190,118,247,238,221,40,44,212,166,82,150,97,188,193,106,181,226,243,207,63,87,124,191,217,18,137,30, +3,111,35,180,136,169,109,148,89,157,100,90,36,251,255,128,171,236,183,214,5,114,122,218,10,23,0,213,213,118,21,14,186,0,0,14,158,248,23,202,92,22,157,224,245,181,30,143,7,235,215,115,189,7,19,56,44,22,11,126,253,245,87,116,236,216,81,209,253,54,107,57, +94,123,242,46,156,56,114,128,216,50,166,182,224,114,211,13,178,43,181,147,20,199,231,166,167,167,123,100,0,144,0,213,219,0,101,14,194,85,156,209,72,167,197,248,157,203,98,226,33,195,251,66,192,149,43,87,106,104,13,195,92,156,164,164,36,44,93,186,20,237, +219,183,87,116,127,113,97,30,166,78,25,131,156,172,35,196,150,49,181,1,202,83,2,137,2,128,28,0,144,1,64,16,4,0,37,54,186,150,61,93,66,28,153,22,227,127,162,116,6,180,140,244,190,29,112,217,178,101,26,90,195,48,222,145,156,156,172,42,19,80,148,159,195, +153,0,166,90,76,6,239,15,73,187,24,197,182,60,10,153,108,224,116,0,0,33,78,168,85,35,138,74,0,0,114,132,5,114,180,247,149,228,76,240,209,57,198,251,109,128,63,255,252,19,5,5,5,26,90,195,48,222,193,153,0,134,26,73,146,16,105,50,144,233,149,217,213,191, +43,5,78,249,252,83,25,0,73,86,125,198,110,9,77,84,114,6,125,253,186,164,122,140,127,185,58,54,201,235,107,221,110,55,150,47,95,174,161,53,12,227,61,201,201,201,88,190,124,185,226,32,160,40,63,7,175,79,188,135,131,0,6,0,16,101,54,144,110,1,20,219,114, +41,100,142,0,167,3,0,73,8,213,1,0,101,6,0,0,244,41,28,0,132,50,221,227,235,250,84,7,176,112,225,66,13,173,97,24,223,224,237,0,134,138,152,8,218,154,54,10,95,43,137,83,139,126,25,0,100,89,125,0,64,157,1,48,164,114,0,16,202,36,24,140,62,205,3,152,63,127, +62,92,46,151,134,22,49,140,111,36,37,37,97,217,178,101,138,131,128,226,194,60,188,57,233,62,14,2,194,156,104,11,109,0,80,98,39,240,181,210,89,25,0,143,208,169,14,0,42,156,165,112,186,233,142,237,229,12,64,232,211,35,62,217,235,107,243,243,243,177,106, +213,42,13,173,97,24,223,225,32,128,81,11,101,6,192,35,220,40,39,105,185,119,31,3,78,7,0,70,135,71,117,0,0,8,20,217,232,166,247,113,13,64,232,147,150,80,207,167,235,231,206,157,171,145,37,12,163,28,46,12,100,212,16,77,24,0,148,218,243,33,132,250,153,2, +54,155,249,159,45,128,39,6,100,22,0,80,61,94,168,200,122,82,173,196,25,56,3,16,250,92,25,155,136,4,131,247,127,252,25,25,25,112,58,233,38,102,49,12,21,92,19,192,40,37,134,112,11,160,160,66,117,195,30,0,20,165,15,250,182,4,168,108,3,60,197,126,181,170, +133,21,132,1,64,221,68,72,6,186,214,9,198,255,232,36,9,189,19,82,188,190,62,39,39,7,75,150,44,209,208,34,134,81,14,111,7,48,74,160,220,2,40,168,200,162,144,217,87,249,127,228,234,190,168,148,34,27,93,0,0,157,14,250,134,245,233,244,152,128,208,63,209, +183,223,225,87,95,125,165,145,37,12,163,30,14,2,24,95,136,50,27,96,208,203,23,191,208,75,72,2,0,33,85,13,0,36,33,84,7,0,148,25,0,0,48,54,109,72,170,199,248,159,30,241,201,136,210,233,189,190,126,222,188,121,60,20,136,9,106,184,38,128,241,150,248,40,51, +169,30,73,0,32,87,147,1,240,200,234,51,0,5,86,146,253,137,51,24,154,54,34,213,99,252,143,89,214,97,80,82,3,175,175,183,217,108,152,62,125,186,134,22,49,140,122,184,38,128,241,134,248,104,19,169,30,133,143,149,60,158,51,127,116,103,2,0,217,45,171,174, +1,40,177,229,195,225,182,170,149,57,131,161,9,103,0,106,3,183,213,245,45,144,251,240,195,15,225,241,208,157,158,197,48,90,192,219,1,204,197,160,204,0,56,221,118,162,33,64,213,213,0,232,92,123,85,43,67,32,175,252,152,122,153,211,24,155,113,6,160,54,112, +101,108,34,26,153,35,189,190,126,255,254,253,248,233,167,159,52,180,136,97,104,224,32,128,185,16,241,81,116,25,128,66,235,73,8,33,84,235,56,141,158,170,1,192,211,189,230,30,7,80,170,86,60,159,48,0,208,167,212,133,100,226,163,129,67,29,9,192,45,62,102, +1,222,121,231,29,109,140,97,24,98,184,38,128,169,14,73,2,226,34,233,2,0,162,14,128,226,127,245,152,123,166,88,239,159,34,64,9,2,18,118,169,85,167,204,0,64,150,120,27,160,150,48,50,165,41,244,146,247,213,176,75,150,44,193,159,127,254,169,161,69,12,67, +7,215,4,48,231,19,109,49,66,175,163,235,0,160,240,173,146,132,29,146,132,51,105,132,115,172,19,66,236,80,251,128,188,10,194,0,0,128,177,101,83,82,61,38,48,212,53,154,209,175,142,247,51,1,0,224,181,215,94,211,200,26,134,161,135,183,3,152,179,169,19,99, +33,213,203,46,35,248,187,240,72,219,207,254,207,243,194,147,115,191,169,132,220,50,218,52,150,177,117,115,82,61,38,112,220,89,191,153,79,215,207,153,51,7,123,246,236,209,200,26,134,161,135,183,3,152,74,146,136,3,128,156,178,195,170,53,60,18,206,89,228, +159,19,0,232,36,177,83,237,3,74,237,249,68,135,21,156,194,212,166,5,153,22,19,88,174,142,75,66,203,8,239,79,8,116,187,221,120,225,133,23,52,180,136,97,232,73,78,78,198,242,229,203,21,7,1,69,249,57,120,125,226,61,28,4,132,56,73,177,116,1,128,213,89,74, +115,226,174,240,212,156,1,144,100,245,25,0,0,200,41,59,68,33,3,0,48,52,107,12,201,200,35,129,107,3,18,128,251,27,248,22,208,205,152,49,3,155,55,111,214,198,32,134,209,8,174,9,96,234,196,208,181,0,102,19,249,84,55,46,176,5,80,254,107,251,195,32,232,4, +160,50,22,0,36,189,14,198,230,77,200,244,152,192,114,91,221,70,168,111,138,240,250,122,143,199,131,231,158,123,78,67,139,24,70,27,184,38,32,124,137,139,52,193,168,215,145,233,17,45,170,11,159,233,147,121,252,236,47,156,19,0,164,167,167,123,0,168,94,110, +229,148,30,84,43,113,14,92,7,80,123,208,75,50,238,243,49,11,48,111,222,60,172,94,189,90,35,139,24,70,59,146,146,146,240,198,27,111,40,190,191,184,48,15,63,124,249,30,161,69,140,63,72,36,76,255,3,64,118,233,33,10,153,191,207,255,66,149,30,5,1,241,151, +218,167,156,164,14,0,218,112,0,80,155,24,81,175,137,79,199,4,3,192,184,113,227,120,58,32,19,114,108,222,188,25,119,220,113,135,226,251,27,183,108,135,187,38,60,79,104,17,227,15,40,247,255,1,32,167,76,189,79,149,132,116,241,0,0,82,213,139,124,165,200, +118,18,54,87,185,90,153,51,152,218,181,34,211,98,2,79,132,78,143,49,13,90,250,116,207,95,127,253,133,47,190,248,66,27,131,24,70,3,54,111,222,140,190,125,251,34,47,79,89,241,86,227,150,237,240,196,127,63,65,68,148,247,133,179,76,112,144,28,235,253,54, +231,197,112,121,28,40,168,80,127,6,128,144,177,233,252,175,85,9,0,36,33,171,14,0,132,16,56,94,76,215,190,101,104,148,10,93,124,44,153,30,19,120,238,73,109,129,20,147,111,81,242,148,41,83,80,92,76,215,97,194,48,90,193,206,63,124,209,235,100,210,2,192, +19,37,251,225,17,110,213,58,30,119,213,236,126,149,0,192,38,101,111,7,96,83,251,176,227,197,170,135,10,254,131,36,193,212,177,45,157,30,19,112,204,178,14,15,55,108,237,211,61,57,57,57,120,246,217,103,53,178,136,97,104,216,180,105,19,250,244,233,163,216, +249,55,107,115,9,158,124,229,51,118,254,33,74,221,184,8,200,146,68,166,119,188,120,55,133,140,213,161,203,173,178,42,175,18,0,164,167,173,112,1,216,166,246,105,199,104,140,62,131,233,18,14,0,106,27,35,82,154,160,177,197,251,67,130,0,224,131,15,62,192, +202,149,43,53,178,136,97,212,177,121,243,102,244,235,215,15,249,249,202,78,109,107,220,178,29,30,127,241,67,88,34,163,136,45,99,252,69,189,120,186,244,63,0,28,47,33,201,166,111,57,237,219,207,161,134,65,197,98,189,218,167,157,40,217,7,183,167,202,243, +20,99,190,180,29,153,22,19,28,232,37,25,79,55,233,224,211,61,30,143,7,99,198,140,129,213,74,119,236,52,195,80,192,43,127,6,0,234,197,251,182,168,185,48,2,89,20,219,233,2,235,170,251,114,181,1,128,36,36,213,1,128,203,227,64,54,65,229,98,37,198,22,77,32, +71,81,254,96,153,96,96,112,82,42,174,142,75,242,233,158,61,123,246,240,108,0,38,168,224,149,63,3,0,58,89,34,237,0,40,168,56,129,10,103,137,106,29,129,234,125,122,245,1,128,222,83,109,180,224,43,68,123,23,167,144,101,152,58,248,182,103,204,132,6,207,183, +184,20,122,31,247,204,166,78,157,202,179,1,152,160,128,11,254,152,74,146,98,35,72,79,0,36,243,161,178,188,182,218,47,87,247,197,137,215,206,217,7,64,245,224,97,234,58,0,115,39,101,179,181,153,224,166,85,68,12,70,164,248,118,234,163,199,227,193,253,247, +223,15,155,77,117,189,42,195,40,102,211,166,77,236,252,153,51,144,239,255,211,116,211,229,76,73,251,238,80,117,223,168,62,3,32,65,72,192,31,106,159,74,218,9,0,192,124,249,165,164,122,76,112,224,129,64,185,219,247,122,145,93,187,118,225,197,23,95,212, +192,34,134,185,56,106,157,63,239,249,215,62,26,36,210,110,225,28,47,33,88,68,11,172,169,233,91,53,230,42,4,160,186,14,160,220,81,140,66,235,73,181,50,103,48,182,104,2,93,157,120,50,61,38,240,120,32,48,113,247,95,152,155,173,236,228,179,169,83,167,162, +176,176,144,216,42,134,185,48,149,206,95,233,158,127,179,54,151,96,252,75,31,243,158,127,45,194,160,151,145,28,71,151,1,176,58,75,145,95,113,252,226,23,94,156,26,125,121,141,1,128,228,145,86,81,60,153,180,14,64,146,96,238,114,9,157,30,19,80,42,157,255, +156,108,101,231,92,235,116,58,124,250,233,167,136,143,231,160,144,241,31,106,157,63,23,252,213,78,82,235,68,145,246,255,31,46,220,6,33,132,106,29,143,84,179,47,175,49,0,48,68,136,117,0,236,106,31,126,172,136,118,27,192,114,101,39,82,61,38,48,168,117, +254,122,189,30,51,103,206,196,200,145,35,137,45,99,152,154,161,88,249,115,218,191,118,210,160,14,109,64,119,184,112,43,133,140,53,202,86,186,177,166,111,214,24,0,60,113,77,166,85,2,106,188,209,91,14,22,84,25,63,172,10,203,149,157,0,153,46,202,98,252, +15,197,202,255,203,47,191,196,144,33,67,136,45,99,152,154,225,149,63,115,33,82,137,247,255,15,81,4,0,18,214,141,27,180,184,198,133,252,5,251,21,4,196,111,106,159,95,98,207,167,218,199,0,0,200,177,49,48,182,108,70,166,199,248,23,10,231,255,213,87,95,241, +202,159,241,43,20,206,159,171,253,107,47,113,145,38,68,91,124,59,225,244,66,20,89,179,81,100,205,86,173,35,60,210,5,199,166,94,164,97,81,38,153,185,122,32,95,245,249,66,231,192,219,0,161,9,59,127,38,20,97,231,207,92,12,234,234,255,131,5,91,72,116,100, +129,11,46,226,47,24,0,216,36,177,26,128,234,121,190,228,1,64,183,43,72,245,24,237,97,231,207,132,34,236,252,25,111,104,156,76,251,251,61,92,72,18,0,56,172,86,235,5,187,249,46,24,0,164,167,101,150,129,96,30,192,209,226,157,112,184,233,6,182,152,218,180, +128,62,57,145,76,143,209,22,118,254,76,40,194,206,159,241,6,147,65,135,186,132,3,128,132,240,224,112,209,118,10,169,53,233,55,204,175,184,208,5,23,157,89,40,132,244,139,90,43,220,30,23,142,20,146,252,131,78,33,73,156,5,8,17,216,249,51,161,8,59,127,198, +91,26,39,199,144,182,255,157,44,61,0,155,179,140,64,233,226,190,251,226,1,128,4,213,1,0,0,28,40,160,221,6,136,232,113,37,169,30,67,15,59,127,38,20,97,231,207,248,2,117,250,127,63,209,150,185,240,16,4,0,14,41,103,61,128,98,181,198,80,215,1,152,46,109, +15,57,134,219,105,130,21,118,254,76,40,194,206,159,241,5,189,78,70,106,29,218,83,106,247,229,169,238,190,7,128,194,230,5,158,191,46,118,209,69,3,128,244,180,21,46,0,43,212,90,83,108,203,37,109,7,148,244,58,88,186,118,33,211,99,232,224,33,63,76,40,178, +113,227,70,244,233,211,135,135,252,48,94,211,48,49,138,244,244,191,18,91,30,178,203,14,17,40,137,95,134,14,205,116,95,236,42,239,44,151,212,215,1,0,192,129,124,218,161,64,17,215,94,69,170,199,168,135,135,252,48,161,200,234,213,171,209,183,111,95,20,20, +20,40,186,159,135,252,132,39,212,233,255,83,171,127,245,227,127,189,221,186,247,42,0,208,201,98,145,58,115,78,65,93,7,96,185,170,51,228,72,218,227,23,25,229,112,218,159,9,69,126,251,237,55,12,28,56,16,197,197,202,118,58,187,116,233,130,140,239,231,243, +202,63,204,208,201,18,26,37,71,147,106,238,205,219,64,33,35,100,120,126,242,230,66,175,2,128,137,61,51,15,2,216,161,202,36,0,71,10,183,19,85,55,158,66,50,26,184,24,48,72,224,180,63,19,138,124,255,253,247,24,48,96,0,74,75,75,21,221,223,181,107,87,44,95, +190,28,87,182,111,134,238,237,235,19,91,199,4,51,141,146,99,96,212,235,200,244,236,174,10,28,45,222,169,94,72,96,211,164,180,185,199,188,185,212,235,205,11,73,136,249,202,45,58,133,71,184,169,34,156,51,68,246,187,150,84,143,241,29,10,231,63,99,198,12, +78,251,51,126,229,131,15,62,192,144,33,67,96,179,41,155,81,210,181,107,87,252,252,243,207,136,137,57,181,242,111,211,32,129,131,128,48,162,69,74,44,169,222,129,130,191,225,246,168,158,187,7,33,137,5,222,94,235,117,0,32,100,201,107,209,11,177,43,103,45, +133,204,25,204,157,47,129,46,49,129,84,147,241,30,222,243,103,66,13,33,4,210,211,211,241,232,163,143,194,237,190,104,157,84,181,116,233,210,5,139,22,45,58,227,252,43,225,32,32,60,48,25,116,104,144,72,156,254,207,37,169,254,135,128,88,232,237,181,94,7, +0,205,114,177,22,128,178,242,216,179,56,84,184,21,86,167,178,116,91,181,200,18,34,122,93,77,167,199,120,13,167,253,153,80,163,162,162,2,195,135,15,199,243,207,63,175,88,163,50,237,31,31,31,95,237,247,57,8,168,253,52,173,27,11,29,225,169,180,110,143,11, +7,104,78,206,205,113,172,236,232,117,154,221,235,0,96,232,208,76,55,132,88,172,204,166,127,240,8,55,246,228,170,158,46,124,14,81,188,13,224,119,120,229,207,132,26,199,142,29,67,207,158,61,145,145,145,161,88,163,166,149,255,249,112,16,80,187,105,174,65, +250,223,238,42,39,80,146,22,166,167,167,123,188,189,218,167,6,70,73,150,126,244,221,160,170,236,204,89,67,33,115,6,99,155,22,48,52,226,15,155,191,224,149,63,19,106,172,90,181,10,93,186,116,193,198,141,202,211,172,221,187,119,191,224,202,255,124,56,8, +168,157,68,154,13,168,23,79,59,252,103,103,54,141,79,148,36,204,243,229,122,159,2,0,107,153,109,17,0,213,97,202,145,162,237,40,119,168,30,46,120,14,145,215,245,34,213,99,170,135,87,254,76,40,33,132,192,59,239,188,131,62,125,250,32,39,39,71,177,78,207, +158,61,189,90,249,159,15,7,1,181,143,150,245,227,64,56,250,31,78,183,29,251,242,73,246,255,203,12,38,241,179,47,55,248,20,0,156,62,89,200,167,7,84,135,16,30,236,201,189,224,41,133,62,19,53,184,15,36,194,150,12,166,42,225,180,242,47,44,44,12,180,9,140, +74,242,242,242,112,253,245,215,99,252,248,241,112,58,157,138,117,174,191,254,122,252,244,211,79,136,142,86,86,244,197,65,64,237,162,85,170,119,25,32,111,217,147,247,7,156,110,187,122,33,33,45,120,226,154,76,171,47,183,40,153,97,56,71,193,61,85,160,222, +6,208,37,196,193,124,85,103,82,77,230,31,194,169,213,47,51,51,19,169,169,169,120,230,153,103,96,183,19,124,48,25,191,179,108,217,50,92,118,217,101,88,180,72,221,12,179,97,195,134,97,206,156,57,48,155,205,170,116,56,8,168,29,164,214,137,66,76,132,145, +84,115,103,246,239,36,58,146,44,124,246,205,62,7,0,146,209,62,31,128,178,198,217,179,56,86,188,19,101,118,218,85,86,244,245,125,73,245,152,83,132,83,218,127,246,236,217,184,227,142,59,96,181,90,241,210,75,47,161,115,231,206,88,191,158,54,91,197,104,135, +213,106,197,228,201,147,113,221,117,215,225,216,49,175,102,161,212,200,184,113,227,48,99,198,12,24,141,52,47,124,14,2,66,159,214,13,104,87,255,54,103,25,14,21,110,165,144,178,202,14,179,207,69,250,62,7,0,147,186,207,43,21,2,75,125,189,239,124,132,16, +216,157,187,78,173,204,57,88,186,118,134,190,110,34,169,102,184,19,78,105,255,204,204,76,140,24,49,226,156,116,241,142,29,59,208,173,91,55,76,156,56,17,86,171,79,217,53,198,207,172,94,189,26,151,94,122,41,94,125,245,85,120,60,94,23,66,87,65,146,101,188, +249,230,155,120,231,157,119,32,203,116,7,189,0,28,4,132,50,38,131,142,124,246,255,206,156,181,36,195,127,0,44,158,216,255,107,159,235,243,20,253,117,203,128,242,62,154,179,216,158,189,146,66,230,31,100,25,145,3,210,104,53,195,152,112,75,251,143,28,57, +18,46,87,213,15,163,219,237,198,27,111,188,129,75,47,189,20,171,86,173,10,128,117,204,133,40,44,44,196,3,15,60,128,107,175,189,22,123,247,238,85,165,37,233,141,168,63,234,57,196,92,59,148,200,186,170,112,16,16,154,180,74,141,39,237,253,7,128,157,57,171, +105,132,36,145,169,228,54,101,225,173,201,254,3,128,10,69,247,158,197,137,146,253,200,41,83,230,92,106,34,106,112,95,128,56,106,15,71,216,249,87,101,239,222,189,232,213,171,23,30,123,236,49,197,7,199,48,116,8,33,48,99,198,12,180,109,219,22,211,166,77, +83,181,234,7,0,125,108,18,26,63,246,62,98,46,235,141,169,191,31,196,167,27,213,109,33,92,8,14,2,66,143,214,196,197,127,197,182,28,28,163,152,253,15,148,217,202,236,62,181,255,85,162,200,83,78,234,62,175,84,2,84,159,13,0,0,155,179,84,239,38,156,131,190, +110,34,44,93,185,24,80,13,225,184,231,127,49,231,95,137,199,227,193,251,239,191,143,230,205,155,227,157,119,222,81,60,74,150,81,199,198,141,27,209,171,87,47,220,113,199,29,200,206,206,86,173,103,105,210,30,77,159,152,6,75,163,54,103,190,198,65,0,83,73, +253,132,72,196,69,153,72,53,183,156,248,21,66,16,28,253,11,124,127,186,67,207,103,20,47,149,5,196,76,165,247,158,205,246,236,85,52,45,16,103,17,115,219,32,82,189,112,34,220,247,252,189,37,63,63,31,227,199,143,71,215,174,93,177,122,53,81,26,143,185,40, +71,142,28,193,29,119,220,129,43,175,188,18,43,87,210,108,33,198,93,53,24,141,31,121,23,250,152,58,85,190,199,65,0,3,0,237,27,211,214,150,9,225,193,182,19,43,72,180,36,161,220,23,43,14,0,108,121,210,98,16,156,13,96,119,85,144,23,3,154,47,191,20,134,102, +141,73,53,195,1,78,251,251,206,198,141,27,209,189,123,119,220,120,227,141,216,186,149,164,154,151,169,134,172,172,44,60,246,216,99,104,213,170,21,102,204,152,65,178,114,146,141,102,212,31,49,5,41,195,39,65,210,27,106,188,142,131,128,240,38,218,98,68, +163,164,40,82,205,253,249,127,163,196,174,218,125,2,64,110,124,108,130,226,52,186,226,0,32,125,104,166,67,34,154,9,176,57,107,25,133,204,57,68,223,50,128,92,179,54,195,206,95,29,243,231,207,71,167,78,157,48,106,212,40,236,217,179,135,76,55,220,201,202, +202,194,132,9,19,208,188,121,115,188,255,254,251,100,115,25,76,245,154,160,201,132,143,17,123,229,64,175,174,231,32,32,124,105,223,184,14,36,202,209,127,0,182,156,88,78,164,36,50,30,184,124,154,226,41,87,170,170,229,132,132,175,213,220,95,201,177,226, +93,200,43,63,74,33,117,134,168,235,122,66,142,161,61,174,177,182,194,206,159,6,143,199,131,111,191,253,22,109,219,182,197,208,161,67,241,215,95,127,145,63,35,92,216,178,101,11,238,190,251,110,52,109,218,20,111,191,253,54,108,54,213,163,71,206,16,215, +117,48,154,76,152,6,83,189,166,62,221,199,65,64,248,97,208,203,104,149,26,71,170,89,238,40,194,254,124,154,119,131,36,164,175,212,220,175,42,0,152,156,150,249,59,128,93,106,52,42,161,139,136,78,33,153,77,136,26,220,135,84,179,54,194,206,159,30,143,199, +131,204,204,76,116,233,210,5,253,251,247,199,162,69,139,84,87,168,135,3,46,151,11,63,254,248,35,250,247,239,143,78,157,58,225,203,47,191,132,195,225,32,211,215,71,39,160,225,253,255,69,202,176,73,144,141,202,38,251,113,16,16,94,180,78,141,135,145,120, +196,252,214,19,191,194,35,72,138,135,183,79,234,147,169,234,104,93,213,253,114,18,132,170,8,164,146,109,39,87,194,229,81,62,175,187,58,162,111,25,8,232,248,124,128,154,96,231,175,61,75,150,44,193,224,193,131,209,170,85,43,188,249,230,155,40,40,40,240, +235,243,67,129,195,135,15,227,185,231,158,67,227,198,141,113,243,205,55,99,201,146,37,36,123,252,103,19,211,41,13,205,38,125,133,168,246,221,84,107,249,35,8,184,186,109,138,102,250,140,119,72,18,208,174,81,213,194,80,117,8,108,33,42,254,19,146,152,174, +86,67,125,195,188,75,255,37,0,213,225,140,213,89,138,61,185,170,130,153,42,232,235,38,34,50,237,26,82,205,218,2,59,127,255,178,127,255,126,60,245,212,83,72,77,77,197,208,161,67,177,96,193,130,128,218,19,104,242,242,242,240,225,135,31,162,103,207,158, +104,214,172,25,94,120,225,5,100,101,101,145,63,71,31,155,132,6,247,188,136,212,187,158,135,46,146,110,138,155,214,65,64,251,70,117,56,19,16,96,154,36,199,144,207,253,63,92,184,13,133,214,19,20,82,78,143,219,240,141,90,17,146,202,134,87,151,15,89,40,0, +213,189,119,141,227,59,96,120,167,231,40,76,58,131,243,208,49,100,221,51,30,240,208,174,40,66,25,118,254,193,65,114,114,50,134,14,29,138,91,110,185,5,215,94,123,45,244,122,125,160,77,210,148,99,199,142,97,193,130,5,248,241,199,31,177,108,217,50,85,39, +244,93,20,89,70,66,247,91,145,52,240,62,200,102,218,179,219,207,230,137,238,77,113,255,229,13,52,211,223,117,172,0,191,111,167,15,140,152,139,115,243,213,205,145,24,99,33,213,156,179,245,53,236,203,35,57,250,247,199,201,189,51,111,86,43,66,243,198,145, +48,29,66,125,0,112,184,112,59,114,203,143,34,41,178,33,133,85,0,0,67,147,6,176,116,237,2,235,26,146,31,122,200,195,206,223,123,186,53,189,18,22,131,5,191,238,93,5,183,160,223,195,207,201,201,193,251,239,191,143,247,223,127,31,117,234,212,193,245,215, +95,143,235,175,191,30,189,123,247,70,66,66,2,249,243,252,141,205,102,195,250,245,235,177,124,249,114,44,92,184,16,127,253,245,23,121,106,191,58,44,141,219,161,222,109,227,97,110,216,230,226,23,171,100,234,239,7,1,64,179,32,160,77,131,83,127,7,28,4,248, +151,6,137,81,228,206,191,208,122,18,251,243,255,36,209,146,128,207,137,116,212,243,241,198,177,134,194,146,194,67,0,84,231,172,58,166,164,97,80,155,135,212,27,117,22,246,29,123,113,242,161,201,164,154,161,8,59,127,239,233,222,172,43,238,191,106,20,36, +73,194,177,162,44,124,243,103,38,118,102,251,167,189,79,167,211,161,115,231,206,232,215,175,31,122,244,232,129,171,174,186,10,241,241,180,99,72,181,160,176,176,16,127,252,241,7,214,175,95,143,21,43,86,96,221,186,117,126,61,64,201,16,95,23,201,215,63, +128,152,203,250,156,218,192,245,35,156,9,168,93,12,190,162,41,82,18,104,51,71,75,247,78,199,159,199,124,62,176,175,58,178,226,99,226,155,168,105,255,171,132,236,83,242,223,101,67,94,148,36,252,159,90,29,89,210,225,193,171,223,71,180,137,182,248,34,251, +241,231,96,219,180,157,84,51,148,96,231,239,61,103,59,255,179,217,112,228,111,100,108,250,1,57,101,121,20,102,122,141,36,73,104,221,186,53,186,118,237,138,78,157,58,161,67,135,14,184,228,146,75,144,148,148,228,87,59,42,113,187,221,56,120,240,32,118,236, +216,129,29,59,118,96,235,214,173,216,176,97,131,234,131,120,148,34,155,35,81,167,207,72,212,233,57,20,146,129,118,92,171,47,112,16,80,59,72,142,181,224,198,174,205,73,53,29,110,43,254,183,230,65,216,93,234,3,98,73,18,233,147,210,102,63,79,96,22,209,22, +0,0,183,94,247,177,222,237,158,12,64,85,217,189,71,184,241,215,241,37,232,217,108,4,145,101,167,136,25,117,91,216,6,0,236,252,189,167,38,231,15,0,87,52,186,12,157,27,92,130,223,246,175,193,143,219,22,163,200,234,159,3,129,132,16,216,181,107,23,118,237, +58,183,227,54,57,57,25,45,91,182,68,179,102,205,208,164,73,19,52,109,218,20,245,234,213,67,221,186,117,145,156,156,140,196,196,68,152,205,190,181,187,57,28,14,228,229,229,33,47,47,15,217,217,217,200,205,205,197,241,227,199,113,232,208,161,51,255,59,112, +224,0,105,95,190,82,100,147,5,241,221,111,69,157,180,17,164,5,126,74,225,237,128,218,65,167,230,201,228,154,155,179,150,145,56,127,0,46,167,71,250,148,66,8,32,204,0,0,192,43,191,14,153,7,129,27,212,234,152,245,145,120,232,154,15,97,212,41,235,213,173, +137,19,15,76,130,99,215,62,82,205,96,135,157,191,247,92,200,249,159,143,195,229,192,47,123,126,195,226,157,75,81,106,47,83,244,60,127,96,50,153,16,17,17,129,232,232,104,24,141,70,196,198,198,158,249,94,121,121,57,28,14,7,156,78,39,202,202,202,80,90,90, +26,148,197,146,231,35,27,205,136,187,230,38,36,246,185,3,186,40,218,33,45,20,76,232,214,4,99,174,160,171,99,58,159,237,71,242,177,118,39,73,37,57,115,30,9,209,102,220,122,77,11,82,77,33,60,152,182,254,113,20,89,213,31,90,5,96,238,228,222,153,183,81,8, +1,132,25,0,0,240,8,233,35,25,66,117,0,96,115,149,99,203,137,229,184,188,1,237,161,62,113,247,14,67,206,211,47,145,106,6,51,124,170,159,247,116,109,220,5,247,93,117,135,215,35,63,141,122,35,6,183,235,135,254,109,210,240,251,129,117,248,113,219,79,40,168, +40,84,244,108,45,177,219,237,176,219,237,40,44,12,62,219,124,69,31,21,143,184,110,55,35,161,199,173,208,69,198,94,252,134,0,241,214,234,67,0,160,89,16,208,190,81,29,232,100,137,51,1,26,208,165,5,253,234,127,111,222,6,42,231,15,201,131,143,72,132,78,67, +58,37,167,71,211,33,251,245,141,115,239,4,160,186,98,169,160,34,11,93,26,12,32,157,193,108,104,144,2,251,223,219,224,202,206,37,211,12,86,168,78,245,27,62,124,56,177,101,244,80,172,252,199,94,125,23,100,201,247,177,24,178,36,163,73,66,35,244,109,117, +45,146,34,19,145,83,150,27,212,25,129,80,196,148,210,12,201,131,199,162,254,200,41,136,108,213,69,241,20,63,127,178,238,104,17,140,58,25,93,82,181,9,84,18,99,44,136,48,235,113,36,183,84,19,253,112,36,49,198,130,174,109,232,7,48,253,188,231,19,148,216, +8,234,134,4,246,78,234,147,249,196,243,36,191,106,233,49,0,0,32,0,73,68,65,84,187,255,167,32,13,0,86,172,88,33,250,142,110,39,32,73,222,157,176,113,1,236,174,114,36,70,54,68,34,97,75,32,0,24,82,83,80,182,152,118,236,112,176,65,177,242,255,234,171,175, +66,194,249,83,172,252,199,92,61,90,145,243,63,27,89,146,209,56,161,33,250,180,186,22,151,165,118,132,211,237,68,86,201,73,191,180,189,213,70,36,189,1,49,151,244,68,221,91,198,161,238,13,15,193,220,176,21,36,57,180,166,122,114,16,16,90,244,236,216,128, +124,240,79,86,201,94,172,58,56,139,68,75,2,210,187,55,219,65,58,45,143,252,19,213,125,72,243,109,122,163,254,65,0,17,106,181,138,109,185,232,84,191,47,129,85,255,160,175,155,4,251,214,93,112,157,160,73,201,4,27,188,242,247,30,53,43,255,11,17,103,137, +69,151,134,157,208,163,217,213,176,232,205,200,175,40,64,133,195,127,237,112,161,140,165,113,59,212,233,51,18,245,239,120,6,177,151,247,135,177,78,125,191,183,244,81,194,65,64,104,80,47,62,2,151,183,172,75,174,251,243,238,105,40,180,158,164,144,42,178, +201,184,107,197,151,59,232,14,199,128,6,1,192,138,153,123,156,125,239,106,23,11,72,61,212,106,149,57,10,209,56,190,3,98,205,180,237,78,198,198,13,80,182,144,254,8,226,64,195,5,127,222,227,75,193,159,82,44,6,51,218,214,109,133,126,173,123,161,93,221,214, +144,37,25,57,101,185,112,121,130,191,208,206,159,152,234,53,65,66,143,219,145,50,108,34,234,244,30,9,75,227,118,144,13,180,43,177,64,194,65,64,240,211,179,99,3,68,91,104,255,230,114,202,14,97,249,62,213,211,122,1,0,18,240,222,51,189,51,23,146,136,157, +133,38,179,71,221,122,207,251,58,151,238,73,0,170,155,114,215,31,153,135,134,113,109,9,172,250,7,99,155,22,176,92,93,187,166,3,114,193,159,247,248,90,240,167,22,9,18,90,39,183,64,235,228,22,184,243,242,161,216,147,187,31,127,31,223,138,63,14,255,133, +98,91,137,95,108,8,42,36,25,230,6,45,17,213,238,26,68,183,191,6,230,134,173,3,109,145,230,104,93,24,200,45,130,202,105,144,24,69,62,244,7,0,214,28,154,3,128,100,11,208,165,19,238,15,40,132,206,71,179,55,224,43,203,111,255,12,144,238,165,208,186,179,203, +75,168,31,211,146,66,234,12,142,253,135,113,226,254,167,128,90,112,76,43,175,252,189,199,31,43,127,111,241,8,15,118,231,236,195,150,172,237,216,118,114,23,142,22,30,135,160,121,97,4,29,134,132,122,136,108,209,25,17,45,59,35,170,237,85,65,93,197,175,37, +220,34,24,92,72,18,112,83,87,250,153,255,249,21,199,241,217,31,79,16,213,0,137,140,201,189,103,15,35,16,170,130,134,167,143,136,169,128,116,15,8,130,140,213,7,51,49,228,210,127,17,216,244,15,198,230,141,17,53,168,55,202,22,44,37,213,245,55,236,252,189, +39,152,156,63,112,170,112,176,109,221,86,104,91,183,21,134,1,40,177,149,98,71,246,110,236,204,222,131,125,121,7,145,85,124,18,30,13,206,32,208,28,89,134,169,110,99,88,26,181,131,165,105,7,68,182,232,12,67,29,62,222,22,224,22,193,96,163,69,74,28,185,243, +7,128,181,135,230,146,21,0,123,60,210,219,36,66,213,160,233,155,144,234,148,64,0,24,121,217,243,228,91,1,238,194,98,100,221,241,8,60,229,161,89,160,197,206,223,123,130,205,249,123,131,205,105,195,129,252,195,216,159,127,8,71,10,143,225,88,81,22,178,75, +115,52,57,152,72,41,178,41,2,166,186,141,96,172,215,20,230,148,102,48,55,108,3,115,131,86,144,77,244,47,213,218,132,214,153,0,30,27,124,113,244,58,25,183,119,111,137,40,179,129,84,183,200,154,141,79,214,143,135,71,184,41,228,86,76,238,157,153,70,33,84, +29,154,158,63,234,17,120,83,146,104,2,128,223,15,101,96,68,167,127,83,72,157,65,23,31,139,152,225,55,163,232,179,153,164,186,254,128,157,191,247,132,162,243,7,0,179,193,140,118,245,90,163,93,189,127,246,200,93,30,23,178,138,79,226,68,73,54,114,203,243, +145,91,150,143,188,178,60,228,150,23,160,200,90,4,187,139,180,72,24,70,147,25,194,18,3,125,92,18,12,9,41,48,36,212,131,49,161,30,12,9,41,48,38,55,132,33,190,30,233,243,194,5,174,9,8,60,151,52,73,36,119,254,0,176,238,200,15,84,206,31,16,226,53,26,161, +234,209,252,141,248,202,242,33,127,2,232,76,161,53,162,211,191,209,40,190,61,133,212,25,132,221,129,172,59,199,133,212,112,32,118,254,222,19,170,206,95,41,14,183,19,101,246,50,20,219,74,145,122,77,99,196,183,75,134,195,225,64,105,105,41,172,86,107,149, +25,254,70,163,17,145,145,145,136,137,137,129,217,108,70,84,84,20,162,163,163,145,156,156,140,228,228,100,100,236,42,196,235,171,14,6,232,95,83,251,225,76,64,96,176,24,245,24,218,163,21,12,122,218,22,224,98,91,14,62,89,63,30,110,130,78,31,1,108,153,156, +150,217,73,146,180,43,12,210,52,3,0,0,146,36,166,10,33,145,244,66,172,60,248,29,70,197,191,64,33,117,6,201,100,68,220,253,35,145,247,210,59,164,186,90,193,213,254,222,227,239,106,255,96,192,168,51,32,33,34,30,9,17,241,232,124,233,85,232,112,163,218,216, +59,244,71,8,7,51,156,9,8,12,87,180,170,75,238,252,1,96,229,129,153,36,206,31,0,32,164,87,180,116,254,0,64,255,19,56,143,184,232,132,12,0,71,40,180,142,23,239,198,129,130,77,20,82,231,16,217,175,7,140,109,104,15,128,208,2,170,9,127,35,71,142,36,182,140, +158,217,179,103,99,228,200,145,112,58,149,29,121,221,181,113,23,60,112,205,221,228,67,126,24,134,154,183,86,31,194,39,27,142,106,166,223,166,65,2,174,110,203,69,152,149,36,68,155,209,178,190,234,105,245,85,200,41,59,140,157,57,107,168,228,14,218,229, +156,76,42,177,154,208,252,237,248,192,229,211,156,18,196,171,84,122,171,14,124,7,162,222,202,127,144,36,212,153,48,6,144,131,119,165,72,53,225,47,20,156,127,102,102,38,70,140,24,161,216,249,119,111,214,21,15,94,115,15,59,127,38,100,208,58,8,104,223,168, +14,186,183,175,175,153,126,40,113,117,155,20,77,134,75,174,60,48,131,172,242,95,0,175,164,167,173,208,124,98,152,95,222,144,113,49,9,159,0,32,217,72,60,89,122,0,251,242,254,164,144,58,7,99,155,22,136,26,76,59,118,152,10,78,251,123,79,56,166,253,153,218, +129,63,50,1,225,30,4,180,74,141,215,100,232,207,177,226,93,216,159,255,55,149,220,17,123,30,190,160,18,187,16,126,9,0,30,184,124,154,83,64,122,145,74,111,213,193,89,154,28,178,18,63,118,20,116,113,49,228,186,106,224,180,191,247,112,218,159,9,117,56,8, +208,14,147,65,135,43,90,209,207,251,7,128,223,246,207,160,19,147,196,203,233,67,51,105,219,121,106,192,111,111,202,230,121,226,75,0,187,41,180,114,202,14,99,91,246,111,20,82,231,32,199,68,33,110,236,40,114,93,53,124,116,116,15,167,253,189,128,211,254, +76,109,129,131,0,109,184,162,101,93,88,140,244,117,239,251,242,254,196,177,226,93,36,90,18,112,212,150,43,77,39,17,243,2,191,189,45,135,14,205,116,67,162,203,2,172,220,63,19,14,55,253,0,159,168,65,189,97,238,68,219,106,168,134,91,146,27,33,86,175,172, +87,245,219,111,191,13,137,180,63,183,250,49,204,185,112,16,64,75,82,172,5,173,79,119,68,80,34,132,192,202,131,223,145,233,121,132,228,183,213,63,224,199,0,0,0,154,229,138,153,16,216,73,161,85,230,40,196,218,195,63,80,72,157,139,36,33,97,252,253,144,244, +193,113,246,120,138,201,130,87,91,117,81,116,239,241,227,199,137,173,161,135,247,252,25,166,122,56,8,160,65,146,36,116,111,151,170,73,225,223,150,147,203,145,91,166,44,67,91,13,71,34,237,165,126,91,253,3,126,14,0,78,103,1,210,169,244,54,28,157,143,66, +43,253,193,23,134,166,141,16,125,219,96,114,93,165,12,72,172,143,91,235,54,242,249,190,41,83,166,96,203,150,45,26,88,68,3,239,249,51,204,133,225,22,65,245,180,111,148,128,58,49,102,114,93,135,219,138,85,7,102,145,233,73,66,164,143,27,180,216,78,38,232, +5,126,127,115,78,74,203,200,4,176,153,66,203,237,113,97,5,101,241,197,89,196,221,55,2,250,6,193,243,193,120,190,249,165,104,96,142,240,233,30,187,221,142,145,35,71,86,153,254,22,12,176,243,103,24,239,224,22,65,229,68,91,140,232,210,82,155,194,191,213, +7,103,163,220,81,68,37,183,199,42,231,125,77,37,230,45,126,127,123,74,18,132,68,152,5,216,147,187,30,135,10,232,87,185,146,201,136,196,41,143,5,205,108,128,104,189,1,83,91,95,14,157,143,121,172,237,219,183,227,153,103,158,209,200,42,101,112,193,31,195, +248,6,111,7,40,163,123,251,250,48,232,232,223,19,69,214,108,252,121,252,39,50,61,1,233,95,254,232,251,63,159,128,188,65,39,165,101,252,0,224,15,42,189,101,251,190,164,59,124,225,44,76,29,90,35,250,166,1,228,186,74,185,50,54,17,99,27,180,242,249,190,183, +222,122,11,203,151,47,215,192,34,223,225,61,127,134,81,6,7,1,190,209,182,97,2,82,235,68,105,162,189,116,239,23,112,123,148,45,96,170,225,207,201,105,25,115,169,196,124,33,112,75,40,33,210,169,164,242,202,143,98,203,9,109,28,92,252,131,119,66,95,63,120, +78,60,123,178,73,91,92,26,237,219,24,75,143,199,131,209,163,71,163,160,160,64,35,171,188,131,211,254,12,163,14,14,2,188,35,210,108,208,172,231,255,96,193,102,236,207,167,27,70,39,132,248,151,214,51,255,107,34,96,111,210,201,125,102,47,6,176,132,74,111, +213,129,89,176,187,202,169,228,206,32,153,77,168,51,241,65,104,82,66,170,0,189,36,227,205,214,151,195,34,251,214,165,112,252,248,113,140,29,59,86,35,171,46,14,59,127,134,161,129,131,128,139,211,163,125,42,140,26,116,114,121,132,27,191,238,251,138,82, +114,233,148,62,179,201,252,160,175,4,244,109,234,150,228,39,1,144,236,123,84,56,75,176,250,208,28,10,169,42,152,59,119,68,212,224,62,154,104,43,161,69,68,52,38,55,235,224,243,125,115,230,204,193,55,223,144,28,204,232,19,236,252,25,134,22,238,14,168,153, +86,169,241,104,144,168,77,234,255,175,99,63,33,183,156,236,231,238,148,116,242,56,42,49,37,4,244,141,250,127,105,179,182,9,72,211,168,244,254,60,182,24,217,165,218,156,93,158,240,216,189,48,52,12,158,168,120,116,253,230,232,157,224,251,214,196,163,143, +62,138,195,135,201,250,86,47,10,59,127,134,209,6,238,14,168,74,180,197,136,171,219,104,19,184,148,216,243,177,234,96,6,157,160,36,125,48,169,231,44,146,185,56,74,9,248,91,213,228,16,207,2,200,167,208,242,8,55,22,237,250,159,38,5,129,146,217,132,196,103, +199,7,205,128,32,9,192,235,173,187,32,209,104,242,233,190,226,226,98,140,26,53,10,110,55,253,207,232,124,216,249,51,140,182,240,118,192,63,72,18,112,109,135,84,24,244,218,188,47,150,238,249,156,114,250,108,129,199,237,36,155,140,171,148,128,123,179,159, +191,217,97,237,119,87,7,27,128,129,20,122,229,142,98,152,116,17,72,141,109,77,33,119,14,186,196,4,64,8,216,54,109,39,215,86,66,132,78,143,198,230,40,44,200,61,230,211,125,71,142,28,65,68,68,4,186,119,239,174,145,101,52,227,125,199,94,125,23,59,127,21, +164,116,104,128,228,214,234,86,67,155,78,148,96,205,17,178,94,103,70,3,214,29,45,130,81,39,163,75,106,172,38,250,137,49,22,68,152,245,56,146,91,170,137,62,21,151,53,79,70,171,84,223,10,164,189,101,119,238,122,172,57,52,155,78,80,224,201,41,125,231,172, +164,19,84,70,80,188,93,173,82,206,255,36,96,27,149,222,239,135,50,80,100,205,166,146,59,135,216,59,111,131,169,61,125,112,161,148,254,137,245,49,172,94,19,159,239,251,191,255,251,63,252,251,223,255,214,36,19,192,179,253,25,198,191,132,123,38,32,49,198, +130,203,154,39,105,162,109,119,89,177,108,47,233,132,222,29,54,57,247,19,74,65,165,4,69,0,144,158,182,194,229,145,164,9,84,122,78,183,29,139,119,127,4,104,209,89,161,211,33,241,217,241,144,35,45,244,218,10,249,119,243,75,208,196,226,91,209,139,219,237, +198,127,254,243,31,244,238,221,155,244,204,0,238,243,103,152,192,16,174,65,128,94,39,35,237,146,6,144,53,122,103,252,118,96,6,74,237,116,45,212,66,136,9,129,24,250,83,29,65,17,0,0,192,148,180,140,165,0,22,82,233,29,41,220,142,173,39,86,80,201,157,131, +62,37,25,241,227,238,215,68,91,9,17,122,3,190,248,247,11,48,24,124,63,53,112,229,202,149,232,212,169,19,22,46,84,255,163,231,61,127,134,9,44,225,216,29,112,77,219,20,196,70,250,86,11,229,45,39,74,246,97,83,214,47,116,130,18,190,15,100,219,223,249,4,213, +155,86,2,158,4,64,118,20,226,242,253,95,163,220,81,76,37,119,14,81,3,122,33,106,96,154,38,218,62,33,73,72,120,236,30,244,156,52,30,83,166,76,81,36,145,151,151,135,27,110,184,1,19,39,78,84,236,188,121,188,47,195,4,7,225,212,29,208,188,94,172,102,251,254, +30,225,198,226,93,31,65,8,15,149,164,93,246,200,19,169,196,40,8,170,183,237,164,222,153,187,1,188,79,165,103,115,150,97,233,222,207,169,228,170,144,48,97,44,140,45,154,104,166,127,81,78,59,255,202,147,11,159,125,246,89,116,237,218,85,145,148,16,2,111, +188,241,6,174,185,230,26,236,223,191,223,167,123,57,237,207,48,193,69,56,108,7,196,70,154,208,189,125,170,102,250,107,14,205,69,110,249,17,58,65,9,111,61,221,103,150,111,47,87,141,9,170,0,0,0,76,146,243,5,0,57,84,122,187,114,214,98,95,222,70,42,185,115, +144,76,70,36,166,63,25,152,122,128,243,156,63,0,232,245,122,124,243,205,55,136,142,142,86,44,187,113,227,70,116,238,220,25,179,102,121,119,204,37,167,253,25,38,56,169,205,65,128,94,39,163,111,167,70,154,181,252,157,44,61,128,181,135,73,199,243,159,144, +12,246,151,41,5,41,8,186,183,238,132,180,31,138,32,137,199,41,53,151,236,249,76,147,49,193,0,96,104,88,31,9,79,61,164,137,118,141,84,227,252,43,105,222,188,57,222,120,227,13,85,242,37,37,37,24,62,124,56,70,143,30,141,138,138,138,26,175,99,231,207,48, +193,77,109,13,2,186,181,171,143,248,40,109,246,253,93,30,39,22,238,252,128,116,158,140,128,244,216,164,238,243,130,174,143,50,40,223,188,147,211,102,127,39,128,121,84,122,165,246,124,44,222,245,17,149,92,21,34,123,119,67,244,77,253,53,211,63,135,11,56, +255,74,198,142,29,139,27,110,184,65,245,163,190,254,250,107,116,235,214,13,123,246,236,169,242,61,222,243,103,152,208,160,182,5,1,109,26,36,160,101,253,56,205,244,87,29,252,14,121,116,227,126,33,4,22,76,233,157,161,205,156,122,149,4,237,219,87,118,233, +30,2,64,86,193,183,59,119,61,182,157,252,141,74,174,10,241,143,221,3,99,235,230,154,233,3,56,237,252,239,189,160,243,175,36,35,35,3,227,198,169,31,51,189,105,211,38,116,233,210,229,156,51,4,120,207,159,97,66,139,218,210,29,80,39,218,172,233,115,142,23, +239,198,134,163,100,205,104,0,80,34,203,110,63,167,136,189,39,224,147,0,107,98,233,215,219,74,251,141,110,95,6,9,131,168,52,15,23,110,69,155,228,174,176,24,148,239,145,215,132,164,211,33,226,234,46,168,88,177,22,158,242,154,211,230,202,31,80,233,252, +189,251,113,232,245,122,12,28,56,16,109,218,180,193,47,191,252,2,187,221,174,248,209,14,135,3,223,127,255,61,142,28,57,130,226,226,98,140,30,61,154,39,252,133,0,60,9,144,57,27,173,39,6,38,199,70,192,100,212,225,88,94,153,38,250,145,102,3,6,93,209,20, +38,131,54,110,203,233,182,35,99,243,203,176,58,233,50,245,2,24,55,185,247,156,95,201,4,137,9,234,183,176,117,85,251,255,1,248,157,74,207,225,182,97,254,142,119,53,57,43,0,56,53,42,56,249,205,231,160,175,155,72,44,172,67,157,167,31,246,218,249,159,205, +240,225,195,177,101,203,22,197,221,1,103,51,125,250,116,220,117,215,93,188,242,103,152,16,197,31,45,130,61,218,167,146,127,198,163,204,6,12,188,188,9,34,205,190,207,58,241,150,95,247,127,141,66,235,9,74,201,149,147,211,50,131,98,226,95,77,4,109,6,0,0, +86,172,88,33,122,223,217,126,189,36,225,126,0,122,10,205,50,123,33,36,200,104,20,223,158,66,174,10,186,216,24,68,166,117,131,125,231,94,184,115,242,212,235,213,137,71,242,203,147,17,209,227,42,197,26,113,113,113,184,251,238,187,225,112,56,176,102,205, +26,213,54,41,129,11,254,252,15,103,0,152,234,88,119,180,8,6,141,207,14,168,23,31,137,99,121,101,112,185,213,247,208,215,141,139,192,128,46,77,16,19,97,36,176,174,122,246,231,255,141,229,251,190,162,148,180,73,192,224,238,205,118,168,119,2,26,18,212,1, +0,0,44,251,106,71,110,191,187,219,233,0,169,23,149,230,241,226,221,104,18,223,17,49,102,226,149,250,105,228,8,11,162,250,247,130,108,49,195,177,115,47,132,211,247,21,179,164,215,33,250,198,254,72,122,97,34,12,141,27,168,183,73,150,209,183,111,95,116, +234,212,9,75,150,44,129,213,74,118,170,213,69,225,180,127,96,224,0,128,169,9,173,131,128,104,139,17,173,27,196,195,225,242,160,160,212,166,104,40,187,81,175,67,151,22,117,209,163,125,125,24,53,74,251,3,167,14,144,203,220,242,18,156,110,27,161,170,244, +239,201,189,51,127,32,20,212,132,160,15,0,0,160,251,224,246,107,245,17,184,21,64,50,133,158,128,192,225,194,237,232,152,146,6,189,172,81,74,73,150,97,234,216,6,81,131,251,66,142,176,192,117,252,164,87,181,1,186,248,88,68,223,208,15,137,207,140,71,100, +191,107,33,153,104,163,222,54,109,218,96,196,136,17,216,176,97,3,142,30,213,46,21,88,9,31,236,19,56,56,0,96,46,132,214,65,128,94,39,163,81,82,52,90,156,174,216,47,181,58,189,202,8,68,153,13,232,216,36,9,189,58,166,34,53,49,74,211,119,135,16,2,115,183, +189,78,59,240,71,96,107,124,108,252,93,11,166,253,73,54,66,80,43,66,230,173,252,242,242,219,174,146,33,175,6,97,208,210,161,94,79,12,110,251,8,149,220,133,17,2,142,189,7,97,223,178,19,142,131,71,224,46,40,130,176,59,32,25,244,208,37,38,192,208,40,21, +166,142,109,97,106,211,28,144,181,95,41,239,92,178,5,255,122,106,10,126,220,182,24,66,104,112,104,18,56,237,31,104,58,15,235,138,14,55,118,86,165,49,253,207,99,120,125,213,65,34,139,152,96,100,124,183,38,24,123,69,67,205,159,227,17,2,121,197,86,100,23, +85,160,168,220,142,10,187,11,30,143,128,78,150,16,97,210,35,62,202,140,122,241,145,168,19,99,214,220,150,74,86,31,202,196,239,7,51,41,37,61,30,15,186,255,171,111,230,90,74,81,173,32,217,87,247,7,255,234,61,103,253,127,151,223,254,129,4,73,125,111,219, +105,182,157,252,13,205,234,116,66,219,228,110,84,146,53,35,73,48,182,106,6,99,171,102,218,63,235,34,236,89,182,29,27,190,250,29,183,116,28,140,214,201,45,240,241,154,47,81,100,165,61,51,129,157,63,195,132,6,111,175,62,4,0,154,7,1,178,36,33,57,46,2,201, +113,17,154,62,199,91,142,22,237,192,234,67,228,237,249,111,135,138,243,7,130,188,11,224,124,244,78,203,191,0,84,157,74,163,130,159,118,77,67,126,5,221,113,184,193,206,158,101,219,177,110,250,111,103,78,74,110,87,183,53,94,24,56,5,29,83,218,146,61,131, +157,63,195,132,22,111,175,62,132,105,26,118,7,4,27,86,103,41,230,239,120,151,242,160,31,64,96,167,173,220,246,44,157,160,246,132,212,27,122,98,255,175,203,5,48,18,132,39,6,58,220,86,204,221,250,58,236,46,255,21,197,5,138,243,157,127,37,49,230,104,60, +217,235,17,220,122,201,245,170,157,54,79,248,99,152,208,36,124,130,0,129,69,187,62,68,169,189,128,82,212,41,132,124,87,250,13,243,53,24,2,163,29,33,247,150,158,210,59,243,79,9,34,157,82,179,160,34,11,139,119,253,15,85,60,99,45,162,38,231,95,137,36,73, +184,169,195,64,60,115,221,147,72,140,172,163,232,25,220,231,207,48,161,77,56,4,1,235,143,204,163,63,32,78,72,255,154,210,119,214,6,90,81,237,9,185,0,0,0,172,43,59,188,10,96,57,165,230,238,220,245,88,127,132,236,248,129,160,226,98,206,255,108,154,215, +105,130,244,1,79,163,83,106,7,159,158,193,105,127,134,169,29,212,230,32,224,112,225,86,252,118,96,38,169,166,0,126,179,173,106,55,149,84,212,79,132,68,27,224,249,172,88,177,66,244,187,187,205,114,64,190,27,0,217,89,188,135,139,182,161,126,76,43,196,91, +234,81,73,6,28,95,156,127,37,38,189,17,93,155,92,142,72,99,4,118,102,239,129,231,34,251,100,236,252,131,19,110,3,100,148,162,117,139,96,32,40,177,229,98,214,230,23,225,116,43,31,139,94,13,133,110,157,238,186,231,238,126,159,182,138,218,79,132,236,27, +123,82,218,220,99,2,210,88,74,77,33,4,230,237,120,7,197,182,28,74,217,128,177,235,231,173,62,59,255,74,36,72,184,174,117,26,158,185,238,73,36,71,213,60,48,137,157,63,195,212,78,222,94,125,8,95,252,85,59,10,164,93,30,39,190,223,246,38,233,156,255,83,72, +15,62,211,243,187,144,77,151,132,244,91,123,74,239,140,57,2,226,75,74,77,155,179,12,223,111,125,19,46,15,89,157,97,64,216,191,106,55,254,248,122,149,234,178,134,166,9,141,240,159,129,83,208,181,113,151,42,223,99,231,207,48,181,155,215,87,30,64,198,86, +210,249,248,1,97,201,158,79,113,178,244,0,177,170,248,100,114,239,140,12,98,81,191,18,242,111,110,187,36,61,10,129,189,148,154,217,101,7,177,116,239,116,74,73,191,114,98,251,49,172,153,182,156,172,166,209,98,48,227,161,110,247,98,236,213,163,97,212,159, +154,76,200,206,159,97,106,63,2,192,11,203,247,99,221,209,208,221,6,218,120,108,17,182,158,32,63,144,111,159,100,116,60,73,45,234,111,66,254,237,157,158,150,89,38,201,242,104,0,202,142,168,171,129,205,89,203,176,249,196,50,74,73,191,96,47,179,99,213,7, +75,33,60,244,29,13,221,154,94,133,103,251,61,137,235,219,93,199,173,126,12,19,38,184,133,192,196,197,187,80,108,35,125,197,250,133,163,69,59,241,235,190,175,169,101,29,146,228,25,49,169,251,60,234,253,4,191,83,43,222,224,147,210,102,173,147,32,253,135, +90,247,151,61,159,225,72,209,118,106,89,77,249,59,99,29,108,197,218,181,162,54,138,111,128,33,157,110,226,86,63,134,9,35,242,43,156,120,107,117,104,141,132,46,182,229,224,135,237,83,201,143,127,23,146,244,220,164,180,57,196,125,132,129,161,86,4,0,0,208, +52,79,188,12,128,116,201,238,246,184,240,253,214,55,66,102,82,96,105,78,9,246,174,216,25,104,51,24,134,169,133,204,217,150,141,195,69,161,49,48,205,238,42,71,230,230,255,162,194,65,92,156,47,97,177,253,183,118,175,211,138,6,142,90,19,0,12,29,154,233, +54,58,48,20,0,105,152,106,115,149,35,115,243,203,40,167,254,67,210,128,93,63,111,133,32,56,127,155,97,24,230,124,220,66,224,219,77,89,129,54,227,162,120,132,27,63,108,155,74,190,112,19,192,97,61,244,163,211,211,211,107,205,75,182,214,4,0,0,240,196,128, +204,2,89,194,173,0,72,195,212,98,91,46,102,111,121,133,186,127,148,20,225,246,224,224,26,210,99,18,24,134,97,206,97,209,238,92,184,53,168,47,162,228,151,61,159,227,80,225,86,106,89,155,78,200,183,62,149,54,51,143,90,56,144,212,170,0,0,0,158,78,203,220, +36,9,60,64,173,123,178,116,63,126,220,254,54,237,225,17,132,228,29,204,133,173,36,52,210,115,12,195,132,38,5,86,39,182,231,148,5,218,140,26,89,123,120,46,54,101,253,66,174,43,36,60,244,116,159,89,127,145,11,7,152,90,23,0,0,192,164,62,153,95,3,226,19, +106,221,253,249,127,226,215,253,223,80,203,146,144,187,231,100,160,77,96,24,38,12,248,243,120,112,110,135,238,202,89,139,85,7,103,145,235,10,9,239,79,73,203,252,130,92,56,8,168,149,1,0,0,68,216,202,31,3,240,7,181,238,134,163,11,240,215,177,159,168,101, +85,83,156,85,24,104,19,24,134,9,3,14,20,4,95,166,241,88,241,110,44,220,249,62,132,32,223,158,88,99,207,69,200,247,251,215,68,173,13,0,198,13,90,108,119,233,116,183,3,200,165,214,94,186,111,58,246,230,5,215,193,79,86,13,91,255,24,134,97,42,201,171,8,174, +41,169,121,229,71,49,103,235,171,112,121,156,212,210,217,46,129,161,233,67,51,131,235,31,76,72,173,13,0,0,224,153,158,223,29,21,2,195,65,60,36,72,8,129,249,59,222,197,137,146,253,148,178,170,112,59,66,111,72,7,195,48,161,135,213,73,219,87,175,134,98, +91,14,102,109,126,17,54,39,121,93,130,83,246,136,33,207,244,201,12,141,30,112,133,212,234,0,0,0,166,244,201,92,46,128,127,81,235,58,221,118,204,218,252,34,178,203,130,99,56,134,222,100,8,180,9,12,195,132,1,145,198,224,56,68,182,194,89,130,140,205,47, +163,204,78,191,253,41,65,122,234,233,190,179,87,145,11,7,25,181,62,0,0,128,201,105,153,111,64,96,54,181,174,253,244,140,128,130,138,192,31,150,97,137,37,59,21,153,97,24,166,70,18,35,140,129,54,1,118,87,5,102,109,122,17,5,21,244,115,9,4,164,111,39,245, +206,120,151,92,56,8,9,139,0,64,146,32,140,22,140,150,36,172,165,214,46,119,20,227,187,77,255,9,248,17,194,177,13,18,2,250,124,134,97,194,131,150,137,145,1,125,190,203,227,192,156,173,175,34,167,236,144,22,242,127,216,203,173,164,199,204,7,51,97,17,0, +0,192,19,215,100,90,117,208,223,8,96,31,181,118,169,61,31,223,109,122,65,147,84,148,183,212,109,157,18,176,103,51,12,19,62,92,158,26,27,176,103,11,225,193,252,29,239,225,104,145,38,35,207,15,232,156,174,27,210,111,152,31,54,21,213,97,19,0,0,192,83,105, +51,243,36,157,124,35,240,255,237,221,121,124,148,229,185,240,241,223,61,51,201,100,223,23,200,2,36,44,33,4,148,197,93,22,179,176,185,160,5,130,212,86,218,99,107,151,115,142,231,188,237,91,13,112,168,70,43,21,180,245,244,120,186,89,125,173,82,169,144, +0,238,184,177,136,90,197,202,38,251,146,4,8,9,89,39,123,50,51,153,153,231,126,255,64,44,85,246,228,153,103,150,251,251,249,240,177,254,115,95,215,199,14,243,92,115,63,247,125,93,244,251,147,186,205,222,192,170,93,143,208,227,234,232,239,165,47,74,194, +224,100,34,18,162,12,137,173,40,74,112,24,24,109,37,39,217,152,29,0,41,53,222,56,240,91,14,55,125,170,199,242,205,38,179,54,227,254,233,47,27,187,149,235,101,65,85,0,0,148,76,89,125,0,41,238,0,250,189,175,175,173,167,150,85,187,126,161,199,137,212,11, +19,48,252,166,92,239,199,85,20,37,104,20,143,25,128,17,115,64,165,212,120,243,224,239,217,223,240,145,30,203,247,10,77,204,123,96,202,218,35,122,44,238,203,130,174,0,0,88,88,88,246,1,66,126,23,232,247,174,17,77,93,199,41,223,253,24,189,30,239,55,203, +200,153,58,154,144,48,117,27,64,81,148,254,23,109,181,48,111,140,247,95,53,74,41,89,127,240,15,236,171,255,64,151,229,133,144,247,148,20,149,109,214,99,113,95,23,148,5,0,192,194,252,53,171,128,82,61,214,62,217,113,132,181,187,31,199,173,121,183,127,68, +88,76,56,99,110,159,224,213,152,138,162,4,135,31,94,147,73,66,184,119,127,96,156,122,248,255,158,189,245,91,116,10,192,226,146,252,53,43,245,89,220,247,5,109,1,0,80,146,95,254,11,36,207,235,177,118,117,219,62,202,62,95,138,211,237,221,157,128,188,91, +198,146,60,124,128,87,99,42,138,18,216,198,167,197,240,157,241,233,94,142,42,121,247,240,179,250,61,252,225,255,45,44,44,95,166,215,226,254,32,168,11,0,33,144,241,177,241,63,64,208,255,227,163,128,19,109,7,88,181,235,17,236,174,78,61,150,63,43,97,54, +49,249,190,105,234,64,160,162,40,253,98,96,180,149,95,223,156,139,89,120,243,237,191,228,157,67,207,234,50,217,239,11,239,56,68,211,143,244,90,220,95,4,117,1,0,240,195,171,254,228,178,226,154,7,236,211,99,253,250,206,74,86,237,250,133,87,111,7,68,38, +70,49,117,225,109,68,196,27,123,95,87,81,20,255,150,26,101,229,153,111,140,38,53,202,123,205,127,164,212,88,127,224,15,186,61,252,37,236,118,56,66,231,149,230,191,31,244,253,211,131,190,0,0,248,73,254,43,109,110,179,121,38,112,76,143,245,27,187,142,241, +215,29,15,121,181,79,64,108,122,60,51,31,158,67,194,144,36,175,197,84,20,37,112,228,166,68,241,210,252,43,201,78,136,240,90,76,143,230,230,213,125,191,97,79,253,251,122,133,168,52,185,205,51,75,111,94,105,204,125,109,31,163,10,128,47,44,153,178,234,132, +73,154,138,128,254,239,45,201,169,43,130,47,238,88,66,155,189,65,143,229,207,42,50,49,138,153,165,115,200,157,126,133,215,98,42,138,226,255,102,229,166,176,114,222,149,12,136,178,122,45,166,203,227,100,221,158,199,57,212,180,85,175,16,53,102,51,83,75, +166,173,210,229,59,222,31,169,2,224,12,15,20,174,174,212,52,83,62,160,203,83,186,221,209,196,202,29,15,210,220,125,66,143,229,207,202,28,98,230,234,5,19,153,248,227,34,53,48,72,81,148,243,10,179,152,248,197,212,225,44,155,158,67,152,197,123,143,7,167, +187,135,178,207,151,82,213,178,75,175,16,77,194,108,154,118,255,148,114,223,152,222,230,35,84,1,240,21,139,139,86,31,54,107,218,52,160,69,143,245,187,122,91,121,105,215,35,52,118,29,215,99,249,115,202,158,56,130,91,30,157,75,156,154,25,160,40,202,89, +100,197,135,179,106,254,88,230,228,121,247,22,81,79,111,59,47,237,124,152,154,246,131,122,133,104,147,102,109,122,201,148,213,186,244,15,246,103,170,0,56,139,251,139,214,238,22,194,116,11,160,75,75,191,158,222,118,94,218,245,48,117,29,149,122,44,127, +78,177,105,241,220,252,240,28,178,110,24,238,213,184,138,162,248,182,91,71,166,80,126,215,56,70,120,121,208,79,135,211,198,202,157,15,233,57,86,189,67,106,166,105,139,166,172,221,169,87,0,127,166,10,128,115,40,201,95,189,85,104,98,22,160,203,69,126,135, +171,139,151,118,149,82,209,188,77,143,229,207,201,18,22,194,164,127,155,202,13,247,230,99,81,93,3,21,37,168,69,134,154,89,58,117,4,143,207,200,33,34,196,236,213,216,205,221,53,172,220,241,115,93,70,250,126,161,7,41,110,91,84,180,250,51,189,2,248,59,85, +0,156,71,73,81,217,102,41,165,46,115,3,224,139,67,47,123,127,197,246,154,183,244,88,254,188,134,221,148,203,172,101,119,146,50,66,77,17,84,148,96,52,102,64,52,107,238,26,199,55,242,82,189,30,251,120,235,94,94,220,241,115,58,28,205,122,133,232,213,16, +197,11,11,203,116,233,31,28,40,84,1,112,1,139,10,215,188,43,132,152,15,232,114,103,84,74,141,13,71,254,204,134,35,127,70,74,77,143,16,231,20,149,28,195,244,37,183,51,126,254,245,152,204,234,163,160,40,193,192,44,4,223,191,42,131,149,243,174,100,112,92, +184,215,227,239,173,223,66,249,238,95,226,116,119,235,21,194,35,165,252,246,226,130,178,245,122,5,8,20,234,91,255,34,148,228,151,189,34,36,247,0,186,61,161,183,215,188,197,203,123,127,141,203,163,203,102,195,57,9,179,137,209,183,141,99,198,131,223,32, +58,213,184,57,223,138,162,232,47,45,198,202,243,115,199,240,211,137,89,88,76,222,158,235,39,249,219,177,53,188,121,224,247,120,52,221,122,240,104,66,200,239,44,42,92,83,174,87,128,64,162,10,128,139,84,82,88,254,23,41,197,183,209,105,39,0,224,72,243,103, +188,180,171,148,238,222,118,189,66,156,83,210,176,84,110,93,90,204,208,201,35,189,30,91,81,20,125,9,96,118,94,42,175,126,123,2,19,210,189,95,232,107,210,195,59,135,158,225,163,163,101,232,48,132,245,52,143,16,226,158,96,30,238,115,169,84,1,112,9,22,21, +150,189,132,20,179,1,135,94,49,234,58,42,249,203,246,197,216,122,106,245,10,113,78,33,225,161,220,248,195,2,138,74,110,37,50,81,205,18,80,148,64,144,18,25,202,111,103,141,226,209,169,35,136,12,245,238,65,63,128,94,143,157,181,123,30,103,215,201,13,186, +134,17,200,121,37,249,101,47,232,25,36,208,168,2,224,18,45,44,44,123,93,67,204,65,167,219,1,112,170,97,208,139,219,151,80,221,170,203,120,130,11,74,187,98,16,179,150,207,39,119,250,21,8,175,14,0,81,20,165,191,8,96,222,152,1,188,249,157,171,200,207,78, +52,36,135,150,158,58,86,108,91,76,149,77,215,91,120,61,32,102,149,20,172,89,167,103,144,64,164,10,128,203,176,184,160,108,189,208,132,110,125,2,0,28,238,110,202,118,47,229,243,147,27,245,10,113,94,33,225,161,92,189,96,34,211,127,126,7,49,3,227,12,201, +65,81,148,203,147,17,19,198,115,115,198,80,90,56,220,144,95,253,0,85,182,157,172,208,127,55,179,3,41,102,46,44,40,123,71,207,32,129,74,21,0,151,169,164,168,108,179,16,90,62,96,211,43,134,71,115,243,246,161,167,121,227,192,111,113,107,189,122,133,57,175, +148,156,129,220,186,180,248,212,110,128,215,15,13,41,138,114,41,204,66,240,157,241,233,188,182,96,2,215,102,26,87,184,111,171,89,207,154,61,203,245,60,233,15,208,42,132,105,186,186,234,119,249,84,1,208,7,37,249,107,183,153,4,69,64,147,158,113,246,213, +127,192,139,219,127,78,187,163,81,207,48,231,100,177,134,112,245,130,137,220,242,104,49,201,195,189,219,38,84,81,148,139,147,247,197,244,190,146,201,217,94,237,227,127,38,183,230,226,205,3,191,99,227,145,231,245,190,214,220,0,166,252,146,252,213,186, +77,14,10,6,170,0,232,163,7,242,203,119,105,66,155,12,212,232,25,167,161,235,40,47,108,91,196,209,150,233,133,193,178,0,0,23,211,73,68,65,84,207,245,12,115,94,9,131,147,152,249,208,108,110,252,81,33,214,232,48,195,242,80,20,229,31,98,172,22,22,77,201, +102,213,55,199,50,58,53,218,176,60,58,157,54,86,238,120,144,189,245,91,244,14,85,7,90,225,194,130,213,198,125,25,6,8,99,94,14,5,152,141,47,28,104,158,182,96,204,107,82,200,89,128,110,251,110,110,173,151,253,141,127,195,108,10,33,35,54,135,83,199,124, +188,76,156,42,4,134,223,52,10,205,229,193,86,101,204,174,132,114,97,3,71,103,144,146,211,183,78,143,187,234,58,248,184,186,173,159,50,82,250,147,224,212,216,222,223,207,202,227,186,65,113,152,12,60,176,123,188,117,15,171,119,61,74,171,189,94,239,80,149, +82,152,167,44,42,40,63,162,119,160,96,160,10,128,126,242,222,138,125,173,55,221,115,197,58,147,148,211,128,20,253,34,73,142,183,238,161,169,251,4,67,19,199,97,54,25,211,207,223,18,106,33,253,202,65,12,204,203,160,229,88,51,246,246,30,67,242,80,206,77, +21,0,129,43,55,37,138,255,190,37,151,187,199,165,19,238,229,30,254,103,146,82,227,111,199,214,240,246,161,167,113,121,116,187,29,125,218,231,194,109,46,90,88,180,202,123,243,212,3,156,42,0,250,209,166,231,247,118,76,189,119,216,95,208,44,99,1,93,71,238, +217,122,106,57,220,244,41,131,227,71,19,17,106,92,7,191,200,164,104,134,23,140,34,62,35,145,230,138,6,92,118,99,14,43,42,95,167,10,128,192,147,18,25,202,253,147,179,121,168,112,24,233,49,198,190,134,235,113,117,240,202,222,95,179,187,110,19,58,54,247, +57,69,240,30,30,110,94,56,173,76,183,225,1,193,72,21,0,253,108,195,115,135,122,139,239,155,88,230,112,56,50,17,140,213,51,150,221,213,197,190,250,15,137,13,75,33,57,106,144,158,161,206,75,8,65,92,70,2,35,10,243,8,9,15,165,185,162,1,205,237,221,185,6, +202,215,169,2,32,112,132,89,76,124,119,124,58,79,222,146,203,184,180,24,67,183,251,225,31,91,254,141,93,199,189,16,77,62,227,16,205,119,45,41,92,175,91,239,149,96,165,238,117,233,104,217,230,226,255,68,242,36,94,56,108,57,50,229,122,166,231,252,128,48, +139,119,231,121,159,77,79,107,55,187,215,125,198,145,247,15,32,53,157,127,25,40,231,52,254,206,235,24,61,107,124,159,214,248,243,246,26,158,248,80,183,89,237,202,5,8,96,218,240,36,238,159,148,77,90,140,213,232,116,0,201,214,234,215,248,160,234,37,111, +12,47,147,82,138,71,22,21,150,149,234,29,40,88,169,29,0,29,109,120,97,255,167,69,223,29,93,5,220,2,88,244,140,213,220,93,195,193,198,79,24,16,51,148,152,176,36,61,67,93,80,72,120,40,25,227,135,144,57,126,8,221,182,46,58,27,188,63,219,64,81,59,0,254,110, +210,144,120,158,188,57,151,111,143,75,39,218,170,235,215,199,69,233,234,109,101,221,158,39,190,104,78,166,123,97,239,144,130,187,23,21,148,255,78,239,64,193,76,21,0,58,219,240,194,190,221,69,11,70,109,66,136,219,129,8,61,99,57,221,221,236,173,223,130, +219,227,100,80,124,30,66,24,123,203,51,60,46,146,236,27,71,144,118,69,38,93,77,29,116,53,117,26,154,79,176,81,5,128,127,26,159,22,195,99,211,115,248,209,53,131,72,142,12,53,58,29,0,14,53,125,202,154,221,143,209,220,173,235,109,231,211,90,144,226,214, +69,5,229,106,156,175,206,212,43,0,47,121,108,115,241,48,161,177,30,161,239,225,192,211,6,198,12,227,182,81,247,17,31,222,183,7,64,127,106,60,84,199,142,213,91,105,60,84,103,116,42,65,65,189,2,240,47,99,6,68,243,163,107,6,145,159,157,96,116,42,95,114, +186,237,188,95,249,23,189,7,249,156,169,74,192,205,37,5,229,135,188,21,48,152,169,29,0,47,217,248,194,254,150,130,5,57,127,21,194,116,3,160,251,137,189,46,103,11,123,234,182,16,30,18,205,128,232,108,189,195,93,148,200,164,104,134,77,206,37,97,72,18,237, +181,109,56,212,213,65,93,169,29,0,255,48,50,57,146,135,139,134,115,255,164,108,178,226,195,141,78,231,75,181,237,135,41,219,189,148,99,173,123,188,21,114,171,217,229,46,122,96,234,218,106,111,5,12,118,170,0,240,162,141,43,14,218,39,206,29,186,218,18, +106,30,14,34,79,239,120,30,233,166,210,182,157,150,158,90,134,36,140,193,98,242,129,237,68,1,177,105,241,228,20,229,49,112,116,6,221,205,93,116,53,117,24,157,85,64,82,5,128,111,27,159,22,195,146,252,97,148,76,201,38,43,94,215,183,131,151,196,163,185, +248,160,234,37,222,62,244,71,28,46,221,230,157,125,213,95,29,34,114,246,127,21,173,82,7,134,188,72,189,2,48,128,148,136,229,155,230,253,95,132,124,12,157,15,7,158,22,109,77,96,234,136,239,49,60,233,106,111,132,187,36,141,135,234,216,251,250,78,106,118, +29,243,194,217,162,224,161,94,1,248,166,241,105,49,124,239,170,76,159,218,234,63,173,177,235,56,111,28,248,45,77,94,185,222,7,128,11,193,253,11,243,203,255,199,91,1,149,127,48,254,104,105,16,18,2,9,101,191,90,182,113,222,223,17,114,53,160,251,132,157, +78,103,11,235,246,60,193,208,196,9,76,207,185,151,104,171,239,124,249,164,228,12,164,32,103,32,45,199,154,217,243,234,118,170,63,171,66,74,85,9,40,129,195,36,96,218,240,100,238,189,42,131,220,148,40,163,211,249,26,183,230,98,235,241,87,216,90,253,50, +30,205,237,173,176,77,82,50,127,81,65,249,38,111,5,84,254,153,218,1,48,216,163,27,139,211,45,130,53,192,117,222,138,105,181,68,114,211,208,111,49,54,173,16,95,252,8,116,54,118,112,100,211,62,14,111,218,79,111,183,211,232,116,252,150,218,1,48,94,100,168, +153,91,114,146,89,48,46,157,236,4,223,217,230,63,83,77,251,65,222,62,248,52,182,158,90,111,134,221,134,135,57,11,167,150,171,247,253,6,82,103,0,12,182,105,197,254,206,89,119,14,126,177,215,18,18,35,16,215,122,35,166,71,115,81,105,219,206,241,182,125, +100,196,230,16,30,98,220,4,177,179,177,70,90,25,56,58,147,156,169,99,136,74,142,161,179,177,29,103,167,238,125,198,3,142,58,3,96,156,204,216,48,190,127,117,38,79,204,200,97,250,240,100,226,195,141,153,217,113,62,78,119,15,239,87,190,200,187,135,159,165, +199,229,189,115,56,2,254,228,104,102,238,146,89,229,45,94,11,170,156,149,239,253,252,11,98,203,55,22,223,45,5,127,68,231,126,1,103,178,152,66,185,118,208,237,92,63,248,27,152,77,190,249,70,72,74,73,237,206,227,28,120,103,55,117,251,106,212,57,129,139, +52,126,254,245,140,190,109,92,159,214,120,126,71,45,143,127,80,213,79,25,5,54,1,92,155,25,199,221,227,210,153,146,149,128,201,135,191,93,43,154,183,243,222,225,103,233,112,218,188,25,214,33,17,255,182,168,160,236,57,111,6,85,206,205,135,63,162,193,105, +249,230,57,87,73,105,90,139,23,174,10,158,41,53,42,139,153,35,127,68,106,116,150,55,195,94,178,142,186,54,42,182,28,160,98,203,65,28,29,170,53,248,249,92,189,96,34,185,211,175,232,211,26,43,63,63,201,210,205,149,253,148,81,96,138,177,90,152,49,34,137, +187,174,76,99,68,146,241,173,184,207,167,195,209,196,198,138,23,56,220,244,119,111,135,62,106,18,204,126,32,191,124,151,183,3,43,231,166,10,0,31,244,171,205,223,76,114,75,247,75,64,145,55,227,154,132,153,241,25,51,152,56,100,46,86,31,152,41,112,62,154, +91,227,196,142,163,28,217,180,159,186,189,53,234,208,224,89,76,252,113,17,217,19,71,244,105,141,55,15,53,113,255,91,7,251,41,163,192,97,18,112,195,160,120,230,142,30,64,126,118,34,33,102,223,254,42,117,107,46,254,94,253,26,91,171,95,193,229,241,238,185, +26,1,111,135,244,242,173,159,206,80,91,254,190,198,183,63,181,65,172,172,172,216,92,149,40,23,33,196,67,120,249,182,70,120,72,52,147,178,230,51,54,173,208,240,118,194,23,163,171,169,147,138,45,7,168,252,224,32,221,54,175,221,91,246,121,51,75,103,147, +60,188,111,23,76,246,212,119,114,231,42,245,163,237,180,180,24,43,183,231,166,50,59,47,213,240,113,188,23,171,162,121,27,27,43,94,160,205,222,224,237,208,46,36,15,58,62,204,123,188,180,180,84,141,7,245,65,170,0,240,113,143,109,184,243,106,33,180,149, +222,106,33,124,166,196,136,116,10,134,127,135,236,4,93,167,26,247,43,219,209,38,170,62,60,196,209,79,142,4,245,43,2,147,197,196,252,103,190,143,37,180,111,181,99,175,71,227,218,63,124,130,51,136,199,59,71,91,45,228,103,39,112,123,110,42,215,13,138,243, +155,47,205,86,123,61,27,143,60,79,165,109,135,17,225,143,106,26,223,90,92,84,254,137,17,193,149,139,227,47,159,229,160,182,252,163,89,209,210,105,125,10,193,119,141,136,63,34,249,26,242,135,222,77,92,120,170,17,225,47,139,230,214,168,221,93,205,209,191, +29,230,196,142,99,120,122,189,118,183,217,39,12,204,203,96,234,226,89,253,178,214,247,214,237,225,147,32,187,9,16,102,49,145,159,157,200,173,35,147,153,56,56,193,231,183,248,207,212,235,177,243,201,241,151,249,236,196,27,222,188,211,127,6,249,140,217, +21,254,147,251,167,255,165,219,128,224,202,37,240,159,79,181,194,242,77,115,103,75,196,51,128,215,187,248,152,132,153,113,233,211,152,148,53,31,171,197,119,250,149,95,12,151,195,69,205,142,99,84,127,86,69,237,238,106,220,14,151,209,41,233,238,250,239, +223,196,240,252,81,253,178,214,186,125,13,44,121,239,112,191,172,229,203,34,66,204,76,28,18,79,209,208,68,242,179,19,137,12,245,175,91,210,154,244,176,187,110,51,31,29,45,163,187,215,144,130,173,13,33,127,188,48,127,205,42,35,130,43,151,78,21,0,126,230, +209,45,243,51,45,30,207,10,224,38,35,226,135,135,68,115,195,144,57,76,72,159,225,23,231,3,190,202,227,242,208,120,168,142,154,29,199,56,246,105,5,246,182,192,27,72,100,141,178,50,231,169,5,88,172,253,115,247,220,233,214,40,122,238,239,216,122,2,175,112, +138,13,179,48,37,43,129,252,236,68,38,13,137,39,34,196,191,30,250,167,85,52,111,103,83,197,10,90,237,134,77,218,220,228,150,44,88,82,88,238,213,110,66,74,223,168,2,192,15,73,137,88,254,126,241,127,32,121,28,48,100,194,79,82,100,38,55,14,153,203,200,148, +235,240,215,143,145,212,36,13,135,78,82,179,227,24,181,159,87,211,94,219,106,116,74,253,98,194,93,55,144,119,75,255,158,219,8,164,142,128,67,19,34,152,52,36,158,155,178,19,153,144,30,131,89,248,231,231,23,224,100,199,17,54,87,190,72,77,219,1,163,82,112, +73,41,126,233,252,112,212,35,234,160,159,255,241,223,79,190,114,186,103,192,74,160,111,119,189,250,96,64,244,80,38,101,205,35,59,177,111,13,103,124,65,183,173,139,147,187,171,57,185,187,154,186,189,181,244,246,248,95,27,226,184,140,4,110,93,58,15,147, +165,127,119,103,92,30,201,220,191,238,228,136,205,255,94,235,70,91,45,92,159,25,199,141,67,226,153,56,56,158,129,209,86,163,83,234,179,230,238,26,182,84,173,164,162,121,187,145,105,28,148,102,237,174,69,83,214,238,52,50,9,229,242,169,2,192,207,61,241, +206,221,145,238,16,251,47,5,226,223,1,195,246,228,211,99,115,152,148,117,39,131,227,71,27,149,66,191,146,30,141,166,138,6,78,238,61,65,195,254,147,52,87,54,224,113,121,140,78,235,188,44,161,22,102,62,50,135,248,204,68,93,214,63,220,220,205,252,85,187, +112,248,248,141,0,171,197,196,232,212,104,174,201,136,229,198,193,241,92,57,32,26,179,47,183,229,187,4,182,158,90,62,62,182,150,3,141,31,35,165,97,255,63,120,64,62,229,232,118,46,41,189,237,245,192,123,135,22,68,2,227,111,133,194,99,91,230,140,19,30, +211,179,64,223,166,191,244,81,70,108,14,147,178,230,51,40,62,207,200,52,250,157,199,229,193,86,213,72,195,129,147,52,28,170,163,233,112,29,46,31,58,76,40,76,130,155,254,207,12,50,39,232,219,201,113,83,165,141,255,124,227,0,30,31,106,188,20,25,106,102, +220,192,24,38,164,199,114,85,122,12,99,6,68,19,106,246,191,243,41,231,99,235,169,229,147,227,47,179,191,225,35,35,31,252,32,217,163,9,237,222,197,5,107,63,53,46,9,165,191,168,2,32,128,60,189,237,7,33,45,157,109,63,21,82,62,12,24,186,207,57,36,126,12, +147,179,191,201,192,152,97,70,166,161,27,233,209,104,57,222,76,83,69,3,182,170,70,154,171,26,233,56,217,102,72,71,66,139,53,132,201,255,62,149,140,241,67,188,18,111,115,85,11,63,123,235,32,118,3,118,68,76,2,178,226,35,24,157,26,197,232,1,209,92,57,32, +154,220,228,168,128,249,133,255,85,62,243,224,7,135,148,98,185,211,38,127,89,58,175,188,215,200,68,148,254,19,152,127,107,130,220,242,45,119,230,226,209,158,145,112,163,177,153,8,134,38,142,231,218,65,179,200,140,203,53,54,21,47,112,57,92,180,28,109, +194,118,180,145,230,202,70,108,71,155,232,106,234,64,106,250,21,5,9,67,146,152,248,227,34,226,50,188,123,51,244,136,173,155,133,239,28,230,64,163,126,157,23,77,2,50,98,195,201,75,137,58,245,192,79,141,102,84,74,148,223,93,207,187,28,205,221,39,248,248, +216,58,14,54,125,236,11,109,174,63,208,52,211,189,139,139,86,7,254,93,208,32,163,10,128,0,37,37,98,217,230,226,123,5,60,1,196,24,157,79,106,84,22,87,101,222,204,168,212,137,152,68,224,127,129,159,230,233,117,211,126,178,149,214,19,45,180,213,156,250, +211,94,219,66,87,83,103,159,214,141,136,143,100,204,29,19,24,158,63,10,147,65,219,221,110,77,178,102,111,61,127,252,180,154,198,238,190,253,40,76,139,177,50,44,33,146,225,73,17,12,75,140,100,88,98,4,67,19,34,8,235,231,195,140,190,174,166,253,32,91,143, +191,250,69,247,62,195,31,252,237,8,30,114,108,201,251,95,117,194,63,48,169,2,32,192,45,253,96,246,64,179,219,252,91,96,182,209,185,0,196,134,37,51,54,125,26,227,210,166,98,181,120,109,234,177,207,113,57,92,116,214,183,211,217,216,78,103,99,7,93,141,29, +116,54,180,211,217,208,65,119,75,23,210,243,245,239,219,136,248,72,6,228,101,48,248,234,108,50,198,13,70,248,200,123,110,143,38,121,255,104,11,239,85,52,243,233,137,54,26,186,190,94,12,152,133,96,96,180,149,140,216,48,6,197,133,145,25,27,78,102,108,24, +153,177,97,12,138,11,15,138,95,245,231,34,165,164,210,182,131,79,142,175,227,100,199,17,163,211,1,64,74,222,240,88,204,255,186,100,202,170,19,70,231,162,232,71,21,0,65,98,217,230,185,243,145,226,55,128,79,244,243,13,179,68,50,54,125,26,19,50,102,16,21, +26,111,116,58,62,69,243,104,216,91,187,177,119,216,65,147,152,66,204,68,37,71,19,26,225,31,215,215,58,157,110,106,59,156,244,122,52,76,2,18,194,67,73,137,10,197,18,160,239,233,47,151,211,109,103,119,221,70,182,213,172,167,195,209,108,116,58,167,213,73, +196,125,139,10,202,214,26,157,136,162,63,245,55,50,136,252,247,230,59,226,28,210,242,176,64,252,43,94,158,48,120,46,102,83,8,121,169,19,185,58,243,86,146,34,51,141,78,71,81,116,215,106,175,99,87,237,6,62,175,219,136,211,237,51,183,232,156,66,202,223, +96,237,93,90,50,241,181,190,189,159,82,252,134,42,0,130,208,178,45,197,99,240,240,20,6,181,19,62,59,193,224,248,209,92,153,86,200,136,164,171,49,155,250,167,141,173,162,248,2,77,122,168,104,222,206,174,147,239,113,180,101,55,62,240,126,255,31,36,175, +152,48,253,236,129,194,213,149,70,167,162,120,151,42,0,130,216,178,141,243,110,147,66,254,175,128,193,70,231,114,38,171,37,146,220,148,235,25,159,62,157,228,40,159,74,77,81,46,73,119,111,27,123,234,183,176,179,246,93,58,28,77,70,167,243,85,7,145,242, +167,11,11,215,188,101,116,34,138,49,84,1,16,228,158,120,231,238,72,45,212,254,51,41,197,253,64,164,209,249,124,85,70,236,72,174,76,43,100,100,202,245,88,76,134,140,61,80,148,75,34,165,228,120,235,30,118,157,220,192,145,230,207,208,164,207,117,144,108, +70,242,96,182,141,63,205,155,87,238,115,201,41,222,163,10,0,5,128,229,239,206,79,195,226,121,72,194,247,0,159,59,146,109,181,132,147,155,114,35,99,211,166,146,26,173,111,183,59,69,185,28,182,158,90,14,52,124,204,222,250,45,180,59,26,141,78,231,108,220, +2,158,51,11,203,127,253,44,255,37,159,57,117,168,24,71,21,0,202,63,121,124,115,241,88,77,242,107,160,192,232,92,206,101,96,204,80,242,82,39,147,147,124,29,81,86,117,131,64,49,142,221,213,201,254,134,143,216,215,240,1,117,29,190,251,10,93,192,219,30,161, +253,100,113,254,218,131,70,231,162,248,14,85,0,40,103,181,108,227,220,153,32,150,34,240,217,49,127,66,8,50,98,115,201,77,185,129,156,228,107,137,8,141,53,58,37,37,8,184,181,94,170,108,59,217,91,255,1,85,45,59,241,104,110,163,83,58,159,109,66,99,113,73, +81,249,123,70,39,162,248,30,85,0,40,231,36,37,98,217,166,185,115,133,16,143,98,224,200,225,139,33,132,32,61,102,4,57,41,215,147,155,114,35,145,170,24,80,250,145,91,235,229,88,203,30,14,54,125,66,69,243,103,56,221,118,163,83,186,144,131,82,202,7,23,22, +172,89,35,132,47,93,57,80,124,137,42,0,148,11,42,221,124,147,37,76,75,249,23,132,124,16,200,48,58,159,11,49,9,51,67,226,199,48,50,245,6,70,36,93,141,213,226,115,103,27,21,63,224,116,219,169,180,237,224,80,211,86,142,182,236,194,229,113,26,157,210,5,73, +56,110,146,242,225,44,155,88,161,14,248,41,23,162,10,0,229,162,61,181,126,166,213,110,141,186,87,10,74,240,131,66,0,78,53,26,26,20,55,138,172,132,177,100,39,142,37,49,34,221,232,148,20,31,214,233,108,161,170,101,39,21,205,219,57,214,242,57,110,205,119, +70,62,95,64,181,148,226,49,167,77,62,167,166,245,41,23,75,21,0,202,37,43,45,43,14,13,75,146,243,65,60,4,100,27,157,207,165,136,13,75,38,43,225,74,6,199,143,33,43,97,44,86,75,184,209,41,41,6,146,82,163,161,235,24,21,205,219,169,180,109,167,190,243,40, +62,213,164,231,194,170,17,60,233,32,242,233,210,252,231,29,70,39,163,248,23,85,0,40,151,237,169,245,51,173,61,214,168,123,164,160,196,215,154,9,93,12,179,41,132,204,216,145,100,37,142,37,59,97,28,73,145,126,177,169,161,244,81,167,211,198,209,150,207, +169,178,237,228,88,235,30,95,106,199,123,41,170,144,98,153,195,38,95,80,191,248,149,203,165,10,0,165,207,158,222,246,131,144,182,246,214,249,8,30,144,48,218,232,124,46,87,76,88,50,89,241,87,144,17,55,146,244,216,28,226,195,7,24,157,146,210,15,58,156, +54,78,180,238,163,186,109,63,39,218,246,211,106,175,55,58,165,190,248,187,148,242,87,67,109,98,157,122,199,175,244,149,42,0,148,126,181,108,115,241,68,36,15,1,69,70,231,210,87,145,161,177,12,136,30,70,70,220,72,50,98,115,24,24,61,84,205,40,240,3,93,206, +86,106,218,15,114,188,117,15,53,237,7,105,238,174,49,58,165,190,210,164,100,61,38,241,63,139,242,203,54,24,157,140,18,56,84,1,160,232,226,139,66,224,39,192,237,248,96,103,193,203,17,98,182,50,32,122,40,153,113,185,164,199,140,32,61,54,7,171,37,194,232, +180,130,154,195,213,69,93,103,37,117,29,21,212,117,86,82,223,81,73,87,111,171,209,105,245,23,135,128,21,192,147,37,5,229,135,140,78,70,9,60,170,0,80,116,245,196,150,226,44,143,71,222,7,226,123,64,140,209,249,244,39,33,4,113,97,169,164,68,13,38,57,106, +16,201,145,131,73,137,26,76,92,120,10,234,175,86,255,115,184,187,105,234,170,166,190,179,146,186,142,74,234,58,43,104,179,55,24,157,150,30,154,129,223,155,93,238,223,221,63,253,101,159,236,41,172,4,6,245,45,165,120,197,242,143,102,69,75,151,245,30,36, +247,1,67,141,206,71,79,161,230,48,146,34,51,191,40,12,6,147,28,57,136,148,168,65,170,31,193,69,234,245,56,176,117,215,208,212,93,77,115,119,13,205,221,39,104,238,62,65,167,179,197,232,212,244,37,57,34,132,252,141,189,219,249,124,233,109,175,251,229,201, +68,197,191,168,2,64,241,170,210,210,82,83,216,228,253,83,65,254,24,184,149,0,121,61,112,49,98,194,146,136,15,31,72,124,248,0,226,195,7,16,23,158,74,124,196,169,255,29,108,147,14,157,110,59,237,142,70,218,236,13,95,254,179,205,209,136,173,187,150,118, +71,19,126,118,21,175,47,220,8,94,151,154,252,163,243,195,209,27,74,75,75,53,163,19,82,130,135,42,0,20,195,44,223,60,59,67,74,243,189,192,247,129,52,163,243,49,82,68,104,44,49,214,68,162,173,137,196,134,37,19,19,150,68,180,53,145,168,208,56,194,67,99, +136,10,141,243,155,29,4,187,171,147,238,222,118,186,123,219,232,238,109,165,187,183,131,174,222,22,58,29,54,218,190,120,216,219,93,157,70,167,105,180,90,41,197,179,30,228,51,75,10,203,107,141,78,70,9,78,170,0,80,12,247,244,182,31,132,180,117,182,221, +34,145,247,32,153,9,88,140,206,201,23,153,77,33,68,132,196,16,25,26,75,88,72,20,97,150,200,47,255,88,67,162,8,179,68,16,106,14,199,36,204,132,89,34,49,153,204,132,154,195,177,152,66,177,156,113,123,33,196,108,253,231,219,12,82,226,112,119,127,249,175, +46,205,249,229,128,27,77,122,232,245,56,112,186,123,232,117,247,224,244,216,233,117,219,233,245,216,113,186,123,112,184,187,233,117,219,113,184,187,233,116,182,208,227,106,247,245,225,56,70,114,75,88,47,144,207,57,68,243,155,165,249,239,171,255,80,138, +161,84,1,160,248,148,199,55,23,15,208,224,78,36,255,2,92,105,116,62,138,210,15,14,74,33,158,55,35,95,120,32,191,220,175,155,16,40,129,69,21,0,138,207,250,229,134,226,235,77,38,238,6,230,1,137,70,231,163,40,151,160,89,34,202,36,158,21,139,11,214,126,106, +116,50,138,114,54,170,0,80,124,94,89,89,177,185,50,89,228,35,229,2,1,119,0,209,70,231,164,40,103,97,151,146,141,32,87,36,196,38,188,242,195,171,254,228,55,147,132,148,224,164,10,0,197,175,60,241,206,221,145,90,168,253,14,77,138,121,2,166,1,97,70,231, +164,4,53,59,146,119,36,162,204,217,99,127,85,93,223,83,252,137,42,0,20,191,245,228,199,197,225,189,118,81,36,133,44,86,59,3,138,23,217,165,100,163,16,178,220,225,176,190,82,122,243,202,14,163,19,82,148,203,161,10,0,37,32,60,249,113,113,184,211,206,12, +132,188,93,32,110,6,146,141,206,73,9,40,77,18,185,30,41,94,181,134,243,246,79,111,40,183,27,157,144,162,244,149,42,0,148,128,83,90,90,106,178,78,222,55,14,41,110,19,66,222,10,140,71,125,214,149,75,183,95,72,249,186,102,50,109,112,210,248,190,186,182, +167,4,26,245,165,168,4,188,101,239,21,15,146,102,102,124,113,102,160,0,136,55,58,39,197,39,181,32,217,4,226,93,183,197,244,246,146,41,171,78,24,157,144,162,232,73,21,0,74,80,41,43,43,54,87,36,105,87,153,164,152,138,16,83,129,235,1,53,227,55,56,245,74, +248,196,36,120,15,141,247,178,108,108,159,55,175,220,99,116,82,138,226,45,170,0,80,130,90,233,235,183,69,132,69,133,141,151,136,27,133,148,69,192,141,64,184,209,121,41,186,112,1,187,133,148,27,36,166,191,57,156,33,91,212,1,62,37,152,169,2,64,81,206,240, +212,250,153,86,71,104,228,53,154,201,52,9,33,175,67,114,45,144,98,116,94,202,101,105,148,176,213,132,220,42,133,248,48,194,222,245,217,127,220,252,150,211,232,164,20,197,87,168,2,64,81,46,224,241,141,119,14,149,38,207,117,82,154,174,5,121,45,112,5,170, +255,128,175,113,0,187,65,124,10,114,171,212,180,173,139,138,214,86,25,157,148,162,248,50,85,0,40,202,37,42,221,124,147,37,76,38,230,72,41,70,129,41,15,228,4,33,184,22,117,245,208,91,58,4,236,209,144,219,65,236,19,130,253,234,215,189,162,92,58,85,0,40, +74,63,121,236,195,187,226,133,219,149,39,37,163,64,230,9,196,40,78,13,52,82,133,193,229,233,0,142,72,216,143,16,251,132,198,126,41,61,251,22,22,174,61,42,4,210,232,228,20,197,223,169,2,64,81,116,182,252,221,249,105,210,172,13,147,130,97,2,109,40,48,12, +196,48,96,40,16,107,112,122,70,107,3,42,65,86,2,21,66,158,250,227,10,213,42,254,107,242,186,58,163,147,83,148,64,166,10,0,69,49,80,233,250,111,197,132,133,57,50,53,204,131,5,50,67,8,145,137,100,16,200,1,72,6,34,72,230,212,14,130,217,232,92,47,145,7,104, +146,208,40,160,30,68,189,68,59,14,162,70,72,121,2,33,171,69,168,171,186,100,226,107,157,70,39,170,40,193,74,21,0,138,226,227,164,68,252,234,221,111,36,247,134,134,166,88,60,50,25,147,22,143,16,241,26,50,78,96,138,67,106,241,18,83,156,64,134,3,49,82,96, +21,146,8,32,18,8,229,212,46,131,233,140,37,195,248,250,85,71,59,167,14,210,157,166,1,237,64,47,208,45,5,61,66,226,4,58,36,194,142,144,173,2,209,38,209,218,144,166,86,19,90,27,154,169,85,154,60,141,102,151,214,244,179,105,47,55,169,109,122,69,241,109, +255,31,204,74,105,51,128,163,115,61,0,0,0,0,73,69,78,68,174,66,96,130,0,0 }; const char* JUCEAppIcon_png = (const char*) temp_binary_data_0; @@ -667,7 +692,7 @@ const char* getNamedResource (const char* resourceNameUTF8, int& numBytes) switch (hash) { - case 0xdb43fd77: numBytes = 45854; return JUCEAppIcon_png; + case 0xdb43fd77: numBytes = 47266; return JUCEAppIcon_png; default: break; } diff --git a/extras/AudioPluginHost/JuceLibraryCode/BinaryData.h b/extras/AudioPluginHost/JuceLibraryCode/BinaryData.h index 10d01a63..cf2d32ac 100644 --- a/extras/AudioPluginHost/JuceLibraryCode/BinaryData.h +++ b/extras/AudioPluginHost/JuceLibraryCode/BinaryData.h @@ -9,7 +9,7 @@ namespace BinaryData { extern const char* JUCEAppIcon_png; - const int JUCEAppIcon_pngSize = 45854; + const int JUCEAppIcon_pngSize = 47266; // Number of elements in the namedResourceList and originalFileNames arrays. const int namedResourceListSize = 1; diff --git a/extras/AudioPluginHost/JuceLibraryCode/JuceHeader.h b/extras/AudioPluginHost/JuceLibraryCode/JuceHeader.h index 5b63c7a0..ab68217a 100644 --- a/extras/AudioPluginHost/JuceLibraryCode/JuceHeader.h +++ b/extras/AudioPluginHost/JuceLibraryCode/JuceHeader.h @@ -12,7 +12,6 @@ #pragma once -#include "AppConfig.h" #include <juce_audio_basics/juce_audio_basics.h> #include <juce_audio_devices/juce_audio_devices.h> @@ -22,12 +21,12 @@ #include <juce_core/juce_core.h> #include <juce_cryptography/juce_cryptography.h> #include <juce_data_structures/juce_data_structures.h> +#include <juce_dsp/juce_dsp.h> #include <juce_events/juce_events.h> #include <juce_graphics/juce_graphics.h> #include <juce_gui_basics/juce_gui_basics.h> #include <juce_gui_extra/juce_gui_extra.h> #include <juce_opengl/juce_opengl.h> -#include <juce_video/juce_video.h> #include "BinaryData.h" @@ -50,7 +49,7 @@ namespace ProjectInfo { const char* const projectName = "AudioPluginHost"; - const char* const companyName = "ROLI Ltd."; + const char* const companyName = "Raw Material Software Limited"; const char* const versionString = "1.0.0"; const int versionNumber = 0x10000; } diff --git a/extras/AudioPluginHost/JuceLibraryCode/include_juce_audio_basics.cpp b/extras/AudioPluginHost/JuceLibraryCode/include_juce_audio_basics.cpp index 41869487..e5c3ae92 100644 --- a/extras/AudioPluginHost/JuceLibraryCode/include_juce_audio_basics.cpp +++ b/extras/AudioPluginHost/JuceLibraryCode/include_juce_audio_basics.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_basics/juce_audio_basics.cpp> diff --git a/extras/AudioPluginHost/JuceLibraryCode/include_juce_audio_basics.mm b/extras/AudioPluginHost/JuceLibraryCode/include_juce_audio_basics.mm index e0e6c577..c7f36c64 100644 --- a/extras/AudioPluginHost/JuceLibraryCode/include_juce_audio_basics.mm +++ b/extras/AudioPluginHost/JuceLibraryCode/include_juce_audio_basics.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_basics/juce_audio_basics.mm> diff --git a/extras/AudioPluginHost/JuceLibraryCode/include_juce_audio_devices.cpp b/extras/AudioPluginHost/JuceLibraryCode/include_juce_audio_devices.cpp index fb5c2219..29b774fd 100644 --- a/extras/AudioPluginHost/JuceLibraryCode/include_juce_audio_devices.cpp +++ b/extras/AudioPluginHost/JuceLibraryCode/include_juce_audio_devices.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_devices/juce_audio_devices.cpp> diff --git a/extras/AudioPluginHost/JuceLibraryCode/include_juce_audio_devices.mm b/extras/AudioPluginHost/JuceLibraryCode/include_juce_audio_devices.mm index e58b67ea..287da26e 100644 --- a/extras/AudioPluginHost/JuceLibraryCode/include_juce_audio_devices.mm +++ b/extras/AudioPluginHost/JuceLibraryCode/include_juce_audio_devices.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_devices/juce_audio_devices.mm> diff --git a/extras/AudioPluginHost/JuceLibraryCode/include_juce_audio_formats.cpp b/extras/AudioPluginHost/JuceLibraryCode/include_juce_audio_formats.cpp index a3c61170..8dac3325 100644 --- a/extras/AudioPluginHost/JuceLibraryCode/include_juce_audio_formats.cpp +++ b/extras/AudioPluginHost/JuceLibraryCode/include_juce_audio_formats.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_formats/juce_audio_formats.cpp> diff --git a/extras/AudioPluginHost/JuceLibraryCode/include_juce_audio_formats.mm b/extras/AudioPluginHost/JuceLibraryCode/include_juce_audio_formats.mm index f325b8fb..79e6a22f 100644 --- a/extras/AudioPluginHost/JuceLibraryCode/include_juce_audio_formats.mm +++ b/extras/AudioPluginHost/JuceLibraryCode/include_juce_audio_formats.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_formats/juce_audio_formats.mm> diff --git a/extras/AudioPluginHost/JuceLibraryCode/include_juce_audio_processors.cpp b/extras/AudioPluginHost/JuceLibraryCode/include_juce_audio_processors.cpp index bfe172ed..217d330a 100644 --- a/extras/AudioPluginHost/JuceLibraryCode/include_juce_audio_processors.cpp +++ b/extras/AudioPluginHost/JuceLibraryCode/include_juce_audio_processors.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_processors/juce_audio_processors.cpp> diff --git a/extras/AudioPluginHost/JuceLibraryCode/include_juce_audio_processors.mm b/extras/AudioPluginHost/JuceLibraryCode/include_juce_audio_processors.mm index b80ae901..1f7cc419 100644 --- a/extras/AudioPluginHost/JuceLibraryCode/include_juce_audio_processors.mm +++ b/extras/AudioPluginHost/JuceLibraryCode/include_juce_audio_processors.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_processors/juce_audio_processors.mm> diff --git a/extras/AudioPluginHost/JuceLibraryCode/include_juce_audio_utils.cpp b/extras/AudioPluginHost/JuceLibraryCode/include_juce_audio_utils.cpp index 97bd2c56..046bf31d 100644 --- a/extras/AudioPluginHost/JuceLibraryCode/include_juce_audio_utils.cpp +++ b/extras/AudioPluginHost/JuceLibraryCode/include_juce_audio_utils.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_utils/juce_audio_utils.cpp> diff --git a/extras/AudioPluginHost/JuceLibraryCode/include_juce_audio_utils.mm b/extras/AudioPluginHost/JuceLibraryCode/include_juce_audio_utils.mm index 8eae7c6e..a3f746dc 100644 --- a/extras/AudioPluginHost/JuceLibraryCode/include_juce_audio_utils.mm +++ b/extras/AudioPluginHost/JuceLibraryCode/include_juce_audio_utils.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_utils/juce_audio_utils.mm> diff --git a/extras/AudioPluginHost/JuceLibraryCode/include_juce_core.cpp b/extras/AudioPluginHost/JuceLibraryCode/include_juce_core.cpp index d0ce1636..84fe988c 100644 --- a/extras/AudioPluginHost/JuceLibraryCode/include_juce_core.cpp +++ b/extras/AudioPluginHost/JuceLibraryCode/include_juce_core.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_core/juce_core.cpp> diff --git a/extras/AudioPluginHost/JuceLibraryCode/include_juce_core.mm b/extras/AudioPluginHost/JuceLibraryCode/include_juce_core.mm index 72b10bf8..9ee67bf6 100644 --- a/extras/AudioPluginHost/JuceLibraryCode/include_juce_core.mm +++ b/extras/AudioPluginHost/JuceLibraryCode/include_juce_core.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_core/juce_core.mm> diff --git a/extras/AudioPluginHost/JuceLibraryCode/include_juce_cryptography.cpp b/extras/AudioPluginHost/JuceLibraryCode/include_juce_cryptography.cpp index 10b3401d..ee7d9085 100644 --- a/extras/AudioPluginHost/JuceLibraryCode/include_juce_cryptography.cpp +++ b/extras/AudioPluginHost/JuceLibraryCode/include_juce_cryptography.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_cryptography/juce_cryptography.cpp> diff --git a/extras/AudioPluginHost/JuceLibraryCode/include_juce_cryptography.mm b/extras/AudioPluginHost/JuceLibraryCode/include_juce_cryptography.mm index 9311ea0f..03ee05f4 100644 --- a/extras/AudioPluginHost/JuceLibraryCode/include_juce_cryptography.mm +++ b/extras/AudioPluginHost/JuceLibraryCode/include_juce_cryptography.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_cryptography/juce_cryptography.mm> diff --git a/extras/AudioPluginHost/JuceLibraryCode/include_juce_data_structures.cpp b/extras/AudioPluginHost/JuceLibraryCode/include_juce_data_structures.cpp index 9315aa16..152980ae 100644 --- a/extras/AudioPluginHost/JuceLibraryCode/include_juce_data_structures.cpp +++ b/extras/AudioPluginHost/JuceLibraryCode/include_juce_data_structures.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_data_structures/juce_data_structures.cpp> diff --git a/extras/AudioPluginHost/JuceLibraryCode/include_juce_data_structures.mm b/extras/AudioPluginHost/JuceLibraryCode/include_juce_data_structures.mm index 695ec439..02b9711c 100644 --- a/extras/AudioPluginHost/JuceLibraryCode/include_juce_data_structures.mm +++ b/extras/AudioPluginHost/JuceLibraryCode/include_juce_data_structures.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_data_structures/juce_data_structures.mm> diff --git a/extras/AudioPluginHost/JuceLibraryCode/include_juce_video.mm b/extras/AudioPluginHost/JuceLibraryCode/include_juce_dsp.cpp similarity index 68% rename from extras/AudioPluginHost/JuceLibraryCode/include_juce_video.mm rename to extras/AudioPluginHost/JuceLibraryCode/include_juce_dsp.cpp index 3da705bc..0f0af659 100644 --- a/extras/AudioPluginHost/JuceLibraryCode/include_juce_video.mm +++ b/extras/AudioPluginHost/JuceLibraryCode/include_juce_dsp.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" -#include <juce_video/juce_video.mm> +#include <juce_dsp/juce_dsp.cpp> diff --git a/extras/AudioPluginHost/JuceLibraryCode/include_juce_video.cpp b/extras/AudioPluginHost/JuceLibraryCode/include_juce_dsp.mm similarity index 68% rename from extras/AudioPluginHost/JuceLibraryCode/include_juce_video.cpp rename to extras/AudioPluginHost/JuceLibraryCode/include_juce_dsp.mm index bdf22ee1..a5cb956c 100644 --- a/extras/AudioPluginHost/JuceLibraryCode/include_juce_video.cpp +++ b/extras/AudioPluginHost/JuceLibraryCode/include_juce_dsp.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" -#include <juce_video/juce_video.cpp> +#include <juce_dsp/juce_dsp.mm> diff --git a/extras/AudioPluginHost/JuceLibraryCode/include_juce_events.cpp b/extras/AudioPluginHost/JuceLibraryCode/include_juce_events.cpp index 1bba110a..39268e2b 100644 --- a/extras/AudioPluginHost/JuceLibraryCode/include_juce_events.cpp +++ b/extras/AudioPluginHost/JuceLibraryCode/include_juce_events.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_events/juce_events.cpp> diff --git a/extras/AudioPluginHost/JuceLibraryCode/include_juce_events.mm b/extras/AudioPluginHost/JuceLibraryCode/include_juce_events.mm index 4cc34fc4..191a9987 100644 --- a/extras/AudioPluginHost/JuceLibraryCode/include_juce_events.mm +++ b/extras/AudioPluginHost/JuceLibraryCode/include_juce_events.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_events/juce_events.mm> diff --git a/extras/AudioPluginHost/JuceLibraryCode/include_juce_graphics.cpp b/extras/AudioPluginHost/JuceLibraryCode/include_juce_graphics.cpp index 319c76de..8ccabef9 100644 --- a/extras/AudioPluginHost/JuceLibraryCode/include_juce_graphics.cpp +++ b/extras/AudioPluginHost/JuceLibraryCode/include_juce_graphics.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_graphics/juce_graphics.cpp> diff --git a/extras/AudioPluginHost/JuceLibraryCode/include_juce_graphics.mm b/extras/AudioPluginHost/JuceLibraryCode/include_juce_graphics.mm index b28e6dd0..6bb7456d 100644 --- a/extras/AudioPluginHost/JuceLibraryCode/include_juce_graphics.mm +++ b/extras/AudioPluginHost/JuceLibraryCode/include_juce_graphics.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_graphics/juce_graphics.mm> diff --git a/extras/AudioPluginHost/JuceLibraryCode/include_juce_gui_basics.cpp b/extras/AudioPluginHost/JuceLibraryCode/include_juce_gui_basics.cpp index 216c76bb..71d04b24 100644 --- a/extras/AudioPluginHost/JuceLibraryCode/include_juce_gui_basics.cpp +++ b/extras/AudioPluginHost/JuceLibraryCode/include_juce_gui_basics.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_gui_basics/juce_gui_basics.cpp> diff --git a/extras/AudioPluginHost/JuceLibraryCode/include_juce_gui_basics.mm b/extras/AudioPluginHost/JuceLibraryCode/include_juce_gui_basics.mm index 6a9726fa..e449e0b7 100644 --- a/extras/AudioPluginHost/JuceLibraryCode/include_juce_gui_basics.mm +++ b/extras/AudioPluginHost/JuceLibraryCode/include_juce_gui_basics.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_gui_basics/juce_gui_basics.mm> diff --git a/extras/AudioPluginHost/JuceLibraryCode/include_juce_gui_extra.cpp b/extras/AudioPluginHost/JuceLibraryCode/include_juce_gui_extra.cpp index 7226e198..a33ece00 100644 --- a/extras/AudioPluginHost/JuceLibraryCode/include_juce_gui_extra.cpp +++ b/extras/AudioPluginHost/JuceLibraryCode/include_juce_gui_extra.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_gui_extra/juce_gui_extra.cpp> diff --git a/extras/AudioPluginHost/JuceLibraryCode/include_juce_gui_extra.mm b/extras/AudioPluginHost/JuceLibraryCode/include_juce_gui_extra.mm index c9b6c3bf..6dacee3a 100644 --- a/extras/AudioPluginHost/JuceLibraryCode/include_juce_gui_extra.mm +++ b/extras/AudioPluginHost/JuceLibraryCode/include_juce_gui_extra.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_gui_extra/juce_gui_extra.mm> diff --git a/extras/AudioPluginHost/JuceLibraryCode/include_juce_opengl.cpp b/extras/AudioPluginHost/JuceLibraryCode/include_juce_opengl.cpp index d9895bce..e6541a42 100644 --- a/extras/AudioPluginHost/JuceLibraryCode/include_juce_opengl.cpp +++ b/extras/AudioPluginHost/JuceLibraryCode/include_juce_opengl.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_opengl/juce_opengl.cpp> diff --git a/extras/AudioPluginHost/JuceLibraryCode/include_juce_opengl.mm b/extras/AudioPluginHost/JuceLibraryCode/include_juce_opengl.mm index 6c2c32d0..793619ea 100644 --- a/extras/AudioPluginHost/JuceLibraryCode/include_juce_opengl.mm +++ b/extras/AudioPluginHost/JuceLibraryCode/include_juce_opengl.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_opengl/juce_opengl.mm> diff --git a/extras/AudioPluginHost/Source/HostStartup.cpp b/extras/AudioPluginHost/Source/HostStartup.cpp index cce530eb..2aca5df3 100644 --- a/extras/AudioPluginHost/Source/HostStartup.cpp +++ b/extras/AudioPluginHost/Source/HostStartup.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -150,7 +149,11 @@ static PluginHostApp& getApp() { return *dynamic_cast<PluginH ApplicationProperties& getAppProperties() { return *getApp().appProperties; } ApplicationCommandManager& getCommandManager() { return getApp().commandManager; } -bool isOnTouchDevice() { return Desktop::getInstance().getMainMouseSource().isTouch(); } +bool isOnTouchDevice() +{ + static bool isTouch = Desktop::getInstance().getMainMouseSource().isTouch(); + return isTouch; +} // This kicks the whole thing off.. START_JUCE_APPLICATION (PluginHostApp) diff --git a/extras/AudioPluginHost/Source/JUCEAppIcon.png b/extras/AudioPluginHost/Source/JUCEAppIcon.png index 2564a24f7846d841e57b35b191bd8fa82ce648aa..19be2f283076ae4e301aaf4123b17bc8f61fe495 100644 GIT binary patch literal 47266 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 literal 45854 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 A=Kufz diff --git a/extras/AudioPluginHost/Source/Plugins/IOConfigurationWindow.cpp b/extras/AudioPluginHost/Source/Plugins/IOConfigurationWindow.cpp index 03b34541..f0cfe339 100644 --- a/extras/AudioPluginHost/Source/Plugins/IOConfigurationWindow.cpp +++ b/extras/AudioPluginHost/Source/Plugins/IOConfigurationWindow.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/AudioPluginHost/Source/Plugins/IOConfigurationWindow.h b/extras/AudioPluginHost/Source/Plugins/IOConfigurationWindow.h index ec7123ed..d638f1f0 100644 --- a/extras/AudioPluginHost/Source/Plugins/IOConfigurationWindow.h +++ b/extras/AudioPluginHost/Source/Plugins/IOConfigurationWindow.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/AudioPluginHost/Source/Plugins/InternalPlugins.cpp b/extras/AudioPluginHost/Source/Plugins/InternalPlugins.cpp index eb10b98b..59f23168 100644 --- a/extras/AudioPluginHost/Source/Plugins/InternalPlugins.cpp +++ b/extras/AudioPluginHost/Source/Plugins/InternalPlugins.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -25,110 +24,133 @@ */ #include <JuceHeader.h> + +#include <juce_audio_plugin_client/juce_audio_plugin_client.h> + #include "InternalPlugins.h" #include "PluginGraph.h" +#include "../../../../examples/Plugins/AUv3SynthPluginDemo.h" +#include "../../../../examples/Plugins/ArpeggiatorPluginDemo.h" +#include "../../../../examples/Plugins/AudioPluginDemo.h" +#include "../../../../examples/Plugins/DSPModulePluginDemo.h" +#include "../../../../examples/Plugins/GainPluginDemo.h" +#include "../../../../examples/Plugins/MidiLoggerPluginDemo.h" +#include "../../../../examples/Plugins/MultiOutSynthPluginDemo.h" +#include "../../../../examples/Plugins/NoiseGatePluginDemo.h" +#include "../../../../examples/Plugins/SamplerPluginDemo.h" +#include "../../../../examples/Plugins/SurroundPluginDemo.h" + //============================================================================== class InternalPlugin : public AudioPluginInstance { -protected: - InternalPlugin (const PluginDescription& descr, - const AudioChannelSet& channelSetToUse = AudioChannelSet::stereo()) - : AudioPluginInstance (getBusProperties (descr.numInputChannels == 0, channelSetToUse)), - name (descr.fileOrIdentifier.upToFirstOccurrenceOf (":", false, false)), - state (descr.fileOrIdentifier.fromFirstOccurrenceOf (":", false, false)), - isGenerator (descr.numInputChannels == 0), - hasMidi (descr.isInstrument), - channelSet (channelSetToUse) - { - jassert (channelSetToUse.size() == descr.numOutputChannels); - } - public: - //============================================================================== - const String getName() const override { return name; } - double getTailLengthSeconds() const override { return 0.0; } - bool acceptsMidi() const override { return hasMidi; } - bool producesMidi() const override { return hasMidi; } - AudioProcessorEditor* createEditor() override { return nullptr; } - bool hasEditor() const override { return false; } - int getNumPrograms() override { return 0; } - int getCurrentProgram() override { return 0; } - void setCurrentProgram (int) override {} - const String getProgramName (int) override { return {}; } - void changeProgramName (int, const String&) override {} - void getStateInformation (juce::MemoryBlock&) override {} - void setStateInformation (const void*, int) override {} - - //============================================================================== - bool isBusesLayoutSupported (const BusesLayout& layout) const override + explicit InternalPlugin (std::unique_ptr<AudioProcessor> innerIn) + : inner (std::move (innerIn)) { - if (! isGenerator) - if (layout.getMainOutputChannelSet() != channelSet) - return false; + jassert (inner != nullptr); - if (layout.getMainInputChannelSet() != channelSet) - return false; + for (auto isInput : { true, false }) + matchChannels (isInput); - return true; + setBusesLayout (inner->getBusesLayout()); } + //============================================================================== + const String getName() const override { return inner->getName(); } + StringArray getAlternateDisplayNames() const override { return inner->getAlternateDisplayNames(); } + double getTailLengthSeconds() const override { return inner->getTailLengthSeconds(); } + bool acceptsMidi() const override { return inner->acceptsMidi(); } + bool producesMidi() const override { return inner->producesMidi(); } + AudioProcessorEditor* createEditor() override { return inner->createEditor(); } + bool hasEditor() const override { return inner->hasEditor(); } + int getNumPrograms() override { return inner->getNumPrograms(); } + int getCurrentProgram() override { return inner->getCurrentProgram(); } + void setCurrentProgram (int i) override { inner->setCurrentProgram (i); } + const String getProgramName (int i) override { return inner->getProgramName (i); } + void changeProgramName (int i, const String& n) override { inner->changeProgramName (i, n); } + void getStateInformation (juce::MemoryBlock& b) override { inner->getStateInformation (b); } + void setStateInformation (const void* d, int s) override { inner->setStateInformation (d, s); } + void getCurrentProgramStateInformation (juce::MemoryBlock& b) override { inner->getCurrentProgramStateInformation (b); } + void setCurrentProgramStateInformation (const void* d, int s) override { inner->setCurrentProgramStateInformation (d, s); } + void prepareToPlay (double sr, int bs) override { inner->setRateAndBufferSizeDetails (sr, bs); inner->prepareToPlay (sr, bs); } + void releaseResources() override { inner->releaseResources(); } + void memoryWarningReceived() override { inner->memoryWarningReceived(); } + void processBlock (AudioBuffer<float>& a, MidiBuffer& m) override { inner->processBlock (a, m); } + void processBlock (AudioBuffer<double>& a, MidiBuffer& m) override { inner->processBlock (a, m); } + void processBlockBypassed (AudioBuffer<float>& a, MidiBuffer& m) override { inner->processBlockBypassed (a, m); } + void processBlockBypassed (AudioBuffer<double>& a, MidiBuffer& m) override { inner->processBlockBypassed (a, m); } + bool supportsDoublePrecisionProcessing() const override { return inner->supportsDoublePrecisionProcessing(); } + bool supportsMPE() const override { return inner->supportsMPE(); } + bool isMidiEffect() const override { return inner->isMidiEffect(); } + void reset() override { inner->reset(); } + void setNonRealtime (bool b) noexcept override { inner->setNonRealtime (b); } + void refreshParameterList() override { inner->refreshParameterList(); } + void numChannelsChanged() override { inner->numChannelsChanged(); } + void numBusesChanged() override { inner->numBusesChanged(); } + void processorLayoutsChanged() override { inner->processorLayoutsChanged(); } + void setPlayHead (AudioPlayHead* p) override { inner->setPlayHead (p); } + void updateTrackProperties (const TrackProperties& p) override { inner->updateTrackProperties (p); } + bool isBusesLayoutSupported (const BusesLayout& layout) const override { return inner->checkBusesLayoutSupported (layout); } + + bool canAddBus (bool) const override { return true; } + bool canRemoveBus (bool) const override { return true; } + //============================================================================== void fillInPluginDescription (PluginDescription& description) const override { - description = getPluginDescription (name + ":" + state, - isGenerator, - hasMidi, - channelSet); + description = getPluginDescription (*inner); } - static PluginDescription getPluginDescription (const String& identifier, - bool registerAsGenerator, - bool acceptsMidi, - const AudioChannelSet& channelSetToUse - = AudioChannelSet::stereo()) +private: + static PluginDescription getPluginDescription (const AudioProcessor& proc) { + const auto ins = proc.getTotalNumInputChannels(); + const auto outs = proc.getTotalNumOutputChannels(); + const auto identifier = proc.getName(); + const auto registerAsGenerator = ins == 0; + const auto acceptsMidi = proc.acceptsMidi(); + PluginDescription descr; - auto pluginName = identifier.upToFirstOccurrenceOf (":", false, false); - auto pluginState = identifier.fromFirstOccurrenceOf (":", false, false); - descr.name = pluginName; - descr.descriptiveName = pluginName; - descr.pluginFormatName = "Internal"; + descr.name = identifier; + descr.descriptiveName = identifier; + descr.pluginFormatName = InternalPluginFormat::getIdentifier(); descr.category = (registerAsGenerator ? (acceptsMidi ? "Synth" : "Generator") : "Effect"); descr.manufacturerName = "JUCE"; descr.version = ProjectInfo::versionString; - descr.fileOrIdentifier = pluginName + ":" + pluginState; - descr.uid = pluginName.hashCode(); + descr.fileOrIdentifier = identifier; + descr.uid = identifier.hashCode(); descr.isInstrument = (acceptsMidi && registerAsGenerator); - descr.numInputChannels = (registerAsGenerator ? 0 : channelSetToUse.size()); - descr.numOutputChannels = channelSetToUse.size(); + descr.numInputChannels = ins; + descr.numOutputChannels = outs; return descr; } -private: - static BusesProperties getBusProperties (bool registerAsGenerator, - const AudioChannelSet& channelSetToUse) + + void matchChannels (bool isInput) { - return registerAsGenerator ? BusesProperties().withOutput ("Output", channelSetToUse) - : BusesProperties().withInput ("Input", channelSetToUse) - .withOutput ("Output", channelSetToUse); + const auto inBuses = inner->getBusCount (isInput); + + while (getBusCount (isInput) < inBuses) + addBus (isInput); + + while (inBuses < getBusCount (isInput)) + removeBus (isInput); } - //============================================================================== - String name, state; - bool isGenerator, hasMidi; - AudioChannelSet channelSet; + std::unique_ptr<AudioProcessor> inner; //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (InternalPlugin) }; //============================================================================== -class SineWaveSynth : public InternalPlugin +class SineWaveSynth : public AudioProcessor { public: - SineWaveSynth (const PluginDescription& descr) : InternalPlugin (descr) + SineWaveSynth() + : AudioProcessor (BusesProperties().withOutput ("Output", AudioChannelSet::stereo())) { const int numVoices = 8; @@ -145,11 +167,6 @@ public: return "Sine Wave Synth"; } - static PluginDescription getPluginDescription() - { - return InternalPlugin::getPluginDescription (getIdentifier(), true, true); - } - //============================================================================== void prepareToPlay (double newSampleRate, int) override { @@ -168,7 +185,21 @@ public: buffer.applyGain (0.8f); } - using InternalPlugin::processBlock; + using AudioProcessor::processBlock; + + const String getName() const override { return getIdentifier(); } + double getTailLengthSeconds() const override { return 0.0; } + bool acceptsMidi() const override { return true; } + bool producesMidi() const override { return true; } + AudioProcessorEditor* createEditor() override { return nullptr; } + bool hasEditor() const override { return false; } + int getNumPrograms() override { return 1; } + int getCurrentProgram() override { return 0; } + void setCurrentProgram (int) override {} + const String getProgramName (int) override { return {}; } + void changeProgramName (int, const String&) override {} + void getStateInformation (juce::MemoryBlock&) override {} + void setStateInformation (const void*, int) override {} private: //============================================================================== @@ -291,10 +322,12 @@ private: }; //============================================================================== -class ReverbPlugin : public InternalPlugin +class ReverbPlugin : public AudioProcessor { public: - ReverbPlugin (const PluginDescription& descr) : InternalPlugin (descr) + ReverbPlugin() + : AudioProcessor (BusesProperties().withInput ("Input", AudioChannelSet::stereo()) + .withOutput ("Output", AudioChannelSet::stereo())) {} static String getIdentifier() @@ -302,11 +335,6 @@ public: return "Reverb"; } - static PluginDescription getPluginDescription() - { - return InternalPlugin::getPluginDescription (getIdentifier(), false, false); - } - void prepareToPlay (double newSampleRate, int) override { reverb.setSampleRate (newSampleRate); @@ -334,47 +362,82 @@ public: buffer.clear (ch, 0, buffer.getNumSamples()); } - using InternalPlugin::processBlock; + using AudioProcessor::processBlock; + + const String getName() const override { return getIdentifier(); } + double getTailLengthSeconds() const override { return 0.0; } + bool acceptsMidi() const override { return false; } + bool producesMidi() const override { return false; } + AudioProcessorEditor* createEditor() override { return nullptr; } + bool hasEditor() const override { return false; } + int getNumPrograms() override { return 1; } + int getCurrentProgram() override { return 0; } + void setCurrentProgram (int) override {} + const String getProgramName (int) override { return {}; } + void changeProgramName (int, const String&) override {} + void getStateInformation (juce::MemoryBlock&) override {} + void setStateInformation (const void*, int) override {} private: Reverb reverb; }; //============================================================================== -InternalPluginFormat::InternalPluginFormat() + +InternalPluginFormat::InternalPluginFactory::InternalPluginFactory (const std::initializer_list<Constructor>& constructorsIn) + : constructors (constructorsIn), + descriptions ([&] + { + std::vector<PluginDescription> result; + + for (const auto& constructor : constructors) + result.push_back (constructor()->getPluginDescription()); + + return result; + }()) +{} + +std::unique_ptr<AudioPluginInstance> InternalPluginFormat::InternalPluginFactory::createInstance (const String& name) const { - { - AudioProcessorGraph::AudioGraphIOProcessor p (AudioProcessorGraph::AudioGraphIOProcessor::audioOutputNode); - p.fillInPluginDescription (audioOutDesc); - } + const auto begin = descriptions.begin(); + const auto it = std::find_if (begin, + descriptions.end(), + [&] (const PluginDescription& desc) { return name == desc.name; }); - { - AudioProcessorGraph::AudioGraphIOProcessor p (AudioProcessorGraph::AudioGraphIOProcessor::audioInputNode); - p.fillInPluginDescription (audioInDesc); - } + if (it == descriptions.end()) + return nullptr; - { - AudioProcessorGraph::AudioGraphIOProcessor p (AudioProcessorGraph::AudioGraphIOProcessor::midiInputNode); - p.fillInPluginDescription (midiInDesc); - } + const auto index = (size_t) std::distance (begin, it); + return constructors[index](); +} - { - AudioProcessorGraph::AudioGraphIOProcessor p (AudioProcessorGraph::AudioGraphIOProcessor::midiOutputNode); - p.fillInPluginDescription (midiOutDesc); +InternalPluginFormat::InternalPluginFormat() + : factory { + [] { return std::make_unique<AudioProcessorGraph::AudioGraphIOProcessor> (AudioProcessorGraph::AudioGraphIOProcessor::audioInputNode); }, + [] { return std::make_unique<AudioProcessorGraph::AudioGraphIOProcessor> (AudioProcessorGraph::AudioGraphIOProcessor::midiInputNode); }, + [] { return std::make_unique<AudioProcessorGraph::AudioGraphIOProcessor> (AudioProcessorGraph::AudioGraphIOProcessor::audioOutputNode); }, + [] { return std::make_unique<AudioProcessorGraph::AudioGraphIOProcessor> (AudioProcessorGraph::AudioGraphIOProcessor::midiOutputNode); }, + + [] { return std::make_unique<InternalPlugin> (std::make_unique<SineWaveSynth>()); }, + [] { return std::make_unique<InternalPlugin> (std::make_unique<ReverbPlugin>()); }, + + [] { return std::make_unique<InternalPlugin> (std::make_unique<AUv3SynthProcessor>()); }, + [] { return std::make_unique<InternalPlugin> (std::make_unique<Arpeggiator>()); }, + [] { return std::make_unique<InternalPlugin> (std::make_unique<DspModulePluginDemoAudioProcessor>()); }, + [] { return std::make_unique<InternalPlugin> (std::make_unique<GainProcessor>()); }, + [] { return std::make_unique<InternalPlugin> (std::make_unique<JuceDemoPluginAudioProcessor>()); }, + [] { return std::make_unique<InternalPlugin> (std::make_unique<MidiLoggerPluginDemoProcessor>()); }, + [] { return std::make_unique<InternalPlugin> (std::make_unique<MultiOutSynth>()); }, + [] { return std::make_unique<InternalPlugin> (std::make_unique<NoiseGate>()); }, + [] { return std::make_unique<InternalPlugin> (std::make_unique<SamplerAudioProcessor>()); }, + [] { return std::make_unique<InternalPlugin> (std::make_unique<SurroundProcessor>()); } } +{ } std::unique_ptr<AudioPluginInstance> InternalPluginFormat::createInstance (const String& name) { - if (name == audioOutDesc.name) return std::make_unique<AudioProcessorGraph::AudioGraphIOProcessor> (AudioProcessorGraph::AudioGraphIOProcessor::audioOutputNode); - if (name == audioInDesc.name) return std::make_unique<AudioProcessorGraph::AudioGraphIOProcessor> (AudioProcessorGraph::AudioGraphIOProcessor::audioInputNode); - if (name == midiInDesc.name) return std::make_unique<AudioProcessorGraph::AudioGraphIOProcessor> (AudioProcessorGraph::AudioGraphIOProcessor::midiInputNode); - if (name == midiOutDesc.name) return std::make_unique<AudioProcessorGraph::AudioGraphIOProcessor> (AudioProcessorGraph::AudioGraphIOProcessor::midiOutputNode); - - if (name == SineWaveSynth::getIdentifier()) return std::make_unique<SineWaveSynth> (SineWaveSynth::getPluginDescription()); - if (name == ReverbPlugin::getIdentifier()) return std::make_unique<ReverbPlugin> (ReverbPlugin::getPluginDescription()); - - return {}; + return factory.createInstance (name); } void InternalPluginFormat::createPluginInstance (const PluginDescription& desc, @@ -392,8 +455,7 @@ bool InternalPluginFormat::requiresUnblockedMessageThreadDuringCreation (const P return false; } -void InternalPluginFormat::getAllTypes (Array<PluginDescription>& results) +const std::vector<PluginDescription>& InternalPluginFormat::getAllTypes() const { - results.add (audioInDesc, audioOutDesc, midiInDesc, midiOutDesc, - SineWaveSynth::getPluginDescription(), ReverbPlugin::getPluginDescription()); + return factory.getDescriptions(); } diff --git a/extras/AudioPluginHost/Source/Plugins/InternalPlugins.h b/extras/AudioPluginHost/Source/Plugins/InternalPlugins.h index b5282a09..54e189bb 100644 --- a/extras/AudioPluginHost/Source/Plugins/InternalPlugins.h +++ b/extras/AudioPluginHost/Source/Plugins/InternalPlugins.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -38,14 +37,13 @@ class InternalPluginFormat : public AudioPluginFormat public: //============================================================================== InternalPluginFormat(); - ~InternalPluginFormat() override {} //============================================================================== - PluginDescription audioInDesc, audioOutDesc, midiInDesc, midiOutDesc; - void getAllTypes (Array<PluginDescription>&); + const std::vector<PluginDescription>& getAllTypes() const; //============================================================================== - String getName() const override { return "Internal"; } + static String getIdentifier() { return "Internal"; } + String getName() const override { return getIdentifier(); } bool fileMightContainThisPluginType (const String&) override { return true; } FileSearchPath getDefaultLocationsToSearch() override { return {}; } bool canScanForPlugins() const override { return false; } @@ -57,6 +55,22 @@ public: StringArray searchPathsForPlugins (const FileSearchPath&, bool, bool) override { return {}; } private: + class InternalPluginFactory + { + public: + using Constructor = std::function<std::unique_ptr<AudioPluginInstance>()>; + + explicit InternalPluginFactory (const std::initializer_list<Constructor>& constructorsIn); + + const std::vector<PluginDescription>& getDescriptions() const { return descriptions; } + + std::unique_ptr<AudioPluginInstance> createInstance (const String& name) const; + + private: + const std::vector<Constructor> constructors; + const std::vector<PluginDescription> descriptions; + }; + //============================================================================== void createPluginInstance (const PluginDescription&, double initialSampleRate, int initialBufferSize, @@ -65,4 +79,6 @@ private: std::unique_ptr<AudioPluginInstance> createInstance (const String& name); bool requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const override; + + InternalPluginFactory factory; }; diff --git a/extras/AudioPluginHost/Source/Plugins/PluginGraph.cpp b/extras/AudioPluginHost/Source/Plugins/PluginGraph.cpp index 8d9b9261..ce45ba18 100644 --- a/extras/AudioPluginHost/Source/Plugins/PluginGraph.cpp +++ b/extras/AudioPluginHost/Source/Plugins/PluginGraph.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -152,7 +151,7 @@ PluginWindow* PluginGraph::getOrCreateWindowFor (AudioProcessorGraph::Node* node { auto description = plugin->getPluginDescription(); - if (description.pluginFormatName == "Internal") + if (! plugin->hasEditor() && description.pluginFormatName == "Internal") { getCommandManager().invokeDirectly (CommandIDs::showAudioSettings, false); return nullptr; @@ -199,10 +198,12 @@ void PluginGraph::newDocument() InternalPluginFormat internalFormat; - addPlugin (internalFormat.audioInDesc, { 0.5, 0.1 }); - addPlugin (internalFormat.midiInDesc, { 0.25, 0.1 }); - addPlugin (internalFormat.audioOutDesc, { 0.5, 0.9 }); - addPlugin (internalFormat.midiOutDesc, { 0.25, 0.9 }); + jassert (internalFormat.getAllTypes().size() > 3); + + addPlugin (internalFormat.getAllTypes()[0], { 0.5, 0.1 }); + addPlugin (internalFormat.getAllTypes()[1], { 0.25, 0.1 }); + addPlugin (internalFormat.getAllTypes()[2], { 0.5, 0.9 }); + addPlugin (internalFormat.getAllTypes()[3], { 0.25, 0.9 }); MessageManager::callAsync ([this] { diff --git a/extras/AudioPluginHost/Source/Plugins/PluginGraph.h b/extras/AudioPluginHost/Source/Plugins/PluginGraph.h index 75764752..59217f0e 100644 --- a/extras/AudioPluginHost/Source/Plugins/PluginGraph.h +++ b/extras/AudioPluginHost/Source/Plugins/PluginGraph.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/AudioPluginHost/Source/UI/GraphEditorPanel.cpp b/extras/AudioPluginHost/Source/UI/GraphEditorPanel.cpp index afa65bdb..9591c88a 100644 --- a/extras/AudioPluginHost/Source/UI/GraphEditorPanel.cpp +++ b/extras/AudioPluginHost/Source/UI/GraphEditorPanel.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -140,7 +139,7 @@ struct GraphEditorPanel::PinComponent : public Component, auto colour = (pin.isMIDI() ? Colours::red : Colours::green); - g.setColour (colour.withRotatedHue (busIdx / 5.0f)); + g.setColour (colour.withRotatedHue ((float) busIdx / 5.0f)); g.fillPath (p); } @@ -510,7 +509,8 @@ struct GraphEditorPanel::PluginComponent : public Component, struct GraphEditorPanel::ConnectorComponent : public Component, public SettableTooltipClient { - ConnectorComponent (GraphEditorPanel& p) : panel (p), graph (p.graph) + explicit ConnectorComponent (GraphEditorPanel& p) + : panel (p), graph (p.graph) { setAlwaysOnTop (true); } @@ -963,7 +963,7 @@ struct GraphDocumentComponent::TooltipBar : public Component, void paint (Graphics& g) override { - g.setFont (Font (getHeight() * 0.7f, Font::bold)); + g.setFont (Font ((float) getHeight() * 0.7f, Font::bold)); g.setColour (Colours::black); g.drawFittedText (tip, 10, 0, getWidth() - 12, getHeight(), Justification::centredLeft, 1); } @@ -994,7 +994,7 @@ class GraphDocumentComponent::TitleBarComponent : public Component, private Button::Listener { public: - TitleBarComponent (GraphDocumentComponent& graphDocumentComponent) + explicit TitleBarComponent (GraphDocumentComponent& graphDocumentComponent) : owner (graphDocumentComponent) { static const unsigned char burgerMenuPathData[] @@ -1189,11 +1189,8 @@ void GraphDocumentComponent::init() if (isOnTouchDevice()) { - if (isOnTouchDevice()) - { - titleBarComponent.reset (new TitleBarComponent (*this)); - addAndMakeVisible (titleBarComponent.get()); - } + titleBarComponent.reset (new TitleBarComponent (*this)); + addAndMakeVisible (titleBarComponent.get()); pluginListBoxModel.reset (new PluginListBoxModel (pluginListBox, pluginList)); @@ -1206,11 +1203,8 @@ void GraphDocumentComponent::init() 0, 2, 0, 2, true, true, true, false)); - if (isOnTouchDevice()) - { - addAndMakeVisible (pluginListSidePanel); - addAndMakeVisible (mobileSettingsSidePanel); - } + addAndMakeVisible (pluginListSidePanel); + addAndMakeVisible (mobileSettingsSidePanel); } } diff --git a/extras/AudioPluginHost/Source/UI/GraphEditorPanel.h b/extras/AudioPluginHost/Source/UI/GraphEditorPanel.h index f5a5a6cc..0cc2a508 100644 --- a/extras/AudioPluginHost/Source/UI/GraphEditorPanel.h +++ b/extras/AudioPluginHost/Source/UI/GraphEditorPanel.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/AudioPluginHost/Source/UI/MainHostWindow.cpp b/extras/AudioPluginHost/Source/UI/MainHostWindow.cpp index 104b8aae..dfd4927c 100644 --- a/extras/AudioPluginHost/Source/UI/MainHostWindow.cpp +++ b/extras/AudioPluginHost/Source/UI/MainHostWindow.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -106,7 +105,7 @@ MainHostWindow::MainHostWindow() setVisible (true); InternalPluginFormat internalFormat; - internalFormat.getAllTypes (internalTypes); + internalTypes = internalFormat.getAllTypes(); if (auto savedPluginList = getAppProperties().getUserSettings()->getXmlValue ("pluginList")) knownPluginList.recreateFromXml (*savedPluginList); @@ -371,20 +370,26 @@ void MainHostWindow::addPluginsToMenu (PopupMenu& m) int i = 0; for (auto& t : internalTypes) - m.addItem (++i, t.name + " (" + t.pluginFormatName + ")", - graphHolder->graph->getNodeForName (t.name) == nullptr); + m.addItem (++i, t.name + " (" + t.pluginFormatName + ")"); } m.addSeparator(); pluginDescriptions = knownPluginList.getTypes(); + + // This avoids showing the internal types again later on in the list + pluginDescriptions.removeIf ([] (PluginDescription& desc) + { + return desc.pluginFormatName == InternalPluginFormat::getIdentifier(); + }); + KnownPluginList::addToMenu (m, pluginDescriptions, pluginSortMethod); } PluginDescription MainHostWindow::getChosenType (const int menuID) const { - if (menuID >= 1 && menuID < 1 + internalTypes.size()) - return internalTypes [menuID - 1]; + if (menuID >= 1 && menuID < (int) (1 + internalTypes.size())) + return internalTypes[(size_t) (menuID - 1)]; return pluginDescriptions[KnownPluginList::getIndexChosenByMenu (pluginDescriptions, menuID)]; } diff --git a/extras/AudioPluginHost/Source/UI/MainHostWindow.h b/extras/AudioPluginHost/Source/UI/MainHostWindow.h index ded302bf..313a41bd 100644 --- a/extras/AudioPluginHost/Source/UI/MainHostWindow.h +++ b/extras/AudioPluginHost/Source/UI/MainHostWindow.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -99,7 +98,7 @@ private: AudioDeviceManager deviceManager; AudioPluginFormatManager formatManager; - Array<PluginDescription> internalTypes; + std::vector<PluginDescription> internalTypes; KnownPluginList knownPluginList; KnownPluginList::SortMethod pluginSortMethod; Array<PluginDescription> pluginDescriptions; diff --git a/extras/AudioPluginHost/Source/UI/PluginWindow.h b/extras/AudioPluginHost/Source/UI/PluginWindow.h index ac1af990..7cec3d81 100644 --- a/extras/AudioPluginHost/Source/UI/PluginWindow.h +++ b/extras/AudioPluginHost/Source/UI/PluginWindow.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -111,8 +110,8 @@ private: list.scrollToEnsureRowIsOnscreen (log.size() - 1); } - JUCE_CONSTEXPR static const int maxLogSize = 300; - JUCE_CONSTEXPR static const int logSizeTrimThreshold = 400; + constexpr static const int maxLogSize = 300; + constexpr static const int logSizeTrimThreshold = 400; ListBox list { "Log", this }; @@ -227,6 +226,7 @@ private: case Type::programs: return "Programs"; case Type::audioIO: return "IO"; case Type::debug: return "Debug"; + case Type::numTypes: default: return {}; } } diff --git a/extras/BLOCKS/standalone_sdk/examples/BlockFinder/BlockFinder.cpp b/extras/BLOCKS/standalone_sdk/examples/BlockFinder/BlockFinder.cpp index 7622facb..6f5519f1 100644 --- a/extras/BLOCKS/standalone_sdk/examples/BlockFinder/BlockFinder.cpp +++ b/extras/BLOCKS/standalone_sdk/examples/BlockFinder/BlockFinder.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 diff --git a/extras/BLOCKS/standalone_sdk/examples/BlockFinder/BlockFinder.h b/extras/BLOCKS/standalone_sdk/examples/BlockFinder/BlockFinder.h index 2366c7aa..12a82f1e 100644 --- a/extras/BLOCKS/standalone_sdk/examples/BlockFinder/BlockFinder.h +++ b/extras/BLOCKS/standalone_sdk/examples/BlockFinder/BlockFinder.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 diff --git a/extras/BLOCKS/standalone_sdk/examples/BlockFinder/Linux/main.cpp b/extras/BLOCKS/standalone_sdk/examples/BlockFinder/Linux/main.cpp index f05c77ca..12260389 100644 --- a/extras/BLOCKS/standalone_sdk/examples/BlockFinder/Linux/main.cpp +++ b/extras/BLOCKS/standalone_sdk/examples/BlockFinder/Linux/main.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 diff --git a/extras/BLOCKS/standalone_sdk/examples/BlockFinder/MacOS/main.mm b/extras/BLOCKS/standalone_sdk/examples/BlockFinder/MacOS/main.mm index ba02d820..31afa153 100644 --- a/extras/BLOCKS/standalone_sdk/examples/BlockFinder/MacOS/main.mm +++ b/extras/BLOCKS/standalone_sdk/examples/BlockFinder/MacOS/main.mm @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 diff --git a/extras/BLOCKS/standalone_sdk/examples/BlockFinder/Windows/main.cpp b/extras/BLOCKS/standalone_sdk/examples/BlockFinder/Windows/main.cpp index f05c77ca..12260389 100644 --- a/extras/BLOCKS/standalone_sdk/examples/BlockFinder/Windows/main.cpp +++ b/extras/BLOCKS/standalone_sdk/examples/BlockFinder/Windows/main.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 diff --git a/extras/BinaryBuilder/BinaryBuilder.jucer b/extras/BinaryBuilder/BinaryBuilder.jucer index 55c70b5f..58f894c3 100644 --- a/extras/BinaryBuilder/BinaryBuilder.jucer +++ b/extras/BinaryBuilder/BinaryBuilder.jucer @@ -1,9 +1,10 @@ <?xml version="1.0" encoding="UTF-8"?> <JUCERPROJECT id="3t6YqETY1" name="BinaryBuilder" projectType="consoleapp" - juceFolder="../../../juce" jucerVersion="5.4.7" bundleIdentifier="com.roli.binarybuilder" - displaySplashScreen="0" reportAppUsage="0" companyName="ROLI Ltd." - companyCopyright="ROLI Ltd."> + juceFolder="../../../juce" bundleIdentifier="com.juce.binarybuilder" + displaySplashScreen="0" reportAppUsage="0" companyName="Raw Material Software Limited" + companyCopyright="Raw Material Software Limited" useAppConfig="0" + addUsingNamespaceToJuceHeader="1" jucerFormatVersion="1"> <EXPORTFORMATS> <XCODE_MAC targetFolder="Builds/MacOSX" vstFolder="~/SDKs/vstsdk2.4" rtasFolder="~/SDKs/PT_80_SDK" objCExtraSuffix="OeJtJb"> @@ -17,9 +18,8 @@ </XCODE_MAC> <LINUX_MAKE targetFolder="Builds/LinuxMakefile" vstFolder="~/SDKs/vstsdk2.4"> <CONFIGURATIONS> - <CONFIGURATION name="Debug" isDebug="1" targetName="BinaryBuilder" libraryPath="/usr/X11R6/lib/"/> - <CONFIGURATION name="Release" isDebug="0" optimisation="2" targetName="BinaryBuilder" - libraryPath="/usr/X11R6/lib/"/> + <CONFIGURATION name="Debug" isDebug="1" targetName="BinaryBuilder"/> + <CONFIGURATION name="Release" isDebug="0" optimisation="2" targetName="BinaryBuilder"/> </CONFIGURATIONS> <MODULEPATHS> <MODULEPATH id="juce_core" path="../../modules"/> diff --git a/extras/BinaryBuilder/Builds/LinuxMakefile/Makefile b/extras/BinaryBuilder/Builds/LinuxMakefile/Makefile index 4ade9f34..56637be0 100644 --- a/extras/BinaryBuilder/Builds/LinuxMakefile/Makefile +++ b/extras/BinaryBuilder/Builds/LinuxMakefile/Makefile @@ -35,13 +35,13 @@ ifeq ($(CONFIG),Debug) TARGET_ARCH := endif - JUCE_CPPFLAGS := $(DEPFLAGS) -DLINUX=1 -DDEBUG=1 -D_DEBUG=1 -DJUCER_LINUX_MAKE_6D53C8B4=1 -DJUCE_APP_VERSION=1.0.0 -DJUCE_APP_VERSION_HEX=0x10000 $(shell pkg-config --cflags libcurl) -pthread -I../../JuceLibraryCode -I../../../../modules $(CPPFLAGS) - JUCE_CPPFLAGS_CONSOLEAPP := -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_CPPFLAGS := $(DEPFLAGS) "-DLINUX=1" "-DDEBUG=1" "-D_DEBUG=1" "-DJUCE_DISPLAY_SPLASH_SCREEN=0" "-DJUCE_USE_DARK_SPLASH_SCREEN=1" "-DJUCE_PROJUCER_VERSION=0x60005" "-DJUCE_MODULE_AVAILABLE_juce_core=1" "-DJUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1" "-DJUCE_STANDALONE_APPLICATION=1" "-DJUCER_LINUX_MAKE_6D53C8B4=1" "-DJUCE_APP_VERSION=1.0.0" "-DJUCE_APP_VERSION_HEX=0x10000" $(shell pkg-config --cflags libcurl) -pthread -I../../JuceLibraryCode -I../../../../modules $(CPPFLAGS) + JUCE_CPPFLAGS_CONSOLEAPP := "-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_CONSOLEAPP := BinaryBuilder JUCE_CFLAGS += $(JUCE_CPPFLAGS) $(TARGET_ARCH) -g -ggdb -O0 $(CFLAGS) JUCE_CXXFLAGS += $(JUCE_CFLAGS) -std=c++14 $(CXXFLAGS) - JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) -L/usr/X11R6/lib/ $(shell pkg-config --libs libcurl) -lrt -ldl -lpthread $(LDFLAGS) + JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) $(shell pkg-config --libs libcurl) -fvisibility=hidden -lrt -ldl -lpthread $(LDFLAGS) CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(TARGET) $(JUCE_OBJDIR) endif @@ -56,13 +56,13 @@ ifeq ($(CONFIG),Release) TARGET_ARCH := endif - JUCE_CPPFLAGS := $(DEPFLAGS) -DLINUX=1 -DNDEBUG=1 -DJUCER_LINUX_MAKE_6D53C8B4=1 -DJUCE_APP_VERSION=1.0.0 -DJUCE_APP_VERSION_HEX=0x10000 $(shell pkg-config --cflags libcurl) -pthread -I../../JuceLibraryCode -I../../../../modules $(CPPFLAGS) - JUCE_CPPFLAGS_CONSOLEAPP := -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_CPPFLAGS := $(DEPFLAGS) "-DLINUX=1" "-DNDEBUG=1" "-DJUCE_DISPLAY_SPLASH_SCREEN=0" "-DJUCE_USE_DARK_SPLASH_SCREEN=1" "-DJUCE_PROJUCER_VERSION=0x60005" "-DJUCE_MODULE_AVAILABLE_juce_core=1" "-DJUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1" "-DJUCE_STANDALONE_APPLICATION=1" "-DJUCER_LINUX_MAKE_6D53C8B4=1" "-DJUCE_APP_VERSION=1.0.0" "-DJUCE_APP_VERSION_HEX=0x10000" $(shell pkg-config --cflags libcurl) -pthread -I../../JuceLibraryCode -I../../../../modules $(CPPFLAGS) + JUCE_CPPFLAGS_CONSOLEAPP := "-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_CONSOLEAPP := BinaryBuilder JUCE_CFLAGS += $(JUCE_CPPFLAGS) $(TARGET_ARCH) -Os $(CFLAGS) JUCE_CXXFLAGS += $(JUCE_CFLAGS) -std=c++14 $(CXXFLAGS) - JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) -L/usr/X11R6/lib/ $(shell pkg-config --libs libcurl) -fvisibility=hidden -lrt -ldl -lpthread $(LDFLAGS) + JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) $(shell pkg-config --libs libcurl) -fvisibility=hidden -lrt -ldl -lpthread $(LDFLAGS) CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(TARGET) $(JUCE_OBJDIR) endif diff --git a/extras/BinaryBuilder/Builds/MacOSX/BinaryBuilder.xcodeproj/project.pbxproj b/extras/BinaryBuilder/Builds/MacOSX/BinaryBuilder.xcodeproj/project.pbxproj index 557784d5..9b235ee9 100644 --- a/extras/BinaryBuilder/Builds/MacOSX/BinaryBuilder.xcodeproj/project.pbxproj +++ b/extras/BinaryBuilder/Builds/MacOSX/BinaryBuilder.xcodeproj/project.pbxproj @@ -13,6 +13,10 @@ isa = PBXBuildFile; fileRef = 57DDB771ED96A256F190ADF8; }; + C17566E1AACD033B3DD74E9F = { + isa = PBXBuildFile; + fileRef = 6AA23C81496E022290EB2A0C; + }; 0D53D8B0AEE37C02C147344B = { isa = PBXBuildFile; fileRef = F769CD634476C91F4C9D0596; @@ -50,6 +54,13 @@ path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; + 6AA23C81496E022290EB2A0C = { + isa = PBXFileReference; + lastKnownFileType = wrapper.framework; + name = Foundation.framework; + path = System/Library/Frameworks/Foundation.framework; + sourceTree = SDKROOT; + }; 799073185F72F5FAD05253C3 = { isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; @@ -57,13 +68,6 @@ path = BinaryBuilder; sourceTree = "BUILT_PRODUCTS_DIR"; }; - 7E86227B01E504302C234A04 = { - isa = PBXFileReference; - lastKnownFileType = sourcecode.c.h; - name = AppConfig.h; - path = ../../JuceLibraryCode/AppConfig.h; - sourceTree = "SOURCE_ROOT"; - }; 8702176D2368B6F785546D2B = { isa = PBXFileReference; lastKnownFileType = file; @@ -119,7 +123,6 @@ 8905BD956C24F83087634C3A = { isa = PBXGroup; children = ( - 7E86227B01E504302C234A04, D186E2D509765FAE0758F17D, D6C3594C8BEC94040AF108FE, ); @@ -138,6 +141,7 @@ isa = PBXGroup; children = ( 57DDB771ED96A256F190ADF8, + 6AA23C81496E022290EB2A0C, F769CD634476C91F4C9D0596, ); name = Frameworks; @@ -179,6 +183,12 @@ GCC_PREPROCESSOR_DEFINITIONS = ( "_DEBUG=1", "DEBUG=1", + "JUCE_DISPLAY_SPLASH_SCREEN=0", + "JUCE_USE_DARK_SPLASH_SCREEN=1", + "JUCE_PROJUCER_VERSION=0x60005", + "JUCE_MODULE_AVAILABLE_juce_core=1", + "JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1", + "JUCE_STANDALONE_APPLICATION=1", "JUCER_XCODE_MAC_F6D2F4CF=1", "JUCE_APP_VERSION=1.0.0", "JUCE_APP_VERSION_HEX=0x10000", @@ -199,9 +209,14 @@ ); INSTALL_PATH = "/usr/bin"; MACOSX_DEPLOYMENT_TARGET = 10.11; - PRODUCT_BUNDLE_IDENTIFIER = com.roli.binarybuilder; + MTL_HEADER_SEARCH_PATHS = ( + "../../JuceLibraryCode", + "../../../../modules", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.juce.binarybuilder; PRODUCT_NAME = "BinaryBuilder"; USE_HEADERMAP = NO; + VALID_ARCHS = "i386 x86_64 arm64 arm64e"; }; name = Debug; }; @@ -220,6 +235,12 @@ GCC_PREPROCESSOR_DEFINITIONS = ( "_NDEBUG=1", "NDEBUG=1", + "JUCE_DISPLAY_SPLASH_SCREEN=0", + "JUCE_USE_DARK_SPLASH_SCREEN=1", + "JUCE_PROJUCER_VERSION=0x60005", + "JUCE_MODULE_AVAILABLE_juce_core=1", + "JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1", + "JUCE_STANDALONE_APPLICATION=1", "JUCER_XCODE_MAC_F6D2F4CF=1", "JUCE_APP_VERSION=1.0.0", "JUCE_APP_VERSION_HEX=0x10000", @@ -232,7 +253,6 @@ "JucePlugin_Build_Standalone=0", "JucePlugin_Build_Unity=0", ); - GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; HEADER_SEARCH_PATHS = ( "../../JuceLibraryCode", @@ -242,9 +262,14 @@ INSTALL_PATH = "/usr/bin"; LLVM_LTO = YES; MACOSX_DEPLOYMENT_TARGET = 10.11; - PRODUCT_BUNDLE_IDENTIFIER = com.roli.binarybuilder; + MTL_HEADER_SEARCH_PATHS = ( + "../../JuceLibraryCode", + "../../../../modules", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.juce.binarybuilder; PRODUCT_NAME = "BinaryBuilder"; USE_HEADERMAP = NO; + VALID_ARCHS = "i386 x86_64 arm64 arm64e"; }; name = Release; }; @@ -273,11 +298,12 @@ CODE_SIGN_IDENTITY = ""; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; + ENABLE_TESTABILITY = NO; GCC_C_LANGUAGE_STANDARD = c11; GCC_INLINES_ARE_PRIVATE_EXTERN = YES; GCC_MODEL_TUNING = G5; GCC_NO_COMMON_BLOCKS = YES; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; @@ -321,10 +347,12 @@ CODE_SIGN_IDENTITY = ""; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = NO; GCC_C_LANGUAGE_STANDARD = c11; GCC_INLINES_ARE_PRIVATE_EXTERN = YES; GCC_MODEL_TUNING = G5; GCC_NO_COMMON_BLOCKS = YES; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; @@ -342,10 +370,6 @@ }; name = Release; }; - 78C9910DF129FD687A56D083 = { - isa = PBXTargetDependency; - target = 80B70DE094998C267F152DD5; - }; E4C85B0464A93027D035AA1F = { isa = XCConfigurationList; buildConfigurations = ( @@ -386,6 +410,7 @@ buildActionMask = 2147483647; files = ( 4B72EFB0E9D74CA7227F6CAB, + C17566E1AACD033B3DD74E9F, 0D53D8B0AEE37C02C147344B, ); runOnlyForDeploymentPostprocessing = 0; @@ -408,7 +433,7 @@ 36B6F402BC83F21646259DEF = { isa = PBXProject; buildConfigurationList = E4C85B0464A93027D035AA1F; - attributes = { LastUpgradeCheck = 1100; ORGANIZATIONNAME = "ROLI Ltd."; }; + attributes = { LastUpgradeCheck = 1200; ORGANIZATIONNAME = "Raw Material Software Limited"; }; compatibilityVersion = "Xcode 3.2"; hasScannedForEncodings = 0; mainGroup = C18D022743CF5BD14D6A6A9E; diff --git a/extras/BinaryBuilder/Builds/MacOSX/BinaryBuilder.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/extras/BinaryBuilder/Builds/MacOSX/BinaryBuilder.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings index 949b6789..f2e3cbe8 100644 --- a/extras/BinaryBuilder/Builds/MacOSX/BinaryBuilder.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ b/extras/BinaryBuilder/Builds/MacOSX/BinaryBuilder.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -4,5 +4,7 @@ <dict> <key>BuildSystemType</key> <string>Original</string> + <key>DisableBuildSystemDeprecationWarning</key> + <true/> </dict> </plist> diff --git a/extras/BinaryBuilder/Builds/MacOSX/ConsoleApp.entitlements b/extras/BinaryBuilder/Builds/MacOSX/ConsoleApp.entitlements deleted file mode 100644 index 6631ffa6..00000000 --- a/extras/BinaryBuilder/Builds/MacOSX/ConsoleApp.entitlements +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> -</dict> -</plist> diff --git a/extras/BinaryBuilder/Builds/VisualStudio2019/BinaryBuilder_ConsoleApp.vcxproj b/extras/BinaryBuilder/Builds/VisualStudio2019/BinaryBuilder_ConsoleApp.vcxproj index 7e823639..71844699 100644 --- a/extras/BinaryBuilder/Builds/VisualStudio2019/BinaryBuilder_ConsoleApp.vcxproj +++ b/extras/BinaryBuilder/Builds/VisualStudio2019/BinaryBuilder_ConsoleApp.vcxproj @@ -64,10 +64,10 @@ <Optimization>Disabled</Optimization> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_CONSOLE;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=1.0.0;JUCE_APP_VERSION_HEX=0x10000;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_CONSOLE;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCE_DISPLAY_SPLASH_SCREEN=0;JUCE_USE_DARK_SPLASH_SCREEN=1;JUCE_PROJUCER_VERSION=0x60005;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_STANDALONE_APPLICATION=1;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=1.0.0;JUCE_APP_VERSION_HEX=0x10000;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> <RuntimeTypeInfo>true</RuntimeTypeInfo> - <PrecompiledHeader/> + <PrecompiledHeader>NotUsing</PrecompiledHeader> <AssemblerListingLocation>$(IntDir)\</AssemblerListingLocation> <ObjectFileName>$(IntDir)\</ObjectFileName> <ProgramDataBaseFileName>$(IntDir)\</ProgramDataBaseFileName> @@ -105,10 +105,10 @@ <ClCompile> <Optimization>Full</Optimization> <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_CONSOLE;WIN32;_WINDOWS;NDEBUG;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=1.0.0;JUCE_APP_VERSION_HEX=0x10000;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_CONSOLE;WIN32;_WINDOWS;NDEBUG;JUCE_DISPLAY_SPLASH_SCREEN=0;JUCE_USE_DARK_SPLASH_SCREEN=1;JUCE_PROJUCER_VERSION=0x60005;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_STANDALONE_APPLICATION=1;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=1.0.0;JUCE_APP_VERSION_HEX=0x10000;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> <RuntimeTypeInfo>true</RuntimeTypeInfo> - <PrecompiledHeader/> + <PrecompiledHeader>NotUsing</PrecompiledHeader> <AssemblerListingLocation>$(IntDir)\</AssemblerListingLocation> <ObjectFileName>$(IntDir)\</ObjectFileName> <ProgramDataBaseFileName>$(IntDir)\</ProgramDataBaseFileName> @@ -130,6 +130,7 @@ <OptimizeReferences>true</OptimizeReferences> <EnableCOMDATFolding>true</EnableCOMDATFolding> <LargeAddressAware>true</LargeAddressAware> + <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> </Link> <Bscmake> <SuppressStartupBanner>true</SuppressStartupBanner> @@ -187,6 +188,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_FileSearchPath.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -214,6 +218,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_MemoryBlock.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -469,6 +476,7 @@ <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_FileOutputStream.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_FileSearchPath.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_MemoryMappedFile.h"/> + <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_WildcardFileFilter.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\javascript\juce_Javascript.h"/> @@ -482,6 +490,7 @@ <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_Random.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_Range.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_StatisticsAccumulator.h"/> + <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_Atomic.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_ByteOrder.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_ContainerDeletePolicy.h"/> @@ -524,6 +533,7 @@ <ClInclude Include="..\..\..\..\modules\juce_core\streams\juce_SubregionStream.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\streams\juce_URLInputSource.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerSupport.h"/> + <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerWarnings.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_PlatformDefs.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_StandardHeader.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_SystemStats.h"/> @@ -581,7 +591,6 @@ <ClInclude Include="..\..\..\..\modules\juce_core\zip\juce_GZIPDecompressorInputStream.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\zip\juce_ZipFile.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\juce_core.h"/> - <ClInclude Include="..\..\JuceLibraryCode\AppConfig.h"/> <ClInclude Include="..\..\JuceLibraryCode\JuceHeader.h"/> </ItemGroup> <ItemGroup> diff --git a/extras/BinaryBuilder/Builds/VisualStudio2019/BinaryBuilder_ConsoleApp.vcxproj.filters b/extras/BinaryBuilder/Builds/VisualStudio2019/BinaryBuilder_ConsoleApp.vcxproj.filters index 98e83714..57ad38db 100644 --- a/extras/BinaryBuilder/Builds/VisualStudio2019/BinaryBuilder_ConsoleApp.vcxproj.filters +++ b/extras/BinaryBuilder/Builds/VisualStudio2019/BinaryBuilder_ConsoleApp.vcxproj.filters @@ -127,6 +127,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_FileSearchPath.cpp"> <Filter>JUCE Modules\juce_core\files</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.cpp"> + <Filter>JUCE Modules\juce_core\files</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.cpp"> <Filter>JUCE Modules\juce_core\files</Filter> </ClCompile> @@ -154,6 +157,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> <Filter>JUCE Modules\juce_core\maths</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.cpp"> + <Filter>JUCE Modules\juce_core\memory</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_MemoryBlock.cpp"> <Filter>JUCE Modules\juce_core\memory</Filter> </ClCompile> @@ -477,6 +483,9 @@ <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_MemoryMappedFile.h"> <Filter>JUCE Modules\juce_core\files</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.h"> + <Filter>JUCE Modules\juce_core\files</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.h"> <Filter>JUCE Modules\juce_core\files</Filter> </ClInclude> @@ -516,6 +525,9 @@ <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_StatisticsAccumulator.h"> <Filter>JUCE Modules\juce_core\maths</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.h"> + <Filter>JUCE Modules\juce_core\memory</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_Atomic.h"> <Filter>JUCE Modules\juce_core\memory</Filter> </ClInclude> @@ -642,6 +654,9 @@ <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerSupport.h"> <Filter>JUCE Modules\juce_core\system</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerWarnings.h"> + <Filter>JUCE Modules\juce_core\system</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_PlatformDefs.h"> <Filter>JUCE Modules\juce_core\system</Filter> </ClInclude> @@ -813,9 +828,6 @@ <ClInclude Include="..\..\..\..\modules\juce_core\juce_core.h"> <Filter>JUCE Modules\juce_core</Filter> </ClInclude> - <ClInclude Include="..\..\JuceLibraryCode\AppConfig.h"> - <Filter>JUCE Library Code</Filter> - </ClInclude> <ClInclude Include="..\..\JuceLibraryCode\JuceHeader.h"> <Filter>JUCE Library Code</Filter> </ClInclude> diff --git a/extras/BinaryBuilder/Builds/VisualStudio2019/resources.rc b/extras/BinaryBuilder/Builds/VisualStudio2019/resources.rc index f1fe4e9e..dc885ea9 100644 --- a/extras/BinaryBuilder/Builds/VisualStudio2019/resources.rc +++ b/extras/BinaryBuilder/Builds/VisualStudio2019/resources.rc @@ -1,3 +1,5 @@ +#pragma code_page(65001) + #ifdef JUCE_USER_DEFINED_RC_FILE #include JUCE_USER_DEFINED_RC_FILE #else @@ -13,8 +15,8 @@ BEGIN BEGIN BLOCK "040904E4" BEGIN - VALUE "CompanyName", "ROLI Ltd.\0" - VALUE "LegalCopyright", "ROLI Ltd.\0" + VALUE "CompanyName", "Raw Material Software Limited\0" + VALUE "LegalCopyright", "Raw Material Software Limited\0" VALUE "FileDescription", "BinaryBuilder\0" VALUE "FileVersion", "1.0.0\0" VALUE "ProductName", "BinaryBuilder\0" diff --git a/extras/BinaryBuilder/CMakeLists.txt b/extras/BinaryBuilder/CMakeLists.txt new file mode 100644 index 00000000..76303e6e --- /dev/null +++ b/extras/BinaryBuilder/CMakeLists.txt @@ -0,0 +1,36 @@ +# ============================================================================== +# +# This file is part of the JUCE library. +# Copyright (c) 2020 - Raw Material Software Limited +# +# JUCE is an open source library subject to commercial or open-source +# licensing. +# +# By using JUCE, you agree to the terms of both the JUCE 6 End-User License +# Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). +# +# End User License Agreement: www.juce.com/juce-6-licence +# Privacy Policy: www.juce.com/juce-privacy-policy +# +# Or: You may also use this code under the terms of the GPL v3 (see +# www.gnu.org/licenses). +# +# JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER +# EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE +# DISCLAIMED. +# +# ============================================================================== + +juce_add_console_app(BinaryBuilder) + +juce_generate_juce_header(BinaryBuilder) + +target_sources(BinaryBuilder PRIVATE Source/Main.cpp) + +target_compile_definitions(BinaryBuilder PRIVATE JUCE_USE_CURL=0) + +target_link_libraries(BinaryBuilder PRIVATE + juce::juce_core + juce::juce_recommended_config_flags + juce::juce_recommended_lto_flags + juce::juce_recommended_warning_flags) diff --git a/extras/BinaryBuilder/JuceLibraryCode/AppConfig.h b/extras/BinaryBuilder/JuceLibraryCode/AppConfig.h deleted file mode 100644 index 88f91e28..00000000 --- a/extras/BinaryBuilder/JuceLibraryCode/AppConfig.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - - IMPORTANT! This file is auto-generated each time you save your - project - if you alter its contents, your changes may be overwritten! - - There's a section below where you can add your own custom code safely, and the - Projucer will preserve the contents of that block, but the best way to change - any of these definitions is by using the Projucer's project settings. - - Any commented-out settings will assume their default values. - -*/ - -#pragma once - -//============================================================================== -// [BEGIN_USER_CODE_SECTION] - -// (You can add your own code in this section, and the Projucer will not overwrite it) - -// [END_USER_CODE_SECTION] - -/* - ============================================================================== - - In accordance with the terms of the JUCE 5 End-Use License Agreement, the - JUCE Code in SECTION A cannot be removed, changed or otherwise rendered - ineffective unless you have a JUCE Indie or Pro license, or are using JUCE - under the GPL v3 license. - - End User License Agreement: www.juce.com/juce-5-licence - - ============================================================================== -*/ - -// BEGIN SECTION A - -#ifndef JUCE_DISPLAY_SPLASH_SCREEN - #define JUCE_DISPLAY_SPLASH_SCREEN 0 -#endif - -#ifndef JUCE_REPORT_APP_USAGE - #define JUCE_REPORT_APP_USAGE 0 -#endif - -// END SECTION A - -#define JUCE_USE_DARK_SPLASH_SCREEN 1 - -#define JUCE_PROJUCER_VERSION 0x50407 - -//============================================================================== -#define JUCE_MODULE_AVAILABLE_juce_core 1 - -#define JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED 1 - -//============================================================================== -// juce_core flags: - -#ifndef JUCE_FORCE_DEBUG - //#define JUCE_FORCE_DEBUG 0 -#endif - -#ifndef JUCE_LOG_ASSERTIONS - //#define JUCE_LOG_ASSERTIONS 0 -#endif - -#ifndef JUCE_CHECK_MEMORY_LEAKS - //#define JUCE_CHECK_MEMORY_LEAKS 1 -#endif - -#ifndef JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES - //#define JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES 0 -#endif - -#ifndef JUCE_INCLUDE_ZLIB_CODE - //#define JUCE_INCLUDE_ZLIB_CODE 1 -#endif - -#ifndef JUCE_USE_CURL - //#define JUCE_USE_CURL 1 -#endif - -#ifndef JUCE_LOAD_CURL_SYMBOLS_LAZILY - //#define JUCE_LOAD_CURL_SYMBOLS_LAZILY 0 -#endif - -#ifndef JUCE_CATCH_UNHANDLED_EXCEPTIONS - //#define JUCE_CATCH_UNHANDLED_EXCEPTIONS 0 -#endif - -#ifndef JUCE_ALLOW_STATIC_NULL_VARIABLES - //#define JUCE_ALLOW_STATIC_NULL_VARIABLES 0 -#endif - -#ifndef JUCE_STRICT_REFCOUNTEDPOINTER - //#define JUCE_STRICT_REFCOUNTEDPOINTER 0 -#endif - -//============================================================================== -#ifndef JUCE_STANDALONE_APPLICATION - #if defined(JucePlugin_Name) && defined(JucePlugin_Build_Standalone) - #define JUCE_STANDALONE_APPLICATION JucePlugin_Build_Standalone - #else - #define JUCE_STANDALONE_APPLICATION 1 - #endif -#endif diff --git a/extras/BinaryBuilder/JuceLibraryCode/JuceHeader.h b/extras/BinaryBuilder/JuceLibraryCode/JuceHeader.h index 990925e6..d84015ad 100644 --- a/extras/BinaryBuilder/JuceLibraryCode/JuceHeader.h +++ b/extras/BinaryBuilder/JuceLibraryCode/JuceHeader.h @@ -12,7 +12,6 @@ #pragma once -#include "AppConfig.h" #include <juce_core/juce_core.h> @@ -36,7 +35,7 @@ namespace ProjectInfo { const char* const projectName = "BinaryBuilder"; - const char* const companyName = "ROLI Ltd."; + const char* const companyName = "Raw Material Software Limited"; const char* const versionString = "1.0.0"; const int versionNumber = 0x10000; } diff --git a/extras/BinaryBuilder/JuceLibraryCode/include_juce_core.cpp b/extras/BinaryBuilder/JuceLibraryCode/include_juce_core.cpp index d0ce1636..84fe988c 100644 --- a/extras/BinaryBuilder/JuceLibraryCode/include_juce_core.cpp +++ b/extras/BinaryBuilder/JuceLibraryCode/include_juce_core.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_core/juce_core.cpp> diff --git a/extras/BinaryBuilder/JuceLibraryCode/include_juce_core.mm b/extras/BinaryBuilder/JuceLibraryCode/include_juce_core.mm index 72b10bf8..9ee67bf6 100644 --- a/extras/BinaryBuilder/JuceLibraryCode/include_juce_core.mm +++ b/extras/BinaryBuilder/JuceLibraryCode/include_juce_core.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_core/juce_core.mm> diff --git a/extras/BinaryBuilder/Source/Main.cpp b/extras/BinaryBuilder/Source/Main.cpp index 9716d7c1..e84a49c9 100644 --- a/extras/BinaryBuilder/Source/Main.cpp +++ b/extras/BinaryBuilder/Source/Main.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Build/CMake/JUCECheckAtomic.cmake b/extras/Build/CMake/JUCECheckAtomic.cmake new file mode 100644 index 00000000..bdbdbc04 --- /dev/null +++ b/extras/Build/CMake/JUCECheckAtomic.cmake @@ -0,0 +1,83 @@ +# ============================================================================== +# +# This file is part of the JUCE library. +# Copyright (c) 2020 - Raw Material Software Limited +# +# JUCE is an open source library subject to commercial or open-source +# licensing. +# +# By using JUCE, you agree to the terms of both the JUCE 6 End-User License +# Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). +# +# End User License Agreement: www.juce.com/juce-6-licence +# Privacy Policy: www.juce.com/juce-privacy-policy +# +# Or: You may also use this code under the terms of the GPL v3 (see +# www.gnu.org/licenses). +# +# JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER +# EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE +# DISCLAIMED. +# +# ============================================================================== + +function(_juce_create_atomic_target target_name) + add_library("${target_name}" INTERFACE) + add_library("juce::${target_name}" ALIAS "${target_name}") + + if(NOT (CMAKE_SYSTEM_NAME STREQUAL "Linux")) + return() + endif() + + set(test_file_contents + [[ + #include <atomic> + + int main (int argc, char** argv) + { + std::atomic<long long> ll { static_cast<long long> (argc) }; + ll ^= 1; + return static_cast<int> (ll); + } + ]]) + + string(RANDOM LENGTH 16 random_file_string) + set(test_file_name "${CMAKE_CURRENT_BINARY_DIR}/check_atomic_${random_file_string}.cpp") + + string(RANDOM LENGTH 16 random_dir_string) + set(test_bindir "${CMAKE_CURRENT_BINARY_DIR}/check_atomic_dir_${random_dir_string}") + + file(WRITE "${test_file_name}" "${test_file_contents}") + + try_compile(compile_result "${test_bindir}" "${test_file_name}" + OUTPUT_VARIABLE test_build_output_0 + CXX_STANDARD 11 + CXX_STANDARD_REQUIRED TRUE + CXX_EXTENSIONS FALSE) + + if(NOT compile_result) + try_compile(compile_result "${test_bindir}" "${test_file_name}" + OUTPUT_VARIABLE test_build_output_1 + LINK_LIBRARIES atomic + CXX_STANDARD 11 + CXX_STANDARD_REQUIRED TRUE + CXX_EXTENSIONS FALSE) + + if (NOT compile_result) + message(FATAL_ERROR + "First build output:\n" + "${test_build_output_0}" + "\n\nSecond build output:\n" + "${test_build_output_1}" + "\n\nJUCE requires support for std::atomic, but this system cannot " + "successfully compile a program which uses std::atomic. " + "You may need to install a dedicated libatomic package using your " + "system's package manager.") + endif() + + target_link_libraries("${target_name}" INTERFACE atomic) + endif() + + file(REMOVE "${test_file_name}") + file(REMOVE_RECURSE "${test_bindir}") +endfunction() diff --git a/extras/Build/CMake/JUCEConfig.cmake.in b/extras/Build/CMake/JUCEConfig.cmake.in new file mode 100644 index 00000000..3e5c97de --- /dev/null +++ b/extras/Build/CMake/JUCEConfig.cmake.in @@ -0,0 +1,90 @@ +# ============================================================================== +# +# This file is part of the JUCE library. +# Copyright (c) 2020 - Raw Material Software Limited +# +# JUCE is an open source library subject to commercial or open-source +# licensing. +# +# The code included in this file is provided under the terms of the ISC license +# http://www.isc.org/downloads/software-support-policy/isc-license. Permission +# To use, copy, modify, and/or distribute this software for any purpose with or +# without fee is hereby granted provided that the above copyright notice and +# this permission notice appear in all copies. +# +# JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER +# EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE +# DISCLAIMED. +# +# ============================================================================== + +@PACKAGE_INIT@ + +if(NOT TARGET juce::juceaide) + add_executable(juce::juceaide IMPORTED) + set_target_properties(juce::juceaide PROPERTIES + IMPORTED_LOCATION "@PACKAGE_JUCEAIDE_PATH@") +endif() + +check_required_components("@PROJECT_NAME@") + +set(JUCE_MODULES_DIR "@PACKAGE_JUCE_MODULE_PATH@" CACHE INTERNAL + "The path to JUCE modules") + +include("@PACKAGE_UTILS_INSTALL_DIR@/JUCEUtils.cmake") + +set(_juce_modules + juce_analytics + juce_audio_basics + juce_audio_devices + juce_audio_formats + juce_audio_plugin_client + juce_audio_processors + juce_audio_utils + juce_blocks_basics + juce_box2d + juce_core + juce_cryptography + juce_data_structures + juce_dsp + juce_events + juce_graphics + juce_gui_basics + juce_gui_extra + juce_opengl + juce_osc + juce_product_unlocking + juce_video) + +set(_targets_defined) +set(_targets_expected) + +foreach(_juce_module IN LISTS _juce_modules) + list(APPEND _targets_expected ${_juce_module} juce::${_juce_modules}) + if(TARGET ${_juce_module}) + list(APPEND _targets_defined ${_juce_module}) + endif() + + if(TARGET juce::${_juce_module}) + list(APPEND _targets_defined juce::${_juce_module}) + endif() +endforeach() + +if("${_targets_defined}" STREQUAL "${_targets_expected}") + unset(_targets_defined) + unset(_targets_expected) + return() +endif() + +if(NOT "${_targets_defined}" STREQUAL "") + message(FATAL_ERROR "Some targets in this export set were already defined.") +endif() + +unset(_targets_defined) +unset(_targets_expected) + +foreach(_juce_module IN LISTS _juce_modules) + juce_add_module("@PACKAGE_JUCE_MODULE_PATH@/${_juce_module}" ALIAS_NAMESPACE juce) +endforeach() + +unset(_juce_modules) diff --git a/extras/Build/CMake/JUCEHelperTargets.cmake b/extras/Build/CMake/JUCEHelperTargets.cmake new file mode 100644 index 00000000..97e4194d --- /dev/null +++ b/extras/Build/CMake/JUCEHelperTargets.cmake @@ -0,0 +1,62 @@ +add_library(juce_recommended_warning_flags INTERFACE) +add_library(juce::juce_recommended_warning_flags ALIAS juce_recommended_warning_flags) + +if((CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") OR (CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC")) + target_compile_options(juce_recommended_warning_flags INTERFACE "/W4") +elseif((CMAKE_CXX_COMPILER_ID STREQUAL "Clang") OR (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")) + target_compile_options(juce_recommended_warning_flags INTERFACE + -Wall -Wshadow-all -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized + -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion + -Wconditional-uninitialized -Woverloaded-virtual -Wreorder + -Wconstant-conversion -Wsign-conversion -Wunused-private-field + -Wbool-conversion -Wextra-semi -Wunreachable-code + -Wzero-as-null-pointer-constant -Wcast-align + -Winconsistent-missing-destructor-override -Wshift-sign-overflow + -Wnullable-to-nonnull-conversion -Wno-missing-field-initializers + -Wno-ignored-qualifiers -Wswitch-enum -Wpedantic) +elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + target_compile_options(juce_recommended_warning_flags INTERFACE + -Wall -Wextra -Wstrict-aliasing -Wuninitialized -Wunused-parameter + -Wsign-compare -Woverloaded-virtual -Wreorder -Wsign-conversion + -Wunreachable-code -Wzero-as-null-pointer-constant -Wcast-align + -Wno-implicit-fallthrough -Wno-maybe-uninitialized + -Wno-missing-field-initializers -Wno-ignored-qualifiers -Wswitch-enum + -Wredundant-decls -Wpedantic) + + if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "7.0.0") + target_compile_options(juce_recommended_warning_flags INTERFACE "-Wno-strict-overflow") + endif() +endif() + +# ================================================================================================== + +add_library(juce_recommended_config_flags INTERFACE) +add_library(juce::juce_recommended_config_flags ALIAS juce_recommended_config_flags) + +if((CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") OR (CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC")) + target_compile_options(juce_recommended_config_flags INTERFACE + $<IF:$<CONFIG:Debug>,/Od,/Ox> $<$<STREQUAL:"${CMAKE_CXX_COMPILER_ID}","MSVC">:/MP> /EHsc) +elseif((CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + OR (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") + OR (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")) + target_compile_options(juce_recommended_config_flags INTERFACE + $<$<CONFIG:Debug>:-g -O0> + $<$<CONFIG:Release>:-O3>) +endif() + +# ================================================================================================== + +add_library(juce_recommended_lto_flags INTERFACE) +add_library(juce::juce_recommended_lto_flags ALIAS juce_recommended_lto_flags) + +if((CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") OR (CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC")) + target_compile_options(juce_recommended_lto_flags INTERFACE + $<$<CONFIG:Release>:$<IF:$<STREQUAL:"${CMAKE_CXX_COMPILER_ID}","MSVC">,-GL,-flto>>) + target_link_libraries(juce_recommended_lto_flags INTERFACE + $<$<CONFIG:Release>:$<$<STREQUAL:"${CMAKE_CXX_COMPILER_ID}","MSVC">:-LTCG>>) +elseif((CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + OR (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") + OR (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")) + target_compile_options(juce_recommended_lto_flags INTERFACE $<$<CONFIG:Release>:-flto>) + target_link_libraries(juce_recommended_lto_flags INTERFACE $<$<CONFIG:Release>:-flto>) +endif() diff --git a/extras/Build/CMake/JUCEUtils.cmake b/extras/Build/CMake/JUCEUtils.cmake new file mode 100644 index 00000000..73a450e8 --- /dev/null +++ b/extras/Build/CMake/JUCEUtils.cmake @@ -0,0 +1,2296 @@ +# ============================================================================== +# +# This file is part of the JUCE library. +# Copyright (c) 2020 - Raw Material Software Limited +# +# JUCE is an open source library subject to commercial or open-source +# licensing. +# +# By using JUCE, you agree to the terms of both the JUCE 6 End-User License +# Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). +# +# End User License Agreement: www.juce.com/juce-6-licence +# Privacy Policy: www.juce.com/juce-privacy-policy +# +# Or: You may also use this code under the terms of the GPL v3 (see +# www.gnu.org/licenses). +# +# JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER +# EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE +# DISCLAIMED. +# +# ============================================================================== + +# ================================================================================================== +# JUCE/CMake Compatibility Module +# +# In this file, functions intended for use by end-users have the prefix `juce_`. +# Functions beginning with an underscore should be considered private and susceptible to +# change, so don't call them directly. +# +# See the readme at `docs/CMake API.md` for more information about CMake usage, +# including documentation of the public functions in this file. +# ================================================================================================== + +include_guard(GLOBAL) +cmake_minimum_required(VERSION 3.12) + +define_property(TARGET PROPERTY JUCE_COMPANY_NAME INHERITED + BRIEF_DOCS "The company name for a particular target" + FULL_DOCS "This can be found in ProjectInfo::companyName in a generated JuceHeader.h") +set_property(GLOBAL PROPERTY JUCE_COMPANY_NAME "yourcompany") + +define_property(TARGET PROPERTY JUCE_COMPANY_WEBSITE INHERITED + BRIEF_DOCS "The company website for a particular target" + FULL_DOCS "This will be placed in the Info.plist for the target") +set_property(GLOBAL PROPERTY JUCE_COMPANY_WEBSITE "") + +define_property(TARGET PROPERTY JUCE_COMPANY_EMAIL INHERITED + BRIEF_DOCS "The company email address for a particular target" + FULL_DOCS "This will be placed in the Info.plist for the target") +set_property(GLOBAL PROPERTY JUCE_COMPANY_EMAIL "") + +define_property(TARGET PROPERTY JUCE_COMPANY_COPYRIGHT INHERITED + BRIEF_DOCS "The company copyright for a particular target" + FULL_DOCS "This will be placed in the Info.plist for the target") +set_property(GLOBAL PROPERTY JUCE_COMPANY_COPYRIGHT "") + +define_property(TARGET PROPERTY JUCE_VST_COPY_DIR INHERITED + BRIEF_DOCS "Install location for VST2 plugins" + FULL_DOCS "This is where the plugin will be copied if plugin copying is enabled") + +define_property(TARGET PROPERTY JUCE_VST3_COPY_DIR INHERITED + BRIEF_DOCS "Install location for VST3 plugins" + FULL_DOCS "This is where the plugin will be copied if plugin copying is enabled") + +define_property(TARGET PROPERTY JUCE_AU_COPY_DIR INHERITED + BRIEF_DOCS "Install location for AU plugins" + FULL_DOCS "This is where the plugin will be copied if plugin copying is enabled") + +define_property(TARGET PROPERTY JUCE_AAX_COPY_DIR INHERITED + BRIEF_DOCS "Install location for AAX plugins" + FULL_DOCS "This is where the plugin will be copied if plugin copying is enabled") + +define_property(TARGET PROPERTY JUCE_UNITY_COPY_DIR INHERITED + BRIEF_DOCS "Install location for Unity plugins" + FULL_DOCS "This is where the plugin will be copied if plugin copying is enabled") + +define_property(TARGET PROPERTY JUCE_COPY_PLUGIN_AFTER_BUILD INHERITED + BRIEF_DOCS "Whether or not plugins should be copied after building" + FULL_DOCS "Whether or not plugins should be copied after building") +set_property(GLOBAL PROPERTY JUCE_COPY_PLUGIN_AFTER_BUILD FALSE) + +# ================================================================================================== + +function(_juce_add_interface_library target) + add_library(${target} INTERFACE) + target_sources(${target} INTERFACE ${ARGN}) +endfunction() + +# ================================================================================================== + +function(_juce_create_pkgconfig_target name) + if(TARGET juce::pkgconfig_${name}) + return() + endif() + + find_package(PkgConfig REQUIRED) + pkg_check_modules(${name} ${ARGN}) + + add_library(pkgconfig_${name} INTERFACE) + add_library(juce::pkgconfig_${name} ALIAS pkgconfig_${name}) + install(TARGETS pkgconfig_${name} EXPORT JUCE) + + set(pairs + "INCLUDE_DIRECTORIES\;INCLUDE_DIRS" + "LINK_LIBRARIES\;LINK_LIBRARIES" + "LINK_OPTIONS\;LDFLAGS_OTHER" + "COMPILE_OPTIONS\;CFLAGS_OTHER") + + foreach(pair IN LISTS pairs) + list(GET pair 0 key) + list(GET pair 1 value) + + if(${name}_${value}) + set_target_properties(pkgconfig_${name} PROPERTIES INTERFACE_${key} "${${name}_${value}}") + endif() + endforeach() +endfunction() + +# ================================================================================================== + +set(JUCE_CMAKE_UTILS_DIR ${CMAKE_CURRENT_LIST_DIR} + CACHE INTERNAL "The path to the folder holding this file and other resources") + +include("${JUCE_CMAKE_UTILS_DIR}/JUCEHelperTargets.cmake") +include("${JUCE_CMAKE_UTILS_DIR}/JUCECheckAtomic.cmake") + +_juce_create_atomic_target(juce_atomic_wrapper) + +# Tries to discover the target platform architecture, which is necessary for +# naming VST3 bundle folders correctly. +function(_juce_find_linux_target_architecture result) + set(test_file "${JUCE_CMAKE_UTILS_DIR}/juce_runtime_arch_detection.cpp") + try_compile(compile_result "${CMAKE_CURRENT_BINARY_DIR}" "${test_file}" + OUTPUT_VARIABLE compile_output) + string(REGEX REPLACE ".*JUCE_ARCH ([a-zA-Z0-9_-]*).*" "\\1" match_result "${compile_output}") + set("${result}" "${match_result}" PARENT_SCOPE) +endfunction() + +if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + _juce_create_pkgconfig_target(JUCE_CURL_LINUX_DEPS libcurl) + _juce_create_pkgconfig_target(JUCE_BROWSER_LINUX_DEPS webkit2gtk-4.0 gtk+-x11-3.0) + + # If you really need to override the detected arch for some reason, + # you can configure the build with -DJUCE_LINUX_TARGET_ARCHITECTURE=<custom arch> + if(NOT DEFINED JUCE_LINUX_TARGET_ARCHITECTURE) + _juce_find_linux_target_architecture(target_arch) + set(JUCE_LINUX_TARGET_ARCHITECTURE "${target_arch}" + CACHE INTERNAL "The target architecture, used to name internal folders in VST3 bundles") + endif() +elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + find_program(JUCE_XCRUN xcrun) + + if(NOT JUCE_XCRUN) + message(WARNING "failed to find xcrun; older resource-based AU plug-ins may not work correctly") + endif() +endif() + +# We set up default/fallback copy dirs here. If you need different copy dirs, use +# set_directory_properties or set_target_properties to adjust the values of `JUCE_*_COPY_DIR` at +# the appropriate scope. + +function(_juce_set_default_properties) + if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + set_property(GLOBAL PROPERTY JUCE_VST_COPY_DIR "$ENV{HOME}/Library/Audio/Plug-Ins/VST") + set_property(GLOBAL PROPERTY JUCE_VST3_COPY_DIR "$ENV{HOME}/Library/Audio/Plug-Ins/VST3") + set_property(GLOBAL PROPERTY JUCE_AU_COPY_DIR "$ENV{HOME}/Library/Audio/Plug-Ins/Components") + set_property(GLOBAL PROPERTY JUCE_AAX_COPY_DIR "/Library/Application Support/Avid/Audio/Plug-Ins") + elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows") + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set_property(GLOBAL PROPERTY JUCE_VST_COPY_DIR "$ENV{ProgramW6432}/Steinberg/Vstplugins") + set(prefix "$ENV{CommonProgramW6432}") + else() + set_property(GLOBAL PROPERTY JUCE_VST_COPY_DIR "$ENV{programfiles\(x86\)}/Steinberg/Vstplugins") + set(prefix "$ENV{CommonProgramFiles\(x86\)}") + endif() + + set_property(GLOBAL PROPERTY JUCE_VST3_COPY_DIR "${prefix}/VST3") + set_property(GLOBAL PROPERTY JUCE_AAX_COPY_DIR "${prefix}/Avid/Audio/Plug-Ins") + elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") + set_property(GLOBAL PROPERTY JUCE_VST_COPY_DIR "$ENV{HOME}/.vst") + set_property(GLOBAL PROPERTY JUCE_VST3_COPY_DIR "$ENV{HOME}/.vst3") + endif() +endfunction() + +_juce_set_default_properties() + +# ================================================================================================== + +function(_juce_add_standard_defs juce_target) + target_compile_definitions(${juce_target} INTERFACE + JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1 + $<IF:$<CONFIG:DEBUG>,DEBUG=1 _DEBUG=1,NDEBUG=1 _NDEBUG=1> + $<$<PLATFORM_ID:Android>:JUCE_ANDROID=1>) +endfunction() + +# ================================================================================================== + +macro(_juce_make_absolute path) + if(NOT IS_ABSOLUTE "${${path}}") + get_filename_component("${path}" "${${path}}" ABSOLUTE BASE_DIR "${CMAKE_CURRENT_LIST_DIR}") + endif() +endmacro() + +macro(_juce_make_absolute_and_check path) + _juce_make_absolute("${path}") + + if(NOT EXISTS "${${path}}") + message(FATAL_ERROR "No file at path ${${path}}") + endif() +endmacro() + +# ================================================================================================== + +function(juce_add_bundle_resources_directory target folder) + _juce_make_absolute(folder) + + if(NOT EXISTS "${folder}") + message(FATAL_ERROR "Could not find resource folder ${folder}") + endif() + + get_filename_component(folder_parent_path "${folder}" DIRECTORY) + file(GLOB_RECURSE resources RELATIVE "${folder_parent_path}" "${folder}/*") + + foreach(file IN LISTS resources) + target_sources(${target} PRIVATE "${folder_parent_path}/${file}") + get_filename_component(resource_parent_path "${file}" DIRECTORY) + set_source_files_properties("${folder_parent_path}/${file}" PROPERTIES + HEADER_FILE_ONLY TRUE + MACOSX_PACKAGE_LOCATION "Resources/${resource_parent_path}") + endforeach() +endfunction() + +# ================================================================================================== + +# This creates an imported interface library with a random name, and then adds +# the fields from a JUCE module header to the target as INTERFACE_ properties. +# We can extract properties later using `_juce_get_metadata`. +# This way, the interface library ends up behaving a bit like a dictionary, +# and we don't have to parse the module header from scratch every time we +# want to find a specific key. +function(_juce_extract_metadata_block delim_str file_with_block out_dict) + string(RANDOM LENGTH 16 random_string) + set(target_name "${random_string}_dict") + set(${out_dict} "${target_name}" PARENT_SCOPE) + add_library(${target_name} INTERFACE IMPORTED) + + if(NOT EXISTS ${file_with_block}) + message(FATAL_ERROR "Unable to find file ${file_with_block}") + endif() + + file(STRINGS ${file_with_block} module_header_contents) + + set(last_written_key) + set(append NO) + + foreach(line IN LISTS module_header_contents) + if(NOT append) + if(line MATCHES " *BEGIN_${delim_str} *") + set(append YES) + endif() + + continue() + endif() + + if(append AND (line MATCHES " *END_${delim_str} *")) + break() + endif() + + if(line MATCHES "^ *([a-zA-Z]+):") + set(last_written_key "${CMAKE_MATCH_1}") + endif() + + string(REGEX REPLACE "^ *${last_written_key}: *" "" line "${line}") + string(REGEX REPLACE "[ ,]+" ";" line "${line}") + + set_property(TARGET ${target_name} APPEND PROPERTY + "INTERFACE_JUCE_${last_written_key}" "${line}") + endforeach() +endfunction() + +# Fetches properties attached to a metadata target. +function(_juce_get_metadata target key out_var) + get_target_property(content "${target}" "INTERFACE_JUCE_${key}") + + if(NOT "${content}" STREQUAL "content-NOTFOUND") + set(${out_var} "${content}" PARENT_SCOPE) + endif() +endfunction() + +# ================================================================================================== + +function(_juce_module_sources module_path output_path out_var) + get_filename_component(module_parent_path ${module_path} DIRECTORY) + get_filename_component(module_glob ${module_path} NAME) + + file(GLOB module_cpp + CONFIGURE_DEPENDS LIST_DIRECTORIES false + RELATIVE "${module_parent_path}" + "${module_path}/${module_glob}*.cpp") + + if(APPLE) + file(GLOB module_mm + CONFIGURE_DEPENDS LIST_DIRECTORIES false + RELATIVE "${module_parent_path}" + "${module_path}/${module_glob}*.mm" + "${module_path}/${module_glob}*.r") + + if(module_mm) + set(module_mm_replaced ${module_mm}) + list(TRANSFORM module_mm_replaced REPLACE "\\.mm$" ".cpp") + list(REMOVE_ITEM module_cpp ${module_mm_replaced}) + list(APPEND module_cpp ${module_mm}) + endif() + endif() + + list(TRANSFORM module_cpp PREPEND "${output_path}/") + + set(${out_var} ${module_cpp} PARENT_SCOPE) +endfunction() + +# ================================================================================================== + +function(_juce_get_all_plugin_kinds out) + set(${out} AU AUv3 AAX Standalone Unity VST VST3 PARENT_SCOPE) +endfunction() + +function(_juce_get_platform_plugin_kinds out) + set(result Standalone) + + if(APPLE AND (CMAKE_GENERATOR STREQUAL "Xcode")) + list(APPEND result AUv3) + endif() + + if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + list(APPEND result AU) + endif() + + if(NOT CMAKE_SYSTEM_NAME STREQUAL "iOS" AND NOT CMAKE_SYSTEM_NAME STREQUAL "Android") + list(APPEND result AAX Unity VST) + + if(NOT MINGW AND NOT MSYS) + list(APPEND result VST3) + endif() + endif() + + set(${out} ${result} PARENT_SCOPE) +endfunction() + +function(_juce_add_plugin_definitions target visibility) + _juce_get_all_plugin_kinds(options) + cmake_parse_arguments(JUCE_ARG "${options}" "" "" ${ARGN}) + + foreach(opt IN LISTS options) + set(flag_value 0) + + if(JUCE_ARG_${opt}) + set(flag_value 1) + endif() + + target_compile_definitions(${target} ${visibility} "JucePlugin_Build_${opt}=${flag_value}") + endforeach() +endfunction() + +# ================================================================================================== + +function(_juce_add_au_resource_fork shared_code_target au_target) + if(NOT JUCE_XCRUN) + return() + endif() + + get_target_property(product_name ${shared_code_target} JUCE_PRODUCT_NAME) + get_target_property(module_sources juce::juce_audio_plugin_client_AU INTERFACE_SOURCES) + + list(FILTER module_sources INCLUDE REGEX "/juce_audio_plugin_client_AU.r$") + + if(NOT module_sources) + message(FATAL_ERROR "Failed to find AU resource file input") + endif() + + list(GET module_sources 0 au_rez_sources) + + get_target_property(juce_library_code ${shared_code_target} JUCE_GENERATED_SOURCES_DIRECTORY) + # We don't want our AU AppConfig.h to end up on peoples' include paths if we can help it + set(secret_au_resource_dir "${juce_library_code}/${au_target}/secret") + set(secret_au_plugindefines "${secret_au_resource_dir}/JucePluginDefines.h") + + set(au_rez_output "${secret_au_resource_dir}/${product_name}.rsrc") + + target_sources(${au_target} PRIVATE "${au_rez_output}") + set_source_files_properties("${au_rez_output}" PROPERTIES + GENERATED TRUE + MACOSX_PACKAGE_LOCATION Resources) + + set(defs_file $<GENEX_EVAL:$<TARGET_PROPERTY:${shared_code_target},JUCE_DEFS_FILE>>) + + # Passing all our compile definitions using generator expressions is really painful + # because some of the definitions have pipes and quotes and dollars and goodness-knows + # what else that the shell would very much like to claim for itself, thank you very much. + # CMake definitely knows how to escape all these things, because it's perfectly happy to pass + # them to compiler invocations, but I have no idea how to get it to escape them + # in a custom command. + # In the end, it's simplest to generate a special single-purpose appconfig just for the + # resource compiler. + add_custom_command(OUTPUT "${secret_au_plugindefines}" + COMMAND juce::juceaide auplugindefines "${defs_file}" "${secret_au_plugindefines}" + DEPENDS "${defs_file}" + VERBATIM) + + add_custom_command(OUTPUT "${au_rez_output}" + COMMAND "${JUCE_XCRUN}" Rez + -d "ppc_$ppc" -d "i386_$i386" -d "ppc64_$ppc64" -d "x86_64_$x86_64" + -I "${secret_au_resource_dir}" + -I "/System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Versions/A/Headers" + -I "/Applications/Xcode.app/Contents/Developer/Extras/CoreAudio/AudioUnits/AUPublic/AUBase" + -I "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/AudioUnit.framework/Headers" + -isysroot "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk" + "${au_rez_sources}" + -useDF + -o "${au_rez_output}" + DEPENDS "${secret_au_plugindefines}" + VERBATIM) + + set(au_resource_directory "$<TARGET_BUNDLE_DIR:${au_target}>/Contents/Resources") +endfunction() + +# ================================================================================================== + +# Takes a target, a link visibility, and a variable-length list of framework +# names. On macOS, finds the requested frameworks using `find_library` and +# links them. On iOS, links directly with `-framework Name`. +function(_juce_link_frameworks target visibility) + foreach(framework IN LISTS ARGN) + if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + find_library("juce_found_${framework}" "${framework}" REQUIRED) + target_link_libraries("${target}" "${visibility}" "${juce_found_${framework}}") + elseif(CMAKE_SYSTEM_NAME STREQUAL "iOS") + target_link_libraries("${target}" "${visibility}" "-framework ${framework}") + endif() + endforeach() +endfunction() + +# ================================================================================================== + +function(_juce_add_plugin_wrapper_target) + set(one_value_args FORMAT PATH OUT_PATH INSTALL_EXPORT) + cmake_parse_arguments(JUCE_ARG "" "${one_value_args}" "" ${ARGN}) + + _juce_module_sources("${JUCE_ARG_PATH}" "${JUCE_ARG_OUT_PATH}" out_var) + list(FILTER out_var EXCLUDE REGEX "/juce_audio_plugin_client_utils.cpp$") + set(target_name juce_audio_plugin_client_${JUCE_ARG_FORMAT}) + + _juce_add_interface_library("${target_name}" ${out_var}) + _juce_add_plugin_definitions("${target_name}" INTERFACE ${JUCE_ARG_FORMAT}) + _juce_add_standard_defs("${target_name}") + + target_compile_features("${target_name}" INTERFACE cxx_std_11) + add_library("juce::${target_name}" ALIAS "${target_name}") + + install(TARGETS "${target_name}" EXPORT "${JUCE_ARG_INSTALL_EXPORT}") + + if(JUCE_ARG_FORMAT STREQUAL "AUv3") + _juce_link_frameworks("${target_name}" INTERFACE AVFoundation) + + if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + _juce_link_frameworks("${target_name}" INTERFACE AudioUnit) + endif() + elseif(JUCE_ARG_FORMAT STREQUAL "AU") + _juce_link_frameworks("${target_name}" INTERFACE AudioUnit CoreAudioKit) + endif() +endfunction() + +# ================================================================================================== + +function(_juce_link_libs_from_metadata module_name dict key) + _juce_get_metadata("${dict}" "${key}" libs) + + if(libs) + target_link_libraries(${module_name} INTERFACE ${libs}) + endif() +endfunction() + +# ================================================================================================== + +function(juce_add_module module_path) + set(one_value_args INSTALL_PATH ALIAS_NAMESPACE) + cmake_parse_arguments(JUCE_ARG "" "${one_value_args}" "" ${ARGN}) + + _juce_make_absolute(module_path) + + get_filename_component(module_name ${module_path} NAME) + get_filename_component(module_parent_path ${module_path} DIRECTORY) + + set(module_header_name "${module_name}.h") + + if(NOT EXISTS "${module_path}/${module_header_name}") + set(module_header_name "${module_header_name}pp") + endif() + + if(NOT EXISTS "${module_path}/${module_header_name}") + message(FATAL_ERROR "Could not locate module header for module '${module_path}'") + endif() + + set(base_path "${module_parent_path}") + + list(APPEND all_module_sources "${base_path}/${module_name}/${module_header_name}") + + if(${module_name} STREQUAL "juce_audio_plugin_client") + _juce_get_platform_plugin_kinds(plugin_kinds) + + foreach(kind IN LISTS plugin_kinds) + _juce_add_plugin_wrapper_target(FORMAT ${kind} + PATH "${module_path}" + OUT_PATH "${base_path}") + endforeach() + + set(utils_source + "${base_path}/${module_name}/juce_audio_plugin_client_utils.cpp") + add_library(juce_audio_plugin_client_utils INTERFACE) + target_sources(juce_audio_plugin_client_utils INTERFACE "${utils_source}") + + if(JUCE_ARG_ALIAS_NAMESPACE) + add_library(${JUCE_ARG_ALIAS_NAMESPACE}::juce_audio_plugin_client_utils + ALIAS juce_audio_plugin_client_utils) + endif() + else() + _juce_module_sources("${module_path}" "${base_path}" globbed_sources) + list(APPEND all_module_sources ${globbed_sources}) + endif() + + _juce_add_interface_library(${module_name} ${all_module_sources}) + + if(${module_name} STREQUAL "juce_core") + _juce_add_standard_defs(${module_name}) + + target_link_libraries(juce_core INTERFACE juce::juce_atomic_wrapper) + + if(CMAKE_SYSTEM_NAME STREQUAL "Android") + target_sources(juce_core INTERFACE "${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c") + target_include_directories(juce_core INTERFACE "${ANDROID_NDK}/sources/android/cpufeatures") + target_link_libraries(juce_core INTERFACE android log) + endif() + endif() + + if(${module_name} STREQUAL "juce_audio_processors") + add_library(juce_vst3_headers INTERFACE) + target_include_directories(juce_vst3_headers INTERFACE + "${base_path}/juce_audio_processors/format_types/VST3_SDK") + target_link_libraries(juce_audio_processors INTERFACE juce_vst3_headers) + + if(JUCE_ARG_ALIAS_NAMESPACE) + add_library(${JUCE_ARG_ALIAS_NAMESPACE}::juce_vst3_headers ALIAS juce_vst3_headers) + endif() + endif() + + target_include_directories(${module_name} INTERFACE ${base_path}) + + target_compile_definitions(${module_name} INTERFACE JUCE_MODULE_AVAILABLE_${module_name}=1) + + if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + target_compile_definitions(${module_name} INTERFACE LINUX=1) + endif() + + _juce_extract_metadata_block(JUCE_MODULE_DECLARATION "${module_path}/${module_header_name}" metadata_dict) + + _juce_get_metadata("${metadata_dict}" minimumCppStandard module_cpp_standard) + + if(module_cpp_standard) + target_compile_features(${module_name} INTERFACE cxx_std_${module_cpp_standard}) + else() + target_compile_features(${module_name} INTERFACE cxx_std_11) + endif() + + if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + _juce_get_metadata("${metadata_dict}" OSXFrameworks module_osxframeworks) + + foreach(module_framework IN LISTS module_osxframeworks) + if(module_framework STREQUAL "") + continue() + endif() + + _juce_link_frameworks("${module_name}" INTERFACE "${module_framework}") + endforeach() + + _juce_link_libs_from_metadata("${module_name}" "${metadata_dict}" OSXLibs) + elseif(CMAKE_SYSTEM_NAME STREQUAL "iOS") + _juce_get_metadata("${metadata_dict}" iOSFrameworks module_iosframeworks) + + foreach(module_framework IN LISTS module_iosframeworks) + if(module_framework STREQUAL "") + continue() + endif() + + _juce_link_frameworks("${module_name}" INTERFACE "${module_framework}") + endforeach() + + _juce_link_libs_from_metadata("${module_name}" "${metadata_dict}" iOSLibs) + elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") + _juce_get_metadata("${metadata_dict}" linuxPackages module_linuxpackages) + + if(module_linuxpackages) + _juce_create_pkgconfig_target(${module_name}_LINUX_DEPS ${module_linuxpackages}) + target_link_libraries(${module_name} INTERFACE juce::pkgconfig_${module_name}_LINUX_DEPS) + endif() + + _juce_link_libs_from_metadata("${module_name}" "${metadata_dict}" linuxLibs) + elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows") + if((CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") OR (CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC")) + if(module_name STREQUAL "juce_gui_basics") + target_compile_options(${module_name} INTERFACE /bigobj) + endif() + + _juce_link_libs_from_metadata("${module_name}" "${metadata_dict}" windowsLibs) + elseif(MSYS OR MINGW) + if(module_name STREQUAL "juce_gui_basics") + target_compile_options(${module_name} INTERFACE "-Wa,-mbig-obj") + endif() + + _juce_link_libs_from_metadata("${module_name}" "${metadata_dict}" mingwLibs) + endif() + endif() + + _juce_get_metadata("${metadata_dict}" dependencies module_dependencies) + target_link_libraries(${module_name} INTERFACE ${module_dependencies}) + + _juce_get_metadata("${metadata_dict}" searchpaths module_searchpaths) + + if(NOT module_searchpaths STREQUAL "") + foreach(module_searchpath IN LISTS module_searchpaths) + target_include_directories(${module_name} + INTERFACE "${module_path}/${module_searchpath}") + endforeach() + endif() + + if(JUCE_ARG_INSTALL_PATH) + install(DIRECTORY "${module_path}" DESTINATION "${JUCE_ARG_INSTALL_PATH}") + endif() + + if(JUCE_ARG_ALIAS_NAMESPACE) + add_library(${JUCE_ARG_ALIAS_NAMESPACE}::${module_name} ALIAS ${module_name}) + endif() + + if(JUCE_ENABLE_MODULE_SOURCE_GROUPS) + file(GLOB_RECURSE extra_files LIST_DIRECTORIES FALSE "${module_path}/*") + add_custom_target(${module_name}_sources SOURCES ${extra_files}) + set_target_properties(${module_name}_sources PROPERTIES FOLDER Modules) + source_group(TREE "${module_path}" FILES ${extra_files}) + endif() +endfunction() + +function(juce_add_modules) + set(one_value_args INSTALL_PATH ALIAS_NAMESPACE) + cmake_parse_arguments(JUCE_ARG "" "${one_value_args}" "" ${ARGN}) + + foreach(path IN LISTS JUCE_ARG_UNPARSED_ARGUMENTS) + juce_add_module(${path} + INSTALL_PATH "${JUCE_ARG_INSTALL_PATH}" + ALIAS_NAMESPACE "${JUCE_ARG_ALIAS_NAMESPACE}") + endforeach() +endfunction() + +# ================================================================================================== + +# Ideally, we'd check the preprocessor defs on the target to see whether +# JUCE_USE_CURL, JUCE_WEB_BROWSER, or JUCE_IN_APP_PURCHASES have been explicitly turned off, +# and then link libraries as appropriate. +# Unfortunately, this doesn't work, because linking a new library (curl/webkit/StoreKit) +# updates the target's compile defs, which results in a recursion/circular-dependency. +# Instead, we ask the user to explicitly request curl/webkit/StoreKit linking if they +# know they need it. Otherwise, we won't link anything. +# See the NEEDS_CURL, NEEDS_WEB_BROWSER, and NEEDS_STORE_KIT options in the CMake/readme.md. +function(_juce_link_optional_libraries target) + if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + get_target_property(needs_curl ${target} JUCE_NEEDS_CURL) + + if(needs_curl) + target_link_libraries(${target} PRIVATE juce::pkgconfig_JUCE_CURL_LINUX_DEPS) + endif() + + get_target_property(needs_browser ${target} JUCE_NEEDS_WEB_BROWSER) + + if(needs_browser) + target_link_libraries(${target} PRIVATE juce::pkgconfig_JUCE_BROWSER_LINUX_DEPS) + endif() + elseif(APPLE) + get_target_property(needs_storekit ${target} JUCE_NEEDS_STORE_KIT) + + if(needs_storekit) + _juce_link_frameworks("${target}" PRIVATE StoreKit) + endif() + + get_target_property(needs_camera ${target} JUCE_CAMERA_PERMISSION_ENABLED) + + if(CMAKE_SYSTEM_NAME STREQUAL "iOS" AND needs_camera) + _juce_link_frameworks("${target}" PRIVATE ImageIO) + endif() + endif() +endfunction() + +# ================================================================================================== + +function(_juce_get_module_definitions target filter out_var) + set(compile_defs $<TARGET_GENEX_EVAL:${target},$<TARGET_PROPERTY:${target},COMPILE_DEFINITIONS>>) + + if(filter) + set(${out_var} $<FILTER:${compile_defs},EXCLUDE,JucePlugin_Build_|JUCE_SHARED_CODE> PARENT_SCOPE) + else() + set(${out_var} ${compile_defs} PARENT_SCOPE) + endif() +endfunction() + +function(_juce_append_record output key) + string(ASCII 30 RS) + string(ASCII 31 US) + set(${output} "${${output}}${key}${US}${ARGN}${RS}" PARENT_SCOPE) +endfunction() + +function(_juce_append_target_property output key target property) + get_target_property(prop ${target} ${property}) + + if(prop STREQUAL "prop-NOTFOUND") + set(prop) + endif() + + _juce_append_record(${output} ${key} ${prop}) + set(${output} "${${output}}" PARENT_SCOPE) +endfunction() + +# This is all info that should be known at configure time (i.e. no generator expressions here!) +# We use this info to generate plists and entitlements files, also at configure time. +function(_juce_write_configure_time_info target) + _juce_append_target_property(file_content EXECUTABLE_NAME ${target} JUCE_PRODUCT_NAME) + _juce_append_target_property(file_content VERSION ${target} JUCE_VERSION) + _juce_append_target_property(file_content PLIST_TO_MERGE ${target} JUCE_PLIST_TO_MERGE) + _juce_append_target_property(file_content BUNDLE_ID ${target} JUCE_BUNDLE_ID) + _juce_append_target_property(file_content XCODE_EXTRA_PLIST_ENTRIES ${target} JUCE_XCODE_EXTRA_PLIST_ENTRIES) + _juce_append_target_property(file_content MICROPHONE_PERMISSION_ENABLED ${target} JUCE_MICROPHONE_PERMISSION_ENABLED) + _juce_append_target_property(file_content MICROPHONE_PERMISSION_TEXT ${target} JUCE_MICROPHONE_PERMISSION_TEXT) + _juce_append_target_property(file_content CAMERA_PERMISSION_ENABLED ${target} JUCE_CAMERA_PERMISSION_ENABLED) + _juce_append_target_property(file_content CAMERA_PERMISSION_TEXT ${target} JUCE_CAMERA_PERMISSION_TEXT) + _juce_append_target_property(file_content BLUETOOTH_PERMISSION_ENABLED ${target} JUCE_BLUETOOTH_PERMISSION_ENABLED) + _juce_append_target_property(file_content BLUETOOTH_PERMISSION_TEXT ${target} JUCE_BLUETOOTH_PERMISSION_TEXT) + _juce_append_target_property(file_content SEND_APPLE_EVENTS_PERMISSION_ENABLED ${target} JUCE_SEND_APPLE_EVENTS_PERMISSION_ENABLED) + _juce_append_target_property(file_content SEND_APPLE_EVENTS_PERMISSION_TEXT ${target} JUCE_SEND_APPLE_EVENTS_PERMISSION_TEXT) + _juce_append_target_property(file_content SHOULD_ADD_STORYBOARD ${target} JUCE_SHOULD_ADD_STORYBOARD) + _juce_append_target_property(file_content LAUNCH_STORYBOARD_FILE ${target} JUCE_LAUNCH_STORYBOARD_FILE) + _juce_append_target_property(file_content ICON_FILE ${target} JUCE_ICON_FILE) + _juce_append_target_property(file_content PROJECT_NAME ${target} JUCE_PRODUCT_NAME) + _juce_append_target_property(file_content COMPANY_COPYRIGHT ${target} JUCE_COMPANY_COPYRIGHT) + _juce_append_target_property(file_content COMPANY_NAME ${target} JUCE_COMPANY_NAME) + _juce_append_target_property(file_content DOCUMENT_EXTENSIONS ${target} JUCE_DOCUMENT_EXTENSIONS) + _juce_append_target_property(file_content FILE_SHARING_ENABLED ${target} JUCE_FILE_SHARING_ENABLED) + _juce_append_target_property(file_content DOCUMENT_BROWSER_ENABLED ${target} JUCE_DOCUMENT_BROWSER_ENABLED) + _juce_append_target_property(file_content STATUS_BAR_HIDDEN ${target} JUCE_STATUS_BAR_HIDDEN) + _juce_append_target_property(file_content BACKGROUND_AUDIO_ENABLED ${target} JUCE_BACKGROUND_AUDIO_ENABLED) + _juce_append_target_property(file_content BACKGROUND_BLE_ENABLED ${target} JUCE_BACKGROUND_BLE_ENABLED) + _juce_append_target_property(file_content PUSH_NOTIFICATIONS_ENABLED ${target} JUCE_PUSH_NOTIFICATIONS_ENABLED) + _juce_append_target_property(file_content PLUGIN_MANUFACTURER_CODE ${target} JUCE_PLUGIN_MANUFACTURER_CODE) + _juce_append_target_property(file_content PLUGIN_CODE ${target} JUCE_PLUGIN_CODE) + _juce_append_target_property(file_content IPHONE_SCREEN_ORIENTATIONS ${target} JUCE_IPHONE_SCREEN_ORIENTATIONS) + _juce_append_target_property(file_content IPAD_SCREEN_ORIENTATIONS ${target} JUCE_IPAD_SCREEN_ORIENTATIONS) + _juce_append_target_property(file_content PLUGIN_NAME ${target} JUCE_PLUGIN_NAME) + _juce_append_target_property(file_content PLUGIN_MANUFACTURER ${target} JUCE_COMPANY_NAME) + _juce_append_target_property(file_content PLUGIN_DESCRIPTION ${target} JUCE_DESCRIPTION) + _juce_append_target_property(file_content PLUGIN_AU_EXPORT_PREFIX ${target} JUCE_AU_EXPORT_PREFIX) + _juce_append_target_property(file_content PLUGIN_AU_MAIN_TYPE ${target} JUCE_AU_MAIN_TYPE_CODE) + _juce_append_target_property(file_content IS_AU_SANDBOX_SAFE ${target} JUCE_AU_SANDBOX_SAFE) + _juce_append_target_property(file_content IS_PLUGIN_SYNTH ${target} JUCE_IS_SYNTH) + _juce_append_target_property(file_content SUPPRESS_AU_PLIST_RESOURCE_USAGE ${target} JUCE_SUPPRESS_AU_PLIST_RESOURCE_USAGE) + _juce_append_target_property(file_content HARDENED_RUNTIME_ENABLED ${target} JUCE_HARDENED_RUNTIME_ENABLED) + _juce_append_target_property(file_content APP_SANDBOX_ENABLED ${target} JUCE_APP_SANDBOX_ENABLED) + _juce_append_target_property(file_content APP_SANDBOX_INHERIT ${target} JUCE_APP_SANDBOX_INHERIT) + _juce_append_target_property(file_content HARDENED_RUNTIME_OPTIONS ${target} JUCE_HARDENED_RUNTIME_OPTIONS) + _juce_append_target_property(file_content APP_SANDBOX_OPTIONS ${target} JUCE_APP_SANDBOX_OPTIONS) + _juce_append_target_property(file_content APP_GROUPS_ENABLED ${target} JUCE_APP_GROUPS_ENABLED) + _juce_append_target_property(file_content APP_GROUP_IDS ${target} JUCE_APP_GROUP_IDS) + _juce_append_target_property(file_content IS_PLUGIN ${target} JUCE_IS_PLUGIN) + _juce_append_target_property(file_content ICLOUD_PERMISSIONS_ENABLED ${target} JUCE_ICLOUD_PERMISSIONS_ENABLED) + + if(CMAKE_SYSTEM_NAME STREQUAL "iOS") + _juce_append_record(file_content IS_IOS 1) + else() + _juce_append_record(file_content IS_IOS 0) + endif() + + get_target_property(juce_library_code ${target} JUCE_GENERATED_SOURCES_DIRECTORY) + + set(info_file "${juce_library_code}/Info.txt") + file(WRITE "${info_file}" "${file_content}") + set_target_properties(${target} PROPERTIES JUCE_INFO_FILE "${info_file}") +endfunction() + +# In this file, we put things that CMake is only able to divine at generate time, like preprocessor definitions. +# We use the target preprocessor definitions to work out which JUCE modules should go in the JuceHeader.h. +function(_juce_write_generate_time_info target) + _juce_get_module_definitions(${target} OFF module_defs) + _juce_append_record(defs MODULE_DEFINITIONS ${module_defs}) + + _juce_append_target_property(defs EXECUTABLE_NAME ${target} JUCE_PRODUCT_NAME) + _juce_append_target_property(defs PROJECT_NAME ${target} JUCE_PRODUCT_NAME) + _juce_append_target_property(defs VERSION ${target} JUCE_VERSION) + _juce_append_target_property(defs COMPANY_NAME ${target} JUCE_COMPANY_NAME) + + get_target_property(juce_library_code ${target} JUCE_GENERATED_SOURCES_DIRECTORY) + + set(defs_file "${juce_library_code}/$<CONFIG>/Defs.txt") + file(GENERATE OUTPUT "${defs_file}" CONTENT "${defs}") + set_target_properties(${target} PROPERTIES JUCE_DEFS_FILE "${defs_file}") +endfunction() + +# ================================================================================================== + +function(juce_add_binary_data target) + set(one_value_args NAMESPACE HEADER_NAME) + set(multi_value_args SOURCES) + cmake_parse_arguments(JUCE_ARG "" "${one_value_args}" "${multi_value_args}" ${ARGN}) + + list(LENGTH JUCE_ARG_SOURCES num_binary_files) + + if(${num_binary_files} LESS 1) + message(FATAL_ERROR "juce_add_binary_data must be passed at least one file to encode") + endif() + + add_library(${target} STATIC) + + set(juce_binary_data_folder "${CMAKE_CURRENT_BINARY_DIR}/juce_binarydata_${target}/JuceLibraryCode") + + set(binary_file_names) + + foreach(index RANGE 1 ${num_binary_files}) + list(APPEND binary_file_names "${juce_binary_data_folder}/BinaryData${index}.cpp") + endforeach() + + file(MAKE_DIRECTORY ${juce_binary_data_folder}) + + if(NOT JUCE_ARG_NAMESPACE) + set(JUCE_ARG_NAMESPACE BinaryData) + endif() + + if(NOT JUCE_ARG_HEADER_NAME) + set(JUCE_ARG_HEADER_NAME BinaryData.h) + endif() + + list(APPEND binary_file_names "${juce_binary_data_folder}/${JUCE_ARG_HEADER_NAME}") + + add_custom_command(OUTPUT ${binary_file_names} + COMMAND juce::juceaide binarydata "${JUCE_ARG_NAMESPACE}" "${JUCE_ARG_HEADER_NAME}" + ${juce_binary_data_folder} ${JUCE_ARG_SOURCES} + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} + DEPENDS ${JUCE_ARG_SOURCES} + VERBATIM) + + target_sources(${target} PRIVATE "${binary_file_names}") + target_include_directories(${target} INTERFACE ${juce_binary_data_folder}) + target_compile_features(${target} PRIVATE cxx_std_11) + + if(JUCE_ARG_HEADER_NAME STREQUAL "BinaryData.h") + target_compile_definitions(${target} INTERFACE JUCE_TARGET_HAS_BINARY_DATA=1) + endif() +endfunction() + +# ================================================================================================== + +# math(EXPR ... OUTPUT_FORMAT HEXADECIMAL) wasn't added until 3.13, but we need 3.12 for vcpkg +# compatibility +function(_juce_dec_to_hex num out_var) + while(num) + math(EXPR digit "${num} % 16") + math(EXPR num "${num} / 16") + + if(digit GREATER_EQUAL 10) + math(EXPR ascii_code "${digit} + 55") + string(ASCII "${ascii_code}" digit) + endif() + + set(result "${digit}${result}") + endwhile() + + set(${out_var} "${result}" PARENT_SCOPE) +endfunction() + +function(_juce_version_code version_in out_var) + string(REGEX REPLACE "\\." ";" version_list ${version_in}) + list(LENGTH version_list num_version_components) + + set(version_major 0) + set(version_minor 0) + set(version_patch 0) + + if(num_version_components GREATER 0) + list(GET version_list 0 version_major) + endif() + + if(num_version_components GREATER 1) + list(GET version_list 1 version_minor) + endif() + + if(num_version_components GREATER 2) + list(GET version_list 2 version_patch) + endif() + + math(EXPR decimal "(${version_major} << 16) + (${version_minor} << 8) + ${version_patch}") + _juce_dec_to_hex(${decimal} hex) + set(${out_var} "${hex}" PARENT_SCOPE) +endfunction() + +function(_juce_to_char_literal str out_var) + string(APPEND str " ") # Make sure there are at least 4 characters in the string. + + # Round-tripping through a file is the simplest way to convert a string to hex... + string(SUBSTRING "${str}" 0 4 four_chars) + string(RANDOM LENGTH 16 random_string) + set(scratch_file "${CMAKE_CURRENT_BINARY_DIR}/${random_string}_ascii_conversion.txt") + + file(WRITE "${scratch_file}" "${four_chars}") + file(READ "${scratch_file}" four_chars_hex HEX) + file(REMOVE "${scratch_file}") + + set(${out_var} ${four_chars_hex} PARENT_SCOPE) +endfunction() + +# ================================================================================================== + +function(juce_generate_juce_header target) + get_target_property(juce_library_code ${target} JUCE_GENERATED_SOURCES_DIRECTORY) + + if(NOT juce_library_code) + message(FATAL_ERROR "Target ${target} does not have a generated sources directory. Ensure it was created with a juce_add_* function") + endif() + + set(juce_header ${juce_library_code}/JuceHeader.h) + target_sources(${target} PRIVATE ${juce_header}) + + set(defs_file $<GENEX_EVAL:$<TARGET_PROPERTY:${target},JUCE_DEFS_FILE>>) + + set(extra_args) + + add_custom_command(OUTPUT "${juce_header}" + COMMAND juce::juceaide header "${defs_file}" "${juce_header}" ${extra_args} + DEPENDS "${defs_file}" + VERBATIM) +endfunction() + +# ================================================================================================== + +function(_juce_execute_juceaide) + if(NOT TARGET juce::juceaide) + message(FATAL_ERROR "The juceaide target does not exist") + endif() + + get_target_property(juceaide_location juce::juceaide IMPORTED_LOCATION) + + if(NOT EXISTS "${juceaide_location}") + message(FATAL_ERROR "juceaide was imported, but it doesn't exist!") + endif() + + execute_process(COMMAND "${juceaide_location}" ${ARGN} RESULT_VARIABLE result_variable) + + if(result_variable) + message(FATAL_ERROR "Running juceaide failed") + endif() +endfunction() + +function(_juce_set_output_name target name) + if(NOT CMAKE_SYSTEM_NAME STREQUAL "Android") + set_target_properties(${target} PROPERTIES + OUTPUT_NAME ${name} + XCODE_ATTRIBUTE_PRODUCT_NAME ${name}) + endif() +endfunction() + +function(_juce_generate_icon source_target dest_target) + get_target_property(juce_library_code ${source_target} JUCE_GENERATED_SOURCES_DIRECTORY) + get_target_property(juce_property_icon_big ${source_target} JUCE_ICON_BIG) + get_target_property(juce_property_icon_small ${source_target} JUCE_ICON_SMALL) + + if(NOT (juce_property_icon_big OR juce_property_icon_small)) + return() + endif() + + set(icon_args) + + if(juce_property_icon_big) + list(APPEND icon_args "${juce_property_icon_big}") + endif() + + if(juce_property_icon_small) + list(APPEND icon_args "${juce_property_icon_small}") + endif() + + set(generated_icon) + + if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + set(generated_icon "${juce_library_code}/Icon.icns") + # To get compiled properly, we need the icon before the plist is generated! + _juce_execute_juceaide(macicon "${generated_icon}" ${icon_args}) + set_source_files_properties(${generated_icon} PROPERTIES MACOSX_PACKAGE_LOCATION Resources) + elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows") + set(generated_icon "${juce_library_code}/icon.ico") + _juce_execute_juceaide(winicon "${generated_icon}" ${icon_args}) + elseif(CMAKE_SYSTEM_NAME STREQUAL "iOS") + get_target_property(generated_icon ${source_target} JUCE_CUSTOM_XCASSETS_FOLDER) + + if(NOT generated_icon) + set(out_path "${juce_library_code}/${dest_target}") + set(generated_icon "${out_path}/Images.xcassets") + + # To get compiled properly, we need iOS assets at configure time! + _juce_execute_juceaide(iosassets "${out_path}" ${icon_args}) + endif() + + set_target_properties(${dest_target} PROPERTIES + XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_APPICON_NAME "AppIcon") + + get_target_property(add_storyboard ${source_target} JUCE_SHOULD_ADD_STORYBOARD) + + if(NOT add_storyboard) + set_target_properties(${dest_target} PROPERTIES + XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME "LaunchImage") + endif() + endif() + + if(generated_icon) + target_sources(${dest_target} PRIVATE ${generated_icon}) + set_target_properties(${source_target} ${dest_target} PROPERTIES + JUCE_ICON_FILE "${generated_icon}" + RESOURCE "${generated_icon}") + endif() +endfunction() + +function(_juce_add_xcode_entitlements source_target dest_target) + get_target_property(juce_kind_string ${dest_target} JUCE_TARGET_KIND_STRING) + get_target_property(input_info_file ${source_target} JUCE_INFO_FILE) + + get_target_property(juce_library_code ${source_target} JUCE_GENERATED_SOURCES_DIRECTORY) + set(entitlements_file "${juce_library_code}/${dest_target}.entitlements") + + _juce_execute_juceaide(entitlements "${juce_kind_string}" "${input_info_file}" "${entitlements_file}") + set_target_properties(${dest_target} PROPERTIES + XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${entitlements_file}") +endfunction() + +function(_juce_configure_bundle source_target dest_target) + _juce_generate_icon(${source_target} ${dest_target}) + _juce_write_configure_time_info(${source_target}) + + if(NOT APPLE) + return() + endif() + + get_target_property(generated_icon ${source_target} JUCE_ICON_FILE) + set(icon_dependency) + + if(generated_icon) + set(icon_dependency "${generated_icon}") + endif() + + get_target_property(juce_library_code ${source_target} JUCE_GENERATED_SOURCES_DIRECTORY) + get_target_property(input_info_file ${source_target} JUCE_INFO_FILE) + + set(this_output_info_dir "${juce_library_code}/${dest_target}") + set(this_output_pkginfo "${this_output_info_dir}/PkgInfo") + set(this_output_plist "${this_output_info_dir}/Info.plist") + + get_target_property(juce_kind_string ${dest_target} JUCE_TARGET_KIND_STRING) + + _juce_execute_juceaide(plist "${juce_kind_string}" "${input_info_file}" "${this_output_plist}") + set_target_properties(${dest_target} PROPERTIES + BUNDLE TRUE + MACOSX_BUNDLE_INFO_PLIST "${this_output_plist}") + + add_custom_command(OUTPUT "${this_output_pkginfo}" + COMMAND juce::juceaide pkginfo "${juce_kind_string}" "${this_output_pkginfo}" + VERBATIM) + + set(output_folder "$<TARGET_BUNDLE_CONTENT_DIR:${dest_target}>") + + target_sources(${dest_target} PRIVATE "${this_output_pkginfo}") + set_source_files_properties("${this_output_pkginfo}" PROPERTIES + HEADER_FILE_ONLY TRUE + GENERATED TRUE) + add_custom_command(TARGET ${dest_target} POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E copy "${this_output_pkginfo}" "${output_folder}" + DEPENDS "${this_output_pkginfo}" + VERBATIM) + + _juce_add_xcode_entitlements(${source_target} ${dest_target}) + + if(CMAKE_SYSTEM_NAME STREQUAL "iOS") + get_target_property(add_storyboard ${source_target} JUCE_SHOULD_ADD_STORYBOARD) + + if(add_storyboard) + get_target_property(storyboard_file ${source_target} JUCE_LAUNCH_STORYBOARD_FILE) + + if(NOT EXISTS "${storyboard_file}") + message(FATAL_ERROR "Could not find storyboard file: ${storyboard_file}") + endif() + + target_sources(${dest_target} PRIVATE "${storyboard_file}") + set_property(TARGET ${dest_target} APPEND PROPERTY RESOURCE "${storyboard_file}") + endif() + endif() + + set_target_properties(${dest_target} PROPERTIES + XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME + $<TARGET_PROPERTY:${source_target},JUCE_HARDENED_RUNTIME_ENABLED>) + + if(juce_kind_string STREQUAL "AUv3 AppExtension") + get_target_property(source_bundle_id ${source_target} JUCE_BUNDLE_ID) + + if(source_bundle_id MATCHES "\\.([^.]+)$") + set_target_properties(${dest_target} PROPERTIES + XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER + "${source_bundle_id}.${CMAKE_MATCH_1}AUv3") + else() + message(FATAL_ERROR "Bundle ID should contain at least one `.`!") + endif() + else() + set_target_properties(${dest_target} PROPERTIES + XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER + $<TARGET_PROPERTY:${source_target},JUCE_BUNDLE_ID>) + endif() +endfunction() + +function(_juce_add_resources_rc source_target dest_target) + if(NOT CMAKE_SYSTEM_NAME STREQUAL "Windows") + return() + endif() + + get_target_property(juce_library_code ${source_target} JUCE_GENERATED_SOURCES_DIRECTORY) + set(input_info_file "$<TARGET_PROPERTY:${source_target},JUCE_INFO_FILE>") + + get_target_property(generated_icon ${source_target} JUCE_ICON_FILE) + set(dependency) + + if(generated_icon) + set(dependency DEPENDS "${generated_icon}") + endif() + + set(resource_rc_file "${juce_library_code}/resources.rc") + + add_custom_command(OUTPUT "${resource_rc_file}" + COMMAND juce::juceaide rcfile "${input_info_file}" "${resource_rc_file}" + ${dependency} + VERBATIM) + + target_sources(${dest_target} PRIVATE "${resource_rc_file}") +endfunction() + +function(_juce_configure_app_bundle source_target dest_target) + set_target_properties(${dest_target} PROPERTIES + JUCE_TARGET_KIND_STRING "App" + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE) + + _juce_add_resources_rc(${source_target} ${dest_target}) + + if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + set(nib_path "${JUCE_CMAKE_UTILS_DIR}/RecentFilesMenuTemplate.nib") + target_sources("${dest_target}" PRIVATE "${nib_path}") + set_source_files_properties("${nib_path}" PROPERTIES MACOSX_PACKAGE_LOCATION Resources) + endif() +endfunction() + +# ================================================================================================== + +function(_juce_create_windows_package source_target dest_target extension default_icon x32folder x64folder) + if(NOT CMAKE_SYSTEM_NAME STREQUAL "Windows") + return() + endif() + + get_target_property(products_folder ${dest_target} LIBRARY_OUTPUT_DIRECTORY) + + set(product_name $<TARGET_PROPERTY:${source_target},JUCE_PRODUCT_NAME>) + set(output_folder "${products_folder}/${product_name}.${extension}") + + set(is_x64 $<EQUAL:${CMAKE_SIZEOF_VOID_P},8>) + set(arch_string $<IF:${is_x64},${x64folder},${x32folder}>) + + set_target_properties(${dest_target} + PROPERTIES + LIBRARY_OUTPUT_DIRECTORY "${output_folder}/Contents/${arch_string}") + + get_target_property(icon_file ${source_target} JUCE_ICON_FILE) + + if(NOT icon_file) + set(icon_file "${default_icon}") + endif() + + if(icon_file) + set(desktop_ini "${output_folder}/desktop.ini") + set(plugin_ico "${output_folder}/Plugin.ico") + + file(GENERATE OUTPUT "${desktop_ini}" + CONTENT + "[.ShellClassInfo]\nIconResource=Plugin.ico,0\nIconFile=Plugin.ico\nIconIndex=0\n") + add_custom_command(TARGET ${dest_target} POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E copy "${icon_file}" "${plugin_ico}" + COMMAND attrib +s "${desktop_ini}" + COMMAND attrib +s "${output_folder}" + DEPENDS "${icon_file}" "${desktop_ini}" + VERBATIM) + endif() +endfunction() + +# ================================================================================================== + +function(_juce_add_unity_plugin_prefix_if_necessary name out_var) + string(TOLOWER "${name}" lower) + + if(NOT lower MATCHES "^audioplugin") + set(${out_var} "audioplugin_${name}" PARENT_SCOPE) + else() + set(${out_var} "${name}" PARENT_SCOPE) + endif() +endfunction() + +function(_juce_add_unity_script_file shared_target out_var) + set(script_in "${JUCE_CMAKE_UTILS_DIR}/UnityPluginGUIScript.cs.in") + + get_target_property(plugin_name ${shared_target} JUCE_PLUGIN_NAME) + get_target_property(plugin_vendor ${shared_target} JUCE_COMPANY_NAME) + get_target_property(plugin_description ${shared_target} JUCE_DESCRIPTION) + + string(REGEX REPLACE " +" "_" plugin_class_name "${plugin_name}") + + get_target_property(juce_library_code ${shared_target} JUCE_GENERATED_SOURCES_DIRECTORY) + _juce_add_unity_plugin_prefix_if_necessary("${plugin_name}" script_prefix) + set(script_out "${juce_library_code}/${script_prefix}_UnityScript.cs") + configure_file(${script_in} ${script_out}) + set(${out_var} "${script_out}" PARENT_SCOPE) +endfunction() + +# ================================================================================================== + +function(_juce_copy_dir target from to) + # This is a shim to make CMake copy a whole directory, rather than just + # the contents of a directory + add_custom_command(TARGET ${target} POST_BUILD + COMMAND "${CMAKE_COMMAND}" + "-Dsrc=${from}" + "-Ddest=${to}" + "-P" "${JUCE_CMAKE_UTILS_DIR}/copyDir.cmake" + VERBATIM) +endfunction() + +function(_juce_copy_after_build shared_code target from to) + get_target_property(wants_copy ${shared_code} JUCE_COPY_PLUGIN_AFTER_BUILD) + + if(wants_copy) + get_target_property(dest ${shared_code} ${to}) + + if(NOT dest) + message(FATAL_ERROR "Target '${target}' wants to be copied, but its property '${to}' is not set") + endif() + + _juce_copy_dir(${target} "${from}" "$<GENEX_EVAL:$<TARGET_PROPERTY:${shared_code},${to}>>") + endif() +endfunction() + +function(_juce_set_plugin_target_properties shared_code_target kind) + set(target_name ${shared_code_target}_${kind}) + + set_target_properties(${target_name} PROPERTIES + ARCHIVE_OUTPUT_DIRECTORY "$<GENEX_EVAL:$<TARGET_PROPERTY:${shared_code_target},ARCHIVE_OUTPUT_DIRECTORY>>/${kind}" + LIBRARY_OUTPUT_DIRECTORY "$<GENEX_EVAL:$<TARGET_PROPERTY:${shared_code_target},LIBRARY_OUTPUT_DIRECTORY>>/${kind}" + RUNTIME_OUTPUT_DIRECTORY "$<GENEX_EVAL:$<TARGET_PROPERTY:${shared_code_target},RUNTIME_OUTPUT_DIRECTORY>>/${kind}") + + get_target_property(products_folder ${target_name} LIBRARY_OUTPUT_DIRECTORY) + set(product_name $<TARGET_PROPERTY:${shared_code_target},JUCE_PRODUCT_NAME>) + + if(kind STREQUAL "VST3") + set_target_properties(${target_name} PROPERTIES + BUNDLE_EXTENSION vst3 + PREFIX "" + SUFFIX .vst3 + BUNDLE TRUE + XCODE_ATTRIBUTE_WRAPPER_EXTENSION vst3 + XCODE_ATTRIBUTE_LIBRARY_STYLE Bundle + XCODE_ATTRIBUTE_GENERATE_PKGINFO_FILE YES) + + _juce_create_windows_package(${shared_code_target} ${target_name} vst3 "" x86-win x86_64-win) + + set(output_path "${products_folder}/${product_name}.vst3") + + if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + set_target_properties(${target_name} PROPERTIES + SUFFIX .so + LIBRARY_OUTPUT_DIRECTORY "${output_path}/Contents/${JUCE_LINUX_TARGET_ARCHITECTURE}-linux") + endif() + + _juce_copy_after_build(${shared_code_target} ${target_name} "${output_path}" JUCE_VST3_COPY_DIR) + elseif(kind STREQUAL "VST") + set_target_properties(${target_name} PROPERTIES + BUNDLE_EXTENSION vst + BUNDLE TRUE + XCODE_ATTRIBUTE_WRAPPER_EXTENSION vst + XCODE_ATTRIBUTE_LIBRARY_STYLE Bundle + XCODE_ATTRIBUTE_GENERATE_PKGINFO_FILE YES) + + set(output_path "$<TARGET_FILE:${target_name}>") + + if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + set(output_path "$<TARGET_BUNDLE_DIR:${target_name}>") + endif() + + _juce_copy_after_build(${shared_code_target} ${target_name} "${output_path}" JUCE_VST_COPY_DIR) + elseif(kind STREQUAL "AU") + set_target_properties(${target_name} PROPERTIES + BUNDLE_EXTENSION component + XCODE_ATTRIBUTE_WRAPPER_EXTENSION component + BUNDLE TRUE + XCODE_ATTRIBUTE_LIBRARY_STYLE Bundle + XCODE_ATTRIBUTE_GENERATE_PKGINFO_FILE YES) + + set(output_path "$<TARGET_BUNDLE_DIR:${target_name}>") + _juce_copy_after_build(${shared_code_target} ${target_name} "${output_path}" JUCE_AU_COPY_DIR) + elseif(kind STREQUAL "AUv3") + set_target_properties(${target_name} PROPERTIES + XCODE_PRODUCT_TYPE "com.apple.product-type.app-extension" + BUNDLE_EXTENSION appex + XCODE_ATTRIBUTE_WRAPPER_EXTENSION appex + XCODE_ATTRIBUTE_GENERATE_PKGINFO_FILE YES) + elseif(kind STREQUAL "AAX") + set_target_properties(${target_name} PROPERTIES + BUNDLE_EXTENSION aaxplugin + PREFIX "" + SUFFIX .aaxplugin + XCODE_ATTRIBUTE_WRAPPER_EXTENSION aaxplugin + BUNDLE TRUE + XCODE_ATTRIBUTE_LIBRARY_STYLE Bundle + XCODE_ATTRIBUTE_GENERATE_PKGINFO_FILE YES) + + get_target_property(default_icon juce_aax_sdk INTERFACE_JUCE_AAX_DEFAULT_ICON) + _juce_create_windows_package(${shared_code_target} ${target_name} aaxplugin "${default_icon}" Win32 x64) + + set(output_path "${products_folder}/${product_name}.aaxplugin") + _juce_copy_after_build(${shared_code_target} ${target_name} "${output_path}" JUCE_AAX_COPY_DIR) + elseif(kind STREQUAL "Unity") + set_target_properties(${target_name} PROPERTIES + BUNDLE_EXTENSION bundle + XCODE_ATTRIBUTE_WRAPPER_EXTENSION bundle + BUNDLE TRUE + XCODE_ATTRIBUTE_LIBRARY_STYLE Bundle + XCODE_ATTRIBUTE_GENERATE_PKGINFO_FILE YES) + + _juce_add_unity_script_file(${shared_code_target} script_file) + target_sources(${target_name} PRIVATE "${script_file}") + set_source_files_properties("${script_file}" PROPERTIES + GENERATED TRUE + MACOSX_PACKAGE_LOCATION Resources) + + if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + set(output_path "$<TARGET_BUNDLE_DIR:${target_name}>") + _juce_copy_after_build(${shared_code_target} ${target_name} "${output_path}" JUCE_UNITY_COPY_DIR) + else() + # On windows and linux, the gui script needs to be copied next to the unity output + add_custom_command(TARGET ${target_name} POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E copy "${script_file}" "${products_folder}" + DEPENDS "${script_file}" + VERBATIM) + + _juce_copy_after_build(${shared_code_target} + ${target_name} + "$<TARGET_FILE:${target_name}>" + JUCE_UNITY_COPY_DIR) + _juce_copy_after_build(${shared_code_target} + ${target_name} + "${script_file}" + JUCE_UNITY_COPY_DIR) + endif() + endif() +endfunction() + +# Place plugin wrapper targets alongside the shared code target in IDEs +function(_juce_set_plugin_folder_property shared_target wrapper_target) + get_target_property(folder_to_use "${shared_target}" FOLDER) + + if(folder_to_use STREQUAL "folder_to_use-NOTFOUND") + set_target_properties("${shared_target}" PROPERTIES FOLDER "${shared_target}") + elseif(NOT folder_to_use MATCHES ".*${shared_target}$") + set_target_properties("${shared_target}" PROPERTIES FOLDER "${folder_to_use}/${shared_target}") + endif() + + get_target_property(folder_to_use "${shared_target}" FOLDER) + set_target_properties("${wrapper_target}" PROPERTIES FOLDER "${folder_to_use}") +endfunction() + +# Convert the cmake plugin kind ids to strings understood by ProjectType::Target::typeFromName +function(_juce_get_plugin_kind_name kind out_var) + if(kind STREQUAL "AU") + set(${out_var} "AU" PARENT_SCOPE) + elseif(kind STREQUAL "AUv3") + set(${out_var} "AUv3 AppExtension" PARENT_SCOPE) + elseif(kind STREQUAL "AAX") + set(${out_var} "AAX" PARENT_SCOPE) + elseif(kind STREQUAL "Standalone") + set(${out_var} "Standalone Plugin" PARENT_SCOPE) + elseif(kind STREQUAL "Unity") + set(${out_var} "Unity Plugin" PARENT_SCOPE) + elseif(kind STREQUAL "VST") + set(${out_var} "VST" PARENT_SCOPE) + elseif(kind STREQUAL "VST3") + set(${out_var} "VST3" PARENT_SCOPE) + endif() +endfunction() + +function(_juce_link_plugin_wrapper shared_code_target kind) + set(target_name ${shared_code_target}_${kind}) + + if(CMAKE_SYSTEM_NAME STREQUAL "Android") + add_library(${target_name} SHARED) + elseif((kind STREQUAL "Standalone") OR (kind STREQUAL "AUv3")) + add_executable(${target_name} WIN32 MACOSX_BUNDLE) + else() + add_library(${target_name} MODULE) + endif() + + if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + target_link_libraries(${target_name} PRIVATE "-Wl,--no-undefined") + endif() + + # We re-export the shared code's private include dirs, because the wrapper targets need to + # see the module headers. We don't just link publicly, because that would introduce + # conflicting macro definitions. + target_include_directories(${target_name} PRIVATE + $<TARGET_PROPERTY:${shared_code_target},INCLUDE_DIRECTORIES>) + + target_link_libraries(${target_name} PRIVATE + ${shared_code_target} + juce::juce_audio_plugin_client_${kind}) + + _juce_set_output_name(${target_name} $<TARGET_PROPERTY:${shared_code_target},JUCE_PRODUCT_NAME>) + + _juce_set_plugin_folder_property("${shared_code_target}" "${target_name}") + + _juce_get_plugin_kind_name(${kind} juce_kind_string) + set_target_properties(${target_name} PROPERTIES + XCODE_ATTRIBUTE_CLANG_LINK_OBJC_RUNTIME NO + XCODE_ATTRIBUTE_COMBINE_HIDPI_IMAGES YES + POSITION_INDEPENDENT_CODE TRUE + VISIBILITY_INLINES_HIDDEN TRUE + C_VISIBILITY_PRESET hidden + CXX_VISIBILITY_PRESET hidden + JUCE_TARGET_KIND_STRING "${juce_kind_string}") + add_dependencies(${shared_code_target}_All ${target_name}) + + _juce_configure_bundle(${shared_code_target} ${target_name}) + _juce_set_plugin_target_properties(${shared_code_target} ${kind}) +endfunction() + +# ================================================================================================== + +function(_juce_get_vst3_category_string target out_var) + get_target_property(vst3_categories ${target} JUCE_VST3_CATEGORIES) + + if((NOT Fx IN_LIST vst3_categories) AND (NOT Instrument IN_LIST vst3_categories)) + get_target_property(is_synth ${target} JUCE_IS_SYNTH) + + if(is_synth) + set(first_type Instrument) + else() + set(first_type Fx) + endif() + + list(INSERT vst3_categories 0 ${first_type}) + else() + if(Instrument IN_LIST vst3_categories) + list(REMOVE_ITEM vst3_categories Instrument) + list(INSERT vst3_categories 0 Instrument) + endif() + + if(Fx IN_LIST vst3_categories) + list(REMOVE_ITEM vst3_categories Fx) + list(INSERT vst3_categories 0 Fx) + endif() + endif() + + string(REGEX REPLACE ";" "|" result "${vst3_categories}") + set(${out_var} ${result} PARENT_SCOPE) +endfunction() + +function(_juce_get_iaa_type_code target out_var) + get_target_property(wants_midi_input ${target} JUCE_NEEDS_MIDI_INPUT) + get_target_property(is_synth ${target} JUCE_IS_SYNTH) + + set(result) + + if(wants_midi_input) + if(is_synth) + set(result "auri") + else() + set(result "aurm") + endif() + else() + if(is_synth) + set(result "aurg") + else() + set(result "aurx") + endif() + endif() + + set(${out_var} ${result} PARENT_SCOPE) +endfunction() + +function(_juce_configure_plugin_targets target) + if(CMAKE_VERSION VERSION_LESS "3.15.0") + message(FATAL_ERROR "Plugin targets require CMake 3.15 or higher") + endif() + + _juce_set_output_name(${target} $<TARGET_PROPERTY:${target},JUCE_PRODUCT_NAME>_SharedCode) + + target_link_libraries(${target} PRIVATE juce::juce_audio_plugin_client_utils) + + get_target_property(enabled_formats ${target} JUCE_FORMATS) + + set(active_formats) + _juce_get_platform_plugin_kinds(plugin_kinds) + + foreach(kind IN LISTS plugin_kinds) + if(kind IN_LIST enabled_formats) + list(APPEND active_formats "${kind}") + endif() + endforeach() + + if((VST IN_LIST active_formats) AND (NOT TARGET juce_vst2_sdk)) + message(FATAL_ERROR "Use juce_set_vst2_sdk_path to set up the VST sdk before adding VST targets") + elseif((AAX IN_LIST active_formats) AND (NOT TARGET juce_aax_sdk)) + message(FATAL_ERROR "Use juce_set_aax_sdk_path to set up the AAX sdk before adding AAX targets") + endif() + + _juce_add_standard_defs(${target}) + _juce_add_plugin_definitions(${target} PRIVATE ${active_formats}) + + # The plugin wrappers need to know what other modules are available, especially + # juce_audio_utils and juce_gui_basics. We achieve this by searching for + # JUCE_MODULE_AVAILABLE_ private compile definitions, and reexporting them in + # the interface compile definitions. + # Unfortunately this requires CMake 3.15. + _juce_get_module_definitions(${target} ON enabled_modules) + target_compile_definitions(${target} INTERFACE ${enabled_modules}) + + target_compile_definitions(${target} PRIVATE JUCE_SHARED_CODE=1) + + get_target_property(project_version_string ${target} JUCE_VERSION) + _juce_version_code(${project_version_string} project_version_hex) + + get_target_property(project_manufacturer_code ${target} JUCE_PLUGIN_MANUFACTURER_CODE) + get_target_property(project_plugin_code ${target} JUCE_PLUGIN_CODE) + + get_target_property(use_legacy_compatibility_plugin_code ${target} JUCE_USE_LEGACY_COMPATIBILITY_PLUGIN_CODE) + + if(use_legacy_compatibility_plugin_code) + set(project_manufacturer_code "project_manufacturer_code-NOTFOUND") + endif() + + _juce_to_char_literal(${project_manufacturer_code} project_manufacturer_code) + _juce_to_char_literal(${project_plugin_code} project_plugin_code) + + _juce_get_vst3_category_string(${target} vst3_category_string) + _juce_get_iaa_type_code(${target} iaa_type_code) + + target_compile_definitions(${target} PUBLIC + JUCE_STANDALONE_APPLICATION=JucePlugin_Build_Standalone + JucePlugin_IsSynth=$<BOOL:$<TARGET_PROPERTY:${target},JUCE_IS_SYNTH>> + JucePlugin_ManufacturerCode=0x${project_manufacturer_code} + JucePlugin_Manufacturer="$<TARGET_PROPERTY:${target},JUCE_COMPANY_NAME>" + JucePlugin_ManufacturerWebsite="$<TARGET_PROPERTY:${target},JUCE_COMPANY_WEBSITE>" + JucePlugin_ManufacturerEmail="$<TARGET_PROPERTY:${target},JUCE_COMPANY_EMAIL>" + JucePlugin_PluginCode=0x${project_plugin_code} + JucePlugin_ProducesMidiOutput=$<BOOL:$<TARGET_PROPERTY:${target},JUCE_NEEDS_MIDI_OUTPUT>> + JucePlugin_IsMidiEffect=$<BOOL:$<TARGET_PROPERTY:${target},JUCE_IS_MIDI_EFFECT>> + JucePlugin_WantsMidiInput=$<BOOL:$<TARGET_PROPERTY:${target},JUCE_NEEDS_MIDI_INPUT>> + JucePlugin_EditorRequiresKeyboardFocus=$<BOOL:$<TARGET_PROPERTY:${target},JUCE_EDITOR_WANTS_KEYBOARD_FOCUS>> + JucePlugin_Name="$<TARGET_PROPERTY:${target},JUCE_PLUGIN_NAME>" + JucePlugin_Desc="$<TARGET_PROPERTY:${target},JUCE_DESCRIPTION>" + JucePlugin_Version=${project_version_string} + JucePlugin_VersionString="${project_version_string}" + JucePlugin_VersionCode=0x${project_version_hex} + JucePlugin_VSTUniqueID=JucePlugin_PluginCode + JucePlugin_VSTCategory=$<TARGET_PROPERTY:${target},JUCE_VST2_CATEGORY> + JucePlugin_Vst3Category="${vst3_category_string}" + JucePlugin_AUMainType=$<TARGET_PROPERTY:${target},JUCE_AU_MAIN_TYPE_CODE> + JucePlugin_AUSubType=JucePlugin_PluginCode + JucePlugin_AUExportPrefix=$<TARGET_PROPERTY:${target},JUCE_AU_EXPORT_PREFIX> + JucePlugin_AUExportPrefixQuoted="$<TARGET_PROPERTY:${target},JUCE_AU_EXPORT_PREFIX>" + JucePlugin_AUManufacturerCode=JucePlugin_ManufacturerCode + JucePlugin_CFBundleIdentifier=$<TARGET_PROPERTY:${target},JUCE_BUNDLE_ID> + JucePlugin_AAXIdentifier=$<TARGET_PROPERTY:${target},JUCE_AAX_IDENTIFIER> + JucePlugin_AAXManufacturerCode=JucePlugin_ManufacturerCode + JucePlugin_AAXProductId=JucePlugin_PluginCode + JucePlugin_AAXCategory=$<TARGET_PROPERTY:${target},JUCE_AAX_CATEGORY> + JucePlugin_AAXDisableBypass=$<BOOL:$<TARGET_PROPERTY:${target},JUCE_DISABLE_AAX_BYPASS>> + JucePlugin_AAXDisableMultiMono=$<BOOL:$<TARGET_PROPERTY:${target},JUCE_DISABLE_AAX_MULTI_MONO>> + JucePlugin_VSTNumMidiInputs=$<TARGET_PROPERTY:${target},JUCE_VST_NUM_MIDI_INS> + JucePlugin_VSTNumMidiOutputs=$<TARGET_PROPERTY:${target},JUCE_VST_NUM_MIDI_OUTS>) + + set_target_properties(${target} PROPERTIES + POSITION_INDEPENDENT_CODE TRUE + INTERFACE_POSITION_INDEPENDENT_CODE TRUE + VISIBILITY_INLINES_HIDDEN TRUE + C_VISIBILITY_PRESET hidden + CXX_VISIBILITY_PRESET hidden) + + # A convenience target for building all plugin variations at once + add_custom_target(${target}_All) + _juce_set_plugin_folder_property("${target}" "${target}_All") + + foreach(kind IN LISTS active_formats) + _juce_link_plugin_wrapper(${target} ${kind}) + + if(TARGET ${target}_${kind}) + list(APPEND active_plugin_targets ${target}_${kind}) + endif() + endforeach() + + set_target_properties(${target} PROPERTIES JUCE_ACTIVE_PLUGIN_TARGETS "${active_plugin_targets}") + + if(TARGET ${target}_Standalone) + _juce_configure_app_bundle(${target} ${target}_Standalone) + endif() + + if(TARGET ${target}_AU) + _juce_add_au_resource_fork(${target} ${target}_AU) + endif() + + if(TARGET ${target}_AAX) + target_link_libraries(${target}_AAX PRIVATE juce_aax_sdk) + endif() + + if((TARGET ${target}_AUv3) AND (TARGET ${target}_Standalone)) + add_dependencies(${target}_Standalone ${target}_AUv3) + # Copy the AUv3 into the Standalone app bundle + _juce_copy_dir(${target}_Standalone + "$<TARGET_BUNDLE_DIR:${target}_AUv3>" + "$<TARGET_BUNDLE_CONTENT_DIR:${target}_Standalone>/PlugIns") + endif() +endfunction() + +# ================================================================================================== + +function(_juce_set_generic_property_if_not_set target property) + list(LENGTH ARGN num_extra_args) + + if(num_extra_args EQUAL 0) + return() + endif() + + set(existing_property) + get_target_property(existing_property ${target} ${property}) + + if(existing_property STREQUAL "existing_property-NOTFOUND") + set_target_properties(${target} PROPERTIES ${property} "${ARGN}") + endif() +endfunction() + +function(_juce_set_property_if_not_set target property) + _juce_set_generic_property_if_not_set(${target} JUCE_${property} ${ARGN}) +endfunction() + +function(_juce_make_valid_4cc out_var) + string(RANDOM LENGTH 1 ALPHABET "ABCDEFGHIJKLMNOPQRSTUVWXYZ" head) + string(RANDOM LENGTH 3 ALPHABET "abcdefghijklmnopqrstuvwxyz" tail) + set(${out_var} "${head}${tail}" PARENT_SCOPE) +endfunction() + +# This function adds some default properties that plugin targets expect to be +# set, in order to generate the correct compile definitions. +function(_juce_set_fallback_properties target) + _juce_set_property_if_not_set(${target} PRODUCT_NAME ${target}) + + get_target_property(output_name ${target} JUCE_PRODUCT_NAME) + _juce_set_property_if_not_set(${target} DESCRIPTION "${output_name}") + _juce_set_property_if_not_set(${target} PLUGIN_NAME "${output_name}") + + get_target_property(real_company_name ${target} JUCE_COMPANY_NAME) + _juce_set_property_if_not_set(${target} BUNDLE_ID "com.${real_company_name}.${target}") + + _juce_set_property_if_not_set(${target} VERSION ${PROJECT_VERSION}) + + get_target_property(final_version ${target} JUCE_VERSION) + + if(NOT final_version) + message(FATAL_ERROR "Target ${target} must have its VERSION argument set, or must be part of a project with a PROJECT_VERSION") + endif() + + get_target_property(custom_xcassets ${target} JUCE_CUSTOM_XCASSETS_FOLDER) + + set(needs_storyboard TRUE) + + if(custom_xcassets) + set(needs_storyboard FALSE) + endif() + + set_target_properties(${target} PROPERTIES JUCE_SHOULD_ADD_STORYBOARD ${needs_storyboard}) + + _juce_set_property_if_not_set(${target} IPHONE_SCREEN_ORIENTATIONS + UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight) + + _juce_set_property_if_not_set(${target} IPAD_SCREEN_ORIENTATIONS + UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight) + + _juce_set_property_if_not_set(${target} + LAUNCH_STORYBOARD_FILE "${JUCE_CMAKE_UTILS_DIR}/LaunchScreen.storyboard") + + _juce_set_property_if_not_set(${target} PLUGIN_MANUFACTURER_CODE "Manu") + + # The plugin code will change on each run, unless you specify one manually! + _juce_make_valid_4cc(random_code) + _juce_set_property_if_not_set(${target} PLUGIN_CODE ${random_code}) + + _juce_set_property_if_not_set(${target} IS_SYNTH FALSE) + _juce_set_property_if_not_set(${target} NEEDS_MIDI_INPUT FALSE) + _juce_set_property_if_not_set(${target} NEEDS_MIDI_OUTPUT FALSE) + _juce_set_property_if_not_set(${target} IS_MIDI_EFFECT FALSE) + _juce_set_property_if_not_set(${target} EDITOR_WANTS_KEYBOARD_FOCUS FALSE) + _juce_set_property_if_not_set(${target} DISABLE_AAX_BYPASS FALSE) + _juce_set_property_if_not_set(${target} DISABLE_AAX_MULTI_MONO FALSE) + + _juce_set_property_if_not_set(${target} PLUGINHOST_AU FALSE) + + get_target_property(bundle_id ${target} JUCE_BUNDLE_ID) + _juce_set_property_if_not_set(${target} AAX_IDENTIFIER ${bundle_id}) + + _juce_set_property_if_not_set(${target} VST_NUM_MIDI_INS 16) + _juce_set_property_if_not_set(${target} VST_NUM_MIDI_OUTS 16) + + _juce_set_property_if_not_set(${target} AU_SANDBOX_SAFE FALSE) + + _juce_set_property_if_not_set(${target} SUPPRESS_AU_PLIST_RESOURCE_USAGE FALSE) + + _juce_set_property_if_not_set(${target} HARDENED_RUNTIME_ENABLED NO) + _juce_set_property_if_not_set(${target} APP_SANDBOX_ENABLED NO) + _juce_set_property_if_not_set(${target} APP_SANDBOX_INHERIT NO) + + get_target_property(is_synth ${target} JUCE_IS_SYNTH) + + # VST3_CATEGORIES + if(is_synth) + _juce_set_property_if_not_set(${target} VST3_CATEGORIES Instrument Synth) + else() + _juce_set_property_if_not_set(${target} VST3_CATEGORIES Fx) + endif() + + # VST2_CATEGORY + if(is_synth) + _juce_set_property_if_not_set(${target} VST2_CATEGORY kPlugCategSynth) + else() + _juce_set_property_if_not_set(${target} VST2_CATEGORY kPlugCategEffect) + endif() + + get_target_property(is_midi_effect ${target} JUCE_IS_MIDI_EFFECT) + get_target_property(needs_midi_input ${target} JUCE_NEEDS_MIDI_INPUT) + + # AU MAIN TYPE + if(is_midi_effect) + _juce_set_property_if_not_set(${target} AU_MAIN_TYPE kAudioUnitType_MIDIProcessor) + elseif(is_synth) + _juce_set_property_if_not_set(${target} AU_MAIN_TYPE kAudioUnitType_MusicDevice) + elseif(needs_midi_input) + _juce_set_property_if_not_set(${target} AU_MAIN_TYPE kAudioUnitType_MusicEffect) + else() + _juce_set_property_if_not_set(${target} AU_MAIN_TYPE kAudioUnitType_Effect) + endif() + + set(au_category_codes + 'aufx' + 'aufc' + 'augn' + 'aumi' + 'aumx' + 'aumu' + 'aumf' + 'auol' + 'auou' + 'aupn') + + set(au_category_strings + kAudioUnitType_Effect + kAudioUnitType_FormatConverter + kAudioUnitType_Generator + kAudioUnitType_MIDIProcessor + kAudioUnitType_Mixer + kAudioUnitType_MusicDevice + kAudioUnitType_MusicEffect + kAudioUnitType_OfflineEffect + kAudioUnitType_Output + kAudioUnitType_Panner) + + # AU export prefix + string(MAKE_C_IDENTIFIER ${output_name} au_prefix) + set(au_prefix "${au_prefix}AU") + _juce_set_property_if_not_set(${target} AU_EXPORT_PREFIX ${au_prefix}) + + # Find appropriate AU category code + get_target_property(actual_au_category ${target} JUCE_AU_MAIN_TYPE) + list(FIND au_category_strings ${actual_au_category} au_index) + + if(au_index GREATER_EQUAL 0) + list(GET au_category_codes ${au_index} au_code_representation) + set_target_properties(${target} PROPERTIES JUCE_AU_MAIN_TYPE_CODE ${au_code_representation}) + endif() + + # AAX category + set(aax_category_ints + 0x00000000 + 0x00000001 + 0x00000002 + 0x00000004 + 0x00000008 + 0x00000010 + 0x00000020 + 0x00000040 + 0x00000080 + 0x00000100 + 0x00000200 + 0x00000400 + 0x00000800 + 0x00001000 + 0x00002000) + + set(aax_category_strings + ePlugInCategory_None + ePlugInCategory_EQ + ePlugInCategory_Dynamics + ePlugInCategory_PitchShift + ePlugInCategory_Reverb + ePlugInCategory_Delay + ePlugInCategory_Modulation + ePlugInCategory_Harmonic + ePlugInCategory_NoiseReduction + ePlugInCategory_Dither + ePlugInCategory_SoundField + ePlugInCategory_HWGenerators + ePlugInCategory_SWGenerators + ePlugInCategory_WrappedPlugin + ePlugInCategory_Effect) + + if(is_synth) + set(default_aax_category ePlugInCategory_SWGenerators) + else() + set(default_aax_category ePlugInCategory_None) + endif() + + _juce_set_property_if_not_set(${target} AAX_CATEGORY ${default_aax_category}) + + # Replace AAX category string with its integral representation + get_target_property(actual_aax_category ${target} JUCE_AAX_CATEGORY) + list(FIND aax_category_strings ${actual_aax_category} aax_index) + + if(aax_index GREATER_EQUAL 0) + list(GET aax_category_ints ${aax_index} aax_int_representation) + set_target_properties(${target} PROPERTIES JUCE_AAX_CATEGORY ${aax_int_representation}) + endif() +endfunction() + +# ================================================================================================== + +function(_juce_initialise_target target) + set(one_value_args + VERSION + PRODUCT_NAME + PLIST_TO_MERGE + BUNDLE_ID + MICROPHONE_PERMISSION_ENABLED + MICROPHONE_PERMISSION_TEXT + CAMERA_PERMISSION_ENABLED + CAMERA_PERMISSION_TEXT + SEND_APPLE_EVENTS_PERMISSION_ENABLED + SEND_APPLE_EVENTS_PERMISSION_TEXT + BLUETOOTH_PERMISSION_ENABLED + BLUETOOTH_PERMISSION_TEXT + FILE_SHARING_ENABLED # iOS only + DOCUMENT_BROWSER_ENABLED # iOS only + LAUNCH_STORYBOARD_FILE # iOS only + APP_GROUPS_ENABLED # iOS only + ICLOUD_PERMISSIONS_ENABLED # iOS only + STATUS_BAR_HIDDEN # iOS only + BACKGROUND_AUDIO_ENABLED # iOS only + BACKGROUND_BLE_ENABLED # iOS only + CUSTOM_XCASSETS_FOLDER # iOS only + ICON_BIG + ICON_SMALL + COMPANY_COPYRIGHT + COMPANY_NAME + COMPANY_WEBSITE + COMPANY_EMAIL + NEEDS_CURL # Set this true if you want to link curl on Linux + NEEDS_WEB_BROWSER # Set this true if you want to link webkit on Linux + NEEDS_STORE_KIT # Set this true if you want in-app-purchases on Mac + PUSH_NOTIFICATIONS_ENABLED + HARDENED_RUNTIME_ENABLED + APP_SANDBOX_ENABLED + APP_SANDBOX_INHERIT + + PLUGIN_NAME + PLUGIN_MANUFACTURER_CODE + PLUGIN_CODE + DESCRIPTION + IS_SYNTH + NEEDS_MIDI_INPUT + NEEDS_MIDI_OUTPUT + IS_MIDI_EFFECT + EDITOR_WANTS_KEYBOARD_FOCUS + DISABLE_AAX_BYPASS + DISABLE_AAX_MULTI_MONO + AAX_IDENTIFIER + VST_NUM_MIDI_INS + VST_NUM_MIDI_OUTS + VST2_CATEGORY + AU_MAIN_TYPE + AU_EXPORT_PREFIX + AU_SANDBOX_SAFE + SUPPRESS_AU_PLIST_RESOURCE_USAGE + AAX_CATEGORY + PLUGINHOST_AU # Set this true if you want to host AU plugins + USE_LEGACY_COMPATIBILITY_PLUGIN_CODE + + VST_COPY_DIR + VST3_COPY_DIR + AAX_COPY_DIR + AU_COPY_DIR + UNITY_COPY_DIR + COPY_PLUGIN_AFTER_BUILD) + + set(multi_value_args + FORMATS + VST3_CATEGORIES + HARDENED_RUNTIME_OPTIONS + APP_SANDBOX_OPTIONS + DOCUMENT_EXTENSIONS + IPHONE_SCREEN_ORIENTATIONS # iOS only + IPAD_SCREEN_ORIENTATIONS # iOS only + APP_GROUP_IDS) # iOS only + + cmake_parse_arguments(JUCE_ARG "" "${one_value_args}" "${multi_value_args}" ${ARGN}) + + set(base_folder "${CMAKE_CURRENT_BINARY_DIR}/${target}_artefacts") + set(products_folder "${base_folder}/$<CONFIG>") + set(juce_library_code "${base_folder}/JuceLibraryCode") + + set_target_properties(${target} PROPERTIES JUCE_GENERATED_SOURCES_DIRECTORY "${juce_library_code}") + + set_target_properties(${target} PROPERTIES + ARCHIVE_OUTPUT_DIRECTORY "${products_folder}" + LIBRARY_OUTPUT_DIRECTORY "${products_folder}" + RUNTIME_OUTPUT_DIRECTORY "${products_folder}") + + if(JUCE_ARG_ICON_BIG) + _juce_make_absolute_and_check(JUCE_ARG_ICON_BIG) + endif() + + if(JUCE_ARG_ICON_SMALL) + _juce_make_absolute_and_check(JUCE_ARG_ICON_SMALL) + endif() + + set(inherited_properties + COMPANY_NAME + COMPANY_WEBSITE + COMPANY_EMAIL + COMPANY_COPYRIGHT + VST_COPY_DIR + VST3_COPY_DIR + AU_COPY_DIR + AAX_COPY_DIR + UNITY_COPY_DIR + COPY_PLUGIN_AFTER_BUILD) + + # Overwrite any properties that might be inherited + foreach(prop_string IN LISTS inherited_properties) + if(NOT ${JUCE_ARG_${prop_string}} STREQUAL "") + set_target_properties(${target} PROPERTIES JUCE_${prop_string} "${JUCE_ARG_${prop_string}}") + endif() + endforeach() + + # Add each of the function arguments as target properties, so that it's easier to + # extract them in other functions + foreach(arg_string IN LISTS one_value_args multi_value_args) + _juce_set_property_if_not_set(${target} ${arg_string} "${JUCE_ARG_${arg_string}}") + endforeach() + + _juce_set_fallback_properties(${target}) + + target_include_directories(${target} PRIVATE + $<TARGET_PROPERTY:${target},JUCE_GENERATED_SOURCES_DIRECTORY>) + target_link_libraries(${target} PUBLIC $<$<TARGET_EXISTS:juce_vst2_sdk>:juce_vst2_sdk>) + + get_target_property(is_pluginhost_au ${target} JUCE_PLUGINHOST_AU) + + if(is_pluginhost_au) + target_compile_definitions(${target} PUBLIC JUCE_PLUGINHOST_AU=1) + + if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" OR CMAKE_SYSTEM_NAME STREQUAL "iOS") + _juce_link_frameworks("${target}" PRIVATE CoreAudioKit) + endif() + + if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + _juce_link_frameworks("${target}" PRIVATE AudioUnit) + endif() + endif() + + _juce_write_generate_time_info(${target}) + _juce_link_optional_libraries(${target}) +endfunction() + +# ================================================================================================== + +function(juce_add_console_app target) + add_executable(${target}) + target_compile_definitions(${target} PRIVATE JUCE_STANDALONE_APPLICATION=1) + + if(CMAKE_SYSTEM_NAME STREQUAL "Windows") + target_compile_definitions(${target} PRIVATE _CONSOLE=1) + endif() + + _juce_initialise_target(${target} ${ARGN}) +endfunction() + +function(juce_add_gui_app target) + if(CMAKE_SYSTEM_NAME STREQUAL "Android") + add_library(${target} SHARED) + else() + add_executable(${target}) + endif() + + target_compile_definitions(${target} PRIVATE JUCE_STANDALONE_APPLICATION=1) + _juce_initialise_target(${target} ${ARGN}) + _juce_set_output_name(${target} $<TARGET_PROPERTY:${target},JUCE_PRODUCT_NAME>) + set_target_properties(${target} PROPERTIES JUCE_TARGET_KIND_STRING "App") + _juce_configure_bundle(${target} ${target}) + _juce_configure_app_bundle(${target} ${target}) +endfunction() + +function(juce_add_plugin target) + add_library(${target} STATIC) + set_target_properties(${target} PROPERTIES JUCE_IS_PLUGIN TRUE) + _juce_initialise_target(${target} ${ARGN}) + _juce_configure_plugin_targets(${target}) +endfunction() + +# ================================================================================================== + +function(_juce_target_args_from_plugin_characteristics out_var) + set(pairs + "pluginIsSynth\;IS_SYNTH" + "pluginWantsMidiIn\;NEEDS_MIDI_INPUT" + "pluginProducesMidiOut\;NEEDS_MIDI_OUTPUT" + "pluginIsMidiEffectPlugin\;IS_MIDI_EFFECT" + "pluginEditorRequiresKeys\;EDITOR_WANTS_KEYBOARD_FOCUS") + + set(result) + + foreach(pair IN LISTS pairs) + list(GET pair 0 old_key) + + if("${old_key}" IN_LIST ARGN) + list(GET pair 1 new_key) + list(APPEND result ${new_key} TRUE) + endif() + endforeach() + + set(${out_var} ${result} PARENT_SCOPE) +endfunction() + +# ================================================================================================== + +function(_juce_get_pip_targets pip out_var) + set(test_targets "${pip}") + + _juce_get_all_plugin_kinds(plugin_kinds) + + foreach(plugin_kind IN LISTS plugin_kinds) + list(APPEND test_targets "${JUCE_PIP_NAME}_${plugin_kind}") + endforeach() + + set(${out_var} ${test_targets} PARENT_SCOPE) +endfunction() + +function(juce_add_pip header) + _juce_make_absolute(header) + + _juce_extract_metadata_block(JUCE_PIP_METADATA "${header}" metadata_dict) + + _juce_get_metadata("${metadata_dict}" name JUCE_PIP_NAME) + + if(NOT JUCE_PIP_NAME) + message(FATAL_ERROR "PIP headers must declare a `name` field") + endif() + + string(MAKE_C_IDENTIFIER "${JUCE_PIP_NAME}" pip_name_sanitised) + + if(NOT JUCE_PIP_NAME STREQUAL pip_name_sanitised) + message(FATAL_ERROR "PIP `name` value '${JUCE_PIP_NAME}' must be a valid C identifier") + endif() + + if(TARGET "${JUCE_PIP_NAME}") + # We already added a target with this name, let's try using the filename instead + get_filename_component(JUCE_PIP_NAME "${header}" NAME_WE) + endif() + + if(TARGET "${JUCE_PIP_NAME}") + message(FATAL_ERROR "Could not create a unique target name for PIP ${header}") + endif() + + _juce_get_metadata("${metadata_dict}" type pip_kind) + + if(NOT pip_kind) + message(FATAL_ERROR "PIP headers must declare a `type` field") + endif() + + _juce_get_metadata("${metadata_dict}" pluginCharacteristics pip_charateristics) + + _juce_target_args_from_plugin_characteristics(extra_target_args ${pip_charateristics}) + + list(APPEND extra_target_args + NEEDS_CURL TRUE + NEEDS_WEB_BROWSER TRUE) + + _juce_get_metadata("${metadata_dict}" moduleFlags pip_moduleflags) + + if("JUCE_IN_APP_PURCHASES=1" IN_LIST pip_moduleflags) + list(APPEND extra_target_args + BUNDLE_ID "com.rmsl.juceInAppPurchaseSample" + NEEDS_STORE_KIT TRUE) + endif() + + if(pip_kind STREQUAL "AudioProcessor") + set(source_main "${JUCE_CMAKE_UTILS_DIR}/PIPAudioProcessor.cpp.in") + + # We add AAX/VST2 targets too, if the user has set up those SDKs + + set(extra_formats) + + if(TARGET juce_aax_sdk) + list(APPEND extra_formats AAX) + endif() + + if(TARGET juce_vst2_sdk) + list(APPEND extra_formats VST) + endif() + + # Standalone plugins might want to access the mic + list(APPEND extra_target_args MICROPHONE_PERMISSION_ENABLED TRUE) + + juce_add_plugin(${JUCE_PIP_NAME} + FORMATS AU AUv3 VST3 Unity Standalone ${extra_formats} + ${extra_target_args}) + elseif(pip_kind STREQUAL "Component") + set(source_main "${JUCE_CMAKE_UTILS_DIR}/PIPComponent.cpp.in") + juce_add_gui_app(${JUCE_PIP_NAME} ${extra_target_args}) + elseif(pip_kind STREQUAL "Console") + set(source_main "${JUCE_CMAKE_UTILS_DIR}/PIPConsole.cpp.in") + juce_add_console_app(${JUCE_PIP_NAME} ${extra_target_args}) + else() + message(FATAL_ERROR "PIP kind must be either AudioProcessor, Component, or Console") + endif() + + if(NOT ARGV1 STREQUAL "") + set("${ARGV1}" "${JUCE_PIP_NAME}" PARENT_SCOPE) + endif() + + # Generate Main.cpp + _juce_get_metadata("${metadata_dict}" mainClass JUCE_PIP_MAIN_CLASS) + get_target_property(juce_library_code ${JUCE_PIP_NAME} JUCE_GENERATED_SOURCES_DIRECTORY) + set(pip_main "${juce_library_code}/Main.cpp") + + set(JUCE_PIP_HEADER "${header}") + configure_file(${source_main} ${pip_main}) + target_sources(${JUCE_PIP_NAME} PRIVATE ${pip_main}) + + _juce_get_metadata("${metadata_dict}" dependencies pip_dependencies) + + juce_generate_juce_header(${JUCE_PIP_NAME}) + + foreach(module IN LISTS pip_dependencies) + if(module STREQUAL "") + continue() + endif() + + set(discovered_module) + + if(TARGET "${module}") + set(discovered_module "${module}") + else() + message(FATAL_ERROR "No such module: ${module}") + endif() + + target_link_libraries(${JUCE_PIP_NAME} PRIVATE ${discovered_module}) + endforeach() + + target_compile_definitions(${JUCE_PIP_NAME} + PRIVATE ${pip_moduleflags} + PUBLIC JUCE_VST3_CAN_REPLACE_VST2=0) + + _juce_get_pip_targets(${JUCE_PIP_NAME} pip_targets) + + # This keeps the PIPs slightly better organised in the JUCE megaproject + if((DEFINED JUCE_SOURCE_DIR) AND (header MATCHES "^${JUCE_SOURCE_DIR}")) + file(RELATIVE_PATH folder "${JUCE_SOURCE_DIR}" "${header}") + get_filename_component(folder_parent "${folder}" DIRECTORY) + + foreach(target_name IN ITEMS ${pip_targets} ${JUCE_PIP_NAME}_All) + if(TARGET "${target_name}") + set_target_properties("${target_name}" PROPERTIES + FOLDER "${folder_parent}/${JUCE_PIP_NAME}") + endif() + endforeach() + endif() + + # We're building JUCE itself + if(DEFINED JUCE_SOURCE_DIR) + # PIPs need to know about the resources folder + target_compile_definitions(${JUCE_PIP_NAME} PRIVATE + PIP_JUCE_EXAMPLES_DIRECTORY_STRING="${JUCE_SOURCE_DIR}/examples") + + get_filename_component(pip_parent_path "${header}" DIRECTORY) + target_include_directories(${JUCE_PIP_NAME} PRIVATE "${pip_parent_path}") + + if((CMAKE_SYSTEM_NAME STREQUAL "iOS") AND (header MATCHES "^${JUCE_SOURCE_DIR}")) + foreach(target_name IN LISTS pip_targets) + if(TARGET "${target_name}") + juce_add_bundle_resources_directory("${target_name}" "${JUCE_SOURCE_DIR}/examples/Assets") + endif() + endforeach() + endif() + endif() +endfunction() + +# ================================================================================================== + +function(juce_set_aax_sdk_path path) + if(TARGET juce_aax_sdk) + message(FATAL_ERROR "juce_set_aax_sdk_path should only be called once") + endif() + + _juce_make_absolute(path) + + if((NOT EXISTS "${path}") + OR (NOT EXISTS "${path}/Interfaces") + OR (NOT EXISTS "${path}/Interfaces/ACF")) + message(FATAL_ERROR "Could not find AAX SDK at the specified path: ${path}") + endif() + + if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + add_library(juce_aax_sdk STATIC IMPORTED) + set_target_properties(juce_aax_sdk PROPERTIES + IMPORTED_LOCATION_DEBUG "${path}/Libs/Debug/libAAXLibrary_libcpp.a" + IMPORTED_LOCATION "${path}/Libs/Release/libAAXLibrary_libcpp.a") + elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows") + add_library(juce_aax_sdk INTERFACE IMPORTED) + else() + return() + endif() + + target_include_directories(juce_aax_sdk INTERFACE + "${path}" + "${path}/Interfaces" + "${path}/Interfaces/ACF") + target_compile_definitions(juce_aax_sdk INTERFACE JucePlugin_AAXLibs_path="${path}/Libs") + set_target_properties(juce_aax_sdk PROPERTIES INTERFACE_JUCE_AAX_DEFAULT_ICON "${path}/Utilities/PlugIn.ico") +endfunction() + +function(juce_set_vst2_sdk_path path) + if(TARGET juce_vst2_sdk) + message(FATAL_ERROR "juce_set_vst2_sdk_path should only be called once") + endif() + + _juce_make_absolute(path) + + if(NOT EXISTS "${path}") + message(FATAL_ERROR "Could not find VST2 SDK at the specified path: ${path}") + endif() + + add_library(juce_vst2_sdk INTERFACE IMPORTED) + + # This is a bit of a hack, but we really need the VST2 paths to always follow the VST3 paths. + target_include_directories(juce_vst2_sdk INTERFACE + $<TARGET_PROPERTY:juce::juce_vst3_headers,INTERFACE_INCLUDE_DIRECTORIES> + "${path}") +endfunction() + +# ================================================================================================== + +function(juce_disable_default_flags) + set(langs C CXX) + set(modes DEBUG RELEASE RELWITHDEBINFO MINSIZEREL) + + foreach(lang IN LISTS langs) + foreach(mode IN LISTS modes) + list(FILTER CMAKE_${lang}_FLAGS_${mode} INCLUDE REGEX "[/-]M[TD]d?") + set(CMAKE_${lang}_FLAGS_${mode} "${CMAKE_${lang}_FLAGS_${mode}}" PARENT_SCOPE) + endforeach() + endforeach() +endfunction() diff --git a/extras/Build/CMake/LaunchScreen.storyboard b/extras/Build/CMake/LaunchScreen.storyboard new file mode 100644 index 00000000..ce0d6fd7 --- /dev/null +++ b/extras/Build/CMake/LaunchScreen.storyboard @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM"> + <scenes> + <scene sceneID="EHf-IW-A2E"> + <objects> + <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="" sceneMemberID="firstResponder"/> + <viewController id="01J-lp-oVM" sceneMemberID="viewController"> + <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3"> + <autoresizingMask key="autoresizingMask"/> + <color key="backgroundColor" red="0" green="0" blue="0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> + </view> + </viewController> + </objects> + </scene> + </scenes> +</document> diff --git a/extras/Build/CMake/PIPAudioProcessor.cpp.in b/extras/Build/CMake/PIPAudioProcessor.cpp.in new file mode 100644 index 00000000..2dd950ff --- /dev/null +++ b/extras/Build/CMake/PIPAudioProcessor.cpp.in @@ -0,0 +1,16 @@ +/* + ============================================================================== + + This file was auto-generated and contains the startup code for a PIP. + + ============================================================================== +*/ + +#include <JuceHeader.h> +#include "${JUCE_PIP_HEADER}" + +//============================================================================== +juce::AudioProcessor* JUCE_CALLTYPE createPluginFilter() +{ + return new ${JUCE_PIP_MAIN_CLASS}(); +} diff --git a/extras/Build/CMake/PIPComponent.cpp.in b/extras/Build/CMake/PIPComponent.cpp.in new file mode 100644 index 00000000..662c11d2 --- /dev/null +++ b/extras/Build/CMake/PIPComponent.cpp.in @@ -0,0 +1,68 @@ +/* + ============================================================================== + + This file contains the startup code for a PIP. + + ============================================================================== +*/ + +#include <JuceHeader.h> +#include "${JUCE_PIP_HEADER}" + +class Application : public juce::JUCEApplication +{ +public: + //============================================================================== + Application() = default; + + const juce::String getApplicationName() override { return "${JUCE_PIP_NAME}"; } + const juce::String getApplicationVersion() override { return "${PROJECT_VERSION}"; } + + void initialise (const juce::String&) override + { + mainWindow.reset (new MainWindow ("${JUCE_PIP_NAME}", new ${JUCE_PIP_MAIN_CLASS}, *this)); + } + + void shutdown() override { mainWindow = nullptr; } + +private: + class MainWindow : public juce::DocumentWindow + { + public: + MainWindow (const juce::String& name, juce::Component* c, JUCEApplication& a) + : DocumentWindow (name, juce::Desktop::getInstance().getDefaultLookAndFeel() + .findColour (ResizableWindow::backgroundColourId), + juce::DocumentWindow::allButtons), + app (a) + { + setUsingNativeTitleBar (true); + setContentOwned (c, true); + + #if JUCE_ANDROID || JUCE_IOS + setFullScreen (true); + #else + setResizable (true, false); + setResizeLimits (300, 250, 10000, 10000); + centreWithSize (getWidth(), getHeight()); + #endif + + setVisible (true); + } + + void closeButtonPressed() override + { + app.systemRequestedQuit(); + } + + private: + JUCEApplication& app; + + //============================================================================== + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainWindow) + }; + + std::unique_ptr<MainWindow> mainWindow; +}; + +//============================================================================== +START_JUCE_APPLICATION (Application) diff --git a/extras/Build/CMake/PIPConsole.cpp.in b/extras/Build/CMake/PIPConsole.cpp.in new file mode 100644 index 00000000..ee311ad0 --- /dev/null +++ b/extras/Build/CMake/PIPConsole.cpp.in @@ -0,0 +1,10 @@ +/* + ============================================================================== + + This file was auto-generated and contains the startup code for a PIP. + + ============================================================================== +*/ + +#include <JuceHeader.h> +#include "${JUCE_PIP_HEADER}" diff --git a/extras/Projucer/Source/BinaryData/RecentFilesMenuTemplate.nib b/extras/Build/CMake/RecentFilesMenuTemplate.nib similarity index 100% rename from extras/Projucer/Source/BinaryData/RecentFilesMenuTemplate.nib rename to extras/Build/CMake/RecentFilesMenuTemplate.nib diff --git a/extras/Projucer/Source/BinaryData/Templates/jucer_UnityPluginGUIScript.cs b/extras/Build/CMake/UnityPluginGUIScript.cs.in similarity index 78% rename from extras/Projucer/Source/BinaryData/Templates/jucer_UnityPluginGUIScript.cs rename to extras/Build/CMake/UnityPluginGUIScript.cs.in index 3b15b1f8..3f00b908 100644 --- a/extras/Projucer/Source/BinaryData/Templates/jucer_UnityPluginGUIScript.cs +++ b/extras/Build/CMake/UnityPluginGUIScript.cs.in @@ -6,24 +6,24 @@ using UnityEngine; using System.Collections.Generic; using System.Runtime.InteropServices; -public class %%plugin_class_name%%GUI : IAudioEffectPluginGUI +public class ${plugin_class_name}GUI : IAudioEffectPluginGUI { - public override string Name { get { return "%%plugin_name%%"; } } - public override string Description { get { return "%%plugin_description%%"; } } - public override string Vendor { get { return "%%plugin_vendor%%"; } } + public override string Name { get { return "${plugin_name}"; } } + public override string Description { get { return "${plugin_description}"; } } + public override string Vendor { get { return "${plugin_vendor}"; } } //============================================================================== - [DllImport("%%plugin_name%%")] static extern System.IntPtr getRenderCallback(); + [DllImport("${plugin_name}")] static extern System.IntPtr getRenderCallback(); - [DllImport("%%plugin_name%%")] static extern void unityInitialiseTexture (int id, System.IntPtr texture, int width, int height); + [DllImport("${plugin_name}")] static extern void unityInitialiseTexture (int id, System.IntPtr texture, int width, int height); - [DllImport("%%plugin_name%%")] static extern void unityMouseDown (int id, float x, float y, EventModifiers mods, int button); - [DllImport("%%plugin_name%%")] static extern void unityMouseDrag (int id, float x, float y, EventModifiers mods, int button); - [DllImport("%%plugin_name%%")] static extern void unityMouseUp (int id, float x, float y, EventModifiers mods); + [DllImport("${plugin_name}")] static extern void unityMouseDown (int id, float x, float y, EventModifiers mods, int button); + [DllImport("${plugin_name}")] static extern void unityMouseDrag (int id, float x, float y, EventModifiers mods, int button); + [DllImport("${plugin_name}")] static extern void unityMouseUp (int id, float x, float y, EventModifiers mods); - [DllImport("%%plugin_name%%")] static extern void unityKeyEvent (int id, KeyCode code, EventModifiers mods, string name); + [DllImport("${plugin_name}")] static extern void unityKeyEvent (int id, KeyCode code, EventModifiers mods, string name); - [DllImport("%%plugin_name%%")] static extern void unitySetScreenBounds (int id, float x, float y, float w, float h); + [DllImport("${plugin_name}")] static extern void unitySetScreenBounds (int id, float x, float y, float w, float h); //============================================================================== private class PluginGUIInstance @@ -38,10 +38,10 @@ public class %%plugin_class_name%%GUI : IAudioEffectPluginGUI } public void repaint (Rect r) - { + { Vector2 newScreenPosition = GUIUtility.GUIToScreenPoint (r.position); - if (bounds != r + if (bounds != r || screenPosition != newScreenPosition) { screenPosition = newScreenPosition; @@ -51,7 +51,7 @@ public class %%plugin_class_name%%GUI : IAudioEffectPluginGUI setupTexture(); } - GL.IssuePluginEvent (getRenderCallback(), instanceID); + GL.IssuePluginEvent (getRenderCallback(), instanceID); texture.SetPixels32 (pixels); texture.Apply(); @@ -69,7 +69,7 @@ public class %%plugin_class_name%%GUI : IAudioEffectPluginGUI Vector2 relativePos = new Vector2 (mousePos.x - bounds.x, mousePos.y - bounds.y); - if (eventType == EventType.MouseDown) + if (eventType == EventType.MouseDown) { unityMouseDown (instanceID, relativePos.x, relativePos.y, mods, Event.current.button); GUIUtility.hotControl = GUIUtility.GetControlID (FocusType.Passive); @@ -79,7 +79,7 @@ public class %%plugin_class_name%%GUI : IAudioEffectPluginGUI unityMouseUp (instanceID, relativePos.x, relativePos.y, mods); GUIUtility.hotControl = 0; } - else if (eventType == EventType.MouseDrag) + else if (eventType == EventType.MouseDrag) { unityMouseDrag (instanceID, relativePos.x, relativePos.y, mods, Event.current.button); } diff --git a/extras/Build/CMake/copyDir.cmake b/extras/Build/CMake/copyDir.cmake new file mode 100644 index 00000000..b93aa172 --- /dev/null +++ b/extras/Build/CMake/copyDir.cmake @@ -0,0 +1,24 @@ +# ============================================================================== +# +# This file is part of the JUCE library. +# Copyright (c) 2020 - Raw Material Software Limited +# +# JUCE is an open source library subject to commercial or open-source +# licensing. +# +# By using JUCE, you agree to the terms of both the JUCE 6 End-User License +# Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). +# +# End User License Agreement: www.juce.com/juce-6-licence +# Privacy Policy: www.juce.com/juce-privacy-policy +# +# Or: You may also use this code under the terms of the GPL v3 (see +# www.gnu.org/licenses). +# +# JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER +# EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE +# DISCLAIMED. +# +# ============================================================================== + +file(INSTALL ${src} DESTINATION ${dest}) diff --git a/extras/Build/CMake/juce_runtime_arch_detection.cpp b/extras/Build/CMake/juce_runtime_arch_detection.cpp new file mode 100644 index 00000000..7aea5fbb --- /dev/null +++ b/extras/Build/CMake/juce_runtime_arch_detection.cpp @@ -0,0 +1,57 @@ +#if defined(__arm__) || defined(__TARGET_ARCH_ARM) || defined(_M_ARM) || defined(_M_ARM64) || defined(__aarch64__) || defined(__ARM64__) + + #if defined(_M_ARM64) || defined(__aarch64__) || defined(__ARM64__) + #error JUCE_ARCH arm64 + #elif (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM == 8) || defined(__ARMv8__) || defined(__ARMv8_A__) + #error JUCE_ARCH armv8l + #elif (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM == 7) || defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) || defined(_ARM_ARCH_7) || defined(__CORE_CORTEXA__) + #error JUCE_ARCH armv7l + #elif (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM == 6) || defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6T2__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6M__) + #error JUCE_ARCH armv6l + #elif (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM == 5) || defined(__ARM_ARCH_5TEJ__) + #error JUCE_ARCH armv5l + #else + #error JUCE_ARCH arm + #endif + +#elif defined(__i386) || defined(__i386__) || defined(_M_IX86) + + #error JUCE_ARCH i386 + +#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64) + + #error JUCE_ARCH x86_64 + +#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64) + + #error JUCE_ARCH ia64 + +#elif defined(__mips) || defined(__mips__) || defined(_M_MRX000) + + #if defined(_MIPS_ARCH_MIPS64) || defined(__mips64) + #error JUCE_ARCH mips64 + #else + #error JUCE_ARCH mips + #endif + +#elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__) || defined(_ARCH_COM) || defined(_ARCH_PWR) || defined(_ARCH_PPC) || defined(_M_MPPC) || defined(_M_PPC) + + #if defined(__ppc64__) || defined(__powerpc64__) || defined(__64BIT__) + #error JUCE_ARCH ppc64 + #else + #error JUCE_ARCH ppc + #endif + +#elif defined(__riscv) + + #if __riscv_xlen == 64 + #error JUCE_ARCH riscv64 + #else + #error JUCE_ARCH riscv + #endif + +#else + + #error JUCE_ARCH unknown + +#endif diff --git a/extras/Build/CMakeLists.txt b/extras/Build/CMakeLists.txt new file mode 100644 index 00000000..122d12e2 --- /dev/null +++ b/extras/Build/CMakeLists.txt @@ -0,0 +1,27 @@ +# ============================================================================== +# +# This file is part of the JUCE library. +# Copyright (c) 2020 - Raw Material Software Limited +# +# JUCE is an open source library subject to commercial or open-source +# licensing. +# +# By using JUCE, you agree to the terms of both the JUCE 6 End-User License +# Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). +# +# End User License Agreement: www.juce.com/juce-6-licence +# Privacy Policy: www.juce.com/juce-privacy-policy +# +# Or: You may also use this code under the terms of the GPL v3 (see +# www.gnu.org/licenses). +# +# JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER +# EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE +# DISCLAIMED. +# +# ============================================================================== + +juce_add_module(juce_build_tools ALIAS_NAMESPACE juce) + +add_subdirectory(juceaide) + diff --git a/extras/Build/juce_build_tools/juce_build_tools.cpp b/extras/Build/juce_build_tools/juce_build_tools.cpp new file mode 100644 index 00000000..3dea8ef4 --- /dev/null +++ b/extras/Build/juce_build_tools/juce_build_tools.cpp @@ -0,0 +1,47 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +#ifdef JUCE_BUILD_TOOLS_H_INCLUDED + /* When you add this cpp file to your project, you mustn't include it in a file where you've + already included any other headers - just put it inside a file on its own, possibly with your config + flags preceding it, but don't include anything else. That also includes avoiding any automatic prefix + header files that the compiler may be using. + */ + #error "Incorrect use of JUCE cpp file" +#endif + +#include "juce_build_tools.h" + +#include <numeric> + +#include "utils/juce_CppTokeniserFunctions.cpp" +#include "utils/juce_BuildHelperFunctions.cpp" +#include "utils/juce_BinaryResourceFile.cpp" +#include "utils/juce_Icons.cpp" +#include "utils/juce_PlistOptions.cpp" +#include "utils/juce_ResourceFileHelpers.cpp" +#include "utils/juce_ResourceRc.cpp" +#include "utils/juce_VersionNumbers.cpp" +#include "utils/juce_Entitlements.cpp" diff --git a/extras/Build/juce_build_tools/juce_build_tools.h b/extras/Build/juce_build_tools/juce_build_tools.h new file mode 100644 index 00000000..f67a76f8 --- /dev/null +++ b/extras/Build/juce_build_tools/juce_build_tools.h @@ -0,0 +1,67 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +/******************************************************************************* + The block below describes the properties of this module, and is read by + the Projucer to automatically generate project code that uses it. + For details about the syntax and how to create or use a module, see the + JUCE Module Format.md file. + + + BEGIN_JUCE_MODULE_DECLARATION + + ID: juce_build_tools + vendor: juce + version: 6.0.5 + name: JUCE Build Tools + description: Classes for generating intermediate files for JUCE projects. + website: http://www.juce.com/juce + license: GPL/Commercial + + dependencies: juce_gui_basics + + END_JUCE_MODULE_DECLARATION + +*******************************************************************************/ + +// This module is shared by juceaide and the Projucer, but should not be +// considered 'public'. That is, its API, functionality, and contents (and +// existence!) may change between releases without warning. + +#pragma once +#define JUCE_BUILD_TOOLS_H_INCLUDED + +#include <juce_gui_basics/juce_gui_basics.h> + +#include "utils/juce_ProjectType.h" +#include "utils/juce_BuildHelperFunctions.h" +#include "utils/juce_BinaryResourceFile.h" +#include "utils/juce_RelativePath.h" +#include "utils/juce_Icons.h" +#include "utils/juce_PlistOptions.h" +#include "utils/juce_ResourceFileHelpers.h" +#include "utils/juce_ResourceRc.h" +#include "utils/juce_VersionNumbers.h" +#include "utils/juce_Entitlements.h" diff --git a/extras/Build/juce_build_tools/utils/juce_BinaryResourceFile.cpp b/extras/Build/juce_build_tools/utils/juce_BinaryResourceFile.cpp new file mode 100644 index 00000000..fa9c3f2e --- /dev/null +++ b/extras/Build/juce_build_tools/utils/juce_BinaryResourceFile.cpp @@ -0,0 +1,287 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace build_tools +{ + static const char* resourceFileIdentifierString = "JUCER_BINARY_RESOURCE"; + + //============================================================================== + void ResourceFile::setClassName (const String& name) + { + className = name; + } + + void ResourceFile::addFile (const File& file) + { + files.add (file); + + auto variableNameRoot = makeBinaryDataIdentifierName (file); + auto variableName = variableNameRoot; + + int suffix = 2; + + while (variableNames.contains (variableName)) + variableName = variableNameRoot + String (suffix++); + + variableNames.add (variableName); + } + + String ResourceFile::getDataVariableFor (const File& file) const + { + const auto index = files.indexOf (file); + jassert (index >= 0); + return variableNames[index]; + } + + String ResourceFile::getSizeVariableFor (const File& file) const + { + return getDataVariableFor (file) + "Size"; + } + + int64 ResourceFile::getTotalDataSize() const + { + return std::accumulate (files.begin(), + files.end(), + int64 { 0 }, + [] (int64 acc, const File& f) { return acc + f.getSize(); }); + } + + static void writeComment (MemoryOutputStream& mo) + { + mo << newLine << newLine + << " This is an auto-generated file: Any edits you make may be overwritten!" << newLine + << newLine + << "*/" << newLine + << newLine; + } + + Result ResourceFile::writeHeader (MemoryOutputStream& header) + { + header << "/* ========================================================================================="; + writeComment (header); + header << "#pragma once" << newLine + << newLine + << "namespace " << className << newLine + << "{" << newLine; + + for (int i = 0; i < files.size(); ++i) + { + auto& file = files.getReference(i); + + if (! file.existsAsFile()) + return Result::fail ("Can't open resource file: " + file.getFullPathName()); + + auto dataSize = file.getSize(); + + auto variableName = variableNames[i]; + + FileInputStream fileStream (file); + + if (fileStream.openedOk()) + { + header << " extern const char* " << variableName << ";" << newLine; + header << " const int " << variableName << "Size = " << (int) dataSize << ";" << newLine << newLine; + } + } + + header << " // Number of elements in the namedResourceList and originalFileNames arrays." << newLine + << " const int namedResourceListSize = " << files.size() << ";" << newLine + << newLine + << " // Points to the start of a list of resource names." << newLine + << " extern const char* namedResourceList[];" << newLine + << newLine + << " // Points to the start of a list of resource filenames." << newLine + << " extern const char* originalFilenames[];" << newLine + << newLine + << " // If you provide the name of one of the binary resource variables above, this function will" << newLine + << " // return the corresponding data and its size (or a null pointer if the name isn't found)." << newLine + << " const char* getNamedResource (const char* resourceNameUTF8, int& dataSizeInBytes);" << newLine + << newLine + << " // If you provide the name of one of the binary resource variables above, this function will" << newLine + << " // return the corresponding original, non-mangled filename (or a null pointer if the name isn't found)." << newLine + << " const char* getNamedResourceOriginalFilename (const char* resourceNameUTF8);" << newLine + << "}" << newLine; + + return Result::ok(); + } + + Result ResourceFile::writeCpp (MemoryOutputStream& cpp, const File& headerFile, int& i, const int maxFileSize) + { + bool isFirstFile = (i == 0); + + cpp << "/* ==================================== " << resourceFileIdentifierString << " ===================================="; + writeComment (cpp); + cpp << "namespace " << className << newLine + << "{" << newLine; + + while (i < files.size()) + { + auto& file = files.getReference(i); + auto variableName = variableNames[i]; + + FileInputStream fileStream (file); + + if (fileStream.openedOk()) + { + auto tempVariable = "temp_binary_data_" + String (i); + + cpp << newLine << "//================== " << file.getFileName() << " ==================" << newLine + << "static const unsigned char " << tempVariable << "[] =" << newLine; + + { + MemoryBlock data; + fileStream.readIntoMemoryBlock (data); + writeDataAsCppLiteral (data, cpp, true, true); + } + + cpp << newLine << newLine + << "const char* " << variableName << " = (const char*) " << tempVariable << ";" << newLine; + } + + ++i; + + if (cpp.getPosition() > maxFileSize) + break; + } + + if (isFirstFile) + { + if (i < files.size()) + { + cpp << newLine + << "}" << newLine + << newLine + << "#include \"" << headerFile.getFileName() << "\"" << newLine + << newLine + << "namespace " << className << newLine + << "{"; + } + + cpp << newLine + << newLine + << "const char* getNamedResource (const char* resourceNameUTF8, int& numBytes)" << newLine + << "{" << newLine; + + StringArray returnCodes; + for (auto& file : files) + { + auto dataSize = file.getSize(); + returnCodes.add ("numBytes = " + String (dataSize) + "; return " + variableNames[files.indexOf (file)] + ";"); + } + + createStringMatcher (cpp, "resourceNameUTF8", variableNames, returnCodes, 4); + + cpp << " numBytes = 0;" << newLine + << " return nullptr;" << newLine + << "}" << newLine + << newLine; + + cpp << "const char* namedResourceList[] =" << newLine + << "{" << newLine; + + for (int j = 0; j < files.size(); ++j) + cpp << " " << variableNames[j].quoted() << (j < files.size() - 1 ? "," : "") << newLine; + + cpp << "};" << newLine << newLine; + + cpp << "const char* originalFilenames[] =" << newLine + << "{" << newLine; + + for (auto& f : files) + cpp << " " << f.getFileName().quoted() << (files.indexOf (f) < files.size() - 1 ? "," : "") << newLine; + + cpp << "};" << newLine << newLine; + + cpp << "const char* getNamedResourceOriginalFilename (const char* resourceNameUTF8)" << newLine + << "{" << newLine + << " for (unsigned int i = 0; i < (sizeof (namedResourceList) / sizeof (namedResourceList[0])); ++i)" << newLine + << " {" << newLine + << " if (namedResourceList[i] == resourceNameUTF8)" << newLine + << " return originalFilenames[i];" << newLine + << " }" << newLine + << newLine + << " return nullptr;" << newLine + << "}" << newLine + << newLine; + } + + cpp << "}" << newLine; + + return Result::ok(); + } + + ResourceFile::WriteResult ResourceFile::write (int maxFileSize, + String projectLineFeed, + File headerFile, + std::function<File (int)> getCppFile) + { + Array<File> filesCreated; + + { + MemoryOutputStream mo; + mo.setNewLineString (projectLineFeed); + + auto r = writeHeader (mo); + + if (r.failed()) + return { r, {} }; + + if (! overwriteFileWithNewDataIfDifferent (headerFile, mo)) + return { Result::fail ("Can't write to file: " + headerFile.getFullPathName()), {} }; + + filesCreated.add (headerFile); + } + + int i = 0; + int fileIndex = 0; + + for (;;) + { + auto cpp = getCppFile (fileIndex); + + MemoryOutputStream mo; + mo.setNewLineString (projectLineFeed); + + auto r = writeCpp (mo, headerFile, i, maxFileSize); + + if (r.failed()) + return { r, std::move (filesCreated) }; + + if (! overwriteFileWithNewDataIfDifferent (cpp, mo)) + return { Result::fail ("Can't write to file: " + cpp.getFullPathName()), std::move (filesCreated) }; + + filesCreated.add (cpp); + ++fileIndex; + + if (i >= files.size()) + break; + } + + return { Result::ok(), std::move (filesCreated) }; + } +} +} diff --git a/extras/Build/juce_build_tools/utils/juce_BinaryResourceFile.h b/extras/Build/juce_build_tools/utils/juce_BinaryResourceFile.h new file mode 100644 index 00000000..5c137626 --- /dev/null +++ b/extras/Build/juce_build_tools/utils/juce_BinaryResourceFile.h @@ -0,0 +1,74 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace build_tools +{ + class ResourceFile + { + public: + ResourceFile() = default; + + void setClassName (const String& className); + + String getClassName() const { return className; } + + void addFile (const File& file); + + String getDataVariableFor (const File& file) const; + + String getSizeVariableFor (const File& file) const; + + int getNumFiles() const { return files.size (); } + + const File& getFile (int index) const { return files.getReference (index); } + + int64 getTotalDataSize() const; + + struct WriteResult + { + Result result; + Array<File> filesCreated; + }; + + WriteResult write (int maxFileSize, + String projectLineFeed, + File headerFile, + std::function<File (int)> getCppFile); + + private: + Array<File> files; + StringArray variableNames; + String className { "BinaryData" }; + + Result writeHeader (MemoryOutputStream&); + + Result writeCpp (MemoryOutputStream&, const File&, int&, int); + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ResourceFile) + }; +} +} diff --git a/extras/Build/juce_build_tools/utils/juce_BuildHelperFunctions.cpp b/extras/Build/juce_build_tools/utils/juce_BuildHelperFunctions.cpp new file mode 100644 index 00000000..1e193e58 --- /dev/null +++ b/extras/Build/juce_build_tools/utils/juce_BuildHelperFunctions.cpp @@ -0,0 +1,351 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace build_tools +{ + void overwriteFileIfDifferentOrThrow (const File& file, const MemoryOutputStream& newData) + { + if (! overwriteFileWithNewDataIfDifferent (file, newData)) + throw SaveError (file); + } + + void overwriteFileIfDifferentOrThrow (const File& file, const String& newData) + { + if (! overwriteFileWithNewDataIfDifferent (file, newData)) + throw SaveError (file); + } + + String replacePreprocessorDefs (const StringPairArray& definitions, String sourceString) + { + for (int i = 0; i < definitions.size(); ++i) + { + const String key (definitions.getAllKeys()[i]); + const String value (definitions.getAllValues()[i]); + + sourceString = sourceString.replace ("${" + key + "}", value); + } + + return sourceString; + } + + String getXcodePackageType (ProjectType::Target::Type type) + { + switch (type) + { + case ProjectType::Target::Type::GUIApp: + case ProjectType::Target::Type::StandalonePlugIn: + return "APPL"; + + case ProjectType::Target::Type::VSTPlugIn: + case ProjectType::Target::Type::VST3PlugIn: + case ProjectType::Target::Type::AudioUnitPlugIn: + case ProjectType::Target::Type::UnityPlugIn: + return "BNDL"; + + case ProjectType::Target::Type::AudioUnitv3PlugIn: + return "XPC!"; + + case ProjectType::Target::Type::AAXPlugIn: + case ProjectType::Target::Type::RTASPlugIn: + return "TDMw"; + + case ProjectType::Target::Type::ConsoleApp: + case ProjectType::Target::Type::StaticLibrary: + case ProjectType::Target::Type::DynamicLibrary: + case ProjectType::Target::Type::SharedCodeTarget: + case ProjectType::Target::Type::AggregateTarget: + case ProjectType::Target::Type::unspecified: + default: + return {}; + } + } + + String getXcodeBundleSignature (ProjectType::Target::Type type) + { + switch (type) + { + case ProjectType::Target::Type::GUIApp: + case ProjectType::Target::Type::VSTPlugIn: + case ProjectType::Target::Type::VST3PlugIn: + case ProjectType::Target::Type::AudioUnitPlugIn: + case ProjectType::Target::Type::StandalonePlugIn: + case ProjectType::Target::Type::AudioUnitv3PlugIn: + case ProjectType::Target::Type::UnityPlugIn: + return "????"; + + case ProjectType::Target::Type::AAXPlugIn: + case ProjectType::Target::Type::RTASPlugIn: + return "PTul"; + + case ProjectType::Target::Type::ConsoleApp: + case ProjectType::Target::Type::StaticLibrary: + case ProjectType::Target::Type::DynamicLibrary: + case ProjectType::Target::Type::SharedCodeTarget: + case ProjectType::Target::Type::AggregateTarget: + case ProjectType::Target::Type::unspecified: + default: + return {}; + } + } + + static unsigned int calculateHash (const String& s, const unsigned int hashMultiplier) + { + auto t = s.toUTF8(); + unsigned int hash = 0; + + while (*t != 0) + hash = hashMultiplier * hash + (unsigned int) *t++; + + return hash; + } + + static unsigned int findBestHashMultiplier (const StringArray& strings) + { + unsigned int v = 31; + + for (;;) + { + SortedSet<unsigned int> hashes; + bool collision = false; + + for (int i = strings.size(); --i >= 0;) + { + auto hash = calculateHash (strings[i], v); + + if (hashes.contains (hash)) + { + collision = true; + break; + } + + hashes.add (hash); + } + + if (! collision) + break; + + v += 2; + } + + return v; + } + + String makeValidIdentifier (String s, bool makeCamelCase, bool removeColons, bool allowTemplates, bool allowAsterisks) + { + if (s.isEmpty()) + return "unknown"; + + if (removeColons) + s = s.replaceCharacters (".,;:/@", "______"); + else + s = s.replaceCharacters (".,;/@", "_____"); + + for (int i = s.length(); --i > 0;) + if (CharacterFunctions::isLetter (s[i]) + && CharacterFunctions::isLetter (s[i - 1]) + && CharacterFunctions::isUpperCase (s[i]) + && ! CharacterFunctions::isUpperCase (s[i - 1])) + s = s.substring (0, i) + " " + s.substring (i); + + String allowedChars ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_ 0123456789"); + if (allowTemplates) + allowedChars += "<>"; + + if (! removeColons) + allowedChars += ":"; + + if (allowAsterisks) + allowedChars += "*"; + + StringArray words; + words.addTokens (s.retainCharacters (allowedChars), false); + words.trim(); + + auto n = words[0]; + + if (makeCamelCase) + n = n.toLowerCase(); + + for (int i = 1; i < words.size(); ++i) + { + if (makeCamelCase && words[i].length() > 1) + n << words[i].substring (0, 1).toUpperCase() + << words[i].substring (1).toLowerCase(); + else + n << words[i]; + } + + if (CharacterFunctions::isDigit (n[0])) + n = "_" + n; + + if (isReservedKeyword (n)) + n << '_'; + + return n; + } + + String makeBinaryDataIdentifierName (const File& file) + { + return makeValidIdentifier (file.getFileName() + .replaceCharacters (" .", "__") + .retainCharacters ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_0123456789"), + false, true, false); + } + + void writeDataAsCppLiteral (const MemoryBlock& mb, OutputStream& out, + bool breakAtNewLines, bool allowStringBreaks) + { + const int maxCharsOnLine = 250; + + auto data = (const unsigned char*) mb.getData(); + int charsOnLine = 0; + + bool canUseStringLiteral = mb.getSize() < 32768; // MS compilers can't handle big string literals.. + + if (canUseStringLiteral) + { + unsigned int numEscaped = 0; + + for (size_t i = 0; i < mb.getSize(); ++i) + { + auto num = (unsigned int) data[i]; + + if (! ((num >= 32 && num < 127) || num == '\t' || num == '\r' || num == '\n')) + { + if (++numEscaped > mb.getSize() / 4) + { + canUseStringLiteral = false; + break; + } + } + } + } + + if (! canUseStringLiteral) + { + out << "{ "; + + for (size_t i = 0; i < mb.getSize(); ++i) + { + auto num = (int) (unsigned int) data[i]; + out << num << ','; + + charsOnLine += 2; + + if (num >= 10) + { + ++charsOnLine; + + if (num >= 100) + ++charsOnLine; + } + + if (charsOnLine >= maxCharsOnLine) + { + charsOnLine = 0; + out << newLine; + } + } + + out << "0,0 };"; + } + else + { + out << "\""; + writeEscapeChars (out, (const char*) data, (int) mb.getSize(), + maxCharsOnLine, breakAtNewLines, false, allowStringBreaks); + out << "\";"; + } + } + + void createStringMatcher (OutputStream& out, const String& utf8PointerVariable, + const StringArray& strings, const StringArray& codeToExecute, const int indentLevel) + { + jassert (strings.size() == codeToExecute.size()); + auto indent = String::repeatedString (" ", indentLevel); + auto hashMultiplier = findBestHashMultiplier (strings); + + out << indent << "unsigned int hash = 0;" << newLine + << newLine + << indent << "if (" << utf8PointerVariable << " != nullptr)" << newLine + << indent << " while (*" << utf8PointerVariable << " != 0)" << newLine + << indent << " hash = " << (int) hashMultiplier << " * hash + (unsigned int) *" << utf8PointerVariable << "++;" << newLine + << newLine + << indent << "switch (hash)" << newLine + << indent << "{" << newLine; + + for (int i = 0; i < strings.size(); ++i) + { + out << indent << " case 0x" << hexString8Digits ((int) calculateHash (strings[i], hashMultiplier)) + << ": " << codeToExecute[i] << newLine; + } + + out << indent << " default: break;" << newLine + << indent << "}" << newLine << newLine; + } + + String unixStylePath (const String& path) { return path.replaceCharacter ('\\', '/'); } + String windowsStylePath (const String& path) { return path.replaceCharacter ('/', '\\'); } + + String currentOSStylePath (const String& path) + { + #if JUCE_WINDOWS + return windowsStylePath (path); + #else + return unixStylePath (path); + #endif + } + + bool isAbsolutePath (const String& path) + { + return File::isAbsolutePath (path) + || path.startsWithChar ('/') // (needed because File::isAbsolutePath will ignore forward-slashes on Windows) + || path.startsWithChar ('$') + || path.startsWithChar ('~') + || (CharacterFunctions::isLetter (path[0]) && path[1] == ':') + || path.startsWithIgnoreCase ("smb:"); + } + + String getRelativePathFrom (const File& file, const File& sourceFolder) + { + #if ! JUCE_WINDOWS + // On a non-windows machine, we can't know if a drive-letter path may be relative or not. + if (CharacterFunctions::isLetter (file.getFullPathName()[0]) && file.getFullPathName()[1] == ':') + return file.getFullPathName(); + #endif + + return file.getRelativePathFrom (sourceFolder); + } + + void writeStreamToFile (const File& file, const std::function<void (MemoryOutputStream&)>& writer) + { + MemoryOutputStream mo; + writer (mo); + overwriteFileIfDifferentOrThrow (file, mo); + } +} +} diff --git a/extras/Build/juce_build_tools/utils/juce_BuildHelperFunctions.h b/extras/Build/juce_build_tools/utils/juce_BuildHelperFunctions.h new file mode 100644 index 00000000..74da0fdd --- /dev/null +++ b/extras/Build/juce_build_tools/utils/juce_BuildHelperFunctions.h @@ -0,0 +1,86 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace build_tools +{ + void overwriteFileIfDifferentOrThrow (const File& file, const MemoryOutputStream& newData); + void overwriteFileIfDifferentOrThrow (const File& file, const String& newData); + + class SaveError + { + public: + SaveError (const String& error) : message (error) + {} + + SaveError (const File& fileThatFailedToWrite) + : message ("Can't write to the file: " + fileThatFailedToWrite.getFullPathName()) + {} + + String message; + }; + + String replacePreprocessorDefs (const StringPairArray& definitions, String sourceString); + + String getXcodePackageType (ProjectType::Target::Type); + String getXcodeBundleSignature (ProjectType::Target::Type); + + inline String hexString8Digits (int value) + { + return String::toHexString (value).paddedLeft ('0', 8); + } + + String makeValidIdentifier (String s, + bool makeCamelCase, + bool removeColons, + bool allowTemplates, + bool allowAsterisks = false); + + String makeBinaryDataIdentifierName (const File& file); + + void writeDataAsCppLiteral (const MemoryBlock& mb, + OutputStream& out, + bool breakAtNewLines, + bool allowStringBreaks); + + void createStringMatcher (OutputStream& out, + const String& utf8PointerVariable, + const StringArray& strings, + const StringArray& codeToExecute, + const int indentLevel); + + String unixStylePath (const String& path); + String windowsStylePath (const String& path); + String currentOSStylePath (const String& path); + + bool isAbsolutePath (const String& path); + + // A windows-aware version of File::getRelativePath() + String getRelativePathFrom (const File& file, const File& sourceFolder); + + void writeStreamToFile (const File& file, const std::function<void (MemoryOutputStream&)>& writer); +} +} diff --git a/extras/Build/juce_build_tools/utils/juce_CppTokeniserFunctions.cpp b/extras/Build/juce_build_tools/utils/juce_CppTokeniserFunctions.cpp new file mode 100644 index 00000000..412936f5 --- /dev/null +++ b/extras/Build/juce_build_tools/utils/juce_CppTokeniserFunctions.cpp @@ -0,0 +1,206 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace build_tools +{ + static bool isReservedKeyword (String::CharPointerType token, const int tokenLength) noexcept + { + static const char* const keywords2Char[] = + { "do", "if", "or", nullptr }; + + static const char* const keywords3Char[] = + { "and", "asm", "for", "int", "new", "not", "try", "xor", nullptr }; + + static const char* const keywords4Char[] = + { "auto", "bool", "case", "char", "else", "enum", "goto", + "long", "this", "true", "void", nullptr }; + + static const char* const keywords5Char[] = + { "bitor", "break", "catch", "class", "compl", "const", "false", "final", + "float", "or_eq", "short", "throw", "union", "using", "while", nullptr }; + + static const char* const keywords6Char[] = + { "and_eq", "bitand", "delete", "double", "export", "extern", "friend", + "import", "inline", "module", "not_eq", "public", "return", "signed", + "sizeof", "static", "struct", "switch", "typeid", "xor_eq", nullptr }; + + static const char* const keywords7Char[] = + { "__cdecl", "_Pragma", "alignas", "alignof", "concept", "default", + "mutable", "nullptr", "private", "typedef", "uint8_t", "virtual", + "wchar_t", nullptr }; + + static const char* const keywordsOther[] = + { "@class", "@dynamic", "@end", "@implementation", "@interface", "@public", + "@private", "@protected", "@property", "@synthesize", "__fastcall", "__stdcall", + "atomic_cancel", "atomic_commit", "atomic_noexcept", "char16_t", "char32_t", + "co_await", "co_return", "co_yield", "const_cast", "constexpr", "continue", + "decltype", "dynamic_cast", "explicit", "namespace", "noexcept", "operator", "override", + "protected", "register", "reinterpret_cast", "requires", "static_assert", + "static_cast", "synchronized", "template", "thread_local", "typename", "unsigned", + "volatile", nullptr }; + + const char* const* k; + + switch (tokenLength) + { + case 2: k = keywords2Char; break; + case 3: k = keywords3Char; break; + case 4: k = keywords4Char; break; + case 5: k = keywords5Char; break; + case 6: k = keywords6Char; break; + case 7: k = keywords7Char; break; + + default: + if (tokenLength < 2 || tokenLength > 16) + return false; + + k = keywordsOther; + break; + } + + for (int i = 0; k[i] != nullptr; ++i) + if (token.compare (CharPointer_ASCII (k[i])) == 0) + return true; + + return false; + } + + static bool isReservedKeyword (const String& token) noexcept + { + return isReservedKeyword (token.getCharPointer(), token.length()); + } + + //============================================================================== + /** Takes a UTF8 string and writes it to a stream using standard C++ escape sequences for any + non-ascii bytes. + + Although not strictly a tokenising function, this is still a function that often comes in + handy when working with C++ code! + + Note that addEscapeChars() is easier to use than this function if you're working with Strings. + + @see addEscapeChars + */ + static void writeEscapeChars (OutputStream& out, const char* utf8, const int numBytesToRead, + const int maxCharsOnLine, const bool breakAtNewLines, + const bool replaceSingleQuotes, const bool allowStringBreaks) + { + int charsOnLine = 0; + bool lastWasHexEscapeCode = false; + bool trigraphDetected = false; + + for (int i = 0; i < numBytesToRead || numBytesToRead < 0; ++i) + { + auto c = (unsigned char) utf8[i]; + bool startNewLine = false; + + switch (c) + { + + case '\t': out << "\\t"; trigraphDetected = false; lastWasHexEscapeCode = false; charsOnLine += 2; break; + case '\r': out << "\\r"; trigraphDetected = false; lastWasHexEscapeCode = false; charsOnLine += 2; break; + case '\n': out << "\\n"; trigraphDetected = false; lastWasHexEscapeCode = false; charsOnLine += 2; startNewLine = breakAtNewLines; break; + case '\\': out << "\\\\"; trigraphDetected = false; lastWasHexEscapeCode = false; charsOnLine += 2; break; + case '\"': out << "\\\""; trigraphDetected = false; lastWasHexEscapeCode = false; charsOnLine += 2; break; + + case '?': + if (trigraphDetected) + { + out << "\\?"; + charsOnLine++; + trigraphDetected = false; + } + else + { + out << "?"; + trigraphDetected = true; + } + + lastWasHexEscapeCode = false; + charsOnLine++; + break; + + case 0: + if (numBytesToRead < 0) + return; + + out << "\\0"; + lastWasHexEscapeCode = true; + trigraphDetected = false; + charsOnLine += 2; + break; + + case '\'': + if (replaceSingleQuotes) + { + out << "\\\'"; + lastWasHexEscapeCode = false; + trigraphDetected = false; + charsOnLine += 2; + break; + } + + // deliberate fall-through... + + default: + if (c >= 32 && c < 127 && ! (lastWasHexEscapeCode // (have to avoid following a hex escape sequence with a valid hex digit) + && CharacterFunctions::getHexDigitValue (c) >= 0)) + { + out << (char) c; + lastWasHexEscapeCode = false; + trigraphDetected = false; + ++charsOnLine; + } + else if (allowStringBreaks && lastWasHexEscapeCode && c >= 32 && c < 127) + { + out << "\"\"" << (char) c; + lastWasHexEscapeCode = false; + trigraphDetected = false; + charsOnLine += 3; + } + else + { + out << (c < 16 ? "\\x0" : "\\x") << String::toHexString ((int) c); + lastWasHexEscapeCode = true; + trigraphDetected = false; + charsOnLine += 4; + } + + break; + } + + if ((startNewLine || (maxCharsOnLine > 0 && charsOnLine >= maxCharsOnLine)) + && (numBytesToRead < 0 || i < numBytesToRead - 1)) + { + charsOnLine = 0; + out << "\"" << newLine << "\""; + lastWasHexEscapeCode = false; + } + } + } +} +} diff --git a/extras/Build/juce_build_tools/utils/juce_Entitlements.cpp b/extras/Build/juce_build_tools/utils/juce_Entitlements.cpp new file mode 100644 index 00000000..779c62e6 --- /dev/null +++ b/extras/Build/juce_build_tools/utils/juce_Entitlements.cpp @@ -0,0 +1,116 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace build_tools +{ + String EntitlementOptions::getEntitlementsFileContent() const + { + String content = + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n" + "<plist version=\"1.0\">\n" + "<dict>\n"; + + const auto entitlements = getEntitlements(); + + for (auto& key : entitlements.getAllKeys()) + content += "\t<key>" + key + "</key>\n\t" + entitlements[key] + "\n"; + + return content + "</dict>\n</plist>\n"; + } + + StringPairArray EntitlementOptions::getEntitlements() const + { + StringPairArray entitlements; + + if (isiOS) + { + if (isAudioPluginProject && shouldEnableIAA) + entitlements.set ("inter-app-audio", "<true/>"); + + if (isiCloudPermissionsEnabled) + { + entitlements.set ("com.apple.developer.icloud-container-identifiers", + "<array>\n" + " <string>iCloud.$(CFBundleIdentifier)</string>\n" + " </array>"); + + entitlements.set ("com.apple.developer.icloud-services", + "<array>\n" + " <string>CloudDocuments</string>\n" + " </array>"); + + entitlements.set ("com.apple.developer.ubiquity-container-identifiers", + "<array>\n" + " <string>iCloud.$(CFBundleIdentifier)</string>\n" + " </array>"); + } + } + + if (isPushNotificationsEnabled) + entitlements.set (isiOS ? "aps-environment" + : "com.apple.developer.aps-environment", + "<string>development</string>"); + + if (isAppGroupsEnabled) + { + auto appGroups = StringArray::fromTokens (appGroupIdString, ";", {}); + auto groups = String ("<array>"); + + for (auto group : appGroups) + groups += "\n\t\t<string>" + group.trim() + "</string>"; + + groups += "\n\t</array>"; + + entitlements.set ("com.apple.security.application-groups", groups); + } + + if (isHardenedRuntimeEnabled) + for (auto& option : hardenedRuntimeOptions) + entitlements.set (option, "<true/>"); + + if (isAppSandboxEnabled || (! isiOS && isAudioPluginProject && type == ProjectType::Target::AudioUnitv3PlugIn)) + { + entitlements.set ("com.apple.security.app-sandbox", "<true/>"); + + if (isAppSandboxInhertianceEnabled) + { + // no other sandbox options can be specified if sandbox inheritance is enabled! + jassert (appSandboxOptions.isEmpty()); + + entitlements.set ("com.apple.security.inherit", "<true/>"); + } + + if (isAppSandboxEnabled) + for (auto& option : appSandboxOptions) + entitlements.set (option, "<true/>"); + } + + return entitlements; + } +} +} diff --git a/extras/Build/juce_build_tools/utils/juce_Entitlements.h b/extras/Build/juce_build_tools/utils/juce_Entitlements.h new file mode 100644 index 00000000..97b2fdbb --- /dev/null +++ b/extras/Build/juce_build_tools/utils/juce_Entitlements.h @@ -0,0 +1,55 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace build_tools +{ + struct EntitlementOptions final + { + String getEntitlementsFileContent() const; + + ProjectType::Target::Type type = ProjectType::Target::GUIApp; + + bool isiOS = false; + bool isAudioPluginProject = false; + bool shouldEnableIAA = false; + bool isiCloudPermissionsEnabled = false; + bool isPushNotificationsEnabled = false; + bool isAppGroupsEnabled = false; + bool isHardenedRuntimeEnabled = false; + bool isAppSandboxEnabled = false; + bool isAppSandboxInhertianceEnabled = false; + + String appGroupIdString; + + StringArray hardenedRuntimeOptions; + StringArray appSandboxOptions; + + private: + StringPairArray getEntitlements() const; + }; +} +} diff --git a/extras/Build/juce_build_tools/utils/juce_Icons.cpp b/extras/Build/juce_build_tools/utils/juce_Icons.cpp new file mode 100644 index 00000000..c0e51acc --- /dev/null +++ b/extras/Build/juce_build_tools/utils/juce_Icons.cpp @@ -0,0 +1,505 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace build_tools +{ + Array<Drawable*> asArray (const Icons& icons) + { + Array<Drawable*> result; + + if (icons.small != nullptr) + result.add (icons.small.get()); + + if (icons.big != nullptr) + result.add (icons.big.get()); + + return result; + } + + namespace mac + { + static Image fixIconImageSize (Drawable& image) + { + const int validSizes[] = { 16, 32, 64, 128, 256, 512, 1024 }; + + auto w = image.getWidth(); + auto h = image.getHeight(); + + int bestSize = 16; + + for (int size : validSizes) + { + if (w == h && w == size) + { + bestSize = w; + break; + } + + if (jmax (w, h) > size) + bestSize = size; + } + + return rescaleImageForIcon (image, bestSize); + } + + static void writeIconData (MemoryOutputStream& out, const Image& image, const char* type) + { + MemoryOutputStream pngData; + PNGImageFormat pngFormat; + pngFormat.writeImageToStream (image, pngData); + + out.write (type, 4); + out.writeIntBigEndian (8 + (int) pngData.getDataSize()); + out << pngData; + } + } // namespace mac + + static void writeMacIcon (const Icons& icons, OutputStream& out) + { + MemoryOutputStream data; + auto smallest = std::numeric_limits<int>::max(); + Drawable* smallestImage = nullptr; + + const auto images = asArray (icons); + + for (int i = 0; i < images.size(); ++i) + { + auto image = mac::fixIconImageSize (*images[i]); + jassert (image.getWidth() == image.getHeight()); + + if (image.getWidth() < smallest) + { + smallest = image.getWidth(); + smallestImage = images[i]; + } + + switch (image.getWidth()) + { + case 16: mac::writeIconData (data, image, "icp4"); break; + case 32: mac::writeIconData (data, image, "icp5"); break; + case 64: mac::writeIconData (data, image, "icp6"); break; + case 128: mac::writeIconData (data, image, "ic07"); break; + case 256: mac::writeIconData (data, image, "ic08"); break; + case 512: mac::writeIconData (data, image, "ic09"); break; + case 1024: mac::writeIconData (data, image, "ic10"); break; + default: break; + } + } + + jassert (data.getDataSize() > 0); // no suitable sized images? + + // If you only supply a 1024 image, the file doesn't work on 10.8, so we need + // to force a smaller one in there too.. + if (smallest > 512 && smallestImage != nullptr) + mac::writeIconData (data, rescaleImageForIcon (*smallestImage, 512), "ic09"); + + out.write ("icns", 4); + out.writeIntBigEndian ((int) data.getDataSize() + 8); + out << data; + } + + Image getBestIconForSize (const Icons& icons, + int size, + bool returnNullIfNothingBigEnough) + { + auto* const im = [&]() -> Drawable* + { + if ((icons.small != nullptr) != (icons.big != nullptr)) + return icons.small != nullptr ? icons.small.get() : icons.big.get(); + + if (icons.small != nullptr && icons.big != nullptr) + { + if (icons.small->getWidth() >= size && icons.big->getWidth() >= size) + return icons.small->getWidth() < icons.big->getWidth() ? icons.small.get() : icons.big.get(); + + if (icons.small->getWidth() >= size) + return icons.small.get(); + + if (icons.big->getWidth() >= size) + return icons.big.get(); + } + + return nullptr; + }(); + + if (im == nullptr) + return {}; + + if (returnNullIfNothingBigEnough && im->getWidth() < size && im->getHeight() < size) + return {}; + + return rescaleImageForIcon (*im, size); + } + + namespace win + { + static void writeBMPImage (const Image& image, const int w, const int h, MemoryOutputStream& out) + { + int maskStride = (w / 8 + 3) & ~3; + + out.writeInt (40); // bitmapinfoheader size + out.writeInt (w); + out.writeInt (h * 2); + out.writeShort (1); // planes + out.writeShort (32); // bits + out.writeInt (0); // compression + out.writeInt ((h * w * 4) + (h * maskStride)); // size image + out.writeInt (0); // x pixels per meter + out.writeInt (0); // y pixels per meter + out.writeInt (0); // clr used + out.writeInt (0); // clr important + + Image::BitmapData bitmap (image, Image::BitmapData::readOnly); + int alphaThreshold = 5; + + int y; + for (y = h; --y >= 0;) + { + for (int x = 0; x < w; ++x) + { + auto pixel = bitmap.getPixelColour (x, y); + + if (pixel.getAlpha() <= alphaThreshold) + { + out.writeInt (0); + } + else + { + out.writeByte ((char) pixel.getBlue()); + out.writeByte ((char) pixel.getGreen()); + out.writeByte ((char) pixel.getRed()); + out.writeByte ((char) pixel.getAlpha()); + } + } + } + + for (y = h; --y >= 0;) + { + int mask = 0, count = 0; + + for (int x = 0; x < w; ++x) + { + auto pixel = bitmap.getPixelColour (x, y); + + mask <<= 1; + if (pixel.getAlpha() <= alphaThreshold) + mask |= 1; + + if (++count == 8) + { + out.writeByte ((char) mask); + count = 0; + mask = 0; + } + } + + if (mask != 0) + out.writeByte ((char) mask); + + for (int i = maskStride - w / 8; --i >= 0;) + out.writeByte (0); + } + } + + static void writeIcon (const Array<Image>& images, OutputStream& out) + { + out.writeShort (0); // reserved + out.writeShort (1); // .ico tag + out.writeShort ((short) images.size()); + + MemoryOutputStream dataBlock; + + int imageDirEntrySize = 16; + int dataBlockStart = 6 + images.size() * imageDirEntrySize; + + for (int i = 0; i < images.size(); ++i) + { + auto oldDataSize = dataBlock.getDataSize(); + + auto& image = images.getReference (i); + auto w = image.getWidth(); + auto h = image.getHeight(); + + if (w >= 256 || h >= 256) + { + PNGImageFormat pngFormat; + pngFormat.writeImageToStream (image, dataBlock); + } + else + { + writeBMPImage (image, w, h, dataBlock); + } + + out.writeByte ((char) w); + out.writeByte ((char) h); + out.writeByte (0); + out.writeByte (0); + out.writeShort (1); // colour planes + out.writeShort (32); // bits per pixel + out.writeInt ((int) (dataBlock.getDataSize() - oldDataSize)); + out.writeInt (dataBlockStart + (int) oldDataSize); + } + + jassert (out.getPosition() == dataBlockStart); + out << dataBlock; + } + } // namespace win + + static void writeWinIcon (const Icons& icons, OutputStream& os) + { + Array<Image> images; + int sizes[] = { 16, 32, 48, 256 }; + + for (int size : sizes) + { + auto im = getBestIconForSize (icons, size, true); + + if (im.isValid()) + images.add (im); + } + + if (images.size() > 0) + win::writeIcon (images, os); + } + + void writeMacIcon (const Icons& icons, const File& file) + { + writeStreamToFile (file, [&] (juce::MemoryOutputStream& mo) { writeMacIcon (icons, mo); }); + } + + void writeWinIcon (const Icons& icons, const File& file) + { + writeStreamToFile (file, [&] (juce::MemoryOutputStream& mo) { writeWinIcon (icons, mo); }); + } + + Image rescaleImageForIcon (Drawable& d, const int size) + { + if (auto* drawableImage = dynamic_cast<DrawableImage*> (&d)) + { + auto im = SoftwareImageType().convert (drawableImage->getImage()); + + if (im.getWidth() == size && im.getHeight() == size) + return im; + + // (scale it down in stages for better resampling) + while (im.getWidth() > 2 * size && im.getHeight() > 2 * size) + im = im.rescaled (im.getWidth() / 2, + im.getHeight() / 2); + + Image newIm (Image::ARGB, size, size, true, SoftwareImageType()); + Graphics g (newIm); + g.drawImageWithin (im, 0, 0, size, size, + RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize, false); + return newIm; + } + + Image im (Image::ARGB, size, size, true, SoftwareImageType()); + Graphics g (im); + d.drawWithin (g, im.getBounds().toFloat(), RectanglePlacement::centred, 1.0f); + return im; + } + + struct AppIconType + { + const char* idiom; + const char* sizeString; + const char* filename; + const char* scale; + int size; + }; + + static const AppIconType iOSAppIconTypes[] + { + { "iphone", "20x20", "Icon-Notification-20@2x.png", "2x", 40 }, + { "iphone", "20x20", "Icon-Notification-20@3x.png", "3x", 60 }, + { "iphone", "29x29", "Icon-29.png", "1x", 29 }, + { "iphone", "29x29", "Icon-29@2x.png", "2x", 58 }, + { "iphone", "29x29", "Icon-29@3x.png", "3x", 87 }, + { "iphone", "40x40", "Icon-Spotlight-40@2x.png", "2x", 80 }, + { "iphone", "40x40", "Icon-Spotlight-40@3x.png", "3x", 120 }, + { "iphone", "57x57", "Icon.png", "1x", 57 }, + { "iphone", "57x57", "Icon@2x.png", "2x", 114 }, + { "iphone", "60x60", "Icon-60@2x.png", "2x", 120 }, + { "iphone", "60x60", "Icon-@3x.png", "3x", 180 }, + { "ipad", "20x20", "Icon-Notifications-20.png", "1x", 20 }, + { "ipad", "20x20", "Icon-Notifications-20@2x.png", "2x", 40 }, + { "ipad", "29x29", "Icon-Small-1.png", "1x", 29 }, + { "ipad", "29x29", "Icon-Small@2x-1.png", "2x", 58 }, + { "ipad", "40x40", "Icon-Spotlight-40.png", "1x", 40 }, + { "ipad", "40x40", "Icon-Spotlight-40@2x-1.png", "2x", 80 }, + { "ipad", "50x50", "Icon-Small-50.png", "1x", 50 }, + { "ipad", "50x50", "Icon-Small-50@2x.png", "2x", 100 }, + { "ipad", "72x72", "Icon-72.png", "1x", 72 }, + { "ipad", "72x72", "Icon-72@2x.png", "2x", 144 }, + { "ipad", "76x76", "Icon-76.png", "1x", 76 }, + { "ipad", "76x76", "Icon-76@2x.png", "2x", 152 }, + { "ipad", "83.5x83.5", "Icon-83.5@2x.png", "2x", 167 }, + { "ios-marketing", "1024x1024", "Icon-AppStore-1024.png", "1x", 1024 } + }; + + static void createiOSIconFiles (const Icons& icons, File appIconSet) + { + auto* imageToUse = icons.big != nullptr ? icons.big.get() + : icons.small.get(); + + if (imageToUse != nullptr) + { + for (auto& type : iOSAppIconTypes) + { + auto image = rescaleImageForIcon (*imageToUse, type.size); + + if (image.hasAlphaChannel()) + { + Image background (Image::RGB, image.getWidth(), image.getHeight(), false); + Graphics g (background); + g.fillAll (Colours::white); + + g.drawImageWithin (image, 0, 0, image.getWidth(), image.getHeight(), + RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize); + + image = background; + } + + MemoryOutputStream pngData; + PNGImageFormat pngFormat; + pngFormat.writeImageToStream (image, pngData); + + overwriteFileIfDifferentOrThrow (appIconSet.getChildFile (type.filename), pngData); + } + } + } + + static String getiOSAssetContents (var images) + { + DynamicObject::Ptr v (new DynamicObject()); + + var info (new DynamicObject()); + info.getDynamicObject()->setProperty ("version", 1); + info.getDynamicObject()->setProperty ("author", "xcode"); + + v->setProperty ("images", images); + v->setProperty ("info", info); + + return JSON::toString (var (v.get())); + } + + //============================================================================== + static String getiOSAppIconContents() + { + var images; + + for (auto& type : iOSAppIconTypes) + { + DynamicObject::Ptr d (new DynamicObject()); + d->setProperty ("idiom", type.idiom); + d->setProperty ("size", type.sizeString); + d->setProperty ("filename", type.filename); + d->setProperty ("scale", type.scale); + images.append (var (d.get())); + } + + return getiOSAssetContents (images); + } + + struct ImageType + { + const char* orientation; + const char* idiom; + const char* subtype; + const char* extent; + const char* scale; + const char* filename; + int width; + int height; + }; + + static const ImageType iOSLaunchImageTypes[] + { + { "portrait", "iphone", nullptr, "full-screen", "2x", "LaunchImage-iphone-2x.png", 640, 960 }, + { "portrait", "iphone", "retina4", "full-screen", "2x", "LaunchImage-iphone-retina4.png", 640, 1136 }, + { "portrait", "ipad", nullptr, "full-screen", "1x", "LaunchImage-ipad-portrait-1x.png", 768, 1024 }, + { "landscape","ipad", nullptr, "full-screen", "1x", "LaunchImage-ipad-landscape-1x.png", 1024, 768 }, + { "portrait", "ipad", nullptr, "full-screen", "2x", "LaunchImage-ipad-portrait-2x.png", 1536, 2048 }, + { "landscape","ipad", nullptr, "full-screen", "2x", "LaunchImage-ipad-landscape-2x.png", 2048, 1536 } + }; + + static void createiOSLaunchImageFiles (const File& launchImageSet) + { + for (auto& type : iOSLaunchImageTypes) + { + Image image (Image::ARGB, type.width, type.height, true); // (empty black image) + image.clear (image.getBounds(), Colours::black); + + MemoryOutputStream pngData; + PNGImageFormat pngFormat; + pngFormat.writeImageToStream (image, pngData); + build_tools::overwriteFileIfDifferentOrThrow (launchImageSet.getChildFile (type.filename), pngData); + } + } + + static String getiOSLaunchImageContents() + { + var images; + + for (auto& type : iOSLaunchImageTypes) + { + DynamicObject::Ptr d (new DynamicObject()); + d->setProperty ("orientation", type.orientation); + d->setProperty ("idiom", type.idiom); + d->setProperty ("extent", type.extent); + d->setProperty ("minimum-system-version", "7.0"); + d->setProperty ("scale", type.scale); + d->setProperty ("filename", type.filename); + + if (type.subtype != nullptr) + d->setProperty ("subtype", type.subtype); + + images.append (var (d.get())); + } + + return getiOSAssetContents (images); + } + + RelativePath createXcassetsFolderFromIcons (const Icons& icons, + const File& targetFolder, + String projectFilenameRootString) + { + const auto assets = targetFolder.getChildFile (projectFilenameRootString) + .getChildFile ("Images.xcassets"); + const auto iconSet = assets.getChildFile ("AppIcon.appiconset"); + const auto launchImage = assets.getChildFile ("LaunchImage.launchimage"); + + overwriteFileIfDifferentOrThrow (iconSet.getChildFile ("Contents.json"), getiOSAppIconContents()); + createiOSIconFiles (icons, iconSet); + + overwriteFileIfDifferentOrThrow (launchImage.getChildFile ("Contents.json"), getiOSLaunchImageContents()); + createiOSLaunchImageFiles (launchImage); + + return { assets, targetFolder, RelativePath::buildTargetFolder }; + } +} +} diff --git a/extras/Build/juce_build_tools/utils/juce_Icons.h b/extras/Build/juce_build_tools/utils/juce_Icons.h new file mode 100644 index 00000000..d5590316 --- /dev/null +++ b/extras/Build/juce_build_tools/utils/juce_Icons.h @@ -0,0 +1,49 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace build_tools +{ + struct Icons + { + std::unique_ptr<Drawable> small; + std::unique_ptr<Drawable> big; + }; + + Array<Drawable*> asArray (const Icons&); + void writeMacIcon (const Icons&, const File&); + void writeWinIcon (const Icons&, const File&); + + Image getBestIconForSize (const Icons& icons, + int size, + bool returnNullIfNothingBigEnough); + Image rescaleImageForIcon (Drawable& d, const int size); + + RelativePath createXcassetsFolderFromIcons (const Icons& icons, + const File& targetFolder, + String projectFilenameRootString); +} +} diff --git a/extras/Build/juce_build_tools/utils/juce_PlistOptions.cpp b/extras/Build/juce_build_tools/utils/juce_PlistOptions.cpp new file mode 100644 index 00000000..8b23e0ee --- /dev/null +++ b/extras/Build/juce_build_tools/utils/juce_PlistOptions.cpp @@ -0,0 +1,352 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace build_tools +{ + //============================================================================== + static bool keyFoundAndNotSequentialDuplicate (XmlElement& xml, const String& key) + { + forEachXmlChildElementWithTagName (xml, element, "key") + { + if (element->getAllSubText().trim().equalsIgnoreCase (key)) + { + if (element->getNextElement() != nullptr && element->getNextElement()->hasTagName ("key")) + { + // found broken plist format (sequential duplicate), fix by removing + xml.removeChildElement (element, true); + return false; + } + + // key found (not sequential duplicate) + return true; + } + } + + // key not found + return false; + } + + static bool addKeyIfNotFound (XmlElement& xml, const String& key) + { + if (! keyFoundAndNotSequentialDuplicate (xml, key)) + { + xml.createNewChildElement ("key")->addTextElement (key); + return true; + } + + return false; + } + + static void addPlistDictionaryKey (XmlElement& xml, const String& key, const String& value) + { + if (addKeyIfNotFound (xml, key)) + xml.createNewChildElement ("string")->addTextElement (value); + } + + template <size_t N> + static void addPlistDictionaryKey (XmlElement& xml, const String& key, const char (&value) [N]) + { + addPlistDictionaryKey (xml, key, String { value }); + } + + static void addPlistDictionaryKey (XmlElement& xml, const String& key, const bool value) + { + if (addKeyIfNotFound (xml, key)) + xml.createNewChildElement (value ? "true" : "false"); + } + + static void addPlistDictionaryKey (XmlElement& xml, const String& key, int value) + { + if (addKeyIfNotFound (xml, key)) + xml.createNewChildElement ("integer")->addTextElement (String (value)); + } + + //============================================================================== + static void addArrayToPlist (XmlElement& dict, String arrayKey, const StringArray& arrayElements) + { + dict.createNewChildElement ("key")->addTextElement (arrayKey); + auto* plistStringArray = dict.createNewChildElement ("array"); + + for (auto& e : arrayElements) + plistStringArray->createNewChildElement ("string")->addTextElement (e); + } + + void PlistOptions::write (const File& infoPlistFile) const + { + writeStreamToFile (infoPlistFile, [&] (MemoryOutputStream& mo) { write (mo); }); + } + + void PlistOptions::write (MemoryOutputStream& mo) const + { + XmlElement::TextFormat format; + format.dtd = "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"; + createXML()->writeTo (mo, format); + } + + std::unique_ptr<XmlElement> PlistOptions::createXML() const + { + auto plist = parseXML (plistToMerge); + + if (plist == nullptr || ! plist->hasTagName ("plist")) + plist.reset (new XmlElement ("plist")); + + auto* dict = plist->getChildByName ("dict"); + + if (dict == nullptr) + dict = plist->createNewChildElement ("dict"); + + if (microphonePermissionEnabled) + addPlistDictionaryKey (*dict, "NSMicrophoneUsageDescription", microphonePermissionText); + + if (cameraPermissionEnabled) + addPlistDictionaryKey (*dict, "NSCameraUsageDescription", cameraPermissionText); + + if (bluetoothPermissionEnabled) + addPlistDictionaryKey (*dict, "NSBluetoothAlwaysUsageDescription", bluetoothPermissionText); + + if (iOS) + { + if (bluetoothPermissionEnabled) + addPlistDictionaryKey (*dict, "NSBluetoothPeripheralUsageDescription", bluetoothPermissionText); // needed for pre iOS 13.0 + + addPlistDictionaryKey (*dict, "LSRequiresIPhoneOS", true); + + if (type != ProjectType::Target::AudioUnitv3PlugIn) + addPlistDictionaryKey (*dict, "UIViewControllerBasedStatusBarAppearance", false); + + if (shouldAddStoryboardToProject) + addPlistDictionaryKey (*dict, "UILaunchStoryboardName", storyboardName); + } + else + { + if (sendAppleEventsPermissionEnabled) + addPlistDictionaryKey (*dict, "NSAppleEventsUsageDescription", sendAppleEventsPermissionText); + } + + addPlistDictionaryKey (*dict, "CFBundleExecutable", executableName); + + if (! iOS) // (NB: on iOS this causes error ITMS-90032 during publishing) + addPlistDictionaryKey (*dict, "CFBundleIconFile", iconFile.exists() ? iconFile.getFileName() : String()); + + addPlistDictionaryKey (*dict, "CFBundleIdentifier", bundleIdentifier); + addPlistDictionaryKey (*dict, "CFBundleName", projectName); + + // needed by NSExtension on iOS + addPlistDictionaryKey (*dict, "CFBundleDisplayName", projectName); + addPlistDictionaryKey (*dict, "CFBundlePackageType", getXcodePackageType (type)); + addPlistDictionaryKey (*dict, "CFBundleSignature", getXcodeBundleSignature (type)); + addPlistDictionaryKey (*dict, "CFBundleShortVersionString", version); + addPlistDictionaryKey (*dict, "CFBundleVersion", version); + addPlistDictionaryKey (*dict, "NSHumanReadableCopyright", companyCopyright); + addPlistDictionaryKey (*dict, "NSHighResolutionCapable", true); + + auto replacedDocExtensions = StringArray::fromTokens (replacePreprocessorDefs (allPreprocessorDefs, + documentExtensions), ",", {}); + replacedDocExtensions.trim(); + replacedDocExtensions.removeEmptyStrings (true); + + if (! replacedDocExtensions.isEmpty() && type != ProjectType::Target::AudioUnitv3PlugIn) + { + dict->createNewChildElement ("key")->addTextElement ("CFBundleDocumentTypes"); + auto* dict2 = dict->createNewChildElement ("array")->createNewChildElement ("dict"); + XmlElement* arrayTag = nullptr; + + for (auto ex : replacedDocExtensions) + { + if (ex.startsWithChar ('.')) + ex = ex.substring (1); + + if (arrayTag == nullptr) + { + dict2->createNewChildElement ("key")->addTextElement ("CFBundleTypeExtensions"); + arrayTag = dict2->createNewChildElement ("array"); + + addPlistDictionaryKey (*dict2, "CFBundleTypeName", ex); + addPlistDictionaryKey (*dict2, "CFBundleTypeRole", "Editor"); + addPlistDictionaryKey (*dict2, "CFBundleTypeIconFile", "Icon"); + addPlistDictionaryKey (*dict2, "NSPersistentStoreTypeKey", "XML"); + } + + arrayTag->createNewChildElement ("string")->addTextElement (ex); + } + } + + if (fileSharingEnabled && type != ProjectType::Target::AudioUnitv3PlugIn) + addPlistDictionaryKey (*dict, "UIFileSharingEnabled", true); + + if (documentBrowserEnabled) + addPlistDictionaryKey (*dict, "UISupportsDocumentBrowser", true); + + if (statusBarHidden && type != ProjectType::Target::AudioUnitv3PlugIn) + addPlistDictionaryKey (*dict, "UIStatusBarHidden", true); + + if (iOS) + { + if (type != ProjectType::Target::AudioUnitv3PlugIn) + { + // Forcing full screen disables the split screen feature and prevents error ITMS-90475 + addPlistDictionaryKey (*dict, "UIRequiresFullScreen", true); + addPlistDictionaryKey (*dict, "UIStatusBarHidden", true); + + addIosScreenOrientations (*dict); + addIosBackgroundModes (*dict); + } + + if (type == ProjectType::Target::StandalonePlugIn && enableIAA) + { + XmlElement audioComponentsPlistKey ("key"); + audioComponentsPlistKey.addTextElement ("AudioComponents"); + + dict->addChildElement (new XmlElement (audioComponentsPlistKey)); + + XmlElement audioComponentsPlistEntry ("array"); + auto* audioComponentsDict = audioComponentsPlistEntry.createNewChildElement ("dict"); + + addPlistDictionaryKey (*audioComponentsDict, "name", IAAPluginName); + addPlistDictionaryKey (*audioComponentsDict, "manufacturer", pluginManufacturerCode.substring (0, 4)); + addPlistDictionaryKey (*audioComponentsDict, "type", IAATypeCode); + addPlistDictionaryKey (*audioComponentsDict, "subtype", pluginCode.substring (0, 4)); + addPlistDictionaryKey (*audioComponentsDict, "version", versionAsHex); + + dict->addChildElement (new XmlElement (audioComponentsPlistEntry)); + } + } + + const auto extraOptions = [&]() -> Array<XmlElement> + { + if (type == ProjectType::Target::Type::AudioUnitPlugIn) + return createExtraAudioUnitTargetPlistOptions(); + + if (type == ProjectType::Target::Type::AudioUnitv3PlugIn) + return createExtraAudioUnitV3TargetPlistOptions(); + + return {}; + }(); + + for (auto& e : extraOptions) + dict->addChildElement (new XmlElement (e)); + + return plist; + } + + void PlistOptions::addIosScreenOrientations (XmlElement& dict) const + { + addArrayToPlist (dict, "UISupportedInterfaceOrientations", iPhoneScreenOrientations); + + if (iPadScreenOrientations != iPhoneScreenOrientations) + addArrayToPlist (dict, "UISupportedInterfaceOrientations~ipad", iPadScreenOrientations); + } + + void PlistOptions::addIosBackgroundModes (XmlElement& dict) const + { + StringArray iosBackgroundModes; + if (backgroundAudioEnabled) iosBackgroundModes.add ("audio"); + if (backgroundBleEnabled) iosBackgroundModes.add ("bluetooth-central"); + if (pushNotificationsEnabled) iosBackgroundModes.add ("remote-notification"); + + addArrayToPlist (dict, "UIBackgroundModes", iosBackgroundModes); + } + + Array<XmlElement> PlistOptions::createExtraAudioUnitTargetPlistOptions() const + { + XmlElement plistKey ("key"); + plistKey.addTextElement ("AudioComponents"); + + XmlElement plistEntry ("array"); + auto* dict = plistEntry.createNewChildElement ("dict"); + + auto truncatedCode = pluginManufacturerCode.substring (0, 4); + auto pluginSubType = pluginCode.substring (0, 4); + + if (truncatedCode.toLowerCase() == truncatedCode) + { + throw SaveError ("AudioUnit plugin code identifiers invalid!\n\n" + "You have used only lower case letters in your AU plugin manufacturer identifier. " + "You must have at least one uppercase letter in your AU plugin manufacturer " + "identifier code."); + } + + addPlistDictionaryKey (*dict, "name", pluginManufacturer + ": " + pluginName); + addPlistDictionaryKey (*dict, "description", pluginDescription); + addPlistDictionaryKey (*dict, "factoryFunction", pluginAUExportPrefix + "Factory"); + addPlistDictionaryKey (*dict, "manufacturer", truncatedCode); + addPlistDictionaryKey (*dict, "type", auMainType.removeCharacters ("'")); + addPlistDictionaryKey (*dict, "subtype", pluginSubType); + addPlistDictionaryKey (*dict, "version", versionAsHex); + + if (isAuSandboxSafe) + { + addPlistDictionaryKey (*dict, "sandboxSafe", true); + } + else if (! suppressResourceUsage) + { + dict->createNewChildElement ("key")->addTextElement ("resourceUsage"); + auto* resourceUsageDict = dict->createNewChildElement ("dict"); + + addPlistDictionaryKey (*resourceUsageDict, "network.client", true); + addPlistDictionaryKey (*resourceUsageDict, "temporary-exception.files.all.read-write", true); + } + + return { plistKey, plistEntry }; + } + + Array<XmlElement> PlistOptions::createExtraAudioUnitV3TargetPlistOptions() const + { + XmlElement plistKey ("key"); + plistKey.addTextElement ("NSExtension"); + + XmlElement plistEntry ("dict"); + + addPlistDictionaryKey (plistEntry, "NSExtensionPrincipalClass", pluginAUExportPrefix + "FactoryAUv3"); + addPlistDictionaryKey (plistEntry, "NSExtensionPointIdentifier", "com.apple.AudioUnit-UI"); + plistEntry.createNewChildElement ("key")->addTextElement ("NSExtensionAttributes"); + + auto* dict = plistEntry.createNewChildElement ("dict"); + dict->createNewChildElement ("key")->addTextElement ("AudioComponents"); + auto* componentArray = dict->createNewChildElement ("array"); + + auto* componentDict = componentArray->createNewChildElement ("dict"); + + addPlistDictionaryKey (*componentDict, "name", pluginManufacturer + ": " + pluginName); + addPlistDictionaryKey (*componentDict, "description", pluginDescription); + addPlistDictionaryKey (*componentDict, "factoryFunction", pluginAUExportPrefix + "FactoryAUv3"); + addPlistDictionaryKey (*componentDict, "manufacturer", pluginManufacturerCode.substring (0, 4)); + addPlistDictionaryKey (*componentDict, "type", auMainType.removeCharacters ("'")); + addPlistDictionaryKey (*componentDict, "subtype", pluginCode.substring (0, 4)); + addPlistDictionaryKey (*componentDict, "version", versionAsHex); + addPlistDictionaryKey (*componentDict, "sandboxSafe", true); + + componentDict->createNewChildElement ("key")->addTextElement ("tags"); + auto* tagsArray = componentDict->createNewChildElement ("array"); + + tagsArray->createNewChildElement ("string") + ->addTextElement (isPluginSynth ? "Synth" : "Effects"); + + return { plistKey, plistEntry }; + } +} +} diff --git a/extras/Build/juce_build_tools/utils/juce_PlistOptions.h b/extras/Build/juce_build_tools/utils/juce_PlistOptions.h new file mode 100644 index 00000000..780dbd9e --- /dev/null +++ b/extras/Build/juce_build_tools/utils/juce_PlistOptions.h @@ -0,0 +1,103 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace build_tools +{ + class PlistOptions final + { + public: + void write (const File& infoPlistFile) const; + + //============================================================================== + ProjectType::Target::Type type = ProjectType::Target::Type::GUIApp; + + String executableName; + String bundleIdentifier; + + String plistToMerge; + + bool iOS = false; + + bool microphonePermissionEnabled = false; + String microphonePermissionText; + + bool cameraPermissionEnabled = false; + String cameraPermissionText; + + bool bluetoothPermissionEnabled = false; + String bluetoothPermissionText; + + bool sendAppleEventsPermissionEnabled = false; + String sendAppleEventsPermissionText; + + bool shouldAddStoryboardToProject = false; + String storyboardName; + + File iconFile; + String projectName; + String version; + String companyCopyright; + + StringPairArray allPreprocessorDefs; + String documentExtensions; + + bool fileSharingEnabled = false; + bool documentBrowserEnabled = false; + bool statusBarHidden = false; + bool backgroundAudioEnabled = false; + bool backgroundBleEnabled = false; + bool pushNotificationsEnabled = false; + + bool enableIAA = false; + String IAAPluginName; + String pluginManufacturerCode; + String IAATypeCode; + String pluginCode; + int versionAsHex = 0; + + StringArray iPhoneScreenOrientations; + StringArray iPadScreenOrientations; + + String pluginName; + String pluginManufacturer; + String pluginDescription; + String pluginAUExportPrefix; + String auMainType; + bool isAuSandboxSafe = false; + bool isPluginSynth = false; + bool suppressResourceUsage = false; + + private: + void write (MemoryOutputStream&) const; + std::unique_ptr<XmlElement> createXML() const; + void addIosScreenOrientations (XmlElement&) const; + void addIosBackgroundModes (XmlElement&) const; + Array<XmlElement> createExtraAudioUnitTargetPlistOptions() const; + Array<XmlElement> createExtraAudioUnitV3TargetPlistOptions() const; + }; +} +} diff --git a/extras/Build/juce_build_tools/utils/juce_ProjectType.h b/extras/Build/juce_build_tools/utils/juce_ProjectType.h new file mode 100644 index 00000000..d4f1bfb5 --- /dev/null +++ b/extras/Build/juce_build_tools/utils/juce_ProjectType.h @@ -0,0 +1,275 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace build_tools +{ + //============================================================================== + class ProjectType + { + public: + //============================================================================== + virtual ~ProjectType() { getAllTypes().removeFirstMatchingValue (this); } + + const String& getType() const noexcept { return type; } + const String& getDescription() const noexcept { return desc; } + + //============================================================================== + static Array<ProjectType*> getAllTypes(); + static const ProjectType* findType (const String& typeCode) + { + const auto& types = getAllTypes(); + + for (auto i = types.size(); --i >= 0;) + if (types.getUnchecked(i)->getType() == typeCode) + return types.getUnchecked(i); + + jassertfalse; + return nullptr; + } + + //============================================================================== + virtual bool isStaticLibrary() const { return false; } + virtual bool isDynamicLibrary() const { return false; } + virtual bool isGUIApplication() const { return false; } + virtual bool isCommandLineApp() const { return false; } + virtual bool isAudioPlugin() const { return false; } + + //============================================================================== + struct Target + { + enum Type + { + GUIApp = 0, + ConsoleApp = 1, + StaticLibrary = 2, + DynamicLibrary = 3, + + VSTPlugIn = 10, + VST3PlugIn = 11, + AAXPlugIn = 12, + RTASPlugIn = 13, + AudioUnitPlugIn = 14, + AudioUnitv3PlugIn = 15, + StandalonePlugIn = 16, + UnityPlugIn = 17, + + SharedCodeTarget = 20, // internal + AggregateTarget = 21, + + unspecified = 30 + }; + + enum TargetFileType + { + executable = 0, + staticLibrary = 1, + sharedLibraryOrDLL = 2, + pluginBundle = 3, + macOSAppex = 4, + unknown = 5 + }; + + //============================================================================== + explicit Target (Type targetType) : type (targetType) {} + + const char* getName() const noexcept + { + switch (type) + { + case GUIApp: return "App"; + case ConsoleApp: return "ConsoleApp"; + case StaticLibrary: return "Static Library"; + case DynamicLibrary: return "Dynamic Library"; + case VSTPlugIn: return "VST"; + case VST3PlugIn: return "VST3"; + case AudioUnitPlugIn: return "AU"; + case StandalonePlugIn: return "Standalone Plugin"; + case AudioUnitv3PlugIn: return "AUv3 AppExtension"; + case AAXPlugIn: return "AAX"; + case RTASPlugIn: return "RTAS"; + case UnityPlugIn: return "Unity Plugin"; + case SharedCodeTarget: return "Shared Code"; + case AggregateTarget: return "All"; + case unspecified: + default: break; + } + + return "undefined"; + } + + static Type typeFromName (const juce::String& name) + { + if (name == "App") return Type::GUIApp; + if (name == "ConsoleApp") return Type::ConsoleApp; + if (name == "Static Library") return Type::StaticLibrary; + if (name == "Dynamic Library") return Type::DynamicLibrary; + if (name == "VST") return Type::VSTPlugIn; + if (name == "VST3") return Type::VST3PlugIn; + if (name == "AU") return Type::AudioUnitPlugIn; + if (name == "Standalone Plugin") return Type::StandalonePlugIn; + if (name == "AUv3 AppExtension") return Type::AudioUnitv3PlugIn; + if (name == "AAX") return Type::AAXPlugIn; + if (name == "RTAS") return Type::RTASPlugIn; + if (name == "Unity Plugin") return Type::UnityPlugIn; + if (name == "Shared Code") return Type::SharedCodeTarget; + if (name == "All") return Type::AggregateTarget; + + jassertfalse; + return Type::ConsoleApp; + } + + TargetFileType getTargetFileType() const noexcept + { + switch (type) + { + case GUIApp: return executable; + case ConsoleApp: return executable; + case StaticLibrary: return staticLibrary; + case DynamicLibrary: return sharedLibraryOrDLL; + case VSTPlugIn: return pluginBundle; + case VST3PlugIn: return pluginBundle; + case AudioUnitPlugIn: return pluginBundle; + case StandalonePlugIn: return executable; + case AudioUnitv3PlugIn: return macOSAppex; + case AAXPlugIn: return pluginBundle; + case RTASPlugIn: return pluginBundle; + case UnityPlugIn: return pluginBundle; + case SharedCodeTarget: return staticLibrary; + case AggregateTarget: + case unspecified: + default: break; + } + + return unknown; + } + + const Type type; + + private: + //============================================================================== + Target& operator= (const Target&) = delete; + }; + + virtual bool supportsTargetType (Target::Type /*targetType*/) const { return false; } + + protected: + ProjectType (const String& t, const String& d) + : type (t), desc (d) + {} + + private: + const String type, desc; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProjectType) + }; + + //============================================================================== + struct ProjectType_GUIApp : public ProjectType + { + ProjectType_GUIApp() : ProjectType (getTypeName(), "GUI Application") {} + + static const char* getTypeName() noexcept { return "guiapp"; } + bool isGUIApplication() const override { return true; } + bool supportsTargetType (Target::Type targetType) const override { return (targetType == Target::GUIApp); } + }; + + struct ProjectType_ConsoleApp : public ProjectType + { + ProjectType_ConsoleApp() : ProjectType (getTypeName(), "Console Application") {} + + static const char* getTypeName() noexcept { return "consoleapp"; } + bool isCommandLineApp() const override { return true; } + bool supportsTargetType (Target::Type targetType) const override { return (targetType == Target::ConsoleApp); } + }; + + struct ProjectType_StaticLibrary : public ProjectType + { + ProjectType_StaticLibrary() : ProjectType (getTypeName(), "Static Library") {} + + static const char* getTypeName() noexcept { return "library"; } + bool isStaticLibrary() const override { return true; } + bool supportsTargetType (Target::Type targetType) const override { return (targetType == Target::StaticLibrary); } + }; + + struct ProjectType_DLL : public ProjectType + { + ProjectType_DLL() : ProjectType (getTypeName(), "Dynamic Library") {} + + static const char* getTypeName() noexcept { return "dll"; } + bool isDynamicLibrary() const override { return true; } + bool supportsTargetType (Target::Type targetType) const override { return (targetType == Target::DynamicLibrary); } + }; + + struct ProjectType_AudioPlugin : public ProjectType + { + ProjectType_AudioPlugin() : ProjectType (getTypeName(), "Audio Plug-in") {} + + static const char* getTypeName() noexcept { return "audioplug"; } + bool isAudioPlugin() const override { return true; } + + bool supportsTargetType (Target::Type targetType) const override + { + switch (targetType) + { + case Target::VSTPlugIn: + case Target::VST3PlugIn: + case Target::AAXPlugIn: + case Target::RTASPlugIn: + case Target::AudioUnitPlugIn: + case Target::AudioUnitv3PlugIn: + case Target::StandalonePlugIn: + case Target::UnityPlugIn: + case Target::SharedCodeTarget: + case Target::AggregateTarget: + return true; + + case Target::GUIApp: + case Target::ConsoleApp: + case Target::StaticLibrary: + case Target::DynamicLibrary: + case Target::unspecified: + default: + break; + } + + return false; + } + }; + + //============================================================================== + inline Array<ProjectType*> ProjectType::getAllTypes() + { + static ProjectType_GUIApp guiApp; + static ProjectType_ConsoleApp consoleApp; + static ProjectType_StaticLibrary staticLib; + static ProjectType_DLL dll; + static ProjectType_AudioPlugin plugin; + + return Array<ProjectType*>(&guiApp, &consoleApp, &staticLib, &dll, &plugin); + } +} +} diff --git a/extras/Build/juce_build_tools/utils/juce_RelativePath.h b/extras/Build/juce_build_tools/utils/juce_RelativePath.h new file mode 100644 index 00000000..79409025 --- /dev/null +++ b/extras/Build/juce_build_tools/utils/juce_RelativePath.h @@ -0,0 +1,129 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace build_tools +{ + //============================================================================== + /** Manipulates a cross-platform partial file path. (Needed because File is designed + for absolute paths on the active OS) + */ + class RelativePath + { + public: + //============================================================================== + enum RootFolder + { + unknown, + projectFolder, + buildTargetFolder + }; + + //============================================================================== + RelativePath() + : root (unknown) + {} + + RelativePath (const String& relPath, const RootFolder rootType) + : path (unixStylePath (relPath)), root (rootType) + {} + + RelativePath (const File& file, const File& rootFolder, const RootFolder rootType) + : path (unixStylePath (getRelativePathFrom (file, rootFolder))), root (rootType) + {} + + RootFolder getRoot() const { return root; } + + String toUnixStyle() const { return unixStylePath (path); } + String toWindowsStyle() const { return windowsStylePath (path); } + + String getFileName() const { return getFakeFile().getFileName(); } + String getFileNameWithoutExtension() const { return getFakeFile().getFileNameWithoutExtension(); } + + String getFileExtension() const { return getFakeFile().getFileExtension(); } + bool hasFileExtension (juce::StringRef extension) const { return getFakeFile().hasFileExtension (extension); } + bool isAbsolute() const { return isAbsolutePath (path); } + + RelativePath withFileExtension (const String& extension) const + { + return RelativePath (path.upToLastOccurrenceOf (".", ! extension.startsWithChar ('.'), false) + extension, root); + } + + RelativePath getParentDirectory() const + { + String p (path); + if (path.endsWithChar ('/')) + p = p.dropLastCharacters (1); + + return RelativePath (p.upToLastOccurrenceOf ("/", false, false), root); + } + + RelativePath getChildFile (const String& subpath) const + { + if (isAbsolutePath (subpath)) + return RelativePath (subpath, root); + + String p (toUnixStyle()); + if (! p.endsWithChar ('/')) + p << '/'; + + return RelativePath (p + subpath, root); + } + + RelativePath rebased (const File& originalRoot, const File& newRoot, const RootFolder newRootType) const + { + if (isAbsolute()) + return RelativePath (path, newRootType); + + return RelativePath (getRelativePathFrom (originalRoot.getChildFile (toUnixStyle()), newRoot), newRootType); + } + + private: + //============================================================================== + String path; + RootFolder root; + + File getFakeFile() const + { + #if JUCE_WINDOWS + if (isAbsolutePath (path)) + { + // This is a hack to convert unix-style absolute paths into valid absolute Windows paths to avoid hitting + // an assertion in File::parseAbsolutePath(). + if (path.startsWithChar (L'/') || path.startsWithChar (L'$') || path.startsWithChar (L'~')) + return File (String ("C:\\") + windowsStylePath (path.substring (1))); + + return File (path); + } + #endif + + // This method gets called very often, so we'll cache this directory. + static const File currentWorkingDirectory (File::getCurrentWorkingDirectory()); + return currentWorkingDirectory.getChildFile (path); + } + }; +} +} diff --git a/extras/Build/juce_build_tools/utils/juce_ResourceFileHelpers.cpp b/extras/Build/juce_build_tools/utils/juce_ResourceFileHelpers.cpp new file mode 100644 index 00000000..85ea18ea --- /dev/null +++ b/extras/Build/juce_build_tools/utils/juce_ResourceFileHelpers.cpp @@ -0,0 +1,91 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace build_tools +{ + uint64 calculateStreamHashCode (InputStream& in) + { + uint64 t = 0; + + const int bufferSize = 4096; + HeapBlock<uint8> buffer; + buffer.malloc (bufferSize); + + for (;;) + { + auto num = in.read (buffer, bufferSize); + + if (num <= 0) + break; + + for (int i = 0; i < num; ++i) + t = t * 65599 + buffer[i]; + } + + return t; + } + + uint64 calculateFileHashCode (const File& file) + { + std::unique_ptr<FileInputStream> stream (file.createInputStream()); + return stream != nullptr ? calculateStreamHashCode (*stream) : 0; + } + + uint64 calculateMemoryHashCode (const void* data, size_t numBytes) + { + uint64 t = 0; + + for (size_t i = 0; i < numBytes; ++i) + t = t * 65599 + static_cast<const uint8*> (data)[i]; + + return t; + } + + bool overwriteFileWithNewDataIfDifferent (const File& file, const void* data, size_t numBytes) + { + if (file.getSize() == (int64) numBytes + && calculateMemoryHashCode (data, numBytes) == calculateFileHashCode (file)) + return true; + + if (file.exists()) + return file.replaceWithData (data, numBytes); + + return file.getParentDirectory().createDirectory() && file.appendData (data, numBytes); + } + + bool overwriteFileWithNewDataIfDifferent (const File& file, const MemoryOutputStream& newData) + { + return overwriteFileWithNewDataIfDifferent (file, newData.getData(), newData.getDataSize()); + } + + bool overwriteFileWithNewDataIfDifferent (const File& file, const String& newData) + { + const char* const utf8 = newData.toUTF8(); + return overwriteFileWithNewDataIfDifferent (file, utf8, strlen (utf8)); + } +} +} diff --git a/extras/Build/juce_build_tools/utils/juce_ResourceFileHelpers.h b/extras/Build/juce_build_tools/utils/juce_ResourceFileHelpers.h new file mode 100644 index 00000000..91ba8194 --- /dev/null +++ b/extras/Build/juce_build_tools/utils/juce_ResourceFileHelpers.h @@ -0,0 +1,38 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace build_tools +{ + uint64 calculateStreamHashCode (InputStream& in); + uint64 calculateFileHashCode (const File& file); + uint64 calculateMemoryHashCode (const void* data, size_t numBytes); + + bool overwriteFileWithNewDataIfDifferent (const File& file, const void* data, size_t numBytes); + bool overwriteFileWithNewDataIfDifferent (const File& file, const MemoryOutputStream& newData); + bool overwriteFileWithNewDataIfDifferent (const File& file, const String& newData); +} +} diff --git a/extras/Build/juce_build_tools/utils/juce_ResourceRc.cpp b/extras/Build/juce_build_tools/utils/juce_ResourceRc.cpp new file mode 100644 index 00000000..4e1572a8 --- /dev/null +++ b/extras/Build/juce_build_tools/utils/juce_ResourceRc.cpp @@ -0,0 +1,97 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace build_tools +{ + static String getCommaSeparatedVersionNumber (const String& version) + { + auto versionParts = StringArray::fromTokens (version, ",.", ""); + versionParts.trim(); + versionParts.removeEmptyStrings(); + while (versionParts.size() < 4) + versionParts.add ("0"); + + return versionParts.joinIntoString (","); + } + + void ResourceRcOptions::write (const File& resourceRcFile) const + { + MemoryOutputStream mo; + + mo << "#pragma code_page(65001)" << newLine + << newLine + << "#ifdef JUCE_USER_DEFINED_RC_FILE" << newLine + << " #include JUCE_USER_DEFINED_RC_FILE" << newLine + << "#else" << newLine + << newLine + << "#undef WIN32_LEAN_AND_MEAN" << newLine + << "#define WIN32_LEAN_AND_MEAN" << newLine + << "#include <windows.h>" << newLine + << newLine + << "VS_VERSION_INFO VERSIONINFO" << newLine + << "FILEVERSION " << getCommaSeparatedVersionNumber (version) << newLine + << "BEGIN" << newLine + << " BLOCK \"StringFileInfo\"" << newLine + << " BEGIN" << newLine + << " BLOCK \"040904E4\"" << newLine + << " BEGIN" << newLine; + + const auto writeRCValue = [&] (const String& n, const String& value) + { + if (value.isNotEmpty()) + mo << " VALUE \"" << n << "\", \"" + << value.replace ("\"", "\"\"") << "\\0\"" << newLine; + }; + + writeRCValue ("CompanyName", companyName); + writeRCValue ("LegalCopyright", companyCopyright); + writeRCValue ("FileDescription", projectName); + writeRCValue ("FileVersion", version); + writeRCValue ("ProductName", projectName); + writeRCValue ("ProductVersion", version); + + mo << " END" << newLine + << " END" << newLine + << newLine + << " BLOCK \"VarFileInfo\"" << newLine + << " BEGIN" << newLine + << " VALUE \"Translation\", 0x409, 1252" << newLine + << " END" << newLine + << "END" << newLine + << newLine + << "#endif" << newLine; + + if (icon.existsAsFile()) + mo << newLine + << "IDI_ICON1 ICON DISCARDABLE " << icon.getFileName().quoted() + << newLine + << "IDI_ICON2 ICON DISCARDABLE " << icon.getFileName().quoted(); + + overwriteFileIfDifferentOrThrow (resourceRcFile, mo); + } +} +} diff --git a/extras/Build/juce_build_tools/utils/juce_ResourceRc.h b/extras/Build/juce_build_tools/utils/juce_ResourceRc.h new file mode 100644 index 00000000..1dfc381e --- /dev/null +++ b/extras/Build/juce_build_tools/utils/juce_ResourceRc.h @@ -0,0 +1,43 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace build_tools +{ + class ResourceRcOptions final + { + public: + void write (const File& resourceRcFile) const; + + //============================================================================== + String version; + String companyName; + String companyCopyright; + String projectName; + File icon; + }; +} +} diff --git a/extras/Build/juce_build_tools/utils/juce_VersionNumbers.cpp b/extras/Build/juce_build_tools/utils/juce_VersionNumbers.cpp new file mode 100644 index 00000000..29f351d9 --- /dev/null +++ b/extras/Build/juce_build_tools/utils/juce_VersionNumbers.cpp @@ -0,0 +1,57 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace build_tools +{ + StringArray getVersionSegments (juce::StringRef p) + { + auto segments = StringArray::fromTokens (p, ",.", ""); + segments.trim(); + segments.removeEmptyStrings(); + return segments; + } + + int getVersionAsHexInteger (juce::StringRef versionString) + { + auto segments = getVersionSegments (versionString); + + auto value = (segments[0].getIntValue() << 16) + + (segments[1].getIntValue() << 8) + + segments[2].getIntValue(); + + if (segments.size() > 3) + value = (value << 8) + segments[3].getIntValue(); + + return value; + } + + String getVersionAsHex (juce::StringRef versionString) + { + return "0x" + String::toHexString (getVersionAsHexInteger (versionString)); + } +} +} diff --git a/extras/Projucer/Source/Wizards/jucer_NewProjectWizardClasses.h b/extras/Build/juce_build_tools/utils/juce_VersionNumbers.h similarity index 50% rename from extras/Projucer/Source/Wizards/jucer_NewProjectWizardClasses.h rename to extras/Build/juce_build_tools/utils/juce_VersionNumbers.h index 26633b02..a8d81bec 100644 --- a/extras/Projucer/Source/Wizards/jucer_NewProjectWizardClasses.h +++ b/extras/Build/juce_build_tools/utils/juce_VersionNumbers.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -24,7 +23,14 @@ ============================================================================== */ -#pragma once +namespace juce +{ +namespace build_tools +{ + StringArray getVersionSegments (juce::StringRef p); + int getVersionAsHexInteger (juce::StringRef versionString); -Component* createNewProjectWizardComponent(); + String getVersionAsHex (juce::StringRef versionString); +} +} diff --git a/extras/Build/juceaide/CMakeLists.txt b/extras/Build/juceaide/CMakeLists.txt new file mode 100644 index 00000000..6f5c6401 --- /dev/null +++ b/extras/Build/juceaide/CMakeLists.txt @@ -0,0 +1,107 @@ +# ============================================================================== +# +# This file is part of the JUCE library. +# Copyright (c) 2020 - Raw Material Software Limited +# +# JUCE is an open source library subject to commercial or open-source +# licensing. +# +# By using JUCE, you agree to the terms of both the JUCE 6 End-User License +# Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). +# +# End User License Agreement: www.juce.com/juce-6-licence +# Privacy Policy: www.juce.com/juce-privacy-policy +# +# Or: You may also use this code under the terms of the GPL v3 (see +# www.gnu.org/licenses). +# +# JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER +# EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE +# DISCLAIMED. +# +# ============================================================================== + +# The juceaide program generates intermediate build files including BinaryData sources, icons, and +# plists. To ensure that we always build it for the host system, and not for, say, a device or +# simulator if we're targeting iOS or Android, we reinvoke cmake here and build juceaide during the +# configuration stage of the outer project. + +if(JUCE_BUILD_HELPER_TOOLS) + # Build the tool for the current system + juce_add_console_app(juceaide) + + target_sources(juceaide PRIVATE Main.cpp) + + target_compile_definitions(juceaide PRIVATE + JUCE_DISABLE_JUCE_VERSION_PRINTING=1 + JUCE_USE_CURL=0) + + target_link_libraries(juceaide PRIVATE + juce::juce_build_tools + juce::juce_recommended_config_flags + juce::juce_recommended_lto_flags + juce::juce_recommended_warning_flags) + + export(TARGETS juceaide + NAMESPACE juce_tools:: + FILE "${JUCE_BINARY_DIR}/JUCEToolsExport.cmake") +else() + # If we're building using the NDK, the gradle wrapper will try to inject its own compiler using + # environment variables, which is unfortunate because we really don't want to cross-compile + # juceaide. If you really want to set the compilers for juceaide, pass the appropriate + # CMAKE_<lang>_COMPILER flags when configuring CMake. + unset(ENV{ASM}) + unset(ENV{CC}) + unset(ENV{CXX}) + + message(STATUS "Configuring juceaide") + + # Looks like we're boostrapping, reinvoke CMake + execute_process(COMMAND "${CMAKE_COMMAND}" + "." + "-B${JUCE_BINARY_DIR}/tools" + "-G${CMAKE_GENERATOR}" + "-DCMAKE_BUILD_TYPE=Debug" + "-DJUCE_BUILD_HELPER_TOOLS=ON" + "-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}" + WORKING_DIRECTORY "${JUCE_SOURCE_DIR}" + OUTPUT_VARIABLE command_output + ERROR_VARIABLE command_output + RESULT_VARIABLE result_variable) + + if(result_variable) + message(FATAL_ERROR "Failed to configure juceaide\n${command_output}") + endif() + + message(STATUS "Building juceaide") + + execute_process(COMMAND "${CMAKE_COMMAND}" + --build "${JUCE_BINARY_DIR}/tools" + --config Debug + OUTPUT_VARIABLE command_output + ERROR_VARIABLE command_output + RESULT_VARIABLE result_variable) + + if(result_variable) + message(FATAL_ERROR "Failed to build juceaide\n${command_output}") + endif() + + message(STATUS "Exporting juceaide") + + # This will be generated by the recursive invocation of CMake (above) + include("${JUCE_BINARY_DIR}/tools/JUCEToolsExport.cmake") + + add_executable(juceaide IMPORTED GLOBAL) + get_target_property(imported_location juce_tools::juceaide IMPORTED_LOCATION_DEBUG) + set_target_properties(juceaide PROPERTIES IMPORTED_LOCATION "${imported_location}") + + add_executable(juce::juceaide ALIAS juceaide) + + set(JUCE_TOOL_INSTALL_DIR "bin/JUCE-${JUCE_VERSION}" CACHE STRING + "The location, relative to the install prefix, where juceaide will be installed") + + install(PROGRAMS "${imported_location}" DESTINATION "${JUCE_TOOL_INSTALL_DIR}") + + get_filename_component(binary_name "${imported_location}" NAME) + set(JUCE_JUCEAIDE_NAME "${binary_name}" CACHE INTERNAL "The name of the juceaide program") +endif() diff --git a/extras/Build/juceaide/Main.cpp b/extras/Build/juceaide/Main.cpp new file mode 100644 index 00000000..b5d51448 --- /dev/null +++ b/extras/Build/juceaide/Main.cpp @@ -0,0 +1,512 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +#include <juce_build_tools/juce_build_tools.h> + +#include <fstream> +#include <unordered_map> + +namespace +{ + +constexpr auto headerTemplate = R"(/* + IMPORTANT! This file is auto-generated. + If you alter its contents, your changes may be overwritten! + + This is the header file that your files should include in order to get all the + JUCE library headers. You should avoid including the JUCE headers directly in + your own source files, because that wouldn't pick up the correct configuration + options for your app. + +*/ + +#pragma once + +${JUCE_INCLUDES} + +#if JUCE_TARGET_HAS_BINARY_DATA + #include "BinaryData.h" +#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. + using namespace juce; +#endif + +#if ! JUCE_DONT_DECLARE_PROJECTINFO +namespace ProjectInfo +{ + const char* const projectName = "${JUCE_EXECUTABLE_NAME}"; + const char* const companyName = "${JUCE_COMPANY_NAME}"; + const char* const versionString = "${JUCE_PROJECT_VERSION}"; + const int versionNumber = ${JUCE_PROJECT_VERSION_HEX}; +} +#endif +)"; + +int writeBinaryData (juce::ArgumentList&& args) +{ + args.checkMinNumArguments (3); + const auto namespaceName = args.arguments.removeAndReturn (0); + const auto headerName = args.arguments.removeAndReturn (0); + const auto outFolder = args.arguments.removeAndReturn (0).resolveAsExistingFolder(); + + juce::build_tools::ResourceFile resourceFile; + + resourceFile.setClassName (namespaceName.text); + const auto lineEndings = args.removeOptionIfFound ("--windows") ? "\r\n" : "\n"; + + for (const auto& arg : args.arguments) + resourceFile.addFile (arg.resolveAsExistingFile()); + + const auto result = resourceFile.write (0, + lineEndings, + outFolder.getChildFile (headerName.text), + [&outFolder] (int index) + { + return outFolder.getChildFile ("./BinaryData" + juce::String { index + 1 } + ".cpp"); + }); + + if (result.result.failed()) + juce::ConsoleApplication::fail (result.result.getErrorMessage(), 1); + + return 0; +} + +struct IconParseResults final +{ + juce::build_tools::Icons icons; + juce::File output; +}; + +IconParseResults parseIconArguments (juce::ArgumentList&& args) +{ + args.checkMinNumArguments (2); + const auto output = args.arguments.removeAndReturn (0); + + const auto popDrawable = [&args]() -> std::unique_ptr<juce::Drawable> + { + if (args.size() == 0) + return {}; + + const auto firstArgText = args.arguments.removeAndReturn (0).text; + return juce::Drawable::createFromImageFile (firstArgText); + }; + + auto smallIcon = popDrawable(); + auto bigIcon = popDrawable(); + + return { { std::move (smallIcon), std::move (bigIcon) }, output.text }; +} + +int writeMacIcon (juce::ArgumentList&& argumentList) +{ + const auto parsed = parseIconArguments (std::move (argumentList)); + juce::build_tools::writeMacIcon (parsed.icons, parsed.output); + return 0; +} + +int writeiOSAssets (juce::ArgumentList&& argumentList) +{ + const auto parsed = parseIconArguments (std::move (argumentList)); + juce::build_tools::createXcassetsFolderFromIcons (parsed.icons, + parsed.output.getParentDirectory(), + parsed.output.getFileName()); + return 0; +} + +int writeWinIcon (juce::ArgumentList&& argumentList) +{ + const auto parsed = parseIconArguments (std::move (argumentList)); + juce::build_tools::writeWinIcon (parsed.icons, parsed.output); + return 0; +} + +std::unordered_map<juce::String, juce::String> parseProjectData (const juce::File& file) +{ + constexpr auto recordSeparator = "\x1e"; + const auto contents = file.loadFileAsString(); + const auto lines = juce::StringArray::fromTokens (contents, recordSeparator, {}); + + std::unordered_map<juce::String, juce::String> result; + + constexpr auto unitSeparator = "\x1f"; + + for (const auto& line : lines) + { + if (line.isEmpty()) + continue; + + result.emplace (line.upToFirstOccurrenceOf (unitSeparator, false, false), + line.fromFirstOccurrenceOf (unitSeparator, false, false)); + } + + return result; +} + +juce::String getStringValue (const std::unordered_map<juce::String, juce::String>& dict, + juce::StringRef key) +{ + const auto it = dict.find (key); + return it != dict.cend() ? it->second : juce::String{}; +} + +bool getBoolValue (const std::unordered_map<juce::String, juce::String>& dict, juce::StringRef key) +{ + const auto str = getStringValue (dict, key); + return str.equalsIgnoreCase ("yes") + || str.equalsIgnoreCase ("true") + || str.equalsIgnoreCase ("1") + || str.equalsIgnoreCase ("on"); +} + +struct UpdateField final +{ + const std::unordered_map<juce::String, juce::String>& dict; + + void operator() (juce::StringRef key, juce::String& value) const + { + value = getStringValue (dict, key); + } + + void operator() (juce::StringRef key, juce::File& value) const + { + value = getStringValue (dict, key); + } + + void operator() (juce::StringRef key, bool& value) const + { + value = getBoolValue (dict, key); + } + + void operator() (juce::StringRef key, juce::StringArray& value) const + { + value = juce::StringArray::fromTokens (getStringValue (dict, key), ";", {}); + } +}; + +void setIfEmpty (juce::String& field, juce::StringRef fallback) +{ + if (field.isEmpty()) + field = fallback; +} + +juce::build_tools::PlistOptions parsePlistOptions (const juce::File& file, + juce::build_tools::ProjectType::Target::Type type) +{ + if (type == juce::build_tools::ProjectType::Target::ConsoleApp) + juce::ConsoleApplication::fail ("Deduced project type does not require a plist", 1); + + const auto dict = parseProjectData (file); + + UpdateField updateField { dict }; + + juce::build_tools::PlistOptions result; + + updateField ("EXECUTABLE_NAME", result.executableName); + updateField ("PLIST_TO_MERGE", result.plistToMerge); + updateField ("IS_IOS", result.iOS); + updateField ("MICROPHONE_PERMISSION_ENABLED", result.microphonePermissionEnabled); + updateField ("MICROPHONE_PERMISSION_TEXT", result.microphonePermissionText); + updateField ("CAMERA_PERMISSION_ENABLED", result.cameraPermissionEnabled); + updateField ("CAMERA_PERMISSION_TEXT", result.cameraPermissionText); + updateField ("BLUETOOTH_PERMISSION_ENABLED", result.bluetoothPermissionEnabled); + updateField ("BLUETOOTH_PERMISSION_TEXT", result.bluetoothPermissionText); + updateField ("SEND_APPLE_EVENTS_PERMISSION_ENABLED", result.sendAppleEventsPermissionEnabled); + updateField ("SEND_APPLE_EVENTS_PERMISSION_TEXT", result.sendAppleEventsPermissionText); + updateField ("SHOULD_ADD_STORYBOARD", result.shouldAddStoryboardToProject); + updateField ("LAUNCH_STORYBOARD_FILE", result.storyboardName); + updateField ("PROJECT_NAME", result.projectName); + updateField ("VERSION", result.version); + updateField ("COMPANY_COPYRIGHT", result.companyCopyright); + updateField ("DOCUMENT_EXTENSIONS", result.documentExtensions); + updateField ("FILE_SHARING_ENABLED", result.fileSharingEnabled); + updateField ("DOCUMENT_BROWSER_ENABLED", result.documentBrowserEnabled); + updateField ("STATUS_BAR_HIDDEN", result.statusBarHidden); + updateField ("BACKGROUND_AUDIO_ENABLED", result.backgroundAudioEnabled); + updateField ("BACKGROUND_BLE_ENABLED", result.backgroundBleEnabled); + updateField ("PUSH_NOTIFICATIONS_ENABLED", result.pushNotificationsEnabled); + updateField ("PLUGIN_MANUFACTURER_CODE", result.pluginManufacturerCode); + updateField ("PLUGIN_CODE", result.pluginCode); + updateField ("IPHONE_SCREEN_ORIENTATIONS", result.iPhoneScreenOrientations); + updateField ("IPAD_SCREEN_ORIENTATIONS", result.iPadScreenOrientations); + updateField ("PLUGIN_NAME", result.pluginName); + updateField ("PLUGIN_MANUFACTURER", result.pluginManufacturer); + updateField ("PLUGIN_DESCRIPTION", result.pluginDescription); + updateField ("PLUGIN_AU_EXPORT_PREFIX", result.pluginAUExportPrefix); + updateField ("PLUGIN_AU_MAIN_TYPE", result.auMainType); + updateField ("IS_AU_SANDBOX_SAFE", result.isAuSandboxSafe); + updateField ("IS_PLUGIN_SYNTH", result.isPluginSynth); + updateField ("SUPPRESS_AU_PLIST_RESOURCE_USAGE", result.suppressResourceUsage); + updateField ("BUNDLE_ID", result.bundleIdentifier); + updateField ("ICON_FILE", result.iconFile); + + result.type = type; + result.versionAsHex = juce::build_tools::getVersionAsHexInteger (result.version); + + if (result.storyboardName.isNotEmpty()) + result.storyboardName = result.storyboardName.fromLastOccurrenceOf ("/", false, false) + .upToLastOccurrenceOf (".storyboard", false, false); + + setIfEmpty (result.microphonePermissionText, + "This app requires audio input. If you do not have an audio interface connected it will use the built-in microphone."); + setIfEmpty (result.cameraPermissionText, + "This app requires access to the camera to function correctly."); + setIfEmpty (result.bluetoothPermissionText, + "This app requires access to Bluetooth to function correctly."); + setIfEmpty (result.sendAppleEventsPermissionText, + "This app requires the ability to send Apple events to function correctly."); + + result.documentExtensions = result.documentExtensions.replace (";", ","); + + // AUv3 needs a slightly different bundle ID + if (type == juce::build_tools::ProjectType::Target::Type::AudioUnitv3PlugIn) + { + const auto bundleIdSegments = juce::StringArray::fromTokens (result.bundleIdentifier, ".", {}); + jassert (! bundleIdSegments.isEmpty()); + + const auto last = bundleIdSegments.isEmpty() ? "" + : bundleIdSegments[bundleIdSegments.size() - 1]; + + result.bundleIdentifier += "." + last + "AUv3"; + } + + return result; +} + +int writePlist (juce::ArgumentList&& args) +{ + args.checkMinNumArguments (3); + const auto kind = args.arguments.removeAndReturn (0); + const auto input = args.arguments.removeAndReturn (0); + const auto output = args.arguments.removeAndReturn (0); + parsePlistOptions (input.resolveAsExistingFile(), + juce::build_tools::ProjectType::Target::typeFromName (kind.text)) + .write (output.resolveAsFile()); + return 0; +} + +juce::build_tools::EntitlementOptions parseEntitlementsOptions (const juce::File& file, + juce::build_tools::ProjectType::Target::Type type) +{ + if (type == juce::build_tools::ProjectType::Target::ConsoleApp) + juce::ConsoleApplication::fail ("Deduced project type does not require entitlements", 1); + + const auto dict = parseProjectData (file); + + UpdateField updateField { dict }; + + juce::build_tools::EntitlementOptions result; + + updateField ("IS_IOS", result.isiOS); + updateField ("IS_PLUGIN", result.isAudioPluginProject); + updateField ("ICLOUD_PERMISSIONS_ENABLED", result.isiCloudPermissionsEnabled); + updateField ("PUSH_NOTIFICATIONS_ENABLED", result.isPushNotificationsEnabled); + updateField ("APP_GROUPS_ENABLED", result.isAppGroupsEnabled); + updateField ("APP_GROUP_IDS", result.appGroupIdString); + updateField ("HARDENED_RUNTIME_ENABLED", result.isHardenedRuntimeEnabled); + updateField ("HARDENED_RUNTIME_OPTIONS", result.hardenedRuntimeOptions); + updateField ("APP_SANDBOX_ENABLED", result.isAppSandboxEnabled); + updateField ("APP_SANDBOX_INHERIT", result.isAppSandboxInhertianceEnabled); + updateField ("APP_SANDBOX_OPTIONS", result.appSandboxOptions); + + result.type = type; + + return result; +} + +int writeEntitlements (juce::ArgumentList&& args) +{ + args.checkMinNumArguments (3); + const auto kind = args.arguments.removeAndReturn (0); + const auto input = args.arguments.removeAndReturn (0); + const auto output = args.arguments.removeAndReturn (0); + + const auto options = parseEntitlementsOptions (input.resolveAsExistingFile(), + juce::build_tools::ProjectType::Target::typeFromName (kind.text)); + juce::build_tools::overwriteFileIfDifferentOrThrow (output.resolveAsFile(), options.getEntitlementsFileContent()); + return 0; +} + +int createAndWrite (const juce::File& file, juce::StringRef text) +{ + if (file.create()) + return file.replaceWithText (text) ? 0 : 1; + + return 1; +} + +int writePkgInfo (juce::ArgumentList&& args) +{ + args.checkMinNumArguments (2); + const auto kind = args.arguments.removeAndReturn (0); + const auto output = args.arguments.removeAndReturn (0); + + const auto projectType = juce::build_tools::ProjectType::Target::typeFromName (kind.text); + return createAndWrite (output.resolveAsFile(), + juce::build_tools::getXcodePackageType (projectType) + + juce::build_tools::getXcodeBundleSignature (projectType)); +} + +juce::build_tools::ResourceRcOptions parseRcFileOptions (const juce::File& file) +{ + const auto dict = parseProjectData (file); + UpdateField updateField { dict }; + + juce::build_tools::ResourceRcOptions result; + + updateField ("VERSION", result.version); + updateField ("COMPANY_NAME", result.companyName); + updateField ("COMPANY_COPYRIGHT", result.companyCopyright); + updateField ("PROJECT_NAME", result.projectName); + updateField ("ICON_FILE", result.icon); + + return result; +} + +int writeRcFile (juce::ArgumentList&& args) +{ + args.checkMinNumArguments (2); + const auto input = args.arguments.removeAndReturn (0); + const auto output = args.arguments.removeAndReturn (0); + parseRcFileOptions (input.resolveAsExistingFile()).write (output.resolveAsFile()); + return 0; +} + +juce::String createDefineStatements (juce::StringRef definitions) +{ + const auto split = juce::StringArray::fromTokens (definitions, ";", "\""); + + juce::String defineStatements; + + for (const auto& def : split) + { + if (! def.startsWith ("JucePlugin_")) + continue; + + const auto defineName = def.upToFirstOccurrenceOf ("=", false, false); + const auto defineValue = def.fromFirstOccurrenceOf ("=", false, false); + defineStatements += "#define " + defineName + " " + defineValue + '\n'; + } + + return defineStatements; +} + +int writeAuPluginDefines (juce::ArgumentList&& args) +{ + args.checkMinNumArguments (2); + const auto input = args.arguments.removeAndReturn (0); + const auto output = args.arguments.removeAndReturn (0); + + const auto dict = parseProjectData (input.resolveAsExistingFile()); + const auto getString = [&] (juce::StringRef key) { return getStringValue (dict, key); }; + + const auto defines = "#pragma once\n" + createDefineStatements (getString ("MODULE_DEFINITIONS")); + return createAndWrite (output.resolveAsFile(), defines); +} + +juce::String createIncludeStatements (juce::StringRef definitions) +{ + const auto split = juce::StringArray::fromTokens (definitions, ";", "\""); + + juce::String includeStatements; + + for (const auto& def : split) + { + constexpr auto moduleToken = "JUCE_MODULE_AVAILABLE_"; + + if (def.startsWith (moduleToken)) + { + const auto moduleName = def.fromFirstOccurrenceOf (moduleToken, false, false) + .upToFirstOccurrenceOf ("=", false, false); + includeStatements += "#include <" + moduleName + "/" + moduleName + ".h>\n"; + } + } + + return includeStatements; +} + +int writeHeader (juce::ArgumentList&& args) +{ + args.checkMinNumArguments (2); + const auto input = args.arguments.removeAndReturn (0); + const auto output = args.arguments.removeAndReturn (0); + + const auto dict = parseProjectData (input.resolveAsExistingFile()); + + const auto getString = [&] (juce::StringRef key) { return getStringValue (dict, key); }; + + const auto includes = createIncludeStatements (getString ("MODULE_DEFINITIONS")); + const auto projectName = getString ("PROJECT_NAME"); + const auto name = projectName.isEmpty() ? getString ("EXECUTABLE_NAME") : projectName; + const auto versionString = getString ("VERSION"); + + const auto headerText = juce::String (headerTemplate) + .replace ("${JUCE_INCLUDES}", includes) + .replace ("${JUCE_EXECUTABLE_NAME}", name) + .replace ("${JUCE_COMPANY_NAME}", getString ("COMPANY_NAME")) + .replace ("${JUCE_PROJECT_VERSION}", versionString) + .replace ("${JUCE_PROJECT_VERSION_HEX}", juce::build_tools::getVersionAsHex (versionString)); + + return createAndWrite (output.resolveAsFile(), headerText); +} + +} // namespace + +int main (int argc, char** argv) +{ + juce::ScopedJuceInitialiser_GUI libraryInitialiser; + + return juce::ConsoleApplication::invokeCatchingFailures ([argc, argv] + { + juce::ArgumentList argumentList { argc, argv }; + + using Fn = typename std::add_lvalue_reference<decltype (writeBinaryData)>::type; + + const std::unordered_map<juce::String, Fn> commands + { + { "auplugindefines", writeAuPluginDefines }, + { "binarydata", writeBinaryData }, + { "entitlements", writeEntitlements }, + { "header", writeHeader }, + { "iosassets", writeiOSAssets }, + { "macicon", writeMacIcon }, + { "pkginfo", writePkgInfo }, + { "plist", writePlist }, + { "rcfile", writeRcFile }, + { "winicon", writeWinIcon } + }; + + argumentList.checkMinNumArguments (1); + const auto mode = argumentList.arguments.removeAndReturn (0); + const auto it = commands.find (mode.text); + + if (it == commands.cend()) + juce::ConsoleApplication::fail ("No matching mode", 1); + + return it->second (std::move (argumentList)); + }); +} diff --git a/extras/CMakeLists.txt b/extras/CMakeLists.txt new file mode 100644 index 00000000..bb08cea0 --- /dev/null +++ b/extras/CMakeLists.txt @@ -0,0 +1,30 @@ +# ============================================================================== +# +# This file is part of the JUCE library. +# Copyright (c) 2020 - Raw Material Software Limited +# +# JUCE is an open source library subject to commercial or open-source +# licensing. +# +# By using JUCE, you agree to the terms of both the JUCE 6 End-User License +# Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). +# +# End User License Agreement: www.juce.com/juce-6-licence +# Privacy Policy: www.juce.com/juce-privacy-policy +# +# Or: You may also use this code under the terms of the GPL v3 (see +# www.gnu.org/licenses). +# +# JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER +# EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE +# DISCLAIMED. +# +# ============================================================================== + +set(CMAKE_FOLDER extras) +add_subdirectory(AudioPerformanceTest) +add_subdirectory(AudioPluginHost) +add_subdirectory(BinaryBuilder) +add_subdirectory(NetworkGraphicsDemo) +add_subdirectory(Projucer) +add_subdirectory(UnitTestRunner) diff --git a/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt b/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt index 0b74a58e..8f3ab5eb 100644 --- a/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt +++ b/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt @@ -3,12 +3,16 @@ cmake_minimum_required(VERSION 3.4.1) -SET(BINARY_NAME "juce_jni") +set(BINARY_NAME "juce_jni") + +set(OBOE_DIR "../../../../../modules/juce_audio_devices/native/oboe") + +add_subdirectory (${OBOE_DIR} ./oboe) 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=16" "-DJUCE_PUSH_NOTIFICATIONS=1" "-DJUCE_PUSH_NOTIFICATIONS_ACTIVITY=\"com/roli/juce/JuceActivity\"" "-DJUCER_ANDROIDSTUDIO_7F0E4A25=1" "-DJUCE_APP_VERSION=1.0.0" "-DJUCE_APP_VERSION_HEX=0x10000") +add_definitions("-DJUCE_ANDROID=1" "-DJUCE_ANDROID_API_VERSION=16" "-DJUCE_PUSH_NOTIFICATIONS=1" "-DJUCE_PUSH_NOTIFICATIONS_ACTIVITY=\"com/rmsl/juce/JuceActivity\"" "-DJUCER_ANDROIDSTUDIO_7F0E4A25=1" "-DJUCE_APP_VERSION=1.0.0" "-DJUCE_APP_VERSION_HEX=0x10000") include_directories( AFTER "../../../JuceLibraryCode" @@ -18,13 +22,13 @@ include_directories( AFTER enable_language(ASM) -IF(JUCE_BUILD_CONFIGURATION MATCHES "DEBUG") - add_definitions("-DJUCE_DEBUG=0" "-DDEBUG=1" "-D_DEBUG=1") -ELSEIF(JUCE_BUILD_CONFIGURATION MATCHES "RELEASE") - add_definitions("-DNDEBUG=1") -ELSE(JUCE_BUILD_CONFIGURATION MATCHES "DEBUG") - MESSAGE( FATAL_ERROR "No matching build-configuration found." ) -ENDIF(JUCE_BUILD_CONFIGURATION MATCHES "DEBUG") +if(JUCE_BUILD_CONFIGURATION MATCHES "DEBUG") + add_definitions("-DJUCE_DISPLAY_SPLASH_SCREEN=0" "-DJUCE_USE_DARK_SPLASH_SCREEN=1" "-DJUCE_PROJUCER_VERSION=0x60005" "-DJUCE_MODULE_AVAILABLE_juce_audio_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_devices=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_formats=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_processors=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_utils=1" "-DJUCE_MODULE_AVAILABLE_juce_core=1" "-DJUCE_MODULE_AVAILABLE_juce_cryptography=1" "-DJUCE_MODULE_AVAILABLE_juce_data_structures=1" "-DJUCE_MODULE_AVAILABLE_juce_events=1" "-DJUCE_MODULE_AVAILABLE_juce_graphics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_extra=1" "-DJUCE_MODULE_AVAILABLE_juce_opengl=1" "-DJUCE_MODULE_AVAILABLE_juce_osc=1" "-DJUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1" "-DJUCE_STANDALONE_APPLICATION=1" "-DJUCE_DEBUG=0" "-DJUCER_ANDROIDSTUDIO_7F0E4A25=1" "-DJUCE_APP_VERSION=1.0.0" "-DJUCE_APP_VERSION_HEX=0x10000" "-DDEBUG=1" "-D_DEBUG=1") +elseif(JUCE_BUILD_CONFIGURATION MATCHES "RELEASE") + add_definitions("-DJUCE_DISPLAY_SPLASH_SCREEN=0" "-DJUCE_USE_DARK_SPLASH_SCREEN=1" "-DJUCE_PROJUCER_VERSION=0x60005" "-DJUCE_MODULE_AVAILABLE_juce_audio_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_devices=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_formats=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_processors=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_utils=1" "-DJUCE_MODULE_AVAILABLE_juce_core=1" "-DJUCE_MODULE_AVAILABLE_juce_cryptography=1" "-DJUCE_MODULE_AVAILABLE_juce_data_structures=1" "-DJUCE_MODULE_AVAILABLE_juce_events=1" "-DJUCE_MODULE_AVAILABLE_juce_graphics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_extra=1" "-DJUCE_MODULE_AVAILABLE_juce_opengl=1" "-DJUCE_MODULE_AVAILABLE_juce_osc=1" "-DJUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1" "-DJUCE_STANDALONE_APPLICATION=1" "-DJUCER_ANDROIDSTUDIO_7F0E4A25=1" "-DJUCE_APP_VERSION=1.0.0" "-DJUCE_APP_VERSION_HEX=0x10000" "-DNDEBUG=1") +else() + message( FATAL_ERROR "No matching build-configuration found." ) +endif() add_library( ${BINARY_NAME} @@ -98,16 +102,17 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp" "../../../../../modules/juce_audio_basics/synthesisers/juce_Synthesiser.h" "../../../../../modules/juce_audio_basics/utilities/juce_ADSR.h" - "../../../../../modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.cpp" - "../../../../../modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.h" "../../../../../modules/juce_audio_basics/utilities/juce_Decibels.h" + "../../../../../modules/juce_audio_basics/utilities/juce_GenericInterpolator.h" "../../../../../modules/juce_audio_basics/utilities/juce_IIRFilter.cpp" "../../../../../modules/juce_audio_basics/utilities/juce_IIRFilter.h" + "../../../../../modules/juce_audio_basics/utilities/juce_Interpolators.cpp" + "../../../../../modules/juce_audio_basics/utilities/juce_Interpolators.h" "../../../../../modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.cpp" - "../../../../../modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.h" "../../../../../modules/juce_audio_basics/utilities/juce_Reverb.h" "../../../../../modules/juce_audio_basics/utilities/juce_SmoothedValue.cpp" "../../../../../modules/juce_audio_basics/utilities/juce_SmoothedValue.h" + "../../../../../modules/juce_audio_basics/utilities/juce_WindowedSincInterpolator.cpp" "../../../../../modules/juce_audio_basics/juce_audio_basics.cpp" "../../../../../modules/juce_audio_basics/juce_audio_basics.mm" "../../../../../modules/juce_audio_basics/juce_audio_basics.h" @@ -122,7 +127,118 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_devices/midi_io/juce_MidiDevices.h" "../../../../../modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.cpp" "../../../../../modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStream.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamBase.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamBuilder.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamCallback.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Definitions.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/LatencyTuner.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Oboe.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/ResultWithValue.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/StabilizedCallback.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Utilities.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Version.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AAudioLoader.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AAudioLoader.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioClock.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioSourceCaller.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioSourceCaller.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioStream.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioStreamBuilder.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/DataConversionFlowGraph.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/DataConversionFlowGraph.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/FilterAudioStream.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/FilterAudioStream.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockAdapter.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockAdapter.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockReader.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockReader.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockWriter.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockWriter.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/LatencyTuner.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/MonotonicCounter.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/OboeDebug.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/QuirksManager.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/QuirksManager.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceFloatCaller.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceFloatCaller.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceI16Caller.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceI16Caller.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/StabilizedCallback.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/Trace.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/Trace.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/Utilities.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/Version.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoController.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoController.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/HyperbolicCosineWindow.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/IntegerRatio.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/IntegerRatio.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/KaiserWindow.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/LinearResampler.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/LinearResampler.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/MultiChannelResampler.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/MultiChannelResampler.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResampler.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResampler.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResamplerStereo.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResamplerStereo.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ClipToRange.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ClipToRange.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/RampLinear.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/RampLinear.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SampleRateConverter.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SampleRateConverter.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkFloat.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkFloat.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI16.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI16.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI24.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI24.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceFloat.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceFloat.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI16.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI16.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI24.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI24.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioInputStreamOpenSLES.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioInputStreamOpenSLES.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioOutputStreamOpenSLES.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioOutputStreamOpenSLES.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamBuffered.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamBuffered.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamOpenSLES.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamOpenSLES.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/EngineOpenSLES.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/EngineOpenSLES.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/OpenSLESUtilities.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/OpenSLESUtilities.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/OutputMixerOpenSLES.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/OutputMixerOpenSLES.h" + "../../../../../modules/juce_audio_devices/native/oboe/CMakeLists.txt" + "../../../../../modules/juce_audio_devices/native/oboe/readme.md" "../../../../../modules/juce_audio_devices/native/juce_android_Audio.cpp" + "../../../../../modules/juce_audio_devices/native/juce_android_HighPerformanceAudioHelpers.h" "../../../../../modules/juce_audio_devices/native/juce_android_Midi.cpp" "../../../../../modules/juce_audio_devices/native/juce_android_Oboe.cpp" "../../../../../modules/juce_audio_devices/native/juce_android_OpenSL.cpp" @@ -194,73 +310,76 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_formats/codecs/flac/stream_decoder.h" "../../../../../modules/juce_audio_formats/codecs/flac/stream_encoder.h" "../../../../../modules/juce_audio_formats/codecs/flac/win_utf8_io.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/books/coupled/res_books_51.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/books/coupled/res_books_stereo.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/books/floor/floor_books.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/books/uncoupled/res_books_uncoupled.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/floor_all.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/psych_8.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/psych_11.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/psych_16.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/psych_44.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_8.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_16.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_44.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_44p51.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_44u.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_8.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_11.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_16.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_22.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_32.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_44.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_44p51.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_44u.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_X.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/analysis.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/backends.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/bitrate.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/bitrate.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/block.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/codebook.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/codebook.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/codec_internal.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/envelope.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/envelope.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/floor0.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/floor1.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/highlevel.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/info.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lookup.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lookup.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lookup_data.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lpc.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lpc.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lsp.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lsp.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/mapping0.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/masking.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/mdct.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/mdct.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/misc.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/os.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/psy.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/psy.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/registry.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/registry.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/res0.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/scales.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/sharedbook.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/smallft.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/smallft.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/synthesis.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/vorbisenc.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/vorbisfile.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/window.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/window.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/books/coupled/res_books_51.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/books/coupled/res_books_stereo.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/books/floor/floor_books.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/books/uncoupled/res_books_uncoupled.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/floor_all.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/psych_8.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/psych_11.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/psych_16.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/psych_44.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/residue_8.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/residue_16.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/residue_44.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/residue_44p51.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/residue_44u.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_8.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_11.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_16.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_22.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_32.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_44.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_44p51.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_44u.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_X.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/analysis.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/backends.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/bitrate.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/bitrate.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/block.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/codebook.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/codebook.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/codec_internal.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/envelope.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/envelope.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/floor0.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/floor1.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/highlevel.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/info.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lookup.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lookup.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lookup_data.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lpc.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lpc.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lsp.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lsp.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/mapping0.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/masking.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/mdct.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/mdct.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/misc.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/misc.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/os.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/psy.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/psy.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/registry.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/registry.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/res0.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/scales.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/sharedbook.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/smallft.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/smallft.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/synthesis.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/vorbisenc.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/vorbisfile.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/window.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/window.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/README.md" "../../../../../modules/juce_audio_formats/codecs/oggvorbis/bitwise.c" "../../../../../modules/juce_audio_formats/codecs/oggvorbis/codec.h" "../../../../../modules/juce_audio_formats/codecs/oggvorbis/config_types.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/crctable.h" "../../../../../modules/juce_audio_formats/codecs/oggvorbis/framing.c" "../../../../../modules/juce_audio_formats/codecs/oggvorbis/Ogg Vorbis Licence.txt" "../../../../../modules/juce_audio_formats/codecs/oggvorbis/ogg.h" @@ -450,6 +569,8 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.h" "../../../../../modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp" "../../../../../modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h" + "../../../../../modules/juce_audio_processors/utilities/juce_ParameterAttachments.cpp" + "../../../../../modules/juce_audio_processors/utilities/juce_ParameterAttachments.h" "../../../../../modules/juce_audio_processors/utilities/juce_RangedAudioParameter.cpp" "../../../../../modules/juce_audio_processors/utilities/juce_RangedAudioParameter.h" "../../../../../modules/juce_audio_processors/juce_audio_processors.cpp" @@ -529,6 +650,8 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_core/files/juce_FileSearchPath.cpp" "../../../../../modules/juce_core/files/juce_FileSearchPath.h" "../../../../../modules/juce_core/files/juce_MemoryMappedFile.h" + "../../../../../modules/juce_core/files/juce_RangedDirectoryIterator.cpp" + "../../../../../modules/juce_core/files/juce_RangedDirectoryIterator.h" "../../../../../modules/juce_core/files/juce_TemporaryFile.cpp" "../../../../../modules/juce_core/files/juce_TemporaryFile.h" "../../../../../modules/juce_core/files/juce_WildcardFileFilter.cpp" @@ -551,6 +674,8 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_core/maths/juce_Random.h" "../../../../../modules/juce_core/maths/juce_Range.h" "../../../../../modules/juce_core/maths/juce_StatisticsAccumulator.h" + "../../../../../modules/juce_core/memory/juce_AllocationHooks.cpp" + "../../../../../modules/juce_core/memory/juce_AllocationHooks.h" "../../../../../modules/juce_core/memory/juce_Atomic.h" "../../../../../modules/juce_core/memory/juce_ByteOrder.h" "../../../../../modules/juce_core/memory/juce_ContainerDeletePolicy.h" @@ -637,6 +762,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_core/streams/juce_URLInputSource.cpp" "../../../../../modules/juce_core/streams/juce_URLInputSource.h" "../../../../../modules/juce_core/system/juce_CompilerSupport.h" + "../../../../../modules/juce_core/system/juce_CompilerWarnings.h" "../../../../../modules/juce_core/system/juce_PlatformDefs.h" "../../../../../modules/juce_core/system/juce_StandardHeader.h" "../../../../../modules/juce_core/system/juce_SystemStats.cpp" @@ -1161,6 +1287,11 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_gui_basics/mouse/juce_SelectedItemSet.h" "../../../../../modules/juce_gui_basics/mouse/juce_TextDragAndDropTarget.h" "../../../../../modules/juce_gui_basics/mouse/juce_TooltipClient.h" + "../../../../../modules/juce_gui_basics/native/x11/juce_linux_X11_DragAndDrop.cpp" + "../../../../../modules/juce_gui_basics/native/x11/juce_linux_X11_Symbols.cpp" + "../../../../../modules/juce_gui_basics/native/x11/juce_linux_X11_Symbols.h" + "../../../../../modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.cpp" + "../../../../../modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.h" "../../../../../modules/juce_gui_basics/native/juce_android_ContentSharer.cpp" "../../../../../modules/juce_gui_basics/native/juce_android_FileChooser.cpp" "../../../../../modules/juce_gui_basics/native/juce_android_Windowing.cpp" @@ -1170,10 +1301,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm" "../../../../../modules/juce_gui_basics/native/juce_ios_Windowing.mm" "../../../../../modules/juce_gui_basics/native/juce_linux_FileChooser.cpp" - "../../../../../modules/juce_gui_basics/native/juce_linux_X11.cpp" - "../../../../../modules/juce_gui_basics/native/juce_linux_X11.h" - "../../../../../modules/juce_gui_basics/native/juce_linux_X11_Clipboard.cpp" - "../../../../../modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp" + "../../../../../modules/juce_gui_basics/native/juce_linux_Windowing.cpp" "../../../../../modules/juce_gui_basics/native/juce_mac_FileChooser.mm" "../../../../../modules/juce_gui_basics/native/juce_mac_MainMenu.mm" "../../../../../modules/juce_gui_basics/native/juce_mac_MouseCursor.mm" @@ -1278,6 +1406,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.h" "../../../../../modules/juce_gui_extra/embedding/juce_ActiveXControlComponent.h" "../../../../../modules/juce_gui_extra/embedding/juce_AndroidViewComponent.h" + "../../../../../modules/juce_gui_extra/embedding/juce_HWNDComponent.h" "../../../../../modules/juce_gui_extra/embedding/juce_NSViewComponent.h" "../../../../../modules/juce_gui_extra/embedding/juce_ScopedDPIAwarenessDisabler.h" "../../../../../modules/juce_gui_extra/embedding/juce_UIViewComponent.h" @@ -1319,6 +1448,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_gui_extra/native/juce_mac_SystemTrayIcon.cpp" "../../../../../modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm" "../../../../../modules/juce_gui_extra/native/juce_win32_ActiveXComponent.cpp" + "../../../../../modules/juce_gui_extra/native/juce_win32_HWNDComponent.cpp" "../../../../../modules/juce_gui_extra/native/juce_win32_SystemTrayIcon.cpp" "../../../../../modules/juce_gui_extra/native/juce_win32_WebBrowserComponent.cpp" "../../../../../modules/juce_gui_extra/juce_gui_extra.cpp" @@ -1375,7 +1505,6 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_osc/osc/juce_OSCTypes.h" "../../../../../modules/juce_osc/juce_osc.cpp" "../../../../../modules/juce_osc/juce_osc.h" - "../../../JuceLibraryCode/AppConfig.h" "../../../JuceLibraryCode/BinaryData.cpp" "../../../JuceLibraryCode/BinaryData.h" "../../../JuceLibraryCode/include_juce_audio_basics.cpp" @@ -1462,16 +1591,17 @@ set_source_files_properties("../../../../../modules/juce_audio_basics/sources/ju set_source_files_properties("../../../../../modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/synthesisers/juce_Synthesiser.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_ADSR.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_Decibels.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_GenericInterpolator.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_IIRFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_IIRFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_Interpolators.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_Interpolators.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_Reverb.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_SmoothedValue.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_SmoothedValue.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_WindowedSincInterpolator.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/juce_audio_basics.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/juce_audio_basics.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/juce_audio_basics.h" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -1486,7 +1616,118 @@ set_source_files_properties("../../../../../modules/juce_audio_devices/midi_io/j set_source_files_properties("../../../../../modules/juce_audio_devices/midi_io/juce_MidiDevices.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStream.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamBase.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamBuilder.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamCallback.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Definitions.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/LatencyTuner.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Oboe.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/ResultWithValue.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/StabilizedCallback.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Utilities.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Version.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AAudioLoader.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AAudioLoader.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioClock.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioSourceCaller.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioSourceCaller.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioStream.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioStreamBuilder.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/DataConversionFlowGraph.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/DataConversionFlowGraph.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/FilterAudioStream.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/FilterAudioStream.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockAdapter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockAdapter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockReader.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockReader.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockWriter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockWriter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/LatencyTuner.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/MonotonicCounter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/OboeDebug.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/QuirksManager.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/QuirksManager.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceFloatCaller.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceFloatCaller.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceI16Caller.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceI16Caller.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/StabilizedCallback.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/Trace.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/Trace.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/Utilities.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/Version.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoController.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoController.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/HyperbolicCosineWindow.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/IntegerRatio.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/IntegerRatio.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/KaiserWindow.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/LinearResampler.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/LinearResampler.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/MultiChannelResampler.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/MultiChannelResampler.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResampler.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResampler.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResamplerStereo.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResamplerStereo.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ClipToRange.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ClipToRange.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/RampLinear.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/RampLinear.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SampleRateConverter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SampleRateConverter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkFloat.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkFloat.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI16.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI16.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI24.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI24.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceFloat.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceFloat.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI16.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI16.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI24.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI24.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioInputStreamOpenSLES.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioInputStreamOpenSLES.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioOutputStreamOpenSLES.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioOutputStreamOpenSLES.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamBuffered.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamBuffered.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamOpenSLES.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamOpenSLES.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/EngineOpenSLES.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/EngineOpenSLES.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/OpenSLESUtilities.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/OpenSLESUtilities.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/OutputMixerOpenSLES.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/OutputMixerOpenSLES.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/CMakeLists.txt" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/readme.md" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_android_Audio.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_android_HighPerformanceAudioHelpers.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_android_Midi.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_android_Oboe.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_android_OpenSL.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -1558,73 +1799,76 @@ set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/fl set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/stream_decoder.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/stream_encoder.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/win_utf8_io.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/books/coupled/res_books_51.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/books/coupled/res_books_stereo.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/books/floor/floor_books.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/books/uncoupled/res_books_uncoupled.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/floor_all.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/psych_8.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/psych_11.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/psych_16.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/psych_44.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_8.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_16.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_44.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_44p51.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_44u.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_8.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_11.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_16.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_22.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_32.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_44.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_44p51.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_44u.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_X.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/analysis.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/backends.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/bitrate.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/bitrate.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/block.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/codebook.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/codebook.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/codec_internal.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/envelope.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/envelope.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/floor0.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/floor1.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/highlevel.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/info.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lookup.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lookup.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lookup_data.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lpc.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lpc.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lsp.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lsp.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/mapping0.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/masking.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/mdct.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/mdct.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/misc.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/os.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/psy.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/psy.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/registry.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/registry.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/res0.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/scales.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/sharedbook.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/smallft.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/smallft.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/synthesis.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/vorbisenc.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/vorbisfile.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/window.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/window.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/books/coupled/res_books_51.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/books/coupled/res_books_stereo.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/books/floor/floor_books.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/books/uncoupled/res_books_uncoupled.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/floor_all.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/psych_8.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/psych_11.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/psych_16.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/psych_44.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/residue_8.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/residue_16.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/residue_44.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/residue_44p51.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/residue_44u.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_8.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_11.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_16.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_22.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_32.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_44.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_44p51.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_44u.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_X.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/analysis.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/backends.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/bitrate.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/bitrate.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/block.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/codebook.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/codebook.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/codec_internal.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/envelope.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/envelope.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/floor0.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/floor1.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/highlevel.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/info.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lookup.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lookup.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lookup_data.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lpc.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lpc.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lsp.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lsp.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/mapping0.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/masking.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/mdct.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/mdct.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/misc.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/misc.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/os.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/psy.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/psy.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/registry.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/registry.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/res0.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/scales.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/sharedbook.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/smallft.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/smallft.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/synthesis.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/vorbisenc.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/vorbisfile.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/window.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/window.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/README.md" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/bitwise.c" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/codec.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/config_types.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/crctable.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/framing.c" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/Ogg Vorbis Licence.txt" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/ogg.h" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -1814,6 +2058,8 @@ set_source_files_properties("../../../../../modules/juce_audio_processors/utilit set_source_files_properties("../../../../../modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_processors/utilities/juce_ParameterAttachments.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_processors/utilities/juce_ParameterAttachments.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_processors/utilities/juce_RangedAudioParameter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_processors/utilities/juce_RangedAudioParameter.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_processors/juce_audio_processors.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -1893,6 +2139,8 @@ set_source_files_properties("../../../../../modules/juce_core/files/juce_FileOut set_source_files_properties("../../../../../modules/juce_core/files/juce_FileSearchPath.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/files/juce_FileSearchPath.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/files/juce_MemoryMappedFile.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_core/files/juce_RangedDirectoryIterator.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_core/files/juce_RangedDirectoryIterator.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/files/juce_TemporaryFile.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/files/juce_TemporaryFile.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/files/juce_WildcardFileFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -1915,6 +2163,8 @@ set_source_files_properties("../../../../../modules/juce_core/maths/juce_Random. set_source_files_properties("../../../../../modules/juce_core/maths/juce_Random.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/maths/juce_Range.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/maths/juce_StatisticsAccumulator.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_core/memory/juce_AllocationHooks.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_core/memory/juce_AllocationHooks.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/memory/juce_Atomic.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/memory/juce_ByteOrder.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/memory/juce_ContainerDeletePolicy.h" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -2001,6 +2251,7 @@ set_source_files_properties("../../../../../modules/juce_core/streams/juce_Subre set_source_files_properties("../../../../../modules/juce_core/streams/juce_URLInputSource.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/streams/juce_URLInputSource.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/system/juce_CompilerSupport.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_core/system/juce_CompilerWarnings.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/system/juce_PlatformDefs.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/system/juce_StandardHeader.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/system/juce_SystemStats.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -2525,6 +2776,11 @@ set_source_files_properties("../../../../../modules/juce_gui_basics/mouse/juce_M set_source_files_properties("../../../../../modules/juce_gui_basics/mouse/juce_SelectedItemSet.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/mouse/juce_TextDragAndDropTarget.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/mouse/juce_TooltipClient.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_gui_basics/native/x11/juce_linux_X11_DragAndDrop.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_gui_basics/native/x11/juce_linux_X11_Symbols.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_gui_basics/native/x11/juce_linux_X11_Symbols.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_android_ContentSharer.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_android_FileChooser.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_android_Windowing.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -2534,10 +2790,7 @@ set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_ set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_ios_Windowing.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_linux_FileChooser.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_linux_X11.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_linux_X11.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_linux_X11_Clipboard.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_linux_Windowing.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_mac_FileChooser.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_mac_MainMenu.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_mac_MouseCursor.mm" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -2642,6 +2895,7 @@ set_source_files_properties("../../../../../modules/juce_gui_extra/documents/juc set_source_files_properties("../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/embedding/juce_ActiveXControlComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/embedding/juce_AndroidViewComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_gui_extra/embedding/juce_HWNDComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/embedding/juce_NSViewComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/embedding/juce_ScopedDPIAwarenessDisabler.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/embedding/juce_UIViewComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -2683,6 +2937,7 @@ set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_m set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_mac_SystemTrayIcon.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_win32_ActiveXComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_win32_HWNDComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_win32_SystemTrayIcon.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_win32_WebBrowserComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/juce_gui_extra.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -2739,10 +2994,19 @@ set_source_files_properties("../../../../../modules/juce_osc/osc/juce_OSCTypes.c set_source_files_properties("../../../../../modules/juce_osc/osc/juce_OSCTypes.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_osc/juce_osc.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_osc/juce_osc.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../JuceLibraryCode/AppConfig.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../JuceLibraryCode/BinaryData.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../JuceLibraryCode/JuceHeader.h" PROPERTIES HEADER_FILE_ONLY TRUE) +target_compile_options( ${BINARY_NAME} PRIVATE "-fsigned-char" ) + +if( JUCE_BUILD_CONFIGURATION MATCHES "DEBUG" ) + target_compile_options( ${BINARY_NAME} PRIVATE) +endif() + +if( JUCE_BUILD_CONFIGURATION MATCHES "RELEASE" ) + target_compile_options( ${BINARY_NAME} PRIVATE) +endif() + find_library(log "log") find_library(android "android") find_library(glesv2 "GLESv2") @@ -2755,4 +3019,5 @@ target_link_libraries( ${BINARY_NAME} ${glesv2} ${egl} "cpufeatures" + "oboe" ) diff --git a/extras/NetworkGraphicsDemo/Builds/Android/app/build.gradle b/extras/NetworkGraphicsDemo/Builds/Android/app/build.gradle index 7ae8705b..e403ef4f 100644 --- a/extras/NetworkGraphicsDemo/Builds/Android/app/build.gradle +++ b/extras/NetworkGraphicsDemo/Builds/Android/app/build.gradle @@ -1,7 +1,7 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 28 + compileSdkVersion 29 externalNativeBuild { cmake { path "CMakeLists.txt" @@ -20,12 +20,10 @@ android { defaultConfig { applicationId "com.juce.networkgraphicsdemo" minSdkVersion 16 - targetSdkVersion 28 + targetSdkVersion 29 externalNativeBuild { cmake { - arguments "-DANDROID_TOOLCHAIN=clang", "-DANDROID_PLATFORM=android-16", "-DANDROID_STL=c++_static", "-DANDROID_CPP_FEATURES=exceptions rtti", "-DANDROID_ARM_MODE=arm", "-DANDROID_ARM_NEON=TRUE" - cFlags "-fsigned-char" - cppFlags "-fsigned-char", "-std=c++14" + arguments "-DANDROID_TOOLCHAIN=clang", "-DANDROID_PLATFORM=android-16", "-DANDROID_STL=c++_static", "-DANDROID_CPP_FEATURES=exceptions rtti", "-DANDROID_ARM_MODE=arm", "-DANDROID_ARM_NEON=TRUE", "-DCMAKE_CXX_STANDARD=14", "-DCMAKE_CXX_EXTENSIONS=OFF" } } } @@ -86,7 +84,6 @@ android { main.java.srcDirs += ["../../../../../modules/juce_core/native/javacore/init", "../../../../../modules/juce_core/native/javacore/app", - "../../../../../modules/juce_gui_basics/native/javacore/app", "../../../../../modules/juce_gui_basics/native/javaopt/app"] main.res.srcDirs += diff --git a/extras/NetworkGraphicsDemo/Builds/Android/app/src/main/AndroidManifest.xml b/extras/NetworkGraphicsDemo/Builds/Android/app/src/main/AndroidManifest.xml index d3befd5e..6624aa7f 100644 --- a/extras/NetworkGraphicsDemo/Builds/Android/app/src/main/AndroidManifest.xml +++ b/extras/NetworkGraphicsDemo/Builds/Android/app/src/main/AndroidManifest.xml @@ -2,17 +2,18 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0.0" package="com.juce.NetworkGraphicsDemo"> - <supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:anyDensity="true"/> + <supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:anyDensity="true" + android:xlargeScreens="true"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> - <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> + <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/> <uses-permission android:name="android.permission.BLUETOOTH"/> <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/> <uses-permission android:name="android.permission.INTERNET"/> <uses-feature android:glEsVersion="0x00020000" android:required="true"/> - <application android:label="@string/app_name" android:name="com.roli.juce.JuceApp" android:icon="@drawable/icon" android:hardwareAccelerated="false"> - <activity android:name="com.roli.juce.JuceActivity" android:label="@string/app_name" android:configChanges="keyboardHidden|orientation|screenSize" + <application android:label="@string/app_name" android:name="com.rmsl.juce.JuceApp" android:icon="@drawable/icon" android:hardwareAccelerated="false"> + <activity android:name="com.rmsl.juce.JuceActivity" android:label="@string/app_name" android:configChanges="keyboardHidden|orientation|screenSize" android:screenOrientation="unspecified" android:launchMode="singleTask" android:hardwareAccelerated="true"> <intent-filter> <action android:name="android.intent.action.MAIN"/> diff --git a/extras/NetworkGraphicsDemo/Builds/Android/app/src/main/java/com/android/vending/billing/IInAppBillingService.java b/extras/NetworkGraphicsDemo/Builds/Android/app/src/main/java/com/android/vending/billing/IInAppBillingService.java deleted file mode 100644 index 0bb31cb5..00000000 --- a/extras/NetworkGraphicsDemo/Builds/Android/app/src/main/java/com/android/vending/billing/IInAppBillingService.java +++ /dev/null @@ -1,971 +0,0 @@ -/* - ============================================================================== - - 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. - - 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. - - ============================================================================== -*/ - -package com.android.vending.billing; -/** - * InAppBillingService is the service that provides in-app billing version 3 and beyond. - * This service provides the following features: - * 1. Provides a new API to get details of in-app items published for the app including - * price, type, title and description. - * 2. The purchase flow is synchronous and purchase information is available immediately - * after it completes. - * 3. Purchase information of in-app purchases is maintained within the Google Play system - * till the purchase is consumed. - * 4. An API to consume a purchase of an inapp item. All purchases of one-time - * in-app items are consumable and thereafter can be purchased again. - * 5. An API to get current purchases of the user immediately. This will not contain any - * consumed purchases. - * - * All calls will give a response code with the following possible values - * RESULT_OK = 0 - success - * RESULT_USER_CANCELED = 1 - User pressed back or canceled a dialog - * RESULT_SERVICE_UNAVAILABLE = 2 - The network connection is down - * RESULT_BILLING_UNAVAILABLE = 3 - This billing API version is not supported for the type requested - * RESULT_ITEM_UNAVAILABLE = 4 - Requested SKU is not available for purchase - * RESULT_DEVELOPER_ERROR = 5 - Invalid arguments provided to the API - * RESULT_ERROR = 6 - Fatal error during the API action - * RESULT_ITEM_ALREADY_OWNED = 7 - Failure to purchase since item is already owned - * RESULT_ITEM_NOT_OWNED = 8 - Failure to consume since item is not owned - */ -public interface IInAppBillingService extends android.os.IInterface - { - /** Local-side IPC implementation stub class. */ - public static abstract class Stub extends android.os.Binder implements com.android.vending.billing.IInAppBillingService - { - private static final java.lang.String DESCRIPTOR = "com.android.vending.billing.IInAppBillingService"; - /** Construct the stub at attach it to the interface. */ - public Stub() - { - this.attachInterface(this, DESCRIPTOR); - } - /** - * Cast an IBinder object into an com.android.vending.billing.IInAppBillingService interface, - * generating a proxy if needed. - */ - public static com.android.vending.billing.IInAppBillingService asInterface(android.os.IBinder obj) - { - if ((obj==null)) { - return null; - } - android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); - if (((iin!=null)&&(iin instanceof com.android.vending.billing.IInAppBillingService))) { - return ((com.android.vending.billing.IInAppBillingService)iin); - } - return new com.android.vending.billing.IInAppBillingService.Stub.Proxy(obj); - } - @Override public android.os.IBinder asBinder() - { - return this; - } - @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException - { - switch (code) - { - case INTERFACE_TRANSACTION: - { - reply.writeString(DESCRIPTOR); - return true; - } - case TRANSACTION_isBillingSupported: - { - data.enforceInterface(DESCRIPTOR); - int _arg0; - _arg0 = data.readInt(); - java.lang.String _arg1; - _arg1 = data.readString(); - java.lang.String _arg2; - _arg2 = data.readString(); - int _result = this.isBillingSupported(_arg0, _arg1, _arg2); - reply.writeNoException(); - reply.writeInt(_result); - return true; - } - case TRANSACTION_getSkuDetails: - { - data.enforceInterface(DESCRIPTOR); - int _arg0; - _arg0 = data.readInt(); - java.lang.String _arg1; - _arg1 = data.readString(); - java.lang.String _arg2; - _arg2 = data.readString(); - android.os.Bundle _arg3; - if ((0!=data.readInt())) { - _arg3 = android.os.Bundle.CREATOR.createFromParcel(data); - } - else { - _arg3 = null; - } - android.os.Bundle _result = this.getSkuDetails(_arg0, _arg1, _arg2, _arg3); - reply.writeNoException(); - if ((_result!=null)) { - reply.writeInt(1); - _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE); - } - else { - reply.writeInt(0); - } - return true; - } - case TRANSACTION_getBuyIntent: - { - data.enforceInterface(DESCRIPTOR); - int _arg0; - _arg0 = data.readInt(); - java.lang.String _arg1; - _arg1 = data.readString(); - java.lang.String _arg2; - _arg2 = data.readString(); - java.lang.String _arg3; - _arg3 = data.readString(); - java.lang.String _arg4; - _arg4 = data.readString(); - android.os.Bundle _result = this.getBuyIntent(_arg0, _arg1, _arg2, _arg3, _arg4); - reply.writeNoException(); - if ((_result!=null)) { - reply.writeInt(1); - _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE); - } - else { - reply.writeInt(0); - } - return true; - } - case TRANSACTION_getPurchases: - { - data.enforceInterface(DESCRIPTOR); - int _arg0; - _arg0 = data.readInt(); - java.lang.String _arg1; - _arg1 = data.readString(); - java.lang.String _arg2; - _arg2 = data.readString(); - java.lang.String _arg3; - _arg3 = data.readString(); - android.os.Bundle _result = this.getPurchases(_arg0, _arg1, _arg2, _arg3); - reply.writeNoException(); - if ((_result!=null)) { - reply.writeInt(1); - _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE); - } - else { - reply.writeInt(0); - } - return true; - } - case TRANSACTION_consumePurchase: - { - data.enforceInterface(DESCRIPTOR); - int _arg0; - _arg0 = data.readInt(); - java.lang.String _arg1; - _arg1 = data.readString(); - java.lang.String _arg2; - _arg2 = data.readString(); - int _result = this.consumePurchase(_arg0, _arg1, _arg2); - reply.writeNoException(); - reply.writeInt(_result); - return true; - } - case TRANSACTION_stub: - { - data.enforceInterface(DESCRIPTOR); - int _arg0; - _arg0 = data.readInt(); - java.lang.String _arg1; - _arg1 = data.readString(); - java.lang.String _arg2; - _arg2 = data.readString(); - int _result = this.stub(_arg0, _arg1, _arg2); - reply.writeNoException(); - reply.writeInt(_result); - return true; - } - case TRANSACTION_getBuyIntentToReplaceSkus: - { - data.enforceInterface(DESCRIPTOR); - int _arg0; - _arg0 = data.readInt(); - java.lang.String _arg1; - _arg1 = data.readString(); - java.util.List<java.lang.String> _arg2; - _arg2 = data.createStringArrayList(); - java.lang.String _arg3; - _arg3 = data.readString(); - java.lang.String _arg4; - _arg4 = data.readString(); - java.lang.String _arg5; - _arg5 = data.readString(); - android.os.Bundle _result = this.getBuyIntentToReplaceSkus(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5); - reply.writeNoException(); - if ((_result!=null)) { - reply.writeInt(1); - _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE); - } - else { - reply.writeInt(0); - } - return true; - } - case TRANSACTION_getBuyIntentExtraParams: - { - data.enforceInterface(DESCRIPTOR); - int _arg0; - _arg0 = data.readInt(); - java.lang.String _arg1; - _arg1 = data.readString(); - java.lang.String _arg2; - _arg2 = data.readString(); - java.lang.String _arg3; - _arg3 = data.readString(); - java.lang.String _arg4; - _arg4 = data.readString(); - android.os.Bundle _arg5; - if ((0!=data.readInt())) { - _arg5 = android.os.Bundle.CREATOR.createFromParcel(data); - } - else { - _arg5 = null; - } - android.os.Bundle _result = this.getBuyIntentExtraParams(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5); - reply.writeNoException(); - if ((_result!=null)) { - reply.writeInt(1); - _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE); - } - else { - reply.writeInt(0); - } - return true; - } - case TRANSACTION_getPurchaseHistory: - { - data.enforceInterface(DESCRIPTOR); - int _arg0; - _arg0 = data.readInt(); - java.lang.String _arg1; - _arg1 = data.readString(); - java.lang.String _arg2; - _arg2 = data.readString(); - java.lang.String _arg3; - _arg3 = data.readString(); - android.os.Bundle _arg4; - if ((0!=data.readInt())) { - _arg4 = android.os.Bundle.CREATOR.createFromParcel(data); - } - else { - _arg4 = null; - } - android.os.Bundle _result = this.getPurchaseHistory(_arg0, _arg1, _arg2, _arg3, _arg4); - reply.writeNoException(); - if ((_result!=null)) { - reply.writeInt(1); - _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE); - } - else { - reply.writeInt(0); - } - return true; - } - case TRANSACTION_isBillingSupportedExtraParams: - { - data.enforceInterface(DESCRIPTOR); - int _arg0; - _arg0 = data.readInt(); - java.lang.String _arg1; - _arg1 = data.readString(); - java.lang.String _arg2; - _arg2 = data.readString(); - android.os.Bundle _arg3; - if ((0!=data.readInt())) { - _arg3 = android.os.Bundle.CREATOR.createFromParcel(data); - } - else { - _arg3 = null; - } - int _result = this.isBillingSupportedExtraParams(_arg0, _arg1, _arg2, _arg3); - reply.writeNoException(); - reply.writeInt(_result); - return true; - } - } - return super.onTransact(code, data, reply, flags); - } - private static class Proxy implements com.android.vending.billing.IInAppBillingService - { - private android.os.IBinder mRemote; - Proxy(android.os.IBinder remote) - { - mRemote = remote; - } - @Override public android.os.IBinder asBinder() - { - return mRemote; - } - public java.lang.String getInterfaceDescriptor() - { - return DESCRIPTOR; - } - @Override public int isBillingSupported(int apiVersion, java.lang.String packageName, java.lang.String type) throws android.os.RemoteException - { - android.os.Parcel _data = android.os.Parcel.obtain(); - android.os.Parcel _reply = android.os.Parcel.obtain(); - int _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeInt(apiVersion); - _data.writeString(packageName); - _data.writeString(type); - mRemote.transact(Stub.TRANSACTION_isBillingSupported, _data, _reply, 0); - _reply.readException(); - _result = _reply.readInt(); - } - finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - /** - * Provides details of a list of SKUs - * Given a list of SKUs of a valid type in the skusBundle, this returns a bundle - * with a list JSON strings containing the productId, price, title and description. - * This API can be called with a maximum of 20 SKUs. - * @param apiVersion billing API version that the app is using - * @param packageName the package name of the calling app - * @param type of the in-app items ("inapp" for one-time purchases - * and "subs" for subscriptions) - * @param skusBundle bundle containing a StringArrayList of SKUs with key "ITEM_ID_LIST" - * @return Bundle containing the following key-value pairs - * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes - * on failures. - * "DETAILS_LIST" with a StringArrayList containing purchase information - * in JSON format similar to: - * '{ "productId" : "exampleSku", - * "type" : "inapp", - * "price" : "$5.00", - * "price_currency": "USD", - * "price_amount_micros": 5000000, - * "title : "Example Title", - * "description" : "This is an example description" }' - */ - @Override public android.os.Bundle getSkuDetails(int apiVersion, java.lang.String packageName, java.lang.String type, android.os.Bundle skusBundle) throws android.os.RemoteException - { - android.os.Parcel _data = android.os.Parcel.obtain(); - android.os.Parcel _reply = android.os.Parcel.obtain(); - android.os.Bundle _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeInt(apiVersion); - _data.writeString(packageName); - _data.writeString(type); - if ((skusBundle!=null)) { - _data.writeInt(1); - skusBundle.writeToParcel(_data, 0); - } - else { - _data.writeInt(0); - } - mRemote.transact(Stub.TRANSACTION_getSkuDetails, _data, _reply, 0); - _reply.readException(); - if ((0!=_reply.readInt())) { - _result = android.os.Bundle.CREATOR.createFromParcel(_reply); - } - else { - _result = null; - } - } - finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - /** - * Returns a pending intent to launch the purchase flow for an in-app item by providing a SKU, - * the type, a unique purchase token and an optional developer payload. - * @param apiVersion billing API version that the app is using - * @param packageName package name of the calling app - * @param sku the SKU of the in-app item as published in the developer console - * @param type of the in-app item being purchased ("inapp" for one-time purchases - * and "subs" for subscriptions) - * @param developerPayload optional argument to be sent back with the purchase information - * @return Bundle containing the following key-value pairs - * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes - * on failures. - * "BUY_INTENT" - PendingIntent to start the purchase flow - * - * The Pending intent should be launched with startIntentSenderForResult. When purchase flow - * has completed, the onActivityResult() will give a resultCode of OK or CANCELED. - * If the purchase is successful, the result data will contain the following key-value pairs - * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response - * codes on failures. - * "INAPP_PURCHASE_DATA" - String in JSON format similar to - * '{"orderId":"12999763169054705758.1371079406387615", - * "packageName":"com.example.app", - * "productId":"exampleSku", - * "purchaseTime":1345678900000, - * "purchaseToken" : "122333444455555", - * "developerPayload":"example developer payload" }' - * "INAPP_DATA_SIGNATURE" - String containing the signature of the purchase data that - * was signed with the private key of the developer - */ - @Override public android.os.Bundle getBuyIntent(int apiVersion, java.lang.String packageName, java.lang.String sku, java.lang.String type, java.lang.String developerPayload) throws android.os.RemoteException - { - android.os.Parcel _data = android.os.Parcel.obtain(); - android.os.Parcel _reply = android.os.Parcel.obtain(); - android.os.Bundle _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeInt(apiVersion); - _data.writeString(packageName); - _data.writeString(sku); - _data.writeString(type); - _data.writeString(developerPayload); - mRemote.transact(Stub.TRANSACTION_getBuyIntent, _data, _reply, 0); - _reply.readException(); - if ((0!=_reply.readInt())) { - _result = android.os.Bundle.CREATOR.createFromParcel(_reply); - } - else { - _result = null; - } - } - finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - /** - * Returns the current SKUs owned by the user of the type and package name specified along with - * purchase information and a signature of the data to be validated. - * This will return all SKUs that have been purchased in V3 and managed items purchased using - * V1 and V2 that have not been consumed. - * @param apiVersion billing API version that the app is using - * @param packageName package name of the calling app - * @param type of the in-app items being requested ("inapp" for one-time purchases - * and "subs" for subscriptions) - * @param continuationToken to be set as null for the first call, if the number of owned - * skus are too many, a continuationToken is returned in the response bundle. - * This method can be called again with the continuation token to get the next set of - * owned skus. - * @return Bundle containing the following key-value pairs - * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes - on failures. - * "INAPP_PURCHASE_ITEM_LIST" - StringArrayList containing the list of SKUs - * "INAPP_PURCHASE_DATA_LIST" - StringArrayList containing the purchase information - * "INAPP_DATA_SIGNATURE_LIST"- StringArrayList containing the signatures - * of the purchase information - * "INAPP_CONTINUATION_TOKEN" - String containing a continuation token for the - * next set of in-app purchases. Only set if the - * user has more owned skus than the current list. - */ - @Override public android.os.Bundle getPurchases(int apiVersion, java.lang.String packageName, java.lang.String type, java.lang.String continuationToken) throws android.os.RemoteException - { - android.os.Parcel _data = android.os.Parcel.obtain(); - android.os.Parcel _reply = android.os.Parcel.obtain(); - android.os.Bundle _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeInt(apiVersion); - _data.writeString(packageName); - _data.writeString(type); - _data.writeString(continuationToken); - mRemote.transact(Stub.TRANSACTION_getPurchases, _data, _reply, 0); - _reply.readException(); - if ((0!=_reply.readInt())) { - _result = android.os.Bundle.CREATOR.createFromParcel(_reply); - } - else { - _result = null; - } - } - finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - @Override public int consumePurchase(int apiVersion, java.lang.String packageName, java.lang.String purchaseToken) throws android.os.RemoteException - { - android.os.Parcel _data = android.os.Parcel.obtain(); - android.os.Parcel _reply = android.os.Parcel.obtain(); - int _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeInt(apiVersion); - _data.writeString(packageName); - _data.writeString(purchaseToken); - mRemote.transact(Stub.TRANSACTION_consumePurchase, _data, _reply, 0); - _reply.readException(); - _result = _reply.readInt(); - } - finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - @Override public int stub(int apiVersion, java.lang.String packageName, java.lang.String type) throws android.os.RemoteException - { - android.os.Parcel _data = android.os.Parcel.obtain(); - android.os.Parcel _reply = android.os.Parcel.obtain(); - int _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeInt(apiVersion); - _data.writeString(packageName); - _data.writeString(type); - mRemote.transact(Stub.TRANSACTION_stub, _data, _reply, 0); - _reply.readException(); - _result = _reply.readInt(); - } - finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - /** - * Returns a pending intent to launch the purchase flow for upgrading or downgrading a - * subscription. The existing owned SKU(s) should be provided along with the new SKU that - * the user is upgrading or downgrading to. - * @param apiVersion billing API version that the app is using, must be 5 or later - * @param packageName package name of the calling app - * @param oldSkus the SKU(s) that the user is upgrading or downgrading from, - * if null or empty this method will behave like {@link #getBuyIntent} - * @param newSku the SKU that the user is upgrading or downgrading to - * @param type of the item being purchased, currently must be "subs" - * @param developerPayload optional argument to be sent back with the purchase information - * @return Bundle containing the following key-value pairs - * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes - * on failures. - * "BUY_INTENT" - PendingIntent to start the purchase flow - * - * The Pending intent should be launched with startIntentSenderForResult. When purchase flow - * has completed, the onActivityResult() will give a resultCode of OK or CANCELED. - * If the purchase is successful, the result data will contain the following key-value pairs - * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response - * codes on failures. - * "INAPP_PURCHASE_DATA" - String in JSON format similar to - * '{"orderId":"12999763169054705758.1371079406387615", - * "packageName":"com.example.app", - * "productId":"exampleSku", - * "purchaseTime":1345678900000, - * "purchaseToken" : "122333444455555", - * "developerPayload":"example developer payload" }' - * "INAPP_DATA_SIGNATURE" - String containing the signature of the purchase data that - * was signed with the private key of the developer - */ - @Override public android.os.Bundle getBuyIntentToReplaceSkus(int apiVersion, java.lang.String packageName, java.util.List<java.lang.String> oldSkus, java.lang.String newSku, java.lang.String type, java.lang.String developerPayload) throws android.os.RemoteException - { - android.os.Parcel _data = android.os.Parcel.obtain(); - android.os.Parcel _reply = android.os.Parcel.obtain(); - android.os.Bundle _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeInt(apiVersion); - _data.writeString(packageName); - _data.writeStringList(oldSkus); - _data.writeString(newSku); - _data.writeString(type); - _data.writeString(developerPayload); - mRemote.transact(Stub.TRANSACTION_getBuyIntentToReplaceSkus, _data, _reply, 0); - _reply.readException(); - if ((0!=_reply.readInt())) { - _result = android.os.Bundle.CREATOR.createFromParcel(_reply); - } - else { - _result = null; - } - } - finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - /** - * Returns a pending intent to launch the purchase flow for an in-app item. This method is - * a variant of the {@link #getBuyIntent} method and takes an additional {@code extraParams} - * parameter. This parameter is a Bundle of optional keys and values that affect the - * operation of the method. - * @param apiVersion billing API version that the app is using, must be 6 or later - * @param packageName package name of the calling app - * @param sku the SKU of the in-app item as published in the developer console - * @param type of the in-app item being purchased ("inapp" for one-time purchases - * and "subs" for subscriptions) - * @param developerPayload optional argument to be sent back with the purchase information - * @extraParams a Bundle with the following optional keys: - * "skusToReplace" - List<String> - an optional list of SKUs that the user is - * upgrading or downgrading from. - * Pass this field if the purchase is upgrading or downgrading - * existing subscriptions. - * The specified SKUs are replaced with the SKUs that the user is - * purchasing. Google Play replaces the specified SKUs at the start of - * the next billing cycle. - * "replaceSkusProration" - Boolean - whether the user should be credited for any unused - * subscription time on the SKUs they are upgrading or downgrading. - * If you set this field to true, Google Play swaps out the old SKUs - * and credits the user with the unused value of their subscription - * time on a pro-rated basis. - * Google Play applies this credit to the new subscription, and does - * not begin billing the user for the new subscription until after - * the credit is used up. - * If you set this field to false, the user does not receive credit for - * any unused subscription time and the recurrence date does not - * change. - * Default value is true. Ignored if you do not pass skusToReplace. - * "accountId" - String - an optional obfuscated string that is uniquely - * associated with the user's account in your app. - * If you pass this value, Google Play can use it to detect irregular - * activity, such as many devices making purchases on the same - * account in a short period of time. - * Do not use the developer ID or the user's Google ID for this field. - * In addition, this field should not contain the user's ID in - * cleartext. - * We recommend that you use a one-way hash to generate a string from - * the user's ID, and store the hashed string in this field. - * "vr" - Boolean - an optional flag indicating whether the returned intent - * should start a VR purchase flow. The apiVersion must also be 7 or - * later to use this flag. - */ - @Override public android.os.Bundle getBuyIntentExtraParams(int apiVersion, java.lang.String packageName, java.lang.String sku, java.lang.String type, java.lang.String developerPayload, android.os.Bundle extraParams) throws android.os.RemoteException - { - android.os.Parcel _data = android.os.Parcel.obtain(); - android.os.Parcel _reply = android.os.Parcel.obtain(); - android.os.Bundle _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeInt(apiVersion); - _data.writeString(packageName); - _data.writeString(sku); - _data.writeString(type); - _data.writeString(developerPayload); - if ((extraParams!=null)) { - _data.writeInt(1); - extraParams.writeToParcel(_data, 0); - } - else { - _data.writeInt(0); - } - mRemote.transact(Stub.TRANSACTION_getBuyIntentExtraParams, _data, _reply, 0); - _reply.readException(); - if ((0!=_reply.readInt())) { - _result = android.os.Bundle.CREATOR.createFromParcel(_reply); - } - else { - _result = null; - } - } - finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - /** - * Returns the most recent purchase made by the user for each SKU, even if that purchase is - * expired, canceled, or consumed. - * @param apiVersion billing API version that the app is using, must be 6 or later - * @param packageName package name of the calling app - * @param type of the in-app items being requested ("inapp" for one-time purchases - * and "subs" for subscriptions) - * @param continuationToken to be set as null for the first call, if the number of owned - * skus is too large, a continuationToken is returned in the response bundle. - * This method can be called again with the continuation token to get the next set of - * owned skus. - * @param extraParams a Bundle with extra params that would be appended into http request - * query string. Not used at this moment. Reserved for future functionality. - * @return Bundle containing the following key-value pairs - * "RESPONSE_CODE" with int value: RESULT_OK(0) if success, - * {@link IabHelper#BILLING_RESPONSE_RESULT_*} response codes on failures. - * - * "INAPP_PURCHASE_ITEM_LIST" - ArrayList<String> containing the list of SKUs - * "INAPP_PURCHASE_DATA_LIST" - ArrayList<String> containing the purchase information - * "INAPP_DATA_SIGNATURE_LIST"- ArrayList<String> containing the signatures - * of the purchase information - * "INAPP_CONTINUATION_TOKEN" - String containing a continuation token for the - * next set of in-app purchases. Only set if the - * user has more owned skus than the current list. - */ - @Override public android.os.Bundle getPurchaseHistory(int apiVersion, java.lang.String packageName, java.lang.String type, java.lang.String continuationToken, android.os.Bundle extraParams) throws android.os.RemoteException - { - android.os.Parcel _data = android.os.Parcel.obtain(); - android.os.Parcel _reply = android.os.Parcel.obtain(); - android.os.Bundle _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeInt(apiVersion); - _data.writeString(packageName); - _data.writeString(type); - _data.writeString(continuationToken); - if ((extraParams!=null)) { - _data.writeInt(1); - extraParams.writeToParcel(_data, 0); - } - else { - _data.writeInt(0); - } - mRemote.transact(Stub.TRANSACTION_getPurchaseHistory, _data, _reply, 0); - _reply.readException(); - if ((0!=_reply.readInt())) { - _result = android.os.Bundle.CREATOR.createFromParcel(_reply); - } - else { - _result = null; - } - } - finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - @Override public int isBillingSupportedExtraParams(int apiVersion, java.lang.String packageName, java.lang.String type, android.os.Bundle extraParams) throws android.os.RemoteException - { - android.os.Parcel _data = android.os.Parcel.obtain(); - android.os.Parcel _reply = android.os.Parcel.obtain(); - int _result; - try { - _data.writeInterfaceToken(DESCRIPTOR); - _data.writeInt(apiVersion); - _data.writeString(packageName); - _data.writeString(type); - if ((extraParams!=null)) { - _data.writeInt(1); - extraParams.writeToParcel(_data, 0); - } - else { - _data.writeInt(0); - } - mRemote.transact(Stub.TRANSACTION_isBillingSupportedExtraParams, _data, _reply, 0); - _reply.readException(); - _result = _reply.readInt(); - } - finally { - _reply.recycle(); - _data.recycle(); - } - return _result; - } - } - static final int TRANSACTION_isBillingSupported = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); - static final int TRANSACTION_getSkuDetails = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1); - static final int TRANSACTION_getBuyIntent = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2); - static final int TRANSACTION_getPurchases = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3); - static final int TRANSACTION_consumePurchase = (android.os.IBinder.FIRST_CALL_TRANSACTION + 4); - static final int TRANSACTION_stub = (android.os.IBinder.FIRST_CALL_TRANSACTION + 5); - static final int TRANSACTION_getBuyIntentToReplaceSkus = (android.os.IBinder.FIRST_CALL_TRANSACTION + 6); - static final int TRANSACTION_getBuyIntentExtraParams = (android.os.IBinder.FIRST_CALL_TRANSACTION + 7); - static final int TRANSACTION_getPurchaseHistory = (android.os.IBinder.FIRST_CALL_TRANSACTION + 8); - static final int TRANSACTION_isBillingSupportedExtraParams = (android.os.IBinder.FIRST_CALL_TRANSACTION + 9); - } - public int isBillingSupported(int apiVersion, java.lang.String packageName, java.lang.String type) throws android.os.RemoteException; - /** - * Provides details of a list of SKUs - * Given a list of SKUs of a valid type in the skusBundle, this returns a bundle - * with a list JSON strings containing the productId, price, title and description. - * This API can be called with a maximum of 20 SKUs. - * @param apiVersion billing API version that the app is using - * @param packageName the package name of the calling app - * @param type of the in-app items ("inapp" for one-time purchases - * and "subs" for subscriptions) - * @param skusBundle bundle containing a StringArrayList of SKUs with key "ITEM_ID_LIST" - * @return Bundle containing the following key-value pairs - * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes - * on failures. - * "DETAILS_LIST" with a StringArrayList containing purchase information - * in JSON format similar to: - * '{ "productId" : "exampleSku", - * "type" : "inapp", - * "price" : "$5.00", - * "price_currency": "USD", - * "price_amount_micros": 5000000, - * "title : "Example Title", - * "description" : "This is an example description" }' - */ - public android.os.Bundle getSkuDetails(int apiVersion, java.lang.String packageName, java.lang.String type, android.os.Bundle skusBundle) throws android.os.RemoteException; - /** - * Returns a pending intent to launch the purchase flow for an in-app item by providing a SKU, - * the type, a unique purchase token and an optional developer payload. - * @param apiVersion billing API version that the app is using - * @param packageName package name of the calling app - * @param sku the SKU of the in-app item as published in the developer console - * @param type of the in-app item being purchased ("inapp" for one-time purchases - * and "subs" for subscriptions) - * @param developerPayload optional argument to be sent back with the purchase information - * @return Bundle containing the following key-value pairs - * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes - * on failures. - * "BUY_INTENT" - PendingIntent to start the purchase flow - * - * The Pending intent should be launched with startIntentSenderForResult. When purchase flow - * has completed, the onActivityResult() will give a resultCode of OK or CANCELED. - * If the purchase is successful, the result data will contain the following key-value pairs - * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response - * codes on failures. - * "INAPP_PURCHASE_DATA" - String in JSON format similar to - * '{"orderId":"12999763169054705758.1371079406387615", - * "packageName":"com.example.app", - * "productId":"exampleSku", - * "purchaseTime":1345678900000, - * "purchaseToken" : "122333444455555", - * "developerPayload":"example developer payload" }' - * "INAPP_DATA_SIGNATURE" - String containing the signature of the purchase data that - * was signed with the private key of the developer - */ - public android.os.Bundle getBuyIntent(int apiVersion, java.lang.String packageName, java.lang.String sku, java.lang.String type, java.lang.String developerPayload) throws android.os.RemoteException; - /** - * Returns the current SKUs owned by the user of the type and package name specified along with - * purchase information and a signature of the data to be validated. - * This will return all SKUs that have been purchased in V3 and managed items purchased using - * V1 and V2 that have not been consumed. - * @param apiVersion billing API version that the app is using - * @param packageName package name of the calling app - * @param type of the in-app items being requested ("inapp" for one-time purchases - * and "subs" for subscriptions) - * @param continuationToken to be set as null for the first call, if the number of owned - * skus are too many, a continuationToken is returned in the response bundle. - * This method can be called again with the continuation token to get the next set of - * owned skus. - * @return Bundle containing the following key-value pairs - * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes - on failures. - * "INAPP_PURCHASE_ITEM_LIST" - StringArrayList containing the list of SKUs - * "INAPP_PURCHASE_DATA_LIST" - StringArrayList containing the purchase information - * "INAPP_DATA_SIGNATURE_LIST"- StringArrayList containing the signatures - * of the purchase information - * "INAPP_CONTINUATION_TOKEN" - String containing a continuation token for the - * next set of in-app purchases. Only set if the - * user has more owned skus than the current list. - */ - public android.os.Bundle getPurchases(int apiVersion, java.lang.String packageName, java.lang.String type, java.lang.String continuationToken) throws android.os.RemoteException; - public int consumePurchase(int apiVersion, java.lang.String packageName, java.lang.String purchaseToken) throws android.os.RemoteException; - public int stub(int apiVersion, java.lang.String packageName, java.lang.String type) throws android.os.RemoteException; - /** - * Returns a pending intent to launch the purchase flow for upgrading or downgrading a - * subscription. The existing owned SKU(s) should be provided along with the new SKU that - * the user is upgrading or downgrading to. - * @param apiVersion billing API version that the app is using, must be 5 or later - * @param packageName package name of the calling app - * @param oldSkus the SKU(s) that the user is upgrading or downgrading from, - * if null or empty this method will behave like {@link #getBuyIntent} - * @param newSku the SKU that the user is upgrading or downgrading to - * @param type of the item being purchased, currently must be "subs" - * @param developerPayload optional argument to be sent back with the purchase information - * @return Bundle containing the following key-value pairs - * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes - * on failures. - * "BUY_INTENT" - PendingIntent to start the purchase flow - * - * The Pending intent should be launched with startIntentSenderForResult. When purchase flow - * has completed, the onActivityResult() will give a resultCode of OK or CANCELED. - * If the purchase is successful, the result data will contain the following key-value pairs - * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response - * codes on failures. - * "INAPP_PURCHASE_DATA" - String in JSON format similar to - * '{"orderId":"12999763169054705758.1371079406387615", - * "packageName":"com.example.app", - * "productId":"exampleSku", - * "purchaseTime":1345678900000, - * "purchaseToken" : "122333444455555", - * "developerPayload":"example developer payload" }' - * "INAPP_DATA_SIGNATURE" - String containing the signature of the purchase data that - * was signed with the private key of the developer - */ - public android.os.Bundle getBuyIntentToReplaceSkus(int apiVersion, java.lang.String packageName, java.util.List<java.lang.String> oldSkus, java.lang.String newSku, java.lang.String type, java.lang.String developerPayload) throws android.os.RemoteException; - /** - * Returns a pending intent to launch the purchase flow for an in-app item. This method is - * a variant of the {@link #getBuyIntent} method and takes an additional {@code extraParams} - * parameter. This parameter is a Bundle of optional keys and values that affect the - * operation of the method. - * @param apiVersion billing API version that the app is using, must be 6 or later - * @param packageName package name of the calling app - * @param sku the SKU of the in-app item as published in the developer console - * @param type of the in-app item being purchased ("inapp" for one-time purchases - * and "subs" for subscriptions) - * @param developerPayload optional argument to be sent back with the purchase information - * @extraParams a Bundle with the following optional keys: - * "skusToReplace" - List<String> - an optional list of SKUs that the user is - * upgrading or downgrading from. - * Pass this field if the purchase is upgrading or downgrading - * existing subscriptions. - * The specified SKUs are replaced with the SKUs that the user is - * purchasing. Google Play replaces the specified SKUs at the start of - * the next billing cycle. - * "replaceSkusProration" - Boolean - whether the user should be credited for any unused - * subscription time on the SKUs they are upgrading or downgrading. - * If you set this field to true, Google Play swaps out the old SKUs - * and credits the user with the unused value of their subscription - * time on a pro-rated basis. - * Google Play applies this credit to the new subscription, and does - * not begin billing the user for the new subscription until after - * the credit is used up. - * If you set this field to false, the user does not receive credit for - * any unused subscription time and the recurrence date does not - * change. - * Default value is true. Ignored if you do not pass skusToReplace. - * "accountId" - String - an optional obfuscated string that is uniquely - * associated with the user's account in your app. - * If you pass this value, Google Play can use it to detect irregular - * activity, such as many devices making purchases on the same - * account in a short period of time. - * Do not use the developer ID or the user's Google ID for this field. - * In addition, this field should not contain the user's ID in - * cleartext. - * We recommend that you use a one-way hash to generate a string from - * the user's ID, and store the hashed string in this field. - * "vr" - Boolean - an optional flag indicating whether the returned intent - * should start a VR purchase flow. The apiVersion must also be 7 or - * later to use this flag. - */ - public android.os.Bundle getBuyIntentExtraParams(int apiVersion, java.lang.String packageName, java.lang.String sku, java.lang.String type, java.lang.String developerPayload, android.os.Bundle extraParams) throws android.os.RemoteException; - /** - * Returns the most recent purchase made by the user for each SKU, even if that purchase is - * expired, canceled, or consumed. - * @param apiVersion billing API version that the app is using, must be 6 or later - * @param packageName package name of the calling app - * @param type of the in-app items being requested ("inapp" for one-time purchases - * and "subs" for subscriptions) - * @param continuationToken to be set as null for the first call, if the number of owned - * skus is too large, a continuationToken is returned in the response bundle. - * This method can be called again with the continuation token to get the next set of - * owned skus. - * @param extraParams a Bundle with extra params that would be appended into http request - * query string. Not used at this moment. Reserved for future functionality. - * @return Bundle containing the following key-value pairs - * "RESPONSE_CODE" with int value: RESULT_OK(0) if success, - * {@link IabHelper#BILLING_RESPONSE_RESULT_*} response codes on failures. - * - * "INAPP_PURCHASE_ITEM_LIST" - ArrayList<String> containing the list of SKUs - * "INAPP_PURCHASE_DATA_LIST" - ArrayList<String> containing the purchase information - * "INAPP_DATA_SIGNATURE_LIST"- ArrayList<String> containing the signatures - * of the purchase information - * "INAPP_CONTINUATION_TOKEN" - String containing a continuation token for the - * next set of in-app purchases. Only set if the - * user has more owned skus than the current list. - */ - public android.os.Bundle getPurchaseHistory(int apiVersion, java.lang.String packageName, java.lang.String type, java.lang.String continuationToken, android.os.Bundle extraParams) throws android.os.RemoteException; - public int isBillingSupportedExtraParams(int apiVersion, java.lang.String packageName, java.lang.String type, android.os.Bundle extraParams) throws android.os.RemoteException; - } diff --git a/extras/NetworkGraphicsDemo/Builds/Android/app/src/main/java/com/juce/networkgraphicsdemo/JUCENetworkGraphicsDemo.java b/extras/NetworkGraphicsDemo/Builds/Android/app/src/main/java/com/juce/networkgraphicsdemo/JUCENetworkGraphicsDemo.java deleted file mode 100644 index 40223e01..00000000 --- a/extras/NetworkGraphicsDemo/Builds/Android/app/src/main/java/com/juce/networkgraphicsdemo/JUCENetworkGraphicsDemo.java +++ /dev/null @@ -1,1889 +0,0 @@ -/* - ============================================================================== - - 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. - - 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. - - ============================================================================== -*/ - -package com.juce.networkgraphicsdemo; - -import android.app.Activity; -import android.app.AlertDialog; -import android.content.DialogInterface; -import android.content.Context; -import android.content.Intent; -import android.content.res.Configuration; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.net.http.SslError; -import android.net.Uri; -import android.os.Bundle; -import android.os.Looper; -import android.os.Handler; -import android.os.Message; -import android.os.ParcelUuid; -import android.os.Environment; -import android.view.*; -import android.view.inputmethod.BaseInputConnection; -import android.view.inputmethod.EditorInfo; -import android.view.inputmethod.InputConnection; -import android.view.inputmethod.InputMethodManager; -import android.graphics.*; -import android.text.ClipboardManager; -import android.text.InputType; -import android.util.DisplayMetrics; -import android.util.Log; -import android.util.Pair; -import android.webkit.SslErrorHandler; -import android.webkit.WebChromeClient; -import android.webkit.WebView; -import android.webkit.WebViewClient; -import java.lang.Runnable; -import java.lang.ref.WeakReference; -import java.lang.reflect.*; -import java.util.*; -import java.io.*; -import java.net.URL; -import java.net.HttpURLConnection; -import android.media.AudioManager; -import android.Manifest; -import java.util.concurrent.CancellationException; -import java.util.concurrent.Future; -import java.util.concurrent.Executors; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.Callable; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.locks.ReentrantLock; -import java.util.concurrent.atomic.*; - - - -//============================================================================== -public class JUCENetworkGraphicsDemo extends Activity -{ - //============================================================================== - static - { - System.loadLibrary ("juce_jni"); - } - - //============================================================================== - public boolean isPermissionDeclaredInManifest (int permissionID) - { - return isPermissionDeclaredInManifest (getAndroidPermissionName (permissionID)); - } - - public boolean isPermissionDeclaredInManifest (String permissionToCheck) - { - try - { - PackageInfo info = getPackageManager().getPackageInfo(getApplicationContext().getPackageName(), PackageManager.GET_PERMISSIONS); - - if (info.requestedPermissions != null) - for (String permission : info.requestedPermissions) - if (permission.equals (permissionToCheck)) - return true; - } - catch (PackageManager.NameNotFoundException e) - { - Log.d ("JUCE", "isPermissionDeclaredInManifest: PackageManager.NameNotFoundException = " + e.toString()); - } - - Log.d ("JUCE", "isPermissionDeclaredInManifest: could not find requested permission " + permissionToCheck); - return false; - } - - //============================================================================== - // these have to match the values of enum PermissionID in C++ class RuntimePermissions: - private static final int JUCE_PERMISSIONS_RECORD_AUDIO = 1; - private static final int JUCE_PERMISSIONS_BLUETOOTH_MIDI = 2; - private static final int JUCE_PERMISSIONS_READ_EXTERNAL_STORAGE = 3; - private static final int JUCE_PERMISSIONS_WRITE_EXTERNAL_STORAGE = 4; - private static final int JUCE_PERMISSIONS_CAMERA = 5; - - private static String getAndroidPermissionName (int permissionID) - { - switch (permissionID) - { - case JUCE_PERMISSIONS_RECORD_AUDIO: return Manifest.permission.RECORD_AUDIO; - case JUCE_PERMISSIONS_BLUETOOTH_MIDI: return Manifest.permission.ACCESS_COARSE_LOCATION; - // use string value as this is not defined in SDKs < 16 - case JUCE_PERMISSIONS_READ_EXTERNAL_STORAGE: return "android.permission.READ_EXTERNAL_STORAGE"; - case JUCE_PERMISSIONS_WRITE_EXTERNAL_STORAGE: return Manifest.permission.WRITE_EXTERNAL_STORAGE; - case JUCE_PERMISSIONS_CAMERA: return Manifest.permission.CAMERA; - } - - // unknown permission ID! - assert false; - return new String(); - } - - public boolean isPermissionGranted (int permissionID) - { - return getApplicationContext().checkCallingOrSelfPermission (getAndroidPermissionName (permissionID)) == PackageManager.PERMISSION_GRANTED; - } - - private Map<Integer, Long> permissionCallbackPtrMap; - - public void requestRuntimePermission (int permissionID, long ptrToCallback) - { - String permissionName = getAndroidPermissionName (permissionID); - - if (getApplicationContext().checkCallingOrSelfPermission (permissionName) != PackageManager.PERMISSION_GRANTED) - { - // remember callbackPtr, request permissions, and let onRequestPermissionResult call callback asynchronously - permissionCallbackPtrMap.put (permissionID, ptrToCallback); - requestPermissionsCompat (new String[]{permissionName}, permissionID); - } - else - { - // permissions were already granted before, we can call callback directly - androidRuntimePermissionsCallback (true, ptrToCallback); - } - } - - private native void androidRuntimePermissionsCallback (boolean permissionWasGranted, long ptrToCallback); - - - //============================================================================== - public interface JuceMidiPort - { - boolean isInputPort(); - - // start, stop does nothing on an output port - void start(); - void stop(); - - void close(); - - // send will do nothing on an input port - void sendMidi (byte[] msg, int offset, int count); - } - - //============================================================================== - //============================================================================== - public class BluetoothManager - { - BluetoothManager() - { - } - - public String[] getMidiBluetoothAddresses() - { - String[] bluetoothAddresses = new String[0]; - return bluetoothAddresses; - } - - public String getHumanReadableStringForBluetoothAddress (String address) - { - return address; - } - - public int getBluetoothDeviceStatus (String address) - { - return 0; - } - - public void startStopScan (boolean shouldStart) - { - } - - public boolean pairBluetoothMidiDevice(String address) - { - return false; - } - - public void unpairBluetoothMidiDevice (String address) - { - } - } - - //============================================================================== - public class MidiDeviceManager - { - public MidiDeviceManager() - { - } - - public String[] getJuceAndroidMidiInputDevices() - { - return new String[0]; - } - - public String[] getJuceAndroidMidiOutputDevices() - { - return new String[0]; - } - - public JuceMidiPort openMidiInputPortWithJuceIndex (int index, long host) - { - return null; - } - - public JuceMidiPort openMidiOutputPortWithJuceIndex (int index) - { - return null; - } - - public String getInputPortNameForJuceIndex (int index) - { - return ""; - } - - public String getOutputPortNameForJuceIndex (int index) - { - return ""; - } - } - - - public MidiDeviceManager getAndroidMidiDeviceManager() - { - return null; - } - - public BluetoothManager getAndroidBluetoothManager() - { - return null; - } - - //============================================================================== - @Override - public void onCreate (Bundle savedInstanceState) - { - super.onCreate (savedInstanceState); - - isScreenSaverEnabled = true; - hideActionBar(); - viewHolder = new ViewHolder (this); - setContentView (viewHolder); - - setVolumeControlStream (AudioManager.STREAM_MUSIC); - - permissionCallbackPtrMap = new HashMap<Integer, Long>(); - appPausedResumedListeners = new HashMap<Long, AppPausedResumedListener>(); - } - - @Override - protected void onDestroy() - { - quitApp(); - super.onDestroy(); - - clearDataCache(); - } - - @Override - protected void onPause() - { - suspendApp(); - - Long[] keys = appPausedResumedListeners.keySet().toArray (new Long[appPausedResumedListeners.keySet().size()]); - - for (Long k : keys) - appPausedResumedListeners.get (k).appPaused(); - - try - { - Thread.sleep (1000); // This is a bit of a hack to avoid some hard-to-track-down - // openGL glitches when pausing/resuming apps.. - } catch (InterruptedException e) {} - - super.onPause(); - } - - @Override - protected void onResume() - { - super.onResume(); - resumeApp(); - - Long[] keys = appPausedResumedListeners.keySet().toArray (new Long[appPausedResumedListeners.keySet().size()]); - - for (Long k : keys) - appPausedResumedListeners.get (k).appResumed(); - } - - @Override - public void onConfigurationChanged (Configuration cfg) - { - super.onConfigurationChanged (cfg); - setContentView (viewHolder); - } - - private void callAppLauncher() - { - launchApp (getApplicationInfo().publicSourceDir, - getApplicationInfo().dataDir); - } - - // Need to override this as the default implementation always finishes the activity. - @Override - public void onBackPressed() - { - ComponentPeerView focusedView = getViewWithFocusOrDefaultView(); - - if (focusedView == null) - return; - - focusedView.backButtonPressed(); - } - - private ComponentPeerView getViewWithFocusOrDefaultView() - { - for (int i = 0; i < viewHolder.getChildCount(); ++i) - { - if (viewHolder.getChildAt (i).hasFocus()) - return (ComponentPeerView) viewHolder.getChildAt (i); - } - - if (viewHolder.getChildCount() > 0) - return (ComponentPeerView) viewHolder.getChildAt (0); - - return null; - } - - //============================================================================== - private void hideActionBar() - { - // get "getActionBar" method - java.lang.reflect.Method getActionBarMethod = null; - try - { - getActionBarMethod = this.getClass().getMethod ("getActionBar"); - } - catch (SecurityException e) { return; } - catch (NoSuchMethodException e) { return; } - if (getActionBarMethod == null) return; - - // invoke "getActionBar" method - Object actionBar = null; - try - { - actionBar = getActionBarMethod.invoke (this); - } - catch (java.lang.IllegalArgumentException e) { return; } - catch (java.lang.IllegalAccessException e) { return; } - catch (java.lang.reflect.InvocationTargetException e) { return; } - if (actionBar == null) return; - - // get "hide" method - java.lang.reflect.Method actionBarHideMethod = null; - try - { - actionBarHideMethod = actionBar.getClass().getMethod ("hide"); - } - catch (SecurityException e) { return; } - catch (NoSuchMethodException e) { return; } - if (actionBarHideMethod == null) return; - - // invoke "hide" method - try - { - actionBarHideMethod.invoke (actionBar); - } - catch (java.lang.IllegalArgumentException e) {} - catch (java.lang.IllegalAccessException e) {} - catch (java.lang.reflect.InvocationTargetException e) {} - } - - void requestPermissionsCompat (String[] permissions, int requestCode) - { - Method requestPermissionsMethod = null; - try - { - requestPermissionsMethod = this.getClass().getMethod ("requestPermissions", - String[].class, int.class); - } - catch (SecurityException e) { return; } - catch (NoSuchMethodException e) { return; } - if (requestPermissionsMethod == null) return; - - try - { - requestPermissionsMethod.invoke (this, permissions, requestCode); - } - catch (java.lang.IllegalArgumentException e) {} - catch (java.lang.IllegalAccessException e) {} - catch (java.lang.reflect.InvocationTargetException e) {} - } - - //============================================================================== - private native void launchApp (String appFile, String appDataDir); - private native void quitApp(); - private native void suspendApp(); - private native void resumeApp(); - private native void setScreenSize (int screenWidth, int screenHeight, int dpi); - private native void appActivityResult (int requestCode, int resultCode, Intent data); - private native void appNewIntent (Intent intent); - - //============================================================================== - private ViewHolder viewHolder; - private MidiDeviceManager midiDeviceManager = null; - private BluetoothManager bluetoothManager = null; - private boolean isScreenSaverEnabled; - private java.util.Timer keepAliveTimer; - - public final ComponentPeerView createNewView (boolean opaque, long host) - { - ComponentPeerView v = new ComponentPeerView (this, opaque, host); - viewHolder.addView (v); - addAppPausedResumedListener (v, host); - return v; - } - - public final void deleteView (ComponentPeerView view) - { - removeAppPausedResumedListener (view, view.host); - - view.host = 0; - - ViewGroup group = (ViewGroup) (view.getParent()); - - if (group != null) - group.removeView (view); - } - - public final void deleteNativeSurfaceView (NativeSurfaceView view) - { - ViewGroup group = (ViewGroup) (view.getParent()); - - if (group != null) - group.removeView (view); - } - - final class ViewHolder extends ViewGroup - { - public ViewHolder (Context context) - { - super (context); - setDescendantFocusability (ViewGroup.FOCUS_AFTER_DESCENDANTS); - setFocusable (false); - } - - protected final void onLayout (boolean changed, int left, int top, int right, int bottom) - { - setScreenSize (getWidth(), getHeight(), getDPI()); - - if (isFirstResize) - { - isFirstResize = false; - callAppLauncher(); - } - } - - private final int getDPI() - { - DisplayMetrics metrics = new DisplayMetrics(); - getWindowManager().getDefaultDisplay().getMetrics (metrics); - return metrics.densityDpi; - } - - private boolean isFirstResize = true; - } - - public final void excludeClipRegion (android.graphics.Canvas canvas, float left, float top, float right, float bottom) - { - canvas.clipRect (left, top, right, bottom, android.graphics.Region.Op.DIFFERENCE); - } - - //============================================================================== - public final void setScreenSaver (boolean enabled) - { - if (isScreenSaverEnabled != enabled) - { - isScreenSaverEnabled = enabled; - - if (keepAliveTimer != null) - { - keepAliveTimer.cancel(); - keepAliveTimer = null; - } - - if (enabled) - { - getWindow().clearFlags (WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); - } - else - { - getWindow().addFlags (WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); - - // If no user input is received after about 3 seconds, the OS will lower the - // task's priority, so this timer forces it to be kept active. - keepAliveTimer = new java.util.Timer(); - - keepAliveTimer.scheduleAtFixedRate (new TimerTask() - { - @Override - public void run() - { - android.app.Instrumentation instrumentation = new android.app.Instrumentation(); - - try - { - instrumentation.sendKeyDownUpSync (KeyEvent.KEYCODE_UNKNOWN); - } - catch (Exception e) - { - } - } - }, 2000, 2000); - } - } - } - - public final boolean getScreenSaver() - { - return isScreenSaverEnabled; - } - - //============================================================================== - public final String getClipboardContent() - { - ClipboardManager clipboard = (ClipboardManager) getSystemService (CLIPBOARD_SERVICE); - - CharSequence content = clipboard.getText(); - return content != null ? content.toString() : new String(); - } - - public final void setClipboardContent (String newText) - { - ClipboardManager clipboard = (ClipboardManager) getSystemService (CLIPBOARD_SERVICE); - clipboard.setText (newText); - } - - //============================================================================== - public final void showMessageBox (String title, String message, final long callback) - { - AlertDialog.Builder builder = new AlertDialog.Builder (this); - builder.setTitle (title) - .setMessage (message) - .setCancelable (true) - .setOnCancelListener (new DialogInterface.OnCancelListener() - { - public void onCancel (DialogInterface dialog) - { - JUCENetworkGraphicsDemo.this.alertDismissed (callback, 0); - } - }) - .setPositiveButton ("OK", new DialogInterface.OnClickListener() - { - public void onClick (DialogInterface dialog, int id) - { - dialog.dismiss(); - JUCENetworkGraphicsDemo.this.alertDismissed (callback, 0); - } - }); - - builder.create().show(); - } - - public final void showOkCancelBox (String title, String message, final long callback, - String okButtonText, String cancelButtonText) - { - AlertDialog.Builder builder = new AlertDialog.Builder (this); - builder.setTitle (title) - .setMessage (message) - .setCancelable (true) - .setOnCancelListener (new DialogInterface.OnCancelListener() - { - public void onCancel (DialogInterface dialog) - { - JUCENetworkGraphicsDemo.this.alertDismissed (callback, 0); - } - }) - .setPositiveButton (okButtonText.isEmpty() ? "OK" : okButtonText, new DialogInterface.OnClickListener() - { - public void onClick (DialogInterface dialog, int id) - { - dialog.dismiss(); - JUCENetworkGraphicsDemo.this.alertDismissed (callback, 1); - } - }) - .setNegativeButton (cancelButtonText.isEmpty() ? "Cancel" : cancelButtonText, new DialogInterface.OnClickListener() - { - public void onClick (DialogInterface dialog, int id) - { - dialog.dismiss(); - JUCENetworkGraphicsDemo.this.alertDismissed (callback, 0); - } - }); - - builder.create().show(); - } - - public final void showYesNoCancelBox (String title, String message, final long callback) - { - AlertDialog.Builder builder = new AlertDialog.Builder (this); - builder.setTitle (title) - .setMessage (message) - .setCancelable (true) - .setOnCancelListener (new DialogInterface.OnCancelListener() - { - public void onCancel (DialogInterface dialog) - { - JUCENetworkGraphicsDemo.this.alertDismissed (callback, 0); - } - }) - .setPositiveButton ("Yes", new DialogInterface.OnClickListener() - { - public void onClick (DialogInterface dialog, int id) - { - dialog.dismiss(); - JUCENetworkGraphicsDemo.this.alertDismissed (callback, 1); - } - }) - .setNegativeButton ("No", new DialogInterface.OnClickListener() - { - public void onClick (DialogInterface dialog, int id) - { - dialog.dismiss(); - JUCENetworkGraphicsDemo.this.alertDismissed (callback, 2); - } - }) - .setNeutralButton ("Cancel", new DialogInterface.OnClickListener() - { - public void onClick (DialogInterface dialog, int id) - { - dialog.dismiss(); - JUCENetworkGraphicsDemo.this.alertDismissed (callback, 0); - } - }); - - builder.create().show(); - } - - public native void alertDismissed (long callback, int id); - - //============================================================================== - public interface AppPausedResumedListener - { - void appPaused(); - void appResumed(); - } - - private Map<Long, AppPausedResumedListener> appPausedResumedListeners; - - public void addAppPausedResumedListener (AppPausedResumedListener l, long listenerHost) - { - appPausedResumedListeners.put (new Long (listenerHost), l); - } - - public void removeAppPausedResumedListener (AppPausedResumedListener l, long listenerHost) - { - appPausedResumedListeners.remove (new Long (listenerHost)); - } - - //============================================================================== - public final class ComponentPeerView extends ViewGroup - implements View.OnFocusChangeListener, AppPausedResumedListener - { - public ComponentPeerView (Context context, boolean opaque_, long host) - { - super (context); - this.host = host; - setWillNotDraw (false); - opaque = opaque_; - - setFocusable (true); - setFocusableInTouchMode (true); - setOnFocusChangeListener (this); - - // swap red and blue colours to match internal opengl texture format - ColorMatrix colorMatrix = new ColorMatrix(); - - float[] colorTransform = { 0, 0, 1.0f, 0, 0, - 0, 1.0f, 0, 0, 0, - 1.0f, 0, 0, 0, 0, - 0, 0, 0, 1.0f, 0 }; - - colorMatrix.set (colorTransform); - paint.setColorFilter (new ColorMatrixColorFilter (colorMatrix)); - - java.lang.reflect.Method method = null; - - try - { - method = getClass().getMethod ("setLayerType", int.class, Paint.class); - } - catch (SecurityException e) {} - catch (NoSuchMethodException e) {} - - if (method != null) - { - try - { - int layerTypeNone = 0; - method.invoke (this, layerTypeNone, null); - } - catch (java.lang.IllegalArgumentException e) {} - catch (java.lang.IllegalAccessException e) {} - catch (java.lang.reflect.InvocationTargetException e) {} - } - } - - //============================================================================== - private native void handlePaint (long host, Canvas canvas, Paint paint); - - @Override - public void onDraw (Canvas canvas) - { - if (host == 0) - return; - - handlePaint (host, canvas, paint); - } - - @Override - public boolean isOpaque() - { - return opaque; - } - - private boolean opaque; - private long host; - private Paint paint = new Paint(); - - //============================================================================== - private native void handleMouseDown (long host, int index, float x, float y, long time); - private native void handleMouseDrag (long host, int index, float x, float y, long time); - private native void handleMouseUp (long host, int index, float x, float y, long time); - - @Override - public boolean onTouchEvent (MotionEvent event) - { - if (host == 0) - return false; - - int action = event.getAction(); - long time = event.getEventTime(); - - switch (action & MotionEvent.ACTION_MASK) - { - case MotionEvent.ACTION_DOWN: - handleMouseDown (host, event.getPointerId(0), event.getX(), event.getY(), time); - return true; - - case MotionEvent.ACTION_CANCEL: - case MotionEvent.ACTION_UP: - handleMouseUp (host, event.getPointerId(0), event.getX(), event.getY(), time); - return true; - - case MotionEvent.ACTION_MOVE: - { - int n = event.getPointerCount(); - for (int i = 0; i < n; ++i) - handleMouseDrag (host, event.getPointerId(i), event.getX(i), event.getY(i), time); - - return true; - } - - case MotionEvent.ACTION_POINTER_UP: - { - int i = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; - handleMouseUp (host, event.getPointerId(i), event.getX(i), event.getY(i), time); - return true; - } - - case MotionEvent.ACTION_POINTER_DOWN: - { - int i = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; - handleMouseDown (host, event.getPointerId(i), event.getX(i), event.getY(i), time); - return true; - } - - default: - break; - } - - return false; - } - - //============================================================================== - private native void handleKeyDown (long host, int keycode, int textchar); - private native void handleKeyUp (long host, int keycode, int textchar); - private native void handleBackButton (long host); - private native void handleKeyboardHidden (long host); - - public void showKeyboard (String type) - { - InputMethodManager imm = (InputMethodManager) getSystemService (Context.INPUT_METHOD_SERVICE); - - if (imm != null) - { - if (type.length() > 0) - { - imm.showSoftInput (this, android.view.inputmethod.InputMethodManager.SHOW_IMPLICIT); - imm.setInputMethod (getWindowToken(), type); - keyboardDismissListener.startListening(); - } - else - { - imm.hideSoftInputFromWindow (getWindowToken(), 0); - keyboardDismissListener.stopListening(); - } - } - } - - public void backButtonPressed() - { - if (host == 0) - return; - - handleBackButton (host); - } - - @Override - public boolean onKeyDown (int keyCode, KeyEvent event) - { - if (host == 0) - return false; - - switch (keyCode) - { - case KeyEvent.KEYCODE_VOLUME_UP: - case KeyEvent.KEYCODE_VOLUME_DOWN: - return super.onKeyDown (keyCode, event); - case KeyEvent.KEYCODE_BACK: - { - ((Activity) getContext()).onBackPressed(); - return true; - } - - default: - break; - } - - handleKeyDown (host, keyCode, event.getUnicodeChar()); - return true; - } - - @Override - public boolean onKeyUp (int keyCode, KeyEvent event) - { - if (host == 0) - return false; - - handleKeyUp (host, keyCode, event.getUnicodeChar()); - return true; - } - - @Override - public boolean onKeyMultiple (int keyCode, int count, KeyEvent event) - { - if (host == 0) - return false; - - if (keyCode != KeyEvent.KEYCODE_UNKNOWN || event.getAction() != KeyEvent.ACTION_MULTIPLE) - return super.onKeyMultiple (keyCode, count, event); - - if (event.getCharacters() != null) - { - int utf8Char = event.getCharacters().codePointAt (0); - handleKeyDown (host, utf8Char, utf8Char); - return true; - } - - return false; - } - - //============================================================================== - private final class KeyboardDismissListener - { - public KeyboardDismissListener (ComponentPeerView viewToUse) - { - view = viewToUse; - } - - private void startListening() - { - view.getViewTreeObserver().addOnGlobalLayoutListener(viewTreeObserver); - } - - private void stopListening() - { - view.getViewTreeObserver().removeGlobalOnLayoutListener(viewTreeObserver); - } - - private class TreeObserver implements ViewTreeObserver.OnGlobalLayoutListener - { - TreeObserver() - { - keyboardShown = false; - } - - @Override - public void onGlobalLayout() - { - Rect r = new Rect(); - - ViewGroup parentView = (ViewGroup) getParent(); - - if (parentView == null) - return; - - parentView.getWindowVisibleDisplayFrame (r); - - int diff = parentView.getHeight() - (r.bottom - r.top); - - // Arbitrary threshold, surely keyboard would take more than 20 pix. - if (diff < 20 && keyboardShown) - { - keyboardShown = false; - handleKeyboardHidden (view.host); - } - - if (! keyboardShown && diff > 20) - keyboardShown = true; - }; - - private boolean keyboardShown; - }; - - private ComponentPeerView view; - private TreeObserver viewTreeObserver = new TreeObserver(); - } - - private KeyboardDismissListener keyboardDismissListener = new KeyboardDismissListener(this); - - // this is here to make keyboard entry work on a Galaxy Tab2 10.1 - @Override - public InputConnection onCreateInputConnection (EditorInfo outAttrs) - { - outAttrs.actionLabel = ""; - outAttrs.hintText = ""; - outAttrs.initialCapsMode = 0; - outAttrs.initialSelEnd = outAttrs.initialSelStart = -1; - outAttrs.label = ""; - outAttrs.imeOptions = EditorInfo.IME_ACTION_DONE | EditorInfo.IME_FLAG_NO_EXTRACT_UI; - outAttrs.inputType = InputType.TYPE_NULL; - - return new BaseInputConnection (this, false); - } - - //============================================================================== - @Override - protected void onSizeChanged (int w, int h, int oldw, int oldh) - { - if (host == 0) - return; - - super.onSizeChanged (w, h, oldw, oldh); - viewSizeChanged (host); - } - - @Override - protected void onLayout (boolean changed, int left, int top, int right, int bottom) - { - for (int i = getChildCount(); --i >= 0;) - requestTransparentRegion (getChildAt (i)); - } - - private native void viewSizeChanged (long host); - - @Override - public void onFocusChange (View v, boolean hasFocus) - { - if (host == 0) - return; - - if (v == this) - focusChanged (host, hasFocus); - } - - private native void focusChanged (long host, boolean hasFocus); - - public void setViewName (String newName) {} - - public void setSystemUiVisibilityCompat (int visibility) - { - Method systemUIVisibilityMethod = null; - try - { - systemUIVisibilityMethod = this.getClass().getMethod ("setSystemUiVisibility", int.class); - } - catch (SecurityException e) { return; } - catch (NoSuchMethodException e) { return; } - if (systemUIVisibilityMethod == null) return; - - try - { - systemUIVisibilityMethod.invoke (this, visibility); - } - catch (java.lang.IllegalArgumentException e) {} - catch (java.lang.IllegalAccessException e) {} - catch (java.lang.reflect.InvocationTargetException e) {} - } - - public boolean isVisible() { return getVisibility() == VISIBLE; } - public void setVisible (boolean b) { setVisibility (b ? VISIBLE : INVISIBLE); } - - public boolean containsPoint (int x, int y) - { - return true; //xxx needs to check overlapping views - } - - //============================================================================== - private native void handleAppPaused (long host); - private native void handleAppResumed (long host); - - @Override - public void appPaused() - { - if (host == 0) - return; - - handleAppPaused (host); - } - - @Override - public void appResumed() - { - if (host == 0) - return; - - // Ensure that navigation/status bar visibility is correctly restored. - handleAppResumed (host); - } - } - - //============================================================================== - public static class NativeSurfaceView extends SurfaceView - implements SurfaceHolder.Callback - { - private long nativeContext = 0; - private boolean forVideo; - - NativeSurfaceView (Context context, long nativeContextPtr, boolean createdForVideo) - { - super (context); - nativeContext = nativeContextPtr; - forVideo = createdForVideo; - } - - public Surface getNativeSurface() - { - Surface retval = null; - - SurfaceHolder holder = getHolder(); - if (holder != null) - retval = holder.getSurface(); - - return retval; - } - - //============================================================================== - @Override - public void surfaceChanged (SurfaceHolder holder, int format, int width, int height) - { - if (forVideo) - surfaceChangedNativeVideo (nativeContext, holder, format, width, height); - else - surfaceChangedNative (nativeContext, holder, format, width, height); - } - - @Override - public void surfaceCreated (SurfaceHolder holder) - { - if (forVideo) - surfaceCreatedNativeVideo (nativeContext, holder); - else - surfaceCreatedNative (nativeContext, holder); - } - - @Override - public void surfaceDestroyed (SurfaceHolder holder) - { - if (forVideo) - surfaceDestroyedNativeVideo (nativeContext, holder); - else - surfaceDestroyedNative (nativeContext, holder); - } - - @Override - protected void dispatchDraw (Canvas canvas) - { - super.dispatchDraw (canvas); - - if (forVideo) - dispatchDrawNativeVideo (nativeContext, canvas); - else - dispatchDrawNative (nativeContext, canvas); - } - - //============================================================================== - @Override - protected void onAttachedToWindow() - { - super.onAttachedToWindow(); - getHolder().addCallback (this); - } - - @Override - protected void onDetachedFromWindow() - { - super.onDetachedFromWindow(); - getHolder().removeCallback (this); - } - - //============================================================================== - private native void dispatchDrawNative (long nativeContextPtr, Canvas canvas); - private native void surfaceCreatedNative (long nativeContextptr, SurfaceHolder holder); - private native void surfaceDestroyedNative (long nativeContextptr, SurfaceHolder holder); - private native void surfaceChangedNative (long nativeContextptr, SurfaceHolder holder, - int format, int width, int height); - - private native void dispatchDrawNativeVideo (long nativeContextPtr, Canvas canvas); - private native void surfaceCreatedNativeVideo (long nativeContextptr, SurfaceHolder holder); - private native void surfaceDestroyedNativeVideo (long nativeContextptr, SurfaceHolder holder); - private native void surfaceChangedNativeVideo (long nativeContextptr, SurfaceHolder holder, - int format, int width, int height); - } - - public NativeSurfaceView createNativeSurfaceView (long nativeSurfacePtr, boolean forVideo) - { - return new NativeSurfaceView (this, nativeSurfacePtr, forVideo); - } - - //============================================================================== - public final int[] renderGlyph (char glyph1, char glyph2, Paint paint, android.graphics.Matrix matrix, Rect bounds) - { - Path p = new Path(); - - char[] str = { glyph1, glyph2 }; - paint.getTextPath (str, 0, (glyph2 != 0 ? 2 : 1), 0.0f, 0.0f, p); - - RectF boundsF = new RectF(); - p.computeBounds (boundsF, true); - matrix.mapRect (boundsF); - - boundsF.roundOut (bounds); - bounds.left--; - bounds.right++; - - final int w = bounds.width(); - final int h = Math.max (1, bounds.height()); - - Bitmap bm = Bitmap.createBitmap (w, h, Bitmap.Config.ARGB_8888); - - Canvas c = new Canvas (bm); - matrix.postTranslate (-bounds.left, -bounds.top); - c.setMatrix (matrix); - c.drawPath (p, paint); - - final int sizeNeeded = w * h; - if (cachedRenderArray.length < sizeNeeded) - cachedRenderArray = new int [sizeNeeded]; - - bm.getPixels (cachedRenderArray, 0, w, 0, 0, w, h); - bm.recycle(); - return cachedRenderArray; - } - - private int[] cachedRenderArray = new int [256]; - - //============================================================================== - public static class NativeInvocationHandler implements InvocationHandler - { - public NativeInvocationHandler (Activity activityToUse, long nativeContextRef) - { - activity = activityToUse; - nativeContext = nativeContextRef; - } - - public void nativeContextDeleted() - { - nativeContext = 0; - } - - @Override - public void finalize() - { - activity.runOnUiThread (new Runnable() - { - @Override - public void run() - { - if (nativeContext != 0) - dispatchFinalize (nativeContext); - } - }); - } - - @Override - public Object invoke (Object proxy, Method method, Object[] args) throws Throwable - { - return dispatchInvoke (nativeContext, proxy, method, args); - } - - //============================================================================== - Activity activity; - private long nativeContext = 0; - - private native void dispatchFinalize (long nativeContextRef); - private native Object dispatchInvoke (long nativeContextRef, Object proxy, Method method, Object[] args); - } - - public InvocationHandler createInvocationHandler (long nativeContextRef) - { - return new NativeInvocationHandler (this, nativeContextRef); - } - - public void invocationHandlerContextDeleted (InvocationHandler handler) - { - ((NativeInvocationHandler) handler).nativeContextDeleted(); - } - - //============================================================================== - public static class HTTPStream - { - public HTTPStream (String address, boolean isPostToUse, byte[] postDataToUse, - String headersToUse, int timeOutMsToUse, - int[] statusCodeToUse, StringBuffer responseHeadersToUse, - int numRedirectsToFollowToUse, String httpRequestCmdToUse) throws IOException - { - isPost = isPostToUse; - postData = postDataToUse; - headers = headersToUse; - timeOutMs = timeOutMsToUse; - statusCode = statusCodeToUse; - responseHeaders = responseHeadersToUse; - totalLength = -1; - numRedirectsToFollow = numRedirectsToFollowToUse; - httpRequestCmd = httpRequestCmdToUse; - - connection = createConnection (address, isPost, postData, headers, timeOutMs, httpRequestCmd); - } - - private final HttpURLConnection createConnection (String address, boolean isPost, byte[] postData, - String headers, int timeOutMs, String httpRequestCmdToUse) throws IOException - { - HttpURLConnection newConnection = (HttpURLConnection) (new URL(address).openConnection()); - - try - { - newConnection.setInstanceFollowRedirects (false); - newConnection.setConnectTimeout (timeOutMs); - newConnection.setReadTimeout (timeOutMs); - - // headers - if not empty, this string is appended onto the headers that are used for the request. It must therefore be a valid set of HTML header directives, separated by newlines. - // So convert headers string to an array, with an element for each line - String headerLines[] = headers.split("\\n"); - - // Set request headers - for (int i = 0; i < headerLines.length; ++i) - { - int pos = headerLines[i].indexOf (":"); - - if (pos > 0 && pos < headerLines[i].length()) - { - String field = headerLines[i].substring (0, pos); - String value = headerLines[i].substring (pos + 1); - - if (value.length() > 0) - newConnection.setRequestProperty (field, value); - } - } - - newConnection.setRequestMethod (httpRequestCmd); - - if (isPost) - { - newConnection.setDoOutput (true); - - if (postData != null) - { - OutputStream out = newConnection.getOutputStream(); - out.write(postData); - out.flush(); - } - } - - return newConnection; - } - catch (Throwable e) - { - newConnection.disconnect(); - throw new IOException ("Connection error"); - } - } - - private final InputStream getCancellableStream (final boolean isInput) throws ExecutionException - { - synchronized (createFutureLock) - { - if (hasBeenCancelled.get()) - return null; - - streamFuture = executor.submit (new Callable<BufferedInputStream>() - { - @Override - public BufferedInputStream call() throws IOException - { - return new BufferedInputStream (isInput ? connection.getInputStream() - : connection.getErrorStream()); - } - }); - } - - try - { - return streamFuture.get(); - } - catch (InterruptedException e) - { - return null; - } - catch (CancellationException e) - { - return null; - } - } - - public final boolean connect() - { - boolean result = false; - int numFollowedRedirects = 0; - - while (true) - { - result = doConnect(); - - if (! result) - return false; - - if (++numFollowedRedirects > numRedirectsToFollow) - break; - - int status = statusCode[0]; - - if (status == 301 || status == 302 || status == 303 || status == 307) - { - // Assumes only one occurrence of "Location" - int pos1 = responseHeaders.indexOf ("Location:") + 10; - int pos2 = responseHeaders.indexOf ("\n", pos1); - - if (pos2 > pos1) - { - String currentLocation = connection.getURL().toString(); - String newLocation = responseHeaders.substring (pos1, pos2); - - try - { - // Handle newLocation whether it's absolute or relative - URL baseUrl = new URL (currentLocation); - URL newUrl = new URL (baseUrl, newLocation); - String transformedNewLocation = newUrl.toString(); - - if (transformedNewLocation != currentLocation) - { - // Clear responseHeaders before next iteration - responseHeaders.delete (0, responseHeaders.length()); - - synchronized (createStreamLock) - { - if (hasBeenCancelled.get()) - return false; - - connection.disconnect(); - - try - { - connection = createConnection (transformedNewLocation, isPost, - postData, headers, timeOutMs, - httpRequestCmd); - } - catch (Throwable e) - { - return false; - } - } - } - else - { - break; - } - } - catch (Throwable e) - { - return false; - } - } - else - { - break; - } - } - else - { - break; - } - } - - return result; - } - - private final boolean doConnect() - { - synchronized (createStreamLock) - { - if (hasBeenCancelled.get()) - return false; - - try - { - try - { - inputStream = getCancellableStream (true); - } - catch (ExecutionException e) - { - if (connection.getResponseCode() < 400) - { - statusCode[0] = connection.getResponseCode(); - connection.disconnect(); - return false; - } - } - finally - { - statusCode[0] = connection.getResponseCode(); - } - - try - { - if (statusCode[0] >= 400) - inputStream = getCancellableStream (false); - else - inputStream = getCancellableStream (true); - } - catch (ExecutionException e) - {} - - for (java.util.Map.Entry<String, java.util.List<String>> entry : connection.getHeaderFields().entrySet()) - { - if (entry.getKey() != null && entry.getValue() != null) - { - responseHeaders.append(entry.getKey() + ": " - + android.text.TextUtils.join(",", entry.getValue()) + "\n"); - - if (entry.getKey().compareTo ("Content-Length") == 0) - totalLength = Integer.decode (entry.getValue().get (0)); - } - } - - return true; - } - catch (IOException e) - { - return false; - } - } - } - - static class DisconnectionRunnable implements Runnable - { - public DisconnectionRunnable (HttpURLConnection theConnection, - InputStream theInputStream, - ReentrantLock theCreateStreamLock, - Object theCreateFutureLock, - Future<BufferedInputStream> theStreamFuture) - { - connectionToDisconnect = theConnection; - inputStream = theInputStream; - createStreamLock = theCreateStreamLock; - createFutureLock = theCreateFutureLock; - streamFuture = theStreamFuture; - } - - public void run() - { - try - { - if (! createStreamLock.tryLock()) - { - synchronized (createFutureLock) - { - if (streamFuture != null) - streamFuture.cancel (true); - } - - createStreamLock.lock(); - } - - if (connectionToDisconnect != null) - connectionToDisconnect.disconnect(); - - if (inputStream != null) - inputStream.close(); - } - catch (IOException e) - {} - finally - { - createStreamLock.unlock(); - } - } - - private HttpURLConnection connectionToDisconnect; - private InputStream inputStream; - private ReentrantLock createStreamLock; - private Object createFutureLock; - Future<BufferedInputStream> streamFuture; - } - - public final void release() - { - DisconnectionRunnable disconnectionRunnable = new DisconnectionRunnable (connection, - inputStream, - createStreamLock, - createFutureLock, - streamFuture); - - synchronized (createStreamLock) - { - hasBeenCancelled.set (true); - - connection = null; - } - - Thread disconnectionThread = new Thread(disconnectionRunnable); - disconnectionThread.start(); - } - - public final int read (byte[] buffer, int numBytes) - { - int num = 0; - - try - { - synchronized (createStreamLock) - { - if (inputStream != null) - num = inputStream.read (buffer, 0, numBytes); - } - } - catch (IOException e) - {} - - if (num > 0) - position += num; - - return num; - } - - public final long getPosition() { return position; } - public final long getTotalLength() { return totalLength; } - public final boolean isExhausted() { return false; } - public final boolean setPosition (long newPos) { return false; } - - private boolean isPost; - private byte[] postData; - private String headers; - private int timeOutMs; - String httpRequestCmd; - private HttpURLConnection connection; - private int[] statusCode; - private StringBuffer responseHeaders; - private int totalLength; - private int numRedirectsToFollow; - private InputStream inputStream; - private long position; - private final ReentrantLock createStreamLock = new ReentrantLock(); - private final Object createFutureLock = new Object(); - private AtomicBoolean hasBeenCancelled = new AtomicBoolean(); - - private final ExecutorService executor = Executors.newCachedThreadPool (Executors.defaultThreadFactory()); - Future<BufferedInputStream> streamFuture; - } - - public static final HTTPStream createHTTPStream (String address, boolean isPost, byte[] postData, - String headers, int timeOutMs, int[] statusCode, - StringBuffer responseHeaders, int numRedirectsToFollow, - String httpRequestCmd) - { - // timeout parameter of zero for HttpUrlConnection is a blocking connect (negative value for juce::URL) - if (timeOutMs < 0) - timeOutMs = 0; - else if (timeOutMs == 0) - timeOutMs = 30000; - - for (;;) - { - try - { - HTTPStream httpStream = new HTTPStream (address, isPost, postData, headers, - timeOutMs, statusCode, responseHeaders, - numRedirectsToFollow, httpRequestCmd); - - return httpStream; - } - catch (Throwable e) {} - - return null; - } - } - - public final void launchURL (String url) - { - startActivity (new Intent (Intent.ACTION_VIEW, Uri.parse (url))); - } - - private native boolean webViewPageLoadStarted (long host, WebView view, String url); - private native void webViewPageLoadFinished (long host, WebView view, String url); - private native void webViewReceivedSslError (long host, WebView view, SslErrorHandler handler, SslError error); - private native void webViewCloseWindowRequest (long host, WebView view); - private native void webViewCreateWindowRequest (long host, WebView view); - - //============================================================================== - public class JuceWebViewClient extends WebViewClient - { - public JuceWebViewClient (long hostToUse) - { - host = hostToUse; - } - - public void hostDeleted() - { - synchronized (hostLock) - { - host = 0; - } - } - - @Override - public void onPageFinished (WebView view, String url) - { - if (host == 0) - return; - - webViewPageLoadFinished (host, view, url); - } - - @Override - public void onReceivedSslError (WebView view, SslErrorHandler handler, SslError error) - { - if (host == 0) - return; - - webViewReceivedSslError (host, view, handler, error); - } - - @Override - public void onPageStarted (WebView view, String url, Bitmap favicon) - { - if (host != 0) - webViewPageLoadStarted (host, view, url); - } - - private long host; - private final Object hostLock = new Object(); - } - - public class JuceWebChromeClient extends WebChromeClient - { - public JuceWebChromeClient (long hostToUse) - { - host = hostToUse; - } - - @Override - public void onCloseWindow (WebView window) - { - webViewCloseWindowRequest (host, window); - } - - @Override - public boolean onCreateWindow (WebView view, boolean isDialog, - boolean isUserGesture, Message resultMsg) - { - webViewCreateWindowRequest (host, view); - return false; - } - - private long host; - private final Object hostLock = new Object(); - } - - - //============================================================================== - public static final String getLocaleValue (boolean isRegion) - { - java.util.Locale locale = java.util.Locale.getDefault(); - - return isRegion ? locale.getCountry() - : locale.getLanguage(); - } - - private static final String getFileLocation (String type) - { - return Environment.getExternalStoragePublicDirectory (type).getAbsolutePath(); - } - - public static final String getDocumentsFolder() - { - if (getAndroidSDKVersion() >= 19) - return getFileLocation ("Documents"); - - return Environment.getDataDirectory().getAbsolutePath(); - } - - public static final String getPicturesFolder() { return getFileLocation (Environment.DIRECTORY_PICTURES); } - public static final String getMusicFolder() { return getFileLocation (Environment.DIRECTORY_MUSIC); } - public static final String getMoviesFolder() { return getFileLocation (Environment.DIRECTORY_MOVIES); } - public static final String getDownloadsFolder() { return getFileLocation (Environment.DIRECTORY_DOWNLOADS); } - - //============================================================================== - @Override - protected void onActivityResult (int requestCode, int resultCode, Intent data) - { - appActivityResult (requestCode, resultCode, data); - } - - @Override - protected void onNewIntent (Intent intent) - { - super.onNewIntent(intent); - setIntent(intent); - - appNewIntent (intent); - } - - //============================================================================== - public final Typeface getTypeFaceFromAsset (String assetName) - { - try - { - return Typeface.createFromAsset (this.getResources().getAssets(), assetName); - } - catch (Throwable e) {} - - return null; - } - - final protected static char[] hexArray = "0123456789ABCDEF".toCharArray(); - - public static String bytesToHex (byte[] bytes) - { - char[] hexChars = new char[bytes.length * 2]; - - for (int j = 0; j < bytes.length; ++j) - { - int v = bytes[j] & 0xff; - hexChars[j * 2] = hexArray[v >>> 4]; - hexChars[j * 2 + 1] = hexArray[v & 0x0f]; - } - - return new String (hexChars); - } - - final private java.util.Map dataCache = new java.util.HashMap(); - - synchronized private final File getDataCacheFile (byte[] data) - { - try - { - java.security.MessageDigest digest = java.security.MessageDigest.getInstance ("MD5"); - digest.update (data); - - String key = bytesToHex (digest.digest()); - - if (dataCache.containsKey (key)) - return (File) dataCache.get (key); - - File f = new File (this.getCacheDir(), "bindata_" + key); - f.delete(); - FileOutputStream os = new FileOutputStream (f); - os.write (data, 0, data.length); - dataCache.put (key, f); - return f; - } - catch (Throwable e) {} - - return null; - } - - private final void clearDataCache() - { - java.util.Iterator it = dataCache.values().iterator(); - - while (it.hasNext()) - { - File f = (File) it.next(); - f.delete(); - } - } - - public final Typeface getTypeFaceFromByteArray (byte[] data) - { - try - { - File f = getDataCacheFile (data); - - if (f != null) - return Typeface.createFromFile (f); - } - catch (Exception e) - { - Log.e ("JUCE", e.toString()); - } - - return null; - } - - public static final int getAndroidSDKVersion() - { - return android.os.Build.VERSION.SDK_INT; - } - - public final String audioManagerGetProperty (String property) - { - Object obj = getSystemService (AUDIO_SERVICE); - if (obj == null) - return null; - - java.lang.reflect.Method method; - - try - { - method = obj.getClass().getMethod ("getProperty", String.class); - } - catch (SecurityException e) { return null; } - catch (NoSuchMethodException e) { return null; } - - if (method == null) - return null; - - try - { - return (String) method.invoke (obj, property); - } - catch (java.lang.IllegalArgumentException e) {} - catch (java.lang.IllegalAccessException e) {} - catch (java.lang.reflect.InvocationTargetException e) {} - - return null; - } - - public final boolean hasSystemFeature (String property) - { - return getPackageManager().hasSystemFeature (property); - } -} diff --git a/extras/NetworkGraphicsDemo/Builds/Android/app/src/main/java/com/juce/networkgraphicsdemo/SharingContentProvider.java b/extras/NetworkGraphicsDemo/Builds/Android/app/src/main/java/com/juce/networkgraphicsdemo/SharingContentProvider.java deleted file mode 100644 index 4112f21b..00000000 --- a/extras/NetworkGraphicsDemo/Builds/Android/app/src/main/java/com/juce/networkgraphicsdemo/SharingContentProvider.java +++ /dev/null @@ -1,129 +0,0 @@ -package com.juce.networkgraphicsdemo; - -import android.content.ContentProvider; -import android.content.ContentValues; -import android.content.res.AssetFileDescriptor; -import android.content.res.Resources; -import android.database.Cursor; -import android.database.MatrixCursor; -import android.net.Uri; -import android.os.FileObserver; -import android.os.ParcelFileDescriptor; -import java.lang.String; - -public final class SharingContentProvider extends ContentProvider -{ - private Object lock = new Object(); - - private native void contentSharerFileObserverEvent (long host, int event, String path); - - private native Cursor contentSharerQuery (Uri uri, String[] projection, String selection, - String[] selectionArgs, String sortOrder); - - private native void contentSharerCursorClosed (long host); - - private native AssetFileDescriptor contentSharerOpenFile (Uri uri, String mode); - private native String[] contentSharerGetStreamTypes (Uri uri, String mimeTypeFilter); - - public final class ProviderFileObserver extends FileObserver - { - public ProviderFileObserver (long hostToUse, String path, int mask) - { - super (path, mask); - - host = hostToUse; - } - - public void onEvent (int event, String path) - { - contentSharerFileObserverEvent (host, event, path); - } - - private long host; - } - - public final class ProviderCursor extends MatrixCursor - { - ProviderCursor (long hostToUse, String[] columnNames) - { - super (columnNames); - - host = hostToUse; - } - - @Override - public void close() - { - super.close(); - - contentSharerCursorClosed (host); - } - - private long host; - } - - @Override - public boolean onCreate() - { - return true; - } - - @Override - public Cursor query (Uri url, String[] projection, String selection, - String[] selectionArgs, String sortOrder) - { - synchronized (lock) - { - return contentSharerQuery (url, projection, selection, selectionArgs, sortOrder); - } - } - - @Override - public Uri insert (Uri uri, ContentValues values) - { - return null; - } - - @Override - public int update (Uri uri, ContentValues values, String selection, - String[] selectionArgs) - { - return 0; - } - - @Override - public int delete (Uri uri, String selection, String[] selectionArgs) - { - return 0; - } - - @Override - public String getType (Uri uri) - { - return null; - } - - @Override - public AssetFileDescriptor openAssetFile (Uri uri, String mode) - { - synchronized (lock) - { - return contentSharerOpenFile (uri, mode); - } - } - - @Override - public ParcelFileDescriptor openFile (Uri uri, String mode) - { - synchronized (lock) - { - AssetFileDescriptor result = contentSharerOpenFile (uri, mode); - - if (result != null) - return result.getParcelFileDescriptor(); - - return null; - } - } - -} diff --git a/extras/NetworkGraphicsDemo/Builds/Android/build.gradle b/extras/NetworkGraphicsDemo/Builds/Android/build.gradle index cfd3a2f8..0fe5b4aa 100644 --- a/extras/NetworkGraphicsDemo/Builds/Android/build.gradle +++ b/extras/NetworkGraphicsDemo/Builds/Android/build.gradle @@ -4,7 +4,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.5.3' + classpath 'com.android.tools.build:gradle:4.0.0' } } diff --git a/extras/NetworkGraphicsDemo/Builds/Android/gradle/wrapper/gradle-wrapper.properties b/extras/NetworkGraphicsDemo/Builds/Android/gradle/wrapper/gradle-wrapper.properties index b66802c7..49479605 100644 --- a/extras/NetworkGraphicsDemo/Builds/Android/gradle/wrapper/gradle-wrapper.properties +++ b/extras/NetworkGraphicsDemo/Builds/Android/gradle/wrapper/gradle-wrapper.properties @@ -1 +1 @@ -distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip \ No newline at end of file +distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip \ No newline at end of file diff --git a/extras/NetworkGraphicsDemo/Builds/LinuxMakefile/Makefile b/extras/NetworkGraphicsDemo/Builds/LinuxMakefile/Makefile index 18a67b54..0343013d 100644 --- a/extras/NetworkGraphicsDemo/Builds/LinuxMakefile/Makefile +++ b/extras/NetworkGraphicsDemo/Builds/LinuxMakefile/Makefile @@ -35,13 +35,13 @@ ifeq ($(CONFIG),Debug) TARGET_ARCH := endif - JUCE_CPPFLAGS := $(DEPFLAGS) -DLINUX=1 -DDEBUG=1 -D_DEBUG=1 -DJUCER_LINUX_MAKE_6D53C8B4=1 -DJUCE_APP_VERSION=1.0.0 -DJUCE_APP_VERSION_HEX=0x10000 $(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_CPPFLAGS := $(DEPFLAGS) "-DLINUX=1" "-DDEBUG=1" "-D_DEBUG=1" "-DJUCE_DISPLAY_SPLASH_SCREEN=0" "-DJUCE_USE_DARK_SPLASH_SCREEN=1" "-DJUCE_PROJUCER_VERSION=0x60005" "-DJUCE_MODULE_AVAILABLE_juce_audio_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_devices=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_formats=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_processors=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_utils=1" "-DJUCE_MODULE_AVAILABLE_juce_core=1" "-DJUCE_MODULE_AVAILABLE_juce_cryptography=1" "-DJUCE_MODULE_AVAILABLE_juce_data_structures=1" "-DJUCE_MODULE_AVAILABLE_juce_events=1" "-DJUCE_MODULE_AVAILABLE_juce_graphics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_extra=1" "-DJUCE_MODULE_AVAILABLE_juce_opengl=1" "-DJUCE_MODULE_AVAILABLE_juce_osc=1" "-DJUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1" "-DJUCE_STANDALONE_APPLICATION=1" "-DJUCER_LINUX_MAKE_6D53C8B4=1" "-DJUCE_APP_VERSION=1.0.0" "-DJUCE_APP_VERSION_HEX=0x10000" $(shell pkg-config --cflags alsa freetype2 libcurl 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 := JUCE\ Network\ Graphics\ Demo JUCE_CFLAGS += $(JUCE_CPPFLAGS) $(TARGET_ARCH) -g -ggdb -O0 $(CFLAGS) JUCE_CXXFLAGS += $(JUCE_CFLAGS) -std=c++14 $(CXXFLAGS) - JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) -L/usr/X11R6/lib/ $(shell pkg-config --libs alsa x11 xinerama xext freetype2 webkit2gtk-4.0 gtk+-x11-3.0 libcurl) -lrt -ldl -lpthread -lGL $(LDFLAGS) + JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) $(shell pkg-config --libs alsa freetype2 libcurl) -fvisibility=hidden -lrt -ldl -lpthread -lGL $(LDFLAGS) CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(TARGET) $(JUCE_OBJDIR) endif @@ -56,13 +56,13 @@ ifeq ($(CONFIG),Release) TARGET_ARCH := endif - JUCE_CPPFLAGS := $(DEPFLAGS) -DLINUX=1 -DNDEBUG=1 -DJUCER_LINUX_MAKE_6D53C8B4=1 -DJUCE_APP_VERSION=1.0.0 -DJUCE_APP_VERSION_HEX=0x10000 $(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_CPPFLAGS := $(DEPFLAGS) "-DLINUX=1" "-DNDEBUG=1" "-DJUCE_DISPLAY_SPLASH_SCREEN=0" "-DJUCE_USE_DARK_SPLASH_SCREEN=1" "-DJUCE_PROJUCER_VERSION=0x60005" "-DJUCE_MODULE_AVAILABLE_juce_audio_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_devices=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_formats=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_processors=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_utils=1" "-DJUCE_MODULE_AVAILABLE_juce_core=1" "-DJUCE_MODULE_AVAILABLE_juce_cryptography=1" "-DJUCE_MODULE_AVAILABLE_juce_data_structures=1" "-DJUCE_MODULE_AVAILABLE_juce_events=1" "-DJUCE_MODULE_AVAILABLE_juce_graphics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_extra=1" "-DJUCE_MODULE_AVAILABLE_juce_opengl=1" "-DJUCE_MODULE_AVAILABLE_juce_osc=1" "-DJUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1" "-DJUCE_STANDALONE_APPLICATION=1" "-DJUCER_LINUX_MAKE_6D53C8B4=1" "-DJUCE_APP_VERSION=1.0.0" "-DJUCE_APP_VERSION_HEX=0x10000" $(shell pkg-config --cflags alsa freetype2 libcurl 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 := JUCE\ Network\ Graphics\ Demo JUCE_CFLAGS += $(JUCE_CPPFLAGS) $(TARGET_ARCH) -O3 $(CFLAGS) JUCE_CXXFLAGS += $(JUCE_CFLAGS) -std=c++14 $(CXXFLAGS) - JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) -L/usr/X11R6/lib/ $(shell pkg-config --libs alsa x11 xinerama xext freetype2 webkit2gtk-4.0 gtk+-x11-3.0 libcurl) -fvisibility=hidden -lrt -ldl -lpthread -lGL $(LDFLAGS) + JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) $(shell pkg-config --libs alsa freetype2 libcurl) -fvisibility=hidden -lrt -ldl -lpthread -lGL $(LDFLAGS) CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(TARGET) $(JUCE_OBJDIR) endif @@ -91,7 +91,7 @@ all : $(JUCE_OUTDIR)/$(JUCE_TARGET_APP) $(JUCE_OUTDIR)/$(JUCE_TARGET_APP) : $(OBJECTS_APP) $(RESOURCES) @command -v pkg-config >/dev/null 2>&1 || { echo >&2 "pkg-config not installed. Please, install it."; exit 1; } - @pkg-config --print-errors alsa x11 xinerama xext freetype2 webkit2gtk-4.0 gtk+-x11-3.0 libcurl + @pkg-config --print-errors alsa freetype2 libcurl @echo Linking "NetworkGraphicsDemo - App" -$(V_AT)mkdir -p $(JUCE_BINDIR) -$(V_AT)mkdir -p $(JUCE_LIBDIR) diff --git a/extras/NetworkGraphicsDemo/Builds/MacOSX/App.entitlements b/extras/NetworkGraphicsDemo/Builds/MacOSX/App.entitlements deleted file mode 100644 index 6631ffa6..00000000 --- a/extras/NetworkGraphicsDemo/Builds/MacOSX/App.entitlements +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> -</dict> -</plist> diff --git a/extras/NetworkGraphicsDemo/Builds/MacOSX/Info-App.plist b/extras/NetworkGraphicsDemo/Builds/MacOSX/Info-App.plist index 94cfc076..7c2f3835 100644 --- a/extras/NetworkGraphicsDemo/Builds/MacOSX/Info-App.plist +++ b/extras/NetworkGraphicsDemo/Builds/MacOSX/Info-App.plist @@ -22,7 +22,7 @@ <key>CFBundleVersion</key> <string>1.0.0</string> <key>NSHumanReadableCopyright</key> - <string>ROLI Ltd.</string> + <string>Raw Material Software Limited</string> <key>NSHighResolutionCapable</key> <true/> </dict> diff --git a/extras/NetworkGraphicsDemo/Builds/MacOSX/NetworkGraphicsDemo.xcodeproj/project.pbxproj b/extras/NetworkGraphicsDemo/Builds/MacOSX/NetworkGraphicsDemo.xcodeproj/project.pbxproj index 2a3a20b3..08effdcc 100644 --- a/extras/NetworkGraphicsDemo/Builds/MacOSX/NetworkGraphicsDemo.xcodeproj/project.pbxproj +++ b/extras/NetworkGraphicsDemo/Builds/MacOSX/NetworkGraphicsDemo.xcodeproj/project.pbxproj @@ -41,6 +41,10 @@ isa = PBXBuildFile; fileRef = CB82A14817C3E2ABBBBC3864; }; + F918FB5901F09EA77DB32022 = { + isa = PBXBuildFile; + fileRef = F7D557738137CA1A370BAA27; + }; 77745BF98931B91341FE17F6 = { isa = PBXBuildFile; fileRef = F3292E3563DB7ABB076DB400; @@ -136,13 +140,6 @@ path = "../../JuceLibraryCode/include_juce_core.mm"; sourceTree = "SOURCE_ROOT"; }; - 0555BAE6156EAF15CA77A2D8 = { - isa = PBXFileReference; - lastKnownFileType = sourcecode.c.h; - name = AppConfig.h; - path = ../../JuceLibraryCode/AppConfig.h; - sourceTree = "SOURCE_ROOT"; - }; 0ADF0DECFCB1DB4D3A847EB5 = { isa = PBXFileReference; lastKnownFileType = image.png; @@ -486,6 +483,13 @@ path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; }; + F7D557738137CA1A370BAA27 = { + isa = PBXFileReference; + lastKnownFileType = wrapper.framework; + name = Foundation.framework; + path = System/Library/Frameworks/Foundation.framework; + sourceTree = SDKROOT; + }; F98A4DAA0502EE9252EBE06F = { isa = PBXFileReference; lastKnownFileType = file; @@ -552,7 +556,6 @@ C20D4DECE1291BF6AF8711DC = { isa = PBXGroup; children = ( - 0555BAE6156EAF15CA77A2D8, 74711D7544168CCAC4969A07, 92800676AF753D1A60108F11, 6D1F9E505D20C09647124F0A, @@ -595,6 +598,7 @@ 4D1DB6D77B6F3DE7A569780B, 448838BE6E937D450A3C84CE, CB82A14817C3E2ABBBBC3864, + F7D557738137CA1A370BAA27, F3292E3563DB7ABB076DB400, 996E743A20FC78671766BF59, 935CA85EF98714D3A17AE737, @@ -639,6 +643,25 @@ GCC_PREPROCESSOR_DEFINITIONS = ( "_DEBUG=1", "DEBUG=1", + "JUCE_DISPLAY_SPLASH_SCREEN=0", + "JUCE_USE_DARK_SPLASH_SCREEN=1", + "JUCE_PROJUCER_VERSION=0x60005", + "JUCE_MODULE_AVAILABLE_juce_audio_basics=1", + "JUCE_MODULE_AVAILABLE_juce_audio_devices=1", + "JUCE_MODULE_AVAILABLE_juce_audio_formats=1", + "JUCE_MODULE_AVAILABLE_juce_audio_processors=1", + "JUCE_MODULE_AVAILABLE_juce_audio_utils=1", + "JUCE_MODULE_AVAILABLE_juce_core=1", + "JUCE_MODULE_AVAILABLE_juce_cryptography=1", + "JUCE_MODULE_AVAILABLE_juce_data_structures=1", + "JUCE_MODULE_AVAILABLE_juce_events=1", + "JUCE_MODULE_AVAILABLE_juce_graphics=1", + "JUCE_MODULE_AVAILABLE_juce_gui_basics=1", + "JUCE_MODULE_AVAILABLE_juce_gui_extra=1", + "JUCE_MODULE_AVAILABLE_juce_opengl=1", + "JUCE_MODULE_AVAILABLE_juce_osc=1", + "JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1", + "JUCE_STANDALONE_APPLICATION=1", "JUCER_XCODE_MAC_F6D2F4CF=1", "JUCE_APP_VERSION=1.0.0", "JUCE_APP_VERSION_HEX=0x10000", @@ -661,9 +684,14 @@ INFOPLIST_PREPROCESS = NO; INSTALL_PATH = "$(HOME)/Applications"; MACOSX_DEPLOYMENT_TARGET = 10.9; + MTL_HEADER_SEARCH_PATHS = ( + "../../JuceLibraryCode", + "../../../../modules", + ); PRODUCT_BUNDLE_IDENTIFIER = com.juce.NetworkGraphicsDemo; PRODUCT_NAME = "JUCE Network Graphics Demo"; USE_HEADERMAP = NO; + VALID_ARCHS = "i386 x86_64 arm64 arm64e"; }; name = Debug; }; @@ -682,6 +710,25 @@ GCC_PREPROCESSOR_DEFINITIONS = ( "_NDEBUG=1", "NDEBUG=1", + "JUCE_DISPLAY_SPLASH_SCREEN=0", + "JUCE_USE_DARK_SPLASH_SCREEN=1", + "JUCE_PROJUCER_VERSION=0x60005", + "JUCE_MODULE_AVAILABLE_juce_audio_basics=1", + "JUCE_MODULE_AVAILABLE_juce_audio_devices=1", + "JUCE_MODULE_AVAILABLE_juce_audio_formats=1", + "JUCE_MODULE_AVAILABLE_juce_audio_processors=1", + "JUCE_MODULE_AVAILABLE_juce_audio_utils=1", + "JUCE_MODULE_AVAILABLE_juce_core=1", + "JUCE_MODULE_AVAILABLE_juce_cryptography=1", + "JUCE_MODULE_AVAILABLE_juce_data_structures=1", + "JUCE_MODULE_AVAILABLE_juce_events=1", + "JUCE_MODULE_AVAILABLE_juce_graphics=1", + "JUCE_MODULE_AVAILABLE_juce_gui_basics=1", + "JUCE_MODULE_AVAILABLE_juce_gui_extra=1", + "JUCE_MODULE_AVAILABLE_juce_opengl=1", + "JUCE_MODULE_AVAILABLE_juce_osc=1", + "JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1", + "JUCE_STANDALONE_APPLICATION=1", "JUCER_XCODE_MAC_F6D2F4CF=1", "JUCE_APP_VERSION=1.0.0", "JUCE_APP_VERSION_HEX=0x10000", @@ -694,7 +741,6 @@ "JucePlugin_Build_Standalone=0", "JucePlugin_Build_Unity=0", ); - GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; HEADER_SEARCH_PATHS = ( "../../JuceLibraryCode", @@ -706,9 +752,14 @@ INSTALL_PATH = "$(HOME)/Applications"; LLVM_LTO = YES; MACOSX_DEPLOYMENT_TARGET = 10.9; + MTL_HEADER_SEARCH_PATHS = ( + "../../JuceLibraryCode", + "../../../../modules", + ); PRODUCT_BUNDLE_IDENTIFIER = com.juce.NetworkGraphicsDemo; PRODUCT_NAME = "JUCE Network Graphics Demo"; USE_HEADERMAP = NO; + VALID_ARCHS = "i386 x86_64 arm64 arm64e"; }; name = Release; }; @@ -737,11 +788,12 @@ CODE_SIGN_IDENTITY = ""; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; + ENABLE_TESTABILITY = NO; GCC_C_LANGUAGE_STANDARD = c11; GCC_INLINES_ARE_PRIVATE_EXTERN = YES; GCC_MODEL_TUNING = G5; GCC_NO_COMMON_BLOCKS = YES; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; @@ -785,10 +837,12 @@ CODE_SIGN_IDENTITY = ""; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = NO; GCC_C_LANGUAGE_STANDARD = c11; GCC_INLINES_ARE_PRIVATE_EXTERN = YES; GCC_MODEL_TUNING = G5; GCC_NO_COMMON_BLOCKS = YES; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; @@ -806,10 +860,6 @@ }; name = Release; }; - 80BE97CC38B01FABC0E73204 = { - isa = PBXTargetDependency; - target = 4311FBCBD02948A0ED96C7DD; - }; 02715337C584F3C721251428 = { isa = XCConfigurationList; buildConfigurations = ( @@ -872,6 +922,7 @@ 770AB74B1D3A0108F764DD47, CA694B2A73FCF12D7F9E7E49, 80B9F7ED2009922C693B7DD4, + F918FB5901F09EA77DB32022, 77745BF98931B91341FE17F6, B323E5E5FBD5663B21A8E623, EC14DA30C090DDC62084DB4C, @@ -897,7 +948,7 @@ A5398ADB6F5B128C00EB935C = { isa = PBXProject; buildConfigurationList = 02715337C584F3C721251428; - attributes = { LastUpgradeCheck = 1100; ORGANIZATIONNAME = "ROLI Ltd."; TargetAttributes = { 4311FBCBD02948A0ED96C7DD = { SystemCapabilities = {com.apple.ApplicationGroups.iOS = { enabled = 0; }; com.apple.InAppPurchase = { enabled = 0; }; com.apple.InterAppAudio = { enabled = 0; }; com.apple.Push = { enabled = 0; }; com.apple.Sandbox = { enabled = 0; }; com.apple.HardenedRuntime = { enabled = 0; }; }; }; }; }; + attributes = { LastUpgradeCheck = 1200; ORGANIZATIONNAME = "Raw Material Software Limited"; TargetAttributes = { 4311FBCBD02948A0ED96C7DD = { SystemCapabilities = {com.apple.ApplicationGroups.iOS = { enabled = 0; }; com.apple.InAppPurchase = { enabled = 0; }; com.apple.InterAppAudio = { enabled = 0; }; com.apple.Push = { enabled = 0; }; com.apple.Sandbox = { enabled = 0; }; com.apple.HardenedRuntime = { enabled = 0; }; }; }; }; }; compatibilityVersion = "Xcode 3.2"; hasScannedForEncodings = 0; mainGroup = D2EB65517396C974F0415A7F; diff --git a/extras/NetworkGraphicsDemo/Builds/MacOSX/NetworkGraphicsDemo.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/extras/NetworkGraphicsDemo/Builds/MacOSX/NetworkGraphicsDemo.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings index 949b6789..f2e3cbe8 100644 --- a/extras/NetworkGraphicsDemo/Builds/MacOSX/NetworkGraphicsDemo.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ b/extras/NetworkGraphicsDemo/Builds/MacOSX/NetworkGraphicsDemo.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -4,5 +4,7 @@ <dict> <key>BuildSystemType</key> <string>Original</string> + <key>DisableBuildSystemDeprecationWarning</key> + <true/> </dict> </plist> diff --git a/extras/NetworkGraphicsDemo/Builds/VisualStudio2019/NetworkGraphicsDemo_App.vcxproj b/extras/NetworkGraphicsDemo/Builds/VisualStudio2019/NetworkGraphicsDemo_App.vcxproj index 99d26bb3..2bb0f746 100644 --- a/extras/NetworkGraphicsDemo/Builds/VisualStudio2019/NetworkGraphicsDemo_App.vcxproj +++ b/extras/NetworkGraphicsDemo/Builds/VisualStudio2019/NetworkGraphicsDemo_App.vcxproj @@ -64,10 +64,10 @@ <Optimization>Disabled</Optimization> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=1.0.0;JUCE_APP_VERSION_HEX=0x10000;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCE_DISPLAY_SPLASH_SCREEN=0;JUCE_USE_DARK_SPLASH_SCREEN=1;JUCE_PROJUCER_VERSION=0x60005;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_audio_formats=1;JUCE_MODULE_AVAILABLE_juce_audio_processors=1;JUCE_MODULE_AVAILABLE_juce_audio_utils=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_MODULE_AVAILABLE_juce_opengl=1;JUCE_MODULE_AVAILABLE_juce_osc=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_STANDALONE_APPLICATION=1;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=1.0.0;JUCE_APP_VERSION_HEX=0x10000;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> <RuntimeTypeInfo>true</RuntimeTypeInfo> - <PrecompiledHeader/> + <PrecompiledHeader>NotUsing</PrecompiledHeader> <AssemblerListingLocation>$(IntDir)\</AssemblerListingLocation> <ObjectFileName>$(IntDir)\</ObjectFileName> <ProgramDataBaseFileName>$(IntDir)\</ProgramDataBaseFileName> @@ -105,10 +105,10 @@ <ClCompile> <Optimization>Full</Optimization> <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=1.0.0;JUCE_APP_VERSION_HEX=0x10000;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCE_DISPLAY_SPLASH_SCREEN=0;JUCE_USE_DARK_SPLASH_SCREEN=1;JUCE_PROJUCER_VERSION=0x60005;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_audio_formats=1;JUCE_MODULE_AVAILABLE_juce_audio_processors=1;JUCE_MODULE_AVAILABLE_juce_audio_utils=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_MODULE_AVAILABLE_juce_opengl=1;JUCE_MODULE_AVAILABLE_juce_osc=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_STANDALONE_APPLICATION=1;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=1.0.0;JUCE_APP_VERSION_HEX=0x10000;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> <RuntimeTypeInfo>true</RuntimeTypeInfo> - <PrecompiledHeader/> + <PrecompiledHeader>NotUsing</PrecompiledHeader> <AssemblerListingLocation>$(IntDir)\</AssemblerListingLocation> <ObjectFileName>$(IntDir)\</ObjectFileName> <ProgramDataBaseFileName>$(IntDir)\</ProgramDataBaseFileName> @@ -130,6 +130,7 @@ <OptimizeReferences>true</OptimizeReferences> <EnableCOMDATFolding>true</EnableCOMDATFolding> <LargeAddressAware>true</LargeAddressAware> + <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> </Link> <Bscmake> <SuppressStartupBanner>true</SuppressStartupBanner> @@ -223,10 +224,10 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_basics\synthesisers\juce_Synthesiser.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_CatmullRomInterpolator.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Interpolators.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_LagrangeInterpolator.cpp"> @@ -235,6 +236,9 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_SmoothedValue.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_WindowedSincInterpolator.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_basics\juce_audio_basics.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -253,6 +257,153 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_devices\midi_io\juce_MidiMessageCollector.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AAudioLoader.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AudioStreamAAudio.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioSourceCaller.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioStream.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioStreamBuilder.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\DataConversionFlowGraph.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FilterAudioStream.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockAdapter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockReader.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockWriter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\LatencyTuner.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\QuirksManager.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceFloatCaller.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceI16Caller.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\StabilizedCallback.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Trace.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Utilities.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Version.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoBuffer.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoController.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerBase.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerIndirect.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\IntegerRatio.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\LinearResampler.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\MultiChannelResampler.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResampler.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerMono.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerStereo.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResampler.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResamplerStereo.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ClipToRange.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\FlowGraphNode.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ManyToMultiConverter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\MonoToMultiConverter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\RampLinear.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SampleRateConverter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkFloat.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI16.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI24.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceFloat.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI16.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI24.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioInputStreamOpenSLES.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioOutputStreamOpenSLES.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamBuffered.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamOpenSLES.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\EngineOpenSLES.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OpenSLESUtilities.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OutputMixerOpenSLES.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_android_Audio.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -352,70 +503,73 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\libFLAC\window_flac.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\analysis.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\analysis.c"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\bitrate.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\bitrate.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\block.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\block.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codebook.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codebook.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\envelope.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\envelope.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\floor0.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\floor0.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\floor1.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\floor1.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\info.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\info.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lpc.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lpc.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lsp.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lsp.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mapping0.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mapping0.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mdct.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mdct.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\misc.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\psy.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\psy.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\registry.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\registry.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\res0.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\res0.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\sharedbook.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\sharedbook.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\smallft.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\smallft.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\synthesis.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\synthesis.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\vorbisenc.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\vorbisenc.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\vorbisfile.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\vorbisfile.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\window.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\window.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\bitwise.c"> @@ -610,6 +764,9 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioProcessorValueTreeState.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_ParameterAttachments.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_RangedAudioParameter.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -712,6 +869,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_FileSearchPath.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -739,6 +899,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_MemoryBlock.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -1624,6 +1787,15 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_MouseListener.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_DragAndDrop.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_android_ContentSharer.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -1642,13 +1814,7 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_FileChooser.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.cpp"> - <ExcludedFromBuild>true</ExcludedFromBuild> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Clipboard.cpp"> - <ExcludedFromBuild>true</ExcludedFromBuild> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Windowing.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_Windowing.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_win32_DragAndDrop.cpp"> @@ -1852,6 +2018,9 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_ActiveXComponent.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_HWNDComponent.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_SystemTrayIcon.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -1973,10 +2142,10 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_basics\sources\juce_ToneGeneratorAudioSource.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\synthesisers\juce_Synthesiser.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_ADSR.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_CatmullRomInterpolator.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Decibels.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_GenericInterpolator.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_LagrangeInterpolator.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Interpolators.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Reverb.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_SmoothedValue.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\juce_audio_basics.h"/> @@ -1986,6 +2155,66 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_devices\audio_io\juce_SystemAudioVolume.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\midi_io\juce_MidiDevices.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\midi_io\juce_MidiMessageCollector.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStream.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamBase.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamBuilder.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamCallback.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Definitions.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\LatencyTuner.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Oboe.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\ResultWithValue.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\StabilizedCallback.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Utilities.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Version.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AAudioLoader.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AudioStreamAAudio.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioClock.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioSourceCaller.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\DataConversionFlowGraph.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FilterAudioStream.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockAdapter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockReader.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockWriter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\MonotonicCounter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\OboeDebug.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\QuirksManager.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceFloatCaller.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceI16Caller.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Trace.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoBuffer.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoController.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerBase.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerIndirect.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\HyperbolicCosineWindow.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\IntegerRatio.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\KaiserWindow.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\LinearResampler.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\MultiChannelResampler.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResampler.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerMono.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerStereo.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResampler.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResamplerStereo.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ClipToRange.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\FlowGraphNode.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ManyToMultiConverter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\MonoToMultiConverter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\RampLinear.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SampleRateConverter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkFloat.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI16.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI24.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceFloat.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI16.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI24.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioInputStreamOpenSLES.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioOutputStreamOpenSLES.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamBuffered.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamOpenSLES.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\EngineOpenSLES.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OpenSLESUtilities.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OutputMixerOpenSLES.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\juce_android_HighPerformanceAudioHelpers.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\juce_ios_Audio.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\juce_MidiDataConcatenator.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\sources\juce_AudioSourcePlayer.h"/> @@ -2023,50 +2252,51 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\stream_decoder.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\stream_encoder.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\win_utf8_io.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled\res_books_51.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled\res_books_stereo.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\floor\floor_books.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\uncoupled\res_books_uncoupled.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\floor_all.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_8.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_11.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_16.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_44.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_8.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_16.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44p51.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44u.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_8.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_11.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_16.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_22.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_32.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44p51.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44u.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_X.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\backends.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\bitrate.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codebook.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codec_internal.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\envelope.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\highlevel.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup_data.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lpc.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lsp.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\masking.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mdct.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\misc.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\os.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\psy.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\registry.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\scales.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\smallft.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\window.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled\res_books_51.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled\res_books_stereo.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\floor\floor_books.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\uncoupled\res_books_uncoupled.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\floor_all.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_8.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_11.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_16.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_44.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_8.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_16.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44p51.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44u.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_8.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_11.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_16.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_22.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_32.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44p51.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44u.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_X.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\backends.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\bitrate.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codebook.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codec_internal.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\envelope.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\highlevel.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup_data.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lpc.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lsp.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\masking.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mdct.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\misc.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\os.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\psy.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\registry.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\scales.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\smallft.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\window.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\codec.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\config_types.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\crctable.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\ogg.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\os_types.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\vorbisenc.h"/> @@ -2155,6 +2385,7 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst\vsteditcontroller.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst\vstparameters.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst\vstpresetfile.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_AU_Shared.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_AudioUnitPluginFormat.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LADSPAPluginFormat.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_VST3Common.h"/> @@ -2181,6 +2412,7 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioParameterInt.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioProcessorParameterWithID.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioProcessorValueTreeState.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_ParameterAttachments.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_RangedAudioParameter.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\juce_audio_processors.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_utils\audio_cd\juce_AudioCDBurner.h"/> @@ -2220,6 +2452,7 @@ <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_FileOutputStream.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_FileSearchPath.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_MemoryMappedFile.h"/> + <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_WildcardFileFilter.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\javascript\juce_Javascript.h"/> @@ -2233,6 +2466,7 @@ <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_Random.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_Range.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_StatisticsAccumulator.h"/> + <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_Atomic.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_ByteOrder.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_ContainerDeletePolicy.h"/> @@ -2275,6 +2509,7 @@ <ClInclude Include="..\..\..\..\modules\juce_core\streams\juce_SubregionStream.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\streams\juce_URLInputSource.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerSupport.h"/> + <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerWarnings.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_PlatformDefs.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_StandardHeader.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_SystemStats.h"/> @@ -2531,7 +2766,8 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_SelectedItemSet.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_TextDragAndDropTarget.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_TooltipClient.h"/> - <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.h"/> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.h"/> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_MultiTouchMapper.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\positioning\juce_MarkerList.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\positioning\juce_RelativeCoordinate.h"/> @@ -2583,6 +2819,7 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ActiveXControlComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"/> + <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_HWNDComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_NSViewComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ScopedDPIAwarenessDisabler.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_UIViewComponent.h"/> @@ -2632,13 +2869,15 @@ <ClInclude Include="..\..\..\..\modules\juce_osc\osc\juce_OSCTimeTag.h"/> <ClInclude Include="..\..\..\..\modules\juce_osc\osc\juce_OSCTypes.h"/> <ClInclude Include="..\..\..\..\modules\juce_osc\juce_osc.h"/> - <ClInclude Include="..\..\JuceLibraryCode\AppConfig.h"/> <ClInclude Include="..\..\JuceLibraryCode\BinaryData.h"/> <ClInclude Include="..\..\JuceLibraryCode\JuceHeader.h"/> </ItemGroup> <ItemGroup> <None Include="..\..\Source\juce_icon.png"/> + <None Include="..\..\..\..\modules\juce_audio_devices\native\oboe\CMakeLists.txt"/> + <None Include="..\..\..\..\modules\juce_audio_devices\native\oboe\readme.md"/> <None Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\Flac Licence.txt"/> + <None Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\README.md"/> <None Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\Ogg Vorbis Licence.txt"/> <None Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\base\LICENSE.txt"/> <None Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\base\README.md"/> diff --git a/extras/NetworkGraphicsDemo/Builds/VisualStudio2019/NetworkGraphicsDemo_App.vcxproj.filters b/extras/NetworkGraphicsDemo/Builds/VisualStudio2019/NetworkGraphicsDemo_App.vcxproj.filters index 0181b46d..4f667072 100644 --- a/extras/NetworkGraphicsDemo/Builds/VisualStudio2019/NetworkGraphicsDemo_App.vcxproj.filters +++ b/extras/NetworkGraphicsDemo/Builds/VisualStudio2019/NetworkGraphicsDemo_App.vcxproj.filters @@ -41,6 +41,36 @@ <Filter Include="JUCE Modules\juce_audio_devices\midi_io"> <UniqueIdentifier>{092EFC17-7C95-7E04-0ACA-0D61A462EE81}</UniqueIdentifier> </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\include\oboe"> + <UniqueIdentifier>{285118C6-8FDA-7DCE-BEF4-FFB2120876C5}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\include"> + <UniqueIdentifier>{69ED6B61-9B8D-D47E-E4A6-2E9F9A94A75A}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\aaudio"> + <UniqueIdentifier>{7CDB7CD1-BB96-F593-3C78-1E06182B5839}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\common"> + <UniqueIdentifier>{B0A708DE-B4CF-196B-14FB-DC8221509B8E}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\fifo"> + <UniqueIdentifier>{34F46ADE-EE31-227A-A69E-7732E70145F1}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler"> + <UniqueIdentifier>{BB9B3C77-17FB-E994-8B75-88F1727E4655}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph"> + <UniqueIdentifier>{C0971D77-2F14-190A-E2AE-89D6285F4D5A}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\opensles"> + <UniqueIdentifier>{AABEA333-6524-8891-51C7-6DAEB5700628}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src"> + <UniqueIdentifier>{F2D29337-983E-BAD7-7B5C-E0AB3D53D404}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe"> + <UniqueIdentifier>{C674B0FB-1FC0-2986-94B1-083845018994}</UniqueIdentifier> + </Filter> <Filter Include="JUCE Modules\juce_audio_devices\native"> <UniqueIdentifier>{0AFC1CE8-F6E6-9817-8C21-8432B2A375DA}</UniqueIdentifier> </Filter> @@ -65,26 +95,26 @@ <Filter Include="JUCE Modules\juce_audio_formats\codecs\flac"> <UniqueIdentifier>{9EB3EC7F-2AB7-DDAA-3C05-DF382B728D3F}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled"> - <UniqueIdentifier>{02D37B85-7DE2-C8E7-A274-A5A0FBE99D69}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled"> + <UniqueIdentifier>{6B9FBFDC-1D10-6246-356D-00FF4535CECB}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\floor"> - <UniqueIdentifier>{DAF3BAAF-5207-4C34-61B9-A97DDC930D50}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\floor"> + <UniqueIdentifier>{D6FCFC8E-7136-9109-78C0-91A3EB4C443F}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\uncoupled"> - <UniqueIdentifier>{C7885588-8436-4C21-DC1E-58879BF53BDC}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\uncoupled"> + <UniqueIdentifier>{EBF18AC1-F0ED-937A-2824-4307CE2ADAF7}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books"> - <UniqueIdentifier>{E4ECEA39-0EFF-2443-91B3-1E5DA7AD5AE4}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books"> + <UniqueIdentifier>{5A0F7922-2EFB-6465-57E4-A445B804EFB5}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes"> - <UniqueIdentifier>{210B8D25-68E0-32C3-1449-6A40F109C5E9}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes"> + <UniqueIdentifier>{4EC45416-0E7C-7567-6F75-D0C8CEE7DC4F}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib"> - <UniqueIdentifier>{378AD911-E8E4-D230-E76B-34542849509D}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib"> + <UniqueIdentifier>{C2985031-0496-55B5-41A8-BAB99E53D89D}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2"> - <UniqueIdentifier>{F6CED5B6-0A8C-56D2-C1AC-DED6BE774A13}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7"> + <UniqueIdentifier>{FB4AB426-7009-0036-BB75-E34256AA7C89}</UniqueIdentifier> </Filter> <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis"> <UniqueIdentifier>{E684D858-09E8-0251-8E86-5657129641E1}</UniqueIdentifier> @@ -353,6 +383,9 @@ <Filter Include="JUCE Modules\juce_gui_basics\mouse"> <UniqueIdentifier>{FE3CB19C-EF43-5CF5-DAF0-09D4E43D0AB9}</UniqueIdentifier> </Filter> + <Filter Include="JUCE Modules\juce_gui_basics\native\x11"> + <UniqueIdentifier>{FE7E6CD5-C7A0-DB20-4E7E-D6E7F08C4578}</UniqueIdentifier> + </Filter> <Filter Include="JUCE Modules\juce_gui_basics\native"> <UniqueIdentifier>{895C2D33-E08D-B1BA-BB36-FC4CA65090C8}</UniqueIdentifier> </Filter> @@ -505,10 +538,10 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_basics\synthesisers\juce_Synthesiser.cpp"> <Filter>JUCE Modules\juce_audio_basics\synthesisers</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_CatmullRomInterpolator.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.cpp"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Interpolators.cpp"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_LagrangeInterpolator.cpp"> @@ -517,6 +550,9 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_SmoothedValue.cpp"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_WindowedSincInterpolator.cpp"> + <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_basics\juce_audio_basics.cpp"> <Filter>JUCE Modules\juce_audio_basics</Filter> </ClCompile> @@ -538,6 +574,153 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_devices\midi_io\juce_MidiMessageCollector.cpp"> <Filter>JUCE Modules\juce_audio_devices\midi_io</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AAudioLoader.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\aaudio</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AudioStreamAAudio.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\aaudio</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioSourceCaller.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioStream.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioStreamBuilder.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\DataConversionFlowGraph.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FilterAudioStream.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockAdapter.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockReader.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockWriter.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\LatencyTuner.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\QuirksManager.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceFloatCaller.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceI16Caller.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\StabilizedCallback.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Trace.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Utilities.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Version.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoBuffer.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoController.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerBase.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerIndirect.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\IntegerRatio.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\LinearResampler.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\MultiChannelResampler.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResampler.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerMono.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerStereo.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResampler.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResamplerStereo.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ClipToRange.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\FlowGraphNode.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ManyToMultiConverter.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\MonoToMultiConverter.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\RampLinear.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SampleRateConverter.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkFloat.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI16.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI24.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceFloat.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI16.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI24.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioInputStreamOpenSLES.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioOutputStreamOpenSLES.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamBuffered.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamOpenSLES.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\EngineOpenSLES.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OpenSLESUtilities.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OutputMixerOpenSLES.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_android_Audio.cpp"> <Filter>JUCE Modules\juce_audio_devices\native</Filter> </ClCompile> @@ -640,71 +823,74 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\libFLAC\window_flac.c"> <Filter>JUCE Modules\juce_audio_formats\codecs\flac\libFLAC</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\analysis.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\analysis.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\bitrate.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\bitrate.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\block.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\block.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codebook.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codebook.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\envelope.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\envelope.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\floor0.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\floor0.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\floor1.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\floor1.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\info.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\info.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lpc.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lpc.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lsp.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lsp.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mapping0.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mapping0.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mdct.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mdct.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\misc.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\psy.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\psy.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\registry.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\registry.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\res0.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\res0.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\sharedbook.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\sharedbook.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\smallft.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\smallft.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\synthesis.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\synthesis.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\vorbisenc.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\vorbisenc.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\vorbisfile.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\vorbisfile.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\window.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\window.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\bitwise.c"> <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> @@ -904,6 +1090,9 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioProcessorValueTreeState.cpp"> <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_ParameterAttachments.cpp"> + <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_RangedAudioParameter.cpp"> <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> </ClCompile> @@ -1024,6 +1213,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_FileSearchPath.cpp"> <Filter>JUCE Modules\juce_core\files</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.cpp"> + <Filter>JUCE Modules\juce_core\files</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.cpp"> <Filter>JUCE Modules\juce_core\files</Filter> </ClCompile> @@ -1051,6 +1243,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> <Filter>JUCE Modules\juce_core\maths</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.cpp"> + <Filter>JUCE Modules\juce_core\memory</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_MemoryBlock.cpp"> <Filter>JUCE Modules\juce_core\memory</Filter> </ClCompile> @@ -1978,6 +2173,15 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_MouseListener.cpp"> <Filter>JUCE Modules\juce_gui_basics\mouse</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_DragAndDrop.cpp"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.cpp"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.cpp"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_android_ContentSharer.cpp"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> </ClCompile> @@ -2005,13 +2209,7 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_FileChooser.cpp"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.cpp"> - <Filter>JUCE Modules\juce_gui_basics\native</Filter> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Clipboard.cpp"> - <Filter>JUCE Modules\juce_gui_basics\native</Filter> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Windowing.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_Windowing.cpp"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_mac_FileChooser.mm"> @@ -2245,6 +2443,9 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_ActiveXComponent.cpp"> <Filter>JUCE Modules\juce_gui_extra\native</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_HWNDComponent.cpp"> + <Filter>JUCE Modules\juce_gui_extra\native</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_SystemTrayIcon.cpp"> <Filter>JUCE Modules\juce_gui_extra\native</Filter> </ClCompile> @@ -2478,16 +2679,16 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_ADSR.h"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_CatmullRomInterpolator.h"> + <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Decibels.h"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Decibels.h"> + <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_GenericInterpolator.h"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.h"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_LagrangeInterpolator.h"> + <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Interpolators.h"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Reverb.h"> @@ -2517,6 +2718,186 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_devices\midi_io\juce_MidiMessageCollector.h"> <Filter>JUCE Modules\juce_audio_devices\midi_io</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStream.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamBase.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamBuilder.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamCallback.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Definitions.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\LatencyTuner.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Oboe.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\ResultWithValue.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\StabilizedCallback.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Utilities.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Version.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AAudioLoader.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\aaudio</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AudioStreamAAudio.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\aaudio</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioClock.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioSourceCaller.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\DataConversionFlowGraph.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FilterAudioStream.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockAdapter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockReader.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockWriter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\MonotonicCounter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\OboeDebug.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\QuirksManager.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceFloatCaller.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceI16Caller.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Trace.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoBuffer.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoController.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerBase.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerIndirect.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\HyperbolicCosineWindow.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\IntegerRatio.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\KaiserWindow.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\LinearResampler.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\MultiChannelResampler.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResampler.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerMono.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerStereo.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResampler.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResamplerStereo.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ClipToRange.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\FlowGraphNode.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ManyToMultiConverter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\MonoToMultiConverter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\RampLinear.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SampleRateConverter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkFloat.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI16.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI24.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceFloat.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI16.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI24.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioInputStreamOpenSLES.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioOutputStreamOpenSLES.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamBuffered.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamOpenSLES.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\EngineOpenSLES.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OpenSLESUtilities.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OutputMixerOpenSLES.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\juce_android_HighPerformanceAudioHelpers.h"> + <Filter>JUCE Modules\juce_audio_devices\native</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\juce_ios_Audio.h"> <Filter>JUCE Modules\juce_audio_devices\native</Filter> </ClInclude> @@ -2628,131 +3009,131 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\win_utf8_io.h"> <Filter>JUCE Modules\juce_audio_formats\codecs\flac</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled\res_books_51.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled\res_books_51.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled\res_books_stereo.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled\res_books_stereo.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\floor\floor_books.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\floor</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\floor\floor_books.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\floor</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\uncoupled\res_books_uncoupled.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\uncoupled</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\uncoupled\res_books_uncoupled.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\uncoupled</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\floor_all.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\floor_all.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_8.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_8.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_11.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_11.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_16.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_16.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_44.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_44.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_8.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_8.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_16.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_16.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44p51.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44p51.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44u.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44u.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_8.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_8.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_11.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_11.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_16.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_16.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_22.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_22.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_32.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_32.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44p51.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44p51.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44u.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44u.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_X.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_X.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\backends.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\backends.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\bitrate.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\bitrate.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codebook.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codebook.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codec_internal.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codec_internal.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\envelope.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\envelope.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\highlevel.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\highlevel.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup_data.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup_data.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lpc.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lpc.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lsp.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lsp.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\masking.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\masking.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mdct.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mdct.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\misc.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\misc.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\os.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\os.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\psy.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\psy.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\registry.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\registry.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\scales.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\scales.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\smallft.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\smallft.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\window.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\window.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\codec.h"> <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> @@ -2760,6 +3141,9 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\config_types.h"> <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\crctable.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\ogg.h"> <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> </ClInclude> @@ -3024,6 +3408,9 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst\vstpresetfile.h"> <Filter>JUCE Modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_AU_Shared.h"> + <Filter>JUCE Modules\juce_audio_processors\format_types</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_AudioUnitPluginFormat.h"> <Filter>JUCE Modules\juce_audio_processors\format_types</Filter> </ClInclude> @@ -3102,6 +3489,9 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioProcessorValueTreeState.h"> <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_ParameterAttachments.h"> + <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_RangedAudioParameter.h"> <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> </ClInclude> @@ -3219,6 +3609,9 @@ <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_MemoryMappedFile.h"> <Filter>JUCE Modules\juce_core\files</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.h"> + <Filter>JUCE Modules\juce_core\files</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.h"> <Filter>JUCE Modules\juce_core\files</Filter> </ClInclude> @@ -3258,6 +3651,9 @@ <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_StatisticsAccumulator.h"> <Filter>JUCE Modules\juce_core\maths</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.h"> + <Filter>JUCE Modules\juce_core\memory</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_Atomic.h"> <Filter>JUCE Modules\juce_core\memory</Filter> </ClInclude> @@ -3384,6 +3780,9 @@ <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerSupport.h"> <Filter>JUCE Modules\juce_core\system</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerWarnings.h"> + <Filter>JUCE Modules\juce_core\system</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_PlatformDefs.h"> <Filter>JUCE Modules\juce_core\system</Filter> </ClInclude> @@ -4152,8 +4551,11 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_TooltipClient.h"> <Filter>JUCE Modules\juce_gui_basics\mouse</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.h"> - <Filter>JUCE Modules\juce_gui_basics\native</Filter> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.h"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.h"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_MultiTouchMapper.h"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> @@ -4308,6 +4710,9 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"> <Filter>JUCE Modules\juce_gui_extra\embedding</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_HWNDComponent.h"> + <Filter>JUCE Modules\juce_gui_extra\embedding</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_NSViewComponent.h"> <Filter>JUCE Modules\juce_gui_extra\embedding</Filter> </ClInclude> @@ -4455,9 +4860,6 @@ <ClInclude Include="..\..\..\..\modules\juce_osc\juce_osc.h"> <Filter>JUCE Modules\juce_osc</Filter> </ClInclude> - <ClInclude Include="..\..\JuceLibraryCode\AppConfig.h"> - <Filter>JUCE Library Code</Filter> - </ClInclude> <ClInclude Include="..\..\JuceLibraryCode\BinaryData.h"> <Filter>JUCE Library Code</Filter> </ClInclude> @@ -4469,9 +4871,18 @@ <None Include="..\..\Source\juce_icon.png"> <Filter>NetworkGraphicsDemo</Filter> </None> + <None Include="..\..\..\..\modules\juce_audio_devices\native\oboe\CMakeLists.txt"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe</Filter> + </None> + <None Include="..\..\..\..\modules\juce_audio_devices\native\oboe\readme.md"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe</Filter> + </None> <None Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\Flac Licence.txt"> <Filter>JUCE Modules\juce_audio_formats\codecs\flac</Filter> </None> + <None Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\README.md"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7</Filter> + </None> <None Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\Ogg Vorbis Licence.txt"> <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> </None> diff --git a/extras/NetworkGraphicsDemo/Builds/VisualStudio2019/resources.rc b/extras/NetworkGraphicsDemo/Builds/VisualStudio2019/resources.rc index 1a2342ea..4a3e44a5 100644 --- a/extras/NetworkGraphicsDemo/Builds/VisualStudio2019/resources.rc +++ b/extras/NetworkGraphicsDemo/Builds/VisualStudio2019/resources.rc @@ -1,3 +1,5 @@ +#pragma code_page(65001) + #ifdef JUCE_USER_DEFINED_RC_FILE #include JUCE_USER_DEFINED_RC_FILE #else @@ -13,8 +15,8 @@ BEGIN BEGIN BLOCK "040904E4" BEGIN - VALUE "CompanyName", "ROLI Ltd.\0" - VALUE "LegalCopyright", "ROLI Ltd.\0" + VALUE "CompanyName", "Raw Material Software Limited\0" + VALUE "LegalCopyright", "Raw Material Software Limited\0" VALUE "FileDescription", "NetworkGraphicsDemo\0" VALUE "FileVersion", "1.0.0\0" VALUE "ProductName", "NetworkGraphicsDemo\0" diff --git a/extras/NetworkGraphicsDemo/Builds/iOS/App.entitlements b/extras/NetworkGraphicsDemo/Builds/iOS/App.entitlements deleted file mode 100644 index 6631ffa6..00000000 --- a/extras/NetworkGraphicsDemo/Builds/iOS/App.entitlements +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> -</dict> -</plist> diff --git a/extras/NetworkGraphicsDemo/Builds/iOS/Info-App.plist b/extras/NetworkGraphicsDemo/Builds/iOS/Info-App.plist index 72c9f8a7..2fceeb6f 100644 --- a/extras/NetworkGraphicsDemo/Builds/iOS/Info-App.plist +++ b/extras/NetworkGraphicsDemo/Builds/iOS/Info-App.plist @@ -26,7 +26,7 @@ <key>CFBundleVersion</key> <string>1.0.0</string> <key>NSHumanReadableCopyright</key> - <string>ROLI Ltd.</string> + <string>Raw Material Software Limited</string> <key>NSHighResolutionCapable</key> <true/> <key>UIRequiresFullScreen</key> diff --git a/extras/NetworkGraphicsDemo/Builds/iOS/NetworkGraphicsDemo.xcodeproj/project.pbxproj b/extras/NetworkGraphicsDemo/Builds/iOS/NetworkGraphicsDemo.xcodeproj/project.pbxproj index 69eb6184..0462d718 100644 --- a/extras/NetworkGraphicsDemo/Builds/iOS/NetworkGraphicsDemo.xcodeproj/project.pbxproj +++ b/extras/NetworkGraphicsDemo/Builds/iOS/NetworkGraphicsDemo.xcodeproj/project.pbxproj @@ -41,6 +41,10 @@ isa = PBXBuildFile; fileRef = 448838BE6E937D450A3C84CE; }; + E29AB6243FBBDDD7BD723340 = { + isa = PBXBuildFile; + fileRef = EA5D4F9D63C0ED79CDE8967A; + }; 5A64B64E5B45AEA1A0EECC4B = { isa = PBXBuildFile; fileRef = 9193D2A3C463BEAA07FD424D; @@ -49,10 +53,6 @@ isa = PBXBuildFile; fileRef = F7D557738137CA1A370BAA27; }; - 1006E2E5DFA26D7DD20BC438 = { - isa = PBXBuildFile; - fileRef = 855850D3F44F120C46DE82EC; - }; A6AA70BD9364BB974CDEB337 = { isa = PBXBuildFile; fileRef = C821C5805007FFDC2636BBE6; @@ -65,6 +65,10 @@ isa = PBXBuildFile; fileRef = 379F77D23BFAE3795282CEB3; }; + 8ECB0767EE340DD83869E37D = { + isa = PBXBuildFile; + fileRef = EC794872987FEA2E129C589A; + }; 1282A62308CD1AC3F88A5D03 = { isa = PBXBuildFile; fileRef = 5273768FBB55D0DD57A5E70C; @@ -148,13 +152,6 @@ path = "../../JuceLibraryCode/include_juce_core.mm"; sourceTree = "SOURCE_ROOT"; }; - 0555BAE6156EAF15CA77A2D8 = { - isa = PBXFileReference; - lastKnownFileType = sourcecode.c.h; - name = AppConfig.h; - path = ../../JuceLibraryCode/AppConfig.h; - sourceTree = "SOURCE_ROOT"; - }; 080961C54C58ECF2346B4C23 = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; @@ -323,13 +320,6 @@ path = "../../JuceLibraryCode/include_juce_gui_basics.mm"; sourceTree = "SOURCE_ROOT"; }; - 855850D3F44F120C46DE82EC = { - isa = PBXFileReference; - lastKnownFileType = wrapper.framework; - name = MobileCoreServices.framework; - path = System/Library/Frameworks/MobileCoreServices.framework; - sourceTree = SDKROOT; - }; 89583CD42AD218E9753DF11C = { isa = PBXFileReference; lastKnownFileType = file; @@ -512,6 +502,20 @@ path = System/Library/Frameworks/CoreImage.framework; sourceTree = SDKROOT; }; + EA5D4F9D63C0ED79CDE8967A = { + isa = PBXFileReference; + lastKnownFileType = wrapper.framework; + name = CoreServices.framework; + path = System/Library/Frameworks/CoreServices.framework; + sourceTree = SDKROOT; + }; + EC794872987FEA2E129C589A = { + isa = PBXFileReference; + lastKnownFileType = wrapper.framework; + name = WebKit.framework; + path = System/Library/Frameworks/WebKit.framework; + sourceTree = SDKROOT; + }; F7D557738137CA1A370BAA27 = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; @@ -585,7 +589,6 @@ C20D4DECE1291BF6AF8711DC = { isa = PBXGroup; children = ( - 0555BAE6156EAF15CA77A2D8, 74711D7544168CCAC4969A07, 92800676AF753D1A60108F11, 6D1F9E505D20C09647124F0A, @@ -629,12 +632,13 @@ DA40ED39AF4B56000E5A2743, E51ABCA80B75F33848F28184, 448838BE6E937D450A3C84CE, + EA5D4F9D63C0ED79CDE8967A, 9193D2A3C463BEAA07FD424D, F7D557738137CA1A370BAA27, - 855850D3F44F120C46DE82EC, C821C5805007FFDC2636BBE6, 935CA85EF98714D3A17AE737, 379F77D23BFAE3795282CEB3, + EC794872987FEA2E129C589A, ); name = Frameworks; sourceTree = "<group>"; @@ -676,6 +680,26 @@ GCC_PREPROCESSOR_DEFINITIONS = ( "_DEBUG=1", "DEBUG=1", + "JUCE_CONTENT_SHARING=1", + "JUCE_DISPLAY_SPLASH_SCREEN=0", + "JUCE_USE_DARK_SPLASH_SCREEN=1", + "JUCE_PROJUCER_VERSION=0x60005", + "JUCE_MODULE_AVAILABLE_juce_audio_basics=1", + "JUCE_MODULE_AVAILABLE_juce_audio_devices=1", + "JUCE_MODULE_AVAILABLE_juce_audio_formats=1", + "JUCE_MODULE_AVAILABLE_juce_audio_processors=1", + "JUCE_MODULE_AVAILABLE_juce_audio_utils=1", + "JUCE_MODULE_AVAILABLE_juce_core=1", + "JUCE_MODULE_AVAILABLE_juce_cryptography=1", + "JUCE_MODULE_AVAILABLE_juce_data_structures=1", + "JUCE_MODULE_AVAILABLE_juce_events=1", + "JUCE_MODULE_AVAILABLE_juce_graphics=1", + "JUCE_MODULE_AVAILABLE_juce_gui_basics=1", + "JUCE_MODULE_AVAILABLE_juce_gui_extra=1", + "JUCE_MODULE_AVAILABLE_juce_opengl=1", + "JUCE_MODULE_AVAILABLE_juce_osc=1", + "JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1", + "JUCE_STANDALONE_APPLICATION=1", "JUCER_XCODE_IPHONE_5BC26AE3=1", "JUCE_APP_VERSION=1.0.0", "JUCE_APP_VERSION_HEX=0x10000", @@ -697,6 +721,10 @@ INFOPLIST_FILE = Info-App.plist; INFOPLIST_PREPROCESS = NO; INSTALL_PATH = "$(HOME)/Applications"; + MTL_HEADER_SEARCH_PATHS = ( + "../../JuceLibraryCode", + "../../../../modules", + ); PRODUCT_BUNDLE_IDENTIFIER = com.juce.NetworkGraphicsDemo; PRODUCT_NAME = "JUCE Network Graphics Demo"; USE_HEADERMAP = NO; @@ -719,6 +747,26 @@ GCC_PREPROCESSOR_DEFINITIONS = ( "_NDEBUG=1", "NDEBUG=1", + "JUCE_CONTENT_SHARING=1", + "JUCE_DISPLAY_SPLASH_SCREEN=0", + "JUCE_USE_DARK_SPLASH_SCREEN=1", + "JUCE_PROJUCER_VERSION=0x60005", + "JUCE_MODULE_AVAILABLE_juce_audio_basics=1", + "JUCE_MODULE_AVAILABLE_juce_audio_devices=1", + "JUCE_MODULE_AVAILABLE_juce_audio_formats=1", + "JUCE_MODULE_AVAILABLE_juce_audio_processors=1", + "JUCE_MODULE_AVAILABLE_juce_audio_utils=1", + "JUCE_MODULE_AVAILABLE_juce_core=1", + "JUCE_MODULE_AVAILABLE_juce_cryptography=1", + "JUCE_MODULE_AVAILABLE_juce_data_structures=1", + "JUCE_MODULE_AVAILABLE_juce_events=1", + "JUCE_MODULE_AVAILABLE_juce_graphics=1", + "JUCE_MODULE_AVAILABLE_juce_gui_basics=1", + "JUCE_MODULE_AVAILABLE_juce_gui_extra=1", + "JUCE_MODULE_AVAILABLE_juce_opengl=1", + "JUCE_MODULE_AVAILABLE_juce_osc=1", + "JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1", + "JUCE_STANDALONE_APPLICATION=1", "JUCER_XCODE_IPHONE_5BC26AE3=1", "JUCE_APP_VERSION=1.0.0", "JUCE_APP_VERSION_HEX=0x10000", @@ -731,7 +779,6 @@ "JucePlugin_Build_Standalone=0", "JucePlugin_Build_Unity=0", ); - GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; HEADER_SEARCH_PATHS = ( "../../JuceLibraryCode", @@ -742,6 +789,10 @@ INFOPLIST_PREPROCESS = NO; INSTALL_PATH = "$(HOME)/Applications"; LLVM_LTO = YES; + MTL_HEADER_SEARCH_PATHS = ( + "../../JuceLibraryCode", + "../../../../modules", + ); PRODUCT_BUNDLE_IDENTIFIER = com.juce.NetworkGraphicsDemo; PRODUCT_NAME = "JUCE Network Graphics Demo"; USE_HEADERMAP = NO; @@ -773,11 +824,12 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; + ENABLE_TESTABILITY = NO; GCC_C_LANGUAGE_STANDARD = c11; GCC_INLINES_ARE_PRIVATE_EXTERN = YES; GCC_MODEL_TUNING = G5; GCC_NO_COMMON_BLOCKS = YES; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; @@ -823,10 +875,12 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = NO; GCC_C_LANGUAGE_STANDARD = c11; GCC_INLINES_ARE_PRIVATE_EXTERN = YES; GCC_MODEL_TUNING = G5; GCC_NO_COMMON_BLOCKS = YES; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; @@ -846,10 +900,6 @@ }; name = Release; }; - 80BE97CC38B01FABC0E73204 = { - isa = PBXTargetDependency; - target = 4311FBCBD02948A0ED96C7DD; - }; 02715337C584F3C721251428 = { isa = XCConfigurationList; buildConfigurations = ( @@ -913,12 +963,13 @@ 366A216FDEBD7BDDC1BA12D9, 1F7A8BD2B43B3D191132301D, CA694B2A73FCF12D7F9E7E49, + E29AB6243FBBDDD7BD723340, 5A64B64E5B45AEA1A0EECC4B, F918FB5901F09EA77DB32022, - 1006E2E5DFA26D7DD20BC438, A6AA70BD9364BB974CDEB337, EC14DA30C090DDC62084DB4C, F714F0C84F5945BF3539239E, + 8ECB0767EE340DD83869E37D, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -940,7 +991,7 @@ A5398ADB6F5B128C00EB935C = { isa = PBXProject; buildConfigurationList = 02715337C584F3C721251428; - attributes = { LastUpgradeCheck = 1100; ORGANIZATIONNAME = "ROLI Ltd."; TargetAttributes = { 4311FBCBD02948A0ED96C7DD = { SystemCapabilities = {com.apple.ApplicationGroups.iOS = { enabled = 0; }; com.apple.InAppPurchase = { enabled = 0; }; com.apple.InterAppAudio = { enabled = 0; }; com.apple.Push = { enabled = 0; }; com.apple.Sandbox = { enabled = 0; }; com.apple.HardenedRuntime = { enabled = 0; }; }; }; }; }; + attributes = { LastUpgradeCheck = 1200; ORGANIZATIONNAME = "Raw Material Software Limited"; TargetAttributes = { 4311FBCBD02948A0ED96C7DD = { SystemCapabilities = {com.apple.ApplicationGroups.iOS = { enabled = 0; }; com.apple.InAppPurchase = { enabled = 0; }; com.apple.InterAppAudio = { enabled = 0; }; com.apple.Push = { enabled = 0; }; com.apple.Sandbox = { enabled = 0; }; com.apple.HardenedRuntime = { enabled = 0; }; }; }; }; }; compatibilityVersion = "Xcode 3.2"; hasScannedForEncodings = 0; mainGroup = D2EB65517396C974F0415A7F; diff --git a/extras/NetworkGraphicsDemo/Builds/iOS/NetworkGraphicsDemo.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/extras/NetworkGraphicsDemo/Builds/iOS/NetworkGraphicsDemo.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings index 949b6789..f2e3cbe8 100644 --- a/extras/NetworkGraphicsDemo/Builds/iOS/NetworkGraphicsDemo.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ b/extras/NetworkGraphicsDemo/Builds/iOS/NetworkGraphicsDemo.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -4,5 +4,7 @@ <dict> <key>BuildSystemType</key> <string>Original</string> + <key>DisableBuildSystemDeprecationWarning</key> + <true/> </dict> </plist> diff --git a/extras/NetworkGraphicsDemo/CMakeLists.txt b/extras/NetworkGraphicsDemo/CMakeLists.txt new file mode 100644 index 00000000..d968b304 --- /dev/null +++ b/extras/NetworkGraphicsDemo/CMakeLists.txt @@ -0,0 +1,40 @@ +# ============================================================================== +# +# This file is part of the JUCE library. +# Copyright (c) 2020 - Raw Material Software Limited +# +# JUCE is an open source library subject to commercial or open-source +# licensing. +# +# By using JUCE, you agree to the terms of both the JUCE 6 End-User License +# Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). +# +# End User License Agreement: www.juce.com/juce-6-licence +# Privacy Policy: www.juce.com/juce-privacy-policy +# +# Or: You may also use this code under the terms of the GPL v3 (see +# www.gnu.org/licenses). +# +# JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER +# EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE +# DISCLAIMED. +# +# ============================================================================== + +juce_add_gui_app(NetworkGraphicsDemo) + +juce_generate_juce_header(NetworkGraphicsDemo) + +target_sources(NetworkGraphicsDemo PRIVATE Source/Main.cpp) + +target_compile_definitions(NetworkGraphicsDemo PRIVATE + JUCE_USE_CURL=0 JUCE_WEB_BROWSER=0) + +target_link_libraries(NetworkGraphicsDemo PRIVATE + juce::juce_audio_utils + juce::juce_cryptography + juce::juce_opengl + juce::juce_osc + juce::juce_recommended_config_flags + juce::juce_recommended_lto_flags + juce::juce_recommended_warning_flags) diff --git a/extras/NetworkGraphicsDemo/JuceLibraryCode/AppConfig.h b/extras/NetworkGraphicsDemo/JuceLibraryCode/AppConfig.h deleted file mode 100644 index 8b0ed52b..00000000 --- a/extras/NetworkGraphicsDemo/JuceLibraryCode/AppConfig.h +++ /dev/null @@ -1,284 +0,0 @@ -/* - - IMPORTANT! This file is auto-generated each time you save your - project - if you alter its contents, your changes may be overwritten! - - There's a section below where you can add your own custom code safely, and the - Projucer will preserve the contents of that block, but the best way to change - any of these definitions is by using the Projucer's project settings. - - Any commented-out settings will assume their default values. - -*/ - -#pragma once - -//============================================================================== -// [BEGIN_USER_CODE_SECTION] - -// (You can add your own code in this section, and the Projucer will not overwrite it) - -// [END_USER_CODE_SECTION] - -/* - ============================================================================== - - In accordance with the terms of the JUCE 5 End-Use License Agreement, the - JUCE Code in SECTION A cannot be removed, changed or otherwise rendered - ineffective unless you have a JUCE Indie or Pro license, or are using JUCE - under the GPL v3 license. - - End User License Agreement: www.juce.com/juce-5-licence - - ============================================================================== -*/ - -// BEGIN SECTION A - -#ifndef JUCE_DISPLAY_SPLASH_SCREEN - #define JUCE_DISPLAY_SPLASH_SCREEN 0 -#endif - -#ifndef JUCE_REPORT_APP_USAGE - #define JUCE_REPORT_APP_USAGE 0 -#endif - -// END SECTION A - -#define JUCE_USE_DARK_SPLASH_SCREEN 1 - -#define JUCE_PROJUCER_VERSION 0x50407 - -//============================================================================== -#define JUCE_MODULE_AVAILABLE_juce_audio_basics 1 -#define JUCE_MODULE_AVAILABLE_juce_audio_devices 1 -#define JUCE_MODULE_AVAILABLE_juce_audio_formats 1 -#define JUCE_MODULE_AVAILABLE_juce_audio_processors 1 -#define JUCE_MODULE_AVAILABLE_juce_audio_utils 1 -#define JUCE_MODULE_AVAILABLE_juce_core 1 -#define JUCE_MODULE_AVAILABLE_juce_cryptography 1 -#define JUCE_MODULE_AVAILABLE_juce_data_structures 1 -#define JUCE_MODULE_AVAILABLE_juce_events 1 -#define JUCE_MODULE_AVAILABLE_juce_graphics 1 -#define JUCE_MODULE_AVAILABLE_juce_gui_basics 1 -#define JUCE_MODULE_AVAILABLE_juce_gui_extra 1 -#define JUCE_MODULE_AVAILABLE_juce_opengl 1 -#define JUCE_MODULE_AVAILABLE_juce_osc 1 - -#define JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED 1 - -//============================================================================== -// juce_audio_devices flags: - -#ifndef JUCE_USE_WINRT_MIDI - //#define JUCE_USE_WINRT_MIDI 0 -#endif - -#ifndef JUCE_ASIO - //#define JUCE_ASIO 0 -#endif - -#ifndef JUCE_WASAPI - //#define JUCE_WASAPI 1 -#endif - -#ifndef JUCE_WASAPI_EXCLUSIVE - //#define JUCE_WASAPI_EXCLUSIVE 0 -#endif - -#ifndef JUCE_DIRECTSOUND - //#define JUCE_DIRECTSOUND 1 -#endif - -#ifndef JUCE_ALSA - //#define JUCE_ALSA 1 -#endif - -#ifndef JUCE_JACK - //#define JUCE_JACK 0 -#endif - -#ifndef JUCE_BELA - //#define JUCE_BELA 0 -#endif - -#ifndef JUCE_USE_ANDROID_OBOE - //#define JUCE_USE_ANDROID_OBOE 0 -#endif - -#ifndef JUCE_USE_ANDROID_OPENSLES - //#define JUCE_USE_ANDROID_OPENSLES 0 -#endif - -#ifndef JUCE_DISABLE_AUDIO_MIXING_WITH_OTHER_APPS - //#define JUCE_DISABLE_AUDIO_MIXING_WITH_OTHER_APPS 0 -#endif - -//============================================================================== -// juce_audio_formats flags: - -#ifndef JUCE_USE_FLAC - //#define JUCE_USE_FLAC 1 -#endif - -#ifndef JUCE_USE_OGGVORBIS - //#define JUCE_USE_OGGVORBIS 1 -#endif - -#ifndef JUCE_USE_MP3AUDIOFORMAT - //#define JUCE_USE_MP3AUDIOFORMAT 0 -#endif - -#ifndef JUCE_USE_LAME_AUDIO_FORMAT - //#define JUCE_USE_LAME_AUDIO_FORMAT 0 -#endif - -#ifndef JUCE_USE_WINDOWS_MEDIA_FORMAT - //#define JUCE_USE_WINDOWS_MEDIA_FORMAT 1 -#endif - -//============================================================================== -// juce_audio_processors flags: - -#ifndef JUCE_PLUGINHOST_VST - //#define JUCE_PLUGINHOST_VST 0 -#endif - -#ifndef JUCE_PLUGINHOST_VST3 - //#define JUCE_PLUGINHOST_VST3 0 -#endif - -#ifndef JUCE_PLUGINHOST_AU - //#define JUCE_PLUGINHOST_AU 0 -#endif - -#ifndef JUCE_PLUGINHOST_LADSPA - //#define JUCE_PLUGINHOST_LADSPA 0 -#endif - -//============================================================================== -// juce_audio_utils flags: - -#ifndef JUCE_USE_CDREADER - //#define JUCE_USE_CDREADER 0 -#endif - -#ifndef JUCE_USE_CDBURNER - //#define JUCE_USE_CDBURNER 0 -#endif - -//============================================================================== -// juce_core flags: - -#ifndef JUCE_FORCE_DEBUG - //#define JUCE_FORCE_DEBUG 0 -#endif - -#ifndef JUCE_LOG_ASSERTIONS - //#define JUCE_LOG_ASSERTIONS 0 -#endif - -#ifndef JUCE_CHECK_MEMORY_LEAKS - //#define JUCE_CHECK_MEMORY_LEAKS 1 -#endif - -#ifndef JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES - //#define JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES 0 -#endif - -#ifndef JUCE_INCLUDE_ZLIB_CODE - //#define JUCE_INCLUDE_ZLIB_CODE 1 -#endif - -#ifndef JUCE_USE_CURL - //#define JUCE_USE_CURL 1 -#endif - -#ifndef JUCE_LOAD_CURL_SYMBOLS_LAZILY - //#define JUCE_LOAD_CURL_SYMBOLS_LAZILY 0 -#endif - -#ifndef JUCE_CATCH_UNHANDLED_EXCEPTIONS - //#define JUCE_CATCH_UNHANDLED_EXCEPTIONS 0 -#endif - -#ifndef JUCE_ALLOW_STATIC_NULL_VARIABLES - //#define JUCE_ALLOW_STATIC_NULL_VARIABLES 0 -#endif - -#ifndef JUCE_STRICT_REFCOUNTEDPOINTER - //#define JUCE_STRICT_REFCOUNTEDPOINTER 0 -#endif - -//============================================================================== -// juce_events flags: - -#ifndef JUCE_EXECUTE_APP_SUSPEND_ON_BACKGROUND_TASK - //#define JUCE_EXECUTE_APP_SUSPEND_ON_BACKGROUND_TASK 0 -#endif - -//============================================================================== -// juce_graphics flags: - -#ifndef JUCE_USE_COREIMAGE_LOADER - //#define JUCE_USE_COREIMAGE_LOADER 1 -#endif - -#ifndef JUCE_USE_DIRECTWRITE - //#define JUCE_USE_DIRECTWRITE 1 -#endif - -#ifndef JUCE_DISABLE_COREGRAPHICS_FONT_SMOOTHING - //#define JUCE_DISABLE_COREGRAPHICS_FONT_SMOOTHING 0 -#endif - -//============================================================================== -// juce_gui_basics flags: - -#ifndef JUCE_ENABLE_REPAINT_DEBUGGING - //#define JUCE_ENABLE_REPAINT_DEBUGGING 0 -#endif - -#ifndef JUCE_USE_XRANDR - //#define JUCE_USE_XRANDR 1 -#endif - -#ifndef JUCE_USE_XINERAMA - //#define JUCE_USE_XINERAMA 1 -#endif - -#ifndef JUCE_USE_XSHM - //#define JUCE_USE_XSHM 1 -#endif - -#ifndef JUCE_USE_XRENDER - //#define JUCE_USE_XRENDER 0 -#endif - -#ifndef JUCE_USE_XCURSOR - //#define JUCE_USE_XCURSOR 1 -#endif - -#ifndef JUCE_WIN_PER_MONITOR_DPI_AWARE - //#define JUCE_WIN_PER_MONITOR_DPI_AWARE 1 -#endif - -//============================================================================== -// juce_gui_extra flags: - -#ifndef JUCE_WEB_BROWSER - //#define JUCE_WEB_BROWSER 1 -#endif - -#ifndef JUCE_ENABLE_LIVE_CONSTANT_EDITOR - //#define JUCE_ENABLE_LIVE_CONSTANT_EDITOR 0 -#endif - -//============================================================================== -#ifndef JUCE_STANDALONE_APPLICATION - #if defined(JucePlugin_Name) && defined(JucePlugin_Build_Standalone) - #define JUCE_STANDALONE_APPLICATION JucePlugin_Build_Standalone - #else - #define JUCE_STANDALONE_APPLICATION 1 - #endif -#endif diff --git a/extras/NetworkGraphicsDemo/JuceLibraryCode/JuceHeader.h b/extras/NetworkGraphicsDemo/JuceLibraryCode/JuceHeader.h index e7443e58..07833451 100644 --- a/extras/NetworkGraphicsDemo/JuceLibraryCode/JuceHeader.h +++ b/extras/NetworkGraphicsDemo/JuceLibraryCode/JuceHeader.h @@ -12,7 +12,6 @@ #pragma once -#include "AppConfig.h" #include <juce_audio_basics/juce_audio_basics.h> #include <juce_audio_devices/juce_audio_devices.h> @@ -50,7 +49,7 @@ namespace ProjectInfo { const char* const projectName = "NetworkGraphicsDemo"; - const char* const companyName = "ROLI Ltd."; + const char* const companyName = "Raw Material Software Limited"; const char* const versionString = "1.0.0"; const int versionNumber = 0x10000; } diff --git a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_audio_basics.cpp b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_audio_basics.cpp index 41869487..e5c3ae92 100644 --- a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_audio_basics.cpp +++ b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_audio_basics.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_basics/juce_audio_basics.cpp> diff --git a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_audio_basics.mm b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_audio_basics.mm index e0e6c577..c7f36c64 100644 --- a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_audio_basics.mm +++ b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_audio_basics.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_basics/juce_audio_basics.mm> diff --git a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_audio_devices.cpp b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_audio_devices.cpp index fb5c2219..29b774fd 100644 --- a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_audio_devices.cpp +++ b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_audio_devices.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_devices/juce_audio_devices.cpp> diff --git a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_audio_devices.mm b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_audio_devices.mm index e58b67ea..287da26e 100644 --- a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_audio_devices.mm +++ b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_audio_devices.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_devices/juce_audio_devices.mm> diff --git a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_audio_formats.cpp b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_audio_formats.cpp index a3c61170..8dac3325 100644 --- a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_audio_formats.cpp +++ b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_audio_formats.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_formats/juce_audio_formats.cpp> diff --git a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_audio_formats.mm b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_audio_formats.mm index f325b8fb..79e6a22f 100644 --- a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_audio_formats.mm +++ b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_audio_formats.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_formats/juce_audio_formats.mm> diff --git a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_audio_processors.cpp b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_audio_processors.cpp index bfe172ed..217d330a 100644 --- a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_audio_processors.cpp +++ b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_audio_processors.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_processors/juce_audio_processors.cpp> diff --git a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_audio_processors.mm b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_audio_processors.mm index b80ae901..1f7cc419 100644 --- a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_audio_processors.mm +++ b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_audio_processors.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_processors/juce_audio_processors.mm> diff --git a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_audio_utils.cpp b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_audio_utils.cpp index 97bd2c56..046bf31d 100644 --- a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_audio_utils.cpp +++ b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_audio_utils.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_utils/juce_audio_utils.cpp> diff --git a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_audio_utils.mm b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_audio_utils.mm index 8eae7c6e..a3f746dc 100644 --- a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_audio_utils.mm +++ b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_audio_utils.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_utils/juce_audio_utils.mm> diff --git a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_core.cpp b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_core.cpp index d0ce1636..84fe988c 100644 --- a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_core.cpp +++ b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_core.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_core/juce_core.cpp> diff --git a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_core.mm b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_core.mm index 72b10bf8..9ee67bf6 100644 --- a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_core.mm +++ b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_core.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_core/juce_core.mm> diff --git a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_cryptography.cpp b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_cryptography.cpp index 10b3401d..ee7d9085 100644 --- a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_cryptography.cpp +++ b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_cryptography.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_cryptography/juce_cryptography.cpp> diff --git a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_cryptography.mm b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_cryptography.mm index 9311ea0f..03ee05f4 100644 --- a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_cryptography.mm +++ b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_cryptography.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_cryptography/juce_cryptography.mm> diff --git a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_data_structures.cpp b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_data_structures.cpp index 9315aa16..152980ae 100644 --- a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_data_structures.cpp +++ b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_data_structures.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_data_structures/juce_data_structures.cpp> diff --git a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_data_structures.mm b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_data_structures.mm index 695ec439..02b9711c 100644 --- a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_data_structures.mm +++ b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_data_structures.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_data_structures/juce_data_structures.mm> diff --git a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_events.cpp b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_events.cpp index 1bba110a..39268e2b 100644 --- a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_events.cpp +++ b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_events.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_events/juce_events.cpp> diff --git a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_events.mm b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_events.mm index 4cc34fc4..191a9987 100644 --- a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_events.mm +++ b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_events.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_events/juce_events.mm> diff --git a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_graphics.cpp b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_graphics.cpp index 319c76de..8ccabef9 100644 --- a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_graphics.cpp +++ b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_graphics.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_graphics/juce_graphics.cpp> diff --git a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_graphics.mm b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_graphics.mm index b28e6dd0..6bb7456d 100644 --- a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_graphics.mm +++ b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_graphics.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_graphics/juce_graphics.mm> diff --git a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_gui_basics.cpp b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_gui_basics.cpp index 216c76bb..71d04b24 100644 --- a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_gui_basics.cpp +++ b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_gui_basics.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_gui_basics/juce_gui_basics.cpp> diff --git a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_gui_basics.mm b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_gui_basics.mm index 6a9726fa..e449e0b7 100644 --- a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_gui_basics.mm +++ b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_gui_basics.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_gui_basics/juce_gui_basics.mm> diff --git a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_gui_extra.cpp b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_gui_extra.cpp index 7226e198..a33ece00 100644 --- a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_gui_extra.cpp +++ b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_gui_extra.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_gui_extra/juce_gui_extra.cpp> diff --git a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_gui_extra.mm b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_gui_extra.mm index c9b6c3bf..6dacee3a 100644 --- a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_gui_extra.mm +++ b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_gui_extra.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_gui_extra/juce_gui_extra.mm> diff --git a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_opengl.cpp b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_opengl.cpp index d9895bce..e6541a42 100644 --- a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_opengl.cpp +++ b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_opengl.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_opengl/juce_opengl.cpp> diff --git a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_opengl.mm b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_opengl.mm index 6c2c32d0..793619ea 100644 --- a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_opengl.mm +++ b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_opengl.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_opengl/juce_opengl.mm> diff --git a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_osc.cpp b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_osc.cpp index 0c3b9ae9..7eadead5 100644 --- a/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_osc.cpp +++ b/extras/NetworkGraphicsDemo/JuceLibraryCode/include_juce_osc.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_osc/juce_osc.cpp> diff --git a/extras/NetworkGraphicsDemo/NetworkGraphicsDemo.jucer b/extras/NetworkGraphicsDemo/NetworkGraphicsDemo.jucer index f9a08d9e..929a883b 100644 --- a/extras/NetworkGraphicsDemo/NetworkGraphicsDemo.jucer +++ b/extras/NetworkGraphicsDemo/NetworkGraphicsDemo.jucer @@ -1,8 +1,9 @@ <?xml version="1.0" encoding="UTF-8"?> <JUCERPROJECT id="gWI5Ir" name="NetworkGraphicsDemo" projectType="guiapp" bundleIdentifier="com.juce.NetworkGraphicsDemo" - jucerVersion="5.4.7" displaySplashScreen="0" reportAppUsage="0" - companyName="ROLI Ltd." companyCopyright="ROLI Ltd."> + displaySplashScreen="0" reportAppUsage="0" companyName="Raw Material Software Limited" + companyCopyright="Raw Material Software Limited" useAppConfig="0" + addUsingNamespaceToJuceHeader="1" jucerFormatVersion="1"> <MAINGROUP id="OT9rJ2" name="NetworkGraphicsDemo"> <GROUP id="{48D54E6E-37F4-B20A-E038-C63E4EDFD4D9}" name="Source"> <FILE id="BfclEZ" name="Demos.h" compile="0" resource="0" file="Source/Demos.h"/> @@ -84,8 +85,8 @@ </XCODE_IPHONE> <LINUX_MAKE targetFolder="Builds/LinuxMakefile" bigIcon="Ww6bQw"> <CONFIGURATIONS> - <CONFIGURATION name="Debug" libraryPath="/usr/X11R6/lib/" isDebug="1" targetName="JUCE Network Graphics Demo"/> - <CONFIGURATION name="Release" libraryPath="/usr/X11R6/lib/" isDebug="0" targetName="JUCE Network Graphics Demo"/> + <CONFIGURATION name="Debug" isDebug="1" targetName="JUCE Network Graphics Demo"/> + <CONFIGURATION name="Release" isDebug="0" targetName="JUCE Network Graphics Demo"/> </CONFIGURATIONS> <MODULEPATHS> <MODULEPATH id="juce_osc" path="../../modules"/> diff --git a/extras/NetworkGraphicsDemo/Source/Demos.h b/extras/NetworkGraphicsDemo/Source/Demos.h index e9c0dcfc..1c759b5e 100644 --- a/extras/NetworkGraphicsDemo/Source/Demos.h +++ b/extras/NetworkGraphicsDemo/Source/Demos.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -91,7 +90,7 @@ struct BackgroundLogo : public AnimatedContent void reset() override {} void handleTouch (Point<float>) override {} - void generateCanvas (Graphics& g, SharedCanvasDescription& canvas, Rectangle<float> activeArea) override + void generateCanvas (Graphics& g, SharedCanvasDescription& canvas, Rectangle<float>) override { logo->drawWithin (g, canvas.getLimits().reduced (3.0f), RectanglePlacement (RectanglePlacement::centred), 0.6f); } @@ -473,7 +472,7 @@ struct MultiLogo : public BackgroundLogo { String getName() const override { return "Multi-Logo " + String ((int) numHorizontalLogos); } - void generateCanvas (Graphics& g, SharedCanvasDescription& canvas, Rectangle<float> activeArea) override + void generateCanvas (Graphics& g, SharedCanvasDescription& canvas, Rectangle<float>) override { float indent = 0.5f; float logoSize = canvas.getLimits().getWidth() / numHorizontalLogos; diff --git a/extras/NetworkGraphicsDemo/Source/Main.cpp b/extras/NetworkGraphicsDemo/Source/Main.cpp index 07298d41..c055dc78 100644 --- a/extras/NetworkGraphicsDemo/Source/Main.cpp +++ b/extras/NetworkGraphicsDemo/Source/Main.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -39,7 +38,7 @@ namespace static const String canvasStateOSCAddress = "/juce/nfd/canvasState"; static const String newClientOSCAddress = "/juce/nfd/newClient"; static const String userInputOSCAddress = "/juce/nfd/userInput"; -}; +} #include "SharedCanvas.h" #include "SlaveComponent.h" @@ -92,7 +91,7 @@ public: //============================================================================== struct MainWindow : public DocumentWindow { - MainWindow (PropertiesFile& props) + explicit MainWindow (PropertiesFile& props) : DocumentWindow ("JUCE Networked Graphics Demo - Master", Colours::white, DocumentWindow::allButtons) { setUsingNativeTitleBar (true); @@ -122,7 +121,7 @@ public: #endif } - ~MainWindow() + ~MainWindow() override { glContext.detach(); } diff --git a/extras/NetworkGraphicsDemo/Source/MasterComponent.h b/extras/NetworkGraphicsDemo/Source/MasterComponent.h index 8464f669..12cad9ed 100644 --- a/extras/NetworkGraphicsDemo/Source/MasterComponent.h +++ b/extras/NetworkGraphicsDemo/Source/MasterComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -56,7 +55,7 @@ struct MasterContentComponent : public Component, startTimerHz (30); } - ~MasterContentComponent() + ~MasterContentComponent() override { OSCReceiver::removeListener (this); } @@ -257,8 +256,8 @@ private: { auto total = currentCanvas.getLimits(); - return { getWidth() * (p.x - total.getX()) / total.getWidth(), - getHeight() * (p.y - total.getY()) / total.getHeight() }; + return { (float) getWidth() * (p.x - total.getX()) / total.getWidth(), + (float) getHeight() * (p.y - total.getY()) / total.getHeight() }; } Rectangle<float> virtualSpaceToLocal (Rectangle<float> p) const @@ -271,8 +270,8 @@ private: { auto total = currentCanvas.getLimits(); - return { total.getX() + total.getWidth() * (p.x / getWidth()), - total.getY() + total.getHeight() * (p.y / getHeight()) }; + return { total.getX() + total.getWidth() * (p.x / (float) getWidth()), + total.getY() + total.getHeight() * (p.y / (float) getHeight()) }; } //============================================================================== diff --git a/extras/NetworkGraphicsDemo/Source/SharedCanvas.h b/extras/NetworkGraphicsDemo/Source/SharedCanvas.h index 5688c7bb..cdeb6343 100644 --- a/extras/NetworkGraphicsDemo/Source/SharedCanvas.h +++ b/extras/NetworkGraphicsDemo/Source/SharedCanvas.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -455,9 +454,9 @@ struct BlockPacketiser while (remaining > 0) { - auto num = (int) jmin (maxBlockSize, remaining); - blocks.add (MemoryBlock (addBytesToPointer (data.getData(), offset), (size_t) num)); - offset += num; + auto num = (size_t) jmin (maxBlockSize, remaining); + blocks.add (MemoryBlock (addBytesToPointer (data.getData(), offset), num)); + offset += (int) num; remaining -= num; } @@ -467,7 +466,7 @@ struct BlockPacketiser for (int i = 0; i < blocks.size(); ++i) { - uint32 index = ByteOrder::swapIfBigEndian (i); + auto index = (uint32) ByteOrder::swapIfBigEndian (i); blocks.getReference(i).append (&index, sizeof (index)); } } @@ -505,9 +504,9 @@ struct BlockPacketiser static int compareElements (const MemoryBlock& b1, const MemoryBlock& b2) { - int i1 = ByteOrder::littleEndianInt (addBytesToPointer (b1.getData(), b1.getSize() - 4)); - int i2 = ByteOrder::littleEndianInt (addBytesToPointer (b2.getData(), b2.getSize() - 4)); - return i1 - i2; + auto i1 = ByteOrder::littleEndianInt (addBytesToPointer (b1.getData(), b1.getSize() - 4)); + auto i2 = ByteOrder::littleEndianInt (addBytesToPointer (b2.getData(), b2.getSize() - 4)); + return (int) (i1 - i2); } static const char* getLastPacketPrefix() { return "**END_OF_PACKET_LIST** "; } diff --git a/extras/NetworkGraphicsDemo/Source/SlaveComponent.h b/extras/NetworkGraphicsDemo/Source/SlaveComponent.h index be00993b..4d185215 100644 --- a/extras/NetworkGraphicsDemo/Source/SlaveComponent.h +++ b/extras/NetworkGraphicsDemo/Source/SlaveComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -66,7 +65,7 @@ public: startTimer (2000); } - ~SlaveCanvasComponent() + ~SlaveCanvasComponent() override { OSCReceiver::removeListener (this); } @@ -81,8 +80,8 @@ private: OSCMessage message (userInputOSCAddress); message.addString (clientName); - message.addFloat32 (e.position.x * clientArea.getWidth() / getWidth() + clientArea.getX()); - message.addFloat32 (e.position.y * clientArea.getHeight() / getHeight() + clientArea.getY()); + message.addFloat32 (e.position.x * clientArea.getWidth() / (float) getWidth() + clientArea.getX()); + message.addFloat32 (e.position.y * clientArea.getHeight() / (float) getHeight() + clientArea.getY()); send (message); } @@ -126,8 +125,8 @@ private: //============================================================================== String getMachineInfoToDisplay() const { - auto display = Desktop::getInstance().getDisplays().findDisplayForPoint (getScreenBounds().getCentre()); - return getOSName() + " " + String (display.dpi) + " " + String (display.scale); + auto* display = Desktop::getInstance().getDisplays().getDisplayForPoint (getScreenBounds().getCentre()); + return getOSName() + " " + String (display->dpi) + " " + String (display->scale); } static String getOSName() @@ -181,8 +180,8 @@ private: if (auto client = canvas.findClient (clientName)) { auto screenBounds = getScreenBounds(); - auto display = Desktop::getInstance().getDisplays().findDisplayForPoint (screenBounds.getCentre()); - return ((screenBounds - display.userArea.getCentre()).toFloat() / (client->scaleFactor * display.dpi / display.scale)) + client->centre; + auto* display = Desktop::getInstance().getDisplays().getDisplayForPoint (screenBounds.getCentre()); + return ((screenBounds - display->userArea.getCentre()).toFloat() / (client->scaleFactor * display->dpi / display->scale)) + client->centre; } return {}; @@ -192,8 +191,8 @@ private: { if (auto client = canvas.findClient (clientName)) { - auto display = Desktop::getInstance().getDisplays().findDisplayForPoint (getScreenBounds().getCentre()); - return (display.userArea.toFloat() / (client->scaleFactor * display.dpi / display.scale)).withCentre (client->centre); + auto* display = Desktop::getInstance().getDisplays().getDisplayForPoint (getScreenBounds().getCentre()); + return (display->userArea.toFloat() / (client->scaleFactor * display->dpi / display->scale)).withCentre (client->centre); } return {}; diff --git a/extras/Projucer/Builds/LinuxMakefile/Makefile b/extras/Projucer/Builds/LinuxMakefile/Makefile index 65fd56aa..00638ef5 100644 --- a/extras/Projucer/Builds/LinuxMakefile/Makefile +++ b/extras/Projucer/Builds/LinuxMakefile/Makefile @@ -35,13 +35,13 @@ ifeq ($(CONFIG),Debug) TARGET_ARCH := endif - JUCE_CPPFLAGS := $(DEPFLAGS) -DLINUX=1 -DDEBUG=1 -D_DEBUG=1 -DJUCER_LINUX_MAKE_6D53C8B4=1 -DJUCE_APP_VERSION=5.4.7 -DJUCE_APP_VERSION_HEX=0x50407 $(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_CPPFLAGS := $(DEPFLAGS) "-DLINUX=1" "-DDEBUG=1" "-D_DEBUG=1" "-DJUCE_DISPLAY_SPLASH_SCREEN=0" "-DJUCE_USE_DARK_SPLASH_SCREEN=1" "-DJUCE_PROJUCER_VERSION=0x60005" "-DJUCE_MODULE_AVAILABLE_juce_build_tools=1" "-DJUCE_MODULE_AVAILABLE_juce_core=1" "-DJUCE_MODULE_AVAILABLE_juce_cryptography=1" "-DJUCE_MODULE_AVAILABLE_juce_data_structures=1" "-DJUCE_MODULE_AVAILABLE_juce_events=1" "-DJUCE_MODULE_AVAILABLE_juce_graphics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_extra=1" "-DJUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1" "-DJUCE_LOG_ASSERTIONS=1" "-DJUCE_USE_CURL=1" "-DJUCE_LOAD_CURL_SYMBOLS_LAZILY=1" "-DJUCE_ALLOW_STATIC_NULL_VARIABLES=0" "-DJUCE_STRICT_REFCOUNTEDPOINTER=1" "-DJUCE_WEB_BROWSER=0" "-DJUCE_STANDALONE_APPLICATION=1" "-DJUCER_LINUX_MAKE_6D53C8B4=1" "-DJUCE_APP_VERSION=6.0.5" "-DJUCE_APP_VERSION_HEX=0x60005" $(shell pkg-config --cflags freetype2) -pthread -I../../JuceLibraryCode -I../../../Build -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 JUCE_CFLAGS += $(JUCE_CPPFLAGS) $(TARGET_ARCH) -g -ggdb -O0 $(CFLAGS) JUCE_CXXFLAGS += $(JUCE_CFLAGS) -std=c++11 $(CXXFLAGS) - JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) $(shell pkg-config --libs x11 xinerama xext freetype2 webkit2gtk-4.0 gtk+-x11-3.0) -lrt -ldl -lpthread $(LDFLAGS) + JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) $(shell pkg-config --libs freetype2) -fvisibility=hidden -lrt -ldl -lpthread $(LDFLAGS) CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(TARGET) $(JUCE_OBJDIR) endif @@ -56,23 +56,24 @@ ifeq ($(CONFIG),Release) TARGET_ARCH := endif - JUCE_CPPFLAGS := $(DEPFLAGS) -DLINUX=1 -DNDEBUG=1 -DJUCER_LINUX_MAKE_6D53C8B4=1 -DJUCE_APP_VERSION=5.4.7 -DJUCE_APP_VERSION_HEX=0x50407 $(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_CPPFLAGS := $(DEPFLAGS) "-DLINUX=1" "-DNDEBUG=1" "-DJUCE_DISPLAY_SPLASH_SCREEN=0" "-DJUCE_USE_DARK_SPLASH_SCREEN=1" "-DJUCE_PROJUCER_VERSION=0x60005" "-DJUCE_MODULE_AVAILABLE_juce_build_tools=1" "-DJUCE_MODULE_AVAILABLE_juce_core=1" "-DJUCE_MODULE_AVAILABLE_juce_cryptography=1" "-DJUCE_MODULE_AVAILABLE_juce_data_structures=1" "-DJUCE_MODULE_AVAILABLE_juce_events=1" "-DJUCE_MODULE_AVAILABLE_juce_graphics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_extra=1" "-DJUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1" "-DJUCE_LOG_ASSERTIONS=1" "-DJUCE_USE_CURL=1" "-DJUCE_LOAD_CURL_SYMBOLS_LAZILY=1" "-DJUCE_ALLOW_STATIC_NULL_VARIABLES=0" "-DJUCE_STRICT_REFCOUNTEDPOINTER=1" "-DJUCE_WEB_BROWSER=0" "-DJUCE_STANDALONE_APPLICATION=1" "-DJUCER_LINUX_MAKE_6D53C8B4=1" "-DJUCE_APP_VERSION=6.0.5" "-DJUCE_APP_VERSION_HEX=0x60005" $(shell pkg-config --cflags freetype2) -pthread -I../../JuceLibraryCode -I../../../Build -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 JUCE_CFLAGS += $(JUCE_CPPFLAGS) $(TARGET_ARCH) -O3 $(CFLAGS) JUCE_CXXFLAGS += $(JUCE_CFLAGS) -std=c++11 $(CXXFLAGS) - JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) $(shell pkg-config --libs x11 xinerama xext freetype2 webkit2gtk-4.0 gtk+-x11-3.0) -fvisibility=hidden -lrt -ldl -lpthread $(LDFLAGS) + JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) $(shell pkg-config --libs freetype2) -fvisibility=hidden -lrt -ldl -lpthread $(LDFLAGS) CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(TARGET) $(JUCE_OBJDIR) endif OBJECTS_APP := \ + $(JUCE_OBJDIR)/jucer_NewProjectWizard_7817a7e4.o \ + $(JUCE_OBJDIR)/jucer_StartPageComponent_de6b22ec.o \ $(JUCE_OBJDIR)/jucer_AutoUpdater_ca658dc2.o \ $(JUCE_OBJDIR)/jucer_CommandLine_f35de107.o \ $(JUCE_OBJDIR)/jucer_Main_f8488f5b.o \ $(JUCE_OBJDIR)/jucer_MainWindow_1e163aeb.o \ - $(JUCE_OBJDIR)/jucer_ProjucerAnalytics_5740f336.o \ $(JUCE_OBJDIR)/jucer_DocumentEditorComponent_bc853a2f.o \ $(JUCE_OBJDIR)/jucer_OpenDocumentManager_ba866622.o \ $(JUCE_OBJDIR)/jucer_SourceCodeEditor_55965985.o \ @@ -98,12 +99,11 @@ OBJECTS_APP := \ $(JUCE_OBJDIR)/jucer_JucerDocument_ff8afcc2.o \ $(JUCE_OBJDIR)/jucer_ObjectTypes_4406f01c.o \ $(JUCE_OBJDIR)/jucer_PaintRoutine_e1e891ee.o \ - $(JUCE_OBJDIR)/jucer_LicenseController_9abff0cf.o \ $(JUCE_OBJDIR)/jucer_CompileEngineClient_aee8c99c.o \ $(JUCE_OBJDIR)/jucer_CompileEngineServer_5d8914.o \ $(JUCE_OBJDIR)/jucer_DownloadCompileEngineThread_19bb4bb3.o \ + $(JUCE_OBJDIR)/jucer_Modules_e20cbd10.o \ $(JUCE_OBJDIR)/jucer_HeaderComponent_1ebf72ba.o \ - $(JUCE_OBJDIR)/jucer_Module_3f7666a5.o \ $(JUCE_OBJDIR)/jucer_Project_c131864a.o \ $(JUCE_OBJDIR)/jucer_ProjectExporter_cf377b25.o \ $(JUCE_OBJDIR)/jucer_ProjectSaver_4276639b.o \ @@ -113,16 +113,15 @@ OBJECTS_APP := \ $(JUCE_OBJDIR)/jucer_CodeHelpers_1e797672.o \ $(JUCE_OBJDIR)/jucer_FileHelpers_54f12f83.o \ $(JUCE_OBJDIR)/jucer_MiscUtilities_31fc8dd8.o \ + $(JUCE_OBJDIR)/jucer_NewFileWizard_b233dda1.o \ $(JUCE_OBJDIR)/jucer_VersionInfo_46f3ed40.o \ $(JUCE_OBJDIR)/jucer_PIPGenerator_fd3402c7.o \ $(JUCE_OBJDIR)/jucer_Icons_d02d18f1.o \ $(JUCE_OBJDIR)/jucer_JucerTreeViewBase_9b9f2ff0.o \ $(JUCE_OBJDIR)/jucer_ProjucerLookAndFeel_3b20291d.o \ $(JUCE_OBJDIR)/jucer_SlidingPanelComponent_4e7dc07e.o \ - $(JUCE_OBJDIR)/jucer_NewFileWizard_fac97f47.o \ - $(JUCE_OBJDIR)/jucer_NewProjectWizardClasses_891f6fa2.o \ $(JUCE_OBJDIR)/BinaryData_ce4232d4.o \ - $(JUCE_OBJDIR)/include_juce_analytics_f8e9fa94.o \ + $(JUCE_OBJDIR)/include_juce_build_tools_f5069398.o \ $(JUCE_OBJDIR)/include_juce_core_f26d17db.o \ $(JUCE_OBJDIR)/include_juce_cryptography_8cb807a8.o \ $(JUCE_OBJDIR)/include_juce_data_structures_7471b1e3.o \ @@ -137,13 +136,23 @@ all : $(JUCE_OUTDIR)/$(JUCE_TARGET_APP) $(JUCE_OUTDIR)/$(JUCE_TARGET_APP) : $(OBJECTS_APP) $(RESOURCES) @command -v pkg-config >/dev/null 2>&1 || { echo >&2 "pkg-config not installed. Please, install it."; exit 1; } - @pkg-config --print-errors x11 xinerama xext freetype2 webkit2gtk-4.0 gtk+-x11-3.0 + @pkg-config --print-errors freetype2 @echo Linking "Projucer - App" -$(V_AT)mkdir -p $(JUCE_BINDIR) -$(V_AT)mkdir -p $(JUCE_LIBDIR) -$(V_AT)mkdir -p $(JUCE_OUTDIR) $(V_AT)$(CXX) -o $(JUCE_OUTDIR)/$(JUCE_TARGET_APP) $(OBJECTS_APP) $(JUCE_LDFLAGS) $(JUCE_LDFLAGS_APP) $(RESOURCES) $(TARGET_ARCH) +$(JUCE_OBJDIR)/jucer_NewProjectWizard_7817a7e4.o: ../../Source/Application/StartPage/jucer_NewProjectWizard.cpp + -$(V_AT)mkdir -p $(JUCE_OBJDIR) + @echo "Compiling jucer_NewProjectWizard.cpp" + $(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<" + +$(JUCE_OBJDIR)/jucer_StartPageComponent_de6b22ec.o: ../../Source/Application/StartPage/jucer_StartPageComponent.cpp + -$(V_AT)mkdir -p $(JUCE_OBJDIR) + @echo "Compiling jucer_StartPageComponent.cpp" + $(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<" + $(JUCE_OBJDIR)/jucer_AutoUpdater_ca658dc2.o: ../../Source/Application/jucer_AutoUpdater.cpp -$(V_AT)mkdir -p $(JUCE_OBJDIR) @echo "Compiling jucer_AutoUpdater.cpp" @@ -164,11 +173,6 @@ $(JUCE_OBJDIR)/jucer_MainWindow_1e163aeb.o: ../../Source/Application/jucer_MainW @echo "Compiling jucer_MainWindow.cpp" $(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<" -$(JUCE_OBJDIR)/jucer_ProjucerAnalytics_5740f336.o: ../../Source/Application/jucer_ProjucerAnalytics.cpp - -$(V_AT)mkdir -p $(JUCE_OBJDIR) - @echo "Compiling jucer_ProjucerAnalytics.cpp" - $(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<" - $(JUCE_OBJDIR)/jucer_DocumentEditorComponent_bc853a2f.o: ../../Source/CodeEditor/jucer_DocumentEditorComponent.cpp -$(V_AT)mkdir -p $(JUCE_OBJDIR) @echo "Compiling jucer_DocumentEditorComponent.cpp" @@ -294,11 +298,6 @@ $(JUCE_OBJDIR)/jucer_PaintRoutine_e1e891ee.o: ../../Source/ComponentEditor/jucer @echo "Compiling jucer_PaintRoutine.cpp" $(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<" -$(JUCE_OBJDIR)/jucer_LicenseController_9abff0cf.o: ../../Source/Licenses/jucer_LicenseController.cpp - -$(V_AT)mkdir -p $(JUCE_OBJDIR) - @echo "Compiling jucer_LicenseController.cpp" - $(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<" - $(JUCE_OBJDIR)/jucer_CompileEngineClient_aee8c99c.o: ../../Source/LiveBuildEngine/jucer_CompileEngineClient.cpp -$(V_AT)mkdir -p $(JUCE_OBJDIR) @echo "Compiling jucer_CompileEngineClient.cpp" @@ -314,14 +313,14 @@ $(JUCE_OBJDIR)/jucer_DownloadCompileEngineThread_19bb4bb3.o: ../../Source/LiveBu @echo "Compiling jucer_DownloadCompileEngineThread.cpp" $(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<" -$(JUCE_OBJDIR)/jucer_HeaderComponent_1ebf72ba.o: ../../Source/Project/UI/jucer_HeaderComponent.cpp +$(JUCE_OBJDIR)/jucer_Modules_e20cbd10.o: ../../Source/Project/Modules/jucer_Modules.cpp -$(V_AT)mkdir -p $(JUCE_OBJDIR) - @echo "Compiling jucer_HeaderComponent.cpp" + @echo "Compiling jucer_Modules.cpp" $(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<" -$(JUCE_OBJDIR)/jucer_Module_3f7666a5.o: ../../Source/Project/jucer_Module.cpp +$(JUCE_OBJDIR)/jucer_HeaderComponent_1ebf72ba.o: ../../Source/Project/UI/jucer_HeaderComponent.cpp -$(V_AT)mkdir -p $(JUCE_OBJDIR) - @echo "Compiling jucer_Module.cpp" + @echo "Compiling jucer_HeaderComponent.cpp" $(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<" $(JUCE_OBJDIR)/jucer_Project_c131864a.o: ../../Source/Project/jucer_Project.cpp @@ -369,6 +368,11 @@ $(JUCE_OBJDIR)/jucer_MiscUtilities_31fc8dd8.o: ../../Source/Utility/Helpers/juce @echo "Compiling jucer_MiscUtilities.cpp" $(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<" +$(JUCE_OBJDIR)/jucer_NewFileWizard_b233dda1.o: ../../Source/Utility/Helpers/jucer_NewFileWizard.cpp + -$(V_AT)mkdir -p $(JUCE_OBJDIR) + @echo "Compiling jucer_NewFileWizard.cpp" + $(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<" + $(JUCE_OBJDIR)/jucer_VersionInfo_46f3ed40.o: ../../Source/Utility/Helpers/jucer_VersionInfo.cpp -$(V_AT)mkdir -p $(JUCE_OBJDIR) @echo "Compiling jucer_VersionInfo.cpp" @@ -399,24 +403,14 @@ $(JUCE_OBJDIR)/jucer_SlidingPanelComponent_4e7dc07e.o: ../../Source/Utility/UI/j @echo "Compiling jucer_SlidingPanelComponent.cpp" $(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<" -$(JUCE_OBJDIR)/jucer_NewFileWizard_fac97f47.o: ../../Source/Wizards/jucer_NewFileWizard.cpp - -$(V_AT)mkdir -p $(JUCE_OBJDIR) - @echo "Compiling jucer_NewFileWizard.cpp" - $(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<" - -$(JUCE_OBJDIR)/jucer_NewProjectWizardClasses_891f6fa2.o: ../../Source/Wizards/jucer_NewProjectWizardClasses.cpp - -$(V_AT)mkdir -p $(JUCE_OBJDIR) - @echo "Compiling jucer_NewProjectWizardClasses.cpp" - $(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<" - $(JUCE_OBJDIR)/BinaryData_ce4232d4.o: ../../JuceLibraryCode/BinaryData.cpp -$(V_AT)mkdir -p $(JUCE_OBJDIR) @echo "Compiling BinaryData.cpp" $(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<" -$(JUCE_OBJDIR)/include_juce_analytics_f8e9fa94.o: ../../JuceLibraryCode/include_juce_analytics.cpp +$(JUCE_OBJDIR)/include_juce_build_tools_f5069398.o: ../../JuceLibraryCode/include_juce_build_tools.cpp -$(V_AT)mkdir -p $(JUCE_OBJDIR) - @echo "Compiling include_juce_analytics.cpp" + @echo "Compiling include_juce_build_tools.cpp" $(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<" $(JUCE_OBJDIR)/include_juce_core_f26d17db.o: ../../JuceLibraryCode/include_juce_core.cpp diff --git a/extras/Projucer/Builds/MacOSX/App.entitlements b/extras/Projucer/Builds/MacOSX/App.entitlements deleted file mode 100644 index 6631ffa6..00000000 --- a/extras/Projucer/Builds/MacOSX/App.entitlements +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> -</dict> -</plist> diff --git a/extras/Projucer/Builds/MacOSX/Icon.icns b/extras/Projucer/Builds/MacOSX/Icon.icns index 64566582b2fa7109c5409816ee0cbb78564cd94a..6ab6915802b8cc41702a02e8527aec517d379e77 100644 GIT binary patch delta 23 ccmZ2}kLlPRR*uZ%ykZ8%IJb=)^6Nnu0BpAicK`qY delta 19 bcmX@MhjsZqCXUSHykZ81_39fr<ktfLPI3n! diff --git a/extras/Projucer/Builds/MacOSX/Info-App.plist b/extras/Projucer/Builds/MacOSX/Info-App.plist index 90b42330..f4f845eb 100644 --- a/extras/Projucer/Builds/MacOSX/Info-App.plist +++ b/extras/Projucer/Builds/MacOSX/Info-App.plist @@ -22,11 +22,11 @@ <key>CFBundleSignature</key> <string>????</string> <key>CFBundleShortVersionString</key> - <string>5.4.7</string> + <string>6.0.5</string> <key>CFBundleVersion</key> - <string>5.4.7</string> + <string>6.0.5</string> <key>NSHumanReadableCopyright</key> - <string>ROLI Ltd.</string> + <string>Raw Material Software Limited</string> <key>NSHighResolutionCapable</key> <true/> <key>CFBundleDocumentTypes</key> diff --git a/extras/Projucer/Builds/MacOSX/Projucer.xcodeproj/project.pbxproj b/extras/Projucer/Builds/MacOSX/Projucer.xcodeproj/project.pbxproj index 94c16df9..8f94d1a6 100644 --- a/extras/Projucer/Builds/MacOSX/Projucer.xcodeproj/project.pbxproj +++ b/extras/Projucer/Builds/MacOSX/Projucer.xcodeproj/project.pbxproj @@ -49,6 +49,10 @@ isa = PBXBuildFile; fileRef = 842427CFE565F3FCE5B99174; }; + DD0FF38F7E8DE0220D73671D = { + isa = PBXBuildFile; + fileRef = BF006EF584FB274FF0319E08; + }; 49C22786B54C5DC94E4654B8 = { isa = PBXBuildFile; fileRef = E96597BBC6A98255B51B94DC; @@ -77,6 +81,14 @@ isa = PBXBuildFile; fileRef = 951128CA33CCDEF570436B1C; }; + 0A89E8E0E99C3B5B2B38F2E6 = { + isa = PBXBuildFile; + fileRef = C2835F16963B34839FC36220; + }; + 908B7D4FB180F53405DA8EF9 = { + isa = PBXBuildFile; + fileRef = 82C18723A3D0E39BBD8F0F6E; + }; 6DD9DA1677A6CF789CDAB478 = { isa = PBXBuildFile; fileRef = 0D4D508C638BC74943B9976D; @@ -93,10 +105,6 @@ isa = PBXBuildFile; fileRef = 9069981E414A631B036CC9AC; }; - 98F9BB4612E82EE59689E15C = { - isa = PBXBuildFile; - fileRef = B6496F16ACE80CACC5721570; - }; 09C4EDDF7F8B6E75EA3CE3A9 = { isa = PBXBuildFile; fileRef = BC3B310D42C489E8B8D93327; @@ -197,10 +205,6 @@ isa = PBXBuildFile; fileRef = C187718F7B9EBA88584B43F3; }; - 6FD0752A5CADCF60D79FDBB7 = { - isa = PBXBuildFile; - fileRef = 51CBE59779A36D1B80B26974; - }; D25EBE02B55DB244BE0D5635 = { isa = PBXBuildFile; fileRef = DE3E6B2614229FAD56D50770; @@ -213,13 +217,13 @@ isa = PBXBuildFile; fileRef = ADA538034910F52FDD2DC88D; }; - 05A08E366EBF8D650974E695 = { + 0E783907C6214ADD59EC95DC = { isa = PBXBuildFile; - fileRef = 516D6D7C564DD5DF5C15CB06; + fileRef = F58B23995765C9FDBE28F871; }; - 3FCA61C401007B243E2E9035 = { + 05A08E366EBF8D650974E695 = { isa = PBXBuildFile; - fileRef = F797071D88542C813CF7222A; + fileRef = 516D6D7C564DD5DF5C15CB06; }; 30B921C38DCEE787B294B746 = { isa = PBXBuildFile; @@ -257,6 +261,10 @@ isa = PBXBuildFile; fileRef = 486E8D02DAD2A0BF54A901C0; }; + 4581B3A9A0D92FC01D4149EF = { + isa = PBXBuildFile; + fileRef = E4532338917106FA0B61A429; + }; 44AD0D81A65C5EAE3BE588FD = { isa = PBXBuildFile; fileRef = FF3A6A384D536E1AEF47CD54; @@ -281,21 +289,13 @@ isa = PBXBuildFile; fileRef = 0CECD562059DFD7FBFB37E3C; }; - 518DD443B6F17A5AFD707263 = { - isa = PBXBuildFile; - fileRef = A69024A225F2AC31F17B1314; - }; - B7EBA1A83575F48CD08140B9 = { - isa = PBXBuildFile; - fileRef = 4B083E951ECB62217C46CB01; - }; 3C5267E06A897B0DC0F7EA50 = { isa = PBXBuildFile; fileRef = 472F9A90F685220D730EBF6C; }; - 202DC8CF15ACBE096CC327EA = { + 4C743A3DA8682EEE89BDBD28 = { isa = PBXBuildFile; - fileRef = 805A3A5FBA3B9E28363DD77B; + fileRef = E2687B099347B364D1919A9B; }; 5DD883699B85E4C492CAD065 = { isa = PBXBuildFile; @@ -402,13 +402,6 @@ path = "../../Source/ComponentEditor/Components/jucer_ViewportHandler.h"; sourceTree = "SOURCE_ROOT"; }; - 05D67B5A8D64947C067C0945 = { - isa = PBXFileReference; - lastKnownFileType = sourcecode.c.h; - name = "jucer_ProjectWizard_GUIApp.h"; - path = "../../Source/Wizards/jucer_ProjectWizard_GUIApp.h"; - sourceTree = "SOURCE_ROOT"; - }; 0640E34282A97BF73CC8F1EB = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; @@ -423,13 +416,6 @@ path = "../../Source/BinaryData/Templates/jucer_AudioPluginFilterTemplate.cpp"; sourceTree = "SOURCE_ROOT"; }; - 087CB3A961CD3C7434D660A4 = { - isa = PBXFileReference; - lastKnownFileType = sourcecode.c.h; - name = "jucer_NewProjectWizard.h"; - path = "../../Source/Wizards/jucer_NewProjectWizard.h"; - sourceTree = "SOURCE_ROOT"; - }; 09DE066936CF037E9709ADB1 = { isa = PBXFileReference; explicitFileType = wrapper.application; @@ -472,13 +458,6 @@ path = "../../Source/ComponentEditor/UI/jucer_ResourceEditorPanel.cpp"; sourceTree = "SOURCE_ROOT"; }; - 0F01067432AC314EAC213C1C = { - isa = PBXFileReference; - lastKnownFileType = sourcecode.c.h; - name = "jucer_ProjectWizard_Blank.h"; - path = "../../Source/Wizards/jucer_ProjectWizard_Blank.h"; - sourceTree = "SOURCE_ROOT"; - }; 0F8C000E5FF4A2DAC1FEF8EB = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; @@ -486,13 +465,6 @@ path = "../../Source/Utility/UI/jucer_ProjucerLookAndFeel.cpp"; sourceTree = "SOURCE_ROOT"; }; - 11DC04468BC6023671017EBF = { - isa = PBXFileReference; - lastKnownFileType = sourcecode.c.h; - name = "jucer_NewFileWizard.h"; - path = "../../Source/Wizards/jucer_NewFileWizard.h"; - sourceTree = "SOURCE_ROOT"; - }; 11DEED05110D3D1D02FCFFB6 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; @@ -556,13 +528,6 @@ path = "../../Source/Utility/PIPs/jucer_PIPGenerator.cpp"; sourceTree = "SOURCE_ROOT"; }; - 194457D806A26E793584AC0C = { - isa = PBXFileReference; - lastKnownFileType = file.svg; - name = "huckleberry_icon.svg"; - path = "../../Source/BinaryData/Icons/huckleberry_icon.svg"; - sourceTree = "SOURCE_ROOT"; - }; 1B0F18E1D96F727C062B05FA = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; @@ -591,6 +556,13 @@ path = "../../Source/Project/UI/Sidebar/jucer_ProjectTab.h"; sourceTree = "SOURCE_ROOT"; }; + 1D7D2E563E8491643C9F2748 = { + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = "jucer_StartPageComponent.h"; + path = "../../Source/Application/StartPage/jucer_StartPageComponent.h"; + sourceTree = "SOURCE_ROOT"; + }; 1DCA18E935A35D29D2D9B6A0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; @@ -605,6 +577,13 @@ path = "../../JuceLibraryCode/include_juce_data_structures.mm"; sourceTree = "SOURCE_ROOT"; }; + 1F0E279DB49BBF49D81C6D0D = { + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = "jucer_NewProjectTemplates.h"; + path = "../../Source/Application/StartPage/jucer_NewProjectTemplates.h"; + sourceTree = "SOURCE_ROOT"; + }; 20075A86A4D0E8A5B973D9DB = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; @@ -640,6 +619,20 @@ path = "../../../../modules/juce_events"; sourceTree = "SOURCE_ROOT"; }; + 233C7FC5157176DB33FE2F27 = { + isa = PBXFileReference; + lastKnownFileType = file.nib; + name = RecentFilesMenuTemplate.nib; + path = ../../../Build/CMake/RecentFilesMenuTemplate.nib; + sourceTree = "SOURCE_ROOT"; + }; + 234251407CD1A499D8A816BB = { + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = "jucer_ValueWithDefaultWrapper.h"; + path = "../../Source/Utility/Helpers/jucer_ValueWithDefaultWrapper.h"; + sourceTree = "SOURCE_ROOT"; + }; 23A8DE16C0CDB8EED18B008B = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; @@ -661,6 +654,13 @@ path = "../../Source/LiveBuildEngine/jucer_ActivityList.h"; sourceTree = "SOURCE_ROOT"; }; + 247768B490B9D759DDA79359 = { + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = "jucer_UserAvatarComponent.h"; + path = "../../Source/Project/UI/jucer_UserAvatarComponent.h"; + sourceTree = "SOURCE_ROOT"; + }; 24EB4C2412821B8019D6F754 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; @@ -682,13 +682,6 @@ path = "../../Source/ComponentEditor/jucer_JucerDocument.cpp"; sourceTree = "SOURCE_ROOT"; }; - 28D0199327887FFABF9C3F20 = { - isa = PBXFileReference; - lastKnownFileType = sourcecode.c.h; - name = "jucer_UserSettingsPopup.h"; - path = "../../Source/Utility/UI/jucer_UserSettingsPopup.h"; - sourceTree = "SOURCE_ROOT"; - }; 2BD9B4556479A8A41740BCAE = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; @@ -717,6 +710,13 @@ path = "../../Source/Application/jucer_CommandLine.h"; sourceTree = "SOURCE_ROOT"; }; + 2F0A7CA808B2FCCC9ED68992 = { + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = "jucer_LicenseQueryThread.h"; + path = "../../Source/Application/UserAccount/jucer_LicenseQueryThread.h"; + sourceTree = "SOURCE_ROOT"; + }; 2F373F97E30AC1A0BFC1FC61 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; @@ -815,13 +815,6 @@ path = "../../Source/LiveBuildEngine/UI/jucer_ErrorListComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 3C95FA2AA91EBA19ADDD5C29 = { - isa = PBXFileReference; - lastKnownFileType = sourcecode.c.h; - name = "jucer_ProjectWizard_Animated.h"; - path = "../../Source/Wizards/jucer_ProjectWizard_Animated.h"; - sourceTree = "SOURCE_ROOT"; - }; 3D36F0CEB84B27BD02FC461A = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; @@ -836,13 +829,6 @@ path = "../../Source/Utility/UI/jucer_SlidingPanelComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 3DC2ED15A9DFAAEF3D2ACDDF = { - isa = PBXFileReference; - lastKnownFileType = sourcecode.cpp.cpp; - name = "jucer_PIPMain.cpp"; - path = "../../Source/BinaryData/Templates/jucer_PIPMain.cpp"; - sourceTree = "SOURCE_ROOT"; - }; 3EA27F52A254912218F4DE94 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; @@ -871,13 +857,6 @@ path = "../../Source/ComponentEditor/jucer_ComponentLayout.h"; sourceTree = "SOURCE_ROOT"; }; - 4073A12E196BDDADE211E19F = { - isa = PBXFileReference; - lastKnownFileType = text.txt; - name = "projucer_EULA.txt"; - path = "../../Source/BinaryData/projucer_EULA.txt"; - sourceTree = "SOURCE_ROOT"; - }; 409C636B96A9AC1D732B96F8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; @@ -913,11 +892,11 @@ path = "../../Source/BinaryData/Icons/juce-logo-with-text.svg"; sourceTree = "SOURCE_ROOT"; }; - 471C7B0A8B92320AF0C80839 = { + 463C8CF42FAA00014198B71B = { isa = PBXFileReference; - lastKnownFileType = sourcecode.c.h; - name = "jucer_ProjectWizard_StaticLibrary.h"; - path = "../../Source/Wizards/jucer_ProjectWizard_StaticLibrary.h"; + lastKnownFileType = file.in; + name = PIPComponent.cpp.in; + path = ../../../Build/CMake/PIPComponent.cpp.in; sourceTree = "SOURCE_ROOT"; }; 472F9A90F685220D730EBF6C = { @@ -927,13 +906,6 @@ path = ../../JuceLibraryCode/BinaryData.cpp; sourceTree = "SOURCE_ROOT"; }; - 4818A05DE44ADA03D85E1083 = { - isa = PBXFileReference; - lastKnownFileType = sourcecode.c.h; - name = "jucer_ProjucerAnalytics.h"; - path = "../../Source/Application/jucer_ProjucerAnalytics.h"; - sourceTree = "SOURCE_ROOT"; - }; 486E8D02DAD2A0BF54A901C0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; @@ -948,11 +920,11 @@ path = "../../Source/Project/UI/Sidebar/jucer_FileTreeItems.h"; sourceTree = "SOURCE_ROOT"; }; - 4A4EBDAD8D098F72CE053235 = { + 497E1F5F0894B87461734963 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; - name = "jucer_ProjectWizard_AudioPlugin.h"; - path = "../../Source/Wizards/jucer_ProjectWizard_AudioPlugin.h"; + name = "jucer_StartPageTreeHolder.h"; + path = "../../Source/Application/StartPage/jucer_StartPageTreeHolder.h"; sourceTree = "SOURCE_ROOT"; }; 4AE469CD40BDAD634135785E = { @@ -969,13 +941,6 @@ path = "../../Source/ComponentEditor/PaintElements/jucer_PaintElementPath.cpp"; sourceTree = "SOURCE_ROOT"; }; - 4B083E951ECB62217C46CB01 = { - isa = PBXFileReference; - lastKnownFileType = sourcecode.cpp.cpp; - name = "jucer_NewProjectWizardClasses.cpp"; - path = "../../Source/Wizards/jucer_NewProjectWizardClasses.cpp"; - sourceTree = "SOURCE_ROOT"; - }; 4D5F0CA8D1273144681A1D48 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; @@ -1025,6 +990,13 @@ path = "../../Source/ComponentEditor/jucer_ObjectTypes.h"; sourceTree = "SOURCE_ROOT"; }; + 50F89D3827B83B48855B3564 = { + isa = PBXFileReference; + lastKnownFileType = file.storyboard; + name = LaunchScreen.storyboard; + path = ../../../Build/CMake/LaunchScreen.storyboard; + sourceTree = "SOURCE_ROOT"; + }; 512D80BE12634967A085A1DC = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; @@ -1053,11 +1025,11 @@ path = "../../Source/CodeEditor/jucer_DocumentEditorComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 51CBE59779A36D1B80B26974 = { + 52E30AD23A8BE69D5766AF6D = { isa = PBXFileReference; - lastKnownFileType = sourcecode.cpp.cpp; - name = "jucer_LicenseController.cpp"; - path = "../../Source/Licenses/jucer_LicenseController.cpp"; + lastKnownFileType = sourcecode.c.h; + name = "jucer_NewFileWizard.h"; + path = "../../Source/Utility/Helpers/jucer_NewFileWizard.h"; sourceTree = "SOURCE_ROOT"; }; 5432B7B9B2CF2EAEC8B66D5C = { @@ -1109,11 +1081,11 @@ path = "../../Source/ComponentEditor/Properties/jucer_ComponentTextProperty.h"; sourceTree = "SOURCE_ROOT"; }; - 58139D8D454051C59E77609B = { + 582F659B801F656C2B7C51B1 = { isa = PBXFileReference; - lastKnownFileType = file.nib; - name = RecentFilesMenuTemplate.nib; - path = ../../Source/BinaryData/RecentFilesMenuTemplate.nib; + lastKnownFileType = sourcecode.c.h; + name = "jucer_Modules.h"; + path = "../../Source/Project/Modules/jucer_Modules.h"; sourceTree = "SOURCE_ROOT"; }; 5867DC4E39DF8539B54C0D59 = { @@ -1123,13 +1095,6 @@ path = "../../JuceLibraryCode/include_juce_events.mm"; sourceTree = "SOURCE_ROOT"; }; - 58DE91CE6B05AFBACADDB251 = { - isa = PBXFileReference; - lastKnownFileType = file; - name = "juce_analytics"; - path = "../../../../modules/juce_analytics"; - sourceTree = "SOURCE_ROOT"; - }; 58F1FF52E887887A93E84FC2 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; @@ -1151,13 +1116,6 @@ path = "../../Source/ProjectSaving/jucer_ProjectExport_Make.h"; sourceTree = "SOURCE_ROOT"; }; - 59B08C7B13B8EA5137ACA77A = { - isa = PBXFileReference; - lastKnownFileType = text.txt; - name = nothingtoseehere.txt; - path = ../../Source/BinaryData/nothingtoseehere.txt; - sourceTree = "SOURCE_ROOT"; - }; 59F8A47C0020D62C8836A1E7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; @@ -1319,13 +1277,6 @@ path = "../../Source/ComponentEditor/Components/jucer_GroupComponentHandler.h"; sourceTree = "SOURCE_ROOT"; }; - 714267352CE5C4357ADBC231 = { - isa = PBXFileReference; - lastKnownFileType = sourcecode.c.h; - name = "jucer_StartPageComponent.h"; - path = "../../Source/Wizards/jucer_StartPageComponent.h"; - sourceTree = "SOURCE_ROOT"; - }; 719B56C8587863D7AE9B69C6 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; @@ -1333,13 +1284,6 @@ path = "../../Source/ComponentEditor/UI/jucer_RelativePositionedRectangle.h"; sourceTree = "SOURCE_ROOT"; }; - 7211101FFA28400ADBB1D47A = { - isa = PBXFileReference; - lastKnownFileType = sourcecode.c.h; - name = "jucer_Module.h"; - path = "../../Source/Project/jucer_Module.h"; - sourceTree = "SOURCE_ROOT"; - }; 728FE25157E9874D50BBECB2 = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; @@ -1368,13 +1312,6 @@ path = "../../Source/ComponentEditor/UI/jucer_SnapGridPainter.h"; sourceTree = "SOURCE_ROOT"; }; - 763A63E75AC802F17D11FE8B = { - isa = PBXFileReference; - lastKnownFileType = file.cs; - name = "jucer_UnityPluginGUIScript.cs"; - path = "../../Source/BinaryData/Templates/jucer_UnityPluginGUIScript.cs"; - sourceTree = "SOURCE_ROOT"; - }; 7687A1374C60A025BDBE98DE = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; @@ -1396,13 +1333,6 @@ path = "../../Source/ComponentEditor/jucer_GeneratedCode.cpp"; sourceTree = "SOURCE_ROOT"; }; - 790F6302B9A0620F23F8A6C1 = { - isa = PBXFileReference; - lastKnownFileType = sourcecode.c.h; - name = "jucer_LicenseThread.h"; - path = "../../Source/Licenses/jucer_LicenseThread.h"; - sourceTree = "SOURCE_ROOT"; - }; 7AB7640968FAAC73072FBD10 = { isa = PBXFileReference; lastKnownFileType = file; @@ -1438,13 +1368,6 @@ path = "../../Source/ComponentEditor/Properties/jucer_ColourPropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; - 805A3A5FBA3B9E28363DD77B = { - isa = PBXFileReference; - lastKnownFileType = sourcecode.cpp.cpp; - name = "include_juce_analytics.cpp"; - path = "../../JuceLibraryCode/include_juce_analytics.cpp"; - sourceTree = "SOURCE_ROOT"; - }; 807049CA2D5B6DE18EA078F2 = { isa = PBXFileReference; lastKnownFileType = file.svg; @@ -1459,6 +1382,13 @@ path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; }; + 82C18723A3D0E39BBD8F0F6E = { + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = "jucer_StartPageComponent.cpp"; + path = "../../Source/Application/StartPage/jucer_StartPageComponent.cpp"; + sourceTree = "SOURCE_ROOT"; + }; 8336A43CE1C3C26D7C7B53D8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; @@ -1501,13 +1431,6 @@ path = "../../Source/ComponentEditor/Components/jucer_TextEditorHandler.h"; sourceTree = "SOURCE_ROOT"; }; - 8702F43110E4CCA5E5F827F5 = { - isa = PBXFileReference; - lastKnownFileType = sourcecode.c.h; - name = AppConfig.h; - path = ../../JuceLibraryCode/AppConfig.h; - sourceTree = "SOURCE_ROOT"; - }; 8A82061A978B03745485C3AC = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; @@ -1515,27 +1438,6 @@ path = "../../Source/CodeEditor/jucer_LiveBuildCodeEditor.h"; sourceTree = "SOURCE_ROOT"; }; - 8A825FDDC00DD253F44D2C3A = { - isa = PBXFileReference; - lastKnownFileType = sourcecode.c.h; - name = "jucer_ProjectWizard_AudioApp.h"; - path = "../../Source/Wizards/jucer_ProjectWizard_AudioApp.h"; - sourceTree = "SOURCE_ROOT"; - }; - 8BD8E9DA627D6EF9BA10FB9E = { - isa = PBXFileReference; - lastKnownFileType = sourcecode.c.h; - name = "jucer_NewProjectWizardComponent.h"; - path = "../../Source/Wizards/jucer_NewProjectWizardComponent.h"; - sourceTree = "SOURCE_ROOT"; - }; - 8C281F2F8EA3AD614ADF7955 = { - isa = PBXFileReference; - lastKnownFileType = text.html; - name = offlinepage.html; - path = ../../Source/BinaryData/offlinepage.html; - sourceTree = "SOURCE_ROOT"; - }; 8C52A3DDA62A746AA7A68535 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; @@ -1648,6 +1550,13 @@ path = "../../Source/Project/UI/jucer_ProjectContentComponent.h"; sourceTree = "SOURCE_ROOT"; }; + 94146B40B41BF0AACF4359DD = { + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = "jucer_LicenseState.h"; + path = "../../Source/Application/UserAccount/jucer_LicenseState.h"; + sourceTree = "SOURCE_ROOT"; + }; 951128CA33CCDEF570436B1C = { isa = PBXFileReference; lastKnownFileType = file.icns; @@ -1662,13 +1571,6 @@ path = "../../Source/Project/UI/Sidebar/jucer_TabComponents.h"; sourceTree = "SOURCE_ROOT"; }; - 97A847B59EE04483E8850E4B = { - isa = PBXFileReference; - lastKnownFileType = sourcecode.cpp.cpp; - name = "jucer_MainTemplate_SimpleWindow.cpp"; - path = "../../Source/BinaryData/Templates/jucer_MainTemplate_SimpleWindow.cpp"; - sourceTree = "SOURCE_ROOT"; - }; 983CFBA01CA8811F30FA7F4C = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; @@ -1683,13 +1585,6 @@ path = "../../Source/ComponentEditor/PaintElements/jucer_PaintElementGroup.cpp"; sourceTree = "SOURCE_ROOT"; }; - 98E6D61BFF7D85F0E00F0FBF = { - isa = PBXFileReference; - lastKnownFileType = sourcecode.c.h; - name = "jucer_LicenseWebview.h"; - path = "../../Source/Licenses/jucer_LicenseWebview.h"; - sourceTree = "SOURCE_ROOT"; - }; 9914F905BFCFBE5F76619670 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; @@ -1704,13 +1599,6 @@ path = ../../Source/BinaryData/gradle/LICENSE; sourceTree = "SOURCE_ROOT"; }; - 9992E6950C64322A11E39ADF = { - isa = PBXFileReference; - lastKnownFileType = sourcecode.c.h; - name = "jucer_ProjectWizard_DLL.h"; - path = "../../Source/Wizards/jucer_ProjectWizard_DLL.h"; - sourceTree = "SOURCE_ROOT"; - }; 9A3B8BBDA8E144A3DF6B9349 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; @@ -1809,13 +1697,6 @@ path = "../../Source/LiveBuildEngine/jucer_CompileEngineSettings.h"; sourceTree = "SOURCE_ROOT"; }; - A085174413736ACC8D7D42A2 = { - isa = PBXFileReference; - lastKnownFileType = sourcecode.c.h; - name = "jucer_ProjectWizard_openGL.h"; - path = "../../Source/Wizards/jucer_ProjectWizard_openGL.h"; - sourceTree = "SOURCE_ROOT"; - }; A0BBBFBA13A1308B3CD725D5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; @@ -1823,6 +1704,13 @@ path = "../../Source/ComponentEditor/UI/jucer_ComponentLayoutPanel.h"; sourceTree = "SOURCE_ROOT"; }; + A0ECDAF137029C445910D3ED = { + isa = PBXFileReference; + lastKnownFileType = file.in; + name = PIPAudioProcessor.cpp.in; + path = ../../../Build/CMake/PIPAudioProcessor.cpp.in; + sourceTree = "SOURCE_ROOT"; + }; A160AEF56553A658E6EA6A8E = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; @@ -1837,13 +1725,6 @@ path = "../../Source/ComponentEditor/Components/jucer_TreeViewHandler.h"; sourceTree = "SOURCE_ROOT"; }; - A44A774EFC020D3D046A9249 = { - isa = PBXFileReference; - lastKnownFileType = sourcecode.c.h; - name = "jucer_ProjectWizard_Console.h"; - path = "../../Source/Wizards/jucer_ProjectWizard_Console.h"; - sourceTree = "SOURCE_ROOT"; - }; A49503B646A7BD2BEEFC5CBD = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; @@ -1865,20 +1746,6 @@ path = "../../Source/BinaryData/Templates/jucer_MainConsoleAppTemplate.cpp"; sourceTree = "SOURCE_ROOT"; }; - A69024A225F2AC31F17B1314 = { - isa = PBXFileReference; - lastKnownFileType = sourcecode.cpp.cpp; - name = "jucer_NewFileWizard.cpp"; - path = "../../Source/Wizards/jucer_NewFileWizard.cpp"; - sourceTree = "SOURCE_ROOT"; - }; - A6C4AE13FB409DE414094CFA = { - isa = PBXFileReference; - lastKnownFileType = sourcecode.c.h; - name = "jucer_RelativePath.h"; - path = "../../Source/Utility/Helpers/jucer_RelativePath.h"; - sourceTree = "SOURCE_ROOT"; - }; A978DFE87D9BB5EFE5B3DAAC = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; @@ -1900,6 +1767,13 @@ path = "../../../../modules/juce_cryptography"; sourceTree = "SOURCE_ROOT"; }; + AAF90697C0F171EFC3984A5D = { + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = "jucer_ContentComponents.h"; + path = "../../Source/Application/StartPage/jucer_ContentComponents.h"; + sourceTree = "SOURCE_ROOT"; + }; ADA538034910F52FDD2DC88D = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; @@ -1963,11 +1837,11 @@ path = "../../Source/Utility/Helpers/jucer_FileHelpers.cpp"; sourceTree = "SOURCE_ROOT"; }; - B6496F16ACE80CACC5721570 = { + B6444A4A8DFD6828FF6BD1CB = { isa = PBXFileReference; - lastKnownFileType = sourcecode.cpp.cpp; - name = "jucer_ProjucerAnalytics.cpp"; - path = "../../Source/Application/jucer_ProjucerAnalytics.cpp"; + lastKnownFileType = sourcecode.c.h; + name = "jucer_LoginFormComponent.h"; + path = "../../Source/Application/UserAccount/jucer_LoginFormComponent.h"; sourceTree = "SOURCE_ROOT"; }; B6F2905330EA5C560D527209 = { @@ -1977,13 +1851,6 @@ path = "../../../../modules/juce_graphics"; sourceTree = "SOURCE_ROOT"; }; - B8385E9A644BD3CD94876448 = { - isa = PBXFileReference; - lastKnownFileType = sourcecode.c.h; - name = "jucer_ProjectType.h"; - path = "../../Source/Project/jucer_ProjectType.h"; - sourceTree = "SOURCE_ROOT"; - }; B83C9BD89F31EA9E5E12A3C6 = { isa = PBXFileReference; lastKnownFileType = image.png; @@ -1991,13 +1858,6 @@ path = "../../Source/BinaryData/Icons/juce_icon.png"; sourceTree = "SOURCE_ROOT"; }; - B83DAADA1A871F21582FFB23 = { - isa = PBXFileReference; - lastKnownFileType = sourcecode.c.h; - name = "jucer_ApplicationUsageDataWindowComponent.h"; - path = "../../Source/Application/Windows/jucer_ApplicationUsageDataWindowComponent.h"; - sourceTree = "SOURCE_ROOT"; - }; B97D60D2531CFD0D8555BA5C = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; @@ -2033,13 +1893,6 @@ path = "../../Source/Project/jucer_Project.cpp"; sourceTree = "SOURCE_ROOT"; }; - BB187CD608EB6368B29EC335 = { - isa = PBXFileReference; - lastKnownFileType = sourcecode.c.h; - name = "jucer_LicenseController.h"; - path = "../../Source/Licenses/jucer_LicenseController.h"; - sourceTree = "SOURCE_ROOT"; - }; BC3B310D42C489E8B8D93327 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; @@ -2075,6 +1928,13 @@ path = "../../Source/Settings/jucer_AppearanceSettings.cpp"; sourceTree = "SOURCE_ROOT"; }; + BF006EF584FB274FF0319E08 = { + isa = PBXFileReference; + lastKnownFileType = wrapper.framework; + name = Foundation.framework; + path = System/Library/Frameworks/Foundation.framework; + sourceTree = SDKROOT; + }; BF301C2E545AEB4AC112C176 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; @@ -2089,13 +1949,6 @@ path = "../../Source/Project/jucer_Project.h"; sourceTree = "SOURCE_ROOT"; }; - C09BBB58CA45B66D693E8C31 = { - isa = PBXFileReference; - lastKnownFileType = sourcecode.c.h; - name = "jucer_TemplateThumbnailsComponent.h"; - path = "../../Source/Wizards/jucer_TemplateThumbnailsComponent.h"; - sourceTree = "SOURCE_ROOT"; - }; C16F9F479A3A5F6DAD7647A2 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; @@ -2110,11 +1963,11 @@ path = "../../Source/ComponentEditor/jucer_PaintRoutine.cpp"; sourceTree = "SOURCE_ROOT"; }; - C2990A8D054BC230E7C637C3 = { + C2835F16963B34839FC36220 = { isa = PBXFileReference; - lastKnownFileType = sourcecode.c.h; - name = "jucer_NewProjectWizardClasses.h"; - path = "../../Source/Wizards/jucer_NewProjectWizardClasses.h"; + lastKnownFileType = sourcecode.cpp.cpp; + name = "jucer_NewProjectWizard.cpp"; + path = "../../Source/Application/StartPage/jucer_NewProjectWizard.cpp"; sourceTree = "SOURCE_ROOT"; }; C3BB9F92B02B06D04A73794C = { @@ -2145,6 +1998,13 @@ path = "../../Source/Utility/UI/jucer_Icons.h"; sourceTree = "SOURCE_ROOT"; }; + C5A1549AD0C20CF42C1FE630 = { + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = "juce_runtime_arch_detection.cpp"; + path = "../../../Build/CMake/juce_runtime_arch_detection.cpp"; + sourceTree = "SOURCE_ROOT"; + }; C607639897ED2538CBB860D0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; @@ -2194,6 +2054,13 @@ path = "../../Source/LiveBuildEngine/UI/jucer_BuildTabStatusComponent.h"; sourceTree = "SOURCE_ROOT"; }; + CD267A28C16C4E79EB749005 = { + isa = PBXFileReference; + lastKnownFileType = file.svg; + name = "gpl_logo.svg"; + path = "../../Source/BinaryData/Icons/gpl_logo.svg"; + sourceTree = "SOURCE_ROOT"; + }; CF6C8BD0DA3D8CD4E99EBADA = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; @@ -2390,6 +2257,13 @@ path = "Info-App.plist"; sourceTree = "SOURCE_ROOT"; }; + E2687B099347B364D1919A9B = { + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = "include_juce_build_tools.cpp"; + path = "../../JuceLibraryCode/include_juce_build_tools.cpp"; + sourceTree = "SOURCE_ROOT"; + }; E2B668E2A65AEE8F07B406C8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; @@ -2411,6 +2285,13 @@ path = "../../Source/Project/UI/Sidebar/jucer_ProjectTreeItemBase.h"; sourceTree = "SOURCE_ROOT"; }; + E4532338917106FA0B61A429 = { + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = "jucer_NewFileWizard.cpp"; + path = "../../Source/Utility/Helpers/jucer_NewFileWizard.cpp"; + sourceTree = "SOURCE_ROOT"; + }; E468FDB5504C5D9315B2D04F = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; @@ -2474,6 +2355,13 @@ path = "../../Source/ComponentEditor/UI/jucer_PaintRoutineEditor.h"; sourceTree = "SOURCE_ROOT"; }; + EE12741389A87D1BF04AE795 = { + isa = PBXFileReference; + lastKnownFileType = file; + name = "juce_build_tools"; + path = "../../../Build/juce_build_tools"; + sourceTree = "SOURCE_ROOT"; + }; EE690110171E1648FF2118B8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; @@ -2516,6 +2404,20 @@ path = "../../Source/Utility/Helpers/jucer_CodeHelpers.cpp"; sourceTree = "SOURCE_ROOT"; }; + F30DF63DBEFA4BEEF7C369FC = { + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = "jucer_LicenseController.h"; + path = "../../Source/Application/UserAccount/jucer_LicenseController.h"; + sourceTree = "SOURCE_ROOT"; + }; + F313EE01ECE306DB2CFE011D = { + isa = PBXFileReference; + lastKnownFileType = file.in; + name = UnityPluginGUIScript.cs.in; + path = ../../../Build/CMake/UnityPluginGUIScript.cs.in; + sourceTree = "SOURCE_ROOT"; + }; F3CC8F26ECCDA6DCD8A284D2 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; @@ -2530,6 +2432,13 @@ path = "../../Source/ComponentEditor/Properties/jucer_ComponentBooleanProperty.h"; sourceTree = "SOURCE_ROOT"; }; + F58B23995765C9FDBE28F871 = { + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = "jucer_Modules.cpp"; + path = "../../Source/Project/Modules/jucer_Modules.cpp"; + sourceTree = "SOURCE_ROOT"; + }; F5DD97B45B8EA60C1ED0DD80 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; @@ -2537,11 +2446,11 @@ path = "../../Source/Settings/jucer_StoredSettings.cpp"; sourceTree = "SOURCE_ROOT"; }; - F797071D88542C813CF7222A = { + F63F46CA0A51C679867855A7 = { isa = PBXFileReference; - lastKnownFileType = sourcecode.cpp.cpp; - name = "jucer_Module.cpp"; - path = "../../Source/Project/jucer_Module.cpp"; + lastKnownFileType = sourcecode.c.h; + name = "jucer_ProjectMessagesComponent.h"; + path = "../../Source/Project/UI/jucer_ProjectMessagesComponent.h"; sourceTree = "SOURCE_ROOT"; }; F7C74E934C954F6F1A3BE4F9 = { @@ -2551,6 +2460,13 @@ path = "../../Source/Application/Windows/jucer_TranslationToolWindowComponent.h"; sourceTree = "SOURCE_ROOT"; }; + F84D031B2A6BB1EE6A316C71 = { + isa = PBXFileReference; + lastKnownFileType = file.in; + name = PIPConsole.cpp.in; + path = ../../../Build/CMake/PIPConsole.cpp.in; + sourceTree = "SOURCE_ROOT"; + }; F8A38C0C7C45F2DB6A5FB812 = { isa = PBXFileReference; lastKnownFileType = file.svg; @@ -2565,6 +2481,13 @@ path = "../../Source/CodeEditor/jucer_OpenDocumentManager.cpp"; sourceTree = "SOURCE_ROOT"; }; + F9A363BFBB6B1143C2E967C3 = { + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = "jucer_ModuleDescription.h"; + path = "../../Source/Project/Modules/jucer_ModuleDescription.h"; + sourceTree = "SOURCE_ROOT"; + }; FA790C59A304579F660F112F = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; @@ -2586,6 +2509,20 @@ path = "../../Source/ComponentEditor/Properties/jucer_ComponentColourProperty.h"; sourceTree = "SOURCE_ROOT"; }; + FD7885911A317D73E98D49B3 = { + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = "jucer_NewProjectWizard.h"; + path = "../../Source/Application/StartPage/jucer_NewProjectWizard.h"; + sourceTree = "SOURCE_ROOT"; + }; + FDABEE6B64546586368A4729 = { + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = "jucer_AvailableModulesList.h"; + path = "../../Source/Project/Modules/jucer_AvailableModulesList.h"; + sourceTree = "SOURCE_ROOT"; + }; FE20FE5805A02A4843048200 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; @@ -2614,11 +2551,35 @@ path = "../../Source/ComponentEditor/UI/jucer_PaintRoutinePanel.cpp"; sourceTree = "SOURCE_ROOT"; }; + A734ACA659C8B85D24B27673 = { + isa = PBXGroup; + children = ( + AAF90697C0F171EFC3984A5D, + 1F0E279DB49BBF49D81C6D0D, + C2835F16963B34839FC36220, + FD7885911A317D73E98D49B3, + 82C18723A3D0E39BBD8F0F6E, + 1D7D2E563E8491643C9F2748, + 497E1F5F0894B87461734963, + ); + name = StartPage; + sourceTree = "<group>"; + }; + 9D43579A76E23FBCE6B36333 = { + isa = PBXGroup; + children = ( + F30DF63DBEFA4BEEF7C369FC, + 2F0A7CA808B2FCCC9ED68992, + 94146B40B41BF0AACF4359DD, + B6444A4A8DFD6828FF6BD1CB, + ); + name = UserAccount; + sourceTree = "<group>"; + }; EB1D55A76652399EB81CC1F0 = { isa = PBXGroup; children = ( DE4A987B2D5529990A6AA9D4, - B83DAADA1A871F21582FFB23, D91E7F8FEF9290195D56782C, C736264708F3F68BA745BA29, EB2E723DC3DB150A8A644D08, @@ -2633,6 +2594,8 @@ BC67FD952A6F210A11A1ECB8 = { isa = PBXGroup; children = ( + A734ACA659C8B85D24B27673, + 9D43579A76E23FBCE6B36333, EB1D55A76652399EB81CC1F0, 7CA44FF0BA319517C6E39651, EE690110171E1648FF2118B8, @@ -2646,13 +2609,11 @@ 8C52A3DDA62A746AA7A68535, 9069981E414A631B036CC9AC, 2CD34A70B4032C0426F7AA10, - B6496F16ACE80CACC5721570, - 4818A05DE44ADA03D85E1083, ); name = Application; sourceTree = "<group>"; }; - 8CF70DA9AB4725126B9F55BE = { + 59BA7D0ED63ACD9A7F3E8814 = { isa = PBXGroup; children = ( 129F2DE0FEF154F8F8C7A74E, @@ -2663,7 +2624,7 @@ name = gradle; sourceTree = "<group>"; }; - F0F189518721D46C0F94FD56 = { + C83BF6127A39BE2C4ED80B67 = { isa = PBXGroup; children = ( 514F2FAFDBF535AC03FA2E6C, @@ -2673,7 +2634,7 @@ 69B478C992FA0B8C885946A6, EAC1731150A7F79D59BAA0B6, 8F4D281E98808204E2846A7D, - 194457D806A26E793584AC0C, + CD267A28C16C4E79EB749005, 432EC251A122071809471804, B83C9BD89F31EA9E5E12A3C6, 8FEF6F5EA676B824C021EB6F, @@ -2690,7 +2651,7 @@ name = Icons; sourceTree = "<group>"; }; - E59ABA0D11CBAAD77179E9C6 = { + 86B4069D904AB46AC86FB383 = { isa = PBXGroup; children = ( 9A3B8BBDA8E144A3DF6B9349, @@ -2711,7 +2672,6 @@ 32C4B61AD995877956B7FA66, A66F17E7472E5C19AFE98E46, F159C1B99ACF1D91E12D978E, - 97A847B59EE04483E8850E4B, A160AEF56553A658E6EA6A8E, 8336A43CE1C3C26D7C7B53D8, C7245390C6C44E89F7526CFC, @@ -2722,25 +2682,26 @@ 023B92AC0340305762412E90, 3F7C5B53347A487C7FBD2223, 4ECF029E3A69BF42FED1503D, - 3DC2ED15A9DFAAEF3D2ACDDF, E67999BF57B139E00207A374, - 763A63E75AC802F17D11FE8B, ); name = Templates; sourceTree = "<group>"; }; - A9399733CAA07BDAB958242C = { + DC3A4B0AD79334BA8A7E0661 = { isa = PBXGroup; children = ( - 8CF70DA9AB4725126B9F55BE, - F0F189518721D46C0F94FD56, - E59ABA0D11CBAAD77179E9C6, + 50F89D3827B83B48855B3564, + A0ECDAF137029C445910D3ED, + 463C8CF42FAA00014198B71B, + F84D031B2A6BB1EE6A316C71, + 233C7FC5157176DB33FE2F27, + F313EE01ECE306DB2CFE011D, + 59BA7D0ED63ACD9A7F3E8814, + C83BF6127A39BE2C4ED80B67, + 86B4069D904AB46AC86FB383, 41105E536155E394E54BDD35, 5F6584B675E30761521A9F42, - 59B08C7B13B8EA5137ACA77A, - 8C281F2F8EA3AD614ADF7955, - 4073A12E196BDDADE211E19F, - 58139D8D454051C59E77609B, + C5A1549AD0C20CF42C1FE630, ); name = BinaryData; sourceTree = "<group>"; @@ -2893,17 +2854,6 @@ name = ComponentEditor; sourceTree = "<group>"; }; - 144B649D98AE8316058B8281 = { - isa = PBXGroup; - children = ( - 51CBE59779A36D1B80B26974, - BB187CD608EB6368B29EC335, - 790F6302B9A0620F23F8A6C1, - 98E6D61BFF7D85F0E00F0FBF, - ); - name = Licenses; - sourceTree = "<group>"; - }; 9014CA5F3B8D23E883D6975E = { isa = PBXGroup; children = ( @@ -2941,6 +2891,17 @@ name = LiveBuildEngine; sourceTree = "<group>"; }; + 5108FDF7F62E617332FB13B0 = { + isa = PBXGroup; + children = ( + FDABEE6B64546586368A4729, + F9A363BFBB6B1143C2E967C3, + F58B23995765C9FDBE28F871, + 582F659B801F656C2B7C51B1, + ); + name = Modules; + sourceTree = "<group>"; + }; 236D186F5A6536C59D6E751C = { isa = PBXGroup; children = ( @@ -2967,6 +2928,8 @@ B3528C08B84CBC950252EA69, 1B0F18E1D96F727C062B05FA, 92A66A8BD87F98EB6B4FB6D0, + F63F46CA0A51C679867855A7, + 247768B490B9D759DDA79359, ); name = UI; sourceTree = "<group>"; @@ -2974,12 +2937,10 @@ 89E9055A179B4C2019B4E1AE = { isa = PBXGroup; children = ( + 5108FDF7F62E617332FB13B0, EBC037ECAAC8156B8B19DC69, - F797071D88542C813CF7222A, - 7211101FFA28400ADBB1D47A, BAC43B20E14A340CCF14119C, BF3CEF080FA013E2778DCE90, - B8385E9A644BD3CD94876448, ); name = Project; sourceTree = "<group>"; @@ -3025,10 +2986,12 @@ E186BC01A1B1529937A46485, 486E8D02DAD2A0BF54A901C0, 983CFBA01CA8811F30FA7F4C, + E4532338917106FA0B61A429, + 52E30AD23A8BE69D5766AF6D, 58F1FF52E887887A93E84FC2, - A6C4AE13FB409DE414094CFA, 6FD8DBC0FF42C87D8BEE2452, 00515BA4EC5A7D4DC078ED37, + 234251407CD1A499D8A816BB, FF3A6A384D536E1AEF47CD54, C16F9F479A3A5F6DAD7647A2, ); @@ -3068,7 +3031,6 @@ FE20FE5805A02A4843048200, 0CECD562059DFD7FBFB37E3C, 3D6FD9C0065BF16568EC0AB7, - 28D0199327887FFABF9C3F20, ); name = UI; sourceTree = "<group>"; @@ -3083,44 +3045,18 @@ name = Utility; sourceTree = "<group>"; }; - 73BAA89A783BBDD79AA27964 = { - isa = PBXGroup; - children = ( - A69024A225F2AC31F17B1314, - 11DC04468BC6023671017EBF, - 087CB3A961CD3C7434D660A4, - 4B083E951ECB62217C46CB01, - C2990A8D054BC230E7C637C3, - 8BD8E9DA627D6EF9BA10FB9E, - 3C95FA2AA91EBA19ADDD5C29, - 8A825FDDC00DD253F44D2C3A, - 4A4EBDAD8D098F72CE053235, - 0F01067432AC314EAC213C1C, - A44A774EFC020D3D046A9249, - 9992E6950C64322A11E39ADF, - 05D67B5A8D64947C067C0945, - A085174413736ACC8D7D42A2, - 471C7B0A8B92320AF0C80839, - 714267352CE5C4357ADBC231, - C09BBB58CA45B66D693E8C31, - ); - name = Wizards; - sourceTree = "<group>"; - }; D3109994DA6AD871BE85C4E2 = { isa = PBXGroup; children = ( BC67FD952A6F210A11A1ECB8, - A9399733CAA07BDAB958242C, + DC3A4B0AD79334BA8A7E0661, F1B44F007A02A0FAE4DC8D79, F6BD840F9A06F2DA891E2CB8, - 144B649D98AE8316058B8281, 20B39D53B7DAAB53C7533532, 89E9055A179B4C2019B4E1AE, 4DCC5D64BBE8DE85360A3D57, EC535A977A1A114BC5DAE7B3, 2B1F885AA027E1A76A1C32E3, - 73BAA89A783BBDD79AA27964, ); name = Projucer; sourceTree = "<group>"; @@ -3128,7 +3064,7 @@ 8A24D1B6925535A868974986 = { isa = PBXGroup; children = ( - 58DE91CE6B05AFBACADDB251, + EE12741389A87D1BF04AE795, BA159A3B7D129771F5C15EA3, AA1C44E89D792DDC4867B2C8, 69555CEFC6ED613AA3949298, @@ -3143,10 +3079,9 @@ 2C6746F66EF4444F53B3221F = { isa = PBXGroup; children = ( - 8702F43110E4CCA5E5F827F5, 472F9A90F685220D730EBF6C, 4F687965FBE86EAFDB3ACFEC, - 805A3A5FBA3B9E28363DD77B, + E2687B099347B364D1919A9B, DB9C8E35DF815B803CB4A9CF, D766BB9D8C32B5560F0493F3, 1DE5BBC777FB64798D823002, @@ -3182,6 +3117,7 @@ E983E6DDE3318B872EBE347F, 8F7BE18698ADCEF51CDE4A5C, 842427CFE565F3FCE5B99174, + BF006EF584FB274FF0319E08, E96597BBC6A98255B51B94DC, 431D30038CBF67F80E8B3A13, 9F01BA9942D038EA8B5289A8, @@ -3227,9 +3163,28 @@ GCC_PREPROCESSOR_DEFINITIONS = ( "_DEBUG=1", "DEBUG=1", + "JUCE_DISPLAY_SPLASH_SCREEN=0", + "JUCE_USE_DARK_SPLASH_SCREEN=1", + "JUCE_PROJUCER_VERSION=0x60005", + "JUCE_MODULE_AVAILABLE_juce_build_tools=1", + "JUCE_MODULE_AVAILABLE_juce_core=1", + "JUCE_MODULE_AVAILABLE_juce_cryptography=1", + "JUCE_MODULE_AVAILABLE_juce_data_structures=1", + "JUCE_MODULE_AVAILABLE_juce_events=1", + "JUCE_MODULE_AVAILABLE_juce_graphics=1", + "JUCE_MODULE_AVAILABLE_juce_gui_basics=1", + "JUCE_MODULE_AVAILABLE_juce_gui_extra=1", + "JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1", + "JUCE_LOG_ASSERTIONS=1", + "JUCE_USE_CURL=1", + "JUCE_LOAD_CURL_SYMBOLS_LAZILY=1", + "JUCE_ALLOW_STATIC_NULL_VARIABLES=0", + "JUCE_STRICT_REFCOUNTEDPOINTER=1", + "JUCE_WEB_BROWSER=0", + "JUCE_STANDALONE_APPLICATION=1", "JUCER_XCODE_MAC_F6D2F4CF=1", - "JUCE_APP_VERSION=5.4.7", - "JUCE_APP_VERSION_HEX=0x50407", + "JUCE_APP_VERSION=6.0.5", + "JUCE_APP_VERSION_HEX=0x60005", "JucePlugin_Build_VST=0", "JucePlugin_Build_VST3=0", "JucePlugin_Build_AU=0", @@ -3242,6 +3197,7 @@ GCC_VERSION = com.apple.compilers.llvm.clang.1_0; HEADER_SEARCH_PATHS = ( "../../JuceLibraryCode", + "../../../Build", "../../../../modules", "$(inherited)", ); @@ -3249,10 +3205,16 @@ INFOPLIST_PREPROCESS = NO; INSTALL_PATH = "$(HOME)/Applications"; MACOSX_DEPLOYMENT_TARGET = 10.11; - OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow-all -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wunreachable-code -Wzero-as-null-pointer-constant -Wcast-align -Winconsistent-missing-destructor-override -Wshift-sign-overflow -Wnullable-to-nonnull-conversion -Wno-missing-field-initializers -Wno-ignored-qualifiers"; + MTL_HEADER_SEARCH_PATHS = ( + "../../JuceLibraryCode", + "../../../Build", + "../../../../modules", + ); + OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow-all -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wunreachable-code -Wzero-as-null-pointer-constant -Wcast-align -Winconsistent-missing-destructor-override -Wshift-sign-overflow -Wnullable-to-nonnull-conversion -Wno-missing-field-initializers -Wno-ignored-qualifiers -Wswitch-enum"; PRODUCT_BUNDLE_IDENTIFIER = com.juce.theprojucer; PRODUCT_NAME = "Projucer"; USE_HEADERMAP = NO; + VALID_ARCHS = "i386 x86_64 arm64 arm64e"; }; name = Debug; }; @@ -3271,9 +3233,28 @@ GCC_PREPROCESSOR_DEFINITIONS = ( "_NDEBUG=1", "NDEBUG=1", + "JUCE_DISPLAY_SPLASH_SCREEN=0", + "JUCE_USE_DARK_SPLASH_SCREEN=1", + "JUCE_PROJUCER_VERSION=0x60005", + "JUCE_MODULE_AVAILABLE_juce_build_tools=1", + "JUCE_MODULE_AVAILABLE_juce_core=1", + "JUCE_MODULE_AVAILABLE_juce_cryptography=1", + "JUCE_MODULE_AVAILABLE_juce_data_structures=1", + "JUCE_MODULE_AVAILABLE_juce_events=1", + "JUCE_MODULE_AVAILABLE_juce_graphics=1", + "JUCE_MODULE_AVAILABLE_juce_gui_basics=1", + "JUCE_MODULE_AVAILABLE_juce_gui_extra=1", + "JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1", + "JUCE_LOG_ASSERTIONS=1", + "JUCE_USE_CURL=1", + "JUCE_LOAD_CURL_SYMBOLS_LAZILY=1", + "JUCE_ALLOW_STATIC_NULL_VARIABLES=0", + "JUCE_STRICT_REFCOUNTEDPOINTER=1", + "JUCE_WEB_BROWSER=0", + "JUCE_STANDALONE_APPLICATION=1", "JUCER_XCODE_MAC_F6D2F4CF=1", - "JUCE_APP_VERSION=5.4.7", - "JUCE_APP_VERSION_HEX=0x50407", + "JUCE_APP_VERSION=6.0.5", + "JUCE_APP_VERSION_HEX=0x60005", "JucePlugin_Build_VST=0", "JucePlugin_Build_VST3=0", "JucePlugin_Build_AU=0", @@ -3283,10 +3264,10 @@ "JucePlugin_Build_Standalone=0", "JucePlugin_Build_Unity=0", ); - GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; HEADER_SEARCH_PATHS = ( "../../JuceLibraryCode", + "../../../Build", "../../../../modules", "$(inherited)", ); @@ -3294,10 +3275,16 @@ INFOPLIST_PREPROCESS = NO; INSTALL_PATH = "$(HOME)/Applications"; MACOSX_DEPLOYMENT_TARGET = 10.11; - OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow-all -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wunreachable-code -Wzero-as-null-pointer-constant -Wcast-align -Winconsistent-missing-destructor-override -Wshift-sign-overflow -Wnullable-to-nonnull-conversion -Wno-missing-field-initializers -Wno-ignored-qualifiers"; + MTL_HEADER_SEARCH_PATHS = ( + "../../JuceLibraryCode", + "../../../Build", + "../../../../modules", + ); + OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow-all -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wunreachable-code -Wzero-as-null-pointer-constant -Wcast-align -Winconsistent-missing-destructor-override -Wshift-sign-overflow -Wnullable-to-nonnull-conversion -Wno-missing-field-initializers -Wno-ignored-qualifiers -Wswitch-enum"; PRODUCT_BUNDLE_IDENTIFIER = com.juce.theprojucer; PRODUCT_NAME = "Projucer"; USE_HEADERMAP = NO; + VALID_ARCHS = "i386 x86_64 arm64 arm64e"; }; name = Release; }; @@ -3326,11 +3313,12 @@ CODE_SIGN_IDENTITY = ""; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; + ENABLE_TESTABILITY = NO; GCC_C_LANGUAGE_STANDARD = c11; GCC_INLINES_ARE_PRIVATE_EXTERN = YES; GCC_MODEL_TUNING = G5; GCC_NO_COMMON_BLOCKS = YES; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; @@ -3374,10 +3362,12 @@ CODE_SIGN_IDENTITY = ""; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = NO; GCC_C_LANGUAGE_STANDARD = c11; GCC_INLINES_ARE_PRIVATE_EXTERN = YES; GCC_MODEL_TUNING = G5; GCC_NO_COMMON_BLOCKS = YES; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; @@ -3395,10 +3385,6 @@ }; name = Release; }; - 50E3FDD15B8D8C9793DFABF9 = { - isa = PBXTargetDependency; - target = 0039FE1A254FE518518BF8B8; - }; F90407F24422C589DA251604 = { isa = XCConfigurationList; buildConfigurations = ( @@ -3430,11 +3416,12 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 0A89E8E0E99C3B5B2B38F2E6, + 908B7D4FB180F53405DA8EF9, 6DD9DA1677A6CF789CDAB478, 954A036F5DDB375DB23FFB3E, 95B44E6C74B1DED31DBE37EB, AA9D0B8E23F3D87A23DE9F8A, - 98F9BB4612E82EE59689E15C, 09C4EDDF7F8B6E75EA3CE3A9, 71713DE4716DCEDB45A206E2, 940CE4E081E9E685243C07AA, @@ -3460,12 +3447,11 @@ 209FCCC2155A1FCB7E11E20D, C93569F47B4AC1A8E37992ED, 1B988E139004D8E2850EB656, - 6FD0752A5CADCF60D79FDBB7, D25EBE02B55DB244BE0D5635, 85E7FCB0516EFF853FA7B380, CC6C4D351BA9B473E5F95791, + 0E783907C6214ADD59EC95DC, 05A08E366EBF8D650974E695, - 3FCA61C401007B243E2E9035, 30B921C38DCEE787B294B746, 244567D3AE2E417A8CB2B95E, 26D6AEA321E80ABCC3CCCCD1, @@ -3475,16 +3461,15 @@ 8BE478303CDF061B72F219E2, BF913199032B4CE970E82AA3, 25EF9B3FECB4C9F0F522DCAA, + 4581B3A9A0D92FC01D4149EF, 44AD0D81A65C5EAE3BE588FD, 638C7247B6DBA67EFE46E124, D0E26EB54B0087C8BE3D541E, 468548FB21D264DC12321327, 6ECB2F11D2F593FACCCF99DB, 95F56FB44C669F93AE77E465, - 518DD443B6F17A5AFD707263, - B7EBA1A83575F48CD08140B9, 3C5267E06A897B0DC0F7EA50, - 202DC8CF15ACBE096CC327EA, + 4C743A3DA8682EEE89BDBD28, 5DD883699B85E4C492CAD065, D5C9125F65493CA481F18E53, 02E8F35A8E0D4A0DF6F38D60, @@ -3509,6 +3494,7 @@ 091A57B4B9CE623E75E9A756, FAB47E69F7D9DCE1F906AA07, 0E884E47A637D6C65154699A, + DD0FF38F7E8DE0220D73671D, 49C22786B54C5DC94E4654B8, CDEF9FF2D119476D707305DF, 96EC6315E1B3F1A109F84BAF, @@ -3535,7 +3521,7 @@ 74EA481348A24104E6ACE009 = { isa = PBXProject; buildConfigurationList = F90407F24422C589DA251604; - attributes = { LastUpgradeCheck = 1100; ORGANIZATIONNAME = "ROLI Ltd."; TargetAttributes = { 0039FE1A254FE518518BF8B8 = { SystemCapabilities = {com.apple.ApplicationGroups.iOS = { enabled = 0; }; com.apple.InAppPurchase = { enabled = 0; }; com.apple.InterAppAudio = { enabled = 0; }; com.apple.Push = { enabled = 0; }; com.apple.Sandbox = { enabled = 0; }; com.apple.HardenedRuntime = { enabled = 0; }; }; }; }; }; + attributes = { LastUpgradeCheck = 1200; ORGANIZATIONNAME = "Raw Material Software Limited"; TargetAttributes = { 0039FE1A254FE518518BF8B8 = { SystemCapabilities = {com.apple.ApplicationGroups.iOS = { enabled = 0; }; com.apple.InAppPurchase = { enabled = 0; }; com.apple.InterAppAudio = { enabled = 0; }; com.apple.Push = { enabled = 0; }; com.apple.Sandbox = { enabled = 0; }; com.apple.HardenedRuntime = { enabled = 0; }; }; }; }; }; compatibilityVersion = "Xcode 3.2"; hasScannedForEncodings = 0; mainGroup = 3CC531922CC2D398E283A845; diff --git a/extras/Projucer/Builds/MacOSX/Projucer.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/extras/Projucer/Builds/MacOSX/Projucer.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings index 949b6789..f2e3cbe8 100644 --- a/extras/Projucer/Builds/MacOSX/Projucer.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ b/extras/Projucer/Builds/MacOSX/Projucer.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -4,5 +4,7 @@ <dict> <key>BuildSystemType</key> <string>Original</string> + <key>DisableBuildSystemDeprecationWarning</key> + <true/> </dict> </plist> diff --git a/extras/Projucer/Builds/VisualStudio2015/Projucer_App.vcxproj b/extras/Projucer/Builds/VisualStudio2015/Projucer_App.vcxproj index 35ce8e3c..902819b0 100644 --- a/extras/Projucer/Builds/VisualStudio2015/Projucer_App.vcxproj +++ b/extras/Projucer/Builds/VisualStudio2015/Projucer_App.vcxproj @@ -63,11 +63,11 @@ <ClCompile> <Optimization>Disabled</Optimization> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCER_VS2015_78A5022=1;JUCE_APP_VERSION=5.4.7;JUCE_APP_VERSION_HEX=0x50407;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\Build;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCE_DISPLAY_SPLASH_SCREEN=0;JUCE_USE_DARK_SPLASH_SCREEN=1;JUCE_PROJUCER_VERSION=0x60005;JUCE_MODULE_AVAILABLE_juce_build_tools=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_LOG_ASSERTIONS=1;JUCE_USE_CURL=1;JUCE_LOAD_CURL_SYMBOLS_LAZILY=1;JUCE_ALLOW_STATIC_NULL_VARIABLES=0;JUCE_STRICT_REFCOUNTEDPOINTER=1;JUCE_WEB_BROWSER=0;JUCE_STANDALONE_APPLICATION=1;JUCER_VS2015_78A5022=1;JUCE_APP_VERSION=6.0.5;JUCE_APP_VERSION_HEX=0x60005;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> <RuntimeTypeInfo>true</RuntimeTypeInfo> - <PrecompiledHeader/> + <PrecompiledHeader>NotUsing</PrecompiledHeader> <AssemblerListingLocation>$(IntDir)\</AssemblerListingLocation> <ObjectFileName>$(IntDir)\</ObjectFileName> <ProgramDataBaseFileName>$(IntDir)\</ProgramDataBaseFileName> @@ -105,11 +105,11 @@ </Midl> <ClCompile> <Optimization>Full</Optimization> - <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCER_VS2015_78A5022=1;JUCE_APP_VERSION=5.4.7;JUCE_APP_VERSION_HEX=0x50407;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\Build;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCE_DISPLAY_SPLASH_SCREEN=0;JUCE_USE_DARK_SPLASH_SCREEN=1;JUCE_PROJUCER_VERSION=0x60005;JUCE_MODULE_AVAILABLE_juce_build_tools=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_LOG_ASSERTIONS=1;JUCE_USE_CURL=1;JUCE_LOAD_CURL_SYMBOLS_LAZILY=1;JUCE_ALLOW_STATIC_NULL_VARIABLES=0;JUCE_STRICT_REFCOUNTEDPOINTER=1;JUCE_WEB_BROWSER=0;JUCE_STANDALONE_APPLICATION=1;JUCER_VS2015_78A5022=1;JUCE_APP_VERSION=6.0.5;JUCE_APP_VERSION_HEX=0x60005;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreaded</RuntimeLibrary> <RuntimeTypeInfo>true</RuntimeTypeInfo> - <PrecompiledHeader/> + <PrecompiledHeader>NotUsing</PrecompiledHeader> <AssemblerListingLocation>$(IntDir)\</AssemblerListingLocation> <ObjectFileName>$(IntDir)\</ObjectFileName> <ProgramDataBaseFileName>$(IntDir)\</ProgramDataBaseFileName> @@ -140,6 +140,8 @@ <Lib/> </ItemDefinitionGroup> <ItemGroup> + <ClCompile Include="..\..\Source\Application\StartPage\jucer_NewProjectWizard.cpp"/> + <ClCompile Include="..\..\Source\Application\StartPage\jucer_StartPageComponent.cpp"/> <ClCompile Include="..\..\Source\Application\jucer_Application.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -147,7 +149,6 @@ <ClCompile Include="..\..\Source\Application\jucer_CommandLine.cpp"/> <ClCompile Include="..\..\Source\Application\jucer_Main.cpp"/> <ClCompile Include="..\..\Source\Application\jucer_MainWindow.cpp"/> - <ClCompile Include="..\..\Source\Application\jucer_ProjucerAnalytics.cpp"/> <ClCompile Include="..\..\Source\BinaryData\Templates\jucer_AnimatedComponentTemplate.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -172,9 +173,6 @@ <ClCompile Include="..\..\Source\BinaryData\Templates\jucer_MainTemplate_NoWindow.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\Source\BinaryData\Templates\jucer_MainTemplate_SimpleWindow.cpp"> - <ExcludedFromBuild>true</ExcludedFromBuild> - </ClCompile> <ClCompile Include="..\..\Source\BinaryData\Templates\jucer_MainTemplate_Window.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -187,7 +185,7 @@ <ClCompile Include="..\..\Source\BinaryData\Templates\jucer_OpenGLComponentTemplate.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\Source\BinaryData\Templates\jucer_PIPMain.cpp"> + <ClCompile Include="..\..\..\Build\CMake\juce_runtime_arch_detection.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\..\Source\CodeEditor\jucer_DocumentEditorComponent.cpp"/> @@ -215,15 +213,14 @@ <ClCompile Include="..\..\Source\ComponentEditor\jucer_JucerDocument.cpp"/> <ClCompile Include="..\..\Source\ComponentEditor\jucer_ObjectTypes.cpp"/> <ClCompile Include="..\..\Source\ComponentEditor\jucer_PaintRoutine.cpp"/> - <ClCompile Include="..\..\Source\Licenses\jucer_LicenseController.cpp"/> <ClCompile Include="..\..\Source\LiveBuildEngine\jucer_CompileEngineClient.cpp"/> <ClCompile Include="..\..\Source\LiveBuildEngine\jucer_CompileEngineServer.cpp"/> <ClCompile Include="..\..\Source\LiveBuildEngine\jucer_DownloadCompileEngineThread.cpp"/> + <ClCompile Include="..\..\Source\Project\Modules\jucer_Modules.cpp"/> <ClCompile Include="..\..\Source\Project\UI\jucer_HeaderComponent.cpp"/> <ClCompile Include="..\..\Source\Project\UI\jucer_ProjectContentComponent.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\Source\Project\jucer_Module.cpp"/> <ClCompile Include="..\..\Source\Project\jucer_Project.cpp"/> <ClCompile Include="..\..\Source\ProjectSaving\jucer_ProjectExporter.cpp"/> <ClCompile Include="..\..\Source\ProjectSaving\jucer_ProjectSaver.cpp"/> @@ -233,24 +230,41 @@ <ClCompile Include="..\..\Source\Utility\Helpers\jucer_CodeHelpers.cpp"/> <ClCompile Include="..\..\Source\Utility\Helpers\jucer_FileHelpers.cpp"/> <ClCompile Include="..\..\Source\Utility\Helpers\jucer_MiscUtilities.cpp"/> + <ClCompile Include="..\..\Source\Utility\Helpers\jucer_NewFileWizard.cpp"/> <ClCompile Include="..\..\Source\Utility\Helpers\jucer_VersionInfo.cpp"/> <ClCompile Include="..\..\Source\Utility\PIPs\jucer_PIPGenerator.cpp"/> <ClCompile Include="..\..\Source\Utility\UI\jucer_Icons.cpp"/> <ClCompile Include="..\..\Source\Utility\UI\jucer_JucerTreeViewBase.cpp"/> <ClCompile Include="..\..\Source\Utility\UI\jucer_ProjucerLookAndFeel.cpp"/> <ClCompile Include="..\..\Source\Utility\UI\jucer_SlidingPanelComponent.cpp"/> - <ClCompile Include="..\..\Source\Wizards\jucer_NewFileWizard.cpp"/> - <ClCompile Include="..\..\Source\Wizards\jucer_NewProjectWizardClasses.cpp"/> - <ClCompile Include="..\..\..\..\modules\juce_analytics\analytics\juce_Analytics.cpp"> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_BinaryResourceFile.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_BuildHelperFunctions.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_CppTokeniserFunctions.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_Entitlements.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_analytics\analytics\juce_ButtonTracker.cpp"> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_Icons.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_analytics\destinations\juce_ThreadedAnalyticsDestination.cpp"> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_PlistOptions.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_analytics\juce_analytics.cpp"> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_ResourceFileHelpers.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_ResourceRc.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_VersionNumbers.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\Build\juce_build_tools\juce_build_tools.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_AbstractFifo.cpp"> @@ -301,6 +315,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_FileSearchPath.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -328,6 +345,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_MemoryBlock.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -1213,6 +1233,15 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_MouseListener.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_DragAndDrop.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_android_ContentSharer.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -1231,13 +1260,7 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_FileChooser.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.cpp"> - <ExcludedFromBuild>true</ExcludedFromBuild> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Clipboard.cpp"> - <ExcludedFromBuild>true</ExcludedFromBuild> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Windowing.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_Windowing.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_win32_DragAndDrop.cpp"> @@ -1441,6 +1464,9 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_ActiveXComponent.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_HWNDComponent.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_SystemTrayIcon.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -1451,7 +1477,7 @@ <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\..\JuceLibraryCode\BinaryData.cpp"/> - <ClCompile Include="..\..\JuceLibraryCode\include_juce_analytics.cpp"/> + <ClCompile Include="..\..\JuceLibraryCode\include_juce_build_tools.cpp"/> <ClCompile Include="..\..\JuceLibraryCode\include_juce_core.cpp"/> <ClCompile Include="..\..\JuceLibraryCode\include_juce_cryptography.cpp"/> <ClCompile Include="..\..\JuceLibraryCode\include_juce_data_structures.cpp"/> @@ -1461,8 +1487,16 @@ <ClCompile Include="..\..\JuceLibraryCode\include_juce_gui_extra.cpp"/> </ItemGroup> <ItemGroup> + <ClInclude Include="..\..\Source\Application\StartPage\jucer_ContentComponents.h"/> + <ClInclude Include="..\..\Source\Application\StartPage\jucer_NewProjectTemplates.h"/> + <ClInclude Include="..\..\Source\Application\StartPage\jucer_NewProjectWizard.h"/> + <ClInclude Include="..\..\Source\Application\StartPage\jucer_StartPageComponent.h"/> + <ClInclude Include="..\..\Source\Application\StartPage\jucer_StartPageTreeHolder.h"/> + <ClInclude Include="..\..\Source\Application\UserAccount\jucer_LicenseController.h"/> + <ClInclude Include="..\..\Source\Application\UserAccount\jucer_LicenseQueryThread.h"/> + <ClInclude Include="..\..\Source\Application\UserAccount\jucer_LicenseState.h"/> + <ClInclude Include="..\..\Source\Application\UserAccount\jucer_LoginFormComponent.h"/> <ClInclude Include="..\..\Source\Application\Windows\jucer_AboutWindowComponent.h"/> - <ClInclude Include="..\..\Source\Application\Windows\jucer_ApplicationUsageDataWindowComponent.h"/> <ClInclude Include="..\..\Source\Application\Windows\jucer_EditorColourSchemeWindowComponent.h"/> <ClInclude Include="..\..\Source\Application\Windows\jucer_FloatingToolWindow.h"/> <ClInclude Include="..\..\Source\Application\Windows\jucer_GlobalPathsWindowComponent.h"/> @@ -1477,7 +1511,6 @@ <ClInclude Include="..\..\Source\Application\jucer_CommonHeaders.h"/> <ClInclude Include="..\..\Source\Application\jucer_Headers.h"/> <ClInclude Include="..\..\Source\Application\jucer_MainWindow.h"/> - <ClInclude Include="..\..\Source\Application\jucer_ProjucerAnalytics.h"/> <ClInclude Include="..\..\Source\BinaryData\Templates\jucer_AnimatedComponentSimpleTemplate.h"/> <ClInclude Include="..\..\Source\BinaryData\Templates\jucer_AnimatedComponentTemplate.h"/> <ClInclude Include="..\..\Source\BinaryData\Templates\jucer_AudioComponentSimpleTemplate.h"/> @@ -1564,9 +1597,6 @@ <ClInclude Include="..\..\Source\ComponentEditor\jucer_ObjectTypes.h"/> <ClInclude Include="..\..\Source\ComponentEditor\jucer_PaintRoutine.h"/> <ClInclude Include="..\..\Source\ComponentEditor\jucer_UtilityFunctions.h"/> - <ClInclude Include="..\..\Source\Licenses\jucer_LicenseController.h"/> - <ClInclude Include="..\..\Source\Licenses\jucer_LicenseThread.h"/> - <ClInclude Include="..\..\Source\Licenses\jucer_LicenseWebview.h"/> <ClInclude Include="..\..\Source\LiveBuildEngine\UI\jucer_ActivityListComponent.h"/> <ClInclude Include="..\..\Source\LiveBuildEngine\UI\jucer_BuildTabStatusComponent.h"/> <ClInclude Include="..\..\Source\LiveBuildEngine\UI\jucer_ComponentListComponent.h"/> @@ -1586,6 +1616,9 @@ <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_MessageIDs.h"/> <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_ProjectBuildInfo.h"/> <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_SourceCodeRange.h"/> + <ClInclude Include="..\..\Source\Project\Modules\jucer_AvailableModulesList.h"/> + <ClInclude Include="..\..\Source\Project\Modules\jucer_ModuleDescription.h"/> + <ClInclude Include="..\..\Source\Project\Modules\jucer_Modules.h"/> <ClInclude Include="..\..\Source\Project\UI\Sidebar\jucer_ExporterTreeItems.h"/> <ClInclude Include="..\..\Source\Project\UI\Sidebar\jucer_FileTreeItems.h"/> <ClInclude Include="..\..\Source\Project\UI\Sidebar\jucer_LiveBuildTab.h"/> @@ -1599,9 +1632,9 @@ <ClInclude Include="..\..\Source\Project\UI\jucer_HeaderComponent.h"/> <ClInclude Include="..\..\Source\Project\UI\jucer_ModulesInformationComponent.h"/> <ClInclude Include="..\..\Source\Project\UI\jucer_ProjectContentComponent.h"/> - <ClInclude Include="..\..\Source\Project\jucer_Module.h"/> + <ClInclude Include="..\..\Source\Project\UI\jucer_ProjectMessagesComponent.h"/> + <ClInclude Include="..\..\Source\Project\UI\jucer_UserAvatarComponent.h"/> <ClInclude Include="..\..\Source\Project\jucer_Project.h"/> - <ClInclude Include="..\..\Source\Project\jucer_ProjectType.h"/> <ClInclude Include="..\..\Source\ProjectSaving\jucer_ProjectExport_Android.h"/> <ClInclude Include="..\..\Source\ProjectSaving\jucer_ProjectExport_CLion.h"/> <ClInclude Include="..\..\Source\ProjectSaving\jucer_ProjectExport_CodeBlocks.h"/> @@ -1618,10 +1651,11 @@ <ClInclude Include="..\..\Source\Utility\Helpers\jucer_Colours.h"/> <ClInclude Include="..\..\Source\Utility\Helpers\jucer_FileHelpers.h"/> <ClInclude Include="..\..\Source\Utility\Helpers\jucer_MiscUtilities.h"/> + <ClInclude Include="..\..\Source\Utility\Helpers\jucer_NewFileWizard.h"/> <ClInclude Include="..\..\Source\Utility\Helpers\jucer_PresetIDs.h"/> - <ClInclude Include="..\..\Source\Utility\Helpers\jucer_RelativePath.h"/> <ClInclude Include="..\..\Source\Utility\Helpers\jucer_TranslationHelpers.h"/> <ClInclude Include="..\..\Source\Utility\Helpers\jucer_ValueSourceHelpers.h"/> + <ClInclude Include="..\..\Source\Utility\Helpers\jucer_ValueWithDefaultWrapper.h"/> <ClInclude Include="..\..\Source\Utility\Helpers\jucer_VersionInfo.h"/> <ClInclude Include="..\..\Source\Utility\PIPs\jucer_PIPGenerator.h"/> <ClInclude Include="..\..\Source\Utility\UI\PropertyComponents\jucer_ColourPropertyComponent.h"/> @@ -1633,27 +1667,17 @@ <ClInclude Include="..\..\Source\Utility\UI\jucer_JucerTreeViewBase.h"/> <ClInclude Include="..\..\Source\Utility\UI\jucer_ProjucerLookAndFeel.h"/> <ClInclude Include="..\..\Source\Utility\UI\jucer_SlidingPanelComponent.h"/> - <ClInclude Include="..\..\Source\Utility\UI\jucer_UserSettingsPopup.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_NewFileWizard.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_NewProjectWizard.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_NewProjectWizardClasses.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_NewProjectWizardComponent.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_Animated.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_AudioApp.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_AudioPlugin.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_Blank.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_Console.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_DLL.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_GUIApp.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_openGL.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_StaticLibrary.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_StartPageComponent.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_TemplateThumbnailsComponent.h"/> - <ClInclude Include="..\..\..\..\modules\juce_analytics\analytics\juce_Analytics.h"/> - <ClInclude Include="..\..\..\..\modules\juce_analytics\analytics\juce_ButtonTracker.h"/> - <ClInclude Include="..\..\..\..\modules\juce_analytics\destinations\juce_AnalyticsDestination.h"/> - <ClInclude Include="..\..\..\..\modules\juce_analytics\destinations\juce_ThreadedAnalyticsDestination.h"/> - <ClInclude Include="..\..\..\..\modules\juce_analytics\juce_analytics.h"/> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_BinaryResourceFile.h"/> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_BuildHelperFunctions.h"/> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_Entitlements.h"/> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_Icons.h"/> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_PlistOptions.h"/> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_ProjectType.h"/> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_RelativePath.h"/> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_ResourceFileHelpers.h"/> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_ResourceRc.h"/> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_VersionNumbers.h"/> + <ClInclude Include="..\..\..\Build\juce_build_tools\juce_build_tools.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\containers\juce_AbstractFifo.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\containers\juce_Array.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\containers\juce_ArrayAllocationBase.h"/> @@ -1678,6 +1702,7 @@ <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_FileOutputStream.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_FileSearchPath.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_MemoryMappedFile.h"/> + <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_WildcardFileFilter.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\javascript\juce_Javascript.h"/> @@ -1691,6 +1716,7 @@ <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_Random.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_Range.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_StatisticsAccumulator.h"/> + <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_Atomic.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_ByteOrder.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_ContainerDeletePolicy.h"/> @@ -1733,6 +1759,7 @@ <ClInclude Include="..\..\..\..\modules\juce_core\streams\juce_SubregionStream.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\streams\juce_URLInputSource.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerSupport.h"/> + <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerWarnings.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_PlatformDefs.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_StandardHeader.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_SystemStats.h"/> @@ -1989,7 +2016,8 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_SelectedItemSet.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_TextDragAndDropTarget.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_TooltipClient.h"/> - <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.h"/> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.h"/> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_MultiTouchMapper.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\positioning\juce_MarkerList.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\positioning\juce_RelativeCoordinate.h"/> @@ -2041,6 +2069,7 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ActiveXControlComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"/> + <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_HWNDComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_NSViewComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ScopedDPIAwarenessDisabler.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_UIViewComponent.h"/> @@ -2059,11 +2088,16 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_mac_CarbonViewWrapperComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\juce_gui_extra.h"/> - <ClInclude Include="..\..\JuceLibraryCode\AppConfig.h"/> <ClInclude Include="..\..\JuceLibraryCode\BinaryData.h"/> <ClInclude Include="..\..\JuceLibraryCode\JuceHeader.h"/> </ItemGroup> <ItemGroup> + <None Include="..\..\..\Build\CMake\LaunchScreen.storyboard"/> + <None Include="..\..\..\Build\CMake\PIPAudioProcessor.cpp.in"/> + <None Include="..\..\..\Build\CMake\PIPComponent.cpp.in"/> + <None Include="..\..\..\Build\CMake\PIPConsole.cpp.in"/> + <None Include="..\..\..\Build\CMake\RecentFilesMenuTemplate.nib"/> + <None Include="..\..\..\Build\CMake\UnityPluginGUIScript.cs.in"/> <None Include="..\..\Source\BinaryData\gradle\gradle-wrapper.jar"/> <None Include="..\..\Source\BinaryData\gradle\gradlew"/> <None Include="..\..\Source\BinaryData\gradle\gradlew.bat"/> @@ -2075,7 +2109,7 @@ <None Include="..\..\Source\BinaryData\Icons\export_linux.svg"/> <None Include="..\..\Source\BinaryData\Icons\export_visualStudio.svg"/> <None Include="..\..\Source\BinaryData\Icons\export_xcode.svg"/> - <None Include="..\..\Source\BinaryData\Icons\huckleberry_icon.svg"/> + <None Include="..\..\Source\BinaryData\Icons\gpl_logo.svg"/> <None Include="..\..\Source\BinaryData\Icons\juce-logo-with-text.svg"/> <None Include="..\..\Source\BinaryData\Icons\juce_icon.png"/> <None Include="..\..\Source\BinaryData\Icons\wizard_AnimatedApp.svg"/> @@ -2088,13 +2122,8 @@ <None Include="..\..\Source\BinaryData\Icons\wizard_Openfile.svg"/> <None Include="..\..\Source\BinaryData\Icons\wizard_OpenGL.svg"/> <None Include="..\..\Source\BinaryData\Icons\wizard_StaticLibrary.svg"/> - <None Include="..\..\Source\BinaryData\Templates\jucer_UnityPluginGUIScript.cs"/> <None Include="..\..\Source\BinaryData\colourscheme_dark.xml"/> <None Include="..\..\Source\BinaryData\colourscheme_light.xml"/> - <None Include="..\..\Source\BinaryData\nothingtoseehere.txt"/> - <None Include="..\..\Source\BinaryData\offlinepage.html"/> - <None Include="..\..\Source\BinaryData\projucer_EULA.txt"/> - <None Include="..\..\Source\BinaryData\RecentFilesMenuTemplate.nib"/> <None Include="..\..\..\..\modules\juce_core\native\java\README.txt"/> <None Include="..\..\..\..\modules\juce_graphics\image_formats\jpglib\changes to libjpeg for JUCE.txt"/> <None Include="..\..\..\..\modules\juce_graphics\image_formats\pnglib\libpng_readme.txt"/> diff --git a/extras/Projucer/Builds/VisualStudio2015/Projucer_App.vcxproj.filters b/extras/Projucer/Builds/VisualStudio2015/Projucer_App.vcxproj.filters index 16e2c05d..f3263ed4 100644 --- a/extras/Projucer/Builds/VisualStudio2015/Projucer_App.vcxproj.filters +++ b/extras/Projucer/Builds/VisualStudio2015/Projucer_App.vcxproj.filters @@ -2,6 +2,12 @@ <Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup> + <Filter Include="Projucer\Application\StartPage"> + <UniqueIdentifier>{1E1D2D75-0ADA-6E9E-105F-2F87632B55AF}</UniqueIdentifier> + </Filter> + <Filter Include="Projucer\Application\UserAccount"> + <UniqueIdentifier>{DA27985D-8427-CE70-CA06-EAF7009CCC60}</UniqueIdentifier> + </Filter> <Filter Include="Projucer\Application\Windows"> <UniqueIdentifier>{DC7E18A5-E854-3D99-627F-AAA88246B712}</UniqueIdentifier> </Filter> @@ -41,15 +47,15 @@ <Filter Include="Projucer\ComponentEditor"> <UniqueIdentifier>{5F21E507-E5E8-0A74-F1AE-874BB67C26CC}</UniqueIdentifier> </Filter> - <Filter Include="Projucer\Licenses"> - <UniqueIdentifier>{E5D23B90-895E-EB0B-AC18-C7EBB25546AE}</UniqueIdentifier> - </Filter> <Filter Include="Projucer\LiveBuildEngine\UI"> <UniqueIdentifier>{E880260F-D9FB-64B6-244B-6F06B70FE9EE}</UniqueIdentifier> </Filter> <Filter Include="Projucer\LiveBuildEngine"> <UniqueIdentifier>{0A3B9446-F50B-3D4E-230F-7ED493541A07}</UniqueIdentifier> </Filter> + <Filter Include="Projucer\Project\Modules"> + <UniqueIdentifier>{F5C79836-30DE-9DC7-9392-DAAB3F04C18E}</UniqueIdentifier> + </Filter> <Filter Include="Projucer\Project\UI\Sidebar"> <UniqueIdentifier>{A0A94AE6-B447-151A-D0DA-FAE9B5410EBF}</UniqueIdentifier> </Filter> @@ -80,20 +86,14 @@ <Filter Include="Projucer\Utility"> <UniqueIdentifier>{F77CA057-8DE4-E076-7EB6-D2646794864B}</UniqueIdentifier> </Filter> - <Filter Include="Projucer\Wizards"> - <UniqueIdentifier>{4BBA3556-B2A1-3008-8BE1-F82DE6666552}</UniqueIdentifier> - </Filter> <Filter Include="Projucer"> <UniqueIdentifier>{7DBEF27C-2AFE-DA02-1DBF-E80FAAC99EA7}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_analytics\analytics"> - <UniqueIdentifier>{E3CEC08A-FA14-D343-5BFF-3D6A4A4FD713}</UniqueIdentifier> - </Filter> - <Filter Include="JUCE Modules\juce_analytics\destinations"> - <UniqueIdentifier>{B3BC836A-3932-C1E4-CA3C-A1C0D83281BA}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_build_tools\utils"> + <UniqueIdentifier>{D9FAFF6D-6737-F775-056A-D0B29BE13820}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_analytics"> - <UniqueIdentifier>{97F7F593-75F8-D6B2-DC96-C946C3976226}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_build_tools"> + <UniqueIdentifier>{065C11E4-EB37-5B72-0A01-F549675EB866}</UniqueIdentifier> </Filter> <Filter Include="JUCE Modules\juce_core\containers"> <UniqueIdentifier>{42F7BE9D-3C8A-AE26-289B-8F355C068036}</UniqueIdentifier> @@ -269,6 +269,9 @@ <Filter Include="JUCE Modules\juce_gui_basics\mouse"> <UniqueIdentifier>{FE3CB19C-EF43-5CF5-DAF0-09D4E43D0AB9}</UniqueIdentifier> </Filter> + <Filter Include="JUCE Modules\juce_gui_basics\native\x11"> + <UniqueIdentifier>{FE7E6CD5-C7A0-DB20-4E7E-D6E7F08C4578}</UniqueIdentifier> + </Filter> <Filter Include="JUCE Modules\juce_gui_basics\native"> <UniqueIdentifier>{895C2D33-E08D-B1BA-BB36-FC4CA65090C8}</UniqueIdentifier> </Filter> @@ -313,6 +316,12 @@ </Filter> </ItemGroup> <ItemGroup> + <ClCompile Include="..\..\Source\Application\StartPage\jucer_NewProjectWizard.cpp"> + <Filter>Projucer\Application\StartPage</Filter> + </ClCompile> + <ClCompile Include="..\..\Source\Application\StartPage\jucer_StartPageComponent.cpp"> + <Filter>Projucer\Application\StartPage</Filter> + </ClCompile> <ClCompile Include="..\..\Source\Application\jucer_Application.cpp"> <Filter>Projucer\Application</Filter> </ClCompile> @@ -328,9 +337,6 @@ <ClCompile Include="..\..\Source\Application\jucer_MainWindow.cpp"> <Filter>Projucer\Application</Filter> </ClCompile> - <ClCompile Include="..\..\Source\Application\jucer_ProjucerAnalytics.cpp"> - <Filter>Projucer\Application</Filter> - </ClCompile> <ClCompile Include="..\..\Source\BinaryData\Templates\jucer_AnimatedComponentTemplate.cpp"> <Filter>Projucer\BinaryData\Templates</Filter> </ClCompile> @@ -355,9 +361,6 @@ <ClCompile Include="..\..\Source\BinaryData\Templates\jucer_MainTemplate_NoWindow.cpp"> <Filter>Projucer\BinaryData\Templates</Filter> </ClCompile> - <ClCompile Include="..\..\Source\BinaryData\Templates\jucer_MainTemplate_SimpleWindow.cpp"> - <Filter>Projucer\BinaryData\Templates</Filter> - </ClCompile> <ClCompile Include="..\..\Source\BinaryData\Templates\jucer_MainTemplate_Window.cpp"> <Filter>Projucer\BinaryData\Templates</Filter> </ClCompile> @@ -370,8 +373,8 @@ <ClCompile Include="..\..\Source\BinaryData\Templates\jucer_OpenGLComponentTemplate.cpp"> <Filter>Projucer\BinaryData\Templates</Filter> </ClCompile> - <ClCompile Include="..\..\Source\BinaryData\Templates\jucer_PIPMain.cpp"> - <Filter>Projucer\BinaryData\Templates</Filter> + <ClCompile Include="..\..\..\Build\CMake\juce_runtime_arch_detection.cpp"> + <Filter>Projucer\BinaryData</Filter> </ClCompile> <ClCompile Include="..\..\Source\CodeEditor\jucer_DocumentEditorComponent.cpp"> <Filter>Projucer\CodeEditor</Filter> @@ -448,9 +451,6 @@ <ClCompile Include="..\..\Source\ComponentEditor\jucer_PaintRoutine.cpp"> <Filter>Projucer\ComponentEditor</Filter> </ClCompile> - <ClCompile Include="..\..\Source\Licenses\jucer_LicenseController.cpp"> - <Filter>Projucer\Licenses</Filter> - </ClCompile> <ClCompile Include="..\..\Source\LiveBuildEngine\jucer_CompileEngineClient.cpp"> <Filter>Projucer\LiveBuildEngine</Filter> </ClCompile> @@ -460,15 +460,15 @@ <ClCompile Include="..\..\Source\LiveBuildEngine\jucer_DownloadCompileEngineThread.cpp"> <Filter>Projucer\LiveBuildEngine</Filter> </ClCompile> + <ClCompile Include="..\..\Source\Project\Modules\jucer_Modules.cpp"> + <Filter>Projucer\Project\Modules</Filter> + </ClCompile> <ClCompile Include="..\..\Source\Project\UI\jucer_HeaderComponent.cpp"> <Filter>Projucer\Project\UI</Filter> </ClCompile> <ClCompile Include="..\..\Source\Project\UI\jucer_ProjectContentComponent.cpp"> <Filter>Projucer\Project\UI</Filter> </ClCompile> - <ClCompile Include="..\..\Source\Project\jucer_Module.cpp"> - <Filter>Projucer\Project</Filter> - </ClCompile> <ClCompile Include="..\..\Source\Project\jucer_Project.cpp"> <Filter>Projucer\Project</Filter> </ClCompile> @@ -496,6 +496,9 @@ <ClCompile Include="..\..\Source\Utility\Helpers\jucer_MiscUtilities.cpp"> <Filter>Projucer\Utility\Helpers</Filter> </ClCompile> + <ClCompile Include="..\..\Source\Utility\Helpers\jucer_NewFileWizard.cpp"> + <Filter>Projucer\Utility\Helpers</Filter> + </ClCompile> <ClCompile Include="..\..\Source\Utility\Helpers\jucer_VersionInfo.cpp"> <Filter>Projucer\Utility\Helpers</Filter> </ClCompile> @@ -514,23 +517,35 @@ <ClCompile Include="..\..\Source\Utility\UI\jucer_SlidingPanelComponent.cpp"> <Filter>Projucer\Utility\UI</Filter> </ClCompile> - <ClCompile Include="..\..\Source\Wizards\jucer_NewFileWizard.cpp"> - <Filter>Projucer\Wizards</Filter> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_BinaryResourceFile.cpp"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClCompile> - <ClCompile Include="..\..\Source\Wizards\jucer_NewProjectWizardClasses.cpp"> - <Filter>Projucer\Wizards</Filter> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_BuildHelperFunctions.cpp"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_analytics\analytics\juce_Analytics.cpp"> - <Filter>JUCE Modules\juce_analytics\analytics</Filter> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_CppTokeniserFunctions.cpp"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_analytics\analytics\juce_ButtonTracker.cpp"> - <Filter>JUCE Modules\juce_analytics\analytics</Filter> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_Entitlements.cpp"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_analytics\destinations\juce_ThreadedAnalyticsDestination.cpp"> - <Filter>JUCE Modules\juce_analytics\destinations</Filter> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_Icons.cpp"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_analytics\juce_analytics.cpp"> - <Filter>JUCE Modules\juce_analytics</Filter> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_PlistOptions.cpp"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> + </ClCompile> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_ResourceFileHelpers.cpp"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> + </ClCompile> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_ResourceRc.cpp"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> + </ClCompile> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_VersionNumbers.cpp"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> + </ClCompile> + <ClCompile Include="..\..\..\Build\juce_build_tools\juce_build_tools.cpp"> + <Filter>JUCE Modules\juce_build_tools</Filter> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_AbstractFifo.cpp"> <Filter>JUCE Modules\juce_core\containers</Filter> @@ -580,6 +595,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_FileSearchPath.cpp"> <Filter>JUCE Modules\juce_core\files</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.cpp"> + <Filter>JUCE Modules\juce_core\files</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.cpp"> <Filter>JUCE Modules\juce_core\files</Filter> </ClCompile> @@ -607,6 +625,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> <Filter>JUCE Modules\juce_core\maths</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.cpp"> + <Filter>JUCE Modules\juce_core\memory</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_MemoryBlock.cpp"> <Filter>JUCE Modules\juce_core\memory</Filter> </ClCompile> @@ -1534,6 +1555,15 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_MouseListener.cpp"> <Filter>JUCE Modules\juce_gui_basics\mouse</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_DragAndDrop.cpp"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.cpp"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.cpp"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_android_ContentSharer.cpp"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> </ClCompile> @@ -1561,13 +1591,7 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_FileChooser.cpp"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.cpp"> - <Filter>JUCE Modules\juce_gui_basics\native</Filter> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Clipboard.cpp"> - <Filter>JUCE Modules\juce_gui_basics\native</Filter> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Windowing.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_Windowing.cpp"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_mac_FileChooser.mm"> @@ -1801,6 +1825,9 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_ActiveXComponent.cpp"> <Filter>JUCE Modules\juce_gui_extra\native</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_HWNDComponent.cpp"> + <Filter>JUCE Modules\juce_gui_extra\native</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_SystemTrayIcon.cpp"> <Filter>JUCE Modules\juce_gui_extra\native</Filter> </ClCompile> @@ -1816,7 +1843,7 @@ <ClCompile Include="..\..\JuceLibraryCode\BinaryData.cpp"> <Filter>JUCE Library Code</Filter> </ClCompile> - <ClCompile Include="..\..\JuceLibraryCode\include_juce_analytics.cpp"> + <ClCompile Include="..\..\JuceLibraryCode\include_juce_build_tools.cpp"> <Filter>JUCE Library Code</Filter> </ClCompile> <ClCompile Include="..\..\JuceLibraryCode\include_juce_core.cpp"> @@ -1842,10 +1869,34 @@ </ClCompile> </ItemGroup> <ItemGroup> - <ClInclude Include="..\..\Source\Application\Windows\jucer_AboutWindowComponent.h"> - <Filter>Projucer\Application\Windows</Filter> + <ClInclude Include="..\..\Source\Application\StartPage\jucer_ContentComponents.h"> + <Filter>Projucer\Application\StartPage</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\Application\StartPage\jucer_NewProjectTemplates.h"> + <Filter>Projucer\Application\StartPage</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\Application\StartPage\jucer_NewProjectWizard.h"> + <Filter>Projucer\Application\StartPage</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Application\Windows\jucer_ApplicationUsageDataWindowComponent.h"> + <ClInclude Include="..\..\Source\Application\StartPage\jucer_StartPageComponent.h"> + <Filter>Projucer\Application\StartPage</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\Application\StartPage\jucer_StartPageTreeHolder.h"> + <Filter>Projucer\Application\StartPage</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\Application\UserAccount\jucer_LicenseController.h"> + <Filter>Projucer\Application\UserAccount</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\Application\UserAccount\jucer_LicenseQueryThread.h"> + <Filter>Projucer\Application\UserAccount</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\Application\UserAccount\jucer_LicenseState.h"> + <Filter>Projucer\Application\UserAccount</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\Application\UserAccount\jucer_LoginFormComponent.h"> + <Filter>Projucer\Application\UserAccount</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\Application\Windows\jucer_AboutWindowComponent.h"> <Filter>Projucer\Application\Windows</Filter> </ClInclude> <ClInclude Include="..\..\Source\Application\Windows\jucer_EditorColourSchemeWindowComponent.h"> @@ -1890,9 +1941,6 @@ <ClInclude Include="..\..\Source\Application\jucer_MainWindow.h"> <Filter>Projucer\Application</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Application\jucer_ProjucerAnalytics.h"> - <Filter>Projucer\Application</Filter> - </ClInclude> <ClInclude Include="..\..\Source\BinaryData\Templates\jucer_AnimatedComponentSimpleTemplate.h"> <Filter>Projucer\BinaryData\Templates</Filter> </ClInclude> @@ -2151,15 +2199,6 @@ <ClInclude Include="..\..\Source\ComponentEditor\jucer_UtilityFunctions.h"> <Filter>Projucer\ComponentEditor</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Licenses\jucer_LicenseController.h"> - <Filter>Projucer\Licenses</Filter> - </ClInclude> - <ClInclude Include="..\..\Source\Licenses\jucer_LicenseThread.h"> - <Filter>Projucer\Licenses</Filter> - </ClInclude> - <ClInclude Include="..\..\Source\Licenses\jucer_LicenseWebview.h"> - <Filter>Projucer\Licenses</Filter> - </ClInclude> <ClInclude Include="..\..\Source\LiveBuildEngine\UI\jucer_ActivityListComponent.h"> <Filter>Projucer\LiveBuildEngine\UI</Filter> </ClInclude> @@ -2217,6 +2256,15 @@ <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_SourceCodeRange.h"> <Filter>Projucer\LiveBuildEngine</Filter> </ClInclude> + <ClInclude Include="..\..\Source\Project\Modules\jucer_AvailableModulesList.h"> + <Filter>Projucer\Project\Modules</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\Project\Modules\jucer_ModuleDescription.h"> + <Filter>Projucer\Project\Modules</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\Project\Modules\jucer_Modules.h"> + <Filter>Projucer\Project\Modules</Filter> + </ClInclude> <ClInclude Include="..\..\Source\Project\UI\Sidebar\jucer_ExporterTreeItems.h"> <Filter>Projucer\Project\UI\Sidebar</Filter> </ClInclude> @@ -2256,13 +2304,13 @@ <ClInclude Include="..\..\Source\Project\UI\jucer_ProjectContentComponent.h"> <Filter>Projucer\Project\UI</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Project\jucer_Module.h"> - <Filter>Projucer\Project</Filter> + <ClInclude Include="..\..\Source\Project\UI\jucer_ProjectMessagesComponent.h"> + <Filter>Projucer\Project\UI</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Project\jucer_Project.h"> - <Filter>Projucer\Project</Filter> + <ClInclude Include="..\..\Source\Project\UI\jucer_UserAvatarComponent.h"> + <Filter>Projucer\Project\UI</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Project\jucer_ProjectType.h"> + <ClInclude Include="..\..\Source\Project\jucer_Project.h"> <Filter>Projucer\Project</Filter> </ClInclude> <ClInclude Include="..\..\Source\ProjectSaving\jucer_ProjectExport_Android.h"> @@ -2313,10 +2361,10 @@ <ClInclude Include="..\..\Source\Utility\Helpers\jucer_MiscUtilities.h"> <Filter>Projucer\Utility\Helpers</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Utility\Helpers\jucer_PresetIDs.h"> + <ClInclude Include="..\..\Source\Utility\Helpers\jucer_NewFileWizard.h"> <Filter>Projucer\Utility\Helpers</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Utility\Helpers\jucer_RelativePath.h"> + <ClInclude Include="..\..\Source\Utility\Helpers\jucer_PresetIDs.h"> <Filter>Projucer\Utility\Helpers</Filter> </ClInclude> <ClInclude Include="..\..\Source\Utility\Helpers\jucer_TranslationHelpers.h"> @@ -2325,6 +2373,9 @@ <ClInclude Include="..\..\Source\Utility\Helpers\jucer_ValueSourceHelpers.h"> <Filter>Projucer\Utility\Helpers</Filter> </ClInclude> + <ClInclude Include="..\..\Source\Utility\Helpers\jucer_ValueWithDefaultWrapper.h"> + <Filter>Projucer\Utility\Helpers</Filter> + </ClInclude> <ClInclude Include="..\..\Source\Utility\Helpers\jucer_VersionInfo.h"> <Filter>Projucer\Utility\Helpers</Filter> </ClInclude> @@ -2358,68 +2409,38 @@ <ClInclude Include="..\..\Source\Utility\UI\jucer_SlidingPanelComponent.h"> <Filter>Projucer\Utility\UI</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Utility\UI\jucer_UserSettingsPopup.h"> - <Filter>Projucer\Utility\UI</Filter> - </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_NewFileWizard.h"> - <Filter>Projucer\Wizards</Filter> - </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_NewProjectWizard.h"> - <Filter>Projucer\Wizards</Filter> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_BinaryResourceFile.h"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_NewProjectWizardClasses.h"> - <Filter>Projucer\Wizards</Filter> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_BuildHelperFunctions.h"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_NewProjectWizardComponent.h"> - <Filter>Projucer\Wizards</Filter> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_Entitlements.h"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_Animated.h"> - <Filter>Projucer\Wizards</Filter> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_Icons.h"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_AudioApp.h"> - <Filter>Projucer\Wizards</Filter> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_PlistOptions.h"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_AudioPlugin.h"> - <Filter>Projucer\Wizards</Filter> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_ProjectType.h"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_Blank.h"> - <Filter>Projucer\Wizards</Filter> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_RelativePath.h"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_Console.h"> - <Filter>Projucer\Wizards</Filter> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_ResourceFileHelpers.h"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_DLL.h"> - <Filter>Projucer\Wizards</Filter> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_ResourceRc.h"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_GUIApp.h"> - <Filter>Projucer\Wizards</Filter> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_VersionNumbers.h"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_openGL.h"> - <Filter>Projucer\Wizards</Filter> - </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_StaticLibrary.h"> - <Filter>Projucer\Wizards</Filter> - </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_StartPageComponent.h"> - <Filter>Projucer\Wizards</Filter> - </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_TemplateThumbnailsComponent.h"> - <Filter>Projucer\Wizards</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_analytics\analytics\juce_Analytics.h"> - <Filter>JUCE Modules\juce_analytics\analytics</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_analytics\analytics\juce_ButtonTracker.h"> - <Filter>JUCE Modules\juce_analytics\analytics</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_analytics\destinations\juce_AnalyticsDestination.h"> - <Filter>JUCE Modules\juce_analytics\destinations</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_analytics\destinations\juce_ThreadedAnalyticsDestination.h"> - <Filter>JUCE Modules\juce_analytics\destinations</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_analytics\juce_analytics.h"> - <Filter>JUCE Modules\juce_analytics</Filter> + <ClInclude Include="..\..\..\Build\juce_build_tools\juce_build_tools.h"> + <Filter>JUCE Modules\juce_build_tools</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_core\containers\juce_AbstractFifo.h"> <Filter>JUCE Modules\juce_core\containers</Filter> @@ -2493,6 +2514,9 @@ <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_MemoryMappedFile.h"> <Filter>JUCE Modules\juce_core\files</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.h"> + <Filter>JUCE Modules\juce_core\files</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.h"> <Filter>JUCE Modules\juce_core\files</Filter> </ClInclude> @@ -2532,6 +2556,9 @@ <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_StatisticsAccumulator.h"> <Filter>JUCE Modules\juce_core\maths</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.h"> + <Filter>JUCE Modules\juce_core\memory</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_Atomic.h"> <Filter>JUCE Modules\juce_core\memory</Filter> </ClInclude> @@ -2658,6 +2685,9 @@ <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerSupport.h"> <Filter>JUCE Modules\juce_core\system</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerWarnings.h"> + <Filter>JUCE Modules\juce_core\system</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_PlatformDefs.h"> <Filter>JUCE Modules\juce_core\system</Filter> </ClInclude> @@ -3426,8 +3456,11 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_TooltipClient.h"> <Filter>JUCE Modules\juce_gui_basics\mouse</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.h"> - <Filter>JUCE Modules\juce_gui_basics\native</Filter> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.h"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.h"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_MultiTouchMapper.h"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> @@ -3582,6 +3615,9 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"> <Filter>JUCE Modules\juce_gui_extra\embedding</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_HWNDComponent.h"> + <Filter>JUCE Modules\juce_gui_extra\embedding</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_NSViewComponent.h"> <Filter>JUCE Modules\juce_gui_extra\embedding</Filter> </ClInclude> @@ -3636,9 +3672,6 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_extra\juce_gui_extra.h"> <Filter>JUCE Modules\juce_gui_extra</Filter> </ClInclude> - <ClInclude Include="..\..\JuceLibraryCode\AppConfig.h"> - <Filter>JUCE Library Code</Filter> - </ClInclude> <ClInclude Include="..\..\JuceLibraryCode\BinaryData.h"> <Filter>JUCE Library Code</Filter> </ClInclude> @@ -3647,6 +3680,24 @@ </ClInclude> </ItemGroup> <ItemGroup> + <None Include="..\..\..\Build\CMake\LaunchScreen.storyboard"> + <Filter>Projucer\BinaryData</Filter> + </None> + <None Include="..\..\..\Build\CMake\PIPAudioProcessor.cpp.in"> + <Filter>Projucer\BinaryData</Filter> + </None> + <None Include="..\..\..\Build\CMake\PIPComponent.cpp.in"> + <Filter>Projucer\BinaryData</Filter> + </None> + <None Include="..\..\..\Build\CMake\PIPConsole.cpp.in"> + <Filter>Projucer\BinaryData</Filter> + </None> + <None Include="..\..\..\Build\CMake\RecentFilesMenuTemplate.nib"> + <Filter>Projucer\BinaryData</Filter> + </None> + <None Include="..\..\..\Build\CMake\UnityPluginGUIScript.cs.in"> + <Filter>Projucer\BinaryData</Filter> + </None> <None Include="..\..\Source\BinaryData\gradle\gradle-wrapper.jar"> <Filter>Projucer\BinaryData\gradle</Filter> </None> @@ -3680,7 +3731,7 @@ <None Include="..\..\Source\BinaryData\Icons\export_xcode.svg"> <Filter>Projucer\BinaryData\Icons</Filter> </None> - <None Include="..\..\Source\BinaryData\Icons\huckleberry_icon.svg"> + <None Include="..\..\Source\BinaryData\Icons\gpl_logo.svg"> <Filter>Projucer\BinaryData\Icons</Filter> </None> <None Include="..\..\Source\BinaryData\Icons\juce-logo-with-text.svg"> @@ -3719,27 +3770,12 @@ <None Include="..\..\Source\BinaryData\Icons\wizard_StaticLibrary.svg"> <Filter>Projucer\BinaryData\Icons</Filter> </None> - <None Include="..\..\Source\BinaryData\Templates\jucer_UnityPluginGUIScript.cs"> - <Filter>Projucer\BinaryData\Templates</Filter> - </None> <None Include="..\..\Source\BinaryData\colourscheme_dark.xml"> <Filter>Projucer\BinaryData</Filter> </None> <None Include="..\..\Source\BinaryData\colourscheme_light.xml"> <Filter>Projucer\BinaryData</Filter> </None> - <None Include="..\..\Source\BinaryData\nothingtoseehere.txt"> - <Filter>Projucer\BinaryData</Filter> - </None> - <None Include="..\..\Source\BinaryData\offlinepage.html"> - <Filter>Projucer\BinaryData</Filter> - </None> - <None Include="..\..\Source\BinaryData\projucer_EULA.txt"> - <Filter>Projucer\BinaryData</Filter> - </None> - <None Include="..\..\Source\BinaryData\RecentFilesMenuTemplate.nib"> - <Filter>Projucer\BinaryData</Filter> - </None> <None Include="..\..\..\..\modules\juce_core\native\java\README.txt"> <Filter>JUCE Modules\juce_core\native\java</Filter> </None> diff --git a/extras/Projucer/Builds/VisualStudio2015/resources.rc b/extras/Projucer/Builds/VisualStudio2015/resources.rc index 3cc301e6..cb7ae4b8 100644 --- a/extras/Projucer/Builds/VisualStudio2015/resources.rc +++ b/extras/Projucer/Builds/VisualStudio2015/resources.rc @@ -1,3 +1,5 @@ +#pragma code_page(65001) + #ifdef JUCE_USER_DEFINED_RC_FILE #include JUCE_USER_DEFINED_RC_FILE #else @@ -7,18 +9,18 @@ #include <windows.h> VS_VERSION_INFO VERSIONINFO -FILEVERSION 5,4,7,0 +FILEVERSION 6,0,5,0 BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904E4" BEGIN - VALUE "CompanyName", "ROLI Ltd.\0" - VALUE "LegalCopyright", "ROLI Ltd.\0" + VALUE "CompanyName", "Raw Material Software Limited\0" + VALUE "LegalCopyright", "Raw Material Software Limited\0" VALUE "FileDescription", "Projucer\0" - VALUE "FileVersion", "5.4.7\0" + VALUE "FileVersion", "6.0.5\0" VALUE "ProductName", "Projucer\0" - VALUE "ProductVersion", "5.4.7\0" + VALUE "ProductVersion", "6.0.5\0" END END diff --git a/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj b/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj index 1bfe1bf0..eb01454f 100644 --- a/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj +++ b/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj @@ -63,11 +63,11 @@ <ClCompile> <Optimization>Disabled</Optimization> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCER_VS2017_78A5024=1;JUCE_APP_VERSION=5.4.7;JUCE_APP_VERSION_HEX=0x50407;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\Build;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCE_DISPLAY_SPLASH_SCREEN=0;JUCE_USE_DARK_SPLASH_SCREEN=1;JUCE_PROJUCER_VERSION=0x60005;JUCE_MODULE_AVAILABLE_juce_build_tools=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_LOG_ASSERTIONS=1;JUCE_USE_CURL=1;JUCE_LOAD_CURL_SYMBOLS_LAZILY=1;JUCE_ALLOW_STATIC_NULL_VARIABLES=0;JUCE_STRICT_REFCOUNTEDPOINTER=1;JUCE_WEB_BROWSER=0;JUCE_STANDALONE_APPLICATION=1;JUCER_VS2017_78A5024=1;JUCE_APP_VERSION=6.0.5;JUCE_APP_VERSION_HEX=0x60005;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> <RuntimeTypeInfo>true</RuntimeTypeInfo> - <PrecompiledHeader/> + <PrecompiledHeader>NotUsing</PrecompiledHeader> <AssemblerListingLocation>$(IntDir)\</AssemblerListingLocation> <ObjectFileName>$(IntDir)\</ObjectFileName> <ProgramDataBaseFileName>$(IntDir)\</ProgramDataBaseFileName> @@ -105,11 +105,11 @@ </Midl> <ClCompile> <Optimization>Full</Optimization> - <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCER_VS2017_78A5024=1;JUCE_APP_VERSION=5.4.7;JUCE_APP_VERSION_HEX=0x50407;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\Build;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCE_DISPLAY_SPLASH_SCREEN=0;JUCE_USE_DARK_SPLASH_SCREEN=1;JUCE_PROJUCER_VERSION=0x60005;JUCE_MODULE_AVAILABLE_juce_build_tools=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_LOG_ASSERTIONS=1;JUCE_USE_CURL=1;JUCE_LOAD_CURL_SYMBOLS_LAZILY=1;JUCE_ALLOW_STATIC_NULL_VARIABLES=0;JUCE_STRICT_REFCOUNTEDPOINTER=1;JUCE_WEB_BROWSER=0;JUCE_STANDALONE_APPLICATION=1;JUCER_VS2017_78A5024=1;JUCE_APP_VERSION=6.0.5;JUCE_APP_VERSION_HEX=0x60005;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreaded</RuntimeLibrary> <RuntimeTypeInfo>true</RuntimeTypeInfo> - <PrecompiledHeader/> + <PrecompiledHeader>NotUsing</PrecompiledHeader> <AssemblerListingLocation>$(IntDir)\</AssemblerListingLocation> <ObjectFileName>$(IntDir)\</ObjectFileName> <ProgramDataBaseFileName>$(IntDir)\</ProgramDataBaseFileName> @@ -140,6 +140,8 @@ <Lib/> </ItemDefinitionGroup> <ItemGroup> + <ClCompile Include="..\..\Source\Application\StartPage\jucer_NewProjectWizard.cpp"/> + <ClCompile Include="..\..\Source\Application\StartPage\jucer_StartPageComponent.cpp"/> <ClCompile Include="..\..\Source\Application\jucer_Application.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -147,7 +149,6 @@ <ClCompile Include="..\..\Source\Application\jucer_CommandLine.cpp"/> <ClCompile Include="..\..\Source\Application\jucer_Main.cpp"/> <ClCompile Include="..\..\Source\Application\jucer_MainWindow.cpp"/> - <ClCompile Include="..\..\Source\Application\jucer_ProjucerAnalytics.cpp"/> <ClCompile Include="..\..\Source\BinaryData\Templates\jucer_AnimatedComponentTemplate.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -172,9 +173,6 @@ <ClCompile Include="..\..\Source\BinaryData\Templates\jucer_MainTemplate_NoWindow.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\Source\BinaryData\Templates\jucer_MainTemplate_SimpleWindow.cpp"> - <ExcludedFromBuild>true</ExcludedFromBuild> - </ClCompile> <ClCompile Include="..\..\Source\BinaryData\Templates\jucer_MainTemplate_Window.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -187,7 +185,7 @@ <ClCompile Include="..\..\Source\BinaryData\Templates\jucer_OpenGLComponentTemplate.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\Source\BinaryData\Templates\jucer_PIPMain.cpp"> + <ClCompile Include="..\..\..\Build\CMake\juce_runtime_arch_detection.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\..\Source\CodeEditor\jucer_DocumentEditorComponent.cpp"/> @@ -215,15 +213,14 @@ <ClCompile Include="..\..\Source\ComponentEditor\jucer_JucerDocument.cpp"/> <ClCompile Include="..\..\Source\ComponentEditor\jucer_ObjectTypes.cpp"/> <ClCompile Include="..\..\Source\ComponentEditor\jucer_PaintRoutine.cpp"/> - <ClCompile Include="..\..\Source\Licenses\jucer_LicenseController.cpp"/> <ClCompile Include="..\..\Source\LiveBuildEngine\jucer_CompileEngineClient.cpp"/> <ClCompile Include="..\..\Source\LiveBuildEngine\jucer_CompileEngineServer.cpp"/> <ClCompile Include="..\..\Source\LiveBuildEngine\jucer_DownloadCompileEngineThread.cpp"/> + <ClCompile Include="..\..\Source\Project\Modules\jucer_Modules.cpp"/> <ClCompile Include="..\..\Source\Project\UI\jucer_HeaderComponent.cpp"/> <ClCompile Include="..\..\Source\Project\UI\jucer_ProjectContentComponent.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\Source\Project\jucer_Module.cpp"/> <ClCompile Include="..\..\Source\Project\jucer_Project.cpp"/> <ClCompile Include="..\..\Source\ProjectSaving\jucer_ProjectExporter.cpp"/> <ClCompile Include="..\..\Source\ProjectSaving\jucer_ProjectSaver.cpp"/> @@ -233,24 +230,41 @@ <ClCompile Include="..\..\Source\Utility\Helpers\jucer_CodeHelpers.cpp"/> <ClCompile Include="..\..\Source\Utility\Helpers\jucer_FileHelpers.cpp"/> <ClCompile Include="..\..\Source\Utility\Helpers\jucer_MiscUtilities.cpp"/> + <ClCompile Include="..\..\Source\Utility\Helpers\jucer_NewFileWizard.cpp"/> <ClCompile Include="..\..\Source\Utility\Helpers\jucer_VersionInfo.cpp"/> <ClCompile Include="..\..\Source\Utility\PIPs\jucer_PIPGenerator.cpp"/> <ClCompile Include="..\..\Source\Utility\UI\jucer_Icons.cpp"/> <ClCompile Include="..\..\Source\Utility\UI\jucer_JucerTreeViewBase.cpp"/> <ClCompile Include="..\..\Source\Utility\UI\jucer_ProjucerLookAndFeel.cpp"/> <ClCompile Include="..\..\Source\Utility\UI\jucer_SlidingPanelComponent.cpp"/> - <ClCompile Include="..\..\Source\Wizards\jucer_NewFileWizard.cpp"/> - <ClCompile Include="..\..\Source\Wizards\jucer_NewProjectWizardClasses.cpp"/> - <ClCompile Include="..\..\..\..\modules\juce_analytics\analytics\juce_Analytics.cpp"> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_BinaryResourceFile.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_BuildHelperFunctions.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_CppTokeniserFunctions.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_Entitlements.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_analytics\analytics\juce_ButtonTracker.cpp"> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_Icons.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_analytics\destinations\juce_ThreadedAnalyticsDestination.cpp"> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_PlistOptions.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_analytics\juce_analytics.cpp"> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_ResourceFileHelpers.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_ResourceRc.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_VersionNumbers.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\Build\juce_build_tools\juce_build_tools.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_AbstractFifo.cpp"> @@ -301,6 +315,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_FileSearchPath.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -328,6 +345,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_MemoryBlock.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -1213,6 +1233,15 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_MouseListener.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_DragAndDrop.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_android_ContentSharer.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -1231,13 +1260,7 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_FileChooser.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.cpp"> - <ExcludedFromBuild>true</ExcludedFromBuild> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Clipboard.cpp"> - <ExcludedFromBuild>true</ExcludedFromBuild> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Windowing.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_Windowing.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_win32_DragAndDrop.cpp"> @@ -1441,6 +1464,9 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_ActiveXComponent.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_HWNDComponent.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_SystemTrayIcon.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -1451,7 +1477,7 @@ <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\..\JuceLibraryCode\BinaryData.cpp"/> - <ClCompile Include="..\..\JuceLibraryCode\include_juce_analytics.cpp"/> + <ClCompile Include="..\..\JuceLibraryCode\include_juce_build_tools.cpp"/> <ClCompile Include="..\..\JuceLibraryCode\include_juce_core.cpp"/> <ClCompile Include="..\..\JuceLibraryCode\include_juce_cryptography.cpp"/> <ClCompile Include="..\..\JuceLibraryCode\include_juce_data_structures.cpp"/> @@ -1461,8 +1487,16 @@ <ClCompile Include="..\..\JuceLibraryCode\include_juce_gui_extra.cpp"/> </ItemGroup> <ItemGroup> + <ClInclude Include="..\..\Source\Application\StartPage\jucer_ContentComponents.h"/> + <ClInclude Include="..\..\Source\Application\StartPage\jucer_NewProjectTemplates.h"/> + <ClInclude Include="..\..\Source\Application\StartPage\jucer_NewProjectWizard.h"/> + <ClInclude Include="..\..\Source\Application\StartPage\jucer_StartPageComponent.h"/> + <ClInclude Include="..\..\Source\Application\StartPage\jucer_StartPageTreeHolder.h"/> + <ClInclude Include="..\..\Source\Application\UserAccount\jucer_LicenseController.h"/> + <ClInclude Include="..\..\Source\Application\UserAccount\jucer_LicenseQueryThread.h"/> + <ClInclude Include="..\..\Source\Application\UserAccount\jucer_LicenseState.h"/> + <ClInclude Include="..\..\Source\Application\UserAccount\jucer_LoginFormComponent.h"/> <ClInclude Include="..\..\Source\Application\Windows\jucer_AboutWindowComponent.h"/> - <ClInclude Include="..\..\Source\Application\Windows\jucer_ApplicationUsageDataWindowComponent.h"/> <ClInclude Include="..\..\Source\Application\Windows\jucer_EditorColourSchemeWindowComponent.h"/> <ClInclude Include="..\..\Source\Application\Windows\jucer_FloatingToolWindow.h"/> <ClInclude Include="..\..\Source\Application\Windows\jucer_GlobalPathsWindowComponent.h"/> @@ -1477,7 +1511,6 @@ <ClInclude Include="..\..\Source\Application\jucer_CommonHeaders.h"/> <ClInclude Include="..\..\Source\Application\jucer_Headers.h"/> <ClInclude Include="..\..\Source\Application\jucer_MainWindow.h"/> - <ClInclude Include="..\..\Source\Application\jucer_ProjucerAnalytics.h"/> <ClInclude Include="..\..\Source\BinaryData\Templates\jucer_AnimatedComponentSimpleTemplate.h"/> <ClInclude Include="..\..\Source\BinaryData\Templates\jucer_AnimatedComponentTemplate.h"/> <ClInclude Include="..\..\Source\BinaryData\Templates\jucer_AudioComponentSimpleTemplate.h"/> @@ -1564,9 +1597,6 @@ <ClInclude Include="..\..\Source\ComponentEditor\jucer_ObjectTypes.h"/> <ClInclude Include="..\..\Source\ComponentEditor\jucer_PaintRoutine.h"/> <ClInclude Include="..\..\Source\ComponentEditor\jucer_UtilityFunctions.h"/> - <ClInclude Include="..\..\Source\Licenses\jucer_LicenseController.h"/> - <ClInclude Include="..\..\Source\Licenses\jucer_LicenseThread.h"/> - <ClInclude Include="..\..\Source\Licenses\jucer_LicenseWebview.h"/> <ClInclude Include="..\..\Source\LiveBuildEngine\UI\jucer_ActivityListComponent.h"/> <ClInclude Include="..\..\Source\LiveBuildEngine\UI\jucer_BuildTabStatusComponent.h"/> <ClInclude Include="..\..\Source\LiveBuildEngine\UI\jucer_ComponentListComponent.h"/> @@ -1586,6 +1616,9 @@ <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_MessageIDs.h"/> <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_ProjectBuildInfo.h"/> <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_SourceCodeRange.h"/> + <ClInclude Include="..\..\Source\Project\Modules\jucer_AvailableModulesList.h"/> + <ClInclude Include="..\..\Source\Project\Modules\jucer_ModuleDescription.h"/> + <ClInclude Include="..\..\Source\Project\Modules\jucer_Modules.h"/> <ClInclude Include="..\..\Source\Project\UI\Sidebar\jucer_ExporterTreeItems.h"/> <ClInclude Include="..\..\Source\Project\UI\Sidebar\jucer_FileTreeItems.h"/> <ClInclude Include="..\..\Source\Project\UI\Sidebar\jucer_LiveBuildTab.h"/> @@ -1599,9 +1632,9 @@ <ClInclude Include="..\..\Source\Project\UI\jucer_HeaderComponent.h"/> <ClInclude Include="..\..\Source\Project\UI\jucer_ModulesInformationComponent.h"/> <ClInclude Include="..\..\Source\Project\UI\jucer_ProjectContentComponent.h"/> - <ClInclude Include="..\..\Source\Project\jucer_Module.h"/> + <ClInclude Include="..\..\Source\Project\UI\jucer_ProjectMessagesComponent.h"/> + <ClInclude Include="..\..\Source\Project\UI\jucer_UserAvatarComponent.h"/> <ClInclude Include="..\..\Source\Project\jucer_Project.h"/> - <ClInclude Include="..\..\Source\Project\jucer_ProjectType.h"/> <ClInclude Include="..\..\Source\ProjectSaving\jucer_ProjectExport_Android.h"/> <ClInclude Include="..\..\Source\ProjectSaving\jucer_ProjectExport_CLion.h"/> <ClInclude Include="..\..\Source\ProjectSaving\jucer_ProjectExport_CodeBlocks.h"/> @@ -1618,10 +1651,11 @@ <ClInclude Include="..\..\Source\Utility\Helpers\jucer_Colours.h"/> <ClInclude Include="..\..\Source\Utility\Helpers\jucer_FileHelpers.h"/> <ClInclude Include="..\..\Source\Utility\Helpers\jucer_MiscUtilities.h"/> + <ClInclude Include="..\..\Source\Utility\Helpers\jucer_NewFileWizard.h"/> <ClInclude Include="..\..\Source\Utility\Helpers\jucer_PresetIDs.h"/> - <ClInclude Include="..\..\Source\Utility\Helpers\jucer_RelativePath.h"/> <ClInclude Include="..\..\Source\Utility\Helpers\jucer_TranslationHelpers.h"/> <ClInclude Include="..\..\Source\Utility\Helpers\jucer_ValueSourceHelpers.h"/> + <ClInclude Include="..\..\Source\Utility\Helpers\jucer_ValueWithDefaultWrapper.h"/> <ClInclude Include="..\..\Source\Utility\Helpers\jucer_VersionInfo.h"/> <ClInclude Include="..\..\Source\Utility\PIPs\jucer_PIPGenerator.h"/> <ClInclude Include="..\..\Source\Utility\UI\PropertyComponents\jucer_ColourPropertyComponent.h"/> @@ -1633,27 +1667,17 @@ <ClInclude Include="..\..\Source\Utility\UI\jucer_JucerTreeViewBase.h"/> <ClInclude Include="..\..\Source\Utility\UI\jucer_ProjucerLookAndFeel.h"/> <ClInclude Include="..\..\Source\Utility\UI\jucer_SlidingPanelComponent.h"/> - <ClInclude Include="..\..\Source\Utility\UI\jucer_UserSettingsPopup.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_NewFileWizard.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_NewProjectWizard.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_NewProjectWizardClasses.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_NewProjectWizardComponent.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_Animated.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_AudioApp.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_AudioPlugin.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_Blank.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_Console.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_DLL.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_GUIApp.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_openGL.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_StaticLibrary.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_StartPageComponent.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_TemplateThumbnailsComponent.h"/> - <ClInclude Include="..\..\..\..\modules\juce_analytics\analytics\juce_Analytics.h"/> - <ClInclude Include="..\..\..\..\modules\juce_analytics\analytics\juce_ButtonTracker.h"/> - <ClInclude Include="..\..\..\..\modules\juce_analytics\destinations\juce_AnalyticsDestination.h"/> - <ClInclude Include="..\..\..\..\modules\juce_analytics\destinations\juce_ThreadedAnalyticsDestination.h"/> - <ClInclude Include="..\..\..\..\modules\juce_analytics\juce_analytics.h"/> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_BinaryResourceFile.h"/> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_BuildHelperFunctions.h"/> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_Entitlements.h"/> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_Icons.h"/> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_PlistOptions.h"/> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_ProjectType.h"/> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_RelativePath.h"/> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_ResourceFileHelpers.h"/> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_ResourceRc.h"/> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_VersionNumbers.h"/> + <ClInclude Include="..\..\..\Build\juce_build_tools\juce_build_tools.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\containers\juce_AbstractFifo.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\containers\juce_Array.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\containers\juce_ArrayAllocationBase.h"/> @@ -1678,6 +1702,7 @@ <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_FileOutputStream.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_FileSearchPath.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_MemoryMappedFile.h"/> + <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_WildcardFileFilter.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\javascript\juce_Javascript.h"/> @@ -1691,6 +1716,7 @@ <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_Random.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_Range.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_StatisticsAccumulator.h"/> + <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_Atomic.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_ByteOrder.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_ContainerDeletePolicy.h"/> @@ -1733,6 +1759,7 @@ <ClInclude Include="..\..\..\..\modules\juce_core\streams\juce_SubregionStream.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\streams\juce_URLInputSource.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerSupport.h"/> + <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerWarnings.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_PlatformDefs.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_StandardHeader.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_SystemStats.h"/> @@ -1989,7 +2016,8 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_SelectedItemSet.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_TextDragAndDropTarget.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_TooltipClient.h"/> - <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.h"/> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.h"/> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_MultiTouchMapper.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\positioning\juce_MarkerList.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\positioning\juce_RelativeCoordinate.h"/> @@ -2041,6 +2069,7 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ActiveXControlComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"/> + <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_HWNDComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_NSViewComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ScopedDPIAwarenessDisabler.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_UIViewComponent.h"/> @@ -2059,11 +2088,16 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_mac_CarbonViewWrapperComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\juce_gui_extra.h"/> - <ClInclude Include="..\..\JuceLibraryCode\AppConfig.h"/> <ClInclude Include="..\..\JuceLibraryCode\BinaryData.h"/> <ClInclude Include="..\..\JuceLibraryCode\JuceHeader.h"/> </ItemGroup> <ItemGroup> + <None Include="..\..\..\Build\CMake\LaunchScreen.storyboard"/> + <None Include="..\..\..\Build\CMake\PIPAudioProcessor.cpp.in"/> + <None Include="..\..\..\Build\CMake\PIPComponent.cpp.in"/> + <None Include="..\..\..\Build\CMake\PIPConsole.cpp.in"/> + <None Include="..\..\..\Build\CMake\RecentFilesMenuTemplate.nib"/> + <None Include="..\..\..\Build\CMake\UnityPluginGUIScript.cs.in"/> <None Include="..\..\Source\BinaryData\gradle\gradle-wrapper.jar"/> <None Include="..\..\Source\BinaryData\gradle\gradlew"/> <None Include="..\..\Source\BinaryData\gradle\gradlew.bat"/> @@ -2075,7 +2109,7 @@ <None Include="..\..\Source\BinaryData\Icons\export_linux.svg"/> <None Include="..\..\Source\BinaryData\Icons\export_visualStudio.svg"/> <None Include="..\..\Source\BinaryData\Icons\export_xcode.svg"/> - <None Include="..\..\Source\BinaryData\Icons\huckleberry_icon.svg"/> + <None Include="..\..\Source\BinaryData\Icons\gpl_logo.svg"/> <None Include="..\..\Source\BinaryData\Icons\juce-logo-with-text.svg"/> <None Include="..\..\Source\BinaryData\Icons\juce_icon.png"/> <None Include="..\..\Source\BinaryData\Icons\wizard_AnimatedApp.svg"/> @@ -2088,13 +2122,8 @@ <None Include="..\..\Source\BinaryData\Icons\wizard_Openfile.svg"/> <None Include="..\..\Source\BinaryData\Icons\wizard_OpenGL.svg"/> <None Include="..\..\Source\BinaryData\Icons\wizard_StaticLibrary.svg"/> - <None Include="..\..\Source\BinaryData\Templates\jucer_UnityPluginGUIScript.cs"/> <None Include="..\..\Source\BinaryData\colourscheme_dark.xml"/> <None Include="..\..\Source\BinaryData\colourscheme_light.xml"/> - <None Include="..\..\Source\BinaryData\nothingtoseehere.txt"/> - <None Include="..\..\Source\BinaryData\offlinepage.html"/> - <None Include="..\..\Source\BinaryData\projucer_EULA.txt"/> - <None Include="..\..\Source\BinaryData\RecentFilesMenuTemplate.nib"/> <None Include="..\..\..\..\modules\juce_core\native\java\README.txt"/> <None Include="..\..\..\..\modules\juce_graphics\image_formats\jpglib\changes to libjpeg for JUCE.txt"/> <None Include="..\..\..\..\modules\juce_graphics\image_formats\pnglib\libpng_readme.txt"/> diff --git a/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj.filters b/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj.filters index 8148e932..bab64ae0 100644 --- a/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj.filters +++ b/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj.filters @@ -2,6 +2,12 @@ <Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup> + <Filter Include="Projucer\Application\StartPage"> + <UniqueIdentifier>{1E1D2D75-0ADA-6E9E-105F-2F87632B55AF}</UniqueIdentifier> + </Filter> + <Filter Include="Projucer\Application\UserAccount"> + <UniqueIdentifier>{DA27985D-8427-CE70-CA06-EAF7009CCC60}</UniqueIdentifier> + </Filter> <Filter Include="Projucer\Application\Windows"> <UniqueIdentifier>{DC7E18A5-E854-3D99-627F-AAA88246B712}</UniqueIdentifier> </Filter> @@ -41,15 +47,15 @@ <Filter Include="Projucer\ComponentEditor"> <UniqueIdentifier>{5F21E507-E5E8-0A74-F1AE-874BB67C26CC}</UniqueIdentifier> </Filter> - <Filter Include="Projucer\Licenses"> - <UniqueIdentifier>{E5D23B90-895E-EB0B-AC18-C7EBB25546AE}</UniqueIdentifier> - </Filter> <Filter Include="Projucer\LiveBuildEngine\UI"> <UniqueIdentifier>{E880260F-D9FB-64B6-244B-6F06B70FE9EE}</UniqueIdentifier> </Filter> <Filter Include="Projucer\LiveBuildEngine"> <UniqueIdentifier>{0A3B9446-F50B-3D4E-230F-7ED493541A07}</UniqueIdentifier> </Filter> + <Filter Include="Projucer\Project\Modules"> + <UniqueIdentifier>{F5C79836-30DE-9DC7-9392-DAAB3F04C18E}</UniqueIdentifier> + </Filter> <Filter Include="Projucer\Project\UI\Sidebar"> <UniqueIdentifier>{A0A94AE6-B447-151A-D0DA-FAE9B5410EBF}</UniqueIdentifier> </Filter> @@ -80,20 +86,14 @@ <Filter Include="Projucer\Utility"> <UniqueIdentifier>{F77CA057-8DE4-E076-7EB6-D2646794864B}</UniqueIdentifier> </Filter> - <Filter Include="Projucer\Wizards"> - <UniqueIdentifier>{4BBA3556-B2A1-3008-8BE1-F82DE6666552}</UniqueIdentifier> - </Filter> <Filter Include="Projucer"> <UniqueIdentifier>{7DBEF27C-2AFE-DA02-1DBF-E80FAAC99EA7}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_analytics\analytics"> - <UniqueIdentifier>{E3CEC08A-FA14-D343-5BFF-3D6A4A4FD713}</UniqueIdentifier> - </Filter> - <Filter Include="JUCE Modules\juce_analytics\destinations"> - <UniqueIdentifier>{B3BC836A-3932-C1E4-CA3C-A1C0D83281BA}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_build_tools\utils"> + <UniqueIdentifier>{D9FAFF6D-6737-F775-056A-D0B29BE13820}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_analytics"> - <UniqueIdentifier>{97F7F593-75F8-D6B2-DC96-C946C3976226}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_build_tools"> + <UniqueIdentifier>{065C11E4-EB37-5B72-0A01-F549675EB866}</UniqueIdentifier> </Filter> <Filter Include="JUCE Modules\juce_core\containers"> <UniqueIdentifier>{42F7BE9D-3C8A-AE26-289B-8F355C068036}</UniqueIdentifier> @@ -269,6 +269,9 @@ <Filter Include="JUCE Modules\juce_gui_basics\mouse"> <UniqueIdentifier>{FE3CB19C-EF43-5CF5-DAF0-09D4E43D0AB9}</UniqueIdentifier> </Filter> + <Filter Include="JUCE Modules\juce_gui_basics\native\x11"> + <UniqueIdentifier>{FE7E6CD5-C7A0-DB20-4E7E-D6E7F08C4578}</UniqueIdentifier> + </Filter> <Filter Include="JUCE Modules\juce_gui_basics\native"> <UniqueIdentifier>{895C2D33-E08D-B1BA-BB36-FC4CA65090C8}</UniqueIdentifier> </Filter> @@ -313,6 +316,12 @@ </Filter> </ItemGroup> <ItemGroup> + <ClCompile Include="..\..\Source\Application\StartPage\jucer_NewProjectWizard.cpp"> + <Filter>Projucer\Application\StartPage</Filter> + </ClCompile> + <ClCompile Include="..\..\Source\Application\StartPage\jucer_StartPageComponent.cpp"> + <Filter>Projucer\Application\StartPage</Filter> + </ClCompile> <ClCompile Include="..\..\Source\Application\jucer_Application.cpp"> <Filter>Projucer\Application</Filter> </ClCompile> @@ -328,9 +337,6 @@ <ClCompile Include="..\..\Source\Application\jucer_MainWindow.cpp"> <Filter>Projucer\Application</Filter> </ClCompile> - <ClCompile Include="..\..\Source\Application\jucer_ProjucerAnalytics.cpp"> - <Filter>Projucer\Application</Filter> - </ClCompile> <ClCompile Include="..\..\Source\BinaryData\Templates\jucer_AnimatedComponentTemplate.cpp"> <Filter>Projucer\BinaryData\Templates</Filter> </ClCompile> @@ -355,9 +361,6 @@ <ClCompile Include="..\..\Source\BinaryData\Templates\jucer_MainTemplate_NoWindow.cpp"> <Filter>Projucer\BinaryData\Templates</Filter> </ClCompile> - <ClCompile Include="..\..\Source\BinaryData\Templates\jucer_MainTemplate_SimpleWindow.cpp"> - <Filter>Projucer\BinaryData\Templates</Filter> - </ClCompile> <ClCompile Include="..\..\Source\BinaryData\Templates\jucer_MainTemplate_Window.cpp"> <Filter>Projucer\BinaryData\Templates</Filter> </ClCompile> @@ -370,8 +373,8 @@ <ClCompile Include="..\..\Source\BinaryData\Templates\jucer_OpenGLComponentTemplate.cpp"> <Filter>Projucer\BinaryData\Templates</Filter> </ClCompile> - <ClCompile Include="..\..\Source\BinaryData\Templates\jucer_PIPMain.cpp"> - <Filter>Projucer\BinaryData\Templates</Filter> + <ClCompile Include="..\..\..\Build\CMake\juce_runtime_arch_detection.cpp"> + <Filter>Projucer\BinaryData</Filter> </ClCompile> <ClCompile Include="..\..\Source\CodeEditor\jucer_DocumentEditorComponent.cpp"> <Filter>Projucer\CodeEditor</Filter> @@ -448,9 +451,6 @@ <ClCompile Include="..\..\Source\ComponentEditor\jucer_PaintRoutine.cpp"> <Filter>Projucer\ComponentEditor</Filter> </ClCompile> - <ClCompile Include="..\..\Source\Licenses\jucer_LicenseController.cpp"> - <Filter>Projucer\Licenses</Filter> - </ClCompile> <ClCompile Include="..\..\Source\LiveBuildEngine\jucer_CompileEngineClient.cpp"> <Filter>Projucer\LiveBuildEngine</Filter> </ClCompile> @@ -460,15 +460,15 @@ <ClCompile Include="..\..\Source\LiveBuildEngine\jucer_DownloadCompileEngineThread.cpp"> <Filter>Projucer\LiveBuildEngine</Filter> </ClCompile> + <ClCompile Include="..\..\Source\Project\Modules\jucer_Modules.cpp"> + <Filter>Projucer\Project\Modules</Filter> + </ClCompile> <ClCompile Include="..\..\Source\Project\UI\jucer_HeaderComponent.cpp"> <Filter>Projucer\Project\UI</Filter> </ClCompile> <ClCompile Include="..\..\Source\Project\UI\jucer_ProjectContentComponent.cpp"> <Filter>Projucer\Project\UI</Filter> </ClCompile> - <ClCompile Include="..\..\Source\Project\jucer_Module.cpp"> - <Filter>Projucer\Project</Filter> - </ClCompile> <ClCompile Include="..\..\Source\Project\jucer_Project.cpp"> <Filter>Projucer\Project</Filter> </ClCompile> @@ -496,6 +496,9 @@ <ClCompile Include="..\..\Source\Utility\Helpers\jucer_MiscUtilities.cpp"> <Filter>Projucer\Utility\Helpers</Filter> </ClCompile> + <ClCompile Include="..\..\Source\Utility\Helpers\jucer_NewFileWizard.cpp"> + <Filter>Projucer\Utility\Helpers</Filter> + </ClCompile> <ClCompile Include="..\..\Source\Utility\Helpers\jucer_VersionInfo.cpp"> <Filter>Projucer\Utility\Helpers</Filter> </ClCompile> @@ -514,23 +517,35 @@ <ClCompile Include="..\..\Source\Utility\UI\jucer_SlidingPanelComponent.cpp"> <Filter>Projucer\Utility\UI</Filter> </ClCompile> - <ClCompile Include="..\..\Source\Wizards\jucer_NewFileWizard.cpp"> - <Filter>Projucer\Wizards</Filter> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_BinaryResourceFile.cpp"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClCompile> - <ClCompile Include="..\..\Source\Wizards\jucer_NewProjectWizardClasses.cpp"> - <Filter>Projucer\Wizards</Filter> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_BuildHelperFunctions.cpp"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_analytics\analytics\juce_Analytics.cpp"> - <Filter>JUCE Modules\juce_analytics\analytics</Filter> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_CppTokeniserFunctions.cpp"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_analytics\analytics\juce_ButtonTracker.cpp"> - <Filter>JUCE Modules\juce_analytics\analytics</Filter> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_Entitlements.cpp"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_analytics\destinations\juce_ThreadedAnalyticsDestination.cpp"> - <Filter>JUCE Modules\juce_analytics\destinations</Filter> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_Icons.cpp"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_analytics\juce_analytics.cpp"> - <Filter>JUCE Modules\juce_analytics</Filter> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_PlistOptions.cpp"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> + </ClCompile> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_ResourceFileHelpers.cpp"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> + </ClCompile> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_ResourceRc.cpp"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> + </ClCompile> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_VersionNumbers.cpp"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> + </ClCompile> + <ClCompile Include="..\..\..\Build\juce_build_tools\juce_build_tools.cpp"> + <Filter>JUCE Modules\juce_build_tools</Filter> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_AbstractFifo.cpp"> <Filter>JUCE Modules\juce_core\containers</Filter> @@ -580,6 +595,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_FileSearchPath.cpp"> <Filter>JUCE Modules\juce_core\files</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.cpp"> + <Filter>JUCE Modules\juce_core\files</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.cpp"> <Filter>JUCE Modules\juce_core\files</Filter> </ClCompile> @@ -607,6 +625,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> <Filter>JUCE Modules\juce_core\maths</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.cpp"> + <Filter>JUCE Modules\juce_core\memory</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_MemoryBlock.cpp"> <Filter>JUCE Modules\juce_core\memory</Filter> </ClCompile> @@ -1534,6 +1555,15 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_MouseListener.cpp"> <Filter>JUCE Modules\juce_gui_basics\mouse</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_DragAndDrop.cpp"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.cpp"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.cpp"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_android_ContentSharer.cpp"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> </ClCompile> @@ -1561,13 +1591,7 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_FileChooser.cpp"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.cpp"> - <Filter>JUCE Modules\juce_gui_basics\native</Filter> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Clipboard.cpp"> - <Filter>JUCE Modules\juce_gui_basics\native</Filter> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Windowing.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_Windowing.cpp"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_mac_FileChooser.mm"> @@ -1801,6 +1825,9 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_ActiveXComponent.cpp"> <Filter>JUCE Modules\juce_gui_extra\native</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_HWNDComponent.cpp"> + <Filter>JUCE Modules\juce_gui_extra\native</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_SystemTrayIcon.cpp"> <Filter>JUCE Modules\juce_gui_extra\native</Filter> </ClCompile> @@ -1816,7 +1843,7 @@ <ClCompile Include="..\..\JuceLibraryCode\BinaryData.cpp"> <Filter>JUCE Library Code</Filter> </ClCompile> - <ClCompile Include="..\..\JuceLibraryCode\include_juce_analytics.cpp"> + <ClCompile Include="..\..\JuceLibraryCode\include_juce_build_tools.cpp"> <Filter>JUCE Library Code</Filter> </ClCompile> <ClCompile Include="..\..\JuceLibraryCode\include_juce_core.cpp"> @@ -1842,10 +1869,34 @@ </ClCompile> </ItemGroup> <ItemGroup> - <ClInclude Include="..\..\Source\Application\Windows\jucer_AboutWindowComponent.h"> - <Filter>Projucer\Application\Windows</Filter> + <ClInclude Include="..\..\Source\Application\StartPage\jucer_ContentComponents.h"> + <Filter>Projucer\Application\StartPage</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\Application\StartPage\jucer_NewProjectTemplates.h"> + <Filter>Projucer\Application\StartPage</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\Application\StartPage\jucer_NewProjectWizard.h"> + <Filter>Projucer\Application\StartPage</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Application\Windows\jucer_ApplicationUsageDataWindowComponent.h"> + <ClInclude Include="..\..\Source\Application\StartPage\jucer_StartPageComponent.h"> + <Filter>Projucer\Application\StartPage</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\Application\StartPage\jucer_StartPageTreeHolder.h"> + <Filter>Projucer\Application\StartPage</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\Application\UserAccount\jucer_LicenseController.h"> + <Filter>Projucer\Application\UserAccount</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\Application\UserAccount\jucer_LicenseQueryThread.h"> + <Filter>Projucer\Application\UserAccount</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\Application\UserAccount\jucer_LicenseState.h"> + <Filter>Projucer\Application\UserAccount</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\Application\UserAccount\jucer_LoginFormComponent.h"> + <Filter>Projucer\Application\UserAccount</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\Application\Windows\jucer_AboutWindowComponent.h"> <Filter>Projucer\Application\Windows</Filter> </ClInclude> <ClInclude Include="..\..\Source\Application\Windows\jucer_EditorColourSchemeWindowComponent.h"> @@ -1890,9 +1941,6 @@ <ClInclude Include="..\..\Source\Application\jucer_MainWindow.h"> <Filter>Projucer\Application</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Application\jucer_ProjucerAnalytics.h"> - <Filter>Projucer\Application</Filter> - </ClInclude> <ClInclude Include="..\..\Source\BinaryData\Templates\jucer_AnimatedComponentSimpleTemplate.h"> <Filter>Projucer\BinaryData\Templates</Filter> </ClInclude> @@ -2151,15 +2199,6 @@ <ClInclude Include="..\..\Source\ComponentEditor\jucer_UtilityFunctions.h"> <Filter>Projucer\ComponentEditor</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Licenses\jucer_LicenseController.h"> - <Filter>Projucer\Licenses</Filter> - </ClInclude> - <ClInclude Include="..\..\Source\Licenses\jucer_LicenseThread.h"> - <Filter>Projucer\Licenses</Filter> - </ClInclude> - <ClInclude Include="..\..\Source\Licenses\jucer_LicenseWebview.h"> - <Filter>Projucer\Licenses</Filter> - </ClInclude> <ClInclude Include="..\..\Source\LiveBuildEngine\UI\jucer_ActivityListComponent.h"> <Filter>Projucer\LiveBuildEngine\UI</Filter> </ClInclude> @@ -2217,6 +2256,15 @@ <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_SourceCodeRange.h"> <Filter>Projucer\LiveBuildEngine</Filter> </ClInclude> + <ClInclude Include="..\..\Source\Project\Modules\jucer_AvailableModulesList.h"> + <Filter>Projucer\Project\Modules</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\Project\Modules\jucer_ModuleDescription.h"> + <Filter>Projucer\Project\Modules</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\Project\Modules\jucer_Modules.h"> + <Filter>Projucer\Project\Modules</Filter> + </ClInclude> <ClInclude Include="..\..\Source\Project\UI\Sidebar\jucer_ExporterTreeItems.h"> <Filter>Projucer\Project\UI\Sidebar</Filter> </ClInclude> @@ -2256,13 +2304,13 @@ <ClInclude Include="..\..\Source\Project\UI\jucer_ProjectContentComponent.h"> <Filter>Projucer\Project\UI</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Project\jucer_Module.h"> - <Filter>Projucer\Project</Filter> + <ClInclude Include="..\..\Source\Project\UI\jucer_ProjectMessagesComponent.h"> + <Filter>Projucer\Project\UI</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Project\jucer_Project.h"> - <Filter>Projucer\Project</Filter> + <ClInclude Include="..\..\Source\Project\UI\jucer_UserAvatarComponent.h"> + <Filter>Projucer\Project\UI</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Project\jucer_ProjectType.h"> + <ClInclude Include="..\..\Source\Project\jucer_Project.h"> <Filter>Projucer\Project</Filter> </ClInclude> <ClInclude Include="..\..\Source\ProjectSaving\jucer_ProjectExport_Android.h"> @@ -2313,10 +2361,10 @@ <ClInclude Include="..\..\Source\Utility\Helpers\jucer_MiscUtilities.h"> <Filter>Projucer\Utility\Helpers</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Utility\Helpers\jucer_PresetIDs.h"> + <ClInclude Include="..\..\Source\Utility\Helpers\jucer_NewFileWizard.h"> <Filter>Projucer\Utility\Helpers</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Utility\Helpers\jucer_RelativePath.h"> + <ClInclude Include="..\..\Source\Utility\Helpers\jucer_PresetIDs.h"> <Filter>Projucer\Utility\Helpers</Filter> </ClInclude> <ClInclude Include="..\..\Source\Utility\Helpers\jucer_TranslationHelpers.h"> @@ -2325,6 +2373,9 @@ <ClInclude Include="..\..\Source\Utility\Helpers\jucer_ValueSourceHelpers.h"> <Filter>Projucer\Utility\Helpers</Filter> </ClInclude> + <ClInclude Include="..\..\Source\Utility\Helpers\jucer_ValueWithDefaultWrapper.h"> + <Filter>Projucer\Utility\Helpers</Filter> + </ClInclude> <ClInclude Include="..\..\Source\Utility\Helpers\jucer_VersionInfo.h"> <Filter>Projucer\Utility\Helpers</Filter> </ClInclude> @@ -2358,68 +2409,38 @@ <ClInclude Include="..\..\Source\Utility\UI\jucer_SlidingPanelComponent.h"> <Filter>Projucer\Utility\UI</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Utility\UI\jucer_UserSettingsPopup.h"> - <Filter>Projucer\Utility\UI</Filter> - </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_NewFileWizard.h"> - <Filter>Projucer\Wizards</Filter> - </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_NewProjectWizard.h"> - <Filter>Projucer\Wizards</Filter> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_BinaryResourceFile.h"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_NewProjectWizardClasses.h"> - <Filter>Projucer\Wizards</Filter> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_BuildHelperFunctions.h"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_NewProjectWizardComponent.h"> - <Filter>Projucer\Wizards</Filter> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_Entitlements.h"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_Animated.h"> - <Filter>Projucer\Wizards</Filter> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_Icons.h"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_AudioApp.h"> - <Filter>Projucer\Wizards</Filter> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_PlistOptions.h"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_AudioPlugin.h"> - <Filter>Projucer\Wizards</Filter> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_ProjectType.h"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_Blank.h"> - <Filter>Projucer\Wizards</Filter> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_RelativePath.h"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_Console.h"> - <Filter>Projucer\Wizards</Filter> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_ResourceFileHelpers.h"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_DLL.h"> - <Filter>Projucer\Wizards</Filter> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_ResourceRc.h"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_GUIApp.h"> - <Filter>Projucer\Wizards</Filter> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_VersionNumbers.h"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_openGL.h"> - <Filter>Projucer\Wizards</Filter> - </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_StaticLibrary.h"> - <Filter>Projucer\Wizards</Filter> - </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_StartPageComponent.h"> - <Filter>Projucer\Wizards</Filter> - </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_TemplateThumbnailsComponent.h"> - <Filter>Projucer\Wizards</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_analytics\analytics\juce_Analytics.h"> - <Filter>JUCE Modules\juce_analytics\analytics</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_analytics\analytics\juce_ButtonTracker.h"> - <Filter>JUCE Modules\juce_analytics\analytics</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_analytics\destinations\juce_AnalyticsDestination.h"> - <Filter>JUCE Modules\juce_analytics\destinations</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_analytics\destinations\juce_ThreadedAnalyticsDestination.h"> - <Filter>JUCE Modules\juce_analytics\destinations</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_analytics\juce_analytics.h"> - <Filter>JUCE Modules\juce_analytics</Filter> + <ClInclude Include="..\..\..\Build\juce_build_tools\juce_build_tools.h"> + <Filter>JUCE Modules\juce_build_tools</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_core\containers\juce_AbstractFifo.h"> <Filter>JUCE Modules\juce_core\containers</Filter> @@ -2493,6 +2514,9 @@ <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_MemoryMappedFile.h"> <Filter>JUCE Modules\juce_core\files</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.h"> + <Filter>JUCE Modules\juce_core\files</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.h"> <Filter>JUCE Modules\juce_core\files</Filter> </ClInclude> @@ -2532,6 +2556,9 @@ <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_StatisticsAccumulator.h"> <Filter>JUCE Modules\juce_core\maths</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.h"> + <Filter>JUCE Modules\juce_core\memory</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_Atomic.h"> <Filter>JUCE Modules\juce_core\memory</Filter> </ClInclude> @@ -2658,6 +2685,9 @@ <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerSupport.h"> <Filter>JUCE Modules\juce_core\system</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerWarnings.h"> + <Filter>JUCE Modules\juce_core\system</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_PlatformDefs.h"> <Filter>JUCE Modules\juce_core\system</Filter> </ClInclude> @@ -3426,8 +3456,11 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_TooltipClient.h"> <Filter>JUCE Modules\juce_gui_basics\mouse</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.h"> - <Filter>JUCE Modules\juce_gui_basics\native</Filter> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.h"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.h"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_MultiTouchMapper.h"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> @@ -3582,6 +3615,9 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"> <Filter>JUCE Modules\juce_gui_extra\embedding</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_HWNDComponent.h"> + <Filter>JUCE Modules\juce_gui_extra\embedding</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_NSViewComponent.h"> <Filter>JUCE Modules\juce_gui_extra\embedding</Filter> </ClInclude> @@ -3636,9 +3672,6 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_extra\juce_gui_extra.h"> <Filter>JUCE Modules\juce_gui_extra</Filter> </ClInclude> - <ClInclude Include="..\..\JuceLibraryCode\AppConfig.h"> - <Filter>JUCE Library Code</Filter> - </ClInclude> <ClInclude Include="..\..\JuceLibraryCode\BinaryData.h"> <Filter>JUCE Library Code</Filter> </ClInclude> @@ -3647,6 +3680,24 @@ </ClInclude> </ItemGroup> <ItemGroup> + <None Include="..\..\..\Build\CMake\LaunchScreen.storyboard"> + <Filter>Projucer\BinaryData</Filter> + </None> + <None Include="..\..\..\Build\CMake\PIPAudioProcessor.cpp.in"> + <Filter>Projucer\BinaryData</Filter> + </None> + <None Include="..\..\..\Build\CMake\PIPComponent.cpp.in"> + <Filter>Projucer\BinaryData</Filter> + </None> + <None Include="..\..\..\Build\CMake\PIPConsole.cpp.in"> + <Filter>Projucer\BinaryData</Filter> + </None> + <None Include="..\..\..\Build\CMake\RecentFilesMenuTemplate.nib"> + <Filter>Projucer\BinaryData</Filter> + </None> + <None Include="..\..\..\Build\CMake\UnityPluginGUIScript.cs.in"> + <Filter>Projucer\BinaryData</Filter> + </None> <None Include="..\..\Source\BinaryData\gradle\gradle-wrapper.jar"> <Filter>Projucer\BinaryData\gradle</Filter> </None> @@ -3680,7 +3731,7 @@ <None Include="..\..\Source\BinaryData\Icons\export_xcode.svg"> <Filter>Projucer\BinaryData\Icons</Filter> </None> - <None Include="..\..\Source\BinaryData\Icons\huckleberry_icon.svg"> + <None Include="..\..\Source\BinaryData\Icons\gpl_logo.svg"> <Filter>Projucer\BinaryData\Icons</Filter> </None> <None Include="..\..\Source\BinaryData\Icons\juce-logo-with-text.svg"> @@ -3719,27 +3770,12 @@ <None Include="..\..\Source\BinaryData\Icons\wizard_StaticLibrary.svg"> <Filter>Projucer\BinaryData\Icons</Filter> </None> - <None Include="..\..\Source\BinaryData\Templates\jucer_UnityPluginGUIScript.cs"> - <Filter>Projucer\BinaryData\Templates</Filter> - </None> <None Include="..\..\Source\BinaryData\colourscheme_dark.xml"> <Filter>Projucer\BinaryData</Filter> </None> <None Include="..\..\Source\BinaryData\colourscheme_light.xml"> <Filter>Projucer\BinaryData</Filter> </None> - <None Include="..\..\Source\BinaryData\nothingtoseehere.txt"> - <Filter>Projucer\BinaryData</Filter> - </None> - <None Include="..\..\Source\BinaryData\offlinepage.html"> - <Filter>Projucer\BinaryData</Filter> - </None> - <None Include="..\..\Source\BinaryData\projucer_EULA.txt"> - <Filter>Projucer\BinaryData</Filter> - </None> - <None Include="..\..\Source\BinaryData\RecentFilesMenuTemplate.nib"> - <Filter>Projucer\BinaryData</Filter> - </None> <None Include="..\..\..\..\modules\juce_core\native\java\README.txt"> <Filter>JUCE Modules\juce_core\native\java</Filter> </None> diff --git a/extras/Projucer/Builds/VisualStudio2017/resources.rc b/extras/Projucer/Builds/VisualStudio2017/resources.rc index 3cc301e6..cb7ae4b8 100644 --- a/extras/Projucer/Builds/VisualStudio2017/resources.rc +++ b/extras/Projucer/Builds/VisualStudio2017/resources.rc @@ -1,3 +1,5 @@ +#pragma code_page(65001) + #ifdef JUCE_USER_DEFINED_RC_FILE #include JUCE_USER_DEFINED_RC_FILE #else @@ -7,18 +9,18 @@ #include <windows.h> VS_VERSION_INFO VERSIONINFO -FILEVERSION 5,4,7,0 +FILEVERSION 6,0,5,0 BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904E4" BEGIN - VALUE "CompanyName", "ROLI Ltd.\0" - VALUE "LegalCopyright", "ROLI Ltd.\0" + VALUE "CompanyName", "Raw Material Software Limited\0" + VALUE "LegalCopyright", "Raw Material Software Limited\0" VALUE "FileDescription", "Projucer\0" - VALUE "FileVersion", "5.4.7\0" + VALUE "FileVersion", "6.0.5\0" VALUE "ProductName", "Projucer\0" - VALUE "ProductVersion", "5.4.7\0" + VALUE "ProductVersion", "6.0.5\0" END END diff --git a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj index c5a3d25f..37d7f62d 100644 --- a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj +++ b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj @@ -63,11 +63,11 @@ <ClCompile> <Optimization>Disabled</Optimization> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=5.4.7;JUCE_APP_VERSION_HEX=0x50407;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\Build;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCE_DISPLAY_SPLASH_SCREEN=0;JUCE_USE_DARK_SPLASH_SCREEN=1;JUCE_PROJUCER_VERSION=0x60005;JUCE_MODULE_AVAILABLE_juce_build_tools=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_LOG_ASSERTIONS=1;JUCE_USE_CURL=1;JUCE_LOAD_CURL_SYMBOLS_LAZILY=1;JUCE_ALLOW_STATIC_NULL_VARIABLES=0;JUCE_STRICT_REFCOUNTEDPOINTER=1;JUCE_WEB_BROWSER=0;JUCE_STANDALONE_APPLICATION=1;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=6.0.5;JUCE_APP_VERSION_HEX=0x60005;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> <RuntimeTypeInfo>true</RuntimeTypeInfo> - <PrecompiledHeader/> + <PrecompiledHeader>NotUsing</PrecompiledHeader> <AssemblerListingLocation>$(IntDir)\</AssemblerListingLocation> <ObjectFileName>$(IntDir)\</ObjectFileName> <ProgramDataBaseFileName>$(IntDir)\</ProgramDataBaseFileName> @@ -105,11 +105,11 @@ </Midl> <ClCompile> <Optimization>Full</Optimization> - <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=5.4.7;JUCE_APP_VERSION_HEX=0x50407;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\Build;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCE_DISPLAY_SPLASH_SCREEN=0;JUCE_USE_DARK_SPLASH_SCREEN=1;JUCE_PROJUCER_VERSION=0x60005;JUCE_MODULE_AVAILABLE_juce_build_tools=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_LOG_ASSERTIONS=1;JUCE_USE_CURL=1;JUCE_LOAD_CURL_SYMBOLS_LAZILY=1;JUCE_ALLOW_STATIC_NULL_VARIABLES=0;JUCE_STRICT_REFCOUNTEDPOINTER=1;JUCE_WEB_BROWSER=0;JUCE_STANDALONE_APPLICATION=1;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=6.0.5;JUCE_APP_VERSION_HEX=0x60005;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreaded</RuntimeLibrary> <RuntimeTypeInfo>true</RuntimeTypeInfo> - <PrecompiledHeader/> + <PrecompiledHeader>NotUsing</PrecompiledHeader> <AssemblerListingLocation>$(IntDir)\</AssemblerListingLocation> <ObjectFileName>$(IntDir)\</ObjectFileName> <ProgramDataBaseFileName>$(IntDir)\</ProgramDataBaseFileName> @@ -140,6 +140,8 @@ <Lib/> </ItemDefinitionGroup> <ItemGroup> + <ClCompile Include="..\..\Source\Application\StartPage\jucer_NewProjectWizard.cpp"/> + <ClCompile Include="..\..\Source\Application\StartPage\jucer_StartPageComponent.cpp"/> <ClCompile Include="..\..\Source\Application\jucer_Application.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -147,7 +149,6 @@ <ClCompile Include="..\..\Source\Application\jucer_CommandLine.cpp"/> <ClCompile Include="..\..\Source\Application\jucer_Main.cpp"/> <ClCompile Include="..\..\Source\Application\jucer_MainWindow.cpp"/> - <ClCompile Include="..\..\Source\Application\jucer_ProjucerAnalytics.cpp"/> <ClCompile Include="..\..\Source\BinaryData\Templates\jucer_AnimatedComponentTemplate.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -172,9 +173,6 @@ <ClCompile Include="..\..\Source\BinaryData\Templates\jucer_MainTemplate_NoWindow.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\Source\BinaryData\Templates\jucer_MainTemplate_SimpleWindow.cpp"> - <ExcludedFromBuild>true</ExcludedFromBuild> - </ClCompile> <ClCompile Include="..\..\Source\BinaryData\Templates\jucer_MainTemplate_Window.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -187,7 +185,7 @@ <ClCompile Include="..\..\Source\BinaryData\Templates\jucer_OpenGLComponentTemplate.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\Source\BinaryData\Templates\jucer_PIPMain.cpp"> + <ClCompile Include="..\..\..\Build\CMake\juce_runtime_arch_detection.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\..\Source\CodeEditor\jucer_DocumentEditorComponent.cpp"/> @@ -215,15 +213,14 @@ <ClCompile Include="..\..\Source\ComponentEditor\jucer_JucerDocument.cpp"/> <ClCompile Include="..\..\Source\ComponentEditor\jucer_ObjectTypes.cpp"/> <ClCompile Include="..\..\Source\ComponentEditor\jucer_PaintRoutine.cpp"/> - <ClCompile Include="..\..\Source\Licenses\jucer_LicenseController.cpp"/> <ClCompile Include="..\..\Source\LiveBuildEngine\jucer_CompileEngineClient.cpp"/> <ClCompile Include="..\..\Source\LiveBuildEngine\jucer_CompileEngineServer.cpp"/> <ClCompile Include="..\..\Source\LiveBuildEngine\jucer_DownloadCompileEngineThread.cpp"/> + <ClCompile Include="..\..\Source\Project\Modules\jucer_Modules.cpp"/> <ClCompile Include="..\..\Source\Project\UI\jucer_HeaderComponent.cpp"/> <ClCompile Include="..\..\Source\Project\UI\jucer_ProjectContentComponent.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\Source\Project\jucer_Module.cpp"/> <ClCompile Include="..\..\Source\Project\jucer_Project.cpp"/> <ClCompile Include="..\..\Source\ProjectSaving\jucer_ProjectExporter.cpp"/> <ClCompile Include="..\..\Source\ProjectSaving\jucer_ProjectSaver.cpp"/> @@ -233,24 +230,41 @@ <ClCompile Include="..\..\Source\Utility\Helpers\jucer_CodeHelpers.cpp"/> <ClCompile Include="..\..\Source\Utility\Helpers\jucer_FileHelpers.cpp"/> <ClCompile Include="..\..\Source\Utility\Helpers\jucer_MiscUtilities.cpp"/> + <ClCompile Include="..\..\Source\Utility\Helpers\jucer_NewFileWizard.cpp"/> <ClCompile Include="..\..\Source\Utility\Helpers\jucer_VersionInfo.cpp"/> <ClCompile Include="..\..\Source\Utility\PIPs\jucer_PIPGenerator.cpp"/> <ClCompile Include="..\..\Source\Utility\UI\jucer_Icons.cpp"/> <ClCompile Include="..\..\Source\Utility\UI\jucer_JucerTreeViewBase.cpp"/> <ClCompile Include="..\..\Source\Utility\UI\jucer_ProjucerLookAndFeel.cpp"/> <ClCompile Include="..\..\Source\Utility\UI\jucer_SlidingPanelComponent.cpp"/> - <ClCompile Include="..\..\Source\Wizards\jucer_NewFileWizard.cpp"/> - <ClCompile Include="..\..\Source\Wizards\jucer_NewProjectWizardClasses.cpp"/> - <ClCompile Include="..\..\..\..\modules\juce_analytics\analytics\juce_Analytics.cpp"> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_BinaryResourceFile.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_BuildHelperFunctions.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_CppTokeniserFunctions.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_Entitlements.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_analytics\analytics\juce_ButtonTracker.cpp"> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_Icons.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_analytics\destinations\juce_ThreadedAnalyticsDestination.cpp"> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_PlistOptions.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_analytics\juce_analytics.cpp"> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_ResourceFileHelpers.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_ResourceRc.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_VersionNumbers.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\Build\juce_build_tools\juce_build_tools.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_AbstractFifo.cpp"> @@ -301,6 +315,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_FileSearchPath.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -328,6 +345,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_MemoryBlock.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -1213,6 +1233,15 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_MouseListener.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_DragAndDrop.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_android_ContentSharer.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -1231,13 +1260,7 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_FileChooser.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.cpp"> - <ExcludedFromBuild>true</ExcludedFromBuild> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Clipboard.cpp"> - <ExcludedFromBuild>true</ExcludedFromBuild> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Windowing.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_Windowing.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_win32_DragAndDrop.cpp"> @@ -1441,6 +1464,9 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_ActiveXComponent.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_HWNDComponent.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_SystemTrayIcon.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -1451,7 +1477,7 @@ <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\..\JuceLibraryCode\BinaryData.cpp"/> - <ClCompile Include="..\..\JuceLibraryCode\include_juce_analytics.cpp"/> + <ClCompile Include="..\..\JuceLibraryCode\include_juce_build_tools.cpp"/> <ClCompile Include="..\..\JuceLibraryCode\include_juce_core.cpp"/> <ClCompile Include="..\..\JuceLibraryCode\include_juce_cryptography.cpp"/> <ClCompile Include="..\..\JuceLibraryCode\include_juce_data_structures.cpp"/> @@ -1461,8 +1487,16 @@ <ClCompile Include="..\..\JuceLibraryCode\include_juce_gui_extra.cpp"/> </ItemGroup> <ItemGroup> + <ClInclude Include="..\..\Source\Application\StartPage\jucer_ContentComponents.h"/> + <ClInclude Include="..\..\Source\Application\StartPage\jucer_NewProjectTemplates.h"/> + <ClInclude Include="..\..\Source\Application\StartPage\jucer_NewProjectWizard.h"/> + <ClInclude Include="..\..\Source\Application\StartPage\jucer_StartPageComponent.h"/> + <ClInclude Include="..\..\Source\Application\StartPage\jucer_StartPageTreeHolder.h"/> + <ClInclude Include="..\..\Source\Application\UserAccount\jucer_LicenseController.h"/> + <ClInclude Include="..\..\Source\Application\UserAccount\jucer_LicenseQueryThread.h"/> + <ClInclude Include="..\..\Source\Application\UserAccount\jucer_LicenseState.h"/> + <ClInclude Include="..\..\Source\Application\UserAccount\jucer_LoginFormComponent.h"/> <ClInclude Include="..\..\Source\Application\Windows\jucer_AboutWindowComponent.h"/> - <ClInclude Include="..\..\Source\Application\Windows\jucer_ApplicationUsageDataWindowComponent.h"/> <ClInclude Include="..\..\Source\Application\Windows\jucer_EditorColourSchemeWindowComponent.h"/> <ClInclude Include="..\..\Source\Application\Windows\jucer_FloatingToolWindow.h"/> <ClInclude Include="..\..\Source\Application\Windows\jucer_GlobalPathsWindowComponent.h"/> @@ -1477,7 +1511,6 @@ <ClInclude Include="..\..\Source\Application\jucer_CommonHeaders.h"/> <ClInclude Include="..\..\Source\Application\jucer_Headers.h"/> <ClInclude Include="..\..\Source\Application\jucer_MainWindow.h"/> - <ClInclude Include="..\..\Source\Application\jucer_ProjucerAnalytics.h"/> <ClInclude Include="..\..\Source\BinaryData\Templates\jucer_AnimatedComponentSimpleTemplate.h"/> <ClInclude Include="..\..\Source\BinaryData\Templates\jucer_AnimatedComponentTemplate.h"/> <ClInclude Include="..\..\Source\BinaryData\Templates\jucer_AudioComponentSimpleTemplate.h"/> @@ -1564,9 +1597,6 @@ <ClInclude Include="..\..\Source\ComponentEditor\jucer_ObjectTypes.h"/> <ClInclude Include="..\..\Source\ComponentEditor\jucer_PaintRoutine.h"/> <ClInclude Include="..\..\Source\ComponentEditor\jucer_UtilityFunctions.h"/> - <ClInclude Include="..\..\Source\Licenses\jucer_LicenseController.h"/> - <ClInclude Include="..\..\Source\Licenses\jucer_LicenseThread.h"/> - <ClInclude Include="..\..\Source\Licenses\jucer_LicenseWebview.h"/> <ClInclude Include="..\..\Source\LiveBuildEngine\UI\jucer_ActivityListComponent.h"/> <ClInclude Include="..\..\Source\LiveBuildEngine\UI\jucer_BuildTabStatusComponent.h"/> <ClInclude Include="..\..\Source\LiveBuildEngine\UI\jucer_ComponentListComponent.h"/> @@ -1586,6 +1616,9 @@ <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_MessageIDs.h"/> <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_ProjectBuildInfo.h"/> <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_SourceCodeRange.h"/> + <ClInclude Include="..\..\Source\Project\Modules\jucer_AvailableModulesList.h"/> + <ClInclude Include="..\..\Source\Project\Modules\jucer_ModuleDescription.h"/> + <ClInclude Include="..\..\Source\Project\Modules\jucer_Modules.h"/> <ClInclude Include="..\..\Source\Project\UI\Sidebar\jucer_ExporterTreeItems.h"/> <ClInclude Include="..\..\Source\Project\UI\Sidebar\jucer_FileTreeItems.h"/> <ClInclude Include="..\..\Source\Project\UI\Sidebar\jucer_LiveBuildTab.h"/> @@ -1599,9 +1632,9 @@ <ClInclude Include="..\..\Source\Project\UI\jucer_HeaderComponent.h"/> <ClInclude Include="..\..\Source\Project\UI\jucer_ModulesInformationComponent.h"/> <ClInclude Include="..\..\Source\Project\UI\jucer_ProjectContentComponent.h"/> - <ClInclude Include="..\..\Source\Project\jucer_Module.h"/> + <ClInclude Include="..\..\Source\Project\UI\jucer_ProjectMessagesComponent.h"/> + <ClInclude Include="..\..\Source\Project\UI\jucer_UserAvatarComponent.h"/> <ClInclude Include="..\..\Source\Project\jucer_Project.h"/> - <ClInclude Include="..\..\Source\Project\jucer_ProjectType.h"/> <ClInclude Include="..\..\Source\ProjectSaving\jucer_ProjectExport_Android.h"/> <ClInclude Include="..\..\Source\ProjectSaving\jucer_ProjectExport_CLion.h"/> <ClInclude Include="..\..\Source\ProjectSaving\jucer_ProjectExport_CodeBlocks.h"/> @@ -1618,10 +1651,11 @@ <ClInclude Include="..\..\Source\Utility\Helpers\jucer_Colours.h"/> <ClInclude Include="..\..\Source\Utility\Helpers\jucer_FileHelpers.h"/> <ClInclude Include="..\..\Source\Utility\Helpers\jucer_MiscUtilities.h"/> + <ClInclude Include="..\..\Source\Utility\Helpers\jucer_NewFileWizard.h"/> <ClInclude Include="..\..\Source\Utility\Helpers\jucer_PresetIDs.h"/> - <ClInclude Include="..\..\Source\Utility\Helpers\jucer_RelativePath.h"/> <ClInclude Include="..\..\Source\Utility\Helpers\jucer_TranslationHelpers.h"/> <ClInclude Include="..\..\Source\Utility\Helpers\jucer_ValueSourceHelpers.h"/> + <ClInclude Include="..\..\Source\Utility\Helpers\jucer_ValueWithDefaultWrapper.h"/> <ClInclude Include="..\..\Source\Utility\Helpers\jucer_VersionInfo.h"/> <ClInclude Include="..\..\Source\Utility\PIPs\jucer_PIPGenerator.h"/> <ClInclude Include="..\..\Source\Utility\UI\PropertyComponents\jucer_ColourPropertyComponent.h"/> @@ -1633,27 +1667,17 @@ <ClInclude Include="..\..\Source\Utility\UI\jucer_JucerTreeViewBase.h"/> <ClInclude Include="..\..\Source\Utility\UI\jucer_ProjucerLookAndFeel.h"/> <ClInclude Include="..\..\Source\Utility\UI\jucer_SlidingPanelComponent.h"/> - <ClInclude Include="..\..\Source\Utility\UI\jucer_UserSettingsPopup.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_NewFileWizard.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_NewProjectWizard.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_NewProjectWizardClasses.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_NewProjectWizardComponent.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_Animated.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_AudioApp.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_AudioPlugin.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_Blank.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_Console.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_DLL.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_GUIApp.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_openGL.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_StaticLibrary.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_StartPageComponent.h"/> - <ClInclude Include="..\..\Source\Wizards\jucer_TemplateThumbnailsComponent.h"/> - <ClInclude Include="..\..\..\..\modules\juce_analytics\analytics\juce_Analytics.h"/> - <ClInclude Include="..\..\..\..\modules\juce_analytics\analytics\juce_ButtonTracker.h"/> - <ClInclude Include="..\..\..\..\modules\juce_analytics\destinations\juce_AnalyticsDestination.h"/> - <ClInclude Include="..\..\..\..\modules\juce_analytics\destinations\juce_ThreadedAnalyticsDestination.h"/> - <ClInclude Include="..\..\..\..\modules\juce_analytics\juce_analytics.h"/> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_BinaryResourceFile.h"/> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_BuildHelperFunctions.h"/> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_Entitlements.h"/> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_Icons.h"/> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_PlistOptions.h"/> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_ProjectType.h"/> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_RelativePath.h"/> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_ResourceFileHelpers.h"/> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_ResourceRc.h"/> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_VersionNumbers.h"/> + <ClInclude Include="..\..\..\Build\juce_build_tools\juce_build_tools.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\containers\juce_AbstractFifo.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\containers\juce_Array.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\containers\juce_ArrayAllocationBase.h"/> @@ -1678,6 +1702,7 @@ <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_FileOutputStream.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_FileSearchPath.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_MemoryMappedFile.h"/> + <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_WildcardFileFilter.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\javascript\juce_Javascript.h"/> @@ -1691,6 +1716,7 @@ <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_Random.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_Range.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_StatisticsAccumulator.h"/> + <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_Atomic.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_ByteOrder.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_ContainerDeletePolicy.h"/> @@ -1733,6 +1759,7 @@ <ClInclude Include="..\..\..\..\modules\juce_core\streams\juce_SubregionStream.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\streams\juce_URLInputSource.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerSupport.h"/> + <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerWarnings.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_PlatformDefs.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_StandardHeader.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_SystemStats.h"/> @@ -1989,7 +2016,8 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_SelectedItemSet.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_TextDragAndDropTarget.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_TooltipClient.h"/> - <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.h"/> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.h"/> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_MultiTouchMapper.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\positioning\juce_MarkerList.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\positioning\juce_RelativeCoordinate.h"/> @@ -2041,6 +2069,7 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ActiveXControlComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"/> + <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_HWNDComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_NSViewComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ScopedDPIAwarenessDisabler.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_UIViewComponent.h"/> @@ -2059,11 +2088,16 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_mac_CarbonViewWrapperComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\juce_gui_extra.h"/> - <ClInclude Include="..\..\JuceLibraryCode\AppConfig.h"/> <ClInclude Include="..\..\JuceLibraryCode\BinaryData.h"/> <ClInclude Include="..\..\JuceLibraryCode\JuceHeader.h"/> </ItemGroup> <ItemGroup> + <None Include="..\..\..\Build\CMake\LaunchScreen.storyboard"/> + <None Include="..\..\..\Build\CMake\PIPAudioProcessor.cpp.in"/> + <None Include="..\..\..\Build\CMake\PIPComponent.cpp.in"/> + <None Include="..\..\..\Build\CMake\PIPConsole.cpp.in"/> + <None Include="..\..\..\Build\CMake\RecentFilesMenuTemplate.nib"/> + <None Include="..\..\..\Build\CMake\UnityPluginGUIScript.cs.in"/> <None Include="..\..\Source\BinaryData\gradle\gradle-wrapper.jar"/> <None Include="..\..\Source\BinaryData\gradle\gradlew"/> <None Include="..\..\Source\BinaryData\gradle\gradlew.bat"/> @@ -2075,7 +2109,7 @@ <None Include="..\..\Source\BinaryData\Icons\export_linux.svg"/> <None Include="..\..\Source\BinaryData\Icons\export_visualStudio.svg"/> <None Include="..\..\Source\BinaryData\Icons\export_xcode.svg"/> - <None Include="..\..\Source\BinaryData\Icons\huckleberry_icon.svg"/> + <None Include="..\..\Source\BinaryData\Icons\gpl_logo.svg"/> <None Include="..\..\Source\BinaryData\Icons\juce-logo-with-text.svg"/> <None Include="..\..\Source\BinaryData\Icons\juce_icon.png"/> <None Include="..\..\Source\BinaryData\Icons\wizard_AnimatedApp.svg"/> @@ -2088,13 +2122,8 @@ <None Include="..\..\Source\BinaryData\Icons\wizard_Openfile.svg"/> <None Include="..\..\Source\BinaryData\Icons\wizard_OpenGL.svg"/> <None Include="..\..\Source\BinaryData\Icons\wizard_StaticLibrary.svg"/> - <None Include="..\..\Source\BinaryData\Templates\jucer_UnityPluginGUIScript.cs"/> <None Include="..\..\Source\BinaryData\colourscheme_dark.xml"/> <None Include="..\..\Source\BinaryData\colourscheme_light.xml"/> - <None Include="..\..\Source\BinaryData\nothingtoseehere.txt"/> - <None Include="..\..\Source\BinaryData\offlinepage.html"/> - <None Include="..\..\Source\BinaryData\projucer_EULA.txt"/> - <None Include="..\..\Source\BinaryData\RecentFilesMenuTemplate.nib"/> <None Include="..\..\..\..\modules\juce_core\native\java\README.txt"/> <None Include="..\..\..\..\modules\juce_graphics\image_formats\jpglib\changes to libjpeg for JUCE.txt"/> <None Include="..\..\..\..\modules\juce_graphics\image_formats\pnglib\libpng_readme.txt"/> diff --git a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters index 1acc5e80..13a8a685 100644 --- a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters +++ b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters @@ -2,6 +2,12 @@ <Project ToolsVersion="16.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup> + <Filter Include="Projucer\Application\StartPage"> + <UniqueIdentifier>{1E1D2D75-0ADA-6E9E-105F-2F87632B55AF}</UniqueIdentifier> + </Filter> + <Filter Include="Projucer\Application\UserAccount"> + <UniqueIdentifier>{DA27985D-8427-CE70-CA06-EAF7009CCC60}</UniqueIdentifier> + </Filter> <Filter Include="Projucer\Application\Windows"> <UniqueIdentifier>{DC7E18A5-E854-3D99-627F-AAA88246B712}</UniqueIdentifier> </Filter> @@ -41,15 +47,15 @@ <Filter Include="Projucer\ComponentEditor"> <UniqueIdentifier>{5F21E507-E5E8-0A74-F1AE-874BB67C26CC}</UniqueIdentifier> </Filter> - <Filter Include="Projucer\Licenses"> - <UniqueIdentifier>{E5D23B90-895E-EB0B-AC18-C7EBB25546AE}</UniqueIdentifier> - </Filter> <Filter Include="Projucer\LiveBuildEngine\UI"> <UniqueIdentifier>{E880260F-D9FB-64B6-244B-6F06B70FE9EE}</UniqueIdentifier> </Filter> <Filter Include="Projucer\LiveBuildEngine"> <UniqueIdentifier>{0A3B9446-F50B-3D4E-230F-7ED493541A07}</UniqueIdentifier> </Filter> + <Filter Include="Projucer\Project\Modules"> + <UniqueIdentifier>{F5C79836-30DE-9DC7-9392-DAAB3F04C18E}</UniqueIdentifier> + </Filter> <Filter Include="Projucer\Project\UI\Sidebar"> <UniqueIdentifier>{A0A94AE6-B447-151A-D0DA-FAE9B5410EBF}</UniqueIdentifier> </Filter> @@ -80,20 +86,14 @@ <Filter Include="Projucer\Utility"> <UniqueIdentifier>{F77CA057-8DE4-E076-7EB6-D2646794864B}</UniqueIdentifier> </Filter> - <Filter Include="Projucer\Wizards"> - <UniqueIdentifier>{4BBA3556-B2A1-3008-8BE1-F82DE6666552}</UniqueIdentifier> - </Filter> <Filter Include="Projucer"> <UniqueIdentifier>{7DBEF27C-2AFE-DA02-1DBF-E80FAAC99EA7}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_analytics\analytics"> - <UniqueIdentifier>{E3CEC08A-FA14-D343-5BFF-3D6A4A4FD713}</UniqueIdentifier> - </Filter> - <Filter Include="JUCE Modules\juce_analytics\destinations"> - <UniqueIdentifier>{B3BC836A-3932-C1E4-CA3C-A1C0D83281BA}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_build_tools\utils"> + <UniqueIdentifier>{D9FAFF6D-6737-F775-056A-D0B29BE13820}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_analytics"> - <UniqueIdentifier>{97F7F593-75F8-D6B2-DC96-C946C3976226}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_build_tools"> + <UniqueIdentifier>{065C11E4-EB37-5B72-0A01-F549675EB866}</UniqueIdentifier> </Filter> <Filter Include="JUCE Modules\juce_core\containers"> <UniqueIdentifier>{42F7BE9D-3C8A-AE26-289B-8F355C068036}</UniqueIdentifier> @@ -269,6 +269,9 @@ <Filter Include="JUCE Modules\juce_gui_basics\mouse"> <UniqueIdentifier>{FE3CB19C-EF43-5CF5-DAF0-09D4E43D0AB9}</UniqueIdentifier> </Filter> + <Filter Include="JUCE Modules\juce_gui_basics\native\x11"> + <UniqueIdentifier>{FE7E6CD5-C7A0-DB20-4E7E-D6E7F08C4578}</UniqueIdentifier> + </Filter> <Filter Include="JUCE Modules\juce_gui_basics\native"> <UniqueIdentifier>{895C2D33-E08D-B1BA-BB36-FC4CA65090C8}</UniqueIdentifier> </Filter> @@ -313,6 +316,12 @@ </Filter> </ItemGroup> <ItemGroup> + <ClCompile Include="..\..\Source\Application\StartPage\jucer_NewProjectWizard.cpp"> + <Filter>Projucer\Application\StartPage</Filter> + </ClCompile> + <ClCompile Include="..\..\Source\Application\StartPage\jucer_StartPageComponent.cpp"> + <Filter>Projucer\Application\StartPage</Filter> + </ClCompile> <ClCompile Include="..\..\Source\Application\jucer_Application.cpp"> <Filter>Projucer\Application</Filter> </ClCompile> @@ -328,9 +337,6 @@ <ClCompile Include="..\..\Source\Application\jucer_MainWindow.cpp"> <Filter>Projucer\Application</Filter> </ClCompile> - <ClCompile Include="..\..\Source\Application\jucer_ProjucerAnalytics.cpp"> - <Filter>Projucer\Application</Filter> - </ClCompile> <ClCompile Include="..\..\Source\BinaryData\Templates\jucer_AnimatedComponentTemplate.cpp"> <Filter>Projucer\BinaryData\Templates</Filter> </ClCompile> @@ -355,9 +361,6 @@ <ClCompile Include="..\..\Source\BinaryData\Templates\jucer_MainTemplate_NoWindow.cpp"> <Filter>Projucer\BinaryData\Templates</Filter> </ClCompile> - <ClCompile Include="..\..\Source\BinaryData\Templates\jucer_MainTemplate_SimpleWindow.cpp"> - <Filter>Projucer\BinaryData\Templates</Filter> - </ClCompile> <ClCompile Include="..\..\Source\BinaryData\Templates\jucer_MainTemplate_Window.cpp"> <Filter>Projucer\BinaryData\Templates</Filter> </ClCompile> @@ -370,8 +373,8 @@ <ClCompile Include="..\..\Source\BinaryData\Templates\jucer_OpenGLComponentTemplate.cpp"> <Filter>Projucer\BinaryData\Templates</Filter> </ClCompile> - <ClCompile Include="..\..\Source\BinaryData\Templates\jucer_PIPMain.cpp"> - <Filter>Projucer\BinaryData\Templates</Filter> + <ClCompile Include="..\..\..\Build\CMake\juce_runtime_arch_detection.cpp"> + <Filter>Projucer\BinaryData</Filter> </ClCompile> <ClCompile Include="..\..\Source\CodeEditor\jucer_DocumentEditorComponent.cpp"> <Filter>Projucer\CodeEditor</Filter> @@ -448,9 +451,6 @@ <ClCompile Include="..\..\Source\ComponentEditor\jucer_PaintRoutine.cpp"> <Filter>Projucer\ComponentEditor</Filter> </ClCompile> - <ClCompile Include="..\..\Source\Licenses\jucer_LicenseController.cpp"> - <Filter>Projucer\Licenses</Filter> - </ClCompile> <ClCompile Include="..\..\Source\LiveBuildEngine\jucer_CompileEngineClient.cpp"> <Filter>Projucer\LiveBuildEngine</Filter> </ClCompile> @@ -460,15 +460,15 @@ <ClCompile Include="..\..\Source\LiveBuildEngine\jucer_DownloadCompileEngineThread.cpp"> <Filter>Projucer\LiveBuildEngine</Filter> </ClCompile> + <ClCompile Include="..\..\Source\Project\Modules\jucer_Modules.cpp"> + <Filter>Projucer\Project\Modules</Filter> + </ClCompile> <ClCompile Include="..\..\Source\Project\UI\jucer_HeaderComponent.cpp"> <Filter>Projucer\Project\UI</Filter> </ClCompile> <ClCompile Include="..\..\Source\Project\UI\jucer_ProjectContentComponent.cpp"> <Filter>Projucer\Project\UI</Filter> </ClCompile> - <ClCompile Include="..\..\Source\Project\jucer_Module.cpp"> - <Filter>Projucer\Project</Filter> - </ClCompile> <ClCompile Include="..\..\Source\Project\jucer_Project.cpp"> <Filter>Projucer\Project</Filter> </ClCompile> @@ -496,6 +496,9 @@ <ClCompile Include="..\..\Source\Utility\Helpers\jucer_MiscUtilities.cpp"> <Filter>Projucer\Utility\Helpers</Filter> </ClCompile> + <ClCompile Include="..\..\Source\Utility\Helpers\jucer_NewFileWizard.cpp"> + <Filter>Projucer\Utility\Helpers</Filter> + </ClCompile> <ClCompile Include="..\..\Source\Utility\Helpers\jucer_VersionInfo.cpp"> <Filter>Projucer\Utility\Helpers</Filter> </ClCompile> @@ -514,23 +517,35 @@ <ClCompile Include="..\..\Source\Utility\UI\jucer_SlidingPanelComponent.cpp"> <Filter>Projucer\Utility\UI</Filter> </ClCompile> - <ClCompile Include="..\..\Source\Wizards\jucer_NewFileWizard.cpp"> - <Filter>Projucer\Wizards</Filter> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_BinaryResourceFile.cpp"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClCompile> - <ClCompile Include="..\..\Source\Wizards\jucer_NewProjectWizardClasses.cpp"> - <Filter>Projucer\Wizards</Filter> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_BuildHelperFunctions.cpp"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_analytics\analytics\juce_Analytics.cpp"> - <Filter>JUCE Modules\juce_analytics\analytics</Filter> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_CppTokeniserFunctions.cpp"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_analytics\analytics\juce_ButtonTracker.cpp"> - <Filter>JUCE Modules\juce_analytics\analytics</Filter> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_Entitlements.cpp"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_analytics\destinations\juce_ThreadedAnalyticsDestination.cpp"> - <Filter>JUCE Modules\juce_analytics\destinations</Filter> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_Icons.cpp"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_analytics\juce_analytics.cpp"> - <Filter>JUCE Modules\juce_analytics</Filter> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_PlistOptions.cpp"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> + </ClCompile> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_ResourceFileHelpers.cpp"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> + </ClCompile> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_ResourceRc.cpp"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> + </ClCompile> + <ClCompile Include="..\..\..\Build\juce_build_tools\utils\juce_VersionNumbers.cpp"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> + </ClCompile> + <ClCompile Include="..\..\..\Build\juce_build_tools\juce_build_tools.cpp"> + <Filter>JUCE Modules\juce_build_tools</Filter> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\containers\juce_AbstractFifo.cpp"> <Filter>JUCE Modules\juce_core\containers</Filter> @@ -580,6 +595,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_FileSearchPath.cpp"> <Filter>JUCE Modules\juce_core\files</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.cpp"> + <Filter>JUCE Modules\juce_core\files</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.cpp"> <Filter>JUCE Modules\juce_core\files</Filter> </ClCompile> @@ -607,6 +625,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> <Filter>JUCE Modules\juce_core\maths</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.cpp"> + <Filter>JUCE Modules\juce_core\memory</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_MemoryBlock.cpp"> <Filter>JUCE Modules\juce_core\memory</Filter> </ClCompile> @@ -1534,6 +1555,15 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_MouseListener.cpp"> <Filter>JUCE Modules\juce_gui_basics\mouse</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_DragAndDrop.cpp"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.cpp"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.cpp"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_android_ContentSharer.cpp"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> </ClCompile> @@ -1561,13 +1591,7 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_FileChooser.cpp"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.cpp"> - <Filter>JUCE Modules\juce_gui_basics\native</Filter> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Clipboard.cpp"> - <Filter>JUCE Modules\juce_gui_basics\native</Filter> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Windowing.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_Windowing.cpp"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_mac_FileChooser.mm"> @@ -1801,6 +1825,9 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_ActiveXComponent.cpp"> <Filter>JUCE Modules\juce_gui_extra\native</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_HWNDComponent.cpp"> + <Filter>JUCE Modules\juce_gui_extra\native</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_SystemTrayIcon.cpp"> <Filter>JUCE Modules\juce_gui_extra\native</Filter> </ClCompile> @@ -1816,7 +1843,7 @@ <ClCompile Include="..\..\JuceLibraryCode\BinaryData.cpp"> <Filter>JUCE Library Code</Filter> </ClCompile> - <ClCompile Include="..\..\JuceLibraryCode\include_juce_analytics.cpp"> + <ClCompile Include="..\..\JuceLibraryCode\include_juce_build_tools.cpp"> <Filter>JUCE Library Code</Filter> </ClCompile> <ClCompile Include="..\..\JuceLibraryCode\include_juce_core.cpp"> @@ -1842,10 +1869,34 @@ </ClCompile> </ItemGroup> <ItemGroup> - <ClInclude Include="..\..\Source\Application\Windows\jucer_AboutWindowComponent.h"> - <Filter>Projucer\Application\Windows</Filter> + <ClInclude Include="..\..\Source\Application\StartPage\jucer_ContentComponents.h"> + <Filter>Projucer\Application\StartPage</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\Application\StartPage\jucer_NewProjectTemplates.h"> + <Filter>Projucer\Application\StartPage</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\Application\StartPage\jucer_NewProjectWizard.h"> + <Filter>Projucer\Application\StartPage</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Application\Windows\jucer_ApplicationUsageDataWindowComponent.h"> + <ClInclude Include="..\..\Source\Application\StartPage\jucer_StartPageComponent.h"> + <Filter>Projucer\Application\StartPage</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\Application\StartPage\jucer_StartPageTreeHolder.h"> + <Filter>Projucer\Application\StartPage</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\Application\UserAccount\jucer_LicenseController.h"> + <Filter>Projucer\Application\UserAccount</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\Application\UserAccount\jucer_LicenseQueryThread.h"> + <Filter>Projucer\Application\UserAccount</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\Application\UserAccount\jucer_LicenseState.h"> + <Filter>Projucer\Application\UserAccount</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\Application\UserAccount\jucer_LoginFormComponent.h"> + <Filter>Projucer\Application\UserAccount</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\Application\Windows\jucer_AboutWindowComponent.h"> <Filter>Projucer\Application\Windows</Filter> </ClInclude> <ClInclude Include="..\..\Source\Application\Windows\jucer_EditorColourSchemeWindowComponent.h"> @@ -1890,9 +1941,6 @@ <ClInclude Include="..\..\Source\Application\jucer_MainWindow.h"> <Filter>Projucer\Application</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Application\jucer_ProjucerAnalytics.h"> - <Filter>Projucer\Application</Filter> - </ClInclude> <ClInclude Include="..\..\Source\BinaryData\Templates\jucer_AnimatedComponentSimpleTemplate.h"> <Filter>Projucer\BinaryData\Templates</Filter> </ClInclude> @@ -2151,15 +2199,6 @@ <ClInclude Include="..\..\Source\ComponentEditor\jucer_UtilityFunctions.h"> <Filter>Projucer\ComponentEditor</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Licenses\jucer_LicenseController.h"> - <Filter>Projucer\Licenses</Filter> - </ClInclude> - <ClInclude Include="..\..\Source\Licenses\jucer_LicenseThread.h"> - <Filter>Projucer\Licenses</Filter> - </ClInclude> - <ClInclude Include="..\..\Source\Licenses\jucer_LicenseWebview.h"> - <Filter>Projucer\Licenses</Filter> - </ClInclude> <ClInclude Include="..\..\Source\LiveBuildEngine\UI\jucer_ActivityListComponent.h"> <Filter>Projucer\LiveBuildEngine\UI</Filter> </ClInclude> @@ -2217,6 +2256,15 @@ <ClInclude Include="..\..\Source\LiveBuildEngine\jucer_SourceCodeRange.h"> <Filter>Projucer\LiveBuildEngine</Filter> </ClInclude> + <ClInclude Include="..\..\Source\Project\Modules\jucer_AvailableModulesList.h"> + <Filter>Projucer\Project\Modules</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\Project\Modules\jucer_ModuleDescription.h"> + <Filter>Projucer\Project\Modules</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\Project\Modules\jucer_Modules.h"> + <Filter>Projucer\Project\Modules</Filter> + </ClInclude> <ClInclude Include="..\..\Source\Project\UI\Sidebar\jucer_ExporterTreeItems.h"> <Filter>Projucer\Project\UI\Sidebar</Filter> </ClInclude> @@ -2256,13 +2304,13 @@ <ClInclude Include="..\..\Source\Project\UI\jucer_ProjectContentComponent.h"> <Filter>Projucer\Project\UI</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Project\jucer_Module.h"> - <Filter>Projucer\Project</Filter> + <ClInclude Include="..\..\Source\Project\UI\jucer_ProjectMessagesComponent.h"> + <Filter>Projucer\Project\UI</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Project\jucer_Project.h"> - <Filter>Projucer\Project</Filter> + <ClInclude Include="..\..\Source\Project\UI\jucer_UserAvatarComponent.h"> + <Filter>Projucer\Project\UI</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Project\jucer_ProjectType.h"> + <ClInclude Include="..\..\Source\Project\jucer_Project.h"> <Filter>Projucer\Project</Filter> </ClInclude> <ClInclude Include="..\..\Source\ProjectSaving\jucer_ProjectExport_Android.h"> @@ -2313,10 +2361,10 @@ <ClInclude Include="..\..\Source\Utility\Helpers\jucer_MiscUtilities.h"> <Filter>Projucer\Utility\Helpers</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Utility\Helpers\jucer_PresetIDs.h"> + <ClInclude Include="..\..\Source\Utility\Helpers\jucer_NewFileWizard.h"> <Filter>Projucer\Utility\Helpers</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Utility\Helpers\jucer_RelativePath.h"> + <ClInclude Include="..\..\Source\Utility\Helpers\jucer_PresetIDs.h"> <Filter>Projucer\Utility\Helpers</Filter> </ClInclude> <ClInclude Include="..\..\Source\Utility\Helpers\jucer_TranslationHelpers.h"> @@ -2325,6 +2373,9 @@ <ClInclude Include="..\..\Source\Utility\Helpers\jucer_ValueSourceHelpers.h"> <Filter>Projucer\Utility\Helpers</Filter> </ClInclude> + <ClInclude Include="..\..\Source\Utility\Helpers\jucer_ValueWithDefaultWrapper.h"> + <Filter>Projucer\Utility\Helpers</Filter> + </ClInclude> <ClInclude Include="..\..\Source\Utility\Helpers\jucer_VersionInfo.h"> <Filter>Projucer\Utility\Helpers</Filter> </ClInclude> @@ -2358,68 +2409,38 @@ <ClInclude Include="..\..\Source\Utility\UI\jucer_SlidingPanelComponent.h"> <Filter>Projucer\Utility\UI</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Utility\UI\jucer_UserSettingsPopup.h"> - <Filter>Projucer\Utility\UI</Filter> - </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_NewFileWizard.h"> - <Filter>Projucer\Wizards</Filter> - </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_NewProjectWizard.h"> - <Filter>Projucer\Wizards</Filter> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_BinaryResourceFile.h"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_NewProjectWizardClasses.h"> - <Filter>Projucer\Wizards</Filter> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_BuildHelperFunctions.h"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_NewProjectWizardComponent.h"> - <Filter>Projucer\Wizards</Filter> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_Entitlements.h"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_Animated.h"> - <Filter>Projucer\Wizards</Filter> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_Icons.h"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_AudioApp.h"> - <Filter>Projucer\Wizards</Filter> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_PlistOptions.h"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_AudioPlugin.h"> - <Filter>Projucer\Wizards</Filter> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_ProjectType.h"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_Blank.h"> - <Filter>Projucer\Wizards</Filter> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_RelativePath.h"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_Console.h"> - <Filter>Projucer\Wizards</Filter> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_ResourceFileHelpers.h"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_DLL.h"> - <Filter>Projucer\Wizards</Filter> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_ResourceRc.h"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_GUIApp.h"> - <Filter>Projucer\Wizards</Filter> + <ClInclude Include="..\..\..\Build\juce_build_tools\utils\juce_VersionNumbers.h"> + <Filter>JUCE Modules\juce_build_tools\utils</Filter> </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_openGL.h"> - <Filter>Projucer\Wizards</Filter> - </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_ProjectWizard_StaticLibrary.h"> - <Filter>Projucer\Wizards</Filter> - </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_StartPageComponent.h"> - <Filter>Projucer\Wizards</Filter> - </ClInclude> - <ClInclude Include="..\..\Source\Wizards\jucer_TemplateThumbnailsComponent.h"> - <Filter>Projucer\Wizards</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_analytics\analytics\juce_Analytics.h"> - <Filter>JUCE Modules\juce_analytics\analytics</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_analytics\analytics\juce_ButtonTracker.h"> - <Filter>JUCE Modules\juce_analytics\analytics</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_analytics\destinations\juce_AnalyticsDestination.h"> - <Filter>JUCE Modules\juce_analytics\destinations</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_analytics\destinations\juce_ThreadedAnalyticsDestination.h"> - <Filter>JUCE Modules\juce_analytics\destinations</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_analytics\juce_analytics.h"> - <Filter>JUCE Modules\juce_analytics</Filter> + <ClInclude Include="..\..\..\Build\juce_build_tools\juce_build_tools.h"> + <Filter>JUCE Modules\juce_build_tools</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_core\containers\juce_AbstractFifo.h"> <Filter>JUCE Modules\juce_core\containers</Filter> @@ -2493,6 +2514,9 @@ <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_MemoryMappedFile.h"> <Filter>JUCE Modules\juce_core\files</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.h"> + <Filter>JUCE Modules\juce_core\files</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.h"> <Filter>JUCE Modules\juce_core\files</Filter> </ClInclude> @@ -2532,6 +2556,9 @@ <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_StatisticsAccumulator.h"> <Filter>JUCE Modules\juce_core\maths</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.h"> + <Filter>JUCE Modules\juce_core\memory</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_Atomic.h"> <Filter>JUCE Modules\juce_core\memory</Filter> </ClInclude> @@ -2658,6 +2685,9 @@ <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerSupport.h"> <Filter>JUCE Modules\juce_core\system</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerWarnings.h"> + <Filter>JUCE Modules\juce_core\system</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_PlatformDefs.h"> <Filter>JUCE Modules\juce_core\system</Filter> </ClInclude> @@ -3426,8 +3456,11 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_TooltipClient.h"> <Filter>JUCE Modules\juce_gui_basics\mouse</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.h"> - <Filter>JUCE Modules\juce_gui_basics\native</Filter> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.h"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.h"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_MultiTouchMapper.h"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> @@ -3582,6 +3615,9 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"> <Filter>JUCE Modules\juce_gui_extra\embedding</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_HWNDComponent.h"> + <Filter>JUCE Modules\juce_gui_extra\embedding</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_NSViewComponent.h"> <Filter>JUCE Modules\juce_gui_extra\embedding</Filter> </ClInclude> @@ -3636,9 +3672,6 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_extra\juce_gui_extra.h"> <Filter>JUCE Modules\juce_gui_extra</Filter> </ClInclude> - <ClInclude Include="..\..\JuceLibraryCode\AppConfig.h"> - <Filter>JUCE Library Code</Filter> - </ClInclude> <ClInclude Include="..\..\JuceLibraryCode\BinaryData.h"> <Filter>JUCE Library Code</Filter> </ClInclude> @@ -3647,6 +3680,24 @@ </ClInclude> </ItemGroup> <ItemGroup> + <None Include="..\..\..\Build\CMake\LaunchScreen.storyboard"> + <Filter>Projucer\BinaryData</Filter> + </None> + <None Include="..\..\..\Build\CMake\PIPAudioProcessor.cpp.in"> + <Filter>Projucer\BinaryData</Filter> + </None> + <None Include="..\..\..\Build\CMake\PIPComponent.cpp.in"> + <Filter>Projucer\BinaryData</Filter> + </None> + <None Include="..\..\..\Build\CMake\PIPConsole.cpp.in"> + <Filter>Projucer\BinaryData</Filter> + </None> + <None Include="..\..\..\Build\CMake\RecentFilesMenuTemplate.nib"> + <Filter>Projucer\BinaryData</Filter> + </None> + <None Include="..\..\..\Build\CMake\UnityPluginGUIScript.cs.in"> + <Filter>Projucer\BinaryData</Filter> + </None> <None Include="..\..\Source\BinaryData\gradle\gradle-wrapper.jar"> <Filter>Projucer\BinaryData\gradle</Filter> </None> @@ -3680,7 +3731,7 @@ <None Include="..\..\Source\BinaryData\Icons\export_xcode.svg"> <Filter>Projucer\BinaryData\Icons</Filter> </None> - <None Include="..\..\Source\BinaryData\Icons\huckleberry_icon.svg"> + <None Include="..\..\Source\BinaryData\Icons\gpl_logo.svg"> <Filter>Projucer\BinaryData\Icons</Filter> </None> <None Include="..\..\Source\BinaryData\Icons\juce-logo-with-text.svg"> @@ -3719,27 +3770,12 @@ <None Include="..\..\Source\BinaryData\Icons\wizard_StaticLibrary.svg"> <Filter>Projucer\BinaryData\Icons</Filter> </None> - <None Include="..\..\Source\BinaryData\Templates\jucer_UnityPluginGUIScript.cs"> - <Filter>Projucer\BinaryData\Templates</Filter> - </None> <None Include="..\..\Source\BinaryData\colourscheme_dark.xml"> <Filter>Projucer\BinaryData</Filter> </None> <None Include="..\..\Source\BinaryData\colourscheme_light.xml"> <Filter>Projucer\BinaryData</Filter> </None> - <None Include="..\..\Source\BinaryData\nothingtoseehere.txt"> - <Filter>Projucer\BinaryData</Filter> - </None> - <None Include="..\..\Source\BinaryData\offlinepage.html"> - <Filter>Projucer\BinaryData</Filter> - </None> - <None Include="..\..\Source\BinaryData\projucer_EULA.txt"> - <Filter>Projucer\BinaryData</Filter> - </None> - <None Include="..\..\Source\BinaryData\RecentFilesMenuTemplate.nib"> - <Filter>Projucer\BinaryData</Filter> - </None> <None Include="..\..\..\..\modules\juce_core\native\java\README.txt"> <Filter>JUCE Modules\juce_core\native\java</Filter> </None> diff --git a/extras/Projucer/Builds/VisualStudio2019/resources.rc b/extras/Projucer/Builds/VisualStudio2019/resources.rc index 3cc301e6..cb7ae4b8 100644 --- a/extras/Projucer/Builds/VisualStudio2019/resources.rc +++ b/extras/Projucer/Builds/VisualStudio2019/resources.rc @@ -1,3 +1,5 @@ +#pragma code_page(65001) + #ifdef JUCE_USER_DEFINED_RC_FILE #include JUCE_USER_DEFINED_RC_FILE #else @@ -7,18 +9,18 @@ #include <windows.h> VS_VERSION_INFO VERSIONINFO -FILEVERSION 5,4,7,0 +FILEVERSION 6,0,5,0 BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904E4" BEGIN - VALUE "CompanyName", "ROLI Ltd.\0" - VALUE "LegalCopyright", "ROLI Ltd.\0" + VALUE "CompanyName", "Raw Material Software Limited\0" + VALUE "LegalCopyright", "Raw Material Software Limited\0" VALUE "FileDescription", "Projucer\0" - VALUE "FileVersion", "5.4.7\0" + VALUE "FileVersion", "6.0.5\0" VALUE "ProductName", "Projucer\0" - VALUE "ProductVersion", "5.4.7\0" + VALUE "ProductVersion", "6.0.5\0" END END diff --git a/extras/Projucer/CMakeLists.txt b/extras/Projucer/CMakeLists.txt new file mode 100644 index 00000000..3346e881 --- /dev/null +++ b/extras/Projucer/CMakeLists.txt @@ -0,0 +1,171 @@ +# ============================================================================== +# +# This file is part of the JUCE library. +# Copyright (c) 2020 - Raw Material Software Limited +# +# JUCE is an open source library subject to commercial or open-source +# licensing. +# +# By using JUCE, you agree to the terms of both the JUCE 6 End-User License +# Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). +# +# End User License Agreement: www.juce.com/juce-6-licence +# Privacy Policy: www.juce.com/juce-privacy-policy +# +# Or: You may also use this code under the terms of the GPL v3 (see +# www.gnu.org/licenses). +# +# JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER +# EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE +# DISCLAIMED. +# +# ============================================================================== + +juce_add_gui_app(Projucer + BUNDLE_ID com.juce.theprojucer + ICON_BIG ${CMAKE_CURRENT_SOURCE_DIR}/Source/BinaryData/Icons/juce_icon.png + DOCUMENT_EXTENSIONS jucer + NEEDS_CURL TRUE + NEEDS_WEB_BROWSER TRUE) + +juce_generate_juce_header(Projucer) + +# This is to work around a bug with how cmake computes language standard flags with +# target_compile_features +set_target_properties(Projucer PROPERTIES CXX_STANDARD 11) + +target_sources(Projucer PRIVATE + Source/Application/jucer_AutoUpdater.cpp + Source/Application/jucer_CommandLine.cpp + Source/Application/jucer_Main.cpp + Source/Application/jucer_MainWindow.cpp + Source/Application/StartPage/jucer_StartPageComponent.cpp + Source/Application/StartPage/jucer_NewProjectWizard.cpp + Source/CodeEditor/jucer_DocumentEditorComponent.cpp + Source/CodeEditor/jucer_OpenDocumentManager.cpp + Source/CodeEditor/jucer_SourceCodeEditor.cpp + Source/ComponentEditor/Components/jucer_ComponentTypeHandler.cpp + Source/ComponentEditor/Documents/jucer_ButtonDocument.cpp + Source/ComponentEditor/Documents/jucer_ComponentDocument.cpp + Source/ComponentEditor/PaintElements/jucer_ColouredElement.cpp + Source/ComponentEditor/PaintElements/jucer_PaintElement.cpp + Source/ComponentEditor/PaintElements/jucer_PaintElementGroup.cpp + Source/ComponentEditor/PaintElements/jucer_PaintElementImage.cpp + Source/ComponentEditor/PaintElements/jucer_PaintElementPath.cpp + Source/ComponentEditor/UI/jucer_ComponentLayoutEditor.cpp + Source/ComponentEditor/UI/jucer_ComponentOverlayComponent.cpp + Source/ComponentEditor/UI/jucer_EditingPanelBase.cpp + Source/ComponentEditor/UI/jucer_JucerDocumentEditor.cpp + Source/ComponentEditor/UI/jucer_PaintRoutineEditor.cpp + Source/ComponentEditor/UI/jucer_PaintRoutinePanel.cpp + Source/ComponentEditor/UI/jucer_ResourceEditorPanel.cpp + Source/ComponentEditor/UI/jucer_TestComponent.cpp + Source/ComponentEditor/jucer_BinaryResources.cpp + Source/ComponentEditor/jucer_ComponentLayout.cpp + Source/ComponentEditor/jucer_GeneratedCode.cpp + Source/ComponentEditor/jucer_JucerDocument.cpp + Source/ComponentEditor/jucer_ObjectTypes.cpp + Source/ComponentEditor/jucer_PaintRoutine.cpp + Source/LiveBuildEngine/jucer_CompileEngineClient.cpp + Source/LiveBuildEngine/jucer_CompileEngineServer.cpp + Source/LiveBuildEngine/jucer_DownloadCompileEngineThread.cpp + Source/Project/Modules/jucer_Modules.cpp + Source/Project/UI/jucer_HeaderComponent.cpp + Source/Project/jucer_Project.cpp + Source/ProjectSaving/jucer_ProjectExporter.cpp + Source/ProjectSaving/jucer_ProjectSaver.cpp + Source/ProjectSaving/jucer_ResourceFile.cpp + Source/Settings/jucer_AppearanceSettings.cpp + Source/Settings/jucer_StoredSettings.cpp + Source/Utility/Helpers/jucer_CodeHelpers.cpp + Source/Utility/Helpers/jucer_FileHelpers.cpp + Source/Utility/Helpers/jucer_MiscUtilities.cpp + Source/Utility/Helpers/jucer_NewFileWizard.cpp + Source/Utility/Helpers/jucer_VersionInfo.cpp + Source/Utility/PIPs/jucer_PIPGenerator.cpp + Source/Utility/UI/jucer_Icons.cpp + Source/Utility/UI/jucer_JucerTreeViewBase.cpp + Source/Utility/UI/jucer_ProjucerLookAndFeel.cpp + Source/Utility/UI/jucer_SlidingPanelComponent.cpp) + +target_compile_definitions(Projucer PRIVATE + JUCE_ALLOW_STATIC_NULL_VARIABLES=0 + JUCE_LOAD_CURL_SYMBOLS_LAZILY=1 + JUCE_LOG_ASSERTIONS=1 + JUCE_STRICT_REFCOUNTEDPOINTER=1 + JUCE_USE_CURL=1 + JUCE_WEB_BROWSER=0) + +juce_add_binary_data(ProjucerData SOURCES + Source/BinaryData/Icons/background_logo.svg + Source/BinaryData/Icons/export_android.svg + Source/BinaryData/Icons/export_clion.svg + Source/BinaryData/Icons/export_codeBlocks.svg + Source/BinaryData/Icons/export_linux.svg + Source/BinaryData/Icons/export_visualStudio.svg + Source/BinaryData/Icons/export_xcode.svg + Source/BinaryData/Icons/gpl_logo.svg + Source/BinaryData/Icons/juce-logo-with-text.svg + Source/BinaryData/Icons/juce_icon.png + Source/BinaryData/Icons/wizard_AnimatedApp.svg + Source/BinaryData/Icons/wizard_AudioApp.svg + Source/BinaryData/Icons/wizard_AudioPlugin.svg + Source/BinaryData/Icons/wizard_ConsoleApp.svg + Source/BinaryData/Icons/wizard_DLL.svg + Source/BinaryData/Icons/wizard_GUI.svg + Source/BinaryData/Icons/wizard_Highlight.svg + Source/BinaryData/Icons/wizard_OpenGL.svg + Source/BinaryData/Icons/wizard_Openfile.svg + Source/BinaryData/Icons/wizard_StaticLibrary.svg + Source/BinaryData/Templates/jucer_AnimatedComponentSimpleTemplate.h + Source/BinaryData/Templates/jucer_AnimatedComponentTemplate.cpp + Source/BinaryData/Templates/jucer_AnimatedComponentTemplate.h + Source/BinaryData/Templates/jucer_AudioComponentSimpleTemplate.h + Source/BinaryData/Templates/jucer_AudioComponentTemplate.cpp + Source/BinaryData/Templates/jucer_AudioComponentTemplate.h + Source/BinaryData/Templates/jucer_AudioPluginEditorTemplate.cpp + Source/BinaryData/Templates/jucer_AudioPluginEditorTemplate.h + Source/BinaryData/Templates/jucer_AudioPluginFilterTemplate.cpp + Source/BinaryData/Templates/jucer_AudioPluginFilterTemplate.h + Source/BinaryData/Templates/jucer_ComponentTemplate.cpp + Source/BinaryData/Templates/jucer_ComponentTemplate.h + Source/BinaryData/Templates/jucer_ContentCompSimpleTemplate.h + Source/BinaryData/Templates/jucer_ContentCompTemplate.cpp + Source/BinaryData/Templates/jucer_ContentCompTemplate.h + Source/BinaryData/Templates/jucer_InlineComponentTemplate.h + Source/BinaryData/Templates/jucer_MainConsoleAppTemplate.cpp + Source/BinaryData/Templates/jucer_MainTemplate_NoWindow.cpp + Source/BinaryData/Templates/jucer_MainTemplate_Window.cpp + Source/BinaryData/Templates/jucer_NewComponentTemplate.cpp + Source/BinaryData/Templates/jucer_NewComponentTemplate.h + Source/BinaryData/Templates/jucer_NewCppFileTemplate.cpp + Source/BinaryData/Templates/jucer_NewCppFileTemplate.h + Source/BinaryData/Templates/jucer_NewInlineComponentTemplate.h + Source/BinaryData/Templates/jucer_OpenGLComponentSimpleTemplate.h + Source/BinaryData/Templates/jucer_OpenGLComponentTemplate.cpp + Source/BinaryData/Templates/jucer_OpenGLComponentTemplate.h + Source/BinaryData/Templates/jucer_PIPAudioProcessorTemplate.h + Source/BinaryData/Templates/jucer_PIPTemplate.h + Source/BinaryData/colourscheme_dark.xml + Source/BinaryData/colourscheme_light.xml + Source/BinaryData/gradle/LICENSE + Source/BinaryData/gradle/gradle-wrapper.jar + Source/BinaryData/gradle/gradlew + Source/BinaryData/gradle/gradlew.bat + + ../Build/CMake/LaunchScreen.storyboard + ../Build/CMake/PIPAudioProcessor.cpp.in + ../Build/CMake/PIPComponent.cpp.in + ../Build/CMake/PIPConsole.cpp.in + ../Build/CMake/RecentFilesMenuTemplate.nib + ../Build/CMake/UnityPluginGUIScript.cs.in + ../Build/CMake/juce_runtime_arch_detection.cpp) + +target_link_libraries(Projucer PRIVATE + ProjucerData + juce::juce_build_tools + juce::juce_cryptography + juce::juce_gui_extra + juce::juce_recommended_config_flags + juce::juce_recommended_lto_flags + juce::juce_recommended_warning_flags) diff --git a/extras/Projucer/JuceLibraryCode/AppConfig.h b/extras/Projucer/JuceLibraryCode/AppConfig.h deleted file mode 100644 index cb5a3244..00000000 --- a/extras/Projucer/JuceLibraryCode/AppConfig.h +++ /dev/null @@ -1,197 +0,0 @@ -/* - - IMPORTANT! This file is auto-generated each time you save your - project - if you alter its contents, your changes may be overwritten! - - There's a section below where you can add your own custom code safely, and the - Projucer will preserve the contents of that block, but the best way to change - any of these definitions is by using the Projucer's project settings. - - Any commented-out settings will assume their default values. - -*/ - -#pragma once - -//============================================================================== -// [BEGIN_USER_CODE_SECTION] - -/* - ============================================================================== - - In accordance with the terms of the JUCE 5 End-Use License Agreement, the - JUCE Code in SECTION A cannot be removed, changed or otherwise rendered - ineffective unless you have a JUCE Indie or Pro license, or are using JUCE - under the GPL v3 license. - - End User License Agreement: www.juce.com/juce-5-licence - - ============================================================================== -*/ - -// BEGIN SECTION A - -#ifndef JUCER_ENABLE_GPL_MODE - #define JUCER_ENABLE_GPL_MODE 0 -#endif - -// END SECTION A - -// [END_USER_CODE_SECTION] - -/* - ============================================================================== - - In accordance with the terms of the JUCE 5 End-Use License Agreement, the - JUCE Code in SECTION A cannot be removed, changed or otherwise rendered - ineffective unless you have a JUCE Indie or Pro license, or are using JUCE - under the GPL v3 license. - - End User License Agreement: www.juce.com/juce-5-licence - - ============================================================================== -*/ - -// BEGIN SECTION A - -#ifndef JUCE_DISPLAY_SPLASH_SCREEN - #define JUCE_DISPLAY_SPLASH_SCREEN 0 -#endif - -#ifndef JUCE_REPORT_APP_USAGE - #define JUCE_REPORT_APP_USAGE 0 -#endif - -// END SECTION A - -#define JUCE_USE_DARK_SPLASH_SCREEN 1 - -#define JUCE_PROJUCER_VERSION 0x50407 - -//============================================================================== -#define JUCE_MODULE_AVAILABLE_juce_analytics 1 -#define JUCE_MODULE_AVAILABLE_juce_core 1 -#define JUCE_MODULE_AVAILABLE_juce_cryptography 1 -#define JUCE_MODULE_AVAILABLE_juce_data_structures 1 -#define JUCE_MODULE_AVAILABLE_juce_events 1 -#define JUCE_MODULE_AVAILABLE_juce_graphics 1 -#define JUCE_MODULE_AVAILABLE_juce_gui_basics 1 -#define JUCE_MODULE_AVAILABLE_juce_gui_extra 1 - -#define JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED 1 - -//============================================================================== -// juce_core flags: - -#ifndef JUCE_FORCE_DEBUG - //#define JUCE_FORCE_DEBUG 0 -#endif - -#ifndef JUCE_LOG_ASSERTIONS - #define JUCE_LOG_ASSERTIONS 1 -#endif - -#ifndef JUCE_CHECK_MEMORY_LEAKS - //#define JUCE_CHECK_MEMORY_LEAKS 1 -#endif - -#ifndef JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES - //#define JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES 0 -#endif - -#ifndef JUCE_INCLUDE_ZLIB_CODE - //#define JUCE_INCLUDE_ZLIB_CODE 1 -#endif - -#ifndef JUCE_USE_CURL - #define JUCE_USE_CURL 1 -#endif - -#ifndef JUCE_LOAD_CURL_SYMBOLS_LAZILY - #define JUCE_LOAD_CURL_SYMBOLS_LAZILY 1 -#endif - -#ifndef JUCE_CATCH_UNHANDLED_EXCEPTIONS - //#define JUCE_CATCH_UNHANDLED_EXCEPTIONS 0 -#endif - -#ifndef JUCE_ALLOW_STATIC_NULL_VARIABLES - #define JUCE_ALLOW_STATIC_NULL_VARIABLES 0 -#endif - -#ifndef JUCE_STRICT_REFCOUNTEDPOINTER - #define JUCE_STRICT_REFCOUNTEDPOINTER 1 -#endif - -//============================================================================== -// juce_events flags: - -#ifndef JUCE_EXECUTE_APP_SUSPEND_ON_BACKGROUND_TASK - //#define JUCE_EXECUTE_APP_SUSPEND_ON_BACKGROUND_TASK 0 -#endif - -//============================================================================== -// juce_graphics flags: - -#ifndef JUCE_USE_COREIMAGE_LOADER - //#define JUCE_USE_COREIMAGE_LOADER 1 -#endif - -#ifndef JUCE_USE_DIRECTWRITE - //#define JUCE_USE_DIRECTWRITE 1 -#endif - -#ifndef JUCE_DISABLE_COREGRAPHICS_FONT_SMOOTHING - //#define JUCE_DISABLE_COREGRAPHICS_FONT_SMOOTHING 0 -#endif - -//============================================================================== -// juce_gui_basics flags: - -#ifndef JUCE_ENABLE_REPAINT_DEBUGGING - //#define JUCE_ENABLE_REPAINT_DEBUGGING 0 -#endif - -#ifndef JUCE_USE_XRANDR - //#define JUCE_USE_XRANDR 1 -#endif - -#ifndef JUCE_USE_XINERAMA - //#define JUCE_USE_XINERAMA 1 -#endif - -#ifndef JUCE_USE_XSHM - //#define JUCE_USE_XSHM 1 -#endif - -#ifndef JUCE_USE_XRENDER - //#define JUCE_USE_XRENDER 0 -#endif - -#ifndef JUCE_USE_XCURSOR - //#define JUCE_USE_XCURSOR 1 -#endif - -#ifndef JUCE_WIN_PER_MONITOR_DPI_AWARE - //#define JUCE_WIN_PER_MONITOR_DPI_AWARE 1 -#endif - -//============================================================================== -// juce_gui_extra flags: - -#ifndef JUCE_WEB_BROWSER - //#define JUCE_WEB_BROWSER 1 -#endif - -#ifndef JUCE_ENABLE_LIVE_CONSTANT_EDITOR - //#define JUCE_ENABLE_LIVE_CONSTANT_EDITOR 0 -#endif - -//============================================================================== -#ifndef JUCE_STANDALONE_APPLICATION - #if defined(JucePlugin_Name) && defined(JucePlugin_Build_Standalone) - #define JUCE_STANDALONE_APPLICATION JucePlugin_Build_Standalone - #else - #define JUCE_STANDALONE_APPLICATION 1 - #endif -#endif diff --git a/extras/Projucer/JuceLibraryCode/BinaryData.cpp b/extras/Projucer/JuceLibraryCode/BinaryData.cpp index 096299a5..da75406b 100644 --- a/extras/Projucer/JuceLibraryCode/BinaryData.cpp +++ b/extras/Projucer/JuceLibraryCode/BinaryData.cpp @@ -7,3415 +7,3086 @@ namespace BinaryData { -//================== gradle-wrapper.jar ================== +//================== LaunchScreen.storyboard ================== static const unsigned char temp_binary_data_0[] = -{ 80,75,3,4,10,0,0,8,8,0,42,178,149,71,0,0,0,0,2,0,0,0,0,0,0,0,9,0,0,0,77,69,84,65,45,73,78,70,47,3,0,80,75,3,4,10,0,0,8,8,0,42,178,149,71,215,149,152,82,63,0,0,0,85,0,0,0,20,0,0,0,77,69,84,65,45,73,78,70,47,77,65,78,73,70,69,83,84,46,77,70,243,77,204, -203,76,75,45,46,209,13,75,45,42,206,204,207,179,82,48,212,51,224,229,242,204,45,200,73,205,77,205,43,73,44,1,10,234,134,100,150,228,164,90,41,184,23,37,166,228,164,98,200,194,181,26,233,25,2,245,242,114,1,0,80,75,3,4,10,0,0,8,8,0,22,178,149,71,0,0,0, -0,2,0,0,0,0,0,0,0,4,0,0,0,111,114,103,47,3,0,80,75,3,4,10,0,0,8,8,0,22,178,149,71,0,0,0,0,2,0,0,0,0,0,0,0,11,0,0,0,111,114,103,47,103,114,97,100,108,101,47,3,0,80,75,3,4,10,0,0,8,8,0,22,178,149,71,0,0,0,0,2,0,0,0,0,0,0,0,19,0,0,0,111,114,103,47,103,114, -97,100,108,101,47,119,114,97,112,112,101,114,47,3,0,80,75,3,4,10,0,0,8,8,0,22,178,149,71,104,130,100,102,163,0,0,0,213,0,0,0,35,0,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,68,111,119,110,108,111,97,100,36,49,46,99,108, -97,115,115,125,140,77,10,194,48,16,133,223,104,53,90,43,118,47,130,11,215,134,158,193,31,112,33,46,60,65,108,67,108,9,73,73,170,189,155,11,15,224,161,196,20,113,235,60,230,61,30,204,124,175,247,227,9,32,67,194,192,24,98,66,124,182,55,151,203,125,169, -37,97,186,181,173,209,86,20,235,74,220,5,97,182,51,185,182,190,52,234,40,155,171,45,24,38,132,133,117,138,43,39,10,45,121,235,68,93,75,199,127,127,171,140,0,66,114,48,70,186,141,22,222,75,79,72,59,26,215,194,40,126,186,84,50,111,8,243,63,144,116,25,16, -61,124,167,31,132,208,34,12,66,70,24,6,31,135,141,195,13,117,45,29,125,0,80,75,3,4,10,0,0,8,8,0,22,178,149,71,197,222,133,214,20,2,0,0,112,4,0,0,68,0,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,68,111,119,110,108,111,97, -100,36,83,121,115,116,101,109,80,114,111,112,101,114,116,105,101,115,80,114,111,120,121,65,117,116,104,101,110,116,105,99,97,116,111,114,46,99,108,97,115,115,165,83,109,111,18,65,16,126,22,40,135,199,209,226,169,96,173,149,218,214,122,84,229,138,111, -209,96,26,9,141,137,9,49,77,170,77,76,63,109,97,3,103,174,119,100,111,145,242,175,244,139,109,52,241,7,248,163,140,179,64,149,32,1,19,239,195,206,236,60,243,204,60,59,187,247,227,231,215,239,0,202,120,106,34,141,130,9,11,5,3,107,41,220,54,177,142,141, -20,54,83,88,214,238,29,19,91,184,107,34,14,199,192,182,129,123,12,201,23,94,224,169,93,134,184,83,60,100,72,212,194,166,96,88,170,123,129,120,211,61,57,22,242,45,63,246,41,98,215,195,6,247,15,185,244,244,126,20,76,168,182,23,49,172,31,244,35,37,78,246, -101,216,17,82,121,34,34,239,180,95,237,170,182,8,148,215,224,42,148,12,214,235,32,16,178,230,243,40,18,196,121,89,15,101,203,109,73,222,244,133,219,147,188,67,84,119,47,236,5,126,200,155,155,243,11,86,24,150,91,66,237,83,185,94,40,155,99,152,23,6,12, -27,78,177,254,129,127,228,110,32,148,59,61,169,98,224,62,3,72,190,51,83,75,185,162,7,19,59,221,97,40,204,73,100,48,15,194,174,108,136,87,158,30,79,230,2,42,105,41,22,50,88,164,26,115,100,49,44,182,149,234,148,58,250,200,239,34,33,13,60,176,80,130,75, -119,240,7,184,224,106,100,199,64,217,194,67,60,210,29,30,27,120,194,176,251,127,195,101,200,253,86,57,1,172,206,156,0,67,118,64,244,121,208,114,135,125,24,210,250,158,134,221,250,12,91,78,125,44,69,73,47,104,85,138,127,135,24,158,77,73,252,71,106,118, -50,70,34,84,88,107,115,89,149,146,147,136,132,83,60,170,49,228,167,180,56,170,233,235,94,153,113,76,172,209,95,102,65,127,113,196,244,173,210,35,90,162,157,75,150,94,20,22,182,207,16,251,76,78,12,89,90,147,131,32,199,101,90,173,97,2,108,92,35,155,64, -14,249,17,185,74,81,141,229,191,33,254,222,78,156,99,193,78,218,198,57,82,95,112,233,12,230,167,137,114,98,172,92,126,88,142,192,12,110,140,202,61,39,27,27,105,97,211,181,228,134,9,35,45,218,91,193,205,1,109,117,144,127,11,87,201,218,228,165,81,196,21, -152,184,78,22,217,212,47,80,75,3,4,10,0,0,8,8,0,22,178,149,71,231,236,88,115,170,0,0,0,219,0,0,0,34,0,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,73,68,111,119,110,108,111,97,100,46,99,108,97,115,115,69,141,193,10,194,48, -12,134,255,204,233,230,20,17,188,10,94,245,98,241,188,171,10,3,65,80,244,94,183,50,54,74,59,234,116,62,155,7,31,192,135,18,59,149,25,8,201,151,252,249,243,124,221,31,0,22,232,123,232,122,8,8,126,162,43,37,53,79,8,147,233,38,231,87,206,148,40,217,97,23, -133,95,202,52,91,103,82,132,179,35,33,88,221,98,81,148,153,86,103,15,61,203,123,125,49,177,168,247,132,65,180,252,89,205,235,67,194,88,155,148,165,134,39,82,176,202,240,162,16,134,53,26,194,240,99,47,185,74,217,246,148,139,184,36,140,254,163,230,83,135, -64,112,80,7,185,132,22,92,203,109,75,117,237,216,244,108,239,192,127,3,80,75,3,4,10,0,0,8,8,0,22,178,149,71,4,169,122,221,92,2,0,0,81,4,0,0,45,0,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,71,114,97,100,108,101,85,115,101, -114,72,111,109,101,76,111,111,107,117,112,46,99,108,97,115,115,141,83,91,79,26,65,20,254,70,145,93,214,245,82,172,40,181,182,106,91,4,91,217,90,237,85,211,196,203,170,137,84,8,32,9,79,100,133,9,174,46,187,100,89,108,252,87,189,36,106,106,210,199,62,244, -71,53,61,195,82,43,200,131,187,201,185,205,119,190,115,230,204,204,239,63,63,126,2,88,194,170,130,81,204,201,120,162,224,41,158,73,136,41,8,96,94,70,92,248,137,16,70,176,32,225,185,130,144,0,189,16,122,81,70,82,104,77,194,75,9,75,12,147,91,250,246,250, -65,42,95,218,201,174,111,165,244,210,65,78,207,150,118,211,159,116,134,112,234,216,56,53,52,203,176,171,90,206,115,77,187,186,202,48,221,141,43,101,178,233,140,158,205,23,75,123,122,145,97,104,211,177,27,158,97,123,5,195,106,114,226,191,133,215,247,11, -62,52,184,102,218,166,247,145,161,63,158,40,48,4,54,157,10,37,140,164,76,155,239,55,107,135,220,205,27,135,22,23,125,56,101,195,42,24,174,41,252,118,48,224,29,153,13,134,68,202,113,171,90,213,53,42,22,215,62,187,70,189,206,93,109,167,229,30,52,184,187, -235,212,120,202,113,78,154,117,106,125,184,218,17,103,24,141,39,252,45,154,142,182,109,90,156,48,242,90,217,106,119,165,228,156,166,91,230,98,129,33,218,139,51,41,146,85,68,48,65,92,62,121,178,73,136,228,17,65,36,188,82,177,140,21,6,245,102,13,1,127, -77,240,238,177,168,120,131,21,21,247,16,102,152,232,158,251,70,211,180,42,220,101,8,93,211,171,120,139,119,212,175,150,244,11,171,120,143,15,12,243,119,28,7,117,240,191,72,250,240,152,151,189,142,80,238,172,225,241,26,195,96,149,123,25,215,33,26,239, -140,33,22,191,125,37,18,189,110,201,120,47,32,157,113,144,232,184,125,74,134,104,205,174,48,44,222,137,178,61,0,113,64,158,227,135,24,238,199,123,212,198,44,221,250,81,122,29,253,136,138,105,146,21,197,24,105,194,147,221,71,127,20,227,55,252,32,33,153, -56,67,146,147,20,209,72,51,210,3,11,23,96,95,91,144,40,201,96,43,56,142,7,36,85,31,128,41,60,36,29,194,52,30,181,147,79,90,100,244,52,195,125,151,232,47,238,253,130,122,133,64,145,168,6,190,132,131,151,144,58,67,194,248,6,89,152,215,133,34,68,12,34,86, -136,118,12,143,73,206,32,134,185,235,194,18,22,40,38,246,37,211,234,191,174,151,41,91,124,83,87,8,21,47,160,132,7,169,254,57,212,240,16,137,115,12,127,135,44,246,194,110,236,37,66,114,166,85,118,246,47,80,75,3,4,10,0,0,8,8,0,22,178,149,71,28,226,93,219, -197,5,0,0,250,10,0,0,51,0,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,69,120,99,108,117,115,105,118,101,70,105,108,101,65,99,99,101,115,115,77,97,110,97,103,101,114,46,99,108,97,115,115,149,86,75,112,19,101,28,255,109,154, -38,105,186,109,33,64,33,80,108,0,133,180,80,130,40,22,211,130,150,216,98,104,90,160,13,165,5,21,183,201,54,93,186,221,141,155,77,75,125,32,62,234,251,117,240,232,157,163,50,35,45,88,7,198,25,71,71,199,131,58,227,129,241,194,197,25,47,158,24,47,30,196, -223,183,155,150,190,29,14,249,30,255,231,239,255,250,54,63,254,251,213,13,0,15,227,147,32,182,161,179,2,17,164,196,210,229,71,119,16,94,28,247,227,68,16,62,116,138,203,73,113,234,9,160,87,236,105,65,57,37,150,190,32,78,163,223,143,129,0,206,4,81,35,136, -53,56,27,196,51,120,54,72,83,207,5,113,14,207,251,161,4,48,40,20,51,1,100,133,154,26,68,45,134,42,145,195,112,16,26,206,87,98,4,186,31,163,126,24,126,152,18,214,164,142,39,58,207,117,36,83,237,231,122,79,117,116,36,251,37,132,82,231,149,49,37,166,43, -70,46,214,107,91,154,145,107,145,80,149,48,141,130,173,24,118,159,162,23,85,9,21,182,54,170,154,69,187,171,32,65,74,74,168,206,155,186,158,52,108,213,26,83,116,65,244,181,106,134,102,31,150,80,30,77,38,27,250,36,120,19,102,150,138,53,41,205,80,187,139, -163,131,170,149,86,6,117,85,248,51,51,138,222,167,88,154,184,151,136,94,123,88,163,149,88,202,180,114,177,156,165,100,117,53,54,110,41,249,188,106,197,218,47,100,244,98,65,27,83,59,52,93,109,203,100,212,66,161,75,49,148,156,106,17,168,79,113,8,18,218, -162,110,28,154,25,19,114,45,238,173,104,107,122,44,99,26,153,162,101,169,134,29,75,40,186,46,60,182,52,204,139,250,248,224,121,53,99,211,152,159,33,91,118,155,205,24,143,17,147,110,102,70,36,212,185,146,6,13,103,134,21,195,80,245,130,227,129,97,140,136, -76,169,243,225,49,51,11,97,136,208,148,2,205,212,255,15,32,9,1,225,207,53,178,198,82,140,172,57,234,6,235,146,54,207,217,237,89,196,19,192,75,200,230,220,44,65,155,112,47,148,173,93,152,255,137,252,108,13,30,92,29,97,107,58,221,114,152,250,65,214,67, -205,219,26,27,132,125,209,171,229,12,197,46,90,212,239,106,77,199,151,102,245,240,125,213,197,117,210,192,85,194,218,81,101,98,80,77,232,102,65,61,89,212,84,91,159,32,248,123,214,28,134,91,75,182,155,143,56,76,129,98,195,60,8,115,72,105,173,34,51,43, -47,97,221,50,70,24,88,175,89,180,50,165,50,214,175,220,117,123,133,178,140,40,242,50,30,194,78,25,187,176,83,130,60,63,74,25,47,192,146,176,113,241,100,29,41,106,122,86,181,100,20,96,203,40,98,140,237,177,87,207,140,200,24,23,132,40,46,200,152,192,139, -126,188,36,227,101,188,34,97,211,74,69,151,224,177,198,101,92,196,171,126,92,146,241,26,94,151,145,192,83,126,188,33,227,77,76,178,95,238,249,238,41,26,98,124,231,178,33,161,50,237,142,115,196,28,138,8,28,111,113,244,34,150,170,100,134,213,108,100,92, -209,108,98,141,12,153,86,100,174,185,35,238,156,69,108,51,50,68,247,113,170,189,237,66,126,199,143,119,101,188,135,247,253,248,64,198,135,200,251,241,145,140,143,145,103,158,151,41,133,132,166,251,154,113,14,195,226,158,146,80,22,21,53,175,202,169,246, -9,69,244,79,105,106,162,13,139,135,207,79,145,110,101,148,204,245,209,134,229,30,58,159,240,111,100,137,42,186,148,189,84,163,84,64,49,173,182,233,146,36,236,88,182,197,23,24,18,29,58,58,146,213,172,130,3,254,204,130,168,122,39,10,182,58,202,134,47,77, -131,40,78,151,166,235,154,43,204,167,40,200,48,18,179,35,190,109,54,146,85,134,124,235,170,2,204,139,109,77,164,156,231,237,129,21,173,149,30,184,121,64,211,195,236,17,230,170,188,160,171,42,235,235,141,30,19,145,213,69,147,171,101,170,134,224,219,6, -11,166,94,180,213,19,138,61,204,25,93,46,215,125,179,168,87,122,27,232,143,15,151,190,184,148,115,175,247,230,149,195,96,192,150,170,171,74,129,70,214,46,153,125,6,228,60,14,252,88,71,248,3,202,16,198,118,236,0,223,68,222,60,8,34,36,38,157,231,144,24, -118,71,66,98,235,55,112,109,228,109,128,50,101,220,107,26,167,33,53,110,185,10,79,99,221,85,148,93,113,148,119,59,106,94,174,219,184,110,71,5,13,87,211,240,30,82,34,174,26,154,176,23,112,78,194,141,228,156,132,35,15,207,49,236,163,20,221,120,234,248, -161,151,1,201,51,3,239,192,238,41,148,207,192,55,48,13,63,143,129,41,84,132,130,92,166,80,57,13,185,187,137,220,41,84,157,150,226,94,41,94,126,13,213,205,62,41,30,8,7,190,71,7,47,181,190,198,47,225,153,84,62,253,12,205,51,168,25,104,10,173,153,198,218, -184,55,236,157,66,40,94,30,166,234,58,71,250,238,207,97,42,175,15,123,185,80,165,108,242,26,54,92,190,59,35,236,52,205,160,118,160,4,32,180,145,158,133,201,41,108,10,133,121,38,162,205,179,96,182,220,220,115,29,117,18,226,21,97,162,220,234,24,36,38,199, -38,225,221,115,16,174,248,34,30,92,94,38,120,51,94,57,79,176,242,38,51,249,57,166,113,139,153,186,133,223,157,125,31,126,194,29,231,254,183,179,151,57,153,191,136,122,174,187,152,247,40,115,216,192,76,55,82,178,9,7,152,241,131,60,165,248,55,173,31,251, -249,111,234,17,12,145,58,130,199,144,71,51,223,196,131,184,132,86,76,226,16,61,181,209,87,2,95,163,29,223,160,3,223,226,40,126,192,211,244,215,137,95,104,225,22,121,183,201,251,131,188,63,201,251,139,188,59,228,253,67,158,168,114,15,2,180,124,131,158, -246,179,130,7,49,67,95,143,146,198,74,206,86,158,167,3,244,44,57,167,102,202,120,136,248,54,30,39,173,140,50,191,33,142,22,198,188,15,191,18,211,33,148,227,48,149,228,57,249,39,40,255,36,41,94,82,234,137,86,244,221,17,182,45,191,8,165,22,61,203,221,227, -180,232,119,168,106,188,142,7,36,92,134,55,117,133,100,47,5,171,168,230,182,106,45,141,3,39,73,237,37,189,143,156,52,219,181,223,9,164,150,50,213,220,219,25,168,219,164,71,25,42,49,32,233,184,60,246,31,80,75,3,4,10,0,0,8,8,0,22,178,149,71,204,13,94,70, -145,2,0,0,249,6,0,0,45,0,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,87,114,97,112,112,101,114,67,111,110,102,105,103,117,114,97,116,105,111,110,46,99,108,97,115,115,141,147,109,79,19,65,16,199,255,219,231,214,131,62,130, -128,162,162,34,237,33,156,160,224,51,9,15,85,49,85,12,21,72,124,67,174,112,150,35,229,142,220,93,53,241,83,105,34,49,241,133,31,192,15,101,156,189,91,160,172,219,196,55,51,179,51,243,159,253,237,92,251,251,207,207,95,0,230,240,40,135,75,152,201,96,54, -139,28,140,12,238,113,63,199,205,60,55,247,185,121,192,205,66,26,139,105,60,100,208,246,109,63,240,236,86,55,176,93,135,97,176,113,104,126,50,13,199,10,140,173,205,245,167,12,133,222,250,138,233,91,12,165,168,167,99,58,109,163,73,53,167,45,247,189,51, -131,3,134,161,222,84,243,192,156,95,88,108,118,143,24,210,95,236,227,104,18,143,162,222,212,51,219,177,131,37,134,120,181,182,205,144,88,117,247,169,158,111,216,142,245,182,123,212,178,188,247,102,171,19,222,237,238,153,157,109,211,179,249,89,36,19,193, -129,237,51,212,26,174,215,54,218,158,185,223,177,140,207,158,121,124,108,121,198,78,228,87,93,231,163,221,238,122,38,103,33,220,124,219,10,214,46,188,188,80,173,201,111,207,251,114,83,177,122,177,135,179,150,165,81,209,211,42,167,227,46,174,169,236,171, -154,135,170,255,246,170,70,71,187,146,103,68,217,17,169,183,103,225,35,126,223,82,142,84,31,78,63,71,206,239,61,68,149,104,184,168,136,67,211,237,122,123,214,11,155,239,126,84,181,224,89,254,26,13,21,12,209,94,95,110,46,175,53,234,187,91,205,250,230, -238,171,141,55,117,13,131,200,51,12,156,126,33,254,43,241,53,20,144,215,80,226,166,204,141,134,1,13,69,222,56,245,159,95,149,174,58,95,226,70,235,208,218,11,48,1,254,135,0,82,136,241,137,20,197,248,237,161,47,8,95,20,190,36,124,57,244,3,96,156,159,236, -48,157,118,40,207,200,143,235,63,192,244,82,236,4,113,189,148,56,65,50,140,83,97,156,254,22,202,47,147,29,70,146,108,5,9,138,114,148,41,96,148,162,49,140,80,86,139,6,81,102,140,60,195,21,92,21,151,24,228,121,45,169,127,71,230,235,217,176,148,16,156,139, -147,103,226,113,92,19,226,37,234,142,241,110,125,250,4,153,115,148,92,152,157,32,205,205,112,194,112,212,37,38,240,72,11,223,202,112,29,55,20,32,113,25,100,82,9,50,65,227,21,32,113,25,164,70,26,189,15,8,255,48,252,226,91,74,144,164,12,50,163,4,185,173, -6,73,202,32,115,164,153,239,3,82,16,32,147,74,144,172,12,178,160,4,185,163,6,201,202,32,143,73,243,164,15,72,81,128,76,41,65,82,50,200,115,37,72,85,13,146,146,65,150,73,179,210,7,164,36,64,106,74,144,180,12,82,87,130,232,106,144,180,12,178,78,154,215, -125,64,202,2,100,58,212,220,253,11,80,75,3,4,10,0,0,8,8,0,22,178,149,71,81,125,29,105,229,4,0,0,25,10,0,0,48,0,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,83,121,115,116,101,109,80,114,111,112,101,114,116,105,101,115,72, -97,110,100,108,101,114,46,99,108,97,115,115,141,86,235,115,19,85,20,255,109,155,100,195,118,203,163,80,74,74,133,8,2,105,250,136,128,21,108,10,42,208,74,165,15,36,80,44,130,186,77,111,147,133,100,55,108,54,180,21,21,159,248,70,253,194,12,142,195,87,62, -57,131,195,24,192,206,200,119,255,40,245,119,55,161,205,139,218,102,122,238,189,231,117,207,249,157,115,207,236,223,255,252,249,23,128,253,248,89,195,46,140,168,120,67,67,19,70,52,156,196,168,138,55,53,248,37,243,148,6,21,99,242,48,46,119,19,42,38,85, -156,86,241,150,134,86,140,4,113,70,174,9,73,206,74,114,78,131,142,169,32,206,107,120,27,211,210,236,66,11,222,193,197,22,92,194,187,146,188,39,47,59,39,165,239,107,48,48,35,73,82,195,44,132,84,158,107,65,10,105,21,166,138,203,10,2,67,166,101,186,71,21, -52,71,186,167,20,248,142,219,179,66,193,134,49,211,18,19,133,236,140,112,206,26,51,25,114,218,198,236,164,145,153,50,28,83,158,203,76,159,155,54,243,10,122,199,108,39,21,75,57,198,108,70,196,230,29,35,151,19,78,44,177,152,119,69,246,180,99,243,224,154, -34,127,210,176,40,118,226,10,54,167,132,91,43,85,176,51,50,118,217,184,102,196,76,59,54,98,102,68,188,187,116,44,184,102,38,54,110,228,104,23,52,173,132,235,8,35,171,32,84,165,59,106,229,10,110,73,68,53,133,129,181,47,203,71,39,135,23,146,34,231,154, -182,69,89,243,21,177,40,115,241,164,25,195,74,197,104,102,90,41,138,212,172,225,38,211,194,89,118,238,221,236,136,148,88,224,253,158,72,198,96,56,169,66,86,88,110,181,151,201,153,203,34,233,82,222,100,190,160,96,75,133,131,81,87,56,134,107,75,219,245, -185,229,116,101,212,100,84,103,172,160,165,172,177,200,132,101,17,106,17,208,114,21,128,109,173,16,175,0,41,51,201,25,46,111,181,26,101,114,186,36,138,75,243,170,130,46,230,158,22,117,160,250,218,161,122,176,234,57,71,233,112,93,194,76,89,134,91,112, -232,99,120,245,98,174,217,167,150,176,11,78,82,148,224,234,122,70,75,245,75,83,29,187,65,232,55,173,220,115,210,200,167,121,151,138,43,58,50,96,211,108,105,132,151,130,142,103,180,146,244,104,233,176,145,211,113,85,250,222,220,160,167,20,116,174,4,126, -166,96,185,102,86,84,8,59,106,179,58,86,48,51,179,178,201,118,15,59,142,237,132,231,211,194,10,103,108,99,150,178,240,74,117,195,115,140,229,136,14,7,121,73,92,29,5,92,147,1,205,43,216,152,95,134,225,98,127,164,63,218,173,98,65,199,34,62,208,113,29,31, -170,248,72,199,199,184,161,226,19,29,159,130,89,124,134,207,117,28,192,23,42,190,212,113,83,114,190,194,215,42,190,209,241,45,190,211,241,61,126,80,113,75,199,143,248,73,65,116,237,15,153,129,212,246,191,2,189,18,75,14,23,179,220,233,28,46,23,88,156, -218,174,144,3,71,38,175,96,219,138,168,242,53,75,13,127,50,99,231,165,51,25,142,69,221,190,72,125,179,116,215,177,202,72,199,107,244,203,47,117,53,253,160,107,151,88,108,153,72,189,34,53,162,13,34,168,224,156,77,59,246,188,124,76,94,252,29,207,120,131, -124,168,73,59,155,243,240,89,37,165,134,143,55,192,57,150,16,174,132,180,82,141,44,10,91,171,24,114,110,150,103,16,31,125,149,122,197,108,106,171,231,50,190,180,145,159,16,11,116,225,179,188,165,26,142,229,161,119,176,50,250,227,105,195,73,136,171,5, -97,37,69,131,28,86,70,105,29,46,227,79,7,176,111,206,148,117,246,167,28,187,192,57,216,30,25,109,88,133,141,181,60,226,146,17,86,202,77,123,13,55,74,154,146,249,239,253,159,250,47,231,81,1,156,55,128,155,217,136,10,14,55,48,95,147,67,60,207,223,46,200, -191,38,40,114,62,145,238,225,41,198,85,225,234,143,62,132,242,187,39,222,75,26,240,152,219,177,143,84,47,41,32,130,110,174,235,16,69,15,181,104,172,60,128,15,65,242,254,88,66,211,244,67,52,143,69,139,240,253,2,127,207,253,37,248,201,8,140,47,65,157,166, -231,224,68,111,95,17,235,248,175,221,131,62,232,147,155,144,239,201,61,132,39,150,160,79,47,161,149,218,235,219,54,20,177,145,46,54,21,209,214,247,16,155,159,180,109,121,132,246,137,222,34,182,62,70,135,130,65,95,200,247,24,219,20,220,193,9,185,11,145, -229,239,11,249,139,232,44,98,251,96,32,20,40,162,235,14,246,132,2,190,34,158,27,84,67,106,17,59,238,162,189,39,164,246,74,173,157,84,124,140,112,51,206,223,251,247,81,207,125,52,19,145,125,232,103,2,253,120,209,91,67,56,132,65,180,80,34,65,152,66,59, -233,14,166,184,19,27,16,198,38,234,135,136,220,46,74,247,17,142,30,2,210,207,245,16,122,105,21,69,156,156,243,228,92,34,170,215,233,241,38,63,182,110,113,220,221,198,65,220,197,75,184,79,205,7,56,236,129,58,7,249,97,212,78,203,62,222,22,71,23,237,98, -220,221,70,39,45,247,243,211,235,38,61,30,160,101,128,190,6,104,61,192,18,164,113,10,47,211,139,79,130,78,79,175,112,13,226,55,222,30,103,145,66,248,21,67,56,194,226,92,226,247,214,81,188,74,127,175,149,11,88,210,122,157,187,99,94,145,143,115,119,194, -219,13,255,7,80,75,3,4,10,0,0,8,8,0,22,178,149,71,165,121,48,186,86,2,0,0,0,5,0,0,31,0,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,76,111,103,103,101,114,46,99,108,97,115,115,133,147,251,111,210,80,20,199,191,151,199,42, -175,49,198,112,76,152,19,157,10,69,87,134,111,49,38,134,100,9,17,31,9,102,38,251,173,148,155,174,75,105,161,20,141,255,138,127,133,26,197,196,31,252,3,252,163,140,231,182,13,18,88,179,144,158,158,115,239,57,159,243,42,127,254,254,250,13,224,16,79,147, -72,224,102,2,151,112,43,129,219,168,38,81,131,44,68,93,136,59,66,220,149,112,32,65,145,208,96,136,143,167,6,119,25,216,9,195,218,51,195,50,220,231,12,177,234,73,237,152,94,109,123,192,25,178,93,195,226,175,167,195,62,119,222,169,125,147,78,54,187,182, -166,154,199,170,99,8,59,56,140,185,167,198,132,161,212,181,29,93,209,29,117,96,114,229,163,163,142,70,220,81,186,182,174,115,167,197,16,53,109,157,161,80,237,158,169,31,84,197,84,45,93,233,185,142,97,233,45,145,80,26,242,201,68,213,189,12,43,14,84,159, -128,89,3,134,198,98,124,251,84,117,122,124,60,229,150,198,91,181,133,139,23,158,183,40,78,36,214,38,99,134,98,88,28,67,51,148,217,233,132,82,227,19,87,117,196,244,58,148,193,43,109,167,218,14,245,102,26,61,109,134,100,207,158,58,26,63,50,196,216,82,254, -108,14,68,76,26,25,28,166,145,66,90,66,51,141,123,184,47,225,65,26,15,81,72,163,136,71,66,60,22,226,9,229,9,157,50,195,198,255,252,111,250,103,92,163,2,183,206,43,137,106,174,138,177,47,248,247,62,77,92,62,164,11,123,74,81,5,191,19,195,86,222,210,10, -92,90,4,87,135,212,72,254,156,99,218,222,72,88,166,197,160,92,180,159,21,226,225,197,211,95,137,41,206,71,189,116,133,10,125,253,9,208,160,233,217,20,227,164,127,70,156,244,12,214,73,102,201,58,66,132,126,64,82,254,9,38,151,126,32,242,149,172,8,54,72, -174,35,74,242,50,98,216,38,74,17,57,207,242,188,137,150,7,60,77,80,105,157,216,66,33,96,190,12,152,89,249,59,34,159,145,252,134,104,125,134,216,50,184,4,9,101,210,175,46,128,179,115,112,150,78,182,61,112,17,59,1,248,85,0,206,249,224,148,15,142,191,151, -191,44,161,43,132,190,78,33,251,11,232,220,28,157,195,21,74,238,163,203,1,90,163,46,99,244,206,251,232,140,64,151,119,103,88,91,133,87,9,94,35,72,221,131,203,126,216,28,158,15,224,66,219,165,222,34,158,182,71,90,212,75,120,45,188,151,210,12,210,106,58, -133,210,53,40,164,25,210,75,133,58,21,189,220,240,226,246,255,1,80,75,3,4,10,0,0,8,8,0,22,178,149,71,206,114,235,138,21,7,0,0,110,14,0,0,38,0,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,80,97,116,104,65,115,115,101,109, -98,108,101,114,46,99,108,97,115,115,149,86,249,99,27,87,17,254,214,214,21,121,147,56,138,115,216,181,131,98,39,141,44,217,22,73,83,40,73,19,240,213,68,173,175,250,42,78,218,184,107,107,35,111,42,239,186,187,171,196,134,114,19,40,247,125,4,2,148,251,6, -23,90,41,196,180,1,126,228,143,2,190,217,93,91,182,42,211,246,7,189,55,239,105,222,204,55,51,223,155,183,255,254,207,253,55,1,156,198,191,226,56,138,194,30,156,197,82,28,6,110,196,41,189,32,67,81,134,229,40,76,217,182,100,177,18,197,139,113,196,81,144, -29,91,36,39,6,87,230,82,28,81,220,148,237,91,50,172,70,177,22,199,65,124,36,142,143,202,127,103,241,82,12,31,139,226,227,113,124,2,159,140,225,83,113,124,26,159,145,197,103,69,186,29,197,231,100,254,124,28,199,240,178,12,95,136,226,139,81,124,41,134, -47,199,209,133,175,196,240,85,81,254,154,12,95,23,155,223,16,233,155,49,124,75,230,111,199,240,157,24,190,27,199,247,240,125,193,113,39,134,31,196,240,67,57,121,39,138,187,10,14,140,88,139,90,113,200,112,92,219,88,40,185,134,101,42,80,115,166,169,219, -131,69,205,113,116,71,193,145,75,147,253,67,35,195,243,51,83,195,147,243,151,199,71,135,231,167,166,39,115,99,151,20,36,70,110,104,55,181,108,81,51,11,217,41,26,48,11,231,21,236,29,180,76,199,213,76,119,86,43,150,116,5,251,38,38,199,159,28,30,156,222, -58,181,175,96,107,249,162,62,227,232,246,101,107,89,52,124,51,134,149,125,194,40,234,52,17,121,220,48,13,247,162,130,198,84,247,172,130,208,160,149,167,218,254,17,195,212,199,74,203,11,186,61,173,45,20,117,241,47,224,103,53,219,144,117,176,25,114,151, -12,162,238,28,177,236,66,214,119,149,189,101,107,43,43,186,157,157,208,220,165,126,70,181,76,77,155,142,14,164,118,186,22,111,251,11,186,187,51,31,243,169,122,182,158,241,103,70,123,221,40,148,108,77,116,207,119,191,173,215,19,111,73,184,228,108,113, -187,21,5,117,205,212,117,168,32,182,160,57,250,152,38,137,140,229,105,214,23,155,108,203,98,24,182,191,138,202,31,92,5,210,21,99,69,193,120,234,173,213,123,23,113,214,169,124,180,100,23,47,107,206,18,37,230,208,151,30,174,227,165,238,225,189,203,186, -227,104,5,125,200,40,232,142,171,160,195,87,114,244,197,146,109,184,107,217,209,237,127,83,63,188,176,230,10,59,27,174,14,40,80,24,227,161,109,86,135,87,23,245,149,32,63,17,199,115,193,194,218,250,178,117,83,31,94,117,117,211,241,210,28,50,189,236,40, -204,134,146,99,206,130,202,251,57,235,12,144,155,186,155,157,153,204,237,18,178,164,115,198,46,110,145,120,83,155,198,87,88,118,5,113,26,29,96,133,188,236,119,238,158,141,42,251,67,82,80,30,156,178,74,246,162,46,155,100,250,14,14,245,201,9,21,23,112, -81,197,121,60,30,197,143,84,12,227,199,42,158,195,53,21,115,120,90,197,83,24,227,69,222,110,89,197,79,240,138,138,5,44,242,74,215,162,24,40,25,197,188,110,171,248,169,232,252,12,63,103,70,178,42,126,33,171,11,248,165,138,95,137,244,107,188,162,224,204, -187,103,184,216,248,77,20,191,85,49,129,167,89,186,147,78,246,36,75,215,92,69,49,190,112,67,95,116,163,248,157,138,223,227,15,188,248,163,67,143,70,241,71,21,127,194,159,85,172,227,85,21,127,193,95,21,180,120,71,150,233,46,59,96,20,114,166,171,23,4,245, -107,162,112,1,175,11,226,178,130,131,117,152,160,160,173,186,59,89,50,93,99,89,223,246,103,251,160,85,42,230,147,166,229,38,151,72,220,164,97,174,148,220,164,79,157,62,177,93,97,70,40,220,195,223,84,220,199,134,138,191,75,70,238,139,187,230,218,6,169, -226,13,188,73,114,4,157,143,23,179,196,102,215,151,55,236,40,30,168,248,135,20,232,2,254,73,110,10,51,206,37,73,189,164,225,36,75,230,11,166,117,139,96,146,111,151,98,5,167,222,225,77,37,186,84,119,45,53,15,214,180,184,1,143,112,45,169,186,20,175,85, -158,240,104,29,17,87,102,94,65,239,59,186,224,1,191,164,93,185,214,84,112,33,187,106,186,111,29,67,179,254,5,98,195,242,49,6,11,31,67,127,221,190,188,179,199,215,243,176,189,219,171,219,83,179,131,146,155,40,35,215,45,155,132,83,240,129,58,145,94,29, -169,229,112,253,62,241,208,255,105,102,126,227,201,121,143,230,34,99,60,189,123,70,119,237,134,49,233,50,126,67,12,165,186,165,37,70,74,43,121,205,165,185,112,234,234,128,68,26,201,7,222,34,169,156,191,115,40,149,171,11,54,93,239,101,168,238,76,47,217, -214,45,121,107,189,4,54,241,51,129,224,243,250,234,248,117,49,89,7,59,243,186,199,41,45,108,246,225,195,169,92,125,191,242,106,4,236,210,95,44,105,69,167,198,222,102,130,175,236,172,211,154,227,234,203,126,18,39,108,139,20,112,215,118,1,50,139,227,252, -222,58,202,111,187,70,180,226,253,120,12,172,42,87,13,200,112,125,110,219,186,151,63,118,86,202,49,238,177,209,114,252,32,87,143,112,86,56,135,211,21,40,175,122,170,31,226,24,231,12,116,32,196,239,179,126,74,170,175,132,1,12,114,22,3,67,129,129,39,168, -41,186,113,49,144,206,188,142,134,170,149,125,132,5,36,105,229,56,246,160,211,179,116,216,215,14,44,137,36,176,4,196,48,109,249,54,255,75,79,81,206,183,211,153,50,26,43,8,141,166,123,42,8,143,165,123,51,21,68,206,133,54,16,157,147,191,98,21,236,217,64, -124,174,130,38,174,212,50,246,38,246,113,104,13,113,40,99,127,5,205,231,194,155,186,7,118,232,38,118,232,122,82,79,245,80,100,3,7,231,210,173,225,214,72,5,45,235,91,225,180,33,194,49,197,80,186,177,31,105,28,97,150,7,209,131,85,102,87,66,187,236,131, -222,10,237,54,46,113,143,92,193,75,200,177,22,13,60,117,19,79,82,106,228,89,147,79,218,99,76,205,32,245,71,152,130,48,237,236,197,40,165,8,53,249,220,5,201,184,193,127,66,156,143,165,137,176,177,140,67,21,28,30,75,28,9,191,129,163,115,141,153,169,185, -80,239,212,61,180,174,215,148,238,52,75,118,198,67,149,246,79,111,161,58,230,33,80,60,73,240,53,80,51,129,113,15,85,131,188,103,129,223,187,60,39,39,251,18,109,247,240,208,40,147,214,62,214,211,91,70,199,6,142,205,133,136,229,61,21,36,155,79,148,113, -124,125,116,3,93,115,137,19,172,209,201,7,158,229,227,44,118,231,142,172,245,115,28,64,19,49,52,147,58,157,44,118,23,203,45,248,206,50,190,8,218,49,137,41,158,104,98,102,166,49,67,44,93,148,103,241,140,23,77,223,22,250,62,124,216,67,223,32,95,5,1,210, -107,212,22,162,181,100,18,15,151,113,234,66,251,93,132,51,235,153,198,246,50,82,213,188,36,188,104,158,98,141,70,104,121,148,185,30,247,252,39,253,179,91,30,90,112,197,243,16,165,198,85,60,235,209,155,159,33,129,47,155,218,98,167,141,249,232,30,237,17, -230,156,186,216,65,135,61,235,61,29,161,231,203,72,87,61,30,102,100,96,84,97,70,164,50,166,102,198,147,32,254,106,85,218,182,188,182,97,30,207,211,71,24,135,160,121,92,81,121,125,196,191,84,133,223,56,129,255,151,121,78,50,50,148,73,16,65,207,29,196, -210,175,161,97,61,147,232,245,86,205,66,247,68,223,61,100,43,120,239,186,148,37,224,124,226,52,233,157,17,174,159,217,228,249,35,15,106,144,62,75,166,62,71,175,215,88,131,121,156,32,142,234,133,29,218,66,58,132,124,80,1,221,59,127,29,239,243,88,199,135, -149,181,124,20,202,255,0,80,75,3,4,10,0,0,8,8,0,22,178,149,71,56,222,182,221,27,19,0,0,236,41,0,0,32,0,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,73,110,115,116,97,108,108,46,99,108,97,115,115,157,89,11,124,20,229,181, -63,39,187,217,217,44,195,43,16,194,202,107,68,34,121,135,55,26,16,13,73,144,216,16,144,240,48,32,234,100,119,146,140,236,35,238,206,146,68,173,90,139,74,213,190,80,91,209,86,172,143,98,45,85,81,73,208,40,216,106,125,182,246,161,181,181,181,213,86,107, -111,235,237,189,189,247,246,222,219,251,42,247,127,102,118,55,155,100,16,226,47,191,253,102,230,123,156,231,255,156,239,124,95,94,253,251,211,71,137,104,33,127,16,160,62,206,151,198,39,141,34,141,95,154,130,2,52,1,105,198,201,167,26,160,50,30,175,240, -4,15,241,155,207,5,40,192,19,101,108,146,52,147,3,92,200,83,164,153,26,224,34,158,22,160,59,184,88,154,233,10,7,3,52,149,103,200,252,153,10,207,242,243,236,0,207,97,77,225,211,3,116,26,207,13,240,25,60,79,122,74,164,57,83,225,249,1,154,195,227,3,92,202, -101,1,170,227,114,249,172,144,166,82,154,170,113,92,205,53,10,47,240,243,66,133,23,201,140,197,1,154,207,75,164,127,169,159,151,201,115,185,136,123,150,140,157,29,160,98,174,245,243,10,121,174,44,224,115,120,85,128,207,229,243,2,120,171,83,120,117,128, -150,131,23,198,234,165,105,144,166,81,40,172,17,10,231,251,121,173,244,52,41,124,129,194,159,242,115,179,159,215,73,71,75,128,206,227,245,210,108,8,240,133,188,81,225,214,0,173,229,241,126,222,36,207,205,210,84,5,120,11,111,85,248,34,133,219,100,210, -182,0,173,231,237,1,106,225,139,21,222,17,160,86,225,219,194,151,248,249,82,249,184,76,154,42,133,245,0,181,113,187,194,161,0,109,231,118,63,135,253,108,248,185,67,228,237,44,224,46,54,69,171,203,253,188,83,158,17,17,38,170,112,44,64,29,176,36,154,248, -56,238,230,43,164,73,40,156,12,208,78,110,148,198,146,137,41,133,119,41,220,19,160,110,153,27,231,94,89,208,39,138,94,25,224,171,248,106,249,188,90,222,62,45,62,185,90,225,107,152,130,13,141,107,234,54,55,111,186,180,161,169,117,211,198,166,213,155,55, -53,173,111,185,116,67,221,166,181,76,133,205,151,235,187,244,154,136,30,235,172,105,181,18,102,172,115,5,211,248,250,120,44,105,233,49,107,139,30,73,65,242,107,153,124,145,120,103,167,145,96,154,209,28,79,116,214,116,38,244,112,196,168,233,73,232,221, -221,70,162,166,217,30,196,74,127,56,222,19,139,196,245,48,211,108,183,137,77,13,233,113,225,210,173,91,93,117,201,164,17,109,143,8,229,185,110,11,54,228,206,193,162,211,140,222,80,36,149,52,119,25,107,204,136,81,23,10,25,201,228,58,61,166,219,178,213, -184,81,104,60,225,2,144,243,173,52,99,166,181,138,233,146,210,143,209,235,227,53,57,185,216,101,91,152,188,245,241,176,193,52,177,217,140,25,45,169,104,187,145,216,164,99,80,60,16,15,233,145,45,122,194,148,239,116,167,215,234,50,147,76,51,93,57,139,111, -34,17,72,31,8,37,12,221,50,26,204,164,197,116,182,171,6,91,157,39,28,218,97,118,166,18,186,101,198,99,43,202,28,167,155,241,26,177,137,184,34,148,59,206,84,118,202,164,160,81,24,236,19,102,123,74,190,55,39,34,76,19,28,242,49,195,170,217,188,177,9,83, -138,114,167,180,118,233,139,150,46,107,77,69,153,38,71,68,245,134,156,65,133,175,67,119,243,200,110,38,181,41,22,3,239,136,14,163,194,48,75,78,106,244,121,163,136,64,16,69,4,105,48,19,89,25,135,76,160,218,178,108,51,187,229,27,166,5,108,140,110,89,150, -84,248,51,240,18,6,67,169,8,172,157,35,255,220,210,225,84,202,220,130,201,211,101,244,50,177,137,95,19,28,219,97,147,207,139,34,66,102,57,211,147,70,40,149,48,173,190,154,117,128,38,112,217,96,118,26,73,75,86,118,8,6,138,178,60,154,98,221,41,11,116,13, -61,138,81,134,85,124,237,169,142,14,65,126,222,246,213,8,190,246,62,128,65,183,116,166,2,48,117,36,96,154,62,74,170,213,246,42,208,152,217,105,88,117,177,240,22,35,97,118,244,229,218,106,99,60,14,72,45,24,161,223,104,245,70,33,169,56,215,213,13,70,50, -148,48,187,29,15,122,195,102,2,234,76,114,86,96,60,82,211,108,218,122,78,27,30,1,125,221,153,40,208,70,204,93,57,156,219,42,89,187,203,145,61,29,140,245,93,70,104,103,82,124,179,180,116,180,180,39,213,6,113,170,68,29,47,192,134,122,200,74,233,17,219, -211,5,201,120,42,17,50,108,120,143,51,122,187,141,144,101,132,237,17,127,196,129,20,84,211,220,225,144,171,170,87,79,36,230,33,102,182,143,180,155,55,98,196,48,144,103,162,41,104,53,59,99,186,149,74,24,163,93,48,146,166,139,73,166,39,13,171,177,23,160, -178,196,138,27,140,68,212,76,38,5,200,136,172,145,212,182,8,203,100,22,35,232,119,176,97,132,55,26,122,216,73,145,73,43,28,79,89,89,32,218,172,215,196,19,81,221,178,236,9,222,8,82,26,232,116,183,35,61,231,24,117,67,34,46,201,118,117,202,140,56,148,176, -161,209,148,209,19,100,196,24,134,243,245,217,224,91,145,5,129,189,162,41,6,150,137,84,55,140,159,59,37,224,36,130,181,241,40,232,140,119,62,234,227,209,168,30,67,148,169,88,17,79,172,203,122,213,76,110,53,99,216,166,160,181,167,180,108,27,20,140,39, -91,116,89,89,16,54,34,134,164,211,132,139,165,48,81,73,166,236,237,3,242,226,203,31,234,130,98,9,3,208,158,178,221,53,240,195,66,40,63,21,187,210,132,226,115,92,99,41,215,17,249,70,204,74,244,101,125,97,219,25,75,107,144,147,26,101,68,146,20,28,145,205, -1,18,56,25,34,235,115,250,133,181,205,210,27,54,100,99,80,132,174,41,89,179,56,135,114,99,44,21,53,178,73,92,185,50,147,248,138,71,115,79,67,116,98,40,222,221,151,147,131,152,170,75,93,115,147,187,84,14,214,96,45,143,141,38,79,68,44,23,208,109,139,206, -91,176,96,1,83,179,235,14,150,217,238,198,156,138,242,122,23,72,179,80,154,69,67,172,22,10,43,247,205,50,195,202,117,251,203,214,56,25,66,139,132,208,202,177,19,202,173,129,50,180,22,159,156,214,73,115,75,134,214,18,161,85,53,22,90,219,134,22,47,149, -197,23,158,194,226,177,230,213,188,222,197,67,92,150,9,151,21,99,118,119,110,180,100,72,45,31,179,182,178,184,213,78,231,14,226,213,244,188,106,153,166,210,243,244,130,74,191,161,119,85,58,76,253,42,253,156,126,161,210,32,61,163,210,117,244,25,149,174, -161,107,85,122,132,30,85,233,70,190,30,140,199,84,112,202,162,207,170,180,155,110,80,233,122,250,172,194,187,85,190,129,111,84,249,38,222,163,240,231,228,227,102,149,111,225,91,85,254,60,223,138,237,249,196,74,205,3,172,73,232,125,65,229,47,242,151,160, -69,174,146,8,232,214,181,117,85,168,83,20,254,178,202,123,249,54,4,118,238,132,156,112,5,17,122,65,225,219,85,190,131,191,162,242,87,249,78,149,247,241,93,200,46,238,101,131,194,119,171,252,53,254,186,202,247,240,126,149,239,229,111,72,115,159,202,247, -139,18,15,168,252,32,253,12,27,193,208,226,141,169,152,101,70,141,108,194,102,186,236,124,91,39,45,183,86,208,230,151,36,231,107,225,184,145,212,98,113,75,67,65,106,233,102,76,211,99,125,152,150,192,126,27,151,28,86,173,53,166,55,95,205,138,107,29,72, -228,154,209,139,125,58,210,167,45,204,206,235,171,70,153,49,196,127,125,251,229,232,86,249,155,124,64,12,246,144,202,223,226,253,76,59,78,40,68,154,119,18,44,226,90,244,147,73,160,242,195,252,109,149,238,33,152,232,32,127,71,229,71,96,21,238,178,43,45, -51,100,167,93,45,222,161,185,201,208,161,195,65,225,211,75,98,37,177,54,192,212,117,78,84,239,211,186,244,93,134,214,110,24,49,205,210,163,221,178,103,107,61,166,213,85,93,18,179,75,244,68,84,179,186,116,11,141,161,205,119,45,192,231,107,221,137,56,22, -90,125,26,44,221,39,188,28,176,85,165,193,86,157,30,135,218,154,212,173,154,153,132,113,18,162,35,28,19,150,37,154,158,128,104,233,132,6,140,216,236,210,203,181,142,68,60,170,233,154,149,72,37,197,94,78,13,85,45,138,105,185,197,166,134,178,170,86,43, -73,150,196,50,153,81,147,138,80,134,156,238,172,197,67,233,242,174,214,118,20,200,104,117,118,141,54,106,64,229,71,5,141,143,169,124,136,31,87,248,9,149,159,20,199,31,230,126,236,214,67,153,179,46,145,208,251,36,125,170,60,64,63,83,249,8,63,165,242,211, -242,54,8,159,209,155,130,228,64,187,25,75,7,161,192,231,25,108,208,39,170,113,134,193,46,83,126,231,135,186,162,113,212,33,158,229,75,151,170,252,44,239,17,42,71,85,62,198,207,41,252,93,149,191,39,96,44,30,29,107,105,138,90,171,97,1,97,153,114,78,235, -30,170,231,180,142,120,162,86,147,232,123,94,225,23,84,254,62,63,148,137,218,81,133,28,83,208,101,171,118,198,84,126,145,95,18,169,94,150,230,149,97,22,202,22,122,42,191,202,123,80,83,136,63,36,150,94,203,76,27,94,176,169,252,3,153,54,251,227,107,54, -166,242,250,120,42,18,182,67,61,121,18,5,177,91,111,136,24,122,82,112,166,201,185,88,98,18,78,71,196,153,29,54,6,123,244,152,37,209,152,194,28,193,95,58,98,54,55,33,17,40,241,100,117,12,229,157,202,63,228,215,21,254,145,202,63,230,159,168,252,83,126, -3,99,61,78,37,168,242,155,12,159,191,197,63,71,25,234,90,254,168,244,33,255,66,225,183,85,254,165,160,227,87,252,78,198,210,163,202,52,149,127,13,31,243,111,4,59,51,71,58,99,253,176,250,109,122,110,74,206,29,18,63,188,43,110,121,79,165,63,209,71,10,255, -86,229,223,241,245,42,191,207,119,34,183,158,120,91,64,249,155,233,145,144,71,205,183,104,236,7,229,140,103,109,247,229,248,12,229,178,148,169,165,77,77,242,156,127,138,87,4,40,28,113,202,28,78,127,82,105,217,200,59,130,233,35,38,229,28,179,167,150,186, -30,172,181,147,105,198,116,233,88,238,68,62,209,141,66,225,8,177,237,195,67,86,189,161,98,52,128,121,217,203,133,221,159,184,242,25,110,181,83,86,206,189,36,243,233,233,227,76,157,235,217,196,70,54,246,194,80,10,25,63,102,213,212,67,56,137,208,97,215, -28,206,230,10,5,103,124,204,93,6,206,204,80,223,214,47,22,130,254,11,93,206,230,101,39,185,12,153,226,146,190,144,142,240,8,11,38,183,175,46,107,130,70,169,238,176,110,73,249,131,14,7,166,190,112,90,4,111,105,153,92,146,76,30,158,153,236,123,195,113, -86,124,237,208,125,73,81,105,147,43,222,124,56,177,116,90,93,118,28,8,47,177,179,28,48,103,148,214,143,158,159,189,98,169,60,177,174,110,211,253,86,60,35,199,132,225,21,62,148,50,147,141,209,110,11,71,68,95,135,157,150,237,115,204,40,234,219,71,187,199, -85,159,34,55,201,228,166,50,105,94,9,19,122,224,178,81,198,200,186,219,103,92,129,20,156,28,65,37,195,78,78,213,206,97,218,137,254,186,246,100,60,146,178,12,137,167,225,155,100,31,42,3,248,209,131,45,34,247,10,96,3,164,25,58,206,78,113,233,134,57,186, -229,43,34,87,75,70,175,105,123,216,241,56,190,236,212,87,32,87,51,2,104,251,230,163,108,212,157,203,56,51,217,144,41,216,32,130,30,134,51,207,56,249,149,23,88,76,130,78,245,122,44,30,67,41,23,113,148,154,86,234,114,9,96,231,75,160,62,97,91,50,215,144, -67,119,31,147,71,117,202,198,164,155,22,182,94,251,100,115,74,240,201,220,177,4,79,120,114,149,35,119,92,96,101,135,98,78,12,21,231,100,171,225,87,140,211,221,207,247,162,213,148,161,161,244,77,145,244,250,37,28,155,237,235,160,149,99,66,230,168,75,37, -201,151,217,59,27,201,30,27,210,165,42,211,153,167,100,146,21,25,156,57,1,36,169,91,46,169,54,183,102,255,231,145,51,176,194,206,1,205,241,30,36,78,20,26,67,60,114,231,184,242,80,80,65,24,189,235,59,78,16,78,77,246,245,88,210,113,191,235,45,81,176,52, -215,4,195,111,101,138,92,7,16,82,93,122,114,93,60,97,52,70,140,40,50,51,0,51,46,102,244,90,233,207,145,27,102,54,102,21,152,209,185,233,242,69,119,58,183,177,193,33,55,142,186,172,169,201,181,193,176,139,168,19,225,101,170,27,45,169,128,35,113,49,106, -126,15,50,187,65,167,83,31,149,17,81,62,5,233,74,186,138,152,174,198,87,30,125,154,10,229,120,141,247,66,57,107,219,79,156,146,237,39,142,204,120,78,193,220,27,233,38,180,123,240,117,29,40,120,241,156,87,62,64,5,229,131,20,104,43,28,55,153,94,30,32,245, -48,141,47,175,56,76,74,121,229,97,242,149,87,29,166,9,135,108,14,159,67,123,26,249,208,206,197,74,141,166,210,25,144,97,30,205,166,18,188,157,73,55,99,164,220,161,73,183,208,173,68,246,155,200,196,246,155,72,149,103,191,137,92,30,244,126,158,190,128, -30,145,230,8,5,72,193,115,85,69,63,77,92,135,102,82,75,249,147,52,1,47,147,107,189,65,111,63,21,214,230,203,99,74,173,15,253,227,131,190,65,154,218,86,30,244,5,243,43,43,170,6,168,168,159,166,61,71,197,143,141,144,179,12,58,150,131,114,37,100,173,162, -25,84,13,201,23,216,114,174,117,184,101,229,92,69,95,164,47,65,162,124,58,155,190,76,123,65,37,64,75,232,54,216,215,131,181,229,116,59,221,9,205,102,64,207,125,116,23,102,205,165,153,116,55,222,124,244,53,172,246,98,229,215,177,6,231,85,71,31,110,66, -95,0,35,55,20,78,63,66,193,117,131,116,90,91,197,0,205,104,241,44,243,78,158,68,207,248,107,243,139,188,121,251,105,102,85,48,191,159,102,46,243,22,121,239,57,254,151,202,96,190,167,8,74,206,58,112,252,131,202,126,154,93,11,45,231,180,13,144,86,171,120, -150,249,139,252,65,223,209,251,104,193,100,58,30,244,21,249,23,95,115,132,78,175,45,8,22,244,211,92,239,189,52,46,168,76,90,208,79,103,108,13,42,210,53,111,235,110,63,31,56,254,122,80,233,167,146,33,179,172,161,201,104,183,66,236,139,104,34,181,1,26, -219,224,194,237,52,135,46,166,249,180,3,134,186,132,206,34,29,230,8,209,249,20,166,141,100,208,101,212,65,38,117,210,21,104,251,208,119,45,69,108,19,118,64,193,203,176,250,94,24,169,128,46,160,165,244,13,186,143,252,162,116,214,172,55,208,253,48,18,34, -6,171,30,160,7,33,197,68,218,69,223,164,3,48,107,33,37,233,33,172,240,130,70,132,190,69,15,195,172,171,192,245,219,120,243,225,185,138,14,210,119,224,166,92,3,63,66,143,166,1,243,12,70,4,106,45,229,176,107,126,75,213,83,116,38,195,55,211,7,105,126,91, -97,169,247,89,42,107,243,84,182,30,33,160,187,226,24,70,43,145,74,246,167,135,171,70,14,123,158,162,234,60,74,3,200,147,3,160,43,208,38,32,115,18,160,77,1,62,187,168,158,122,115,128,222,146,213,180,197,6,6,219,111,143,193,34,121,88,185,150,14,209,227, -160,247,4,201,101,19,167,123,158,68,79,174,78,135,169,63,173,211,179,176,128,112,109,172,122,145,234,203,43,7,168,166,214,91,37,168,95,112,23,45,6,32,22,110,45,92,164,216,162,87,180,182,121,209,177,184,181,45,191,170,181,205,23,244,138,42,181,249,143, -211,18,193,211,82,239,17,90,54,20,179,115,109,167,92,13,134,215,208,56,56,98,42,34,49,136,88,60,11,162,159,135,24,108,0,242,111,182,99,192,135,62,149,6,32,126,62,102,158,141,168,188,202,86,179,49,171,102,35,61,101,231,28,121,19,252,231,217,111,79,219, -113,146,171,212,32,28,228,40,245,19,60,37,214,234,6,105,57,176,124,150,4,247,217,251,104,49,30,181,45,85,71,151,121,61,203,242,139,16,13,247,145,86,85,148,191,168,214,23,244,245,211,138,125,164,86,6,125,79,209,202,60,218,186,59,31,72,126,183,114,200, -55,179,109,130,183,65,173,219,225,155,59,168,148,190,130,176,254,42,4,190,131,206,133,88,153,0,47,5,218,239,183,131,116,42,85,192,186,71,177,126,58,112,126,204,70,221,12,248,244,57,188,229,139,112,89,5,235,210,126,244,131,154,120,47,47,235,61,167,231, -73,244,124,215,54,237,247,240,123,158,94,112,210,41,191,3,46,5,232,255,16,136,58,103,31,121,15,13,82,113,91,69,225,170,1,58,119,29,183,12,210,121,109,190,103,169,174,205,83,184,26,174,43,172,135,227,224,191,134,214,1,106,116,242,219,26,228,55,184,238, -252,187,232,12,36,56,101,144,214,194,88,77,133,23,244,211,167,196,209,120,244,83,115,63,173,59,64,107,6,169,165,109,144,214,183,201,252,13,3,116,225,0,109,148,76,209,138,5,155,106,21,49,223,230,182,90,255,139,84,28,84,10,183,56,80,15,250,91,251,105,235, -86,228,21,73,8,23,181,28,160,105,14,219,109,120,29,231,188,94,220,2,216,149,229,50,223,49,146,185,12,22,94,130,151,67,208,189,8,241,252,16,114,136,60,159,64,14,113,192,118,9,21,163,221,15,235,223,11,139,221,135,77,231,126,123,198,98,68,125,45,226,126, -53,214,180,35,194,123,16,231,215,33,190,111,65,76,239,71,196,60,136,40,120,8,246,126,24,180,30,195,251,19,176,244,97,252,13,2,142,199,0,196,119,0,188,223,227,75,124,219,13,112,246,32,26,191,79,47,194,234,215,97,251,121,137,94,6,199,61,52,139,94,1,20, -253,224,150,160,87,233,53,120,185,150,118,210,15,232,135,240,178,100,149,215,233,71,232,59,108,191,253,216,134,246,135,89,207,127,8,168,138,231,167,208,27,244,83,27,218,69,232,121,195,134,118,158,92,102,165,55,206,109,248,18,216,159,86,120,233,17,186, -236,113,210,251,169,189,185,162,48,212,79,225,188,7,40,223,123,208,115,48,27,122,133,54,143,163,192,207,49,154,6,180,77,7,106,68,131,105,14,133,52,111,149,38,208,91,118,88,229,201,133,121,154,207,131,144,82,176,185,188,194,142,135,106,60,140,117,158, -85,179,42,177,9,156,94,110,195,171,114,214,34,224,107,128,188,178,129,96,91,242,28,220,237,145,88,193,212,133,67,66,56,241,255,34,12,244,18,88,189,140,96,120,5,38,123,21,41,236,53,36,252,151,105,17,212,20,161,150,128,93,9,102,189,77,191,132,216,19,16, -30,146,208,61,88,115,38,253,10,14,16,145,151,103,205,181,156,126,109,155,43,79,110,251,211,187,222,69,224,36,65,176,119,144,58,100,191,235,116,144,213,37,233,217,148,244,108,226,229,114,134,33,118,58,112,143,236,163,98,209,164,82,62,162,208,165,159,98, -64,233,27,131,20,7,196,187,219,134,141,13,208,21,3,148,64,1,16,244,74,87,50,232,27,32,75,224,158,58,64,227,29,224,167,130,202,177,3,199,111,23,166,187,164,211,111,191,5,253,199,14,65,163,29,116,57,96,65,248,89,246,51,128,92,120,19,158,55,193,74,55,141, -216,34,223,194,232,219,52,9,122,7,161,249,60,232,88,9,45,207,161,247,144,49,223,7,165,223,131,214,31,40,78,255,0,74,127,64,110,253,35,104,125,132,58,235,31,65,233,35,84,16,127,206,38,161,121,216,106,223,163,223,194,182,59,176,205,254,14,171,37,197,239, -205,218,113,47,125,144,222,56,246,130,170,192,110,18,234,163,15,65,213,3,25,246,128,195,31,33,123,38,183,182,97,252,79,224,224,228,214,91,208,39,16,41,153,236,69,77,209,82,81,133,90,162,109,153,247,110,154,80,89,101,87,18,61,7,142,255,25,96,232,69,20, -167,70,22,113,127,65,251,111,80,246,175,40,101,254,19,229,220,223,32,234,127,101,129,0,162,89,17,75,160,214,1,91,196,18,40,246,190,189,183,205,177,119,108,15,96,82,76,255,100,231,211,172,136,147,252,244,207,160,238,136,216,136,57,30,60,149,242,10,108, -104,254,161,82,196,103,19,156,97,51,212,156,41,244,47,105,134,10,253,107,218,38,10,68,148,205,52,187,183,128,248,95,233,223,211,33,82,131,167,204,202,151,196,228,78,90,117,38,56,164,177,248,63,160,235,232,197,190,83,91,252,55,24,200,89,92,155,78,2,62, -187,252,112,95,237,4,185,47,171,149,207,209,10,116,254,155,254,199,141,142,247,224,24,233,252,47,253,95,218,204,27,96,29,73,53,126,152,25,245,176,231,144,43,37,167,104,241,103,41,249,65,201,217,205,253,176,179,179,155,251,233,239,195,119,115,240,57,206, -228,234,206,60,119,54,31,239,206,187,114,220,9,172,48,115,158,155,49,216,157,246,9,140,65,121,44,60,243,216,139,58,64,242,110,30,221,193,69,168,11,112,172,178,231,209,255,3,80,75,3,4,10,0,0,8,8,0,22,178,149,71,221,192,76,137,196,4,0,0,149,9,0,0,45,0, -0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,66,111,111,116,115,116,114,97,112,77,97,105,110,83,116,97,114,116,101,114,46,99,108,97,115,115,141,86,89,91,219,86,16,61,194,178,5,170,18,192,108,49,4,112,2,20,155,197,78,83,74, -27,160,52,9,133,176,24,146,96,150,58,164,139,176,47,70,68,150,168,44,19,232,150,46,105,251,27,250,218,151,190,54,47,134,175,124,77,223,251,47,250,212,127,209,118,174,100,131,55,242,213,15,119,153,153,59,115,206,204,189,99,253,249,207,111,47,1,188,129, -31,101,248,113,87,70,47,102,36,188,47,97,86,70,43,230,100,220,195,188,140,5,44,242,97,73,134,7,49,25,203,88,225,195,253,122,60,224,146,135,245,88,149,16,151,48,36,163,17,107,18,214,101,108,96,83,194,7,245,72,112,55,143,248,176,197,135,199,245,248,80, -198,71,248,88,194,39,245,80,249,114,91,70,23,146,18,82,2,124,83,154,161,217,211,2,60,161,240,134,0,113,198,76,49,1,141,49,205,96,43,185,204,54,179,214,212,109,157,36,254,152,153,84,245,13,213,210,248,190,32,20,237,93,45,43,32,28,51,173,116,52,109,169, -41,157,69,159,90,234,254,62,179,162,119,77,211,206,218,180,89,86,53,35,110,171,150,205,172,73,1,222,44,95,10,232,15,109,197,246,212,3,53,170,171,70,58,26,183,45,205,72,79,186,18,205,140,206,105,58,155,116,240,168,86,154,34,180,212,48,22,32,187,33,231, -205,12,97,185,92,126,88,64,131,171,93,84,45,66,159,52,13,155,29,218,51,186,154,205,198,76,53,197,72,24,112,79,24,204,142,174,175,198,74,84,252,112,134,80,59,34,1,205,37,177,29,17,15,205,245,203,204,222,53,41,135,157,37,6,22,219,209,89,210,142,186,58, -178,108,47,79,220,209,126,49,121,173,149,110,167,134,166,185,231,217,195,36,219,183,53,211,200,74,224,165,216,209,140,84,76,205,25,201,93,102,57,100,122,66,21,121,170,100,46,238,104,78,117,84,203,234,39,7,91,85,122,157,25,164,16,22,4,212,105,180,144, -227,102,206,74,178,57,231,84,160,86,225,34,220,131,130,32,174,41,120,7,183,4,116,92,144,58,1,74,169,70,193,14,210,18,118,21,104,216,147,240,68,129,142,140,2,131,15,65,152,18,246,21,124,10,75,65,22,116,39,122,232,26,69,220,170,69,244,2,227,200,61,103, -207,177,40,200,225,128,208,243,212,19,173,138,236,41,120,138,67,1,77,231,226,251,219,123,84,9,9,71,10,62,195,231,69,100,133,52,208,133,215,181,109,142,226,11,5,95,226,43,5,207,240,53,241,114,195,143,22,195,143,70,134,30,19,121,75,194,55,10,190,197,119, -84,236,243,0,171,57,195,214,50,236,172,96,2,102,103,204,156,158,10,26,166,29,212,169,236,54,11,218,187,44,232,82,8,22,125,6,23,239,172,6,53,163,40,78,105,148,109,109,59,199,61,4,7,7,178,131,17,5,207,241,61,135,246,131,128,193,255,249,180,232,141,156, -3,43,65,228,181,205,245,85,42,116,83,40,92,122,221,23,38,203,43,181,80,176,140,85,89,198,200,178,173,34,215,197,90,183,166,153,29,63,202,218,44,83,254,176,138,30,42,79,56,175,146,217,15,84,139,25,84,239,112,177,7,20,35,93,112,138,55,130,146,186,174,237, -90,76,165,103,119,41,153,179,184,163,226,190,181,44,172,43,229,224,179,204,158,169,241,252,59,67,175,8,215,160,211,186,240,254,7,66,213,205,167,138,96,129,90,177,37,220,174,113,102,171,234,76,248,85,141,227,202,69,58,106,218,154,113,96,62,161,59,124, -171,52,140,123,223,203,194,20,68,225,106,145,128,190,138,54,82,131,164,147,8,186,158,92,207,27,97,40,92,213,75,36,34,189,162,242,6,92,158,254,179,38,221,84,41,163,51,25,213,166,135,64,30,219,106,165,246,17,17,220,49,45,50,170,32,88,35,143,53,8,158,69, -174,233,124,3,215,232,255,214,15,254,243,64,224,45,141,198,235,180,139,210,44,208,236,29,58,134,240,130,22,117,232,163,209,231,8,59,208,79,163,226,26,96,0,175,211,76,143,19,33,178,226,135,255,38,59,137,230,205,161,145,99,212,173,156,194,147,16,127,135, -152,240,140,230,225,205,195,23,63,129,148,71,253,49,26,38,196,19,200,1,49,143,215,2,162,95,201,227,210,132,55,224,245,95,38,235,198,132,167,5,77,241,60,154,39,124,1,159,64,18,127,194,51,76,251,150,205,23,14,90,14,167,199,9,19,160,112,157,180,239,194, -48,174,98,12,221,244,205,208,67,31,0,189,14,204,121,23,74,1,38,95,133,49,228,64,223,36,251,17,130,236,195,67,140,210,138,251,28,67,132,184,139,52,247,225,6,125,149,120,201,87,19,110,226,77,178,26,43,144,118,117,111,145,110,156,36,34,73,222,38,47,244, -79,80,200,221,49,69,244,209,188,116,138,214,196,176,191,237,24,237,121,116,44,143,188,156,246,140,139,109,98,247,207,232,29,105,19,111,114,170,121,92,241,7,242,232,252,9,190,128,247,215,231,162,240,203,191,127,157,162,43,225,191,90,36,124,130,238,99, -244,252,113,86,129,118,10,11,10,19,164,221,40,17,188,65,235,113,202,61,167,58,77,97,131,4,119,130,200,120,113,153,234,49,137,41,58,215,76,228,223,37,173,135,62,128,174,227,61,90,137,28,222,89,74,150,156,68,240,130,223,118,226,220,249,15,80,75,3,4,10, -0,0,8,8,0,22,178,149,71,72,214,183,36,211,10,0,0,35,24,0,0,40,0,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,87,114,97,112,112,101,114,69,120,101,99,117,116,111,114,46,99,108,97,115,115,149,87,121,96,28,85,25,255,77,178, -201,110,54,211,132,110,146,182,41,41,44,37,109,210,205,69,203,221,150,35,73,83,26,200,213,108,210,154,162,214,201,238,52,89,216,236,132,217,217,30,8,10,40,40,42,162,28,34,20,68,69,173,183,65,233,6,136,128,162,22,197,27,239,251,62,241,194,3,111,240,247, -205,76,54,179,219,109,13,127,236,155,247,189,247,189,239,248,125,199,123,251,228,115,15,63,10,96,189,18,242,227,45,126,220,17,192,91,131,40,193,157,126,220,21,68,25,14,6,161,224,110,89,185,199,143,183,5,112,175,31,111,15,226,29,120,103,16,21,184,47,136, -74,28,244,227,93,65,84,227,96,5,57,223,45,195,123,100,56,36,195,123,229,244,251,100,120,191,176,124,32,128,15,202,247,67,178,242,97,153,125,36,128,25,249,222,47,195,71,3,248,152,124,31,144,237,195,50,203,6,48,43,223,7,101,120,40,128,135,229,59,39,195, -199,253,120,36,128,71,197,138,199,132,253,19,65,156,142,79,138,157,143,203,236,83,50,251,116,0,159,17,31,142,248,241,132,240,28,145,157,251,100,246,89,63,62,23,196,217,56,24,192,147,242,253,124,0,95,8,224,139,1,124,41,128,47,7,240,149,0,190,42,203,79, -249,241,181,32,186,132,237,235,242,253,134,12,79,85,226,155,248,150,72,249,182,31,223,9,162,23,223,21,37,223,11,226,251,248,129,152,246,195,32,126,132,31,7,241,19,252,52,128,159,41,168,223,210,27,29,25,238,237,26,29,233,29,28,216,61,58,220,183,123,104, -120,112,168,103,120,100,76,65,168,239,50,109,175,214,145,212,82,19,29,81,203,76,164,38,54,41,88,210,109,164,210,150,150,178,118,104,201,140,174,96,101,158,128,174,206,104,143,71,66,254,230,80,231,200,54,207,230,138,188,205,232,182,206,221,27,206,60,107, -119,116,180,95,193,242,93,189,67,187,163,35,131,195,61,133,18,61,59,5,226,130,211,166,49,173,155,86,66,79,43,88,230,152,158,177,18,201,142,161,220,58,205,175,90,224,218,154,72,210,254,42,135,51,97,116,8,45,14,238,211,204,20,125,29,204,88,211,25,43,39, -202,70,161,115,122,90,79,197,181,113,155,177,60,102,164,246,36,38,20,172,235,51,204,137,142,9,83,139,39,245,142,125,166,70,38,179,99,167,243,237,182,121,50,166,102,37,140,20,15,213,236,49,76,26,116,153,30,179,182,36,76,142,134,121,64,193,197,205,249, -86,20,87,121,60,61,61,251,245,88,134,194,168,194,215,109,196,233,88,117,95,34,165,15,100,166,198,117,115,68,142,75,60,141,152,150,220,161,153,9,161,221,69,129,205,181,134,33,161,117,174,192,161,2,156,202,55,39,82,9,235,124,5,231,21,181,181,16,233,99, -120,176,67,129,66,97,117,158,237,158,253,49,125,218,69,199,103,77,38,24,189,198,197,57,186,108,218,212,167,53,83,223,146,72,51,59,199,51,34,100,212,76,40,56,161,121,157,163,32,165,91,29,163,195,189,18,172,180,145,49,99,11,241,94,216,9,230,12,72,251,241, -115,198,223,212,181,184,45,210,24,53,147,204,225,60,122,139,78,165,49,205,210,227,59,53,6,174,130,128,77,105,150,165,155,57,167,108,36,182,206,47,83,65,69,124,65,88,85,210,208,226,67,158,68,109,90,20,154,130,91,32,145,98,17,234,218,84,78,19,207,244,166, -152,163,206,242,38,63,126,193,168,79,232,150,23,15,130,193,149,188,44,84,208,210,252,66,82,214,175,219,144,19,187,75,155,47,61,186,37,20,147,212,43,45,34,153,44,186,215,101,24,22,237,211,166,251,53,241,72,51,5,37,113,208,167,153,19,68,164,166,136,14, -26,145,112,68,42,104,56,158,66,5,181,227,69,228,31,163,70,139,154,194,140,112,216,182,25,83,244,185,146,240,185,145,96,188,215,54,31,109,220,186,98,246,170,110,159,57,48,160,137,148,115,138,156,91,172,164,184,190,71,203,36,231,251,237,185,139,146,180, -171,168,168,128,169,95,145,97,215,137,179,10,119,41,40,219,235,136,172,99,25,25,166,213,159,72,167,201,183,224,108,48,106,215,140,83,255,181,5,245,215,46,242,21,172,254,255,149,74,23,188,41,174,160,185,128,223,33,219,92,178,125,161,67,171,152,196,47, -169,186,88,77,200,222,175,100,72,168,248,53,126,195,58,93,112,120,56,147,178,18,83,122,174,176,21,180,186,54,133,23,132,135,247,208,152,112,211,154,116,83,56,110,144,76,25,86,88,223,207,210,105,103,205,44,200,26,28,151,238,232,199,111,85,60,141,223,137, -194,223,179,106,23,89,61,42,118,227,101,42,198,176,75,197,165,120,177,138,151,224,165,42,14,224,74,21,41,24,42,254,128,63,82,89,220,83,175,93,90,90,87,241,39,60,163,226,117,184,73,197,159,69,93,30,199,144,102,77,170,248,139,112,252,85,54,235,188,155, -209,73,141,151,104,52,51,165,226,111,142,140,155,85,60,43,108,234,149,137,233,40,163,161,59,26,254,46,187,255,200,219,112,4,255,83,54,254,37,27,53,69,122,52,145,236,54,50,201,184,141,150,244,178,240,190,34,192,154,198,148,13,108,187,192,245,111,21,150, -248,250,31,17,252,95,60,167,226,121,206,20,192,96,183,138,231,181,238,164,24,252,250,249,124,113,91,180,138,140,176,46,47,204,231,174,76,34,25,151,210,246,103,204,228,48,43,89,85,20,165,132,153,221,81,0,152,83,129,74,27,61,242,46,239,208,205,180,237, -209,50,239,106,119,82,99,21,236,73,136,96,95,59,161,81,149,82,60,51,15,70,126,111,87,240,248,113,211,138,239,3,139,141,37,29,142,231,46,141,176,158,162,42,114,53,185,70,55,181,134,155,10,141,45,92,115,45,109,10,107,169,120,254,206,130,181,77,237,225, -145,73,61,173,135,247,37,146,201,240,184,30,54,245,41,99,47,21,166,13,35,213,30,30,74,234,12,123,56,147,118,77,147,110,202,107,173,125,13,83,244,105,197,231,87,202,4,189,114,21,183,10,254,203,189,245,234,185,98,24,78,197,175,42,1,165,194,175,4,85,165, -82,10,240,21,48,252,138,170,42,75,148,42,191,82,173,42,39,40,75,21,116,14,24,97,187,185,208,28,107,50,124,185,126,192,81,155,158,214,99,98,110,156,6,20,205,156,121,236,88,131,39,122,147,32,122,128,80,238,247,164,97,77,238,6,28,244,172,158,122,236,119, -212,124,139,229,69,83,218,44,99,185,93,236,105,155,220,149,87,242,14,43,57,156,203,189,120,207,245,222,82,78,143,40,222,190,235,138,221,24,84,95,157,46,188,168,151,54,231,63,77,132,171,166,224,58,151,226,101,67,108,46,170,170,38,93,140,185,80,132,148, -249,209,188,206,234,138,2,222,92,59,225,86,250,152,91,65,158,218,149,152,118,212,5,211,94,194,217,113,132,187,59,14,17,57,254,53,54,50,105,26,251,114,79,198,10,138,137,198,38,117,169,227,37,114,31,243,209,151,178,156,203,36,247,214,91,120,193,215,229, -216,163,78,190,197,120,128,97,44,179,12,226,202,184,106,246,139,84,65,219,162,110,115,183,209,200,253,105,25,243,185,177,249,5,165,196,81,111,194,218,98,207,99,5,167,121,165,118,79,106,102,148,23,182,158,138,233,121,102,229,253,11,89,90,144,242,246,75, -74,58,51,67,214,92,244,157,104,231,85,145,13,2,20,75,26,18,182,149,199,126,97,49,140,49,50,91,246,163,219,174,140,197,62,36,143,10,83,177,75,180,216,139,140,118,165,45,59,128,141,69,223,159,5,238,227,20,254,251,173,4,16,68,61,182,99,152,84,148,84,9,214, -147,30,241,208,43,72,143,122,232,6,210,59,60,244,201,164,119,122,232,83,73,191,200,67,175,69,72,110,118,206,67,114,185,219,95,222,239,246,151,215,62,191,85,168,128,134,113,158,136,145,26,64,57,79,1,43,231,160,140,205,161,100,44,18,42,157,133,111,14,101, -99,179,40,111,153,133,127,198,150,27,231,88,206,51,64,51,116,142,203,156,83,216,99,235,144,153,104,97,85,96,34,39,59,1,191,205,213,22,201,34,112,23,86,204,161,98,44,20,244,61,130,202,177,210,72,244,65,168,179,88,242,152,232,141,20,85,87,133,82,142,173, -20,210,70,24,58,60,106,219,92,215,100,230,168,133,188,185,28,181,202,118,158,40,227,202,108,100,22,85,20,93,77,209,39,28,198,210,72,235,97,132,34,45,135,81,19,105,59,140,218,22,26,117,39,110,107,105,125,16,117,145,7,184,61,139,101,89,44,183,167,161,21, -242,201,162,126,22,43,179,56,209,89,107,112,214,86,217,107,39,57,107,39,59,107,97,98,118,74,22,171,157,197,83,157,197,70,155,113,141,179,182,214,89,107,178,215,154,15,161,97,163,207,134,35,226,192,209,34,112,212,251,102,209,242,216,253,116,99,13,238, -194,61,88,231,2,177,21,75,57,110,128,143,235,213,56,29,181,56,131,81,63,19,39,225,44,174,156,131,8,206,37,181,17,189,216,68,56,54,195,196,121,184,1,231,83,70,39,165,92,128,123,113,33,178,232,182,1,60,131,208,220,139,229,184,12,151,83,30,65,66,18,83,54, -148,179,54,168,138,61,147,12,42,177,103,2,111,41,231,124,25,114,148,168,198,121,78,246,26,9,88,107,31,81,108,123,2,245,118,230,60,128,154,44,218,185,210,193,12,202,226,180,153,150,133,96,134,108,109,91,169,253,34,168,180,116,53,46,241,4,180,209,181,162, -140,249,61,141,43,104,133,73,202,199,111,154,251,86,78,247,118,123,13,16,216,67,161,245,89,108,56,130,165,115,56,157,89,187,126,22,103,204,226,204,25,90,117,86,97,14,13,81,229,118,166,232,136,173,82,117,68,184,42,189,138,50,57,69,207,50,217,229,228,13, -74,223,28,206,102,2,157,19,9,157,75,13,89,108,12,109,226,16,9,109,118,169,243,108,234,252,60,234,2,151,186,144,67,22,157,20,209,69,17,221,253,173,161,45,101,78,246,19,170,232,152,47,180,62,154,69,207,78,82,181,173,89,108,125,8,23,149,96,231,33,84,246, -219,238,108,219,41,158,181,136,83,180,175,132,150,102,114,41,177,150,133,6,22,126,9,3,213,195,16,245,179,184,227,44,111,147,99,134,229,189,151,94,92,77,111,197,223,8,253,235,103,162,236,197,62,242,239,101,117,72,240,5,246,27,92,12,74,240,106,236,183, -155,200,2,26,65,249,71,224,162,241,74,98,33,225,91,53,135,222,49,2,124,113,127,11,237,189,132,191,190,67,8,14,200,183,141,121,91,66,163,170,80,71,198,58,198,181,46,23,132,149,4,83,186,65,5,213,86,81,97,136,217,84,199,111,3,225,22,3,195,54,212,171,114, -69,189,202,206,63,233,37,181,120,57,174,178,93,119,204,186,154,63,190,237,220,254,178,129,95,9,101,192,169,173,254,194,78,149,241,132,59,224,186,170,208,153,107,220,243,29,238,249,50,57,95,120,248,42,207,225,178,220,225,107,113,157,139,73,146,70,75,151, -9,181,58,218,7,54,250,218,90,234,153,246,131,247,23,100,223,53,196,242,90,150,240,117,185,2,148,114,152,47,187,16,94,69,244,21,123,118,61,35,82,98,207,94,131,215,242,108,144,102,223,72,80,124,57,0,36,254,252,55,226,58,176,217,45,197,64,164,69,97,239, -56,165,208,135,235,61,37,22,200,105,12,224,13,118,172,69,210,77,174,164,173,148,84,234,72,106,45,38,233,70,79,160,142,150,36,179,55,114,86,98,203,188,217,149,121,11,169,50,187,81,176,88,217,21,54,108,244,213,251,142,160,188,222,55,211,122,4,101,173,51, -171,238,68,69,132,249,189,109,70,89,208,183,154,178,64,187,130,148,88,77,89,33,188,153,30,220,194,139,241,54,38,204,237,220,191,195,131,99,99,206,150,198,156,45,141,174,45,50,123,19,79,11,142,43,41,97,216,70,235,214,28,122,67,238,245,212,96,55,226,161, -50,183,17,143,249,236,234,116,175,167,2,28,238,246,32,218,144,211,221,224,234,86,104,163,240,223,254,63,80,75,3,4,10,0,0,8,8,0,22,178,149,71,132,26,164,171,178,10,0,0,66,24,0,0,42,0,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101, -114,47,71,114,97,100,108,101,87,114,97,112,112,101,114,77,97,105,110,46,99,108,97,115,115,157,88,7,120,20,199,21,254,7,78,218,211,106,85,56,9,164,195,148,3,11,212,144,206,128,141,177,192,16,89,18,32,144,16,160,102,129,109,188,156,22,233,240,233,86,220, -237,81,226,150,98,167,216,137,211,72,177,147,56,61,78,226,20,156,56,39,217,138,77,236,20,39,78,119,122,239,205,233,189,59,249,103,119,117,58,221,45,66,95,190,15,205,237,188,121,253,189,121,239,13,79,62,243,240,163,0,214,139,141,42,182,225,46,21,27,240, -50,185,188,92,46,175,80,240,74,21,5,18,92,128,87,41,56,227,199,171,253,120,141,220,189,86,197,235,112,183,31,247,248,241,122,5,111,80,81,38,177,202,240,70,121,120,175,138,55,225,205,10,222,162,162,210,1,191,85,197,14,188,77,242,124,187,92,222,33,151, -119,170,184,15,239,82,240,110,5,239,241,227,126,9,122,175,138,229,120,159,130,247,171,88,133,15,168,88,134,179,10,30,80,81,35,185,220,135,15,42,248,144,31,15,170,168,197,135,85,164,49,33,191,38,229,242,144,92,30,246,99,202,143,143,168,240,227,17,185, -127,84,193,57,21,31,197,99,42,30,199,199,84,124,28,159,80,241,73,60,161,224,83,10,62,173,98,51,158,84,241,25,124,214,143,207,73,154,207,251,241,5,5,95,148,159,95,146,135,79,201,195,47,75,70,79,249,241,21,201,232,171,126,124,77,193,215,165,45,119,201, -229,27,126,220,46,127,191,233,199,183,84,124,27,223,81,240,93,63,190,39,137,191,175,226,7,248,161,92,126,164,226,199,248,137,138,159,226,103,10,126,174,162,15,191,16,168,218,121,160,181,189,171,227,112,127,111,199,129,195,187,122,186,59,14,247,236,235, -235,236,217,43,16,232,58,166,159,208,195,49,61,62,18,238,181,18,209,248,200,22,129,146,54,51,158,180,244,184,53,160,199,82,134,64,40,143,188,189,163,175,181,179,171,163,61,195,167,194,69,217,223,223,217,209,151,129,46,155,5,205,35,42,220,26,141,71,173, -109,2,11,235,234,7,4,124,109,230,48,165,149,117,69,227,198,222,212,216,17,35,209,167,31,137,25,82,73,51,162,199,6,244,68,84,238,93,160,207,26,141,38,5,214,118,153,137,145,240,72,66,31,142,25,225,147,9,125,124,220,72,132,119,218,219,65,103,215,173,71, -227,52,202,55,198,95,129,37,117,135,242,77,182,165,235,137,17,242,171,240,56,22,80,93,206,187,245,132,64,169,131,17,53,195,59,162,49,131,167,165,227,9,147,135,86,212,72,74,136,128,146,48,77,171,61,74,220,194,113,61,145,52,248,177,58,91,207,72,44,26,110, -51,199,198,244,248,176,52,118,159,141,67,70,69,17,51,126,130,140,36,193,101,185,4,189,167,147,150,49,182,47,35,42,139,65,219,52,25,121,40,230,184,21,101,252,60,68,218,114,134,179,232,136,94,158,204,97,75,23,57,246,165,172,104,44,60,3,151,118,58,188,250, -169,236,46,115,140,118,22,198,204,145,17,169,236,69,94,81,232,178,15,73,87,230,66,58,78,25,145,148,101,18,191,198,11,127,112,54,150,116,123,199,169,136,49,109,78,133,62,60,156,235,3,129,149,117,179,163,49,123,39,3,171,58,98,28,141,87,228,160,215,231, -198,114,145,171,77,182,140,242,186,60,52,65,94,203,29,96,220,176,194,253,7,58,123,79,199,45,253,84,70,97,226,248,99,76,91,249,157,73,25,23,85,186,210,21,51,96,36,146,54,70,229,180,140,156,171,120,194,65,112,238,3,85,73,24,73,51,149,136,24,173,73,226, -24,250,152,192,226,140,110,157,241,241,148,229,128,73,170,29,73,69,99,195,7,140,136,17,29,183,50,104,54,251,108,45,55,212,93,56,77,242,204,223,62,47,162,185,114,66,237,181,205,112,238,203,146,188,11,219,44,5,106,184,6,215,106,24,193,45,26,110,198,77, -26,142,225,38,86,163,11,93,36,13,191,196,211,116,85,174,59,25,53,254,149,59,164,77,41,98,54,141,50,41,52,252,10,191,86,240,27,13,191,197,239,136,115,92,160,224,120,42,106,208,103,27,255,143,43,168,225,247,248,131,134,63,226,79,10,254,172,225,47,248,43, -147,106,230,66,237,210,147,163,221,250,184,134,191,225,239,26,254,129,127,106,72,226,14,13,167,241,108,13,22,238,84,240,47,13,255,198,127,4,150,122,184,175,83,214,229,88,140,23,206,227,176,221,60,25,143,153,250,48,107,128,115,114,82,195,243,113,155,244, -226,51,179,221,54,77,177,79,183,70,91,147,73,99,140,21,53,33,241,254,203,133,46,64,173,7,242,85,172,105,73,139,27,25,159,94,75,183,141,21,66,44,96,170,101,167,7,205,117,40,155,103,202,162,100,187,80,17,62,77,20,136,66,77,40,140,168,240,83,53,81,132,219, -88,70,174,97,184,19,53,2,197,217,36,66,21,197,146,78,99,185,152,79,141,87,68,137,38,74,69,153,34,202,53,177,72,4,20,81,161,137,74,177,88,17,75,52,81,37,170,233,180,57,238,43,253,61,147,47,7,82,113,43,58,102,100,14,165,26,65,69,44,213,196,69,82,95,223, -81,154,169,137,101,98,185,192,182,54,61,30,55,173,208,176,65,119,140,49,17,66,145,152,158,76,142,211,179,161,163,102,34,228,170,27,98,231,8,29,77,152,99,161,8,155,220,17,61,105,132,106,215,36,107,155,103,165,105,207,145,99,70,196,210,196,10,177,82,74, -12,105,98,149,20,23,12,219,55,185,41,225,92,229,89,62,90,45,46,102,104,247,154,33,27,37,228,162,132,166,171,4,85,72,197,135,41,165,210,171,164,107,162,70,172,209,196,90,81,43,176,137,60,220,90,19,138,219,197,38,148,28,55,34,209,163,81,99,56,20,141,159, -135,127,179,34,234,52,81,143,107,89,158,61,202,11,35,215,102,166,72,55,219,67,211,62,113,229,53,75,99,27,20,209,168,137,117,162,137,215,81,144,109,88,19,151,224,54,69,172,151,247,227,22,58,225,188,197,68,82,111,144,237,33,22,51,79,246,199,111,136,243, -26,244,76,55,141,154,186,250,249,52,222,66,211,213,247,114,207,241,96,14,22,61,211,117,116,142,178,212,227,50,47,30,213,147,173,137,145,212,152,17,183,46,164,90,134,175,156,9,142,70,71,82,9,94,172,53,121,101,55,223,24,217,242,10,236,169,99,190,214,120, -142,5,89,100,118,209,99,43,26,49,172,236,174,88,61,221,177,242,7,5,197,157,99,4,174,154,71,163,200,226,194,202,184,165,62,103,47,135,168,148,213,42,171,94,160,46,23,151,198,174,190,240,40,65,101,121,23,7,115,59,187,83,173,118,123,78,16,182,233,173,196, -143,15,203,121,211,187,155,229,79,44,179,237,205,233,122,249,177,240,30,69,23,229,14,41,132,93,55,39,99,175,86,49,221,14,60,79,103,85,126,91,128,98,216,86,208,33,135,188,178,198,83,132,211,141,60,207,188,186,133,45,231,226,243,187,59,203,5,13,30,44,115, -187,239,46,38,80,76,14,69,21,204,204,11,79,134,249,121,101,103,180,158,224,109,116,50,161,40,179,151,45,212,176,246,234,114,100,212,18,198,120,76,151,163,74,34,201,131,205,117,243,10,163,215,48,87,59,63,82,154,95,54,3,109,147,237,196,177,145,214,89,108, -16,172,11,237,166,243,154,89,61,125,7,147,140,93,34,106,157,14,231,226,80,236,138,185,49,28,63,200,183,151,51,146,241,217,150,199,117,230,148,252,170,207,119,198,10,71,78,93,153,169,55,51,55,59,45,183,107,203,244,164,224,238,89,168,44,147,173,56,15,83, -78,200,213,217,206,234,27,77,152,39,157,123,56,48,155,73,167,19,182,222,200,168,97,191,72,140,227,41,61,70,127,45,206,38,119,26,235,150,250,131,68,96,33,24,211,25,199,43,60,130,113,200,131,198,43,144,139,61,104,237,59,100,39,144,53,234,132,235,64,222, -168,94,239,69,119,158,241,221,231,140,114,213,117,158,231,82,90,241,76,65,62,205,135,240,249,121,207,86,190,194,131,31,35,17,137,153,178,101,52,204,157,163,179,3,145,219,243,242,106,59,131,195,158,55,221,255,60,221,198,152,108,245,84,253,66,188,51,29, -114,237,252,48,249,32,163,195,220,255,210,240,26,112,119,206,122,221,118,153,230,13,169,113,198,161,238,96,253,0,86,97,3,182,1,240,33,136,1,12,114,68,190,154,187,5,40,226,126,40,107,175,114,127,48,107,95,194,253,161,172,125,41,41,132,124,214,112,189, -142,144,48,228,184,13,20,52,76,64,60,96,163,28,230,90,104,3,87,224,122,174,154,131,0,29,71,248,91,132,8,134,137,69,98,113,134,226,138,9,123,124,18,11,186,26,39,177,176,155,139,111,239,20,10,134,38,80,216,226,11,250,210,80,6,131,190,130,71,224,31,90,24, -40,234,29,242,5,212,222,52,138,211,208,102,192,37,18,92,42,193,131,83,40,35,101,121,75,65,176,64,210,46,10,250,26,210,8,180,20,78,162,162,69,9,42,132,22,78,161,146,40,139,211,88,146,70,85,144,39,213,45,254,160,191,105,18,65,185,89,218,82,180,46,88,52, -137,139,90,212,160,218,48,133,101,67,193,162,41,44,231,26,88,49,137,149,19,8,77,97,213,80,208,63,129,213,19,184,120,10,53,228,181,38,141,181,51,150,239,70,128,235,26,58,122,45,109,173,165,195,234,81,133,6,44,71,35,46,197,58,236,66,51,246,211,109,87,99, -61,189,179,17,6,161,167,176,9,183,98,51,110,71,11,94,130,173,56,131,43,241,24,90,109,239,141,59,30,34,222,81,59,124,143,242,57,57,74,143,22,225,33,68,249,37,67,242,32,31,150,163,88,72,57,247,227,6,196,136,181,31,199,49,134,56,189,126,61,189,110,146,75, -33,57,92,75,104,2,10,101,181,113,40,29,133,159,210,54,241,209,150,34,183,51,212,235,4,78,50,34,167,108,57,2,221,252,230,171,206,13,116,132,188,22,240,183,150,190,156,66,237,80,67,160,110,2,245,147,160,131,171,92,80,99,22,104,198,33,165,84,12,104,71,5, -58,232,146,29,182,81,75,28,86,184,145,74,192,254,58,102,27,165,202,23,178,43,240,50,55,179,138,201,174,209,249,119,54,39,191,58,179,242,171,216,246,11,200,226,230,12,139,86,23,175,202,86,56,141,117,252,107,10,52,7,194,105,92,50,129,245,185,236,186,179, -216,85,101,216,241,245,238,178,187,151,174,147,122,239,174,192,134,52,54,166,113,105,26,151,165,177,105,207,125,40,233,154,194,230,161,198,9,92,113,142,50,90,2,91,210,216,122,15,170,37,48,112,165,239,17,108,27,90,216,208,59,137,237,19,120,214,57,87,153, -214,9,92,117,214,150,85,78,223,92,238,106,178,130,50,128,94,194,6,8,237,67,37,250,153,58,131,76,162,171,121,127,15,102,188,87,201,144,221,138,231,144,190,156,73,243,92,60,143,112,191,124,45,187,186,62,205,16,22,240,119,128,186,6,218,210,104,223,211,240, -4,74,108,125,58,28,37,118,48,117,119,118,53,82,147,93,141,129,206,52,118,119,175,155,198,216,35,49,214,237,229,81,87,211,217,22,121,135,186,130,190,115,123,236,179,189,188,232,61,231,200,125,37,182,208,193,210,201,109,246,47,176,157,201,223,205,239,221, -246,175,99,207,6,250,19,252,42,162,230,37,44,1,85,76,164,149,76,197,26,166,115,35,125,27,166,151,175,96,212,183,48,109,119,51,97,247,48,89,165,141,13,148,208,72,75,111,167,237,178,74,181,226,5,120,33,225,43,9,125,17,147,88,16,179,152,30,120,177,29,163, -36,238,112,237,222,103,167,46,253,216,16,40,74,99,223,221,168,116,146,149,155,253,105,28,144,62,159,68,239,76,228,157,236,180,40,33,133,165,76,255,153,12,88,97,95,27,201,221,194,157,46,247,205,46,247,210,41,244,145,105,9,37,76,160,63,55,143,110,204,226, -82,234,114,17,188,106,18,235,165,255,3,80,75,3,4,10,0,0,8,8,0,22,178,149,71,217,206,17,120,160,6,0,0,180,14,0,0,34,0,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,73,110,115,116,97,108,108,36,49,46,99,108,97,115,115,157,87, -107,119,27,213,21,221,215,26,89,138,60,73,28,1,1,81,135,4,48,32,43,216,74,12,9,36,78,66,19,59,128,65,49,33,78,226,198,77,91,198,210,32,143,51,158,81,71,35,39,161,15,160,188,194,35,208,2,165,152,119,31,16,104,75,27,90,172,56,164,13,143,118,173,174,213, -126,236,71,126,5,127,160,101,31,141,100,203,178,226,38,245,90,62,247,222,51,231,158,179,239,57,251,62,244,207,255,124,114,30,192,70,252,125,25,186,113,88,196,119,68,124,87,196,247,68,60,32,194,136,161,7,99,17,100,99,136,34,23,129,25,67,12,99,50,120,80, -122,249,40,198,165,181,68,51,33,226,136,8,91,196,100,12,163,112,162,112,101,80,144,193,247,163,240,196,186,24,131,143,146,104,166,218,112,20,199,196,224,184,12,31,106,195,15,240,195,54,252,8,63,22,241,112,20,143,136,250,209,24,126,130,199,98,120,92,226, -140,226,137,40,158,140,226,41,233,158,16,241,180,204,127,38,70,180,207,70,240,92,4,39,35,120,94,161,125,202,176,59,109,55,107,216,163,86,225,78,203,54,21,86,100,38,140,41,35,109,185,105,25,247,41,180,137,77,206,42,250,3,150,167,112,89,109,228,89,99,37, -223,114,157,3,158,61,55,201,49,253,244,129,125,131,156,180,74,204,178,174,243,160,149,47,121,134,216,41,116,101,92,47,159,206,123,70,206,54,211,71,61,163,80,48,189,244,72,208,246,215,155,114,126,162,49,204,240,184,209,187,105,243,112,105,82,33,30,4,179, -13,39,159,30,166,129,147,231,132,86,127,220,42,118,110,80,232,104,22,101,208,41,250,134,109,139,221,54,203,177,252,29,10,143,39,151,50,92,152,132,102,163,218,90,47,122,81,139,81,119,29,84,208,250,221,28,179,190,50,99,57,230,80,105,114,204,244,246,27, -99,82,135,120,70,202,114,208,240,44,25,87,149,154,172,82,1,10,250,160,227,48,130,109,20,139,38,53,215,44,177,152,206,141,92,183,70,103,44,84,123,178,171,177,190,49,127,178,48,87,253,80,78,138,220,98,117,42,92,30,24,50,251,118,122,208,55,185,10,215,19, -243,73,195,59,98,122,129,249,114,199,52,115,197,1,247,168,99,187,70,78,65,141,18,153,239,22,50,230,148,105,147,47,68,214,94,231,38,195,130,10,22,207,117,125,133,213,11,87,120,188,80,91,229,186,134,41,219,22,66,222,33,40,118,31,203,154,5,201,107,49,130, -23,8,182,182,174,74,126,239,27,155,48,179,18,105,217,176,149,119,12,191,228,209,235,206,197,6,117,113,200,213,108,201,243,76,199,79,247,51,83,2,164,89,216,97,183,228,101,205,96,241,122,53,191,61,98,198,18,238,118,178,182,91,100,97,247,152,254,184,203, -115,224,167,58,126,134,23,117,108,193,86,29,27,176,81,71,175,136,91,112,171,142,77,216,172,227,54,220,174,163,15,47,209,87,125,40,29,47,99,183,194,149,141,132,217,85,178,236,156,233,233,248,57,94,209,241,11,188,202,122,245,184,71,116,76,203,184,15,175, -233,120,29,111,232,120,83,196,91,162,123,27,239,40,132,123,10,134,231,235,248,165,168,127,133,95,51,90,173,98,116,186,78,60,253,38,130,119,117,188,135,83,58,222,199,7,17,252,86,199,239,240,123,29,31,226,15,58,254,136,211,17,124,164,227,79,248,115,4,31, -235,152,17,63,101,236,231,97,48,96,218,166,47,78,72,27,38,212,245,142,211,221,25,204,70,112,86,199,39,56,23,193,95,116,252,21,231,153,185,3,206,67,86,161,32,182,36,192,58,223,165,225,167,248,76,199,231,248,66,199,223,196,229,128,44,186,99,41,30,147,77, -141,53,84,88,179,100,17,9,114,126,202,28,105,20,174,190,112,28,130,205,122,166,225,155,3,228,158,194,150,166,7,69,211,45,190,104,111,133,146,178,199,151,231,77,127,175,33,176,2,226,68,56,30,50,38,205,70,218,206,31,102,226,219,225,126,234,78,54,57,53, -22,169,170,188,224,196,168,239,6,42,133,235,147,205,78,173,198,227,167,205,42,14,212,74,87,129,203,13,220,106,21,3,156,43,137,115,231,88,209,181,75,190,185,215,240,199,153,24,35,155,53,139,60,103,55,240,164,205,92,242,9,218,100,25,243,185,106,205,9,153, -204,249,32,27,37,72,243,236,215,130,52,189,82,50,110,62,95,201,198,130,236,85,183,252,82,217,75,92,208,25,83,99,187,76,234,21,205,234,113,112,30,114,175,64,222,118,233,144,7,107,27,178,239,2,59,96,254,136,141,230,230,186,107,147,13,87,209,130,140,10, -174,40,73,71,162,237,119,121,35,55,240,65,42,93,131,125,203,255,134,221,48,121,241,161,190,98,161,134,177,173,234,165,193,147,62,217,213,252,50,137,47,214,114,123,140,27,197,33,243,24,93,104,78,165,169,193,188,85,96,118,95,10,76,174,241,166,139,220,188, -1,221,7,234,158,28,117,183,229,252,195,70,175,31,207,67,219,36,208,238,191,8,104,245,204,185,152,13,90,11,176,89,2,244,253,223,111,150,122,87,183,93,114,26,229,12,11,142,196,33,243,168,168,176,142,15,201,30,62,67,210,104,109,111,151,187,13,96,219,91, -109,121,195,85,90,94,114,149,150,247,92,165,229,69,200,231,116,136,255,125,216,198,217,219,217,219,139,22,68,216,222,152,90,63,3,149,186,121,6,45,169,238,25,132,82,9,109,6,90,42,17,158,65,56,149,104,157,65,107,234,12,34,31,209,178,5,59,40,91,57,31,140, -124,7,165,94,233,223,136,111,162,31,242,56,226,77,66,43,122,111,241,17,166,37,212,91,231,16,61,148,250,24,45,101,44,59,135,216,161,51,104,11,70,122,25,203,227,43,40,202,88,121,134,143,21,106,67,101,172,154,198,154,245,101,196,167,177,154,10,37,202,224, -195,101,179,184,252,116,48,51,254,26,34,218,41,104,161,237,29,211,152,88,210,255,21,115,254,135,186,203,88,61,34,62,103,113,101,213,48,126,21,63,83,165,149,145,160,85,25,87,7,223,191,33,186,238,179,232,8,161,59,112,182,102,164,134,102,22,215,12,241,211, -90,133,173,90,66,59,11,94,170,211,216,46,189,107,21,62,67,116,107,184,33,198,117,140,145,8,115,1,1,148,106,144,68,120,22,215,143,156,250,239,167,85,191,52,232,44,227,6,137,198,255,214,89,86,101,161,155,155,2,168,45,129,163,120,50,24,134,26,253,86,29, -16,102,87,93,254,184,192,27,152,191,173,90,37,180,54,139,20,115,188,126,36,161,157,174,176,66,170,58,138,213,148,189,72,146,67,91,200,162,12,185,115,152,189,7,200,156,19,100,205,73,242,230,67,86,246,60,173,255,129,157,248,55,118,225,43,244,171,56,6,84, -7,223,15,107,113,151,186,29,131,106,2,247,168,227,200,168,147,216,163,94,193,144,122,157,60,19,166,236,227,175,160,19,236,221,73,166,134,56,115,61,238,98,47,140,47,201,153,187,49,8,77,184,82,229,81,82,77,225,30,126,85,56,172,118,225,94,98,105,97,188, -127,97,15,134,16,162,231,85,184,143,95,53,122,14,24,24,124,187,159,126,247,81,163,81,51,220,190,147,126,247,7,92,228,94,81,21,158,134,83,101,220,124,122,9,34,135,171,0,230,220,80,30,168,216,31,196,72,165,253,22,14,85,190,141,226,219,76,0,248,115,145, -59,26,149,191,175,1,80,75,3,4,10,0,0,8,8,0,22,178,149,71,106,32,106,144,180,1,0,0,86,3,0,0,56,0,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,80,97,116,104,65,115,115,101,109,98,108,101,114,36,76,111,99,97,108,68,105,115, -116,114,105,98,117,116,105,111,110,46,99,108,97,115,115,149,82,91,75,27,65,20,254,206,102,221,213,116,171,113,181,182,218,91,180,121,136,107,235,218,226,91,75,65,18,4,33,180,133,22,31,124,40,76,146,33,78,186,217,13,147,77,139,255,74,193,80,240,161,63, -192,31,85,60,51,134,210,168,16,124,216,153,115,251,46,115,216,203,191,23,127,0,188,197,171,57,204,96,173,8,15,79,77,244,204,28,207,125,188,244,81,38,248,109,53,200,143,84,159,48,223,232,138,159,34,86,89,188,175,18,249,126,220,170,43,77,240,242,99,53, -168,236,16,54,26,153,238,196,29,45,218,137,140,127,105,209,239,75,29,127,17,249,241,222,96,32,123,205,68,106,198,121,31,84,170,242,143,132,189,234,244,241,73,209,201,108,243,144,224,214,178,182,36,44,52,84,42,63,13,123,77,169,191,9,6,18,194,70,214,18, -201,161,208,202,228,227,162,107,140,18,22,109,175,206,246,181,106,14,115,149,165,132,224,32,77,165,174,37,130,165,121,100,119,170,181,202,45,18,126,91,216,145,249,255,37,187,158,82,117,243,230,238,138,60,199,91,53,25,39,95,179,161,110,201,235,36,156, -16,217,54,184,0,69,60,8,16,96,61,192,28,102,3,248,152,245,177,65,120,119,127,143,236,198,90,73,68,218,137,63,55,187,178,149,19,10,85,179,202,242,52,54,172,243,159,225,241,63,83,64,104,60,112,20,26,67,64,169,100,44,218,14,111,18,15,249,156,231,236,59, -28,184,124,47,71,91,35,80,244,27,78,244,122,132,66,244,102,4,247,140,235,14,22,44,135,153,81,204,212,101,212,15,44,33,65,137,43,101,102,99,44,22,249,131,141,140,150,99,35,163,110,180,30,97,101,172,21,243,77,124,207,68,231,40,156,254,35,247,108,81,91, -194,224,122,96,76,72,120,124,39,216,189,9,62,185,3,236,224,137,61,87,217,45,248,237,196,157,23,252,18,186,2,80,75,3,4,10,0,0,8,8,0,22,178,149,71,146,99,74,27,25,8,0,0,75,15,0,0,33,0,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101, -114,47,68,111,119,110,108,111,97,100,46,99,108,97,115,115,133,87,137,127,20,103,25,126,102,179,187,51,59,12,57,22,18,88,40,144,166,13,108,238,34,10,146,180,212,36,144,118,219,52,193,44,9,93,80,113,178,59,217,44,221,204,108,103,102,9,84,109,189,170,245, -110,181,30,85,164,94,21,91,143,150,182,108,40,208,226,85,84,60,90,173,86,91,252,23,252,23,212,231,155,221,236,17,86,204,47,249,142,247,251,222,227,123,159,231,123,231,203,149,127,159,127,5,192,118,252,83,101,99,133,176,3,57,209,220,47,26,91,101,227,40, -112,85,228,113,76,198,162,10,5,199,85,156,192,3,42,62,132,15,139,230,35,98,207,131,42,30,194,71,101,124,76,198,199,85,52,227,19,42,154,240,73,21,15,227,83,98,249,211,10,30,81,241,25,124,86,52,159,83,241,121,124,65,197,23,241,37,209,60,26,162,237,199, -20,124,89,197,87,240,184,140,175,42,248,154,138,205,248,122,0,222,207,68,187,130,111,168,120,2,223,84,241,45,156,84,176,83,76,190,45,140,156,18,146,83,10,158,84,240,29,5,223,85,240,61,5,223,87,240,3,5,79,201,248,161,138,211,248,145,140,167,101,60,35, -227,199,18,32,65,139,153,166,97,143,102,117,199,49,28,9,29,241,19,142,107,44,236,183,173,156,97,187,25,195,225,232,248,137,225,188,59,111,152,110,38,169,187,150,45,161,113,255,212,228,29,83,251,226,241,35,163,119,78,79,220,45,65,138,73,88,61,106,153, -142,171,155,238,140,158,205,27,13,34,74,9,171,70,166,199,198,246,77,29,137,199,14,237,163,104,91,179,132,96,214,74,167,13,90,217,56,110,217,233,129,180,173,167,178,198,192,162,173,231,232,113,96,220,91,28,146,208,196,121,86,56,204,88,230,132,190,96,72, -8,143,31,213,143,233,3,89,221,76,15,196,93,59,99,166,185,45,92,181,109,198,176,29,118,116,113,107,198,204,184,123,36,140,68,175,227,227,90,115,215,74,186,102,36,248,71,173,20,221,55,141,103,76,99,34,191,48,107,216,7,244,217,172,23,144,149,212,179,51, -186,157,17,243,146,208,239,206,103,152,199,77,245,28,239,181,22,205,172,165,167,24,247,13,73,203,156,203,164,243,182,177,50,193,222,9,26,162,194,179,146,42,41,72,216,18,45,6,103,26,238,192,244,84,172,20,106,198,26,24,203,100,13,47,76,89,79,165,108,195, -161,239,198,218,173,68,33,101,56,110,198,44,217,110,172,213,149,160,238,59,158,52,114,98,209,145,241,19,9,205,203,110,99,166,107,216,166,158,101,60,121,59,187,194,240,56,53,27,243,142,97,15,167,141,18,232,204,252,108,126,110,78,128,235,59,60,194,144, -204,252,194,148,33,194,111,202,217,86,90,68,55,106,229,133,81,82,230,46,90,181,242,174,132,182,114,60,147,121,55,151,119,153,122,67,95,160,117,63,115,196,120,215,215,120,37,203,76,35,41,130,229,14,95,134,235,173,101,253,152,89,173,30,38,56,201,124,86, -119,141,233,229,40,37,172,141,118,213,163,145,74,128,202,244,81,197,134,25,195,76,9,174,175,42,78,74,75,45,149,165,10,219,44,167,72,208,144,229,84,11,135,237,228,60,141,197,173,188,157,52,68,170,121,71,150,25,208,47,236,104,216,139,113,13,183,227,61, -26,134,49,162,97,84,52,119,99,156,137,157,119,221,92,127,78,80,67,4,47,227,167,26,126,134,103,37,236,185,14,173,110,254,255,119,87,184,124,78,198,25,13,207,227,5,25,47,106,56,139,130,134,37,156,211,48,141,9,25,47,105,56,143,11,228,231,114,78,71,60,64, -141,84,53,54,196,164,154,66,213,75,194,193,69,209,188,44,227,21,13,151,240,115,13,41,240,232,170,56,71,159,135,130,140,95,104,248,37,126,165,225,215,120,85,198,101,13,191,193,111,101,252,78,195,21,252,94,195,31,68,48,31,192,31,153,251,140,224,138,157, -207,185,70,74,198,159,52,188,134,215,37,172,41,195,61,89,38,174,132,200,114,22,218,23,117,167,189,74,177,95,68,67,53,169,95,198,159,53,252,5,111,200,248,171,134,191,225,77,13,127,199,235,26,254,33,18,238,193,220,127,172,4,186,86,154,149,192,108,42,78, -23,42,18,217,114,250,77,15,116,149,163,26,177,238,193,190,177,211,25,232,116,218,163,157,206,144,247,219,85,53,228,13,171,80,112,114,246,40,233,44,227,45,13,111,227,42,21,175,3,48,97,169,179,26,171,44,111,186,30,59,182,47,167,206,243,91,149,186,170,104, -138,12,98,58,210,134,91,226,209,9,9,91,163,117,42,99,189,107,212,81,183,222,86,34,240,10,85,91,249,58,175,248,172,168,142,225,238,53,230,244,124,150,23,117,99,85,193,171,217,231,217,208,170,249,199,123,37,194,213,109,238,41,206,155,151,111,121,165,200, -5,23,238,75,101,108,199,43,173,135,150,13,148,74,164,132,128,107,177,182,84,41,86,106,92,75,244,218,90,27,137,214,175,89,149,208,74,250,188,201,76,162,89,41,90,18,54,172,112,81,83,208,218,234,175,176,152,49,55,83,198,253,121,22,242,10,46,219,234,224, -82,255,27,214,200,4,85,85,71,9,235,170,50,84,91,54,215,212,17,179,22,219,94,29,15,68,15,143,116,197,106,40,115,96,190,184,180,58,153,183,5,2,203,243,218,74,91,148,210,252,234,140,19,171,92,206,234,234,189,159,209,214,9,163,74,76,255,57,49,163,86,61,70, -10,96,254,231,231,158,12,16,83,147,46,111,169,86,30,157,215,237,184,72,172,153,52,106,72,61,236,237,22,31,117,70,179,182,30,220,12,103,209,206,184,228,155,204,180,196,98,34,128,6,190,110,40,79,102,45,199,168,189,89,94,144,140,98,206,178,23,116,30,97, -119,157,35,28,30,95,89,24,234,221,51,220,200,247,227,118,190,221,222,137,0,54,96,55,6,57,30,226,187,208,135,91,57,191,173,106,190,7,97,241,125,225,56,44,62,49,94,63,234,245,1,238,217,139,125,108,199,56,115,185,215,207,126,125,247,18,164,238,158,179,240, -117,247,158,69,67,119,223,89,248,41,10,156,241,172,221,193,118,3,130,108,55,113,247,102,132,176,5,141,104,199,26,70,180,14,29,184,147,43,221,69,59,136,225,46,239,173,186,222,243,47,121,35,17,129,207,27,137,24,26,56,230,199,174,20,193,24,231,98,215,218, -112,240,28,228,203,104,188,0,37,33,45,33,116,14,106,197,123,35,119,1,157,124,114,111,165,215,168,231,81,43,234,149,60,74,184,7,19,220,45,108,78,115,183,216,223,212,91,192,170,2,180,131,221,61,189,75,88,189,210,92,15,205,245,114,220,231,153,107,47,170, -148,15,208,132,73,236,247,92,52,225,189,152,162,102,156,99,63,37,7,56,158,94,118,38,253,139,41,93,205,149,171,210,132,52,24,232,41,160,113,48,120,1,77,137,11,104,78,208,107,203,18,194,19,145,96,1,107,6,69,70,215,14,202,17,127,184,53,34,23,208,22,241, -23,176,110,48,208,178,173,249,162,50,168,132,118,169,145,64,68,41,96,125,98,103,200,247,36,38,207,33,82,192,134,39,208,250,60,54,134,111,40,96,211,5,108,78,132,183,44,161,253,82,155,218,26,122,88,223,165,182,169,107,113,227,66,232,241,83,104,237,126, -17,190,240,77,5,220,124,208,19,26,187,212,190,136,210,208,26,42,160,243,244,127,158,246,86,183,22,176,45,18,184,12,37,18,40,32,218,119,25,221,125,5,116,157,198,77,131,90,253,117,89,172,71,180,75,103,120,212,0,78,242,133,0,254,93,244,250,98,34,31,32,27, -196,127,76,62,50,51,128,119,97,21,118,98,35,118,145,19,239,38,74,187,185,50,200,209,16,185,112,27,145,223,195,132,222,142,4,121,161,147,19,247,145,13,14,185,248,32,217,248,8,83,249,40,97,56,73,102,60,69,110,60,67,52,159,37,0,47,80,227,60,101,175,82,118, -133,178,215,40,123,131,178,183,9,134,0,45,71,143,171,240,24,102,112,144,252,140,146,207,247,210,143,76,47,239,167,159,67,4,120,156,187,15,51,138,16,229,135,240,62,202,85,1,86,25,230,171,101,152,175,150,96,246,225,45,62,67,142,144,14,29,120,9,31,100,172, -126,158,237,77,204,34,201,190,154,4,124,224,148,88,44,72,160,176,215,153,72,255,120,184,155,84,190,39,220,195,118,34,220,203,118,208,31,238,19,93,32,220,47,186,96,120,64,116,114,248,150,102,229,101,108,79,52,80,171,33,158,240,247,196,19,129,72,32,158, -8,70,130,241,132,28,145,227,9,165,55,158,104,14,246,177,33,109,226,231,240,142,231,202,169,239,240,28,206,208,241,189,76,65,2,45,60,222,122,30,117,11,15,185,149,199,236,227,33,68,138,166,138,129,149,14,28,224,234,28,83,193,79,61,117,211,222,197,108,97, -2,230,189,139,41,174,111,134,35,63,173,140,224,40,255,2,180,53,68,168,70,152,222,62,22,158,172,151,94,31,22,188,56,76,66,45,74,139,143,208,239,0,154,21,250,218,65,192,213,255,2,80,75,3,4,10,0,0,8,8,0,22,178,149,71,192,25,62,198,80,0,0,0,78,0,0,0,35,0, -0,0,103,114,97,100,108,101,45,119,114,97,112,112,101,114,45,99,108,97,115,115,112,97,116,104,46,112,114,111,112,101,114,116,105,101,115,83,206,205,79,41,205,73,85,72,73,77,203,204,203,44,201,204,207,227,82,246,205,207,83,112,73,77,86,48,50,84,48,50,178, -50,52,179,50,49,81,112,118,13,81,48,50,48,52,229,42,40,202,207,74,77,46,41,182,77,47,74,76,201,73,213,77,206,201,228,42,42,205,43,201,204,77,181,229,2,0,80,75,3,4,10,0,0,8,8,0,10,178,149,71,36,217,150,101,206,0,0,0,28,1,0,0,24,0,0,0,98,117,105,108,100, -45,114,101,99,101,105,112,116,46,112,114,111,112,101,114,116,105,101,115,53,143,189,110,195,48,12,132,119,190,74,17,65,148,127,51,104,201,86,160,200,210,162,107,65,75,180,163,192,146,12,73,54,250,248,181,155,132,219,125,228,241,200,97,117,179,189,174, -126,224,164,67,12,12,195,1,190,156,231,92,200,47,90,73,108,80,41,84,136,141,172,223,228,94,96,162,247,174,188,91,173,186,118,176,198,178,237,42,57,54,21,81,111,16,135,186,59,159,251,150,104,164,166,103,84,53,181,112,139,185,4,242,172,45,111,40,166,68, -118,102,17,211,4,46,127,6,90,242,45,22,61,210,156,25,238,180,209,55,167,236,98,208,40,58,33,127,164,130,152,175,135,249,195,133,245,119,23,175,126,37,176,18,242,212,170,211,196,129,147,51,176,164,120,103,83,244,35,1,146,121,126,6,107,230,244,127,64,49, -180,15,23,132,237,177,228,66,153,181,18,40,95,224,233,56,208,31,80,75,3,4,10,0,0,8,8,0,10,178,149,71,0,0,0,0,2,0,0,0,0,0,0,0,15,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,3,0,80,75,3,4,10,0,0,8,8,0,10,178,149,71,144,200,244,150,60,2, -0,0,83,5,0,0,49,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,65,98,115,116,114,97,99,116,67,111,109,109,97,110,100,76,105,110,101,67,111,110,118,101,114,116,101,114,46,99,108,97,115,115,149,84,93,111,18,65,20,61,3,11,139,43,182,136,109, -173,223,208,15,229,163,116,219,62,153,66,72,8,209,104,66,170,17,210,196,199,101,25,215,109,96,151,12,67,163,127,194,223,162,47,52,209,196,31,224,143,50,222,89,144,80,150,180,244,97,231,222,57,123,239,185,115,230,222,221,63,127,127,254,6,112,136,35,3, -9,236,232,216,53,16,193,142,1,29,207,149,247,66,121,57,29,121,29,5,29,69,134,120,197,245,92,89,101,136,230,242,167,12,90,221,239,112,134,213,134,235,241,147,97,175,205,69,203,106,119,9,73,55,124,219,234,158,90,194,85,251,9,168,201,207,238,128,161,212, -240,133,99,58,194,234,116,185,105,119,93,179,214,30,72,97,217,178,238,247,122,150,215,81,100,117,223,59,231,66,114,81,102,216,184,204,245,181,255,159,239,232,38,68,149,86,171,92,37,54,221,30,35,12,199,185,198,153,117,110,153,93,203,115,204,183,20,162, -88,203,51,216,187,246,25,183,101,57,31,134,72,139,37,28,210,178,182,136,130,174,73,210,107,46,213,61,44,200,141,247,45,49,224,130,97,107,94,192,204,193,223,7,49,20,189,232,148,149,25,172,41,133,235,57,129,182,40,105,100,48,94,125,177,121,95,186,190,55, -208,177,199,112,171,233,58,158,37,135,130,174,236,96,105,54,162,202,7,116,31,42,173,227,176,138,106,24,186,66,76,168,11,70,211,31,10,155,191,118,85,31,179,87,245,109,95,213,73,194,192,109,134,204,117,215,149,68,9,251,73,152,56,72,226,30,14,25,138,55, -152,16,134,212,188,38,134,237,37,68,133,203,204,68,213,132,51,236,113,79,78,155,66,13,161,17,252,228,58,65,67,118,115,215,207,128,250,210,98,193,204,48,188,92,56,180,249,121,146,32,179,51,67,69,119,254,38,84,42,28,181,212,244,107,89,250,43,36,64,66,232, -223,17,33,75,205,161,53,73,187,26,89,70,54,86,184,0,251,65,78,20,119,104,141,7,96,26,43,180,38,199,1,88,69,138,236,221,75,72,154,44,163,206,173,81,158,162,251,70,86,35,187,249,11,145,143,23,136,158,20,74,35,104,133,82,113,132,216,222,8,241,239,211,10, -43,100,65,121,9,172,211,126,35,168,84,24,231,78,42,41,111,157,222,176,192,187,79,79,132,162,83,120,128,135,148,171,206,145,9,56,54,39,231,24,199,63,154,198,63,166,248,39,228,107,132,60,197,179,64,122,134,158,177,151,197,86,96,183,255,1,80,75,3,4,10,0, -0,8,8,0,10,178,149,71,50,95,101,143,166,0,0,0,232,0,0,0,40,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,49,46,99,108,97,115,115,133,140,65,10,194,48,16,69,255,104,181,90, -11,118,229,186,136,107,67,207,80,20,4,69,193,19,196,118,168,45,105,2,73,245,112,46,60,128,135,18,83,92,186,112,62,243,63,31,102,222,235,253,120,2,200,16,135,8,67,68,132,232,108,110,182,224,109,173,152,176,200,77,219,74,93,238,107,205,39,105,29,219,117, -35,239,146,48,223,232,66,25,87,235,234,192,221,213,148,33,102,132,165,177,149,168,172,44,21,139,66,213,226,231,121,149,17,64,136,119,90,179,205,149,116,142,29,33,233,145,66,73,93,137,227,165,225,162,35,164,255,72,73,234,57,3,124,103,232,5,223,2,140,124, -6,24,123,159,250,141,252,13,245,45,153,124,0,80,75,3,4,10,0,0,8,8,0,10,178,149,71,82,66,9,29,168,2,0,0,247,6,0,0,60,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,77,105, -115,115,105,110,103,79,112,116,105,111,110,65,114,103,83,116,97,116,101,46,99,108,97,115,115,157,149,93,79,211,96,20,199,255,207,54,186,173,235,100,160,32,190,50,23,148,189,32,99,136,128,128,38,130,47,49,78,52,193,96,130,87,15,172,153,53,221,83,210,22, -223,47,188,241,198,27,253,32,94,72,162,35,241,194,15,224,135,50,158,167,45,115,27,75,198,150,38,237,57,79,207,249,157,215,180,127,254,254,250,13,160,132,21,21,49,228,85,196,81,136,147,52,37,213,171,42,18,152,150,103,69,41,205,68,49,27,197,53,6,197,218, -117,13,75,68,49,199,48,244,216,147,159,112,219,209,237,13,151,187,58,131,246,64,8,221,94,51,185,227,232,14,195,92,217,178,171,197,170,205,43,166,94,220,49,141,226,154,85,171,113,81,41,27,66,247,253,38,142,64,150,41,202,138,33,12,247,22,195,66,182,31, -64,110,147,33,178,102,85,40,159,65,105,184,190,87,219,214,237,167,124,219,164,147,225,178,181,195,205,77,110,27,82,15,14,35,238,11,131,210,29,121,100,56,142,33,170,62,242,182,93,13,170,90,236,158,69,71,79,42,37,85,227,111,183,117,210,108,215,127,71,81, -178,229,151,252,21,47,154,92,84,139,27,174,77,110,203,185,45,134,48,183,171,50,191,35,47,25,146,150,104,65,108,117,64,116,128,246,215,253,132,37,214,45,113,24,42,209,50,223,213,78,185,119,15,211,26,32,101,137,38,147,187,162,66,181,103,115,155,81,92,103, -0,195,243,190,134,222,221,167,228,45,70,232,205,140,188,149,24,38,142,227,194,160,110,88,123,246,142,126,207,144,139,50,122,196,102,90,246,67,195,32,82,242,54,175,65,197,9,13,11,24,211,176,136,27,26,206,225,188,134,37,140,71,65,172,249,254,246,136,97, -170,151,22,51,204,246,222,64,134,76,247,118,48,76,30,99,56,126,163,99,134,115,184,67,170,55,240,93,83,151,97,102,178,61,47,140,234,181,98,175,166,11,151,33,221,205,25,105,250,128,197,33,87,105,88,78,131,36,5,33,57,33,58,25,34,237,62,105,33,122,38,242, -236,0,161,124,225,39,194,251,164,134,200,28,100,30,38,207,119,24,96,239,161,178,15,56,73,103,163,190,57,78,145,4,79,146,88,70,215,105,140,5,208,165,0,170,228,11,117,68,190,53,120,10,228,82,127,108,226,40,13,142,130,51,56,235,113,104,75,2,206,67,138,79, -25,32,153,255,129,112,29,3,133,169,58,148,239,109,184,79,30,46,237,27,54,112,201,0,39,37,149,164,16,201,23,48,30,128,111,6,9,198,37,152,114,140,182,67,63,55,229,24,111,64,227,141,28,211,184,20,160,22,60,61,64,81,142,207,254,183,79,149,238,236,11,98,236, -171,135,211,124,67,31,151,2,77,97,34,128,220,33,203,176,223,176,3,176,253,182,100,94,55,85,216,220,176,203,94,227,165,116,5,147,94,69,89,207,51,71,53,3,25,68,104,56,37,104,17,249,19,43,97,4,242,23,86,194,69,210,51,244,68,42,246,15,80,75,3,4,10,0,0,8, -8,0,10,178,149,71,188,172,77,50,145,2,0,0,131,5,0,0,61,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,79,112,116,105,111,110,83,116,114,105,110,103,67,111,109,112,97,114, -97,116,111,114,46,99,108,97,115,115,157,84,207,79,19,65,20,254,102,186,101,97,109,161,242,163,96,181,130,90,161,80,100,41,32,72,74,136,164,137,9,177,17,19,12,137,222,166,237,166,12,89,118,201,238,150,248,175,192,201,155,7,123,241,2,137,38,198,179,127, -148,241,205,118,173,66,107,106,56,116,222,155,247,190,121,239,219,111,222,244,199,207,47,223,0,20,241,204,192,16,230,13,24,106,209,177,160,99,209,128,134,37,181,152,58,150,85,154,108,81,199,138,142,85,134,129,45,233,200,96,155,33,150,159,63,96,208,202, -110,221,98,24,169,72,199,122,213,60,174,90,222,27,81,181,41,50,90,113,107,194,62,16,158,84,251,40,168,5,135,210,103,72,239,157,4,210,117,246,3,79,58,141,178,123,124,34,60,17,184,30,67,98,215,113,44,175,108,11,223,183,8,183,89,113,189,134,217,240,68,221, -182,204,154,45,77,194,30,11,167,174,154,189,22,158,111,121,185,222,149,74,12,122,45,220,81,211,185,124,229,72,156,10,211,22,78,195,108,35,75,221,145,249,93,58,227,134,213,138,138,125,23,160,147,94,33,17,252,67,215,11,8,199,222,253,222,172,92,107,180, -87,61,178,106,65,169,59,162,26,241,247,203,87,123,68,57,149,33,165,215,24,16,150,235,251,249,197,146,186,132,220,255,0,25,134,246,101,195,17,65,83,137,178,245,47,170,205,64,218,230,31,37,183,186,133,216,166,82,198,190,219,244,106,214,11,169,110,53,221, -213,110,73,29,74,32,129,100,2,79,177,174,99,131,225,121,95,142,101,225,91,187,142,111,57,190,12,228,169,213,61,30,211,125,16,170,227,163,4,38,144,102,72,93,231,205,176,113,195,105,186,82,172,45,22,195,120,47,181,24,30,246,191,9,154,24,219,114,26,193, -97,248,134,104,26,102,250,157,193,50,61,66,131,70,226,22,61,89,13,92,9,75,187,97,218,153,100,105,90,16,95,184,4,255,76,14,199,8,173,3,42,200,83,72,145,159,104,3,112,27,227,80,115,69,242,68,135,63,33,70,113,96,167,112,129,152,246,1,186,246,17,90,108,123, -241,239,221,186,150,61,131,49,161,157,35,206,91,217,115,229,158,33,174,181,190,66,123,203,46,17,47,16,122,160,213,105,124,159,254,67,192,71,49,204,199,144,229,227,152,229,19,200,243,73,20,249,20,86,121,38,36,180,214,110,26,17,82,222,36,166,66,146,59, -184,67,30,39,114,171,200,224,46,209,203,34,135,123,228,105,169,29,34,158,141,136,191,164,76,140,108,114,161,240,29,250,34,253,46,48,216,234,249,245,51,109,96,167,89,146,40,78,135,205,146,148,155,86,48,53,53,81,225,77,178,60,146,147,245,150,51,221,6,116, -10,198,169,96,142,242,49,60,14,241,179,152,11,109,30,99,100,51,20,31,66,1,163,228,61,32,139,212,32,221,96,1,79,144,249,5,80,75,3,4,10,0,0,8,8,0,10,178,149,71,232,35,13,242,71,1,0,0,75,2,0,0,49,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105, -47,67,111,109,109,97,110,100,76,105,110,101,65,114,103,117,109,101,110,116,69,120,99,101,112,116,105,111,110,46,99,108,97,115,115,149,145,205,74,3,49,20,133,79,250,51,163,181,182,90,109,43,234,194,238,180,85,7,215,149,130,136,130,48,184,176,165,251,116, -26,166,145,153,68,50,51,234,107,185,42,184,240,1,124,40,49,73,75,21,45,130,89,220,228,158,220,251,221,19,242,254,241,250,6,224,12,205,18,10,216,50,97,219,69,221,69,131,192,57,231,130,167,61,130,250,161,127,79,31,169,23,81,17,122,253,84,113,17,118,143, -134,4,133,75,57,102,4,85,159,11,118,155,197,35,166,6,116,20,105,165,230,203,128,70,67,170,184,201,231,98,33,157,240,132,224,196,151,42,244,66,69,199,17,243,130,136,123,151,50,142,169,24,27,200,133,10,179,152,137,244,234,57,96,15,41,151,162,75,224,198, -44,73,104,104,169,191,92,16,180,151,120,251,166,12,38,74,62,153,249,214,112,49,160,89,162,73,245,165,21,4,165,190,204,84,192,174,185,241,219,250,203,216,169,1,148,81,132,99,66,133,160,243,143,87,17,236,126,205,191,203,68,202,99,182,184,68,11,121,253, -11,102,229,64,204,4,29,93,157,245,116,158,211,187,211,238,76,65,94,236,253,138,142,37,171,54,117,229,14,86,245,169,49,171,210,250,154,165,56,40,99,93,51,12,171,50,103,221,232,25,121,189,187,237,206,241,20,185,159,176,61,221,180,111,97,7,179,178,5,204, -157,195,204,169,138,13,107,113,211,118,215,62,1,80,75,3,4,10,0,0,8,8,0,10,178,149,71,63,23,104,255,199,7,0,0,135,19,0,0,61,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36, -75,110,111,119,110,79,112,116,105,111,110,80,97,114,115,101,114,83,116,97,116,101,46,99,108,97,115,115,221,88,107,120,20,229,21,126,191,100,147,89,38,3,134,133,0,129,86,167,154,144,100,115,15,1,139,208,180,33,162,164,134,64,27,76,140,180,218,97,119,76, -6,55,51,219,153,217,4,236,197,74,91,237,221,94,208,54,86,123,177,8,218,122,129,74,18,66,188,212,94,176,162,245,214,162,79,255,246,121,250,60,125,250,223,159,173,61,103,102,118,179,155,221,176,137,63,251,231,155,243,157,239,220,190,115,251,206,238,197, -255,158,127,1,64,59,222,149,177,5,119,174,160,37,33,163,19,99,18,76,25,33,88,140,73,242,242,121,94,108,94,28,94,92,166,79,73,24,15,99,66,194,17,25,215,224,168,12,5,119,49,244,133,48,190,88,129,47,225,203,76,116,183,76,226,191,194,219,123,36,124,85,198, -122,124,61,140,123,101,108,195,125,50,190,129,111,242,201,183,100,124,27,223,97,194,239,134,241,61,198,220,95,129,239,227,7,188,252,80,194,143,248,248,56,31,63,32,227,24,30,148,240,99,25,117,176,194,248,9,127,39,121,121,40,140,159,242,247,97,25,143,224, -103,76,251,243,10,252,2,247,75,248,37,171,121,84,194,175,36,156,16,80,172,164,107,88,230,128,107,27,230,136,132,147,132,217,151,133,161,109,175,105,234,118,79,66,115,28,221,17,104,237,179,236,145,214,17,91,139,39,244,214,88,194,104,237,177,198,198,52, -51,222,103,152,250,126,205,118,116,187,38,155,127,135,64,185,175,65,224,234,203,176,250,60,68,93,17,155,71,22,96,241,84,196,179,24,137,165,204,113,53,87,151,112,138,184,125,19,6,24,33,208,82,220,214,44,122,54,117,92,75,164,248,150,149,125,135,181,113, -173,53,229,26,137,214,62,195,113,233,108,197,128,49,98,106,110,202,38,193,53,11,142,119,250,251,132,102,142,180,6,247,238,98,113,238,168,225,212,180,93,254,230,190,5,76,189,211,48,13,183,75,224,66,125,113,242,101,70,161,184,231,139,59,122,121,206,108, -24,20,8,245,88,113,242,214,21,76,210,159,26,59,164,219,7,180,67,9,194,68,250,172,152,150,24,212,108,131,247,1,50,196,222,18,88,119,147,105,77,152,190,85,57,209,220,94,220,128,194,172,228,91,217,50,187,237,145,212,152,110,186,2,187,234,243,195,213,176, -220,84,9,107,25,121,145,124,113,2,171,216,247,154,237,246,235,71,92,82,45,208,86,191,108,29,171,70,116,119,143,230,204,91,94,90,223,112,171,119,25,226,76,38,116,246,74,153,151,178,2,37,70,141,192,218,172,188,236,117,117,91,115,45,206,172,10,203,29,213, -237,125,65,25,42,73,47,180,233,109,94,178,229,69,62,200,16,9,143,11,64,224,223,255,15,233,89,156,186,221,75,225,146,35,109,188,180,243,210,193,203,22,94,58,121,217,202,125,96,9,98,40,96,3,86,202,142,233,55,24,156,230,235,242,104,90,56,104,10,246,160, -87,193,13,184,145,161,39,4,214,204,135,178,219,182,181,163,220,103,248,232,215,10,118,161,71,193,86,108,87,112,29,118,40,216,137,143,41,232,66,183,130,65,12,9,52,46,110,83,58,147,118,31,137,233,65,248,183,4,199,205,9,58,87,253,86,173,214,213,58,117,106, -220,210,29,213,180,92,213,213,238,212,85,205,84,211,25,223,66,253,113,62,227,247,29,58,172,199,200,178,223,224,73,54,239,41,5,79,227,25,129,157,221,166,170,143,37,221,163,25,54,117,66,115,212,164,109,141,27,113,61,174,222,97,217,106,108,17,213,45,18, -78,43,56,131,223,42,184,5,55,43,120,22,67,10,206,98,72,194,148,192,182,162,46,223,107,56,14,101,149,159,57,116,229,160,127,84,21,196,179,205,211,36,181,223,250,32,134,42,152,193,57,9,179,10,206,99,78,193,115,120,70,194,243,10,94,192,139,10,126,199,193, -232,218,155,74,184,6,213,106,70,186,163,78,232,182,190,100,249,47,225,247,18,254,160,224,143,236,131,63,225,66,142,239,253,242,81,240,50,187,253,207,120,69,193,69,188,42,176,126,33,197,174,148,145,136,235,54,245,216,3,163,186,170,224,53,252,133,151,215, -5,54,164,213,25,142,26,215,147,182,30,35,159,196,213,102,34,122,3,175,72,120,83,193,91,44,252,109,252,85,194,223,4,212,98,149,170,224,18,222,17,184,246,3,246,106,129,142,37,182,142,28,166,213,5,112,205,203,234,65,2,77,203,105,32,244,166,23,47,125,129, -186,226,189,50,104,52,212,218,105,45,167,108,24,211,168,211,111,47,240,70,29,236,91,88,117,244,108,21,120,122,170,10,189,111,44,60,161,155,35,238,168,167,171,151,94,151,220,25,134,208,90,60,190,128,59,173,134,94,157,8,61,70,221,137,132,53,145,121,143, -232,177,150,12,103,55,23,249,101,19,195,191,167,192,193,37,56,35,255,241,94,170,3,43,180,88,76,119,156,154,246,206,54,106,217,61,75,214,149,25,0,10,120,114,225,165,242,94,29,26,11,201,105,233,167,244,182,2,142,47,254,180,229,141,5,139,61,192,84,190,142, -113,23,233,220,188,52,6,50,142,98,54,24,140,180,145,250,134,252,161,118,99,38,168,233,62,149,21,220,176,17,140,16,244,104,229,48,103,141,22,145,124,44,101,197,168,230,240,220,67,6,155,222,103,109,125,67,126,82,113,200,226,241,249,225,166,138,108,185, -62,104,65,100,253,144,102,155,94,93,230,50,103,98,147,137,247,86,142,247,246,37,12,37,129,24,195,106,221,79,50,220,33,155,239,199,131,183,150,76,234,38,165,126,115,193,193,112,145,102,186,99,1,253,162,21,57,79,31,118,173,116,179,89,83,192,20,114,92,146, -119,9,30,210,200,25,55,218,86,42,57,100,112,197,174,206,241,255,128,206,222,91,153,131,32,22,91,31,179,198,51,177,175,189,156,71,210,169,55,8,149,126,146,118,210,79,222,114,68,120,164,32,40,194,83,133,247,165,193,194,251,210,108,225,125,105,238,160,249, -239,122,130,75,176,187,178,146,135,21,143,179,132,103,23,58,249,36,237,30,68,41,97,128,166,104,227,20,74,162,98,6,165,209,57,132,134,103,80,54,133,242,104,211,20,164,104,243,20,194,209,234,208,20,86,68,171,9,43,159,241,36,222,68,235,149,144,104,196,60, -1,89,60,138,42,241,24,54,138,147,184,74,156,66,173,120,28,141,226,9,244,17,77,39,202,88,62,246,98,31,224,65,108,119,137,7,177,229,165,30,196,182,135,60,136,173,47,35,235,246,227,83,25,27,37,143,190,63,58,141,138,135,176,105,14,202,112,100,101,232,121, -172,26,46,141,158,133,52,112,14,87,204,160,242,197,198,105,172,78,31,71,242,143,9,46,111,156,197,154,18,12,145,160,181,167,51,183,216,200,30,16,79,65,18,79,147,245,167,177,89,156,65,151,120,22,189,226,172,119,131,117,190,246,204,13,250,241,105,12,144, -109,2,7,112,115,96,227,16,89,79,227,54,106,73,75,120,26,85,147,168,102,125,179,88,39,48,137,149,115,88,63,204,206,221,112,58,87,245,42,190,190,96,170,243,80,197,115,158,58,197,23,20,168,19,60,37,6,74,58,60,165,160,104,248,74,158,204,200,41,103,188,120, -41,139,63,156,225,191,37,109,164,120,128,28,73,78,22,101,236,200,73,212,101,89,232,123,173,186,160,215,86,240,254,28,54,250,90,55,245,249,108,31,162,209,117,26,31,246,128,207,133,78,164,111,126,101,58,2,87,21,142,192,44,221,19,123,155,102,241,17,86,91, -69,192,213,130,102,175,107,250,27,155,167,81,115,234,253,127,249,98,106,47,160,131,160,146,115,216,60,135,58,74,199,250,72,195,52,162,44,109,26,141,145,38,31,102,66,130,166,65,188,45,254,190,117,22,109,89,10,54,164,21,180,247,243,77,136,174,227,212,251, -255,36,80,158,15,194,117,20,6,136,11,88,35,94,166,172,189,72,177,127,21,183,139,215,48,33,94,199,113,241,6,38,197,155,120,88,188,133,147,226,109,92,18,151,240,158,120,7,255,17,239,82,44,254,238,57,188,139,220,127,156,114,118,152,178,162,20,247,96,19, -110,197,65,146,253,30,5,225,51,94,134,255,131,42,197,199,145,243,131,192,116,209,24,248,89,220,6,81,9,170,71,45,8,177,77,178,36,14,98,180,177,169,185,58,84,93,54,3,113,102,65,152,31,241,180,238,241,233,50,89,169,224,16,213,183,240,160,88,80,97,10,226, -65,133,41,208,131,10,83,112,135,87,97,12,141,96,212,235,7,134,167,225,48,62,234,37,89,57,182,225,24,174,133,140,143,211,247,19,33,254,27,236,24,101,125,9,110,167,47,42,195,88,79,223,175,129,255,105,59,134,199,66,242,255,0,80,75,3,4,10,0,0,8,8,0,10,178, -149,71,28,107,22,177,205,2,0,0,219,6,0,0,55,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,79,112,116,105,111,110,67,111,109,112,97,114,97,116,111,114,46,99,108,97,115,115, -149,85,109,79,211,80,20,126,110,215,209,81,58,24,111,83,240,5,68,12,27,111,101,128,32,12,17,156,98,22,23,48,153,33,241,99,25,205,44,233,90,210,118,196,159,225,15,225,139,95,192,72,98,248,236,143,34,158,219,54,115,176,74,225,67,123,207,61,231,57,207,185, -247,188,180,127,174,126,253,6,80,192,142,140,52,230,100,244,242,87,15,230,37,44,200,16,177,40,99,9,203,18,94,74,88,145,145,226,251,20,94,73,88,227,240,117,9,69,9,27,18,94,51,116,109,24,150,225,109,50,36,114,249,125,6,177,100,31,234,12,125,21,195,210, -119,155,141,3,221,249,172,29,152,164,25,168,216,53,205,220,215,28,131,239,67,165,232,125,53,92,134,204,222,177,103,216,86,201,110,28,107,142,230,217,14,131,82,182,44,221,41,153,154,235,234,132,88,170,216,78,93,173,59,218,161,169,171,53,211,80,9,219,208, -172,67,30,230,147,230,184,186,51,121,147,163,200,32,213,252,29,5,250,144,187,133,32,240,44,198,35,242,101,226,180,125,185,192,48,17,239,208,130,47,210,93,27,6,247,26,168,28,105,39,154,106,106,86,93,173,122,142,97,213,139,129,141,32,83,185,54,227,222, -193,145,94,243,138,157,26,126,10,225,219,194,117,170,208,198,45,5,9,84,14,248,116,177,89,43,20,121,213,38,239,2,100,232,174,26,117,75,243,154,60,163,149,255,29,181,233,25,166,250,175,12,27,241,89,218,36,106,185,106,55,157,154,190,99,240,182,200,118,132, -159,231,212,10,50,232,87,240,6,91,18,182,25,86,239,216,18,65,150,219,155,43,27,109,224,252,83,18,222,42,40,225,29,117,229,205,66,49,108,197,134,44,105,174,94,182,92,221,114,13,207,56,209,59,99,143,197,32,20,140,224,61,195,120,92,214,56,110,148,161,112, -239,185,184,118,177,160,114,12,67,81,165,163,22,143,111,11,42,93,93,247,130,32,52,168,253,185,124,91,27,84,117,222,146,183,220,37,96,97,24,110,143,111,154,116,166,128,46,65,131,65,105,207,85,162,236,209,13,87,204,71,141,197,181,209,10,231,174,83,147, -47,99,129,190,111,189,52,60,125,244,117,20,33,240,150,163,221,0,237,84,90,105,174,144,156,62,135,240,131,4,1,131,244,238,226,74,118,133,33,146,149,0,128,97,60,4,159,64,42,81,232,252,157,200,146,180,174,204,156,33,113,1,241,11,59,71,242,39,186,46,33,237, -206,118,168,214,197,11,164,248,190,123,110,68,60,131,124,218,138,214,139,4,23,49,40,208,157,4,193,143,186,28,48,135,81,185,244,8,143,253,147,172,224,9,73,220,243,57,158,98,140,124,167,232,98,227,36,137,153,109,58,221,179,240,116,31,201,66,188,72,79,207, -92,162,103,150,158,51,40,167,145,87,28,15,128,173,96,105,76,16,57,243,165,73,146,132,12,248,24,133,196,107,180,10,97,206,88,116,206,178,1,160,69,152,36,194,28,217,19,200,251,248,105,204,248,235,44,30,208,58,65,121,76,83,41,178,148,217,23,180,34,147,34, -141,74,63,178,81,250,65,169,88,197,232,95,80,75,3,4,10,0,0,8,8,0,10,178,149,71,228,98,213,39,225,2,0,0,110,7,0,0,63,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,85,110, -107,110,111,119,110,79,112,116,105,111,110,80,97,114,115,101,114,83,116,97,116,101,46,99,108,97,115,115,189,85,203,82,19,65,20,61,61,201,36,97,50,64,8,16,241,133,136,40,201,16,8,225,161,34,136,34,165,165,85,20,90,133,178,96,215,36,83,227,232,100,134, -154,76,148,95,240,95,92,72,21,143,42,23,126,128,255,224,198,215,194,141,27,55,186,176,188,61,153,10,17,66,37,113,225,230,222,238,219,247,156,190,125,238,205,228,253,239,183,239,0,228,113,91,65,12,227,10,58,48,209,65,171,156,48,147,194,228,197,193,148, -130,105,204,68,113,53,138,107,12,114,217,227,158,30,197,28,67,252,17,119,203,186,187,38,2,12,234,3,219,214,221,101,139,151,203,122,153,97,98,197,113,141,156,225,242,162,165,231,10,150,153,91,118,74,37,110,23,87,76,91,175,226,70,234,224,243,12,33,238, -26,12,201,149,103,252,5,207,89,220,54,114,107,158,107,218,6,29,197,11,135,88,134,225,163,204,62,79,177,142,159,32,145,5,211,54,189,69,6,61,125,156,177,57,65,123,197,103,214,25,194,203,78,145,138,235,22,41,171,149,210,166,238,62,230,155,150,46,94,228, -20,184,181,206,93,83,236,131,96,216,123,106,146,72,3,79,236,231,182,243,210,126,184,229,153,142,253,151,156,45,148,112,18,152,158,223,101,232,222,125,94,94,114,141,74,73,183,61,82,55,157,217,160,176,99,83,134,235,173,234,219,222,146,144,123,50,157,105, -183,79,138,99,31,210,222,105,160,110,219,140,49,94,227,35,114,202,222,178,116,49,98,55,24,192,240,234,63,52,176,121,118,222,111,178,180,61,41,76,94,152,41,97,166,25,70,90,1,211,203,214,156,138,91,208,239,153,162,253,169,99,57,19,226,141,42,122,209,39, -204,188,138,110,36,84,244,32,169,66,65,151,138,97,12,70,177,160,226,38,22,163,184,197,48,247,207,211,193,48,213,20,219,0,212,211,32,150,109,71,100,250,225,54,23,138,97,52,221,106,51,134,154,13,1,67,39,47,22,239,110,123,46,95,231,86,133,246,253,141,198, -181,1,213,177,43,49,68,31,194,14,250,88,134,144,20,13,161,85,82,180,200,247,212,37,242,17,72,162,125,52,177,253,180,43,209,46,76,190,95,99,7,144,180,177,61,132,180,236,30,194,218,248,30,228,29,58,144,144,34,155,130,76,51,254,17,50,251,4,133,125,70,55, -251,130,62,246,21,167,232,76,171,18,96,0,103,0,127,37,46,100,254,74,92,41,249,43,81,76,136,162,103,113,46,184,58,75,94,100,73,225,215,181,123,34,34,194,190,249,188,106,245,52,224,101,56,143,193,0,153,11,144,178,182,143,200,155,35,224,239,117,96,185,6, -190,64,202,84,193,115,228,165,147,192,63,124,112,170,154,80,123,145,140,139,254,139,152,24,239,128,102,145,114,196,21,9,109,151,212,218,69,104,31,81,114,242,33,163,34,88,216,79,196,217,175,186,146,18,85,86,234,72,47,46,7,92,27,164,32,233,139,152,54,150, -29,63,0,219,57,82,213,7,31,63,83,205,169,85,21,195,149,64,231,24,70,3,157,99,72,251,58,139,85,198,239,140,132,49,159,45,139,78,242,195,20,137,99,22,106,88,252,99,206,226,52,85,121,137,60,18,98,108,102,113,61,172,252,1,80,75,3,4,10,0,0,8,8,0,10,178,149, -71,34,122,201,90,146,5,0,0,153,13,0,0,38,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,79,112,116,105,111,110,46,99,108,97,115,115,157,86,91,115,211,86,16,254,148,24,203,177,69,18,12,196,225,30, -32,128,99,19,220,22,2,148,164,80,8,183,64,72,128,164,73,67,160,69,177,85,71,84,145,92,89,230,210,251,189,253,11,188,244,173,229,165,15,180,83,194,164,204,116,250,196,67,103,250,39,250,67,218,126,71,86,100,217,178,75,166,147,137,206,158,213,158,221,111, -119,191,61,242,31,127,255,250,27,128,151,241,109,28,59,48,37,99,58,142,54,76,117,96,59,222,232,192,12,102,133,244,166,120,204,37,112,3,243,9,220,196,45,241,120,75,198,219,9,220,134,42,99,65,70,62,142,206,234,169,130,144,52,33,189,35,164,162,120,44,198, -160,199,112,71,40,223,141,193,16,170,37,113,214,20,15,75,70,73,198,123,18,100,171,228,232,150,89,150,208,53,126,71,189,171,230,42,142,110,228,166,52,103,88,66,199,148,94,52,85,167,98,107,18,246,214,191,29,169,110,13,213,44,230,166,28,91,55,139,195,39, -121,66,81,237,98,101,73,51,157,233,7,37,30,218,16,176,26,53,212,114,153,38,155,26,117,35,25,113,50,81,208,202,121,91,119,193,72,72,134,221,83,89,208,74,182,150,87,133,201,172,106,155,212,74,136,235,102,190,178,64,157,216,72,55,8,186,104,91,149,210,172, -238,44,74,56,220,8,218,178,139,185,162,173,22,12,45,151,55,244,220,168,181,180,164,154,133,113,221,212,38,221,200,110,18,209,17,221,212,157,147,18,82,233,0,140,49,71,179,213,5,67,27,30,152,145,16,25,181,10,154,40,25,79,78,84,150,22,52,123,90,188,19,192, -173,188,106,204,168,182,46,246,158,50,106,121,105,181,233,253,126,1,92,80,174,83,199,178,25,53,226,44,234,236,194,158,23,99,172,175,161,143,75,66,79,125,112,182,192,3,208,44,143,22,29,204,174,217,86,212,33,94,212,156,201,85,2,109,72,15,132,40,180,175, -81,215,34,108,98,81,45,159,246,184,35,97,40,29,34,206,192,90,234,114,60,116,78,144,107,77,71,251,211,107,50,83,2,56,153,114,39,243,63,27,36,238,166,213,124,235,169,27,181,181,114,197,96,102,91,66,111,207,84,116,163,160,9,6,116,210,119,157,179,163,233, -176,175,53,161,76,18,214,105,195,176,238,5,177,182,167,7,56,30,91,253,87,87,8,72,47,25,90,192,36,190,58,97,90,65,194,102,55,183,240,196,41,212,95,168,205,216,80,184,195,107,154,178,100,186,129,44,130,79,71,211,255,195,151,75,196,41,171,98,231,181,243, -186,160,123,79,200,234,144,240,170,224,32,108,210,180,22,225,162,90,94,100,20,5,59,177,75,70,89,129,131,189,10,246,136,71,70,104,42,10,238,226,158,140,251,10,30,96,76,193,251,248,64,66,119,99,79,100,124,168,224,35,124,204,14,214,92,143,235,101,182,59, -213,162,219,10,246,97,191,130,79,240,169,130,3,66,250,12,159,139,237,23,244,49,95,107,66,223,96,31,47,181,91,10,210,24,96,225,231,107,119,29,117,95,98,84,193,87,248,90,193,55,34,118,223,139,42,85,135,124,114,225,142,150,119,92,82,204,172,226,118,95,204, -88,58,123,31,153,158,187,122,142,61,10,95,5,18,98,186,119,105,177,208,117,189,15,92,102,201,176,150,159,26,242,123,66,187,207,168,17,211,93,234,135,165,10,137,135,215,215,81,128,24,213,130,160,99,58,108,43,8,29,85,75,37,205,164,193,96,211,105,105,61, -110,81,67,51,139,130,193,172,193,152,132,237,233,209,255,178,142,57,86,85,37,34,22,10,28,33,14,115,144,173,163,150,97,16,147,160,164,11,203,214,150,172,187,26,118,243,243,187,131,223,250,40,146,130,101,96,163,184,107,163,190,77,16,205,223,247,243,159, -156,112,229,3,222,202,174,115,77,10,46,250,118,89,126,198,37,18,121,144,242,33,106,126,71,59,34,92,47,101,158,66,202,60,67,219,220,83,180,63,65,36,243,51,214,61,65,180,166,145,179,43,136,73,184,114,112,5,29,18,30,98,27,133,184,196,243,137,137,204,47, -136,12,174,64,105,195,236,163,127,254,250,137,222,218,145,227,115,15,98,124,238,164,255,20,186,208,139,30,230,178,155,88,134,137,229,60,165,49,90,188,68,139,12,45,134,145,224,239,153,253,60,153,230,155,87,112,152,248,136,10,71,48,4,184,210,78,28,37,242, -99,148,21,174,85,205,113,63,175,87,41,157,160,151,106,86,57,238,132,205,58,1,237,177,107,144,115,139,40,148,251,220,160,85,39,235,188,0,85,39,35,212,189,134,147,158,147,107,92,5,8,57,147,21,149,120,236,231,21,119,213,3,60,156,113,93,245,84,205,124,172, -178,215,153,26,86,161,233,247,177,158,114,195,188,206,167,8,115,140,26,97,211,145,217,136,196,106,160,182,64,160,67,60,158,11,96,238,240,2,73,56,221,212,201,250,102,78,14,187,248,154,57,57,131,81,207,201,159,94,194,218,51,116,178,233,93,227,172,94,247, -115,40,89,177,46,99,195,44,215,228,115,164,179,203,216,248,29,226,217,238,190,101,108,154,205,38,55,139,119,194,40,233,10,201,30,207,54,245,16,189,141,182,189,174,201,50,182,212,0,158,32,37,193,86,198,216,196,46,238,122,217,135,93,44,208,126,118,98,144, -25,30,97,158,175,17,230,89,254,93,198,57,92,39,121,230,112,145,191,66,47,5,202,175,121,9,197,112,139,118,231,92,2,156,199,5,47,181,83,193,94,118,135,170,51,193,94,78,182,232,165,152,42,225,236,34,249,90,117,118,194,43,118,55,115,140,114,78,190,135,28, -121,132,72,251,143,13,68,155,10,212,187,219,175,247,165,230,126,216,183,31,90,248,153,109,234,231,114,243,228,146,161,228,230,153,220,205,22,201,29,240,146,75,251,76,26,242,64,201,153,200,19,164,66,206,110,211,153,26,192,35,251,120,198,125,30,5,167,47, -217,56,125,90,147,233,3,174,52,29,93,185,241,176,222,114,116,39,220,123,100,210,115,162,121,21,73,9,39,188,184,182,242,106,18,98,102,5,219,40,214,174,168,78,174,192,18,47,31,147,213,177,2,85,74,249,216,82,222,197,91,27,103,161,201,250,227,124,149,210, -53,87,186,254,47,80,75,3,4,10,0,0,8,8,0,10,178,149,71,156,108,92,207,167,1,0,0,166,3,0,0,56,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,79,112,116,105,111,110,80,97,114, -115,101,114,83,116,97,116,101,46,99,108,97,115,115,149,82,93,75,27,65,20,61,179,89,179,118,77,77,180,154,226,119,140,41,70,41,110,20,95,36,34,104,64,20,130,10,145,60,248,54,73,134,237,200,102,86,102,39,37,255,163,191,164,79,133,62,248,3,250,163,138,119, -54,1,17,11,105,118,30,206,157,187,231,158,203,61,119,254,252,253,253,12,224,16,95,124,100,176,233,195,197,166,135,146,135,109,134,236,169,84,210,156,49,100,170,123,109,6,183,17,247,4,67,190,41,149,184,25,244,59,66,223,243,78,68,153,197,102,220,229,81, -155,107,105,239,227,164,107,190,201,132,97,225,246,201,200,88,221,113,157,8,221,50,220,208,175,220,181,82,66,55,34,158,36,130,40,199,205,88,135,65,168,121,47,18,65,55,146,65,35,238,247,185,234,217,62,163,186,202,59,145,58,195,124,172,40,212,230,70,12, -205,185,14,61,148,25,230,222,244,169,85,247,38,75,191,21,245,99,69,90,131,190,80,134,225,162,218,124,228,223,121,16,113,21,6,45,163,165,10,235,83,43,206,135,194,92,241,228,85,149,204,124,72,27,81,229,83,36,140,240,176,195,0,134,221,234,100,237,195,186, -221,132,51,172,49,84,254,135,77,141,90,241,64,119,197,165,180,75,41,190,227,28,216,9,115,152,65,214,67,133,225,104,250,85,48,20,94,93,186,237,60,138,46,13,249,117,26,151,24,202,147,71,97,40,77,34,185,37,122,194,46,236,151,133,99,103,34,87,61,186,5,132, -100,49,102,246,127,193,249,73,129,131,217,148,100,125,255,129,15,20,231,70,4,248,248,8,184,180,54,44,164,184,136,79,41,46,97,57,197,162,205,23,44,115,101,44,126,66,232,140,197,217,191,197,139,35,194,72,60,141,86,177,150,150,173,167,252,13,106,15,202, -101,232,108,97,206,245,145,39,44,16,126,38,68,97,246,5,80,75,3,4,10,0,0,8,8,0,10,178,149,71,91,120,110,152,148,7,0,0,199,17,0,0,38,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,80,97,114,115,101,100,67,111,109,109,97,110,100,76,105,110, -101,46,99,108,97,115,115,149,87,217,127,27,87,21,254,70,219,200,210,68,177,85,199,142,221,38,85,211,56,150,101,57,134,36,208,120,169,139,227,38,77,28,219,41,113,73,112,90,10,19,107,34,79,144,103,148,209,200,137,91,74,75,161,208,133,165,165,5,154,150, -125,51,139,129,164,52,9,38,63,150,55,248,241,206,27,111,188,240,87,16,190,59,51,26,75,214,184,49,47,51,231,222,57,247,59,231,124,103,185,210,63,254,251,199,63,3,248,48,222,79,160,19,134,12,51,129,16,140,22,228,81,150,113,41,129,168,187,176,196,163,34, -195,78,160,197,221,169,38,177,132,203,73,92,193,178,120,60,35,227,89,25,159,75,160,21,70,2,219,241,92,18,159,199,101,25,207,39,241,2,190,16,199,139,50,190,152,224,177,47,37,208,142,151,100,124,57,129,110,24,113,124,69,188,95,142,227,21,241,126,85,104, -188,38,78,126,53,137,175,225,178,88,126,93,0,124,67,198,235,113,188,145,64,15,190,153,196,155,120,75,232,124,75,60,190,45,30,111,201,248,142,132,237,102,217,214,77,163,114,100,121,214,182,116,163,200,157,169,139,234,146,58,88,181,245,210,224,180,90,30, -145,208,50,171,23,13,213,174,90,154,132,147,141,95,71,221,101,73,53,138,131,46,192,200,148,105,21,7,139,150,90,40,105,131,243,37,125,240,113,213,170,104,133,9,115,113,81,53,10,83,186,161,157,114,44,142,140,17,57,85,182,180,138,102,216,238,86,165,209, -248,172,102,83,229,193,198,157,0,131,14,144,165,45,154,75,90,193,7,74,105,87,108,75,29,183,138,213,69,226,115,163,181,14,103,74,175,8,232,189,27,182,54,193,142,141,234,134,110,143,73,232,204,214,41,156,176,53,75,61,95,210,70,250,206,72,136,76,152,5,77, -120,207,240,102,170,139,231,53,235,9,241,77,66,122,202,156,87,75,103,84,75,23,107,111,179,197,229,156,38,132,66,147,77,9,33,125,175,132,246,58,239,28,99,182,105,241,155,82,118,248,116,3,149,144,221,42,221,140,195,244,206,236,217,120,38,72,59,98,47,232, -149,0,221,38,124,234,202,102,141,246,246,32,134,36,116,52,210,176,92,174,81,113,56,64,127,244,238,238,137,180,140,4,101,99,75,103,69,198,226,182,89,43,248,246,108,95,80,18,148,75,85,211,214,198,141,194,164,169,11,162,131,147,31,116,50,86,241,144,101, -87,168,8,238,171,118,185,106,75,232,106,58,112,164,170,151,10,154,72,173,172,87,142,233,86,133,90,210,57,145,217,160,240,2,43,116,116,203,186,129,254,182,44,168,149,90,61,237,200,54,107,244,209,155,214,5,213,171,185,211,110,167,145,32,30,27,55,150,107, -39,187,178,117,5,59,97,150,74,218,188,195,183,56,189,189,100,22,167,180,37,173,228,247,103,71,176,178,132,92,224,135,77,2,31,8,182,25,28,250,185,13,68,213,162,219,122,7,181,21,53,251,232,134,185,146,174,85,79,253,100,217,215,180,185,73,0,219,212,66,193, -65,60,163,150,170,218,38,244,179,92,163,75,238,247,22,234,215,8,127,58,64,247,238,229,255,127,132,171,184,67,181,102,175,167,105,214,4,160,211,215,196,172,89,181,230,181,99,186,104,240,142,38,248,253,194,105,5,135,241,54,9,93,39,233,184,90,89,224,133, -162,96,0,251,155,62,112,240,43,188,111,15,40,56,132,3,18,238,89,255,58,110,89,234,178,32,88,193,71,240,81,25,87,21,188,131,119,101,124,87,193,247,240,125,5,63,192,15,37,100,238,230,55,51,182,53,86,20,252,8,63,150,241,19,54,196,70,238,101,252,84,193,207, -240,115,9,7,189,113,56,156,233,169,228,51,141,23,145,187,215,120,91,137,189,6,192,83,231,47,178,144,21,204,224,148,130,21,252,130,87,207,38,83,131,119,69,62,163,224,151,248,21,135,70,175,130,41,76,43,152,0,249,253,53,86,101,252,70,193,39,49,167,224,183, -248,29,71,121,221,140,96,167,20,213,82,205,171,163,87,230,53,143,135,157,174,79,153,222,158,74,111,198,48,237,76,65,187,192,232,11,251,69,198,46,200,184,166,224,58,86,21,188,135,167,20,252,30,171,205,228,54,49,39,33,156,21,117,145,110,158,81,156,195, -186,119,181,177,84,26,154,166,238,202,75,55,239,114,88,114,250,204,144,91,7,157,173,29,49,156,69,227,48,119,137,36,68,130,157,235,207,158,182,6,67,238,207,140,109,13,27,13,107,86,37,141,56,211,251,112,182,25,188,121,39,208,131,216,5,211,90,84,137,49, -20,208,182,79,126,48,200,250,205,162,150,203,154,81,88,31,124,141,131,108,243,171,37,62,111,26,182,170,139,232,119,4,196,32,8,108,15,154,164,12,188,40,232,216,23,116,40,40,204,84,227,216,227,121,78,44,225,120,161,48,94,42,81,112,75,31,15,240,87,106,39, -127,68,71,144,22,29,15,9,131,92,133,240,33,174,217,232,254,250,32,215,135,54,172,217,232,254,250,33,36,249,62,140,33,202,195,128,52,128,48,100,238,188,146,187,5,41,119,27,161,185,91,8,223,64,132,98,148,98,236,6,228,117,49,78,177,133,98,226,6,146,253, -107,80,36,76,231,215,176,77,194,85,156,164,144,146,240,87,108,159,185,141,86,234,180,13,71,6,110,34,189,134,123,36,12,71,187,162,158,94,70,72,142,98,251,112,44,247,62,34,93,177,174,200,26,118,132,113,118,229,206,191,86,238,188,119,157,206,132,49,194, -231,1,40,124,118,51,228,29,252,173,223,65,169,147,63,205,119,50,228,123,49,137,251,48,139,93,176,177,27,47,226,126,188,132,12,94,38,73,163,60,113,156,1,217,72,225,97,140,33,134,167,209,139,71,240,49,254,199,152,37,226,56,142,16,111,146,248,19,120,148, -118,30,194,199,157,175,33,65,1,142,226,24,224,72,143,17,69,194,9,202,10,223,238,206,164,79,226,73,74,156,28,124,146,66,124,130,86,132,78,127,186,35,246,39,116,206,133,115,140,75,190,133,157,179,115,17,33,38,29,49,42,196,184,16,255,128,174,107,14,140, -8,210,61,218,227,56,238,154,234,247,220,8,137,113,230,102,9,255,225,59,198,247,233,219,232,38,183,247,78,71,198,92,254,135,35,130,61,135,217,67,66,242,152,141,238,122,7,137,124,250,190,155,216,117,54,159,222,237,188,186,162,117,171,240,216,202,157,191, -231,111,226,254,107,62,221,251,157,202,232,67,28,57,36,232,69,150,21,151,103,173,29,100,208,195,36,125,156,117,118,156,20,78,114,103,154,53,38,60,22,4,103,177,7,143,83,138,178,210,70,28,50,35,194,83,159,204,211,164,88,144,25,231,201,211,76,66,136,232, -199,241,4,105,11,215,17,44,180,206,248,4,159,165,196,65,236,17,124,130,59,34,65,109,185,254,155,200,156,21,236,50,250,7,66,88,245,105,76,56,10,194,157,71,28,199,58,220,3,190,19,109,204,247,24,225,36,156,251,0,216,120,48,236,36,97,79,222,5,246,73,60,229, -229,234,77,190,5,3,125,4,219,83,215,33,221,181,14,105,159,201,177,51,30,188,138,104,100,117,229,206,191,195,171,126,10,58,72,162,168,167,110,82,177,135,36,236,165,175,189,244,88,152,206,17,180,155,14,9,131,162,101,51,126,221,246,249,238,244,225,83,172, -247,250,186,21,59,159,246,105,253,12,37,94,118,94,252,21,162,132,133,142,104,67,58,187,55,68,231,90,167,243,127,195,206,219,232,153,75,239,139,56,213,220,47,10,246,22,122,255,146,95,175,218,180,19,97,129,77,166,81,190,64,39,23,28,39,51,46,96,157,67,46, -63,41,182,172,104,189,16,229,243,152,247,152,26,116,152,3,162,162,73,54,182,68,169,174,37,162,30,160,27,69,129,79,141,70,221,40,30,245,178,168,8,16,70,145,101,245,92,223,144,192,50,75,251,82,93,2,21,223,65,5,69,199,65,48,0,221,67,52,188,4,238,110,224, -101,70,148,93,222,153,104,125,52,49,176,238,111,202,9,90,76,156,42,167,210,146,159,45,34,248,118,118,59,211,72,114,164,9,199,231,20,90,29,74,196,217,139,248,172,103,251,13,207,246,80,127,109,118,250,245,147,173,171,31,186,50,176,134,92,136,219,41,81, -183,92,244,135,196,4,253,231,122,232,110,49,61,195,33,249,44,221,121,142,183,192,243,156,251,47,248,238,237,226,40,125,216,41,166,4,123,191,86,76,67,190,203,67,142,163,34,67,37,7,115,241,127,80,75,3,4,10,0,0,8,8,0,10,178,149,71,139,65,53,108,124,1,0, -0,11,3,0,0,58,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,80,114,111,106,101,99,116,80,114,111,112,101,114,116,105,101,115,67,111,109,109,97,110,100,76,105,110,101,67,111,110,118,101,114,116,101,114,46,99,108,97,115,115,157,146,75,79, -194,64,20,133,207,5,4,68,124,63,80,195,162,236,192,4,26,19,117,227,35,81,140,43,162,36,24,247,67,59,150,49,109,135,12,3,9,255,74,87,38,46,252,1,254,40,227,20,170,49,216,68,227,44,238,233,156,57,223,244,118,166,111,239,47,175,0,246,177,91,64,22,27,121, -108,230,177,149,71,41,135,237,28,118,8,217,19,17,10,125,70,72,87,107,119,132,76,83,186,156,176,220,18,33,191,30,6,93,174,110,89,215,55,206,90,75,58,204,191,99,74,68,243,216,204,232,158,24,16,142,90,82,121,182,167,152,235,115,219,241,133,221,86,242,129, -59,218,72,159,43,45,248,160,41,131,128,133,110,180,107,83,134,35,99,114,117,76,88,245,248,103,104,124,211,215,66,134,132,141,106,173,245,192,70,204,246,89,232,217,29,173,68,232,153,232,206,143,232,37,215,76,248,220,37,148,19,214,6,142,18,241,142,133, -142,28,42,135,95,137,168,229,189,63,245,214,136,58,40,34,135,60,129,218,132,98,127,74,213,141,246,9,23,29,174,173,216,138,116,242,102,235,94,42,75,247,184,213,29,10,223,181,166,13,88,85,222,240,26,86,189,29,140,163,220,105,48,30,49,127,200,107,13,194, -193,127,14,141,112,56,131,157,119,7,90,177,223,56,84,48,103,238,63,26,25,80,244,97,166,206,155,153,109,148,140,206,237,61,131,158,204,67,10,5,83,179,19,115,29,11,166,22,167,1,163,139,19,124,9,203,49,92,143,225,244,90,234,113,6,45,125,67,211,95,232,74, -2,154,158,69,203,137,232,106,2,154,153,69,43,9,168,249,119,39,169,245,15,80,75,3,4,10,0,0,8,8,0,10,178,149,71,50,108,87,182,74,2,0,0,4,5,0,0,70,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97, -114,115,101,114,36,67,97,115,101,73,110,115,101,110,115,105,116,105,118,101,83,116,114,105,110,103,67,111,109,112,97,114,97,116,111,114,46,99,108,97,115,115,165,83,93,111,18,65,20,61,51,124,44,224,98,145,182,248,89,197,138,150,47,187,165,250,98,32,141, -74,98,66,36,106,66,211,247,1,6,156,102,217,109,118,151,198,191,226,127,224,197,151,154,248,96,124,246,71,25,239,44,27,76,11,6,19,67,152,123,231,206,185,231,206,61,119,246,231,175,111,223,1,52,240,60,3,3,79,50,72,233,37,129,61,189,148,13,84,116,184,106, -160,110,224,169,129,125,134,100,75,57,42,56,98,136,149,43,39,12,241,182,59,148,12,27,93,229,200,119,211,73,95,122,199,162,111,83,36,223,117,7,194,62,17,158,210,251,40,24,15,62,42,159,225,65,91,248,178,227,248,210,241,85,160,206,101,47,240,148,51,110, -187,147,51,225,137,192,245,24,204,142,227,72,175,109,11,223,151,148,240,186,235,122,99,107,236,137,161,45,173,129,173,44,194,78,132,51,212,85,63,8,207,151,94,105,13,101,147,193,24,132,59,186,198,94,185,123,42,206,133,101,11,103,108,205,145,205,229,72, -165,67,57,238,89,160,92,167,161,251,89,2,44,142,15,169,179,161,26,141,24,88,231,10,251,251,254,169,28,4,205,229,136,102,231,159,14,46,19,71,103,250,164,97,192,98,64,72,183,182,249,70,83,207,162,244,47,64,134,116,79,141,29,17,76,181,18,173,191,93,117, -26,40,219,250,35,95,107,185,251,35,162,202,244,220,169,55,144,111,148,30,110,97,169,220,190,78,50,145,193,53,19,7,104,152,56,4,41,153,187,74,101,98,19,91,6,158,49,188,252,223,49,95,98,159,55,196,176,181,170,35,134,221,245,106,49,108,70,143,230,216,237, -140,29,215,147,186,62,195,246,138,7,164,7,154,94,160,25,138,235,232,73,18,131,62,55,202,162,15,48,14,174,117,162,157,73,59,139,44,13,31,137,234,87,240,47,228,112,100,105,77,234,32,79,226,58,249,230,28,128,13,228,161,159,9,73,24,37,143,8,29,39,155,175, -213,47,16,59,218,249,140,196,206,76,251,241,217,130,41,175,17,60,133,36,79,35,195,51,48,185,25,178,86,231,153,17,171,246,182,81,8,43,229,113,147,60,78,119,48,113,11,183,17,203,189,162,154,119,162,154,111,17,163,31,144,173,214,126,32,81,167,255,5,146, -179,149,23,47,206,129,139,18,89,220,197,189,176,68,22,59,228,241,28,72,137,98,68,252,130,44,143,148,96,171,149,40,204,1,11,194,4,17,62,164,243,24,118,67,252,35,148,66,251,24,55,194,62,56,201,94,67,142,238,126,159,44,114,169,223,80,75,3,4,10,0,0,8,8,0, -10,178,149,71,133,165,180,23,103,18,0,0,198,42,0,0,38,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,46,99,108,97,115,115,157,89,11,120,84,213,181,94,43,243,56,147,147,3,36, -145,0,131,60,34,15,201,99,146,0,66,128,240,50,68,84,148,4,48,8,134,135,120,72,78,146,129,201,76,152,153,0,81,168,162,212,42,245,81,171,162,96,125,87,169,173,86,69,73,136,81,172,173,239,98,109,171,125,221,62,108,239,237,245,222,91,219,123,111,123,219, -122,107,91,233,191,246,153,153,204,76,14,38,246,227,227,236,61,123,175,189,214,218,235,241,239,181,119,222,252,248,185,19,68,52,139,79,230,210,14,250,127,249,252,69,62,31,201,231,175,26,253,45,151,254,78,31,235,228,161,83,58,237,96,210,169,137,89,227, -28,157,116,105,93,58,25,236,214,217,195,94,153,214,52,246,105,156,155,199,58,231,233,84,192,134,78,249,60,66,227,145,58,21,241,168,60,206,231,130,60,46,228,51,228,51,90,227,34,157,14,240,24,31,143,213,105,60,143,211,216,175,211,36,30,239,227,51,229,247, -4,249,76,20,138,73,58,93,195,147,125,92,44,35,103,201,103,138,140,76,245,241,52,104,201,211,125,124,182,198,51,116,10,48,139,228,18,141,75,117,170,98,246,113,153,180,229,242,9,200,138,10,249,84,10,131,42,225,59,83,62,179,68,79,181,110,118,30,159,195, -115,228,83,160,241,92,157,22,115,181,198,243,116,90,202,243,53,94,160,113,141,78,203,120,161,78,181,188,72,136,22,107,188,68,167,243,197,10,75,117,186,80,102,22,243,185,26,215,234,116,177,48,92,198,115,124,92,39,86,57,79,102,150,251,104,167,72,57,95, -62,23,232,124,33,175,144,222,69,26,95,156,71,235,120,165,143,235,53,110,144,238,42,17,185,218,199,107,68,239,75,124,220,40,191,215,106,124,169,78,87,8,227,117,92,32,189,245,226,138,128,244,2,26,95,230,227,38,217,215,6,157,90,121,163,244,54,249,120,179, -88,231,114,157,183,240,21,58,155,188,213,199,205,162,9,252,209,162,179,197,173,62,110,147,201,118,141,131,76,196,100,172,8,135,173,104,93,200,140,197,172,24,211,152,85,157,241,96,36,220,24,143,6,195,109,117,145,142,78,51,106,198,35,81,141,183,49,77,174, -51,99,214,138,112,204,10,199,130,241,224,78,43,155,136,41,223,94,157,190,110,59,211,184,75,195,219,195,145,93,97,123,114,181,25,141,89,209,198,184,25,183,52,14,65,226,197,167,153,235,96,42,112,24,14,51,21,213,7,99,49,136,182,103,107,163,109,106,10,123, -169,109,141,91,81,123,52,166,113,132,105,180,26,57,63,24,141,197,27,187,182,66,175,14,51,220,2,6,203,172,214,72,212,202,26,215,184,51,101,128,218,93,102,212,202,144,139,60,200,203,24,192,126,141,116,107,49,157,177,106,245,218,21,171,26,182,52,212,214, -47,223,178,186,118,237,218,229,151,52,48,249,87,110,51,119,154,85,93,241,96,168,42,106,181,89,187,171,86,155,113,104,21,94,200,52,42,98,43,187,172,59,201,99,84,26,117,189,217,9,154,220,198,96,91,216,140,119,69,177,195,229,153,179,139,236,159,33,51,220, -86,101,51,88,184,50,18,109,171,106,139,154,45,33,171,170,57,20,172,74,236,109,101,48,108,217,202,46,92,2,158,5,102,40,20,217,85,31,220,109,181,36,204,197,196,27,176,3,53,158,225,47,204,20,182,88,157,81,171,217,84,190,128,20,40,15,27,218,178,131,145,42, -53,180,62,26,196,48,88,159,49,77,66,41,170,150,158,23,140,153,91,67,22,44,238,93,20,12,7,227,75,152,92,37,165,235,152,220,117,145,22,75,54,11,181,26,186,58,182,90,209,181,66,8,81,43,35,205,102,104,157,25,13,202,239,196,160,59,222,30,132,26,83,62,97,111, -182,103,68,124,73,74,175,132,74,34,47,63,123,144,201,211,41,75,152,230,149,108,28,108,197,210,108,81,138,127,75,154,64,112,200,107,30,248,9,193,14,108,0,157,203,119,55,91,201,128,196,30,230,151,164,81,173,128,38,178,195,225,137,51,148,194,9,127,49,205, -25,210,26,211,6,101,15,184,120,173,112,11,50,6,238,94,129,208,138,36,227,87,44,239,160,190,128,132,102,19,205,194,218,72,66,182,203,20,14,57,193,105,200,176,180,136,84,251,65,214,47,76,13,103,110,19,113,215,153,189,49,7,183,58,109,94,87,11,19,121,94, -57,244,214,51,55,61,38,51,170,186,59,147,145,229,228,13,135,164,146,148,89,57,108,218,97,121,115,242,64,6,2,129,18,145,20,171,13,15,228,227,180,146,65,140,156,2,94,87,140,86,33,189,91,135,27,204,78,108,220,102,52,10,119,186,67,86,24,77,65,115,54,108, -124,114,250,37,160,37,21,44,2,26,131,88,196,50,209,173,209,138,99,193,57,153,35,139,134,135,95,122,167,96,206,165,49,179,13,78,244,167,123,166,182,179,19,17,110,103,21,18,223,136,100,32,244,232,72,180,197,138,38,147,200,30,21,181,0,111,173,202,21,201, -145,252,52,181,86,6,99,162,169,107,187,213,13,216,216,105,134,186,32,212,99,133,227,81,249,189,220,110,139,50,145,121,154,26,150,85,145,174,184,4,160,163,134,200,64,156,67,29,234,56,200,100,113,126,114,24,52,35,51,148,134,114,158,16,172,129,214,213,97, -238,102,154,154,109,65,199,240,157,150,181,161,211,144,45,116,218,134,211,49,227,184,122,238,208,199,147,227,58,247,182,72,16,17,182,168,36,109,125,93,36,20,178,154,149,199,157,66,218,1,172,60,56,38,196,201,233,72,182,106,235,54,48,17,220,83,147,177, -148,43,178,101,192,21,49,43,85,200,120,183,118,181,182,138,79,198,13,18,180,76,205,136,184,86,41,31,50,207,247,1,134,139,202,100,99,75,157,119,36,147,195,220,212,167,206,232,84,42,234,102,115,179,21,139,77,155,59,115,38,211,244,146,161,65,160,20,5,64, -206,238,153,3,43,231,203,202,115,134,179,114,80,209,146,100,177,64,88,228,37,126,204,82,170,44,24,62,195,65,197,133,111,17,232,237,66,66,111,140,116,69,155,81,195,9,142,143,25,196,162,82,24,24,116,23,221,109,208,65,186,211,160,47,208,109,6,221,65,119, -50,141,79,242,94,213,21,239,236,138,195,166,150,217,97,139,208,56,110,208,15,184,203,160,195,188,19,31,122,80,62,247,0,16,7,54,120,161,25,107,199,38,113,226,59,232,40,11,119,105,188,219,224,110,190,210,160,135,233,49,166,226,161,142,131,65,236,145,198, -26,95,101,240,30,222,43,12,63,35,159,171,153,170,135,60,246,28,235,90,89,125,141,198,251,12,190,150,175,211,120,191,193,159,229,235,13,254,28,223,0,156,203,142,45,131,111,228,3,136,131,138,10,131,63,207,55,49,85,12,41,52,189,234,22,89,55,227,24,168,168, -216,120,249,226,205,229,6,223,194,7,12,190,149,191,96,240,109,252,69,131,111,231,59,0,104,37,75,99,165,9,138,197,149,101,6,223,201,7,133,232,46,131,239,230,67,0,109,53,47,211,50,75,135,196,105,121,137,177,138,205,149,101,72,203,52,56,77,86,155,203,163, -209,72,212,224,195,162,244,216,193,89,27,12,181,72,66,51,246,117,15,127,201,224,123,249,62,131,239,23,67,60,192,119,24,252,32,63,100,240,195,124,200,224,47,211,61,6,63,194,143,106,124,196,224,175,8,183,108,7,14,202,54,131,31,227,175,38,3,34,19,191,37, -126,190,157,225,224,181,81,203,130,131,153,102,13,179,128,27,184,78,137,117,191,38,159,199,13,126,130,191,158,220,103,2,212,195,219,173,150,84,112,206,27,38,243,236,75,156,193,79,242,83,25,91,169,141,70,205,110,57,50,52,126,26,129,17,40,54,232,151,244, -43,131,143,138,1,159,225,103,13,62,198,79,105,220,99,208,79,185,215,224,227,89,203,83,167,136,193,125,18,113,238,233,177,233,225,140,192,179,49,218,224,231,248,6,131,251,249,121,8,153,174,188,244,2,2,41,86,92,44,11,12,62,33,105,56,198,25,141,53,126,81, -232,191,129,34,37,173,70,3,218,182,153,33,20,187,93,29,56,172,83,133,56,106,47,123,235,197,51,166,199,102,20,7,99,197,102,8,8,208,210,93,220,130,34,32,108,181,84,138,22,47,137,153,191,105,240,183,36,27,106,234,204,112,56,18,47,54,91,90,138,35,105,107, -77,172,13,39,71,154,109,154,88,220,140,198,139,119,5,227,237,197,51,42,102,84,26,116,11,221,170,241,203,6,191,194,175,106,252,154,100,196,245,76,27,135,201,177,56,18,14,117,23,55,71,194,113,51,24,134,162,157,237,102,24,219,137,6,155,139,155,219,225,177, -102,132,88,12,241,41,178,84,179,101,70,229,39,6,172,237,124,141,95,55,248,13,81,100,66,201,166,165,123,54,117,94,85,27,2,223,189,27,83,189,138,45,155,203,74,13,126,147,17,188,83,134,140,37,92,14,206,29,146,104,200,231,131,5,67,178,56,221,75,194,112,226, -221,249,157,129,105,246,167,191,71,13,7,138,79,243,70,49,119,120,112,58,232,201,98,184,249,156,253,112,193,20,248,52,151,165,225,224,125,230,163,71,249,233,233,29,82,47,253,188,233,142,197,173,142,65,15,9,246,113,188,112,160,172,207,58,168,85,89,63,122, -208,45,127,131,186,230,103,161,22,202,61,175,25,19,236,146,10,104,227,224,186,176,116,112,153,63,34,3,186,192,64,21,252,224,52,174,164,244,116,165,163,255,52,133,171,232,52,214,249,198,143,153,237,195,40,132,134,190,74,14,125,23,158,165,164,21,14,214, -2,245,84,48,113,101,7,180,102,108,47,237,42,95,56,120,20,184,220,110,198,26,172,221,113,245,160,131,186,209,29,86,63,70,151,148,58,21,223,249,29,102,247,86,185,189,71,227,201,219,100,81,137,67,89,187,65,222,39,118,116,153,161,88,22,65,210,93,32,88,49, -200,106,255,188,77,52,156,209,205,237,226,220,220,88,215,214,88,34,162,139,74,86,56,150,226,35,36,232,211,182,176,193,97,11,255,204,237,219,241,157,102,100,66,152,24,89,189,215,204,28,198,115,64,214,179,135,22,12,183,88,187,229,93,192,141,45,173,16,31, -175,112,222,154,174,32,74,37,43,211,50,39,215,124,90,217,121,137,51,43,118,177,220,154,189,166,186,244,2,93,28,121,159,166,90,147,130,63,30,73,221,221,75,28,85,31,217,102,197,81,245,12,168,175,219,21,83,200,18,52,243,134,172,112,91,188,93,133,41,12,144, -23,9,55,68,194,73,7,230,43,202,228,54,150,139,126,174,54,169,204,206,118,138,61,167,192,78,3,11,85,210,185,112,158,35,152,218,162,145,174,206,245,65,145,91,152,14,13,242,228,33,113,55,99,232,204,79,68,104,22,178,36,207,74,53,231,133,176,218,80,232,19, -224,7,233,162,99,67,169,135,131,130,140,28,183,31,96,70,102,34,160,109,208,243,172,88,115,52,152,124,237,235,148,39,140,249,14,54,25,166,149,188,219,173,110,101,158,145,3,147,245,166,88,199,35,1,9,191,248,212,107,138,162,241,65,252,58,251,141,197,139, -174,29,62,246,43,201,192,11,65,122,8,12,1,235,233,47,41,19,156,50,123,32,216,60,173,161,174,24,180,26,237,100,77,28,164,195,140,221,196,251,192,130,79,165,107,102,80,59,162,35,92,174,171,234,50,102,135,86,90,241,159,241,119,133,20,174,69,213,237,125, -128,81,29,42,198,70,224,171,21,110,182,50,108,100,47,175,183,23,45,116,224,92,159,228,55,42,141,155,252,205,8,152,210,98,197,130,81,171,37,117,15,19,4,232,194,132,214,140,112,85,183,243,79,72,122,135,191,138,208,89,180,131,154,136,200,75,227,165,120, -70,47,71,110,239,196,244,69,213,191,29,255,113,145,87,253,131,170,45,148,123,62,81,254,56,185,43,226,247,40,208,226,218,142,239,151,240,107,49,185,209,195,104,89,63,121,154,142,146,183,151,180,94,242,61,173,24,220,139,175,142,150,104,41,141,164,115,233, -62,244,12,155,156,238,167,7,136,20,171,7,19,172,54,147,71,209,78,44,235,165,92,176,211,155,122,41,239,24,185,208,53,154,202,221,189,52,226,24,241,0,227,66,72,38,90,134,239,2,176,171,163,9,116,158,18,48,198,102,146,16,32,189,187,232,33,136,216,71,15,211, -151,49,103,107,157,163,168,114,203,202,143,211,200,30,26,245,84,138,173,87,233,183,42,141,85,110,138,85,46,61,66,143,98,254,8,250,178,237,175,224,255,195,244,24,185,132,169,235,32,244,207,3,27,119,63,229,55,245,83,65,83,217,179,228,234,163,66,166,94, -58,163,151,70,215,247,83,81,83,89,128,123,105,76,67,121,31,141,197,213,199,237,119,247,209,56,166,67,124,82,122,126,166,111,208,248,26,79,133,223,211,67,103,30,226,39,252,158,194,9,61,52,241,16,229,247,211,164,38,89,58,185,225,8,223,139,225,226,30,58, -235,16,141,7,165,223,3,226,41,61,52,181,198,235,247,246,208,52,16,236,1,193,116,69,80,233,247,228,47,238,161,179,171,189,54,101,17,40,102,8,173,230,215,252,248,229,190,66,173,45,193,162,11,176,168,84,45,58,75,209,186,61,9,82,176,245,123,188,41,186,201, -71,169,236,48,21,129,186,28,212,135,41,175,159,2,240,84,197,139,88,2,162,26,175,108,219,239,237,163,202,28,68,204,24,225,229,77,72,84,218,209,187,9,222,53,154,162,212,18,148,251,42,250,169,10,140,102,22,206,234,161,217,66,60,187,135,206,145,118,106,141, -207,239,235,161,57,135,168,208,239,75,110,23,170,208,1,25,158,219,224,169,206,45,202,21,147,85,63,68,243,177,43,252,146,125,205,168,209,51,89,234,9,150,122,138,229,220,134,253,185,124,228,212,203,71,104,41,116,201,73,87,55,49,127,132,166,15,165,151,16, -233,202,101,243,26,142,124,60,179,162,135,230,7,36,158,92,42,158,142,82,0,223,141,52,142,54,209,84,196,120,45,93,78,23,209,22,90,75,87,144,137,127,219,105,43,117,83,51,93,77,45,116,19,89,72,177,86,68,89,27,61,75,237,244,18,5,233,187,180,141,126,6,170, -247,40,68,31,82,7,157,162,48,143,160,8,143,165,78,158,72,59,184,152,162,92,74,113,158,71,93,220,72,59,121,35,237,226,109,212,205,157,116,37,239,165,171,248,0,237,225,71,105,47,63,142,223,199,104,31,63,79,215,241,171,180,159,223,166,27,248,3,186,145,127, -79,55,243,31,233,86,254,43,221,198,31,211,237,57,146,254,18,251,61,72,176,110,100,195,87,233,107,248,222,73,147,233,113,122,2,189,71,144,108,50,166,65,51,195,158,133,46,54,157,6,105,83,232,235,244,36,233,28,67,206,63,133,21,185,208,106,171,154,245,65, -110,110,162,87,74,175,211,211,160,211,160,131,189,214,135,157,253,1,214,122,18,191,107,249,57,122,6,61,15,149,243,59,176,196,49,73,245,28,119,50,15,209,123,4,250,225,214,192,191,69,110,29,71,150,78,229,95,81,31,61,7,155,247,39,49,70,81,61,159,145,173, -54,196,189,128,254,9,122,49,129,58,115,49,34,25,175,149,185,33,166,108,0,8,108,224,186,27,74,28,74,3,46,45,5,92,7,157,89,228,12,98,113,47,88,220,231,192,98,31,146,253,37,155,5,187,161,185,134,177,77,130,27,189,180,160,190,188,161,226,68,181,219,85,237, -41,242,20,185,31,66,74,22,121,102,215,120,3,201,220,170,201,193,118,23,230,208,250,253,30,196,239,47,2,125,180,136,169,161,194,6,19,26,91,145,192,146,197,130,48,129,30,90,114,228,212,251,101,3,49,57,5,214,38,32,153,15,182,153,4,187,204,68,91,13,47,172, -129,31,214,195,207,27,224,55,209,119,19,252,53,9,113,96,123,69,71,36,127,19,171,92,192,242,18,250,22,104,220,84,64,211,225,159,39,176,195,53,160,120,153,94,193,216,98,64,174,248,204,165,56,36,177,115,19,189,170,176,211,135,200,127,13,222,207,73,121,202, -30,121,67,25,241,77,250,182,109,17,215,42,240,3,154,242,91,253,180,180,169,188,151,206,5,124,214,2,86,151,53,1,5,235,122,233,188,134,138,20,190,246,209,114,152,162,159,206,135,233,46,168,113,87,40,107,212,0,195,18,246,56,41,189,132,65,188,54,155,11,133, -205,10,176,81,72,136,140,191,40,201,228,98,48,89,137,204,214,108,46,185,254,220,4,151,117,210,75,64,180,46,32,82,237,126,128,166,248,125,78,24,211,71,245,96,118,132,38,15,76,79,24,60,125,234,81,191,175,176,225,56,173,130,20,168,176,90,216,190,74,121, -138,247,97,210,10,215,96,192,237,207,245,235,125,116,137,75,232,103,34,32,228,160,104,148,61,139,118,94,9,6,165,221,36,233,37,180,211,138,60,130,79,213,199,105,109,181,7,225,33,75,46,29,188,164,51,181,100,157,88,161,143,214,171,229,74,248,153,129,194, -203,220,47,80,83,147,2,104,212,186,141,61,180,17,27,90,16,72,238,103,19,182,82,4,208,219,92,120,185,189,41,79,6,121,147,59,193,209,94,120,234,38,132,225,150,167,83,33,120,37,2,75,64,38,23,9,236,71,10,151,66,187,217,72,224,213,8,11,19,105,27,70,154,238, -66,154,74,150,221,15,173,78,32,244,254,5,1,246,115,132,209,251,8,151,223,33,132,62,66,208,124,76,39,89,167,183,0,137,223,225,124,122,155,231,208,119,249,92,250,30,215,209,247,185,141,222,225,93,244,46,223,74,63,228,87,232,199,252,58,253,132,79,130,75, -18,222,14,162,98,56,41,96,69,215,0,152,37,100,115,33,251,49,122,11,188,53,72,191,157,190,67,111,35,60,223,167,105,0,187,39,49,251,59,132,246,247,212,138,213,208,245,40,194,221,75,53,100,67,148,7,178,13,5,126,26,79,82,105,113,12,208,216,6,184,255,62,189, -139,177,53,224,168,198,36,168,147,105,129,222,15,232,135,8,249,92,126,153,126,68,63,70,18,248,249,89,250,9,52,112,209,108,190,7,218,222,70,110,236,236,5,250,169,74,51,73,154,57,104,109,61,127,150,210,243,231,0,85,91,214,47,48,102,243,120,35,197,227,61, -164,165,46,47,203,137,250,231,151,104,161,7,93,212,79,87,192,153,102,189,123,73,249,107,228,45,92,179,178,172,143,182,166,23,38,52,61,81,152,212,120,38,30,166,220,0,206,252,230,245,1,57,236,90,164,231,2,178,252,8,158,181,6,192,165,82,210,86,244,129,38, -34,115,36,164,22,208,175,1,30,255,14,160,121,31,64,243,159,40,5,255,11,149,219,111,104,57,125,160,188,177,4,218,4,80,110,253,43,253,27,246,230,71,63,1,250,56,42,127,141,117,164,122,239,195,182,2,23,203,232,63,192,35,7,220,133,207,157,233,160,175,232, -127,131,214,134,250,15,0,178,71,233,183,9,144,109,135,101,100,215,39,202,235,3,39,150,184,170,221,69,238,137,15,209,174,64,145,123,118,141,71,33,171,39,81,139,248,251,169,181,169,176,45,145,0,158,198,227,212,222,75,65,84,56,146,228,219,146,243,219,179, -231,143,82,72,44,211,209,67,225,195,9,154,72,54,205,126,55,0,251,198,126,90,220,36,165,103,47,117,214,7,20,248,164,227,247,164,138,84,42,187,149,94,238,64,18,1,222,11,12,28,47,213,52,2,223,63,209,104,250,51,32,253,67,154,79,127,129,109,62,162,203,232, -111,40,34,254,78,123,48,119,45,140,114,11,51,61,206,56,49,216,69,207,227,168,73,66,251,104,148,24,71,213,49,155,131,12,16,104,207,65,127,175,130,118,23,236,124,165,130,118,55,14,132,17,42,174,221,56,13,167,165,160,253,68,10,218,79,36,160,253,22,248,87, -114,34,39,223,135,76,249,239,196,233,88,133,86,60,35,22,118,63,158,85,103,87,167,157,139,30,250,31,97,136,197,255,75,191,119,88,236,202,46,210,157,23,255,193,81,114,206,240,36,255,31,253,209,97,49,15,67,50,236,245,167,212,173,168,90,205,16,141,63,131, -118,244,80,20,88,238,62,66,110,215,51,84,86,24,59,78,241,103,40,244,180,170,33,6,138,132,106,228,200,60,244,254,172,36,125,136,172,22,140,28,69,93,184,175,137,98,23,162,221,141,59,91,55,218,43,209,46,67,123,21,218,61,104,247,130,199,103,208,94,173,252, -184,131,246,185,117,186,22,237,117,24,159,132,118,63,218,207,162,189,30,243,69,104,63,135,246,6,180,55,186,115,232,0,218,207,131,254,38,180,55,131,110,29,208,244,29,111,238,63,0,80,75,3,4,10,0,0,8,8,0,10,178,149,71,95,15,62,210,163,2,0,0,41,7,0,0,51, -0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,65,102,116,101,114,79,112,116,105,111,110,115,46,99,108,97,115,115,173,149,109,79,211,80,20,199,255,183,27,235,232,6,27,40, -136,207,11,130,64,11,148,161,162,136,49,81,124,8,201,68,19,116,137,188,49,119,107,29,213,174,53,119,69,241,35,248,93,124,33,137,74,162,137,31,192,15,101,60,183,171,163,178,145,130,49,77,122,207,57,247,220,223,57,231,222,115,219,159,191,190,253,0,80,198, -138,6,21,211,26,178,152,233,39,73,87,49,171,33,141,121,13,38,22,84,148,85,44,50,228,234,126,179,201,61,171,226,120,54,195,120,197,23,13,179,33,184,229,218,102,221,117,204,39,92,180,108,107,117,223,103,133,33,115,203,241,156,224,54,195,228,116,178,251, -76,149,33,189,234,91,4,47,72,195,250,118,179,102,139,167,188,230,146,101,184,226,215,185,91,229,194,145,122,100,76,7,91,78,139,33,127,231,101,96,139,199,111,2,199,247,164,186,230,121,182,88,117,121,171,101,147,106,30,140,28,139,25,38,33,38,226,235,41, -235,98,147,191,175,217,27,1,23,65,219,200,48,50,93,121,197,223,114,211,229,94,195,220,8,132,227,53,86,102,54,25,82,92,52,100,114,93,147,12,3,190,23,67,168,184,194,48,212,150,219,81,105,50,160,26,54,123,144,123,196,74,46,162,139,45,247,223,143,242,207, -249,222,186,239,253,169,38,247,87,6,119,123,213,150,28,47,30,73,197,85,6,48,172,29,225,152,147,201,229,176,21,148,157,5,249,42,51,76,28,101,9,131,182,225,111,139,186,253,192,145,173,49,218,229,51,47,139,204,35,135,188,124,93,203,163,31,154,138,37,134, -229,68,250,51,239,181,231,191,243,122,156,222,216,97,83,50,198,117,21,55,242,88,198,77,134,185,99,245,32,195,236,113,182,159,97,241,248,221,65,55,56,121,87,25,166,186,78,244,176,243,42,37,249,49,124,232,213,235,255,161,97,226,173,248,175,233,118,197, -165,27,204,45,235,254,78,32,120,149,187,219,246,33,31,129,42,74,244,197,204,66,182,255,176,236,41,146,250,160,200,62,35,203,0,105,15,73,83,104,204,233,108,15,138,110,124,65,106,151,84,5,131,244,30,68,138,86,214,208,199,234,208,152,133,2,217,70,219,238, -40,226,4,16,74,18,203,232,57,137,145,8,186,68,163,244,82,82,31,59,172,12,228,37,220,138,49,148,14,67,33,203,169,144,49,134,179,17,227,17,173,160,232,40,124,71,250,185,161,127,70,74,102,216,247,233,0,176,25,2,75,109,215,14,176,16,1,165,116,142,36,133, -228,243,184,24,161,239,70,53,107,146,106,124,69,70,223,167,106,114,134,9,100,89,43,150,170,214,33,107,109,114,81,22,62,30,241,238,145,143,140,159,209,141,61,176,221,3,25,190,136,101,152,233,112,50,184,20,110,155,148,38,48,25,102,116,57,92,57,69,39,5, -232,116,78,42,12,12,145,215,105,26,207,164,229,15,208,192,5,26,75,52,162,152,165,127,160,129,57,104,191,1,80,75,3,4,10,0,0,8,8,0,10,178,149,71,71,209,102,236,146,2,0,0,156,5,0,0,51,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109, -109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,79,112,116,105,111,110,83,116,114,105,110,103,46,99,108,97,115,115,149,83,237,78,19,65,20,61,211,15,182,148,181,93,202,151,40,154,130,85,218,45,101,41,226,39,136,198,26,19,35,1,19,12,6,255,13,237, -88,150,108,119,155,221,197,232,163,248,4,254,149,68,32,209,196,7,240,161,140,119,166,43,66,219,4,248,115,231,222,59,115,238,61,231,206,204,239,63,63,126,1,168,226,217,32,174,160,148,38,99,166,145,65,89,134,115,41,84,210,152,135,165,97,33,13,13,101,105, -170,210,44,166,112,87,158,93,210,112,95,195,3,134,56,247,155,12,185,181,61,254,145,91,14,119,155,214,102,232,219,110,115,153,97,192,107,135,182,231,146,179,98,187,118,184,202,48,91,236,61,215,155,41,109,49,36,106,94,67,48,100,215,108,87,172,239,183,118, -132,255,150,239,56,66,118,242,234,220,217,226,190,45,227,40,153,8,119,237,128,65,223,80,13,59,101,40,124,229,186,194,175,57,60,8,4,237,90,107,158,223,180,154,62,111,56,194,170,59,182,85,243,90,45,238,54,100,139,55,220,15,132,95,56,141,39,1,153,166,8, -95,216,65,219,225,159,215,121,139,250,140,22,75,253,132,166,66,175,227,107,120,200,0,134,215,23,210,121,62,159,170,154,69,236,211,130,52,85,105,22,25,10,23,193,49,12,241,122,93,4,65,161,186,180,64,240,90,241,146,234,251,10,77,111,122,251,126,93,188,180, -229,208,199,123,42,204,75,136,142,97,24,58,114,24,145,230,145,142,44,12,98,94,169,104,120,172,99,25,43,12,19,221,165,159,239,219,78,67,248,58,158,96,85,199,13,76,49,176,138,142,235,152,210,240,148,161,114,41,234,12,198,255,250,27,59,123,162,30,50,204, -156,63,51,122,203,69,57,110,163,155,29,233,14,66,238,135,193,59,59,220,101,24,235,115,185,165,247,244,202,121,187,45,220,6,209,237,119,160,39,21,105,166,169,230,207,227,134,60,253,184,12,253,214,24,77,148,198,73,94,78,78,153,214,164,202,141,208,155,27, -165,104,155,162,56,173,89,243,24,113,179,124,136,132,57,119,8,118,160,160,99,10,150,160,247,57,132,4,211,49,200,168,40,203,96,156,242,249,14,12,19,184,6,40,79,182,97,202,147,141,98,228,211,109,68,109,62,168,24,88,49,191,35,145,75,30,97,224,11,166,126, -66,219,62,70,74,134,131,148,103,180,28,33,253,21,147,255,54,134,206,108,124,59,225,52,32,107,177,97,197,67,239,212,141,120,48,249,20,162,158,22,173,114,47,105,30,65,239,6,143,159,2,39,59,96,67,138,205,71,224,13,146,71,194,161,153,229,185,99,196,14,186, -224,154,130,155,157,35,39,51,208,48,29,205,64,195,140,154,129,244,110,161,128,184,145,194,109,220,233,97,70,226,186,153,105,103,152,77,171,210,49,204,42,91,196,164,186,146,24,221,238,61,92,69,26,55,105,133,145,250,11,80,75,3,4,10,0,0,8,8,0,10,178,149, -71,120,38,226,84,96,4,0,0,26,11,0,0,59,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,65,98,115,116,114,97,99,116,80,114,111,112,101,114,116,105,101,115,67,111,109,109,97,110,100,76,105,110,101,67,111,110,118,101,114,116,101,114,46,99,108, -97,115,115,173,86,91,119,26,85,20,254,14,12,76,50,153,230,130,161,53,38,173,73,12,21,2,13,173,182,105,45,52,74,211,212,96,201,69,169,137,105,43,118,128,9,153,20,102,112,102,136,68,255,131,239,174,229,123,95,235,11,109,92,75,87,159,253,29,254,14,117,159, -129,32,100,176,165,89,194,226,92,246,217,103,239,111,127,251,156,125,248,227,175,95,127,7,112,5,63,72,56,135,219,34,150,37,156,197,29,222,172,72,184,139,79,37,172,34,205,167,159,241,209,61,9,25,172,73,88,199,198,16,54,241,249,16,190,64,150,55,247,7,240, -165,4,15,182,6,176,61,132,113,124,197,39,59,188,121,32,226,33,223,255,72,196,215,34,114,12,254,164,166,107,246,18,131,55,28,217,98,16,150,141,162,202,48,146,209,116,117,189,86,201,171,230,125,37,95,38,73,32,99,20,148,242,150,98,106,124,222,18,10,246, -158,102,49,92,207,24,102,41,94,50,149,98,89,141,23,202,90,60,149,183,108,83,41,216,155,166,81,85,77,91,83,173,101,163,82,81,244,34,55,187,108,232,7,36,84,205,4,195,88,73,61,86,58,220,168,218,154,161,51,140,135,35,153,125,229,64,137,151,21,189,20,207, -218,166,166,151,72,117,194,165,122,71,181,21,173,172,22,25,166,122,172,89,5,83,107,89,28,44,24,250,174,86,170,153,4,57,20,62,9,182,3,218,166,98,90,132,139,19,225,175,58,99,134,217,215,235,147,182,209,114,245,42,237,38,50,210,22,11,77,10,24,110,187,208, -56,38,139,29,187,18,77,50,106,182,86,142,175,41,213,68,228,196,156,50,87,53,40,9,44,77,73,122,162,30,110,41,229,154,186,82,175,154,170,101,57,144,2,189,216,244,104,115,196,116,135,169,52,37,68,177,13,30,140,216,12,198,234,17,141,27,29,131,84,109,103, -153,31,156,147,232,206,118,31,156,195,234,241,225,185,214,173,154,116,195,116,75,150,184,191,149,122,65,109,34,20,241,13,101,55,171,149,116,197,118,178,251,227,27,243,217,167,219,200,41,193,174,246,13,200,217,185,145,223,87,11,118,34,226,22,81,202,234, -151,121,115,165,59,163,237,229,226,127,93,194,94,87,47,121,170,112,28,246,179,70,205,44,168,119,53,158,194,104,127,23,125,129,219,146,241,54,38,24,70,79,218,149,241,46,166,101,204,96,90,196,99,25,239,67,17,145,151,81,64,81,198,44,95,81,177,43,162,196, -87,246,68,104,50,246,241,68,68,89,70,5,186,8,67,70,21,223,202,48,193,175,192,45,25,54,106,12,144,113,128,239,100,212,113,200,155,239,25,206,116,197,43,35,130,121,58,129,167,42,91,20,246,27,48,237,214,238,208,74,153,165,90,69,213,237,246,137,102,152,126, -93,181,161,114,27,126,232,206,78,164,159,194,243,10,227,199,213,87,222,83,172,99,88,68,233,92,184,47,195,195,180,171,171,228,46,134,255,39,136,174,235,194,144,236,199,182,107,95,219,195,197,254,52,169,176,208,171,226,84,83,226,33,16,238,172,0,25,205, -226,87,110,184,91,194,48,160,181,170,40,149,189,174,13,29,213,53,224,150,82,201,37,254,214,213,186,237,60,195,15,232,97,213,157,73,247,83,216,190,234,162,166,23,213,250,198,46,67,176,23,21,105,254,36,212,104,251,141,176,123,119,159,197,102,208,170,241, -67,77,246,120,40,233,116,207,39,57,24,238,37,23,102,232,255,197,57,240,143,8,198,111,61,181,239,208,44,78,61,221,77,248,230,159,131,253,66,3,15,38,169,245,59,194,32,166,192,239,173,163,128,243,184,0,8,2,47,13,78,63,211,234,103,121,79,58,239,97,174,101, -180,74,218,94,234,47,70,125,191,193,179,227,157,111,192,155,221,17,168,19,178,13,248,214,98,13,248,215,98,52,21,27,24,216,254,215,107,0,2,181,147,4,116,138,190,231,17,34,143,28,193,116,211,90,19,129,51,10,209,143,145,222,8,85,160,48,237,102,188,120,144, -22,247,254,39,121,247,83,159,139,114,191,13,12,54,32,29,97,136,97,253,210,17,100,134,159,176,66,131,51,12,47,225,185,41,76,8,129,225,6,70,22,125,65,223,207,24,139,209,116,244,8,99,94,108,63,197,36,205,188,65,95,3,129,9,33,232,19,30,55,240,86,107,233, -239,23,177,103,228,193,235,160,190,64,148,130,216,8,17,19,11,196,194,135,196,67,138,240,237,16,178,71,132,139,71,176,68,136,22,16,165,111,140,208,133,112,21,151,104,46,96,12,247,40,5,151,157,248,114,237,248,114,244,111,243,3,135,245,28,89,187,74,241, -93,107,231,129,75,22,73,114,157,198,2,73,110,224,35,135,191,155,163,41,242,149,160,17,231,96,149,44,114,155,210,124,52,246,18,227,13,4,159,245,204,109,147,89,169,237,89,66,178,229,89,194,45,66,221,233,199,211,242,244,49,62,113,250,212,63,80,75,3,4,10, -0,0,8,8,0,10,178,149,71,147,157,188,21,188,2,0,0,32,5,0,0,44,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,80,97,114,115,101,100,67,111,109,109,97,110,100,76,105,110,101,79,112,116,105,111,110,46,99,108,97,115,115,141,83,91,79,19,65,20, -254,182,183,45,237,34,165,92,20,65,40,23,161,45,202,138,23,188,80,171,4,49,33,105,196,164,6,131,111,67,59,89,134,108,119,155,221,45,17,127,10,207,38,190,248,160,137,74,144,68,125,246,71,25,207,236,46,165,20,73,124,153,157,57,251,157,239,124,223,57,51, -191,255,124,255,1,96,17,43,41,100,80,80,81,76,33,130,66,15,250,48,159,162,229,134,138,155,73,44,164,144,128,158,198,45,44,38,113,91,126,239,168,184,43,191,247,228,178,164,226,190,138,7,10,18,123,204,108,113,87,65,166,178,203,246,152,222,242,132,169,87, -132,235,45,43,232,169,10,195,98,94,203,225,10,102,186,126,151,130,179,201,44,67,175,122,142,176,140,229,50,165,36,74,194,18,94,89,65,52,95,216,84,16,91,181,235,148,220,87,17,22,127,209,106,108,115,231,21,219,54,41,146,173,216,53,102,110,50,71,200,115, -24,140,121,59,130,148,228,43,182,99,232,134,195,234,38,215,107,166,208,95,50,199,229,245,85,187,209,96,86,93,82,109,52,61,97,91,84,46,105,112,111,83,26,80,48,152,47,156,151,68,30,78,16,68,156,61,129,116,154,156,61,23,188,192,90,154,213,235,43,142,209, -106,112,203,83,48,148,63,143,146,142,147,172,13,201,254,75,79,114,135,185,161,98,106,209,27,5,169,170,221,114,106,252,185,144,29,24,187,192,234,130,100,210,48,132,97,5,3,167,106,87,28,135,237,75,201,26,250,145,213,112,29,179,10,38,78,171,174,155,38,55, -152,89,245,152,199,215,222,214,184,207,69,136,128,52,87,183,185,155,179,108,47,183,195,246,120,142,89,251,57,255,50,44,200,66,83,42,30,106,120,4,146,60,26,194,73,121,174,209,50,61,209,52,121,128,116,9,90,194,99,186,60,221,78,53,148,241,68,195,83,41,104, -246,255,198,121,134,101,99,123,151,215,168,135,151,206,142,134,238,136,43,222,5,189,91,167,149,134,43,71,177,222,57,250,32,149,116,71,105,96,93,131,10,255,201,190,171,194,93,107,52,189,125,76,210,155,201,208,131,162,129,201,46,210,119,128,78,17,12,34, -78,123,106,57,173,151,41,82,70,148,118,64,166,120,8,165,120,140,200,214,33,162,95,17,251,236,163,175,208,42,223,33,40,35,70,57,35,180,211,2,60,174,98,212,231,31,195,181,144,171,25,114,45,21,191,33,126,128,222,99,36,182,178,234,33,146,63,139,95,16,59, -66,15,25,125,31,134,83,39,225,232,17,210,17,252,130,246,169,93,113,152,52,130,106,169,84,163,159,248,199,169,66,30,19,29,213,151,218,213,199,41,30,241,171,235,116,146,255,226,146,245,148,44,225,7,167,59,146,227,97,114,208,144,28,197,38,49,21,90,120,70, -17,105,87,147,36,243,71,232,141,224,117,119,43,230,144,38,57,35,190,80,31,27,242,201,221,52,102,124,25,116,103,67,198,82,40,43,27,244,224,146,130,3,168,177,15,100,252,99,151,198,249,14,141,217,182,193,57,31,149,255,11,80,75,3,4,10,0,0,8,8,0,10,178,149, -71,182,192,176,115,152,2,0,0,170,6,0,0,61,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,79,112,116,105,111,110,65,119,97,114,101,80,97,114,115,101,114,83,116,97,116,101, -46,99,108,97,115,115,173,85,237,78,19,81,16,61,183,93,186,237,118,177,21,161,126,224,7,98,17,186,20,10,53,200,167,10,18,49,36,13,154,212,52,193,127,183,237,90,23,183,187,230,238,214,143,71,241,9,252,227,15,77,68,141,36,62,128,15,101,156,91,150,90,210, -154,69,226,159,206,206,204,153,115,166,119,230,238,254,252,245,253,7,128,121,172,39,144,196,13,13,58,178,242,105,66,163,159,155,26,38,49,165,33,7,67,197,180,6,21,51,42,102,53,36,48,167,98,94,69,145,33,89,115,155,77,238,212,75,150,99,50,140,151,92,209, -40,52,4,175,219,102,161,102,91,133,199,92,120,102,125,243,15,102,149,33,230,63,183,188,236,92,31,116,23,174,93,40,36,122,205,114,44,255,46,195,195,169,112,120,184,124,174,194,160,108,186,117,106,54,37,3,59,173,102,213,20,79,120,213,166,200,80,201,173, -113,187,194,133,37,253,32,168,200,118,25,50,143,94,250,150,235,108,188,230,34,80,43,251,220,167,188,190,237,56,166,216,180,185,231,153,132,91,14,237,50,219,159,137,254,107,186,201,223,86,77,242,132,127,136,97,24,153,42,237,241,87,188,96,115,167,81,40, -251,194,114,26,171,185,167,12,81,46,26,178,225,158,36,141,196,117,118,92,231,136,32,121,172,217,251,253,232,194,59,62,222,166,86,118,91,162,102,110,89,242,120,50,61,232,89,169,160,35,133,180,142,179,88,208,49,136,51,58,110,99,84,197,162,142,37,44,171, -88,209,177,138,53,134,133,80,229,141,103,190,41,182,44,225,249,229,86,53,72,51,12,247,11,75,181,59,12,51,39,227,60,60,31,26,152,222,237,74,14,218,181,197,83,206,144,33,255,47,103,169,226,30,3,24,38,195,87,59,59,223,94,221,184,229,29,13,118,44,108,215, -25,6,121,189,254,224,141,47,120,133,219,45,243,47,203,84,233,165,234,81,167,153,243,90,205,244,188,236,194,28,93,220,137,19,92,69,185,164,47,254,203,149,61,233,217,108,247,168,157,158,107,60,28,167,140,209,27,82,167,119,103,4,195,114,197,129,116,90,46, -61,69,162,80,104,143,134,104,178,231,200,43,17,34,74,54,109,76,239,131,25,236,43,34,70,126,31,209,79,65,45,168,150,242,44,15,141,205,32,197,102,49,66,177,12,229,168,134,236,69,160,253,36,53,34,196,121,9,163,1,243,10,249,18,21,51,166,191,64,249,208,225, -139,65,174,85,177,139,39,214,225,137,225,50,174,80,158,225,42,198,2,158,61,12,180,81,69,227,51,162,68,53,64,150,125,67,236,29,50,7,80,119,165,39,51,212,121,252,61,82,7,72,236,6,174,246,177,163,169,73,6,182,136,56,91,234,210,45,118,116,139,129,110,4,215, -219,53,227,184,64,214,32,229,36,125,95,206,43,17,58,203,28,174,41,242,43,147,67,158,16,9,178,5,226,189,69,22,233,248,111,80,75,3,4,10,0,0,8,8,0,10,178,149,71,39,4,72,12,25,1,0,0,103,2,0,0,41,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47, -67,111,109,109,97,110,100,76,105,110,101,67,111,110,118,101,114,116,101,114,46,99,108,97,115,115,141,81,77,75,195,64,16,125,211,214,198,212,175,170,39,207,34,52,10,70,175,77,41,72,81,20,2,10,9,222,183,233,186,108,73,55,178,221,148,254,54,15,254,0,127, -148,184,77,161,4,147,66,23,150,157,121,179,239,189,97,230,231,247,235,27,192,61,206,29,116,29,156,18,156,36,83,11,174,13,161,223,11,167,108,193,252,148,41,225,191,24,174,217,56,229,65,9,123,29,79,121,98,2,175,10,17,58,143,203,132,127,26,153,169,185,131, -51,130,27,73,161,152,201,53,39,220,213,9,15,74,88,100,180,84,34,24,6,113,28,120,246,18,158,123,97,166,133,47,52,155,164,220,79,82,233,191,49,61,231,147,81,54,155,49,53,9,165,218,185,179,235,29,164,54,190,174,157,198,135,20,69,219,87,21,98,137,82,104, -232,192,123,39,244,6,113,191,106,60,172,157,82,148,229,58,225,79,50,181,250,23,37,185,209,122,9,92,223,174,88,132,203,237,206,155,175,132,238,127,11,194,205,118,226,131,22,249,140,43,179,217,84,155,64,104,96,117,154,45,66,19,45,155,237,217,172,101,241, -54,28,27,53,176,95,84,220,154,74,199,86,14,112,88,196,107,228,8,199,197,123,242,7,80,75,3,4,10,0,0,8,8,0,10,178,149,71,67,209,22,230,234,3,0,0,124,11,0,0,60,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105, -110,101,80,97,114,115,101,114,36,66,101,102,111,114,101,70,105,114,115,116,83,117,98,67,111,109,109,97,110,100,46,99,108,97,115,115,197,86,109,83,19,87,20,126,110,178,112,113,179,104,72,13,149,182,216,72,131,64,94,8,65,171,64,16,11,17,144,18,137,109, -148,54,216,183,77,88,211,213,100,215,217,108,170,127,161,63,161,255,194,206,180,131,150,169,246,91,103,250,165,255,163,63,162,211,115,119,99,8,38,176,193,113,166,95,238,203,185,207,61,231,185,207,158,123,246,254,245,239,111,47,0,164,113,95,198,89,204, -157,162,102,94,70,24,115,28,25,25,18,22,101,44,224,90,0,75,184,206,241,137,152,44,115,172,8,216,13,25,50,86,57,214,6,176,206,113,83,198,6,62,149,49,136,77,142,156,140,16,182,56,242,28,183,25,250,237,239,245,122,116,134,97,44,103,90,149,84,197,82,119, -171,90,170,92,213,83,89,179,86,83,141,221,156,110,104,183,85,171,174,89,25,66,47,234,134,110,47,49,172,79,122,195,95,71,56,230,221,54,92,102,106,155,65,202,154,187,26,195,25,97,216,106,212,74,154,117,71,45,85,201,18,202,153,101,181,186,173,90,186,152, -55,141,146,160,203,16,94,209,238,155,150,182,166,91,117,187,208,40,53,125,50,40,27,134,161,89,217,170,90,175,107,4,155,243,36,25,237,234,136,78,26,40,31,64,187,136,211,121,22,134,65,211,40,216,170,101,231,31,217,186,105,112,124,206,48,228,142,221,88, -180,104,147,175,157,201,220,3,245,7,53,85,85,141,74,170,96,91,186,81,201,116,90,166,188,169,119,248,38,14,126,213,170,8,233,58,252,209,183,51,29,60,137,228,14,220,5,154,230,15,77,83,189,6,110,57,30,106,147,42,223,140,113,92,54,185,152,12,71,129,1,12, -15,223,74,42,121,179,78,59,233,230,123,50,35,154,180,104,102,25,162,189,236,99,144,11,102,195,42,83,154,136,28,28,238,192,76,11,185,21,156,195,136,130,97,188,203,113,135,33,121,34,25,197,230,187,10,182,241,5,199,151,10,138,216,97,136,120,73,168,224,30, -190,98,152,247,140,116,215,120,104,152,143,141,46,201,120,238,168,37,5,23,48,38,88,125,203,16,63,58,192,178,85,105,212,52,195,94,125,82,214,154,159,254,66,211,101,164,153,22,201,42,225,34,110,206,69,38,198,235,19,211,12,193,131,252,204,151,30,104,101, -155,227,59,5,42,74,34,98,153,225,170,231,145,54,143,56,208,112,247,5,225,151,234,195,149,55,171,7,189,16,114,67,46,63,86,45,237,48,161,163,22,102,79,126,193,233,94,121,167,235,177,137,227,130,24,54,123,42,66,189,94,42,89,45,151,181,122,61,58,55,67,151, -235,82,15,247,121,202,141,213,176,245,106,234,150,250,72,20,207,67,6,42,100,21,205,102,184,216,78,211,205,148,87,123,219,77,7,12,230,5,131,241,94,24,236,112,144,158,129,67,234,254,216,77,149,183,80,122,218,107,116,175,154,6,95,103,66,21,156,82,179,166, -146,44,243,93,120,222,59,94,169,86,181,14,119,217,43,226,253,243,6,101,216,227,215,224,253,15,248,191,196,77,156,196,43,34,244,160,10,211,59,140,5,131,162,188,211,200,15,159,168,246,244,247,122,143,102,55,105,238,167,94,137,197,127,133,47,22,79,236,193, -255,51,205,125,120,159,218,211,98,141,93,67,31,91,66,128,93,199,7,100,27,166,53,194,99,148,124,195,25,81,181,37,27,195,71,184,216,244,250,55,6,208,71,189,182,15,169,24,79,176,61,244,109,197,126,129,239,25,250,19,207,193,125,248,3,3,11,210,136,244,39, -210,174,249,212,79,8,237,67,46,198,105,26,136,17,94,121,186,143,193,98,232,180,244,59,206,20,253,201,194,51,4,247,48,244,114,31,161,162,216,145,28,145,94,33,223,121,218,162,123,30,156,232,102,137,234,13,140,178,85,140,177,53,36,216,58,50,108,131,222, -139,57,135,254,101,151,88,139,190,134,9,76,18,109,49,154,162,145,15,1,236,32,134,4,29,125,148,228,73,98,26,82,16,36,89,186,121,184,60,173,72,212,115,71,45,118,160,86,191,112,195,22,157,48,49,23,210,10,195,49,75,234,51,103,116,201,209,75,140,46,227,99, -231,123,92,113,124,92,197,135,212,175,144,118,103,233,57,124,158,44,81,234,199,37,241,92,94,64,156,94,197,41,234,17,28,128,120,46,103,33,30,195,11,184,69,184,48,245,159,73,62,124,77,253,55,146,252,31,80,75,3,4,10,0,0,8,8,0,10,178,149,71,147,0,59,153, -124,1,0,0,252,2,0,0,57,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,83,121,115,116,101,109,80,114,111,112,101,114,116,105,101,115,67,111,109,109,97,110,100,76,105,110,101,67,111,110,118,101,114,116,101,114,46,99,108,97,115,115,157,146, -203,74,195,64,20,134,207,216,171,109,181,182,214,106,213,69,220,53,66,19,68,196,133,23,144,22,23,82,47,80,233,126,154,30,211,145,36,19,38,211,66,222,74,87,130,11,31,192,135,18,39,105,16,169,65,196,89,156,51,243,207,255,205,156,185,188,127,188,190,1,192, -1,108,151,32,15,141,34,108,20,161,89,132,205,2,108,21,160,69,32,127,202,60,38,207,9,100,218,250,144,64,182,203,199,72,160,218,103,30,222,76,221,17,138,123,58,114,148,82,239,115,139,58,67,42,88,52,78,196,172,156,176,128,192,81,159,11,219,180,5,29,59,104, -90,14,51,7,97,32,209,189,19,220,71,33,25,6,93,238,186,212,27,71,139,118,185,55,83,34,138,19,2,53,27,101,98,10,111,125,201,184,71,160,209,214,251,143,116,70,77,135,122,182,57,144,130,121,182,178,182,126,88,123,40,41,115,112,76,96,55,101,46,176,4,75,86, -44,13,248,84,88,120,201,162,138,245,191,148,102,68,5,84,160,0,69,2,164,71,160,28,196,80,199,87,20,129,227,1,74,109,174,104,126,178,173,198,31,52,57,65,237,106,120,173,181,209,176,13,173,211,115,195,104,246,204,13,103,212,153,162,110,16,56,252,199,53, -169,219,93,160,46,70,129,20,212,146,191,115,176,7,57,245,224,81,203,2,137,206,162,226,178,26,153,42,19,149,115,251,47,64,158,85,103,9,74,42,230,99,177,14,101,21,43,115,131,202,43,49,190,10,213,4,238,36,112,166,190,244,180,128,54,191,161,153,47,116,45, -5,205,44,162,59,169,104,45,5,205,46,162,90,10,170,62,107,236,90,255,4,80,75,3,4,10,0,0,8,8,0,10,178,149,71,45,21,104,130,7,2,0,0,187,4,0,0,50,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97, -114,115,101,114,36,80,97,114,115,101,114,83,116,97,116,101,46,99,108,97,115,115,149,83,223,111,210,80,20,254,78,41,20,11,115,192,220,84,52,19,55,28,48,54,234,124,51,24,77,36,154,152,144,109,9,102,15,123,187,64,195,186,148,91,115,219,45,250,63,249,226, -139,38,62,248,7,248,71,25,207,109,217,100,131,4,105,210,158,31,247,156,239,124,231,156,219,223,127,126,254,2,112,0,199,70,26,219,54,50,216,206,162,106,227,25,118,44,212,45,52,8,153,87,158,244,162,215,132,84,189,113,66,48,59,193,208,37,172,118,61,233, -30,94,140,251,174,250,40,250,62,123,74,221,96,32,252,19,161,60,109,79,156,102,116,230,133,132,220,177,80,161,171,122,145,136,216,153,255,32,165,171,58,190,8,67,151,15,91,221,64,141,156,145,18,67,223,117,6,190,231,116,130,241,88,200,161,174,144,228,85, -167,210,219,132,194,88,124,233,187,108,169,232,232,83,228,5,146,176,94,239,158,139,75,225,248,66,142,156,94,164,60,57,106,55,78,9,89,47,188,10,73,9,53,210,44,103,226,8,43,129,156,66,179,176,75,40,38,250,13,222,167,115,138,204,41,187,184,157,25,108,230, -144,11,228,97,32,175,200,190,157,215,207,210,115,10,228,84,200,59,57,180,208,36,128,80,171,47,134,58,104,235,109,27,159,159,19,170,255,19,77,176,123,193,133,26,184,239,61,189,248,141,153,152,150,110,40,15,11,89,130,85,127,19,54,246,91,77,11,123,121,236, -163,104,161,69,216,91,166,61,238,238,223,128,142,250,231,238,32,34,188,88,126,242,132,173,197,205,221,40,150,108,131,123,24,139,104,112,166,47,112,101,17,130,89,225,191,43,3,253,88,48,244,8,120,9,119,216,114,88,242,70,144,222,253,1,227,27,43,6,108,254, -102,180,147,202,200,177,158,79,2,88,174,2,38,51,65,49,6,42,177,76,64,218,156,101,104,232,102,41,245,29,230,215,91,48,155,49,204,70,18,146,192,196,218,26,238,129,24,112,29,15,98,224,135,40,67,95,142,71,215,236,154,177,205,239,109,102,59,83,204,40,129, -44,104,200,205,73,226,75,150,198,164,173,153,228,242,20,159,244,53,159,52,158,160,18,167,61,141,227,183,112,151,101,25,41,62,169,97,197,180,57,163,134,251,44,31,179,68,33,251,23,80,75,3,4,10,0,0,8,8,0,10,178,149,71,70,182,8,247,61,3,0,0,202,9,0,0,59, -0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,65,102,116,101,114,70,105,114,115,116,83,117,98,67,111,109,109,97,110,100,46,99,108,97,115,115,197,86,235,82,211,80,16,254, -78,91,8,164,1,74,5,196,59,98,101,160,45,180,5,17,176,120,41,85,46,82,40,88,69,209,95,161,196,26,40,9,147,6,241,21,124,0,223,3,103,116,80,153,113,252,231,140,143,226,67,56,238,73,10,20,75,155,194,48,227,159,179,123,118,247,124,103,119,179,187,57,191,254, -124,251,14,32,134,69,17,205,136,52,210,18,21,209,130,136,72,178,65,47,134,112,75,192,176,128,219,92,51,42,66,192,152,128,59,2,198,69,120,113,79,132,136,251,2,30,8,72,48,212,155,111,212,66,32,202,208,157,210,141,92,36,103,200,171,121,37,146,205,171,145, -164,190,177,33,107,171,41,85,83,22,100,163,160,24,113,178,30,87,53,213,188,199,48,213,235,108,254,175,133,37,94,45,177,139,247,45,49,120,146,250,170,194,208,194,5,243,91,27,43,138,241,84,94,201,147,196,159,210,179,114,126,73,54,84,190,47,10,61,220,93, -134,182,196,107,83,49,38,85,163,96,102,182,86,138,144,12,210,140,166,41,70,50,47,23,10,10,89,141,56,250,24,56,14,135,226,244,102,15,45,143,73,77,121,36,12,77,186,150,49,101,195,76,111,154,170,174,9,72,50,180,218,188,125,21,41,77,194,122,217,155,90,147, -223,202,145,188,172,229,34,25,211,80,181,92,188,92,210,231,236,121,25,54,249,224,150,141,28,79,92,25,30,125,57,221,178,39,167,74,66,75,23,101,213,190,189,109,19,23,240,144,1,12,235,103,242,225,157,195,139,89,197,225,122,23,229,75,140,47,131,12,129,90, -206,49,136,25,125,203,200,42,147,42,175,152,142,50,155,1,158,30,9,126,156,147,224,67,171,128,71,18,38,49,37,96,90,194,12,30,51,116,57,101,131,97,204,209,145,103,218,186,166,111,107,199,148,64,103,37,149,132,75,184,204,29,155,163,218,117,188,96,182,2, -124,71,37,69,127,141,53,101,215,12,117,83,233,150,187,53,207,151,52,195,240,169,218,170,150,152,236,27,19,219,178,161,28,141,169,146,98,240,228,125,66,229,238,92,69,85,139,192,54,162,58,147,179,89,165,80,8,140,70,169,74,135,106,104,140,62,187,51,183, -76,53,31,153,147,55,249,212,56,34,160,14,206,41,38,67,79,233,144,72,175,172,41,89,115,255,108,169,72,192,2,141,170,35,161,189,63,110,188,156,65,59,150,206,153,90,155,119,182,166,81,87,43,218,239,83,12,158,234,21,94,205,188,56,245,254,87,234,194,39,65, -69,23,253,229,91,232,61,192,124,62,62,208,136,115,195,197,231,27,205,235,54,218,77,211,222,77,84,10,134,62,195,21,12,133,119,225,254,72,123,23,218,105,109,230,58,182,136,58,246,4,94,150,65,7,201,58,72,71,246,56,143,139,128,197,209,100,34,25,195,21,186, -205,70,253,128,6,120,136,38,130,159,224,250,2,79,248,43,234,92,248,129,250,249,254,159,240,239,65,88,14,145,166,33,200,118,209,184,179,7,113,153,219,237,193,187,28,10,147,72,234,223,87,54,237,28,184,226,231,128,236,57,90,217,11,180,179,101,4,216,43,203, -157,160,125,209,129,59,9,92,71,55,185,193,185,27,196,185,40,232,40,2,184,9,183,143,163,244,22,93,76,83,104,252,164,96,197,204,14,99,174,231,135,217,66,9,184,112,0,46,160,143,224,152,197,5,173,168,57,23,66,216,202,106,191,133,49,128,11,68,39,40,3,205, -244,226,234,36,201,85,162,215,60,34,122,136,194,215,64,39,98,24,1,127,106,197,16,39,189,151,232,93,240,71,90,12,19,30,23,102,137,166,60,226,95,80,75,3,4,10,0,0,8,8,0,10,178,149,71,105,222,125,0,70,0,0,0,68,0,0,0,31,0,0,0,103,114,97,100,108,101,45,99, -108,105,45,99,108,97,115,115,112,97,116,104,46,112,114,111,112,101,114,116,105,101,115,83,206,205,79,41,205,73,85,72,73,77,203,204,203,44,201,204,207,227,82,246,205,207,83,112,73,77,86,48,50,84,48,50,178,50,52,179,50,50,80,112,118,13,81,48,50,48,52,229, -42,40,202,207,74,77,46,41,182,229,42,42,205,43,201,204,77,181,229,2,0,80,75,1,2,20,3,10,0,0,8,8,0,42,178,149,71,0,0,0,0,2,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,16,0,237,65,0,0,0,0,77,69,84,65,45,73,78,70,47,80,75,1,2,20,3,10,0,0,8,8,0,42,178,149,71,215,149, -152,82,63,0,0,0,85,0,0,0,20,0,0,0,0,0,0,0,0,0,0,0,164,129,41,0,0,0,77,69,84,65,45,73,78,70,47,77,65,78,73,70,69,83,84,46,77,70,80,75,1,2,20,3,10,0,0,8,8,0,22,178,149,71,0,0,0,0,2,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,16,0,253,65,154,0,0,0,111,114,103,47, -80,75,1,2,20,3,10,0,0,8,8,0,22,178,149,71,0,0,0,0,2,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,16,0,253,65,190,0,0,0,111,114,103,47,103,114,97,100,108,101,47,80,75,1,2,20,3,10,0,0,8,8,0,22,178,149,71,0,0,0,0,2,0,0,0,0,0,0,0,19,0,0,0,0,0,0,0,0,0,16,0,253,65,233, -0,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,80,75,1,2,20,3,10,0,0,8,8,0,22,178,149,71,104,130,100,102,163,0,0,0,213,0,0,0,35,0,0,0,0,0,0,0,0,0,0,0,180,129,28,1,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112, -112,101,114,47,68,111,119,110,108,111,97,100,36,49,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,22,178,149,71,197,222,133,214,20,2,0,0,112,4,0,0,68,0,0,0,0,0,0,0,0,0,0,0,180,129,0,2,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112, -101,114,47,68,111,119,110,108,111,97,100,36,83,121,115,116,101,109,80,114,111,112,101,114,116,105,101,115,80,114,111,120,121,65,117,116,104,101,110,116,105,99,97,116,111,114,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,22,178,149,71,231,236,88,115, -170,0,0,0,219,0,0,0,34,0,0,0,0,0,0,0,0,0,0,0,180,129,118,4,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,73,68,111,119,110,108,111,97,100,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,22,178,149,71,4,169,122,221,92,2,0, -0,81,4,0,0,45,0,0,0,0,0,0,0,0,0,0,0,180,129,96,5,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,71,114,97,100,108,101,85,115,101,114,72,111,109,101,76,111,111,107,117,112,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,22, -178,149,71,28,226,93,219,197,5,0,0,250,10,0,0,51,0,0,0,0,0,0,0,0,0,0,0,180,129,7,8,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,69,120,99,108,117,115,105,118,101,70,105,108,101,65,99,99,101,115,115,77,97,110,97,103,101,114, -46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,22,178,149,71,204,13,94,70,145,2,0,0,249,6,0,0,45,0,0,0,0,0,0,0,0,0,0,0,180,129,29,14,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,87,114,97,112,112,101,114,67,111,110,102, -105,103,117,114,97,116,105,111,110,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,22,178,149,71,81,125,29,105,229,4,0,0,25,10,0,0,48,0,0,0,0,0,0,0,0,0,0,0,180,129,249,16,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,83, -121,115,116,101,109,80,114,111,112,101,114,116,105,101,115,72,97,110,100,108,101,114,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,22,178,149,71,165,121,48,186,86,2,0,0,0,5,0,0,31,0,0,0,0,0,0,0,0,0,0,0,180,129,44,22,0,0,111,114,103,47,103,114,97,100, -108,101,47,119,114,97,112,112,101,114,47,76,111,103,103,101,114,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,22,178,149,71,206,114,235,138,21,7,0,0,110,14,0,0,38,0,0,0,0,0,0,0,0,0,0,0,180,129,191,24,0,0,111,114,103,47,103,114,97,100,108,101,47,119, -114,97,112,112,101,114,47,80,97,116,104,65,115,115,101,109,98,108,101,114,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,22,178,149,71,56,222,182,221,27,19,0,0,236,41,0,0,32,0,0,0,0,0,0,0,0,0,0,0,180,129,24,32,0,0,111,114,103,47,103,114,97,100,108, -101,47,119,114,97,112,112,101,114,47,73,110,115,116,97,108,108,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,22,178,149,71,221,192,76,137,196,4,0,0,149,9,0,0,45,0,0,0,0,0,0,0,0,0,0,0,180,129,113,51,0,0,111,114,103,47,103,114,97,100,108,101,47,119, -114,97,112,112,101,114,47,66,111,111,116,115,116,114,97,112,77,97,105,110,83,116,97,114,116,101,114,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,22,178,149,71,72,214,183,36,211,10,0,0,35,24,0,0,40,0,0,0,0,0,0,0,0,0,0,0,180,129,128,56,0,0,111,114, -103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,87,114,97,112,112,101,114,69,120,101,99,117,116,111,114,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,22,178,149,71,132,26,164,171,178,10,0,0,66,24,0,0,42,0,0,0,0,0,0,0,0,0,0,0,180,129, -153,67,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,71,114,97,100,108,101,87,114,97,112,112,101,114,77,97,105,110,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,22,178,149,71,217,206,17,120,160,6,0,0,180,14,0,0,34,0,0, -0,0,0,0,0,0,0,0,0,180,129,147,78,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,73,110,115,116,97,108,108,36,49,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,22,178,149,71,106,32,106,144,180,1,0,0,86,3,0,0,56,0,0,0,0,0, -0,0,0,0,0,0,180,129,115,85,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,80,97,116,104,65,115,115,101,109,98,108,101,114,36,76,111,99,97,108,68,105,115,116,114,105,98,117,116,105,111,110,46,99,108,97,115,115,80,75,1,2,20, -3,10,0,0,8,8,0,22,178,149,71,146,99,74,27,25,8,0,0,75,15,0,0,33,0,0,0,0,0,0,0,0,0,0,0,180,129,125,87,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,68,111,119,110,108,111,97,100,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8, -8,0,22,178,149,71,192,25,62,198,80,0,0,0,78,0,0,0,35,0,0,0,0,0,0,0,0,0,0,0,180,129,213,95,0,0,103,114,97,100,108,101,45,119,114,97,112,112,101,114,45,99,108,97,115,115,112,97,116,104,46,112,114,111,112,101,114,116,105,101,115,80,75,1,2,20,3,10,0,0,8, -8,0,10,178,149,71,36,217,150,101,206,0,0,0,28,1,0,0,24,0,0,0,0,0,0,0,0,0,0,0,180,129,102,96,0,0,98,117,105,108,100,45,114,101,99,101,105,112,116,46,112,114,111,112,101,114,116,105,101,115,80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,0,0,0,0,2,0,0,0,0,0, -0,0,15,0,0,0,0,0,0,0,0,0,16,0,253,65,106,97,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,144,200,244,150,60,2,0,0,83,5,0,0,49,0,0,0,0,0,0,0,0,0,0,0,180,129,153,97,0,0,111,114,103,47,103,114,97,100, -108,101,47,99,108,105,47,65,98,115,116,114,97,99,116,67,111,109,109,97,110,100,76,105,110,101,67,111,110,118,101,114,116,101,114,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,50,95,101,143,166,0,0,0,232,0,0,0,40,0,0,0,0,0,0,0,0,0,0,0, -180,129,36,100,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,49,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,82,66,9,29,168,2,0,0,247,6,0,0,60,0,0,0,0,0, -0,0,0,0,0,0,180,129,16,101,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,77,105,115,115,105,110,103,79,112,116,105,111,110,65,114,103,83,116,97,116,101,46,99,108,97,115,115, -80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,188,172,77,50,145,2,0,0,131,5,0,0,61,0,0,0,0,0,0,0,0,0,0,0,180,129,18,104,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,79,112,116, -105,111,110,83,116,114,105,110,103,67,111,109,112,97,114,97,116,111,114,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,232,35,13,242,71,1,0,0,75,2,0,0,49,0,0,0,0,0,0,0,0,0,0,0,180,129,254,106,0,0,111,114,103,47,103,114,97,100,108,101, -47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,65,114,103,117,109,101,110,116,69,120,99,101,112,116,105,111,110,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,63,23,104,255,199,7,0,0,135,19,0,0,61,0,0,0,0,0,0,0,0,0,0,0,180, -129,148,108,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,75,110,111,119,110,79,112,116,105,111,110,80,97,114,115,101,114,83,116,97,116,101,46,99,108,97,115,115,80,75,1,2, -20,3,10,0,0,8,8,0,10,178,149,71,28,107,22,177,205,2,0,0,219,6,0,0,55,0,0,0,0,0,0,0,0,0,0,0,180,129,182,116,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,79,112,116,105,111, -110,67,111,109,112,97,114,97,116,111,114,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,228,98,213,39,225,2,0,0,110,7,0,0,63,0,0,0,0,0,0,0,0,0,0,0,180,129,216,119,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109, -97,110,100,76,105,110,101,80,97,114,115,101,114,36,85,110,107,110,111,119,110,79,112,116,105,111,110,80,97,114,115,101,114,83,116,97,116,101,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,34,122,201,90,146,5,0,0,153,13,0,0,38,0,0,0,0, -0,0,0,0,0,0,0,180,129,22,123,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,79,112,116,105,111,110,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,156,108,92,207,167,1,0,0,166,3,0,0, -56,0,0,0,0,0,0,0,0,0,0,0,180,129,236,128,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,79,112,116,105,111,110,80,97,114,115,101,114,83,116,97,116,101,46,99,108,97,115,115, -80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,91,120,110,152,148,7,0,0,199,17,0,0,38,0,0,0,0,0,0,0,0,0,0,0,180,129,233,130,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,80,97,114,115,101,100,67,111,109,109,97,110,100,76,105,110,101,46,99,108, -97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,139,65,53,108,124,1,0,0,11,3,0,0,58,0,0,0,0,0,0,0,0,0,0,0,180,129,193,138,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,80,114,111,106,101,99,116,80,114,111,112,101,114,116,105,101,115, -67,111,109,109,97,110,100,76,105,110,101,67,111,110,118,101,114,116,101,114,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,50,108,87,182,74,2,0,0,4,5,0,0,70,0,0,0,0,0,0,0,0,0,0,0,180,129,149,140,0,0,111,114,103,47,103,114,97,100,108,101, -47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,67,97,115,101,73,110,115,101,110,115,105,116,105,118,101,83,116,114,105,110,103,67,111,109,112,97,114,97,116,111,114,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,10, -178,149,71,133,165,180,23,103,18,0,0,198,42,0,0,38,0,0,0,0,0,0,0,0,0,0,0,180,129,67,143,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,46,99,108,97,115,115,80,75,1,2,20,3,10,0, -0,8,8,0,10,178,149,71,95,15,62,210,163,2,0,0,41,7,0,0,51,0,0,0,0,0,0,0,0,0,0,0,180,129,238,161,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,65,102,116,101,114,79,112,116, -105,111,110,115,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,71,209,102,236,146,2,0,0,156,5,0,0,51,0,0,0,0,0,0,0,0,0,0,0,180,129,226,164,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110, -101,80,97,114,115,101,114,36,79,112,116,105,111,110,83,116,114,105,110,103,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,120,38,226,84,96,4,0,0,26,11,0,0,59,0,0,0,0,0,0,0,0,0,0,0,180,129,197,167,0,0,111,114,103,47,103,114,97,100,108, -101,47,99,108,105,47,65,98,115,116,114,97,99,116,80,114,111,112,101,114,116,105,101,115,67,111,109,109,97,110,100,76,105,110,101,67,111,110,118,101,114,116,101,114,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,147,157,188,21,188,2,0, -0,32,5,0,0,44,0,0,0,0,0,0,0,0,0,0,0,180,129,126,172,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,80,97,114,115,101,100,67,111,109,109,97,110,100,76,105,110,101,79,112,116,105,111,110,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,10,178, -149,71,182,192,176,115,152,2,0,0,170,6,0,0,61,0,0,0,0,0,0,0,0,0,0,0,180,129,132,175,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,79,112,116,105,111,110,65,119,97,114,101, -80,97,114,115,101,114,83,116,97,116,101,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,39,4,72,12,25,1,0,0,103,2,0,0,41,0,0,0,0,0,0,0,0,0,0,0,180,129,119,178,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97, -110,100,76,105,110,101,67,111,110,118,101,114,116,101,114,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,67,209,22,230,234,3,0,0,124,11,0,0,60,0,0,0,0,0,0,0,0,0,0,0,180,129,215,179,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105, -47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,66,101,102,111,114,101,70,105,114,115,116,83,117,98,67,111,109,109,97,110,100,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,147,0,59,153,124,1,0,0,252,2,0,0,57,0,0, -0,0,0,0,0,0,0,0,0,180,129,27,184,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,83,121,115,116,101,109,80,114,111,112,101,114,116,105,101,115,67,111,109,109,97,110,100,76,105,110,101,67,111,110,118,101,114,116,101,114,46,99,108,97,115,115, -80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,45,21,104,130,7,2,0,0,187,4,0,0,50,0,0,0,0,0,0,0,0,0,0,0,180,129,238,185,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,80,97,114, -115,101,114,83,116,97,116,101,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,70,182,8,247,61,3,0,0,202,9,0,0,59,0,0,0,0,0,0,0,0,0,0,0,180,129,69,188,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100, -76,105,110,101,80,97,114,115,101,114,36,65,102,116,101,114,70,105,114,115,116,83,117,98,67,111,109,109,97,110,100,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,105,222,125,0,70,0,0,0,68,0,0,0,31,0,0,0,0,0,0,0,0,0,0,0,180,129,219,191, -0,0,103,114,97,100,108,101,45,99,108,105,45,99,108,97,115,115,112,97,116,104,46,112,114,111,112,101,114,116,105,101,115,80,75,5,6,0,0,0,0,49,0,49,0,16,17,0,0,94,192,0,0,0,0,0,0 }; - -const char* gradlewrapper_jar = (const char*) temp_binary_data_0; - -//================== gradlew ================== -static const unsigned char temp_binary_data_1[] = -"#!/usr/bin/env bash\n" -"\n" -"##############################################################################\n" -"##\n" -"## Gradle start up script for UN*X\n" -"##\n" -"##############################################################################\n" -"\n" -"# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\n" -"DEFAULT_JVM_OPTS=\"\"\n" -"\n" -"APP_NAME=\"Gradle\"\n" -"APP_BASE_NAME=`basename \"$0\"`\n" -"\n" -"# Use the maximum available, or set MAX_FD != -1 to use that value.\n" -"MAX_FD=\"maximum\"\n" -"\n" -"warn ( ) {\n" -" echo \"$*\"\n" -"}\n" -"\n" -"die ( ) {\n" -" echo\n" -" echo \"$*\"\n" -" echo\n" -" exit 1\n" -"}\n" -"\n" -"# OS specific support (must be 'true' or 'false').\n" -"cygwin=false\n" -"msys=false\n" -"darwin=false\n" -"case \"`uname`\" in\n" -" CYGWIN* )\n" -" cygwin=true\n" -" ;;\n" -" Darwin* )\n" -" darwin=true\n" -" ;;\n" -" MINGW* )\n" -" msys=true\n" -" ;;\n" -"esac\n" -"\n" -"# Attempt to set APP_HOME\n" -"# Resolve links: $0 may be a link\n" -"PRG=\"$0\"\n" -"# Need this for relative symlinks.\n" -"while [ -h \"$PRG\" ] ; do\n" -" ls=`ls -ld \"$PRG\"`\n" -" link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n" -" if expr \"$link\" : '/.*' > /dev/null; then\n" -" PRG=\"$link\"\n" -" else\n" -" PRG=`dirname \"$PRG\"`\"/$link\"\n" -" fi\n" -"done\n" -"SAVED=\"`pwd`\"\n" -"cd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\n" -"APP_HOME=\"`pwd -P`\"\n" -"cd \"$SAVED\" >/dev/null\n" -"\n" -"CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n" -"\n" -"# Determine the Java command to use to start the JVM.\n" -"if [ -n \"$JAVA_HOME\" ] ; then\n" -" if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n" -" # IBM's JDK on AIX uses strange locations for the executables\n" -" JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n" -" else\n" -" JAVACMD=\"$JAVA_HOME/bin/java\"\n" -" fi\n" -" if [ ! -x \"$JAVACMD\" ] ; then\n" -" die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n" -"\n" -"Please set the JAVA_HOME variable in your environment to match the\n" -"location of your Java installation.\"\n" -" fi\n" -"else\n" -" JAVACMD=\"java\"\n" -" which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n" -"\n" -"Please set the JAVA_HOME variable in your environment to match the\n" -"location of your Java installation.\"\n" -"fi\n" -"\n" -"# Increase the maximum file descriptors if we can.\n" -"if [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" ] ; then\n" -" MAX_FD_LIMIT=`ulimit -H -n`\n" -" if [ $? -eq 0 ] ; then\n" -" if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n" -" MAX_FD=\"$MAX_FD_LIMIT\"\n" -" fi\n" -" ulimit -n $MAX_FD\n" -" if [ $? -ne 0 ] ; then\n" -" warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n" -" fi\n" -" else\n" -" warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n" -" fi\n" -"fi\n" -"\n" -"# For Darwin, add options to specify how the application appears in the dock\n" -"if $darwin; then\n" -" GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\n" -"fi\n" -"\n" -"# For Cygwin, switch paths to Windows format before running java\n" -"if $cygwin ; then\n" -" APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n" -" CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n" -" JAVACMD=`cygpath --unix \"$JAVACMD\"`\n" -"\n" -" # We build the pattern for arguments to be converted via cygpath\n" -" ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n" -" SEP=\"\"\n" -" for dir in $ROOTDIRSRAW ; do\n" -" ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n" -" SEP=\"|\"\n" -" done\n" -" OURCYGPATTERN=\"(^($ROOTDIRS))\"\n" -" # Add a user-defined pattern to the cygpath arguments\n" -" if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n" -" OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n" -" fi\n" -" # Now convert the arguments - kludge to limit ourselves to /bin/sh\n" -" i=0\n" -" for arg in \"$@\" ; do\n" -" CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n" -" CHECK2=`echo \"$arg\"|egrep -c \"^-\"` ### Determine if an option\n" -"\n" -" if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition\n" -" eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n" -" else\n" -" eval `echo args$i`=\"\\\"$arg\\\"\"\n" -" fi\n" -" i=$((i+1))\n" -" done\n" -" case $i in\n" -" (0) set -- ;;\n" -" (1) set -- \"$args0\" ;;\n" -" (2) set -- \"$args0\" \"$args1\" ;;\n" -" (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n" -" (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n" -" (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n" -" (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n" -" (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n" -" (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n" -" (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n" -" esac\n" -"fi\n" -"\n" -"# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules\n" -"function splitJvmOpts() {\n" -" JVM_OPTS=(\"$@\")\n" -"}\n" -"eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\n" -"JVM_OPTS[${#JVM_OPTS[*]}]=\"-Dorg.gradle.appname=$APP_BASE_NAME\"\n" -"\n" -"exec \"$JAVACMD\" \"${JVM_OPTS[@]}\" -classpath \"$CLASSPATH\" org.gradle.wrapper.GradleWrapperMain \"$@\"\n"; - -const char* gradlew = (const char*) temp_binary_data_1; - -//================== gradlew.bat ================== -static const unsigned char temp_binary_data_2[] = -"@if \"%DEBUG%\" == \"\" @echo off\r\n" -"@rem ##########################################################################\r\n" -"@rem\r\n" -"@rem Gradle startup script for Windows\r\n" -"@rem\r\n" -"@rem ##########################################################################\r\n" -"\r\n" -"@rem Set local scope for the variables with windows NT shell\r\n" -"if \"%OS%\"==\"Windows_NT\" setlocal\r\n" -"\r\n" -"@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r\n" -"set DEFAULT_JVM_OPTS=\r\n" -"\r\n" -"set DIRNAME=%~dp0\r\n" -"if \"%DIRNAME%\" == \"\" set DIRNAME=.\r\n" -"set APP_BASE_NAME=%~n0\r\n" -"set APP_HOME=%DIRNAME%\r\n" -"\r\n" -"@rem Find java.exe\r\n" -"if defined JAVA_HOME goto findJavaFromJavaHome\r\n" -"\r\n" -"set JAVA_EXE=java.exe\r\n" -"%JAVA_EXE% -version >NUL 2>&1\r\n" -"if \"%ERRORLEVEL%\" == \"0\" goto init\r\n" -"\r\n" -"echo.\r\n" -"echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r\n" -"echo.\r\n" -"echo Please set the JAVA_HOME variable in your environment to match the\r\n" -"echo location of your Java installation.\r\n" -"\r\n" -"goto fail\r\n" -"\r\n" -":findJavaFromJavaHome\r\n" -"set JAVA_HOME=%JAVA_HOME:\"=%\r\n" -"set JAVA_EXE=%JAVA_HOME%/bin/java.exe\r\n" -"\r\n" -"if exist \"%JAVA_EXE%\" goto init\r\n" -"\r\n" -"echo.\r\n" -"echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r\n" -"echo.\r\n" -"echo Please set the JAVA_HOME variable in your environment to match the\r\n" -"echo location of your Java installation.\r\n" -"\r\n" -"goto fail\r\n" -"\r\n" -":init\r\n" -"@rem Get command-line arguments, handling Windowz variants\r\n" -"\r\n" -"if not \"%OS%\" == \"Windows_NT\" goto win9xME_args\r\n" -"if \"%@eval[2+2]\" == \"4\" goto 4NT_args\r\n" -"\r\n" -":win9xME_args\r\n" -"@rem Slurp the command line arguments.\r\n" -"set CMD_LINE_ARGS=\r\n" -"set _SKIP=2\r\n" -"\r\n" -":win9xME_args_slurp\r\n" -"if \"x%~1\" == \"x\" goto execute\r\n" -"\r\n" -"set CMD_LINE_ARGS=%*\r\n" -"goto execute\r\n" -"\r\n" -":4NT_args\r\n" -"@rem Get arguments from the 4NT Shell from JP Software\r\n" -"set CMD_LINE_ARGS=%$\r\n" -"\r\n" -":execute\r\n" -"@rem Setup the command line\r\n" -"\r\n" -"set CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\r\n" -"\r\n" -"@rem Execute Gradle\r\n" -"\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\r\n" -"\r\n" -":end\r\n" -"@rem End local scope for the variables with windows NT shell\r\n" -"if \"%ERRORLEVEL%\"==\"0\" goto mainEnd\r\n" -"\r\n" -":fail\r\n" -"rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r\n" -"rem the _cmd.exe /c_ return code!\r\n" -"if not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\r\n" -"exit /b 1\r\n" -"\r\n" -":mainEnd\r\n" -"if \"%OS%\"==\"Windows_NT\" endlocal\r\n" -"\r\n" -":omega\r\n"; - -const char* gradlew_bat = (const char*) temp_binary_data_2; - -//================== LICENSE ================== -static const unsigned char temp_binary_data_3[] = -"Apache License\n" -" Version 2.0, January 2004\n" -" http://www.apache.org/licenses/\n" -"\n" -" TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n" -"\n" -" 1. Definitions.\n" -"\n" -" \"License\" shall mean the terms and conditions for use, reproduction,\n" -" and distribution as defined by Sections 1 through 9 of this document.\n" -"\n" -" \"Licensor\" shall mean the copyright owner or entity authorized by\n" -" the copyright owner that is granting the License.\n" -"\n" -" \"Legal Entity\" shall mean the union of the acting entity and all\n" -" other entities that control, are controlled by, or are under common\n" -" control with that entity. For the purposes of this definition,\n" -" \"control\" means (i) the power, direct or indirect, to cause the\n" -" direction or management of such entity, whether by contract or\n" -" otherwise, or (ii) ownership of fifty percent (50%) or more of the\n" -" outstanding shares, or (iii) beneficial ownership of such entity.\n" -"\n" -" \"You\" (or \"Your\") shall mean an individual or Legal Entity\n" -" exercising permissions granted by this License.\n" -"\n" -" \"Source\" form shall mean the preferred form for making modifications,\n" -" including but not limited to software source code, documentation\n" -" source, and configuration files.\n" -"\n" -" \"Object\" form shall mean any form resulting from mechanical\n" -" transformation or translation of a Source form, including but\n" -" not limited to compiled object code, generated documentation,\n" -" and conversions to other media types.\n" -"\n" -" \"Work\" shall mean the work of authorship, whether in Source or\n" -" Object form, made available under the License, as indicated by a\n" -" copyright notice that is included in or attached to the work\n" -" (an example is provided in the Appendix below).\n" -"\n" -" \"Derivative Works\" shall mean any work, whether in Source or Object\n" -" form, that is based on (or derived from) the Work and for which the\n" -" editorial revisions, annotations, elaborations, or other modifications\n" -" represent, as a whole, an original work of authorship. For the purposes\n" -" of this License, Derivative Works shall not include works that remain\n" -" separable from, or merely link (or bind by name) to the interfaces of,\n" -" the Work and Derivative Works thereof.\n" -"\n" -" \"Contribution\" shall mean any work of authorship, including\n" -" the original version of the Work and any modifications or additions\n" -" to that Work or Derivative Works thereof, that is intentionally\n" -" submitted to Licensor for inclusion in the Work by the copyright owner\n" -" or by an individual or Legal Entity authorized to submit on behalf of\n" -" the copyright owner. For the purposes of this definition, \"submitted\"\n" -" means any form of electronic, verbal, or written communication sent\n" -" to the Licensor or its representatives, including but not limited to\n" -" communication on electronic mailing lists, source code control systems,\n" -" and issue tracking systems that are managed by, or on behalf of, the\n" -" Licensor for the purpose of discussing and improving the Work, but\n" -" excluding communication that is conspicuously marked or otherwise\n" -" designated in writing by the copyright owner as \"Not a Contribution.\"\n" -"\n" -" \"Contributor\" shall mean Licensor and any individual or Legal Entity\n" -" on behalf of whom a Contribution has been received by Licensor and\n" -" subsequently incorporated within the Work.\n" -"\n" -" 2. Grant of Copyright License. Subject to the terms and conditions of\n" -" this License, each Contributor hereby grants to You a perpetual,\n" -" worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n" -" copyright license to reproduce, prepare Derivative Works of,\n" -" publicly display, publicly perform, sublicense, and distribute the\n" -" Work and such Derivative Works in Source or Object form.\n" -"\n" -" 3. Grant of Patent License. Subject to the terms and conditions of\n" -" this License, each Contributor hereby grants to You a perpetual,\n" -" worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n" -" (except as stated in this section) patent license to make, have made,\n" -" use, offer to sell, sell, import, and otherwise transfer the Work,\n" -" where such license applies only to those patent claims licensable\n" -" by such Contributor that are necessarily infringed by their\n" -" Contribution(s) alone or by combination of their Contribution(s)\n" -" with the Work to which such Contribution(s) was submitted. If You\n" -" institute patent litigation against any entity (including a\n" -" cross-claim or counterclaim in a lawsuit) alleging that the Work\n" -" or a Contribution incorporated within the Work constitutes direct\n" -" or contributory patent infringement, then any patent licenses\n" -" granted to You under this License for that Work shall terminate\n" -" as of the date such litigation is filed.\n" -"\n" -" 4. Redistribution. You may reproduce and distribute copies of the\n" -" Work or Derivative Works thereof in any medium, with or without\n" -" modifications, and in Source or Object form, provided that You\n" -" meet the following conditions:\n" -"\n" -" (a) You must give any other recipients of the Work or\n" -" Derivative Works a copy of this License; and\n" -"\n" -" (b) You must cause any modified files to carry prominent notices\n" -" stating that You changed the files; and\n" -"\n" -" (c) You must retain, in the Source form of any Derivative Works\n" -" that You distribute, all copyright, patent, trademark, and\n" -" attribution notices from the Source form of the Work,\n" -" excluding those notices that do not pertain to any part of\n" -" the Derivative Works; and\n" -"\n" -" (d) If the Work includes a \"NOTICE\" text file as part of its\n" -" distribution, then any Derivative Works that You distribute must\n" -" include a readable copy of the attribution notices contained\n" -" within such NOTICE file, excluding those notices that do not\n" -" pertain to any part of the Derivative Works, in at least one\n" -" of the following places: within a NOTICE text file distributed\n" -" as part of the Derivative Works; within the Source form or\n" -" documentation, if provided along with the Derivative Works; or,\n" -" within a display generated by the Derivative Works, if and\n" -" wherever such third-party notices normally appear. The contents\n" -" of the NOTICE file are for informational purposes only and\n" -" do not modify the License. You may add Your own attribution\n" -" notices within Derivative Works that You distribute, alongside\n" -" or as an addendum to the NOTICE text from the Work, provided\n" -" that such additional attribution notices cannot be construed\n" -" as modifying the License.\n" -"\n" -" You may add Your own copyright statement to Your modifications and\n" -" may provide additional or different license terms and conditions\n" -" for use, reproduction, or distribution of Your modifications, or\n" -" for any such Derivative Works as a whole, provided Your use,\n" -" reproduction, and distribution of the Work otherwise complies with\n" -" the conditions stated in this License.\n" -"\n" -" 5. Submission of Contributions. Unless You explicitly state otherwise,\n" -" any Contribution intentionally submitted for inclusion in the Work\n" -" by You to the Licensor shall be under the terms and conditions of\n" -" this License, without any additional terms or conditions.\n" -" Notwithstanding the above, nothing herein shall supersede or modify\n" -" the terms of any separate license agreement you may have executed\n" -" with Licensor regarding such Contributions.\n" -"\n" -" 6. Trademarks. This License does not grant permission to use the trade\n" -" names, trademarks, service marks, or product names of the Licensor,\n" -" except as required for reasonable and customary use in describing the\n" -" origin of the Work and reproducing the content of the NOTICE file.\n" -"\n" -" 7. Disclaimer of Warranty. Unless required by applicable law or\n" -" agreed to in writing, Licensor provides the Work (and each\n" -" Contributor provides its Contributions) on an \"AS IS\" BASIS,\n" -" WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n" -" implied, including, without limitation, any warranties or conditions\n" -" of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n" -" PARTICULAR PURPOSE. You are solely responsible for determining the\n" -" appropriateness of using or redistributing the Work and assume any\n" -" risks associated with Your exercise of permissions under this License.\n" -"\n" -" 8. Limitation of Liability. In no event and under no legal theory,\n" -" whether in tort (including negligence), contract, or otherwise,\n" -" unless required by applicable law (such as deliberate and grossly\n" -" negligent acts) or agreed to in writing, shall any Contributor be\n" -" liable to You for damages, including any direct, indirect, special,\n" -" incidental, or consequential damages of any character arising as a\n" -" result of this License or out of the use or inability to use the\n" -" Work (including but not limited to damages for loss of goodwill,\n" -" work stoppage, computer failure or malfunction, or any and all\n" -" other commercial damages or losses), even if such Contributor\n" -" has been advised of the possibility of such damages.\n" -"\n" -" 9. Accepting Warranty or Additional Liability. While redistributing\n" -" the Work or Derivative Works thereof, You may choose to offer,\n" -" and charge a fee for, acceptance of support, warranty, indemnity,\n" -" or other liability obligations and/or rights consistent with this\n" -" License. However, in accepting such obligations, You may act only\n" -" on Your own behalf and on Your sole responsibility, not on behalf\n" -" of any other Contributor, and only if You agree to indemnify,\n" -" defend, and hold each Contributor harmless for any liability\n" -" incurred by, or claims asserted against, such Contributor by reason\n" -" of your accepting any such warranty or additional liability.\n" -"\n" -" END OF TERMS AND CONDITIONS\n" -"\n" -" APPENDIX: How to apply the Apache License to your work.\n" -"\n" -" To apply the Apache License to your work, attach the following\n" -" boilerplate notice, with the fields enclosed by brackets \"{}\"\n" -" replaced with your own identifying information. (Don't include\n" -" the brackets!) The text should be enclosed in the appropriate\n" -" comment syntax for the file format. We also recommend that a\n" -" file or class name and description of purpose be included on the\n" -" same \"printed page\" as the copyright notice for easier\n" -" identification within third-party archives.\n" -"\n" -" Copyright {yyyy} {name of copyright owner}\n" -"\n" -" Licensed under the Apache License, Version 2.0 (the \"License\");\n" -" you may not use this file except in compliance with the License.\n" -" You may obtain a copy of the License at\n" -"\n" -" http://www.apache.org/licenses/LICENSE-2.0\n" -"\n" -" Unless required by applicable law or agreed to in writing, software\n" -" distributed under the License is distributed on an \"AS IS\" BASIS,\n" -" WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" -" See the License for the specific language governing permissions and\n" -" limitations under the License.\n" -"\n"; - -const char* LICENSE = (const char*) temp_binary_data_3; - -//================== background_logo.svg ================== -static const unsigned char temp_binary_data_4[] = -"<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" -"<svg version=\"1.1\" id=\"Layer_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"\r\n" -"\t viewBox=\"0 0 451.7 451.7\" enable-background=\"new 0 0 451.7 451.7\" xml:space=\"preserve\">\r\n" -"<g>\r\n" -"\t<g>\r\n" -"\t\t<path fill=\"#808285\" d=\"M111.8,421.9c-8.7,0-15.6-3.2-21.8-11.3l8.5-7.3c4.2,5.5,8.2,7.6,13.3,7.6c9.2,0,15.5-6.9,15.5-17.5v-51.8\r\n" -"\t\t\th11.7v51.8C138.9,410.4,127.7,421.9,111.8,421.9z\"/>\r\n" -"\t\t<path fill=\"#808285\" d=\"M185.7,421.9c-17,0-31.6-12.5-31.6-33.1v-47.2h11.7v46.6c0,13.8,8.2,22.8,19.9,22.8c11.7,0,20-8.9,20-22.8\r\n" -"\t\t\tv-46.6h11.7v47.2C217.4,409.4,202.7,421.9,185.7,421.9z\"/>\r\n" -"\t\t<path fill=\"#808285\" d=\"M268.9,421.9c-22.6,0-40.9-18.1-40.9-40.6c0-22.6,18.5-40.6,40.9-40.6c10,0,18.8,3.5,25.7,9.2l-6.9,8.6\r\n" -"\t\t\tc-7.1-5-12-6.8-18.7-6.8c-16.2,0-29.1,13-29.1,29.7c0,16.7,12.9,29.7,29.1,29.7c6.4,0,11.8-2,18.6-6.7l7,8.7\r\n" -"\t\t\tC285.9,419.6,278.1,421.9,268.9,421.9z\"/>\r\n" -"\t\t<path fill=\"#808285\" d=\"M307.5,420.9v-79.3h47.8v10.5h-36.1v23.5h34.7V386h-34.7v24.4h36.1v10.5H307.5z\"/>\r\n" -"\t</g>\r\n" -"</g>\r\n" -"<g>\r\n" -"\t<path fill=\"#808285\" d=\"M222.6,313.3c-78.2,0-141.7-63.6-141.7-141.7S144.5,29.8,222.6,29.8s141.7,63.6,141.7,141.7\r\n" -"\t\tS300.8,313.3,222.6,313.3z M222.6,39.3c-72.9,0-132.3,59.3-132.3,132.3s59.3,132.3,132.3,132.3s132.3-59.3,132.3-132.3\r\n" -"\t\tS295.6,39.3,222.6,39.3z\"/>\r\n" -"\t<path fill=\"#414042\" d=\"M334.5,166.8c2.4,0,4.8-0.9,6.5-2.6c1.9-1.9,2.7-4.4,2.4-7c-2.6-22.2-11.4-43.3-25.3-60.9\r\n" -"\t\tc-1.7-2.2-4.1-3.3-6.6-3.3c-2.3,0-4.5,1-6.2,2.7L236.9,164c-1.1,1.1-0.3,2.9,1.2,2.9L334.5,166.8z\"/>\r\n" -"\t<path fill=\"#58595B\" d=\"M311.5,250.2L311.5,250.2c2.6,0,4.9-1.2,6.6-3.3c13.9-17.6,22.6-38.7,25.3-60.9c0.3-2.6-0.6-5.1-2.4-7\r\n" -"\t\tc-1.7-1.7-4.1-2.6-6.5-2.6l-96.4,0c-1.5,0-2.2,1.8-1.2,2.9l68.4,68.4C307,249.2,309.2,250.2,311.5,250.2z\"/>\r\n" -"\t<path fill=\"#6D6E71\" d=\"M229.9,290L229.9,290c1.8,1.8,4.3,2.7,7.1,2.3c22.3-2.6,43.4-11.3,60.9-25.2c2.1-1.6,3.2-4,3.3-6.7\r\n" -"\t\tc0-2.4-1-4.7-2.8-6.4l-68.1-68.1c-1.1-1.1-2.9-0.3-2.9,1.2l0,96.7C227.4,286.1,228.2,288.4,229.9,290z\"/>\r\n" -"\t<path fill=\"#A7A9AC\" d=\"M133.8,92.9c-2.6,0-4.9,1.2-6.6,3.3c-13.9,17.6-22.6,38.7-25.3,60.9c-0.3,2.6,0.6,5.1,2.4,7\r\n" -"\t\tc1.7,1.7,4.1,2.6,6.5,2.6l96.4,0c1.5,0,2.2-1.8,1.2-2.9L140,95.6C138.3,93.9,136.1,92.9,133.8,92.9z\"/>\r\n" -"\t<path fill=\"#BCBEC0\" d=\"M215.4,53.1c-1.8-1.8-4.3-2.7-7.1-2.3C186.1,53.4,165,62.1,147.4,76c-2.1,1.6-3.2,4-3.3,6.7\r\n" -"\t\tc0,2.4,1,4.7,2.8,6.4l68.1,68.1c1.1,1.1,2.9,0.3,2.9-1.2l0-96.7C217.9,57,217,54.8,215.4,53.1z\"/>\r\n" -"\t<path fill=\"#D1D3D4\" d=\"M301.3,82.7c0-2.6-1.2-4.9-3.3-6.6c-17.6-13.9-38.7-22.6-60.9-25.3c-2.6-0.3-5.1,0.6-7,2.4\r\n" -"\t\tc-1.7,1.7-2.6,4.1-2.6,6.5l0,96.4c0,1.5,1.8,2.2,2.9,1.2l68.4-68.4C300.3,87.2,301.3,85,301.3,82.7z\"/>\r\n" -"\t<path fill=\"#939598\" d=\"M207.2,176.3l-96.4,0c-2.4,0-4.8,0.9-6.5,2.6c-1.9,1.9-2.7,4.4-2.4,7c2.6,22.2,11.4,43.3,25.3,60.9\r\n" -"\t\tc1.7,2.2,4.1,3.3,6.6,3.3c2.3,0,4.5-1,6.2-2.7c0,0,0,0,0,0l68.4-68.4C209.4,178.1,208.7,176.3,207.2,176.3z\"/>\r\n" -"\t<path fill=\"#808285\" d=\"M215.1,185.8L146.9,254c-1.7,1.7-2.8,4-2.8,6.4c0,2.7,1.2,5.1,3.3,6.7c17.6,13.9,38.6,22.6,60.9,25.2\r\n" -"\t\tc2.7,0.3,5.2-0.5,7.1-2.3c1.6-1.6,2.5-3.8,2.5-6.3c0,0,0,0,0,0l0-96.7C217.9,185.5,216.1,184.8,215.1,185.8z\"/>\r\n" -"</g>\r\n" -"</svg>\r\n"; - -const char* background_logo_svg = (const char*) temp_binary_data_4; - -//================== export_android.svg ================== -static const unsigned char temp_binary_data_5[] = -"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" -"<svg width=\"19px\" height=\"23px\" viewBox=\"0 0 19 23\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n" -" <!-- Generator: Sketch 43.1 (39012) - http://www.bohemiancoding.com/sketch -->\n" -" <title>androd</title>\n" -" <desc>Created with Sketch.</desc>\n" -" <defs></defs>\n" -" <g id=\"Page-1\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n" -" <g id=\"Artboard\" transform=\"translate(-71.000000, -8.000000)\" fill-rule=\"nonzero\">\n" -" <g id=\"android\" transform=\"translate(67.000000, 6.000000)\">\n" -" <g id=\"androd\" transform=\"translate(4.149701, 2.592000)\">\n" -" <path d=\"M12.0887784,1.906092 L13.1751916,0.325404 C13.2397006,0.231444 13.2236407,0.108108 13.1392994,0.049788 C13.0550659,-0.008208 12.9342395,0.020466 12.8702156,0.114534 L11.7411198,1.75662 C10.9970299,1.462914 10.1707545,1.2" -"9924 9.29985629,1.29924 C8.42895808,1.29924 7.60246707,1.462752 6.85843114,1.75662 L5.72949701,0.11448 C5.66477246,0.02052 5.54416168,-0.008262 5.45987425,0.049734 C5.37558683,0.107892 5.35958084,0.231282 5.42408982,0.32535 L6.51088024,1.906038 C4.78" -"293413,2.711502 3.57116766,4.242078 3.41676647,6.028398 L15.1822994,6.028398 C15.0284371,4.242078 13.8166168,2.711556 12.0887784,1.906092\" id=\"Shape\" fill=\"#9FBF3B\"></path>\n" -" <path d=\"M6.84194012,4.397652 C6.48231737,4.397652 6.19092216,4.105674 6.19092216,3.745386 C6.19092216,3.385152 6.48215569,3.093066 6.84194012,3.093066 C7.20129341,3.093066 7.49258084,3.385044 7.49258084,3.745386 C7.49263473,4.10" -"562 7.20129341,4.397652 6.84194012,4.397652\" id=\"Shape\" fill=\"#FFFFFF\"></path>\n" -" <path d=\"M11.7571796,4.397652 C11.3978263,4.397652 11.106485,4.105674 11.106485,3.745386 C11.106485,3.385044 11.3978263,3.093066 11.7571796,3.093066 C12.1169102,3.093066 12.4081437,3.385152 12.4081437,3.745386 C12.4081437,4.10562" -" 12.1168024,4.397652 11.7571796,4.397652\" id=\"Shape\" fill=\"#FFFFFF\"></path>\n" -" <path d=\"M2.66135928,13.478292 C2.66135928,14.204592 2.07371856,14.793408 1.34881437,14.793408 L1.34881437,14.793408 C0.623964072,14.793408 0.0363233533,14.204592 0.0363233533,13.478292 L0.0363233533,8.15886 C0.0363233533,7.43256" -" 0.623964072,6.843744 1.34881437,6.843744 L1.34881437,6.843744 C2.07371856,6.843744 2.66135928,7.43256 2.66135928,8.15886 L2.66135928,13.478292 Z\" id=\"Shape\" fill=\"#9FBF3B\"></path>\n" -" <path d=\"M3.4165509,6.884406 L3.4165509,16.491816 C3.4165509,17.06238 3.87819162,17.524998 4.44777844,17.524998 L5.66752096,17.524998 L5.66752096,20.481174 C5.66752096,21.207528 6.25510778,21.79629 6.98001198,21.79629 C7.70491617" -",21.79629 8.29255689,21.207528 8.29255689,20.481174 L8.29255689,17.524998 L10.3065629,17.524998 L10.3065629,20.481174 C10.3065629,21.207528 10.8940958,21.79629 11.6190539,21.79629 C12.344012,21.79629 12.9315449,21.207528 12.9315449,20.481174 L12.9315" -"449,17.524998 L14.1512874,17.524998 C14.7208743,17.524998 15.1826228,17.06265 15.1826228,16.491816 L15.1826228,6.884406 L3.4165509,6.884406 Z\" id=\"Shape\" fill=\"#9FBF3B\"></path>\n" -" <path d=\"M15.9377605,13.478292 C15.9377605,14.204592 16.5253473,14.793408 17.2502515,14.793408 L17.2502515,14.793408 C17.9751018,14.793408 18.5627425,14.204592 18.5627425,13.478292 L18.5627425,8.15886 C18.5627425,7.43256 17.97510" -"18,6.843744 17.2502515,6.843744 L17.2502515,6.843744 C16.5253473,6.843744 15.9377605,7.43256 15.9377605,8.15886 L15.9377605,13.478292 Z\" id=\"Shape\" fill=\"#9FBF3B\"></path>\n" -" </g>\n" -" </g>\n" -" </g>\n" -" </g>\n" -"</svg>"; - -const char* export_android_svg = (const char*) temp_binary_data_5; - -//================== export_clion.svg ================== -static const unsigned char temp_binary_data_6[] = -"<svg id=\"Layer_1\" data-name=\"Layer 1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 128 128\">\n" -" <defs>\n" -" <linearGradient id=\"linear-gradient\" x1=\"40.69\" y1=\"-676.56\" x2=\"83.48\" y2=\"-676.56\" gradientTransform=\"matrix(1, 0, 0, -1, 0, -648.86)\" gradientUnits=\"userSpaceOnUse\">\n" -" <stop offset=\"0\" stop-color=\"#ed358c\"/>\n" -" <stop offset=\"0.16\" stop-color=\"#e9388c\"/>\n" -" <stop offset=\"0.3\" stop-color=\"#de418c\"/>\n" -" <stop offset=\"0.43\" stop-color=\"#cc508c\"/>\n" -" <stop offset=\"0.57\" stop-color=\"#b2658d\"/>\n" -" <stop offset=\"0.7\" stop-color=\"#90808d\"/>\n" -" <stop offset=\"0.83\" stop-color=\"#67a18e\"/>\n" -" <stop offset=\"0.95\" stop-color=\"#37c78f\"/>\n" -" <stop offset=\"1\" stop-color=\"#22d88f\"/>\n" -" </linearGradient>\n" -" <linearGradient id=\"linear-gradient-2\" x1=\"32.58\" y1=\"-665.27\" x2=\"13.76\" y2=\"-791.59\" gradientTransform=\"matrix(1, 0, 0, -1, 0, -648.86)\" gradientUnits=\"userSpaceOnUse\">\n" -" <stop offset=\"0.09\" stop-color=\"#22d88f\"/>\n" -" <stop offset=\"0.9\" stop-color=\"#029de0\"/>\n" -" </linearGradient>\n" -" <linearGradient id=\"linear-gradient-3\" x1=\"116.68\" y1=\"-660.66\" x2=\"-12.09\" y2=\"-796.66\" xlink:href=\"#linear-gradient-2\"/>\n" -" <linearGradient id=\"linear-gradient-4\" x1=\"73.35\" y1=\"-739.1\" x2=\"122.29\" y2=\"-746.06\" xlink:href=\"#linear-gradient-2\"/>\n" -" </defs>\n" -" <title>icon_CLion</title>\n" -" <g>\n" -" <polygon points=\"49.2 51.8 40.6 55.4 48.4 0 77.8 16.2 49.2 51.8\" fill=\"url(#linear-gradient)\"/>\n" -" <polygon points=\"44.6 76.8 48.8 0 11.8 23.2 0 94 44.6 76.8\" fill=\"url(#linear-gradient-2)\"/>\n" -" <polygon points=\"125.4 38.4 109 4.8 77.8 16.2 55 41.4 0 94 41.6 124.4 93.6 77.2 125.4 38.4\" fill=\"url(#linear-gradient-3)\"/>\n" -" <polygon points=\"53.8 54.6 46.6 98.4 75.8 121 107.8 128 128 82.4 53.8 54.6\" fill=\"url(#linear-gradient-4)\"/>\n" -" </g>\n" -" <g>\n" -" <rect x=\"24\" y=\"24\" width=\"80\" height=\"80\"/>\n" -" <rect x=\"31.6\" y=\"89\" width=\"30\" height=\"5\" fill=\"#fff\"/>\n" -" <path d=\"M31,51.2h0A16.83,16.83,0,0,1,48.2,34c6.2,0,10,2,13,5.2l-4.6,5.4c-2.6-2.4-5.2-3.8-8.4-3.8-5.6,0-9.6,4.6-9.6,10.4h0c0,5.6,4,10.4,9.6,10.4,3.8,0,6.2-1.6,8.8-3.8l4.6,4.6c-3.4,3.6-7.2,6-13.6,6A17,17,0,0,1,31,51.2\" fill=\"#fff\"/>\n" -" <path d=\"M66.6,34.4H74v27H88.4v6.2H66.6V34.4Z\" fill=\"#fff\"/>\n" -" </g>\n" -"</svg>\n"; - -const char* export_clion_svg = (const char*) temp_binary_data_6; - -//================== export_codeBlocks.svg ================== -static const unsigned char temp_binary_data_7[] = -"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" -"<svg width=\"20px\" height=\"20px\" viewBox=\"0 0 20 20\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n" -" <!-- Generator: Sketch 43.1 (39012) - http://www.bohemiancoding.com/sketch -->\n" -" <title>Group</title>\n" -" <desc>Created with Sketch.</desc>\n" -" <defs></defs>\n" -" <g id=\"Page-1\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n" -" <g id=\"Artboard\" transform=\"translate(-33.000000, -4.000000)\">\n" -" <g id=\"Group\" transform=\"translate(33.000000, 4.000000)\">\n" -" <polygon id=\"Rectangle-5-Copy-4\" fill=\"#FD3535\" points=\"7.36842105 -1.87919855e-13 9.47368421 4.21052632 9.47368421 9.47368421 4.21052632 9.47368421 6.83692868e-14 7.36842105 3.55271368e-15 -1.67409946e-14\"></polygon>\n" -" <polygon id=\"Rectangle-5-Copy-5\" fill=\"#6AC300\" transform=\"translate(15.263158, 4.736842) scale(-1, 1) translate(-15.263158, -4.736842) \" points=\"17.8947368 -1.87919855e-13 20 4.21052632 20 9.47368421 14.7368421 9.47368421 10.5" -"263158 7.36842105 10.5263158 -1.67409946e-14\"></polygon>\n" -" <polygon id=\"Rectangle-5-Copy-7\" fill=\"#EBBF20\" transform=\"translate(4.736842, 15.263158) scale(1, -1) translate(-4.736842, -15.263158) \" points=\"7.36842105 10.5263158 9.47368421 14.7368421 9.47368421 20 4.21052632 20 6.8369286" -"8e-14 17.8947368 3.55271368e-15 10.5263158\"></polygon>\n" -" <polygon id=\"Rectangle-5-Copy-6\" fill=\"#1F6CE9\" transform=\"translate(15.263158, 15.263158) scale(-1, -1) translate(-15.263158, -15.263158) \" points=\"17.8947368 10.5263158 20 14.7368421 20 20 14.7368421 20 10.5263158 17.8947368 " -"10.5263158 10.5263158\"></polygon>\n" -" </g>\n" -" </g>\n" -" </g>\n" -"</svg>"; - -const char* export_codeBlocks_svg = (const char*) temp_binary_data_7; - -//================== export_linux.svg ================== -static const unsigned char temp_binary_data_8[] = -"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" -"<svg width=\"63px\" height=\"75px\" viewBox=\"0 0 63 75\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n" -" <!-- Generator: Sketch 43.1 (39012) - http://www.bohemiancoding.com/sketch -->\n" -" <title>Android</title>\n" -" <desc>Created with Sketch.</desc>\n" -" <defs></defs>\n" -" <g id=\"Page-1\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n" -" <g id=\"Artboard\" transform=\"translate(-115.000000, -15.000000)\" fill-rule=\"nonzero\">\n" -" <g id=\"Android\" transform=\"translate(115.000000, 15.000000)\">\n" -" <path d=\"M46.1535022,26.1203623 C46.9768865,27.8918861 47.8751239,29.6135078 48.6735572,31.3850316 C50.2205216,34.8033239 51.3932204,38.3962736 51.8922412,42.1139784 C52.391262,45.8316832 52.1667026,49.6741432 50.9940038,53.2171908 C" -"49.6715987,57.2343081 47.2014459,60.8023067 44.1324681,63.7465293 C40.5145674,67.2147237 35.8986252,69.8844849 30.8834663,70.0840932 C27.6148802,70.2088484 24.3712451,69.28566 21.5018756,67.7636466 C19.0816248,66.4911436 16.8609823,64.7944729 15.0894" -"586,62.6985856 C13.3179348,60.6026983 12.0204807,58.1075944 11.3967048,55.4378333 C10.6481736,52.1442961 10.9974881,48.6511506 12.1202849,45.4823687 C12.9187182,43.2118241 14.116368,41.0909858 14.9896544,38.8453923 C15.9128428,36.3752394 16.4368147,3" -"3.7553803 17.6843666,31.4099826 C18.8071634,29.2891443 20.478883,27.4926695 21.3771204,25.272027 C21.9010922,23.9496219 22.1506026,22.5274127 22.4749661,21.1301545 C22.8242807,19.7328963 23.2983504,18.3605892 24.2464899,17.2627434 C25.3692867,15.9652" -"894 27.0659573,15.2666603 28.787579,15.067052 C30.4842497,14.8674437 32.2308224,15.1419051 33.902542,15.5161707 C35.2498981,15.8155832 36.5473522,16.1898488 37.8448062,16.6639185 C38.9426519,17.0631351 40.0404976,17.5122538 40.9886371,18.1859319 C42." -"2860912,19.1091203 43.2841327,20.4065744 44.0576149,21.8038326 C44.8310972,23.2010907 45.5047752,24.6732021 46.1535022,26.1203623\" id=\"path29670-2\" fill=\"#020204\"></path>\n" -" <path d=\"M32.3071772,70.3379664 C33.6794843,70.4128195 35.0517915,70.5625257 36.3991476,70.7621341 C37.5967974,70.9367913 38.7694963,71.1863017 39.9671462,71.4607632 C41.813523,71.9098819 43.6349489,72.4837558 45.5312279,72.5336578 C" -"46.0302487,72.5586089 46.5292694,72.5336578 47.0282902,72.4089026 C47.527311,72.3090985 47.9764297,72.1094902 48.3756463,71.7851267 C48.9495202,71.3110569 49.3237858,70.6124278 49.4734921,69.8888477 C49.6231983,69.1652676 49.5233941,68.3917853 49.323" -"7858,67.6931563 C48.8996182,66.270947 47.9764297,65.0483461 47.2278985,63.7758431 C46.8037309,63.052263 46.4045142,62.2787808 45.9304445,61.5801517 C45.4563748,60.8815226 44.8825009,60.2078445 44.1838718,59.7587258 C43.1858302,59.1099988 41.9632293,5" -"8.9103905 40.7905304,59.0351457 C39.6178316,59.1599009 38.4950348,59.5840685 37.4470912,60.1080404 C35.9749799,60.8565715 34.6026728,61.9045152 33.8042395,63.3516754 C33.5297781,63.8506962 33.3301698,64.3996191 33.0806594,64.9235909 C32.8561,65.44756" -"27 32.5566875,65.9715346 32.1574709,66.3707512 C31.7083522,66.8198699 31.1344783,67.1442334 30.6604086,67.5933521 C30.4358492,67.8179114 30.2362409,68.0674218 30.1114857,68.3668343 C29.9867305,68.6662468 29.9617795,69.0155613 30.0615836,69.3149738 C3" -"0.1364368,69.5145821 30.2611919,69.7141904 30.4358492,69.8389456 C30.6105065,69.9886518 30.8101148,70.088456 31.0097231,70.1633091 C31.4338908,70.2880643 31.8830095,70.3130154 32.3071772,70.3379664\" id=\"path29676-3\" fill=\"#020204\"></path>\n" -" <path d=\"M27.9409416,70.2361543 C26.7931938,70.2611053 25.6703971,70.4607136 24.5476003,70.710224 C23.4747056,70.9347834 22.401811,71.1842938 21.3538673,71.4587552 C19.5573925,71.9328249 17.7858687,72.4817478 15.9394918,72.5316499 C1" -"5.4654221,72.5316499 14.9664013,72.5066988 14.4923316,72.4068947 C14.0182618,72.3070905 13.5691431,72.1074822 13.1699265,71.8080697 C12.5960526,71.334 12.221787,70.6603219 12.0720808,69.9117908 C11.9223745,69.1632596 12.0221787,68.4147284 12.221787,6" -"7.7160993 C12.6459547,66.2938901 13.5441921,65.0712892 14.2927233,63.7987862 C14.7168909,63.0752061 15.0911565,62.3017238 15.5402752,61.6030947 C15.9893939,60.9044656 16.5383168,60.2307876 17.2618969,59.7567179 C18.2100364,59.1329419 19.4076863,58.90" -"83825 20.5554341,59.0331377 C21.7031819,59.1578929 22.8010276,59.5571095 23.7990692,60.1060324 C25.2212784,60.8795146 26.5187324,61.9524093 27.3421167,63.3496675 C27.9159906,64.322758 28.2653052,65.4455548 28.9389832,66.3687432 C29.3132488,66.867764 " -"29.7623675,67.2919317 30.06178,67.8159035 C30.2114862,68.0903649 30.3112904,68.3648263 30.3611924,68.6891898 C30.3861435,68.9886023 30.3112904,69.3129658 30.1615841,69.5624762 C30.0368289,69.7371335 29.8871227,69.8618887 29.7124654,69.9616928 C29.537" -"8081,70.061497 29.3381998,70.1363501 29.1385915,70.1613012 C28.7643259,70.2361543 28.3401583,70.2361543 27.9409416,70.2361543\" id=\"path29676-7-1\" fill=\"#020204\"></path>\n" -" <path d=\"M21.3925244,22.15769 C21.2428181,20.211509 21.2677692,18.290279 21.192916,16.3440979 C21.1180629,14.47277 20.9434057,12.6263931 21.0182588,10.7550652 C21.0931119,8.85878618 21.3925244,6.93755617 22.2408597,5.24088552 C23.089" -"195,3.54421486 24.4615022,2.09705459 26.1332218,1.19881718 C27.7051373,0.350481853 29.5265631,-0.0237837335 31.2980869,0.0011673056 C33.7183377,0.0261183447 36.1635395,0.749698478 38.1097206,2.17190771 C39.3323215,3.07014511 40.3802651,4.21789291 41." -"2036494,5.49039591 C41.9022785,6.58824163 42.4512014,7.7858915 42.7755649,9.03344346 C43.474194,11.6034005 43.2995367,14.2981127 43.4492429,16.9678739 C43.5739981,19.4879288 43.9732147,22.0079838 43.8484595,24.5280387 C43.8235085,25.0769616 43.748655" -"4,25.6258845 43.524096,26.1249052 C43.2745856,26.598975 42.875369,26.9981916 42.4262503,27.247702 C41.9521806,27.5221634 41.4531598,27.6718697 40.9042369,27.7467228 C39.8562933,27.9213801 38.7833986,27.7966249 37.7105039,27.896429 C36.1635395,28.0461" -"352 34.6914282,28.6200091 33.1694148,28.8445685 C31.347989,29.1190299 29.476661,28.9194216 27.6552352,28.8445685 C26.906704,28.8196175 26.1831239,28.7946664 25.4345927,28.7198133 C24.7110126,28.6200091 23.9624814,28.4453519 23.3137544,28.0960373 C22." -"9145377,27.871478 22.5402722,27.5970165 22.2408597,27.272653 C21.9414472,26.9233385 21.7168879,26.5241219 21.5921327,26.0750032 C21.4174754,25.4013251 21.5172796,24.727647 21.5172796,24.029018 C21.5172796,23.405242 21.4424264,22.781466 21.3925244,22." -"15769\" id=\"path28712-2\" fill=\"#020204\"></path>\n" -" <path d=\"M24.4857731,22.0829382 C24.2362627,22.4073017 24.0616054,22.8065184 23.9618013,23.205735 C23.8619971,23.6049516 23.812095,24.0291193 23.812095,24.453287 C23.787144,25.3016223 23.8370461,26.1499576 23.6124867,26.9483909 C23.3" -"879274,27.8216772 22.8390045,28.5702084 22.3150327,29.2937885 C21.4167953,30.5662915 20.5185579,31.8637456 20.0694392,33.3358569 C19.7949777,34.2340943 19.7201246,35.1822338 19.8199288,36.1303733 C18.8218872,37.6024846 17.9486009,39.1744 17.2250207,4" -"0.8211686 C16.127175,43.2913215 15.3786438,45.9361316 15.1041824,48.6308438 C14.7798189,51.924381 15.2039866,55.3426734 16.5014406,58.3867001 C17.4495801,60.5823916 18.8468383,62.6034257 20.6682641,64.1753412 C21.5914526,64.9737744 22.6144452,65.6474" -"525 23.7122909,66.1963754 C27.5048488,68.0677033 32.1956442,68.0677033 35.9383,66.0716202 C37.8844811,65.0236765 39.5312497,63.5016631 41.1281162,61.9796498 C42.0762557,61.0564613 43.0243951,60.1083218 43.7729263,58.9855251 C45.1701845,56.8397357 45." -"6692053,54.2448276 45.9686178,51.6998216 C46.4925896,47.2585367 46.5175406,42.5427903 44.5713596,38.525673 C43.8976815,37.1284148 42.9994441,35.8559118 41.9265494,34.7580661 C41.652088,32.8118851 41.0782141,30.9156061 40.2548298,29.1440823 C39.656004" -"9,27.8466283 38.9324247,26.6240274 38.3835019,25.3265733 C38.1589425,24.8026015 37.9593342,24.2536786 37.7098238,23.7297068 C37.4603134,23.205735 37.160901,22.7067142 36.7367333,22.3074976 C36.3125656,21.908281 35.7636428,21.6088685 35.2147199,21.409" -"2602 C34.640846,21.2346029 34.0669721,21.1347988 33.4681472,21.1098477 C32.2704973,21.0599456 31.0977985,21.2096519 29.9001486,21.1597498 C28.9520091,21.1098477 28.0038696,20.9601415 27.0557301,21.0100436 C26.5816604,21.0349946 26.1075906,21.1347988 " -"25.6584719,21.309456 C25.2093532,21.4841133 24.7851856,21.7086727 24.4857731,22.0829382\" id=\"path29719-5\" fill=\"#FDFDFB\"></path>\n" -" <path d=\"M25.1049189,11.0038778 C24.6558002,11.0288289 24.2316326,11.2284372 23.9072691,11.5278496 C23.5829056,11.8272621 23.3583462,12.2264787 23.20864,12.6506464 C22.9341785,13.4989817 22.9840806,14.4221702 23.0589337,15.2954566 C2" -"3.1088358,16.0938898 23.1836889,16.9172741 23.4831014,17.6658053 C23.6328076,18.0400709 23.857367,18.3893854 24.1318284,18.6887979 C24.4062898,18.9882103 24.7805554,19.1878187 25.154821,19.2876228 C25.5290866,19.387427 25.9033522,19.3624759 26.277617" -"8,19.2377207 C26.6269323,19.1129655 26.9762469,18.9133572 27.2257573,18.6638468 C27.6249739,18.2895812 27.8744843,17.7656094 28.0491416,17.2416376 C28.1988478,16.7176658 28.2487499,16.1437919 28.2487499,15.594869 C28.2487499,14.8962399 28.1489457,14." -"2225619 27.9243864,13.5488838 C27.699827,12.9001568 27.3754635,12.2763808 26.8764427,11.77736 C26.6518834,11.5278496 26.3774219,11.3282413 26.0780095,11.1785351 C25.778597,11.0787309 25.4542335,10.9789268 25.1049189,11.0038778\" id=\"path28795-9-5\" " -"fill=\"#FDFDFB\"></path>\n" -" <path d=\"M32.7547573,11.5576557 C32.0561282,12.0317255 31.4822543,12.7054035 31.2077928,13.5038368 C30.8584783,14.5018783 30.9832335,15.6246751 31.332548,16.6227167 C31.6818626,17.6457093 32.2806875,18.6187998 33.1789249,19.2425758 C" -"33.6280436,19.5419882 34.1520155,19.7665476 34.6759873,19.8164497 C35.2249101,19.8913028 35.773833,19.7914986 36.2479027,19.5419882 C36.8467277,19.2425758 37.2708953,18.6936529 37.5703078,18.094828 C37.8447692,17.496003 37.9695244,16.822325 37.994475" -"5,16.173598 C38.0443776,15.3252626 37.9695244,14.4769273 37.695063,13.678494 C37.3956505,12.8052077 36.8467277,12.0067744 36.0732455,11.5077536 C35.6989799,11.2582433 35.2498612,11.083586 34.8007425,11.0336839 C34.3516238,10.9588308 33.877554,11.0087" -"329 33.4533864,11.1833901 C33.1789249,11.2831943 32.9543656,11.4079495 32.7547573,11.5576557\" id=\"path28795-3\" fill=\"#FDFDFB\"></path>\n" -" <g id=\"g28965-1\" transform=\"translate(33.000000, 13.000000)\" fill=\"#020204\">\n" -" <path d=\"M1.79647481,0.0998041564 C1.54696442,0.124755195 1.27250299,0.199608313 1.04794364,0.349314547 C0.82338429,0.499020782 0.648727016,0.673678056 0.499020782,0.898237407 C0.199608313,1.32240507 0.0748531173,1.84637689 0.049" -"9020782,2.37034871 C0.0249510391,2.76956534 0.0748531173,3.16878196 0.199608313,3.51809651 C0.324363508,3.8923621 0.54892286,4.24167665 0.848335329,4.49118704 C1.1477478,4.74069743 1.54696442,4.89040366 1.94618105,4.9153547 C2.34539767,4.94030574 2.7" -"446143,4.81555055 3.09392885,4.59099119 C3.36839028,4.41633392 3.56799859,4.16682353 3.71770482,3.86741106 C3.86741106,3.59294963 3.96721522,3.26858612 3.99216625,2.94422261 C4.06701937,2.39529975 3.99216625,1.79647481 3.71770482,1.29745403 C3.468194" -"43,0.798433251 3.01907573,0.374265586 2.49510391,0.174657274 C2.27054456,0.124755195 2.02103417,0.0748531173 1.79647481,0.0998041564\" id=\"path28879-6\"></path>\n" -" </g>\n" -" <g id=\"g29497-8\" transform=\"translate(24.000000, 14.000000)\" fill=\"#020204\">\n" -" <path d=\"M0.224559352,1.42220923 C0.124755195,1.97113209 0.124755195,2.56995703 0.324363508,3.09392885 C0.449118704,3.44324339 0.673678056,3.7676069 0.923188446,4.04206833 C1.09784572,4.21672561 1.27250299,4.39138288 1.49706235,4" -".49118704 C1.7216217,4.59099119 1.97113209,4.64089327 2.22064248,4.59099119 C2.44520183,4.54108912 2.64481014,4.39138288 2.76956534,4.21672561 C2.91927157,4.04206833 2.99412469,3.81750898 3.06897781,3.61790067 C3.26858612,2.96917365 3.24363508,2.2705" -"4456 3.04402677,1.64676858 C2.89432053,1.17269884 2.66976118,0.723580134 2.2954956,0.424167665 C2.12083832,0.27446143 1.92123001,0.149706235 1.67171962,0.0998041564 C1.44716027,0.0499020782 1.19764988,0.0499020782 0.998041564,0.149706235 C0.773482212" -",0.249510391 0.573873899,0.449118704 0.474069743,0.698629095 C0.349314547,0.923188446 0.27446143,1.17269884 0.224559352,1.42220923\" id=\"path29453-9\"></path>\n" -" </g>\n" -" <g id=\"g29634-9\" transform=\"translate(22.999845, 16.000000)\">\n" -" <path d=\"M0,5.72292607 C0.0249510391,5.79777918 0.0499020782,5.8726323 0.0748531173,5.92253438 C0.149706235,6.02233853 0.249510391,6.12214269 0.349314547,6.19699581 C0.449118704,6.27184893 0.573873899,6.34670204 0.673678056,6.396" -"60412 C1.24755195,6.77086971 1.7216217,7.26989049 2.14578936,7.81881335 C2.71966326,8.54239348 3.21868404,9.36577777 3.96721522,9.88974959 C4.49118704,10.2640152 5.13991405,10.4885745 5.78864107,10.5384766 C6.56212328,10.6133297 7.31065445,10.4885745" -" 8.05918563,10.2640152 C8.73286368,10.0644069 9.40654174,9.78994544 10.0053667,9.41567985 C11.1531145,8.71705076 12.101254,7.66910712 13.373757,7.19503737 C13.6482184,7.09523322 13.9476309,7.0203801 14.1971412,6.8956249 C14.4716027,6.77086971 14.7211" -"131,6.57126139 14.8458683,6.321751 C14.9706235,6.07224061 14.9706235,5.77282814 14.9955745,5.49836671 C15.0454766,5.19895424 15.1452807,4.89954178 15.1951828,4.60012931 C15.2450849,4.30071684 15.2450849,3.97635333 15.1203297,3.7018919 C15.0205255,3.4" -"7733255 14.8209172,3.30267527 14.5963579,3.17792008 C14.3717985,3.05316488 14.1222881,3.0032628 13.8727777,3.0032628 C13.373757,2.97831177 12.8747362,3.10306696 12.3757154,3.15296904 C11.7269884,3.20287112 11.0533103,3.128018 10.3796323,3.15296904 C9" -".55624797,3.17792008 8.73286368,3.35257735 7.90947939,3.40247943 C6.96133991,3.45238151 6.03815146,3.30267527 5.09001198,3.2527732 C4.69079535,3.22782216 4.26662769,3.22782216 3.86741106,3.30267527 C3.46819443,3.37752839 3.06897781,3.50228359 2.74461" -"43,3.75179398 C2.42025079,3.97635333 2.14578936,4.2757658 1.84637689,4.55022723 C1.69667066,4.67498242 1.54696442,4.79973762 1.34735611,4.87459074 C1.1477478,4.94944385 0.973090525,5.02429697 0.773482212,4.99934593 C0.673678056,4.99934593 0.573873899" -",4.97439489 0.474069743,4.99934593 C0.424167665,5.02429697 0.349314547,5.04924801 0.324363508,5.09915009 C0.299412469,5.14905217 0.249510391,5.19895424 0.199608313,5.24885632 C0.124755195,5.44846464 0.0499020782,5.57321983 0,5.72292607\" id=\"path284" -"61-2\" fill=\"#FFB510\"></path>\n" -" <g id=\"path27476-7-8\" transform=\"translate(0.000000, 3.000000)\" fill=\"#604405\">\n" -" <path d=\"M1.52201338,1.32240507 C1.19764988,1.52201338 0.873286368,1.74657274 0.54892286,1.97113209 C0.374265586,2.09588728 0.224559352,2.22064248 0.124755195,2.39529975 C0.0748531173,2.52005495 0.0499020782,2.66976118 0.0499" -"020782,2.81946742 L0.0499020782,3.24363508 C0.0249510391,3.34343924 0,3.44324339 0,3.54304755 C0,3.59294963 0,3.64285171 0.0249510391,3.69275379 C0.0499020782,3.74265586 0.0499020782,3.79255794 0.0998041564,3.81750898 C0.149706235,3.86741106 0.199608" -"313,3.8923621 0.249510391,3.91731314 C0.299412469,3.94226418 0.374265586,3.94226418 0.424167665,3.96721522 C0.723580134,4.04206833 0.973090525,4.21672561 1.19764988,4.41633392 C1.42220923,4.61594223 1.62181754,4.84050158 1.84637689,5.0401099 C2.47015" -"287,5.56408172 3.3184882,5.76369003 4.14187249,5.78864107 C4.96525678,5.81359211 5.76369003,5.63893484 6.56212328,5.46427756 C7.18589926,5.31457133 7.80967524,5.16486509 8.40850017,4.96525678 C9.33168862,4.61594223 10.180024,4.11692145 10.9285551,3.4" -"6819443 C11.2529186,3.16878196 11.5772821,2.84441846 11.9515477,2.6198591 C12.2759112,2.42025079 12.6501768,2.27054456 12.9994914,2.07093624 C13.0244424,2.04598521 13.0493934,2.04598521 13.0992955,2.02103417 C13.1242466,1.99608313 13.1491976,1.971132" -"09 13.1741486,1.94618105 C13.1990997,1.89627897 13.1990997,1.82142585 13.1741486,1.77152378 C13.1491976,1.7216217 13.1242466,1.67171962 13.0743445,1.62181754 C13.0244424,1.57191546 12.9745403,1.52201338 12.9246383,1.47211131 C12.5753237,1.17269884 12" -".0763029,1.04794364 11.6271842,1.0229926 C11.1531145,0.998041564 10.6790447,1.0229926 10.229926,0.923188446 C9.80575836,0.848335329 9.3815907,0.698629095 8.95742303,0.54892286 C8.50830433,0.399216625 8.05918563,0.299412469 7.61006692,0.224559352 C6.5" -"3717224,0.0499020782 5.43932652,0.0748531173 4.36643184,0.299412469 C3.36839028,0.424167665 2.39529975,0.798433251 1.52201338,1.32240507\" id=\"Shape\"></path>\n" -" </g>\n" -" <path d=\"M1.99608313,2.36612373 C1.52201338,2.69048723 1.07289468,3.08970386 0.723580134,3.53882256 C0.523971821,3.78833295 0.324363508,4.08774542 0.224559352,4.38715789 C0.149706235,4.63666828 0.124755195,4.88617867 0.0499020782" -",5.1606401 C0.0249510391,5.26044426 0,5.36024842 0,5.46005257 C0,5.50995465 0,5.55985673 0.0249510391,5.60975881 C0.0499020782,5.65966089 0.0748531173,5.70956296 0.0998041564,5.734514 C0.149706235,5.78441608 0.224559352,5.83431816 0.324363508,5.83431" -"816 C0.399216625,5.8592692 0.474069743,5.8592692 0.573873899,5.8592692 C0.948139486,5.90917128 1.27250299,6.08382855 1.57191546,6.28343686 C1.87132793,6.48304518 2.14578936,6.73255557 2.47015287,6.93216388 C3.14383093,7.35633154 3.96721522,7.55593986" -" 4.76564847,7.5808909 C5.56408172,7.60584193 6.38746601,7.48108674 7.16094822,7.3313805 C7.7847242,7.20662531 8.40850017,7.05691907 9.00732511,6.83235972 C9.93051356,6.48304518 10.7538978,5.90917128 11.5273801,5.33529738 C11.8766946,5.06083595 12.226" -"0092,4.78637452 12.5503727,4.48696205 C12.6501768,4.38715789 12.774932,4.2624027 12.8747362,4.18754958 C12.9994914,4.08774542 13.1242466,4.01289231 13.2739528,3.96299023 C13.4985121,3.88813711 13.7230715,3.91308815 13.9476309,3.96299023 C14.1222881,3" -".98794127 14.2969454,4.03784334 14.4716027,4.01289231 C14.5464558,4.01289231 14.6462599,3.98794127 14.7211131,3.96299023 C14.7959662,3.93803919 14.8708193,3.88813711 14.9207214,3.81328399 C14.9955745,3.71347984 15.0205255,3.61367568 15.0205255,3.4889" -"2048 C15.0205255,3.36416529 14.9955745,3.26436113 14.9207214,3.16455698 C14.7959662,2.96494866 14.5963579,2.84019347 14.3967496,2.74038931 C14.1222881,2.61563412 13.7979246,2.540781 13.4985121,2.46592788 C12.5753237,2.24136853 11.6521353,1.91700502 1" -"0.8037999,1.46788632 C10.3796323,1.24332697 9.9554646,1.01876761 9.53129693,0.794208262 C9.10712927,0.56964891 8.65801057,0.345089558 8.18394082,0.195383324 C7.13599718,-0.128980184 5.98824938,-0.029176028 4.94030574,0.345089558 C3.84246002,0.7193551" -"45 2.79451638,1.44293528 1.99608313,2.36612373 L1.99608313,2.36612373\" id=\"path27476-4\" fill=\"#FFB510\"></path>\n" -" </g>\n" -" <path d=\"M47.3006272,37.3384927 C48.8226406,38.5610936 49.7707801,40.4074705 50.0701925,42.3287005 C50.2947519,43.8257629 50.1450456,45.3727273 49.8206821,46.8448386 C49.4963186,48.3169499 48.9473958,49.7641102 48.448375,51.1863194 C" -"48.2487667,51.7601933 48.0242073,52.3340672 47.9493542,52.9328922 C47.8745011,53.5317171 47.9244032,54.1804441 48.1988646,54.7044159 C48.5232281,55.3032409 49.1470041,55.7274085 49.8206821,55.9270168 C50.4694091,56.1266252 51.1929893,56.1266252 51.84" -"17163,55.9519679 C52.5153944,55.7773106 53.1391703,55.4529471 53.6631421,55.0537305 C55.0354493,53.9808358 55.8588336,52.3340672 56.1831971,50.6124455 C56.5075606,48.8908238 56.3578544,47.1193 56.0584419,45.4226294 C55.6592253,43.0772317 54.9605962,4" -"0.7817361 54.0873098,38.5860447 C53.4385828,36.9642271 52.6900516,35.3673606 51.642108,33.9701024 C50.6191154,32.5977953 49.3216613,31.4500475 48.3236198,30.0777403 C47.6249907,29.1046498 47.0760678,28.0567062 46.2277325,27.2083708 C45.8035648,26.784" -"2032 45.3294951,26.4348886 44.7556212,26.2103293 C44.2066983,25.9857699 43.5829224,25.9358679 43.0090485,26.0855741 C42.2605173,26.3101334 41.6367413,26.8840073 41.3123778,27.6075875 C40.9880143,28.3311676 40.9381122,29.1296009 41.0628674,29.9030831 " -"C41.2375247,30.9011246 41.6866434,31.8243131 42.1856642,32.6975994 C42.7595381,33.67069 43.4332161,34.6188295 44.3065025,35.3673606 C45.254642,36.0909408 46.3774387,36.5899615 47.3006272,37.3384927\" id=\"path29705-5-0\" fill=\"#020204\"></path>\n" -" <g id=\"g17048\" transform=\"translate(41.000000, 52.000000)\" fill=\"#FFB510\">\n" -" <path d=\"M21.707404,11.6022332 C21.5327467,12.0264008 21.3081874,12.4256175 21.0087749,12.774932 C20.3600479,13.5484142 19.4368595,14.072386 18.538622,14.5215048 C16.9916576,15.319938 15.3947911,15.9936161 13.9476309,16.9417555 C" -"12.9745403,17.5655315 12.0763029,18.3140627 11.2279676,19.1124959 C10.5043875,19.811125 9.8307094,20.5347052 9.03227615,21.1085791 C8.20889186,21.707404 7.28570342,22.1315717 6.28766185,22.2812779 C5.09001198,22.4559352 3.84246002,22.2313758 2.719663" -"26,21.7323551 C1.94618105,21.3830405 1.17269884,20.9089708 0.723580134,20.1853906 C0.27446143,19.4618105 0.174657274,18.5635731 0.174657274,17.7152378 C0.174657274,16.1932244 0.449118704,14.696162 0.723580134,13.1990997 C0.948139486,11.9515477 1.1477" -"478,10.7039958 1.29745403,9.45644382 C1.54696442,7.18589926 1.54696442,4.86545262 1.37230715,2.59490807 C1.34735611,2.22064248 1.32240507,1.82142585 1.37230715,1.44716027 C1.42220923,1.07289468 1.5968665,0.698629095 1.87132793,0.449118704 C2.14578936" -",0.224559352 2.49510391,0.124755195 2.84441846,0.0998041564 C3.193733,0.0748531173 3.54304755,0.124755195 3.8923621,0.199608313 C4.71574639,0.324363508 5.56408172,0.424167665 6.36251497,0.623775977 C6.86153575,0.748531173 7.36055653,0.948139486 7.884" -"52835,1.07289468 C8.73286368,1.29745403 9.63110109,1.42220923 10.5043875,1.32240507 C11.4525269,1.22260092 12.3507644,0.848335329 13.2989038,0.873286368 C13.6981205,0.873286368 14.072386,0.948139486 14.4466516,1.07289468 C14.8209172,1.19764988 15.195" -"1828,1.37230715 15.4696442,1.64676858 C15.6692526,1.87132793 15.8189588,2.12083832 15.943714,2.42025079 C16.1183713,2.84441846 16.1932244,3.29353716 16.2431264,3.71770482 C16.2680775,4.11692145 16.2680775,4.51613808 16.3429306,4.9153547 C16.4676858,5" -".56408172 16.7920493,6.13795562 17.216217,6.6369764 C17.6403846,7.13599718 18.1394054,7.56016485 18.6384262,7.98433251 C19.137447,8.40850017 19.6364678,8.83266784 20.1853906,9.18198239 C20.434901,9.35663966 20.7093624,9.50634589 20.9339218,9.70595421" -" C21.1834322,9.90556252 21.3830405,10.1051708 21.5327467,10.3796323 C21.7323551,10.7538978 21.8072082,11.2030166 21.707404,11.6022332 L21.707404,11.6022332\" id=\"path14296-0\"></path>\n" -" </g>\n" -" <g id=\"path28767-9-3\" opacity=\"0.25\" transform=\"translate(20.000000, 28.000000)\" fill=\"#7C7C7C\">\n" -" <path d=\"M1.1477478,0.399216625 C1.12279676,0.0499020782 0.598824938,-0.0249510391 0.374265586,0.174657274 C0.174657274,0.324363508 -2.65065747e-15,0.848335329 0.174657274,1.04794364 C0.424167665,1.37230715 1.17269884,0.898237407" -" 1.1477478,0.399216625 Z\" id=\"Shape\"></path>\n" -" </g>\n" -" <g id=\"g14884-8\" transform=\"translate(46.000000, 50.000000)\" fill=\"#020204\">\n" -" <path d=\"M9.03227615,2.24559352 C8.932472,1.97113209 8.75781472,1.7216217 8.53325537,1.52201338 C8.30869602,1.32240507 8.05918563,1.17269884 7.7847242,1.04794364 C7.23580134,0.82338429 6.66192744,0.723580134 6.08805354,0.62377597" -"7 C5.53913068,0.523971821 5.01515886,0.399216625 4.466236,0.299412469 C3.8923621,0.199608313 3.3184882,0.149706235 2.7446143,0.27446143 C2.24559352,0.374265586 1.79647481,0.648727016 1.42220923,0.973090525 C1.04794364,1.29745403 0.773482212,1.7465727" -"4 0.54892286,2.19569144 C0.174657274,2.99412469 0.0748531173,3.91731314 0.124755195,4.79059951 C0.174657274,5.43932652 0.349314547,6.11300458 0.773482212,6.61202536 C1.12279676,7.01124199 1.62181754,7.26075238 2.12083832,7.41045861 C2.99412469,7.6599" -"69 3.96721522,7.659969 4.84050158,7.36055653 C6.28766185,6.88648679 7.56016485,5.91339627 8.40850017,4.66584431 C8.6829616,4.26662769 8.932472,3.81750898 9.05722719,3.3184882 C9.15703135,2.99412469 9.15703135,2.59490807 9.03227615,2.24559352\" id=\"p" -"ath29714-5-4\"></path>\n" -" </g>\n" -" <g id=\"g15037-4\" transform=\"translate(9.000000, 27.000000)\" fill=\"#020204\">\n" -" <path d=\"M10.0303177,2.6198591 C9.30673758,3.51809651 8.60810849,4.41633392 7.88452835,5.31457133 C7.01124199,6.41241705 6.11300458,7.51026277 5.53913068,8.78276576 C5.0401099,9.88061148 4.81555055,11.0782614 4.466236,12.2260092 " -"C4.09197041,13.5484142 3.56799859,14.8209172 2.96917365,16.0435181 C2.42025079,17.1912659 1.84637689,18.3140627 1.24755195,19.4119084 C0.82338429,20.2352927 0.374265586,21.058677 0.224559352,21.9569144 C0.0998041564,22.6804945 0.174657274,23.4040747 " -"0.349314547,24.1276548 C0.523971821,24.8262839 0.82338429,25.499962 1.1477478,26.148689 C2.56995703,28.9182543 4.69079535,31.288603 7.18589926,33.1100289 C8.33364706,33.9334132 7.06114406,32.1618894 8.33364706,32.7357633 C9.03227615,33.0601268 9.7558" -"5629,33.3345882 10.5293385,33.3595393 C10.9036041,33.3595393 11.3028207,33.3096372 11.6521353,33.159931 C12.0014498,33.0102247 12.3258133,32.7607143 12.5254216,32.4363508 C12.774932,32.0371342 12.8747362,31.5630645 12.8248341,31.0889947 C12.774932,30" -".614925 12.6002747,30.1658063 12.3507644,29.7665896 C11.7519394,28.7934991 10.8037999,28.069919 9.90556252,27.3712899 C7.95938147,25.8492765 8.55820641,26.7475139 6.73678056,25.0757943 C6.23775977,24.6017245 5.71378795,24.1027038 5.36447341,23.503878" -"8 C5.01515886,22.9300049 4.84050158,22.2563269 4.69079535,21.5826488 C4.3414808,19.761223 4.44128496,17.8150419 5.06506094,16.0684692 C5.31457133,15.3698401 5.63893484,14.7211131 5.9383473,14.072386 C6.48727016,12.9246383 6.98629095,11.7519394 7.6849" -"2004,10.7039958 C8.55820641,9.40654174 9.75585629,8.28374498 10.4794364,6.88648679 C11.0782614,5.71378795 11.3277717,4.36643184 11.5772821,3.06897781 C11.7519394,2.07093624 11.9265967,1.04794364 12.101254,0.0249510391 C11.4026249,0.898237407 10.70399" -"58,1.77152378 10.0303177,2.6198591 Z\" id=\"path14967-1-0\"></path>\n" -" </g>\n" -" <g id=\"Group\" transform=\"translate(0.000000, 51.000000)\" fill=\"#FFB510\">\n" -" <g id=\"g14180-6\" transform=\"translate(0.000000, -0.000000)\">\n" -" <path d=\"M10.3796323,0.174657274 C10.7788489,-1.26496036e-14 11.2279676,-0.0249510391 11.6521353,0.0499020782 C12.0763029,0.124755195 12.4755195,0.299412469 12.8248341,0.54892286 C13.5484142,1.0229926 14.072386,1.74657274 14." -"5714068,2.44520183 C15.7441057,4.04206833 16.8669024,5.68883691 17.864944,7.38550757 C18.6883283,8.75781472 19.4368595,10.204975 20.40995,11.502429 C21.033726,12.3507644 21.7323551,13.1242466 22.356131,13.9725819 C22.979907,14.8209172 23.5288299,15.7" -"441057 23.8032913,16.7421472 C24.1526058,18.0645523 24.0278506,19.5117126 23.4040747,20.7343135 C22.954956,21.5826488 22.2812779,22.33118 21.4578936,22.8052497 C20.6345093,23.2793195 19.6614188,23.5537809 18.7132793,23.5288299 C17.1912659,23.4789278 " -"15.7940077,22.7054456 14.3717985,22.1565227 C11.477478,21.0087749 8.33364706,20.6345093 5.36447341,19.7362719 C4.44128496,19.4618105 3.54304755,19.137447 2.6198591,18.8879366 C2.22064248,18.7631814 1.79647481,18.6883283 1.39725819,18.48872 C0.9980415" -"64,18.3140627 0.648727016,18.0645523 0.424167665,17.6902867 C0.249510391,17.4158253 0.199608313,17.0665107 0.199608313,16.7421472 C0.199608313,16.4177837 0.27446143,16.0934202 0.399216625,15.7690567 C0.623775977,15.1452807 0.973090525,14.5963579 1.22" -"260092,13.9725819 C1.62181754,12.9745403 1.69667066,11.8766946 1.64676858,10.8037999 C1.5968665,9.73090525 1.42220923,8.6829616 1.34735611,7.61006692 C1.32240507,7.13599718 1.29745403,6.6369764 1.39725819,6.1878577 C1.49706235,5.73873899 1.69667066,5" -".26466925 2.04598521,4.9153547 C2.37034871,4.61594223 2.79451638,4.41633392 3.21868404,4.3414808 C3.64285171,4.24167665 4.09197041,4.24167665 4.54108912,4.26662769 C4.99020782,4.26662769 5.41437548,4.29157872 5.86349419,4.26662769 C6.31261289,4.24167" -"665 6.73678056,4.14187249 7.13599718,3.91731314 C7.51026277,3.71770482 7.80967524,3.39334132 8.03423459,3.06897781 C8.25879394,2.7446143 8.48335329,2.37034871 8.6829616,1.99608313 C8.88256992,1.62181754 9.10712927,1.27250299 9.35663966,0.948139486 C9" -".60615005,0.623775977 9.98041564,0.324363508 10.3796323,0.174657274\" id=\"path4635-1\"></path>\n" -" </g>\n" -" </g>\n" -" </g>\n" -" </g>\n" -" </g>\n" -"</svg>"; - -const char* export_linux_svg = (const char*) temp_binary_data_8; - -//================== export_visualStudio.svg ================== -static const unsigned char temp_binary_data_9[] = -"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" -"<svg width=\"20px\" height=\"20px\" viewBox=\"0 0 20 20\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n" -" <!-- Generator: Sketch 43.1 (39012) - http://www.bohemiancoding.com/sketch -->\n" -" <title>Visual Studio</title>\n" -" <desc>Created with Sketch.</desc>\n" -" <defs></defs>\n" -" <g id=\"Page-1\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n" -" <g id=\"Artboard\" transform=\"translate(-77.000000, -43.000000)\">\n" -" <g id=\"Visual-Studio\" transform=\"translate(76.000000, 41.000000)\">\n" -" <polygon id=\"Rectangle\" fill=\"#68217A\" points=\"1 7 3 6 3 18 1 17\"></polygon>\n" -" <polygon id=\"Rectangle-2\" fill=\"#541D66\" transform=\"translate(5.607051, 10.000000) rotate(-330.000000) translate(-5.607051, -10.000000) \" points=\"1.34927858 7.83942379 7.86482304 8.6964746 9.86482304 12.1605762 2.84927858 10.43" -"75\"></polygon>\n" -" <polygon id=\"Rectangle-3\" fill=\"#541D66\" points=\"3 15 8 10 8 14 3 18\"></polygon>\n" -" <polygon id=\"Rectangle-2-Copy\" fill=\"#68217A\" transform=\"translate(12.000000, 16.000000) rotate(-330.000000) translate(-12.000000, -16.000000) \" points=\"5.53589838 12.8038476 15.4641016 14 18.4641016 19.1961524 7.53589838 16.26" -"79492\"></polygon>\n" -" <polygon id=\"Rectangle-2-Copy-2\" fill=\"#68217A\" transform=\"translate(12.433013, 8.250000) rotate(-330.000000) translate(-12.433013, -8.250000) \" points=\"9.46891109 11.9820508 12.3971143 1.05384758 15.3971143 6.25 11.4689111 15." -"4461524\"></polygon>\n" -" <polygon id=\"Rectangle-4\" fill=\"#541D66\" points=\"16 2 21 4 21 20 16 22\"></polygon>\n" -" </g>\n" -" </g>\n" -" </g>\n" -"</svg>"; - -const char* export_visualStudio_svg = (const char*) temp_binary_data_9; - -//================== export_xcode.svg ================== -static const unsigned char temp_binary_data_10[] = -"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" -"<svg width=\"33px\" height=\"32px\" viewBox=\"0 0 33 32\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n" -" <!-- Generator: Sketch 43.1 (39012) - http://www.bohemiancoding.com/sketch -->\n" -" <title>Group 2</title>\n" -" <desc>Created with Sketch.</desc>\n" -" <defs></defs>\n" -" <g id=\"Page-1\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n" -" <g id=\"Artboard\" transform=\"translate(-28.000000, -50.000000)\">\n" -" <g id=\"Group-2\" transform=\"translate(28.000000, 50.000000)\">\n" -" <g id=\"folder\" transform=\"translate(0.000000, 5.000000)\">\n" -" <polygon id=\"Rectangle-5\" fill=\"#457EFD\" points=\"0 4 27 0 30 21 3 25\"></polygon>\n" -" <path d=\"M19.9232759,13.0294985 C20.1413793,12.8123894 20.1034483,12.6519174 19.9517241,12.4725664 C19.3543103,11.7646018 18.7758621,11.0566372 18.1784483,10.3486726 C16.5189655,8.35693215 14.85,6.35575221 13.1905172,4.35457227 C" -"13.0577586,4.19410029 12.9439655,3.97699115 12.9060345,3.76932153 C12.8396552,3.36342183 13.1146552,2.99528024 13.512931,2.83480826 C13.9396552,2.67433628 14.3094828,2.78761062 14.6698276,3.21238938 C16.3008621,5.15693215 17.9413793,7.10147493 19.572" -"4138,9.0460177 C19.9612069,9.50855457 20.3594828,9.97109145 20.7672414,10.4525074 C20.9758621,10.2353982 20.9474138,10.0749263 20.7956897,9.89557522 C20.1413793,9.12153392 19.487069,8.3380531 18.8327586,7.5640118 C17.5146552,5.99705015 16.2060345,4.4" -"300885 14.8784483,2.8820059 C14.3474138,2.26843658 13.5413793,2.23067847 12.9534483,2.74041298 C12.375,3.24070796 12.3465517,3.94867257 12.887069,4.59056047 C14.9353448,7.05427729 16.9836207,9.50855457 19.0318966,11.9722714 C19.3258621,12.3309735 19." -"6198276,12.6707965 19.9232759,13.0294985 Z\" id=\"Shape\" fill=\"#235EE1\" fill-rule=\"nonzero\"></path>\n" -" <path d=\"M13.3801724,9.05545723 C13.3137931,9.00825959 13.237931,8.94218289 13.1525862,8.90442478 C12.4982759,8.65899705 11.8439655,8.43244838 11.1896552,8.18702065 C10.9810345,8.11150442 10.8862069,8.18702065 10.8103448,8.366371" -"68 C9.61551724,11.2926254 8.42068966,14.2094395 7.22586207,17.1356932 C7.13103448,17.3528024 7.19741379,17.4566372 7.39655172,17.5321534 C8.01293103,17.7775811 8.62931034,18.0135693 9.2362069,18.2873156 C9.56810345,18.4383481 9.70086207,18.3628319 9." -"82413793,18.0324484 C10.962069,15.1345133 12.1189655,12.2460177 13.2663793,9.35752212 C13.2948276,9.29144543 13.3232759,9.19705015 13.3801724,9.05545723 Z\" id=\"Shape\" fill=\"#FFFFFF\" fill-rule=\"nonzero\"></path>\n" -" <path d=\"M19.6293103,13.1050147 C19.1551724,12.5103245 18.7189655,12.019469 18.3586207,11.4908555 C18.0362069,11 17.6758621,10.7451327 17.0784483,10.9905605 C16.9362069,11.0471976 16.775,11.0471976 16.6232759,11.0660767 C15.35258" -"62,11.2831858 14.0913793,11.500295 12.8206897,11.7174041 C12.6215517,11.7551622 12.4508621,11.8023599 12.3655172,12.0383481 C12.1189655,12.7368732 11.8534483,13.4259587 11.5974138,14.1244838 C11.5689655,14.2 11.5689655,14.2943953 11.55,14.4265487 C14" -".2525862,13.9923304 16.8887931,13.5581121 19.6293103,13.1050147 Z\" id=\"Shape\" fill=\"#FFFFFF\" fill-rule=\"nonzero\"></path>\n" -" <path d=\"M8.97068966,12.2648968 C7.41551724,12.519764 5.9362069,12.7557522 4.40948276,13.0011799 C4.5137931,13.7091445 4.62758621,14.379351 4.70344828,15.0589971 C4.74137931,15.3516224 4.86465517,15.3893805 5.13017241,15.3516224 " -"C5.90775862,15.2289086 6.69482759,15.1250737 7.48189655,15.0306785 C7.71896552,15.0023599 7.87068966,14.9079646 7.96551724,14.6908555 C8.25,14.0112094 8.55344828,13.3315634 8.84741379,12.6519174 C8.89482759,12.5386431 8.9137931,12.4442478 8.97068966," -"12.2648968 Z\" id=\"Shape\" fill=\"#FFFFFF\" fill-rule=\"nonzero\"></path>\n" -" <path d=\"M25.6413793,18.1551622 C24.712069,17.5887906 23.7922414,17.0318584 22.787069,16.4277286 C22.825,16.6070796 22.8060345,16.8147493 22.9008621,16.9185841 C23.0810345,17.1168142 23.2991379,17.2867257 23.5362069,17.4094395 C2" -"3.8586207,17.5887906 24.2,17.7115044 24.5318966,17.8719764 C25.0155172,18.1079646 25.3663793,18.4477876 25.3663793,19.0330383 C25.3663793,19.1274336 25.4137931,19.2218289 25.4517241,19.3256637 C25.5086207,19.2973451 25.5275862,19.2879056 25.5465517,1" -"9.2784661 C25.575,19.2501475 25.5939655,19.2218289 25.612931,19.1935103 C26.1818966,18.3533923 26.2198276,17.4283186 25.9732759,16.4843658 C25.6982759,15.4271386 25.2051724,14.5115044 24.1715517,13.9828909 C23.887069,13.8412979 23.7068966,13.9640118 " -"23.4982759,14.1056047 C23.2801724,14.2566372 23.1568966,14.4359882 23.2137931,14.7569322 C23.3655172,14.6625369 23.4982759,14.5964602 23.5931034,14.5020649 C23.8301724,14.2566372 24.0482759,14.3132743 24.3137931,14.4831858 C25.3568966,15.2100295 26.0" -"112069,17.0412979 25.6413793,18.1551622 Z\" id=\"Shape\" fill=\"#235EE1\" fill-rule=\"nonzero\"></path>\n" -" <path d=\"M6.57155172,22.1103245 C6.60948276,22.1292035 6.64741379,22.1480826 6.68534483,22.1575221 C7.62413793,20.9870206 8.57241379,19.8165192 9.53017241,18.6176991 C9.38793103,18.5421829 9.30258621,18.4855457 9.20775862,18.4477" -"876 C8.60086207,18.2023599 7.99396552,17.9758112 7.39655172,17.720944 C7.11206897,17.5982301 7.02672414,17.6831858 7.00775862,17.9758112 C6.93189655,18.7687316 6.83706897,19.5616519 6.75172414,20.3640118 C6.68534483,20.9492625 6.62844828,21.5345133 6" -".57155172,22.1103245 Z\" id=\"Shape\" fill=\"#FFFFFF\" fill-rule=\"nonzero\"></path>\n" -" <path d=\"M12.687931,5.83657817 C12.137931,5.89321534 11.7775862,6.11976401 11.5689655,6.60117994 C11.4267241,6.95044248 11.2939655,7.29970501 11.1327586,7.63952802 C11.037931,7.83775811 11.0663793,7.96047198 11.2939655,8.0359882 " -"C11.9293103,8.25309735 12.5646552,8.48908555 13.1905172,8.73451327 C13.4181034,8.81946903 13.512931,8.7439528 13.5982759,8.54572271 C13.7405172,8.18702065 13.9017241,7.82831858 14.0534483,7.46961652 C14.2525862,6.98820059 14.1672414,6.58230088 13.731" -"0345,6.29911504 C13.4181034,6.10088496 13.0387931,5.98761062 12.687931,5.83657817 Z\" id=\"Shape\" fill=\"#FFFFFF\" fill-rule=\"nonzero\"></path>\n" -" <path d=\"M23.8112069,12.3498525 C24.6077586,12.2460177 25.3948276,12.1421829 26.1724138,12.019469 C26.2387931,12.0100295 26.3241379,11.840118 26.3146552,11.7646018 C26.2198276,11.1415929 26.1060345,10.5091445 25.9732759,9.8955752" -"2 C25.9543103,9.80117994 25.7931034,9.66902655 25.6982759,9.66902655 C25.3,9.69734513 24.9017241,9.7539823 24.5034483,9.820059 C24.3043103,9.84837758 24.162069,9.94277286 24.2758621,10.2259587 C24.6362069,10.1787611 25.0060345,10.1221239 25.3758621,1" -"0.0938053 C25.4612069,10.0843658 25.6224138,10.159882 25.6318966,10.2165192 C25.7362069,10.6884956 25.812069,11.179351 25.9068966,11.679646 C25.2905172,11.7646018 24.712069,11.840118 24.1431034,11.9156342 C23.9344828,11.9439528 23.7448276,11.9911504 " -"23.8112069,12.3498525 Z\" id=\"Shape\" fill=\"#235EE1\" fill-rule=\"nonzero\"></path>\n" -" <path d=\"M19.9232759,13.0294985 C19.6198276,12.6707965 19.3258621,12.3309735 19.0318966,11.9722714 C16.9836207,9.50855457 14.9353448,7.05427729 12.887069,4.59056047 C12.3465517,3.94867257 12.375,3.25014749 12.9534483,2.74041298 C" -"13.5508621,2.22123894 14.3568966,2.25899705 14.8784483,2.8820059 C16.2060345,4.4300885 17.5146552,6.00648968 18.8327586,7.5640118 C19.487069,8.3380531 20.1318966,9.12153392 20.7956897,9.89557522 C20.9474138,10.0749263 20.9853448,10.2353982 20.7672414" -",10.4525074 C20.3594828,9.97109145 19.9612069,9.50855457 19.5724138,9.0460177 C17.9413793,7.10147493 16.3008621,5.15693215 14.6698276,3.21238938 C14.3094828,2.78761062 13.9396552,2.66489676 13.512931,2.83480826 C13.1051724,2.99528024 12.8396552,3.363" -"42183 12.9060345,3.76932153 C12.9344828,3.97699115 13.0482759,4.19410029 13.1905172,4.35457227 C14.85,6.35575221 16.5094828,8.34749263 18.1784483,10.3486726 C18.7663793,11.0566372 19.3543103,11.7646018 19.9517241,12.4725664 C20.1034483,12.6519174 20." -"1508621,12.8123894 19.9232759,13.0294985 Z\" id=\"Shape\" fill=\"#FFFFFF\" fill-rule=\"nonzero\"></path>\n" -" <path d=\"M25.6413793,18.1551622 C26.0112069,17.0412979 25.3568966,15.2100295 24.3137931,14.5020649 C24.0577586,14.3227139 23.8396552,14.2755162 23.5931034,14.520944 C23.4982759,14.6153392 23.3655172,14.6719764 23.2137931,14.77581" -"12 C23.1568966,14.4454277 23.2801724,14.2755162 23.4982759,14.1244838 C23.7068966,13.9734513 23.887069,13.860177 24.1715517,14.0017699 C25.2051724,14.5303835 25.6982759,15.4460177 25.9732759,16.5032448 C26.2198276,17.4471976 26.1818966,18.3722714 25." -"612931,19.2123894 C25.5939655,19.240708 25.575,19.2690265 25.5465517,19.2973451 C25.5275862,19.3162242 25.5086207,19.3162242 25.4517241,19.3445428 C25.4232759,19.240708 25.3663793,19.1463127 25.3663793,19.0519174 C25.3663793,18.4666667 25.0155172,18." -"1268437 24.5318966,17.8908555 C24.2,17.7303835 23.8491379,17.6076696 23.5362069,17.4283186 C23.2991379,17.2961652 23.0715517,17.1356932 22.9008621,16.9374631 C22.8060345,16.8336283 22.825,16.6259587 22.787069,16.4466077 C23.7922414,17.0318584 24.7120" -"69,17.5887906 25.6413793,18.1551622 Z\" id=\"Shape\" fill=\"#FFFFFF\" fill-rule=\"nonzero\"></path>\n" -" <path d=\"M23.8112069,12.3498525 C23.7353448,11.9911504 23.9344828,11.9439528 24.1431034,11.9156342 C24.712069,11.840118 25.2810345,11.7646018 25.9068966,11.679646 C25.812069,11.179351 25.7362069,10.6979351 25.6318966,10.2165192 C" -"25.6224138,10.159882 25.4612069,10.0843658 25.3758621,10.0938053 C25.0060345,10.1221239 24.6362069,10.1787611 24.2758621,10.2259587 C24.1715517,9.93333333 24.3137931,9.84837758 24.5034483,9.820059 C24.9017241,9.76342183 25.3,9.69734513 25.6982759,9.6" -"6902655 C25.7931034,9.65958702 25.9543103,9.80117994 25.9732759,9.89557522 C26.1060345,10.5185841 26.2198276,11.1415929 26.3146552,11.7646018 C26.3241379,11.840118 26.2293103,12.0100295 26.1724138,12.019469 C25.3948276,12.1421829 24.6172414,12.236578" -"2 23.8112069,12.3498525 Z\" id=\"Shape\" fill=\"#FFFFFF\" fill-rule=\"nonzero\"></path>\n" -" </g>\n" -" <path d=\"M24.3232759,13.3569322 C23.687931,13.1681416 23.0810345,12.9982301 22.4836207,12.8283186 C22.2655172,12.7622419 22.3034483,12.6300885 22.3508621,12.4696165 C22.7017241,11.2330383 23.0431034,9.99646018 23.4034483,8.76932153 C" -"23.7448276,7.60825959 23.9724138,6.42831858 23.8681034,5.220059 C23.7922414,4.35162242 23.6689655,3.5020649 23.0905172,2.76578171 C22.55,2.07669617 21.8198276,1.80294985 21.0043103,1.69911504 C19.8,1.53864307 18.6051724,1.55752212 17.3439655,1.661356" -"93 C17.4672414,1.55752212 17.5715517,1.43480826 17.7043103,1.34041298 C18.6241379,0.689085546 19.6862069,0.396460177 20.7767241,0.226548673 C23.0525862,-0.132153392 25.2525862,0.207669617 27.4051724,0.943952802 C28.1543103,1.19882006 28.7801724,1.633" -"03835 29.3301724,2.18053097 C29.8517241,2.69970501 30.4396552,2.80353982 31.0844828,2.53923304 C31.4827586,2.36932153 31.8241379,2.4259587 32.2034483,2.55811209 C33.1137931,2.87905605 33.1137931,2.86961652 32.8387931,3.80412979 C32.5922414,4.62536873" -" 32.3456897,5.44660767 32.1086207,6.27728614 C32.0327586,6.53215339 31.9284483,6.6359882 31.6534483,6.54159292 C31.4543103,6.4660767 31.2456897,6.40943953 31.037069,6.38112094 C30.5913793,6.31504425 30.2689655,6.0979351 30.0034483,5.72035398 C29.5767" -"241,5.14454277 28.9318966,5.19174041 28.3155172,5.25781711 C27.3862069,5.36165192 26.7887931,5.8619469 26.437931,6.74926254 C25.6508621,8.72212389 25.0724138,10.7610619 24.5034483,12.8 C24.4465517,12.9699115 24.3896552,13.139823 24.3232759,13.3569322" -" Z\" id=\"Shape\" fill=\"#D2D2D2\" fill-rule=\"nonzero\"></path>\n" -" <path d=\"M18.4913793,31.9150442 C17.1163793,31.9056047 16.2155172,31.0182891 16.262931,29.7250737 C16.2724138,29.5079646 16.3387931,29.2814159 16.4146552,29.0737463 C18.2068966,23.9858407 20.0086207,18.9073746 21.8103448,13.8289086 C" -"22.0189655,13.2247788 21.8862069,13.2058997 22.6163793,13.4135693 C23.0146552,13.5268437 23.412931,13.6495575 23.8112069,13.7439528 C24.1051724,13.8100295 24.1810345,13.9327434 24.1051724,14.2348083 C23.7258621,15.7923304 23.375,17.3498525 23.0051724" -",18.9073746 C22.1043103,22.6548673 21.2034483,26.4117994 20.2931034,30.159292 C20.2077586,30.5085546 20.0655172,30.8578171 19.8853448,31.1693215 C19.5724138,31.6884956 19.0887931,31.9622419 18.4913793,31.9150442 Z\" id=\"Shape\" fill=\"#000000\" fill" -"-rule=\"nonzero\"></path>\n" -" </g>\n" -" </g>\n" -" </g>\n" -"</svg>"; - -const char* export_xcode_svg = (const char*) temp_binary_data_10; - -//================== huckleberry_icon.svg ================== -static const unsigned char temp_binary_data_11[] = -"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" -"<!-- Generator: Adobe Illustrator 21.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->\n" -"<svg version=\"1.1\" id=\"Layer_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"\n" -"\t viewBox=\"0 0 169.7 205.2\" style=\"enable-background:new 0 0 169.7 205.2;\" xml:space=\"preserve\">\n" -"<style type=\"text/css\">\n" -"\t.st0{fill:#A65A95;}\n" -"\t.st1{fill:#001946;}\n" -"</style>\n" -"<g>\n" -"\t<g>\n" -"\t\t<path class=\"st0\" d=\"M45.2,167.8c-3,0-5.4-1.1-7.8-4.3l3.6-3.1c1.6,2.1,2.7,2.7,4.2,2.7c2.6,0,4.4-2,4.4-5v-17.2h5V158\n" -"\t\t\tC54.6,163.9,50.7,167.8,45.2,167.8z\"/>\n" -"\t\t<path class=\"st0\" d=\"M70.7,167.8c-5.8,0-10.8-4.2-10.8-11.2v-15.8h5v15.6c0,4.1,2.4,6.7,5.8,6.7c3.4,0,5.8-2.6,5.8-6.7v-15.6h5\n" -"\t\t\tv15.8C81.5,163.5,76.5,167.8,70.7,167.8z\"/>\n" -"\t\t<path class=\"st0\" d=\"M99,167.8c-7.6,0-13.9-6.1-13.9-13.6c0-7.6,6.3-13.6,13.9-13.6c3.4,0,6.3,1.2,9.1,3.4l-2.9,3.6\n" -"\t\t\tc-2.6-1.8-4.1-2.4-6.2-2.4c-4.8,0-8.8,3.9-8.8,9c0,5,3.9,9,8.8,9c2,0,3.6-0.6,6.1-2.4l3,3.7C104.6,167,102,167.8,99,167.8z\"/>\n" -"\t\t<path class=\"st0\" d=\"M111.3,167.4v-26.6h16.6v4.5h-11.6v6.4h11.2v4.5h-11.2v6.7h11.6v4.5H111.3z\"/>\n" -"\t</g>\n" -"\t<g>\n" -"\t\t<circle class=\"st1\" cx=\"84.9\" cy=\"74.9\" r=\"37.4\"/>\n" -"\t\t<circle class=\"st0\" cx=\"84.9\" cy=\"74.9\" r=\"28\"/>\n" -"\t\t<circle class=\"st1\" cx=\"84.9\" cy=\"67.9\" r=\"2.1\"/>\n" -"\t\t<circle class=\"st1\" cx=\"91.4\" cy=\"72.6\" r=\"2.1\"/>\n" -"\t\t<circle class=\"st1\" cx=\"88.9\" cy=\"80.3\" r=\"2.1\"/>\n" -"\t\t<circle class=\"st1\" cx=\"80.8\" cy=\"80.3\" r=\"2.1\"/>\n" -"\t\t<circle class=\"st1\" cx=\"78.3\" cy=\"72.6\" r=\"2.1\"/>\n" -"\t</g>\n" -"\t<g>\n" -"\t\t<path class=\"st1\" d=\"M48.2,131.7v-4.6h-4.3v4.6h-2V121h2v4.3h4.3V121h2v10.8H48.2z\"/>\n" -"\t\t<path class=\"st1\" d=\"M56.7,131.7v-0.5c-0.5,0.4-1.3,0.7-2.1,0.7c-1.9,0-3.2-1.3-3.2-3.4v-5h2v4.8c0,1.2,0.7,1.8,1.7,1.8\n" -"\t\t\tc1,0,1.7-0.7,1.7-1.8v-4.8h2v8.3H56.7z\"/>\n" -"\t\t<path class=\"st1\" d=\"M63.8,131.9c-2.4,0-4.3-1.9-4.3-4.3c0-2.4,1.9-4.3,4.3-4.3c1.1,0,2.1,0.4,3.3,1.5l-1.3,1.2\n" -"\t\t\tc-0.7-0.7-1.3-1-2-1c-1.3,0-2.3,1.1-2.3,2.5c0,1.3,1,2.5,2.3,2.5c0.6,0,1.3-0.2,2-0.9l1.3,1.2C66,131.5,65,131.9,63.8,131.9z\"/>\n" -"\t\t<path class=\"st1\" d=\"M73.8,131.7l-3.9-3.9v3.9h-2v-11.3h2v6.8l3.6-3.7h2.5l-3.9,4l4.3,4.3H73.8z\"/>\n" -"\t\t<path class=\"st1\" d=\"M77.1,131.7v-11.3h2v11.3H77.1z\"/>\n" -"\t\t<path class=\"st1\" d=\"M88.6,128.4h-6.2c0.1,1,1.1,1.7,2.1,1.7c0.7,0,1.5-0.3,2.3-1.1l1.3,1.2c-1.1,1.2-2.3,1.7-3.6,1.7\n" -"\t\t\tc-2.4,0-4.3-1.9-4.3-4.3c0-2.4,1.9-4.3,4.3-4.3c2.4,0,4.1,1.9,4.1,4.2C88.7,127.9,88.6,128.4,88.6,128.4z M84.5,125.1\n" -"\t\t\tc-1,0-1.9,0.6-2.1,1.5h4.1C86.3,125.8,85.5,125.1,84.5,125.1z\"/>\n" -"\t\t<path class=\"st1\" d=\"M93.9,131.9c-0.9,0-1.7-0.3-2.3-0.8v0.6h-2v-11.3h2v3.7c0.6-0.5,1.4-0.8,2.3-0.8c2.3,0,4.2,1.9,4.2,4.3\n" -"\t\t\tC98.1,129.9,96.2,131.9,93.9,131.9z M93.9,125.1c-1.3,0-2.2,1.1-2.2,2.5c0,1.4,1,2.5,2.2,2.5c1.3,0,2.2-1.1,2.2-2.5\n" -"\t\t\tC96.2,126.2,95.2,125.1,93.9,125.1z\"/>\n" -"\t\t<path class=\"st1\" d=\"M107.4,128.4h-6.2c0.1,1,1.1,1.7,2.1,1.7c0.7,0,1.5-0.3,2.3-1.1l1.3,1.2c-1.1,1.2-2.3,1.7-3.6,1.7\n" -"\t\t\tc-2.4,0-4.3-1.9-4.3-4.3c0-2.4,1.9-4.3,4.3-4.3c2.4,0,4.1,1.9,4.1,4.2C107.5,127.9,107.4,128.4,107.4,128.4z M103.3,125.1\n" -"\t\t\tc-1,0-1.9,0.6-2.1,1.5h4.1C105.1,125.8,104.3,125.1,103.3,125.1z\"/>\n" -"\t\t<path class=\"st1\" d=\"M110.4,127.8v3.9h-2v-8.3h2v0.8c0.7-0.6,1.4-0.9,2.6-1v1.8C111,125.4,110.4,126.6,110.4,127.8z\"/>\n" -"\t\t<path class=\"st1\" d=\"M116,127.8v3.9h-2v-8.3h2v0.8c0.7-0.6,1.4-0.9,2.6-1v1.8C116.6,125.4,116,126.6,116,127.8z\"/>\n" -"\t\t<path class=\"st1\" d=\"M122.2,134.6h-2.1l2.2-4.2l-3.4-6.9h2.1l2.4,4.8l2.3-4.8h2.2L122.2,134.6z\"/>\n" -"\t</g>\n" -"</g>\n" -"</svg>\n"; - -const char* huckleberry_icon_svg = (const char*) temp_binary_data_11; - -//================== juce-logo-with-text.svg ================== -static const unsigned char temp_binary_data_12[] = -"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" -"<svg\n" -" xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n" -" xmlns:cc=\"http://creativecommons.org/ns#\"\n" -" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n" -" xmlns:svg=\"http://www.w3.org/2000/svg\"\n" -" xmlns=\"http://www.w3.org/2000/svg\"\n" -" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n" -" xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\"\n" -" xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"\n" -" id=\"Layer_1\"\n" -" width=\"113.4\"\n" -" height=\"35.9\"\n" -" viewBox=\"0 0 113.4 35.9\"\n" -" version=\"1.1\"\n" -" inkscape:version=\"0.91 r13725\"\n" -" sodipodi:docname=\"juce-logo-with-text.svg\">\n" -" <metadata\n" -" id=\"metadata35\">\n" -" <rdf:RDF>\n" -" <cc:Work\n" -" rdf:about=\"\">\n" -" <dc:format>image/svg+xml</dc:format>\n" -" <dc:type\n" -" rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\" />\n" -" <dc:title />\n" -" </cc:Work>\n" -" </rdf:RDF>\n" -" </metadata>\n" -" <sodipodi:namedview\n" -" pagecolor=\"#ffffff\"\n" -" bordercolor=\"#666666\"\n" -" borderopacity=\"1\"\n" -" objecttolerance=\"10\"\n" -" gridtolerance=\"10\"\n" -" guidetolerance=\"10\"\n" -" inkscape:pageopacity=\"0\"\n" -" inkscape:pageshadow=\"2\"\n" -" inkscape:window-width=\"1920\"\n" -" inkscape:window-height=\"1029\"\n" -" id=\"namedview33\"\n" -" showgrid=\"false\"\n" -" inkscape:zoom=\"9.3827159\"\n" -" inkscape:cx=\"26.137564\"\n" -" inkscape:cy=\"37.52419\"\n" -" inkscape:window-x=\"0\"\n" -" inkscape:window-y=\"0\"\n" -" inkscape:window-maximized=\"1\"\n" -" inkscape:current-layer=\"Layer_1\" />\n" -" <style\n" -" id=\"style3\"><![CDATA[\n" -"\t.st0{clip-path:url(#SVGID_2_);fill:#A65A95;}\n" -"\t.st1{clip-path:url(#SVGID_2_);fill:#E67E3C;}\n" -"\t.st2{clip-path:url(#SVGID_2_);fill:#E73E51;}\n" -"\t.st3{clip-path:url(#SVGID_2_);fill:#F0E049;}\n" -"\t.st4{clip-path:url(#SVGID_2_);fill:#F19F53;}\n" -"\t.st5{clip-path:url(#SVGID_2_);fill:#F5BD47;}\n" -"\t.st6{clip-path:url(#SVGID_2_);fill:#288DC1;}\n" -"\t.st7{clip-path:url(#SVGID_2_);fill:#FFFFFF;}\n" -"\t.st8{clip-path:url(#SVGID_2_);fill:#9CB6D3;}\n" -"\t.st9{clip-path:url(#SVGID_2_);fill:#6CC04A;}\n" -"]]></style>\n" -" <defs\n" -" id=\"defs5\">\n" -" <path\n" -" id=\"SVGID_1_\"\n" -" d=\"M0 0h113.4v35.9H0z\" />\n" -" </defs>\n" -" <clipPath\n" -" id=\"SVGID_2_\">\n" -" <use\n" -" xlink:href=\"#SVGID_1_\"\n" -" overflow=\"visible\"\n" -" id=\"use9\" />\n" -" </clipPath>\n" -" <path\n" -" class=\"st9\"\n" -" d=\"M5.2 5.2c7-7 18.4-7 25.4 0s7 18.4 0 25.4-18.4 7-25.4 0c-6.9-7-6.9-18.4 0-25.4\"\n" -" id=\"path11\"\n" -" clip-path=\"url(#SVGID_2_)\"\n" -" style=\"fill:#6cc04a;fill-opacity:1\" />\n" -" <path\n" -" class=\"st7\"\n" -" d=\"m 29.8,29.8 c 6.5,-6.5 6.5,-17.2 0,-23.7 -6.5,-6.5 -17.2,-6.5 -23.7,0 -6.5,6.5 -6.5,17.2 0,23.7 6.5,6.5 17.1,6.5 23.7,0\"\n" -" id=\"path13\"\n" -" clip-path=\"url(#SVGID_2_)\"\n" -" inkscape:connector-curvature=\"0\"\n" -" style=\"fill:#ffffff\" />\n" -" <path\n" -" class=\"st8\"\n" -" d=\"M28.4 27.5c.4.4 1.1.4 1.5 0l.1-.1c1.8-2.2 2.9-4.9 3.2-7.7 0-.3-.1-.6-.3-.9-.2-.2-.5-.4-.8-.4H19.9c-.2 0-.3.2-.1.4l8.6 8.7z\"\n" -" id=\"path15\"\n" -" clip-path=\"url(#SVGID_2_)\"\n" -" style=\"fill:#9cb6d3;fill-opacity:1\" />\n" -" <path\n" -" class=\"st0\"\n" -" d=\"M8.3 28.4c-.2.2-.3.5-.3.8 0 .3.2.6.4.8 2.2 1.8 4.9 2.9 7.7 3.2.3 0 .7-.1.9-.3.2-.2.3-.5.3-.8V19.9c0-.2-.2-.3-.4-.1l-8.6 8.6z\"\n" -" id=\"path17\"\n" -" clip-path=\"url(#SVGID_2_)\"\n" -" style=\"fill:#a65a95;fill-opacity:1\" />\n" -" <path\n" -" class=\"st6\"\n" -" d=\"M18.9 33c.2.2.5.3.9.3 2.8-.3 5.5-1.4 7.7-3.2l.1-.1c.4-.4.4-1.1 0-1.5l-8.7-8.7c-.1-.1-.4 0-.4.1v12.2c0 .4.2.7.4.9\"\n" -" id=\"path19\"\n" -" clip-path=\"url(#SVGID_2_)\"\n" -" style=\"fill:#288dc1;fill-opacity:1\" />\n" -" <path\n" -" class=\"st1\"\n" -" d=\"M7.5 8.3c-.5-.4-1.1-.4-1.6 0l-.1.1c-1.8 2.2-2.9 4.9-3.2 7.7 0 .3.1.6.3.8.2.2.5.4.8.4H16c.2 0 .3-.2.1-.4L7.5 8.3z\"\n" -" id=\"path21\"\n" -" clip-path=\"url(#SVGID_2_)\"\n" -" style=\"fill:#e67e3c;fill-opacity:1\" />\n" -" <path\n" -" class=\"st2\"\n" -" d=\"M2.9 18.8c-.2.2-.3.5-.3.9.3 2.8 1.4 5.5 3.2 7.7.2.3.5.4.8.4.3 0 .6-.1.8-.3l8.6-8.6c.1-.1 0-.4-.1-.4H3.7c-.3 0-.6.1-.8.3\"\n" -" id=\"path23\"\n" -" clip-path=\"url(#SVGID_2_)\"\n" -" style=\"fill:#e73e51;fill-opacity:1\" />\n" -" <path\n" -" class=\"st3\"\n" -" d=\"M32.9 17c.2-.2.3-.5.3-.9-.3-2.8-1.4-5.5-3.2-7.7-.2-.2-.5-.4-.8-.4-.3 0-.6.1-.8.3L19.7 17c-.1.1 0 .4.1.4H32c.4-.1.7-.2.9-.4\"\n" -" id=\"path25\"\n" -" clip-path=\"url(#SVGID_2_)\"\n" -" style=\"fill:#f0e049;fill-opacity:1\" />\n" -" <path\n" -" class=\"st5\"\n" -" d=\"M18.9 16.1l8.6-8.6c.2-.2.4-.5.3-.8 0-.3-.2-.6-.4-.8-2.2-1.8-4.9-2.9-7.7-3.2-.3 0-.7.1-.9.3-.2.2-.3.5-.3.8V16c0 .2.3.3.4.1\"\n" -" id=\"path27\"\n" -" clip-path=\"url(#SVGID_2_)\"\n" -" style=\"fill:#f5bd47;fill-opacity:1\" />\n" -" <path\n" -" class=\"st4\"\n" -" d=\"M17.3 3.7c0-.3-.1-.6-.4-.8-.2-.2-.5-.3-.9-.3-2.7.4-5.4 1.5-7.6 3.2l-.1.1c-.2.2-.3.5-.3.9 0 .2.1.5.3.7l8.6 8.6c.1.1.4 0 .4-.2V3.7z\"\n" -" id=\"path29\"\n" -" clip-path=\"url(#SVGID_2_)\"\n" -" style=\"fill:#f19f53;fill-opacity:1\" />\n" -" <path\n" -" class=\"st7\"\n" -" d=\"M45.3 29.3c-2.4 0-4.4-.9-6.1-3.2l2.4-2c1.2 1.5 2.3 2.1 3.7 2.1 2.6 0 4.3-1.9 4.3-4.9V6.8h3.3v14.5c0 4.8-3.1 8-7.6 8M66 29.3c-4.8 0-8.8-3.5-8.8-9.3V6.8h3.3v13c0 3.9 2.3 6.4 5.6 6.4s5.6-2.5 5.6-6.4v-13H75V20c-.2 5.8-4.3 9.3-9 9.3M89.2 29.3c-6." -"3 0-11.4-5.1-11.4-11.4 0-6.3 5.2-11.4 11.4-11.4 2.8 0 5.3 1 7.2 2.6l-1.9 2.4c-2-1.4-3.4-1.9-5.2-1.9-4.5 0-8.1 3.6-8.1 8.3 0 4.7 3.6 8.3 8.1 8.3 1.8 0 3.3-.6 5.2-1.9l2 2.4c-2.5 2-4.7 2.6-7.3 2.6M100 29V6.8h13.4v3h-10.1v6.5h9.7v3h-9.7v6.8h10.1V29z\"\n" -" id=\"path31\"\n" -" clip-path=\"url(#SVGID_2_)\"\n" -" style=\"fill:#ffffff;fill-opacity:1\" />\n" -"</svg>\n"; - -const char* jucelogowithtext_svg = (const char*) temp_binary_data_12; - -//================== juce_icon.png ================== -static const unsigned char temp_binary_data_13[] = -{ 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,2,0,0,0,2,0,8,6,0,0,0,244,120,212,250,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101,60,0,0,3,40,105,84,88,116,88,77,76,58, -99,111,109,46,97,100,111,98,101,46,120,109,112,0,0,0,0,0,60,63,120,112,97,99,107,101,116,32,98,101,103,105,110,61,34,239,187,191,34,32,105,100,61,34,87,53,77,48,77,112,67,101,104,105,72,122,114,101,83,122,78,84,99,122,107,99,57,100,34,63,62,32,60,120, -58,120,109,112,109,101,116,97,32,120,109,108,110,115,58,120,61,34,97,100,111,98,101,58,110,115,58,109,101,116,97,47,34,32,120,58,120,109,112,116,107,61,34,65,100,111,98,101,32,88,77,80,32,67,111,114,101,32,53,46,54,45,99,48,54,55,32,55,57,46,49,53,55, -55,52,55,44,32,50,48,49,53,47,48,51,47,51,48,45,50,51,58,52,48,58,52,50,32,32,32,32,32,32,32,32,34,62,32,60,114,100,102,58,82,68,70,32,120,109,108,110,115,58,114,100,102,61,34,104,116,116,112,58,47,47,119,119,119,46,119,51,46,111,114,103,47,49,57,57, -57,47,48,50,47,50,50,45,114,100,102,45,115,121,110,116,97,120,45,110,115,35,34,62,32,60,114,100,102,58,68,101,115,99,114,105,112,116,105,111,110,32,114,100,102,58,97,98,111,117,116,61,34,34,32,120,109,108,110,115,58,120,109,112,61,34,104,116,116,112, -58,47,47,110,115,46,97,100,111,98,101,46,99,111,109,47,120,97,112,47,49,46,48,47,34,32,120,109,108,110,115,58,120,109,112,77,77,61,34,104,116,116,112,58,47,47,110,115,46,97,100,111,98,101,46,99,111,109,47,120,97,112,47,49,46,48,47,109,109,47,34,32,120, -109,108,110,115,58,115,116,82,101,102,61,34,104,116,116,112,58,47,47,110,115,46,97,100,111,98,101,46,99,111,109,47,120,97,112,47,49,46,48,47,115,84,121,112,101,47,82,101,115,111,117,114,99,101,82,101,102,35,34,32,120,109,112,58,67,114,101,97,116,111, -114,84,111,111,108,61,34,65,100,111,98,101,32,80,104,111,116,111,115,104,111,112,32,67,67,32,50,48,49,53,32,40,77,97,99,105,110,116,111,115,104,41,34,32,120,109,112,77,77,58,73,110,115,116,97,110,99,101,73,68,61,34,120,109,112,46,105,105,100,58,53,52, -53,66,70,48,69,70,55,66,48,54,49,49,69,53,66,51,49,53,69,69,54,51,67,65,56,68,70,50,56,48,34,32,120,109,112,77,77,58,68,111,99,117,109,101,110,116,73,68,61,34,120,109,112,46,100,105,100,58,53,52,53,66,70,48,70,48,55,66,48,54,49,49,69,53,66,51,49,53,69, -69,54,51,67,65,56,68,70,50,56,48,34,62,32,60,120,109,112,77,77,58,68,101,114,105,118,101,100,70,114,111,109,32,115,116,82,101,102,58,105,110,115,116,97,110,99,101,73,68,61,34,120,109,112,46,105,105,100,58,53,52,53,66,70,48,69,68,55,66,48,54,49,49,69, -53,66,51,49,53,69,69,54,51,67,65,56,68,70,50,56,48,34,32,115,116,82,101,102,58,100,111,99,117,109,101,110,116,73,68,61,34,120,109,112,46,100,105,100,58,53,52,53,66,70,48,69,69,55,66,48,54,49,49,69,53,66,51,49,53,69,69,54,51,67,65,56,68,70,50,56,48,34, -47,62,32,60,47,114,100,102,58,68,101,115,99,114,105,112,116,105,111,110,62,32,60,47,114,100,102,58,82,68,70,62,32,60,47,120,58,120,109,112,109,101,116,97,62,32,60,63,120,112,97,99,107,101,116,32,101,110,100,61,34,114,34,63,62,115,115,54,90,0,0,175,140, -73,68,65,84,120,218,236,157,7,128,92,117,181,255,207,45,211,251,236,204,246,94,179,61,189,247,144,70,11,45,244,14,74,81,154,20,17,241,1,239,161,40,54,44,207,191,138,138,62,124,2,250,176,32,85,233,32,37,72,9,9,73,72,239,61,219,119,218,109,255,223,239, -55,155,80,4,201,220,123,103,167,157,79,24,118,179,73,238,220,185,237,124,207,249,157,194,105,154,6,8,130,32,8,130,20,22,60,30,2,4,65,16,4,65,1,128,32,8,130,32,8,10,0,4,65,16,4,65,80,0,32,8,130,32,8,130,2,0,65,16,4,65,16,20,0,8,130,32,8,130,160,0,64,16, -4,65,16,4,5,0,130,32,8,130,32,40,0,16,4,65,16,4,65,1,128,32,8,130,32,8,10,0,4,65,16,4,65,80,0,32,8,130,32,8,130,2,0,65,16,4,65,16,20,0,8,130,32,8,130,160,0,64,16,4,65,16,4,5,0,130,32,8,130,32,40,0,16,4,65,16,4,65,1,128,32,8,130,32,40,0,16,4,65,16,4,65, -1,128,32,8,130,32,8,10,0,4,65,16,4,65,80,0,32,8,130,32,8,130,2,0,65,16,4,65,16,20,0,8,130,32,8,130,160,0,64,16,4,65,16,4,5,0,130,32,8,130,32,40,0,16,4,65,16,4,65,1,128,32,8,130,32,8,10,0,4,65,16,4,65,204,70,204,228,155,39,18,9,60,3,8,242,41,104,154,70, -254,207,129,166,210,175,26,249,10,160,42,90,242,207,200,207,52,250,61,151,252,187,28,207,125,228,223,90,28,2,136,86,129,254,171,195,63,226,224,200,223,102,247,61,247,9,111,41,147,151,58,242,103,106,242,31,113,228,61,85,136,15,201,255,186,111,201,221, -98,239,205,9,220,200,126,16,175,66,224,217,31,28,222,39,186,141,79,124,55,4,65,64,20,69,224,249,204,248,226,25,19,0,146,36,193,130,5,11,96,231,206,157,120,5,32,5,13,51,234,228,63,85,86,129,218,85,250,123,142,163,134,52,105,53,109,30,11,8,22,94,180,186, -69,167,59,108,247,17,227,239,119,23,59,124,158,18,71,144,124,31,176,216,5,127,184,217,235,35,127,213,71,254,185,151,124,245,120,74,236,14,103,192,102,39,127,238,36,191,23,200,203,245,33,163,79,191,255,164,39,78,100,68,4,208,191,23,165,223,115,28,23,149, -98,74,172,103,219,16,253,253,16,121,13,240,60,55,208,187,125,184,47,210,19,31,32,6,191,55,62,40,31,234,217,58,216,79,12,126,127,124,64,234,27,58,24,31,34,251,31,143,13,74,160,74,42,168,106,82,188,80,113,64,182,199,62,23,21,12,60,143,194,0,65,238,186, -235,46,56,243,204,51,11,75,0,80,15,98,243,230,205,176,123,247,110,188,2,144,2,119,1,136,53,182,130,215,95,233,12,19,207,189,44,212,228,173,180,58,197,202,80,163,183,130,220,41,85,254,74,23,253,121,88,180,11,1,135,207,234,34,247,142,155,23,121,142,136, -2,96,138,129,69,4,134,142,184,249,148,65,101,16,6,134,52,115,246,143,108,84,168,251,168,94,8,212,2,4,57,203,72,132,194,2,85,9,43,48,177,16,149,135,163,253,210,0,177,243,251,251,119,69,14,202,49,101,119,223,206,200,174,72,111,124,199,240,193,248,142,129, -61,145,61,145,158,196,190,200,65,169,15,18,32,227,201,71,10,157,190,190,190,76,62,122,50,135,213,106,197,179,143,20,4,212,163,119,4,108,78,95,133,179,212,225,183,214,16,35,223,20,168,118,53,187,66,182,6,242,179,42,209,42,148,147,159,7,136,23,109,103, -134,29,52,226,57,143,68,8,104,100,64,101,170,153,121,211,28,36,163,239,144,248,136,141,254,8,212,229,55,53,195,71,249,183,250,0,172,34,93,110,0,135,197,99,117,184,253,92,136,236,106,125,113,93,128,236,3,199,62,59,93,14,160,75,22,170,162,41,137,136,220, -79,94,123,7,118,69,118,70,251,19,27,15,109,26,220,60,180,63,182,190,111,199,240,150,222,29,195,187,162,125,137,94,37,161,226,69,131,20,4,130,32,20,166,0,64,144,124,196,234,18,121,111,153,163,140,24,246,70,226,197,183,133,155,188,157,158,18,71,139,167, -212,81,103,243,136,101,196,192,219,233,58,57,91,199,39,47,69,214,152,113,87,228,164,209,147,227,202,191,221,190,150,133,159,121,36,16,193,34,123,138,170,141,8,151,79,121,222,89,248,160,51,96,13,186,195,246,54,142,227,22,53,31,83,206,142,131,42,107,74, -108,80,58,56,124,48,182,131,8,130,181,68,24,172,233,221,54,188,234,224,166,129,13,228,247,59,134,14,196,162,120,117,33,8,10,0,4,201,10,44,78,17,136,177,175,40,170,115,183,21,143,241,141,35,6,127,188,191,202,213,78,60,251,26,171,67,244,208,117,111,234, -201,51,239,151,122,242,228,171,36,43,255,222,165,206,115,180,145,156,0,85,86,62,30,74,16,44,14,161,36,88,235,46,9,53,120,38,214,207,44,97,130,66,142,41,82,124,88,222,49,176,59,178,238,208,150,161,119,14,174,31,120,107,207,234,222,213,253,187,34,91,163, -125,137,56,94,133,8,130,2,0,65,210,14,241,226,93,129,42,87,115,89,87,96,2,49,246,83,194,77,158,241,174,176,189,145,24,123,47,13,185,39,13,125,242,149,136,224,18,119,106,202,32,121,252,20,250,98,63,72,254,159,227,192,98,115,137,245,37,173,254,250,178, -206,192,177,116,73,65,138,169,82,164,55,190,109,96,119,116,21,17,3,43,14,172,31,120,125,255,218,190,247,250,118,70,246,107,170,134,199,18,65,80,0,32,136,97,131,239,41,110,241,117,86,116,7,166,149,118,4,102,4,106,220,227,236,94,177,150,174,211,83,207, -158,101,185,163,177,79,175,46,24,17,6,170,66,4,193,136,191,79,69,129,51,96,109,116,19,241,85,57,33,120,50,21,15,241,65,233,16,17,0,171,247,173,233,123,109,247,202,158,151,247,174,233,127,171,127,231,240,238,195,165,147,8,130,160,0,64,144,79,197,225,179, -90,66,77,158,182,154,41,225,217,229,221,193,185,129,26,215,68,135,223,86,205,11,192,214,234,21,98,240,229,4,121,197,49,73,45,227,162,128,69,90,62,88,70,224,69,190,40,220,232,153,83,210,234,155,211,117,106,205,151,227,67,82,127,255,142,200,187,251,214, -246,189,176,107,101,239,243,68,24,188,213,179,117,168,23,143,30,130,160,0,64,16,98,52,56,8,84,187,43,171,38,21,205,168,28,87,180,176,180,195,63,195,85,100,107,33,30,62,71,13,62,245,240,165,40,122,247,57,33,10,84,141,136,51,162,12,70,42,8,120,129,247, -133,26,61,179,138,91,125,179,58,79,169,185,53,62,40,237,57,184,113,240,181,157,111,31,122,122,199,138,131,47,238,93,219,191,70,138,200,168,228,16,20,0,8,82,40,208,44,125,226,221,119,86,79,14,45,168,28,31,92,66,4,192,100,155,91,244,209,144,190,146,80, -208,195,207,87,65,32,242,101,101,93,129,147,43,198,7,79,158,116,126,163,210,191,43,178,234,192,250,254,167,55,191,180,239,137,237,111,28,92,49,124,48,62,132,71,13,65,1,128,32,121,6,241,234,173,229,93,129,201,213,147,195,75,171,38,135,150,248,43,156,99, -137,65,224,169,193,167,158,254,199,91,221,34,121,42,8,98,35,75,6,28,8,222,50,199,216,64,181,107,108,243,194,242,27,134,246,199,182,31,218,52,248,236,150,87,246,63,178,245,213,3,47,244,110,27,234,193,35,134,160,0,64,144,92,53,250,33,155,181,106,98,104, -74,195,156,210,19,43,186,3,199,186,66,246,54,218,181,134,54,153,145,98,133,93,138,135,106,0,88,62,7,125,81,236,94,75,117,245,148,208,133,181,211,139,47,140,13,36,246,237,93,211,247,252,150,151,247,255,105,235,43,251,159,233,221,62,124,16,15,24,130,2, -0,65,178,28,171,75,132,138,238,224,148,230,99,202,78,174,153,86,124,2,17,1,109,244,97,79,155,235,96,166,62,242,105,208,74,1,53,154,20,133,188,200,151,84,79,10,157,81,59,181,248,140,88,63,17,3,107,251,254,78,196,192,31,54,60,179,231,133,161,3,177,126, -60,90,8,10,0,4,201,18,232,112,153,146,86,127,203,152,37,21,167,212,78,15,159,234,43,119,78,160,195,102,104,184,55,49,92,200,70,95,251,88,215,192,145,185,1,159,82,21,199,29,233,39,252,65,99,97,238,99,191,47,136,163,166,106,32,29,22,3,22,34,6,38,134,206, -37,98,224,220,73,231,55,108,223,181,178,247,209,13,207,238,249,253,214,127,236,127,41,129,9,132,8,10,0,4,201,12,129,106,87,81,211,130,178,165,228,117,78,176,214,51,87,180,243,118,37,126,56,188,159,127,166,156,118,197,35,126,234,145,175,234,200,215,164, -81,255,192,170,243,28,207,70,240,114,35,95,217,48,31,78,36,63,23,152,6,160,163,71,121,78,132,15,154,10,115,108,59,10,237,221,203,141,180,243,213,228,15,189,39,253,170,30,249,154,28,240,155,220,238,225,247,161,191,232,164,63,238,200,215,252,16,14,76,12, -140,44,23,217,60,150,234,230,5,101,87,146,235,237,202,254,157,195,43,183,188,178,255,247,239,63,185,235,255,246,174,233,95,143,205,135,16,20,0,8,146,102,104,136,191,114,124,209,180,214,165,21,231,84,79,14,159,236,240,91,203,21,73,97,235,250,137,161,220, -117,200,14,27,87,149,189,20,106,222,143,24,117,129,23,153,1,183,10,54,176,11,14,242,114,130,83,116,147,151,7,156,150,145,175,228,247,118,209,69,94,78,246,231,54,242,119,173,188,29,44,188,13,68,242,239,69,222,194,182,65,223,135,126,165,191,255,240,84, -1,250,94,146,26,63,34,6,36,37,193,246,35,174,198,200,207,19,144,80,98,16,147,163,16,87,34,16,37,175,136,60,4,195,210,0,68,229,225,35,223,199,200,207,227,74,148,189,36,34,38,152,136,208,180,35,194,128,10,147,195,47,14,248,156,59,71,116,153,224,240,50, -146,167,196,209,61,238,140,186,238,174,147,107,110,221,255,126,255,51,235,158,220,245,155,141,207,237,125,98,232,64,108,24,239,82,4,5,0,130,152,136,159,120,251,205,243,203,78,110,59,190,234,34,127,149,115,58,53,42,82,156,24,168,33,41,183,12,61,53,240, -212,219,166,70,158,188,168,129,164,6,145,26,106,106,196,221,86,31,248,172,69,16,176,133,193,79,94,65,242,242,218,130,228,103,65,112,89,188,224,32,70,222,33,184,70,12,120,246,64,141,125,156,136,132,40,17,3,84,16,12,36,122,161,63,209,3,125,241,131,208, -27,219,15,189,228,43,253,126,80,234,35,127,62,200,4,133,60,50,45,136,70,38,4,242,226,217,139,203,137,200,193,225,4,66,178,187,142,146,86,255,241,229,93,129,227,39,95,212,180,113,203,203,251,126,191,246,137,93,191,221,245,78,207,90,140,10,32,40,0,16,68, -39,116,132,108,221,244,240,216,214,99,43,47,172,158,28,90,238,8,216,202,233,186,126,114,125,54,55,60,122,106,232,15,123,194,2,47,48,239,220,111,13,16,195,94,12,197,142,10,40,118,86,64,152,124,45,178,151,48,35,239,182,248,178,206,184,31,13,52,170,144, -140,74,184,161,232,83,143,137,10,195,210,32,19,1,135,162,251,224,96,108,15,236,143,238,130,253,145,157,228,251,189,76,48,68,165,33,34,12,164,145,72,133,192,162,31,84,24,112,89,42,10,180,145,4,83,57,14,96,115,139,141,29,39,85,223,66,68,234,151,246,172, -234,125,226,189,191,238,248,229,166,23,246,254,45,54,32,73,120,55,35,40,0,16,228,40,176,185,45,98,219,241,149,75,90,22,149,127,190,180,221,191,132,120,251,22,230,237,15,102,239,115,84,101,198,254,131,176,183,133,183,18,99,238,133,32,49,236,165,206,106, -40,119,213,66,133,187,142,25,123,191,173,136,9,129,130,19,116,192,51,129,67,95,101,206,154,143,252,25,53,250,3,82,47,28,136,238,134,189,195,219,97,247,240,86,216,51,188,13,14,196,118,195,64,188,7,98,106,116,68,68,37,151,67,4,58,102,49,203,68,1,91,34, -24,102,121,20,118,218,112,168,114,124,240,228,254,221,205,239,110,120,102,207,47,222,125,120,219,3,125,59,177,156,16,65,1,128,32,159,136,183,220,233,239,62,181,230,204,134,185,165,159,11,214,184,199,43,172,13,111,118,122,251,204,179,39,70,139,126,165, -30,170,203,226,33,94,124,13,51,242,53,238,102,168,242,52,66,137,163,146,133,239,185,2,203,162,215,245,32,226,45,44,42,66,95,45,254,177,71,126,78,151,19,168,40,216,53,180,25,182,15,109,128,29,67,155,96,127,100,23,12,38,122,89,110,2,93,62,17,88,126,67, -22,69,9,104,84,32,166,0,93,224,112,6,109,93,19,207,171,255,97,251,9,85,55,111,123,253,192,253,111,63,184,229,87,123,86,245,174,199,51,142,160,0,64,16,66,105,135,191,178,109,105,229,197,77,11,202,46,118,133,237,53,244,225,153,109,107,251,116,189,94,30, -49,248,52,169,206,107,13,66,153,171,6,106,61,45,80,231,109,133,74,119,3,11,227,179,76,123,196,52,232,146,66,141,167,153,189,166,195,18,246,51,154,95,176,39,178,13,182,13,188,15,91,6,214,18,81,176,17,122,98,7,88,18,98,182,9,2,85,86,201,181,172,130,96, -227,203,91,22,149,127,185,97,78,201,23,247,174,238,123,248,173,7,54,255,100,211,11,251,94,199,51,140,160,0,64,10,211,240,183,251,155,198,159,93,127,69,195,236,146,243,45,78,177,72,138,200,89,19,230,167,235,213,52,73,141,26,125,106,76,168,193,167,222, -125,189,183,13,26,253,29,196,224,55,178,53,123,100,244,241,90,3,236,117,56,82,64,171,14,246,68,182,195,150,254,181,176,190,111,37,108,31,92,15,61,241,253,144,80,226,236,220,209,232,66,166,133,153,54,178,60,192,113,224,170,24,23,60,159,188,206,221,249, -86,207,99,171,255,188,253,135,155,95,218,247,52,54,169,66,80,0,32,5,65,205,212,112,71,251,241,85,95,32,222,208,121,162,93,112,209,48,127,54,24,126,133,121,249,9,182,158,79,203,235,106,60,245,196,216,119,194,24,255,56,168,246,52,129,223,22,194,147,151, -133,216,4,7,139,196,208,215,188,202,147,32,38,71,96,231,240,38,34,6,222,133,245,189,239,176,101,131,129,68,15,75,44,20,57,11,203,35,200,84,116,128,38,13,178,101,45,14,120,34,2,78,168,158,20,58,225,208,230,193,103,222,249,195,214,123,214,60,182,243,81, -9,133,0,50,138,112,154,150,153,82,149,68,34,1,45,45,45,176,117,235,86,60,11,5,66,195,220,210,174,241,103,213,93,91,49,54,120,54,199,113,54,250,32,204,212,245,119,24,234,225,203,154,196,18,212,168,129,175,243,142,129,214,224,4,104,246,119,67,185,179,134, -53,185,65,114,27,90,126,184,169,255,61,88,211,243,79,216,208,255,46,171,60,160,125,14,104,100,128,190,50,189,84,32,88,121,16,201,235,208,166,161,23,222,249,195,150,239,172,121,124,23,10,129,2,226,231,63,255,57,124,238,115,159,195,8,0,146,159,148,119, -7,219,102,92,209,114,35,241,120,206,38,191,181,102,58,177,143,26,125,154,64,70,215,242,195,142,114,102,236,59,138,166,64,163,175,147,133,150,145,252,130,10,187,9,197,115,216,139,246,31,216,54,180,1,222,59,180,130,9,130,93,195,91,88,51,35,26,21,160,149, -27,153,16,3,180,137,21,125,249,170,156,115,22,220,220,57,167,251,244,186,231,87,254,97,235,119,215,62,182,243,81,92,26,64,48,2,128,228,36,165,29,254,134,241,103,213,95,223,48,187,228,2,226,229,56,89,75,213,12,57,252,180,60,143,173,9,147,7,61,205,206, -111,13,142,135,238,208,116,104,240,117,20,100,73,30,146,204,243,216,49,184,9,222,235,89,1,239,30,122,141,124,191,145,137,129,100,231,68,107,198,34,3,201,136,128,0,135,182,12,254,253,173,223,109,254,214,170,63,109,127,6,207,22,70,0,48,2,128,228,4,197, -99,124,165,147,206,111,184,174,126,86,201,101,162,93,240,81,143,63,19,94,63,205,220,79,168,113,22,222,15,59,202,160,189,104,50,51,250,77,196,211,167,235,198,72,129,123,63,228,186,160,185,29,244,181,180,230,28,216,57,180,9,222,57,248,50,188,123,240,53, -246,125,76,137,177,168,192,104,55,102,58,28,17,240,87,56,23,30,243,149,174,133,99,22,87,252,133,8,129,187,54,189,136,85,3,8,10,0,36,75,241,150,59,61,99,151,215,94,209,177,172,234,58,187,215,82,154,136,140,254,52,62,154,232,37,17,79,159,38,244,209,208, -239,184,192,108,152,88,60,7,90,2,227,88,73,25,130,124,26,180,148,147,190,142,171,61,15,54,247,175,133,183,15,190,68,196,192,171,176,55,178,157,37,134,90,121,219,168,86,19,200,68,4,16,5,11,21,227,130,203,42,199,23,29,183,253,141,131,247,255,227,255,173, -251,230,222,213,125,216,71,0,49,71,4,227,18,0,98,20,155,91,228,186,79,171,61,103,252,57,245,95,117,6,108,99,18,81,153,149,61,141,38,178,38,51,195,111,23,29,172,84,111,66,241,92,230,237,211,158,250,8,162,23,90,98,248,126,239,219,176,98,255,179,176,166, -231,77,232,143,31,202,204,18,1,121,43,139,93,160,145,129,193,141,47,236,253,241,171,63,93,255,253,190,157,195,7,240,12,229,62,184,4,128,228,166,122,228,57,104,154,95,58,119,218,101,45,183,23,213,185,231,176,114,190,81,108,224,115,216,219,167,195,117, -104,95,253,113,225,153,48,169,100,1,43,7,67,16,83,196,173,224,128,46,34,36,233,235,80,108,31,91,34,88,177,239,89,216,54,248,62,200,138,196,38,52,142,74,84,96,164,124,144,220,115,158,49,139,43,190,82,51,37,124,206,170,63,109,187,235,141,223,108,250,69, -98,88,198,76,65,4,35,0,200,232,81,214,17,168,159,126,69,203,127,84,79,14,93,192,38,163,37,70,111,20,47,13,239,211,108,110,155,96,103,117,250,211,75,23,179,7,52,134,248,145,209,17,158,42,235,49,240,234,158,167,88,242,96,50,42,96,97,249,2,163,5,47,112, -32,58,4,232,219,54,252,218,235,247,109,188,109,237,99,59,254,166,225,240,65,140,0,96,4,0,73,39,142,128,213,49,229,162,166,171,59,78,170,190,73,180,241,193,209,92,227,167,165,123,180,132,143,134,245,103,150,45,133,105,101,139,89,184,31,65,70,213,107,2, -158,117,33,164,47,26,21,120,99,223,179,240,218,190,191,179,121,5,244,79,105,84,32,221,203,3,108,240,208,144,12,158,50,199,212,197,183,117,63,53,102,113,249,111,95,253,217,250,219,247,172,238,221,132,103,8,65,1,128,152,251,208,35,207,179,182,227,171,142, -157,114,73,211,157,254,42,215,56,106,248,71,35,179,255,112,152,159,122,93,229,174,122,152,78,140,254,228,146,5,184,182,143,100,5,116,254,195,146,154,179,96,126,213,41,176,234,224,171,240,210,158,199,224,253,222,149,68,172,198,193,202,219,217,108,130, -116,114,184,98,160,102,74,248,220,242,238,224,177,171,254,180,237,155,43,126,181,241,135,209,254,68,28,207,14,130,2,0,49,76,121,87,160,102,234,231,155,255,139,60,100,206,163,15,155,209,104,219,75,13,63,13,243,211,245,213,38,127,23,204,174,56,1,198,133, -102,18,239,202,158,215,199,90,147,162,160,197,7,65,27,62,8,234,240,33,80,135,246,147,239,15,145,159,13,177,68,48,206,230,1,222,83,10,66,184,9,132,162,6,0,193,146,241,125,86,135,183,129,58,176,46,249,53,222,75,63,4,112,130,131,236,107,17,112,116,64,146, -189,152,124,31,6,206,234,7,206,226,205,203,243,70,43,4,104,226,41,125,109,236,95,5,47,238,250,43,188,115,240,21,24,150,6,216,53,43,164,57,79,128,54,12,226,120,46,56,225,156,134,187,27,102,151,158,241,218,47,215,223,180,230,177,157,207,2,46,11,32,40,0, -16,61,216,189,22,24,127,78,253,149,19,206,174,191,77,176,9,197,163,17,238,215,52,34,48,212,24,123,160,142,13,207,132,121,21,203,160,45,56,41,255,12,61,49,242,42,49,242,218,192,94,80,250,119,18,3,186,135,188,246,130,22,33,198,62,54,64,108,104,12,52,37, -145,108,30,127,56,4,147,60,64,201,223,138,86,224,125,149,96,169,39,162,168,101,49,112,206,81,238,96,72,206,147,188,239,89,144,118,61,6,10,49,254,154,52,4,201,46,79,28,251,239,200,126,211,96,56,79,30,51,196,8,82,227,207,89,131,192,59,136,40,112,84,0,231, -170,6,222,89,65,4,66,25,17,8,116,255,243,163,237,50,237,40,73,95,123,134,183,194,139,187,31,101,73,131,180,29,49,93,26,16,56,49,141,167,68,99,73,184,238,98,251,132,37,183,143,125,166,101,81,197,207,94,188,103,205,109,135,54,15,238,195,167,25,242,73,96, -18,32,242,137,212,207,44,233,158,117,117,235,119,138,26,60,199,80,195,79,31,46,105,245,34,137,65,97,137,125,162,131,101,243,207,175,56,25,234,125,237,249,97,236,35,61,160,246,239,2,165,119,27,40,61,196,75,238,219,65,60,251,3,196,208,247,3,80,67,79,62, -59,179,155,212,75,228,5,90,94,49,98,240,185,127,27,35,1,69,102,34,129,247,148,128,109,220,153,96,29,179,100,84,62,143,210,255,30,36,214,255,63,80,250,86,38,141,54,77,126,251,183,161,110,109,68,16,168,116,44,30,19,15,236,51,83,113,32,88,147,194,192,22, -38,98,160,18,120,119,29,8,238,6,224,220,181,192,211,101,30,222,146,243,231,159,230,9,188,188,231,49,120,101,207,147,112,48,186,55,237,66,224,72,84,194,41,66,180,47,177,253,205,255,221,124,243,91,15,108,126,96,52,19,117,145,163,39,147,73,128,40,0,144, -143,123,253,214,233,151,183,220,216,121,114,205,45,228,183,78,57,158,222,117,126,106,8,98,74,148,77,223,155,24,158,11,243,42,79,102,157,217,114,214,216,75,81,98,236,119,131,122,104,19,40,7,55,18,131,191,37,233,217,83,175,94,145,62,102,232,133,15,60,123, -67,22,89,34,54,85,2,107,203,66,112,76,191,18,64,180,165,237,243,73,59,31,129,248,250,255,38,239,25,37,94,189,25,221,20,53,38,8,168,48,208,52,153,9,5,118,124,200,245,192,219,138,153,32,224,189,77,32,120,90,200,247,181,44,130,144,171,208,137,132,47,239, -126,156,69,5,14,68,119,131,133,8,1,49,205,66,128,86,11,88,93,34,236,124,187,231,15,47,222,179,230,166,61,171,122,241,129,139,2,0,5,0,242,137,94,255,100,226,245,255,128,120,253,83,105,134,113,58,175,13,186,198,31,87,34,96,23,92,48,169,120,30,44,168,58, -149,117,97,203,57,131,31,31,2,149,122,246,251,215,129,188,255,125,80,123,182,38,67,251,114,44,121,131,209,7,188,48,226,213,167,53,51,92,99,251,98,169,159,5,206,121,55,166,69,4,72,219,30,76,26,127,230,241,167,217,131,61,34,10,164,164,40,160,83,251,172, -1,224,93,213,32,120,199,0,239,239,32,162,160,25,56,123,113,206,93,51,131,137,62,120,137,136,128,164,16,216,53,146,35,144,222,227,105,113,8,32,199,213,253,111,254,118,211,87,87,220,183,241,23,180,116,23,65,1,128,2,0,1,187,207,98,153,126,89,203,87,70,188, -126,91,58,189,254,164,225,143,178,53,254,241,197,179,97,97,213,114,168,201,165,198,61,74,130,133,241,149,189,239,129,188,119,53,40,135,182,36,215,237,229,4,51,242,156,32,154,231,217,235,20,36,214,214,165,224,152,125,141,169,219,149,247,62,3,177,85,119, -16,227,111,251,140,112,127,250,174,28,38,10,84,137,232,1,133,69,9,104,82,33,239,170,1,193,215,14,66,112,44,240,222,22,224,44,254,220,17,2,82,31,60,191,243,47,68,8,60,2,61,177,253,172,233,80,58,155,10,113,52,26,224,20,97,247,59,61,15,191,112,207,154,27, -48,26,128,2,0,5,64,129,83,55,163,120,236,236,107,218,126,72,188,254,89,233,246,250,233,26,63,71,140,71,87,104,42,44,169,57,27,26,188,185,177,198,175,13,29,0,121,223,26,144,119,175,4,101,223,58,80,7,247,178,36,189,35,6,159,134,243,51,60,83,254,35,18,43, -17,1,231,220,47,129,165,121,161,41,91,84,163,187,33,186,226,242,100,162,95,54,173,201,211,124,2,85,102,75,7,52,209,144,179,133,88,84,64,8,78,0,33,48,150,45,25,192,40,246,238,215,75,111,252,0,60,179,227,97,120,121,207,227,44,58,64,219,89,115,105,76,136, -28,137,6,236,253,231,253,155,110,124,237,222,245,191,197,167,96,225,10,0,172,2,40,80,68,27,15,51,174,28,115,245,184,51,234,190,78,108,190,59,157,165,125,180,129,15,29,199,75,27,167,44,37,134,191,163,104,74,182,155,124,22,202,151,119,173,36,175,183,217, -90,190,26,237,99,63,167,161,104,160,198,198,154,173,35,132,147,137,117,177,55,127,7,98,245,100,224,236,62,227,194,109,211,175,64,139,31,34,23,77,150,117,90,164,198,93,16,200,39,78,46,119,104,137,94,144,15,188,12,210,254,23,129,19,93,44,58,32,6,199,129, -16,154,2,130,183,213,164,156,5,243,161,61,45,78,107,188,28,102,149,31,7,79,110,127,16,86,236,125,26,98,106,20,236,172,228,213,124,97,73,251,119,240,2,87,58,253,242,150,251,203,58,252,139,94,184,103,205,245,61,91,134,112,174,64,33,218,1,60,4,133,71,73, -171,175,122,254,151,59,127,76,110,254,19,232,196,190,116,101,248,83,163,159,80,226,80,233,174,103,134,127,74,233,49,105,245,108,140,217,124,149,24,250,13,32,239,124,27,228,29,255,4,133,8,0,234,73,3,207,143,100,170,231,208,248,96,193,194,202,10,19,239, -255,13,108,221,203,141,121,255,131,27,65,38,6,21,68,103,246,127,110,150,111,33,142,152,76,34,226,6,55,64,188,127,13,112,219,126,207,202,13,133,192,56,16,195,211,129,247,119,146,191,154,125,109,163,75,156,85,112,193,152,27,153,16,120,108,235,253,176,234, -224,107,108,41,137,46,151,153,13,237,36,72,69,127,237,180,226,243,74,59,2,211,94,250,193,154,47,174,126,100,199,83,248,116,68,1,128,228,49,227,207,170,63,101,202,165,77,63,178,185,197,242,248,80,122,234,250,233,58,127,76,142,128,223,86,4,39,212,93,0, -243,43,79,33,222,76,118,26,16,229,208,38,144,183,173,32,70,255,13,150,177,79,67,251,28,109,174,195,146,206,156,57,123,158,105,159,0,105,211,11,96,235,56,201,80,179,32,105,207,83,160,201,195,89,105,48,63,43,18,66,147,21,57,214,159,159,136,129,200,110, -80,134,182,178,42,6,206,81,14,98,209,4,16,139,103,131,64,196,64,182,69,6,104,123,235,171,186,238,130,183,15,188,4,143,18,33,176,117,96,93,218,74,7,105,3,33,209,198,55,46,188,181,235,137,170,201,161,187,158,251,246,123,183,199,250,19,18,32,40,0,144,252, -193,225,183,218,231,223,216,241,141,150,197,21,215,73,177,244,181,241,165,235,252,2,47,194,236,242,227,225,184,186,243,32,100,47,203,186,99,65,203,242,228,109,175,129,180,237,85,22,222,167,158,254,7,70,223,149,31,39,156,70,1,250,118,50,81,35,132,155, -117,30,40,137,252,251,55,71,140,104,46,195,37,207,237,72,254,130,22,223,15,137,29,127,6,105,215,163,192,19,175,91,12,77,5,161,120,14,17,3,237,144,61,185,28,0,227,194,179,160,189,104,50,188,176,235,47,240,212,246,135,160,55,118,0,236,162,211,244,57,3, -170,76,187,110,42,92,235,146,202,91,194,77,222,25,79,127,227,221,203,118,175,236,125,31,159,154,40,0,144,60,160,118,122,113,251,220,47,181,221,27,172,245,76,75,215,184,222,195,225,254,102,127,55,156,84,127,49,180,4,198,101,213,49,208,18,195,32,239,124, -139,121,197,52,131,95,141,246,19,131,64,215,144,173,249,99,244,63,102,244,104,101,130,114,96,131,110,1,160,198,246,146,227,180,55,253,37,127,163,31,30,33,255,137,35,145,129,93,16,223,250,0,112,59,254,200,18,8,197,146,57,44,50,64,163,4,217,0,13,255,47, -172,58,29,198,135,231,192,163,91,255,7,94,221,251,20,168,170,98,126,75,108,13,88,23,193,64,181,123,206,169,255,61,245,229,21,247,109,188,122,197,125,27,30,208,176,90,16,5,0,146,187,76,185,164,233,28,242,250,33,199,113,193,116,24,255,195,225,254,160,189, -24,150,54,158,13,115,42,78,28,149,46,103,71,45,76,136,135,79,141,190,188,245,53,80,6,118,143,60,255,109,57,29,222,79,197,241,165,29,8,117,159,219,216,62,114,0,35,201,210,191,124,61,64,71,34,3,26,185,62,214,130,220,183,10,248,45,191,101,149,4,98,217,98, -16,139,38,101,69,229,3,29,58,68,243,3,166,148,44,128,63,111,254,37,108,32,251,153,142,101,1,90,2,204,9,92,104,198,149,99,126,87,60,198,55,245,239,119,190,123,83,12,7,11,161,0,64,114,11,135,223,106,157,119,99,199,183,90,22,149,95,43,199,20,80,20,243,165, -60,157,120,70,153,89,126,44,156,88,119,17,123,72,101,133,183,47,69,147,33,254,13,207,129,76,188,125,250,123,186,38,158,83,137,124,102,69,1,232,16,33,221,81,147,129,100,169,93,129,28,43,42,116,56,242,210,148,56,155,115,32,239,123,30,120,119,61,136,165, -11,192,82,58,63,43,162,2,99,2,227,225,134,241,157,240,236,142,63,194,147,219,126,7,3,82,31,216,89,14,131,121,203,2,218,72,130,96,227,220,210,171,3,213,174,113,79,127,99,213,37,187,87,246,108,192,167,42,10,0,36,7,168,24,27,172,59,230,150,174,95,21,213, -187,231,198,233,0,31,147,147,252,105,223,126,218,197,175,202,211,4,167,212,127,14,186,66,211,178,226,115,171,196,195,151,54,60,11,210,230,151,64,233,219,201,50,168,57,161,64,188,253,127,19,163,49,160,164,14,143,247,41,48,221,196,3,140,36,173,170,195, -91,33,190,225,167,32,109,123,8,132,240,116,176,16,177,43,4,186,51,251,208,230,44,176,168,250,12,232,14,205,128,63,110,190,23,222,218,255,2,139,4,136,38,71,42,232,12,144,64,141,123,214,41,63,156,242,210,63,254,223,186,207,191,253,224,150,71,240,233,138, -2,0,201,98,58,150,85,47,154,115,93,219,175,68,187,80,145,142,44,127,154,228,39,242,86,88,90,123,46,28,87,115,46,56,196,204,175,159,43,251,214,66,98,221,147,32,109,127,29,52,186,182,95,144,222,126,154,188,226,66,103,164,146,64,83,162,32,239,122,28,228, -189,127,7,193,223,5,150,138,227,64,12,207,98,83,14,51,69,137,179,18,174,232,184,3,94,223,251,52,252,105,243,47,216,124,1,179,147,4,105,244,144,23,185,146,185,215,183,255,185,168,222,243,181,231,190,189,250,235,216,70,24,5,0,146,109,207,41,145,135,89, -95,28,115,237,248,115,234,239,150,227,138,133,222,184,230,123,253,81,168,247,181,193,233,141,87,66,19,121,8,102,214,177,85,65,222,190,2,18,107,159,0,121,247,187,44,108,203,137,246,60,77,232,67,50,175,133,132,145,94,8,26,40,61,111,131,220,243,38,155,90, -200,132,64,233,66,214,150,56,83,208,254,26,99,130,227,224,143,155,238,101,73,130,60,249,37,154,88,185,65,171,4,36,69,230,186,78,173,185,51,80,227,234,122,234,246,149,151,13,236,137,244,225,69,129,2,0,201,2,188,101,14,251,130,155,59,127,84,63,171,228, -82,186,118,103,118,55,223,195,94,63,173,233,63,150,120,254,214,76,38,133,201,9,144,182,188,76,12,255,227,108,0,15,11,81,211,48,191,197,137,23,2,50,58,81,17,226,245,83,31,91,29,222,6,241,117,63,128,196,182,63,128,165,124,9,17,3,199,103,108,56,145,207, -90,4,23,181,222,12,93,69,83,225,255,54,253,12,246,71,118,153,26,13,160,207,20,250,108,169,28,95,116,250,242,159,78,107,122,250,27,239,158,187,237,245,3,107,240,122,64,1,128,100,144,146,86,95,213,226,219,198,222,31,106,242,206,137,13,152,155,229,175,129, -10,81,57,2,245,222,86,56,189,233,139,208,156,65,175,159,38,242,73,27,95,32,134,255,49,80,14,109,102,51,5,64,180,99,144,26,201,28,212,203,166,203,3,137,67,16,223,244,75,144,118,253,21,68,226,141,91,171,78,206,88,194,224,132,226,185,208,232,239,132,255, -219,248,51,120,109,239,223,76,207,13,160,121,1,238,98,251,184,19,190,61,241,185,127,252,100,221,69,111,63,184,229,113,188,16,80,0,32,25,128,120,252,83,150,220,49,246,119,86,167,88,111,118,47,127,218,191,159,178,184,250,76,88,86,127,81,230,58,249,73,49, -72,108,120,6,18,107,30,99,237,121,233,240,29,92,223,71,178,43,40,32,178,78,137,154,52,8,137,173,191,3,121,207,83,172,132,48,83,66,128,70,3,46,105,187,5,218,130,19,225,225,77,63,131,190,248,65,83,239,95,90,42,200,139,92,241,156,235,218,30,241,150,57,174, -123,233,135,107,127,68,91,11,35,40,0,144,209,82,250,231,212,47,159,117,85,235,47,21,89,243,72,38,175,247,71,229,97,150,96,116,102,243,85,208,85,148,161,12,127,69,34,30,255,243,16,95,253,103,80,15,109,97,157,237,10,59,155,31,201,126,33,32,36,133,128,28, -25,17,2,79,130,165,108,41,88,170,79,203,200,210,192,180,210,69,208,232,235,128,7,214,255,16,86,30,124,5,108,130,221,180,113,195,52,47,64,83,20,97,210,249,141,63,116,6,109,245,207,222,189,250,122,226,132,96,118,32,10,0,36,189,207,24,14,230,94,215,126, -67,247,242,154,111,43,9,21,204,84,222,138,166,176,218,254,201,37,11,136,241,255,34,243,36,70,29,77,3,105,243,139,16,95,245,39,80,14,172,103,99,94,1,13,63,146,147,66,32,202,132,128,180,247,239,96,169,60,145,188,78,30,245,100,193,176,163,28,174,234,190, -11,158,218,246,32,252,117,235,111,32,65,238,111,179,114,120,104,94,64,180,63,1,173,75,43,175,13,84,187,106,30,185,225,159,23,13,29,136,245,227,5,128,2,0,73,3,118,175,133,159,127,83,231,247,91,143,171,184,58,62,64,231,160,155,103,252,227,74,140,205,33, -95,222,120,57,27,222,147,9,104,171,222,248,59,191,39,158,211,106,182,198,143,137,125,72,174,11,1,16,93,160,73,3,144,216,248,11,144,118,63,9,214,154,211,193,82,126,220,168,150,15,210,68,192,37,53,103,65,131,191,29,254,247,253,123,96,251,224,6,112,178, -242,93,115,50,104,104,135,209,226,86,255,201,167,253,116,90,249,223,239,92,121,250,174,183,123,182,227,201,207,13,120,60,4,185,129,59,108,119,157,242,227,169,15,142,89,90,113,117,172,95,50,209,248,107,16,149,135,160,202,211,0,95,26,251,221,140,24,127, -58,145,47,242,204,93,16,121,234,14,144,247,18,227,111,33,15,71,209,138,39,29,201,19,33,64,252,44,26,17,136,29,128,216,218,239,67,228,141,47,176,78,131,163,77,147,175,11,110,28,119,15,235,220,25,83,34,44,226,103,22,82,68,6,127,165,115,202,9,119,79,124, -174,122,82,104,44,158,116,20,0,136,73,132,155,188,37,203,190,63,249,177,146,86,223,114,51,147,253,84,242,0,136,42,81,242,64,56,14,110,32,15,134,58,111,235,168,126,46,45,210,3,177,87,127,14,195,127,253,50,72,155,95,78,206,114,23,237,120,194,145,60,125, -218,90,200,245,237,2,117,104,19,196,222,189,29,162,111,221,0,74,223,234,81,221,5,151,197,11,23,183,126,5,206,105,254,18,155,218,153,80,205,107,243,79,39,140,210,132,228,147,238,153,252,247,238,229,181,199,224,9,207,126,112,9,32,203,169,28,23,108,56,225, -219,19,255,100,243,88,58,105,9,142,105,55,43,185,241,45,188,141,60,8,174,37,94,255,201,163,251,161,84,5,18,235,158,128,248,202,135,65,29,220,203,178,250,49,179,31,41,28,33,144,92,131,87,14,173,128,104,239,59,96,169,88,10,214,186,243,129,179,133,71,109, -23,230,85,158,4,213,158,70,248,205,186,239,192,174,161,205,166,117,244,164,93,2,121,145,11,205,187,161,227,17,14,224,194,119,254,176,245,247,120,194,49,2,128,232,160,98,92,81,55,49,254,127,183,186,44,157,84,93,155,5,205,242,15,59,42,224,154,238,111,141, -186,241,151,119,175,132,225,71,111,134,232,203,63,1,45,218,155,236,220,199,225,101,136,20,32,35,67,124,18,219,255,4,145,215,47,7,105,251,195,163,58,124,169,193,215,1,55,142,191,7,38,22,207,101,203,128,180,239,135,41,250,94,214,64,73,40,142,57,215,183, -63,48,235,170,214,203,56,108,214,129,17,0,36,53,58,150,85,205,156,117,117,219,195,22,135,80,76,235,110,205,64,99,235,253,195,48,54,60,19,206,111,185,30,252,182,208,168,125,30,109,248,16,196,222,126,0,164,245,79,211,39,4,150,244,33,8,133,38,187,178,68, -193,62,136,173,251,62,155,64,104,109,188,116,212,6,14,121,44,126,184,162,243,14,248,235,150,122,120,116,235,253,192,17,107,77,135,13,25,22,1,10,121,218,104,42,63,229,226,166,159,218,125,22,223,223,191,254,238,221,128,173,2,80,0,32,159,77,247,242,218, -197,243,111,236,120,72,145,84,31,45,245,51,3,154,240,35,171,9,88,90,115,54,156,210,240,121,16,76,170,7,62,26,18,239,255,13,226,111,61,48,18,238,39,134,95,196,203,14,65,62,42,4,104,254,139,8,74,223,187,16,125,235,122,176,84,46,3,107,253,249,228,126,241, -141,198,155,195,9,117,23,66,185,187,22,126,75,68,200,176,52,0,86,19,170,20,52,85,99,101,130,93,167,212,124,139,24,127,239,211,223,120,247,86,13,69,0,10,0,228,223,26,255,147,231,221,208,254,91,41,174,56,53,83,106,252,57,144,212,88,114,189,127,204,141, -44,225,111,180,80,123,183,65,108,197,175,217,148,62,78,176,226,160,30,4,249,44,168,225,213,84,72,108,123,16,148,131,175,129,181,241,115,32,150,204,29,149,183,158,16,158,203,150,6,127,181,230,27,176,99,112,147,105,121,1,180,69,121,215,169,53,95,37,143, -34,247,211,223,88,117,45,21,6,72,118,128,139,175,217,101,252,151,207,163,158,127,66,53,201,248,211,250,254,8,4,108,197,112,117,247,55,71,207,248,107,10,36,86,253,41,153,221,191,125,69,210,235,231,81,107,34,200,209,105,118,158,53,18,82,163,187,33,246, -238,109,16,91,125,39,104,241,3,163,242,214,213,238,38,248,210,216,239,65,119,104,58,68,88,94,128,57,207,161,216,160,68,71,149,95,115,242,15,38,255,212,25,176,98,86,0,10,0,228,99,198,255,2,98,252,31,160,163,124,205,234,238,71,215,251,233,248,222,235,199, -125,15,154,253,163,179,166,72,7,245,12,63,126,43,68,95,189,23,52,57,142,217,253,8,162,251,233,108,5,16,108,172,129,80,100,197,149,32,239,125,122,84,222,214,107,13,192,23,186,238,132,133,85,203,217,8,112,58,10,220,184,83,144,28,36,84,55,189,248,178,19, -191,59,233,94,103,192,134,34,0,5,0,242,33,227,255,43,37,174,8,102,120,254,84,181,83,245,62,177,100,46,92,219,125,55,107,7,58,10,110,63,107,223,27,121,236,43,32,239,94,149,76,242,227,5,60,185,8,98,44,28,144,76,18,140,31,130,216,170,255,76,70,3,18,135, -210,254,174,116,138,224,89,205,87,195,233,141,87,178,126,33,138,102,78,9,50,141,4,148,119,5,47,57,241,187,19,239,117,96,36,0,5,0,26,127,98,252,111,104,167,198,159,55,195,243,167,106,61,70,84,251,162,234,51,224,178,246,219,193,33,186,211,254,25,212,254, -221,16,121,242,118,214,212,71,147,19,201,78,126,8,130,152,248,164,182,176,252,128,100,52,224,11,32,31,120,105,84,222,150,62,71,46,109,191,21,44,188,245,200,132,80,163,208,214,193,101,157,129,75,150,125,119,18,21,1,120,110,81,0,20,184,231,159,80,77,49, -254,84,165,203,154,68,84,251,21,112,102,211,23,129,31,133,250,122,105,195,51,48,252,232,77,32,237,248,103,50,201,15,189,126,4,73,111,52,32,182,15,98,43,191,6,241,247,127,72,110,250,104,218,223,149,246,9,248,98,215,93,224,179,6,217,146,128,25,208,229, -128,178,46,38,2,126,225,12,226,114,0,10,128,194,51,254,203,169,231,47,155,228,249,203,170,68,78,38,15,23,181,222,12,139,171,207,76,251,254,107,241,65,136,190,120,15,68,158,255,30,249,126,8,215,250,17,100,212,158,218,86,246,74,108,123,8,34,255,188,26, -148,129,117,105,127,203,102,127,23,92,59,246,219,80,238,170,101,115,4,76,17,1,67,50,148,19,17,112,252,55,39,220,43,88,208,20,161,0,40,28,227,127,242,188,27,58,126,75,61,127,227,107,254,28,107,235,107,23,157,112,69,231,127,178,25,224,233,70,217,183,134, -117,243,75,172,123,42,25,238,199,12,127,4,201,64,52,192,13,234,192,122,136,190,121,45,72,59,254,152,246,119,164,198,255,186,177,223,129,38,95,39,75,48,54,131,56,17,1,21,227,139,46,153,255,229,142,31,112,216,50,16,5,64,1,24,255,197,243,110,236,248,173, -156,80,172,170,9,198,159,134,228,104,104,142,206,252,238,40,154,146,246,253,79,172,250,51,12,63,241,31,160,246,110,31,169,235,199,155,22,65,50,6,237,27,160,202,16,91,251,61,150,36,168,73,253,105,125,59,218,61,244,170,238,111,30,41,19,52,39,18,32,209, -102,65,87,31,115,75,231,93,40,2,80,0,228,45,237,39,84,205,156,127,83,199,239,21,83,154,252,112,172,198,191,216,81,1,87,119,223,13,13,222,246,180,238,187,22,27,128,232,179,223,134,232,171,63,79,246,43,23,109,120,66,17,36,43,130,1,2,203,13,144,246,60,5, -81,186,36,208,255,94,90,223,206,41,186,225,242,142,59,96,106,233,66,211,68,192,72,179,160,155,137,8,248,42,138,0,20,0,121,71,197,184,96,215,156,107,219,30,86,18,170,215,140,53,255,152,50,12,149,238,6,184,102,236,183,200,215,250,180,238,187,114,96,61, -12,63,118,11,36,54,62,155,44,239,227,48,209,15,65,178,78,7,208,37,129,161,109,172,149,176,180,243,47,105,125,47,171,96,131,75,218,110,129,185,21,39,154,214,48,136,150,8,118,157,82,115,231,130,175,116,94,133,103,19,5,64,62,25,255,134,19,191,61,241,17, -209,33,20,211,113,153,198,141,127,4,234,188,99,88,119,63,26,1,72,39,52,203,63,242,196,215,88,91,95,108,229,139,32,89,14,49,204,160,74,16,95,251,29,136,175,251,46,251,62,109,111,197,137,112,222,152,27,96,81,245,233,16,147,35,198,69,0,249,231,177,33,22, -9,248,225,184,51,235,206,193,147,137,2,32,231,41,170,247,20,19,227,255,103,171,75,172,49,99,176,15,77,190,105,244,117,16,227,255,45,8,164,121,126,120,124,229,31,32,242,194,247,89,71,63,12,249,35,72,206,132,2,216,168,225,196,246,135,33,186,242,86,114, -255,14,167,239,173,200,175,51,155,174,98,149,71,102,137,0,90,34,56,231,186,182,95,117,47,175,93,130,39,19,5,64,206,226,14,219,93,75,254,115,220,255,217,60,150,14,57,110,134,231,63,12,77,254,78,248,66,231,215,217,24,207,116,146,120,239,175,16,123,253, -62,54,196,7,179,252,17,36,231,84,0,209,1,30,144,247,191,4,177,213,95,39,134,85,78,235,187,157,222,116,37,156,88,119,33,139,78,26,21,1,116,88,16,113,150,172,243,110,236,120,176,110,102,241,100,60,151,40,0,114,14,98,244,249,101,223,155,244,235,226,22,239, -44,41,170,24,247,252,21,234,249,19,227,223,69,140,191,53,189,198,95,217,179,138,24,255,95,2,103,177,177,193,36,8,130,228,168,12,176,16,17,176,239,121,72,108,186,47,237,239,181,172,254,98,56,177,246,66,83,34,1,52,79,138,142,67,95,124,219,216,135,43,198, -21,213,227,153,68,1,144,51,208,166,22,243,191,220,241,253,146,54,255,105,52,156,101,134,241,111,58,108,252,211,236,249,131,28,135,232,107,247,210,59,16,147,253,16,36,31,68,128,232,74,142,23,78,115,117,192,17,17,80,119,33,43,79,54,44,2,36,21,236,30,75, -229,177,119,142,251,163,167,196,17,196,51,137,2,32,39,152,117,77,235,245,237,199,85,93,29,31,52,158,128,67,67,106,204,248,119,222,153,126,227,79,72,108,120,22,148,3,27,112,205,31,65,242,70,1,144,199,188,154,128,196,230,251,71,229,237,168,8,88,82,115, -22,203,87,50,42,2,164,152,2,174,144,173,251,196,239,76,124,192,21,182,227,224,0,20,0,217,205,248,179,235,79,27,123,90,237,183,105,93,171,193,187,246,72,182,63,29,205,233,177,6,210,191,243,196,235,151,222,255,27,113,252,45,120,34,17,36,159,16,236,160, -244,188,9,234,224,134,81,121,187,211,26,46,135,37,35,137,129,96,84,4,68,21,40,105,243,47,90,116,107,215,127,243,34,246,8,64,1,144,165,212,205,40,158,52,251,154,214,251,20,73,229,52,205,200,69,159,108,242,83,229,110,128,43,153,231,31,24,149,253,87,122, -54,147,215,86,186,134,129,39,19,65,242,236,81,175,145,103,138,124,224,31,163,246,142,167,55,125,1,230,86,158,4,17,19,170,16,104,52,181,110,102,201,165,243,111,234,188,25,207,37,10,128,172,35,220,226,173,88,250,95,227,126,175,72,154,219,104,163,159,184, -26,133,98,103,37,49,254,255,149,246,82,191,143,8,128,125,235,146,37,127,216,222,23,65,242,14,142,19,65,233,95,51,170,239,121,110,203,117,48,163,108,137,41,29,3,105,203,224,142,147,170,239,162,81,86,60,155,40,0,178,6,79,137,195,190,244,142,113,15,88,157, -98,173,42,27,43,247,163,131,125,252,214,16,92,217,241,95,16,78,115,147,159,127,17,0,125,59,209,246,35,72,222,42,0,1,180,232,94,114,163,199,71,239,45,201,175,11,198,220,4,227,195,179,13,15,16,162,65,85,37,174,192,172,171,90,127,89,59,45,60,14,79,40,10, -128,140,35,218,4,56,230,150,206,31,135,154,188,179,104,194,138,17,232,72,95,135,232,130,43,58,238,128,10,119,221,168,127,22,45,62,128,222,63,130,228,111,8,0,52,37,6,154,26,31,213,183,21,121,11,92,218,254,85,24,19,24,103,120,148,48,141,174,106,170,230, -93,124,251,216,223,251,43,93,97,60,169,40,0,50,202,244,43,90,174,169,159,85,122,137,209,140,127,69,147,65,224,5,184,180,237,107,80,239,107,203,208,167,209,240,132,34,72,94,147,153,123,220,46,56,225,178,142,219,161,202,221,196,74,4,141,56,26,180,157,186, -195,103,109,60,225,238,137,247,219,125,86,172,85,70,1,144,25,218,79,168,58,102,226,185,13,223,137,15,38,140,169,90,77,37,2,64,129,243,90,110,128,142,162,204,53,190,226,44,46,20,1,8,146,207,182,159,120,227,92,134,58,123,122,173,1,184,162,243,14,8,217, -75,33,161,198,12,109,139,70,91,195,45,222,197,243,110,104,255,22,158,88,20,0,163,78,121,87,160,122,238,245,237,247,75,49,89,52,146,240,79,235,100,105,210,223,169,13,159,103,227,53,51,122,49,120,203,146,11,109,8,130,228,33,10,240,182,34,54,39,32,83,208, -225,101,151,117,222,14,78,209,5,178,102,44,106,26,31,146,96,204,146,138,235,39,158,223,112,54,158,91,20,0,163,134,221,103,177,46,188,181,251,126,209,46,148,170,178,49,131,73,19,99,22,85,157,206,134,105,100,26,33,220,8,156,128,125,255,17,36,47,3,0,170, -76,68,126,11,100,58,207,167,214,51,6,46,110,189,133,37,8,170,154,129,188,41,242,232,149,99,10,76,191,172,229,167,181,51,138,187,240,12,163,0,24,21,230,223,212,249,237,162,122,207,108,217,96,210,31,53,254,147,74,230,193,242,198,43,178,226,115,9,225,102, -224,61,165,0,170,140,39,25,65,242,12,142,19,64,44,154,146,21,251,210,21,154,198,166,8,74,106,194,80,183,64,86,114,205,129,103,209,215,186,255,215,87,225,244,226,89,70,1,144,86,38,95,220,116,86,203,162,138,171,227,195,198,194,87,49,37,202,198,250,94,56, -230,203,192,103,73,207,125,206,226,4,75,237,140,145,94,0,8,130,228,13,106,156,120,255,77,32,4,186,179,102,151,230,84,156,8,75,106,206,54,92,30,72,199,172,187,130,182,142,133,183,118,255,183,96,69,147,134,2,32,77,212,76,13,143,153,122,105,211,79,228,152, -108,40,87,142,214,250,135,236,37,240,185,246,91,89,217,95,54,97,105,59,22,120,103,32,57,12,8,65,144,188,64,83,37,176,86,47,39,79,252,236,106,167,127,74,253,165,48,181,228,24,195,34,32,17,145,161,122,74,232,220,105,159,111,190,2,207,54,10,0,211,113,248, -172,246,121,55,118,252,134,227,192,111,164,211,31,45,247,179,240,54,184,164,237,171,16,114,148,103,223,5,225,46,6,91,247,114,208,164,40,158,116,4,201,7,227,47,71,88,232,95,44,61,38,235,246,141,227,120,56,111,204,13,172,244,217,104,121,32,237,20,56,241, -220,134,239,54,206,45,29,143,103,29,5,128,169,204,187,169,227,174,96,141,123,178,28,215,223,233,143,174,117,209,102,63,103,53,95,13,77,254,236,205,89,177,118,156,8,150,186,233,160,37,134,241,196,35,72,46,163,38,88,230,191,173,245,186,172,29,239,77,163, -160,151,182,221,10,126,91,136,60,31,245,47,63,106,228,209,172,170,154,131,58,106,238,176,221,131,39,31,5,128,41,140,61,163,110,217,152,37,21,215,210,178,19,35,208,48,23,205,246,159,81,182,52,187,63,48,121,80,56,102,95,11,98,113,11,70,2,16,36,103,141, -191,196,66,254,246,206,175,2,239,172,202,234,93,45,113,86,194,69,173,95,102,17,1,218,23,69,47,52,31,192,93,108,239,88,112,115,231,247,104,231,67,4,5,128,33,194,77,222,138,105,159,111,254,169,20,53,150,25,79,141,255,216,240,76,56,185,225,115,57,241,185, -57,187,23,28,199,124,21,132,162,122,20,1,8,146,147,198,223,66,140,255,109,32,4,39,229,196,46,183,145,253,60,181,225,50,214,23,197,72,146,85,98,88,134,134,185,165,151,78,190,176,225,12,188,16,80,0,232,134,102,148,30,243,213,174,159,217,220,162,161,122, -255,132,26,135,82,87,53,92,48,230,6,16,184,220,233,92,201,187,195,224,90,244,31,40,2,16,36,23,141,127,215,109,32,134,167,231,212,174,31,83,117,26,204,42,59,206,112,82,160,20,145,105,197,214,143,75,90,125,181,120,65,160,0,208,197,140,43,199,92,85,214, -17,56,78,138,234,207,136,167,45,126,173,188,21,46,106,189,25,124,214,162,156,59,6,28,17,1,206,17,17,0,40,2,16,36,103,60,127,49,52,61,39,63,194,153,205,87,65,189,175,99,36,41,80,231,97,80,52,16,173,124,104,254,151,59,127,110,117,137,184,22,128,2,32,53, -106,166,134,59,198,159,89,127,23,45,47,209,143,198,122,94,159,214,120,5,171,249,207,217,139,100,36,18,192,99,36,0,65,114,195,248,135,167,231,236,199,160,131,131,104,62,128,219,226,3,89,211,255,252,165,142,91,121,87,112,225,244,203,91,174,197,139,3,5, -192,81,99,243,88,196,185,215,183,255,92,211,52,151,166,234,15,253,71,228,97,22,206,154,91,177,44,231,143,9,139,4,44,190,13,151,3,16,4,141,127,218,41,119,213,194,217,205,215,130,162,202,134,58,5,210,65,109,221,167,213,222,89,61,57,212,137,23,9,10,128, -163,130,40,198,175,20,213,123,166,201,113,253,161,127,234,249,215,122,91,224,140,230,47,230,207,197,226,10,97,78,0,130,160,241,31,21,104,155,244,99,170,78,53,148,15,144,156,109,166,57,169,67,103,115,91,44,120,177,124,20,156,252,242,49,106,167,134,39, -116,157,90,115,107,194,64,171,95,58,224,194,198,59,224,130,49,55,130,67,72,83,167,63,162,140,19,187,214,129,180,125,53,200,7,182,129,26,237,103,87,59,103,119,131,24,172,0,75,101,27,88,171,218,129,179,153,251,254,135,115,2,34,127,251,79,80,14,109,6,206, -226,192,139,6,65,242,214,248,107,160,36,54,130,28,95,3,138,180,13,52,181,47,89,112,207,59,129,23,75,65,180,182,128,104,107,3,142,79,79,217,253,41,13,159,135,173,3,239,195,198,254,85,96,211,57,197,144,246,110,9,53,122,167,78,251,124,243,77,207,127,239, -189,175,227,69,131,2,224,19,177,123,45,214,57,95,106,255,41,185,230,173,6,74,81,153,247,127,78,203,151,160,198,211,98,254,237,40,197,32,242,207,191,146,215,95,64,222,183,25,180,196,72,247,44,158,251,64,242,210,151,96,97,66,192,222,49,15,92,83,78,5,129, -124,111,90,36,96,36,39,96,24,69,0,130,100,222,248,119,165,33,225,79,75,64,124,248,41,136,15,61,193,4,128,166,142,68,252,56,254,67,174,181,198,122,134,240,98,9,88,157,51,193,238,57,133,124,95,97,234,110,88,120,43,156,63,230,6,248,214,91,87,177,164,64, -129,211,103,178,168,67,215,189,188,246,107,155,95,222,247,232,246,21,7,87,226,197,51,242,44,199,67,240,1,211,46,107,185,161,168,193,51,209,72,232,159,134,171,38,23,47,128,121,21,39,153,190,127,241,141,43,224,224,79,46,134,254,63,125,3,164,221,235,217, -205,72,61,126,206,238,2,206,234,76,190,136,199,207,126,102,177,129,210,183,7,134,158,253,21,28,248,201,133,48,244,226,253,73,229,110,114,36,0,171,3,16,36,195,158,191,201,198,95,138,189,1,3,123,175,132,225,131,119,19,239,121,45,115,48,56,222,149,124,113, -142,228,139,119,142,252,222,14,154,124,8,98,253,15,193,192,158,43,32,54,240,144,233,31,181,204,85,3,167,55,94,105,104,114,224,200,163,207,54,247,250,246,159,216,220,22,116,124,81,0,124,148,154,105,225,14,22,250,31,50,144,117,74,46,80,218,209,234,204, -230,171,77,223,191,225,127,60,0,61,247,93,3,210,222,13,71,12,252,103,118,186,18,44,192,57,60,160,69,135,96,224,175,223,133,158,255,185,30,212,225,94,115,35,1,139,147,213,1,40,2,16,36,3,198,223,228,176,127,172,255,127,96,104,223,205,32,19,175,63,105,224, -109,240,153,253,249,137,87,206,241,110,208,180,8,68,122,126,4,195,7,238,32,6,55,98,234,126,77,47,91,66,94,75,33,38,235,223,46,117,236,66,141,222,233,211,46,107,190,6,47,34,20,0,71,176,185,69,126,238,117,237,63,34,226,210,161,105,58,21,230,136,50,61,155, -92,91,94,107,192,212,253,27,122,238,62,232,255,203,221,204,224,115,22,123,234,27,16,68,38,4,98,171,159,131,67,191,186,10,148,190,189,230,69,2,92,88,29,128,32,249,96,252,35,189,63,38,175,159,177,176,62,245,236,83,39,41,4,226,195,127,131,161,3,255,65,4, -129,185,207,131,211,27,175,96,209,0,201,192,188,0,218,37,176,251,180,218,219,202,187,2,77,120,49,161,0,96,76,56,167,254,243,161,6,207,92,163,161,255,5,85,167,66,71,209,20,83,247,45,250,246,227,48,240,212,127,3,103,115,146,179,101,172,139,32,21,1,210, -206,53,208,243,155,235,76,21,1,180,58,192,137,213,1,8,146,211,198,63,214,255,32,51,224,70,205,2,77,8,148,162,175,66,228,208,247,76,221,71,218,23,224,236,150,107,128,35,251,167,129,190,229,76,90,214,77,252,40,207,236,107,218,126,32,88,208,252,21,252,17, -40,105,245,87,78,56,183,241,206,248,176,254,208,63,109,245,91,231,109,133,101,117,23,153,186,111,210,174,181,196,243,255,22,17,228,150,15,146,111,140,122,236,54,23,203,31,48,91,4,124,56,39,0,69,0,130,228,162,241,167,21,67,230,52,205,163,34,128,38,16, -198,6,30,52,117,95,219,2,19,89,187,224,168,129,165,0,41,166,64,197,216,224,210,73,23,52,158,131,2,160,144,63,188,192,193,140,47,180,124,75,180,241,69,122,27,254,208,201,85,34,39,178,208,191,222,50,149,79,220,110,164,31,250,254,112,59,168,241,8,11,225, -155,9,141,38,164,67,4,240,40,2,16,36,125,198,191,43,93,198,255,33,83,141,255,7,34,192,1,209,222,95,128,28,251,167,169,219,61,161,238,66,226,112,141,129,132,18,211,239,180,69,100,24,127,118,221,55,131,53,238,162,66,190,180,10,90,0,140,89,92,177,168,102, -106,248,108,35,237,126,227,74,4,22,215,156,5,13,190,118,83,247,173,255,145,187,153,145,214,181,230,159,37,34,0,19,3,17,196,68,207,223,228,108,255,72,207,97,207,223,105,186,241,79,66,151,44,85,86,77,160,42,251,77,219,170,77,176,195,89,205,87,131,200,91, -65,211,89,217,68,103,5,216,60,150,202,233,87,182,220,129,2,160,0,113,248,172,182,169,151,53,127,151,206,143,214,173,34,137,2,173,39,134,255,216,26,115,35,73,195,47,255,14,162,111,61,206,178,253,211,73,186,150,3,62,92,29,128,145,0,4,49,193,248,135,211, -96,252,7,30,76,139,231,255,209,135,140,21,20,101,15,68,14,125,151,252,70,49,109,179,141,190,78,88,88,181,28,162,138,254,165,0,234,248,53,205,43,187,188,97,78,233,100,20,0,5,198,228,139,27,175,241,87,186,58,244,10,0,170,60,69,114,115,158,217,116,21,107, -86,97,22,137,237,171,96,224,169,159,144,251,102,52,154,235,104,35,34,224,253,17,17,176,207,188,251,158,85,7,224,114,0,130,100,157,241,239,29,37,227,127,248,89,192,185,136,177,253,7,196,250,127,107,234,118,143,173,61,151,229,94,37,244,86,5,104,44,18,32, -204,184,162,229,123,22,135,80,144,182,176,32,63,116,73,171,175,186,235,148,154,175,36,12,36,254,81,229,73,179,254,205,12,253,171,209,65,232,123,248,191,64,147,227,134,51,254,83,19,1,238,17,17,112,173,201,213,1,97,156,29,128,32,217,102,252,251,71,207, -248,31,17,1,188,19,162,125,255,99,106,62,0,93,10,56,163,233,11,196,136,241,186,27,4,177,222,0,77,222,25,19,206,109,56,31,5,64,1,192,241,52,241,175,245,78,193,38,248,245,38,254,209,58,212,106,79,35,28,87,123,158,169,251,54,240,216,61,32,239,73,223,186, -255,103,71,2,176,58,0,65,50,138,150,127,198,255,3,83,163,193,240,161,239,131,166,244,153,182,213,102,127,55,204,173,92,102,104,96,16,29,27,60,246,244,218,59,189,165,142,64,161,93,110,5,39,0,26,231,150,206,172,153,26,58,71,210,153,248,167,141,104,205, -211,26,175,96,115,171,205,34,250,246,19,16,121,227,207,105,95,247,255,183,198,58,141,137,129,24,9,64,144,163,240,252,185,220,203,246,63,250,7,140,21,20,121,59,217,151,31,153,186,217,19,106,47,132,50,103,53,235,196,170,235,176,203,42,56,252,214,138,233, -87,180,220,140,2,32,143,161,235,60,228,36,127,83,77,168,186,63,55,109,69,57,189,116,49,116,4,205,203,27,81,14,237,132,254,199,190,7,156,104,201,220,205,153,102,17,128,179,3,16,228,51,140,127,206,102,251,167,240,28,224,92,16,31,250,59,36,134,30,55,109, -155,46,139,135,77,13,164,83,88,65,231,82,0,141,2,52,47,40,255,98,121,119,160,25,5,64,158,210,189,188,246,204,162,58,207,12,89,103,226,159,172,201,16,180,23,195,178,250,139,77,188,241,85,232,123,228,110,80,7,15,177,222,253,217,192,104,84,7,160,8,64,144, -79,48,254,185,154,237,159,202,243,133,183,178,150,195,170,188,211,180,109,78,40,158,3,227,195,179,33,166,232,123,174,208,229,96,222,202,59,103,92,57,166,160,198,5,23,140,0,240,20,219,93,19,207,107,184,67,138,25,24,246,163,196,217,186,127,192,22,54,109, -191,134,95,121,8,226,107,95,98,70,55,123,248,120,78,0,86,7,32,8,26,127,179,16,137,223,211,11,195,61,63,160,7,192,180,173,158,210,240,57,112,137,222,145,72,128,158,40,128,12,149,227,138,78,109,61,182,114,54,10,128,60,99,236,25,117,87,56,131,182,70,85, -214,23,34,138,43,49,150,112,50,171,252,56,211,246,73,222,187,17,6,159,254,217,40,149,252,233,21,1,35,213,1,253,230,86,7,56,23,225,0,33,4,141,127,190,148,250,165,236,8,112,78,144,34,175,65,108,240,143,166,109,179,196,89,5,139,170,79,39,207,106,157,207, -20,141,229,3,112,147,47,106,252,186,197,33,114,133,112,9,22,132,0,8,55,121,139,59,79,169,185,73,26,214,159,248,39,242,34,83,152,2,103,82,91,94,85,129,254,71,190,205,74,255,70,175,228,207,64,36,224,215,102,231,4,224,0,33,4,141,127,254,101,251,167,240, -12,224,237,16,237,187,15,20,105,171,105,219,164,115,2,170,60,77,186,19,2,233,242,112,81,189,103,102,235,146,138,83,80,0,228,9,19,47,104,184,222,238,17,195,170,206,178,63,154,248,55,181,116,17,52,249,187,76,219,39,22,250,223,184,34,57,229,47,203,193,217, -1,8,146,6,227,159,175,217,254,71,141,0,154,58,8,209,158,31,131,89,75,1,116,30,203,178,186,139,117,47,3,48,17,16,83,96,194,249,245,183,59,131,54,107,190,95,138,121,47,0,138,91,124,53,141,115,74,175,212,219,239,95,33,23,146,223,86,4,39,212,154,215,39,66, -62,176,21,6,159,190,55,75,67,255,153,19,1,152,24,136,20,138,241,119,164,35,219,191,55,123,178,253,143,250,185,194,57,33,17,125,29,226,131,143,152,182,205,113,225,153,208,77,142,109,76,103,155,96,69,82,33,88,227,233,24,119,70,221,121,249,126,57,230,189, -0,152,112,94,253,205,162,93,112,235,156,25,193,214,147,142,169,90,14,65,123,137,57,59,164,105,172,225,143,26,237,207,226,208,255,167,137,0,156,29,128,32,134,61,127,98,252,133,112,186,74,253,114,193,243,255,216,115,133,183,177,165,0,85,222,99,218,54,79, -172,191,136,69,3,84,157,15,254,68,68,130,246,101,85,183,184,66,25,108,204,130,2,192,24,165,29,254,230,198,185,165,23,208,236,78,61,208,117,164,42,119,3,204,175,60,217,188,27,245,173,71,33,182,246,197,44,203,250,63,106,245,130,213,1,8,98,208,248,23,78, -182,255,209,34,130,170,244,176,210,64,179,168,118,55,193,204,178,99,217,180,86,93,167,75,214,192,29,182,215,143,61,189,230,226,124,190,44,243,86,0,208,150,191,179,190,216,122,139,96,21,28,122,189,127,69,149,89,217,31,85,146,166,60,3,6,15,193,224,223, -126,10,156,152,203,75,75,31,171,14,192,217,1,8,146,57,227,223,155,235,198,255,240,243,218,73,188,238,231,64,138,188,104,218,54,151,214,158,205,74,182,21,77,167,3,24,85,160,253,196,234,47,17,33,224,65,1,144,99,212,78,15,183,85,140,15,158,165,215,251,167, -101,127,45,129,177,48,177,120,158,105,251,68,75,254,148,222,221,89,211,240,199,188,72,0,206,14,64,144,140,24,255,254,220,55,254,35,119,62,249,37,64,164,239,94,208,212,33,83,182,232,183,134,96,65,213,105,108,108,187,190,40,128,74,163,0,53,221,167,213, -92,142,2,32,151,62,20,241,254,39,158,219,240,101,98,167,172,122,58,67,210,178,63,158,227,224,248,218,243,201,87,115,14,81,98,203,91,16,249,231,35,57,26,250,255,148,91,22,103,7,32,200,103,27,255,130,207,246,63,218,7,138,21,148,196,22,136,13,252,206,180, -77,206,173,88,6,229,174,90,144,232,185,208,21,5,144,161,99,89,245,181,238,144,221,139,2,32,71,168,156,80,52,134,120,255,103,208,16,142,94,239,191,43,52,29,90,131,19,204,217,33,69,134,129,39,127,12,154,162,208,180,215,188,58,214,56,59,0,65,62,221,248, -99,182,127,138,247,61,249,76,177,129,63,130,34,109,50,101,123,14,209,5,139,170,207,0,89,247,160,32,13,92,97,123,121,247,233,53,23,162,0,200,17,218,79,172,186,142,227,56,155,158,127,171,129,10,86,222,10,199,214,156,107,218,254,12,191,241,103,72,108,121, -155,8,92,123,62,30,110,172,14,64,144,79,242,252,49,219,95,151,73,210,180,8,68,123,127,97,218,22,167,149,46,130,90,111,11,27,227,174,43,10,16,145,161,131,230,2,228,97,69,64,222,9,128,226,22,95,125,227,220,178,243,164,136,94,239,63,202,6,75,212,121,199, -152,243,44,24,234,129,161,231,238,3,206,98,131,252,229,99,57,1,253,88,29,128,160,241,199,108,127,157,247,60,235,13,240,10,36,76,74,8,20,137,67,183,184,250,44,80,84,125,54,65,85,88,20,160,166,123,121,237,57,40,0,178,156,9,231,214,95,101,177,243,14,77, -75,125,241,95,211,84,176,11,46,114,177,156,105,218,254,12,61,255,107,80,122,119,229,65,226,223,209,138,128,247,161,231,215,105,168,14,64,17,128,228,140,241,255,15,204,246,55,42,2,64,128,88,223,125,228,153,28,51,101,123,19,137,83,215,224,239,128,132,129, -40,0,141,44,187,66,246,188,242,228,242,74,0,148,140,241,149,53,206,45,189,80,111,215,191,152,26,133,201,37,243,161,210,221,96,202,254,208,97,63,195,43,254,148,87,137,127,41,69,2,204,204,9,112,97,117,0,146,205,151,254,135,61,255,25,230,27,255,254,194, -49,254,201,27,222,10,114,98,3,196,7,255,98,142,161,227,4,54,40,72,111,99,32,26,5,112,23,219,91,154,230,149,230,213,140,128,188,18,0,109,199,87,93,106,113,138,126,77,87,230,191,10,78,193,13,11,171,150,155,182,63,131,207,220,11,90,124,152,102,182,20,212, -179,16,103,7,32,5,231,249,115,233,44,245,123,168,176,140,255,225,231,8,111,135,216,192,239,65,83,14,154,178,189,113,161,153,208,232,107,215,29,5,144,227,10,116,157,86,123,157,197,33,228,205,3,61,111,62,136,167,212,225,105,94,88,246,121,73,175,247,47, -71,97,82,201,60,40,115,213,154,178,63,241,77,43,32,186,250,57,34,100,157,80,136,224,236,0,164,96,140,255,225,108,255,48,102,251,155,139,8,170,188,143,136,128,135,76,139,2,44,172,210,31,5,80,18,42,132,26,60,147,90,151,86,30,131,2,32,203,232,58,165,230, -44,87,200,94,73,67,53,169,123,255,26,216,69,39,204,175,52,41,186,67,46,176,193,103,126,193,190,230,91,217,95,106,34,192,149,214,62,1,60,138,0,36,11,140,63,102,251,167,51,10,224,132,216,224,99,160,72,219,77,217,222,216,176,177,40,128,34,171,208,122,92, -229,181,180,211,44,10,128,44,193,230,22,197,166,5,101,95,160,99,28,117,121,235,114,4,198,135,103,155,182,246,31,91,253,44,36,54,189,153,83,211,254,210,67,26,171,3,104,36,96,241,109,184,28,128,100,220,248,155,237,249,71,123,10,43,225,239,179,76,20,29, -25,28,27,248,95,83,182,38,112,2,235,14,168,119,92,176,18,87,160,172,195,191,176,110,70,113,55,10,128,44,161,97,110,233,194,96,173,187,139,142,113,212,227,253,91,5,59,185,40,78,53,199,228,201,9,24,124,254,55,57,55,233,47,253,34,224,112,117,128,121,34, -128,119,133,176,68,16,201,43,227,79,61,255,40,26,255,143,69,1,28,144,24,126,22,148,196,251,166,108,143,230,2,212,120,154,217,176,183,148,159,102,26,155,51,35,118,44,171,186,18,5,64,54,124,0,145,167,77,26,190,168,199,248,83,104,159,232,142,162,201,80, -235,105,49,71,189,175,124,10,164,29,239,229,121,221,191,145,72,192,181,88,29,128,228,240,165,140,131,125,50,19,5,136,67,180,255,183,166,108,77,36,231,111,94,197,73,32,235,109,15,28,81,160,122,114,248,140,112,179,183,20,5,64,134,169,158,84,212,81,62,46, -184,72,79,248,63,217,243,95,48,109,237,95,75,68,97,232,69,114,145,138,22,188,103,63,201,88,99,117,0,146,235,158,63,102,251,103,44,10,32,69,95,1,57,254,158,41,219,155,84,50,31,202,92,53,32,107,169,139,0,218,99,198,234,18,124,173,199,86,158,143,2,32,195, -180,29,87,117,9,167,129,168,75,201,17,85,217,228,235,132,150,192,56,115,188,255,183,31,7,121,207,250,28,31,247,155,251,34,0,19,3,145,180,24,127,204,246,207,228,147,131,24,94,217,180,92,0,58,226,125,86,217,177,32,41,122,27,3,41,48,102,113,197,37,206,128, -45,167,67,189,57,45,0,188,101,142,64,205,212,240,217,180,62,83,215,61,173,169,48,167,98,25,27,68,105,138,247,255,202,67,104,252,143,74,4,96,117,0,146,123,198,31,179,253,51,252,220,224,236,196,240,190,6,114,124,181,41,219,155,86,182,24,2,246,98,80,116, -36,4,178,198,64,97,91,115,227,252,210,69,40,0,50,68,243,194,242,83,156,1,107,177,158,210,63,58,29,170,210,93,15,99,77,186,161,233,218,191,188,103,3,0,10,128,163,145,75,31,36,6,178,234,0,147,167,8,98,117,0,146,6,227,143,189,253,179,32,10,0,178,105,125, -1,188,214,32,76,42,158,199,242,192,244,160,200,26,180,46,169,184,44,151,75,2,115,86,0,88,157,34,215,113,98,245,231,36,157,165,127,116,62,244,244,210,165,96,225,141,71,112,52,57,14,195,175,254,30,215,254,83,22,1,238,100,36,224,215,215,97,117,0,146,181, -198,223,129,9,127,89,20,5,112,128,20,121,21,228,248,26,83,182,55,171,252,120,54,50,152,118,130,77,217,137,140,43,80,210,30,56,166,172,35,208,132,2,96,148,41,31,27,156,228,175,118,77,214,147,253,79,107,64,3,182,16,76,41,53,167,161,19,173,251,151,118,173, -3,78,196,204,255,212,69,128,51,125,213,1,40,2,16,19,60,127,1,141,127,150,69,1,18,16,31,252,63,115,236,136,171,22,218,139,38,65,92,79,46,128,70,3,190,188,173,245,184,138,243,80,0,140,50,109,199,85,94,192,233,188,123,226,106,12,198,23,207,6,159,53,104, -194,131,66,129,225,87,254,128,117,255,70,110,233,116,37,6,162,8,64,12,26,255,180,101,251,115,104,252,245,71,1,236,144,136,188,2,138,180,217,156,40,64,217,113,196,16,234,59,23,82,84,134,250,89,37,231,56,131,182,156,236,250,150,147,2,192,87,238,244,87, -79,9,157,42,233,44,253,179,241,118,152,81,182,212,148,125,137,175,127,5,18,219,223,5,206,98,199,59,51,75,69,128,11,171,3,144,20,141,63,102,251,103,183,217,210,212,97,136,15,254,217,148,173,141,9,78,128,106,79,147,174,198,64,52,255,204,83,236,168,111, -154,95,186,0,5,192,40,209,188,176,252,56,103,192,86,162,169,169,39,255,209,178,143,38,127,23,212,152,212,248,103,248,213,63,224,253,104,154,8,72,211,40,97,172,14,64,82,244,252,49,219,63,203,159,21,196,137,75,12,63,79,12,176,241,220,33,145,19,97,106,233, -34,150,24,174,235,178,81,84,104,156,91,118,65,46,158,214,156,19,0,180,243,95,243,49,101,23,40,9,157,165,127,228,215,244,178,37,166,236,139,180,99,53,196,55,190,129,222,191,105,124,124,118,128,217,213,1,73,17,128,203,1,200,167,26,255,46,204,246,207,13, -4,98,120,123,32,62,248,184,41,91,155,88,60,15,252,182,176,174,25,1,82,92,129,242,238,192,226,226,102,95,5,10,128,52,19,110,242,54,6,235,61,179,229,68,234,201,127,138,38,67,177,163,2,186,138,166,153,227,253,191,254,48,171,0,40,228,137,127,105,21,1,191, -78,223,114,0,138,0,228,227,198,159,133,253,67,104,252,115,43,10,240,55,208,212,33,195,219,242,219,138,160,43,52,77,95,73,32,49,69,22,135,232,105,152,83,114,50,10,128,52,211,118,92,197,105,162,77,176,65,234,209,127,114,114,227,108,234,31,45,251,48,138, -210,187,27,98,107,94,64,239,63,109,34,192,153,182,229,0,108,27,140,252,139,231,143,217,254,57,136,8,138,180,19,18,145,231,77,217,218,212,210,133,32,240,22,246,252,73,21,57,161,208,165,233,179,45,14,33,167,78,116,78,9,0,139,83,224,107,166,21,159,174,196, -117,38,255,137,14,152,108,82,174,70,228,205,71,65,29,234,197,236,255,116,42,252,116,182,13,198,234,0,36,237,217,254,104,252,211,254,140,224,68,136,15,209,101,0,197,240,182,104,91,248,100,50,160,164,227,82,82,33,80,229,154,92,218,17,232,64,1,144,38,202, -58,2,227,253,149,206,110,85,78,61,252,79,147,255,26,188,237,80,237,54,222,179,65,75,68,32,250,206,83,56,241,47,151,69,128,11,103,7,160,241,79,119,182,63,26,255,244,63,32,172,160,196,215,130,28,91,105,252,153,192,9,48,177,120,174,174,100,64,58,38,152, -23,121,161,97,78,201,105,40,0,210,68,203,226,138,229,28,207,241,154,142,240,63,237,247,76,39,64,153,65,108,237,203,32,31,216,2,32,96,231,191,209,17,1,31,106,27,140,179,3,16,19,61,127,204,246,207,249,167,3,49,190,202,72,20,192,56,19,138,231,128,219,234, -103,115,98,82,118,50,99,10,237,9,112,138,221,103,21,115,229,232,229,140,0,112,6,108,150,186,233,197,39,233,25,251,75,51,59,253,182,16,116,135,204,73,254,139,188,249,87,154,129,130,247,222,168,241,161,182,193,105,154,29,128,213,1,133,103,252,205,246,252, -163,152,240,151,25,9,192,219,136,126,127,29,84,217,248,115,33,100,47,131,22,255,88,54,41,54,229,75,75,86,193,87,225,236,168,158,84,52,1,5,128,201,84,77,42,154,228,10,217,154,245,12,254,73,144,147,217,26,156,0,62,107,145,225,253,160,70,40,177,229,45,76, -254,203,136,8,72,87,117,64,8,171,3,10,200,248,59,210,52,216,39,138,198,63,67,208,146,192,62,72,68,158,53,101,107,180,36,80,211,147,101,206,174,49,128,134,57,165,57,83,13,144,51,2,160,97,46,57,168,58,207,9,29,247,75,215,118,76,81,249,239,60,1,90,60,130, -165,127,25,19,1,88,29,128,232,185,116,48,219,63,175,163,0,156,5,18,195,207,38,207,179,65,58,138,38,65,145,189,148,149,141,167,10,173,6,168,28,95,116,162,195,103,205,137,245,225,156,16,0,206,160,205,90,49,54,120,130,172,35,251,159,158,196,176,163,2,198, -4,198,25,127,134,196,135,33,250,222,115,152,252,151,233,155,29,171,3,144,84,61,127,14,179,253,243,251,161,96,37,198,119,19,72,241,119,140,219,27,209,3,109,193,137,250,90,3,203,26,184,139,237,173,85,147,67,227,81,0,152,68,121,87,96,130,59,108,111,209, -27,254,239,40,154,12,118,193,105,120,63,226,235,95,3,229,224,14,76,254,203,10,17,224,194,217,1,200,209,25,127,44,245,43,16,20,72,12,61,109,202,150,38,132,103,179,170,0,125,209,8,128,234,137,161,147,80,0,152,68,245,164,208,9,122,35,238,2,39,194,184,208, -12,115,110,248,119,158,196,251,60,107,208,62,90,29,208,143,179,3,16,52,254,5,237,20,112,54,144,98,111,128,166,244,24,222,22,157,23,19,118,148,235,91,6,136,171,80,49,46,120,172,197,46,100,125,147,152,172,23,0,22,135,40,84,79,13,31,75,15,106,202,39,66, -147,160,196,81,1,13,62,227,189,25,148,222,61,144,216,242,38,112,34,134,255,179,75,4,184,147,34,128,37,6,238,51,239,97,50,82,29,128,203,1,104,252,63,78,20,75,253,178,20,1,84,249,0,36,162,175,24,222,146,77,112,64,107,96,2,235,30,155,178,173,144,84,240, -87,187,218,203,58,3,237,40,0,12,82,49,54,216,230,175,116,117,208,131,154,42,146,146,128,214,224,68,176,10,198,51,246,99,107,158,199,206,127,89,45,2,232,114,192,181,166,87,7,124,52,49,16,31,246,185,100,252,49,219,191,16,195,0,2,155,18,104,6,99,195,51, -64,224,245,149,244,11,34,47,212,207,41,93,154,237,135,43,235,5,64,213,164,162,69,188,160,111,49,70,36,39,111,108,104,166,41,70,38,186,250,89,122,86,241,6,203,90,17,224,76,75,179,32,238,35,137,129,17,60,212,57,228,249,11,56,213,175,240,236,63,77,6,140, -191,71,188,240,237,134,183,69,91,3,211,101,0,89,213,87,13,80,222,21,56,150,207,242,209,0,89,45,0,232,232,223,202,241,69,75,21,41,245,236,127,26,254,15,179,240,127,155,225,253,144,246,110,4,105,231,90,224,68,43,222,97,217,124,243,167,49,49,16,171,3,114, -203,248,139,88,234,87,160,240,108,58,160,20,125,217,240,150,232,50,0,173,30,147,53,29,213,0,146,10,69,117,238,137,225,102,111,21,10,0,157,248,43,157,101,193,90,247,100,61,225,127,153,60,12,104,71,39,122,18,141,18,95,243,34,104,241,33,236,254,87,224,34, -192,133,34,32,235,141,191,163,11,19,254,48,10,32,130,20,161,121,0,154,225,109,209,209,241,156,142,115,78,219,213,91,156,162,179,122,114,104,46,10,0,157,84,77,10,205,180,185,45,30,29,109,153,217,73,235,44,154,98,194,131,69,129,216,218,23,1,4,244,254,115, -3,45,109,34,128,195,18,193,236,246,252,137,241,23,66,104,252,81,1,208,158,0,27,64,73,108,50,188,169,70,95,7,4,236,197,108,150,76,202,151,165,172,66,213,132,208,98,46,139,155,198,101,183,0,24,95,180,88,83,83,87,113,201,222,255,97,104,244,119,26,222,7, -105,207,122,242,218,128,225,255,156,20,1,135,115,2,176,58,32,239,141,63,13,251,135,48,219,31,73,186,127,154,58,76,52,186,241,106,0,151,197,11,13,190,118,93,77,129,228,132,10,225,22,239,44,103,145,205,153,173,71,42,107,5,128,221,107,181,148,118,6,102, -209,100,138,148,141,54,57,89,245,222,86,112,91,124,134,247,35,254,254,43,160,37,162,216,250,55,39,69,192,72,137,32,171,14,48,79,4,252,107,117,0,146,113,227,143,217,254,200,135,37,0,109,13,28,93,1,102,44,3,180,7,39,147,205,164,30,134,166,206,171,195,111, -173,14,55,123,187,81,0,164,72,81,131,167,205,85,100,109,212,211,253,143,142,114,164,173,28,141,219,16,21,98,239,255,3,64,196,206,127,185,29,9,48,191,68,144,195,182,193,121,109,252,49,225,47,215,21,128,21,148,196,70,80,164,173,134,55,213,226,239,6,151, -213,11,42,164,40,2,52,90,149,200,67,221,140,226,249,217,122,152,178,86,0,212,78,13,205,17,44,228,232,105,169,30,115,21,156,22,55,52,251,141,139,46,121,255,150,100,248,31,91,255,230,246,179,32,93,179,3,92,56,64,40,239,140,63,203,246,127,8,141,127,238, -223,245,35,203,0,43,12,111,41,228,40,131,10,87,61,75,44,79,253,82,85,161,180,221,63,143,23,179,243,90,202,74,1,64,147,237,203,199,6,231,41,178,158,236,127,25,202,156,53,80,226,50,94,125,17,223,176,2,180,24,102,255,231,135,8,112,165,109,128,208,225,234, -0,76,12,204,3,227,207,214,252,157,104,252,243,225,158,231,4,83,4,0,77,40,167,21,101,138,142,126,0,106,178,43,224,120,111,137,163,40,27,143,81,86,90,54,87,145,221,21,172,117,79,84,117,150,255,209,228,63,222,132,143,22,219,240,10,118,254,203,27,210,95, -29,128,179,3,70,201,248,99,169,31,114,84,55,38,93,6,216,0,170,98,60,255,135,246,3,16,121,11,164,154,83,160,170,26,216,61,150,64,73,155,127,98,54,30,162,172,20,0,197,45,222,46,71,192,86,169,103,253,159,78,112,106,13,24,159,196,168,14,236,7,105,231,58, -204,254,207,75,17,144,190,234,0,30,151,3,210,111,252,49,219,31,57,74,243,166,42,125,32,199,86,26,222,82,181,167,9,2,182,176,174,114,64,26,65,40,31,27,156,141,2,224,40,33,7,107,58,207,167,126,35,210,242,63,159,53,8,53,158,102,195,251,16,223,186,18,212, -161,30,140,0,228,165,8,248,208,236,128,126,115,171,3,176,89,80,250,140,191,35,13,165,126,152,237,159,255,72,209,55,12,111,195,33,186,153,93,145,116,228,1,208,78,182,165,237,254,153,217,216,22,56,235,4,0,173,182,43,235,12,204,212,53,252,71,147,160,210, -93,15,94,34,2,140,146,216,104,78,9,9,146,205,145,0,34,2,126,125,173,233,203,1,88,29,96,230,169,250,80,147,31,204,246,71,82,189,31,249,228,108,0,77,51,126,47,54,5,186,200,118,82,183,75,138,172,65,160,218,213,233,41,115,134,80,0,124,6,174,34,187,35,88, -235,30,175,103,253,95,85,21,168,247,25,159,192,168,201,113,136,111,91,137,221,255,242,94,4,96,117,64,214,123,254,92,122,154,252,96,182,127,161,64,71,4,239,99,185,0,70,105,244,117,130,77,176,147,39,71,106,142,33,237,7,96,243,88,2,165,109,190,172,235,7, -144,117,2,192,95,237,106,177,123,45,149,122,218,255,210,233,127,180,117,163,81,228,125,155,65,233,217,9,28,78,255,203,127,15,33,93,34,192,141,34,192,176,241,199,108,127,196,248,29,78,188,246,4,200,177,119,12,111,169,220,89,3,65,123,9,168,154,172,103, -55,104,100,123,42,10,128,207,58,200,221,129,137,188,149,231,83,85,89,116,253,159,134,254,171,220,141,134,247,33,177,229,109,208,226,216,253,175,112,68,128,43,45,163,132,89,137,32,206,14,200,82,227,143,158,127,225,220,224,2,72,38,36,2,90,137,247,95,229, -110,208,53,30,88,149,53,218,220,14,5,192,103,17,110,242,77,213,145,104,201,198,255,150,187,106,193,99,245,27,222,135,248,230,183,200,145,193,218,255,194,225,195,109,131,175,51,53,49,240,112,199,64,172,14,64,227,143,100,200,254,115,22,80,164,205,160,41, -135,12,111,139,206,5,80,117,132,167,217,120,224,122,79,151,51,104,115,100,211,177,201,42,43,103,177,139,92,168,201,51,94,79,2,160,162,42,80,235,29,99,220,20,196,134,216,0,32,14,215,255,11,87,4,252,218,236,234,0,28,37,156,138,241,119,164,171,189,47,26, -255,2,69,0,85,233,5,57,177,209,240,150,106,189,173,96,101,182,33,245,126,0,14,175,165,50,80,237,106,66,1,240,41,120,203,29,101,158,98,123,147,166,163,254,95,224,4,54,0,200,40,210,222,141,172,7,0,8,88,254,87,152,34,32,141,213,1,152,19,240,111,14,61,102, -251,35,233,188,190,20,144,227,171,12,111,166,204,85,3,94,107,81,234,253,0,136,73,19,108,60,95,222,21,28,139,2,224,83,40,170,247,180,91,156,162,59,213,17,192,52,36,227,180,120,160,210,221,96,120,31,18,219,87,145,103,81,28,31,20,5,12,38,6,102,192,243,199, -108,127,36,173,55,181,192,202,1,141,226,18,61,80,230,172,214,151,7,160,2,132,154,188,89,213,17,48,171,4,64,184,217,59,78,207,61,170,104,50,132,236,165,172,83,147,25,2,0,123,255,35,40,2,70,209,248,167,189,189,47,102,251,23,252,253,204,242,0,182,129,166, -244,26,222,86,181,167,153,37,157,167,126,169,107,16,172,115,143,203,166,193,64,89,101,233,66,141,222,241,122,194,255,84,0,84,184,235,89,27,96,35,104,137,40,200,123,55,0,135,227,127,17,72,115,117,192,71,6,8,21,168,113,74,99,123,95,76,248,67,62,138,64, -140,127,31,75,6,52,74,173,183,133,216,154,212,77,167,42,171,224,45,177,183,184,195,14,127,182,28,149,172,17,0,22,135,40,4,170,93,109,84,37,165,108,184,53,13,106,60,198,115,43,228,131,219,65,233,223,79,142,10,214,255,35,236,202,250,88,117,128,217,29,3, -15,207,14,136,20,174,241,239,68,227,143,140,210,221,172,73,32,199,215,26,222,78,185,171,14,28,162,139,141,158,79,233,253,85,13,172,94,107,40,80,227,170,71,1,240,49,124,229,206,18,87,216,86,167,103,0,144,69,176,66,149,219,184,0,144,118,175,99,81,0,172, -255,71,254,85,4,208,196,64,115,69,64,193,206,14,192,108,127,36,19,16,175,93,78,188,111,120,51,69,246,18,240,219,66,186,6,3,9,2,199,133,155,189,29,217,114,72,178,71,0,84,58,27,89,2,160,150,122,3,32,183,197,7,197,206,74,227,2,96,231,90,188,73,144,79,17, -1,174,15,68,0,86,7,24,56,148,152,237,143,100,200,254,131,8,138,180,149,214,122,27,218,142,133,183,66,169,179,26,20,29,137,128,212,190,249,43,93,89,211,18,56,107,4,64,176,222,221,206,235,240,188,169,10,11,218,74,192,99,49,186,172,162,177,250,127,12,255, -35,159,46,2,48,49,208,176,231,159,174,108,255,30,204,246,71,62,75,1,136,160,202,7,64,145,247,24,222,20,29,58,167,171,33,144,172,65,168,193,211,158,45,147,1,179,70,0,20,55,123,59,85,85,95,2,96,153,171,90,87,82,198,71,78,204,96,15,40,61,187,176,255,63, -242,239,159,33,163,32,2,242,178,109,112,186,179,253,7,48,219,31,249,236,24,128,166,69,64,73,24,79,4,76,38,157,235,75,4,244,148,58,26,109,30,139,13,5,192,225,157,16,121,240,150,58,199,168,74,234,138,138,134,84,104,82,134,81,104,2,160,58,220,135,45,128, -145,163,16,1,31,174,14,48,177,99,224,200,236,0,62,223,68,64,58,179,253,113,205,31,73,205,96,152,50,25,144,46,1,216,4,135,222,201,128,21,222,50,71,25,10,128,17,236,30,139,195,83,98,175,211,100,29,29,0,121,129,8,128,26,227,2,96,223,70,208,228,4,62,68,144, -163,185,141,63,36,2,174,53,183,58,32,223,102,7,28,78,248,75,87,169,31,174,249,35,41,221,96,66,50,15,192,32,65,91,49,120,172,129,148,251,1,208,20,55,209,46,216,189,229,206,172,168,4,200,10,1,224,173,112,148,217,188,150,178,84,59,0,210,50,12,187,224,132, -98,71,133,225,125,144,246,108,196,236,127,36,197,72,192,135,171,3,112,118,192,167,26,255,206,219,64,192,82,63,36,27,238,89,160,2,96,39,49,196,198,18,1,105,25,32,173,6,208,83,9,192,243,28,109,8,212,130,2,96,4,103,192,86,43,88,4,91,138,5,0,44,9,195,75, -84,24,45,201,48,44,0,14,108,33,71,3,251,255,35,122,34,1,233,153,29,224,202,229,196,192,116,103,251,163,241,71,116,70,0,52,181,7,52,249,128,225,77,81,199,83,85,83,23,0,212,209,45,170,243,160,0,56,76,81,189,167,81,79,86,36,157,0,24,176,21,179,181,24,67, -207,170,216,32,40,189,123,201,3,5,19,0,17,61,34,32,61,137,129,92,174,86,7,96,182,63,146,181,240,196,104,71,64,145,119,26,222,18,77,62,79,53,7,224,176,0,32,78,111,19,199,115,89,112,52,178,128,96,173,187,89,211,81,1,160,130,98,74,248,95,38,15,109,117,184, -23,35,0,136,126,99,141,213,1,31,24,255,195,29,254,48,219,31,201,74,205,174,176,185,0,198,35,0,149,108,10,109,202,142,43,109,9,92,225,168,177,56,50,63,114,54,43,4,128,43,100,111,72,181,1,16,59,143,228,223,148,152,208,0,72,57,180,19,59,0,34,38,136,128, -52,206,14,200,133,234,128,81,25,236,131,158,63,98,244,70,229,76,17,0,33,71,41,88,5,123,234,149,0,228,175,91,157,98,153,35,96,11,20,180,0,96,109,127,45,192,249,42,156,213,84,21,165,188,243,28,15,97,71,185,241,8,192,193,237,116,103,240,198,64,140,186,22, -31,21,1,38,38,6,102,125,117,0,14,246,65,114,6,1,84,121,183,225,173,248,172,69,224,178,120,82,175,4,160,165,128,110,209,239,10,217,202,51,125,36,50,27,1,208,232,51,131,115,139,54,190,44,213,165,20,170,186,44,188,13,130,246,18,227,2,224,192,118,244,254, -17,19,35,1,238,15,37,6,154,91,29,64,7,8,101,93,78,0,14,246,65,114,233,254,100,2,224,0,107,10,100,4,151,197,11,94,107,48,245,142,128,26,235,125,195,23,213,186,43,51,125,44,50,27,1,32,94,191,175,194,81,108,247,91,131,169,14,1,210,200,65,119,90,220,224, -183,21,25,222,15,165,119,23,174,255,35,105,136,4,172,79,246,9,232,51,121,128,80,54,37,6,166,115,205,31,179,253,145,180,40,0,158,120,225,253,160,201,61,6,133,4,7,1,91,56,229,8,0,251,183,196,225,180,121,44,181,5,31,1,160,107,33,60,207,165,220,22,81,37, -191,220,68,129,185,68,175,177,93,72,68,65,25,56,128,2,0,73,131,8,200,243,234,128,116,27,127,108,242,131,164,41,6,160,169,81,80,149,253,134,183,68,123,1,232,201,95,83,201,191,41,106,240,212,100,250,72,100,84,0,40,10,29,140,224,174,20,44,60,164,186,4,64, -235,47,233,26,140,72,30,64,134,158,97,195,189,236,197,113,40,0,144,52,60,106,142,68,2,242,108,128,208,168,100,251,163,241,71,210,36,0,52,25,20,217,248,253,88,100,47,213,85,10,72,255,137,205,37,86,23,180,0,160,203,238,54,183,69,215,58,8,141,0,208,240, -139,97,17,50,112,16,180,120,148,102,20,226,125,129,164,41,18,144,198,234,128,197,25,40,17,196,176,63,146,243,168,166,36,2,210,62,52,122,135,2,249,171,93,44,9,80,79,9,124,206,11,0,26,53,161,205,127,138,26,61,149,122,166,0,210,176,75,192,94,108,92,0,244, -239,3,77,193,25,0,72,186,69,128,59,61,213,1,174,207,168,14,208,49,178,244,35,110,202,199,189,27,244,252,145,188,8,2,240,196,8,27,95,2,240,219,67,44,10,173,165,158,197,78,19,1,75,129,214,193,21,106,4,96,228,64,232,238,228,19,48,161,5,48,243,200,84,21, -111,8,100,148,68,64,122,170,3,92,135,171,3,18,31,202,108,150,19,192,123,74,245,63,35,29,149,44,99,26,14,39,57,169,137,35,189,253,177,206,31,201,109,136,0,80,140,183,3,246,90,252,96,163,189,0,82,204,3,208,20,218,13,208,26,180,20,129,71,149,11,50,2,64, -199,34,90,193,95,229,42,81,83,238,1,160,129,192,139,44,7,192,120,4,96,63,150,0,34,163,40,2,210,83,29,192,141,84,7,136,101,29,201,72,0,121,137,85,19,193,218,113,162,238,109,10,254,54,176,212,158,149,20,0,242,48,112,86,31,246,246,71,242,35,0,64,132,173, -166,244,209,44,112,67,219,161,125,0,232,96,32,58,152,46,85,251,39,216,120,15,103,129,160,158,36,66,179,200,92,243,123,141,206,101,224,4,209,46,132,116,68,79,64,224,68,86,131,105,120,55,162,3,248,208,65,70,89,4,124,80,29,16,188,224,251,196,208,150,154, -178,101,90,29,224,58,246,235,32,239,89,197,68,173,88,218,65,110,20,35,17,70,14,108,77,151,131,165,100,30,168,177,125,32,248,218,200,190,135,76,61,26,81,204,246,71,50,36,1,52,45,78,94,18,185,85,172,186,183,66,167,209,58,69,15,244,196,14,64,170,227,108, -104,245,27,141,2,104,25,12,64,103,46,2,160,106,96,247,138,46,139,67,8,164,60,6,152,40,38,171,96,99,101,128,8,146,147,143,159,52,149,8,82,131,47,86,142,7,177,98,156,65,227,255,161,135,132,183,5,196,226,217,166,27,127,26,246,143,162,241,71,114,24,158,19, -192,101,241,233,106,7,44,88,5,26,1,47,214,148,2,92,2,160,141,127,220,97,187,207,225,183,186,83,22,0,228,151,93,112,128,67,116,26,127,16,59,168,136,192,28,0,36,19,34,32,61,213,1,185,0,174,249,35,153,69,35,158,191,205,144,247,127,24,15,17,0,122,154,1,81, -205,160,72,106,56,147,71,33,179,125,0,36,213,71,140,127,202,86,156,118,1,164,161,23,155,224,50,188,15,98,168,10,64,195,219,1,201,208,67,40,77,213,1,104,252,17,228,223,221,121,10,240,98,152,141,173,54,44,0,172,126,0,157,189,0,124,101,142,112,38,199,2, -103,116,9,192,87,238,244,11,34,207,167,126,220,52,112,90,60,134,155,0,81,44,21,173,228,26,176,3,170,0,36,179,34,192,252,234,128,172,52,254,152,240,135,100,197,109,167,128,96,29,99,202,166,220,116,9,64,143,253,39,255,200,87,225,12,101,242,54,200,168,0, -240,148,56,130,188,133,75,249,224,209,225,11,14,209,109,202,113,179,150,183,128,24,174,1,144,37,188,41,144,12,138,128,244,84,7,100,157,241,199,53,127,36,27,238,55,222,10,22,199,20,147,4,128,254,92,52,69,82,139,50,233,123,102,122,9,32,160,47,114,162,130, -139,8,0,83,16,173,224,24,187,24,52,41,142,247,5,146,97,17,144,166,196,192,44,0,179,253,145,172,185,211,180,56,121,236,183,129,104,51,39,2,224,20,189,186,186,1,82,39,216,225,183,6,5,107,230,204,112,70,5,128,213,37,250,117,31,116,139,199,180,253,112,78, -58,9,132,162,10,162,72,18,120,119,32,25,37,31,69,0,245,252,49,219,31,201,22,161,77,95,118,223,25,228,171,57,243,95,92,22,247,136,0,72,205,155,165,137,240,222,114,151,215,234,204,220,28,154,140,9,0,154,248,16,106,242,250,245,212,64,210,181,19,167,224, -54,239,32,184,2,224,57,230,50,208,164,4,96,46,0,146,121,17,144,63,213,1,216,222,23,201,42,243,175,14,131,213,57,15,44,142,153,166,109,147,46,71,211,114,64,77,215,254,104,30,173,80,151,0,8,58,23,79,136,130,51,161,4,240,35,81,128,137,39,130,115,242,201, -160,70,7,241,46,65,50,238,165,164,107,138,224,104,126,134,40,102,251,35,217,35,171,137,227,24,5,193,82,7,174,224,85,166,110,153,182,2,166,141,233,244,56,143,196,248,187,105,83,192,66,21,0,250,226,248,28,199,218,47,154,141,111,217,151,193,209,185,16,212, -200,0,128,134,145,0,36,11,34,1,187,214,65,239,131,183,130,150,136,230,212,190,71,251,239,39,175,223,161,241,71,178,198,243,23,196,82,112,23,255,39,112,66,145,169,219,166,77,233,216,64,160,84,59,218,146,191,111,113,8,46,171,83,176,102,234,184,100,78,0, -104,201,240,135,190,157,230,137,234,114,154,190,75,156,197,6,129,179,190,14,174,105,167,177,161,42,154,140,57,1,72,134,35,1,118,55,36,182,188,5,137,109,239,228,208,110,199,32,49,244,4,209,233,14,52,254,72,134,81,137,157,25,4,209,214,66,140,255,221,44, -2,96,54,22,142,8,0,78,76,189,27,160,162,129,171,200,106,245,20,59,108,5,39,0,44,78,1,188,101,14,151,170,163,13,34,71,123,148,11,233,57,102,84,4,248,79,253,26,4,206,184,19,196,64,25,121,150,13,38,43,4,52,236,22,136,100,44,22,192,198,151,230,142,108,249, -215,239,16,100,116,189,75,137,60,178,135,128,142,187,113,248,206,5,79,201,61,196,248,215,164,199,150,17,91,36,232,236,73,67,103,226,105,154,102,207,212,145,202,216,48,32,209,198,131,51,96,179,15,12,105,41,202,16,218,194,145,7,171,144,222,99,230,24,127, -44,216,90,103,66,244,237,199,33,250,206,147,32,237,221,4,90,124,56,25,183,97,211,3,209,179,65,70,225,81,38,199,193,222,50,29,172,53,221,185,35,87,56,59,216,220,75,33,210,251,19,250,1,112,218,38,50,74,70,95,27,185,254,172,192,139,101,196,201,156,70,174, -195,99,211,226,245,127,196,150,113,22,22,1,208,41,120,173,35,175,194,18,0,90,114,9,192,161,239,1,195,129,133,79,127,212,132,119,120,193,53,253,76,112,77,59,3,228,125,155,32,177,123,29,200,251,183,130,58,116,136,60,215,254,63,123,231,1,47,71,89,245,255, -179,51,179,237,246,126,211,147,155,222,72,2,161,6,233,72,145,162,2,214,191,149,87,254,250,250,250,170,20,11,254,241,125,21,21,21,20,17,20,72,40,210,91,66,73,40,161,164,87,82,110,239,189,238,189,119,123,239,51,187,255,231,121,54,137,160,160,185,179,51, -91,207,55,159,225,134,36,187,59,59,237,252,206,121,78,17,81,3,32,234,18,139,129,80,49,19,10,63,241,229,99,221,42,179,7,67,233,87,217,90,171,24,106,252,123,20,3,65,212,50,254,196,139,212,240,37,204,240,11,186,69,192,147,45,177,4,165,62,188,134,7,45,175, -99,213,105,50,46,115,33,47,5,192,241,99,39,231,84,211,37,0,65,163,77,221,94,178,209,170,11,217,134,32,200,73,221,52,196,251,186,138,109,8,146,211,87,58,177,15,84,4,36,97,131,243,48,9,48,241,217,178,82,249,105,205,165,192,9,120,229,33,8,130,32,105,37, -97,143,244,172,67,173,28,39,56,30,139,167,205,152,165,59,179,72,70,92,48,206,170,0,18,107,46,8,130,32,8,146,165,226,129,215,128,177,52,125,189,128,185,108,61,112,113,204,48,70,16,4,65,210,238,197,106,64,199,233,166,94,6,24,143,131,96,224,161,108,78,81, -81,186,246,61,157,2,128,186,240,83,95,2,160,69,3,26,14,120,92,2,64,16,4,65,50,65,4,208,50,93,89,189,128,19,67,129,242,81,0,208,240,191,172,36,64,186,230,194,167,50,9,16,65,16,4,65,114,140,116,47,1,196,211,242,82,4,65,16,4,65,1,128,32,8,130,32,8,10,0, -4,65,16,4,65,80,0,100,34,52,219,50,142,189,249,17,4,65,16,36,43,5,128,72,182,192,84,95,68,219,138,75,49,17,162,49,156,212,135,32,8,130,100,49,26,214,11,32,109,125,178,211,41,0,104,22,159,132,87,0,130,32,8,146,173,208,136,116,68,10,179,150,192,83,118, -102,163,49,240,89,67,193,124,20,0,199,244,143,188,3,142,141,128,16,4,65,144,76,17,1,114,204,159,20,142,129,103,60,16,206,215,8,128,95,214,65,139,139,16,149,162,120,213,33,8,130,32,233,53,254,241,56,196,226,146,60,127,86,3,113,13,159,190,73,153,233,108, -167,151,212,18,128,20,79,253,234,129,100,182,129,52,97,134,152,211,13,241,96,16,175,124,68,237,39,11,8,179,103,130,118,213,178,172,220,125,79,32,2,102,103,128,60,28,227,56,12,24,81,213,144,240,28,7,6,29,15,69,6,45,20,23,232,200,255,167,238,138,163,198, -95,140,69,88,75,96,25,80,79,54,148,127,2,64,195,198,40,6,101,188,140,28,240,24,68,98,169,49,192,226,192,8,132,182,237,133,240,251,13,32,142,154,32,230,245,147,83,134,209,7,36,53,2,0,200,131,173,232,107,55,64,241,247,255,35,171,118,125,216,236,133,109, -77,228,222,137,72,104,252,145,212,152,20,141,6,116,2,7,133,70,45,76,47,47,132,5,51,74,97,86,149,250,109,246,99,228,151,24,139,78,57,7,224,184,95,9,137,132,248,252,18,0,113,49,14,209,144,20,158,250,49,211,176,7,163,218,85,0,212,211,247,61,250,60,4,223, -219,3,113,143,15,200,149,5,26,65,75,54,30,64,139,115,8,144,20,33,73,224,123,246,85,48,92,118,1,104,151,46,204,138,93,142,197,226,112,184,103,18,194,196,248,211,7,50,130,164,236,118,33,215,158,203,23,6,187,39,4,29,163,14,152,81,81,8,107,23,214,192,172, -234,34,21,63,83,100,2,64,38,212,144,165,45,7,32,109,150,44,236,19,193,49,236,11,112,117,220,148,23,2,168,226,138,72,234,69,77,168,199,239,249,195,195,32,77,90,65,83,104,4,77,113,33,222,89,72,122,224,137,224,12,133,137,32,181,100,141,0,16,165,24,4,194, -98,74,195,176,8,146,136,2,144,91,134,252,231,248,181,103,178,251,96,194,225,135,85,117,85,112,246,178,105,192,169,80,113,71,157,81,49,46,130,156,28,0,13,167,9,211,45,93,199,43,221,242,220,39,43,122,64,4,64,72,82,103,9,192,255,236,43,224,188,253,183,32, -57,221,9,195,207,161,7,131,164,143,120,56,2,124,117,37,232,86,44,206,154,125,214,106,121,168,45,43,128,168,132,205,186,144,52,95,139,60,199,140,126,67,159,5,222,173,31,97,226,84,121,1,16,78,44,1,76,81,0,16,195,15,33,79,52,18,116,69,210,150,3,144,110, -235,230,145,245,80,140,199,33,44,6,20,223,153,192,150,119,192,243,199,13,160,209,10,160,209,225,180,65,36,205,198,63,74,30,42,122,29,148,222,241,67,224,106,170,178,199,11,35,219,39,86,204,128,26,42,2,68,20,1,72,250,163,2,122,34,74,251,198,93,176,179, -121,140,165,214,40,9,141,70,211,101,128,169,6,23,232,4,225,16,49,254,1,71,56,109,93,237,210,42,0,56,94,227,145,121,74,33,40,249,21,221,151,104,103,47,120,239,121,152,60,112,181,137,176,43,130,164,19,106,252,181,90,40,191,235,167,160,63,239,204,172,219, -253,34,163,22,62,117,198,60,168,42,53,160,8,64,50,2,42,2,186,199,156,208,216,111,85,244,125,195,82,24,196,120,20,100,46,1,120,201,150,182,36,192,244,9,0,162,194,156,35,126,183,220,37,153,128,168,160,0,16,37,240,222,187,1,98,129,32,128,128,9,126,72,250, -141,63,156,48,254,103,101,237,215,72,136,128,58,34,2,140,40,2,144,140,64,43,240,208,208,107,6,135,87,185,168,123,136,56,163,180,44,93,142,41,99,2,64,147,190,174,118,105,19,0,52,140,239,183,132,220,178,122,39,144,35,22,136,122,149,59,129,59,247,67,184, -190,5,52,5,70,188,67,144,12,242,252,207,202,250,175,243,247,72,128,17,115,2,144,180,67,115,3,195,68,140,54,244,41,23,5,8,136,190,99,195,233,166,158,3,16,116,134,189,98,36,125,247,69,122,151,0,180,156,67,206,235,104,178,5,61,232,10,41,17,8,188,178,21, -147,253,144,140,241,252,203,114,196,248,255,147,8,40,193,72,0,146,1,81,0,158,131,97,139,135,53,170,82,2,191,232,133,152,140,158,118,28,175,1,207,68,192,25,13,164,111,36,78,218,172,30,245,226,195,222,168,51,30,139,203,120,45,167,152,0,144,70,199,33,218, -209,195,146,173,16,36,221,198,191,60,199,140,255,71,70,2,80,4,32,105,132,46,59,135,194,34,17,1,202,68,145,253,17,183,236,196,66,34,2,236,233,236,148,149,62,1,64,212,143,125,208,227,20,35,177,248,84,243,0,56,22,1,240,42,210,14,56,210,218,5,49,175,15,35, -0,72,218,136,231,184,241,71,17,128,100,158,8,208,192,132,93,25,39,210,23,245,200,126,173,20,141,217,210,121,28,210,92,5,192,121,104,32,64,78,4,32,40,250,33,162,64,47,0,113,104,4,20,175,11,65,144,41,120,254,154,60,48,254,255,44,2,176,58,0,73,163,237,225, -52,224,14,68,88,46,90,178,120,163,46,89,109,128,105,14,128,185,203,99,139,75,233,179,63,233,139,0,112,108,9,192,21,9,74,126,205,20,59,134,209,28,128,48,49,254,74,84,2,196,236,46,244,254,145,180,25,127,200,35,227,255,97,17,128,213,1,72,26,35,0,100,139, -68,37,69,18,83,189,17,34,0,228,152,210,132,217,179,228,101,4,128,38,64,120,205,33,111,208,21,117,77,89,0,104,184,99,2,32,249,16,78,92,20,241,110,64,114,202,248,139,225,40,217,148,187,174,105,154,142,39,172,236,125,130,213,1,72,46,64,35,8,190,168,27,56, -205,212,77,105,140,136,95,191,61,108,213,164,209,255,76,107,209,187,134,215,68,136,16,160,107,32,11,166,42,156,162,49,145,40,47,103,242,66,196,104,196,37,0,36,103,140,127,203,198,195,208,183,179,147,37,58,45,184,112,25,156,114,253,25,160,73,162,39,255, -246,126,59,220,187,119,16,108,129,8,172,153,94,2,191,252,228,34,152,86,164,87,84,4,188,117,100,8,108,238,32,104,113,112,16,146,74,39,148,220,36,154,36,103,3,68,98,33,86,5,48,85,1,64,63,86,138,198,36,247,88,192,78,243,225,242,46,2,64,31,74,17,111,20,220, -99,126,171,70,152,234,1,208,128,20,23,193,29,177,39,127,0,170,42,80,0,32,105,48,254,183,43,110,252,143,252,109,15,52,60,115,0,2,54,47,248,173,94,168,127,106,31,244,19,49,32,151,17,87,8,126,248,122,39,52,79,122,193,30,136,194,150,78,11,124,125,99,11,140, -123,148,155,93,130,37,130,72,58,160,81,45,189,78,96,37,129,201,224,143,122,89,62,154,70,70,42,127,60,30,247,145,87,57,210,121,28,210,42,185,165,72,12,162,1,113,92,142,10,163,161,23,103,56,249,4,74,126,90,53,128,6,167,150,33,234,243,225,108,127,101,219, -251,82,227,223,190,185,1,116,133,122,224,180,252,137,109,162,117,84,246,123,54,78,120,192,17,140,64,145,142,7,129,8,246,50,131,0,237,102,31,124,115,19,17,1,94,133,69,192,153,243,160,18,115,2,144,84,221,139,228,87,161,33,249,0,56,173,0,8,75,1,182,44,61, -37,195,43,112,224,183,69,92,17,43,184,120,109,250,204,112,26,251,0,80,21,22,7,247,120,208,36,43,131,146,188,198,25,74,62,127,130,9,0,173,0,128,65,0,68,101,207,95,173,108,255,19,198,191,64,247,225,102,100,52,196,153,68,145,177,72,220,164,15,142,79,165, -183,8,21,3,237,22,34,2,88,36,64,185,118,170,84,4,92,133,213,1,72,170,4,0,177,61,244,154,75,22,26,133,142,178,73,128,50,246,33,22,55,199,99,16,74,231,113,72,107,4,128,118,79,244,219,66,163,26,89,9,148,156,34,17,0,174,186,10,52,6,67,98,103,16,68,37,227, -15,170,25,255,189,208,190,165,145,24,127,253,71,71,178,146,8,110,125,220,75,139,143,139,128,151,91,85,88,14,192,234,0,36,37,46,40,148,24,147,111,254,230,12,91,217,36,192,169,222,104,52,2,224,26,241,79,178,61,225,242,48,7,32,241,197,1,2,206,200,104,76, -70,29,36,77,186,112,19,1,16,135,228,30,20,92,69,25,112,37,197,137,69,33,4,201,42,227,191,7,58,182,212,131,206,168,131,84,118,19,139,31,19,1,29,116,57,224,101,117,114,2,42,177,58,0,81,211,246,144,251,165,184,32,121,1,96,15,77,202,86,215,209,160,56,146, -238,227,144,222,70,64,180,25,131,41,48,17,151,98,83,30,165,68,5,128,39,234,2,127,52,185,82,64,174,184,16,248,170,114,136,75,18,222,21,72,118,121,254,155,27,64,107,212,67,58,90,137,158,88,14,80,73,4,92,133,137,129,136,138,215,46,77,254,43,86,32,2,96,15, -78,202,170,36,160,182,207,214,231,25,206,107,1,192,166,33,185,162,230,72,64,154,242,88,96,142,205,3,240,130,55,154,100,41,32,249,96,126,122,45,0,10,0,68,201,135,140,202,158,127,59,245,252,11,210,99,252,255,49,18,208,174,98,36,0,151,3,16,197,175,219,120, -28,116,90,94,145,36,64,71,216,2,188,134,151,245,218,136,95,204,115,1,192,107,32,64,51,33,253,162,121,234,221,0,57,136,72,97,112,40,145,8,56,107,58,46,1,32,138,26,127,213,19,254,140,233,53,254,31,41,2,212,168,14,56,3,171,3,16,165,5,0,16,227,175,5,189, -54,57,1,16,146,130,224,14,219,137,51,58,69,1,64,123,0,144,235,217,214,239,195,37,0,144,64,244,140,7,70,57,25,77,64,196,88,20,108,193,137,164,247,67,152,59,43,35,30,166,72,14,144,142,108,255,12,16,1,234,87,7,160,8,64,148,33,70,156,189,18,114,15,37,91, -253,237,137,56,192,39,122,100,53,1,138,134,36,127,192,25,49,229,181,0,96,15,49,242,244,8,58,35,253,114,219,33,154,131,163,73,239,134,48,103,102,98,28,48,54,4,66,146,52,254,106,133,253,143,50,227,255,47,178,253,51,0,117,171,3,80,4,32,202,9,214,178,194, -228,187,89,58,66,102,8,139,129,41,155,209,99,77,240,38,189,230,160,53,191,5,192,49,236,131,222,62,78,198,64,30,26,122,177,4,146,23,81,252,244,26,208,176,74,0,124,184,32,153,103,252,19,165,126,153,231,249,127,212,131,245,131,213,1,38,172,14,64,50,16,122, -11,149,43,208,206,218,18,52,177,40,244,84,111,73,54,7,199,18,26,147,194,82,56,221,199,34,35,4,0,57,24,189,114,198,50,210,228,11,90,134,65,79,66,82,7,161,162,12,248,218,106,172,4,64,50,208,248,239,73,107,182,191,28,17,112,188,58,224,70,172,14,64,50,16, -129,231,160,76,1,1,48,225,31,145,213,63,142,230,190,5,29,145,62,41,154,254,107,56,35,4,128,115,216,55,40,137,177,41,91,95,26,1,112,71,28,224,73,182,18,128,227,216,50,0,136,40,0,144,12,51,254,172,201,143,46,171,114,84,254,185,58,64,217,156,0,92,14,64, -228,66,187,207,26,245,2,203,1,72,22,186,252,204,201,168,0,160,209,110,251,160,183,59,19,142,71,70,8,0,183,41,48,22,241,68,237,220,20,167,34,209,54,165,129,168,79,153,68,192,5,115,177,18,0,153,154,161,75,129,231,159,234,38,63,170,136,128,77,152,19,128, -100,136,0,136,209,6,64,180,2,128,79,234,125,162,177,8,235,1,32,167,4,144,205,177,25,241,161,0,56,78,200,29,117,251,109,225,145,169,143,69,212,64,52,30,129,201,64,242,213,20,218,69,117,0,60,143,119,8,114,210,158,127,190,101,251,203,17,1,39,170,3,54,97, -159,0,36,51,34,0,229,133,134,228,157,214,136,29,220,97,135,172,8,0,29,3,236,26,245,247,163,0,56,134,24,150,226,30,115,176,139,147,49,23,89,67,158,50,227,190,193,228,35,0,117,179,129,43,41,196,68,64,228,164,140,191,250,97,127,125,206,76,169,252,123,117, -0,77,12,84,97,57,160,196,8,17,20,1,200,73,66,69,99,178,152,3,99,16,148,124,83,46,1,164,54,46,236,137,90,220,166,224,72,38,28,11,46,83,78,138,99,200,215,206,201,152,205,204,113,2,140,7,146,111,168,68,147,0,89,34,32,230,1,32,105,52,254,29,91,178,55,236, -255,175,34,1,199,171,3,110,84,163,68,240,204,99,145,0,172,14,64,254,157,163,71,12,112,101,73,242,17,0,147,127,16,68,54,4,104,138,14,43,249,124,191,53,52,24,242,68,188,40,0,62,44,0,218,228,172,192,211,53,24,107,112,28,130,162,63,201,43,67,0,97,254,28, -0,81,196,187,4,73,143,231,191,185,49,107,178,253,229,136,128,34,21,19,3,177,58,0,249,119,176,4,64,157,160,72,5,128,201,55,32,111,6,0,113,114,61,230,96,135,20,201,140,235,52,99,4,128,173,215,219,45,6,197,232,212,135,2,241,224,9,59,192,26,26,79,122,31, -180,203,22,225,18,0,146,30,227,191,37,251,215,252,79,54,18,144,16,1,152,24,136,164,88,0,196,226,204,248,27,146,76,0,164,19,104,39,252,195,196,249,156,122,43,97,186,4,96,237,245,182,100,202,49,201,24,1,224,53,7,71,195,62,113,108,234,51,1,52,16,142,133, -136,34,75,62,15,128,9,0,157,22,59,2,34,31,190,225,213,14,251,103,80,111,255,212,138,0,117,102,7,160,8,64,62,46,2,160,196,250,191,43,108,7,91,72,94,5,0,221,7,107,143,7,5,192,63,18,116,134,67,158,137,96,23,47,99,38,0,53,216,35,222,158,164,247,65,152,63, -23,248,138,114,0,92,75,68,62,224,249,171,157,237,175,205,113,207,255,163,68,192,137,229,128,141,88,29,128,164,6,26,178,175,45,43,72,250,125,104,213,153,63,234,158,114,5,0,253,252,168,79,244,57,6,189,189,40,0,254,217,134,131,99,192,219,200,9,114,102,43, -11,48,234,235,75,254,96,148,151,130,48,111,22,196,49,15,0,57,102,252,213,15,251,231,78,182,255,84,249,96,117,0,54,11,66,212,22,157,180,246,191,74,129,4,192,17,98,191,229,36,0,82,219,230,179,134,6,60,147,193,73,20,0,31,129,165,199,211,32,231,89,40,104, -4,54,19,192,27,117,37,189,15,218,21,75,48,17,16,73,81,182,191,62,175,167,80,126,120,118,128,90,57,1,6,172,14,64,78,76,0,84,162,3,224,144,167,123,202,229,127,9,1,192,129,115,196,223,34,134,50,231,130,204,40,1,96,235,243,180,73,209,184,140,68,64,14,60, -17,39,75,204,72,22,221,234,229,216,16,8,141,63,102,251,167,80,4,20,169,218,54,184,14,171,3,16,38,0,170,75,141,178,50,247,63,244,104,136,69,192,228,31,0,158,155,122,2,32,93,49,176,245,122,142,102,210,113,201,44,1,208,235,25,242,89,67,35,156,156,142,128, -228,196,12,121,186,146,143,0,44,89,192,150,2,48,15,0,141,63,118,248,75,109,36,0,171,3,16,53,175,177,233,21,133,73,191,143,53,104,2,71,200,34,171,2,128,238,4,141,114,163,0,248,24,66,222,104,216,61,30,104,230,4,57,163,129,57,24,244,116,38,127,64,106,170, -64,168,155,147,200,252,70,242,235,33,145,18,227,143,158,255,191,21,1,216,54,24,81,242,218,138,39,214,255,107,203,147,79,0,28,242,244,64,72,10,176,234,179,41,185,168,156,6,66,158,168,131,56,185,157,153,116,108,184,76,59,89,147,173,206,195,114,18,1,121, -78,11,163,190,126,8,75,201,135,16,217,50,0,118,4,204,59,207,31,123,251,167,95,4,224,236,0,68,105,104,233,93,89,161,30,74,11,146,111,0,52,224,105,151,103,104,137,77,243,76,4,59,137,131,107,67,1,240,47,176,244,184,15,201,25,178,76,107,50,29,97,139,34,131, -129,116,107,87,17,79,16,243,0,242,201,248,99,182,127,230,80,252,1,17,96,82,169,58,0,103,7,228,15,82,44,206,188,255,100,111,191,88,92,98,9,128,114,194,255,180,188,221,222,239,61,28,207,176,137,179,25,39,0,172,221,158,214,176,55,234,144,213,16,72,12,194, -160,167,35,233,125,160,13,129,248,234,74,140,2,160,241,79,138,163,152,237,47,59,18,192,170,3,44,42,205,14,32,34,160,26,171,3,242,6,106,248,103,86,21,37,111,155,130,19,96,9,154,100,37,0,82,75,107,106,178,31,200,180,99,147,113,2,192,109,10,216,93,99,129, -86,94,198,50,128,70,195,65,175,171,53,249,131,82,90,12,218,165,139,48,15,32,231,141,191,168,162,231,191,23,218,48,219,63,41,17,80,164,106,78,0,86,7,228,197,117,68,46,164,2,189,22,166,41,177,254,239,237,130,128,232,37,70,115,106,102,147,86,30,136,33,41, -108,238,112,215,163,0,248,55,196,164,56,76,182,59,15,242,50,66,240,2,167,37,39,169,27,194,82,48,233,253,208,159,185,6,64,194,8,64,110,123,254,130,138,107,254,245,184,230,175,80,36,224,239,205,130,48,39,0,153,26,82,44,198,162,61,5,122,33,233,247,234,113, -53,201,139,64,208,9,128,246,112,55,113,110,71,50,237,248,112,153,120,210,198,155,156,123,227,50,18,1,88,30,64,208,204,234,52,147,69,119,250,42,208,20,21,210,133,31,188,139,114,205,176,164,160,206,31,179,253,21,22,1,102,20,1,136,12,135,50,30,135,153,149, -201,135,255,197,184,8,3,238,78,214,116,110,202,118,73,203,209,254,255,7,195,190,104,198,121,148,25,41,0,204,29,174,6,114,176,60,156,140,60,128,72,44,76,148,90,115,210,251,32,204,155,147,40,7,20,113,25,32,215,60,127,13,78,245,67,17,128,34,32,47,208,242, -60,204,170,78,94,0,76,250,135,143,173,255,107,167,110,100,121,13,140,55,59,118,103,226,241,201,72,1,224,158,8,76,186,70,3,205,156,118,234,187,71,163,0,93,206,166,228,119,130,231,64,127,198,106,128,8,10,128,92,50,254,170,103,251,227,154,191,250,34,96, -147,122,179,3,176,58,32,119,160,217,255,229,197,122,168,40,78,190,255,127,143,171,5,66,162,140,250,127,242,207,165,168,20,158,104,113,30,70,1,112,146,196,196,56,152,219,93,187,228,8,0,129,245,3,232,3,79,196,145,244,126,232,215,157,14,26,28,15,140,198, -255,36,140,63,102,251,167,78,4,116,88,212,235,24,136,213,1,185,37,0,102,85,21,1,167,64,249,109,151,179,65,118,255,127,151,41,208,97,235,247,14,102,226,49,226,50,245,228,153,154,29,187,228,24,94,58,162,209,19,118,64,159,187,61,233,125,160,131,129,248, -217,51,176,28,48,235,141,191,186,217,254,108,164,47,26,255,148,137,128,34,85,151,3,176,58,32,87,224,57,13,204,169,41,73,250,125,124,81,15,171,255,23,184,169,15,18,226,117,28,76,182,185,246,68,252,153,121,65,101,172,0,152,108,119,53,132,188,81,139,12, -209,5,177,120,12,58,28,71,146,222,7,141,65,15,186,211,87,67,60,18,193,187,41,171,61,127,181,179,253,209,248,167,35,18,160,110,78,128,1,69,64,150,123,255,37,133,58,168,45,51,38,253,94,180,251,159,51,108,101,203,203,83,182,33,26,13,76,180,56,183,103,234, -113,202,88,1,224,30,243,187,108,189,222,131,188,110,234,7,93,203,235,216,154,13,29,16,148,44,6,98,52,52,56,29,48,59,13,5,102,251,231,135,8,80,171,79,0,38,6,102,181,0,152,85,89,4,2,159,188,137,107,183,31,97,93,0,167,108,252,201,71,135,60,17,215,200,17, -219,33,20,0,83,189,193,201,29,62,214,96,223,198,203,24,12,68,75,53,44,193,49,24,246,246,36,189,31,186,83,87,2,63,115,90,34,140,140,100,149,231,143,189,253,243,68,4,96,159,0,228,31,13,27,241,188,235,166,37,31,254,23,227,81,232,118,53,129,86,78,248,95, -203,129,99,200,127,196,51,17,176,160,0,144,193,200,17,235,118,73,140,201,176,188,26,136,74,17,162,220,146,79,188,212,20,24,65,119,230,169,184,12,144,101,198,31,167,250,229,107,36,0,171,3,242,157,24,241,254,75,11,117,48,77,129,241,191,35,222,94,48,7,70, -101,181,255,165,205,236,70,143,218,222,165,73,237,40,0,100,96,237,246,116,187,77,254,118,94,86,53,128,0,29,206,163,44,31,32,89,140,151,156,75,206,38,143,213,0,104,252,19,217,254,104,252,51,82,4,168,94,29,128,34,32,43,16,137,0,152,83,83,12,90,5,194,255, -109,246,67,16,145,194,83,46,255,163,72,209,88,140,8,128,247,50,58,82,146,201,59,71,51,39,205,157,238,247,104,38,229,212,5,128,14,198,124,3,48,238,79,190,250,66,187,122,5,8,115,103,65,92,196,101,128,204,54,254,152,237,159,207,34,224,131,213,1,38,204,9, -200,91,104,246,255,252,105,165,201,71,18,136,243,216,102,63,194,156,201,41,27,86,65,3,126,107,168,139,216,175,246,76,62,86,92,166,159,204,129,61,150,183,228,60,113,169,98,163,141,27,218,28,10,44,3,24,244,96,56,239,76,128,48,46,3,100,182,231,47,168,104, -252,49,219,63,91,34,1,84,4,220,168,70,78,192,153,88,29,144,233,208,228,63,218,248,71,137,225,63,212,121,164,109,229,229,148,255,9,122,158,150,178,191,23,246,102,118,242,88,198,11,128,209,35,182,195,62,75,112,140,182,83,156,186,18,20,160,197,118,16,228, -204,21,248,71,12,151,158,71,132,128,1,151,1,50,214,248,171,24,246,199,53,255,172,20,1,44,39,192,171,160,8,48,96,36,32,27,4,0,77,254,155,106,27,249,143,162,197,126,80,86,247,191,227,23,98,223,174,201,55,50,253,120,101,188,0,8,56,195,126,91,159,119,155, -156,101,0,154,185,73,147,56,38,252,67,73,239,135,118,217,34,208,46,93,136,201,128,121,102,252,105,123,95,45,102,251,103,167,8,176,168,85,34,136,213,1,153,122,222,117,2,7,11,166,39,31,254,143,199,99,204,121,148,19,254,215,16,241,17,116,69,76,227,205,206, -247,81,0,40,192,224,126,203,102,186,166,50,229,19,65,126,5,69,63,52,89,247,43,112,164,56,22,5,192,114,192,204,50,254,170,151,250,225,154,127,86,139,128,14,172,14,200,31,239,95,138,65,109,121,161,34,189,255,71,125,253,196,121,236,147,25,254,231,192,220, -233,222,230,183,133,124,40,0,20,17,0,230,93,33,119,212,170,145,17,214,161,179,1,154,108,7,20,169,6,48,92,114,46,112,21,101,52,206,132,119,91,134,120,254,101,152,237,143,252,11,17,80,132,213,1,121,3,157,220,190,104,102,169,34,239,213,100,219,7,97,41,40, -43,252,79,157,213,254,61,147,175,102,195,49,203,10,1,224,54,5,92,147,237,174,93,130,78,222,112,160,49,95,31,81,115,201,55,5,226,167,213,128,254,172,211,32,30,14,227,221,150,86,227,175,118,182,127,35,102,251,231,152,8,80,179,99,96,37,46,7,100,128,241, -143,67,49,57,31,117,181,201,11,0,218,122,166,153,56,141,90,25,163,127,19,225,255,168,109,232,128,117,15,10,0,5,25,216,107,222,164,209,202,91,6,8,75,33,168,183,42,51,142,217,120,213,37,180,205,20,222,113,105,245,252,213,206,246,199,53,255,92,19,1,106, -118,12,188,10,103,7,164,29,81,138,195,188,218,18,48,232,146,111,219,62,232,233,32,78,227,32,240,50,4,0,13,255,79,182,185,182,121,38,2,78,20,0,10,50,184,223,242,158,220,101,0,58,27,128,42,186,72,44,249,27,95,127,198,26,16,22,214,97,50,96,58,30,228,152, -237,143,36,43,2,84,157,29,128,34,32,93,8,196,46,44,153,85,174,204,179,192,178,19,196,88,68,86,248,95,147,8,255,191,152,45,199,45,107,4,128,219,20,112,154,219,93,239,81,133,53,229,139,67,163,133,73,255,8,116,59,155,146,223,17,157,22,10,46,191,16,32,18, -197,187,46,197,198,95,131,217,254,136,82,145,0,28,32,148,67,222,63,77,254,43,128,26,5,106,255,105,210,120,171,253,125,208,241,250,169,27,127,34,66,66,174,168,121,232,128,117,7,10,0,21,232,223,99,126,145,19,228,237,114,140,252,58,108,222,166,200,126,24, -174,184,16,184,138,114,76,6,76,21,152,237,143,40,44,2,58,44,88,29,144,43,208,228,191,165,179,43,20,185,125,105,235,95,107,112,28,120,205,212,203,255,104,243,159,201,118,215,155,158,137,128,7,5,128,10,244,237,152,216,225,179,4,77,114,74,2,117,156,30,218, -29,71,193,21,182,37,189,31,44,25,144,24,162,120,40,132,119,95,10,140,63,246,246,71,148,22,1,88,29,144,43,198,63,49,248,71,137,214,191,148,67,230,237,242,26,255,64,98,252,111,215,214,177,23,178,233,248,101,149,0,240,219,195,62,83,163,99,11,85,90,83,254, -162,26,30,220,97,59,52,40,148,156,89,240,153,203,65,163,211,98,103,64,85,141,191,168,242,84,63,204,246,207,119,17,160,110,78,0,46,7,168,13,77,254,91,52,163,12,116,218,228,77,25,157,250,215,195,70,255,78,61,252,79,157,82,175,37,52,48,120,192,178,23,5, -128,138,244,108,159,120,142,217,92,25,15,109,218,26,248,176,121,135,34,61,1,116,171,151,131,110,205,74,136,227,124,0,21,61,127,65,213,193,62,152,237,143,34,64,205,234,0,236,24,168,242,249,35,39,208,160,229,97,233,108,101,146,255,14,19,239,223,31,245, -16,103,81,70,158,25,237,253,95,111,127,37,228,142,102,85,88,56,235,4,192,208,1,235,251,238,49,127,27,47,99,25,128,182,6,30,242,116,65,191,187,45,249,29,209,104,160,224,186,79,97,30,128,26,55,182,218,237,125,49,219,31,249,71,17,96,70,17,144,117,62,2,121, -246,206,173,45,129,210,66,125,210,239,69,43,196,142,88,118,201,242,254,233,115,36,38,197,165,246,55,70,159,203,182,99,152,117,2,32,26,20,197,193,125,150,231,229,44,3,208,181,157,104,44,2,7,38,222,86,100,95,12,23,156,13,194,162,58,114,245,96,20,64,73, -227,175,118,182,63,122,254,200,199,138,0,156,29,144,53,208,177,191,43,231,85,42,242,94,237,246,35,108,102,140,32,163,246,159,215,114,224,26,241,31,153,104,85,162,204,12,5,192,191,165,115,235,216,139,98,36,22,210,200,120,136,235,121,3,52,219,15,42,146, -12,8,122,29,20,124,246,10,136,99,73,160,66,234,14,179,253,145,244,138,0,172,14,200,14,104,233,223,172,170,34,69,198,254,82,246,79,188,37,251,181,212,25,237,126,111,252,153,104,80,202,186,132,176,172,20,0,214,94,111,191,185,211,189,157,215,201,75,6,116, -133,237,44,219,83,9,140,159,186,24,248,89,211,201,21,137,67,130,146,53,254,152,237,143,164,91,4,124,184,58,64,121,17,128,213,1,202,157,171,149,243,170,20,121,47,147,127,16,186,156,141,160,227,167,62,68,136,58,161,17,191,232,238,223,51,185,41,27,143,99, -86,10,128,24,185,129,186,182,154,30,231,101,102,126,210,30,207,7,39,223,97,203,1,73,31,192,146,98,40,184,230,50,136,135,112,62,128,124,227,127,60,219,255,118,204,246,71,50,66,4,36,114,2,90,177,58,32,19,189,255,88,156,120,254,133,48,167,166,88,33,239, -127,43,107,0,36,167,252,79,48,240,96,106,118,188,110,237,246,152,81,0,164,144,222,29,19,111,251,172,161,33,142,151,151,12,104,242,13,176,166,15,74,64,151,1,184,234,74,58,143,18,239,78,89,158,255,241,108,255,51,85,48,254,184,230,143,76,93,4,96,78,64,6, -159,31,34,0,78,153,87,169,200,72,22,95,212,13,71,205,59,101,117,254,99,17,0,158,131,206,55,199,30,203,214,99,153,181,2,32,224,8,7,6,246,154,159,211,26,229,15,127,216,109,122,93,153,131,72,140,127,193,85,151,64,60,136,141,129,166,116,35,171,26,246,223, -139,189,253,145,228,69,192,241,156,0,47,138,128,76,241,254,171,201,113,91,48,93,153,198,63,180,244,207,30,154,148,213,249,143,23,56,112,143,249,91,6,247,89,246,161,0,72,3,29,111,142,61,41,69,99,97,57,15,120,186,222,211,237,106,132,65,79,167,50,81,128, -47,92,11,92,101,57,70,1,166,224,249,171,155,237,95,15,90,52,254,136,82,34,96,163,58,145,0,28,37,60,53,98,212,251,175,171,2,78,1,247,159,14,252,217,55,254,22,8,156,78,214,235,5,3,7,61,219,198,31,11,251,162,89,155,0,150,213,2,96,178,205,217,51,209,234, -122,71,118,73,160,20,134,93,166,205,138,236,11,109,15,92,112,245,39,49,10,144,9,198,31,179,253,17,133,69,64,199,137,102,65,202,38,6,94,133,213,1,39,141,68,140,127,85,137,1,22,206,80,198,251,111,182,29,132,17,95,31,91,18,158,178,253,32,2,36,236,19,157, -109,175,141,190,144,205,199,52,171,5,64,76,138,67,235,107,35,15,201,153,13,144,136,2,24,161,209,186,15,44,193,49,101,162,0,95,196,40,192,201,24,127,26,246,47,195,108,127,36,139,68,0,171,14,56,150,24,104,194,234,128,52,9,128,24,172,158,95,13,2,207,41, -112,78,227,204,249,147,219,247,95,107,224,97,228,176,109,163,107,204,111,65,1,144,70,6,246,154,183,123,198,131,109,188,140,41,129,180,229,163,63,234,38,23,194,22,229,162,0,215,94,134,81,128,143,53,254,216,219,31,201,110,17,64,19,3,111,196,234,128,148, -67,215,254,107,202,10,96,209,204,50,69,222,175,199,217,4,61,174,102,217,201,127,177,88,92,106,223,50,250,112,182,31,215,172,23,0,97,111,52,218,179,109,124,61,45,199,144,3,109,12,116,104,114,27,184,34,118,69,246,167,240,203,159,5,190,166,138,118,170,192, -187,246,159,60,127,65,229,246,190,152,237,143,168,43,2,212,175,14,192,72,192,71,30,123,34,0,214,16,239,159,231,148,185,193,183,143,189,2,82,92,146,87,250,167,231,193,214,231,221,53,116,208,210,136,2,32,3,104,122,105,232,217,160,59,98,145,83,18,200,105, -4,112,133,173,176,87,169,138,128,170,10,40,184,225,42,140,2,124,240,230,197,222,254,72,174,137,128,227,57,1,94,21,34,1,37,24,9,248,144,247,47,197,96,90,69,33,44,80,104,237,127,200,219,5,173,246,247,153,243,39,235,25,47,104,160,245,213,225,251,99,82,246, -79,130,205,9,1,224,157,12,58,135,14,88,158,148,27,5,160,21,1,251,38,222,98,53,161,74,80,240,249,107,129,159,51,35,225,245,162,241,79,65,111,127,52,254,72,14,69,2,206,196,18,193,127,100,237,162,26,226,172,41,115,147,191,55,178,145,53,129,147,227,253,211, -230,115,158,137,96,123,215,86,211,214,92,56,174,92,174,92,32,13,207,13,60,44,134,99,65,57,223,136,214,128,218,130,147,176,119,252,77,101,14,106,105,49,20,125,245,122,28,21,140,217,254,72,62,136,0,21,167,8,230,123,117,0,157,248,71,59,254,205,85,168,235, -223,152,175,31,154,108,251,137,247,111,148,245,122,234,100,118,189,109,122,48,18,16,115,194,187,203,25,1,96,233,242,12,76,180,58,55,105,245,242,162,0,90,94,15,187,77,91,192,47,122,20,217,31,227,181,151,129,118,217,162,252,21,1,216,219,31,201,51,17,128, -213,1,202,67,215,252,79,95,92,171,216,251,189,55,186,17,194,98,64,150,247,79,67,255,62,75,104,188,121,227,208,179,185,114,124,115,70,0,196,227,113,104,120,118,224,62,208,104,100,101,223,9,26,1,172,65,19,236,49,189,161,200,254,104,244,122,40,250,214,151, -243,179,36,16,179,253,145,60,20,1,88,29,160,44,52,250,177,104,102,57,212,150,41,51,241,207,228,31,128,122,203,110,208,11,242,188,127,173,65,128,193,125,150,13,62,107,200,157,43,199,152,203,165,11,102,240,128,165,97,172,222,254,182,214,32,55,10,96,72, -68,1,162,202,68,1,12,23,173,3,253,186,211,33,30,8,230,207,3,17,179,253,145,124,142,4,168,84,29,80,153,103,137,129,49,114,80,141,228,152,158,190,168,70,177,247,124,123,248,5,8,73,212,251,159,186,217,163,141,127,34,1,209,213,244,210,224,250,92,58,206,57, -37,0,104,169,72,203,166,225,123,56,65,222,215,58,30,5,216,105,122,77,153,29,210,104,160,248,59,95,3,141,94,151,184,162,243,192,248,171,185,230,143,189,253,145,140,23,1,22,117,68,192,85,52,49,48,143,68,0,93,251,95,85,87,5,37,5,58,69,222,111,216,219,67, -188,255,93,178,51,255,117,70,129,14,160,251,155,181,215,51,137,2,32,131,25,58,104,217,109,31,240,238,226,117,242,190,154,238,88,20,192,29,113,40,178,63,218,21,139,193,120,237,229,16,15,4,114,252,142,85,63,219,31,123,251,35,249,44,2,242,165,58,128,182, -252,173,44,54,192,170,249,213,138,189,231,214,225,103,33,194,198,198,200,240,254,53,204,251,247,55,60,51,240,64,174,29,235,156,19,0,228,68,65,227,11,131,119,11,50,147,1,105,69,128,35,100,134,109,163,155,20,219,167,226,111,125,137,117,9,132,236,157,25, -241,111,141,191,154,83,253,48,219,31,201,86,17,96,194,234,128,41,19,139,199,225,204,197,181,160,19,148,49,79,189,174,22,104,178,202,207,252,167,19,103,199,26,237,207,90,251,60,131,40,0,178,128,206,183,198,222,182,247,123,247,9,50,163,0,244,66,217,59, -254,6,88,131,227,202,28,228,170,10,40,186,241,139,185,89,17,160,246,72,223,45,245,24,246,71,178,82,4,208,1,66,55,170,48,64,40,151,171,3,168,176,153,87,91,162,88,211,31,122,54,222,28,122,26,164,184,40,175,239,191,134,37,152,135,154,94,28,252,99,46,94, -171,57,41,0,162,33,41,222,248,194,224,93,188,94,222,215,227,52,60,120,35,46,216,58,252,156,98,251,84,240,217,43,65,183,246,148,220,234,16,168,122,182,127,3,102,251,35,89,43,2,138,78,148,8,170,83,29,144,107,163,132,137,227,15,122,45,15,103,45,157,166, -216,123,54,217,14,64,187,227,136,124,239,223,192,195,232,81,251,179,67,7,173,61,40,0,178,41,10,176,213,244,182,173,223,183,79,174,8,48,8,70,120,127,242,61,150,60,162,8,2,15,37,223,255,15,182,78,14,177,28,184,105,49,219,31,65,78,42,18,160,86,179,160,227, -163,132,115,69,4,68,164,24,172,174,171,98,235,255,74,32,198,163,204,251,215,104,100,154,57,13,243,6,67,71,159,238,191,59,87,175,209,156,21,0,209,160,24,111,122,97,240,46,65,199,203,60,247,28,68,98,33,120,125,240,9,197,246,73,187,106,89,98,78,128,63,187, -203,2,213,238,237,143,217,254,72,78,138,128,77,106,204,14,200,13,17,32,74,113,168,46,49,192,154,133,202,37,254,237,31,223,10,3,238,14,208,113,242,38,254,209,204,255,129,221,147,79,142,28,178,245,228,234,245,201,229,242,205,215,185,117,108,171,125,192, -187,83,110,66,32,13,27,53,219,14,66,139,253,160,114,55,237,77,95,6,161,110,54,196,35,217,153,15,16,199,108,127,4,145,39,2,104,98,224,70,245,218,6,103,179,8,160,183,251,186,229,211,65,203,43,99,146,104,47,151,183,135,159,39,239,39,175,140,144,214,253, -71,195,146,255,192,67,221,191,163,77,230,80,0,100,101,20,64,130,163,79,245,223,73,91,56,202,187,40,53,172,4,100,203,192,223,216,240,8,69,14,120,73,49,91,10,0,41,150,88,244,202,170,3,170,158,241,63,138,189,253,145,124,17,1,155,80,4,124,144,136,40,193, -210,57,21,48,187,186,88,177,247,124,103,228,5,176,4,199,64,208,104,101,189,94,91,32,64,239,246,137,13,182,126,239,80,46,95,151,92,174,223,120,29,111,140,237,26,171,183,191,65,75,57,228,64,195,71,131,158,78,216,99,218,162,216,62,233,47,90,7,198,79,93, -12,113,127,22,245,6,80,123,164,47,246,246,71,242,73,4,168,84,29,144,109,34,128,214,252,151,146,251,254,172,37,202,245,251,31,247,15,193,46,211,102,208,243,242,90,8,211,148,129,104,64,116,214,63,51,112,79,174,95,147,57,47,0,104,248,134,156,200,95,16,79, -94,118,17,62,109,14,180,117,248,121,112,134,173,138,237,23,141,2,240,51,167,101,199,200,96,149,179,253,59,176,183,63,146,111,34,64,181,234,128,121,89,85,29,64,107,254,105,232,223,168,23,20,123,207,205,3,143,65,64,244,1,39,51,249,79,87,192,186,254,221, -103,235,243,76,160,0,200,1,6,15,88,234,71,142,216,158,211,26,229,93,100,180,57,16,53,254,175,15,62,169,220,129,175,170,128,146,31,124,11,226,162,152,217,75,1,41,200,246,215,98,182,63,146,183,34,32,127,171,3,104,205,255,210,89,229,48,127,122,169,98,239, -73,71,253,54,88,247,129,65,102,217,31,199,107,192,111,11,143,29,92,223,115,127,62,92,139,121,33,0,232,140,128,189,15,116,222,41,69,99,126,154,220,33,7,131,80,0,7,38,222,134,30,87,139,98,251,101,248,228,249,96,188,242,146,140,93,10,192,108,127,4,73,129, -8,200,195,234,128,68,232,95,7,103,47,155,174,216,123,134,165,32,188,54,240,232,49,207,95,222,67,69,87,168,133,182,205,163,191,241,76,4,92,40,0,114,8,75,151,187,191,111,231,196,3,186,2,185,101,129,26,136,197,37,120,165,127,61,171,47,85,138,146,31,126, -11,132,217,51,32,30,201,172,165,0,204,246,71,144,20,137,0,21,171,3,50,117,57,128,6,61,207,93,57,3,10,20,12,253,191,59,242,34,140,120,251,64,203,201,203,252,167,243,99,236,131,222,214,250,231,6,30,207,151,107,144,203,167,27,110,255,131,93,247,4,156,145, -113,26,230,145,165,14,121,3,244,186,90,97,215,216,107,202,157,128,202,114,40,249,209,127,38,154,3,101,202,82,64,74,178,253,49,236,143,32,255,156,24,152,251,203,1,225,168,4,43,230,86,64,93,109,137,98,239,57,238,31,132,119,71,55,202,14,253,83,104,215,191, -134,103,7,110,15,185,35,145,124,185,254,242,74,0,120,38,130,142,230,77,195,191,20,100,86,4,36,68,128,30,222,28,122,70,177,57,1,20,106,100,11,191,112,45,196,125,25,176,20,144,178,108,127,180,254,8,242,33,17,112,44,39,192,148,195,213,1,172,225,15,217,151, -179,151,77,83,244,8,110,234,123,24,130,162,159,181,113,151,131,64,140,255,120,179,115,107,231,91,99,111,230,211,181,199,229,219,205,86,255,116,255,227,174,17,127,189,220,113,193,52,33,208,27,117,193,203,253,235,21,221,175,226,239,126,29,180,167,44,73, -239,172,0,236,237,143,32,105,23,1,55,170,84,29,144,110,17,64,3,156,60,167,129,11,86,205,2,157,192,43,246,190,251,39,222,97,205,218,146,241,254,53,188,38,242,254,163,61,63,137,134,164,188,186,238,242,78,0,68,2,162,248,254,35,61,63,230,181,242,191,186, -129,47,128,122,203,110,56,98,217,169,216,126,105,10,140,80,250,179,239,179,159,32,165,225,34,76,73,111,127,52,254,8,114,178,145,128,92,19,1,81,242,92,59,99,73,45,76,43,47,80,236,61,157,97,27,75,252,147,187,238,79,209,23,105,161,111,219,196,131,131,7, -44,173,249,118,205,113,249,120,163,117,189,109,218,49,124,208,250,60,173,247,148,11,141,4,208,40,128,39,226,84,108,191,180,203,22,65,201,247,190,9,241,96,56,165,199,3,179,253,17,36,3,69,64,14,85,7,208,146,191,186,105,165,176,102,65,181,162,239,75,147, -178,29,33,11,121,30,203,235,248,71,187,196,6,221,145,241,253,15,119,255,26,226,249,119,189,229,165,0,160,161,168,125,15,118,221,30,13,73,110,185,101,129,2,167,5,107,96,156,92,128,27,20,221,183,130,207,95,147,232,18,232,243,167,196,96,98,182,63,130,100, -166,8,232,200,145,217,1,180,228,175,164,64,7,23,156,50,83,209,199,0,141,194,190,63,185,141,149,104,203,118,186,140,2,52,60,55,112,135,115,216,103,207,199,107,141,203,215,155,204,210,229,30,110,121,101,248,215,186,66,249,81,0,122,225,237,159,120,27,26, -172,123,21,221,183,146,31,255,39,8,11,235,212,143,4,168,109,252,177,183,63,130,200,22,1,133,42,86,7,164,74,4,28,47,108,186,112,213,44,40,52,104,21,123,95,119,196,1,27,251,30,34,158,63,207,74,180,101,57,113,122,14,172,61,238,61,13,207,41,216,225,13,5, -64,246,112,248,241,222,251,93,163,254,38,185,249,0,244,194,227,53,28,108,236,125,144,37,6,42,118,82,74,75,160,236,127,111,1,141,65,79,211,102,85,51,254,234,133,253,247,66,7,246,246,71,144,164,249,112,78,64,246,85,7,68,201,243,235,140,197,181,48,187,186, -72,209,247,125,185,111,61,171,196,162,145,88,153,15,111,224,4,46,122,224,161,238,155,163,193,44,159,165,140,2,64,30,33,79,52,114,240,225,238,155,5,61,47,123,245,71,224,116,96,9,154,152,26,85,18,237,202,37,80,114,243,255,133,120,56,172,124,127,0,85,179, -253,137,241,223,92,143,217,254,8,162,80,36,64,237,217,1,85,37,234,136,0,186,238,191,112,70,25,172,93,84,163,236,51,198,178,19,14,78,190,3,198,36,66,255,250,2,1,58,223,26,187,191,127,143,185,33,159,175,47,46,223,111,176,174,119,199,119,13,238,183,60,154, -204,82,0,189,16,15,78,188,3,135,205,219,21,221,183,130,235,174,132,130,207,95,11,113,175,95,97,207,95,205,108,255,122,92,243,71,16,213,68,128,10,203,1,103,38,34,1,17,5,69,64,84,138,65,101,177,1,46,88,53,83,209,99,65,19,254,94,234,253,43,240,156,0,114, -31,50,196,243,135,128,51,50,176,255,161,238,59,243,253,218,202,123,1,64,231,4,236,250,99,219,207,130,174,136,73,110,135,64,122,33,210,11,242,165,222,7,193,30,154,84,116,255,74,110,185,9,244,23,156,77,68,128,47,249,239,26,142,96,182,63,130,100,187,8,80, -169,58,160,154,137,128,228,151,28,69,98,252,11,244,90,248,228,105,115,192,160,19,20,61,14,47,244,62,0,142,176,5,4,141,252,124,2,173,129,131,3,15,119,255,208,59,25,244,160,0,64,192,57,226,183,29,125,170,255,182,100,162,0,244,130,116,69,108,240,108,207, -125,228,102,85,46,100,175,209,233,152,193,54,92,124,46,196,61,222,68,203,96,57,15,16,127,0,184,242,82,40,191,231,231,152,237,143,32,217,44,2,44,199,68,128,194,145,128,171,207,170,131,89,85,197,172,85,175,220,85,71,42,32,78,204,33,40,49,40,250,253,119, -140,189,202,50,255,141,124,161,124,227,111,228,97,172,193,241,124,235,107,195,175,227,21,133,2,224,4,77,47,14,189,96,106,116,188,170,77,162,77,48,109,16,212,108,61,192,134,82,40,137,166,168,16,202,239,190,3,138,190,245,101,58,64,27,226,129,224,73,231, -5,80,175,159,182,24,214,159,125,26,84,109,184,155,253,84,220,248,99,111,127,4,73,125,36,64,225,229,0,58,152,231,42,34,2,78,91,88,195,62,135,46,9,156,172,16,160,165,126,244,223,207,169,41,129,79,159,179,0,106,202,140,138,126,239,17,111,47,188,218,255, -40,155,199,34,219,216,241,26,136,134,36,203,174,123,219,111,141,199,240,90,66,1,240,1,196,136,4,59,255,208,254,3,49,28,179,201,95,10,0,208,243,70,216,50,248,4,12,120,58,148,221,65,65,128,226,255,190,17,42,30,188,11,244,231,158,145,16,2,62,63,107,29,204, -26,249,208,208,29,221,162,34,196,67,225,196,223,145,159,218,69,117,80,118,231,109,80,241,215,187,128,159,59,75,97,227,255,193,108,127,180,254,8,146,30,17,160,92,117,128,192,105,96,221,242,233,112,237,217,243,97,254,180,18,118,91,71,162,18,91,211,167, -70,62,22,63,182,145,223,211,80,63,53,250,244,239,202,139,12,112,241,234,217,112,245,153,117,172,230,95,73,232,152,223,167,187,255,0,33,41,192,202,254,228,66,27,191,29,121,162,255,86,75,151,123,2,175,162,99,231,27,15,193,223,49,119,186,70,143,60,217,255, -147,115,191,187,228,177,176,87,222,120,94,58,139,58,34,133,225,169,174,123,224,199,167,221,15,5,66,177,162,251,168,59,117,37,84,144,45,218,209,11,225,125,135,32,210,218,5,210,132,133,24,251,196,67,128,214,245,115,213,149,160,93,186,0,244,231,156,14,250, -211,87,179,164,63,165,57,145,237,143,97,127,4,73,179,8,104,133,191,93,191,10,102,148,232,21,123,255,233,21,5,100,155,7,118,34,46,134,45,94,152,116,248,193,19,136,48,99,79,195,2,28,17,10,116,157,191,178,212,0,115,170,139,97,54,217,120,78,157,7,193,43, -253,143,64,191,187,131,60,75,229,151,18,210,134,63,99,13,142,205,245,207,244,63,131,87,15,10,128,143,165,254,233,190,199,235,206,173,190,118,218,138,178,79,71,131,242,18,98,232,196,192,81,111,31,188,216,251,87,248,230,178,159,170,178,159,218,229,139, -216,198,30,6,212,227,103,229,130,84,0,8,160,41,44,80,245,24,97,111,127,4,201,188,72,128,210,34,128,66,215,241,19,107,249,213,44,2,112,188,92,144,227,64,209,129,62,31,7,173,172,218,49,246,10,24,5,249,235,254,26,94,3,98,72,180,236,252,67,219,247,164,40, -198,254,63,228,176,226,33,248,48,98,36,70,151,2,190,151,236,82,0,189,96,247,143,111,133,221,227,91,84,223,103,218,48,136,54,15,226,202,74,82,96,252,247,98,182,63,130,100,168,8,80,178,58,224,31,161,30,190,129,124,22,221,82,97,252,39,2,35,240,124,207,253, -228,115,181,178,187,253,49,135,172,64,128,195,79,244,221,98,233,118,143,225,21,131,2,224,223,98,238,112,141,29,121,178,239,7,218,130,100,2,36,26,208,242,122,216,216,251,144,242,249,0,105,34,145,237,143,97,127,4,201,88,17,160,112,117,64,186,8,75,33,120, -162,243,247,224,139,186,65,208,200,127,14,83,227,111,106,114,188,80,255,204,192,179,120,165,160,0,56,105,14,63,222,251,220,224,62,243,179,201,148,6,210,132,149,72,44,124,226,66,206,122,227,143,189,253,17,36,59,34,1,89,46,2,54,246,61,8,189,174,22,150, -84,45,219,184,9,28,157,244,55,186,237,174,150,31,96,232,31,5,192,212,110,40,114,71,237,250,99,251,15,66,158,232,16,29,25,41,91,129,114,122,48,249,6,225,233,238,123,21,237,15,144,90,227,191,151,213,249,99,216,31,65,178,41,18,16,202,202,239,177,119,252, -13,216,101,218,156,212,186,63,133,150,116,31,120,168,235,59,246,126,175,5,175,14,20,0,83,198,57,226,183,239,190,183,253,38,65,199,199,146,49,124,244,66,62,98,222,1,111,14,61,149,149,198,159,102,251,163,231,143,32,89,36,2,88,179,160,86,48,101,89,36,160, -207,221,198,146,167,169,227,148,204,186,191,190,88,11,29,111,142,221,215,242,202,200,91,120,85,160,0,144,13,185,136,182,117,189,99,250,189,190,40,185,81,150,116,94,192,235,131,79,66,131,117,79,118,121,254,88,234,135,32,89,43,2,254,227,229,86,176,248, -35,89,177,223,174,176,13,254,214,241,91,136,198,194,192,37,81,239,47,232,121,234,188,213,239,189,191,243,103,120,53,160,0,72,154,157,247,180,253,175,173,207,187,95,48,200,191,40,53,228,80,107,52,28,60,221,245,71,24,243,245,103,252,119,110,125,249,8,51, -254,186,2,236,240,135,32,217,40,2,138,136,8,104,157,244,192,247,183,116,64,40,195,39,222,70,99,17,120,188,243,183,96,14,140,129,150,147,95,202,168,225,52,180,121,145,111,251,111,91,190,225,183,133,130,120,37,160,0,72,154,144,39,26,125,239,215,205,223, -136,137,49,135,38,137,210,64,58,47,192,39,122,224,209,142,95,131,55,234,202,216,239,59,209,58,10,77,47,30,2,45,107,239,139,214,31,65,178,149,98,189,0,187,7,29,240,199,189,131,25,189,159,47,245,61,8,109,246,195,96,16,146,43,99,214,23,9,112,228,169,254, -91,70,14,219,218,240,236,163,0,80,208,40,58,251,14,61,214,251,93,93,65,114,189,147,244,156,1,70,125,253,240,183,142,223,129,20,23,51,238,123,74,17,17,234,159,218,199,166,36,106,56,52,254,8,146,11,34,224,241,250,49,104,24,207,204,225,119,219,70,55,178, -65,63,201,38,253,209,138,173,161,131,214,167,223,127,164,231,17,60,235,40,0,20,231,200,147,125,47,246,238,152,120,32,153,210,64,10,157,102,213,100,219,207,198,7,103,26,131,123,187,193,222,103,6,65,143,77,34,17,36,39,30,242,68,199,135,197,24,252,245,253, -225,140,219,183,102,242,28,220,212,191,158,56,70,201,37,253,241,90,14,124,214,80,251,123,119,181,96,183,63,20,0,234,64,39,72,189,123,103,243,143,236,3,190,131,201,228,3,48,17,64,212,238,182,177,77,240,222,232,75,153,243,253,164,24,244,110,107,7,142,231, -241,100,35,72,14,81,160,229,97,239,160,19,186,172,254,140,217,39,58,225,239,111,157,191,103,9,11,201,36,253,209,72,37,39,112,254,237,191,107,253,170,199,20,240,224,217,70,1,160,26,97,111,52,252,222,175,155,191,34,69,98,214,100,90,5,83,181,75,151,3,54, -245,173,135,122,235,238,140,248,110,206,17,59,56,134,108,192,235,208,251,71,144,92,139,2,248,34,34,108,235,179,101,196,254,56,66,22,88,223,254,75,8,136,94,16,184,228,42,172,104,68,246,224,134,238,239,13,236,49,55,226,153,70,1,160,58,19,173,206,129,125, -127,233,252,166,96,224,227,201,228,200,81,213,75,43,3,158,236,188,27,122,221,173,105,255,94,214,158,73,16,67,81,204,250,71,144,28,132,142,250,61,58,150,254,142,164,65,209,15,27,218,239,4,115,96,20,116,156,252,78,127,52,114,64,235,253,123,119,76,60,120, -232,241,222,39,240,12,163,0,72,25,77,47,13,189,217,242,202,240,255,232,146,236,15,64,251,92,211,190,215,27,218,126,201,134,95,164,19,247,152,3,79,44,130,228,176,0,24,243,132,210,90,18,72,19,159,105,185,31,109,243,107,224,11,18,86,92,38,218,2,30,108,253, -222,125,59,126,223,118,75,150,54,89,69,1,144,205,236,190,183,227,215,163,71,237,155,244,73,38,5,210,186,87,218,4,227,225,214,255,97,63,211,69,216,19,196,204,127,4,201,213,135,189,70,3,254,136,4,193,168,148,182,125,120,182,251,62,168,183,236,78,58,227, -159,23,56,136,248,37,211,187,191,108,250,178,223,22,10,227,217,69,1,144,114,196,176,4,239,252,162,233,91,238,137,96,179,160,79,230,80,198,217,208,11,147,127,16,30,110,251,5,4,68,95,90,190,79,28,147,103,17,36,167,137,39,229,115,39,199,171,3,143,192,110, -211,102,40,16,138,146,122,31,186,236,202,235,184,200,206,63,180,253,159,201,118,215,40,158,85,20,0,105,195,51,17,112,191,251,171,230,47,74,209,184,45,153,161,65,20,26,18,163,161,177,71,219,127,197,166,8,166,26,193,40,64,60,142,177,52,4,201,73,227,31, -167,209,70,13,232,210,16,229,123,103,228,69,120,115,232,25,48,36,233,249,179,231,100,137,142,54,251,249,126,231,91,99,187,241,172,162,0,72,59,163,71,108,93,251,254,210,249,53,94,203,75,201,54,206,163,161,177,38,219,1,54,66,56,22,79,109,168,174,168,166, -20,112,45,13,65,114,19,137,40,128,234,66,29,20,166,184,199,199,158,241,55,224,229,190,135,137,240,48,36,85,235,207,140,63,29,242,179,117,236,190,131,235,187,215,227,25,69,1,144,49,52,189,52,180,181,225,249,129,155,13,165,186,164,223,139,134,200,222,159, -124,15,158,233,254,19,164,210,34,87,45,172,5,13,143,151,4,130,228,34,81,41,6,43,107,139,83,90,228,115,216,188,13,158,35,207,49,158,211,2,167,73,238,217,66,199,251,78,116,184,222,216,241,251,214,219,176,217,15,10,128,140,99,223,95,187,30,104,127,125,244, -207,180,31,181,18,34,128,206,196,166,163,49,83,69,245,226,90,40,170,46,134,152,136,55,23,130,228,26,60,199,193,69,11,42,83,246,121,116,242,233,19,93,247,176,82,103,94,147,92,115,49,58,225,47,232,138,180,188,249,211,250,175,134,220,105,204,98,68,1,128, -124,28,49,162,74,183,255,182,245,150,201,118,215,230,100,103,6,80,232,114,192,187,35,47,178,65,25,169,128,142,253,157,123,206,66,16,195,81,60,153,8,146,67,208,210,191,101,213,133,112,206,156,178,148,124,30,29,236,243,88,199,93,16,139,199,136,241,79,238, -89,72,219,252,70,2,226,196,27,63,173,191,222,109,10,184,240,108,162,0,200,88,200,133,26,219,114,219,209,175,186,70,253,135,105,200,42,25,232,122,25,77,154,121,103,248,5,216,60,240,120,74,246,127,233,149,171,193,88,94,8,49,9,163,0,8,146,51,207,37,114, -63,127,235,204,217,228,121,162,254,35,191,205,113,24,214,183,255,2,164,152,200,250,156,36,245,12,228,52,52,227,63,176,231,190,142,207,155,26,29,125,120,38,81,0,100,60,62,107,200,251,206,157,205,55,132,189,209,1,170,94,147,23,1,5,176,101,240,137,148,136, -128,194,234,98,88,245,185,51,18,29,1,17,4,201,122,188,97,9,46,93,88,5,215,173,168,77,137,231,191,190,245,23,16,149,34,73,183,248,165,9,213,196,137,138,239,188,167,237,27,237,175,143,238,195,51,137,2,32,107,24,111,118,140,190,241,211,250,235,136,253,182, -39,51,51,224,67,34,96,40,53,34,96,217,149,171,97,193,249,75,33,226,199,254,26,8,146,173,208,167,78,32,42,193,156,50,3,220,117,217,98,224,53,234,166,255,29,247,252,163,177,228,141,63,133,182,249,109,121,121,248,135,77,47,13,109,196,179,137,2,32,235,24, -61,106,111,222,125,111,251,231,121,29,31,212,40,33,2,248,2,120,125,232,73,216,212,247,176,202,79,14,13,156,253,159,151,192,172,181,117,40,2,16,36,75,241,19,227,95,83,168,131,245,159,89,9,179,74,13,42,123,254,135,96,125,219,47,21,241,252,41,116,192,15, -49,254,119,237,184,187,237,126,60,147,40,0,178,150,230,77,195,59,118,254,161,237,27,188,150,139,37,219,102,151,77,16,228,141,176,117,248,89,213,171,3,180,70,45,92,248,163,79,193,194,139,150,65,36,16,134,120,12,27,4,32,72,182,64,195,254,75,170,10,225, -169,207,175,134,85,211,139,85,253,44,154,237,255,80,219,255,18,207,63,172,152,231,63,124,200,246,200,182,187,90,254,31,62,119,80,0,100,191,8,216,56,244,82,253,51,3,223,165,77,44,146,45,194,61,158,24,248,238,200,11,240,116,247,31,33,14,234,37,235,9,6, -45,124,226,7,151,195,25,95,63,143,117,8,148,34,88,125,131,32,153,76,140,220,167,158,176,8,87,47,173,134,23,190,116,42,44,175,41,82,245,243,14,153,183,193,163,29,191,97,67,126,4,141,50,158,255,120,179,99,211,219,255,211,248,159,216,148,20,5,64,206,176, -255,161,174,245,205,155,134,126,202,68,64,146,28,23,1,187,198,94,131,199,59,126,11,98,44,162,234,190,175,248,204,90,184,248,167,215,64,65,101,17,68,131,17,60,153,8,146,97,80,191,34,44,198,128,22,239,220,126,193,2,88,255,217,149,80,89,160,85,245,51,247, -140,191,14,127,235,248,29,113,14,98,202,24,255,2,129,142,90,127,119,243,173,71,190,22,112,132,209,219,64,1,144,59,196,165,56,108,187,171,245,247,45,47,15,255,198,80,162,76,36,192,40,20,193,254,137,183,217,218,91,72,10,168,186,255,51,214,204,129,203,127, -117,253,137,188,0,12,205,33,72,230,224,33,246,114,122,137,30,30,189,254,20,248,239,117,115,85,255,188,119,70,94,128,103,186,238,101,221,253,146,173,243,63,110,252,29,67,190,3,91,110,61,250,185,160,51,18,196,51,138,2,32,247,68,64,156,137,128,59,90,94, -25,254,179,18,141,130,40,180,99,96,131,117,47,252,165,229,103,224,137,56,84,221,127,218,37,240,226,219,175,129,83,191,116,14,19,0,82,68,196,147,138,32,105,68,138,197,153,241,191,124,113,21,108,250,242,169,112,209,252,10,213,63,243,149,129,71,96,99,223, -67,32,112,58,34,0,248,164,223,143,118,249,11,56,195,245,239,252,162,233,51,228,167,7,207,42,10,128,220,22,1,191,105,249,225,240,251,214,13,74,44,7,80,104,199,192,46,103,35,252,169,249,199,96,14,142,169,186,255,52,145,113,245,23,206,34,66,224,106,40,174, -45,133,72,0,151,4,16,36,29,4,163,49,208,104,52,240,255,46,156,15,143,17,207,127,70,137,186,153,254,116,157,255,169,174,63,192,27,131,79,177,100,228,100,123,251,31,55,254,33,79,164,117,243,173,71,62,61,217,225,178,226,89,69,1,144,7,34,0,224,237,255,109, -250,142,169,217,241,152,174,72,153,72,0,45,17,28,245,246,193,125,141,183,193,160,167,83,245,239,48,99,205,92,184,252,215,55,192,130,243,151,64,52,24,197,249,1,8,146,194,231,7,77,244,91,82,93,8,207,124,97,53,252,215,57,115,85,31,240,19,20,125,240,112, -219,47,216,124,18,26,117,212,40,240,137,204,248,187,35,237,196,248,127,106,178,205,101,194,51,139,2,32,111,8,56,194,113,114,225,127,107,162,197,249,24,205,124,85,74,4,216,195,22,248,115,243,79,160,217,118,64,245,239,96,44,43,128,243,110,190,2,214,125, -247,18,208,21,234,48,65,16,65,84,38,44,197,32,68,182,111,172,157,197,66,254,103,206,42,85,253,51,237,33,51,121,166,252,20,26,44,187,153,241,87,130,99,158,127,223,230,219,142,92,75,140,255,24,158,89,20,0,121,71,208,25,1,34,2,110,154,104,117,62,166,47, -82,98,57,32,14,58,78,15,33,49,192,212,250,110,211,150,148,124,143,69,151,174,128,203,127,117,3,204,60,117,30,68,3,17,156,35,128,32,74,123,253,64,107,251,69,152,81,108,128,245,159,89,193,58,251,149,24,4,213,63,119,216,219,13,127,106,186,21,250,220,173, -44,233,88,17,227,111,96,158,127,31,121,246,93,73,140,255,0,158,93,20,0,249,44,2,226,91,110,61,122,211,120,139,67,33,17,0,172,25,7,13,208,61,211,125,47,188,220,191,158,60,60,212,207,216,47,157,89,14,151,222,241,105,56,227,155,231,131,160,19,216,178,0, -130,32,201,67,7,249,208,245,254,207,175,154,14,175,126,229,52,184,98,113,117,74,62,183,201,182,15,238,107,250,17,88,130,38,48,240,133,202,121,254,238,72,219,230,219,142,94,65,140,63,14,247,65,1,128,4,156,97,34,2,142,220,52,214,104,87,44,39,128,102,231, -234,120,3,188,53,244,12,108,104,187,19,2,162,79,253,47,66,84,199,242,107,79,133,203,239,188,30,102,174,153,131,209,0,4,73,198,235,143,39,188,254,233,197,122,248,235,181,203,225,79,87,45,131,154,34,93,74,62,251,189,209,151,224,225,182,95,66,80,12,128, -142,51,28,139,65,40,96,252,19,9,127,196,243,119,246,227,25,70,1,128,156,16,1,145,248,43,223,123,255,91,109,175,141,254,89,169,234,128,227,189,2,14,155,183,49,37,111,14,140,166,228,187,148,207,171,130,75,127,254,105,56,235,166,11,65,87,160,99,66,0,176, -109,0,130,156,52,33,49,198,214,251,255,207,154,153,240,234,87,215,194,53,203,106,82,242,185,98,44,10,207,246,252,137,181,26,231,200,243,67,137,214,190,20,109,129,64,141,255,209,99,9,127,184,230,143,2,0,249,167,155,47,28,131,109,191,105,254,97,203,43, -195,191,99,205,130,20,130,138,0,90,25,240,135,198,91,216,208,142,148,160,209,192,210,79,173,134,43,126,243,57,152,119,238,98,16,35,81,144,162,216,220,11,65,254,21,137,186,126,17,22,87,21,178,210,190,187,175,92,194,6,250,164,2,71,216,10,247,55,255,20, -182,143,190,114,172,204,143,87,228,125,89,147,159,65,239,62,52,254,40,0,144,127,3,13,251,189,119,87,203,237,68,4,252,92,137,217,1,199,161,55,52,109,20,244,215,214,59,88,120,47,85,148,76,47,131,11,110,187,18,46,184,229,74,40,158,86,138,93,4,17,228,163, -238,123,178,249,35,18,104,121,14,110,62,183,14,94,249,202,105,112,201,130,202,148,125,126,175,171,5,254,216,120,51,116,56,143,42,86,230,199,140,127,161,0,19,109,206,119,55,126,231,224,213,196,248,99,157,127,134,33,224,33,200,204,167,193,182,223,180,252, -154,136,1,247,170,235,230,222,31,241,139,138,24,77,45,167,131,88,92,130,23,122,255,2,38,223,32,124,113,209,247,216,76,129,84,48,119,221,34,152,182,106,54,180,191,90,15,93,239,180,178,101,1,58,113,16,65,242,29,218,195,95,36,55,251,165,11,171,224,182,243, -234,96,69,109,81,74,63,159,86,11,209,206,126,116,154,31,45,37,86,10,58,213,143,14,246,161,189,253,177,189,47,10,0,100,138,145,0,34,2,30,112,12,120,29,231,255,112,249,99,98,36,166,167,243,4,146,133,134,245,140,124,33,236,25,127,3,76,254,65,248,198,178, -31,195,204,194,249,41,249,78,250,34,3,156,246,213,115,97,238,185,139,160,249,133,67,48,86,63,200,58,11,242,58,188,12,145,252,67,36,162,62,16,149,88,67,159,31,174,171,131,79,47,175,73,233,231,135,165,32,188,212,247,32,19,0,90,78,207,54,69,208,36,194,254, -195,7,45,27,182,254,188,233,187,196,248,227,218,95,134,130,75,0,25,78,195,243,131,207,238,252,67,251,117,130,158,119,241,130,114,167,139,134,249,134,60,93,240,199,134,155,225,176,121,123,74,191,83,229,252,26,184,248,103,215,192,249,183,94,9,101,179,43, -33,26,8,99,39,65,36,111,136,29,203,238,47,212,241,240,163,243,231,195,230,175,174,77,185,241,31,39,226,255,222,166,219,96,231,216,107,108,121,144,87,104,189,95,67,140,63,93,186,108,123,109,228,174,87,126,112,248,219,1,39,78,245,195,8,0,146,20,205,27, -135,222,242,154,131,87,92,118,199,234,141,250,18,237,108,49,164,204,61,69,111,252,160,228,135,71,219,127,13,3,158,78,184,126,193,77,202,121,1,39,193,188,117,139,96,214,105,243,160,251,237,22,232,120,179,9,2,54,47,8,6,29,139,10,32,72,174,65,227,119,1, -226,12,235,137,144,255,194,170,25,108,106,95,93,185,49,229,251,241,190,249,61,120,177,231,175,224,139,186,20,235,236,199,140,63,185,111,181,70,62,222,180,113,248,230,29,191,107,249,115,28,83,125,80,0,32,202,48,176,199,124,232,245,159,28,189,232,83,191, -62,109,83,97,165,126,77,84,33,17,192,107,180,192,241,2,188,59,242,34,235,250,245,149,197,55,195,204,162,249,169,187,0,13,90,88,241,153,181,48,239,19,139,161,227,245,70,232,219,209,1,17,95,24,4,163,150,13,58,65,144,92,128,54,242,161,92,180,160,18,254, -251,156,185,112,70,10,90,248,254,35,52,228,255,114,255,6,230,245,243,156,192,28,0,165,224,181,28,221,252,59,239,105,187,177,233,165,161,151,240,140,103,7,184,4,144,69,152,26,29,253,47,126,107,255,165,214,94,207,219,74,150,9,210,140,95,234,9,244,185,90, -225,15,141,55,195,190,137,183,82,254,221,10,171,138,89,23,193,43,127,243,57,88,120,209,50,230,46,177,110,130,232,70,32,89,12,173,231,167,217,253,167,205,44,129,71,174,91,9,79,125,110,85,90,140,255,144,183,139,221,219,219,70,55,129,142,215,131,160,81, -206,247,163,13,126,196,144,100,122,239,55,205,87,162,241,71,1,128,168,136,103,34,104,223,124,203,145,79,15,236,53,111,160,173,131,149,116,146,169,71,16,146,2,240,68,231,221,240,120,231,111,193,27,117,165,252,251,149,205,169,132,115,191,127,25,92,246, -203,235,96,238,217,11,32,38,197,201,195,37,138,141,132,144,172,130,102,246,123,195,18,44,175,41,130,63,95,179,140,13,238,185,108,81,85,90,246,133,26,253,123,27,111,133,33,79,183,162,37,126,20,173,129,117,247,107,220,114,219,145,139,219,54,143,238,197, -51,159,93,224,18,64,22,226,179,134,34,175,221,114,228,219,151,252,244,148,193,149,215,206,249,173,68,60,140,152,164,140,133,228,137,103,192,243,60,236,31,223,10,3,238,14,248,226,162,255,134,149,149,103,166,252,59,86,47,158,6,23,254,248,42,48,119,152, -160,125,115,3,152,26,135,89,91,97,173,94,0,192,165,1,36,131,61,126,154,221,79,13,255,55,215,206,130,235,86,214,18,97,157,30,63,203,30,154,132,23,123,255,2,245,214,61,172,157,175,158,55,40,250,254,180,204,207,220,238,218,242,214,29,13,223,112,142,248, -157,120,246,81,0,32,41,130,150,4,110,251,77,203,239,156,195,190,254,79,252,215,178,71,52,92,188,84,138,42,149,73,79,91,8,23,130,53,56,14,127,105,253,25,92,50,235,122,184,182,238,27,138,174,25,158,44,181,203,103,178,109,178,109,12,58,223,106,6,83,195, -16,72,145,40,8,122,45,38,11,34,25,101,248,105,23,191,149,211,138,225,171,167,206,128,207,46,159,6,70,109,250,2,172,135,204,219,96,83,223,122,112,134,45,172,236,87,73,88,166,127,137,14,58,182,142,221,183,235,158,182,219,2,88,230,135,2,0,73,15,245,207, -12,108,116,12,250,6,47,251,249,234,103,140,101,186,37,74,37,7,82,104,227,160,56,196,224,237,225,231,160,203,217,0,95,88,244,61,88,92,182,58,45,223,115,218,202,89,108,51,119,142,67,247,214,102,24,171,31,98,205,132,4,131,64,132,0,174,100,33,105,16,225, -113,128,160,152,184,223,78,155,81,202,12,63,237,217,175,227,211,119,61,186,194,54,120,165,127,3,28,156,124,143,149,246,41,217,216,135,194,9,28,240,58,46,124,232,241,222,31,238,251,107,215,195,216,213,19,5,0,146,102,6,247,91,142,190,120,211,129,11,174, -249,253,218,191,85,47,41,189,50,236,83,110,205,92,3,28,155,37,48,234,235,131,63,55,255,24,46,153,117,3,92,53,239,43,105,137,6,176,136,192,178,25,108,115,12,88,161,251,221,86,24,121,191,31,130,110,63,8,58,45,123,56,33,136,218,72,196,242,211,172,126,26, -218,63,191,174,2,190,186,102,38,92,186,176,18,248,52,71,164,14,91,118,192,43,125,27,88,228,206,32,20,40,186,214,207,28,2,35,15,17,191,56,178,253,119,45,223,232,120,99,108,39,94,9,40,0,144,12,193,53,234,55,111,250,238,251,215,92,120,219,138,223,45,189, -124,230,109,180,87,128,82,121,1,20,186,134,24,139,199,224,141,161,167,160,221,113,4,110,88,248,29,88,86,126,90,218,190,111,197,252,106,56,231,59,23,195,202,207,172,133,254,157,157,48,176,183,27,188,19,174,132,135,162,21,0,112,117,0,81,152,40,185,159, -66,196,227,47,51,106,225,138,197,213,240,21,98,248,207,154,93,154,246,253,114,132,204,196,235,127,4,14,89,182,3,79,126,25,85,104,239,77,215,251,109,253,222,221,219,126,221,252,245,241,22,231,48,94,13,40,0,144,12,35,232,138,72,91,239,104,252,145,189,207, -219,124,246,77,139,255,194,243,154,82,41,162,92,135,61,78,195,177,44,226,68,52,224,39,112,193,204,107,224,154,121,95,131,34,109,89,218,190,51,29,48,180,230,75,103,195,242,107,214,192,208,129,94,38,6,108,125,22,34,126,36,204,19,64,146,134,134,249,143, -175,239,207,45,55,192,213,75,107,224,115,167,76,135,133,149,5,25,177,127,123,199,223,132,45,131,79,48,17,160,134,215,79,239,31,218,214,183,111,231,228,95,119,220,221,122,171,207,18,10,227,85,129,2,0,201,96,14,63,209,247,140,109,192,219,126,233,237,171, -254,86,88,165,95,77,135,9,41,137,142,211,179,220,128,109,35,155,160,221,126,24,62,61,255,70,56,163,230,226,180,126,103,93,145,1,22,95,118,10,44,186,116,37,76,180,140,66,255,174,78,24,111,26,134,144,59,8,156,150,248,69,90,62,63,47,6,77,90,94,154,245,208, -76,254,96,84,34,70,149,103,117,251,55,172,156,198,188,254,50,99,102,60,50,169,8,127,149,120,253,45,246,247,65,224,116,170,120,253,188,142,3,142,215,120,15,172,239,254,225,161,199,122,30,143,99,183,110,20,0,72,118,48,176,199,220,184,113,232,192,5,151, -220,190,234,254,57,103,86,125,77,169,137,130,127,55,14,28,123,232,216,130,19,176,161,237,78,56,90,189,11,62,51,255,63,96,122,225,220,244,218,59,226,177,204,88,51,135,109,222,73,55,139,10,12,147,205,57,108,99,101,132,130,78,0,13,159,39,185,2,196,125,165, -3,152,228,82,162,23,242,170,226,146,222,30,97,81,2,186,114,54,163,88,15,151,18,79,255,51,43,106,225,204,89,165,25,179,143,180,79,199,59,35,47,192,246,209,151,33,32,250,20,79,242,59,33,168,11,5,32,222,126,203,206,63,180,221,72,188,255,122,124,162,162, -0,64,178,12,231,136,223,253,234,15,14,125,125,221,119,150,28,90,251,229,249,247,196,98,241,2,37,151,4,216,5,68,188,15,1,226,80,111,221,13,93,174,70,184,116,246,13,240,201,217,159,83,237,193,52,21,232,242,192,41,215,157,14,43,174,61,149,69,5,134,246,245, -194,120,243,48,4,28,126,34,2,52,44,87,32,167,151,8,136,33,43,154,38,223,120,213,18,35,104,16,56,22,6,207,85,33,64,37,113,68,140,65,132,136,195,34,34,120,214,205,45,135,107,151,213,178,164,190,234,66,93,70,237,107,3,185,199,104,184,127,212,219,199,146, -112,213,184,199,232,253,160,47,18,96,232,160,245,201,237,191,107,253,129,107,212,239,198,39,41,10,0,36,75,161,6,127,239,253,157,15,78,182,187,234,47,188,121,197,250,162,90,131,226,75,2,52,30,64,31,70,81,41,12,175,245,63,10,245,150,221,112,205,188,175, -195,218,154,11,50,226,24,112,2,15,51,79,155,199,182,128,221,199,74,8,135,15,246,129,173,119,18,34,254,48,75,28,164,203,4,185,54,123,128,126,167,202,186,106,217,175,159,87,110,132,154,34,61,76,120,195,160,205,161,99,67,141,62,77,232,163,222,190,142,156, -251,197,213,133,240,201,133,85,112,229,146,106,88,81,83,148,113,251,59,234,235,135,215,137,225,111,178,238,35,215,104,162,42,71,13,88,200,159,211,120,15,61,222,123,219,193,13,61,27,148,118,22,16,20,0,72,154,232,221,62,113,104,178,205,121,254,197,63,57, -229,158,5,23,76,251,191,209,128,168,104,149,0,51,56,26,158,61,156,38,252,195,240,112,251,47,96,213,228,57,44,73,112,94,201,210,140,57,14,5,149,69,176,248,178,149,108,115,141,218,97,244,200,32,17,4,131,172,172,48,26,140,228,140,24,160,227,149,139,170, -139,161,124,158,124,1,80,164,227,225,212,233,37,48,228,52,131,86,151,221,57,20,39,140,62,237,38,73,188,220,185,101,70,184,96,126,5,92,177,168,10,78,159,85,154,214,218,253,143,195,19,113,194,123,163,47,193,110,211,150,99,225,126,35,168,149,153,65,179, -252,157,35,190,195,59,239,110,251,54,241,254,155,240,137,137,2,0,201,49,188,230,144,103,243,45,71,190,125,214,127,44,218,117,198,215,23,222,167,53,242,53,209,160,242,77,188,104,3,33,250,200,109,182,237,135,110,103,3,172,155,126,37,92,62,231,139,80,105, -168,205,168,227,81,54,187,146,109,116,153,192,222,111,97,93,6,105,203,97,154,47,64,155,12,209,92,1,154,60,152,141,203,4,98,88,132,89,107,235,64,107,76,110,104,20,157,83,255,90,135,57,59,141,62,177,250,52,180,79,55,106,224,231,150,27,97,221,156,114,214, -147,159,26,253,162,12,21,53,98,44,10,123,39,222,100,19,58,45,1,147,106,225,126,38,218,137,224,165,253,252,59,223,28,187,119,239,3,157,63,247,89,67,1,124,82,162,0,64,114,152,67,143,245,62,63,114,216,118,248,194,91,87,60,48,99,85,249,149,97,175,72,30,150, -74,119,244,74,44,11,208,222,1,52,97,169,193,178,7,46,158,245,89,184,112,214,103,20,157,65,174,20,149,11,106,216,182,234,115,103,130,99,200,6,19,45,35,48,78,196,128,99,208,10,33,79,144,125,31,42,6,56,234,41,102,184,30,160,201,158,250,34,61,44,190,252, -148,164,223,235,130,186,10,56,117,70,9,52,79,120,192,152,5,149,20,180,92,143,122,249,244,103,161,78,128,165,53,69,112,238,220,114,184,136,120,251,107,166,151,144,63,203,236,239,208,96,221,3,91,135,159,99,115,56,180,42,101,247,31,135,150,247,5,221,145, -161,189,127,238,248,126,211,198,161,215,241,201,152,127,104,226,105,26,183,26,137,68,96,201,146,37,48,52,52,132,103,33,77,208,100,159,117,223,89,114,203,170,235,230,253,138,78,4,22,195,234,181,244,150,226,34,241,196,194,48,163,112,46,92,58,251,115,176, -110,250,229,228,1,167,207,130,168,137,27,44,29,227,48,78,4,129,173,199,12,126,155,7,232,240,37,22,29,32,222,83,38,86,20,68,124,97,88,249,217,181,112,250,55,206,83,228,253,118,15,58,224,107,27,91,88,231,187,76,11,134,196,200,243,139,134,246,169,151,79, -59,241,85,21,232,96,101,109,17,75,230,163,134,159,10,0,109,22,68,112,104,171,109,106,248,59,28,245,108,249,73,167,226,189,193,241,26,208,18,227,111,106,180,63,183,243,158,182,91,45,221,158,73,124,26,166,143,13,27,54,192,77,55,221,132,2,0,73,15,243,214, -213,156,122,254,15,150,61,80,181,176,228,220,136,79,141,104,192,223,161,225,205,104,60,2,243,138,151,194,101,115,62,199,250,7,208,220,129,108,128,46,11,56,134,172,108,48,17,157,73,224,26,177,179,62,3,113,98,124,50,69,16,68,67,81,150,248,119,217,157,215, -17,15,79,57,35,242,203,237,125,240,208,161,17,40,51,164,55,104,120,220,224,71,143,149,180,210,82,197,186,10,35,235,197,127,206,156,50,22,173,152,94,172,207,154,123,143,122,250,239,142,190,8,77,214,253,76,36,39,38,246,169,39,88,104,59,223,104,72,154,60, -250,84,255,79,142,60,217,255,20,205,21,65,80,0,160,0,200,247,104,64,177,86,183,238,255,46,254,241,170,235,231,254,140,184,32,70,53,163,1,204,80,197,194,108,121,96,126,233,10,184,116,246,245,176,182,250,66,214,105,48,155,160,21,5,116,137,128,138,1,123, -159,25,220,99,78,8,121,2,32,145,135,42,71,188,78,238,152,32,72,85,66,161,72,140,127,97,117,49,92,122,199,167,161,116,86,133,178,247,43,17,57,255,181,185,3,222,232,178,64,105,138,68,0,125,52,73,199,12,190,24,35,199,148,28,71,250,217,115,202,140,112,202, -180,98,214,160,135,134,245,235,202,141,105,239,195,63,85,70,188,61,196,240,191,196,150,198,34,228,94,160,235,252,26,21,13,255,9,175,191,193,254,202,238,251,58,110,157,108,119,225,131,23,5,0,10,0,228,159,162,1,167,159,255,253,101,127,172,90,84,114,190, -210,205,131,62,242,58,32,15,191,248,9,33,112,3,17,2,231,103,77,68,224,159,4,129,195,207,162,2,54,34,6,236,3,22,112,143,58,200,159,249,152,87,78,187,204,208,222,3,52,135,128,78,47,84,52,177,144,38,187,5,195,80,54,171,18,46,184,237,83,80,62,183,82,149, -239,71,59,227,221,250,86,23,188,218,110,102,9,116,74,26,221,227,198,158,118,224,163,27,253,127,131,150,131,170,2,45,204,43,47,96,97,125,234,221,175,168,45,134,57,165,134,172,51,248,31,52,252,219,198,18,57,49,180,169,143,218,134,63,225,245,11,228,26,20, -39,234,159,238,255,201,225,39,250,159,70,175,31,5,0,10,0,228,95,69,3,248,117,223,94,124,243,170,235,230,222,65,172,113,169,24,82,127,220,247,7,133,0,77,22,92,91,125,1,8,156,54,171,143,35,245,200,125,22,15,56,137,40,160,101,134,180,236,144,118,39,12,186, -252,16,13,70,217,210,1,125,246,127,80,20,76,73,24,144,91,87,140,136,204,122,206,57,123,33,156,245,173,11,192,88,94,168,234,119,162,79,139,251,15,12,195,67,135,134,193,75,174,139,2,29,7,252,20,34,28,84,79,210,48,190,116,204,208,211,223,83,207,222,72,140, -125,185,81,203,188,251,69,149,133,176,172,166,136,108,133,196,187,47,128,202,2,109,214,223,83,253,158,118,150,12,219,98,59,64,12,127,16,244,156,129,213,244,171,9,39,104,64,208,243,96,106,114,60,179,231,79,29,183,79,118,184,198,240,233,134,2,0,5,0,114, -82,204,60,181,114,217,39,190,183,244,247,51,215,84,92,163,70,223,128,143,19,2,177,184,4,115,139,23,195,5,51,175,101,57,2,106,102,66,167,26,26,13,8,218,125,224,153,116,129,107,196,1,158,113,39,75,52,164,203,9,33,111,8,196,96,132,181,44,102,150,86,147, -16,4,116,57,225,120,43,62,122,191,198,99,177,19,109,141,171,22,77,131,101,87,175,129,185,68,0,164,146,118,179,15,30,62,60,2,59,251,137,184,33,98,134,138,0,129,238,43,221,79,77,66,41,80,143,254,184,177,167,80,175,157,86,18,148,234,5,214,101,112,22,241, -228,23,84,20,16,131,95,0,117,228,231,172,18,3,84,228,128,177,255,32,29,142,163,176,211,244,26,155,153,145,8,245,27,88,27,109,117,159,234,199,50,252,157,145,158,131,143,244,252,164,245,149,225,215,82,113,239,34,40,0,80,0,228,24,212,131,56,253,107,11,190, -118,218,151,234,238,212,23,107,231,70,2,98,194,56,169,109,40,99,17,98,64,162,48,173,96,46,156,59,253,74,56,103,218,101,80,166,175,202,217,227,28,9,132,33,228,10,130,223,230,5,159,213,3,126,139,135,252,244,38,132,129,39,200,234,250,169,93,229,137,241, -44,172,44,130,202,133,181,48,99,205,92,168,89,58,61,173,251,61,224,8,176,42,129,35,99,110,24,38,251,239,9,137,236,242,160,98,128,122,244,53,133,58,152,73,12,253,76,98,220,231,150,25,96,6,249,89,91,164,135,10,242,119,185,218,94,152,94,187,180,107,223, -238,241,215,161,215,213,66,174,99,233,152,225,215,164,228,126,229,120,77,164,115,171,233,254,131,27,186,239,114,155,2,78,124,138,161,0,64,1,128,36,69,213,130,226,234,115,190,189,248,127,23,92,56,253,59,113,41,198,139,225,212,172,35,178,170,1,242,64,45, -55,84,195,233,53,23,50,49,48,187,104,97,94,29,123,41,34,130,36,74,204,124,112,90,33,99,39,27,82,143,63,16,137,17,1,16,103,17,129,66,93,126,77,96,244,68,28,112,200,188,29,14,78,190,195,250,245,83,131,175,229,245,41,49,252,199,147,252,172,61,158,157,196, -240,255,180,111,231,228,97,124,106,161,0,64,1,128,40,202,162,139,167,175,35,66,224,174,170,5,37,23,68,137,183,23,19,83,115,253,80,47,42,34,133,216,114,192,242,138,51,224,19,68,8,172,168,60,131,24,26,236,101,133,164,23,58,154,247,224,196,59,112,212,178, -27,236,161,73,150,187,146,232,134,153,138,39,120,34,220,31,114,71,71,27,95,28,252,101,195,115,3,143,71,252,34,198,251,81,0,156,20,248,244,68,166,68,239,142,137,3,195,135,172,23,157,254,149,5,223,92,117,195,220,255,49,150,233,230,210,118,194,106,87,11, -240,108,206,64,33,241,45,99,208,104,221,3,77,182,125,48,167,104,17,156,53,237,18,86,66,88,97,168,193,147,131,164,206,129,33,98,180,213,126,136,121,251,93,206,70,8,138,126,208,17,111,63,149,249,42,130,129,167,249,33,225,222,237,19,15,30,220,208,243,59, -251,128,215,130,103,6,65,1,128,168,251,240,35,30,198,129,245,221,143,183,191,62,186,101,221,119,150,220,182,240,226,105,223,19,244,124,161,26,115,5,254,217,225,225,88,233,212,113,207,107,176,167,19,222,30,126,1,78,169,60,155,136,129,75,97,113,217,106, -38,22,16,68,13,198,253,67,112,196,178,19,26,136,183,63,238,31,6,154,16,147,106,195,79,167,246,209,181,254,137,22,199,235,71,158,232,255,69,223,238,201,6,60,51,136,172,231,41,46,1,32,201,50,235,180,202,229,68,8,252,124,198,234,138,47,210,210,54,49,197, -99,68,105,213,0,205,176,22,52,2,204,46,94,8,107,107,46,132,211,170,206,131,154,130,89,120,114,144,164,241,139,94,104,35,222,254,17,243,14,232,113,53,131,63,234,101,33,254,84,151,169,210,178,62,26,238,183,15,250,26,27,95,24,252,69,251,150,145,45,169,202, -197,65,212,3,115,0,144,156,96,197,53,179,47,62,253,107,11,126,94,89,87,124,33,237,36,40,69,83,251,112,162,201,103,52,105,144,110,197,186,82,88,84,182,10,78,175,185,8,150,87,156,14,197,218,50,60,65,200,73,35,198,69,232,119,181,194,81,235,110,102,252,173, -193,9,150,202,71,123,244,107,82,220,177,146,150,130,234,10,120,240,217,194,67,29,111,140,221,93,255,108,255,99,65,39,121,128,34,40,0,146,4,151,0,16,197,104,127,125,116,71,239,246,137,29,203,175,154,245,185,83,191,84,119,123,197,188,162,83,105,217,96, -170,18,5,89,214,53,241,204,232,22,145,34,172,191,122,163,117,31,27,67,76,69,192,169,213,231,193,162,210,85,57,213,87,0,81,86,64,14,123,186,161,201,182,31,90,236,239,195,184,111,144,85,160,208,16,191,225,216,178,83,170,13,63,235,221,31,148,108,29,111, -154,30,56,248,72,207,95,220,99,126,7,158,41,4,5,0,146,145,80,131,223,180,113,104,99,207,246,137,45,167,125,185,238,235,203,175,158,125,107,81,181,97,113,52,152,58,33,64,161,115,5,142,231,10,120,34,78,216,59,254,38,236,159,120,27,170,13,51,136,24,88,11, -171,170,214,193,162,178,83,84,155,179,142,100,7,116,30,133,201,63,0,45,182,131,208,74,140,254,136,183,15,194,82,144,133,247,143,111,169,183,252,0,58,214,190,87,242,118,110,29,219,208,248,252,224,159,205,157,238,81,60,91,136,226,151,26,46,1,32,106,82, -60,205,88,188,250,250,185,55,18,33,240,125,34,4,230,167,178,116,240,163,160,161,93,81,138,0,199,241,80,99,156,1,139,203,214,192,41,149,103,193,66,34,6,112,153,32,63,160,94,253,136,183,151,133,246,219,29,71,136,0,24,132,144,24,32,198,94,32,155,46,37,117, -251,31,103,248,181,6,158,118,125,12,14,236,49,63,121,232,177,158,123,137,225,239,197,51,150,219,96,14,0,146,15,66,160,116,245,13,243,190,189,226,234,89,223,45,172,50,204,77,183,16,56,33,6,136,49,160,149,5,21,134,106,168,43,89,14,43,42,78,103,162,160, -22,19,8,115,10,111,196,5,3,158,14,98,240,15,179,68,62,115,96,12,34,82,248,132,151,159,54,163,15,137,80,63,45,233,131,88,60,56,86,111,127,166,254,249,193,251,6,247,153,59,240,172,161,0,64,1,128,228,154,16,40,95,125,253,220,175,46,191,102,246,127,23,85, -27,22,166,122,105,224,227,160,141,134,168,24,160,235,192,133,66,49,204,44,170,99,66,96,73,249,26,214,111,160,80,91,130,39,47,139,160,137,160,180,100,175,215,221,2,93,142,70,24,246,118,131,43,108,99,21,35,212,203,231,137,183,159,78,163,127,220,240,211, -53,254,72,64,244,142,55,57,158,109,222,56,252,192,0,26,126,20,0,40,0,144,60,16,2,37,171,111,152,251,229,229,87,207,254,175,162,42,195,74,49,34,129,20,201,140,146,38,186,46,44,198,163,32,197,68,230,29,150,235,171,97,78,241,34,86,85,176,176,116,37,204, -40,156,119,34,191,0,129,140,57,103,150,160,137,24,250,46,232,118,54,195,160,167,147,253,63,13,237,211,124,16,102,244,51,164,63,4,107,219,203,12,191,100,239,219,57,249,100,195,243,3,15,89,186,220,125,120,22,81,0,160,0,64,242,75,8,212,26,13,11,47,154,118, -253,170,207,206,249,110,229,130,146,117,146,72,140,111,88,74,201,192,161,147,35,126,44,58,16,101,70,134,14,117,169,48,212,194,172,162,5,176,160,116,5,212,149,44,133,105,5,115,160,72,91,138,39,51,149,207,143,88,24,44,1,106,240,123,136,177,239,128,33,79, -55,51,248,196,153,102,127,47,104,180,25,225,229,127,200,240,11,28,51,252,62,75,112,116,232,128,245,177,166,141,67,143,17,195,143,35,122,81,0,96,25,32,146,159,120,205,193,80,227,11,131,207,182,111,25,125,118,249,85,179,174,88,122,197,204,255,154,182,162, -236,83,26,226,182,69,67,234,183,24,62,9,141,204,230,13,240,188,112,76,14,196,193,22,156,0,115,96,148,53,134,209,242,58,40,213,85,194,116,34,2,102,23,47,130,121,197,75,88,132,128,150,30,234,136,88,64,148,144,96,113,112,134,173,48,233,31,129,17,95,47,43, -213,163,137,123,142,144,5,66,82,128,253,27,122,142,104,35,168,140,171,234,32,250,67,208,113,204,248,123,38,130,205,221,239,152,30,109,222,52,252,28,185,238,177,156,15,73,59,40,0,144,204,240,232,18,229,131,111,55,109,26,122,123,193,249,211,78,95,113,237, -236,155,230,156,81,121,131,190,72,91,193,242,4,50,100,158,57,245,40,89,226,24,104,79,24,39,58,5,206,73,140,17,237,13,79,195,205,180,207,0,29,93,92,107,156,77,68,193,2,152,89,56,159,37,21,210,121,5,5,66,49,158,236,127,227,217,187,195,118,230,205,155,124, -3,48,70,182,201,192,8,216,66,19,172,3,31,141,196,208,99,204,68,25,39,100,108,25,39,91,223,55,240,16,139,197,99,246,126,239,123,173,175,141,172,39,198,255,141,144,39,26,197,179,140,160,0,64,144,143,118,247,160,127,247,228,81,186,77,91,81,246,171,37,151, -207,252,210,146,79,206,248,122,97,181,126,5,77,22,204,172,229,129,132,32,248,96,132,128,66,115,7,104,120,122,194,63,12,13,214,61,39,122,18,20,235,202,88,100,160,198,56,11,166,21,204,102,173,138,171,13,211,161,68,95,193,150,16,50,41,92,173,54,116,109, -222,19,117,130,61,56,9,214,208,56,57,86,35,44,170,66,167,233,185,35,118,54,92,71,36,199,81,163,57,118,124,53,252,137,38,79,153,12,175,229,88,175,254,176,79,180,145,107,248,229,246,55,198,30,27,220,111,57,18,19,177,101,47,130,2,0,65,78,154,201,118,215, -24,217,238,57,250,84,223,253,139,46,158,254,169,37,151,205,252,70,237,242,210,203,4,29,103,160,131,135,50,37,42,240,79,162,128,38,157,209,13,180,31,208,53,113,150,133,110,15,153,217,244,56,154,123,67,141,26,93,38,40,212,22,67,137,174,130,37,27,82,129, -64,55,250,123,186,21,17,209,80,164,45,33,2,162,32,107,134,28,209,137,141,180,196,206,23,245,128,95,244,144,239,109,103,223,157,46,157,56,194,102,22,186,167,94,62,253,123,26,194,167,94,61,133,35,223,143,126,71,142,25,123,61,219,178,1,42,82,4,3,199,188, -126,183,41,208,208,187,115,226,201,246,45,163,27,29,131,190,9,188,139,17,20,0,8,146,4,126,91,56,220,244,210,208,171,205,155,134,95,157,177,186,98,233,178,43,102,126,121,254,121,53,95,44,170,49,46,138,209,225,67,52,87,32,195,39,160,159,136,20,104,132, -127,48,150,116,9,193,197,140,228,144,167,139,9,3,250,43,145,185,174,101,73,135,6,190,16,10,180,69,172,81,17,141,20,208,173,88,151,248,61,93,82,40,20,138,192,72,54,42,38,244,124,194,112,106,201,79,186,38,206,49,131,202,177,159,199,247,227,223,27,112,242, -43,30,99,73,143,180,108,142,38,65,70,99,97,136,196,34,108,12,46,13,211,135,136,135,30,16,125,224,167,70,62,234,5,111,212,77,54,39,248,34,110,98,216,221,108,128,14,245,226,195,196,211,143,30,171,168,56,110,44,143,27,122,218,127,65,75,190,99,166,123,245, -31,115,66,129,23,18,83,249,34,1,209,49,114,196,246,70,231,155,99,79,15,236,179,236,12,123,163,18,222,181,8,10,0,4,81,210,179,140,197,193,212,104,239,34,219,255,20,62,98,248,237,162,139,166,125,114,193,133,211,190,50,99,85,249,101,58,163,80,202,6,16,209, -80,107,60,123,190,83,66,24,240,31,233,221,83,67,76,103,26,132,137,209,117,133,173,9,131,12,137,80,242,241,234,157,132,113,39,222,39,121,61,53,248,44,63,225,88,6,60,21,27,58,98,92,57,46,241,147,190,130,14,179,161,255,62,254,15,7,137,238,71,226,243,194, -240,247,202,135,8,49,252,137,225,74,18,107,154,36,178,242,200,68,69,132,116,66,36,28,127,47,106,220,169,81,63,177,79,244,23,249,169,211,16,79,62,75,188,249,127,7,157,200,71,141,126,92,138,199,157,35,254,3,61,219,39,94,24,216,61,249,170,185,203,109,194, -59,20,65,1,128,32,41,137,10,132,130,77,27,135,182,208,173,118,121,217,156,249,231,213,126,122,241,165,211,63,95,54,187,240,28,242,144,230,197,16,49,78,89,190,238,154,48,160,212,99,231,224,95,59,238,9,19,124,220,128,71,32,116,194,40,31,143,40,36,84,81, -194,200,255,171,112,73,226,243,78,124,58,253,131,99,31,173,57,254,39,199,146,240,56,128,60,201,89,96,157,250,244,28,59,54,62,107,168,119,172,97,242,53,226,237,191,100,106,118,28,165,75,81,8,130,2,0,65,210,132,185,195,53,66,182,7,142,62,213,247,192,140, -213,21,107,136,24,184,110,254,39,106,62,93,50,163,96,21,181,119,180,201,80,38,116,27,84,87,42,252,163,1,63,241,87,72,18,70,159,227,57,8,186,34,227,227,205,142,173,93,239,140,111,28,58,104,217,19,176,135,131,120,132,16,20,0,8,146,65,80,111,108,248,125, -107,19,221,222,127,84,119,231,156,51,170,206,92,112,193,180,107,103,174,169,184,170,168,218,176,146,26,67,218,109,48,219,150,9,144,20,25,125,94,147,168,217,39,63,131,238,168,217,212,228,216,62,184,215,188,105,232,160,117,151,107,204,239,196,35,132,160, -0,64,144,44,32,232,140,136,221,239,142,31,160,91,65,185,238,231,179,207,168,58,131,8,130,171,103,172,174,184,162,108,78,225,26,242,144,215,72,209,24,196,200,22,71,49,144,167,22,63,209,150,87,208,241,76,15,134,92,145,81,83,3,49,250,251,204,155,135,222, -183,238,117,141,250,237,120,144,16,20,0,8,146,197,4,156,145,232,113,49,160,53,242,119,204,88,85,177,122,193,5,181,159,156,190,170,252,138,138,185,69,103,234,10,132,66,42,4,152,32,144,80,13,228,180,205,231,52,137,90,125,178,145,243,29,247,89,67,29,19, -45,206,247,250,247,76,190,57,222,236,60,228,53,7,189,120,148,16,20,0,8,146,131,68,131,82,108,248,144,181,145,110,196,251,187,187,122,113,233,188,185,103,85,157,63,107,109,229,39,171,23,151,156,107,44,211,213,81,35,193,4,129,24,207,128,86,196,72,178,94, -62,45,215,163,205,121,104,126,68,200,19,113,216,7,188,71,71,143,218,223,29,61,106,219,110,238,112,181,133,60,81,17,15,20,130,2,0,65,242,8,234,237,155,59,93,67,116,59,252,68,223,83,197,53,134,130,234,37,165,107,230,173,171,190,104,218,242,178,11,203,102, -23,158,170,47,214,86,178,127,43,210,8,1,10,130,140,183,247,180,112,129,167,30,190,134,37,240,17,47,63,228,54,249,59,38,219,93,251,198,91,156,59,136,225,63,228,26,245,79,226,121,68,16,20,0,8,114,2,175,37,20,32,219,129,129,189,230,3,26,78,243,155,178,89, -5,181,181,203,203,78,155,177,186,226,188,218,229,165,231,150,207,42,92,161,47,33,130,64,3,172,170,128,70,9,98,212,144,160,45,73,159,193,231,52,172,54,159,122,249,244,188,136,97,41,24,176,135,186,173,189,222,131,19,45,142,61,227,173,174,163,214,30,119, -95,196,143,78,62,130,160,0,64,144,147,128,122,136,206,17,191,153,108,91,187,222,54,109,165,225,227,210,89,5,53,181,203,74,87,17,65,112,118,229,252,162,179,43,235,138,79,33,130,96,182,160,227,53,244,223,211,234,130,24,46,27,168,107,236,249,132,193,167, -63,227,49,128,144,55,98,115,141,132,58,109,3,222,195,227,77,142,131,230,78,87,163,219,20,24,12,121,162,120,18,16,4,5,0,130,40,32,8,226,113,112,141,250,45,100,219,214,253,238,248,54,250,103,69,53,134,162,178,217,133,11,103,172,42,95,93,181,176,120,109, -249,220,226,53,197,181,134,197,134,98,109,45,53,82,180,186,128,69,10,136,48,160,162,0,171,13,78,214,210,3,112,196,216,211,178,60,142,255,187,177,39,94,188,199,109,14,14,146,115,208,102,235,243,28,181,116,121,26,172,189,158,78,207,120,192,138,201,155, -8,130,2,0,65,82,134,207,18,242,145,173,105,172,222,222,68,254,247,73,106,244,139,170,141,21,21,117,133,117,53,139,75,87,150,204,44,56,165,106,126,241,138,226,233,198,133,250,98,237,76,157,158,55,82,163,70,141,21,21,4,9,97,0,121,27,49,160,30,61,109,40, -72,215,234,143,255,164,66,75,138,198,164,176,55,106,38,199,118,208,103,13,117,90,123,60,45,150,110,119,171,99,200,215,235,157,12,142,71,131,104,237,17,4,5,0,130,100,16,212,219,247,76,4,28,116,27,58,96,173,63,254,231,5,21,122,67,201,116,227,180,226,105, -198,186,202,249,197,75,43,235,138,150,24,203,117,139,74,103,22,206,209,26,249,25,250,34,109,57,17,15,26,106,16,227,82,252,88,228,32,209,159,32,17,57,56,102,239,178,105,198,193,177,14,132,52,33,143,254,158,138,35,250,27,234,217,179,89,3,116,180,115,72, -242,134,60,81,139,215,28,26,11,185,34,189,182,126,111,47,241,238,187,220,166,192,128,115,196,63,26,116,133,221,185,221,193,17,65,80,0,32,72,78,19,112,132,67,100,27,154,108,119,13,245,110,159,216,121,252,207,245,197,90,222,88,170,171,40,172,54,204,168, -152,91,56,147,252,127,93,213,130,226,217,186,66,97,94,217,156,194,105,188,150,155,110,44,211,149,11,122,190,152,136,3,3,45,101,75,180,242,255,123,226,33,253,253,7,141,36,251,43,137,206,64,248,168,30,192,39,177,12,161,249,184,137,129,241,99,30,187,230, -67,30,60,13,207,159,120,29,75,193,63,81,49,33,17,241,226,241,91,67,110,242,211,236,28,245,155,137,231,62,108,235,245,140,68,2,226,144,173,207,75,12,124,196,228,179,4,109,33,111,52,132,137,148,8,146,103,2,192,235,197,158,27,72,254,66,199,198,146,205,234, -26,243,91,77,141,246,230,143,248,39,58,190,2,138,180,70,168,48,148,232,42,202,231,20,86,199,164,120,109,113,141,161,178,100,102,65,53,49,177,85,134,18,109,25,249,125,105,92,130,98,242,239,139,5,3,103,44,252,255,236,221,75,106,194,64,0,128,225,104,226, -139,90,104,233,190,208,131,120,75,47,215,19,20,173,90,84,218,196,81,155,206,152,62,20,234,174,208,133,223,7,1,5,31,193,133,243,79,72,50,119,189,126,28,232,211,26,187,157,163,173,125,184,235,93,63,63,123,36,33,141,223,233,102,72,187,240,189,136,82,136, -91,90,237,38,196,193,61,196,125,173,226,140,61,45,23,184,110,229,217,186,92,132,213,122,82,46,227,27,103,241,125,207,211,199,229,60,126,196,244,117,182,153,174,158,222,94,222,247,217,60,76,178,101,124,189,123,231,195,25,33,132,203,11,128,162,40,178,241, -120,44,2,224,183,249,118,115,121,97,136,3,254,34,62,94,52,51,251,250,103,182,253,57,19,79,119,180,235,118,138,172,46,234,230,105,63,239,12,175,6,131,56,213,79,235,239,118,143,182,162,119,221,105,223,222,15,135,231,206,57,72,231,39,196,25,123,21,7,245, -144,53,153,80,197,45,93,63,183,137,223,183,41,119,161,42,55,135,127,171,109,154,237,239,110,246,217,182,191,255,58,64,144,213,15,205,145,137,195,145,130,188,217,209,188,104,157,236,47,112,106,52,26,253,219,119,183,106,167,38,3,192,197,105,251,9,0,64, -0,0,0,2,0,0,16,0,0,128,0,0,0,4,0,0,32,0,0,0,1,0,0,8,0,0,64,0,0,0,2,0,0,16,0,0,128,0,0,0,4,0,0,32,0,0,0,1,0,0,8,0,0,64,0,0,128,0,0,0,4,0,0,32,0,0,0,1,0,0,8,0,0,64,0,0,0,2,0,0,16,0,0,128,0,0,0,4,0,0,32,0,0,128,191,246,33,192,0,100,235,173,153,70,62,64, -37,0,0,0,0,73,69,78,68,174,66,96,130,0,0 }; - -const char* juce_icon_png = (const char*) temp_binary_data_13; - -//================== wizard_AnimatedApp.svg ================== -static const unsigned char temp_binary_data_14[] = -"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" -"<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->\n" -"\n" -"<svg\n" -" xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n" -" xmlns:cc=\"http://creativecommons.org/ns#\"\n" -" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n" -" xmlns:svg=\"http://www.w3.org/2000/svg\"\n" -" xmlns=\"http://www.w3.org/2000/svg\"\n" -" xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\"\n" -" xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"\n" -" version=\"1.1\"\n" -" id=\"Layer_1\"\n" -" x=\"0px\"\n" -" y=\"0px\"\n" -" viewBox=\"0 0 136.9 114.8\"\n" -" enable-background=\"new 0 0 136.9 114.8\"\n" -" xml:space=\"preserve\"\n" -" inkscape:version=\"0.91 r13725\"\n" -" sodipodi:docname=\"wizard_AnimatedApp.svg\"><metadata\n" -" id=\"metadata50\"><rdf:RDF><cc:Work\n" -" rdf:about=\"\"><dc:format>image/svg+xml</dc:format><dc:type\n" -" rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\" /></cc:Work></rdf:RDF></metadata><defs\n" -" id=\"defs48\" /><sodipodi:namedview\n" -" pagecolor=\"#ffffff\"\n" -" bordercolor=\"#666666\"\n" -" borderopacity=\"1\"\n" -" objecttolerance=\"10\"\n" -" gridtolerance=\"10\"\n" -" guidetolerance=\"10\"\n" -" inkscape:pageopacity=\"0\"\n" -" inkscape:pageshadow=\"2\"\n" -" inkscape:window-width=\"1680\"\n" -" inkscape:window-height=\"1001\"\n" -" id=\"namedview46\"\n" -" showgrid=\"false\"\n" -" inkscape:zoom=\"5.6568543\"\n" -" inkscape:cx=\"85.414924\"\n" -" inkscape:cy=\"49.441529\"\n" -" inkscape:window-x=\"0\"\n" -" inkscape:window-y=\"1\"\n" -" inkscape:window-maximized=\"1\"\n" -" inkscape:current-layer=\"Layer_1\" /><g\n" -" id=\"Layer_1_18_\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\"><rect\n" -" x=\"16.3\"\n" -" y=\"10.9\"\n" -" stroke-miterlimit=\"10\"\n" -" width=\"103.6\"\n" -" height=\"67.5\"\n" -" id=\"rect4\"\n" -" stroke-width=\"1.3469\"\n" -" stroke=\"#a45c94\"\n" -" fill=\"none\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><rect\n" -" x=\"16.3\"\n" -" y=\"10.9\"\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.3469\"\n" -" stroke-miterlimit=\"10\"\n" -" width=\"103.6\"\n" -" height=\"2.4\"\n" -" id=\"rect6\"\n" -" style=\"stroke:#a45c9f;stroke-opacity:0.94117647\" /><circle\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.3469\"\n" -" stroke-miterlimit=\"10\"\n" -" cx=\"80.3\"\n" -" cy=\"45\"\n" -" r=\"20.8\"\n" -" id=\"circle8\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><g\n" -" id=\"g10\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\"><g\n" -" id=\"g12\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\"><path\n" -" stroke-miterlimit=\"10\"\n" -" d=\"M97.8,40.1c0.9,3.2,0,8-2.1,8.3 c-2,0.2-10.5-2.2-14.8-3.6c2.9-3.4,8.9-10,10.8-10.8C93.5,33.2,96.9,36.9,97.8,40.1z\"\n" -" id=\"path14\"\n" -" stroke-width=\"1.3469\"\n" -" stroke=\"#a45c94\"\n" -" fill=\"none\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><g\n" -" id=\"g16\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\"><path\n" -" stroke-miterlimit=\"10\"\n" -" d=\"M93.3,57.7c-2.3,2.4-7,4-8.2,2.4 c-1.2-1.6-3.4-10.2-4.3-14.6c4.4,0.8,13.1,2.8,14.7,4C97.2,50.5,95.6,55.3,93.3,57.7z\"\n" -" id=\"path18\"\n" -" stroke-width=\"1.3469\"\n" -" stroke=\"#a45c94\"\n" -" fill=\"none\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><g\n" -" id=\"g20\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\"><path\n" -" stroke-miterlimit=\"10\"\n" -" d=\"M75.7,62.6c-3.2-0.8-7-4.1-6.1-6 c0.8-1.9,7.2-8,10.5-11.1c1.5,4.3,4.1,12.7,3.9,14.8C83.9,62.4,79,63.4,75.7,62.6z\"\n" -" id=\"path22\"\n" -" stroke-width=\"1.3469\"\n" -" stroke=\"#a45c94\"\n" -" fill=\"none\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><g\n" -" id=\"g24\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\"><path\n" -" stroke-miterlimit=\"10\"\n" -" d=\"M62.9,49.9c-0.9-3.2,0-8,2.1-8.3 c2-0.2,10.5,2.2,14.8,3.6c-2.9,3.4-8.9,10-10.8,10.8C67.2,56.8,63.8,53.1,62.9,49.9z\"\n" -" id=\"path26\"\n" -" stroke-width=\"1.3469\"\n" -" stroke=\"#a45c94\"\n" -" fill=\"none\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><g\n" -" id=\"g28\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\"><path\n" -" stroke-miterlimit=\"10\"\n" -" d=\"M67.4,32.3c2.3-2.4,7-4,8.2-2.4 c1.2,1.6,3.4,10.2,4.3,14.6c-4.4-0.8-13.1-2.8-14.7-4C63.5,39.4,65.1,34.7,67.4,32.3z\"\n" -" id=\"path30\"\n" -" stroke-width=\"1.3469\"\n" -" stroke=\"#a45c94\"\n" -" fill=\"none\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><g\n" -" id=\"g32\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\"><path\n" -" stroke-miterlimit=\"10\"\n" -" d=\"M84.8,27.4c3.2,0.8,7,4.1,6.1,6 c-0.8,1.9-7.2,8-10.5,11.1c-1.5-4.3-4.1-12.7-3.9-14.8C76.7,27.6,81.6,26.6,84.8,27.4z\"\n" -" id=\"path34\"\n" -" stroke-width=\"1.3469\"\n" -" stroke=\"#a45c94\"\n" -" fill=\"none\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /></g></g><path\n" -" stroke-miterlimit=\"10\"\n" -" d=\"M130,114.8H6.9c-3.8,0-6.9-3.1-6.9-6.9V6.9 C0,3.1,3.1,0,6.9,0H130c3.8,0,6.9,3.1,6.9,6.9v101.1C136.9,111.7,133.9,114.8,130,114.8z\"\n" -" id=\"path36\"\n" -" stroke-width=\"1.3469\"\n" -" stroke=\"#a45c94\"\n" -" fill=\"none\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><path\n" -" opacity=\"0.8\"\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.3469\"\n" -" stroke-miterlimit=\"10\"\n" -" d=\"M62.6,61.4 c-9.1-9.1-9.1-23.7,0-32.8\"\n" -" id=\"path38\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><path\n" -" opacity=\"0.5\"\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.3469\"\n" -" stroke-miterlimit=\"10\"\n" -" d=\"M55.9,57.3 c-4.7-7.4-4.7-16.9-0.1-24.4\"\n" -" id=\"path40\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" opacity=\"0.7\"\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.3469\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"57.7\"\n" -" y1=\"41.5\"\n" -" x2=\"37.8\"\n" -" y2=\"41.5\"\n" -" id=\"line42\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" opacity=\"0.7\"\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.3469\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"57.7\"\n" -" y1=\"48.4\"\n" -" x2=\"34.2\"\n" -" y2=\"48.4\"\n" -" id=\"line44\"\n" -" style=\"stroke:#a45c94;stroke-opacity:0.94117647\" /></svg>"; - -const char* wizard_AnimatedApp_svg = (const char*) temp_binary_data_14; - -//================== wizard_AudioApp.svg ================== -static const unsigned char temp_binary_data_15[] = -"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" -"<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->\n" -"\n" -"<svg\n" -" xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n" -" xmlns:cc=\"http://creativecommons.org/ns#\"\n" -" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n" -" xmlns:svg=\"http://www.w3.org/2000/svg\"\n" -" xmlns=\"http://www.w3.org/2000/svg\"\n" -" xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\"\n" -" xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"\n" -" version=\"1.1\"\n" -" id=\"Layer_1\"\n" -" x=\"0px\"\n" -" y=\"0px\"\n" -" viewBox=\"0 0 136.9 114.8\"\n" -" enable-background=\"new 0 0 136.9 114.8\"\n" -" xml:space=\"preserve\"\n" -" inkscape:version=\"0.91 r13725\"\n" -" sodipodi:docname=\"wizard_AudioApp.svg\"><metadata\n" -" id=\"metadata137\"><rdf:RDF><cc:Work\n" -" rdf:about=\"\"><dc:format>image/svg+xml</dc:format><dc:type\n" -" rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\" /></cc:Work></rdf:RDF></metadata><defs\n" -" id=\"defs135\" /><sodipodi:namedview\n" -" pagecolor=\"#ffffff\"\n" -" bordercolor=\"#666666\"\n" -" borderopacity=\"1\"\n" -" objecttolerance=\"10\"\n" -" gridtolerance=\"10\"\n" -" guidetolerance=\"10\"\n" -" inkscape:pageopacity=\"0\"\n" -" inkscape:pageshadow=\"2\"\n" -" inkscape:window-width=\"1680\"\n" -" inkscape:window-height=\"1001\"\n" -" id=\"namedview133\"\n" -" showgrid=\"false\"\n" -" inkscape:zoom=\"4.1114981\"\n" -" inkscape:cx=\"45.83412\"\n" -" inkscape:cy=\"47.98031\"\n" -" inkscape:window-x=\"0\"\n" -" inkscape:window-y=\"1\"\n" -" inkscape:window-maximized=\"1\"\n" -" inkscape:current-layer=\"Layer_1\" /><path\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.3469\"\n" -" stroke-miterlimit=\"10\"\n" -" d=\"M130,114.8H6.9c-3.8,0-6.9-3.1-6.9-6.9V6.9 C0,3.1,3.1,0,6.9,0H130c3.8,0,6.9,3.1,6.9,6.9v101.1C136.9,111.7,133.9,114.8,130,114.8z\"\n" -" id=\"path3\"\n" -" style=\"fill:none;fill-opacity:1;stroke:#a45c94;stroke-opacity:1\" /><rect\n" -" x=\"16.5\"\n" -" y=\"10.9\"\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.3412\"\n" -" stroke-miterlimit=\"10\"\n" -" width=\"102.7\"\n" -" height=\"2.4\"\n" -" id=\"rect5\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><rect\n" -" x=\"16.5\"\n" -" y=\"10.9\"\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.3469\"\n" -" stroke-miterlimit=\"10\"\n" -" width=\"102.9\"\n" -" height=\"67.5\"\n" -" id=\"rect7\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"17.1\"\n" -" y1=\"43.8\"\n" -" x2=\"17.1\"\n" -" y2=\"44.5\"\n" -" id=\"line9\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"18.8\"\n" -" y1=\"43.6\"\n" -" x2=\"18.8\"\n" -" y2=\"44.7\"\n" -" id=\"line11\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"20.4\"\n" -" y1=\"43.8\"\n" -" x2=\"20.4\"\n" -" y2=\"44.5\"\n" -" id=\"line13\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"22.1\"\n" -" y1=\"43.6\"\n" -" x2=\"22.1\"\n" -" y2=\"44.7\"\n" -" id=\"line15\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"23.8\"\n" -" y1=\"43.1\"\n" -" x2=\"23.8\"\n" -" y2=\"45.2\"\n" -" id=\"line17\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"25.4\"\n" -" y1=\"42.3\"\n" -" x2=\"25.4\"\n" -" y2=\"46\"\n" -" id=\"line19\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"27.1\"\n" -" y1=\"43.9\"\n" -" x2=\"27.1\"\n" -" y2=\"44.4\"\n" -" id=\"line21\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"28.8\"\n" -" y1=\"43.3\"\n" -" x2=\"28.8\"\n" -" y2=\"45\"\n" -" id=\"line23\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"30.4\"\n" -" y1=\"29.3\"\n" -" x2=\"30.4\"\n" -" y2=\"59\"\n" -" id=\"line25\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"32.1\"\n" -" y1=\"40.9\"\n" -" x2=\"32.1\"\n" -" y2=\"47.4\"\n" -" id=\"line27\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"33.8\"\n" -" y1=\"42.7\"\n" -" x2=\"33.8\"\n" -" y2=\"45.6\"\n" -" id=\"line29\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"35.4\"\n" -" y1=\"36.6\"\n" -" x2=\"35.4\"\n" -" y2=\"51.7\"\n" -" id=\"line31\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"37.1\"\n" -" y1=\"33.3\"\n" -" x2=\"37.1\"\n" -" y2=\"55.1\"\n" -" id=\"line33\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"38.8\"\n" -" y1=\"42.6\"\n" -" x2=\"38.8\"\n" -" y2=\"45.7\"\n" -" id=\"line35\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"40.4\"\n" -" y1=\"37.4\"\n" -" x2=\"40.4\"\n" -" y2=\"50.9\"\n" -" id=\"line37\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"42.1\"\n" -" y1=\"27.4\"\n" -" x2=\"42.1\"\n" -" y2=\"60.9\"\n" -" id=\"line39\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"43.8\"\n" -" y1=\"39.3\"\n" -" x2=\"43.8\"\n" -" y2=\"49\"\n" -" id=\"line41\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"45.4\"\n" -" y1=\"41.1\"\n" -" x2=\"45.4\"\n" -" y2=\"47.2\"\n" -" id=\"line43\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"47.1\"\n" -" y1=\"42.6\"\n" -" x2=\"47.1\"\n" -" y2=\"45.7\"\n" -" id=\"line45\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"48.8\"\n" -" y1=\"36.2\"\n" -" x2=\"48.8\"\n" -" y2=\"52.1\"\n" -" id=\"line47\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"50.4\"\n" -" y1=\"42.5\"\n" -" x2=\"50.4\"\n" -" y2=\"45.9\"\n" -" id=\"line49\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"52.1\"\n" -" y1=\"39.3\"\n" -" x2=\"52.1\"\n" -" y2=\"49\"\n" -" id=\"line51\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"53.8\"\n" -" y1=\"34.8\"\n" -" x2=\"53.8\"\n" -" y2=\"53.5\"\n" -" id=\"line53\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"55.4\"\n" -" y1=\"42.2\"\n" -" x2=\"55.4\"\n" -" y2=\"46.1\"\n" -" id=\"line55\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"57.1\"\n" -" y1=\"41\"\n" -" x2=\"57.1\"\n" -" y2=\"47.3\"\n" -" id=\"line57\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"58.8\"\n" -" y1=\"35.4\"\n" -" x2=\"58.8\"\n" -" y2=\"53\"\n" -" id=\"line59\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"60.4\"\n" -" y1=\"32.6\"\n" -" x2=\"60.4\"\n" -" y2=\"55.8\"\n" -" id=\"line61\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"62.1\"\n" -" y1=\"37.4\"\n" -" x2=\"62.1\"\n" -" y2=\"50.9\"\n" -" id=\"line63\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"63.8\"\n" -" y1=\"38.1\"\n" -" x2=\"63.8\"\n" -" y2=\"50.2\"\n" -" id=\"line65\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"65.4\"\n" -" y1=\"42.2\"\n" -" x2=\"65.4\"\n" -" y2=\"46.1\"\n" -" id=\"line67\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"67.1\"\n" -" y1=\"38.9\"\n" -" x2=\"67.1\"\n" -" y2=\"49.4\"\n" -" id=\"line69\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"68.8\"\n" -" y1=\"43.6\"\n" -" x2=\"68.8\"\n" -" y2=\"44.7\"\n" -" id=\"line71\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"70.4\"\n" -" y1=\"41.4\"\n" -" x2=\"70.4\"\n" -" y2=\"47\"\n" -" id=\"line73\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"72.1\"\n" -" y1=\"39\"\n" -" x2=\"72.1\"\n" -" y2=\"49.3\"\n" -" id=\"line75\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"73.8\"\n" -" y1=\"40.9\"\n" -" x2=\"73.8\"\n" -" y2=\"47.5\"\n" -" id=\"line77\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"75.4\"\n" -" y1=\"40.6\"\n" -" x2=\"75.4\"\n" -" y2=\"47.8\"\n" -" id=\"line79\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"77.1\"\n" -" y1=\"38.4\"\n" -" x2=\"77.1\"\n" -" y2=\"49.9\"\n" -" id=\"line81\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"78.8\"\n" -" y1=\"42\"\n" -" x2=\"78.8\"\n" -" y2=\"46.3\"\n" -" id=\"line83\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"80.4\"\n" -" y1=\"42.2\"\n" -" x2=\"80.4\"\n" -" y2=\"46.1\"\n" -" id=\"line85\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"82.1\"\n" -" y1=\"43.6\"\n" -" x2=\"82.1\"\n" -" y2=\"44.7\"\n" -" id=\"line87\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"83.8\"\n" -" y1=\"42.6\"\n" -" x2=\"83.8\"\n" -" y2=\"45.7\"\n" -" id=\"line89\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"85.4\"\n" -" y1=\"43.3\"\n" -" x2=\"85.4\"\n" -" y2=\"45\"\n" -" id=\"line91\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"87.1\"\n" -" y1=\"39.9\"\n" -" x2=\"87.1\"\n" -" y2=\"48.4\"\n" -" id=\"line93\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"88.8\"\n" -" y1=\"42.9\"\n" -" x2=\"88.8\"\n" -" y2=\"45.4\"\n" -" id=\"line95\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"90.4\"\n" -" y1=\"43.6\"\n" -" x2=\"90.4\"\n" -" y2=\"44.7\"\n" -" id=\"line97\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"92.1\"\n" -" y1=\"43.6\"\n" -" x2=\"92.1\"\n" -" y2=\"44.7\"\n" -" id=\"line99\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"93.8\"\n" -" y1=\"42.7\"\n" -" x2=\"93.8\"\n" -" y2=\"45.6\"\n" -" id=\"line101\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"95.4\"\n" -" y1=\"41.1\"\n" -" x2=\"95.4\"\n" -" y2=\"47.2\"\n" -" id=\"line103\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"97.1\"\n" -" y1=\"42.7\"\n" -" x2=\"97.1\"\n" -" y2=\"45.6\"\n" -" id=\"line105\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"98.8\"\n" -" y1=\"43.6\"\n" -" x2=\"98.8\"\n" -" y2=\"44.7\"\n" -" id=\"line107\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"100.4\"\n" -" y1=\"43.1\"\n" -" x2=\"100.4\"\n" -" y2=\"45.2\"\n" -" id=\"line109\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"102.1\"\n" -" y1=\"43.6\"\n" -" x2=\"102.1\"\n" -" y2=\"44.7\"\n" -" id=\"line111\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"103.8\"\n" -" y1=\"42\"\n" -" x2=\"103.8\"\n" -" y2=\"46.3\"\n" -" id=\"line113\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +"<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"14460.31\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" launchScreen=\"YES\" useTraitCollections=\"YES\" " +"useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"01J-lp-oVM\">\n" +" <scenes>\n" +" <scene sceneID=\"EHf-IW-A2E\">\n" +" <objects>\n" +" <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"iYj-Kq-Ea1\" userLabel=\"\" sceneMemberID=\"firstResponder\"/>\n" +" <viewController id=\"01J-lp-oVM\" sceneMemberID=\"viewController\">\n" +" <view key=\"view\" contentMode=\"scaleToFill\" id=\"Ze5-6b-2t3\">\n" +" <autoresizingMask key=\"autoresizingMask\"/>\n" +" <color key=\"backgroundColor\" red=\"0\" green=\"0\" blue=\"0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n" +" </view>\n" +" </viewController>\n" +" </objects>\n" +" </scene>\n" +" </scenes>\n" +"</document>\n"; + +const char* LaunchScreen_storyboard = (const char*) temp_binary_data_0; + +//================== PIPAudioProcessor.cpp.in ================== +static const unsigned char temp_binary_data_1[] = +"/*\n" +" ==============================================================================\n" +"\n" +" This file was auto-generated and contains the startup code for a PIP.\n" +"\n" +" ==============================================================================\n" +"*/\n" +"\n" +"#include <JuceHeader.h>\n" +"#include \"${JUCE_PIP_HEADER}\"\n" +"\n" +"//==============================================================================\n" +"juce::AudioProcessor* JUCE_CALLTYPE createPluginFilter()\n" +"{\n" +" return new ${JUCE_PIP_MAIN_CLASS}();\n" +"}\n"; + +const char* PIPAudioProcessor_cpp_in = (const char*) temp_binary_data_1; + +//================== PIPComponent.cpp.in ================== +static const unsigned char temp_binary_data_2[] = +"/*\r\n" +" ==============================================================================\r\n" +"\r\n" +" This file contains the startup code for a PIP.\r\n" +"\r\n" +" ==============================================================================\r\n" +"*/\r\n" +"\r\n" +"#include <JuceHeader.h>\r\n" +"#include \"${JUCE_PIP_HEADER}\"\r\n" +"\r\n" +"class Application : public juce::JUCEApplication\r\n" +"{\r\n" +"public:\r\n" +" //==============================================================================\r\n" +" Application() = default;\r\n" +"\r\n" +" const juce::String getApplicationName() override { return \"${JUCE_PIP_NAME}\"; }\r\n" +" const juce::String getApplicationVersion() override { return \"${PROJECT_VERSION}\"; }\r\n" +"\r\n" +" void initialise (const juce::String&) override\r\n" +" {\r\n" +" mainWindow.reset (new MainWindow (\"${JUCE_PIP_NAME}\", new ${JUCE_PIP_MAIN_CLASS}, *this));\r\n" +" }\r\n" +"\r\n" +" void shutdown() override { mainWindow = nullptr; }\r\n" +"\r\n" +"private:\r\n" +" class MainWindow : public juce::DocumentWindow\r\n" +" {\r\n" +" public:\r\n" +" MainWindow (const juce::String& name, juce::Component* c, JUCEApplication& a)\r\n" +" : DocumentWindow (name, juce::Desktop::getInstance().getDefaultLookAndFeel()\r\n" +" .findColour (ResizableWindow::backgroundColourId),\r\n" +" juce::DocumentWindow::allButtons),\r\n" +" app (a)\r\n" +" {\r\n" +" setUsingNativeTitleBar (true);\r\n" +" setContentOwned (c, true);\r\n" +"\r\n" +" #if JUCE_ANDROID || JUCE_IOS\r\n" +" setFullScreen (true);\r\n" +" #else\r\n" +" setResizable (true, false);\r\n" +" setResizeLimits (300, 250, 10000, 10000);\r\n" +" centreWithSize (getWidth(), getHeight());\r\n" +" #endif\r\n" +"\r\n" +" setVisible (true);\r\n" +" }\r\n" +"\r\n" +" void closeButtonPressed() override\r\n" +" {\r\n" +" app.systemRequestedQuit();\r\n" +" }\r\n" +"\r\n" +" private:\r\n" +" JUCEApplication& app;\r\n" +"\r\n" +" //==============================================================================\r\n" +" JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainWindow)\r\n" +" };\r\n" +"\r\n" +" std::unique_ptr<MainWindow> mainWindow;\r\n" +"};\r\n" +"\r\n" +"//==============================================================================\r\n" +"START_JUCE_APPLICATION (Application)\r\n"; + +const char* PIPComponent_cpp_in = (const char*) temp_binary_data_2; + +//================== PIPConsole.cpp.in ================== +static const unsigned char temp_binary_data_3[] = +"/*\n" +" ==============================================================================\n" +"\n" +" This file was auto-generated and contains the startup code for a PIP.\n" +"\n" +" ==============================================================================\n" +"*/\n" +"\n" +"#include <JuceHeader.h>\n" +"#include \"${JUCE_PIP_HEADER}\"\n"; + +const char* PIPConsole_cpp_in = (const char*) temp_binary_data_3; + +//================== RecentFilesMenuTemplate.nib ================== +static const unsigned char temp_binary_data_4[] = +{ 98,112,108,105,115,116,48,48,212,0,1,0,2,0,3,0,4,0,5,0,6,1,53,1,54,88,36,118,101,114,115,105,111,110,88,36,111,98,106,101,99,116,115,89,36,97,114,99,104,105,118,101,114,84,36,116,111,112,18,0,1,134,160,175,16,74,0,7,0,8,0,31,0,35,0,36,0,42,0,46,0,50, +0,53,0,57,0,74,0,77,0,78,0,86,0,87,0,97,0,112,0,113,0,114,0,119,0,120,0,121,0,124,0,128,0,129,0,132,0,143,0,144,0,145,0,149,0,153,0,162,0,163,0,164,0,169,0,173,0,180,0,181,0,182,0,185,0,192,0,193,0,200,0,201,0,208,0,209,0,216,0,217,0,224,0,225,0,226, +0,229,0,230,0,232,0,249,1,11,1,29,1,30,1,31,1,32,1,33,1,34,1,35,1,36,1,37,1,38,1,39,1,40,1,41,1,42,1,43,1,44,1,47,1,50,85,36,110,117,108,108,219,0,9,0,10,0,11,0,12,0,13,0,14,0,15,0,16,0,17,0,18,0,19,0,20,0,21,0,22,0,23,0,24,0,25,0,26,0,27,0,28,0,29,0, +29,95,16,16,78,83,86,105,115,105,98,108,101,87,105,110,100,111,119,115,93,78,83,79,98,106,101,99,116,115,75,101,121,115,86,78,83,82,111,111,116,92,78,83,79,105,100,115,86,97,108,117,101,115,86,36,99,108,97,115,115,90,78,83,79,105,100,115,75,101,121,115, +93,78,83,67,111,110,110,101,99,116,105,111,110,115,95,16,15,78,83,79,98,106,101,99,116,115,86,97,108,117,101,115,95,16,25,78,83,65,99,99,101,115,115,105,98,105,108,105,116,121,67,111,110,110,101,99,116,111,114,115,95,16,23,78,83,65,99,99,101,115,115, +105,98,105,108,105,116,121,79,105,100,115,75,101,121,115,95,16,25,78,83,65,99,99,101,115,115,105,98,105,108,105,116,121,79,105,100,115,86,97,108,117,101,115,128,5,128,9,128,2,128,55,128,73,128,54,128,7,128,53,128,71,128,72,128,72,210,0,13,0,32,0,33,0, +34,91,78,83,67,108,97,115,115,78,97,109,101,128,4,128,3,93,78,83,65,112,112,108,105,99,97,116,105,111,110,210,0,37,0,38,0,39,0,40,90,36,99,108,97,115,115,110,97,109,101,88,36,99,108,97,115,115,101,115,94,78,83,67,117,115,116,111,109,79,98,106,101,99, +116,162,0,39,0,41,88,78,83,79,98,106,101,99,116,210,0,13,0,43,0,44,0,45,90,78,83,46,111,98,106,101,99,116,115,128,6,160,210,0,37,0,38,0,47,0,48,92,78,83,77,117,116,97,98,108,101,83,101,116,163,0,47,0,49,0,41,85,78,83,83,101,116,210,0,13,0,43,0,51,0,52, +128,8,160,210,0,37,0,38,0,54,0,55,94,78,83,77,117,116,97,98,108,101,65,114,114,97,121,163,0,54,0,56,0,41,87,78,83,65,114,114,97,121,210,0,13,0,43,0,58,0,59,128,52,174,0,60,0,61,0,62,0,63,0,64,0,65,0,66,0,67,0,68,0,69,0,70,0,71,0,72,0,73,128,10,128,12, +128,45,128,15,128,39,128,25,128,28,128,30,128,33,128,35,128,43,128,41,128,47,128,50,210,0,13,0,32,0,33,0,76,128,4,128,11,93,78,83,65,112,112,108,105,99,97,116,105,111,110,212,0,79,0,13,0,80,0,81,0,82,0,83,0,84,0,85,91,78,83,77,101,110,117,73,116,101, +109,115,86,78,83,78,97,109,101,87,78,83,84,105,116,108,101,128,14,128,38,128,49,128,13,89,65,77,97,105,110,77,101,110,117,210,0,13,0,43,0,51,0,89,128,8,167,0,63,0,65,0,64,0,71,0,70,0,62,0,72,128,15,128,25,128,39,128,41,128,43,128,45,128,47,216,0,98,0, +99,0,100,0,13,0,101,0,102,0,103,0,81,0,104,0,61,0,106,0,107,0,108,0,109,0,110,0,111,95,16,17,78,83,75,101,121,69,113,117,105,118,77,111,100,77,97,115,107,86,78,83,77,101,110,117,89,78,83,79,110,73,109,97,103,101,90,78,83,75,101,121,69,113,117,105,118, +93,78,83,77,110,101,109,111,110,105,99,76,111,99,92,78,83,77,105,120,101,100,73,109,97,103,101,18,0,16,0,0,128,12,128,18,128,24,128,17,18,127,255,255,255,128,22,128,16,91,100,101,108,109,101,65,112,112,75,105,116,80,211,0,13,0,115,0,32,0,116,0,117,0, +118,94,78,83,82,101,115,111,117,114,99,101,78,97,109,101,128,21,128,20,128,19,87,78,83,73,109,97,103,101,95,16,15,78,83,77,101,110,117,67,104,101,99,107,109,97,114,107,210,0,37,0,38,0,122,0,123,95,16,16,78,83,67,117,115,116,111,109,82,101,115,111,117, +114,99,101,162,0,122,0,41,211,0,13,0,115,0,32,0,116,0,126,0,118,128,21,128,23,128,19,95,16,16,78,83,77,101,110,117,77,105,120,101,100,83,116,97,116,101,210,0,37,0,38,0,130,0,131,90,78,83,77,101,110,117,73,116,101,109,162,0,130,0,41,218,0,133,0,98,0,134, +0,99,0,100,0,13,0,101,0,102,0,103,0,81,0,135,0,104,0,66,0,61,0,106,0,107,0,108,0,109,0,110,0,142,88,78,83,65,99,116,105,111,110,89,78,83,83,117,98,109,101,110,117,128,27,128,28,128,12,128,18,128,24,128,17,128,22,128,26,84,70,105,108,101,94,115,117,98, +109,101,110,117,65,99,116,105,111,110,58,211,0,79,0,13,0,81,0,146,0,83,0,142,128,29,128,38,128,26,210,0,13,0,43,0,51,0,151,128,8,161,0,67,128,30,218,0,133,0,98,0,134,0,99,0,100,0,13,0,101,0,102,0,103,0,81,0,154,0,104,0,68,0,66,0,106,0,107,0,108,0,109, +0,110,0,161,128,32,128,33,128,28,128,18,128,24,128,17,128,22,128,31,91,79,112,101,110,32,82,101,99,101,110,116,94,115,117,98,109,101,110,117,65,99,116,105,111,110,58,212,0,79,0,13,0,80,0,81,0,165,0,83,0,167,0,161,128,34,128,38,128,37,128,31,210,0,13, +0,43,0,51,0,171,128,8,161,0,69,128,35,216,0,98,0,99,0,100,0,13,0,101,0,102,0,103,0,81,0,104,0,68,0,106,0,107,0,108,0,109,0,110,0,179,128,33,128,18,128,24,128,17,128,22,128,36,90,67,108,101,97,114,32,77,101,110,117,95,16,22,95,78,83,82,101,99,101,110, +116,68,111,99,117,109,101,110,116,115,77,101,110,117,210,0,37,0,38,0,183,0,184,86,78,83,77,101,110,117,162,0,183,0,41,216,0,98,0,99,0,100,0,13,0,101,0,102,0,103,0,81,0,104,0,61,0,106,0,107,0,108,0,109,0,110,0,191,128,12,128,18,128,24,128,17,128,22,128, +40,84,69,100,105,116,215,0,99,0,100,0,13,0,101,0,102,0,103,0,81,0,61,0,106,0,107,0,108,0,109,0,110,0,199,128,12,128,18,128,24,128,17,128,22,128,42,86,70,111,114,109,97,116,216,0,98,0,99,0,100,0,13,0,101,0,102,0,103,0,81,0,104,0,61,0,106,0,107,0,108,0, +109,0,110,0,207,128,12,128,18,128,24,128,17,128,22,128,44,84,86,105,101,119,216,0,98,0,99,0,100,0,13,0,101,0,102,0,103,0,81,0,104,0,61,0,106,0,107,0,108,0,109,0,110,0,215,128,12,128,18,128,24,128,17,128,22,128,46,86,87,105,110,100,111,119,215,0,99,0, +100,0,13,0,101,0,102,0,103,0,81,0,61,0,106,0,107,0,108,0,109,0,110,0,223,128,12,128,18,128,24,128,17,128,22,128,48,84,72,101,108,112,91,95,78,83,77,97,105,110,77,101,110,117,210,0,13,0,32,0,33,0,228,128,4,128,51,93,78,83,70,111,110,116,77,97,110,97,103, +101,114,210,0,37,0,38,0,56,0,231,162,0,56,0,41,210,0,13,0,43,0,58,0,234,128,52,174,0,22,0,22,0,61,0,61,0,61,0,61,0,65,0,66,0,67,0,68,0,61,0,61,0,61,0,22,128,2,128,2,128,12,128,12,128,12,128,12,128,25,128,28,128,30,128,33,128,12,128,12,128,12,128,2,210, +0,13,0,43,0,58,0,251,128,52,175,16,15,0,22,0,60,0,61,0,62,0,63,0,64,0,65,0,66,0,67,0,68,0,69,0,70,0,71,0,72,0,73,128,2,128,10,128,12,128,45,128,15,128,39,128,25,128,28,128,30,128,33,128,35,128,43,128,41,128,47,128,50,210,0,13,0,43,0,58,1,13,128,52,175, +16,15,1,14,1,15,1,16,1,17,1,18,1,19,1,20,1,21,1,22,1,23,1,24,1,25,1,26,1,27,1,28,128,56,128,57,128,58,128,59,128,60,128,61,128,62,128,63,128,64,128,65,128,66,128,67,128,68,128,69,128,70,17,2,22,17,2,23,17,2,24,17,2,25,17,2,26,17,2,27,17,2,28,17,2,29, +17,2,30,17,2,31,17,2,32,17,2,33,17,2,34,17,2,35,17,2,36,210,0,13,0,43,0,51,1,46,128,8,160,210,0,13,0,43,0,58,1,49,128,52,160,210,0,37,0,38,1,51,1,52,94,78,83,73,66,79,98,106,101,99,116,68,97,116,97,162,1,51,0,41,95,16,15,78,83,75,101,121,101,100,65,114, +99,104,105,118,101,114,209,1,55,1,56,93,73,66,46,111,98,106,101,99,116,100,97,116,97,128,1,0,8,0,25,0,34,0,43,0,53,0,58,0,63,0,214,0,220,1,9,1,28,1,42,1,49,1,62,1,69,1,80,1,94,1,112,1,140,1,166,1,194,1,196,1,198,1,200,1,202,1,204,1,206,1,208,1,210,1, +212,1,214,1,216,1,225,1,237,1,239,1,241,1,255,2,8,2,19,2,28,2,43,2,48,2,57,2,66,2,77,2,79,2,80,2,89,2,102,2,109,2,115,2,124,2,126,2,127,2,136,2,151,2,158,2,166,2,175,2,177,2,206,2,208,2,210,2,212,2,214,2,216,2,218,2,220,2,222,2,224,2,226,2,228,2,230, +2,232,2,234,2,243,2,245,2,247,3,5,3,22,3,34,3,41,3,49,3,51,3,53,3,55,3,57,3,67,3,76,3,78,3,93,3,95,3,97,3,99,3,101,3,103,3,105,3,107,3,140,3,160,3,167,3,177,3,188,3,202,3,215,3,220,3,222,3,224,3,226,3,228,3,233,3,235,3,237,3,249,3,250,4,7,4,22,4,24,4, +26,4,28,4,36,4,54,4,63,4,82,4,87,4,100,4,102,4,104,4,106,4,125,4,134,4,145,4,150,4,191,4,200,4,210,4,212,4,214,4,216,4,218,4,220,4,222,4,224,4,226,4,231,4,246,5,3,5,5,5,7,5,9,5,18,5,20,5,23,5,25,5,66,5,68,5,70,5,72,5,74,5,76,5,78,5,80,5,82,5,94,5,109, +5,126,5,128,5,130,5,132,5,134,5,143,5,145,5,148,5,150,5,183,5,185,5,187,5,189,5,191,5,193,5,195,5,206,5,231,5,240,5,247,5,252,6,29,6,31,6,33,6,35,6,37,6,39,6,41,6,46,6,75,6,77,6,79,6,81,6,83,6,85,6,87,6,94,6,127,6,129,6,131,6,133,6,135,6,137,6,139,6, +144,6,177,6,179,6,181,6,183,6,185,6,187,6,189,6,196,6,225,6,227,6,229,6,231,6,233,6,235,6,237,6,242,6,254,7,7,7,9,7,11,7,25,7,34,7,39,7,48,7,50,7,79,7,81,7,83,7,85,7,87,7,89,7,91,7,93,7,95,7,97,7,99,7,101,7,103,7,105,7,107,7,116,7,118,7,151,7,153,7,155, +7,157,7,159,7,161,7,163,7,165,7,167,7,169,7,171,7,173,7,175,7,177,7,179,7,181,7,190,7,192,7,225,7,227,7,229,7,231,7,233,7,235,7,237,7,239,7,241,7,243,7,245,7,247,7,249,7,251,7,253,7,255,8,2,8,5,8,8,8,11,8,14,8,17,8,20,8,23,8,26,8,29,8,32,8,35,8,38,8, +41,8,44,8,53,8,55,8,56,8,65,8,67,8,68,8,77,8,92,8,97,8,115,8,120,8,134,0,0,0,0,0,0,2,2,0,0,0,0,0,0,1,57,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,136,0,0 }; + +const char* RecentFilesMenuTemplate_nib = (const char*) temp_binary_data_4; + +//================== UnityPluginGUIScript.cs.in ================== +static const unsigned char temp_binary_data_5[] = +"#if UNITY_EDITOR\n" +"\n" +"using UnityEditor;\n" +"using UnityEngine;\n" +"\n" +"using System.Collections.Generic;\n" +"using System.Runtime.InteropServices;\n" +"\n" +"public class ${plugin_class_name}GUI : IAudioEffectPluginGUI\n" +"{\n" +" public override string Name { get { return \"${plugin_name}\"; } }\n" +" public override string Description { get { return \"${plugin_description}\"; } }\n" +" public override string Vendor { get { return \"${plugin_vendor}\"; } }\n" +"\n" +" //==============================================================================\n" +" [DllImport(\"${plugin_name}\")] static extern System.IntPtr getRenderCallback();\n" +"\n" +" [DllImport(\"${plugin_name}\")] static extern void unityInitialiseTexture (int id, System.IntPtr texture, int width, int height);\n" +"\n" +" [DllImport(\"${plugin_name}\")] static extern void unityMouseDown (int id, float x, float y, EventModifiers mods, int button);\n" +" [DllImport(\"${plugin_name}\")] static extern void unityMouseDrag (int id, float x, float y, EventModifiers mods, int button);\n" +" [DllImport(\"${plugin_name}\")] static extern void unityMouseUp (int id, float x, float y, EventModifiers mods);\n" +"\n" +" [DllImport(\"${plugin_name}\")] static extern void unityKeyEvent (int id, KeyCode code, EventModifiers mods, string name);\n" +"\n" +" [DllImport(\"${plugin_name}\")] static extern void unitySetScreenBounds (int id, float x, float y, float w, float h);\n" +"\n" +" //==============================================================================\n" +" private class PluginGUIInstance\n" +" {\n" +" public PluginGUIInstance (ref IAudioEffectPlugin plugin, int id)\n" +" {\n" +" instanceID = id;\n" +"\n" +" float[] arr;\n" +" plugin.GetFloatBuffer (\"Editor\", out arr, 1);\n" +" hasEditor = (arr[0] > 0.0f);\n" +" }\n" +"\n" +" public void repaint (Rect r)\n" +" {\n" +" Vector2 newScreenPosition = GUIUtility.GUIToScreenPoint (r.position);\n" +"\n" +" if (bounds != r\n" +" || screenPosition != newScreenPosition)\n" +" {\n" +" screenPosition = newScreenPosition;\n" +" bounds = r;\n" +"\n" +" unitySetScreenBounds (instanceID, screenPosition.x, screenPosition.y, bounds.width, bounds.height);\n" +" setupTexture();\n" +" }\n" +"\n" +" GL.IssuePluginEvent (getRenderCallback(), instanceID);\n" +"\n" +" texture.SetPixels32 (pixels);\n" +" texture.Apply();\n" +"\n" +" EditorGUI.DrawPreviewTexture (bounds, texture);\n" +" }\n" +"\n" +" public bool handleMouseEvent (EventType eventType)\n" +" {\n" +" Vector2 mousePos = Event.current.mousePosition;\n" +" EventModifiers mods = Event.current.modifiers;\n" +"\n" +" if (! bounds.Contains (mousePos))\n" +" return false;\n" +"\n" +" Vector2 relativePos = new Vector2 (mousePos.x - bounds.x, mousePos.y - bounds.y);\n" +"\n" +" if (eventType == EventType.MouseDown)\n" +" {\n" +" unityMouseDown (instanceID, relativePos.x, relativePos.y, mods, Event.current.button);\n" +" GUIUtility.hotControl = GUIUtility.GetControlID (FocusType.Passive);\n" +" }\n" +" else if (eventType == EventType.MouseUp)\n" +" {\n" +" unityMouseUp (instanceID, relativePos.x, relativePos.y, mods);\n" +" GUIUtility.hotControl = 0;\n" +" }\n" +" else if (eventType == EventType.MouseDrag)\n" +" {\n" +" unityMouseDrag (instanceID, relativePos.x, relativePos.y, mods, Event.current.button);\n" +" }\n" +"\n" +" Event.current.Use();\n" +"\n" +" return true;\n" +" }\n" +"\n" +" public void handleKeyEvent (EventType eventType)\n" +" {\n" +" if (eventType == EventType.KeyDown)\n" +" {\n" +" KeyCode code = Event.current.keyCode;\n" +"\n" +" if (code == KeyCode.None)\n" +" return;\n" +"\n" +" EventModifiers mods = Event.current.modifiers;\n" +"\n" +" unityKeyEvent (instanceID, code, mods, code.ToString());\n" +" }\n" +" }\n" +"\n" +" private void setupTexture()\n" +" {\n" +" if (pixelHandle.IsAllocated)\n" +" pixelHandle.Free();\n" +"\n" +" texture = new Texture2D ((int) bounds.width, (int) bounds.height, TextureFormat.ARGB32, false);\n" +"\n" +" pixels = texture.GetPixels32();\n" +" pixelHandle = GCHandle.Alloc (pixels, GCHandleType.Pinned);\n" +"\n" +" unityInitialiseTexture (instanceID, pixelHandle.AddrOfPinnedObject(), texture.width, texture.height);\n" +" }\n" +"\n" +" public int instanceID = -1;\n" +" public bool hasEditor;\n" +"\n" +" private Vector2 screenPosition;\n" +" private Rect bounds;\n" +"\n" +" private Texture2D texture;\n" +" private Color32[] pixels;\n" +" private GCHandle pixelHandle;\n" +" }\n" +" List<PluginGUIInstance> guis = new List<PluginGUIInstance>();\n" +"\n" +" private PluginGUIInstance getGUIInstanceForPlugin (ref IAudioEffectPlugin plugin)\n" +" {\n" +" float[] idArray;\n" +" plugin.GetFloatBuffer (\"ID\", out idArray, 1);\n" +"\n" +" int id = (int) idArray[0];\n" +"\n" +" for (int i = 0; i < guis.Count; ++i)\n" +" {\n" +" if (guis[i].instanceID == id)\n" +" return guis[i];\n" +" }\n" +"\n" +" PluginGUIInstance newInstance = new PluginGUIInstance (ref plugin, id);\n" +" guis.Add (newInstance);\n" +"\n" +" return guis[guis.Count - 1];\n" +" }\n" +"\n" +" //==============================================================================\n" +" public override bool OnGUI (IAudioEffectPlugin plugin)\n" +" {\n" +" PluginGUIInstance guiInstance = getGUIInstanceForPlugin (ref plugin);\n" +"\n" +" if (! guiInstance.hasEditor)\n" +" return true;\n" +"\n" +" float[] arr;\n" +" plugin.GetFloatBuffer (\"Size\", out arr, 6);\n" +"\n" +" Rect r = GUILayoutUtility.GetRect (arr[0], arr[1],\n" +" new GUILayoutOption[] { GUILayout.MinWidth (arr[2]), GUILayout.MinHeight (arr[3]),\n" +" GUILayout.MaxWidth (arr[4]), GUILayout.MaxHeight (arr[5]) });\n" +"\n" +" int controlID = GUIUtility.GetControlID (FocusType.Passive);\n" +" Event currentEvent = Event.current;\n" +" EventType currentEventType = currentEvent.GetTypeForControl (controlID);\n" +"\n" +" if (currentEventType == EventType.Repaint)\n" +" guiInstance.repaint (r);\n" +" else if (currentEvent.isMouse)\n" +" guiInstance.handleMouseEvent (currentEventType);\n" +" else if (currentEvent.isKey)\n" +" guiInstance.handleKeyEvent (currentEventType);\n" +"\n" +" return false;\n" +" }\n" +"}\n" +"\n" +"#endif\n"; + +const char* UnityPluginGUIScript_cs_in = (const char*) temp_binary_data_5; + +//================== gradle-wrapper.jar ================== +static const unsigned char temp_binary_data_6[] = +{ 80,75,3,4,10,0,0,8,8,0,42,178,149,71,0,0,0,0,2,0,0,0,0,0,0,0,9,0,0,0,77,69,84,65,45,73,78,70,47,3,0,80,75,3,4,10,0,0,8,8,0,42,178,149,71,215,149,152,82,63,0,0,0,85,0,0,0,20,0,0,0,77,69,84,65,45,73,78,70,47,77,65,78,73,70,69,83,84,46,77,70,243,77,204, +203,76,75,45,46,209,13,75,45,42,206,204,207,179,82,48,212,51,224,229,242,204,45,200,73,205,77,205,43,73,44,1,10,234,134,100,150,228,164,90,41,184,23,37,166,228,164,98,200,194,181,26,233,25,2,245,242,114,1,0,80,75,3,4,10,0,0,8,8,0,22,178,149,71,0,0,0, +0,2,0,0,0,0,0,0,0,4,0,0,0,111,114,103,47,3,0,80,75,3,4,10,0,0,8,8,0,22,178,149,71,0,0,0,0,2,0,0,0,0,0,0,0,11,0,0,0,111,114,103,47,103,114,97,100,108,101,47,3,0,80,75,3,4,10,0,0,8,8,0,22,178,149,71,0,0,0,0,2,0,0,0,0,0,0,0,19,0,0,0,111,114,103,47,103,114, +97,100,108,101,47,119,114,97,112,112,101,114,47,3,0,80,75,3,4,10,0,0,8,8,0,22,178,149,71,104,130,100,102,163,0,0,0,213,0,0,0,35,0,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,68,111,119,110,108,111,97,100,36,49,46,99,108, +97,115,115,125,140,77,10,194,48,16,133,223,104,53,90,43,118,47,130,11,215,134,158,193,31,112,33,46,60,65,108,67,108,9,73,73,170,189,155,11,15,224,161,196,20,113,235,60,230,61,30,204,124,175,247,227,9,32,67,194,192,24,98,66,124,182,55,151,203,125,169, +37,97,186,181,173,209,86,20,235,74,220,5,97,182,51,185,182,190,52,234,40,155,171,45,24,38,132,133,117,138,43,39,10,45,121,235,68,93,75,199,127,127,171,140,0,66,114,48,70,186,141,22,222,75,79,72,59,26,215,194,40,126,186,84,50,111,8,243,63,144,116,25,16, +61,124,167,31,132,208,34,12,66,70,24,6,31,135,141,195,13,117,45,29,125,0,80,75,3,4,10,0,0,8,8,0,22,178,149,71,197,222,133,214,20,2,0,0,112,4,0,0,68,0,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,68,111,119,110,108,111,97, +100,36,83,121,115,116,101,109,80,114,111,112,101,114,116,105,101,115,80,114,111,120,121,65,117,116,104,101,110,116,105,99,97,116,111,114,46,99,108,97,115,115,165,83,109,111,18,65,16,126,22,40,135,199,209,226,169,96,173,149,218,214,122,84,229,138,111, +209,96,26,9,141,137,9,49,77,170,77,76,63,109,97,3,103,174,119,100,111,145,242,175,244,139,109,52,241,7,248,163,140,179,64,149,32,1,19,239,195,206,236,60,243,204,60,59,187,247,227,231,215,239,0,202,120,106,34,141,130,9,11,5,3,107,41,220,54,177,142,141, +20,54,83,88,214,238,29,19,91,184,107,34,14,199,192,182,129,123,12,201,23,94,224,169,93,134,184,83,60,100,72,212,194,166,96,88,170,123,129,120,211,61,57,22,242,45,63,246,41,98,215,195,6,247,15,185,244,244,126,20,76,168,182,23,49,172,31,244,35,37,78,246, +101,216,17,82,121,34,34,239,180,95,237,170,182,8,148,215,224,42,148,12,214,235,32,16,178,230,243,40,18,196,121,89,15,101,203,109,73,222,244,133,219,147,188,67,84,119,47,236,5,126,200,155,155,243,11,86,24,150,91,66,237,83,185,94,40,155,99,152,23,6,12, +27,78,177,254,129,127,228,110,32,148,59,61,169,98,224,62,3,72,190,51,83,75,185,162,7,19,59,221,97,40,204,73,100,48,15,194,174,108,136,87,158,30,79,230,2,42,105,41,22,50,88,164,26,115,100,49,44,182,149,234,148,58,250,200,239,34,33,13,60,176,80,130,75, +119,240,7,184,224,106,100,199,64,217,194,67,60,210,29,30,27,120,194,176,251,127,195,101,200,253,86,57,1,172,206,156,0,67,118,64,244,121,208,114,135,125,24,210,250,158,134,221,250,12,91,78,125,44,69,73,47,104,85,138,127,135,24,158,77,73,252,71,106,118, +50,70,34,84,88,107,115,89,149,146,147,136,132,83,60,170,49,228,167,180,56,170,233,235,94,153,113,76,172,209,95,102,65,127,113,196,244,173,210,35,90,162,157,75,150,94,20,22,182,207,16,251,76,78,12,89,90,147,131,32,199,101,90,173,97,2,108,92,35,155,64, +14,249,17,185,74,81,141,229,191,33,254,222,78,156,99,193,78,218,198,57,82,95,112,233,12,230,167,137,114,98,172,92,126,88,142,192,12,110,140,202,61,39,27,27,105,97,211,181,228,134,9,35,45,218,91,193,205,1,109,117,144,127,11,87,201,218,228,165,81,196,21, +152,184,78,22,217,212,47,80,75,3,4,10,0,0,8,8,0,22,178,149,71,231,236,88,115,170,0,0,0,219,0,0,0,34,0,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,73,68,111,119,110,108,111,97,100,46,99,108,97,115,115,69,141,193,10,194,48, +12,134,255,204,233,230,20,17,188,10,94,245,98,241,188,171,10,3,65,80,244,94,183,50,54,74,59,234,116,62,155,7,31,192,135,18,59,149,25,8,201,151,252,249,243,124,221,31,0,22,232,123,232,122,8,8,126,162,43,37,53,79,8,147,233,38,231,87,206,148,40,217,97,23, +133,95,202,52,91,103,82,132,179,35,33,88,221,98,81,148,153,86,103,15,61,203,123,125,49,177,168,247,132,65,180,252,89,205,235,67,194,88,155,148,165,134,39,82,176,202,240,162,16,134,53,26,194,240,99,47,185,74,217,246,148,139,184,36,140,254,163,230,83,135, +64,112,80,7,185,132,22,92,203,109,75,117,237,216,244,108,239,192,127,3,80,75,3,4,10,0,0,8,8,0,22,178,149,71,4,169,122,221,92,2,0,0,81,4,0,0,45,0,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,71,114,97,100,108,101,85,115,101, +114,72,111,109,101,76,111,111,107,117,112,46,99,108,97,115,115,141,83,91,79,26,65,20,254,70,145,93,214,245,82,172,40,181,182,106,91,4,91,217,90,237,85,211,196,203,170,137,84,8,32,9,79,100,133,9,174,46,187,100,89,108,252,87,189,36,106,106,210,199,62,244, +71,53,61,195,82,43,200,131,187,201,185,205,119,190,115,230,204,204,239,63,63,126,2,88,194,170,130,81,204,201,120,162,224,41,158,73,136,41,8,96,94,70,92,248,137,16,70,176,32,225,185,130,144,0,189,16,122,81,70,82,104,77,194,75,9,75,12,147,91,250,246,250, +65,42,95,218,201,174,111,165,244,210,65,78,207,150,118,211,159,116,134,112,234,216,56,53,52,203,176,171,90,206,115,77,187,186,202,48,221,141,43,101,178,233,140,158,205,23,75,123,122,145,97,104,211,177,27,158,97,123,5,195,106,114,226,191,133,215,247,11, +62,52,184,102,218,166,247,145,161,63,158,40,48,4,54,157,10,37,140,164,76,155,239,55,107,135,220,205,27,135,22,23,125,56,101,195,42,24,174,41,252,118,48,224,29,153,13,134,68,202,113,171,90,213,53,42,22,215,62,187,70,189,206,93,109,167,229,30,52,184,187, +235,212,120,202,113,78,154,117,106,125,184,218,17,103,24,141,39,252,45,154,142,182,109,90,156,48,242,90,217,106,119,165,228,156,166,91,230,98,129,33,218,139,51,41,146,85,68,48,65,92,62,121,178,73,136,228,17,65,36,188,82,177,140,21,6,245,102,13,1,127, +77,240,238,177,168,120,131,21,21,247,16,102,152,232,158,251,70,211,180,42,220,101,8,93,211,171,120,139,119,212,175,150,244,11,171,120,143,15,12,243,119,28,7,117,240,191,72,250,240,152,151,189,142,80,238,172,225,241,26,195,96,149,123,25,215,33,26,239, +140,33,22,191,125,37,18,189,110,201,120,47,32,157,113,144,232,184,125,74,134,104,205,174,48,44,222,137,178,61,0,113,64,158,227,135,24,238,199,123,212,198,44,221,250,81,122,29,253,136,138,105,146,21,197,24,105,194,147,221,71,127,20,227,55,252,32,33,153, +56,67,146,147,20,209,72,51,210,3,11,23,96,95,91,144,40,201,96,43,56,142,7,36,85,31,128,41,60,36,29,194,52,30,181,147,79,90,100,244,52,195,125,151,232,47,238,253,130,122,133,64,145,168,6,190,132,131,151,144,58,67,194,248,6,89,152,215,133,34,68,12,34,86, +136,118,12,143,73,206,32,134,185,235,194,18,22,40,38,246,37,211,234,191,174,151,41,91,124,83,87,8,21,47,160,132,7,169,254,57,212,240,16,137,115,12,127,135,44,246,194,110,236,37,66,114,166,85,118,246,47,80,75,3,4,10,0,0,8,8,0,22,178,149,71,28,226,93,219, +197,5,0,0,250,10,0,0,51,0,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,69,120,99,108,117,115,105,118,101,70,105,108,101,65,99,99,101,115,115,77,97,110,97,103,101,114,46,99,108,97,115,115,149,86,75,112,19,101,28,255,109,154, +38,105,186,109,33,64,33,80,108,0,133,180,80,130,40,22,211,130,150,216,98,104,90,160,13,165,5,21,183,201,54,93,186,221,141,155,77,75,125,32,62,234,251,117,240,232,157,163,50,35,45,88,7,198,25,71,71,199,131,58,227,129,241,194,197,25,47,158,24,47,30,196, +223,183,155,150,190,29,14,249,30,255,231,239,255,250,54,63,254,251,213,13,0,15,227,147,32,182,161,179,2,17,164,196,210,229,71,119,16,94,28,247,227,68,16,62,116,138,203,73,113,234,9,160,87,236,105,65,57,37,150,190,32,78,163,223,143,129,0,206,4,81,35,136, +53,56,27,196,51,120,54,72,83,207,5,113,14,207,251,161,4,48,40,20,51,1,100,133,154,26,68,45,134,42,145,195,112,16,26,206,87,98,4,186,31,163,126,24,126,152,18,214,164,142,39,58,207,117,36,83,237,231,122,79,117,116,36,251,37,132,82,231,149,49,37,166,43, +70,46,214,107,91,154,145,107,145,80,149,48,141,130,173,24,118,159,162,23,85,9,21,182,54,170,154,69,187,171,32,65,74,74,168,206,155,186,158,52,108,213,26,83,116,65,244,181,106,134,102,31,150,80,30,77,38,27,250,36,120,19,102,150,138,53,41,205,80,187,139, +163,131,170,149,86,6,117,85,248,51,51,138,222,167,88,154,184,151,136,94,123,88,163,149,88,202,180,114,177,156,165,100,117,53,54,110,41,249,188,106,197,218,47,100,244,98,65,27,83,59,52,93,109,203,100,212,66,161,75,49,148,156,106,17,168,79,113,8,18,218, +162,110,28,154,25,19,114,45,238,173,104,107,122,44,99,26,153,162,101,169,134,29,75,40,186,46,60,182,52,204,139,250,248,224,121,53,99,211,152,159,33,91,118,155,205,24,143,17,147,110,102,70,36,212,185,146,6,13,103,134,21,195,80,245,130,227,129,97,140,136, +76,169,243,225,49,51,11,97,136,208,148,2,205,212,255,15,32,9,1,225,207,53,178,198,82,140,172,57,234,6,235,146,54,207,217,237,89,196,19,192,75,200,230,220,44,65,155,112,47,148,173,93,152,255,137,252,108,13,30,92,29,97,107,58,221,114,152,250,65,214,67, +205,219,26,27,132,125,209,171,229,12,197,46,90,212,239,106,77,199,151,102,245,240,125,213,197,117,210,192,85,194,218,81,101,98,80,77,232,102,65,61,89,212,84,91,159,32,248,123,214,28,134,91,75,182,155,143,56,76,129,98,195,60,8,115,72,105,173,34,51,43, +47,97,221,50,70,24,88,175,89,180,50,165,50,214,175,220,117,123,133,178,140,40,242,50,30,194,78,25,187,176,83,130,60,63,74,25,47,192,146,176,113,241,100,29,41,106,122,86,181,100,20,96,203,40,98,140,237,177,87,207,140,200,24,23,132,40,46,200,152,192,139, +126,188,36,227,101,188,34,97,211,74,69,151,224,177,198,101,92,196,171,126,92,146,241,26,94,151,145,192,83,126,188,33,227,77,76,178,95,238,249,238,41,26,98,124,231,178,33,161,50,237,142,115,196,28,138,8,28,111,113,244,34,150,170,100,134,213,108,100,92, +209,108,98,141,12,153,86,100,174,185,35,238,156,69,108,51,50,68,247,113,170,189,237,66,126,199,143,119,101,188,135,247,253,248,64,198,135,200,251,241,145,140,143,145,103,158,151,41,133,132,166,251,154,113,14,195,226,158,146,80,22,21,53,175,202,169,246, +9,69,244,79,105,106,162,13,139,135,207,79,145,110,101,148,204,245,209,134,229,30,58,159,240,111,100,137,42,186,148,189,84,163,84,64,49,173,182,233,146,36,236,88,182,197,23,24,18,29,58,58,146,213,172,130,3,254,204,130,168,122,39,10,182,58,202,134,47,77, +131,40,78,151,166,235,154,43,204,167,40,200,48,18,179,35,190,109,54,146,85,134,124,235,170,2,204,139,109,77,164,156,231,237,129,21,173,149,30,184,121,64,211,195,236,17,230,170,188,160,171,42,235,235,141,30,19,145,213,69,147,171,101,170,134,224,219,6, +11,166,94,180,213,19,138,61,204,25,93,46,215,125,179,168,87,122,27,232,143,15,151,190,184,148,115,175,247,230,149,195,96,192,150,170,171,74,129,70,214,46,153,125,6,228,60,14,252,88,71,248,3,202,16,198,118,236,0,223,68,222,60,8,34,36,38,157,231,144,24, +118,71,66,98,235,55,112,109,228,109,128,50,101,220,107,26,167,33,53,110,185,10,79,99,221,85,148,93,113,148,119,59,106,94,174,219,184,110,71,5,13,87,211,240,30,82,34,174,26,154,176,23,112,78,194,141,228,156,132,35,15,207,49,236,163,20,221,120,234,248, +161,151,1,201,51,3,239,192,238,41,148,207,192,55,48,13,63,143,129,41,84,132,130,92,166,80,57,13,185,187,137,220,41,84,157,150,226,94,41,94,126,13,213,205,62,41,30,8,7,190,71,7,47,181,190,198,47,225,153,84,62,253,12,205,51,168,25,104,10,173,153,198,218, +184,55,236,157,66,40,94,30,166,234,58,71,250,238,207,97,42,175,15,123,185,80,165,108,242,26,54,92,190,59,35,236,52,205,160,118,160,4,32,180,145,158,133,201,41,108,10,133,121,38,162,205,179,96,182,220,220,115,29,117,18,226,21,97,162,220,234,24,36,38,199, +38,225,221,115,16,174,248,34,30,92,94,38,120,51,94,57,79,176,242,38,51,249,57,166,113,139,153,186,133,223,157,125,31,126,194,29,231,254,183,179,151,57,153,191,136,122,174,187,152,247,40,115,216,192,76,55,82,178,9,7,152,241,131,60,165,248,55,173,31,251, +249,111,234,17,12,145,58,130,199,144,71,51,223,196,131,184,132,86,76,226,16,61,181,209,87,2,95,163,29,223,160,3,223,226,40,126,192,211,244,215,137,95,104,225,22,121,183,201,251,131,188,63,201,251,139,188,59,228,253,67,158,168,114,15,2,180,124,131,158, +246,179,130,7,49,67,95,143,146,198,74,206,86,158,167,3,244,44,57,167,102,202,120,136,248,54,30,39,173,140,50,191,33,142,22,198,188,15,191,18,211,33,148,227,48,149,228,57,249,39,40,255,36,41,94,82,234,137,86,244,221,17,182,45,191,8,165,22,61,203,221,227, +180,232,119,168,106,188,142,7,36,92,134,55,117,133,100,47,5,171,168,230,182,106,45,141,3,39,73,237,37,189,143,156,52,219,181,223,9,164,150,50,213,220,219,25,168,219,164,71,25,42,49,32,233,184,60,246,31,80,75,3,4,10,0,0,8,8,0,22,178,149,71,204,13,94,70, +145,2,0,0,249,6,0,0,45,0,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,87,114,97,112,112,101,114,67,111,110,102,105,103,117,114,97,116,105,111,110,46,99,108,97,115,115,141,147,109,79,19,65,16,199,255,219,231,214,131,62,130, +128,162,162,34,237,33,156,160,224,51,9,15,85,49,85,12,21,72,124,67,174,112,150,35,229,142,220,93,53,241,83,105,34,49,241,133,31,192,15,101,156,189,91,160,172,219,196,55,51,179,51,243,159,253,237,92,251,251,207,207,95,0,230,240,40,135,75,152,201,96,54, +139,28,140,12,238,113,63,199,205,60,55,247,185,121,192,205,66,26,139,105,60,100,208,246,109,63,240,236,86,55,176,93,135,97,176,113,104,126,50,13,199,10,140,173,205,245,167,12,133,222,250,138,233,91,12,165,168,167,99,58,109,163,73,53,167,45,247,189,51, +131,3,134,161,222,84,243,192,156,95,88,108,118,143,24,210,95,236,227,104,18,143,162,222,212,51,219,177,131,37,134,120,181,182,205,144,88,117,247,169,158,111,216,142,245,182,123,212,178,188,247,102,171,19,222,237,238,153,157,109,211,179,249,89,36,19,193, +129,237,51,212,26,174,215,54,218,158,185,223,177,140,207,158,121,124,108,121,198,78,228,87,93,231,163,221,238,122,38,103,33,220,124,219,10,214,46,188,188,80,173,201,111,207,251,114,83,177,122,177,135,179,150,165,81,209,211,42,167,227,46,174,169,236,171, +154,135,170,255,246,170,70,71,187,146,103,68,217,17,169,183,103,225,35,126,223,82,142,84,31,78,63,71,206,239,61,68,149,104,184,168,136,67,211,237,122,123,214,11,155,239,126,84,181,224,89,254,26,13,21,12,209,94,95,110,46,175,53,234,187,91,205,250,230, +238,171,141,55,117,13,131,200,51,12,156,126,33,254,43,241,53,20,144,215,80,226,166,204,141,134,1,13,69,222,56,245,159,95,149,174,58,95,226,70,235,208,218,11,48,1,254,135,0,82,136,241,137,20,197,248,237,161,47,8,95,20,190,36,124,57,244,3,96,156,159,236, +48,157,118,40,207,200,143,235,63,192,244,82,236,4,113,189,148,56,65,50,140,83,97,156,254,22,202,47,147,29,70,146,108,5,9,138,114,148,41,96,148,162,49,140,80,86,139,6,81,102,140,60,195,21,92,21,151,24,228,121,45,169,127,71,230,235,217,176,148,16,156,139, +147,103,226,113,92,19,226,37,234,142,241,110,125,250,4,153,115,148,92,152,157,32,205,205,112,194,112,212,37,38,240,72,11,223,202,112,29,55,20,32,113,25,100,82,9,50,65,227,21,32,113,25,164,70,26,189,15,8,255,48,252,226,91,74,144,164,12,50,163,4,185,173, +6,73,202,32,115,164,153,239,3,82,16,32,147,74,144,172,12,178,160,4,185,163,6,201,202,32,143,73,243,164,15,72,81,128,76,41,65,82,50,200,115,37,72,85,13,146,146,65,150,73,179,210,7,164,36,64,106,74,144,180,12,82,87,130,232,106,144,180,12,178,78,154,215, +125,64,202,2,100,58,212,220,253,11,80,75,3,4,10,0,0,8,8,0,22,178,149,71,81,125,29,105,229,4,0,0,25,10,0,0,48,0,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,83,121,115,116,101,109,80,114,111,112,101,114,116,105,101,115,72, +97,110,100,108,101,114,46,99,108,97,115,115,141,86,235,115,19,85,20,255,109,155,100,195,118,203,163,80,74,74,133,8,2,105,250,136,128,21,108,10,42,208,74,165,15,36,80,44,130,186,77,111,147,133,100,55,108,54,180,21,21,159,248,70,253,194,12,142,195,87,62, +57,131,195,24,192,206,200,119,255,40,245,119,55,161,205,139,218,102,122,238,189,231,117,207,249,157,115,207,236,223,255,252,249,23,128,253,248,89,195,46,140,168,120,67,67,19,70,52,156,196,168,138,55,53,248,37,243,148,6,21,99,242,48,46,119,19,42,38,85, +156,86,241,150,134,86,140,4,113,70,174,9,73,206,74,114,78,131,142,169,32,206,107,120,27,211,210,236,66,11,222,193,197,22,92,194,187,146,188,39,47,59,39,165,239,107,48,48,35,73,82,195,44,132,84,158,107,65,10,105,21,166,138,203,10,2,67,166,101,186,71,21, +52,71,186,167,20,248,142,219,179,66,193,134,49,211,18,19,133,236,140,112,206,26,51,25,114,218,198,236,164,145,153,50,28,83,158,203,76,159,155,54,243,10,122,199,108,39,21,75,57,198,108,70,196,230,29,35,151,19,78,44,177,152,119,69,246,180,99,243,224,154, +34,127,210,176,40,118,226,10,54,167,132,91,43,85,176,51,50,118,217,184,102,196,76,59,54,98,102,68,188,187,116,44,184,102,38,54,110,228,104,23,52,173,132,235,8,35,171,32,84,165,59,106,229,10,110,73,68,53,133,129,181,47,203,71,39,135,23,146,34,231,154, +182,69,89,243,21,177,40,115,241,164,25,195,74,197,104,102,90,41,138,212,172,225,38,211,194,89,118,238,221,236,136,148,88,224,253,158,72,198,96,56,169,66,86,88,110,181,151,201,153,203,34,233,82,222,100,190,160,96,75,133,131,81,87,56,134,107,75,219,245, +185,229,116,101,212,100,84,103,172,160,165,172,177,200,132,101,17,106,17,208,114,21,128,109,173,16,175,0,41,51,201,25,46,111,181,26,101,114,186,36,138,75,243,170,130,46,230,158,22,117,160,250,218,161,122,176,234,57,71,233,112,93,194,76,89,134,91,112, +232,99,120,245,98,174,217,167,150,176,11,78,82,148,224,234,122,70,75,245,75,83,29,187,65,232,55,173,220,115,210,200,167,121,151,138,43,58,50,96,211,108,105,132,151,130,142,103,180,146,244,104,233,176,145,211,113,85,250,222,220,160,167,20,116,174,4,126, +166,96,185,102,86,84,8,59,106,179,58,86,48,51,179,178,201,118,15,59,142,237,132,231,211,194,10,103,108,99,150,178,240,74,117,195,115,140,229,136,14,7,121,73,92,29,5,92,147,1,205,43,216,152,95,134,225,98,127,164,63,218,173,98,65,199,34,62,208,113,29,31, +170,248,72,199,199,184,161,226,19,29,159,130,89,124,134,207,117,28,192,23,42,190,212,113,83,114,190,194,215,42,190,209,241,45,190,211,241,61,126,80,113,75,199,143,248,73,65,116,237,15,153,129,212,246,191,2,189,18,75,14,23,179,220,233,28,46,23,88,156, +218,174,144,3,71,38,175,96,219,138,168,242,53,75,13,127,50,99,231,165,51,25,142,69,221,190,72,125,179,116,215,177,202,72,199,107,244,203,47,117,53,253,160,107,151,88,108,153,72,189,34,53,162,13,34,168,224,156,77,59,246,188,124,76,94,252,29,207,120,131, +124,168,73,59,155,243,240,89,37,165,134,143,55,192,57,150,16,174,132,180,82,141,44,10,91,171,24,114,110,150,103,16,31,125,149,122,197,108,106,171,231,50,190,180,145,159,16,11,116,225,179,188,165,26,142,229,161,119,176,50,250,227,105,195,73,136,171,5, +97,37,69,131,28,86,70,105,29,46,227,79,7,176,111,206,148,117,246,167,28,187,192,57,216,30,25,109,88,133,141,181,60,226,146,17,86,202,77,123,13,55,74,154,146,249,239,253,159,250,47,231,81,1,156,55,128,155,217,136,10,14,55,48,95,147,67,60,207,223,46,200, +191,38,40,114,62,145,238,225,41,198,85,225,234,143,62,132,242,187,39,222,75,26,240,152,219,177,143,84,47,41,32,130,110,174,235,16,69,15,181,104,172,60,128,15,65,242,254,88,66,211,244,67,52,143,69,139,240,253,2,127,207,253,37,248,201,8,140,47,65,157,166, +231,224,68,111,95,17,235,248,175,221,131,62,232,147,155,144,239,201,61,132,39,150,160,79,47,161,149,218,235,219,54,20,177,145,46,54,21,209,214,247,16,155,159,180,109,121,132,246,137,222,34,182,62,70,135,130,65,95,200,247,24,219,20,220,193,9,185,11,145, +229,239,11,249,139,232,44,98,251,96,32,20,40,162,235,14,246,132,2,190,34,158,27,84,67,106,17,59,238,162,189,39,164,246,74,173,157,84,124,140,112,51,206,223,251,247,81,207,125,52,19,145,125,232,103,2,253,120,209,91,67,56,132,65,180,80,34,65,152,66,59, +233,14,166,184,19,27,16,198,38,234,135,136,220,46,74,247,17,142,30,2,210,207,245,16,122,105,21,69,156,156,243,228,92,34,170,215,233,241,38,63,182,110,113,220,221,198,65,220,197,75,184,79,205,7,56,236,129,58,7,249,97,212,78,203,62,222,22,71,23,237,98, +220,221,70,39,45,247,243,211,235,38,61,30,160,101,128,190,6,104,61,192,18,164,113,10,47,211,139,79,130,78,79,175,112,13,226,55,222,30,103,145,66,248,21,67,56,194,226,92,226,247,214,81,188,74,127,175,149,11,88,210,122,157,187,99,94,145,143,115,119,194, +219,13,255,7,80,75,3,4,10,0,0,8,8,0,22,178,149,71,165,121,48,186,86,2,0,0,0,5,0,0,31,0,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,76,111,103,103,101,114,46,99,108,97,115,115,133,147,251,111,210,80,20,199,191,151,199,42, +175,49,198,112,76,152,19,157,10,69,87,134,111,49,38,134,100,9,17,31,9,102,38,251,173,148,155,174,75,105,161,20,141,255,138,127,133,26,197,196,31,252,3,252,163,140,231,182,13,18,88,179,144,158,158,115,239,57,159,243,42,127,254,254,250,13,224,16,79,147, +72,224,102,2,151,112,43,129,219,168,38,81,131,44,68,93,136,59,66,220,149,112,32,65,145,208,96,136,143,167,6,119,25,216,9,195,218,51,195,50,220,231,12,177,234,73,237,152,94,109,123,192,25,178,93,195,226,175,167,195,62,119,222,169,125,147,78,54,187,182, +166,154,199,170,99,8,59,56,140,185,167,198,132,161,212,181,29,93,209,29,117,96,114,229,163,163,142,70,220,81,186,182,174,115,167,197,16,53,109,157,161,80,237,158,169,31,84,197,84,45,93,233,185,142,97,233,45,145,80,26,242,201,68,213,189,12,43,14,84,159, +128,89,3,134,198,98,124,251,84,117,122,124,60,229,150,198,91,181,133,139,23,158,183,40,78,36,214,38,99,134,98,88,28,67,51,148,217,233,132,82,227,19,87,117,196,244,58,148,193,43,109,167,218,14,245,102,26,61,109,134,100,207,158,58,26,63,50,196,216,82,254, +108,14,68,76,26,25,28,166,145,66,90,66,51,141,123,184,47,225,65,26,15,81,72,163,136,71,66,60,22,226,9,229,9,157,50,195,198,255,252,111,250,103,92,163,2,183,206,43,137,106,174,138,177,47,248,247,62,77,92,62,164,11,123,74,81,5,191,19,195,86,222,210,10, +92,90,4,87,135,212,72,254,156,99,218,222,72,88,166,197,160,92,180,159,21,226,225,197,211,95,137,41,206,71,189,116,133,10,125,253,9,208,160,233,217,20,227,164,127,70,156,244,12,214,73,102,201,58,66,132,126,64,82,254,9,38,151,126,32,242,149,172,8,54,72, +174,35,74,242,50,98,216,38,74,17,57,207,242,188,137,150,7,60,77,80,105,157,216,66,33,96,190,12,152,89,249,59,34,159,145,252,134,104,125,134,216,50,184,4,9,101,210,175,46,128,179,115,112,150,78,182,61,112,17,59,1,248,85,0,206,249,224,148,15,142,191,151, +191,44,161,43,132,190,78,33,251,11,232,220,28,157,195,21,74,238,163,203,1,90,163,46,99,244,206,251,232,140,64,151,119,103,88,91,133,87,9,94,35,72,221,131,203,126,216,28,158,15,224,66,219,165,222,34,158,182,71,90,212,75,120,45,188,151,210,12,210,106,58, +133,210,53,40,164,25,210,75,133,58,21,189,220,240,226,246,255,1,80,75,3,4,10,0,0,8,8,0,22,178,149,71,206,114,235,138,21,7,0,0,110,14,0,0,38,0,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,80,97,116,104,65,115,115,101,109, +98,108,101,114,46,99,108,97,115,115,149,86,249,99,27,87,17,254,214,214,21,121,147,56,138,115,216,181,131,98,39,141,44,217,22,73,83,40,73,19,240,213,68,173,175,250,42,78,218,184,107,107,35,111,42,239,186,187,171,196,134,114,19,40,247,125,4,2,148,251,6, +23,90,41,196,180,1,126,228,143,2,190,217,93,91,182,42,211,246,7,189,55,239,105,222,204,55,51,223,155,183,255,254,207,253,55,1,156,198,191,226,56,138,194,30,156,197,82,28,6,110,196,41,189,32,67,81,134,229,40,76,217,182,100,177,18,197,139,113,196,81,144, +29,91,36,39,6,87,230,82,28,81,220,148,237,91,50,172,70,177,22,199,65,124,36,142,143,202,127,103,241,82,12,31,139,226,227,113,124,2,159,140,225,83,113,124,26,159,145,197,103,69,186,29,197,231,100,254,124,28,199,240,178,12,95,136,226,139,81,124,41,134, +47,199,209,133,175,196,240,85,81,254,154,12,95,23,155,223,16,233,155,49,124,75,230,111,199,240,157,24,190,27,199,247,240,125,193,113,39,134,31,196,240,67,57,121,39,138,187,10,14,140,88,139,90,113,200,112,92,219,88,40,185,134,101,42,80,115,166,169,219, +131,69,205,113,116,71,193,145,75,147,253,67,35,195,243,51,83,195,147,243,151,199,71,135,231,167,166,39,115,99,151,20,36,70,110,104,55,181,108,81,51,11,217,41,26,48,11,231,21,236,29,180,76,199,213,76,119,86,43,150,116,5,251,38,38,199,159,28,30,156,222, +58,181,175,96,107,249,162,62,227,232,246,101,107,89,52,124,51,134,149,125,194,40,234,52,17,121,220,48,13,247,162,130,198,84,247,172,130,208,160,149,167,218,254,17,195,212,199,74,203,11,186,61,173,45,20,117,241,47,224,103,53,219,144,117,176,25,114,151, +12,162,238,28,177,236,66,214,119,149,189,101,107,43,43,186,157,157,208,220,165,126,70,181,76,77,155,142,14,164,118,186,22,111,251,11,186,187,51,31,243,169,122,182,158,241,103,70,123,221,40,148,108,77,116,207,119,191,173,215,19,111,73,184,228,108,113, +187,21,5,117,205,212,117,168,32,182,160,57,250,152,38,137,140,229,105,214,23,155,108,203,98,24,182,191,138,202,31,92,5,210,21,99,69,193,120,234,173,213,123,23,113,214,169,124,180,100,23,47,107,206,18,37,230,208,151,30,174,227,165,238,225,189,203,186, +227,104,5,125,200,40,232,142,171,160,195,87,114,244,197,146,109,184,107,217,209,237,127,83,63,188,176,230,10,59,27,174,14,40,80,24,227,161,109,86,135,87,23,245,149,32,63,17,199,115,193,194,218,250,178,117,83,31,94,117,117,211,241,210,28,50,189,236,40, +204,134,146,99,206,130,202,251,57,235,12,144,155,186,155,157,153,204,237,18,178,164,115,198,46,110,145,120,83,155,198,87,88,118,5,113,26,29,96,133,188,236,119,238,158,141,42,251,67,82,80,30,156,178,74,246,162,46,155,100,250,14,14,245,201,9,21,23,112, +81,197,121,60,30,197,143,84,12,227,199,42,158,195,53,21,115,120,90,197,83,24,227,69,222,110,89,197,79,240,138,138,5,44,242,74,215,162,24,40,25,197,188,110,171,248,169,232,252,12,63,103,70,178,42,126,33,171,11,248,165,138,95,137,244,107,188,162,224,204, +187,103,184,216,248,77,20,191,85,49,129,167,89,186,147,78,246,36,75,215,92,69,49,190,112,67,95,116,163,248,157,138,223,227,15,188,248,163,67,143,70,241,71,21,127,194,159,85,172,227,85,21,127,193,95,21,180,120,71,150,233,46,59,96,20,114,166,171,23,4,245, +107,162,112,1,175,11,226,178,130,131,117,152,160,160,173,186,59,89,50,93,99,89,223,246,103,251,160,85,42,230,147,166,229,38,151,72,220,164,97,174,148,220,164,79,157,62,177,93,97,70,40,220,195,223,84,220,199,134,138,191,75,70,238,139,187,230,218,6,169, +226,13,188,73,114,4,157,143,23,179,196,102,215,151,55,236,40,30,168,248,135,20,232,2,254,73,110,10,51,206,37,73,189,164,225,36,75,230,11,166,117,139,96,146,111,151,98,5,167,222,225,77,37,186,84,119,45,53,15,214,180,184,1,143,112,45,169,186,20,175,85, +158,240,104,29,17,87,102,94,65,239,59,186,224,1,191,164,93,185,214,84,112,33,187,106,186,111,29,67,179,254,5,98,195,242,49,6,11,31,67,127,221,190,188,179,199,215,243,176,189,219,171,219,83,179,131,146,155,40,35,215,45,155,132,83,240,129,58,145,94,29, +169,229,112,253,62,241,208,255,105,102,126,227,201,121,143,230,34,99,60,189,123,70,119,237,134,49,233,50,126,67,12,165,186,165,37,70,74,43,121,205,165,185,112,234,234,128,68,26,201,7,222,34,169,156,191,115,40,149,171,11,54,93,239,101,168,238,76,47,217, +214,45,121,107,189,4,54,241,51,129,224,243,250,234,248,117,49,89,7,59,243,186,199,41,45,108,246,225,195,169,92,125,191,242,106,4,236,210,95,44,105,69,167,198,222,102,130,175,236,172,211,154,227,234,203,126,18,39,108,139,20,112,215,118,1,50,139,227,252, +222,58,202,111,187,70,180,226,253,120,12,172,42,87,13,200,112,125,110,219,186,151,63,118,86,202,49,238,177,209,114,252,32,87,143,112,86,56,135,211,21,40,175,122,170,31,226,24,231,12,116,32,196,239,179,126,74,170,175,132,1,12,114,22,3,67,129,129,39,168, +41,186,113,49,144,206,188,142,134,170,149,125,132,5,36,105,229,56,246,160,211,179,116,216,215,14,44,137,36,176,4,196,48,109,249,54,255,75,79,81,206,183,211,153,50,26,43,8,141,166,123,42,8,143,165,123,51,21,68,206,133,54,16,157,147,191,98,21,236,217,64, +124,174,130,38,174,212,50,246,38,246,113,104,13,113,40,99,127,5,205,231,194,155,186,7,118,232,38,118,232,122,82,79,245,80,100,3,7,231,210,173,225,214,72,5,45,235,91,225,180,33,194,49,197,80,186,177,31,105,28,97,150,7,209,131,85,102,87,66,187,236,131, +222,10,237,54,46,113,143,92,193,75,200,177,22,13,60,117,19,79,82,106,228,89,147,79,218,99,76,205,32,245,71,152,130,48,237,236,197,40,165,8,53,249,220,5,201,184,193,127,66,156,143,165,137,176,177,140,67,21,28,30,75,28,9,191,129,163,115,141,153,169,185, +80,239,212,61,180,174,215,148,238,52,75,118,198,67,149,246,79,111,161,58,230,33,80,60,73,240,53,80,51,129,113,15,85,131,188,103,129,223,187,60,39,39,251,18,109,247,240,208,40,147,214,62,214,211,91,70,199,6,142,205,133,136,229,61,21,36,155,79,148,113, +124,125,116,3,93,115,137,19,172,209,201,7,158,229,227,44,118,231,142,172,245,115,28,64,19,49,52,147,58,157,44,118,23,203,45,248,206,50,190,8,218,49,137,41,158,104,98,102,166,49,67,44,93,148,103,241,140,23,77,223,22,250,62,124,216,67,223,32,95,5,1,210, +107,212,22,162,181,100,18,15,151,113,234,66,251,93,132,51,235,153,198,246,50,82,213,188,36,188,104,158,98,141,70,104,121,148,185,30,247,252,39,253,179,91,30,90,112,197,243,16,165,198,85,60,235,209,155,159,33,129,47,155,218,98,167,141,249,232,30,237,17, +230,156,186,216,65,135,61,235,61,29,161,231,203,72,87,61,30,102,100,96,84,97,70,164,50,166,102,198,147,32,254,106,85,218,182,188,182,97,30,207,211,71,24,135,160,121,92,81,121,125,196,191,84,133,223,56,129,255,151,121,78,50,50,148,73,16,65,207,29,196, +210,175,161,97,61,147,232,245,86,205,66,247,68,223,61,100,43,120,239,186,148,37,224,124,226,52,233,157,17,174,159,217,228,249,35,15,106,144,62,75,166,62,71,175,215,88,131,121,156,32,142,234,133,29,218,66,58,132,124,80,1,221,59,127,29,239,243,88,199,135, +149,181,124,20,202,255,0,80,75,3,4,10,0,0,8,8,0,22,178,149,71,56,222,182,221,27,19,0,0,236,41,0,0,32,0,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,73,110,115,116,97,108,108,46,99,108,97,115,115,157,89,11,124,20,229,181, +63,39,187,217,217,44,195,43,16,194,202,107,68,34,121,135,55,26,16,13,73,144,216,16,144,240,48,32,234,100,119,146,140,236,35,238,206,146,68,173,90,139,74,213,190,80,91,209,86,172,143,98,45,85,81,73,208,40,216,106,125,182,246,161,181,181,181,213,86,107, +111,235,237,189,189,247,246,222,219,251,42,247,127,102,118,55,155,100,16,226,47,191,253,102,230,123,156,231,255,156,239,124,95,94,253,251,211,71,137,104,33,127,16,160,62,206,151,198,39,141,34,141,95,154,130,2,52,1,105,198,201,167,26,160,50,30,175,240, +4,15,241,155,207,5,40,192,19,101,108,146,52,147,3,92,200,83,164,153,26,224,34,158,22,160,59,184,88,154,233,10,7,3,52,149,103,200,252,153,10,207,242,243,236,0,207,97,77,225,211,3,116,26,207,13,240,25,60,79,122,74,164,57,83,225,249,1,154,195,227,3,92,202, +101,1,170,227,114,249,172,144,166,82,154,170,113,92,205,53,10,47,240,243,66,133,23,201,140,197,1,154,207,75,164,127,169,159,151,201,115,185,136,123,150,140,157,29,160,98,174,245,243,10,121,174,44,224,115,120,85,128,207,229,243,2,120,171,83,120,117,128, +150,131,23,198,234,165,105,144,166,81,40,172,17,10,231,251,121,173,244,52,41,124,129,194,159,242,115,179,159,215,73,71,75,128,206,227,245,210,108,8,240,133,188,81,225,214,0,173,229,241,126,222,36,207,205,210,84,5,120,11,111,85,248,34,133,219,100,210, +182,0,173,231,237,1,106,225,139,21,222,17,160,86,225,219,194,151,248,249,82,249,184,76,154,42,133,245,0,181,113,187,194,161,0,109,231,118,63,135,253,108,248,185,67,228,237,44,224,46,54,69,171,203,253,188,83,158,17,17,38,170,112,44,64,29,176,36,154,248, +56,238,230,43,164,73,40,156,12,208,78,110,148,198,146,137,41,133,119,41,220,19,160,110,153,27,231,94,89,208,39,138,94,25,224,171,248,106,249,188,90,222,62,45,62,185,90,225,107,152,130,13,141,107,234,54,55,111,186,180,161,169,117,211,198,166,213,155,55, +53,173,111,185,116,67,221,166,181,76,133,205,151,235,187,244,154,136,30,235,172,105,181,18,102,172,115,5,211,248,250,120,44,105,233,49,107,139,30,73,65,242,107,153,124,145,120,103,167,145,96,154,209,28,79,116,214,116,38,244,112,196,168,233,73,232,221, +221,70,162,166,217,30,196,74,127,56,222,19,139,196,245,48,211,108,183,137,77,13,233,113,225,210,173,91,93,117,201,164,17,109,143,8,229,185,110,11,54,228,206,193,162,211,140,222,80,36,149,52,119,25,107,204,136,81,23,10,25,201,228,58,61,166,219,178,213, +184,81,104,60,225,2,144,243,173,52,99,166,181,138,233,146,210,143,209,235,227,53,57,185,216,101,91,152,188,245,241,176,193,52,177,217,140,25,45,169,104,187,145,216,164,99,80,60,16,15,233,145,45,122,194,148,239,116,167,215,234,50,147,76,51,93,57,139,111, +34,17,72,31,8,37,12,221,50,26,204,164,197,116,182,171,6,91,157,39,28,218,97,118,166,18,186,101,198,99,43,202,28,167,155,241,26,177,137,184,34,148,59,206,84,118,202,164,160,81,24,236,19,102,123,74,190,55,39,34,76,19,28,242,49,195,170,217,188,177,9,83, +138,114,167,180,118,233,139,150,46,107,77,69,153,38,71,68,245,134,156,65,133,175,67,119,243,200,110,38,181,41,22,3,239,136,14,163,194,48,75,78,106,244,121,163,136,64,16,69,4,105,48,19,89,25,135,76,160,218,178,108,51,187,229,27,166,5,108,140,110,89,150, +84,248,51,240,18,6,67,169,8,172,157,35,255,220,210,225,84,202,220,130,201,211,101,244,50,177,137,95,19,28,219,97,147,207,139,34,66,102,57,211,147,70,40,149,48,173,190,154,117,128,38,112,217,96,118,26,73,75,86,118,8,6,138,178,60,154,98,221,41,11,116,13, +61,138,81,134,85,124,237,169,142,14,65,126,222,246,213,8,190,246,62,128,65,183,116,166,2,48,117,36,96,154,62,74,170,213,246,42,208,152,217,105,88,117,177,240,22,35,97,118,244,229,218,106,99,60,14,72,45,24,161,223,104,245,70,33,169,56,215,213,13,70,50, +148,48,187,29,15,122,195,102,2,234,76,114,86,96,60,82,211,108,218,122,78,27,30,1,125,221,153,40,208,70,204,93,57,156,219,42,89,187,203,145,61,29,140,245,93,70,104,103,82,124,179,180,116,180,180,39,213,6,113,170,68,29,47,192,134,122,200,74,233,17,219, +211,5,201,120,42,17,50,108,120,143,51,122,187,141,144,101,132,237,17,127,196,129,20,84,211,220,225,144,171,170,87,79,36,230,33,102,182,143,180,155,55,98,196,48,144,103,162,41,104,53,59,99,186,149,74,24,163,93,48,146,166,139,73,166,39,13,171,177,23,160, +178,196,138,27,140,68,212,76,38,5,200,136,172,145,212,182,8,203,100,22,35,232,119,176,97,132,55,26,122,216,73,145,73,43,28,79,89,89,32,218,172,215,196,19,81,221,178,236,9,222,8,82,26,232,116,183,35,61,231,24,117,67,34,46,201,118,117,202,140,56,148,176, +161,209,148,209,19,100,196,24,134,243,245,217,224,91,145,5,129,189,162,41,6,150,137,84,55,140,159,59,37,224,36,130,181,241,40,232,140,119,62,234,227,209,168,30,67,148,169,88,17,79,172,203,122,213,76,110,53,99,216,166,160,181,167,180,108,27,20,140,39, +91,116,89,89,16,54,34,134,164,211,132,139,165,48,81,73,166,236,237,3,242,226,203,31,234,130,98,9,3,208,158,178,221,53,240,195,66,40,63,21,187,210,132,226,115,92,99,41,215,17,249,70,204,74,244,101,125,97,219,25,75,107,144,147,26,101,68,146,20,28,145,205, +1,18,56,25,34,235,115,250,133,181,205,210,27,54,100,99,80,132,174,41,89,179,56,135,114,99,44,21,53,178,73,92,185,50,147,248,138,71,115,79,67,116,98,40,222,221,151,147,131,152,170,75,93,115,147,187,84,14,214,96,45,143,141,38,79,68,44,23,208,109,139,206, +91,176,96,1,83,179,235,14,150,217,238,198,156,138,242,122,23,72,179,80,154,69,67,172,22,10,43,247,205,50,195,202,117,251,203,214,56,25,66,139,132,208,202,177,19,202,173,129,50,180,22,159,156,214,73,115,75,134,214,18,161,85,53,22,90,219,134,22,47,149, +197,23,158,194,226,177,230,213,188,222,197,67,92,150,9,151,21,99,118,119,110,180,100,72,45,31,179,182,178,184,213,78,231,14,226,213,244,188,106,153,166,210,243,244,130,74,191,161,119,85,58,76,253,42,253,156,126,161,210,32,61,163,210,117,244,25,149,174, +161,107,85,122,132,30,85,233,70,190,30,140,199,84,112,202,162,207,170,180,155,110,80,233,122,250,172,194,187,85,190,129,111,84,249,38,222,163,240,231,228,227,102,149,111,225,91,85,254,60,223,138,237,249,196,74,205,3,172,73,232,125,65,229,47,242,151,160, +69,174,146,8,232,214,181,117,85,168,83,20,254,178,202,123,249,54,4,118,238,132,156,112,5,17,122,65,225,219,85,190,131,191,162,242,87,249,78,149,247,241,93,200,46,238,101,131,194,119,171,252,53,254,186,202,247,240,126,149,239,229,111,72,115,159,202,247, +139,18,15,168,252,32,253,12,27,193,208,226,141,169,152,101,70,141,108,194,102,186,236,124,91,39,45,183,86,208,230,151,36,231,107,225,184,145,212,98,113,75,67,65,106,233,102,76,211,99,125,152,150,192,126,27,151,28,86,173,53,166,55,95,205,138,107,29,72, +228,154,209,139,125,58,210,167,45,204,206,235,171,70,153,49,196,127,125,251,229,232,86,249,155,124,64,12,246,144,202,223,226,253,76,59,78,40,68,154,119,18,44,226,90,244,147,73,160,242,195,252,109,149,238,33,152,232,32,127,71,229,71,96,21,238,178,43,45, +51,100,167,93,45,222,161,185,201,208,161,195,65,225,211,75,98,37,177,54,192,212,117,78,84,239,211,186,244,93,134,214,110,24,49,205,210,163,221,178,103,107,61,166,213,85,93,18,179,75,244,68,84,179,186,116,11,141,161,205,119,45,192,231,107,221,137,56,22, +90,125,26,44,221,39,188,28,176,85,165,193,86,157,30,135,218,154,212,173,154,153,132,113,18,162,35,28,19,150,37,154,158,128,104,233,132,6,140,216,236,210,203,181,142,68,60,170,233,154,149,72,37,197,94,78,13,85,45,138,105,185,197,166,134,178,170,86,43, +73,150,196,50,153,81,147,138,80,134,156,238,172,197,67,233,242,174,214,118,20,200,104,117,118,141,54,106,64,229,71,5,141,143,169,124,136,31,87,248,9,149,159,20,199,31,230,126,236,214,67,153,179,46,145,208,251,36,125,170,60,64,63,83,249,8,63,165,242,211, +242,54,8,159,209,155,130,228,64,187,25,75,7,161,192,231,25,108,208,39,170,113,134,193,46,83,126,231,135,186,162,113,212,33,158,229,75,151,170,252,44,239,17,42,71,85,62,198,207,41,252,93,149,191,39,96,44,30,29,107,105,138,90,171,97,1,97,153,114,78,235, +30,170,231,180,142,120,162,86,147,232,123,94,225,23,84,254,62,63,148,137,218,81,133,28,83,208,101,171,118,198,84,126,145,95,18,169,94,150,230,149,97,22,202,22,122,42,191,202,123,80,83,136,63,36,150,94,203,76,27,94,176,169,252,3,153,54,251,227,107,54, +166,242,250,120,42,18,182,67,61,121,18,5,177,91,111,136,24,122,82,112,166,201,185,88,98,18,78,71,196,153,29,54,6,123,244,152,37,209,152,194,28,193,95,58,98,54,55,33,17,40,241,100,117,12,229,157,202,63,228,215,21,254,145,202,63,230,159,168,252,83,126, +3,99,61,78,37,168,242,155,12,159,191,197,63,71,25,234,90,254,168,244,33,255,66,225,183,85,254,165,160,227,87,252,78,198,210,163,202,52,149,127,13,31,243,111,4,59,51,71,58,99,253,176,250,109,122,110,74,206,29,18,63,188,43,110,121,79,165,63,209,71,10,255, +86,229,223,241,245,42,191,207,119,34,183,158,120,91,64,249,155,233,145,144,71,205,183,104,236,7,229,140,103,109,247,229,248,12,229,178,148,169,165,77,77,242,156,127,138,87,4,40,28,113,202,28,78,127,82,105,217,200,59,130,233,35,38,229,28,179,167,150,186, +30,172,181,147,105,198,116,233,88,238,68,62,209,141,66,225,8,177,237,195,67,86,189,161,98,52,128,121,217,203,133,221,159,184,242,25,110,181,83,86,206,189,36,243,233,233,227,76,157,235,217,196,70,54,246,194,80,10,25,63,102,213,212,67,56,137,208,97,215, +28,206,230,10,5,103,124,204,93,6,206,204,80,223,214,47,22,130,254,11,93,206,230,101,39,185,12,153,226,146,190,144,142,240,8,11,38,183,175,46,107,130,70,169,238,176,110,73,249,131,14,7,166,190,112,90,4,111,105,153,92,146,76,30,158,153,236,123,195,113, +86,124,237,208,125,73,81,105,147,43,222,124,56,177,116,90,93,118,28,8,47,177,179,28,48,103,148,214,143,158,159,189,98,169,60,177,174,110,211,253,86,60,35,199,132,225,21,62,148,50,147,141,209,110,11,71,68,95,135,157,150,237,115,204,40,234,219,71,187,199, +85,159,34,55,201,228,166,50,105,94,9,19,122,224,178,81,198,200,186,219,103,92,129,20,156,28,65,37,195,78,78,213,206,97,218,137,254,186,246,100,60,146,178,12,137,167,225,155,100,31,42,3,248,209,131,45,34,247,10,96,3,164,25,58,206,78,113,233,134,57,186, +229,43,34,87,75,70,175,105,123,216,241,56,190,236,212,87,32,87,51,2,104,251,230,163,108,212,157,203,56,51,217,144,41,216,32,130,30,134,51,207,56,249,149,23,88,76,130,78,245,122,44,30,67,41,23,113,148,154,86,234,114,9,96,231,75,160,62,97,91,50,215,144, +67,119,31,147,71,117,202,198,164,155,22,182,94,251,100,115,74,240,201,220,177,4,79,120,114,149,35,119,92,96,101,135,98,78,12,21,231,100,171,225,87,140,211,221,207,247,162,213,148,161,161,244,77,145,244,250,37,28,155,237,235,160,149,99,66,230,168,75,37, +201,151,217,59,27,201,30,27,210,165,42,211,153,167,100,146,21,25,156,57,1,36,169,91,46,169,54,183,102,255,231,145,51,176,194,206,1,205,241,30,36,78,20,26,67,60,114,231,184,242,80,80,65,24,189,235,59,78,16,78,77,246,245,88,210,113,191,235,45,81,176,52, +215,4,195,111,101,138,92,7,16,82,93,122,114,93,60,97,52,70,140,40,50,51,0,51,46,102,244,90,233,207,145,27,102,54,102,21,152,209,185,233,242,69,119,58,183,177,193,33,55,142,186,172,169,201,181,193,176,139,168,19,225,101,170,27,45,169,128,35,113,49,106, +126,15,50,187,65,167,83,31,149,17,81,62,5,233,74,186,138,152,174,198,87,30,125,154,10,229,120,141,247,66,57,107,219,79,156,146,237,39,142,204,120,78,193,220,27,233,38,180,123,240,117,29,40,120,241,156,87,62,64,5,229,131,20,104,43,28,55,153,94,30,32,245, +48,141,47,175,56,76,74,121,229,97,242,149,87,29,166,9,135,108,14,159,67,123,26,249,208,206,197,74,141,166,210,25,144,97,30,205,166,18,188,157,73,55,99,164,220,161,73,183,208,173,68,246,155,200,196,246,155,72,149,103,191,137,92,30,244,126,158,190,128, +30,145,230,8,5,72,193,115,85,69,63,77,92,135,102,82,75,249,147,52,1,47,147,107,189,65,111,63,21,214,230,203,99,74,173,15,253,227,131,190,65,154,218,86,30,244,5,243,43,43,170,6,168,168,159,166,61,71,197,143,141,144,179,12,58,150,131,114,37,100,173,162, +25,84,13,201,23,216,114,174,117,184,101,229,92,69,95,164,47,65,162,124,58,155,190,76,123,65,37,64,75,232,54,216,215,131,181,229,116,59,221,9,205,102,64,207,125,116,23,102,205,165,153,116,55,222,124,244,53,172,246,98,229,215,177,6,231,85,71,31,110,66, +95,0,35,55,20,78,63,66,193,117,131,116,90,91,197,0,205,104,241,44,243,78,158,68,207,248,107,243,139,188,121,251,105,102,85,48,191,159,102,46,243,22,121,239,57,254,151,202,96,190,167,8,74,206,58,112,252,131,202,126,154,93,11,45,231,180,13,144,86,171,120, +150,249,139,252,65,223,209,251,104,193,100,58,30,244,21,249,23,95,115,132,78,175,45,8,22,244,211,92,239,189,52,46,168,76,90,208,79,103,108,13,42,210,53,111,235,110,63,31,56,254,122,80,233,167,146,33,179,172,161,201,104,183,66,236,139,104,34,181,1,26, +219,224,194,237,52,135,46,166,249,180,3,134,186,132,206,34,29,230,8,209,249,20,166,141,100,208,101,212,65,38,117,210,21,104,251,208,119,45,69,108,19,118,64,193,203,176,250,94,24,169,128,46,160,165,244,13,186,143,252,162,116,214,172,55,208,253,48,18,34, +6,171,30,160,7,33,197,68,218,69,223,164,3,48,107,33,37,233,33,172,240,130,70,132,190,69,15,195,172,171,192,245,219,120,243,225,185,138,14,210,119,224,166,92,3,63,66,143,166,1,243,12,70,4,106,45,229,176,107,126,75,213,83,116,38,195,55,211,7,105,126,91, +97,169,247,89,42,107,243,84,182,30,33,160,187,226,24,70,43,145,74,246,167,135,171,70,14,123,158,162,234,60,74,3,200,147,3,160,43,208,38,32,115,18,160,77,1,62,187,168,158,122,115,128,222,146,213,180,197,6,6,219,111,143,193,34,121,88,185,150,14,209,227, +160,247,4,201,101,19,167,123,158,68,79,174,78,135,169,63,173,211,179,176,128,112,109,172,122,145,234,203,43,7,168,166,214,91,37,168,95,112,23,45,6,32,22,110,45,92,164,216,162,87,180,182,121,209,177,184,181,45,191,170,181,205,23,244,138,42,181,249,143, +211,18,193,211,82,239,17,90,54,20,179,115,109,167,92,13,134,215,208,56,56,98,42,34,49,136,88,60,11,162,159,135,24,108,0,242,111,182,99,192,135,62,149,6,32,126,62,102,158,141,168,188,202,86,179,49,171,102,35,61,101,231,28,121,19,252,231,217,111,79,219, +113,146,171,212,32,28,228,40,245,19,60,37,214,234,6,105,57,176,124,150,4,247,217,251,104,49,30,181,45,85,71,151,121,61,203,242,139,16,13,247,145,86,85,148,191,168,214,23,244,245,211,138,125,164,86,6,125,79,209,202,60,218,186,59,31,72,126,183,114,200, +55,179,109,130,183,65,173,219,225,155,59,168,148,190,130,176,254,42,4,190,131,206,133,88,153,0,47,5,218,239,183,131,116,42,85,192,186,71,177,126,58,112,126,204,70,221,12,248,244,57,188,229,139,112,89,5,235,210,126,244,131,154,120,47,47,235,61,167,231, +73,244,124,215,54,237,247,240,123,158,94,112,210,41,191,3,46,5,232,255,16,136,58,103,31,121,15,13,82,113,91,69,225,170,1,58,119,29,183,12,210,121,109,190,103,169,174,205,83,184,26,174,43,172,135,227,224,191,134,214,1,106,116,242,219,26,228,55,184,238, +252,187,232,12,36,56,101,144,214,194,88,77,133,23,244,211,167,196,209,120,244,83,115,63,173,59,64,107,6,169,165,109,144,214,183,201,252,13,3,116,225,0,109,148,76,209,138,5,155,106,21,49,223,230,182,90,255,139,84,28,84,10,183,56,80,15,250,91,251,105,235, +86,228,21,73,8,23,181,28,160,105,14,219,109,120,29,231,188,94,220,2,216,149,229,50,223,49,146,185,12,22,94,130,151,67,208,189,8,241,252,16,114,136,60,159,64,14,113,192,118,9,21,163,221,15,235,223,11,139,221,135,77,231,126,123,198,98,68,125,45,226,126, +53,214,180,35,194,123,16,231,215,33,190,111,65,76,239,71,196,60,136,40,120,8,246,126,24,180,30,195,251,19,176,244,97,252,13,2,142,199,0,196,119,0,188,223,227,75,124,219,13,112,246,32,26,191,79,47,194,234,215,97,251,121,137,94,6,199,61,52,139,94,1,20, +253,224,150,160,87,233,53,120,185,150,118,210,15,232,135,240,178,100,149,215,233,71,232,59,108,191,253,216,134,246,135,89,207,127,8,168,138,231,167,208,27,244,83,27,218,69,232,121,195,134,118,158,92,102,165,55,206,109,248,18,216,159,86,120,233,17,186, +236,113,210,251,169,189,185,162,48,212,79,225,188,7,40,223,123,208,115,48,27,122,133,54,143,163,192,207,49,154,6,180,77,7,106,68,131,105,14,133,52,111,149,38,208,91,118,88,229,201,133,121,154,207,131,144,82,176,185,188,194,142,135,106,60,140,117,158, +85,179,42,177,9,156,94,110,195,171,114,214,34,224,107,128,188,178,129,96,91,242,28,220,237,145,88,193,212,133,67,66,56,241,255,34,12,244,18,88,189,140,96,120,5,38,123,21,41,236,53,36,252,151,105,17,212,20,161,150,128,93,9,102,189,77,191,132,216,19,16, +30,146,208,61,88,115,38,253,10,14,16,145,151,103,205,181,156,126,109,155,43,79,110,251,211,187,222,69,224,36,65,176,119,144,58,100,191,235,116,144,213,37,233,217,148,244,108,226,229,114,134,33,118,58,112,143,236,163,98,209,164,82,62,162,208,165,159,98, +64,233,27,131,20,7,196,187,219,134,141,13,208,21,3,148,64,1,16,244,74,87,50,232,27,32,75,224,158,58,64,227,29,224,167,130,202,177,3,199,111,23,166,187,164,211,111,191,5,253,199,14,65,163,29,116,57,96,65,248,89,246,51,128,92,120,19,158,55,193,74,55,141, +216,34,223,194,232,219,52,9,122,7,161,249,60,232,88,9,45,207,161,247,144,49,223,7,165,223,131,214,31,40,78,255,0,74,127,64,110,253,35,104,125,132,58,235,31,65,233,35,84,16,127,206,38,161,121,216,106,223,163,223,194,182,59,176,205,254,14,171,37,197,239, +205,218,113,47,125,144,222,56,246,130,170,192,110,18,234,163,15,65,213,3,25,246,128,195,31,33,123,38,183,182,97,252,79,224,224,228,214,91,208,39,16,41,153,236,69,77,209,82,81,133,90,162,109,153,247,110,154,80,89,101,87,18,61,7,142,255,25,96,232,69,20, +167,70,22,113,127,65,251,111,80,246,175,40,101,254,19,229,220,223,32,234,127,101,129,0,162,89,17,75,160,214,1,91,196,18,40,246,190,189,183,205,177,119,108,15,96,82,76,255,100,231,211,172,136,147,252,244,207,160,238,136,216,136,57,30,60,149,242,10,108, +104,254,161,82,196,103,19,156,97,51,212,156,41,244,47,105,134,10,253,107,218,38,10,68,148,205,52,187,183,128,248,95,233,223,211,33,82,131,167,204,202,151,196,228,78,90,117,38,56,164,177,248,63,160,235,232,197,190,83,91,252,55,24,200,89,92,155,78,2,62, +187,252,112,95,237,4,185,47,171,149,207,209,10,116,254,155,254,199,141,142,247,224,24,233,252,47,253,95,218,204,27,96,29,73,53,126,152,25,245,176,231,144,43,37,167,104,241,103,41,249,65,201,217,205,253,176,179,179,155,251,233,239,195,119,115,240,57,206, +228,234,206,60,119,54,31,239,206,187,114,220,9,172,48,115,158,155,49,216,157,246,9,140,65,121,44,60,243,216,139,58,64,242,110,30,221,193,69,168,11,112,172,178,231,209,255,3,80,75,3,4,10,0,0,8,8,0,22,178,149,71,221,192,76,137,196,4,0,0,149,9,0,0,45,0, +0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,66,111,111,116,115,116,114,97,112,77,97,105,110,83,116,97,114,116,101,114,46,99,108,97,115,115,141,86,89,91,219,86,16,61,194,178,5,170,18,192,108,49,4,112,2,20,155,197,78,83,74, +27,160,52,9,133,176,24,146,96,150,58,164,139,176,47,70,68,150,168,44,19,232,150,46,105,251,27,250,218,151,190,54,47,134,175,124,77,223,251,47,250,212,127,209,118,174,100,131,55,242,213,15,119,153,153,59,115,206,204,189,99,253,249,207,111,47,1,188,129, +31,101,248,113,87,70,47,102,36,188,47,97,86,70,43,230,100,220,195,188,140,5,44,242,97,73,134,7,49,25,203,88,225,195,253,122,60,224,146,135,245,88,149,16,151,48,36,163,17,107,18,214,101,108,96,83,194,7,245,72,112,55,143,248,176,197,135,199,245,248,80, +198,71,248,88,194,39,245,80,249,114,91,70,23,146,18,82,2,124,83,154,161,217,211,2,60,161,240,134,0,113,198,76,49,1,141,49,205,96,43,185,204,54,179,214,212,109,157,36,254,152,153,84,245,13,213,210,248,190,32,20,237,93,45,43,32,28,51,173,116,52,109,169, +41,157,69,159,90,234,254,62,179,162,119,77,211,206,218,180,89,86,53,35,110,171,150,205,172,73,1,222,44,95,10,232,15,109,197,246,212,3,53,170,171,70,58,26,183,45,205,72,79,186,18,205,140,206,105,58,155,116,240,168,86,154,34,180,212,48,22,32,187,33,231, +205,12,97,185,92,126,88,64,131,171,93,84,45,66,159,52,13,155,29,218,51,186,154,205,198,76,53,197,72,24,112,79,24,204,142,174,175,198,74,84,252,112,134,80,59,34,1,205,37,177,29,17,15,205,245,203,204,222,53,41,135,157,37,6,22,219,209,89,210,142,186,58, +178,108,47,79,220,209,126,49,121,173,149,110,167,134,166,185,231,217,195,36,219,183,53,211,200,74,224,165,216,209,140,84,76,205,25,201,93,102,57,100,122,66,21,121,170,100,46,238,104,78,117,84,203,234,39,7,91,85,122,157,25,164,16,22,4,212,105,180,144, +227,102,206,74,178,57,231,84,160,86,225,34,220,131,130,32,174,41,120,7,183,4,116,92,144,58,1,74,169,70,193,14,210,18,118,21,104,216,147,240,68,129,142,140,2,131,15,65,152,18,246,21,124,10,75,65,22,116,39,122,232,26,69,220,170,69,244,2,227,200,61,103, +207,177,40,200,225,128,208,243,212,19,173,138,236,41,120,138,67,1,77,231,226,251,219,123,84,9,9,71,10,62,195,231,69,100,133,52,208,133,215,181,109,142,226,11,5,95,226,43,5,207,240,53,241,114,195,143,22,195,143,70,134,30,19,121,75,194,55,10,190,197,119, +84,236,243,0,171,57,195,214,50,236,172,96,2,102,103,204,156,158,10,26,166,29,212,169,236,54,11,218,187,44,232,82,8,22,125,6,23,239,172,6,53,163,40,78,105,148,109,109,59,199,61,4,7,7,178,131,17,5,207,241,61,135,246,131,128,193,255,249,180,232,141,156, +3,43,65,228,181,205,245,85,42,116,83,40,92,122,221,23,38,203,43,181,80,176,140,85,89,198,200,178,173,34,215,197,90,183,166,153,29,63,202,218,44,83,254,176,138,30,42,79,56,175,146,217,15,84,139,25,84,239,112,177,7,20,35,93,112,138,55,130,146,186,174,237, +90,76,165,103,119,41,153,179,184,163,226,190,181,44,172,43,229,224,179,204,158,169,241,252,59,67,175,8,215,160,211,186,240,254,7,66,213,205,167,138,96,129,90,177,37,220,174,113,102,171,234,76,248,85,141,227,202,69,58,106,218,154,113,96,62,161,59,124, +171,52,140,123,223,203,194,20,68,225,106,145,128,190,138,54,82,131,164,147,8,186,158,92,207,27,97,40,92,213,75,36,34,189,162,242,6,92,158,254,179,38,221,84,41,163,51,25,213,166,135,64,30,219,106,165,246,17,17,220,49,45,50,170,32,88,35,143,53,8,158,69, +174,233,124,3,215,232,255,214,15,254,243,64,224,45,141,198,235,180,139,210,44,208,236,29,58,134,240,130,22,117,232,163,209,231,8,59,208,79,163,226,26,96,0,175,211,76,143,19,33,178,226,135,255,38,59,137,230,205,161,145,99,212,173,156,194,147,16,127,135, +152,240,140,230,225,205,195,23,63,129,148,71,253,49,26,38,196,19,200,1,49,143,215,2,162,95,201,227,210,132,55,224,245,95,38,235,198,132,167,5,77,241,60,154,39,124,1,159,64,18,127,194,51,76,251,150,205,23,14,90,14,167,199,9,19,160,112,157,180,239,194, +48,174,98,12,221,244,205,208,67,31,0,189,14,204,121,23,74,1,38,95,133,49,228,64,223,36,251,17,130,236,195,67,140,210,138,251,28,67,132,184,139,52,247,225,6,125,149,120,201,87,19,110,226,77,178,26,43,144,118,117,111,145,110,156,36,34,73,222,38,47,244, +79,80,200,221,49,69,244,209,188,116,138,214,196,176,191,237,24,237,121,116,44,143,188,156,246,140,139,109,98,247,207,232,29,105,19,111,114,170,121,92,241,7,242,232,252,9,190,128,247,215,231,162,240,203,191,127,157,162,43,225,191,90,36,124,130,238,99, +244,252,113,86,129,118,10,11,10,19,164,221,40,17,188,65,235,113,202,61,167,58,77,97,131,4,119,130,200,120,113,153,234,49,137,41,58,215,76,228,223,37,173,135,62,128,174,227,61,90,137,28,222,89,74,150,156,68,240,130,223,118,226,220,249,15,80,75,3,4,10, +0,0,8,8,0,22,178,149,71,72,214,183,36,211,10,0,0,35,24,0,0,40,0,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,87,114,97,112,112,101,114,69,120,101,99,117,116,111,114,46,99,108,97,115,115,149,87,121,96,28,85,25,255,77,178, +201,110,54,211,132,110,146,182,41,41,44,37,109,210,205,69,203,221,150,35,73,83,26,200,213,108,210,154,162,214,201,238,52,89,216,236,132,217,217,30,8,10,40,40,42,162,28,34,20,68,69,173,183,65,233,6,136,128,162,22,197,27,239,251,62,241,194,3,111,240,247, +205,76,54,179,219,109,13,127,236,155,247,189,247,189,239,248,125,199,123,251,228,115,15,63,10,96,189,18,242,227,45,126,220,17,192,91,131,40,193,157,126,220,21,68,25,14,6,161,224,110,89,185,199,143,183,5,112,175,31,111,15,226,29,120,103,16,21,184,47,136, +74,28,244,227,93,65,84,227,96,5,57,223,45,195,123,100,56,36,195,123,229,244,251,100,120,191,176,124,32,128,15,202,247,67,178,242,97,153,125,36,128,25,249,222,47,195,71,3,248,152,124,31,144,237,195,50,203,6,48,43,223,7,101,120,40,128,135,229,59,39,195, +199,253,120,36,128,71,197,138,199,132,253,19,65,156,142,79,138,157,143,203,236,83,50,251,116,0,159,17,31,142,248,241,132,240,28,145,157,251,100,246,89,63,62,23,196,217,56,24,192,147,242,253,124,0,95,8,224,139,1,124,41,128,47,7,240,149,0,190,42,203,79, +249,241,181,32,186,132,237,235,242,253,134,12,79,85,226,155,248,150,72,249,182,31,223,9,162,23,223,21,37,223,11,226,251,248,129,152,246,195,32,126,132,31,7,241,19,252,52,128,159,41,168,223,210,27,29,25,238,237,26,29,233,29,28,216,61,58,220,183,123,104, +120,112,168,103,120,100,76,65,168,239,50,109,175,214,145,212,82,19,29,81,203,76,164,38,54,41,88,210,109,164,210,150,150,178,118,104,201,140,174,96,101,158,128,174,206,104,143,71,66,254,230,80,231,200,54,207,230,138,188,205,232,182,206,221,27,206,60,107, +119,116,180,95,193,242,93,189,67,187,163,35,131,195,61,133,18,61,59,5,226,130,211,166,49,173,155,86,66,79,43,88,230,152,158,177,18,201,142,161,220,58,205,175,90,224,218,154,72,210,254,42,135,51,97,116,8,45,14,238,211,204,20,125,29,204,88,211,25,43,39, +202,70,161,115,122,90,79,197,181,113,155,177,60,102,164,246,36,38,20,172,235,51,204,137,142,9,83,139,39,245,142,125,166,70,38,179,99,167,243,237,182,121,50,166,102,37,140,20,15,213,236,49,76,26,116,153,30,179,182,36,76,142,134,121,64,193,197,205,249, +86,20,87,121,60,61,61,251,245,88,134,194,168,194,215,109,196,233,88,117,95,34,165,15,100,166,198,117,115,68,142,75,60,141,152,150,220,161,153,9,161,221,69,129,205,181,134,33,161,117,174,192,161,2,156,202,55,39,82,9,235,124,5,231,21,181,181,16,233,99, +120,176,67,129,66,97,117,158,237,158,253,49,125,218,69,199,103,77,38,24,189,198,197,57,186,108,218,212,167,53,83,223,146,72,51,59,199,51,34,100,212,76,40,56,161,121,157,163,32,165,91,29,163,195,189,18,172,180,145,49,99,11,241,94,216,9,230,12,72,251,241, +115,198,223,212,181,184,45,210,24,53,147,204,225,60,122,139,78,165,49,205,210,227,59,53,6,174,130,128,77,105,150,165,155,57,167,108,36,182,206,47,83,65,69,124,65,88,85,210,208,226,67,158,68,109,90,20,154,130,91,32,145,98,17,234,218,84,78,19,207,244,166, +152,163,206,242,38,63,126,193,168,79,232,150,23,15,130,193,149,188,44,84,208,210,252,66,82,214,175,219,144,19,187,75,155,47,61,186,37,20,147,212,43,45,34,153,44,186,215,101,24,22,237,211,166,251,53,241,72,51,5,37,113,208,167,153,19,68,164,166,136,14, +26,145,112,68,42,104,56,158,66,5,181,227,69,228,31,163,70,139,154,194,140,112,216,182,25,83,244,185,146,240,185,145,96,188,215,54,31,109,220,186,98,246,170,110,159,57,48,160,137,148,115,138,156,91,172,164,184,190,71,203,36,231,251,237,185,139,146,180, +171,168,168,128,169,95,145,97,215,137,179,10,119,41,40,219,235,136,172,99,25,25,166,213,159,72,167,201,183,224,108,48,106,215,140,83,255,181,5,245,215,46,242,21,172,254,255,149,74,23,188,41,174,160,185,128,223,33,219,92,178,125,161,67,171,152,196,47, +169,186,88,77,200,222,175,100,72,168,248,53,126,195,58,93,112,120,56,147,178,18,83,122,174,176,21,180,186,54,133,23,132,135,247,208,152,112,211,154,116,83,56,110,144,76,25,86,88,223,207,210,105,103,205,44,200,26,28,151,238,232,199,111,85,60,141,223,137, +194,223,179,106,23,89,61,42,118,227,101,42,198,176,75,197,165,120,177,138,151,224,165,42,14,224,74,21,41,24,42,254,128,63,82,89,220,83,175,93,90,90,87,241,39,60,163,226,117,184,73,197,159,69,93,30,199,144,102,77,170,248,139,112,252,85,54,235,188,155, +209,73,141,151,104,52,51,165,226,111,142,140,155,85,60,43,108,234,149,137,233,40,163,161,59,26,254,46,187,255,200,219,112,4,255,83,54,254,37,27,53,69,122,52,145,236,54,50,201,184,141,150,244,178,240,190,34,192,154,198,148,13,108,187,192,245,111,21,150, +248,250,31,17,252,95,60,167,226,121,206,20,192,96,183,138,231,181,238,164,24,252,250,249,124,113,91,180,138,140,176,46,47,204,231,174,76,34,25,151,210,246,103,204,228,48,43,89,85,20,165,132,153,221,81,0,152,83,129,74,27,61,242,46,239,208,205,180,237, +209,50,239,106,119,82,99,21,236,73,136,96,95,59,161,81,149,82,60,51,15,70,126,111,87,240,248,113,211,138,239,3,139,141,37,29,142,231,46,141,176,158,162,42,114,53,185,70,55,181,134,155,10,141,45,92,115,45,109,10,107,169,120,254,206,130,181,77,237,225, +145,73,61,173,135,247,37,146,201,240,184,30,54,245,41,99,47,21,166,13,35,213,30,30,74,234,12,123,56,147,118,77,147,110,202,107,173,125,13,83,244,105,197,231,87,202,4,189,114,21,183,10,254,203,189,245,234,185,98,24,78,197,175,42,1,165,194,175,4,85,165, +82,10,240,21,48,252,138,170,42,75,148,42,191,82,173,42,39,40,75,21,116,14,24,97,187,185,208,28,107,50,124,185,126,192,81,155,158,214,99,98,110,156,6,20,205,156,121,236,88,131,39,122,147,32,122,128,80,238,247,164,97,77,238,6,28,244,172,158,122,236,119, +212,124,139,229,69,83,218,44,99,185,93,236,105,155,220,149,87,242,14,43,57,156,203,189,120,207,245,222,82,78,143,40,222,190,235,138,221,24,84,95,157,46,188,168,151,54,231,63,77,132,171,166,224,58,151,226,101,67,108,46,170,170,38,93,140,185,80,132,148, +249,209,188,206,234,138,2,222,92,59,225,86,250,152,91,65,158,218,149,152,118,212,5,211,94,194,217,113,132,187,59,14,17,57,254,53,54,50,105,26,251,114,79,198,10,138,137,198,38,117,169,227,37,114,31,243,209,151,178,156,203,36,247,214,91,120,193,215,229, +216,163,78,190,197,120,128,97,44,179,12,226,202,184,106,246,139,84,65,219,162,110,115,183,209,200,253,105,25,243,185,177,249,5,165,196,81,111,194,218,98,207,99,5,167,121,165,118,79,106,102,148,23,182,158,138,233,121,102,229,253,11,89,90,144,242,246,75, +74,58,51,67,214,92,244,157,104,231,85,145,13,2,20,75,26,18,182,149,199,126,97,49,140,49,50,91,246,163,219,174,140,197,62,36,143,10,83,177,75,180,216,139,140,118,165,45,59,128,141,69,223,159,5,238,227,20,254,251,173,4,16,68,61,182,99,152,84,148,84,9,214, +147,30,241,208,43,72,143,122,232,6,210,59,60,244,201,164,119,122,232,83,73,191,200,67,175,69,72,110,118,206,67,114,185,219,95,222,239,246,151,215,62,191,85,168,128,134,113,158,136,145,26,64,57,79,1,43,231,160,140,205,161,100,44,18,42,157,133,111,14,101, +99,179,40,111,153,133,127,198,150,27,231,88,206,51,64,51,116,142,203,156,83,216,99,235,144,153,104,97,85,96,34,39,59,1,191,205,213,22,201,34,112,23,86,204,161,98,44,20,244,61,130,202,177,210,72,244,65,168,179,88,242,152,232,141,20,85,87,133,82,142,173, +20,210,70,24,58,60,106,219,92,215,100,230,168,133,188,185,28,181,202,118,158,40,227,202,108,100,22,85,20,93,77,209,39,28,198,210,72,235,97,132,34,45,135,81,19,105,59,140,218,22,26,117,39,110,107,105,125,16,117,145,7,184,61,139,101,89,44,183,167,161,21, +242,201,162,126,22,43,179,56,209,89,107,112,214,86,217,107,39,57,107,39,59,107,97,98,118,74,22,171,157,197,83,157,197,70,155,113,141,179,182,214,89,107,178,215,154,15,161,97,163,207,134,35,226,192,209,34,112,212,251,102,209,242,216,253,116,99,13,238, +194,61,88,231,2,177,21,75,57,110,128,143,235,213,56,29,181,56,131,81,63,19,39,225,44,174,156,131,8,206,37,181,17,189,216,68,56,54,195,196,121,184,1,231,83,70,39,165,92,128,123,113,33,178,232,182,1,60,131,208,220,139,229,184,12,151,83,30,65,66,18,83,54, +148,179,54,168,138,61,147,12,42,177,103,2,111,41,231,124,25,114,148,168,198,121,78,246,26,9,88,107,31,81,108,123,2,245,118,230,60,128,154,44,218,185,210,193,12,202,226,180,153,150,133,96,134,108,109,91,169,253,34,168,180,116,53,46,241,4,180,209,181,162, +140,249,61,141,43,104,133,73,202,199,111,154,251,86,78,247,118,123,13,16,216,67,161,245,89,108,56,130,165,115,56,157,89,187,126,22,103,204,226,204,25,90,117,86,97,14,13,81,229,118,166,232,136,173,82,117,68,184,42,189,138,50,57,69,207,50,217,229,228,13, +74,223,28,206,102,2,157,19,9,157,75,13,89,108,12,109,226,16,9,109,118,169,243,108,234,252,60,234,2,151,186,144,67,22,157,20,209,69,17,221,253,173,161,45,101,78,246,19,170,232,152,47,180,62,154,69,207,78,82,181,173,89,108,125,8,23,149,96,231,33,84,246, +219,238,108,219,41,158,181,136,83,180,175,132,150,102,114,41,177,150,133,6,22,126,9,3,213,195,16,245,179,184,227,44,111,147,99,134,229,189,151,94,92,77,111,197,223,8,253,235,103,162,236,197,62,242,239,101,117,72,240,5,246,27,92,12,74,240,106,236,183, +155,200,2,26,65,249,71,224,162,241,74,98,33,225,91,53,135,222,49,2,124,113,127,11,237,189,132,191,190,67,8,14,200,183,141,121,91,66,163,170,80,71,198,58,198,181,46,23,132,149,4,83,186,65,5,213,86,81,97,136,217,84,199,111,3,225,22,3,195,54,212,171,114, +69,189,202,206,63,233,37,181,120,57,174,178,93,119,204,186,154,63,190,237,220,254,178,129,95,9,101,192,169,173,254,194,78,149,241,132,59,224,186,170,208,153,107,220,243,29,238,249,50,57,95,120,248,42,207,225,178,220,225,107,113,157,139,73,146,70,75,151, +9,181,58,218,7,54,250,218,90,234,153,246,131,247,23,100,223,53,196,242,90,150,240,117,185,2,148,114,152,47,187,16,94,69,244,21,123,118,61,35,82,98,207,94,131,215,242,108,144,102,223,72,80,124,57,0,36,254,252,55,226,58,176,217,45,197,64,164,69,97,239, +56,165,208,135,235,61,37,22,200,105,12,224,13,118,172,69,210,77,174,164,173,148,84,234,72,106,45,38,233,70,79,160,142,150,36,179,55,114,86,98,203,188,217,149,121,11,169,50,187,81,176,88,217,21,54,108,244,213,251,142,160,188,222,55,211,122,4,101,173,51, +171,238,68,69,132,249,189,109,70,89,208,183,154,178,64,187,130,148,88,77,89,33,188,153,30,220,194,139,241,54,38,204,237,220,191,195,131,99,99,206,150,198,156,45,141,174,45,50,123,19,79,11,142,43,41,97,216,70,235,214,28,122,67,238,245,212,96,55,226,161, +50,183,17,143,249,236,234,116,175,167,2,28,238,246,32,218,144,211,221,224,234,86,104,163,240,223,254,63,80,75,3,4,10,0,0,8,8,0,22,178,149,71,132,26,164,171,178,10,0,0,66,24,0,0,42,0,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101, +114,47,71,114,97,100,108,101,87,114,97,112,112,101,114,77,97,105,110,46,99,108,97,115,115,157,88,7,120,20,199,21,254,7,78,218,211,106,85,56,9,164,195,148,3,11,212,144,206,128,141,177,192,16,89,18,32,144,16,160,102,129,109,188,156,22,233,240,233,86,220, +237,81,226,150,98,167,216,137,211,72,177,147,56,61,78,226,20,156,56,39,217,138,77,236,20,39,78,119,122,239,205,233,189,59,249,103,119,117,58,221,45,66,95,190,15,205,237,188,121,253,189,121,239,13,79,62,243,240,163,0,214,139,141,42,182,225,46,21,27,240, +50,185,188,92,46,175,80,240,74,21,5,18,92,128,87,41,56,227,199,171,253,120,141,220,189,86,197,235,112,183,31,247,248,241,122,5,111,80,81,38,177,202,240,70,121,120,175,138,55,225,205,10,222,162,162,210,1,191,85,197,14,188,77,242,124,187,92,222,33,151, +119,170,184,15,239,82,240,110,5,239,241,227,126,9,122,175,138,229,120,159,130,247,171,88,133,15,168,88,134,179,10,30,80,81,35,185,220,135,15,42,248,144,31,15,170,168,197,135,85,164,49,33,191,38,229,242,144,92,30,246,99,202,143,143,168,240,227,17,185, +127,84,193,57,21,31,197,99,42,30,199,199,84,124,28,159,80,241,73,60,161,224,83,10,62,173,98,51,158,84,241,25,124,214,143,207,73,154,207,251,241,5,5,95,148,159,95,146,135,79,201,195,47,75,70,79,249,241,21,201,232,171,126,124,77,193,215,165,45,119,201, +229,27,126,220,46,127,191,233,199,183,84,124,27,223,81,240,93,63,190,39,137,191,175,226,7,248,161,92,126,164,226,199,248,137,138,159,226,103,10,126,174,162,15,191,16,168,218,121,160,181,189,171,227,112,127,111,199,129,195,187,122,186,59,14,247,236,235, +235,236,217,43,16,232,58,166,159,208,195,49,61,62,18,238,181,18,209,248,200,22,129,146,54,51,158,180,244,184,53,160,199,82,134,64,40,143,188,189,163,175,181,179,171,163,61,195,167,194,69,217,223,223,217,209,151,129,46,155,5,205,35,42,220,26,141,71,173, +109,2,11,235,234,7,4,124,109,230,48,165,149,117,69,227,198,222,212,216,17,35,209,167,31,137,25,82,73,51,162,199,6,244,68,84,238,93,160,207,26,141,38,5,214,118,153,137,145,240,72,66,31,142,25,225,147,9,125,124,220,72,132,119,218,219,65,103,215,173,71, +227,52,202,55,198,95,129,37,117,135,242,77,182,165,235,137,17,242,171,240,56,22,80,93,206,187,245,132,64,169,131,17,53,195,59,162,49,131,167,165,227,9,147,135,86,212,72,74,136,128,146,48,77,171,61,74,220,194,113,61,145,52,248,177,58,91,207,72,44,26,110, +51,199,198,244,248,176,52,118,159,141,67,70,69,17,51,126,130,140,36,193,101,185,4,189,167,147,150,49,182,47,35,42,139,65,219,52,25,121,40,230,184,21,101,252,60,68,218,114,134,179,232,136,94,158,204,97,75,23,57,246,165,172,104,44,60,3,151,118,58,188,250, +169,236,46,115,140,118,22,198,204,145,17,169,236,69,94,81,232,178,15,73,87,230,66,58,78,25,145,148,101,18,191,198,11,127,112,54,150,116,123,199,169,136,49,109,78,133,62,60,156,235,3,129,149,117,179,163,49,123,39,3,171,58,98,28,141,87,228,160,215,231, +198,114,145,171,77,182,140,242,186,60,52,65,94,203,29,96,220,176,194,253,7,58,123,79,199,45,253,84,70,97,226,248,99,76,91,249,157,73,25,23,85,186,210,21,51,96,36,146,54,70,229,180,140,156,171,120,194,65,112,238,3,85,73,24,73,51,149,136,24,173,73,226, +24,250,152,192,226,140,110,157,241,241,148,229,128,73,170,29,73,69,99,195,7,140,136,17,29,183,50,104,54,251,108,45,55,212,93,56,77,242,204,223,62,47,162,185,114,66,237,181,205,112,238,203,146,188,11,219,44,5,106,184,6,215,106,24,193,45,26,110,198,77, +26,142,225,38,86,163,11,93,36,13,191,196,211,116,85,174,59,25,53,254,149,59,164,77,41,98,54,141,50,41,52,252,10,191,86,240,27,13,191,197,239,136,115,92,160,224,120,42,106,208,103,27,255,143,43,168,225,247,248,131,134,63,226,79,10,254,172,225,47,248,43, +147,106,230,66,237,210,147,163,221,250,184,134,191,225,239,26,254,129,127,106,72,226,14,13,167,241,108,13,22,238,84,240,47,13,255,198,127,4,150,122,184,175,83,214,229,88,140,23,206,227,176,221,60,25,143,153,250,48,107,128,115,114,82,195,243,113,155,244, +226,51,179,221,54,77,177,79,183,70,91,147,73,99,140,21,53,33,241,254,203,133,46,64,173,7,242,85,172,105,73,139,27,25,159,94,75,183,141,21,66,44,96,170,101,167,7,205,117,40,155,103,202,162,100,187,80,17,62,77,20,136,66,77,40,140,168,240,83,53,81,132,219, +88,70,174,97,184,19,53,2,197,217,36,66,21,197,146,78,99,185,152,79,141,87,68,137,38,74,69,153,34,202,53,177,72,4,20,81,161,137,74,177,88,17,75,52,81,37,170,233,180,57,238,43,253,61,147,47,7,82,113,43,58,102,100,14,165,26,65,69,44,213,196,69,82,95,223, +81,154,169,137,101,98,185,192,182,54,61,30,55,173,208,176,65,119,140,49,17,66,145,152,158,76,142,211,179,161,163,102,34,228,170,27,98,231,8,29,77,152,99,161,8,155,220,17,61,105,132,106,215,36,107,155,103,165,105,207,145,99,70,196,210,196,10,177,82,74, +12,105,98,149,20,23,12,219,55,185,41,225,92,229,89,62,90,45,46,102,104,247,154,33,27,37,228,162,132,166,171,4,85,72,197,135,41,165,210,171,164,107,162,70,172,209,196,90,81,43,176,137,60,220,90,19,138,219,197,38,148,28,55,34,209,163,81,99,56,20,141,159, +135,127,179,34,234,52,81,143,107,89,158,61,202,11,35,215,102,166,72,55,219,67,211,62,113,229,53,75,99,27,20,209,168,137,117,162,137,215,81,144,109,88,19,151,224,54,69,172,151,247,227,22,58,225,188,197,68,82,111,144,237,33,22,51,79,246,199,111,136,243, +26,244,76,55,141,154,186,250,249,52,222,66,211,213,247,114,207,241,96,14,22,61,211,117,116,142,178,212,227,50,47,30,213,147,173,137,145,212,152,17,183,46,164,90,134,175,156,9,142,70,71,82,9,94,172,53,121,101,55,223,24,217,242,10,236,169,99,190,214,120, +142,5,89,100,118,209,99,43,26,49,172,236,174,88,61,221,177,242,7,5,197,157,99,4,174,154,71,163,200,226,194,202,184,165,62,103,47,135,168,148,213,42,171,94,160,46,23,151,198,174,190,240,40,65,101,121,23,7,115,59,187,83,173,118,123,78,16,182,233,173,196, +143,15,203,121,211,187,155,229,79,44,179,237,205,233,122,249,177,240,30,69,23,229,14,41,132,93,55,39,99,175,86,49,221,14,60,79,103,85,126,91,128,98,216,86,208,33,135,188,178,198,83,132,211,141,60,207,188,186,133,45,231,226,243,187,59,203,5,13,30,44,115, +187,239,46,38,80,76,14,69,21,204,204,11,79,134,249,121,101,103,180,158,224,109,116,50,161,40,179,151,45,212,176,246,234,114,100,212,18,198,120,76,151,163,74,34,201,131,205,117,243,10,163,215,48,87,59,63,82,154,95,54,3,109,147,237,196,177,145,214,89,108, +16,172,11,237,166,243,154,89,61,125,7,147,140,93,34,106,157,14,231,226,80,236,138,185,49,28,63,200,183,151,51,146,241,217,150,199,117,230,148,252,170,207,119,198,10,71,78,93,153,169,55,51,55,59,45,183,107,203,244,164,224,238,89,168,44,147,173,56,15,83, +78,200,213,217,206,234,27,77,152,39,157,123,56,48,155,73,167,19,182,222,200,168,97,191,72,140,227,41,61,70,127,45,206,38,119,26,235,150,250,131,68,96,33,24,211,25,199,43,60,130,113,200,131,198,43,144,139,61,104,237,59,100,39,144,53,234,132,235,64,222, +168,94,239,69,119,158,241,221,231,140,114,213,117,158,231,82,90,241,76,65,62,205,135,240,249,121,207,86,190,194,131,31,35,17,137,153,178,101,52,204,157,163,179,3,145,219,243,242,106,59,131,195,158,55,221,255,60,221,198,152,108,245,84,253,66,188,51,29, +114,237,252,48,249,32,163,195,220,255,210,240,26,112,119,206,122,221,118,153,230,13,169,113,198,161,238,96,253,0,86,97,3,182,1,240,33,136,1,12,114,68,190,154,187,5,40,226,126,40,107,175,114,127,48,107,95,194,253,161,172,125,41,41,132,124,214,112,189, +142,144,48,228,184,13,20,52,76,64,60,96,163,28,230,90,104,3,87,224,122,174,154,131,0,29,71,248,91,132,8,134,137,69,98,113,134,226,138,9,123,124,18,11,186,26,39,177,176,155,139,111,239,20,10,134,38,80,216,226,11,250,210,80,6,131,190,130,71,224,31,90,24, +40,234,29,242,5,212,222,52,138,211,208,102,192,37,18,92,42,193,131,83,40,35,101,121,75,65,176,64,210,46,10,250,26,210,8,180,20,78,162,162,69,9,42,132,22,78,161,146,40,139,211,88,146,70,85,144,39,213,45,254,160,191,105,18,65,185,89,218,82,180,46,88,52, +137,139,90,212,160,218,48,133,101,67,193,162,41,44,231,26,88,49,137,149,19,8,77,97,213,80,208,63,129,213,19,184,120,10,53,228,181,38,141,181,51,150,239,70,128,235,26,58,122,45,109,173,165,195,234,81,133,6,44,71,35,46,197,58,236,66,51,246,211,109,87,99, +61,189,179,17,6,161,167,176,9,183,98,51,110,71,11,94,130,173,56,131,43,241,24,90,109,239,141,59,30,34,222,81,59,124,143,242,57,57,74,143,22,225,33,68,249,37,67,242,32,31,150,163,88,72,57,247,227,6,196,136,181,31,199,49,134,56,189,126,61,189,110,146,75, +33,57,92,75,104,2,10,101,181,113,40,29,133,159,210,54,241,209,150,34,183,51,212,235,4,78,50,34,167,108,57,2,221,252,230,171,206,13,116,132,188,22,240,183,150,190,156,66,237,80,67,160,110,2,245,147,160,131,171,92,80,99,22,104,198,33,165,84,12,104,71,5, +58,232,146,29,182,81,75,28,86,184,145,74,192,254,58,102,27,165,202,23,178,43,240,50,55,179,138,201,174,209,249,119,54,39,191,58,179,242,171,216,246,11,200,226,230,12,139,86,23,175,202,86,56,141,117,252,107,10,52,7,194,105,92,50,129,245,185,236,186,179, +216,85,101,216,241,245,238,178,187,151,174,147,122,239,174,192,134,52,54,166,113,105,26,151,165,177,105,207,125,40,233,154,194,230,161,198,9,92,113,142,50,90,2,91,210,216,122,15,170,37,48,112,165,239,17,108,27,90,216,208,59,137,237,19,120,214,57,87,153, +214,9,92,117,214,150,85,78,223,92,238,106,178,130,50,128,94,194,6,8,237,67,37,250,153,58,131,76,162,171,121,127,15,102,188,87,201,144,221,138,231,144,190,156,73,243,92,60,143,112,191,124,45,187,186,62,205,16,22,240,119,128,186,6,218,210,104,223,211,240, +4,74,108,125,58,28,37,118,48,117,119,118,53,82,147,93,141,129,206,52,118,119,175,155,198,216,35,49,214,237,229,81,87,211,217,22,121,135,186,130,190,115,123,236,179,189,188,232,61,231,200,125,37,182,208,193,210,201,109,246,47,176,157,201,223,205,239,221, +246,175,99,207,6,250,19,252,42,162,230,37,44,1,85,76,164,149,76,197,26,166,115,35,125,27,166,151,175,96,212,183,48,109,119,51,97,247,48,89,165,141,13,148,208,72,75,111,167,237,178,74,181,226,5,120,33,225,43,9,125,17,147,88,16,179,152,30,120,177,29,163, +36,238,112,237,222,103,167,46,253,216,16,40,74,99,223,221,168,116,146,149,155,253,105,28,144,62,159,68,239,76,228,157,236,180,40,33,133,165,76,255,153,12,88,97,95,27,201,221,194,157,46,247,205,46,247,210,41,244,145,105,9,37,76,160,63,55,143,110,204,226, +82,234,114,17,188,106,18,235,165,255,3,80,75,3,4,10,0,0,8,8,0,22,178,149,71,217,206,17,120,160,6,0,0,180,14,0,0,34,0,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,73,110,115,116,97,108,108,36,49,46,99,108,97,115,115,157,87, +107,119,27,213,21,221,215,26,89,138,60,73,28,1,1,81,135,4,48,32,43,216,74,12,9,36,78,66,19,59,128,65,49,33,78,226,198,77,91,198,210,32,143,51,158,81,71,35,39,161,15,160,188,194,35,208,2,165,152,119,31,16,104,75,27,90,172,56,164,13,143,118,173,174,213, +126,236,71,126,5,127,160,101,31,141,100,203,178,226,38,245,90,62,247,222,51,231,158,179,239,57,251,62,244,207,255,124,114,30,192,70,252,125,25,186,113,88,196,119,68,124,87,196,247,68,60,32,194,136,161,7,99,17,100,99,136,34,23,129,25,67,12,99,50,120,80, +122,249,40,198,165,181,68,51,33,226,136,8,91,196,100,12,163,112,162,112,101,80,144,193,247,163,240,196,186,24,131,143,146,104,166,218,112,20,199,196,224,184,12,31,106,195,15,240,195,54,252,8,63,22,241,112,20,143,136,250,209,24,126,130,199,98,120,92,226, +140,226,137,40,158,140,226,41,233,158,16,241,180,204,127,38,70,180,207,70,240,92,4,39,35,120,94,161,125,202,176,59,109,55,107,216,163,86,225,78,203,54,21,86,100,38,140,41,35,109,185,105,25,247,41,180,137,77,206,42,250,3,150,167,112,89,109,228,89,99,37, +223,114,157,3,158,61,55,201,49,253,244,129,125,131,156,180,74,204,178,174,243,160,149,47,121,134,216,41,116,101,92,47,159,206,123,70,206,54,211,71,61,163,80,48,189,244,72,208,246,215,155,114,126,162,49,204,240,184,209,187,105,243,112,105,82,33,30,4,179, +13,39,159,30,166,129,147,231,132,86,127,220,42,118,110,80,232,104,22,101,208,41,250,134,109,139,221,54,203,177,252,29,10,143,39,151,50,92,152,132,102,163,218,90,47,122,81,139,81,119,29,84,208,250,221,28,179,190,50,99,57,230,80,105,114,204,244,246,27, +99,82,135,120,70,202,114,208,240,44,25,87,149,154,172,82,1,10,250,160,227,48,130,109,20,139,38,53,215,44,177,152,206,141,92,183,70,103,44,84,123,178,171,177,190,49,127,178,48,87,253,80,78,138,220,98,117,42,92,30,24,50,251,118,122,208,55,185,10,215,19, +243,73,195,59,98,122,129,249,114,199,52,115,197,1,247,168,99,187,70,78,65,141,18,153,239,22,50,230,148,105,147,47,68,214,94,231,38,195,130,10,22,207,117,125,133,213,11,87,120,188,80,91,229,186,134,41,219,22,66,222,33,40,118,31,203,154,5,201,107,49,130, +23,8,182,182,174,74,126,239,27,155,48,179,18,105,217,176,149,119,12,191,228,209,235,206,197,6,117,113,200,213,108,201,243,76,199,79,247,51,83,2,164,89,216,97,183,228,101,205,96,241,122,53,191,61,98,198,18,238,118,178,182,91,100,97,247,152,254,184,203, +115,224,167,58,126,134,23,117,108,193,86,29,27,176,81,71,175,136,91,112,171,142,77,216,172,227,54,220,174,163,15,47,209,87,125,40,29,47,99,183,194,149,141,132,217,85,178,236,156,233,233,248,57,94,209,241,11,188,202,122,245,184,71,116,76,203,184,15,175, +233,120,29,111,232,120,83,196,91,162,123,27,239,40,132,123,10,134,231,235,248,165,168,127,133,95,51,90,173,98,116,186,78,60,253,38,130,119,117,188,135,83,58,222,199,7,17,252,86,199,239,240,123,29,31,226,15,58,254,136,211,17,124,164,227,79,248,115,4,31, +235,152,17,63,101,236,231,97,48,96,218,166,47,78,72,27,38,212,245,142,211,221,25,204,70,112,86,199,39,56,23,193,95,116,252,21,231,153,185,3,206,67,86,161,32,182,36,192,58,223,165,225,167,248,76,199,231,248,66,199,223,196,229,128,44,186,99,41,30,147,77, +141,53,84,88,179,100,17,9,114,126,202,28,105,20,174,190,112,28,130,205,122,166,225,155,3,228,158,194,150,166,7,69,211,45,190,104,111,133,146,178,199,151,231,77,127,175,33,176,2,226,68,56,30,50,38,205,70,218,206,31,102,226,219,225,126,234,78,54,57,53, +22,169,170,188,224,196,168,239,6,42,133,235,147,205,78,173,198,227,167,205,42,14,212,74,87,129,203,13,220,106,21,3,156,43,137,115,231,88,209,181,75,190,185,215,240,199,153,24,35,155,53,139,60,103,55,240,164,205,92,242,9,218,100,25,243,185,106,205,9,153, +204,249,32,27,37,72,243,236,215,130,52,189,82,50,110,62,95,201,198,130,236,85,183,252,82,217,75,92,208,25,83,99,187,76,234,21,205,234,113,112,30,114,175,64,222,118,233,144,7,107,27,178,239,2,59,96,254,136,141,230,230,186,107,147,13,87,209,130,140,10, +174,40,73,71,162,237,119,121,35,55,240,65,42,93,131,125,203,255,134,221,48,121,241,161,190,98,161,134,177,173,234,165,193,147,62,217,213,252,50,137,47,214,114,123,140,27,197,33,243,24,93,104,78,165,169,193,188,85,96,118,95,10,76,174,241,166,139,220,188, +1,221,7,234,158,28,117,183,229,252,195,70,175,31,207,67,219,36,208,238,191,8,104,245,204,185,152,13,90,11,176,89,2,244,253,223,111,150,122,87,183,93,114,26,229,12,11,142,196,33,243,168,168,176,142,15,201,30,62,67,210,104,109,111,151,187,13,96,219,91, +109,121,195,85,90,94,114,149,150,247,92,165,229,69,200,231,116,136,255,125,216,198,217,219,217,219,139,22,68,216,222,152,90,63,3,149,186,121,6,45,169,238,25,132,82,9,109,6,90,42,17,158,65,56,149,104,157,65,107,234,12,34,31,209,178,5,59,40,91,57,31,140, +124,7,165,94,233,223,136,111,162,31,242,56,226,77,66,43,122,111,241,17,166,37,212,91,231,16,61,148,250,24,45,101,44,59,135,216,161,51,104,11,70,122,25,203,227,43,40,202,88,121,134,143,21,106,67,101,172,154,198,154,245,101,196,167,177,154,10,37,202,224, +195,101,179,184,252,116,48,51,254,26,34,218,41,104,161,237,29,211,152,88,210,255,21,115,254,135,186,203,88,61,34,62,103,113,101,213,48,126,21,63,83,165,149,145,160,85,25,87,7,223,191,33,186,238,179,232,8,161,59,112,182,102,164,134,102,22,215,12,241,211, +90,133,173,90,66,59,11,94,170,211,216,46,189,107,21,62,67,116,107,184,33,198,117,140,145,8,115,1,1,148,106,144,68,120,22,215,143,156,250,239,167,85,191,52,232,44,227,6,137,198,255,214,89,86,101,161,155,155,2,168,45,129,163,120,50,24,134,26,253,86,29, +16,102,87,93,254,184,192,27,152,191,173,90,37,180,54,139,20,115,188,126,36,161,157,174,176,66,170,58,138,213,148,189,72,146,67,91,200,162,12,185,115,152,189,7,200,156,19,100,205,73,242,230,67,86,246,60,173,255,129,157,248,55,118,225,43,244,171,56,6,84, +7,223,15,107,113,151,186,29,131,106,2,247,168,227,200,168,147,216,163,94,193,144,122,157,60,19,166,236,227,175,160,19,236,221,73,166,134,56,115,61,238,98,47,140,47,201,153,187,49,8,77,184,82,229,81,82,77,225,30,126,85,56,172,118,225,94,98,105,97,188, +127,97,15,134,16,162,231,85,184,143,95,53,122,14,24,24,124,187,159,126,247,81,163,81,51,220,190,147,126,247,7,92,228,94,81,21,158,134,83,101,220,124,122,9,34,135,171,0,230,220,80,30,168,216,31,196,72,165,253,22,14,85,190,141,226,219,76,0,248,115,145, +59,26,149,191,175,1,80,75,3,4,10,0,0,8,8,0,22,178,149,71,106,32,106,144,180,1,0,0,86,3,0,0,56,0,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,80,97,116,104,65,115,115,101,109,98,108,101,114,36,76,111,99,97,108,68,105,115, +116,114,105,98,117,116,105,111,110,46,99,108,97,115,115,149,82,91,75,27,65,20,254,206,102,221,213,116,171,113,181,182,218,91,180,121,136,107,235,218,226,91,75,65,18,4,33,180,133,22,31,124,40,76,146,33,78,186,217,13,147,77,139,255,74,193,80,240,161,63, +192,31,85,60,51,134,210,168,16,124,216,153,115,251,46,115,216,203,191,23,127,0,188,197,171,57,204,96,173,8,15,79,77,244,204,28,207,125,188,244,81,38,248,109,53,200,143,84,159,48,223,232,138,159,34,86,89,188,175,18,249,126,220,170,43,77,240,242,99,53, +168,236,16,54,26,153,238,196,29,45,218,137,140,127,105,209,239,75,29,127,17,249,241,222,96,32,123,205,68,106,198,121,31,84,170,242,143,132,189,234,244,241,73,209,201,108,243,144,224,214,178,182,36,44,52,84,42,63,13,123,77,169,191,9,6,18,194,70,214,18, +201,161,208,202,228,227,162,107,140,18,22,109,175,206,246,181,106,14,115,149,165,132,224,32,77,165,174,37,130,165,121,100,119,170,181,202,45,18,126,91,216,145,249,255,37,187,158,82,117,243,230,238,138,60,199,91,53,25,39,95,179,161,110,201,235,36,156, +16,217,54,184,0,69,60,8,16,96,61,192,28,102,3,248,152,245,177,65,120,119,127,143,236,198,90,73,68,218,137,63,55,187,178,149,19,10,85,179,202,242,52,54,172,243,159,225,241,63,83,64,104,60,112,20,26,67,64,169,100,44,218,14,111,18,15,249,156,231,236,59, +28,184,124,47,71,91,35,80,244,27,78,244,122,132,66,244,102,4,247,140,235,14,22,44,135,153,81,204,212,101,212,15,44,33,65,137,43,101,102,99,44,22,249,131,141,140,150,99,35,163,110,180,30,97,101,172,21,243,77,124,207,68,231,40,156,254,35,247,108,81,91, +194,224,122,96,76,72,120,124,39,216,189,9,62,185,3,236,224,137,61,87,217,45,248,237,196,157,23,252,18,186,2,80,75,3,4,10,0,0,8,8,0,22,178,149,71,146,99,74,27,25,8,0,0,75,15,0,0,33,0,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101, +114,47,68,111,119,110,108,111,97,100,46,99,108,97,115,115,133,87,137,127,20,103,25,126,102,179,187,51,59,12,57,22,18,88,40,144,166,13,108,238,34,10,146,180,212,36,144,118,219,52,193,44,9,93,80,113,178,59,217,44,221,204,108,103,102,9,84,109,189,170,245, +110,181,30,85,164,94,21,91,143,150,182,108,40,208,226,85,84,60,90,173,86,91,252,23,252,23,212,231,155,221,236,17,86,204,47,249,142,247,251,222,227,123,159,231,123,231,203,149,127,159,127,5,192,118,252,83,101,99,133,176,3,57,209,220,47,26,91,101,227,40, +112,85,228,113,76,198,162,10,5,199,85,156,192,3,42,62,132,15,139,230,35,98,207,131,42,30,194,71,101,124,76,198,199,85,52,227,19,42,154,240,73,21,15,227,83,98,249,211,10,30,81,241,25,124,86,52,159,83,241,121,124,65,197,23,241,37,209,60,26,162,237,199, +20,124,89,197,87,240,184,140,175,42,248,154,138,205,248,122,0,222,207,68,187,130,111,168,120,2,223,84,241,45,156,84,176,83,76,190,45,140,156,18,146,83,10,158,84,240,29,5,223,85,240,61,5,223,87,240,3,5,79,201,248,161,138,211,248,145,140,167,101,60,35, +227,199,18,32,65,139,153,166,97,143,102,117,199,49,28,9,29,241,19,142,107,44,236,183,173,156,97,187,25,195,225,232,248,137,225,188,59,111,152,110,38,169,187,150,45,161,113,255,212,228,29,83,251,226,241,35,163,119,78,79,220,45,65,138,73,88,61,106,153, +142,171,155,238,140,158,205,27,13,34,74,9,171,70,166,199,198,246,77,29,137,199,14,237,163,104,91,179,132,96,214,74,167,13,90,217,56,110,217,233,129,180,173,167,178,198,192,162,173,231,232,113,96,220,91,28,146,208,196,121,86,56,204,88,230,132,190,96,72, +8,143,31,213,143,233,3,89,221,76,15,196,93,59,99,166,185,45,92,181,109,198,176,29,118,116,113,107,198,204,184,123,36,140,68,175,227,227,90,115,215,74,186,102,36,248,71,173,20,221,55,141,103,76,99,34,191,48,107,216,7,244,217,172,23,144,149,212,179,51, +186,157,17,243,146,208,239,206,103,152,199,77,245,28,239,181,22,205,172,165,167,24,247,13,73,203,156,203,164,243,182,177,50,193,222,9,26,162,194,179,146,42,41,72,216,18,45,6,103,26,238,192,244,84,172,20,106,198,26,24,203,100,13,47,76,89,79,165,108,195, +161,239,198,218,173,68,33,101,56,110,198,44,217,110,172,213,149,160,238,59,158,52,114,98,209,145,241,19,9,205,203,110,99,166,107,216,166,158,101,60,121,59,187,194,240,56,53,27,243,142,97,15,167,141,18,232,204,252,108,126,110,78,128,235,59,60,194,144, +204,252,194,148,33,194,111,202,217,86,90,68,55,106,229,133,81,82,230,46,90,181,242,174,132,182,114,60,147,121,55,151,119,153,122,67,95,160,117,63,115,196,120,215,215,120,37,203,76,35,41,130,229,14,95,134,235,173,101,253,152,89,173,30,38,56,201,124,86, +119,141,233,229,40,37,172,141,118,213,163,145,74,128,202,244,81,197,134,25,195,76,9,174,175,42,78,74,75,45,149,165,10,219,44,167,72,208,144,229,84,11,135,237,228,60,141,197,173,188,157,52,68,170,121,71,150,25,208,47,236,104,216,139,113,13,183,227,61, +26,134,49,162,97,84,52,119,99,156,137,157,119,221,92,127,78,80,67,4,47,227,167,26,126,134,103,37,236,185,14,173,110,254,255,119,87,184,124,78,198,25,13,207,227,5,25,47,106,56,139,130,134,37,156,211,48,141,9,25,47,105,56,143,11,228,231,114,78,71,60,64, +141,84,53,54,196,164,154,66,213,75,194,193,69,209,188,44,227,21,13,151,240,115,13,41,240,232,170,56,71,159,135,130,140,95,104,248,37,126,165,225,215,120,85,198,101,13,191,193,111,101,252,78,195,21,252,94,195,31,68,48,31,192,31,153,251,140,224,138,157, +207,185,70,74,198,159,52,188,134,215,37,172,41,195,61,89,38,174,132,200,114,22,218,23,117,167,189,74,177,95,68,67,53,169,95,198,159,53,252,5,111,200,248,171,134,191,225,77,13,127,199,235,26,254,33,18,238,193,220,127,172,4,186,86,154,149,192,108,42,78, +23,42,18,217,114,250,77,15,116,149,163,26,177,238,193,190,177,211,25,232,116,218,163,157,206,144,247,219,85,53,228,13,171,80,112,114,246,40,233,44,227,45,13,111,227,42,21,175,3,48,97,169,179,26,171,44,111,186,30,59,182,47,167,206,243,91,149,186,170,104, +138,12,98,58,210,134,91,226,209,9,9,91,163,117,42,99,189,107,212,81,183,222,86,34,240,10,85,91,249,58,175,248,172,168,142,225,238,53,230,244,124,150,23,117,99,85,193,171,217,231,217,208,170,249,199,123,37,194,213,109,238,41,206,155,151,111,121,165,200, +5,23,238,75,101,108,199,43,173,135,150,13,148,74,164,132,128,107,177,182,84,41,86,106,92,75,244,218,90,27,137,214,175,89,149,208,74,250,188,201,76,162,89,41,90,18,54,172,112,81,83,208,218,234,175,176,152,49,55,83,198,253,121,22,242,10,46,219,234,224, +82,255,27,214,200,4,85,85,71,9,235,170,50,84,91,54,215,212,17,179,22,219,94,29,15,68,15,143,116,197,106,40,115,96,190,184,180,58,153,183,5,2,203,243,218,74,91,148,210,252,234,140,19,171,92,206,234,234,189,159,209,214,9,163,74,76,255,57,49,163,86,61,70, +10,96,254,231,231,158,12,16,83,147,46,111,169,86,30,157,215,237,184,72,172,153,52,106,72,61,236,237,22,31,117,70,179,182,30,220,12,103,209,206,184,228,155,204,180,196,98,34,128,6,190,110,40,79,102,45,199,168,189,89,94,144,140,98,206,178,23,116,30,97, +119,157,35,28,30,95,89,24,234,221,51,220,200,247,227,118,190,221,222,137,0,54,96,55,6,57,30,226,187,208,135,91,57,191,173,106,190,7,97,241,125,225,56,44,62,49,94,63,234,245,1,238,217,139,125,108,199,56,115,185,215,207,126,125,247,18,164,238,158,179,240, +117,247,158,69,67,119,223,89,248,41,10,156,241,172,221,193,118,3,130,108,55,113,247,102,132,176,5,141,104,199,26,70,180,14,29,184,147,43,221,69,59,136,225,46,239,173,186,222,243,47,121,35,17,129,207,27,137,24,26,56,230,199,174,20,193,24,231,98,215,218, +112,240,28,228,203,104,188,0,37,33,45,33,116,14,106,197,123,35,119,1,157,124,114,111,165,215,168,231,81,43,234,149,60,74,184,7,19,220,45,108,78,115,183,216,223,212,91,192,170,2,180,131,221,61,189,75,88,189,210,92,15,205,245,114,220,231,153,107,47,170, +148,15,208,132,73,236,247,92,52,225,189,152,162,102,156,99,63,37,7,56,158,94,118,38,253,139,41,93,205,149,171,210,132,52,24,232,41,160,113,48,120,1,77,137,11,104,78,208,107,203,18,194,19,145,96,1,107,6,69,70,215,14,202,17,127,184,53,34,23,208,22,241, +23,176,110,48,208,178,173,249,162,50,168,132,118,169,145,64,68,41,96,125,98,103,200,247,36,38,207,33,82,192,134,39,208,250,60,54,134,111,40,96,211,5,108,78,132,183,44,161,253,82,155,218,26,122,88,223,165,182,169,107,113,227,66,232,241,83,104,237,126, +17,190,240,77,5,220,124,208,19,26,187,212,190,136,210,208,26,42,160,243,244,127,158,246,86,183,22,176,45,18,184,12,37,18,40,32,218,119,25,221,125,5,116,157,198,77,131,90,253,117,89,172,71,180,75,103,120,212,0,78,242,133,0,254,93,244,250,98,34,31,32,27, +196,127,76,62,50,51,128,119,97,21,118,98,35,118,145,19,239,38,74,187,185,50,200,209,16,185,112,27,145,223,195,132,222,142,4,121,161,147,19,247,145,13,14,185,248,32,217,248,8,83,249,40,97,56,73,102,60,69,110,60,67,52,159,37,0,47,80,227,60,101,175,82,118, +133,178,215,40,123,131,178,183,9,134,0,45,71,143,171,240,24,102,112,144,252,140,146,207,247,210,143,76,47,239,167,159,67,4,120,156,187,15,51,138,16,229,135,240,62,202,85,1,86,25,230,171,101,152,175,150,96,246,225,45,62,67,142,144,14,29,120,9,31,100,172, +126,158,237,77,204,34,201,190,154,4,124,224,148,88,44,72,160,176,215,153,72,255,120,184,155,84,190,39,220,195,118,34,220,203,118,208,31,238,19,93,32,220,47,186,96,120,64,116,114,248,150,102,229,101,108,79,52,80,171,33,158,240,247,196,19,129,72,32,158, +8,70,130,241,132,28,145,227,9,165,55,158,104,14,246,177,33,109,226,231,240,142,231,202,169,239,240,28,206,208,241,189,76,65,2,45,60,222,122,30,117,11,15,185,149,199,236,227,33,68,138,166,138,129,149,14,28,224,234,28,83,193,79,61,117,211,222,197,108,97, +2,230,189,139,41,174,111,134,35,63,173,140,224,40,255,2,180,53,68,168,70,152,222,62,22,158,172,151,94,31,22,188,56,76,66,45,74,139,143,208,239,0,154,21,250,218,65,192,213,255,2,80,75,3,4,10,0,0,8,8,0,22,178,149,71,192,25,62,198,80,0,0,0,78,0,0,0,35,0, +0,0,103,114,97,100,108,101,45,119,114,97,112,112,101,114,45,99,108,97,115,115,112,97,116,104,46,112,114,111,112,101,114,116,105,101,115,83,206,205,79,41,205,73,85,72,73,77,203,204,203,44,201,204,207,227,82,246,205,207,83,112,73,77,86,48,50,84,48,50,178, +50,52,179,50,49,81,112,118,13,81,48,50,48,52,229,42,40,202,207,74,77,46,41,182,77,47,74,76,201,73,213,77,206,201,228,42,42,205,43,201,204,77,181,229,2,0,80,75,3,4,10,0,0,8,8,0,10,178,149,71,36,217,150,101,206,0,0,0,28,1,0,0,24,0,0,0,98,117,105,108,100, +45,114,101,99,101,105,112,116,46,112,114,111,112,101,114,116,105,101,115,53,143,189,110,195,48,12,132,119,190,74,17,65,148,127,51,104,201,86,160,200,210,162,107,65,75,180,163,192,146,12,73,54,250,248,181,155,132,219,125,228,241,200,97,117,179,189,174, +126,224,164,67,12,12,195,1,190,156,231,92,200,47,90,73,108,80,41,84,136,141,172,223,228,94,96,162,247,174,188,91,173,186,118,176,198,178,237,42,57,54,21,81,111,16,135,186,59,159,251,150,104,164,166,103,84,53,181,112,139,185,4,242,172,45,111,40,166,68, +118,102,17,211,4,46,127,6,90,242,45,22,61,210,156,25,238,180,209,55,167,236,98,208,40,58,33,127,164,130,152,175,135,249,195,133,245,119,23,175,126,37,176,18,242,212,170,211,196,129,147,51,176,164,120,103,83,244,35,1,146,121,126,6,107,230,244,127,64,49, +180,15,23,132,237,177,228,66,153,181,18,40,95,224,233,56,208,31,80,75,3,4,10,0,0,8,8,0,10,178,149,71,0,0,0,0,2,0,0,0,0,0,0,0,15,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,3,0,80,75,3,4,10,0,0,8,8,0,10,178,149,71,144,200,244,150,60,2, +0,0,83,5,0,0,49,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,65,98,115,116,114,97,99,116,67,111,109,109,97,110,100,76,105,110,101,67,111,110,118,101,114,116,101,114,46,99,108,97,115,115,149,84,93,111,18,65,20,61,3,11,139,43,182,136,109, +173,223,208,15,229,163,116,219,62,153,66,72,8,209,104,66,170,17,210,196,199,101,25,215,109,96,151,12,67,163,127,194,223,162,47,52,209,196,31,224,143,50,222,89,144,80,150,180,244,97,231,222,57,123,239,185,115,230,222,221,63,127,127,254,6,112,136,35,3, +9,236,232,216,53,16,193,142,1,29,207,149,247,66,121,57,29,121,29,5,29,69,134,120,197,245,92,89,101,136,230,242,167,12,90,221,239,112,134,213,134,235,241,147,97,175,205,69,203,106,119,9,73,55,124,219,234,158,90,194,85,251,9,168,201,207,238,128,161,212, +240,133,99,58,194,234,116,185,105,119,93,179,214,30,72,97,217,178,238,247,122,150,215,81,100,117,223,59,231,66,114,81,102,216,184,204,245,181,255,159,239,232,38,68,149,86,171,92,37,54,221,30,35,12,199,185,198,153,117,110,153,93,203,115,204,183,20,162, +88,203,51,216,187,246,25,183,101,57,31,134,72,139,37,28,210,178,182,136,130,174,73,210,107,46,213,61,44,200,141,247,45,49,224,130,97,107,94,192,204,193,223,7,49,20,189,232,148,149,25,172,41,133,235,57,129,182,40,105,100,48,94,125,177,121,95,186,190,55, +208,177,199,112,171,233,58,158,37,135,130,174,236,96,105,54,162,202,7,116,31,42,173,227,176,138,106,24,186,66,76,168,11,70,211,31,10,155,191,118,85,31,179,87,245,109,95,213,73,194,192,109,134,204,117,215,149,68,9,251,73,152,56,72,226,30,14,25,138,55, +152,16,134,212,188,38,134,237,37,68,133,203,204,68,213,132,51,236,113,79,78,155,66,13,161,17,252,228,58,65,67,118,115,215,207,128,250,210,98,193,204,48,188,92,56,180,249,121,146,32,179,51,67,69,119,254,38,84,42,28,181,212,244,107,89,250,43,36,64,66,232, +223,17,33,75,205,161,53,73,187,26,89,70,54,86,184,0,251,65,78,20,119,104,141,7,96,26,43,180,38,199,1,88,69,138,236,221,75,72,154,44,163,206,173,81,158,162,251,70,86,35,187,249,11,145,143,23,136,158,20,74,35,104,133,82,113,132,216,222,8,241,239,211,10, +43,100,65,121,9,172,211,126,35,168,84,24,231,78,42,41,111,157,222,176,192,187,79,79,132,162,83,120,128,135,148,171,206,145,9,56,54,39,231,24,199,63,154,198,63,166,248,39,228,107,132,60,197,179,64,122,134,158,177,151,197,86,96,183,255,1,80,75,3,4,10,0, +0,8,8,0,10,178,149,71,50,95,101,143,166,0,0,0,232,0,0,0,40,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,49,46,99,108,97,115,115,133,140,65,10,194,48,16,69,255,104,181,90, +11,118,229,186,136,107,67,207,80,20,4,69,193,19,196,118,168,45,105,2,73,245,112,46,60,128,135,18,83,92,186,112,62,243,63,31,102,222,235,253,120,2,200,16,135,8,67,68,132,232,108,110,182,224,109,173,152,176,200,77,219,74,93,238,107,205,39,105,29,219,117, +35,239,146,48,223,232,66,25,87,235,234,192,221,213,148,33,102,132,165,177,149,168,172,44,21,139,66,213,226,231,121,149,17,64,136,119,90,179,205,149,116,142,29,33,233,145,66,73,93,137,227,165,225,162,35,164,255,72,73,234,57,3,124,103,232,5,223,2,140,124, +6,24,123,159,250,141,252,13,245,45,153,124,0,80,75,3,4,10,0,0,8,8,0,10,178,149,71,82,66,9,29,168,2,0,0,247,6,0,0,60,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,77,105, +115,115,105,110,103,79,112,116,105,111,110,65,114,103,83,116,97,116,101,46,99,108,97,115,115,157,149,93,79,211,96,20,199,255,207,54,186,173,235,100,160,32,190,50,23,148,189,32,99,136,128,128,38,130,47,49,78,52,193,96,130,87,15,172,153,53,221,83,210,22, +223,47,188,241,198,27,253,32,94,72,162,35,241,194,15,224,135,50,158,167,45,115,27,75,198,150,38,237,57,79,207,249,157,215,180,127,254,254,250,13,160,132,21,21,49,228,85,196,81,136,147,52,37,213,171,42,18,152,150,103,69,41,205,68,49,27,197,53,6,197,218, +117,13,75,68,49,199,48,244,216,147,159,112,219,209,237,13,151,187,58,131,246,64,8,221,94,51,185,227,232,14,195,92,217,178,171,197,170,205,43,166,94,220,49,141,226,154,85,171,113,81,41,27,66,247,253,38,142,64,150,41,202,138,33,12,247,22,195,66,182,31, +64,110,147,33,178,102,85,40,159,65,105,184,190,87,219,214,237,167,124,219,164,147,225,178,181,195,205,77,110,27,82,15,14,35,238,11,131,210,29,121,100,56,142,33,170,62,242,182,93,13,170,90,236,158,69,71,79,42,37,85,227,111,183,117,210,108,215,127,71,81, +178,229,151,252,21,47,154,92,84,139,27,174,77,110,203,185,45,134,48,183,171,50,191,35,47,25,146,150,104,65,108,117,64,116,128,246,215,253,132,37,214,45,113,24,42,209,50,223,213,78,185,119,15,211,26,32,101,137,38,147,187,162,66,181,103,115,155,81,92,103, +0,195,243,190,134,222,221,167,228,45,70,232,205,140,188,149,24,38,142,227,194,160,110,88,123,246,142,126,207,144,139,50,122,196,102,90,246,67,195,32,82,242,54,175,65,197,9,13,11,24,211,176,136,27,26,206,225,188,134,37,140,71,65,172,249,254,246,136,97, +170,151,22,51,204,246,222,64,134,76,247,118,48,76,30,99,56,126,163,99,134,115,184,67,170,55,240,93,83,151,97,102,178,61,47,140,234,181,98,175,166,11,151,33,221,205,25,105,250,128,197,33,87,105,88,78,131,36,5,33,57,33,58,25,34,237,62,105,33,122,38,242, +236,0,161,124,225,39,194,251,164,134,200,28,100,30,38,207,119,24,96,239,161,178,15,56,73,103,163,190,57,78,145,4,79,146,88,70,215,105,140,5,208,165,0,170,228,11,117,68,190,53,120,10,228,82,127,108,226,40,13,142,130,51,56,235,113,104,75,2,206,67,138,79, +25,32,153,255,129,112,29,3,133,169,58,148,239,109,184,79,30,46,237,27,54,112,201,0,39,37,149,164,16,201,23,48,30,128,111,6,9,198,37,152,114,140,182,67,63,55,229,24,111,64,227,141,28,211,184,20,160,22,60,61,64,81,142,207,254,183,79,149,238,236,11,98,236, +171,135,211,124,67,31,151,2,77,97,34,128,220,33,203,176,223,176,3,176,253,182,100,94,55,85,216,220,176,203,94,227,165,116,5,147,94,69,89,207,51,71,53,3,25,68,104,56,37,104,17,249,19,43,97,4,242,23,86,194,69,210,51,244,68,42,246,15,80,75,3,4,10,0,0,8, +8,0,10,178,149,71,188,172,77,50,145,2,0,0,131,5,0,0,61,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,79,112,116,105,111,110,83,116,114,105,110,103,67,111,109,112,97,114, +97,116,111,114,46,99,108,97,115,115,157,84,207,79,19,65,20,254,102,186,101,97,109,161,242,163,96,181,130,90,161,80,100,41,32,72,74,136,164,137,9,177,17,19,12,137,222,166,237,166,12,89,118,201,238,150,248,175,192,201,155,7,123,241,2,137,38,198,179,127, +148,241,205,118,173,66,107,106,56,116,222,155,247,190,121,239,219,111,222,244,199,207,47,223,0,20,241,204,192,16,230,13,24,106,209,177,160,99,209,128,134,37,181,152,58,150,85,154,108,81,199,138,142,85,134,129,45,233,200,96,155,33,150,159,63,96,208,202, +110,221,98,24,169,72,199,122,213,60,174,90,222,27,81,181,41,50,90,113,107,194,62,16,158,84,251,40,168,5,135,210,103,72,239,157,4,210,117,246,3,79,58,141,178,123,124,34,60,17,184,30,67,98,215,113,44,175,108,11,223,183,8,183,89,113,189,134,217,240,68,221, +182,204,154,45,77,194,30,11,167,174,154,189,22,158,111,121,185,222,149,74,12,122,45,220,81,211,185,124,229,72,156,10,211,22,78,195,108,35,75,221,145,249,93,58,227,134,213,138,138,125,23,160,147,94,33,17,252,67,215,11,8,199,222,253,222,172,92,107,180, +87,61,178,106,65,169,59,162,26,241,247,203,87,123,68,57,149,33,165,215,24,16,150,235,251,249,197,146,186,132,220,255,0,25,134,246,101,195,17,65,83,137,178,245,47,170,205,64,218,230,31,37,183,186,133,216,166,82,198,190,219,244,106,214,11,169,110,53,221, +213,110,73,29,74,32,129,100,2,79,177,174,99,131,225,121,95,142,101,225,91,187,142,111,57,190,12,228,169,213,61,30,211,125,16,170,227,163,4,38,144,102,72,93,231,205,176,113,195,105,186,82,172,45,22,195,120,47,181,24,30,246,191,9,154,24,219,114,26,193, +97,248,134,104,26,102,250,157,193,50,61,66,131,70,226,22,61,89,13,92,9,75,187,97,218,153,100,105,90,16,95,184,4,255,76,14,199,8,173,3,42,200,83,72,145,159,104,3,112,27,227,80,115,69,242,68,135,63,33,70,113,96,167,112,129,152,246,1,186,246,17,90,108,123, +241,239,221,186,150,61,131,49,161,157,35,206,91,217,115,229,158,33,174,181,190,66,123,203,46,17,47,16,122,160,213,105,124,159,254,67,192,71,49,204,199,144,229,227,152,229,19,200,243,73,20,249,20,86,121,38,36,180,214,110,26,17,82,222,36,166,66,146,59, +184,67,30,39,114,171,200,224,46,209,203,34,135,123,228,105,169,29,34,158,141,136,191,164,76,140,108,114,161,240,29,250,34,253,46,48,216,234,249,245,51,109,96,167,89,146,40,78,135,205,146,148,155,86,48,53,53,81,225,77,178,60,146,147,245,150,51,221,6,116, +10,198,169,96,142,242,49,60,14,241,179,152,11,109,30,99,100,51,20,31,66,1,163,228,61,32,139,212,32,221,96,1,79,144,249,5,80,75,3,4,10,0,0,8,8,0,10,178,149,71,232,35,13,242,71,1,0,0,75,2,0,0,49,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105, +47,67,111,109,109,97,110,100,76,105,110,101,65,114,103,117,109,101,110,116,69,120,99,101,112,116,105,111,110,46,99,108,97,115,115,149,145,205,74,3,49,20,133,79,250,51,163,181,182,90,109,43,234,194,238,180,85,7,215,149,130,136,130,48,184,176,165,251,116, +26,166,145,153,68,50,51,234,107,185,42,184,240,1,124,40,49,73,75,21,45,130,89,220,228,158,220,251,221,19,242,254,241,250,6,224,12,205,18,10,216,50,97,219,69,221,69,131,192,57,231,130,167,61,130,250,161,127,79,31,169,23,81,17,122,253,84,113,17,118,143, +134,4,133,75,57,102,4,85,159,11,118,155,197,35,166,6,116,20,105,165,230,203,128,70,67,170,184,201,231,98,33,157,240,132,224,196,151,42,244,66,69,199,17,243,130,136,123,151,50,142,169,24,27,200,133,10,179,152,137,244,234,57,96,15,41,151,162,75,224,198, +44,73,104,104,169,191,92,16,180,151,120,251,166,12,38,74,62,153,249,214,112,49,160,89,162,73,245,165,21,4,165,190,204,84,192,174,185,241,219,250,203,216,169,1,148,81,132,99,66,133,160,243,143,87,17,236,126,205,191,203,68,202,99,182,184,68,11,121,253, +11,102,229,64,204,4,29,93,157,245,116,158,211,187,211,238,76,65,94,236,253,138,142,37,171,54,117,229,14,86,245,169,49,171,210,250,154,165,56,40,99,93,51,12,171,50,103,221,232,25,121,189,187,237,206,241,20,185,159,176,61,221,180,111,97,7,179,178,5,204, +157,195,204,169,138,13,107,113,211,118,215,62,1,80,75,3,4,10,0,0,8,8,0,10,178,149,71,63,23,104,255,199,7,0,0,135,19,0,0,61,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36, +75,110,111,119,110,79,112,116,105,111,110,80,97,114,115,101,114,83,116,97,116,101,46,99,108,97,115,115,221,88,107,120,20,229,21,126,191,100,147,89,38,3,134,133,0,129,86,167,154,144,100,115,15,1,139,208,180,33,162,164,134,64,27,76,140,180,218,97,119,76, +6,55,51,219,153,217,4,236,197,74,91,237,221,94,208,54,86,123,177,8,218,122,129,74,18,66,188,212,94,176,162,245,214,162,79,255,246,121,250,60,125,250,223,159,173,61,103,102,118,179,155,221,176,137,63,251,231,155,243,157,239,220,190,115,251,206,238,197, +255,158,127,1,64,59,222,149,177,5,119,174,160,37,33,163,19,99,18,76,25,33,88,140,73,242,242,121,94,108,94,28,94,92,166,79,73,24,15,99,66,194,17,25,215,224,168,12,5,119,49,244,133,48,190,88,129,47,225,203,76,116,183,76,226,191,194,219,123,36,124,85,198, +122,124,61,140,123,101,108,195,125,50,190,129,111,242,201,183,100,124,27,223,97,194,239,134,241,61,198,220,95,129,239,227,7,188,252,80,194,143,248,248,56,31,63,32,227,24,30,148,240,99,25,117,176,194,248,9,127,39,121,121,40,140,159,242,247,97,25,143,224, +103,76,251,243,10,252,2,247,75,248,37,171,121,84,194,175,36,156,16,80,172,164,107,88,230,128,107,27,230,136,132,147,132,217,151,133,161,109,175,105,234,118,79,66,115,28,221,17,104,237,179,236,145,214,17,91,139,39,244,214,88,194,104,237,177,198,198,52, +51,222,103,152,250,126,205,118,116,187,38,155,127,135,64,185,175,65,224,234,203,176,250,60,68,93,17,155,71,22,96,241,84,196,179,24,137,165,204,113,53,87,151,112,138,184,125,19,6,24,33,208,82,220,214,44,122,54,117,92,75,164,248,150,149,125,135,181,113, +173,53,229,26,137,214,62,195,113,233,108,197,128,49,98,106,110,202,38,193,53,11,142,119,250,251,132,102,142,180,6,247,238,98,113,238,168,225,212,180,93,254,230,190,5,76,189,211,48,13,183,75,224,66,125,113,242,101,70,161,184,231,139,59,122,121,206,108, +24,20,8,245,88,113,242,214,21,76,210,159,26,59,164,219,7,180,67,9,194,68,250,172,152,150,24,212,108,131,247,1,50,196,222,18,88,119,147,105,77,152,190,85,57,209,220,94,220,128,194,172,228,91,217,50,187,237,145,212,152,110,186,2,187,234,243,195,213,176, +220,84,9,107,25,121,145,124,113,2,171,216,247,154,237,246,235,71,92,82,45,208,86,191,108,29,171,70,116,119,143,230,204,91,94,90,223,112,171,119,25,226,76,38,116,246,74,153,151,178,2,37,70,141,192,218,172,188,236,117,117,91,115,45,206,172,10,203,29,213, +237,125,65,25,42,73,47,180,233,109,94,178,229,69,62,200,16,9,143,11,64,224,223,255,15,233,89,156,186,221,75,225,146,35,109,188,180,243,210,193,203,22,94,58,121,217,202,125,96,9,98,40,96,3,86,202,142,233,55,24,156,230,235,242,104,90,56,104,10,246,160, +87,193,13,184,145,161,39,4,214,204,135,178,219,182,181,163,220,103,248,232,215,10,118,161,71,193,86,108,87,112,29,118,40,216,137,143,41,232,66,183,130,65,12,9,52,46,110,83,58,147,118,31,137,233,65,248,183,4,199,205,9,58,87,253,86,173,214,213,58,117,106, +220,210,29,213,180,92,213,213,238,212,85,205,84,211,25,223,66,253,113,62,227,247,29,58,172,199,200,178,223,224,73,54,239,41,5,79,227,25,129,157,221,166,170,143,37,221,163,25,54,117,66,115,212,164,109,141,27,113,61,174,222,97,217,106,108,17,213,45,18, +78,43,56,131,223,42,184,5,55,43,120,22,67,10,206,98,72,194,148,192,182,162,46,223,107,56,14,101,149,159,57,116,229,160,127,84,21,196,179,205,211,36,181,223,250,32,134,42,152,193,57,9,179,10,206,99,78,193,115,120,70,194,243,10,94,192,139,10,126,199,193, +232,218,155,74,184,6,213,106,70,186,163,78,232,182,190,100,249,47,225,247,18,254,160,224,143,236,131,63,225,66,142,239,253,242,81,240,50,187,253,207,120,69,193,69,188,42,176,126,33,197,174,148,145,136,235,54,245,216,3,163,186,170,224,53,252,133,151,215, +5,54,164,213,25,142,26,215,147,182,30,35,159,196,213,102,34,122,3,175,72,120,83,193,91,44,252,109,252,85,194,223,4,212,98,149,170,224,18,222,17,184,246,3,246,106,129,142,37,182,142,28,166,213,5,112,205,203,234,65,2,77,203,105,32,244,166,23,47,125,129, +186,226,189,50,104,52,212,218,105,45,167,108,24,211,168,211,111,47,240,70,29,236,91,88,117,244,108,21,120,122,170,10,189,111,44,60,161,155,35,238,168,167,171,151,94,151,220,25,134,208,90,60,190,128,59,173,134,94,157,8,61,70,221,137,132,53,145,121,143, +232,177,150,12,103,55,23,249,101,19,195,191,167,192,193,37,56,35,255,241,94,170,3,43,180,88,76,119,156,154,246,206,54,106,217,61,75,214,149,25,0,10,120,114,225,165,242,94,29,26,11,201,105,233,167,244,182,2,142,47,254,180,229,141,5,139,61,192,84,190,142, +113,23,233,220,188,52,6,50,142,98,54,24,140,180,145,250,134,252,161,118,99,38,168,233,62,149,21,220,176,17,140,16,244,104,229,48,103,141,22,145,124,44,101,197,168,230,240,220,67,6,155,222,103,109,125,67,126,82,113,200,226,241,249,225,166,138,108,185, +62,104,65,100,253,144,102,155,94,93,230,50,103,98,147,137,247,86,142,247,246,37,12,37,129,24,195,106,221,79,50,220,33,155,239,199,131,183,150,76,234,38,165,126,115,193,193,112,145,102,186,99,1,253,162,21,57,79,31,118,173,116,179,89,83,192,20,114,92,146, +119,9,30,210,200,25,55,218,86,42,57,100,112,197,174,206,241,255,128,206,222,91,153,131,32,22,91,31,179,198,51,177,175,189,156,71,210,169,55,8,149,126,146,118,210,79,222,114,68,120,164,32,40,194,83,133,247,165,193,194,251,210,108,225,125,105,238,160,249, +239,122,130,75,176,187,178,146,135,21,143,179,132,103,23,58,249,36,237,30,68,41,97,128,166,104,227,20,74,162,98,6,165,209,57,132,134,103,80,54,133,242,104,211,20,164,104,243,20,194,209,234,208,20,86,68,171,9,43,159,241,36,222,68,235,149,144,104,196,60, +1,89,60,138,42,241,24,54,138,147,184,74,156,66,173,120,28,141,226,9,244,17,77,39,202,88,62,246,98,31,224,65,108,119,137,7,177,229,165,30,196,182,135,60,136,173,47,35,235,246,227,83,25,27,37,143,190,63,58,141,138,135,176,105,14,202,112,100,101,232,121, +172,26,46,141,158,133,52,112,14,87,204,160,242,197,198,105,172,78,31,71,242,143,9,46,111,156,197,154,18,12,145,160,181,167,51,183,216,200,30,16,79,65,18,79,147,245,167,177,89,156,65,151,120,22,189,226,172,119,131,117,190,246,204,13,250,241,105,12,144, +109,2,7,112,115,96,227,16,89,79,227,54,106,73,75,120,26,85,147,168,102,125,179,88,39,48,137,149,115,88,63,204,206,221,112,58,87,245,42,190,190,96,170,243,80,197,115,158,58,197,23,20,168,19,60,37,6,74,58,60,165,160,104,248,74,158,204,200,41,103,188,120, +41,139,63,156,225,191,37,109,164,120,128,28,73,78,22,101,236,200,73,212,101,89,232,123,173,186,160,215,86,240,254,28,54,250,90,55,245,249,108,31,162,209,117,26,31,246,128,207,133,78,164,111,126,101,58,2,87,21,142,192,44,221,19,123,155,102,241,17,86,91, +69,192,213,130,102,175,107,250,27,155,167,81,115,234,253,127,249,98,106,47,160,131,160,146,115,216,60,135,58,74,199,250,72,195,52,162,44,109,26,141,145,38,31,102,66,130,166,65,188,45,254,190,117,22,109,89,10,54,164,21,180,247,243,77,136,174,227,212,251, +255,36,80,158,15,194,117,20,6,136,11,88,35,94,166,172,189,72,177,127,21,183,139,215,48,33,94,199,113,241,6,38,197,155,120,88,188,133,147,226,109,92,18,151,240,158,120,7,255,17,239,82,44,254,238,57,188,139,220,127,156,114,118,152,178,162,20,247,96,19, +110,197,65,146,253,30,5,225,51,94,134,255,131,42,197,199,145,243,131,192,116,209,24,248,89,220,6,81,9,170,71,45,8,177,77,178,36,14,98,180,177,169,185,58,84,93,54,3,113,102,65,152,31,241,180,238,241,233,50,89,169,224,16,213,183,240,160,88,80,97,10,226, +65,133,41,208,131,10,83,112,135,87,97,12,141,96,212,235,7,134,167,225,48,62,234,37,89,57,182,225,24,174,133,140,143,211,247,19,33,254,27,236,24,101,125,9,110,167,47,42,195,88,79,223,175,129,255,105,59,134,199,66,242,255,0,80,75,3,4,10,0,0,8,8,0,10,178, +149,71,28,107,22,177,205,2,0,0,219,6,0,0,55,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,79,112,116,105,111,110,67,111,109,112,97,114,97,116,111,114,46,99,108,97,115,115, +149,85,109,79,211,80,20,126,110,215,209,81,58,24,111,83,240,5,68,12,27,111,101,128,32,12,17,156,98,22,23,48,153,33,241,99,25,205,44,233,90,210,118,196,159,225,15,225,139,95,192,72,98,248,236,143,34,158,219,54,115,176,74,225,67,123,207,61,231,57,207,185, +247,188,180,127,174,126,253,6,80,192,142,140,52,230,100,244,242,87,15,230,37,44,200,16,177,40,99,9,203,18,94,74,88,145,145,226,251,20,94,73,88,227,240,117,9,69,9,27,18,94,51,116,109,24,150,225,109,50,36,114,249,125,6,177,100,31,234,12,125,21,195,210, +119,155,141,3,221,249,172,29,152,164,25,168,216,53,205,220,215,28,131,239,67,165,232,125,53,92,134,204,222,177,103,216,86,201,110,28,107,142,230,217,14,131,82,182,44,221,41,153,154,235,234,132,88,170,216,78,93,173,59,218,161,169,171,53,211,80,9,219,208, +172,67,30,230,147,230,184,186,51,121,147,163,200,32,213,252,29,5,250,144,187,133,32,240,44,198,35,242,101,226,180,125,185,192,48,17,239,208,130,47,210,93,27,6,247,26,168,28,105,39,154,106,106,86,93,173,122,142,97,213,139,129,141,32,83,185,54,227,222, +193,145,94,243,138,157,26,126,10,225,219,194,117,170,208,198,45,5,9,84,14,248,116,177,89,43,20,121,213,38,239,2,100,232,174,26,117,75,243,154,60,163,149,255,29,181,233,25,166,250,175,12,27,241,89,218,36,106,185,106,55,157,154,190,99,240,182,200,118,132, +159,231,212,10,50,232,87,240,6,91,18,182,25,86,239,216,18,65,150,219,155,43,27,109,224,252,83,18,222,42,40,225,29,117,229,205,66,49,108,197,134,44,105,174,94,182,92,221,114,13,207,56,209,59,99,143,197,32,20,140,224,61,195,120,92,214,56,110,148,161,112, +239,185,184,118,177,160,114,12,67,81,165,163,22,143,111,11,42,93,93,247,130,32,52,168,253,185,124,91,27,84,117,222,146,183,220,37,96,97,24,110,143,111,154,116,166,128,46,65,131,65,105,207,85,162,236,209,13,87,204,71,141,197,181,209,10,231,174,83,147, +47,99,129,190,111,189,52,60,125,244,117,20,33,240,150,163,221,0,237,84,90,105,174,144,156,62,135,240,131,4,1,131,244,238,226,74,118,133,33,146,149,0,128,97,60,4,159,64,42,81,232,252,157,200,146,180,174,204,156,33,113,1,241,11,59,71,242,39,186,46,33,237, +206,118,168,214,197,11,164,248,190,123,110,68,60,131,124,218,138,214,139,4,23,49,40,208,157,4,193,143,186,28,48,135,81,185,244,8,143,253,147,172,224,9,73,220,243,57,158,98,140,124,167,232,98,227,36,137,153,109,58,221,179,240,116,31,201,66,188,72,79,207, +92,162,103,150,158,51,40,167,145,87,28,15,128,173,96,105,76,16,57,243,165,73,146,132,12,248,24,133,196,107,180,10,97,206,88,116,206,178,1,160,69,152,36,194,28,217,19,200,251,248,105,204,248,235,44,30,208,58,65,121,76,83,41,178,148,217,23,180,34,147,34, +141,74,63,178,81,250,65,169,88,197,232,95,80,75,3,4,10,0,0,8,8,0,10,178,149,71,228,98,213,39,225,2,0,0,110,7,0,0,63,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,85,110, +107,110,111,119,110,79,112,116,105,111,110,80,97,114,115,101,114,83,116,97,116,101,46,99,108,97,115,115,189,85,203,82,19,65,20,61,61,201,36,97,50,64,8,16,241,133,136,40,201,16,8,225,161,34,136,34,165,165,85,20,90,133,178,96,215,36,83,227,232,100,134, +154,76,148,95,240,95,92,72,21,143,42,23,126,128,255,224,198,215,194,141,27,55,186,176,188,61,153,10,17,66,37,113,225,230,222,238,219,247,156,190,125,238,205,228,253,239,183,239,0,228,113,91,65,12,227,10,58,48,209,65,171,156,48,147,194,228,197,193,148, +130,105,204,68,113,53,138,107,12,114,217,227,158,30,197,28,67,252,17,119,203,186,187,38,2,12,234,3,219,214,221,101,139,151,203,122,153,97,98,197,113,141,156,225,242,162,165,231,10,150,153,91,118,74,37,110,23,87,76,91,175,226,70,234,224,243,12,33,238, +26,12,201,149,103,252,5,207,89,220,54,114,107,158,107,218,6,29,197,11,135,88,134,225,163,204,62,79,177,142,159,32,145,5,211,54,189,69,6,61,125,156,177,57,65,123,197,103,214,25,194,203,78,145,138,235,22,41,171,149,210,166,238,62,230,155,150,46,94,228, +20,184,181,206,93,83,236,131,96,216,123,106,146,72,3,79,236,231,182,243,210,126,184,229,153,142,253,151,156,45,148,112,18,152,158,223,101,232,222,125,94,94,114,141,74,73,183,61,82,55,157,217,160,176,99,83,134,235,173,234,219,222,146,144,123,50,157,105, +183,79,138,99,31,210,222,105,160,110,219,140,49,94,227,35,114,202,222,178,116,49,98,55,24,192,240,234,63,52,176,121,118,222,111,178,180,61,41,76,94,152,41,97,166,25,70,90,1,211,203,214,156,138,91,208,239,153,162,253,169,99,57,19,226,141,42,122,209,39, +204,188,138,110,36,84,244,32,169,66,65,151,138,97,12,70,177,160,226,38,22,163,184,197,48,247,207,211,193,48,213,20,219,0,212,211,32,150,109,71,100,250,225,54,23,138,97,52,221,106,51,134,154,13,1,67,39,47,22,239,110,123,46,95,231,86,133,246,253,141,198, +181,1,213,177,43,49,68,31,194,14,250,88,134,144,20,13,161,85,82,180,200,247,212,37,242,17,72,162,125,52,177,253,180,43,209,46,76,190,95,99,7,144,180,177,61,132,180,236,30,194,218,248,30,228,29,58,144,144,34,155,130,76,51,254,17,50,251,4,133,125,70,55, +251,130,62,246,21,167,232,76,171,18,96,0,103,0,127,37,46,100,254,74,92,41,249,43,81,76,136,162,103,113,46,184,58,75,94,100,73,225,215,181,123,34,34,194,190,249,188,106,245,52,224,101,56,143,193,0,153,11,144,178,182,143,200,155,35,224,239,117,96,185,6, +190,64,202,84,193,115,228,165,147,192,63,124,112,170,154,80,123,145,140,139,254,139,152,24,239,128,102,145,114,196,21,9,109,151,212,218,69,104,31,81,114,242,33,163,34,88,216,79,196,217,175,186,146,18,85,86,234,72,47,46,7,92,27,164,32,233,139,152,54,150, +29,63,0,219,57,82,213,7,31,63,83,205,169,85,21,195,149,64,231,24,70,3,157,99,72,251,58,139,85,198,239,140,132,49,159,45,139,78,242,195,20,137,99,22,106,88,252,99,206,226,52,85,121,137,60,18,98,108,102,113,61,172,252,1,80,75,3,4,10,0,0,8,8,0,10,178,149, +71,34,122,201,90,146,5,0,0,153,13,0,0,38,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,79,112,116,105,111,110,46,99,108,97,115,115,157,86,91,115,211,86,16,254,148,24,203,177,69,18,12,196,225,30, +32,128,99,19,220,22,2,148,164,80,8,183,64,72,128,164,73,67,160,69,177,85,71,84,145,92,89,230,210,251,189,253,11,188,244,173,229,165,15,180,83,194,164,204,116,250,196,67,103,250,39,250,67,218,126,71,86,100,217,178,75,166,147,137,206,158,213,158,221,111, +119,191,61,242,31,127,255,250,27,128,151,241,109,28,59,48,37,99,58,142,54,76,117,96,59,222,232,192,12,102,133,244,166,120,204,37,112,3,243,9,220,196,45,241,120,75,198,219,9,220,134,42,99,65,70,62,142,206,234,169,130,144,52,33,189,35,164,162,120,44,198, +160,199,112,71,40,223,141,193,16,170,37,113,214,20,15,75,70,73,198,123,18,100,171,228,232,150,89,150,208,53,126,71,189,171,230,42,142,110,228,166,52,103,88,66,199,148,94,52,85,167,98,107,18,246,214,191,29,169,110,13,213,44,230,166,28,91,55,139,195,39, +121,66,81,237,98,101,73,51,157,233,7,37,30,218,16,176,26,53,212,114,153,38,155,26,117,35,25,113,50,81,208,202,121,91,119,193,72,72,134,221,83,89,208,74,182,150,87,133,201,172,106,155,212,74,136,235,102,190,178,64,157,216,72,55,8,186,104,91,149,210,172, +238,44,74,56,220,8,218,178,139,185,162,173,22,12,45,151,55,244,220,168,181,180,164,154,133,113,221,212,38,221,200,110,18,209,17,221,212,157,147,18,82,233,0,140,49,71,179,213,5,67,27,30,152,145,16,25,181,10,154,40,25,79,78,84,150,22,52,123,90,188,19,192, +173,188,106,204,168,182,46,246,158,50,106,121,105,181,233,253,126,1,92,80,174,83,199,178,25,53,226,44,234,236,194,158,23,99,172,175,161,143,75,66,79,125,112,182,192,3,208,44,143,22,29,204,174,217,86,212,33,94,212,156,201,85,2,109,72,15,132,40,180,175, +81,215,34,108,98,81,45,159,246,184,35,97,40,29,34,206,192,90,234,114,60,116,78,144,107,77,71,251,211,107,50,83,2,56,153,114,39,243,63,27,36,238,166,213,124,235,169,27,181,181,114,197,96,102,91,66,111,207,84,116,163,160,9,6,116,210,119,157,179,163,233, +176,175,53,161,76,18,214,105,195,176,238,5,177,182,167,7,56,30,91,253,87,87,8,72,47,25,90,192,36,190,58,97,90,65,194,102,55,183,240,196,41,212,95,168,205,216,80,184,195,107,154,178,100,186,129,44,130,79,71,211,255,195,151,75,196,41,171,98,231,181,243, +186,160,123,79,200,234,144,240,170,224,32,108,210,180,22,225,162,90,94,100,20,5,59,177,75,70,89,129,131,189,10,246,136,71,70,104,42,10,238,226,158,140,251,10,30,96,76,193,251,248,64,66,119,99,79,100,124,168,224,35,124,204,14,214,92,143,235,101,182,59, +213,162,219,10,246,97,191,130,79,240,169,130,3,66,250,12,159,139,237,23,244,49,95,107,66,223,96,31,47,181,91,10,210,24,96,225,231,107,119,29,117,95,98,84,193,87,248,90,193,55,34,118,223,139,42,85,135,124,114,225,142,150,119,92,82,204,172,226,118,95,204, +88,58,123,31,153,158,187,122,142,61,10,95,5,18,98,186,119,105,177,208,117,189,15,92,102,201,176,150,159,26,242,123,66,187,207,168,17,211,93,234,135,165,10,137,135,215,215,81,128,24,213,130,160,99,58,108,43,8,29,85,75,37,205,164,193,96,211,105,105,61, +110,81,67,51,139,130,193,172,193,152,132,237,233,209,255,178,142,57,86,85,37,34,22,10,28,33,14,115,144,173,163,150,97,16,147,160,164,11,203,214,150,172,187,26,118,243,243,187,131,223,250,40,146,130,101,96,163,184,107,163,190,77,16,205,223,247,243,159, +156,112,229,3,222,202,174,115,77,10,46,250,118,89,126,198,37,18,121,144,242,33,106,126,71,59,34,92,47,101,158,66,202,60,67,219,220,83,180,63,65,36,243,51,214,61,65,180,166,145,179,43,136,73,184,114,112,5,29,18,30,98,27,133,184,196,243,137,137,204,47, +136,12,174,64,105,195,236,163,127,254,250,137,222,218,145,227,115,15,98,124,238,164,255,20,186,208,139,30,230,178,155,88,134,137,229,60,165,49,90,188,68,139,12,45,134,145,224,239,153,253,60,153,230,155,87,112,152,248,136,10,71,48,4,184,210,78,28,37,242, +99,148,21,174,85,205,113,63,175,87,41,157,160,151,106,86,57,238,132,205,58,1,237,177,107,144,115,139,40,148,251,220,160,85,39,235,188,0,85,39,35,212,189,134,147,158,147,107,92,5,8,57,147,21,149,120,236,231,21,119,213,3,60,156,113,93,245,84,205,124,172, +178,215,153,26,86,161,233,247,177,158,114,195,188,206,167,8,115,140,26,97,211,145,217,136,196,106,160,182,64,160,67,60,158,11,96,238,240,2,73,56,221,212,201,250,102,78,14,187,248,154,57,57,131,81,207,201,159,94,194,218,51,116,178,233,93,227,172,94,247, +115,40,89,177,46,99,195,44,215,228,115,164,179,203,216,248,29,226,217,238,190,101,108,154,205,38,55,139,119,194,40,233,10,201,30,207,54,245,16,189,141,182,189,174,201,50,182,212,0,158,32,37,193,86,198,216,196,46,238,122,217,135,93,44,208,126,118,98,144, +25,30,97,158,175,17,230,89,254,93,198,57,92,39,121,230,112,145,191,66,47,5,202,175,121,9,197,112,139,118,231,92,2,156,199,5,47,181,83,193,94,118,135,170,51,193,94,78,182,232,165,152,42,225,236,34,249,90,117,118,194,43,118,55,115,140,114,78,190,135,28, +121,132,72,251,143,13,68,155,10,212,187,219,175,247,165,230,126,216,183,31,90,248,153,109,234,231,114,243,228,146,161,228,230,153,220,205,22,201,29,240,146,75,251,76,26,242,64,201,153,200,19,164,66,206,110,211,153,26,192,35,251,120,198,125,30,5,167,47, +217,56,125,90,147,233,3,174,52,29,93,185,241,176,222,114,116,39,220,123,100,210,115,162,121,21,73,9,39,188,184,182,242,106,18,98,102,5,219,40,214,174,168,78,174,192,18,47,31,147,213,177,2,85,74,249,216,82,222,197,91,27,103,161,201,250,227,124,149,210, +53,87,186,254,47,80,75,3,4,10,0,0,8,8,0,10,178,149,71,156,108,92,207,167,1,0,0,166,3,0,0,56,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,79,112,116,105,111,110,80,97,114, +115,101,114,83,116,97,116,101,46,99,108,97,115,115,149,82,93,75,27,65,20,61,179,89,179,118,77,77,180,154,226,119,140,41,70,41,110,20,95,36,34,104,64,20,130,10,145,60,248,54,73,134,237,200,102,86,102,39,37,255,163,191,164,79,133,62,248,3,250,163,138,119, +54,1,17,11,105,118,30,206,157,187,231,158,203,61,119,254,252,253,253,12,224,16,95,124,100,176,233,195,197,166,135,146,135,109,134,236,169,84,210,156,49,100,170,123,109,6,183,17,247,4,67,190,41,149,184,25,244,59,66,223,243,78,68,153,197,102,220,229,81, +155,107,105,239,227,164,107,190,201,132,97,225,246,201,200,88,221,113,157,8,221,50,220,208,175,220,181,82,66,55,34,158,36,130,40,199,205,88,135,65,168,121,47,18,65,55,146,65,35,238,247,185,234,217,62,163,186,202,59,145,58,195,124,172,40,212,230,70,12, +205,185,14,61,148,25,230,222,244,169,85,247,38,75,191,21,245,99,69,90,131,190,80,134,225,162,218,124,228,223,121,16,113,21,6,45,163,165,10,235,83,43,206,135,194,92,241,228,85,149,204,124,72,27,81,229,83,36,140,240,176,195,0,134,221,234,100,237,195,186, +221,132,51,172,49,84,254,135,77,141,90,241,64,119,197,165,180,75,41,190,227,28,216,9,115,152,65,214,67,133,225,104,250,85,48,20,94,93,186,237,60,138,46,13,249,117,26,151,24,202,147,71,97,40,77,34,185,37,122,194,46,236,151,133,99,103,34,87,61,186,5,132, +100,49,102,246,127,193,249,73,129,131,217,148,100,125,255,129,15,20,231,70,4,248,248,8,184,180,54,44,164,184,136,79,41,46,97,57,197,162,205,23,44,115,101,44,126,66,232,140,197,217,191,197,139,35,194,72,60,141,86,177,150,150,173,167,252,13,106,15,202, +101,232,108,97,206,245,145,39,44,16,126,38,68,97,246,5,80,75,3,4,10,0,0,8,8,0,10,178,149,71,91,120,110,152,148,7,0,0,199,17,0,0,38,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,80,97,114,115,101,100,67,111,109,109,97,110,100,76,105,110, +101,46,99,108,97,115,115,149,87,217,127,27,87,21,254,70,219,200,210,68,177,85,199,142,221,38,85,211,56,150,101,57,134,36,208,120,169,139,227,38,77,28,219,41,113,73,112,90,10,19,107,34,79,144,103,148,209,200,137,91,74,75,161,208,133,165,165,5,154,150, +125,51,139,129,164,52,9,38,63,150,55,248,241,206,27,111,188,240,87,16,190,59,51,26,75,214,184,49,47,51,231,222,57,247,59,231,124,103,185,210,63,254,251,199,63,3,248,48,222,79,160,19,134,12,51,129,16,140,22,228,81,150,113,41,129,168,187,176,196,163,34, +195,78,160,197,221,169,38,177,132,203,73,92,193,178,120,60,35,227,89,25,159,75,160,21,70,2,219,241,92,18,159,199,101,25,207,39,241,2,190,16,199,139,50,190,152,224,177,47,37,208,142,151,100,124,57,129,110,24,113,124,69,188,95,142,227,21,241,126,85,104, +188,38,78,126,53,137,175,225,178,88,126,93,0,124,67,198,235,113,188,145,64,15,190,153,196,155,120,75,232,124,75,60,190,45,30,111,201,248,142,132,237,102,217,214,77,163,114,100,121,214,182,116,163,200,157,169,139,234,146,58,88,181,245,210,224,180,90,30, +145,208,50,171,23,13,213,174,90,154,132,147,141,95,71,221,101,73,53,138,131,46,192,200,148,105,21,7,139,150,90,40,105,131,243,37,125,240,113,213,170,104,133,9,115,113,81,53,10,83,186,161,157,114,44,142,140,17,57,85,182,180,138,102,216,238,86,165,209, +248,172,102,83,229,193,198,157,0,131,14,144,165,45,154,75,90,193,7,74,105,87,108,75,29,183,138,213,69,226,115,163,181,14,103,74,175,8,232,189,27,182,54,193,142,141,234,134,110,143,73,232,204,214,41,156,176,53,75,61,95,210,70,250,206,72,136,76,152,5,77, +120,207,240,102,170,139,231,53,235,9,241,77,66,122,202,156,87,75,103,84,75,23,107,111,179,197,229,156,38,132,66,147,77,9,33,125,175,132,246,58,239,28,99,182,105,241,155,82,118,248,116,3,149,144,221,42,221,140,195,244,206,236,217,120,38,72,59,98,47,232, +149,0,221,38,124,234,202,102,141,246,246,32,134,36,116,52,210,176,92,174,81,113,56,64,127,244,238,238,137,180,140,4,101,99,75,103,69,198,226,182,89,43,248,246,108,95,80,18,148,75,85,211,214,198,141,194,164,169,11,162,131,147,31,116,50,86,241,144,101, +87,168,8,238,171,118,185,106,75,232,106,58,112,164,170,151,10,154,72,173,172,87,142,233,86,133,90,210,57,145,217,160,240,2,43,116,116,203,186,129,254,182,44,168,149,90,61,237,200,54,107,244,209,155,214,5,213,171,185,211,110,167,145,32,30,27,55,150,107, +39,187,178,117,5,59,97,150,74,218,188,195,183,56,189,189,100,22,167,180,37,173,228,247,103,71,176,178,132,92,224,135,77,2,31,8,182,25,28,250,185,13,68,213,162,219,122,7,181,21,53,251,232,134,185,146,174,85,79,253,100,217,215,180,185,73,0,219,212,66,193, +65,60,163,150,170,218,38,244,179,92,163,75,238,247,22,234,215,8,127,58,64,247,238,229,255,127,132,171,184,67,181,102,175,167,105,214,4,160,211,215,196,172,89,181,230,181,99,186,104,240,142,38,248,253,194,105,5,135,241,54,9,93,39,233,184,90,89,224,133, +162,96,0,251,155,62,112,240,43,188,111,15,40,56,132,3,18,238,89,255,58,110,89,234,178,32,88,193,71,240,81,25,87,21,188,131,119,101,124,87,193,247,240,125,5,63,192,15,37,100,238,230,55,51,182,53,86,20,252,8,63,150,241,19,54,196,70,238,101,252,84,193,207, +240,115,9,7,189,113,56,156,233,169,228,51,141,23,145,187,215,120,91,137,189,6,192,83,231,47,178,144,21,204,224,148,130,21,252,130,87,207,38,83,131,119,69,62,163,224,151,248,21,135,70,175,130,41,76,43,152,0,249,253,53,86,101,252,70,193,39,49,167,224,183, +248,29,71,121,221,140,96,167,20,213,82,205,171,163,87,230,53,143,135,157,174,79,153,222,158,74,111,198,48,237,76,65,187,192,232,11,251,69,198,46,200,184,166,224,58,86,21,188,135,167,20,252,30,171,205,228,54,49,39,33,156,21,117,145,110,158,81,156,195, +186,119,181,177,84,26,154,166,238,202,75,55,239,114,88,114,250,204,144,91,7,157,173,29,49,156,69,227,48,119,137,36,68,130,157,235,207,158,182,6,67,238,207,140,109,13,27,13,107,86,37,141,56,211,251,112,182,25,188,121,39,208,131,216,5,211,90,84,137,49, +20,208,182,79,126,48,200,250,205,162,150,203,154,81,88,31,124,141,131,108,243,171,37,62,111,26,182,170,139,232,119,4,196,32,8,108,15,154,164,12,188,40,232,216,23,116,40,40,204,84,227,216,227,121,78,44,225,120,161,48,94,42,81,112,75,31,15,240,87,106,39, +127,68,71,144,22,29,15,9,131,92,133,240,33,174,217,232,254,250,32,215,135,54,172,217,232,254,250,33,36,249,62,140,33,202,195,128,52,128,48,100,238,188,146,187,5,41,119,27,161,185,91,8,223,64,132,98,148,98,236,6,228,117,49,78,177,133,98,226,6,146,253, +107,80,36,76,231,215,176,77,194,85,156,164,144,146,240,87,108,159,185,141,86,234,180,13,71,6,110,34,189,134,123,36,12,71,187,162,158,94,70,72,142,98,251,112,44,247,62,34,93,177,174,200,26,118,132,113,118,229,206,191,86,238,188,119,157,206,132,49,194, +231,1,40,124,118,51,228,29,252,173,223,65,169,147,63,205,119,50,228,123,49,137,251,48,139,93,176,177,27,47,226,126,188,132,12,94,38,73,163,60,113,156,1,217,72,225,97,140,33,134,167,209,139,71,240,49,254,199,152,37,226,56,142,16,111,146,248,19,120,148, +118,30,194,199,157,175,33,65,1,142,226,24,224,72,143,17,69,194,9,202,10,223,238,206,164,79,226,73,74,156,28,124,146,66,124,130,86,132,78,127,186,35,246,39,116,206,133,115,140,75,190,133,157,179,115,17,33,38,29,49,42,196,184,16,255,128,174,107,14,140, +8,210,61,218,227,56,238,154,234,247,220,8,137,113,230,102,9,255,225,59,198,247,233,219,232,38,183,247,78,71,198,92,254,135,35,130,61,135,217,67,66,242,152,141,238,122,7,137,124,250,190,155,216,117,54,159,222,237,188,186,162,117,171,240,216,202,157,191, +231,111,226,254,107,62,221,251,157,202,232,67,28,57,36,232,69,150,21,151,103,173,29,100,208,195,36,125,156,117,118,156,20,78,114,103,154,53,38,60,22,4,103,177,7,143,83,138,178,210,70,28,50,35,194,83,159,204,211,164,88,144,25,231,201,211,76,66,136,232, +199,241,4,105,11,215,17,44,180,206,248,4,159,165,196,65,236,17,124,130,59,34,65,109,185,254,155,200,156,21,236,50,250,7,66,88,245,105,76,56,10,194,157,71,28,199,58,220,3,190,19,109,204,247,24,225,36,156,251,0,216,120,48,236,36,97,79,222,5,246,73,60,229, +229,234,77,190,5,3,125,4,219,83,215,33,221,181,14,105,159,201,177,51,30,188,138,104,100,117,229,206,191,195,171,126,10,58,72,162,168,167,110,82,177,135,36,236,165,175,189,244,88,152,206,17,180,155,14,9,131,162,101,51,126,221,246,249,238,244,225,83,172, +247,250,186,21,59,159,246,105,253,12,37,94,118,94,252,21,162,132,133,142,104,67,58,187,55,68,231,90,167,243,127,195,206,219,232,153,75,239,139,56,213,220,47,10,246,22,122,255,146,95,175,218,180,19,97,129,77,166,81,190,64,39,23,28,39,51,46,96,157,67,46, +63,41,182,172,104,189,16,229,243,152,247,152,26,116,152,3,162,162,73,54,182,68,169,174,37,162,30,160,27,69,129,79,141,70,221,40,30,245,178,168,8,16,70,145,101,245,92,223,144,192,50,75,251,82,93,2,21,223,65,5,69,199,65,48,0,221,67,52,188,4,238,110,224, +101,70,148,93,222,153,104,125,52,49,176,238,111,202,9,90,76,156,42,167,210,146,159,45,34,248,118,118,59,211,72,114,164,9,199,231,20,90,29,74,196,217,139,248,172,103,251,13,207,246,80,127,109,118,250,245,147,173,171,31,186,50,176,134,92,136,219,41,81, +183,92,244,135,196,4,253,231,122,232,110,49,61,195,33,249,44,221,121,142,183,192,243,156,251,47,248,238,237,226,40,125,216,41,166,4,123,191,86,76,67,190,203,67,142,163,34,67,37,7,115,241,127,80,75,3,4,10,0,0,8,8,0,10,178,149,71,139,65,53,108,124,1,0, +0,11,3,0,0,58,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,80,114,111,106,101,99,116,80,114,111,112,101,114,116,105,101,115,67,111,109,109,97,110,100,76,105,110,101,67,111,110,118,101,114,116,101,114,46,99,108,97,115,115,157,146,75,79, +194,64,20,133,207,5,4,68,124,63,80,195,162,236,192,4,26,19,117,227,35,81,140,43,162,36,24,247,67,59,150,49,109,135,12,3,9,255,74,87,38,46,252,1,254,40,227,20,170,49,216,68,227,44,238,233,156,57,223,244,118,166,111,239,47,175,0,246,177,91,64,22,27,121, +108,230,177,149,71,41,135,237,28,118,8,217,19,17,10,125,70,72,87,107,119,132,76,83,186,156,176,220,18,33,191,30,6,93,174,110,89,215,55,206,90,75,58,204,191,99,74,68,243,216,204,232,158,24,16,142,90,82,121,182,167,152,235,115,219,241,133,221,86,242,129, +59,218,72,159,43,45,248,160,41,131,128,133,110,180,107,83,134,35,99,114,117,76,88,245,248,103,104,124,211,215,66,134,132,141,106,173,245,192,70,204,246,89,232,217,29,173,68,232,153,232,206,143,232,37,215,76,248,220,37,148,19,214,6,142,18,241,142,133, +142,28,42,135,95,137,168,229,189,63,245,214,136,58,40,34,135,60,129,218,132,98,127,74,213,141,246,9,23,29,174,173,216,138,116,242,102,235,94,42,75,247,184,213,29,10,223,181,166,13,88,85,222,240,26,86,189,29,140,163,220,105,48,30,49,127,200,107,13,194, +193,127,14,141,112,56,131,157,119,7,90,177,223,56,84,48,103,238,63,26,25,80,244,97,166,206,155,153,109,148,140,206,237,61,131,158,204,67,10,5,83,179,19,115,29,11,166,22,167,1,163,139,19,124,9,203,49,92,143,225,244,90,234,113,6,45,125,67,211,95,232,74, +2,154,158,69,203,137,232,106,2,154,153,69,43,9,168,249,119,39,169,245,15,80,75,3,4,10,0,0,8,8,0,10,178,149,71,50,108,87,182,74,2,0,0,4,5,0,0,70,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97, +114,115,101,114,36,67,97,115,101,73,110,115,101,110,115,105,116,105,118,101,83,116,114,105,110,103,67,111,109,112,97,114,97,116,111,114,46,99,108,97,115,115,165,83,93,111,18,65,20,61,51,124,44,224,98,145,182,248,89,197,138,150,47,187,165,250,98,32,141, +74,98,66,36,106,66,211,247,1,6,156,102,217,109,118,151,198,191,226,127,224,197,151,154,248,96,124,246,71,25,239,44,27,76,11,6,19,67,152,123,231,206,185,231,206,61,119,246,231,175,111,223,1,52,240,60,3,3,79,50,72,233,37,129,61,189,148,13,84,116,184,106, +160,110,224,169,129,125,134,100,75,57,42,56,98,136,149,43,39,12,241,182,59,148,12,27,93,229,200,119,211,73,95,122,199,162,111,83,36,223,117,7,194,62,17,158,210,251,40,24,15,62,42,159,225,65,91,248,178,227,248,210,241,85,160,206,101,47,240,148,51,110, +187,147,51,225,137,192,245,24,204,142,227,72,175,109,11,223,151,148,240,186,235,122,99,107,236,137,161,45,173,129,173,44,194,78,132,51,212,85,63,8,207,151,94,105,13,101,147,193,24,132,59,186,198,94,185,123,42,206,133,101,11,103,108,205,145,205,229,72, +165,67,57,238,89,160,92,167,161,251,89,2,44,142,15,169,179,161,26,141,24,88,231,10,251,251,254,169,28,4,205,229,136,102,231,159,14,46,19,71,103,250,164,97,192,98,64,72,183,182,249,70,83,207,162,244,47,64,134,116,79,141,29,17,76,181,18,173,191,93,117, +26,40,219,250,35,95,107,185,251,35,162,202,244,220,169,55,144,111,148,30,110,97,169,220,190,78,50,145,193,53,19,7,104,152,56,4,41,153,187,74,101,98,19,91,6,158,49,188,252,223,49,95,98,159,55,196,176,181,170,35,134,221,245,106,49,108,70,143,230,216,237, +140,29,215,147,186,62,195,246,138,7,164,7,154,94,160,25,138,235,232,73,18,131,62,55,202,162,15,48,14,174,117,162,157,73,59,139,44,13,31,137,234,87,240,47,228,112,100,105,77,234,32,79,226,58,249,230,28,128,13,228,161,159,9,73,24,37,143,8,29,39,155,175, +213,47,16,59,218,249,140,196,206,76,251,241,217,130,41,175,17,60,133,36,79,35,195,51,48,185,25,178,86,231,153,17,171,246,182,81,8,43,229,113,147,60,78,119,48,113,11,183,17,203,189,162,154,119,162,154,111,17,163,31,144,173,214,126,32,81,167,255,5,146, +179,149,23,47,206,129,139,18,89,220,197,189,176,68,22,59,228,241,28,72,137,98,68,252,130,44,143,148,96,171,149,40,204,1,11,194,4,17,62,164,243,24,118,67,252,35,148,66,251,24,55,194,62,56,201,94,67,142,238,126,159,44,114,169,223,80,75,3,4,10,0,0,8,8,0, +10,178,149,71,133,165,180,23,103,18,0,0,198,42,0,0,38,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,46,99,108,97,115,115,157,89,11,120,84,213,181,94,43,243,56,147,147,3,36, +145,0,131,60,34,15,201,99,146,0,66,128,240,50,68,84,148,4,48,8,134,135,120,72,78,146,129,201,76,152,153,0,81,168,162,212,42,245,81,171,162,96,125,87,169,173,86,69,73,136,81,172,173,239,98,109,171,125,221,62,108,239,237,245,222,91,219,123,111,123,219, +122,107,91,233,191,246,153,153,204,76,14,38,246,227,227,236,61,123,175,189,214,218,235,241,239,181,119,222,252,248,185,19,68,52,139,79,230,210,14,250,127,249,252,69,62,31,201,231,175,26,253,45,151,254,78,31,235,228,161,83,58,237,96,210,169,137,89,227, +28,157,116,105,93,58,25,236,214,217,195,94,153,214,52,246,105,156,155,199,58,231,233,84,192,134,78,249,60,66,227,145,58,21,241,168,60,206,231,130,60,46,228,51,228,51,90,227,34,157,14,240,24,31,143,213,105,60,143,211,216,175,211,36,30,239,227,51,229,247, +4,249,76,20,138,73,58,93,195,147,125,92,44,35,103,201,103,138,140,76,245,241,52,104,201,211,125,124,182,198,51,116,10,48,139,228,18,141,75,117,170,98,246,113,153,180,229,242,9,200,138,10,249,84,10,131,42,225,59,83,62,179,68,79,181,110,118,30,159,195, +115,228,83,160,241,92,157,22,115,181,198,243,116,90,202,243,53,94,160,113,141,78,203,120,161,78,181,188,72,136,22,107,188,68,167,243,197,10,75,117,186,80,102,22,243,185,26,215,234,116,177,48,92,198,115,124,92,39,86,57,79,102,150,251,104,167,72,57,95, +62,23,232,124,33,175,144,222,69,26,95,156,71,235,120,165,143,235,53,110,144,238,42,17,185,218,199,107,68,239,75,124,220,40,191,215,106,124,169,78,87,8,227,117,92,32,189,245,226,138,128,244,2,26,95,230,227,38,217,215,6,157,90,121,163,244,54,249,120,179, +88,231,114,157,183,240,21,58,155,188,213,199,205,162,9,252,209,162,179,197,173,62,110,147,201,118,141,131,76,196,100,172,8,135,173,104,93,200,140,197,172,24,211,152,85,157,241,96,36,220,24,143,6,195,109,117,145,142,78,51,106,198,35,81,141,183,49,77,174, +51,99,214,138,112,204,10,199,130,241,224,78,43,155,136,41,223,94,157,190,110,59,211,184,75,195,219,195,145,93,97,123,114,181,25,141,89,209,198,184,25,183,52,14,65,226,197,167,153,235,96,42,112,24,14,51,21,213,7,99,49,136,182,103,107,163,109,106,10,123, +169,109,141,91,81,123,52,166,113,132,105,180,26,57,63,24,141,197,27,187,182,66,175,14,51,220,2,6,203,172,214,72,212,202,26,215,184,51,101,128,218,93,102,212,202,144,139,60,200,203,24,192,126,141,116,107,49,157,177,106,245,218,21,171,26,182,52,212,214, +47,223,178,186,118,237,218,229,151,52,48,249,87,110,51,119,154,85,93,241,96,168,42,106,181,89,187,171,86,155,113,104,21,94,200,52,42,98,43,187,172,59,201,99,84,26,117,189,217,9,154,220,198,96,91,216,140,119,69,177,195,229,153,179,139,236,159,33,51,220, +86,101,51,88,184,50,18,109,171,106,139,154,45,33,171,170,57,20,172,74,236,109,101,48,108,217,202,46,92,2,158,5,102,40,20,217,85,31,220,109,181,36,204,197,196,27,176,3,53,158,225,47,204,20,182,88,157,81,171,217,84,190,128,20,40,15,27,218,178,131,145,42, +53,180,62,26,196,48,88,159,49,77,66,41,170,150,158,23,140,153,91,67,22,44,238,93,20,12,7,227,75,152,92,37,165,235,152,220,117,145,22,75,54,11,181,26,186,58,182,90,209,181,66,8,81,43,35,205,102,104,157,25,13,202,239,196,160,59,222,30,132,26,83,62,97,111, +182,103,68,124,73,74,175,132,74,34,47,63,123,144,201,211,41,75,152,230,149,108,28,108,197,210,108,81,138,127,75,154,64,112,200,107,30,248,9,193,14,108,0,157,203,119,55,91,201,128,196,30,230,151,164,81,173,128,38,178,195,225,137,51,148,194,9,127,49,205, +25,210,26,211,6,101,15,184,120,173,112,11,50,6,238,94,129,208,138,36,227,87,44,239,160,190,128,132,102,19,205,194,218,72,66,182,203,20,14,57,193,105,200,176,180,136,84,251,65,214,47,76,13,103,110,19,113,215,153,189,49,7,183,58,109,94,87,11,19,121,94, +57,244,214,51,55,61,38,51,170,186,59,147,145,229,228,13,135,164,146,148,89,57,108,218,97,121,115,242,64,6,2,129,18,145,20,171,13,15,228,227,180,146,65,140,156,2,94,87,140,86,33,189,91,135,27,204,78,108,220,102,52,10,119,186,67,86,24,77,65,115,54,108, +124,114,250,37,160,37,21,44,2,26,131,88,196,50,209,173,209,138,99,193,57,153,35,139,134,135,95,122,167,96,206,165,49,179,13,78,244,167,123,166,182,179,19,17,110,103,21,18,223,136,100,32,244,232,72,180,197,138,38,147,200,30,21,181,0,111,173,202,21,201, +145,252,52,181,86,6,99,162,169,107,187,213,13,216,216,105,134,186,32,212,99,133,227,81,249,189,220,110,139,50,145,121,154,26,150,85,145,174,184,4,160,163,134,200,64,156,67,29,234,56,200,100,113,126,114,24,52,35,51,148,134,114,158,16,172,129,214,213,97, +238,102,154,154,109,65,199,240,157,150,181,161,211,144,45,116,218,134,211,49,227,184,122,238,208,199,147,227,58,247,182,72,16,17,182,168,36,109,125,93,36,20,178,154,149,199,157,66,218,1,172,60,56,38,196,201,233,72,182,106,235,54,48,17,220,83,147,177, +148,43,178,101,192,21,49,43,85,200,120,183,118,181,182,138,79,198,13,18,180,76,205,136,184,86,41,31,50,207,247,1,134,139,202,100,99,75,157,119,36,147,195,220,212,167,206,232,84,42,234,102,115,179,21,139,77,155,59,115,38,211,244,146,161,65,160,20,5,64, +206,238,153,3,43,231,203,202,115,134,179,114,80,209,146,100,177,64,88,228,37,126,204,82,170,44,24,62,195,65,197,133,111,17,232,237,66,66,111,140,116,69,155,81,195,9,142,143,25,196,162,82,24,24,116,23,221,109,208,65,186,211,160,47,208,109,6,221,65,119, +50,141,79,242,94,213,21,239,236,138,195,166,150,217,97,139,208,56,110,208,15,184,203,160,195,188,19,31,122,80,62,247,0,16,7,54,120,161,25,107,199,38,113,226,59,232,40,11,119,105,188,219,224,110,190,210,160,135,233,49,166,226,161,142,131,65,236,145,198, +26,95,101,240,30,222,43,12,63,35,159,171,153,170,135,60,246,28,235,90,89,125,141,198,251,12,190,150,175,211,120,191,193,159,229,235,13,254,28,223,0,156,203,142,45,131,111,228,3,136,131,138,10,131,63,207,55,49,85,12,41,52,189,234,22,89,55,227,24,168,168, +216,120,249,226,205,229,6,223,194,7,12,190,149,191,96,240,109,252,69,131,111,231,59,0,104,37,75,99,165,9,138,197,149,101,6,223,201,7,133,232,46,131,239,230,67,0,109,53,47,211,50,75,135,196,105,121,137,177,138,205,149,101,72,203,52,56,77,86,155,203,163, +209,72,212,224,195,162,244,216,193,89,27,12,181,72,66,51,246,117,15,127,201,224,123,249,62,131,239,23,67,60,192,119,24,252,32,63,100,240,195,124,200,224,47,211,61,6,63,194,143,106,124,196,224,175,8,183,108,7,14,202,54,131,31,227,175,38,3,34,19,191,37, +126,190,157,225,224,181,81,203,130,131,153,102,13,179,128,27,184,78,137,117,191,38,159,199,13,126,130,191,158,220,103,2,212,195,219,173,150,84,112,206,27,38,243,236,75,156,193,79,242,83,25,91,169,141,70,205,110,57,50,52,126,26,129,17,40,54,232,151,244, +43,131,143,138,1,159,225,103,13,62,198,79,105,220,99,208,79,185,215,224,227,89,203,83,167,136,193,125,18,113,238,233,177,233,225,140,192,179,49,218,224,231,248,6,131,251,249,121,8,153,174,188,244,2,2,41,86,92,44,11,12,62,33,105,56,198,25,141,53,126,81, +232,191,129,34,37,173,70,3,218,182,153,33,20,187,93,29,56,172,83,133,56,106,47,123,235,197,51,166,199,102,20,7,99,197,102,8,8,208,210,93,220,130,34,32,108,181,84,138,22,47,137,153,191,105,240,183,36,27,106,234,204,112,56,18,47,54,91,90,138,35,105,107, +77,172,13,39,71,154,109,154,88,220,140,198,139,119,5,227,237,197,51,42,102,84,26,116,11,221,170,241,203,6,191,194,175,106,252,154,100,196,245,76,27,135,201,177,56,18,14,117,23,55,71,194,113,51,24,134,162,157,237,102,24,219,137,6,155,139,155,219,225,177, +102,132,88,12,241,41,178,84,179,101,70,229,39,6,172,237,124,141,95,55,248,13,81,100,66,201,166,165,123,54,117,94,85,27,2,223,189,27,83,189,138,45,155,203,74,13,126,147,17,188,83,134,140,37,92,14,206,29,146,104,200,231,131,5,67,178,56,221,75,194,112,226, +221,249,157,129,105,246,167,191,71,13,7,138,79,243,70,49,119,120,112,58,232,201,98,184,249,156,253,112,193,20,248,52,151,165,225,224,125,230,163,71,249,233,233,29,82,47,253,188,233,142,197,173,142,65,15,9,246,113,188,112,160,172,207,58,168,85,89,63,122, +208,45,127,131,186,230,103,161,22,202,61,175,25,19,236,146,10,104,227,224,186,176,116,112,153,63,34,3,186,192,64,21,252,224,52,174,164,244,116,165,163,255,52,133,171,232,52,214,249,198,143,153,237,195,40,132,134,190,74,14,125,23,158,165,164,21,14,214, +2,245,84,48,113,101,7,180,102,108,47,237,42,95,56,120,20,184,220,110,198,26,172,221,113,245,160,131,186,209,29,86,63,70,151,148,58,21,223,249,29,102,247,86,185,189,71,227,201,219,100,81,137,67,89,187,65,222,39,118,116,153,161,88,22,65,210,93,32,88,49, +200,106,255,188,77,52,156,209,205,237,226,220,220,88,215,214,88,34,162,139,74,86,56,150,226,35,36,232,211,182,176,193,97,11,255,204,237,219,241,157,102,100,66,152,24,89,189,215,204,28,198,115,64,214,179,135,22,12,183,88,187,229,93,192,141,45,173,16,31, +175,112,222,154,174,32,74,37,43,211,50,39,215,124,90,217,121,137,51,43,118,177,220,154,189,166,186,244,2,93,28,121,159,166,90,147,130,63,30,73,221,221,75,28,85,31,217,102,197,81,245,12,168,175,219,21,83,200,18,52,243,134,172,112,91,188,93,133,41,12,144, +23,9,55,68,194,73,7,230,43,202,228,54,150,139,126,174,54,169,204,206,118,138,61,167,192,78,3,11,85,210,185,112,158,35,152,218,162,145,174,206,245,65,145,91,152,14,13,242,228,33,113,55,99,232,204,79,68,104,22,178,36,207,74,53,231,133,176,218,80,232,19, +224,7,233,162,99,67,169,135,131,130,140,28,183,31,96,70,102,34,160,109,208,243,172,88,115,52,152,124,237,235,148,39,140,249,14,54,25,166,149,188,219,173,110,101,158,145,3,147,245,166,88,199,35,1,9,191,248,212,107,138,162,241,65,252,58,251,141,197,139, +174,29,62,246,43,201,192,11,65,122,8,12,1,235,233,47,41,19,156,50,123,32,216,60,173,161,174,24,180,26,237,100,77,28,164,195,140,221,196,251,192,130,79,165,107,102,80,59,162,35,92,174,171,234,50,102,135,86,90,241,159,241,119,133,20,174,69,213,237,125, +128,81,29,42,198,70,224,171,21,110,182,50,108,100,47,175,183,23,45,116,224,92,159,228,55,42,141,155,252,205,8,152,210,98,197,130,81,171,37,117,15,19,4,232,194,132,214,140,112,85,183,243,79,72,122,135,191,138,208,89,180,131,154,136,200,75,227,165,120, +70,47,71,110,239,196,244,69,213,191,29,255,113,145,87,253,131,170,45,148,123,62,81,254,56,185,43,226,247,40,208,226,218,142,239,151,240,107,49,185,209,195,104,89,63,121,154,142,146,183,151,180,94,242,61,173,24,220,139,175,142,150,104,41,141,164,115,233, +62,244,12,155,156,238,167,7,136,20,171,7,19,172,54,147,71,209,78,44,235,165,92,176,211,155,122,41,239,24,185,208,53,154,202,221,189,52,226,24,241,0,227,66,72,38,90,134,239,2,176,171,163,9,116,158,18,48,198,102,146,16,32,189,187,232,33,136,216,71,15,211, +151,49,103,107,157,163,168,114,203,202,143,211,200,30,26,245,84,138,173,87,233,183,42,141,85,110,138,85,46,61,66,143,98,254,8,250,178,237,175,224,255,195,244,24,185,132,169,235,32,244,207,3,27,119,63,229,55,245,83,65,83,217,179,228,234,163,66,166,94, +58,163,151,70,215,247,83,81,83,89,128,123,105,76,67,121,31,141,197,213,199,237,119,247,209,56,166,67,124,82,122,126,166,111,208,248,26,79,133,223,211,67,103,30,226,39,252,158,194,9,61,52,241,16,229,247,211,164,38,89,58,185,225,8,223,139,225,226,30,58, +235,16,141,7,165,223,3,226,41,61,52,181,198,235,247,246,208,52,16,236,1,193,116,69,80,233,247,228,47,238,161,179,171,189,54,101,17,40,102,8,173,230,215,252,248,229,190,66,173,45,193,162,11,176,168,84,45,58,75,209,186,61,9,82,176,245,123,188,41,186,201, +71,169,236,48,21,129,186,28,212,135,41,175,159,2,240,84,197,139,88,2,162,26,175,108,219,239,237,163,202,28,68,204,24,225,229,77,72,84,218,209,187,9,222,53,154,162,212,18,148,251,42,250,169,10,140,102,22,206,234,161,217,66,60,187,135,206,145,118,106,141, +207,239,235,161,57,135,168,208,239,75,110,23,170,208,1,25,158,219,224,169,206,45,202,21,147,85,63,68,243,177,43,252,146,125,205,168,209,51,89,234,9,150,122,138,229,220,134,253,185,124,228,212,203,71,104,41,116,201,73,87,55,49,127,132,166,15,165,151,16, +233,202,101,243,26,142,124,60,179,162,135,230,7,36,158,92,42,158,142,82,0,223,141,52,142,54,209,84,196,120,45,93,78,23,209,22,90,75,87,144,137,127,219,105,43,117,83,51,93,77,45,116,19,89,72,177,86,68,89,27,61,75,237,244,18,5,233,187,180,141,126,6,170, +247,40,68,31,82,7,157,162,48,143,160,8,143,165,78,158,72,59,184,152,162,92,74,113,158,71,93,220,72,59,121,35,237,226,109,212,205,157,116,37,239,165,171,248,0,237,225,71,105,47,63,142,223,199,104,31,63,79,215,241,171,180,159,223,166,27,248,3,186,145,127, +79,55,243,31,233,86,254,43,221,198,31,211,237,57,146,254,18,251,61,72,176,110,100,195,87,233,107,248,222,73,147,233,113,122,2,189,71,144,108,50,166,65,51,195,158,133,46,54,157,6,105,83,232,235,244,36,233,28,67,206,63,133,21,185,208,106,171,154,245,65, +110,110,162,87,74,175,211,211,160,211,160,131,189,214,135,157,253,1,214,122,18,191,107,249,57,122,6,61,15,149,243,59,176,196,49,73,245,28,119,50,15,209,123,4,250,225,214,192,191,69,110,29,71,150,78,229,95,81,31,61,7,155,247,39,49,70,81,61,159,145,173, +54,196,189,128,254,9,122,49,129,58,115,49,34,25,175,149,185,33,166,108,0,8,108,224,186,27,74,28,74,3,46,45,5,92,7,157,89,228,12,98,113,47,88,220,231,192,98,31,146,253,37,155,5,187,161,185,134,177,77,130,27,189,180,160,190,188,161,226,68,181,219,85,237, +41,242,20,185,31,66,74,22,121,102,215,120,3,201,220,170,201,193,118,23,230,208,250,253,30,196,239,47,2,125,180,136,169,161,194,6,19,26,91,145,192,146,197,130,48,129,30,90,114,228,212,251,101,3,49,57,5,214,38,32,153,15,182,153,4,187,204,68,91,13,47,172, +129,31,214,195,207,27,224,55,209,119,19,252,53,9,113,96,123,69,71,36,127,19,171,92,192,242,18,250,22,104,220,84,64,211,225,159,39,176,195,53,160,120,153,94,193,216,98,64,174,248,204,165,56,36,177,115,19,189,170,176,211,135,200,127,13,222,207,73,121,202, +30,121,67,25,241,77,250,182,109,17,215,42,240,3,154,242,91,253,180,180,169,188,151,206,5,124,214,2,86,151,53,1,5,235,122,233,188,134,138,20,190,246,209,114,152,162,159,206,135,233,46,168,113,87,40,107,212,0,195,18,246,56,41,189,132,65,188,54,155,11,133, +205,10,176,81,72,136,140,191,40,201,228,98,48,89,137,204,214,108,46,185,254,220,4,151,117,210,75,64,180,46,32,82,237,126,128,166,248,125,78,24,211,71,245,96,118,132,38,15,76,79,24,60,125,234,81,191,175,176,225,56,173,130,20,168,176,90,216,190,74,121, +138,247,97,210,10,215,96,192,237,207,245,235,125,116,137,75,232,103,34,32,228,160,104,148,61,139,118,94,9,6,165,221,36,233,37,180,211,138,60,130,79,213,199,105,109,181,7,225,33,75,46,29,188,164,51,181,100,157,88,161,143,214,171,229,74,248,153,129,194, +203,220,47,80,83,147,2,104,212,186,141,61,180,17,27,90,16,72,238,103,19,182,82,4,208,219,92,120,185,189,41,79,6,121,147,59,193,209,94,120,234,38,132,225,150,167,83,33,120,37,2,75,64,38,23,9,236,71,10,151,66,187,217,72,224,213,8,11,19,105,27,70,154,238, +66,154,74,150,221,15,173,78,32,244,254,5,1,246,115,132,209,251,8,151,223,33,132,62,66,208,124,76,39,89,167,183,0,137,223,225,124,122,155,231,208,119,249,92,250,30,215,209,247,185,141,222,225,93,244,46,223,74,63,228,87,232,199,252,58,253,132,79,130,75, +18,222,14,162,98,56,41,96,69,215,0,152,37,100,115,33,251,49,122,11,188,53,72,191,157,190,67,111,35,60,223,167,105,0,187,39,49,251,59,132,246,247,212,138,213,208,245,40,194,221,75,53,100,67,148,7,178,13,5,126,26,79,82,105,113,12,208,216,6,184,255,62,189, +139,177,53,224,168,198,36,168,147,105,129,222,15,232,135,8,249,92,126,153,126,68,63,70,18,248,249,89,250,9,52,112,209,108,190,7,218,222,70,110,236,236,5,250,169,74,51,73,154,57,104,109,61,127,150,210,243,231,0,85,91,214,47,48,102,243,120,35,197,227,61, +164,165,46,47,203,137,250,231,151,104,161,7,93,212,79,87,192,153,102,189,123,73,249,107,228,45,92,179,178,172,143,182,166,23,38,52,61,81,152,212,120,38,30,166,220,0,206,252,230,245,1,57,236,90,164,231,2,178,252,8,158,181,6,192,165,82,210,86,244,129,38, +34,115,36,164,22,208,175,1,30,255,14,160,121,31,64,243,159,40,5,255,11,149,219,111,104,57,125,160,188,177,4,218,4,80,110,253,43,253,27,246,230,71,63,1,250,56,42,127,141,117,164,122,239,195,182,2,23,203,232,63,192,35,7,220,133,207,157,233,160,175,232, +127,131,214,134,250,15,0,178,71,233,183,9,144,109,135,101,100,215,39,202,235,3,39,150,184,170,221,69,238,137,15,209,174,64,145,123,118,141,71,33,171,39,81,139,248,251,169,181,169,176,45,145,0,158,198,227,212,222,75,65,84,56,146,228,219,146,243,219,179, +231,143,82,72,44,211,209,67,225,195,9,154,72,54,205,126,55,0,251,198,126,90,220,36,165,103,47,117,214,7,20,248,164,227,247,164,138,84,42,187,149,94,238,64,18,1,222,11,12,28,47,213,52,2,223,63,209,104,250,51,32,253,67,154,79,127,129,109,62,162,203,232, +111,40,34,254,78,123,48,119,45,140,114,11,51,61,206,56,49,216,69,207,227,168,73,66,251,104,148,24,71,213,49,155,131,12,16,104,207,65,127,175,130,118,23,236,124,165,130,118,55,14,132,17,42,174,221,56,13,167,165,160,253,68,10,218,79,36,160,253,22,248,87, +114,34,39,223,135,76,249,239,196,233,88,133,86,60,35,22,118,63,158,85,103,87,167,157,139,30,250,31,97,136,197,255,75,191,119,88,236,202,46,210,157,23,255,193,81,114,206,240,36,255,31,253,209,97,49,15,67,50,236,245,167,212,173,168,90,205,16,141,63,131, +118,244,80,20,88,238,62,66,110,215,51,84,86,24,59,78,241,103,40,244,180,170,33,6,138,132,106,228,200,60,244,254,172,36,125,136,172,22,140,28,69,93,184,175,137,98,23,162,221,141,59,91,55,218,43,209,46,67,123,21,218,61,104,247,130,199,103,208,94,173,252, +184,131,246,185,117,186,22,237,117,24,159,132,118,63,218,207,162,189,30,243,69,104,63,135,246,6,180,55,186,115,232,0,218,207,131,254,38,180,55,131,110,29,208,244,29,111,238,63,0,80,75,3,4,10,0,0,8,8,0,10,178,149,71,95,15,62,210,163,2,0,0,41,7,0,0,51, +0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,65,102,116,101,114,79,112,116,105,111,110,115,46,99,108,97,115,115,173,149,109,79,211,80,20,199,255,183,27,235,232,6,27,40, +136,207,11,130,64,11,148,161,162,136,49,81,124,8,201,68,19,116,137,188,49,119,107,29,213,174,53,119,69,241,35,248,93,124,33,137,74,162,137,31,192,15,101,60,183,171,163,178,145,130,49,77,122,207,57,247,220,223,57,231,222,115,219,159,191,190,253,0,80,198, +138,6,21,211,26,178,152,233,39,73,87,49,171,33,141,121,13,38,22,84,148,85,44,50,228,234,126,179,201,61,171,226,120,54,195,120,197,23,13,179,33,184,229,218,102,221,117,204,39,92,180,108,107,117,223,103,133,33,115,203,241,156,224,54,195,228,116,178,251, +76,149,33,189,234,91,4,47,72,195,250,118,179,102,139,167,188,230,146,101,184,226,215,185,91,229,194,145,122,100,76,7,91,78,139,33,127,231,101,96,139,199,111,2,199,247,164,186,230,121,182,88,117,121,171,101,147,106,30,140,28,139,25,38,33,38,226,235,41, +235,98,147,191,175,217,27,1,23,65,219,200,48,50,93,121,197,223,114,211,229,94,195,220,8,132,227,53,86,102,54,25,82,92,52,100,114,93,147,12,3,190,23,67,168,184,194,48,212,150,219,81,105,50,160,26,54,123,144,123,196,74,46,162,139,45,247,223,143,242,207, +249,222,186,239,253,169,38,247,87,6,119,123,213,150,28,47,30,73,197,85,6,48,172,29,225,152,147,201,229,176,21,148,157,5,249,42,51,76,28,101,9,131,182,225,111,139,186,253,192,145,173,49,218,229,51,47,139,204,35,135,188,124,93,203,163,31,154,138,37,134, +229,68,250,51,239,181,231,191,243,122,156,222,216,97,83,50,198,117,21,55,242,88,198,77,134,185,99,245,32,195,236,113,182,159,97,241,248,221,65,55,56,121,87,25,166,186,78,244,176,243,42,37,249,49,124,232,213,235,255,161,97,226,173,248,175,233,118,197, +165,27,204,45,235,254,78,32,120,149,187,219,246,33,31,129,42,74,244,197,204,66,182,255,176,236,41,146,250,160,200,62,35,203,0,105,15,73,83,104,204,233,108,15,138,110,124,65,106,151,84,5,131,244,30,68,138,86,214,208,199,234,208,152,133,2,217,70,219,238, +40,226,4,16,74,18,203,232,57,137,145,8,186,68,163,244,82,82,31,59,172,12,228,37,220,138,49,148,14,67,33,203,169,144,49,134,179,17,227,17,173,160,232,40,124,71,250,185,161,127,70,74,102,216,247,233,0,176,25,2,75,109,215,14,176,16,1,165,116,142,36,133, +228,243,184,24,161,239,70,53,107,146,106,124,69,70,223,167,106,114,134,9,100,89,43,150,170,214,33,107,109,114,81,22,62,30,241,238,145,143,140,159,209,141,61,176,221,3,25,190,136,101,152,233,112,50,184,20,110,155,148,38,48,25,102,116,57,92,57,69,39,5, +232,116,78,42,12,12,145,215,105,26,207,164,229,15,208,192,5,26,75,52,162,152,165,127,160,129,57,104,191,1,80,75,3,4,10,0,0,8,8,0,10,178,149,71,71,209,102,236,146,2,0,0,156,5,0,0,51,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109, +109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,79,112,116,105,111,110,83,116,114,105,110,103,46,99,108,97,115,115,149,83,237,78,19,65,20,61,211,15,182,148,181,93,202,151,40,154,130,85,218,45,101,41,226,39,136,198,26,19,35,1,19,12,6,255,13,237, +88,150,108,119,155,221,197,232,163,248,4,254,149,68,32,209,196,7,240,161,140,119,166,43,66,219,4,248,115,231,222,59,115,238,61,231,206,204,239,63,63,126,1,168,226,217,32,174,160,148,38,99,166,145,65,89,134,115,41,84,210,152,135,165,97,33,13,13,101,105, +170,210,44,166,112,87,158,93,210,112,95,195,3,134,56,247,155,12,185,181,61,254,145,91,14,119,155,214,102,232,219,110,115,153,97,192,107,135,182,231,146,179,98,187,118,184,202,48,91,236,61,215,155,41,109,49,36,106,94,67,48,100,215,108,87,172,239,183,118, +132,255,150,239,56,66,118,242,234,220,217,226,190,45,227,40,153,8,119,237,128,65,223,80,13,59,101,40,124,229,186,194,175,57,60,8,4,237,90,107,158,223,180,154,62,111,56,194,170,59,182,85,243,90,45,238,54,100,139,55,220,15,132,95,56,141,39,1,153,166,8, +95,216,65,219,225,159,215,121,139,250,140,22,75,253,132,166,66,175,227,107,120,200,0,134,215,23,210,121,62,159,170,154,69,236,211,130,52,85,105,22,25,10,23,193,49,12,241,122,93,4,65,161,186,180,64,240,90,241,146,234,251,10,77,111,122,251,126,93,188,180, +229,208,199,123,42,204,75,136,142,97,24,58,114,24,145,230,145,142,44,12,98,94,169,104,120,172,99,25,43,12,19,221,165,159,239,219,78,67,248,58,158,96,85,199,13,76,49,176,138,142,235,152,210,240,148,161,114,41,234,12,198,255,250,27,59,123,162,30,50,204, +156,63,51,122,203,69,57,110,163,155,29,233,14,66,238,135,193,59,59,220,101,24,235,115,185,165,247,244,202,121,187,45,220,6,209,237,119,160,39,21,105,166,169,230,207,227,134,60,253,184,12,253,214,24,77,148,198,73,94,78,78,153,214,164,202,141,208,155,27, +165,104,155,162,56,173,89,243,24,113,179,124,136,132,57,119,8,118,160,160,99,10,150,160,247,57,132,4,211,49,200,168,40,203,96,156,242,249,14,12,19,184,6,40,79,182,97,202,147,141,98,228,211,109,68,109,62,168,24,88,49,191,35,145,75,30,97,224,11,166,126, +66,219,62,70,74,134,131,148,103,180,28,33,253,21,147,255,54,134,206,108,124,59,225,52,32,107,177,97,197,67,239,212,141,120,48,249,20,162,158,22,173,114,47,105,30,65,239,6,143,159,2,39,59,96,67,138,205,71,224,13,146,71,194,161,153,229,185,99,196,14,186, +224,154,130,155,157,35,39,51,208,48,29,205,64,195,140,154,129,244,110,161,128,184,145,194,109,220,233,97,70,226,186,153,105,103,152,77,171,210,49,204,42,91,196,164,186,146,24,221,238,61,92,69,26,55,105,133,145,250,11,80,75,3,4,10,0,0,8,8,0,10,178,149, +71,120,38,226,84,96,4,0,0,26,11,0,0,59,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,65,98,115,116,114,97,99,116,80,114,111,112,101,114,116,105,101,115,67,111,109,109,97,110,100,76,105,110,101,67,111,110,118,101,114,116,101,114,46,99,108, +97,115,115,173,86,91,119,26,85,20,254,14,12,76,50,153,230,130,161,53,38,173,73,12,21,2,13,173,182,105,45,52,74,211,212,96,201,69,169,137,105,43,118,128,9,153,20,102,112,102,136,68,255,131,239,174,229,123,95,235,11,109,92,75,87,159,253,29,254,14,117,159, +129,32,100,176,165,89,194,226,92,246,217,103,239,111,127,251,156,125,248,227,175,95,127,7,112,5,63,72,56,135,219,34,150,37,156,197,29,222,172,72,184,139,79,37,172,34,205,167,159,241,209,61,9,25,172,73,88,199,198,16,54,241,249,16,190,64,150,55,247,7,240, +165,4,15,182,6,176,61,132,113,124,197,39,59,188,121,32,226,33,223,255,72,196,215,34,114,12,254,164,166,107,246,18,131,55,28,217,98,16,150,141,162,202,48,146,209,116,117,189,86,201,171,230,125,37,95,38,73,32,99,20,148,242,150,98,106,124,222,18,10,246, +158,102,49,92,207,24,102,41,94,50,149,98,89,141,23,202,90,60,149,183,108,83,41,216,155,166,81,85,77,91,83,173,101,163,82,81,244,34,55,187,108,232,7,36,84,205,4,195,88,73,61,86,58,220,168,218,154,161,51,140,135,35,153,125,229,64,137,151,21,189,20,207, +218,166,166,151,72,117,194,165,122,71,181,21,173,172,22,25,166,122,172,89,5,83,107,89,28,44,24,250,174,86,170,153,4,57,20,62,9,182,3,218,166,98,90,132,139,19,225,175,58,99,134,217,215,235,147,182,209,114,245,42,237,38,50,210,22,11,77,10,24,110,187,208, +56,38,139,29,187,18,77,50,106,182,86,142,175,41,213,68,228,196,156,50,87,53,40,9,44,77,73,122,162,30,110,41,229,154,186,82,175,154,170,101,57,144,2,189,216,244,104,115,196,116,135,169,52,37,68,177,13,30,140,216,12,198,234,17,141,27,29,131,84,109,103, +153,31,156,147,232,206,118,31,156,195,234,241,225,185,214,173,154,116,195,116,75,150,184,191,149,122,65,109,34,20,241,13,101,55,171,149,116,197,118,178,251,227,27,243,217,167,219,200,41,193,174,246,13,200,217,185,145,223,87,11,118,34,226,22,81,202,234, +151,121,115,165,59,163,237,229,226,127,93,194,94,87,47,121,170,112,28,246,179,70,205,44,168,119,53,158,194,104,127,23,125,129,219,146,241,54,38,24,70,79,218,149,241,46,166,101,204,96,90,196,99,25,239,67,17,145,151,81,64,81,198,44,95,81,177,43,162,196, +87,246,68,104,50,246,241,68,68,89,70,5,186,8,67,70,21,223,202,48,193,175,192,45,25,54,106,12,144,113,128,239,100,212,113,200,155,239,25,206,116,197,43,35,130,121,58,129,167,42,91,20,246,27,48,237,214,238,208,74,153,165,90,69,213,237,246,137,102,152,126, +93,181,161,114,27,126,232,206,78,164,159,194,243,10,227,199,213,87,222,83,172,99,88,68,233,92,184,47,195,195,180,171,171,228,46,134,255,39,136,174,235,194,144,236,199,182,107,95,219,195,197,254,52,169,176,208,171,226,84,83,226,33,16,238,172,0,25,205, +226,87,110,184,91,194,48,160,181,170,40,149,189,174,13,29,213,53,224,150,82,201,37,254,214,213,186,237,60,195,15,232,97,213,157,73,247,83,216,190,234,162,166,23,213,250,198,46,67,176,23,21,105,254,36,212,104,251,141,176,123,119,159,197,102,208,170,241, +67,77,246,120,40,233,116,207,39,57,24,238,37,23,102,232,255,197,57,240,143,8,198,111,61,181,239,208,44,78,61,221,77,248,230,159,131,253,66,3,15,38,169,245,59,194,32,166,192,239,173,163,128,243,184,0,8,2,47,13,78,63,211,234,103,121,79,58,239,97,174,101, +180,74,218,94,234,47,70,125,191,193,179,227,157,111,192,155,221,17,168,19,178,13,248,214,98,13,248,215,98,52,21,27,24,216,254,215,107,0,2,181,147,4,116,138,190,231,17,34,143,28,193,116,211,90,19,129,51,10,209,143,145,222,8,85,160,48,237,102,188,120,144, +22,247,254,39,121,247,83,159,139,114,191,13,12,54,32,29,97,136,97,253,210,17,100,134,159,176,66,131,51,12,47,225,185,41,76,8,129,225,6,70,22,125,65,223,207,24,139,209,116,244,8,99,94,108,63,197,36,205,188,65,95,3,129,9,33,232,19,30,55,240,86,107,233, +239,23,177,103,228,193,235,160,190,64,148,130,216,8,17,19,11,196,194,135,196,67,138,240,237,16,178,71,132,139,71,176,68,136,22,16,165,111,140,208,133,112,21,151,104,46,96,12,247,40,5,151,157,248,114,237,248,114,244,111,243,3,135,245,28,89,187,74,241, +93,107,231,129,75,22,73,114,157,198,2,73,110,224,35,135,191,155,163,41,242,149,160,17,231,96,149,44,114,155,210,124,52,246,18,227,13,4,159,245,204,109,147,89,169,237,89,66,178,229,89,194,45,66,221,233,199,211,242,244,49,62,113,250,212,63,80,75,3,4,10, +0,0,8,8,0,10,178,149,71,147,157,188,21,188,2,0,0,32,5,0,0,44,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,80,97,114,115,101,100,67,111,109,109,97,110,100,76,105,110,101,79,112,116,105,111,110,46,99,108,97,115,115,141,83,91,79,19,65,20, +254,182,183,45,237,34,165,92,20,65,40,23,161,45,202,138,23,188,80,171,4,49,33,105,196,164,6,131,111,67,59,89,134,108,119,155,221,45,17,127,10,207,38,190,248,160,137,74,144,68,125,246,71,25,207,236,46,165,20,73,124,153,157,57,251,157,239,124,223,57,51, +191,255,124,255,1,96,17,43,41,100,80,80,81,76,33,130,66,15,250,48,159,162,229,134,138,155,73,44,164,144,128,158,198,45,44,38,113,91,126,239,168,184,43,191,247,228,178,164,226,190,138,7,10,18,123,204,108,113,87,65,166,178,203,246,152,222,242,132,169,87, +132,235,45,43,232,169,10,195,98,94,203,225,10,102,186,126,151,130,179,201,44,67,175,122,142,176,140,229,50,165,36,74,194,18,94,89,65,52,95,216,84,16,91,181,235,148,220,87,17,22,127,209,106,108,115,231,21,219,54,41,146,173,216,53,102,110,50,71,200,115, +24,140,121,59,130,148,228,43,182,99,232,134,195,234,38,215,107,166,208,95,50,199,229,245,85,187,209,96,86,93,82,109,52,61,97,91,84,46,105,112,111,83,26,80,48,152,47,156,151,68,30,78,16,68,156,61,129,116,154,156,61,23,188,192,90,154,213,235,43,142,209, +106,112,203,83,48,148,63,143,146,142,147,172,13,201,254,75,79,114,135,185,161,98,106,209,27,5,169,170,221,114,106,252,185,144,29,24,187,192,234,130,100,210,48,132,97,5,3,167,106,87,28,135,237,75,201,26,250,145,213,112,29,179,10,38,78,171,174,155,38,55, +152,89,245,152,199,215,222,214,184,207,69,136,128,52,87,183,185,155,179,108,47,183,195,246,120,142,89,251,57,255,50,44,200,66,83,42,30,106,120,4,146,60,26,194,73,121,174,209,50,61,209,52,121,128,116,9,90,194,99,186,60,221,78,53,148,241,68,195,83,41,104, +246,255,198,121,134,101,99,123,151,215,168,135,151,206,142,134,238,136,43,222,5,189,91,167,149,134,43,71,177,222,57,250,32,149,116,71,105,96,93,131,10,255,201,190,171,194,93,107,52,189,125,76,210,155,201,208,131,162,129,201,46,210,119,128,78,17,12,34, +78,123,106,57,173,151,41,82,70,148,118,64,166,120,8,165,120,140,200,214,33,162,95,17,251,236,163,175,208,42,223,33,40,35,70,57,35,180,211,2,60,174,98,212,231,31,195,181,144,171,25,114,45,21,191,33,126,128,222,99,36,182,178,234,33,146,63,139,95,16,59, +66,15,25,125,31,134,83,39,225,232,17,210,17,252,130,246,169,93,113,152,52,130,106,169,84,163,159,248,199,169,66,30,19,29,213,151,218,213,199,41,30,241,171,235,116,146,255,226,146,245,148,44,225,7,167,59,146,227,97,114,208,144,28,197,38,49,21,90,120,70, +17,105,87,147,36,243,71,232,141,224,117,119,43,230,144,38,57,35,190,80,31,27,242,201,221,52,102,124,25,116,103,67,198,82,40,43,27,244,224,146,130,3,168,177,15,100,252,99,151,198,249,14,141,217,182,193,57,31,149,255,11,80,75,3,4,10,0,0,8,8,0,10,178,149, +71,182,192,176,115,152,2,0,0,170,6,0,0,61,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,79,112,116,105,111,110,65,119,97,114,101,80,97,114,115,101,114,83,116,97,116,101, +46,99,108,97,115,115,173,85,237,78,19,81,16,61,183,93,186,237,118,177,21,161,126,224,7,98,17,186,20,10,53,200,167,10,18,49,36,13,154,212,52,193,127,183,237,90,23,183,187,230,238,214,143,71,241,9,252,227,15,77,68,141,36,62,128,15,101,156,91,150,90,210, +154,69,226,159,206,206,204,153,115,166,119,230,238,254,252,245,253,7,128,121,172,39,144,196,13,13,58,178,242,105,66,163,159,155,26,38,49,165,33,7,67,197,180,6,21,51,42,102,53,36,48,167,98,94,69,145,33,89,115,155,77,238,212,75,150,99,50,140,151,92,209, +40,52,4,175,219,102,161,102,91,133,199,92,120,102,125,243,15,102,149,33,230,63,183,188,236,92,31,116,23,174,93,40,36,122,205,114,44,255,46,195,195,169,112,120,184,124,174,194,160,108,186,117,106,54,37,3,59,173,102,213,20,79,120,213,166,200,80,201,173, +113,187,194,133,37,253,32,168,200,118,25,50,143,94,250,150,235,108,188,230,34,80,43,251,220,167,188,190,237,56,166,216,180,185,231,153,132,91,14,237,50,219,159,137,254,107,186,201,223,86,77,242,132,127,136,97,24,153,42,237,241,87,188,96,115,167,81,40, +251,194,114,26,171,185,167,12,81,46,26,178,225,158,36,141,196,117,118,92,231,136,32,121,172,217,251,253,232,194,59,62,222,166,86,118,91,162,102,110,89,242,120,50,61,232,89,169,160,35,133,180,142,179,88,208,49,136,51,58,110,99,84,197,162,142,37,44,171, +88,209,177,138,53,134,133,80,229,141,103,190,41,182,44,225,249,229,86,53,72,51,12,247,11,75,181,59,12,51,39,227,60,60,31,26,152,222,237,74,14,218,181,197,83,206,144,33,255,47,103,169,226,30,3,24,38,195,87,59,59,223,94,221,184,229,29,13,118,44,108,215, +25,6,121,189,254,224,141,47,120,133,219,45,243,47,203,84,233,165,234,81,167,153,243,90,205,244,188,236,194,28,93,220,137,19,92,69,185,164,47,254,203,149,61,233,217,108,247,168,157,158,107,60,28,167,140,209,27,82,167,119,103,4,195,114,197,129,116,90,46, +61,69,162,80,104,143,134,104,178,231,200,43,17,34,74,54,109,76,239,131,25,236,43,34,70,126,31,209,79,65,45,168,150,242,44,15,141,205,32,197,102,49,66,177,12,229,168,134,236,69,160,253,36,53,34,196,121,9,163,1,243,10,249,18,21,51,166,191,64,249,208,225, +139,65,174,85,177,139,39,214,225,137,225,50,174,80,158,225,42,198,2,158,61,12,180,81,69,227,51,162,68,53,64,150,125,67,236,29,50,7,80,119,165,39,51,212,121,252,61,82,7,72,236,6,174,246,177,163,169,73,6,182,136,56,91,234,210,45,118,116,139,129,110,4,215, +219,53,227,184,64,214,32,229,36,125,95,206,43,17,58,203,28,174,41,242,43,147,67,158,16,9,178,5,226,189,69,22,233,248,111,80,75,3,4,10,0,0,8,8,0,10,178,149,71,39,4,72,12,25,1,0,0,103,2,0,0,41,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47, +67,111,109,109,97,110,100,76,105,110,101,67,111,110,118,101,114,116,101,114,46,99,108,97,115,115,141,81,77,75,195,64,16,125,211,214,198,212,175,170,39,207,34,52,10,70,175,77,41,72,81,20,2,10,9,222,183,233,186,108,73,55,178,221,148,254,54,15,254,0,127, +148,184,77,161,4,147,66,23,150,157,121,179,239,189,97,230,231,247,235,27,192,61,206,29,116,29,156,18,156,36,83,11,174,13,161,223,11,167,108,193,252,148,41,225,191,24,174,217,56,229,65,9,123,29,79,121,98,2,175,10,17,58,143,203,132,127,26,153,169,185,131, +51,130,27,73,161,152,201,53,39,220,213,9,15,74,88,100,180,84,34,24,6,113,28,120,246,18,158,123,97,166,133,47,52,155,164,220,79,82,233,191,49,61,231,147,81,54,155,49,53,9,165,218,185,179,235,29,164,54,190,174,157,198,135,20,69,219,87,21,98,137,82,104, +232,192,123,39,244,6,113,191,106,60,172,157,82,148,229,58,225,79,50,181,250,23,37,185,209,122,9,92,223,174,88,132,203,237,206,155,175,132,238,127,11,194,205,118,226,131,22,249,140,43,179,217,84,155,64,104,96,117,154,45,66,19,45,155,237,217,172,101,241, +54,28,27,53,176,95,84,220,154,74,199,86,14,112,88,196,107,228,8,199,197,123,242,7,80,75,3,4,10,0,0,8,8,0,10,178,149,71,67,209,22,230,234,3,0,0,124,11,0,0,60,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105, +110,101,80,97,114,115,101,114,36,66,101,102,111,114,101,70,105,114,115,116,83,117,98,67,111,109,109,97,110,100,46,99,108,97,115,115,197,86,109,83,19,87,20,126,110,178,112,113,179,104,72,13,149,182,216,72,131,64,94,8,65,171,64,16,11,17,144,18,137,109, +148,54,216,183,77,88,211,213,100,215,217,108,170,127,161,63,161,255,194,206,180,131,150,169,246,91,103,250,165,255,163,63,162,211,115,119,99,8,38,176,193,113,166,95,238,203,185,207,61,231,185,207,158,123,246,254,245,239,111,47,0,164,113,95,198,89,204, +157,162,102,94,70,24,115,28,25,25,18,22,101,44,224,90,0,75,184,206,241,137,152,44,115,172,8,216,13,25,50,86,57,214,6,176,206,113,83,198,6,62,149,49,136,77,142,156,140,16,182,56,242,28,183,25,250,237,239,245,122,116,134,97,44,103,90,149,84,197,82,119, +171,90,170,92,213,83,89,179,86,83,141,221,156,110,104,183,85,171,174,89,25,66,47,234,134,110,47,49,172,79,122,195,95,71,56,230,221,54,92,102,106,155,65,202,154,187,26,195,25,97,216,106,212,74,154,117,71,45,85,201,18,202,153,101,181,186,173,90,186,152, +55,141,146,160,203,16,94,209,238,155,150,182,166,91,117,187,208,40,53,125,50,40,27,134,161,89,217,170,90,175,107,4,155,243,36,25,237,234,136,78,26,40,31,64,187,136,211,121,22,134,65,211,40,216,170,101,231,31,217,186,105,112,124,206,48,228,142,221,88, +180,104,147,175,157,201,220,3,245,7,53,85,85,141,74,170,96,91,186,81,201,116,90,166,188,169,119,248,38,14,126,213,170,8,233,58,252,209,183,51,29,60,137,228,14,220,5,154,230,15,77,83,189,6,110,57,30,106,147,42,223,140,113,92,54,185,152,12,71,129,1,12, +15,223,74,42,121,179,78,59,233,230,123,50,35,154,180,104,102,25,162,189,236,99,144,11,102,195,42,83,154,136,28,28,238,192,76,11,185,21,156,195,136,130,97,188,203,113,135,33,121,34,25,197,230,187,10,182,241,5,199,151,10,138,216,97,136,120,73,168,224,30, +190,98,152,247,140,116,215,120,104,152,143,141,46,201,120,238,168,37,5,23,48,38,88,125,203,16,63,58,192,178,85,105,212,52,195,94,125,82,214,154,159,254,66,211,101,164,153,22,201,42,225,34,110,206,69,38,198,235,19,211,12,193,131,252,204,151,30,104,101, +155,227,59,5,42,74,34,98,153,225,170,231,145,54,143,56,208,112,247,5,225,151,234,195,149,55,171,7,189,16,114,67,46,63,86,45,237,48,161,163,22,102,79,126,193,233,94,121,167,235,177,137,227,130,24,54,123,42,66,189,94,42,89,45,151,181,122,61,58,55,67,151, +235,82,15,247,121,202,141,213,176,245,106,234,150,250,72,20,207,67,6,42,100,21,205,102,184,216,78,211,205,148,87,123,219,77,7,12,230,5,131,241,94,24,236,112,144,158,129,67,234,254,216,77,149,183,80,122,218,107,116,175,154,6,95,103,66,21,156,82,179,166, +146,44,243,93,120,222,59,94,169,86,181,14,119,217,43,226,253,243,6,101,216,227,215,224,253,15,248,191,196,77,156,196,43,34,244,160,10,211,59,140,5,131,162,188,211,200,15,159,168,246,244,247,122,143,102,55,105,238,167,94,137,197,127,133,47,22,79,236,193, +255,51,205,125,120,159,218,211,98,141,93,67,31,91,66,128,93,199,7,100,27,166,53,194,99,148,124,195,25,81,181,37,27,195,71,184,216,244,250,55,6,208,71,189,182,15,169,24,79,176,61,244,109,197,126,129,239,25,250,19,207,193,125,248,3,3,11,210,136,244,39, +210,174,249,212,79,8,237,67,46,198,105,26,136,17,94,121,186,143,193,98,232,180,244,59,206,20,253,201,194,51,4,247,48,244,114,31,161,162,216,145,28,145,94,33,223,121,218,162,123,30,156,232,102,137,234,13,140,178,85,140,177,53,36,216,58,50,108,131,222, +139,57,135,254,101,151,88,139,190,134,9,76,18,109,49,154,162,145,15,1,236,32,134,4,29,125,148,228,73,98,26,82,16,36,89,186,121,184,60,173,72,212,115,71,45,118,160,86,191,112,195,22,157,48,49,23,210,10,195,49,75,234,51,103,116,201,209,75,140,46,227,99, +231,123,92,113,124,92,197,135,212,175,144,118,103,233,57,124,158,44,81,234,199,37,241,92,94,64,156,94,197,41,234,17,28,128,120,46,103,33,30,195,11,184,69,184,48,245,159,73,62,124,77,253,55,146,252,31,80,75,3,4,10,0,0,8,8,0,10,178,149,71,147,0,59,153, +124,1,0,0,252,2,0,0,57,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,83,121,115,116,101,109,80,114,111,112,101,114,116,105,101,115,67,111,109,109,97,110,100,76,105,110,101,67,111,110,118,101,114,116,101,114,46,99,108,97,115,115,157,146, +203,74,195,64,20,134,207,216,171,109,181,182,214,106,213,69,220,53,66,19,68,196,133,23,144,22,23,82,47,80,233,126,154,30,211,145,36,19,38,211,66,222,74,87,130,11,31,192,135,18,39,105,16,169,65,196,89,156,51,243,207,255,205,156,185,188,127,188,190,1,192, +1,108,151,32,15,141,34,108,20,161,89,132,205,2,108,21,160,69,32,127,202,60,38,207,9,100,218,250,144,64,182,203,199,72,160,218,103,30,222,76,221,17,138,123,58,114,148,82,239,115,139,58,67,42,88,52,78,196,172,156,176,128,192,81,159,11,219,180,5,29,59,104, +90,14,51,7,97,32,209,189,19,220,71,33,25,6,93,238,186,212,27,71,139,118,185,55,83,34,138,19,2,53,27,101,98,10,111,125,201,184,71,160,209,214,251,143,116,70,77,135,122,182,57,144,130,121,182,178,182,126,88,123,40,41,115,112,76,96,55,101,46,176,4,75,86, +44,13,248,84,88,120,201,162,138,245,191,148,102,68,5,84,160,0,69,2,164,71,160,28,196,80,199,87,20,129,227,1,74,109,174,104,126,178,173,198,31,52,57,65,237,106,120,173,181,209,176,13,173,211,115,195,104,246,204,13,103,212,153,162,110,16,56,252,199,53, +169,219,93,160,46,70,129,20,212,146,191,115,176,7,57,245,224,81,203,2,137,206,162,226,178,26,153,42,19,149,115,251,47,64,158,85,103,9,74,42,230,99,177,14,101,21,43,115,131,202,43,49,190,10,213,4,238,36,112,166,190,244,180,128,54,191,161,153,47,116,45, +5,205,44,162,59,169,104,45,5,205,46,162,90,10,170,62,107,236,90,255,4,80,75,3,4,10,0,0,8,8,0,10,178,149,71,45,21,104,130,7,2,0,0,187,4,0,0,50,0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97, +114,115,101,114,36,80,97,114,115,101,114,83,116,97,116,101,46,99,108,97,115,115,149,83,223,111,210,80,20,254,78,41,20,11,115,192,220,84,52,19,55,28,48,54,234,124,51,24,77,36,154,152,144,109,9,102,15,123,187,64,195,186,148,91,115,219,45,250,63,249,226, +139,38,62,248,7,248,71,25,207,109,217,100,131,4,105,210,158,31,247,156,239,124,231,156,219,223,127,126,254,2,112,0,199,70,26,219,54,50,216,206,162,106,227,25,118,44,212,45,52,8,153,87,158,244,162,215,132,84,189,113,66,48,59,193,208,37,172,118,61,233, +30,94,140,251,174,250,40,250,62,123,74,221,96,32,252,19,161,60,109,79,156,102,116,230,133,132,220,177,80,161,171,122,145,136,216,153,255,32,165,171,58,190,8,67,151,15,91,221,64,141,156,145,18,67,223,117,6,190,231,116,130,241,88,200,161,174,144,228,85, +167,210,219,132,194,88,124,233,187,108,169,232,232,83,228,5,146,176,94,239,158,139,75,225,248,66,142,156,94,164,60,57,106,55,78,9,89,47,188,10,73,9,53,210,44,103,226,8,43,129,156,66,179,176,75,40,38,250,13,222,167,115,138,204,41,187,184,157,25,108,230, +144,11,228,97,32,175,200,190,157,215,207,210,115,10,228,84,200,59,57,180,208,36,128,80,171,47,134,58,104,235,109,27,159,159,19,170,255,19,77,176,123,193,133,26,184,239,61,189,248,141,153,152,150,110,40,15,11,89,130,85,127,19,54,246,91,77,11,123,121,236, +163,104,161,69,216,91,166,61,238,238,223,128,142,250,231,238,32,34,188,88,126,242,132,173,197,205,221,40,150,108,131,123,24,139,104,112,166,47,112,101,17,130,89,225,191,43,3,253,88,48,244,8,120,9,119,216,114,88,242,70,144,222,253,1,227,27,43,6,108,254, +102,180,147,202,200,177,158,79,2,88,174,2,38,51,65,49,6,42,177,76,64,218,156,101,104,232,102,41,245,29,230,215,91,48,155,49,204,70,18,146,192,196,218,26,238,129,24,112,29,15,98,224,135,40,67,95,142,71,215,236,154,177,205,239,109,102,59,83,204,40,129, +44,104,200,205,73,226,75,150,198,164,173,153,228,242,20,159,244,53,159,52,158,160,18,167,61,141,227,183,112,151,101,25,41,62,169,97,197,180,57,163,134,251,44,31,179,68,33,251,23,80,75,3,4,10,0,0,8,8,0,10,178,149,71,70,182,8,247,61,3,0,0,202,9,0,0,59, +0,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,65,102,116,101,114,70,105,114,115,116,83,117,98,67,111,109,109,97,110,100,46,99,108,97,115,115,197,86,235,82,211,80,16,254, +78,91,8,164,1,74,5,196,59,98,101,160,45,180,5,17,176,120,41,85,46,82,40,88,69,209,95,161,196,26,40,9,147,6,241,21,124,0,223,3,103,116,80,153,113,252,231,140,143,226,67,56,238,73,10,20,75,155,194,48,227,159,179,123,118,247,124,103,119,179,187,57,191,254, +124,251,14,32,134,69,17,205,136,52,210,18,21,209,130,136,72,178,65,47,134,112,75,192,176,128,219,92,51,42,66,192,152,128,59,2,198,69,120,113,79,132,136,251,2,30,8,72,48,212,155,111,212,66,32,202,208,157,210,141,92,36,103,200,171,121,37,146,205,171,145, +164,190,177,33,107,171,41,85,83,22,100,163,160,24,113,178,30,87,53,213,188,199,48,213,235,108,254,175,133,37,94,45,177,139,247,45,49,120,146,250,170,194,208,194,5,243,91,27,43,138,241,84,94,201,147,196,159,210,179,114,126,73,54,84,190,47,10,61,220,93, +134,182,196,107,83,49,38,85,163,96,102,182,86,138,144,12,210,140,166,41,70,50,47,23,10,10,89,141,56,250,24,56,14,135,226,244,102,15,45,143,73,77,121,36,12,77,186,150,49,101,195,76,111,154,170,174,9,72,50,180,218,188,125,21,41,77,194,122,217,155,90,147, +223,202,145,188,172,229,34,25,211,80,181,92,188,92,210,231,236,121,25,54,249,224,150,141,28,79,92,25,30,125,57,221,178,39,167,74,66,75,23,101,213,190,189,109,19,23,240,144,1,12,235,103,242,225,157,195,139,89,197,225,122,23,229,75,140,47,131,12,129,90, +206,49,136,25,125,203,200,42,147,42,175,152,142,50,155,1,158,30,9,126,156,147,224,67,171,128,71,18,38,49,37,96,90,194,12,30,51,116,57,101,131,97,204,209,145,103,218,186,166,111,107,199,148,64,103,37,149,132,75,184,204,29,155,163,218,117,188,96,182,2, +124,71,37,69,127,141,53,101,215,12,117,83,233,150,187,53,207,151,52,195,240,169,218,170,150,152,236,27,19,219,178,161,28,141,169,146,98,240,228,125,66,229,238,92,69,85,139,192,54,162,58,147,179,89,165,80,8,140,70,169,74,135,106,104,140,62,187,51,183, +76,53,31,153,147,55,249,212,56,34,160,14,206,41,38,67,79,233,144,72,175,172,41,89,115,255,108,169,72,192,2,141,170,35,161,189,63,110,188,156,65,59,150,206,153,90,155,119,182,166,81,87,43,218,239,83,12,158,234,21,94,205,188,56,245,254,87,234,194,39,65, +69,23,253,229,91,232,61,192,124,62,62,208,136,115,195,197,231,27,205,235,54,218,77,211,222,77,84,10,134,62,195,21,12,133,119,225,254,72,123,23,218,105,109,230,58,182,136,58,246,4,94,150,65,7,201,58,72,71,246,56,143,139,128,197,209,100,34,25,195,21,186, +205,70,253,128,6,120,136,38,130,159,224,250,2,79,248,43,234,92,248,129,250,249,254,159,240,239,65,88,14,145,166,33,200,118,209,184,179,7,113,153,219,237,193,187,28,10,147,72,234,223,87,54,237,28,184,226,231,128,236,57,90,217,11,180,179,101,4,216,43,203, +157,160,125,209,129,59,9,92,71,55,185,193,185,27,196,185,40,232,40,2,184,9,183,143,163,244,22,93,76,83,104,252,164,96,197,204,14,99,174,231,135,217,66,9,184,112,0,46,160,143,224,152,197,5,173,168,57,23,66,216,202,106,191,133,49,128,11,68,39,40,3,205, +244,226,234,36,201,85,162,215,60,34,122,136,194,215,64,39,98,24,1,127,106,197,16,39,189,151,232,93,240,71,90,12,19,30,23,102,137,166,60,226,95,80,75,3,4,10,0,0,8,8,0,10,178,149,71,105,222,125,0,70,0,0,0,68,0,0,0,31,0,0,0,103,114,97,100,108,101,45,99, +108,105,45,99,108,97,115,115,112,97,116,104,46,112,114,111,112,101,114,116,105,101,115,83,206,205,79,41,205,73,85,72,73,77,203,204,203,44,201,204,207,227,82,246,205,207,83,112,73,77,86,48,50,84,48,50,178,50,52,179,50,50,80,112,118,13,81,48,50,48,52,229, +42,40,202,207,74,77,46,41,182,229,42,42,205,43,201,204,77,181,229,2,0,80,75,1,2,20,3,10,0,0,8,8,0,42,178,149,71,0,0,0,0,2,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,16,0,237,65,0,0,0,0,77,69,84,65,45,73,78,70,47,80,75,1,2,20,3,10,0,0,8,8,0,42,178,149,71,215,149, +152,82,63,0,0,0,85,0,0,0,20,0,0,0,0,0,0,0,0,0,0,0,164,129,41,0,0,0,77,69,84,65,45,73,78,70,47,77,65,78,73,70,69,83,84,46,77,70,80,75,1,2,20,3,10,0,0,8,8,0,22,178,149,71,0,0,0,0,2,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,16,0,253,65,154,0,0,0,111,114,103,47, +80,75,1,2,20,3,10,0,0,8,8,0,22,178,149,71,0,0,0,0,2,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,16,0,253,65,190,0,0,0,111,114,103,47,103,114,97,100,108,101,47,80,75,1,2,20,3,10,0,0,8,8,0,22,178,149,71,0,0,0,0,2,0,0,0,0,0,0,0,19,0,0,0,0,0,0,0,0,0,16,0,253,65,233, +0,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,80,75,1,2,20,3,10,0,0,8,8,0,22,178,149,71,104,130,100,102,163,0,0,0,213,0,0,0,35,0,0,0,0,0,0,0,0,0,0,0,180,129,28,1,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112, +112,101,114,47,68,111,119,110,108,111,97,100,36,49,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,22,178,149,71,197,222,133,214,20,2,0,0,112,4,0,0,68,0,0,0,0,0,0,0,0,0,0,0,180,129,0,2,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112, +101,114,47,68,111,119,110,108,111,97,100,36,83,121,115,116,101,109,80,114,111,112,101,114,116,105,101,115,80,114,111,120,121,65,117,116,104,101,110,116,105,99,97,116,111,114,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,22,178,149,71,231,236,88,115, +170,0,0,0,219,0,0,0,34,0,0,0,0,0,0,0,0,0,0,0,180,129,118,4,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,73,68,111,119,110,108,111,97,100,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,22,178,149,71,4,169,122,221,92,2,0, +0,81,4,0,0,45,0,0,0,0,0,0,0,0,0,0,0,180,129,96,5,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,71,114,97,100,108,101,85,115,101,114,72,111,109,101,76,111,111,107,117,112,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,22, +178,149,71,28,226,93,219,197,5,0,0,250,10,0,0,51,0,0,0,0,0,0,0,0,0,0,0,180,129,7,8,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,69,120,99,108,117,115,105,118,101,70,105,108,101,65,99,99,101,115,115,77,97,110,97,103,101,114, +46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,22,178,149,71,204,13,94,70,145,2,0,0,249,6,0,0,45,0,0,0,0,0,0,0,0,0,0,0,180,129,29,14,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,87,114,97,112,112,101,114,67,111,110,102, +105,103,117,114,97,116,105,111,110,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,22,178,149,71,81,125,29,105,229,4,0,0,25,10,0,0,48,0,0,0,0,0,0,0,0,0,0,0,180,129,249,16,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,83, +121,115,116,101,109,80,114,111,112,101,114,116,105,101,115,72,97,110,100,108,101,114,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,22,178,149,71,165,121,48,186,86,2,0,0,0,5,0,0,31,0,0,0,0,0,0,0,0,0,0,0,180,129,44,22,0,0,111,114,103,47,103,114,97,100, +108,101,47,119,114,97,112,112,101,114,47,76,111,103,103,101,114,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,22,178,149,71,206,114,235,138,21,7,0,0,110,14,0,0,38,0,0,0,0,0,0,0,0,0,0,0,180,129,191,24,0,0,111,114,103,47,103,114,97,100,108,101,47,119, +114,97,112,112,101,114,47,80,97,116,104,65,115,115,101,109,98,108,101,114,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,22,178,149,71,56,222,182,221,27,19,0,0,236,41,0,0,32,0,0,0,0,0,0,0,0,0,0,0,180,129,24,32,0,0,111,114,103,47,103,114,97,100,108, +101,47,119,114,97,112,112,101,114,47,73,110,115,116,97,108,108,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,22,178,149,71,221,192,76,137,196,4,0,0,149,9,0,0,45,0,0,0,0,0,0,0,0,0,0,0,180,129,113,51,0,0,111,114,103,47,103,114,97,100,108,101,47,119, +114,97,112,112,101,114,47,66,111,111,116,115,116,114,97,112,77,97,105,110,83,116,97,114,116,101,114,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,22,178,149,71,72,214,183,36,211,10,0,0,35,24,0,0,40,0,0,0,0,0,0,0,0,0,0,0,180,129,128,56,0,0,111,114, +103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,87,114,97,112,112,101,114,69,120,101,99,117,116,111,114,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,22,178,149,71,132,26,164,171,178,10,0,0,66,24,0,0,42,0,0,0,0,0,0,0,0,0,0,0,180,129, +153,67,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,71,114,97,100,108,101,87,114,97,112,112,101,114,77,97,105,110,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,22,178,149,71,217,206,17,120,160,6,0,0,180,14,0,0,34,0,0, +0,0,0,0,0,0,0,0,0,180,129,147,78,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,73,110,115,116,97,108,108,36,49,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,22,178,149,71,106,32,106,144,180,1,0,0,86,3,0,0,56,0,0,0,0,0, +0,0,0,0,0,0,180,129,115,85,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,80,97,116,104,65,115,115,101,109,98,108,101,114,36,76,111,99,97,108,68,105,115,116,114,105,98,117,116,105,111,110,46,99,108,97,115,115,80,75,1,2,20, +3,10,0,0,8,8,0,22,178,149,71,146,99,74,27,25,8,0,0,75,15,0,0,33,0,0,0,0,0,0,0,0,0,0,0,180,129,125,87,0,0,111,114,103,47,103,114,97,100,108,101,47,119,114,97,112,112,101,114,47,68,111,119,110,108,111,97,100,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8, +8,0,22,178,149,71,192,25,62,198,80,0,0,0,78,0,0,0,35,0,0,0,0,0,0,0,0,0,0,0,180,129,213,95,0,0,103,114,97,100,108,101,45,119,114,97,112,112,101,114,45,99,108,97,115,115,112,97,116,104,46,112,114,111,112,101,114,116,105,101,115,80,75,1,2,20,3,10,0,0,8, +8,0,10,178,149,71,36,217,150,101,206,0,0,0,28,1,0,0,24,0,0,0,0,0,0,0,0,0,0,0,180,129,102,96,0,0,98,117,105,108,100,45,114,101,99,101,105,112,116,46,112,114,111,112,101,114,116,105,101,115,80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,0,0,0,0,2,0,0,0,0,0, +0,0,15,0,0,0,0,0,0,0,0,0,16,0,253,65,106,97,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,144,200,244,150,60,2,0,0,83,5,0,0,49,0,0,0,0,0,0,0,0,0,0,0,180,129,153,97,0,0,111,114,103,47,103,114,97,100, +108,101,47,99,108,105,47,65,98,115,116,114,97,99,116,67,111,109,109,97,110,100,76,105,110,101,67,111,110,118,101,114,116,101,114,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,50,95,101,143,166,0,0,0,232,0,0,0,40,0,0,0,0,0,0,0,0,0,0,0, +180,129,36,100,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,49,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,82,66,9,29,168,2,0,0,247,6,0,0,60,0,0,0,0,0, +0,0,0,0,0,0,180,129,16,101,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,77,105,115,115,105,110,103,79,112,116,105,111,110,65,114,103,83,116,97,116,101,46,99,108,97,115,115, +80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,188,172,77,50,145,2,0,0,131,5,0,0,61,0,0,0,0,0,0,0,0,0,0,0,180,129,18,104,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,79,112,116, +105,111,110,83,116,114,105,110,103,67,111,109,112,97,114,97,116,111,114,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,232,35,13,242,71,1,0,0,75,2,0,0,49,0,0,0,0,0,0,0,0,0,0,0,180,129,254,106,0,0,111,114,103,47,103,114,97,100,108,101, +47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,65,114,103,117,109,101,110,116,69,120,99,101,112,116,105,111,110,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,63,23,104,255,199,7,0,0,135,19,0,0,61,0,0,0,0,0,0,0,0,0,0,0,180, +129,148,108,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,75,110,111,119,110,79,112,116,105,111,110,80,97,114,115,101,114,83,116,97,116,101,46,99,108,97,115,115,80,75,1,2, +20,3,10,0,0,8,8,0,10,178,149,71,28,107,22,177,205,2,0,0,219,6,0,0,55,0,0,0,0,0,0,0,0,0,0,0,180,129,182,116,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,79,112,116,105,111, +110,67,111,109,112,97,114,97,116,111,114,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,228,98,213,39,225,2,0,0,110,7,0,0,63,0,0,0,0,0,0,0,0,0,0,0,180,129,216,119,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109, +97,110,100,76,105,110,101,80,97,114,115,101,114,36,85,110,107,110,111,119,110,79,112,116,105,111,110,80,97,114,115,101,114,83,116,97,116,101,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,34,122,201,90,146,5,0,0,153,13,0,0,38,0,0,0,0, +0,0,0,0,0,0,0,180,129,22,123,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,79,112,116,105,111,110,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,156,108,92,207,167,1,0,0,166,3,0,0, +56,0,0,0,0,0,0,0,0,0,0,0,180,129,236,128,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,79,112,116,105,111,110,80,97,114,115,101,114,83,116,97,116,101,46,99,108,97,115,115, +80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,91,120,110,152,148,7,0,0,199,17,0,0,38,0,0,0,0,0,0,0,0,0,0,0,180,129,233,130,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,80,97,114,115,101,100,67,111,109,109,97,110,100,76,105,110,101,46,99,108, +97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,139,65,53,108,124,1,0,0,11,3,0,0,58,0,0,0,0,0,0,0,0,0,0,0,180,129,193,138,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,80,114,111,106,101,99,116,80,114,111,112,101,114,116,105,101,115, +67,111,109,109,97,110,100,76,105,110,101,67,111,110,118,101,114,116,101,114,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,50,108,87,182,74,2,0,0,4,5,0,0,70,0,0,0,0,0,0,0,0,0,0,0,180,129,149,140,0,0,111,114,103,47,103,114,97,100,108,101, +47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,67,97,115,101,73,110,115,101,110,115,105,116,105,118,101,83,116,114,105,110,103,67,111,109,112,97,114,97,116,111,114,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,10, +178,149,71,133,165,180,23,103,18,0,0,198,42,0,0,38,0,0,0,0,0,0,0,0,0,0,0,180,129,67,143,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,46,99,108,97,115,115,80,75,1,2,20,3,10,0, +0,8,8,0,10,178,149,71,95,15,62,210,163,2,0,0,41,7,0,0,51,0,0,0,0,0,0,0,0,0,0,0,180,129,238,161,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,65,102,116,101,114,79,112,116, +105,111,110,115,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,71,209,102,236,146,2,0,0,156,5,0,0,51,0,0,0,0,0,0,0,0,0,0,0,180,129,226,164,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110, +101,80,97,114,115,101,114,36,79,112,116,105,111,110,83,116,114,105,110,103,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,120,38,226,84,96,4,0,0,26,11,0,0,59,0,0,0,0,0,0,0,0,0,0,0,180,129,197,167,0,0,111,114,103,47,103,114,97,100,108, +101,47,99,108,105,47,65,98,115,116,114,97,99,116,80,114,111,112,101,114,116,105,101,115,67,111,109,109,97,110,100,76,105,110,101,67,111,110,118,101,114,116,101,114,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,147,157,188,21,188,2,0, +0,32,5,0,0,44,0,0,0,0,0,0,0,0,0,0,0,180,129,126,172,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,80,97,114,115,101,100,67,111,109,109,97,110,100,76,105,110,101,79,112,116,105,111,110,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,10,178, +149,71,182,192,176,115,152,2,0,0,170,6,0,0,61,0,0,0,0,0,0,0,0,0,0,0,180,129,132,175,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,79,112,116,105,111,110,65,119,97,114,101, +80,97,114,115,101,114,83,116,97,116,101,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,39,4,72,12,25,1,0,0,103,2,0,0,41,0,0,0,0,0,0,0,0,0,0,0,180,129,119,178,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97, +110,100,76,105,110,101,67,111,110,118,101,114,116,101,114,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,67,209,22,230,234,3,0,0,124,11,0,0,60,0,0,0,0,0,0,0,0,0,0,0,180,129,215,179,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105, +47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,66,101,102,111,114,101,70,105,114,115,116,83,117,98,67,111,109,109,97,110,100,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,147,0,59,153,124,1,0,0,252,2,0,0,57,0,0, +0,0,0,0,0,0,0,0,0,180,129,27,184,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,83,121,115,116,101,109,80,114,111,112,101,114,116,105,101,115,67,111,109,109,97,110,100,76,105,110,101,67,111,110,118,101,114,116,101,114,46,99,108,97,115,115, +80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,45,21,104,130,7,2,0,0,187,4,0,0,50,0,0,0,0,0,0,0,0,0,0,0,180,129,238,185,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100,76,105,110,101,80,97,114,115,101,114,36,80,97,114, +115,101,114,83,116,97,116,101,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,70,182,8,247,61,3,0,0,202,9,0,0,59,0,0,0,0,0,0,0,0,0,0,0,180,129,69,188,0,0,111,114,103,47,103,114,97,100,108,101,47,99,108,105,47,67,111,109,109,97,110,100, +76,105,110,101,80,97,114,115,101,114,36,65,102,116,101,114,70,105,114,115,116,83,117,98,67,111,109,109,97,110,100,46,99,108,97,115,115,80,75,1,2,20,3,10,0,0,8,8,0,10,178,149,71,105,222,125,0,70,0,0,0,68,0,0,0,31,0,0,0,0,0,0,0,0,0,0,0,180,129,219,191, +0,0,103,114,97,100,108,101,45,99,108,105,45,99,108,97,115,115,112,97,116,104,46,112,114,111,112,101,114,116,105,101,115,80,75,5,6,0,0,0,0,49,0,49,0,16,17,0,0,94,192,0,0,0,0,0,0 }; + +const char* gradlewrapper_jar = (const char*) temp_binary_data_6; + +//================== gradlew ================== +static const unsigned char temp_binary_data_7[] = +"#!/usr/bin/env bash\n" +"\n" +"##############################################################################\n" +"##\n" +"## Gradle start up script for UN*X\n" +"##\n" +"##############################################################################\n" +"\n" +"# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\n" +"DEFAULT_JVM_OPTS=\"\"\n" +"\n" +"APP_NAME=\"Gradle\"\n" +"APP_BASE_NAME=`basename \"$0\"`\n" +"\n" +"# Use the maximum available, or set MAX_FD != -1 to use that value.\n" +"MAX_FD=\"maximum\"\n" +"\n" +"warn ( ) {\n" +" echo \"$*\"\n" +"}\n" +"\n" +"die ( ) {\n" +" echo\n" +" echo \"$*\"\n" +" echo\n" +" exit 1\n" +"}\n" +"\n" +"# OS specific support (must be 'true' or 'false').\n" +"cygwin=false\n" +"msys=false\n" +"darwin=false\n" +"case \"`uname`\" in\n" +" CYGWIN* )\n" +" cygwin=true\n" +" ;;\n" +" Darwin* )\n" +" darwin=true\n" +" ;;\n" +" MINGW* )\n" +" msys=true\n" +" ;;\n" +"esac\n" +"\n" +"# Attempt to set APP_HOME\n" +"# Resolve links: $0 may be a link\n" +"PRG=\"$0\"\n" +"# Need this for relative symlinks.\n" +"while [ -h \"$PRG\" ] ; do\n" +" ls=`ls -ld \"$PRG\"`\n" +" link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n" +" if expr \"$link\" : '/.*' > /dev/null; then\n" +" PRG=\"$link\"\n" +" else\n" +" PRG=`dirname \"$PRG\"`\"/$link\"\n" +" fi\n" +"done\n" +"SAVED=\"`pwd`\"\n" +"cd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\n" +"APP_HOME=\"`pwd -P`\"\n" +"cd \"$SAVED\" >/dev/null\n" +"\n" +"CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n" +"\n" +"# Determine the Java command to use to start the JVM.\n" +"if [ -n \"$JAVA_HOME\" ] ; then\n" +" if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n" +" # IBM's JDK on AIX uses strange locations for the executables\n" +" JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n" +" else\n" +" JAVACMD=\"$JAVA_HOME/bin/java\"\n" +" fi\n" +" if [ ! -x \"$JAVACMD\" ] ; then\n" +" die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n" +"\n" +"Please set the JAVA_HOME variable in your environment to match the\n" +"location of your Java installation.\"\n" +" fi\n" +"else\n" +" JAVACMD=\"java\"\n" +" which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n" +"\n" +"Please set the JAVA_HOME variable in your environment to match the\n" +"location of your Java installation.\"\n" +"fi\n" +"\n" +"# Increase the maximum file descriptors if we can.\n" +"if [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" ] ; then\n" +" MAX_FD_LIMIT=`ulimit -H -n`\n" +" if [ $? -eq 0 ] ; then\n" +" if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n" +" MAX_FD=\"$MAX_FD_LIMIT\"\n" +" fi\n" +" ulimit -n $MAX_FD\n" +" if [ $? -ne 0 ] ; then\n" +" warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n" +" fi\n" +" else\n" +" warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n" +" fi\n" +"fi\n" +"\n" +"# For Darwin, add options to specify how the application appears in the dock\n" +"if $darwin; then\n" +" GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\n" +"fi\n" +"\n" +"# For Cygwin, switch paths to Windows format before running java\n" +"if $cygwin ; then\n" +" APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n" +" CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n" +" JAVACMD=`cygpath --unix \"$JAVACMD\"`\n" +"\n" +" # We build the pattern for arguments to be converted via cygpath\n" +" ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n" +" SEP=\"\"\n" +" for dir in $ROOTDIRSRAW ; do\n" +" ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n" +" SEP=\"|\"\n" +" done\n" +" OURCYGPATTERN=\"(^($ROOTDIRS))\"\n" +" # Add a user-defined pattern to the cygpath arguments\n" +" if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n" +" OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n" +" fi\n" +" # Now convert the arguments - kludge to limit ourselves to /bin/sh\n" +" i=0\n" +" for arg in \"$@\" ; do\n" +" CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n" +" CHECK2=`echo \"$arg\"|egrep -c \"^-\"` ### Determine if an option\n" +"\n" +" if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition\n" +" eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n" +" else\n" +" eval `echo args$i`=\"\\\"$arg\\\"\"\n" +" fi\n" +" i=$((i+1))\n" +" done\n" +" case $i in\n" +" (0) set -- ;;\n" +" (1) set -- \"$args0\" ;;\n" +" (2) set -- \"$args0\" \"$args1\" ;;\n" +" (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n" +" (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n" +" (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n" +" (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n" +" (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n" +" (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n" +" (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n" +" esac\n" +"fi\n" +"\n" +"# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules\n" +"function splitJvmOpts() {\n" +" JVM_OPTS=(\"$@\")\n" +"}\n" +"eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\n" +"JVM_OPTS[${#JVM_OPTS[*]}]=\"-Dorg.gradle.appname=$APP_BASE_NAME\"\n" +"\n" +"exec \"$JAVACMD\" \"${JVM_OPTS[@]}\" -classpath \"$CLASSPATH\" org.gradle.wrapper.GradleWrapperMain \"$@\"\n"; + +const char* gradlew = (const char*) temp_binary_data_7; + +//================== gradlew.bat ================== +static const unsigned char temp_binary_data_8[] = +"@if \"%DEBUG%\" == \"\" @echo off\r\n" +"@rem ##########################################################################\r\n" +"@rem\r\n" +"@rem Gradle startup script for Windows\r\n" +"@rem\r\n" +"@rem ##########################################################################\r\n" +"\r\n" +"@rem Set local scope for the variables with windows NT shell\r\n" +"if \"%OS%\"==\"Windows_NT\" setlocal\r\n" +"\r\n" +"@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r\n" +"set DEFAULT_JVM_OPTS=\r\n" +"\r\n" +"set DIRNAME=%~dp0\r\n" +"if \"%DIRNAME%\" == \"\" set DIRNAME=.\r\n" +"set APP_BASE_NAME=%~n0\r\n" +"set APP_HOME=%DIRNAME%\r\n" +"\r\n" +"@rem Find java.exe\r\n" +"if defined JAVA_HOME goto findJavaFromJavaHome\r\n" +"\r\n" +"set JAVA_EXE=java.exe\r\n" +"%JAVA_EXE% -version >NUL 2>&1\r\n" +"if \"%ERRORLEVEL%\" == \"0\" goto init\r\n" +"\r\n" +"echo.\r\n" +"echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r\n" +"echo.\r\n" +"echo Please set the JAVA_HOME variable in your environment to match the\r\n" +"echo location of your Java installation.\r\n" +"\r\n" +"goto fail\r\n" +"\r\n" +":findJavaFromJavaHome\r\n" +"set JAVA_HOME=%JAVA_HOME:\"=%\r\n" +"set JAVA_EXE=%JAVA_HOME%/bin/java.exe\r\n" +"\r\n" +"if exist \"%JAVA_EXE%\" goto init\r\n" +"\r\n" +"echo.\r\n" +"echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r\n" +"echo.\r\n" +"echo Please set the JAVA_HOME variable in your environment to match the\r\n" +"echo location of your Java installation.\r\n" +"\r\n" +"goto fail\r\n" +"\r\n" +":init\r\n" +"@rem Get command-line arguments, handling Windowz variants\r\n" +"\r\n" +"if not \"%OS%\" == \"Windows_NT\" goto win9xME_args\r\n" +"if \"%@eval[2+2]\" == \"4\" goto 4NT_args\r\n" +"\r\n" +":win9xME_args\r\n" +"@rem Slurp the command line arguments.\r\n" +"set CMD_LINE_ARGS=\r\n" +"set _SKIP=2\r\n" +"\r\n" +":win9xME_args_slurp\r\n" +"if \"x%~1\" == \"x\" goto execute\r\n" +"\r\n" +"set CMD_LINE_ARGS=%*\r\n" +"goto execute\r\n" +"\r\n" +":4NT_args\r\n" +"@rem Get arguments from the 4NT Shell from JP Software\r\n" +"set CMD_LINE_ARGS=%$\r\n" +"\r\n" +":execute\r\n" +"@rem Setup the command line\r\n" +"\r\n" +"set CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\r\n" +"\r\n" +"@rem Execute Gradle\r\n" +"\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\r\n" +"\r\n" +":end\r\n" +"@rem End local scope for the variables with windows NT shell\r\n" +"if \"%ERRORLEVEL%\"==\"0\" goto mainEnd\r\n" +"\r\n" +":fail\r\n" +"rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r\n" +"rem the _cmd.exe /c_ return code!\r\n" +"if not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\r\n" +"exit /b 1\r\n" +"\r\n" +":mainEnd\r\n" +"if \"%OS%\"==\"Windows_NT\" endlocal\r\n" +"\r\n" +":omega\r\n"; + +const char* gradlew_bat = (const char*) temp_binary_data_8; + +//================== LICENSE ================== +static const unsigned char temp_binary_data_9[] = +"Apache License\n" +" Version 2.0, January 2004\n" +" http://www.apache.org/licenses/\n" +"\n" +" TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n" +"\n" +" 1. Definitions.\n" +"\n" +" \"License\" shall mean the terms and conditions for use, reproduction,\n" +" and distribution as defined by Sections 1 through 9 of this document.\n" +"\n" +" \"Licensor\" shall mean the copyright owner or entity authorized by\n" +" the copyright owner that is granting the License.\n" +"\n" +" \"Legal Entity\" shall mean the union of the acting entity and all\n" +" other entities that control, are controlled by, or are under common\n" +" control with that entity. For the purposes of this definition,\n" +" \"control\" means (i) the power, direct or indirect, to cause the\n" +" direction or management of such entity, whether by contract or\n" +" otherwise, or (ii) ownership of fifty percent (50%) or more of the\n" +" outstanding shares, or (iii) beneficial ownership of such entity.\n" +"\n" +" \"You\" (or \"Your\") shall mean an individual or Legal Entity\n" +" exercising permissions granted by this License.\n" +"\n" +" \"Source\" form shall mean the preferred form for making modifications,\n" +" including but not limited to software source code, documentation\n" +" source, and configuration files.\n" +"\n" +" \"Object\" form shall mean any form resulting from mechanical\n" +" transformation or translation of a Source form, including but\n" +" not limited to compiled object code, generated documentation,\n" +" and conversions to other media types.\n" +"\n" +" \"Work\" shall mean the work of authorship, whether in Source or\n" +" Object form, made available under the License, as indicated by a\n" +" copyright notice that is included in or attached to the work\n" +" (an example is provided in the Appendix below).\n" +"\n" +" \"Derivative Works\" shall mean any work, whether in Source or Object\n" +" form, that is based on (or derived from) the Work and for which the\n" +" editorial revisions, annotations, elaborations, or other modifications\n" +" represent, as a whole, an original work of authorship. For the purposes\n" +" of this License, Derivative Works shall not include works that remain\n" +" separable from, or merely link (or bind by name) to the interfaces of,\n" +" the Work and Derivative Works thereof.\n" +"\n" +" \"Contribution\" shall mean any work of authorship, including\n" +" the original version of the Work and any modifications or additions\n" +" to that Work or Derivative Works thereof, that is intentionally\n" +" submitted to Licensor for inclusion in the Work by the copyright owner\n" +" or by an individual or Legal Entity authorized to submit on behalf of\n" +" the copyright owner. For the purposes of this definition, \"submitted\"\n" +" means any form of electronic, verbal, or written communication sent\n" +" to the Licensor or its representatives, including but not limited to\n" +" communication on electronic mailing lists, source code control systems,\n" +" and issue tracking systems that are managed by, or on behalf of, the\n" +" Licensor for the purpose of discussing and improving the Work, but\n" +" excluding communication that is conspicuously marked or otherwise\n" +" designated in writing by the copyright owner as \"Not a Contribution.\"\n" +"\n" +" \"Contributor\" shall mean Licensor and any individual or Legal Entity\n" +" on behalf of whom a Contribution has been received by Licensor and\n" +" subsequently incorporated within the Work.\n" +"\n" +" 2. Grant of Copyright License. Subject to the terms and conditions of\n" +" this License, each Contributor hereby grants to You a perpetual,\n" +" worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n" +" copyright license to reproduce, prepare Derivative Works of,\n" +" publicly display, publicly perform, sublicense, and distribute the\n" +" Work and such Derivative Works in Source or Object form.\n" +"\n" +" 3. Grant of Patent License. Subject to the terms and conditions of\n" +" this License, each Contributor hereby grants to You a perpetual,\n" +" worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n" +" (except as stated in this section) patent license to make, have made,\n" +" use, offer to sell, sell, import, and otherwise transfer the Work,\n" +" where such license applies only to those patent claims licensable\n" +" by such Contributor that are necessarily infringed by their\n" +" Contribution(s) alone or by combination of their Contribution(s)\n" +" with the Work to which such Contribution(s) was submitted. If You\n" +" institute patent litigation against any entity (including a\n" +" cross-claim or counterclaim in a lawsuit) alleging that the Work\n" +" or a Contribution incorporated within the Work constitutes direct\n" +" or contributory patent infringement, then any patent licenses\n" +" granted to You under this License for that Work shall terminate\n" +" as of the date such litigation is filed.\n" +"\n" +" 4. Redistribution. You may reproduce and distribute copies of the\n" +" Work or Derivative Works thereof in any medium, with or without\n" +" modifications, and in Source or Object form, provided that You\n" +" meet the following conditions:\n" +"\n" +" (a) You must give any other recipients of the Work or\n" +" Derivative Works a copy of this License; and\n" +"\n" +" (b) You must cause any modified files to carry prominent notices\n" +" stating that You changed the files; and\n" +"\n" +" (c) You must retain, in the Source form of any Derivative Works\n" +" that You distribute, all copyright, patent, trademark, and\n" +" attribution notices from the Source form of the Work,\n" +" excluding those notices that do not pertain to any part of\n" +" the Derivative Works; and\n" +"\n" +" (d) If the Work includes a \"NOTICE\" text file as part of its\n" +" distribution, then any Derivative Works that You distribute must\n" +" include a readable copy of the attribution notices contained\n" +" within such NOTICE file, excluding those notices that do not\n" +" pertain to any part of the Derivative Works, in at least one\n" +" of the following places: within a NOTICE text file distributed\n" +" as part of the Derivative Works; within the Source form or\n" +" documentation, if provided along with the Derivative Works; or,\n" +" within a display generated by the Derivative Works, if and\n" +" wherever such third-party notices normally appear. The contents\n" +" of the NOTICE file are for informational purposes only and\n" +" do not modify the License. You may add Your own attribution\n" +" notices within Derivative Works that You distribute, alongside\n" +" or as an addendum to the NOTICE text from the Work, provided\n" +" that such additional attribution notices cannot be construed\n" +" as modifying the License.\n" +"\n" +" You may add Your own copyright statement to Your modifications and\n" +" may provide additional or different license terms and conditions\n" +" for use, reproduction, or distribution of Your modifications, or\n" +" for any such Derivative Works as a whole, provided Your use,\n" +" reproduction, and distribution of the Work otherwise complies with\n" +" the conditions stated in this License.\n" +"\n" +" 5. Submission of Contributions. Unless You explicitly state otherwise,\n" +" any Contribution intentionally submitted for inclusion in the Work\n" +" by You to the Licensor shall be under the terms and conditions of\n" +" this License, without any additional terms or conditions.\n" +" Notwithstanding the above, nothing herein shall supersede or modify\n" +" the terms of any separate license agreement you may have executed\n" +" with Licensor regarding such Contributions.\n" +"\n" +" 6. Trademarks. This License does not grant permission to use the trade\n" +" names, trademarks, service marks, or product names of the Licensor,\n" +" except as required for reasonable and customary use in describing the\n" +" origin of the Work and reproducing the content of the NOTICE file.\n" +"\n" +" 7. Disclaimer of Warranty. Unless required by applicable law or\n" +" agreed to in writing, Licensor provides the Work (and each\n" +" Contributor provides its Contributions) on an \"AS IS\" BASIS,\n" +" WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n" +" implied, including, without limitation, any warranties or conditions\n" +" of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n" +" PARTICULAR PURPOSE. You are solely responsible for determining the\n" +" appropriateness of using or redistributing the Work and assume any\n" +" risks associated with Your exercise of permissions under this License.\n" +"\n" +" 8. Limitation of Liability. In no event and under no legal theory,\n" +" whether in tort (including negligence), contract, or otherwise,\n" +" unless required by applicable law (such as deliberate and grossly\n" +" negligent acts) or agreed to in writing, shall any Contributor be\n" +" liable to You for damages, including any direct, indirect, special,\n" +" incidental, or consequential damages of any character arising as a\n" +" result of this License or out of the use or inability to use the\n" +" Work (including but not limited to damages for loss of goodwill,\n" +" work stoppage, computer failure or malfunction, or any and all\n" +" other commercial damages or losses), even if such Contributor\n" +" has been advised of the possibility of such damages.\n" +"\n" +" 9. Accepting Warranty or Additional Liability. While redistributing\n" +" the Work or Derivative Works thereof, You may choose to offer,\n" +" and charge a fee for, acceptance of support, warranty, indemnity,\n" +" or other liability obligations and/or rights consistent with this\n" +" License. However, in accepting such obligations, You may act only\n" +" on Your own behalf and on Your sole responsibility, not on behalf\n" +" of any other Contributor, and only if You agree to indemnify,\n" +" defend, and hold each Contributor harmless for any liability\n" +" incurred by, or claims asserted against, such Contributor by reason\n" +" of your accepting any such warranty or additional liability.\n" +"\n" +" END OF TERMS AND CONDITIONS\n" +"\n" +" APPENDIX: How to apply the Apache License to your work.\n" +"\n" +" To apply the Apache License to your work, attach the following\n" +" boilerplate notice, with the fields enclosed by brackets \"{}\"\n" +" replaced with your own identifying information. (Don't include\n" +" the brackets!) The text should be enclosed in the appropriate\n" +" comment syntax for the file format. We also recommend that a\n" +" file or class name and description of purpose be included on the\n" +" same \"printed page\" as the copyright notice for easier\n" +" identification within third-party archives.\n" +"\n" +" Copyright {yyyy} {name of copyright owner}\n" +"\n" +" Licensed under the Apache License, Version 2.0 (the \"License\");\n" +" you may not use this file except in compliance with the License.\n" +" You may obtain a copy of the License at\n" +"\n" +" http://www.apache.org/licenses/LICENSE-2.0\n" +"\n" +" Unless required by applicable law or agreed to in writing, software\n" +" distributed under the License is distributed on an \"AS IS\" BASIS,\n" +" WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" +" See the License for the specific language governing permissions and\n" +" limitations under the License.\n" +"\n"; + +const char* LICENSE = (const char*) temp_binary_data_9; + +//================== background_logo.svg ================== +static const unsigned char temp_binary_data_10[] = +"<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" +"<svg version=\"1.1\" id=\"Layer_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"\r\n" +"\t viewBox=\"0 0 451.7 451.7\" enable-background=\"new 0 0 451.7 451.7\" xml:space=\"preserve\">\r\n" +"<g>\r\n" +"\t<g>\r\n" +"\t\t<path fill=\"#808285\" d=\"M111.8,421.9c-8.7,0-15.6-3.2-21.8-11.3l8.5-7.3c4.2,5.5,8.2,7.6,13.3,7.6c9.2,0,15.5-6.9,15.5-17.5v-51.8\r\n" +"\t\t\th11.7v51.8C138.9,410.4,127.7,421.9,111.8,421.9z\"/>\r\n" +"\t\t<path fill=\"#808285\" d=\"M185.7,421.9c-17,0-31.6-12.5-31.6-33.1v-47.2h11.7v46.6c0,13.8,8.2,22.8,19.9,22.8c11.7,0,20-8.9,20-22.8\r\n" +"\t\t\tv-46.6h11.7v47.2C217.4,409.4,202.7,421.9,185.7,421.9z\"/>\r\n" +"\t\t<path fill=\"#808285\" d=\"M268.9,421.9c-22.6,0-40.9-18.1-40.9-40.6c0-22.6,18.5-40.6,40.9-40.6c10,0,18.8,3.5,25.7,9.2l-6.9,8.6\r\n" +"\t\t\tc-7.1-5-12-6.8-18.7-6.8c-16.2,0-29.1,13-29.1,29.7c0,16.7,12.9,29.7,29.1,29.7c6.4,0,11.8-2,18.6-6.7l7,8.7\r\n" +"\t\t\tC285.9,419.6,278.1,421.9,268.9,421.9z\"/>\r\n" +"\t\t<path fill=\"#808285\" d=\"M307.5,420.9v-79.3h47.8v10.5h-36.1v23.5h34.7V386h-34.7v24.4h36.1v10.5H307.5z\"/>\r\n" +"\t</g>\r\n" +"</g>\r\n" +"<g>\r\n" +"\t<path fill=\"#808285\" d=\"M222.6,313.3c-78.2,0-141.7-63.6-141.7-141.7S144.5,29.8,222.6,29.8s141.7,63.6,141.7,141.7\r\n" +"\t\tS300.8,313.3,222.6,313.3z M222.6,39.3c-72.9,0-132.3,59.3-132.3,132.3s59.3,132.3,132.3,132.3s132.3-59.3,132.3-132.3\r\n" +"\t\tS295.6,39.3,222.6,39.3z\"/>\r\n" +"\t<path fill=\"#414042\" d=\"M334.5,166.8c2.4,0,4.8-0.9,6.5-2.6c1.9-1.9,2.7-4.4,2.4-7c-2.6-22.2-11.4-43.3-25.3-60.9\r\n" +"\t\tc-1.7-2.2-4.1-3.3-6.6-3.3c-2.3,0-4.5,1-6.2,2.7L236.9,164c-1.1,1.1-0.3,2.9,1.2,2.9L334.5,166.8z\"/>\r\n" +"\t<path fill=\"#58595B\" d=\"M311.5,250.2L311.5,250.2c2.6,0,4.9-1.2,6.6-3.3c13.9-17.6,22.6-38.7,25.3-60.9c0.3-2.6-0.6-5.1-2.4-7\r\n" +"\t\tc-1.7-1.7-4.1-2.6-6.5-2.6l-96.4,0c-1.5,0-2.2,1.8-1.2,2.9l68.4,68.4C307,249.2,309.2,250.2,311.5,250.2z\"/>\r\n" +"\t<path fill=\"#6D6E71\" d=\"M229.9,290L229.9,290c1.8,1.8,4.3,2.7,7.1,2.3c22.3-2.6,43.4-11.3,60.9-25.2c2.1-1.6,3.2-4,3.3-6.7\r\n" +"\t\tc0-2.4-1-4.7-2.8-6.4l-68.1-68.1c-1.1-1.1-2.9-0.3-2.9,1.2l0,96.7C227.4,286.1,228.2,288.4,229.9,290z\"/>\r\n" +"\t<path fill=\"#A7A9AC\" d=\"M133.8,92.9c-2.6,0-4.9,1.2-6.6,3.3c-13.9,17.6-22.6,38.7-25.3,60.9c-0.3,2.6,0.6,5.1,2.4,7\r\n" +"\t\tc1.7,1.7,4.1,2.6,6.5,2.6l96.4,0c1.5,0,2.2-1.8,1.2-2.9L140,95.6C138.3,93.9,136.1,92.9,133.8,92.9z\"/>\r\n" +"\t<path fill=\"#BCBEC0\" d=\"M215.4,53.1c-1.8-1.8-4.3-2.7-7.1-2.3C186.1,53.4,165,62.1,147.4,76c-2.1,1.6-3.2,4-3.3,6.7\r\n" +"\t\tc0,2.4,1,4.7,2.8,6.4l68.1,68.1c1.1,1.1,2.9,0.3,2.9-1.2l0-96.7C217.9,57,217,54.8,215.4,53.1z\"/>\r\n" +"\t<path fill=\"#D1D3D4\" d=\"M301.3,82.7c0-2.6-1.2-4.9-3.3-6.6c-17.6-13.9-38.7-22.6-60.9-25.3c-2.6-0.3-5.1,0.6-7,2.4\r\n" +"\t\tc-1.7,1.7-2.6,4.1-2.6,6.5l0,96.4c0,1.5,1.8,2.2,2.9,1.2l68.4-68.4C300.3,87.2,301.3,85,301.3,82.7z\"/>\r\n" +"\t<path fill=\"#939598\" d=\"M207.2,176.3l-96.4,0c-2.4,0-4.8,0.9-6.5,2.6c-1.9,1.9-2.7,4.4-2.4,7c2.6,22.2,11.4,43.3,25.3,60.9\r\n" +"\t\tc1.7,2.2,4.1,3.3,6.6,3.3c2.3,0,4.5-1,6.2-2.7c0,0,0,0,0,0l68.4-68.4C209.4,178.1,208.7,176.3,207.2,176.3z\"/>\r\n" +"\t<path fill=\"#808285\" d=\"M215.1,185.8L146.9,254c-1.7,1.7-2.8,4-2.8,6.4c0,2.7,1.2,5.1,3.3,6.7c17.6,13.9,38.6,22.6,60.9,25.2\r\n" +"\t\tc2.7,0.3,5.2-0.5,7.1-2.3c1.6-1.6,2.5-3.8,2.5-6.3c0,0,0,0,0,0l0-96.7C217.9,185.5,216.1,184.8,215.1,185.8z\"/>\r\n" +"</g>\r\n" +"</svg>\r\n"; + +const char* background_logo_svg = (const char*) temp_binary_data_10; + +//================== export_android.svg ================== +static const unsigned char temp_binary_data_11[] = +"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +"<svg width=\"19px\" height=\"23px\" viewBox=\"0 0 19 23\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n" +" <!-- Generator: Sketch 43.1 (39012) - http://www.bohemiancoding.com/sketch -->\n" +" <title>androd</title>\n" +" <desc>Created with Sketch.</desc>\n" +" <defs></defs>\n" +" <g id=\"Page-1\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n" +" <g id=\"Artboard\" transform=\"translate(-71.000000, -8.000000)\" fill-rule=\"nonzero\">\n" +" <g id=\"android\" transform=\"translate(67.000000, 6.000000)\">\n" +" <g id=\"androd\" transform=\"translate(4.149701, 2.592000)\">\n" +" <path d=\"M12.0887784,1.906092 L13.1751916,0.325404 C13.2397006,0.231444 13.2236407,0.108108 13.1392994,0.049788 C13.0550659,-0.008208 12.9342395,0.020466 12.8702156,0.114534 L11.7411198,1.75662 C10.9970299,1.462914 10.1707545,1.2" +"9924 9.29985629,1.29924 C8.42895808,1.29924 7.60246707,1.462752 6.85843114,1.75662 L5.72949701,0.11448 C5.66477246,0.02052 5.54416168,-0.008262 5.45987425,0.049734 C5.37558683,0.107892 5.35958084,0.231282 5.42408982,0.32535 L6.51088024,1.906038 C4.78" +"293413,2.711502 3.57116766,4.242078 3.41676647,6.028398 L15.1822994,6.028398 C15.0284371,4.242078 13.8166168,2.711556 12.0887784,1.906092\" id=\"Shape\" fill=\"#9FBF3B\"></path>\n" +" <path d=\"M6.84194012,4.397652 C6.48231737,4.397652 6.19092216,4.105674 6.19092216,3.745386 C6.19092216,3.385152 6.48215569,3.093066 6.84194012,3.093066 C7.20129341,3.093066 7.49258084,3.385044 7.49258084,3.745386 C7.49263473,4.10" +"562 7.20129341,4.397652 6.84194012,4.397652\" id=\"Shape\" fill=\"#FFFFFF\"></path>\n" +" <path d=\"M11.7571796,4.397652 C11.3978263,4.397652 11.106485,4.105674 11.106485,3.745386 C11.106485,3.385044 11.3978263,3.093066 11.7571796,3.093066 C12.1169102,3.093066 12.4081437,3.385152 12.4081437,3.745386 C12.4081437,4.10562" +" 12.1168024,4.397652 11.7571796,4.397652\" id=\"Shape\" fill=\"#FFFFFF\"></path>\n" +" <path d=\"M2.66135928,13.478292 C2.66135928,14.204592 2.07371856,14.793408 1.34881437,14.793408 L1.34881437,14.793408 C0.623964072,14.793408 0.0363233533,14.204592 0.0363233533,13.478292 L0.0363233533,8.15886 C0.0363233533,7.43256" +" 0.623964072,6.843744 1.34881437,6.843744 L1.34881437,6.843744 C2.07371856,6.843744 2.66135928,7.43256 2.66135928,8.15886 L2.66135928,13.478292 Z\" id=\"Shape\" fill=\"#9FBF3B\"></path>\n" +" <path d=\"M3.4165509,6.884406 L3.4165509,16.491816 C3.4165509,17.06238 3.87819162,17.524998 4.44777844,17.524998 L5.66752096,17.524998 L5.66752096,20.481174 C5.66752096,21.207528 6.25510778,21.79629 6.98001198,21.79629 C7.70491617" +",21.79629 8.29255689,21.207528 8.29255689,20.481174 L8.29255689,17.524998 L10.3065629,17.524998 L10.3065629,20.481174 C10.3065629,21.207528 10.8940958,21.79629 11.6190539,21.79629 C12.344012,21.79629 12.9315449,21.207528 12.9315449,20.481174 L12.9315" +"449,17.524998 L14.1512874,17.524998 C14.7208743,17.524998 15.1826228,17.06265 15.1826228,16.491816 L15.1826228,6.884406 L3.4165509,6.884406 Z\" id=\"Shape\" fill=\"#9FBF3B\"></path>\n" +" <path d=\"M15.9377605,13.478292 C15.9377605,14.204592 16.5253473,14.793408 17.2502515,14.793408 L17.2502515,14.793408 C17.9751018,14.793408 18.5627425,14.204592 18.5627425,13.478292 L18.5627425,8.15886 C18.5627425,7.43256 17.97510" +"18,6.843744 17.2502515,6.843744 L17.2502515,6.843744 C16.5253473,6.843744 15.9377605,7.43256 15.9377605,8.15886 L15.9377605,13.478292 Z\" id=\"Shape\" fill=\"#9FBF3B\"></path>\n" +" </g>\n" +" </g>\n" +" </g>\n" +" </g>\n" +"</svg>"; + +const char* export_android_svg = (const char*) temp_binary_data_11; + +//================== export_clion.svg ================== +static const unsigned char temp_binary_data_12[] = +"<svg id=\"Layer_1\" data-name=\"Layer 1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 128 128\">\n" +" <defs>\n" +" <linearGradient id=\"linear-gradient\" x1=\"40.69\" y1=\"-676.56\" x2=\"83.48\" y2=\"-676.56\" gradientTransform=\"matrix(1, 0, 0, -1, 0, -648.86)\" gradientUnits=\"userSpaceOnUse\">\n" +" <stop offset=\"0\" stop-color=\"#ed358c\"/>\n" +" <stop offset=\"0.16\" stop-color=\"#e9388c\"/>\n" +" <stop offset=\"0.3\" stop-color=\"#de418c\"/>\n" +" <stop offset=\"0.43\" stop-color=\"#cc508c\"/>\n" +" <stop offset=\"0.57\" stop-color=\"#b2658d\"/>\n" +" <stop offset=\"0.7\" stop-color=\"#90808d\"/>\n" +" <stop offset=\"0.83\" stop-color=\"#67a18e\"/>\n" +" <stop offset=\"0.95\" stop-color=\"#37c78f\"/>\n" +" <stop offset=\"1\" stop-color=\"#22d88f\"/>\n" +" </linearGradient>\n" +" <linearGradient id=\"linear-gradient-2\" x1=\"32.58\" y1=\"-665.27\" x2=\"13.76\" y2=\"-791.59\" gradientTransform=\"matrix(1, 0, 0, -1, 0, -648.86)\" gradientUnits=\"userSpaceOnUse\">\n" +" <stop offset=\"0.09\" stop-color=\"#22d88f\"/>\n" +" <stop offset=\"0.9\" stop-color=\"#029de0\"/>\n" +" </linearGradient>\n" +" <linearGradient id=\"linear-gradient-3\" x1=\"116.68\" y1=\"-660.66\" x2=\"-12.09\" y2=\"-796.66\" xlink:href=\"#linear-gradient-2\"/>\n" +" <linearGradient id=\"linear-gradient-4\" x1=\"73.35\" y1=\"-739.1\" x2=\"122.29\" y2=\"-746.06\" xlink:href=\"#linear-gradient-2\"/>\n" +" </defs>\n" +" <title>icon_CLion</title>\n" +" <g>\n" +" <polygon points=\"49.2 51.8 40.6 55.4 48.4 0 77.8 16.2 49.2 51.8\" fill=\"url(#linear-gradient)\"/>\n" +" <polygon points=\"44.6 76.8 48.8 0 11.8 23.2 0 94 44.6 76.8\" fill=\"url(#linear-gradient-2)\"/>\n" +" <polygon points=\"125.4 38.4 109 4.8 77.8 16.2 55 41.4 0 94 41.6 124.4 93.6 77.2 125.4 38.4\" fill=\"url(#linear-gradient-3)\"/>\n" +" <polygon points=\"53.8 54.6 46.6 98.4 75.8 121 107.8 128 128 82.4 53.8 54.6\" fill=\"url(#linear-gradient-4)\"/>\n" +" </g>\n" +" <g>\n" +" <rect x=\"24\" y=\"24\" width=\"80\" height=\"80\"/>\n" +" <rect x=\"31.6\" y=\"89\" width=\"30\" height=\"5\" fill=\"#fff\"/>\n" +" <path d=\"M31,51.2h0A16.83,16.83,0,0,1,48.2,34c6.2,0,10,2,13,5.2l-4.6,5.4c-2.6-2.4-5.2-3.8-8.4-3.8-5.6,0-9.6,4.6-9.6,10.4h0c0,5.6,4,10.4,9.6,10.4,3.8,0,6.2-1.6,8.8-3.8l4.6,4.6c-3.4,3.6-7.2,6-13.6,6A17,17,0,0,1,31,51.2\" fill=\"#fff\"/>\n" +" <path d=\"M66.6,34.4H74v27H88.4v6.2H66.6V34.4Z\" fill=\"#fff\"/>\n" +" </g>\n" +"</svg>\n"; + +const char* export_clion_svg = (const char*) temp_binary_data_12; + +//================== export_codeBlocks.svg ================== +static const unsigned char temp_binary_data_13[] = +"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +"<svg width=\"20px\" height=\"20px\" viewBox=\"0 0 20 20\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n" +" <!-- Generator: Sketch 43.1 (39012) - http://www.bohemiancoding.com/sketch -->\n" +" <title>Group</title>\n" +" <desc>Created with Sketch.</desc>\n" +" <defs></defs>\n" +" <g id=\"Page-1\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n" +" <g id=\"Artboard\" transform=\"translate(-33.000000, -4.000000)\">\n" +" <g id=\"Group\" transform=\"translate(33.000000, 4.000000)\">\n" +" <polygon id=\"Rectangle-5-Copy-4\" fill=\"#FD3535\" points=\"7.36842105 -1.87919855e-13 9.47368421 4.21052632 9.47368421 9.47368421 4.21052632 9.47368421 6.83692868e-14 7.36842105 3.55271368e-15 -1.67409946e-14\"></polygon>\n" +" <polygon id=\"Rectangle-5-Copy-5\" fill=\"#6AC300\" transform=\"translate(15.263158, 4.736842) scale(-1, 1) translate(-15.263158, -4.736842) \" points=\"17.8947368 -1.87919855e-13 20 4.21052632 20 9.47368421 14.7368421 9.47368421 10.5" +"263158 7.36842105 10.5263158 -1.67409946e-14\"></polygon>\n" +" <polygon id=\"Rectangle-5-Copy-7\" fill=\"#EBBF20\" transform=\"translate(4.736842, 15.263158) scale(1, -1) translate(-4.736842, -15.263158) \" points=\"7.36842105 10.5263158 9.47368421 14.7368421 9.47368421 20 4.21052632 20 6.8369286" +"8e-14 17.8947368 3.55271368e-15 10.5263158\"></polygon>\n" +" <polygon id=\"Rectangle-5-Copy-6\" fill=\"#1F6CE9\" transform=\"translate(15.263158, 15.263158) scale(-1, -1) translate(-15.263158, -15.263158) \" points=\"17.8947368 10.5263158 20 14.7368421 20 20 14.7368421 20 10.5263158 17.8947368 " +"10.5263158 10.5263158\"></polygon>\n" +" </g>\n" +" </g>\n" +" </g>\n" +"</svg>"; + +const char* export_codeBlocks_svg = (const char*) temp_binary_data_13; + +//================== export_linux.svg ================== +static const unsigned char temp_binary_data_14[] = +"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +"<svg width=\"63px\" height=\"75px\" viewBox=\"0 0 63 75\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n" +" <!-- Generator: Sketch 43.1 (39012) - http://www.bohemiancoding.com/sketch -->\n" +" <title>Android</title>\n" +" <desc>Created with Sketch.</desc>\n" +" <defs></defs>\n" +" <g id=\"Page-1\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n" +" <g id=\"Artboard\" transform=\"translate(-115.000000, -15.000000)\" fill-rule=\"nonzero\">\n" +" <g id=\"Android\" transform=\"translate(115.000000, 15.000000)\">\n" +" <path d=\"M46.1535022,26.1203623 C46.9768865,27.8918861 47.8751239,29.6135078 48.6735572,31.3850316 C50.2205216,34.8033239 51.3932204,38.3962736 51.8922412,42.1139784 C52.391262,45.8316832 52.1667026,49.6741432 50.9940038,53.2171908 C" +"49.6715987,57.2343081 47.2014459,60.8023067 44.1324681,63.7465293 C40.5145674,67.2147237 35.8986252,69.8844849 30.8834663,70.0840932 C27.6148802,70.2088484 24.3712451,69.28566 21.5018756,67.7636466 C19.0816248,66.4911436 16.8609823,64.7944729 15.0894" +"586,62.6985856 C13.3179348,60.6026983 12.0204807,58.1075944 11.3967048,55.4378333 C10.6481736,52.1442961 10.9974881,48.6511506 12.1202849,45.4823687 C12.9187182,43.2118241 14.116368,41.0909858 14.9896544,38.8453923 C15.9128428,36.3752394 16.4368147,3" +"3.7553803 17.6843666,31.4099826 C18.8071634,29.2891443 20.478883,27.4926695 21.3771204,25.272027 C21.9010922,23.9496219 22.1506026,22.5274127 22.4749661,21.1301545 C22.8242807,19.7328963 23.2983504,18.3605892 24.2464899,17.2627434 C25.3692867,15.9652" +"894 27.0659573,15.2666603 28.787579,15.067052 C30.4842497,14.8674437 32.2308224,15.1419051 33.902542,15.5161707 C35.2498981,15.8155832 36.5473522,16.1898488 37.8448062,16.6639185 C38.9426519,17.0631351 40.0404976,17.5122538 40.9886371,18.1859319 C42." +"2860912,19.1091203 43.2841327,20.4065744 44.0576149,21.8038326 C44.8310972,23.2010907 45.5047752,24.6732021 46.1535022,26.1203623\" id=\"path29670-2\" fill=\"#020204\"></path>\n" +" <path d=\"M32.3071772,70.3379664 C33.6794843,70.4128195 35.0517915,70.5625257 36.3991476,70.7621341 C37.5967974,70.9367913 38.7694963,71.1863017 39.9671462,71.4607632 C41.813523,71.9098819 43.6349489,72.4837558 45.5312279,72.5336578 C" +"46.0302487,72.5586089 46.5292694,72.5336578 47.0282902,72.4089026 C47.527311,72.3090985 47.9764297,72.1094902 48.3756463,71.7851267 C48.9495202,71.3110569 49.3237858,70.6124278 49.4734921,69.8888477 C49.6231983,69.1652676 49.5233941,68.3917853 49.323" +"7858,67.6931563 C48.8996182,66.270947 47.9764297,65.0483461 47.2278985,63.7758431 C46.8037309,63.052263 46.4045142,62.2787808 45.9304445,61.5801517 C45.4563748,60.8815226 44.8825009,60.2078445 44.1838718,59.7587258 C43.1858302,59.1099988 41.9632293,5" +"8.9103905 40.7905304,59.0351457 C39.6178316,59.1599009 38.4950348,59.5840685 37.4470912,60.1080404 C35.9749799,60.8565715 34.6026728,61.9045152 33.8042395,63.3516754 C33.5297781,63.8506962 33.3301698,64.3996191 33.0806594,64.9235909 C32.8561,65.44756" +"27 32.5566875,65.9715346 32.1574709,66.3707512 C31.7083522,66.8198699 31.1344783,67.1442334 30.6604086,67.5933521 C30.4358492,67.8179114 30.2362409,68.0674218 30.1114857,68.3668343 C29.9867305,68.6662468 29.9617795,69.0155613 30.0615836,69.3149738 C3" +"0.1364368,69.5145821 30.2611919,69.7141904 30.4358492,69.8389456 C30.6105065,69.9886518 30.8101148,70.088456 31.0097231,70.1633091 C31.4338908,70.2880643 31.8830095,70.3130154 32.3071772,70.3379664\" id=\"path29676-3\" fill=\"#020204\"></path>\n" +" <path d=\"M27.9409416,70.2361543 C26.7931938,70.2611053 25.6703971,70.4607136 24.5476003,70.710224 C23.4747056,70.9347834 22.401811,71.1842938 21.3538673,71.4587552 C19.5573925,71.9328249 17.7858687,72.4817478 15.9394918,72.5316499 C1" +"5.4654221,72.5316499 14.9664013,72.5066988 14.4923316,72.4068947 C14.0182618,72.3070905 13.5691431,72.1074822 13.1699265,71.8080697 C12.5960526,71.334 12.221787,70.6603219 12.0720808,69.9117908 C11.9223745,69.1632596 12.0221787,68.4147284 12.221787,6" +"7.7160993 C12.6459547,66.2938901 13.5441921,65.0712892 14.2927233,63.7987862 C14.7168909,63.0752061 15.0911565,62.3017238 15.5402752,61.6030947 C15.9893939,60.9044656 16.5383168,60.2307876 17.2618969,59.7567179 C18.2100364,59.1329419 19.4076863,58.90" +"83825 20.5554341,59.0331377 C21.7031819,59.1578929 22.8010276,59.5571095 23.7990692,60.1060324 C25.2212784,60.8795146 26.5187324,61.9524093 27.3421167,63.3496675 C27.9159906,64.322758 28.2653052,65.4455548 28.9389832,66.3687432 C29.3132488,66.867764 " +"29.7623675,67.2919317 30.06178,67.8159035 C30.2114862,68.0903649 30.3112904,68.3648263 30.3611924,68.6891898 C30.3861435,68.9886023 30.3112904,69.3129658 30.1615841,69.5624762 C30.0368289,69.7371335 29.8871227,69.8618887 29.7124654,69.9616928 C29.537" +"8081,70.061497 29.3381998,70.1363501 29.1385915,70.1613012 C28.7643259,70.2361543 28.3401583,70.2361543 27.9409416,70.2361543\" id=\"path29676-7-1\" fill=\"#020204\"></path>\n" +" <path d=\"M21.3925244,22.15769 C21.2428181,20.211509 21.2677692,18.290279 21.192916,16.3440979 C21.1180629,14.47277 20.9434057,12.6263931 21.0182588,10.7550652 C21.0931119,8.85878618 21.3925244,6.93755617 22.2408597,5.24088552 C23.089" +"195,3.54421486 24.4615022,2.09705459 26.1332218,1.19881718 C27.7051373,0.350481853 29.5265631,-0.0237837335 31.2980869,0.0011673056 C33.7183377,0.0261183447 36.1635395,0.749698478 38.1097206,2.17190771 C39.3323215,3.07014511 40.3802651,4.21789291 41." +"2036494,5.49039591 C41.9022785,6.58824163 42.4512014,7.7858915 42.7755649,9.03344346 C43.474194,11.6034005 43.2995367,14.2981127 43.4492429,16.9678739 C43.5739981,19.4879288 43.9732147,22.0079838 43.8484595,24.5280387 C43.8235085,25.0769616 43.748655" +"4,25.6258845 43.524096,26.1249052 C43.2745856,26.598975 42.875369,26.9981916 42.4262503,27.247702 C41.9521806,27.5221634 41.4531598,27.6718697 40.9042369,27.7467228 C39.8562933,27.9213801 38.7833986,27.7966249 37.7105039,27.896429 C36.1635395,28.0461" +"352 34.6914282,28.6200091 33.1694148,28.8445685 C31.347989,29.1190299 29.476661,28.9194216 27.6552352,28.8445685 C26.906704,28.8196175 26.1831239,28.7946664 25.4345927,28.7198133 C24.7110126,28.6200091 23.9624814,28.4453519 23.3137544,28.0960373 C22." +"9145377,27.871478 22.5402722,27.5970165 22.2408597,27.272653 C21.9414472,26.9233385 21.7168879,26.5241219 21.5921327,26.0750032 C21.4174754,25.4013251 21.5172796,24.727647 21.5172796,24.029018 C21.5172796,23.405242 21.4424264,22.781466 21.3925244,22." +"15769\" id=\"path28712-2\" fill=\"#020204\"></path>\n" +" <path d=\"M24.4857731,22.0829382 C24.2362627,22.4073017 24.0616054,22.8065184 23.9618013,23.205735 C23.8619971,23.6049516 23.812095,24.0291193 23.812095,24.453287 C23.787144,25.3016223 23.8370461,26.1499576 23.6124867,26.9483909 C23.3" +"879274,27.8216772 22.8390045,28.5702084 22.3150327,29.2937885 C21.4167953,30.5662915 20.5185579,31.8637456 20.0694392,33.3358569 C19.7949777,34.2340943 19.7201246,35.1822338 19.8199288,36.1303733 C18.8218872,37.6024846 17.9486009,39.1744 17.2250207,4" +"0.8211686 C16.127175,43.2913215 15.3786438,45.9361316 15.1041824,48.6308438 C14.7798189,51.924381 15.2039866,55.3426734 16.5014406,58.3867001 C17.4495801,60.5823916 18.8468383,62.6034257 20.6682641,64.1753412 C21.5914526,64.9737744 22.6144452,65.6474" +"525 23.7122909,66.1963754 C27.5048488,68.0677033 32.1956442,68.0677033 35.9383,66.0716202 C37.8844811,65.0236765 39.5312497,63.5016631 41.1281162,61.9796498 C42.0762557,61.0564613 43.0243951,60.1083218 43.7729263,58.9855251 C45.1701845,56.8397357 45." +"6692053,54.2448276 45.9686178,51.6998216 C46.4925896,47.2585367 46.5175406,42.5427903 44.5713596,38.525673 C43.8976815,37.1284148 42.9994441,35.8559118 41.9265494,34.7580661 C41.652088,32.8118851 41.0782141,30.9156061 40.2548298,29.1440823 C39.656004" +"9,27.8466283 38.9324247,26.6240274 38.3835019,25.3265733 C38.1589425,24.8026015 37.9593342,24.2536786 37.7098238,23.7297068 C37.4603134,23.205735 37.160901,22.7067142 36.7367333,22.3074976 C36.3125656,21.908281 35.7636428,21.6088685 35.2147199,21.409" +"2602 C34.640846,21.2346029 34.0669721,21.1347988 33.4681472,21.1098477 C32.2704973,21.0599456 31.0977985,21.2096519 29.9001486,21.1597498 C28.9520091,21.1098477 28.0038696,20.9601415 27.0557301,21.0100436 C26.5816604,21.0349946 26.1075906,21.1347988 " +"25.6584719,21.309456 C25.2093532,21.4841133 24.7851856,21.7086727 24.4857731,22.0829382\" id=\"path29719-5\" fill=\"#FDFDFB\"></path>\n" +" <path d=\"M25.1049189,11.0038778 C24.6558002,11.0288289 24.2316326,11.2284372 23.9072691,11.5278496 C23.5829056,11.8272621 23.3583462,12.2264787 23.20864,12.6506464 C22.9341785,13.4989817 22.9840806,14.4221702 23.0589337,15.2954566 C2" +"3.1088358,16.0938898 23.1836889,16.9172741 23.4831014,17.6658053 C23.6328076,18.0400709 23.857367,18.3893854 24.1318284,18.6887979 C24.4062898,18.9882103 24.7805554,19.1878187 25.154821,19.2876228 C25.5290866,19.387427 25.9033522,19.3624759 26.277617" +"8,19.2377207 C26.6269323,19.1129655 26.9762469,18.9133572 27.2257573,18.6638468 C27.6249739,18.2895812 27.8744843,17.7656094 28.0491416,17.2416376 C28.1988478,16.7176658 28.2487499,16.1437919 28.2487499,15.594869 C28.2487499,14.8962399 28.1489457,14." +"2225619 27.9243864,13.5488838 C27.699827,12.9001568 27.3754635,12.2763808 26.8764427,11.77736 C26.6518834,11.5278496 26.3774219,11.3282413 26.0780095,11.1785351 C25.778597,11.0787309 25.4542335,10.9789268 25.1049189,11.0038778\" id=\"path28795-9-5\" " +"fill=\"#FDFDFB\"></path>\n" +" <path d=\"M32.7547573,11.5576557 C32.0561282,12.0317255 31.4822543,12.7054035 31.2077928,13.5038368 C30.8584783,14.5018783 30.9832335,15.6246751 31.332548,16.6227167 C31.6818626,17.6457093 32.2806875,18.6187998 33.1789249,19.2425758 C" +"33.6280436,19.5419882 34.1520155,19.7665476 34.6759873,19.8164497 C35.2249101,19.8913028 35.773833,19.7914986 36.2479027,19.5419882 C36.8467277,19.2425758 37.2708953,18.6936529 37.5703078,18.094828 C37.8447692,17.496003 37.9695244,16.822325 37.994475" +"5,16.173598 C38.0443776,15.3252626 37.9695244,14.4769273 37.695063,13.678494 C37.3956505,12.8052077 36.8467277,12.0067744 36.0732455,11.5077536 C35.6989799,11.2582433 35.2498612,11.083586 34.8007425,11.0336839 C34.3516238,10.9588308 33.877554,11.0087" +"329 33.4533864,11.1833901 C33.1789249,11.2831943 32.9543656,11.4079495 32.7547573,11.5576557\" id=\"path28795-3\" fill=\"#FDFDFB\"></path>\n" +" <g id=\"g28965-1\" transform=\"translate(33.000000, 13.000000)\" fill=\"#020204\">\n" +" <path d=\"M1.79647481,0.0998041564 C1.54696442,0.124755195 1.27250299,0.199608313 1.04794364,0.349314547 C0.82338429,0.499020782 0.648727016,0.673678056 0.499020782,0.898237407 C0.199608313,1.32240507 0.0748531173,1.84637689 0.049" +"9020782,2.37034871 C0.0249510391,2.76956534 0.0748531173,3.16878196 0.199608313,3.51809651 C0.324363508,3.8923621 0.54892286,4.24167665 0.848335329,4.49118704 C1.1477478,4.74069743 1.54696442,4.89040366 1.94618105,4.9153547 C2.34539767,4.94030574 2.7" +"446143,4.81555055 3.09392885,4.59099119 C3.36839028,4.41633392 3.56799859,4.16682353 3.71770482,3.86741106 C3.86741106,3.59294963 3.96721522,3.26858612 3.99216625,2.94422261 C4.06701937,2.39529975 3.99216625,1.79647481 3.71770482,1.29745403 C3.468194" +"43,0.798433251 3.01907573,0.374265586 2.49510391,0.174657274 C2.27054456,0.124755195 2.02103417,0.0748531173 1.79647481,0.0998041564\" id=\"path28879-6\"></path>\n" +" </g>\n" +" <g id=\"g29497-8\" transform=\"translate(24.000000, 14.000000)\" fill=\"#020204\">\n" +" <path d=\"M0.224559352,1.42220923 C0.124755195,1.97113209 0.124755195,2.56995703 0.324363508,3.09392885 C0.449118704,3.44324339 0.673678056,3.7676069 0.923188446,4.04206833 C1.09784572,4.21672561 1.27250299,4.39138288 1.49706235,4" +".49118704 C1.7216217,4.59099119 1.97113209,4.64089327 2.22064248,4.59099119 C2.44520183,4.54108912 2.64481014,4.39138288 2.76956534,4.21672561 C2.91927157,4.04206833 2.99412469,3.81750898 3.06897781,3.61790067 C3.26858612,2.96917365 3.24363508,2.2705" +"4456 3.04402677,1.64676858 C2.89432053,1.17269884 2.66976118,0.723580134 2.2954956,0.424167665 C2.12083832,0.27446143 1.92123001,0.149706235 1.67171962,0.0998041564 C1.44716027,0.0499020782 1.19764988,0.0499020782 0.998041564,0.149706235 C0.773482212" +",0.249510391 0.573873899,0.449118704 0.474069743,0.698629095 C0.349314547,0.923188446 0.27446143,1.17269884 0.224559352,1.42220923\" id=\"path29453-9\"></path>\n" +" </g>\n" +" <g id=\"g29634-9\" transform=\"translate(22.999845, 16.000000)\">\n" +" <path d=\"M0,5.72292607 C0.0249510391,5.79777918 0.0499020782,5.8726323 0.0748531173,5.92253438 C0.149706235,6.02233853 0.249510391,6.12214269 0.349314547,6.19699581 C0.449118704,6.27184893 0.573873899,6.34670204 0.673678056,6.396" +"60412 C1.24755195,6.77086971 1.7216217,7.26989049 2.14578936,7.81881335 C2.71966326,8.54239348 3.21868404,9.36577777 3.96721522,9.88974959 C4.49118704,10.2640152 5.13991405,10.4885745 5.78864107,10.5384766 C6.56212328,10.6133297 7.31065445,10.4885745" +" 8.05918563,10.2640152 C8.73286368,10.0644069 9.40654174,9.78994544 10.0053667,9.41567985 C11.1531145,8.71705076 12.101254,7.66910712 13.373757,7.19503737 C13.6482184,7.09523322 13.9476309,7.0203801 14.1971412,6.8956249 C14.4716027,6.77086971 14.7211" +"131,6.57126139 14.8458683,6.321751 C14.9706235,6.07224061 14.9706235,5.77282814 14.9955745,5.49836671 C15.0454766,5.19895424 15.1452807,4.89954178 15.1951828,4.60012931 C15.2450849,4.30071684 15.2450849,3.97635333 15.1203297,3.7018919 C15.0205255,3.4" +"7733255 14.8209172,3.30267527 14.5963579,3.17792008 C14.3717985,3.05316488 14.1222881,3.0032628 13.8727777,3.0032628 C13.373757,2.97831177 12.8747362,3.10306696 12.3757154,3.15296904 C11.7269884,3.20287112 11.0533103,3.128018 10.3796323,3.15296904 C9" +".55624797,3.17792008 8.73286368,3.35257735 7.90947939,3.40247943 C6.96133991,3.45238151 6.03815146,3.30267527 5.09001198,3.2527732 C4.69079535,3.22782216 4.26662769,3.22782216 3.86741106,3.30267527 C3.46819443,3.37752839 3.06897781,3.50228359 2.74461" +"43,3.75179398 C2.42025079,3.97635333 2.14578936,4.2757658 1.84637689,4.55022723 C1.69667066,4.67498242 1.54696442,4.79973762 1.34735611,4.87459074 C1.1477478,4.94944385 0.973090525,5.02429697 0.773482212,4.99934593 C0.673678056,4.99934593 0.573873899" +",4.97439489 0.474069743,4.99934593 C0.424167665,5.02429697 0.349314547,5.04924801 0.324363508,5.09915009 C0.299412469,5.14905217 0.249510391,5.19895424 0.199608313,5.24885632 C0.124755195,5.44846464 0.0499020782,5.57321983 0,5.72292607\" id=\"path284" +"61-2\" fill=\"#FFB510\"></path>\n" +" <g id=\"path27476-7-8\" transform=\"translate(0.000000, 3.000000)\" fill=\"#604405\">\n" +" <path d=\"M1.52201338,1.32240507 C1.19764988,1.52201338 0.873286368,1.74657274 0.54892286,1.97113209 C0.374265586,2.09588728 0.224559352,2.22064248 0.124755195,2.39529975 C0.0748531173,2.52005495 0.0499020782,2.66976118 0.0499" +"020782,2.81946742 L0.0499020782,3.24363508 C0.0249510391,3.34343924 0,3.44324339 0,3.54304755 C0,3.59294963 0,3.64285171 0.0249510391,3.69275379 C0.0499020782,3.74265586 0.0499020782,3.79255794 0.0998041564,3.81750898 C0.149706235,3.86741106 0.199608" +"313,3.8923621 0.249510391,3.91731314 C0.299412469,3.94226418 0.374265586,3.94226418 0.424167665,3.96721522 C0.723580134,4.04206833 0.973090525,4.21672561 1.19764988,4.41633392 C1.42220923,4.61594223 1.62181754,4.84050158 1.84637689,5.0401099 C2.47015" +"287,5.56408172 3.3184882,5.76369003 4.14187249,5.78864107 C4.96525678,5.81359211 5.76369003,5.63893484 6.56212328,5.46427756 C7.18589926,5.31457133 7.80967524,5.16486509 8.40850017,4.96525678 C9.33168862,4.61594223 10.180024,4.11692145 10.9285551,3.4" +"6819443 C11.2529186,3.16878196 11.5772821,2.84441846 11.9515477,2.6198591 C12.2759112,2.42025079 12.6501768,2.27054456 12.9994914,2.07093624 C13.0244424,2.04598521 13.0493934,2.04598521 13.0992955,2.02103417 C13.1242466,1.99608313 13.1491976,1.971132" +"09 13.1741486,1.94618105 C13.1990997,1.89627897 13.1990997,1.82142585 13.1741486,1.77152378 C13.1491976,1.7216217 13.1242466,1.67171962 13.0743445,1.62181754 C13.0244424,1.57191546 12.9745403,1.52201338 12.9246383,1.47211131 C12.5753237,1.17269884 12" +".0763029,1.04794364 11.6271842,1.0229926 C11.1531145,0.998041564 10.6790447,1.0229926 10.229926,0.923188446 C9.80575836,0.848335329 9.3815907,0.698629095 8.95742303,0.54892286 C8.50830433,0.399216625 8.05918563,0.299412469 7.61006692,0.224559352 C6.5" +"3717224,0.0499020782 5.43932652,0.0748531173 4.36643184,0.299412469 C3.36839028,0.424167665 2.39529975,0.798433251 1.52201338,1.32240507\" id=\"Shape\"></path>\n" +" </g>\n" +" <path d=\"M1.99608313,2.36612373 C1.52201338,2.69048723 1.07289468,3.08970386 0.723580134,3.53882256 C0.523971821,3.78833295 0.324363508,4.08774542 0.224559352,4.38715789 C0.149706235,4.63666828 0.124755195,4.88617867 0.0499020782" +",5.1606401 C0.0249510391,5.26044426 0,5.36024842 0,5.46005257 C0,5.50995465 0,5.55985673 0.0249510391,5.60975881 C0.0499020782,5.65966089 0.0748531173,5.70956296 0.0998041564,5.734514 C0.149706235,5.78441608 0.224559352,5.83431816 0.324363508,5.83431" +"816 C0.399216625,5.8592692 0.474069743,5.8592692 0.573873899,5.8592692 C0.948139486,5.90917128 1.27250299,6.08382855 1.57191546,6.28343686 C1.87132793,6.48304518 2.14578936,6.73255557 2.47015287,6.93216388 C3.14383093,7.35633154 3.96721522,7.55593986" +" 4.76564847,7.5808909 C5.56408172,7.60584193 6.38746601,7.48108674 7.16094822,7.3313805 C7.7847242,7.20662531 8.40850017,7.05691907 9.00732511,6.83235972 C9.93051356,6.48304518 10.7538978,5.90917128 11.5273801,5.33529738 C11.8766946,5.06083595 12.226" +"0092,4.78637452 12.5503727,4.48696205 C12.6501768,4.38715789 12.774932,4.2624027 12.8747362,4.18754958 C12.9994914,4.08774542 13.1242466,4.01289231 13.2739528,3.96299023 C13.4985121,3.88813711 13.7230715,3.91308815 13.9476309,3.96299023 C14.1222881,3" +".98794127 14.2969454,4.03784334 14.4716027,4.01289231 C14.5464558,4.01289231 14.6462599,3.98794127 14.7211131,3.96299023 C14.7959662,3.93803919 14.8708193,3.88813711 14.9207214,3.81328399 C14.9955745,3.71347984 15.0205255,3.61367568 15.0205255,3.4889" +"2048 C15.0205255,3.36416529 14.9955745,3.26436113 14.9207214,3.16455698 C14.7959662,2.96494866 14.5963579,2.84019347 14.3967496,2.74038931 C14.1222881,2.61563412 13.7979246,2.540781 13.4985121,2.46592788 C12.5753237,2.24136853 11.6521353,1.91700502 1" +"0.8037999,1.46788632 C10.3796323,1.24332697 9.9554646,1.01876761 9.53129693,0.794208262 C9.10712927,0.56964891 8.65801057,0.345089558 8.18394082,0.195383324 C7.13599718,-0.128980184 5.98824938,-0.029176028 4.94030574,0.345089558 C3.84246002,0.7193551" +"45 2.79451638,1.44293528 1.99608313,2.36612373 L1.99608313,2.36612373\" id=\"path27476-4\" fill=\"#FFB510\"></path>\n" +" </g>\n" +" <path d=\"M47.3006272,37.3384927 C48.8226406,38.5610936 49.7707801,40.4074705 50.0701925,42.3287005 C50.2947519,43.8257629 50.1450456,45.3727273 49.8206821,46.8448386 C49.4963186,48.3169499 48.9473958,49.7641102 48.448375,51.1863194 C" +"48.2487667,51.7601933 48.0242073,52.3340672 47.9493542,52.9328922 C47.8745011,53.5317171 47.9244032,54.1804441 48.1988646,54.7044159 C48.5232281,55.3032409 49.1470041,55.7274085 49.8206821,55.9270168 C50.4694091,56.1266252 51.1929893,56.1266252 51.84" +"17163,55.9519679 C52.5153944,55.7773106 53.1391703,55.4529471 53.6631421,55.0537305 C55.0354493,53.9808358 55.8588336,52.3340672 56.1831971,50.6124455 C56.5075606,48.8908238 56.3578544,47.1193 56.0584419,45.4226294 C55.6592253,43.0772317 54.9605962,4" +"0.7817361 54.0873098,38.5860447 C53.4385828,36.9642271 52.6900516,35.3673606 51.642108,33.9701024 C50.6191154,32.5977953 49.3216613,31.4500475 48.3236198,30.0777403 C47.6249907,29.1046498 47.0760678,28.0567062 46.2277325,27.2083708 C45.8035648,26.784" +"2032 45.3294951,26.4348886 44.7556212,26.2103293 C44.2066983,25.9857699 43.5829224,25.9358679 43.0090485,26.0855741 C42.2605173,26.3101334 41.6367413,26.8840073 41.3123778,27.6075875 C40.9880143,28.3311676 40.9381122,29.1296009 41.0628674,29.9030831 " +"C41.2375247,30.9011246 41.6866434,31.8243131 42.1856642,32.6975994 C42.7595381,33.67069 43.4332161,34.6188295 44.3065025,35.3673606 C45.254642,36.0909408 46.3774387,36.5899615 47.3006272,37.3384927\" id=\"path29705-5-0\" fill=\"#020204\"></path>\n" +" <g id=\"g17048\" transform=\"translate(41.000000, 52.000000)\" fill=\"#FFB510\">\n" +" <path d=\"M21.707404,11.6022332 C21.5327467,12.0264008 21.3081874,12.4256175 21.0087749,12.774932 C20.3600479,13.5484142 19.4368595,14.072386 18.538622,14.5215048 C16.9916576,15.319938 15.3947911,15.9936161 13.9476309,16.9417555 C" +"12.9745403,17.5655315 12.0763029,18.3140627 11.2279676,19.1124959 C10.5043875,19.811125 9.8307094,20.5347052 9.03227615,21.1085791 C8.20889186,21.707404 7.28570342,22.1315717 6.28766185,22.2812779 C5.09001198,22.4559352 3.84246002,22.2313758 2.719663" +"26,21.7323551 C1.94618105,21.3830405 1.17269884,20.9089708 0.723580134,20.1853906 C0.27446143,19.4618105 0.174657274,18.5635731 0.174657274,17.7152378 C0.174657274,16.1932244 0.449118704,14.696162 0.723580134,13.1990997 C0.948139486,11.9515477 1.1477" +"478,10.7039958 1.29745403,9.45644382 C1.54696442,7.18589926 1.54696442,4.86545262 1.37230715,2.59490807 C1.34735611,2.22064248 1.32240507,1.82142585 1.37230715,1.44716027 C1.42220923,1.07289468 1.5968665,0.698629095 1.87132793,0.449118704 C2.14578936" +",0.224559352 2.49510391,0.124755195 2.84441846,0.0998041564 C3.193733,0.0748531173 3.54304755,0.124755195 3.8923621,0.199608313 C4.71574639,0.324363508 5.56408172,0.424167665 6.36251497,0.623775977 C6.86153575,0.748531173 7.36055653,0.948139486 7.884" +"52835,1.07289468 C8.73286368,1.29745403 9.63110109,1.42220923 10.5043875,1.32240507 C11.4525269,1.22260092 12.3507644,0.848335329 13.2989038,0.873286368 C13.6981205,0.873286368 14.072386,0.948139486 14.4466516,1.07289468 C14.8209172,1.19764988 15.195" +"1828,1.37230715 15.4696442,1.64676858 C15.6692526,1.87132793 15.8189588,2.12083832 15.943714,2.42025079 C16.1183713,2.84441846 16.1932244,3.29353716 16.2431264,3.71770482 C16.2680775,4.11692145 16.2680775,4.51613808 16.3429306,4.9153547 C16.4676858,5" +".56408172 16.7920493,6.13795562 17.216217,6.6369764 C17.6403846,7.13599718 18.1394054,7.56016485 18.6384262,7.98433251 C19.137447,8.40850017 19.6364678,8.83266784 20.1853906,9.18198239 C20.434901,9.35663966 20.7093624,9.50634589 20.9339218,9.70595421" +" C21.1834322,9.90556252 21.3830405,10.1051708 21.5327467,10.3796323 C21.7323551,10.7538978 21.8072082,11.2030166 21.707404,11.6022332 L21.707404,11.6022332\" id=\"path14296-0\"></path>\n" +" </g>\n" +" <g id=\"path28767-9-3\" opacity=\"0.25\" transform=\"translate(20.000000, 28.000000)\" fill=\"#7C7C7C\">\n" +" <path d=\"M1.1477478,0.399216625 C1.12279676,0.0499020782 0.598824938,-0.0249510391 0.374265586,0.174657274 C0.174657274,0.324363508 -2.65065747e-15,0.848335329 0.174657274,1.04794364 C0.424167665,1.37230715 1.17269884,0.898237407" +" 1.1477478,0.399216625 Z\" id=\"Shape\"></path>\n" +" </g>\n" +" <g id=\"g14884-8\" transform=\"translate(46.000000, 50.000000)\" fill=\"#020204\">\n" +" <path d=\"M9.03227615,2.24559352 C8.932472,1.97113209 8.75781472,1.7216217 8.53325537,1.52201338 C8.30869602,1.32240507 8.05918563,1.17269884 7.7847242,1.04794364 C7.23580134,0.82338429 6.66192744,0.723580134 6.08805354,0.62377597" +"7 C5.53913068,0.523971821 5.01515886,0.399216625 4.466236,0.299412469 C3.8923621,0.199608313 3.3184882,0.149706235 2.7446143,0.27446143 C2.24559352,0.374265586 1.79647481,0.648727016 1.42220923,0.973090525 C1.04794364,1.29745403 0.773482212,1.7465727" +"4 0.54892286,2.19569144 C0.174657274,2.99412469 0.0748531173,3.91731314 0.124755195,4.79059951 C0.174657274,5.43932652 0.349314547,6.11300458 0.773482212,6.61202536 C1.12279676,7.01124199 1.62181754,7.26075238 2.12083832,7.41045861 C2.99412469,7.6599" +"69 3.96721522,7.659969 4.84050158,7.36055653 C6.28766185,6.88648679 7.56016485,5.91339627 8.40850017,4.66584431 C8.6829616,4.26662769 8.932472,3.81750898 9.05722719,3.3184882 C9.15703135,2.99412469 9.15703135,2.59490807 9.03227615,2.24559352\" id=\"p" +"ath29714-5-4\"></path>\n" +" </g>\n" +" <g id=\"g15037-4\" transform=\"translate(9.000000, 27.000000)\" fill=\"#020204\">\n" +" <path d=\"M10.0303177,2.6198591 C9.30673758,3.51809651 8.60810849,4.41633392 7.88452835,5.31457133 C7.01124199,6.41241705 6.11300458,7.51026277 5.53913068,8.78276576 C5.0401099,9.88061148 4.81555055,11.0782614 4.466236,12.2260092 " +"C4.09197041,13.5484142 3.56799859,14.8209172 2.96917365,16.0435181 C2.42025079,17.1912659 1.84637689,18.3140627 1.24755195,19.4119084 C0.82338429,20.2352927 0.374265586,21.058677 0.224559352,21.9569144 C0.0998041564,22.6804945 0.174657274,23.4040747 " +"0.349314547,24.1276548 C0.523971821,24.8262839 0.82338429,25.499962 1.1477478,26.148689 C2.56995703,28.9182543 4.69079535,31.288603 7.18589926,33.1100289 C8.33364706,33.9334132 7.06114406,32.1618894 8.33364706,32.7357633 C9.03227615,33.0601268 9.7558" +"5629,33.3345882 10.5293385,33.3595393 C10.9036041,33.3595393 11.3028207,33.3096372 11.6521353,33.159931 C12.0014498,33.0102247 12.3258133,32.7607143 12.5254216,32.4363508 C12.774932,32.0371342 12.8747362,31.5630645 12.8248341,31.0889947 C12.774932,30" +".614925 12.6002747,30.1658063 12.3507644,29.7665896 C11.7519394,28.7934991 10.8037999,28.069919 9.90556252,27.3712899 C7.95938147,25.8492765 8.55820641,26.7475139 6.73678056,25.0757943 C6.23775977,24.6017245 5.71378795,24.1027038 5.36447341,23.503878" +"8 C5.01515886,22.9300049 4.84050158,22.2563269 4.69079535,21.5826488 C4.3414808,19.761223 4.44128496,17.8150419 5.06506094,16.0684692 C5.31457133,15.3698401 5.63893484,14.7211131 5.9383473,14.072386 C6.48727016,12.9246383 6.98629095,11.7519394 7.6849" +"2004,10.7039958 C8.55820641,9.40654174 9.75585629,8.28374498 10.4794364,6.88648679 C11.0782614,5.71378795 11.3277717,4.36643184 11.5772821,3.06897781 C11.7519394,2.07093624 11.9265967,1.04794364 12.101254,0.0249510391 C11.4026249,0.898237407 10.70399" +"58,1.77152378 10.0303177,2.6198591 Z\" id=\"path14967-1-0\"></path>\n" +" </g>\n" +" <g id=\"Group\" transform=\"translate(0.000000, 51.000000)\" fill=\"#FFB510\">\n" +" <g id=\"g14180-6\" transform=\"translate(0.000000, -0.000000)\">\n" +" <path d=\"M10.3796323,0.174657274 C10.7788489,-1.26496036e-14 11.2279676,-0.0249510391 11.6521353,0.0499020782 C12.0763029,0.124755195 12.4755195,0.299412469 12.8248341,0.54892286 C13.5484142,1.0229926 14.072386,1.74657274 14." +"5714068,2.44520183 C15.7441057,4.04206833 16.8669024,5.68883691 17.864944,7.38550757 C18.6883283,8.75781472 19.4368595,10.204975 20.40995,11.502429 C21.033726,12.3507644 21.7323551,13.1242466 22.356131,13.9725819 C22.979907,14.8209172 23.5288299,15.7" +"441057 23.8032913,16.7421472 C24.1526058,18.0645523 24.0278506,19.5117126 23.4040747,20.7343135 C22.954956,21.5826488 22.2812779,22.33118 21.4578936,22.8052497 C20.6345093,23.2793195 19.6614188,23.5537809 18.7132793,23.5288299 C17.1912659,23.4789278 " +"15.7940077,22.7054456 14.3717985,22.1565227 C11.477478,21.0087749 8.33364706,20.6345093 5.36447341,19.7362719 C4.44128496,19.4618105 3.54304755,19.137447 2.6198591,18.8879366 C2.22064248,18.7631814 1.79647481,18.6883283 1.39725819,18.48872 C0.9980415" +"64,18.3140627 0.648727016,18.0645523 0.424167665,17.6902867 C0.249510391,17.4158253 0.199608313,17.0665107 0.199608313,16.7421472 C0.199608313,16.4177837 0.27446143,16.0934202 0.399216625,15.7690567 C0.623775977,15.1452807 0.973090525,14.5963579 1.22" +"260092,13.9725819 C1.62181754,12.9745403 1.69667066,11.8766946 1.64676858,10.8037999 C1.5968665,9.73090525 1.42220923,8.6829616 1.34735611,7.61006692 C1.32240507,7.13599718 1.29745403,6.6369764 1.39725819,6.1878577 C1.49706235,5.73873899 1.69667066,5" +".26466925 2.04598521,4.9153547 C2.37034871,4.61594223 2.79451638,4.41633392 3.21868404,4.3414808 C3.64285171,4.24167665 4.09197041,4.24167665 4.54108912,4.26662769 C4.99020782,4.26662769 5.41437548,4.29157872 5.86349419,4.26662769 C6.31261289,4.24167" +"665 6.73678056,4.14187249 7.13599718,3.91731314 C7.51026277,3.71770482 7.80967524,3.39334132 8.03423459,3.06897781 C8.25879394,2.7446143 8.48335329,2.37034871 8.6829616,1.99608313 C8.88256992,1.62181754 9.10712927,1.27250299 9.35663966,0.948139486 C9" +".60615005,0.623775977 9.98041564,0.324363508 10.3796323,0.174657274\" id=\"path4635-1\"></path>\n" +" </g>\n" +" </g>\n" +" </g>\n" +" </g>\n" +" </g>\n" +"</svg>"; + +const char* export_linux_svg = (const char*) temp_binary_data_14; + +//================== export_visualStudio.svg ================== +static const unsigned char temp_binary_data_15[] = +"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +"<svg width=\"20px\" height=\"20px\" viewBox=\"0 0 20 20\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n" +" <!-- Generator: Sketch 43.1 (39012) - http://www.bohemiancoding.com/sketch -->\n" +" <title>Visual Studio</title>\n" +" <desc>Created with Sketch.</desc>\n" +" <defs></defs>\n" +" <g id=\"Page-1\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n" +" <g id=\"Artboard\" transform=\"translate(-77.000000, -43.000000)\">\n" +" <g id=\"Visual-Studio\" transform=\"translate(76.000000, 41.000000)\">\n" +" <polygon id=\"Rectangle\" fill=\"#68217A\" points=\"1 7 3 6 3 18 1 17\"></polygon>\n" +" <polygon id=\"Rectangle-2\" fill=\"#541D66\" transform=\"translate(5.607051, 10.000000) rotate(-330.000000) translate(-5.607051, -10.000000) \" points=\"1.34927858 7.83942379 7.86482304 8.6964746 9.86482304 12.1605762 2.84927858 10.43" +"75\"></polygon>\n" +" <polygon id=\"Rectangle-3\" fill=\"#541D66\" points=\"3 15 8 10 8 14 3 18\"></polygon>\n" +" <polygon id=\"Rectangle-2-Copy\" fill=\"#68217A\" transform=\"translate(12.000000, 16.000000) rotate(-330.000000) translate(-12.000000, -16.000000) \" points=\"5.53589838 12.8038476 15.4641016 14 18.4641016 19.1961524 7.53589838 16.26" +"79492\"></polygon>\n" +" <polygon id=\"Rectangle-2-Copy-2\" fill=\"#68217A\" transform=\"translate(12.433013, 8.250000) rotate(-330.000000) translate(-12.433013, -8.250000) \" points=\"9.46891109 11.9820508 12.3971143 1.05384758 15.3971143 6.25 11.4689111 15." +"4461524\"></polygon>\n" +" <polygon id=\"Rectangle-4\" fill=\"#541D66\" points=\"16 2 21 4 21 20 16 22\"></polygon>\n" +" </g>\n" +" </g>\n" +" </g>\n" +"</svg>"; + +const char* export_visualStudio_svg = (const char*) temp_binary_data_15; + +//================== export_xcode.svg ================== +static const unsigned char temp_binary_data_16[] = +"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +"<svg width=\"33px\" height=\"32px\" viewBox=\"0 0 33 32\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n" +" <!-- Generator: Sketch 43.1 (39012) - http://www.bohemiancoding.com/sketch -->\n" +" <title>Group 2</title>\n" +" <desc>Created with Sketch.</desc>\n" +" <defs></defs>\n" +" <g id=\"Page-1\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n" +" <g id=\"Artboard\" transform=\"translate(-28.000000, -50.000000)\">\n" +" <g id=\"Group-2\" transform=\"translate(28.000000, 50.000000)\">\n" +" <g id=\"folder\" transform=\"translate(0.000000, 5.000000)\">\n" +" <polygon id=\"Rectangle-5\" fill=\"#457EFD\" points=\"0 4 27 0 30 21 3 25\"></polygon>\n" +" <path d=\"M19.9232759,13.0294985 C20.1413793,12.8123894 20.1034483,12.6519174 19.9517241,12.4725664 C19.3543103,11.7646018 18.7758621,11.0566372 18.1784483,10.3486726 C16.5189655,8.35693215 14.85,6.35575221 13.1905172,4.35457227 C" +"13.0577586,4.19410029 12.9439655,3.97699115 12.9060345,3.76932153 C12.8396552,3.36342183 13.1146552,2.99528024 13.512931,2.83480826 C13.9396552,2.67433628 14.3094828,2.78761062 14.6698276,3.21238938 C16.3008621,5.15693215 17.9413793,7.10147493 19.572" +"4138,9.0460177 C19.9612069,9.50855457 20.3594828,9.97109145 20.7672414,10.4525074 C20.9758621,10.2353982 20.9474138,10.0749263 20.7956897,9.89557522 C20.1413793,9.12153392 19.487069,8.3380531 18.8327586,7.5640118 C17.5146552,5.99705015 16.2060345,4.4" +"300885 14.8784483,2.8820059 C14.3474138,2.26843658 13.5413793,2.23067847 12.9534483,2.74041298 C12.375,3.24070796 12.3465517,3.94867257 12.887069,4.59056047 C14.9353448,7.05427729 16.9836207,9.50855457 19.0318966,11.9722714 C19.3258621,12.3309735 19." +"6198276,12.6707965 19.9232759,13.0294985 Z\" id=\"Shape\" fill=\"#235EE1\" fill-rule=\"nonzero\"></path>\n" +" <path d=\"M13.3801724,9.05545723 C13.3137931,9.00825959 13.237931,8.94218289 13.1525862,8.90442478 C12.4982759,8.65899705 11.8439655,8.43244838 11.1896552,8.18702065 C10.9810345,8.11150442 10.8862069,8.18702065 10.8103448,8.366371" +"68 C9.61551724,11.2926254 8.42068966,14.2094395 7.22586207,17.1356932 C7.13103448,17.3528024 7.19741379,17.4566372 7.39655172,17.5321534 C8.01293103,17.7775811 8.62931034,18.0135693 9.2362069,18.2873156 C9.56810345,18.4383481 9.70086207,18.3628319 9." +"82413793,18.0324484 C10.962069,15.1345133 12.1189655,12.2460177 13.2663793,9.35752212 C13.2948276,9.29144543 13.3232759,9.19705015 13.3801724,9.05545723 Z\" id=\"Shape\" fill=\"#FFFFFF\" fill-rule=\"nonzero\"></path>\n" +" <path d=\"M19.6293103,13.1050147 C19.1551724,12.5103245 18.7189655,12.019469 18.3586207,11.4908555 C18.0362069,11 17.6758621,10.7451327 17.0784483,10.9905605 C16.9362069,11.0471976 16.775,11.0471976 16.6232759,11.0660767 C15.35258" +"62,11.2831858 14.0913793,11.500295 12.8206897,11.7174041 C12.6215517,11.7551622 12.4508621,11.8023599 12.3655172,12.0383481 C12.1189655,12.7368732 11.8534483,13.4259587 11.5974138,14.1244838 C11.5689655,14.2 11.5689655,14.2943953 11.55,14.4265487 C14" +".2525862,13.9923304 16.8887931,13.5581121 19.6293103,13.1050147 Z\" id=\"Shape\" fill=\"#FFFFFF\" fill-rule=\"nonzero\"></path>\n" +" <path d=\"M8.97068966,12.2648968 C7.41551724,12.519764 5.9362069,12.7557522 4.40948276,13.0011799 C4.5137931,13.7091445 4.62758621,14.379351 4.70344828,15.0589971 C4.74137931,15.3516224 4.86465517,15.3893805 5.13017241,15.3516224 " +"C5.90775862,15.2289086 6.69482759,15.1250737 7.48189655,15.0306785 C7.71896552,15.0023599 7.87068966,14.9079646 7.96551724,14.6908555 C8.25,14.0112094 8.55344828,13.3315634 8.84741379,12.6519174 C8.89482759,12.5386431 8.9137931,12.4442478 8.97068966," +"12.2648968 Z\" id=\"Shape\" fill=\"#FFFFFF\" fill-rule=\"nonzero\"></path>\n" +" <path d=\"M25.6413793,18.1551622 C24.712069,17.5887906 23.7922414,17.0318584 22.787069,16.4277286 C22.825,16.6070796 22.8060345,16.8147493 22.9008621,16.9185841 C23.0810345,17.1168142 23.2991379,17.2867257 23.5362069,17.4094395 C2" +"3.8586207,17.5887906 24.2,17.7115044 24.5318966,17.8719764 C25.0155172,18.1079646 25.3663793,18.4477876 25.3663793,19.0330383 C25.3663793,19.1274336 25.4137931,19.2218289 25.4517241,19.3256637 C25.5086207,19.2973451 25.5275862,19.2879056 25.5465517,1" +"9.2784661 C25.575,19.2501475 25.5939655,19.2218289 25.612931,19.1935103 C26.1818966,18.3533923 26.2198276,17.4283186 25.9732759,16.4843658 C25.6982759,15.4271386 25.2051724,14.5115044 24.1715517,13.9828909 C23.887069,13.8412979 23.7068966,13.9640118 " +"23.4982759,14.1056047 C23.2801724,14.2566372 23.1568966,14.4359882 23.2137931,14.7569322 C23.3655172,14.6625369 23.4982759,14.5964602 23.5931034,14.5020649 C23.8301724,14.2566372 24.0482759,14.3132743 24.3137931,14.4831858 C25.3568966,15.2100295 26.0" +"112069,17.0412979 25.6413793,18.1551622 Z\" id=\"Shape\" fill=\"#235EE1\" fill-rule=\"nonzero\"></path>\n" +" <path d=\"M6.57155172,22.1103245 C6.60948276,22.1292035 6.64741379,22.1480826 6.68534483,22.1575221 C7.62413793,20.9870206 8.57241379,19.8165192 9.53017241,18.6176991 C9.38793103,18.5421829 9.30258621,18.4855457 9.20775862,18.4477" +"876 C8.60086207,18.2023599 7.99396552,17.9758112 7.39655172,17.720944 C7.11206897,17.5982301 7.02672414,17.6831858 7.00775862,17.9758112 C6.93189655,18.7687316 6.83706897,19.5616519 6.75172414,20.3640118 C6.68534483,20.9492625 6.62844828,21.5345133 6" +".57155172,22.1103245 Z\" id=\"Shape\" fill=\"#FFFFFF\" fill-rule=\"nonzero\"></path>\n" +" <path d=\"M12.687931,5.83657817 C12.137931,5.89321534 11.7775862,6.11976401 11.5689655,6.60117994 C11.4267241,6.95044248 11.2939655,7.29970501 11.1327586,7.63952802 C11.037931,7.83775811 11.0663793,7.96047198 11.2939655,8.0359882 " +"C11.9293103,8.25309735 12.5646552,8.48908555 13.1905172,8.73451327 C13.4181034,8.81946903 13.512931,8.7439528 13.5982759,8.54572271 C13.7405172,8.18702065 13.9017241,7.82831858 14.0534483,7.46961652 C14.2525862,6.98820059 14.1672414,6.58230088 13.731" +"0345,6.29911504 C13.4181034,6.10088496 13.0387931,5.98761062 12.687931,5.83657817 Z\" id=\"Shape\" fill=\"#FFFFFF\" fill-rule=\"nonzero\"></path>\n" +" <path d=\"M23.8112069,12.3498525 C24.6077586,12.2460177 25.3948276,12.1421829 26.1724138,12.019469 C26.2387931,12.0100295 26.3241379,11.840118 26.3146552,11.7646018 C26.2198276,11.1415929 26.1060345,10.5091445 25.9732759,9.8955752" +"2 C25.9543103,9.80117994 25.7931034,9.66902655 25.6982759,9.66902655 C25.3,9.69734513 24.9017241,9.7539823 24.5034483,9.820059 C24.3043103,9.84837758 24.162069,9.94277286 24.2758621,10.2259587 C24.6362069,10.1787611 25.0060345,10.1221239 25.3758621,1" +"0.0938053 C25.4612069,10.0843658 25.6224138,10.159882 25.6318966,10.2165192 C25.7362069,10.6884956 25.812069,11.179351 25.9068966,11.679646 C25.2905172,11.7646018 24.712069,11.840118 24.1431034,11.9156342 C23.9344828,11.9439528 23.7448276,11.9911504 " +"23.8112069,12.3498525 Z\" id=\"Shape\" fill=\"#235EE1\" fill-rule=\"nonzero\"></path>\n" +" <path d=\"M19.9232759,13.0294985 C19.6198276,12.6707965 19.3258621,12.3309735 19.0318966,11.9722714 C16.9836207,9.50855457 14.9353448,7.05427729 12.887069,4.59056047 C12.3465517,3.94867257 12.375,3.25014749 12.9534483,2.74041298 C" +"13.5508621,2.22123894 14.3568966,2.25899705 14.8784483,2.8820059 C16.2060345,4.4300885 17.5146552,6.00648968 18.8327586,7.5640118 C19.487069,8.3380531 20.1318966,9.12153392 20.7956897,9.89557522 C20.9474138,10.0749263 20.9853448,10.2353982 20.7672414" +",10.4525074 C20.3594828,9.97109145 19.9612069,9.50855457 19.5724138,9.0460177 C17.9413793,7.10147493 16.3008621,5.15693215 14.6698276,3.21238938 C14.3094828,2.78761062 13.9396552,2.66489676 13.512931,2.83480826 C13.1051724,2.99528024 12.8396552,3.363" +"42183 12.9060345,3.76932153 C12.9344828,3.97699115 13.0482759,4.19410029 13.1905172,4.35457227 C14.85,6.35575221 16.5094828,8.34749263 18.1784483,10.3486726 C18.7663793,11.0566372 19.3543103,11.7646018 19.9517241,12.4725664 C20.1034483,12.6519174 20." +"1508621,12.8123894 19.9232759,13.0294985 Z\" id=\"Shape\" fill=\"#FFFFFF\" fill-rule=\"nonzero\"></path>\n" +" <path d=\"M25.6413793,18.1551622 C26.0112069,17.0412979 25.3568966,15.2100295 24.3137931,14.5020649 C24.0577586,14.3227139 23.8396552,14.2755162 23.5931034,14.520944 C23.4982759,14.6153392 23.3655172,14.6719764 23.2137931,14.77581" +"12 C23.1568966,14.4454277 23.2801724,14.2755162 23.4982759,14.1244838 C23.7068966,13.9734513 23.887069,13.860177 24.1715517,14.0017699 C25.2051724,14.5303835 25.6982759,15.4460177 25.9732759,16.5032448 C26.2198276,17.4471976 26.1818966,18.3722714 25." +"612931,19.2123894 C25.5939655,19.240708 25.575,19.2690265 25.5465517,19.2973451 C25.5275862,19.3162242 25.5086207,19.3162242 25.4517241,19.3445428 C25.4232759,19.240708 25.3663793,19.1463127 25.3663793,19.0519174 C25.3663793,18.4666667 25.0155172,18." +"1268437 24.5318966,17.8908555 C24.2,17.7303835 23.8491379,17.6076696 23.5362069,17.4283186 C23.2991379,17.2961652 23.0715517,17.1356932 22.9008621,16.9374631 C22.8060345,16.8336283 22.825,16.6259587 22.787069,16.4466077 C23.7922414,17.0318584 24.7120" +"69,17.5887906 25.6413793,18.1551622 Z\" id=\"Shape\" fill=\"#FFFFFF\" fill-rule=\"nonzero\"></path>\n" +" <path d=\"M23.8112069,12.3498525 C23.7353448,11.9911504 23.9344828,11.9439528 24.1431034,11.9156342 C24.712069,11.840118 25.2810345,11.7646018 25.9068966,11.679646 C25.812069,11.179351 25.7362069,10.6979351 25.6318966,10.2165192 C" +"25.6224138,10.159882 25.4612069,10.0843658 25.3758621,10.0938053 C25.0060345,10.1221239 24.6362069,10.1787611 24.2758621,10.2259587 C24.1715517,9.93333333 24.3137931,9.84837758 24.5034483,9.820059 C24.9017241,9.76342183 25.3,9.69734513 25.6982759,9.6" +"6902655 C25.7931034,9.65958702 25.9543103,9.80117994 25.9732759,9.89557522 C26.1060345,10.5185841 26.2198276,11.1415929 26.3146552,11.7646018 C26.3241379,11.840118 26.2293103,12.0100295 26.1724138,12.019469 C25.3948276,12.1421829 24.6172414,12.236578" +"2 23.8112069,12.3498525 Z\" id=\"Shape\" fill=\"#FFFFFF\" fill-rule=\"nonzero\"></path>\n" +" </g>\n" +" <path d=\"M24.3232759,13.3569322 C23.687931,13.1681416 23.0810345,12.9982301 22.4836207,12.8283186 C22.2655172,12.7622419 22.3034483,12.6300885 22.3508621,12.4696165 C22.7017241,11.2330383 23.0431034,9.99646018 23.4034483,8.76932153 C" +"23.7448276,7.60825959 23.9724138,6.42831858 23.8681034,5.220059 C23.7922414,4.35162242 23.6689655,3.5020649 23.0905172,2.76578171 C22.55,2.07669617 21.8198276,1.80294985 21.0043103,1.69911504 C19.8,1.53864307 18.6051724,1.55752212 17.3439655,1.661356" +"93 C17.4672414,1.55752212 17.5715517,1.43480826 17.7043103,1.34041298 C18.6241379,0.689085546 19.6862069,0.396460177 20.7767241,0.226548673 C23.0525862,-0.132153392 25.2525862,0.207669617 27.4051724,0.943952802 C28.1543103,1.19882006 28.7801724,1.633" +"03835 29.3301724,2.18053097 C29.8517241,2.69970501 30.4396552,2.80353982 31.0844828,2.53923304 C31.4827586,2.36932153 31.8241379,2.4259587 32.2034483,2.55811209 C33.1137931,2.87905605 33.1137931,2.86961652 32.8387931,3.80412979 C32.5922414,4.62536873" +" 32.3456897,5.44660767 32.1086207,6.27728614 C32.0327586,6.53215339 31.9284483,6.6359882 31.6534483,6.54159292 C31.4543103,6.4660767 31.2456897,6.40943953 31.037069,6.38112094 C30.5913793,6.31504425 30.2689655,6.0979351 30.0034483,5.72035398 C29.5767" +"241,5.14454277 28.9318966,5.19174041 28.3155172,5.25781711 C27.3862069,5.36165192 26.7887931,5.8619469 26.437931,6.74926254 C25.6508621,8.72212389 25.0724138,10.7610619 24.5034483,12.8 C24.4465517,12.9699115 24.3896552,13.139823 24.3232759,13.3569322" +" Z\" id=\"Shape\" fill=\"#D2D2D2\" fill-rule=\"nonzero\"></path>\n" +" <path d=\"M18.4913793,31.9150442 C17.1163793,31.9056047 16.2155172,31.0182891 16.262931,29.7250737 C16.2724138,29.5079646 16.3387931,29.2814159 16.4146552,29.0737463 C18.2068966,23.9858407 20.0086207,18.9073746 21.8103448,13.8289086 C" +"22.0189655,13.2247788 21.8862069,13.2058997 22.6163793,13.4135693 C23.0146552,13.5268437 23.412931,13.6495575 23.8112069,13.7439528 C24.1051724,13.8100295 24.1810345,13.9327434 24.1051724,14.2348083 C23.7258621,15.7923304 23.375,17.3498525 23.0051724" +",18.9073746 C22.1043103,22.6548673 21.2034483,26.4117994 20.2931034,30.159292 C20.2077586,30.5085546 20.0655172,30.8578171 19.8853448,31.1693215 C19.5724138,31.6884956 19.0887931,31.9622419 18.4913793,31.9150442 Z\" id=\"Shape\" fill=\"#000000\" fill" +"-rule=\"nonzero\"></path>\n" +" </g>\n" +" </g>\n" +" </g>\n" +"</svg>"; + +const char* export_xcode_svg = (const char*) temp_binary_data_16; + +//================== gpl_logo.svg ================== +static const unsigned char temp_binary_data_17[] = +"<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"720\" height=\"358\" version=\"1.1\">\n" +" <g id=\"g1\" transform=\"translate(-26.149211,-6.9701601)\">\n" +" <path id=\"path1\" style=\"fill:#bd0000;\" d=\"m 107.04146,18.25331 c 2e-5,0 -59.309734,258.76742 -59.309734,258.76742 0.01705,0 0.01919,0 0.05329,0 0,0 274.380814,0 274.380814,0 10e-6,0 142.70573,0 142.70573,0 -17.00107,-1.48353 -30.42327,-7.451" +"82 -38.42076,-18.33112 -1.48353,-2.01219 -2.70918,-4.17993 -3.78347,-6.44788 -0.68207,-1.6711 -1.32368,-3.35715 -1.97167,-5.06237 -1.70524,-5.42261 -2.38517,-11.43991 -2.07824,-17.85154 0.85262,-17.87074 9.23805,-39.12802 23.76654,-61.38798 15.43225," +"-23.65656 37.79837,-48.45089 65.49116,-71.45944 6.20699,-5.15319 12.62503,-10.24199 19.34361,-15.18714 8.30441,-6.10979 16.67281,-11.73661 25.04545,-16.99893 30.84745,-19.42077 61.61817,-33.01012 88.88467,-39.91282 -26.05577,8.50051 -55.32805,22.9313" +"8 -84.24861,42.57724 -1.04016,0.70255 -2.06758,1.42215 -3.09072,2.13152 -16.04613,11.11805 -30.58314,22.92586 -43.26998,34.85046 -40.82303,38.38457 -62.40046,78.15884 -52.59544,101.46069 0.69916,1.6029 1.53256,3.13335 2.50455,4.58279 10.53825,15.5004" +"7 36.65587,18.17979 69.75422,9.85831 2.25089,-0.56275 4.50178,-1.20004 6.82088,-1.86508 10.57238,-3.05237 21.797,-7.17473 33.3584,-12.25628 2.77949,-1.22777 5.58887,-2.48963 8.41953,-3.83676 0.28988,-0.13641 0.56273,-0.27283 0.85261,-0.4263 36.49173," +"-18.13162 64.53625,-38.99458 70.60684,-51.52967 1.33008,-2.72662 1.6498,-5.0513 0.74603,-6.87417 -4.33124,-8.78188 -34.63945,-2.849 -71.35287,13.0556 -2.95003,1.2789 -5.93417,2.59492 -8.95241,3.99661 2.45552,-2.27986 5.01123,-4.56828 7.6202,-6.82089 " +"4.16075,-3.58438 8.46856,-7.08945 13.0556,-10.55104 7.179,-5.43627 14.43685,-10.35071 21.58173,-14.70754 33.45643,-25.24067 50.3701,-49.11722 46.8403,-57.97753 -0.66505,-1.66943 -2.08037,-2.81789 -4.26306,-3.51703 -6.97438,-2.21847 -19.70383,0.42929 " +"-35.17019,6.7676 -12.75504,5.23164 -27.40504,12.9908 -42.25752,22.64748 0,0 -2.02495,1.3322 -2.02495,1.3322 2e-5,0 -0.37302,0.21314 -0.37302,0.21314 2e-5,2e-5 -7.14061,4.74265 -7.14061,4.74265 -2e-5,-1e-5 4.10319,-7.51363 4.10319,-7.51363 6.08765,-11" +".14364 16.0035,-22.77067 28.3493,-33.57154 9.05473,-7.89689 19.39903,-15.33762 30.53413,-21.84816 4.21191,-2.46573 8.4174,-4.75586 12.62929,-6.82088 4.31422,-2.10769 8.63055,-3.98089 12.84246,-5.64859 12.23682,-4.8393 23.91781,-7.7798 34.10442,-8.579" +"4 -0.92767,0 -28.61574,0 -28.61574,0 10e-6,0 -96.45159,0 -96.45159,0 10e-6,0 -425.29295,0 -425.29295,0 0,0 -33.73141,0 -33.73141,0 z m 305.98071,0.3731 c -1.67109,25.50496 3.27403,62.86211 14.49439,104.3382 1.99509,7.38021 4.16712,14.89085 6.55444,22" +".48762 1.48356,4.69104 3.01399,9.30881 4.58278,13.85492 -0.9208,1.35396 -1.84804,2.69937 -2.7177,4.0499 -13.99985,21.45508 -22.1828,41.73104 -24.24611,59.36303 -5.91714,-19.81468 -10.37201,-41.5183 -12.89574,-64.53198 -0.71619,-6.5941 -1.27679,-13.11" +"442 -1.65194,-19.55675 -2.76247,-46.79639 3.34649,-89.2172 15.87988,-120.00494 z m -279.3899,33.1985 c 0.31934,-0.0075 0.63414,0 0.95918,0 0,-2e-5 63.03991,0 63.03991,0 5.38851,-2e-5 9.55564,1.00991 12.52272,3.03742 2.95002,2.03946 4.05631,4.67743 3." +"35715,7.88665 2e-5,2e-5 -7.51363,33.94456 -7.51363,33.94456 0,3e-5 -22.22116,0 -22.22116,0 2e-5,3e-5 7.30048,-33.03866 7.30048,-33.03866 -2e-5,0 -55.63285,0 -55.63285,0 -2e-5,0 -20.08965,90.80305 -20.08965,90.80305 2e-5,0 -7.24719,32.87881 -7.24719,3" +"2.87881 0,3e-5 55.57957,0 55.57957,0 0,3e-5 0.0533,-0.21316 0.0533,-0.21316 0,2e-5 11.13722,-50.30404 11.13722,-50.30404 0,-2e-5 -26.1112,0 -26.1112,0 0,-2e-5 2.50454,-11.35038 2.50454,-11.35038 -1e-5,-2e-5 48.33238,0 48.33238,0 0,-2e-5 -13.85493,62." +"77348 -13.85493,62.77348 -0.18757,0.89352 -0.51582,1.70308 -0.95919,2.50453 -1.14249,2.08037 -3.13547,3.86234 -5.91498,5.32883 -3.85378,2.02923 -8.46643,3.03742 -13.85493,3.03742 0,2e-5 -62.98662,0 -62.98662,0 -5.388524,2e-5 -9.555644,-1.00821 -12.52" +"2724,-3.03742 -2.95001,-2.0292 -4.07335,-4.62073 -3.35715,-7.83336 10e-6,-2e-5 27.763134,-125.49366 27.763134,-125.49366 0.71618,-3.20921 2.95005,-5.84721 6.82089,-7.88665 0.13642,-0.07331 0.28989,-0.08995 0.4263,-0.15986 3.53302,-1.7697 7.67937,-2.7" +"6443 12.46944,-2.87756 z m 98.79628,0 c -2e-5,-2e-5 79.34608,0 79.34608,0 5.32031,-2e-5 9.50235,1.00991 12.46943,3.03742 2.98417,2.03946 4.12666,4.67743 3.41045,7.88665 2e-5,2e-5 -14.81411,66.92995 -14.81411,66.92995 -0.69912,3.18874 -2.98627,5.7905 " +"-6.87417,7.83336 -3.8879,2.04966 -8.4643,3.09071 -13.80164,3.09071 -2e-5,0 -57.6578,0 -57.6578,0 0,0 -11.13723,50.25075 -11.13723,50.25075 0,2e-5 -1.8118,8.25967 -1.8118,8.25967 1e-5,2e-5 -21.74158,0 -21.74158,0 0,2e-5 1.65193,-7.46034 1.65193,-7.460" +"34 0,2e-5 30.96044,-139.82817 30.96044,-139.82817 z m 109.61377,0 c -1e-5,-2e-5 21.74158,0 21.74158,0 2e-5,-2e-5 -24.61914,111.21241 -24.61914,111.21241 2e-5,2e-5 -5.3821,24.29942 -5.3821,24.29942 0,3e-5 52.00926,0 52.00926,0 0.54568,3.98854 1.18299," +"7.90582 1.86508,11.77668 -2e-5,2e-5 -78.22705,0 -78.22705,0 2e-5,2e-5 6.18143,-27.92301 6.18143,-27.92301 2e-5,0 26.43094,-119.3655 26.43094,-119.3655 z M 251.559,63.65488 c 2e-5,0 -14.4411,65.11814 -14.4411,65.11814 0,-2e-5 54.19408,0 54.19408,0 -1e" +"-5,-2e-5 14.3878,-65.11814 14.3878,-65.11814 2e-5,0 -54.14078,0 -54.14078,0 z m -45.5614,145.68987 c 0.21267,-0.007 0.42524,0 0.63947,0 2.52373,2e-5 4.72772,0.44336 6.50115,1.27891 1.8928,0.88671 3.24632,2.204 3.99662,3.94333 0.73325,1.68819 0.92508," +"3.60441 0.53287,5.70184 0,1e-5 -0.15985,0.79933 -0.15985,0.79933 1e-5,-3e-5 -6.23472,0 -6.23472,0 -2e-5,-3e-5 0.0533,-0.74605 0.0533,-0.74605 0.16118,-1.46543 -0.0205,-2.61779 -0.58618,-3.41043 -0.0737,-0.0994 -0.18053,-0.23063 -0.26644,-0.31973 -0.1" +"4068,-0.14363 -0.35198,-0.3078 -0.53287,-0.42631 -0.87238,-0.5495 -2.23703,-0.85262 -3.99662,-0.85262 -2.33615,2e-5 -4.08187,0.40712 -5.27552,1.22564 -1.15956,0.80146 -1.8928,1.6967 -2.13153,2.77098 -0.23875,1.09134 0.15346,1.66472 0.42631,1.97166 0." +"008,0.008 0.0429,0.0438 0.0533,0.0533 0.34552,0.29445 1.54536,0.98476 5.27553,1.86508 3.37632,0.81851 5.61232,1.55389 6.87418,2.18482 1.90987,0.97196 3.24419,2.2317 3.94334,3.78346 0.69911,1.53472 0.8526,3.33157 0.4263,5.27553 -0.4263,1.89279 -1.3918" +"9,3.63852 -2.82428,5.27554 -1.41532,1.637 -3.21647,2.93297 -5.38211,3.83673 -2.1486,0.88672 -4.50604,1.38549 -6.92746,1.38549 -3.0694,-1e-5 -5.53343,-0.46467 -7.46034,-1.38549 -2.01217,-0.95491 -3.46374,-2.4619 -4.31634,-4.42291 -0.81851,-1.90986 -0." +"9933,-4.07762 -0.53289,-6.44786 0,-3e-5 0.15987,-0.74605 0.15987,-0.74605 0,0 6.12814,0 6.12814,0 0,0 -0.0533,0.74605 -0.0533,0.74605 -0.15348,1.41532 -0.002,2.55782 0.37302,3.41043 0.35809,0.81853 1.04019,1.49633 2.13152,2.02496 1.15954,0.5627 2.608" +"98,0.8526 4.26305,0.8526 1.48355,-1e-5 2.83921,-0.24939 4.04991,-0.69273 1.19365,-0.4263 2.14218,-0.98904 2.82427,-1.70523 0.66502,-0.71622 1.05511,-1.47288 1.22563,-2.2914 0.17052,-0.73324 0.13002,-1.3535 -0.15987,-1.86508 -0.32399,-0.54564 -0.96558" +",-1.02953 -1.97165,-1.43878 0,-1e-5 -5.22226,-1.54536 -5.22226,-1.54536 -2.91592,-0.73323 -4.87905,-1.43238 -6.02155,-2.13152 -1.55177,-0.92081 -2.67081,-2.10169 -3.25059,-3.51702 -0.57977,-1.39831 -0.64158,-2.94791 -0.26643,-4.63608 0.3922,-1.80753 " +"1.26399,-3.52767 2.61111,-5.06237 1.3642,-1.55177 3.12482,-2.76885 5.22225,-3.57031 1.85443,-0.6954 3.80596,-1.10321 5.86169,-1.17234 z m 55.9526,0.10658 c 0.33725,-0.0263 0.65436,0 1.01247,0 10e-6,0 3.83675,0.4263 3.83675,0.4263 -10e-6,0 1.27891,0.1" +"0658 1.27891,0.10658 2e-5,1e-5 -1.86508,4.74264 -1.86508,4.74264 -1e-5,2e-5 -0.37302,0.74604 -0.37302,0.74604 0,-2e-5 -2.93084,-0.26644 -2.93084,-0.26644 -0.86541,0 -1.50113,0.13352 -1.91838,0.4263 -0.0277,0.0209 -0.081,0.0842 -0.10658,0.10658 -0.055" +"9,0.049 -0.14991,0.13458 -0.21315,0.21316 -0.25659,0.33651 -0.56912,0.93786 -0.79932,2.02495 -2e-5,0 -0.11084,0.4604 -0.21315,0.85261 1.34713,1e-5 4.58277,0 4.58277,0 0,1e-5 -1.17233,5.27552 -1.17233,5.27552 0,-1e-5 -3.35076,0 -4.4762,0 -0.34106,1.53" +"469 -4.5295,20.3028 -4.5295,20.3028 -2e-5,-2e-5 -6.18143,0 -6.18143,0 -2e-5,-2e-5 4.01793,-18.03485 4.5295,-20.3028 -1.04021,-1e-5 -3.57031,0 -3.57031,0 0,-1e-5 1.17234,-5.27552 1.17234,-5.27552 10e-6,1e-5 2.54504,0 3.51701,0 0.17052,-0.73324 0.4263," +"-1.65194 0.4263,-1.65194 0.37516,-1.70522 0.76735,-2.93085 1.27891,-3.78346 0.69917,-1.17659 1.68606,-2.16137 2.93087,-2.87756 1.02527,-0.59575 2.32198,-0.95194 3.78346,-1.06576 z m 14.76082,0.26644 c -2e-5,-1e-5 -1.6157,7.27064 -2.02495,9.11228 1.19" +"364,1e-5 3.99661,0 3.99661,0 0,1e-5 -1.17233,5.27552 -1.17233,5.27552 -2e-5,-1e-5 -2.93939,0 -3.99662,0 -0.32401,1.46647 -2.87756,12.84246 -2.87756,12.84246 2e-5,-2e-5 -0.21316,1.36631 -0.21316,1.75851 2.8e-4,0.0131 -10e-4,0.0437 0,0.0533 8.4e-4,0.00" +"4 -10e-4,0.05 0,0.0533 0.002,0.003 0.0512,-0.002 0.0533,0 0,-2e-5 0.63947,0.0533 0.63947,0.0533 0,0 2.93085,-0.21315 2.93085,-0.21315 0,0 -0.31973,4.74264 -0.31973,4.74264 2e-5,0 0.0533,0.85261 0.0533,0.85261 -2e-5,-2e-5 -4.20978,0.4796 -4.20978,0.47" +"96 -1.6711,-2e-5 -2.89675,-0.27283 -3.78346,-0.8526 -0.93785,-0.61392 -1.48354,-1.42814 -1.70522,-2.45126 -0.0341,-0.18759 -0.10658,-0.46042 -0.10658,-0.85261 0,-0.76736 0.14495,-2.06545 0.63946,-4.31634 2e-5,2e-5 2.24023,-10.03524 2.7177,-12.14972 -" +"0.80143,-1e-5 -2.93085,0 -2.93085,0 2e-5,-1e-5 1.17233,-5.27552 1.17233,-5.27552 -2e-5,10e-6 2.07824,0 2.93086,0 0.27281,-1.22775 1.22562,-5.4354 1.22562,-5.4354 0,2e-5 4.95581,-2.61112 4.95581,-2.61112 -10e-6,2e-5 2.02495,-1.06576 2.02495,-1.06576 z" +" m -196.366934,0.21315 c 2e-5,0 23.979684,0 23.979684,0 0,0 -1.3322,5.96828 -1.3322,5.96828 0,2e-5 -15.997114,0 -17.531814,0 -0.27282,1.21073 -1.36631,6.11322 -1.75851,7.88665 2.2168,0 15.18713,0 15.18713,0 0,0 -1.33221,5.96826 -1.33221,5.96826 -1e-5" +",0 -13.65242,0 -15.18713,0 -0.32399,1.48355 -3.25058,14.65426 -3.25058,14.65426 2e-5,-2e-5 -6.44786,0 -6.44786,0 1e-5,-2e-5 7.67349,-34.47745 7.67349,-34.47745 z m 32.132764,8.41954 c 0.24067,-0.0296 0.50358,0 0.74604,0 1.5347,0 2.95217,0.4668 4.3163" +"5,1.43877 0,2e-5 0.8526,0.58617 0.8526,0.58617 0,0 -3.30386,5.4354 -3.30386,5.4354 0,-2e-5 -0.90589,-0.63946 -0.90589,-0.63946 -0.66504,-0.42629 -1.38123,-0.63946 -2.13153,-0.63946 -0.64799,2e-5 -1.25121,0.2302 -1.86509,0.63946 -0.64797,0.4263 -1.189" +"4,0.99115 -1.59864,1.75851 -0.7162,1.31304 -1.24056,2.78377 -1.59865,4.36963 0,1e-5 -2.87756,13.10889 -2.87756,13.10889 0,-2e-5 -6.181434,0 -6.181434,0 0,-2e-5 5.701844,-25.57832 5.701844,-25.57832 2e-5,1e-5 5.75512,0 5.75512,0 0,1e-5 -0.19824,0.7758" +"8 -0.26645,1.06576 0.27284,-0.20461 0.56059,-0.48599 0.79933,-0.63946 0.82597,-0.4929 1.69837,-0.80035 2.55782,-0.90589 z m 18.33114,0 c 0.37219,-0.0282 0.73859,0 1.11906,0 3.47866,0 6.11108,1.21922 7.83335,3.62359 1.07428,1.55174 1.65195,3.47012 1.6" +"5195,5.75512 0,1.26185 -0.15561,2.61965 -0.47959,4.10319 0,0 -0.47961,1.86509 -0.47961,1.86509 0,-2e-5 -15.63261,0 -17.37194,0 -0.0341,0.35808 -0.0533,0.74177 -0.0533,1.06576 0,1.33009 0.27283,2.37665 0.85261,3.14401 0.2755,0.37513 0.5949,0.71299 0.9" +"5919,0.95918 0.68678,0.44789 1.57334,0.69275 2.61112,0.69275 1.26188,-2e-5 2.37025,-0.34745 3.41044,-1.01248 0.98905,-0.63093 1.93544,-1.63914 2.77099,-3.03742 0,-3e-5 6.60773,0 6.60773,0 0,-3e-5 -0.58616,1.27891 -0.58616,1.27891 -1.26187,2.55785 -3." +"02251,4.55294 -5.22225,5.96828 -2.19973,1.41533 -4.82791,2.1848 -7.72679,2.1848 -3.76854,-1e-5 -6.57363,-1.21922 -8.31296,-3.62358 -1.72226,-2.35323 -2.09315,-5.60593 -1.17233,-9.69846 0.92083,-4.16073 2.7582,-7.48591 5.43539,-9.80502 2.39958,-2.0806" +"2 5.12245,-3.23468 8.15309,-3.46372 z m 27.76315,0 c 0.37218,-0.0282 0.73857,0 1.11904,0 3.47867,0 6.1111,1.21922 7.83337,3.62359 1.07429,1.55174 1.65193,3.47012 1.65193,5.75512 0,1.2448 -0.1556,2.58341 -0.4796,4.0499 0,2e-5 -0.47958,1.91838 -0.47958" +",1.91838 0,-2e-5 -15.63263,0 -17.37195,0 -0.0171,0.2387 -0.0362,0.45402 -0.0533,0.69275 -0.0128,0.0895 0.006,0.22541 0,0.31972 -5e-4,0.0154 0,0.0384 0,0.0533 0,0.2558 0.0362,0.5073 0.0533,0.74604 0.0852,0.97196 0.33892,1.78409 0.79932,2.39797 0.0877," +"0.11936 0.17008,0.2667 0.26644,0.37302 0.78101,0.83554 1.8864,1.27891 3.30387,1.27891 1.26188,-2e-5 2.38731,-0.34745 3.41045,-1.01248 0.98904,-0.63093 1.93542,-1.63914 2.77098,-3.03742 0,-3e-5 6.66102,0 6.66102,0 -1e-5,-3e-5 -0.63946,1.27891 -0.63946" +",1.27891 -1.26186,2.55785 -3.0225,4.55294 -5.22224,5.96828 -2.19974,1.41533 -4.82791,2.1848 -7.72678,2.1848 -3.76853,-1e-5 -6.57363,-1.21922 -8.31296,-3.62358 -1.12545,-1.53472 -1.65194,-3.48931 -1.65194,-5.80841 0,-0.35812 0.0192,-0.74391 0.0533,-1." +"11905 0.0682,-0.88671 0.20463,-1.78196 0.42631,-2.771 0.92084,-4.14368 2.70491,-7.48591 5.3821,-9.80502 2.39957,-2.08062 5.17575,-3.23468 8.20639,-3.46372 z m 75.61591,0 c 0.38084,-0.0293 0.73112,0 1.11905,0 3.54687,0 6.2731,1.20004 8.04652,3.5703 1." +"7564,2.37023 2.18269,5.56754 1.27891,9.59186 -0.69913,3.13763 -1.70947,5.672 -3.0907,7.51365 -1.38126,1.84165 -3.14188,3.34649 -5.22226,4.36962 -2.06328,1.02314 -4.24813,1.54535 -6.44786,1.54535 -3.61507,-1e-5 -6.30719,-1.23628 -8.04652,-3.62358 -1.1" +"2546,-1.51764 -1.70522,-3.47226 -1.70522,-5.80841 2e-5,-1.26187 0.13856,-2.6026 0.4796,-4.10319 1.02315,-4.57001 3.11202,-8.05078 6.18143,-10.28462 2.25301,-1.62634 4.74114,-2.56606 7.40705,-2.77098 z m 93.62733,0 c 0.4496,-0.0277 0.86593,0 1.3322,0 " +"2.14859,0 3.83675,0.2174 5.11567,0.74602 1.36418,0.54569 2.33189,1.31729 2.87756,2.23811 0.52864,0.86963 0.79933,1.93756 0.79933,3.25057 10e-6,2e-5 -0.63948,3.89004 -0.63948,3.89004 3e-5,0 -1.17232,5.27554 -1.17232,5.27554 -1.00611,4.50176 -1.22776,6" +".18995 -1.27893,6.82089 -0.0512,0.85262 0.0277,1.6839 0.26645,2.45125 2e-5,-2e-5 0.4263,1.38549 0.4263,1.38549 2e-5,-2e-5 -6.288,0 -6.288,0 -2e-5,-2e-5 -0.26645,-0.79933 -0.26645,-0.79933 -0.10231,-0.37512 -0.0725,-0.8526 -0.10657,-1.27891 -1.19365,0" +".73325 -2.38944,1.38336 -3.46373,1.75851 -1.58584,0.54569 -3.23139,0.8526 -4.90251,0.8526 -2.89886,-1e-5 -5.04532,-0.75454 -6.3413,-2.2381 -0.98902,-1.09133 -1.43877,-2.42567 -1.43877,-3.94332 -2e-5,-0.57977 0.0767,-1.18087 0.21314,-1.81179 0.28988,-" +"1.29597 0.81638,-2.49603 1.65194,-3.57032 0.81851,-1.05726 1.78623,-1.92689 2.87756,-2.55782 1.05726,-0.63092 2.23598,-1.07855 3.46374,-1.3855 -2e-5,0 3.78346,-0.63946 3.78346,-0.63946 2.91594,-0.34106 5.09221,-0.76521 6.66102,-1.22562 0.0341,-0.1705" +"2 0.10657,-0.37302 0.10657,-0.37302 0.24726,-1.09718 0.21632,-1.92188 -0.0533,-2.34468 -0.0198,-0.0273 -0.0842,-0.0831 -0.10657,-0.10658 -0.0576,-0.0614 -0.14603,-0.15779 -0.21316,-0.21315 -0.64135,-0.50753 -1.73506,-0.74603 -3.19728,-0.74603 -1.6540" +"7,0 -2.87756,0.27071 -3.73018,0.79931 -0.83555,0.52863 -1.60931,1.49634 -2.29139,2.87756 -1e-5,-1e-5 -6.44787,0 -6.44787,0 2e-5,-1e-5 0.58617,-1.27891 0.58617,-1.27891 0.76733,-1.77345 1.68178,-3.24418 2.82428,-4.36963 1.1425,-1.12547 2.68572,-1.9972" +"4 4.4762,-2.61111 1.37216,-0.45297 2.8705,-0.75354 4.47621,-0.85261 z m 27.01711,0 c 0.24046,-0.0296 0.50356,0 0.74603,0 1.55173,0 3.00545,0.4668 4.36963,1.43877 2e-5,2e-5 0.79932,0.58617 0.79932,0.58617 1e-5,0 -3.30386,5.4354 -3.30386,5.4354 10e-6,-" +"2e-5 -0.9059,-0.63946 -0.9059,-0.63946 -0.66503,-0.42629 -1.34501,-0.63946 -2.07824,-0.63946 -0.64801,2e-5 -1.28744,0.2302 -1.91839,0.63946 -0.64797,0.4263 -1.11904,0.99115 -1.54534,1.75851 -0.69916,1.31304 -1.24056,2.78377 -1.59865,4.36963 -2e-5,1e-" +"5 -2.93085,13.10889 -2.93085,13.10889 2e-5,-2e-5 -6.18142,0 -6.18142,0 0,-2e-5 5.70182,-25.57832 5.70182,-25.57832 -10e-6,1e-5 5.75512,0 5.75512,0 0,1e-5 -0.14494,0.77588 -0.21314,1.06576 0.27282,-0.20461 0.54353,-0.48599 0.79932,-0.63946 0.81263,-0." +"4929 1.64571,-0.80035 2.50455,-0.90589 z m 18.27783,0 c 0.37185,-0.0282 0.73859,0 1.11906,0 3.47866,0 6.12813,1.21922 7.83337,3.62359 1.09135,1.55174 1.65193,3.47012 1.65193,5.75512 -2e-5,1.26185 -0.2089,2.61965 -0.53289,4.10319 0,0 -0.4263,1.86509 -" +"0.4263,1.86509 -10e-6,-2e-5 -15.64968,0 -17.37194,0 -0.0341,0.35808 -0.10659,0.74177 -0.10659,1.06576 0,1.33009 0.28989,2.37665 0.85262,3.14401 0.0877,0.11936 0.223,0.2667 0.31972,0.37302 0.056,0.0597 0.15412,0.15773 0.21316,0.21314 0.76235,0.69302 1" +".79981,1.06577 3.0907,1.06577 1.26189,-2e-5 2.37027,-0.34745 3.41045,-1.01248 0.98905,-0.63093 1.91839,-1.63914 2.77099,-3.03742 -2e-5,-3e-5 6.66102,0 6.66102,0 0,-3e-5 -0.63946,1.27891 -0.63946,1.27891 -1.26187,2.55785 -3.03955,4.55294 -5.22224,5.96" +"828 -2.21677,1.41533 -4.81085,2.1848 -7.72679,2.1848 -3.76851,-1e-5 -6.52034,-1.21922 -8.25966,-3.62358 -1.7223,-2.35323 -2.1294,-5.60593 -1.22563,-9.69846 0.92081,-4.16073 2.70491,-7.48591 5.38211,-9.80502 2.41475,-2.08062 5.17852,-3.23468 8.20637,-" +"3.46372 z m -93.3076,0.47959 c 2e-5,1e-5 6.34131,0 6.34131,0 2e-5,1e-5 0.78226,15.17861 0.79931,15.40027 0.25578,-0.54356 0.45424,-1.00087 0.47961,-1.06575 1e-5,1e-5 6.98074,-14.33452 6.98074,-14.33452 2e-5,1e-5 5.80841,0 5.80841,0 -10e-6,1e-5 0.5328" +"8,14.99528 0.53288,15.08054 0.17055,-0.30691 7.93994,-15.08054 7.93994,-15.08054 -2e-5,1e-5 6.28801,0 6.28801,0 -10e-6,1e-5 -13.85493,25.57832 -13.85493,25.57832 2e-5,-2e-5 -5.70183,0 -5.70183,0 0,-2e-5 -0.55206,-13.86984 -0.58617,-14.65426 -2.35323," +"4.8258 -7.14063,14.65426 -7.14063,14.65426 0,-2e-5 -5.86168,0 -5.86168,0 0,-2e-5 -2.02497,-25.57832 -2.02497,-25.57832 z m -148.88715,4.84922 c -1.46893,0.062 -2.80295,0.59149 -4.04989,1.59864 -0.98902,0.78441 -1.65621,1.86084 -2.18483,3.03743 0,2e-5" +" 10.49777,0 10.49777,0 0.0171,-0.18756 0.0533,-0.41564 0.0533,-0.58617 -2e-5,-0.97195 -0.17266,-1.72653 -0.47959,-2.2381 -0.75028,-1.22777 -1.86295,-1.8118 -3.51702,-1.8118 -0.0991,0 -0.2218,-0.004 -0.31973,0 z m 27.76313,0 c -1.46892,0.062 -2.80295," +"0.59149 -4.0499,1.59864 -0.98904,0.78441 -1.63913,1.86084 -2.1848,3.03743 0,2e-5 10.49776,0 10.49776,0 0.017,-0.18756 0.0533,-0.41564 0.0533,-0.58617 -1e-5,-0.97195 -0.1556,-1.72653 -0.4796,-2.2381 -0.14894,-0.24939 -0.35043,-0.49739 -0.53288,-0.6927" +"4 -0.71199,-0.73572 -1.6919,-1.11906 -2.98413,-1.11906 -0.0991,0 -0.2218,-0.004 -0.31974,0 z m 214.75136,0 c -1.51056,0.0465 -2.92125,0.55794 -4.20977,1.59864 -0.97198,0.78441 -1.63915,1.86084 -2.18482,3.03743 2e-5,2e-5 10.44449,0 10.44449,0 0.017,-0" +".18756 0.0533,-0.41564 0.0533,-0.58617 -1e-5,-0.97195 -0.1556,-1.72653 -0.4796,-2.2381 -0.73324,-1.21072 -1.86296,-1.79474 -3.51702,-1.8118 -0.049,5.3e-4 -0.0578,-0.001 -0.10657,0 z m -139.61502,0.10658 c -1.40963,0.16739 -2.72036,0.81051 -3.94333,1." +"91837 -1.46648,1.33009 -2.53012,3.41897 -3.14399,6.18143 -0.25579,1.15955 -0.37303,2.15071 -0.37303,3.03742 2e-5,1.2107 0.23233,2.16137 0.69275,2.87756 0.12257,0.18384 0.28516,0.37811 0.42631,0.53289 0.75804,0.80488 1.81659,1.22563 3.144,1.22563 1.72" +"226,-2e-5 3.23992,-0.64159 4.68935,-1.97167 1.46652,-1.34714 2.51307,-3.45734 3.144,-6.288 0.5798,-2.59195 0.49878,-4.52736 -0.31972,-5.75512 -0.7844,-1.19366 -1.93116,-1.75851 -3.51701,-1.75851 -0.26911,0 -0.5383,-0.031 -0.79933,0 z m 96.29173,9.325" +"43 c -1.44941,0.39218 -3.07367,0.72258 -5.22224,1.01248 -1.60289,0.23874 -2.74541,0.49024 -3.41045,0.74603 -0.57976,0.23872 -1.04658,0.56911 -1.43878,1.01248 -0.37516,0.42627 -0.62666,0.87392 -0.74602,1.38549 -0.0341,0.20464 -0.0533,0.41564 -0.0533,0" +".58617 0,0.0138 -3.1e-4,0.0396 0,0.0533 0.002,0.0406 -0.004,0.1207 0,0.15985 0.0107,0.0774 0.0322,0.1944 0.0533,0.26645 0.008,0.0237 0.0445,0.0834 0.0533,0.10657 0.0187,0.0458 0.0301,0.11611 0.0533,0.15987 0.0243,0.0433 0.0779,0.11849 0.10658,0.15986" +" 0.0446,0.0614 0.1055,0.1556 0.15987,0.21315 0.42631,0.47746 1.27678,0.69275 2.50454,0.69275 1.34715,1e-5 2.6431,-0.25578 3.83675,-0.85261 1.17662,-0.57977 2.12513,-1.44518 2.82427,-2.45126 0.51159,-0.7162 0.92083,-1.8182 1.27892,-3.25057 z\"/>\n" +" <path id=\"path2\" style=\"fill:none;stroke:#bd0000;stroke-width:8.52610779;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;\" d=\"m 417.07944,250.20635 c 0.69221,1.77962 1.38445,3.55633 2.1055,5.2941 1.11046,2.36077 2.39396,4.6206 " +"3.93704,6.73045 8.33557,11.33086 22.29546,17.53495 40.01931,19.07947 0,0 19.06506,0 19.06506,0 6.02811,-0.47014 12.34467,-1.34696 18.89198,-2.62759 11.29193,-2.2079 23.26167,-5.5998 35.69288,-10.13244 9.41715,-3.43375 19.0939,-7.49624 28.91485,-12.21" +"778 21.38688,-10.25215 43.48041,-23.47509 65.15575,-39.43235 7.13857,-5.25082 13.98872,-10.63863 20.56487,-16.1173 6.02813,-5.01576 11.8111,-10.10942 17.33446,-15.25927 15.41645,-14.85689 27.0545,-29.94597 33.64507,-43.1949 6.86452,-13.7969 8.23461,-" +"25.59358 2.61028,-33.02493 -3.44673,-4.56146 -9.21527,-7.00589 -16.64228,-7.5813 33.45753,-25.10471 52.95528,-55.55833 45.96096,-74.7589 -2.22096,-6.1277 -7.10981,-10.6992 -14.11858,-13.2273 -3.11497,-1.1205 -6.61943,-1.8301 -10.4411,-2.1531 0,0 -10." +"29683,0 -10.29683,0 -14.37808,1.0369 -35.28664,6.1853 -53.0249,14.8785\"/>\n" +" <g id=\"g2\" style=\"fill:#bd0000;fill-opacity:1\" transform=\"scale(1.705222,1.705222)\">\n" +" <path id=\"path1\" transform=\"translate(15.5783,177.825)\" d=\"m 0,36 c 0,0 7.46,0 7.46,0 0,0 3.35,-14 3.35,-14 0,0 12.12,0 12.12,0 0,0 1.56,-6 1.56,-6 0,0 -12.17,0 -12.17,0 0,0 2.02,-9 2.02,-9 0,0 12.95,0 12.95,0 0,0 1.56,-7 1.56,-7 C 28.85,0" +" 8.4,0 8.4,0 8.4,0 0,36 0,36 z\"/>\n" +" <path id=\"path2\" transform=\"translate(41.5283,187.825)\" d=\"m 7.51,26 c 0,0 2.24,-9.4 2.24,-9.4 1.18,-5.09 3.67,-9.6 8.38,-9.6 0.42,0 0.83,0.21 1.14,0.26 0,0 1.82,-7.21 1.82,-7.21 -0.42,0 -0.88,-0.05 -1.4,-0.05 -3.47,0 -6.38,2.44 -8.32,5.94" +" 0,0 -0.2,0 -0.2,0 C 11.46,4.23 11.71,2.61 11.9,1 11.9,1 5.47,1 5.47,1 5.1,3.08 4.53,7.15 3.66,10.82 3.66,10.82 0,26 0,26 c 0,0 7.51,0 7.51,0 z\"/>\n" +" <path id=\"path3\" transform=\"translate(62.1583,187.825)\" d=\"M 20.06,19.25 C 17.99,20.26 15.63,20 12.88,20 10.71,20 9.03,19.62 8.11,18.88 7.63,18.07 7.43,16.81 7.47,16 17.6,16.27 23.99,13.93 24.31,7.53 24.55,2.7 21.02,0 15.89,0 6.73,0 0.73,8" +".08 0.34,15.86 0,22.65 3.52,26 10.78,26 c 2.79,0 6.49,-0.32 9.52,-1.23 0,0 -0.24,-5.52 -0.24,-5.52 z M 17.32,7.53 C 17.2,9.91 14.26,10.05 8.47,10 9.1,7.91 11.22,6 14.69,6 c 1.71,0 2.69,0.65 2.63,1.53 z\"/>\n" +" <path id=\"path4\" transform=\"translate(88.6783,187.825)\" d=\"M 20.05,19.25 C 17.98,20.26 15.62,20 12.88,20 10.7,20 9.03,19.62 8.11,18.88 7.63,18.07 7.42,16.81 7.46,16 17.6,16.27 23.98,13.93 24.31,7.53 24.55,2.7 21.02,0 15.89,0 6.72,0 0.72,8." +"08 0.33,15.86 0,22.65 3.52,26 10.77,26 c 2.8,0 6.5,-0.32 9.53,-1.23 0,0 -0.25,-5.52 -0.25,-5.52 z M 17.32,7.53 C 17.2,9.91 14.26,10.05 8.46,10 9.1,7.91 11.21,6 14.68,6 c 1.71,0 2.7,0.65 2.64,1.53 z\"/>\n" +" <path id=\"path5\" transform=\"translate(124.5883,187.825)\" d=\"M 22.74,26 C 22.8,22.83 23.56,17.85 24.35,14.58 24.35,14.58 27.56,1 27.56,1 25.52,0.31 22.34,0 19.28,0 6.86,0 0.7,9.2 0.27,17.82 0,23.23 2.93,26 7.49,26 c 2.95,0 6.28,-1.43 8.87,-" +"5.73 0,0 0.11,0 0.11,0 -0.2,2.07 -0.44,4.08 -0.57,5.73 0,0 6.84,0 6.84,0 z M 17.61,11.72 C 16.15,18.08 13.17,20 10.95,20 8.88,20 7.98,18.53 8.1,16.39 8.34,11.56 12.16,6 16.98,6 c 0.78,0 1.39,-0.14 1.96,-0.28 0,0 -1.33,6 -1.33,6 z\"/>\n" +" <path id=\"path6\" transform=\"translate(152.2183,187.825)\" d=\"m 0,24.82 c 1.44,1.12 4.46,1.13 7.61,1.18 6.73,0.05 11.81,-2.89 12.11,-8.29 0.17,-3.6 -2.62,-5.73 -5.35,-7.16 C 12.4,9.6 11.41,8.69 11.46,7.63 11.53,6.2 12.87,6 14.84,6 c 2.22,0 4" +",0.27 5.02,0.47 0,0 2.02,-5.42 2.02,-5.42 C 20.73,0.36 18.43,0 15.48,0 8.95,0 4.17,3.45 3.9,8.69 c -0.16,3.24 2.17,5.42 4.99,6.9 2.28,1.17 3.06,2.07 3,3.34 C 11.82,20.21 10.68,20 8.61,20 6.18,20 3.49,19.68 2.07,19.46 2.07,19.46 0,24.82 0,24.82 z\"/>\n" +" <path id=\"path7\" transform=\"translate(184.6683,176.825)\" d=\"m 7.45,37 c 0,0 6.05,-25 6.05,-25 0,0 -7.41,0 -7.41,0 0,0 -6.09,25 -6.09,25 0,0 7.45,0 7.45,0 z M 10.92,9 C 13.46,9 15.72,6.9 15.86,3.3 15.98,0.86 14.4,0 12.07,0 9.64,0 7.42,1.58 " +"7.29,3.94 7.17,6.32 8.75,9 10.92,9 z\"/>\n" +" <path id=\"path8\" transform=\"translate(198.9583,188.515)\" d=\"m 7.46,25.31 c 0,0 2.64,-11.26 2.64,-11.26 1.37,-5.73 4.32,-7.74 6.75,-7.74 1.92,0 2.48,0.82 2.39,2.01 -0.05,0.96 -0.2,1.97 -0.4,2.87 0,0 -3.36,14.12 -3.36,14.12 0,0 7.46,0 7.46,0" +" 0,0 3.54,-14.81 3.54,-14.81 C 26.75,9.22 27.05,7.31 27.11,6.15 27.33,1.64 25.08,0 20.94,0 c -3.32,0 -6.55,1.54 -9.1,4.88 0,0 -0.1,0 -0.1,0 0,0 0.68,-4.57 0.68,-4.57 0,0 -6.58,0 -6.58,0 C 5.41,2.45 4.86,5.04 4.08,8.06 4.08,8.06 0,25.31 0,25.31 c 0,0 " +"7.46,0 7.46,0 z\"/>\n" +" <path id=\"path9\" transform=\"translate(238.5183,177.825)\" d=\"m 0,36 c 0,0 7.46,0 7.46,0 0,0 3.36,-14 3.36,-14 0,0 12.11,0 12.11,0 0,0 1.56,-6 1.56,-6 0,0 -12.17,0 -12.17,0 0,0 2.02,-9 2.02,-9 0,0 12.95,0 12.95,0 0,0 1.56,-7 1.56,-7 C 28.85," +"0 8.4,0 8.4,0 8.4,0 0,36 0,36 z\"/>\n" +" <path id=\"path10\" transform=\"translate(264.4683,187.825)\" d=\"m 7.51,26 c 0,0 2.24,-9.4 2.24,-9.4 1.18,-5.09 3.67,-9.6 8.38,-9.6 0.42,0 0.83,0.21 1.14,0.26 0,0 1.82,-7.21 1.82,-7.21 -0.42,0 -0.88,-0.05 -1.4,-0.05 -3.47,0 -6.38,2.44 -8.32,5." +"94 0,0 -0.2,0 -0.2,0 C 11.46,4.23 11.71,2.61 11.9,1 11.9,1 5.47,1 5.47,1 5.11,3.08 4.53,7.15 3.66,10.82 3.66,10.82 0,26 0,26 c 0,0 7.51,0 7.51,0 z\"/>\n" +" <path id=\"path11\" transform=\"translate(285.0983,187.825)\" d=\"M 20.06,19.25 C 17.99,20.26 15.63,20 12.88,20 10.71,20 9.03,19.62 8.11,18.88 7.63,18.07 7.43,16.81 7.47,16 17.6,16.27 23.99,13.93 24.31,7.53 24.55,2.7 21.02,0 15.89,0 6.73,0 0.73" +",8.08 0.34,15.86 0,22.65 3.53,26 10.78,26 c 2.79,0 6.5,-0.32 9.52,-1.23 0,0 -0.24,-5.52 -0.24,-5.52 z M 17.32,7.53 C 17.2,9.91 14.26,10.05 8.47,10 9.1,7.91 11.22,6 14.69,6 c 1.71,0 2.69,0.65 2.63,1.53 z\"/>\n" +" <path id=\"path12\" transform=\"translate(311.6183,187.825)\" d=\"M 20.05,19.25 C 17.98,20.26 15.62,20 12.88,20 10.7,20 9.03,19.62 8.11,18.88 7.63,18.07 7.42,16.81 7.46,16 17.6,16.27 23.98,13.93 24.31,7.53 24.55,2.7 21.02,0 15.89,0 6.72,0 0.72," +"8.08 0.33,15.86 0,22.65 3.52,26 10.77,26 c 2.8,0 6.5,-0.32 9.53,-1.23 0,0 -0.25,-5.52 -0.25,-5.52 z M 17.32,7.53 C 17.2,9.91 14.26,10.05 8.46,10 9.1,7.91 11.21,6 14.68,6 c 1.71,0 2.7,0.65 2.64,1.53 z\"/>\n" +" <path id=\"path13\" transform=\"translate(337.9983,176.825)\" d=\"M 23.31,0 C 23.31,0 20.5,11.36 20.5,11.36 19.48,10.94 18.15,11 17.11,11 7.53,11 0.75,19.2 0.3,28.08 0,34.34 3.34,37 7.64,37 c 3.01,0 6.18,-1.33 8.58,-4.77 0,0 0.1,0 0.1,0 0,0 -0." +"57,4.77 -0.57,4.77 0,0 6.78,0 6.78,0 0.31,-3 0.96,-6.57 1.69,-9.83 0,0 6.49,-27.17 6.49,-27.17 0,0 -7.4,0 -7.4,0 z M 17.47,24.42 C 16.3,29.35 13.54,31 11.36,31 9.19,31 7.98,29.49 8.13,26.8 8.38,21.82 11.8,17 16.25,17 c 1.25,0 2.32,0.19 2.91,0.47 0,0 " +"-1.69,6.95 -1.69,6.95 z\"/>\n" +" <path id=\"path14\" transform=\"translate(367.7083,187.825)\" d=\"M 10.61,26 C 19.31,26 26.02,19.41 26.49,10.44 26.78,4.5 23.08,0 16.25,0 7.23,0 0.76,7.3 0.31,16.12 0,22.54 4.14,26 10.61,26 z m 1.17,-6 C 9.24,20 7.84,18.38 7.99,15.96 8.19,11.93" +" 10.68,6 14.97,6 c 2.96,0 3.87,2.27 3.75,4.5 -0.22,4.4 -2.9,9.5 -6.94,9.5 z\"/>\n" +" <path id=\"path15\" transform=\"translate(396.2683,187.825)\" d=\"M 7.2,26 C 7.2,26 9.9,14.58 9.9,14.58 11.03,9.49 13.85,6 16.38,6 c 1.82,0 2.32,1.33 2.23,3.07 -0.05,0.9 -0.25,1.91 -0.46,2.91 0,0 -3.34,14.02 -3.34,14.02 0,0 7.2,0 7.2,0 0,0 2.7," +"-11.47 2.7,-11.47 C 25.95,9.28 28.61,6 31.09,6 c 1.71,0 2.42,1.22 2.34,2.96 -0.05,1.01 -0.26,2.12 -0.52,3.13 0,0 -3.24,13.91 -3.24,13.91 0,0 7.25,0 7.25,0 0,0 3.49,-14.81 3.49,-14.81 0.27,-1.33 0.58,-3.4 0.63,-4.46 C 41.26,2.33 39.11,0 35.23,0 31.91," +"0 28.68,1.5 26.23,4.66 26.14,2.38 24.51,0 20.47,0 17.2,0 14.08,1.48 11.58,4.83 c 0,0 -0.1,0 -0.1,0 0,0 0.67,-3.83 0.67,-3.83 0,0 -6.42,0 -6.42,0 C 5.31,3.14 4.8,5.73 4.02,8.75 4.02,8.75 0,26 0,26 c 0,0 7.2,0 7.2,0 z\"/>\n" +" </g>\n" +" </g>\n" +"</svg>"; + +const char* gpl_logo_svg = (const char*) temp_binary_data_17; + +//================== juce-logo-with-text.svg ================== +static const unsigned char temp_binary_data_18[] = +"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" +"<svg\n" +" xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n" +" xmlns:cc=\"http://creativecommons.org/ns#\"\n" +" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n" +" xmlns:svg=\"http://www.w3.org/2000/svg\"\n" +" xmlns=\"http://www.w3.org/2000/svg\"\n" +" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n" +" xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\"\n" +" xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"\n" +" id=\"Layer_1\"\n" +" width=\"113.4\"\n" +" height=\"35.9\"\n" +" viewBox=\"0 0 113.4 35.9\"\n" +" version=\"1.1\"\n" +" inkscape:version=\"0.91 r13725\"\n" +" sodipodi:docname=\"juce-logo-with-text.svg\">\n" +" <metadata\n" +" id=\"metadata35\">\n" +" <rdf:RDF>\n" +" <cc:Work\n" +" rdf:about=\"\">\n" +" <dc:format>image/svg+xml</dc:format>\n" +" <dc:type\n" +" rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\" />\n" +" <dc:title />\n" +" </cc:Work>\n" +" </rdf:RDF>\n" +" </metadata>\n" +" <sodipodi:namedview\n" +" pagecolor=\"#ffffff\"\n" +" bordercolor=\"#666666\"\n" +" borderopacity=\"1\"\n" +" objecttolerance=\"10\"\n" +" gridtolerance=\"10\"\n" +" guidetolerance=\"10\"\n" +" inkscape:pageopacity=\"0\"\n" +" inkscape:pageshadow=\"2\"\n" +" inkscape:window-width=\"1920\"\n" +" inkscape:window-height=\"1029\"\n" +" id=\"namedview33\"\n" +" showgrid=\"false\"\n" +" inkscape:zoom=\"9.3827159\"\n" +" inkscape:cx=\"26.137564\"\n" +" inkscape:cy=\"37.52419\"\n" +" inkscape:window-x=\"0\"\n" +" inkscape:window-y=\"0\"\n" +" inkscape:window-maximized=\"1\"\n" +" inkscape:current-layer=\"Layer_1\" />\n" +" <style\n" +" id=\"style3\"><![CDATA[\n" +"\t.st0{clip-path:url(#SVGID_2_);fill:#A65A95;}\n" +"\t.st1{clip-path:url(#SVGID_2_);fill:#E67E3C;}\n" +"\t.st2{clip-path:url(#SVGID_2_);fill:#E73E51;}\n" +"\t.st3{clip-path:url(#SVGID_2_);fill:#F0E049;}\n" +"\t.st4{clip-path:url(#SVGID_2_);fill:#F19F53;}\n" +"\t.st5{clip-path:url(#SVGID_2_);fill:#F5BD47;}\n" +"\t.st6{clip-path:url(#SVGID_2_);fill:#288DC1;}\n" +"\t.st7{clip-path:url(#SVGID_2_);fill:#FFFFFF;}\n" +"\t.st8{clip-path:url(#SVGID_2_);fill:#9CB6D3;}\n" +"\t.st9{clip-path:url(#SVGID_2_);fill:#6CC04A;}\n" +"]]></style>\n" +" <defs\n" +" id=\"defs5\">\n" +" <path\n" +" id=\"SVGID_1_\"\n" +" d=\"M0 0h113.4v35.9H0z\" />\n" +" </defs>\n" +" <clipPath\n" +" id=\"SVGID_2_\">\n" +" <use\n" +" xlink:href=\"#SVGID_1_\"\n" +" overflow=\"visible\"\n" +" id=\"use9\" />\n" +" </clipPath>\n" +" <path\n" +" class=\"st9\"\n" +" d=\"M5.2 5.2c7-7 18.4-7 25.4 0s7 18.4 0 25.4-18.4 7-25.4 0c-6.9-7-6.9-18.4 0-25.4\"\n" +" id=\"path11\"\n" +" clip-path=\"url(#SVGID_2_)\"\n" +" style=\"fill:#6cc04a;fill-opacity:1\" />\n" +" <path\n" +" class=\"st7\"\n" +" d=\"m 29.8,29.8 c 6.5,-6.5 6.5,-17.2 0,-23.7 -6.5,-6.5 -17.2,-6.5 -23.7,0 -6.5,6.5 -6.5,17.2 0,23.7 6.5,6.5 17.1,6.5 23.7,0\"\n" +" id=\"path13\"\n" +" clip-path=\"url(#SVGID_2_)\"\n" +" inkscape:connector-curvature=\"0\"\n" +" style=\"fill:#ffffff\" />\n" +" <path\n" +" class=\"st8\"\n" +" d=\"M28.4 27.5c.4.4 1.1.4 1.5 0l.1-.1c1.8-2.2 2.9-4.9 3.2-7.7 0-.3-.1-.6-.3-.9-.2-.2-.5-.4-.8-.4H19.9c-.2 0-.3.2-.1.4l8.6 8.7z\"\n" +" id=\"path15\"\n" +" clip-path=\"url(#SVGID_2_)\"\n" +" style=\"fill:#9cb6d3;fill-opacity:1\" />\n" +" <path\n" +" class=\"st0\"\n" +" d=\"M8.3 28.4c-.2.2-.3.5-.3.8 0 .3.2.6.4.8 2.2 1.8 4.9 2.9 7.7 3.2.3 0 .7-.1.9-.3.2-.2.3-.5.3-.8V19.9c0-.2-.2-.3-.4-.1l-8.6 8.6z\"\n" +" id=\"path17\"\n" +" clip-path=\"url(#SVGID_2_)\"\n" +" style=\"fill:#a65a95;fill-opacity:1\" />\n" +" <path\n" +" class=\"st6\"\n" +" d=\"M18.9 33c.2.2.5.3.9.3 2.8-.3 5.5-1.4 7.7-3.2l.1-.1c.4-.4.4-1.1 0-1.5l-8.7-8.7c-.1-.1-.4 0-.4.1v12.2c0 .4.2.7.4.9\"\n" +" id=\"path19\"\n" +" clip-path=\"url(#SVGID_2_)\"\n" +" style=\"fill:#288dc1;fill-opacity:1\" />\n" +" <path\n" +" class=\"st1\"\n" +" d=\"M7.5 8.3c-.5-.4-1.1-.4-1.6 0l-.1.1c-1.8 2.2-2.9 4.9-3.2 7.7 0 .3.1.6.3.8.2.2.5.4.8.4H16c.2 0 .3-.2.1-.4L7.5 8.3z\"\n" +" id=\"path21\"\n" +" clip-path=\"url(#SVGID_2_)\"\n" +" style=\"fill:#e67e3c;fill-opacity:1\" />\n" +" <path\n" +" class=\"st2\"\n" +" d=\"M2.9 18.8c-.2.2-.3.5-.3.9.3 2.8 1.4 5.5 3.2 7.7.2.3.5.4.8.4.3 0 .6-.1.8-.3l8.6-8.6c.1-.1 0-.4-.1-.4H3.7c-.3 0-.6.1-.8.3\"\n" +" id=\"path23\"\n" +" clip-path=\"url(#SVGID_2_)\"\n" +" style=\"fill:#e73e51;fill-opacity:1\" />\n" +" <path\n" +" class=\"st3\"\n" +" d=\"M32.9 17c.2-.2.3-.5.3-.9-.3-2.8-1.4-5.5-3.2-7.7-.2-.2-.5-.4-.8-.4-.3 0-.6.1-.8.3L19.7 17c-.1.1 0 .4.1.4H32c.4-.1.7-.2.9-.4\"\n" +" id=\"path25\"\n" +" clip-path=\"url(#SVGID_2_)\"\n" +" style=\"fill:#f0e049;fill-opacity:1\" />\n" +" <path\n" +" class=\"st5\"\n" +" d=\"M18.9 16.1l8.6-8.6c.2-.2.4-.5.3-.8 0-.3-.2-.6-.4-.8-2.2-1.8-4.9-2.9-7.7-3.2-.3 0-.7.1-.9.3-.2.2-.3.5-.3.8V16c0 .2.3.3.4.1\"\n" +" id=\"path27\"\n" +" clip-path=\"url(#SVGID_2_)\"\n" +" style=\"fill:#f5bd47;fill-opacity:1\" />\n" +" <path\n" +" class=\"st4\"\n" +" d=\"M17.3 3.7c0-.3-.1-.6-.4-.8-.2-.2-.5-.3-.9-.3-2.7.4-5.4 1.5-7.6 3.2l-.1.1c-.2.2-.3.5-.3.9 0 .2.1.5.3.7l8.6 8.6c.1.1.4 0 .4-.2V3.7z\"\n" +" id=\"path29\"\n" +" clip-path=\"url(#SVGID_2_)\"\n" +" style=\"fill:#f19f53;fill-opacity:1\" />\n" +" <path\n" +" class=\"st7\"\n" +" d=\"M45.3 29.3c-2.4 0-4.4-.9-6.1-3.2l2.4-2c1.2 1.5 2.3 2.1 3.7 2.1 2.6 0 4.3-1.9 4.3-4.9V6.8h3.3v14.5c0 4.8-3.1 8-7.6 8M66 29.3c-4.8 0-8.8-3.5-8.8-9.3V6.8h3.3v13c0 3.9 2.3 6.4 5.6 6.4s5.6-2.5 5.6-6.4v-13H75V20c-.2 5.8-4.3 9.3-9 9.3M89.2 29.3c-6." +"3 0-11.4-5.1-11.4-11.4 0-6.3 5.2-11.4 11.4-11.4 2.8 0 5.3 1 7.2 2.6l-1.9 2.4c-2-1.4-3.4-1.9-5.2-1.9-4.5 0-8.1 3.6-8.1 8.3 0 4.7 3.6 8.3 8.1 8.3 1.8 0 3.3-.6 5.2-1.9l2 2.4c-2.5 2-4.7 2.6-7.3 2.6M100 29V6.8h13.4v3h-10.1v6.5h9.7v3h-9.7v6.8h10.1V29z\"\n" +" id=\"path31\"\n" +" clip-path=\"url(#SVGID_2_)\"\n" +" style=\"fill:#ffffff;fill-opacity:1\" />\n" +"</svg>\n"; + +const char* jucelogowithtext_svg = (const char*) temp_binary_data_18; + +//================== juce_icon.png ================== +static const unsigned char temp_binary_data_19[] = +{ 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,2,0,0,0,2,0,8,6,0,0,0,244,120,212,250,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101,60,0,0,3,40,105,84,88,116,88,77,76,58, +99,111,109,46,97,100,111,98,101,46,120,109,112,0,0,0,0,0,60,63,120,112,97,99,107,101,116,32,98,101,103,105,110,61,34,239,187,191,34,32,105,100,61,34,87,53,77,48,77,112,67,101,104,105,72,122,114,101,83,122,78,84,99,122,107,99,57,100,34,63,62,32,60,120, +58,120,109,112,109,101,116,97,32,120,109,108,110,115,58,120,61,34,97,100,111,98,101,58,110,115,58,109,101,116,97,47,34,32,120,58,120,109,112,116,107,61,34,65,100,111,98,101,32,88,77,80,32,67,111,114,101,32,53,46,54,45,99,48,54,55,32,55,57,46,49,53,55, +55,52,55,44,32,50,48,49,53,47,48,51,47,51,48,45,50,51,58,52,48,58,52,50,32,32,32,32,32,32,32,32,34,62,32,60,114,100,102,58,82,68,70,32,120,109,108,110,115,58,114,100,102,61,34,104,116,116,112,58,47,47,119,119,119,46,119,51,46,111,114,103,47,49,57,57, +57,47,48,50,47,50,50,45,114,100,102,45,115,121,110,116,97,120,45,110,115,35,34,62,32,60,114,100,102,58,68,101,115,99,114,105,112,116,105,111,110,32,114,100,102,58,97,98,111,117,116,61,34,34,32,120,109,108,110,115,58,120,109,112,61,34,104,116,116,112, +58,47,47,110,115,46,97,100,111,98,101,46,99,111,109,47,120,97,112,47,49,46,48,47,34,32,120,109,108,110,115,58,120,109,112,77,77,61,34,104,116,116,112,58,47,47,110,115,46,97,100,111,98,101,46,99,111,109,47,120,97,112,47,49,46,48,47,109,109,47,34,32,120, +109,108,110,115,58,115,116,82,101,102,61,34,104,116,116,112,58,47,47,110,115,46,97,100,111,98,101,46,99,111,109,47,120,97,112,47,49,46,48,47,115,84,121,112,101,47,82,101,115,111,117,114,99,101,82,101,102,35,34,32,120,109,112,58,67,114,101,97,116,111, +114,84,111,111,108,61,34,65,100,111,98,101,32,80,104,111,116,111,115,104,111,112,32,67,67,32,50,48,49,53,32,40,77,97,99,105,110,116,111,115,104,41,34,32,120,109,112,77,77,58,73,110,115,116,97,110,99,101,73,68,61,34,120,109,112,46,105,105,100,58,53,52, +53,66,70,48,69,70,55,66,48,54,49,49,69,53,66,51,49,53,69,69,54,51,67,65,56,68,70,50,56,48,34,32,120,109,112,77,77,58,68,111,99,117,109,101,110,116,73,68,61,34,120,109,112,46,100,105,100,58,53,52,53,66,70,48,70,48,55,66,48,54,49,49,69,53,66,51,49,53,69, +69,54,51,67,65,56,68,70,50,56,48,34,62,32,60,120,109,112,77,77,58,68,101,114,105,118,101,100,70,114,111,109,32,115,116,82,101,102,58,105,110,115,116,97,110,99,101,73,68,61,34,120,109,112,46,105,105,100,58,53,52,53,66,70,48,69,68,55,66,48,54,49,49,69, +53,66,51,49,53,69,69,54,51,67,65,56,68,70,50,56,48,34,32,115,116,82,101,102,58,100,111,99,117,109,101,110,116,73,68,61,34,120,109,112,46,100,105,100,58,53,52,53,66,70,48,69,69,55,66,48,54,49,49,69,53,66,51,49,53,69,69,54,51,67,65,56,68,70,50,56,48,34, +47,62,32,60,47,114,100,102,58,68,101,115,99,114,105,112,116,105,111,110,62,32,60,47,114,100,102,58,82,68,70,62,32,60,47,120,58,120,109,112,109,101,116,97,62,32,60,63,120,112,97,99,107,101,116,32,101,110,100,61,34,114,34,63,62,115,115,54,90,0,0,175,140, +73,68,65,84,120,218,236,157,7,128,92,117,181,255,207,45,211,251,236,204,246,94,179,61,189,247,144,70,11,45,244,14,74,81,154,20,17,241,1,239,161,40,54,44,207,191,138,138,62,124,2,250,176,32,85,233,32,37,72,9,9,73,72,239,61,219,119,218,109,255,223,239, +55,155,80,4,201,220,123,103,167,157,79,24,118,179,73,238,220,185,237,124,207,249,157,194,105,154,6,8,130,32,8,130,20,22,60,30,2,4,65,16,4,65,1,128,32,8,130,32,8,10,0,4,65,16,4,65,80,0,32,8,130,32,8,130,2,0,65,16,4,65,16,20,0,8,130,32,8,130,160,0,64,16, +4,65,16,4,5,0,130,32,8,130,32,40,0,16,4,65,16,4,65,1,128,32,8,130,32,8,10,0,4,65,16,4,65,80,0,32,8,130,32,8,130,2,0,65,16,4,65,16,20,0,8,130,32,8,130,160,0,64,16,4,65,16,4,5,0,130,32,8,130,32,40,0,16,4,65,16,4,65,1,128,32,8,130,32,40,0,16,4,65,16,4,65, +1,128,32,8,130,32,8,10,0,4,65,16,4,65,80,0,32,8,130,32,8,130,2,0,65,16,4,65,16,20,0,8,130,32,8,130,160,0,64,16,4,65,16,4,5,0,130,32,8,130,32,40,0,16,4,65,16,4,65,1,128,32,8,130,32,8,10,0,4,65,16,4,65,204,70,204,228,155,39,18,9,60,3,8,242,41,104,154,70, +254,207,129,166,210,175,26,249,10,160,42,90,242,207,200,207,52,250,61,151,252,187,28,207,125,228,223,90,28,2,136,86,129,254,171,195,63,226,224,200,223,102,247,61,247,9,111,41,147,151,58,242,103,106,242,31,113,228,61,85,136,15,201,255,186,111,201,221, +98,239,205,9,220,200,126,16,175,66,224,217,31,28,222,39,186,141,79,124,55,4,65,64,20,69,224,249,204,248,226,25,19,0,146,36,193,130,5,11,96,231,206,157,120,5,32,5,13,51,234,228,63,85,86,129,218,85,250,123,142,163,134,52,105,53,109,30,11,8,22,94,180,186, +69,167,59,108,247,17,227,239,119,23,59,124,158,18,71,144,124,31,176,216,5,127,184,217,235,35,127,213,71,254,185,151,124,245,120,74,236,14,103,192,102,39,127,238,36,191,23,200,203,245,33,163,79,191,255,164,39,78,100,68,4,208,191,23,165,223,115,28,23,149, +98,74,172,103,219,16,253,253,16,121,13,240,60,55,208,187,125,184,47,210,19,31,32,6,191,55,62,40,31,234,217,58,216,79,12,126,127,124,64,234,27,58,24,31,34,251,31,143,13,74,160,74,42,168,106,82,188,80,113,64,182,199,62,23,21,12,60,143,194,0,65,238,186, +235,46,56,243,204,51,11,75,0,80,15,98,243,230,205,176,123,247,110,188,2,144,2,119,1,136,53,182,130,215,95,233,12,19,207,189,44,212,228,173,180,58,197,202,80,163,183,130,220,41,85,254,74,23,253,121,88,180,11,1,135,207,234,34,247,142,155,23,121,142,136, +2,96,138,129,69,4,134,142,184,249,148,65,101,16,6,134,52,115,246,143,108,84,168,251,168,94,8,212,2,4,57,203,72,132,194,2,85,9,43,48,177,16,149,135,163,253,210,0,177,243,251,251,119,69,14,202,49,101,119,223,206,200,174,72,111,124,199,240,193,248,142,129, +61,145,61,145,158,196,190,200,65,169,15,18,32,227,201,71,10,157,190,190,190,76,62,122,50,135,213,106,197,179,143,20,4,212,163,119,4,108,78,95,133,179,212,225,183,214,16,35,223,20,168,118,53,187,66,182,6,242,179,42,209,42,148,147,159,7,136,23,109,103, +134,29,52,226,57,143,68,8,104,100,64,101,170,153,121,211,28,36,163,239,144,248,136,141,254,8,212,229,55,53,195,71,249,183,250,0,172,34,93,110,0,135,197,99,117,184,253,92,136,236,106,125,113,93,128,236,3,199,62,59,93,14,160,75,22,170,162,41,137,136,220, +79,94,123,7,118,69,118,70,251,19,27,15,109,26,220,60,180,63,182,190,111,199,240,150,222,29,195,187,162,125,137,94,37,161,226,69,131,20,4,130,32,20,166,0,64,144,124,196,234,18,121,111,153,163,140,24,246,70,226,197,183,133,155,188,157,158,18,71,139,167, +212,81,103,243,136,101,196,192,219,233,58,57,91,199,39,47,69,214,152,113,87,228,164,209,147,227,202,191,221,190,150,133,159,121,36,16,193,34,123,138,170,141,8,151,79,121,222,89,248,160,51,96,13,186,195,246,54,142,227,22,53,31,83,206,142,131,42,107,74, +108,80,58,56,124,48,182,131,8,130,181,68,24,172,233,221,54,188,234,224,166,129,13,228,247,59,134,14,196,162,120,117,33,8,10,0,4,201,10,44,78,17,136,177,175,40,170,115,183,21,143,241,141,35,6,127,188,191,202,213,78,60,251,26,171,67,244,208,117,111,234, +201,51,239,151,122,242,228,171,36,43,255,222,165,206,115,180,145,156,0,85,86,62,30,74,16,44,14,161,36,88,235,46,9,53,120,38,214,207,44,97,130,66,142,41,82,124,88,222,49,176,59,178,238,208,150,161,119,14,174,31,120,107,207,234,222,213,253,187,34,91,163, +125,137,56,94,133,8,130,2,0,65,210,14,241,226,93,129,42,87,115,89,87,96,2,49,246,83,194,77,158,241,174,176,189,145,24,123,47,13,185,39,13,125,242,149,136,224,18,119,106,202,32,121,252,20,250,98,63,72,254,159,227,192,98,115,137,245,37,173,254,250,178, +206,192,177,116,73,65,138,169,82,164,55,190,109,96,119,116,21,17,3,43,14,172,31,120,125,255,218,190,247,250,118,70,246,107,170,134,199,18,65,80,0,32,136,97,131,239,41,110,241,117,86,116,7,166,149,118,4,102,4,106,220,227,236,94,177,150,174,211,83,207, +158,101,185,163,177,79,175,46,24,17,6,170,66,4,193,136,191,79,69,129,51,96,109,116,19,241,85,57,33,120,50,21,15,241,65,233,16,17,0,171,247,173,233,123,109,247,202,158,151,247,174,233,127,171,127,231,240,238,195,165,147,8,130,160,0,64,144,79,197,225,179, +90,66,77,158,182,154,41,225,217,229,221,193,185,129,26,215,68,135,223,86,205,11,192,214,234,21,98,240,229,4,121,197,49,73,45,227,162,128,69,90,62,88,70,224,69,190,40,220,232,153,83,210,234,155,211,117,106,205,151,227,67,82,127,255,142,200,187,251,214, +246,189,176,107,101,239,243,68,24,188,213,179,117,168,23,143,30,130,160,0,64,16,98,52,56,8,84,187,43,171,38,21,205,168,28,87,180,176,180,195,63,195,85,100,107,33,30,62,71,13,62,245,240,165,40,122,247,57,33,10,84,141,136,51,162,12,70,42,8,120,129,247, +133,26,61,179,138,91,125,179,58,79,169,185,53,62,40,237,57,184,113,240,181,157,111,31,122,122,199,138,131,47,238,93,219,191,70,138,200,168,228,16,20,0,8,82,40,208,44,125,226,221,119,86,79,14,45,168,28,31,92,66,4,192,100,155,91,244,209,144,190,146,80, +208,195,207,87,65,32,242,101,101,93,129,147,43,198,7,79,158,116,126,163,210,191,43,178,234,192,250,254,167,55,191,180,239,137,237,111,28,92,49,124,48,62,132,71,13,65,1,128,32,121,6,241,234,173,229,93,129,201,213,147,195,75,171,38,135,150,248,43,156,99, +137,65,224,169,193,167,158,254,199,91,221,34,121,42,8,98,35,75,6,28,8,222,50,199,216,64,181,107,108,243,194,242,27,134,246,199,182,31,218,52,248,236,150,87,246,63,178,245,213,3,47,244,110,27,234,193,35,134,160,0,64,144,92,53,250,33,155,181,106,98,104, +74,195,156,210,19,43,186,3,199,186,66,246,54,218,181,134,54,153,145,98,133,93,138,135,106,0,88,62,7,125,81,236,94,75,117,245,148,208,133,181,211,139,47,140,13,36,246,237,93,211,247,252,150,151,247,255,105,235,43,251,159,233,221,62,124,16,15,24,130,2, +0,65,178,28,171,75,132,138,238,224,148,230,99,202,78,174,153,86,124,2,17,1,109,244,97,79,155,235,96,166,62,242,105,208,74,1,53,154,20,133,188,200,151,84,79,10,157,81,59,181,248,140,88,63,17,3,107,251,254,78,196,192,31,54,60,179,231,133,161,3,177,126, +60,90,8,10,0,4,201,18,232,112,153,146,86,127,203,152,37,21,167,212,78,15,159,234,43,119,78,160,195,102,104,184,55,49,92,200,70,95,251,88,215,192,145,185,1,159,82,21,199,29,233,39,252,65,99,97,238,99,191,47,136,163,166,106,32,29,22,3,22,34,6,38,134,206, +37,98,224,220,73,231,55,108,223,181,178,247,209,13,207,238,249,253,214,127,236,127,41,129,9,132,8,10,0,4,201,12,129,106,87,81,211,130,178,165,228,117,78,176,214,51,87,180,243,118,37,126,56,188,159,127,166,156,118,197,35,126,234,145,175,234,200,215,164, +81,255,192,170,243,28,207,70,240,114,35,95,217,48,31,78,36,63,23,152,6,160,163,71,121,78,132,15,154,10,115,108,59,10,237,221,203,141,180,243,213,228,15,189,39,253,170,30,249,154,28,240,155,220,238,225,247,161,191,232,164,63,238,200,215,252,16,14,76,12, +140,44,23,217,60,150,234,230,5,101,87,146,235,237,202,254,157,195,43,183,188,178,255,247,239,63,185,235,255,246,174,233,95,143,205,135,16,20,0,8,146,102,104,136,191,114,124,209,180,214,165,21,231,84,79,14,159,236,240,91,203,21,73,97,235,250,137,161,220, +117,200,14,27,87,149,189,20,106,222,143,24,117,129,23,153,1,183,10,54,176,11,14,242,114,130,83,116,147,151,7,156,150,145,175,228,247,118,209,69,94,78,246,231,54,242,119,173,188,29,44,188,13,68,242,239,69,222,194,182,65,223,135,126,165,191,255,240,84, +1,250,94,146,26,63,34,6,36,37,193,246,35,174,198,200,207,19,144,80,98,16,147,163,16,87,34,16,37,175,136,60,4,195,210,0,68,229,225,35,223,199,200,207,227,74,148,189,36,34,38,152,136,208,180,35,194,128,10,147,195,47,14,248,156,59,71,116,153,224,240,50, +146,167,196,209,61,238,140,186,238,174,147,107,110,221,255,126,255,51,235,158,220,245,155,141,207,237,125,98,232,64,108,24,239,82,4,5,0,130,152,136,159,120,251,205,243,203,78,110,59,190,234,34,127,149,115,58,53,42,82,156,24,168,33,41,183,12,61,53,240, +212,219,166,70,158,188,168,129,164,6,145,26,106,106,196,221,86,31,248,172,69,16,176,133,193,79,94,65,242,242,218,130,228,103,65,112,89,188,224,32,70,222,33,184,70,12,120,246,64,141,125,156,136,132,40,17,3,84,16,12,36,122,161,63,209,3,125,241,131,208, +27,219,15,189,228,43,253,126,80,234,35,127,62,200,4,133,60,50,45,136,70,38,4,242,226,217,139,203,137,200,193,225,4,66,178,187,142,146,86,255,241,229,93,129,227,39,95,212,180,113,203,203,251,126,191,246,137,93,191,221,245,78,207,90,140,10,32,40,0,16,68, +39,116,132,108,221,244,240,216,214,99,43,47,172,158,28,90,238,8,216,202,233,186,126,114,125,54,55,60,122,106,232,15,123,194,2,47,48,239,220,111,13,16,195,94,12,197,142,10,40,118,86,64,152,124,45,178,151,48,35,239,182,248,178,206,184,31,13,52,170,144, +140,74,184,161,232,83,143,137,10,195,210,32,19,1,135,162,251,224,96,108,15,236,143,238,130,253,145,157,228,251,189,76,48,68,165,33,34,12,164,145,72,133,192,162,31,84,24,112,89,42,10,180,145,4,83,57,14,96,115,139,141,29,39,85,223,66,68,234,151,246,172, +234,125,226,189,191,238,248,229,166,23,246,254,45,54,32,73,120,55,35,40,0,16,228,40,176,185,45,98,219,241,149,75,90,22,149,127,190,180,221,191,132,120,251,22,230,237,15,102,239,115,84,101,198,254,131,176,183,133,183,18,99,238,133,32,49,236,165,206,106, +40,119,213,66,133,187,142,25,123,191,173,136,9,129,130,19,116,192,51,129,67,95,101,206,154,143,252,25,53,250,3,82,47,28,136,238,134,189,195,219,97,247,240,86,216,51,188,13,14,196,118,195,64,188,7,98,106,116,68,68,37,151,67,4,58,102,49,203,68,1,91,34, +24,102,121,20,118,218,112,168,114,124,240,228,254,221,205,239,110,120,102,207,47,222,125,120,219,3,125,59,177,156,16,65,1,128,32,159,136,183,220,233,239,62,181,230,204,134,185,165,159,11,214,184,199,43,172,13,111,118,122,251,204,179,39,70,139,126,165, +30,170,203,226,33,94,124,13,51,242,53,238,102,168,242,52,66,137,163,146,133,239,185,2,203,162,215,245,32,226,45,44,42,66,95,45,254,177,71,126,78,151,19,168,40,216,53,180,25,182,15,109,128,29,67,155,96,127,100,23,12,38,122,89,110,2,93,62,17,88,126,67, +22,69,9,104,84,32,166,0,93,224,112,6,109,93,19,207,171,255,97,251,9,85,55,111,123,253,192,253,111,63,184,229,87,123,86,245,174,199,51,142,160,0,64,16,66,105,135,191,178,109,105,229,197,77,11,202,46,118,133,237,53,244,225,153,109,107,251,116,189,94,30, +49,248,52,169,206,107,13,66,153,171,6,106,61,45,80,231,109,133,74,119,3,11,227,179,76,123,196,52,232,146,66,141,167,153,189,166,195,18,246,51,154,95,176,39,178,13,182,13,188,15,91,6,214,18,81,176,17,122,98,7,88,18,98,182,9,2,85,86,201,181,172,130,96, +227,203,91,22,149,127,185,97,78,201,23,247,174,238,123,248,173,7,54,255,100,211,11,251,94,199,51,140,160,0,64,10,211,240,183,251,155,198,159,93,127,69,195,236,146,243,45,78,177,72,138,200,89,19,230,167,235,213,52,73,141,26,125,106,76,168,193,167,222, +125,189,183,13,26,253,29,196,224,55,178,53,123,100,244,241,90,3,236,117,56,82,64,171,14,246,68,182,195,150,254,181,176,190,111,37,108,31,92,15,61,241,253,144,80,226,236,220,209,232,66,166,133,153,54,178,60,192,113,224,170,24,23,60,159,188,206,221,249, +86,207,99,171,255,188,253,135,155,95,218,247,52,54,169,66,80,0,32,5,65,205,212,112,71,251,241,85,95,32,222,208,121,162,93,112,209,48,127,54,24,126,133,121,249,9,182,158,79,203,235,106,60,245,196,216,119,194,24,255,56,168,246,52,129,223,22,194,147,151, +133,216,4,7,139,196,208,215,188,202,147,32,38,71,96,231,240,38,34,6,222,133,245,189,239,176,101,131,129,68,15,75,44,20,57,11,203,35,200,84,116,128,38,13,178,101,45,14,120,34,2,78,168,158,20,58,225,208,230,193,103,222,249,195,214,123,214,60,182,243,81, +9,133,0,50,138,112,154,150,153,82,149,68,34,1,45,45,45,176,117,235,86,60,11,5,66,195,220,210,174,241,103,213,93,91,49,54,120,54,199,113,54,250,32,204,212,245,119,24,234,225,203,154,196,18,212,168,129,175,243,142,129,214,224,4,104,246,119,67,185,179,134, +53,185,65,114,27,90,126,184,169,255,61,88,211,243,79,216,208,255,46,171,60,160,125,14,104,100,128,190,50,189,84,32,88,121,16,201,235,208,166,161,23,222,249,195,150,239,172,121,124,23,10,129,2,226,231,63,255,57,124,238,115,159,195,8,0,146,159,148,119, +7,219,102,92,209,114,35,241,120,206,38,191,181,102,58,177,143,26,125,154,64,70,215,242,195,142,114,102,236,59,138,166,64,163,175,147,133,150,145,252,130,10,187,9,197,115,216,139,246,31,216,54,180,1,222,59,180,130,9,130,93,195,91,88,51,35,26,21,160,149, +27,153,16,3,180,137,21,125,249,170,156,115,22,220,220,57,167,251,244,186,231,87,254,97,235,119,215,62,182,243,81,92,26,64,48,2,128,228,36,165,29,254,134,241,103,213,95,223,48,187,228,2,226,229,56,89,75,213,12,57,252,180,60,143,173,9,147,7,61,205,206, +111,13,142,135,238,208,116,104,240,117,20,100,73,30,146,204,243,216,49,184,9,222,235,89,1,239,30,122,141,124,191,145,137,129,100,231,68,107,198,34,3,201,136,128,0,135,182,12,254,253,173,223,109,254,214,170,63,109,127,6,207,22,70,0,48,2,128,228,4,197, +99,124,165,147,206,111,184,174,126,86,201,101,162,93,240,81,143,63,19,94,63,205,220,79,168,113,22,222,15,59,202,160,189,104,50,51,250,77,196,211,167,235,198,72,129,123,63,228,186,160,185,29,244,181,180,230,28,216,57,180,9,222,57,248,50,188,123,240,53, +246,125,76,137,177,168,192,104,55,102,58,28,17,240,87,56,23,30,243,149,174,133,99,22,87,252,133,8,129,187,54,189,136,85,3,8,10,0,36,75,241,150,59,61,99,151,215,94,209,177,172,234,58,187,215,82,154,136,140,254,52,62,154,232,37,17,79,159,38,244,209,208, +239,184,192,108,152,88,60,7,90,2,227,88,73,25,130,124,26,180,148,147,190,142,171,61,15,54,247,175,133,183,15,190,68,196,192,171,176,55,178,157,37,134,90,121,219,168,86,19,200,68,4,16,5,11,21,227,130,203,42,199,23,29,183,253,141,131,247,255,227,255,173, +251,230,222,213,125,216,71,0,49,71,4,227,18,0,98,20,155,91,228,186,79,171,61,103,252,57,245,95,117,6,108,99,18,81,153,149,61,141,38,178,38,51,195,111,23,29,172,84,111,66,241,92,230,237,211,158,250,8,162,23,90,98,248,126,239,219,176,98,255,179,176,166, +231,77,232,143,31,202,204,18,1,121,43,139,93,160,145,129,193,141,47,236,253,241,171,63,93,255,253,190,157,195,7,240,12,229,62,184,4,128,228,166,122,228,57,104,154,95,58,119,218,101,45,183,23,213,185,231,176,114,190,81,108,224,115,216,219,167,195,117, +104,95,253,113,225,153,48,169,100,1,43,7,67,16,83,196,173,224,128,46,34,36,233,235,80,108,31,91,34,88,177,239,89,216,54,248,62,200,138,196,38,52,142,74,84,96,164,124,144,220,115,158,49,139,43,190,82,51,37,124,206,170,63,109,187,235,141,223,108,250,69, +98,88,198,76,65,4,35,0,200,232,81,214,17,168,159,126,69,203,127,84,79,14,93,192,38,163,37,70,111,20,47,13,239,211,108,110,155,96,103,117,250,211,75,23,179,7,52,134,248,145,209,17,158,42,235,49,240,234,158,167,88,242,96,50,42,96,97,249,2,163,5,47,112, +32,58,4,232,219,54,252,218,235,247,109,188,109,237,99,59,254,166,225,240,65,140,0,96,4,0,73,39,142,128,213,49,229,162,166,171,59,78,170,190,73,180,241,193,209,92,227,167,165,123,180,132,143,134,245,103,150,45,133,105,101,139,89,184,31,65,70,213,107,2, +158,117,33,164,47,26,21,120,99,223,179,240,218,190,191,179,121,5,244,79,105,84,32,221,203,3,108,240,208,144,12,158,50,199,212,197,183,117,63,53,102,113,249,111,95,253,217,250,219,247,172,238,221,132,103,8,65,1,128,152,251,208,35,207,179,182,227,171,142, +157,114,73,211,157,254,42,215,56,106,248,71,35,179,255,112,152,159,122,93,229,174,122,152,78,140,254,228,146,5,184,182,143,100,5,116,254,195,146,154,179,96,126,213,41,176,234,224,171,240,210,158,199,224,253,222,149,68,172,198,193,202,219,217,108,130, +116,114,184,98,160,102,74,248,220,242,238,224,177,171,254,180,237,155,43,126,181,241,135,209,254,68,28,207,14,130,2,0,49,76,121,87,160,102,234,231,155,255,139,60,100,206,163,15,155,209,104,219,75,13,63,13,243,211,245,213,38,127,23,204,174,56,1,198,133, +102,18,239,202,158,215,199,90,147,162,160,197,7,65,27,62,8,234,240,33,80,135,246,147,239,15,145,159,13,177,68,48,206,230,1,222,83,10,66,184,9,132,162,6,0,193,146,241,125,86,135,183,129,58,176,46,249,53,222,75,63,4,112,130,131,236,107,17,112,116,64,146, +189,152,124,31,6,206,234,7,206,226,205,203,243,70,43,4,104,226,41,125,109,236,95,5,47,238,250,43,188,115,240,21,24,150,6,216,53,43,164,57,79,128,54,12,226,120,46,56,225,156,134,187,27,102,151,158,241,218,47,215,223,180,230,177,157,207,2,46,11,32,40,0, +16,61,216,189,22,24,127,78,253,149,19,206,174,191,77,176,9,197,163,17,238,215,52,34,48,212,24,123,160,142,13,207,132,121,21,203,160,45,56,41,255,12,61,49,242,42,49,242,218,192,94,80,250,119,18,3,186,135,188,246,130,22,33,198,62,54,64,108,104,12,52,37, +145,108,30,127,56,4,147,60,64,201,223,138,86,224,125,149,96,169,39,162,168,101,49,112,206,81,238,96,72,206,147,188,239,89,144,118,61,6,10,49,254,154,52,4,201,46,79,28,251,239,200,126,211,96,56,79,30,51,196,8,82,227,207,89,131,192,59,136,40,112,84,0,231, +170,6,222,89,65,4,66,25,17,8,116,255,243,163,237,50,237,40,73,95,123,134,183,194,139,187,31,101,73,131,180,29,49,93,26,16,56,49,141,167,68,99,73,184,238,98,251,132,37,183,143,125,166,101,81,197,207,94,188,103,205,109,135,54,15,238,195,167,25,242,73,96, +18,32,242,137,212,207,44,233,158,117,117,235,119,138,26,60,199,80,195,79,31,46,105,245,34,137,65,97,137,125,162,131,101,243,207,175,56,25,234,125,237,249,97,236,35,61,160,246,239,2,165,119,27,40,61,196,75,238,219,65,60,251,3,196,208,247,3,80,67,79,62, +59,179,155,212,75,228,5,90,94,49,98,240,185,127,27,35,1,69,102,34,129,247,148,128,109,220,153,96,29,179,100,84,62,143,210,255,30,36,214,255,63,80,250,86,38,141,54,77,126,251,183,161,110,109,68,16,168,116,44,30,19,15,236,51,83,113,32,88,147,194,192,22, +38,98,160,18,120,119,29,8,238,6,224,220,181,192,211,101,30,222,146,243,231,159,230,9,188,188,231,49,120,101,207,147,112,48,186,55,237,66,224,72,84,194,41,66,180,47,177,253,205,255,221,124,243,91,15,108,126,96,52,19,117,145,163,39,147,73,128,40,0,144, +143,123,253,214,233,151,183,220,216,121,114,205,45,228,183,78,57,158,222,117,126,106,8,98,74,148,77,223,155,24,158,11,243,42,79,102,157,217,114,214,216,75,81,98,236,119,131,122,104,19,40,7,55,18,131,191,37,233,217,83,175,94,145,62,102,232,133,15,60,123, +67,22,89,34,54,85,2,107,203,66,112,76,191,18,64,180,165,237,243,73,59,31,129,248,250,255,38,239,25,37,94,189,25,221,20,53,38,8,168,48,208,52,153,9,5,118,124,200,245,192,219,138,153,32,224,189,77,32,120,90,200,247,181,44,130,144,171,208,137,132,47,239, +126,156,69,5,14,68,119,131,133,8,1,49,205,66,128,86,11,88,93,34,236,124,187,231,15,47,222,179,230,166,61,171,122,241,129,139,2,0,5,0,242,137,94,255,100,226,245,255,128,120,253,83,105,134,113,58,175,13,186,198,31,87,34,96,23,92,48,169,120,30,44,168,58, +149,117,97,203,57,131,31,31,2,149,122,246,251,215,129,188,255,125,80,123,182,38,67,251,114,44,121,131,209,7,188,48,226,213,167,53,51,92,99,251,98,169,159,5,206,121,55,166,69,4,72,219,30,76,26,127,230,241,167,217,131,61,34,10,164,164,40,160,83,251,172, +1,224,93,213,32,120,199,0,239,239,32,162,160,25,56,123,113,206,93,51,131,137,62,120,137,136,128,164,16,216,53,146,35,144,222,227,105,113,8,32,199,213,253,111,254,118,211,87,87,220,183,241,23,180,116,23,65,1,128,2,0,1,187,207,98,153,126,89,203,87,70,188, +126,91,58,189,254,164,225,143,178,53,254,241,197,179,97,97,213,114,168,201,165,198,61,74,130,133,241,149,189,239,129,188,119,53,40,135,182,36,215,237,229,4,51,242,156,32,154,231,217,235,20,36,214,214,165,224,152,125,141,169,219,149,247,62,3,177,85,119, +16,227,111,251,140,112,127,250,174,28,38,10,84,137,232,1,133,69,9,104,82,33,239,170,1,193,215,14,66,112,44,240,222,22,224,44,254,220,17,2,82,31,60,191,243,47,68,8,60,2,61,177,253,172,233,80,58,155,10,113,52,26,224,20,97,247,59,61,15,191,112,207,154,27, +48,26,128,2,0,5,64,129,83,55,163,120,236,236,107,218,126,72,188,254,89,233,246,250,233,26,63,71,140,71,87,104,42,44,169,57,27,26,188,185,177,198,175,13,29,0,121,223,26,144,119,175,4,101,223,58,80,7,247,178,36,189,35,6,159,134,243,51,60,83,254,35,18,43, +17,1,231,220,47,129,165,121,161,41,91,84,163,187,33,186,226,242,100,162,95,54,173,201,211,124,2,85,102,75,7,52,209,144,179,133,88,84,64,8,78,0,33,48,150,45,25,192,40,246,238,215,75,111,252,0,60,179,227,97,120,121,207,227,44,58,64,219,89,115,105,76,136, +28,137,6,236,253,231,253,155,110,124,237,222,245,191,197,167,96,225,10,0,172,2,40,80,68,27,15,51,174,28,115,245,184,51,234,190,78,108,190,59,157,165,125,180,129,15,29,199,75,27,167,44,37,134,191,163,104,74,182,155,124,22,202,151,119,173,36,175,183,217, +90,190,26,237,99,63,167,161,104,160,198,198,154,173,35,132,147,137,117,177,55,127,7,98,245,100,224,236,62,227,194,109,211,175,64,139,31,34,23,77,150,117,90,164,198,93,16,200,39,78,46,119,104,137,94,144,15,188,12,210,254,23,129,19,93,44,58,32,6,199,129, +16,154,2,130,183,213,164,156,5,243,161,61,45,78,107,188,28,102,149,31,7,79,110,127,16,86,236,125,26,98,106,20,236,172,228,213,124,97,73,251,119,240,2,87,58,253,242,150,251,203,58,252,139,94,184,103,205,245,61,91,134,112,174,64,33,218,1,60,4,133,71,73, +171,175,122,254,151,59,127,76,110,254,19,232,196,190,116,101,248,83,163,159,80,226,80,233,174,103,134,127,74,233,49,105,245,108,140,217,124,149,24,250,13,32,239,124,27,228,29,255,4,133,8,0,234,73,3,207,143,100,170,231,208,248,96,193,194,202,10,19,239, +255,13,108,221,203,141,121,255,131,27,65,38,6,21,68,103,246,127,110,150,111,33,142,152,76,34,226,6,55,64,188,127,13,112,219,126,207,202,13,133,192,56,16,195,211,129,247,119,146,191,154,125,109,163,75,156,85,112,193,152,27,153,16,120,108,235,253,176,234, +224,107,108,41,137,46,151,153,13,237,36,72,69,127,237,180,226,243,74,59,2,211,94,250,193,154,47,174,126,100,199,83,248,116,68,1,128,228,49,227,207,170,63,101,202,165,77,63,178,185,197,242,248,80,122,234,250,233,58,127,76,142,128,223,86,4,39,212,93,0, +243,43,79,33,222,76,118,26,16,229,208,38,144,183,173,32,70,255,13,150,177,79,67,251,28,109,174,195,146,206,156,57,123,158,105,159,0,105,211,11,96,235,56,201,80,179,32,105,207,83,160,201,195,89,105,48,63,43,18,66,147,21,57,214,159,159,136,129,200,110, +80,134,182,178,42,6,206,81,14,98,209,4,16,139,103,131,64,196,64,182,69,6,104,123,235,171,186,238,130,183,15,188,4,143,18,33,176,117,96,93,218,74,7,105,3,33,209,198,55,46,188,181,235,137,170,201,161,187,158,251,246,123,183,199,250,19,18,32,40,0,144,252, +193,225,183,218,231,223,216,241,141,150,197,21,215,73,177,244,181,241,165,235,252,2,47,194,236,242,227,225,184,186,243,32,100,47,203,186,99,65,203,242,228,109,175,129,180,237,85,22,222,167,158,254,7,70,223,149,31,39,156,70,1,250,118,50,81,35,132,155, +117,30,40,137,252,251,55,71,140,104,46,195,37,207,237,72,254,130,22,223,15,137,29,127,6,105,215,163,192,19,175,91,12,77,5,161,120,14,17,3,237,144,61,185,28,0,227,194,179,160,189,104,50,188,176,235,47,240,212,246,135,160,55,118,0,236,162,211,244,57,3, +170,76,187,110,42,92,235,146,202,91,194,77,222,25,79,127,227,221,203,118,175,236,125,31,159,154,40,0,144,60,160,118,122,113,251,220,47,181,221,27,172,245,76,75,215,184,222,195,225,254,102,127,55,156,84,127,49,180,4,198,101,213,49,208,18,195,32,239,124, +139,121,197,52,131,95,141,246,19,131,64,215,144,173,249,99,244,63,102,244,104,101,130,114,96,131,110,1,160,198,246,146,227,180,55,253,37,127,163,31,30,33,255,137,35,145,129,93,16,223,250,0,112,59,254,200,18,8,197,146,57,44,50,64,163,4,217,0,13,255,47, +172,58,29,198,135,231,192,163,91,255,7,94,221,251,20,168,170,98,126,75,108,13,88,23,193,64,181,123,206,169,255,61,245,229,21,247,109,188,122,197,125,27,30,208,176,90,16,5,0,146,187,76,185,164,233,28,242,250,33,199,113,193,116,24,255,195,225,254,160,189, +24,150,54,158,13,115,42,78,28,149,46,103,71,45,76,136,135,79,141,190,188,245,53,80,6,118,143,60,255,109,57,29,222,79,197,241,165,29,8,117,159,219,216,62,114,0,35,201,210,191,124,61,64,71,34,3,26,185,62,214,130,220,183,10,248,45,191,101,149,4,98,217,98, +16,139,38,101,69,229,3,29,58,68,243,3,166,148,44,128,63,111,254,37,108,32,251,153,142,101,1,90,2,204,9,92,104,198,149,99,126,87,60,198,55,245,239,119,190,123,83,12,7,11,161,0,64,114,11,135,223,106,157,119,99,199,183,90,22,149,95,43,199,20,80,20,243,165, +60,157,120,70,153,89,126,44,156,88,119,17,123,72,101,133,183,47,69,147,33,254,13,207,129,76,188,125,250,123,186,38,158,83,137,124,102,69,1,232,16,33,221,81,147,129,100,169,93,129,28,43,42,116,56,242,210,148,56,155,115,32,239,123,30,120,119,61,136,165, +11,192,82,58,63,43,162,2,99,2,227,225,134,241,157,240,236,142,63,194,147,219,126,7,3,82,31,216,89,14,131,121,203,2,218,72,130,96,227,220,210,171,3,213,174,113,79,127,99,213,37,187,87,246,108,192,167,42,10,0,36,7,168,24,27,172,59,230,150,174,95,21,213, +187,231,198,233,0,31,147,147,252,105,223,126,218,197,175,202,211,4,167,212,127,14,186,66,211,178,226,115,171,196,195,151,54,60,11,210,230,151,64,233,219,201,50,168,57,161,64,188,253,127,19,163,49,160,164,14,143,247,41,48,221,196,3,140,36,173,170,195, +91,33,190,225,167,32,109,123,8,132,240,116,176,16,177,43,4,186,51,251,208,230,44,176,168,250,12,232,14,205,128,63,110,190,23,222,218,255,2,139,4,136,38,71,42,232,12,144,64,141,123,214,41,63,156,242,210,63,254,223,186,207,191,253,224,150,71,240,233,138, +2,0,201,98,58,150,85,47,154,115,93,219,175,68,187,80,145,142,44,127,154,228,39,242,86,88,90,123,46,28,87,115,46,56,196,204,175,159,43,251,214,66,98,221,147,32,109,127,29,52,186,182,95,144,222,126,154,188,226,66,103,164,146,64,83,162,32,239,122,28,228, +189,127,7,193,223,5,150,138,227,64,12,207,98,83,14,51,69,137,179,18,174,232,184,3,94,223,251,52,252,105,243,47,216,124,1,179,147,4,105,244,144,23,185,146,185,215,183,255,185,168,222,243,181,231,190,189,250,235,216,70,24,5,0,146,109,207,41,145,135,89, +95,28,115,237,248,115,234,239,150,227,138,133,222,184,230,123,253,81,168,247,181,193,233,141,87,66,19,121,8,102,214,177,85,65,222,190,2,18,107,159,0,121,247,187,44,108,203,137,246,60,77,232,67,50,175,133,132,145,94,8,26,40,61,111,131,220,243,38,155,90, +200,132,64,233,66,214,150,56,83,208,254,26,99,130,227,224,143,155,238,101,73,130,60,249,37,154,88,185,65,171,4,36,69,230,186,78,173,185,51,80,227,234,122,234,246,149,151,13,236,137,244,225,69,129,2,0,201,2,188,101,14,251,130,155,59,127,84,63,171,228, +82,186,118,103,118,55,223,195,94,63,173,233,63,150,120,254,214,76,38,133,201,9,144,182,188,76,12,255,227,108,0,15,11,81,211,48,191,197,137,23,2,50,58,81,17,226,245,83,31,91,29,222,6,241,117,63,128,196,182,63,128,165,124,9,17,3,199,103,108,56,145,207, +90,4,23,181,222,12,93,69,83,225,255,54,253,12,246,71,118,153,26,13,160,207,20,250,108,169,28,95,116,250,242,159,78,107,122,250,27,239,158,187,237,245,3,107,240,122,64,1,128,100,144,146,86,95,213,226,219,198,222,31,106,242,206,137,13,152,155,229,175,129, +10,81,57,2,245,222,86,56,189,233,139,208,156,65,175,159,38,242,73,27,95,32,134,255,49,80,14,109,102,51,5,64,180,99,144,26,201,28,212,203,166,203,3,137,67,16,223,244,75,144,118,253,21,68,226,141,91,171,78,206,88,194,224,132,226,185,208,232,239,132,255, +219,248,51,120,109,239,223,76,207,13,160,121,1,238,98,251,184,19,190,61,241,185,127,252,100,221,69,111,63,184,229,113,188,16,80,0,32,25,128,120,252,83,150,220,49,246,119,86,167,88,111,118,47,127,218,191,159,178,184,250,76,88,86,127,81,230,58,249,73,49, +72,108,120,6,18,107,30,99,237,121,233,240,29,92,223,71,178,43,40,32,178,78,137,154,52,8,137,173,191,3,121,207,83,172,132,48,83,66,128,70,3,46,105,187,5,218,130,19,225,225,77,63,131,190,248,65,83,239,95,90,42,200,139,92,241,156,235,218,30,241,150,57,174, +123,233,135,107,127,68,91,11,35,40,0,144,209,82,250,231,212,47,159,117,85,235,47,21,89,243,72,38,175,247,71,229,97,150,96,116,102,243,85,208,85,148,161,12,127,69,34,30,255,243,16,95,253,103,80,15,109,97,157,237,10,59,155,31,201,126,33,32,36,133,128,28, +25,17,2,79,130,165,108,41,88,170,79,203,200,210,192,180,210,69,208,232,235,128,7,214,255,16,86,30,124,5,108,130,221,180,113,195,52,47,64,83,20,97,210,249,141,63,116,6,109,245,207,222,189,250,122,226,132,96,118,32,10,0,36,189,207,24,14,230,94,215,126, +67,247,242,154,111,43,9,21,204,84,222,138,166,176,218,254,201,37,11,136,241,255,34,243,36,70,29,77,3,105,243,139,16,95,245,39,80,14,172,103,99,94,1,13,63,146,147,66,32,202,132,128,180,247,239,96,169,60,145,188,78,30,245,100,193,176,163,28,174,234,190, +11,158,218,246,32,252,117,235,111,32,65,238,111,179,114,120,104,94,64,180,63,1,173,75,43,175,13,84,187,106,30,185,225,159,23,13,29,136,245,227,5,128,2,0,73,3,118,175,133,159,127,83,231,247,91,143,171,184,58,62,64,231,160,155,103,252,227,74,140,205,33, +95,222,120,57,27,222,147,9,104,171,222,248,59,191,39,158,211,106,182,198,143,137,125,72,174,11,1,16,93,160,73,3,144,216,248,11,144,118,63,9,214,154,211,193,82,126,220,168,150,15,210,68,192,37,53,103,65,131,191,29,254,247,253,123,96,251,224,6,112,178, +242,93,115,50,104,104,135,209,226,86,255,201,167,253,116,90,249,223,239,92,121,250,174,183,123,182,227,201,207,13,120,60,4,185,129,59,108,119,157,242,227,169,15,142,89,90,113,117,172,95,50,209,248,107,16,149,135,160,202,211,0,95,26,251,221,140,24,127, +58,145,47,242,204,93,16,121,234,14,144,247,18,227,111,33,15,71,209,138,39,29,201,19,33,64,252,44,26,17,136,29,128,216,218,239,67,228,141,47,176,78,131,163,77,147,175,11,110,28,119,15,235,220,25,83,34,44,226,103,22,82,68,6,127,165,115,202,9,119,79,124, +174,122,82,104,44,158,116,20,0,136,73,132,155,188,37,203,190,63,249,177,146,86,223,114,51,147,253,84,242,0,136,42,81,242,64,56,14,110,32,15,134,58,111,235,168,126,46,45,210,3,177,87,127,14,195,127,253,50,72,155,95,78,206,114,23,237,120,194,145,60,125, +218,90,200,245,237,2,117,104,19,196,222,189,29,162,111,221,0,74,223,234,81,221,5,151,197,11,23,183,126,5,206,105,254,18,155,218,153,80,205,107,243,79,39,140,210,132,228,147,238,153,252,247,238,229,181,199,224,9,207,126,112,9,32,203,169,28,23,108,56,225, +219,19,255,100,243,88,58,105,9,142,105,55,43,185,241,45,188,141,60,8,174,37,94,255,201,163,251,161,84,5,18,235,158,128,248,202,135,65,29,220,203,178,250,49,179,31,41,28,33,144,92,131,87,14,173,128,104,239,59,96,169,88,10,214,186,243,129,179,133,71,109, +23,230,85,158,4,213,158,70,248,205,186,239,192,174,161,205,166,117,244,164,93,2,121,145,11,205,187,161,227,17,14,224,194,119,254,176,245,247,120,194,49,2,128,232,160,98,92,81,55,49,254,127,183,186,44,157,84,93,155,5,205,242,15,59,42,224,154,238,111,141, +186,241,151,119,175,132,225,71,111,134,232,203,63,1,45,218,155,236,220,199,225,101,136,20,32,35,67,124,18,219,255,4,145,215,47,7,105,251,195,163,58,124,169,193,215,1,55,142,191,7,38,22,207,101,203,128,180,239,135,41,250,94,214,64,73,40,142,57,215,183, +63,48,235,170,214,203,56,108,214,129,17,0,36,53,58,150,85,205,156,117,117,219,195,22,135,80,76,235,110,205,64,99,235,253,195,48,54,60,19,206,111,185,30,252,182,208,168,125,30,109,248,16,196,222,126,0,164,245,79,211,39,4,150,244,33,8,133,38,187,178,68, +193,62,136,173,251,62,155,64,104,109,188,116,212,6,14,121,44,126,184,162,243,14,248,235,150,122,120,116,235,253,192,17,107,77,135,13,25,22,1,10,121,218,104,42,63,229,226,166,159,218,125,22,223,223,191,254,238,221,128,173,2,80,0,32,159,77,247,242,218, +197,243,111,236,120,72,145,84,31,45,245,51,3,154,240,35,171,9,88,90,115,54,156,210,240,121,16,76,170,7,62,26,18,239,255,13,226,111,61,48,18,238,39,134,95,196,203,14,65,62,42,4,104,254,139,8,74,223,187,16,125,235,122,176,84,46,3,107,253,249,228,126,241, +141,198,155,195,9,117,23,66,185,187,22,126,75,68,200,176,52,0,86,19,170,20,52,85,99,101,130,93,167,212,124,139,24,127,239,211,223,120,247,86,13,69,0,10,0,228,223,26,255,147,231,221,208,254,91,41,174,56,53,83,106,252,57,144,212,88,114,189,127,204,141, +44,225,111,180,80,123,183,65,108,197,175,217,148,62,78,176,226,160,30,4,249,44,168,225,213,84,72,108,123,16,148,131,175,129,181,241,115,32,150,204,29,149,183,158,16,158,203,150,6,127,181,230,27,176,99,112,147,105,121,1,180,69,121,215,169,53,95,37,143, +34,247,211,223,88,117,45,21,6,72,118,128,139,175,217,101,252,151,207,163,158,127,66,53,201,248,211,250,254,8,4,108,197,112,117,247,55,71,207,248,107,10,36,86,253,41,153,221,191,125,69,210,235,231,81,107,34,200,209,105,118,158,53,18,82,163,187,33,246, +238,109,16,91,125,39,104,241,3,163,242,214,213,238,38,248,210,216,239,65,119,104,58,68,88,94,128,57,207,161,216,160,68,71,149,95,115,242,15,38,255,212,25,176,98,86,0,10,0,228,99,198,255,2,98,252,31,160,163,124,205,234,238,71,215,251,233,248,222,235,199, +125,15,154,253,163,179,166,72,7,245,12,63,126,43,68,95,189,23,52,57,142,217,253,8,162,251,233,108,5,16,108,172,129,80,100,197,149,32,239,125,122,84,222,214,107,13,192,23,186,238,132,133,85,203,217,8,112,58,10,220,184,83,144,28,36,84,55,189,248,178,19, +191,59,233,94,103,192,134,34,0,5,0,242,33,227,255,43,37,174,8,102,120,254,84,181,83,245,62,177,100,46,92,219,125,55,107,7,58,10,110,63,107,223,27,121,236,43,32,239,94,149,76,242,227,5,60,185,8,98,44,28,144,76,18,140,31,130,216,170,255,76,70,3,18,135, +210,254,174,116,138,224,89,205,87,195,233,141,87,178,126,33,138,102,78,9,50,141,4,148,119,5,47,57,241,187,19,239,117,96,36,0,5,0,26,127,98,252,111,104,167,198,159,55,195,243,167,106,61,70,84,251,162,234,51,224,178,246,219,193,33,186,211,254,25,212,254, +221,16,121,242,118,214,212,71,147,19,201,78,126,8,130,152,248,164,182,176,252,128,100,52,224,11,32,31,120,105,84,222,150,62,71,46,109,191,21,44,188,245,200,132,80,163,208,214,193,101,157,129,75,150,125,119,18,21,1,120,110,81,0,20,184,231,159,80,77,49, +254,84,165,203,154,68,84,251,21,112,102,211,23,129,31,133,250,122,105,195,51,48,252,232,77,32,237,248,103,50,201,15,189,126,4,73,111,52,32,182,15,98,43,191,6,241,247,127,72,110,250,104,218,223,149,246,9,248,98,215,93,224,179,6,217,146,128,25,208,229, +128,178,46,38,2,126,225,12,226,114,0,10,128,194,51,254,203,169,231,47,155,228,249,203,170,68,78,38,15,23,181,222,12,139,171,207,76,251,254,107,241,65,136,190,120,15,68,158,255,30,249,126,8,215,250,17,100,212,158,218,86,246,74,108,123,8,34,255,188,26, +148,129,117,105,127,203,102,127,23,92,59,246,219,80,238,170,101,115,4,76,17,1,67,50,148,19,17,112,252,55,39,220,43,88,208,20,161,0,40,28,227,127,242,188,27,58,126,75,61,127,227,107,254,28,107,235,107,23,157,112,69,231,127,178,25,224,233,70,217,183,134, +117,243,75,172,123,42,25,238,199,12,127,4,201,64,52,192,13,234,192,122,136,190,121,45,72,59,254,152,246,119,164,198,255,186,177,223,129,38,95,39,75,48,54,131,56,17,1,21,227,139,46,153,255,229,142,31,112,216,50,16,5,64,1,24,255,197,243,110,236,248,173, +156,80,172,170,9,198,159,134,228,104,104,142,206,252,238,40,154,146,246,253,79,172,250,51,12,63,241,31,160,246,110,31,169,235,199,155,22,65,50,6,237,27,160,202,16,91,251,61,150,36,168,73,253,105,125,59,218,61,244,170,238,111,30,41,19,52,39,18,32,209, +102,65,87,31,115,75,231,93,40,2,80,0,228,45,237,39,84,205,156,127,83,199,239,21,83,154,252,112,172,198,191,216,81,1,87,119,223,13,13,222,246,180,238,187,22,27,128,232,179,223,134,232,171,63,79,246,43,23,109,120,66,17,36,43,130,1,2,203,13,144,246,60,5, +81,186,36,208,255,94,90,223,206,41,186,225,242,142,59,96,106,233,66,211,68,192,72,179,160,155,137,8,248,42,138,0,20,0,121,71,197,184,96,215,156,107,219,30,86,18,170,215,140,53,255,152,50,12,149,238,6,184,102,236,183,200,215,250,180,238,187,114,96,61, +12,63,118,11,36,54,62,155,44,239,227,48,209,15,65,178,78,7,208,37,129,161,109,172,149,176,180,243,47,105,125,47,171,96,131,75,218,110,129,185,21,39,154,214,48,136,150,8,118,157,82,115,231,130,175,116,94,133,103,19,5,64,62,25,255,134,19,191,61,241,17, +209,33,20,211,113,153,198,141,127,4,234,188,99,88,119,63,26,1,72,39,52,203,63,242,196,215,88,91,95,108,229,139,32,89,14,49,204,160,74,16,95,251,29,136,175,251,46,251,62,109,111,197,137,112,222,152,27,96,81,245,233,16,147,35,198,69,0,249,231,177,33,22, +9,248,225,184,51,235,206,193,147,137,2,32,231,41,170,247,20,19,227,255,103,171,75,172,49,99,176,15,77,190,105,244,117,16,227,255,45,8,164,121,126,120,124,229,31,32,242,194,247,89,71,63,12,249,35,72,206,132,2,216,168,225,196,246,135,33,186,242,86,114, +255,14,167,239,173,200,175,51,155,174,98,149,71,102,137,0,90,34,56,231,186,182,95,117,47,175,93,130,39,19,5,64,206,226,14,219,93,75,254,115,220,255,217,60,150,14,57,110,134,231,63,12,77,254,78,248,66,231,215,217,24,207,116,146,120,239,175,16,123,253, +62,54,196,7,179,252,17,36,231,84,0,209,1,30,144,247,191,4,177,213,95,39,134,85,78,235,187,157,222,116,37,156,88,119,33,139,78,26,21,1,116,88,16,113,150,172,243,110,236,120,176,110,102,241,100,60,151,40,0,114,14,98,244,249,101,223,155,244,235,226,22,239, +44,41,170,24,247,252,21,234,249,19,227,223,69,140,191,53,189,198,95,217,179,138,24,255,95,2,103,177,177,193,36,8,130,228,168,12,176,16,17,176,239,121,72,108,186,47,237,239,181,172,254,98,56,177,246,66,83,34,1,52,79,138,142,67,95,124,219,216,135,43,198, +21,213,227,153,68,1,144,51,208,166,22,243,191,220,241,253,146,54,255,105,52,156,101,134,241,111,58,108,252,211,236,249,131,28,135,232,107,247,210,59,16,147,253,16,36,31,68,128,232,74,142,23,78,115,117,192,17,17,80,119,33,43,79,54,44,2,36,21,236,30,75, +229,177,119,142,251,163,167,196,17,196,51,137,2,32,39,152,117,77,235,245,237,199,85,93,29,31,52,158,128,67,67,106,204,248,119,222,153,126,227,79,72,108,120,22,148,3,27,112,205,31,65,242,70,1,144,199,188,154,128,196,230,251,71,229,237,168,8,88,82,115, +22,203,87,50,42,2,164,152,2,174,144,173,251,196,239,76,124,192,21,182,227,224,0,20,0,217,205,248,179,235,79,27,123,90,237,183,105,93,171,193,187,246,72,182,63,29,205,233,177,6,210,191,243,196,235,151,222,255,27,113,252,45,120,34,17,36,159,16,236,160, +244,188,9,234,224,134,81,121,187,211,26,46,135,37,35,137,129,96,84,4,68,21,40,105,243,47,90,116,107,215,127,243,34,246,8,64,1,144,165,212,205,40,158,52,251,154,214,251,20,73,229,52,205,200,69,159,108,242,83,229,110,128,43,153,231,31,24,149,253,87,122, +54,147,215,86,186,134,129,39,19,65,242,236,81,175,145,103,138,124,224,31,163,246,142,167,55,125,1,230,86,158,4,17,19,170,16,104,52,181,110,102,201,165,243,111,234,188,25,207,37,10,128,172,35,220,226,173,88,250,95,227,126,175,72,154,219,104,163,159,184, +26,133,98,103,37,49,254,255,149,246,82,191,143,8,128,125,235,146,37,127,216,222,23,65,242,14,142,19,65,233,95,51,170,239,121,110,203,117,48,163,108,137,41,29,3,105,203,224,142,147,170,239,162,81,86,60,155,40,0,178,6,79,137,195,190,244,142,113,15,88,157, +98,173,42,27,43,247,163,131,125,252,214,16,92,217,241,95,16,78,115,147,159,127,17,0,125,59,209,246,35,72,222,42,0,1,180,232,94,114,163,199,71,239,45,201,175,11,198,220,4,227,195,179,13,15,16,162,65,85,37,174,192,172,171,90,127,89,59,45,60,14,79,40,10, +128,140,35,218,4,56,230,150,206,31,135,154,188,179,104,194,138,17,232,72,95,135,232,130,43,58,238,128,10,119,221,168,127,22,45,62,128,222,63,130,228,111,8,0,52,37,6,154,26,31,213,183,21,121,11,92,218,254,85,24,19,24,103,120,148,48,141,174,106,170,230, +93,124,251,216,223,251,43,93,97,60,169,40,0,50,202,244,43,90,174,169,159,85,122,137,209,140,127,69,147,65,224,5,184,180,237,107,80,239,107,203,208,167,209,240,132,34,72,94,147,153,123,220,46,56,225,178,142,219,161,202,221,196,74,4,141,56,26,180,157,186, +195,103,109,60,225,238,137,247,219,125,86,172,85,70,1,144,25,218,79,168,58,102,226,185,13,223,137,15,38,140,169,90,77,37,2,64,129,243,90,110,128,142,162,204,53,190,226,44,46,20,1,8,146,207,182,159,120,227,92,134,58,123,122,173,1,184,162,243,14,8,217, +75,33,161,198,12,109,139,70,91,195,45,222,197,243,110,104,255,22,158,88,20,0,163,78,121,87,160,122,238,245,237,247,75,49,89,52,146,240,79,235,100,105,210,223,169,13,159,103,227,53,51,122,49,120,203,146,11,109,8,130,228,33,10,240,182,34,54,39,32,83,208, +225,101,151,117,222,14,78,209,5,178,102,44,106,26,31,146,96,204,146,138,235,39,158,223,112,54,158,91,20,0,163,134,221,103,177,46,188,181,251,126,209,46,148,170,178,49,131,73,19,99,22,85,157,206,134,105,100,26,33,220,8,156,128,125,255,17,36,47,3,0,170, +76,68,126,11,100,58,207,167,214,51,6,46,110,189,133,37,8,170,154,129,188,41,242,232,149,99,10,76,191,172,229,167,181,51,138,187,240,12,163,0,24,21,230,223,212,249,237,162,122,207,108,217,96,210,31,53,254,147,74,230,193,242,198,43,178,226,115,9,225,102, +224,61,165,0,170,140,39,25,65,242,12,142,19,64,44,154,146,21,251,210,21,154,198,166,8,74,106,194,80,183,64,86,114,205,129,103,209,215,186,255,215,87,225,244,226,89,70,1,144,86,38,95,220,116,86,203,162,138,171,227,195,198,194,87,49,37,202,198,250,94,56, +230,203,192,103,73,207,125,206,226,4,75,237,140,145,94,0,8,130,228,13,106,156,120,255,77,32,4,186,179,102,151,230,84,156,8,75,106,206,54,92,30,72,199,172,187,130,182,142,133,183,118,255,183,96,69,147,134,2,32,77,212,76,13,143,153,122,105,211,79,228,152, +108,40,87,142,214,250,135,236,37,240,185,246,91,89,217,95,54,97,105,59,22,120,103,32,57,12,8,65,144,188,64,83,37,176,86,47,39,79,252,236,106,167,127,74,253,165,48,181,228,24,195,34,32,17,145,161,122,74,232,220,105,159,111,190,2,207,54,10,0,211,113,248, +172,246,121,55,118,252,134,227,192,111,164,211,31,45,247,179,240,54,184,164,237,171,16,114,148,103,223,5,225,46,6,91,247,114,208,164,40,158,116,4,201,7,227,47,71,88,232,95,44,61,38,235,246,141,227,120,56,111,204,13,172,244,217,104,121,32,237,20,56,241, +220,134,239,54,206,45,29,143,103,29,5,128,169,204,187,169,227,174,96,141,123,178,28,215,223,233,143,174,117,209,102,63,103,53,95,13,77,254,236,205,89,177,118,156,8,150,186,233,160,37,134,241,196,35,72,46,163,38,88,230,191,173,245,186,172,29,239,77,163, +160,151,182,221,10,126,91,136,60,31,245,47,63,106,228,209,172,170,154,131,58,106,238,176,221,131,39,31,5,128,41,140,61,163,110,217,152,37,21,215,210,178,19,35,208,48,23,205,246,159,81,182,52,187,63,48,121,80,56,102,95,11,98,113,11,70,2,16,36,103,141, +191,196,66,254,246,206,175,2,239,172,202,234,93,45,113,86,194,69,173,95,102,17,1,218,23,69,47,52,31,192,93,108,239,88,112,115,231,247,104,231,67,4,5,128,33,194,77,222,138,105,159,111,254,169,20,53,150,25,79,141,255,216,240,76,56,185,225,115,57,241,185, +57,187,23,28,199,124,21,132,162,122,20,1,8,146,147,198,223,66,140,255,109,32,4,39,229,196,46,183,145,253,60,181,225,50,214,23,197,72,146,85,98,88,134,134,185,165,151,78,190,176,225,12,188,16,80,0,232,134,102,148,30,243,213,174,159,217,220,162,161,122, +255,132,26,135,82,87,53,92,48,230,6,16,184,220,233,92,201,187,195,224,90,244,31,40,2,16,36,23,141,127,215,109,32,134,167,231,212,174,31,83,117,26,204,42,59,206,112,82,160,20,145,105,197,214,143,75,90,125,181,120,65,160,0,208,197,140,43,199,92,85,214, +17,56,78,138,234,207,136,167,45,126,173,188,21,46,106,189,25,124,214,162,156,59,6,28,17,1,206,17,17,0,40,2,16,36,103,60,127,49,52,61,39,63,194,153,205,87,65,189,175,99,36,41,80,231,97,80,52,16,173,124,104,254,151,59,127,110,117,137,184,22,128,2,32,53, +106,166,134,59,198,159,89,127,23,45,47,209,143,198,122,94,159,214,120,5,171,249,207,217,139,100,36,18,192,99,36,0,65,114,195,248,135,167,231,236,199,160,131,131,104,62,128,219,226,3,89,211,255,252,165,142,91,121,87,112,225,244,203,91,174,197,139,3,5, +192,81,99,243,88,196,185,215,183,255,92,211,52,151,166,234,15,253,71,228,97,22,206,154,91,177,44,231,143,9,139,4,44,190,13,151,3,16,4,141,127,218,41,119,213,194,217,205,215,130,162,202,134,58,5,210,65,109,221,167,213,222,89,61,57,212,137,23,9,10,128, +163,130,40,198,175,20,213,123,166,201,113,253,161,127,234,249,215,122,91,224,140,230,47,230,207,197,226,10,97,78,0,130,160,241,31,21,104,155,244,99,170,78,53,148,15,144,156,109,166,57,169,67,103,115,91,44,120,177,124,20,156,252,242,49,106,167,134,39, +116,157,90,115,107,194,64,171,95,58,224,194,198,59,224,130,49,55,130,67,72,83,167,63,162,140,19,187,214,129,180,125,53,200,7,182,129,26,237,103,87,59,103,119,131,24,172,0,75,101,27,88,171,218,129,179,153,251,254,135,115,2,34,127,251,79,80,14,109,6,206, +226,192,139,6,65,242,214,248,107,160,36,54,130,28,95,3,138,180,13,52,181,47,89,112,207,59,129,23,75,65,180,182,128,104,107,3,142,79,79,217,253,41,13,159,135,173,3,239,195,198,254,85,96,211,57,197,144,246,110,9,53,122,167,78,251,124,243,77,207,127,239, +189,175,227,69,131,2,224,19,177,123,45,214,57,95,106,255,41,185,230,173,6,74,81,153,247,127,78,203,151,160,198,211,98,254,237,40,197,32,242,207,191,146,215,95,64,222,183,25,180,196,72,247,44,158,251,64,242,210,151,96,97,66,192,222,49,15,92,83,78,5,129, +124,111,90,36,96,36,39,96,24,69,0,130,100,222,248,119,165,33,225,79,75,64,124,248,41,136,15,61,193,4,128,166,142,68,252,56,254,67,174,181,198,122,134,240,98,9,88,157,51,193,238,57,133,124,95,97,234,110,88,120,43,156,63,230,6,248,214,91,87,177,164,64, +129,211,103,178,168,67,215,189,188,246,107,155,95,222,247,232,246,21,7,87,226,197,51,242,44,199,67,240,1,211,46,107,185,161,168,193,51,209,72,232,159,134,171,38,23,47,128,121,21,39,153,190,127,241,141,43,224,224,79,46,134,254,63,125,3,164,221,235,217, +205,72,61,126,206,238,2,206,234,76,190,136,199,207,126,102,177,129,210,183,7,134,158,253,21,28,248,201,133,48,244,226,253,73,229,110,114,36,0,171,3,16,36,195,158,191,201,198,95,138,189,1,3,123,175,132,225,131,119,19,239,121,45,115,48,56,222,149,124,113, +142,228,139,119,142,252,222,14,154,124,8,98,253,15,193,192,158,43,32,54,240,144,233,31,181,204,85,3,167,55,94,105,104,114,224,200,163,207,54,247,250,246,159,216,220,22,116,124,81,0,124,148,154,105,225,14,22,250,31,50,144,117,74,46,80,218,209,234,204, +230,171,77,223,191,225,127,60,0,61,247,93,3,210,222,13,71,12,252,103,118,186,18,44,192,57,60,160,69,135,96,224,175,223,133,158,255,185,30,212,225,94,115,35,1,139,147,213,1,40,2,16,36,3,198,223,228,176,127,172,255,127,96,104,223,205,32,19,175,63,105,224, +109,240,153,253,249,137,87,206,241,110,208,180,8,68,122,126,4,195,7,238,32,6,55,98,234,126,77,47,91,66,94,75,33,38,235,223,46,117,236,66,141,222,233,211,46,107,190,6,47,34,20,0,71,176,185,69,126,238,117,237,63,34,226,210,161,105,58,21,230,136,50,61,155, +92,91,94,107,192,212,253,27,122,238,62,232,255,203,221,204,224,115,22,123,234,27,16,68,38,4,98,171,159,131,67,191,186,10,148,190,189,230,69,2,92,88,29,128,32,249,96,252,35,189,63,38,175,159,177,176,62,245,236,83,39,41,4,226,195,127,131,161,3,255,65,4, +129,185,207,131,211,27,175,96,209,0,201,192,188,0,218,37,176,251,180,218,219,202,187,2,77,120,49,161,0,96,76,56,167,254,243,161,6,207,92,163,161,255,5,85,167,66,71,209,20,83,247,45,250,246,227,48,240,212,127,3,103,115,146,179,101,172,139,32,21,1,210, +206,53,208,243,155,235,76,21,1,180,58,192,137,213,1,8,146,211,198,63,214,255,32,51,224,70,205,2,77,8,148,162,175,66,228,208,247,76,221,71,218,23,224,236,150,107,128,35,251,167,129,190,229,76,90,214,77,252,40,207,236,107,218,126,32,88,208,252,21,252,17, +40,105,245,87,78,56,183,241,206,248,176,254,208,63,109,245,91,231,109,133,101,117,23,153,186,111,210,174,181,196,243,255,22,17,228,150,15,146,111,140,122,236,54,23,203,31,48,91,4,124,56,39,0,69,0,130,228,162,241,167,21,67,230,52,205,163,34,128,38,16, +198,6,30,52,117,95,219,2,19,89,187,224,168,129,165,0,41,166,64,197,216,224,210,73,23,52,158,131,2,160,144,63,188,192,193,140,47,180,124,75,180,241,69,122,27,254,208,201,85,34,39,178,208,191,222,50,149,79,220,110,164,31,250,254,112,59,168,241,8,11,225, +155,9,141,38,164,67,4,240,40,2,16,36,125,198,191,43,93,198,255,33,83,141,255,7,34,192,1,209,222,95,128,28,251,167,169,219,61,161,238,66,226,112,141,129,132,18,211,239,180,69,100,24,127,118,221,55,131,53,238,162,66,190,180,10,90,0,140,89,92,177,168,102, +106,248,108,35,237,126,227,74,4,22,215,156,5,13,190,118,83,247,173,255,145,187,153,145,214,181,230,159,37,34,0,19,3,17,196,68,207,223,228,108,255,72,207,97,207,223,105,186,241,79,66,151,44,85,86,77,160,42,251,77,219,170,77,176,195,89,205,87,131,200,91, +65,211,89,217,68,103,5,216,60,150,202,233,87,182,220,129,2,160,0,113,248,172,182,169,151,53,127,151,206,143,214,173,34,137,2,173,39,134,255,216,26,115,35,73,195,47,255,14,162,111,61,206,178,253,211,73,186,150,3,62,92,29,128,145,0,4,49,193,248,135,211, +96,252,7,30,76,139,231,255,209,135,140,21,20,101,15,68,14,125,151,252,70,49,109,179,141,190,78,88,88,181,28,162,138,254,165,0,234,248,53,205,43,187,188,97,78,233,100,20,0,5,198,228,139,27,175,241,87,186,58,244,10,0,170,60,69,114,115,158,217,116,21,107, +86,97,22,137,237,171,96,224,169,159,144,251,102,52,154,235,104,35,34,224,253,17,17,176,207,188,251,158,85,7,224,114,0,130,100,157,241,239,29,37,227,127,248,89,192,185,136,177,253,7,196,250,127,107,234,118,143,173,61,151,229,94,37,244,86,5,104,44,18,32, +204,184,162,229,123,22,135,80,144,182,176,32,63,116,73,171,175,186,235,148,154,175,36,12,36,254,81,229,73,179,254,205,12,253,171,209,65,232,123,248,191,64,147,227,134,51,254,83,19,1,238,17,17,112,173,201,213,1,97,156,29,128,32,217,102,252,251,71,207, +248,31,17,1,188,19,162,125,255,99,106,62,0,93,10,56,163,233,11,196,136,241,186,27,4,177,222,0,77,222,25,19,206,109,56,31,5,64,1,192,241,52,241,175,245,78,193,38,248,245,38,254,209,58,212,106,79,35,28,87,123,158,169,251,54,240,216,61,32,239,73,223,186, +255,103,71,2,176,58,0,65,50,138,150,127,198,255,3,83,163,193,240,161,239,131,166,244,153,182,213,102,127,55,204,173,92,102,104,96,16,29,27,60,246,244,218,59,189,165,142,64,161,93,110,5,39,0,26,231,150,206,172,153,26,58,71,210,153,248,167,141,104,205, +211,26,175,96,115,171,205,34,250,246,19,16,121,227,207,105,95,247,255,183,198,58,141,137,129,24,9,64,144,163,240,252,185,220,203,246,63,250,7,140,21,20,121,59,217,151,31,153,186,217,19,106,47,132,50,103,53,235,196,170,235,176,203,42,56,252,214,138,233, +87,180,220,140,2,32,143,161,235,60,228,36,127,83,77,168,186,63,55,109,69,57,189,116,49,116,4,205,203,27,81,14,237,132,254,199,190,7,156,104,201,220,205,153,102,17,128,179,3,16,228,51,140,127,206,102,251,167,240,28,224,92,16,31,250,59,36,134,30,55,109, +155,46,139,135,77,13,164,83,88,65,231,82,0,141,2,52,47,40,255,98,121,119,160,25,5,64,158,210,189,188,246,204,162,58,207,12,89,103,226,159,172,201,16,180,23,195,178,250,139,77,188,241,85,232,123,228,110,80,7,15,177,222,253,217,192,104,84,7,160,8,64,144, +79,48,254,185,154,237,159,202,243,133,183,178,150,195,170,188,211,180,109,78,40,158,3,227,195,179,33,166,232,123,174,208,229,96,222,202,59,103,92,57,166,160,198,5,23,140,0,240,20,219,93,19,207,107,184,67,138,25,24,246,163,196,217,186,127,192,22,54,109, +191,134,95,121,8,226,107,95,98,70,55,123,248,120,78,0,86,7,32,8,26,127,179,16,137,223,211,11,195,61,63,160,7,192,180,173,158,210,240,57,112,137,222,145,72,128,158,40,128,12,149,227,138,78,109,61,182,114,54,10,128,60,99,236,25,117,87,56,131,182,70,85, +214,23,34,138,43,49,150,112,50,171,252,56,211,246,73,222,187,17,6,159,254,217,40,149,252,233,21,1,35,213,1,253,230,86,7,56,23,225,0,33,4,141,127,190,148,250,165,236,8,112,78,144,34,175,65,108,240,143,166,109,179,196,89,5,139,170,79,39,207,106,157,207, +20,141,229,3,112,147,47,106,252,186,197,33,114,133,112,9,22,132,0,8,55,121,139,59,79,169,185,73,26,214,159,248,39,242,34,83,152,2,103,82,91,94,85,129,254,71,190,205,74,255,70,175,228,207,64,36,224,215,102,231,4,224,0,33,4,141,127,254,101,251,167,240, +12,224,237,16,237,187,15,20,105,171,105,219,164,115,2,170,60,77,186,19,2,233,242,112,81,189,103,102,235,146,138,83,80,0,228,9,19,47,104,184,222,238,17,195,170,206,178,63,154,248,55,181,116,17,52,249,187,76,219,39,22,250,223,184,34,57,229,47,203,193,217, +1,8,146,6,227,159,175,217,254,71,141,0,154,58,8,209,158,31,131,89,75,1,116,30,203,178,186,139,117,47,3,48,17,16,83,96,194,249,245,183,59,131,54,107,190,95,138,121,47,0,138,91,124,53,141,115,74,175,212,219,239,95,33,23,146,223,86,4,39,212,154,215,39,66, +62,176,21,6,159,190,55,75,67,255,153,19,1,152,24,136,20,138,241,119,164,35,219,191,55,123,178,253,143,250,185,194,57,33,17,125,29,226,131,143,152,182,205,113,225,153,208,77,142,109,76,103,155,96,69,82,33,88,227,233,24,119,70,221,121,249,126,57,230,189, +0,152,112,94,253,205,162,93,112,235,156,25,193,214,147,142,169,90,14,65,123,137,57,59,164,105,172,225,143,26,237,207,226,208,255,167,137,0,156,29,128,32,134,61,127,98,252,133,112,186,74,253,114,193,243,255,216,115,133,183,177,165,0,85,222,99,218,54,79, +172,191,136,69,3,84,157,15,254,68,68,130,246,101,85,183,184,66,25,108,204,130,2,192,24,165,29,254,230,198,185,165,23,208,236,78,61,208,117,164,42,119,3,204,175,60,217,188,27,245,173,71,33,182,246,197,44,203,250,63,106,245,130,213,1,8,98,208,248,23,78, +182,255,209,34,130,170,244,176,210,64,179,168,118,55,193,204,178,99,217,180,86,93,167,75,214,192,29,182,215,143,61,189,230,226,124,190,44,243,86,0,208,150,191,179,190,216,122,139,96,21,28,122,189,127,69,149,89,217,31,85,146,166,60,3,6,15,193,224,223, +126,10,156,152,203,75,75,31,171,14,192,217,1,8,146,57,227,223,155,235,198,255,240,243,218,73,188,238,231,64,138,188,104,218,54,151,214,158,205,74,182,21,77,167,3,24,85,160,253,196,234,47,17,33,224,65,1,144,99,212,78,15,183,85,140,15,158,165,215,251,167, +101,127,45,129,177,48,177,120,158,105,251,68,75,254,148,222,221,89,211,240,199,188,72,0,206,14,64,144,140,24,255,254,220,55,254,35,119,62,249,37,64,164,239,94,208,212,33,83,182,232,183,134,96,65,213,105,108,108,187,190,40,128,74,163,0,53,221,167,213, +92,142,2,32,151,62,20,241,254,39,158,219,240,101,98,167,172,122,58,67,210,178,63,158,227,224,248,218,243,201,87,115,14,81,98,203,91,16,249,231,35,57,26,250,255,148,91,22,103,7,32,200,103,27,255,130,207,246,63,218,7,138,21,148,196,22,136,13,252,206,180, +77,206,173,88,6,229,174,90,144,232,185,208,21,5,144,161,99,89,245,181,238,144,221,139,2,32,71,168,156,80,52,134,120,255,103,208,16,142,94,239,191,43,52,29,90,131,19,204,217,33,69,134,129,39,127,12,154,162,208,180,215,188,58,214,56,59,0,65,62,221,248, +99,182,127,138,247,61,249,76,177,129,63,130,34,109,50,101,123,14,209,5,139,170,207,0,89,247,160,32,13,92,97,123,121,247,233,53,23,162,0,200,17,218,79,172,186,142,227,56,155,158,127,171,129,10,86,222,10,199,214,156,107,218,254,12,191,241,103,72,108,121, +155,8,92,123,62,30,110,172,14,64,144,79,242,252,49,219,95,151,73,210,180,8,68,123,127,97,218,22,167,149,46,130,90,111,11,27,227,174,43,10,16,145,161,131,230,2,228,97,69,64,222,9,128,226,22,95,125,227,220,178,243,164,136,94,239,63,202,6,75,212,121,199, +152,243,44,24,234,129,161,231,238,3,206,98,131,252,229,99,57,1,253,88,29,128,160,241,199,108,127,157,247,60,235,13,240,10,36,76,74,8,20,137,67,183,184,250,44,80,84,125,54,65,85,88,20,160,166,123,121,237,57,40,0,178,156,9,231,214,95,101,177,243,14,77, +75,125,241,95,211,84,176,11,46,114,177,156,105,218,254,12,61,255,107,80,122,119,229,65,226,223,209,138,128,247,161,231,215,105,168,14,64,17,128,228,140,241,255,15,204,246,55,42,2,64,128,88,223,125,228,153,28,51,101,123,19,137,83,215,224,239,128,132,129, +40,0,141,44,187,66,246,188,242,228,242,74,0,148,140,241,149,53,206,45,189,80,111,215,191,152,26,133,201,37,243,161,210,221,96,202,254,208,97,63,195,43,254,148,87,137,127,41,69,2,204,204,9,112,97,117,0,146,205,151,254,135,61,255,25,230,27,255,254,194, +49,254,201,27,222,10,114,98,3,196,7,255,98,142,161,227,4,54,40,72,111,99,32,26,5,112,23,219,91,154,230,149,230,213,140,128,188,18,0,109,199,87,93,106,113,138,126,77,87,230,191,10,78,193,13,11,171,150,155,182,63,131,207,220,11,90,124,152,102,182,20,212, +179,16,103,7,32,5,231,249,115,233,44,245,123,168,176,140,255,225,231,8,111,135,216,192,239,65,83,14,154,178,189,113,161,153,208,232,107,215,29,5,144,227,10,116,157,86,123,157,197,33,228,205,3,61,111,62,136,167,212,225,105,94,88,246,121,73,175,247,47, +71,97,82,201,60,40,115,213,154,178,63,241,77,43,32,186,250,57,34,100,157,80,136,224,236,0,164,96,140,255,225,108,255,48,102,251,155,139,8,170,188,143,136,128,135,76,139,2,44,172,210,31,5,80,18,42,132,26,60,147,90,151,86,30,131,2,32,203,232,58,165,230, +44,87,200,94,73,67,53,169,123,255,26,216,69,39,204,175,52,41,186,67,46,176,193,103,126,193,190,230,91,217,95,106,34,192,149,214,62,1,60,138,0,36,11,140,63,102,251,167,51,10,224,132,216,224,99,160,72,219,77,217,222,216,176,177,40,128,34,171,208,122,92, +229,181,180,211,44,10,128,44,193,230,22,197,166,5,101,95,160,99,28,117,121,235,114,4,198,135,103,155,182,246,31,91,253,44,36,54,189,153,83,211,254,210,67,26,171,3,104,36,96,241,109,184,28,128,100,220,248,155,237,249,71,123,10,43,225,239,179,76,20,29, +25,28,27,248,95,83,182,38,112,2,235,14,168,119,92,176,18,87,160,172,195,191,176,110,70,113,55,10,128,44,161,97,110,233,194,96,173,187,139,142,113,212,227,253,91,5,59,185,40,78,53,199,228,201,9,24,124,254,55,57,55,233,47,253,34,224,112,117,128,121,34, +128,119,133,176,68,16,201,43,227,79,61,255,40,26,255,143,69,1,28,144,24,126,22,148,196,251,166,108,143,230,2,212,120,154,217,176,183,148,159,102,26,155,51,35,118,44,171,186,18,5,64,54,124,0,145,167,77,26,190,168,199,248,83,104,159,232,142,162,201,80, +235,105,49,71,189,175,124,10,164,29,239,229,121,221,191,145,72,192,181,88,29,128,228,240,165,140,131,125,50,19,5,136,67,180,255,183,166,108,77,36,231,111,94,197,73,32,235,109,15,28,81,160,122,114,248,140,112,179,183,20,5,64,134,169,158,84,212,81,62,46, +184,72,79,248,63,217,243,95,48,109,237,95,75,68,97,232,69,114,145,138,22,188,103,63,201,88,99,117,0,146,235,158,63,102,251,103,44,10,32,69,95,1,57,254,158,41,219,155,84,50,31,202,92,53,32,107,169,139,0,218,99,198,234,18,124,173,199,86,158,143,2,32,195, +180,29,87,117,9,167,129,168,75,201,17,85,217,228,235,132,150,192,56,115,188,255,183,31,7,121,207,250,28,31,247,155,251,34,0,19,3,145,180,24,127,204,246,207,228,147,131,24,94,217,180,92,0,58,226,125,86,217,177,32,41,122,27,3,41,48,102,113,197,37,206,128, +45,167,67,189,57,45,0,188,101,142,64,205,212,240,217,180,62,83,215,61,173,169,48,167,98,25,27,68,105,138,247,255,202,67,104,252,143,74,4,96,117,0,146,123,198,31,179,253,51,252,220,224,236,196,240,190,6,114,124,181,41,219,155,86,182,24,2,246,98,80,116, +36,4,178,198,64,97,91,115,227,252,210,69,40,0,50,68,243,194,242,83,156,1,107,177,158,210,63,58,29,170,210,93,15,99,77,186,161,233,218,191,188,103,3,0,10,128,163,145,75,31,36,6,178,234,0,147,167,8,98,117,0,146,6,227,143,189,253,179,32,10,0,178,105,125, +1,188,214,32,76,42,158,199,242,192,244,160,200,26,180,46,169,184,44,151,75,2,115,86,0,88,157,34,215,113,98,245,231,36,157,165,127,116,62,244,244,210,165,96,225,141,71,112,52,57,14,195,175,254,30,215,254,83,22,1,238,100,36,224,215,215,97,117,0,146,181, +198,223,129,9,127,89,20,5,112,128,20,121,21,228,248,26,83,182,55,171,252,120,54,50,152,118,130,77,217,137,140,43,80,210,30,56,166,172,35,208,132,2,96,148,41,31,27,156,228,175,118,77,214,147,253,79,107,64,3,182,16,76,41,53,167,161,19,173,251,151,118,173, +3,78,196,204,255,212,69,128,51,125,213,1,40,2,16,19,60,127,1,141,127,150,69,1,18,16,31,252,63,115,236,136,171,22,218,139,38,65,92,79,46,128,70,3,190,188,173,245,184,138,243,80,0,140,50,109,199,85,94,192,233,188,123,226,106,12,198,23,207,6,159,53,104, +194,131,66,129,225,87,254,128,117,255,70,110,233,116,37,6,162,8,64,12,26,255,180,101,251,115,104,252,245,71,1,236,144,136,188,2,138,180,217,156,40,64,217,113,196,16,234,59,23,82,84,134,250,89,37,231,56,131,182,156,236,250,150,147,2,192,87,238,244,87, +79,9,157,42,233,44,253,179,241,118,152,81,182,212,148,125,137,175,127,5,18,219,223,5,206,98,199,59,51,75,69,128,11,171,3,144,20,141,63,102,251,103,183,217,210,212,97,136,15,254,217,148,173,141,9,78,128,106,79,147,174,198,64,52,255,204,83,236,168,111, +154,95,186,0,5,192,40,209,188,176,252,56,103,192,86,162,169,169,39,255,209,178,143,38,127,23,212,152,212,248,103,248,213,63,224,253,104,154,8,72,211,40,97,172,14,64,82,244,252,49,219,63,203,159,21,196,137,75,12,63,79,12,176,241,220,33,145,19,97,106,233, +34,150,24,174,235,178,81,84,104,156,91,118,65,46,158,214,156,19,0,180,243,95,243,49,101,23,40,9,157,165,127,228,215,244,178,37,166,236,139,180,99,53,196,55,190,129,222,191,105,124,124,118,128,217,213,1,73,17,128,203,1,200,167,26,255,46,204,246,207,13, +4,98,120,123,32,62,248,184,41,91,155,88,60,15,252,182,176,174,25,1,82,92,129,242,238,192,226,226,102,95,5,10,128,52,19,110,242,54,6,235,61,179,229,68,234,201,127,138,38,67,177,163,2,186,138,166,153,227,253,191,254,48,171,0,40,228,137,127,105,21,1,191, +78,223,114,0,138,0,228,227,198,159,133,253,67,104,252,115,43,10,240,55,208,212,33,195,219,242,219,138,160,43,52,77,95,73,32,49,69,22,135,232,105,152,83,114,50,10,128,52,211,118,92,197,105,162,77,176,65,234,209,127,114,114,227,108,234,31,45,251,48,138, +210,187,27,98,107,94,64,239,63,109,34,192,153,182,229,0,108,27,140,252,139,231,143,217,254,57,136,8,138,180,19,18,145,231,77,217,218,212,210,133,32,240,22,246,252,73,21,57,161,208,165,233,179,45,14,33,167,78,116,78,9,0,139,83,224,107,166,21,159,174,196, +117,38,255,137,14,152,108,82,174,70,228,205,71,65,29,234,197,236,255,116,42,252,116,182,13,198,234,0,36,237,217,254,104,252,211,254,140,224,68,136,15,209,101,0,197,240,182,104,91,248,100,50,160,164,227,82,82,33,80,229,154,92,218,17,232,64,1,144,38,202, +58,2,227,253,149,206,110,85,78,61,252,79,147,255,26,188,237,80,237,54,222,179,65,75,68,32,250,206,83,56,241,47,151,69,128,11,103,7,160,241,79,119,182,63,26,255,244,63,32,172,160,196,215,130,28,91,105,252,153,192,9,48,177,120,174,174,100,64,58,38,152, +23,121,161,97,78,201,105,40,0,210,68,203,226,138,229,28,207,241,154,142,240,63,237,247,76,39,64,153,65,108,237,203,32,31,216,2,32,96,231,191,209,17,1,31,106,27,140,179,3,16,19,61,127,204,246,207,249,167,3,49,190,202,72,20,192,56,19,138,231,128,219,234, +103,115,98,82,118,50,99,10,237,9,112,138,221,103,21,115,229,232,229,140,0,112,6,108,150,186,233,197,39,233,25,251,75,51,59,253,182,16,116,135,204,73,254,139,188,249,87,154,129,130,247,222,168,241,161,182,193,105,154,29,128,213,1,133,103,252,205,246,252, +163,152,240,151,25,9,192,219,136,126,127,29,84,217,248,115,33,100,47,131,22,255,88,54,41,54,229,75,75,86,193,87,225,236,168,158,84,52,1,5,128,201,84,77,42,154,228,10,217,154,245,12,254,73,144,147,217,26,156,0,62,107,145,225,253,160,70,40,177,229,45,76, +254,203,136,8,72,87,117,64,8,171,3,10,200,248,59,210,52,216,39,138,198,63,67,208,146,192,62,72,68,158,53,101,107,180,36,80,211,147,101,206,174,49,128,134,57,165,57,83,13,144,51,2,160,97,46,57,168,58,207,9,29,247,75,215,118,76,81,249,239,60,1,90,60,130, +165,127,25,19,1,88,29,128,232,185,116,48,219,63,175,163,0,156,5,18,195,207,38,207,179,65,58,138,38,65,145,189,148,149,141,167,10,173,6,168,28,95,116,162,195,103,205,137,245,225,156,16,0,206,160,205,90,49,54,120,130,172,35,251,159,158,196,176,163,2,198, +4,198,25,127,134,196,135,33,250,222,115,152,252,151,233,155,29,171,3,144,84,61,127,14,179,253,243,251,161,96,37,198,119,19,72,241,119,140,219,27,209,3,109,193,137,250,90,3,203,26,184,139,237,173,85,147,67,227,81,0,152,68,121,87,96,130,59,108,111,209, +27,254,239,40,154,12,118,193,105,120,63,226,235,95,3,229,224,14,76,254,203,10,17,224,194,217,1,200,209,25,127,44,245,43,16,20,72,12,61,109,202,150,38,132,103,179,170,0,125,209,8,128,234,137,161,147,80,0,152,68,245,164,208,9,122,35,238,2,39,194,184,208, +12,115,110,248,119,158,196,251,60,107,208,62,90,29,208,143,179,3,16,52,254,5,237,20,112,54,144,98,111,128,166,244,24,222,22,157,23,19,118,148,235,91,6,136,171,80,49,46,120,172,197,46,100,125,147,152,172,23,0,22,135,40,84,79,13,31,75,15,106,202,39,66, +147,160,196,81,1,13,62,227,189,25,148,222,61,144,216,242,38,112,34,134,255,179,75,4,184,147,34,128,37,6,238,51,239,97,50,82,29,128,203,1,104,252,63,78,20,75,253,178,20,1,84,249,0,36,162,175,24,222,146,77,112,64,107,96,2,235,30,155,178,173,144,84,240, +87,187,218,203,58,3,237,40,0,12,82,49,54,216,230,175,116,117,208,131,154,42,146,146,128,214,224,68,176,10,198,51,246,99,107,158,199,206,127,89,45,2,232,114,192,181,166,87,7,124,52,49,16,31,246,185,100,252,49,219,191,16,195,0,2,155,18,104,6,99,195,51, +64,224,245,149,244,11,34,47,212,207,41,93,154,237,135,43,235,5,64,213,164,162,69,188,160,111,49,70,36,39,111,108,104,166,41,70,38,186,250,89,122,86,241,6,203,90,17,224,76,75,179,32,238,35,137,129,17,60,212,57,228,249,11,56,213,175,240,236,63,77,6,140, +191,71,188,240,237,134,183,69,91,3,211,101,0,89,213,87,13,80,222,21,56,150,207,242,209,0,89,45,0,232,232,223,202,241,69,75,21,41,245,236,127,26,254,15,179,240,127,155,225,253,144,246,110,4,105,231,90,224,68,43,222,97,217,124,243,167,49,49,16,171,3,114, +203,248,139,88,234,87,160,240,108,58,160,20,125,217,240,150,232,50,0,173,30,147,53,29,213,0,146,10,69,117,238,137,225,102,111,21,10,0,157,248,43,157,101,193,90,247,100,61,225,127,153,60,12,104,71,39,122,18,141,18,95,243,34,104,241,33,236,254,87,224,34, +192,133,34,32,235,141,191,163,11,19,254,48,10,32,130,20,161,121,0,154,225,109,209,209,241,156,142,115,78,219,213,91,156,162,179,122,114,104,46,10,0,157,84,77,10,205,180,185,45,30,29,109,153,217,73,235,44,154,98,194,131,69,129,216,218,23,1,4,244,254,115, +3,45,109,34,128,195,18,193,236,246,252,137,241,23,66,104,252,81,1,208,158,0,27,64,73,108,50,188,169,70,95,7,4,236,197,108,150,76,202,151,165,172,66,213,132,208,98,46,139,155,198,101,183,0,24,95,180,88,83,83,87,113,201,222,255,97,104,244,119,26,222,7, +105,207,122,242,218,128,225,255,156,20,1,135,115,2,176,58,32,239,141,63,13,251,135,48,219,31,73,186,127,154,58,76,52,186,241,106,0,151,197,11,13,190,118,93,77,129,228,132,10,225,22,239,44,103,145,205,153,173,71,42,107,5,128,221,107,181,148,118,6,102, +209,100,138,148,141,54,57,89,245,222,86,112,91,124,134,247,35,254,254,43,160,37,162,216,250,55,39,69,192,72,137,32,171,14,48,79,4,252,107,117,0,146,113,227,143,217,254,200,135,37,0,109,13,28,93,1,102,44,3,180,7,39,147,205,164,30,134,166,206,171,195,111, +173,14,55,123,187,81,0,164,72,81,131,167,205,85,100,109,212,211,253,143,142,114,164,173,28,141,219,16,21,98,239,255,3,64,196,206,127,185,29,9,48,191,68,144,195,182,193,121,109,252,49,225,47,215,21,128,21,148,196,70,80,164,173,134,55,213,226,239,6,151, +213,11,42,164,40,2,52,90,149,200,67,221,140,226,249,217,122,152,178,86,0,212,78,13,205,17,44,228,232,105,169,30,115,21,156,22,55,52,251,141,139,46,121,255,150,100,248,31,91,255,230,246,179,32,93,179,3,92,56,64,40,239,140,63,203,246,127,8,141,127,238, +223,245,35,203,0,43,12,111,41,228,40,131,10,87,61,75,44,79,253,82,85,161,180,221,63,143,23,179,243,90,202,74,1,64,147,237,203,199,6,231,41,178,158,236,127,25,202,156,53,80,226,50,94,125,17,223,176,2,180,24,102,255,231,135,8,112,165,109,128,208,225,234, +0,76,12,204,3,227,207,214,252,157,104,252,243,225,158,231,4,83,4,0,77,40,167,21,101,138,142,126,0,106,178,43,224,120,111,137,163,40,27,143,81,86,90,54,87,145,221,21,172,117,79,84,117,150,255,209,228,63,222,132,143,22,219,240,10,118,254,203,27,210,95, +29,128,179,3,70,201,248,99,169,31,114,84,55,38,93,6,216,0,170,98,60,255,135,246,3,16,121,11,164,154,83,160,170,26,216,61,150,64,73,155,127,98,54,30,162,172,20,0,197,45,222,46,71,192,86,169,103,253,159,78,112,106,13,24,159,196,168,14,236,7,105,231,58, +204,254,207,75,17,144,190,234,0,30,151,3,210,111,252,49,219,31,57,74,243,166,42,125,32,199,86,26,222,82,181,167,9,2,182,176,174,114,64,26,65,40,31,27,156,141,2,224,40,33,7,107,58,207,167,126,35,210,242,63,159,53,8,53,158,102,195,251,16,223,186,18,212, +161,30,140,0,228,165,8,248,208,236,128,126,115,171,3,176,89,80,250,140,191,35,13,165,126,152,237,159,255,72,209,55,12,111,195,33,186,153,93,145,116,228,1,208,78,182,165,237,254,153,217,216,22,56,235,4,0,173,182,43,235,12,204,212,53,252,71,147,160,210, +93,15,94,34,2,140,146,216,104,78,9,9,146,205,145,0,34,2,126,125,173,233,203,1,88,29,96,230,169,250,80,147,31,204,246,71,82,189,31,249,228,108,0,77,51,126,47,54,5,186,200,118,82,183,75,138,172,65,160,218,213,233,41,115,134,80,0,124,6,174,34,187,35,88, +235,30,175,103,253,95,85,21,168,247,25,159,192,168,201,113,136,111,91,137,221,255,242,94,4,96,117,64,214,123,254,92,122,154,252,96,182,127,161,64,71,4,239,99,185,0,70,105,244,117,130,77,176,147,39,71,106,142,33,237,7,96,243,88,2,165,109,190,172,235,7, +144,117,2,192,95,237,106,177,123,45,149,122,218,255,210,233,127,180,117,163,81,228,125,155,65,233,217,9,28,78,255,203,127,15,33,93,34,192,141,34,192,176,241,199,108,127,196,248,29,78,188,246,4,200,177,119,12,111,169,220,89,3,65,123,9,168,154,172,103, +55,104,100,123,42,10,128,207,58,200,221,129,137,188,149,231,83,85,89,116,253,159,134,254,171,220,141,134,247,33,177,229,109,208,226,216,253,175,112,68,128,43,45,163,132,89,137,32,206,14,200,82,227,143,158,127,225,220,224,2,72,38,36,2,90,137,247,95,229, +110,208,53,30,88,149,53,218,220,14,5,192,103,17,110,242,77,213,145,104,201,198,255,150,187,106,193,99,245,27,222,135,248,230,183,200,145,193,218,255,194,225,195,109,131,175,51,53,49,240,112,199,64,172,14,64,227,143,100,200,254,115,22,80,164,205,160,41, +135,12,111,139,206,5,80,117,132,167,217,120,224,122,79,151,51,104,115,100,211,177,201,42,43,103,177,139,92,168,201,51,94,79,2,160,162,42,80,235,29,99,220,20,196,134,216,0,32,14,215,255,11,87,4,252,218,236,234,0,28,37,156,138,241,119,164,171,189,47,26, +255,2,69,0,85,233,5,57,177,209,240,150,106,189,173,96,101,182,33,245,126,0,14,175,165,50,80,237,106,66,1,240,41,120,203,29,101,158,98,123,147,166,163,254,95,224,4,54,0,200,40,210,222,141,172,7,0,8,88,254,87,152,34,32,141,213,1,152,19,240,111,14,61,102, +251,35,233,188,190,20,144,227,171,12,111,166,204,85,3,94,107,81,234,253,0,136,73,19,108,60,95,222,21,28,139,2,224,83,40,170,247,180,91,156,162,59,213,17,192,52,36,227,180,120,160,210,221,96,120,31,18,219,87,145,103,81,28,31,20,5,12,38,6,102,192,243,199, +108,127,36,173,55,181,192,202,1,141,226,18,61,80,230,172,214,151,7,160,2,132,154,188,89,213,17,48,171,4,64,184,217,59,78,207,61,170,104,50,132,236,165,172,83,147,25,2,0,123,255,35,40,2,70,209,248,167,189,189,47,102,251,23,252,253,204,242,0,182,129,166, +244,26,222,86,181,167,153,37,157,167,126,169,107,16,172,115,143,203,166,193,64,89,101,233,66,141,222,241,122,194,255,84,0,84,184,235,89,27,96,35,104,137,40,200,123,55,0,135,227,127,17,72,115,117,192,71,6,8,21,168,113,74,99,123,95,76,248,67,62,138,64, +140,127,31,75,6,52,74,173,183,133,216,154,212,77,167,42,171,224,45,177,183,184,195,14,127,182,28,149,172,17,0,22,135,40,4,170,93,109,84,37,165,108,184,53,13,106,60,198,115,43,228,131,219,65,233,223,79,142,10,214,255,35,236,202,250,88,117,128,217,29,3, +15,207,14,136,20,174,241,239,68,227,143,140,210,221,172,73,32,199,215,26,222,78,185,171,14,28,162,139,141,158,79,233,253,85,13,172,94,107,40,80,227,170,71,1,240,49,124,229,206,18,87,216,86,167,103,0,144,69,176,66,149,219,184,0,144,118,175,99,81,0,172, +255,71,254,85,4,208,196,64,115,69,64,193,206,14,192,108,127,36,19,16,175,93,78,188,111,120,51,69,246,18,240,219,66,186,6,3,9,2,199,133,155,189,29,217,114,72,178,71,0,84,58,27,89,2,160,150,122,3,32,183,197,7,197,206,74,227,2,96,231,90,188,73,144,79,17, +1,174,15,68,0,86,7,24,56,148,152,237,143,100,200,254,131,8,138,180,149,214,122,27,218,142,133,183,66,169,179,26,20,29,137,128,212,190,249,43,93,89,211,18,56,107,4,64,176,222,221,206,235,240,188,169,10,11,218,74,192,99,49,186,172,162,177,250,127,12,255, +35,159,46,2,48,49,208,176,231,159,174,108,255,30,204,246,71,62,75,1,136,160,202,7,64,145,247,24,222,20,29,58,167,171,33,144,172,65,168,193,211,158,45,147,1,179,70,0,20,55,123,59,85,85,95,2,96,153,171,90,87,82,198,71,78,204,96,15,40,61,187,176,255,63, +242,239,159,33,163,32,2,242,178,109,112,186,179,253,7,48,219,31,249,236,24,128,166,69,64,73,24,79,4,76,38,157,235,75,4,244,148,58,26,109,30,139,13,5,192,225,157,16,121,240,150,58,199,168,74,234,138,138,134,84,104,82,134,81,104,2,160,58,220,135,45,128, +145,163,16,1,31,174,14,48,177,99,224,200,236,0,62,223,68,64,58,179,253,113,205,31,73,205,96,152,50,25,144,46,1,216,4,135,222,201,128,21,222,50,71,25,10,128,17,236,30,139,195,83,98,175,211,100,29,29,0,121,129,8,128,26,227,2,96,223,70,208,228,4,62,68,144, +163,185,141,63,36,2,174,53,183,58,32,223,102,7,28,78,248,75,87,169,31,174,249,35,41,221,96,66,50,15,192,32,65,91,49,120,172,129,148,251,1,208,20,55,209,46,216,189,229,206,172,168,4,200,10,1,224,173,112,148,217,188,150,178,84,59,0,210,50,12,187,224,132, +98,71,133,225,125,144,246,108,196,236,127,36,197,72,192,135,171,3,112,118,192,167,26,255,206,219,64,192,82,63,36,27,238,89,160,2,96,39,49,196,198,18,1,105,25,32,173,6,208,83,9,192,243,28,109,8,212,130,2,96,4,103,192,86,43,88,4,91,138,5,0,44,9,195,75, +84,24,45,201,48,44,0,14,108,33,71,3,251,255,35,122,34,1,233,153,29,224,202,229,196,192,116,103,251,163,241,71,116,70,0,52,181,7,52,249,128,225,77,81,199,83,85,83,23,0,212,209,45,170,243,160,0,56,76,81,189,167,81,79,86,36,157,0,24,176,21,179,181,24,67, +207,170,216,32,40,189,123,201,3,5,19,0,17,61,34,32,61,137,129,92,174,86,7,96,182,63,146,181,240,196,104,71,64,145,119,26,222,18,77,62,79,53,7,224,176,0,32,78,111,19,199,115,89,112,52,178,128,96,173,187,89,211,81,1,160,130,98,74,248,95,38,15,109,117,184, +23,35,0,136,126,99,141,213,1,31,24,255,195,29,254,48,219,31,201,74,205,174,176,185,0,198,35,0,149,108,10,109,202,142,43,109,9,92,225,168,177,56,50,63,114,54,43,4,128,43,100,111,72,181,1,16,59,143,228,223,148,152,208,0,72,57,180,19,59,0,34,38,136,128, +52,206,14,200,133,234,128,81,25,236,131,158,63,98,244,70,229,76,17,0,33,71,41,88,5,123,234,149,0,228,175,91,157,98,153,35,96,11,20,180,0,96,109,127,45,192,249,42,156,213,84,21,165,188,243,28,15,97,71,185,241,8,192,193,237,116,103,240,198,64,140,186,22, +31,21,1,38,38,6,102,125,117,0,14,246,65,114,6,1,84,121,183,225,173,248,172,69,224,178,120,82,175,4,160,165,128,110,209,239,10,217,202,51,125,36,50,27,1,208,232,51,131,115,139,54,190,44,213,165,20,170,186,44,188,13,130,246,18,227,2,224,192,118,244,254, +17,19,35,1,238,15,37,6,154,91,29,64,7,8,101,93,78,0,14,246,65,114,233,254,100,2,224,0,107,10,100,4,151,197,11,94,107,48,245,142,128,26,235,125,195,23,213,186,43,51,125,44,50,27,1,32,94,191,175,194,81,108,247,91,131,169,14,1,210,200,65,119,90,220,224, +183,21,25,222,15,165,119,23,174,255,35,105,136,4,172,79,246,9,232,51,121,128,80,54,37,6,166,115,205,31,179,253,145,180,40,0,158,120,225,253,160,201,61,6,133,4,7,1,91,56,229,8,0,251,183,196,225,180,121,44,181,5,31,1,160,107,33,60,207,165,220,22,81,37, +191,220,68,129,185,68,175,177,93,72,68,65,25,56,128,2,0,73,131,8,200,243,234,128,116,27,127,108,242,131,164,41,6,160,169,81,80,149,253,134,183,68,123,1,232,201,95,83,201,191,41,106,240,212,100,250,72,100,84,0,40,10,29,140,224,174,20,44,60,164,186,4,64, +235,47,233,26,140,72,30,64,134,158,97,195,189,236,197,113,40,0,144,52,60,106,142,68,2,242,108,128,208,168,100,251,163,241,71,210,36,0,52,25,20,217,248,253,88,100,47,213,85,10,72,255,137,205,37,86,23,180,0,160,203,238,54,183,69,215,58,8,141,0,208,240, +139,97,17,50,112,16,180,120,148,102,20,226,125,129,164,41,18,144,198,234,128,197,25,40,17,196,176,63,146,243,168,166,36,2,210,62,52,122,135,2,249,171,93,44,9,80,79,9,124,206,11,0,26,53,161,205,127,138,26,61,149,122,166,0,210,176,75,192,94,108,92,0,244, +239,3,77,193,25,0,72,186,69,128,59,61,213,1,174,207,168,14,208,49,178,244,35,110,202,199,189,27,244,252,145,188,8,2,240,196,8,27,95,2,240,219,67,44,10,173,165,158,197,78,19,1,75,129,214,193,21,106,4,96,228,64,232,238,228,19,48,161,5,48,243,200,84,21, +111,8,100,148,68,64,122,170,3,92,135,171,3,18,31,202,108,150,19,192,123,74,245,63,35,29,149,44,99,26,14,39,57,169,137,35,189,253,177,206,31,201,109,136,0,80,140,183,3,246,90,252,96,163,189,0,82,204,3,208,20,218,13,208,26,180,20,129,71,149,11,50,2,64, +199,34,90,193,95,229,42,81,83,238,1,160,129,192,139,44,7,192,120,4,96,63,150,0,34,163,40,2,210,83,29,192,141,84,7,136,101,29,201,72,0,121,137,85,19,193,218,113,162,238,109,10,254,54,176,212,158,149,20,0,242,48,112,86,31,246,246,71,242,35,0,64,132,173, +166,244,209,44,112,67,219,161,125,0,232,96,32,58,152,46,85,251,39,216,120,15,103,129,160,158,36,66,179,200,92,243,123,141,206,101,224,4,209,46,132,116,68,79,64,224,68,86,131,105,120,55,162,3,248,208,65,70,89,4,124,80,29,16,188,224,251,196,208,150,154, +178,101,90,29,224,58,246,235,32,239,89,197,68,173,88,218,65,110,20,35,17,70,14,108,77,151,131,165,100,30,168,177,125,32,248,218,200,190,135,76,61,26,81,204,246,71,50,36,1,52,45,78,94,18,185,85,172,186,183,66,167,209,58,69,15,244,196,14,64,170,227,108, +104,245,27,141,2,104,25,12,64,103,46,2,160,106,96,247,138,46,139,67,8,164,60,6,152,40,38,171,96,99,101,128,8,146,147,143,159,52,149,8,82,131,47,86,142,7,177,98,156,65,227,255,161,135,132,183,5,196,226,217,166,27,127,26,246,143,162,241,71,114,24,158,19, +192,101,241,233,106,7,44,88,5,26,1,47,214,148,2,92,2,160,141,127,220,97,187,207,225,183,186,83,22,0,228,151,93,112,128,67,116,26,127,16,59,168,136,192,28,0,36,19,34,32,61,213,1,185,0,174,249,35,153,69,35,158,191,205,144,247,127,24,15,17,0,122,154,1,81, +205,160,72,106,56,147,71,33,179,125,0,36,213,71,140,127,202,86,156,118,1,164,161,23,155,224,50,188,15,98,168,10,64,195,219,1,201,208,67,40,77,213,1,104,252,17,228,223,221,121,10,240,98,152,141,173,54,44,0,172,126,0,157,189,0,124,101,142,112,38,199,2, +103,116,9,192,87,238,244,11,34,207,167,126,220,52,112,90,60,134,155,0,81,44,21,173,228,26,176,3,170,0,36,179,34,192,252,234,128,172,52,254,152,240,135,100,197,109,167,128,96,29,99,202,166,220,116,9,64,143,253,39,255,200,87,225,12,101,242,54,200,168,0, +240,148,56,130,188,133,75,249,224,209,225,11,14,209,109,202,113,179,150,183,128,24,174,1,144,37,188,41,144,12,138,128,244,84,7,100,157,241,199,53,127,36,27,238,55,222,10,22,199,20,147,4,128,254,92,52,69,82,139,50,233,123,102,122,9,32,160,47,114,162,130, +139,8,0,83,16,173,224,24,187,24,52,41,142,247,5,146,97,17,144,166,196,192,44,0,179,253,145,172,185,211,180,56,121,236,183,129,104,51,39,2,224,20,189,186,186,1,82,39,216,225,183,6,5,107,230,204,112,70,5,128,213,37,250,117,31,116,139,199,180,253,112,78, +58,9,132,162,10,162,72,18,120,119,32,25,37,31,69,0,245,252,49,219,31,201,22,161,77,95,118,223,25,228,171,57,243,95,92,22,247,136,0,72,205,155,165,137,240,222,114,151,215,234,204,220,28,154,140,9,0,154,248,16,106,242,250,245,212,64,210,181,19,167,224, +54,239,32,184,2,224,57,230,50,208,164,4,96,46,0,146,121,17,144,63,213,1,216,222,23,201,42,243,175,14,131,213,57,15,44,142,153,166,109,147,46,71,211,114,64,77,215,254,104,30,173,80,151,0,8,58,23,79,136,130,51,161,4,240,35,81,128,137,39,130,115,242,201, +160,70,7,241,46,65,50,238,165,164,107,138,224,104,126,134,40,102,251,35,217,35,171,137,227,24,5,193,82,7,174,224,85,166,110,153,182,2,166,141,233,244,56,143,196,248,187,105,83,192,66,21,0,250,226,248,28,199,218,47,154,141,111,217,151,193,209,185,16,212, +200,0,128,134,145,0,36,11,34,1,187,214,65,239,131,183,130,150,136,230,212,190,71,251,239,39,175,223,161,241,71,178,198,243,23,196,82,112,23,255,39,112,66,145,169,219,166,77,233,216,64,160,84,59,218,146,191,111,113,8,46,171,83,176,102,234,184,100,78,0, +104,201,240,135,190,157,230,137,234,114,154,190,75,156,197,6,129,179,190,14,174,105,167,177,161,42,154,140,57,1,72,134,35,1,118,55,36,182,188,5,137,109,239,228,208,110,199,32,49,244,4,209,233,14,52,254,72,134,81,137,157,25,4,209,214,66,140,255,221,44, +2,96,54,22,142,8,0,78,76,189,27,160,162,129,171,200,106,245,20,59,108,5,39,0,44,78,1,188,101,14,151,170,163,13,34,71,123,148,11,233,57,102,84,4,248,79,253,26,4,206,184,19,196,64,25,121,150,13,38,43,4,52,236,22,136,100,44,22,192,198,151,230,142,108,249, +215,239,16,100,116,189,75,137,60,178,135,128,142,187,113,248,206,5,79,201,61,196,248,215,164,199,150,17,91,36,232,236,73,67,103,226,105,154,102,207,212,145,202,216,48,32,209,198,131,51,96,179,15,12,105,41,202,16,218,194,145,7,171,144,222,99,230,24,127, +44,216,90,103,66,244,237,199,33,250,206,147,32,237,221,4,90,124,56,25,183,97,211,3,209,179,65,70,225,81,38,199,193,222,50,29,172,53,221,185,35,87,56,59,216,220,75,33,210,251,19,250,1,112,218,38,50,74,70,95,27,185,254,172,192,139,101,196,201,156,70,174, +195,99,211,226,245,127,196,150,113,22,22,1,208,41,120,173,35,175,194,18,0,90,114,9,192,161,239,1,195,129,133,79,127,212,132,119,120,193,53,253,76,112,77,59,3,228,125,155,32,177,123,29,200,251,183,130,58,116,136,60,215,254,63,123,231,1,47,71,89,245,255, +179,51,179,237,246,126,211,147,155,222,72,2,161,6,233,72,145,162,2,214,191,149,87,254,250,250,250,170,20,11,254,241,125,21,21,21,20,17,20,72,40,210,91,66,73,40,161,164,87,82,110,239,189,238,189,119,123,239,51,187,255,231,121,54,137,160,160,185,179,51, +91,207,55,159,225,134,36,187,59,59,237,252,206,121,78,17,81,3,32,234,18,139,129,80,49,19,10,63,241,229,99,221,42,179,7,67,233,87,217,90,171,24,106,252,123,20,3,65,212,50,254,196,139,212,240,37,204,240,11,186,69,192,147,45,177,4,165,62,188,134,7,45,175, +99,213,105,50,46,115,33,47,5,192,241,99,39,231,84,211,37,0,65,163,77,221,94,178,209,170,11,217,134,32,200,73,221,52,196,251,186,138,109,8,146,211,87,58,177,15,84,4,36,97,131,243,48,9,48,241,217,178,82,249,105,205,165,192,9,120,229,33,8,130,32,105,37, +97,143,244,172,67,173,28,39,56,30,139,167,205,152,165,59,179,72,70,92,48,206,170,0,18,107,46,8,130,32,8,146,165,226,129,215,128,177,52,125,189,128,185,108,61,112,113,204,48,70,16,4,65,210,238,197,106,64,199,233,166,94,6,24,143,131,96,224,161,108,78,81, +81,186,246,61,157,2,128,186,240,83,95,2,160,69,3,26,14,120,92,2,64,16,4,65,50,65,4,208,50,93,89,189,128,19,67,129,242,81,0,208,240,191,172,36,64,186,230,194,167,50,9,16,65,16,4,65,114,140,116,47,1,196,211,242,82,4,65,16,4,65,1,128,32,8,130,32,8,10,0, +4,65,16,4,65,80,0,100,34,52,219,50,142,189,249,17,4,65,16,36,43,5,128,72,182,192,84,95,68,219,138,75,49,17,162,49,156,212,135,32,8,130,100,49,26,214,11,32,109,125,178,211,41,0,104,22,159,132,87,0,130,32,8,146,173,208,136,116,68,10,179,150,192,83,118, +102,163,49,240,89,67,193,124,20,0,199,244,143,188,3,142,141,128,16,4,65,144,76,17,1,114,204,159,20,142,129,103,60,16,206,215,8,128,95,214,65,139,139,16,149,162,120,213,33,8,130,32,233,53,254,241,56,196,226,146,60,127,86,3,113,13,159,190,73,153,233,108, +167,151,212,18,128,20,79,253,234,129,100,182,129,52,97,134,152,211,13,241,96,16,175,124,68,237,39,11,8,179,103,130,118,213,178,172,220,125,79,32,2,102,103,128,60,28,227,56,12,24,81,213,144,240,28,7,6,29,15,69,6,45,20,23,232,200,255,167,238,138,163,198, +95,140,69,88,75,96,25,80,79,54,148,127,2,64,195,198,40,6,101,188,140,28,240,24,68,98,169,49,192,226,192,8,132,182,237,133,240,251,13,32,142,154,32,230,245,147,83,134,209,7,36,53,2,0,200,131,173,232,107,55,64,241,247,255,35,171,118,125,216,236,133,109, +77,228,222,137,72,104,252,145,212,152,20,141,6,116,2,7,133,70,45,76,47,47,132,5,51,74,97,86,149,250,109,246,99,228,151,24,139,78,57,7,224,184,95,9,137,132,248,252,18,0,113,49,14,209,144,20,158,250,49,211,176,7,163,218,85,0,212,211,247,61,250,60,4,223, +219,3,113,143,15,200,149,5,26,65,75,54,30,64,139,115,8,144,20,33,73,224,123,246,85,48,92,118,1,104,151,46,204,138,93,142,197,226,112,184,103,18,194,196,248,211,7,50,130,164,236,118,33,215,158,203,23,6,187,39,4,29,163,14,152,81,81,8,107,23,214,192,172, +234,34,21,63,83,100,2,64,38,212,144,165,45,7,32,109,150,44,236,19,193,49,236,11,112,117,220,148,23,2,168,226,138,72,234,69,77,168,199,239,249,195,195,32,77,90,65,83,104,4,77,113,33,222,89,72,122,224,137,224,12,133,137,32,181,100,141,0,16,165,24,4,194, +98,74,195,176,8,146,136,2,144,91,134,252,231,248,181,103,178,251,96,194,225,135,85,117,85,112,246,178,105,192,169,80,113,71,157,81,49,46,130,156,28,0,13,167,9,211,45,93,199,43,221,242,220,39,43,122,64,4,64,72,82,103,9,192,255,236,43,224,188,253,183,32, +57,221,9,195,207,161,7,131,164,143,120,56,2,124,117,37,232,86,44,206,154,125,214,106,121,168,45,43,128,168,132,205,186,144,52,95,139,60,199,140,126,67,159,5,222,173,31,97,226,84,121,1,16,78,44,1,76,81,0,16,195,15,33,79,52,18,116,69,210,150,3,144,110, +235,230,145,245,80,140,199,33,44,6,20,223,153,192,150,119,192,243,199,13,160,209,10,160,209,225,180,65,36,205,198,63,74,30,42,122,29,148,222,241,67,224,106,170,178,199,11,35,219,39,86,204,128,26,42,2,68,20,1,72,250,163,2,122,34,74,251,198,93,176,179, +121,140,165,214,40,9,141,70,211,101,128,169,6,23,232,4,225,16,49,254,1,71,56,109,93,237,210,42,0,56,94,227,145,121,74,33,40,249,21,221,151,104,103,47,120,239,121,152,60,112,181,137,176,43,130,164,19,106,252,181,90,40,191,235,167,160,63,239,204,172,219, +253,34,163,22,62,117,198,60,168,42,53,160,8,64,50,2,42,2,186,199,156,208,216,111,85,244,125,195,82,24,196,120,20,100,46,1,120,201,150,182,36,192,244,9,0,162,194,156,35,126,183,220,37,153,128,168,160,0,16,37,240,222,187,1,98,129,32,128,128,9,126,72,250, +141,63,156,48,254,103,101,237,215,72,136,128,58,34,2,140,40,2,144,140,64,43,240,208,208,107,6,135,87,185,168,123,136,56,163,180,44,93,142,41,99,2,64,147,190,174,118,105,19,0,52,140,239,183,132,220,178,122,39,144,35,22,136,122,149,59,129,59,247,67,184, +190,5,52,5,70,188,67,144,12,242,252,207,202,250,175,243,247,72,128,17,115,2,144,180,67,115,3,195,68,140,54,244,41,23,5,8,136,190,99,195,233,166,158,3,16,116,134,189,98,36,125,247,69,122,151,0,180,156,67,206,235,104,178,5,61,232,10,41,17,8,188,178,21, +147,253,144,140,241,252,203,114,196,248,255,147,8,40,193,72,0,146,1,81,0,158,131,97,139,135,53,170,82,2,191,232,133,152,140,158,118,28,175,1,207,68,192,25,13,164,111,36,78,218,172,30,245,226,195,222,168,51,30,139,203,120,45,167,152,0,144,70,199,33,218, +209,195,146,173,16,36,221,198,191,60,199,140,255,71,70,2,80,4,32,105,132,46,59,135,194,34,17,1,202,68,145,253,17,183,236,196,66,34,2,236,233,236,148,149,62,1,64,212,143,125,208,227,20,35,177,248,84,243,0,56,22,1,240,42,210,14,56,210,218,5,49,175,15,35, +0,72,218,136,231,184,241,71,17,128,100,158,8,208,192,132,93,25,39,210,23,245,200,126,173,20,141,217,210,121,28,210,92,5,192,121,104,32,64,78,4,32,40,250,33,162,64,47,0,113,104,4,20,175,11,65,144,41,120,254,154,60,48,254,255,44,2,176,58,0,73,163,237,225, +52,224,14,68,88,46,90,178,120,163,46,89,109,128,105,14,128,185,203,99,139,75,233,179,63,233,139,0,112,108,9,192,21,9,74,126,205,20,59,134,209,28,128,48,49,254,74,84,2,196,236,46,244,254,145,180,25,127,200,35,227,255,97,17,128,213,1,72,26,35,0,100,139, +68,37,69,18,83,189,17,34,0,228,152,210,132,217,179,228,101,4,128,38,64,120,205,33,111,208,21,117,77,89,0,104,184,99,2,32,249,16,78,92,20,241,110,64,114,202,248,139,225,40,217,148,187,174,105,154,142,39,172,236,125,130,213,1,72,46,64,35,8,190,168,27,56, +205,212,77,105,140,136,95,191,61,108,213,164,209,255,76,107,209,187,134,215,68,136,16,160,107,32,11,166,42,156,162,49,145,40,47,103,242,66,196,104,196,37,0,36,103,140,127,203,198,195,208,183,179,147,37,58,45,184,112,25,156,114,253,25,160,73,162,39,255, +246,126,59,220,187,119,16,108,129,8,172,153,94,2,191,252,228,34,152,86,164,87,84,4,188,117,100,8,108,238,32,104,113,112,16,146,74,39,148,220,36,154,36,103,3,68,98,33,86,5,48,85,1,64,63,86,138,198,36,247,88,192,78,243,225,242,46,2,64,31,74,17,111,20,220, +99,126,171,70,152,234,1,208,128,20,23,193,29,177,39,127,0,170,42,80,0,32,105,48,254,183,43,110,252,143,252,109,15,52,60,115,0,2,54,47,248,173,94,168,127,106,31,244,19,49,32,151,17,87,8,126,248,122,39,52,79,122,193,30,136,194,150,78,11,124,125,99,11,140, +123,148,155,93,130,37,130,72,58,160,81,45,189,78,96,37,129,201,224,143,122,89,62,154,70,70,42,127,60,30,247,145,87,57,210,121,28,210,42,185,165,72,12,162,1,113,92,142,10,163,161,23,103,56,249,4,74,126,90,53,128,6,167,150,33,234,243,225,108,127,101,219, +251,82,227,223,190,185,1,116,133,122,224,180,252,137,109,162,117,84,246,123,54,78,120,192,17,140,64,145,142,7,129,8,246,50,131,0,237,102,31,124,115,19,17,1,94,133,69,192,153,243,160,18,115,2,144,84,221,139,228,87,161,33,249,0,56,173,0,8,75,1,182,44,61, +37,195,43,112,224,183,69,92,17,43,184,120,109,250,204,112,26,251,0,80,21,22,7,247,120,208,36,43,131,146,188,198,25,74,62,127,130,9,0,173,0,128,65,0,68,101,207,95,173,108,255,19,198,191,64,247,225,102,100,52,196,153,68,145,177,72,220,164,15,142,79,165, +183,8,21,3,237,22,34,2,88,36,64,185,118,170,84,4,92,133,213,1,72,170,4,0,177,61,244,154,75,22,26,133,142,178,73,128,50,246,33,22,55,199,99,16,74,231,113,72,107,4,128,118,79,244,219,66,163,26,89,9,148,156,34,17,0,174,186,10,52,6,67,98,103,16,68,37,227, +15,170,25,255,189,208,190,165,145,24,127,253,71,71,178,146,8,110,125,220,75,139,143,139,128,151,91,85,88,14,192,234,0,36,37,46,40,148,24,147,111,254,230,12,91,217,36,192,169,222,104,52,2,224,26,241,79,178,61,225,242,48,7,32,241,197,1,2,206,200,104,76, +70,29,36,77,186,112,19,1,16,135,228,30,20,92,69,25,112,37,197,137,69,33,4,201,42,227,191,7,58,182,212,131,206,168,131,84,118,19,139,31,19,1,29,116,57,224,101,117,114,2,42,177,58,0,81,211,246,144,251,165,184,32,121,1,96,15,77,202,86,215,209,160,56,146, +238,227,144,222,70,64,180,25,131,41,48,17,151,98,83,30,165,68,5,128,39,234,2,127,52,185,82,64,174,184,16,248,170,114,136,75,18,222,21,72,118,121,254,155,27,64,107,212,67,58,90,137,158,88,14,80,73,4,92,133,137,129,136,138,215,46,77,254,43,86,32,2,96,15, +78,202,170,36,160,182,207,214,231,25,206,107,1,192,166,33,185,162,230,72,64,154,242,88,96,142,205,3,240,130,55,154,100,41,32,249,96,126,122,45,0,10,0,68,201,135,140,202,158,127,59,245,252,11,210,99,252,255,49,18,208,174,98,36,0,151,3,16,197,175,219,120, +28,116,90,94,145,36,64,71,216,2,188,134,151,245,218,136,95,204,115,1,192,107,32,64,51,33,253,162,121,234,221,0,57,136,72,97,112,40,145,8,56,107,58,46,1,32,138,26,127,213,19,254,140,233,53,254,31,41,2,212,168,14,56,3,171,3,16,165,5,0,16,227,175,5,189, +54,57,1,16,146,130,224,14,219,137,51,58,69,1,64,123,0,144,235,217,214,239,195,37,0,144,64,244,140,7,70,57,25,77,64,196,88,20,108,193,137,164,247,67,152,59,43,35,30,166,72,14,144,142,108,255,12,16,1,234,87,7,160,8,64,148,33,70,156,189,18,114,15,37,91, +253,237,137,56,192,39,122,100,53,1,138,134,36,127,192,25,49,229,181,0,96,15,49,242,244,8,58,35,253,114,219,33,154,131,163,73,239,134,48,103,102,98,28,48,54,4,66,146,52,254,106,133,253,143,50,227,255,47,178,253,51,0,117,171,3,80,4,32,202,9,214,178,194, +228,187,89,58,66,102,8,139,129,41,155,209,99,77,240,38,189,230,160,53,191,5,192,49,236,131,222,62,78,198,64,30,26,122,177,4,146,23,81,252,244,26,208,176,74,0,124,184,32,153,103,252,19,165,126,153,231,249,127,212,131,245,131,213,1,38,172,14,64,50,16,122, +11,149,43,208,206,218,18,52,177,40,244,84,111,73,54,7,199,18,26,147,194,82,56,221,199,34,35,4,0,57,24,189,114,198,50,210,228,11,90,134,65,79,66,82,7,161,162,12,248,218,106,172,4,64,50,208,248,239,73,107,182,191,28,17,112,188,58,224,70,172,14,64,50,16, +129,231,160,76,1,1,48,225,31,145,213,63,142,230,190,5,29,145,62,41,154,254,107,56,35,4,128,115,216,55,40,137,177,41,91,95,26,1,112,71,28,224,73,182,18,128,227,216,50,0,136,40,0,144,12,51,254,172,201,143,46,171,114,84,254,185,58,64,217,156,0,92,14,64, +228,66,187,207,26,245,2,203,1,72,22,186,252,204,201,168,0,160,209,110,251,160,183,59,19,142,71,70,8,0,183,41,48,22,241,68,237,220,20,167,34,209,54,165,129,168,79,153,68,192,5,115,177,18,0,153,154,161,75,129,231,159,234,38,63,170,136,128,77,152,19,128, +100,136,0,136,209,6,64,180,2,128,79,234,125,162,177,8,235,1,32,167,4,144,205,177,25,241,161,0,56,78,200,29,117,251,109,225,145,169,143,69,212,64,52,30,129,201,64,242,213,20,218,69,117,0,60,143,119,8,114,210,158,127,190,101,251,203,17,1,39,170,3,54,97, +159,0,36,51,34,0,229,133,134,228,157,214,136,29,220,97,135,172,8,0,29,3,236,26,245,247,163,0,56,134,24,150,226,30,115,176,139,147,49,23,89,67,158,50,227,190,193,228,35,0,117,179,129,43,41,196,68,64,228,164,140,191,250,97,127,125,206,76,169,252,123,117, +0,77,12,84,97,57,160,196,8,17,20,1,200,73,66,69,99,178,152,3,99,16,148,124,83,46,1,164,54,46,236,137,90,220,166,224,72,38,28,11,46,83,78,138,99,200,215,206,201,152,205,204,113,2,140,7,146,111,168,68,147,0,89,34,32,230,1,32,105,52,254,29,91,178,55,236, +255,175,34,1,199,171,3,110,84,163,68,240,204,99,145,0,172,14,64,254,157,163,71,12,112,101,73,242,17,0,147,127,16,68,54,4,104,138,14,43,249,124,191,53,52,24,242,68,188,40,0,62,44,0,218,228,172,192,211,53,24,107,112,28,130,162,63,201,43,67,0,97,254,28, +0,81,196,187,4,73,143,231,191,185,49,107,178,253,229,136,128,34,21,19,3,177,58,0,249,119,176,4,64,157,160,72,5,128,201,55,32,111,6,0,113,114,61,230,96,135,20,201,140,235,52,99,4,128,173,215,219,45,6,197,232,212,135,2,241,224,9,59,192,26,26,79,122,31, +180,203,22,225,18,0,146,30,227,191,37,251,215,252,79,54,18,144,16,1,152,24,136,164,88,0,196,226,204,248,27,146,76,0,164,19,104,39,252,195,196,249,156,122,43,97,186,4,96,237,245,182,100,202,49,201,24,1,224,53,7,71,195,62,113,108,234,51,1,52,16,142,133, +136,34,75,62,15,128,9,0,157,22,59,2,34,31,190,225,213,14,251,103,80,111,255,212,138,0,117,102,7,160,8,64,62,46,2,160,196,250,191,43,108,7,91,72,94,5,0,221,7,107,143,7,5,192,63,18,116,134,67,158,137,96,23,47,99,38,0,53,216,35,222,158,164,247,65,152,63, +23,248,138,114,0,92,75,68,62,224,249,171,157,237,175,205,113,207,255,163,68,192,137,229,128,141,88,29,128,164,6,26,178,175,45,43,72,250,125,104,213,153,63,234,158,114,5,0,253,252,168,79,244,57,6,189,189,40,0,254,217,134,131,99,192,219,200,9,114,102,43, +11,48,234,235,75,254,96,148,151,130,48,111,22,196,49,15,0,57,102,252,213,15,251,231,78,182,255,84,249,96,117,0,54,11,66,212,22,157,180,246,191,74,129,4,192,17,98,191,229,36,0,82,219,230,179,134,6,60,147,193,73,20,0,31,129,165,199,211,32,231,89,40,104, +4,54,19,192,27,117,37,189,15,218,21,75,48,17,16,73,81,182,191,62,175,167,80,126,120,118,128,90,57,1,6,172,14,64,78,76,0,84,162,3,224,144,167,123,202,229,127,9,1,192,129,115,196,223,34,134,50,231,130,204,40,1,96,235,243,180,73,209,184,140,68,64,14,60, +17,39,75,204,72,22,221,234,229,216,16,8,141,63,102,251,167,80,4,20,169,218,54,184,14,171,3,16,38,0,170,75,141,178,50,247,63,244,104,136,69,192,228,31,0,158,155,122,2,32,93,49,176,245,122,142,102,210,113,201,44,1,208,235,25,242,89,67,35,156,156,142,128, +228,196,12,121,186,146,143,0,44,89,192,150,2,48,15,0,141,63,118,248,75,109,36,0,171,3,16,53,175,177,233,21,133,73,191,143,53,104,2,71,200,34,171,2,128,238,4,141,114,163,0,248,24,66,222,104,216,61,30,104,230,4,57,163,129,57,24,244,116,38,127,64,106,170, +64,168,155,147,200,252,70,242,235,33,145,18,227,143,158,255,191,21,1,216,54,24,81,242,218,138,39,214,255,107,203,147,79,0,28,242,244,64,72,10,176,234,179,41,185,168,156,6,66,158,168,131,56,185,157,153,116,108,184,76,59,89,147,173,206,195,114,18,1,121, +78,11,163,190,126,8,75,201,135,16,217,50,0,118,4,204,59,207,31,123,251,167,95,4,224,236,0,68,105,104,233,93,89,161,30,74,11,146,111,0,52,224,105,151,103,104,137,77,243,76,4,59,137,131,107,67,1,240,47,176,244,184,15,201,25,178,76,107,50,29,97,139,34,131, +129,116,107,87,17,79,16,243,0,242,201,248,99,182,127,230,80,252,1,17,96,82,169,58,0,103,7,228,15,82,44,206,188,255,100,111,191,88,92,98,9,128,114,194,255,180,188,221,222,239,61,28,207,176,137,179,25,39,0,172,221,158,214,176,55,234,144,213,16,72,12,194, +160,167,35,233,125,160,13,129,248,234,74,140,2,160,241,79,138,163,152,237,47,59,18,192,170,3,44,42,205,14,32,34,160,26,171,3,242,6,106,248,103,86,21,37,111,155,130,19,96,9,154,100,37,0,82,75,107,106,178,31,200,180,99,147,113,2,192,109,10,216,93,99,129, +86,94,198,50,128,70,195,65,175,171,53,249,131,82,90,12,218,165,139,48,15,32,231,141,191,168,162,231,191,23,218,48,219,63,41,17,80,164,106,78,0,86,7,228,197,117,68,46,164,2,189,22,166,41,177,254,239,237,130,128,232,37,70,115,106,102,147,86,30,136,33,41, +108,238,112,215,163,0,248,55,196,164,56,76,182,59,15,242,50,66,240,2,167,37,39,169,27,194,82,48,233,253,208,159,185,6,64,194,8,64,110,123,254,130,138,107,254,245,184,230,175,80,36,224,239,205,130,48,39,0,153,26,82,44,198,162,61,5,122,33,233,247,234,113, +53,201,139,64,208,9,128,246,112,55,113,110,71,50,237,248,112,153,120,210,198,155,156,123,227,50,18,1,88,30,64,208,204,234,52,147,69,119,250,42,208,20,21,210,133,31,188,139,114,205,176,164,160,206,31,179,253,21,22,1,102,20,1,136,12,135,50,30,135,153,149, +201,135,255,197,184,8,3,238,78,214,116,110,202,118,73,203,209,254,255,7,195,190,104,198,121,148,25,41,0,204,29,174,6,114,176,60,156,140,60,128,72,44,76,148,90,115,210,251,32,204,155,147,40,7,20,113,25,32,215,60,127,13,78,245,67,17,128,34,32,47,208,242, +60,204,170,78,94,0,76,250,135,143,173,255,107,167,110,100,121,13,140,55,59,118,103,226,241,201,72,1,224,158,8,76,186,70,3,205,156,118,234,187,71,163,0,93,206,166,228,119,130,231,64,127,198,106,128,8,10,128,92,50,254,170,103,251,227,154,191,250,34,96, +147,122,179,3,176,58,32,119,160,217,255,229,197,122,168,40,78,190,255,127,143,171,5,66,162,140,250,127,242,207,165,168,20,158,104,113,30,70,1,112,146,196,196,56,152,219,93,187,228,8,0,129,245,3,232,3,79,196,145,244,126,232,215,157,14,26,28,15,140,198, +255,36,140,63,102,251,167,78,4,116,88,212,235,24,136,213,1,185,37,0,102,85,21,1,167,64,249,109,151,179,65,118,255,127,151,41,208,97,235,247,14,102,226,49,226,50,245,228,153,154,29,187,228,24,94,58,162,209,19,118,64,159,187,61,233,125,160,131,129,248, +217,51,176,28,48,235,141,191,186,217,254,108,164,47,26,255,148,137,128,34,85,151,3,176,58,32,87,224,57,13,204,169,41,73,250,125,124,81,15,171,255,23,184,169,15,18,226,117,28,76,182,185,246,68,252,153,121,65,101,172,0,152,108,119,53,132,188,81,139,12, +209,5,177,120,12,58,28,71,146,222,7,141,65,15,186,211,87,67,60,18,193,187,41,171,61,127,181,179,253,209,248,167,35,18,160,110,78,128,1,69,64,150,123,255,37,133,58,168,45,51,38,253,94,180,251,159,51,108,101,203,203,83,182,33,26,13,76,180,56,183,103,234, +113,202,88,1,224,30,243,187,108,189,222,131,188,110,234,7,93,203,235,216,154,13,29,16,148,44,6,98,52,52,56,29,48,59,13,5,102,251,231,135,8,80,171,79,0,38,6,102,181,0,152,85,89,4,2,159,188,137,107,183,31,97,93,0,167,108,252,201,71,135,60,17,215,200,17, +219,33,20,0,83,189,193,201,29,62,214,96,223,198,203,24,12,68,75,53,44,193,49,24,246,246,36,189,31,186,83,87,2,63,115,90,34,140,140,100,149,231,143,189,253,243,68,4,96,159,0,228,31,13,27,241,188,235,166,37,31,254,23,227,81,232,118,53,129,86,78,248,95, +203,129,99,200,127,196,51,17,176,160,0,144,193,200,17,235,118,73,140,201,176,188,26,136,74,17,162,220,146,79,188,212,20,24,65,119,230,169,184,12,144,101,198,31,167,250,229,107,36,0,171,3,242,157,24,241,254,75,11,117,48,77,129,241,191,35,222,94,48,7,70, +101,181,255,165,205,236,70,143,218,222,165,73,237,40,0,100,96,237,246,116,187,77,254,118,94,86,53,128,0,29,206,163,44,31,32,89,140,151,156,75,206,38,143,213,0,104,252,19,217,254,104,252,51,82,4,168,94,29,128,34,32,43,16,137,0,152,83,83,12,90,5,194,255, +109,246,67,16,145,194,83,46,255,163,72,209,88,140,8,128,247,50,58,82,146,201,59,71,51,39,205,157,238,247,104,38,229,212,5,128,14,198,124,3,48,238,79,190,250,66,187,122,5,8,115,103,65,92,196,101,128,204,54,254,152,237,159,207,34,224,131,213,1,38,204,9, +200,91,104,246,255,252,105,165,201,71,18,136,243,216,102,63,194,156,201,41,27,86,65,3,126,107,168,139,216,175,246,76,62,86,92,166,159,204,129,61,150,183,228,60,113,169,98,163,141,27,218,28,10,44,3,24,244,96,56,239,76,128,48,46,3,100,182,231,47,168,104, +252,49,219,63,91,34,1,84,4,220,168,70,78,192,153,88,29,144,233,208,228,63,218,248,71,137,225,63,212,121,164,109,229,229,148,255,9,122,158,150,178,191,23,246,102,118,242,88,198,11,128,209,35,182,195,62,75,112,140,182,83,156,186,18,20,160,197,118,16,228, +204,21,248,71,12,151,158,71,132,128,1,151,1,50,214,248,171,24,246,199,53,255,172,20,1,44,39,192,171,160,8,48,96,36,32,27,4,0,77,254,155,106,27,249,143,162,197,126,80,86,247,191,227,23,98,223,174,201,55,50,253,120,101,188,0,8,56,195,126,91,159,119,155, +156,101,0,154,185,73,147,56,38,252,67,73,239,135,118,217,34,208,46,93,136,201,128,121,102,252,105,123,95,45,102,251,103,167,8,176,168,85,34,136,213,1,153,122,222,117,2,7,11,166,39,31,254,143,199,99,204,121,148,19,254,215,16,241,17,116,69,76,227,205,206, +247,81,0,40,192,224,126,203,102,186,166,50,229,19,65,126,5,69,63,52,89,247,43,112,164,56,22,5,192,114,192,204,50,254,170,151,250,225,154,127,86,139,128,14,172,14,200,31,239,95,138,65,109,121,161,34,189,255,71,125,253,196,121,236,147,25,254,231,192,220, +233,222,230,183,133,124,40,0,20,17,0,230,93,33,119,212,170,145,17,214,161,179,1,154,108,7,20,169,6,48,92,114,46,112,21,101,52,206,132,119,91,134,120,254,101,152,237,143,252,11,17,80,132,213,1,121,3,157,220,190,104,102,169,34,239,213,100,219,7,97,41,40, +43,252,79,157,213,254,61,147,175,102,195,49,203,10,1,224,54,5,92,147,237,174,93,130,78,222,112,160,49,95,31,81,115,201,55,5,226,167,213,128,254,172,211,32,30,14,227,221,150,86,227,175,118,182,127,35,102,251,231,152,8,80,179,99,96,37,46,7,100,128,241, +143,67,49,57,31,117,181,201,11,0,218,122,166,153,56,141,90,25,163,127,19,225,255,168,109,232,128,117,15,10,0,5,25,216,107,222,164,209,202,91,6,8,75,33,168,183,42,51,142,217,120,213,37,180,205,20,222,113,105,245,252,213,206,246,199,53,255,92,19,1,106, +118,12,188,10,103,7,164,29,81,138,195,188,218,18,48,232,146,111,219,62,232,233,32,78,227,32,240,50,4,0,13,255,79,182,185,182,121,38,2,78,20,0,10,50,184,223,242,158,220,101,0,58,27,128,42,186,72,44,249,27,95,127,198,26,16,22,214,97,50,96,58,30,228,152, +237,143,36,43,2,84,157,29,128,34,32,93,8,196,46,44,153,85,174,204,179,192,178,19,196,88,68,86,248,95,147,8,255,191,152,45,199,45,107,4,128,219,20,112,154,219,93,239,81,133,53,229,139,67,163,133,73,255,8,116,59,155,146,223,17,157,22,10,46,191,16,32,18, +197,187,46,197,198,95,131,217,254,136,82,145,0,28,32,148,67,222,63,77,254,43,128,26,5,106,255,105,210,120,171,253,125,208,241,250,169,27,127,34,66,66,174,168,121,232,128,117,7,10,0,21,232,223,99,126,145,19,228,237,114,140,252,58,108,222,166,200,126,24, +174,184,16,184,138,114,76,6,76,21,152,237,143,40,44,2,58,44,88,29,144,43,208,228,191,165,179,43,20,185,125,105,235,95,107,112,28,120,205,212,203,255,104,243,159,201,118,215,155,158,137,128,7,5,128,10,244,237,152,216,225,179,4,77,114,74,2,117,156,30,218, +29,71,193,21,182,37,189,31,44,25,144,24,162,120,40,132,119,95,10,140,63,246,246,71,148,22,1,88,29,144,43,198,63,49,248,71,137,214,191,148,67,230,237,242,26,255,64,98,252,111,215,214,177,23,178,233,248,101,149,0,240,219,195,62,83,163,99,11,85,90,83,254, +162,26,30,220,97,59,52,40,148,156,89,240,153,203,65,163,211,98,103,64,85,141,191,168,242,84,63,204,246,207,119,17,160,110,78,0,46,7,168,13,77,254,91,52,163,12,116,218,228,77,25,157,250,215,195,70,255,78,61,252,79,157,82,175,37,52,48,120,192,178,23,5, +128,138,244,108,159,120,142,217,92,25,15,109,218,26,248,176,121,135,34,61,1,116,171,151,131,110,205,74,136,227,124,0,21,61,127,65,213,193,62,152,237,143,34,64,205,234,0,236,24,168,242,249,35,39,208,160,229,97,233,108,101,146,255,14,19,239,223,31,245, +16,103,81,70,158,25,237,253,95,111,127,37,228,142,102,85,88,56,235,4,192,208,1,235,251,238,49,127,27,47,99,25,128,182,6,30,242,116,65,191,187,45,249,29,209,104,160,224,186,79,97,30,128,26,55,182,218,237,125,49,219,31,249,71,17,96,70,17,144,117,62,2,121, +246,206,173,45,129,210,66,125,210,239,69,43,196,142,88,118,201,242,254,233,115,36,38,197,165,246,55,70,159,203,182,99,152,117,2,32,26,20,197,193,125,150,231,229,44,3,208,181,157,104,44,2,7,38,222,86,100,95,12,23,156,13,194,162,58,114,245,96,20,64,73, +227,175,118,182,63,122,254,200,199,138,0,156,29,144,53,208,177,191,43,231,85,42,242,94,237,246,35,108,102,140,32,163,246,159,215,114,224,26,241,31,153,104,85,162,204,12,5,192,191,165,115,235,216,139,98,36,22,210,200,120,136,235,121,3,52,219,15,42,146, +12,8,122,29,20,124,246,10,136,99,73,160,66,234,14,179,253,145,244,138,0,172,14,200,14,104,233,223,172,170,34,69,198,254,82,246,79,188,37,251,181,212,25,237,126,111,252,153,104,80,202,186,132,176,172,20,0,214,94,111,191,185,211,189,157,215,201,75,6,116, +133,237,44,219,83,9,140,159,186,24,248,89,211,201,21,137,67,130,146,53,254,152,237,143,164,91,4,124,184,58,64,121,17,128,213,1,202,157,171,149,243,170,20,121,47,147,127,16,186,156,141,160,227,167,62,68,136,58,161,17,191,232,238,223,51,185,41,27,143,99, +86,10,128,24,185,129,186,182,154,30,231,101,102,126,210,30,207,7,39,223,97,203,1,73,31,192,146,98,40,184,230,50,136,135,112,62,128,124,227,127,60,219,255,118,204,246,71,50,66,4,36,114,2,90,177,58,32,19,189,255,88,156,120,254,133,48,167,166,88,33,239, +127,43,107,0,36,167,252,79,48,240,96,106,118,188,110,237,246,152,81,0,164,144,222,29,19,111,251,172,161,33,142,151,151,12,104,242,13,176,166,15,74,64,151,1,184,234,74,58,143,18,239,78,89,158,255,241,108,255,51,85,48,254,184,230,143,76,93,4,96,78,64,6, +159,31,34,0,78,153,87,169,200,72,22,95,212,13,71,205,59,101,117,254,99,17,0,158,131,206,55,199,30,203,214,99,153,181,2,32,224,8,7,6,246,154,159,211,26,229,15,127,216,109,122,93,153,131,72,140,127,193,85,151,64,60,136,141,129,166,116,35,171,26,246,223, +139,189,253,145,228,69,192,241,156,0,47,138,128,76,241,254,171,201,113,91,48,93,153,198,63,180,244,207,30,154,148,213,249,143,23,56,112,143,249,91,6,247,89,246,161,0,72,3,29,111,142,61,41,69,99,97,57,15,120,186,222,211,237,106,132,65,79,167,50,81,128, +47,92,11,92,101,57,70,1,166,224,249,171,155,237,95,15,90,52,254,136,82,34,96,163,58,145,0,28,37,60,53,98,212,251,175,171,2,78,1,247,159,14,252,217,55,254,22,8,156,78,214,235,5,3,7,61,219,198,31,11,251,162,89,155,0,150,213,2,96,178,205,217,51,209,234, +122,71,118,73,160,20,134,93,166,205,138,236,11,109,15,92,112,245,39,49,10,144,9,198,31,179,253,17,133,69,64,199,137,102,65,202,38,6,94,133,213,1,39,141,68,140,127,85,137,1,22,206,80,198,251,111,182,29,132,17,95,31,91,18,158,178,253,32,2,36,236,19,157, +109,175,141,190,144,205,199,52,171,5,64,76,138,67,235,107,35,15,201,153,13,144,136,2,24,161,209,186,15,44,193,49,101,162,0,95,196,40,192,201,24,127,26,246,47,195,108,127,36,139,68,0,171,14,56,150,24,104,194,234,128,52,9,128,24,172,158,95,13,2,207,41, +112,78,227,204,249,147,219,247,95,107,224,97,228,176,109,163,107,204,111,65,1,144,70,6,246,154,183,123,198,131,109,188,140,41,129,180,229,163,63,234,38,23,194,22,229,162,0,215,94,134,81,128,143,53,254,216,219,31,201,110,17,64,19,3,111,196,234,128,148, +67,215,254,107,202,10,96,209,204,50,69,222,175,199,217,4,61,174,102,217,201,127,177,88,92,106,223,50,250,112,182,31,215,172,23,0,97,111,52,218,179,109,124,61,45,199,144,3,109,12,116,104,114,27,184,34,118,69,246,167,240,203,159,5,190,166,138,118,170,192, +187,246,159,60,127,65,229,246,190,152,237,143,168,43,2,212,175,14,192,72,192,71,30,123,34,0,214,16,239,159,231,148,185,193,183,143,189,2,82,92,146,87,250,167,231,193,214,231,221,53,116,208,210,136,2,32,3,104,122,105,232,217,160,59,98,145,83,18,200,105, +4,112,133,173,176,87,169,138,128,170,10,40,184,225,42,140,2,124,240,230,197,222,254,72,174,137,128,227,57,1,94,21,34,1,37,24,9,248,144,247,47,197,96,90,69,33,44,80,104,237,127,200,219,5,173,246,247,153,243,39,235,25,47,104,160,245,213,225,251,99,82,246, +79,130,205,9,1,224,157,12,58,135,14,88,158,148,27,5,160,21,1,251,38,222,98,53,161,74,80,240,249,107,129,159,51,35,225,245,162,241,79,65,111,127,52,254,72,14,69,2,206,196,18,193,127,100,237,162,26,226,172,41,115,147,191,55,178,145,53,129,147,227,253,211, +230,115,158,137,96,123,215,86,211,214,92,56,174,92,174,92,32,13,207,13,60,44,134,99,65,57,223,136,214,128,218,130,147,176,119,252,77,101,14,106,105,49,20,125,245,122,28,21,140,217,254,72,62,136,0,21,167,8,230,123,117,0,157,248,71,59,254,205,85,168,235, +223,152,175,31,154,108,251,137,247,111,148,245,122,234,100,118,189,109,122,48,18,16,115,194,187,203,25,1,96,233,242,12,76,180,58,55,105,245,242,162,0,90,94,15,187,77,91,192,47,122,20,217,31,227,181,151,129,118,217,162,252,21,1,216,219,31,201,51,17,128, +213,1,202,67,215,252,79,95,92,171,216,251,189,55,186,17,194,98,64,150,247,79,67,255,62,75,104,188,121,227,208,179,185,114,124,115,70,0,196,227,113,104,120,118,224,62,208,104,100,101,223,9,26,1,172,65,19,236,49,189,161,200,254,104,244,122,40,250,214,151, +243,179,36,16,179,253,145,60,20,1,88,29,160,44,52,250,177,104,102,57,212,150,41,51,241,207,228,31,128,122,203,110,208,11,242,188,127,173,65,128,193,125,150,13,62,107,200,157,43,199,152,203,165,11,102,240,128,165,97,172,222,254,182,214,32,55,10,96,72, +68,1,162,202,68,1,12,23,173,3,253,186,211,33,30,8,230,207,3,17,179,253,145,124,142,4,168,84,29,80,153,103,137,129,49,114,80,141,228,152,158,190,168,70,177,247,124,123,248,5,8,73,212,251,159,186,217,163,141,127,34,1,209,213,244,210,224,250,92,58,206,57, +37,0,104,169,72,203,166,225,123,56,65,222,215,58,30,5,216,105,122,77,153,29,210,104,160,248,59,95,3,141,94,151,184,162,243,192,248,171,185,230,143,189,253,145,140,23,1,22,117,68,192,85,52,49,48,143,68,0,93,251,95,85,87,5,37,5,58,69,222,111,216,219,67, +188,255,93,178,51,255,117,70,129,14,160,251,155,181,215,51,137,2,32,131,25,58,104,217,109,31,240,238,226,117,242,190,154,238,88,20,192,29,113,40,178,63,218,21,139,193,120,237,229,16,15,4,114,252,142,85,63,219,31,123,251,35,249,44,2,242,165,58,128,182, +252,173,44,54,192,170,249,213,138,189,231,214,225,103,33,194,198,198,200,240,254,53,204,251,247,55,60,51,240,64,174,29,235,156,19,0,228,68,65,227,11,131,119,11,50,147,1,105,69,128,35,100,134,109,163,155,20,219,167,226,111,125,137,117,9,132,236,157,25, +241,111,141,191,154,83,253,48,219,31,201,86,17,96,194,234,128,41,19,139,199,225,204,197,181,160,19,148,49,79,189,174,22,104,178,202,207,252,167,19,103,199,26,237,207,90,251,60,131,40,0,178,128,206,183,198,222,182,247,123,247,9,50,163,0,244,66,217,59, +254,6,88,131,227,202,28,228,170,10,40,186,241,139,185,89,17,160,246,72,223,45,245,24,246,71,178,82,4,208,1,66,55,170,48,64,40,151,171,3,168,176,153,87,91,162,88,211,31,122,54,222,28,122,26,164,184,40,175,239,191,134,37,152,135,154,94,28,252,99,46,94, +171,57,41,0,162,33,41,222,248,194,224,93,188,94,222,215,227,52,60,120,35,46,216,58,252,156,98,251,84,240,217,43,65,183,246,148,220,234,16,168,122,182,127,3,102,251,35,89,43,2,138,78,148,8,170,83,29,144,107,163,132,137,227,15,122,45,15,103,45,157,166, +216,123,54,217,14,64,187,227,136,124,239,223,192,195,232,81,251,179,67,7,173,61,40,0,178,41,10,176,213,244,182,173,223,183,79,174,8,48,8,70,120,127,242,61,150,60,162,8,2,15,37,223,255,15,182,78,14,177,28,184,105,49,219,31,65,78,42,18,160,86,179,160,227, +163,132,115,69,4,68,164,24,172,174,171,98,235,255,74,32,198,163,204,251,215,104,100,154,57,13,243,6,67,71,159,238,191,59,87,175,209,156,21,0,209,160,24,111,122,97,240,46,65,199,203,60,247,28,68,98,33,120,125,240,9,197,246,73,187,106,89,98,78,128,63,187, +203,2,213,238,237,143,217,254,72,78,138,128,77,106,204,14,200,13,17,32,74,113,168,46,49,192,154,133,202,37,254,237,31,223,10,3,238,14,208,113,242,38,254,209,204,255,129,221,147,79,142,28,178,245,228,234,245,201,229,242,205,215,185,117,108,171,125,192, +187,83,110,66,32,13,27,53,219,14,66,139,253,160,114,55,237,77,95,6,161,110,54,196,35,217,153,15,16,199,108,127,4,145,39,2,104,98,224,70,245,218,6,103,179,8,160,183,251,186,229,211,65,203,43,99,146,104,47,151,183,135,159,39,239,39,175,140,144,214,253, +71,195,146,255,192,67,221,191,163,77,230,80,0,100,101,20,64,130,163,79,245,223,73,91,56,202,187,40,53,172,4,100,203,192,223,216,240,8,69,14,120,73,49,91,10,0,41,150,88,244,202,170,3,170,158,241,63,138,189,253,145,124,17,1,155,80,4,124,144,136,40,193, +210,57,21,48,187,186,88,177,247,124,103,228,5,176,4,199,64,208,104,101,189,94,91,32,64,239,246,137,13,182,126,239,80,46,95,151,92,174,223,120,29,111,140,237,26,171,183,191,65,75,57,228,64,195,71,131,158,78,216,99,218,162,216,62,233,47,90,7,198,79,93, +12,113,127,22,245,6,80,123,164,47,246,246,71,242,73,4,168,84,29,144,109,34,128,214,252,151,146,251,254,172,37,202,245,251,31,247,15,193,46,211,102,208,243,242,90,8,211,148,129,104,64,116,214,63,51,112,79,174,95,147,57,47,0,104,248,134,156,200,95,16,79, +94,118,17,62,109,14,180,117,248,121,112,134,173,138,237,23,141,2,240,51,167,101,199,200,96,149,179,253,59,176,183,63,146,111,34,64,181,234,128,121,89,85,29,64,107,254,105,232,223,168,23,20,123,207,205,3,143,65,64,244,1,39,51,249,79,87,192,186,254,221, +103,235,243,76,160,0,200,1,6,15,88,234,71,142,216,158,211,26,229,93,100,180,57,16,53,254,175,15,62,169,220,129,175,170,128,146,31,124,11,226,162,152,217,75,1,41,200,246,215,98,182,63,146,183,34,32,127,171,3,104,205,255,210,89,229,48,127,122,169,98,239, +73,71,253,54,88,247,129,65,102,217,31,199,107,192,111,11,143,29,92,223,115,127,62,92,139,121,33,0,232,140,128,189,15,116,222,41,69,99,126,154,220,33,7,131,80,0,7,38,222,134,30,87,139,98,251,101,248,228,249,96,188,242,146,140,93,10,192,108,127,4,73,129, +8,200,195,234,128,68,232,95,7,103,47,155,174,216,123,134,165,32,188,54,240,232,49,207,95,222,67,69,87,168,133,182,205,163,191,241,76,4,92,40,0,114,8,75,151,187,191,111,231,196,3,186,2,185,101,129,26,136,197,37,120,165,127,61,171,47,85,138,146,31,126, +11,132,217,51,32,30,201,172,165,0,204,246,71,144,20,137,0,21,171,3,50,117,57,128,6,61,207,93,57,3,10,20,12,253,191,59,242,34,140,120,251,64,203,201,203,252,167,243,99,236,131,222,214,250,231,6,30,207,151,107,144,203,167,27,110,255,131,93,247,4,156,145, +113,26,230,145,165,14,121,3,244,186,90,97,215,216,107,202,157,128,202,114,40,249,209,127,38,154,3,101,202,82,64,74,178,253,49,236,143,32,255,156,24,152,251,203,1,225,168,4,43,230,86,64,93,109,137,98,239,57,238,31,132,119,71,55,202,14,253,83,104,215,191, +134,103,7,110,15,185,35,145,124,185,254,242,74,0,120,38,130,142,230,77,195,191,20,100,86,4,36,68,128,30,222,28,122,70,177,57,1,20,106,100,11,191,112,45,196,125,25,176,20,144,178,108,127,180,254,8,242,33,17,112,44,39,192,148,195,213,1,172,225,15,217,151, +179,151,77,83,244,8,110,234,123,24,130,162,159,181,113,151,131,64,140,255,120,179,115,107,231,91,99,111,230,211,181,199,229,219,205,86,255,116,255,227,174,17,127,189,220,113,193,52,33,208,27,117,193,203,253,235,21,221,175,226,239,126,29,180,167,44,73, +239,172,0,236,237,143,32,105,23,1,55,170,84,29,144,110,17,64,3,156,60,167,129,11,86,205,2,157,192,43,246,190,251,39,222,97,205,218,146,241,254,53,188,38,242,254,163,61,63,137,134,164,188,186,238,242,78,0,68,2,162,248,254,35,61,63,230,181,242,191,186, +129,47,128,122,203,110,56,98,217,169,216,126,105,10,140,80,250,179,239,179,159,32,165,225,34,76,73,111,127,52,254,8,114,178,145,128,92,19,1,81,242,92,59,99,73,45,76,43,47,80,236,61,157,97,27,75,252,147,187,238,79,209,23,105,161,111,219,196,131,131,7, +44,173,249,118,205,113,249,120,163,117,189,109,218,49,124,208,250,60,173,247,148,11,141,4,208,40,128,39,226,84,108,191,180,203,22,65,201,247,190,9,241,96,56,165,199,3,179,253,17,36,3,69,64,14,85,7,208,146,191,186,105,165,176,102,65,181,162,239,75,147, +178,29,33,11,121,30,203,235,248,71,187,196,6,221,145,241,253,15,119,255,26,226,249,119,189,229,165,0,160,161,168,125,15,118,221,30,13,73,110,185,101,129,2,167,5,107,96,156,92,128,27,20,221,183,130,207,95,147,232,18,232,243,167,196,96,98,182,63,130,100, +166,8,232,200,145,217,1,180,228,175,164,64,7,23,156,50,83,209,199,0,141,194,190,63,185,141,149,104,203,118,186,140,2,52,60,55,112,135,115,216,103,207,199,107,141,203,215,155,204,210,229,30,110,121,101,248,215,186,66,249,81,0,122,225,237,159,120,27,26, +172,123,21,221,183,146,31,255,39,8,11,235,212,143,4,168,109,252,177,183,63,130,200,22,1,133,42,86,7,164,74,4,28,47,108,186,112,213,44,40,52,104,21,123,95,119,196,1,27,251,30,34,158,63,207,74,180,101,57,113,122,14,172,61,238,61,13,207,41,216,225,13,5, +64,246,112,248,241,222,251,93,163,254,38,185,249,0,244,194,227,53,28,108,236,125,144,37,6,42,118,82,74,75,160,236,127,111,1,141,65,79,211,102,85,51,254,234,133,253,247,66,7,246,246,71,144,164,249,112,78,64,246,85,7,68,201,243,235,140,197,181,48,187,186, +72,209,247,125,185,111,61,171,196,162,145,88,153,15,111,224,4,46,122,224,161,238,155,163,193,44,159,165,140,2,64,30,33,79,52,114,240,225,238,155,5,61,47,123,245,71,224,116,96,9,154,152,26,85,18,237,202,37,80,114,243,255,133,120,56,172,124,127,0,85,179, +253,137,241,223,92,143,217,254,8,162,80,36,64,237,217,1,85,37,234,136,0,186,238,191,112,70,25,172,93,84,163,236,51,198,178,19,14,78,190,3,198,36,66,255,250,2,1,58,223,26,187,191,127,143,185,33,159,175,47,46,223,111,176,174,119,199,119,13,238,183,60,154, +204,82,0,189,16,15,78,188,3,135,205,219,21,221,183,130,235,174,132,130,207,95,11,113,175,95,97,207,95,205,108,255,122,92,243,71,16,213,68,128,10,203,1,103,38,34,1,17,5,69,64,84,138,65,101,177,1,46,88,53,83,209,99,65,19,254,94,234,253,43,240,156,0,114, +31,50,196,243,135,128,51,50,176,255,161,238,59,243,253,218,202,123,1,64,231,4,236,250,99,219,207,130,174,136,73,110,135,64,122,33,210,11,242,165,222,7,193,30,154,84,116,255,74,110,185,9,244,23,156,77,68,128,47,249,239,26,142,96,182,63,130,100,187,8,80, +169,58,160,154,137,128,228,151,28,69,98,252,11,244,90,248,228,105,115,192,160,19,20,61,14,47,244,62,0,142,176,5,4,141,252,124,2,173,129,131,3,15,119,255,208,59,25,244,160,0,64,192,57,226,183,29,125,170,255,182,100,162,0,244,130,116,69,108,240,108,207, +125,228,102,85,46,100,175,209,233,152,193,54,92,124,46,196,61,222,68,203,96,57,15,16,127,0,184,242,82,40,191,231,231,152,237,143,32,217,44,2,44,199,68,128,194,145,128,171,207,170,131,89,85,197,172,85,175,220,85,71,42,32,78,204,33,40,49,40,250,253,119, +140,189,202,50,255,141,124,161,124,227,111,228,97,172,193,241,124,235,107,195,175,227,21,133,2,224,4,77,47,14,189,96,106,116,188,170,77,162,77,48,109,16,212,108,61,192,134,82,40,137,166,168,16,202,239,190,3,138,190,245,101,58,64,27,226,129,224,73,231, +5,80,175,159,182,24,214,159,125,26,84,109,184,155,253,84,220,248,99,111,127,4,73,125,36,64,225,229,0,58,152,231,42,34,2,78,91,88,195,62,135,46,9,156,172,16,160,165,126,244,223,207,169,41,129,79,159,179,0,106,202,140,138,126,239,17,111,47,188,218,255, +40,155,199,34,219,216,241,26,136,134,36,203,174,123,219,111,141,199,240,90,66,1,240,1,196,136,4,59,255,208,254,3,49,28,179,201,95,10,0,208,243,70,216,50,248,4,12,120,58,148,221,65,65,128,226,255,190,17,42,30,188,11,244,231,158,145,16,2,62,63,107,29,204, +26,249,208,208,29,221,162,34,196,67,225,196,223,145,159,218,69,117,80,118,231,109,80,241,215,187,128,159,59,75,97,227,255,193,108,127,180,254,8,146,30,17,160,92,117,128,192,105,96,221,242,233,112,237,217,243,97,254,180,18,118,91,71,162,18,91,211,167, +70,62,22,63,182,145,223,211,80,63,53,250,244,239,202,139,12,112,241,234,217,112,245,153,117,172,230,95,73,232,152,223,167,187,255,0,33,41,192,202,254,228,66,27,191,29,121,162,255,86,75,151,123,2,175,162,99,231,27,15,193,223,49,119,186,70,143,60,217,255, +147,115,191,187,228,177,176,87,222,120,94,58,139,58,34,133,225,169,174,123,224,199,167,221,15,5,66,177,162,251,168,59,117,37,84,144,45,218,209,11,225,125,135,32,210,218,5,210,132,133,24,251,196,67,128,214,245,115,213,149,160,93,186,0,244,231,156,14,250, +211,87,179,164,63,165,57,145,237,143,97,127,4,73,179,8,104,133,191,93,191,10,102,148,232,21,123,255,233,21,5,100,155,7,118,34,46,134,45,94,152,116,248,193,19,136,48,99,79,195,2,28,17,10,116,157,191,178,212,0,115,170,139,97,54,217,120,78,157,7,193,43, +253,143,64,191,187,131,60,75,229,151,18,210,134,63,99,13,142,205,245,207,244,63,131,87,15,10,128,143,165,254,233,190,199,235,206,173,190,118,218,138,178,79,71,131,242,18,98,232,196,192,81,111,31,188,216,251,87,248,230,178,159,170,178,159,218,229,139, +216,198,30,6,212,227,103,229,130,84,0,8,160,41,44,80,245,24,97,111,127,4,201,188,72,128,210,34,128,66,215,241,19,107,249,213,44,2,112,188,92,144,227,64,209,129,62,31,7,173,172,218,49,246,10,24,5,249,235,254,26,94,3,98,72,180,236,252,67,219,247,164,40, +198,254,63,228,176,226,33,248,48,98,36,70,151,2,190,151,236,82,0,189,96,247,143,111,133,221,227,91,84,223,103,218,48,136,54,15,226,202,74,82,96,252,247,98,182,63,130,100,168,8,80,178,58,224,31,161,30,190,129,124,22,221,82,97,252,39,2,35,240,124,207,253, +228,115,181,178,187,253,49,135,172,64,128,195,79,244,221,98,233,118,143,225,21,131,2,224,223,98,238,112,141,29,121,178,239,7,218,130,100,2,36,26,208,242,122,216,216,251,144,242,249,0,105,34,145,237,143,97,127,4,201,88,17,160,112,117,64,186,8,75,33,120, +162,243,247,224,139,186,65,208,200,127,14,83,227,111,106,114,188,80,255,204,192,179,120,165,160,0,56,105,14,63,222,251,220,224,62,243,179,201,148,6,210,132,149,72,44,124,226,66,206,122,227,143,189,253,17,36,59,34,1,89,46,2,54,246,61,8,189,174,22,150, +84,45,219,184,9,28,157,244,55,186,237,174,150,31,96,232,31,5,192,212,110,40,114,71,237,250,99,251,15,66,158,232,16,29,25,41,91,129,114,122,48,249,6,225,233,238,123,21,237,15,144,90,227,191,151,213,249,99,216,31,65,178,41,18,16,202,202,239,177,119,252, +13,216,101,218,156,212,186,63,133,150,116,31,120,168,235,59,246,126,175,5,175,14,20,0,83,198,57,226,183,239,190,183,253,38,65,199,199,146,49,124,244,66,62,98,222,1,111,14,61,149,149,198,159,102,251,163,231,143,32,89,36,2,88,179,160,86,48,101,89,36,160, +207,221,198,146,167,169,227,148,204,186,191,190,88,11,29,111,142,221,215,242,202,200,91,120,85,160,0,144,13,185,136,182,117,189,99,250,189,190,40,185,81,150,116,94,192,235,131,79,66,131,117,79,118,121,254,88,234,135,32,89,43,2,254,227,229,86,176,248, +35,89,177,223,174,176,13,254,214,241,91,136,198,194,192,37,81,239,47,232,121,234,188,213,239,189,191,243,103,120,53,160,0,72,154,157,247,180,253,175,173,207,187,95,48,200,191,40,53,228,80,107,52,28,60,221,245,71,24,243,245,103,252,119,110,125,249,8,51, +254,186,2,236,240,135,32,217,40,2,138,136,8,104,157,244,192,247,183,116,64,40,195,39,222,70,99,17,120,188,243,183,96,14,140,129,150,147,95,202,168,225,52,180,121,145,111,251,111,91,190,225,183,133,130,120,37,160,0,72,154,144,39,26,125,239,215,205,223, +136,137,49,135,38,137,210,64,58,47,192,39,122,224,209,142,95,131,55,234,202,216,239,59,209,58,10,77,47,30,2,45,107,239,139,214,31,65,178,149,98,189,0,187,7,29,240,199,189,131,25,189,159,47,245,61,8,109,246,195,96,16,146,43,99,214,23,9,112,228,169,254, +91,70,14,219,218,240,236,163,0,80,208,40,58,251,14,61,214,251,93,93,65,114,189,147,244,156,1,70,125,253,240,183,142,223,129,20,23,51,238,123,74,17,17,234,159,218,199,166,36,106,56,52,254,8,146,11,34,224,241,250,49,104,24,207,204,225,119,219,70,55,178, +65,63,201,38,253,209,138,173,161,131,214,167,223,127,164,231,17,60,235,40,0,20,231,200,147,125,47,246,238,152,120,32,153,210,64,10,157,102,213,100,219,207,198,7,103,26,131,123,187,193,222,103,6,65,143,77,34,17,36,39,30,242,68,199,135,197,24,252,245,253, +225,140,219,183,102,242,28,220,212,191,158,56,70,201,37,253,241,90,14,124,214,80,251,123,119,181,96,183,63,20,0,234,64,39,72,189,123,103,243,143,236,3,190,131,201,228,3,48,17,64,212,238,182,177,77,240,222,232,75,153,243,253,164,24,244,110,107,7,142,231, +241,100,35,72,14,81,160,229,97,239,160,19,186,172,254,140,217,39,58,225,239,111,157,191,103,9,11,201,36,253,209,72,37,39,112,254,237,191,107,253,170,199,20,240,224,217,70,1,160,26,97,111,52,252,222,175,155,191,34,69,98,214,100,90,5,83,181,75,151,3,54, +245,173,135,122,235,238,140,248,110,206,17,59,56,134,108,192,235,208,251,71,144,92,139,2,248,34,34,108,235,179,101,196,254,56,66,22,88,223,254,75,8,136,94,16,184,228,42,172,104,68,246,224,134,238,239,13,236,49,55,226,153,70,1,160,58,19,173,206,129,125, +127,233,252,166,96,224,227,201,228,200,81,213,75,43,3,158,236,188,27,122,221,173,105,255,94,214,158,73,16,67,81,204,250,71,144,28,132,142,250,61,58,150,254,142,164,65,209,15,27,218,239,4,115,96,20,116,156,252,78,127,52,114,64,235,253,123,119,76,60,120, +232,241,222,39,240,12,163,0,72,25,77,47,13,189,217,242,202,240,255,232,146,236,15,64,251,92,211,190,215,27,218,126,201,134,95,164,19,247,152,3,79,44,130,228,176,0,24,243,132,210,90,18,72,19,159,105,185,31,109,243,107,224,11,18,86,92,38,218,2,30,108,253, +222,125,59,126,223,118,75,150,54,89,69,1,144,205,236,190,183,227,215,163,71,237,155,244,73,38,5,210,186,87,218,4,227,225,214,255,97,63,211,69,216,19,196,204,127,4,201,213,135,189,70,3,254,136,4,193,168,148,182,125,120,182,251,62,168,183,236,78,58,227, +159,23,56,136,248,37,211,187,191,108,250,178,223,22,10,227,217,69,1,144,114,196,176,4,239,252,162,233,91,238,137,96,179,160,79,230,80,198,217,208,11,147,127,16,30,110,251,5,4,68,95,90,190,79,28,147,103,17,36,167,137,39,229,115,39,199,171,3,143,192,110, +211,102,40,16,138,146,122,31,186,236,202,235,184,200,206,63,180,253,159,201,118,215,40,158,85,20,0,105,195,51,17,112,191,251,171,230,47,74,209,184,45,153,161,65,20,26,18,163,161,177,71,219,127,197,166,8,166,26,193,40,64,60,142,177,52,4,201,73,227,31, +167,209,70,13,232,210,16,229,123,103,228,69,120,115,232,25,48,36,233,249,179,231,100,137,142,54,251,249,126,231,91,99,187,241,172,162,0,72,59,163,71,108,93,251,254,210,249,53,94,203,75,201,54,206,163,161,177,38,219,1,54,66,56,22,79,109,168,174,168,166, +20,112,45,13,65,114,19,137,40,128,234,66,29,20,166,184,199,199,158,241,55,224,229,190,135,137,240,48,36,85,235,207,140,63,29,242,179,117,236,190,131,235,187,215,227,25,69,1,144,49,52,189,52,180,181,225,249,129,155,13,165,186,164,223,139,134,200,222,159, +124,15,158,233,254,19,164,210,34,87,45,172,5,13,143,151,4,130,228,34,81,41,6,43,107,139,83,90,228,115,216,188,13,158,35,207,49,158,211,2,167,73,238,217,66,199,251,78,116,184,222,216,241,251,214,219,176,217,15,10,128,140,99,223,95,187,30,104,127,125,244, +207,180,31,181,18,34,128,206,196,166,163,49,83,69,245,226,90,40,170,46,134,152,136,55,23,130,228,26,60,199,193,69,11,42,83,246,121,116,242,233,19,93,247,176,82,103,94,147,92,115,49,58,225,47,232,138,180,188,249,211,250,175,134,220,105,204,98,68,1,128, +124,28,49,162,74,183,255,182,245,150,201,118,215,230,100,103,6,80,232,114,192,187,35,47,178,65,25,169,128,142,253,157,123,206,66,16,195,81,60,153,8,146,67,208,210,191,101,213,133,112,206,156,178,148,124,30,29,236,243,88,199,93,16,139,199,136,241,79,238, +89,72,219,252,70,2,226,196,27,63,173,191,222,109,10,184,240,108,162,0,200,88,200,133,26,219,114,219,209,175,186,70,253,135,105,200,42,25,232,122,25,77,154,121,103,248,5,216,60,240,120,74,246,127,233,149,171,193,88,94,8,49,9,163,0,8,146,51,207,37,114, +63,127,235,204,217,228,121,162,254,35,191,205,113,24,214,183,255,2,164,152,200,250,156,36,245,12,228,52,52,227,63,176,231,190,142,207,155,26,29,125,120,38,81,0,100,60,62,107,200,251,206,157,205,55,132,189,209,1,170,94,147,23,1,5,176,101,240,137,148,136, +128,194,234,98,88,245,185,51,18,29,1,17,4,201,122,188,97,9,46,93,88,5,215,173,168,77,137,231,191,190,245,23,16,149,34,73,183,248,165,9,213,196,137,138,239,188,167,237,27,237,175,143,238,195,51,137,2,32,107,24,111,118,140,190,241,211,250,235,136,253,182, +39,51,51,224,67,34,96,40,53,34,96,217,149,171,97,193,249,75,33,226,199,254,26,8,146,173,208,167,78,32,42,193,156,50,3,220,117,217,98,224,53,234,166,255,29,247,252,163,177,228,141,63,133,182,249,109,121,121,248,135,77,47,13,109,196,179,137,2,32,235,24, +61,106,111,222,125,111,251,231,121,29,31,212,40,33,2,248,2,120,125,232,73,216,212,247,176,202,79,14,13,156,253,159,151,192,172,181,117,40,2,16,36,75,241,19,227,95,83,168,131,245,159,89,9,179,74,13,42,123,254,135,96,125,219,47,21,241,252,41,116,192,15, +49,254,119,237,184,187,237,126,60,147,40,0,178,150,230,77,195,59,118,254,161,237,27,188,150,139,37,219,102,151,77,16,228,141,176,117,248,89,213,171,3,180,70,45,92,248,163,79,193,194,139,150,65,36,16,134,120,12,27,4,32,72,182,64,195,254,75,170,10,225, +169,207,175,134,85,211,139,85,253,44,154,237,255,80,219,255,18,207,63,172,152,231,63,124,200,246,200,182,187,90,254,31,62,119,80,0,100,191,8,216,56,244,82,253,51,3,223,165,77,44,146,45,194,61,158,24,248,238,200,11,240,116,247,31,33,14,234,37,235,9,6, +45,124,226,7,151,195,25,95,63,143,117,8,148,34,88,125,131,32,153,76,140,220,167,158,176,8,87,47,173,134,23,190,116,42,44,175,41,82,245,243,14,153,183,193,163,29,191,97,67,126,4,141,50,158,255,120,179,99,211,219,255,211,248,159,216,148,20,5,64,206,176, +255,161,174,245,205,155,134,126,202,68,64,146,28,23,1,187,198,94,131,199,59,126,11,98,44,162,234,190,175,248,204,90,184,248,167,215,64,65,101,17,68,131,17,60,153,8,146,97,80,191,34,44,198,128,22,239,220,126,193,2,88,255,217,149,80,89,160,85,245,51,247, +140,191,14,127,235,248,29,113,14,98,202,24,255,2,129,142,90,127,119,243,173,71,190,22,112,132,209,219,64,1,144,59,196,165,56,108,187,171,245,247,45,47,15,255,198,80,162,76,36,192,40,20,193,254,137,183,217,218,91,72,10,168,186,255,51,214,204,129,203,127, +117,253,137,188,0,12,205,33,72,230,224,33,246,114,122,137,30,30,189,254,20,248,239,117,115,85,255,188,119,70,94,128,103,186,238,101,221,253,146,173,243,63,110,252,29,67,190,3,91,110,61,250,185,160,51,18,196,51,138,2,32,247,68,64,156,137,128,59,90,94, +25,254,179,18,141,130,40,180,99,96,131,117,47,252,165,229,103,224,137,56,84,221,127,218,37,240,226,219,175,129,83,191,116,14,19,0,82,68,196,147,138,32,105,68,138,197,153,241,191,124,113,21,108,250,242,169,112,209,252,10,213,63,243,149,129,71,96,99,223, +67,32,112,58,34,0,248,164,223,143,118,249,11,56,195,245,239,252,162,233,51,228,167,7,207,42,10,128,220,22,1,191,105,249,225,240,251,214,13,74,44,7,80,104,199,192,46,103,35,252,169,249,199,96,14,142,169,186,255,52,145,113,245,23,206,34,66,224,106,40,174, +45,133,72,0,151,4,16,36,29,4,163,49,208,104,52,240,255,46,156,15,143,17,207,127,70,137,186,153,254,116,157,255,169,174,63,192,27,131,79,177,100,228,100,123,251,31,55,254,33,79,164,117,243,173,71,62,61,217,225,178,226,89,69,1,144,7,34,0,224,237,255,109, +250,142,169,217,241,152,174,72,153,72,0,45,17,28,245,246,193,125,141,183,193,160,167,83,245,239,48,99,205,92,184,252,215,55,192,130,243,151,64,52,24,197,249,1,8,146,194,231,7,77,244,91,82,93,8,207,124,97,53,252,215,57,115,85,31,240,19,20,125,240,112, +219,47,216,124,18,26,117,212,40,240,137,204,248,187,35,237,196,248,127,106,178,205,101,194,51,139,2,32,111,8,56,194,113,114,225,127,107,162,197,249,24,205,124,85,74,4,216,195,22,248,115,243,79,160,217,118,64,245,239,96,44,43,128,243,110,190,2,214,125, +247,18,208,21,234,48,65,16,65,84,38,44,197,32,68,182,111,172,157,197,66,254,103,206,42,85,253,51,237,33,51,121,166,252,20,26,44,187,153,241,87,130,99,158,127,223,230,219,142,92,75,140,255,24,158,89,20,0,121,71,208,25,1,34,2,110,154,104,117,62,166,47, +82,98,57,32,14,58,78,15,33,49,192,212,250,110,211,150,148,124,143,69,151,174,128,203,127,117,3,204,60,117,30,68,3,17,156,35,128,32,74,123,253,64,107,251,69,152,81,108,128,245,159,89,193,58,251,149,24,4,213,63,119,216,219,13,127,106,186,21,250,220,173, +44,233,88,17,227,111,96,158,127,31,121,246,93,73,140,255,0,158,93,20,0,249,44,2,226,91,110,61,122,211,120,139,67,33,17,0,172,25,7,13,208,61,211,125,47,188,220,191,158,60,60,212,207,216,47,157,89,14,151,222,241,105,56,227,155,231,131,160,19,216,178,0, +130,32,201,67,7,249,208,245,254,207,175,154,14,175,126,229,52,184,98,113,117,74,62,183,201,182,15,238,107,250,17,88,130,38,48,240,133,202,121,254,238,72,219,230,219,142,94,65,140,63,14,247,65,1,128,4,156,97,34,2,142,220,52,214,104,87,44,39,128,102,231, +234,120,3,188,53,244,12,108,104,187,19,2,162,79,253,47,66,84,199,242,107,79,133,203,239,188,30,102,174,153,131,209,0,4,73,198,235,143,39,188,254,233,197,122,248,235,181,203,225,79,87,45,131,154,34,93,74,62,251,189,209,151,224,225,182,95,66,80,12,128, +142,51,28,139,65,40,96,252,19,9,127,196,243,119,246,227,25,70,1,128,156,16,1,145,248,43,223,123,255,91,109,175,141,254,89,169,234,128,227,189,2,14,155,183,49,37,111,14,140,166,228,187,148,207,171,130,75,127,254,105,56,235,166,11,65,87,160,99,66,0,176, +109,0,130,156,52,33,49,198,214,251,255,207,154,153,240,234,87,215,194,53,203,106,82,242,185,98,44,10,207,246,252,137,181,26,231,200,243,67,137,214,190,20,109,129,64,141,255,209,99,9,127,184,230,143,2,0,249,167,155,47,28,131,109,191,105,254,97,203,43, +195,191,99,205,130,20,130,138,0,90,25,240,135,198,91,216,208,142,148,160,209,192,210,79,173,134,43,126,243,57,152,119,238,98,16,35,81,144,162,216,220,11,65,254,21,137,186,126,17,22,87,21,178,210,190,187,175,92,194,6,250,164,2,71,216,10,247,55,255,20, +182,143,190,114,172,204,143,87,228,125,89,147,159,65,239,62,52,254,40,0,144,127,3,13,251,189,119,87,203,237,68,4,252,92,137,217,1,199,161,55,52,109,20,244,215,214,59,88,120,47,85,148,76,47,131,11,110,187,18,46,184,229,74,40,158,86,138,93,4,17,228,163, +238,123,178,249,35,18,104,121,14,110,62,183,14,94,249,202,105,112,201,130,202,148,125,126,175,171,5,254,216,120,51,116,56,143,42,86,230,199,140,127,161,0,19,109,206,119,55,126,231,224,213,196,248,99,157,127,134,33,224,33,200,204,167,193,182,223,180,252, +154,136,1,247,170,235,230,222,31,241,139,138,24,77,45,167,131,88,92,130,23,122,255,2,38,223,32,124,113,209,247,216,76,129,84,48,119,221,34,152,182,106,54,180,191,90,15,93,239,180,178,101,1,58,113,16,65,242,29,218,195,95,36,55,251,165,11,171,224,182,243, +234,96,69,109,81,74,63,159,86,11,209,206,126,116,154,31,45,37,86,10,58,213,143,14,246,161,189,253,177,189,47,10,0,100,138,145,0,34,2,30,112,12,120,29,231,255,112,249,99,98,36,166,167,243,4,146,133,134,245,140,124,33,236,25,127,3,76,254,65,248,198,178, +31,195,204,194,249,41,249,78,250,34,3,156,246,213,115,97,238,185,139,160,249,133,67,48,86,63,200,58,11,242,58,188,12,145,252,67,36,162,62,16,149,88,67,159,31,174,171,131,79,47,175,73,233,231,135,165,32,188,212,247,32,19,0,90,78,207,54,69,208,36,194,254, +195,7,45,27,182,254,188,233,187,196,248,227,218,95,134,130,75,0,25,78,195,243,131,207,238,252,67,251,117,130,158,119,241,130,114,167,139,134,249,134,60,93,240,199,134,155,225,176,121,123,74,191,83,229,252,26,184,248,103,215,192,249,183,94,9,101,179,43, +33,26,8,99,39,65,36,111,136,29,203,238,47,212,241,240,163,243,231,195,230,175,174,77,185,241,31,39,226,255,222,166,219,96,231,216,107,108,121,144,87,104,189,95,67,140,63,93,186,108,123,109,228,174,87,126,112,248,219,1,39,78,245,195,8,0,146,20,205,27, +135,222,242,154,131,87,92,118,199,234,141,250,18,237,108,49,164,204,61,69,111,252,160,228,135,71,219,127,13,3,158,78,184,126,193,77,202,121,1,39,193,188,117,139,96,214,105,243,160,251,237,22,232,120,179,9,2,54,47,8,6,29,139,10,32,72,174,65,227,119,1, +226,12,235,137,144,255,194,170,25,108,106,95,93,185,49,229,251,241,190,249,61,120,177,231,175,224,139,186,20,235,236,199,140,63,185,111,181,70,62,222,180,113,248,230,29,191,107,249,115,28,83,125,80,0,32,202,48,176,199,124,232,245,159,28,189,232,83,191, +62,109,83,97,165,126,77,84,33,17,192,107,180,192,241,2,188,59,242,34,235,250,245,149,197,55,195,204,162,249,169,187,0,13,90,88,241,153,181,48,239,19,139,161,227,245,70,232,219,209,1,17,95,24,4,163,150,13,58,65,144,92,128,54,242,161,92,180,160,18,254, +251,156,185,112,70,10,90,248,254,35,52,228,255,114,255,6,230,245,243,156,192,28,0,165,224,181,28,221,252,59,239,105,187,177,233,165,161,151,240,140,103,7,184,4,144,69,152,26,29,253,47,126,107,255,165,214,94,207,219,74,150,9,210,140,95,234,9,244,185,90, +225,15,141,55,195,190,137,183,82,254,221,10,171,138,89,23,193,43,127,243,57,88,120,209,50,230,46,177,110,130,232,70,32,89,12,173,231,167,217,253,167,205,44,129,71,174,91,9,79,125,110,85,90,140,255,144,183,139,221,219,219,70,55,129,142,215,131,160,81, +206,247,163,13,126,196,144,100,122,239,55,205,87,162,241,71,1,128,168,136,103,34,104,223,124,203,145,79,15,236,53,111,160,173,131,149,116,146,169,71,16,146,2,240,68,231,221,240,120,231,111,193,27,117,165,252,251,149,205,169,132,115,191,127,25,92,246, +203,235,96,238,217,11,32,38,197,201,195,37,138,141,132,144,172,130,102,246,123,195,18,44,175,41,130,63,95,179,140,13,238,185,108,81,85,90,246,133,26,253,123,27,111,133,33,79,183,162,37,126,20,173,129,117,247,107,220,114,219,145,139,219,54,143,238,197, +51,159,93,224,18,64,22,226,179,134,34,175,221,114,228,219,151,252,244,148,193,149,215,206,249,173,68,60,140,152,164,140,133,228,137,103,192,243,60,236,31,223,10,3,238,14,248,226,162,255,134,149,149,103,166,252,59,86,47,158,6,23,254,248,42,48,119,152, +160,125,115,3,152,26,135,89,91,97,173,94,0,192,165,1,36,131,61,126,154,221,79,13,255,55,215,206,130,235,86,214,18,97,157,30,63,203,30,154,132,23,123,255,2,245,214,61,172,157,175,158,55,40,250,254,180,204,207,220,238,218,242,214,29,13,223,112,142,248, +157,120,246,81,0,32,41,130,150,4,110,251,77,203,239,156,195,190,254,79,252,215,178,71,52,92,188,84,138,42,149,73,79,91,8,23,130,53,56,14,127,105,253,25,92,50,235,122,184,182,238,27,138,174,25,158,44,181,203,103,178,109,178,109,12,58,223,106,6,83,195, +16,72,145,40,8,122,45,38,11,34,25,101,248,105,23,191,149,211,138,225,171,167,206,128,207,46,159,6,70,109,250,2,172,135,204,219,96,83,223,122,112,134,45,172,236,87,73,88,166,127,137,14,58,182,142,221,183,235,158,182,219,2,88,230,135,2,0,73,15,245,207, +12,108,116,12,250,6,47,251,249,234,103,140,101,186,37,74,37,7,82,104,227,160,56,196,224,237,225,231,160,203,217,0,95,88,244,61,88,92,182,58,45,223,115,218,202,89,108,51,119,142,67,247,214,102,24,171,31,98,205,132,4,131,64,132,0,174,100,33,105,16,225, +113,128,160,152,184,223,78,155,81,202,12,63,237,217,175,227,211,119,61,186,194,54,120,165,127,3,28,156,124,143,149,246,41,217,216,135,194,9,28,240,58,46,124,232,241,222,31,238,251,107,215,195,216,213,19,5,0,146,102,6,247,91,142,190,120,211,129,11,174, +249,253,218,191,85,47,41,189,50,236,83,110,205,92,3,28,155,37,48,234,235,131,63,55,255,24,46,153,117,3,92,53,239,43,105,137,6,176,136,192,178,25,108,115,12,88,161,251,221,86,24,121,191,31,130,110,63,8,58,45,123,56,33,136,218,72,196,242,211,172,126,26, +218,63,191,174,2,190,186,102,38,92,186,176,18,248,52,71,164,14,91,118,192,43,125,27,88,228,206,32,20,40,186,214,207,28,2,35,15,17,191,56,178,253,119,45,223,232,120,99,108,39,94,9,40,0,144,12,193,53,234,55,111,250,238,251,215,92,120,219,138,223,45,189, +124,230,109,180,87,128,82,121,1,20,186,134,24,139,199,224,141,161,167,160,221,113,4,110,88,248,29,88,86,126,90,218,190,111,197,252,106,56,231,59,23,195,202,207,172,133,254,157,157,48,176,183,27,188,19,174,132,135,162,21,0,112,117,0,81,152,40,185,159, +66,196,227,47,51,106,225,138,197,213,240,21,98,248,207,154,93,154,246,253,114,132,204,196,235,127,4,14,89,182,3,79,126,25,85,104,239,77,215,251,109,253,222,221,219,126,221,252,245,241,22,231,48,94,13,40,0,144,12,35,232,138,72,91,239,104,252,145,189,207, +219,124,246,77,139,255,194,243,154,82,41,162,92,135,61,78,195,177,44,226,68,52,224,39,112,193,204,107,224,154,121,95,131,34,109,89,218,190,51,29,48,180,230,75,103,195,242,107,214,192,208,129,94,38,6,108,125,22,34,126,36,204,19,64,146,134,134,249,143, +175,239,207,45,55,192,213,75,107,224,115,167,76,135,133,149,5,25,177,127,123,199,223,132,45,131,79,48,17,160,134,215,79,239,31,218,214,183,111,231,228,95,119,220,221,122,171,207,18,10,227,85,129,2,0,201,96,14,63,209,247,140,109,192,219,126,233,237,171, +254,86,88,165,95,77,135,9,41,137,142,211,179,220,128,109,35,155,160,221,126,24,62,61,255,70,56,163,230,226,180,126,103,93,145,1,22,95,118,10,44,186,116,37,76,180,140,66,255,174,78,24,111,26,134,144,59,8,156,150,248,69,90,62,63,47,6,77,90,94,154,245,208, +76,254,96,84,34,70,149,103,117,251,55,172,156,198,188,254,50,99,102,60,50,169,8,127,149,120,253,45,246,247,65,224,116,170,120,253,188,142,3,142,215,120,15,172,239,254,225,161,199,122,30,143,99,183,110,20,0,72,118,48,176,199,220,184,113,232,192,5,151, +220,190,234,254,57,103,86,125,77,169,137,130,127,55,14,28,123,232,216,130,19,176,161,237,78,56,90,189,11,62,51,255,63,96,122,225,220,244,218,59,226,177,204,88,51,135,109,222,73,55,139,10,12,147,205,57,108,99,101,132,130,78,0,13,159,39,185,2,196,125,165, +3,152,228,82,162,23,242,170,226,146,222,30,97,81,2,186,114,54,163,88,15,151,18,79,255,51,43,106,225,204,89,165,25,179,143,180,79,199,59,35,47,192,246,209,151,33,32,250,20,79,242,59,33,168,11,5,32,222,126,203,206,63,180,221,72,188,255,122,124,162,162, +0,64,178,12,231,136,223,253,234,15,14,125,125,221,119,150,28,90,251,229,249,247,196,98,241,2,37,151,4,216,5,68,188,15,1,226,80,111,221,13,93,174,70,184,116,246,13,240,201,217,159,83,237,193,52,21,232,242,192,41,215,157,14,43,174,61,149,69,5,134,246,245, +194,120,243,48,4,28,126,34,2,52,44,87,32,167,151,8,136,33,43,154,38,223,120,213,18,35,104,16,56,22,6,207,85,33,64,37,113,68,140,65,132,136,195,34,34,120,214,205,45,135,107,151,213,178,164,190,234,66,93,70,237,107,3,185,199,104,184,127,212,219,199,146, +112,213,184,199,232,253,160,47,18,96,232,160,245,201,237,191,107,253,129,107,212,239,198,39,41,10,0,36,75,161,6,127,239,253,157,15,78,182,187,234,47,188,121,197,250,162,90,131,226,75,2,52,30,64,31,70,81,41,12,175,245,63,10,245,150,221,112,205,188,175, +195,218,154,11,50,226,24,112,2,15,51,79,155,199,182,128,221,199,74,8,135,15,246,129,173,119,18,34,254,48,75,28,164,203,4,185,54,123,128,126,167,202,186,106,217,175,159,87,110,132,154,34,61,76,120,195,160,205,161,99,67,141,62,77,232,163,222,190,142,156, +251,197,213,133,240,201,133,85,112,229,146,106,88,81,83,148,113,251,59,234,235,135,215,137,225,111,178,238,35,215,104,162,42,71,13,88,200,159,211,120,15,61,222,123,219,193,13,61,27,148,118,22,16,20,0,72,154,232,221,62,113,104,178,205,121,254,197,63,57, +229,158,5,23,76,251,191,209,128,168,104,149,0,51,56,26,158,61,156,38,252,195,240,112,251,47,96,213,228,57,44,73,112,94,201,210,140,57,14,5,149,69,176,248,178,149,108,115,141,218,97,244,200,32,17,4,131,172,172,48,26,140,228,140,24,160,227,149,139,170, +139,161,124,158,124,1,80,164,227,225,212,233,37,48,228,52,131,86,151,221,57,20,39,140,62,237,38,73,188,220,185,101,70,184,96,126,5,92,177,168,10,78,159,85,154,214,218,253,143,195,19,113,194,123,163,47,193,110,211,150,99,225,126,35,168,149,153,65,179, +252,157,35,190,195,59,239,110,251,54,241,254,155,240,137,137,2,0,201,49,188,230,144,103,243,45,71,190,125,214,127,44,218,117,198,215,23,222,167,53,242,53,209,160,242,77,188,104,3,33,250,200,109,182,237,135,110,103,3,172,155,126,37,92,62,231,139,80,105, +168,205,168,227,81,54,187,146,109,116,153,192,222,111,97,93,6,105,203,97,154,47,64,155,12,209,92,1,154,60,152,141,203,4,98,88,132,89,107,235,64,107,76,110,104,20,157,83,255,90,135,57,59,141,62,177,250,52,180,79,55,106,224,231,150,27,97,221,156,114,214, +147,159,26,253,162,12,21,53,98,44,10,123,39,222,100,19,58,45,1,147,106,225,126,38,218,137,224,165,253,252,59,223,28,187,119,239,3,157,63,247,89,67,1,124,82,162,0,64,114,152,67,143,245,62,63,114,216,118,248,194,91,87,60,48,99,85,249,149,97,175,72,30,150, +74,119,244,74,44,11,208,222,1,52,97,169,193,178,7,46,158,245,89,184,112,214,103,20,157,65,174,20,149,11,106,216,182,234,115,103,130,99,200,6,19,45,35,48,78,196,128,99,208,10,33,79,144,125,31,42,6,56,234,41,102,184,30,160,201,158,250,34,61,44,190,252, +148,164,223,235,130,186,10,56,117,70,9,52,79,120,192,152,5,149,20,180,92,143,122,249,244,103,161,78,128,165,53,69,112,238,220,114,184,136,120,251,107,166,151,144,63,203,236,239,208,96,221,3,91,135,159,99,115,56,180,42,101,247,31,135,150,247,5,221,145, +161,189,127,238,248,126,211,198,161,215,241,201,152,127,104,226,105,26,183,26,137,68,96,201,146,37,48,52,52,132,103,33,77,208,100,159,117,223,89,114,203,170,235,230,253,138,78,4,22,195,234,181,244,150,226,34,241,196,194,48,163,112,46,92,58,251,115,176, +110,250,229,228,1,167,207,130,168,137,27,44,29,227,48,78,4,129,173,199,12,126,155,7,232,240,37,22,29,32,222,83,38,86,20,68,124,97,88,249,217,181,112,250,55,206,83,228,253,118,15,58,224,107,27,91,88,231,187,76,11,134,196,200,243,139,134,246,169,151,79, +59,241,85,21,232,96,101,109,17,75,230,163,134,159,10,0,109,22,68,112,104,171,109,106,248,59,28,245,108,249,73,167,226,189,193,241,26,208,18,227,111,106,180,63,183,243,158,182,91,45,221,158,73,124,26,166,143,13,27,54,192,77,55,221,132,2,0,73,15,243,214, +213,156,122,254,15,150,61,80,181,176,228,220,136,79,141,104,192,223,161,225,205,104,60,2,243,138,151,194,101,115,62,199,250,7,208,220,129,108,128,46,11,56,134,172,108,48,17,157,73,224,26,177,179,62,3,113,98,124,50,69,16,68,67,81,150,248,119,217,157,215, +17,15,79,57,35,242,203,237,125,240,208,161,17,40,51,164,55,104,120,220,224,71,143,149,180,210,82,197,186,10,35,235,197,127,206,156,50,22,173,152,94,172,207,154,123,143,122,250,239,142,190,8,77,214,253,76,36,39,38,246,169,39,88,104,59,223,104,72,154,60, +250,84,255,79,142,60,217,255,20,205,21,65,80,0,160,0,200,247,104,64,177,86,183,238,255,46,254,241,170,235,231,254,140,184,32,70,53,163,1,204,80,197,194,108,121,96,126,233,10,184,116,246,245,176,182,250,66,214,105,48,155,160,21,5,116,137,128,138,1,123, +159,25,220,99,78,8,121,2,32,145,135,42,71,188,78,238,152,32,72,85,66,161,72,140,127,97,117,49,92,122,199,167,161,116,86,133,178,247,43,17,57,255,181,185,3,222,232,178,64,105,138,68,0,125,52,73,199,12,190,24,35,199,148,28,71,250,217,115,202,140,112,202, +180,98,214,160,135,134,245,235,202,141,105,239,195,63,85,70,188,61,196,240,191,196,150,198,34,228,94,160,235,252,26,21,13,255,9,175,191,193,254,202,238,251,58,110,157,108,119,225,131,23,5,0,10,0,228,159,162,1,167,159,255,253,101,127,172,90,84,114,190, +210,205,131,62,242,58,32,15,191,248,9,33,112,3,17,2,231,103,77,68,224,159,4,129,195,207,162,2,54,34,6,236,3,22,112,143,58,200,159,249,152,87,78,187,204,208,222,3,52,135,128,78,47,84,52,177,144,38,187,5,195,80,54,171,18,46,184,237,83,80,62,183,82,149, +239,71,59,227,221,250,86,23,188,218,110,102,9,116,74,26,221,227,198,158,118,224,163,27,253,127,131,150,131,170,2,45,204,43,47,96,97,125,234,221,175,168,45,134,57,165,134,172,51,248,31,52,252,219,198,18,57,49,180,169,143,218,134,63,225,245,11,228,26,20, +39,234,159,238,255,201,225,39,250,159,70,175,31,5,0,10,0,228,95,69,3,248,117,223,94,124,243,170,235,230,222,65,172,113,169,24,82,127,220,247,7,133,0,77,22,92,91,125,1,8,156,54,171,143,35,245,200,125,22,15,56,137,40,160,101,134,180,236,144,118,39,12,186, +252,16,13,70,217,210,1,125,246,127,80,20,76,73,24,144,91,87,140,136,204,122,206,57,123,33,156,245,173,11,192,88,94,168,234,119,162,79,139,251,15,12,195,67,135,134,193,75,174,139,2,29,7,252,20,34,28,84,79,210,48,190,116,204,208,211,223,83,207,222,72,140, +125,185,81,203,188,251,69,149,133,176,172,166,136,108,133,196,187,47,128,202,2,109,214,223,83,253,158,118,150,12,219,98,59,64,12,127,16,244,156,129,213,244,171,9,39,104,64,208,243,96,106,114,60,179,231,79,29,183,79,118,184,198,240,233,134,2,0,5,0,114, +82,204,60,181,114,217,39,190,183,244,247,51,215,84,92,163,70,223,128,143,19,2,177,184,4,115,139,23,195,5,51,175,101,57,2,106,102,66,167,26,26,13,8,218,125,224,153,116,129,107,196,1,158,113,39,75,52,164,203,9,33,111,8,196,96,132,181,44,102,150,86,147, +16,4,116,57,225,120,43,62,122,191,198,99,177,19,109,141,171,22,77,131,101,87,175,129,185,68,0,164,146,118,179,15,30,62,60,2,59,251,137,184,33,98,134,138,0,129,238,43,221,79,77,66,41,80,143,254,184,177,167,80,175,157,86,18,148,234,5,214,101,112,22,241, +228,23,84,20,16,131,95,0,117,228,231,172,18,3,84,228,128,177,255,32,29,142,163,176,211,244,26,155,153,145,8,245,27,88,27,109,117,159,234,199,50,252,157,145,158,131,143,244,252,164,245,149,225,215,82,113,239,34,40,0,80,0,228,24,212,131,56,253,107,11,190, +118,218,151,234,238,212,23,107,231,70,2,98,194,56,169,109,40,99,17,98,64,162,48,173,96,46,156,59,253,74,56,103,218,101,80,166,175,202,217,227,28,9,132,33,228,10,130,223,230,5,159,213,3,126,139,135,252,244,38,132,129,39,200,234,250,169,93,229,137,241, +44,172,44,130,202,133,181,48,99,205,92,168,89,58,61,173,251,61,224,8,176,42,129,35,99,110,24,38,251,239,9,137,236,242,160,98,128,122,244,53,133,58,152,73,12,253,76,98,220,231,150,25,96,6,249,89,91,164,135,10,242,119,185,218,94,152,94,187,180,107,223, +238,241,215,161,215,213,66,174,99,233,152,225,215,164,228,126,229,120,77,164,115,171,233,254,131,27,186,239,114,155,2,78,124,138,161,0,64,1,128,36,69,213,130,226,234,115,190,189,248,127,23,92,56,253,59,113,41,198,139,225,212,172,35,178,170,1,242,64,45, +55,84,195,233,53,23,50,49,48,187,104,97,94,29,123,41,34,130,36,74,204,124,112,90,33,99,39,27,82,143,63,16,137,17,1,16,103,17,129,66,93,126,77,96,244,68,28,112,200,188,29,14,78,190,195,250,245,83,131,175,229,245,41,49,252,199,147,252,172,61,158,157,196, +240,255,180,111,231,228,97,124,106,161,0,64,1,128,40,202,162,139,167,175,35,66,224,174,170,5,37,23,68,137,183,23,19,83,115,253,80,47,42,34,133,216,114,192,242,138,51,224,19,68,8,172,168,60,131,24,26,236,101,133,164,23,58,154,247,224,196,59,112,212,178, +27,236,161,73,150,187,146,232,134,153,138,39,120,34,220,31,114,71,71,27,95,28,252,101,195,115,3,143,71,252,34,198,251,81,0,156,20,248,244,68,166,68,239,142,137,3,195,135,172,23,157,254,149,5,223,92,117,195,220,255,49,150,233,230,210,118,194,106,87,11, +240,108,206,64,33,241,45,99,208,104,221,3,77,182,125,48,167,104,17,156,53,237,18,86,66,88,97,168,193,147,131,164,206,129,33,98,180,213,126,136,121,251,93,206,70,8,138,126,208,17,111,63,149,249,42,130,129,167,249,33,225,222,237,19,15,30,220,208,243,59, +251,128,215,130,103,6,65,1,128,168,251,240,35,30,198,129,245,221,143,183,191,62,186,101,221,119,150,220,182,240,226,105,223,19,244,124,161,26,115,5,254,217,225,225,88,233,212,113,207,107,176,167,19,222,30,126,1,78,169,60,155,136,129,75,97,113,217,106, +38,22,16,68,13,198,253,67,112,196,178,19,26,136,183,63,238,31,6,154,16,147,106,195,79,167,246,209,181,254,137,22,199,235,71,158,232,255,69,223,238,201,6,60,51,136,172,231,41,46,1,32,201,50,235,180,202,229,68,8,252,124,198,234,138,47,210,210,54,49,197, +99,68,105,213,0,205,176,22,52,2,204,46,94,8,107,107,46,132,211,170,206,131,154,130,89,120,114,144,164,241,139,94,104,35,222,254,17,243,14,232,113,53,131,63,234,101,33,254,84,151,169,210,178,62,26,238,183,15,250,26,27,95,24,252,69,251,150,145,45,169,202, +197,65,212,3,115,0,144,156,96,197,53,179,47,62,253,107,11,126,94,89,87,124,33,237,36,40,69,83,251,112,162,201,103,52,105,144,110,197,186,82,88,84,182,10,78,175,185,8,150,87,156,14,197,218,50,60,65,200,73,35,198,69,232,119,181,194,81,235,110,102,252,173, +193,9,150,202,71,123,244,107,82,220,177,146,150,130,234,10,120,240,217,194,67,29,111,140,221,93,255,108,255,99,65,39,121,128,34,40,0,146,4,151,0,16,197,104,127,125,116,71,239,246,137,29,203,175,154,245,185,83,191,84,119,123,197,188,162,83,105,217,96, +170,18,5,89,214,53,241,204,232,22,145,34,172,191,122,163,117,31,27,67,76,69,192,169,213,231,193,162,210,85,57,213,87,0,81,86,64,14,123,186,161,201,182,31,90,236,239,195,184,111,144,85,160,208,16,191,225,216,178,83,170,13,63,235,221,31,148,108,29,111, +154,30,56,248,72,207,95,220,99,126,7,158,41,4,5,0,146,145,80,131,223,180,113,104,99,207,246,137,45,167,125,185,238,235,203,175,158,125,107,81,181,97,113,52,152,58,33,64,161,115,5,142,231,10,120,34,78,216,59,254,38,236,159,120,27,170,13,51,136,24,88,11, +171,170,214,193,162,178,83,84,155,179,142,100,7,116,30,133,201,63,0,45,182,131,208,74,140,254,136,183,15,194,82,144,133,247,143,111,169,183,252,0,58,214,190,87,242,118,110,29,219,208,248,252,224,159,205,157,238,81,60,91,136,226,151,26,46,1,32,106,82, +60,205,88,188,250,250,185,55,18,33,240,125,34,4,230,167,178,116,240,163,160,161,93,81,138,0,199,241,80,99,156,1,139,203,214,192,41,149,103,193,66,34,6,112,153,32,63,160,94,253,136,183,151,133,246,219,29,71,136,0,24,132,144,24,32,198,94,32,155,46,37,117, +251,31,103,248,181,6,158,118,125,12,14,236,49,63,121,232,177,158,123,137,225,239,197,51,150,219,96,14,0,146,15,66,160,116,245,13,243,190,189,226,234,89,223,45,172,50,204,77,183,16,56,33,6,136,49,160,149,5,21,134,106,168,43,89,14,43,42,78,103,162,160, +22,19,8,115,10,111,196,5,3,158,14,98,240,15,179,68,62,115,96,12,34,82,248,132,151,159,54,163,15,137,80,63,45,233,131,88,60,56,86,111,127,166,254,249,193,251,6,247,153,59,240,172,161,0,64,1,128,228,154,16,40,95,125,253,220,175,46,191,102,246,127,23,85, +27,22,166,122,105,224,227,160,141,134,168,24,160,235,192,133,66,49,204,44,170,99,66,96,73,249,26,214,111,160,80,91,130,39,47,139,160,137,160,180,100,175,215,221,2,93,142,70,24,246,118,131,43,108,99,21,35,212,203,231,137,183,159,78,163,127,220,240,211, +53,254,72,64,244,142,55,57,158,109,222,56,252,192,0,26,126,20,0,40,0,144,60,16,2,37,171,111,152,251,229,229,87,207,254,175,162,42,195,74,49,34,129,20,201,140,146,38,186,46,44,198,163,32,197,68,230,29,150,235,171,97,78,241,34,86,85,176,176,116,37,204, +40,156,119,34,191,0,129,140,57,103,150,160,137,24,250,46,232,118,54,195,160,167,147,253,63,13,237,211,124,16,102,244,51,164,63,4,107,219,203,12,191,100,239,219,57,249,100,195,243,3,15,89,186,220,125,120,22,81,0,160,0,64,242,75,8,212,26,13,11,47,154,118, +253,170,207,206,249,110,229,130,146,117,146,72,140,111,88,74,201,192,161,147,35,126,44,58,16,101,70,134,14,117,169,48,212,194,172,162,5,176,160,116,5,212,149,44,133,105,5,115,160,72,91,138,39,51,149,207,143,88,24,44,1,106,240,123,136,177,239,128,33,79, +55,51,248,196,153,102,127,47,104,180,25,225,229,127,200,240,11,28,51,252,62,75,112,116,232,128,245,177,166,141,67,143,17,195,143,35,122,81,0,96,25,32,146,159,120,205,193,80,227,11,131,207,182,111,25,125,118,249,85,179,174,88,122,197,204,255,154,182,162, +236,83,26,226,182,69,67,234,183,24,62,9,141,204,230,13,240,188,112,76,14,196,193,22,156,0,115,96,148,53,134,209,242,58,40,213,85,194,116,34,2,102,23,47,130,121,197,75,88,132,128,150,30,234,136,88,64,148,144,96,113,112,134,173,48,233,31,129,17,95,47,43, +213,163,137,123,142,144,5,66,82,128,253,27,122,142,104,35,168,140,171,234,32,250,67,208,113,204,248,123,38,130,205,221,239,152,30,109,222,52,252,28,185,238,177,156,15,73,59,40,0,144,204,240,232,18,229,131,111,55,109,26,122,123,193,249,211,78,95,113,237, +236,155,230,156,81,121,131,190,72,91,193,242,4,50,100,158,57,245,40,89,226,24,104,79,24,39,58,5,206,73,140,17,237,13,79,195,205,180,207,0,29,93,92,107,156,77,68,193,2,152,89,56,159,37,21,210,121,5,5,66,49,158,236,127,227,217,187,195,118,230,205,155,124, +3,48,70,182,201,192,8,216,66,19,172,3,31,141,196,208,99,204,68,25,39,100,108,25,39,91,223,55,240,16,139,197,99,246,126,239,123,173,175,141,172,39,198,255,141,144,39,26,197,179,140,160,0,64,144,143,118,247,160,127,247,228,81,186,77,91,81,246,171,37,151, +207,252,210,146,79,206,248,122,97,181,126,5,77,22,204,172,229,129,132,32,248,96,132,128,66,115,7,104,120,122,194,63,12,13,214,61,39,122,18,20,235,202,88,100,160,198,56,11,166,21,204,102,173,138,171,13,211,161,68,95,193,150,16,50,41,92,173,54,116,109, +222,19,117,130,61,56,9,214,208,56,57,86,35,44,170,66,167,233,185,35,118,54,92,71,36,199,81,163,57,118,124,53,252,137,38,79,153,12,175,229,88,175,254,176,79,180,145,107,248,229,246,55,198,30,27,220,111,57,18,19,177,101,47,130,2,0,65,78,154,201,118,215, +24,217,238,57,250,84,223,253,139,46,158,254,169,37,151,205,252,70,237,242,210,203,4,29,103,160,131,135,50,37,42,240,79,162,128,38,157,209,13,180,31,208,53,113,150,133,110,15,153,217,244,56,154,123,67,141,26,93,38,40,212,22,67,137,174,130,37,27,82,129, +64,55,250,123,186,21,17,209,80,164,45,33,2,162,32,107,134,28,209,137,141,180,196,206,23,245,128,95,244,144,239,109,103,223,157,46,157,56,194,102,22,186,167,94,62,253,123,26,194,167,94,61,133,35,223,143,126,71,142,25,123,61,219,178,1,42,82,4,3,199,188, +126,183,41,208,208,187,115,226,201,246,45,163,27,29,131,190,9,188,139,17,20,0,8,146,4,126,91,56,220,244,210,208,171,205,155,134,95,157,177,186,98,233,178,43,102,126,121,254,121,53,95,44,170,49,46,138,209,225,67,52,87,32,195,39,160,159,136,20,104,132, +127,48,150,116,9,193,197,140,228,144,167,139,9,3,250,43,145,185,174,101,73,135,6,190,16,10,180,69,172,81,17,141,20,208,173,88,151,248,61,93,82,40,20,138,192,72,54,42,38,244,124,194,112,106,201,79,186,38,206,49,131,202,177,159,199,247,227,223,27,112,242, +43,30,99,73,143,180,108,142,38,65,70,99,97,136,196,34,108,12,46,13,211,135,136,135,30,16,125,224,167,70,62,234,5,111,212,77,54,39,248,34,110,98,216,221,108,128,14,245,226,195,196,211,143,30,171,168,56,110,44,143,27,122,218,127,65,75,190,99,166,123,245, +31,115,66,129,23,18,83,249,34,1,209,49,114,196,246,70,231,155,99,79,15,236,179,236,12,123,163,18,222,181,8,10,0,4,81,210,179,140,197,193,212,104,239,34,219,255,20,62,98,248,237,162,139,166,125,114,193,133,211,190,50,99,85,249,101,58,163,80,202,6,16,209, +80,107,60,123,190,83,66,24,240,31,233,221,83,67,76,103,26,132,137,209,117,133,173,9,131,12,137,80,242,241,234,157,132,113,39,222,39,121,61,53,248,44,63,225,88,6,60,21,27,58,98,92,57,46,241,147,190,130,14,179,161,255,62,254,15,7,137,238,71,226,243,194, +240,247,202,135,8,49,252,137,225,74,18,107,154,36,178,242,200,68,69,132,116,66,36,28,127,47,106,220,169,81,63,177,79,244,23,249,169,211,16,79,62,75,188,249,127,7,157,200,71,141,126,92,138,199,157,35,254,3,61,219,39,94,24,216,61,249,170,185,203,109,194, +59,20,65,1,128,32,41,137,10,132,130,77,27,135,182,208,173,118,121,217,156,249,231,213,126,122,241,165,211,63,95,54,187,240,28,242,144,230,197,16,49,78,89,190,238,154,48,160,212,99,231,224,95,59,238,9,19,124,220,128,71,32,116,194,40,31,143,40,36,84,81, +194,200,255,171,112,73,226,243,78,124,58,253,131,99,31,173,57,254,39,199,146,240,56,128,60,201,89,96,157,250,244,28,59,54,62,107,168,119,172,97,242,53,226,237,191,100,106,118,28,165,75,81,8,130,2,0,65,210,132,185,195,53,66,182,7,142,62,213,247,192,140, +213,21,107,136,24,184,110,254,39,106,62,93,50,163,96,21,181,119,180,201,80,38,116,27,84,87,42,252,163,1,63,241,87,72,18,70,159,227,57,8,186,34,227,227,205,142,173,93,239,140,111,28,58,104,217,19,176,135,131,120,132,16,20,0,8,146,65,80,111,108,248,125, +107,19,221,222,127,84,119,231,156,51,170,206,92,112,193,180,107,103,174,169,184,170,168,218,176,146,26,67,218,109,48,219,150,9,144,20,25,125,94,147,168,217,39,63,131,238,168,217,212,228,216,62,184,215,188,105,232,160,117,151,107,204,239,196,35,132,160, +0,64,144,44,32,232,140,136,221,239,142,31,160,91,65,185,238,231,179,207,168,58,131,8,130,171,103,172,174,184,162,108,78,225,26,242,144,215,72,209,24,196,200,22,71,49,144,167,22,63,209,150,87,208,241,76,15,134,92,145,81,83,3,49,250,251,204,155,135,222, +183,238,117,141,250,237,120,144,16,20,0,8,146,197,4,156,145,232,113,49,160,53,242,119,204,88,85,177,122,193,5,181,159,156,190,170,252,138,138,185,69,103,234,10,132,66,42,4,152,32,144,80,13,228,180,205,231,52,137,90,125,178,145,243,29,247,89,67,29,19, +45,206,247,250,247,76,190,57,222,236,60,228,53,7,189,120,148,16,20,0,8,146,131,68,131,82,108,248,144,181,145,110,196,251,187,187,122,113,233,188,185,103,85,157,63,107,109,229,39,171,23,151,156,107,44,211,213,81,35,193,4,129,24,207,128,86,196,72,178,94, +62,45,215,163,205,121,104,126,68,200,19,113,216,7,188,71,71,143,218,223,29,61,106,219,110,238,112,181,133,60,81,17,15,20,130,2,0,65,242,8,234,237,155,59,93,67,116,59,252,68,223,83,197,53,134,130,234,37,165,107,230,173,171,190,104,218,242,178,11,203,102, +23,158,170,47,214,86,178,127,43,210,8,1,10,130,140,183,247,180,112,129,167,30,190,134,37,240,17,47,63,228,54,249,59,38,219,93,251,198,91,156,59,136,225,63,228,26,245,79,226,121,68,16,20,0,8,114,2,175,37,20,32,219,129,129,189,230,3,26,78,243,155,178,89, +5,181,181,203,203,78,155,177,186,226,188,218,229,165,231,150,207,42,92,161,47,33,130,64,3,172,170,128,70,9,98,212,144,160,45,73,159,193,231,52,172,54,159,122,249,244,188,136,97,41,24,176,135,186,173,189,222,131,19,45,142,61,227,173,174,163,214,30,119, +95,196,143,78,62,130,160,0,64,144,147,128,122,136,206,17,191,153,108,91,187,222,54,109,165,225,227,210,89,5,53,181,203,74,87,17,65,112,118,229,252,162,179,43,235,138,79,33,130,96,182,160,227,53,244,223,211,234,130,24,46,27,168,107,236,249,132,193,167, +63,227,49,128,144,55,98,115,141,132,58,109,3,222,195,227,77,142,131,230,78,87,163,219,20,24,12,121,162,120,18,16,4,5,0,130,40,32,8,226,113,112,141,250,45,100,219,214,253,238,248,54,250,103,69,53,134,162,178,217,133,11,103,172,42,95,93,181,176,120,109, +249,220,226,53,197,181,134,197,134,98,109,45,53,82,180,186,128,69,10,136,48,160,162,0,171,13,78,214,210,3,112,196,216,211,178,60,142,255,187,177,39,94,188,199,109,14,14,146,115,208,102,235,243,28,181,116,121,26,172,189,158,78,207,120,192,138,201,155, +8,130,2,0,65,82,134,207,18,242,145,173,105,172,222,222,68,254,247,73,106,244,139,170,141,21,21,117,133,117,53,139,75,87,150,204,44,56,165,106,126,241,138,226,233,198,133,250,98,237,76,157,158,55,82,163,70,141,21,21,4,9,97,0,121,27,49,160,30,61,109,40, +72,215,234,143,255,164,66,75,138,198,164,176,55,106,38,199,118,208,103,13,117,90,123,60,45,150,110,119,171,99,200,215,235,157,12,142,71,131,104,237,17,4,5,0,130,100,16,212,219,247,76,4,28,116,27,58,96,173,63,254,231,5,21,122,67,201,116,227,180,226,105, +198,186,202,249,197,75,43,235,138,150,24,203,117,139,74,103,22,206,209,26,249,25,250,34,109,57,17,15,26,106,16,227,82,252,88,228,32,209,159,32,17,57,56,102,239,178,105,198,193,177,14,132,52,33,143,254,158,138,35,250,27,234,217,179,89,3,116,180,115,72, +242,134,60,81,139,215,28,26,11,185,34,189,182,126,111,47,241,238,187,220,166,192,128,115,196,63,26,116,133,221,185,221,193,17,65,80,0,32,72,78,19,112,132,67,100,27,154,108,119,13,245,110,159,216,121,252,207,245,197,90,222,88,170,171,40,172,54,204,168, +152,91,56,147,252,127,93,213,130,226,217,186,66,97,94,217,156,194,105,188,150,155,110,44,211,149,11,122,190,152,136,3,3,45,101,75,180,242,255,123,226,33,253,253,7,141,36,251,43,137,206,64,248,168,30,192,39,177,12,161,249,184,137,129,241,99,30,187,230, +67,30,60,13,207,159,120,29,75,193,63,81,49,33,17,241,226,241,91,67,110,242,211,236,28,245,155,137,231,62,108,235,245,140,68,2,226,144,173,207,75,12,124,196,228,179,4,109,33,111,52,132,137,148,8,146,103,2,192,235,197,158,27,72,254,66,199,198,146,205,234, +26,243,91,77,141,246,230,143,248,39,58,190,2,138,180,70,168,48,148,232,42,202,231,20,86,199,164,120,109,113,141,161,178,100,102,65,53,49,177,85,134,18,109,25,249,125,105,92,130,98,242,239,139,5,3,103,44,252,255,236,221,75,106,194,64,0,128,225,104,226, +139,90,104,233,190,208,131,120,75,47,215,19,20,173,90,84,218,196,81,155,206,152,62,20,234,174,208,133,223,7,1,5,31,193,133,243,79,72,50,119,189,126,28,232,211,26,187,157,163,173,125,184,235,93,63,63,123,36,33,141,223,233,102,72,187,240,189,136,82,136, +91,90,237,38,196,193,61,196,125,173,226,140,61,45,23,184,110,229,217,186,92,132,213,122,82,46,227,27,103,241,125,207,211,199,229,60,126,196,244,117,182,153,174,158,222,94,222,247,217,60,76,178,101,124,189,123,231,195,25,33,132,203,11,128,162,40,178,241, +120,44,2,224,183,249,118,115,121,97,136,3,254,34,62,94,52,51,251,250,103,182,253,57,19,79,119,180,235,118,138,172,46,234,230,105,63,239,12,175,6,131,56,213,79,235,239,118,143,182,162,119,221,105,223,222,15,135,231,206,57,72,231,39,196,25,123,21,7,245, +144,53,153,80,197,45,93,63,183,137,223,183,41,119,161,42,55,135,127,171,109,154,237,239,110,246,217,182,191,255,58,64,144,213,15,205,145,137,195,145,130,188,217,209,188,104,157,236,47,112,106,52,26,253,219,119,183,106,167,38,3,192,197,105,251,9,0,64, +0,0,0,2,0,0,16,0,0,128,0,0,0,4,0,0,32,0,0,0,1,0,0,8,0,0,64,0,0,0,2,0,0,16,0,0,128,0,0,0,4,0,0,32,0,0,0,1,0,0,8,0,0,64,0,0,128,0,0,0,4,0,0,32,0,0,0,1,0,0,8,0,0,64,0,0,0,2,0,0,16,0,0,128,0,0,0,4,0,0,32,0,0,128,191,246,33,192,0,100,235,173,153,70,62,64, +37,0,0,0,0,73,69,78,68,174,66,96,130,0,0 }; + +const char* juce_icon_png = (const char*) temp_binary_data_19; + +//================== wizard_AnimatedApp.svg ================== +static const unsigned char temp_binary_data_20[] = +"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" +"<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->\n" +"\n" +"<svg\n" +" xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n" +" xmlns:cc=\"http://creativecommons.org/ns#\"\n" +" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n" +" xmlns:svg=\"http://www.w3.org/2000/svg\"\n" +" xmlns=\"http://www.w3.org/2000/svg\"\n" +" xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\"\n" +" xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"\n" +" version=\"1.1\"\n" +" id=\"Layer_1\"\n" +" x=\"0px\"\n" +" y=\"0px\"\n" +" viewBox=\"0 0 136.9 114.8\"\n" +" enable-background=\"new 0 0 136.9 114.8\"\n" +" xml:space=\"preserve\"\n" +" inkscape:version=\"0.91 r13725\"\n" +" sodipodi:docname=\"wizard_AnimatedApp.svg\"><metadata\n" +" id=\"metadata50\"><rdf:RDF><cc:Work\n" +" rdf:about=\"\"><dc:format>image/svg+xml</dc:format><dc:type\n" +" rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\" /></cc:Work></rdf:RDF></metadata><defs\n" +" id=\"defs48\" /><sodipodi:namedview\n" +" pagecolor=\"#ffffff\"\n" +" bordercolor=\"#666666\"\n" +" borderopacity=\"1\"\n" +" objecttolerance=\"10\"\n" +" gridtolerance=\"10\"\n" +" guidetolerance=\"10\"\n" +" inkscape:pageopacity=\"0\"\n" +" inkscape:pageshadow=\"2\"\n" +" inkscape:window-width=\"1680\"\n" +" inkscape:window-height=\"1001\"\n" +" id=\"namedview46\"\n" +" showgrid=\"false\"\n" +" inkscape:zoom=\"5.6568543\"\n" +" inkscape:cx=\"85.414924\"\n" +" inkscape:cy=\"49.441529\"\n" +" inkscape:window-x=\"0\"\n" +" inkscape:window-y=\"1\"\n" +" inkscape:window-maximized=\"1\"\n" +" inkscape:current-layer=\"Layer_1\" /><g\n" +" id=\"Layer_1_18_\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\"><rect\n" +" x=\"16.3\"\n" +" y=\"10.9\"\n" +" stroke-miterlimit=\"10\"\n" +" width=\"103.6\"\n" +" height=\"67.5\"\n" +" id=\"rect4\"\n" +" stroke-width=\"1.3469\"\n" +" stroke=\"#a45c94\"\n" +" fill=\"none\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><rect\n" +" x=\"16.3\"\n" +" y=\"10.9\"\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" +" stroke-width=\"1.3469\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"105.4\"\n" -" y1=\"43.6\"\n" -" x2=\"105.4\"\n" -" y2=\"44.7\"\n" -" id=\"line115\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" width=\"103.6\"\n" +" height=\"2.4\"\n" +" id=\"rect6\"\n" +" style=\"stroke:#a45c9f;stroke-opacity:0.94117647\" /><circle\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" +" stroke-width=\"1.3469\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"107.1\"\n" -" y1=\"43.8\"\n" -" x2=\"107.1\"\n" -" y2=\"44.5\"\n" -" id=\"line117\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" +" cx=\"80.3\"\n" +" cy=\"45\"\n" +" r=\"20.8\"\n" +" id=\"circle8\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><g\n" +" id=\"g10\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\"><g\n" +" id=\"g12\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\"><path\n" +" stroke-miterlimit=\"10\"\n" +" d=\"M97.8,40.1c0.9,3.2,0,8-2.1,8.3 c-2,0.2-10.5-2.2-14.8-3.6c2.9-3.4,8.9-10,10.8-10.8C93.5,33.2,96.9,36.9,97.8,40.1z\"\n" +" id=\"path14\"\n" +" stroke-width=\"1.3469\"\n" +" stroke=\"#a45c94\"\n" +" fill=\"none\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><g\n" +" id=\"g16\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\"><path\n" +" stroke-miterlimit=\"10\"\n" +" d=\"M93.3,57.7c-2.3,2.4-7,4-8.2,2.4 c-1.2-1.6-3.4-10.2-4.3-14.6c4.4,0.8,13.1,2.8,14.7,4C97.2,50.5,95.6,55.3,93.3,57.7z\"\n" +" id=\"path18\"\n" +" stroke-width=\"1.3469\"\n" +" stroke=\"#a45c94\"\n" +" fill=\"none\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><g\n" +" id=\"g20\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\"><path\n" +" stroke-miterlimit=\"10\"\n" +" d=\"M75.7,62.6c-3.2-0.8-7-4.1-6.1-6 c0.8-1.9,7.2-8,10.5-11.1c1.5,4.3,4.1,12.7,3.9,14.8C83.9,62.4,79,63.4,75.7,62.6z\"\n" +" id=\"path22\"\n" +" stroke-width=\"1.3469\"\n" +" stroke=\"#a45c94\"\n" +" fill=\"none\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><g\n" +" id=\"g24\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\"><path\n" +" stroke-miterlimit=\"10\"\n" +" d=\"M62.9,49.9c-0.9-3.2,0-8,2.1-8.3 c2-0.2,10.5,2.2,14.8,3.6c-2.9,3.4-8.9,10-10.8,10.8C67.2,56.8,63.8,53.1,62.9,49.9z\"\n" +" id=\"path26\"\n" +" stroke-width=\"1.3469\"\n" +" stroke=\"#a45c94\"\n" +" fill=\"none\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><g\n" +" id=\"g28\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\"><path\n" +" stroke-miterlimit=\"10\"\n" +" d=\"M67.4,32.3c2.3-2.4,7-4,8.2-2.4 c1.2,1.6,3.4,10.2,4.3,14.6c-4.4-0.8-13.1-2.8-14.7-4C63.5,39.4,65.1,34.7,67.4,32.3z\"\n" +" id=\"path30\"\n" +" stroke-width=\"1.3469\"\n" +" stroke=\"#a45c94\"\n" +" fill=\"none\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><g\n" +" id=\"g32\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\"><path\n" +" stroke-miterlimit=\"10\"\n" +" d=\"M84.8,27.4c3.2,0.8,7,4.1,6.1,6 c-0.8,1.9-7.2,8-10.5,11.1c-1.5-4.3-4.1-12.7-3.9-14.8C76.7,27.6,81.6,26.6,84.8,27.4z\"\n" +" id=\"path34\"\n" +" stroke-width=\"1.3469\"\n" +" stroke=\"#a45c94\"\n" +" fill=\"none\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /></g></g><path\n" " stroke-miterlimit=\"10\"\n" -" x1=\"108.8\"\n" -" y1=\"43.6\"\n" -" x2=\"108.8\"\n" -" y2=\"44.7\"\n" -" id=\"line119\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" +" d=\"M130,114.8H6.9c-3.8,0-6.9-3.1-6.9-6.9V6.9 C0,3.1,3.1,0,6.9,0H130c3.8,0,6.9,3.1,6.9,6.9v101.1C136.9,111.7,133.9,114.8,130,114.8z\"\n" +" id=\"path36\"\n" +" stroke-width=\"1.3469\"\n" " stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"110.4\"\n" -" y1=\"43.6\"\n" -" x2=\"110.4\"\n" -" y2=\"44.7\"\n" -" id=\"line121\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"112.1\"\n" -" y1=\"42.6\"\n" -" x2=\"112.1\"\n" -" y2=\"45.7\"\n" -" id=\"line123\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><path\n" +" opacity=\"0.8\"\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" +" stroke-width=\"1.3469\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"113.8\"\n" -" y1=\"43.1\"\n" -" x2=\"113.8\"\n" -" y2=\"45.2\"\n" -" id=\"line125\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" d=\"M62.6,61.4 c-9.1-9.1-9.1-23.7,0-32.8\"\n" +" id=\"path38\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><path\n" +" opacity=\"0.5\"\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" +" stroke-width=\"1.3469\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"115.4\"\n" -" y1=\"43.6\"\n" -" x2=\"115.4\"\n" -" y2=\"44.7\"\n" -" id=\"line127\"\n" +" d=\"M55.9,57.3 c-4.7-7.4-4.7-16.9-0.1-24.4\"\n" +" id=\"path40\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" opacity=\"0.7\"\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" +" stroke-width=\"1.3469\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"117.1\"\n" -" y1=\"43.8\"\n" -" x2=\"117.1\"\n" -" y2=\"44.5\"\n" -" id=\"line129\"\n" +" x1=\"57.7\"\n" +" y1=\"41.5\"\n" +" x2=\"37.8\"\n" +" y2=\"41.5\"\n" +" id=\"line42\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" opacity=\"0.7\"\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" +" stroke-width=\"1.3469\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"118.8\"\n" -" y1=\"43.8\"\n" -" x2=\"118.8\"\n" -" y2=\"44.5\"\n" -" id=\"line131\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /></svg>"; +" x1=\"57.7\"\n" +" y1=\"48.4\"\n" +" x2=\"34.2\"\n" +" y2=\"48.4\"\n" +" id=\"line44\"\n" +" style=\"stroke:#a45c94;stroke-opacity:0.94117647\" /></svg>"; -const char* wizard_AudioApp_svg = (const char*) temp_binary_data_15; +const char* wizard_AnimatedApp_svg = (const char*) temp_binary_data_20; -//================== wizard_AudioPlugin.svg ================== -static const unsigned char temp_binary_data_16[] = +//================== wizard_AudioApp.svg ================== +static const unsigned char temp_binary_data_21[] = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" "<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->\n" "\n" @@ -3435,11 +3106,11 @@ static const unsigned char temp_binary_data_16[] = " enable-background=\"new 0 0 136.9 114.8\"\n" " xml:space=\"preserve\"\n" " inkscape:version=\"0.91 r13725\"\n" -" sodipodi:docname=\"wizard_AudioPlugin.svg\"><metadata\n" -" id=\"metadata181\"><rdf:RDF><cc:Work\n" +" sodipodi:docname=\"wizard_AudioApp.svg\"><metadata\n" +" id=\"metadata137\"><rdf:RDF><cc:Work\n" " rdf:about=\"\"><dc:format>image/svg+xml</dc:format><dc:type\n" " rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\" /></cc:Work></rdf:RDF></metadata><defs\n" -" id=\"defs179\" /><sodipodi:namedview\n" +" id=\"defs135\" /><sodipodi:namedview\n" " pagecolor=\"#ffffff\"\n" " bordercolor=\"#666666\"\n" " borderopacity=\"1\"\n" @@ -3450,65 +3121,73 @@ static const unsigned char temp_binary_data_16[] = " inkscape:pageshadow=\"2\"\n" " inkscape:window-width=\"1680\"\n" " inkscape:window-height=\"1001\"\n" -" id=\"namedview177\"\n" +" id=\"namedview133\"\n" " showgrid=\"false\"\n" -" inkscape:zoom=\"8.2229963\"\n" -" inkscape:cx=\"67.455426\"\n" -" inkscape:cy=\"64.924074\"\n" +" inkscape:zoom=\"4.1114981\"\n" +" inkscape:cx=\"45.83412\"\n" +" inkscape:cy=\"47.98031\"\n" " inkscape:window-x=\"0\"\n" " inkscape:window-y=\"1\"\n" " inkscape:window-maximized=\"1\"\n" -" inkscape:current-layer=\"Layer_1\" /><g\n" -" id=\"Layer_1_23_\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\"><rect\n" -" x=\"16.3\"\n" -" y=\"10.9\"\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.3469\"\n" -" stroke-miterlimit=\"10\"\n" -" width=\"103.6\"\n" -" height=\"67.5\"\n" -" id=\"rect4\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><rect\n" -" x=\"16.3\"\n" -" y=\"10.9\"\n" +" inkscape:current-layer=\"Layer_1\" /><path\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" " stroke-width=\"1.3469\"\n" " stroke-miterlimit=\"10\"\n" -" width=\"103.6\"\n" +" d=\"M130,114.8H6.9c-3.8,0-6.9-3.1-6.9-6.9V6.9 C0,3.1,3.1,0,6.9,0H130c3.8,0,6.9,3.1,6.9,6.9v101.1C136.9,111.7,133.9,114.8,130,114.8z\"\n" +" id=\"path3\"\n" +" style=\"fill:none;fill-opacity:1;stroke:#a45c94;stroke-opacity:1\" /><rect\n" +" x=\"16.5\"\n" +" y=\"10.9\"\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.3412\"\n" +" stroke-miterlimit=\"10\"\n" +" width=\"102.7\"\n" " height=\"2.4\"\n" -" id=\"rect6\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><path\n" +" id=\"rect5\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><rect\n" +" x=\"16.5\"\n" +" y=\"10.9\"\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" " stroke-width=\"1.3469\"\n" " stroke-miterlimit=\"10\"\n" -" d=\"M130,114.8H6.9c-3.8,0-6.9-3.1-6.9-6.9V6.9 C0,3.1,3.1,0,6.9,0H130c3.8,0,6.9,3.1,6.9,6.9v101.1C136.9,111.7,133.9,114.8,130,114.8z\"\n" -" id=\"path8\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><g\n" -" id=\"Layer_1_8_\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\"><rect\n" -" x=\"35.7\"\n" -" y=\"23.6\"\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.3469\"\n" -" stroke-miterlimit=\"10\"\n" -" width=\"64.4\"\n" -" height=\"42.3\"\n" -" id=\"rect11\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><line\n" +" width=\"102.9\"\n" +" height=\"67.5\"\n" +" id=\"rect7\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"36\"\n" -" y1=\"44.1\"\n" -" x2=\"36\"\n" -" y2=\"44.6\"\n" +" x1=\"17.1\"\n" +" y1=\"43.8\"\n" +" x2=\"17.1\"\n" +" y2=\"44.5\"\n" +" id=\"line9\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"18.8\"\n" +" y1=\"43.6\"\n" +" x2=\"18.8\"\n" +" y2=\"44.7\"\n" +" id=\"line11\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"20.4\"\n" +" y1=\"43.8\"\n" +" x2=\"20.4\"\n" +" y2=\"44.5\"\n" " id=\"line13\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3516,9 +3195,9 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"37.1\"\n" -" y1=\"44\"\n" -" x2=\"37.1\"\n" +" x1=\"22.1\"\n" +" y1=\"43.6\"\n" +" x2=\"22.1\"\n" " y2=\"44.7\"\n" " id=\"line15\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" @@ -3527,10 +3206,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"38.1\"\n" -" y1=\"44.1\"\n" -" x2=\"38.1\"\n" -" y2=\"44.6\"\n" +" x1=\"23.8\"\n" +" y1=\"43.1\"\n" +" x2=\"23.8\"\n" +" y2=\"45.2\"\n" " id=\"line17\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3538,10 +3217,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"39.2\"\n" -" y1=\"44\"\n" -" x2=\"39.2\"\n" -" y2=\"44.7\"\n" +" x1=\"25.4\"\n" +" y1=\"42.3\"\n" +" x2=\"25.4\"\n" +" y2=\"46\"\n" " id=\"line19\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3549,10 +3228,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"40.2\"\n" -" y1=\"43.7\"\n" -" x2=\"40.2\"\n" -" y2=\"45\"\n" +" x1=\"27.1\"\n" +" y1=\"43.9\"\n" +" x2=\"27.1\"\n" +" y2=\"44.4\"\n" " id=\"line21\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3560,10 +3239,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"41.3\"\n" -" y1=\"43.2\"\n" -" x2=\"41.3\"\n" -" y2=\"45.5\"\n" +" x1=\"28.8\"\n" +" y1=\"43.3\"\n" +" x2=\"28.8\"\n" +" y2=\"45\"\n" " id=\"line23\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3571,10 +3250,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"42.3\"\n" -" y1=\"44.2\"\n" -" x2=\"42.3\"\n" -" y2=\"44.5\"\n" +" x1=\"30.4\"\n" +" y1=\"29.3\"\n" +" x2=\"30.4\"\n" +" y2=\"59\"\n" " id=\"line25\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3582,10 +3261,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"43.3\"\n" -" y1=\"43.8\"\n" -" x2=\"43.3\"\n" -" y2=\"44.9\"\n" +" x1=\"32.1\"\n" +" y1=\"40.9\"\n" +" x2=\"32.1\"\n" +" y2=\"47.4\"\n" " id=\"line27\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3593,10 +3272,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"44.4\"\n" -" y1=\"35.1\"\n" -" x2=\"44.4\"\n" -" y2=\"53.6\"\n" +" x1=\"33.8\"\n" +" y1=\"42.7\"\n" +" x2=\"33.8\"\n" +" y2=\"45.6\"\n" " id=\"line29\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3604,10 +3283,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"45.4\"\n" -" y1=\"42.3\"\n" -" x2=\"45.4\"\n" -" y2=\"46.4\"\n" +" x1=\"35.4\"\n" +" y1=\"36.6\"\n" +" x2=\"35.4\"\n" +" y2=\"51.7\"\n" " id=\"line31\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3615,10 +3294,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"46.5\"\n" -" y1=\"43.4\"\n" -" x2=\"46.5\"\n" -" y2=\"45.3\"\n" +" x1=\"37.1\"\n" +" y1=\"33.3\"\n" +" x2=\"37.1\"\n" +" y2=\"55.1\"\n" " id=\"line33\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3626,10 +3305,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"47.5\"\n" -" y1=\"39.6\"\n" -" x2=\"47.5\"\n" -" y2=\"49.1\"\n" +" x1=\"38.8\"\n" +" y1=\"42.6\"\n" +" x2=\"38.8\"\n" +" y2=\"45.7\"\n" " id=\"line35\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3637,10 +3316,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"48.6\"\n" -" y1=\"37.5\"\n" -" x2=\"48.6\"\n" -" y2=\"51.2\"\n" +" x1=\"40.4\"\n" +" y1=\"37.4\"\n" +" x2=\"40.4\"\n" +" y2=\"50.9\"\n" " id=\"line37\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3648,10 +3327,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"49.6\"\n" -" y1=\"43.4\"\n" -" x2=\"49.6\"\n" -" y2=\"45.3\"\n" +" x1=\"42.1\"\n" +" y1=\"27.4\"\n" +" x2=\"42.1\"\n" +" y2=\"60.9\"\n" " id=\"line39\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3659,10 +3338,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"50.6\"\n" -" y1=\"40.1\"\n" -" x2=\"50.6\"\n" -" y2=\"48.6\"\n" +" x1=\"43.8\"\n" +" y1=\"39.3\"\n" +" x2=\"43.8\"\n" +" y2=\"49\"\n" " id=\"line41\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3670,10 +3349,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"51.7\"\n" -" y1=\"33.9\"\n" -" x2=\"51.7\"\n" -" y2=\"54.9\"\n" +" x1=\"45.4\"\n" +" y1=\"41.1\"\n" +" x2=\"45.4\"\n" +" y2=\"47.2\"\n" " id=\"line43\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3681,10 +3360,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"52.7\"\n" -" y1=\"41.3\"\n" -" x2=\"52.7\"\n" -" y2=\"47.4\"\n" +" x1=\"47.1\"\n" +" y1=\"42.6\"\n" +" x2=\"47.1\"\n" +" y2=\"45.7\"\n" " id=\"line45\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3692,10 +3371,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"53.8\"\n" -" y1=\"42.5\"\n" -" x2=\"53.8\"\n" -" y2=\"46.3\"\n" +" x1=\"48.8\"\n" +" y1=\"36.2\"\n" +" x2=\"48.8\"\n" +" y2=\"52.1\"\n" " id=\"line47\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3703,10 +3382,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"54.8\"\n" -" y1=\"43.4\"\n" -" x2=\"54.8\"\n" -" y2=\"45.3\"\n" +" x1=\"50.4\"\n" +" y1=\"42.5\"\n" +" x2=\"50.4\"\n" +" y2=\"45.9\"\n" " id=\"line49\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3714,10 +3393,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"55.9\"\n" -" y1=\"39.4\"\n" -" x2=\"55.9\"\n" -" y2=\"49.3\"\n" +" x1=\"52.1\"\n" +" y1=\"39.3\"\n" +" x2=\"52.1\"\n" +" y2=\"49\"\n" " id=\"line51\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3725,10 +3404,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"56.9\"\n" -" y1=\"43.3\"\n" -" x2=\"56.9\"\n" -" y2=\"45.4\"\n" +" x1=\"53.8\"\n" +" y1=\"34.8\"\n" +" x2=\"53.8\"\n" +" y2=\"53.5\"\n" " id=\"line53\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3736,10 +3415,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"57.9\"\n" -" y1=\"41.3\"\n" -" x2=\"57.9\"\n" -" y2=\"47.4\"\n" +" x1=\"55.4\"\n" +" y1=\"42.2\"\n" +" x2=\"55.4\"\n" +" y2=\"46.1\"\n" " id=\"line55\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3747,10 +3426,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"59\"\n" -" y1=\"38.5\"\n" -" x2=\"59\"\n" -" y2=\"50.2\"\n" +" x1=\"57.1\"\n" +" y1=\"41\"\n" +" x2=\"57.1\"\n" +" y2=\"47.3\"\n" " id=\"line57\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3758,10 +3437,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"60\"\n" -" y1=\"43.1\"\n" -" x2=\"60\"\n" -" y2=\"45.6\"\n" +" x1=\"58.8\"\n" +" y1=\"35.4\"\n" +" x2=\"58.8\"\n" +" y2=\"53\"\n" " id=\"line59\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3769,10 +3448,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"61.1\"\n" -" y1=\"42.4\"\n" -" x2=\"61.1\"\n" -" y2=\"46.3\"\n" +" x1=\"60.4\"\n" +" y1=\"32.6\"\n" +" x2=\"60.4\"\n" +" y2=\"55.8\"\n" " id=\"line61\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3781,9 +3460,9 @@ static const unsigned char temp_binary_data_16[] = " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" " x1=\"62.1\"\n" -" y1=\"38.8\"\n" +" y1=\"37.4\"\n" " x2=\"62.1\"\n" -" y2=\"49.9\"\n" +" y2=\"50.9\"\n" " id=\"line63\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3791,10 +3470,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"63.2\"\n" -" y1=\"37.1\"\n" -" x2=\"63.2\"\n" -" y2=\"51.6\"\n" +" x1=\"63.8\"\n" +" y1=\"38.1\"\n" +" x2=\"63.8\"\n" +" y2=\"50.2\"\n" " id=\"line65\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3802,10 +3481,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"64.2\"\n" -" y1=\"40.1\"\n" -" x2=\"64.2\"\n" -" y2=\"48.6\"\n" +" x1=\"65.4\"\n" +" y1=\"42.2\"\n" +" x2=\"65.4\"\n" +" y2=\"46.1\"\n" " id=\"line67\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3813,10 +3492,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"65.2\"\n" -" y1=\"40.6\"\n" -" x2=\"65.2\"\n" -" y2=\"48.1\"\n" +" x1=\"67.1\"\n" +" y1=\"38.9\"\n" +" x2=\"67.1\"\n" +" y2=\"49.4\"\n" " id=\"line69\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3824,10 +3503,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"66.3\"\n" -" y1=\"43.1\"\n" -" x2=\"66.3\"\n" -" y2=\"45.6\"\n" +" x1=\"68.8\"\n" +" y1=\"43.6\"\n" +" x2=\"68.8\"\n" +" y2=\"44.7\"\n" " id=\"line71\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3835,10 +3514,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"67.3\"\n" -" y1=\"41.1\"\n" -" x2=\"67.3\"\n" -" y2=\"47.6\"\n" +" x1=\"70.4\"\n" +" y1=\"41.4\"\n" +" x2=\"70.4\"\n" +" y2=\"47\"\n" " id=\"line73\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3846,10 +3525,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"68.4\"\n" -" y1=\"44\"\n" -" x2=\"68.4\"\n" -" y2=\"44.7\"\n" +" x1=\"72.1\"\n" +" y1=\"39\"\n" +" x2=\"72.1\"\n" +" y2=\"49.3\"\n" " id=\"line75\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3857,10 +3536,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"69.4\"\n" -" y1=\"42.6\"\n" -" x2=\"69.4\"\n" -" y2=\"46.1\"\n" +" x1=\"73.8\"\n" +" y1=\"40.9\"\n" +" x2=\"73.8\"\n" +" y2=\"47.5\"\n" " id=\"line77\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3868,10 +3547,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"70.5\"\n" -" y1=\"41.1\"\n" -" x2=\"70.5\"\n" -" y2=\"47.6\"\n" +" x1=\"75.4\"\n" +" y1=\"40.6\"\n" +" x2=\"75.4\"\n" +" y2=\"47.8\"\n" " id=\"line79\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3879,10 +3558,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"71.5\"\n" -" y1=\"42.3\"\n" -" x2=\"71.5\"\n" -" y2=\"46.4\"\n" +" x1=\"77.1\"\n" +" y1=\"38.4\"\n" +" x2=\"77.1\"\n" +" y2=\"49.9\"\n" " id=\"line81\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3890,10 +3569,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"72.5\"\n" -" y1=\"42.1\"\n" -" x2=\"72.5\"\n" -" y2=\"46.6\"\n" +" x1=\"78.8\"\n" +" y1=\"42\"\n" +" x2=\"78.8\"\n" +" y2=\"46.3\"\n" " id=\"line83\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3901,10 +3580,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"73.6\"\n" -" y1=\"40.8\"\n" -" x2=\"73.6\"\n" -" y2=\"47.9\"\n" +" x1=\"80.4\"\n" +" y1=\"42.2\"\n" +" x2=\"80.4\"\n" +" y2=\"46.1\"\n" " id=\"line85\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3912,10 +3591,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"74.6\"\n" -" y1=\"43\"\n" -" x2=\"74.6\"\n" -" y2=\"45.7\"\n" +" x1=\"82.1\"\n" +" y1=\"43.6\"\n" +" x2=\"82.1\"\n" +" y2=\"44.7\"\n" " id=\"line87\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3923,10 +3602,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"75.7\"\n" -" y1=\"43.1\"\n" -" x2=\"75.7\"\n" -" y2=\"45.6\"\n" +" x1=\"83.8\"\n" +" y1=\"42.6\"\n" +" x2=\"83.8\"\n" +" y2=\"45.7\"\n" " id=\"line89\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3934,10 +3613,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"76.7\"\n" -" y1=\"44\"\n" -" x2=\"76.7\"\n" -" y2=\"44.7\"\n" +" x1=\"85.4\"\n" +" y1=\"43.3\"\n" +" x2=\"85.4\"\n" +" y2=\"45\"\n" " id=\"line91\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3945,10 +3624,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"77.8\"\n" -" y1=\"43.4\"\n" -" x2=\"77.8\"\n" -" y2=\"45.3\"\n" +" x1=\"87.1\"\n" +" y1=\"39.9\"\n" +" x2=\"87.1\"\n" +" y2=\"48.4\"\n" " id=\"line93\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3956,10 +3635,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"78.8\"\n" -" y1=\"43.8\"\n" -" x2=\"78.8\"\n" -" y2=\"44.9\"\n" +" x1=\"88.8\"\n" +" y1=\"42.9\"\n" +" x2=\"88.8\"\n" +" y2=\"45.4\"\n" " id=\"line95\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3967,10 +3646,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"79.9\"\n" -" y1=\"41.7\"\n" -" x2=\"79.9\"\n" -" y2=\"47\"\n" +" x1=\"90.4\"\n" +" y1=\"43.6\"\n" +" x2=\"90.4\"\n" +" y2=\"44.7\"\n" " id=\"line97\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3978,10 +3657,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"80.9\"\n" +" x1=\"92.1\"\n" " y1=\"43.6\"\n" -" x2=\"80.9\"\n" -" y2=\"45.2\"\n" +" x2=\"92.1\"\n" +" y2=\"44.7\"\n" " id=\"line99\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -3989,10 +3668,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"81.9\"\n" -" y1=\"44\"\n" -" x2=\"81.9\"\n" -" y2=\"44.7\"\n" +" x1=\"93.8\"\n" +" y1=\"42.7\"\n" +" x2=\"93.8\"\n" +" y2=\"45.6\"\n" " id=\"line101\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -4000,10 +3679,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"83\"\n" -" y1=\"44\"\n" -" x2=\"83\"\n" -" y2=\"44.7\"\n" +" x1=\"95.4\"\n" +" y1=\"41.1\"\n" +" x2=\"95.4\"\n" +" y2=\"47.2\"\n" " id=\"line103\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -4011,10 +3690,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"84\"\n" -" y1=\"43.4\"\n" -" x2=\"84\"\n" -" y2=\"45.3\"\n" +" x1=\"97.1\"\n" +" y1=\"42.7\"\n" +" x2=\"97.1\"\n" +" y2=\"45.6\"\n" " id=\"line105\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -4022,10 +3701,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"85.1\"\n" -" y1=\"42.5\"\n" -" x2=\"85.1\"\n" -" y2=\"46.3\"\n" +" x1=\"98.8\"\n" +" y1=\"43.6\"\n" +" x2=\"98.8\"\n" +" y2=\"44.7\"\n" " id=\"line107\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -4033,9 +3712,9 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"86.1\"\n" -" y1=\"43.5\"\n" -" x2=\"86.1\"\n" +" x1=\"100.4\"\n" +" y1=\"43.1\"\n" +" x2=\"100.4\"\n" " y2=\"45.2\"\n" " id=\"line109\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" @@ -4044,9 +3723,9 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"87.2\"\n" -" y1=\"44\"\n" -" x2=\"87.2\"\n" +" x1=\"102.1\"\n" +" y1=\"43.6\"\n" +" x2=\"102.1\"\n" " y2=\"44.7\"\n" " id=\"line111\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" @@ -4055,10 +3734,10 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"88.2\"\n" -" y1=\"43.7\"\n" -" x2=\"88.2\"\n" -" y2=\"45\"\n" +" x1=\"103.8\"\n" +" y1=\"42\"\n" +" x2=\"103.8\"\n" +" y2=\"46.3\"\n" " id=\"line113\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" @@ -4066,9 +3745,9 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"89.2\"\n" -" y1=\"44\"\n" -" x2=\"89.2\"\n" +" x1=\"105.4\"\n" +" y1=\"43.6\"\n" +" x2=\"105.4\"\n" " y2=\"44.7\"\n" " id=\"line115\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" @@ -4077,294 +3756,94 @@ static const unsigned char temp_binary_data_16[] = " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"90.3\"\n" -" y1=\"43\"\n" -" x2=\"90.3\"\n" -" y2=\"45.7\"\n" +" x1=\"107.1\"\n" +" y1=\"43.8\"\n" +" x2=\"107.1\"\n" +" y2=\"44.5\"\n" " id=\"line117\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"91.3\"\n" -" y1=\"44\"\n" -" x2=\"91.3\"\n" -" y2=\"44.7\"\n" -" id=\"line119\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"92.4\"\n" -" y1=\"44.2\"\n" -" x2=\"92.4\"\n" -" y2=\"44.6\"\n" -" id=\"line121\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-linecap=\"round\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"93.4\"\n" -" y1=\"44\"\n" -" x2=\"93.4\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"108.8\"\n" +" y1=\"43.6\"\n" +" x2=\"108.8\"\n" " y2=\"44.7\"\n" -" id=\"line123\"\n" +" id=\"line119\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"94.5\"\n" -" y1=\"44\"\n" -" x2=\"94.5\"\n" +" x1=\"110.4\"\n" +" y1=\"43.6\"\n" +" x2=\"110.4\"\n" " y2=\"44.7\"\n" -" id=\"line125\"\n" +" id=\"line121\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"95.5\"\n" -" y1=\"43.4\"\n" -" x2=\"95.5\"\n" -" y2=\"45.3\"\n" -" id=\"line127\"\n" +" x1=\"112.1\"\n" +" y1=\"42.6\"\n" +" x2=\"112.1\"\n" +" y2=\"45.7\"\n" +" id=\"line123\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"96.5\"\n" -" y1=\"43.7\"\n" -" x2=\"96.5\"\n" -" y2=\"45\"\n" -" id=\"line129\"\n" +" x1=\"113.8\"\n" +" y1=\"43.1\"\n" +" x2=\"113.8\"\n" +" y2=\"45.2\"\n" +" id=\"line125\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"97.6\"\n" -" y1=\"44\"\n" -" x2=\"97.6\"\n" +" x1=\"115.4\"\n" +" y1=\"43.6\"\n" +" x2=\"115.4\"\n" " y2=\"44.7\"\n" -" id=\"line131\"\n" +" id=\"line127\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"98.6\"\n" -" y1=\"44.2\"\n" -" x2=\"98.6\"\n" -" y2=\"44.6\"\n" -" id=\"line133\"\n" +" x1=\"117.1\"\n" +" y1=\"43.8\"\n" +" x2=\"117.1\"\n" +" y2=\"44.5\"\n" +" id=\"line129\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" " stroke-width=\"1.5\"\n" " stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"99.7\"\n" -" y1=\"44.2\"\n" -" x2=\"99.7\"\n" -" y2=\"44.6\"\n" -" id=\"line135\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><g\n" -" id=\"g137\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\"><g\n" -" id=\"g139\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\"><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"16.3\"\n" -" y1=\"35.1\"\n" -" x2=\"35.8\"\n" -" y2=\"35.1\"\n" -" id=\"line141\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\" /><g\n" -" id=\"g143\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\"><circle\n" -" fill=\"#a45c94\"\n" -" cx=\"35.7\"\n" -" cy=\"35.1\"\n" -" r=\"1.7\"\n" -" id=\"circle145\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\" /></g></g></g><g\n" -" id=\"g147\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\"><g\n" -" id=\"g149\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\"><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"16.3\"\n" -" y1=\"54.4\"\n" -" x2=\"35.8\"\n" -" y2=\"54.4\"\n" -" id=\"line151\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\" /><g\n" -" id=\"g153\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\"><circle\n" -" fill=\"#a45c94\"\n" -" cx=\"35.7\"\n" -" cy=\"54.4\"\n" -" r=\"1.7\"\n" -" id=\"circle155\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\" /></g></g></g><g\n" -" id=\"g157\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\"><g\n" -" id=\"g159\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\"><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"119.7\"\n" -" y1=\"54.4\"\n" -" x2=\"100.2\"\n" -" y2=\"54.4\"\n" -" id=\"line161\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\" /><g\n" -" id=\"g163\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\"><circle\n" -" fill=\"#a45c94\"\n" -" cx=\"100.3\"\n" -" cy=\"54.4\"\n" -" r=\"1.7\"\n" -" id=\"circle165\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\" /></g></g></g><g\n" -" id=\"g167\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\"><g\n" -" id=\"g169\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\"><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.5\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"119.7\"\n" -" y1=\"35.1\"\n" -" x2=\"100.2\"\n" -" y2=\"35.1\"\n" -" id=\"line171\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\" /><g\n" -" id=\"g173\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\"><circle\n" -" fill=\"#a45c94\"\n" -" cx=\"100.3\"\n" -" cy=\"35.1\"\n" -" r=\"1.7\"\n" -" id=\"circle175\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\" /></g></g></g></svg>"; - -const char* wizard_AudioPlugin_svg = (const char*) temp_binary_data_16; - -//================== wizard_ConsoleApp.svg ================== -static const unsigned char temp_binary_data_17[] = -"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" -"<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->\n" -"\n" -"<svg\n" -" xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n" -" xmlns:cc=\"http://creativecommons.org/ns#\"\n" -" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n" -" xmlns:svg=\"http://www.w3.org/2000/svg\"\n" -" xmlns=\"http://www.w3.org/2000/svg\"\n" -" xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\"\n" -" xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"\n" -" version=\"1.1\"\n" -" id=\"Layer_1\"\n" -" x=\"0px\"\n" -" y=\"0px\"\n" -" viewBox=\"0 0 136.9 114.8\"\n" -" enable-background=\"new 0 0 136.9 114.8\"\n" -" xml:space=\"preserve\"\n" -" inkscape:version=\"0.91 r13725\"\n" -" sodipodi:docname=\"wizard_ConsoleApp.svg\"><metadata\n" -" id=\"metadata25\"><rdf:RDF><cc:Work\n" -" rdf:about=\"\"><dc:format>image/svg+xml</dc:format><dc:type\n" -" rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\" /></cc:Work></rdf:RDF></metadata><defs\n" -" id=\"defs23\" /><sodipodi:namedview\n" -" pagecolor=\"#ffffff\"\n" -" bordercolor=\"#666666\"\n" -" borderopacity=\"1\"\n" -" objecttolerance=\"10\"\n" -" gridtolerance=\"10\"\n" -" guidetolerance=\"10\"\n" -" inkscape:pageopacity=\"0\"\n" -" inkscape:pageshadow=\"2\"\n" -" inkscape:window-width=\"1680\"\n" -" inkscape:window-height=\"1001\"\n" -" id=\"namedview21\"\n" -" showgrid=\"false\"\n" -" inkscape:zoom=\"2.0557491\"\n" -" inkscape:cx=\"68.449997\"\n" -" inkscape:cy=\"57.400002\"\n" -" inkscape:window-x=\"0\"\n" -" inkscape:window-y=\"1\"\n" -" inkscape:window-maximized=\"1\"\n" -" inkscape:current-layer=\"Layer_1\" /><path\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.3469\"\n" -" stroke-miterlimit=\"10\"\n" -" d=\"M130,114.8H6.9c-3.8,0-6.9-3.1-6.9-6.9V6.9 C0,3.1,3.1,0,6.9,0H130c3.8,0,6.9,3.1,6.9,6.9v101.1C136.9,111.7,133.9,114.8,130,114.8z\"\n" -" id=\"path3\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><g\n" -" id=\"Layer_1_22_\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\"><rect\n" -" x=\"16.3\"\n" -" y=\"10.9\"\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.3469\"\n" -" stroke-miterlimit=\"10\"\n" -" width=\"102.9\"\n" -" height=\"67.5\"\n" -" id=\"rect6\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><g\n" -" id=\"Layer_3_3_\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\"><g\n" -" opacity=\"0.8\"\n" -" id=\"g9\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\"><path\n" -" fill=\"#a45c94\"\n" -" d=\"M40.6,28.3l-14.4-6.6v-2.3l17.3,7.8v2.1l-17.3,7.8v-2.3L40.6,28.3z\"\n" -" id=\"path11\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\" /><path\n" -" fill=\"#a45c94\"\n" -" d=\"M62,39.5v1.7H45v-1.7H62z\"\n" -" id=\"path13\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\" /></g><g\n" -" id=\"g15\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\"><path\n" -" fill=\"#a45c94\"\n" -" d=\"M40.6,28.3l-14.4-6.6v-2.3l17.3,7.8v2.1l-17.3,7.8v-2.3L40.6,28.3z\"\n" -" id=\"path17\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\" /><path\n" -" fill=\"#a45c94\"\n" -" d=\"M62,39.5v1.7H45v-1.7H62z\"\n" -" id=\"path19\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\" /></g></g></svg>"; +" x1=\"118.8\"\n" +" y1=\"43.8\"\n" +" x2=\"118.8\"\n" +" y2=\"44.5\"\n" +" id=\"line131\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /></svg>"; -const char* wizard_ConsoleApp_svg = (const char*) temp_binary_data_17; +const char* wizard_AudioApp_svg = (const char*) temp_binary_data_21; -//================== wizard_DLL.svg ================== -static const unsigned char temp_binary_data_18[] = +//================== wizard_AudioPlugin.svg ================== +static const unsigned char temp_binary_data_22[] = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" "<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->\n" "\n" @@ -4384,11 +3863,11 @@ static const unsigned char temp_binary_data_18[] = " enable-background=\"new 0 0 136.9 114.8\"\n" " xml:space=\"preserve\"\n" " inkscape:version=\"0.91 r13725\"\n" -" sodipodi:docname=\"wizard_DLL.svg\"><metadata\n" -" id=\"metadata60\"><rdf:RDF><cc:Work\n" +" sodipodi:docname=\"wizard_AudioPlugin.svg\"><metadata\n" +" id=\"metadata181\"><rdf:RDF><cc:Work\n" " rdf:about=\"\"><dc:format>image/svg+xml</dc:format><dc:type\n" " rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\" /></cc:Work></rdf:RDF></metadata><defs\n" -" id=\"defs58\" /><sodipodi:namedview\n" +" id=\"defs179\" /><sodipodi:namedview\n" " pagecolor=\"#ffffff\"\n" " bordercolor=\"#666666\"\n" " borderopacity=\"1\"\n" @@ -4399,2457 +3878,2839 @@ static const unsigned char temp_binary_data_18[] = " inkscape:pageshadow=\"2\"\n" " inkscape:window-width=\"1680\"\n" " inkscape:window-height=\"1001\"\n" -" id=\"namedview56\"\n" -" showgrid=\"false\"\n" -" inkscape:zoom=\"2.0557491\"\n" -" inkscape:cx=\"68.449997\"\n" -" inkscape:cy=\"57.400002\"\n" +" id=\"namedview177\"\n" +" showgrid=\"false\"\n" +" inkscape:zoom=\"8.2229963\"\n" +" inkscape:cx=\"67.455426\"\n" +" inkscape:cy=\"64.924074\"\n" " inkscape:window-x=\"0\"\n" " inkscape:window-y=\"1\"\n" " inkscape:window-maximized=\"1\"\n" -" inkscape:current-layer=\"Layer_1\" /><path\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.3469\"\n" -" stroke-miterlimit=\"10\"\n" -" d=\"M130,114.9H6.9c-3.8,0-6.9-3.1-6.9-6.9V7 c0-3.8,3.1-6.9,6.9-6.9H130c3.8,0,6.9,3.1,6.9,6.9V108C136.9,111.8,133.9,114.9,130,114.9z\"\n" -" id=\"path3\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><g\n" -" id=\"Layer_1_19_\"\n" +" inkscape:current-layer=\"Layer_1\" /><g\n" +" id=\"Layer_1_23_\"\n" " style=\"stroke:#a45c94;stroke-opacity:1\"><rect\n" " x=\"16.3\"\n" -" y=\"11\"\n" +" y=\"10.9\"\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" " stroke-width=\"1.3469\"\n" " stroke-miterlimit=\"10\"\n" -" width=\"102.9\"\n" +" width=\"103.6\"\n" " height=\"67.5\"\n" -" id=\"rect6\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><g\n" -" id=\"g8\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\"><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"0.4307\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"39.6\"\n" -" y1=\"25\"\n" -" x2=\"39.6\"\n" -" y2=\"62.3\"\n" -" id=\"line10\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"0.4307\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"41.2\"\n" -" y1=\"25\"\n" -" x2=\"41.2\"\n" -" y2=\"62.3\"\n" -" id=\"line12\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"0.4307\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"42.8\"\n" -" y1=\"25\"\n" -" x2=\"42.8\"\n" -" y2=\"62.3\"\n" -" id=\"line14\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"0.4307\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"44.5\"\n" -" y1=\"25\"\n" -" x2=\"44.5\"\n" -" y2=\"62.3\"\n" -" id=\"line16\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"0.4307\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"46.1\"\n" -" y1=\"25\"\n" -" x2=\"46.1\"\n" -" y2=\"62.3\"\n" -" id=\"line18\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" id=\"rect4\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><rect\n" +" x=\"16.3\"\n" +" y=\"10.9\"\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.3469\"\n" +" stroke-miterlimit=\"10\"\n" +" width=\"103.6\"\n" +" height=\"2.4\"\n" +" id=\"rect6\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><path\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.3469\"\n" +" stroke-miterlimit=\"10\"\n" +" d=\"M130,114.8H6.9c-3.8,0-6.9-3.1-6.9-6.9V6.9 C0,3.1,3.1,0,6.9,0H130c3.8,0,6.9,3.1,6.9,6.9v101.1C136.9,111.7,133.9,114.8,130,114.8z\"\n" +" id=\"path8\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><g\n" +" id=\"Layer_1_8_\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\"><rect\n" +" x=\"35.7\"\n" +" y=\"23.6\"\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" -" stroke-width=\"0.4307\"\n" +" stroke-width=\"1.3469\"\n" " stroke-miterlimit=\"10\"\n" -" x1=\"47.7\"\n" -" y1=\"25\"\n" -" x2=\"47.7\"\n" -" y2=\"62.3\"\n" -" id=\"line20\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><path\n" +" width=\"64.4\"\n" +" height=\"42.3\"\n" +" id=\"rect11\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"36\"\n" +" y1=\"44.1\"\n" +" x2=\"36\"\n" +" y2=\"44.6\"\n" +" id=\"line13\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"37.1\"\n" +" y1=\"44\"\n" +" x2=\"37.1\"\n" +" y2=\"44.7\"\n" +" id=\"line15\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"38.1\"\n" +" y1=\"44.1\"\n" +" x2=\"38.1\"\n" +" y2=\"44.6\"\n" +" id=\"line17\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"39.2\"\n" +" y1=\"44\"\n" +" x2=\"39.2\"\n" +" y2=\"44.7\"\n" +" id=\"line19\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"40.2\"\n" +" y1=\"43.7\"\n" +" x2=\"40.2\"\n" +" y2=\"45\"\n" +" id=\"line21\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"41.3\"\n" +" y1=\"43.2\"\n" +" x2=\"41.3\"\n" +" y2=\"45.5\"\n" +" id=\"line23\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"42.3\"\n" +" y1=\"44.2\"\n" +" x2=\"42.3\"\n" +" y2=\"44.5\"\n" +" id=\"line25\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"43.3\"\n" +" y1=\"43.8\"\n" +" x2=\"43.3\"\n" +" y2=\"44.9\"\n" +" id=\"line27\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"44.4\"\n" +" y1=\"35.1\"\n" +" x2=\"44.4\"\n" +" y2=\"53.6\"\n" +" id=\"line29\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"45.4\"\n" +" y1=\"42.3\"\n" +" x2=\"45.4\"\n" +" y2=\"46.4\"\n" +" id=\"line31\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"46.5\"\n" +" y1=\"43.4\"\n" +" x2=\"46.5\"\n" +" y2=\"45.3\"\n" +" id=\"line33\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"47.5\"\n" +" y1=\"39.6\"\n" +" x2=\"47.5\"\n" +" y2=\"49.1\"\n" +" id=\"line35\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"48.6\"\n" +" y1=\"37.5\"\n" +" x2=\"48.6\"\n" +" y2=\"51.2\"\n" +" id=\"line37\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"49.6\"\n" +" y1=\"43.4\"\n" +" x2=\"49.6\"\n" +" y2=\"45.3\"\n" +" id=\"line39\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" -" stroke-width=\"1.0853\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" d=\"M49.9,23.9v38.6c0,0.9-0.7,1.6-1.6,1.6H39 c-0.9,0-1.6-0.7-1.6-1.6V23.9\"\n" -" id=\"path22\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><g\n" -" id=\"g24\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\"><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"0.4307\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"54.8\"\n" -" y1=\"27.5\"\n" -" x2=\"67.4\"\n" -" y2=\"62.6\"\n" -" id=\"line26\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"0.4307\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"56.3\"\n" -" y1=\"27\"\n" -" x2=\"69\"\n" -" y2=\"62\"\n" -" id=\"line28\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"0.4307\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"57.8\"\n" -" y1=\"26.4\"\n" -" x2=\"70.5\"\n" -" y2=\"61.5\"\n" -" id=\"line30\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"0.4307\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"59.4\"\n" -" y1=\"25.9\"\n" -" x2=\"72.1\"\n" -" y2=\"60.9\"\n" -" id=\"line32\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"0.4307\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"60.9\"\n" -" y1=\"25.3\"\n" -" x2=\"73.6\"\n" -" y2=\"60.4\"\n" -" id=\"line34\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"0.4307\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"62.4\"\n" -" y1=\"24.8\"\n" -" x2=\"75.1\"\n" -" y2=\"59.8\"\n" -" id=\"line36\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><path\n" +" x1=\"50.6\"\n" +" y1=\"40.1\"\n" +" x2=\"50.6\"\n" +" y2=\"48.6\"\n" +" id=\"line41\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" -" stroke-width=\"1.0853\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" d=\"M64.1,23l13.1,36.3c0.3,0.8-0.1,1.7-0.9,2 l-8.8,3.2c-0.8,0.3-1.7-0.1-2-0.9L52.4,27.2\"\n" -" id=\"path38\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><g\n" -" id=\"g40\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\"><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"0.4307\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"72.5\"\n" -" y1=\"30.6\"\n" -" x2=\"93.5\"\n" -" y2=\"61.4\"\n" -" id=\"line42\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"0.4307\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"73.8\"\n" -" y1=\"29.7\"\n" -" x2=\"94.9\"\n" -" y2=\"60.5\"\n" -" id=\"line44\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"0.4307\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"75.2\"\n" -" y1=\"28.8\"\n" -" x2=\"96.2\"\n" -" y2=\"59.6\"\n" -" id=\"line46\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"0.4307\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"76.5\"\n" -" y1=\"27.9\"\n" -" x2=\"97.6\"\n" -" y2=\"58.6\"\n" -" id=\"line48\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"0.4307\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"77.9\"\n" -" y1=\"27\"\n" -" x2=\"98.9\"\n" -" y2=\"57.7\"\n" -" id=\"line50\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"0.4307\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"79.2\"\n" -" y1=\"26\"\n" -" x2=\"100.3\"\n" -" y2=\"56.8\"\n" -" id=\"line52\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><path\n" +" x1=\"51.7\"\n" +" y1=\"33.9\"\n" +" x2=\"51.7\"\n" +" y2=\"54.9\"\n" +" id=\"line43\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" -" stroke-width=\"1.0853\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" d=\"M80.4,23.9l21.8,31.9c0.5,0.7,0.3,1.7-0.4,2.2 l-7.7,5.3c-0.7,0.5-1.7,0.3-2.2-0.4L70.1,31\"\n" -" id=\"path54\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /></svg>"; - -const char* wizard_DLL_svg = (const char*) temp_binary_data_18; - -//================== wizard_GUI.svg ================== -static const unsigned char temp_binary_data_19[] = -"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" -"<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->\n" -"\n" -"<svg\n" -" xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n" -" xmlns:cc=\"http://creativecommons.org/ns#\"\n" -" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n" -" xmlns:svg=\"http://www.w3.org/2000/svg\"\n" -" xmlns=\"http://www.w3.org/2000/svg\"\n" -" xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\"\n" -" xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"\n" -" version=\"1.1\"\n" -" id=\"Layer_1\"\n" -" x=\"0px\"\n" -" y=\"0px\"\n" -" viewBox=\"0 0 136.9 114.8\"\n" -" enable-background=\"new 0 0 136.9 114.8\"\n" -" xml:space=\"preserve\"\n" -" inkscape:version=\"0.91 r13725\"\n" -" sodipodi:docname=\"wizard_GUI.svg\"><metadata\n" -" id=\"metadata53\"><rdf:RDF><cc:Work\n" -" rdf:about=\"\"><dc:format>image/svg+xml</dc:format><dc:type\n" -" rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\" /></cc:Work></rdf:RDF></metadata><defs\n" -" id=\"defs51\" /><sodipodi:namedview\n" -" pagecolor=\"#ffffff\"\n" -" bordercolor=\"#666666\"\n" -" borderopacity=\"1\"\n" -" objecttolerance=\"10\"\n" -" gridtolerance=\"10\"\n" -" guidetolerance=\"10\"\n" -" inkscape:pageopacity=\"0\"\n" -" inkscape:pageshadow=\"2\"\n" -" inkscape:window-width=\"1680\"\n" -" inkscape:window-height=\"1001\"\n" -" id=\"namedview49\"\n" -" showgrid=\"false\"\n" -" inkscape:zoom=\"2.0557491\"\n" -" inkscape:cx=\"68.449997\"\n" -" inkscape:cy=\"57.400002\"\n" -" inkscape:window-x=\"0\"\n" -" inkscape:window-y=\"1\"\n" -" inkscape:window-maximized=\"1\"\n" -" inkscape:current-layer=\"Layer_1\" /><rect\n" -" x=\"16.3\"\n" -" y=\"10.9\"\n" +" x1=\"52.7\"\n" +" y1=\"41.3\"\n" +" x2=\"52.7\"\n" +" y2=\"47.4\"\n" +" id=\"line45\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"53.8\"\n" +" y1=\"42.5\"\n" +" x2=\"53.8\"\n" +" y2=\"46.3\"\n" +" id=\"line47\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"54.8\"\n" +" y1=\"43.4\"\n" +" x2=\"54.8\"\n" +" y2=\"45.3\"\n" +" id=\"line49\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"55.9\"\n" +" y1=\"39.4\"\n" +" x2=\"55.9\"\n" +" y2=\"49.3\"\n" +" id=\"line51\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"56.9\"\n" +" y1=\"43.3\"\n" +" x2=\"56.9\"\n" +" y2=\"45.4\"\n" +" id=\"line53\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" -" stroke-width=\"1.3469\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" width=\"103.6\"\n" -" height=\"67.5\"\n" -" id=\"rect3\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><path\n" +" x1=\"57.9\"\n" +" y1=\"41.3\"\n" +" x2=\"57.9\"\n" +" y2=\"47.4\"\n" +" id=\"line55\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" -" stroke-width=\"0.7078\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" d=\"M55.2,62.5H23.4c-0.4,0-0.7-0.4-0.7-0.9l0,0 c0-0.5,0.3-0.9,0.7-0.9h31.8c0.4,0,0.7,0.4,0.7,0.9l0,0C55.9,62.1,55.5,62.5,55.2,62.5z\"\n" -" id=\"path5\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><path\n" -" fill=\"#a45c94\"\n" -" d=\"M38.1,62.5H23.4c-0.4,0-0.7-0.4-0.7-0.9l0,0c0-0.5,0.3-0.9,0.7-0.9h14.7c0.4,0,0.7,0.4,0.7,0.9l0,0 C38.7,62.1,38.4,62.5,38.1,62.5z\"\n" -" id=\"path7\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\" /><path\n" +" x1=\"59\"\n" +" y1=\"38.5\"\n" +" x2=\"59\"\n" +" y2=\"50.2\"\n" +" id=\"line57\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" -" stroke-width=\"0.7078\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" d=\"M55.2,67.8H23.4c-0.4,0-0.7-0.4-0.7-0.9l0,0 c0-0.5,0.3-0.9,0.7-0.9h31.8c0.4,0,0.7,0.4,0.7,0.9l0,0C55.9,67.4,55.5,67.8,55.2,67.8z\"\n" -" id=\"path9\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><path\n" -" fill=\"#a45c94\"\n" -" d=\"M44.2,67.8H23.4c-0.4,0-0.7-0.4-0.7-0.9l0,0c0-0.5,0.3-0.9,0.7-0.9h20.8c0.4,0,0.7,0.4,0.7,0.9l0,0 C44.8,67.4,44.6,67.8,44.2,67.8z\"\n" -" id=\"path11\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\" /><path\n" +" x1=\"60\"\n" +" y1=\"43.1\"\n" +" x2=\"60\"\n" +" y2=\"45.6\"\n" +" id=\"line59\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" -" stroke-width=\"0.7078\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" d=\"M55.2,73H23.4c-0.4,0-0.7-0.4-0.7-0.9l0,0 c0-0.5,0.3-0.9,0.7-0.9h31.8c0.4,0,0.7,0.4,0.7,0.9l0,0C55.9,72.6,55.5,73,55.2,73z\"\n" -" id=\"path13\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><path\n" -" fill=\"#a45c94\"\n" -" d=\"M49.4,73h-26c-0.4,0-0.7-0.4-0.7-0.9l0,0c0-0.5,0.3-0.9,0.7-0.9h26c0.4,0,0.7,0.4,0.7,0.9l0,0 C50.1,72.6,49.8,73,49.4,73z\"\n" -" id=\"path15\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\" /><rect\n" -" x=\"16.3\"\n" -" y=\"10.9\"\n" +" x1=\"61.1\"\n" +" y1=\"42.4\"\n" +" x2=\"61.1\"\n" +" y2=\"46.3\"\n" +" id=\"line61\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" -" stroke-width=\"1.3469\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" width=\"103.6\"\n" -" height=\"2.4\"\n" -" id=\"rect17\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><circle\n" +" x1=\"62.1\"\n" +" y1=\"38.8\"\n" +" x2=\"62.1\"\n" +" y2=\"49.9\"\n" +" id=\"line63\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" -" stroke-width=\"1.3469\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" cx=\"69.3\"\n" -" cy=\"39.6\"\n" -" r=\"13.9\"\n" -" id=\"circle19\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><g\n" -" id=\"g21\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\"><g\n" -" id=\"g23\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\"><path\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.2523\"\n" -" stroke-miterlimit=\"10\"\n" -" d=\"M79.8,33.5c1.1,1.9,1.3,5.2,0,5.7 c-1.3,0.5-7.2,0.3-10.2,0.2c1.3-2.7,4.1-7.9,5.2-8.8C75.9,29.7,78.7,31.6,79.8,33.5z\"\n" -" id=\"path25\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><g\n" -" id=\"g27\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\"><path\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.2523\"\n" -" stroke-miterlimit=\"10\"\n" -" d=\"M79.8,45.6c-1.1,1.9-3.8,3.7-4.9,2.9 c-1.1-0.9-3.9-6.1-5.2-8.8c3-0.2,8.9-0.4,10.2,0.1C81.2,40.4,80.9,43.7,79.8,45.6z\"\n" -" id=\"path29\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><g\n" -" id=\"g31\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\"><path\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.2523\"\n" -" stroke-miterlimit=\"10\"\n" -" d=\"M69.3,51.7c-2.2,0-5.2-1.5-5-2.8 s3.3-6.4,5-8.9c1.7,2.5,4.8,7.5,5,8.9S71.5,51.7,69.3,51.7z\"\n" -" id=\"path33\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><g\n" -" id=\"g35\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\"><path\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.2523\"\n" -" stroke-miterlimit=\"10\"\n" -" d=\"M58.9,45.6c-1.1-1.9-1.3-5.2,0-5.7 c1.3-0.5,7.2-0.3,10.2-0.2c-1.3,2.7-4.1,7.9-5.2,8.8C62.8,49.4,60,47.6,58.9,45.6z\"\n" -" id=\"path37\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><g\n" -" id=\"g39\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\"><path\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.2523\"\n" -" stroke-miterlimit=\"10\"\n" -" d=\"M58.9,33.5c1.1-1.9,3.8-3.7,4.9-2.9 c1.1,0.9,3.9,6.1,5.2,8.8c-3,0.2-8.9,0.4-10.2-0.1C57.5,38.8,57.8,35.5,58.9,33.5z\"\n" -" id=\"path41\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><g\n" -" id=\"g43\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\"><path\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.2523\"\n" -" stroke-miterlimit=\"10\"\n" -" d=\"M69.3,27.5c2.2,0,5.2,1.5,5,2.8 s-3.3,6.4-5,8.9c-1.7-2.5-4.8-7.5-5-8.9S67.1,27.5,69.3,27.5z\"\n" -" id=\"path45\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /></g></g><path\n" +" x1=\"63.2\"\n" +" y1=\"37.1\"\n" +" x2=\"63.2\"\n" +" y2=\"51.6\"\n" +" id=\"line65\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" -" stroke-width=\"1.3469\"\n" -" stroke-miterlimit=\"10\"\n" -" d=\"M130,114.8H6.9c-3.8,0-6.9-3.1-6.9-6.9V6.9 C0,3.1,3.1,0,6.9,0H130c3.8,0,6.9,3.1,6.9,6.9v101.1C136.9,111.7,133.9,114.8,130,114.8z\"\n" -" id=\"path47\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /></svg>"; - -const char* wizard_GUI_svg = (const char*) temp_binary_data_19; - -//================== wizard_Highlight.svg ================== -static const unsigned char temp_binary_data_20[] = -"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" -"<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->\n" -"\n" -"<svg\n" -" xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n" -" xmlns:cc=\"http://creativecommons.org/ns#\"\n" -" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n" -" xmlns:svg=\"http://www.w3.org/2000/svg\"\n" -" xmlns=\"http://www.w3.org/2000/svg\"\n" -" xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\"\n" -" xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"\n" -" version=\"1.1\"\n" -" id=\"Layer_1\"\n" -" x=\"0px\"\n" -" y=\"0px\"\n" -" viewBox=\"0 0 136.9 114.8\"\n" -" enable-background=\"new 0 0 136.9 114.8\"\n" -" xml:space=\"preserve\"\n" -" inkscape:version=\"0.91 r13725\"\n" -" sodipodi:docname=\"wizard_Highlight.svg\"><metadata\n" -" id=\"metadata9\"><rdf:RDF><cc:Work\n" -" rdf:about=\"\"><dc:format>image/svg+xml</dc:format><dc:type\n" -" rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\" /></cc:Work></rdf:RDF></metadata><defs\n" -" id=\"defs7\" /><sodipodi:namedview\n" -" pagecolor=\"#ffffff\"\n" -" bordercolor=\"#666666\"\n" -" borderopacity=\"1\"\n" -" objecttolerance=\"10\"\n" -" gridtolerance=\"10\"\n" -" guidetolerance=\"10\"\n" -" inkscape:pageopacity=\"0\"\n" -" inkscape:pageshadow=\"2\"\n" -" inkscape:window-width=\"1680\"\n" -" inkscape:window-height=\"1001\"\n" -" id=\"namedview5\"\n" -" showgrid=\"false\"\n" -" inkscape:zoom=\"2.0557491\"\n" -" inkscape:cx=\"68.449997\"\n" -" inkscape:cy=\"57.400002\"\n" -" inkscape:window-x=\"0\"\n" -" inkscape:window-y=\"1\"\n" -" inkscape:window-maximized=\"1\"\n" -" inkscape:current-layer=\"Layer_1\" /><path\n" -" opacity=\"0.2\"\n" -" fill=\"#a45c94\"\n" -" d=\"M130.1,114.8H6.9c-3.8,0-6.9-3.1-6.9-6.9V6.9C0,3.1,3.1,0,6.9,0h123.2c3.8,0,6.9,3.1,6.9,6.9 V108C136.9,111.8,133.9,114.8,130.1,114.8z\"\n" -" id=\"path3\"\n" -" style=\"fill:#a45c94;fill-opacity:1\" /></svg>"; - -const char* wizard_Highlight_svg = (const char*) temp_binary_data_20; - -//================== wizard_Openfile.svg ================== -static const unsigned char temp_binary_data_21[] = -"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" -"<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->\n" -"\n" -"<svg\n" -" xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n" -" xmlns:cc=\"http://creativecommons.org/ns#\"\n" -" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n" -" xmlns:svg=\"http://www.w3.org/2000/svg\"\n" -" xmlns=\"http://www.w3.org/2000/svg\"\n" -" xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\"\n" -" xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"\n" -" version=\"1.1\"\n" -" id=\"Layer_1\"\n" -" x=\"0px\"\n" -" y=\"0px\"\n" -" viewBox=\"0 0 177.9 114.8\"\n" -" enable-background=\"new 0 0 177.9 114.8\"\n" -" xml:space=\"preserve\"\n" -" inkscape:version=\"0.91 r13725\"\n" -" sodipodi:docname=\"wizard_Openfile.svg\"><metadata\n" -" id=\"metadata9\"><rdf:RDF><cc:Work\n" -" rdf:about=\"\"><dc:format>image/svg+xml</dc:format><dc:type\n" -" rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\" /></cc:Work></rdf:RDF></metadata><defs\n" -" id=\"defs7\" /><sodipodi:namedview\n" -" pagecolor=\"#ffffff\"\n" -" bordercolor=\"#666666\"\n" -" borderopacity=\"1\"\n" -" objecttolerance=\"10\"\n" -" gridtolerance=\"10\"\n" -" guidetolerance=\"10\"\n" -" inkscape:pageopacity=\"0\"\n" -" inkscape:pageshadow=\"2\"\n" -" inkscape:window-width=\"1680\"\n" -" inkscape:window-height=\"1001\"\n" -" id=\"namedview5\"\n" -" showgrid=\"false\"\n" -" inkscape:zoom=\"1.7425521\"\n" -" inkscape:cx=\"88.949997\"\n" -" inkscape:cy=\"57.400002\"\n" -" inkscape:window-x=\"0\"\n" -" inkscape:window-y=\"1\"\n" -" inkscape:window-maximized=\"1\"\n" -" inkscape:current-layer=\"Layer_1\" /><path\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"64.2\"\n" +" y1=\"40.1\"\n" +" x2=\"64.2\"\n" +" y2=\"48.6\"\n" +" id=\"line67\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" -" stroke-width=\"1.3469\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" d=\"M164.7,71.4H13.2c-3.8,0-6.9-3.1-6.9-6.9V43.6 c0-3.8,3.1-6.9,6.9-6.9h151.5c3.8,0,6.9,3.1,6.9,6.9v20.9C171.6,68.3,168.5,71.4,164.7,71.4z\"\n" -" id=\"path3\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /></svg>"; - -const char* wizard_Openfile_svg = (const char*) temp_binary_data_21; - -//================== wizard_OpenGL.svg ================== -static const unsigned char temp_binary_data_22[] = -"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" -"<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->\n" -"\n" -"<svg\n" -" xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n" -" xmlns:cc=\"http://creativecommons.org/ns#\"\n" -" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n" -" xmlns:svg=\"http://www.w3.org/2000/svg\"\n" -" xmlns=\"http://www.w3.org/2000/svg\"\n" -" xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\"\n" -" xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"\n" -" version=\"1.1\"\n" -" id=\"Layer_1\"\n" -" x=\"0px\"\n" -" y=\"0px\"\n" -" viewBox=\"0 0 136.9 114.8\"\n" -" enable-background=\"new 0 0 136.9 114.8\"\n" -" xml:space=\"preserve\"\n" -" inkscape:version=\"0.91 r13725\"\n" -" sodipodi:docname=\"wizard_OpenGL.svg\"><metadata\n" -" id=\"metadata29\"><rdf:RDF><cc:Work\n" -" rdf:about=\"\"><dc:format>image/svg+xml</dc:format><dc:type\n" -" rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\" /></cc:Work></rdf:RDF></metadata><defs\n" -" id=\"defs27\" /><sodipodi:namedview\n" -" pagecolor=\"#ffffff\"\n" -" bordercolor=\"#666666\"\n" -" borderopacity=\"1\"\n" -" objecttolerance=\"10\"\n" -" gridtolerance=\"10\"\n" -" guidetolerance=\"10\"\n" -" inkscape:pageopacity=\"0\"\n" -" inkscape:pageshadow=\"2\"\n" -" inkscape:window-width=\"1680\"\n" -" inkscape:window-height=\"1001\"\n" -" id=\"namedview25\"\n" -" showgrid=\"false\"\n" -" inkscape:zoom=\"2.0557491\"\n" -" inkscape:cx=\"-16.190683\"\n" -" inkscape:cy=\"57.400002\"\n" -" inkscape:window-x=\"0\"\n" -" inkscape:window-y=\"1\"\n" -" inkscape:window-maximized=\"1\"\n" -" inkscape:current-layer=\"Layer_1\" /><rect\n" -" x=\"16.3\"\n" -" y=\"10.9\"\n" +" x1=\"65.2\"\n" +" y1=\"40.6\"\n" +" x2=\"65.2\"\n" +" y2=\"48.1\"\n" +" id=\"line69\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" -" stroke-width=\"1.3469\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" width=\"103.6\"\n" -" height=\"67.5\"\n" -" id=\"rect3\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><rect\n" -" x=\"16.3\"\n" -" y=\"10.9\"\n" +" x1=\"66.3\"\n" +" y1=\"43.1\"\n" +" x2=\"66.3\"\n" +" y2=\"45.6\"\n" +" id=\"line71\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" -" stroke-width=\"1.3469\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" width=\"103.6\"\n" -" height=\"2.4\"\n" -" id=\"rect5\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><path\n" +" x1=\"67.3\"\n" +" y1=\"41.1\"\n" +" x2=\"67.3\"\n" +" y2=\"47.6\"\n" +" id=\"line73\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" -" stroke-width=\"1.3469\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" d=\"M75.8,31.5c8.7,4.7,14.8,13.2,13.5,20 c-1.6,8.5-13.8,11.4-26.8,4.3S45.3,36.9,51.6,30.9C56.7,26.1,67.1,26.7,75.8,31.5z\"\n" -" id=\"path7\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><path\n" +" x1=\"68.4\"\n" +" y1=\"44\"\n" +" x2=\"68.4\"\n" +" y2=\"44.7\"\n" +" id=\"line75\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" -" stroke-width=\"1.3469\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" d=\"M86.1,43.6c1,2.4,0.5,5.5-1.3,5 c-1.9-0.5-9.8-5-13.8-7.4c2.9-1.2,8.2-3.2,9.8-3.2C82.2,38.2,85.2,41.4,86.1,43.6z\"\n" -" id=\"path9\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><path\n" +" x1=\"69.4\"\n" +" y1=\"42.6\"\n" +" x2=\"69.4\"\n" +" y2=\"46.1\"\n" +" id=\"line77\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" -" stroke-width=\"1.3469\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" d=\"M83,55.3c-2.3,1.3-7.3,1.2-8.6-0.7 c-1.2-1.9-2.9-9.5-3.5-12.9c4.2,2.1,12.2,6.3,13.8,7.7C86.3,50.7,85.2,54,83,55.3z\"\n" -" id=\"path11\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><path\n" +" x1=\"70.5\"\n" +" y1=\"41.1\"\n" +" x2=\"70.5\"\n" +" y2=\"47.6\"\n" +" id=\"line79\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" -" stroke-width=\"1.3469\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" d=\"M63.6,53.5c-3.6-2-7.3-6.3-5.9-7.6 c1.3-1.2,9-3.5,12.5-4.4c1.2,3.5,3.4,11.2,3.1,13C73,56.3,67.3,55.5,63.6,53.5z\"\n" -" id=\"path13\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><path\n" +" x1=\"71.5\"\n" +" y1=\"42.3\"\n" +" x2=\"71.5\"\n" +" y2=\"46.4\"\n" +" id=\"line81\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" -" stroke-width=\"1.3469\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" d=\"M51.9,38.3c-0.1-2.5,2-5.2,4.1-4.6 c2.1,0.6,9.9,5.1,13.9,7.5c-3.2,1.3-10.5,4.1-12.8,4.1C54.9,45.1,52,40.9,51.9,38.3z\"\n" -" id=\"path15\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><path\n" +" x1=\"72.5\"\n" +" y1=\"42.1\"\n" +" x2=\"72.5\"\n" +" y2=\"46.6\"\n" +" id=\"line83\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" -" stroke-width=\"1.3469\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" d=\"M60,29.3c2.4-0.4,6.6,0.3,7.5,1.5 c0.9,1.2,2.1,6.8,2.6,9.9c-4.2-2.1-12.3-6.3-13.7-7.6C55,31.8,57.4,29.8,60,29.3z\"\n" -" id=\"path17\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><path\n" +" x1=\"73.6\"\n" +" y1=\"40.8\"\n" +" x2=\"73.6\"\n" +" y2=\"47.9\"\n" +" id=\"line85\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" -" stroke-width=\"1.3469\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" d=\"M75.2,32.5c2.5,1.4,5.6,4.3,5,5 c-0.7,0.8-6.3,2.5-9.5,3.3c-1.1-3.2-2.7-8.9-2.4-9.9C68.6,30,72.6,31.1,75.2,32.5z\"\n" -" id=\"path19\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><path\n" +" x1=\"74.6\"\n" +" y1=\"43\"\n" +" x2=\"74.6\"\n" +" y2=\"45.7\"\n" +" id=\"line87\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" -" stroke-width=\"1.3469\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" d=\"M130,114.8H6.9c-3.8,0-6.9-3.1-6.9-6.9V6.9 C0,3.1,3.1,0,6.9,0H130c3.8,0,6.9,3.1,6.9,6.9v101.1C136.9,111.7,133.9,114.8,130,114.8z\"\n" -" id=\"path21\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><path\n" +" x1=\"75.7\"\n" +" y1=\"43.1\"\n" +" x2=\"75.7\"\n" +" y2=\"45.6\"\n" +" id=\"line89\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" -" stroke-width=\"1.3469\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" d=\"M87.4,55.5c-6.6,10.4-20.4,14.6-30.8,8 s-13.4-19.6-6.9-30\"\n" -" id=\"path23\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /></svg>"; - -const char* wizard_OpenGL_svg = (const char*) temp_binary_data_22; - -//================== wizard_StaticLibrary.svg ================== -static const unsigned char temp_binary_data_23[] = -"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" -"<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->\n" -"\n" -"<svg\n" -" xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n" -" xmlns:cc=\"http://creativecommons.org/ns#\"\n" -" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n" -" xmlns:svg=\"http://www.w3.org/2000/svg\"\n" -" xmlns=\"http://www.w3.org/2000/svg\"\n" -" xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\"\n" -" xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"\n" -" version=\"1.1\"\n" -" id=\"Layer_1\"\n" -" x=\"0px\"\n" -" y=\"0px\"\n" -" viewBox=\"0 0 136.9 114.8\"\n" -" enable-background=\"new 0 0 136.9 114.8\"\n" -" xml:space=\"preserve\"\n" -" inkscape:version=\"0.91 r13725\"\n" -" sodipodi:docname=\"wizard_StaticLibrary.svg\"><metadata\n" -" id=\"metadata60\"><rdf:RDF><cc:Work\n" -" rdf:about=\"\"><dc:format>image/svg+xml</dc:format><dc:type\n" -" rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\" /></cc:Work></rdf:RDF></metadata><defs\n" -" id=\"defs58\" /><sodipodi:namedview\n" -" pagecolor=\"#ffffff\"\n" -" bordercolor=\"#666666\"\n" -" borderopacity=\"1\"\n" -" objecttolerance=\"10\"\n" -" gridtolerance=\"10\"\n" -" guidetolerance=\"10\"\n" -" inkscape:pageopacity=\"0\"\n" -" inkscape:pageshadow=\"2\"\n" -" inkscape:window-width=\"1680\"\n" -" inkscape:window-height=\"1001\"\n" -" id=\"namedview56\"\n" -" showgrid=\"false\"\n" -" inkscape:zoom=\"2.0557491\"\n" -" inkscape:cx=\"68.449997\"\n" -" inkscape:cy=\"57.400002\"\n" -" inkscape:window-x=\"0\"\n" -" inkscape:window-y=\"1\"\n" -" inkscape:window-maximized=\"1\"\n" -" inkscape:current-layer=\"Layer_1\" /><path\n" +" x1=\"76.7\"\n" +" y1=\"44\"\n" +" x2=\"76.7\"\n" +" y2=\"44.7\"\n" +" id=\"line91\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"77.8\"\n" +" y1=\"43.4\"\n" +" x2=\"77.8\"\n" +" y2=\"45.3\"\n" +" id=\"line93\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" -" stroke-width=\"1.3469\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" d=\"M130,114.8H6.9c-3.8,0-6.9-3.1-6.9-6.9V6.9 C0,3,3.1,0,6.9,0H130c3.8,0,6.9,3.1,6.9,6.9v101.1C136.9,111.7,133.9,114.8,130,114.8z\"\n" -" id=\"path3\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><g\n" -" id=\"Layer_1_21_\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\"><rect\n" -" x=\"16.3\"\n" -" y=\"10.9\"\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"1.3469\"\n" -" stroke-miterlimit=\"10\"\n" -" width=\"102.9\"\n" -" height=\"67.5\"\n" -" id=\"rect6\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><g\n" -" id=\"g8\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\"><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"0.4942\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"43.1\"\n" -" y1=\"22.1\"\n" -" x2=\"43.1\"\n" -" y2=\"64.9\"\n" -" id=\"line10\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"0.4942\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"45\"\n" -" y1=\"22.1\"\n" -" x2=\"45\"\n" -" y2=\"64.9\"\n" -" id=\"line12\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"0.4942\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"46.8\"\n" -" y1=\"22.1\"\n" -" x2=\"46.8\"\n" -" y2=\"64.9\"\n" -" id=\"line14\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"0.4942\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"48.7\"\n" -" y1=\"22.1\"\n" -" x2=\"48.7\"\n" -" y2=\"64.9\"\n" -" id=\"line16\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"0.4942\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"50.6\"\n" -" y1=\"22.1\"\n" -" x2=\"50.6\"\n" -" y2=\"64.9\"\n" -" id=\"line18\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"0.4942\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"52.5\"\n" -" y1=\"22.1\"\n" -" x2=\"52.5\"\n" -" y2=\"64.9\"\n" -" id=\"line20\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><path\n" +" x1=\"78.8\"\n" +" y1=\"43.8\"\n" +" x2=\"78.8\"\n" +" y2=\"44.9\"\n" +" id=\"line95\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" -" stroke-width=\"1.2453\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" d=\"M54.9,20.8v44.3c0,1-0.8,1.8-1.8,1.8H42.4 c-1,0-1.8-0.8-1.8-1.8V20.8\"\n" -" id=\"path22\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><g\n" -" id=\"g24\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\"><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"0.4942\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"64.5\"\n" -" y1=\"22.1\"\n" -" x2=\"64.5\"\n" -" y2=\"64.9\"\n" -" id=\"line26\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"0.4942\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"66.4\"\n" -" y1=\"22.1\"\n" -" x2=\"66.4\"\n" -" y2=\"64.9\"\n" -" id=\"line28\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"0.4942\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"68.3\"\n" -" y1=\"22.1\"\n" -" x2=\"68.3\"\n" -" y2=\"64.9\"\n" -" id=\"line30\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"0.4942\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"70.1\"\n" -" y1=\"22.1\"\n" -" x2=\"70.1\"\n" -" y2=\"64.9\"\n" -" id=\"line32\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"0.4942\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"72\"\n" -" y1=\"22.1\"\n" -" x2=\"72\"\n" -" y2=\"64.9\"\n" -" id=\"line34\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"0.4942\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"73.9\"\n" -" y1=\"22.1\"\n" -" x2=\"73.9\"\n" -" y2=\"64.9\"\n" -" id=\"line36\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><path\n" +" x1=\"79.9\"\n" +" y1=\"41.7\"\n" +" x2=\"79.9\"\n" +" y2=\"47\"\n" +" id=\"line97\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" -" stroke-width=\"1.2453\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" d=\"M76.4,20.8v44.3c0,1-0.8,1.8-1.8,1.8H63.8 c-1,0-1.8-0.8-1.8-1.8V20.8\"\n" -" id=\"path38\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><g\n" -" id=\"g40\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\"><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"0.4942\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"85.9\"\n" -" y1=\"22.1\"\n" -" x2=\"85.9\"\n" -" y2=\"64.9\"\n" -" id=\"line42\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"0.4942\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"87.8\"\n" -" y1=\"22.1\"\n" -" x2=\"87.8\"\n" -" y2=\"64.9\"\n" -" id=\"line44\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"0.4942\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"89.7\"\n" -" y1=\"22.1\"\n" -" x2=\"89.7\"\n" -" y2=\"64.9\"\n" -" id=\"line46\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"0.4942\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"91.6\"\n" -" y1=\"22.1\"\n" -" x2=\"91.6\"\n" -" y2=\"64.9\"\n" -" id=\"line48\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"0.4942\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"93.4\"\n" -" y1=\"22.1\"\n" -" x2=\"93.4\"\n" -" y2=\"64.9\"\n" -" id=\"line50\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" -" fill=\"none\"\n" -" stroke=\"#a45c94\"\n" -" stroke-width=\"0.4942\"\n" -" stroke-miterlimit=\"10\"\n" -" x1=\"95.3\"\n" -" y1=\"22.1\"\n" -" x2=\"95.3\"\n" -" y2=\"64.9\"\n" -" id=\"line52\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><path\n" +" x1=\"80.9\"\n" +" y1=\"43.6\"\n" +" x2=\"80.9\"\n" +" y2=\"45.2\"\n" +" id=\"line99\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"81.9\"\n" +" y1=\"44\"\n" +" x2=\"81.9\"\n" +" y2=\"44.7\"\n" +" id=\"line101\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"83\"\n" +" y1=\"44\"\n" +" x2=\"83\"\n" +" y2=\"44.7\"\n" +" id=\"line103\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" " fill=\"none\"\n" " stroke=\"#a45c94\"\n" -" stroke-width=\"1.2453\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" " stroke-miterlimit=\"10\"\n" -" d=\"M97.8,20.8v44.3c0,1-0.8,1.8-1.8,1.8H85.3 c-1,0-1.8-0.8-1.8-1.8V20.8\"\n" -" id=\"path54\"\n" -" style=\"stroke:#a45c94;stroke-opacity:1\" /></svg>"; - -const char* wizard_StaticLibrary_svg = (const char*) temp_binary_data_23; - -//================== jucer_AnimatedComponentSimpleTemplate.h ================== -static const unsigned char temp_binary_data_24[] = -"/*\r\n" -" ==============================================================================\r\n" -"\r\n" -" This file was auto-generated!\r\n" -"\r\n" -" ==============================================================================\r\n" -"*/\r\n" -"\r\n" -"#pragma once\r\n" -"\r\n" -"%%include_juce%%\r\n" -"\r\n" -"//==============================================================================\r\n" -"/*\r\n" -" This component lives inside our window, and this is where you should put all\r\n" -" your controls and content.\r\n" -"*/\r\n" -"class %%content_component_class%% : public AnimatedAppComponent\r\n" -"{\r\n" -"public:\r\n" -" //==============================================================================\r\n" -" %%content_component_class%%()\r\n" -" {\r\n" -" // Make sure you set the size of the component after\r\n" -" // you add any child components.\r\n" -" setSize (800, 600);\r\n" -" setFramesPerSecond (60); // This sets the frequency of the update calls.\r\n" -" }\r\n" -"\r\n" -" ~%%content_component_class%%()\r\n" -" {\r\n" -" }\r\n" -"\r\n" -" //==============================================================================\r\n" -" void update() override\r\n" -" {\r\n" -" // This function is called at the frequency specified by the setFramesPerSecond() call\r\n" -" // in the constructor. You can use it to update counters, animate values, etc.\r\n" -" }\r\n" -"\r\n" -" //==============================================================================\r\n" -" void paint (Graphics& g) override\r\n" -" {\r\n" -" // (Our component is opaque, so we must completely fill the background with a solid colour)\r\n" -" g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId));\r\n" -"\r\n" -" // You can add your drawing code here!\r\n" -" }\r\n" -"\r\n" -" void resized() override\r\n" -" {\r\n" -" // This is called when the MainContentComponent is resized.\r\n" -" // If you add any child components, this is where you should\r\n" -" // update their positions.\r\n" -" }\r\n" -"\r\n" -"\r\n" -"private:\r\n" -" //==============================================================================\r\n" -" // Your private member variables go here...\r\n" -"\r\n" -"\r\n" -" JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%content_component_class%%)\r\n" -"};\r\n"; - -const char* jucer_AnimatedComponentSimpleTemplate_h = (const char*) temp_binary_data_24; - -//================== jucer_AnimatedComponentTemplate.cpp ================== -static const unsigned char temp_binary_data_25[] = -"/*\r\n" -" ==============================================================================\r\n" -"\r\n" -" This file was auto-generated!\r\n" -"\r\n" -" ==============================================================================\r\n" -"*/\r\n" -"\r\n" -"%%include_corresponding_header%%\r\n" -"\r\n" -"//==============================================================================\r\n" -"%%content_component_class%%::%%content_component_class%%()\r\n" -"{\r\n" -" // Make sure you set the size of the component after\r\n" -" // you add any child components.\r\n" -" setSize (800, 600);\r\n" -" setFramesPerSecond (60); // This sets the frequency of the update calls.\r\n" -"}\r\n" -"\r\n" -"%%content_component_class%%::~%%content_component_class%%()\r\n" -"{\r\n" -"}\r\n" -"\r\n" -"//==============================================================================\r\n" -"void %%content_component_class%%::update()\r\n" -"{\r\n" -" // This function is called at the frequency specified by the setFramesPerSecond() call\r\n" -" // in the constructor. You can use it to update counters, animate values, etc.\r\n" -"}\r\n" -"\r\n" -"//==============================================================================\r\n" -"void %%content_component_class%%::paint (Graphics& g)\r\n" -"{\r\n" -" // (Our component is opaque, so we must completely fill the background with a solid colour)\r\n" -" g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId));\r\n" -"\r\n" -" // You can add your drawing code here!\r\n" -"}\r\n" -"\r\n" -"void %%content_component_class%%::resized()\r\n" -"{\r\n" -" // This is called when the MainContentComponent is resized.\r\n" -" // If you add any child components, this is where you should\r\n" -" // update their positions.\r\n" -"}\r\n"; - -const char* jucer_AnimatedComponentTemplate_cpp = (const char*) temp_binary_data_25; - -//================== jucer_AnimatedComponentTemplate.h ================== -static const unsigned char temp_binary_data_26[] = -"/*\r\n" -" ==============================================================================\r\n" -"\r\n" -" This file was auto-generated!\r\n" -"\r\n" -" ==============================================================================\r\n" -"*/\r\n" -"\r\n" -"#pragma once\r\n" -"\r\n" -"%%include_juce%%\r\n" -"\r\n" -"//==============================================================================\r\n" -"/*\r\n" -" This component lives inside our window, and this is where you should put all\r\n" -" your controls and content.\r\n" -"*/\r\n" -"class %%content_component_class%% : public AnimatedAppComponent\r\n" -"{\r\n" -"public:\r\n" -" //==============================================================================\r\n" -" %%content_component_class%%();\r\n" -" ~%%content_component_class%%();\r\n" -"\r\n" -" //==============================================================================\r\n" -" void update() override;\r\n" -"\r\n" -" //==============================================================================\r\n" -" void paint (Graphics& g) override;\r\n" -" void resized() override;\r\n" -"\r\n" -"private:\r\n" -" //==============================================================================\r\n" -" // Your private member variables go here...\r\n" -"\r\n" -"\r\n" -" JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%content_component_class%%)\r\n" -"};\r\n"; - -const char* jucer_AnimatedComponentTemplate_h = (const char*) temp_binary_data_26; - -//================== jucer_AudioComponentSimpleTemplate.h ================== -static const unsigned char temp_binary_data_27[] = -"/*\r\n" -" ==============================================================================\r\n" -"\r\n" -" This file was auto-generated!\r\n" -"\r\n" -" ==============================================================================\r\n" -"*/\r\n" -"\r\n" -"#pragma once\r\n" -"\r\n" -"%%include_juce%%\r\n" -"\r\n" -"//==============================================================================\r\n" -"/*\r\n" -" This component lives inside our window, and this is where you should put all\r\n" -" your controls and content.\r\n" -"*/\r\n" -"class %%content_component_class%% : public AudioAppComponent\r\n" -"{\r\n" -"public:\r\n" -" //==============================================================================\r\n" -" %%content_component_class%%()\r\n" -" {\r\n" -" // Make sure you set the size of the component after\r\n" -" // you add any child components.\r\n" -" setSize (800, 600);\r\n" -"\r\n" -" // Some platforms require permissions to open input channels so request that here\r\n" -" if (RuntimePermissions::isRequired (RuntimePermissions::recordAudio)\r\n" -" && ! RuntimePermissions::isGranted (RuntimePermissions::recordAudio))\r\n" -" {\r\n" -" RuntimePermissions::request (RuntimePermissions::recordAudio,\r\n" -" [&] (bool granted) { if (granted) setAudioChannels (2, 2); });\r\n" -" }\r\n" -" else\r\n" -" {\r\n" -" // Specify the number of input and output channels that we want to open\r\n" -" setAudioChannels (2, 2);\r\n" -" }\r\n" -" }\r\n" -"\r\n" -" ~%%content_component_class%%()\r\n" -" {\r\n" -" // This shuts down the audio device and clears the audio source.\r\n" -" shutdownAudio();\r\n" -" }\r\n" -"\r\n" -" //==============================================================================\r\n" -" void prepareToPlay (int samplesPerBlockExpected, double sampleRate) override\r\n" -" {\r\n" -" // This function will be called when the audio device is started, or when\r\n" -" // its settings (i.e. sample rate, block size, etc) are changed.\r\n" -"\r\n" -" // You can use this function to initialise any resources you might need,\r\n" -" // but be careful - it will be called on the audio thread, not the GUI thread.\r\n" -"\r\n" -" // For more details, see the help for AudioProcessor::prepareToPlay()\r\n" -" }\r\n" -"\r\n" -" void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) override\r\n" -" {\r\n" -" // Your audio-processing code goes here!\r\n" -"\r\n" -" // For more details, see the help for AudioProcessor::getNextAudioBlock()\r\n" -"\r\n" -" // Right now we are not producing any data, in which case we need to clear the buffer\r\n" -" // (to prevent the output of random noise)\r\n" -" bufferToFill.clearActiveBufferRegion();\r\n" -" }\r\n" -"\r\n" -" void releaseResources() override\r\n" -" {\r\n" -" // This will be called when the audio device stops, or when it is being\r\n" -" // restarted due to a setting change.\r\n" -"\r\n" -" // For more details, see the help for AudioProcessor::releaseResources()\r\n" -" }\r\n" -"\r\n" -" //==============================================================================\r\n" -" void paint (Graphics& g) override\r\n" -" {\r\n" -" // (Our component is opaque, so we must completely fill the background with a solid colour)\r\n" -" g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId));\r\n" -"\r\n" -" // You can add your drawing code here!\r\n" -" }\r\n" -"\r\n" -" void resized() override\r\n" -" {\r\n" -" // This is called when the MainContentComponent is resized.\r\n" -" // If you add any child components, this is where you should\r\n" -" // update their positions.\r\n" -" }\r\n" -"\r\n" -"\r\n" -"private:\r\n" -" //==============================================================================\r\n" -" // Your private member variables go here...\r\n" -"\r\n" -"\r\n" -" JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%content_component_class%%)\r\n" -"};\r\n"; +" x1=\"84\"\n" +" y1=\"43.4\"\n" +" x2=\"84\"\n" +" y2=\"45.3\"\n" +" id=\"line105\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"85.1\"\n" +" y1=\"42.5\"\n" +" x2=\"85.1\"\n" +" y2=\"46.3\"\n" +" id=\"line107\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"86.1\"\n" +" y1=\"43.5\"\n" +" x2=\"86.1\"\n" +" y2=\"45.2\"\n" +" id=\"line109\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"87.2\"\n" +" y1=\"44\"\n" +" x2=\"87.2\"\n" +" y2=\"44.7\"\n" +" id=\"line111\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"88.2\"\n" +" y1=\"43.7\"\n" +" x2=\"88.2\"\n" +" y2=\"45\"\n" +" id=\"line113\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"89.2\"\n" +" y1=\"44\"\n" +" x2=\"89.2\"\n" +" y2=\"44.7\"\n" +" id=\"line115\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"90.3\"\n" +" y1=\"43\"\n" +" x2=\"90.3\"\n" +" y2=\"45.7\"\n" +" id=\"line117\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"91.3\"\n" +" y1=\"44\"\n" +" x2=\"91.3\"\n" +" y2=\"44.7\"\n" +" id=\"line119\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"92.4\"\n" +" y1=\"44.2\"\n" +" x2=\"92.4\"\n" +" y2=\"44.6\"\n" +" id=\"line121\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"93.4\"\n" +" y1=\"44\"\n" +" x2=\"93.4\"\n" +" y2=\"44.7\"\n" +" id=\"line123\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"94.5\"\n" +" y1=\"44\"\n" +" x2=\"94.5\"\n" +" y2=\"44.7\"\n" +" id=\"line125\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"95.5\"\n" +" y1=\"43.4\"\n" +" x2=\"95.5\"\n" +" y2=\"45.3\"\n" +" id=\"line127\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"96.5\"\n" +" y1=\"43.7\"\n" +" x2=\"96.5\"\n" +" y2=\"45\"\n" +" id=\"line129\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"97.6\"\n" +" y1=\"44\"\n" +" x2=\"97.6\"\n" +" y2=\"44.7\"\n" +" id=\"line131\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"98.6\"\n" +" y1=\"44.2\"\n" +" x2=\"98.6\"\n" +" y2=\"44.6\"\n" +" id=\"line133\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-linecap=\"round\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"99.7\"\n" +" y1=\"44.2\"\n" +" x2=\"99.7\"\n" +" y2=\"44.6\"\n" +" id=\"line135\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><g\n" +" id=\"g137\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\"><g\n" +" id=\"g139\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\"><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"16.3\"\n" +" y1=\"35.1\"\n" +" x2=\"35.8\"\n" +" y2=\"35.1\"\n" +" id=\"line141\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\" /><g\n" +" id=\"g143\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\"><circle\n" +" fill=\"#a45c94\"\n" +" cx=\"35.7\"\n" +" cy=\"35.1\"\n" +" r=\"1.7\"\n" +" id=\"circle145\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\" /></g></g></g><g\n" +" id=\"g147\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\"><g\n" +" id=\"g149\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\"><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"16.3\"\n" +" y1=\"54.4\"\n" +" x2=\"35.8\"\n" +" y2=\"54.4\"\n" +" id=\"line151\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\" /><g\n" +" id=\"g153\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\"><circle\n" +" fill=\"#a45c94\"\n" +" cx=\"35.7\"\n" +" cy=\"54.4\"\n" +" r=\"1.7\"\n" +" id=\"circle155\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\" /></g></g></g><g\n" +" id=\"g157\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\"><g\n" +" id=\"g159\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\"><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"119.7\"\n" +" y1=\"54.4\"\n" +" x2=\"100.2\"\n" +" y2=\"54.4\"\n" +" id=\"line161\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\" /><g\n" +" id=\"g163\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\"><circle\n" +" fill=\"#a45c94\"\n" +" cx=\"100.3\"\n" +" cy=\"54.4\"\n" +" r=\"1.7\"\n" +" id=\"circle165\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\" /></g></g></g><g\n" +" id=\"g167\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\"><g\n" +" id=\"g169\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\"><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.5\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"119.7\"\n" +" y1=\"35.1\"\n" +" x2=\"100.2\"\n" +" y2=\"35.1\"\n" +" id=\"line171\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\" /><g\n" +" id=\"g173\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\"><circle\n" +" fill=\"#a45c94\"\n" +" cx=\"100.3\"\n" +" cy=\"35.1\"\n" +" r=\"1.7\"\n" +" id=\"circle175\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\" /></g></g></g></svg>"; -const char* jucer_AudioComponentSimpleTemplate_h = (const char*) temp_binary_data_27; +const char* wizard_AudioPlugin_svg = (const char*) temp_binary_data_22; -//================== jucer_AudioComponentTemplate.cpp ================== -static const unsigned char temp_binary_data_28[] = -"/*\r\n" -" ==============================================================================\r\n" -"\r\n" -" This file was auto-generated!\r\n" -"\r\n" -" ==============================================================================\r\n" -"*/\r\n" -"\r\n" -"%%include_corresponding_header%%\r\n" -"\r\n" -"//==============================================================================\r\n" -"%%content_component_class%%::%%content_component_class%%()\r\n" -"{\r\n" -" // Make sure you set the size of the component after\r\n" -" // you add any child components.\r\n" -" setSize (800, 600);\r\n" -"\r\n" -" // Some platforms require permissions to open input channels so request that here\r\n" -" if (RuntimePermissions::isRequired (RuntimePermissions::recordAudio)\r\n" -" && ! RuntimePermissions::isGranted (RuntimePermissions::recordAudio))\r\n" -" {\r\n" -" RuntimePermissions::request (RuntimePermissions::recordAudio,\r\n" -" [&] (bool granted) { if (granted) setAudioChannels (2, 2); });\r\n" -" }\r\n" -" else\r\n" -" {\r\n" -" // Specify the number of input and output channels that we want to open\r\n" -" setAudioChannels (2, 2);\r\n" -" }\r\n" -"}\r\n" -"\r\n" -"%%content_component_class%%::~%%content_component_class%%()\r\n" -"{\r\n" -" // This shuts down the audio device and clears the audio source.\r\n" -" shutdownAudio();\r\n" -"}\r\n" -"\r\n" -"//==============================================================================\r\n" -"void %%content_component_class%%::prepareToPlay (int samplesPerBlockExpected, double sampleRate)\r\n" -"{\r\n" -" // This function will be called when the audio device is started, or when\r\n" -" // its settings (i.e. sample rate, block size, etc) are changed.\r\n" -"\r\n" -" // You can use this function to initialise any resources you might need,\r\n" -" // but be careful - it will be called on the audio thread, not the GUI thread.\r\n" -"\r\n" -" // For more details, see the help for AudioProcessor::prepareToPlay()\r\n" -"}\r\n" -"\r\n" -"void %%content_component_class%%::getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill)\r\n" -"{\r\n" -" // Your audio-processing code goes here!\r\n" -"\r\n" -" // For more details, see the help for AudioProcessor::getNextAudioBlock()\r\n" -"\r\n" -" // Right now we are not producing any data, in which case we need to clear the buffer\r\n" -" // (to prevent the output of random noise)\r\n" -" bufferToFill.clearActiveBufferRegion();\r\n" -"}\r\n" -"\r\n" -"void %%content_component_class%%::releaseResources()\r\n" -"{\r\n" -" // This will be called when the audio device stops, or when it is being\r\n" -" // restarted due to a setting change.\r\n" -"\r\n" -" // For more details, see the help for AudioProcessor::releaseResources()\r\n" -"}\r\n" -"\r\n" -"//==============================================================================\r\n" -"void %%content_component_class%%::paint (Graphics& g)\r\n" -"{\r\n" -" // (Our component is opaque, so we must completely fill the background with a solid colour)\r\n" -" g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId));\r\n" -"\r\n" -" // You can add your drawing code here!\r\n" -"}\r\n" -"\r\n" -"void %%content_component_class%%::resized()\r\n" -"{\r\n" -" // This is called when the MainContentComponent is resized.\r\n" -" // If you add any child components, this is where you should\r\n" -" // update their positions.\r\n" -"}\r\n"; +//================== wizard_ConsoleApp.svg ================== +static const unsigned char temp_binary_data_23[] = +"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" +"<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->\n" +"\n" +"<svg\n" +" xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n" +" xmlns:cc=\"http://creativecommons.org/ns#\"\n" +" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n" +" xmlns:svg=\"http://www.w3.org/2000/svg\"\n" +" xmlns=\"http://www.w3.org/2000/svg\"\n" +" xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\"\n" +" xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"\n" +" version=\"1.1\"\n" +" id=\"Layer_1\"\n" +" x=\"0px\"\n" +" y=\"0px\"\n" +" viewBox=\"0 0 136.9 114.8\"\n" +" enable-background=\"new 0 0 136.9 114.8\"\n" +" xml:space=\"preserve\"\n" +" inkscape:version=\"0.91 r13725\"\n" +" sodipodi:docname=\"wizard_ConsoleApp.svg\"><metadata\n" +" id=\"metadata25\"><rdf:RDF><cc:Work\n" +" rdf:about=\"\"><dc:format>image/svg+xml</dc:format><dc:type\n" +" rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\" /></cc:Work></rdf:RDF></metadata><defs\n" +" id=\"defs23\" /><sodipodi:namedview\n" +" pagecolor=\"#ffffff\"\n" +" bordercolor=\"#666666\"\n" +" borderopacity=\"1\"\n" +" objecttolerance=\"10\"\n" +" gridtolerance=\"10\"\n" +" guidetolerance=\"10\"\n" +" inkscape:pageopacity=\"0\"\n" +" inkscape:pageshadow=\"2\"\n" +" inkscape:window-width=\"1680\"\n" +" inkscape:window-height=\"1001\"\n" +" id=\"namedview21\"\n" +" showgrid=\"false\"\n" +" inkscape:zoom=\"2.0557491\"\n" +" inkscape:cx=\"68.449997\"\n" +" inkscape:cy=\"57.400002\"\n" +" inkscape:window-x=\"0\"\n" +" inkscape:window-y=\"1\"\n" +" inkscape:window-maximized=\"1\"\n" +" inkscape:current-layer=\"Layer_1\" /><path\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.3469\"\n" +" stroke-miterlimit=\"10\"\n" +" d=\"M130,114.8H6.9c-3.8,0-6.9-3.1-6.9-6.9V6.9 C0,3.1,3.1,0,6.9,0H130c3.8,0,6.9,3.1,6.9,6.9v101.1C136.9,111.7,133.9,114.8,130,114.8z\"\n" +" id=\"path3\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><g\n" +" id=\"Layer_1_22_\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\"><rect\n" +" x=\"16.3\"\n" +" y=\"10.9\"\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.3469\"\n" +" stroke-miterlimit=\"10\"\n" +" width=\"102.9\"\n" +" height=\"67.5\"\n" +" id=\"rect6\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><g\n" +" id=\"Layer_3_3_\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\"><g\n" +" opacity=\"0.8\"\n" +" id=\"g9\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\"><path\n" +" fill=\"#a45c94\"\n" +" d=\"M40.6,28.3l-14.4-6.6v-2.3l17.3,7.8v2.1l-17.3,7.8v-2.3L40.6,28.3z\"\n" +" id=\"path11\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\" /><path\n" +" fill=\"#a45c94\"\n" +" d=\"M62,39.5v1.7H45v-1.7H62z\"\n" +" id=\"path13\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\" /></g><g\n" +" id=\"g15\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\"><path\n" +" fill=\"#a45c94\"\n" +" d=\"M40.6,28.3l-14.4-6.6v-2.3l17.3,7.8v2.1l-17.3,7.8v-2.3L40.6,28.3z\"\n" +" id=\"path17\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\" /><path\n" +" fill=\"#a45c94\"\n" +" d=\"M62,39.5v1.7H45v-1.7H62z\"\n" +" id=\"path19\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\" /></g></g></svg>"; + +const char* wizard_ConsoleApp_svg = (const char*) temp_binary_data_23; + +//================== wizard_DLL.svg ================== +static const unsigned char temp_binary_data_24[] = +"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" +"<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->\n" +"\n" +"<svg\n" +" xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n" +" xmlns:cc=\"http://creativecommons.org/ns#\"\n" +" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n" +" xmlns:svg=\"http://www.w3.org/2000/svg\"\n" +" xmlns=\"http://www.w3.org/2000/svg\"\n" +" xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\"\n" +" xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"\n" +" version=\"1.1\"\n" +" id=\"Layer_1\"\n" +" x=\"0px\"\n" +" y=\"0px\"\n" +" viewBox=\"0 0 136.9 114.8\"\n" +" enable-background=\"new 0 0 136.9 114.8\"\n" +" xml:space=\"preserve\"\n" +" inkscape:version=\"0.91 r13725\"\n" +" sodipodi:docname=\"wizard_DLL.svg\"><metadata\n" +" id=\"metadata60\"><rdf:RDF><cc:Work\n" +" rdf:about=\"\"><dc:format>image/svg+xml</dc:format><dc:type\n" +" rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\" /></cc:Work></rdf:RDF></metadata><defs\n" +" id=\"defs58\" /><sodipodi:namedview\n" +" pagecolor=\"#ffffff\"\n" +" bordercolor=\"#666666\"\n" +" borderopacity=\"1\"\n" +" objecttolerance=\"10\"\n" +" gridtolerance=\"10\"\n" +" guidetolerance=\"10\"\n" +" inkscape:pageopacity=\"0\"\n" +" inkscape:pageshadow=\"2\"\n" +" inkscape:window-width=\"1680\"\n" +" inkscape:window-height=\"1001\"\n" +" id=\"namedview56\"\n" +" showgrid=\"false\"\n" +" inkscape:zoom=\"2.0557491\"\n" +" inkscape:cx=\"68.449997\"\n" +" inkscape:cy=\"57.400002\"\n" +" inkscape:window-x=\"0\"\n" +" inkscape:window-y=\"1\"\n" +" inkscape:window-maximized=\"1\"\n" +" inkscape:current-layer=\"Layer_1\" /><path\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.3469\"\n" +" stroke-miterlimit=\"10\"\n" +" d=\"M130,114.9H6.9c-3.8,0-6.9-3.1-6.9-6.9V7 c0-3.8,3.1-6.9,6.9-6.9H130c3.8,0,6.9,3.1,6.9,6.9V108C136.9,111.8,133.9,114.9,130,114.9z\"\n" +" id=\"path3\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><g\n" +" id=\"Layer_1_19_\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\"><rect\n" +" x=\"16.3\"\n" +" y=\"11\"\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.3469\"\n" +" stroke-miterlimit=\"10\"\n" +" width=\"102.9\"\n" +" height=\"67.5\"\n" +" id=\"rect6\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><g\n" +" id=\"g8\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\"><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"0.4307\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"39.6\"\n" +" y1=\"25\"\n" +" x2=\"39.6\"\n" +" y2=\"62.3\"\n" +" id=\"line10\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"0.4307\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"41.2\"\n" +" y1=\"25\"\n" +" x2=\"41.2\"\n" +" y2=\"62.3\"\n" +" id=\"line12\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"0.4307\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"42.8\"\n" +" y1=\"25\"\n" +" x2=\"42.8\"\n" +" y2=\"62.3\"\n" +" id=\"line14\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"0.4307\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"44.5\"\n" +" y1=\"25\"\n" +" x2=\"44.5\"\n" +" y2=\"62.3\"\n" +" id=\"line16\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"0.4307\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"46.1\"\n" +" y1=\"25\"\n" +" x2=\"46.1\"\n" +" y2=\"62.3\"\n" +" id=\"line18\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"0.4307\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"47.7\"\n" +" y1=\"25\"\n" +" x2=\"47.7\"\n" +" y2=\"62.3\"\n" +" id=\"line20\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><path\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.0853\"\n" +" stroke-miterlimit=\"10\"\n" +" d=\"M49.9,23.9v38.6c0,0.9-0.7,1.6-1.6,1.6H39 c-0.9,0-1.6-0.7-1.6-1.6V23.9\"\n" +" id=\"path22\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><g\n" +" id=\"g24\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\"><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"0.4307\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"54.8\"\n" +" y1=\"27.5\"\n" +" x2=\"67.4\"\n" +" y2=\"62.6\"\n" +" id=\"line26\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"0.4307\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"56.3\"\n" +" y1=\"27\"\n" +" x2=\"69\"\n" +" y2=\"62\"\n" +" id=\"line28\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"0.4307\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"57.8\"\n" +" y1=\"26.4\"\n" +" x2=\"70.5\"\n" +" y2=\"61.5\"\n" +" id=\"line30\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"0.4307\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"59.4\"\n" +" y1=\"25.9\"\n" +" x2=\"72.1\"\n" +" y2=\"60.9\"\n" +" id=\"line32\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"0.4307\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"60.9\"\n" +" y1=\"25.3\"\n" +" x2=\"73.6\"\n" +" y2=\"60.4\"\n" +" id=\"line34\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"0.4307\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"62.4\"\n" +" y1=\"24.8\"\n" +" x2=\"75.1\"\n" +" y2=\"59.8\"\n" +" id=\"line36\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><path\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.0853\"\n" +" stroke-miterlimit=\"10\"\n" +" d=\"M64.1,23l13.1,36.3c0.3,0.8-0.1,1.7-0.9,2 l-8.8,3.2c-0.8,0.3-1.7-0.1-2-0.9L52.4,27.2\"\n" +" id=\"path38\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><g\n" +" id=\"g40\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\"><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"0.4307\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"72.5\"\n" +" y1=\"30.6\"\n" +" x2=\"93.5\"\n" +" y2=\"61.4\"\n" +" id=\"line42\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"0.4307\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"73.8\"\n" +" y1=\"29.7\"\n" +" x2=\"94.9\"\n" +" y2=\"60.5\"\n" +" id=\"line44\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"0.4307\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"75.2\"\n" +" y1=\"28.8\"\n" +" x2=\"96.2\"\n" +" y2=\"59.6\"\n" +" id=\"line46\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"0.4307\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"76.5\"\n" +" y1=\"27.9\"\n" +" x2=\"97.6\"\n" +" y2=\"58.6\"\n" +" id=\"line48\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"0.4307\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"77.9\"\n" +" y1=\"27\"\n" +" x2=\"98.9\"\n" +" y2=\"57.7\"\n" +" id=\"line50\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"0.4307\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"79.2\"\n" +" y1=\"26\"\n" +" x2=\"100.3\"\n" +" y2=\"56.8\"\n" +" id=\"line52\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><path\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.0853\"\n" +" stroke-miterlimit=\"10\"\n" +" d=\"M80.4,23.9l21.8,31.9c0.5,0.7,0.3,1.7-0.4,2.2 l-7.7,5.3c-0.7,0.5-1.7,0.3-2.2-0.4L70.1,31\"\n" +" id=\"path54\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /></svg>"; -const char* jucer_AudioComponentTemplate_cpp = (const char*) temp_binary_data_28; +const char* wizard_DLL_svg = (const char*) temp_binary_data_24; -//================== jucer_AudioComponentTemplate.h ================== -static const unsigned char temp_binary_data_29[] = -"/*\r\n" -" ==============================================================================\r\n" -"\r\n" -" This file was auto-generated!\r\n" -"\r\n" -" ==============================================================================\r\n" -"*/\r\n" -"\r\n" -"#pragma once\r\n" -"\r\n" -"%%include_juce%%\r\n" -"\r\n" -"//==============================================================================\r\n" -"/*\r\n" -" This component lives inside our window, and this is where you should put all\r\n" -" your controls and content.\r\n" -"*/\r\n" -"class %%content_component_class%% : public AudioAppComponent\r\n" -"{\r\n" -"public:\r\n" -" //==============================================================================\r\n" -" %%content_component_class%%();\r\n" -" ~%%content_component_class%%();\r\n" -"\r\n" -" //==============================================================================\r\n" -" void prepareToPlay (int samplesPerBlockExpected, double sampleRate) override;\r\n" -" void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) override;\r\n" -" void releaseResources() override;\r\n" -"\r\n" -" //==============================================================================\r\n" -" void paint (Graphics& g) override;\r\n" -" void resized() override;\r\n" -"\r\n" -"private:\r\n" -" //==============================================================================\r\n" -" // Your private member variables go here...\r\n" -"\r\n" -"\r\n" -" JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%content_component_class%%)\r\n" -"};\r\n"; +//================== wizard_GUI.svg ================== +static const unsigned char temp_binary_data_25[] = +"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" +"<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->\n" +"\n" +"<svg\n" +" xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n" +" xmlns:cc=\"http://creativecommons.org/ns#\"\n" +" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n" +" xmlns:svg=\"http://www.w3.org/2000/svg\"\n" +" xmlns=\"http://www.w3.org/2000/svg\"\n" +" xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\"\n" +" xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"\n" +" version=\"1.1\"\n" +" id=\"Layer_1\"\n" +" x=\"0px\"\n" +" y=\"0px\"\n" +" viewBox=\"0 0 136.9 114.8\"\n" +" enable-background=\"new 0 0 136.9 114.8\"\n" +" xml:space=\"preserve\"\n" +" inkscape:version=\"0.91 r13725\"\n" +" sodipodi:docname=\"wizard_GUI.svg\"><metadata\n" +" id=\"metadata53\"><rdf:RDF><cc:Work\n" +" rdf:about=\"\"><dc:format>image/svg+xml</dc:format><dc:type\n" +" rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\" /></cc:Work></rdf:RDF></metadata><defs\n" +" id=\"defs51\" /><sodipodi:namedview\n" +" pagecolor=\"#ffffff\"\n" +" bordercolor=\"#666666\"\n" +" borderopacity=\"1\"\n" +" objecttolerance=\"10\"\n" +" gridtolerance=\"10\"\n" +" guidetolerance=\"10\"\n" +" inkscape:pageopacity=\"0\"\n" +" inkscape:pageshadow=\"2\"\n" +" inkscape:window-width=\"1680\"\n" +" inkscape:window-height=\"1001\"\n" +" id=\"namedview49\"\n" +" showgrid=\"false\"\n" +" inkscape:zoom=\"2.0557491\"\n" +" inkscape:cx=\"68.449997\"\n" +" inkscape:cy=\"57.400002\"\n" +" inkscape:window-x=\"0\"\n" +" inkscape:window-y=\"1\"\n" +" inkscape:window-maximized=\"1\"\n" +" inkscape:current-layer=\"Layer_1\" /><rect\n" +" x=\"16.3\"\n" +" y=\"10.9\"\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.3469\"\n" +" stroke-miterlimit=\"10\"\n" +" width=\"103.6\"\n" +" height=\"67.5\"\n" +" id=\"rect3\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><path\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"0.7078\"\n" +" stroke-miterlimit=\"10\"\n" +" d=\"M55.2,62.5H23.4c-0.4,0-0.7-0.4-0.7-0.9l0,0 c0-0.5,0.3-0.9,0.7-0.9h31.8c0.4,0,0.7,0.4,0.7,0.9l0,0C55.9,62.1,55.5,62.5,55.2,62.5z\"\n" +" id=\"path5\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><path\n" +" fill=\"#a45c94\"\n" +" d=\"M38.1,62.5H23.4c-0.4,0-0.7-0.4-0.7-0.9l0,0c0-0.5,0.3-0.9,0.7-0.9h14.7c0.4,0,0.7,0.4,0.7,0.9l0,0 C38.7,62.1,38.4,62.5,38.1,62.5z\"\n" +" id=\"path7\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\" /><path\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"0.7078\"\n" +" stroke-miterlimit=\"10\"\n" +" d=\"M55.2,67.8H23.4c-0.4,0-0.7-0.4-0.7-0.9l0,0 c0-0.5,0.3-0.9,0.7-0.9h31.8c0.4,0,0.7,0.4,0.7,0.9l0,0C55.9,67.4,55.5,67.8,55.2,67.8z\"\n" +" id=\"path9\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><path\n" +" fill=\"#a45c94\"\n" +" d=\"M44.2,67.8H23.4c-0.4,0-0.7-0.4-0.7-0.9l0,0c0-0.5,0.3-0.9,0.7-0.9h20.8c0.4,0,0.7,0.4,0.7,0.9l0,0 C44.8,67.4,44.6,67.8,44.2,67.8z\"\n" +" id=\"path11\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\" /><path\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"0.7078\"\n" +" stroke-miterlimit=\"10\"\n" +" d=\"M55.2,73H23.4c-0.4,0-0.7-0.4-0.7-0.9l0,0 c0-0.5,0.3-0.9,0.7-0.9h31.8c0.4,0,0.7,0.4,0.7,0.9l0,0C55.9,72.6,55.5,73,55.2,73z\"\n" +" id=\"path13\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><path\n" +" fill=\"#a45c94\"\n" +" d=\"M49.4,73h-26c-0.4,0-0.7-0.4-0.7-0.9l0,0c0-0.5,0.3-0.9,0.7-0.9h26c0.4,0,0.7,0.4,0.7,0.9l0,0 C50.1,72.6,49.8,73,49.4,73z\"\n" +" id=\"path15\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1\" /><rect\n" +" x=\"16.3\"\n" +" y=\"10.9\"\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.3469\"\n" +" stroke-miterlimit=\"10\"\n" +" width=\"103.6\"\n" +" height=\"2.4\"\n" +" id=\"rect17\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><circle\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.3469\"\n" +" stroke-miterlimit=\"10\"\n" +" cx=\"69.3\"\n" +" cy=\"39.6\"\n" +" r=\"13.9\"\n" +" id=\"circle19\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><g\n" +" id=\"g21\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\"><g\n" +" id=\"g23\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\"><path\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.2523\"\n" +" stroke-miterlimit=\"10\"\n" +" d=\"M79.8,33.5c1.1,1.9,1.3,5.2,0,5.7 c-1.3,0.5-7.2,0.3-10.2,0.2c1.3-2.7,4.1-7.9,5.2-8.8C75.9,29.7,78.7,31.6,79.8,33.5z\"\n" +" id=\"path25\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><g\n" +" id=\"g27\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\"><path\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.2523\"\n" +" stroke-miterlimit=\"10\"\n" +" d=\"M79.8,45.6c-1.1,1.9-3.8,3.7-4.9,2.9 c-1.1-0.9-3.9-6.1-5.2-8.8c3-0.2,8.9-0.4,10.2,0.1C81.2,40.4,80.9,43.7,79.8,45.6z\"\n" +" id=\"path29\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><g\n" +" id=\"g31\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\"><path\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.2523\"\n" +" stroke-miterlimit=\"10\"\n" +" d=\"M69.3,51.7c-2.2,0-5.2-1.5-5-2.8 s3.3-6.4,5-8.9c1.7,2.5,4.8,7.5,5,8.9S71.5,51.7,69.3,51.7z\"\n" +" id=\"path33\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><g\n" +" id=\"g35\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\"><path\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.2523\"\n" +" stroke-miterlimit=\"10\"\n" +" d=\"M58.9,45.6c-1.1-1.9-1.3-5.2,0-5.7 c1.3-0.5,7.2-0.3,10.2-0.2c-1.3,2.7-4.1,7.9-5.2,8.8C62.8,49.4,60,47.6,58.9,45.6z\"\n" +" id=\"path37\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><g\n" +" id=\"g39\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\"><path\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.2523\"\n" +" stroke-miterlimit=\"10\"\n" +" d=\"M58.9,33.5c1.1-1.9,3.8-3.7,4.9-2.9 c1.1,0.9,3.9,6.1,5.2,8.8c-3,0.2-8.9,0.4-10.2-0.1C57.5,38.8,57.8,35.5,58.9,33.5z\"\n" +" id=\"path41\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><g\n" +" id=\"g43\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\"><path\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.2523\"\n" +" stroke-miterlimit=\"10\"\n" +" d=\"M69.3,27.5c2.2,0,5.2,1.5,5,2.8 s-3.3,6.4-5,8.9c-1.7-2.5-4.8-7.5-5-8.9S67.1,27.5,69.3,27.5z\"\n" +" id=\"path45\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /></g></g><path\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.3469\"\n" +" stroke-miterlimit=\"10\"\n" +" d=\"M130,114.8H6.9c-3.8,0-6.9-3.1-6.9-6.9V6.9 C0,3.1,3.1,0,6.9,0H130c3.8,0,6.9,3.1,6.9,6.9v101.1C136.9,111.7,133.9,114.8,130,114.8z\"\n" +" id=\"path47\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /></svg>"; -const char* jucer_AudioComponentTemplate_h = (const char*) temp_binary_data_29; +const char* wizard_GUI_svg = (const char*) temp_binary_data_25; -//================== jucer_AudioPluginEditorTemplate.cpp ================== -static const unsigned char temp_binary_data_30[] = -"/*\r\n" -" ==============================================================================\r\n" -"\r\n" -" This file was auto-generated!\r\n" -"\r\n" -" It contains the basic framework code for a JUCE plugin editor.\r\n" -"\r\n" -" ==============================================================================\r\n" -"*/\r\n" -"\r\n" -"%%editor_cpp_headers%%\r\n" -"\r\n" -"//==============================================================================\r\n" -"%%editor_class_name%%::%%editor_class_name%% (%%filter_class_name%%& p)\r\n" -" : AudioProcessorEditor (&p), processor (p)\r\n" -"{\r\n" -" // Make sure that before the constructor has finished, you've set the\r\n" -" // editor's size to whatever you need it to be.\r\n" -" setSize (400, 300);\r\n" -"}\r\n" -"\r\n" -"%%editor_class_name%%::~%%editor_class_name%%()\r\n" -"{\r\n" -"}\r\n" -"\r\n" -"//==============================================================================\r\n" -"void %%editor_class_name%%::paint (Graphics& g)\r\n" -"{\r\n" -" // (Our component is opaque, so we must completely fill the background with a solid colour)\r\n" -" g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId));\r\n" -"\r\n" -" g.setColour (Colours::white);\r\n" -" g.setFont (15.0f);\r\n" -" g.drawFittedText (\"Hello World!\", getLocalBounds(), Justification::centred, 1);\r\n" -"}\r\n" -"\r\n" -"void %%editor_class_name%%::resized()\r\n" -"{\r\n" -" // This is generally where you'll want to lay out the positions of any\r\n" -" // subcomponents in your editor..\r\n" -"}\r\n"; +//================== wizard_Highlight.svg ================== +static const unsigned char temp_binary_data_26[] = +"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" +"<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->\n" +"\n" +"<svg\n" +" xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n" +" xmlns:cc=\"http://creativecommons.org/ns#\"\n" +" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n" +" xmlns:svg=\"http://www.w3.org/2000/svg\"\n" +" xmlns=\"http://www.w3.org/2000/svg\"\n" +" xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\"\n" +" xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"\n" +" version=\"1.1\"\n" +" id=\"Layer_1\"\n" +" x=\"0px\"\n" +" y=\"0px\"\n" +" viewBox=\"0 0 136.9 114.8\"\n" +" enable-background=\"new 0 0 136.9 114.8\"\n" +" xml:space=\"preserve\"\n" +" inkscape:version=\"0.91 r13725\"\n" +" sodipodi:docname=\"wizard_Highlight.svg\"><metadata\n" +" id=\"metadata9\"><rdf:RDF><cc:Work\n" +" rdf:about=\"\"><dc:format>image/svg+xml</dc:format><dc:type\n" +" rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\" /></cc:Work></rdf:RDF></metadata><defs\n" +" id=\"defs7\" /><sodipodi:namedview\n" +" pagecolor=\"#ffffff\"\n" +" bordercolor=\"#666666\"\n" +" borderopacity=\"1\"\n" +" objecttolerance=\"10\"\n" +" gridtolerance=\"10\"\n" +" guidetolerance=\"10\"\n" +" inkscape:pageopacity=\"0\"\n" +" inkscape:pageshadow=\"2\"\n" +" inkscape:window-width=\"1680\"\n" +" inkscape:window-height=\"1001\"\n" +" id=\"namedview5\"\n" +" showgrid=\"false\"\n" +" inkscape:zoom=\"2.0557491\"\n" +" inkscape:cx=\"68.449997\"\n" +" inkscape:cy=\"57.400002\"\n" +" inkscape:window-x=\"0\"\n" +" inkscape:window-y=\"1\"\n" +" inkscape:window-maximized=\"1\"\n" +" inkscape:current-layer=\"Layer_1\" /><path\n" +" opacity=\"0.2\"\n" +" fill=\"#a45c94\"\n" +" d=\"M130.1,114.8H6.9c-3.8,0-6.9-3.1-6.9-6.9V6.9C0,3.1,3.1,0,6.9,0h123.2c3.8,0,6.9,3.1,6.9,6.9 V108C136.9,111.8,133.9,114.8,130.1,114.8z\"\n" +" id=\"path3\"\n" +" style=\"fill:#a45c94;fill-opacity:1\" /></svg>"; -const char* jucer_AudioPluginEditorTemplate_cpp = (const char*) temp_binary_data_30; +const char* wizard_Highlight_svg = (const char*) temp_binary_data_26; -//================== jucer_AudioPluginEditorTemplate.h ================== -static const unsigned char temp_binary_data_31[] = -"/*\r\n" -" ==============================================================================\r\n" -"\r\n" -" This file was auto-generated!\r\n" -"\r\n" -" It contains the basic framework code for a JUCE plugin editor.\r\n" -"\r\n" -" ==============================================================================\r\n" -"*/\r\n" -"\r\n" -"#pragma once\r\n" -"\r\n" -"%%editor_headers%%\r\n" -"\r\n" -"//==============================================================================\r\n" -"/**\r\n" -"*/\r\n" -"class %%editor_class_name%% : public AudioProcessorEditor\r\n" -"{\r\n" -"public:\r\n" -" %%editor_class_name%% (%%filter_class_name%%&);\r\n" -" ~%%editor_class_name%%();\r\n" -"\r\n" -" //==============================================================================\r\n" -" void paint (Graphics&) override;\r\n" -" void resized() override;\r\n" -"\r\n" -"private:\r\n" -" // This reference is provided as a quick way for your editor to\r\n" -" // access the processor object that created it.\r\n" -" %%filter_class_name%%& processor;\r\n" -"\r\n" -" JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%editor_class_name%%)\r\n" -"};\r\n"; +//================== wizard_Openfile.svg ================== +static const unsigned char temp_binary_data_27[] = +"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" +"<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->\n" +"\n" +"<svg\n" +" xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n" +" xmlns:cc=\"http://creativecommons.org/ns#\"\n" +" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n" +" xmlns:svg=\"http://www.w3.org/2000/svg\"\n" +" xmlns=\"http://www.w3.org/2000/svg\"\n" +" xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\"\n" +" xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"\n" +" version=\"1.1\"\n" +" id=\"Layer_1\"\n" +" x=\"0px\"\n" +" y=\"0px\"\n" +" viewBox=\"0 0 177.9 114.8\"\n" +" enable-background=\"new 0 0 177.9 114.8\"\n" +" xml:space=\"preserve\"\n" +" inkscape:version=\"0.91 r13725\"\n" +" sodipodi:docname=\"wizard_Openfile.svg\"><metadata\n" +" id=\"metadata9\"><rdf:RDF><cc:Work\n" +" rdf:about=\"\"><dc:format>image/svg+xml</dc:format><dc:type\n" +" rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\" /></cc:Work></rdf:RDF></metadata><defs\n" +" id=\"defs7\" /><sodipodi:namedview\n" +" pagecolor=\"#ffffff\"\n" +" bordercolor=\"#666666\"\n" +" borderopacity=\"1\"\n" +" objecttolerance=\"10\"\n" +" gridtolerance=\"10\"\n" +" guidetolerance=\"10\"\n" +" inkscape:pageopacity=\"0\"\n" +" inkscape:pageshadow=\"2\"\n" +" inkscape:window-width=\"1680\"\n" +" inkscape:window-height=\"1001\"\n" +" id=\"namedview5\"\n" +" showgrid=\"false\"\n" +" inkscape:zoom=\"1.7425521\"\n" +" inkscape:cx=\"88.949997\"\n" +" inkscape:cy=\"57.400002\"\n" +" inkscape:window-x=\"0\"\n" +" inkscape:window-y=\"1\"\n" +" inkscape:window-maximized=\"1\"\n" +" inkscape:current-layer=\"Layer_1\" /><path\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.3469\"\n" +" stroke-miterlimit=\"10\"\n" +" d=\"M164.7,71.4H13.2c-3.8,0-6.9-3.1-6.9-6.9V43.6 c0-3.8,3.1-6.9,6.9-6.9h151.5c3.8,0,6.9,3.1,6.9,6.9v20.9C171.6,68.3,168.5,71.4,164.7,71.4z\"\n" +" id=\"path3\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /></svg>"; -const char* jucer_AudioPluginEditorTemplate_h = (const char*) temp_binary_data_31; +const char* wizard_Openfile_svg = (const char*) temp_binary_data_27; -//================== jucer_AudioPluginFilterTemplate.cpp ================== -static const unsigned char temp_binary_data_32[] = -"/*\r\n" -" ==============================================================================\r\n" -"\r\n" -" This file was auto-generated!\r\n" -"\r\n" -" It contains the basic framework code for a JUCE plugin processor.\r\n" -"\r\n" -" ==============================================================================\r\n" -"*/\r\n" -"\r\n" -"%%filter_headers%%\r\n" -"\r\n" -"//==============================================================================\r\n" -"%%filter_class_name%%::%%filter_class_name%%()\r\n" -"#ifndef JucePlugin_PreferredChannelConfigurations\r\n" -" : AudioProcessor (BusesProperties()\r\n" -" #if ! JucePlugin_IsMidiEffect\r\n" -" #if ! JucePlugin_IsSynth\r\n" -" .withInput (\"Input\", AudioChannelSet::stereo(), true)\r\n" -" #endif\r\n" -" .withOutput (\"Output\", AudioChannelSet::stereo(), true)\r\n" -" #endif\r\n" -" )\r\n" -"#endif\r\n" -"{\r\n" -"}\r\n" -"\r\n" -"%%filter_class_name%%::~%%filter_class_name%%()\r\n" -"{\r\n" -"}\r\n" -"\r\n" -"//==============================================================================\r\n" -"const String %%filter_class_name%%::getName() const\r\n" -"{\r\n" -" return JucePlugin_Name;\r\n" -"}\r\n" -"\r\n" -"bool %%filter_class_name%%::acceptsMidi() const\r\n" -"{\r\n" -" #if JucePlugin_WantsMidiInput\r\n" -" return true;\r\n" -" #else\r\n" -" return false;\r\n" -" #endif\r\n" -"}\r\n" -"\r\n" -"bool %%filter_class_name%%::producesMidi() const\r\n" -"{\r\n" -" #if JucePlugin_ProducesMidiOutput\r\n" -" return true;\r\n" -" #else\r\n" -" return false;\r\n" -" #endif\r\n" -"}\r\n" -"\r\n" -"bool %%filter_class_name%%::isMidiEffect() const\r\n" -"{\r\n" -" #if JucePlugin_IsMidiEffect\r\n" -" return true;\r\n" -" #else\r\n" -" return false;\r\n" -" #endif\r\n" -"}\r\n" -"\r\n" -"double %%filter_class_name%%::getTailLengthSeconds() const\r\n" -"{\r\n" -" return 0.0;\r\n" -"}\r\n" -"\r\n" -"int %%filter_class_name%%::getNumPrograms()\r\n" -"{\r\n" -" return 1; // NB: some hosts don't cope very well if you tell them there are 0 programs,\r\n" -" // so this should be at least 1, even if you're not really implementing programs.\r\n" -"}\r\n" -"\r\n" -"int %%filter_class_name%%::getCurrentProgram()\r\n" -"{\r\n" -" return 0;\r\n" -"}\r\n" -"\r\n" -"void %%filter_class_name%%::setCurrentProgram (int index)\r\n" -"{\r\n" -"}\r\n" -"\r\n" -"const String %%filter_class_name%%::getProgramName (int index)\r\n" -"{\r\n" -" return {};\r\n" -"}\r\n" +//================== wizard_OpenGL.svg ================== +static const unsigned char temp_binary_data_28[] = +"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" +"<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->\n" +"\n" +"<svg\n" +" xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n" +" xmlns:cc=\"http://creativecommons.org/ns#\"\n" +" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n" +" xmlns:svg=\"http://www.w3.org/2000/svg\"\n" +" xmlns=\"http://www.w3.org/2000/svg\"\n" +" xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\"\n" +" xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"\n" +" version=\"1.1\"\n" +" id=\"Layer_1\"\n" +" x=\"0px\"\n" +" y=\"0px\"\n" +" viewBox=\"0 0 136.9 114.8\"\n" +" enable-background=\"new 0 0 136.9 114.8\"\n" +" xml:space=\"preserve\"\n" +" inkscape:version=\"0.91 r13725\"\n" +" sodipodi:docname=\"wizard_OpenGL.svg\"><metadata\n" +" id=\"metadata29\"><rdf:RDF><cc:Work\n" +" rdf:about=\"\"><dc:format>image/svg+xml</dc:format><dc:type\n" +" rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\" /></cc:Work></rdf:RDF></metadata><defs\n" +" id=\"defs27\" /><sodipodi:namedview\n" +" pagecolor=\"#ffffff\"\n" +" bordercolor=\"#666666\"\n" +" borderopacity=\"1\"\n" +" objecttolerance=\"10\"\n" +" gridtolerance=\"10\"\n" +" guidetolerance=\"10\"\n" +" inkscape:pageopacity=\"0\"\n" +" inkscape:pageshadow=\"2\"\n" +" inkscape:window-width=\"1680\"\n" +" inkscape:window-height=\"1001\"\n" +" id=\"namedview25\"\n" +" showgrid=\"false\"\n" +" inkscape:zoom=\"2.0557491\"\n" +" inkscape:cx=\"-16.190683\"\n" +" inkscape:cy=\"57.400002\"\n" +" inkscape:window-x=\"0\"\n" +" inkscape:window-y=\"1\"\n" +" inkscape:window-maximized=\"1\"\n" +" inkscape:current-layer=\"Layer_1\" /><rect\n" +" x=\"16.3\"\n" +" y=\"10.9\"\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.3469\"\n" +" stroke-miterlimit=\"10\"\n" +" width=\"103.6\"\n" +" height=\"67.5\"\n" +" id=\"rect3\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><rect\n" +" x=\"16.3\"\n" +" y=\"10.9\"\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.3469\"\n" +" stroke-miterlimit=\"10\"\n" +" width=\"103.6\"\n" +" height=\"2.4\"\n" +" id=\"rect5\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><path\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.3469\"\n" +" stroke-miterlimit=\"10\"\n" +" d=\"M75.8,31.5c8.7,4.7,14.8,13.2,13.5,20 c-1.6,8.5-13.8,11.4-26.8,4.3S45.3,36.9,51.6,30.9C56.7,26.1,67.1,26.7,75.8,31.5z\"\n" +" id=\"path7\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><path\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.3469\"\n" +" stroke-miterlimit=\"10\"\n" +" d=\"M86.1,43.6c1,2.4,0.5,5.5-1.3,5 c-1.9-0.5-9.8-5-13.8-7.4c2.9-1.2,8.2-3.2,9.8-3.2C82.2,38.2,85.2,41.4,86.1,43.6z\"\n" +" id=\"path9\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><path\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.3469\"\n" +" stroke-miterlimit=\"10\"\n" +" d=\"M83,55.3c-2.3,1.3-7.3,1.2-8.6-0.7 c-1.2-1.9-2.9-9.5-3.5-12.9c4.2,2.1,12.2,6.3,13.8,7.7C86.3,50.7,85.2,54,83,55.3z\"\n" +" id=\"path11\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><path\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.3469\"\n" +" stroke-miterlimit=\"10\"\n" +" d=\"M63.6,53.5c-3.6-2-7.3-6.3-5.9-7.6 c1.3-1.2,9-3.5,12.5-4.4c1.2,3.5,3.4,11.2,3.1,13C73,56.3,67.3,55.5,63.6,53.5z\"\n" +" id=\"path13\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><path\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.3469\"\n" +" stroke-miterlimit=\"10\"\n" +" d=\"M51.9,38.3c-0.1-2.5,2-5.2,4.1-4.6 c2.1,0.6,9.9,5.1,13.9,7.5c-3.2,1.3-10.5,4.1-12.8,4.1C54.9,45.1,52,40.9,51.9,38.3z\"\n" +" id=\"path15\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><path\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.3469\"\n" +" stroke-miterlimit=\"10\"\n" +" d=\"M60,29.3c2.4-0.4,6.6,0.3,7.5,1.5 c0.9,1.2,2.1,6.8,2.6,9.9c-4.2-2.1-12.3-6.3-13.7-7.6C55,31.8,57.4,29.8,60,29.3z\"\n" +" id=\"path17\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><path\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.3469\"\n" +" stroke-miterlimit=\"10\"\n" +" d=\"M75.2,32.5c2.5,1.4,5.6,4.3,5,5 c-0.7,0.8-6.3,2.5-9.5,3.3c-1.1-3.2-2.7-8.9-2.4-9.9C68.6,30,72.6,31.1,75.2,32.5z\"\n" +" id=\"path19\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><path\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.3469\"\n" +" stroke-miterlimit=\"10\"\n" +" d=\"M130,114.8H6.9c-3.8,0-6.9-3.1-6.9-6.9V6.9 C0,3.1,3.1,0,6.9,0H130c3.8,0,6.9,3.1,6.9,6.9v101.1C136.9,111.7,133.9,114.8,130,114.8z\"\n" +" id=\"path21\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><path\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.3469\"\n" +" stroke-miterlimit=\"10\"\n" +" d=\"M87.4,55.5c-6.6,10.4-20.4,14.6-30.8,8 s-13.4-19.6-6.9-30\"\n" +" id=\"path23\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /></svg>"; + +const char* wizard_OpenGL_svg = (const char*) temp_binary_data_28; + +//================== wizard_StaticLibrary.svg ================== +static const unsigned char temp_binary_data_29[] = +"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" +"<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->\n" +"\n" +"<svg\n" +" xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n" +" xmlns:cc=\"http://creativecommons.org/ns#\"\n" +" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n" +" xmlns:svg=\"http://www.w3.org/2000/svg\"\n" +" xmlns=\"http://www.w3.org/2000/svg\"\n" +" xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\"\n" +" xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"\n" +" version=\"1.1\"\n" +" id=\"Layer_1\"\n" +" x=\"0px\"\n" +" y=\"0px\"\n" +" viewBox=\"0 0 136.9 114.8\"\n" +" enable-background=\"new 0 0 136.9 114.8\"\n" +" xml:space=\"preserve\"\n" +" inkscape:version=\"0.91 r13725\"\n" +" sodipodi:docname=\"wizard_StaticLibrary.svg\"><metadata\n" +" id=\"metadata60\"><rdf:RDF><cc:Work\n" +" rdf:about=\"\"><dc:format>image/svg+xml</dc:format><dc:type\n" +" rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\" /></cc:Work></rdf:RDF></metadata><defs\n" +" id=\"defs58\" /><sodipodi:namedview\n" +" pagecolor=\"#ffffff\"\n" +" bordercolor=\"#666666\"\n" +" borderopacity=\"1\"\n" +" objecttolerance=\"10\"\n" +" gridtolerance=\"10\"\n" +" guidetolerance=\"10\"\n" +" inkscape:pageopacity=\"0\"\n" +" inkscape:pageshadow=\"2\"\n" +" inkscape:window-width=\"1680\"\n" +" inkscape:window-height=\"1001\"\n" +" id=\"namedview56\"\n" +" showgrid=\"false\"\n" +" inkscape:zoom=\"2.0557491\"\n" +" inkscape:cx=\"68.449997\"\n" +" inkscape:cy=\"57.400002\"\n" +" inkscape:window-x=\"0\"\n" +" inkscape:window-y=\"1\"\n" +" inkscape:window-maximized=\"1\"\n" +" inkscape:current-layer=\"Layer_1\" /><path\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.3469\"\n" +" stroke-miterlimit=\"10\"\n" +" d=\"M130,114.8H6.9c-3.8,0-6.9-3.1-6.9-6.9V6.9 C0,3,3.1,0,6.9,0H130c3.8,0,6.9,3.1,6.9,6.9v101.1C136.9,111.7,133.9,114.8,130,114.8z\"\n" +" id=\"path3\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><g\n" +" id=\"Layer_1_21_\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\"><rect\n" +" x=\"16.3\"\n" +" y=\"10.9\"\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.3469\"\n" +" stroke-miterlimit=\"10\"\n" +" width=\"102.9\"\n" +" height=\"67.5\"\n" +" id=\"rect6\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><g\n" +" id=\"g8\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\"><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"0.4942\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"43.1\"\n" +" y1=\"22.1\"\n" +" x2=\"43.1\"\n" +" y2=\"64.9\"\n" +" id=\"line10\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"0.4942\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"45\"\n" +" y1=\"22.1\"\n" +" x2=\"45\"\n" +" y2=\"64.9\"\n" +" id=\"line12\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"0.4942\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"46.8\"\n" +" y1=\"22.1\"\n" +" x2=\"46.8\"\n" +" y2=\"64.9\"\n" +" id=\"line14\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"0.4942\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"48.7\"\n" +" y1=\"22.1\"\n" +" x2=\"48.7\"\n" +" y2=\"64.9\"\n" +" id=\"line16\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"0.4942\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"50.6\"\n" +" y1=\"22.1\"\n" +" x2=\"50.6\"\n" +" y2=\"64.9\"\n" +" id=\"line18\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"0.4942\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"52.5\"\n" +" y1=\"22.1\"\n" +" x2=\"52.5\"\n" +" y2=\"64.9\"\n" +" id=\"line20\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><path\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.2453\"\n" +" stroke-miterlimit=\"10\"\n" +" d=\"M54.9,20.8v44.3c0,1-0.8,1.8-1.8,1.8H42.4 c-1,0-1.8-0.8-1.8-1.8V20.8\"\n" +" id=\"path22\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><g\n" +" id=\"g24\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\"><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"0.4942\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"64.5\"\n" +" y1=\"22.1\"\n" +" x2=\"64.5\"\n" +" y2=\"64.9\"\n" +" id=\"line26\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"0.4942\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"66.4\"\n" +" y1=\"22.1\"\n" +" x2=\"66.4\"\n" +" y2=\"64.9\"\n" +" id=\"line28\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"0.4942\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"68.3\"\n" +" y1=\"22.1\"\n" +" x2=\"68.3\"\n" +" y2=\"64.9\"\n" +" id=\"line30\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"0.4942\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"70.1\"\n" +" y1=\"22.1\"\n" +" x2=\"70.1\"\n" +" y2=\"64.9\"\n" +" id=\"line32\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"0.4942\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"72\"\n" +" y1=\"22.1\"\n" +" x2=\"72\"\n" +" y2=\"64.9\"\n" +" id=\"line34\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"0.4942\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"73.9\"\n" +" y1=\"22.1\"\n" +" x2=\"73.9\"\n" +" y2=\"64.9\"\n" +" id=\"line36\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><path\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.2453\"\n" +" stroke-miterlimit=\"10\"\n" +" d=\"M76.4,20.8v44.3c0,1-0.8,1.8-1.8,1.8H63.8 c-1,0-1.8-0.8-1.8-1.8V20.8\"\n" +" id=\"path38\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><g\n" +" id=\"g40\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\"><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"0.4942\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"85.9\"\n" +" y1=\"22.1\"\n" +" x2=\"85.9\"\n" +" y2=\"64.9\"\n" +" id=\"line42\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"0.4942\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"87.8\"\n" +" y1=\"22.1\"\n" +" x2=\"87.8\"\n" +" y2=\"64.9\"\n" +" id=\"line44\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"0.4942\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"89.7\"\n" +" y1=\"22.1\"\n" +" x2=\"89.7\"\n" +" y2=\"64.9\"\n" +" id=\"line46\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"0.4942\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"91.6\"\n" +" y1=\"22.1\"\n" +" x2=\"91.6\"\n" +" y2=\"64.9\"\n" +" id=\"line48\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"0.4942\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"93.4\"\n" +" y1=\"22.1\"\n" +" x2=\"93.4\"\n" +" y2=\"64.9\"\n" +" id=\"line50\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /><line\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"0.4942\"\n" +" stroke-miterlimit=\"10\"\n" +" x1=\"95.3\"\n" +" y1=\"22.1\"\n" +" x2=\"95.3\"\n" +" y2=\"64.9\"\n" +" id=\"line52\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /></g><path\n" +" fill=\"none\"\n" +" stroke=\"#a45c94\"\n" +" stroke-width=\"1.2453\"\n" +" stroke-miterlimit=\"10\"\n" +" d=\"M97.8,20.8v44.3c0,1-0.8,1.8-1.8,1.8H85.3 c-1,0-1.8-0.8-1.8-1.8V20.8\"\n" +" id=\"path54\"\n" +" style=\"stroke:#a45c94;stroke-opacity:1\" /></svg>"; + +const char* wizard_StaticLibrary_svg = (const char*) temp_binary_data_29; + +//================== jucer_AnimatedComponentSimpleTemplate.h ================== +static const unsigned char temp_binary_data_30[] = +"#pragma once\r\n" "\r\n" -"void %%filter_class_name%%::changeProgramName (int index, const String& newName)\r\n" -"{\r\n" -"}\r\n" +"%%include_juce%%\r\n" "\r\n" "//==============================================================================\r\n" -"void %%filter_class_name%%::prepareToPlay (double sampleRate, int samplesPerBlock)\r\n" +"/*\r\n" +" This component lives inside our window, and this is where you should put all\r\n" +" your controls and content.\r\n" +"*/\r\n" +"class %%content_component_class%% : public juce::AnimatedAppComponent\r\n" "{\r\n" -" // Use this method as the place to do any pre-playback\r\n" -" // initialisation that you need..\r\n" -"}\r\n" +"public:\r\n" +" //==============================================================================\r\n" +" %%content_component_class%%()\r\n" +" {\r\n" +" // Make sure you set the size of the component after\r\n" +" // you add any child components.\r\n" +" setSize (800, 600);\r\n" +" setFramesPerSecond (60); // This sets the frequency of the update calls.\r\n" +" }\r\n" "\r\n" -"void %%filter_class_name%%::releaseResources()\r\n" -"{\r\n" -" // When playback stops, you can use this as an opportunity to free up any\r\n" -" // spare memory, etc.\r\n" -"}\r\n" +" ~%%content_component_class%%() override\r\n" +" {\r\n" +" }\r\n" "\r\n" -"#ifndef JucePlugin_PreferredChannelConfigurations\r\n" -"bool %%filter_class_name%%::isBusesLayoutSupported (const BusesLayout& layouts) const\r\n" -"{\r\n" -" #if JucePlugin_IsMidiEffect\r\n" -" ignoreUnused (layouts);\r\n" -" return true;\r\n" -" #else\r\n" -" // This is the place where you check if the layout is supported.\r\n" -" // In this template code we only support mono or stereo.\r\n" -" if (layouts.getMainOutputChannelSet() != AudioChannelSet::mono()\r\n" -" && layouts.getMainOutputChannelSet() != AudioChannelSet::stereo())\r\n" -" return false;\r\n" +" //==============================================================================\r\n" +" void update() override\r\n" +" {\r\n" +" // This function is called at the frequency specified by the setFramesPerSecond() call\r\n" +" // in the constructor. You can use it to update counters, animate values, etc.\r\n" +" }\r\n" "\r\n" -" // This checks if the input layout matches the output layout\r\n" -" #if ! JucePlugin_IsSynth\r\n" -" if (layouts.getMainOutputChannelSet() != layouts.getMainInputChannelSet())\r\n" -" return false;\r\n" -" #endif\r\n" +" //==============================================================================\r\n" +" void paint (juce::Graphics& g) override\r\n" +" {\r\n" +" // (Our component is opaque, so we must completely fill the background with a solid colour)\r\n" +" g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId));\r\n" "\r\n" -" return true;\r\n" -" #endif\r\n" -"}\r\n" -"#endif\r\n" +" // You can add your drawing code here!\r\n" +" }\r\n" "\r\n" -"void %%filter_class_name%%::processBlock (AudioBuffer<float>& buffer, MidiBuffer& midiMessages)\r\n" -"{\r\n" -" ScopedNoDenormals noDenormals;\r\n" -" auto totalNumInputChannels = getTotalNumInputChannels();\r\n" -" auto totalNumOutputChannels = getTotalNumOutputChannels();\r\n" +" void resized() override\r\n" +" {\r\n" +" // This is called when the MainContentComponent is resized.\r\n" +" // If you add any child components, this is where you should\r\n" +" // update their positions.\r\n" +" }\r\n" "\r\n" -" // In case we have more outputs than inputs, this code clears any output\r\n" -" // channels that didn't contain input data, (because these aren't\r\n" -" // guaranteed to be empty - they may contain garbage).\r\n" -" // This is here to avoid people getting screaming feedback\r\n" -" // when they first compile a plugin, but obviously you don't need to keep\r\n" -" // this code if your algorithm always overwrites all the output channels.\r\n" -" for (auto i = totalNumInputChannels; i < totalNumOutputChannels; ++i)\r\n" -" buffer.clear (i, 0, buffer.getNumSamples());\r\n" "\r\n" -" // This is the place where you'd normally do the guts of your plugin's\r\n" -" // audio processing...\r\n" -" // Make sure to reset the state if your inner loop is processing\r\n" -" // the samples and the outer loop is handling the channels.\r\n" -" // Alternatively, you can process the samples with the channels\r\n" -" // interleaved by keeping the same state.\r\n" -" for (int channel = 0; channel < totalNumInputChannels; ++channel)\r\n" -" {\r\n" -" auto* channelData = buffer.getWritePointer (channel);\r\n" +"private:\r\n" +" //==============================================================================\r\n" +" // Your private member variables go here...\r\n" "\r\n" -" // ..do something to the data...\r\n" -" }\r\n" -"}\r\n" +"\r\n" +" JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%content_component_class%%)\r\n" +"};\r\n"; + +const char* jucer_AnimatedComponentSimpleTemplate_h = (const char*) temp_binary_data_30; + +//================== jucer_AnimatedComponentTemplate.cpp ================== +static const unsigned char temp_binary_data_31[] = +"%%include_corresponding_header%%\r\n" "\r\n" "//==============================================================================\r\n" -"bool %%filter_class_name%%::hasEditor() const\r\n" +"%%content_component_class%%::%%content_component_class%%()\r\n" "{\r\n" -" return true; // (change this to false if you choose to not supply an editor)\r\n" +" // Make sure you set the size of the component after\r\n" +" // you add any child components.\r\n" +" setSize (800, 600);\r\n" +" setFramesPerSecond (60); // This sets the frequency of the update calls.\r\n" "}\r\n" "\r\n" -"AudioProcessorEditor* %%filter_class_name%%::createEditor()\r\n" +"%%content_component_class%%::~%%content_component_class%%()\r\n" "{\r\n" -" return new %%editor_class_name%% (*this);\r\n" "}\r\n" "\r\n" "//==============================================================================\r\n" -"void %%filter_class_name%%::getStateInformation (MemoryBlock& destData)\r\n" +"void %%content_component_class%%::update()\r\n" "{\r\n" -" // You should use this method to store your parameters in the memory block.\r\n" -" // You could do that either as raw data, or use the XML or ValueTree classes\r\n" -" // as intermediaries to make it easy to save and load complex data.\r\n" +" // This function is called at the frequency specified by the setFramesPerSecond() call\r\n" +" // in the constructor. You can use it to update counters, animate values, etc.\r\n" "}\r\n" "\r\n" -"void %%filter_class_name%%::setStateInformation (const void* data, int sizeInBytes)\r\n" +"//==============================================================================\r\n" +"void %%content_component_class%%::paint (juce::Graphics& g)\r\n" "{\r\n" -" // You should use this method to restore your parameters from this memory block,\r\n" -" // whose contents will have been created by the getStateInformation() call.\r\n" +" // (Our component is opaque, so we must completely fill the background with a solid colour)\r\n" +" g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId));\r\n" +"\r\n" +" // You can add your drawing code here!\r\n" "}\r\n" "\r\n" -"//==============================================================================\r\n" -"// This creates new instances of the plugin..\r\n" -"AudioProcessor* JUCE_CALLTYPE createPluginFilter()\r\n" +"void %%content_component_class%%::resized()\r\n" "{\r\n" -" return new %%filter_class_name%%();\r\n" +" // This is called when the MainContentComponent is resized.\r\n" +" // If you add any child components, this is where you should\r\n" +" // update their positions.\r\n" "}\r\n"; -const char* jucer_AudioPluginFilterTemplate_cpp = (const char*) temp_binary_data_32; +const char* jucer_AnimatedComponentTemplate_cpp = (const char*) temp_binary_data_31; -//================== jucer_AudioPluginFilterTemplate.h ================== -static const unsigned char temp_binary_data_33[] = +//================== jucer_AnimatedComponentTemplate.h ================== +static const unsigned char temp_binary_data_32[] = +"#pragma once\r\n" +"\r\n" +"%%include_juce%%\r\n" +"\r\n" +"//==============================================================================\r\n" "/*\r\n" -" ==============================================================================\r\n" +" This component lives inside our window, and this is where you should put all\r\n" +" your controls and content.\r\n" +"*/\r\n" +"class %%content_component_class%% : public juce::AnimatedAppComponent\r\n" +"{\r\n" +"public:\r\n" +" //==============================================================================\r\n" +" %%content_component_class%%();\r\n" +" ~%%content_component_class%%() override;\r\n" +"\r\n" +" //==============================================================================\r\n" +" void update() override;\r\n" "\r\n" -" This file was auto-generated!\r\n" +" //==============================================================================\r\n" +" void paint (juce::Graphics& g) override;\r\n" +" void resized() override;\r\n" "\r\n" -" It contains the basic framework code for a JUCE plugin processor.\r\n" +"private:\r\n" +" //==============================================================================\r\n" +" // Your private member variables go here...\r\n" "\r\n" -" ==============================================================================\r\n" -"*/\r\n" "\r\n" +" JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%content_component_class%%)\r\n" +"};\r\n"; + +const char* jucer_AnimatedComponentTemplate_h = (const char*) temp_binary_data_32; + +//================== jucer_AudioComponentSimpleTemplate.h ================== +static const unsigned char temp_binary_data_33[] = "#pragma once\r\n" "\r\n" -"%%app_headers%%\r\n" +"%%include_juce%%\r\n" "\r\n" "//==============================================================================\r\n" -"/**\r\n" +"/*\r\n" +" This component lives inside our window, and this is where you should put all\r\n" +" your controls and content.\r\n" "*/\r\n" -"class %%filter_class_name%% : public AudioProcessor\r\n" +"class %%content_component_class%% : public juce::AudioAppComponent\r\n" "{\r\n" "public:\r\n" " //==============================================================================\r\n" -" %%filter_class_name%%();\r\n" -" ~%%filter_class_name%%();\r\n" +" %%content_component_class%%()\r\n" +" {\r\n" +" // Make sure you set the size of the component after\r\n" +" // you add any child components.\r\n" +" setSize (800, 600);\r\n" +"\r\n" +" // Some platforms require permissions to open input channels so request that here\r\n" +" if (juce::RuntimePermissions::isRequired (juce::RuntimePermissions::recordAudio)\r\n" +" && ! juce::RuntimePermissions::isGranted (juce::RuntimePermissions::recordAudio))\r\n" +" {\r\n" +" juce::RuntimePermissions::request (juce::RuntimePermissions::recordAudio,\r\n" +" [&] (bool granted) { setAudioChannels (granted ? 2 : 0, 2); });\r\n" +" }\r\n" +" else\r\n" +" {\r\n" +" // Specify the number of input and output channels that we want to open\r\n" +" setAudioChannels (2, 2);\r\n" +" }\r\n" +" }\r\n" +"\r\n" +" ~%%content_component_class%%() override\r\n" +" {\r\n" +" // This shuts down the audio device and clears the audio source.\r\n" +" shutdownAudio();\r\n" +" }\r\n" "\r\n" " //==============================================================================\r\n" -" void prepareToPlay (double sampleRate, int samplesPerBlock) override;\r\n" -" void releaseResources() override;\r\n" +" void prepareToPlay (int samplesPerBlockExpected, double sampleRate) override\r\n" +" {\r\n" +" // This function will be called when the audio device is started, or when\r\n" +" // its settings (i.e. sample rate, block size, etc) are changed.\r\n" "\r\n" -" #ifndef JucePlugin_PreferredChannelConfigurations\r\n" -" bool isBusesLayoutSupported (const BusesLayout& layouts) const override;\r\n" -" #endif\r\n" +" // You can use this function to initialise any resources you might need,\r\n" +" // but be careful - it will be called on the audio thread, not the GUI thread.\r\n" "\r\n" -" void processBlock (AudioBuffer<float>&, MidiBuffer&) override;\r\n" +" // For more details, see the help for AudioProcessor::prepareToPlay()\r\n" +" }\r\n" "\r\n" -" //==============================================================================\r\n" -" AudioProcessorEditor* createEditor() override;\r\n" -" bool hasEditor() const override;\r\n" +" void getNextAudioBlock (const juce::AudioSourceChannelInfo& bufferToFill) override\r\n" +" {\r\n" +" // Your audio-processing code goes here!\r\n" "\r\n" -" //==============================================================================\r\n" -" const String getName() const override;\r\n" +" // For more details, see the help for AudioProcessor::getNextAudioBlock()\r\n" "\r\n" -" bool acceptsMidi() const override;\r\n" -" bool producesMidi() const override;\r\n" -" bool isMidiEffect() const override;\r\n" -" double getTailLengthSeconds() const override;\r\n" +" // Right now we are not producing any data, in which case we need to clear the buffer\r\n" +" // (to prevent the output of random noise)\r\n" +" bufferToFill.clearActiveBufferRegion();\r\n" +" }\r\n" +"\r\n" +" void releaseResources() override\r\n" +" {\r\n" +" // This will be called when the audio device stops, or when it is being\r\n" +" // restarted due to a setting change.\r\n" +"\r\n" +" // For more details, see the help for AudioProcessor::releaseResources()\r\n" +" }\r\n" "\r\n" " //==============================================================================\r\n" -" int getNumPrograms() override;\r\n" -" int getCurrentProgram() override;\r\n" -" void setCurrentProgram (int index) override;\r\n" -" const String getProgramName (int index) override;\r\n" -" void changeProgramName (int index, const String& newName) override;\r\n" +" void paint (juce::Graphics& g) override\r\n" +" {\r\n" +" // (Our component is opaque, so we must completely fill the background with a solid colour)\r\n" +" g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId));\r\n" +"\r\n" +" // You can add your drawing code here!\r\n" +" }\r\n" +"\r\n" +" void resized() override\r\n" +" {\r\n" +" // This is called when the MainContentComponent is resized.\r\n" +" // If you add any child components, this is where you should\r\n" +" // update their positions.\r\n" +" }\r\n" "\r\n" -" //==============================================================================\r\n" -" void getStateInformation (MemoryBlock& destData) override;\r\n" -" void setStateInformation (const void* data, int sizeInBytes) override;\r\n" "\r\n" "private:\r\n" " //==============================================================================\r\n" -" JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%filter_class_name%%)\r\n" +" // Your private member variables go here...\r\n" +"\r\n" +"\r\n" +" JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%content_component_class%%)\r\n" "};\r\n"; -const char* jucer_AudioPluginFilterTemplate_h = (const char*) temp_binary_data_33; +const char* jucer_AudioComponentSimpleTemplate_h = (const char*) temp_binary_data_33; -//================== jucer_ComponentTemplate.cpp ================== +//================== jucer_AudioComponentTemplate.cpp ================== static const unsigned char temp_binary_data_34[] = -"/*\r\n" -" ==============================================================================\r\n" -"\r\n" -" This is an automatically generated GUI class created by the Projucer!\r\n" -"\r\n" -" Be careful when adding custom code to these files, as only the code within\r\n" -" the \"//[xyz]\" and \"//[/xyz]\" sections will be retained when the file is loaded\r\n" -" and re-saved.\r\n" -"\r\n" -" Created with Projucer version: %%version%%\r\n" -"\r\n" -" ------------------------------------------------------------------------------\r\n" -"\r\n" -" The Projucer is part of the JUCE library.\r\n" -" Copyright (c) 2017 - ROLI Ltd.\r\n" -"\r\n" -" ==============================================================================\r\n" -"*/\r\n" +"%%include_corresponding_header%%\r\n" "\r\n" -"//[Headers] You can add your own extra header files here...\r\n" -"//[/Headers]\r\n" +"//==============================================================================\r\n" +"%%content_component_class%%::%%content_component_class%%()\r\n" +"{\r\n" +" // Make sure you set the size of the component after\r\n" +" // you add any child components.\r\n" +" setSize (800, 600);\r\n" "\r\n" -"%%include_files_cpp%%\r\n" +" // Some platforms require permissions to open input channels so request that here\r\n" +" if (juce::RuntimePermissions::isRequired (juce::RuntimePermissions::recordAudio)\r\n" +" && ! juce::RuntimePermissions::isGranted (juce::RuntimePermissions::recordAudio))\r\n" +" {\r\n" +" juce::RuntimePermissions::request (juce::RuntimePermissions::recordAudio,\r\n" +" [&] (bool granted) { setAudioChannels (granted ? 2 : 0, 2); });\r\n" +" }\r\n" +" else\r\n" +" {\r\n" +" // Specify the number of input and output channels that we want to open\r\n" +" setAudioChannels (2, 2);\r\n" +" }\r\n" +"}\r\n" "\r\n" -"//[MiscUserDefs] You can add your own user definitions and misc code here...\r\n" -"//[/MiscUserDefs]\r\n" +"%%content_component_class%%::~%%content_component_class%%()\r\n" +"{\r\n" +" // This shuts down the audio device and clears the audio source.\r\n" +" shutdownAudio();\r\n" +"}\r\n" "\r\n" "//==============================================================================\r\n" -"%%class_name%%::%%class_name%% (%%constructor_params%%)\r\n" -"%%initialisers%%{\r\n" -" //[Constructor_pre] You can add your own custom stuff here..\r\n" -" //[/Constructor_pre]\r\n" +"void %%content_component_class%%::prepareToPlay (int samplesPerBlockExpected, double sampleRate)\r\n" +"{\r\n" +" // This function will be called when the audio device is started, or when\r\n" +" // its settings (i.e. sample rate, block size, etc) are changed.\r\n" "\r\n" -" %%constructor%%\r\n" +" // You can use this function to initialise any resources you might need,\r\n" +" // but be careful - it will be called on the audio thread, not the GUI thread.\r\n" "\r\n" -" //[Constructor] You can add your own custom stuff here..\r\n" -" //[/Constructor]\r\n" +" // For more details, see the help for AudioProcessor::prepareToPlay()\r\n" "}\r\n" "\r\n" -"%%class_name%%::~%%class_name%%()\r\n" +"void %%content_component_class%%::getNextAudioBlock (const juce::AudioSourceChannelInfo& bufferToFill)\r\n" "{\r\n" -" //[Destructor_pre]. You can add your own custom destruction code here..\r\n" -" //[/Destructor_pre]\r\n" +" // Your audio-processing code goes here!\r\n" "\r\n" -" %%destructor%%\r\n" +" // For more details, see the help for AudioProcessor::getNextAudioBlock()\r\n" "\r\n" -" //[Destructor]. You can add your own custom destruction code here..\r\n" -" //[/Destructor]\r\n" +" // Right now we are not producing any data, in which case we need to clear the buffer\r\n" +" // (to prevent the output of random noise)\r\n" +" bufferToFill.clearActiveBufferRegion();\r\n" "}\r\n" "\r\n" -"//==============================================================================\r\n" -"%%method_definitions%%\r\n" -"\r\n" -"//[MiscUserCode] You can add your own definitions of your custom methods or any other code here...\r\n" -"//[/MiscUserCode]\r\n" +"void %%content_component_class%%::releaseResources()\r\n" +"{\r\n" +" // This will be called when the audio device stops, or when it is being\r\n" +" // restarted due to a setting change.\r\n" "\r\n" +" // For more details, see the help for AudioProcessor::releaseResources()\r\n" +"}\r\n" "\r\n" "//==============================================================================\r\n" -"#if 0\r\n" -"/* -- Projucer information section --\r\n" -"\r\n" -" This is where the Projucer stores the metadata that describe this GUI layout, so\r\n" -" make changes in here at your peril!\r\n" -"\r\n" -"BEGIN_JUCER_METADATA\r\n" +"void %%content_component_class%%::paint (juce::Graphics& g)\r\n" +"{\r\n" +" // (Our component is opaque, so we must completely fill the background with a solid colour)\r\n" +" g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId));\r\n" "\r\n" -"%%metadata%%\r\n" -"END_JUCER_METADATA\r\n" -"*/\r\n" -"#endif\r\n" +" // You can add your drawing code here!\r\n" +"}\r\n" "\r\n" -"%%static_member_definitions%%\r\n" -"//[EndFile] You can add extra defines here...\r\n" -"//[/EndFile]\r\n"; +"void %%content_component_class%%::resized()\r\n" +"{\r\n" +" // This is called when the MainContentComponent is resized.\r\n" +" // If you add any child components, this is where you should\r\n" +" // update their positions.\r\n" +"}\r\n"; -const char* jucer_ComponentTemplate_cpp = (const char*) temp_binary_data_34; +const char* jucer_AudioComponentTemplate_cpp = (const char*) temp_binary_data_34; -//================== jucer_ComponentTemplate.h ================== +//================== jucer_AudioComponentTemplate.h ================== static const unsigned char temp_binary_data_35[] = -"/*\r\n" -" ==============================================================================\r\n" -"\r\n" -" This is an automatically generated GUI class created by the Projucer!\r\n" -"\r\n" -" Be careful when adding custom code to these files, as only the code within\r\n" -" the \"//[xyz]\" and \"//[/xyz]\" sections will be retained when the file is loaded\r\n" -" and re-saved.\r\n" -"\r\n" -" Created with Projucer version: %%version%%\r\n" -"\r\n" -" ------------------------------------------------------------------------------\r\n" -"\r\n" -" The Projucer is part of the JUCE library.\r\n" -" Copyright (c) 2017 - ROLI Ltd.\r\n" -"\r\n" -" ==============================================================================\r\n" -"*/\r\n" -"\r\n" "#pragma once\r\n" "\r\n" -"//[Headers] -- You can add your own extra header files here --\r\n" "%%include_juce%%\r\n" -"//[/Headers]\r\n" -"\r\n" -"%%include_files_h%%\r\n" "\r\n" "//==============================================================================\r\n" -"/**\r\n" -" //[Comments]\r\n" -" An auto-generated component, created by the Projucer.\r\n" -"\r\n" -" Describe your class and how it works here!\r\n" -" //[/Comments]\r\n" +"/*\r\n" +" This component lives inside our window, and this is where you should put all\r\n" +" your controls and content.\r\n" "*/\r\n" -"%%class_declaration%%\r\n" +"class %%content_component_class%% : public juce::AudioAppComponent\r\n" "{\r\n" "public:\r\n" " //==============================================================================\r\n" -" %%class_name%% (%%constructor_params%%);\r\n" -" ~%%class_name%%() override;\r\n" +" %%content_component_class%%();\r\n" +" ~%%content_component_class%%() override;\r\n" "\r\n" " //==============================================================================\r\n" -" //[UserMethods] -- You can add your own custom methods in this section.\r\n" -" //[/UserMethods]\r\n" +" void prepareToPlay (int samplesPerBlockExpected, double sampleRate) override;\r\n" +" void getNextAudioBlock (const juce::AudioSourceChannelInfo& bufferToFill) override;\r\n" +" void releaseResources() override;\r\n" "\r\n" -" %%public_member_declarations%%\r\n" +" //==============================================================================\r\n" +" void paint (juce::Graphics& g) override;\r\n" +" void resized() override;\r\n" "\r\n" "private:\r\n" -" //[UserVariables] -- You can add your own custom variables in this section.\r\n" -" //[/UserVariables]\r\n" -"\r\n" " //==============================================================================\r\n" -" %%private_member_declarations%%\r\n" +" // Your private member variables go here...\r\n" "\r\n" -" //==============================================================================\r\n" -" JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%class_name%%)\r\n" -"};\r\n" "\r\n" -"//[EndFile] You can add extra defines here...\r\n" -"//[/EndFile]\r\n"; +" JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%content_component_class%%)\r\n" +"};\r\n"; -const char* jucer_ComponentTemplate_h = (const char*) temp_binary_data_35; +const char* jucer_AudioComponentTemplate_h = (const char*) temp_binary_data_35; -//================== jucer_ContentCompSimpleTemplate.h ================== +//================== jucer_AudioPluginEditorTemplate.cpp ================== static const unsigned char temp_binary_data_36[] = "/*\r\n" " ==============================================================================\r\n" "\r\n" -" This file was auto-generated!\r\n" +" This file contains the basic framework code for a JUCE plugin editor.\r\n" "\r\n" " ==============================================================================\r\n" "*/\r\n" "\r\n" -"#pragma once\r\n" +"%%editor_cpp_headers%%\r\n" "\r\n" -"%%include_juce%%\r\n" +"//==============================================================================\r\n" +"%%editor_class_name%%::%%editor_class_name%% (%%filter_class_name%%& p)\r\n" +" : AudioProcessorEditor (&p), audioProcessor (p)\r\n" +"{\r\n" +" // Make sure that before the constructor has finished, you've set the\r\n" +" // editor's size to whatever you need it to be.\r\n" +" setSize (400, 300);\r\n" +"}\r\n" +"\r\n" +"%%editor_class_name%%::~%%editor_class_name%%()\r\n" +"{\r\n" +"}\r\n" "\r\n" "//==============================================================================\r\n" -"/*\r\n" -" This component lives inside our window, and this is where you should put all\r\n" -" your controls and content.\r\n" -"*/\r\n" -"class %%content_component_class%% : public Component\r\n" +"void %%editor_class_name%%::paint (juce::Graphics& g)\r\n" "{\r\n" -"public:\r\n" -" //==============================================================================\r\n" -" %%content_component_class%%()\r\n" -" {\r\n" -" setSize (600, 400);\r\n" -" }\r\n" +" // (Our component is opaque, so we must completely fill the background with a solid colour)\r\n" +" g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId));\r\n" "\r\n" -" ~%%content_component_class%%()\r\n" -" {\r\n" -" }\r\n" +" g.setColour (juce::Colours::white);\r\n" +" g.setFont (15.0f);\r\n" +" g.drawFittedText (\"Hello World!\", getLocalBounds(), juce::Justification::centred, 1);\r\n" +"}\r\n" "\r\n" -" //==============================================================================\r\n" -" void paint (Graphics& g) override\r\n" -" {\r\n" -" // (Our component is opaque, so we must completely fill the background with a solid colour)\r\n" -" g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId));\r\n" +"void %%editor_class_name%%::resized()\r\n" +"{\r\n" +" // This is generally where you'll want to lay out the positions of any\r\n" +" // subcomponents in your editor..\r\n" +"}\r\n"; + +const char* jucer_AudioPluginEditorTemplate_cpp = (const char*) temp_binary_data_36; + +//================== jucer_AudioPluginEditorTemplate.h ================== +static const unsigned char temp_binary_data_37[] = +"/*\r\n" +" ==============================================================================\r\n" "\r\n" -" g.setFont (Font (16.0f));\r\n" -" g.setColour (Colours::white);\r\n" -" g.drawText (\"Hello World!\", getLocalBounds(), Justification::centred, true);\r\n" -" }\r\n" +" This file contains the basic framework code for a JUCE plugin editor.\r\n" "\r\n" -" void resized() override\r\n" -" {\r\n" -" // This is called when the %%content_component_class%% is resized.\r\n" -" // If you add any child components, this is where you should\r\n" -" // update their positions.\r\n" -" }\r\n" +" ==============================================================================\r\n" +"*/\r\n" "\r\n" +"#pragma once\r\n" +"\r\n" +"%%editor_headers%%\r\n" +"\r\n" +"//==============================================================================\r\n" +"/**\r\n" +"*/\r\n" +"class %%editor_class_name%% : public juce::AudioProcessorEditor\r\n" +"{\r\n" +"public:\r\n" +" %%editor_class_name%% (%%filter_class_name%%&);\r\n" +" ~%%editor_class_name%%() override;\r\n" "\r\n" -"private:\r\n" " //==============================================================================\r\n" -" // Your private member variables go here...\r\n" +" void paint (juce::Graphics&) override;\r\n" +" void resized() override;\r\n" "\r\n" +"private:\r\n" +" // This reference is provided as a quick way for your editor to\r\n" +" // access the processor object that created it.\r\n" +" %%filter_class_name%%& audioProcessor;\r\n" "\r\n" -" JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%content_component_class%%)\r\n" +" JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%editor_class_name%%)\r\n" "};\r\n"; -const char* jucer_ContentCompSimpleTemplate_h = (const char*) temp_binary_data_36; +const char* jucer_AudioPluginEditorTemplate_h = (const char*) temp_binary_data_37; -//================== jucer_ContentCompTemplate.cpp ================== -static const unsigned char temp_binary_data_37[] = +//================== jucer_AudioPluginFilterTemplate.cpp ================== +static const unsigned char temp_binary_data_38[] = "/*\r\n" " ==============================================================================\r\n" "\r\n" -" This file was auto-generated!\r\n" +" This file contains the basic framework code for a JUCE plugin processor.\r\n" "\r\n" " ==============================================================================\r\n" "*/\r\n" "\r\n" -"%%include_corresponding_header%%\r\n" +"%%filter_headers%%\r\n" "\r\n" "//==============================================================================\r\n" -"%%content_component_class%%::%%content_component_class%%()\r\n" +"%%filter_class_name%%::%%filter_class_name%%()\r\n" +"#ifndef JucePlugin_PreferredChannelConfigurations\r\n" +" : AudioProcessor (BusesProperties()\r\n" +" #if ! JucePlugin_IsMidiEffect\r\n" +" #if ! JucePlugin_IsSynth\r\n" +" .withInput (\"Input\", juce::AudioChannelSet::stereo(), true)\r\n" +" #endif\r\n" +" .withOutput (\"Output\", juce::AudioChannelSet::stereo(), true)\r\n" +" #endif\r\n" +" )\r\n" +"#endif\r\n" "{\r\n" -" setSize (600, 400);\r\n" "}\r\n" "\r\n" -"%%content_component_class%%::~%%content_component_class%%()\r\n" +"%%filter_class_name%%::~%%filter_class_name%%()\r\n" "{\r\n" "}\r\n" "\r\n" "//==============================================================================\r\n" -"void %%content_component_class%%::paint (Graphics& g)\r\n" +"const juce::String %%filter_class_name%%::getName() const\r\n" "{\r\n" -" // (Our component is opaque, so we must completely fill the background with a solid colour)\r\n" -" g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId));\r\n" -"\r\n" -" g.setFont (Font (16.0f));\r\n" -" g.setColour (Colours::white);\r\n" -" g.drawText (\"Hello World!\", getLocalBounds(), Justification::centred, true);\r\n" +" return JucePlugin_Name;\r\n" "}\r\n" "\r\n" -"void %%content_component_class%%::resized()\r\n" +"bool %%filter_class_name%%::acceptsMidi() const\r\n" "{\r\n" -" // This is called when the %%content_component_class%% is resized.\r\n" -" // If you add any child components, this is where you should\r\n" -" // update their positions.\r\n" -"}\r\n"; - -const char* jucer_ContentCompTemplate_cpp = (const char*) temp_binary_data_37; - -//================== jucer_ContentCompTemplate.h ================== -static const unsigned char temp_binary_data_38[] = -"/*\r\n" -" ==============================================================================\r\n" +" #if JucePlugin_WantsMidiInput\r\n" +" return true;\r\n" +" #else\r\n" +" return false;\r\n" +" #endif\r\n" +"}\r\n" "\r\n" -" This file was auto-generated!\r\n" +"bool %%filter_class_name%%::producesMidi() const\r\n" +"{\r\n" +" #if JucePlugin_ProducesMidiOutput\r\n" +" return true;\r\n" +" #else\r\n" +" return false;\r\n" +" #endif\r\n" +"}\r\n" "\r\n" -" ==============================================================================\r\n" -"*/\r\n" +"bool %%filter_class_name%%::isMidiEffect() const\r\n" +"{\r\n" +" #if JucePlugin_IsMidiEffect\r\n" +" return true;\r\n" +" #else\r\n" +" return false;\r\n" +" #endif\r\n" +"}\r\n" "\r\n" -"#pragma once\r\n" +"double %%filter_class_name%%::getTailLengthSeconds() const\r\n" +"{\r\n" +" return 0.0;\r\n" +"}\r\n" "\r\n" -"%%include_juce%%\r\n" +"int %%filter_class_name%%::getNumPrograms()\r\n" +"{\r\n" +" return 1; // NB: some hosts don't cope very well if you tell them there are 0 programs,\r\n" +" // so this should be at least 1, even if you're not really implementing programs.\r\n" +"}\r\n" "\r\n" -"//==============================================================================\r\n" -"/*\r\n" -" This component lives inside our window, and this is where you should put all\r\n" -" your controls and content.\r\n" -"*/\r\n" -"class %%content_component_class%% : public Component\r\n" +"int %%filter_class_name%%::getCurrentProgram()\r\n" "{\r\n" -"public:\r\n" -" //==============================================================================\r\n" -" %%content_component_class%%();\r\n" -" ~%%content_component_class%%();\r\n" +" return 0;\r\n" +"}\r\n" "\r\n" -" //==============================================================================\r\n" -" void paint (Graphics&) override;\r\n" -" void resized() override;\r\n" +"void %%filter_class_name%%::setCurrentProgram (int index)\r\n" +"{\r\n" +"}\r\n" "\r\n" -"private:\r\n" -" //==============================================================================\r\n" -" // Your private member variables go here...\r\n" +"const juce::String %%filter_class_name%%::getProgramName (int index)\r\n" +"{\r\n" +" return {};\r\n" +"}\r\n" "\r\n" +"void %%filter_class_name%%::changeProgramName (int index, const juce::String& newName)\r\n" +"{\r\n" +"}\r\n" "\r\n" -" JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%content_component_class%%)\r\n" -"};\r\n"; - -const char* jucer_ContentCompTemplate_h = (const char*) temp_binary_data_38; - -//================== jucer_InlineComponentTemplate.h ================== -static const unsigned char temp_binary_data_39[] = "//==============================================================================\r\n" -"class %%component_class%% : public Component\r\n" +"void %%filter_class_name%%::prepareToPlay (double sampleRate, int samplesPerBlock)\r\n" "{\r\n" -"public:\r\n" -" %%component_class%%()\r\n" -" {\r\n" -" // In your constructor, you should add any child components, and\r\n" -" // initialise any special settings that your component needs.\r\n" +" // Use this method as the place to do any pre-playback\r\n" +" // initialisation that you need..\r\n" +"}\r\n" "\r\n" -" }\r\n" +"void %%filter_class_name%%::releaseResources()\r\n" +"{\r\n" +" // When playback stops, you can use this as an opportunity to free up any\r\n" +" // spare memory, etc.\r\n" +"}\r\n" "\r\n" -" ~%%component_class%%()\r\n" -" {\r\n" -" }\r\n" +"#ifndef JucePlugin_PreferredChannelConfigurations\r\n" +"bool %%filter_class_name%%::isBusesLayoutSupported (const BusesLayout& layouts) const\r\n" +"{\r\n" +" #if JucePlugin_IsMidiEffect\r\n" +" juce::ignoreUnused (layouts);\r\n" +" return true;\r\n" +" #else\r\n" +" // This is the place where you check if the layout is supported.\r\n" +" // In this template code we only support mono or stereo.\r\n" +" if (layouts.getMainOutputChannelSet() != juce::AudioChannelSet::mono()\r\n" +" && layouts.getMainOutputChannelSet() != juce::AudioChannelSet::stereo())\r\n" +" return false;\r\n" "\r\n" -" void paint (Graphics& g) override\r\n" -" {\r\n" -" // You should replace everything in this method with your own drawing code..\r\n" +" // This checks if the input layout matches the output layout\r\n" +" #if ! JucePlugin_IsSynth\r\n" +" if (layouts.getMainOutputChannelSet() != layouts.getMainInputChannelSet())\r\n" +" return false;\r\n" +" #endif\r\n" "\r\n" -" g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId)); // clear the background\r\n" +" return true;\r\n" +" #endif\r\n" +"}\r\n" +"#endif\r\n" "\r\n" -" g.setColour (Colours::grey);\r\n" -" g.drawRect (getLocalBounds(), 1); // draw an outline around the component\r\n" +"void %%filter_class_name%%::processBlock (juce::AudioBuffer<float>& buffer, juce::MidiBuffer& midiMessages)\r\n" +"{\r\n" +" juce::ScopedNoDenormals noDenormals;\r\n" +" auto totalNumInputChannels = getTotalNumInputChannels();\r\n" +" auto totalNumOutputChannels = getTotalNumOutputChannels();\r\n" "\r\n" -" g.setColour (Colours::white);\r\n" -" g.setFont (14.0f);\r\n" -" g.drawText (\"%%component_class%%\", getLocalBounds(),\r\n" -" Justification::centred, true); // draw some placeholder text\r\n" -" }\r\n" +" // In case we have more outputs than inputs, this code clears any output\r\n" +" // channels that didn't contain input data, (because these aren't\r\n" +" // guaranteed to be empty - they may contain garbage).\r\n" +" // This is here to avoid people getting screaming feedback\r\n" +" // when they first compile a plugin, but obviously you don't need to keep\r\n" +" // this code if your algorithm always overwrites all the output channels.\r\n" +" for (auto i = totalNumInputChannels; i < totalNumOutputChannels; ++i)\r\n" +" buffer.clear (i, 0, buffer.getNumSamples());\r\n" "\r\n" -" void resized() override\r\n" +" // This is the place where you'd normally do the guts of your plugin's\r\n" +" // audio processing...\r\n" +" // Make sure to reset the state if your inner loop is processing\r\n" +" // the samples and the outer loop is handling the channels.\r\n" +" // Alternatively, you can process the samples with the channels\r\n" +" // interleaved by keeping the same state.\r\n" +" for (int channel = 0; channel < totalNumInputChannels; ++channel)\r\n" " {\r\n" -" // This method is where you should set the bounds of any child\r\n" -" // components that your component contains..\r\n" +" auto* channelData = buffer.getWritePointer (channel);\r\n" "\r\n" +" // ..do something to the data...\r\n" " }\r\n" +"}\r\n" "\r\n" -"private:\r\n" -" JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%component_class%%)\r\n" -"};\r\n"; - -const char* jucer_InlineComponentTemplate_h = (const char*) temp_binary_data_39; - -//================== jucer_MainConsoleAppTemplate.cpp ================== -static const unsigned char temp_binary_data_40[] = -"/*\r\n" -" ==============================================================================\r\n" -"\r\n" -" This file was auto-generated!\r\n" -"\r\n" -" It contains the basic startup code for a JUCE application.\r\n" -"\r\n" -" ==============================================================================\r\n" -"*/\r\n" +"//==============================================================================\r\n" +"bool %%filter_class_name%%::hasEditor() const\r\n" +"{\r\n" +" return true; // (change this to false if you choose to not supply an editor)\r\n" +"}\r\n" "\r\n" -"%%app_headers%%\r\n" +"juce::AudioProcessorEditor* %%filter_class_name%%::createEditor()\r\n" +"{\r\n" +" return new %%editor_class_name%% (*this);\r\n" +"}\r\n" "\r\n" "//==============================================================================\r\n" -"int main (int argc, char* argv[])\r\n" +"void %%filter_class_name%%::getStateInformation (juce::MemoryBlock& destData)\r\n" "{\r\n" +" // You should use this method to store your parameters in the memory block.\r\n" +" // You could do that either as raw data, or use the XML or ValueTree classes\r\n" +" // as intermediaries to make it easy to save and load complex data.\r\n" +"}\r\n" "\r\n" -" // ..your code goes here!\r\n" -"\r\n" +"void %%filter_class_name%%::setStateInformation (const void* data, int sizeInBytes)\r\n" +"{\r\n" +" // You should use this method to restore your parameters from this memory block,\r\n" +" // whose contents will have been created by the getStateInformation() call.\r\n" +"}\r\n" "\r\n" -" return 0;\r\n" +"//==============================================================================\r\n" +"// This creates new instances of the plugin..\r\n" +"juce::AudioProcessor* JUCE_CALLTYPE createPluginFilter()\r\n" +"{\r\n" +" return new %%filter_class_name%%();\r\n" "}\r\n"; -const char* jucer_MainConsoleAppTemplate_cpp = (const char*) temp_binary_data_40; +const char* jucer_AudioPluginFilterTemplate_cpp = (const char*) temp_binary_data_38; -//================== jucer_MainTemplate_NoWindow.cpp ================== -static const unsigned char temp_binary_data_41[] = +//================== jucer_AudioPluginFilterTemplate.h ================== +static const unsigned char temp_binary_data_39[] = "/*\r\n" " ==============================================================================\r\n" "\r\n" -" This file was auto-generated!\r\n" -"\r\n" -" It contains the basic startup code for a JUCE application.\r\n" +" This file contains the basic framework code for a JUCE plugin processor.\r\n" "\r\n" " ==============================================================================\r\n" "*/\r\n" "\r\n" +"#pragma once\r\n" +"\r\n" "%%app_headers%%\r\n" "\r\n" "//==============================================================================\r\n" -"class %%app_class_name%% : public JUCEApplication\r\n" +"/**\r\n" +"*/\r\n" +"class %%filter_class_name%% : public juce::AudioProcessor\r\n" "{\r\n" "public:\r\n" " //==============================================================================\r\n" -" %%app_class_name%%() {}\r\n" +" %%filter_class_name%%();\r\n" +" ~%%filter_class_name%%() override;\r\n" +"\r\n" +" //==============================================================================\r\n" +" void prepareToPlay (double sampleRate, int samplesPerBlock) override;\r\n" +" void releaseResources() override;\r\n" +"\r\n" +" #ifndef JucePlugin_PreferredChannelConfigurations\r\n" +" bool isBusesLayoutSupported (const BusesLayout& layouts) const override;\r\n" +" #endif\r\n" "\r\n" -" const String getApplicationName() override { return ProjectInfo::projectName; }\r\n" -" const String getApplicationVersion() override { return ProjectInfo::versionString; }\r\n" -" bool moreThanOneInstanceAllowed() override { return %%allow_more_than_one_instance%%; }\r\n" +" void processBlock (juce::AudioBuffer<float>&, juce::MidiBuffer&) override;\r\n" "\r\n" " //==============================================================================\r\n" -" void initialise (const String& commandLine) override\r\n" -" {\r\n" -" // Add your application's initialisation code here..\r\n" -" }\r\n" +" juce::AudioProcessorEditor* createEditor() override;\r\n" +" bool hasEditor() const override;\r\n" "\r\n" -" void shutdown() override\r\n" -" {\r\n" -" // Add your application's shutdown code here..\r\n" -" }\r\n" +" //==============================================================================\r\n" +" const juce::String getName() const override;\r\n" +"\r\n" +" bool acceptsMidi() const override;\r\n" +" bool producesMidi() const override;\r\n" +" bool isMidiEffect() const override;\r\n" +" double getTailLengthSeconds() const override;\r\n" "\r\n" " //==============================================================================\r\n" -" void systemRequestedQuit() override\r\n" -" {\r\n" -" // This is called when the app is being asked to quit: you can ignore this\r\n" -" // request and let the app carry on running, or call quit() to allow the app to close.\r\n" -" quit();\r\n" -" }\r\n" +" int getNumPrograms() override;\r\n" +" int getCurrentProgram() override;\r\n" +" void setCurrentProgram (int index) override;\r\n" +" const juce::String getProgramName (int index) override;\r\n" +" void changeProgramName (int index, const juce::String& newName) override;\r\n" "\r\n" -" void anotherInstanceStarted (const String& commandLine) override\r\n" -" {\r\n" -" // When another instance of the app is launched while this one is running,\r\n" -" // this method is invoked, and the commandLine parameter tells you what\r\n" -" // the other instance's command-line arguments were.\r\n" -" }\r\n" -"};\r\n" +" //==============================================================================\r\n" +" void getStateInformation (juce::MemoryBlock& destData) override;\r\n" +" void setStateInformation (const void* data, int sizeInBytes) override;\r\n" "\r\n" -"//==============================================================================\r\n" -"// This macro generates the main() routine that launches the app.\r\n" -"START_JUCE_APPLICATION (%%app_class_name%%)\r\n"; +"private:\r\n" +" //==============================================================================\r\n" +" JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%filter_class_name%%)\r\n" +"};\r\n"; -const char* jucer_MainTemplate_NoWindow_cpp = (const char*) temp_binary_data_41; +const char* jucer_AudioPluginFilterTemplate_h = (const char*) temp_binary_data_39; -//================== jucer_MainTemplate_SimpleWindow.cpp ================== -static const unsigned char temp_binary_data_42[] = +//================== jucer_ComponentTemplate.cpp ================== +static const unsigned char temp_binary_data_40[] = "/*\r\n" " ==============================================================================\r\n" "\r\n" -" This file was auto-generated!\r\n" +" This is an automatically generated GUI class created by the Projucer!\r\n" +"\r\n" +" Be careful when adding custom code to these files, as only the code within\r\n" +" the \"//[xyz]\" and \"//[/xyz]\" sections will be retained when the file is loaded\r\n" +" and re-saved.\r\n" +"\r\n" +" Created with Projucer version: %%version%%\r\n" +"\r\n" +" ------------------------------------------------------------------------------\r\n" "\r\n" -" It contains the basic startup code for a JUCE application.\r\n" +" The Projucer is part of the JUCE library.\r\n" +" Copyright (c) 2020 - Raw Material Software Limited.\r\n" "\r\n" " ==============================================================================\r\n" "*/\r\n" "\r\n" -"%%app_headers%%\r\n" +"//[Headers] You can add your own extra header files here...\r\n" +"//[/Headers]\r\n" "\r\n" -"//==============================================================================\r\n" -"class %%app_class_name%% : public JUCEApplication\r\n" -"{\r\n" -"public:\r\n" -" //==============================================================================\r\n" -" %%app_class_name%%() {}\r\n" +"%%include_files_cpp%%\r\n" "\r\n" -" const String getApplicationName() override { return ProjectInfo::projectName; }\r\n" -" const String getApplicationVersion() override { return ProjectInfo::versionString; }\r\n" -" bool moreThanOneInstanceAllowed() override { return %%allow_more_than_one_instance%%; }\r\n" +"//[MiscUserDefs] You can add your own user definitions and misc code here...\r\n" +"//[/MiscUserDefs]\r\n" "\r\n" -" //==============================================================================\r\n" -" void initialise (const String& commandLine) override\r\n" -" {\r\n" -" // This method is where you should put your application's initialisation code..\r\n" +"//==============================================================================\r\n" +"%%class_name%%::%%class_name%% (%%constructor_params%%)\r\n" +"%%initialisers%%{\r\n" +" //[Constructor_pre] You can add your own custom stuff here..\r\n" +" //[/Constructor_pre]\r\n" "\r\n" -" mainWindow.reset (new MainWindow (getApplicationName()));\r\n" -" }\r\n" +" %%constructor%%\r\n" "\r\n" -" void shutdown() override\r\n" -" {\r\n" -" // Add your application's shutdown code here..\r\n" +" //[Constructor] You can add your own custom stuff here..\r\n" +" //[/Constructor]\r\n" +"}\r\n" "\r\n" -" mainWindow = nullptr; // (deletes our window)\r\n" -" }\r\n" +"%%class_name%%::~%%class_name%%()\r\n" +"{\r\n" +" //[Destructor_pre]. You can add your own custom destruction code here..\r\n" +" //[/Destructor_pre]\r\n" "\r\n" -" //==============================================================================\r\n" -" void systemRequestedQuit() override\r\n" -" {\r\n" -" // This is called when the app is being asked to quit: you can ignore this\r\n" -" // request and let the app carry on running, or call quit() to allow the app to close.\r\n" -" quit();\r\n" -" }\r\n" +" %%destructor%%\r\n" "\r\n" -" void anotherInstanceStarted (const String& commandLine) override\r\n" -" {\r\n" -" // When another instance of the app is launched while this one is running,\r\n" -" // this method is invoked, and the commandLine parameter tells you what\r\n" -" // the other instance's command-line arguments were.\r\n" -" }\r\n" +" //[Destructor]. You can add your own custom destruction code here..\r\n" +" //[/Destructor]\r\n" +"}\r\n" "\r\n" -" //==============================================================================\r\n" -" /*\r\n" -" This class implements the desktop window that contains an instance of\r\n" -" our %%content_component_class%% class.\r\n" -" */\r\n" -" class MainWindow : public DocumentWindow\r\n" -" {\r\n" -" public:\r\n" -" MainWindow (String name) : DocumentWindow (name,\r\n" -" Desktop::getInstance().getDefaultLookAndFeel()\r\n" -" .findColour (ResizableWindow::backgroundColourId),\r\n" -" DocumentWindow::allButtons)\r\n" -" {\r\n" -" setUsingNativeTitleBar (true);\r\n" -" setContentOwned (new %%content_component_class%%(), true);\r\n" +"//==============================================================================\r\n" +"%%method_definitions%%\r\n" "\r\n" -" #if JUCE_IOS || JUCE_ANDROID\r\n" -" setFullScreen (true);\r\n" -" #else\r\n" -" setResizable (true, true);\r\n" -" centreWithSize (getWidth(), getHeight());\r\n" -" #endif\r\n" +"//[MiscUserCode] You can add your own definitions of your custom methods or any other code here...\r\n" +"//[/MiscUserCode]\r\n" "\r\n" -" setVisible (true);\r\n" -" }\r\n" "\r\n" -" void closeButtonPressed() override\r\n" -" {\r\n" -" // This is called when the user tries to close this window. Here, we'll just\r\n" -" // ask the app to quit when this happens, but you can change this to do\r\n" -" // whatever you need.\r\n" -" JUCEApplication::getInstance()->systemRequestedQuit();\r\n" -" }\r\n" +"//==============================================================================\r\n" +"#if 0\r\n" +"/* -- Projucer information section --\r\n" "\r\n" -" /* Note: Be careful if you override any DocumentWindow methods - the base\r\n" -" class uses a lot of them, so by overriding you might break its functionality.\r\n" -" It's best to do all your work in your content component instead, but if\r\n" -" you really have to override any DocumentWindow methods, make sure your\r\n" -" subclass also calls the superclass's method.\r\n" -" */\r\n" +" This is where the Projucer stores the metadata that describe this GUI layout, so\r\n" +" make changes in here at your peril!\r\n" "\r\n" -" private:\r\n" -" JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainWindow)\r\n" -" };\r\n" +"BEGIN_JUCER_METADATA\r\n" "\r\n" -"private:\r\n" -" std::unique_ptr<MainWindow> mainWindow;\r\n" -"};\r\n" +"%%metadata%%\r\n" +"END_JUCER_METADATA\r\n" +"*/\r\n" +"#endif\r\n" "\r\n" -"//==============================================================================\r\n" -"// This macro generates the main() routine that launches the app.\r\n" -"START_JUCE_APPLICATION (%%app_class_name%%)\r\n"; +"%%static_member_definitions%%\r\n" +"//[EndFile] You can add extra defines here...\r\n" +"//[/EndFile]\r\n"; -const char* jucer_MainTemplate_SimpleWindow_cpp = (const char*) temp_binary_data_42; +const char* jucer_ComponentTemplate_cpp = (const char*) temp_binary_data_40; -//================== jucer_MainTemplate_Window.cpp ================== -static const unsigned char temp_binary_data_43[] = +//================== jucer_ComponentTemplate.h ================== +static const unsigned char temp_binary_data_41[] = "/*\r\n" " ==============================================================================\r\n" "\r\n" -" This file was auto-generated!\r\n" +" This is an automatically generated GUI class created by the Projucer!\r\n" +"\r\n" +" Be careful when adding custom code to these files, as only the code within\r\n" +" the \"//[xyz]\" and \"//[/xyz]\" sections will be retained when the file is loaded\r\n" +" and re-saved.\r\n" +"\r\n" +" Created with Projucer version: %%version%%\r\n" +"\r\n" +" ------------------------------------------------------------------------------\r\n" "\r\n" -" It contains the basic startup code for a JUCE application.\r\n" +" The Projucer is part of the JUCE library.\r\n" +" Copyright (c) 2020 - Raw Material Software Limited.\r\n" "\r\n" " ==============================================================================\r\n" "*/\r\n" "\r\n" -"%%app_headers%%\r\n" +"#pragma once\r\n" +"\r\n" +"//[Headers] -- You can add your own extra header files here --\r\n" +"%%include_juce%%\r\n" +"//[/Headers]\r\n" +"\r\n" +"%%include_files_h%%\r\n" "\r\n" "//==============================================================================\r\n" -"class %%app_class_name%% : public JUCEApplication\r\n" +"/**\r\n" +" //[Comments]\r\n" +" An auto-generated component, created by the Projucer.\r\n" +"\r\n" +" Describe your class and how it works here!\r\n" +" //[/Comments]\r\n" +"*/\r\n" +"%%class_declaration%%\r\n" "{\r\n" "public:\r\n" " //==============================================================================\r\n" -" %%app_class_name%%() {}\r\n" +" %%class_name%% (%%constructor_params%%);\r\n" +" ~%%class_name%%() override;\r\n" +"\r\n" +" //==============================================================================\r\n" +" //[UserMethods] -- You can add your own custom methods in this section.\r\n" +" //[/UserMethods]\r\n" +"\r\n" +" %%public_member_declarations%%\r\n" "\r\n" -" const String getApplicationName() override { return ProjectInfo::projectName; }\r\n" -" const String getApplicationVersion() override { return ProjectInfo::versionString; }\r\n" -" bool moreThanOneInstanceAllowed() override { return %%allow_more_than_one_instance%%; }\r\n" +"private:\r\n" +" //[UserVariables] -- You can add your own custom variables in this section.\r\n" +" //[/UserVariables]\r\n" "\r\n" " //==============================================================================\r\n" -" void initialise (const String& commandLine) override\r\n" -" {\r\n" -" // This method is where you should put your application's initialisation code..\r\n" +" %%private_member_declarations%%\r\n" "\r\n" -" mainWindow.reset (new MainWindow (getApplicationName()));\r\n" -" }\r\n" +" //==============================================================================\r\n" +" JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%class_name%%)\r\n" +"};\r\n" "\r\n" -" void shutdown() override\r\n" -" {\r\n" -" // Add your application's shutdown code here..\r\n" +"//[EndFile] You can add extra defines here...\r\n" +"//[/EndFile]\r\n"; + +const char* jucer_ComponentTemplate_h = (const char*) temp_binary_data_41; + +//================== jucer_ContentCompSimpleTemplate.h ================== +static const unsigned char temp_binary_data_42[] = +"#pragma once\r\n" "\r\n" -" mainWindow = nullptr; // (deletes our window)\r\n" -" }\r\n" +"%%include_juce%%\r\n" "\r\n" +"//==============================================================================\r\n" +"/*\r\n" +" This component lives inside our window, and this is where you should put all\r\n" +" your controls and content.\r\n" +"*/\r\n" +"class %%content_component_class%% : public juce::Component\r\n" +"{\r\n" +"public:\r\n" " //==============================================================================\r\n" -" void systemRequestedQuit() override\r\n" +" %%content_component_class%%()\r\n" " {\r\n" -" // This is called when the app is being asked to quit: you can ignore this\r\n" -" // request and let the app carry on running, or call quit() to allow the app to close.\r\n" -" quit();\r\n" +" setSize (600, 400);\r\n" " }\r\n" "\r\n" -" void anotherInstanceStarted (const String& commandLine) override\r\n" +" ~%%content_component_class%%() override\r\n" " {\r\n" -" // When another instance of the app is launched while this one is running,\r\n" -" // this method is invoked, and the commandLine parameter tells you what\r\n" -" // the other instance's command-line arguments were.\r\n" " }\r\n" "\r\n" " //==============================================================================\r\n" -" /*\r\n" -" This class implements the desktop window that contains an instance of\r\n" -" our %%content_component_class%% class.\r\n" -" */\r\n" -" class MainWindow : public DocumentWindow\r\n" +" void paint (juce::Graphics& g) override\r\n" " {\r\n" -" public:\r\n" -" MainWindow (String name) : DocumentWindow (name,\r\n" -" Desktop::getInstance().getDefaultLookAndFeel()\r\n" -" .findColour (ResizableWindow::backgroundColourId),\r\n" -" DocumentWindow::allButtons)\r\n" -" {\r\n" -" setUsingNativeTitleBar (true);\r\n" -" setContentOwned (new %%content_component_class%%(), true);\r\n" -"\r\n" -" #if JUCE_IOS || JUCE_ANDROID\r\n" -" setFullScreen (true);\r\n" -" #else\r\n" -" setResizable (true, true);\r\n" -" centreWithSize (getWidth(), getHeight());\r\n" -" #endif\r\n" -"\r\n" -" setVisible (true);\r\n" -" }\r\n" +" // (Our component is opaque, so we must completely fill the background with a solid colour)\r\n" +" g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId));\r\n" "\r\n" -" void closeButtonPressed() override\r\n" -" {\r\n" -" // This is called when the user tries to close this window. Here, we'll just\r\n" -" // ask the app to quit when this happens, but you can change this to do\r\n" -" // whatever you need.\r\n" -" JUCEApplication::getInstance()->systemRequestedQuit();\r\n" -" }\r\n" +" g.setFont (juce::Font (16.0f));\r\n" +" g.setColour (juce::Colours::white);\r\n" +" g.drawText (\"Hello World!\", getLocalBounds(), juce::Justification::centred, true);\r\n" +" }\r\n" "\r\n" -" /* Note: Be careful if you override any DocumentWindow methods - the base\r\n" -" class uses a lot of them, so by overriding you might break its functionality.\r\n" -" It's best to do all your work in your content component instead, but if\r\n" -" you really have to override any DocumentWindow methods, make sure your\r\n" -" subclass also calls the superclass's method.\r\n" -" */\r\n" +" void resized() override\r\n" +" {\r\n" +" // This is called when the %%content_component_class%% is resized.\r\n" +" // If you add any child components, this is where you should\r\n" +" // update their positions.\r\n" +" }\r\n" "\r\n" -" private:\r\n" -" JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainWindow)\r\n" -" };\r\n" "\r\n" "private:\r\n" -" std::unique_ptr<MainWindow> mainWindow;\r\n" -"};\r\n" +" //==============================================================================\r\n" +" // Your private member variables go here...\r\n" "\r\n" -"//==============================================================================\r\n" -"// This macro generates the main() routine that launches the app.\r\n" -"START_JUCE_APPLICATION (%%app_class_name%%)\r\n"; +"\r\n" +" JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%content_component_class%%)\r\n" +"};\r\n"; -const char* jucer_MainTemplate_Window_cpp = (const char*) temp_binary_data_43; +const char* jucer_ContentCompSimpleTemplate_h = (const char*) temp_binary_data_42; -//================== jucer_NewComponentTemplate.cpp ================== -static const unsigned char temp_binary_data_44[] = -"/*\r\n" -" ==============================================================================\r\n" -"\r\n" -" %%filename%%\r\n" -" Created: %%date%%\r\n" -" Author: %%author%%\r\n" -"\r\n" -" ==============================================================================\r\n" -"*/\r\n" -"\r\n" -"%%include_juce%%\r\n" +//================== jucer_ContentCompTemplate.cpp ================== +static const unsigned char temp_binary_data_43[] = "%%include_corresponding_header%%\r\n" "\r\n" "//==============================================================================\r\n" -"%%component_class%%::%%component_class%%()\r\n" +"%%content_component_class%%::%%content_component_class%%()\r\n" "{\r\n" -" // In your constructor, you should add any child components, and\r\n" -" // initialise any special settings that your component needs.\r\n" -"\r\n" +" setSize (600, 400);\r\n" "}\r\n" "\r\n" -"%%component_class%%::~%%component_class%%()\r\n" +"%%content_component_class%%::~%%content_component_class%%()\r\n" "{\r\n" "}\r\n" "\r\n" -"void %%component_class%%::paint (Graphics& g)\r\n" +"//==============================================================================\r\n" +"void %%content_component_class%%::paint (juce::Graphics& g)\r\n" "{\r\n" -" /* This demo code just fills the component's background and\r\n" -" draws some placeholder text to get you started.\r\n" -"\r\n" -" You should replace everything in this method with your own\r\n" -" drawing code..\r\n" -" */\r\n" -"\r\n" -" g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId)); // clear the background\r\n" -"\r\n" -" g.setColour (Colours::grey);\r\n" -" g.drawRect (getLocalBounds(), 1); // draw an outline around the component\r\n" +" // (Our component is opaque, so we must completely fill the background with a solid colour)\r\n" +" g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId));\r\n" "\r\n" -" g.setColour (Colours::white);\r\n" -" g.setFont (14.0f);\r\n" -" g.drawText (\"%%component_class%%\", getLocalBounds(),\r\n" -" Justification::centred, true); // draw some placeholder text\r\n" +" g.setFont (juce::Font (16.0f));\r\n" +" g.setColour (juce::Colours::white);\r\n" +" g.drawText (\"Hello World!\", getLocalBounds(), juce::Justification::centred, true);\r\n" "}\r\n" "\r\n" -"void %%component_class%%::resized()\r\n" +"void %%content_component_class%%::resized()\r\n" "{\r\n" -" // This method is where you should set the bounds of any child\r\n" -" // components that your component contains..\r\n" -"\r\n" +" // This is called when the %%content_component_class%% is resized.\r\n" +" // If you add any child components, this is where you should\r\n" +" // update their positions.\r\n" "}\r\n"; -const char* jucer_NewComponentTemplate_cpp = (const char*) temp_binary_data_44; +const char* jucer_ContentCompTemplate_cpp = (const char*) temp_binary_data_43; -//================== jucer_NewComponentTemplate.h ================== -static const unsigned char temp_binary_data_45[] = -"/*\r\n" -" ==============================================================================\r\n" -"\r\n" -" %%filename%%\r\n" -" Created: %%date%%\r\n" -" Author: %%author%%\r\n" -"\r\n" -" ==============================================================================\r\n" -"*/\r\n" -"\r\n" +//================== jucer_ContentCompTemplate.h ================== +static const unsigned char temp_binary_data_44[] = "#pragma once\r\n" "\r\n" "%%include_juce%%\r\n" "\r\n" "//==============================================================================\r\n" "/*\r\n" +" This component lives inside our window, and this is where you should put all\r\n" +" your controls and content.\r\n" "*/\r\n" -"class %%component_class%% : public Component\r\n" +"class %%content_component_class%% : public juce::Component\r\n" "{\r\n" "public:\r\n" -" %%component_class%%();\r\n" -" ~%%component_class%%();\r\n" +" //==============================================================================\r\n" +" %%content_component_class%%();\r\n" +" ~%%content_component_class%%() override;\r\n" "\r\n" -" void paint (Graphics&) override;\r\n" +" //==============================================================================\r\n" +" void paint (juce::Graphics&) override;\r\n" " void resized() override;\r\n" "\r\n" "private:\r\n" -" JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%component_class%%)\r\n" -"};\r\n"; - -const char* jucer_NewComponentTemplate_h = (const char*) temp_binary_data_45; - -//================== jucer_NewCppFileTemplate.cpp ================== -static const unsigned char temp_binary_data_46[] = -"/*\r\n" -" ==============================================================================\r\n" -"\r\n" -" %%filename%%\r\n" -" Created: %%date%%\r\n" -" Author: %%author%%\r\n" -"\r\n" -" ==============================================================================\r\n" -"*/\r\n" -"\r\n" -"%%include_corresponding_header%%\r\n"; - -const char* jucer_NewCppFileTemplate_cpp = (const char*) temp_binary_data_46; - -//================== jucer_NewCppFileTemplate.h ================== -static const unsigned char temp_binary_data_47[] = -"/*\r\n" -" ==============================================================================\r\n" -"\r\n" -" %%filename%%\r\n" -" Created: %%date%%\r\n" -" Author: %%author%%\r\n" +" //==============================================================================\r\n" +" // Your private member variables go here...\r\n" "\r\n" -" ==============================================================================\r\n" -"*/\r\n" "\r\n" -"#pragma once\r\n"; +" JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%content_component_class%%)\r\n" +"};\r\n"; -const char* jucer_NewCppFileTemplate_h = (const char*) temp_binary_data_47; +const char* jucer_ContentCompTemplate_h = (const char*) temp_binary_data_44; -//================== jucer_NewInlineComponentTemplate.h ================== -static const unsigned char temp_binary_data_48[] = -"/*\r\n" -" ==============================================================================\r\n" -"\r\n" -" %%filename%%\r\n" -" Created: %%date%%\r\n" -" Author: %%author%%\r\n" -"\r\n" -" ==============================================================================\r\n" -"*/\r\n" -"\r\n" -"#pragma once\r\n" -"\r\n" -"%%include_juce%%\r\n" -"\r\n" +//================== jucer_InlineComponentTemplate.h ================== +static const unsigned char temp_binary_data_45[] = "//==============================================================================\r\n" -"/*\r\n" -"*/\r\n" -"class %%component_class%% : public Component\r\n" +"class %%component_class%% : public juce::Component\r\n" "{\r\n" "public:\r\n" " %%component_class%%()\r\n" @@ -6859,28 +6720,23 @@ static const unsigned char temp_binary_data_48[] = "\r\n" " }\r\n" "\r\n" -" ~%%component_class%%()\r\n" +" ~%%component_class%%() override\r\n" " {\r\n" " }\r\n" "\r\n" -" void paint (Graphics& g) override\r\n" +" void paint (juce::Graphics& g) override\r\n" " {\r\n" -" /* This demo code just fills the component's background and\r\n" -" draws some placeholder text to get you started.\r\n" -"\r\n" -" You should replace everything in this method with your own\r\n" -" drawing code..\r\n" -" */\r\n" +" // You should replace everything in this method with your own drawing code..\r\n" "\r\n" -" g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId)); // clear the background\r\n" +" g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId)); // clear the background\r\n" "\r\n" -" g.setColour (Colours::grey);\r\n" +" g.setColour (juce::Colours::grey);\r\n" " g.drawRect (getLocalBounds(), 1); // draw an outline around the component\r\n" "\r\n" -" g.setColour (Colours::white);\r\n" +" g.setColour (juce::Colours::white);\r\n" " g.setFont (14.0f);\r\n" " g.drawText (\"%%component_class%%\", getLocalBounds(),\r\n" -" Justification::centred, true); // draw some placeholder text\r\n" +" juce::Justification::centred, true); // draw some placeholder text\r\n" " }\r\n" "\r\n" " void resized() override\r\n" @@ -6894,155 +6750,261 @@ static const unsigned char temp_binary_data_48[] = " JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%component_class%%)\r\n" "};\r\n"; -const char* jucer_NewInlineComponentTemplate_h = (const char*) temp_binary_data_48; +const char* jucer_InlineComponentTemplate_h = (const char*) temp_binary_data_45; -//================== jucer_OpenGLComponentSimpleTemplate.h ================== -static const unsigned char temp_binary_data_49[] = +//================== jucer_MainConsoleAppTemplate.cpp ================== +static const unsigned char temp_binary_data_46[] = "/*\r\n" " ==============================================================================\r\n" "\r\n" -" This file was auto-generated!\r\n" +" This file contains the basic startup code for a JUCE application.\r\n" "\r\n" " ==============================================================================\r\n" "*/\r\n" "\r\n" -"#pragma once\r\n" -"\r\n" -"%%include_juce%%\r\n" +"%%app_headers%%\r\n" "\r\n" "//==============================================================================\r\n" +"int main (int argc, char* argv[])\r\n" +"{\r\n" +"\r\n" +" // ..your code goes here!\r\n" +"\r\n" +"\r\n" +" return 0;\r\n" +"}\r\n"; + +const char* jucer_MainConsoleAppTemplate_cpp = (const char*) temp_binary_data_46; + +//================== jucer_MainTemplate_NoWindow.cpp ================== +static const unsigned char temp_binary_data_47[] = "/*\r\n" -" This component lives inside our window, and this is where you should put all\r\n" -" your controls and content.\r\n" +" ==============================================================================\r\n" +"\r\n" +" This file contains the basic startup code for a JUCE application.\r\n" +"\r\n" +" ==============================================================================\r\n" "*/\r\n" -"class %%content_component_class%% : public OpenGLAppComponent\r\n" +"\r\n" +"%%app_headers%%\r\n" +"\r\n" +"//==============================================================================\r\n" +"class %%app_class_name%% : public juce::JUCEApplication\r\n" "{\r\n" "public:\r\n" " //==============================================================================\r\n" -" %%content_component_class%%()\r\n" +" %%app_class_name%%() {}\r\n" +"\r\n" +" const juce::String getApplicationName() override { return ProjectInfo::projectName; }\r\n" +" const juce::String getApplicationVersion() override { return ProjectInfo::versionString; }\r\n" +" bool moreThanOneInstanceAllowed() override { return true; }\r\n" +"\r\n" +" //==============================================================================\r\n" +" void initialise (const juce::String& commandLine) override\r\n" " {\r\n" -" // Make sure you set the size of the component after\r\n" -" // you add any child components.\r\n" -" setSize (800, 600);\r\n" +" // Add your application's initialisation code here..\r\n" " }\r\n" "\r\n" -" ~%%content_component_class%%()\r\n" +" void shutdown() override\r\n" " {\r\n" -" // This shuts down the GL system and stops the rendering calls.\r\n" -" shutdownOpenGL();\r\n" +" // Add your application's shutdown code here..\r\n" " }\r\n" "\r\n" " //==============================================================================\r\n" -" void initialise() override\r\n" +" void systemRequestedQuit() override\r\n" " {\r\n" -" // Initialise GL objects for rendering here.\r\n" +" // This is called when the app is being asked to quit: you can ignore this\r\n" +" // request and let the app carry on running, or call quit() to allow the app to close.\r\n" +" quit();\r\n" " }\r\n" "\r\n" -" void shutdown() override\r\n" +" void anotherInstanceStarted (const juce::String& commandLine) override\r\n" " {\r\n" -" // Free any GL objects created for rendering here.\r\n" +" // When another instance of the app is launched while this one is running,\r\n" +" // this method is invoked, and the commandLine parameter tells you what\r\n" +" // the other instance's command-line arguments were.\r\n" " }\r\n" +"};\r\n" "\r\n" -" void render() override\r\n" +"//==============================================================================\r\n" +"// This macro generates the main() routine that launches the app.\r\n" +"START_JUCE_APPLICATION (%%app_class_name%%)\r\n"; + +const char* jucer_MainTemplate_NoWindow_cpp = (const char*) temp_binary_data_47; + +//================== jucer_MainTemplate_Window.cpp ================== +static const unsigned char temp_binary_data_48[] = +"/*\r\n" +" ==============================================================================\r\n" +"\r\n" +" This file contains the basic startup code for a JUCE application.\r\n" +"\r\n" +" ==============================================================================\r\n" +"*/\r\n" +"\r\n" +"%%app_headers%%\r\n" +"\r\n" +"//==============================================================================\r\n" +"class %%app_class_name%% : public juce::JUCEApplication\r\n" +"{\r\n" +"public:\r\n" +" //==============================================================================\r\n" +" %%app_class_name%%() {}\r\n" +"\r\n" +" const juce::String getApplicationName() override { return ProjectInfo::projectName; }\r\n" +" const juce::String getApplicationVersion() override { return ProjectInfo::versionString; }\r\n" +" bool moreThanOneInstanceAllowed() override { return true; }\r\n" +"\r\n" +" //==============================================================================\r\n" +" void initialise (const juce::String& commandLine) override\r\n" " {\r\n" -" // This clears the context with a black background.\r\n" -" OpenGLHelpers::clear (Colours::black);\r\n" +" // This method is where you should put your application's initialisation code..\r\n" "\r\n" -" // Add your rendering code here...\r\n" +" mainWindow.reset (new MainWindow (getApplicationName()));\r\n" " }\r\n" "\r\n" -" //==============================================================================\r\n" -" void paint (Graphics& g) override\r\n" +" void shutdown() override\r\n" " {\r\n" -" // You can add your component specific drawing code here!\r\n" -" // This will draw over the top of the openGL background.\r\n" +" // Add your application's shutdown code here..\r\n" +"\r\n" +" mainWindow = nullptr; // (deletes our window)\r\n" " }\r\n" "\r\n" -" void resized() override\r\n" +" //==============================================================================\r\n" +" void systemRequestedQuit() override\r\n" " {\r\n" -" // This is called when the MainContentComponent is resized.\r\n" -" // If you add any child components, this is where you should\r\n" -" // update their positions.\r\n" +" // This is called when the app is being asked to quit: you can ignore this\r\n" +" // request and let the app carry on running, or call quit() to allow the app to close.\r\n" +" quit();\r\n" " }\r\n" "\r\n" +" void anotherInstanceStarted (const juce::String& commandLine) override\r\n" +" {\r\n" +" // When another instance of the app is launched while this one is running,\r\n" +" // this method is invoked, and the commandLine parameter tells you what\r\n" +" // the other instance's command-line arguments were.\r\n" +" }\r\n" "\r\n" -"private:\r\n" " //==============================================================================\r\n" -" // Your private member variables go here...\r\n" +" /*\r\n" +" This class implements the desktop window that contains an instance of\r\n" +" our %%content_component_class%% class.\r\n" +" */\r\n" +" class MainWindow : public juce::DocumentWindow\r\n" +" {\r\n" +" public:\r\n" +" MainWindow (juce::String name)\r\n" +" : DocumentWindow (name,\r\n" +" juce::Desktop::getInstance().getDefaultLookAndFeel()\r\n" +" .findColour (juce::ResizableWindow::backgroundColourId),\r\n" +" DocumentWindow::allButtons)\r\n" +" {\r\n" +" setUsingNativeTitleBar (true);\r\n" +" setContentOwned (new %%content_component_class%%(), true);\r\n" +"\r\n" +" #if JUCE_IOS || JUCE_ANDROID\r\n" +" setFullScreen (true);\r\n" +" #else\r\n" +" setResizable (true, true);\r\n" +" centreWithSize (getWidth(), getHeight());\r\n" +" #endif\r\n" +"\r\n" +" setVisible (true);\r\n" +" }\r\n" +"\r\n" +" void closeButtonPressed() override\r\n" +" {\r\n" +" // This is called when the user tries to close this window. Here, we'll just\r\n" +" // ask the app to quit when this happens, but you can change this to do\r\n" +" // whatever you need.\r\n" +" JUCEApplication::getInstance()->systemRequestedQuit();\r\n" +" }\r\n" +"\r\n" +" /* Note: Be careful if you override any DocumentWindow methods - the base\r\n" +" class uses a lot of them, so by overriding you might break its functionality.\r\n" +" It's best to do all your work in your content component instead, but if\r\n" +" you really have to override any DocumentWindow methods, make sure your\r\n" +" subclass also calls the superclass's method.\r\n" +" */\r\n" +"\r\n" +" private:\r\n" +" JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainWindow)\r\n" +" };\r\n" "\r\n" +"private:\r\n" +" std::unique_ptr<MainWindow> mainWindow;\r\n" +"};\r\n" "\r\n" -" JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%content_component_class%%)\r\n" -"};\r\n"; +"//==============================================================================\r\n" +"// This macro generates the main() routine that launches the app.\r\n" +"START_JUCE_APPLICATION (%%app_class_name%%)\r\n"; -const char* jucer_OpenGLComponentSimpleTemplate_h = (const char*) temp_binary_data_49; +const char* jucer_MainTemplate_Window_cpp = (const char*) temp_binary_data_48; -//================== jucer_OpenGLComponentTemplate.cpp ================== -static const unsigned char temp_binary_data_50[] = +//================== jucer_NewComponentTemplate.cpp ================== +static const unsigned char temp_binary_data_49[] = "/*\r\n" " ==============================================================================\r\n" "\r\n" -" This file was auto-generated!\r\n" +" %%filename%%\r\n" +" Created: %%date%%\r\n" +" Author: %%author%%\r\n" "\r\n" " ==============================================================================\r\n" "*/\r\n" "\r\n" +"%%include_juce%%\r\n" "%%include_corresponding_header%%\r\n" "\r\n" "//==============================================================================\r\n" -"%%content_component_class%%::%%content_component_class%%()\r\n" +"%%component_class%%::%%component_class%%()\r\n" "{\r\n" -" // Make sure you set the size of the component after\r\n" -" // you add any child components.\r\n" -" setSize (800, 600);\r\n" -"}\r\n" +" // In your constructor, you should add any child components, and\r\n" +" // initialise any special settings that your component needs.\r\n" "\r\n" -"%%content_component_class%%::~%%content_component_class%%()\r\n" -"{\r\n" -" // This shuts down the GL system and stops the rendering calls.\r\n" -" shutdownOpenGL();\r\n" "}\r\n" "\r\n" -"//==============================================================================\r\n" -"void %%content_component_class%%::initialise()\r\n" +"%%component_class%%::~%%component_class%%()\r\n" "{\r\n" -" // Initialise GL objects for rendering here.\r\n" "}\r\n" "\r\n" -"void %%content_component_class%%::shutdown()\r\n" +"void %%component_class%%::paint (juce::Graphics& g)\r\n" "{\r\n" -" // Free any GL objects created for rendering here.\r\n" -"}\r\n" +" /* This demo code just fills the component's background and\r\n" +" draws some placeholder text to get you started.\r\n" "\r\n" -"void %%content_component_class%%::render()\r\n" -"{\r\n" -" // This clears the context with a black background.\r\n" -" OpenGLHelpers::clear (Colours::black);\r\n" +" You should replace everything in this method with your own\r\n" +" drawing code..\r\n" +" */\r\n" "\r\n" -" // Add your rendering code here...\r\n" -"}\r\n" +" g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId)); // clear the background\r\n" "\r\n" -"//==============================================================================\r\n" -"void %%content_component_class%%::paint (Graphics& g)\r\n" -"{\r\n" -" // You can add your component specific drawing code here!\r\n" -" // This will draw over the top of the openGL background.\r\n" +" g.setColour (juce::Colours::grey);\r\n" +" g.drawRect (getLocalBounds(), 1); // draw an outline around the component\r\n" +"\r\n" +" g.setColour (juce::Colours::white);\r\n" +" g.setFont (14.0f);\r\n" +" g.drawText (\"%%component_class%%\", getLocalBounds(),\r\n" +" juce::Justification::centred, true); // draw some placeholder text\r\n" "}\r\n" "\r\n" -"void %%content_component_class%%::resized()\r\n" +"void %%component_class%%::resized()\r\n" "{\r\n" -" // This is called when the %%content_component_class%% is resized.\r\n" -" // If you add any child components, this is where you should\r\n" -" // update their positions.\r\n" +" // This method is where you should set the bounds of any child\r\n" +" // components that your component contains..\r\n" +"\r\n" "}\r\n"; -const char* jucer_OpenGLComponentTemplate_cpp = (const char*) temp_binary_data_50; +const char* jucer_NewComponentTemplate_cpp = (const char*) temp_binary_data_49; -//================== jucer_OpenGLComponentTemplate.h ================== -static const unsigned char temp_binary_data_51[] = +//================== jucer_NewComponentTemplate.h ================== +static const unsigned char temp_binary_data_50[] = "/*\r\n" " ==============================================================================\r\n" "\r\n" -" This file was auto-generated!\r\n" +" %%filename%%\r\n" +" Created: %%date%%\r\n" +" Author: %%author%%\r\n" "\r\n" " ==============================================================================\r\n" "*/\r\n" @@ -7053,439 +7015,418 @@ static const unsigned char temp_binary_data_51[] = "\r\n" "//==============================================================================\r\n" "/*\r\n" -" This component lives inside our window, and this is where you should put all\r\n" -" your controls and content.\r\n" "*/\r\n" -"class %%content_component_class%% : public OpenGLAppComponent\r\n" +"class %%component_class%% : public juce::Component\r\n" "{\r\n" "public:\r\n" -" //==============================================================================\r\n" -" %%content_component_class%%();\r\n" -" ~%%content_component_class%%();\r\n" -"\r\n" -" //==============================================================================\r\n" -" void initialise() override;\r\n" -" void shutdown() override;\r\n" -" void render() override;\r\n" +" %%component_class%%();\r\n" +" ~%%component_class%%() override;\r\n" "\r\n" -" //==============================================================================\r\n" -" void paint (Graphics& g) override;\r\n" +" void paint (juce::Graphics&) override;\r\n" " void resized() override;\r\n" "\r\n" "private:\r\n" -" //==============================================================================\r\n" -" // Your private member variables go here...\r\n" -"\r\n" -"\r\n" -" JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%content_component_class%%)\r\n" +" JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%component_class%%)\r\n" "};\r\n"; -const char* jucer_OpenGLComponentTemplate_h = (const char*) temp_binary_data_51; +const char* jucer_NewComponentTemplate_h = (const char*) temp_binary_data_50; -//================== jucer_PIPAudioProcessorTemplate.h ================== -static const unsigned char temp_binary_data_52[] = -"class %%class_name%% : public AudioProcessor\r\n" -"{\r\n" -"public:\r\n" -" //==============================================================================\r\n" -" %%class_name%%()\r\n" -" : AudioProcessor (BusesProperties().withInput (\"Input\", AudioChannelSet::stereo())\r\n" -" .withOutput (\"Output\", AudioChannelSet::stereo()))\r\n" -" {\r\n" -" }\r\n" +//================== jucer_NewCppFileTemplate.cpp ================== +static const unsigned char temp_binary_data_51[] = +"/*\r\n" +" ==============================================================================\r\n" "\r\n" -" ~%%class_name%%()\r\n" -" {\r\n" -" }\r\n" +" %%filename%%\r\n" +" Created: %%date%%\r\n" +" Author: %%author%%\r\n" "\r\n" -" //==============================================================================\r\n" -" void prepareToPlay (double, int) override\r\n" -" {\r\n" -" // Use this method as the place to do any pre-playback\r\n" -" // initialisation that you need..\r\n" -" }\r\n" +" ==============================================================================\r\n" +"*/\r\n" "\r\n" -" void releaseResources() override\r\n" -" {\r\n" -" // When playback stops, you can use this as an opportunity to free up any\r\n" -" // spare memory, etc.\r\n" -" }\r\n" +"%%include_corresponding_header%%\r\n"; + +const char* jucer_NewCppFileTemplate_cpp = (const char*) temp_binary_data_51; + +//================== jucer_NewCppFileTemplate.h ================== +static const unsigned char temp_binary_data_52[] = +"/*\r\n" +" ==============================================================================\r\n" "\r\n" -" void processBlock (AudioBuffer<float>& buffer, MidiBuffer&) override\r\n" -" {\r\n" -" ScopedNoDenormals noDenormals;\r\n" -" auto totalNumInputChannels = getTotalNumInputChannels();\r\n" -" auto totalNumOutputChannels = getTotalNumOutputChannels();\r\n" +" %%filename%%\r\n" +" Created: %%date%%\r\n" +" Author: %%author%%\r\n" "\r\n" -" // In case we have more outputs than inputs, this code clears any output\r\n" -" // channels that didn't contain input data, (because these aren't\r\n" -" // guaranteed to be empty - they may contain garbage).\r\n" -" // This is here to avoid people getting screaming feedback\r\n" -" // when they first compile a plugin, but obviously you don't need to keep\r\n" -" // this code if your algorithm always overwrites all the output channels.\r\n" -" for (auto i = totalNumInputChannels; i < totalNumOutputChannels; ++i)\r\n" -" buffer.clear (i, 0, buffer.getNumSamples());\r\n" +" ==============================================================================\r\n" +"*/\r\n" "\r\n" -" // This is the place where you'd normally do the guts of your plugin's\r\n" -" // audio processing...\r\n" -" // Make sure to reset the state if your inner loop is processing\r\n" -" // the samples and the outer loop is handling the channels.\r\n" -" // Alternatively, you can process the samples with the channels\r\n" -" // interleaved by keeping the same state.\r\n" -" for (int channel = 0; channel < totalNumInputChannels; ++channel)\r\n" -" {\r\n" -" auto* channelData = buffer.getWritePointer (channel);\r\n" +"#pragma once\r\n"; + +const char* jucer_NewCppFileTemplate_h = (const char*) temp_binary_data_52; + +//================== jucer_NewInlineComponentTemplate.h ================== +static const unsigned char temp_binary_data_53[] = +"/*\r\n" +" ==============================================================================\r\n" "\r\n" -" // ..do something to the data...\r\n" -" }\r\n" -" }\r\n" +" %%filename%%\r\n" +" Created: %%date%%\r\n" +" Author: %%author%%\r\n" "\r\n" -" //==============================================================================\r\n" -" AudioProcessorEditor* createEditor() override { return nullptr; }\r\n" -" bool hasEditor() const override { return false; }\r\n" +" ==============================================================================\r\n" +"*/\r\n" "\r\n" -" //==============================================================================\r\n" -" const String getName() const override { return \"%%name%%\"; }\r\n" -" bool acceptsMidi() const override { return false; }\r\n" -" bool producesMidi() const override { return false; }\r\n" -" double getTailLengthSeconds() const override { return 0; }\r\n" +"#pragma once\r\n" "\r\n" -" //==============================================================================\r\n" -" int getNumPrograms() override { return 1; }\r\n" -" int getCurrentProgram() override { return 0; }\r\n" -" void setCurrentProgram (int) override {}\r\n" -" const String getProgramName (int) override { return {}; }\r\n" -" void changeProgramName (int, const String&) override {}\r\n" +"%%include_juce%%\r\n" "\r\n" -" //==============================================================================\r\n" -" void getStateInformation (MemoryBlock& destData) override\r\n" +"//==============================================================================\r\n" +"/*\r\n" +"*/\r\n" +"class %%component_class%% : public juce::Component\r\n" +"{\r\n" +"public:\r\n" +" %%component_class%%()\r\n" " {\r\n" -" // You should use this method to store your parameters in the memory block.\r\n" -" // You could do that either as raw data, or use the XML or ValueTree classes\r\n" -" // as intermediaries to make it easy to save and load complex data.\r\n" +" // In your constructor, you should add any child components, and\r\n" +" // initialise any special settings that your component needs.\r\n" +"\r\n" " }\r\n" "\r\n" -" void setStateInformation (const void* data, int sizeInBytes) override\r\n" +" ~%%component_class%%() override\r\n" " {\r\n" -" // You should use this method to restore your parameters from this memory block,\r\n" -" // whose contents will have been created by the getStateInformation() call.\r\n" " }\r\n" "\r\n" -" //==============================================================================\r\n" -" bool isBusesLayoutSupported (const BusesLayout& layouts) const override\r\n" +" void paint (juce::Graphics& g) override\r\n" " {\r\n" -" // This is the place where you check if the layout is supported.\r\n" -" // In this template code we only support mono or stereo.\r\n" -" if (layouts.getMainOutputChannelSet() != AudioChannelSet::mono()\r\n" -" && layouts.getMainOutputChannelSet() != AudioChannelSet::stereo())\r\n" -" return false;\r\n" +" /* This demo code just fills the component's background and\r\n" +" draws some placeholder text to get you started.\r\n" "\r\n" -" // This checks if the input layout matches the output layout\r\n" -" if (layouts.getMainOutputChannelSet() != layouts.getMainInputChannelSet())\r\n" -" return false;\r\n" +" You should replace everything in this method with your own\r\n" +" drawing code..\r\n" +" */\r\n" +"\r\n" +" g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId)); // clear the background\r\n" +"\r\n" +" g.setColour (juce::Colours::grey);\r\n" +" g.drawRect (getLocalBounds(), 1); // draw an outline around the component\r\n" +"\r\n" +" g.setColour (juce::Colours::white);\r\n" +" g.setFont (14.0f);\r\n" +" g.drawText (\"%%component_class%%\", getLocalBounds(),\r\n" +" juce::Justification::centred, true); // draw some placeholder text\r\n" +" }\r\n" +"\r\n" +" void resized() override\r\n" +" {\r\n" +" // This method is where you should set the bounds of any child\r\n" +" // components that your component contains..\r\n" "\r\n" -" return true;\r\n" " }\r\n" "\r\n" "private:\r\n" -" //==============================================================================\r\n" -" JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%class_name%%)\r\n" +" JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%component_class%%)\r\n" "};\r\n"; -const char* jucer_PIPAudioProcessorTemplate_h = (const char*) temp_binary_data_52; +const char* jucer_NewInlineComponentTemplate_h = (const char*) temp_binary_data_53; -//================== jucer_PIPMain.cpp ================== -static const unsigned char temp_binary_data_53[] = -"/*\r\n" -" ==============================================================================\r\n" -"\r\n" -" This file was auto-generated and contains the startup code for a PIP.\r\n" -"\r\n" -" ==============================================================================\r\n" -"*/\r\n" +//================== jucer_OpenGLComponentSimpleTemplate.h ================== +static const unsigned char temp_binary_data_54[] = +"#pragma once\r\n" "\r\n" "%%include_juce%%\r\n" -"#include \"%%filename%%\"\r\n" "\r\n" -"%%component_begin%%\r\n" -"class Application : public JUCEApplication\r\n" +"//==============================================================================\r\n" +"/*\r\n" +" This component lives inside our window, and this is where you should put all\r\n" +" your controls and content.\r\n" +"*/\r\n" +"class %%content_component_class%% : public juce::OpenGLAppComponent\r\n" "{\r\n" "public:\r\n" " //==============================================================================\r\n" -" Application() {}\r\n" -"\r\n" -" const String getApplicationName() override { return \"%%project_name%%\"; }\r\n" -" const String getApplicationVersion() override { return \"%%project_version%%\"; }\r\n" -"\r\n" -" void initialise (const String&) override { %%startup%% }\r\n" -" void shutdown() override { %%shutdown%% }\r\n" +" %%content_component_class%%()\r\n" +" {\r\n" +" // Make sure you set the size of the component after\r\n" +" // you add any child components.\r\n" +" setSize (800, 600);\r\n" +" }\r\n" "\r\n" -"private:\r\n" -" class MainWindow : public DocumentWindow\r\n" +" ~%%content_component_class%%() override\r\n" " {\r\n" -" public:\r\n" -" MainWindow (const String& name, Component* c, JUCEApplication& a)\r\n" -" : DocumentWindow (name, Desktop::getInstance().getDefaultLookAndFeel()\r\n" -" .findColour (ResizableWindow::backgroundColourId),\r\n" -" DocumentWindow::allButtons),\r\n" -" app (a)\r\n" -" {\r\n" -" setUsingNativeTitleBar (true);\r\n" -" setContentOwned (c, true);\r\n" +" // This shuts down the GL system and stops the rendering calls.\r\n" +" shutdownOpenGL();\r\n" +" }\r\n" "\r\n" -" #if JUCE_ANDROID || JUCE_IOS\r\n" -" setFullScreen (true);\r\n" -" #else\r\n" -" setResizable (true, false);\r\n" -" setResizeLimits (300, 250, 10000, 10000);\r\n" -" centreWithSize (getWidth(), getHeight());\r\n" -" #endif\r\n" +" //==============================================================================\r\n" +" void initialise() override\r\n" +" {\r\n" +" // Initialise GL objects for rendering here.\r\n" +" }\r\n" "\r\n" -" setVisible (true);\r\n" -" }\r\n" +" void shutdown() override\r\n" +" {\r\n" +" // Free any GL objects created for rendering here.\r\n" +" }\r\n" "\r\n" -" void closeButtonPressed() override\r\n" -" {\r\n" -" app.systemRequestedQuit();\r\n" -" }\r\n" +" void render() override\r\n" +" {\r\n" +" // This clears the context with a black background.\r\n" +" juce::OpenGLHelpers::clear (Colours::black);\r\n" "\r\n" -" private:\r\n" -" JUCEApplication& app;\r\n" +" // Add your rendering code here...\r\n" +" }\r\n" "\r\n" -" //==============================================================================\r\n" -" JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainWindow)\r\n" -" };\r\n" +" //==============================================================================\r\n" +" void paint (juce::Graphics& g) override\r\n" +" {\r\n" +" // You can add your component specific drawing code here!\r\n" +" // This will draw over the top of the openGL background.\r\n" +" }\r\n" "\r\n" -" std::unique_ptr<MainWindow> mainWindow;\r\n" -"};\r\n" +" void resized() override\r\n" +" {\r\n" +" // This is called when the MainContentComponent is resized.\r\n" +" // If you add any child components, this is where you should\r\n" +" // update their positions.\r\n" +" }\r\n" "\r\n" -"//==============================================================================\r\n" -"START_JUCE_APPLICATION (Application)\r\n" -"%%component_end%%\r\n" "\r\n" -"%%audioprocessor_begin%%\r\n" -"//==============================================================================\r\n" -"AudioProcessor* JUCE_CALLTYPE createPluginFilter()\r\n" -"{\r\n" -" return new %%class_name%%();\r\n" -"}\r\n" -"%%audioprocessor_end%%\r\n" +"private:\r\n" +" //==============================================================================\r\n" +" // Your private member variables go here...\r\n" +"\r\n" "\r\n" -"%%console_begin%%\r\n" -"%%console_end%%\r\n"; +" JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%content_component_class%%)\r\n" +"};\r\n"; -const char* jucer_PIPMain_cpp = (const char*) temp_binary_data_53; +const char* jucer_OpenGLComponentSimpleTemplate_h = (const char*) temp_binary_data_54; -//================== jucer_PIPTemplate.h ================== -static const unsigned char temp_binary_data_54[] = -"/*******************************************************************************\r\n" -" The block below describes the properties of this PIP. A PIP is a short snippet\r\n" -" of code that can be read by the Projucer and used to generate a JUCE project.\r\n" +//================== jucer_OpenGLComponentTemplate.cpp ================== +static const unsigned char temp_binary_data_55[] = +"%%include_corresponding_header%%\r\n" "\r\n" -" BEGIN_JUCE_PIP_METADATA\r\n" +"//==============================================================================\r\n" +"%%content_component_class%%::%%content_component_class%%()\r\n" +"{\r\n" +" // Make sure you set the size of the component after\r\n" +" // you add any child components.\r\n" +" setSize (800, 600);\r\n" +"}\r\n" "\r\n" -"%%pip_metadata%%\r\n" +"%%content_component_class%%::~%%content_component_class%%()\r\n" +"{\r\n" +" // This shuts down the GL system and stops the rendering calls.\r\n" +" shutdownOpenGL();\r\n" +"}\r\n" "\r\n" -" END_JUCE_PIP_METADATA\r\n" +"//==============================================================================\r\n" +"void %%content_component_class%%::initialise()\r\n" +"{\r\n" +" // Initialise GL objects for rendering here.\r\n" +"}\r\n" "\r\n" -"*******************************************************************************/\r\n" +"void %%content_component_class%%::shutdown()\r\n" +"{\r\n" +" // Free any GL objects created for rendering here.\r\n" +"}\r\n" "\r\n" -"#pragma once\r\n" +"void %%content_component_class%%::render()\r\n" +"{\r\n" +" // This clears the context with a black background.\r\n" +" juce::OpenGLHelpers::clear (juce::Colours::black);\r\n" "\r\n" +" // Add your rendering code here...\r\n" +"}\r\n" "\r\n" "//==============================================================================\r\n" -"%%pip_code%%\r\n"; - -const char* jucer_PIPTemplate_h = (const char*) temp_binary_data_54; - -//================== jucer_UnityPluginGUIScript.cs ================== -static const unsigned char temp_binary_data_55[] = -"#if UNITY_EDITOR\n" -"\n" -"using UnityEditor;\n" -"using UnityEngine;\n" -"\n" -"using System.Collections.Generic;\n" -"using System.Runtime.InteropServices;\n" -"\n" -"public class %%plugin_class_name%%GUI : IAudioEffectPluginGUI\n" -"{\n" -" public override string Name { get { return \"%%plugin_name%%\"; } }\n" -" public override string Description { get { return \"%%plugin_description%%\"; } }\n" -" public override string Vendor { get { return \"%%plugin_vendor%%\"; } }\n" -"\n" -" //==============================================================================\n" -"\t[DllImport(\"%%plugin_name%%\")] static extern System.IntPtr getRenderCallback();\n" -"\n" -" [DllImport(\"%%plugin_name%%\")] static extern void unityInitialiseTexture (int id, System.IntPtr texture, int width, int height);\n" -"\n" -" [DllImport(\"%%plugin_name%%\")] static extern void unityMouseDown (int id, float x, float y, EventModifiers mods, int button);\n" -" [DllImport(\"%%plugin_name%%\")] static extern void unityMouseDrag (int id, float x, float y, EventModifiers mods, int button);\n" -" [DllImport(\"%%plugin_name%%\")] static extern void unityMouseUp (int id, float x, float y, EventModifiers mods);\n" -"\n" -" [DllImport(\"%%plugin_name%%\")] static extern void unityKeyEvent (int id, KeyCode code, EventModifiers mods, string name);\n" -"\n" -" [DllImport(\"%%plugin_name%%\")] static extern void unitySetScreenBounds (int id, float x, float y, float w, float h);\n" -"\n" -" //==============================================================================\n" -" private class PluginGUIInstance\n" -" {\n" -" public PluginGUIInstance (ref IAudioEffectPlugin plugin, int id)\n" -" {\n" -" instanceID = id;\n" -"\n" -" float[] arr;\n" -" plugin.GetFloatBuffer (\"Editor\", out arr, 1);\n" -" hasEditor = (arr[0] > 0.0f);\n" -" }\n" -"\n" -" public void repaint (Rect r)\n" -" { \n" -" Vector2 newScreenPosition = GUIUtility.GUIToScreenPoint (r.position);\n" -"\n" -" if (bounds != r \n" -" || screenPosition != newScreenPosition)\n" -" {\n" -" screenPosition = newScreenPosition;\n" -" bounds = r;\n" -"\n" -" unitySetScreenBounds (instanceID, screenPosition.x, screenPosition.y, bounds.width, bounds.height);\n" -" setupTexture();\n" -" }\n" -"\n" -"\t\t\tGL.IssuePluginEvent (getRenderCallback(), instanceID);\n" -"\n" -" texture.SetPixels32 (pixels);\n" -" texture.Apply();\n" -"\n" -" EditorGUI.DrawPreviewTexture (bounds, texture);\n" -" }\n" -"\n" -" public bool handleMouseEvent (EventType eventType)\n" -" {\n" -" Vector2 mousePos = Event.current.mousePosition;\n" -" EventModifiers mods = Event.current.modifiers;\n" -"\n" -" if (! bounds.Contains (mousePos))\n" -" return false;\n" -"\n" -" Vector2 relativePos = new Vector2 (mousePos.x - bounds.x, mousePos.y - bounds.y);\n" -"\n" -" if (eventType == EventType.MouseDown) \n" -" {\n" -" unityMouseDown (instanceID, relativePos.x, relativePos.y, mods, Event.current.button);\n" -" GUIUtility.hotControl = GUIUtility.GetControlID (FocusType.Passive);\n" -" }\n" -" else if (eventType == EventType.MouseUp)\n" -" {\n" -" unityMouseUp (instanceID, relativePos.x, relativePos.y, mods);\n" -" GUIUtility.hotControl = 0;\n" -" }\n" -" else if (eventType == EventType.MouseDrag) \n" -" {\n" -" unityMouseDrag (instanceID, relativePos.x, relativePos.y, mods, Event.current.button);\n" -" }\n" -"\n" -" Event.current.Use();\n" -"\n" -" return true;\n" -" }\n" -"\n" -" public void handleKeyEvent (EventType eventType)\n" -" {\n" -" if (eventType == EventType.KeyDown)\n" -" {\n" -" KeyCode code = Event.current.keyCode;\n" -"\n" -" if (code == KeyCode.None)\n" -" return;\n" -"\n" -" EventModifiers mods = Event.current.modifiers;\n" -"\n" -" unityKeyEvent (instanceID, code, mods, code.ToString());\n" -" }\n" -" }\n" -"\n" -" private void setupTexture()\n" -" {\n" -" if (pixelHandle.IsAllocated)\n" -" pixelHandle.Free();\n" -"\n" -" texture = new Texture2D ((int) bounds.width, (int) bounds.height, TextureFormat.ARGB32, false);\n" -"\n" -" pixels = texture.GetPixels32();\n" -" pixelHandle = GCHandle.Alloc (pixels, GCHandleType.Pinned);\n" -"\n" -" unityInitialiseTexture (instanceID, pixelHandle.AddrOfPinnedObject(), texture.width, texture.height);\n" -" }\n" -"\n" -" public int instanceID = -1;\n" -" public bool hasEditor;\n" -"\n" -" private Vector2 screenPosition;\n" -" private Rect bounds;\n" -"\n" -" private Texture2D texture;\n" -" private Color32[] pixels;\n" -" private GCHandle pixelHandle;\n" -" }\n" -" List<PluginGUIInstance> guis = new List<PluginGUIInstance>();\n" -"\n" -" private PluginGUIInstance getGUIInstanceForPlugin (ref IAudioEffectPlugin plugin)\n" -" {\n" -" float[] idArray;\n" -" plugin.GetFloatBuffer (\"ID\", out idArray, 1);\n" -"\n" -" int id = (int) idArray[0];\n" -"\n" -" for (int i = 0; i < guis.Count; ++i)\n" -" {\n" -" if (guis[i].instanceID == id)\n" -" return guis[i];\n" -" }\n" -"\n" -" PluginGUIInstance newInstance = new PluginGUIInstance (ref plugin, id);\n" -" guis.Add (newInstance);\n" -"\n" -" return guis[guis.Count - 1];\n" -" }\n" -"\n" -" //==============================================================================\n" -" public override bool OnGUI (IAudioEffectPlugin plugin)\n" -" {\n" -" PluginGUIInstance guiInstance = getGUIInstanceForPlugin (ref plugin);\n" -"\n" -" if (! guiInstance.hasEditor)\n" -" return true;\n" -"\n" -" float[] arr;\n" -" plugin.GetFloatBuffer (\"Size\", out arr, 6);\n" -"\n" -" Rect r = GUILayoutUtility.GetRect (arr[0], arr[1],\n" -" new GUILayoutOption[] { GUILayout.MinWidth (arr[2]), GUILayout.MinHeight (arr[3]),\n" -" GUILayout.MaxWidth (arr[4]), GUILayout.MaxHeight (arr[5]) });\n" -"\n" -" int controlID = GUIUtility.GetControlID (FocusType.Passive);\n" -" Event currentEvent = Event.current;\n" -" EventType currentEventType = currentEvent.GetTypeForControl (controlID);\n" -"\n" -" if (currentEventType == EventType.Repaint)\n" -" guiInstance.repaint (r);\n" -" else if (currentEvent.isMouse)\n" -" guiInstance.handleMouseEvent (currentEventType);\n" -" else if (currentEvent.isKey)\n" -" guiInstance.handleKeyEvent (currentEventType);\n" -"\n" -" return false;\n" -" }\n" -"}\n" -"\n" -"#endif\n"; +"void %%content_component_class%%::paint (juce::Graphics& g)\r\n" +"{\r\n" +" // You can add your component specific drawing code here!\r\n" +" // This will draw over the top of the openGL background.\r\n" +"}\r\n" +"\r\n" +"void %%content_component_class%%::resized()\r\n" +"{\r\n" +" // This is called when the %%content_component_class%% is resized.\r\n" +" // If you add any child components, this is where you should\r\n" +" // update their positions.\r\n" +"}\r\n"; -const char* jucer_UnityPluginGUIScript_cs = (const char*) temp_binary_data_55; +const char* jucer_OpenGLComponentTemplate_cpp = (const char*) temp_binary_data_55; -//================== colourscheme_dark.xml ================== +//================== jucer_OpenGLComponentTemplate.h ================== static const unsigned char temp_binary_data_56[] = +"#pragma once\r\n" +"\r\n" +"%%include_juce%%\r\n" +"\r\n" +"//==============================================================================\r\n" +"/*\r\n" +" This component lives inside our window, and this is where you should put all\r\n" +" your controls and content.\r\n" +"*/\r\n" +"class %%content_component_class%% : public juce::OpenGLAppComponent\r\n" +"{\r\n" +"public:\r\n" +" //==============================================================================\r\n" +" %%content_component_class%%();\r\n" +" ~%%content_component_class%%() override;\r\n" +"\r\n" +" //==============================================================================\r\n" +" void initialise() override;\r\n" +" void shutdown() override;\r\n" +" void render() override;\r\n" +"\r\n" +" //==============================================================================\r\n" +" void paint (juce::Graphics& g) override;\r\n" +" void resized() override;\r\n" +"\r\n" +"private:\r\n" +" //==============================================================================\r\n" +" // Your private member variables go here...\r\n" +"\r\n" +"\r\n" +" JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%content_component_class%%)\r\n" +"};\r\n"; + +const char* jucer_OpenGLComponentTemplate_h = (const char*) temp_binary_data_56; + +//================== jucer_PIPAudioProcessorTemplate.h ================== +static const unsigned char temp_binary_data_57[] = +"class %%class_name%% : public juce::AudioProcessor\r\n" +"{\r\n" +"public:\r\n" +" //==============================================================================\r\n" +" %%class_name%%()\r\n" +" : AudioProcessor (BusesProperties().withInput (\"Input\", juce::AudioChannelSet::stereo())\r\n" +" .withOutput (\"Output\", juce::AudioChannelSet::stereo()))\r\n" +" {\r\n" +" }\r\n" +"\r\n" +" ~%%class_name%%() override\r\n" +" {\r\n" +" }\r\n" +"\r\n" +" //==============================================================================\r\n" +" void prepareToPlay (double, int) override\r\n" +" {\r\n" +" // Use this method as the place to do any pre-playback\r\n" +" // initialisation that you need..\r\n" +" }\r\n" +"\r\n" +" void releaseResources() override\r\n" +" {\r\n" +" // When playback stops, you can use this as an opportunity to free up any\r\n" +" // spare memory, etc.\r\n" +" }\r\n" +"\r\n" +" void processBlock (juce::AudioBuffer<float>& buffer, juce::MidiBuffer&) override\r\n" +" {\r\n" +" juce::ScopedNoDenormals noDenormals;\r\n" +" auto totalNumInputChannels = getTotalNumInputChannels();\r\n" +" auto totalNumOutputChannels = getTotalNumOutputChannels();\r\n" +"\r\n" +" // In case we have more outputs than inputs, this code clears any output\r\n" +" // channels that didn't contain input data, (because these aren't\r\n" +" // guaranteed to be empty - they may contain garbage).\r\n" +" // This is here to avoid people getting screaming feedback\r\n" +" // when they first compile a plugin, but obviously you don't need to keep\r\n" +" // this code if your algorithm always overwrites all the output channels.\r\n" +" for (auto i = totalNumInputChannels; i < totalNumOutputChannels; ++i)\r\n" +" buffer.clear (i, 0, buffer.getNumSamples());\r\n" +"\r\n" +" // This is the place where you'd normally do the guts of your plugin's\r\n" +" // audio processing...\r\n" +" // Make sure to reset the state if your inner loop is processing\r\n" +" // the samples and the outer loop is handling the channels.\r\n" +" // Alternatively, you can process the samples with the channels\r\n" +" // interleaved by keeping the same state.\r\n" +" for (int channel = 0; channel < totalNumInputChannels; ++channel)\r\n" +" {\r\n" +" auto* channelData = buffer.getWritePointer (channel);\r\n" +"\r\n" +" // ..do something to the data...\r\n" +" }\r\n" +" }\r\n" +"\r\n" +" //==============================================================================\r\n" +" juce::AudioProcessorEditor* createEditor() override { return nullptr; }\r\n" +" bool hasEditor() const override { return false; }\r\n" +"\r\n" +" //==============================================================================\r\n" +" const juce::String getName() const override { return \"%%name%%\"; }\r\n" +" bool acceptsMidi() const override { return false; }\r\n" +" bool producesMidi() const override { return false; }\r\n" +" double getTailLengthSeconds() const override { return 0; }\r\n" +"\r\n" +" //==============================================================================\r\n" +" int getNumPrograms() override { return 1; }\r\n" +" int getCurrentProgram() override { return 0; }\r\n" +" void setCurrentProgram (int) override {}\r\n" +" const juce::String getProgramName (int) override { return {}; }\r\n" +" void changeProgramName (int, const juce::String&) override {}\r\n" +"\r\n" +" //==============================================================================\r\n" +" void getStateInformation (juce::MemoryBlock& destData) override\r\n" +" {\r\n" +" // You should use this method to store your parameters in the memory block.\r\n" +" // You could do that either as raw data, or use the XML or ValueTree classes\r\n" +" // as intermediaries to make it easy to save and load complex data.\r\n" +" }\r\n" +"\r\n" +" void setStateInformation (const void* data, int sizeInBytes) override\r\n" +" {\r\n" +" // You should use this method to restore your parameters from this memory block,\r\n" +" // whose contents will have been created by the getStateInformation() call.\r\n" +" }\r\n" +"\r\n" +" //==============================================================================\r\n" +" bool isBusesLayoutSupported (const BusesLayout& layouts) const override\r\n" +" {\r\n" +" // This is the place where you check if the layout is supported.\r\n" +" // In this template code we only support mono or stereo.\r\n" +" if (layouts.getMainOutputChannelSet() != juce::AudioChannelSet::mono()\r\n" +" && layouts.getMainOutputChannelSet() != juce::AudioChannelSet::stereo())\r\n" +" return false;\r\n" +"\r\n" +" // This checks if the input layout matches the output layout\r\n" +" if (layouts.getMainOutputChannelSet() != layouts.getMainInputChannelSet())\r\n" +" return false;\r\n" +"\r\n" +" return true;\r\n" +" }\r\n" +"\r\n" +"private:\r\n" +" //==============================================================================\r\n" +" JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%class_name%%)\r\n" +"};\r\n"; + +const char* jucer_PIPAudioProcessorTemplate_h = (const char*) temp_binary_data_57; + +//================== jucer_PIPTemplate.h ================== +static const unsigned char temp_binary_data_58[] = +"/*******************************************************************************\r\n" +" The block below describes the properties of this PIP. A PIP is a short snippet\r\n" +" of code that can be read by the Projucer and used to generate a JUCE project.\r\n" +"\r\n" +" BEGIN_JUCE_PIP_METADATA\r\n" +"\r\n" +"%%pip_metadata%%\r\n" +"\r\n" +" END_JUCE_PIP_METADATA\r\n" +"\r\n" +"*******************************************************************************/\r\n" +"\r\n" +"#pragma once\r\n" +"\r\n" +"\r\n" +"//==============================================================================\r\n" +"%%pip_code%%\r\n"; + +const char* jucer_PIPTemplate_h = (const char*) temp_binary_data_58; + +//================== colourscheme_dark.xml ================== +static const unsigned char temp_binary_data_59[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" "\r\n" "<COLOUR_SCHEME font=\"&lt;Monospaced&gt;; 13.0\">\r\n" @@ -7510,10 +7451,10 @@ static const unsigned char temp_binary_data_56[] = " <COLOUR name=\"Error\" colour=\"FFE60000\"/>\r\n" "</COLOUR_SCHEME>\r\n"; -const char* colourscheme_dark_xml = (const char*) temp_binary_data_56; +const char* colourscheme_dark_xml = (const char*) temp_binary_data_59; //================== colourscheme_light.xml ================== -static const unsigned char temp_binary_data_57[] = +static const unsigned char temp_binary_data_60[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" "\r\n" "<COLOUR_SCHEME font=\"&lt;Monospaced&gt;; 13.0\">\r\n" @@ -7538,267 +7479,71 @@ static const unsigned char temp_binary_data_57[] = " <COLOUR name=\"Error\" colour=\"ffcc0000\"/>\r\n" "</COLOUR_SCHEME>\r\n"; -const char* colourscheme_light_xml = (const char*) temp_binary_data_57; - -//================== nothingtoseehere.txt ================== -static const unsigned char temp_binary_data_58[] = -"VUEtMTk3NTkzMTgtNA=="; - -const char* nothingtoseehere_txt = (const char*) temp_binary_data_58; - -//================== offlinepage.html ================== -static const unsigned char temp_binary_data_59[] = -"<html>\n" -" <head>\n" -" <meta http-equiv=\"X-UA-Compatible\" content=\"IE=11\">\n" -" <style>\n" -" body {\n" -" background-color: #f1f1f1;\n" -" color: #101010;\n" -" font-family: Helvetica, Arial, sans-serif;\n" -" display: flex;\n" -" justify-content: center;\n" -" align-items: center;\n" -" }\n" -" .button {\n" -" display: block;\n" -" padding: 15px 20px 16px;\n" -" width: 200px;\n" -" border: 1px solid #c8c9cb;\n" -" border-radius: 6px;\n" -" margin: auto;\n" -" cursor: pointer;\n" -" font-size: 20px;\n" -" margin-top: 30px;\n" -" color: inherit;\n" -" text-decoration: none;\n" -" }\n" -" #offline {\n" -" display: block;\n" -" text-align: center;\n" -" }\n" -" </style>\n" -" </head>\n" -" <body>\n" -" <div id='offline'>\n" -" <h1>No internet connection</h1>\n" -"\n" -" <p>You appear to be offline. An internet connection is required to login to the Projucer.</p>\n" -" <p>If you want to use JUCE under the GPL without signing-in, you can enable the pre-processor macro JUCER_ENABLE_GPL_MODE=1 and recompile the Projucer yourself.</p>\n" -"\n" -" <a class='button' href='__URL_PLACEHOLDER__'>Try again</a>\n" -" </div>\n" -" </body>\n" -"</html>"; - -const char* offlinepage_html = (const char*) temp_binary_data_59; +const char* colourscheme_light_xml = (const char*) temp_binary_data_60; -//================== projucer_EULA.txt ================== -static const unsigned char temp_binary_data_60[] = -"\r\n" -"IMPORTANT NOTICE: PLEASE READ CAREFULLY BEFORE INSTALLING THE SOFTWARE:\r\n" -"\r\n" -"This license agreement (License) is a legal agreement between you (Licensee or you) and Raw Material Software Limited (Licensor, us or we) for:\r\n" -"\r\n" -"- The Projucer software and the associated media and, save where expressly specified through subsequent license terms notified to you in writing, any and all new releases, derivatives of and updates thereto supplied by us to you for a period of one (" -"1) month from the date of your installation of the software (the Software);\r\n" -"\r\n" -"- printed materials and online and electronic documentation (Documentation).\r\n" -"\r\n" -"The Software is comprised of numerous components that may be licensed under separate license terms. The Software is a collective work of the Licensor and we license the use of the Software and Documentation to you on the basis of this License and any" -" applicable license terms for any third party software components which make up the Software. Where you deal with a copy of any software component independent from the Software, you must remove all our trade marks, trade dress and logos from that cop" -"y.\r\n" -"\r\n" -"We do not sell the Software or Documentation to you. We and/or our licensors remain the owners of the Software and Documentation at all times. If you are accepting the terms of this License on behalf of a company or other legal entity, you represent " -"and warrant that you have the authority to bind that company or other legal entity to the terms of this License and, in such event, \"you\" and \"Licensee\" will refer to that company or other legal entity.\r\n" -"\r\n" -"The Software may be downloaded from the Licensor website - www.juce.com - (the \"Website\").\r\n" -"\r\n" -"OPERATING SYSTEM REQUIREMENTS: The Software requires a Windows or MAC OS X operating system.\r\n" -"\r\n" -"IMPORTANT NOTICE TO ALL USERS:\r\n" -"\r\n" -"- BY CLICKING ON THE \"ACCEPT\" BUTTON BELOW YOU AGREE TO THE TERMS OF THIS LICENCE WHICH WILL BIND YOU AND YOUR EMPLOYEES.\r\n" -"\r\n" -"- IF YOU DO NOT AGREE TO THE TERMS OF THIS LICENCE, WE WILL NOT LICENSE THE SOFTWARE AND DOCUMENTATION TO YOU AND YOU MUST DISCONTINUE THE INSTALLATION PROCESS.\r\n" -"\r\n" -"\r\n" -"You should print a copy of this License for future reference.\r\n" -"\r\n" -"1. Grant and scope of license\r\n" -"\r\n" -"1.1. In consideration of you agreeing to abide by the terms of this License the Licensor hereby grants to you a non-exclusive, non-transferable license to use the Software and the Documentation on the terms of this License.\r\n" -"\r\n" -"1.2. You may:\r\n" -" (a) install and use the Software for your internal business purposes on one central processing unit (CPU) per single user license granted through this License;\r\n" -" (b) provided it is used on only one computer at any one time, transfer the Software from one computer to another;\r\n" -" (c) provided you comply with the provisions in clause 2, make a single copy of the Software for back-up purposes, provided that you reproduce on it all copyright and other proprietary notices that are on the original copy of the Software;\r\n" -" (d) receive and use any free supplementary software code or update of the Software incorporating \"patches\", corrections of errors and software updates as may be provided by the Licensor from time to time;\r\n" -" (e) use any Documentation in support of the use permitted under condition 1.2 and make a single copy of the Documentation as is reasonably necessary for its lawful use.\r\n" -"\r\n" -"2. Restrictions\r\n" -" Except as expressly set out in this License or as permitted by any local law, you undertake:\r\n" -" (a) not, in whole or in part, to copy the Software or Documentation except where such copying is incidental to normal use of the Software or where it is necessary for the purpose of back-up or operational security;\r\n" -" (b) not to rent, lease, sub-license, loan, translate, merge, adapt, vary or modify the Software or Documentation;\r\n" -" (c) not to make alterations to, or modifications of, the whole or any part of the Software nor permit the Software or any part of it to be combined with, or become incorporated in, any other programs;\r\n" -" (d) not to disassemble, de-compile, reverse engineer or create derivative works based on the whole or any part of the Software nor attempt to do any such things except to the extent that (by virtue of section 296A of the Copyright, Designs and Pat" -"ents Act 1988) such actions cannot be prohibited because they are essential for the purpose of achieving inter-operability of the Software with another software program, and provided that the information obtained by you during such activities:\r\n" -" (i) is used only for the purpose of achieving inter-operability of the Software with another software program;\r\n" -" (ii) is not disclosed or communicated without the Licensor's prior written consent to any third party to whom it is not necessary to disclose or communicate it; and\r\n" -" (iii) is not used to create any software which is substantially similar to the Software;\r\n" -" (e) to keep all copies of the Software secure and to maintain accurate and up-to-date records of the number and locations of all copies of the Software;\r\n" -" (f) not to provide, or otherwise make available, the Software in any form, in whole or in part (including, but not limited to, program listings, object and source program listings, object code and source code) to any person other than your employe" -"es without prior written consent from us;\r\n" -" (g) to comply with all applicable technology control or export laws and regulations.\r\n" -" (h) to supervise and control use of the Software and ensure that the Software is used by your employees and representatives in accordance with the terms of this License;\r\n" -" (i) not to charge or otherwise deal in the Software or any part or interest therein except as expressly provided herein;\r\n" -" (j) not to use the Software for any illegal or immoral purposes;\r\n" -" (k) not otherwise use, copy, transfer or distribute the Software or part of it, except as expressly permitted by this License, in any manner which is inconsistent with this License.\r\n" -"\r\n" -"3. Fee\r\n" -"\r\n" -"3.1. You may install and use a limited version of the Software (Demo Mode).\r\n" -"\r\n" -"3.2. Where you have purchased the JUCE 4 software on or after 1 November 2015 you shall be entitled to use the Software for free subject to your continued payment of the JUCE 4 software license fee and the JUCE 4 license terms.\r\n" -"\r\n" -"3.3. Save as set out above, your right to use the Software shall be subject to payment of the Projucer Software license fee.\r\n" -"\r\n" -"3.4. Where you have purchased a perpetual license you agree to pay the license fee as notified to you on the Website at the time you purchase the License.\r\n" -"\r\n" -"3.5. Where you have purchased an educational license the fee shall be the fee as notified to you on the Website at the time you purchase the License and shall be payable for each academic year from the first day of the first full calendar month after" -" the grant of the License and thereafter on the anniversary of that initial payment date.\r\n" -"\r\n" -"4. Intellectual property rights\r\n" -"\r\n" -"4.1. You acknowledge that all intellectual property rights in the Software and the Documentation and all copies thereof throughout the world belong to us, that rights in the Software are licensed (not sold) to you, and that you have no rights in, or " -"to, the Software or the Documentation other than the right to use them in accordance with the terms of this License.\r\n" -"\r\n" -"4.2. You acknowledge that you have no right to have access to the Software in source code form or in unlocked coding or with comments.\r\n" -"\r\n" -"4.3. The Software may contain certain third party licensed materials and our licensors may act to protect their rights in the event of any violation of this License.\r\n" -"\r\n" -"5. Limited warranty\r\n" -"\r\n" -"5.1. We warrant that, save as already set out above in relation to component parts of the Software, we own the Software and have the right to convey this License.\r\n" -"\r\n" -"5.2. We shall have no obligation to provide support and maintenance services to you. You may participate in our online support forum in accordance with our forum policies in place from time to time.\r\n" -"\r\n" -"5.3. We do not warrant that your use of the Software will be uninterrupted or error free.\r\n" -"\r\n" -"6. Limitation of liability\r\n" -"\r\n" -"6.1. You acknowledge that the Software has not been developed to meet your individual requirements, and that it is therefore your responsibility to ensure that the facilities and functions of the Software as described in the Documentation meet your r" -"equirements.\r\n" -"\r\n" -"6.2. Without prejudice to clause 5.4 below, you acknowledge that the Software is not designed or intended for use with on-line control equipment in hazardous environments requiring fail safe performance, such as in the operation of nuclear facilities" -", aircraft navigation, communication, or control systems, direct life support machines, weapons systems, or other uses in which failure of the Software could lead directly to death, personal injury or severe physical or environmental damage.\r\n" -"\r\n" -"6.3. Neither the Licensor nor its parent company, subsidiaries or employees shall in any circumstances whatsoever be liable to you, whether in contract, tort (including negligence), breach of statutory duty, or otherwise, arising under or in connecti" -"on with this License for any indirect, consequential or special loss or damage, including but not limited to, for:\r\n" -" (a) loss of profits, sales, business, or revenue;\r\n" -" (b) business interruption;\r\n" -" (c) loss of anticipated savings;\r\n" -" (d) loss or corruption of data or information;\r\n" -" (e) loss of business opportunity, goodwill or reputation;\r\n" -" (f) any indirect or consequential loss or damage; or\r\n" -" (g) any computer failure or malfunction, corruption to or loss of data or files, or any and all other commercial damage or loss.\r\n" -"\r\n" -"6.4. Nothing in this License shall limit or exclude our liability for:\r\n" -" (a) death or personal injury resulting from our negligence;\r\n" -" (b) fraud or fraudulent misrepresentation;\r\n" -" (c) any other liability that cannot be excluded or limited by English law.\r\n" -"\r\n" -"6.5. This License sets out the full extent of our obligations and liabilities in respect of the supply of the Software and Documentation. Except as expressly stated in this License, there are no conditions, warranties, representations or other terms," -" express or implied, that are binding on us. Any condition, warranty, representation or other term concerning the supply of the Software and Documentation which might otherwise be implied into, or incorporated in, this License whether by statute, co" -"mmon law or otherwise, is excluded to the fullest extent permitted by law.\r\n" -"\r\n" -"6.6. Subject to clause 5.2 and 5.3, our maximum aggregate liability under or in connection with this License whether in contract, tort (including negligence) or otherwise, shall in all circumstances be limited to a sum equal to $49.\r\n" -"\r\n" -"6.7. You agree to indemnify, defend and hold us and our licensors, partners, affiliates, contractors, officers, directors, employees and agents harmless from any claims, costs and expenses (including legal expenses) arising directly or indirectly fro" -"m your use, handling or operation of the Software otherwise than in accordance with this Agreement.\r\n" -"\r\n" -"6.8. This clause 5 shall survive and shall not be rendered ineffective by the termination or expiry of this agreement for whatever reason.\r\n" +//================== juce_runtime_arch_detection.cpp ================== +static const unsigned char temp_binary_data_61[] = +"#if defined(__arm__) || defined(__TARGET_ARCH_ARM) || defined(_M_ARM) || defined(_M_ARM64) || defined(__aarch64__) || defined(__ARM64__)\r\n" +"\r\n" +" #if defined(_M_ARM64) || defined(__aarch64__) || defined(__ARM64__)\r\n" +" #error JUCE_ARCH arm64\r\n" +" #elif (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM == 8) || defined(__ARMv8__) || defined(__ARMv8_A__)\r\n" +" #error JUCE_ARCH armv8l\r\n" +" #elif (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM == 7) || defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) || defined(_ARM_ARCH_7) || defined(__CORE_CORTEX" +"A__)\r\n" +" #error JUCE_ARCH armv7l\r\n" +" #elif (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM == 6) || defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6T2__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_A" +"RCH_6M__)\r\n" +" #error JUCE_ARCH armv6l\r\n" +" #elif (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM == 5) || defined(__ARM_ARCH_5TEJ__)\r\n" +" #error JUCE_ARCH armv5l\r\n" +" #else\r\n" +" #error JUCE_ARCH arm\r\n" +" #endif\r\n" "\r\n" -"7. Termination\r\n" +"#elif defined(__i386) || defined(__i386__) || defined(_M_IX86)\r\n" "\r\n" -"7.1. We may terminate this License immediately by written notice to you if you commit a material or persistent breach of this License which you fail to remedy (if remediable) within 14 days after the service of written notice requiring you to do so.\r" -"\n" +" #error JUCE_ARCH i386\r\n" "\r\n" -"7.2. Upon termination for any reason:\r\n" -" (a) all rights granted to you under this License shall cease;\r\n" -" (b) you must cease all activities authorised by this License;\r\n" -" (c) you must immediately delete or remove the Software from all computer equipment in your possession and immediately destroy or return to us (at our option) all copies of the Software then in your possession, custody or control and, in the case o" -"f destruction, certify to us that you have done so.\r\n" +"#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64)\r\n" "\r\n" -"8. Communications between us\r\n" +" #error JUCE_ARCH x86_64\r\n" "\r\n" -"8.1. If you wish to contact us in writing, or if any condition in this License requires you to give us notice in writing, you can send this to us by e-mail or by pre-paid post to us at support@juce.com. We will confirm receipt of this by contacting y" -"ou in writing, normally by e-mail.\r\n" +"#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)\r\n" "\r\n" -"8.2. If we have to contact you or give you notice in writing, we will do so by e-mail or by pre-paid post to the address you provide to us in your order for the Software.\r\n" +" #error JUCE_ARCH ia64\r\n" "\r\n" -"9. Data\r\n" +"#elif defined(__mips) || defined(__mips__) || defined(_M_MRX000)\r\n" "\r\n" -"9.1. We may collect and process information about your use of or Software through the Software, some of which may amount to your personal data. Personal data will be collected and processed in accordance with our Privacy Policy which can be reviewed " -"at https://www.juce.com/privacy-policy.\r\n" +" #if defined(_MIPS_ARCH_MIPS64) || defined(__mips64)\r\n" +" #error JUCE_ARCH mips64\r\n" +" #else\r\n" +" #error JUCE_ARCH mips\r\n" +" #endif\r\n" "\r\n" -"10. Other important terms\r\n" +"#elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__) || defined(_ARCH_COM) || defined(_ARCH_PWR) || defined(_ARCH_PPC) || defined(_M_MPPC) || defined(_M_PPC)\r\n" "\r\n" -"10.1. We may transfer our rights and obligations under this License to another organisation, but this will not affect your rights or our obligations under this License.\r\n" +" #if defined(__ppc64__) || defined(__powerpc64__) || defined(__64BIT__)\r\n" +" #error JUCE_ARCH ppc64\r\n" +" #else\r\n" +" #error JUCE_ARCH ppc\r\n" +" #endif\r\n" "\r\n" -"10.2. You may only transfer your rights or your obligations under this License to another person if we agree in writing.\r\n" +"#elif defined(__riscv)\r\n" "\r\n" -"10.3. This License and any document expressly referred to in it constitutes the entire agreement between you and us. You acknowledge that you have not relied on any statement, promise or representation made or given by or on behalf of us which is not" -" set out in this License or any document expressly referred to in it.\r\n" +" #if __riscv_xlen == 64\r\n" +" #error JUCE_ARCH riscv64\r\n" +" #else\r\n" +" #error JUCE_ARCH riscv\r\n" +" #endif\r\n" "\r\n" -"10.4. If we fail to insist that you perform any of your obligations under this License, or if we do not enforce our rights against you, or if we delay in doing so, that will not mean that we have waived our rights against you and will not mean that y" -"ou do not have to comply with those obligations. If we do waive a default by you, we will only do so in writing, and that will not mean that we will automatically waive any later default by you.\r\n" +"#else\r\n" "\r\n" -"10.5. Each of the conditions of this License operates separately. If any court or competent authority decides that any of them are unlawful or unenforceable, the remaining conditions will remain in full force and effect.\r\n" +" #error JUCE_ARCH unknown\r\n" "\r\n" -"10.6. Please note that this License, its subject matter and its formation, are governed by English law. You and we both agree to that the courts of England and Wales will have exclusive jurisdiction.\r\n"; - -const char* projucer_EULA_txt = (const char*) temp_binary_data_60; - -//================== RecentFilesMenuTemplate.nib ================== -static const unsigned char temp_binary_data_61[] = -{ 98,112,108,105,115,116,48,48,212,0,1,0,2,0,3,0,4,0,5,0,6,1,53,1,54,88,36,118,101,114,115,105,111,110,88,36,111,98,106,101,99,116,115,89,36,97,114,99,104,105,118,101,114,84,36,116,111,112,18,0,1,134,160,175,16,74,0,7,0,8,0,31,0,35,0,36,0,42,0,46,0,50, -0,53,0,57,0,74,0,77,0,78,0,86,0,87,0,97,0,112,0,113,0,114,0,119,0,120,0,121,0,124,0,128,0,129,0,132,0,143,0,144,0,145,0,149,0,153,0,162,0,163,0,164,0,169,0,173,0,180,0,181,0,182,0,185,0,192,0,193,0,200,0,201,0,208,0,209,0,216,0,217,0,224,0,225,0,226, -0,229,0,230,0,232,0,249,1,11,1,29,1,30,1,31,1,32,1,33,1,34,1,35,1,36,1,37,1,38,1,39,1,40,1,41,1,42,1,43,1,44,1,47,1,50,85,36,110,117,108,108,219,0,9,0,10,0,11,0,12,0,13,0,14,0,15,0,16,0,17,0,18,0,19,0,20,0,21,0,22,0,23,0,24,0,25,0,26,0,27,0,28,0,29,0, -29,95,16,16,78,83,86,105,115,105,98,108,101,87,105,110,100,111,119,115,93,78,83,79,98,106,101,99,116,115,75,101,121,115,86,78,83,82,111,111,116,92,78,83,79,105,100,115,86,97,108,117,101,115,86,36,99,108,97,115,115,90,78,83,79,105,100,115,75,101,121,115, -93,78,83,67,111,110,110,101,99,116,105,111,110,115,95,16,15,78,83,79,98,106,101,99,116,115,86,97,108,117,101,115,95,16,25,78,83,65,99,99,101,115,115,105,98,105,108,105,116,121,67,111,110,110,101,99,116,111,114,115,95,16,23,78,83,65,99,99,101,115,115, -105,98,105,108,105,116,121,79,105,100,115,75,101,121,115,95,16,25,78,83,65,99,99,101,115,115,105,98,105,108,105,116,121,79,105,100,115,86,97,108,117,101,115,128,5,128,9,128,2,128,55,128,73,128,54,128,7,128,53,128,71,128,72,128,72,210,0,13,0,32,0,33,0, -34,91,78,83,67,108,97,115,115,78,97,109,101,128,4,128,3,93,78,83,65,112,112,108,105,99,97,116,105,111,110,210,0,37,0,38,0,39,0,40,90,36,99,108,97,115,115,110,97,109,101,88,36,99,108,97,115,115,101,115,94,78,83,67,117,115,116,111,109,79,98,106,101,99, -116,162,0,39,0,41,88,78,83,79,98,106,101,99,116,210,0,13,0,43,0,44,0,45,90,78,83,46,111,98,106,101,99,116,115,128,6,160,210,0,37,0,38,0,47,0,48,92,78,83,77,117,116,97,98,108,101,83,101,116,163,0,47,0,49,0,41,85,78,83,83,101,116,210,0,13,0,43,0,51,0,52, -128,8,160,210,0,37,0,38,0,54,0,55,94,78,83,77,117,116,97,98,108,101,65,114,114,97,121,163,0,54,0,56,0,41,87,78,83,65,114,114,97,121,210,0,13,0,43,0,58,0,59,128,52,174,0,60,0,61,0,62,0,63,0,64,0,65,0,66,0,67,0,68,0,69,0,70,0,71,0,72,0,73,128,10,128,12, -128,45,128,15,128,39,128,25,128,28,128,30,128,33,128,35,128,43,128,41,128,47,128,50,210,0,13,0,32,0,33,0,76,128,4,128,11,93,78,83,65,112,112,108,105,99,97,116,105,111,110,212,0,79,0,13,0,80,0,81,0,82,0,83,0,84,0,85,91,78,83,77,101,110,117,73,116,101, -109,115,86,78,83,78,97,109,101,87,78,83,84,105,116,108,101,128,14,128,38,128,49,128,13,89,65,77,97,105,110,77,101,110,117,210,0,13,0,43,0,51,0,89,128,8,167,0,63,0,65,0,64,0,71,0,70,0,62,0,72,128,15,128,25,128,39,128,41,128,43,128,45,128,47,216,0,98,0, -99,0,100,0,13,0,101,0,102,0,103,0,81,0,104,0,61,0,106,0,107,0,108,0,109,0,110,0,111,95,16,17,78,83,75,101,121,69,113,117,105,118,77,111,100,77,97,115,107,86,78,83,77,101,110,117,89,78,83,79,110,73,109,97,103,101,90,78,83,75,101,121,69,113,117,105,118, -93,78,83,77,110,101,109,111,110,105,99,76,111,99,92,78,83,77,105,120,101,100,73,109,97,103,101,18,0,16,0,0,128,12,128,18,128,24,128,17,18,127,255,255,255,128,22,128,16,91,100,101,108,109,101,65,112,112,75,105,116,80,211,0,13,0,115,0,32,0,116,0,117,0, -118,94,78,83,82,101,115,111,117,114,99,101,78,97,109,101,128,21,128,20,128,19,87,78,83,73,109,97,103,101,95,16,15,78,83,77,101,110,117,67,104,101,99,107,109,97,114,107,210,0,37,0,38,0,122,0,123,95,16,16,78,83,67,117,115,116,111,109,82,101,115,111,117, -114,99,101,162,0,122,0,41,211,0,13,0,115,0,32,0,116,0,126,0,118,128,21,128,23,128,19,95,16,16,78,83,77,101,110,117,77,105,120,101,100,83,116,97,116,101,210,0,37,0,38,0,130,0,131,90,78,83,77,101,110,117,73,116,101,109,162,0,130,0,41,218,0,133,0,98,0,134, -0,99,0,100,0,13,0,101,0,102,0,103,0,81,0,135,0,104,0,66,0,61,0,106,0,107,0,108,0,109,0,110,0,142,88,78,83,65,99,116,105,111,110,89,78,83,83,117,98,109,101,110,117,128,27,128,28,128,12,128,18,128,24,128,17,128,22,128,26,84,70,105,108,101,94,115,117,98, -109,101,110,117,65,99,116,105,111,110,58,211,0,79,0,13,0,81,0,146,0,83,0,142,128,29,128,38,128,26,210,0,13,0,43,0,51,0,151,128,8,161,0,67,128,30,218,0,133,0,98,0,134,0,99,0,100,0,13,0,101,0,102,0,103,0,81,0,154,0,104,0,68,0,66,0,106,0,107,0,108,0,109, -0,110,0,161,128,32,128,33,128,28,128,18,128,24,128,17,128,22,128,31,91,79,112,101,110,32,82,101,99,101,110,116,94,115,117,98,109,101,110,117,65,99,116,105,111,110,58,212,0,79,0,13,0,80,0,81,0,165,0,83,0,167,0,161,128,34,128,38,128,37,128,31,210,0,13, -0,43,0,51,0,171,128,8,161,0,69,128,35,216,0,98,0,99,0,100,0,13,0,101,0,102,0,103,0,81,0,104,0,68,0,106,0,107,0,108,0,109,0,110,0,179,128,33,128,18,128,24,128,17,128,22,128,36,90,67,108,101,97,114,32,77,101,110,117,95,16,22,95,78,83,82,101,99,101,110, -116,68,111,99,117,109,101,110,116,115,77,101,110,117,210,0,37,0,38,0,183,0,184,86,78,83,77,101,110,117,162,0,183,0,41,216,0,98,0,99,0,100,0,13,0,101,0,102,0,103,0,81,0,104,0,61,0,106,0,107,0,108,0,109,0,110,0,191,128,12,128,18,128,24,128,17,128,22,128, -40,84,69,100,105,116,215,0,99,0,100,0,13,0,101,0,102,0,103,0,81,0,61,0,106,0,107,0,108,0,109,0,110,0,199,128,12,128,18,128,24,128,17,128,22,128,42,86,70,111,114,109,97,116,216,0,98,0,99,0,100,0,13,0,101,0,102,0,103,0,81,0,104,0,61,0,106,0,107,0,108,0, -109,0,110,0,207,128,12,128,18,128,24,128,17,128,22,128,44,84,86,105,101,119,216,0,98,0,99,0,100,0,13,0,101,0,102,0,103,0,81,0,104,0,61,0,106,0,107,0,108,0,109,0,110,0,215,128,12,128,18,128,24,128,17,128,22,128,46,86,87,105,110,100,111,119,215,0,99,0, -100,0,13,0,101,0,102,0,103,0,81,0,61,0,106,0,107,0,108,0,109,0,110,0,223,128,12,128,18,128,24,128,17,128,22,128,48,84,72,101,108,112,91,95,78,83,77,97,105,110,77,101,110,117,210,0,13,0,32,0,33,0,228,128,4,128,51,93,78,83,70,111,110,116,77,97,110,97,103, -101,114,210,0,37,0,38,0,56,0,231,162,0,56,0,41,210,0,13,0,43,0,58,0,234,128,52,174,0,22,0,22,0,61,0,61,0,61,0,61,0,65,0,66,0,67,0,68,0,61,0,61,0,61,0,22,128,2,128,2,128,12,128,12,128,12,128,12,128,25,128,28,128,30,128,33,128,12,128,12,128,12,128,2,210, -0,13,0,43,0,58,0,251,128,52,175,16,15,0,22,0,60,0,61,0,62,0,63,0,64,0,65,0,66,0,67,0,68,0,69,0,70,0,71,0,72,0,73,128,2,128,10,128,12,128,45,128,15,128,39,128,25,128,28,128,30,128,33,128,35,128,43,128,41,128,47,128,50,210,0,13,0,43,0,58,1,13,128,52,175, -16,15,1,14,1,15,1,16,1,17,1,18,1,19,1,20,1,21,1,22,1,23,1,24,1,25,1,26,1,27,1,28,128,56,128,57,128,58,128,59,128,60,128,61,128,62,128,63,128,64,128,65,128,66,128,67,128,68,128,69,128,70,17,2,22,17,2,23,17,2,24,17,2,25,17,2,26,17,2,27,17,2,28,17,2,29, -17,2,30,17,2,31,17,2,32,17,2,33,17,2,34,17,2,35,17,2,36,210,0,13,0,43,0,51,1,46,128,8,160,210,0,13,0,43,0,58,1,49,128,52,160,210,0,37,0,38,1,51,1,52,94,78,83,73,66,79,98,106,101,99,116,68,97,116,97,162,1,51,0,41,95,16,15,78,83,75,101,121,101,100,65,114, -99,104,105,118,101,114,209,1,55,1,56,93,73,66,46,111,98,106,101,99,116,100,97,116,97,128,1,0,8,0,25,0,34,0,43,0,53,0,58,0,63,0,214,0,220,1,9,1,28,1,42,1,49,1,62,1,69,1,80,1,94,1,112,1,140,1,166,1,194,1,196,1,198,1,200,1,202,1,204,1,206,1,208,1,210,1, -212,1,214,1,216,1,225,1,237,1,239,1,241,1,255,2,8,2,19,2,28,2,43,2,48,2,57,2,66,2,77,2,79,2,80,2,89,2,102,2,109,2,115,2,124,2,126,2,127,2,136,2,151,2,158,2,166,2,175,2,177,2,206,2,208,2,210,2,212,2,214,2,216,2,218,2,220,2,222,2,224,2,226,2,228,2,230, -2,232,2,234,2,243,2,245,2,247,3,5,3,22,3,34,3,41,3,49,3,51,3,53,3,55,3,57,3,67,3,76,3,78,3,93,3,95,3,97,3,99,3,101,3,103,3,105,3,107,3,140,3,160,3,167,3,177,3,188,3,202,3,215,3,220,3,222,3,224,3,226,3,228,3,233,3,235,3,237,3,249,3,250,4,7,4,22,4,24,4, -26,4,28,4,36,4,54,4,63,4,82,4,87,4,100,4,102,4,104,4,106,4,125,4,134,4,145,4,150,4,191,4,200,4,210,4,212,4,214,4,216,4,218,4,220,4,222,4,224,4,226,4,231,4,246,5,3,5,5,5,7,5,9,5,18,5,20,5,23,5,25,5,66,5,68,5,70,5,72,5,74,5,76,5,78,5,80,5,82,5,94,5,109, -5,126,5,128,5,130,5,132,5,134,5,143,5,145,5,148,5,150,5,183,5,185,5,187,5,189,5,191,5,193,5,195,5,206,5,231,5,240,5,247,5,252,6,29,6,31,6,33,6,35,6,37,6,39,6,41,6,46,6,75,6,77,6,79,6,81,6,83,6,85,6,87,6,94,6,127,6,129,6,131,6,133,6,135,6,137,6,139,6, -144,6,177,6,179,6,181,6,183,6,185,6,187,6,189,6,196,6,225,6,227,6,229,6,231,6,233,6,235,6,237,6,242,6,254,7,7,7,9,7,11,7,25,7,34,7,39,7,48,7,50,7,79,7,81,7,83,7,85,7,87,7,89,7,91,7,93,7,95,7,97,7,99,7,101,7,103,7,105,7,107,7,116,7,118,7,151,7,153,7,155, -7,157,7,159,7,161,7,163,7,165,7,167,7,169,7,171,7,173,7,175,7,177,7,179,7,181,7,190,7,192,7,225,7,227,7,229,7,231,7,233,7,235,7,237,7,239,7,241,7,243,7,245,7,247,7,249,7,251,7,253,7,255,8,2,8,5,8,8,8,11,8,14,8,17,8,20,8,23,8,26,8,29,8,32,8,35,8,38,8, -41,8,44,8,53,8,55,8,56,8,65,8,67,8,68,8,77,8,92,8,97,8,115,8,120,8,134,0,0,0,0,0,0,2,2,0,0,0,0,0,0,1,57,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,136,0,0 }; +"#endif\r\n"; -const char* RecentFilesMenuTemplate_nib = (const char*) temp_binary_data_61; +const char* juce_runtime_arch_detection_cpp = (const char*) temp_binary_data_61; const char* getNamedResource (const char* resourceNameUTF8, int& numBytes) @@ -7811,6 +7556,12 @@ const char* getNamedResource (const char* resourceNameUTF8, int& numBytes) switch (hash) { + case 0x31d21131: numBytes = 1042; return LaunchScreen_storyboard; + case 0x24e5a04d: numBytes = 483; return PIPAudioProcessor_cpp_in; + case 0xd572ce5a: numBytes = 2275; return PIPComponent_cpp_in; + case 0x1a77c680: numBytes = 299; return PIPConsole_cpp_in; + case 0xa41e649d: numBytes = 2842; return RecentFilesMenuTemplate_nib; + case 0x667fbbb3: numBytes = 6424; return UnityPluginGUIScript_cs_in; case 0x4d6bedc8: numBytes = 53636; return gradlewrapper_jar; case 0x10b04d10: numBytes = 4971; return gradlew; case 0x76cff066: numBytes = 2404; return gradlew_bat; @@ -7822,7 +7573,7 @@ const char* getNamedResource (const char* resourceNameUTF8, int& numBytes) case 0x96d2a1ce: numBytes = 28184; return export_linux_svg; case 0x2505bd06: numBytes = 1706; return export_visualStudio_svg; case 0x3198e2bf: numBytes = 12295; return export_xcode_svg; - case 0x0cd37295: numBytes = 3375; return huckleberry_icon_svg; + case 0xc9c78dec: numBytes = 27030; return gpl_logo_svg; case 0x80b17530: numBytes = 5312; return jucelogowithtext_svg; case 0x154a7275: numBytes = 45854; return juce_icon_png; case 0x1f3b6d2f: numBytes = 5978; return wizard_AnimatedApp_svg; @@ -7835,44 +7586,38 @@ const char* getNamedResource (const char* resourceNameUTF8, int& numBytes) case 0x52a8dfdf: numBytes = 1859; return wizard_Openfile_svg; case 0x58e2ae48: numBytes = 4551; return wizard_OpenGL_svg; case 0xb1da6f9e: numBytes = 7488; return wizard_StaticLibrary_svg; - case 0xd11e6d35: numBytes = 2085; return jucer_AnimatedComponentSimpleTemplate_h; - case 0x6cf2645e: numBytes = 1563; return jucer_AnimatedComponentTemplate_cpp; - case 0x97b055e3: numBytes = 1201; return jucer_AnimatedComponentTemplate_h; - case 0xfb6f6d96: numBytes = 3693; return jucer_AudioComponentSimpleTemplate_h; - case 0xafccbd3f: numBytes = 3094; return jucer_AudioComponentTemplate_cpp; - case 0x915d7304: numBytes = 1374; return jucer_AudioComponentTemplate_h; - case 0x27c5a93a: numBytes = 1356; return jucer_AudioPluginEditorTemplate_cpp; - case 0x4d0721bf: numBytes = 977; return jucer_AudioPluginEditorTemplate_h; - case 0x51b49ac5: numBytes = 6036; return jucer_AudioPluginFilterTemplate_cpp; - case 0x488afa0a: numBytes = 2272; return jucer_AudioPluginFilterTemplate_h; - case 0xabad7041: numBytes = 2126; return jucer_ComponentTemplate_cpp; - case 0xfc72fe86: numBytes = 2044; return jucer_ComponentTemplate_h; - case 0x1657b643: numBytes = 1693; return jucer_ContentCompSimpleTemplate_h; - case 0x0b66646c: numBytes = 1190; return jucer_ContentCompTemplate_cpp; - case 0x6fa10171: numBytes = 1071; return jucer_ContentCompTemplate_h; - case 0x28d496ad: numBytes = 1233; return jucer_InlineComponentTemplate_h; - case 0x8905395b: numBytes = 473; return jucer_MainConsoleAppTemplate_cpp; - case 0x5e5ea047: numBytes = 2021; return jucer_MainTemplate_NoWindow_cpp; - case 0xda2391f8: numBytes = 4127; return jucer_MainTemplate_SimpleWindow_cpp; - case 0x400bc026: numBytes = 4127; return jucer_MainTemplate_Window_cpp; - case 0xf4842835: numBytes = 1491; return jucer_NewComponentTemplate_cpp; - case 0xe7bf237a: numBytes = 646; return jucer_NewComponentTemplate_h; + case 0xd11e6d35: numBytes = 1898; return jucer_AnimatedComponentSimpleTemplate_h; + case 0x6cf2645e: numBytes = 1362; return jucer_AnimatedComponentTemplate_cpp; + case 0x97b055e3: numBytes = 1008; return jucer_AnimatedComponentTemplate_h; + case 0xfb6f6d96: numBytes = 3554; return jucer_AudioComponentSimpleTemplate_h; + case 0xafccbd3f: numBytes = 2941; return jucer_AudioComponentTemplate_cpp; + case 0x915d7304: numBytes = 1187; return jucer_AudioComponentTemplate_h; + case 0x27c5a93a: numBytes = 1355; return jucer_AudioPluginEditorTemplate_cpp; + case 0x4d0721bf: numBytes = 973; return jucer_AudioPluginEditorTemplate_h; + case 0x51b49ac5: numBytes = 6090; return jucer_AudioPluginFilterTemplate_cpp; + case 0x488afa0a: numBytes = 2299; return jucer_AudioPluginFilterTemplate_h; + case 0xabad7041: numBytes = 2147; return jucer_ComponentTemplate_cpp; + case 0xfc72fe86: numBytes = 2065; return jucer_ComponentTemplate_h; + case 0x1657b643: numBytes = 1524; return jucer_ContentCompSimpleTemplate_h; + case 0x0b66646c: numBytes = 1007; return jucer_ContentCompTemplate_cpp; + case 0x6fa10171: numBytes = 878; return jucer_ContentCompTemplate_h; + case 0x28d496ad: numBytes = 1276; return jucer_InlineComponentTemplate_h; + case 0x8905395b: numBytes = 443; return jucer_MainConsoleAppTemplate_cpp; + case 0x5e5ea047: numBytes = 1999; return jucer_MainTemplate_NoWindow_cpp; + case 0x400bc026: numBytes = 4081; return jucer_MainTemplate_Window_cpp; + case 0xf4842835: numBytes = 1521; return jucer_NewComponentTemplate_cpp; + case 0xe7bf237a: numBytes = 665; return jucer_NewComponentTemplate_h; case 0x02a2a077: numBytes = 278; return jucer_NewCppFileTemplate_cpp; case 0x0842c43c: numBytes = 258; return jucer_NewCppFileTemplate_h; - case 0x36e634a1: numBytes = 1676; return jucer_NewInlineComponentTemplate_h; - case 0x6bdeb129: numBytes = 2174; return jucer_OpenGLComponentSimpleTemplate_h; - case 0x7fbac252: numBytes = 1665; return jucer_OpenGLComponentTemplate_cpp; - case 0x491fa0d7: numBytes = 1263; return jucer_OpenGLComponentTemplate_h; - case 0xbc050edc: numBytes = 4926; return jucer_PIPAudioProcessorTemplate_h; - case 0xf4ca9e9a: numBytes = 2421; return jucer_PIPMain_cpp; + case 0x36e634a1: numBytes = 1719; return jucer_NewInlineComponentTemplate_h; + case 0x6bdeb129: numBytes = 1987; return jucer_OpenGLComponentSimpleTemplate_h; + case 0x7fbac252: numBytes = 1470; return jucer_OpenGLComponentTemplate_cpp; + case 0x491fa0d7: numBytes = 1070; return jucer_OpenGLComponentTemplate_h; + case 0xbc050edc: numBytes = 5055; return jucer_PIPAudioProcessorTemplate_h; case 0x0b16e320: numBytes = 517; return jucer_PIPTemplate_h; - case 0xcd472557: numBytes = 6433; return jucer_UnityPluginGUIScript_cs; case 0x763d39dc: numBytes = 1050; return colourscheme_dark_xml; case 0xe8b08520: numBytes = 1050; return colourscheme_light_xml; - case 0x938e96ec: numBytes = 20; return nothingtoseehere_txt; - case 0xf11580d8: numBytes = 1155; return offlinepage_html; - case 0xd6bb7d1d: numBytes = 14361; return projucer_EULA_txt; - case 0xa41e649d: numBytes = 2842; return RecentFilesMenuTemplate_nib; + case 0x7c03d519: numBytes = 2127; return juce_runtime_arch_detection_cpp; default: break; } @@ -7882,6 +7627,12 @@ const char* getNamedResource (const char* resourceNameUTF8, int& numBytes) const char* namedResourceList[] = { + "LaunchScreen_storyboard", + "PIPAudioProcessor_cpp_in", + "PIPComponent_cpp_in", + "PIPConsole_cpp_in", + "RecentFilesMenuTemplate_nib", + "UnityPluginGUIScript_cs_in", "gradlewrapper_jar", "gradlew", "gradlew_bat", @@ -7893,7 +7644,7 @@ const char* namedResourceList[] = "export_linux_svg", "export_visualStudio_svg", "export_xcode_svg", - "huckleberry_icon_svg", + "gpl_logo_svg", "jucelogowithtext_svg", "juce_icon_png", "wizard_AnimatedApp_svg", @@ -7924,7 +7675,6 @@ const char* namedResourceList[] = "jucer_InlineComponentTemplate_h", "jucer_MainConsoleAppTemplate_cpp", "jucer_MainTemplate_NoWindow_cpp", - "jucer_MainTemplate_SimpleWindow_cpp", "jucer_MainTemplate_Window_cpp", "jucer_NewComponentTemplate_cpp", "jucer_NewComponentTemplate_h", @@ -7935,19 +7685,20 @@ const char* namedResourceList[] = "jucer_OpenGLComponentTemplate_cpp", "jucer_OpenGLComponentTemplate_h", "jucer_PIPAudioProcessorTemplate_h", - "jucer_PIPMain_cpp", "jucer_PIPTemplate_h", - "jucer_UnityPluginGUIScript_cs", "colourscheme_dark_xml", "colourscheme_light_xml", - "nothingtoseehere_txt", - "offlinepage_html", - "projucer_EULA_txt", - "RecentFilesMenuTemplate_nib" + "juce_runtime_arch_detection_cpp" }; const char* originalFilenames[] = { + "LaunchScreen.storyboard", + "PIPAudioProcessor.cpp.in", + "PIPComponent.cpp.in", + "PIPConsole.cpp.in", + "RecentFilesMenuTemplate.nib", + "UnityPluginGUIScript.cs.in", "gradle-wrapper.jar", "gradlew", "gradlew.bat", @@ -7959,7 +7710,7 @@ const char* originalFilenames[] = "export_linux.svg", "export_visualStudio.svg", "export_xcode.svg", - "huckleberry_icon.svg", + "gpl_logo.svg", "juce-logo-with-text.svg", "juce_icon.png", "wizard_AnimatedApp.svg", @@ -7990,7 +7741,6 @@ const char* originalFilenames[] = "jucer_InlineComponentTemplate.h", "jucer_MainConsoleAppTemplate.cpp", "jucer_MainTemplate_NoWindow.cpp", - "jucer_MainTemplate_SimpleWindow.cpp", "jucer_MainTemplate_Window.cpp", "jucer_NewComponentTemplate.cpp", "jucer_NewComponentTemplate.h", @@ -8001,15 +7751,10 @@ const char* originalFilenames[] = "jucer_OpenGLComponentTemplate.cpp", "jucer_OpenGLComponentTemplate.h", "jucer_PIPAudioProcessorTemplate.h", - "jucer_PIPMain.cpp", "jucer_PIPTemplate.h", - "jucer_UnityPluginGUIScript.cs", "colourscheme_dark.xml", "colourscheme_light.xml", - "nothingtoseehere.txt", - "offlinepage.html", - "projucer_EULA.txt", - "RecentFilesMenuTemplate.nib" + "juce_runtime_arch_detection.cpp" }; const char* getNamedResourceOriginalFilename (const char* resourceNameUTF8) diff --git a/extras/Projucer/JuceLibraryCode/BinaryData.h b/extras/Projucer/JuceLibraryCode/BinaryData.h index 474d506e..e2eeae6b 100644 --- a/extras/Projucer/JuceLibraryCode/BinaryData.h +++ b/extras/Projucer/JuceLibraryCode/BinaryData.h @@ -8,6 +8,24 @@ namespace BinaryData { + extern const char* LaunchScreen_storyboard; + const int LaunchScreen_storyboardSize = 1042; + + extern const char* PIPAudioProcessor_cpp_in; + const int PIPAudioProcessor_cpp_inSize = 483; + + extern const char* PIPComponent_cpp_in; + const int PIPComponent_cpp_inSize = 2275; + + extern const char* PIPConsole_cpp_in; + const int PIPConsole_cpp_inSize = 299; + + extern const char* RecentFilesMenuTemplate_nib; + const int RecentFilesMenuTemplate_nibSize = 2842; + + extern const char* UnityPluginGUIScript_cs_in; + const int UnityPluginGUIScript_cs_inSize = 6424; + extern const char* gradlewrapper_jar; const int gradlewrapper_jarSize = 53636; @@ -41,8 +59,8 @@ namespace BinaryData extern const char* export_xcode_svg; const int export_xcode_svgSize = 12295; - extern const char* huckleberry_icon_svg; - const int huckleberry_icon_svgSize = 3375; + extern const char* gpl_logo_svg; + const int gpl_logo_svgSize = 27030; extern const char* jucelogowithtext_svg; const int jucelogowithtext_svgSize = 5312; @@ -81,70 +99,67 @@ namespace BinaryData const int wizard_StaticLibrary_svgSize = 7488; extern const char* jucer_AnimatedComponentSimpleTemplate_h; - const int jucer_AnimatedComponentSimpleTemplate_hSize = 2085; + const int jucer_AnimatedComponentSimpleTemplate_hSize = 1898; extern const char* jucer_AnimatedComponentTemplate_cpp; - const int jucer_AnimatedComponentTemplate_cppSize = 1563; + const int jucer_AnimatedComponentTemplate_cppSize = 1362; extern const char* jucer_AnimatedComponentTemplate_h; - const int jucer_AnimatedComponentTemplate_hSize = 1201; + const int jucer_AnimatedComponentTemplate_hSize = 1008; extern const char* jucer_AudioComponentSimpleTemplate_h; - const int jucer_AudioComponentSimpleTemplate_hSize = 3693; + const int jucer_AudioComponentSimpleTemplate_hSize = 3554; extern const char* jucer_AudioComponentTemplate_cpp; - const int jucer_AudioComponentTemplate_cppSize = 3094; + const int jucer_AudioComponentTemplate_cppSize = 2941; extern const char* jucer_AudioComponentTemplate_h; - const int jucer_AudioComponentTemplate_hSize = 1374; + const int jucer_AudioComponentTemplate_hSize = 1187; extern const char* jucer_AudioPluginEditorTemplate_cpp; - const int jucer_AudioPluginEditorTemplate_cppSize = 1356; + const int jucer_AudioPluginEditorTemplate_cppSize = 1355; extern const char* jucer_AudioPluginEditorTemplate_h; - const int jucer_AudioPluginEditorTemplate_hSize = 977; + const int jucer_AudioPluginEditorTemplate_hSize = 973; extern const char* jucer_AudioPluginFilterTemplate_cpp; - const int jucer_AudioPluginFilterTemplate_cppSize = 6036; + const int jucer_AudioPluginFilterTemplate_cppSize = 6090; extern const char* jucer_AudioPluginFilterTemplate_h; - const int jucer_AudioPluginFilterTemplate_hSize = 2272; + const int jucer_AudioPluginFilterTemplate_hSize = 2299; extern const char* jucer_ComponentTemplate_cpp; - const int jucer_ComponentTemplate_cppSize = 2126; + const int jucer_ComponentTemplate_cppSize = 2147; extern const char* jucer_ComponentTemplate_h; - const int jucer_ComponentTemplate_hSize = 2044; + const int jucer_ComponentTemplate_hSize = 2065; extern const char* jucer_ContentCompSimpleTemplate_h; - const int jucer_ContentCompSimpleTemplate_hSize = 1693; + const int jucer_ContentCompSimpleTemplate_hSize = 1524; extern const char* jucer_ContentCompTemplate_cpp; - const int jucer_ContentCompTemplate_cppSize = 1190; + const int jucer_ContentCompTemplate_cppSize = 1007; extern const char* jucer_ContentCompTemplate_h; - const int jucer_ContentCompTemplate_hSize = 1071; + const int jucer_ContentCompTemplate_hSize = 878; extern const char* jucer_InlineComponentTemplate_h; - const int jucer_InlineComponentTemplate_hSize = 1233; + const int jucer_InlineComponentTemplate_hSize = 1276; extern const char* jucer_MainConsoleAppTemplate_cpp; - const int jucer_MainConsoleAppTemplate_cppSize = 473; + const int jucer_MainConsoleAppTemplate_cppSize = 443; extern const char* jucer_MainTemplate_NoWindow_cpp; - const int jucer_MainTemplate_NoWindow_cppSize = 2021; - - extern const char* jucer_MainTemplate_SimpleWindow_cpp; - const int jucer_MainTemplate_SimpleWindow_cppSize = 4127; + const int jucer_MainTemplate_NoWindow_cppSize = 1999; extern const char* jucer_MainTemplate_Window_cpp; - const int jucer_MainTemplate_Window_cppSize = 4127; + const int jucer_MainTemplate_Window_cppSize = 4081; extern const char* jucer_NewComponentTemplate_cpp; - const int jucer_NewComponentTemplate_cppSize = 1491; + const int jucer_NewComponentTemplate_cppSize = 1521; extern const char* jucer_NewComponentTemplate_h; - const int jucer_NewComponentTemplate_hSize = 646; + const int jucer_NewComponentTemplate_hSize = 665; extern const char* jucer_NewCppFileTemplate_cpp; const int jucer_NewCppFileTemplate_cppSize = 278; @@ -153,46 +168,31 @@ namespace BinaryData const int jucer_NewCppFileTemplate_hSize = 258; extern const char* jucer_NewInlineComponentTemplate_h; - const int jucer_NewInlineComponentTemplate_hSize = 1676; + const int jucer_NewInlineComponentTemplate_hSize = 1719; extern const char* jucer_OpenGLComponentSimpleTemplate_h; - const int jucer_OpenGLComponentSimpleTemplate_hSize = 2174; + const int jucer_OpenGLComponentSimpleTemplate_hSize = 1987; extern const char* jucer_OpenGLComponentTemplate_cpp; - const int jucer_OpenGLComponentTemplate_cppSize = 1665; + const int jucer_OpenGLComponentTemplate_cppSize = 1470; extern const char* jucer_OpenGLComponentTemplate_h; - const int jucer_OpenGLComponentTemplate_hSize = 1263; + const int jucer_OpenGLComponentTemplate_hSize = 1070; extern const char* jucer_PIPAudioProcessorTemplate_h; - const int jucer_PIPAudioProcessorTemplate_hSize = 4926; - - extern const char* jucer_PIPMain_cpp; - const int jucer_PIPMain_cppSize = 2421; + const int jucer_PIPAudioProcessorTemplate_hSize = 5055; extern const char* jucer_PIPTemplate_h; const int jucer_PIPTemplate_hSize = 517; - extern const char* jucer_UnityPluginGUIScript_cs; - const int jucer_UnityPluginGUIScript_csSize = 6433; - extern const char* colourscheme_dark_xml; const int colourscheme_dark_xmlSize = 1050; extern const char* colourscheme_light_xml; const int colourscheme_light_xmlSize = 1050; - extern const char* nothingtoseehere_txt; - const int nothingtoseehere_txtSize = 20; - - extern const char* offlinepage_html; - const int offlinepage_htmlSize = 1155; - - extern const char* projucer_EULA_txt; - const int projucer_EULA_txtSize = 14361; - - extern const char* RecentFilesMenuTemplate_nib; - const int RecentFilesMenuTemplate_nibSize = 2842; + extern const char* juce_runtime_arch_detection_cpp; + const int juce_runtime_arch_detection_cppSize = 2127; // Number of elements in the namedResourceList and originalFileNames arrays. const int namedResourceListSize = 62; diff --git a/extras/Projucer/JuceLibraryCode/JuceHeader.h b/extras/Projucer/JuceLibraryCode/JuceHeader.h index abc5ebe6..5d222093 100644 --- a/extras/Projucer/JuceLibraryCode/JuceHeader.h +++ b/extras/Projucer/JuceLibraryCode/JuceHeader.h @@ -12,9 +12,8 @@ #pragma once -#include "AppConfig.h" -#include <juce_analytics/juce_analytics.h> +#include <juce_build_tools/juce_build_tools.h> #include <juce_core/juce_core.h> #include <juce_cryptography/juce_cryptography.h> #include <juce_data_structures/juce_data_structures.h> @@ -44,8 +43,8 @@ namespace ProjectInfo { const char* const projectName = "Projucer"; - const char* const companyName = "ROLI Ltd."; - const char* const versionString = "5.4.7"; - const int versionNumber = 0x50407; + const char* const companyName = "Raw Material Software Limited"; + const char* const versionString = "6.0.5"; + const int versionNumber = 0x60005; } #endif diff --git a/extras/Projucer/JuceLibraryCode/include_juce_analytics.cpp b/extras/Projucer/JuceLibraryCode/include_juce_build_tools.cpp similarity index 66% rename from extras/Projucer/JuceLibraryCode/include_juce_analytics.cpp rename to extras/Projucer/JuceLibraryCode/include_juce_build_tools.cpp index 3dfd4d21..e87b7351 100644 --- a/extras/Projucer/JuceLibraryCode/include_juce_analytics.cpp +++ b/extras/Projucer/JuceLibraryCode/include_juce_build_tools.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" -#include <juce_analytics/juce_analytics.cpp> +#include <juce_build_tools/juce_build_tools.cpp> diff --git a/extras/Projucer/JuceLibraryCode/include_juce_core.cpp b/extras/Projucer/JuceLibraryCode/include_juce_core.cpp index d0ce1636..84fe988c 100644 --- a/extras/Projucer/JuceLibraryCode/include_juce_core.cpp +++ b/extras/Projucer/JuceLibraryCode/include_juce_core.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_core/juce_core.cpp> diff --git a/extras/Projucer/JuceLibraryCode/include_juce_core.mm b/extras/Projucer/JuceLibraryCode/include_juce_core.mm index 72b10bf8..9ee67bf6 100644 --- a/extras/Projucer/JuceLibraryCode/include_juce_core.mm +++ b/extras/Projucer/JuceLibraryCode/include_juce_core.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_core/juce_core.mm> diff --git a/extras/Projucer/JuceLibraryCode/include_juce_cryptography.cpp b/extras/Projucer/JuceLibraryCode/include_juce_cryptography.cpp index 10b3401d..ee7d9085 100644 --- a/extras/Projucer/JuceLibraryCode/include_juce_cryptography.cpp +++ b/extras/Projucer/JuceLibraryCode/include_juce_cryptography.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_cryptography/juce_cryptography.cpp> diff --git a/extras/Projucer/JuceLibraryCode/include_juce_cryptography.mm b/extras/Projucer/JuceLibraryCode/include_juce_cryptography.mm index 9311ea0f..03ee05f4 100644 --- a/extras/Projucer/JuceLibraryCode/include_juce_cryptography.mm +++ b/extras/Projucer/JuceLibraryCode/include_juce_cryptography.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_cryptography/juce_cryptography.mm> diff --git a/extras/Projucer/JuceLibraryCode/include_juce_data_structures.cpp b/extras/Projucer/JuceLibraryCode/include_juce_data_structures.cpp index 9315aa16..152980ae 100644 --- a/extras/Projucer/JuceLibraryCode/include_juce_data_structures.cpp +++ b/extras/Projucer/JuceLibraryCode/include_juce_data_structures.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_data_structures/juce_data_structures.cpp> diff --git a/extras/Projucer/JuceLibraryCode/include_juce_data_structures.mm b/extras/Projucer/JuceLibraryCode/include_juce_data_structures.mm index 695ec439..02b9711c 100644 --- a/extras/Projucer/JuceLibraryCode/include_juce_data_structures.mm +++ b/extras/Projucer/JuceLibraryCode/include_juce_data_structures.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_data_structures/juce_data_structures.mm> diff --git a/extras/Projucer/JuceLibraryCode/include_juce_events.cpp b/extras/Projucer/JuceLibraryCode/include_juce_events.cpp index 1bba110a..39268e2b 100644 --- a/extras/Projucer/JuceLibraryCode/include_juce_events.cpp +++ b/extras/Projucer/JuceLibraryCode/include_juce_events.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_events/juce_events.cpp> diff --git a/extras/Projucer/JuceLibraryCode/include_juce_events.mm b/extras/Projucer/JuceLibraryCode/include_juce_events.mm index 4cc34fc4..191a9987 100644 --- a/extras/Projucer/JuceLibraryCode/include_juce_events.mm +++ b/extras/Projucer/JuceLibraryCode/include_juce_events.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_events/juce_events.mm> diff --git a/extras/Projucer/JuceLibraryCode/include_juce_graphics.cpp b/extras/Projucer/JuceLibraryCode/include_juce_graphics.cpp index 319c76de..8ccabef9 100644 --- a/extras/Projucer/JuceLibraryCode/include_juce_graphics.cpp +++ b/extras/Projucer/JuceLibraryCode/include_juce_graphics.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_graphics/juce_graphics.cpp> diff --git a/extras/Projucer/JuceLibraryCode/include_juce_graphics.mm b/extras/Projucer/JuceLibraryCode/include_juce_graphics.mm index b28e6dd0..6bb7456d 100644 --- a/extras/Projucer/JuceLibraryCode/include_juce_graphics.mm +++ b/extras/Projucer/JuceLibraryCode/include_juce_graphics.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_graphics/juce_graphics.mm> diff --git a/extras/Projucer/JuceLibraryCode/include_juce_gui_basics.cpp b/extras/Projucer/JuceLibraryCode/include_juce_gui_basics.cpp index 216c76bb..71d04b24 100644 --- a/extras/Projucer/JuceLibraryCode/include_juce_gui_basics.cpp +++ b/extras/Projucer/JuceLibraryCode/include_juce_gui_basics.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_gui_basics/juce_gui_basics.cpp> diff --git a/extras/Projucer/JuceLibraryCode/include_juce_gui_basics.mm b/extras/Projucer/JuceLibraryCode/include_juce_gui_basics.mm index 6a9726fa..e449e0b7 100644 --- a/extras/Projucer/JuceLibraryCode/include_juce_gui_basics.mm +++ b/extras/Projucer/JuceLibraryCode/include_juce_gui_basics.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_gui_basics/juce_gui_basics.mm> diff --git a/extras/Projucer/JuceLibraryCode/include_juce_gui_extra.cpp b/extras/Projucer/JuceLibraryCode/include_juce_gui_extra.cpp index 7226e198..a33ece00 100644 --- a/extras/Projucer/JuceLibraryCode/include_juce_gui_extra.cpp +++ b/extras/Projucer/JuceLibraryCode/include_juce_gui_extra.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_gui_extra/juce_gui_extra.cpp> diff --git a/extras/Projucer/JuceLibraryCode/include_juce_gui_extra.mm b/extras/Projucer/JuceLibraryCode/include_juce_gui_extra.mm index c9b6c3bf..6dacee3a 100644 --- a/extras/Projucer/JuceLibraryCode/include_juce_gui_extra.mm +++ b/extras/Projucer/JuceLibraryCode/include_juce_gui_extra.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_gui_extra/juce_gui_extra.mm> diff --git a/extras/Projucer/Projucer.jucer b/extras/Projucer/Projucer.jucer index 4e877daa..362bd5e0 100644 --- a/extras/Projucer/Projucer.jucer +++ b/extras/Projucer/Projucer.jucer @@ -1,14 +1,15 @@ <?xml version="1.0" encoding="UTF-8"?> <JUCERPROJECT id="M70qfTRRk" name="Projucer" projectType="guiapp" juceFolder="../../juce" - jucerVersion="5.4.7" version="5.4.7" bundleIdentifier="com.juce.theprojucer" - splashScreenColour="Dark" displaySplashScreen="0" reportAppUsage="0" - companyName="ROLI Ltd." companyCopyright="ROLI Ltd." cppLanguageStandard="11"> + version="6.0.5" bundleIdentifier="com.juce.theprojucer" splashScreenColour="Dark" + displaySplashScreen="0" reportAppUsage="0" companyName="Raw Material Software Limited" + companyCopyright="Raw Material Software Limited" cppLanguageStandard="11" + useAppConfig="0" addUsingNamespaceToJuceHeader="1" jucerFormatVersion="1"> <EXPORTFORMATS> <XCODE_MAC targetFolder="Builds/MacOSX" vstFolder="~/SDKs/vstsdk2.4" rtasFolder="~/SDKs/PT_80_SDK" - documentExtensions=".jucer" objCExtraSuffix="zkVtji" bigIcon="rv1F4h" + documentExtensions=".jucer" objCExtraSuffix="zkVtji" bigIcon="Zrx1Gl" extraFrameworks="AudioUnit; Accelerate; AVFoundation; CoreAudio; CoreAudioKit; CoreMIDI; DiscRecording; QuartzCore; AudioToolbox; OpenGL; QTKit; QuickTime" - microphonePermissionNeeded="1" cameraPermissionNeeded="1"> + microphonePermissionNeeded="1" cameraPermissionNeeded="1" smallIcon="Zrx1Gl"> <CONFIGURATIONS> <CONFIGURATION name="Debug" isDebug="1" targetName="Projucer" cppLibType="libc++" recommendedWarnings="LLVM"/> @@ -23,10 +24,11 @@ <MODULEPATH id="juce_data_structures" path="../../modules"/> <MODULEPATH id="juce_cryptography" path="../../modules"/> <MODULEPATH id="juce_core" path="../../modules"/> - <MODULEPATH id="juce_analytics" path="../../modules"/> + <MODULEPATH id="juce_build_tools" path="../Build"/> </MODULEPATHS> </XCODE_MAC> - <VS2015 targetFolder="Builds/VisualStudio2015" bigIcon="rv1F4h" extraCompilerFlags="/bigobj"> + <VS2015 targetFolder="Builds/VisualStudio2015" bigIcon="Zrx1Gl" extraCompilerFlags="/bigobj" + smallIcon="Zrx1Gl"> <CONFIGURATIONS> <CONFIGURATION name="Debug" isDebug="1" targetName="Projucer" debugInformationFormat="ProgramDatabase" useRuntimeLibDLL="1"/> @@ -41,10 +43,11 @@ <MODULEPATH id="juce_data_structures" path="../../modules"/> <MODULEPATH id="juce_cryptography" path="../../modules"/> <MODULEPATH id="juce_core" path="../../modules"/> - <MODULEPATH id="juce_analytics" path="../../modules"/> + <MODULEPATH id="juce_build_tools" path="../Build"/> </MODULEPATHS> </VS2015> - <VS2017 targetFolder="Builds/VisualStudio2017" bigIcon="rv1F4h" extraCompilerFlags="/w44265 /w45038 /w44062"> + <VS2017 targetFolder="Builds/VisualStudio2017" bigIcon="Zrx1Gl" extraCompilerFlags="/w44265 /w45038 /w44062" + smallIcon="Zrx1Gl"> <CONFIGURATIONS> <CONFIGURATION name="Debug" isDebug="1" targetName="Projucer" useRuntimeLibDLL="0"/> <CONFIGURATION name="Release" isDebug="0" optimisation="3" targetName="Projucer" @@ -58,10 +61,11 @@ <MODULEPATH id="juce_data_structures" path="../../modules"/> <MODULEPATH id="juce_cryptography" path="../../modules"/> <MODULEPATH id="juce_core" path="../../modules"/> - <MODULEPATH id="juce_analytics" path="../../modules"/> + <MODULEPATH id="juce_build_tools" path="../Build"/> </MODULEPATHS> </VS2017> - <VS2019 targetFolder="Builds/VisualStudio2019" bigIcon="rv1F4h" extraCompilerFlags="/w44265 /w45038 /w44062"> + <VS2019 targetFolder="Builds/VisualStudio2019" bigIcon="Zrx1Gl" extraCompilerFlags="/w44265 /w45038 /w44062" + smallIcon="Zrx1Gl"> <CONFIGURATIONS> <CONFIGURATION name="Debug" isDebug="1" targetName="Projucer" useRuntimeLibDLL="0"/> <CONFIGURATION name="Release" isDebug="0" optimisation="3" targetName="Projucer" @@ -75,10 +79,10 @@ <MODULEPATH id="juce_data_structures" path="../../modules"/> <MODULEPATH id="juce_cryptography" path="../../modules"/> <MODULEPATH id="juce_core" path="../../modules"/> - <MODULEPATH id="juce_analytics" path="../../modules"/> + <MODULEPATH id="juce_build_tools" path="../Build"/> </MODULEPATHS> </VS2019> - <LINUX_MAKE targetFolder="Builds/LinuxMakefile" bigIcon="rv1F4h"> + <LINUX_MAKE targetFolder="Builds/LinuxMakefile" bigIcon="Zrx1Gl" smallIcon="Zrx1Gl"> <CONFIGURATIONS> <CONFIGURATION name="Debug" isDebug="1" targetName="Projucer"/> <CONFIGURATION name="Release" isDebug="0" targetName="Projucer"/> @@ -91,17 +95,41 @@ <MODULEPATH id="juce_data_structures" path="../../modules"/> <MODULEPATH id="juce_cryptography" path="../../modules"/> <MODULEPATH id="juce_core" path="../../modules"/> - <MODULEPATH id="juce_analytics" path="../../modules"/> + <MODULEPATH id="juce_build_tools" path="../Build"/> </MODULEPATHS> </LINUX_MAKE> </EXPORTFORMATS> <MAINGROUP name="Projucer" id="NhrJq66R"> <GROUP id="{9E4C4E0D-7BAB-EB6F-87DA-FB264EC2AE68}" name="Application"> + <GROUP id="{2F6B47CF-F27B-0D18-331F-533DE3F89310}" name="StartPage"> + <FILE id="PewFno" name="jucer_ContentComponents.h" compile="0" resource="0" + file="Source/Application/StartPage/jucer_ContentComponents.h"/> + <FILE id="ApAD9d" name="jucer_NewProjectTemplates.h" compile="0" resource="0" + file="Source/Application/StartPage/jucer_NewProjectTemplates.h"/> + <FILE id="t8pBCG" name="jucer_NewProjectWizard.cpp" compile="1" resource="0" + file="Source/Application/StartPage/jucer_NewProjectWizard.cpp"/> + <FILE id="eoPkbr" name="jucer_NewProjectWizard.h" compile="0" resource="0" + file="Source/Application/StartPage/jucer_NewProjectWizard.h"/> + <FILE id="OuSOwU" name="jucer_StartPageComponent.cpp" compile="1" resource="0" + file="Source/Application/StartPage/jucer_StartPageComponent.cpp"/> + <FILE id="gLig4M" name="jucer_StartPageComponent.h" compile="0" resource="0" + file="Source/Application/StartPage/jucer_StartPageComponent.h"/> + <FILE id="dsxevB" name="jucer_StartPageTreeHolder.h" compile="0" resource="0" + file="Source/Application/StartPage/jucer_StartPageTreeHolder.h"/> + </GROUP> + <GROUP id="{70333C48-4F84-A180-24E1-0EC9EF223F3B}" name="UserAccount"> + <FILE id="Rw7w0l" name="jucer_LicenseController.h" compile="0" resource="0" + file="Source/Application/UserAccount/jucer_LicenseController.h"/> + <FILE id="rUtPud" name="jucer_LicenseQueryThread.h" compile="0" resource="0" + file="Source/Application/UserAccount/jucer_LicenseQueryThread.h"/> + <FILE id="Dwndl3" name="jucer_LicenseState.h" compile="0" resource="0" + file="Source/Application/UserAccount/jucer_LicenseState.h"/> + <FILE id="d5kWEN" name="jucer_LoginFormComponent.h" compile="0" resource="0" + file="Source/Application/UserAccount/jucer_LoginFormComponent.h"/> + </GROUP> <GROUP id="{2F08ABDF-C7BB-5F54-55F5-0C2E27983930}" name="Windows"> <FILE id="w1XB4w" name="jucer_AboutWindowComponent.h" compile="0" resource="0" file="Source/Application/Windows/jucer_AboutWindowComponent.h"/> - <FILE id="cWiY1u" name="jucer_ApplicationUsageDataWindowComponent.h" - compile="0" resource="0" file="Source/Application/Windows/jucer_ApplicationUsageDataWindowComponent.h"/> <FILE id="gAju2c" name="jucer_EditorColourSchemeWindowComponent.h" compile="0" resource="0" file="Source/Application/Windows/jucer_EditorColourSchemeWindowComponent.h"/> <FILE id="YO9U3v" name="jucer_FloatingToolWindow.h" compile="0" resource="0" @@ -139,136 +167,131 @@ file="Source/Application/jucer_MainWindow.cpp"/> <FILE id="HmkREh" name="jucer_MainWindow.h" compile="0" resource="0" file="Source/Application/jucer_MainWindow.h"/> - <FILE id="HcONni" name="jucer_ProjucerAnalytics.cpp" compile="1" resource="0" - file="Source/Application/jucer_ProjucerAnalytics.cpp"/> - <FILE id="spHBY0" name="jucer_ProjucerAnalytics.h" compile="0" resource="0" - file="Source/Application/jucer_ProjucerAnalytics.h"/> </GROUP> - <GROUP id="{8853BD6C-8307-BCF8-65BE-6A2F57093B40}" name="BinaryData"> - <GROUP id="{1A183456-21D3-225D-99E4-93B1A8E8C43A}" name="gradle"> - <FILE id="iKvP2G" name="gradle-wrapper.jar" compile="0" resource="1" + <GROUP id="{BFDB3102-5EB6-41E0-043A-05C0DFF7A34D}" name="BinaryData"> + <FILE id="QRvesq" name="LaunchScreen.storyboard" compile="0" resource="1" + file="../Build/CMake/LaunchScreen.storyboard"/> + <FILE id="QCgjY8" name="PIPAudioProcessor.cpp.in" compile="0" resource="1" + file="../Build/CMake/PIPAudioProcessor.cpp.in"/> + <FILE id="AwIYFr" name="PIPComponent.cpp.in" compile="0" resource="1" + file="../Build/CMake/PIPComponent.cpp.in"/> + <FILE id="SncItz" name="PIPConsole.cpp.in" compile="0" resource="1" + file="../Build/CMake/PIPConsole.cpp.in"/> + <FILE id="xokhSP" name="RecentFilesMenuTemplate.nib" compile="0" resource="1" + file="../Build/CMake/RecentFilesMenuTemplate.nib"/> + <FILE id="H4EF8K" name="UnityPluginGUIScript.cs.in" compile="0" resource="1" + file="../Build/CMake/UnityPluginGUIScript.cs.in"/> + <GROUP id="{6528902B-862F-277C-31AA-6F6283E7D5C8}" name="gradle"> + <FILE id="HA0Kl7" name="gradle-wrapper.jar" compile="0" resource="1" file="Source/BinaryData/gradle/gradle-wrapper.jar"/> - <FILE id="Ap8FMN" name="gradlew" compile="0" resource="1" file="Source/BinaryData/gradle/gradlew"/> - <FILE id="dv12Xk" name="gradlew.bat" compile="0" resource="1" file="Source/BinaryData/gradle/gradlew.bat"/> - <FILE id="Df6IUU" name="LICENSE" compile="0" resource="1" file="Source/BinaryData/gradle/LICENSE"/> + <FILE id="RmqRJ9" name="gradlew" compile="0" resource="1" file="Source/BinaryData/gradle/gradlew"/> + <FILE id="gOeI5K" name="gradlew.bat" compile="0" resource="1" file="Source/BinaryData/gradle/gradlew.bat"/> + <FILE id="xtpyoD" name="LICENSE" compile="0" resource="1" file="Source/BinaryData/gradle/LICENSE"/> </GROUP> - <GROUP id="{C49A0B44-304A-389D-AAB0-06169AD6ABAD}" name="Icons"> - <FILE id="kyKYL7" name="background_logo.svg" compile="0" resource="1" + <GROUP id="{85F5CA8E-1014-692B-2677-292237A41AF5}" name="Icons"> + <FILE id="HvDzzK" name="background_logo.svg" compile="0" resource="1" file="Source/BinaryData/Icons/background_logo.svg"/> - <FILE id="csCUBK" name="export_android.svg" compile="0" resource="1" + <FILE id="qqeJmA" name="export_android.svg" compile="0" resource="1" file="Source/BinaryData/Icons/export_android.svg"/> - <FILE id="ILM268" name="export_clion.svg" compile="0" resource="1" + <FILE id="WF3jeY" name="export_clion.svg" compile="0" resource="1" file="Source/BinaryData/Icons/export_clion.svg"/> - <FILE id="aEHhYA" name="export_codeBlocks.svg" compile="0" resource="1" + <FILE id="FiwPHz" name="export_codeBlocks.svg" compile="0" resource="1" file="Source/BinaryData/Icons/export_codeBlocks.svg"/> - <FILE id="gT2nPs" name="export_linux.svg" compile="0" resource="1" + <FILE id="WBmsi6" name="export_linux.svg" compile="0" resource="1" file="Source/BinaryData/Icons/export_linux.svg"/> - <FILE id="woYtVL" name="export_visualStudio.svg" compile="0" resource="1" + <FILE id="fETsmT" name="export_visualStudio.svg" compile="0" resource="1" file="Source/BinaryData/Icons/export_visualStudio.svg"/> - <FILE id="rgD9FB" name="export_xcode.svg" compile="0" resource="1" + <FILE id="G0oYd6" name="export_xcode.svg" compile="0" resource="1" file="Source/BinaryData/Icons/export_xcode.svg"/> - <FILE id="xH7xtt" name="huckleberry_icon.svg" compile="0" resource="1" - file="Source/BinaryData/Icons/huckleberry_icon.svg"/> - <FILE id="LKlNVR" name="juce-logo-with-text.svg" compile="0" resource="1" + <FILE id="CfDTJ0" name="gpl_logo.svg" compile="0" resource="1" file="Source/BinaryData/Icons/gpl_logo.svg"/> + <FILE id="Pk2LIn" name="juce-logo-with-text.svg" compile="0" resource="1" file="Source/BinaryData/Icons/juce-logo-with-text.svg"/> - <FILE id="rv1F4h" name="juce_icon.png" compile="0" resource="1" file="Source/BinaryData/Icons/juce_icon.png"/> - <FILE id="g5vwqt" name="wizard_AnimatedApp.svg" compile="0" resource="1" + <FILE id="Zrx1Gl" name="juce_icon.png" compile="0" resource="1" file="Source/BinaryData/Icons/juce_icon.png"/> + <FILE id="iPYmG9" name="wizard_AnimatedApp.svg" compile="0" resource="1" file="Source/BinaryData/Icons/wizard_AnimatedApp.svg"/> - <FILE id="inzYsC" name="wizard_AudioApp.svg" compile="0" resource="1" + <FILE id="nAIo3Q" name="wizard_AudioApp.svg" compile="0" resource="1" file="Source/BinaryData/Icons/wizard_AudioApp.svg"/> - <FILE id="ZQgRRl" name="wizard_AudioPlugin.svg" compile="0" resource="1" + <FILE id="hwarU2" name="wizard_AudioPlugin.svg" compile="0" resource="1" file="Source/BinaryData/Icons/wizard_AudioPlugin.svg"/> - <FILE id="jOtJaP" name="wizard_ConsoleApp.svg" compile="0" resource="1" + <FILE id="SMzg53" name="wizard_ConsoleApp.svg" compile="0" resource="1" file="Source/BinaryData/Icons/wizard_ConsoleApp.svg"/> - <FILE id="O2L6xg" name="wizard_DLL.svg" compile="0" resource="1" file="Source/BinaryData/Icons/wizard_DLL.svg"/> - <FILE id="u5Kfkt" name="wizard_GUI.svg" compile="0" resource="1" file="Source/BinaryData/Icons/wizard_GUI.svg"/> - <FILE id="fgDQ9M" name="wizard_Highlight.svg" compile="0" resource="1" + <FILE id="YG6Eva" name="wizard_DLL.svg" compile="0" resource="1" file="Source/BinaryData/Icons/wizard_DLL.svg"/> + <FILE id="obZCkC" name="wizard_GUI.svg" compile="0" resource="1" file="Source/BinaryData/Icons/wizard_GUI.svg"/> + <FILE id="U47vkJ" name="wizard_Highlight.svg" compile="0" resource="1" file="Source/BinaryData/Icons/wizard_Highlight.svg"/> - <FILE id="XUBtiD" name="wizard_Openfile.svg" compile="0" resource="1" + <FILE id="k4YA4V" name="wizard_Openfile.svg" compile="0" resource="1" file="Source/BinaryData/Icons/wizard_Openfile.svg"/> - <FILE id="IwMd6Z" name="wizard_OpenGL.svg" compile="0" resource="1" + <FILE id="jYodWX" name="wizard_OpenGL.svg" compile="0" resource="1" file="Source/BinaryData/Icons/wizard_OpenGL.svg"/> - <FILE id="mzlH8U" name="wizard_StaticLibrary.svg" compile="0" resource="1" + <FILE id="Rbi6lX" name="wizard_StaticLibrary.svg" compile="0" resource="1" file="Source/BinaryData/Icons/wizard_StaticLibrary.svg"/> </GROUP> - <GROUP id="{D5514787-89A7-C727-422F-2BF9D9C6CF70}" name="Templates"> - <FILE id="thU560" name="jucer_AnimatedComponentSimpleTemplate.h" compile="0" + <GROUP id="{A8B4BB53-2426-F6A0-9FB1-463BB9D64DB4}" name="Templates"> + <FILE id="Uadbrm" name="jucer_AnimatedComponentSimpleTemplate.h" compile="0" resource="1" file="Source/BinaryData/Templates/jucer_AnimatedComponentSimpleTemplate.h"/> - <FILE id="GCUpe7" name="jucer_AnimatedComponentTemplate.cpp" compile="0" + <FILE id="fFFqLB" name="jucer_AnimatedComponentTemplate.cpp" compile="0" resource="1" file="Source/BinaryData/Templates/jucer_AnimatedComponentTemplate.cpp"/> - <FILE id="if7mRo" name="jucer_AnimatedComponentTemplate.h" compile="0" + <FILE id="Wh7G1x" name="jucer_AnimatedComponentTemplate.h" compile="0" resource="1" file="Source/BinaryData/Templates/jucer_AnimatedComponentTemplate.h"/> - <FILE id="o5WUW4" name="jucer_AudioComponentSimpleTemplate.h" compile="0" + <FILE id="jzLsG8" name="jucer_AudioComponentSimpleTemplate.h" compile="0" resource="1" file="Source/BinaryData/Templates/jucer_AudioComponentSimpleTemplate.h"/> - <FILE id="xynUPZ" name="jucer_AudioComponentTemplate.cpp" compile="0" + <FILE id="BzvUrn" name="jucer_AudioComponentTemplate.cpp" compile="0" resource="1" file="Source/BinaryData/Templates/jucer_AudioComponentTemplate.cpp"/> - <FILE id="zC555M" name="jucer_AudioComponentTemplate.h" compile="0" + <FILE id="i9bm2b" name="jucer_AudioComponentTemplate.h" compile="0" resource="1" file="Source/BinaryData/Templates/jucer_AudioComponentTemplate.h"/> - <FILE id="A3dhSd" name="jucer_AudioPluginEditorTemplate.cpp" compile="0" + <FILE id="BYSiw7" name="jucer_AudioPluginEditorTemplate.cpp" compile="0" resource="1" file="Source/BinaryData/Templates/jucer_AudioPluginEditorTemplate.cpp"/> - <FILE id="TPGNqq" name="jucer_AudioPluginEditorTemplate.h" compile="0" + <FILE id="wcuIlm" name="jucer_AudioPluginEditorTemplate.h" compile="0" resource="1" file="Source/BinaryData/Templates/jucer_AudioPluginEditorTemplate.h"/> - <FILE id="mKYQMY" name="jucer_AudioPluginFilterTemplate.cpp" compile="0" + <FILE id="Ik2XYj" name="jucer_AudioPluginFilterTemplate.cpp" compile="0" resource="1" file="Source/BinaryData/Templates/jucer_AudioPluginFilterTemplate.cpp"/> - <FILE id="lxnKNQ" name="jucer_AudioPluginFilterTemplate.h" compile="0" + <FILE id="ZuBmpP" name="jucer_AudioPluginFilterTemplate.h" compile="0" resource="1" file="Source/BinaryData/Templates/jucer_AudioPluginFilterTemplate.h"/> - <FILE id="lK02mj" name="jucer_ComponentTemplate.cpp" compile="0" resource="1" + <FILE id="fnjYOi" name="jucer_ComponentTemplate.cpp" compile="0" resource="1" file="Source/BinaryData/Templates/jucer_ComponentTemplate.cpp"/> - <FILE id="LZik3e" name="jucer_ComponentTemplate.h" compile="0" resource="1" + <FILE id="BlVkqH" name="jucer_ComponentTemplate.h" compile="0" resource="1" file="Source/BinaryData/Templates/jucer_ComponentTemplate.h"/> - <FILE id="cTnZ6j" name="jucer_ContentCompSimpleTemplate.h" compile="0" + <FILE id="xfOeO3" name="jucer_ContentCompSimpleTemplate.h" compile="0" resource="1" file="Source/BinaryData/Templates/jucer_ContentCompSimpleTemplate.h"/> - <FILE id="yYPIFT" name="jucer_ContentCompTemplate.cpp" compile="0" + <FILE id="HX3JPg" name="jucer_ContentCompTemplate.cpp" compile="0" resource="1" file="Source/BinaryData/Templates/jucer_ContentCompTemplate.cpp"/> - <FILE id="Ze6RvS" name="jucer_ContentCompTemplate.h" compile="0" resource="1" + <FILE id="QTVhfj" name="jucer_ContentCompTemplate.h" compile="0" resource="1" file="Source/BinaryData/Templates/jucer_ContentCompTemplate.h"/> - <FILE id="SSXmPL" name="jucer_InlineComponentTemplate.h" compile="0" + <FILE id="PuyOnZ" name="jucer_InlineComponentTemplate.h" compile="0" resource="1" file="Source/BinaryData/Templates/jucer_InlineComponentTemplate.h"/> - <FILE id="DIZd10" name="jucer_MainConsoleAppTemplate.cpp" compile="0" + <FILE id="FwmOVk" name="jucer_MainConsoleAppTemplate.cpp" compile="0" resource="1" file="Source/BinaryData/Templates/jucer_MainConsoleAppTemplate.cpp"/> - <FILE id="vbXfRZ" name="jucer_MainTemplate_NoWindow.cpp" compile="0" + <FILE id="IW9dIW" name="jucer_MainTemplate_NoWindow.cpp" compile="0" resource="1" file="Source/BinaryData/Templates/jucer_MainTemplate_NoWindow.cpp"/> - <FILE id="mh39Tv" name="jucer_MainTemplate_SimpleWindow.cpp" compile="0" - resource="1" file="Source/BinaryData/Templates/jucer_MainTemplate_SimpleWindow.cpp"/> - <FILE id="H3c6AE" name="jucer_MainTemplate_Window.cpp" compile="0" + <FILE id="Zx5T5B" name="jucer_MainTemplate_Window.cpp" compile="0" resource="1" file="Source/BinaryData/Templates/jucer_MainTemplate_Window.cpp"/> - <FILE id="lCVXSL" name="jucer_NewComponentTemplate.cpp" compile="0" + <FILE id="jCBXcQ" name="jucer_NewComponentTemplate.cpp" compile="0" resource="1" file="Source/BinaryData/Templates/jucer_NewComponentTemplate.cpp"/> - <FILE id="nsaLHZ" name="jucer_NewComponentTemplate.h" compile="0" resource="1" + <FILE id="Jmpp81" name="jucer_NewComponentTemplate.h" compile="0" resource="1" file="Source/BinaryData/Templates/jucer_NewComponentTemplate.h"/> - <FILE id="edeOEj" name="jucer_NewCppFileTemplate.cpp" compile="0" resource="1" + <FILE id="mJuFw3" name="jucer_NewCppFileTemplate.cpp" compile="0" resource="1" file="Source/BinaryData/Templates/jucer_NewCppFileTemplate.cpp"/> - <FILE id="tXjAnD" name="jucer_NewCppFileTemplate.h" compile="0" resource="1" + <FILE id="AMybWD" name="jucer_NewCppFileTemplate.h" compile="0" resource="1" file="Source/BinaryData/Templates/jucer_NewCppFileTemplate.h"/> - <FILE id="gqGzE1" name="jucer_NewInlineComponentTemplate.h" compile="0" + <FILE id="UfHALE" name="jucer_NewInlineComponentTemplate.h" compile="0" resource="1" file="Source/BinaryData/Templates/jucer_NewInlineComponentTemplate.h"/> - <FILE id="EfEiMx" name="jucer_OpenGLComponentSimpleTemplate.h" compile="0" + <FILE id="l16bPj" name="jucer_OpenGLComponentSimpleTemplate.h" compile="0" resource="1" file="Source/BinaryData/Templates/jucer_OpenGLComponentSimpleTemplate.h"/> - <FILE id="fSnbWk" name="jucer_OpenGLComponentTemplate.cpp" compile="0" + <FILE id="r1X5GG" name="jucer_OpenGLComponentTemplate.cpp" compile="0" resource="1" file="Source/BinaryData/Templates/jucer_OpenGLComponentTemplate.cpp"/> - <FILE id="Edyh5d" name="jucer_OpenGLComponentTemplate.h" compile="0" + <FILE id="FBo5Mj" name="jucer_OpenGLComponentTemplate.h" compile="0" resource="1" file="Source/BinaryData/Templates/jucer_OpenGLComponentTemplate.h"/> - <FILE id="BVHe2G" name="jucer_PIPAudioProcessorTemplate.h" compile="0" + <FILE id="e0zFrj" name="jucer_PIPAudioProcessorTemplate.h" compile="0" resource="1" file="Source/BinaryData/Templates/jucer_PIPAudioProcessorTemplate.h"/> - <FILE id="aUkNL5" name="jucer_PIPMain.cpp" compile="0" resource="1" - file="Source/BinaryData/Templates/jucer_PIPMain.cpp"/> - <FILE id="WqDCf0" name="jucer_PIPTemplate.h" compile="0" resource="1" + <FILE id="iamwVV" name="jucer_PIPTemplate.h" compile="0" resource="1" file="Source/BinaryData/Templates/jucer_PIPTemplate.h"/> - <FILE id="wrkU1v" name="jucer_UnityPluginGUIScript.cs" compile="0" - resource="1" file="Source/BinaryData/Templates/jucer_UnityPluginGUIScript.cs"/> </GROUP> - <FILE id="oXM3fR" name="colourscheme_dark.xml" compile="0" resource="1" + <FILE id="Dfk9dC" name="colourscheme_dark.xml" compile="0" resource="1" file="Source/BinaryData/colourscheme_dark.xml"/> - <FILE id="ZZ5K4s" name="colourscheme_light.xml" compile="0" resource="1" + <FILE id="bvFank" name="colourscheme_light.xml" compile="0" resource="1" file="Source/BinaryData/colourscheme_light.xml"/> - <FILE id="gjEdBX" name="nothingtoseehere.txt" compile="0" resource="1" - file="Source/BinaryData/nothingtoseehere.txt"/> - <FILE id="ckpkjs" name="offlinepage.html" compile="0" resource="1" - file="Source/BinaryData/offlinepage.html"/> - <FILE id="kT5f0b" name="projucer_EULA.txt" compile="0" resource="1" - file="Source/BinaryData/projucer_EULA.txt"/> - <FILE id="Y4HEng" name="RecentFilesMenuTemplate.nib" compile="0" resource="1" - file="Source/BinaryData/RecentFilesMenuTemplate.nib"/> + <FILE id="SDFoQY" name="juce_runtime_arch_detection.cpp" compile="0" resource="1" + file="../Build/CMake/juce_runtime_arch_detection.cpp"/> </GROUP> <GROUP id="{A5AE7471-B900-FD9D-8DE7-2FB68D11AE30}" name="CodeEditor"> <FILE id="w3ka6n" name="jucer_DocumentEditorComponent.cpp" compile="1" @@ -472,16 +495,6 @@ <FILE id="pl4vjj" name="jucer_UtilityFunctions.h" compile="0" resource="0" file="Source/ComponentEditor/jucer_UtilityFunctions.h"/> </GROUP> - <GROUP id="{025B2596-DEB8-D8EF-367D-41C8D290229A}" name="Licenses"> - <FILE id="KCuLAZ" name="jucer_LicenseController.cpp" compile="1" resource="0" - file="Source/Licenses/jucer_LicenseController.cpp"/> - <FILE id="zrVlbi" name="jucer_LicenseController.h" compile="0" resource="0" - file="Source/Licenses/jucer_LicenseController.h"/> - <FILE id="S3VWFZ" name="jucer_LicenseThread.h" compile="0" resource="0" - file="Source/Licenses/jucer_LicenseThread.h"/> - <FILE id="lHIbn4" name="jucer_LicenseWebview.h" compile="0" resource="0" - file="Source/Licenses/jucer_LicenseWebview.h"/> - </GROUP> <GROUP id="{1F4F21DC-6856-2C06-EEC5-39EE3B95C206}" name="LiveBuildEngine"> <GROUP id="{A09CCB6F-E688-7D17-BF10-AE3C7916AACA}" name="UI"> <FILE id="ESpwdA" name="jucer_ActivityListComponent.h" compile="0" @@ -531,6 +544,15 @@ file="Source/LiveBuildEngine/jucer_SourceCodeRange.h"/> </GROUP> <GROUP id="{6653587F-C475-46AA-E7CF-1D0DFA0FEAA9}" name="Project"> + <GROUP id="{F2E7D5CA-F002-2635-DA2C-898FA5EA2936}" name="Modules"> + <FILE id="w7QIJd" name="jucer_AvailableModulesList.h" compile="0" resource="0" + file="Source/Project/Modules/jucer_AvailableModulesList.h"/> + <FILE id="fQrJvA" name="jucer_ModuleDescription.h" compile="0" resource="0" + file="Source/Project/Modules/jucer_ModuleDescription.h"/> + <FILE id="mOC0iL" name="jucer_Modules.cpp" compile="1" resource="0" + file="Source/Project/Modules/jucer_Modules.cpp"/> + <FILE id="TnngL4" name="jucer_Modules.h" compile="0" resource="0" file="Source/Project/Modules/jucer_Modules.h"/> + </GROUP> <GROUP id="{C37B7D1A-F059-9C82-9436-A2A94552BF90}" name="UI"> <GROUP id="{19B83596-13BE-A80E-2722-BB5CCDA111FA}" name="Sidebar"> <FILE id="bItg9o" name="jucer_ExporterTreeItems.h" compile="0" resource="0" @@ -564,15 +586,14 @@ resource="0" file="Source/Project/UI/jucer_ProjectContentComponent.cpp"/> <FILE id="z576fZ" name="jucer_ProjectContentComponent.h" compile="0" resource="0" file="Source/Project/UI/jucer_ProjectContentComponent.h"/> + <FILE id="itkVli" name="jucer_ProjectMessagesComponent.h" compile="0" + resource="0" file="Source/Project/UI/jucer_ProjectMessagesComponent.h"/> + <FILE id="UUlUDF" name="jucer_UserAvatarComponent.h" compile="0" resource="0" + file="Source/Project/UI/jucer_UserAvatarComponent.h"/> </GROUP> - <FILE id="kPwhZB" name="jucer_Module.cpp" compile="1" resource="0" - file="Source/Project/jucer_Module.cpp"/> - <FILE id="YlGT8P" name="jucer_Module.h" compile="0" resource="0" file="Source/Project/jucer_Module.h"/> <FILE id="JT1rMJ" name="jucer_Project.cpp" compile="1" resource="0" file="Source/Project/jucer_Project.cpp"/> <FILE id="bUjtVS" name="jucer_Project.h" compile="0" resource="0" file="Source/Project/jucer_Project.h"/> - <FILE id="LuEXHg" name="jucer_ProjectType.h" compile="0" resource="0" - file="Source/Project/jucer_ProjectType.h"/> </GROUP> <GROUP id="{00CEE998-91CD-5001-DE85-4F4895E99A32}" name="ProjectSaving"> <FILE id="JBLk8Y" name="jucer_ProjectExport_Android.h" compile="0" @@ -627,14 +648,18 @@ file="Source/Utility/Helpers/jucer_MiscUtilities.cpp"/> <FILE id="ilDiWE" name="jucer_MiscUtilities.h" compile="0" resource="0" file="Source/Utility/Helpers/jucer_MiscUtilities.h"/> + <FILE id="BICStH" name="jucer_NewFileWizard.cpp" compile="1" resource="0" + file="Source/Utility/Helpers/jucer_NewFileWizard.cpp"/> + <FILE id="laRrOn" name="jucer_NewFileWizard.h" compile="0" resource="0" + file="Source/Utility/Helpers/jucer_NewFileWizard.h"/> <FILE id="rCaPHQ" name="jucer_PresetIDs.h" compile="0" resource="0" file="Source/Utility/Helpers/jucer_PresetIDs.h"/> - <FILE id="I1mt4g" name="jucer_RelativePath.h" compile="0" resource="0" - file="Source/Utility/Helpers/jucer_RelativePath.h"/> <FILE id="gOrmP5" name="jucer_TranslationHelpers.h" compile="0" resource="0" file="Source/Utility/Helpers/jucer_TranslationHelpers.h"/> <FILE id="EuC4K4" name="jucer_ValueSourceHelpers.h" compile="0" resource="0" file="Source/Utility/Helpers/jucer_ValueSourceHelpers.h"/> + <FILE id="W5a5Fy" name="jucer_ValueWithDefaultWrapper.h" compile="0" + resource="0" file="Source/Utility/Helpers/jucer_ValueWithDefaultWrapper.h"/> <FILE id="BPCoKV" name="jucer_VersionInfo.cpp" compile="1" resource="0" file="Source/Utility/Helpers/jucer_VersionInfo.cpp"/> <FILE id="TnBQtv" name="jucer_VersionInfo.h" compile="0" resource="0" @@ -673,51 +698,14 @@ resource="0" file="Source/Utility/UI/jucer_SlidingPanelComponent.cpp"/> <FILE id="cbUrIP" name="jucer_SlidingPanelComponent.h" compile="0" resource="0" file="Source/Utility/UI/jucer_SlidingPanelComponent.h"/> - <FILE id="xrwb6j" name="jucer_UserSettingsPopup.h" compile="0" resource="0" - file="Source/Utility/UI/jucer_UserSettingsPopup.h"/> </GROUP> </GROUP> - <GROUP id="{ECF14F8E-E605-CFBF-7BAD-2CE0A360EDAA}" name="Wizards"> - <FILE id="ICGT7i" name="jucer_NewFileWizard.cpp" compile="1" resource="0" - file="Source/Wizards/jucer_NewFileWizard.cpp"/> - <FILE id="fg6m0u" name="jucer_NewFileWizard.h" compile="0" resource="0" - file="Source/Wizards/jucer_NewFileWizard.h"/> - <FILE id="OA9jot" name="jucer_NewProjectWizard.h" compile="0" resource="0" - file="Source/Wizards/jucer_NewProjectWizard.h"/> - <FILE id="fIFyt2" name="jucer_NewProjectWizardClasses.cpp" compile="1" - resource="0" file="Source/Wizards/jucer_NewProjectWizardClasses.cpp"/> - <FILE id="xSc6Lz" name="jucer_NewProjectWizardClasses.h" compile="0" - resource="0" file="Source/Wizards/jucer_NewProjectWizardClasses.h"/> - <FILE id="k0Y8ph" name="jucer_NewProjectWizardComponent.h" compile="0" - resource="0" file="Source/Wizards/jucer_NewProjectWizardComponent.h"/> - <FILE id="YnByBt" name="jucer_ProjectWizard_Animated.h" compile="0" - resource="0" file="Source/Wizards/jucer_ProjectWizard_Animated.h"/> - <FILE id="n4Mwbm" name="jucer_ProjectWizard_AudioApp.h" compile="0" - resource="0" file="Source/Wizards/jucer_ProjectWizard_AudioApp.h"/> - <FILE id="ItaszP" name="jucer_ProjectWizard_AudioPlugin.h" compile="0" - resource="0" file="Source/Wizards/jucer_ProjectWizard_AudioPlugin.h"/> - <FILE id="t0ntRv" name="jucer_ProjectWizard_Blank.h" compile="0" resource="0" - file="Source/Wizards/jucer_ProjectWizard_Blank.h"/> - <FILE id="dm6mDO" name="jucer_ProjectWizard_Console.h" compile="0" - resource="0" file="Source/Wizards/jucer_ProjectWizard_Console.h"/> - <FILE id="FlLyrJ" name="jucer_ProjectWizard_DLL.h" compile="0" resource="0" - file="Source/Wizards/jucer_ProjectWizard_DLL.h"/> - <FILE id="mzzOny" name="jucer_ProjectWizard_GUIApp.h" compile="0" resource="0" - file="Source/Wizards/jucer_ProjectWizard_GUIApp.h"/> - <FILE id="l7EQOJ" name="jucer_ProjectWizard_openGL.h" compile="0" resource="0" - file="Source/Wizards/jucer_ProjectWizard_openGL.h"/> - <FILE id="qik3Jx" name="jucer_ProjectWizard_StaticLibrary.h" compile="0" - resource="0" file="Source/Wizards/jucer_ProjectWizard_StaticLibrary.h"/> - <FILE id="bMgfxz" name="jucer_StartPageComponent.h" compile="0" resource="0" - file="Source/Wizards/jucer_StartPageComponent.h"/> - <FILE id="aX8eVH" name="jucer_TemplateThumbnailsComponent.h" compile="0" - resource="0" file="Source/Wizards/jucer_TemplateThumbnailsComponent.h"/> - </GROUP> </MAINGROUP> <JUCEOPTIONS JUCE_LOG_ASSERTIONS="1" JUCE_USE_CURL="1" JUCE_ALLOW_STATIC_NULL_VARIABLES="0" - JUCE_STRICT_REFCOUNTEDPOINTER="1" JUCE_LOAD_CURL_SYMBOLS_LAZILY="1"/> + JUCE_STRICT_REFCOUNTEDPOINTER="1" JUCE_LOAD_CURL_SYMBOLS_LAZILY="1" + JUCE_WEB_BROWSER="0"/> <MODULES> - <MODULE id="juce_analytics" showAllCode="1" useLocalCopy="0" useGlobalPath="0"/> + <MODULE id="juce_build_tools" showAllCode="1" useLocalCopy="0" useGlobalPath="0"/> <MODULE id="juce_core" showAllCode="1"/> <MODULE id="juce_cryptography" showAllCode="1"/> <MODULE id="juce_data_structures" showAllCode="1"/> diff --git a/extras/Projucer/Source/Application/StartPage/jucer_ContentComponents.h b/extras/Projucer/Source/Application/StartPage/jucer_ContentComponents.h new file mode 100644 index 00000000..4f4fd675 --- /dev/null +++ b/extras/Projucer/Source/Application/StartPage/jucer_ContentComponents.h @@ -0,0 +1,312 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +#pragma once + +#include "../../ProjectSaving/jucer_ProjectExporter.h" +#include "../../Utility/UI/PropertyComponents/jucer_FilePathPropertyComponent.h" +#include "../../Utility/Helpers/jucer_ValueWithDefaultWrapper.h" + +#include "jucer_NewProjectWizard.h" + +//============================================================================== +class ItemHeader : public Component +{ +public: + ItemHeader (StringRef name, StringRef description, const char* iconSvgData) + : nameLabel ({}, name), + descriptionLabel ({}, description), + icon (makeIcon (iconSvgData)) + { + addAndMakeVisible (nameLabel); + nameLabel.setFont (18.0f); + nameLabel.setMinimumHorizontalScale (1.0f); + + addAndMakeVisible (descriptionLabel); + descriptionLabel.setMinimumHorizontalScale (1.0f); + } + + void resized() override + { + auto bounds = getLocalBounds(); + + auto topSlice = bounds.removeFromTop (50); + iconBounds = topSlice.removeFromRight (75); + nameLabel.setBounds (topSlice); + + bounds.removeFromTop (10); + descriptionLabel.setBounds (bounds.removeFromTop (50)); + bounds.removeFromTop (20); + } + + void paint (Graphics& g) override + { + g.fillAll (findColour (secondaryBackgroundColourId)); + + if (icon != nullptr) + icon->drawWithin (g, iconBounds.toFloat(), RectanglePlacement::centred, 1.0f); + } + +private: + static std::unique_ptr<Drawable> makeIcon (const char* iconSvgData) + { + if (auto svg = XmlDocument::parse (iconSvgData)) + return Drawable::createFromSVG (*svg); + + return {}; + } + + Label nameLabel, descriptionLabel; + + Rectangle<int> iconBounds; + std::unique_ptr<Drawable> icon; + + //============================================================================== + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ItemHeader) +}; + +//============================================================================== +class TemplateComponent : public Component +{ +public: + TemplateComponent (const NewProjectTemplates::ProjectTemplate& temp, + std::function<void (std::unique_ptr<Project>)>&& createdCallback) + : projectTemplate (temp), + projectCreatedCallback (std::move (createdCallback)), + header (projectTemplate.displayName, projectTemplate.description, projectTemplate.icon) + { + createProjectButton.onClick = [this] + { + FileChooser fc ("Save Project", NewProjectWizard::getLastWizardFolder()); + + if (fc.browseForDirectory()) + { + auto dir = fc.getResult(); + + if (auto project = NewProjectWizard::createNewProject (projectTemplate, + dir.getChildFile (projectNameValue.get().toString()), + projectNameValue.get(), + modulesValue.get(), + exportersValue.get(), + fileOptionsValue.get(), + modulePathValue.getCurrentValue(), + modulePathValue.getWrappedValueWithDefault().isUsingDefault())) + { + projectCreatedCallback (std::move (project)); + getAppSettings().lastWizardFolder = dir; + } + } + }; + + addAndMakeVisible (createProjectButton); + addAndMakeVisible (header); + + modulePathValue.init ({ settingsTree, Ids::defaultJuceModulePath, nullptr }, + getAppSettings().getStoredPath (Ids::defaultJuceModulePath, TargetOS::getThisOS()), + TargetOS::getThisOS()); + + panel.addProperties (buildPropertyList()); + addAndMakeVisible (panel); + } + + void resized() override + { + auto bounds = getLocalBounds().reduced (10); + + header.setBounds (bounds.removeFromTop (150)); + createProjectButton.setBounds (bounds.removeFromBottom (30).removeFromRight (150)); + bounds.removeFromBottom (5); + + panel.setBounds (bounds); + } + + void paint (Graphics& g) override + { + g.fillAll (findColour (secondaryBackgroundColourId)); + } + +private: + NewProjectTemplates::ProjectTemplate projectTemplate; + + std::function<void (std::unique_ptr<Project>)> projectCreatedCallback; + + ItemHeader header; + TextButton createProjectButton { "Create Project..." }; + + ValueTree settingsTree { "NewProjectSettings" }; + + ValueWithDefault projectNameValue { settingsTree, Ids::name, nullptr, "NewProject" }, + modulesValue { settingsTree, Ids::dependencies_, nullptr, projectTemplate.requiredModules, "," }, + exportersValue { settingsTree, Ids::exporters, nullptr, StringArray (ProjectExporter::getCurrentPlatformExporterTypeInfo().identifier.toString()), "," }, + fileOptionsValue { settingsTree, Ids::file, nullptr, NewProjectTemplates::getVarForFileOption (projectTemplate.defaultFileOption) }; + + ValueWithDefaultWrapper modulePathValue; + + PropertyPanel panel; + + //============================================================================== + PropertyComponent* createProjectNamePropertyComponent() + { + return new TextPropertyComponent (projectNameValue, "Project Name", 1024, false); + } + + PropertyComponent* createModulesPropertyComponent() + { + Array<var> moduleVars; + var requiredModules; + + for (auto& m : getJUCEModules()) + { + moduleVars.add (m); + + if (projectTemplate.requiredModules.contains (m)) + requiredModules.append (m); + } + + modulesValue = requiredModules; + + return new MultiChoicePropertyComponent (modulesValue, "Modules", + getJUCEModules(), moduleVars); + } + + PropertyComponent* createModulePathPropertyComponent() + { + return new FilePathPropertyComponent (modulePathValue.getWrappedValueWithDefault(), "Path to Modules", true); + } + + PropertyComponent* createExportersPropertyValue() + { + Array<var> exporterVars; + StringArray exporterNames; + + for (auto& exporterTypeInfo : ProjectExporter::getExporterTypeInfos()) + { + exporterVars.add (exporterTypeInfo.identifier.toString()); + exporterNames.add (exporterTypeInfo.displayName); + } + + return new MultiChoicePropertyComponent (exportersValue, "Exporters", exporterNames, exporterVars); + } + + PropertyComponent* createFileCreationOptionsPropertyComponent() + { + Array<var> optionVars; + StringArray optionStrings; + + for (auto& opt : projectTemplate.fileOptionsAndFiles) + { + optionVars.add (NewProjectTemplates::getVarForFileOption (opt.first)); + optionStrings.add (NewProjectTemplates::getStringForFileOption (opt.first)); + } + + return new ChoicePropertyComponent (fileOptionsValue, "File Creation Options", optionStrings, optionVars); + } + + Array<PropertyComponent*> buildPropertyList() + { + PropertyListBuilder builder; + + builder.add (createProjectNamePropertyComponent()); + builder.add (createModulesPropertyComponent()); + builder.add (createModulePathPropertyComponent()); + builder.add (createExportersPropertyValue()); + + if (! projectTemplate.fileOptionsAndFiles.empty()) + builder.add (createFileCreationOptionsPropertyComponent()); + + return builder.components; + } + + //============================================================================== + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TemplateComponent) +}; + +//============================================================================== +class ExampleComponent : public Component +{ +public: + ExampleComponent (const File& f, std::function<void (const File&)> selectedCallback) + : exampleFile (f), + metadata (parseJUCEHeaderMetadata (exampleFile)), + exampleSelectedCallback (std::move (selectedCallback)), + header (metadata[Ids::name].toString(), metadata[Ids::description].toString(), BinaryData::background_logo_svg), + codeViewer (doc, &cppTokeniser) + { + addAndMakeVisible (header); + + openExampleButton.onClick = [this] { exampleSelectedCallback (exampleFile); }; + addAndMakeVisible (openExampleButton); + + setupCodeViewer(); + addAndMakeVisible (codeViewer); + } + + void paint (Graphics& g) override + { + g.fillAll (findColour (secondaryBackgroundColourId)); + } + + void resized() override + { + auto bounds = getLocalBounds().reduced (10); + + header.setBounds (bounds.removeFromTop (125)); + openExampleButton.setBounds (bounds.removeFromBottom (30).removeFromRight (150)); + codeViewer.setBounds (bounds); + } + +private: + void setupCodeViewer() + { + auto fileString = exampleFile.loadFileAsString(); + + doc.replaceAllContent (fileString); + + codeViewer.setScrollbarThickness (6); + codeViewer.setReadOnly (true); + getAppSettings().appearance.applyToCodeEditor (codeViewer); + + codeViewer.scrollToLine (findBestLineToScrollToForClass (StringArray::fromLines (fileString), + metadata[Ids::name].toString(), + metadata[Ids::type] == "AudioProcessor")); + } + + //============================================================================== + File exampleFile; + var metadata; + + std::function<void (const File&)> exampleSelectedCallback; + + ItemHeader header; + + CPlusPlusCodeTokeniser cppTokeniser; + CodeDocument doc; + CodeEditorComponent codeViewer; + + TextButton openExampleButton { "Open Example..." }; + + //============================================================================== + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ExampleComponent) +}; diff --git a/extras/Projucer/Source/Application/StartPage/jucer_NewProjectTemplates.h b/extras/Projucer/Source/Application/StartPage/jucer_NewProjectTemplates.h new file mode 100644 index 00000000..87d695a7 --- /dev/null +++ b/extras/Projucer/Source/Application/StartPage/jucer_NewProjectTemplates.h @@ -0,0 +1,251 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +#pragma once + +#include "../../Utility/Helpers/jucer_MiscUtilities.h" + +//============================================================================== +namespace NewProjectTemplates +{ + enum class ProjectCategory + { + application, + plugin, + library + }; + + inline String getProjectCategoryString (ProjectCategory category) + { + if (category == ProjectCategory::application) return "Application"; + if (category == ProjectCategory::plugin) return "Plug-In"; + if (category == ProjectCategory::library) return "Library"; + + jassertfalse; + return "Unknown"; + } + + enum class FileCreationOptions + { + noFiles, + main, + header, + headerAndCpp, + processorAndEditor + }; + + using FilenameAndContent = std::pair<String, String>; + using OptionAndFilenameAndContent = std::pair<FileCreationOptions, std::vector<FilenameAndContent>>; + using OptionsAndFiles = std::vector<OptionAndFilenameAndContent>; + + struct ProjectTemplate + { + ProjectCategory category; + String displayName, description, projectTypeString; + + const char* icon; + StringArray requiredModules; + OptionsAndFiles fileOptionsAndFiles; + FileCreationOptions defaultFileOption; + + std::vector<FilenameAndContent> getFilesForOption (FileCreationOptions option) const + { + auto iter = std::find_if (fileOptionsAndFiles.begin(), fileOptionsAndFiles.end(), + [option] (const OptionAndFilenameAndContent& opt) { return opt.first == option; }); + + if (iter != fileOptionsAndFiles.end()) + return iter->second; + + return {}; + } + }; + + inline bool isApplication (const ProjectTemplate& t) noexcept { return t.category == ProjectCategory::application; } + inline bool isPlugin (const ProjectTemplate& t) noexcept { return t.category == ProjectCategory::plugin; } + inline bool isLibrary (const ProjectTemplate& t) noexcept { return t.category == ProjectCategory::library; } + + //============================================================================== + inline var getVarForFileOption (FileCreationOptions opt) + { + if (opt == FileCreationOptions::noFiles) return "none"; + if (opt == FileCreationOptions::main) return "main"; + if (opt == FileCreationOptions::header) return "header"; + if (opt == FileCreationOptions::headerAndCpp) return "headercpp"; + if (opt == FileCreationOptions::processorAndEditor) return "processoreditor"; + + jassertfalse; + return {}; + } + + inline FileCreationOptions getFileOptionForVar (var opt) + { + if (opt == "none") return FileCreationOptions::noFiles; + if (opt == "main") return FileCreationOptions::main; + if (opt == "header") return FileCreationOptions::header; + if (opt == "headercpp") return FileCreationOptions::headerAndCpp; + if (opt == "processoreditor") return FileCreationOptions::processorAndEditor; + + jassertfalse; + return {}; + } + + inline String getStringForFileOption (FileCreationOptions opt) + { + if (opt == FileCreationOptions::noFiles) return "No Files"; + if (opt == FileCreationOptions::main) return "Main.cpp"; + if (opt == FileCreationOptions::header) return "Main.cpp + .h"; + if (opt == FileCreationOptions::headerAndCpp) return "Main.cpp + .h/.cpp "; + if (opt == FileCreationOptions::processorAndEditor) return "Processor and Editor"; + + jassertfalse; + return {}; + } + + //============================================================================== + template <typename... Strings> + inline StringArray addAndReturn (StringArray arr, Strings... strings) + { + arr.addArray ({ strings... }); + return arr; + } + + inline std::vector<ProjectTemplate> getAllTemplates() + { + return + { + { ProjectCategory::application, + "Blank", "Creates a blank JUCE GUI application.", + build_tools::ProjectType_GUIApp::getTypeName(), + BinaryData::wizard_GUI_svg, + getModulesRequiredForComponent(), + {}, + FileCreationOptions::noFiles + }, + + { ProjectCategory::application, + "GUI", "Creates a blank JUCE GUI application with a single window component.", + build_tools::ProjectType_GUIApp::getTypeName(), + BinaryData::wizard_GUI_svg, + getModulesRequiredForComponent(), + { + { FileCreationOptions::noFiles, {} }, + { FileCreationOptions::main, { { "Main.cpp", "jucer_MainTemplate_NoWindow_cpp" } } }, + { FileCreationOptions::header, { { "Main.cpp", "jucer_MainTemplate_Window_cpp" }, + { "MainComponent.h", "jucer_ContentCompSimpleTemplate_h" } } }, + { FileCreationOptions::headerAndCpp, { { "Main.cpp", "jucer_MainTemplate_Window_cpp" }, + { "MainComponent.h", "jucer_ContentCompTemplate_h" }, + { "MainComponent.cpp", "jucer_ContentCompTemplate_cpp" } } } + }, + FileCreationOptions::headerAndCpp }, + + { ProjectCategory::application, + "Audio", "Creates a blank JUCE GUI application with a single window component and audio and MIDI in/out functions.", + build_tools::ProjectType_GUIApp::getTypeName(), + BinaryData::wizard_AudioApp_svg, + addAndReturn (getModulesRequiredForComponent(), "juce_audio_basics", "juce_audio_devices", "juce_audio_formats", + "juce_audio_processors", "juce_audio_utils", "juce_gui_extra"), + { + { FileCreationOptions::header, { { "Main.cpp", "jucer_MainTemplate_Window_cpp" }, + { "MainComponent.h", "jucer_AudioComponentSimpleTemplate_h" } } }, + { FileCreationOptions::headerAndCpp, { { "Main.cpp", "jucer_MainTemplate_Window_cpp" }, + { "MainComponent.h", "jucer_AudioComponentTemplate_h" }, + { "MainComponent.cpp", "jucer_AudioComponentTemplate_cpp" } } } + }, + FileCreationOptions::headerAndCpp }, + + { ProjectCategory::application, + "Console", "Creates a command-line application without GUI support.", + build_tools::ProjectType_ConsoleApp::getTypeName(), + BinaryData::wizard_ConsoleApp_svg, + getModulesRequiredForConsole(), + { + { FileCreationOptions::noFiles, {} }, + { FileCreationOptions::main, { { "Main.cpp", "jucer_MainConsoleAppTemplate_cpp" } } } + }, + FileCreationOptions::main }, + + { ProjectCategory::application, + "Animated", "Creates a JUCE GUI application which draws an animated graphical display.", + build_tools::ProjectType_GUIApp::getTypeName(), + BinaryData::wizard_AnimatedApp_svg, + addAndReturn (getModulesRequiredForComponent(), "juce_gui_extra"), + { + { FileCreationOptions::header, { { "Main.cpp", "jucer_MainTemplate_Window_cpp" }, + { "MainComponent.h", "jucer_AudioComponentSimpleTemplate_h" } } }, + { FileCreationOptions::headerAndCpp, { { "Main.cpp", "jucer_MainTemplate_Window_cpp" }, + { "MainComponent.h", "jucer_AnimatedComponentTemplate_h" }, + { "MainComponent.cpp", "jucer_AnimatedComponentTemplate_cpp" } } } + }, + FileCreationOptions::headerAndCpp }, + + { ProjectCategory::application, + "OpenGL", "Creates a blank JUCE application with a single window component. " + "This component supports openGL drawing features including 3D model import and GLSL shaders.", + build_tools::ProjectType_GUIApp::getTypeName(), + BinaryData::wizard_OpenGL_svg, + addAndReturn (getModulesRequiredForComponent(), "juce_gui_extra", "juce_opengl"), + { + { FileCreationOptions::header, { { "Main.cpp", "jucer_MainTemplate_Window_cpp" }, + { "MainComponent.h", "jucer_AudioComponentSimpleTemplate_h" } } }, + { FileCreationOptions::headerAndCpp, { { "Main.cpp", "jucer_MainTemplate_Window_cpp" }, + { "MainComponent.h", "jucer_OpenGLComponentTemplate_h" }, + { "MainComponent.cpp", "jucer_OpenGLComponentTemplate_cpp" } } } + }, + FileCreationOptions::headerAndCpp }, + + { ProjectCategory::plugin, + "Basic", "Creates an audio plug-in with a single window GUI and audio/MIDI IO functions.", + build_tools::ProjectType_AudioPlugin::getTypeName(), + BinaryData::wizard_AudioPlugin_svg, + getModulesRequiredForAudioProcessor(), + { + { FileCreationOptions::processorAndEditor, { { "PluginProcessor.cpp", "jucer_AudioPluginFilterTemplate_cpp" }, + { "PluginProcessor.h", "jucer_AudioPluginFilterTemplate_h" }, + { "PluginEditor.cpp", "jucer_AudioPluginEditorTemplate_cpp" }, + { "PluginEditor.h", "jucer_AudioPluginEditorTemplate_h" } } } + }, + FileCreationOptions::processorAndEditor + }, + + { ProjectCategory::library, + "Static Library", "Creates a static library.", + build_tools::ProjectType_StaticLibrary::getTypeName(), + BinaryData::wizard_StaticLibrary_svg, + getModulesRequiredForConsole(), + {}, + FileCreationOptions::noFiles + }, + + { ProjectCategory::library, + "Dynamic Library", "Creates a dynamic library.", + build_tools::ProjectType_DLL::getTypeName(), + BinaryData::wizard_DLL_svg, + getModulesRequiredForConsole(), + {}, + FileCreationOptions::noFiles + } + }; + } +} diff --git a/extras/Projucer/Source/Application/StartPage/jucer_NewProjectWizard.cpp b/extras/Projucer/Source/Application/StartPage/jucer_NewProjectWizard.cpp new file mode 100644 index 00000000..e6119667 --- /dev/null +++ b/extras/Projucer/Source/Application/StartPage/jucer_NewProjectWizard.cpp @@ -0,0 +1,282 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +#include "../jucer_Headers.h" +#include "../jucer_Application.h" +#include "../../ProjectSaving/jucer_ProjectExporter.h" + +#include "jucer_NewProjectWizard.h" + +//============================================================================== +static String getFileTemplate (const String& templateName) +{ + int dataSize = 0; + + if (auto* data = BinaryData::getNamedResource (templateName.toUTF8(), dataSize)) + return String::fromUTF8 (data, dataSize); + + jassertfalse; + return {}; +} + +static String getJuceHeaderInclude() +{ + return CodeHelpers::createIncludePathIncludeStatement (Project::getJuceSourceHFilename()); +} + +static String getContentComponentName() +{ + return "MainComponent"; +} + +using Opts = NewProjectTemplates::FileCreationOptions; + +static bool shouldCreateHeaderFile (Opts opts) noexcept { return opts == Opts::header || opts == Opts::headerAndCpp; } +static bool shouldCreateCppFile (Opts opts) noexcept { return opts == Opts::headerAndCpp; } + +static void doBasicProjectSetup (Project& project, const NewProjectTemplates::ProjectTemplate& projectTemplate, const String& name) +{ + project.setTitle (name); + project.setProjectType (projectTemplate.projectTypeString); + project.getMainGroup().addNewSubGroup ("Source", 0); + + project.getConfigFlag ("JUCE_STRICT_REFCOUNTEDPOINTER") = true; + project.getProjectValue (Ids::useAppConfig) = false; + project.getProjectValue (Ids::addUsingNamespaceToJuceHeader) = false; + + if (! ProjucerApplication::getApp().getLicenseController().getCurrentState().canUnlockFullFeatures()) + project.getProjectValue (Ids::displaySplashScreen) = true; + + if (NewProjectTemplates::isPlugin (projectTemplate)) + project.getConfigFlag ("JUCE_VST3_CAN_REPLACE_VST2") = 0; +} + +static std::map<String, String> getSharedFileTokenReplacements() +{ + return { { "%%app_headers%%", getJuceHeaderInclude() } }; +} + +static std::map<String, String> getApplicationFileTokenReplacements (const String& name, + NewProjectTemplates::FileCreationOptions fileOptions, + const File& sourceFolder) +{ + auto tokenReplacements = getSharedFileTokenReplacements(); + + tokenReplacements.insert ({ "%%app_class_name%%", + build_tools::makeValidIdentifier (name + "Application", false, true, false) }); + tokenReplacements.insert ({ "%%content_component_class%%", + getContentComponentName() }); + tokenReplacements.insert ({ "%%include_juce%%", + getJuceHeaderInclude() }); + + if (shouldCreateHeaderFile (fileOptions)) + tokenReplacements["%%app_headers%%"] << newLine + << CodeHelpers::createIncludeStatement (sourceFolder.getChildFile ("MainComponent.h"), + sourceFolder.getChildFile ("Main.cpp")); + + if (shouldCreateCppFile (fileOptions)) + tokenReplacements.insert ({ "%%include_corresponding_header%%", + CodeHelpers::createIncludeStatement (sourceFolder.getChildFile ("MainComponent.h"), + sourceFolder.getChildFile ("MainComponent.cpp")) }); + + return tokenReplacements; +} + +static std::map<String, String> getPluginFileTokenReplacements (const String& name, + const File& sourceFolder) +{ + auto tokenReplacements = getSharedFileTokenReplacements(); + + auto processorCppFile = sourceFolder.getChildFile ("PluginProcessor.cpp"); + auto processorHFile = processorCppFile.withFileExtension (".h"); + auto editorCppFile = sourceFolder.getChildFile ("PluginEditor.cpp"); + auto editorHFile = editorCppFile.withFileExtension (".h"); + + auto processorHInclude = CodeHelpers::createIncludeStatement (processorHFile, processorCppFile); + auto editorHInclude = CodeHelpers::createIncludeStatement (editorHFile, processorCppFile); + + auto processorClassName = build_tools::makeValidIdentifier (name, false, true, false) + "AudioProcessor"; + processorClassName = processorClassName.substring (0, 1).toUpperCase() + processorClassName.substring (1); + auto editorClassName = processorClassName + "Editor"; + + tokenReplacements.insert ({"%%filter_headers%%", processorHInclude + newLine + editorHInclude }); + tokenReplacements.insert ({"%%filter_class_name%%", processorClassName }); + tokenReplacements.insert ({"%%editor_class_name%%", editorClassName }); + tokenReplacements.insert ({"%%editor_cpp_headers%%", processorHInclude + newLine + editorHInclude }); + tokenReplacements.insert ({"%%editor_headers%%", getJuceHeaderInclude() + newLine + processorHInclude }); + + return tokenReplacements; +} + +static bool addFiles (Project& project, const NewProjectTemplates::ProjectTemplate& projectTemplate, + const String& name, var fileOptionsVar, StringArray& failedFiles) +{ + auto sourceFolder = project.getFile().getSiblingFile ("Source"); + + if (! sourceFolder.createDirectory()) + { + failedFiles.add (sourceFolder.getFullPathName()); + return false; + } + + auto fileOptions = NewProjectTemplates::getFileOptionForVar (fileOptionsVar); + + if (fileOptions == Opts::noFiles) + return true; + + auto tokenReplacements = [&]() -> std::map<String, String> + { + if (NewProjectTemplates::isApplication (projectTemplate)) + return getApplicationFileTokenReplacements (name, fileOptions, sourceFolder); + + if (NewProjectTemplates::isPlugin (projectTemplate)) + return getPluginFileTokenReplacements (name, sourceFolder); + + jassertfalse; + return {}; + }(); + + auto sourceGroup = project.getMainGroup().getOrCreateSubGroup ("Source"); + + for (auto& files : projectTemplate.getFilesForOption (fileOptions)) + { + auto file = sourceFolder.getChildFile (files.first); + auto fileContent = getFileTemplate (files.second); + + for (auto& tokenReplacement : tokenReplacements) + fileContent = fileContent.replace (tokenReplacement.first, tokenReplacement.second, false); + + if (! build_tools::overwriteFileWithNewDataIfDifferent (file, fileContent)) + { + failedFiles.add (file.getFullPathName()); + return false; + } + + sourceGroup.addFileAtIndex (file, -1, (file.hasFileExtension (sourceFileExtensions))); + } + + return true; +} + +static void addModules (Project& project, Array<var> modules, const String& modulePath, bool useGlobalPath) +{ + AvailableModulesList list; + list.scanPaths ({ modulePath }); + + auto& projectModules = project.getEnabledModules(); + + for (auto& mod : list.getAllModules()) + if (modules.contains (mod.first)) + projectModules.addModule (mod.second, false, useGlobalPath); + + for (auto& mod : projectModules.getModulesWithMissingDependencies()) + projectModules.tryToFixMissingDependencies (mod); +} + +static void addExporters (Project& project, Array<var> exporters) +{ + for (auto exporter : exporters) + project.addNewExporter (exporter.toString()); + + for (Project::ExporterIterator exporter (project); exporter.next();) + for (ProjectExporter::ConfigIterator config (*exporter); config.next();) + config->getValue (Ids::targetName) = project.getProjectFilenameRootString(); +} + +//============================================================================== +File NewProjectWizard::getLastWizardFolder() +{ + if (getAppSettings().lastWizardFolder.isDirectory()) + return getAppSettings().lastWizardFolder; + + #if JUCE_WINDOWS + static File lastFolderFallback (File::getSpecialLocation (File::userDocumentsDirectory)); + #else + static File lastFolderFallback (File::getSpecialLocation (File::userHomeDirectory)); + #endif + + return lastFolderFallback; +} + +std::unique_ptr<Project> NewProjectWizard::createNewProject (const NewProjectTemplates::ProjectTemplate& projectTemplate, + const File& targetFolder, const String& name, var modules, var exporters, var fileOptions, + const String& modulePath, bool useGlobalModulePath) +{ + StringArray failedFiles; + + if (! targetFolder.exists()) + { + if (! targetFolder.createDirectory()) + failedFiles.add (targetFolder.getFullPathName()); + } + else if (FileHelpers::containsAnyNonHiddenFiles (targetFolder)) + { + if (! AlertWindow::showOkCancelBox (AlertWindow::InfoIcon, + TRANS("New JUCE Project"), + TRANS("You chose the folder:\n\nXFLDRX\n\n").replace ("XFLDRX", targetFolder.getFullPathName()) + + TRANS("This folder isn't empty - are you sure you want to create the project there?") + + "\n\n" + + TRANS("Any existing files with the same names may be overwritten by the new files."))) + { + return nullptr; + } + } + + auto project = std::make_unique<Project> (targetFolder.getChildFile (File::createLegalFileName (name)) + .withFileExtension (Project::projectFileExtension)); + + if (failedFiles.isEmpty()) + { + doBasicProjectSetup (*project, projectTemplate, name); + + if (addFiles (*project, projectTemplate, name, fileOptions, failedFiles)) + { + addExporters (*project, *exporters.getArray()); + addModules (*project, *modules.getArray(), modulePath, useGlobalModulePath); + + if (project->save (false, true) == FileBasedDocument::savedOk) + { + project->setChangedFlag (false); + project->loadFrom (project->getFile(), true); + } + else + { + failedFiles.add (project->getFile().getFullPathName()); + } + } + } + + if (! failedFiles.isEmpty()) + { + AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon, + TRANS("Errors in Creating Project!"), + TRANS("The following files couldn't be written:") + + "\n\n" + + failedFiles.joinIntoString ("\n", 0, 10)); + return nullptr; + } + + return project; +} diff --git a/extras/Projucer/Source/Application/StartPage/jucer_NewProjectWizard.h b/extras/Projucer/Source/Application/StartPage/jucer_NewProjectWizard.h new file mode 100644 index 00000000..1fe23290 --- /dev/null +++ b/extras/Projucer/Source/Application/StartPage/jucer_NewProjectWizard.h @@ -0,0 +1,38 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +#pragma once + +#include "jucer_NewProjectTemplates.h" + +//============================================================================== +namespace NewProjectWizard +{ + File getLastWizardFolder(); + + std::unique_ptr<Project> createNewProject (const NewProjectTemplates::ProjectTemplate& projectTemplate, + const File& targetFolder, const String& name, var modules, var exporters, var fileOptions, + const String& modulePath, bool useGlobalModulePath); +} diff --git a/extras/Projucer/Source/Application/StartPage/jucer_StartPageComponent.cpp b/extras/Projucer/Source/Application/StartPage/jucer_StartPageComponent.cpp new file mode 100644 index 00000000..2d0a34c5 --- /dev/null +++ b/extras/Projucer/Source/Application/StartPage/jucer_StartPageComponent.cpp @@ -0,0 +1,272 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +#include "../jucer_Headers.h" +#include "../jucer_Application.h" + +#include "jucer_StartPageComponent.h" +#include "jucer_StartPageTreeHolder.h" +#include "jucer_NewProjectTemplates.h" +#include "jucer_ContentComponents.h" + +//============================================================================== +struct ContentComponent : public Component +{ + void resized() override + { + if (content != nullptr) + content->setBounds (getLocalBounds()); + } + + void setContent (std::unique_ptr<Component>&& newContent) + { + if (content.get() != newContent.get()) + { + content = std::move (newContent); + addAndMakeVisible (content.get()); + resized(); + } + } + +private: + std::unique_ptr<Component> content; + + //============================================================================== + JUCE_LEAK_DETECTOR (ContentComponent) +}; + +//============================================================================== +static File findExampleFile (int dirIndex, int index) +{ + auto dir = ProjucerApplication::getSortedExampleDirectories()[dirIndex]; + return ProjucerApplication::getSortedExampleFilesInDirectory (dir)[index]; +} + +static std::unique_ptr<Component> createExampleProjectsTab (ContentComponent& content, std::function<void (const File&)> cb) +{ + StringArray exampleCategories; + std::vector<StringArray> examples; + + for (auto& dir : ProjucerApplication::getSortedExampleDirectories()) + { + exampleCategories.add (dir.getFileName()); + + StringArray ex; + for (auto& f : ProjucerApplication::getSortedExampleFilesInDirectory (dir)) + ex.add (f.getFileNameWithoutExtension()); + + examples.push_back (ex); + } + + if (exampleCategories.isEmpty()) + return nullptr; + + auto selectedCallback = [&, cb] (int category, int index) mutable + { + content.setContent (std::make_unique<ExampleComponent> (findExampleFile (category, index), cb)); + }; + + return std::make_unique<StartPageTreeHolder> (exampleCategories, + examples, + std::move (selectedCallback), + StartPageTreeHolder::Open::no); +} + +//============================================================================== +static StringArray getAllTemplateCategoryStrings() +{ + StringArray categories; + + for (auto& t : NewProjectTemplates::getAllTemplates()) + categories.addIfNotAlreadyThere (NewProjectTemplates::getProjectCategoryString (t.category)); + + return categories; +} + +static std::vector<NewProjectTemplates::ProjectTemplate> getTemplatesInCategory (const String& category) +{ + std::vector<NewProjectTemplates::ProjectTemplate> templates; + + for (auto& t : NewProjectTemplates::getAllTemplates()) + if (NewProjectTemplates::getProjectCategoryString (t.category) == category) + templates.push_back (t); + + return templates; +} + +static StringArray getAllTemplateNamesForCategory (const String& category) +{ + StringArray types; + + for (auto& t : getTemplatesInCategory (category)) + types.add (t.displayName); + + return types; +} + +static std::unique_ptr<Component> createProjectTemplatesTab (ContentComponent& content, + std::function<void (std::unique_ptr<Project>&&)>&& cb) +{ + auto categories = getAllTemplateCategoryStrings(); + + std::vector<StringArray> templateNames; + + for (auto& c : categories) + templateNames.push_back (getAllTemplateNamesForCategory (c)); + + auto selectedCallback = [&, cb] (int category, int index) + { + auto categoryString = getAllTemplateCategoryStrings()[category]; + auto templates = getTemplatesInCategory (categoryString); + + content.setContent (std::make_unique<TemplateComponent> (templates[(size_t) index], std::move (cb))); + }; + + auto holder = std::make_unique<StartPageTreeHolder> (categories, + templateNames, + std::move (selectedCallback), + StartPageTreeHolder::Open::yes); + holder->setSelectedItem (categories[0], 1); + + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wredundant-move") + return std::move (holder); + JUCE_END_IGNORE_WARNINGS_GCC_LIKE +} + +//============================================================================== +struct ProjectTemplatesAndExamples : public TabbedComponent +{ + ProjectTemplatesAndExamples (ContentComponent& c, + std::function<void (std::unique_ptr<Project>&&)>&& newProjectCb, + std::function<void (const File&)>&& exampleCb) + : TabbedComponent (TabbedButtonBar::Orientation::TabsAtTop), + content (c), + exampleSelectedCallback (std::move (exampleCb)) + { + addTab ("New Project", Colours::transparentBlack, createProjectTemplatesTab (content, std::move (newProjectCb)).release(), true); + refreshExamplesTab(); + } + + void refreshExamplesTab() + { + auto wasOpen = (getCurrentTabIndex() == 1); + + removeTab (1); + + auto exampleTabs = createExampleProjectsTab (content, exampleSelectedCallback); + + addTab ("Open Example", Colours::transparentBlack, exampleTabs == nullptr ? new SetJUCEPathComponent (*this) + : exampleTabs.release(), + true); + + if (wasOpen) + setCurrentTabIndex (1); + } + +private: + //============================================================================== + struct SetJUCEPathComponent : public Component, + private ChangeListener + { + explicit SetJUCEPathComponent (ProjectTemplatesAndExamples& o) + : owner (o) + { + getGlobalProperties().addChangeListener (this); + + setPathButton.setButtonText ("Set path to JUCE..."); + setPathButton.onClick = [] { ProjucerApplication::getApp().showPathsWindow (true); }; + + addAndMakeVisible (setPathButton); + } + + ~SetJUCEPathComponent() override + { + getGlobalProperties().removeChangeListener (this); + } + + void paint (Graphics& g) override + { + g.fillAll (findColour (secondaryBackgroundColourId)); + } + + void resized() override + { + auto bounds = getLocalBounds().reduced (5); + bounds.removeFromTop (25); + + setPathButton.setBounds (bounds.removeFromTop (25)); + } + + private: + void changeListenerCallback (ChangeBroadcaster*) override + { + if (isValidJUCEExamplesDirectory (ProjucerApplication::getJUCEExamplesDirectoryPathFromGlobal())) + owner.refreshExamplesTab(); + } + + ProjectTemplatesAndExamples& owner; + TextButton setPathButton; + }; + + ContentComponent& content; + std::function<void (const File&)> exampleSelectedCallback; +}; + +//============================================================================== +StartPageComponent::StartPageComponent (std::function<void (std::unique_ptr<Project>&&)>&& newProjectCb, + std::function<void (const File&)>&& exampleCb) + : content (std::make_unique<ContentComponent>()), + tabs (std::make_unique<ProjectTemplatesAndExamples> (*content, std::move (newProjectCb), std::move (exampleCb))) +{ + tabs->setOutline (0); + addAndMakeVisible (*tabs); + + addAndMakeVisible (openExistingButton); + openExistingButton.setCommandToTrigger (&ProjucerApplication::getCommandManager(), CommandIDs::open, true); + + addAndMakeVisible (*content); + + setSize (900, 600); +} + +void StartPageComponent::paint (Graphics& g) +{ + g.fillAll (findColour (backgroundColourId)); +} + +void StartPageComponent::resized() +{ + auto bounds = getLocalBounds().reduced (10); + + auto tabBounds = bounds.removeFromLeft (bounds.getWidth() / 3); + + openExistingButton.setBounds (tabBounds.removeFromBottom (30).reduced (10, 0)); + tabBounds.removeFromBottom (5); + + tabs->setBounds (tabBounds); + bounds.removeFromLeft (10); + + content->setBounds (bounds); +} diff --git a/extras/Projucer/Source/Application/StartPage/jucer_StartPageComponent.h b/extras/Projucer/Source/Application/StartPage/jucer_StartPageComponent.h new file mode 100644 index 00000000..44bfa19a --- /dev/null +++ b/extras/Projucer/Source/Application/StartPage/jucer_StartPageComponent.h @@ -0,0 +1,50 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +#pragma once + +struct ContentComponent; +struct ProjectTemplatesAndExamples; + +//============================================================================== +class StartPageComponent : public Component +{ +public: + StartPageComponent (std::function<void (std::unique_ptr<Project>&&)>&& newProjectCb, + std::function<void (const File&)>&& exampleCb); + + void paint (Graphics& g) override; + void resized() override; + +private: + //============================================================================== + std::unique_ptr<ContentComponent> content; + std::unique_ptr<ProjectTemplatesAndExamples> tabs; + + TextButton openExistingButton { "Open Existing Project..." }; + + //============================================================================== + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (StartPageComponent) +}; diff --git a/extras/Projucer/Source/Application/StartPage/jucer_StartPageTreeHolder.h b/extras/Projucer/Source/Application/StartPage/jucer_StartPageTreeHolder.h new file mode 100644 index 00000000..5228a566 --- /dev/null +++ b/extras/Projucer/Source/Application/StartPage/jucer_StartPageTreeHolder.h @@ -0,0 +1,174 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +#pragma once + +//============================================================================== +class StartPageTreeHolder : public Component +{ +public: + enum class Open { no, yes }; + + StartPageTreeHolder (const StringArray& headerNames, const std::vector<StringArray>& itemNames, + std::function<void (int, int)>&& selectedCallback, Open shouldBeOpen) + : headers (headerNames), + items (itemNames), + itemSelectedCallback (std::move (selectedCallback)) + { + jassert (headers.size() == (int) items.size()); + + tree.setRootItem (new TreeRootItem (*this)); + tree.setRootItemVisible (false); + tree.setIndentSize (15); + tree.setDefaultOpenness (shouldBeOpen == Open::yes); + + addAndMakeVisible (tree); + } + + ~StartPageTreeHolder() override + { + tree.deleteRootItem(); + } + + void paint (Graphics& g) override + { + g.fillAll (findColour (secondaryBackgroundColourId)); + } + + void resized() override + { + tree.setBounds (getLocalBounds()); + } + + void setSelectedItem (const String& category, int index) + { + auto* root = tree.getRootItem(); + + for (int i = root->getNumSubItems(); --i >=0;) + { + if (auto* item = root->getSubItem (i)) + { + if (item->getUniqueName() == category) + item->getSubItem (index)->setSelected (true, true); + } + } + } + +private: + //============================================================================== + class TreeSubItem : public TreeViewItem + { + public: + TreeSubItem (StartPageTreeHolder& o, const String& n, const StringArray& subItems) + : owner (o), name (n), isHeader (subItems.size() > 0) + { + for (auto& s : subItems) + addSubItem (new TreeSubItem (owner, s, {})); + } + + bool mightContainSubItems() override { return isHeader; } + bool canBeSelected() const override { return ! isHeader; } + + int getItemWidth() const override { return -1; } + int getItemHeight() const override { return 25; } + + String getUniqueName() const override { return name; } + + void paintOpenCloseButton (Graphics& g, const Rectangle<float>& area, Colour, bool isMouseOver) override + { + g.setColour (getOwnerView()->findColour (isSelected() ? defaultHighlightedTextColourId + : treeIconColourId)); + + TreeViewItem::paintOpenCloseButton (g, area, getOwnerView()->findColour (defaultIconColourId), isMouseOver); + } + + void paintItem (Graphics& g, int w, int h) override + { + Rectangle<int> bounds (w, h); + + auto shouldBeHighlighted = isSelected(); + + if (shouldBeHighlighted) + { + g.setColour (getOwnerView()->findColour (defaultHighlightColourId)); + g.fillRect (bounds); + } + + g.setColour (shouldBeHighlighted ? getOwnerView()->findColour (defaultHighlightedTextColourId) + : getOwnerView()->findColour (defaultTextColourId)); + + g.drawFittedText (name, bounds.reduced (5).withTrimmedLeft (10), Justification::centredLeft, 1); + } + + void itemClicked (const MouseEvent&) override + { + if (isSelected()) + itemSelectionChanged (true); + } + + void itemSelectionChanged (bool isNowSelected) override + { + jassert (! isHeader); + + if (isNowSelected) + owner.itemSelectedCallback (getParentItem()->getIndexInParent(), getIndexInParent()); + } + + private: + StartPageTreeHolder& owner; + String name; + bool isHeader = false; + + //============================================================================== + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TreeSubItem) + }; + + struct TreeRootItem : public TreeViewItem + { + explicit TreeRootItem (StartPageTreeHolder& o) + : owner (o) + { + for (int i = 0; i < owner.headers.size(); ++i) + addSubItem (new TreeSubItem (owner, owner.headers[i], owner.items[(size_t) i])); + } + + bool mightContainSubItems() override { return ! owner.headers.isEmpty();} + + StartPageTreeHolder& owner; + + //============================================================================== + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TreeRootItem) + }; + + //============================================================================== + TreeView tree; + StringArray headers; + std::vector<StringArray> items; + + std::function<void (int, int)> itemSelectedCallback; + + //============================================================================== + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (StartPageTreeHolder) +}; diff --git a/extras/Projucer/Source/Application/UserAccount/jucer_LicenseController.h b/extras/Projucer/Source/Application/UserAccount/jucer_LicenseController.h new file mode 100644 index 00000000..a39aed03 --- /dev/null +++ b/extras/Projucer/Source/Application/UserAccount/jucer_LicenseController.h @@ -0,0 +1,224 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +#pragma once + +#include "jucer_LicenseState.h" +#include "jucer_LicenseQueryThread.h" + +//============================================================================== +class LicenseController : private Timer +{ +public: + LicenseController() + { + checkLicense(); + } + + //============================================================================== + static LicenseState getGPLState() + { + return { LicenseState::Type::gpl, projucerMajorVersion, {}, {} }; + } + + LicenseState getCurrentState() const noexcept + { + return state; + } + + void setState (const LicenseState& newState) + { + if (state != newState) + { + state = newState; + licenseStateToSettings (state, getGlobalProperties()); + + stateListeners.call ([] (LicenseStateListener& l) { l.licenseStateChanged(); }); + } + } + + void resetState() + { + setState ({}); + } + + void signIn (const String& email, const String& password, + std::function<void (const String&)> completionCallback) + { + licenseQueryThread.doSignIn (email, password, + [this, completionCallback] (LicenseQueryThread::ErrorMessageAndType error, + LicenseState newState) + { + completionCallback (error.first); + setState (newState); + }); + } + + void cancelSignIn() + { + licenseQueryThread.cancelRunningJobs(); + } + + //============================================================================== + struct LicenseStateListener + { + virtual ~LicenseStateListener() = default; + virtual void licenseStateChanged() = 0; + }; + + void addListener (LicenseStateListener* listenerToAdd) + { + stateListeners.add (listenerToAdd); + } + + void removeListener (LicenseStateListener* listenerToRemove) + { + stateListeners.remove (listenerToRemove); + } + +private: + //============================================================================== + static const char* getLicenseStateValue (LicenseState::Type type) + { + switch (type) + { + case LicenseState::Type::gpl: return "GPL"; + case LicenseState::Type::personal: return "personal"; + case LicenseState::Type::educational: return "edu"; + case LicenseState::Type::indie: return "indie"; + case LicenseState::Type::pro: return "pro"; + case LicenseState::Type::none: + default: break; + } + + return nullptr; + } + + static LicenseState::Type getLicenseTypeFromValue (const String& d) + { + if (d == getLicenseStateValue (LicenseState::Type::gpl)) return LicenseState::Type::gpl; + if (d == getLicenseStateValue (LicenseState::Type::personal)) return LicenseState::Type::personal; + if (d == getLicenseStateValue (LicenseState::Type::educational)) return LicenseState::Type::educational; + if (d == getLicenseStateValue (LicenseState::Type::indie)) return LicenseState::Type::indie; + if (d == getLicenseStateValue (LicenseState::Type::pro)) return LicenseState::Type::pro; + return LicenseState::Type::none; + } + + static LicenseState licenseStateFromSettings (PropertiesFile& props) + { + if (auto licenseXml = props.getXmlValue ("license")) + { + // this is here for backwards compatibility with old-style settings files using XML text elements + if (licenseXml->getChildElementAllSubText ("type", {}).isNotEmpty()) + { + auto stateFromOldSettings = [&licenseXml]() -> LicenseState + { + return { getLicenseTypeFromValue (licenseXml->getChildElementAllSubText ("type", {})), + licenseXml->getChildElementAllSubText ("version", "-1").getIntValue(), + licenseXml->getChildElementAllSubText ("username", {}), + licenseXml->getChildElementAllSubText ("authToken", {}) }; + }(); + + licenseStateToSettings (stateFromOldSettings, props); + + return stateFromOldSettings; + } + + return { getLicenseTypeFromValue (licenseXml->getStringAttribute ("type", {})), + licenseXml->getIntAttribute ("version", -1), + licenseXml->getStringAttribute ("username", {}), + licenseXml->getStringAttribute ("authToken", {}) }; + } + + return {}; + } + + static void licenseStateToSettings (const LicenseState& state, PropertiesFile& props) + { + props.removeValue ("license"); + + if (state.isSignedIn()) + { + XmlElement licenseXml ("license"); + + if (auto* typeString = getLicenseStateValue (state.type)) + licenseXml.setAttribute ("type", typeString); + + licenseXml.setAttribute ("version", state.version); + licenseXml.setAttribute ("username", state.username); + licenseXml.setAttribute ("authToken", state.authToken); + + props.setValue ("license", &licenseXml); + } + + props.saveIfNeeded(); + } + + //============================================================================== + void checkLicense() + { + if (state.isSignedIn() && ! state.isGPL()) + { + auto completionCallback = [this] (LicenseQueryThread::ErrorMessageAndType error, + LicenseState updatedState) + { + if (error == LicenseQueryThread::ErrorMessageAndType()) + { + setState (updatedState); + } + else if ((error.second == LicenseQueryThread::ErrorType::busy + || error.second == LicenseQueryThread::ErrorType::cancelled + || error.second == LicenseQueryThread::ErrorType::connectionError) + && ! hasRetriedLicenseCheck) + { + hasRetriedLicenseCheck = true; + startTimer (10000); + } + }; + + licenseQueryThread.checkLicenseValidity (state, std::move (completionCallback)); + } + } + + void timerCallback() override + { + stopTimer(); + checkLicense(); + } + + //============================================================================== + #if JUCER_ENABLE_GPL_MODE + LicenseState state = getGPLState(); + #else + LicenseState state = licenseStateFromSettings (getGlobalProperties()); + #endif + + ListenerList<LicenseStateListener> stateListeners; + LicenseQueryThread licenseQueryThread; + bool hasRetriedLicenseCheck = false; + + //============================================================================== + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LicenseController) +}; diff --git a/extras/Projucer/Source/Application/UserAccount/jucer_LicenseQueryThread.h b/extras/Projucer/Source/Application/UserAccount/jucer_LicenseQueryThread.h new file mode 100644 index 00000000..8b3eed64 --- /dev/null +++ b/extras/Projucer/Source/Application/UserAccount/jucer_LicenseQueryThread.h @@ -0,0 +1,369 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +#pragma once + +//============================================================================== +namespace LicenseHelpers +{ + inline LicenseState::Type licenseTypeForString (const String& licenseString) + { + if (licenseString == "juce-pro") return LicenseState::Type::pro; + if (licenseString == "juce-indie") return LicenseState::Type::indie; + if (licenseString == "juce-edu") return LicenseState::Type::educational; + if (licenseString == "juce-personal") return LicenseState::Type::personal; + + jassertfalse; // unknown type + return LicenseState::Type::none; + } + + using LicenseVersionAndType = std::pair<int, LicenseState::Type>; + + inline LicenseVersionAndType findBestLicense (std::vector<LicenseVersionAndType>&& licenses) + { + if (licenses.size() == 1) + return licenses[0]; + + auto getValueForLicenceType = [] (LicenseState::Type type) + { + switch (type) + { + case LicenseState::Type::pro: return 4; + case LicenseState::Type::indie: return 3; + case LicenseState::Type::educational: return 2; + case LicenseState::Type::personal: return 1; + case LicenseState::Type::gpl: + case LicenseState::Type::none: + default: return -1; + } + }; + + std::sort (licenses.begin(), licenses.end(), + [getValueForLicenceType] (const LicenseVersionAndType& l1, const LicenseVersionAndType& l2) + { + if (l1.first > l2.first) + return true; + + if (l1.first == l2.first) + return getValueForLicenceType (l1.second) > getValueForLicenceType (l2.second); + + return false; + }); + + auto findFirstLicense = [&licenses] (bool isPaid) + { + auto iter = std::find_if (licenses.begin(), licenses.end(), + [isPaid] (const LicenseVersionAndType& l) + { + auto proOrIndie = (l.second == LicenseState::Type::pro || l.second == LicenseState::Type::indie); + return isPaid ? proOrIndie : ! proOrIndie; + }); + + return iter != licenses.end() ? *iter + : LicenseVersionAndType(); + }; + + auto newestPaid = findFirstLicense (true); + auto newestFree = findFirstLicense (false); + + if (newestPaid.first >= projucerMajorVersion || newestPaid.first >= newestFree.first) + return newestPaid; + + return newestFree; + } +} + +//============================================================================== +class LicenseQueryThread +{ +public: + enum class ErrorType + { + busy, + cancelled, + connectionError, + webResponseError + }; + + using ErrorMessageAndType = std::pair<String, ErrorType>; + using LicenseQueryCallback = std::function<void (ErrorMessageAndType, LicenseState)>; + + //============================================================================== + LicenseQueryThread() = default; + + void checkLicenseValidity (const LicenseState& state, LicenseQueryCallback completionCallback) + { + if (jobPool.getNumJobs() > 0) + { + completionCallback ({ {}, ErrorType::busy }, {}); + return; + } + + jobPool.addJob ([this, state, completionCallback] + { + auto updatedState = state; + + auto result = runTask (std::make_unique<UserLicenseQuery> (state.authToken), updatedState); + + WeakReference<LicenseQueryThread> weakThis (this); + MessageManager::callAsync ([weakThis, result, updatedState, completionCallback] + { + if (weakThis != nullptr) + completionCallback (result, updatedState); + }); + }); + } + + void doSignIn (const String& email, const String& password, LicenseQueryCallback completionCallback) + { + cancelRunningJobs(); + + jobPool.addJob ([this, email, password, completionCallback] + { + LicenseState state; + + auto result = runTask (std::make_unique<UserLogin> (email, password), state); + + if (result == ErrorMessageAndType()) + result = runTask (std::make_unique<UserLicenseQuery> (state.authToken), state); + + if (result != ErrorMessageAndType()) + state = {}; + + WeakReference<LicenseQueryThread> weakThis (this); + MessageManager::callAsync ([weakThis, result, state, completionCallback] + { + if (weakThis != nullptr) + completionCallback (result, state); + }); + }); + } + + void cancelRunningJobs() + { + jobPool.removeAllJobs (true, 500); + } + +private: + //============================================================================== + struct AccountEnquiryBase + { + virtual ~AccountEnquiryBase() = default; + + virtual bool isPOSTLikeRequest() const = 0; + virtual String getEndpointURLSuffix() const = 0; + virtual StringPairArray getParameterNamesAndValues() const = 0; + virtual String getExtraHeaders() const = 0; + virtual int getSuccessCode() const = 0; + virtual String errorCodeToString (int) const = 0; + virtual bool parseServerResponse (const String&, LicenseState&) = 0; + }; + + struct UserLogin : public AccountEnquiryBase + { + UserLogin (const String& e, const String& p) + : userEmail (e), userPassword (p) + { + } + + bool isPOSTLikeRequest() const override { return true; } + String getEndpointURLSuffix() const override { return "/authenticate/projucer"; } + int getSuccessCode() const override { return 200; } + + StringPairArray getParameterNamesAndValues() const override + { + StringPairArray namesAndValues; + namesAndValues.set ("email", userEmail); + namesAndValues.set ("password", userPassword); + + return namesAndValues; + } + + String getExtraHeaders() const override + { + return "Content-Type: application/json"; + } + + String errorCodeToString (int errorCode) const override + { + switch (errorCode) + { + case 400: return "Please enter your email and password to sign in."; + case 401: return "Your email and password are incorrect."; + case 451: return "Access denied."; + default: return "Something went wrong, please try again."; + } + } + + bool parseServerResponse (const String& serverResponse, LicenseState& licenseState) override + { + auto json = JSON::parse (serverResponse); + + licenseState.authToken = json.getProperty ("token", {}).toString(); + licenseState.username = json.getProperty ("user", {}).getProperty ("username", {}).toString(); + + return (licenseState.authToken.isNotEmpty() && licenseState.username.isNotEmpty()); + } + + String userEmail, userPassword; + }; + + struct UserLicenseQuery : public AccountEnquiryBase + { + UserLicenseQuery (const String& authToken) + : userAuthToken (authToken) + { + } + + bool isPOSTLikeRequest() const override { return false; } + String getEndpointURLSuffix() const override { return "/user/licences/projucer"; } + int getSuccessCode() const override { return 200; } + + StringPairArray getParameterNamesAndValues() const override + { + return {}; + } + + String getExtraHeaders() const override + { + return "x-access-token: " + userAuthToken; + } + + String errorCodeToString (int errorCode) const override + { + switch (errorCode) + { + case 401: return "User not found or could not be verified."; + default: return "User licenses info fetch failed (unknown error)."; + } + } + + bool parseServerResponse (const String& serverResponse, LicenseState& licenseState) override + { + auto json = JSON::parse (serverResponse); + + if (auto* licensesJson = json.getArray()) + { + std::vector<LicenseHelpers::LicenseVersionAndType> licenses; + + for (auto& license : *licensesJson) + { + auto version = license.getProperty ("product_version", {}).toString().trim(); + auto type = license.getProperty ("licence_type", {}).toString(); + auto status = license.getProperty ("status", {}).toString(); + + if (status == "active" && type.isNotEmpty() && version.isNotEmpty()) + licenses.push_back ({ version.getIntValue(), LicenseHelpers::licenseTypeForString (type) }); + } + + if (! licenses.empty()) + { + auto bestLicense = LicenseHelpers::findBestLicense (std::move (licenses)); + + licenseState.version = bestLicense.first; + licenseState.type = bestLicense.second; + } + + return true; + } + + return false; + } + + String userAuthToken; + }; + + //============================================================================== + static String postDataStringAsJSON (const StringPairArray& parameters) + { + DynamicObject::Ptr d (new DynamicObject()); + + for (auto& key : parameters.getAllKeys()) + d->setProperty (key, parameters[key]); + + return JSON::toString (var (d.get())); + } + + static ErrorMessageAndType runTask (std::unique_ptr<AccountEnquiryBase> accountEnquiryTask, LicenseState& state) + { + const ErrorMessageAndType cancelledError ("Cancelled.", ErrorType::cancelled); + const String endpointURL = "https://api.juce.com/api/v1"; + + auto url = URL (endpointURL + accountEnquiryTask->getEndpointURLSuffix()); + + auto isPOST = accountEnquiryTask->isPOSTLikeRequest(); + + if (isPOST) + url = url.withPOSTData (postDataStringAsJSON (accountEnquiryTask->getParameterNamesAndValues())); + + if (ThreadPoolJob::getCurrentThreadPoolJob()->shouldExit()) + return cancelledError; + + int statusCode = 0; + auto urlStream = url.createInputStream (isPOST, nullptr, nullptr, + accountEnquiryTask->getExtraHeaders(), + 5000, nullptr, &statusCode); + + if (urlStream == nullptr) + return { "Failed to connect to the web server.", ErrorType::connectionError }; + + if (statusCode != accountEnquiryTask->getSuccessCode()) + return { accountEnquiryTask->errorCodeToString (statusCode), ErrorType::webResponseError }; + + if (ThreadPoolJob::getCurrentThreadPoolJob()->shouldExit()) + return cancelledError; + + String response; + + for (;;) + { + char buffer [8192]; + auto num = urlStream->read (buffer, sizeof (buffer)); + + if (ThreadPoolJob::getCurrentThreadPoolJob()->shouldExit()) + return cancelledError; + + if (num <= 0) + break; + + response += buffer; + } + + if (ThreadPoolJob::getCurrentThreadPoolJob()->shouldExit()) + return cancelledError; + + if (! accountEnquiryTask->parseServerResponse (response, state)) + return { "Failed to parse server response.", ErrorType::webResponseError }; + + return {}; + } + + //============================================================================== + ThreadPool jobPool { 1 }; + + //============================================================================== + JUCE_DECLARE_WEAK_REFERENCEABLE (LicenseQueryThread) + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LicenseQueryThread) +}; diff --git a/extras/Projucer/Source/Application/UserAccount/jucer_LicenseState.h b/extras/Projucer/Source/Application/UserAccount/jucer_LicenseState.h new file mode 100644 index 00000000..5d685038 --- /dev/null +++ b/extras/Projucer/Source/Application/UserAccount/jucer_LicenseState.h @@ -0,0 +1,91 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +#pragma once + + +//============================================================================== +struct LicenseState +{ + enum class Type + { + none, + gpl, + personal, + educational, + indie, + pro + }; + + LicenseState() = default; + + LicenseState (Type t, int v, String user, String token) + : type (t), version (v), username (user), authToken (token) + { + } + + bool operator== (const LicenseState& other) const noexcept + { + return type == other.type + && version == other.version + && username == other.username + && authToken == other.authToken; + } + + bool operator != (const LicenseState& other) const noexcept + { + return ! operator== (other); + } + + bool isSignedIn() const noexcept { return isGPL() || (version > 0 && username.isNotEmpty()); } + bool isOldLicense() const noexcept { return isSignedIn() && version < projucerMajorVersion; } + bool isGPL() const noexcept { return type == Type::gpl; } + + bool canUnlockFullFeatures() const noexcept + { + return isGPL() || (isSignedIn() && ! isOldLicense() && (type == Type::indie || type == Type::pro)); + } + + String getLicenseTypeString() const + { + switch (type) + { + case Type::none: return "No license"; + case Type::gpl: return "GPL"; + case Type::personal: return "Personal"; + case Type::educational: return "Educational"; + case Type::indie: return "Indie"; + case Type::pro: return "Pro"; + default: break; + }; + + jassertfalse; + return {}; + } + + Type type = Type::none; + int version = -1; + String username, authToken; +}; diff --git a/extras/Projucer/Source/Application/UserAccount/jucer_LoginFormComponent.h b/extras/Projucer/Source/Application/UserAccount/jucer_LoginFormComponent.h new file mode 100644 index 00000000..9d43feb1 --- /dev/null +++ b/extras/Projucer/Source/Application/UserAccount/jucer_LoginFormComponent.h @@ -0,0 +1,278 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +#pragma once + + +#include "../../Project/UI/jucer_UserAvatarComponent.h" + +//============================================================================== +class LoginFormComponent : public Component +{ +public: + LoginFormComponent (MainWindow& window) + : mainWindow (window) + { + addAndMakeVisible (emailBox); + emailBox.setTextToShowWhenEmpty ("Email", Colours::black.withAlpha (0.2f)); + emailBox.setJustification (Justification::centredLeft); + emailBox.onReturnKey = [this] { submitDetails(); }; + + addAndMakeVisible (passwordBox); + passwordBox.setTextToShowWhenEmpty ("Password", Colours::black.withAlpha (0.2f)); + passwordBox.setPasswordCharacter ((juce_wchar) 0x2022); + passwordBox.setJustification (Justification::centredLeft); + passwordBox.onReturnKey = [this] { submitDetails(); }; + + addAndMakeVisible (logInButton); + logInButton.onClick = [this] { submitDetails(); }; + + addAndMakeVisible (enableGPLButton); + enableGPLButton.onClick = [this] + { + ProjucerApplication::getApp().getLicenseController().setState (LicenseController::getGPLState()); + mainWindow.hideLoginFormOverlay(); + }; + + addAndMakeVisible (userAvatar); + + addAndMakeVisible (createAccountLabel); + createAccountLabel.setFont (Font (14.0f, Font::underlined)); + createAccountLabel.addMouseListener (this, false); + createAccountLabel.setMouseCursor (MouseCursor::PointingHandCursor); + + addAndMakeVisible (errorMessageLabel); + errorMessageLabel.setMinimumHorizontalScale (1.0f); + errorMessageLabel.setFont (12.0f); + errorMessageLabel.setColour (Label::textColourId, Colours::red); + errorMessageLabel.setVisible (false); + + dismissButton.setShape (getLookAndFeel().getCrossShape (1.0f), false, true, false); + addAndMakeVisible (dismissButton); + dismissButton.onClick = [this] { mainWindow.hideLoginFormOverlay(); }; + + setWantsKeyboardFocus (true); + setOpaque (true); + + lookAndFeelChanged(); + + setSize (300, 350); + } + + ~LoginFormComponent() override + { + ProjucerApplication::getApp().getLicenseController().cancelSignIn(); + } + + void resized() override + { + auto bounds = getLocalBounds().reduced (20); + auto spacing = bounds.getHeight() / 20; + + userAvatar.setBounds (bounds.removeFromTop (iconHeight).reduced ((bounds.getWidth() / 2) - (iconHeight / 2), 0)); + + errorMessageLabel.setBounds (bounds.removeFromTop (spacing)); + bounds.removeFromTop (spacing / 2); + + auto textEditorHeight = bounds.getHeight() / 5; + + emailBox.setBounds (bounds.removeFromTop (textEditorHeight)); + bounds.removeFromTop (spacing); + + passwordBox.setBounds (bounds.removeFromTop (textEditorHeight)); + bounds.removeFromTop (spacing * 2); + + emailBox.setFont (Font ((float) textEditorHeight / 2.5f)); + passwordBox.setFont (Font ((float) textEditorHeight / 2.5f)); + + logInButton.setBounds (bounds.removeFromTop (textEditorHeight)); + + auto slice = bounds.removeFromTop (textEditorHeight); + createAccountLabel.setBounds (slice.removeFromLeft (createAccountLabel.getFont().getStringWidth (createAccountLabel.getText()) + 5)); + slice.removeFromLeft (15); + enableGPLButton.setBounds (slice.reduced (0, 5)); + + dismissButton.setBounds (getLocalBounds().reduced (10).removeFromTop (20).removeFromRight (20)); + } + + void paint (Graphics& g) override + { + g.fillAll (findColour (secondaryBackgroundColourId).contrasting (0.1f)); + } + + void mouseUp (const MouseEvent& event) override + { + if (event.eventComponent == &createAccountLabel) + URL ("https://juce.com/verification/register").launchInDefaultBrowser(); + } + + void lookAndFeelChanged() override + { + enableGPLButton.setColour (TextButton::buttonColourId, findColour (secondaryButtonBackgroundColourId)); + } + +private: + class ProgressButton : public TextButton, + private Timer + { + public: + ProgressButton (const String& buttonName) + : TextButton (buttonName), text (buttonName) + { + } + + void setBusy (bool shouldBeBusy) + { + isInProgress = shouldBeBusy; + + if (isInProgress) + { + setEnabled (false); + setButtonText ({}); + startTimerHz (30); + } + else + { + setEnabled (true); + setButtonText (text); + stopTimer(); + } + } + + void paint (Graphics& g) override + { + TextButton::paint (g); + + if (isInProgress) + { + auto size = getHeight() - 10; + auto halfSize = size / 2; + + getLookAndFeel().drawSpinningWaitAnimation (g, Colours::white, + (getWidth() / 2) - halfSize, (getHeight() / 2) - halfSize, + size, size); + } + } + + private: + void timerCallback() override + { + repaint(); + } + + String text; + bool isInProgress = false; + }; + + //============================================================================== + void updateLoginButtonStates (bool isLoggingIn) + { + logInButton.setBusy (isLoggingIn); + + emailBox.setEnabled (! isLoggingIn); + passwordBox.setEnabled (! isLoggingIn); + } + + void submitDetails() + { + auto loginFormError = checkLoginFormsAreValid(); + + if (loginFormError.isNotEmpty()) + { + showErrorMessage (loginFormError); + return; + } + + updateLoginButtonStates (true); + + WeakReference<Component> weakThis (this); + auto completionCallback = [this, weakThis] (const String& errorMessage) + { + if (weakThis == nullptr) + return; + + updateLoginButtonStates (false); + + if (errorMessage.isNotEmpty()) + { + showErrorMessage (errorMessage); + } + else + { + hideErrorMessage(); + mainWindow.hideLoginFormOverlay(); + ProjucerApplication::getApp().getCommandManager().commandStatusChanged(); + } + }; + + ProjucerApplication::getApp().getLicenseController().signIn (emailBox.getText(), passwordBox.getText(), + std::move (completionCallback)); + } + + String checkLoginFormsAreValid() const + { + auto email = emailBox.getText(); + + if (email.isEmpty() || email.indexOfChar ('@') < 0) + return "Please enter a valid email."; + + auto password = passwordBox.getText(); + + if (password.isEmpty() || password.length() < 8) + return "Please enter a valid password."; + + return {}; + } + + void showErrorMessage (const String& errorMessage) + { + errorMessageLabel.setText (errorMessage, dontSendNotification); + errorMessageLabel.setVisible (true); + } + + void hideErrorMessage() + { + errorMessageLabel.setText ({}, dontSendNotification); + errorMessageLabel.setVisible (false); + } + + //============================================================================== + static constexpr int iconHeight = 50; + + MainWindow& mainWindow; + + TextEditor emailBox, passwordBox; + ProgressButton logInButton { "Sign In" }; + TextButton enableGPLButton { "Enable GPL Mode" }; + ShapeButton dismissButton { {}, + findColour (treeIconColourId), + findColour (treeIconColourId).overlaidWith (findColour (defaultHighlightedTextColourId).withAlpha (0.2f)), + findColour (treeIconColourId).overlaidWith (findColour (defaultHighlightedTextColourId).withAlpha (0.4f)) }; + UserAvatarComponent userAvatar { false }; + Label createAccountLabel { {}, "Create an account" }, + errorMessageLabel { {}, {} }; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LoginFormComponent) +}; diff --git a/extras/Projucer/Source/Application/Windows/jucer_AboutWindowComponent.h b/extras/Projucer/Source/Application/Windows/jucer_AboutWindowComponent.h index cdaae6cd..23d0e7f9 100644 --- a/extras/Projucer/Source/Application/Windows/jucer_AboutWindowComponent.h +++ b/extras/Projucer/Source/Application/Windows/jucer_AboutWindowComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -33,14 +32,6 @@ class AboutWindowComponent : public Component public: AboutWindowComponent() { - bool showPurchaseButton = false; - - #if ! JUCER_ENABLE_GPL_MODE - if (auto* controller = ProjucerApplication::getApp().licenseController.get()) - showPurchaseButton = (controller->getState().type != LicenseState::Type::indie - && controller->getState().type != LicenseState::Type::pro); - #endif - addAndMakeVisible (titleLabel); titleLabel.setJustificationType (Justification::centred); titleLabel.setFont (Font (35.0f, Font::FontStyleFlags::bold)); @@ -59,17 +50,6 @@ public: addAndMakeVisible (aboutButton); aboutButton.setTooltip ( {} ); - - if (showPurchaseButton) - { - addAndMakeVisible (licenseButton); - - licenseButton.onClick = [] - { - if (auto* controller = ProjucerApplication::getApp().licenseController.get()) - controller->chooseNewLicense(); - }; - } } void resized() override @@ -77,23 +57,15 @@ public: auto bounds = getLocalBounds(); bounds.removeFromBottom (20); - auto rightSlice = bounds.removeFromRight (150); auto leftSlice = bounds.removeFromLeft (150); - auto centreSlice = bounds; - - //============================================================================== - rightSlice.removeFromRight (20); - auto iconSlice = rightSlice.removeFromRight (100); - huckleberryLogoBounds = iconSlice.removeFromBottom (100).toFloat(); + auto centreSlice = bounds.withTrimmedRight (150); - //============================================================================== 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)); @@ -104,10 +76,6 @@ public: versionLabel.setBounds (centreSlice.removeFromTop (40)); centreSlice.removeFromTop (10); - - if (licenseButton.isShowing()) - licenseButton.setBounds (centreSlice.removeFromTop (25).reduced (25, 0)); - aboutButton.setBounds (centreSlice.removeFromBottom (20)); } @@ -117,26 +85,19 @@ public: if (juceLogo != nullptr) juceLogo->drawWithin (g, juceLogoBounds.translated (-75, -75), RectanglePlacement::centred, 1.0); - - if (huckleberryLogo != nullptr) - huckleberryLogo->drawWithin (g, huckleberryLogoBounds, RectanglePlacement::centred, 1.0); } private: Label titleLabel { "title", "PROJUCER" }, versionLabel { "version" }, - copyrightLabel { "copyright", String (CharPointer_UTF8 ("\xc2\xa9")) + String (" 2017 ROLI Ltd.") }; + copyrightLabel { "copyright", String (CharPointer_UTF8 ("\xc2\xa9")) + String (" 2020 Raw Material Software Limited") }; HyperlinkButton aboutButton { "About Us", URL ("https://juce.com") }; - TextButton licenseButton { "Purchase License" }; - Rectangle<float> huckleberryLogoBounds, juceLogoBounds; + Rectangle<float> juceLogoBounds; std::unique_ptr<Drawable> juceLogo { Drawable::createFromImageData (BinaryData::juce_icon_png, BinaryData::juce_icon_pngSize) }; - std::unique_ptr<Drawable> huckleberryLogo { Drawable::createFromImageData (BinaryData::huckleberry_icon_svg, - BinaryData::huckleberry_icon_svgSize) }; - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AboutWindowComponent) }; diff --git a/extras/Projucer/Source/Application/Windows/jucer_ApplicationUsageDataWindowComponent.h b/extras/Projucer/Source/Application/Windows/jucer_ApplicationUsageDataWindowComponent.h deleted file mode 100644 index c9a06df1..00000000 --- a/extras/Projucer/Source/Application/Windows/jucer_ApplicationUsageDataWindowComponent.h +++ /dev/null @@ -1,164 +0,0 @@ -/* - ============================================================================== - - 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. - - ============================================================================== -*/ - -#pragma once - - -//============================================================================== -class ApplicationUsageDataWindowComponent : public Component -{ -public: - ApplicationUsageDataWindowComponent (bool showCheckbox) - { - addAndMakeVisible (headerLabel); - headerLabel.setText ("Application Usage Analytics", dontSendNotification); - headerLabel.setFont (Font (20.0f, Font::FontStyleFlags::bold)); - headerLabel.setJustificationType (Justification::centred); - - auto textToShow = String ("We use analytics services to understand how developers use our software in order for JUCE to improve its software and services. "); - - if (! showCheckbox) - textToShow += String (" Analytics can be disabled with an Indie or Pro license. "); - - textToShow += String ("For more information, please read the JUCE EULA and Privacy policy:"); - - addAndMakeVisible (bodyLabel); - bodyLabel.setText (textToShow, dontSendNotification); - bodyLabel.setFont (Font (14.0f)); - bodyLabel.setJustificationType (Justification::centredLeft); - - addAndMakeVisible (juceEULALink); - juceEULALink.setButtonText ("JUCE EULA"); - juceEULALink.setFont (Font (14.0f), false); - juceEULALink.setURL (URL ("https://juce.com/juce-5-license")); - - addAndMakeVisible (privacyPolicyLink); - privacyPolicyLink.setButtonText ("Privacy Policy"); - privacyPolicyLink.setFont (Font (14.0f), false); - privacyPolicyLink.setURL (URL ("https://juce.com/juce-5-privacy-policy")); - - addAndMakeVisible (okButton); - - if (showCheckbox) - { - shareApplicationUsageDataToggle.reset (new ToggleButton()); - addAndMakeVisible (shareApplicationUsageDataToggle.get()); - - auto* controller = ProjucerApplication::getApp().licenseController.get(); - - if (controller != nullptr && controller->getState().applicationUsageDataState == LicenseState::ApplicationUsageData::disabled) - shareApplicationUsageDataToggle->setToggleState (false, dontSendNotification); - else - shareApplicationUsageDataToggle->setToggleState (true, dontSendNotification); - - addAndMakeVisible (shareApplicationUsageDataLabel); - shareApplicationUsageDataLabel.setFont (Font (14.0f)); - shareApplicationUsageDataLabel.setMinimumHorizontalScale (1.0f); - } - else - { - addAndMakeVisible (upgradeLicenseButton); - upgradeLicenseButton.setColour (TextButton::buttonColourId, findColour (secondaryButtonBackgroundColourId)); - - upgradeLicenseButton.onClick = [] - { - if (auto* controller = ProjucerApplication::getApp().licenseController.get()) - controller->chooseNewLicense(); - }; - } - } - - ~ApplicationUsageDataWindowComponent() override - { - if (auto* controller = ProjucerApplication::getApp().licenseController.get()) - { - auto newApplicationUsageDataState = LicenseState::ApplicationUsageData::enabled; - - if (shareApplicationUsageDataToggle != nullptr && ! shareApplicationUsageDataToggle->getToggleState()) - newApplicationUsageDataState = LicenseState::ApplicationUsageData::disabled; - - controller->setApplicationUsageDataState (newApplicationUsageDataState); - } - } - - void resized() override - { - auto bounds = getLocalBounds().reduced (20); - headerLabel.setBounds (bounds.removeFromTop (40)); - bodyLabel.setBounds (bounds.removeFromTop (75)); - - bounds.removeFromTop (10); - - auto linkBounds = bounds.removeFromTop (20); - juceEULALink.setBounds (linkBounds.removeFromLeft (linkBounds.getWidth() / 2).reduced (2)); - privacyPolicyLink.setBounds (linkBounds.reduced (2)); - - if (shareApplicationUsageDataToggle != nullptr) - { - bounds.removeFromTop (10); - - auto toggleBounds = bounds.removeFromTop (40); - shareApplicationUsageDataToggle->setBounds (toggleBounds.removeFromLeft (40).reduced (5)); - shareApplicationUsageDataLabel.setBounds (toggleBounds); - } - - bounds.removeFromTop (10); - - auto buttonW = 125; - auto buttonH = 40; - - if (upgradeLicenseButton.isShowing()) - { - auto left = bounds.removeFromLeft (bounds.getWidth() / 2); - - upgradeLicenseButton.setSize (buttonW, buttonH); - upgradeLicenseButton.setCentrePosition (left.getCentreX(), left.getCentreY()); - } - - okButton.setSize (buttonW, buttonH); - okButton.setCentrePosition (bounds.getCentreX(), bounds.getCentreY()); - okButton.onClick = [] { ProjucerApplication::getApp().dismissApplicationUsageDataAgreementPopup(); }; - } - - void paint (Graphics& g) override - { - g.fillAll (findColour (backgroundColourId)); - } - -private: - Label headerLabel, bodyLabel; - HyperlinkButton juceEULALink, privacyPolicyLink; - Label shareApplicationUsageDataLabel { {}, "Help JUCE to improve its software and services by sharing my application usage data" }; - std::unique_ptr<ToggleButton> shareApplicationUsageDataToggle; - TextButton okButton { "OK" }, upgradeLicenseButton { "Upgrade License" }; - - void lookAndFeelChanged() override - { - upgradeLicenseButton.setColour (TextButton::buttonColourId, findColour (secondaryButtonBackgroundColourId)); - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ApplicationUsageDataWindowComponent) -}; diff --git a/extras/Projucer/Source/Application/Windows/jucer_EditorColourSchemeWindowComponent.h b/extras/Projucer/Source/Application/Windows/jucer_EditorColourSchemeWindowComponent.h index d125857b..d8e0bf74 100644 --- a/extras/Projucer/Source/Application/Windows/jucer_EditorColourSchemeWindowComponent.h +++ b/extras/Projucer/Source/Application/Windows/jucer_EditorColourSchemeWindowComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/Application/Windows/jucer_FloatingToolWindow.h b/extras/Projucer/Source/Application/Windows/jucer_FloatingToolWindow.h index bcf5c793..75974ab3 100644 --- a/extras/Projucer/Source/Application/Windows/jucer_FloatingToolWindow.h +++ b/extras/Projucer/Source/Application/Windows/jucer_FloatingToolWindow.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/Application/Windows/jucer_GlobalPathsWindowComponent.h b/extras/Projucer/Source/Application/Windows/jucer_GlobalPathsWindowComponent.h index 67eda31d..74a4ef38 100644 --- a/extras/Projucer/Source/Application/Windows/jucer_GlobalPathsWindowComponent.h +++ b/extras/Projucer/Source/Application/Windows/jucer_GlobalPathsWindowComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -31,7 +30,8 @@ //============================================================================== class GlobalPathsWindowComponent : public Component, private Timer, - private Value::Listener + private Value::Listener, + private ChangeListener { public: GlobalPathsWindowComponent() @@ -50,6 +50,16 @@ public: lastUserModulePath = getAppSettings().getStoredPath (Ids::defaultUserModulePath, TargetOS::getThisOS()).get(); }; + addChildComponent (warnAboutJUCEPathButton); + warnAboutJUCEPathButton.setToggleState (ProjucerApplication::getApp().shouldPromptUserAboutIncorrectJUCEPath(), + dontSendNotification); + warnAboutJUCEPathButton.onClick = [this] + { + ProjucerApplication::getApp().setShouldPromptUserAboutIncorrectJUCEPath (warnAboutJUCEPathButton.getToggleState()); + }; + + getGlobalProperties().addChangeListener (this); + addAndMakeVisible (resetToDefaultsButton); resetToDefaultsButton.onClick = [this] { resetCurrentOSPathsToDefaults(); }; @@ -72,6 +82,8 @@ public: ~GlobalPathsWindowComponent() override { + getGlobalProperties().removeChangeListener (this); + auto juceValue = getAppSettings().getStoredPath (Ids::defaultJuceModulePath, TargetOS::getThisOS()); auto userValue = getAppSettings().getStoredPath (Ids::defaultUserModulePath, TargetOS::getThisOS()); @@ -94,12 +106,15 @@ public: { auto b = getLocalBounds().reduced (10); - auto buttonBounds = b.removeFromBottom (50); + auto bottomBounds = b.removeFromBottom (80); + auto buttonBounds = bottomBounds.removeFromBottom (50); rescanJUCEPathButton.setBounds (buttonBounds.removeFromLeft (150).reduced (5, 10)); rescanUserPathButton.setBounds (buttonBounds.removeFromLeft (150).reduced (5, 10)); resetToDefaultsButton.setBounds (buttonBounds.removeFromRight (150).reduced (5, 10)); + warnAboutJUCEPathButton.setBounds (bottomBounds.reduced (0, 5)); + warnAboutJUCEPathButton.changeWidthToFitText(); propertyGroup.updateSize (0, 0, getWidth() - 20 - propertyViewport.getScrollBarThickness()); propertyViewport.setBounds (b); @@ -153,6 +168,12 @@ private: resized(); } + void changeListenerCallback (ChangeBroadcaster*) override + { + warnAboutJUCEPathButton.setToggleState (ProjucerApplication::getApp().shouldPromptUserAboutIncorrectJUCEPath(), + dontSendNotification); + } + //============================================================================== bool isSelectedOSThisOS() { return TargetOS::getThisOS() == getSelectedOS(); } @@ -201,8 +222,6 @@ private: "If you are building a legacy VST plug-in then this path should point to a VST2 SDK. " "The VST2 SDK can be obtained from the vstsdk3610_11_06_2018_build_37 (or older) VST3 SDK or JUCE version 5.3.2. " "You also need a VST2 license from Steinberg to distribute VST2 plug-ins."); - builder.add (new FilePathPropertyComponent (vst3PathValue, "VST3 SDK", true, isThisOS), - "This path can be set to use a custom VST3 SDK instead of the one which is embedded in JUCE."); if (getSelectedOS() != TargetOS::linux) { @@ -214,8 +233,6 @@ private: builder.add (new FilePathPropertyComponent (androidSDKPathValue, "Android SDK", true, isThisOS), "This path will be used when writing the local.properties file of an Android project and should point to the Android SDK folder."); - builder.add (new FilePathPropertyComponent (androidNDKPathValue, "Android NDK", true, isThisOS), - "This path will be used when writing the local.properties file of an Android project and should point to the Android NDK folder."); if (isThisOS) { @@ -233,16 +250,12 @@ private: "This path will be used for the \"Save Project and Open in IDE...\" option of the CLion exporter."); builder.add (new FilePathPropertyComponent (androidStudioExePathValue, "Android Studio " + exeLabel, false, isThisOS), "This path will be used for the \"Save Project and Open in IDE...\" option of the Android Studio exporter."); - - rescanJUCEPathButton.setVisible (true); - rescanUserPathButton.setVisible (true); - } - else - { - rescanJUCEPathButton.setVisible (false); - rescanUserPathButton.setVisible (false); } + rescanJUCEPathButton.setVisible (isThisOS); + rescanUserPathButton.setVisible (isThisOS); + warnAboutJUCEPathButton.setVisible (isThisOS); + propertyGroup.setProperties (builder); } @@ -255,11 +268,9 @@ private: juceModulePathValue = settings.getStoredPath (Ids::defaultJuceModulePath, os); userModulePathValue = settings.getStoredPath (Ids::defaultUserModulePath, os); vstPathValue = settings.getStoredPath (Ids::vstLegacyPath, os); - vst3PathValue = settings.getStoredPath (Ids::vst3Path, os); rtasPathValue = settings.getStoredPath (Ids::rtasPath, os); aaxPathValue = settings.getStoredPath (Ids::aaxPath, os); androidSDKPathValue = settings.getStoredPath (Ids::androidSDKPath, os); - androidNDKPathValue = settings.getStoredPath (Ids::androidNDKPath, os); clionExePathValue = settings.getStoredPath (Ids::clionExePath, os); androidStudioExePathValue = settings.getStoredPath (Ids::androidStudioExePath, os); } @@ -270,11 +281,9 @@ private: juceModulePathValue .resetToDefault(); userModulePathValue .resetToDefault(); vstPathValue .resetToDefault(); - vst3PathValue .resetToDefault(); rtasPathValue .resetToDefault(); aaxPathValue .resetToDefault(); androidSDKPathValue .resetToDefault(); - androidNDKPathValue .resetToDefault(); clionExePathValue .resetToDefault(); androidStudioExePathValue.resetToDefault(); @@ -285,13 +294,12 @@ private: Value selectedOSValue; ValueWithDefault jucePathValue, juceModulePathValue, userModulePathValue, - vst3PathValue, vstPathValue, rtasPathValue, aaxPathValue, - androidSDKPathValue, androidNDKPathValue, - clionExePathValue, androidStudioExePathValue; + vstPathValue, rtasPathValue, aaxPathValue, androidSDKPathValue, clionExePathValue, androidStudioExePathValue; Viewport propertyViewport; PropertyGroupComponent propertyGroup { "Global Paths", { getIcons().openFolder, Colours::transparentBlack } }; + ToggleButton warnAboutJUCEPathButton { "Warn about incorrect JUCE path" }; TextButton rescanJUCEPathButton { "Re-scan JUCE Modules" }, rescanUserPathButton { "Re-scan User Modules" }, resetToDefaultsButton { "Reset to Defaults" }; diff --git a/extras/Projucer/Source/Application/Windows/jucer_PIPCreatorWindowComponent.h b/extras/Projucer/Source/Application/Windows/jucer_PIPCreatorWindowComponent.h index ddadb3fe..a9663721 100644 --- a/extras/Projucer/Source/Application/Windows/jucer_PIPCreatorWindowComponent.h +++ b/extras/Projucer/Source/Application/Windows/jucer_PIPCreatorWindowComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -26,6 +25,7 @@ #pragma once + //============================================================================== static String getWidthLimitedStringFromVarArray (const var& varArray) noexcept { @@ -147,11 +147,15 @@ private: { Array<var> exporterVars; - for (auto& e : ProjectExporter::getExporterValueTreeNames()) - exporterVars.add (e.toLowerCase()); + StringArray exporterNames; + + for (auto& exporterTypeInfo : ProjectExporter::getExporterTypeInfos()) + { + exporterVars.add (exporterTypeInfo.identifier.toString()); + exporterNames.add (exporterTypeInfo.displayName); + } - builder.add (new MultiChoicePropertyComponent (exportersValue, "Exporters", - ProjectExporter::getExporterNames(), exporterVars), + builder.add (new MultiChoicePropertyComponent (exportersValue, "Exporters", exporterNames, exporterVars), "The exporters that should be added to your project."); } @@ -176,9 +180,9 @@ private: } //============================================================================== - void valueTreePropertyChanged (ValueTree&, const Identifier& id) override + void valueTreePropertyChanged (ValueTree&, const Identifier& identifier) override { - if (id == Ids::type) + if (identifier == Ids::type) { auto type = typeValue.get().toString(); @@ -315,8 +319,7 @@ private: websiteValue { pipTree, Ids::website, nullptr }, descriptionValue { pipTree, Ids::description, nullptr }, dependenciesValue { pipTree, Ids::dependencies_, nullptr, getModulesRequiredForComponent(), "," }, - exportersValue { pipTree, Ids::exporters, nullptr, - StringArray (ProjectExporter::getValueTreeNameForExporter (ProjectExporter::getCurrentPlatformExporterName()).toLowerCase()), "," }, + exportersValue { pipTree, Ids::exporters, nullptr, StringArray (ProjectExporter::getCurrentPlatformExporterTypeInfo().identifier.toString()), "," }, moduleFlagsValue { pipTree, Ids::moduleFlags, nullptr, "JUCE_STRICT_REFCOUNTEDPOINTER=1" }, definesValue { pipTree, Ids::defines, nullptr }, typeValue { pipTree, Ids::type, nullptr, "Component" }, diff --git a/extras/Projucer/Source/Application/Windows/jucer_SVGPathDataWindowComponent.h b/extras/Projucer/Source/Application/Windows/jucer_SVGPathDataWindowComponent.h index a3cc6ba7..4dcdb579 100644 --- a/extras/Projucer/Source/Application/Windows/jucer_SVGPathDataWindowComponent.h +++ b/extras/Projucer/Source/Application/Windows/jucer_SVGPathDataWindowComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -85,7 +84,7 @@ public: MemoryOutputStream out; out << "static const unsigned char pathData[] = "; - CodeHelpers::writeDataAsCppLiteral (data.getMemoryBlock(), out, false, true); + build_tools::writeDataAsCppLiteral (data.getMemoryBlock(), out, false, true); out << newLine << newLine << "Path path;" << newLine diff --git a/extras/Projucer/Source/Application/Windows/jucer_TranslationToolWindowComponent.h b/extras/Projucer/Source/Application/Windows/jucer_TranslationToolWindowComponent.h index 57c77ea2..742445c5 100644 --- a/extras/Projucer/Source/Application/Windows/jucer_TranslationToolWindowComponent.h +++ b/extras/Projucer/Source/Application/Windows/jucer_TranslationToolWindowComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/Application/Windows/jucer_UTF8WindowComponent.h b/extras/Projucer/Source/Application/Windows/jucer_UTF8WindowComponent.h index b208b1a4..c7fedeb7 100644 --- a/extras/Projucer/Source/Application/Windows/jucer_UTF8WindowComponent.h +++ b/extras/Projucer/Source/Application/Windows/jucer_UTF8WindowComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/Application/jucer_Application.cpp b/extras/Projucer/Source/Application/jucer_Application.cpp index af8514ec..adb518bb 100644 --- a/extras/Projucer/Source/Application/jucer_Application.cpp +++ b/extras/Projucer/Source/Application/jucer_Application.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -24,7 +23,7 @@ ============================================================================== */ -void createGUIEditorMenu (PopupMenu&); +PopupMenu createGUIEditorMenu(); void handleGUIEditorMenuCommand (int); void registerGUIEditorCommands(); @@ -44,9 +43,7 @@ struct ProjucerApplication::MainMenuModel : public MenuBarModel PopupMenu getMenuForIndex (int /*topLevelMenuIndex*/, const String& menuName) override { - PopupMenu menu; - getApp().createMenu (menu, menuName); - return menu; + return getApp().createMenu (menuName); } void menuItemSelected (int menuItemID, int /*topLevelMenuIndex*/) override @@ -56,10 +53,6 @@ struct ProjucerApplication::MainMenuModel : public MenuBarModel }; //============================================================================== -ProjucerApplication::ProjucerApplication() : isRunningCommandLine (false) -{ -} - void ProjucerApplication::initialise (const String& commandLine) { if (commandLine.trimStart().startsWith ("--server")) @@ -81,13 +74,10 @@ void ProjucerApplication::initialise (const String& commandLine) + "MHz Cores: " + String (SystemStats::getNumCpus()) + " " + String (SystemStats::getMemorySizeInMegabytes()) + "MB"); - initialiseBasics(); - isRunningCommandLine = commandLine.isNotEmpty() && ! commandLine.startsWith ("-NSDocumentRevisionsDebugMode"); - licenseController.reset (new LicenseController); - licenseController->addLicenseStatusChangedCallback (this); + settings = std::make_unique<StoredSettings>(); if (isRunningCommandLine) { @@ -110,37 +100,13 @@ void ProjucerApplication::initialise (const String& commandLine) return; } - rescanJUCEPathModules(); - rescanUserPathModules(); - - openDocumentManager.registerType (new ProjucerAppClasses::LiveBuildCodeEditorDocument::Type(), 2); - - childProcessCache.reset (new ChildProcessCache()); - - initCommandManager(); - menuModel.reset (new MainMenuModel()); - - settings->appearance.refreshPresetSchemeList(); - - setColourScheme (settings->getGlobalProperties().getIntValue ("COLOUR SCHEME"), false); - setEditorColourScheme (settings->getGlobalProperties().getIntValue ("EDITOR COLOUR SCHEME"), false); - updateEditorColourSchemeIfNeeded(); + doBasicApplicationSetup(); // do further initialisation in a moment when the message loop has started triggerAsyncUpdate(); } } -void ProjucerApplication::initialiseBasics() -{ - LookAndFeel::setDefaultLookAndFeel (&lookAndFeel); - - settings.reset (new StoredSettings()); - ImageCache::setCacheTimeout (30 * 1000); - icons.reset (new Icons()); - tooltipWindow.setMillisecondsBeforeTipAppears (1200); -} - bool ProjucerApplication::initialiseLogger (const char* filePrefix) { if (logger == nullptr) @@ -160,46 +126,53 @@ bool ProjucerApplication::initialiseLogger (const char* filePrefix) return logger != nullptr; } +void ProjucerApplication::initialiseWindows (const String& commandLine) +{ + const String commandLineWithoutNSDebug (commandLine.replace ("-NSDocumentRevisionsDebugMode YES", StringRef())); + + if (commandLineWithoutNSDebug.trim().isNotEmpty() && ! commandLineWithoutNSDebug.trim().startsWithChar ('-')) + anotherInstanceStarted (commandLine); + else if (mainWindowList.windows.size() == 0) + mainWindowList.reopenLastProjects(); + + mainWindowList.createWindowIfNoneAreOpen(); +} + void ProjucerApplication::handleAsyncUpdate() { - if (licenseController != nullptr) - licenseController->startWebviewIfNeeded(); + rescanJUCEPathModules(); + rescanUserPathModules(); - #if JUCE_MAC - PopupMenu extraAppleMenuItems; - createExtraAppleMenuItems (extraAppleMenuItems); + openDocumentManager.registerType (new ProjucerAppClasses::LiveBuildCodeEditorDocument::Type(), 2); - // workaround broken "Open Recent" submenu: not passing the - // submenu's title here avoids the defect in JuceMainMenuHandler::addMenuItem - MenuBarModel::setMacMainMenu (menuModel.get(), &extraAppleMenuItems); //, "Open Recent"); + menuModel.reset (new MainMenuModel()); + + #if JUCE_MAC + rebuildAppleMenu(); + appleMenuRebuildListener = std::make_unique<AppleMenuRebuildListener>(); #endif - if (getGlobalProperties().getValue (Ids::dontQueryForUpdate, {}).isEmpty()) - LatestVersionCheckerAndUpdater::getInstance()->checkForNewVersion (false); + settings->appearance.refreshPresetSchemeList(); + setColourScheme (getGlobalProperties().getIntValue ("COLOUR SCHEME"), false); + setEditorColourScheme (getGlobalProperties().getIntValue ("EDITOR COLOUR SCHEME"), false); + updateEditorColourSchemeIfNeeded(); - if (licenseController != nullptr) - { - setAnalyticsEnabled (licenseController->getState().applicationUsageDataState == LicenseState::ApplicationUsageData::enabled); - Analytics::getInstance()->logEvent ("Startup", {}, ProjucerAnalyticsEvent::appEvent); - } + ImageCache::setCacheTimeout (30 * 1000); + tooltipWindow = std::make_unique<TooltipWindow> (nullptr, 1200); + + if (isAutomaticVersionCheckingEnabled()) + LatestVersionCheckerAndUpdater::getInstance()->checkForNewVersion (true); - if (! isRunningCommandLine && settings->shouldAskUserToSetJUCEPath()) - showSetJUCEPathAlert(); + initialiseWindows (getCommandLineParameters()); } -void ProjucerApplication::initialiseWindows (const String& commandLine) +void ProjucerApplication::doBasicApplicationSetup() { - const String commandLineWithoutNSDebug (commandLine.replace ("-NSDocumentRevisionsDebugMode YES", StringRef())); - - if (commandLineWithoutNSDebug.trim().isNotEmpty() && ! commandLineWithoutNSDebug.trim().startsWithChar ('-')) - anotherInstanceStarted (commandLine); - else - mainWindowList.reopenLastProjects(); - - mainWindowList.createWindowIfNoneAreOpen(); - - if (licenseController->getState().applicationUsageDataState == LicenseState::ApplicationUsageData::notChosenYet) - showApplicationUsageDataAgreementPopup(); + licenseController = std::make_unique<LicenseController>(); + LookAndFeel::setDefaultLookAndFeel (&lookAndFeel); + initCommandManager(); + childProcessCache = std::make_unique<ChildProcessCache>(); + icons = std::make_unique<Icons>(); } static void deleteTemporaryFiles() @@ -225,12 +198,6 @@ void ProjucerApplication::shutdown() editorColourSchemeWindow.reset(); pipCreatorWindow.reset(); - if (licenseController != nullptr) - { - licenseController->removeLicenseStatusChangedCallback (this); - licenseController.reset(); - } - mainWindowList.forceCloseAllWindows(); openDocumentManager.clear(); @@ -244,7 +211,8 @@ void ProjucerApplication::shutdown() commandManager.reset(); settings.reset(); - LookAndFeel::setDefaultLookAndFeel (nullptr); + if (! isRunningCommandLine) + LookAndFeel::setDefaultLookAndFeel (nullptr); // clean up after ourselves and delete any temp project files that may have // been created from PIPs @@ -254,8 +222,6 @@ void ProjucerApplication::shutdown() Logger::writeToLog ("Shutdown"); deleteLogger(); - - Analytics::getInstance()->logEvent ("Shutdown", {}, ProjucerAnalyticsEvent::appEvent); } struct AsyncQuitRetrier : private Timer @@ -291,31 +257,6 @@ void ProjucerApplication::systemRequestedQuit() } } -//============================================================================== -void ProjucerApplication::licenseStateChanged (const LicenseState& state) -{ - #if ! JUCER_ENABLE_GPL_MODE - if (state.type != LicenseState::Type::notLoggedIn - && state.type != LicenseState::Type::noLicenseChosenYet) - #else - ignoreUnused (state); - #endif - { - initialiseWindows (getCommandLineParameters()); - } -} - -void ProjucerApplication::doLogout() -{ - if (licenseController != nullptr) - { - const LicenseState& state = licenseController->getState(); - - if (state.type != LicenseState::Type::notLoggedIn && closeAllMainWindows()) - licenseController->logout(); - } -} - //============================================================================== String ProjucerApplication::getVersionDescription() const { @@ -335,7 +276,12 @@ String ProjucerApplication::getVersionDescription() const void ProjucerApplication::anotherInstanceStarted (const String& commandLine) { if (server == nullptr && ! commandLine.trim().startsWithChar ('-')) - openFile (File (commandLine.unquoted())); + { + ArgumentList list ({}, commandLine); + + for (auto& arg : list.arguments) + openFile (arg.resolveAsFile()); + } } ProjucerApplication& ProjucerApplication::getApp() @@ -370,25 +316,52 @@ MenuBarModel* ProjucerApplication::getMenuModel() StringArray ProjucerApplication::getMenuNames() { - return { "File", "Edit", "View", "Build", "Window", "Document", "GUI Editor", "Tools", "Help" }; + StringArray currentMenuNames { "File", "Edit", "View", "Build", "Window", "Document", "GUI Editor", "Tools", "Help" }; + + if (! isLiveBuildEnabled()) currentMenuNames.removeString ("Build"); + if (! isGUIEditorEnabled()) currentMenuNames.removeString ("GUI Editor"); + + return currentMenuNames; } -void ProjucerApplication::createMenu (PopupMenu& menu, const String& menuName) +PopupMenu ProjucerApplication::createMenu (const String& menuName) { - if (menuName == "File") createFileMenu (menu); - else if (menuName == "Edit") createEditMenu (menu); - else if (menuName == "View") createViewMenu (menu); - else if (menuName == "Build") createBuildMenu (menu); - else if (menuName == "Window") createWindowMenu (menu); - else if (menuName == "Document") createDocumentMenu (menu); - else if (menuName == "Tools") createToolsMenu (menu); - else if (menuName == "Help") createHelpMenu (menu); - else if (menuName == "GUI Editor") createGUIEditorMenu (menu); - else jassertfalse; // names have changed? + if (menuName == "File") + return createFileMenu(); + + if (menuName == "Edit") + return createEditMenu(); + + if (menuName == "View") + return createViewMenu(); + + if (menuName == "Build") + if (isLiveBuildEnabled()) + return createBuildMenu(); + + if (menuName == "Window") + return createWindowMenu(); + + if (menuName == "Document") + return createDocumentMenu(); + + if (menuName == "Tools") + return createToolsMenu(); + + if (menuName == "Help") + return createHelpMenu(); + + if (menuName == "GUI Editor") + if (isGUIEditorEnabled()) + return createGUIEditorMenu(); + + jassertfalse; // names have changed? + return {}; } -void ProjucerApplication::createFileMenu (PopupMenu& menu) +PopupMenu ProjucerApplication::createFileMenu() { + PopupMenu menu; menu.addCommandItem (commandManager.get(), CommandIDs::newProject); menu.addCommandItem (commandManager.get(), CommandIDs::newProjectFromClipboard); menu.addCommandItem (commandManager.get(), CommandIDs::newPIP); @@ -409,12 +382,7 @@ void ProjucerApplication::createFileMenu (PopupMenu& menu) menu.addSubMenu ("Open Recent", recentFiles); } - { - PopupMenu examples; - - createExamplesPopupMenu (examples); - menu.addSubMenu ("Open Example", examples); - } + menu.addSubMenu ("Open Example", createExamplesPopupMenu()); menu.addSeparator(); menu.addCommandItem (commandManager.get(), CommandIDs::closeDocument); @@ -433,18 +401,21 @@ void ProjucerApplication::createFileMenu (PopupMenu& menu) menu.addCommandItem (commandManager.get(), CommandIDs::loginLogout); #endif - #if ! JUCE_MAC - menu.addCommandItem (commandManager.get(), CommandIDs::showAboutWindow); - menu.addCommandItem (commandManager.get(), CommandIDs::showAppUsageWindow); - menu.addCommandItem (commandManager.get(), CommandIDs::checkForNewVersion); - menu.addCommandItem (commandManager.get(), CommandIDs::showGlobalPathsWindow); - menu.addSeparator(); - menu.addCommandItem (commandManager.get(), StandardApplicationCommandIDs::quit); - #endif + #if ! JUCE_MAC + menu.addCommandItem (commandManager.get(), CommandIDs::showAboutWindow); + menu.addCommandItem (commandManager.get(), CommandIDs::checkForNewVersion); + menu.addCommandItem (commandManager.get(), CommandIDs::enableNewVersionCheck); + menu.addCommandItem (commandManager.get(), CommandIDs::showGlobalPathsWindow); + menu.addSeparator(); + menu.addCommandItem (commandManager.get(), StandardApplicationCommandIDs::quit); + #endif + + return menu; } -void ProjucerApplication::createEditMenu (PopupMenu& menu) +PopupMenu ProjucerApplication::createEditMenu() { + PopupMenu menu; menu.addCommandItem (commandManager.get(), StandardApplicationCommandIDs::undo); menu.addCommandItem (commandManager.get(), StandardApplicationCommandIDs::redo); menu.addSeparator(); @@ -459,10 +430,12 @@ void ProjucerApplication::createEditMenu (PopupMenu& menu) menu.addCommandItem (commandManager.get(), CommandIDs::findSelection); menu.addCommandItem (commandManager.get(), CommandIDs::findNext); menu.addCommandItem (commandManager.get(), CommandIDs::findPrevious); + return menu; } -void ProjucerApplication::createViewMenu (PopupMenu& menu) +PopupMenu ProjucerApplication::createViewMenu() { + PopupMenu menu; menu.addCommandItem (commandManager.get(), CommandIDs::showProjectSettings); menu.addCommandItem (commandManager.get(), CommandIDs::showProjectTab); menu.addCommandItem (commandManager.get(), CommandIDs::showBuildTab); @@ -473,10 +446,13 @@ void ProjucerApplication::createViewMenu (PopupMenu& menu) menu.addSeparator(); createColourSchemeItems (menu); + + return menu; } -void ProjucerApplication::createBuildMenu (PopupMenu& menu) +PopupMenu ProjucerApplication::createBuildMenu() { + PopupMenu menu; menu.addCommandItem (commandManager.get(), CommandIDs::toggleBuildEnabled); menu.addCommandItem (commandManager.get(), CommandIDs::buildNow); menu.addCommandItem (commandManager.get(), CommandIDs::toggleContinuousBuild); @@ -490,55 +466,60 @@ void ProjucerApplication::createBuildMenu (PopupMenu& menu) menu.addSeparator(); menu.addCommandItem (commandManager.get(), CommandIDs::nextError); menu.addCommandItem (commandManager.get(), CommandIDs::prevError); + return menu; } void ProjucerApplication::createColourSchemeItems (PopupMenu& menu) { - PopupMenu colourSchemeMenu; + { + PopupMenu colourSchemeMenu; + + colourSchemeMenu.addItem (PopupMenu::Item ("Dark") + .setTicked (selectedColourSchemeIndex == 0) + .setAction ([this] { setColourScheme (0, true); updateEditorColourSchemeIfNeeded(); })); - colourSchemeMenu.addItem (PopupMenu::Item ("Dark") - .setTicked (selectedColourSchemeIndex == 0) - .setAction ([this] { setColourScheme (0, true); updateEditorColourSchemeIfNeeded(); })); + colourSchemeMenu.addItem (PopupMenu::Item ("Grey") + .setTicked (selectedColourSchemeIndex == 1) + .setAction ([this] { setColourScheme (1, true); updateEditorColourSchemeIfNeeded(); })); - colourSchemeMenu.addItem (PopupMenu::Item ("Grey") - .setTicked (selectedColourSchemeIndex == 1) - .setAction ([this] { setColourScheme (1, true); updateEditorColourSchemeIfNeeded(); })); + colourSchemeMenu.addItem (PopupMenu::Item ("Light") + .setTicked (selectedColourSchemeIndex == 2) + .setAction ([this] { setColourScheme (2, true); updateEditorColourSchemeIfNeeded(); })); - colourSchemeMenu.addItem (PopupMenu::Item ("Light") - .setTicked (selectedColourSchemeIndex == 2) - .setAction ([this] { setColourScheme (2, true); updateEditorColourSchemeIfNeeded(); })); + menu.addSubMenu ("Colour Scheme", colourSchemeMenu); + } - menu.addSubMenu ("Colour Scheme", colourSchemeMenu); + { + PopupMenu editorColourSchemeMenu; - //============================================================================== - PopupMenu editorColourSchemeMenu; + auto& appearanceSettings = getAppSettings().appearance; - auto& appearanceSettings = getAppSettings().appearance; + appearanceSettings.refreshPresetSchemeList(); + auto schemes = appearanceSettings.getPresetSchemes(); - appearanceSettings.refreshPresetSchemeList(); - auto schemes = appearanceSettings.getPresetSchemes(); + auto i = 0; - auto i = 0; + for (auto& s : schemes) + { + editorColourSchemeMenu.addItem (PopupMenu::Item (s) + .setEnabled (editorColourSchemeWindow == nullptr) + .setTicked (selectedEditorColourSchemeIndex == i) + .setAction ([this, i] { setEditorColourScheme (i, true); })); + ++i; + } - for (auto& s : schemes) - { - editorColourSchemeMenu.addItem (PopupMenu::Item (s) + editorColourSchemeMenu.addSeparator(); + editorColourSchemeMenu.addItem (PopupMenu::Item ("Create...") .setEnabled (editorColourSchemeWindow == nullptr) - .setTicked (selectedEditorColourSchemeIndex == i) - .setAction ([this, i] { setEditorColourScheme (i, true); })); - ++i; - } + .setAction ([this] { showEditorColourSchemeWindow(); })); - editorColourSchemeMenu.addSeparator(); - editorColourSchemeMenu.addItem (PopupMenu::Item ("Create...") - .setEnabled (editorColourSchemeWindow == nullptr) - .setAction ([this] { showEditorColourSchemeWindow(); })); - - menu.addSubMenu ("Editor Colour Scheme", editorColourSchemeMenu); + menu.addSubMenu ("Editor Colour Scheme", editorColourSchemeMenu); + } } -void ProjucerApplication::createWindowMenu (PopupMenu& menu) +PopupMenu ProjucerApplication::createWindowMenu() { + PopupMenu menu; menu.addCommandItem (commandManager.get(), CommandIDs::goToPreviousWindow); menu.addCommandItem (commandManager.get(), CommandIDs::goToNextWindow); menu.addCommandItem (commandManager.get(), CommandIDs::closeWindow); @@ -547,16 +528,22 @@ void ProjucerApplication::createWindowMenu (PopupMenu& menu) int counter = 0; for (auto* window : mainWindowList.windows) + { if (window != nullptr) + { if (auto* project = window->getProject()) menu.addItem (openWindowsBaseID + counter++, project->getProjectNameString()); + } + } menu.addSeparator(); menu.addCommandItem (commandManager.get(), CommandIDs::closeAllWindows); + return menu; } -void ProjucerApplication::createDocumentMenu (PopupMenu& menu) +PopupMenu ProjucerApplication::createDocumentMenu() { + PopupMenu menu; menu.addCommandItem (commandManager.get(), CommandIDs::goToPreviousDoc); menu.addCommandItem (commandManager.get(), CommandIDs::goToNextDoc); menu.addCommandItem (commandManager.get(), CommandIDs::goToCounterpart); @@ -572,35 +559,46 @@ void ProjucerApplication::createDocumentMenu (PopupMenu& menu) menu.addSeparator(); menu.addCommandItem (commandManager.get(), CommandIDs::closeAllDocuments); + return menu; } -void ProjucerApplication::createToolsMenu (PopupMenu& menu) +PopupMenu ProjucerApplication::createToolsMenu() { + PopupMenu menu; menu.addCommandItem (commandManager.get(), CommandIDs::showUTF8Tool); menu.addCommandItem (commandManager.get(), CommandIDs::showSVGPathTool); menu.addCommandItem (commandManager.get(), CommandIDs::showTranslationTool); + menu.addSeparator(); + menu.addCommandItem (commandManager.get(), CommandIDs::enableLiveBuild); + menu.addCommandItem (commandManager.get(), CommandIDs::enableGUIEditor); + return menu; } -void ProjucerApplication::createHelpMenu (PopupMenu& menu) +PopupMenu ProjucerApplication::createHelpMenu() { + PopupMenu menu; menu.addCommandItem (commandManager.get(), CommandIDs::showForum); menu.addSeparator(); menu.addCommandItem (commandManager.get(), CommandIDs::showAPIModules); menu.addCommandItem (commandManager.get(), CommandIDs::showAPIClasses); menu.addCommandItem (commandManager.get(), CommandIDs::showTutorials); + return menu; } -void ProjucerApplication::createExtraAppleMenuItems (PopupMenu& menu) +PopupMenu ProjucerApplication::createExtraAppleMenuItems() { + PopupMenu menu; menu.addCommandItem (commandManager.get(), CommandIDs::showAboutWindow); - menu.addCommandItem (commandManager.get(), CommandIDs::showAppUsageWindow); menu.addCommandItem (commandManager.get(), CommandIDs::checkForNewVersion); + menu.addCommandItem (commandManager.get(), CommandIDs::enableNewVersionCheck); menu.addSeparator(); menu.addCommandItem (commandManager.get(), CommandIDs::showGlobalPathsWindow); + return menu; } -void ProjucerApplication::createExamplesPopupMenu (PopupMenu& menu) noexcept +PopupMenu ProjucerApplication::createExamplesPopupMenu() noexcept { + PopupMenu menu; numExamples = 0; for (auto& dir : getSortedExampleDirectories()) { @@ -623,10 +621,23 @@ void ProjucerApplication::createExamplesPopupMenu (PopupMenu& menu) noexcept menu.addSeparator(); menu.addCommandItem (commandManager.get(), CommandIDs::launchDemoRunner); } + + return menu; } +#if JUCE_MAC + void ProjucerApplication::rebuildAppleMenu() + { + auto extraAppleMenuItems = createExtraAppleMenuItems(); + + // workaround broken "Open Recent" submenu: not passing the + // submenu's title here avoids the defect in JuceMainMenuHandler::addMenuItem + MenuBarModel::setMacMainMenu (menuModel.get(), &extraAppleMenuItems); //, "Open Recent"); + } +#endif + //============================================================================== -static File getJUCEExamplesDirectoryPathFromGlobal() +File ProjucerApplication::getJUCEExamplesDirectoryPathFromGlobal() noexcept { auto globalPath = File::createFileWithoutCheckingPath (getAppSettings().getStoredPath (Ids::jucePath, TargetOS::getThisOS()).get().toString() .replace ("~", File::getSpecialLocation (File::userHomeDirectory).getFullPathName())); @@ -646,14 +657,17 @@ Array<File> ProjucerApplication::getSortedExampleDirectories() noexcept if (! isValidJUCEExamplesDirectory (examplesPath)) return {}; - DirectoryIterator iter (examplesPath, false, "*", File::findDirectories); - while (iter.next()) + for (const auto& iter : RangedDirectoryIterator (examplesPath, false, "*", File::findDirectories)) { auto exampleDirectory = iter.getFile(); if (exampleDirectory.getNumberOfChildFiles (File::findFiles | File::ignoreHiddenFiles) > 0 - && exampleDirectory.getFileName() != "DemoRunner" && exampleDirectory.getFileName() != "Assets") + && exampleDirectory.getFileName() != "DemoRunner" + && exampleDirectory.getFileName() != "Assets" + && exampleDirectory.getFileName() != "CMake") + { exampleDirectories.add (exampleDirectory); + } } exampleDirectories.sort(); @@ -661,12 +675,11 @@ Array<File> ProjucerApplication::getSortedExampleDirectories() noexcept return exampleDirectories; } -Array<File> ProjucerApplication::getSortedExampleFilesInDirectory (const File& directory) const noexcept +Array<File> ProjucerApplication::getSortedExampleFilesInDirectory (const File& directory) noexcept { Array<File> exampleFiles; - DirectoryIterator iter (directory, false, "*.h", File::findFiles); - while (iter.next()) + for (const auto& iter : RangedDirectoryIterator (directory, false, "*.h", File::findFiles)) exampleFiles.add (iter.getFile()); exampleFiles.sort(); @@ -674,26 +687,6 @@ Array<File> ProjucerApplication::getSortedExampleFilesInDirectory (const File& d return exampleFiles; } -bool ProjucerApplication::findWindowAndOpenPIP (const File& pip) -{ - auto* window = mainWindowList.getFrontmostWindow(); - bool shouldCloseWindow = false; - - if (window == nullptr) - { - window = mainWindowList.getOrCreateEmptyWindow(); - shouldCloseWindow = true; - } - - if (window->tryToOpenPIP (pip)) - return true; - - if (shouldCloseWindow) - mainWindowList.closeWindow (window); - - return false; -} - void ProjucerApplication::findAndLaunchExample (int selectedIndex) { File example; @@ -714,12 +707,7 @@ void ProjucerApplication::findAndLaunchExample (int selectedIndex) // example doesn't exist? jassert (example != File()); - findWindowAndOpenPIP (example); - - StringPairArray data; - data.set ("label", example.getFileNameWithoutExtension()); - - Analytics::getInstance()->logEvent ("Example Opened", data, ProjucerAnalyticsEvent::exampleEvent); + openFile (example); } //============================================================================== @@ -739,7 +727,7 @@ static String getPlatformSpecificFileExtension() static File getPlatformSpecificProjectFolder() { - auto examplesDir = getJUCEExamplesDirectoryPathFromGlobal(); + auto examplesDir = ProjucerApplication::getJUCEExamplesDirectoryPathFromGlobal(); if (examplesDir == File()) return {}; @@ -886,18 +874,8 @@ void ProjucerApplication::launchDemoRunner() { auto demoRunnerFile = tryToFindDemoRunnerExecutable(); - if (demoRunnerFile != File()) - { - auto succeeded = demoRunnerFile.startAsProcess(); - - StringPairArray data; - data.set ("label", succeeded ? "Success" : "Failure"); - - Analytics::getInstance()->logEvent ("Launch DemoRunner", data, ProjucerAnalyticsEvent::exampleEvent); - - if (succeeded) - return; - } + if (demoRunnerFile != File() && demoRunnerFile.startAsProcess()) + return; demoRunnerFile = tryToFindDemoRunnerProject(); @@ -920,11 +898,6 @@ void ProjucerApplication::launchDemoRunner() { demoRunnerAlert.reset (nullptr); - StringPairArray data; - data.set ("label", retVal == 1 ? "Opened" : "Cancelled"); - - Analytics::getInstance()->logEvent ("Open DemoRunner Project", data, ProjucerAnalyticsEvent::exampleEvent); - if (retVal == 1) { #if JUCE_LINUX @@ -991,9 +964,11 @@ void ProjucerApplication::getAllCommands (Array <CommandID>& commands) CommandIDs::showGlobalPathsWindow, CommandIDs::showUTF8Tool, CommandIDs::showSVGPathTool, + CommandIDs::enableLiveBuild, + CommandIDs::enableGUIEditor, CommandIDs::showAboutWindow, - CommandIDs::showAppUsageWindow, CommandIDs::checkForNewVersion, + CommandIDs::enableNewVersionCheck, CommandIDs::showForum, CommandIDs::showAPIModules, CommandIDs::showAPIClasses, @@ -1076,18 +1051,35 @@ void ProjucerApplication::getCommandInfo (CommandID commandID, ApplicationComman result.setInfo ("SVG Path Converter", "Shows the SVG->Path data conversion utility", CommandCategories::general, 0); break; - case CommandIDs::showAboutWindow: - result.setInfo ("About Projucer", "Shows the Projucer's 'About' page.", CommandCategories::general, 0); + case CommandIDs::enableLiveBuild: + result.setInfo ("Live-Build Enabled", + "Enables or disables the live-build functionality", + CommandCategories::general, + (isLiveBuildEnabled() ? ApplicationCommandInfo::isTicked : 0)); break; - case CommandIDs::showAppUsageWindow: - result.setInfo ("Application Usage Data", "Shows the application usage data agreement window", CommandCategories::general, 0); + case CommandIDs::enableGUIEditor: + result.setInfo ("GUI Editor Enabled", + "Enables or disables the GUI editor functionality", + CommandCategories::general, + (isGUIEditorEnabled() ? ApplicationCommandInfo::isTicked : 0)); + break; + + case CommandIDs::showAboutWindow: + result.setInfo ("About Projucer", "Shows the Projucer's 'About' page.", CommandCategories::general, 0); break; case CommandIDs::checkForNewVersion: result.setInfo ("Check for New Version...", "Checks the web server for a new version of JUCE", CommandCategories::general, 0); break; + case CommandIDs::enableNewVersionCheck: + result.setInfo ("Automatically Check for New Versions", + "Enables automatic background checking for new versions of JUCE.", + CommandCategories::general, + (isAutomaticVersionCheckingEnabled() ? ApplicationCommandInfo::isTicked : 0)); + break; + case CommandIDs::showForum: result.setInfo ("JUCE Community Forum", "Shows the JUCE community forum in a browser", CommandCategories::general, 0); break; @@ -1106,22 +1098,16 @@ void ProjucerApplication::getCommandInfo (CommandID commandID, ApplicationComman case CommandIDs::loginLogout: { - bool isLoggedIn = false; - String username; - - if (licenseController != nullptr) - { - const LicenseState state = licenseController->getState(); - isLoggedIn = (state.type != LicenseState::Type::notLoggedIn && state.type != LicenseState::Type::GPL); - username = state.username; - } - - result.setInfo (isLoggedIn - ? String ("Sign out ") + username + "..." - : String ("Sign in..."), - "Log out of your JUCE account", CommandCategories::general, 0); + auto licenseState = licenseController->getCurrentState(); + + if (licenseState.isGPL()) + result.setInfo ("Disable GPL mode", "Disables GPL mode", CommandCategories::general, 0); + else + result.setInfo (licenseState.isSignedIn() ? String ("Sign out ") + licenseState.username + "..." : String ("Sign in..."), + "Sign out of your JUCE account", + CommandCategories::general, 0); + break; } - break; default: JUCEApplication::getCommandInfo (commandID, result); @@ -1140,19 +1126,21 @@ bool ProjucerApplication::perform (const InvocationInfo& info) case CommandIDs::launchDemoRunner: launchDemoRunner(); break; case CommandIDs::saveAll: saveAllDocuments(); break; case CommandIDs::closeAllWindows: closeAllMainWindowsAndQuitIfNeeded(); break; - case CommandIDs::closeAllDocuments: closeAllDocuments (true); break; + case CommandIDs::closeAllDocuments: closeAllDocuments (OpenDocumentManager::SaveIfNeeded::yes); break; case CommandIDs::clearRecentFiles: clearRecentFiles(); break; case CommandIDs::showUTF8Tool: showUTF8ToolWindow(); break; case CommandIDs::showSVGPathTool: showSVGPathDataToolWindow(); break; + case CommandIDs::enableLiveBuild: enableOrDisableLiveBuild(); break; + case CommandIDs::enableGUIEditor: enableOrDisableGUIEditor(); break; case CommandIDs::showGlobalPathsWindow: showPathsWindow (false); break; case CommandIDs::showAboutWindow: showAboutWindow(); break; - case CommandIDs::showAppUsageWindow: showApplicationUsageDataAgreementPopup(); break; - case CommandIDs::checkForNewVersion: LatestVersionCheckerAndUpdater::getInstance()->checkForNewVersion (true); break; + case CommandIDs::checkForNewVersion: LatestVersionCheckerAndUpdater::getInstance()->checkForNewVersion (false); break; + case CommandIDs::enableNewVersionCheck: setAutomaticVersionCheckingEnabled (! isAutomaticVersionCheckingEnabled()); break; case CommandIDs::showForum: launchForumBrowser(); break; case CommandIDs::showAPIModules: launchModulesBrowser(); break; case CommandIDs::showAPIClasses: launchClassesBrowser(); break; case CommandIDs::showTutorials: launchTutorialsBrowser(); break; - case CommandIDs::loginLogout: doLogout(); break; + case CommandIDs::loginLogout: doLoginOrLogout(); break; default: return JUCEApplication::perform (info); } @@ -1173,7 +1161,8 @@ void ProjucerApplication::createNewProject() void ProjucerApplication::createNewProjectFromClipboard() { auto tempFile = File::getSpecialLocation (File::SpecialLocationType::tempDirectory).getChildFile ("PIPs").getChildFile ("Clipboard") - .getChildFile ("PIPFile_" + String (std::abs (Random::getSystemRandom().nextInt())) + ".h"); + .getChildFile ("PIPFile_" + String (std::abs (Random::getSystemRandom().nextInt())) + ".h") + .getNonexistentSibling(); if (tempFile.existsAsFile()) tempFile.deleteFile(); @@ -1181,9 +1170,21 @@ void ProjucerApplication::createNewProjectFromClipboard() tempFile.create(); tempFile.appendText (SystemClipboard::getTextFromClipboard()); - if (! findWindowAndOpenPIP (tempFile)) + String errorString; + + if (! isPIPFile (tempFile)) + { + errorString = "Clipboard does not contain a valid PIP."; + } + else if (! openFile (tempFile)) + { + errorString = "Couldn't create project from clipboard contents."; + mainWindowList.closeWindow (mainWindowList.windows.getLast()); + } + + if (errorString.isNotEmpty()) { - AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon, "Error", "Couldn't create project from clipboard contents."); + AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon, "Error", errorString); tempFile.deleteFile(); } } @@ -1215,7 +1216,7 @@ void ProjucerApplication::saveAllDocuments() pcc->refreshProjectTreeFileStatuses(); } -bool ProjucerApplication::closeAllDocuments (bool askUserToSave) +bool ProjucerApplication::closeAllDocuments (OpenDocumentManager::SaveIfNeeded askUserToSave) { return openDocumentManager.closeAll (askUserToSave); } @@ -1265,6 +1266,26 @@ void ProjucerApplication::showSVGPathDataToolWindow() 500, 500, 300, 300, 1000, 1000); } +bool ProjucerApplication::isLiveBuildEnabled() const +{ + return getGlobalProperties().getBoolValue (Ids::liveBuildEnabled); +} + +void ProjucerApplication::enableOrDisableLiveBuild() +{ + getGlobalProperties().setValue (Ids::liveBuildEnabled, ! isLiveBuildEnabled()); +} + +bool ProjucerApplication::isGUIEditorEnabled() const +{ + return getGlobalProperties().getBoolValue (Ids::guiEditorEnabled); +} + +void ProjucerApplication::enableOrDisableGUIEditor() +{ + getGlobalProperties().setValue (Ids::guiEditorEnabled, ! isGUIEditorEnabled()); +} + void ProjucerApplication::showAboutWindow() { if (aboutWindow != nullptr) @@ -1275,22 +1296,6 @@ void ProjucerApplication::showAboutWindow() 500, 300, 500, 300, 500, 300); } -void ProjucerApplication::showApplicationUsageDataAgreementPopup() -{ - if (applicationUsageDataWindow != nullptr) - applicationUsageDataWindow->toFront (true); - else - new FloatingToolWindow ("Application Usage Analytics", {}, - new ApplicationUsageDataWindowComponent (isPaidOrGPL()), applicationUsageDataWindow, false, - 400, 300, 400, 300, 400, 300); -} - -void ProjucerApplication::dismissApplicationUsageDataAgreementPopup() -{ - if (applicationUsageDataWindow != nullptr) - applicationUsageDataWindow.reset(); -} - void ProjucerApplication::showPathsWindow (bool highlightJUCEPath) { if (pathsWindow != nullptr) @@ -1357,6 +1362,26 @@ void ProjucerApplication::launchTutorialsBrowser() tutorialsLink.launchInDefaultBrowser(); } +void ProjucerApplication::doLoginOrLogout() +{ + if (licenseController->getCurrentState().isSignedIn()) + { + licenseController->resetState(); + } + else + { + if (auto* window = mainWindowList.getMainWindowWithLoginFormOpen()) + { + window->toFront (true); + } + else + { + mainWindowList.createWindowIfNoneAreOpen(); + mainWindowList.getFrontmostWindow()->showLoginFormOverlay(); + } + } +} + //============================================================================== struct FileWithTime { @@ -1413,13 +1438,6 @@ PropertiesFile::Options ProjucerApplication::getPropertyFileOptionsFor (const St return options; } -void ProjucerApplication::updateAllBuildTabs() -{ - for (int i = 0; i < mainWindowList.windows.size(); ++i) - if (ProjectContentComponent* p = mainWindowList.windows.getUnchecked(i)->getProjectContentComponent()) - p->rebuildProjectTabs(); -} - void ProjucerApplication::initCommandManager() { commandManager.reset (new ApplicationCommandManager()); @@ -1434,79 +1452,42 @@ void ProjucerApplication::initCommandManager() registerGUIEditorCommands(); } -void ProjucerApplication::setAnalyticsEnabled (bool enabled) +static void rescanModules (AvailableModulesList& list, const Array<File>& paths, bool async) { - resetAnalytics(); - - if (enabled) - setupAnalytics(); + if (async) + list.scanPathsAsync (paths); + else + list.scanPaths (paths); } -void ProjucerApplication::resetAnalytics() noexcept +void ProjucerApplication::rescanJUCEPathModules() { - auto analyticsInstance = Analytics::getInstance(); - - analyticsInstance->setUserId ({}); - analyticsInstance->setUserProperties ({}); - analyticsInstance->getDestinations().clear(); + rescanModules (jucePathModulesList, { getAppSettings().getStoredPath (Ids::defaultJuceModulePath, TargetOS::getThisOS()).get().toString() }, ! isRunningCommandLine); } -void ProjucerApplication::setupAnalytics() +void ProjucerApplication::rescanUserPathModules() { - Analytics::getInstance()->addDestination (new ProjucerAnalyticsDestination()); - - auto deviceString = SystemStats::getDeviceIdentifiers().joinIntoString (":"); - auto deviceIdentifier = String::toHexString (deviceString.hashCode64()); - - Analytics::getInstance()->setUserId (deviceIdentifier); - - StringPairArray userData; - userData.set ("cd1", getApplicationName()); - userData.set ("cd2", getApplicationVersion()); - userData.set ("cd3", SystemStats::getDeviceDescription()); - userData.set ("cd4", deviceString); - userData.set ("cd5", SystemStats::getOperatingSystemName()); - - Analytics::getInstance()->setUserProperties (userData); + rescanModules (userPathsModulesList, { getAppSettings().getStoredPath (Ids::defaultUserModulePath, TargetOS::getThisOS()).get().toString() }, ! isRunningCommandLine); } -void ProjucerApplication::showSetJUCEPathAlert() +bool ProjucerApplication::isAutomaticVersionCheckingEnabled() const { - auto& lf = Desktop::getInstance().getDefaultLookAndFeel(); - pathAlert.reset (lf.createAlertWindow ("Set JUCE Path", "Your global JUCE path is invalid. This path is used to access the JUCE examples and demo project - " - "would you like to set it now?", - "Set path", "Cancel", "Don't ask again", - AlertWindow::WarningIcon, 3, - mainWindowList.getFrontmostWindow (false))); - - pathAlert->enterModalState (true, ModalCallbackFunction::create ([this] (int retVal) - { - pathAlert.reset (nullptr); - - if (retVal == 1) - showPathsWindow (true); - else if (retVal == 0) - settings->setDontAskAboutJUCEPathAgain(); - })); - + return ! getGlobalProperties().getBoolValue (Ids::dontQueryForUpdate); } -void rescanModules (AvailableModuleList& list, const Array<File>& paths, bool async) +void ProjucerApplication::setAutomaticVersionCheckingEnabled (bool enabled) { - if (async) - list.scanPathsAsync (paths); - else - list.scanPaths (paths); + getGlobalProperties().setValue (Ids::dontQueryForUpdate, ! enabled); } -void ProjucerApplication::rescanJUCEPathModules() +bool ProjucerApplication::shouldPromptUserAboutIncorrectJUCEPath() const { - rescanModules (jucePathModuleList, { getAppSettings().getStoredPath (Ids::defaultJuceModulePath, TargetOS::getThisOS()).get().toString() }, ! isRunningCommandLine); + return ! getGlobalProperties().getBoolValue (Ids::dontAskAboutJUCEPath); } -void ProjucerApplication::rescanUserPathModules() +void ProjucerApplication::setShouldPromptUserAboutIncorrectJUCEPath (bool shouldPrompt) { - rescanModules (userPathsModuleList, { getAppSettings().getStoredPath (Ids::defaultUserModulePath, TargetOS::getThisOS()).get().toString() }, ! isRunningCommandLine); + getGlobalProperties().setValue (Ids::dontAskAboutJUCEPath, ! shouldPrompt); } void ProjucerApplication::selectEditorColourSchemeWithName (const String& schemeName) @@ -1536,7 +1517,6 @@ void ProjucerApplication::setColourScheme (int index, bool saveSetting) if (utf8Window != nullptr) utf8Window->sendLookAndFeelChange(); if (svgPathWindow != nullptr) svgPathWindow->sendLookAndFeelChange(); if (aboutWindow != nullptr) aboutWindow->sendLookAndFeelChange(); - if (applicationUsageDataWindow != nullptr) applicationUsageDataWindow->sendLookAndFeelChange(); if (pathsWindow != nullptr) pathsWindow->sendLookAndFeelChange(); if (editorColourSchemeWindow != nullptr) editorColourSchemeWindow->sendLookAndFeelChange(); if (pipCreatorWindow != nullptr) pipCreatorWindow->sendLookAndFeelChange(); @@ -1547,7 +1527,7 @@ void ProjucerApplication::setColourScheme (int index, bool saveSetting) if (saveSetting) { - auto& properties = settings->getGlobalProperties(); + auto& properties = getGlobalProperties(); properties.setValue ("COLOUR SCHEME", index); } @@ -1567,7 +1547,7 @@ void ProjucerApplication::setEditorColourScheme (int index, bool saveSetting) if (saveSetting) { - auto& properties = settings->getGlobalProperties(); + auto& properties = getGlobalProperties(); properties.setValue ("EDITOR COLOUR SCHEME", index); } @@ -1576,13 +1556,13 @@ void ProjucerApplication::setEditorColourScheme (int index, bool saveSetting) getCommandManager().commandStatusChanged(); } -bool ProjucerApplication::isEditorColourSchemeADefaultScheme (const StringArray& schemes, int editorColourSchemeIndex) +static bool isEditorColourSchemeADefaultScheme (const StringArray& schemes, int editorColourSchemeIndex) { auto& schemeName = schemes[editorColourSchemeIndex]; return (schemeName == "Default (Dark)" || schemeName == "Default (Light)"); } -int ProjucerApplication::getEditorColourSchemeForGUIColourScheme (const StringArray& schemes, int guiColourSchemeIndex) +static int getEditorColourSchemeForGUIColourScheme (const StringArray& schemes, int guiColourSchemeIndex) { auto defaultDarkEditorIndex = schemes.indexOf ("Default (Dark)"); auto defaultLightEditorIndex = schemes.indexOf ("Default (Light)"); diff --git a/extras/Projucer/Source/Application/jucer_Application.h b/extras/Projucer/Source/Application/jucer_Application.h index 3552ef53..038b4ac0 100644 --- a/extras/Projucer/Source/Application/jucer_Application.h +++ b/extras/Projucer/Source/Application/jucer_Application.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -26,41 +25,31 @@ #pragma once +#include "UserAccount/jucer_LicenseController.h" #include "jucer_MainWindow.h" -#include "../Project/jucer_Module.h" +#include "../Project/Modules/jucer_Modules.h" #include "jucer_AutoUpdater.h" #include "../CodeEditor/jucer_SourceCodeEditor.h" #include "../Utility/UI/jucer_ProjucerLookAndFeel.h" -#include "../Licenses/jucer_LicenseController.h" - -#if JUCE_MODULE_AVAILABLE_juce_analytics - #include "jucer_ProjucerAnalytics.h" -#endif struct ChildProcessCache; //============================================================================== class ProjucerApplication : public JUCEApplication, - private AsyncUpdater, - private LicenseController::StateChangedCallback + private AsyncUpdater { public: - ProjucerApplication(); + ProjucerApplication() = default; static ProjucerApplication& getApp(); static ApplicationCommandManager& getCommandManager(); //============================================================================== void initialise (const String& commandLine) override; - void initialiseBasics(); - bool initialiseLogger (const char* filePrefix); - void initialiseWindows (const String& commandLine); - void shutdown() override; void systemRequestedQuit() override; void deleteLogger(); - //============================================================================== const String getApplicationName() override { return "Projucer"; } const String getApplicationVersion() override { return ProjectInfo::versionString; } @@ -71,79 +60,38 @@ public: //============================================================================== MenuBarModel* getMenuModel(); - StringArray getMenuNames(); - void createMenu (PopupMenu&, const String& menuName); - void createFileMenu (PopupMenu&); - void createEditMenu (PopupMenu&); - void createViewMenu (PopupMenu&); - void createBuildMenu (PopupMenu&); - void createColourSchemeItems (PopupMenu&); - void createWindowMenu (PopupMenu&); - void createDocumentMenu (PopupMenu&); - void createToolsMenu (PopupMenu&); - void createHelpMenu (PopupMenu&); - void createExtraAppleMenuItems (PopupMenu&); - void handleMainMenuCommand (int menuItemID); - //============================================================================== void getAllCommands (Array<CommandID>&) override; void getCommandInfo (CommandID commandID, ApplicationCommandInfo&) override; bool perform (const InvocationInfo&) override; + bool isLiveBuildEnabled() const; + bool isGUIEditorEnabled() const; + //============================================================================== - void createNewProject(); - void createNewProjectFromClipboard(); - void createNewPIP(); - void askUserToOpenFile(); bool openFile (const File&); - void saveAllDocuments(); - bool closeAllDocuments (bool askUserToSave); - bool closeAllMainWindows(); - void closeAllMainWindowsAndQuitIfNeeded(); - void clearRecentFiles(); - + void showPathsWindow (bool highlightJUCEPath = false); PropertiesFile::Options getPropertyFileOptionsFor (const String& filename, bool isProjectSettings); + void selectEditorColourSchemeWithName (const String& schemeName); //============================================================================== - void showUTF8ToolWindow(); - void showSVGPathDataToolWindow(); - - void showAboutWindow(); - void showApplicationUsageDataAgreementPopup(); - void dismissApplicationUsageDataAgreementPopup(); - - void showPathsWindow (bool highlightJUCEPath = false); - void showEditorColourSchemeWindow(); - - void showPIPCreatorWindow(); - - void launchForumBrowser(); - void launchModulesBrowser(); - void launchClassesBrowser(); - void launchTutorialsBrowser(); + void rescanJUCEPathModules(); + void rescanUserPathModules(); - void updateAllBuildTabs(); + AvailableModulesList& getJUCEPathModulesList() { return jucePathModulesList; } + AvailableModulesList& getUserPathsModulesList() { return userPathsModulesList; } - //============================================================================== - void licenseStateChanged (const LicenseState&) override; - void doLogout(); + LicenseController& getLicenseController() { return *licenseController; } - bool isPaidOrGPL() const { return licenseController == nullptr || licenseController->getState().isPaidOrGPL(); } + bool isAutomaticVersionCheckingEnabled() const; + void setAutomaticVersionCheckingEnabled (bool shouldBeEnabled); - //============================================================================== - void selectEditorColourSchemeWithName (const String& schemeName); - static bool isEditorColourSchemeADefaultScheme (const StringArray& schemes, int editorColourSchemeIndex); - static int getEditorColourSchemeForGUIColourScheme (const StringArray& schemes, int guiColourSchemeIndex); + bool shouldPromptUserAboutIncorrectJUCEPath() const; + void setShouldPromptUserAboutIncorrectJUCEPath (bool shouldPrompt); - //============================================================================== - void setAnalyticsEnabled (bool); - - //============================================================================== - void rescanJUCEPathModules(); - void rescanUserPathModules(); - - AvailableModuleList& getJUCEPathModuleList() { return jucePathModuleList; } - AvailableModuleList& getUserPathsModuleList() { return userPathsModuleList; } + static File getJUCEExamplesDirectoryPathFromGlobal() noexcept; + static Array<File> getSortedExampleDirectories() noexcept; + static Array<File> getSortedExampleFilesInDirectory (const File&) noexcept; //============================================================================== ProjucerLookAndFeel lookAndFeel; @@ -158,24 +106,43 @@ public: OpenDocumentManager openDocumentManager; std::unique_ptr<ApplicationCommandManager> commandManager; - std::unique_ptr<Component> utf8Window, svgPathWindow, aboutWindow, applicationUsageDataWindow, - pathsWindow, editorColourSchemeWindow, pipCreatorWindow; - - std::unique_ptr<FileLogger> logger; - - bool isRunningCommandLine; + bool isRunningCommandLine = false; std::unique_ptr<ChildProcessCache> childProcessCache; - std::unique_ptr<LicenseController> licenseController; private: //============================================================================== void handleAsyncUpdate() override; + void doBasicApplicationSetup(); + void initCommandManager(); + bool initialiseLogger (const char* filePrefix); + void initialiseWindows (const String& commandLine); + + void createNewProject(); + void createNewProjectFromClipboard(); + void createNewPIP(); + void askUserToOpenFile(); + void saveAllDocuments(); + bool closeAllDocuments (OpenDocumentManager::SaveIfNeeded askUserToSave); + bool closeAllMainWindows(); + void closeAllMainWindowsAndQuitIfNeeded(); + void clearRecentFiles(); + + StringArray getMenuNames(); + PopupMenu createMenu (const String& menuName); + PopupMenu createFileMenu(); + PopupMenu createEditMenu(); + PopupMenu createViewMenu(); + PopupMenu createBuildMenu(); + void createColourSchemeItems (PopupMenu&); + PopupMenu createWindowMenu(); + PopupMenu createDocumentMenu(); + PopupMenu createToolsMenu(); + PopupMenu createHelpMenu(); + PopupMenu createExtraAppleMenuItems(); + void handleMainMenuCommand (int menuItemID); + PopupMenu createExamplesPopupMenu() noexcept; - void createExamplesPopupMenu (PopupMenu&) noexcept; - Array<File> getSortedExampleDirectories() noexcept; - Array<File> getSortedExampleFilesInDirectory (const File&) const noexcept; - bool findWindowAndOpenPIP (const File&); void findAndLaunchExample (int); void checkIfGlobalJUCEPathHasChanged(); @@ -183,25 +150,74 @@ private: File tryToFindDemoRunnerProject(); void launchDemoRunner(); - void resetAnalytics() noexcept; - void setupAnalytics(); - - void showSetJUCEPathAlert(); - void setColourScheme (int index, bool saveSetting); void setEditorColourScheme (int index, bool saveSetting); void updateEditorColourSchemeIfNeeded(); + void showUTF8ToolWindow(); + void showSVGPathDataToolWindow(); + void showAboutWindow(); + void showEditorColourSchemeWindow(); + void showPIPCreatorWindow(); + + void launchForumBrowser(); + void launchModulesBrowser(); + void launchClassesBrowser(); + void launchTutorialsBrowser(); + + void doLoginOrLogout(); + void showLoginForm(); + + void enableOrDisableLiveBuild(); + void enableOrDisableGUIEditor(); + + //============================================================================== + #if JUCE_MAC + class AppleMenuRebuildListener : private MenuBarModel::Listener + { + public: + AppleMenuRebuildListener() + { + if (auto* model = ProjucerApplication::getApp().getMenuModel()) + model->addListener (this); + } + + ~AppleMenuRebuildListener() override + { + if (auto* model = ProjucerApplication::getApp().getMenuModel()) + model->removeListener (this); + } + + private: + void menuBarItemsChanged (MenuBarModel*) override {} + + void menuCommandInvoked (MenuBarModel*, + const ApplicationCommandTarget::InvocationInfo& info) override + { + if (info.commandID == CommandIDs::enableNewVersionCheck) + Timer::callAfterDelay (50, [] { ProjucerApplication::getApp().rebuildAppleMenu(); }); + } + }; + + void rebuildAppleMenu(); + + std::unique_ptr<AppleMenuRebuildListener> appleMenuRebuildListener; + #endif + //============================================================================== + std::unique_ptr<LicenseController> licenseController; + void* server = nullptr; + std::unique_ptr<TooltipWindow> tooltipWindow; + AvailableModulesList jucePathModulesList, userPathsModulesList; - TooltipWindow tooltipWindow; + std::unique_ptr<Component> utf8Window, svgPathWindow, aboutWindow, pathsWindow, + editorColourSchemeWindow, pipCreatorWindow; - AvailableModuleList jucePathModuleList, userPathsModuleList; + std::unique_ptr<FileLogger> logger; int numExamples = 0; std::unique_ptr<AlertWindow> demoRunnerAlert; - std::unique_ptr<AlertWindow> pathAlert; bool hasScannedForDemoRunnerExecutable = false, hasScannedForDemoRunnerProject = false; File lastJUCEPath, lastDemoRunnerExectuableFile, lastDemoRunnerProjectFile; #if JUCE_LINUX diff --git a/extras/Projucer/Source/Application/jucer_AutoUpdater.cpp b/extras/Projucer/Source/Application/jucer_AutoUpdater.cpp index 94e8eb72..d1720105 100644 --- a/extras/Projucer/Source/Application/jucer_AutoUpdater.cpp +++ b/extras/Projucer/Source/Application/jucer_AutoUpdater.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -36,15 +35,15 @@ LatestVersionCheckerAndUpdater::LatestVersionCheckerAndUpdater() LatestVersionCheckerAndUpdater::~LatestVersionCheckerAndUpdater() { - stopThread (1000); + stopThread (6000); clearSingletonInstance(); } -void LatestVersionCheckerAndUpdater::checkForNewVersion (bool showAlerts) +void LatestVersionCheckerAndUpdater::checkForNewVersion (bool background) { if (! isThreadRunning()) { - showAlertWindows = showAlerts; + backgroundCheck = background; startThread (3); } } @@ -56,7 +55,7 @@ void LatestVersionCheckerAndUpdater::run() if (info == nullptr) { - if (showAlertWindows) + if (! backgroundCheck) AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon, "Update Server Communication Error", "Failed to communicate with the JUCE update server.\n" @@ -68,7 +67,7 @@ void LatestVersionCheckerAndUpdater::run() if (! info->isNewerVersionThanCurrent()) { - if (showAlertWindows) + if (! backgroundCheck) AlertWindow::showMessageBoxAsync (AlertWindow::InfoIcon, "No New Version Available", "Your JUCE version is up to date."); @@ -107,7 +106,7 @@ void LatestVersionCheckerAndUpdater::run() } } - if (showAlertWindows) + if (! backgroundCheck) AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon, "Failed to find any new downloads", "Please try again in a few minutes."); @@ -145,15 +144,11 @@ public: addAndMakeVisible (cancelButton); cancelButton.onClick = [this] { - if (dontAskAgainButton.getToggleState()) - getGlobalProperties().setValue (Ids::dontQueryForUpdate.toString(), 1); - else - getGlobalProperties().removeValue (Ids::dontQueryForUpdate); - + ProjucerApplication::getApp().setAutomaticVersionCheckingEnabled (! dontAskAgainButton.getToggleState()); exitModalStateWithResult (-1); }; - dontAskAgainButton.setToggleState (getGlobalProperties().getValue (Ids::dontQueryForUpdate, {}).isNotEmpty(), dontSendNotification); + dontAskAgainButton.setToggleState (! ProjucerApplication::getApp().isAutomaticVersionCheckingEnabled(), dontSendNotification); addAndMakeVisible (dontAskAgainButton); juceIcon = Drawable::createFromImageData (BinaryData::juce_icon_png, @@ -295,10 +290,21 @@ void LatestVersionCheckerAndUpdater::askUserForLocationToDownload (const Version void LatestVersionCheckerAndUpdater::askUserAboutNewVersion (const String& newVersionString, const String& releaseNotes, const VersionInfo::Asset& asset) +{ + if (backgroundCheck) + addNotificationToOpenProjects (asset); + else + showDialogWindow (newVersionString, releaseNotes, asset); +} + +void LatestVersionCheckerAndUpdater::showDialogWindow (const String& newVersionString, + const String& releaseNotes, + const VersionInfo::Asset& asset) { dialogWindow = UpdateDialog::launchDialog (newVersionString, releaseNotes); if (auto* mm = ModalComponentManager::getInstance()) + { mm->attachCallback (dialogWindow.get(), ModalCallbackFunction::create ([this, asset] (int result) { @@ -307,6 +313,35 @@ void LatestVersionCheckerAndUpdater::askUserAboutNewVersion (const String& newVe dialogWindow.reset(); })); + } +} + +void LatestVersionCheckerAndUpdater::addNotificationToOpenProjects (const VersionInfo::Asset& asset) +{ + for (auto* window : ProjucerApplication::getApp().mainWindowList.windows) + { + if (auto* project = window->getProject()) + { + Component::SafePointer<MainWindow> safeWindow (window); + + auto ignore = [safeWindow] + { + if (safeWindow != nullptr) + safeWindow->getProject()->removeProjectMessage (ProjectMessages::Ids::newVersionAvailable); + }; + + auto dontAskAgain = [ignore] + { + ignore(); + ProjucerApplication::getApp().setAutomaticVersionCheckingEnabled (false); + }; + + project->addProjectMessage (ProjectMessages::Ids::newVersionAvailable, + { { "Download", [this, asset] { askUserForLocationToDownload (asset); } }, + { "Ignore", std::move (ignore) }, + { "Don't ask again", std::move (dontAskAgain) } }); + } + } } //============================================================================== @@ -384,7 +419,7 @@ private: struct ScopedDownloadFolder { - ScopedDownloadFolder (const File& installTargetFolder) + explicit ScopedDownloadFolder (const File& installTargetFolder) { folder = installTargetFolder.getSiblingFile (installTargetFolder.getFileNameWithoutExtension() + "_download").getNonexistentSibling(); jassert (folder.createDirectory()); @@ -464,7 +499,7 @@ private: std::function<void()> completionCallback; }; -void restartProcess (const File& targetFolder) +static void restartProcess (const File& targetFolder) { #if JUCE_MAC || JUCE_LINUX #if JUCE_MAC diff --git a/extras/Projucer/Source/Application/jucer_AutoUpdater.h b/extras/Projucer/Source/Application/jucer_AutoUpdater.h index 2f4b288b..1e9e1abb 100644 --- a/extras/Projucer/Source/Application/jucer_AutoUpdater.h +++ b/extras/Projucer/Source/Application/jucer_AutoUpdater.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -37,7 +36,7 @@ public: LatestVersionCheckerAndUpdater(); ~LatestVersionCheckerAndUpdater() override; - void checkForNewVersion (bool showAlerts); + void checkForNewVersion (bool isBackgroundCheck); //============================================================================== JUCE_DECLARE_SINGLETON_SINGLETHREADED_MINIMAL (LatestVersionCheckerAndUpdater) @@ -49,8 +48,11 @@ private: void askUserForLocationToDownload (const VersionInfo::Asset&); void downloadAndInstall (const VersionInfo::Asset&, const File&); + void showDialogWindow (const String&, const String&, const VersionInfo::Asset&); + void addNotificationToOpenProjects (const VersionInfo::Asset&); + //============================================================================== - bool showAlertWindows = false; + bool backgroundCheck = false; std::unique_ptr<DownloadAndInstallThread> installer; std::unique_ptr<Component> dialogWindow; diff --git a/extras/Projucer/Source/Application/jucer_CommandIDs.h b/extras/Projucer/Source/Application/jucer_CommandIDs.h index fad09c27..14e6e2a2 100644 --- a/extras/Projucer/Source/Application/jucer_CommandIDs.h +++ b/extras/Projucer/Source/Application/jucer_CommandIDs.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -55,8 +54,10 @@ namespace CommandIDs showTranslationTool = 0x300022, showSVGPathTool = 0x300023, showAboutWindow = 0x300024, - showAppUsageWindow = 0x300025, - checkForNewVersion = 0x300026, + checkForNewVersion = 0x300025, + enableNewVersionCheck = 0x300026, + enableLiveBuild = 0x300027, + enableGUIEditor = 0x300028, showProjectSettings = 0x300030, showProjectTab = 0x300031, @@ -107,6 +108,8 @@ namespace CommandIDs showAPIClasses = 0x300102, showTutorials = 0x300103, + addNewGUIFile = 0x300200, + lastCommandIDEntry }; } diff --git a/extras/Projucer/Source/Application/jucer_CommandLine.cpp b/extras/Projucer/Source/Application/jucer_CommandLine.cpp index fcef733b..bd23f67a 100644 --- a/extras/Projucer/Source/Application/jucer_CommandLine.cpp +++ b/extras/Projucer/Source/Application/jucer_CommandLine.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -48,7 +47,7 @@ namespace { Array<File> files; - for (DirectoryIterator di (folder, true, "*.cpp;*.cxx;*.cc;*.c;*.h;*.hpp;*.hxx;*.hpp;*.mm;*.m;*.java;*.dox;*.soul;*.js", File::findFiles); di.next();) + for (const auto& di : RangedDirectoryIterator (folder, true, "*.cpp;*.cxx;*.cc;*.c;*.h;*.hpp;*.hxx;*.hpp;*.mm;*.m;*.java;*.dox;*.soul;*.js", File::findFiles)) if (! di.getFile().isSymbolicLink()) files.add (di.getFile()); @@ -71,7 +70,7 @@ namespace //============================================================================== struct LoadedProject { - LoadedProject (const ArgumentList::Argument& fileToLoad) + explicit LoadedProject (const ArgumentList::Argument& fileToLoad) { hideDockIcon(); @@ -82,7 +81,7 @@ namespace project.reset (new Project (projectFile)); - if (! project->loadFrom (projectFile, true)) + if (! project->loadFrom (projectFile, true, false)) { project.reset(); ConsoleApplication::fail ("Failed to load the project file: " + projectFile.getFullPathName()); @@ -91,15 +90,18 @@ namespace preferredLineFeed = project->getProjectLineFeed().toRawUTF8(); } - void save (bool justSaveResources) + void save (bool justSaveResources, bool fixMissingDependencies) { if (project != nullptr) { if (! justSaveResources) rescanModulePathsIfNecessary(); - auto error = justSaveResources ? project->saveResourcesOnly (project->getFile()) - : project->saveProject (project->getFile(), true); + if (fixMissingDependencies) + tryToFixMissingModuleDependencies(); + + auto error = justSaveResources ? project->saveResourcesOnly() + : project->saveProject(); project.reset(); @@ -137,6 +139,14 @@ namespace ProjucerApplication::getApp().rescanUserPathModules(); } + void tryToFixMissingModuleDependencies() + { + auto& modules = project->getEnabledModules(); + + for (const auto& m : modules.getModulesWithMissingDependencies()) + modules.tryToFixMissingDependencies (m); + } + std::unique_ptr<Project> project; }; @@ -153,7 +163,7 @@ namespace : "Re-saving file: ") << proj.project->getFile().getFullPathName() << std::endl; - proj.save (justSaveResources); + proj.save (justSaveResources, args.containsOption ("--fix-missing-dependencies")); } //============================================================================== @@ -176,7 +186,7 @@ namespace std::cout << "Setting project version: " << version << std::endl; proj.project->setProjectVersion (version); - proj.save (false); + proj.save (false, false); } //============================================================================== @@ -193,7 +203,7 @@ namespace std::cout << "Bumping project version to: " << version << std::endl; proj.project->setProjectVersion (version); - proj.save (false); + proj.save (false, false); } static void gitTag (const ArgumentList& args) @@ -230,7 +240,6 @@ namespace //============================================================================== static void showStatus (const ArgumentList& args) { - hideDockIcon(); args.checkMinNumArguments (2); LoadedProject proj (args[1]); @@ -239,7 +248,7 @@ namespace << "Name: " << proj.project->getProjectNameString() << std::endl << "UID: " << proj.project->getProjectUIDString() << std::endl; - EnabledModuleList& modules = proj.project->getEnabledModules(); + auto& modules = proj.project->getEnabledModules(); if (int numModules = modules.getNumModules()) { @@ -271,9 +280,7 @@ namespace ZipFile::Builder zip; { - DirectoryIterator i (moduleFolder, true, "*", File::findFiles); - - while (i.next()) + for (const auto& i : RangedDirectoryIterator (moduleFolder, true, "*", File::findFiles)) if (! i.getFile().isHidden()) zip.addFile (i.getFile(), 9, i.getFile().getRelativePathFrom (moduleFolderParent)); } @@ -306,10 +313,9 @@ namespace if (buildAllWithIndex) { auto folderToSearch = args[2].resolveAsFile(); - DirectoryIterator i (folderToSearch, false, "*", File::findDirectories); var infoList; - while (i.next()) + for (const auto& i : RangedDirectoryIterator (folderToSearch, false, "*", File::findDirectories)) { LibraryModule module (i.getFile()); @@ -319,7 +325,7 @@ namespace var moduleInfo (new DynamicObject()); moduleInfo.getDynamicObject()->setProperty ("file", getModulePackageName (module)); - moduleInfo.getDynamicObject()->setProperty ("info", module.moduleInfo.moduleInfo); + moduleInfo.getDynamicObject()->setProperty ("info", module.moduleInfo.getModuleInfo()); infoList.append (moduleInfo); } } @@ -346,8 +352,14 @@ namespace { auto content = file.loadFileAsString(); - if (content.contains ("%""%") && content.contains ("//[")) - return; // ignore projucer GUI template files + auto isProjucerTemplateFile = [file, content] + { + return file.getFullPathName().contains ("Templates") + && content.contains ("%""%") && content.contains ("//["); + }(); + + if (isProjucerTemplateFile) + return; StringArray lines; lines.addLines (content); @@ -421,7 +433,7 @@ namespace files.add (target); for (int i = 0; i < files.size(); ++i) - cleanWhitespace (files.getReference(i), options); + cleanWhitespace (files.getReference (i), options); } } @@ -637,11 +649,11 @@ namespace MemoryBlock data; FileInputStream input (source); input.readIntoMemoryBlock (data); - CodeHelpers::writeDataAsCppLiteral (data, literal, true, true); + build_tools::writeDataAsCppLiteral (data, literal, true, true); dataSize = data.getSize(); } - auto variableName = CodeHelpers::makeBinaryDataIdentifierName (source); + auto variableName = build_tools::makeBinaryDataIdentifierName (source); MemoryOutputStream header, cpp; @@ -698,8 +710,8 @@ namespace static bool isValidPathIdentifier (const String& id, const String& os) { - return id == "vst3Path" || id == "vstLegacyPath" || (id == "aaxPath" && os != "linux") || (id == "rtasPath" && os != "linux") - || id == "androidSDKPath" || id == "androidNDKPath" || id == "defaultJuceModulePath" || id == "defaultUserModulePath"; + return id == "vstLegacyPath" || (id == "aaxPath" && os != "linux") || (id == "rtasPath" && os != "linux") + || id == "androidSDKPath" || id == "defaultJuceModulePath" || id == "defaultUserModulePath"; } static void setGlobalPath (const ArgumentList& args) @@ -808,7 +820,7 @@ namespace << "Usage: " << std::endl << std::endl << " " << appName << " --resave project_file" << std::endl - << " Resaves all files and resources in a project." << std::endl + << " Resaves all files and resources in a project. Add the \"--fix-missing-dependencies\" option to automatically fix any missing module dependencies." << std::endl << std::endl << " " << appName << " --resave-resources project_file" << std::endl << " Resaves just the binary resources for a project." << std::endl @@ -860,7 +872,7 @@ namespace << std::endl << " " << appName << " --set-global-search-path os identifier_to_set new_path" << std::endl << " Sets the global path for a specified os and identifier. The os should be either osx, windows or linux and the identifiers can be any of the following: " - << "defaultJuceModulePath, defaultUserModulePath, vst3Path, vstLegacyPath, aaxPath (not valid on linux), rtasPath (not valid on linux), androidSDKPath or androidNDKPath. " << std::endl + << "defaultJuceModulePath, defaultUserModulePath, vstLegacyPath, aaxPath (not valid on linux), rtasPath (not valid on linux), or androidSDKPath. " << std::endl << std::endl << " " << appName << " --create-project-from-pip path/to/PIP path/to/output path/to/JUCE/modules (optional) path/to/user/modules (optional)" << std::endl << " Generates a folder containing a JUCE project in the specified output path using the specified PIP file. Use the optional JUCE and user module paths to override " @@ -874,7 +886,7 @@ namespace //============================================================================== int performCommandLine (const ArgumentList& args) { - return ConsoleApplication::invokeCatchingFailures ([&] () -> int + return ConsoleApplication::invokeCatchingFailures ([&]() -> int { if (args.containsOption ("--lf")) preferredLineFeed = "\n"; diff --git a/extras/Projucer/Source/Application/jucer_CommandLine.h b/extras/Projucer/Source/Application/jucer_CommandLine.h index 455879d2..467ef18a 100644 --- a/extras/Projucer/Source/Application/jucer_CommandLine.h +++ b/extras/Projucer/Source/Application/jucer_CommandLine.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/Application/jucer_CommonHeaders.h b/extras/Projucer/Source/Application/jucer_CommonHeaders.h index a74f655f..fac5ce53 100644 --- a/extras/Projucer/Source/Application/jucer_CommonHeaders.h +++ b/extras/Projucer/Source/Application/jucer_CommonHeaders.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -28,6 +27,11 @@ //============================================================================== +// The GCC extensions define linux somewhere in the headers, so undef it here... +#if JUCE_GCC + #undef linux +#endif + struct TargetOS { enum OS @@ -60,7 +64,6 @@ typedef TargetOS::OS DependencyPathOS; #include "../Utility/Helpers/jucer_MiscUtilities.h" #include "../Utility/Helpers/jucer_CodeHelpers.h" #include "../Utility/Helpers/jucer_FileHelpers.h" -#include "../Utility/Helpers/jucer_RelativePath.h" #include "../Utility/Helpers/jucer_ValueSourceHelpers.h" #include "../Utility/Helpers/jucer_PresetIDs.h" #include "jucer_CommandIDs.h" @@ -91,3 +94,6 @@ enum ColourIds widgetBackgroundColourId = 0x2340010, secondaryWidgetBackgroundColourId = 0x2340011, }; + +//============================================================================== +static constexpr int projucerMajorVersion = ProjectInfo::versionNumber >> 16; diff --git a/extras/Projucer/Source/Application/jucer_Headers.h b/extras/Projucer/Source/Application/jucer_Headers.h index b96a1bbf..2d73570b 100644 --- a/extras/Projucer/Source/Application/jucer_Headers.h +++ b/extras/Projucer/Source/Application/jucer_Headers.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/Application/jucer_Main.cpp b/extras/Projucer/Source/Application/jucer_Main.cpp index 85e03382..0bc46595 100644 --- a/extras/Projucer/Source/Application/jucer_Main.cpp +++ b/extras/Projucer/Source/Application/jucer_Main.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -30,11 +29,11 @@ #include "../CodeEditor/jucer_OpenDocumentManager.h" #include "../CodeEditor/jucer_SourceCodeEditor.h" #include "../Utility/UI/PropertyComponents/jucer_FilePathPropertyComponent.h" +#include "../Project/UI/jucer_ProjectContentComponent.h" #include "../Project/UI/Sidebar/jucer_TreeItemTypes.h" #include "Windows/jucer_UTF8WindowComponent.h" #include "Windows/jucer_SVGPathDataWindowComponent.h" #include "Windows/jucer_AboutWindowComponent.h" -#include "Windows/jucer_ApplicationUsageDataWindowComponent.h" #include "Windows/jucer_EditorColourSchemeWindowComponent.h" #include "Windows/jucer_GlobalPathsWindowComponent.h" #include "Windows/jucer_PIPCreatorWindowComponent.h" diff --git a/extras/Projucer/Source/Application/jucer_MainWindow.cpp b/extras/Projucer/Source/Application/jucer_MainWindow.cpp index 8a10d2c0..ecbd7952 100644 --- a/extras/Projucer/Source/Application/jucer_MainWindow.cpp +++ b/extras/Projucer/Source/Application/jucer_MainWindow.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -27,9 +26,94 @@ #include "../Application/jucer_Headers.h" #include "jucer_Application.h" #include "jucer_MainWindow.h" -#include "../Wizards/jucer_NewProjectWizardClasses.h" +#include "StartPage/jucer_StartPageComponent.h" #include "../Utility/UI/jucer_JucerTreeViewBase.h" #include "../ProjectSaving/jucer_ProjectSaver.h" +#include "UserAccount/jucer_LoginFormComponent.h" +#include "../Project/UI/jucer_ProjectContentComponent.h" + +//============================================================================== +class BlurOverlayWithComponent : public Component, + private ComponentMovementWatcher, + private AsyncUpdater +{ +public: + BlurOverlayWithComponent (MainWindow& window, std::unique_ptr<Component> comp) + : ComponentMovementWatcher (&window), + mainWindow (window), + componentToShow (std::move (comp)) + { + kernel.createGaussianBlur (1.25f); + + addAndMakeVisible (*componentToShow); + + setAlwaysOnTop (true); + setOpaque (true); + setVisible (true); + + static_cast<Component&> (mainWindow).addChildComponent (this); + componentMovedOrResized (true, true); + } + + void resized() override + { + setBounds (mainWindow.getLocalBounds()); + componentToShow->centreWithSize (componentToShow->getWidth(), componentToShow->getHeight()); + refreshBackgroundImage(); + } + + void paint (Graphics& g) override + { + g.drawImage (componentImage, getLocalBounds().toFloat()); + } + +private: + void componentPeerChanged() override {} + + void componentVisibilityChanged() override {} + using ComponentMovementWatcher::componentVisibilityChanged; + + void componentMovedOrResized (bool, bool) override { triggerAsyncUpdate(); } + using ComponentMovementWatcher::componentMovedOrResized; + + void handleAsyncUpdate() override { resized(); } + + void mouseUp (const MouseEvent& event) override + { + if (event.eventComponent == this) + mainWindow.hideLoginFormOverlay(); + } + + void lookAndFeelChanged() override + { + refreshBackgroundImage(); + repaint(); + } + + void refreshBackgroundImage() + { + setVisible (false); + + auto parentBounds = mainWindow.getBounds(); + + componentImage = mainWindow.createComponentSnapshot (mainWindow.getLocalBounds()) + .rescaled (roundToInt ((float) parentBounds.getWidth() / 1.75f), + roundToInt ((float) parentBounds.getHeight() / 1.75f)); + + kernel.applyToImage (componentImage, componentImage, getLocalBounds()); + + setVisible (true); + } + + //============================================================================== + MainWindow& mainWindow; + std::unique_ptr<Component> componentToShow; + + ImageConvolutionKernel kernel { 3 }; + Image componentImage; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BlurOverlayWithComponent) +}; //============================================================================== MainWindow::MainWindow() @@ -40,6 +124,8 @@ MainWindow::MainWindow() false) { setUsingNativeTitleBar (true); + setResizable (true, false); + setResizeLimits (600, 500, 32000, 32000); #if ! JUCE_MAC setMenuBar (ProjucerApplication::getApp().getMenuModel()); @@ -47,9 +133,6 @@ MainWindow::MainWindow() createProjectContentCompIfNeeded(); - setResizable (true, false); - centreWithSize (800, 600); - auto& commandManager = ProjucerApplication::getCommandManager(); auto registerAllAppCommands = [&] @@ -73,9 +156,10 @@ MainWindow::MainWindow() setWantsKeyboardFocus (false); getLookAndFeel().setColour (ColourSelector::backgroundColourId, Colours::transparentBlack); + projectNameValue.addListener (this); - setResizeLimits (600, 500, 32000, 32000); + centreWithSize (800, 600); } MainWindow::~MainWindow() @@ -85,10 +169,11 @@ MainWindow::~MainWindow() #endif removeKeyListener (ProjucerApplication::getCommandManager().getKeyMappings()); + + // save the current size and position to our settings file.. getGlobalProperties().setValue ("lastMainWindowPos", getWindowStateAsString()); clearContentComponent(); - currentProject.reset(); } void MainWindow::createProjectContentCompIfNeeded() @@ -100,7 +185,7 @@ void MainWindow::createProjectContentCompIfNeeded() } } -void MainWindow::setTitleBarIcon() +void MainWindow::updateTitleBarIcon() { if (auto* peer = getPeer()) { @@ -121,7 +206,7 @@ void MainWindow::makeVisible() setVisible (true); addToDesktop(); restoreWindowPosition(); - setTitleBarIcon(); + updateTitleBarIcon(); getContentComponent()->grabKeyboardFocus(); } @@ -135,7 +220,7 @@ void MainWindow::closeButtonPressed() ProjucerApplication::getApp().mainWindowList.closeWindow (this); } -bool MainWindow::closeCurrentProject (bool askUserToSave) +bool MainWindow::closeCurrentProject (OpenDocumentManager::SaveIfNeeded askUserToSave) { if (currentProject == nullptr) return true; @@ -152,7 +237,8 @@ bool MainWindow::closeCurrentProject (bool askUserToSave) if (ProjucerApplication::getApp().openDocumentManager .closeAllDocumentsUsingProject (*currentProject, askUserToSave)) { - if (! askUserToSave || (currentProject->saveIfNeededAndUserAgrees() == FileBasedDocument::savedOk)) + if (askUserToSave == OpenDocumentManager::SaveIfNeeded::no + || (currentProject->saveIfNeededAndUserAgrees() == FileBasedDocument::savedOk)) { setProject (nullptr); return true; @@ -162,27 +248,21 @@ bool MainWindow::closeCurrentProject (bool askUserToSave) return false; } -void MainWindow::moveProject (File newProjectFileToOpen) +void MainWindow::moveProject (File newProjectFileToOpen, OpenInIDE openInIDE) { - auto openInIDE = currentProject->shouldOpenInIDEAfterSaving(); - - closeCurrentProject (false); + closeCurrentProject (OpenDocumentManager::SaveIfNeeded::no); openFile (newProjectFileToOpen); - if (currentProject != nullptr) - { - ProjucerApplication::getApp().getCommandManager().invokeDirectly (openInIDE ? CommandIDs::saveAndOpenInIDE - : CommandIDs::saveProject, - false); - } + if (currentProject != nullptr && openInIDE == OpenInIDE::yes) + ProjucerApplication::getApp().getCommandManager().invokeDirectly (CommandIDs::openInIDE, false); } void MainWindow::setProject (std::unique_ptr<Project> newProject) { if (newProject == nullptr) { - getProjectContentComponent()->setProject (nullptr); - projectNameValue.referTo (Value()); + if (auto* content = getProjectContentComponent()) + content->setProject (nullptr); currentProject.reset(); } @@ -192,12 +272,11 @@ void MainWindow::setProject (std::unique_ptr<Project> newProject) createProjectContentCompIfNeeded(); getProjectContentComponent()->setProject (currentProject.get()); - projectNameValue.referTo (currentProject->getProjectValue (Ids::name)); - - if (auto* peer = getPeer()) - peer->setRepresentedFile (currentProject->getFile()); } + projectNameValue.referTo (currentProject != nullptr ? currentProject->getProjectValue (Ids::name) : Value()); + initialiseProjectWindow(); + ProjucerApplication::getCommandManager().commandStatusChanged(); } @@ -223,19 +302,19 @@ bool MainWindow::canOpenFile (const File& file) const bool MainWindow::openFile (const File& file) { - createProjectContentCompIfNeeded(); - if (file.hasFileExtension (Project::projectFileExtension)) { auto newDoc = std::make_unique<Project> (file); auto result = newDoc->loadFrom (file, true); - if (result.wasOk() && closeCurrentProject (true)) + if (result.wasOk() && closeCurrentProject (OpenDocumentManager::SaveIfNeeded::yes)) { setProject (std::move (newDoc)); currentProject->setChangedFlag (false); + createProjectContentCompIfNeeded(); getProjectContentComponent()->reloadLastOpenDocuments(); + currentProject->updateDeprecatedProjectSettingsInteractively(); return true; @@ -243,16 +322,18 @@ bool MainWindow::openFile (const File& file) } else if (file.exists()) { + if (isPIPFile (file) && openPIP ({ file })) + return true; + + createProjectContentCompIfNeeded(); return getProjectContentComponent()->showEditorForFile (file, true); } return false; } -bool MainWindow::tryToOpenPIP (const File& pipFile) +bool MainWindow::openPIP (PIPGenerator generator) { - PIPGenerator generator (pipFile); - if (! generator.hasValidPIP()) return false; @@ -267,7 +348,6 @@ bool MainWindow::tryToOpenPIP (const File& pipFile) return false; } - if (! generator.createMainCpp()) { AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon, @@ -277,110 +357,43 @@ bool MainWindow::tryToOpenPIP (const File& pipFile) return false; } - if (! ProjucerApplication::getApp().mainWindowList.openFile (generator.getJucerFile())) - return false; - - openPIP (generator); - return true; -} - -static bool isDivider (const String& line) -{ - auto afterIndent = line.trim(); - - if (afterIndent.startsWith ("//") && afterIndent.length() > 20) + if (! openFile (generator.getJucerFile())) { - afterIndent = afterIndent.substring (2); + AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon, + "PIP Error.", + "Failed to open .jucer file."); - if (afterIndent.containsOnly ("=") - || afterIndent.containsOnly ("/") - || afterIndent.containsOnly ("-")) - { - return true; - } + return false; } - return false; + setupTemporaryPIPProject (generator); + return true; } -static bool isEndOfCommentBlock (const String& line) +void MainWindow::setupTemporaryPIPProject (PIPGenerator& generator) { - if (line.contains ("*/")) - return true; + jassert (currentProject != nullptr); - return false; -} + currentProject->setTemporaryDirectory (generator.getOutputDirectory()); -static int getIndexOfCommentBlockStart (const StringArray& lines, int blockEndIndex) -{ - for (int i = blockEndIndex; i >= 0; --i) - { - if (lines[i].contains ("/*")) - return i; - } - - return 0; -} + ProjectSaver liveBuildSaver (*currentProject); + liveBuildSaver.saveContentNeededForLiveBuild(); -static int findBestLineToScrollTo (StringArray lines, StringRef className) -{ - for (auto line : lines) + if (auto* pcc = getProjectContentComponent()) { - if (line.contains ("struct " + className) || line.contains ("class " + className)) - { - auto index = lines.indexOf (line); - - if (isDivider (lines[index - 1])) - return index - 1; - - if (isEndOfCommentBlock (lines[index - 1])) - { - auto blockStartIndex = getIndexOfCommentBlockStart (lines, index - 1); - - if (blockStartIndex > 0 && isDivider (lines [blockStartIndex - 1])) - return blockStartIndex - 1; - - return blockStartIndex; - } - - return lines.indexOf (line); - } - } + pcc->invokeDirectly (CommandIDs::toggleBuildEnabled, true); + pcc->invokeDirectly (CommandIDs::buildNow, true); + pcc->invokeDirectly (CommandIDs::toggleContinuousBuild, true); - return 0; -} + auto fileToDisplay = generator.getPIPFile(); -void MainWindow::openPIP (PIPGenerator& generator) -{ - if (auto* window = ProjucerApplication::getApp().mainWindowList.getMainWindowForFile (generator.getJucerFile())) - { - if (auto* project = window->getProject()) + if (fileToDisplay != File()) { - project->setTemporaryDirectory (generator.getOutputDirectory()); - - ProjectSaver liveBuildSaver (*project, project->getFile()); - liveBuildSaver.saveContentNeededForLiveBuild(); - - if (auto* pcc = window->getProjectContentComponent()) - { - pcc->invokeDirectly (CommandIDs::toggleBuildEnabled, true); - pcc->invokeDirectly (CommandIDs::buildNow, true); - pcc->invokeDirectly (CommandIDs::toggleContinuousBuild, true); - - auto fileToDisplay = generator.getPIPFile(); + pcc->showEditorForFile (fileToDisplay, true); - if (fileToDisplay != File()) - { - pcc->showEditorForFile (fileToDisplay, true); - - if (auto* sourceCodeEditor = dynamic_cast <SourceCodeEditor*> (pcc->getEditorComponent())) - { - sourceCodeEditor->editor->scrollToLine (findBestLineToScrollTo (StringArray::fromLines (fileToDisplay.loadFileAsString()), - generator.getMainClassName())); - } - } - - } + if (auto* sourceCodeEditor = dynamic_cast <SourceCodeEditor*> (pcc->getEditorComponent())) + sourceCodeEditor->editor->scrollToLine (findBestLineToScrollToForClass (StringArray::fromLines (fileToDisplay.loadFileAsString()), + generator.getMainClassName(), currentProject->getProjectType().isAudioPlugin())); } } } @@ -400,10 +413,7 @@ void MainWindow::filesDropped (const StringArray& filenames, int /*mouseX*/, int { const File f (filename); - if (tryToOpenPIP (f)) - continue; - - if (! isPIPFile (f) && (canOpenFile (f) && openFile (f))) + if (canOpenFile (f) && openFile (f)) break; } } @@ -448,64 +458,43 @@ void MainWindow::activeWindowStatusChanged() pcc->updateMissingFileStatuses(); ProjucerApplication::getApp().openDocumentManager.reloadModifiedFiles(); +} - if (auto* p = getProject()) - { - if (p->hasProjectBeenModified()) - { - Component::SafePointer<Component> safePointer (this); - - MessageManager::callAsync ([=] () - { - if (safePointer == nullptr) - return; // bail out if the window has been deleted - - auto result = AlertWindow::showOkCancelBox (AlertWindow::QuestionIcon, - TRANS ("The .jucer file has been modified since the last save."), - TRANS ("Do you want to keep the current project or re-load from disk?"), - TRANS ("Keep"), - TRANS ("Re-load from disk")); - - if (safePointer == nullptr) - return; - - if (result == 0) - { - if (auto* project = getProject()) - { - auto oldTemporaryDirectory = project->getTemporaryDirectory(); - - auto projectFile = project->getFile(); - setProject (nullptr); - openFile (projectFile); - - if (oldTemporaryDirectory != File()) - if (auto* newProject = getProject()) - newProject->setTemporaryDirectory (oldTemporaryDirectory); - } - } - else - { - ProjucerApplication::getApp().getCommandManager().invokeDirectly (CommandIDs::saveProject, true); - } - }); - } - } +void MainWindow::initialiseProjectWindow() +{ + setResizable (true, false); + updateTitleBarIcon(); } void MainWindow::showStartPage() { jassert (currentProject == nullptr); - setContentOwned (createNewProjectWizardComponent(), true); + setContentOwned (new StartPageComponent ([this] (std::unique_ptr<Project>&& newProject) { setProject (std::move (newProject)); }, + [this] (const File& exampleFile) { openFile (exampleFile); }), + true); - centreWithSize (900, 630); - setVisible (true); + setResizable (false, false); + setName ("New Project"); addToDesktop(); + centreWithSize (getContentComponent()->getWidth(), getContentComponent()->getHeight()); + setVisible (true); getContentComponent()->grabKeyboardFocus(); } +void MainWindow::showLoginFormOverlay() +{ + blurOverlayComponent = std::make_unique<BlurOverlayWithComponent> (*this, std::make_unique<LoginFormComponent> (*this)); + loginFormOpen = true; +} + +void MainWindow::hideLoginFormOverlay() +{ + blurOverlayComponent.reset(); + loginFormOpen = false; +} + //============================================================================== ApplicationCommandTarget* MainWindow::getNextCommandTarget() { @@ -573,12 +562,11 @@ bool MainWindow::perform (const InvocationInfo& info) return true; } -void MainWindow::valueChanged (Value&) +void MainWindow::valueChanged (Value& value) { - if (currentProject != nullptr) - setName (currentProject->getProjectNameString() + " - Projucer"); - else - setName ("Projucer"); + if (value == projectNameValue) + setName (currentProject != nullptr ? currentProject->getProjectNameString() + " - Projucer" + : "Projucer"); } //============================================================================== @@ -597,7 +585,7 @@ bool MainWindowList::askAllWindowsToClose() while (windows.size() > 0) { - if (! windows[0]->closeCurrentProject (true)) + if (! windows[0]->closeCurrentProject (OpenDocumentManager::SaveIfNeeded::yes)) return false; windows.remove (0); @@ -624,7 +612,7 @@ void MainWindowList::closeWindow (MainWindow* w) else #endif { - if (w->closeCurrentProject (true)) + if (w->closeCurrentProject (OpenDocumentManager::SaveIfNeeded::yes)) { windows.removeObject (w); saveCurrentlyOpenProjectList(); @@ -666,6 +654,9 @@ void MainWindowList::openDocument (OpenDocumentManager::Document* doc, bool grab bool MainWindowList::openFile (const File& file, bool openInBackground) { + if (! file.exists()) + return false; + for (auto* w : windows) { if (w->getProject() != nullptr && w->getProject()->getFile() == file) @@ -675,7 +666,8 @@ bool MainWindowList::openFile (const File& file, bool openInBackground) } } - if (file.hasFileExtension (Project::projectFileExtension)) + if (file.hasFileExtension (Project::projectFileExtension) + || isPIPFile (file)) { WeakReference<Component> previousFrontWindow (getFrontmostWindow()); @@ -685,6 +677,7 @@ bool MainWindowList::openFile (const File& file, bool openInBackground) if (w->openFile (file)) { w->makeVisible(); + w->setResizable (true, false); checkWindowBounds (*w); if (openInBackground && previousFrontWindow != nullptr) @@ -697,13 +690,7 @@ bool MainWindowList::openFile (const File& file, bool openInBackground) return false; } - if (getFrontmostWindow()->tryToOpenPIP (file)) - return true; - - if (! isPIPFile (file) && file.exists()) - return getFrontmostWindow()->openFile (file); - - return false; + return getFrontmostWindow()->openFile (file); } MainWindow* MainWindowList::createNewMainWindow() @@ -774,6 +761,15 @@ MainWindow* MainWindowList::getMainWindowForFile (const File& file) return nullptr; } +MainWindow* MainWindowList::getMainWindowWithLoginFormOpen() +{ + for (auto* window : windows) + if (window->isShowingLoginForm()) + return window; + + return nullptr; +} + void MainWindowList::checkWindowBounds (MainWindow& windowToCheck) { auto avoidSuperimposedWindows = [&] @@ -804,7 +800,7 @@ void MainWindowList::checkWindowBounds (MainWindow& windowToCheck) auto ensureWindowIsFullyOnscreen = [&] { auto windowBounds = windowToCheck.getScreenBounds(); - auto screenLimits = Desktop::getInstance().getDisplays().findDisplayForRect (windowBounds).userArea; + auto screenLimits = Desktop::getInstance().getDisplays().getDisplayForRect (windowBounds)->userArea; if (auto* peer = windowToCheck.getPeer()) peer->getFrameSize().subtractFrom (screenLimits); diff --git a/extras/Projucer/Source/Application/jucer_MainWindow.h b/extras/Projucer/Source/Application/jucer_MainWindow.h index 43de4be5..3b187fe0 100644 --- a/extras/Projucer/Source/Application/jucer_MainWindow.h +++ b/extras/Projucer/Source/Application/jucer_MainWindow.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -26,8 +25,11 @@ #pragma once -#include "../Project/UI/jucer_ProjectContentComponent.h" #include "../Utility/PIPs/jucer_PIPGenerator.h" +#include "../Project/jucer_Project.h" +#include "../CodeEditor/jucer_OpenDocumentManager.h" + +class ProjectContentComponent; //============================================================================== /** @@ -44,6 +46,8 @@ public: MainWindow(); ~MainWindow() override; + enum class OpenInIDE { no, yes }; + //============================================================================== void closeButtonPressed() override; @@ -54,15 +58,18 @@ public: void setProject (std::unique_ptr<Project> newProject); Project* getProject() const { return currentProject.get(); } - bool tryToOpenPIP (const File& f); - void makeVisible(); void restoreWindowPosition(); - bool closeCurrentProject (bool askToSave); - void moveProject (File newProjectFile); + void updateTitleBarIcon(); + bool closeCurrentProject (OpenDocumentManager::SaveIfNeeded askToSave); + void moveProject (File newProjectFile, OpenInIDE openInIDE); void showStartPage(); + void showLoginFormOverlay(); + void hideLoginFormOverlay(); + bool isShowingLoginForm() const noexcept { return loginFormOpen; } + bool isInterestedInFileDrag (const StringArray& files) override; void filesDropped (const StringArray& filenames, int mouseX, int mouseY) override; @@ -79,16 +86,21 @@ public: bool shouldDropFilesWhenDraggedExternally (const DragAndDropTarget::SourceDetails& sourceDetails, StringArray& files, bool& canMoveFiles) override; private: - std::unique_ptr<Project> currentProject; - Value projectNameValue; + void valueChanged (Value&) override; static const char* getProjectWindowPosName() { return "projectWindowPos"; } void createProjectContentCompIfNeeded(); - void setTitleBarIcon(); - void openPIP (PIPGenerator&); + bool openPIP (PIPGenerator); + void setupTemporaryPIPProject (PIPGenerator&); - void valueChanged (Value&) override; + void initialiseProjectWindow(); + + std::unique_ptr<Project> currentProject; + Value projectNameValue; + + std::unique_ptr<Component> blurOverlayComponent; + bool loginFormOpen = false; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainWindow) }; @@ -113,6 +125,7 @@ public: MainWindow* getFrontmostWindow (bool createIfNotFound = true); MainWindow* getOrCreateEmptyWindow(); MainWindow* getMainWindowForFile (const File&); + MainWindow* getMainWindowWithLoginFormOpen(); Project* getFrontmostProject(); diff --git a/extras/Projucer/Source/Application/jucer_ProjucerAnalytics.cpp b/extras/Projucer/Source/Application/jucer_ProjucerAnalytics.cpp deleted file mode 100644 index d616a861..00000000 --- a/extras/Projucer/Source/Application/jucer_ProjucerAnalytics.cpp +++ /dev/null @@ -1,254 +0,0 @@ -/* - ============================================================================== - - 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. - - ============================================================================== -*/ - -#include "jucer_ProjucerAnalytics.h" - -//============================================================================== -ProjucerAnalyticsDestination::ProjucerAnalyticsDestination() - : ThreadedAnalyticsDestination ("ProjucerAnalyticsThread") -{ - { - MemoryOutputStream mo; - if (Base64::convertFromBase64 (mo, BinaryData::nothingtoseehere_txt)) - apiKey = mo.toString(); - } - - auto dataDir = File::getSpecialLocation (File::userApplicationDataDirectory) - #if JUCE_MAC - .getChildFile ("Application Support") - #endif - .getChildFile ("Projucer") - .getChildFile ("Analytics"); - - if (! dataDir.exists()) - dataDir.createDirectory(); - - savedEventsFile = dataDir.getChildFile ("analytics_events.xml"); - - startAnalyticsThread (initialPeriodMs); -} - -ProjucerAnalyticsDestination::~ProjucerAnalyticsDestination() -{ - Thread::sleep (initialPeriodMs); - - stopAnalyticsThread (1000); -} - -//============================================================================== -static void setData (const AnalyticsDestination::AnalyticsEvent& event, StringPairArray& data) -{ - data.set ("ea", event.name); - - if (event.parameters.getAllKeys().contains ("label")) - data.set ("el", event.parameters.getValue ("label", {})); - - data.addArray (event.userProperties); -} - -bool ProjucerAnalyticsDestination::logBatchedEvents (const Array<AnalyticsEvent>& events) -{ - String appData ("v=1&aip=1&tid=" + apiKey); - - StringArray postData; - - for (auto& event : events) - { - StringPairArray data; - - data.set ("t", "event"); - data.set ("cid", event.userID); - - switch (event.eventType) - { - case ProjucerAnalyticsEvent::appEvent: - { - data.set ("ec", "App"); - setData (event, data); - - break; - } - - case ProjucerAnalyticsEvent::projectEvent: - { - data.set ("ec", "Project"); - setData (event, data); - - break; - } - - case ProjucerAnalyticsEvent::userEvent: - { - data.set ("ec", "User"); - setData (event, data); - - break; - } - - case ProjucerAnalyticsEvent::exampleEvent: - { - data.set ("ec", "Example"); - setData (event, data); - - break; - } - - case ProjucerAnalyticsEvent::startPageEvent: - { - data.set ("ec", "Start Page"); - setData (event, data); - - break; - } - - default: - { - // unknown event type! - jassertfalse; - break; - } - } - - StringArray eventData; - - for (auto& key : data.getAllKeys()) - eventData.add (key + "=" + URL::addEscapeChars (data[key], true)); - - postData.add (appData + "&" + eventData.joinIntoString ("&")); - } - - auto url = URL ("https://www.google-analytics.com/batch") - .withPOSTData (postData.joinIntoString ("\n")); - - { - const ScopedLock lock (webStreamCreation); - - if (shouldExit) - return false; - - webStream.reset (new WebInputStream (url, true)); - } - - auto success = webStream->connect (nullptr); - - // Do an exponential backoff if we failed to connect. - if (success) - periodMs = initialPeriodMs; - else - periodMs *= 2; - - setBatchPeriod (periodMs); - - return success; -} - -void ProjucerAnalyticsDestination::stopLoggingEvents() -{ - const ScopedLock lock (webStreamCreation); - - shouldExit = true; - - if (webStream.get() != nullptr) - webStream->cancel(); -} - -//============================================================================== -void ProjucerAnalyticsDestination::saveUnloggedEvents (const std::deque<AnalyticsEvent>& eventsToSave) -{ - auto xml = parseXMLIfTagMatches (savedEventsFile, "events"); - - if (xml == nullptr) - xml = std::make_unique<XmlElement> ("events"); - - for (auto& event : eventsToSave) - { - auto* xmlEvent = new XmlElement ("google_analytics_event"); - xmlEvent->setAttribute ("name", event.name); - xmlEvent->setAttribute ("type", event.eventType); - xmlEvent->setAttribute ("timestamp", (int) event.timestamp); - xmlEvent->setAttribute ("user_id", event.userID); - - auto* parameters = new XmlElement ("parameters"); - - for (auto& key : event.parameters.getAllKeys()) - parameters->setAttribute (key, event.parameters[key]); - - xmlEvent->addChildElement (parameters); - - auto* userProperties = new XmlElement ("user_properties"); - - for (auto& key : event.userProperties.getAllKeys()) - userProperties->setAttribute (key, event.userProperties[key]); - - xmlEvent->addChildElement (userProperties); - - xml->addChildElement (xmlEvent); - } - - xml->writeTo (savedEventsFile, {}); -} - -void ProjucerAnalyticsDestination::restoreUnloggedEvents (std::deque<AnalyticsEvent>& restoredEventQueue) -{ - auto xml = parseXMLIfTagMatches (savedEventsFile, "events"); - - if (xml == nullptr) - return; - - auto numEvents = xml->getNumChildElements(); - - for (int iEvent = 0; iEvent < numEvents; ++iEvent) - { - auto* xmlEvent = xml->getChildElement (iEvent); - - StringPairArray parameters; - auto* xmlParameters = xmlEvent->getChildByName ("parameters"); - auto numParameters = xmlParameters->getNumAttributes(); - - for (int iParam = 0; iParam < numParameters; ++iParam) - parameters.set (xmlParameters->getAttributeName (iParam), - xmlParameters->getAttributeValue (iParam)); - - StringPairArray userProperties; - auto* xmlUserProperties = xmlEvent->getChildByName ("user_properties"); - auto numUserProperties = xmlUserProperties->getNumAttributes(); - - for (int iProp = 0; iProp < numUserProperties; ++iProp) - userProperties.set (xmlUserProperties->getAttributeName (iProp), - xmlUserProperties->getAttributeValue (iProp)); - - restoredEventQueue.push_back ({ - xmlEvent->getStringAttribute ("name"), - xmlEvent->getIntAttribute ("type"), - static_cast<uint32> (xmlEvent->getIntAttribute ("timestamp")), - parameters, - xmlEvent->getStringAttribute ("user_id"), - userProperties - }); - } - - savedEventsFile.deleteFile(); -} diff --git a/extras/Projucer/Source/Application/jucer_ProjucerAnalytics.h b/extras/Projucer/Source/Application/jucer_ProjucerAnalytics.h deleted file mode 100644 index f33b009d..00000000 --- a/extras/Projucer/Source/Application/jucer_ProjucerAnalytics.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - ============================================================================== - - 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. - - ============================================================================== -*/ - -#pragma once - -#include "jucer_Headers.h" - -//============================================================================== -enum ProjucerAnalyticsEvent -{ - appEvent, - projectEvent, - userEvent, - exampleEvent, - startPageEvent -}; - -//============================================================================== -class ProjucerAnalyticsDestination : public ThreadedAnalyticsDestination -{ -public: - ProjucerAnalyticsDestination(); - ~ProjucerAnalyticsDestination() override; - - //============================================================================== - bool logBatchedEvents (const Array<AnalyticsEvent>&) override; - void stopLoggingEvents() override; - - int getMaximumBatchSize() override { return 20; } - -private: - void saveUnloggedEvents (const std::deque<AnalyticsEvent>&) override; - void restoreUnloggedEvents (std::deque<AnalyticsEvent>&) override; - - //============================================================================== - String apiKey; - - const int initialPeriodMs = 1000; - int periodMs = initialPeriodMs; - - CriticalSection webStreamCreation; - bool shouldExit = false; - std::unique_ptr<WebInputStream> webStream; - - File savedEventsFile; -}; diff --git a/extras/Projucer/Source/BinaryData/Icons/gpl_logo.svg b/extras/Projucer/Source/BinaryData/Icons/gpl_logo.svg new file mode 100644 index 00000000..fe205244 --- /dev/null +++ b/extras/Projucer/Source/BinaryData/Icons/gpl_logo.svg @@ -0,0 +1,23 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="720" height="358" version="1.1"> + <g id="g1" transform="translate(-26.149211,-6.9701601)"> + <path id="path1" style="fill:#bd0000;" d="m 107.04146,18.25331 c 2e-5,0 -59.309734,258.76742 -59.309734,258.76742 0.01705,0 0.01919,0 0.05329,0 0,0 274.380814,0 274.380814,0 10e-6,0 142.70573,0 142.70573,0 -17.00107,-1.48353 -30.42327,-7.45182 -38.42076,-18.33112 -1.48353,-2.01219 -2.70918,-4.17993 -3.78347,-6.44788 -0.68207,-1.6711 -1.32368,-3.35715 -1.97167,-5.06237 -1.70524,-5.42261 -2.38517,-11.43991 -2.07824,-17.85154 0.85262,-17.87074 9.23805,-39.12802 23.76654,-61.38798 15.43225,-23.65656 37.79837,-48.45089 65.49116,-71.45944 6.20699,-5.15319 12.62503,-10.24199 19.34361,-15.18714 8.30441,-6.10979 16.67281,-11.73661 25.04545,-16.99893 30.84745,-19.42077 61.61817,-33.01012 88.88467,-39.91282 -26.05577,8.50051 -55.32805,22.93138 -84.24861,42.57724 -1.04016,0.70255 -2.06758,1.42215 -3.09072,2.13152 -16.04613,11.11805 -30.58314,22.92586 -43.26998,34.85046 -40.82303,38.38457 -62.40046,78.15884 -52.59544,101.46069 0.69916,1.6029 1.53256,3.13335 2.50455,4.58279 10.53825,15.50047 36.65587,18.17979 69.75422,9.85831 2.25089,-0.56275 4.50178,-1.20004 6.82088,-1.86508 10.57238,-3.05237 21.797,-7.17473 33.3584,-12.25628 2.77949,-1.22777 5.58887,-2.48963 8.41953,-3.83676 0.28988,-0.13641 0.56273,-0.27283 0.85261,-0.4263 36.49173,-18.13162 64.53625,-38.99458 70.60684,-51.52967 1.33008,-2.72662 1.6498,-5.0513 0.74603,-6.87417 -4.33124,-8.78188 -34.63945,-2.849 -71.35287,13.0556 -2.95003,1.2789 -5.93417,2.59492 -8.95241,3.99661 2.45552,-2.27986 5.01123,-4.56828 7.6202,-6.82089 4.16075,-3.58438 8.46856,-7.08945 13.0556,-10.55104 7.179,-5.43627 14.43685,-10.35071 21.58173,-14.70754 33.45643,-25.24067 50.3701,-49.11722 46.8403,-57.97753 -0.66505,-1.66943 -2.08037,-2.81789 -4.26306,-3.51703 -6.97438,-2.21847 -19.70383,0.42929 -35.17019,6.7676 -12.75504,5.23164 -27.40504,12.9908 -42.25752,22.64748 0,0 -2.02495,1.3322 -2.02495,1.3322 2e-5,0 -0.37302,0.21314 -0.37302,0.21314 2e-5,2e-5 -7.14061,4.74265 -7.14061,4.74265 -2e-5,-1e-5 4.10319,-7.51363 4.10319,-7.51363 6.08765,-11.14364 16.0035,-22.77067 28.3493,-33.57154 9.05473,-7.89689 19.39903,-15.33762 30.53413,-21.84816 4.21191,-2.46573 8.4174,-4.75586 12.62929,-6.82088 4.31422,-2.10769 8.63055,-3.98089 12.84246,-5.64859 12.23682,-4.8393 23.91781,-7.7798 34.10442,-8.5794 -0.92767,0 -28.61574,0 -28.61574,0 10e-6,0 -96.45159,0 -96.45159,0 10e-6,0 -425.29295,0 -425.29295,0 0,0 -33.73141,0 -33.73141,0 z m 305.98071,0.3731 c -1.67109,25.50496 3.27403,62.86211 14.49439,104.3382 1.99509,7.38021 4.16712,14.89085 6.55444,22.48762 1.48356,4.69104 3.01399,9.30881 4.58278,13.85492 -0.9208,1.35396 -1.84804,2.69937 -2.7177,4.0499 -13.99985,21.45508 -22.1828,41.73104 -24.24611,59.36303 -5.91714,-19.81468 -10.37201,-41.5183 -12.89574,-64.53198 -0.71619,-6.5941 -1.27679,-13.11442 -1.65194,-19.55675 -2.76247,-46.79639 3.34649,-89.2172 15.87988,-120.00494 z m -279.3899,33.1985 c 0.31934,-0.0075 0.63414,0 0.95918,0 0,-2e-5 63.03991,0 63.03991,0 5.38851,-2e-5 9.55564,1.00991 12.52272,3.03742 2.95002,2.03946 4.05631,4.67743 3.35715,7.88665 2e-5,2e-5 -7.51363,33.94456 -7.51363,33.94456 0,3e-5 -22.22116,0 -22.22116,0 2e-5,3e-5 7.30048,-33.03866 7.30048,-33.03866 -2e-5,0 -55.63285,0 -55.63285,0 -2e-5,0 -20.08965,90.80305 -20.08965,90.80305 2e-5,0 -7.24719,32.87881 -7.24719,32.87881 0,3e-5 55.57957,0 55.57957,0 0,3e-5 0.0533,-0.21316 0.0533,-0.21316 0,2e-5 11.13722,-50.30404 11.13722,-50.30404 0,-2e-5 -26.1112,0 -26.1112,0 0,-2e-5 2.50454,-11.35038 2.50454,-11.35038 -1e-5,-2e-5 48.33238,0 48.33238,0 0,-2e-5 -13.85493,62.77348 -13.85493,62.77348 -0.18757,0.89352 -0.51582,1.70308 -0.95919,2.50453 -1.14249,2.08037 -3.13547,3.86234 -5.91498,5.32883 -3.85378,2.02923 -8.46643,3.03742 -13.85493,3.03742 0,2e-5 -62.98662,0 -62.98662,0 -5.388524,2e-5 -9.555644,-1.00821 -12.522724,-3.03742 -2.95001,-2.0292 -4.07335,-4.62073 -3.35715,-7.83336 10e-6,-2e-5 27.763134,-125.49366 27.763134,-125.49366 0.71618,-3.20921 2.95005,-5.84721 6.82089,-7.88665 0.13642,-0.07331 0.28989,-0.08995 0.4263,-0.15986 3.53302,-1.7697 7.67937,-2.76443 12.46944,-2.87756 z m 98.79628,0 c -2e-5,-2e-5 79.34608,0 79.34608,0 5.32031,-2e-5 9.50235,1.00991 12.46943,3.03742 2.98417,2.03946 4.12666,4.67743 3.41045,7.88665 2e-5,2e-5 -14.81411,66.92995 -14.81411,66.92995 -0.69912,3.18874 -2.98627,5.7905 -6.87417,7.83336 -3.8879,2.04966 -8.4643,3.09071 -13.80164,3.09071 -2e-5,0 -57.6578,0 -57.6578,0 0,0 -11.13723,50.25075 -11.13723,50.25075 0,2e-5 -1.8118,8.25967 -1.8118,8.25967 1e-5,2e-5 -21.74158,0 -21.74158,0 0,2e-5 1.65193,-7.46034 1.65193,-7.46034 0,2e-5 30.96044,-139.82817 30.96044,-139.82817 z m 109.61377,0 c -1e-5,-2e-5 21.74158,0 21.74158,0 2e-5,-2e-5 -24.61914,111.21241 -24.61914,111.21241 2e-5,2e-5 -5.3821,24.29942 -5.3821,24.29942 0,3e-5 52.00926,0 52.00926,0 0.54568,3.98854 1.18299,7.90582 1.86508,11.77668 -2e-5,2e-5 -78.22705,0 -78.22705,0 2e-5,2e-5 6.18143,-27.92301 6.18143,-27.92301 2e-5,0 26.43094,-119.3655 26.43094,-119.3655 z M 251.559,63.65488 c 2e-5,0 -14.4411,65.11814 -14.4411,65.11814 0,-2e-5 54.19408,0 54.19408,0 -1e-5,-2e-5 14.3878,-65.11814 14.3878,-65.11814 2e-5,0 -54.14078,0 -54.14078,0 z m -45.5614,145.68987 c 0.21267,-0.007 0.42524,0 0.63947,0 2.52373,2e-5 4.72772,0.44336 6.50115,1.27891 1.8928,0.88671 3.24632,2.204 3.99662,3.94333 0.73325,1.68819 0.92508,3.60441 0.53287,5.70184 0,1e-5 -0.15985,0.79933 -0.15985,0.79933 1e-5,-3e-5 -6.23472,0 -6.23472,0 -2e-5,-3e-5 0.0533,-0.74605 0.0533,-0.74605 0.16118,-1.46543 -0.0205,-2.61779 -0.58618,-3.41043 -0.0737,-0.0994 -0.18053,-0.23063 -0.26644,-0.31973 -0.14068,-0.14363 -0.35198,-0.3078 -0.53287,-0.42631 -0.87238,-0.5495 -2.23703,-0.85262 -3.99662,-0.85262 -2.33615,2e-5 -4.08187,0.40712 -5.27552,1.22564 -1.15956,0.80146 -1.8928,1.6967 -2.13153,2.77098 -0.23875,1.09134 0.15346,1.66472 0.42631,1.97166 0.008,0.008 0.0429,0.0438 0.0533,0.0533 0.34552,0.29445 1.54536,0.98476 5.27553,1.86508 3.37632,0.81851 5.61232,1.55389 6.87418,2.18482 1.90987,0.97196 3.24419,2.2317 3.94334,3.78346 0.69911,1.53472 0.8526,3.33157 0.4263,5.27553 -0.4263,1.89279 -1.39189,3.63852 -2.82428,5.27554 -1.41532,1.637 -3.21647,2.93297 -5.38211,3.83673 -2.1486,0.88672 -4.50604,1.38549 -6.92746,1.38549 -3.0694,-1e-5 -5.53343,-0.46467 -7.46034,-1.38549 -2.01217,-0.95491 -3.46374,-2.4619 -4.31634,-4.42291 -0.81851,-1.90986 -0.9933,-4.07762 -0.53289,-6.44786 0,-3e-5 0.15987,-0.74605 0.15987,-0.74605 0,0 6.12814,0 6.12814,0 0,0 -0.0533,0.74605 -0.0533,0.74605 -0.15348,1.41532 -0.002,2.55782 0.37302,3.41043 0.35809,0.81853 1.04019,1.49633 2.13152,2.02496 1.15954,0.5627 2.60898,0.8526 4.26305,0.8526 1.48355,-1e-5 2.83921,-0.24939 4.04991,-0.69273 1.19365,-0.4263 2.14218,-0.98904 2.82427,-1.70523 0.66502,-0.71622 1.05511,-1.47288 1.22563,-2.2914 0.17052,-0.73324 0.13002,-1.3535 -0.15987,-1.86508 -0.32399,-0.54564 -0.96558,-1.02953 -1.97165,-1.43878 0,-1e-5 -5.22226,-1.54536 -5.22226,-1.54536 -2.91592,-0.73323 -4.87905,-1.43238 -6.02155,-2.13152 -1.55177,-0.92081 -2.67081,-2.10169 -3.25059,-3.51702 -0.57977,-1.39831 -0.64158,-2.94791 -0.26643,-4.63608 0.3922,-1.80753 1.26399,-3.52767 2.61111,-5.06237 1.3642,-1.55177 3.12482,-2.76885 5.22225,-3.57031 1.85443,-0.6954 3.80596,-1.10321 5.86169,-1.17234 z m 55.9526,0.10658 c 0.33725,-0.0263 0.65436,0 1.01247,0 10e-6,0 3.83675,0.4263 3.83675,0.4263 -10e-6,0 1.27891,0.10658 1.27891,0.10658 2e-5,1e-5 -1.86508,4.74264 -1.86508,4.74264 -1e-5,2e-5 -0.37302,0.74604 -0.37302,0.74604 0,-2e-5 -2.93084,-0.26644 -2.93084,-0.26644 -0.86541,0 -1.50113,0.13352 -1.91838,0.4263 -0.0277,0.0209 -0.081,0.0842 -0.10658,0.10658 -0.0559,0.049 -0.14991,0.13458 -0.21315,0.21316 -0.25659,0.33651 -0.56912,0.93786 -0.79932,2.02495 -2e-5,0 -0.11084,0.4604 -0.21315,0.85261 1.34713,1e-5 4.58277,0 4.58277,0 0,1e-5 -1.17233,5.27552 -1.17233,5.27552 0,-1e-5 -3.35076,0 -4.4762,0 -0.34106,1.53469 -4.5295,20.3028 -4.5295,20.3028 -2e-5,-2e-5 -6.18143,0 -6.18143,0 -2e-5,-2e-5 4.01793,-18.03485 4.5295,-20.3028 -1.04021,-1e-5 -3.57031,0 -3.57031,0 0,-1e-5 1.17234,-5.27552 1.17234,-5.27552 10e-6,1e-5 2.54504,0 3.51701,0 0.17052,-0.73324 0.4263,-1.65194 0.4263,-1.65194 0.37516,-1.70522 0.76735,-2.93085 1.27891,-3.78346 0.69917,-1.17659 1.68606,-2.16137 2.93087,-2.87756 1.02527,-0.59575 2.32198,-0.95194 3.78346,-1.06576 z m 14.76082,0.26644 c -2e-5,-1e-5 -1.6157,7.27064 -2.02495,9.11228 1.19364,1e-5 3.99661,0 3.99661,0 0,1e-5 -1.17233,5.27552 -1.17233,5.27552 -2e-5,-1e-5 -2.93939,0 -3.99662,0 -0.32401,1.46647 -2.87756,12.84246 -2.87756,12.84246 2e-5,-2e-5 -0.21316,1.36631 -0.21316,1.75851 2.8e-4,0.0131 -10e-4,0.0437 0,0.0533 8.4e-4,0.004 -10e-4,0.05 0,0.0533 0.002,0.003 0.0512,-0.002 0.0533,0 0,-2e-5 0.63947,0.0533 0.63947,0.0533 0,0 2.93085,-0.21315 2.93085,-0.21315 0,0 -0.31973,4.74264 -0.31973,4.74264 2e-5,0 0.0533,0.85261 0.0533,0.85261 -2e-5,-2e-5 -4.20978,0.4796 -4.20978,0.4796 -1.6711,-2e-5 -2.89675,-0.27283 -3.78346,-0.8526 -0.93785,-0.61392 -1.48354,-1.42814 -1.70522,-2.45126 -0.0341,-0.18759 -0.10658,-0.46042 -0.10658,-0.85261 0,-0.76736 0.14495,-2.06545 0.63946,-4.31634 2e-5,2e-5 2.24023,-10.03524 2.7177,-12.14972 -0.80143,-1e-5 -2.93085,0 -2.93085,0 2e-5,-1e-5 1.17233,-5.27552 1.17233,-5.27552 -2e-5,10e-6 2.07824,0 2.93086,0 0.27281,-1.22775 1.22562,-5.4354 1.22562,-5.4354 0,2e-5 4.95581,-2.61112 4.95581,-2.61112 -10e-6,2e-5 2.02495,-1.06576 2.02495,-1.06576 z m -196.366934,0.21315 c 2e-5,0 23.979684,0 23.979684,0 0,0 -1.3322,5.96828 -1.3322,5.96828 0,2e-5 -15.997114,0 -17.531814,0 -0.27282,1.21073 -1.36631,6.11322 -1.75851,7.88665 2.2168,0 15.18713,0 15.18713,0 0,0 -1.33221,5.96826 -1.33221,5.96826 -1e-5,0 -13.65242,0 -15.18713,0 -0.32399,1.48355 -3.25058,14.65426 -3.25058,14.65426 2e-5,-2e-5 -6.44786,0 -6.44786,0 1e-5,-2e-5 7.67349,-34.47745 7.67349,-34.47745 z m 32.132764,8.41954 c 0.24067,-0.0296 0.50358,0 0.74604,0 1.5347,0 2.95217,0.4668 4.31635,1.43877 0,2e-5 0.8526,0.58617 0.8526,0.58617 0,0 -3.30386,5.4354 -3.30386,5.4354 0,-2e-5 -0.90589,-0.63946 -0.90589,-0.63946 -0.66504,-0.42629 -1.38123,-0.63946 -2.13153,-0.63946 -0.64799,2e-5 -1.25121,0.2302 -1.86509,0.63946 -0.64797,0.4263 -1.1894,0.99115 -1.59864,1.75851 -0.7162,1.31304 -1.24056,2.78377 -1.59865,4.36963 0,1e-5 -2.87756,13.10889 -2.87756,13.10889 0,-2e-5 -6.181434,0 -6.181434,0 0,-2e-5 5.701844,-25.57832 5.701844,-25.57832 2e-5,1e-5 5.75512,0 5.75512,0 0,1e-5 -0.19824,0.77588 -0.26645,1.06576 0.27284,-0.20461 0.56059,-0.48599 0.79933,-0.63946 0.82597,-0.4929 1.69837,-0.80035 2.55782,-0.90589 z m 18.33114,0 c 0.37219,-0.0282 0.73859,0 1.11906,0 3.47866,0 6.11108,1.21922 7.83335,3.62359 1.07428,1.55174 1.65195,3.47012 1.65195,5.75512 0,1.26185 -0.15561,2.61965 -0.47959,4.10319 0,0 -0.47961,1.86509 -0.47961,1.86509 0,-2e-5 -15.63261,0 -17.37194,0 -0.0341,0.35808 -0.0533,0.74177 -0.0533,1.06576 0,1.33009 0.27283,2.37665 0.85261,3.14401 0.2755,0.37513 0.5949,0.71299 0.95919,0.95918 0.68678,0.44789 1.57334,0.69275 2.61112,0.69275 1.26188,-2e-5 2.37025,-0.34745 3.41044,-1.01248 0.98905,-0.63093 1.93544,-1.63914 2.77099,-3.03742 0,-3e-5 6.60773,0 6.60773,0 0,-3e-5 -0.58616,1.27891 -0.58616,1.27891 -1.26187,2.55785 -3.02251,4.55294 -5.22225,5.96828 -2.19973,1.41533 -4.82791,2.1848 -7.72679,2.1848 -3.76854,-1e-5 -6.57363,-1.21922 -8.31296,-3.62358 -1.72226,-2.35323 -2.09315,-5.60593 -1.17233,-9.69846 0.92083,-4.16073 2.7582,-7.48591 5.43539,-9.80502 2.39958,-2.08062 5.12245,-3.23468 8.15309,-3.46372 z m 27.76315,0 c 0.37218,-0.0282 0.73857,0 1.11904,0 3.47867,0 6.1111,1.21922 7.83337,3.62359 1.07429,1.55174 1.65193,3.47012 1.65193,5.75512 0,1.2448 -0.1556,2.58341 -0.4796,4.0499 0,2e-5 -0.47958,1.91838 -0.47958,1.91838 0,-2e-5 -15.63263,0 -17.37195,0 -0.0171,0.2387 -0.0362,0.45402 -0.0533,0.69275 -0.0128,0.0895 0.006,0.22541 0,0.31972 -5e-4,0.0154 0,0.0384 0,0.0533 0,0.2558 0.0362,0.5073 0.0533,0.74604 0.0852,0.97196 0.33892,1.78409 0.79932,2.39797 0.0877,0.11936 0.17008,0.2667 0.26644,0.37302 0.78101,0.83554 1.8864,1.27891 3.30387,1.27891 1.26188,-2e-5 2.38731,-0.34745 3.41045,-1.01248 0.98904,-0.63093 1.93542,-1.63914 2.77098,-3.03742 0,-3e-5 6.66102,0 6.66102,0 -1e-5,-3e-5 -0.63946,1.27891 -0.63946,1.27891 -1.26186,2.55785 -3.0225,4.55294 -5.22224,5.96828 -2.19974,1.41533 -4.82791,2.1848 -7.72678,2.1848 -3.76853,-1e-5 -6.57363,-1.21922 -8.31296,-3.62358 -1.12545,-1.53472 -1.65194,-3.48931 -1.65194,-5.80841 0,-0.35812 0.0192,-0.74391 0.0533,-1.11905 0.0682,-0.88671 0.20463,-1.78196 0.42631,-2.771 0.92084,-4.14368 2.70491,-7.48591 5.3821,-9.80502 2.39957,-2.08062 5.17575,-3.23468 8.20639,-3.46372 z m 75.61591,0 c 0.38084,-0.0293 0.73112,0 1.11905,0 3.54687,0 6.2731,1.20004 8.04652,3.5703 1.7564,2.37023 2.18269,5.56754 1.27891,9.59186 -0.69913,3.13763 -1.70947,5.672 -3.0907,7.51365 -1.38126,1.84165 -3.14188,3.34649 -5.22226,4.36962 -2.06328,1.02314 -4.24813,1.54535 -6.44786,1.54535 -3.61507,-1e-5 -6.30719,-1.23628 -8.04652,-3.62358 -1.12546,-1.51764 -1.70522,-3.47226 -1.70522,-5.80841 2e-5,-1.26187 0.13856,-2.6026 0.4796,-4.10319 1.02315,-4.57001 3.11202,-8.05078 6.18143,-10.28462 2.25301,-1.62634 4.74114,-2.56606 7.40705,-2.77098 z m 93.62733,0 c 0.4496,-0.0277 0.86593,0 1.3322,0 2.14859,0 3.83675,0.2174 5.11567,0.74602 1.36418,0.54569 2.33189,1.31729 2.87756,2.23811 0.52864,0.86963 0.79933,1.93756 0.79933,3.25057 10e-6,2e-5 -0.63948,3.89004 -0.63948,3.89004 3e-5,0 -1.17232,5.27554 -1.17232,5.27554 -1.00611,4.50176 -1.22776,6.18995 -1.27893,6.82089 -0.0512,0.85262 0.0277,1.6839 0.26645,2.45125 2e-5,-2e-5 0.4263,1.38549 0.4263,1.38549 2e-5,-2e-5 -6.288,0 -6.288,0 -2e-5,-2e-5 -0.26645,-0.79933 -0.26645,-0.79933 -0.10231,-0.37512 -0.0725,-0.8526 -0.10657,-1.27891 -1.19365,0.73325 -2.38944,1.38336 -3.46373,1.75851 -1.58584,0.54569 -3.23139,0.8526 -4.90251,0.8526 -2.89886,-1e-5 -5.04532,-0.75454 -6.3413,-2.2381 -0.98902,-1.09133 -1.43877,-2.42567 -1.43877,-3.94332 -2e-5,-0.57977 0.0767,-1.18087 0.21314,-1.81179 0.28988,-1.29597 0.81638,-2.49603 1.65194,-3.57032 0.81851,-1.05726 1.78623,-1.92689 2.87756,-2.55782 1.05726,-0.63092 2.23598,-1.07855 3.46374,-1.3855 -2e-5,0 3.78346,-0.63946 3.78346,-0.63946 2.91594,-0.34106 5.09221,-0.76521 6.66102,-1.22562 0.0341,-0.17052 0.10657,-0.37302 0.10657,-0.37302 0.24726,-1.09718 0.21632,-1.92188 -0.0533,-2.34468 -0.0198,-0.0273 -0.0842,-0.0831 -0.10657,-0.10658 -0.0576,-0.0614 -0.14603,-0.15779 -0.21316,-0.21315 -0.64135,-0.50753 -1.73506,-0.74603 -3.19728,-0.74603 -1.65407,0 -2.87756,0.27071 -3.73018,0.79931 -0.83555,0.52863 -1.60931,1.49634 -2.29139,2.87756 -1e-5,-1e-5 -6.44787,0 -6.44787,0 2e-5,-1e-5 0.58617,-1.27891 0.58617,-1.27891 0.76733,-1.77345 1.68178,-3.24418 2.82428,-4.36963 1.1425,-1.12547 2.68572,-1.99724 4.4762,-2.61111 1.37216,-0.45297 2.8705,-0.75354 4.47621,-0.85261 z m 27.01711,0 c 0.24046,-0.0296 0.50356,0 0.74603,0 1.55173,0 3.00545,0.4668 4.36963,1.43877 2e-5,2e-5 0.79932,0.58617 0.79932,0.58617 1e-5,0 -3.30386,5.4354 -3.30386,5.4354 10e-6,-2e-5 -0.9059,-0.63946 -0.9059,-0.63946 -0.66503,-0.42629 -1.34501,-0.63946 -2.07824,-0.63946 -0.64801,2e-5 -1.28744,0.2302 -1.91839,0.63946 -0.64797,0.4263 -1.11904,0.99115 -1.54534,1.75851 -0.69916,1.31304 -1.24056,2.78377 -1.59865,4.36963 -2e-5,1e-5 -2.93085,13.10889 -2.93085,13.10889 2e-5,-2e-5 -6.18142,0 -6.18142,0 0,-2e-5 5.70182,-25.57832 5.70182,-25.57832 -10e-6,1e-5 5.75512,0 5.75512,0 0,1e-5 -0.14494,0.77588 -0.21314,1.06576 0.27282,-0.20461 0.54353,-0.48599 0.79932,-0.63946 0.81263,-0.4929 1.64571,-0.80035 2.50455,-0.90589 z m 18.27783,0 c 0.37185,-0.0282 0.73859,0 1.11906,0 3.47866,0 6.12813,1.21922 7.83337,3.62359 1.09135,1.55174 1.65193,3.47012 1.65193,5.75512 -2e-5,1.26185 -0.2089,2.61965 -0.53289,4.10319 0,0 -0.4263,1.86509 -0.4263,1.86509 -10e-6,-2e-5 -15.64968,0 -17.37194,0 -0.0341,0.35808 -0.10659,0.74177 -0.10659,1.06576 0,1.33009 0.28989,2.37665 0.85262,3.14401 0.0877,0.11936 0.223,0.2667 0.31972,0.37302 0.056,0.0597 0.15412,0.15773 0.21316,0.21314 0.76235,0.69302 1.79981,1.06577 3.0907,1.06577 1.26189,-2e-5 2.37027,-0.34745 3.41045,-1.01248 0.98905,-0.63093 1.91839,-1.63914 2.77099,-3.03742 -2e-5,-3e-5 6.66102,0 6.66102,0 0,-3e-5 -0.63946,1.27891 -0.63946,1.27891 -1.26187,2.55785 -3.03955,4.55294 -5.22224,5.96828 -2.21677,1.41533 -4.81085,2.1848 -7.72679,2.1848 -3.76851,-1e-5 -6.52034,-1.21922 -8.25966,-3.62358 -1.7223,-2.35323 -2.1294,-5.60593 -1.22563,-9.69846 0.92081,-4.16073 2.70491,-7.48591 5.38211,-9.80502 2.41475,-2.08062 5.17852,-3.23468 8.20637,-3.46372 z m -93.3076,0.47959 c 2e-5,1e-5 6.34131,0 6.34131,0 2e-5,1e-5 0.78226,15.17861 0.79931,15.40027 0.25578,-0.54356 0.45424,-1.00087 0.47961,-1.06575 1e-5,1e-5 6.98074,-14.33452 6.98074,-14.33452 2e-5,1e-5 5.80841,0 5.80841,0 -10e-6,1e-5 0.53288,14.99528 0.53288,15.08054 0.17055,-0.30691 7.93994,-15.08054 7.93994,-15.08054 -2e-5,1e-5 6.28801,0 6.28801,0 -10e-6,1e-5 -13.85493,25.57832 -13.85493,25.57832 2e-5,-2e-5 -5.70183,0 -5.70183,0 0,-2e-5 -0.55206,-13.86984 -0.58617,-14.65426 -2.35323,4.8258 -7.14063,14.65426 -7.14063,14.65426 0,-2e-5 -5.86168,0 -5.86168,0 0,-2e-5 -2.02497,-25.57832 -2.02497,-25.57832 z m -148.88715,4.84922 c -1.46893,0.062 -2.80295,0.59149 -4.04989,1.59864 -0.98902,0.78441 -1.65621,1.86084 -2.18483,3.03743 0,2e-5 10.49777,0 10.49777,0 0.0171,-0.18756 0.0533,-0.41564 0.0533,-0.58617 -2e-5,-0.97195 -0.17266,-1.72653 -0.47959,-2.2381 -0.75028,-1.22777 -1.86295,-1.8118 -3.51702,-1.8118 -0.0991,0 -0.2218,-0.004 -0.31973,0 z m 27.76313,0 c -1.46892,0.062 -2.80295,0.59149 -4.0499,1.59864 -0.98904,0.78441 -1.63913,1.86084 -2.1848,3.03743 0,2e-5 10.49776,0 10.49776,0 0.017,-0.18756 0.0533,-0.41564 0.0533,-0.58617 -1e-5,-0.97195 -0.1556,-1.72653 -0.4796,-2.2381 -0.14894,-0.24939 -0.35043,-0.49739 -0.53288,-0.69274 -0.71199,-0.73572 -1.6919,-1.11906 -2.98413,-1.11906 -0.0991,0 -0.2218,-0.004 -0.31974,0 z m 214.75136,0 c -1.51056,0.0465 -2.92125,0.55794 -4.20977,1.59864 -0.97198,0.78441 -1.63915,1.86084 -2.18482,3.03743 2e-5,2e-5 10.44449,0 10.44449,0 0.017,-0.18756 0.0533,-0.41564 0.0533,-0.58617 -1e-5,-0.97195 -0.1556,-1.72653 -0.4796,-2.2381 -0.73324,-1.21072 -1.86296,-1.79474 -3.51702,-1.8118 -0.049,5.3e-4 -0.0578,-0.001 -0.10657,0 z m -139.61502,0.10658 c -1.40963,0.16739 -2.72036,0.81051 -3.94333,1.91837 -1.46648,1.33009 -2.53012,3.41897 -3.14399,6.18143 -0.25579,1.15955 -0.37303,2.15071 -0.37303,3.03742 2e-5,1.2107 0.23233,2.16137 0.69275,2.87756 0.12257,0.18384 0.28516,0.37811 0.42631,0.53289 0.75804,0.80488 1.81659,1.22563 3.144,1.22563 1.72226,-2e-5 3.23992,-0.64159 4.68935,-1.97167 1.46652,-1.34714 2.51307,-3.45734 3.144,-6.288 0.5798,-2.59195 0.49878,-4.52736 -0.31972,-5.75512 -0.7844,-1.19366 -1.93116,-1.75851 -3.51701,-1.75851 -0.26911,0 -0.5383,-0.031 -0.79933,0 z m 96.29173,9.32543 c -1.44941,0.39218 -3.07367,0.72258 -5.22224,1.01248 -1.60289,0.23874 -2.74541,0.49024 -3.41045,0.74603 -0.57976,0.23872 -1.04658,0.56911 -1.43878,1.01248 -0.37516,0.42627 -0.62666,0.87392 -0.74602,1.38549 -0.0341,0.20464 -0.0533,0.41564 -0.0533,0.58617 0,0.0138 -3.1e-4,0.0396 0,0.0533 0.002,0.0406 -0.004,0.1207 0,0.15985 0.0107,0.0774 0.0322,0.1944 0.0533,0.26645 0.008,0.0237 0.0445,0.0834 0.0533,0.10657 0.0187,0.0458 0.0301,0.11611 0.0533,0.15987 0.0243,0.0433 0.0779,0.11849 0.10658,0.15986 0.0446,0.0614 0.1055,0.1556 0.15987,0.21315 0.42631,0.47746 1.27678,0.69275 2.50454,0.69275 1.34715,1e-5 2.6431,-0.25578 3.83675,-0.85261 1.17662,-0.57977 2.12513,-1.44518 2.82427,-2.45126 0.51159,-0.7162 0.92083,-1.8182 1.27892,-3.25057 z"/> + <path id="path2" style="fill:none;stroke:#bd0000;stroke-width:8.52610779;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;" d="m 417.07944,250.20635 c 0.69221,1.77962 1.38445,3.55633 2.1055,5.2941 1.11046,2.36077 2.39396,4.6206 3.93704,6.73045 8.33557,11.33086 22.29546,17.53495 40.01931,19.07947 0,0 19.06506,0 19.06506,0 6.02811,-0.47014 12.34467,-1.34696 18.89198,-2.62759 11.29193,-2.2079 23.26167,-5.5998 35.69288,-10.13244 9.41715,-3.43375 19.0939,-7.49624 28.91485,-12.21778 21.38688,-10.25215 43.48041,-23.47509 65.15575,-39.43235 7.13857,-5.25082 13.98872,-10.63863 20.56487,-16.1173 6.02813,-5.01576 11.8111,-10.10942 17.33446,-15.25927 15.41645,-14.85689 27.0545,-29.94597 33.64507,-43.1949 6.86452,-13.7969 8.23461,-25.59358 2.61028,-33.02493 -3.44673,-4.56146 -9.21527,-7.00589 -16.64228,-7.5813 33.45753,-25.10471 52.95528,-55.55833 45.96096,-74.7589 -2.22096,-6.1277 -7.10981,-10.6992 -14.11858,-13.2273 -3.11497,-1.1205 -6.61943,-1.8301 -10.4411,-2.1531 0,0 -10.29683,0 -10.29683,0 -14.37808,1.0369 -35.28664,6.1853 -53.0249,14.8785"/> + <g id="g2" style="fill:#bd0000;fill-opacity:1" transform="scale(1.705222,1.705222)"> + <path id="path1" transform="translate(15.5783,177.825)" d="m 0,36 c 0,0 7.46,0 7.46,0 0,0 3.35,-14 3.35,-14 0,0 12.12,0 12.12,0 0,0 1.56,-6 1.56,-6 0,0 -12.17,0 -12.17,0 0,0 2.02,-9 2.02,-9 0,0 12.95,0 12.95,0 0,0 1.56,-7 1.56,-7 C 28.85,0 8.4,0 8.4,0 8.4,0 0,36 0,36 z"/> + <path id="path2" transform="translate(41.5283,187.825)" d="m 7.51,26 c 0,0 2.24,-9.4 2.24,-9.4 1.18,-5.09 3.67,-9.6 8.38,-9.6 0.42,0 0.83,0.21 1.14,0.26 0,0 1.82,-7.21 1.82,-7.21 -0.42,0 -0.88,-0.05 -1.4,-0.05 -3.47,0 -6.38,2.44 -8.32,5.94 0,0 -0.2,0 -0.2,0 C 11.46,4.23 11.71,2.61 11.9,1 11.9,1 5.47,1 5.47,1 5.1,3.08 4.53,7.15 3.66,10.82 3.66,10.82 0,26 0,26 c 0,0 7.51,0 7.51,0 z"/> + <path id="path3" transform="translate(62.1583,187.825)" d="M 20.06,19.25 C 17.99,20.26 15.63,20 12.88,20 10.71,20 9.03,19.62 8.11,18.88 7.63,18.07 7.43,16.81 7.47,16 17.6,16.27 23.99,13.93 24.31,7.53 24.55,2.7 21.02,0 15.89,0 6.73,0 0.73,8.08 0.34,15.86 0,22.65 3.52,26 10.78,26 c 2.79,0 6.49,-0.32 9.52,-1.23 0,0 -0.24,-5.52 -0.24,-5.52 z M 17.32,7.53 C 17.2,9.91 14.26,10.05 8.47,10 9.1,7.91 11.22,6 14.69,6 c 1.71,0 2.69,0.65 2.63,1.53 z"/> + <path id="path4" transform="translate(88.6783,187.825)" d="M 20.05,19.25 C 17.98,20.26 15.62,20 12.88,20 10.7,20 9.03,19.62 8.11,18.88 7.63,18.07 7.42,16.81 7.46,16 17.6,16.27 23.98,13.93 24.31,7.53 24.55,2.7 21.02,0 15.89,0 6.72,0 0.72,8.08 0.33,15.86 0,22.65 3.52,26 10.77,26 c 2.8,0 6.5,-0.32 9.53,-1.23 0,0 -0.25,-5.52 -0.25,-5.52 z M 17.32,7.53 C 17.2,9.91 14.26,10.05 8.46,10 9.1,7.91 11.21,6 14.68,6 c 1.71,0 2.7,0.65 2.64,1.53 z"/> + <path id="path5" transform="translate(124.5883,187.825)" d="M 22.74,26 C 22.8,22.83 23.56,17.85 24.35,14.58 24.35,14.58 27.56,1 27.56,1 25.52,0.31 22.34,0 19.28,0 6.86,0 0.7,9.2 0.27,17.82 0,23.23 2.93,26 7.49,26 c 2.95,0 6.28,-1.43 8.87,-5.73 0,0 0.11,0 0.11,0 -0.2,2.07 -0.44,4.08 -0.57,5.73 0,0 6.84,0 6.84,0 z M 17.61,11.72 C 16.15,18.08 13.17,20 10.95,20 8.88,20 7.98,18.53 8.1,16.39 8.34,11.56 12.16,6 16.98,6 c 0.78,0 1.39,-0.14 1.96,-0.28 0,0 -1.33,6 -1.33,6 z"/> + <path id="path6" transform="translate(152.2183,187.825)" d="m 0,24.82 c 1.44,1.12 4.46,1.13 7.61,1.18 6.73,0.05 11.81,-2.89 12.11,-8.29 0.17,-3.6 -2.62,-5.73 -5.35,-7.16 C 12.4,9.6 11.41,8.69 11.46,7.63 11.53,6.2 12.87,6 14.84,6 c 2.22,0 4,0.27 5.02,0.47 0,0 2.02,-5.42 2.02,-5.42 C 20.73,0.36 18.43,0 15.48,0 8.95,0 4.17,3.45 3.9,8.69 c -0.16,3.24 2.17,5.42 4.99,6.9 2.28,1.17 3.06,2.07 3,3.34 C 11.82,20.21 10.68,20 8.61,20 6.18,20 3.49,19.68 2.07,19.46 2.07,19.46 0,24.82 0,24.82 z"/> + <path id="path7" transform="translate(184.6683,176.825)" d="m 7.45,37 c 0,0 6.05,-25 6.05,-25 0,0 -7.41,0 -7.41,0 0,0 -6.09,25 -6.09,25 0,0 7.45,0 7.45,0 z M 10.92,9 C 13.46,9 15.72,6.9 15.86,3.3 15.98,0.86 14.4,0 12.07,0 9.64,0 7.42,1.58 7.29,3.94 7.17,6.32 8.75,9 10.92,9 z"/> + <path id="path8" transform="translate(198.9583,188.515)" d="m 7.46,25.31 c 0,0 2.64,-11.26 2.64,-11.26 1.37,-5.73 4.32,-7.74 6.75,-7.74 1.92,0 2.48,0.82 2.39,2.01 -0.05,0.96 -0.2,1.97 -0.4,2.87 0,0 -3.36,14.12 -3.36,14.12 0,0 7.46,0 7.46,0 0,0 3.54,-14.81 3.54,-14.81 C 26.75,9.22 27.05,7.31 27.11,6.15 27.33,1.64 25.08,0 20.94,0 c -3.32,0 -6.55,1.54 -9.1,4.88 0,0 -0.1,0 -0.1,0 0,0 0.68,-4.57 0.68,-4.57 0,0 -6.58,0 -6.58,0 C 5.41,2.45 4.86,5.04 4.08,8.06 4.08,8.06 0,25.31 0,25.31 c 0,0 7.46,0 7.46,0 z"/> + <path id="path9" transform="translate(238.5183,177.825)" d="m 0,36 c 0,0 7.46,0 7.46,0 0,0 3.36,-14 3.36,-14 0,0 12.11,0 12.11,0 0,0 1.56,-6 1.56,-6 0,0 -12.17,0 -12.17,0 0,0 2.02,-9 2.02,-9 0,0 12.95,0 12.95,0 0,0 1.56,-7 1.56,-7 C 28.85,0 8.4,0 8.4,0 8.4,0 0,36 0,36 z"/> + <path id="path10" transform="translate(264.4683,187.825)" d="m 7.51,26 c 0,0 2.24,-9.4 2.24,-9.4 1.18,-5.09 3.67,-9.6 8.38,-9.6 0.42,0 0.83,0.21 1.14,0.26 0,0 1.82,-7.21 1.82,-7.21 -0.42,0 -0.88,-0.05 -1.4,-0.05 -3.47,0 -6.38,2.44 -8.32,5.94 0,0 -0.2,0 -0.2,0 C 11.46,4.23 11.71,2.61 11.9,1 11.9,1 5.47,1 5.47,1 5.11,3.08 4.53,7.15 3.66,10.82 3.66,10.82 0,26 0,26 c 0,0 7.51,0 7.51,0 z"/> + <path id="path11" transform="translate(285.0983,187.825)" d="M 20.06,19.25 C 17.99,20.26 15.63,20 12.88,20 10.71,20 9.03,19.62 8.11,18.88 7.63,18.07 7.43,16.81 7.47,16 17.6,16.27 23.99,13.93 24.31,7.53 24.55,2.7 21.02,0 15.89,0 6.73,0 0.73,8.08 0.34,15.86 0,22.65 3.53,26 10.78,26 c 2.79,0 6.5,-0.32 9.52,-1.23 0,0 -0.24,-5.52 -0.24,-5.52 z M 17.32,7.53 C 17.2,9.91 14.26,10.05 8.47,10 9.1,7.91 11.22,6 14.69,6 c 1.71,0 2.69,0.65 2.63,1.53 z"/> + <path id="path12" transform="translate(311.6183,187.825)" d="M 20.05,19.25 C 17.98,20.26 15.62,20 12.88,20 10.7,20 9.03,19.62 8.11,18.88 7.63,18.07 7.42,16.81 7.46,16 17.6,16.27 23.98,13.93 24.31,7.53 24.55,2.7 21.02,0 15.89,0 6.72,0 0.72,8.08 0.33,15.86 0,22.65 3.52,26 10.77,26 c 2.8,0 6.5,-0.32 9.53,-1.23 0,0 -0.25,-5.52 -0.25,-5.52 z M 17.32,7.53 C 17.2,9.91 14.26,10.05 8.46,10 9.1,7.91 11.21,6 14.68,6 c 1.71,0 2.7,0.65 2.64,1.53 z"/> + <path id="path13" transform="translate(337.9983,176.825)" d="M 23.31,0 C 23.31,0 20.5,11.36 20.5,11.36 19.48,10.94 18.15,11 17.11,11 7.53,11 0.75,19.2 0.3,28.08 0,34.34 3.34,37 7.64,37 c 3.01,0 6.18,-1.33 8.58,-4.77 0,0 0.1,0 0.1,0 0,0 -0.57,4.77 -0.57,4.77 0,0 6.78,0 6.78,0 0.31,-3 0.96,-6.57 1.69,-9.83 0,0 6.49,-27.17 6.49,-27.17 0,0 -7.4,0 -7.4,0 z M 17.47,24.42 C 16.3,29.35 13.54,31 11.36,31 9.19,31 7.98,29.49 8.13,26.8 8.38,21.82 11.8,17 16.25,17 c 1.25,0 2.32,0.19 2.91,0.47 0,0 -1.69,6.95 -1.69,6.95 z"/> + <path id="path14" transform="translate(367.7083,187.825)" d="M 10.61,26 C 19.31,26 26.02,19.41 26.49,10.44 26.78,4.5 23.08,0 16.25,0 7.23,0 0.76,7.3 0.31,16.12 0,22.54 4.14,26 10.61,26 z m 1.17,-6 C 9.24,20 7.84,18.38 7.99,15.96 8.19,11.93 10.68,6 14.97,6 c 2.96,0 3.87,2.27 3.75,4.5 -0.22,4.4 -2.9,9.5 -6.94,9.5 z"/> + <path id="path15" transform="translate(396.2683,187.825)" d="M 7.2,26 C 7.2,26 9.9,14.58 9.9,14.58 11.03,9.49 13.85,6 16.38,6 c 1.82,0 2.32,1.33 2.23,3.07 -0.05,0.9 -0.25,1.91 -0.46,2.91 0,0 -3.34,14.02 -3.34,14.02 0,0 7.2,0 7.2,0 0,0 2.7,-11.47 2.7,-11.47 C 25.95,9.28 28.61,6 31.09,6 c 1.71,0 2.42,1.22 2.34,2.96 -0.05,1.01 -0.26,2.12 -0.52,3.13 0,0 -3.24,13.91 -3.24,13.91 0,0 7.25,0 7.25,0 0,0 3.49,-14.81 3.49,-14.81 0.27,-1.33 0.58,-3.4 0.63,-4.46 C 41.26,2.33 39.11,0 35.23,0 31.91,0 28.68,1.5 26.23,4.66 26.14,2.38 24.51,0 20.47,0 17.2,0 14.08,1.48 11.58,4.83 c 0,0 -0.1,0 -0.1,0 0,0 0.67,-3.83 0.67,-3.83 0,0 -6.42,0 -6.42,0 C 5.31,3.14 4.8,5.73 4.02,8.75 4.02,8.75 0,26 0,26 c 0,0 7.2,0 7.2,0 z"/> + </g> + </g> +</svg> \ No newline at end of file diff --git a/extras/Projucer/Source/BinaryData/Icons/huckleberry_icon.svg b/extras/Projucer/Source/BinaryData/Icons/huckleberry_icon.svg deleted file mode 100644 index e0b66e7d..00000000 --- a/extras/Projucer/Source/BinaryData/Icons/huckleberry_icon.svg +++ /dev/null @@ -1,50 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Generator: Adobe Illustrator 21.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> -<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" - viewBox="0 0 169.7 205.2" style="enable-background:new 0 0 169.7 205.2;" xml:space="preserve"> -<style type="text/css"> - .st0{fill:#A65A95;} - .st1{fill:#001946;} -</style> -<g> - <g> - <path class="st0" d="M45.2,167.8c-3,0-5.4-1.1-7.8-4.3l3.6-3.1c1.6,2.1,2.7,2.7,4.2,2.7c2.6,0,4.4-2,4.4-5v-17.2h5V158 - C54.6,163.9,50.7,167.8,45.2,167.8z"/> - <path class="st0" d="M70.7,167.8c-5.8,0-10.8-4.2-10.8-11.2v-15.8h5v15.6c0,4.1,2.4,6.7,5.8,6.7c3.4,0,5.8-2.6,5.8-6.7v-15.6h5 - v15.8C81.5,163.5,76.5,167.8,70.7,167.8z"/> - <path class="st0" d="M99,167.8c-7.6,0-13.9-6.1-13.9-13.6c0-7.6,6.3-13.6,13.9-13.6c3.4,0,6.3,1.2,9.1,3.4l-2.9,3.6 - c-2.6-1.8-4.1-2.4-6.2-2.4c-4.8,0-8.8,3.9-8.8,9c0,5,3.9,9,8.8,9c2,0,3.6-0.6,6.1-2.4l3,3.7C104.6,167,102,167.8,99,167.8z"/> - <path class="st0" d="M111.3,167.4v-26.6h16.6v4.5h-11.6v6.4h11.2v4.5h-11.2v6.7h11.6v4.5H111.3z"/> - </g> - <g> - <circle class="st1" cx="84.9" cy="74.9" r="37.4"/> - <circle class="st0" cx="84.9" cy="74.9" r="28"/> - <circle class="st1" cx="84.9" cy="67.9" r="2.1"/> - <circle class="st1" cx="91.4" cy="72.6" r="2.1"/> - <circle class="st1" cx="88.9" cy="80.3" r="2.1"/> - <circle class="st1" cx="80.8" cy="80.3" r="2.1"/> - <circle class="st1" cx="78.3" cy="72.6" r="2.1"/> - </g> - <g> - <path class="st1" d="M48.2,131.7v-4.6h-4.3v4.6h-2V121h2v4.3h4.3V121h2v10.8H48.2z"/> - <path class="st1" d="M56.7,131.7v-0.5c-0.5,0.4-1.3,0.7-2.1,0.7c-1.9,0-3.2-1.3-3.2-3.4v-5h2v4.8c0,1.2,0.7,1.8,1.7,1.8 - c1,0,1.7-0.7,1.7-1.8v-4.8h2v8.3H56.7z"/> - <path class="st1" d="M63.8,131.9c-2.4,0-4.3-1.9-4.3-4.3c0-2.4,1.9-4.3,4.3-4.3c1.1,0,2.1,0.4,3.3,1.5l-1.3,1.2 - c-0.7-0.7-1.3-1-2-1c-1.3,0-2.3,1.1-2.3,2.5c0,1.3,1,2.5,2.3,2.5c0.6,0,1.3-0.2,2-0.9l1.3,1.2C66,131.5,65,131.9,63.8,131.9z"/> - <path class="st1" d="M73.8,131.7l-3.9-3.9v3.9h-2v-11.3h2v6.8l3.6-3.7h2.5l-3.9,4l4.3,4.3H73.8z"/> - <path class="st1" d="M77.1,131.7v-11.3h2v11.3H77.1z"/> - <path class="st1" d="M88.6,128.4h-6.2c0.1,1,1.1,1.7,2.1,1.7c0.7,0,1.5-0.3,2.3-1.1l1.3,1.2c-1.1,1.2-2.3,1.7-3.6,1.7 - c-2.4,0-4.3-1.9-4.3-4.3c0-2.4,1.9-4.3,4.3-4.3c2.4,0,4.1,1.9,4.1,4.2C88.7,127.9,88.6,128.4,88.6,128.4z M84.5,125.1 - c-1,0-1.9,0.6-2.1,1.5h4.1C86.3,125.8,85.5,125.1,84.5,125.1z"/> - <path class="st1" d="M93.9,131.9c-0.9,0-1.7-0.3-2.3-0.8v0.6h-2v-11.3h2v3.7c0.6-0.5,1.4-0.8,2.3-0.8c2.3,0,4.2,1.9,4.2,4.3 - C98.1,129.9,96.2,131.9,93.9,131.9z M93.9,125.1c-1.3,0-2.2,1.1-2.2,2.5c0,1.4,1,2.5,2.2,2.5c1.3,0,2.2-1.1,2.2-2.5 - C96.2,126.2,95.2,125.1,93.9,125.1z"/> - <path class="st1" d="M107.4,128.4h-6.2c0.1,1,1.1,1.7,2.1,1.7c0.7,0,1.5-0.3,2.3-1.1l1.3,1.2c-1.1,1.2-2.3,1.7-3.6,1.7 - c-2.4,0-4.3-1.9-4.3-4.3c0-2.4,1.9-4.3,4.3-4.3c2.4,0,4.1,1.9,4.1,4.2C107.5,127.9,107.4,128.4,107.4,128.4z M103.3,125.1 - c-1,0-1.9,0.6-2.1,1.5h4.1C105.1,125.8,104.3,125.1,103.3,125.1z"/> - <path class="st1" d="M110.4,127.8v3.9h-2v-8.3h2v0.8c0.7-0.6,1.4-0.9,2.6-1v1.8C111,125.4,110.4,126.6,110.4,127.8z"/> - <path class="st1" d="M116,127.8v3.9h-2v-8.3h2v0.8c0.7-0.6,1.4-0.9,2.6-1v1.8C116.6,125.4,116,126.6,116,127.8z"/> - <path class="st1" d="M122.2,134.6h-2.1l2.2-4.2l-3.4-6.9h2.1l2.4,4.8l2.3-4.8h2.2L122.2,134.6z"/> - </g> -</g> -</svg> diff --git a/extras/Projucer/Source/BinaryData/Templates/jucer_AnimatedComponentSimpleTemplate.h b/extras/Projucer/Source/BinaryData/Templates/jucer_AnimatedComponentSimpleTemplate.h index 62ff60ab..850c24de 100644 --- a/extras/Projucer/Source/BinaryData/Templates/jucer_AnimatedComponentSimpleTemplate.h +++ b/extras/Projucer/Source/BinaryData/Templates/jucer_AnimatedComponentSimpleTemplate.h @@ -1,11 +1,3 @@ -/* - ============================================================================== - - This file was auto-generated! - - ============================================================================== -*/ - #pragma once %%include_juce%% @@ -15,7 +7,7 @@ This component lives inside our window, and this is where you should put all your controls and content. */ -class %%content_component_class%% : public AnimatedAppComponent +class %%content_component_class%% : public juce::AnimatedAppComponent { public: //============================================================================== @@ -27,7 +19,7 @@ public: setFramesPerSecond (60); // This sets the frequency of the update calls. } - ~%%content_component_class%%() + ~%%content_component_class%%() override { } @@ -39,10 +31,10 @@ public: } //============================================================================== - void paint (Graphics& g) override + void paint (juce::Graphics& g) override { // (Our component is opaque, so we must completely fill the background with a solid colour) - g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId)); + g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId)); // You can add your drawing code here! } diff --git a/extras/Projucer/Source/BinaryData/Templates/jucer_AnimatedComponentTemplate.cpp b/extras/Projucer/Source/BinaryData/Templates/jucer_AnimatedComponentTemplate.cpp index fbbcbc89..e6c11d3a 100644 --- a/extras/Projucer/Source/BinaryData/Templates/jucer_AnimatedComponentTemplate.cpp +++ b/extras/Projucer/Source/BinaryData/Templates/jucer_AnimatedComponentTemplate.cpp @@ -1,11 +1,3 @@ -/* - ============================================================================== - - This file was auto-generated! - - ============================================================================== -*/ - %%include_corresponding_header%% //============================================================================== @@ -29,10 +21,10 @@ void %%content_component_class%%::update() } //============================================================================== -void %%content_component_class%%::paint (Graphics& g) +void %%content_component_class%%::paint (juce::Graphics& g) { // (Our component is opaque, so we must completely fill the background with a solid colour) - g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId)); + g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId)); // You can add your drawing code here! } diff --git a/extras/Projucer/Source/BinaryData/Templates/jucer_AnimatedComponentTemplate.h b/extras/Projucer/Source/BinaryData/Templates/jucer_AnimatedComponentTemplate.h index f8e8f7af..fb2d9b5f 100644 --- a/extras/Projucer/Source/BinaryData/Templates/jucer_AnimatedComponentTemplate.h +++ b/extras/Projucer/Source/BinaryData/Templates/jucer_AnimatedComponentTemplate.h @@ -1,11 +1,3 @@ -/* - ============================================================================== - - This file was auto-generated! - - ============================================================================== -*/ - #pragma once %%include_juce%% @@ -15,18 +7,18 @@ This component lives inside our window, and this is where you should put all your controls and content. */ -class %%content_component_class%% : public AnimatedAppComponent +class %%content_component_class%% : public juce::AnimatedAppComponent { public: //============================================================================== %%content_component_class%%(); - ~%%content_component_class%%(); + ~%%content_component_class%%() override; //============================================================================== void update() override; //============================================================================== - void paint (Graphics& g) override; + void paint (juce::Graphics& g) override; void resized() override; private: diff --git a/extras/Projucer/Source/BinaryData/Templates/jucer_AudioComponentSimpleTemplate.h b/extras/Projucer/Source/BinaryData/Templates/jucer_AudioComponentSimpleTemplate.h index d0cba520..690be702 100644 --- a/extras/Projucer/Source/BinaryData/Templates/jucer_AudioComponentSimpleTemplate.h +++ b/extras/Projucer/Source/BinaryData/Templates/jucer_AudioComponentSimpleTemplate.h @@ -1,11 +1,3 @@ -/* - ============================================================================== - - This file was auto-generated! - - ============================================================================== -*/ - #pragma once %%include_juce%% @@ -15,7 +7,7 @@ This component lives inside our window, and this is where you should put all your controls and content. */ -class %%content_component_class%% : public AudioAppComponent +class %%content_component_class%% : public juce::AudioAppComponent { public: //============================================================================== @@ -26,11 +18,11 @@ public: setSize (800, 600); // Some platforms require permissions to open input channels so request that here - if (RuntimePermissions::isRequired (RuntimePermissions::recordAudio) - && ! RuntimePermissions::isGranted (RuntimePermissions::recordAudio)) + if (juce::RuntimePermissions::isRequired (juce::RuntimePermissions::recordAudio) + && ! juce::RuntimePermissions::isGranted (juce::RuntimePermissions::recordAudio)) { - RuntimePermissions::request (RuntimePermissions::recordAudio, - [&] (bool granted) { if (granted) setAudioChannels (2, 2); }); + juce::RuntimePermissions::request (juce::RuntimePermissions::recordAudio, + [&] (bool granted) { setAudioChannels (granted ? 2 : 0, 2); }); } else { @@ -39,7 +31,7 @@ public: } } - ~%%content_component_class%%() + ~%%content_component_class%%() override { // This shuts down the audio device and clears the audio source. shutdownAudio(); @@ -57,7 +49,7 @@ public: // For more details, see the help for AudioProcessor::prepareToPlay() } - void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) override + void getNextAudioBlock (const juce::AudioSourceChannelInfo& bufferToFill) override { // Your audio-processing code goes here! @@ -77,10 +69,10 @@ public: } //============================================================================== - void paint (Graphics& g) override + void paint (juce::Graphics& g) override { // (Our component is opaque, so we must completely fill the background with a solid colour) - g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId)); + g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId)); // You can add your drawing code here! } diff --git a/extras/Projucer/Source/BinaryData/Templates/jucer_AudioComponentTemplate.cpp b/extras/Projucer/Source/BinaryData/Templates/jucer_AudioComponentTemplate.cpp index 946bc7bf..84c4fea1 100644 --- a/extras/Projucer/Source/BinaryData/Templates/jucer_AudioComponentTemplate.cpp +++ b/extras/Projucer/Source/BinaryData/Templates/jucer_AudioComponentTemplate.cpp @@ -1,11 +1,3 @@ -/* - ============================================================================== - - This file was auto-generated! - - ============================================================================== -*/ - %%include_corresponding_header%% //============================================================================== @@ -16,11 +8,11 @@ setSize (800, 600); // Some platforms require permissions to open input channels so request that here - if (RuntimePermissions::isRequired (RuntimePermissions::recordAudio) - && ! RuntimePermissions::isGranted (RuntimePermissions::recordAudio)) + if (juce::RuntimePermissions::isRequired (juce::RuntimePermissions::recordAudio) + && ! juce::RuntimePermissions::isGranted (juce::RuntimePermissions::recordAudio)) { - RuntimePermissions::request (RuntimePermissions::recordAudio, - [&] (bool granted) { if (granted) setAudioChannels (2, 2); }); + juce::RuntimePermissions::request (juce::RuntimePermissions::recordAudio, + [&] (bool granted) { setAudioChannels (granted ? 2 : 0, 2); }); } else { @@ -47,7 +39,7 @@ void %%content_component_class%%::prepareToPlay (int samplesPerBlockExpected, do // For more details, see the help for AudioProcessor::prepareToPlay() } -void %%content_component_class%%::getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) +void %%content_component_class%%::getNextAudioBlock (const juce::AudioSourceChannelInfo& bufferToFill) { // Your audio-processing code goes here! @@ -67,10 +59,10 @@ void %%content_component_class%%::releaseResources() } //============================================================================== -void %%content_component_class%%::paint (Graphics& g) +void %%content_component_class%%::paint (juce::Graphics& g) { // (Our component is opaque, so we must completely fill the background with a solid colour) - g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId)); + g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId)); // You can add your drawing code here! } diff --git a/extras/Projucer/Source/BinaryData/Templates/jucer_AudioComponentTemplate.h b/extras/Projucer/Source/BinaryData/Templates/jucer_AudioComponentTemplate.h index 99c2590a..1d78d85e 100644 --- a/extras/Projucer/Source/BinaryData/Templates/jucer_AudioComponentTemplate.h +++ b/extras/Projucer/Source/BinaryData/Templates/jucer_AudioComponentTemplate.h @@ -1,11 +1,3 @@ -/* - ============================================================================== - - This file was auto-generated! - - ============================================================================== -*/ - #pragma once %%include_juce%% @@ -15,20 +7,20 @@ This component lives inside our window, and this is where you should put all your controls and content. */ -class %%content_component_class%% : public AudioAppComponent +class %%content_component_class%% : public juce::AudioAppComponent { public: //============================================================================== %%content_component_class%%(); - ~%%content_component_class%%(); + ~%%content_component_class%%() override; //============================================================================== void prepareToPlay (int samplesPerBlockExpected, double sampleRate) override; - void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) override; + void getNextAudioBlock (const juce::AudioSourceChannelInfo& bufferToFill) override; void releaseResources() override; //============================================================================== - void paint (Graphics& g) override; + void paint (juce::Graphics& g) override; void resized() override; private: diff --git a/extras/Projucer/Source/BinaryData/Templates/jucer_AudioPluginEditorTemplate.cpp b/extras/Projucer/Source/BinaryData/Templates/jucer_AudioPluginEditorTemplate.cpp index b94d9843..e68c0a7e 100644 --- a/extras/Projucer/Source/BinaryData/Templates/jucer_AudioPluginEditorTemplate.cpp +++ b/extras/Projucer/Source/BinaryData/Templates/jucer_AudioPluginEditorTemplate.cpp @@ -1,9 +1,7 @@ /* ============================================================================== - This file was auto-generated! - - It contains the basic framework code for a JUCE plugin editor. + This file contains the basic framework code for a JUCE plugin editor. ============================================================================== */ @@ -12,7 +10,7 @@ //============================================================================== %%editor_class_name%%::%%editor_class_name%% (%%filter_class_name%%& p) - : AudioProcessorEditor (&p), processor (p) + : AudioProcessorEditor (&p), audioProcessor (p) { // Make sure that before the constructor has finished, you've set the // editor's size to whatever you need it to be. @@ -24,14 +22,14 @@ } //============================================================================== -void %%editor_class_name%%::paint (Graphics& g) +void %%editor_class_name%%::paint (juce::Graphics& g) { // (Our component is opaque, so we must completely fill the background with a solid colour) - g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId)); + g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId)); - g.setColour (Colours::white); + g.setColour (juce::Colours::white); g.setFont (15.0f); - g.drawFittedText ("Hello World!", getLocalBounds(), Justification::centred, 1); + g.drawFittedText ("Hello World!", getLocalBounds(), juce::Justification::centred, 1); } void %%editor_class_name%%::resized() diff --git a/extras/Projucer/Source/BinaryData/Templates/jucer_AudioPluginEditorTemplate.h b/extras/Projucer/Source/BinaryData/Templates/jucer_AudioPluginEditorTemplate.h index 50c948ce..7a3f4ef7 100644 --- a/extras/Projucer/Source/BinaryData/Templates/jucer_AudioPluginEditorTemplate.h +++ b/extras/Projucer/Source/BinaryData/Templates/jucer_AudioPluginEditorTemplate.h @@ -1,9 +1,7 @@ /* ============================================================================== - This file was auto-generated! - - It contains the basic framework code for a JUCE plugin editor. + This file contains the basic framework code for a JUCE plugin editor. ============================================================================== */ @@ -15,20 +13,20 @@ //============================================================================== /** */ -class %%editor_class_name%% : public AudioProcessorEditor +class %%editor_class_name%% : public juce::AudioProcessorEditor { public: %%editor_class_name%% (%%filter_class_name%%&); - ~%%editor_class_name%%(); + ~%%editor_class_name%%() override; //============================================================================== - void paint (Graphics&) override; + void paint (juce::Graphics&) override; void resized() override; private: // This reference is provided as a quick way for your editor to // access the processor object that created it. - %%filter_class_name%%& processor; + %%filter_class_name%%& audioProcessor; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%editor_class_name%%) }; diff --git a/extras/Projucer/Source/BinaryData/Templates/jucer_AudioPluginFilterTemplate.cpp b/extras/Projucer/Source/BinaryData/Templates/jucer_AudioPluginFilterTemplate.cpp index 66387e98..0b194bdb 100644 --- a/extras/Projucer/Source/BinaryData/Templates/jucer_AudioPluginFilterTemplate.cpp +++ b/extras/Projucer/Source/BinaryData/Templates/jucer_AudioPluginFilterTemplate.cpp @@ -1,9 +1,7 @@ /* ============================================================================== - This file was auto-generated! - - It contains the basic framework code for a JUCE plugin processor. + This file contains the basic framework code for a JUCE plugin processor. ============================================================================== */ @@ -16,9 +14,9 @@ : AudioProcessor (BusesProperties() #if ! JucePlugin_IsMidiEffect #if ! JucePlugin_IsSynth - .withInput ("Input", AudioChannelSet::stereo(), true) + .withInput ("Input", juce::AudioChannelSet::stereo(), true) #endif - .withOutput ("Output", AudioChannelSet::stereo(), true) + .withOutput ("Output", juce::AudioChannelSet::stereo(), true) #endif ) #endif @@ -30,7 +28,7 @@ } //============================================================================== -const String %%filter_class_name%%::getName() const +const juce::String %%filter_class_name%%::getName() const { return JucePlugin_Name; } @@ -82,12 +80,12 @@ void %%filter_class_name%%::setCurrentProgram (int index) { } -const String %%filter_class_name%%::getProgramName (int index) +const juce::String %%filter_class_name%%::getProgramName (int index) { return {}; } -void %%filter_class_name%%::changeProgramName (int index, const String& newName) +void %%filter_class_name%%::changeProgramName (int index, const juce::String& newName) { } @@ -108,13 +106,13 @@ void %%filter_class_name%%::releaseResources() bool %%filter_class_name%%::isBusesLayoutSupported (const BusesLayout& layouts) const { #if JucePlugin_IsMidiEffect - ignoreUnused (layouts); + juce::ignoreUnused (layouts); return true; #else // This is the place where you check if the layout is supported. // In this template code we only support mono or stereo. - if (layouts.getMainOutputChannelSet() != AudioChannelSet::mono() - && layouts.getMainOutputChannelSet() != AudioChannelSet::stereo()) + if (layouts.getMainOutputChannelSet() != juce::AudioChannelSet::mono() + && layouts.getMainOutputChannelSet() != juce::AudioChannelSet::stereo()) return false; // This checks if the input layout matches the output layout @@ -128,9 +126,9 @@ bool %%filter_class_name%%::isBusesLayoutSupported (const BusesLayout& layouts) } #endif -void %%filter_class_name%%::processBlock (AudioBuffer<float>& buffer, MidiBuffer& midiMessages) +void %%filter_class_name%%::processBlock (juce::AudioBuffer<float>& buffer, juce::MidiBuffer& midiMessages) { - ScopedNoDenormals noDenormals; + juce::ScopedNoDenormals noDenormals; auto totalNumInputChannels = getTotalNumInputChannels(); auto totalNumOutputChannels = getTotalNumOutputChannels(); @@ -163,13 +161,13 @@ bool %%filter_class_name%%::hasEditor() const return true; // (change this to false if you choose to not supply an editor) } -AudioProcessorEditor* %%filter_class_name%%::createEditor() +juce::AudioProcessorEditor* %%filter_class_name%%::createEditor() { return new %%editor_class_name%% (*this); } //============================================================================== -void %%filter_class_name%%::getStateInformation (MemoryBlock& destData) +void %%filter_class_name%%::getStateInformation (juce::MemoryBlock& destData) { // You should use this method to store your parameters in the memory block. // You could do that either as raw data, or use the XML or ValueTree classes @@ -184,7 +182,7 @@ void %%filter_class_name%%::setStateInformation (const void* data, int sizeInByt //============================================================================== // This creates new instances of the plugin.. -AudioProcessor* JUCE_CALLTYPE createPluginFilter() +juce::AudioProcessor* JUCE_CALLTYPE createPluginFilter() { return new %%filter_class_name%%(); } diff --git a/extras/Projucer/Source/BinaryData/Templates/jucer_AudioPluginFilterTemplate.h b/extras/Projucer/Source/BinaryData/Templates/jucer_AudioPluginFilterTemplate.h index d1668e95..bfc4dc95 100644 --- a/extras/Projucer/Source/BinaryData/Templates/jucer_AudioPluginFilterTemplate.h +++ b/extras/Projucer/Source/BinaryData/Templates/jucer_AudioPluginFilterTemplate.h @@ -1,9 +1,7 @@ /* ============================================================================== - This file was auto-generated! - - It contains the basic framework code for a JUCE plugin processor. + This file contains the basic framework code for a JUCE plugin processor. ============================================================================== */ @@ -15,12 +13,12 @@ //============================================================================== /** */ -class %%filter_class_name%% : public AudioProcessor +class %%filter_class_name%% : public juce::AudioProcessor { public: //============================================================================== %%filter_class_name%%(); - ~%%filter_class_name%%(); + ~%%filter_class_name%%() override; //============================================================================== void prepareToPlay (double sampleRate, int samplesPerBlock) override; @@ -30,14 +28,14 @@ public: bool isBusesLayoutSupported (const BusesLayout& layouts) const override; #endif - void processBlock (AudioBuffer<float>&, MidiBuffer&) override; + void processBlock (juce::AudioBuffer<float>&, juce::MidiBuffer&) override; //============================================================================== - AudioProcessorEditor* createEditor() override; + juce::AudioProcessorEditor* createEditor() override; bool hasEditor() const override; //============================================================================== - const String getName() const override; + const juce::String getName() const override; bool acceptsMidi() const override; bool producesMidi() const override; @@ -48,11 +46,11 @@ public: int getNumPrograms() override; int getCurrentProgram() override; void setCurrentProgram (int index) override; - const String getProgramName (int index) override; - void changeProgramName (int index, const String& newName) override; + const juce::String getProgramName (int index) override; + void changeProgramName (int index, const juce::String& newName) override; //============================================================================== - void getStateInformation (MemoryBlock& destData) override; + void getStateInformation (juce::MemoryBlock& destData) override; void setStateInformation (const void* data, int sizeInBytes) override; private: diff --git a/extras/Projucer/Source/BinaryData/Templates/jucer_ComponentTemplate.cpp b/extras/Projucer/Source/BinaryData/Templates/jucer_ComponentTemplate.cpp index 11845388..f2433e7c 100644 --- a/extras/Projucer/Source/BinaryData/Templates/jucer_ComponentTemplate.cpp +++ b/extras/Projucer/Source/BinaryData/Templates/jucer_ComponentTemplate.cpp @@ -12,7 +12,7 @@ ------------------------------------------------------------------------------ The Projucer is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited. ============================================================================== */ diff --git a/extras/Projucer/Source/BinaryData/Templates/jucer_ComponentTemplate.h b/extras/Projucer/Source/BinaryData/Templates/jucer_ComponentTemplate.h index ffaafbfc..11b92e65 100644 --- a/extras/Projucer/Source/BinaryData/Templates/jucer_ComponentTemplate.h +++ b/extras/Projucer/Source/BinaryData/Templates/jucer_ComponentTemplate.h @@ -12,7 +12,7 @@ ------------------------------------------------------------------------------ The Projucer is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited. ============================================================================== */ diff --git a/extras/Projucer/Source/BinaryData/Templates/jucer_ContentCompSimpleTemplate.h b/extras/Projucer/Source/BinaryData/Templates/jucer_ContentCompSimpleTemplate.h index 8178bea4..696efd7b 100644 --- a/extras/Projucer/Source/BinaryData/Templates/jucer_ContentCompSimpleTemplate.h +++ b/extras/Projucer/Source/BinaryData/Templates/jucer_ContentCompSimpleTemplate.h @@ -1,11 +1,3 @@ -/* - ============================================================================== - - This file was auto-generated! - - ============================================================================== -*/ - #pragma once %%include_juce%% @@ -15,7 +7,7 @@ This component lives inside our window, and this is where you should put all your controls and content. */ -class %%content_component_class%% : public Component +class %%content_component_class%% : public juce::Component { public: //============================================================================== @@ -24,19 +16,19 @@ public: setSize (600, 400); } - ~%%content_component_class%%() + ~%%content_component_class%%() override { } //============================================================================== - void paint (Graphics& g) override + void paint (juce::Graphics& g) override { // (Our component is opaque, so we must completely fill the background with a solid colour) - g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId)); + g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId)); - g.setFont (Font (16.0f)); - g.setColour (Colours::white); - g.drawText ("Hello World!", getLocalBounds(), Justification::centred, true); + g.setFont (juce::Font (16.0f)); + g.setColour (juce::Colours::white); + g.drawText ("Hello World!", getLocalBounds(), juce::Justification::centred, true); } void resized() override diff --git a/extras/Projucer/Source/BinaryData/Templates/jucer_ContentCompTemplate.cpp b/extras/Projucer/Source/BinaryData/Templates/jucer_ContentCompTemplate.cpp index a55ad088..59e3da34 100644 --- a/extras/Projucer/Source/BinaryData/Templates/jucer_ContentCompTemplate.cpp +++ b/extras/Projucer/Source/BinaryData/Templates/jucer_ContentCompTemplate.cpp @@ -1,11 +1,3 @@ -/* - ============================================================================== - - This file was auto-generated! - - ============================================================================== -*/ - %%include_corresponding_header%% //============================================================================== @@ -19,14 +11,14 @@ } //============================================================================== -void %%content_component_class%%::paint (Graphics& g) +void %%content_component_class%%::paint (juce::Graphics& g) { // (Our component is opaque, so we must completely fill the background with a solid colour) - g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId)); + g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId)); - g.setFont (Font (16.0f)); - g.setColour (Colours::white); - g.drawText ("Hello World!", getLocalBounds(), Justification::centred, true); + g.setFont (juce::Font (16.0f)); + g.setColour (juce::Colours::white); + g.drawText ("Hello World!", getLocalBounds(), juce::Justification::centred, true); } void %%content_component_class%%::resized() diff --git a/extras/Projucer/Source/BinaryData/Templates/jucer_ContentCompTemplate.h b/extras/Projucer/Source/BinaryData/Templates/jucer_ContentCompTemplate.h index 2a87c80e..00c56636 100644 --- a/extras/Projucer/Source/BinaryData/Templates/jucer_ContentCompTemplate.h +++ b/extras/Projucer/Source/BinaryData/Templates/jucer_ContentCompTemplate.h @@ -1,11 +1,3 @@ -/* - ============================================================================== - - This file was auto-generated! - - ============================================================================== -*/ - #pragma once %%include_juce%% @@ -15,15 +7,15 @@ This component lives inside our window, and this is where you should put all your controls and content. */ -class %%content_component_class%% : public Component +class %%content_component_class%% : public juce::Component { public: //============================================================================== %%content_component_class%%(); - ~%%content_component_class%%(); + ~%%content_component_class%%() override; //============================================================================== - void paint (Graphics&) override; + void paint (juce::Graphics&) override; void resized() override; private: diff --git a/extras/Projucer/Source/BinaryData/Templates/jucer_InlineComponentTemplate.h b/extras/Projucer/Source/BinaryData/Templates/jucer_InlineComponentTemplate.h index cd73fcf5..51476373 100644 --- a/extras/Projucer/Source/BinaryData/Templates/jucer_InlineComponentTemplate.h +++ b/extras/Projucer/Source/BinaryData/Templates/jucer_InlineComponentTemplate.h @@ -1,5 +1,5 @@ //============================================================================== -class %%component_class%% : public Component +class %%component_class%% : public juce::Component { public: %%component_class%%() @@ -9,23 +9,23 @@ public: } - ~%%component_class%%() + ~%%component_class%%() override { } - void paint (Graphics& g) override + void paint (juce::Graphics& g) override { // You should replace everything in this method with your own drawing code.. - g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId)); // clear the background + g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId)); // clear the background - g.setColour (Colours::grey); + g.setColour (juce::Colours::grey); g.drawRect (getLocalBounds(), 1); // draw an outline around the component - g.setColour (Colours::white); + g.setColour (juce::Colours::white); g.setFont (14.0f); g.drawText ("%%component_class%%", getLocalBounds(), - Justification::centred, true); // draw some placeholder text + juce::Justification::centred, true); // draw some placeholder text } void resized() override diff --git a/extras/Projucer/Source/BinaryData/Templates/jucer_MainConsoleAppTemplate.cpp b/extras/Projucer/Source/BinaryData/Templates/jucer_MainConsoleAppTemplate.cpp index 27987d4a..17a84b90 100644 --- a/extras/Projucer/Source/BinaryData/Templates/jucer_MainConsoleAppTemplate.cpp +++ b/extras/Projucer/Source/BinaryData/Templates/jucer_MainConsoleAppTemplate.cpp @@ -1,9 +1,7 @@ /* ============================================================================== - This file was auto-generated! - - It contains the basic startup code for a JUCE application. + This file contains the basic startup code for a JUCE application. ============================================================================== */ diff --git a/extras/Projucer/Source/BinaryData/Templates/jucer_MainTemplate_NoWindow.cpp b/extras/Projucer/Source/BinaryData/Templates/jucer_MainTemplate_NoWindow.cpp index 24090035..2deaf61a 100644 --- a/extras/Projucer/Source/BinaryData/Templates/jucer_MainTemplate_NoWindow.cpp +++ b/extras/Projucer/Source/BinaryData/Templates/jucer_MainTemplate_NoWindow.cpp @@ -1,9 +1,7 @@ /* ============================================================================== - This file was auto-generated! - - It contains the basic startup code for a JUCE application. + This file contains the basic startup code for a JUCE application. ============================================================================== */ @@ -11,18 +9,18 @@ %%app_headers%% //============================================================================== -class %%app_class_name%% : public JUCEApplication +class %%app_class_name%% : public juce::JUCEApplication { public: //============================================================================== %%app_class_name%%() {} - const String getApplicationName() override { return ProjectInfo::projectName; } - const String getApplicationVersion() override { return ProjectInfo::versionString; } - bool moreThanOneInstanceAllowed() override { return %%allow_more_than_one_instance%%; } + const juce::String getApplicationName() override { return ProjectInfo::projectName; } + const juce::String getApplicationVersion() override { return ProjectInfo::versionString; } + bool moreThanOneInstanceAllowed() override { return true; } //============================================================================== - void initialise (const String& commandLine) override + void initialise (const juce::String& commandLine) override { // Add your application's initialisation code here.. } @@ -40,7 +38,7 @@ public: quit(); } - void anotherInstanceStarted (const String& commandLine) override + void anotherInstanceStarted (const juce::String& commandLine) override { // When another instance of the app is launched while this one is running, // this method is invoked, and the commandLine parameter tells you what diff --git a/extras/Projucer/Source/BinaryData/Templates/jucer_MainTemplate_Window.cpp b/extras/Projucer/Source/BinaryData/Templates/jucer_MainTemplate_Window.cpp index 926eb48a..f4f2fd67 100644 --- a/extras/Projucer/Source/BinaryData/Templates/jucer_MainTemplate_Window.cpp +++ b/extras/Projucer/Source/BinaryData/Templates/jucer_MainTemplate_Window.cpp @@ -1,9 +1,7 @@ /* ============================================================================== - This file was auto-generated! - - It contains the basic startup code for a JUCE application. + This file contains the basic startup code for a JUCE application. ============================================================================== */ @@ -11,18 +9,18 @@ %%app_headers%% //============================================================================== -class %%app_class_name%% : public JUCEApplication +class %%app_class_name%% : public juce::JUCEApplication { public: //============================================================================== %%app_class_name%%() {} - const String getApplicationName() override { return ProjectInfo::projectName; } - const String getApplicationVersion() override { return ProjectInfo::versionString; } - bool moreThanOneInstanceAllowed() override { return %%allow_more_than_one_instance%%; } + const juce::String getApplicationName() override { return ProjectInfo::projectName; } + const juce::String getApplicationVersion() override { return ProjectInfo::versionString; } + bool moreThanOneInstanceAllowed() override { return true; } //============================================================================== - void initialise (const String& commandLine) override + void initialise (const juce::String& commandLine) override { // This method is where you should put your application's initialisation code.. @@ -44,7 +42,7 @@ public: quit(); } - void anotherInstanceStarted (const String& commandLine) override + void anotherInstanceStarted (const juce::String& commandLine) override { // When another instance of the app is launched while this one is running, // this method is invoked, and the commandLine parameter tells you what @@ -56,13 +54,14 @@ public: This class implements the desktop window that contains an instance of our %%content_component_class%% class. */ - class MainWindow : public DocumentWindow + class MainWindow : public juce::DocumentWindow { public: - MainWindow (String name) : DocumentWindow (name, - Desktop::getInstance().getDefaultLookAndFeel() - .findColour (ResizableWindow::backgroundColourId), - DocumentWindow::allButtons) + MainWindow (juce::String name) + : DocumentWindow (name, + juce::Desktop::getInstance().getDefaultLookAndFeel() + .findColour (juce::ResizableWindow::backgroundColourId), + DocumentWindow::allButtons) { setUsingNativeTitleBar (true); setContentOwned (new %%content_component_class%%(), true); diff --git a/extras/Projucer/Source/BinaryData/Templates/jucer_NewComponentTemplate.cpp b/extras/Projucer/Source/BinaryData/Templates/jucer_NewComponentTemplate.cpp index 6b394260..5d6fb68f 100644 --- a/extras/Projucer/Source/BinaryData/Templates/jucer_NewComponentTemplate.cpp +++ b/extras/Projucer/Source/BinaryData/Templates/jucer_NewComponentTemplate.cpp @@ -23,7 +23,7 @@ { } -void %%component_class%%::paint (Graphics& g) +void %%component_class%%::paint (juce::Graphics& g) { /* This demo code just fills the component's background and draws some placeholder text to get you started. @@ -32,15 +32,15 @@ void %%component_class%%::paint (Graphics& g) drawing code.. */ - g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId)); // clear the background + g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId)); // clear the background - g.setColour (Colours::grey); + g.setColour (juce::Colours::grey); g.drawRect (getLocalBounds(), 1); // draw an outline around the component - g.setColour (Colours::white); + g.setColour (juce::Colours::white); g.setFont (14.0f); g.drawText ("%%component_class%%", getLocalBounds(), - Justification::centred, true); // draw some placeholder text + juce::Justification::centred, true); // draw some placeholder text } void %%component_class%%::resized() diff --git a/extras/Projucer/Source/BinaryData/Templates/jucer_NewComponentTemplate.h b/extras/Projucer/Source/BinaryData/Templates/jucer_NewComponentTemplate.h index 2cb07326..d86709b5 100644 --- a/extras/Projucer/Source/BinaryData/Templates/jucer_NewComponentTemplate.h +++ b/extras/Projucer/Source/BinaryData/Templates/jucer_NewComponentTemplate.h @@ -15,13 +15,13 @@ //============================================================================== /* */ -class %%component_class%% : public Component +class %%component_class%% : public juce::Component { public: %%component_class%%(); - ~%%component_class%%(); + ~%%component_class%%() override; - void paint (Graphics&) override; + void paint (juce::Graphics&) override; void resized() override; private: diff --git a/extras/Projucer/Source/BinaryData/Templates/jucer_NewInlineComponentTemplate.h b/extras/Projucer/Source/BinaryData/Templates/jucer_NewInlineComponentTemplate.h index 2a376486..b6dc046d 100644 --- a/extras/Projucer/Source/BinaryData/Templates/jucer_NewInlineComponentTemplate.h +++ b/extras/Projucer/Source/BinaryData/Templates/jucer_NewInlineComponentTemplate.h @@ -15,7 +15,7 @@ //============================================================================== /* */ -class %%component_class%% : public Component +class %%component_class%% : public juce::Component { public: %%component_class%%() @@ -25,11 +25,11 @@ public: } - ~%%component_class%%() + ~%%component_class%%() override { } - void paint (Graphics& g) override + void paint (juce::Graphics& g) override { /* This demo code just fills the component's background and draws some placeholder text to get you started. @@ -38,15 +38,15 @@ public: drawing code.. */ - g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId)); // clear the background + g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId)); // clear the background - g.setColour (Colours::grey); + g.setColour (juce::Colours::grey); g.drawRect (getLocalBounds(), 1); // draw an outline around the component - g.setColour (Colours::white); + g.setColour (juce::Colours::white); g.setFont (14.0f); g.drawText ("%%component_class%%", getLocalBounds(), - Justification::centred, true); // draw some placeholder text + juce::Justification::centred, true); // draw some placeholder text } void resized() override diff --git a/extras/Projucer/Source/BinaryData/Templates/jucer_OpenGLComponentSimpleTemplate.h b/extras/Projucer/Source/BinaryData/Templates/jucer_OpenGLComponentSimpleTemplate.h index e2f463f6..0c8c4e8f 100644 --- a/extras/Projucer/Source/BinaryData/Templates/jucer_OpenGLComponentSimpleTemplate.h +++ b/extras/Projucer/Source/BinaryData/Templates/jucer_OpenGLComponentSimpleTemplate.h @@ -1,11 +1,3 @@ -/* - ============================================================================== - - This file was auto-generated! - - ============================================================================== -*/ - #pragma once %%include_juce%% @@ -15,7 +7,7 @@ This component lives inside our window, and this is where you should put all your controls and content. */ -class %%content_component_class%% : public OpenGLAppComponent +class %%content_component_class%% : public juce::OpenGLAppComponent { public: //============================================================================== @@ -26,7 +18,7 @@ public: setSize (800, 600); } - ~%%content_component_class%%() + ~%%content_component_class%%() override { // This shuts down the GL system and stops the rendering calls. shutdownOpenGL(); @@ -46,13 +38,13 @@ public: void render() override { // This clears the context with a black background. - OpenGLHelpers::clear (Colours::black); + juce::OpenGLHelpers::clear (Colours::black); // Add your rendering code here... } //============================================================================== - void paint (Graphics& g) override + void paint (juce::Graphics& g) override { // You can add your component specific drawing code here! // This will draw over the top of the openGL background. diff --git a/extras/Projucer/Source/BinaryData/Templates/jucer_OpenGLComponentTemplate.cpp b/extras/Projucer/Source/BinaryData/Templates/jucer_OpenGLComponentTemplate.cpp index 1a53e14c..e21fa1d8 100644 --- a/extras/Projucer/Source/BinaryData/Templates/jucer_OpenGLComponentTemplate.cpp +++ b/extras/Projucer/Source/BinaryData/Templates/jucer_OpenGLComponentTemplate.cpp @@ -1,11 +1,3 @@ -/* - ============================================================================== - - This file was auto-generated! - - ============================================================================== -*/ - %%include_corresponding_header%% //============================================================================== @@ -36,13 +28,13 @@ void %%content_component_class%%::shutdown() void %%content_component_class%%::render() { // This clears the context with a black background. - OpenGLHelpers::clear (Colours::black); + juce::OpenGLHelpers::clear (juce::Colours::black); // Add your rendering code here... } //============================================================================== -void %%content_component_class%%::paint (Graphics& g) +void %%content_component_class%%::paint (juce::Graphics& g) { // You can add your component specific drawing code here! // This will draw over the top of the openGL background. diff --git a/extras/Projucer/Source/BinaryData/Templates/jucer_OpenGLComponentTemplate.h b/extras/Projucer/Source/BinaryData/Templates/jucer_OpenGLComponentTemplate.h index c5ad25da..6686dd59 100644 --- a/extras/Projucer/Source/BinaryData/Templates/jucer_OpenGLComponentTemplate.h +++ b/extras/Projucer/Source/BinaryData/Templates/jucer_OpenGLComponentTemplate.h @@ -1,11 +1,3 @@ -/* - ============================================================================== - - This file was auto-generated! - - ============================================================================== -*/ - #pragma once %%include_juce%% @@ -15,12 +7,12 @@ This component lives inside our window, and this is where you should put all your controls and content. */ -class %%content_component_class%% : public OpenGLAppComponent +class %%content_component_class%% : public juce::OpenGLAppComponent { public: //============================================================================== %%content_component_class%%(); - ~%%content_component_class%%(); + ~%%content_component_class%%() override; //============================================================================== void initialise() override; @@ -28,7 +20,7 @@ public: void render() override; //============================================================================== - void paint (Graphics& g) override; + void paint (juce::Graphics& g) override; void resized() override; private: diff --git a/extras/Projucer/Source/BinaryData/Templates/jucer_PIPAudioProcessorTemplate.h b/extras/Projucer/Source/BinaryData/Templates/jucer_PIPAudioProcessorTemplate.h index 32f6b8a8..ddbc5468 100644 --- a/extras/Projucer/Source/BinaryData/Templates/jucer_PIPAudioProcessorTemplate.h +++ b/extras/Projucer/Source/BinaryData/Templates/jucer_PIPAudioProcessorTemplate.h @@ -1,14 +1,14 @@ -class %%class_name%% : public AudioProcessor +class %%class_name%% : public juce::AudioProcessor { public: //============================================================================== %%class_name%%() - : AudioProcessor (BusesProperties().withInput ("Input", AudioChannelSet::stereo()) - .withOutput ("Output", AudioChannelSet::stereo())) + : AudioProcessor (BusesProperties().withInput ("Input", juce::AudioChannelSet::stereo()) + .withOutput ("Output", juce::AudioChannelSet::stereo())) { } - ~%%class_name%%() + ~%%class_name%%() override { } @@ -25,9 +25,9 @@ public: // spare memory, etc. } - void processBlock (AudioBuffer<float>& buffer, MidiBuffer&) override + void processBlock (juce::AudioBuffer<float>& buffer, juce::MidiBuffer&) override { - ScopedNoDenormals noDenormals; + juce::ScopedNoDenormals noDenormals; auto totalNumInputChannels = getTotalNumInputChannels(); auto totalNumOutputChannels = getTotalNumOutputChannels(); @@ -55,24 +55,24 @@ public: } //============================================================================== - AudioProcessorEditor* createEditor() override { return nullptr; } - bool hasEditor() const override { return false; } + juce::AudioProcessorEditor* createEditor() override { return nullptr; } + bool hasEditor() const override { return false; } //============================================================================== - const String getName() const override { return "%%name%%"; } - bool acceptsMidi() const override { return false; } - bool producesMidi() const override { return false; } - double getTailLengthSeconds() const override { return 0; } + const juce::String getName() const override { return "%%name%%"; } + bool acceptsMidi() const override { return false; } + bool producesMidi() const override { return false; } + double getTailLengthSeconds() const override { return 0; } //============================================================================== - int getNumPrograms() override { return 1; } - int getCurrentProgram() override { return 0; } - void setCurrentProgram (int) override {} - const String getProgramName (int) override { return {}; } - void changeProgramName (int, const String&) override {} + int getNumPrograms() override { return 1; } + int getCurrentProgram() override { return 0; } + void setCurrentProgram (int) override {} + const juce::String getProgramName (int) override { return {}; } + void changeProgramName (int, const juce::String&) override {} //============================================================================== - void getStateInformation (MemoryBlock& destData) override + void getStateInformation (juce::MemoryBlock& destData) override { // You should use this method to store your parameters in the memory block. // You could do that either as raw data, or use the XML or ValueTree classes @@ -90,8 +90,8 @@ public: { // This is the place where you check if the layout is supported. // In this template code we only support mono or stereo. - if (layouts.getMainOutputChannelSet() != AudioChannelSet::mono() - && layouts.getMainOutputChannelSet() != AudioChannelSet::stereo()) + if (layouts.getMainOutputChannelSet() != juce::AudioChannelSet::mono() + && layouts.getMainOutputChannelSet() != juce::AudioChannelSet::stereo()) return false; // This checks if the input layout matches the output layout diff --git a/extras/Projucer/Source/BinaryData/Templates/jucer_PIPMain.cpp b/extras/Projucer/Source/BinaryData/Templates/jucer_PIPMain.cpp deleted file mode 100644 index da0677bd..00000000 --- a/extras/Projucer/Source/BinaryData/Templates/jucer_PIPMain.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - ============================================================================== - - This file was auto-generated and contains the startup code for a PIP. - - ============================================================================== -*/ - -%%include_juce%% -#include "%%filename%%" - -%%component_begin%% -class Application : public JUCEApplication -{ -public: - //============================================================================== - Application() {} - - const String getApplicationName() override { return "%%project_name%%"; } - const String getApplicationVersion() override { return "%%project_version%%"; } - - void initialise (const String&) override { %%startup%% } - void shutdown() override { %%shutdown%% } - -private: - class MainWindow : public DocumentWindow - { - public: - MainWindow (const String& name, Component* c, JUCEApplication& a) - : DocumentWindow (name, Desktop::getInstance().getDefaultLookAndFeel() - .findColour (ResizableWindow::backgroundColourId), - DocumentWindow::allButtons), - app (a) - { - setUsingNativeTitleBar (true); - setContentOwned (c, true); - - #if JUCE_ANDROID || JUCE_IOS - setFullScreen (true); - #else - setResizable (true, false); - setResizeLimits (300, 250, 10000, 10000); - centreWithSize (getWidth(), getHeight()); - #endif - - setVisible (true); - } - - void closeButtonPressed() override - { - app.systemRequestedQuit(); - } - - private: - JUCEApplication& app; - - //============================================================================== - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainWindow) - }; - - std::unique_ptr<MainWindow> mainWindow; -}; - -//============================================================================== -START_JUCE_APPLICATION (Application) -%%component_end%% - -%%audioprocessor_begin%% -//============================================================================== -AudioProcessor* JUCE_CALLTYPE createPluginFilter() -{ - return new %%class_name%%(); -} -%%audioprocessor_end%% - -%%console_begin%% -%%console_end%% diff --git a/extras/Projucer/Source/BinaryData/nothingtoseehere.txt b/extras/Projucer/Source/BinaryData/nothingtoseehere.txt deleted file mode 100644 index 99a42c64..00000000 --- a/extras/Projucer/Source/BinaryData/nothingtoseehere.txt +++ /dev/null @@ -1 +0,0 @@ -VUEtMTk3NTkzMTgtNA== \ No newline at end of file diff --git a/extras/Projucer/Source/BinaryData/offlinepage.html b/extras/Projucer/Source/BinaryData/offlinepage.html deleted file mode 100644 index f5993aa0..00000000 --- a/extras/Projucer/Source/BinaryData/offlinepage.html +++ /dev/null @@ -1,42 +0,0 @@ -<html> - <head> - <meta http-equiv="X-UA-Compatible" content="IE=11"> - <style> - body { - background-color: #f1f1f1; - color: #101010; - font-family: Helvetica, Arial, sans-serif; - display: flex; - justify-content: center; - align-items: center; - } - .button { - display: block; - padding: 15px 20px 16px; - width: 200px; - border: 1px solid #c8c9cb; - border-radius: 6px; - margin: auto; - cursor: pointer; - font-size: 20px; - margin-top: 30px; - color: inherit; - text-decoration: none; - } - #offline { - display: block; - text-align: center; - } - </style> - </head> - <body> - <div id='offline'> - <h1>No internet connection</h1> - - <p>You appear to be offline. An internet connection is required to login to the Projucer.</p> - <p>If you want to use JUCE under the GPL without signing-in, you can enable the pre-processor macro JUCER_ENABLE_GPL_MODE=1 and recompile the Projucer yourself.</p> - - <a class='button' href='__URL_PLACEHOLDER__'>Try again</a> - </div> - </body> -</html> \ No newline at end of file diff --git a/extras/Projucer/Source/BinaryData/projucer_EULA.txt b/extras/Projucer/Source/BinaryData/projucer_EULA.txt deleted file mode 100644 index 31df3379..00000000 --- a/extras/Projucer/Source/BinaryData/projucer_EULA.txt +++ /dev/null @@ -1,142 +0,0 @@ - -IMPORTANT NOTICE: PLEASE READ CAREFULLY BEFORE INSTALLING THE SOFTWARE: - -This license agreement (License) is a legal agreement between you (Licensee or you) and Raw Material Software Limited (Licensor, us or we) for: - -- The Projucer software and the associated media and, save where expressly specified through subsequent license terms notified to you in writing, any and all new releases, derivatives of and updates thereto supplied by us to you for a period of one (1) month from the date of your installation of the software (the Software); - -- printed materials and online and electronic documentation (Documentation). - -The Software is comprised of numerous components that may be licensed under separate license terms. The Software is a collective work of the Licensor and we license the use of the Software and Documentation to you on the basis of this License and any applicable license terms for any third party software components which make up the Software. Where you deal with a copy of any software component independent from the Software, you must remove all our trade marks, trade dress and logos from that copy. - -We do not sell the Software or Documentation to you. We and/or our licensors remain the owners of the Software and Documentation at all times. If you are accepting the terms of this License on behalf of a company or other legal entity, you represent and warrant that you have the authority to bind that company or other legal entity to the terms of this License and, in such event, "you" and "Licensee" will refer to that company or other legal entity. - -The Software may be downloaded from the Licensor website - www.juce.com - (the "Website"). - -OPERATING SYSTEM REQUIREMENTS: The Software requires a Windows or MAC OS X operating system. - -IMPORTANT NOTICE TO ALL USERS: - -- BY CLICKING ON THE "ACCEPT" BUTTON BELOW YOU AGREE TO THE TERMS OF THIS LICENCE WHICH WILL BIND YOU AND YOUR EMPLOYEES. - -- IF YOU DO NOT AGREE TO THE TERMS OF THIS LICENCE, WE WILL NOT LICENSE THE SOFTWARE AND DOCUMENTATION TO YOU AND YOU MUST DISCONTINUE THE INSTALLATION PROCESS. - - -You should print a copy of this License for future reference. - -1. Grant and scope of license - -1.1. In consideration of you agreeing to abide by the terms of this License the Licensor hereby grants to you a non-exclusive, non-transferable license to use the Software and the Documentation on the terms of this License. - -1.2. You may: - (a) install and use the Software for your internal business purposes on one central processing unit (CPU) per single user license granted through this License; - (b) provided it is used on only one computer at any one time, transfer the Software from one computer to another; - (c) provided you comply with the provisions in clause 2, make a single copy of the Software for back-up purposes, provided that you reproduce on it all copyright and other proprietary notices that are on the original copy of the Software; - (d) receive and use any free supplementary software code or update of the Software incorporating "patches", corrections of errors and software updates as may be provided by the Licensor from time to time; - (e) use any Documentation in support of the use permitted under condition 1.2 and make a single copy of the Documentation as is reasonably necessary for its lawful use. - -2. Restrictions - Except as expressly set out in this License or as permitted by any local law, you undertake: - (a) not, in whole or in part, to copy the Software or Documentation except where such copying is incidental to normal use of the Software or where it is necessary for the purpose of back-up or operational security; - (b) not to rent, lease, sub-license, loan, translate, merge, adapt, vary or modify the Software or Documentation; - (c) not to make alterations to, or modifications of, the whole or any part of the Software nor permit the Software or any part of it to be combined with, or become incorporated in, any other programs; - (d) not to disassemble, de-compile, reverse engineer or create derivative works based on the whole or any part of the Software nor attempt to do any such things except to the extent that (by virtue of section 296A of the Copyright, Designs and Patents Act 1988) such actions cannot be prohibited because they are essential for the purpose of achieving inter-operability of the Software with another software program, and provided that the information obtained by you during such activities: - (i) is used only for the purpose of achieving inter-operability of the Software with another software program; - (ii) is not disclosed or communicated without the Licensor's prior written consent to any third party to whom it is not necessary to disclose or communicate it; and - (iii) is not used to create any software which is substantially similar to the Software; - (e) to keep all copies of the Software secure and to maintain accurate and up-to-date records of the number and locations of all copies of the Software; - (f) not to provide, or otherwise make available, the Software in any form, in whole or in part (including, but not limited to, program listings, object and source program listings, object code and source code) to any person other than your employees without prior written consent from us; - (g) to comply with all applicable technology control or export laws and regulations. - (h) to supervise and control use of the Software and ensure that the Software is used by your employees and representatives in accordance with the terms of this License; - (i) not to charge or otherwise deal in the Software or any part or interest therein except as expressly provided herein; - (j) not to use the Software for any illegal or immoral purposes; - (k) not otherwise use, copy, transfer or distribute the Software or part of it, except as expressly permitted by this License, in any manner which is inconsistent with this License. - -3. Fee - -3.1. You may install and use a limited version of the Software (Demo Mode). - -3.2. Where you have purchased the JUCE 4 software on or after 1 November 2015 you shall be entitled to use the Software for free subject to your continued payment of the JUCE 4 software license fee and the JUCE 4 license terms. - -3.3. Save as set out above, your right to use the Software shall be subject to payment of the Projucer Software license fee. - -3.4. Where you have purchased a perpetual license you agree to pay the license fee as notified to you on the Website at the time you purchase the License. - -3.5. Where you have purchased an educational license the fee shall be the fee as notified to you on the Website at the time you purchase the License and shall be payable for each academic year from the first day of the first full calendar month after the grant of the License and thereafter on the anniversary of that initial payment date. - -4. Intellectual property rights - -4.1. You acknowledge that all intellectual property rights in the Software and the Documentation and all copies thereof throughout the world belong to us, that rights in the Software are licensed (not sold) to you, and that you have no rights in, or to, the Software or the Documentation other than the right to use them in accordance with the terms of this License. - -4.2. You acknowledge that you have no right to have access to the Software in source code form or in unlocked coding or with comments. - -4.3. The Software may contain certain third party licensed materials and our licensors may act to protect their rights in the event of any violation of this License. - -5. Limited warranty - -5.1. We warrant that, save as already set out above in relation to component parts of the Software, we own the Software and have the right to convey this License. - -5.2. We shall have no obligation to provide support and maintenance services to you. You may participate in our online support forum in accordance with our forum policies in place from time to time. - -5.3. We do not warrant that your use of the Software will be uninterrupted or error free. - -6. Limitation of liability - -6.1. You acknowledge that the Software has not been developed to meet your individual requirements, and that it is therefore your responsibility to ensure that the facilities and functions of the Software as described in the Documentation meet your requirements. - -6.2. Without prejudice to clause 5.4 below, you acknowledge that the Software is not designed or intended for use with on-line control equipment in hazardous environments requiring fail safe performance, such as in the operation of nuclear facilities, aircraft navigation, communication, or control systems, direct life support machines, weapons systems, or other uses in which failure of the Software could lead directly to death, personal injury or severe physical or environmental damage. - -6.3. Neither the Licensor nor its parent company, subsidiaries or employees shall in any circumstances whatsoever be liable to you, whether in contract, tort (including negligence), breach of statutory duty, or otherwise, arising under or in connection with this License for any indirect, consequential or special loss or damage, including but not limited to, for: - (a) loss of profits, sales, business, or revenue; - (b) business interruption; - (c) loss of anticipated savings; - (d) loss or corruption of data or information; - (e) loss of business opportunity, goodwill or reputation; - (f) any indirect or consequential loss or damage; or - (g) any computer failure or malfunction, corruption to or loss of data or files, or any and all other commercial damage or loss. - -6.4. Nothing in this License shall limit or exclude our liability for: - (a) death or personal injury resulting from our negligence; - (b) fraud or fraudulent misrepresentation; - (c) any other liability that cannot be excluded or limited by English law. - -6.5. This License sets out the full extent of our obligations and liabilities in respect of the supply of the Software and Documentation. Except as expressly stated in this License, there are no conditions, warranties, representations or other terms, express or implied, that are binding on us. Any condition, warranty, representation or other term concerning the supply of the Software and Documentation which might otherwise be implied into, or incorporated in, this License whether by statute, common law or otherwise, is excluded to the fullest extent permitted by law. - -6.6. Subject to clause 5.2 and 5.3, our maximum aggregate liability under or in connection with this License whether in contract, tort (including negligence) or otherwise, shall in all circumstances be limited to a sum equal to $49. - -6.7. You agree to indemnify, defend and hold us and our licensors, partners, affiliates, contractors, officers, directors, employees and agents harmless from any claims, costs and expenses (including legal expenses) arising directly or indirectly from your use, handling or operation of the Software otherwise than in accordance with this Agreement. - -6.8. This clause 5 shall survive and shall not be rendered ineffective by the termination or expiry of this agreement for whatever reason. - -7. Termination - -7.1. We may terminate this License immediately by written notice to you if you commit a material or persistent breach of this License which you fail to remedy (if remediable) within 14 days after the service of written notice requiring you to do so. - -7.2. Upon termination for any reason: - (a) all rights granted to you under this License shall cease; - (b) you must cease all activities authorised by this License; - (c) you must immediately delete or remove the Software from all computer equipment in your possession and immediately destroy or return to us (at our option) all copies of the Software then in your possession, custody or control and, in the case of destruction, certify to us that you have done so. - -8. Communications between us - -8.1. If you wish to contact us in writing, or if any condition in this License requires you to give us notice in writing, you can send this to us by e-mail or by pre-paid post to us at support@juce.com. We will confirm receipt of this by contacting you in writing, normally by e-mail. - -8.2. If we have to contact you or give you notice in writing, we will do so by e-mail or by pre-paid post to the address you provide to us in your order for the Software. - -9. Data - -9.1. We may collect and process information about your use of or Software through the Software, some of which may amount to your personal data. Personal data will be collected and processed in accordance with our Privacy Policy which can be reviewed at https://www.juce.com/privacy-policy. - -10. Other important terms - -10.1. We may transfer our rights and obligations under this License to another organisation, but this will not affect your rights or our obligations under this License. - -10.2. You may only transfer your rights or your obligations under this License to another person if we agree in writing. - -10.3. This License and any document expressly referred to in it constitutes the entire agreement between you and us. You acknowledge that you have not relied on any statement, promise or representation made or given by or on behalf of us which is not set out in this License or any document expressly referred to in it. - -10.4. If we fail to insist that you perform any of your obligations under this License, or if we do not enforce our rights against you, or if we delay in doing so, that will not mean that we have waived our rights against you and will not mean that you do not have to comply with those obligations. If we do waive a default by you, we will only do so in writing, and that will not mean that we will automatically waive any later default by you. - -10.5. Each of the conditions of this License operates separately. If any court or competent authority decides that any of them are unlawful or unenforceable, the remaining conditions will remain in full force and effect. - -10.6. Please note that this License, its subject matter and its formation, are governed by English law. You and we both agree to that the courts of England and Wales will have exclusive jurisdiction. diff --git a/extras/Projucer/Source/CodeEditor/jucer_DocumentEditorComponent.cpp b/extras/Projucer/Source/CodeEditor/jucer_DocumentEditorComponent.cpp index 4a457565..2c951a29 100644 --- a/extras/Projucer/Source/CodeEditor/jucer_DocumentEditorComponent.cpp +++ b/extras/Projucer/Source/CodeEditor/jucer_DocumentEditorComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -27,7 +26,7 @@ #include "../Application/jucer_Headers.h" #include "jucer_DocumentEditorComponent.h" #include "../Application/jucer_Application.h" - +#include "../Project/UI/jucer_ProjectContentComponent.h" //============================================================================== DocumentEditorComponent::DocumentEditorComponent (OpenDocumentManager::Document* doc) diff --git a/extras/Projucer/Source/CodeEditor/jucer_DocumentEditorComponent.h b/extras/Projucer/Source/CodeEditor/jucer_DocumentEditorComponent.h index 9bd7a85a..e392c1b6 100644 --- a/extras/Projucer/Source/CodeEditor/jucer_DocumentEditorComponent.h +++ b/extras/Projucer/Source/CodeEditor/jucer_DocumentEditorComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -30,7 +29,7 @@ //============================================================================== class DocumentEditorComponent : public Component, - public OpenDocumentManager::DocumentCloseListener + private OpenDocumentManager::DocumentCloseListener { public: //============================================================================== @@ -39,8 +38,6 @@ public: OpenDocumentManager::Document* getDocument() const { return document; } - bool documentAboutToClose (OpenDocumentManager::Document*) override; - protected: OpenDocumentManager::Document* document; bool lastEditedState = false; @@ -48,5 +45,7 @@ protected: void setEditedState (bool hasBeenEdited); private: + bool documentAboutToClose (OpenDocumentManager::Document*) override; + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DocumentEditorComponent) }; diff --git a/extras/Projucer/Source/CodeEditor/jucer_ItemPreviewComponent.h b/extras/Projucer/Source/CodeEditor/jucer_ItemPreviewComponent.h index 669c74e7..a2f9f35a 100644 --- a/extras/Projucer/Source/CodeEditor/jucer_ItemPreviewComponent.h +++ b/extras/Projucer/Source/CodeEditor/jucer_ItemPreviewComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -54,7 +53,7 @@ public: } auto area = RectanglePlacement (RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize) - .appliedTo (contentBounds, Rectangle<float> (4.0f, 22.0f, getWidth() - 8.0f, getHeight() - 26.0f)); + .appliedTo (contentBounds, Rectangle<float> (4.0f, 22.0f, (float) getWidth() - 8.0f, (float) getHeight() - 26.0f)); Path p; p.addRectangle (area); diff --git a/extras/Projucer/Source/CodeEditor/jucer_LiveBuildCodeEditor.h b/extras/Projucer/Source/CodeEditor/jucer_LiveBuildCodeEditor.h index 5b9bc781..c87b3e81 100644 --- a/extras/Projucer/Source/CodeEditor/jucer_LiveBuildCodeEditor.h +++ b/extras/Projucer/Source/CodeEditor/jucer_LiveBuildCodeEditor.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -151,7 +150,7 @@ private: const auto charArea = codeEditor->getCharacterBounds (startPosition); const int height = charArea.getHeight() + 8; - Font f (height * 0.7f); + Font f ((float) height * 0.7f); const int width = jmin (height * 2 + f.getStringWidth (launchButton.getName()), jmax (120, codeEditor->proportionOfWidth (0.2f))); @@ -192,7 +191,7 @@ private: .draw (g, r.removeFromLeft (getHeight()).toFloat(), false); g.setColour (Colours::white); - g.setFont (getHeight() * 0.7f); + g.setFont ((float) getHeight() * 0.7f); g.drawFittedText (getName(), r, Justification::centredLeft, 1); } @@ -325,9 +324,9 @@ private: g.fillRect (getLocalBounds().withTrimmedBottom (lineOffset)); Path path; - const float bottomY = getHeight() - (lineOffset / 2.0f); + const float bottomY = (float) getHeight() - ((float) lineOffset / 2.0f); path.addTriangle ((float) arrowXMin, bottomY, - (arrowXMax + arrowXMin) / 2.0f, (float) lineOffset, + (float) (arrowXMax + arrowXMin) / 2.0f, (float) lineOffset, (float) arrowXMax, bottomY); g.setColour (diagColour.withAlpha (0.8f)); diff --git a/extras/Projucer/Source/CodeEditor/jucer_OpenDocumentManager.cpp b/extras/Projucer/Source/CodeEditor/jucer_OpenDocumentManager.cpp index f84d602e..e1586711 100644 --- a/extras/Projucer/Source/CodeEditor/jucer_OpenDocumentManager.cpp +++ b/extras/Projucer/Source/CodeEditor/jucer_OpenDocumentManager.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -189,11 +188,11 @@ FileBasedDocument::SaveResult OpenDocumentManager::saveIfNeededAndUserAgrees (Op } -bool OpenDocumentManager::closeDocument (int index, bool saveIfNeeded) +bool OpenDocumentManager::closeDocument (int index, SaveIfNeeded saveIfNeeded) { if (Document* doc = documents [index]) { - if (saveIfNeeded) + if (saveIfNeeded == SaveIfNeeded::yes) if (saveIfNeededAndUserAgrees (doc) != FileBasedDocument::savedOk) return false; @@ -214,12 +213,12 @@ bool OpenDocumentManager::closeDocument (int index, bool saveIfNeeded) return true; } -bool OpenDocumentManager::closeDocument (Document* document, bool saveIfNeeded) +bool OpenDocumentManager::closeDocument (Document* document, SaveIfNeeded saveIfNeeded) { return closeDocument (documents.indexOf (document), saveIfNeeded); } -void OpenDocumentManager::closeFile (const File& f, bool saveIfNeeded) +void OpenDocumentManager::closeFile (const File& f, SaveIfNeeded saveIfNeeded) { for (int i = documents.size(); --i >= 0;) if (Document* d = documents[i]) @@ -227,7 +226,7 @@ void OpenDocumentManager::closeFile (const File& f, bool saveIfNeeded) closeDocument (i, saveIfNeeded); } -bool OpenDocumentManager::closeAll (bool askUserToSave) +bool OpenDocumentManager::closeAll (SaveIfNeeded askUserToSave) { for (int i = getNumOpenDocuments(); --i >= 0;) if (! closeDocument (i, askUserToSave)) @@ -236,7 +235,7 @@ bool OpenDocumentManager::closeAll (bool askUserToSave) return true; } -bool OpenDocumentManager::closeAllDocumentsUsingProject (Project& project, bool saveIfNeeded) +bool OpenDocumentManager::closeAllDocumentsUsingProject (Project& project, SaveIfNeeded saveIfNeeded) { for (int i = documents.size(); --i >= 0;) if (Document* d = documents[i]) diff --git a/extras/Projucer/Source/CodeEditor/jucer_OpenDocumentManager.h b/extras/Projucer/Source/CodeEditor/jucer_OpenDocumentManager.h index 9607b4f3..42c712b7 100644 --- a/extras/Projucer/Source/CodeEditor/jucer_OpenDocumentManager.h +++ b/extras/Projucer/Source/CodeEditor/jucer_OpenDocumentManager.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -69,13 +68,15 @@ public: Document* getOpenDocument (int index) const; void clear(); + enum class SaveIfNeeded { no, yes }; + bool canOpenFile (const File& file); Document* openFile (Project* project, const File& file); - bool closeDocument (int index, bool saveIfNeeded); - bool closeDocument (Document* document, bool saveIfNeeded); - bool closeAll (bool askUserToSave); - bool closeAllDocumentsUsingProject (Project& project, bool saveIfNeeded); - void closeFile (const File& f, bool saveIfNeeded); + bool closeDocument (int index, SaveIfNeeded saveIfNeeded); + bool closeDocument (Document* document, SaveIfNeeded saveIfNeeded); + bool closeAll (SaveIfNeeded askUserToSave); + bool closeAllDocumentsUsingProject (Project& project, SaveIfNeeded saveIfNeeded); + void closeFile (const File& f, SaveIfNeeded saveIfNeeded); bool anyFilesNeedSaving() const; bool saveAll(); FileBasedDocument::SaveResult saveIfNeededAndUserAgrees (Document* doc); diff --git a/extras/Projucer/Source/CodeEditor/jucer_SourceCodeEditor.cpp b/extras/Projucer/Source/CodeEditor/jucer_SourceCodeEditor.cpp index 2cdb625f..665d0378 100644 --- a/extras/Projucer/Source/CodeEditor/jucer_SourceCodeEditor.cpp +++ b/extras/Projucer/Source/CodeEditor/jucer_SourceCodeEditor.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -404,7 +403,7 @@ public: void paint (Graphics& g) override { Path outline; - outline.addRoundedRectangle (1.0f, 1.0f, getWidth() - 2.0f, getHeight() - 2.0f, 8.0f); + outline.addRoundedRectangle (1.0f, 1.0f, (float) getWidth() - 2.0f, (float) getHeight() - 2.0f, 8.0f); g.setColour (Colours::black.withAlpha (0.6f)); g.fillPath (outline); @@ -654,7 +653,7 @@ void CppCodeEditorComponent::insertComponentClass() { auto className = aw.getTextEditorContents (classNameField).trim(); - if (className == CodeHelpers::makeValidIdentifier (className, false, true, false)) + if (className == build_tools::makeValidIdentifier (className, false, true, false)) { String code (BinaryData::jucer_InlineComponentTemplate_h); code = code.replace ("%%component_class%%", className); diff --git a/extras/Projucer/Source/CodeEditor/jucer_SourceCodeEditor.h b/extras/Projucer/Source/CodeEditor/jucer_SourceCodeEditor.h index 6fd416a4..c1e0ccb1 100644 --- a/extras/Projucer/Source/CodeEditor/jucer_SourceCodeEditor.h +++ b/extras/Projucer/Source/CodeEditor/jucer_SourceCodeEditor.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/ComponentEditor/Components/jucer_ButtonHandler.h b/extras/Projucer/Source/ComponentEditor/Components/jucer_ButtonHandler.h index 16d5fb1e..67e0a262 100644 --- a/extras/Projucer/Source/ComponentEditor/Components/jucer_ButtonHandler.h +++ b/extras/Projucer/Source/ComponentEditor/Components/jucer_ButtonHandler.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -114,16 +113,16 @@ public: StringArray flags; if (b->isConnectedOnLeft()) - flags.add ("Button::ConnectedOnLeft"); + flags.add ("juce::Button::ConnectedOnLeft"); if (b->isConnectedOnRight()) - flags.add ("Button::ConnectedOnRight"); + flags.add ("juce::Button::ConnectedOnRight"); if (b->isConnectedOnTop()) - flags.add ("Button::ConnectedOnTop"); + flags.add ("juce::Button::ConnectedOnTop"); if (b->isConnectedOnBottom()) - flags.add ("Button::ConnectedOnBottom"); + flags.add ("juce::Button::ConnectedOnBottom"); String s; s << memberVariableName << "->setConnectedEdges (" @@ -146,9 +145,9 @@ public: if (needsButtonListener (component)) { - String& callback = code.getCallbackCode ("public Button::Listener", + String& callback = code.getCallbackCode ("public juce::Button::Listener", "void", - "buttonClicked (Button* buttonThatWasClicked)", + "buttonClicked (juce::Button* buttonThatWasClicked)", true); if (callback.isNotEmpty()) diff --git a/extras/Projucer/Source/ComponentEditor/Components/jucer_ComboBoxHandler.h b/extras/Projucer/Source/ComponentEditor/Components/jucer_ComboBoxHandler.h index 55be623a..be39c3f7 100644 --- a/extras/Projucer/Source/ComponentEditor/Components/jucer_ComboBoxHandler.h +++ b/extras/Projucer/Source/ComponentEditor/Components/jucer_ComboBoxHandler.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -32,7 +31,7 @@ class ComboBoxHandler : public ComponentTypeHandler { public: ComboBoxHandler() - : ComponentTypeHandler ("Combo Box", "ComboBox", typeid (ComboBox), 150, 24) + : ComponentTypeHandler ("Combo Box", "juce::ComboBox", typeid (ComboBox), 150, 24) {} Component* createNewComponent (JucerDocument*) override @@ -140,9 +139,9 @@ public: if (needsCallback (component)) { - String& callback = code.getCallbackCode ("public ComboBox::Listener", + String& callback = code.getCallbackCode ("public juce::ComboBox::Listener", "void", - "comboBoxChanged (ComboBox* comboBoxThatHasChanged)", + "comboBoxChanged (juce::ComboBox* comboBoxThatHasChanged)", true); if (callback.trim().isNotEmpty()) diff --git a/extras/Projucer/Source/ComponentEditor/Components/jucer_ComponentNameProperty.h b/extras/Projucer/Source/ComponentEditor/Components/jucer_ComponentNameProperty.h index e9c17275..8f4ea3c5 100644 --- a/extras/Projucer/Source/ComponentEditor/Components/jucer_ComponentNameProperty.h +++ b/extras/Projucer/Source/ComponentEditor/Components/jucer_ComponentNameProperty.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/ComponentEditor/Components/jucer_ComponentTypeHandler.cpp b/extras/Projucer/Source/ComponentEditor/Components/jucer_ComponentTypeHandler.cpp index 792a7790..68a368a1 100644 --- a/extras/Projucer/Source/ComponentEditor/Components/jucer_ComponentTypeHandler.cpp +++ b/extras/Projucer/Source/ComponentEditor/Components/jucer_ComponentTypeHandler.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -554,7 +553,7 @@ void ComponentTypeHandler::fillInMemberVariableDeclarations (GeneratedCode& code String clsName (component->getProperties() ["virtualName"].toString()); if (clsName.isNotEmpty()) - clsName = CodeHelpers::makeValidIdentifier (clsName, false, false, true); + clsName = build_tools::makeValidIdentifier (clsName, false, false, true); else clsName = getClassName (component); @@ -592,7 +591,7 @@ void ComponentTypeHandler::fillInCreationCode (GeneratedCode& code, Component* c s << memberVariableName << ".reset (new "; if (virtualName.isNotEmpty()) - s << CodeHelpers::makeValidIdentifier (virtualName, false, false, true); + s << build_tools::makeValidIdentifier (virtualName, false, false, true); else s << getClassName (component); diff --git a/extras/Projucer/Source/ComponentEditor/Components/jucer_ComponentTypeHandler.h b/extras/Projucer/Source/ComponentEditor/Components/jucer_ComponentTypeHandler.h index ace10a86..ca295ae9 100644 --- a/extras/Projucer/Source/ComponentEditor/Components/jucer_ComponentTypeHandler.h +++ b/extras/Projucer/Source/ComponentEditor/Components/jucer_ComponentTypeHandler.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -53,7 +52,13 @@ public: static ComponentTypeHandler* getHandlerFor (Component& component); //============================================================================== - virtual String getXmlTagName() const noexcept { return className.toUpperCase(); } + virtual String getXmlTagName() const noexcept + { + if (className.startsWith ("juce::")) + return className.substring (6).toUpperCase(); + + return className.toUpperCase(); + } static ComponentTypeHandler* getHandlerForXmlTag (const String& tagName); diff --git a/extras/Projucer/Source/ComponentEditor/Components/jucer_ComponentUndoableAction.h b/extras/Projucer/Source/ComponentEditor/Components/jucer_ComponentUndoableAction.h index b718f3bb..00229f2e 100644 --- a/extras/Projucer/Source/ComponentEditor/Components/jucer_ComponentUndoableAction.h +++ b/extras/Projucer/Source/ComponentEditor/Components/jucer_ComponentUndoableAction.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/ComponentEditor/Components/jucer_GenericComponentHandler.h b/extras/Projucer/Source/ComponentEditor/Components/jucer_GenericComponentHandler.h index d8bc322b..0fc716d7 100644 --- a/extras/Projucer/Source/ComponentEditor/Components/jucer_GenericComponentHandler.h +++ b/extras/Projucer/Source/ComponentEditor/Components/jucer_GenericComponentHandler.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -33,7 +32,7 @@ class GenericComponent : public Component public: GenericComponent() : Component ("new component"), - actualClassName ("Component") + actualClassName ("juce::Component") { } @@ -98,7 +97,7 @@ public: if (! ComponentTypeHandler::restoreFromXml (xml, comp, layout)) return false; - ((GenericComponent*) comp)->actualClassName = xml.getStringAttribute ("class", "Component"); + ((GenericComponent*) comp)->actualClassName = xml.getStringAttribute ("class", "juce::Component"); ((GenericComponent*) comp)->constructorParams = xml.getStringAttribute ("params", String()); return true; } @@ -150,7 +149,7 @@ private: void setText (const String& newText) override { document.perform (new GenericCompClassChangeAction (component, *document.getComponentLayout(), - CodeHelpers::makeValidIdentifier (newText, false, false, true)), + build_tools::makeValidIdentifier (newText, false, false, true)), "Change generic component class"); } diff --git a/extras/Projucer/Source/ComponentEditor/Components/jucer_GroupComponentHandler.h b/extras/Projucer/Source/ComponentEditor/Components/jucer_GroupComponentHandler.h index bc43b112..3cb279a9 100644 --- a/extras/Projucer/Source/ComponentEditor/Components/jucer_GroupComponentHandler.h +++ b/extras/Projucer/Source/ComponentEditor/Components/jucer_GroupComponentHandler.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -32,10 +31,10 @@ class GroupComponentHandler : public ComponentTypeHandler { public: GroupComponentHandler() - : ComponentTypeHandler ("Group Box", "GroupComponent", typeid (GroupComponent), 200, 150) + : ComponentTypeHandler ("Group Box", "juce::GroupComponent", typeid (GroupComponent), 200, 150) { - registerColour (GroupComponent::outlineColourId, "outline", "outlinecol"); - registerColour (GroupComponent::textColourId, "text", "textcol"); + registerColour (juce::GroupComponent::outlineColourId, "outline", "outlinecol"); + registerColour (juce::GroupComponent::textColourId, "text", "textcol"); } Component* createNewComponent (JucerDocument*) override @@ -173,7 +172,7 @@ private: //============================================================================== class GroupJustificationProperty : public JustificationProperty, - public ChangeListener + private ChangeListener { public: GroupJustificationProperty (GroupComponent* const group_, JucerDocument& doc) @@ -184,25 +183,25 @@ private: document.addChangeListener (this); } - ~GroupJustificationProperty() + ~GroupJustificationProperty() override { document.removeChangeListener (this); } - void setJustification (Justification newJustification) + void setJustification (Justification newJustification) override { document.perform (new GroupJustifyChangeAction (group, *document.getComponentLayout(), newJustification), "Change text label position"); } - Justification getJustification() const + Justification getJustification() const override { return group->getTextLabelPosition(); } - void changeListenerCallback (ChangeBroadcaster*) { refresh(); } - private: + void changeListenerCallback (ChangeBroadcaster*) override { refresh(); } + GroupComponent* const group; JucerDocument& document; diff --git a/extras/Projucer/Source/ComponentEditor/Components/jucer_HyperlinkButtonHandler.h b/extras/Projucer/Source/ComponentEditor/Components/jucer_HyperlinkButtonHandler.h index 603b830f..f33f9ba2 100644 --- a/extras/Projucer/Source/ComponentEditor/Components/jucer_HyperlinkButtonHandler.h +++ b/extras/Projucer/Source/ComponentEditor/Components/jucer_HyperlinkButtonHandler.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -32,9 +31,9 @@ class HyperlinkButtonHandler : public ButtonHandler { public: HyperlinkButtonHandler() - : ButtonHandler ("Hyperlink Button", "HyperlinkButton", typeid (HyperlinkButton), 150, 24) + : ButtonHandler ("Hyperlink Button", "juce::HyperlinkButton", typeid (HyperlinkButton), 150, 24) { - registerColour (HyperlinkButton::textColourId, "text", "textCol"); + registerColour (juce::HyperlinkButton::textColourId, "text", "textCol"); } Component* createNewComponent (JucerDocument*) override diff --git a/extras/Projucer/Source/ComponentEditor/Components/jucer_ImageButtonHandler.h b/extras/Projucer/Source/ComponentEditor/Components/jucer_ImageButtonHandler.h index 7e425d23..4412d0dc 100644 --- a/extras/Projucer/Source/ComponentEditor/Components/jucer_ImageButtonHandler.h +++ b/extras/Projucer/Source/ComponentEditor/Components/jucer_ImageButtonHandler.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -40,7 +39,7 @@ public: //============================================================================== ImageButtonHandler() - : ButtonHandler ("Image Button", "ImageButton", typeid (ImageButton), 150, 24) + : ButtonHandler ("Image Button", "juce::ImageButton", typeid (ImageButton), 150, 24) { } @@ -164,9 +163,9 @@ public: const String resName (getImageResource (ib, role)); if (resName.isEmpty()) - return "Image()"; + return "juce::Image()"; - return "ImageCache::getFromMemory (" + resName + ", " + resName + "Size)"; + return "juce::ImageCache::getFromMemory (" + resName + ", " + resName + "Size)"; } //============================================================================== @@ -465,7 +464,7 @@ public: } class ImageButtonColourProperty : public JucerColourPropertyComponent, - public ChangeListener + private ChangeListener { public: ImageButtonColourProperty (ComponentLayout& layout_, ImageButton* const owner_, @@ -478,29 +477,29 @@ public: layout_.getDocument()->addChangeListener (this); } - ~ImageButtonColourProperty() + ~ImageButtonColourProperty() override { layout.getDocument()->removeChangeListener (this); } - void setColour (Colour newColour) + void setColour (Colour newColour) override { setImageColour (layout, owner, role, newColour, true); } - Colour getColour() const + Colour getColour() const override { return getImageColour (owner, role); } - void resetToDefault() {} + void resetToDefault() override {} - void changeListenerCallback (ChangeBroadcaster*) + private: + void changeListenerCallback (ChangeBroadcaster*) override { refresh(); } - private: ImageButton* const owner; ComponentLayout& layout; const ImageRole role; diff --git a/extras/Projucer/Source/ComponentEditor/Components/jucer_JucerComponentHandler.h b/extras/Projucer/Source/ComponentEditor/Components/jucer_JucerComponentHandler.h index cceb7735..f4893211 100644 --- a/extras/Projucer/Source/ComponentEditor/Components/jucer_JucerComponentHandler.h +++ b/extras/Projucer/Source/ComponentEditor/Components/jucer_JucerComponentHandler.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -82,7 +81,7 @@ public: jucerCompClassName = tc->getDocument()->getClassName(); if (jucerCompClassName.isEmpty()) - jucerCompClassName = "Component"; + jucerCompClassName = "juce::Component"; return jucerCompClassName; } @@ -160,7 +159,7 @@ public: private: //============================================================================== class JucerCompFileProperty : public FilePropertyComponent, - public ChangeListener + private ChangeListener { public: JucerCompFileProperty (TestComponent* const comp, JucerDocument& doc) @@ -171,29 +170,29 @@ private: document.addChangeListener (this); } - ~JucerCompFileProperty() + ~JucerCompFileProperty() override { document.removeChangeListener (this); } - void setFile (const File& newFile) + void setFile (const File& newFile) override { setJucerComponentFile (document, component, newFile.getRelativePathFrom (document.getCppFile().getParentDirectory()) .replaceCharacter ('\\', '/')); } - File getFile() const + File getFile() const override { return component->findFile(); } - void changeListenerCallback (ChangeBroadcaster*) + private: + void changeListenerCallback (ChangeBroadcaster*) override { refresh(); } - private: TestComponent* const component; JucerDocument& document; }; diff --git a/extras/Projucer/Source/ComponentEditor/Components/jucer_LabelHandler.h b/extras/Projucer/Source/ComponentEditor/Components/jucer_LabelHandler.h index 50872603..5c77a647 100644 --- a/extras/Projucer/Source/ComponentEditor/Components/jucer_LabelHandler.h +++ b/extras/Projucer/Source/ComponentEditor/Components/jucer_LabelHandler.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -32,14 +31,14 @@ class LabelHandler : public ComponentTypeHandler { public: LabelHandler() - : ComponentTypeHandler ("Label", "Label", typeid (Label), 150, 24) + : ComponentTypeHandler ("Label", "juce::Label", typeid (Label), 150, 24) { - registerColour (Label::backgroundColourId, "background", "bkgCol"); - registerColour (Label::textColourId, "text", "textCol"); - registerColour (Label::outlineColourId, "outline", "outlineCol"); - registerColour (TextEditor::textColourId, "editor text", "edTextCol"); - registerColour (TextEditor::backgroundColourId, "editor bkg", "edBkgCol"); - registerColour (TextEditor::highlightColourId, "highlight", "hiliteCol"); + registerColour (juce::Label::backgroundColourId, "background", "bkgCol"); + registerColour (juce::Label::textColourId, "text", "textCol"); + registerColour (juce::Label::outlineColourId, "outline", "outlineCol"); + registerColour (juce::TextEditor::textColourId, "editor text", "edTextCol"); + registerColour (juce::TextEditor::backgroundColourId, "editor bkg", "edBkgCol"); + registerColour (juce::TextEditor::highlightColourId, "highlight", "hiliteCol"); } Component* createNewComponent (JucerDocument*) override @@ -156,9 +155,9 @@ public: if (needsCallback (component)) { - String& callback = code.getCallbackCode ("public Label::Listener", + String& callback = code.getCallbackCode ("public juce::Label::Listener", "void", - "labelTextChanged (Label* labelThatHasChanged)", + "labelTextChanged (juce::Label* labelThatHasChanged)", true); if (callback.trim().isNotEmpty()) @@ -376,7 +375,7 @@ private: //============================================================================== class LabelJustificationProperty : public JustificationProperty, - public ChangeListener + private ChangeListener { public: LabelJustificationProperty (Label* const label_, JucerDocument& doc) @@ -387,25 +386,25 @@ private: document.addChangeListener (this); } - ~LabelJustificationProperty() + ~LabelJustificationProperty() override { document.removeChangeListener (this); } - void setJustification (Justification newJustification) + void setJustification (Justification newJustification) override { document.perform (new LabelJustifyChangeAction (label, *document.getComponentLayout(), newJustification), "Change Label justification"); } - Justification getJustification() const + Justification getJustification() const override { return label->getJustificationType(); } - void changeListenerCallback (ChangeBroadcaster*) { refresh(); } - private: + void changeListenerCallback (ChangeBroadcaster*) override { refresh(); } + Label* const label; JucerDocument& document; @@ -441,7 +440,7 @@ private: //============================================================================== class FontNameProperty : public FontPropertyComponent, - public ChangeListener + private ChangeListener { public: FontNameProperty (Label* const label_, JucerDocument& doc) @@ -452,25 +451,25 @@ private: document.addChangeListener (this); } - ~FontNameProperty() + ~FontNameProperty() override { document.removeChangeListener (this); } - void setTypefaceName (const String& newFontName) + void setTypefaceName (const String& newFontName) override { document.perform (new FontNameChangeAction (label, *document.getComponentLayout(), newFontName), "Change Label typeface"); } - String getTypefaceName() const + String getTypefaceName() const override { return label->getProperties().getWithDefault ("typefaceName", FontPropertyComponent::getDefaultFont()); } - void changeListenerCallback (ChangeBroadcaster*) { refresh(); } - private: + void changeListenerCallback (ChangeBroadcaster*) override { refresh(); } + Label* const label; JucerDocument& document; @@ -508,7 +507,7 @@ private: //============================================================================== class FontSizeProperty : public SliderPropertyComponent, - public ChangeListener + private ChangeListener { public: FontSizeProperty (Label* const label_, JucerDocument& doc) @@ -519,12 +518,12 @@ private: document.addChangeListener (this); } - ~FontSizeProperty() + ~FontSizeProperty() override { document.removeChangeListener (this); } - void setValue (double newValue) + void setValue (double newValue) override { document.getUndoManager().undoCurrentTransactionOnly(); @@ -532,14 +531,14 @@ private: "Change Label font size"); } - double getValue() const + double getValue() const override { return label->getFont().getHeight(); } - void changeListenerCallback (ChangeBroadcaster*) { refresh(); } - private: + void changeListenerCallback (ChangeBroadcaster*) override { refresh(); } + Label* const label; JucerDocument& document; @@ -579,7 +578,7 @@ private: //============================================================================== class FontStyleProperty : public ChoicePropertyComponent, - public ChangeListener + private ChangeListener { public: FontStyleProperty (Label* const label_, JucerDocument& doc) @@ -592,7 +591,7 @@ private: updateStylesList (label->getFont()); } - ~FontStyleProperty() + ~FontStyleProperty() override { document.removeChangeListener (this); } @@ -619,7 +618,7 @@ private: refresh(); } - void setIndex (int newIndex) + void setIndex (int newIndex) override { Font f (label->getFont()); @@ -640,7 +639,7 @@ private: "Change Label font style"); } - int getIndex() const + int getIndex() const override { auto f = label->getFont(); @@ -660,12 +659,12 @@ private: return typefaceIndex; } - void changeListenerCallback (ChangeBroadcaster*) + private: + void changeListenerCallback (ChangeBroadcaster*) override { updateStylesList (label->getFont()); } - private: Label* const label; JucerDocument& document; @@ -701,7 +700,7 @@ private: //============================================================================== class FontKerningProperty : public SliderPropertyComponent, - public ChangeListener + private ChangeListener { public: FontKerningProperty (Label* const label_, JucerDocument& doc) @@ -712,12 +711,12 @@ private: document.addChangeListener (this); } - ~FontKerningProperty() + ~FontKerningProperty() override { document.removeChangeListener (this); } - void setValue (double newValue) + void setValue (double newValue) override { document.getUndoManager().undoCurrentTransactionOnly(); @@ -725,17 +724,17 @@ private: "Change Label font kerning"); } - double getValue() const + double getValue() const override { return label->getFont().getExtraKerningFactor(); } - void changeListenerCallback (ChangeBroadcaster*) + private: + void changeListenerCallback (ChangeBroadcaster*) override { refresh(); } - private: Label* const label; JucerDocument& document; diff --git a/extras/Projucer/Source/ComponentEditor/Components/jucer_SliderHandler.h b/extras/Projucer/Source/ComponentEditor/Components/jucer_SliderHandler.h index 1b9ac348..abcc52cc 100644 --- a/extras/Projucer/Source/ComponentEditor/Components/jucer_SliderHandler.h +++ b/extras/Projucer/Source/ComponentEditor/Components/jucer_SliderHandler.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -58,17 +57,17 @@ static const Slider::TextEntryBoxPosition sliderTextBoxPositions[] = struct SliderHandler : public ComponentTypeHandler { SliderHandler() - : ComponentTypeHandler ("Slider", "Slider", typeid (Slider), 150, 24) + : ComponentTypeHandler ("Slider", "juce::Slider", typeid (Slider), 150, 24) { - registerColour (Slider::backgroundColourId, "background", "bkgcol"); - registerColour (Slider::thumbColourId, "thumb", "thumbcol"); - registerColour (Slider::trackColourId, "track", "trackcol"); - registerColour (Slider::rotarySliderFillColourId, "rotary fill", "rotarysliderfill"); - registerColour (Slider::rotarySliderOutlineColourId, "rotary outln", "rotaryslideroutline"); - registerColour (Slider::textBoxTextColourId, "textbox text", "textboxtext"); - registerColour (Slider::textBoxBackgroundColourId, "textbox bkgd", "textboxbkgd"); - registerColour (Slider::textBoxHighlightColourId, "textbox highlt", "textboxhighlight"); - registerColour (Slider::textBoxOutlineColourId, "textbox outln", "textboxoutline"); + registerColour (juce::Slider::backgroundColourId, "background", "bkgcol"); + registerColour (juce::Slider::thumbColourId, "thumb", "thumbcol"); + registerColour (juce::Slider::trackColourId, "track", "trackcol"); + registerColour (juce::Slider::rotarySliderFillColourId, "rotary fill", "rotarysliderfill"); + registerColour (juce::Slider::rotarySliderOutlineColourId, "rotary outln", "rotaryslideroutline"); + registerColour (juce::Slider::textBoxTextColourId, "textbox text", "textboxtext"); + registerColour (juce::Slider::textBoxBackgroundColourId, "textbox bkgd", "textboxbkgd"); + registerColour (juce::Slider::textBoxHighlightColourId, "textbox highlt", "textboxhighlight"); + registerColour (juce::Slider::textBoxOutlineColourId, "textbox outln", "textboxoutline"); } Component* createNewComponent (JucerDocument*) override @@ -135,9 +134,9 @@ struct SliderHandler : public ComponentTypeHandler r << memberVariableName << "->setRange (" << s->getMinimum() << ", " << s->getMaximum() << ", " << s->getInterval() << ");\n" - << memberVariableName << "->setSliderStyle (Slider::" + << memberVariableName << "->setSliderStyle (juce::Slider::" << sliderStyleToString (s->getSliderStyle()) << ");\n" - << memberVariableName << "->setTextBoxStyle (Slider::" + << memberVariableName << "->setTextBoxStyle (juce::Slider::" << textBoxPosToString (s->getTextBoxPosition()) << ", " << CodeHelpers::boolLiteral (! s->isTextBoxEditable()) << ", " << s->getTextBoxWidth() << ", " << s->getTextBoxHeight() << ");\n" @@ -159,9 +158,9 @@ struct SliderHandler : public ComponentTypeHandler if (needsSliderListener (component)) { - String& callback = code.getCallbackCode ("public Slider::Listener", + String& callback = code.getCallbackCode ("public juce::Slider::Listener", "void", - "sliderValueChanged (Slider* sliderThatWasMoved)", + "sliderValueChanged (juce::Slider* sliderThatWasMoved)", true); if (callback.isNotEmpty()) diff --git a/extras/Projucer/Source/ComponentEditor/Components/jucer_TabbedComponentHandler.h b/extras/Projucer/Source/ComponentEditor/Components/jucer_TabbedComponentHandler.h index 2667cb04..c72f5e82 100644 --- a/extras/Projucer/Source/ComponentEditor/Components/jucer_TabbedComponentHandler.h +++ b/extras/Projucer/Source/ComponentEditor/Components/jucer_TabbedComponentHandler.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -32,7 +31,7 @@ class TabbedComponentHandler : public ComponentTypeHandler { public: TabbedComponentHandler() - : ComponentTypeHandler ("Tabbed Component", "TabbedComponent", typeid (TabbedComponent), 200, 150) + : ComponentTypeHandler ("Tabbed Component", "juce::TabbedComponent", typeid (TabbedComponent), 200, 150) {} Component* createNewComponent (JucerDocument*) override @@ -152,10 +151,10 @@ public: switch (t->getOrientation()) { - case TabbedButtonBar::TabsAtTop: return "TabbedButtonBar::TabsAtTop"; - case TabbedButtonBar::TabsAtBottom: return "TabbedButtonBar::TabsAtBottom"; - case TabbedButtonBar::TabsAtLeft: return "TabbedButtonBar::TabsAtLeft"; - case TabbedButtonBar::TabsAtRight: return "TabbedButtonBar::TabsAtRight"; + case TabbedButtonBar::TabsAtTop: return "juce::TabbedButtonBar::TabsAtTop"; + case TabbedButtonBar::TabsAtBottom: return "juce::TabbedButtonBar::TabsAtBottom"; + case TabbedButtonBar::TabsAtLeft: return "juce::TabbedButtonBar::TabsAtLeft"; + case TabbedButtonBar::TabsAtRight: return "juce::TabbedButtonBar::TabsAtRight"; default: jassertfalse; break; } @@ -531,7 +530,7 @@ private: //============================================================================== class TabDepthProperty : public SliderPropertyComponent, - public ChangeListener + private ChangeListener { public: TabDepthProperty (TabbedComponent* comp, JucerDocument& doc) @@ -542,12 +541,12 @@ private: document.addChangeListener (this); } - ~TabDepthProperty() + ~TabDepthProperty() override { document.removeChangeListener (this); } - void setValue (double newValue) + void setValue (double newValue) override { document.getUndoManager().undoCurrentTransactionOnly(); @@ -555,20 +554,20 @@ private: "Change TabComponent tab depth"); } - double getValue() const + double getValue() const override { return component->getTabBarDepth(); } - void changeListenerCallback (ChangeBroadcaster*) - { - refresh(); - } - TabbedComponent* const component; JucerDocument& document; private: + void changeListenerCallback (ChangeBroadcaster*) override + { + refresh(); + } + class TabDepthChangeAction : public ComponentUndoableAction<TabbedComponent> { public: @@ -925,7 +924,7 @@ private: //============================================================================== class TabJucerFileProperty : public FilePropertyComponent, - public ChangeListener + private ChangeListener { public: TabJucerFileProperty (TabbedComponent* const comp, JucerDocument& doc, const int tabIndex_) @@ -937,13 +936,13 @@ private: document.addChangeListener (this); } - ~TabJucerFileProperty() + ~TabJucerFileProperty() override { document.removeChangeListener (this); } //============================================================================== - void setFile (const File& newFile) + void setFile (const File& newFile) override { document.perform (new JucerCompFileChangeAction (component, *document.getComponentLayout(), tabIndex, newFile.getRelativePathFrom (document.getCppFile().getParentDirectory()) @@ -951,14 +950,14 @@ private: "Change tab component file"); } - File getFile() const + File getFile() const override { return document.getCppFile().getSiblingFile (getTabJucerFile (component, tabIndex)); } - void changeListenerCallback (ChangeBroadcaster*) { refresh(); } - private: + void changeListenerCallback (ChangeBroadcaster*) override { refresh(); } + TabbedComponent* const component; JucerDocument& document; int tabIndex; diff --git a/extras/Projucer/Source/ComponentEditor/Components/jucer_TextButtonHandler.h b/extras/Projucer/Source/ComponentEditor/Components/jucer_TextButtonHandler.h index ca2d38a2..ec4bf5fd 100644 --- a/extras/Projucer/Source/ComponentEditor/Components/jucer_TextButtonHandler.h +++ b/extras/Projucer/Source/ComponentEditor/Components/jucer_TextButtonHandler.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -32,12 +31,12 @@ class TextButtonHandler : public ButtonHandler { public: TextButtonHandler() - : ButtonHandler ("Text Button", "TextButton", typeid (TextButton), 150, 24) + : ButtonHandler ("Text Button", "juce::TextButton", typeid (TextButton), 150, 24) { - registerColour (TextButton::buttonColourId, "background (normal)", "bgColOff"); - registerColour (TextButton::buttonOnColourId, "background (on)", "bgColOn"); - registerColour (TextButton::textColourOffId, "text colour (normal)", "textCol"); - registerColour (TextButton::textColourOnId, "text colour (on)", "textColOn"); + registerColour (juce::TextButton::buttonColourId, "background (normal)", "bgColOff"); + registerColour (juce::TextButton::buttonOnColourId, "background (on)", "bgColOn"); + registerColour (juce::TextButton::textColourOffId, "text colour (normal)", "textCol"); + registerColour (juce::TextButton::textColourOnId, "text colour (on)", "textColOn"); } Component* createNewComponent (JucerDocument*) override diff --git a/extras/Projucer/Source/ComponentEditor/Components/jucer_TextEditorHandler.h b/extras/Projucer/Source/ComponentEditor/Components/jucer_TextEditorHandler.h index 0298e536..65b44771 100644 --- a/extras/Projucer/Source/ComponentEditor/Components/jucer_TextEditorHandler.h +++ b/extras/Projucer/Source/ComponentEditor/Components/jucer_TextEditorHandler.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -32,14 +31,14 @@ class TextEditorHandler : public ComponentTypeHandler { public: TextEditorHandler() - : ComponentTypeHandler ("Text Editor", "TextEditor", typeid (TextEditor), 150, 24) + : ComponentTypeHandler ("Text Editor", "juce::TextEditor", typeid (TextEditor), 150, 24) { - registerColour (TextEditor::textColourId, "text", "textcol"); - registerColour (TextEditor::backgroundColourId, "background", "bkgcol"); - registerColour (TextEditor::highlightColourId, "highlight", "hilitecol"); - registerColour (TextEditor::outlineColourId, "outline", "outlinecol"); - registerColour (TextEditor::shadowColourId, "shadow", "shadowcol"); - registerColour (CaretComponent::caretColourId, "caret", "caretcol"); + registerColour (juce::TextEditor::textColourId, "text", "textcol"); + registerColour (juce::TextEditor::backgroundColourId, "background", "bkgcol"); + registerColour (juce::TextEditor::highlightColourId, "highlight", "hilitecol"); + registerColour (juce::TextEditor::outlineColourId, "outline", "outlinecol"); + registerColour (juce::TextEditor::shadowColourId, "shadow", "shadowcol"); + registerColour (juce::CaretComponent::caretColourId, "caret", "caretcol"); } Component* createNewComponent (JucerDocument*) override diff --git a/extras/Projucer/Source/ComponentEditor/Components/jucer_ToggleButtonHandler.h b/extras/Projucer/Source/ComponentEditor/Components/jucer_ToggleButtonHandler.h index 8332ae40..7bbf8576 100644 --- a/extras/Projucer/Source/ComponentEditor/Components/jucer_ToggleButtonHandler.h +++ b/extras/Projucer/Source/ComponentEditor/Components/jucer_ToggleButtonHandler.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -32,9 +31,9 @@ class ToggleButtonHandler : public ButtonHandler { public: ToggleButtonHandler() - : ButtonHandler ("Toggle Button", "ToggleButton", typeid (ToggleButton), 150, 24) + : ButtonHandler ("Toggle Button", "juce::ToggleButton", typeid (ToggleButton), 150, 24) { - registerColour (ToggleButton::textColourId, "text colour", "txtcol"); + registerColour (juce::ToggleButton::textColourId, "text colour", "txtcol"); } Component* createNewComponent (JucerDocument*) override diff --git a/extras/Projucer/Source/ComponentEditor/Components/jucer_TreeViewHandler.h b/extras/Projucer/Source/ComponentEditor/Components/jucer_TreeViewHandler.h index 4bf5b6f0..84c38457 100644 --- a/extras/Projucer/Source/ComponentEditor/Components/jucer_TreeViewHandler.h +++ b/extras/Projucer/Source/ComponentEditor/Components/jucer_TreeViewHandler.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -32,10 +31,10 @@ class TreeViewHandler : public ComponentTypeHandler { public: TreeViewHandler() - : ComponentTypeHandler ("TreeView", "TreeView", typeid (DemoTreeView), 150, 150) + : ComponentTypeHandler ("TreeView", "juce::TreeView", typeid (DemoTreeView), 150, 150) { - registerColour (TreeView::backgroundColourId, "background", "backgroundColour"); - registerColour (TreeView::linesColourId, "lines", "linecol"); + registerColour (juce::TreeView::backgroundColourId, "background", "backgroundColour"); + registerColour (juce::TreeView::linesColourId, "lines", "linecol"); } Component* createNewComponent (JucerDocument*) override @@ -147,7 +146,7 @@ private: g.fillAll (Colours::lightblue); g.setColour (Colours::black); - g.setFont (height * 0.7f); + g.setFont ((float) height * 0.7f); g.drawText (name, 4, 0, width - 4, height, Justification::centredLeft, true); } diff --git a/extras/Projucer/Source/ComponentEditor/Components/jucer_ViewportHandler.h b/extras/Projucer/Source/ComponentEditor/Components/jucer_ViewportHandler.h index 6cf4ba1b..570f742b 100644 --- a/extras/Projucer/Source/ComponentEditor/Components/jucer_ViewportHandler.h +++ b/extras/Projucer/Source/ComponentEditor/Components/jucer_ViewportHandler.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -32,7 +31,7 @@ class ViewportHandler : public ComponentTypeHandler { public: ViewportHandler() - : ComponentTypeHandler ("Viewport", "Viewport", typeid (UpdatingViewport), 150, 150) + : ComponentTypeHandler ("Viewport", "juce::Viewport", typeid (UpdatingViewport), 150, 150) {} Component* createNewComponent (JucerDocument*) override @@ -359,7 +358,7 @@ private: //============================================================================== class ViewportScrollbarSizeProperty : public SliderPropertyComponent, - public ChangeListener + private ChangeListener { public: ViewportScrollbarSizeProperty (Viewport* comp, JucerDocument& doc) @@ -370,12 +369,12 @@ private: document.addChangeListener (this); } - ~ViewportScrollbarSizeProperty() + ~ViewportScrollbarSizeProperty() override { document.removeChangeListener (this); } - void setValue (double newValue) + void setValue (double newValue) override { document.getUndoManager().undoCurrentTransactionOnly(); @@ -383,12 +382,13 @@ private: "Change Viewport scrollbar size"); } - double getValue() const + double getValue() const override { return component->getScrollBarThickness(); } - void changeListenerCallback (ChangeBroadcaster*) + private: + void changeListenerCallback (ChangeBroadcaster*) override { refresh(); } @@ -485,7 +485,7 @@ private: //============================================================================== class ViewportJucerFileProperty : public FilePropertyComponent, - public ChangeListener + private ChangeListener { public: ViewportJucerFileProperty (Viewport* const comp, JucerDocument& doc) @@ -496,12 +496,12 @@ private: document.addChangeListener (this); } - ~ViewportJucerFileProperty() + ~ViewportJucerFileProperty() override { document.removeChangeListener (this); } - void setFile (const File& newFile) + void setFile (const File& newFile) override { document.perform (new JucerCompFileChangeAction (component, *document.getComponentLayout(), newFile.getRelativePathFrom (document.getCppFile().getParentDirectory()) @@ -509,7 +509,7 @@ private: "Change Projucer component file"); } - File getFile() const + File getFile() const override { auto filename = getViewportJucerComponentFile (component); @@ -519,12 +519,12 @@ private: return document.getCppFile().getSiblingFile (filename); } - void changeListenerCallback (ChangeBroadcaster*) + private: + void changeListenerCallback (ChangeBroadcaster*) override { refresh(); } - private: Viewport* const component; JucerDocument& document; diff --git a/extras/Projucer/Source/ComponentEditor/Documents/jucer_ButtonDocument.cpp b/extras/Projucer/Source/ComponentEditor/Documents/jucer_ButtonDocument.cpp index fddd1546..56fe2948 100644 --- a/extras/Projucer/Source/ComponentEditor/Documents/jucer_ButtonDocument.cpp +++ b/extras/Projucer/Source/ComponentEditor/Documents/jucer_ButtonDocument.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -50,7 +49,7 @@ ButtonDocument::ButtonDocument (SourceCodeDocument* c) paintStatesEnabled [downOn] = false; paintStatesEnabled [background] = false; - parentClasses = "public Button"; + parentClasses = "public juce::Button"; for (int i = 7; --i >= 0;) { @@ -217,8 +216,8 @@ void ButtonDocument::getOptionalMethods (StringArray& baseClasses, { JucerDocument::getOptionalMethods (baseClasses, returnValues, methods, initialContents); - addMethod ("Button", "void", "clicked()", "", baseClasses, returnValues, methods, initialContents); - addMethod ("Button", "void", "buttonStateChanged()", "", baseClasses, returnValues, methods, initialContents); + addMethod ("juce::Button", "void", "clicked()", "", baseClasses, returnValues, methods, initialContents); + addMethod ("juce::Button", "void", "buttonStateChanged()", "", baseClasses, returnValues, methods, initialContents); } //============================================================================== @@ -330,9 +329,9 @@ void ButtonDocument::fillInPaintCode (GeneratedCode& code) const if (paintStatesEnabled [i]) paintRoutines[i]->fillInGeneratedCode (code, paintCode [i]); - String& s = code.getCallbackCode ("public Button", + String& s = code.getCallbackCode ("public juce::Button", "void", - "paintButton (Graphics& g, bool isMouseOverButton, bool isButtonDown)", + "paintButton (juce::Graphics& g, bool isMouseOverButton, bool isButtonDown)", false); int numPaintRoutines = getNumPaintRoutines(); diff --git a/extras/Projucer/Source/ComponentEditor/Documents/jucer_ButtonDocument.h b/extras/Projucer/Source/ComponentEditor/Documents/jucer_ButtonDocument.h index 10d79a42..2fa41bb9 100644 --- a/extras/Projucer/Source/ComponentEditor/Documents/jucer_ButtonDocument.h +++ b/extras/Projucer/Source/ComponentEditor/Documents/jucer_ButtonDocument.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/ComponentEditor/Documents/jucer_ComponentDocument.cpp b/extras/Projucer/Source/ComponentEditor/Documents/jucer_ComponentDocument.cpp index 89573006..274319c9 100644 --- a/extras/Projucer/Source/ComponentEditor/Documents/jucer_ComponentDocument.cpp +++ b/extras/Projucer/Source/ComponentEditor/Documents/jucer_ComponentDocument.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/ComponentEditor/Documents/jucer_ComponentDocument.h b/extras/Projucer/Source/ComponentEditor/Documents/jucer_ComponentDocument.h index abcf9e33..775b3e34 100644 --- a/extras/Projucer/Source/ComponentEditor/Documents/jucer_ComponentDocument.h +++ b/extras/Projucer/Source/ComponentEditor/Documents/jucer_ComponentDocument.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_ColouredElement.cpp b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_ColouredElement.cpp index 6caa8b1f..1b2ca406 100644 --- a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_ColouredElement.cpp +++ b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_ColouredElement.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -213,7 +212,7 @@ private: class EnableStrokeProperty : public BooleanPropertyComponent { public: - EnableStrokeProperty (ColouredElement* const owner_) + explicit EnableStrokeProperty (ColouredElement* const owner_) : BooleanPropertyComponent ("outline", "Outline enabled", "No outline"), listener (owner_) { @@ -231,7 +230,7 @@ public: class StrokeThicknessProperty : public SliderPropertyComponent { public: - StrokeThicknessProperty (ColouredElement* const owner_) + explicit StrokeThicknessProperty (ColouredElement* const owner_) : SliderPropertyComponent ("outline thickness", 0.1, 200.0, 0.1, 0.3), listener (owner_) { @@ -257,7 +256,7 @@ public: class StrokeJointProperty : public ChoicePropertyComponent { public: - StrokeJointProperty (ColouredElement* const owner_) + explicit StrokeJointProperty (ColouredElement* const owner_) : ChoicePropertyComponent ("joint style"), listener (owner_) { @@ -302,7 +301,7 @@ public: class StrokeEndCapProperty : public ChoicePropertyComponent { public: - StrokeEndCapProperty (ColouredElement* const owner_) + explicit StrokeEndCapProperty (ColouredElement* const owner_) : ChoicePropertyComponent ("end-cap style"), listener (owner_) { diff --git a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_ColouredElement.h b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_ColouredElement.h index 817d0a26..8a3a2dd1 100644 --- a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_ColouredElement.h +++ b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_ColouredElement.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_ElementSiblingComponent.h b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_ElementSiblingComponent.h index 3349cf06..8c191573 100644 --- a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_ElementSiblingComponent.h +++ b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_ElementSiblingComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -26,7 +25,6 @@ #pragma once - //============================================================================== class ElementSiblingComponent : public Component, public ChangeListener @@ -40,19 +38,18 @@ public: owner->getDocument()->addChangeListener (this); } - ~ElementSiblingComponent() + ~ElementSiblingComponent() override { owner->getDocument()->removeChangeListener (this); } virtual void updatePosition() = 0; - -protected: - void changeListenerCallback (ChangeBroadcaster*) + void changeListenerCallback (ChangeBroadcaster*) override { updatePosition(); } +protected: PaintElement* const owner; }; diff --git a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_FillType.h b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_FillType.h index c4168f0c..6eafb586 100644 --- a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_FillType.h +++ b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_FillType.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -124,12 +123,12 @@ public: switch (mode) { case solidColour: - s << "Colour " << type << "Colour = " << CodeHelpers::colourToCode (colour) << ";\n"; + s << "juce::Colour " << type << "Colour = " << CodeHelpers::colourToCode (colour) << ";\n"; break; case linearGradient: case radialGradient: - s << "Colour " << type << "Colour1 = " << CodeHelpers::colourToCode (gradCol1) << ", " << type << "Colour2 = " << CodeHelpers::colourToCode (gradCol2) << ";\n"; + s << "juce::Colour " << type << "Colour1 = " << CodeHelpers::colourToCode (gradCol1) << ", " << type << "Colour2 = " << CodeHelpers::colourToCode (gradCol2) << ";\n"; break; case imageBrush: @@ -161,7 +160,7 @@ public: positionToCode (gradPos1, code.document->getComponentLayout(), x1, y1, w, h); positionToCode (gradPos2, code.document->getComponentLayout(), x2, y2, w, h); - s << "g.setGradientFill (ColourGradient ("; + s << "g.setGradientFill (juce::ColourGradient ("; auto indent = String::repeatedString (" ", s.length()); @@ -377,7 +376,7 @@ private: { if (Project* project = document->getCppDocument().getProject()) { - ResourceFile resourceFile (*project); + JucerResourceFile resourceFile (*project); for (int i = 0; i < resourceFile.getNumFiles(); ++i) { @@ -408,7 +407,7 @@ private: Graphics g (image); g.fillCheckerBoard (image.getBounds().toFloat(), - image.getWidth() * 0.5f, image.getHeight() * 0.5f, + (float) image.getWidth() * 0.5f, (float) image.getHeight() * 0.5f, Colours::white, Colours::lightgrey); g.setFont (12.0f); diff --git a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_GradientPointComponent.h b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_GradientPointComponent.h index fad08316..47e54159 100644 --- a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_GradientPointComponent.h +++ b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_GradientPointComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_ImageResourceProperty.h b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_ImageResourceProperty.h index f75881d6..d3c2cc19 100644 --- a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_ImageResourceProperty.h +++ b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_ImageResourceProperty.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -122,7 +121,7 @@ public: if (Project* project = cpp.getProject()) { - ResourceFile resourceFile (*project); + JucerResourceFile resourceFile (*project); for (int i = 0; i < resourceFile.getNumFiles(); ++i) { diff --git a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElement.cpp b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElement.cpp index 26e196b3..d8030778 100644 --- a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElement.cpp +++ b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElement.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElement.h b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElement.h index 1794a5a4..5ab7104c 100644 --- a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElement.h +++ b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElement.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -39,8 +38,8 @@ class ElementSiblingComponent; */ class PaintElement : public Component, - public ChangeListener, - public ComponentBoundsConstrainer + public ComponentBoundsConstrainer, + private ChangeListener { public: //============================================================================== @@ -139,7 +138,7 @@ private: //============================================================================== template <typename ElementType> -class ElementListener : public ChangeListener +class ElementListener : private ChangeListener { public: ElementListener (ElementType* e) @@ -149,7 +148,7 @@ public: broadcaster.addChangeListener (this); } - ~ElementListener() + ~ElementListener() override { jassert (propToRefresh != nullptr); broadcaster.removeChangeListener (this); @@ -160,16 +159,17 @@ public: propToRefresh = &pc; } - void changeListenerCallback (ChangeBroadcaster*) + mutable Component::SafePointer<ElementType> owner; + ChangeBroadcaster& broadcaster; + PropertyComponent* propToRefresh; + +private: + void changeListenerCallback (ChangeBroadcaster*) override { jassert (propToRefresh != nullptr); if (propToRefresh != nullptr && owner != nullptr) propToRefresh->refresh(); } - mutable Component::SafePointer<ElementType> owner; - ChangeBroadcaster& broadcaster; - PropertyComponent* propToRefresh; - JUCE_DECLARE_NON_COPYABLE (ElementListener) }; diff --git a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementEllipse.h b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementEllipse.h index 016d5365..6e0ba228 100644 --- a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementEllipse.h +++ b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementEllipse.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementGroup.cpp b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementGroup.cpp index 489a70ce..f353f9e2 100644 --- a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementGroup.cpp +++ b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementGroup.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementGroup.h b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementGroup.h index d77c3ba2..39b5d789 100644 --- a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementGroup.h +++ b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementGroup.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementImage.cpp b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementImage.cpp index 0ab74221..8185b3ee 100644 --- a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementImage.cpp +++ b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementImage.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -98,9 +97,9 @@ void PaintElementImage::fillInGeneratedCode (GeneratedCode& code, String& paintM code.addImageResourceLoader (imageVariable, resourceName); if (opacity >= 254.0 / 255.0) - r << " g.setColour (Colours::black);\n"; + r << " g.setColour (juce::Colours::black);\n"; else - r << " g.setColour (Colours::black.withAlpha (" << CodeHelpers::floatLiteral (opacity, 3) << "));\n"; + r << " g.setColour (juce::Colours::black.withAlpha (" << CodeHelpers::floatLiteral (opacity, 3) << "));\n"; if (mode == stretched) { @@ -115,9 +114,9 @@ void PaintElementImage::fillInGeneratedCode (GeneratedCode& code, String& paintM << " "; if (mode == proportionalReducingOnly) - r << "RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize"; + r << "juce::RectanglePlacement::centred | juce::RectanglePlacement::onlyReduceInSize"; else - r << "RectanglePlacement::centred"; + r << "juce::RectanglePlacement::centred"; r << ",\n" << " false);\n"; @@ -131,27 +130,27 @@ void PaintElementImage::fillInGeneratedCode (GeneratedCode& code, String& paintM const String imageVariable ("drawable" + String (code.getUniqueSuffix())); code.privateMemberDeclarations - << "std::unique_ptr<Drawable> " << imageVariable << ";\n"; + << "std::unique_ptr<juce::Drawable> " << imageVariable << ";\n"; code.constructorCode - << imageVariable << " = Drawable::createFromImageData (" + << imageVariable << " = juce::Drawable::createFromImageData (" << resourceName << ", " << resourceName << "Size);\n"; code.destructorCode << imageVariable << " = nullptr;\n"; if (opacity >= 254.0 / 255.0) - r << " g.setColour (Colours::black);\n"; + r << " g.setColour (juce::Colours::black);\n"; else - r << " g.setColour (Colours::black.withAlpha (" << CodeHelpers::floatLiteral (opacity, 3) << "));\n"; + r << " g.setColour (juce::Colours::black.withAlpha (" << CodeHelpers::floatLiteral (opacity, 3) << "));\n"; r << " jassert (" << imageVariable << " != nullptr);\n" << " if (" << imageVariable << " != nullptr)\n" - << " " << imageVariable << "->drawWithin (g, Rectangle<int> (x, y, width, height).toFloat(),\n" + << " " << imageVariable << "->drawWithin (g, juce::Rectangle<int> (x, y, width, height).toFloat(),\n" << " " << String::repeatedString (" ", imageVariable.length() + 18) - << (mode == stretched ? "RectanglePlacement::stretchToFit" - : (mode == proportionalReducingOnly ? "RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize" - : "RectanglePlacement::centred")) + << (mode == stretched ? "juce::RectanglePlacement::stretchToFit" + : (mode == proportionalReducingOnly ? "juce::RectanglePlacement::centred | juce::RectanglePlacement::onlyReduceInSize" + : "juce::RectanglePlacement::centred")) << ", " << CodeHelpers::floatLiteral (opacity, 3) << ");\n"; } } diff --git a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementImage.h b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementImage.h index 905b90a7..5f6c3ca5 100644 --- a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementImage.h +++ b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementImage.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementPath.cpp b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementPath.cpp index feaeff44..0f74d5c9 100644 --- a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementPath.cpp +++ b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementPath.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -99,10 +98,10 @@ private: //============================================================================== class PathWindingModeProperty : public ChoicePropertyComponent, - public ChangeListener + private ChangeListener { public: - PathWindingModeProperty (PaintElementPath* const owner_) + explicit PathWindingModeProperty (PaintElementPath* const owner_) : ChoicePropertyComponent ("winding rule"), owner (owner_) { @@ -112,17 +111,17 @@ public: owner->getDocument()->addChangeListener (this); } - ~PathWindingModeProperty() + ~PathWindingModeProperty() override { owner->getDocument()->removeChangeListener (this); } - void setIndex (int newIndex) { owner->setNonZeroWinding (newIndex == 0, true); } - int getIndex() const { return owner->isNonZeroWinding() ? 0 : 1; } - - void changeListenerCallback (ChangeBroadcaster*) { refresh(); } + void setIndex (int newIndex) override { owner->setNonZeroWinding (newIndex == 0, true); } + int getIndex() const override { return owner->isNonZeroWinding() ? 0 : 1; } private: + void changeListenerCallback (ChangeBroadcaster*) override { refresh(); } + PaintElementPath* const owner; }; @@ -377,7 +376,7 @@ void PaintElementPath::fillInGeneratedCode (GeneratedCode& code, String& paintMe const ComponentLayout* layout = code.document->getComponentLayout(); code.privateMemberDeclarations - << "Path " << pathVariable << ";\n"; + << "juce::Path " << pathVariable << ";\n"; String r; bool somePointsAreRelative = false; @@ -455,14 +454,14 @@ void PaintElementPath::fillInGeneratedCode (GeneratedCode& code, String& paintMe { s << " "; fillType.fillInGeneratedCode ("fill", zero, code, s); - s << " g.fillPath (" << pathVariable << ", AffineTransform::translation(x, y));\n"; + s << " g.fillPath (" << pathVariable << ", juce::AffineTransform::translation(x, y));\n"; } if (isStrokePresent && ! strokeType.isInvisible()) { s << " "; strokeType.fill.fillInGeneratedCode ("stroke", zero, code, s); - s << " g.strokePath (" << pathVariable << ", " << strokeType.getPathStrokeCode() << ", AffineTransform::translation(x, y));\n"; + s << " g.strokePath (" << pathVariable << ", " << strokeType.getPathStrokeCode() << ", juce::AffineTransform::translation(x, y));\n"; } s << "}\n\n"; @@ -1182,7 +1181,7 @@ void PaintElementPath::setPoint (int index, int pointNumber, const RelativePosit //============================================================================== class PathPointTypeProperty : public ChoicePropertyComponent, - public ChangeListener + private ChangeListener { public: PathPointTypeProperty (PaintElementPath* const owner_, @@ -1199,12 +1198,12 @@ public: owner->getDocument()->addChangeListener (this); } - ~PathPointTypeProperty() + ~PathPointTypeProperty() override { owner->getDocument()->removeChangeListener (this); } - void setIndex (int newIndex) + void setIndex (int newIndex) override { Path::Iterator::PathElementType type = Path::Iterator::startNewSubPath; @@ -1221,7 +1220,7 @@ public: owner->getPoint (index)->changePointType (type, area, true); } - int getIndex() const + int getIndex() const override { const PathPoint* const p = owner->getPoint (index); jassert (p != nullptr); @@ -1239,12 +1238,12 @@ public: return 0; } - void changeListenerCallback (ChangeBroadcaster*) +private: + void changeListenerCallback (ChangeBroadcaster*) override { refresh(); } -private: PaintElementPath* const owner; const int index; }; diff --git a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementPath.h b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementPath.h index a97fb6a4..b11a0b11 100644 --- a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementPath.h +++ b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementPath.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementRectangle.h b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementRectangle.h index 5dafb3a4..aee6f147 100644 --- a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementRectangle.h +++ b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementRectangle.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementRoundedRectangle.h b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementRoundedRectangle.h index ca069a48..0fc6f4a0 100644 --- a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementRoundedRectangle.h +++ b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementRoundedRectangle.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -212,7 +211,7 @@ private: //============================================================================== class CornerSizeProperty : public SliderPropertyComponent, - public ChangeListener + private juce::ChangeListener { public: CornerSizeProperty (PaintElementRoundedRectangle* const owner_) @@ -222,23 +221,23 @@ private: owner->getDocument()->addChangeListener (this); } - ~CornerSizeProperty() + ~CornerSizeProperty() override { owner->getDocument()->removeChangeListener (this); } - void setValue (double newValue) + void setValue (double newValue) override { owner->getDocument()->getUndoManager().undoCurrentTransactionOnly(); owner->setCornerSize (newValue, true); } - double getValue() const { return owner->getCornerSize(); } - - void changeListenerCallback (ChangeBroadcaster*) { refresh(); } + double getValue() const override { return owner->getCornerSize(); } private: + void changeListenerCallback (ChangeBroadcaster*) override { refresh(); } + PaintElementRoundedRectangle* const owner; }; diff --git a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementText.h b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementText.h index e8b1be10..95166072 100644 --- a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementText.h +++ b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementText.h @@ -1,673 +1,672 @@ -/* - ============================================================================== - - 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. - - ============================================================================== -*/ - -#pragma once - -#include "jucer_ColouredElement.h" -#include "../Properties/jucer_FontPropertyComponent.h" -#include "../Properties/jucer_JustificationProperty.h" - -//============================================================================== -class PaintElementText : public ColouredElement -{ -public: - PaintElementText (PaintRoutine* pr) - : ColouredElement (pr, "Text", false, false), - text ("Your text goes here"), - font (15.0f), - typefaceName (FontPropertyComponent::getDefaultFont()), - justification (Justification::centred) - { - fillType.colour = Colours::black; - position.rect.setWidth (200); - position.rect.setHeight (30); - } - - //============================================================================== - void draw (Graphics& g, const ComponentLayout* layout, const Rectangle<int>& parentArea) override - { - fillType.setFillType (g, getDocument(), parentArea); - - font = FontPropertyComponent::applyNameToFont (typefaceName, font); - g.setFont (font); - - g.drawText (replaceStringTranslations (text, owner->getDocument()), - position.getRectangle (parentArea, layout), justification, true); - } - - static String replaceStringTranslations (String s, JucerDocument* document) - { - s = s.replace ("%%getName()%%", document->getComponentName()); - s = s.replace ("%%getButtonText()%%", document->getComponentName()); - return s; - } - - void getEditableProperties (Array<PropertyComponent*>& props, bool multipleSelected) override - { - ColouredElement::getEditableProperties (props, multipleSelected); - - if (multipleSelected) - return; - - props.add (new TextProperty (this)); - props.add (new FontNameProperty (this)); - props.add (new FontStyleProperty (this)); - props.add (new FontSizeProperty (this)); - props.add (new FontKerningProperty (this)); - props.add (new TextJustificationProperty (this)); - props.add (new TextToPathProperty (this)); - } - - void fillInGeneratedCode (GeneratedCode& code, String& paintMethodCode) override - { - if (! fillType.isInvisible()) - { - String x, y, w, h, r; - positionToCode (position, code.document->getComponentLayout(), x, y, w, h); - r << "{\n" - << " int x = " << x << ", y = " << y << ", width = " << w << ", height = " << h << ";\n" - << " String text (" << quotedString (text, code.shouldUseTransMacro()) << ");\n" - << " " << fillType.generateVariablesCode ("fill") - << " //[UserPaintCustomArguments] Customize the painting arguments here..\n" - << customPaintCode - << " //[/UserPaintCustomArguments]\n" - << " "; - fillType.fillInGeneratedCode ("fill", position, code, r); - r << " g.setFont (" << FontPropertyComponent::getCompleteFontCode (font, typefaceName) << ");\n" - << " g.drawText (text, x, y, width, height,\n" - << " " << CodeHelpers::justificationToCode (justification) << ", true);\n" - << "}\n\n"; - - paintMethodCode += r; - } - } - - void applyCustomPaintSnippets (StringArray& snippets) override - { - customPaintCode.clear(); - - if (! snippets.isEmpty() && ! fillType.isInvisible()) - { - customPaintCode = snippets[0]; - snippets.remove (0); - } - } - - static const char* getTagName() noexcept { return "TEXT"; } - - XmlElement* createXml() const override - { - XmlElement* e = new XmlElement (getTagName()); - position.applyToXml (*e); - addColourAttributes (e); - e->setAttribute ("text", text); - e->setAttribute ("fontname", typefaceName); - e->setAttribute ("fontsize", roundToInt (font.getHeight() * 100.0) / 100.0); - e->setAttribute ("kerning", roundToInt (font.getExtraKerningFactor() * 1000.0) / 1000.0); - e->setAttribute ("bold", font.isBold()); - e->setAttribute ("italic", font.isItalic()); - e->setAttribute ("justification", justification.getFlags()); - if (font.getTypefaceStyle() != "Regular") - { - e->setAttribute ("typefaceStyle", font.getTypefaceStyle()); - } - - return e; - } - - bool loadFromXml (const XmlElement& xml) override - { - if (xml.hasTagName (getTagName())) - { - position.restoreFromXml (xml, position); - loadColourAttributes (xml); - - text = xml.getStringAttribute ("text", "Hello World"); - typefaceName = xml.getStringAttribute ("fontname", FontPropertyComponent::getDefaultFont()); - font = FontPropertyComponent::applyNameToFont (typefaceName, font); - font.setHeight ((float) xml.getDoubleAttribute ("fontsize", 15.0)); - font.setBold (xml.getBoolAttribute ("bold", false)); - font.setItalic (xml.getBoolAttribute ("italic", false)); - font.setExtraKerningFactor ((float) xml.getDoubleAttribute ("kerning", 0.0)); - justification = Justification (xml.getIntAttribute ("justification", Justification::centred)); - auto fontStyle = xml.getStringAttribute ("typefaceStyle"); - if (! fontStyle.isEmpty()) - font.setTypefaceStyle (fontStyle); - - return true; - } - - jassertfalse; - return false; - } - - //============================================================================== - const String& getText() const noexcept { return text; } - - class SetTextAction : public PaintElementUndoableAction <PaintElementText> - { - public: - SetTextAction (PaintElementText* const element, const String& newText_) - : PaintElementUndoableAction <PaintElementText> (element), - newText (newText_), - oldText (element->getText()) - { - } - - bool perform() - { - showCorrectTab(); - getElement()->setText (newText, false); - return true; - } - - bool undo() - { - showCorrectTab(); - getElement()->setText (oldText, false); - return true; - } - - private: - String newText, oldText; - }; - - void setText (const String& t, const bool undoable) - { - if (t != text) - { - if (undoable) - { - perform (new SetTextAction (this, t), - "Change text element text"); - } - else - { - text = t; - changed(); - } - } - } - - //============================================================================== - const Font& getFont() const { return font; } - - class SetFontAction : public PaintElementUndoableAction <PaintElementText> - { - public: - SetFontAction (PaintElementText* const element, const Font& newFont_) - : PaintElementUndoableAction <PaintElementText> (element), - newFont (newFont_), - oldFont (element->getFont()) - { - } - - bool perform() - { - showCorrectTab(); - getElement()->setFont (newFont, false); - return true; - } - - bool undo() - { - showCorrectTab(); - getElement()->setFont (oldFont, false); - return true; - } - - private: - Font newFont, oldFont; - }; - - void setFont (const Font& newFont, const bool undoable) - { - if (font != newFont) - { - if (undoable) - { - perform (new SetFontAction (this, newFont), - "Change text element font"); - } - else - { - font = newFont; - changed(); - } - } - } - - //============================================================================== - class SetTypefaceAction : public PaintElementUndoableAction <PaintElementText> - { - public: - SetTypefaceAction (PaintElementText* const element, const String& newValue_) - : PaintElementUndoableAction <PaintElementText> (element), - newValue (newValue_), - oldValue (element->getTypefaceName()) - { - } - - bool perform() - { - showCorrectTab(); - getElement()->setTypefaceName (newValue, false); - return true; - } - - bool undo() - { - showCorrectTab(); - getElement()->setTypefaceName (oldValue, false); - return true; - } - - private: - String newValue, oldValue; - }; - - void setTypefaceName (const String& newFontName, const bool undoable) - { - if (undoable) - { - perform (new SetTypefaceAction (this, newFontName), - "Change text element typeface"); - } - else - { - typefaceName = newFontName; - changed(); - } - } - - String getTypefaceName() const noexcept { return typefaceName; } - - //============================================================================== - Justification getJustification() const noexcept { return justification; } - - class SetJustifyAction : public PaintElementUndoableAction <PaintElementText> - { - public: - SetJustifyAction (PaintElementText* const element, Justification newValue_) - : PaintElementUndoableAction <PaintElementText> (element), - newValue (newValue_), - oldValue (element->getJustification()) - { - } - - bool perform() - { - showCorrectTab(); - getElement()->setJustification (newValue, false); - return true; - } - - bool undo() - { - showCorrectTab(); - getElement()->setJustification (oldValue, false); - return true; - } - - private: - Justification newValue, oldValue; - }; - - void setJustification (Justification j, const bool undoable) - { - if (justification.getFlags() != j.getFlags()) - { - if (undoable) - { - perform (new SetJustifyAction (this, j), - "Change text element justification"); - } - else - { - justification = j; - changed(); - } - } - } - - void convertToPath() - { - if (PaintRoutineEditor* parent = dynamic_cast<PaintRoutineEditor*> (getParentComponent())) - { - - font = FontPropertyComponent::applyNameToFont (typefaceName, font); - - const Rectangle<int> r = - getCurrentBounds (parent->getComponentArea().withZeroOrigin()); - - GlyphArrangement arr; - arr.addCurtailedLineOfText (font, text, - 0.0f, 0.0f, (float) r.getWidth(), - true); - - arr.justifyGlyphs (0, arr.getNumGlyphs(), - (float) r.getX(), (float) r.getY(), - (float) r.getWidth(), (float) r.getHeight(), - justification); - - Path path; - arr.createPath (path); - - convertToNewPathElement (path); - } - else - { - jassertfalse; - } - } - -private: - String text; - Font font; - String typefaceName; - Justification justification; - String customPaintCode; - - Array <Justification> justificationTypes; - - //============================================================================== - class TextProperty : public TextPropertyComponent, - public ChangeListener - { - public: - TextProperty (PaintElementText* const e) - : TextPropertyComponent ("text", 2048, false), - element (e) - { - element->getDocument()->addChangeListener (this); - } - - ~TextProperty() override - { - element->getDocument()->removeChangeListener (this); - } - - void setText (const String& newText) override { element->setText (newText, true); } - String getText() const override { return element->getText(); } - - void changeListenerCallback (ChangeBroadcaster*) override { refresh(); } - - private: - PaintElementText* const element; - }; - - //============================================================================== - class FontNameProperty : public FontPropertyComponent, - public ChangeListener - { - public: - FontNameProperty (PaintElementText* const e) - : FontPropertyComponent ("font"), - element (e) - { - element->getDocument()->addChangeListener (this); - } - - ~FontNameProperty() - { - element->getDocument()->removeChangeListener (this); - } - - void setTypefaceName (const String& newFontName) { element->setTypefaceName (newFontName, true); } - String getTypefaceName() const { return element->getTypefaceName(); } - - void changeListenerCallback (ChangeBroadcaster*) { refresh(); } - - private: - PaintElementText* const element; - }; - - //============================================================================== - class FontStyleProperty : public ChoicePropertyComponent, - public ChangeListener - { - public: - FontStyleProperty (PaintElementText* const e) - : ChoicePropertyComponent ("style"), - element (e) - { - element->getDocument()->addChangeListener (this); - - updateStylesList (element->getTypefaceName()); - } - - ~FontStyleProperty() - { - element->getDocument()->removeChangeListener (this); - } - - void updateStylesList (const String& name) - { - if (getNumChildComponents() > 0) - { - if (auto cb = dynamic_cast<ComboBox*> (getChildComponent (0))) - cb->clear(); - - getChildComponent (0)->setVisible (false); - removeAllChildren(); - } - - choices.clear(); - - choices.add ("Regular"); - choices.add ("Bold"); - choices.add ("Italic"); - choices.add ("Bold Italic"); - - choices.mergeArray (Font::findAllTypefaceStyles (name)); - refresh(); - } - - void setIndex (int newIndex) - { - Font f (element->getFont()); - - if (f.getAvailableStyles().contains (choices[newIndex])) - { - f.setBold (false); - f.setItalic (false); - f.setTypefaceStyle (choices[newIndex]); - } - else - { - f.setTypefaceStyle ("Regular"); - f.setBold (newIndex == 1 || newIndex == 3); - f.setItalic (newIndex == 2 || newIndex == 3); - } - - element->setFont (f, true); - } - - int getIndex() const - { - auto f = element->getFont(); - - const auto typefaceIndex = choices.indexOf (f.getTypefaceStyle()); - if (typefaceIndex == -1) - { - if (f.isBold() && f.isItalic()) - return 3; - else if (f.isBold()) - return 1; - else if (f.isItalic()) - return 2; - - return 0; - } - - return typefaceIndex; - } - - void changeListenerCallback (ChangeBroadcaster*) - { - updateStylesList (element->getTypefaceName()); - } - - private: - PaintElementText* const element; - }; - - //============================================================================== - class FontSizeProperty : public SliderPropertyComponent, - public ChangeListener - { - public: - FontSizeProperty (PaintElementText* const e) - : SliderPropertyComponent ("size", 1.0, 250.0, 0.1, 0.3), - element (e) - { - element->getDocument()->addChangeListener (this); - } - - ~FontSizeProperty() - { - element->getDocument()->removeChangeListener (this); - } - - void setValue (double newValue) - { - element->getDocument()->getUndoManager().undoCurrentTransactionOnly(); - - Font f (element->getFont()); - f.setHeight ((float) newValue); - - element->setFont (f, true); - } - - double getValue() const - { - return element->getFont().getHeight(); - } - - void changeListenerCallback (ChangeBroadcaster*) { refresh(); } - - private: - PaintElementText* const element; - }; - - //============================================================================== - class FontKerningProperty : public SliderPropertyComponent, - public ChangeListener - { - public: - FontKerningProperty (PaintElementText* const e) - : SliderPropertyComponent ("kerning", -0.5, 0.5, 0.001), - element (e) - { - element->getDocument()->addChangeListener (this); - } - - ~FontKerningProperty() - { - element->getDocument()->removeChangeListener (this); - } - - void setValue (double newValue) - { - element->getDocument()->getUndoManager().undoCurrentTransactionOnly(); - - Font f (element->getFont()); - f.setExtraKerningFactor ((float) newValue); - - element->setFont (f, true); - } - - double getValue() const - { - return element->getFont().getExtraKerningFactor(); - } - - void changeListenerCallback (ChangeBroadcaster*) - { - refresh(); - } - - private: - PaintElementText* const element; - }; - - //============================================================================== - class TextJustificationProperty : public JustificationProperty, - public ChangeListener - { - public: - TextJustificationProperty (PaintElementText* const e) - : JustificationProperty ("layout", false), - element (e) - { - element->getDocument()->addChangeListener (this); - } - - ~TextJustificationProperty() - { - element->getDocument()->removeChangeListener (this); - } - - void setJustification (Justification newJustification) - { - element->setJustification (newJustification, true); - } - - Justification getJustification() const - { - return element->getJustification(); - } - - void changeListenerCallback (ChangeBroadcaster*) { refresh(); } - - private: - PaintElementText* const element; - }; - - //============================================================================== - class TextToPathProperty : public ButtonPropertyComponent - { - public: - TextToPathProperty (PaintElementText* const e) - : ButtonPropertyComponent ("path", false), - element (e) - { - } - - void buttonClicked() - { - element->convertToPath(); - } - - String getButtonText() const - { - return "convert text to a path"; - } - - private: - PaintElementText* const element; - }; -}; +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +#pragma once + +#include "jucer_ColouredElement.h" +#include "../Properties/jucer_FontPropertyComponent.h" +#include "../Properties/jucer_JustificationProperty.h" + +//============================================================================== +class PaintElementText : public ColouredElement +{ +public: + PaintElementText (PaintRoutine* pr) + : ColouredElement (pr, "Text", false, false), + text ("Your text goes here"), + font (15.0f), + typefaceName (FontPropertyComponent::getDefaultFont()), + justification (Justification::centred) + { + fillType.colour = Colours::black; + position.rect.setWidth (200); + position.rect.setHeight (30); + } + + //============================================================================== + void draw (Graphics& g, const ComponentLayout* layout, const Rectangle<int>& parentArea) override + { + fillType.setFillType (g, getDocument(), parentArea); + + font = FontPropertyComponent::applyNameToFont (typefaceName, font); + g.setFont (font); + + g.drawText (replaceStringTranslations (text, owner->getDocument()), + position.getRectangle (parentArea, layout), justification, true); + } + + static String replaceStringTranslations (String s, JucerDocument* document) + { + s = s.replace ("%%getName()%%", document->getComponentName()); + s = s.replace ("%%getButtonText()%%", document->getComponentName()); + return s; + } + + void getEditableProperties (Array<PropertyComponent*>& props, bool multipleSelected) override + { + ColouredElement::getEditableProperties (props, multipleSelected); + + if (multipleSelected) + return; + + props.add (new TextProperty (this)); + props.add (new FontNameProperty (this)); + props.add (new FontStyleProperty (this)); + props.add (new FontSizeProperty (this)); + props.add (new FontKerningProperty (this)); + props.add (new TextJustificationProperty (this)); + props.add (new TextToPathProperty (this)); + } + + void fillInGeneratedCode (GeneratedCode& code, String& paintMethodCode) override + { + if (! fillType.isInvisible()) + { + String x, y, w, h, r; + positionToCode (position, code.document->getComponentLayout(), x, y, w, h); + r << "{\n" + << " int x = " << x << ", y = " << y << ", width = " << w << ", height = " << h << ";\n" + << " juce::String text (" << quotedString (text, code.shouldUseTransMacro()) << ");\n" + << " " << fillType.generateVariablesCode ("fill") + << " //[UserPaintCustomArguments] Customize the painting arguments here..\n" + << customPaintCode + << " //[/UserPaintCustomArguments]\n" + << " "; + fillType.fillInGeneratedCode ("fill", position, code, r); + r << " g.setFont (" << FontPropertyComponent::getCompleteFontCode (font, typefaceName) << ");\n" + << " g.drawText (text, x, y, width, height,\n" + << " " << CodeHelpers::justificationToCode (justification) << ", true);\n" + << "}\n\n"; + + paintMethodCode += r; + } + } + + void applyCustomPaintSnippets (StringArray& snippets) override + { + customPaintCode.clear(); + + if (! snippets.isEmpty() && ! fillType.isInvisible()) + { + customPaintCode = snippets[0]; + snippets.remove (0); + } + } + + static const char* getTagName() noexcept { return "TEXT"; } + + XmlElement* createXml() const override + { + XmlElement* e = new XmlElement (getTagName()); + position.applyToXml (*e); + addColourAttributes (e); + e->setAttribute ("text", text); + e->setAttribute ("fontname", typefaceName); + e->setAttribute ("fontsize", roundToInt (font.getHeight() * 100.0) / 100.0); + e->setAttribute ("kerning", roundToInt (font.getExtraKerningFactor() * 1000.0) / 1000.0); + e->setAttribute ("bold", font.isBold()); + e->setAttribute ("italic", font.isItalic()); + e->setAttribute ("justification", justification.getFlags()); + if (font.getTypefaceStyle() != "Regular") + { + e->setAttribute ("typefaceStyle", font.getTypefaceStyle()); + } + + return e; + } + + bool loadFromXml (const XmlElement& xml) override + { + if (xml.hasTagName (getTagName())) + { + position.restoreFromXml (xml, position); + loadColourAttributes (xml); + + text = xml.getStringAttribute ("text", "Hello World"); + typefaceName = xml.getStringAttribute ("fontname", FontPropertyComponent::getDefaultFont()); + font = FontPropertyComponent::applyNameToFont (typefaceName, font); + font.setHeight ((float) xml.getDoubleAttribute ("fontsize", 15.0)); + font.setBold (xml.getBoolAttribute ("bold", false)); + font.setItalic (xml.getBoolAttribute ("italic", false)); + font.setExtraKerningFactor ((float) xml.getDoubleAttribute ("kerning", 0.0)); + justification = Justification (xml.getIntAttribute ("justification", Justification::centred)); + auto fontStyle = xml.getStringAttribute ("typefaceStyle"); + if (! fontStyle.isEmpty()) + font.setTypefaceStyle (fontStyle); + + return true; + } + + jassertfalse; + return false; + } + + //============================================================================== + const String& getText() const noexcept { return text; } + + class SetTextAction : public PaintElementUndoableAction <PaintElementText> + { + public: + SetTextAction (PaintElementText* const element, const String& newText_) + : PaintElementUndoableAction <PaintElementText> (element), + newText (newText_), + oldText (element->getText()) + { + } + + bool perform() + { + showCorrectTab(); + getElement()->setText (newText, false); + return true; + } + + bool undo() + { + showCorrectTab(); + getElement()->setText (oldText, false); + return true; + } + + private: + String newText, oldText; + }; + + void setText (const String& t, const bool undoable) + { + if (t != text) + { + if (undoable) + { + perform (new SetTextAction (this, t), + "Change text element text"); + } + else + { + text = t; + changed(); + } + } + } + + //============================================================================== + const Font& getFont() const { return font; } + + class SetFontAction : public PaintElementUndoableAction <PaintElementText> + { + public: + SetFontAction (PaintElementText* const element, const Font& newFont_) + : PaintElementUndoableAction <PaintElementText> (element), + newFont (newFont_), + oldFont (element->getFont()) + { + } + + bool perform() + { + showCorrectTab(); + getElement()->setFont (newFont, false); + return true; + } + + bool undo() + { + showCorrectTab(); + getElement()->setFont (oldFont, false); + return true; + } + + private: + Font newFont, oldFont; + }; + + void setFont (const Font& newFont, const bool undoable) + { + if (font != newFont) + { + if (undoable) + { + perform (new SetFontAction (this, newFont), + "Change text element font"); + } + else + { + font = newFont; + changed(); + } + } + } + + //============================================================================== + class SetTypefaceAction : public PaintElementUndoableAction <PaintElementText> + { + public: + SetTypefaceAction (PaintElementText* const element, const String& newValue_) + : PaintElementUndoableAction <PaintElementText> (element), + newValue (newValue_), + oldValue (element->getTypefaceName()) + { + } + + bool perform() + { + showCorrectTab(); + getElement()->setTypefaceName (newValue, false); + return true; + } + + bool undo() + { + showCorrectTab(); + getElement()->setTypefaceName (oldValue, false); + return true; + } + + private: + String newValue, oldValue; + }; + + void setTypefaceName (const String& newFontName, const bool undoable) + { + if (undoable) + { + perform (new SetTypefaceAction (this, newFontName), + "Change text element typeface"); + } + else + { + typefaceName = newFontName; + changed(); + } + } + + String getTypefaceName() const noexcept { return typefaceName; } + + //============================================================================== + Justification getJustification() const noexcept { return justification; } + + class SetJustifyAction : public PaintElementUndoableAction <PaintElementText> + { + public: + SetJustifyAction (PaintElementText* const element, Justification newValue_) + : PaintElementUndoableAction <PaintElementText> (element), + newValue (newValue_), + oldValue (element->getJustification()) + { + } + + bool perform() + { + showCorrectTab(); + getElement()->setJustification (newValue, false); + return true; + } + + bool undo() + { + showCorrectTab(); + getElement()->setJustification (oldValue, false); + return true; + } + + private: + Justification newValue, oldValue; + }; + + void setJustification (Justification j, const bool undoable) + { + if (justification.getFlags() != j.getFlags()) + { + if (undoable) + { + perform (new SetJustifyAction (this, j), + "Change text element justification"); + } + else + { + justification = j; + changed(); + } + } + } + + void convertToPath() + { + if (PaintRoutineEditor* parent = dynamic_cast<PaintRoutineEditor*> (getParentComponent())) + { + + font = FontPropertyComponent::applyNameToFont (typefaceName, font); + + const Rectangle<int> r = + getCurrentBounds (parent->getComponentArea().withZeroOrigin()); + + GlyphArrangement arr; + arr.addCurtailedLineOfText (font, text, + 0.0f, 0.0f, (float) r.getWidth(), + true); + + arr.justifyGlyphs (0, arr.getNumGlyphs(), + (float) r.getX(), (float) r.getY(), + (float) r.getWidth(), (float) r.getHeight(), + justification); + + Path path; + arr.createPath (path); + + convertToNewPathElement (path); + } + else + { + jassertfalse; + } + } + +private: + String text; + Font font; + String typefaceName; + Justification justification; + String customPaintCode; + + Array <Justification> justificationTypes; + + //============================================================================== + class TextProperty : public TextPropertyComponent, + private juce::ChangeListener + { + public: + TextProperty (PaintElementText* const e) + : TextPropertyComponent ("text", 2048, false), + element (e) + { + element->getDocument()->addChangeListener (this); + } + + ~TextProperty() override + { + element->getDocument()->removeChangeListener (this); + } + + void setText (const String& newText) override { element->setText (newText, true); } + String getText() const override { return element->getText(); } + + private: + void changeListenerCallback (ChangeBroadcaster*) override { refresh(); } + + PaintElementText* const element; + }; + + //============================================================================== + class FontNameProperty : public FontPropertyComponent, + private juce::ChangeListener + { + public: + FontNameProperty (PaintElementText* const e) + : FontPropertyComponent ("font"), + element (e) + { + element->getDocument()->addChangeListener (this); + } + + ~FontNameProperty() + { + element->getDocument()->removeChangeListener (this); + } + + void setTypefaceName (const String& newFontName) { element->setTypefaceName (newFontName, true); } + String getTypefaceName() const { return element->getTypefaceName(); } + + private: + void changeListenerCallback (ChangeBroadcaster*) { refresh(); } + + PaintElementText* const element; + }; + + //============================================================================== + class FontStyleProperty : public ChoicePropertyComponent, + private juce::ChangeListener + { + public: + FontStyleProperty (PaintElementText* const e) + : ChoicePropertyComponent ("style"), + element (e) + { + element->getDocument()->addChangeListener (this); + + updateStylesList (element->getTypefaceName()); + } + + ~FontStyleProperty() + { + element->getDocument()->removeChangeListener (this); + } + + void updateStylesList (const String& name) + { + if (getNumChildComponents() > 0) + { + if (auto cb = dynamic_cast<ComboBox*> (getChildComponent (0))) + cb->clear(); + + getChildComponent (0)->setVisible (false); + removeAllChildren(); + } + + choices.clear(); + + choices.add ("Regular"); + choices.add ("Bold"); + choices.add ("Italic"); + choices.add ("Bold Italic"); + + choices.mergeArray (Font::findAllTypefaceStyles (name)); + refresh(); + } + + void setIndex (int newIndex) + { + Font f (element->getFont()); + + if (f.getAvailableStyles().contains (choices[newIndex])) + { + f.setBold (false); + f.setItalic (false); + f.setTypefaceStyle (choices[newIndex]); + } + else + { + f.setTypefaceStyle ("Regular"); + f.setBold (newIndex == 1 || newIndex == 3); + f.setItalic (newIndex == 2 || newIndex == 3); + } + + element->setFont (f, true); + } + + int getIndex() const + { + auto f = element->getFont(); + + const auto typefaceIndex = choices.indexOf (f.getTypefaceStyle()); + if (typefaceIndex == -1) + { + if (f.isBold() && f.isItalic()) + return 3; + else if (f.isBold()) + return 1; + else if (f.isItalic()) + return 2; + + return 0; + } + + return typefaceIndex; + } + + private: + void changeListenerCallback (ChangeBroadcaster*) + { + updateStylesList (element->getTypefaceName()); + } + + PaintElementText* const element; + }; + + //============================================================================== + class FontSizeProperty : public SliderPropertyComponent, + private juce::ChangeListener + { + public: + FontSizeProperty (PaintElementText* const e) + : SliderPropertyComponent ("size", 1.0, 250.0, 0.1, 0.3), + element (e) + { + element->getDocument()->addChangeListener (this); + } + + ~FontSizeProperty() override + { + element->getDocument()->removeChangeListener (this); + } + + void setValue (double newValue) override + { + element->getDocument()->getUndoManager().undoCurrentTransactionOnly(); + + Font f (element->getFont()); + f.setHeight ((float) newValue); + + element->setFont (f, true); + } + + double getValue() const override + { + return element->getFont().getHeight(); + } + + private: + void changeListenerCallback (ChangeBroadcaster*) override { refresh(); } + + PaintElementText* const element; + }; + + //============================================================================== + class FontKerningProperty : public SliderPropertyComponent, + private juce::ChangeListener + { + public: + FontKerningProperty (PaintElementText* const e) + : SliderPropertyComponent ("kerning", -0.5, 0.5, 0.001), + element (e) + { + element->getDocument()->addChangeListener (this); + } + + ~FontKerningProperty() override + { + element->getDocument()->removeChangeListener (this); + } + + void setValue (double newValue) override + { + element->getDocument()->getUndoManager().undoCurrentTransactionOnly(); + + Font f (element->getFont()); + f.setExtraKerningFactor ((float) newValue); + + element->setFont (f, true); + } + + double getValue() const override + { + return element->getFont().getExtraKerningFactor(); + } + + private: + void changeListenerCallback (ChangeBroadcaster*) override + { + refresh(); + } + + PaintElementText* const element; + }; + + //============================================================================== + class TextJustificationProperty : public JustificationProperty, + private juce::ChangeListener + { + public: + TextJustificationProperty (PaintElementText* const e) + : JustificationProperty ("layout", false), + element (e) + { + element->getDocument()->addChangeListener (this); + } + + ~TextJustificationProperty() override + { + element->getDocument()->removeChangeListener (this); + } + + void setJustification (Justification newJustification) override + { + element->setJustification (newJustification, true); + } + + Justification getJustification() const override + { + return element->getJustification(); + } + + private: + void changeListenerCallback (ChangeBroadcaster*) override { refresh(); } + + PaintElementText* const element; + }; + + //============================================================================== + class TextToPathProperty : public ButtonPropertyComponent + { + public: + TextToPathProperty (PaintElementText* const e) + : ButtonPropertyComponent ("path", false), + element (e) + { + } + + void buttonClicked() + { + element->convertToPath(); + } + + String getButtonText() const + { + return "convert text to a path"; + } + + private: + PaintElementText* const element; + }; +}; diff --git a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementUndoableAction.h b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementUndoableAction.h index 6421dba1..7deb19d6 100644 --- a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementUndoableAction.h +++ b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElementUndoableAction.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -84,7 +83,7 @@ protected: void changed() const { - jassert (routine.getDocument() != 0); + jassert (routine.getDocument() != nullptr); routine.getDocument()->changed(); } diff --git a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PointComponent.h b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PointComponent.h index 2f8a6b55..f3c80d54 100644 --- a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PointComponent.h +++ b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PointComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -58,10 +57,10 @@ public: void paint (Graphics& g) override { g.setColour (Colours::white); - g.drawEllipse (2.0f, 2.0f, getWidth() - 4.0f, getHeight() - 4.0f, 2.0f); + g.drawEllipse (2.0f, 2.0f, (float) getWidth() - 4.0f, (float) getHeight() - 4.0f, 2.0f); g.setColour (Colours::black); - g.drawEllipse (1.0f, 1.0f, getWidth() - 2.0f, getHeight() - 2.0f, 2.0f); + g.drawEllipse (1.0f, 1.0f, (float) getWidth() - 2.0f, (float) getHeight() - 2.0f, 2.0f); } //============================================================================== diff --git a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_StrokeType.h b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_StrokeType.h index dc1c13a5..b65ad3a4 100644 --- a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_StrokeType.h +++ b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_StrokeType.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -43,7 +42,7 @@ public: String s; - s << "PathStrokeType (" << CodeHelpers::floatLiteral (stroke.getStrokeThickness(), 3); + s << "juce::PathStrokeType (" << CodeHelpers::floatLiteral (stroke.getStrokeThickness(), 3); if (stroke.getJointStyle() != defaultStroke.getJointStyle() || stroke.getEndStyle() != defaultStroke.getEndStyle()) @@ -52,9 +51,9 @@ public: switch (stroke.getJointStyle()) { - case PathStrokeType::mitered: s << "PathStrokeType::mitered"; break; - case PathStrokeType::curved: s << "PathStrokeType::curved"; break; - case PathStrokeType::beveled: s << "PathStrokeType::beveled"; break; + case PathStrokeType::mitered: s << "juce::PathStrokeType::mitered"; break; + case PathStrokeType::curved: s << "juce::PathStrokeType::curved"; break; + case PathStrokeType::beveled: s << "juce::PathStrokeType::beveled"; break; default: jassertfalse; break; } @@ -64,9 +63,9 @@ public: switch (stroke.getEndStyle()) { - case PathStrokeType::butt: s << "PathStrokeType::butt"; break; - case PathStrokeType::square: s << "PathStrokeType::square"; break; - case PathStrokeType::rounded: s << "PathStrokeType::rounded"; break; + case PathStrokeType::butt: s << "juce::PathStrokeType::butt"; break; + case PathStrokeType::square: s << "juce::PathStrokeType::square"; break; + case PathStrokeType::rounded: s << "juce::PathStrokeType::rounded"; break; default: jassertfalse; break; } } diff --git a/extras/Projucer/Source/ComponentEditor/Properties/jucer_ColourPropertyComponent.h b/extras/Projucer/Source/ComponentEditor/Properties/jucer_ColourPropertyComponent.h index 971f2167..2ba8f534 100644 --- a/extras/Projucer/Source/ComponentEditor/Properties/jucer_ColourPropertyComponent.h +++ b/extras/Projucer/Source/ComponentEditor/Properties/jucer_ColourPropertyComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -49,7 +48,7 @@ public: } class ColourEditorComponent : public Component, - public ChangeListener + private ChangeListener { public: ColourEditorComponent (const bool canReset) @@ -67,7 +66,7 @@ public: Colour (0xffffffff).overlaidWith (colour)); g.setColour (Colours::white.overlaidWith (colour).contrasting()); - g.setFont (Font (getHeight() * 0.6f, Font::bold)); + g.setFont (Font ((float) getHeight() * 0.6f, Font::bold)); g.drawFittedText (colour.toDisplayString (true), 2, 1, getWidth() - 4, getHeight() - 1, Justification::centred, 1); @@ -90,16 +89,9 @@ public: void mouseDown (const MouseEvent&) override { - CallOutBox::launchAsynchronously (new ColourSelectorComp (this, canResetToDefault), - getScreenBounds(), nullptr); - } - - void changeListenerCallback (ChangeBroadcaster* source) override - { - const ColourSelector* const cs = (const ColourSelector*) source; - - if (cs->getCurrentColour() != getColour()) - setColour (cs->getCurrentColour()); + CallOutBox::launchAsynchronously (std::make_unique<ColourSelectorComp> (this, canResetToDefault), + getScreenBounds(), + nullptr); } class ColourSelectorComp : public Component @@ -174,6 +166,14 @@ public: }; private: + void changeListenerCallback (ChangeBroadcaster* source) override + { + const ColourSelector* const cs = (const ColourSelector*) source; + + if (cs->getCurrentColour() != getColour()) + setColour (cs->getCurrentColour()); + } + Colour colour; bool canResetToDefault; }; diff --git a/extras/Projucer/Source/ComponentEditor/Properties/jucer_ComponentBooleanProperty.h b/extras/Projucer/Source/ComponentEditor/Properties/jucer_ComponentBooleanProperty.h index f9e30b39..d8c0ba7d 100644 --- a/extras/Projucer/Source/ComponentEditor/Properties/jucer_ComponentBooleanProperty.h +++ b/extras/Projucer/Source/ComponentEditor/Properties/jucer_ComponentBooleanProperty.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/ComponentEditor/Properties/jucer_ComponentChoiceProperty.h b/extras/Projucer/Source/ComponentEditor/Properties/jucer_ComponentChoiceProperty.h index b1bca27e..88cdbed0 100644 --- a/extras/Projucer/Source/ComponentEditor/Properties/jucer_ComponentChoiceProperty.h +++ b/extras/Projucer/Source/ComponentEditor/Properties/jucer_ComponentChoiceProperty.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/ComponentEditor/Properties/jucer_ComponentColourProperty.h b/extras/Projucer/Source/ComponentEditor/Properties/jucer_ComponentColourProperty.h index bab22a0c..c90fbaaf 100644 --- a/extras/Projucer/Source/ComponentEditor/Properties/jucer_ComponentColourProperty.h +++ b/extras/Projucer/Source/ComponentEditor/Properties/jucer_ComponentColourProperty.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/ComponentEditor/Properties/jucer_ComponentTextProperty.h b/extras/Projucer/Source/ComponentEditor/Properties/jucer_ComponentTextProperty.h index 1163df02..3a0054e2 100644 --- a/extras/Projucer/Source/ComponentEditor/Properties/jucer_ComponentTextProperty.h +++ b/extras/Projucer/Source/ComponentEditor/Properties/jucer_ComponentTextProperty.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/ComponentEditor/Properties/jucer_FilePropertyComponent.h b/extras/Projucer/Source/ComponentEditor/Properties/jucer_FilePropertyComponent.h index d4a76d6a..0ab20d62 100644 --- a/extras/Projucer/Source/ComponentEditor/Properties/jucer_FilePropertyComponent.h +++ b/extras/Projucer/Source/ComponentEditor/Properties/jucer_FilePropertyComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -29,7 +28,7 @@ //============================================================================== class FilePropertyComponent : public PropertyComponent, - public FilenameComponentListener + private FilenameComponentListener { public: FilePropertyComponent (const String& name, @@ -48,17 +47,17 @@ public: virtual void setFile (const File& newFile) = 0; virtual File getFile() const = 0; - void refresh() + void refresh() override { filenameComp.setCurrentFile (getFile(), false); } - void filenameComponentChanged (FilenameComponent*) +private: + void filenameComponentChanged (FilenameComponent*) override { if (getFile() != filenameComp.getCurrentFile()) setFile (filenameComp.getCurrentFile()); } -private: FilenameComponent filenameComp; }; diff --git a/extras/Projucer/Source/ComponentEditor/Properties/jucer_FontPropertyComponent.h b/extras/Projucer/Source/ComponentEditor/Properties/jucer_FontPropertyComponent.h index 503d9d03..f967698d 100644 --- a/extras/Projucer/Source/ComponentEditor/Properties/jucer_FontPropertyComponent.h +++ b/extras/Projucer/Source/ComponentEditor/Properties/jucer_FontPropertyComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -100,33 +99,33 @@ public: static String getTypefaceNameCode (const String& typefaceName) { if (typefaceName == getDefaultFont()) return {}; - if (typefaceName == getDefaultSans()) return "Font::getDefaultSansSerifFontName(), "; - if (typefaceName == getDefaultSerif()) return "Font::getDefaultSerifFontName(), "; - if (typefaceName == getDefaultMono()) return "Font::getDefaultMonospacedFontName(), "; + if (typefaceName == getDefaultSans()) return "juce::Font::getDefaultSansSerifFontName(), "; + if (typefaceName == getDefaultSerif()) return "juce::Font::getDefaultSerifFontName(), "; + if (typefaceName == getDefaultMono()) return "juce::Font::getDefaultMonospacedFontName(), "; return "\"" + typefaceName + "\", "; } static String getFontStyleCode (const Font& font) { - if (font.isBold() && font.isItalic()) return "Font::bold | Font::italic"; - if (font.isBold()) return "Font::bold"; - if (font.isItalic()) return "Font::italic"; + if (font.isBold() && font.isItalic()) return "juce::Font::bold | juce::Font::italic"; + if (font.isBold()) return "juce::Font::bold"; + if (font.isItalic()) return "juce::Font::italic"; - return "Font::plain"; + return "juce::Font::plain"; } static String getCompleteFontCode (const Font& font, const String& typefaceName) { String s; - s << "Font (" + s << "juce::Font (" << getTypefaceNameCode (typefaceName) << CodeHelpers::floatLiteral (font.getHeight(), 2) << ", "; if (font.getAvailableStyles().contains(font.getTypefaceStyle())) - s << "Font::plain).withTypefaceStyle (" + s << "juce::Font::plain).withTypefaceStyle (" << CodeHelpers::stringLiteral (font.getTypefaceStyle()) << ")"; else diff --git a/extras/Projucer/Source/ComponentEditor/Properties/jucer_JustificationProperty.h b/extras/Projucer/Source/ComponentEditor/Properties/jucer_JustificationProperty.h index f90f1cb0..7ae577a6 100644 --- a/extras/Projucer/Source/ComponentEditor/Properties/jucer_JustificationProperty.h +++ b/extras/Projucer/Source/ComponentEditor/Properties/jucer_JustificationProperty.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/ComponentEditor/Properties/jucer_PositionPropertyBase.h b/extras/Projucer/Source/ComponentEditor/Properties/jucer_PositionPropertyBase.h index f497314a..9a0f482e 100644 --- a/extras/Projucer/Source/ComponentEditor/Properties/jucer_PositionPropertyBase.h +++ b/extras/Projucer/Source/ComponentEditor/Properties/jucer_PositionPropertyBase.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/ComponentEditor/UI/jucer_ComponentLayoutEditor.cpp b/extras/Projucer/Source/ComponentEditor/UI/jucer_ComponentLayoutEditor.cpp index 4b079ecd..78702c86 100644 --- a/extras/Projucer/Source/ComponentEditor/UI/jucer_ComponentLayoutEditor.cpp +++ b/extras/Projucer/Source/ComponentEditor/UI/jucer_ComponentLayoutEditor.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/ComponentEditor/UI/jucer_ComponentLayoutEditor.h b/extras/Projucer/Source/ComponentEditor/UI/jucer_ComponentLayoutEditor.h index 8c4c8e9e..63e86a62 100644 --- a/extras/Projucer/Source/ComponentEditor/UI/jucer_ComponentLayoutEditor.h +++ b/extras/Projucer/Source/ComponentEditor/UI/jucer_ComponentLayoutEditor.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -32,10 +31,10 @@ //============================================================================== class ComponentLayoutEditor : public Component, - public ChangeListener, public FileDragAndDropTarget, public DragAndDropTarget, - public LassoSource<Component*> + public LassoSource<Component*>, + private ChangeListener { public: //============================================================================== @@ -46,7 +45,6 @@ public: void paint (Graphics&) override; void resized() override; void visibilityChanged() override; - void changeListenerCallback (ChangeBroadcaster*) override; void mouseDown (const MouseEvent&) override; void mouseDrag (const MouseEvent&) override; @@ -76,6 +74,8 @@ public: Image createComponentLayerSnapshot() const; private: + void changeListenerCallback (ChangeBroadcaster*) override; + JucerDocument& document; ComponentLayout& layout; Component* subCompHolder; diff --git a/extras/Projucer/Source/ComponentEditor/UI/jucer_ComponentLayoutPanel.h b/extras/Projucer/Source/ComponentEditor/UI/jucer_ComponentLayoutPanel.h index bb6fdb4f..34576ba2 100644 --- a/extras/Projucer/Source/ComponentEditor/UI/jucer_ComponentLayoutPanel.h +++ b/extras/Projucer/Source/ComponentEditor/UI/jucer_ComponentLayoutPanel.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -66,7 +65,7 @@ public: private: class LayoutPropsPanel : public Component, - public ChangeListener + private ChangeListener { public: LayoutPropsPanel (JucerDocument& doc, ComponentLayout& l) @@ -76,22 +75,17 @@ private: addAndMakeVisible (propsPanel); } - ~LayoutPropsPanel() + ~LayoutPropsPanel() override { layout.getSelectedSet().removeChangeListener (this); clear(); } - void resized() + void resized() override { propsPanel.setBounds (4, 4, getWidth() - 8, getHeight() - 8); } - void changeListenerCallback (ChangeBroadcaster*) - { - updateList(); - } - void clear() { propsPanel.clear(); @@ -112,6 +106,11 @@ private: } private: + void changeListenerCallback (ChangeBroadcaster*) override + { + updateList(); + } + JucerDocument& document; ComponentLayout& layout; PropertyPanel propsPanel; diff --git a/extras/Projucer/Source/ComponentEditor/UI/jucer_ComponentOverlayComponent.cpp b/extras/Projucer/Source/ComponentEditor/UI/jucer_ComponentOverlayComponent.cpp index 3ced8183..94749122 100644 --- a/extras/Projucer/Source/ComponentEditor/UI/jucer_ComponentOverlayComponent.cpp +++ b/extras/Projucer/Source/ComponentEditor/UI/jucer_ComponentOverlayComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/ComponentEditor/UI/jucer_ComponentOverlayComponent.h b/extras/Projucer/Source/ComponentEditor/UI/jucer_ComponentOverlayComponent.h index 1a815a62..038f1959 100644 --- a/extras/Projucer/Source/ComponentEditor/UI/jucer_ComponentOverlayComponent.h +++ b/extras/Projucer/Source/ComponentEditor/UI/jucer_ComponentOverlayComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -30,9 +29,9 @@ //============================================================================== class ComponentOverlayComponent : public Component, - public ComponentListener, - public ChangeListener, - public ComponentBoundsConstrainer + private ComponentBoundsConstrainer, + private ComponentListener, + private ChangeListener { public: //============================================================================== @@ -52,15 +51,16 @@ public: void mouseDrag (const MouseEvent&) override; void mouseUp (const MouseEvent&) override; - void componentMovedOrResized (Component&, bool wasMoved, bool wasResized) override; + void updateBoundsToMatchTarget(); - void changeListenerCallback (ChangeBroadcaster*) override; + //============================================================================== + Component::SafePointer<Component> target; + const int borderThickness; +private: void resizeStart() override; void resizeEnd() override; - void updateBoundsToMatchTarget(); - void checkBounds (Rectangle<int>& bounds, const Rectangle<int>& previousBounds, const Rectangle<int>& limits, @@ -71,11 +71,10 @@ public: void applyBoundsToComponent (Component&, Rectangle<int>) override; - //============================================================================== - Component::SafePointer<Component> target; - const int borderThickness; + void componentMovedOrResized (Component&, bool wasMoved, bool wasResized) override; + + void changeListenerCallback (ChangeBroadcaster*) override; -private: std::unique_ptr<ResizableBorderComponent> border; ComponentLayout& layout; diff --git a/extras/Projucer/Source/ComponentEditor/UI/jucer_EditingPanelBase.cpp b/extras/Projucer/Source/ComponentEditor/UI/jucer_EditingPanelBase.cpp index 8765e20d..03486f56 100644 --- a/extras/Projucer/Source/ComponentEditor/UI/jucer_EditingPanelBase.cpp +++ b/extras/Projucer/Source/ComponentEditor/UI/jucer_EditingPanelBase.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -32,7 +31,7 @@ class EditingPanelBase::MagnifierComponent : public Component { public: - MagnifierComponent (Component* c) : content (c) + explicit MagnifierComponent (Component* c) : content (c) { addAndMakeVisible (content.get()); childBoundsChanged (content.get()); @@ -61,7 +60,7 @@ private: class ZoomingViewport : public Viewport { public: - ZoomingViewport (EditingPanelBase* p) : panel (p) + explicit ZoomingViewport (EditingPanelBase* p) : panel (p) { } diff --git a/extras/Projucer/Source/ComponentEditor/UI/jucer_EditingPanelBase.h b/extras/Projucer/Source/ComponentEditor/UI/jucer_EditingPanelBase.h index 2e80eb85..01c47343 100644 --- a/extras/Projucer/Source/ComponentEditor/UI/jucer_EditingPanelBase.h +++ b/extras/Projucer/Source/ComponentEditor/UI/jucer_EditingPanelBase.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/ComponentEditor/UI/jucer_JucerCommandIDs.h b/extras/Projucer/Source/ComponentEditor/UI/jucer_JucerCommandIDs.h index 558e4c77..79e5cd49 100644 --- a/extras/Projucer/Source/ComponentEditor/UI/jucer_JucerCommandIDs.h +++ b/extras/Projucer/Source/ComponentEditor/UI/jucer_JucerCommandIDs.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/ComponentEditor/UI/jucer_JucerDocumentEditor.cpp b/extras/Projucer/Source/ComponentEditor/UI/jucer_JucerDocumentEditor.cpp index de2c5fa0..7faa74bc 100644 --- a/extras/Projucer/Source/ComponentEditor/UI/jucer_JucerDocumentEditor.cpp +++ b/extras/Projucer/Source/ComponentEditor/UI/jucer_JucerDocumentEditor.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -40,7 +39,7 @@ //============================================================================== class ExtraMethodsList : public PropertyComponent, public ListBoxModel, - public ChangeListener + private ChangeListener { public: ExtraMethodsList (JucerDocument& doc) @@ -79,7 +78,7 @@ public: g.setColour (findColour (defaultTextColourId)); } - g.setFont (height * 0.6f); + g.setFont ((float) height * 0.6f); g.drawText (returnValues [row] + " " + baseClasses [row] + "::" + methods [row], 30, 0, width - 32, height, Justification::centredLeft, true); @@ -120,12 +119,12 @@ public: listBox->repaint(); } +private: void changeListenerCallback (ChangeBroadcaster*) override { refresh(); } -private: JucerDocument& document; std::unique_ptr<ListBox> listBox; @@ -138,7 +137,7 @@ class ClassPropertiesPanel : public Component, private ChangeListener { public: - ClassPropertiesPanel (JucerDocument& doc) + explicit ClassPropertiesPanel (JucerDocument& doc) : document (doc) { addAndMakeVisible (panel1); @@ -196,7 +195,7 @@ private: class ComponentClassNameProperty : public ComponentTextProperty <Component> { public: - ComponentClassNameProperty (JucerDocument& doc) + explicit ComponentClassNameProperty (JucerDocument& doc) : ComponentTextProperty<Component> ("Class name", 128, false, nullptr, doc) {} @@ -208,7 +207,7 @@ private: class ComponentCompNameProperty : public ComponentTextProperty <Component> { public: - ComponentCompNameProperty (JucerDocument& doc) + explicit ComponentCompNameProperty (JucerDocument& doc) : ComponentTextProperty<Component> ("Component name", 200, false, nullptr, doc) {} @@ -220,7 +219,7 @@ private: class ComponentParentClassesProperty : public ComponentTextProperty <Component> { public: - ComponentParentClassesProperty (JucerDocument& doc) + explicit ComponentParentClassesProperty (JucerDocument& doc) : ComponentTextProperty<Component> ("Parent classes", 512, false, nullptr, doc) {} @@ -232,7 +231,7 @@ private: class ComponentConstructorParamsProperty : public ComponentTextProperty <Component> { public: - ComponentConstructorParamsProperty (JucerDocument& doc) + explicit ComponentConstructorParamsProperty (JucerDocument& doc) : ComponentTextProperty<Component> ("Constructor params", 2048, false, nullptr, doc) {} @@ -244,7 +243,7 @@ private: class ComponentInitialisersProperty : public ComponentTextProperty <Component> { public: - ComponentInitialisersProperty (JucerDocument& doc) + explicit ComponentInitialisersProperty (JucerDocument& doc) : ComponentTextProperty <Component> ("Member initialisers", 16384, true, nullptr, doc) { preferredHeight = 24 * 3; @@ -288,7 +287,7 @@ private: class FixedSizeProperty : public ComponentChoiceProperty <Component> { public: - FixedSizeProperty (JucerDocument& doc) + explicit FixedSizeProperty (JucerDocument& doc) : ComponentChoiceProperty<Component> ("Fixed size", nullptr, doc) { choices.add ("Resize component to fit workspace"); @@ -303,7 +302,7 @@ private: class TemplateFileProperty : public ComponentTextProperty <Component> { public: - TemplateFileProperty (JucerDocument& doc) + explicit TemplateFileProperty (JucerDocument& doc) : ComponentTextProperty<Component> ("Template file", 2048, false, nullptr, doc) {} @@ -355,12 +354,6 @@ JucerDocumentEditor::JucerDocumentEditor (JucerDocument* const doc) refreshPropertiesPanel(); changeListenerCallback (nullptr); - - if (auto* project = document->getCppDocument().getProject()) - { - if (project->shouldSendGUIBuilderAnalyticsEvent()) - Analytics::getInstance()->logEvent ("GUI Builder", {}, ProjucerAnalyticsEvent::projectEvent); - } } } @@ -1044,7 +1037,7 @@ bool JucerDocumentEditor::perform (const InvocationInfo& info) else if (info.commandID == JucerCommandIDs::compOverlay100) amount = 100; - document->setComponentOverlayOpacity (amount * 0.01f); + document->setComponentOverlayOpacity ((float) amount * 0.01f); } break; @@ -1224,11 +1217,15 @@ Image JucerDocumentEditor::createComponentLayerSnapshot() const const int gridSnapMenuItemBase = 0x8723620; const int snapSizes[] = { 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 24, 32 }; -void createGUIEditorMenu (PopupMenu&); -void createGUIEditorMenu (PopupMenu& menu) +PopupMenu createGUIEditorMenu(); +PopupMenu createGUIEditorMenu() { + PopupMenu menu; auto* commandManager = &ProjucerApplication::getCommandManager(); + menu.addCommandItem (commandManager, CommandIDs::addNewGUIFile); + menu.addSeparator(); + menu.addCommandItem (commandManager, JucerCommandIDs::editCompLayout); menu.addCommandItem (commandManager, JucerCommandIDs::editCompGraphics); menu.addSeparator(); @@ -1297,6 +1294,8 @@ void createGUIEditorMenu (PopupMenu& menu) menu.addSubMenu ("Component Overlay", overlays, holder != nullptr); } + + return menu; } void handleGUIEditorMenuCommand (int); diff --git a/extras/Projucer/Source/ComponentEditor/UI/jucer_JucerDocumentEditor.h b/extras/Projucer/Source/ComponentEditor/UI/jucer_JucerDocumentEditor.h index de5ece63..d0efe69c 100644 --- a/extras/Projucer/Source/ComponentEditor/UI/jucer_JucerDocumentEditor.h +++ b/extras/Projucer/Source/ComponentEditor/UI/jucer_JucerDocumentEditor.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -34,7 +33,7 @@ //============================================================================== class JucerDocumentEditor : public Component, public ApplicationCommandTarget, - public ChangeListener + private ChangeListener { public: //============================================================================== @@ -57,7 +56,6 @@ public: //============================================================================== void paint (Graphics& g) override; void resized() override; - void changeListenerCallback (ChangeBroadcaster*) override; bool keyPressed (const KeyPress&) override; //============================================================================== @@ -69,6 +67,8 @@ public: static JucerDocumentEditor* getActiveDocumentHolder(); private: + void changeListenerCallback (ChangeBroadcaster*) override; + std::unique_ptr<JucerDocument> document; ComponentLayoutPanel* compLayoutPanel = nullptr; diff --git a/extras/Projucer/Source/ComponentEditor/UI/jucer_PaintRoutineEditor.cpp b/extras/Projucer/Source/ComponentEditor/UI/jucer_PaintRoutineEditor.cpp index f7550591..43b4b403 100644 --- a/extras/Projucer/Source/ComponentEditor/UI/jucer_PaintRoutineEditor.cpp +++ b/extras/Projucer/Source/ComponentEditor/UI/jucer_PaintRoutineEditor.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/ComponentEditor/UI/jucer_PaintRoutineEditor.h b/extras/Projucer/Source/ComponentEditor/UI/jucer_PaintRoutineEditor.h index ae3c6d77..d437e187 100644 --- a/extras/Projucer/Source/ComponentEditor/UI/jucer_PaintRoutineEditor.h +++ b/extras/Projucer/Source/ComponentEditor/UI/jucer_PaintRoutineEditor.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -33,9 +32,9 @@ class JucerDocumentEditor; //============================================================================== class PaintRoutineEditor : public Component, - public ChangeListener, public LassoSource <PaintElement*>, - public FileDragAndDropTarget + public FileDragAndDropTarget, + private ChangeListener { public: //============================================================================== diff --git a/extras/Projucer/Source/ComponentEditor/UI/jucer_PaintRoutinePanel.cpp b/extras/Projucer/Source/ComponentEditor/UI/jucer_PaintRoutinePanel.cpp index d9796b75..8488c927 100644 --- a/extras/Projucer/Source/ComponentEditor/UI/jucer_PaintRoutinePanel.cpp +++ b/extras/Projucer/Source/ComponentEditor/UI/jucer_PaintRoutinePanel.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -69,7 +68,7 @@ protected: //============================================================================== class GraphicsPropsPanel : public Component, - public ChangeListener + private ChangeListener { public: GraphicsPropsPanel (PaintRoutine& paintRoutine_, @@ -83,7 +82,7 @@ public: addAndMakeVisible (propsPanel = new PropertyPanel()); } - ~GraphicsPropsPanel() + ~GraphicsPropsPanel() override { paintRoutine.getSelectedPoints().removeChangeListener (this); paintRoutine.getSelectedElements().removeChangeListener (this); @@ -92,16 +91,11 @@ public: deleteAllChildren(); } - void resized() + void resized() override { propsPanel->setBounds (4, 4, getWidth() - 8, getHeight() - 8); } - void changeListenerCallback (ChangeBroadcaster*) - { - updateList(); - } - void clear() { propsPanel->clear(); @@ -153,6 +147,11 @@ public: } private: + void changeListenerCallback (ChangeBroadcaster*) override + { + updateList(); + } + PaintRoutine& paintRoutine; JucerDocument* document; diff --git a/extras/Projucer/Source/ComponentEditor/UI/jucer_PaintRoutinePanel.h b/extras/Projucer/Source/ComponentEditor/UI/jucer_PaintRoutinePanel.h index 88339b8e..9d2abd7b 100644 --- a/extras/Projucer/Source/ComponentEditor/UI/jucer_PaintRoutinePanel.h +++ b/extras/Projucer/Source/ComponentEditor/UI/jucer_PaintRoutinePanel.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/ComponentEditor/UI/jucer_RelativePositionedRectangle.h b/extras/Projucer/Source/ComponentEditor/UI/jucer_RelativePositionedRectangle.h index 545d4327..176d9467 100644 --- a/extras/Projucer/Source/ComponentEditor/UI/jucer_RelativePositionedRectangle.h +++ b/extras/Projucer/Source/ComponentEditor/UI/jucer_RelativePositionedRectangle.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -75,8 +74,8 @@ public: */ PositionedRectangle() noexcept : x (0.0), y (0.0), w (0.0), h (0.0), - xMode (anchorAtLeftOrTop | absoluteFromParentTopLeft), - yMode (anchorAtLeftOrTop | absoluteFromParentTopLeft), + xMode ((int) anchorAtLeftOrTop | (int) absoluteFromParentTopLeft), + yMode ((int) anchorAtLeftOrTop | (int) absoluteFromParentTopLeft), wMode (absoluteSize), hMode (absoluteSize) { } @@ -284,23 +283,23 @@ public: const SizeMode widthMode, const SizeMode heightMode, const Rectangle<int>& target) noexcept { - if (xMode != (xAnchor | xMode_) || wMode != widthMode) + if (xMode != ((int) xAnchor | (int) xMode_) || wMode != widthMode) { double tx, tw; applyPosAndSize (tx, tw, x, w, xMode, wMode, target.getX(), target.getWidth()); - xMode = (uint8) (xAnchor | xMode_); + xMode = (uint8) ((int) xAnchor | (int) xMode_); wMode = (uint8) widthMode; updatePosAndSize (x, w, tx, tw, xMode, wMode, target.getX(), target.getWidth()); } - if (yMode != (yAnchor | yMode_) || hMode != heightMode) + if (yMode != ((int) yAnchor | (int) yMode_) || hMode != heightMode) { double ty, th; applyPosAndSize (ty, th, y, h, yMode, hMode, target.getY(), target.getHeight()); - yMode = (uint8) (yAnchor | yMode_); + yMode = (uint8) ((int) yAnchor | (int) yMode_); hMode = (uint8) heightMode; updatePosAndSize (y, h, ty, th, yMode, hMode, target.getY(), target.getHeight()); @@ -740,7 +739,7 @@ struct RelativePositionedRectangle { double x, y, w, h; getRectangleDouble (x, y, w, h, parentArea, layout); - return Point<float> ((float) x, (float) y); + return { (float) x, (float) y }; } void getXY (double& x, double& y, diff --git a/extras/Projucer/Source/ComponentEditor/UI/jucer_ResourceEditorPanel.cpp b/extras/Projucer/Source/ComponentEditor/UI/jucer_ResourceEditorPanel.cpp index 11bf9cb7..6c5f8ffa 100644 --- a/extras/Projucer/Source/ComponentEditor/UI/jucer_ResourceEditorPanel.cpp +++ b/extras/Projucer/Source/ComponentEditor/UI/jucer_ResourceEditorPanel.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -31,7 +30,7 @@ class ResourceListButton : public Component { public: - ResourceListButton (JucerDocument& doc) + explicit ResourceListButton (JucerDocument& doc) : document (doc), reloadButton ("Reload"), row (0) { setInterceptsMouseClicks (false, true); diff --git a/extras/Projucer/Source/ComponentEditor/UI/jucer_ResourceEditorPanel.h b/extras/Projucer/Source/ComponentEditor/UI/jucer_ResourceEditorPanel.h index cd423df6..600ca661 100644 --- a/extras/Projucer/Source/ComponentEditor/UI/jucer_ResourceEditorPanel.h +++ b/extras/Projucer/Source/ComponentEditor/UI/jucer_ResourceEditorPanel.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/ComponentEditor/UI/jucer_SnapGridPainter.h b/extras/Projucer/Source/ComponentEditor/UI/jucer_SnapGridPainter.h index cc82aca1..01209560 100644 --- a/extras/Projucer/Source/ComponentEditor/UI/jucer_SnapGridPainter.h +++ b/extras/Projucer/Source/ComponentEditor/UI/jucer_SnapGridPainter.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/ComponentEditor/UI/jucer_TestComponent.cpp b/extras/Projucer/Source/ComponentEditor/UI/jucer_TestComponent.cpp index e47b8489..30517543 100644 --- a/extras/Projucer/Source/ComponentEditor/UI/jucer_TestComponent.cpp +++ b/extras/Projucer/Source/ComponentEditor/UI/jucer_TestComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/ComponentEditor/UI/jucer_TestComponent.h b/extras/Projucer/Source/ComponentEditor/UI/jucer_TestComponent.h index ebc7ca42..a23f36ec 100644 --- a/extras/Projucer/Source/ComponentEditor/UI/jucer_TestComponent.h +++ b/extras/Projucer/Source/ComponentEditor/UI/jucer_TestComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/ComponentEditor/jucer_BinaryResources.cpp b/extras/Projucer/Source/ComponentEditor/jucer_BinaryResources.cpp index f0439f06..6a97a4a9 100644 --- a/extras/Projucer/Source/ComponentEditor/jucer_BinaryResources.cpp +++ b/extras/Projucer/Source/ComponentEditor/jucer_BinaryResources.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -162,7 +161,7 @@ String BinaryResources::browseForResource (const String& title, String BinaryResources::findUniqueName (const String& rootName) const { - auto nameRoot = CodeHelpers::makeValidIdentifier (rootName, true, true, false); + auto nameRoot = build_tools::makeValidIdentifier (rootName, true, true, false); auto name = nameRoot; auto names = getResourceNames(); @@ -249,7 +248,7 @@ void BinaryResources::loadFromCpp (const File& cppFileLocation, const String& cp if (c >= '0' && c <= '9') { - n = n * 10 + (c - '0'); + n = n * 10 + (int) (c - '0'); } else if (c == ',') { diff --git a/extras/Projucer/Source/ComponentEditor/jucer_BinaryResources.h b/extras/Projucer/Source/ComponentEditor/jucer_BinaryResources.h index aa38c715..5dce1278 100644 --- a/extras/Projucer/Source/ComponentEditor/jucer_BinaryResources.h +++ b/extras/Projucer/Source/ComponentEditor/jucer_BinaryResources.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/ComponentEditor/jucer_ComponentLayout.cpp b/extras/Projucer/Source/ComponentEditor/jucer_ComponentLayout.cpp index 1ced1baf..bc23a1df 100644 --- a/extras/Projucer/Source/ComponentEditor/jucer_ComponentLayout.cpp +++ b/extras/Projucer/Source/ComponentEditor/jucer_ComponentLayout.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -419,7 +418,7 @@ Component* ComponentLayout::addNewComponent (ComponentTypeHandler* const type, i std::unique_ptr<XmlElement> xml (type->createXmlFor (c.get(), this)); c.reset (addComponentFromXml (*xml, true)); - String memberName (CodeHelpers::makeValidIdentifier (type->getClassName (c.get()), true, true, false)); + String memberName (build_tools::makeValidIdentifier (type->getClassName (c.get()), true, true, false)); setComponentMemberVariableName (c.get(), memberName); selected.selectOnly (c.get()); @@ -860,7 +859,7 @@ String ComponentLayout::getComponentMemberVariableName (Component* comp) const String name (comp->getProperties() ["memberName"].toString()); if (name.isEmpty()) - name = getUnusedMemberName (CodeHelpers::makeValidIdentifier (comp->getName(), true, true, false), comp); + name = getUnusedMemberName (build_tools::makeValidIdentifier (comp->getName(), true, true, false), comp); return name; } @@ -872,7 +871,7 @@ void ComponentLayout::setComponentMemberVariableName (Component* comp, const Str comp->getProperties().set ("memberName", String()); - const String n (getUnusedMemberName (CodeHelpers::makeValidIdentifier (newName, false, true, false), comp)); + const String n (getUnusedMemberName (build_tools::makeValidIdentifier (newName, false, true, false), comp)); comp->getProperties().set ("memberName", n); if (n != oldName) @@ -923,7 +922,7 @@ String ComponentLayout::getComponentVirtualClassName (Component* comp) const void ComponentLayout::setComponentVirtualClassName (Component* comp, const String& newName) { jassert (comp != nullptr); - const String name (CodeHelpers::makeValidIdentifier (newName, false, false, true)); + const String name (build_tools::makeValidIdentifier (newName, false, false, true)); if (name != getComponentVirtualClassName (comp)) { @@ -976,7 +975,7 @@ void positionToCode (const RelativePositionedRectangle& position, if (position.rect.getWidthMode() == PositionedRectangle::proportionalSize) { if (wrw.isNotEmpty()) - w << "roundToInt (" << bracketIfNeeded (wrw) << " * " << CodeHelpers::floatLiteral (position.rect.getWidth(), 4) << ")"; + w << "juce::roundToInt (" << bracketIfNeeded (wrw) << " * " << CodeHelpers::floatLiteral (position.rect.getWidth(), 4) << ")"; else w << "proportionOfWidth (" << CodeHelpers::floatLiteral (position.rect.getWidth(), 4) << ")"; } @@ -999,7 +998,7 @@ void positionToCode (const RelativePositionedRectangle& position, if (position.rect.getHeightMode() == PositionedRectangle::proportionalSize) { if (hrh.isNotEmpty()) - h << "roundToInt (" << bracketIfNeeded (hrh) << " * " << CodeHelpers::floatLiteral (position.rect.getHeight(), 4) << ")"; + h << "juce::roundToInt (" << bracketIfNeeded (hrh) << " * " << CodeHelpers::floatLiteral (position.rect.getHeight(), 4) << ")"; else h << "proportionOfHeight (" << CodeHelpers::floatLiteral (position.rect.getHeight(), 4) << ")"; } @@ -1022,7 +1021,7 @@ void positionToCode (const RelativePositionedRectangle& position, if (position.rect.getPositionModeX() == PositionedRectangle::proportionOfParentSize) { if (xrx.isNotEmpty() && xrw.isNotEmpty()) - x << bracketIfNeeded (xrx) << " + roundToInt (" << bracketIfNeeded (xrw) << " * " << CodeHelpers::floatLiteral (position.rect.getX(), 4) << ")"; + x << bracketIfNeeded (xrx) << " + juce::roundToInt (" << bracketIfNeeded (xrw) << " * " << CodeHelpers::floatLiteral (position.rect.getX(), 4) << ")"; else x << "proportionOfWidth (" << CodeHelpers::floatLiteral (position.rect.getX(), 4) << ")"; } @@ -1068,7 +1067,7 @@ void positionToCode (const RelativePositionedRectangle& position, if (position.rect.getPositionModeY() == PositionedRectangle::proportionOfParentSize) { if (yry.isNotEmpty() && yrh.isNotEmpty()) - y << bracketIfNeeded (yry) << " + roundToInt (" << bracketIfNeeded (yrh) << " * " << CodeHelpers::floatLiteral (position.rect.getY(), 4) << ")"; + y << bracketIfNeeded (yry) << " + juce::roundToInt (" << bracketIfNeeded (yrh) << " * " << CodeHelpers::floatLiteral (position.rect.getY(), 4) << ")"; else y << "proportionOfHeight (" << CodeHelpers::floatLiteral (position.rect.getY(), 4) << ")"; } diff --git a/extras/Projucer/Source/ComponentEditor/jucer_ComponentLayout.h b/extras/Projucer/Source/ComponentEditor/jucer_ComponentLayout.h index 5c14a3f8..bcce3fc1 100644 --- a/extras/Projucer/Source/ComponentEditor/jucer_ComponentLayout.h +++ b/extras/Projucer/Source/ComponentEditor/jucer_ComponentLayout.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/ComponentEditor/jucer_GeneratedCode.cpp b/extras/Projucer/Source/ComponentEditor/jucer_GeneratedCode.cpp index a63a13fe..5c4d23b6 100644 --- a/extras/Projucer/Source/ComponentEditor/jucer_GeneratedCode.cpp +++ b/extras/Projucer/Source/ComponentEditor/jucer_GeneratedCode.cpp @@ -1,349 +1,348 @@ -/* - ============================================================================== - - 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. - - ============================================================================== -*/ - -#include "../Application/jucer_Headers.h" -#include "jucer_GeneratedCode.h" -#include "jucer_JucerDocument.h" - -//============================================================================== -GeneratedCode::GeneratedCode (const JucerDocument* const doc) - : document (doc), suffix (0) -{ -} - -GeneratedCode::~GeneratedCode() -{ -} - -int GeneratedCode::getUniqueSuffix() -{ - return ++suffix; -} - -//============================================================================== -String& GeneratedCode::getCallbackCode (const String& requiredParentClass, - const String& returnType, - const String& prototype, - const bool hasPrePostUserSections) -{ - String parentClass (requiredParentClass); - if (parentClass.isNotEmpty() - && ! (parentClass.startsWith ("public ") - || parentClass.startsWith ("private ") - || parentClass.startsWith ("protected "))) - { - parentClass = "public " + parentClass; - } - - for (int i = callbacks.size(); --i >= 0;) - { - CallbackMethod* const cm = callbacks.getUnchecked(i); - - if (cm->requiredParentClass == parentClass - && cm->returnType == returnType - && cm->prototype == prototype) - return cm->content; - } - - CallbackMethod* const cm = new CallbackMethod(); - callbacks.add (cm); - - cm->requiredParentClass = parentClass; - cm->returnType = returnType; - cm->prototype = prototype; - cm->hasPrePostUserSections = hasPrePostUserSections; - return cm->content; -} - -void GeneratedCode::removeCallback (const String& returnType, const String& prototype) -{ - for (int i = callbacks.size(); --i >= 0;) - { - CallbackMethod* const cm = callbacks.getUnchecked(i); - - if (cm->returnType == returnType && cm->prototype == prototype) - callbacks.remove (i); - } -} - -void GeneratedCode::addImageResourceLoader (const String& imageMemberName, const String& resourceName) -{ - privateMemberDeclarations - << "Image " << imageMemberName << ";\n"; - - if (resourceName.isNotEmpty()) - constructorCode << imageMemberName << " = ImageCache::getFromMemory (" - << resourceName << ", " << resourceName << "Size);\n"; -} - -StringArray GeneratedCode::getExtraParentClasses() const -{ - StringArray s; - - for (int i = 0; i < callbacks.size(); ++i) - { - CallbackMethod* const cm = callbacks.getUnchecked(i); - s.add (cm->requiredParentClass); - } - - return s; -} - -String GeneratedCode::getCallbackDeclarations() const -{ - String s; - - for (int i = 0; i < callbacks.size(); ++i) - { - CallbackMethod* const cm = callbacks.getUnchecked(i); - - s << cm->returnType << " " << cm->prototype << " override;\n"; - } - - return s; -} - -String GeneratedCode::getCallbackDefinitions() const -{ - String s; - - for (int i = 0; i < callbacks.size(); ++i) - { - CallbackMethod* const cm = callbacks.getUnchecked(i); - - const String userCodeBlockName ("User" - + CodeHelpers::makeValidIdentifier (cm->prototype.upToFirstOccurrenceOf ("(", false, false), - true, true, false).trim()); - - if (userCodeBlockName.isNotEmpty() && cm->hasPrePostUserSections) - { - s << cm->returnType << " " << className << "::" << cm->prototype - << "\n{\n //[" << userCodeBlockName << "_Pre]\n //[/" << userCodeBlockName - << "_Pre]\n\n " - << CodeHelpers::indent (cm->content.trim(), 4, false) - << "\n\n //[" << userCodeBlockName << "_Post]\n //[/" << userCodeBlockName - << "_Post]\n}\n\n"; - } - else - { - s << cm->returnType << " " << className << "::" << cm->prototype - << "\n{\n " - << CodeHelpers::indent (cm->content.trim(), 4, false) - << "\n}\n\n"; - } - } - - return s; -} - -//============================================================================== -String GeneratedCode::getClassDeclaration() const -{ - StringArray parentClassLines; - parentClassLines.addTokens (parentClasses, ",", StringRef()); - parentClassLines.addArray (getExtraParentClasses()); - - parentClassLines = getCleanedStringArray (parentClassLines); - - if (parentClassLines.contains ("public Button", false)) - parentClassLines.removeString ("public Component", false); - - String r ("class "); - r << className << " : "; - - r += parentClassLines.joinIntoString (",\n" + String::repeatedString (" ", r.length())); - - return r; -} - -String GeneratedCode::getInitialiserList() const -{ - StringArray inits (initialisers); - - if (parentClassInitialiser.isNotEmpty()) - inits.insert (0, parentClassInitialiser); - - inits = getCleanedStringArray (inits); - - String s; - - if (inits.size() == 0) - return s; - - s << " : "; - - for (int i = 0; i < inits.size(); ++i) - { - String init (inits[i]); - - while (init.endsWithChar (',')) - init = init.dropLastCharacters (1); - - s << init; - - if (i < inits.size() - 1) - s << ",\n "; - else - s << "\n"; - } - - return s; -} - -static String getIncludeFileCode (const Array<File>& files, const File& targetFile) -{ - String s; - - for (int i = 0; i < files.size(); ++i) - s << CodeHelpers::createIncludeStatement (files.getReference(i), targetFile) << newLine; - - return s; -} - -bool GeneratedCode::shouldUseTransMacro() const noexcept -{ - return document->shouldUseTransMacro(); -} - -//============================================================================== -static void replaceTemplate (String& text, const String& itemName, const String& value) -{ - for (;;) - { - const int index = text.indexOf ("%%" + itemName + "%%"); - - if (index < 0) - break; - - int indentLevel = 0; - - for (int i = index; --i >= 0;) - { - if (text[i] == '\n') - break; - - ++indentLevel; - } - - text = text.replaceSection (index, itemName.length() + 4, - CodeHelpers::indent (value, indentLevel, false)); - } -} - -//============================================================================== -static bool getUserSection (const StringArray& lines, const String& tag, StringArray& resultLines) -{ - const int start = indexOfLineStartingWith (lines, "//[" + tag + "]", 0); - - if (start < 0) - return false; - - const int end = indexOfLineStartingWith (lines, "//[/" + tag + "]", start + 1); - - for (int i = start + 1; i < end; ++i) - resultLines.add (lines [i]); - - return true; -} - -static void copyAcrossUserSections (String& dest, const String& src) -{ - StringArray srcLines, dstLines; - srcLines.addLines (src); - dstLines.addLines (dest); - - for (int i = 0; i < dstLines.size(); ++i) - { - if (dstLines[i].trimStart().startsWith ("//[")) - { - String tag (dstLines[i].trimStart().substring (3)); - tag = tag.upToFirstOccurrenceOf ("]", false, false); - - jassert (! tag.startsWithChar ('/')); - - if (! tag.startsWithChar ('/')) - { - const int endLine = indexOfLineStartingWith (dstLines, - "//[/" + tag + "]", - i + 1); - - if (endLine > i) - { - StringArray sourceLines; - - if (tag != "UserPaintCustomArguments" && getUserSection (srcLines, tag, sourceLines)) - { - for (int j = endLine - i; --j > 0;) - dstLines.remove (i + 1); - - for (int j = 0; j < sourceLines.size(); ++j) - dstLines.insert (++i, sourceLines [j].trimEnd()); - - ++i; - } - else - { - i = endLine; - } - } - } - } - - dstLines.set (i, dstLines[i].trimEnd()); - } - - dest = dstLines.joinIntoString ("\n") + "\n"; -} - -//============================================================================== -void GeneratedCode::applyToCode (String& code, const File& targetFile, const String& oldFileWithUserData) const -{ - replaceTemplate (code, "version", JUCEApplicationBase::getInstance()->getApplicationVersion()); - replaceTemplate (code, "creationTime", Time::getCurrentTime().toString (true, true, true)); - - replaceTemplate (code, "class_name", className); - replaceTemplate (code, "constructor_params", constructorParams); - replaceTemplate (code, "initialisers", getInitialiserList()); - - replaceTemplate (code, "class_declaration", getClassDeclaration()); - replaceTemplate (code, "private_member_declarations", privateMemberDeclarations); - replaceTemplate (code, "public_member_declarations", getCallbackDeclarations() + newLine + publicMemberDeclarations); - - replaceTemplate (code, "method_definitions", getCallbackDefinitions()); - - replaceTemplate (code, "include_juce", CodeHelpers::createIncludePathIncludeStatement (Project::getJuceSourceHFilename())); - - replaceTemplate (code, "include_files_h", getIncludeFileCode (includeFilesH, targetFile)); - replaceTemplate (code, "include_files_cpp", getIncludeFileCode (includeFilesCPP, targetFile)); - - replaceTemplate (code, "constructor", constructorCode); - replaceTemplate (code, "destructor", destructorCode); - - replaceTemplate (code, "metadata", jucerMetadata); - replaceTemplate (code, "static_member_definitions", staticMemberDefinitions); - - copyAcrossUserSections (code, oldFileWithUserData); -} +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +#include "../Application/jucer_Headers.h" +#include "jucer_GeneratedCode.h" +#include "jucer_JucerDocument.h" + +//============================================================================== +GeneratedCode::GeneratedCode (const JucerDocument* const doc) + : document (doc), suffix (0) +{ +} + +GeneratedCode::~GeneratedCode() +{ +} + +int GeneratedCode::getUniqueSuffix() +{ + return ++suffix; +} + +//============================================================================== +String& GeneratedCode::getCallbackCode (const String& requiredParentClass, + const String& returnType, + const String& prototype, + const bool hasPrePostUserSections) +{ + String parentClass (requiredParentClass); + if (parentClass.isNotEmpty() + && ! (parentClass.startsWith ("public ") + || parentClass.startsWith ("private ") + || parentClass.startsWith ("protected "))) + { + parentClass = "public " + parentClass; + } + + for (int i = callbacks.size(); --i >= 0;) + { + CallbackMethod* const cm = callbacks.getUnchecked(i); + + if (cm->requiredParentClass == parentClass + && cm->returnType == returnType + && cm->prototype == prototype) + return cm->content; + } + + CallbackMethod* const cm = new CallbackMethod(); + callbacks.add (cm); + + cm->requiredParentClass = parentClass; + cm->returnType = returnType; + cm->prototype = prototype; + cm->hasPrePostUserSections = hasPrePostUserSections; + return cm->content; +} + +void GeneratedCode::removeCallback (const String& returnType, const String& prototype) +{ + for (int i = callbacks.size(); --i >= 0;) + { + CallbackMethod* const cm = callbacks.getUnchecked(i); + + if (cm->returnType == returnType && cm->prototype == prototype) + callbacks.remove (i); + } +} + +void GeneratedCode::addImageResourceLoader (const String& imageMemberName, const String& resourceName) +{ + privateMemberDeclarations + << "juce::Image " << imageMemberName << ";\n"; + + if (resourceName.isNotEmpty()) + constructorCode << imageMemberName << " = juce::ImageCache::getFromMemory (" + << resourceName << ", " << resourceName << "Size);\n"; +} + +StringArray GeneratedCode::getExtraParentClasses() const +{ + StringArray s; + + for (int i = 0; i < callbacks.size(); ++i) + { + CallbackMethod* const cm = callbacks.getUnchecked(i); + s.add (cm->requiredParentClass); + } + + return s; +} + +String GeneratedCode::getCallbackDeclarations() const +{ + String s; + + for (int i = 0; i < callbacks.size(); ++i) + { + CallbackMethod* const cm = callbacks.getUnchecked(i); + + s << cm->returnType << " " << cm->prototype << " override;\n"; + } + + return s; +} + +String GeneratedCode::getCallbackDefinitions() const +{ + String s; + + for (int i = 0; i < callbacks.size(); ++i) + { + CallbackMethod* const cm = callbacks.getUnchecked(i); + + const String userCodeBlockName ("User" + + build_tools::makeValidIdentifier (cm->prototype.upToFirstOccurrenceOf ("(", false, false), + true, true, false).trim()); + + if (userCodeBlockName.isNotEmpty() && cm->hasPrePostUserSections) + { + s << cm->returnType << " " << className << "::" << cm->prototype + << "\n{\n //[" << userCodeBlockName << "_Pre]\n //[/" << userCodeBlockName + << "_Pre]\n\n " + << CodeHelpers::indent (cm->content.trim(), 4, false) + << "\n\n //[" << userCodeBlockName << "_Post]\n //[/" << userCodeBlockName + << "_Post]\n}\n\n"; + } + else + { + s << cm->returnType << " " << className << "::" << cm->prototype + << "\n{\n " + << CodeHelpers::indent (cm->content.trim(), 4, false) + << "\n}\n\n"; + } + } + + return s; +} + +//============================================================================== +String GeneratedCode::getClassDeclaration() const +{ + StringArray parentClassLines; + parentClassLines.addTokens (parentClasses, ",", StringRef()); + parentClassLines.addArray (getExtraParentClasses()); + + parentClassLines = getCleanedStringArray (parentClassLines); + + if (parentClassLines.contains ("public juce::Button", false)) + parentClassLines.removeString ("public juce::Component", false); + + String r ("class "); + r << className << " : "; + + r += parentClassLines.joinIntoString (",\n" + String::repeatedString (" ", r.length())); + + return r; +} + +String GeneratedCode::getInitialiserList() const +{ + StringArray inits (initialisers); + + if (parentClassInitialiser.isNotEmpty()) + inits.insert (0, parentClassInitialiser); + + inits = getCleanedStringArray (inits); + + String s; + + if (inits.size() == 0) + return s; + + s << " : "; + + for (int i = 0; i < inits.size(); ++i) + { + String init (inits[i]); + + while (init.endsWithChar (',')) + init = init.dropLastCharacters (1); + + s << init; + + if (i < inits.size() - 1) + s << ",\n "; + else + s << "\n"; + } + + return s; +} + +static String getIncludeFileCode (const Array<File>& files, const File& targetFile) +{ + String s; + + for (int i = 0; i < files.size(); ++i) + s << CodeHelpers::createIncludeStatement (files.getReference(i), targetFile) << newLine; + + return s; +} + +bool GeneratedCode::shouldUseTransMacro() const noexcept +{ + return document->shouldUseTransMacro(); +} + +//============================================================================== +static void replaceTemplate (String& text, const String& itemName, const String& value) +{ + for (;;) + { + const int index = text.indexOf ("%%" + itemName + "%%"); + + if (index < 0) + break; + + int indentLevel = 0; + + for (int i = index; --i >= 0;) + { + if (text[i] == '\n') + break; + + ++indentLevel; + } + + text = text.replaceSection (index, itemName.length() + 4, + CodeHelpers::indent (value, indentLevel, false)); + } +} + +//============================================================================== +static bool getUserSection (const StringArray& lines, const String& tag, StringArray& resultLines) +{ + const int start = indexOfLineStartingWith (lines, "//[" + tag + "]", 0); + + if (start < 0) + return false; + + const int end = indexOfLineStartingWith (lines, "//[/" + tag + "]", start + 1); + + for (int i = start + 1; i < end; ++i) + resultLines.add (lines [i]); + + return true; +} + +static void copyAcrossUserSections (String& dest, const String& src) +{ + StringArray srcLines, dstLines; + srcLines.addLines (src); + dstLines.addLines (dest); + + for (int i = 0; i < dstLines.size(); ++i) + { + if (dstLines[i].trimStart().startsWith ("//[")) + { + String tag (dstLines[i].trimStart().substring (3)); + tag = tag.upToFirstOccurrenceOf ("]", false, false); + + jassert (! tag.startsWithChar ('/')); + + if (! tag.startsWithChar ('/')) + { + const int endLine = indexOfLineStartingWith (dstLines, + "//[/" + tag + "]", + i + 1); + + if (endLine > i) + { + StringArray sourceLines; + + if (tag != "UserPaintCustomArguments" && getUserSection (srcLines, tag, sourceLines)) + { + for (int j = endLine - i; --j > 0;) + dstLines.remove (i + 1); + + for (int j = 0; j < sourceLines.size(); ++j) + dstLines.insert (++i, sourceLines [j].trimEnd()); + + ++i; + } + else + { + i = endLine; + } + } + } + } + + dstLines.set (i, dstLines[i].trimEnd()); + } + + dest = dstLines.joinIntoString ("\n") + "\n"; +} + +//============================================================================== +void GeneratedCode::applyToCode (String& code, const File& targetFile, const String& oldFileWithUserData) const +{ + replaceTemplate (code, "version", JUCEApplicationBase::getInstance()->getApplicationVersion()); + replaceTemplate (code, "creationTime", Time::getCurrentTime().toString (true, true, true)); + + replaceTemplate (code, "class_name", className); + replaceTemplate (code, "constructor_params", constructorParams); + replaceTemplate (code, "initialisers", getInitialiserList()); + + replaceTemplate (code, "class_declaration", getClassDeclaration()); + replaceTemplate (code, "private_member_declarations", privateMemberDeclarations); + replaceTemplate (code, "public_member_declarations", getCallbackDeclarations() + newLine + publicMemberDeclarations); + + replaceTemplate (code, "method_definitions", getCallbackDefinitions()); + + replaceTemplate (code, "include_juce", CodeHelpers::createIncludePathIncludeStatement (Project::getJuceSourceHFilename())); + + replaceTemplate (code, "include_files_h", getIncludeFileCode (includeFilesH, targetFile)); + replaceTemplate (code, "include_files_cpp", getIncludeFileCode (includeFilesCPP, targetFile)); + + replaceTemplate (code, "constructor", constructorCode); + replaceTemplate (code, "destructor", destructorCode); + + replaceTemplate (code, "metadata", jucerMetadata); + replaceTemplate (code, "static_member_definitions", staticMemberDefinitions); + + copyAcrossUserSections (code, oldFileWithUserData); +} diff --git a/extras/Projucer/Source/ComponentEditor/jucer_GeneratedCode.h b/extras/Projucer/Source/ComponentEditor/jucer_GeneratedCode.h index 5f62f35d..d4485fe6 100644 --- a/extras/Projucer/Source/ComponentEditor/jucer_GeneratedCode.h +++ b/extras/Projucer/Source/ComponentEditor/jucer_GeneratedCode.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/ComponentEditor/jucer_JucerDocument.cpp b/extras/Projucer/Source/ComponentEditor/jucer_JucerDocument.cpp index ad1e8a8e..2513af5d 100644 --- a/extras/Projucer/Source/ComponentEditor/jucer_JucerDocument.cpp +++ b/extras/Projucer/Source/ComponentEditor/jucer_JucerDocument.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -26,7 +25,7 @@ #include "../Application/jucer_Headers.h" #include "../Application/jucer_Application.h" -#include "../Wizards/jucer_NewFileWizard.h" +#include "../Utility/Helpers/jucer_NewFileWizard.h" #include "jucer_JucerDocument.h" #include "jucer_ObjectTypes.h" #include "UI/jucer_JucerDocumentEditor.h" @@ -36,7 +35,7 @@ #include "Documents/jucer_ButtonDocument.h" const char* const defaultClassName = "NewComponent"; -const char* const defaultParentClasses = "public Component"; +const char* const defaultParentClasses = "public juce::Component"; //============================================================================== JucerDocument::JucerDocument (SourceCodeDocument* c) @@ -67,7 +66,7 @@ void JucerDocument::changed() struct UserDocChangeTimer : public Timer { - UserDocChangeTimer (JucerDocument& d) : doc (d) {} + explicit UserDocChangeTimer (JucerDocument& d) : doc (d) {} void timerCallback() override { doc.reloadFromDocument(); } JucerDocument& doc; @@ -126,9 +125,9 @@ void JucerDocument::refreshAllPropertyComps() void JucerDocument::setClassName (const String& newName) { if (newName != className - && CodeHelpers::makeValidIdentifier (newName, false, false, true).isNotEmpty()) + && build_tools::makeValidIdentifier (newName, false, false, true).isNotEmpty()) { - className = CodeHelpers::makeValidIdentifier (newName, false, false, true); + className = build_tools::makeValidIdentifier (newName, false, false, true); changed(); } } @@ -164,7 +163,7 @@ void JucerDocument::setParentClasses (const String& classes) type = s = String(); } - s = type + CodeHelpers::makeValidIdentifier (s.trim(), false, false, true, true); + s = type + build_tools::makeValidIdentifier (s.trim(), false, false, true, true); parentClassLines.set (i, s); } @@ -268,36 +267,36 @@ void JucerDocument::getOptionalMethods (StringArray& baseClasses, StringArray& methods, StringArray& initialContents) const { - addMethod ("Component", "void", "visibilityChanged()", "", baseClasses, returnValues, methods, initialContents); - addMethod ("Component", "void", "moved()", "", baseClasses, returnValues, methods, initialContents); - addMethod ("Component", "void", "parentHierarchyChanged()", "", baseClasses, returnValues, methods, initialContents); - addMethod ("Component", "void", "parentSizeChanged()", "", baseClasses, returnValues, methods, initialContents); - addMethod ("Component", "void", "lookAndFeelChanged()", "", baseClasses, returnValues, methods, initialContents); - addMethod ("Component", "bool", "hitTest (int x, int y)", "return true;", baseClasses, returnValues, methods, initialContents); - addMethod ("Component", "void", "broughtToFront()", "", baseClasses, returnValues, methods, initialContents); - addMethod ("Component", "void", "filesDropped (const StringArray& filenames, int mouseX, int mouseY)", "", baseClasses, returnValues, methods, initialContents); - addMethod ("Component", "void", "handleCommandMessage (int commandId)", "", baseClasses, returnValues, methods, initialContents); - addMethod ("Component", "void", "childrenChanged()", "", baseClasses, returnValues, methods, initialContents); - addMethod ("Component", "void", "enablementChanged()", "", baseClasses, returnValues, methods, initialContents); - - addMethod ("Component", "void", "mouseMove (const MouseEvent& e)", "", baseClasses, returnValues, methods, initialContents); - addMethod ("Component", "void", "mouseEnter (const MouseEvent& e)", "", baseClasses, returnValues, methods, initialContents); - addMethod ("Component", "void", "mouseExit (const MouseEvent& e)", "", baseClasses, returnValues, methods, initialContents); - addMethod ("Component", "void", "mouseDown (const MouseEvent& e)", "", baseClasses, returnValues, methods, initialContents); - addMethod ("Component", "void", "mouseDrag (const MouseEvent& e)", "", baseClasses, returnValues, methods, initialContents); - addMethod ("Component", "void", "mouseUp (const MouseEvent& e)", "", baseClasses, returnValues, methods, initialContents); - addMethod ("Component", "void", "mouseDoubleClick (const MouseEvent& e)", "", baseClasses, returnValues, methods, initialContents); - addMethod ("Component", "void", "mouseWheelMove (const MouseEvent& e, const MouseWheelDetails& wheel)", "", baseClasses, returnValues, methods, initialContents); - - addMethod ("Component", "bool", "keyPressed (const KeyPress& key)", "return false; // Return true if your handler uses this key event, or false to allow it to be passed-on.", baseClasses, returnValues, methods, initialContents); - addMethod ("Component", "bool", "keyStateChanged (bool isKeyDown)", "return false; // Return true if your handler uses this key event, or false to allow it to be passed-on.", baseClasses, returnValues, methods, initialContents); - addMethod ("Component", "void", "modifierKeysChanged (const ModifierKeys& modifiers)", "", baseClasses, returnValues, methods, initialContents); - - addMethod ("Component", "void", "focusGained (FocusChangeType cause)", "", baseClasses, returnValues, methods, initialContents); - addMethod ("Component", "void", "focusLost (FocusChangeType cause)", "", baseClasses, returnValues, methods, initialContents); - addMethod ("Component", "void", "focusOfChildComponentChanged (FocusChangeType cause)", "", baseClasses, returnValues, methods, initialContents); - addMethod ("Component", "void", "modifierKeysChanged (const ModifierKeys& modifiers)", "", baseClasses, returnValues, methods, initialContents); - addMethod ("Component", "void", "inputAttemptWhenModal()", "", baseClasses, returnValues, methods, initialContents); + addMethod ("juce::Component", "void", "visibilityChanged()", "", baseClasses, returnValues, methods, initialContents); + addMethod ("juce::Component", "void", "moved()", "", baseClasses, returnValues, methods, initialContents); + addMethod ("juce::Component", "void", "parentHierarchyChanged()", "", baseClasses, returnValues, methods, initialContents); + addMethod ("juce::Component", "void", "parentSizeChanged()", "", baseClasses, returnValues, methods, initialContents); + addMethod ("juce::Component", "void", "lookAndFeelChanged()", "", baseClasses, returnValues, methods, initialContents); + addMethod ("juce::Component", "bool", "hitTest (int x, int y)", "return true;", baseClasses, returnValues, methods, initialContents); + addMethod ("juce::Component", "void", "broughtToFront()", "", baseClasses, returnValues, methods, initialContents); + addMethod ("juce::Component", "void", "filesDropped (const juce::StringArray& filenames, int mouseX, int mouseY)", "", baseClasses, returnValues, methods, initialContents); + addMethod ("juce::Component", "void", "handleCommandMessage (int commandId)", "", baseClasses, returnValues, methods, initialContents); + addMethod ("juce::Component", "void", "childrenChanged()", "", baseClasses, returnValues, methods, initialContents); + addMethod ("juce::Component", "void", "enablementChanged()", "", baseClasses, returnValues, methods, initialContents); + + addMethod ("juce::Component", "void", "mouseMove (const juce::MouseEvent& e)", "", baseClasses, returnValues, methods, initialContents); + addMethod ("juce::Component", "void", "mouseEnter (const juce::MouseEvent& e)", "", baseClasses, returnValues, methods, initialContents); + addMethod ("juce::Component", "void", "mouseExit (const juce::MouseEvent& e)", "", baseClasses, returnValues, methods, initialContents); + addMethod ("juce::Component", "void", "mouseDown (const juce::MouseEvent& e)", "", baseClasses, returnValues, methods, initialContents); + addMethod ("juce::Component", "void", "mouseDrag (const juce::MouseEvent& e)", "", baseClasses, returnValues, methods, initialContents); + addMethod ("juce::Component", "void", "mouseUp (const juce::MouseEvent& e)", "", baseClasses, returnValues, methods, initialContents); + addMethod ("juce::Component", "void", "mouseDoubleClick (const juce::MouseEvent& e)", "", baseClasses, returnValues, methods, initialContents); + addMethod ("juce::Component", "void", "mouseWheelMove (const juce::MouseEvent& e, const juce::MouseWheelDetails& wheel)", "", baseClasses, returnValues, methods, initialContents); + + addMethod ("juce::Component", "bool", "keyPressed (const juce::KeyPress& key)", "return false; // Return true if your handler uses this key event, or false to allow it to be passed-on.", baseClasses, returnValues, methods, initialContents); + addMethod ("juce::Component", "bool", "keyStateChanged (bool isKeyDown)", "return false; // Return true if your handler uses this key event, or false to allow it to be passed-on.", baseClasses, returnValues, methods, initialContents); + addMethod ("juce::Component", "void", "modifierKeysChanged (const juce::ModifierKeys& modifiers)", "", baseClasses, returnValues, methods, initialContents); + + addMethod ("juce::Component", "void", "focusGained (FocusChangeType cause)", "", baseClasses, returnValues, methods, initialContents); + addMethod ("juce::Component", "void", "focusLost (FocusChangeType cause)", "", baseClasses, returnValues, methods, initialContents); + addMethod ("juce::Component", "void", "focusOfChildComponentChanged (FocusChangeType cause)", "", baseClasses, returnValues, methods, initialContents); + addMethod ("juce::Component", "void", "modifierKeysChanged (const juce::ModifierKeys& modifiers)", "", baseClasses, returnValues, methods, initialContents); + addMethod ("juce::Component", "void", "inputAttemptWhenModal()", "", baseClasses, returnValues, methods, initialContents); } void JucerDocument::setOptionalMethodEnabled (const String& methodSignature, const bool enable) @@ -312,7 +311,8 @@ void JucerDocument::setOptionalMethodEnabled (const String& methodSignature, con bool JucerDocument::isOptionalMethodEnabled (const String& sig) const noexcept { - return activeExtraMethods.contains (sig); + return activeExtraMethods.contains (sig) + || activeExtraMethods.contains (sig.replace ("juce::", {})); } void JucerDocument::addExtraClassProperties (PropertyPanel&) @@ -413,7 +413,7 @@ void JucerDocument::fillInGeneratedCode (GeneratedCode& code) const code.constructorCode << "setName (" + quotedString (componentName, false) + ");\n"; // call these now, just to make sure they're the first two methods in the list. - code.getCallbackCode (String(), "void", "paint (Graphics& g)", false) + code.getCallbackCode (String(), "void", "paint (juce::Graphics& g)", false) << "//[UserPrePaint] Add your own custom painting code here..\n//[/UserPrePaint]\n\n"; code.getCallbackCode (String(), "void", "resized()", false) @@ -437,7 +437,7 @@ void JucerDocument::fillInGeneratedCode (GeneratedCode& code) const if (initialWidth > 0 || initialHeight > 0) code.constructorCode << "\nsetSize (" << initialWidth << ", " << initialHeight << ");\n"; - code.getCallbackCode (String(), "void", "paint (Graphics& g)", false) + code.getCallbackCode (String(), "void", "paint (juce::Graphics& g)", false) << "//[UserPaint] Add your own custom painting code here..\n//[/UserPaint]"; code.getCallbackCode (String(), "void", "resized()", false) @@ -453,7 +453,7 @@ void JucerDocument::fillInGeneratedCode (GeneratedCode& code) const { String baseClassToAdd (baseClasses[i]); - if (baseClassToAdd == "Component" || baseClassToAdd == "Button") + if (baseClassToAdd == "juce::Component" || baseClassToAdd == "juce::Button") baseClassToAdd.clear(); String& s = code.getCallbackCode (baseClassToAdd, returnValues[i], methods[i], false); @@ -479,7 +479,7 @@ void JucerDocument::fillInPaintCode (GeneratedCode& code) const { for (int i = 0; i < getNumPaintRoutines(); ++i) getPaintRoutine (i) - ->fillInGeneratedCode (code, code.getCallbackCode (String(), "void", "paint (Graphics& g)", false)); + ->fillInGeneratedCode (code, code.getCallbackCode (String(), "void", "paint (juce::Graphics& g)", false)); } void JucerDocument::setTemplateFile (const String& newFile) @@ -705,7 +705,7 @@ public: { if (header->save()) { - odm.closeFile (getFile().withFileExtension(".h"), false); + odm.closeFile (getFile().withFileExtension(".h"), OpenDocumentManager::SaveIfNeeded::no); return true; } } @@ -715,10 +715,13 @@ public: Component* createEditor() override { - std::unique_ptr<JucerDocument> jucerDoc (JucerDocument::createForCppFile (getProject(), getFile())); + if (ProjucerApplication::getApp().isGUIEditorEnabled()) + { + std::unique_ptr<JucerDocument> jucerDoc (JucerDocument::createForCppFile (getProject(), getFile())); - if (jucerDoc != nullptr) - return new JucerDocumentEditor (jucerDoc.release()); + if (jucerDoc != nullptr) + return new JucerDocumentEditor (jucerDoc.release()); + } return SourceCodeDocument::createEditor(); } @@ -774,8 +777,8 @@ struct NewGUIComponentWizard : public NewFileWizard::Type cpp->save(); header->save(); - odm.closeDocument (cpp, true); - odm.closeDocument (header, true); + odm.closeDocument (cpp, OpenDocumentManager::SaveIfNeeded::yes); + odm.closeDocument (header, OpenDocumentManager::SaveIfNeeded::yes); parent.addFileRetainingSortOrder (headerFile, true); parent.addFileRetainingSortOrder (cppFile, true); diff --git a/extras/Projucer/Source/ComponentEditor/jucer_JucerDocument.h b/extras/Projucer/Source/ComponentEditor/jucer_JucerDocument.h index 15b81495..b882cdfc 100644 --- a/extras/Projucer/Source/ComponentEditor/jucer_JucerDocument.h +++ b/extras/Projucer/Source/ComponentEditor/jucer_JucerDocument.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/ComponentEditor/jucer_ObjectTypes.cpp b/extras/Projucer/Source/ComponentEditor/jucer_ObjectTypes.cpp index 76ff5203..09527a83 100644 --- a/extras/Projucer/Source/ComponentEditor/jucer_ObjectTypes.cpp +++ b/extras/Projucer/Source/ComponentEditor/jucer_ObjectTypes.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/ComponentEditor/jucer_ObjectTypes.h b/extras/Projucer/Source/ComponentEditor/jucer_ObjectTypes.h index 2681e02a..cdf9f96c 100644 --- a/extras/Projucer/Source/ComponentEditor/jucer_ObjectTypes.h +++ b/extras/Projucer/Source/ComponentEditor/jucer_ObjectTypes.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/ComponentEditor/jucer_PaintRoutine.cpp b/extras/Projucer/Source/ComponentEditor/jucer_PaintRoutine.cpp index fd59d2b5..69c35f6c 100644 --- a/extras/Projucer/Source/ComponentEditor/jucer_PaintRoutine.cpp +++ b/extras/Projucer/Source/ComponentEditor/jucer_PaintRoutine.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -165,7 +164,7 @@ PaintElement* PaintRoutine::addNewElement (PaintElement* e, const int index, con class DeleteElementAction : public PaintElementUndoableAction <PaintElement> { public: - DeleteElementAction (PaintElement* const element) + explicit DeleteElementAction (PaintElement* const element) : PaintElementUndoableAction <PaintElement> (element), oldIndex (-1) { diff --git a/extras/Projucer/Source/ComponentEditor/jucer_PaintRoutine.h b/extras/Projucer/Source/ComponentEditor/jucer_PaintRoutine.h index dc9dc3cf..335d520f 100644 --- a/extras/Projucer/Source/ComponentEditor/jucer_PaintRoutine.h +++ b/extras/Projucer/Source/ComponentEditor/jucer_PaintRoutine.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/ComponentEditor/jucer_UtilityFunctions.h b/extras/Projucer/Source/ComponentEditor/jucer_UtilityFunctions.h index f566a613..691baa73 100644 --- a/extras/Projucer/Source/ComponentEditor/jucer_UtilityFunctions.h +++ b/extras/Projucer/Source/ComponentEditor/jucer_UtilityFunctions.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/Licenses/jucer_LicenseController.cpp b/extras/Projucer/Source/Licenses/jucer_LicenseController.cpp index c73d7345..2a7d97cb 100644 --- a/extras/Projucer/Source/Licenses/jucer_LicenseController.cpp +++ b/extras/Projucer/Source/Licenses/jucer_LicenseController.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -59,6 +58,8 @@ static const char* getLicenseStateValue (LicenseState::Type type) case LicenseState::Type::edu: return "edu"; case LicenseState::Type::indie: return "indie"; case LicenseState::Type::pro: return "pro"; + case LicenseState::Type::notLoggedIn: + case LicenseState::Type::noLicenseChosenYet: default: return nullptr; } } @@ -73,23 +74,6 @@ static LicenseState::Type getLicenseTypeFromValue (const String& d) return LicenseState::Type::noLicenseChosenYet; } -static const char* getApplicationUsageDataStateValue (LicenseState::ApplicationUsageData type) -{ - switch (type) - { - case LicenseState::ApplicationUsageData::enabled: return "enabled"; - case LicenseState::ApplicationUsageData::disabled: return "disabled"; - default: return "notChosen"; - } -} - -static LicenseState::ApplicationUsageData getApplicationUsageDataTypeFromValue (const String& value) -{ - if (value == getApplicationUsageDataStateValue (LicenseState::ApplicationUsageData::enabled)) return LicenseState::ApplicationUsageData::enabled; - if (value == getApplicationUsageDataStateValue (LicenseState::ApplicationUsageData::disabled)) return LicenseState::ApplicationUsageData::disabled; - return LicenseState::ApplicationUsageData::notChosenYet; -} - #if ! JUCER_ENABLE_GPL_MODE struct LicenseController::ModalCompletionCallback : ModalComponentManager::Callback { @@ -177,17 +161,6 @@ void LicenseController::chooseNewLicense() #endif } -void LicenseController::setApplicationUsageDataState (LicenseState::ApplicationUsageData newState) -{ - if (state.applicationUsageDataState != newState) - { - state.applicationUsageDataState = newState; - ProjucerApplication::getApp().setAnalyticsEnabled (newState == LicenseState::ApplicationUsageData::enabled); - - updateState (state); - } -} - //============================================================================== #if ! JUCER_ENABLE_GPL_MODE void LicenseController::closeWebview (int result) @@ -259,27 +232,16 @@ void LicenseController::updateState (const LicenseState& newState) { auto& props = ProjucerApplication::getApp().settings->getGlobalProperties(); - auto oldLicenseType = state.type; - state = newState; licenseStateToSettings (state, props); auto stateParam = getState(); listeners.call ([&] (StateChangedCallback& l) { l.licenseStateChanged (stateParam); }); - - if (oldLicenseType != state.type) - { - StringPairArray data; - data.set ("label", state.licenseTypeToString (state.type)); - - Analytics::getInstance()->logEvent ("License Type", data, ProjucerAnalyticsEvent::userEvent); - } } LicenseState LicenseController::licenseStateFromOldSettings (XmlElement* licenseXml) { LicenseState result; result.type = getLicenseTypeFromValue (licenseXml->getChildElementAllSubText ("type", {})); - result.applicationUsageDataState = getApplicationUsageDataTypeFromValue (licenseXml->getChildElementAllSubText ("applicationUsageData", {})); result.username = licenseXml->getChildElementAllSubText ("username", {}); result.email = licenseXml->getChildElementAllSubText ("email", {}); result.authToken = licenseXml->getChildElementAllSubText ("authToken", {}); @@ -307,7 +269,6 @@ LicenseState LicenseController::licenseStateFromSettings (PropertiesFile& props) LicenseState result; result.type = getLicenseTypeFromValue (licenseXml->getStringAttribute ("type", {})); - result.applicationUsageDataState = getApplicationUsageDataTypeFromValue (licenseXml->getStringAttribute ("applicationUsageData", {})); result.username = licenseXml->getStringAttribute ("username", {}); result.email = licenseXml->getStringAttribute ("email", {}); result.authToken = licenseXml->getStringAttribute ("authToken", {}); @@ -333,7 +294,6 @@ void LicenseController::licenseStateToSettings (const LicenseState& state, Prope if (auto* typeString = getLicenseStateValue (state.type)) licenseXml.setAttribute ("type", typeString); - licenseXml.setAttribute ("applicationUsageData", getApplicationUsageDataStateValue (state.applicationUsageDataState)); licenseXml.setAttribute ("username", state.username); licenseXml.setAttribute ("email", state.email); licenseXml.setAttribute ("authToken", state.authToken); diff --git a/extras/Projucer/Source/Licenses/jucer_LicenseController.h b/extras/Projucer/Source/Licenses/jucer_LicenseController.h deleted file mode 100644 index 8070027c..00000000 --- a/extras/Projucer/Source/Licenses/jucer_LicenseController.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - ============================================================================== - - 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. - - ============================================================================== -*/ - -#pragma once - -struct LicenseThread; -class LicenseWebview; - -//============================================================================== -struct LicenseState -{ - enum class Type - { - notLoggedIn, // only used when the webview is open and the user has not logged in yet - noLicenseChosenYet, - - GPL, // GPL is used when the user enables the GPL compile flag - personal, - edu, - indie, - pro - }; - - enum class ApplicationUsageData - { - notChosenYet, - - enabled, - disabled - }; - - Type type = Type::notLoggedIn; - ApplicationUsageData applicationUsageDataState = ApplicationUsageData::notChosenYet; - String username; - String email; - String authToken; - - static const char* licenseTypeToString (Type licenseType); - - bool isPaidOrGPL() const noexcept { return (type == Type::GPL || type == Type::indie || type == Type::pro); } - - Image avatar; -}; - -//============================================================================== -class LicenseController -{ -public: - //============================================================================== - struct StateChangedCallback - { - virtual ~StateChangedCallback() {} - virtual void licenseStateChanged (const LicenseState&) = 0; - }; - - //============================================================================== - LicenseController(); - ~LicenseController(); - - void startWebviewIfNeeded(); - - //============================================================================== - LicenseState getState() const noexcept; - void logout(); - void chooseNewLicense(); - void setApplicationUsageDataState (LicenseState::ApplicationUsageData newState); - - //============================================================================== - void addLicenseStatusChangedCallback (StateChangedCallback* callback) { listeners.add (callback); } - void removeLicenseStatusChangedCallback (StateChangedCallback* callback) { listeners.remove (callback); } - -private: - //============================================================================== - void updateState (const LicenseState&); - - static LicenseState licenseStateFromOldSettings (XmlElement*); - static LicenseState licenseStateFromSettings (PropertiesFile&); - static void licenseStateToSettings (const LicenseState&, PropertiesFile&); - - #if ! JUCER_ENABLE_GPL_MODE - //============================================================================== - struct ModalCompletionCallback; - friend struct LicenseThread; - - //============================================================================== - void closeWebview (int); - void modalStateFinished (int); - void ensureLicenseWebviewIsOpenWithPage (const String&); - void queryWebview (const String&, const String&, HashMap<String, String>&); - - //============================================================================== - std::unique_ptr<LicenseThread> thread; - LicenseWebview* licenseWebview = nullptr; - #endif - - LicenseState state; - ListenerList<LicenseController::StateChangedCallback> listeners; - bool guiNotInitialisedYet = true; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LicenseController) -}; diff --git a/extras/Projucer/Source/Licenses/jucer_LicenseThread.h b/extras/Projucer/Source/Licenses/jucer_LicenseThread.h deleted file mode 100644 index 2c21429a..00000000 --- a/extras/Projucer/Source/Licenses/jucer_LicenseThread.h +++ /dev/null @@ -1,466 +0,0 @@ -/* - ============================================================================== - - 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. - - ============================================================================== -*/ - -#pragma once - - -//============================================================================== -struct NetWorkerThread : public Thread, - private AsyncUpdater -{ - NetWorkerThread() : Thread ("License") {} - - ~NetWorkerThread() override - { - JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED - - signalThreadShouldExit(); - cancelPendingUpdate(); - finished.signal(); - - { - ScopedLock lock (weakReferenceLock); - - if (currentInputStream != nullptr) - currentInputStream->cancel(); - } - - waitForThreadToExit (-1); - } - - //============================================================================== - void executeOnMessageThreadAndBlock (std::function<void()> f, bool signalWhenFinished = true) - { - // only call this on the worker thread - jassert (Thread::getCurrentThreadId() == getThreadId()); - - if (! isWaiting) - { - ScopedValueSetter<bool> reentrant (isWaiting, true); - - finished.reset(); - - if (! threadShouldExit()) - { - functionToExecute = [signalWhenFinished, f, this] () { f(); if (signalWhenFinished) finished.signal(); }; - triggerAsyncUpdate(); - finished.wait (-1); - } - } - else - { - // only one task at a time - jassertfalse; - return; - } - } - - WebInputStream* getSharedWebInputStream (const URL& url, const bool usePost) - { - ScopedLock lock (weakReferenceLock); - - if (threadShouldExit()) - return nullptr; - - jassert (currentInputStream == nullptr); - return (currentInputStream = new WeakWebInputStream (*this, url, usePost)); - } - - bool isWaiting = false; - WaitableEvent finished; - -private: - //============================================================================== - void handleAsyncUpdate() override - { - if (functionToExecute) - { - std::function<void()> f; - std::swap (f, functionToExecute); - - if (! threadShouldExit()) - f(); - } - } - - //============================================================================== - struct WeakWebInputStream : public WebInputStream - { - WeakWebInputStream (NetWorkerThread& workerThread, const URL& url, const bool usePost) - : WebInputStream (url, usePost), owner (workerThread) {} - - ~WeakWebInputStream() - { - ScopedLock lock (owner.weakReferenceLock); - owner.currentInputStream = nullptr; - } - - NetWorkerThread& owner; - WeakReference<WeakWebInputStream>::Master masterReference; - friend class WeakReference<WeakWebInputStream>; - }; - - //============================================================================== - friend struct WeakWebInputStream; - - std::function<void()> functionToExecute; - CriticalSection weakReferenceLock; - WebInputStream* currentInputStream = nullptr; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NetWorkerThread) -}; - -//============================================================================== -//============================================================================== -//============================================================================== -struct LicenseThread : NetWorkerThread -{ - LicenseThread (LicenseController& licenseController, bool shouldSelectNewLicense) - : owner (licenseController), selectNewLicense (shouldSelectNewLicense) - { - startThread(); - } - - String getAuthToken() - { - if (owner.state.authToken.isNotEmpty()) - return owner.state.authToken; - - selectNewLicense = false; - HashMap<String, String> result; - - if (! queryWebview ("https://auth.roli.com/signin/projucer?redirect=projucer://receive-auth-token?token=", - "receive-auth-token", result)) - return {}; - - return result["token"]; - } - - // returns true if any information was updated - void updateUserInfo (LicenseState& stateToUpdate) - { - jassert (stateToUpdate.authToken.isNotEmpty()); - - auto accessTokenHeader = "x-access-token: " + stateToUpdate.authToken; - std::unique_ptr<WebInputStream> shared (getSharedWebInputStream (URL ("https://api.roli.com/api/v1/user"), false)); - - if (shared != nullptr) - { - const int statusCode = shared->withExtraHeaders (accessTokenHeader).getStatusCode(); - - if (statusCode == 200) - { - var result = JSON::parse (shared->readEntireStreamAsString()); - shared.reset(); - - auto newState = licenseStateFromJSON (result, stateToUpdate.authToken, stateToUpdate.avatar); - - if (newState.type != LicenseState::Type::notLoggedIn) - stateToUpdate = newState; - } - else if (statusCode == 401) - { - selectNewLicense = false; - - // un-authorised: token has expired - stateToUpdate = LicenseState(); - } - } - } - - void updateLicenseType (LicenseState& stateToUpdate) - { - bool requiredWebview = false; - String licenseChooserPage = "https://juce.com/webviews/select_license"; - - jassert (stateToUpdate.authToken.isNotEmpty()); - jassert (stateToUpdate.type != LicenseState::Type::notLoggedIn); - - auto accessTokenHeader = "x-access-token: " + stateToUpdate.authToken; - StringArray licenses; - - while ((licenses.isEmpty() || selectNewLicense) && ! threadShouldExit()) - { - static Identifier licenseTypeIdentifier ("type"); - static Identifier licenseStatusIdentifier ("status"); - static Identifier projucerLicenseTypeIdentifier ("licence_type"); - static Identifier productNameIdentifier ("product_name"); - static Identifier licenseIdentifier ("licence"); - static Identifier serialIdentifier ("serial_number"); - static Identifier versionIdentifier ("product_version"); - static Identifier searchInternalIdentifier ("search_internal_id"); - - if (! selectNewLicense) - { - std::unique_ptr<WebInputStream> shared (getSharedWebInputStream (URL ("https://api.roli.com/api/v1/user/licences?search_internal_id=com.roli.projucer&version=5"), - false)); - if (shared == nullptr) - break; - - var json = JSON::parse (shared->withExtraHeaders (accessTokenHeader) - .readEntireStreamAsString()); - shared.reset(); - - if (auto* jsonLicenses = json.getArray()) - { - for (auto& v : *jsonLicenses) - { - if (auto* obj = v.getDynamicObject()) - { - const String& productType = obj->getProperty (projucerLicenseTypeIdentifier); - const String& status = obj->getProperty (licenseStatusIdentifier); - - if (productType.isNotEmpty() && (status.isEmpty() || status == "active")) - licenses.add (productType); - } - } - } - else - { - // no internet -> then use the last valid license - if (stateToUpdate.type != LicenseState::Type::notLoggedIn - && stateToUpdate.type != LicenseState::Type::noLicenseChosenYet) - return; - } - - if (! licenses.isEmpty()) - break; - } - - // ask the user to select a license - HashMap<String, String> result; - requiredWebview = true; - - if (! queryWebview (licenseChooserPage, {}, result)) - break; - - const String& redirectURL = result["page-redirect"]; - const String& productKey = result["register-product"]; - const String& chosenLicenseType = result["redeem-licence-type"]; - - if (redirectURL.isNotEmpty()) - { - licenseChooserPage = "https://juce.com/webviews/register-product"; - continue; - } - - if (productKey.isNotEmpty()) - { - DynamicObject::Ptr redeemObject (new DynamicObject()); - redeemObject->setProperty (serialIdentifier, productKey); - - String postData (JSON::toString (var (redeemObject.get()))); - - std::unique_ptr<WebInputStream> shared (getSharedWebInputStream (URL ("https://api.roli.com/api/v1/user/products").withPOSTData (postData), - true)); - if (shared == nullptr) - break; - - int statusCode = shared->withExtraHeaders (accessTokenHeader) - .withExtraHeaders ("Content-Type: application/json") - .getStatusCode(); - - licenseChooserPage = String ("https://juce.com/webviews/register-product?error=") - + String (statusCode == 404 ? "invalid" : "server"); - - if (statusCode == 200) - selectNewLicense = false; - - continue; - } - - if (chosenLicenseType.isNotEmpty()) - { - // redeem the license - DynamicObject::Ptr jsonLicenseObject (new DynamicObject()); - jsonLicenseObject->setProperty (projucerLicenseTypeIdentifier, chosenLicenseType); - jsonLicenseObject->setProperty (versionIdentifier, 5); - - - DynamicObject::Ptr jsonLicenseRequest (new DynamicObject()); - jsonLicenseRequest->setProperty (licenseIdentifier, var (jsonLicenseObject.get())); - jsonLicenseRequest->setProperty (searchInternalIdentifier, "com.roli.projucer"); - jsonLicenseRequest->setProperty (licenseTypeIdentifier, "software"); - - String postData (JSON::toString (var (jsonLicenseRequest.get()))); - std::unique_ptr<WebInputStream> shared (getSharedWebInputStream (URL ("https://api.roli.com/api/v1/user/products/redeem") - .withPOSTData (postData), - true)); - - if (shared != nullptr) - { - int statusCode = shared->withExtraHeaders (accessTokenHeader) - .withExtraHeaders ("Content-Type: application/json") - .getStatusCode(); - - if (statusCode == 200) - selectNewLicense = false; - - continue; - } - } - - break; - } - - HashMap<String, String> result; - - if (requiredWebview && ! threadShouldExit()) - queryWebview ("https://juce.com/webviews/registration-complete", "licence_provisioned", result); - - stateToUpdate.type = getBestLicenseTypeFromLicenses (licenses); - } - - //============================================================================== - void run() override - { - LicenseState workState (owner.state); - - while (! threadShouldExit()) - { - workState.authToken = getAuthToken(); - - if (workState.authToken.isEmpty()) - return; - - // read the user information - updateUserInfo (workState); - - if (threadShouldExit()) - return; - - updateIfChanged (workState); - - // if the last step logged us out then retry - if (workState.authToken.isEmpty()) - continue; - - // check if the license has changed - updateLicenseType (workState); - - if (threadShouldExit()) - return; - - updateIfChanged (workState); - closeWebviewOnMessageThread (0); - finished.wait (60 * 5 * 1000); - } - } - - //============================================================================== - LicenseState licenseStateFromJSON (const var& json, const String& authToken, const Image& fallbackAvatar) - { - static Identifier usernameIdentifier ("username"); - static Identifier emailIdentifier ("email"); - static Identifier avatarURLIdentifier ("avatar_url"); - - LicenseState result; - - if (auto* obj = json.getDynamicObject()) - { - result.type = LicenseState::Type::noLicenseChosenYet; - result.username = obj->getProperty (usernameIdentifier); - result.authToken = authToken; - result.email = obj->getProperty (emailIdentifier); - result.avatar = fallbackAvatar; - - String avatarURL = obj->getProperty (avatarURLIdentifier); - - if (avatarURL.isNotEmpty()) - { - std::unique_ptr<WebInputStream> shared (getSharedWebInputStream (URL (avatarURL), false)); - - if (shared != nullptr) - { - MemoryBlock mb; - shared->readIntoMemoryBlock (mb); - - result.avatar = ImageFileFormat::loadFrom (mb.getData(), mb.getSize()); - } - } - } - - return result; - } - - //============================================================================== - bool queryWebview (const String& startURL, const String& valueToQuery, HashMap<String, String>& result) - { - executeOnMessageThreadAndBlock ([&] () { owner.queryWebview (startURL, valueToQuery, result); }, false); - return (! threadShouldExit()); - } - - void closeWebviewOnMessageThread (int result) - { - executeOnMessageThreadAndBlock ([this, result] () { owner.closeWebview (result); }); - } - - static bool stringArrayContainsSubstring (const StringArray& stringArray, const String& substring) - { - jassert (substring.isNotEmpty()); - - for (auto element : stringArray) - if (element.containsIgnoreCase (substring)) - return true; - - return false; - } - - static LicenseState::Type getBestLicenseTypeFromLicenses (const StringArray& licenses) - { - if (stringArrayContainsSubstring (licenses, "juce-pro")) return LicenseState::Type::pro; - else if (stringArrayContainsSubstring (licenses, "juce-indie")) return LicenseState::Type::indie; - else if (stringArrayContainsSubstring (licenses, "juce-personal")) return LicenseState::Type::personal; - else if (stringArrayContainsSubstring (licenses, "juce-edu")) return LicenseState::Type::edu; - - return LicenseState::Type::noLicenseChosenYet; - } - - void updateIfChanged (const LicenseState& newState) - { - LicenseState updatedState (owner.state); - bool changed = false; - bool shouldUpdateLicenseType = (newState.type != LicenseState::Type::noLicenseChosenYet - || updatedState.type == LicenseState::Type::notLoggedIn); - - if (newState.type != LicenseState::Type::notLoggedIn) updatedState.avatar = newState.avatar; - - if (owner.state.type != newState.type && shouldUpdateLicenseType) { updatedState.type = newState.type; changed = true; } - if (owner.state.authToken != newState.authToken) { updatedState.authToken = newState.authToken; changed = true; } - if (owner.state.username != newState.username) { updatedState.username = newState.username; changed = true; } - if (owner.state.email != newState.email) { updatedState.email = newState.email; changed = true; } - if (owner.state.avatar.isValid() != newState.avatar.isValid()) { changed = true; } - - if (changed) - executeOnMessageThreadAndBlock ([this, updatedState] { owner.updateState (updatedState); }); - } - - //============================================================================== - LicenseController& owner; - bool selectNewLicense; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LicenseThread) -}; diff --git a/extras/Projucer/Source/Licenses/jucer_LicenseWebview.h b/extras/Projucer/Source/Licenses/jucer_LicenseWebview.h deleted file mode 100644 index adb3709d..00000000 --- a/extras/Projucer/Source/Licenses/jucer_LicenseWebview.h +++ /dev/null @@ -1,283 +0,0 @@ -/* - ============================================================================== - - 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. - - ============================================================================== -*/ - -#pragma once - - -//============================================================================== -class LicenseWebview : public DialogWindow -{ -public: - LicenseWebview (ModalComponentManager::Callback* callbackToUse, const String& request) - : DialogWindow ("Log-in to Projucer", Colour (0xfff1f1f1), true, true) - { - LicenseWebviewContent* content; - - setUsingNativeTitleBar (true); - setContentOwned (content = new LicenseWebviewContent (*this, callbackToUse), true); - - centreWithSize (getWidth(), getHeight()); - - content->goToURL (request); - } - - void goToURL (const String& request) { reinterpret_cast<LicenseWebviewContent*> (getContentComponent())->goToURL (request); } - - void setPageCallback (const std::function<void (const String&, const HashMap<String, String>&)>& cb) - { - reinterpret_cast<LicenseWebviewContent*> (getContentComponent())->pageCallback = cb; - } - - void setNewWindowCallback (const std::function<void (const String&)>& cb) - { - reinterpret_cast<LicenseWebviewContent*> (getContentComponent())->newWindowCallback = cb; - } - - void closeButtonPressed() override { exitModalState (-1); } - -private: - class LicenseWebviewContent : public Component - { - //============================================================================== - struct RedirectWebBrowserComponent : public WebBrowserComponent - { - RedirectWebBrowserComponent (LicenseWebviewContent& controller) : WebBrowserComponent (false), owner (controller) {} - ~RedirectWebBrowserComponent() override {} - - bool pageAboutToLoad (const String& url) override { return owner.pageAboutToLoad (url); } - void pageFinishedLoading (const String& url) override { owner.pageFinishedLoading (url); } - void newWindowAttemptingToLoad (const String& url) override { owner.newWindowAttemptingToLoad (url); } - bool pageLoadHadNetworkError (const String& err) override { return owner.pageLoadHadNetworkError (err); } - - LicenseWebviewContent& owner; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (RedirectWebBrowserComponent) - }; - - //============================================================================== - struct Header : public Component, - private LicenseController::StateChangedCallback - { - Header() : avatarButton ("User Settings", &getIcons().user) - { - setOpaque (true); - addChildComponent (avatarButton); - - avatarButton.onClick = [this] { showAvatarWindow(); }; - - if (auto* licenseController = ProjucerApplication::getApp().licenseController.get()) - { - licenseController->addLicenseStatusChangedCallback (this); - licenseStateChanged (licenseController->getState()); - } - } - - ~Header() override - { - if (auto* licenseController = ProjucerApplication::getApp().licenseController.get()) - licenseController->removeLicenseStatusChangedCallback (this); - } - - void resized() override - { - auto r = getLocalBounds().reduced (30, 20); - avatarButton.setBounds (r.removeFromRight (r.getHeight())); - } - - void paint (Graphics& g) override - { - auto r = getLocalBounds().reduced (30, 20); - g.fillAll (Colour (backgroundColour)); - - if (juceLogo != nullptr) - juceLogo->drawWithin (g, r.toFloat(), RectanglePlacement::xLeft + RectanglePlacement::yMid, 1.0); - } - - void licenseStateChanged (const LicenseState& state) override - { - avatarButton.iconImage = state.avatar; - avatarButton.setVisible (state.type != LicenseState::Type::notLoggedIn && state.type != LicenseState::Type::GPL); - avatarButton.repaint(); - } - - void showAvatarWindow() - { - if (auto* licenseController = ProjucerApplication::getApp().licenseController.get()) - { - auto type = licenseController->getState().type; - - auto* content = new UserSettingsPopup (true); - content->setSize (200, (type == LicenseState::Type::noLicenseChosenYet ? 100 : 150)); - - CallOutBox::launchAsynchronously (content, avatarButton.getScreenBounds(), nullptr); - } - } - - const uint32 backgroundColour = 0xff414141; - std::unique_ptr<Drawable> juceLogo { Drawable::createFromImageData (BinaryData::jucelogowithtext_svg, - BinaryData::jucelogowithtext_svgSize) }; - IconButton avatarButton; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Header) - }; - - //============================================================================== - public: - LicenseWebviewContent (LicenseWebview& parentWindowToUse, ModalComponentManager::Callback* callbackToUse) - : parentWindow (parentWindowToUse), modalCallback (callbackToUse), webview (*this) - { - addAndMakeVisible (header); - addAndMakeVisible (webview); - - setOpaque (true); - setSize (978, 718); - - #if JUCE_WINDOWS // windows needs the webcomponent be visible - parentWindow.enterModalState (true, modalCallback.release(), true); - #endif - } - - void goToURL (const String& request) - { - lastURL = request; - webview.goToURL (lastURL); - } - - void paint (Graphics& g) override { g.fillAll (Colours::lightblue); } - - void resized() override - { - auto r = getLocalBounds(); - header.setBounds (r.removeFromTop (78)); - webview.setBounds (r); - } - - bool pageAboutToLoad (const String& page) - { - URL url (page); - - if (page == "about:blank" || page.startsWith ("file://") || page.startsWith ("data:text/html")) - { - if (page != lastErrorPageURI) - lastURL = page; - - return true; - } - else if (url.getScheme() == "projucer") - { - HashMap<String, String> params; - - auto n = url.getParameterNames().size(); - - for (int i = 0; i < n; ++i) - params.set (url.getParameterNames()[i], url.getParameterValues()[i]); - - String cmd (url.getDomain()); - - if (n == 0 && cmd.containsChar (L'=')) - { - // old-style callback - StringArray domainTokens (StringArray::fromTokens (cmd, "=", "")); - cmd = domainTokens[0]; - - params.set (cmd, domainTokens[1]); - } - - if (pageCallback) - pageCallback (cmd, params); - - return false; - } - - bool isValid = (url.getDomain().endsWith ("roli.com") || url.getDomain().endsWith ("juce.com")); - - if (isValid) - lastURL = page; - - return true; - } - - void pageFinishedLoading (const String& page) - { - URL url (page); - - if ((isValidURL (url) - || page.startsWith ("file://") || page.startsWith ("data:text/html")) - && ! parentWindow.isCurrentlyModal()) - parentWindow.enterModalState (true, modalCallback.release(), true); - } - - void newWindowAttemptingToLoad (const String& page) - { - URL url (page); - bool isGitHub = url.getDomain().endsWith ("github.com"); - - if (url.getDomain().endsWith ("roli.com") - || url.getDomain().endsWith ("juce.com") - || isGitHub) - { - url.launchInDefaultBrowser(); - - if (newWindowCallback && ! isGitHub) - newWindowCallback (page); - } - } - - bool pageLoadHadNetworkError (const String&) - { - String errorPageSource = String (BinaryData::offlinepage_html, BinaryData::offlinepage_htmlSize) - .replace ("__URL_PLACEHOLDER__", lastURL); - - #if JUCE_WINDOWS - auto tmpFile = File::createTempFile (".html"); - tmpFile.replaceWithText (errorPageSource, true); - - lastErrorPageURI = "file://" + tmpFile.getFullPathName(); - #else - lastErrorPageURI = "data:text/html;base64," + Base64::toBase64 (errorPageSource); - #endif - - goToURL (lastErrorPageURI); - - return false; - } - - static bool isValidURL (const URL& url) { return (url.getDomain().endsWith ("roli.com") || url.getDomain().endsWith ("juce.com")); } - - //============================================================================== - LicenseWebview& parentWindow; - std::unique_ptr<ModalComponentManager::Callback> modalCallback; - Header header; - RedirectWebBrowserComponent webview; - std::function<void (const String&, const HashMap<String, String>&)> pageCallback; - std::function<void (const String&)> newWindowCallback; - String lastURL, lastErrorPageURI; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LicenseWebviewContent) - }; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LicenseWebview) -}; diff --git a/extras/Projucer/Source/LiveBuildEngine/UI/jucer_ActivityListComponent.h b/extras/Projucer/Source/LiveBuildEngine/UI/jucer_ActivityListComponent.h index 70831aeb..839e8c95 100644 --- a/extras/Projucer/Source/LiveBuildEngine/UI/jucer_ActivityListComponent.h +++ b/extras/Projucer/Source/LiveBuildEngine/UI/jucer_ActivityListComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -66,7 +65,7 @@ public: { g.setColour (findColour (defaultTextColourId)); - g.setFont (height * 0.7f); + g.setFont ((float) height * 0.7f); g.drawText (activities [rowNumber], 4, 0, width - 5, height, Justification::centredLeft, true); } diff --git a/extras/Projucer/Source/LiveBuildEngine/UI/jucer_BuildTabStatusComponent.h b/extras/Projucer/Source/LiveBuildEngine/UI/jucer_BuildTabStatusComponent.h index 689090e4..7528954e 100644 --- a/extras/Projucer/Source/LiveBuildEngine/UI/jucer_BuildTabStatusComponent.h +++ b/extras/Projucer/Source/LiveBuildEngine/UI/jucer_BuildTabStatusComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/LiveBuildEngine/UI/jucer_ComponentListComponent.h b/extras/Projucer/Source/LiveBuildEngine/UI/jucer_ComponentListComponent.h index d8c15425..0b89f447 100644 --- a/extras/Projucer/Source/LiveBuildEngine/UI/jucer_ComponentListComponent.h +++ b/extras/Projucer/Source/LiveBuildEngine/UI/jucer_ComponentListComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/LiveBuildEngine/UI/jucer_ErrorListComponent.h b/extras/Projucer/Source/LiveBuildEngine/UI/jucer_ErrorListComponent.h index ccc88afa..caad6dfe 100644 --- a/extras/Projucer/Source/LiveBuildEngine/UI/jucer_ErrorListComponent.h +++ b/extras/Projucer/Source/LiveBuildEngine/UI/jucer_ErrorListComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/LiveBuildEngine/jucer_ActivityList.h b/extras/Projucer/Source/LiveBuildEngine/jucer_ActivityList.h index 90efe242..107664ea 100644 --- a/extras/Projucer/Source/LiveBuildEngine/jucer_ActivityList.h +++ b/extras/Projucer/Source/LiveBuildEngine/jucer_ActivityList.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/LiveBuildEngine/jucer_ClassDatabase.h b/extras/Projucer/Source/LiveBuildEngine/jucer_ClassDatabase.h index 64a6f398..173f7bbf 100644 --- a/extras/Projucer/Source/LiveBuildEngine/jucer_ClassDatabase.h +++ b/extras/Projucer/Source/LiveBuildEngine/jucer_ClassDatabase.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -209,12 +208,6 @@ struct ClassDatabase noDefaultConstructor (false) {} - InstantiationFlags (const InstantiationFlags& other) - : isAbstract (other.isAbstract), - inAnonymousNamespace (other.inAnonymousNamespace), - noDefaultConstructor (other.noDefaultConstructor) - {} - bool canBeInstantiated() const noexcept { return ! (isAbstract || inAnonymousNamespace || noDefaultConstructor); diff --git a/extras/Projucer/Source/LiveBuildEngine/jucer_ClientServerMessages.h b/extras/Projucer/Source/LiveBuildEngine/jucer_ClientServerMessages.h index 0a0fe6a1..2fa64228 100644 --- a/extras/Projucer/Source/LiveBuildEngine/jucer_ClientServerMessages.h +++ b/extras/Projucer/Source/LiveBuildEngine/jucer_ClientServerMessages.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -89,13 +88,10 @@ namespace MessageTypes { inline bool send (MessageHandler& target, const ValueTree& v) { - //DBG ("Send: " << v.getType().toString()); bool result = target.sendMessage (v); if (! result) - { - DBG ("*** Message failed: " << v.getType().toString()); - } + Logger::outputDebugString ("*** Message failed: " + v.getType().toString()); return result; } diff --git a/extras/Projucer/Source/LiveBuildEngine/jucer_CompileEngineClient.cpp b/extras/Projucer/Source/LiveBuildEngine/jucer_CompileEngineClient.cpp index fdaa55c4..1ce5ba57 100644 --- a/extras/Projucer/Source/LiveBuildEngine/jucer_CompileEngineClient.cpp +++ b/extras/Projucer/Source/LiveBuildEngine/jucer_CompileEngineClient.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -37,6 +36,7 @@ #include "jucer_CompileEngineClient.h" #include "jucer_CompileEngineServer.h" #include "jucer_CompileEngineSettings.h" +#include "../Project/UI/jucer_ProjectContentComponent.h" #ifndef RUN_CLANG_IN_CHILD_PROCESS #error @@ -69,7 +69,7 @@ class ClientIPC : public MessageHandler, private Timer { public: - ClientIPC (CompileEngineChildProcess& cp) + explicit ClientIPC (CompileEngineChildProcess& cp) : InterprocessConnection (true), owner (cp) { launchServer(); @@ -216,8 +216,6 @@ public: if (isRunningApp && server != nullptr) server->killServerWithoutMercy(); - - server.reset(); } void restartServer() @@ -313,24 +311,31 @@ private: String getGlobalDefs() { - StringArray defs; - - defs.add (project.getCompileEngineSettings().getExtraPreprocessorDefsString()); - + auto mergeDefs = [] (const StringPairArray& inDefs) -> String { - auto projectDefines = project.getPreprocessorDefs(); + StringArray outDefs; - for (int i = 0; i < projectDefines.size(); ++i) + for (int i = 0; i < inDefs.size(); ++i) { - auto def = projectDefines.getAllKeys()[i]; - auto value = projectDefines.getAllValues()[i]; + auto def = inDefs.getAllKeys()[i]; + auto value = inDefs.getAllValues()[i]; if (value.isNotEmpty()) def << "=" << value; - defs.add (def); + outDefs.add (def); } - } + + return outDefs.joinIntoString (" "); + }; + + StringArray defs; + + if (! project.shouldUseAppConfig()) + defs.add (mergeDefs (project.getAppConfigDefs())); + + defs.add (project.getCompileEngineSettings().getExtraPreprocessorDefsString()); + defs.add (mergeDefs (project.getPreprocessorDefs())); for (Project::ExporterIterator exporter (project); exporter.next();) if (exporter->canLaunchProject()) @@ -375,7 +380,7 @@ private: { auto isVSTHost = project.getEnabledModules().isModuleEnabled ("juce_audio_processors") - && (project.isConfigFlagEnabled ("JUCE_PLUGINHOST_VST3") || project.isConfigFlagEnabled ("JUCE_PLUGINHOST_VST")); + && (project.isConfigFlagEnabled ("JUCE_PLUGINHOST_VST3", false) || project.isConfigFlagEnabled ("JUCE_PLUGINHOST_VST", false)); auto isPluginProject = proj.isAudioPluginProject(); @@ -394,11 +399,12 @@ private: : m->moduleInfo.getFolder(); m->findAndAddCompiledUnits (*exporter, nullptr, compileUnits, - isPluginProject || isVSTHost ? ProjectType::Target::SharedCodeTarget - : ProjectType::Target::unspecified); + isPluginProject || isVSTHost ? build_tools::ProjectType::Target::SharedCodeTarget + : build_tools::ProjectType::Target::unspecified); if (isPluginProject || isVSTHost) - m->findAndAddCompiledUnits (*exporter, nullptr, compileUnits, ProjectType::Target::StandalonePlugIn); + m->findAndAddCompiledUnits (*exporter, nullptr, compileUnits, + build_tools::ProjectType::Target::StandalonePlugIn); } break; @@ -463,13 +469,8 @@ private: paths.addArray (getSearchPathsFromString (project.getCompileEngineSettings().getSystemHeaderPathString())); auto isVSTHost = project.getEnabledModules().isModuleEnabled ("juce_audio_processors") - && (project.isConfigFlagEnabled ("JUCE_PLUGINHOST_VST3") - || project.isConfigFlagEnabled ("JUCE_PLUGINHOST_VST")); - - auto customVst3Path = getAppSettings().getStoredPath (Ids::vst3Path, TargetOS::getThisOS()).get().toString(); - - if (customVst3Path.isNotEmpty() && (project.isAudioPluginProject() || isVSTHost)) - paths.add (customVst3Path); + && (project.isConfigFlagEnabled ("JUCE_PLUGINHOST_VST3", false) + || project.isConfigFlagEnabled ("JUCE_PLUGINHOST_VST", false)); OwnedArray<LibraryModule> modules; project.getEnabledModules().createRequiredModules (modules); @@ -478,9 +479,11 @@ private: { paths.addIfNotAlreadyThere (module->getFolder().getParentDirectory().getFullPathName()); - if (customVst3Path.isEmpty() && (project.isAudioPluginProject() || isVSTHost)) - if (module->getID() == "juce_audio_processors") - paths.addIfNotAlreadyThere (module->getFolder().getChildFile ("format_types").getChildFile ("VST3_SDK").getFullPathName()); + if (module->getID() == "juce_audio_processors" && ((project.isAudioPluginProject() || isVSTHost) + && ! project.isConfigFlagEnabled ("JUCE_CUSTOM_VST3_SDK"))) + { + paths.addIfNotAlreadyThere (module->getFolder().getChildFile ("format_types").getChildFile ("VST3_SDK").getFullPathName()); + } } return convertSearchPathsToAbsolute (paths); @@ -521,9 +524,6 @@ CompileEngineChildProcess::CompileEngineChildProcess (Project& p) CompileEngineChildProcess::~CompileEngineChildProcess() { ProjucerApplication::getApp().openDocumentManager.removeListener (this); - - process.reset(); - lastComponentList.clear(); } void CompileEngineChildProcess::createProcess() @@ -719,7 +719,7 @@ private: struct TransactionTimer : public Timer { - TransactionTimer (CodeDocument& doc) : document (doc) {} + explicit TransactionTimer (CodeDocument& doc) : document (doc) {} void timerCallback() override { diff --git a/extras/Projucer/Source/LiveBuildEngine/jucer_CompileEngineClient.h b/extras/Projucer/Source/LiveBuildEngine/jucer_CompileEngineClient.h index 4c990c3c..bce7b5ea 100644 --- a/extras/Projucer/Source/LiveBuildEngine/jucer_CompileEngineClient.h +++ b/extras/Projucer/Source/LiveBuildEngine/jucer_CompileEngineClient.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/LiveBuildEngine/jucer_CompileEngineDLL.h b/extras/Projucer/Source/LiveBuildEngine/jucer_CompileEngineDLL.h index b88e71dd..347880c9 100644 --- a/extras/Projucer/Source/LiveBuildEngine/jucer_CompileEngineDLL.h +++ b/extras/Projucer/Source/LiveBuildEngine/jucer_CompileEngineDLL.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/LiveBuildEngine/jucer_CompileEngineServer.cpp b/extras/Projucer/Source/LiveBuildEngine/jucer_CompileEngineServer.cpp index 1f809f7c..20ed871d 100644 --- a/extras/Projucer/Source/LiveBuildEngine/jucer_CompileEngineServer.cpp +++ b/extras/Projucer/Source/LiveBuildEngine/jucer_CompileEngineServer.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -52,6 +51,8 @@ #if JUCE_WINDOWS static void setParentProcessID (int); static int getCurrentProcessID(); +#else + #include <unistd.h> #endif //============================================================================== @@ -60,7 +61,7 @@ struct ZombiePatrol : private Thread, private AsyncUpdater, private Timer { - ZombiePatrol (MessageHandler& mh) + explicit ZombiePatrol (MessageHandler& mh) : Thread ("Ping"), owner (mh) { startThread (2); @@ -141,7 +142,7 @@ class ServerIPC : public InterprocessConnection, public MessageHandler { public: - ServerIPC (const StringArray& info) + explicit ServerIPC (const StringArray& info) : InterprocessConnection (true), liveCodeBuilder (nullptr) { if (! createPipe (info[0], -1)) @@ -289,7 +290,7 @@ void sendQuitMessageToIDE (void* server) #define WIN32_LEAN_AND_MEAN 1 #include <windows.h> - static HANDLE parentProcessHandle = 0; + static HANDLE parentProcessHandle = nullptr; static void setParentProcessID (int pid) { parentProcessHandle = OpenProcess (SYNCHRONIZE, FALSE, (DWORD) pid); } static int getCurrentProcessID() { return (int) GetCurrentProcessId(); } #endif diff --git a/extras/Projucer/Source/LiveBuildEngine/jucer_CompileEngineServer.h b/extras/Projucer/Source/LiveBuildEngine/jucer_CompileEngineServer.h index 23fcc4a9..a78cab13 100644 --- a/extras/Projucer/Source/LiveBuildEngine/jucer_CompileEngineServer.h +++ b/extras/Projucer/Source/LiveBuildEngine/jucer_CompileEngineServer.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/LiveBuildEngine/jucer_CompileEngineSettings.h b/extras/Projucer/Source/LiveBuildEngine/jucer_CompileEngineSettings.h index fbb25286..9619ccf0 100644 --- a/extras/Projucer/Source/LiveBuildEngine/jucer_CompileEngineSettings.h +++ b/extras/Projucer/Source/LiveBuildEngine/jucer_CompileEngineSettings.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/LiveBuildEngine/jucer_CppHelpers.h b/extras/Projucer/Source/LiveBuildEngine/jucer_CppHelpers.h index cc5c3270..9fc2e510 100644 --- a/extras/Projucer/Source/LiveBuildEngine/jucer_CppHelpers.h +++ b/extras/Projucer/Source/LiveBuildEngine/jucer_CppHelpers.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -53,7 +52,7 @@ struct CppParserHelpers for (int i = 0; i < text.length(); ++i) { - const int digit = text[i] - '0'; + const auto digit = (int) (text[i] - '0'); if (digit < 0 || digit > 7) break; diff --git a/extras/Projucer/Source/LiveBuildEngine/jucer_DiagnosticMessage.h b/extras/Projucer/Source/LiveBuildEngine/jucer_DiagnosticMessage.h index 252855cc..a62fe1ce 100644 --- a/extras/Projucer/Source/LiveBuildEngine/jucer_DiagnosticMessage.h +++ b/extras/Projucer/Source/LiveBuildEngine/jucer_DiagnosticMessage.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -79,6 +78,7 @@ struct DiagnosticMessage case error: res << "error: "; break; case warning: res << "warning: "; break; case note: res << "note: "; break; + default: break; }; res << mainFile << ": "; diff --git a/extras/Projucer/Source/LiveBuildEngine/jucer_DownloadCompileEngineThread.cpp b/extras/Projucer/Source/LiveBuildEngine/jucer_DownloadCompileEngineThread.cpp index 5b657500..1cb63f68 100644 --- a/extras/Projucer/Source/LiveBuildEngine/jucer_DownloadCompileEngineThread.cpp +++ b/extras/Projucer/Source/LiveBuildEngine/jucer_DownloadCompileEngineThread.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/LiveBuildEngine/jucer_DownloadCompileEngineThread.h b/extras/Projucer/Source/LiveBuildEngine/jucer_DownloadCompileEngineThread.h index fd210a40..b8b14603 100644 --- a/extras/Projucer/Source/LiveBuildEngine/jucer_DownloadCompileEngineThread.h +++ b/extras/Projucer/Source/LiveBuildEngine/jucer_DownloadCompileEngineThread.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/LiveBuildEngine/jucer_ErrorList.h b/extras/Projucer/Source/LiveBuildEngine/jucer_ErrorList.h index 21878217..a3b8d808 100644 --- a/extras/Projucer/Source/LiveBuildEngine/jucer_ErrorList.h +++ b/extras/Projucer/Source/LiveBuildEngine/jucer_ErrorList.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/LiveBuildEngine/jucer_LiveCodeBuilderDLL.h b/extras/Projucer/Source/LiveBuildEngine/jucer_LiveCodeBuilderDLL.h index c092ad98..b29517f6 100644 --- a/extras/Projucer/Source/LiveBuildEngine/jucer_LiveCodeBuilderDLL.h +++ b/extras/Projucer/Source/LiveBuildEngine/jucer_LiveCodeBuilderDLL.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/LiveBuildEngine/jucer_MessageIDs.h b/extras/Projucer/Source/LiveBuildEngine/jucer_MessageIDs.h index 9cfe134e..bd8040fe 100644 --- a/extras/Projucer/Source/LiveBuildEngine/jucer_MessageIDs.h +++ b/extras/Projucer/Source/LiveBuildEngine/jucer_MessageIDs.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -26,10 +25,11 @@ #pragma once -#define DECLARE_ID(name) static const Identifier name (#name) namespace MessageTypes { + #define DECLARE_ID(name) const Identifier name (#name) + DECLARE_ID (PING); DECLARE_ID (BUILDINFO); DECLARE_ID (COMPILEUNIT); @@ -58,6 +58,6 @@ namespace MessageTypes DECLARE_ID (LAUNCH_APP); DECLARE_ID (FOREGROUND); DECLARE_ID (QUIT_SERVER); -} -#undef DECLARE_ID + #undef DECLARE_ID +} diff --git a/extras/Projucer/Source/LiveBuildEngine/jucer_ProjectBuildInfo.h b/extras/Projucer/Source/LiveBuildEngine/jucer_ProjectBuildInfo.h index 5b62e3c3..6daaf87f 100644 --- a/extras/Projucer/Source/LiveBuildEngine/jucer_ProjectBuildInfo.h +++ b/extras/Projucer/Source/LiveBuildEngine/jucer_ProjectBuildInfo.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/LiveBuildEngine/jucer_SourceCodeRange.h b/extras/Projucer/Source/LiveBuildEngine/jucer_SourceCodeRange.h index 7befcd13..5596252e 100644 --- a/extras/Projucer/Source/LiveBuildEngine/jucer_SourceCodeRange.h +++ b/extras/Projucer/Source/LiveBuildEngine/jucer_SourceCodeRange.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/Project/Modules/jucer_AvailableModulesList.h b/extras/Projucer/Source/Project/Modules/jucer_AvailableModulesList.h new file mode 100644 index 00000000..c091b302 --- /dev/null +++ b/extras/Projucer/Source/Project/Modules/jucer_AvailableModulesList.h @@ -0,0 +1,207 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +#pragma once + +#include "jucer_ModuleDescription.h" + +//============================================================================== +class AvailableModulesList : private AsyncUpdater +{ +public: + using ModuleIDAndFolder = std::pair<String, File>; + using ModuleIDAndFolderList = std::vector<ModuleIDAndFolder>; + + AvailableModulesList() = default; + + //============================================================================== + void scanPaths (const Array<File>& paths) + { + auto job = createScannerJob (paths); + auto& ref = *job; + + removePendingAndAddJob (std::move (job)); + scanPool.waitForJobToFinish (&ref, -1); + } + + void scanPathsAsync (const Array<File>& paths) + { + removePendingAndAddJob (createScannerJob (paths)); + } + + //============================================================================== + ModuleIDAndFolderList getAllModules() const + { + const ScopedLock readLock (lock); + return modulesList; + } + + ModuleIDAndFolder getModuleWithID (const String& id) const + { + const ScopedLock readLock (lock); + + for (auto& mod : modulesList) + if (mod.first == id) + return mod; + + return {}; + } + + //============================================================================== + void removeDuplicates (const ModuleIDAndFolderList& other) + { + const ScopedLock readLock (lock); + + const auto predicate = [&] (const ModuleIDAndFolder& entry) + { + return std::find (other.begin(), other.end(), entry) != other.end(); + }; + + modulesList.erase (std::remove_if (modulesList.begin(), modulesList.end(), predicate), + modulesList.end()); + } + + //============================================================================== + struct Listener + { + virtual ~Listener() = default; + virtual void availableModulesChanged (AvailableModulesList* listThatHasChanged) = 0; + }; + + void addListener (Listener* listenerToAdd) { listeners.add (listenerToAdd); } + void removeListener (Listener* listenerToRemove) { listeners.remove (listenerToRemove); } + +private: + //============================================================================== + struct ModuleScannerJob : public ThreadPoolJob + { + ModuleScannerJob (const Array<File>& paths, + std::function<void (const ModuleIDAndFolderList&)>&& callback) + : ThreadPoolJob ("ModuleScannerJob"), + pathsToScan (paths), + completionCallback (std::move (callback)) + { + } + + JobStatus runJob() override + { + ModuleIDAndFolderList list; + + for (auto& p : pathsToScan) + addAllModulesInFolder (p, list); + + if (! shouldExit()) + { + std::sort (list.begin(), list.end(), [] (const ModuleIDAndFolder& m1, + const ModuleIDAndFolder& m2) + { + return m1.first.compareIgnoreCase (m2.first) < 0; + }); + + completionCallback (list); + } + + return jobHasFinished; + } + + static bool tryToAddModuleFromFolder (const File& path, ModuleIDAndFolderList& list) + { + ModuleDescription m (path); + + if (m.isValid()) + { + list.push_back ({ m.getID(), path }); + return true; + } + + return false; + } + + static void addAllModulesInSubfoldersRecursively (const File& path, int depth, ModuleIDAndFolderList& list) + { + if (depth > 0) + { + for (const auto& iter : RangedDirectoryIterator (path, false, "*", File::findDirectories)) + { + if (auto* job = ThreadPoolJob::getCurrentThreadPoolJob()) + if (job->shouldExit()) + return; + + auto childPath = iter.getFile(); + + if (! tryToAddModuleFromFolder (childPath, list)) + addAllModulesInSubfoldersRecursively (childPath, depth - 1, list); + } + } + } + + static void addAllModulesInFolder (const File& path, ModuleIDAndFolderList& list) + { + if (! tryToAddModuleFromFolder (path, list)) + { + constexpr int subfolders = 3; + addAllModulesInSubfoldersRecursively (path, subfolders, list); + } + } + + Array<File> pathsToScan; + std::function<void (const ModuleIDAndFolderList&)> completionCallback; + }; + + //============================================================================== + void handleAsyncUpdate() override + { + listeners.call ([this] (Listener& l) { l.availableModulesChanged (this); }); + } + + std::unique_ptr<ThreadPoolJob> createScannerJob (const Array<File>& paths) + { + return std::make_unique<ModuleScannerJob> (paths, [this] (ModuleIDAndFolderList scannedModulesList) + { + { + const ScopedLock swapLock (lock); + modulesList.swap (scannedModulesList); + } + + triggerAsyncUpdate(); + }); + } + + void removePendingAndAddJob (std::unique_ptr<ThreadPoolJob> jobToAdd) + { + scanPool.removeAllJobs (false, 100); + scanPool.addJob (jobToAdd.release(), true); + } + + //============================================================================== + ThreadPool scanPool { 1 }; + + ModuleIDAndFolderList modulesList; + ListenerList<Listener> listeners; + CriticalSection lock; + + //============================================================================== + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AvailableModulesList) +}; diff --git a/extras/Projucer/Source/Project/Modules/jucer_ModuleDescription.h b/extras/Projucer/Source/Project/Modules/jucer_ModuleDescription.h new file mode 100644 index 00000000..6cb1e70e --- /dev/null +++ b/extras/Projucer/Source/Project/Modules/jucer_ModuleDescription.h @@ -0,0 +1,93 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +#pragma once + + +//============================================================================== +class ModuleDescription +{ +public: + ModuleDescription() = default; + + ModuleDescription (const File& folder) + : moduleFolder (folder), + moduleInfo (parseJUCEHeaderMetadata (getHeader())) + { + } + + bool isValid() const { return getID().isNotEmpty(); } + + String getID() const { return moduleInfo [Ids::ID_uppercase].toString(); } + String getVendor() const { return moduleInfo [Ids::vendor].toString(); } + String getVersion() const { return moduleInfo [Ids::version].toString(); } + String getName() const { return moduleInfo [Ids::name].toString(); } + String getDescription() const { return moduleInfo [Ids::description].toString(); } + String getLicense() const { return moduleInfo [Ids::license].toString(); } + String getMinimumCppStandard() const { return moduleInfo [Ids::minimumCppStandard].toString(); } + String getPreprocessorDefs() const { return moduleInfo [Ids::defines].toString(); } + String getExtraSearchPaths() const { return moduleInfo [Ids::searchpaths].toString(); } + var getModuleInfo() const { return moduleInfo; } + File getModuleFolder() const { return moduleFolder; } + + File getFolder() const + { + jassert (moduleFolder != File()); + + return moduleFolder; + } + + File getHeader() const + { + if (moduleFolder != File()) + { + static const char* extensions[] = { ".h", ".hpp", ".hxx" }; + + for (auto e : extensions) + { + auto header = moduleFolder.getChildFile (moduleFolder.getFileName() + e); + + if (header.existsAsFile()) + return header; + } + } + + return {}; + } + + StringArray getDependencies() const + { + auto moduleDependencies = StringArray::fromTokens (moduleInfo ["dependencies"].toString(), " \t;,", "\"'"); + moduleDependencies.trim(); + moduleDependencies.removeEmptyStrings(); + + return moduleDependencies; + } + +private: + File moduleFolder; + var moduleInfo; + URL url; +}; diff --git a/extras/Projucer/Source/Project/jucer_Module.cpp b/extras/Projucer/Source/Project/Modules/jucer_Modules.cpp similarity index 62% rename from extras/Projucer/Source/Project/jucer_Module.cpp rename to extras/Projucer/Source/Project/Modules/jucer_Modules.cpp index f5ea011b..a62f1875 100644 --- a/extras/Projucer/Source/Project/jucer_Module.cpp +++ b/extras/Projucer/Source/Project/Modules/jucer_Modules.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -24,182 +23,10 @@ ============================================================================== */ -#include "../Application/jucer_Headers.h" -#include "../ProjectSaving/jucer_ProjectSaver.h" -#include "../ProjectSaving/jucer_ProjectExport_Xcode.h" -#include "../Application/jucer_Application.h" - -//============================================================================== -ModuleDescription::ModuleDescription (const File& folder) - : moduleFolder (folder), - moduleInfo (parseJUCEHeaderMetadata (getHeader())) -{ -} - -File ModuleDescription::getHeader() const -{ - if (moduleFolder != File()) - { - static const char* extensions[] = { ".h", ".hpp", ".hxx" }; - - for (auto e : extensions) - { - auto header = moduleFolder.getChildFile (moduleFolder.getFileName() + e); - - if (header.existsAsFile()) - return header; - } - } - - return {}; -} - -StringArray ModuleDescription::getDependencies() const -{ - auto moduleDependencies = StringArray::fromTokens (moduleInfo ["dependencies"].toString(), " \t;,", "\"'"); - moduleDependencies.trim(); - moduleDependencies.removeEmptyStrings(); - - return moduleDependencies; -} - -//============================================================================== -static bool tryToAddModuleFromFolder (const File& path, AvailableModuleList::ModuleIDAndFolderList& list) -{ - ModuleDescription m (path); - - if (m.isValid()) - { - list.push_back ({ m.getID(), path }); - return true; - } - - return false; -} - -static void addAllModulesInSubfoldersRecursively (const File& path, int depth, AvailableModuleList::ModuleIDAndFolderList& list) -{ - if (depth > 0) - { - for (DirectoryIterator iter (path, false, "*", File::findDirectories); iter.next();) - { - if (auto* job = ThreadPoolJob::getCurrentThreadPoolJob()) - if (job->shouldExit()) - return; - - auto childPath = iter.getFile(); - - if (! tryToAddModuleFromFolder (childPath, list)) - addAllModulesInSubfoldersRecursively (childPath, depth - 1, list); - } - } -} - -static void addAllModulesInFolder (const File& path, AvailableModuleList::ModuleIDAndFolderList& list) -{ - if (! tryToAddModuleFromFolder (path, list)) - { - static constexpr int subfolders = 3; - addAllModulesInSubfoldersRecursively (path, subfolders, list); - } -} - -struct ModuleScannerJob : public ThreadPoolJob -{ - ModuleScannerJob (const Array<File>& paths, - std::function<void (const AvailableModuleList::ModuleIDAndFolderList&)>&& callback) - : ThreadPoolJob ("ModuleScannerJob"), - pathsToScan (paths), - completionCallback (std::move (callback)) - { - } - - JobStatus runJob() override - { - AvailableModuleList::ModuleIDAndFolderList list; - - for (auto& p : pathsToScan) - addAllModulesInFolder (p, list); - - if (! shouldExit()) - { - std::sort (list.begin(), list.end(), [] (const AvailableModuleList::ModuleIDAndFolder& m1, - const AvailableModuleList::ModuleIDAndFolder& m2) - { - return m1.first.compareIgnoreCase (m2.first) < 0; - }); - - completionCallback (list); - } - - return jobHasFinished; - } - - Array<File> pathsToScan; - std::function<void (const AvailableModuleList::ModuleIDAndFolderList&)> completionCallback; -}; - -ThreadPoolJob* AvailableModuleList::createScannerJob (const Array<File>& paths) -{ - return new ModuleScannerJob (paths, [this] (AvailableModuleList::ModuleIDAndFolderList scannedModuleList) - { - { - const ScopedLock swapLock (lock); - moduleList.swap (scannedModuleList); - } - - listeners.call ([] (Listener& l) { MessageManager::callAsync ([&] { l.availableModulesChanged(); }); }); - }); -} - -void AvailableModuleList::removePendingAndAddJob (ThreadPoolJob* jobToAdd) -{ - scanPool.removeAllJobs (false, 100); - scanPool.addJob (jobToAdd, true); -} - -void AvailableModuleList::scanPaths (const Array<File>& paths) -{ - auto* job = createScannerJob (paths); - - removePendingAndAddJob (job); - scanPool.waitForJobToFinish (job, -1); -} - -void AvailableModuleList::scanPathsAsync (const Array<File>& paths) -{ - removePendingAndAddJob (createScannerJob (paths)); -} - -AvailableModuleList::ModuleIDAndFolderList AvailableModuleList::getAllModules() const -{ - const ScopedLock readLock (lock); - return moduleList; -} - -AvailableModuleList::ModuleIDAndFolder AvailableModuleList::getModuleWithID (const String& id) const -{ - const ScopedLock readLock (lock); - - for (auto& mod : moduleList) - if (mod.first == id) - return mod; - - return {}; -} - -void AvailableModuleList::removeDuplicates (const ModuleIDAndFolderList& other) -{ - const ScopedLock readLock (lock); - - for (auto& m : other) - { - auto pos = std::find (moduleList.begin(), moduleList.end(), m); - - if (pos != moduleList.end()) - moduleList.erase (pos); - } -} +#include "../../Application/jucer_Headers.h" +#include "../../ProjectSaving/jucer_ProjectSaver.h" +#include "../../ProjectSaving/jucer_ProjectExport_Xcode.h" +#include "../../Application/jucer_Application.h" //============================================================================== LibraryModule::LibraryModule (const ModuleDescription& d) @@ -209,7 +36,7 @@ LibraryModule::LibraryModule (const ModuleDescription& d) void LibraryModule::writeIncludes (ProjectSaver& projectSaver, OutputStream& out) { - auto& project = projectSaver.project; + auto& project = projectSaver.getProject(); auto& modules = project.getEnabledModules(); auto moduleID = getID(); @@ -223,7 +50,7 @@ void LibraryModule::writeIncludes (ProjectSaver& projectSaver, OutputStream& out projectSaver.copyFolder (juceModuleFolder, localModuleFolder); } - out << "#include <" << moduleInfo.moduleFolder.getFileName() << "/" + out << "#include <" << moduleInfo.getModuleFolder().getFileName() << "/" << moduleInfo.getHeader().getFileName() << ">" << newLine; } @@ -308,26 +135,26 @@ void LibraryModule::addLibsToExporter (ProjectExporter& exporter) const xcodeExporter.xcodeFrameworks.add ("AudioUnit"); } - auto frameworks = moduleInfo.moduleInfo [xcodeExporter.isOSX() ? "OSXFrameworks" : "iOSFrameworks"].toString(); + auto frameworks = moduleInfo.getModuleInfo() [xcodeExporter.isOSX() ? "OSXFrameworks" : "iOSFrameworks"].toString(); xcodeExporter.xcodeFrameworks.addTokens (frameworks, ", ", {}); - parseAndAddLibsToList (xcodeExporter.xcodeLibs, moduleInfo.moduleInfo [exporter.isOSX() ? "OSXLibs" : "iOSLibs"].toString()); + parseAndAddLibsToList (xcodeExporter.xcodeLibs, moduleInfo.getModuleInfo() [exporter.isOSX() ? "OSXLibs" : "iOSLibs"].toString()); } else if (exporter.isLinux()) { - parseAndAddLibsToList (exporter.linuxLibs, moduleInfo.moduleInfo ["linuxLibs"].toString()); - parseAndAddLibsToList (exporter.linuxPackages, moduleInfo.moduleInfo ["linuxPackages"].toString()); + parseAndAddLibsToList (exporter.linuxLibs, moduleInfo.getModuleInfo() ["linuxLibs"].toString()); + parseAndAddLibsToList (exporter.linuxPackages, moduleInfo.getModuleInfo() ["linuxPackages"].toString()); } else if (exporter.isWindows()) { if (exporter.isCodeBlocks()) - parseAndAddLibsToList (exporter.mingwLibs, moduleInfo.moduleInfo ["mingwLibs"].toString()); + parseAndAddLibsToList (exporter.mingwLibs, moduleInfo.getModuleInfo() ["mingwLibs"].toString()); else - parseAndAddLibsToList (exporter.windowsLibs, moduleInfo.moduleInfo ["windowsLibs"].toString()); + parseAndAddLibsToList (exporter.windowsLibs, moduleInfo.getModuleInfo() ["windowsLibs"].toString()); } else if (exporter.isAndroid()) { - parseAndAddLibsToList (exporter.androidLibs, moduleInfo.moduleInfo ["androidLibs"].toString()); + parseAndAddLibsToList (exporter.androidLibs, moduleInfo.getModuleInfo() ["androidLibs"].toString()); } } @@ -391,7 +218,7 @@ void LibraryModule::getConfigFlags (Project& project, OwnedArray<Project::Config } } -static void addFileWithGroups (Project::Item& group, const RelativePath& file, const String& path) +static void addFileWithGroups (Project::Item& group, const build_tools::RelativePath& file, const String& path) { auto slash = path.indexOfChar (File::getSeparatorChar()); @@ -423,11 +250,8 @@ void LibraryModule::findBrowseableFiles (const File& folder, Array<File>& filesF Array<File> tempList; FileSorter sorter; - DirectoryIterator iter (folder, true, "*", File::findFiles); - bool isHiddenFile; - - while (iter.next (nullptr, &isHiddenFile, nullptr, nullptr, nullptr, nullptr)) - if (! isHiddenFile && iter.getFile().hasFileExtension (browseableFileExtensions)) + for (const auto& iter : RangedDirectoryIterator (folder, true, "*", File::findFiles)) + if (! iter.isHidden() && iter.getFile().hasFileExtension (browseableFileExtensions)) tempList.addSorted (sorter, iter.getFile()); filesFound.addArray (tempList); @@ -444,7 +268,7 @@ bool LibraryModule::CompileUnit::isNeededForExporter (ProjectExporter& exporter) auto targetType = Project::getTargetTypeFromFilePath (file, false); - if (targetType != ProjectType::Target::unspecified && ! exporter.shouldBuildTargetType (targetType)) + if (targetType != build_tools::ProjectType::Target::unspecified && ! exporter.shouldBuildTargetType (targetType)) return false; return exporter.usesMMFiles() ? isCompiledForObjC @@ -464,7 +288,7 @@ bool LibraryModule::CompileUnit::hasSuffix (const File& f, const char* suffix) || fileWithoutSuffix.containsIgnoreCase (suffix + String ("_")); } -Array<LibraryModule::CompileUnit> LibraryModule::getAllCompileUnits (ProjectType::Target::Type forTarget) const +Array<LibraryModule::CompileUnit> LibraryModule::getAllCompileUnits (build_tools::ProjectType::Target::Type forTarget) const { auto files = getFolder().findChildFiles (File::findFiles, false); @@ -478,12 +302,12 @@ Array<LibraryModule::CompileUnit> LibraryModule::getAllCompileUnits (ProjectType if (file.getFileName().startsWithIgnoreCase (getID()) && file.hasFileExtension (sourceFileExtensions)) { - if (forTarget == ProjectType::Target::unspecified + if (forTarget == build_tools::ProjectType::Target::unspecified || forTarget == Project::getTargetTypeFromFilePath (file, true)) { CompileUnit cu; cu.file = file; - units.add (cu); + units.add (std::move (cu)); } } } @@ -491,10 +315,10 @@ Array<LibraryModule::CompileUnit> LibraryModule::getAllCompileUnits (ProjectType for (auto& cu : units) { cu.isCompiledForObjC = true; - cu.isCompiledForNonObjC = ! cu.file.hasFileExtension ("mm;m"); + cu.isCompiledForNonObjC = ! cu.file.hasFileExtension ("mm;m;metal"); if (cu.isCompiledForNonObjC) - if (files.contains (cu.file.withFileExtension ("mm"))) + if (cu.file.withFileExtension ("mm").existsAsFile()) cu.isCompiledForObjC = false; jassert (cu.isCompiledForObjC || cu.isCompiledForNonObjC); @@ -506,7 +330,7 @@ Array<LibraryModule::CompileUnit> LibraryModule::getAllCompileUnits (ProjectType void LibraryModule::findAndAddCompiledUnits (ProjectExporter& exporter, ProjectSaver* projectSaver, Array<File>& result, - ProjectType::Target::Type forTarget) const + build_tools::ProjectType::Target::Type forTarget) const { for (auto& cu : getAllCompileUnits (forTarget)) { @@ -540,7 +364,7 @@ void LibraryModule::addBrowseableCode (ProjectExporter& exporter, const Array<Fi for (auto& sourceFile : sourceFiles) { - auto pathWithinModule = FileHelpers::getRelativePathFrom (sourceFile, localModuleFolder); + auto pathWithinModule = build_tools::getRelativePathFrom (sourceFile, localModuleFolder); // (Note: in exporters like MSVC we have to avoid adding the same file twice, even if one of those instances // is flagged as being excluded from the build, because this overrides the other and it fails to compile) @@ -555,12 +379,12 @@ void LibraryModule::addBrowseableCode (ProjectExporter& exporter, const Array<Fi } //============================================================================== -EnabledModuleList::EnabledModuleList (Project& p, const ValueTree& s) +EnabledModulesList::EnabledModulesList (Project& p, const ValueTree& s) : project (p), state (s) { } -StringArray EnabledModuleList::getAllModules() const +StringArray EnabledModulesList::getAllModules() const { StringArray moduleIDs; @@ -570,13 +394,13 @@ StringArray EnabledModuleList::getAllModules() const return moduleIDs; } -void EnabledModuleList::createRequiredModules (OwnedArray<LibraryModule>& modules) +void EnabledModulesList::createRequiredModules (OwnedArray<LibraryModule>& modules) { for (int i = 0; i < getNumModules(); ++i) modules.add (new LibraryModule (getModuleInfo (getModuleID (i)))); } -void EnabledModuleList::sortAlphabetically() +void EnabledModulesList::sortAlphabetically() { struct ModuleTreeSorter { @@ -587,17 +411,19 @@ void EnabledModuleList::sortAlphabetically() }; ModuleTreeSorter sorter; + + const ScopedLock sl (stateLock); state.sort (sorter, getUndoManager(), false); } -File EnabledModuleList::getDefaultModulesFolder() const +File EnabledModulesList::getDefaultModulesFolder() const { File globalPath (getAppSettings().getStoredPath (Ids::defaultJuceModulePath, TargetOS::getThisOS()).get().toString()); if (globalPath.exists()) return globalPath; - for (auto& exporterPathModule : project.getExporterPathsModuleList().getAllModules()) + for (auto& exporterPathModule : project.getExporterPathsModulesList().getAllModules()) { auto f = exporterPathModule.second; @@ -608,13 +434,14 @@ File EnabledModuleList::getDefaultModulesFolder() const return File::getCurrentWorkingDirectory(); } -ModuleDescription EnabledModuleList::getModuleInfo (const String& moduleID) +ModuleDescription EnabledModulesList::getModuleInfo (const String& moduleID) const { return ModuleDescription (project.getModuleWithID (moduleID).second); } -bool EnabledModuleList::isModuleEnabled (const String& moduleID) const +bool EnabledModulesList::isModuleEnabled (const String& moduleID) const { + const ScopedLock sl (stateLock); return state.getChildWithProperty (Ids::ID, moduleID).isValid(); } @@ -632,7 +459,7 @@ static void getDependencies (Project& project, const String& moduleID, StringArr } } -StringArray EnabledModuleList::getExtraDependenciesNeeded (const String& moduleID) const +StringArray EnabledModulesList::getExtraDependenciesNeeded (const String& moduleID) const { StringArray dependencies, extraDepsNeeded; getDependencies (project, moduleID, dependencies); @@ -644,11 +471,31 @@ StringArray EnabledModuleList::getExtraDependenciesNeeded (const String& moduleI return extraDepsNeeded; } -bool EnabledModuleList::doesModuleHaveHigherCppStandardThanProject (const String& moduleID) +bool EnabledModulesList::tryToFixMissingDependencies (const String& moduleID) +{ + auto copyLocally = areMostModulesCopiedLocally(); + auto useGlobalPath = areMostModulesUsingGlobalPath(); + + StringArray missing; + + for (auto missingModule : getExtraDependenciesNeeded (moduleID)) + { + auto mod = project.getModuleWithID (missingModule); + + if (mod.second != File()) + addModule (mod.second, copyLocally, useGlobalPath); + else + missing.add (missingModule); + } + + return (missing.size() == 0); +} + +bool EnabledModulesList::doesModuleHaveHigherCppStandardThanProject (const String& moduleID) const { auto projectCppStandard = project.getCppStandardString(); - if (projectCppStandard == "latest") + if (projectCppStandard == Project::getCppStandardVars().getLast().toString()) return false; auto moduleCppStandard = getModuleInfo (moduleID).getMinimumCppStandard(); @@ -656,40 +503,44 @@ bool EnabledModuleList::doesModuleHaveHigherCppStandardThanProject (const String return (moduleCppStandard.getIntValue() > projectCppStandard.getIntValue()); } -bool EnabledModuleList::shouldUseGlobalPath (const String& moduleID) const +bool EnabledModulesList::shouldUseGlobalPath (const String& moduleID) const { + const ScopedLock sl (stateLock); return (bool) shouldUseGlobalPathValue (moduleID).getValue(); } -Value EnabledModuleList::shouldUseGlobalPathValue (const String& moduleID) const +Value EnabledModulesList::shouldUseGlobalPathValue (const String& moduleID) const { + const ScopedLock sl (stateLock); return state.getChildWithProperty (Ids::ID, moduleID) .getPropertyAsValue (Ids::useGlobalPath, getUndoManager()); } -bool EnabledModuleList::shouldShowAllModuleFilesInProject (const String& moduleID) const +bool EnabledModulesList::shouldShowAllModuleFilesInProject (const String& moduleID) const { return (bool) shouldShowAllModuleFilesInProjectValue (moduleID).getValue(); } -Value EnabledModuleList::shouldShowAllModuleFilesInProjectValue (const String& moduleID) const +Value EnabledModulesList::shouldShowAllModuleFilesInProjectValue (const String& moduleID) const { + const ScopedLock sl (stateLock); return state.getChildWithProperty (Ids::ID, moduleID) .getPropertyAsValue (Ids::showAllCode, getUndoManager()); } -bool EnabledModuleList::shouldCopyModuleFilesLocally (const String& moduleID) const +bool EnabledModulesList::shouldCopyModuleFilesLocally (const String& moduleID) const { return (bool) shouldCopyModuleFilesLocallyValue (moduleID).getValue(); } -Value EnabledModuleList::shouldCopyModuleFilesLocallyValue (const String& moduleID) const +Value EnabledModulesList::shouldCopyModuleFilesLocallyValue (const String& moduleID) const { + const ScopedLock sl (stateLock); return state.getChildWithProperty (Ids::ID, moduleID) .getPropertyAsValue (Ids::useLocalCopy, getUndoManager()); } -bool EnabledModuleList::areMostModulesUsingGlobalPath() const +bool EnabledModulesList::areMostModulesUsingGlobalPath() const { int numYes = 0, numNo = 0; @@ -704,7 +555,7 @@ bool EnabledModuleList::areMostModulesUsingGlobalPath() const return numYes > numNo; } -bool EnabledModuleList::areMostModulesCopiedLocally() const +bool EnabledModulesList::areMostModulesCopiedLocally() const { int numYes = 0, numNo = 0; @@ -719,7 +570,47 @@ bool EnabledModuleList::areMostModulesCopiedLocally() const return numYes > numNo; } -void EnabledModuleList::addModule (const File& moduleFolder, bool copyLocally, bool useGlobalPath, bool sendAnalyticsEvent) +StringArray EnabledModulesList::getModulesWithHigherCppStandardThanProject() const +{ + StringArray list; + + for (auto& module : getAllModules()) + if (doesModuleHaveHigherCppStandardThanProject (module)) + list.add (module); + + return list; +} + +StringArray EnabledModulesList::getModulesWithMissingDependencies() const +{ + StringArray list; + + for (auto& module : getAllModules()) + if (getExtraDependenciesNeeded (module).size() > 0) + list.add (module); + + return list; +} + +String EnabledModulesList::getHighestModuleCppStandard() const +{ + auto highestCppStandard = Project::getCppStandardVars()[0].toString(); + + for (auto& mod : getAllModules()) + { + auto moduleCppStandard = getModuleInfo (mod).getMinimumCppStandard(); + + if (moduleCppStandard == "latest") + return moduleCppStandard; + + if (moduleCppStandard.getIntValue() > highestCppStandard.getIntValue()) + highestCppStandard = moduleCppStandard; + } + + return highestCppStandard; +} + +void EnabledModulesList::addModule (const File& moduleFolder, bool copyLocally, bool useGlobalPath) { ModuleDescription info (moduleFolder); @@ -732,47 +623,44 @@ void EnabledModuleList::addModule (const File& moduleFolder, bool copyLocally, b ValueTree module (Ids::MODULE); module.setProperty (Ids::ID, moduleID, getUndoManager()); - state.appendChild (module, getUndoManager()); + { + const ScopedLock sl (stateLock); + state.appendChild (module, getUndoManager()); + } + sortAlphabetically(); shouldShowAllModuleFilesInProjectValue (moduleID) = true; shouldCopyModuleFilesLocallyValue (moduleID) = copyLocally; shouldUseGlobalPathValue (moduleID) = useGlobalPath; - RelativePath path (moduleFolder.getParentDirectory(), - project.getProjectFolder(), RelativePath::projectFolder); + build_tools::RelativePath path (moduleFolder.getParentDirectory(), + project.getProjectFolder(), + build_tools::RelativePath::projectFolder); for (Project::ExporterIterator exporter (project); exporter.next();) exporter->getPathForModuleValue (moduleID) = path.toUnixStyle(); if (! useGlobalPath) project.rescanExporterPathModules (false); - - if (sendAnalyticsEvent) - { - StringPairArray data; - data.set ("label", moduleID); - - Analytics::getInstance()->logEvent ("Module Added", data, ProjucerAnalyticsEvent::projectEvent); - } } } } -void EnabledModuleList::addModuleInteractive (const String& moduleID) +void EnabledModulesList::addModuleInteractive (const String& moduleID) { auto f = project.getModuleWithID (moduleID).second; if (f != File()) { - addModule (f, areMostModulesCopiedLocally(), areMostModulesUsingGlobalPath(), true); + addModule (f, areMostModulesCopiedLocally(), areMostModulesUsingGlobalPath()); return; } addModuleFromUserSelectedFile(); } -void EnabledModuleList::addModuleFromUserSelectedFile() +void EnabledModulesList::addModuleFromUserSelectedFile() { auto lastLocation = getDefaultModulesFolder(); @@ -785,7 +673,7 @@ void EnabledModuleList::addModuleFromUserSelectedFile() } } -void EnabledModuleList::addModuleOfferingToCopy (const File& f, bool isFromUserSpecifiedFolder) +void EnabledModulesList::addModuleOfferingToCopy (const File& f, bool isFromUserSpecifiedFolder) { ModuleDescription m (f); @@ -803,16 +691,19 @@ void EnabledModuleList::addModuleOfferingToCopy (const File& f, bool isFromUserS return; } - addModule (m.moduleFolder, areMostModulesCopiedLocally(), - isFromUserSpecifiedFolder ? false : areMostModulesUsingGlobalPath(), - true); + addModule (m.getModuleFolder(), areMostModulesCopiedLocally(), + isFromUserSpecifiedFolder ? false : areMostModulesUsingGlobalPath()); } -void EnabledModuleList::removeModule (String moduleID) // must be pass-by-value, and not a const ref! +void EnabledModulesList::removeModule (String moduleID) // must be pass-by-value, and not a const ref! { - for (auto i = state.getNumChildren(); --i >= 0;) - if (state.getChild(i) [Ids::ID] == moduleID) - state.removeChild (i, getUndoManager()); + { + const ScopedLock sl (stateLock); + + for (auto i = state.getNumChildren(); --i >= 0;) + if (state.getChild(i) [Ids::ID] == moduleID) + state.removeChild (i, getUndoManager()); + } for (Project::ExporterIterator exporter (project); exporter.next();) exporter->removePathForModule (moduleID); diff --git a/extras/Projucer/Source/Project/jucer_Module.h b/extras/Projucer/Source/Project/Modules/jucer_Modules.h similarity index 54% rename from extras/Projucer/Source/Project/jucer_Module.h rename to extras/Projucer/Source/Project/Modules/jucer_Modules.h index 66b986f0..c75272bc 100644 --- a/extras/Projucer/Source/Project/jucer_Module.h +++ b/extras/Projucer/Source/Project/Modules/jucer_Modules.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -26,37 +25,11 @@ #pragma once -#include "jucer_Project.h" +#include "../jucer_Project.h" + class ProjectExporter; class ProjectSaver; -//============================================================================== -struct ModuleDescription -{ - ModuleDescription() = default; - ModuleDescription (const File& folder); - - bool isValid() const { return getID().isNotEmpty(); } - - String getID() const { return moduleInfo [Ids::ID_uppercase].toString(); } - String getVendor() const { return moduleInfo [Ids::vendor].toString(); } - String getVersion() const { return moduleInfo [Ids::version].toString(); } - String getName() const { return moduleInfo [Ids::name].toString(); } - String getDescription() const { return moduleInfo [Ids::description].toString(); } - String getLicense() const { return moduleInfo [Ids::license].toString(); } - String getMinimumCppStandard() const { return moduleInfo [Ids::minimumCppStandard].toString(); } - String getPreprocessorDefs() const { return moduleInfo [Ids::defines].toString(); } - String getExtraSearchPaths() const { return moduleInfo [Ids::searchpaths].toString(); } - StringArray getDependencies() const; - - File getFolder() const { jassert (moduleFolder != File()); return moduleFolder; } - File getHeader() const; - - File moduleFolder; - var moduleInfo; - URL url; -}; - //============================================================================== class LibraryModule { @@ -82,16 +55,18 @@ public: struct CompileUnit { File file; - bool isCompiledForObjC, isCompiledForNonObjC; + bool isCompiledForObjC = false, isCompiledForNonObjC = false; bool isNeededForExporter (ProjectExporter&) const; String getFilenameForProxyFile() const; static bool hasSuffix (const File&, const char*); }; - Array<CompileUnit> getAllCompileUnits (ProjectType::Target::Type forTarget = ProjectType::Target::unspecified) const; + Array<CompileUnit> getAllCompileUnits (build_tools::ProjectType::Target::Type forTarget = + build_tools::ProjectType::Target::unspecified) const; void findAndAddCompiledUnits (ProjectExporter&, ProjectSaver*, Array<File>& result, - ProjectType::Target::Type forTarget = ProjectType::Target::unspecified) const; + build_tools::ProjectType::Target::Type forTarget = + build_tools::ProjectType::Target::unspecified) const; ModuleDescription moduleInfo; @@ -108,51 +83,10 @@ private: }; //============================================================================== -class AvailableModuleList -{ -public: - using ModuleIDAndFolder = std::pair<String, File>; - using ModuleIDAndFolderList = std::vector<ModuleIDAndFolder>; - - AvailableModuleList() = default; - - void scanPaths (const Array<File>&); - void scanPathsAsync (const Array<File>&); - - ModuleIDAndFolderList getAllModules() const; - ModuleIDAndFolder getModuleWithID (const String&) const; - - void removeDuplicates (const ModuleIDAndFolderList& other); - - //============================================================================== - struct Listener - { - virtual ~Listener() {} - - virtual void availableModulesChanged() = 0; - }; - - void addListener (Listener* listenerToAdd) { listeners.add (listenerToAdd); } - void removeListener (Listener* listenerToRemove) { listeners.remove (listenerToRemove); } - -private: - ThreadPoolJob* createScannerJob (const Array<File>&); - void removePendingAndAddJob (ThreadPoolJob*); - - ThreadPool scanPool { 1 }; - - ModuleIDAndFolderList moduleList; - ListenerList<Listener> listeners; - CriticalSection lock; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AvailableModuleList) -}; - -//============================================================================== -class EnabledModuleList +class EnabledModulesList { public: - EnabledModuleList (Project&, const ValueTree&); + EnabledModulesList (Project&, const ValueTree&); //============================================================================== ValueTree getState() const { return state; } @@ -166,11 +100,14 @@ public: int getNumModules() const { return state.getNumChildren(); } String getModuleID (int index) const { return state.getChild (index) [Ids::ID].toString(); } - ModuleDescription getModuleInfo (const String& moduleID); + ModuleDescription getModuleInfo (const String& moduleID) const; bool isModuleEnabled (const String& moduleID) const; + StringArray getExtraDependenciesNeeded (const String& moduleID) const; - bool doesModuleHaveHigherCppStandardThanProject (const String& moduleID); + bool tryToFixMissingDependencies (const String& moduleID); + + bool doesModuleHaveHigherCppStandardThanProject (const String& moduleID) const; bool shouldUseGlobalPath (const String& moduleID) const; Value shouldUseGlobalPathValue (const String& moduleID) const; @@ -184,8 +121,13 @@ public: bool areMostModulesUsingGlobalPath() const; bool areMostModulesCopiedLocally() const; + StringArray getModulesWithHigherCppStandardThanProject() const; + StringArray getModulesWithMissingDependencies() const; + + String getHighestModuleCppStandard() const; + //============================================================================== - void addModule (const File& moduleManifestFile, bool copyLocally, bool useGlobalPath, bool sendAnalyticsEvent); + void addModule (const File& moduleManifestFile, bool copyLocally, bool useGlobalPath); void addModuleInteractive (const String& moduleID); void addModuleFromUserSelectedFile(); void addModuleOfferingToCopy (const File&, bool isFromUserSpecifiedFolder); @@ -196,7 +138,9 @@ private: UndoManager* getUndoManager() const { return project.getUndoManagerFor (state); } Project& project; + + CriticalSection stateLock; ValueTree state; - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (EnabledModuleList) + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (EnabledModulesList) }; diff --git a/extras/Projucer/Source/Project/UI/Sidebar/jucer_ExporterTreeItems.h b/extras/Projucer/Source/Project/UI/Sidebar/jucer_ExporterTreeItems.h index 4cc84f02..d9bd8eb4 100644 --- a/extras/Projucer/Source/Project/UI/Sidebar/jucer_ExporterTreeItems.h +++ b/extras/Projucer/Source/Project/UI/Sidebar/jucer_ExporterTreeItems.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -47,7 +46,7 @@ public: bool mightContainSubItems() override { return exporter->getNumConfigurations() > 0; } String getUniqueName() const override { return "exporter_" + String (exporterIndex); } String getRenamingName() const override { return getDisplayName(); } - String getDisplayName() const override { return exporter->getName(); } + String getDisplayName() const override { return exporter->getUniqueName(); } void setName (const String&) override {} bool isMissing() const override { return false; } String getTooltip() override { return getDisplayName(); } @@ -116,18 +115,11 @@ public: void handlePopupMenuResult (int resultCode) override { if (resultCode == 1) - { exporter->addNewConfiguration (false); - } else if (resultCode == 2) - { - const ScopedValueSetter<String> valueSetter (project.specifiedExporterToSave, exporter->getName(), {}); - project.save (true, true); - } + project.saveProject (exporter.get()); else if (resultCode == 3) - { deleteAllSelectedItems(); - } } var getDragSourceDescription() override @@ -187,7 +179,7 @@ private: struct SettingsComp : public Component { SettingsComp (ProjectExporter& exp) - : group (exp.getName(), + : group (exp.getUniqueName(), ExporterItem::getIconForExporter (&exp), exp.getDescription()) { @@ -284,7 +276,7 @@ private: { public: SettingsComp (ProjectExporter::BuildConfiguration& conf) - : group (conf.exporter.getName() + " - " + conf.getName(), Icon (getIcons().config, Colours::transparentBlack)) + : group (conf.exporter.getUniqueName() + " - " + conf.getName(), Icon (getIcons().config, Colours::transparentBlack)) { addAndMakeVisible (group); diff --git a/extras/Projucer/Source/Project/UI/Sidebar/jucer_FileTreeItems.h b/extras/Projucer/Source/Project/UI/Sidebar/jucer_FileTreeItems.h index 0778ba84..8604d17d 100644 --- a/extras/Projucer/Source/Project/UI/Sidebar/jucer_FileTreeItems.h +++ b/extras/Projucer/Source/Project/UI/Sidebar/jucer_FileTreeItems.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -29,7 +28,7 @@ //============================================================================== class FileTreeItemBase : public JucerTreeViewBase, - public ValueTree::Listener + private ValueTree::Listener { public: FileTreeItemBase (const Project::Item& projectItem) @@ -118,7 +117,7 @@ public: { auto f = filesToTrash.getUnchecked(i); - om.closeFile (f, false); + om.closeFile (f, OpenDocumentManager::SaveIfNeeded::no); if (! f.moveToTrash()) { @@ -137,7 +136,7 @@ public: pcc->hideEditor(); } - om.closeFile (itemToRemove->getFile(), false); + om.closeFile (itemToRemove->getFile(), OpenDocumentManager::SaveIfNeeded::no); itemToRemove->deleteItem(); } } @@ -235,17 +234,6 @@ public: return nullptr; } - //============================================================================== - void valueTreePropertyChanged (ValueTree& tree, const Identifier&) override - { - if (tree == item.state) - repaintItem(); - } - - void valueTreeChildAdded (ValueTree& parentTree, ValueTree&) override { treeChildrenChanged (parentTree); } - void valueTreeChildRemoved (ValueTree& parentTree, ValueTree&, int) override { treeChildrenChanged (parentTree); } - void valueTreeChildOrderChanged (ValueTree& parentTree, int, int) override { treeChildrenChanged (parentTree); } - //============================================================================== bool mightContainSubItems() override { return item.getNumChildren() > 0; } String getUniqueName() const override { jassert (item.getID().isNotEmpty()); return item.getID(); } @@ -348,6 +336,17 @@ public: Project::Item item; protected: + //============================================================================== + void valueTreePropertyChanged (ValueTree& tree, const Identifier&) override + { + if (tree == item.state) + repaintItem(); + } + + void valueTreeChildAdded (ValueTree& parentTree, ValueTree&) override { treeChildrenChanged (parentTree); } + void valueTreeChildRemoved (ValueTree& parentTree, ValueTree&, int) override { treeChildrenChanged (parentTree); } + void valueTreeChildOrderChanged (ValueTree& parentTree, int, int) override { treeChildrenChanged (parentTree); } + bool isFileMissing; virtual FileTreeItemBase* createSubItem (const Project::Item& node) = 0; @@ -564,16 +563,11 @@ public: m.addItem (4, "Rename File..."); m.addSeparator(); - if (auto* group = dynamic_cast<GroupItem*> (getParentItem())) - { - if (group->isRoot()) - { - m.addItem (5, "Binary Resource", true, item.shouldBeAddedToBinaryResources()); - m.addItem (6, "Xcode Resource", true, item.shouldBeAddedToXcodeResources()); - m.addItem (7, "Compile", true, item.shouldBeCompiled()); - m.addSeparator(); - } - } + m.addItem (5, "Binary Resource", true, item.shouldBeAddedToBinaryResources()); + m.addItem (6, "Xcode Resource", true, item.shouldBeAddedToXcodeResources()); + m.addItem (7, "Compile", item.isSourceFile(), item.shouldBeCompiled()); + m.addItem (8, "Skip PCH", item.shouldBeCompiled(), item.shouldSkipPCH()); + m.addSeparator(); m.addItem (3, "Delete"); @@ -590,13 +584,14 @@ public: { switch (resultCode) { - case 1: getFile().startAsProcess(); break; - case 2: revealInFinder(); break; - case 3: deleteAllSelectedItems(); break; - case 4: triggerAsyncRename (item); break; - case 5: item.getShouldAddToBinaryResourcesValue().setValue (! item.shouldBeAddedToBinaryResources()); break; - case 6: item.getShouldAddToXcodeResourcesValue().setValue (! item.shouldBeAddedToXcodeResources()); break; - case 7: item.getShouldCompileValue().setValue (! item.shouldBeCompiled()); break; + case 1: getFile().startAsProcess(); break; + case 2: revealInFinder(); break; + case 3: deleteAllSelectedItems(); break; + case 4: triggerAsyncRename (item); break; + case 5: item.getShouldAddToBinaryResourcesValue().setValue (! item.shouldBeAddedToBinaryResources()); break; + case 6: item.getShouldAddToXcodeResourcesValue().setValue (! item.shouldBeAddedToXcodeResources()); break; + case 7: item.getShouldCompileValue().setValue (! item.shouldBeCompiled()); break; + case 8: item.getShouldSkipPCHValue().setValue (! item.shouldSkipPCH()); break; default: if (auto* parentGroup = dynamic_cast<GroupItem*> (getParentProjectItem())) diff --git a/extras/Projucer/Source/Project/UI/Sidebar/jucer_LiveBuildTab.h b/extras/Projucer/Source/Project/UI/Sidebar/jucer_LiveBuildTab.h index 096c53f6..6ce902be 100644 --- a/extras/Projucer/Source/Project/UI/Sidebar/jucer_LiveBuildTab.h +++ b/extras/Projucer/Source/Project/UI/Sidebar/jucer_LiveBuildTab.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -69,9 +68,8 @@ class LiveBuildTab : public Component, public: LiveBuildTab (const CompileEngineChildProcess::Ptr& child, String lastErrorMessage) { - settingsButton.reset (new IconButton ("Settings", &getIcons().settings)); - addAndMakeVisible (settingsButton.get()); - settingsButton->onClick = [this] + addAndMakeVisible (settingsButton); + settingsButton.onClick = [this] { if (auto* pcc = findParentComponentOfClass<ProjectContentComponent>()) pcc->showLiveBuildSettings(); @@ -130,9 +128,9 @@ public: { auto bounds = getLocalBounds(); - settingsButton->setBounds (bounds.removeFromBottom (25) - .removeFromRight (25) - .reduced (3)); + settingsButton.setBounds (bounds.removeFromBottom (25) + .removeFromRight (25) + .reduced (3)); if (errorMessageLabel != nullptr) { @@ -163,7 +161,7 @@ public: private: OwnedArray<ConcertinaHeader> headers; ConcertinaPanel concertinaPanel; - std::unique_ptr<IconButton> settingsButton; + IconButton settingsButton { "Settings", getIcons().settings }; std::unique_ptr<TextButton> downloadButton, enableButton; std::unique_ptr<Label> errorMessageLabel; @@ -194,7 +192,7 @@ private: if (isMac) if (osType < SystemStats::MacOSX_10_9) - return "Live-build features are available only on MacOSX 10.9 or higher."; + return "Live-build features are available only on macOS 10.9 or higher."; if (isWin) if (! SystemStats::isOperatingSystem64Bit() || osType < SystemStats::Windows8_0) @@ -226,7 +224,7 @@ private: } if (auto* pcc = findParentComponentOfClass<ProjectContentComponent>()) - pcc->rebuildProjectTabs(); + pcc->rebuildProjectUI(); } } diff --git a/extras/Projucer/Source/Project/UI/Sidebar/jucer_ModuleTreeItems.h b/extras/Projucer/Source/Project/UI/Sidebar/jucer_ModuleTreeItems.h index 709a23a2..891c27bc 100644 --- a/extras/Projucer/Source/Project/UI/Sidebar/jucer_ModuleTreeItems.h +++ b/extras/Projucer/Source/Project/UI/Sidebar/jucer_ModuleTreeItems.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -166,7 +165,7 @@ private: exporterModulePathValues.add (defaultValue.getPropertyAsValue()); auto pathComponent = std::make_unique<FilePathPropertyComponent> (defaultValue, - "Path for " + exporter->getName().quoted(), + "Path for " + exporter->getUniqueName().quoted(), true, exporter->getTargetOSForExporter() == TargetOS::getThisOS(), "*", @@ -176,7 +175,7 @@ private: props.add (pathComponent.release(), "A path to the folder that contains the " + moduleID + " module when compiling the " - + exporter->getName().quoted() + " target. " + + exporter->getUniqueName().quoted() + " target. " "This can be an absolute path, or relative to the jucer project folder, but it " "must be valid on the filesystem of the target machine that will be performing this build. If this " "is empty then the global path will be used."); @@ -369,17 +368,21 @@ private: void fixDependencies() { - if (! tryToFix()) + auto& enabledModules = project.getEnabledModules(); + + if (enabledModules.tryToFixMissingDependencies (moduleID)) + { + missingDependencies.clear(); + } + else { + missingDependencies = enabledModules.getExtraDependenciesNeeded (moduleID); + AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon, "Adding Missing Dependencies", "Couldn't locate some of these modules - you'll need to find their " "folders manually and add them to the list."); - - return; } - - refreshAndReselectItem(); } void resized() override @@ -389,59 +392,11 @@ private: private: Project& project; + String moduleID; StringArray missingDependencies; TextButton fixButton { "Add Required Modules" }; - bool tryToFix() - { - auto& enabledModules = project.getEnabledModules(); - - auto copyLocally = enabledModules.areMostModulesCopiedLocally(); - auto useGlobalPath = enabledModules.areMostModulesUsingGlobalPath(); - - StringArray missing; - - for (auto missingModule : missingDependencies) - { - auto mod = project.getModuleWithID (missingModule); - - if (mod.second != File()) - enabledModules.addModule (mod.second, copyLocally, useGlobalPath, false); - else - missing.add (missingModule); - } - - missingDependencies.swapWith (missing); - return (missingDependencies.size() == 0); - } - - void refreshAndReselectItem() - { - if (auto* settingsPanel = findParentComponentOfClass<ModuleSettingsPanel>()) - { - if (settingsPanel->modulesTree == nullptr) - return; - - auto* rootItem = settingsPanel->modulesTree->getRootItem(); - - if (rootItem == nullptr) - return; - - for (int i = 0; i < rootItem->getNumSubItems(); ++i) - { - if (auto* subItem = dynamic_cast<ProjectTreeItemBase*> (rootItem->getSubItem (i))) - { - if (subItem->getDisplayName() == moduleID) - { - subItem->setSelected (true, true); - return; - } - } - } - } - } - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MissingDependenciesComponent) }; @@ -476,28 +431,30 @@ private: //============================================================================== class EnabledModulesItem : public ProjectTreeItemBase, private Value::Listener, - private AvailableModuleList::Listener + private AvailableModulesList::Listener { public: EnabledModulesItem (Project& p) : project (p), - moduleListTree (project.getEnabledModules().getState()) + modulesListTree (project.getEnabledModules().getState()) { - moduleListTree.addListener (this); + modulesListTree.addListener (this); projectCppStandardValue.referTo (project.getProjectValue (Ids::cppLanguageStandard)); projectCppStandardValue.addListener (this); - ProjucerApplication::getApp().getJUCEPathModuleList().addListener (this); - ProjucerApplication::getApp().getUserPathsModuleList().addListener (this); - project.getExporterPathsModuleList().addListener (this); + ProjucerApplication::getApp().getJUCEPathModulesList().addListener (this); + ProjucerApplication::getApp().getUserPathsModulesList().addListener (this); + + project.getExporterPathsModulesList().addListener (this); } ~EnabledModulesItem() override { - ProjucerApplication::getApp().getJUCEPathModuleList().removeListener (this); - ProjucerApplication::getApp().getUserPathsModuleList().removeListener (this); - project.getExporterPathsModuleList().removeListener (this); + ProjucerApplication::getApp().getJUCEPathModulesList().removeListener (this); + ProjucerApplication::getApp().getUserPathsModulesList().removeListener (this); + + project.getExporterPathsModulesList().removeListener (this); } int getItemHeight() const override { return 22; } @@ -547,10 +504,9 @@ public: } for (int i = 0; i < modules.size(); ++i) - project.getEnabledModules().addModule (modules.getReference(i).moduleFolder, + project.getEnabledModules().addModule (modules.getReference (i).getModuleFolder(), project.getEnabledModules().areMostModulesCopiedLocally(), - project.getEnabledModules().areMostModulesUsingGlobalPath(), - true); + project.getEnabledModules().areMostModulesUsingGlobalPath()); } void addSubItems() override @@ -569,7 +525,7 @@ public: // JUCE path PopupMenu jucePathModules; - for (auto& mod : ProjucerApplication::getApp().getJUCEPathModuleList().getAllModules()) + for (auto& mod : ProjucerApplication::getApp().getJUCEPathModulesList().getAllModules()) jucePathModules.addItem (index++, mod.first, ! enabledModules.isModuleEnabled (mod.first)); jucePathModules.addSeparator(); @@ -581,7 +537,7 @@ public: index = 200; PopupMenu userPathModules; - for (auto& mod : ProjucerApplication::getApp().getUserPathsModuleList().getAllModules()) + for (auto& mod : ProjucerApplication::getApp().getUserPathsModulesList().getAllModules()) userPathModules.addItem (index++, mod.first, ! enabledModules.isModuleEnabled (mod.first)); userPathModules.addSeparator(); @@ -593,7 +549,7 @@ public: index = 300; PopupMenu exporterPathModules; - for (auto& mod : project.getExporterPathsModuleList().getAllModules()) + for (auto& mod : project.getExporterPathsModulesList().getAllModules()) exporterPathModules.addItem (index++, mod.first, ! enabledModules.isModuleEnabled (mod.first)); exporterPathModules.addSeparator(); @@ -624,22 +580,22 @@ public: } else if (resultCode > 0) { - std::vector<AvailableModuleList::ModuleIDAndFolder> list; + std::vector<AvailableModulesList::ModuleIDAndFolder> list; int offset = -1; if (resultCode < 200) { - list = ProjucerApplication::getApp().getJUCEPathModuleList().getAllModules(); + list = ProjucerApplication::getApp().getJUCEPathModulesList().getAllModules(); offset = 100; } else if (resultCode < 300) { - list = ProjucerApplication::getApp().getUserPathsModuleList().getAllModules(); + list = ProjucerApplication::getApp().getUserPathsModulesList().getAllModules(); offset = 200; } else if (resultCode < 400) { - list = project.getExporterPathsModuleList().getAllModules(); + list = project.getExporterPathsModulesList().getAllModules(); offset = 300; } @@ -655,13 +611,20 @@ public: void refreshIfNeeded (ValueTree& changedTree) { - if (changedTree == moduleListTree) + if (changedTree == modulesListTree) + { + auto selectedID = getSelectedItemID(); + refreshSubItems(); + + if (selectedID.isNotEmpty()) + setSelectedItem (selectedID); + } } private: Project& project; - ValueTree moduleListTree; + ValueTree modulesListTree; Value projectCppStandardValue; //============================================================================== @@ -685,22 +648,47 @@ private: void removeDuplicateModules() { - auto jucePathModuleList = ProjucerApplication::getApp().getJUCEPathModuleList().getAllModules(); + auto jucePathModulesList = ProjucerApplication::getApp().getJUCEPathModulesList().getAllModules(); - auto& userPathModules = ProjucerApplication::getApp().getUserPathsModuleList(); - userPathModules.removeDuplicates (jucePathModuleList); + auto& userPathModules = ProjucerApplication::getApp().getUserPathsModulesList(); + userPathModules.removeDuplicates (jucePathModulesList); - auto& exporterPathModules = project.getExporterPathsModuleList(); - exporterPathModules.removeDuplicates (jucePathModuleList); + auto& exporterPathModules = project.getExporterPathsModulesList(); + exporterPathModules.removeDuplicates (jucePathModulesList); exporterPathModules.removeDuplicates (userPathModules.getAllModules()); } - void availableModulesChanged() override + void availableModulesChanged (AvailableModulesList*) override { removeDuplicateModules(); refreshSubItems(); } + String getSelectedItemID() const + { + for (int i = 0; i < getNumSubItems(); ++i) + if (auto* item = getSubItem (i)) + if (item->isSelected()) + return item->getUniqueName(); + + return {}; + } + + void setSelectedItem (const String& itemID) + { + for (int i = 0; i < getNumSubItems(); ++i) + { + if (auto* item = getSubItem (i)) + { + if (item->getUniqueName() == itemID) + { + item->setSelected (true, true); + return; + } + } + } + } + //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (EnabledModulesItem) }; diff --git a/extras/Projucer/Source/Project/UI/Sidebar/jucer_ProjectTab.h b/extras/Projucer/Source/Project/UI/Sidebar/jucer_ProjectTab.h index dbeb8a1b..631dbc71 100644 --- a/extras/Projucer/Source/Project/UI/Sidebar/jucer_ProjectTab.h +++ b/extras/Projucer/Source/Project/UI/Sidebar/jucer_ProjectTab.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -207,14 +206,14 @@ public: jassert (isPositiveAndBelow (panelIndex, concertinaPanel.getNumPanels())); concertinaPanel.setPanelSize (concertinaPanel.getPanel (panelIndex), - roundToInt (prop * (concertinaPanel.getHeight() - 90)), false); + roundToInt (prop * (float) (concertinaPanel.getHeight() - 90)), false); } float getPanelHeightProportion (int panelIndex) { jassert (isPositiveAndBelow (panelIndex, concertinaPanel.getNumPanels())); - return ((float) (concertinaPanel.getPanel (panelIndex)->getHeight()) / (concertinaPanel.getHeight() - 90)); + return ((float) (concertinaPanel.getPanel (panelIndex)->getHeight()) / (float) (concertinaPanel.getHeight() - 90)); } private: diff --git a/extras/Projucer/Source/Project/UI/Sidebar/jucer_ProjectTreeItemBase.h b/extras/Projucer/Source/Project/UI/Sidebar/jucer_ProjectTreeItemBase.h index 6c4711e0..1443832b 100644 --- a/extras/Projucer/Source/Project/UI/Sidebar/jucer_ProjectTreeItemBase.h +++ b/extras/Projucer/Source/Project/UI/Sidebar/jucer_ProjectTreeItemBase.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/Project/UI/Sidebar/jucer_TabComponents.h b/extras/Projucer/Source/Project/UI/Sidebar/jucer_TabComponents.h index c10509a2..8027225c 100644 --- a/extras/Projucer/Source/Project/UI/Sidebar/jucer_TabComponents.h +++ b/extras/Projucer/Source/Project/UI/Sidebar/jucer_TabComponents.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -173,35 +172,27 @@ public: { if (hasAddButton) { - addButton.reset (new IconButton ("Add", &getIcons().plus)); + addButton = std::make_unique<IconButton> ("Add", getIcons().plus); addAndMakeVisible (addButton.get()); addButton->onClick = [this] { showAddMenu(); }; } if (hasSettingsButton) { - settingsButton.reset (new IconButton ("Settings", &getIcons().settings)); + settingsButton = std::make_unique<IconButton> ("Settings", getIcons().settings); addAndMakeVisible (settingsButton.get()); settingsButton->onClick = [this] { showSettings(); }; } if (hasFindPanel) { - findPanel.reset (new FindPanel ([this] (const String& filter) { treeToDisplay->rootItem->setSearchFilter (filter); })); + findPanel = std::make_unique<FindPanel> ([this] (const String& filter) { treeToDisplay->rootItem->setSearchFilter (filter); }); addAndMakeVisible (findPanel.get()); } addAndMakeVisible (treeToDisplay.get()); } - ~ConcertinaTreeComponent() override - { - treeToDisplay.reset(); - addButton.reset(); - findPanel.reset(); - settingsButton.reset(); - } - void resized() override { auto bounds = getLocalBounds(); diff --git a/extras/Projucer/Source/Project/UI/Sidebar/jucer_TreeItemTypes.h b/extras/Projucer/Source/Project/UI/Sidebar/jucer_TreeItemTypes.h index b8934a91..b0a56666 100644 --- a/extras/Projucer/Source/Project/UI/Sidebar/jucer_TreeItemTypes.h +++ b/extras/Projucer/Source/Project/UI/Sidebar/jucer_TreeItemTypes.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -29,7 +28,7 @@ #include "../../../ProjectSaving/jucer_ProjectExporter.h" #include "../../../Application/Windows/jucer_TranslationToolWindowComponent.h" #include "../../../Utility/UI/jucer_JucerTreeViewBase.h" -#include "../../../Wizards/jucer_NewFileWizard.h" +#include "../../../Utility/Helpers/jucer_NewFileWizard.h" #include "../jucer_ContentViewComponents.h" #include "../jucer_FileGroupInformationComponent.h" #include "../jucer_ModulesInformationComponent.h" diff --git a/extras/Projucer/Source/Project/UI/jucer_ContentViewComponents.h b/extras/Projucer/Source/Project/UI/jucer_ContentViewComponents.h index c7ecfc22..cad72585 100644 --- a/extras/Projucer/Source/Project/UI/jucer_ContentViewComponents.h +++ b/extras/Projucer/Source/Project/UI/jucer_ContentViewComponents.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -61,7 +60,7 @@ public: for (auto s : columnHeaders) { addAndMakeVisible (headers.add (new Label (s, s))); - widths.add (1.0f / columnHeaders.size()); + widths.add (1.0f / (float) columnHeaders.size()); } setSize (200, 40); @@ -91,7 +90,7 @@ public: auto index = 0; for (auto h : headers) { - auto headerWidth = roundToInt (width * widths.getUnchecked (index)); + auto headerWidth = roundToInt ((float) width * widths.getUnchecked (index)); h->setBounds (bounds.removeFromLeft (headerWidth)); ++index; } @@ -115,7 +114,7 @@ public: for (int i = 0; i < index; ++i) prop += widths.getUnchecked (i); - return roundToInt (prop * getWidth()); + return roundToInt (prop * (float) getWidth()); } float getProportionAtIndex (int index) @@ -179,10 +178,10 @@ public: void clicked() override { - auto* w = new InfoWindow (info); + auto w = std::make_unique<InfoWindow> (info); w->setSize (width, w->getHeight() * numLines + 10); - CallOutBox::launchAsynchronously (w, getScreenBounds(), nullptr); + CallOutBox::launchAsynchronously (std::move (w), getScreenBounds(), nullptr); } using Button::clicked; @@ -224,7 +223,7 @@ private: g.setColour (findColour (defaultTextColourId)); g.setFont (Font (14.0f)); - g.drawFittedText (stringToDisplay, getLocalBounds(), Justification::centred, 10, 1.0f); + g.drawFittedText (stringToDisplay, getLocalBounds(), Justification::centred, 15, 0.75f); } String stringToDisplay; @@ -373,7 +372,7 @@ private: if (availableTextWidth == 0) return 0; - return static_cast<int> (nameWidth / availableTextWidth); + return static_cast<int> (nameWidth / (float) availableTextWidth); } //============================================================================== diff --git a/extras/Projucer/Source/Project/UI/jucer_FileGroupInformationComponent.h b/extras/Projucer/Source/Project/UI/jucer_FileGroupInformationComponent.h index 5678bf44..78bb426c 100644 --- a/extras/Projucer/Source/Project/UI/jucer_FileGroupInformationComponent.h +++ b/extras/Projucer/Source/Project/UI/jucer_FileGroupInformationComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -37,8 +36,8 @@ public: : item (group), header (item.getName(), { getIcons().openFolder, Colours::transparentBlack }) { - list.setHeaderComponent (new ListBoxHeader ( { "File", "Binary Resource", "Xcode Resource", "Compile", "Compiler Flag Scheme" }, - { 0.3f, 0.15f, 0.15f, 0.15f, 0.25f } )); + list.setHeaderComponent (std::make_unique<ListBoxHeader> (Array<String> { "File", "Binary Resource", "Xcode Resource", "Compile", "Skip PCH", "Compiler Flag Scheme" }, + Array<float> { 0.25f, 0.125f, 0.125f, 0.125f, 0.125f, 0.25f })); list.setModel (this); list.setColour (ListBox::backgroundColourId, Colours::transparentBlack); addAndMakeVisible (list); @@ -137,9 +136,14 @@ private: { if (item.isFile()) { - addAndMakeVisible (compileButton); - compileButton.getToggleStateValue().referTo (item.getShouldCompileValue()); - compileButton.onStateChange = [this] { compilerFlagSchemeSelector.setVisible (compileButton.getToggleState()); }; + auto isSourceFile = item.isSourceFile(); + + if (isSourceFile) + { + addAndMakeVisible (compileButton); + compileButton.getToggleStateValue().referTo (item.getShouldCompileValue()); + compileButton.onStateChange = [this] { compileEnablementChanged(); }; + } addAndMakeVisible (binaryResourceButton); binaryResourceButton.getToggleStateValue().referTo (item.getShouldAddToBinaryResourcesValue()); @@ -147,8 +151,15 @@ private: addAndMakeVisible (xcodeResourceButton); xcodeResourceButton.getToggleStateValue().referTo (item.getShouldAddToXcodeResourcesValue()); - addChildComponent (compilerFlagSchemeSelector); - compilerFlagSchemeSelector.setVisible (compileButton.getToggleState()); + if (isSourceFile) + { + addChildComponent (skipPCHButton); + skipPCHButton.getToggleStateValue().referTo (item.getShouldSkipPCHValue()); + + addChildComponent (compilerFlagSchemeSelector); + + compileEnablementChanged(); + } } } @@ -156,7 +167,7 @@ private: { if (header != nullptr) { - auto textBounds = getLocalBounds().removeFromLeft (roundToInt (header->getProportionAtIndex (0) * getWidth())); + auto textBounds = getLocalBounds().removeFromLeft (roundToInt (header->getProportionAtIndex (0) * (float) getWidth())); auto iconBounds = textBounds.removeFromLeft (25); @@ -176,14 +187,15 @@ private: if (header != nullptr) { auto bounds = getLocalBounds(); - auto width = getWidth(); + auto width = (float) getWidth(); bounds.removeFromLeft (roundToInt (header->getProportionAtIndex (0) * width)); binaryResourceButton.setBounds (bounds.removeFromLeft (roundToInt (header->getProportionAtIndex (1) * width))); xcodeResourceButton.setBounds (bounds.removeFromLeft (roundToInt (header->getProportionAtIndex (2) * width))); compileButton.setBounds (bounds.removeFromLeft (roundToInt (header->getProportionAtIndex (3) * width))); - compilerFlagSchemeSelector.setBounds (bounds.removeFromLeft (roundToInt (header->getProportionAtIndex (4) * width))); + skipPCHButton.setBounds (bounds.removeFromLeft (roundToInt (header->getProportionAtIndex (4) * width))); + compilerFlagSchemeSelector.setBounds (bounds.removeFromLeft (roundToInt (header->getProportionAtIndex (5) * width))); } } @@ -332,10 +344,18 @@ private: Label newSchemeLabel; }; + void compileEnablementChanged() + { + auto shouldBeCompiled = compileButton.getToggleState(); + + skipPCHButton.setVisible (shouldBeCompiled); + compilerFlagSchemeSelector.setVisible (shouldBeCompiled); + } + //============================================================================== ListBoxHeader* header; - ToggleButton compileButton, binaryResourceButton, xcodeResourceButton; + ToggleButton compileButton, binaryResourceButton, xcodeResourceButton, skipPCHButton; CompilerFlagSchemeSelector compilerFlagSchemeSelector; }; diff --git a/extras/Projucer/Source/Project/UI/jucer_HeaderComponent.cpp b/extras/Projucer/Source/Project/UI/jucer_HeaderComponent.cpp index 193fe17d..bd5a1eb9 100644 --- a/extras/Projucer/Source/Project/UI/jucer_HeaderComponent.cpp +++ b/extras/Projucer/Source/Project/UI/jucer_HeaderComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -26,6 +25,8 @@ #include "jucer_HeaderComponent.h" +#include "../../Application/jucer_Application.h" + #include "../../ProjectSaving/jucer_ProjectExporter.h" #include "../../Project/UI/jucer_ProjectContentComponent.h" @@ -36,17 +37,19 @@ #include "../../LiveBuildEngine/jucer_CompileEngineClient.h" //============================================================================== -HeaderComponent::HeaderComponent() +HeaderComponent::HeaderComponent (ProjectContentComponent* pcc) + : projectContentComponent (pcc) { addAndMakeVisible (configLabel); addAndMakeVisible (exporterBox); exporterBox.onChange = [this] { updateExporterButton(); }; - juceIcon.reset (new ImageComponent ("icon")); - addAndMakeVisible (juceIcon.get()); - juceIcon->setImage (ImageCache::getFromMemory (BinaryData::juce_icon_png, BinaryData::juce_icon_pngSize), - RectanglePlacement::centred); + juceIcon.setImage (ImageCache::getFromMemory (BinaryData::juce_icon_png, BinaryData::juce_icon_pngSize), RectanglePlacement::centred); + addAndMakeVisible (juceIcon); + + addAndMakeVisible (userAvatar); + userAvatar.addChangeListener (this); projectNameLabel.setText ({}, dontSendNotification); addAndMakeVisible (projectNameLabel); @@ -56,12 +59,9 @@ HeaderComponent::HeaderComponent() HeaderComponent::~HeaderComponent() { - if (userSettingsWindow != nullptr) - userSettingsWindow->dismiss(); - if (childProcess != nullptr) { - childProcess->activityList.removeChangeListener(this); + childProcess->activityList.removeChangeListener (this); childProcess->errorList.removeChangeListener (this); } } @@ -70,38 +70,38 @@ HeaderComponent::~HeaderComponent() void HeaderComponent::resized() { auto bounds = getLocalBounds(); - configLabel.setFont ({ bounds.getHeight() / 3.0f }); + configLabel.setFont ({ (float) bounds.getHeight() / 3.0f }); - //============================================================================== { auto headerBounds = bounds.removeFromLeft (tabsWidth); const int buttonSize = 25; auto buttonBounds = headerBounds.removeFromRight (buttonSize); - projectSettingsButton->setBounds (buttonBounds.removeFromBottom (buttonSize).reduced (2)); + projectSettingsButton.setBounds (buttonBounds.removeFromBottom (buttonSize).reduced (2)); - juceIcon->setBounds (headerBounds.removeFromLeft (headerBounds.getHeight()).reduced (2)); + juceIcon.setBounds (headerBounds.removeFromLeft (headerBounds.getHeight()).reduced (2)); headerBounds.removeFromRight (5); projectNameLabel.setBounds (headerBounds); } - //============================================================================== - auto exporterWidth = jmin (400, bounds.getWidth() / 2); - Rectangle<int> exporterBounds (0, 0, exporterWidth, bounds.getHeight()); + { + auto exporterWidth = jmin (400, bounds.getWidth() / 2); + Rectangle<int> exporterBounds (0, 0, exporterWidth, bounds.getHeight()); - exporterBounds.setCentre (bounds.getCentre()); + exporterBounds.setCentre (bounds.getCentre()); - runAppButton->setBounds (exporterBounds.removeFromRight (exporterBounds.getHeight()).reduced (2)); - saveAndOpenInIDEButton->setBounds (exporterBounds.removeFromRight (exporterBounds.getHeight()).reduced (2)); + runAppButton.setBounds (exporterBounds.removeFromRight (exporterBounds.getHeight()).reduced (2)); + saveAndOpenInIDEButton.setBounds (exporterBounds.removeFromRight (exporterBounds.getHeight()).reduced (2)); - exporterBounds.removeFromRight (5); - exporterBox.setBounds (exporterBounds.removeFromBottom (roundToInt (exporterBounds.getHeight() / 1.8f))); - configLabel.setBounds (exporterBounds); + exporterBounds.removeFromRight (5); + exporterBox.setBounds (exporterBounds.removeFromBottom (roundToInt ((float) exporterBounds.getHeight() / 1.8f))); + configLabel.setBounds (exporterBounds); + } - bounds.removeFromRight (5); - userSettingsButton->setBounds (bounds.removeFromRight (bounds.getHeight()).reduced (2)); + userAvatar.setBounds (bounds.removeFromRight (userAvatar.isDisplaingGPLLogo() ? roundToInt ((float) bounds.getHeight() * 1.9f) + : bounds.getHeight()).reduced (2)); } void HeaderComponent::paint (Graphics& g) @@ -110,48 +110,53 @@ void HeaderComponent::paint (Graphics& g) if (isBuilding) getLookAndFeel().drawSpinningWaitAnimation (g, findColour (treeIconColourId), - runAppButton->getX(), runAppButton->getY(), - runAppButton->getWidth(), runAppButton->getHeight()); + runAppButton.getX(), runAppButton.getY(), + runAppButton.getWidth(), runAppButton.getHeight()); } //============================================================================== -void HeaderComponent::setCurrentProject (Project* p) noexcept +void HeaderComponent::setCurrentProject (Project* newProject) { - project = p; - - exportersTree = project->getExporters(); - exportersTree.addListener (this); - updateExporters(); - - projectNameValue.referTo (project->getProjectValue (Ids::name)); - projectNameValue.addListener (this); - updateName(); - isBuilding = false; stopTimer(); repaint(); - childProcess = ProjucerApplication::getApp().childProcessCache->getExisting (*project); + projectNameLabel.setText ({}, dontSendNotification); - if (childProcess != nullptr) - { - childProcess->activityList.addChangeListener (this); - childProcess->errorList.addChangeListener (this); + project = newProject; - runAppButton->setTooltip ({}); - runAppButton->setEnabled (true); - } - else + if (project != nullptr) { - runAppButton->setTooltip ("Enable live-build engine to launch application"); - runAppButton->setEnabled (false); + exportersTree = project->getExporters(); + exportersTree.addListener (this); + updateExporters(); + + projectNameValue.referTo (project->getProjectValue (Ids::name)); + projectNameValue.addListener (this); + updateName(); + + childProcess = ProjucerApplication::getApp().childProcessCache->getExisting (*project); + + if (childProcess != nullptr) + { + childProcess->activityList.addChangeListener (this); + childProcess->errorList.addChangeListener (this); + + runAppButton.setTooltip ({}); + runAppButton.setEnabled (true); + } + else + { + runAppButton.setTooltip ("Enable live-build engine to launch application"); + runAppButton.setEnabled (false); + } } } //============================================================================== -void HeaderComponent::updateExporters() noexcept +void HeaderComponent::updateExporters() { - auto selectedName = getSelectedExporterName(); + auto selectedExporter = getSelectedExporter(); exporterBox.clear(); auto preferredExporterIndex = -1; @@ -159,12 +164,14 @@ void HeaderComponent::updateExporters() noexcept int i = 0; for (Project::ExporterIterator exporter (*project); exporter.next(); ++i) { - exporterBox.addItem (exporter->getName(), i + 1); + auto exporterName = exporter->getUniqueName(); - if (selectedName == exporter->getName()) + exporterBox.addItem (exporterName, i + 1); + + if (selectedExporter != nullptr && exporterName == selectedExporter->getUniqueName()) exporterBox.setSelectedId (i + 1); - if (exporter->getName().contains (ProjectExporter::getCurrentPlatformExporterName()) && preferredExporterIndex == -1) + if (exporterName.contains (ProjectExporter::getCurrentPlatformExporterTypeInfo().displayName) && preferredExporterIndex == -1) preferredExporterIndex = i; } @@ -189,60 +196,56 @@ void HeaderComponent::updateExporters() noexcept updateExporterButton(); } -String HeaderComponent::getSelectedExporterName() const noexcept +std::unique_ptr<ProjectExporter> HeaderComponent::getSelectedExporter() const { - return exporterBox.getItemText (exporterBox.getSelectedItemIndex()); + if (project != nullptr) + { + int i = 0; + auto selectedIndex = exporterBox.getSelectedItemIndex(); + + for (Project::ExporterIterator exporter (*project); exporter.next();) + if (i++ == selectedIndex) + return std::move (exporter.exporter); + } + + return nullptr; } -bool HeaderComponent::canCurrentExporterLaunchProject() const noexcept +bool HeaderComponent::canCurrentExporterLaunchProject() const { - for (Project::ExporterIterator exporter (*project); exporter.next();) - if (exporter->getName() == getSelectedExporterName() && exporter->canLaunchProject()) - return true; + if (project != nullptr) + { + if (auto selectedExporter = getSelectedExporter()) + { + for (Project::ExporterIterator exporter (*project); exporter.next();) + if (exporter->canLaunchProject() && exporter->getUniqueName() == selectedExporter->getUniqueName()) + return true; + } + } return false; } //============================================================================== -int HeaderComponent::getUserButtonWidth() const noexcept -{ - return userSettingsButton->getWidth(); -} - -void HeaderComponent::sidebarTabsWidthChanged (int newWidth) noexcept +void HeaderComponent::sidebarTabsWidthChanged (int newWidth) { tabsWidth = newWidth; resized(); } -//============================================================================== -void HeaderComponent::showUserSettings() noexcept +void HeaderComponent::liveBuildEnablementChanged (bool isEnabled) { - #if JUCER_ENABLE_GPL_MODE - auto settingsPopupHeight = 100; - auto settingsPopupWidth = 200; - #else - auto settingsPopupHeight = 150; - auto settingsPopupWidth = 250; - #endif - - auto* content = new UserSettingsPopup (false); - - content->setSize (settingsPopupWidth, settingsPopupHeight); - - userSettingsWindow = &CallOutBox::launchAsynchronously (content, userSettingsButton->getScreenBounds(), nullptr); + runAppButton.setVisible (isEnabled); } //============================================================================== -void HeaderComponent::lookAndFeelChanged() -{ - if (userSettingsWindow != nullptr) - userSettingsWindow->sendLookAndFeelChange(); -} - -void HeaderComponent::changeListenerCallback (ChangeBroadcaster*) +void HeaderComponent::changeListenerCallback (ChangeBroadcaster* source) { - if (childProcess != nullptr) + if (source == &userAvatar) + { + resized(); + } + else if (childProcess != nullptr && source == &childProcess->activityList) { if (childProcess->activityList.getNumActivities() > 0) buildPing(); @@ -262,103 +265,86 @@ void HeaderComponent::timerCallback() } //============================================================================== -static void sendProjectButtonAnalyticsEvent (StringRef label) +void HeaderComponent::initialiseButtons() { - StringPairArray data; - data.set ("label", label); - - Analytics::getInstance()->logEvent ("Project Button", data, ProjucerAnalyticsEvent::projectEvent); -} + addAndMakeVisible (projectSettingsButton); + projectSettingsButton.onClick = [this] { projectContentComponent->showProjectSettings(); }; -void HeaderComponent::initialiseButtons() noexcept -{ - auto& icons = getIcons(); - - projectSettingsButton.reset (new IconButton ("Project Settings", &icons.settings)); - addAndMakeVisible (projectSettingsButton.get()); - projectSettingsButton->onClick = [this] + addAndMakeVisible (saveAndOpenInIDEButton); + saveAndOpenInIDEButton.setBackgroundColour (Colours::white); + saveAndOpenInIDEButton.setIconInset (7); + saveAndOpenInIDEButton.onClick = [this] { - sendProjectButtonAnalyticsEvent ("Project Settings"); - - if (auto* pcc = findParentComponentOfClass<ProjectContentComponent>()) - pcc->showProjectSettings(); - }; + if (project != nullptr) + { + if (project->isSaveAndExportDisabled()) + { + auto setWarningVisible = [this] (const Identifier& identifier) + { + auto child = project->getProjectMessages().getChildWithName (ProjectMessages::Ids::warning) + .getChildWithName (identifier); - saveAndOpenInIDEButton.reset (new IconButton ("Save and Open in IDE", nullptr)); - addAndMakeVisible (saveAndOpenInIDEButton.get()); - saveAndOpenInIDEButton->isIDEButton = true; - saveAndOpenInIDEButton->onClick = [this] - { - sendProjectButtonAnalyticsEvent ("Save and Open in IDE (" + exporterBox.getText() + ")"); + if (child.isValid()) + child.setProperty (ProjectMessages::Ids::isVisible, true, nullptr); + }; - if (auto* pcc = findParentComponentOfClass<ProjectContentComponent>()) - pcc->openInSelectedIDE (true); - }; + if (project->hasIncompatibleLicenseTypeAndSplashScreenSetting()) + setWarningVisible (ProjectMessages::Ids::incompatibleLicense); - userSettingsButton.reset (new IconButton ("User Settings", &icons.user)); - addAndMakeVisible (userSettingsButton.get()); - userSettingsButton->isUserButton = true; - userSettingsButton->onClick = [this] - { - sendProjectButtonAnalyticsEvent ("User Settings"); - - if (findParentComponentOfClass<ProjectContentComponent>() != nullptr) - showUserSettings(); + if (project->isFileModificationCheckPending()) + setWarningVisible (ProjectMessages::Ids::jucerFileModified); + } + else + { + if (auto exporter = getSelectedExporter()) + project->openProjectInIDE (*exporter, true); + } + } }; - runAppButton.reset (new IconButton ("Run Application", &icons.play)); - addAndMakeVisible (runAppButton.get()); - runAppButton->onClick = [this] + addAndMakeVisible (runAppButton); + runAppButton.setIconInset (7); + runAppButton.onClick = [this] { - sendProjectButtonAnalyticsEvent ("Run Application"); - if (childProcess != nullptr) childProcess->launchApp(); }; updateExporterButton(); - updateUserAvatar(); } -void HeaderComponent::updateName() noexcept +void HeaderComponent::updateName() { - projectNameLabel.setText (project->getDocumentTitle(), dontSendNotification); + if (project != nullptr) + projectNameLabel.setText (project->getDocumentTitle(), dontSendNotification); } -void HeaderComponent::updateExporterButton() noexcept +void HeaderComponent::updateExporterButton() { - auto currentExporterName = getSelectedExporterName(); - - for (auto info : ProjectExporter::getExporterTypes()) + if (auto selectedExporter = getSelectedExporter()) { - if (currentExporterName.contains (info.name)) + auto selectedName = selectedExporter->getUniqueName(); + + for (auto info : ProjectExporter::getExporterTypeInfos()) { - saveAndOpenInIDEButton->iconImage = info.getIcon(); - saveAndOpenInIDEButton->repaint(); - saveAndOpenInIDEButton->setEnabled (canCurrentExporterLaunchProject()); + if (selectedName.contains (info.displayName)) + { + saveAndOpenInIDEButton.setImage (info.icon); + saveAndOpenInIDEButton.repaint(); + saveAndOpenInIDEButton.setEnabled (canCurrentExporterLaunchProject()); + } } } } -void HeaderComponent::updateUserAvatar() noexcept -{ - if (auto* controller = ProjucerApplication::getApp().licenseController.get()) - { - auto state = controller->getState(); - - userSettingsButton->iconImage = state.avatar; - userSettingsButton->repaint(); - } -} - //============================================================================== void HeaderComponent::buildPing() { if (! isTimerRunning()) { isBuilding = true; - runAppButton->setEnabled (false); - runAppButton->setTooltip ("Building..."); + runAppButton.setEnabled (false); + runAppButton.setTooltip ("Building..."); startTimer (50); } @@ -384,23 +370,23 @@ void HeaderComponent::setRunAppButtonState (bool buildWasSuccessful) { if (childProcess->isAppRunning() || (! childProcess->isAppRunning() && childProcess->canLaunchApp())) { - runAppButton->setTooltip ("Launch application"); + runAppButton.setTooltip ("Launch application"); shouldEnableButton = true; } else { - runAppButton->setTooltip ("Application can't be launched"); + runAppButton.setTooltip ("Application can't be launched"); } } else { - runAppButton->setTooltip ("Enable live-build engine to launch application"); + runAppButton.setTooltip ("Enable live-build engine to launch application"); } } else { - runAppButton->setTooltip ("Error building application"); + runAppButton.setTooltip ("Error building application"); } - runAppButton->setEnabled (shouldEnableButton); + runAppButton.setEnabled (shouldEnableButton); } diff --git a/extras/Projucer/Source/Project/UI/jucer_HeaderComponent.h b/extras/Projucer/Source/Project/UI/jucer_HeaderComponent.h index 0ebac873..14502f28 100644 --- a/extras/Projucer/Source/Project/UI/jucer_HeaderComponent.h +++ b/extras/Projucer/Source/Project/UI/jucer_HeaderComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -28,9 +27,12 @@ #include "../../Application/jucer_Headers.h" #include "../../Utility/UI/jucer_IconButton.h" -#include "../../Utility/UI/jucer_UserSettingsPopup.h" +#include "jucer_UserAvatarComponent.h" class Project; +class ProjectContentComponent; +class ProjectExporter; +class CompileEngineChildProcess; //============================================================================== class HeaderComponent : public Component, @@ -40,7 +42,7 @@ class HeaderComponent : public Component, private Timer { public: - HeaderComponent(); + HeaderComponent (ProjectContentComponent* projectContentComponent); ~HeaderComponent() override; //============================================================================== @@ -48,23 +50,17 @@ public: void paint (Graphics&) override; //============================================================================== - void setCurrentProject (Project*) noexcept; + void setCurrentProject (Project*); - //============================================================================== - void updateExporters() noexcept; - String getSelectedExporterName() const noexcept; - bool canCurrentExporterLaunchProject() const noexcept; - - //============================================================================== - int getUserButtonWidth() const noexcept; - void sidebarTabsWidthChanged (int newWidth) noexcept; + void updateExporters(); + std::unique_ptr<ProjectExporter> getSelectedExporter() const; + bool canCurrentExporterLaunchProject() const; - //============================================================================== - void showUserSettings() noexcept; + void sidebarTabsWidthChanged (int newWidth); + void liveBuildEnablementChanged (bool isEnabled); private: //============================================================================== - void lookAndFeelChanged() override; void changeListenerCallback (ChangeBroadcaster* source) override; void valueChanged (Value&) override; void timerCallback() override; @@ -74,18 +70,17 @@ private: void valueTreeChildRemoved (ValueTree& parentTree, ValueTree&, int) override { updateIfNeeded (parentTree); } void valueTreeChildOrderChanged (ValueTree& parentTree, int, int) override { updateIfNeeded (parentTree); } - void updateIfNeeded (ValueTree tree) noexcept + void updateIfNeeded (ValueTree tree) { if (tree == exportersTree) updateExporters(); } //============================================================================== - void initialiseButtons() noexcept; + void initialiseButtons(); - void updateName() noexcept; - void updateExporterButton() noexcept; - void updateUserAvatar() noexcept; + void updateName(); + void updateExporterButton(); //============================================================================== void buildPing(); @@ -96,19 +91,21 @@ private: int tabsWidth = 200; bool isBuilding = false; + ProjectContentComponent* projectContentComponent = nullptr; Project* project = nullptr; ValueTree exportersTree; Value projectNameValue; ComboBox exporterBox; - Label configLabel { "Config Label", "Selected exporter" }, - projectNameLabel; + Label configLabel { "Config Label", "Selected exporter" }, projectNameLabel; - std::unique_ptr<ImageComponent> juceIcon; - std::unique_ptr<IconButton> projectSettingsButton, saveAndOpenInIDEButton, userSettingsButton, runAppButton; + ImageComponent juceIcon; + UserAvatarComponent userAvatar { true }; - SafePointer<CallOutBox> userSettingsWindow; + IconButton projectSettingsButton { "Project Settings", getIcons().settings }, + saveAndOpenInIDEButton { "Save and Open in IDE", Image() }, + runAppButton { "Run Application", getIcons().play }; ReferenceCountedObjectPtr<CompileEngineChildProcess> childProcess; diff --git a/extras/Projucer/Source/Project/UI/jucer_ModulesInformationComponent.h b/extras/Projucer/Source/Project/UI/jucer_ModulesInformationComponent.h index d78f9c02..6cf4b9a8 100644 --- a/extras/Projucer/Source/Project/UI/jucer_ModulesInformationComponent.h +++ b/extras/Projucer/Source/Project/UI/jucer_ModulesInformationComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -37,9 +36,10 @@ public: : project (p), modulesValueTree (project.getEnabledModules().getState()) { - listHeader = new ListBoxHeader ( { "Module", "Version", "Make Local Copy", "Paths" }, - { 0.25f, 0.2f, 0.2f, 0.35f } ); - list.setHeaderComponent (listHeader); + auto tempHeader = std::make_unique<ListBoxHeader> (Array<String> { "Module", "Version", "Make Local Copy", "Paths" }, + Array<float> { 0.25f, 0.2f, 0.2f, 0.35f }); + listHeader = tempHeader.get(); + list.setHeaderComponent (std::move (tempHeader)); list.setModel (this); list.setColour (ListBox::backgroundColourId, Colours::transparentBlack); addAndMakeVisible (list); @@ -125,18 +125,18 @@ public: //============================================================================== auto moduleID = project.getEnabledModules().getModuleID (rowNumber); - g.drawFittedText (moduleID, bounds.removeFromLeft (roundToInt (listHeader->getProportionAtIndex (0) * width)), Justification::centredLeft, 1); + g.drawFittedText (moduleID, bounds.removeFromLeft (roundToInt (listHeader->getProportionAtIndex (0) * (float) 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); + g.drawFittedText (version, bounds.removeFromLeft (roundToInt (listHeader->getProportionAtIndex (1) * (float) width)), Justification::centredLeft, 1); //============================================================================== g.drawFittedText (String (project.getEnabledModules().shouldCopyModuleFilesLocally (moduleID) ? "Yes" : "No"), - bounds.removeFromLeft (roundToInt (listHeader->getProportionAtIndex (2) * width)), Justification::centredLeft, 1); + bounds.removeFromLeft (roundToInt (listHeader->getProportionAtIndex (2) * (float) width)), Justification::centredLeft, 1); //============================================================================== String pathText; @@ -155,7 +155,7 @@ public: pathText = paths.joinIntoString (", "); } - g.drawFittedText (pathText, bounds.removeFromLeft (roundToInt (listHeader->getProportionAtIndex (3) * width)), Justification::centredLeft, 1); + g.drawFittedText (pathText, bounds.removeFromLeft (roundToInt (listHeader->getProportionAtIndex (3) * (float) width)), Justification::centredLeft, 1); } void listBoxItemDoubleClicked (int row, const MouseEvent&) override @@ -282,13 +282,13 @@ private: m.addItem (PopupMenu::Item ("Copy the paths from the module '" + moduleToCopy + "' to all other modules") .setAction ([this, moduleToCopy] { - auto& moduleList = project.getEnabledModules(); + auto& modulesList = project.getEnabledModules(); for (Project::ExporterIterator exporter (project); exporter.next();) { - for (int i = 0; i < moduleList.getNumModules(); ++i) + for (int i = 0; i < modulesList.getNumModules(); ++i) { - auto modID = moduleList.getModuleID (i); + auto modID = modulesList.getModuleID (i); if (modID != moduleToCopy) exporter->getPathForModuleValue (modID) = exporter->getPathForModuleValue (moduleToCopy).get(); @@ -305,7 +305,7 @@ private: modulePathClipboard.clear(); for (Project::ExporterIterator exporter (project); exporter.next();) - modulePathClipboard[exporter->getName()] = exporter->getPathForModuleValue (moduleToCopy).get(); + modulePathClipboard[exporter->getUniqueName()] = exporter->getPathForModuleValue (moduleToCopy).get(); list.repaint(); })); @@ -320,7 +320,7 @@ private: auto modID = project.getEnabledModules().getModuleID (rowNumber); for (Project::ExporterIterator exporter (project); exporter.next();) - exporter->getPathForModuleValue (modID) = modulePathClipboard[exporter->getName()]; + exporter->getPathForModuleValue (modID) = modulePathClipboard[exporter->getUniqueName()]; } list.repaint(); diff --git a/extras/Projucer/Source/Project/UI/jucer_ProjectContentComponent.cpp b/extras/Projucer/Source/Project/UI/jucer_ProjectContentComponent.cpp index 052e3c00..a1900796 100644 --- a/extras/Projucer/Source/Project/UI/jucer_ProjectContentComponent.cpp +++ b/extras/Projucer/Source/Project/UI/jucer_ProjectContentComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -29,44 +28,50 @@ #include "../../LiveBuildEngine/jucer_DownloadCompileEngineThread.h" #include "../../LiveBuildEngine/jucer_CompileEngineSettings.h" -#include "jucer_HeaderComponent.h" #include "Sidebar/jucer_TabComponents.h" #include "Sidebar/jucer_ProjectTab.h" #include "Sidebar/jucer_LiveBuildTab.h" +NewFileWizard::Type* createGUIComponentWizard(); + //============================================================================== -struct LogoComponent : public Component +ProjectContentComponent::LogoComponent::LogoComponent() { - LogoComponent() - { - if (auto svg = parseXML (BinaryData::background_logo_svg)) - logo = Drawable::createFromSVG (*svg); - else - jassertfalse; - } + if (auto svg = parseXML (BinaryData::background_logo_svg)) + logo = Drawable::createFromSVG (*svg); +} - void paint (Graphics& g) override - { - g.setColour (findColour (defaultTextColourId)); +void ProjectContentComponent::LogoComponent::paint (Graphics& g) +{ + g.setColour (findColour (defaultTextColourId)); - auto r = getLocalBounds(); + auto r = getLocalBounds(); - g.setFont (15.0f); - g.drawFittedText (getVersionInfo(), r.removeFromBottom (50), Justification::centredBottom, 3); + g.setFont (15.0f); + g.drawFittedText (getVersionInfo(), r.removeFromBottom (50), Justification::centredBottom, 3); - logo->drawWithin (g, r.withTrimmedBottom (r.getHeight() / 4).toFloat(), - RectanglePlacement (RectanglePlacement::centred), 1.0f); - } + logo->drawWithin (g, r.withTrimmedBottom (r.getHeight() / 4).toFloat(), + RectanglePlacement (RectanglePlacement::centred), 1.0f); +} - static String getVersionInfo() - { - return SystemStats::getJUCEVersion() - + newLine - + ProjucerApplication::getApp().getVersionDescription(); - } +String ProjectContentComponent::LogoComponent::getVersionInfo() +{ + return SystemStats::getJUCEVersion() + + newLine + + ProjucerApplication::getApp().getVersionDescription(); +} - std::unique_ptr<Drawable> logo; -}; +//============================================================================== +ProjectContentComponent::ContentViewport::ContentViewport (Component* content) +{ + addAndMakeVisible (viewport); + viewport.setViewedComponent (content, true); +} + +void ProjectContentComponent::ContentViewport::resized() +{ + viewport.setBounds (getLocalBounds()); +} //============================================================================== ProjectContentComponent::ProjectContentComponent() @@ -74,15 +79,12 @@ ProjectContentComponent::ProjectContentComponent() setOpaque (true); setWantsKeyboardFocus (true); - logo.reset (new LogoComponent()); - addAndMakeVisible (logo.get()); + addAndMakeVisible (logoComponent); + addAndMakeVisible (headerComponent); + addAndMakeVisible (projectMessagesComponent); - header.reset (new HeaderComponent()); - addAndMakeVisible (header.get()); - - fileNameLabel.reset (new Label()); - addAndMakeVisible (fileNameLabel.get()); - fileNameLabel->setJustificationType (Justification::centred); + addAndMakeVisible (fileNameLabel); + fileNameLabel.setJustificationType (Justification::centred); sidebarSizeConstrainer.setMinimumWidth (200); sidebarSizeConstrainer.setMaximumWidth (500); @@ -92,8 +94,11 @@ ProjectContentComponent::ProjectContentComponent() ProjucerApplication::getApp().openDocumentManager.addListener (this); + isLiveBuildEnabled = getGlobalProperties().getBoolValue (Ids::liveBuildEnabled); + getGlobalProperties().addChangeListener (this); + liveBuildEnablementChanged (isLiveBuildEnabled); + Desktop::getInstance().addFocusChangeListener (this); - startTimer (1600); } ProjectContentComponent::~ProjectContentComponent() @@ -101,15 +106,11 @@ ProjectContentComponent::~ProjectContentComponent() Desktop::getInstance().removeFocusChangeListener (this); killChildProcess(); + getGlobalProperties().removeChangeListener (this); ProjucerApplication::getApp().openDocumentManager.removeListener (this); - logo.reset(); - header.reset(); setProject (nullptr); - contentView.reset(); - fileNameLabel.reset(); removeChildComponent (&bubbleMessage); - jassert (getNumChildComponents() <= 1); } void ProjectContentComponent::paint (Graphics& g) @@ -123,11 +124,10 @@ void ProjectContentComponent::resized() r.removeFromRight (10); r.removeFromLeft (15); - r.removeFromBottom (40); r.removeFromTop (5); - if (header != nullptr) - header->setBounds (r.removeFromTop (40)); + projectMessagesComponent.setBounds (r.removeFromBottom (40).withWidth (100).reduced (0, 5)); + headerComponent.setBounds (r.removeFromTop (40)); r.removeFromTop (10); @@ -140,22 +140,15 @@ void ProjectContentComponent::resized() if (resizerBar != nullptr) resizerBar->setBounds (r.withWidth (4)); - if (auto* h = dynamic_cast<HeaderComponent*> (header.get())) - { - h->sidebarTabsWidthChanged (sidebarTabs.getWidth()); - r.removeFromRight (h->getUserButtonWidth()); - } + headerComponent.sidebarTabsWidthChanged (sidebarTabs.getWidth()); if (contentView != nullptr) { - if (fileNameLabel != nullptr && fileNameLabel->isVisible()) - fileNameLabel->setBounds (r.removeFromTop (15)); - + fileNameLabel.setBounds (r.removeFromTop (15)); contentView->setBounds (r); } - if (logo != nullptr) - logo->setBounds (r.reduced (r.getWidth() / 6, r.getHeight() / 6)); + logoComponent.setBounds (r.reduced (r.getWidth() / 6, r.getHeight() / 6)); } void ProjectContentComponent::lookAndFeelChanged() @@ -176,7 +169,7 @@ void ProjectContentComponent::setProject (Project* newProject) { if (project != newProject) { - lastCrashMessage = String(); + lastCrashMessage = {}; killChildProcess(); if (project != nullptr) @@ -187,7 +180,8 @@ void ProjectContentComponent::setProject (Project* newProject) deleteProjectTabs(); project = newProject; - rebuildProjectTabs(); + + rebuildProjectUI(); } } @@ -210,20 +204,21 @@ void ProjectContentComponent::createProjectTabs() auto tabColour = Colours::transparentBlack; - auto* pTab = new ProjectTab (project); - sidebarTabs.addTab ("Project", tabColour, pTab, true); + sidebarTabs.addTab (getProjectTabName(), tabColour, new ProjectTab (project), true); - CompileEngineChildProcess::Ptr childProc (getChildProcess()); - - sidebarTabs.addTab ("Build", tabColour, new LiveBuildTab (childProc, lastCrashMessage), true); - - if (childProc != nullptr) + if (isLiveBuildEnabled) { - childProc->crashHandler = [this] (const String& m) { this->handleCrash (m); }; + CompileEngineChildProcess::Ptr childProc (getChildProcess()); + sidebarTabs.addTab (getBuildTabName(), tabColour, new LiveBuildTab (childProc, lastCrashMessage), true); + + if (childProc != nullptr) + { + childProc->crashHandler = [this] (const String& m) { this->handleCrash (m); }; - sidebarTabs.getTabbedButtonBar().getTabButton (1)->setExtraComponent (new BuildStatusTabComp (childProc->errorList, - childProc->activityList), - TabBarButton::afterText); + sidebarTabs.getTabbedButtonBar().getTabButton (1)->setExtraComponent (new BuildStatusTabComp (childProc->errorList, + childProc->activityList), + TabBarButton::afterText); + } } } @@ -246,7 +241,7 @@ void ProjectContentComponent::deleteProjectTabs() sidebarTabs.clearTabs(); } -void ProjectContentComponent::rebuildProjectTabs() +void ProjectContentComponent::rebuildProjectUI() { deleteProjectTabs(); @@ -264,7 +259,12 @@ void ProjectContentComponent::rebuildProjectTabs() sidebarTabs.setBounds (0, 0, lastTreeWidth, getHeight()); - sidebarTabs.setCurrentTabIndex (settings.getValue ("lastViewedTabIndex", "0").getIntValue()); + auto lastTabIndex = settings.getValue ("lastViewedTabIndex", "0").getIntValue(); + + if (lastTabIndex >= sidebarTabs.getNumTabs()) + lastTabIndex = 0; + + sidebarTabs.setCurrentTabIndex (lastTabIndex); auto* projectTab = getProjectTab(); for (int i = 2; i >= 0; --i) @@ -281,18 +281,20 @@ void ProjectContentComponent::rebuildProjectTabs() updateMissingFileStatuses(); - if (auto* h = dynamic_cast<HeaderComponent*> (header.get())) - { - h->setVisible (true); - h->setCurrentProject (project); - } + headerComponent.setVisible (true); + headerComponent.setCurrentProject (project); + + projectMessagesComponent.setVisible (true); } else { sidebarTabs.setVisible (false); - header->setVisible (false); + headerComponent.setVisible (false); + projectMessagesComponent.setVisible (false); } + projectMessagesComponent.setProject (project); + resized(); } @@ -329,9 +331,19 @@ bool ProjectContentComponent::documentAboutToClose (OpenDocumentManager::Documen return true; } -void ProjectContentComponent::changeListenerCallback (ChangeBroadcaster*) +void ProjectContentComponent::changeListenerCallback (ChangeBroadcaster* broadcaster) { - updateMissingFileStatuses(); + if (broadcaster == project) + { + updateMissingFileStatuses(); + } + else if (broadcaster == &getGlobalProperties()) + { + auto isEnabled = ProjucerApplication::getApp().isLiveBuildEnabled(); + + if (isLiveBuildEnabled != isEnabled) + liveBuildEnablementChanged (isEnabled); + } } void ProjectContentComponent::refreshProjectTreeFileStatuses() @@ -353,8 +365,7 @@ bool ProjectContentComponent::showEditorForFile (const File& f, bool grabFocus) if (getCurrentFile() == f || showDocument (ProjucerApplication::getApp().openDocumentManager.openFile (project, f), grabFocus)) { - fileNameLabel->setText (f.getFileName(), dontSendNotification); - + fileNameLabel.setText (f.getFileName(), dontSendNotification); return true; } @@ -403,8 +414,7 @@ void ProjectContentComponent::hideEditor() currentDocument = nullptr; contentView.reset(); - if (fileNameLabel != nullptr) - fileNameLabel->setVisible (false); + fileNameLabel.setVisible (false); ProjucerApplication::getCommandManager().commandStatusChanged(); resized(); @@ -434,7 +444,7 @@ bool ProjectContentComponent::setEditorComponent (Component* editor, contentView.reset (viewport); currentDocument = nullptr; - fileNameLabel->setVisible (false); + fileNameLabel.setVisible (false); addAndMakeVisible (viewport); } @@ -442,8 +452,8 @@ bool ProjectContentComponent::setEditorComponent (Component* editor, { contentView.reset (editor); currentDocument = doc; - fileNameLabel->setText (doc->getFile().getFileName(), dontSendNotification); - fileNameLabel->setVisible (true); + fileNameLabel.setText (doc->getFile().getFileName(), dontSendNotification); + fileNameLabel.setVisible (true); addAndMakeVisible (editor); } @@ -469,7 +479,8 @@ Component* ProjectContentComponent::getEditorComponentContent() const void ProjectContentComponent::closeDocument() { if (currentDocument != nullptr) - ProjucerApplication::getApp().openDocumentManager.closeDocument (currentDocument, true); + ProjucerApplication::getApp().openDocumentManager + .closeDocument (currentDocument, OpenDocumentManager::SaveIfNeeded::yes); else if (contentView != nullptr) if (! goToPreviousFile()) hideEditor(); @@ -543,15 +554,10 @@ bool ProjectContentComponent::goToCounterpart() return false; } -bool ProjectContentComponent::saveProject (bool shouldWait, bool openInIDE) +bool ProjectContentComponent::saveProject() { if (project != nullptr) - { - const ScopedValueSetter<bool> valueSetter (project->shouldWaitAfterSaving, shouldWait, false); - project->setOpenInIDEAfterSaving (openInIDE); - return (project->save (true, true) == FileBasedDocument::savedOk); - } return false; } @@ -559,7 +565,7 @@ bool ProjectContentComponent::saveProject (bool shouldWait, bool openInIDE) void ProjectContentComponent::closeProject() { if (auto* mw = findParentComponentOfClass<MainWindow>()) - mw->closeCurrentProject (true); + mw->closeCurrentProject (OpenDocumentManager::SaveIfNeeded::yes); } void ProjectContentComponent::showProjectSettings() @@ -569,8 +575,8 @@ void ProjectContentComponent::showProjectSettings() void ProjectContentComponent::showCurrentExporterSettings() { - if (auto* h = dynamic_cast<HeaderComponent*> (header.get())) - showExporterSettings (h->getSelectedExporterName()); + if (auto selected = headerComponent.getSelectedExporter()) + showExporterSettings (selected->getUniqueName()); } void ProjectContentComponent::showExporterSettings (const String& exporterName) @@ -582,7 +588,7 @@ void ProjectContentComponent::showExporterSettings (const String& exporterName) if (auto* exportersPanel = getProjectTab()->getExportersTreePanel()) { - if (auto* exporters = dynamic_cast<TreeItemTypes::ExportersTreeRoot*>(exportersPanel->rootItem.get())) + if (auto* exporters = dynamic_cast<TreeItemTypes::ExportersTreeRoot*> (exportersPanel->rootItem.get())) { for (auto i = exporters->getNumSubItems(); i >= 0; --i) { @@ -631,12 +637,6 @@ void ProjectContentComponent::showLiveBuildSettings() setEditorComponent (new LiveBuildSettingsComponent (*project), nullptr); } -void ProjectContentComponent::showUserSettings() -{ - if (auto* headerComp = dynamic_cast<HeaderComponent*> (header.get())) - headerComp->showUserSettings(); -} - StringArray ProjectContentComponent::getExportersWhichCanLaunch() const { StringArray s; @@ -644,7 +644,7 @@ StringArray ProjectContentComponent::getExportersWhichCanLaunch() const if (project != nullptr) for (Project::ExporterIterator exporter (*project); exporter.next();) if (exporter->canLaunchProject()) - s.add (exporter->getName()); + s.add (exporter->getUniqueName()); return s; } @@ -652,50 +652,8 @@ StringArray ProjectContentComponent::getExportersWhichCanLaunch() const void ProjectContentComponent::openInSelectedIDE (bool saveFirst) { if (project != nullptr) - { - if (auto* headerComp = dynamic_cast<HeaderComponent*> (header.get())) - { - auto selectedIDE = headerComp->getSelectedExporterName(); - - for (Project::ExporterIterator exporter (*project); exporter.next();) - { - if (exporter->canLaunchProject() && exporter->getName().contains (selectedIDE)) - { - auto tempProject = project->isTemporaryProject(); // store this before saving as it will always be false after - - if (saveFirst && ! saveProject (exporter->isXcode(), true)) - return; - - if (tempProject) - return; - - exporter->launchProject(); - return; - } - } - } - } -} - -static void newExporterMenuCallback (int result, ProjectContentComponent* comp) -{ - if (comp != nullptr && result > 0) - { - if (auto* p = comp->getProject()) - { - auto exporterName= ProjectExporter::getExporterNames() [result - 1]; - - if (exporterName.isNotEmpty()) - { - p->addNewExporter (exporterName); - - StringPairArray data; - data.set ("label", exporterName); - - Analytics::getInstance()->logEvent ("Exporter Added", data, ProjucerAnalyticsEvent::projectEvent); - } - } - } + if (auto selectedExporter = headerComponent.getSelectedExporter()) + project->openProjectInIDE (*selectedExporter, saveFirst); } void ProjectContentComponent::showNewExporterMenu() @@ -706,17 +664,34 @@ void ProjectContentComponent::showNewExporterMenu() menu.addSectionHeader ("Create a new export target:"); - auto exporters = ProjectExporter::getExporterTypes(); + SafePointer<ProjectContentComponent> safeThis (this); - for (int i = 0; i < exporters.size(); ++i) + for (auto& exporterInfo : ProjectExporter::getExporterTypeInfos()) { - auto& type = exporters.getReference(i); + PopupMenu::Item item; - menu.addItem (i + 1, type.name, true, false, type.getIcon()); + item.itemID = -1; + item.text = exporterInfo.displayName; + + item.image = [exporterInfo] + { + auto drawableImage = std::make_unique<DrawableImage>(); + drawableImage->setImage (exporterInfo.icon); + + return drawableImage; + }(); + + item.action = [safeThis, exporterInfo] + { + if (safeThis != nullptr) + if (auto* p = safeThis->getProject()) + p->addNewExporter (exporterInfo.identifier); + }; + + menu.addItem (item); } - menu.showMenuAsync (PopupMenu::Options(), - ModalCallbackFunction::forComponent (newExporterMenuCallback, this)); + menu.showMenuAsync ({}); } } @@ -823,7 +798,8 @@ void ProjectContentComponent::getAllCommands (Array <CommandID>& commands) CommandIDs::reinstantiateComp, CommandIDs::showWarnings, CommandIDs::nextError, - CommandIDs::prevError }); + CommandIDs::prevError, + CommandIDs::addNewGUIFile }); } void ProjectContentComponent::getCommandInfo (const CommandID commandID, ApplicationCommandInfo& result) @@ -844,7 +820,7 @@ void ProjectContentComponent::getCommandInfo (const CommandID commandID, Applica result.setInfo ("Save Project", "Saves the current project", CommandCategories::general, 0); - result.setActive (project != nullptr && ! project->isCurrentlySaving()); + result.setActive (project != nullptr && ! project->isSaveAndExportDisabled() && ! project->isCurrentlySaving()); result.defaultKeypresses.add ({ 'p', ModifierKeys::commandModifier, 0 }); break; @@ -923,7 +899,7 @@ void ProjectContentComponent::getCommandInfo (const CommandID commandID, Applica result.setInfo ("Show Build Tab", "Shows the tab containing the build panel", CommandCategories::general, 0); - result.setActive (project != nullptr); + result.setActive (project != nullptr && isLiveBuildEnabled); result.defaultKeypresses.add ({ 'b', cmdCtrl, 0 }); break; @@ -963,14 +939,14 @@ void ProjectContentComponent::getCommandInfo (const CommandID commandID, Applica result.setInfo ("Open in IDE...", "Launches the project in an external IDE", CommandCategories::general, 0); - result.setActive (ProjectExporter::canProjectBeLaunched (project)); + result.setActive (ProjectExporter::canProjectBeLaunched (project) && ! project->isSaveAndExportDisabled()); break; case CommandIDs::saveAndOpenInIDE: result.setInfo ("Save Project and Open in IDE...", "Saves the project and launches it in an external IDE", CommandCategories::general, 0); - result.setActive (ProjectExporter::canProjectBeLaunched (project) && ! project->isCurrentlySaving()); + result.setActive (ProjectExporter::canProjectBeLaunched (project) && ! project->isSaveAndExportDisabled() && ! project->isCurrentlySaving()); result.defaultKeypresses.add ({ 'l', ModifierKeys::commandModifier | ModifierKeys::shiftModifier, 0 }); break; @@ -1077,6 +1053,13 @@ void ProjectContentComponent::getCommandInfo (const CommandID commandID, Applica result.setActive (childProcess != nullptr && ! childProcess->errorList.isEmpty()); break; + case CommandIDs::addNewGUIFile: + result.setInfo ("Add new GUI Component...", + "Adds a new GUI Component file to the project", + CommandCategories::general, + (! ProjucerApplication::getApp().isGUIEditorEnabled() ? ApplicationCommandInfo::isDisabled : 0)); + break; + default: break; } @@ -1153,6 +1136,8 @@ bool ProjectContentComponent::perform (const InvocationInfo& info) case CommandIDs::nextError: showNextError(); break; case CommandIDs::prevError: showPreviousError(); break; + case CommandIDs::addNewGUIFile: addNewGUIFile(); break; + default: return false; } @@ -1192,17 +1177,12 @@ void ProjectContentComponent::setBuildEnabled (bool isEnabled, bool displayError project->getCompileEngineSettings().setBuildEnabled (isEnabled); killChildProcess(); refreshTabsIfBuildStatusChanged(); - - StringPairArray data; - data.set ("label", isEnabled ? "Enabled" : "Disabled"); - - Analytics::getInstance()->logEvent ("Live-Build", data, ProjucerAnalyticsEvent::projectEvent); } } void ProjectContentComponent::cleanAll() { - lastCrashMessage = String(); + lastCrashMessage = {}; if (childProcess != nullptr) childProcess->cleanAll(); @@ -1220,25 +1200,24 @@ void ProjectContentComponent::handleCrash (const String& message) setBuildEnabled (false, true); showBuildTab(); } - - StringPairArray data; - data.set ("label", "Crash"); - - Analytics::getInstance()->logEvent ("Live-Build", data, ProjucerAnalyticsEvent::projectEvent); } bool ProjectContentComponent::isBuildEnabled() const { - return project != nullptr && project->getCompileEngineSettings().isBuildEnabled() - && CompileEngineDLL::getInstance()->isLoaded(); + return isLiveBuildEnabled + && project != nullptr + && project->getCompileEngineSettings().isBuildEnabled() + && CompileEngineDLL::getInstance()->isLoaded(); } void ProjectContentComponent::refreshTabsIfBuildStatusChanged() { if (project != nullptr - && (sidebarTabs.getNumTabs() < 2 - || isBuildEnabled() != isBuildTabEnabled())) - rebuildProjectTabs(); + && isLiveBuildEnabled + && (sidebarTabs.getNumTabs() < 2 || isBuildEnabled() != isBuildTabEnabled())) + { + rebuildProjectUI(); + } } bool ProjectContentComponent::areWarningsEnabled() const @@ -1293,6 +1272,15 @@ void ProjectContentComponent::reinstantiateLivePreviewWindows() childProcess->reinstantiatePreviews(); } +void ProjectContentComponent::addNewGUIFile() +{ + if (project != nullptr) + { + std::unique_ptr<NewFileWizard::Type> wizard (createGUIComponentWizard()); + wizard->createNewFile (*project, project->getMainGroup()); + } +} + void ProjectContentComponent::launchApp() { if (childProcess != nullptr) @@ -1333,6 +1321,24 @@ void ProjectContentComponent::timerCallback() refreshTabsIfBuildStatusChanged(); } +void ProjectContentComponent::liveBuildEnablementChanged (bool isEnabled) +{ + isLiveBuildEnabled = isEnabled; + + if (isLiveBuildEnabled) + { + startTimer (1600); + } + else + { + stopTimer(); + killChildProcess(); + } + + rebuildProjectUI(); + headerComponent.liveBuildEnablementChanged (isLiveBuildEnabled); +} + bool ProjectContentComponent::isContinuousRebuildEnabled() { return project != nullptr && project->getCompileEngineSettings().isContinuousRebuildEnabled(); diff --git a/extras/Projucer/Source/Project/UI/jucer_ProjectContentComponent.h b/extras/Projucer/Source/Project/UI/jucer_ProjectContentComponent.h index 5e9c8d36..1654df2b 100644 --- a/extras/Projucer/Source/Project/UI/jucer_ProjectContentComponent.h +++ b/extras/Projucer/Source/Project/UI/jucer_ProjectContentComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -27,11 +26,12 @@ #pragma once #include "../../CodeEditor/jucer_OpenDocumentManager.h" +#include "jucer_HeaderComponent.h" +#include "jucer_ProjectMessagesComponent.h" class CompileEngineChildProcess; class ProjectTab; class LiveBuildTab; -class HeaderComponent; //============================================================================== class ProjectContentComponent : public Component, @@ -47,7 +47,7 @@ public: ~ProjectContentComponent() override; Project* getProject() const noexcept { return project; } - virtual void setProject (Project*); + void setProject (Project*); void saveTreeViewState(); void saveOpenDocumentList(); @@ -75,14 +75,14 @@ public: bool canGoToCounterpart() const; bool goToCounterpart(); - bool saveProject (bool shouldWait = false, bool openInIDE = false); + bool saveProject(); void closeProject(); void openInSelectedIDE (bool saveFirst); void showNewExporterMenu(); - void showProjectTab() { sidebarTabs.setCurrentTabIndex (0); } - void showBuildTab() { sidebarTabs.setCurrentTabIndex (1); } - int getCurrentTabIndex() { return sidebarTabs.getCurrentTabIndex(); } + void showProjectTab() { sidebarTabs.setCurrentTabIndex (0); } + void showBuildTab() { sidebarTabs.setCurrentTabIndex (1); } + int getCurrentTabIndex() { return sidebarTabs.getCurrentTabIndex(); } void showFilesPanel() { showProjectPanel (0); } void showModulesPanel() { showProjectPanel (1); } @@ -101,12 +101,13 @@ public: void updateMissingFileStatuses(); void createProjectTabs(); void deleteProjectTabs(); - void rebuildProjectTabs(); + void rebuildProjectUI(); void refreshTabsIfBuildStatusChanged(); void toggleWarnings(); void showNextError(); void showPreviousError(); void reinstantiateLivePreviewWindows(); + void addNewGUIFile(); void showBubbleMessage (Rectangle<int>, const String&); @@ -137,28 +138,31 @@ public: void childBoundsChanged (Component*) override; void lookAndFeelChanged() override; - String lastCrashMessage; + ProjectMessagesComponent& getProjectMessagesComponent() { return projectMessagesComponent; } -private: - friend HeaderComponent; + static String getProjectTabName() { return "Project"; } + static String getBuildTabName() { return "Build"; } +private: //============================================================================== - Project* project = nullptr; - OpenDocumentManager::Document* currentDocument = nullptr; - RecentDocumentList recentDocumentList; - std::unique_ptr<Component> logo, translationTool, contentView, header; + struct LogoComponent : public Component + { + LogoComponent(); + void paint (Graphics& g) override; + static String getVersionInfo(); - TabbedComponent sidebarTabs { TabbedButtonBar::TabsAtTop }; - std::unique_ptr<ResizableEdgeComponent> resizerBar; - ComponentBoundsConstrainer sidebarSizeConstrainer; + std::unique_ptr<Drawable> logo; + }; - BubbleMessageComponent bubbleMessage; - ReferenceCountedObjectPtr<CompileEngineChildProcess> childProcess; - bool isForeground = false; + struct ContentViewport : public Component + { + ContentViewport (Component* content); + void resized() override; - std::unique_ptr<Label> fileNameLabel; + Viewport viewport; - int lastViewedTab = 0; + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ContentViewport) + }; //============================================================================== bool documentAboutToClose (OpenDocumentManager::Document*) override; @@ -168,6 +172,8 @@ private: void globalFocusChanged (Component*) override; void timerCallback() override; + void liveBuildEnablementChanged (bool isEnabled); + bool isContinuousRebuildEnabled(); void setContinuousRebuildEnabled (bool b); @@ -186,23 +192,26 @@ private: bool canSelectedProjectBeLaunch(); //============================================================================== - struct ContentViewport : public Component - { - ContentViewport (Component* content) - { - addAndMakeVisible (viewport); - viewport.setViewedComponent (content, true); - } + Project* project = nullptr; + OpenDocumentManager::Document* currentDocument = nullptr; + RecentDocumentList recentDocumentList; - void resized() override - { - viewport.setBounds (getLocalBounds()); - } + LogoComponent logoComponent; + HeaderComponent headerComponent { this }; + ProjectMessagesComponent projectMessagesComponent; + Label fileNameLabel; + TabbedComponent sidebarTabs { TabbedButtonBar::TabsAtTop }; + std::unique_ptr<ResizableEdgeComponent> resizerBar; + ComponentBoundsConstrainer sidebarSizeConstrainer; + std::unique_ptr<Component> translationTool, contentView; + BubbleMessageComponent bubbleMessage; - Viewport viewport; + ReferenceCountedObjectPtr<CompileEngineChildProcess> childProcess; + String lastCrashMessage; - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ContentViewport) - }; + bool isForeground = false, isLiveBuildEnabled = false; + int lastViewedTab = 0; + //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProjectContentComponent) }; diff --git a/extras/Projucer/Source/Project/UI/jucer_ProjectMessagesComponent.h b/extras/Projucer/Source/Project/UI/jucer_ProjectMessagesComponent.h new file mode 100644 index 00000000..b8dc861b --- /dev/null +++ b/extras/Projucer/Source/Project/UI/jucer_ProjectMessagesComponent.h @@ -0,0 +1,555 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +#pragma once + +#include "../../Application/jucer_CommonHeaders.h" +#include "../../Application/jucer_Application.h" + +//============================================================================== +class MessagesPopupWindow : public Component, + private ComponentMovementWatcher +{ +public: + MessagesPopupWindow (Component& target, Component& parent, Project& project) + : ComponentMovementWatcher (&parent), + targetComponent (target), + parentComponent (parent), + messagesListComponent (*this, project) + { + parentComponent.addAndMakeVisible (this); + setAlwaysOnTop (true); + + addAndMakeVisible (viewport); + viewport.setScrollBarsShown (true, false); + viewport.setViewedComponent (&messagesListComponent, false); + viewport.setWantsKeyboardFocus (false); + + setOpaque (true); + } + + void paint (Graphics& g) override + { + g.fillAll (findColour (secondaryBackgroundColourId)); + } + + void resized() override + { + viewport.setBounds (getLocalBounds()); + } + + bool isListShowing() const + { + return messagesListComponent.getRequiredHeight() > 0; + } + + void updateBounds (bool animate) + { + auto targetBounds = parentComponent.getLocalArea (&targetComponent, targetComponent.getLocalBounds()); + + auto height = jmin (messagesListComponent.getRequiredHeight(), maxHeight); + auto yPos = jmax (indent, targetBounds.getY() - height); + + Rectangle<int> bounds (targetBounds.getX(), yPos, + jmin (width, parentComponent.getWidth() - targetBounds.getX() - indent), targetBounds.getY() - yPos); + + auto& animator = Desktop::getInstance().getAnimator(); + + if (animate) + { + setBounds (bounds.withY (targetBounds.getY())); + animator.animateComponent (this, bounds, 1.0f, 150, false, 1.0, 1.0); + } + else + { + if (animator.isAnimating (this)) + animator.cancelAnimation (this, false); + + setBounds (bounds); + } + + messagesListComponent.resized(); + } + +private: + //============================================================================== + class MessagesListComponent : public Component, + private ValueTree::Listener, + private AsyncUpdater + { + public: + MessagesListComponent (MessagesPopupWindow& o, Project& currentProject) + : owner (o), + project (currentProject) + { + messagesTree = project.getProjectMessages(); + messagesTree.addListener (this); + + setOpaque (true); + + messagesChanged(); + } + + void resized() override + { + auto bounds = getLocalBounds(); + auto numMessages = messages.size(); + + for (size_t i = 0; i < numMessages; ++i) + { + messages[i]->setBounds (bounds.removeFromTop (messageHeight)); + + if (numMessages > 1 && i != (numMessages - 1)) + bounds.removeFromTop (messageSpacing); + } + } + + void paint (Graphics& g) override + { + g.fillAll (findColour (backgroundColourId).contrasting (0.2f)); + } + + int getRequiredHeight() const + { + auto numMessages = (int) messages.size(); + + if (numMessages > 0) + return (numMessages * messageHeight) + ((numMessages - 1) * messageSpacing); + + return 0; + } + + void updateSize (int parentWidth) + { + setSize (parentWidth, getRequiredHeight()); + } + + private: + static constexpr int messageHeight = 65; + static constexpr int messageSpacing = 2; + + //============================================================================== + struct MessageComponent : public Component + { + MessageComponent (MessagesListComponent& listComponent, + const Identifier& messageToDisplay, + std::vector<ProjectMessages::MessageAction> messageActions) + : message (messageToDisplay) + { + for (auto& action : messageActions) + { + auto button = std::make_unique<TextButton> (action.first); + addAndMakeVisible (*button); + button->onClick = action.second; + + buttons.push_back (std::move (button)); + } + + icon = (ProjectMessages::getTypeForMessage (message) == ProjectMessages::Ids::warning ? getIcons().warning : getIcons().info); + + messageTitleLabel.setText (ProjectMessages::getTitleForMessage (message), dontSendNotification); + messageTitleLabel.setFont (Font (11.0f).boldened()); + addAndMakeVisible (messageTitleLabel); + + messageDescriptionLabel.setText (ProjectMessages::getDescriptionForMessage (message), dontSendNotification); + messageDescriptionLabel.setFont (Font (11.0f)); + messageDescriptionLabel.setJustificationType (Justification::topLeft); + addAndMakeVisible (messageDescriptionLabel); + + dismissButton.setShape (getLookAndFeel().getCrossShape (1.0f), false, true, false); + addAndMakeVisible (dismissButton); + + dismissButton.onClick = [this, &listComponent] + { + listComponent.messagesTree.getChildWithName (ProjectMessages::getTypeForMessage (message)) + .getChildWithName (message) + .setProperty (ProjectMessages::Ids::isVisible, false, nullptr); + }; + } + + void paint (Graphics& g) override + { + g.fillAll (findColour (secondaryBackgroundColourId).contrasting (0.1f)); + + auto bounds = getLocalBounds().reduced (5); + + g.setColour (findColour (defaultIconColourId)); + g.fillPath (icon, icon.getTransformToScaleToFit (bounds.removeFromTop (messageTitleHeight) + .removeFromLeft (messageTitleHeight).toFloat(), true)); + } + + void resized() override + { + auto bounds = getLocalBounds().reduced (5); + + auto topSlice = bounds.removeFromTop (messageTitleHeight); + + topSlice.removeFromLeft (messageTitleHeight + 5); + topSlice.removeFromRight (5); + + dismissButton.setBounds (topSlice.removeFromRight (messageTitleHeight)); + messageTitleLabel.setBounds (topSlice); + bounds.removeFromTop (5); + + auto numButtons = (int) buttons.size(); + + if (numButtons > 0) + { + auto buttonBounds = bounds.removeFromBottom (buttonHeight); + + auto buttonWidth = roundToInt ((float) buttonBounds.getWidth() / 3.5f); + auto requiredWidth = (numButtons * buttonWidth) + ((numButtons - 1) * buttonSpacing); + buttonBounds.reduce ((buttonBounds.getWidth() - requiredWidth) / 2, 0); + + for (auto& b : buttons) + { + b->setBounds (buttonBounds.removeFromLeft (buttonWidth)); + buttonBounds.removeFromLeft (buttonSpacing); + } + + bounds.removeFromBottom (5); + } + + messageDescriptionLabel.setBounds (bounds); + } + + static constexpr int messageTitleHeight = 11; + static constexpr int buttonHeight = messageHeight / 4; + static constexpr int buttonSpacing = 5; + + Identifier message; + + Path icon; + Label messageTitleLabel, messageDescriptionLabel; + std::vector<std::unique_ptr<TextButton>> buttons; + ShapeButton dismissButton { {}, + findColour (treeIconColourId), + findColour (treeIconColourId).overlaidWith (findColour (defaultHighlightedTextColourId).withAlpha (0.2f)), + findColour (treeIconColourId).overlaidWith (findColour (defaultHighlightedTextColourId).withAlpha (0.4f)) }; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MessageComponent) + }; + + //============================================================================== + void valueTreePropertyChanged (ValueTree&, const Identifier&) override { messagesChanged(); } + void valueTreeChildAdded (ValueTree&, ValueTree&) override { messagesChanged(); } + void valueTreeChildRemoved (ValueTree&, ValueTree&, int) override { messagesChanged(); } + void valueTreeChildOrderChanged (ValueTree&, int, int) override { messagesChanged(); } + void valueTreeParentChanged (ValueTree&) override { messagesChanged(); } + void valueTreeRedirected (ValueTree&) override { messagesChanged(); } + + void handleAsyncUpdate() override + { + messagesChanged(); + } + + void messagesChanged() + { + auto listWasShowing = (getHeight() > 0); + + auto warningsTree = messagesTree.getChildWithName (ProjectMessages::Ids::warning); + auto notificationsTree = messagesTree.getChildWithName (ProjectMessages::Ids::notification); + + auto removePredicate = [warningsTree, notificationsTree] (std::unique_ptr<MessageComponent>& messageComponent) + { + for (int i = 0; i < warningsTree.getNumChildren(); ++i) + { + auto child = warningsTree.getChild (i); + + if (child.getType() == messageComponent->message + && child.getProperty (ProjectMessages::Ids::isVisible)) + { + return false; + } + } + + for (int i = 0; i < notificationsTree.getNumChildren(); ++i) + { + auto child = notificationsTree.getChild (i); + + if (child.getType() == messageComponent->message + && child.getProperty (ProjectMessages::Ids::isVisible)) + { + return false; + } + } + + return true; + }; + + messages.erase (std::remove_if (std::begin (messages), std::end (messages), removePredicate), + std::end (messages)); + + for (int i = 0; i < warningsTree.getNumChildren(); ++i) + { + auto child = warningsTree.getChild (i); + + if (! child.getProperty (ProjectMessages::Ids::isVisible)) + continue; + + if (std::find_if (std::begin (messages), std::end (messages), + [child] (const std::unique_ptr<MessageComponent>& messageComponent) { return messageComponent->message == child.getType(); }) + == std::end (messages)) + { + messages.push_back (std::make_unique<MessageComponent> (*this, child.getType(), project.getMessageActions (child.getType()))); + addAndMakeVisible (*messages.back()); + } + } + + for (int i = 0; i < notificationsTree.getNumChildren(); ++i) + { + auto child = notificationsTree.getChild (i); + + if (! child.getProperty (ProjectMessages::Ids::isVisible)) + continue; + + if (std::find_if (std::begin (messages), std::end (messages), + [child] (const std::unique_ptr<MessageComponent>& messageComponent) { return messageComponent->message == child.getType(); }) + == std::end (messages)) + { + messages.push_back (std::make_unique<MessageComponent> (*this, child.getType(), project.getMessageActions (child.getType()))); + addAndMakeVisible (*messages.back()); + } + } + + auto isNowShowing = (messages.size() > 0); + + owner.updateBounds (isNowShowing != listWasShowing); + updateSize (owner.getWidth()); + } + + //============================================================================== + MessagesPopupWindow& owner; + Project& project; + + ValueTree messagesTree; + std::vector<std::unique_ptr<MessageComponent>> messages; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MessagesListComponent) + }; + + //============================================================================== + void componentMovedOrResized (bool, bool) override + { + if (isListShowing()) + updateBounds (false); + } + + using ComponentMovementWatcher::componentMovedOrResized; + + void componentPeerChanged() override + { + if (isListShowing()) + updateBounds (false); + } + + void componentVisibilityChanged() override + { + if (isListShowing()) + updateBounds (false); + } + + using ComponentMovementWatcher::componentVisibilityChanged; + + //============================================================================== + static constexpr int maxHeight = 500, width = 350, indent = 20; + + Component& targetComponent; + Component& parentComponent; + + Viewport viewport; + MessagesListComponent messagesListComponent; + + //============================================================================== + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MessagesPopupWindow) +}; + +//============================================================================== +class ProjectMessagesComponent : public Component +{ +public: + ProjectMessagesComponent() + { + addAndMakeVisible (warningsComponent); + addAndMakeVisible (notificationsComponent); + + warningsComponent.addMouseListener (this, true); + notificationsComponent.addMouseListener (this, true); + + setOpaque (true); + } + + //============================================================================== + void resized() override + { + auto b = getLocalBounds(); + + warningsComponent.setBounds (b.removeFromLeft (b.getWidth() / 2).reduced (5)); + notificationsComponent.setBounds (b.reduced (5)); + } + + void paint (Graphics& g) override + { + auto backgroundColour = findColour (backgroundColourId); + + if (isMouseDown || isMouseOver) + backgroundColour = backgroundColour.overlaidWith (findColour (defaultHighlightColourId) + .withAlpha (isMouseDown ? 1.0f : 0.8f)); + + g.fillAll (backgroundColour); + } + + //============================================================================== + void mouseEnter (const MouseEvent&) override + { + isMouseOver = true; + repaint(); + } + + void mouseExit (const MouseEvent&) override + { + isMouseOver = false; + repaint(); + } + + void mouseDown (const MouseEvent&) override + { + isMouseDown = true; + repaint(); + } + + void mouseUp (const MouseEvent&) override + { + isMouseDown = false; + repaint(); + + if (messagesWindow != nullptr) + showOrHideAllMessages (! messagesWindow->isListShowing()); + } + + //============================================================================== + void setProject (Project* newProject) + { + if (currentProject != newProject) + { + currentProject = newProject; + + if (currentProject != nullptr) + { + auto* projectWindow = ProjucerApplication::getApp().mainWindowList.getMainWindowForFile (currentProject->getFile()); + jassert (projectWindow != nullptr); + messagesWindow = std::make_unique<MessagesPopupWindow> (*this, *projectWindow, *currentProject); + + auto projectMessagesTree = currentProject->getProjectMessages(); + + warningsComponent.setTree (projectMessagesTree.getChildWithName (ProjectMessages::Ids::warning)); + notificationsComponent.setTree (projectMessagesTree.getChildWithName (ProjectMessages::Ids::notification)); + } + else + { + warningsComponent.setTree ({}); + notificationsComponent.setTree ({}); + } + } + } + +private: + //============================================================================== + struct MessageCountComponent : public Component, + private ValueTree::Listener + { + MessageCountComponent (ProjectMessagesComponent& o, Path pathToUse) + : owner (o), + path (pathToUse) + { + setInterceptsMouseClicks (false, false); + } + + void paint (Graphics& g) override + { + auto b = getLocalBounds().toFloat(); + + g.setColour (findColour ((owner.isMouseDown || owner.isMouseOver) ? defaultHighlightedTextColourId : treeIconColourId)); + g.fillPath (path, path.getTransformToScaleToFit (b.removeFromLeft (b.getWidth() / 2.0f), true)); + + b.removeFromLeft (5); + g.drawFittedText (String (numMessages), b.getSmallestIntegerContainer(), Justification::centredLeft, 1); + } + + void setTree (ValueTree tree) + { + messagesTree = tree; + + if (messagesTree.isValid()) + messagesTree.addListener (this); + + updateNumMessages(); + } + + void updateNumMessages() + { + numMessages = messagesTree.getNumChildren(); + repaint(); + } + + private: + void valueTreeChildAdded (ValueTree&, ValueTree&) override { updateNumMessages(); } + void valueTreeChildRemoved (ValueTree&, ValueTree&, int) override { updateNumMessages(); } + + ProjectMessagesComponent& owner; + ValueTree messagesTree; + + Path path; + int numMessages = 0; + }; + + void showOrHideAllMessages (bool shouldBeVisible) + { + if (currentProject != nullptr) + { + auto messagesTree = currentProject->getProjectMessages(); + + auto setVisible = [shouldBeVisible] (ValueTree subTree) + { + for (int i = 0; i < subTree.getNumChildren(); ++i) + subTree.getChild (i).setProperty (ProjectMessages::Ids::isVisible, shouldBeVisible, nullptr); + }; + + setVisible (messagesTree.getChildWithName (ProjectMessages::Ids::warning)); + setVisible (messagesTree.getChildWithName (ProjectMessages::Ids::notification)); + } + } + + //============================================================================== + Project* currentProject = nullptr; + bool isMouseOver = false, isMouseDown = false; + + MessageCountComponent warningsComponent { *this, getIcons().warning }, + notificationsComponent { *this, getIcons().info }; + + std::unique_ptr<MessagesPopupWindow> messagesWindow; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProjectMessagesComponent) +}; diff --git a/extras/Projucer/Source/Project/UI/jucer_UserAvatarComponent.h b/extras/Projucer/Source/Project/UI/jucer_UserAvatarComponent.h new file mode 100644 index 00000000..f48fac8d --- /dev/null +++ b/extras/Projucer/Source/Project/UI/jucer_UserAvatarComponent.h @@ -0,0 +1,157 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +#pragma once + +#include "../../Application/jucer_Application.h" + +//============================================================================== +class UserAvatarComponent : public Component, + public SettableTooltipClient, + public ChangeBroadcaster, + private LicenseController::LicenseStateListener +{ +public: + UserAvatarComponent (bool isInteractive) + : interactive (isInteractive) + { + ProjucerApplication::getApp().getLicenseController().addListener (this); + lookAndFeelChanged(); + } + + ~UserAvatarComponent() override + { + ProjucerApplication::getApp().getLicenseController().removeListener (this); + } + + void paint (Graphics& g) override + { + auto bounds = getLocalBounds(); + + if (! isGPL) + { + bounds = bounds.removeFromRight (bounds.getHeight()); + + Path ellipse; + ellipse.addEllipse (bounds.toFloat()); + + g.reduceClipRegion (ellipse); + } + + g.drawImage (currentAvatar, bounds.toFloat(), RectanglePlacement::fillDestination); + } + + void mouseUp (const MouseEvent&) override + { + if (interactive) + { + PopupMenu menu; + menu.addCommandItem (ProjucerApplication::getApp().commandManager.get(), CommandIDs::loginLogout); + + menu.showMenuAsync (PopupMenu::Options().withTargetComponent (this)); + } + } + + bool isDisplaingGPLLogo() const noexcept { return isGPL; } + +private: + //============================================================================== + static Image createGPLAvatarImage() + { + if (auto logo = Drawable::createFromImageData (BinaryData::gpl_logo_svg, BinaryData::gpl_logo_svgSize)) + { + auto bounds = logo->getDrawableBounds(); + + Image image (Image::ARGB, roundToInt (bounds.getWidth()), roundToInt (bounds.getHeight()), true); + Graphics g (image); + logo->draw (g, 1.0f); + + return image; + } + + jassertfalse; + return {}; + } + + Image createStandardAvatarImage() + { + Image image (Image::ARGB, 250, 250, true); + Graphics g (image); + + g.setColour (findColour (defaultButtonBackgroundColourId)); + g.fillAll(); + + g.setColour (findColour (defaultIconColourId)); + + auto path = getIcons().user; + g.fillPath (path, RectanglePlacement (RectanglePlacement::centred) + .getTransformToFit (path.getBounds(), image.getBounds().reduced (image.getHeight() / 5).toFloat())); + + return image; + } + + //============================================================================== + void licenseStateChanged() override + { + auto state = ProjucerApplication::getApp().getLicenseController().getCurrentState(); + + isGPL = ProjucerApplication::getApp().getLicenseController().getCurrentState().isGPL(); + + if (interactive) + { + auto formattedUserString = [state]() -> String + { + if (state.isSignedIn()) + return (state.isGPL() ? "" : (state.username + " - ")) + state.getLicenseTypeString(); + + return "Not logged in"; + }(); + + setTooltip (formattedUserString); + } + + currentAvatar = isGPL ? gplAvatarImage + : state.isSignedIn() ? standardAvatarImage : signedOutAvatarImage; + + repaint(); + sendChangeMessage(); + } + + void lookAndFeelChanged() override + { + standardAvatarImage = createStandardAvatarImage(); + signedOutAvatarImage = createStandardAvatarImage(); + + if (interactive) + signedOutAvatarImage.multiplyAllAlphas (0.4f); + + licenseStateChanged(); + repaint(); + } + + //============================================================================== + Image standardAvatarImage, signedOutAvatarImage, gplAvatarImage { createGPLAvatarImage() }, currentAvatar; + bool isGPL = false, interactive = false; +}; diff --git a/extras/Projucer/Source/Project/jucer_Project.cpp b/extras/Projucer/Source/Project/jucer_Project.cpp index 24d48f84..ea8bd288 100644 --- a/extras/Projucer/Source/Project/jucer_Project.cpp +++ b/extras/Projucer/Source/Project/jucer_Project.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -30,17 +29,60 @@ #include "../Application/jucer_Application.h" #include "../LiveBuildEngine/jucer_CompileEngineSettings.h" -namespace +//============================================================================== +Project::ProjectFileModificationPoller::ProjectFileModificationPoller (Project& p) + : project (p) +{ + startTimer (250); +} + +void Project::ProjectFileModificationPoller::reset() { - String makeValid4CC (const String& seed) + project.removeProjectMessage (ProjectMessages::Ids::jucerFileModified); + pending = false; + + startTimer (250); +} + +void Project::ProjectFileModificationPoller::timerCallback() +{ + if (project.updateCachedFileState() && ! pending) { - auto s = CodeHelpers::makeValidIdentifier (seed, false, true, false) + "xxxx"; + project.addProjectMessage (ProjectMessages::Ids::jucerFileModified, + { { "Save current state", [this] { resaveProject(); } }, + { "Re-load from disk", [this] { reloadProjectFromDisk(); } }, + { "Ignore", [this] { reset(); } } }); - return s.substring (0, 1).toUpperCase() - + s.substring (1, 4).toLowerCase(); + stopTimer(); + pending = true; } } +void Project::ProjectFileModificationPoller::reloadProjectFromDisk() +{ + auto oldTemporaryDirectory = project.getTemporaryDirectory(); + auto projectFile = project.getFile(); + + MessageManager::callAsync ([oldTemporaryDirectory, projectFile] + { + if (auto* mw = ProjucerApplication::getApp().mainWindowList.getMainWindowForFile (projectFile)) + { + mw->closeCurrentProject (OpenDocumentManager::SaveIfNeeded::no); + mw->openFile (projectFile); + + if (oldTemporaryDirectory != File()) + if (auto* newProject = mw->getProject()) + newProject->setTemporaryDirectory (oldTemporaryDirectory); + } + }); +} + +void Project::ProjectFileModificationPoller::resaveProject() +{ + reset(); + project.saveProject(); +} + //============================================================================== Project::Project (const File& f) : FileBasedDocument (projectFileExtension, @@ -49,36 +91,45 @@ Project::Project (const File& f) "Save Jucer project") { Logger::writeToLog ("Loading project: " + f.getFullPathName()); - setFile (f); - removeDefunctExporters(); - exporterPathsModuleList.reset (new AvailableModuleList()); - updateOldModulePaths(); - updateOldStyleConfigList(); - setCppVersionFromOldExporterSettings(); - moveOldPropertyFromProjectToAllExporters (Ids::bigIcon); - moveOldPropertyFromProjectToAllExporters (Ids::smallIcon); + setFile (f); initialiseProjectValues(); initialiseMainGroup(); initialiseAudioPluginValues(); - parsedPreprocessorDefs = parsePreprocessorDefs (preprocessorDefsValue.get()); + setChangedFlag (false); + updateCachedFileState(); - getEnabledModules().sortAlphabetically(); + auto& app = ProjucerApplication::getApp(); - projectRoot.addListener (this); + if (! app.isRunningCommandLine) + app.getLicenseController().addListener (this); - compileEngineSettings.reset (new CompileEngineSettings (projectRoot)); + app.getJUCEPathModulesList().addListener (this); + app.getUserPathsModulesList().addListener (this); - setChangedFlag (false); - modificationTime = getFile().getLastModificationTime(); + updateJUCEPathWarning(); + getGlobalProperties().addChangeListener (this); + + if (! app.isRunningCommandLine && app.isAutomaticVersionCheckingEnabled()) + LatestVersionCheckerAndUpdater::getInstance()->checkForNewVersion (true); } Project::~Project() { projectRoot.removeListener (this); - ProjucerApplication::getApp().openDocumentManager.closeAllDocumentsUsingProject (*this, false); + getGlobalProperties().removeChangeListener (this); + + auto& app = ProjucerApplication::getApp(); + + app.openDocumentManager.closeAllDocumentsUsingProject (*this, OpenDocumentManager::SaveIfNeeded::no); + + if (! app.isRunningCommandLine) + app.getLicenseController().removeListener (this); + + app.getJUCEPathModulesList().removeListener (this); + app.getUserPathsModulesList().removeListener (this); } const char* Project::projectFileExtension = ".jucer"; @@ -100,7 +151,7 @@ void Project::updateTitleDependencies() pluginNameValue. setDefault (projectName); pluginDescriptionValue. setDefault (projectName); bundleIdentifierValue. setDefault (getDefaultBundleIdentifierString()); - pluginAUExportPrefixValue.setDefault (CodeHelpers::makeValidIdentifier (projectName, false, true, false) + "AU"); + pluginAUExportPrefixValue.setDefault (build_tools::makeValidIdentifier (projectName, false, true, false) + "AU"); pluginAAXIdentifierValue. setDefault (getDefaultAAXIdentifierString()); } @@ -114,11 +165,12 @@ void Project::updateCompanyNameDependencies() bundleIdentifierValue.setDefault (getDefaultBundleIdentifierString()); pluginAAXIdentifierValue.setDefault (getDefaultAAXIdentifierString()); pluginManufacturerValue.setDefault (getDefaultPluginManufacturerString()); + + updateLicenseWarning(); } void Project::updateProjectSettings() { - projectRoot.setProperty (Ids::jucerVersion, ProjectInfo::versionString, nullptr); projectRoot.setProperty (Ids::name, getDocumentTitle(), nullptr); } @@ -126,7 +178,7 @@ bool Project::setCppVersionFromOldExporterSettings() { auto highestLanguageStandard = -1; - for (Project::ExporterIterator exporter (*this); exporter.next();) + for (ExporterIterator exporter (*this); exporter.next();) { if (exporter->isXcode()) // cpp version was per-build configuration for xcode exporters { @@ -151,7 +203,7 @@ bool Project::setCppVersionFromOldExporterSettings() { if (cppLanguageStandard.toString().containsIgnoreCase ("latest")) { - cppStandardValue = "latest"; + cppStandardValue = Project::getCppStandardVars().getLast(); return true; } @@ -172,12 +224,18 @@ bool Project::setCppVersionFromOldExporterSettings() return false; } +void Project::updateDeprecatedProjectSettings() +{ + for (ExporterIterator exporter (*this); exporter.next();) + exporter->updateDeprecatedSettings(); +} + void Project::updateDeprecatedProjectSettingsInteractively() { jassert (! ProjucerApplication::getApp().isRunningCommandLine); - for (Project::ExporterIterator exporter (*this); exporter.next();) - exporter->updateDeprecatedProjectSettingsInteractively(); + for (ExporterIterator exporter (*this); exporter.next();) + exporter->updateDeprecatedSettingsInteractively(); } void Project::initialiseMainGroup() @@ -194,44 +252,36 @@ void Project::initialiseMainGroup() void Project::initialiseProjectValues() { - projectNameValue.referTo (projectRoot, Ids::name, getUndoManager(), "JUCE Project"); - projectUIDValue.referTo (projectRoot, Ids::ID, getUndoManager(), createAlphaNumericUID()); + projectNameValue.referTo (projectRoot, Ids::name, getUndoManager(), "JUCE Project"); + projectUIDValue.referTo (projectRoot, Ids::ID, getUndoManager(), createAlphaNumericUID()); if (projectUIDValue.isUsingDefault()) projectUIDValue = projectUIDValue.getDefault(); - projectLineFeedValue.referTo (projectRoot, Ids::projectLineFeed, getUndoManager(), "\r\n"); + projectLineFeedValue.referTo (projectRoot, Ids::projectLineFeed, getUndoManager(), "\r\n"); - companyNameValue.referTo (projectRoot, Ids::companyName, getUndoManager()); - companyCopyrightValue.referTo (projectRoot, Ids::companyCopyright, getUndoManager()); - companyWebsiteValue.referTo (projectRoot, Ids::companyWebsite, getUndoManager()); - companyEmailValue.referTo (projectRoot, Ids::companyEmail, getUndoManager()); + companyNameValue.referTo (projectRoot, Ids::companyName, getUndoManager()); + companyCopyrightValue.referTo (projectRoot, Ids::companyCopyright, getUndoManager()); + companyWebsiteValue.referTo (projectRoot, Ids::companyWebsite, getUndoManager()); + companyEmailValue.referTo (projectRoot, Ids::companyEmail, getUndoManager()); - projectTypeValue.referTo (projectRoot, Ids::projectType, getUndoManager(), ProjectType_GUIApp::getTypeName()); - versionValue.referTo (projectRoot, Ids::version, getUndoManager(), "1.0.0"); - bundleIdentifierValue.referTo (projectRoot, Ids::bundleIdentifier, getUndoManager(), getDefaultBundleIdentifierString()); + projectTypeValue.referTo (projectRoot, Ids::projectType, getUndoManager(), build_tools::ProjectType_GUIApp::getTypeName()); + versionValue.referTo (projectRoot, Ids::version, getUndoManager(), "1.0.0"); + bundleIdentifierValue.referTo (projectRoot, Ids::bundleIdentifier, getUndoManager(), getDefaultBundleIdentifierString()); - displaySplashScreenValue.referTo (projectRoot, Ids::displaySplashScreen, getUndoManager(), ! ProjucerApplication::getApp().isPaidOrGPL()); + displaySplashScreenValue.referTo (projectRoot, Ids::displaySplashScreen, getUndoManager(), false); splashScreenColourValue.referTo (projectRoot, Ids::splashScreenColour, getUndoManager(), "Dark"); - reportAppUsageValue.referTo (projectRoot, Ids::reportAppUsage, getUndoManager()); - if (ProjucerApplication::getApp().isPaidOrGPL()) - { - reportAppUsageValue.setDefault (ProjucerApplication::getApp().licenseController->getState().applicationUsageDataState - == LicenseState::ApplicationUsageData::enabled); - } - else - { - reportAppUsageValue.setDefault (true); - } + useAppConfigValue.referTo (projectRoot, Ids::useAppConfig, getUndoManager(), true); + addUsingNamespaceToJuceHeader.referTo (projectRoot, Ids::addUsingNamespaceToJuceHeader, getUndoManager(), true); cppStandardValue.referTo (projectRoot, Ids::cppLanguageStandard, getUndoManager(), "14"); - headerSearchPathsValue.referTo (projectRoot, Ids::headerPath, getUndoManager()); - preprocessorDefsValue.referTo (projectRoot, Ids::defines, getUndoManager()); - userNotesValue.referTo (projectRoot, Ids::userNotes, getUndoManager()); + headerSearchPathsValue.referTo (projectRoot, Ids::headerPath, getUndoManager()); + preprocessorDefsValue.referTo (projectRoot, Ids::defines, getUndoManager()); + userNotesValue.referTo (projectRoot, Ids::userNotes, getUndoManager()); - maxBinaryFileSizeValue.referTo (projectRoot, Ids::maxBinaryFileSize, getUndoManager(), 10240 * 1024); + maxBinaryFileSizeValue.referTo (projectRoot, Ids::maxBinaryFileSize, getUndoManager(), 10240 * 1024); // this is here for backwards compatibility with old projects using the incorrect id if (projectRoot.hasProperty ("includeBinaryInAppConfig")) @@ -249,6 +299,14 @@ void Project::initialiseProjectValues() void Project::initialiseAudioPluginValues() { + auto makeValid4CC = [] (const String& seed) + { + auto s = build_tools::makeValidIdentifier (seed, false, true, false) + "xxxx"; + + return s.substring (0, 1).toUpperCase() + + s.substring (1, 4).toLowerCase(); + }; + pluginFormatsValue.referTo (projectRoot, Ids::pluginFormats, getUndoManager(), Array<var> (Ids::buildVST3.toString(), Ids::buildAU.toString(), Ids::buildStandalone.toString()), ","); pluginCharacteristicsValue.referTo (projectRoot, Ids::pluginCharacteristicsValue, getUndoManager(), Array<var> (), ","); @@ -261,7 +319,7 @@ void Project::initialiseAudioPluginValues() pluginChannelConfigsValue.referTo (projectRoot, Ids::pluginChannelConfigs, getUndoManager()); pluginAAXIdentifierValue.referTo (projectRoot, Ids::aaxIdentifier, getUndoManager(), getDefaultAAXIdentifierString()); pluginAUExportPrefixValue.referTo (projectRoot, Ids::pluginAUExportPrefix, getUndoManager(), - CodeHelpers::makeValidIdentifier (getProjectNameString(), false, true, false) + "AU"); + build_tools::makeValidIdentifier (getProjectNameString(), false, true, false) + "AU"); pluginAUMainTypeValue.referTo (projectRoot, Ids::pluginAUMainType, getUndoManager(), getDefaultAUMainTypes(), ","); pluginAUSandboxSafeValue.referTo (projectRoot, Ids::pluginAUIsSandboxSafe, getUndoManager(), false); @@ -282,7 +340,7 @@ void Project::updateOldStyleConfigList() { projectRoot.removeChild (deprecatedConfigsList, nullptr); - for (Project::ExporterIterator exporter (*this); exporter.next();) + for (ExporterIterator exporter (*this); exporter.next();) { if (exporter->getNumConfigurations() == 0) { @@ -310,7 +368,7 @@ void Project::moveOldPropertyFromProjectToAllExporters (Identifier name) { if (projectRoot.hasProperty (name)) { - for (Project::ExporterIterator exporter (*this); exporter.next();) + for (ExporterIterator exporter (*this); exporter.next();) exporter->settings.setProperty (name, projectRoot [name], nullptr); projectRoot.removeProperty (name, nullptr); @@ -348,7 +406,7 @@ void Project::removeDefunctExporters() void Project::updateOldModulePaths() { - for (Project::ExporterIterator exporter (*this); exporter.next();) + for (ExporterIterator exporter (*this); exporter.next();) exporter->updateOldModulePaths(); } @@ -522,37 +580,15 @@ static constexpr int getBuiltJuceVersion() + JUCE_BUILDNUMBER; } -static bool isModuleNewerThanProjucer (const ModuleDescription& module) +//============================================================================== +static File& lastDocumentOpenedSingleton() { - return module.getID().startsWith ("juce_") && getJuceVersion (module.getVersion()) > getBuiltJuceVersion(); + static File lastDocumentOpened; + return lastDocumentOpened; } -void Project::warnAboutOldProjucerVersion() -{ - for (auto& juceModule : ProjucerApplication::getApp().getJUCEPathModuleList().getAllModules()) - { - if (isModuleNewerThanProjucer ({ juceModule.second })) - { - if (ProjucerApplication::getApp().isRunningCommandLine) - std::cout << "WARNING! This version of the Projucer is out-of-date!" << std::endl; - else - AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon, - "Projucer", - "This version of the Projucer is out-of-date!" - "\n\n" - "Always make sure that you're running the very latest version, " - "preferably compiled directly from the JUCE repository that you're working with!"); - - return; - } - } -} - -//============================================================================== -static File lastDocumentOpened; - -File Project::getLastDocumentOpened() { return lastDocumentOpened; } -void Project::setLastDocumentOpened (const File& file) { lastDocumentOpened = file; } +File Project::getLastDocumentOpened() { return lastDocumentOpenedSingleton(); } +void Project::setLastDocumentOpened (const File& file) { lastDocumentOpenedSingleton() = file; } static void registerRecentFile (const File& file) { @@ -583,8 +619,10 @@ Result Project::loadDocument (const File& file) registerRecentFile (file); - enabledModuleList.reset(); + enabledModulesList.reset(); + projectRoot = newTree; + projectRoot.addListener (this); initialiseProjectValues(); initialiseMainGroup(); @@ -598,57 +636,347 @@ Result Project::loadDocument (const File& file) removeDefunctExporters(); updateOldModulePaths(); - setChangedFlag (false); - - if (! ProjucerApplication::getApp().isRunningCommandLine) - warnAboutOldProjucerVersion(); + updateOldStyleConfigList(); + moveOldPropertyFromProjectToAllExporters (Ids::bigIcon); + moveOldPropertyFromProjectToAllExporters (Ids::smallIcon); + getEnabledModules().sortAlphabetically(); compileEngineSettings.reset (new CompileEngineSettings (projectRoot)); - exporterPathsModuleList.reset (new AvailableModuleList()); rescanExporterPathModules (! ProjucerApplication::getApp().isRunningCommandLine); + exporterPathsModulesList.addListener (this); + + if (cppStandardValue.isUsingDefault()) + setCppVersionFromOldExporterSettings(); + + updateDeprecatedProjectSettings(); + + setChangedFlag (false); + + updateExporterWarnings(); + updateLicenseWarning(); return Result::ok(); } Result Project::saveDocument (const File& file) { - return saveProject (file, false); + jassert (file == getFile()); + ignoreUnused (file); + + return saveProject(); } -Result Project::saveProject (const File& file, bool isCommandLineApp) +Result Project::saveProject (ProjectExporter* exporterToSave) { + if (isSaveAndExportDisabled()) + return Result::fail ("Save and export is disabled."); + if (isSaving) return Result::ok(); if (isTemporaryProject()) { - askUserWhereToSaveProject(); + saveAndMoveTemporaryProject (false); return Result::ok(); } updateProjectSettings(); - if (! isCommandLineApp) + if (! ProjucerApplication::getApp().isRunningCommandLine) { ProjucerApplication::getApp().openDocumentManager.saveAll(); if (! isTemporaryProject()) - registerRecentFile (file); + registerRecentFile (getFile()); } const ScopedValueSetter<bool> vs (isSaving, true, false); - ProjectSaver saver (*this, file); - return saver.save (! isCommandLineApp, shouldWaitAfterSaving, specifiedExporterToSave); + ProjectSaver saver (*this); + return saver.save (exporterToSave); +} + +Result Project::openProjectInIDE (ProjectExporter& exporterToOpen, bool saveFirst) +{ + for (ExporterIterator exporter (*this); exporter.next();) + { + if (exporter->canLaunchProject() && exporter->getUniqueName() == exporterToOpen.getUniqueName()) + { + if (isTemporaryProject()) + { + saveAndMoveTemporaryProject (true); + return Result::ok(); + } + + if (saveFirst) + { + auto result = saveProject(); + + if (! result.wasOk()) + return result; + } + + // Workaround for a bug where Xcode thinks the project is invalid if opened immediately + // after writing + if (saveFirst && exporter->isXcode()) + Thread::sleep (1000); + + exporter->launchProject(); + } + } + + return Result::ok(); } -Result Project::saveResourcesOnly (const File& file) +Result Project::saveResourcesOnly() { - ProjectSaver saver (*this, file); + ProjectSaver saver (*this); return saver.saveResourcesOnly(); } +bool Project::hasIncompatibleLicenseTypeAndSplashScreenSetting() const +{ + auto companyName = companyNameValue.get().toString(); + auto isJUCEProject = (companyName == "Raw Material Software Limited" + || companyName == "JUCE" + || companyName == "ROLI Ltd."); + + return ! ProjucerApplication::getApp().isRunningCommandLine && ! isJUCEProject && ! shouldDisplaySplashScreen() + && ! ProjucerApplication::getApp().getLicenseController().getCurrentState().canUnlockFullFeatures(); +} + +bool Project::isFileModificationCheckPending() const +{ + return fileModificationPoller.isCheckPending(); +} + +bool Project::isSaveAndExportDisabled() const +{ + return ! ProjucerApplication::getApp().isRunningCommandLine + && (hasIncompatibleLicenseTypeAndSplashScreenSetting() || isFileModificationCheckPending()); +} + +void Project::updateLicenseWarning() +{ + if (hasIncompatibleLicenseTypeAndSplashScreenSetting()) + { + ProjectMessages::MessageAction action; + auto currentLicenseState = ProjucerApplication::getApp().getLicenseController().getCurrentState(); + + if (currentLicenseState.isSignedIn() && (! currentLicenseState.canUnlockFullFeatures() || currentLicenseState.isOldLicense())) + action = { "Upgrade", [] { URL ("https://juce.com/get-juce").launchInDefaultBrowser(); } }; + else + action = { "Sign in", [this] { ProjucerApplication::getApp().mainWindowList.getMainWindowForFile (getFile())->showLoginFormOverlay(); } }; + + addProjectMessage (ProjectMessages::Ids::incompatibleLicense, + { std::move (action), { "Enable splash screen", [this] { displaySplashScreenValue = true; } } }); + } + else + { + removeProjectMessage (ProjectMessages::Ids::incompatibleLicense); + } +} + +void Project::updateJUCEPathWarning() +{ + if (ProjucerApplication::getApp().shouldPromptUserAboutIncorrectJUCEPath() + && ProjucerApplication::getApp().settings->isJUCEPathIncorrect()) + { + auto dontAskAgain = [this] + { + ProjucerApplication::getApp().setShouldPromptUserAboutIncorrectJUCEPath (false); + removeProjectMessage (ProjectMessages::Ids::jucePath); + }; + + addProjectMessage (ProjectMessages::Ids::jucePath, + { { "Set path", [] { ProjucerApplication::getApp().showPathsWindow (true); } }, + { "Ignore", [this] { removeProjectMessage (ProjectMessages::Ids::jucePath); } }, + { "Don't ask again", std::move (dontAskAgain) } }); + } + else + { + removeProjectMessage (ProjectMessages::Ids::jucePath); + } +} + +void Project::updateModuleWarnings() +{ + auto& modules = getEnabledModules(); + + bool cppStandard = false, missingDependencies = false, oldProjucer = false, moduleNotFound = false; + + for (auto moduleID : modules.getAllModules()) + { + if (! cppStandard && modules.doesModuleHaveHigherCppStandardThanProject (moduleID)) + cppStandard = true; + + if (! missingDependencies && ! modules.getExtraDependenciesNeeded (moduleID).isEmpty()) + missingDependencies = true; + + auto info = modules.getModuleInfo (moduleID); + + if (! oldProjucer && (isJUCEModule (moduleID) && getJuceVersion (info.getVersion()) > getBuiltJuceVersion())) + oldProjucer = true; + + if (! moduleNotFound && ! info.isValid()) + moduleNotFound = true; + } + + updateCppStandardWarning (cppStandard); + updateMissingModuleDependenciesWarning (missingDependencies); + updateOldProjucerWarning (oldProjucer); + updateModuleNotFoundWarning (moduleNotFound); +} + +void Project::updateExporterWarnings() +{ + auto isClionPresent = [this]() + { + for (ExporterIterator exporter (*this); exporter.next();) + if (exporter->isCLion()) + return true; + + return false; + }(); + + updateCLionWarning (isClionPresent); +} + +void Project::updateCppStandardWarning (bool showWarning) +{ + if (showWarning) + { + auto removeModules = [this] + { + auto& modules = getEnabledModules(); + + for (auto& module : modules.getModulesWithHigherCppStandardThanProject()) + modules.removeModule (module); + }; + + auto updateCppStandard = [this] + { + cppStandardValue = getEnabledModules().getHighestModuleCppStandard(); + }; + + addProjectMessage (ProjectMessages::Ids::cppStandard, + { { "Update project C++ standard" , std::move (updateCppStandard) }, + { "Remove module(s)", std::move (removeModules) } }); + } + else + { + removeProjectMessage (ProjectMessages::Ids::cppStandard); + } +} + +void Project::updateMissingModuleDependenciesWarning (bool showWarning) +{ + if (showWarning) + { + auto removeModules = [this] + { + auto& modules = getEnabledModules(); + + for (auto& mod : modules.getModulesWithMissingDependencies()) + modules.removeModule (mod); + }; + + auto addMissingDependencies = [this] + { + auto& modules = getEnabledModules(); + + for (auto& mod : modules.getModulesWithMissingDependencies()) + modules.tryToFixMissingDependencies (mod); + }; + + addProjectMessage (ProjectMessages::Ids::missingModuleDependencies, + { { "Add missing dependencies", std::move (addMissingDependencies) }, + { "Remove module(s)", std::move (removeModules) } }); + } + else + { + removeProjectMessage (ProjectMessages::Ids::missingModuleDependencies); + } +} + +void Project::updateOldProjucerWarning (bool showWarning) +{ + if (showWarning) + addProjectMessage (ProjectMessages::Ids::oldProjucer, {}); + else + removeProjectMessage (ProjectMessages::Ids::oldProjucer); +} + +void Project::updateCLionWarning (bool showWarning) +{ + if (showWarning) + addProjectMessage (ProjectMessages::Ids::cLion, {}); + else + removeProjectMessage (ProjectMessages::Ids::cLion); +} + +void Project::updateModuleNotFoundWarning (bool showWarning) +{ + if (showWarning) + addProjectMessage (ProjectMessages::Ids::moduleNotFound, {}); + else + removeProjectMessage (ProjectMessages::Ids::moduleNotFound); +} + +void Project::licenseStateChanged() +{ + updateLicenseWarning(); +} + +void Project::changeListenerCallback (ChangeBroadcaster*) +{ + updateJUCEPathWarning(); +} + +void Project::availableModulesChanged (AvailableModulesList* listThatHasChanged) +{ + if (listThatHasChanged == &ProjucerApplication::getApp().getJUCEPathModulesList()) + updateJUCEPathWarning(); + + updateModuleWarnings(); +} + +void Project::addProjectMessage (const Identifier& messageToAdd, + std::vector<ProjectMessages::MessageAction>&& actions) +{ + removeProjectMessage (messageToAdd); + + messageActions[messageToAdd] = std::move (actions); + + ValueTree child (messageToAdd); + child.setProperty (ProjectMessages::Ids::isVisible, true, nullptr); + + projectMessages.getChildWithName (ProjectMessages::getTypeForMessage (messageToAdd)).addChild (child, -1, nullptr); +} + +void Project::removeProjectMessage (const Identifier& messageToRemove) +{ + auto subTree = projectMessages.getChildWithName (ProjectMessages::getTypeForMessage (messageToRemove)); + auto child = subTree.getChildWithName (messageToRemove); + + if (child.isValid()) + subTree.removeChild (child, nullptr); + + messageActions.erase (messageToRemove); +} + +std::vector<ProjectMessages::MessageAction> Project::getMessageActions (const Identifier& message) +{ + auto iter = messageActions.find (message); + + if (iter != messageActions.end()) + return iter->second; + + jassertfalse; + return {}; +} + //============================================================================== void Project::setTemporaryDirectory (const File& dir) noexcept { @@ -658,21 +986,21 @@ void Project::setTemporaryDirectory (const File& dir) noexcept forgetRecentFile (getFile()); } -void Project::askUserWhereToSaveProject() +void Project::saveAndMoveTemporaryProject (bool openInIDE) { FileChooser fc ("Save Project"); fc.browseForDirectory(); - if (fc.getResult().exists()) - moveTemporaryDirectory (fc.getResult()); -} + auto newParentDirectory = fc.getResult(); + + if (! newParentDirectory.exists()) + return; -void Project::moveTemporaryDirectory (const File& newParentDirectory) -{ auto newDirectory = newParentDirectory.getChildFile (tempDirectory.getFileName()); auto oldJucerFileName = getFile().getFileName(); - saveProjectRootToFile(); + ProjectSaver saver (*this); + saver.save(); tempDirectory.copyDirectoryTo (newDirectory); tempDirectory.deleteRecursively(); @@ -683,45 +1011,22 @@ void Project::moveTemporaryDirectory (const File& newParentDirectory) { Component::SafePointer<MainWindow> safeWindow (window); - MessageManager::callAsync ([safeWindow, newDirectory, oldJucerFileName] + MessageManager::callAsync ([safeWindow, newDirectory, oldJucerFileName, openInIDE]() mutable { if (safeWindow != nullptr) - safeWindow.getComponent()->moveProject (newDirectory.getChildFile (oldJucerFileName)); + safeWindow->moveProject (newDirectory.getChildFile (oldJucerFileName), + openInIDE ? MainWindow::OpenInIDE::yes + : MainWindow::OpenInIDE::no); }); } } -bool Project::saveProjectRootToFile() -{ - if (auto xml = projectRoot.createXml()) - { - MemoryOutputStream mo; - xml->writeTo (mo, {}); - return FileHelpers::overwriteFileWithNewDataIfDifferent (getFile(), mo); - } - - jassertfalse; - return false; -} - //============================================================================== -static void sendProjectSettingAnalyticsEvent (StringRef label) -{ - StringPairArray data; - data.set ("label", label); - - Analytics::getInstance()->logEvent ("Project Setting", data, ProjucerAnalyticsEvent::projectEvent); -} - void Project::valueTreePropertyChanged (ValueTree& tree, const Identifier& property) { if (tree.getRoot() == tree) { - if (property == Ids::projectType) - { - sendProjectSettingAnalyticsEvent ("Project Type = " + projectTypeValue.get().toString()); - } - else if (property == Ids::name) + if (property == Ids::name) { updateTitleDependencies(); } @@ -733,10 +1038,6 @@ void Project::valueTreePropertyChanged (ValueTree& tree, const Identifier& prope { parsedPreprocessorDefs = parsePreprocessorDefs (preprocessorDefsValue.get()); } - else if (property == Ids::cppLanguageStandard) - { - sendProjectSettingAnalyticsEvent ("C++ Standard = " + cppStandardValue.get().toString()); - } else if (property == Ids::pluginFormats) { if (shouldWriteLegacyPluginFormatSettings) @@ -753,22 +1054,75 @@ void Project::valueTreePropertyChanged (ValueTree& tree, const Identifier& prope if (shouldWriteLegacyPluginCharacteristicsSettings) writeLegacyPluginCharacteristicsSettings(); } + else if (property == Ids::displaySplashScreen) + { + updateLicenseWarning(); + } + else if (property == Ids::cppLanguageStandard) + { + updateModuleWarnings(); + } changed(); } } -void Project::valueTreeChildAdded (ValueTree&, ValueTree&) { changed(); } -void Project::valueTreeChildRemoved (ValueTree&, ValueTree&, int) { changed(); } -void Project::valueTreeChildOrderChanged (ValueTree&, int, int) { changed(); } +void Project::valueTreeChildAdded (ValueTree& parent, ValueTree& child) +{ + ignoreUnused (parent); + + if (child.getType() == Ids::MODULE) + updateModuleWarnings(); + else if (parent.getType() == Ids::EXPORTFORMATS) + updateExporterWarnings(); + + changed(); +} + +void Project::valueTreeChildRemoved (ValueTree& parent, ValueTree& child, int index) +{ + ignoreUnused (parent, index); + + if (child.getType() == Ids::MODULE) + updateModuleWarnings(); + else if (parent.getType() == Ids::EXPORTFORMATS) + updateExporterWarnings(); + + changed(); +} + +void Project::valueTreeChildOrderChanged (ValueTree&, int, int) +{ + changed(); +} //============================================================================== -bool Project::hasProjectBeenModified() +String Project::serialiseProjectXml (std::unique_ptr<XmlElement> xml) const { - auto oldModificationTime = modificationTime; - modificationTime = getFile().getLastModificationTime(); + if (xml == nullptr) + return {}; - return (modificationTime.toMilliseconds() > (oldModificationTime.toMilliseconds() + 1000LL)); + XmlElement::TextFormat format; + format.newLineChars = getProjectLineFeed().toRawUTF8(); + return xml->toString (format); +} + +bool Project::updateCachedFileState() +{ + auto lastModificationTime = getFile().getLastModificationTime(); + + if (lastModificationTime <= cachedFileState.first) + return false; + + cachedFileState.first = lastModificationTime; + + auto serialisedFileContent = serialiseProjectXml (XmlDocument (getFile()).getDocumentElement()); + + if (serialisedFileContent == cachedFileState.second) + return false; + + cachedFileState.second = serialisedFileContent; + return true; } //============================================================================== @@ -777,17 +1131,17 @@ File Project::resolveFilename (String filename) const if (filename.isEmpty()) return {}; - filename = replacePreprocessorDefs (getPreprocessorDefs(), filename); + filename = build_tools::replacePreprocessorDefs (getPreprocessorDefs(), filename); #if ! JUCE_WINDOWS if (filename.startsWith ("~")) return File::getSpecialLocation (File::userHomeDirectory).getChildFile (filename.trimCharactersAtStart ("~/")); #endif - if (FileHelpers::isAbsolutePath (filename)) - return File::createFileWithoutCheckingPath (FileHelpers::currentOSStylePath (filename)); // (avoid assertions for windows-style paths) + if (build_tools::isAbsolutePath (filename)) + return File::createFileWithoutCheckingPath (build_tools::currentOSStylePath (filename)); // (avoid assertions for windows-style paths) - return getFile().getSiblingFile (FileHelpers::currentOSStylePath (filename)); + return getFile().getSiblingFile (build_tools::currentOSStylePath (filename)); } String Project::getRelativePathForFile (const File& file) const @@ -808,24 +1162,24 @@ String Project::getRelativePathForFile (const File& file) const if (p1.upToFirstOccurrenceOf (File::getSeparatorString(), true, false) .equalsIgnoreCase (p2.upToFirstOccurrenceOf (File::getSeparatorString(), true, false))) { - filename = FileHelpers::getRelativePathFrom (file, relativePathBase); + filename = build_tools::getRelativePathFrom (file, relativePathBase); } return filename; } //============================================================================== -const ProjectType& Project::getProjectType() const +const build_tools::ProjectType& Project::getProjectType() const { - if (auto* type = ProjectType::findType (getProjectTypeString())) + if (auto* type = build_tools::ProjectType::findType (getProjectTypeString())) return *type; - auto* guiType = ProjectType::findType (ProjectType_GUIApp::getTypeName()); + auto* guiType = build_tools::ProjectType::findType (build_tools::ProjectType_GUIApp::getTypeName()); jassert (guiType != nullptr); return *guiType; } -bool Project::shouldBuildTargetType (ProjectType::Target::Type targetType) const noexcept +bool Project::shouldBuildTargetType (build_tools::ProjectType::Target::Type targetType) const noexcept { auto& projectType = getProjectType(); @@ -834,27 +1188,31 @@ bool Project::shouldBuildTargetType (ProjectType::Target::Type targetType) const switch (targetType) { - case ProjectType::Target::VSTPlugIn: + case build_tools::ProjectType::Target::VSTPlugIn: return shouldBuildVST(); - case ProjectType::Target::VST3PlugIn: + case build_tools::ProjectType::Target::VST3PlugIn: return shouldBuildVST3(); - case ProjectType::Target::AAXPlugIn: + case build_tools::ProjectType::Target::AAXPlugIn: return shouldBuildAAX(); - case ProjectType::Target::RTASPlugIn: + case build_tools::ProjectType::Target::RTASPlugIn: return shouldBuildRTAS(); - case ProjectType::Target::AudioUnitPlugIn: + case build_tools::ProjectType::Target::AudioUnitPlugIn: return shouldBuildAU(); - case ProjectType::Target::AudioUnitv3PlugIn: + case build_tools::ProjectType::Target::AudioUnitv3PlugIn: return shouldBuildAUv3(); - case ProjectType::Target::StandalonePlugIn: + case build_tools::ProjectType::Target::StandalonePlugIn: return shouldBuildStandalonePlugin(); - case ProjectType::Target::UnityPlugIn: + case build_tools::ProjectType::Target::UnityPlugIn: return shouldBuildUnityPlugin(); - case ProjectType::Target::AggregateTarget: - case ProjectType::Target::SharedCodeTarget: + case build_tools::ProjectType::Target::AggregateTarget: + case build_tools::ProjectType::Target::SharedCodeTarget: return projectType.isAudioPlugin(); - case ProjectType::Target::unspecified: + case build_tools::ProjectType::Target::unspecified: return false; + case build_tools::ProjectType::Target::GUIApp: + case build_tools::ProjectType::Target::ConsoleApp: + case build_tools::ProjectType::Target::StaticLibrary: + case build_tools::ProjectType::Target::DynamicLibrary: default: break; } @@ -862,64 +1220,36 @@ bool Project::shouldBuildTargetType (ProjectType::Target::Type targetType) const return true; } -ProjectType::Target::Type Project::getTargetTypeFromFilePath (const File& file, bool returnSharedTargetIfNoValidSuffix) +build_tools::ProjectType::Target::Type Project::getTargetTypeFromFilePath (const File& file, bool returnSharedTargetIfNoValidSuffix) { - if (LibraryModule::CompileUnit::hasSuffix (file, "_AU")) return ProjectType::Target::AudioUnitPlugIn; - else if (LibraryModule::CompileUnit::hasSuffix (file, "_AUv3")) return ProjectType::Target::AudioUnitv3PlugIn; - else if (LibraryModule::CompileUnit::hasSuffix (file, "_AAX")) return ProjectType::Target::AAXPlugIn; - else if (LibraryModule::CompileUnit::hasSuffix (file, "_RTAS")) return ProjectType::Target::RTASPlugIn; - else if (LibraryModule::CompileUnit::hasSuffix (file, "_VST2")) return ProjectType::Target::VSTPlugIn; - else if (LibraryModule::CompileUnit::hasSuffix (file, "_VST3")) return ProjectType::Target::VST3PlugIn; - else if (LibraryModule::CompileUnit::hasSuffix (file, "_Standalone")) return ProjectType::Target::StandalonePlugIn; - else if (LibraryModule::CompileUnit::hasSuffix (file, "_Unity")) return ProjectType::Target::UnityPlugIn; + auto path = file.getFullPathName(); + String pluginClientModuleName = "juce_audio_plugin_client"; - return (returnSharedTargetIfNoValidSuffix ? ProjectType::Target::SharedCodeTarget : ProjectType::Target::unspecified); -} - -const char* ProjectType::Target::getName() const noexcept -{ - switch (type) + auto isInPluginClientSubdir = [&path, &pluginClientModuleName] (StringRef subDir) { - case GUIApp: return "App"; - case ConsoleApp: return "ConsoleApp"; - case StaticLibrary: return "Static Library"; - case DynamicLibrary: return "Dynamic Library"; - case VSTPlugIn: return "VST"; - case VST3PlugIn: return "VST3"; - case AudioUnitPlugIn: return "AU"; - case StandalonePlugIn: return "Standalone Plugin"; - case AudioUnitv3PlugIn: return "AUv3 AppExtension"; - case AAXPlugIn: return "AAX"; - case RTASPlugIn: return "RTAS"; - case UnityPlugIn: return "Unity Plugin"; - case SharedCodeTarget: return "Shared Code"; - case AggregateTarget: return "All"; - default: return "undefined"; - } -} + return path.contains (pluginClientModuleName + + File::getSeparatorString() + + subDir + + File::getSeparatorString()); + }; -ProjectType::Target::TargetFileType ProjectType::Target::getTargetFileType() const noexcept -{ - switch (type) + auto isPluginClientSource = [&path, &pluginClientModuleName] (StringRef suffix) { - case GUIApp: return executable; - case ConsoleApp: return executable; - case StaticLibrary: return staticLibrary; - case DynamicLibrary: return sharedLibraryOrDLL; - case VSTPlugIn: return pluginBundle; - case VST3PlugIn: return pluginBundle; - case AudioUnitPlugIn: return pluginBundle; - case StandalonePlugIn: return executable; - case AudioUnitv3PlugIn: return macOSAppex; - case AAXPlugIn: return pluginBundle; - case RTASPlugIn: return pluginBundle; - case UnityPlugIn: return pluginBundle; - case SharedCodeTarget: return staticLibrary; - default: - break; - } + auto prefix = pluginClientModuleName + "_" + suffix; + return path.contains (prefix + ".") || path.contains (prefix + "_"); + }; - return unknown; + if (isPluginClientSource ("AU") || isInPluginClientSubdir ("AU")) return build_tools::ProjectType::Target::AudioUnitPlugIn; + if (isPluginClientSource ("AUv3") || isInPluginClientSubdir ("AU")) return build_tools::ProjectType::Target::AudioUnitv3PlugIn; + if (isPluginClientSource ("AAX") || isInPluginClientSubdir ("AAX")) return build_tools::ProjectType::Target::AAXPlugIn; + if (isPluginClientSource ("RTAS") || isInPluginClientSubdir ("RTAS")) return build_tools::ProjectType::Target::RTASPlugIn; + if (isPluginClientSource ("VST2") || isInPluginClientSubdir ("VST")) return build_tools::ProjectType::Target::VSTPlugIn; + if (isPluginClientSource ("VST3") || isInPluginClientSubdir ("VST3")) return build_tools::ProjectType::Target::VST3PlugIn; + if (isPluginClientSource ("Standalone") || isInPluginClientSubdir ("Standalone")) return build_tools::ProjectType::Target::StandalonePlugIn; + if (isPluginClientSource ("Unity") || isInPluginClientSubdir ("Unity")) return build_tools::ProjectType::Target::UnityPlugIn; + + return (returnSharedTargetIfNoValidSuffix ? build_tools::ProjectType::Target::SharedCodeTarget + : build_tools::ProjectType::Target::unspecified); } //============================================================================== @@ -948,50 +1278,33 @@ void Project::createPropertyEditors (PropertyListBuilder& props) props.add (new TextPropertyComponent (companyEmailValue, "Company E-mail", 256, false), "Your company e-mail, which will be added to the properties of the binary where possible"); - { - String licenseRequiredTagline ("Required for closed source applications without an Indie or Pro JUCE license"); - String licenseRequiredInfo ("In accordance with the terms of the JUCE 5 End-Use License Agreement (www.juce.com/juce-5-licence), " - "this option can only be disabled for closed source applications if you have a JUCE Indie or Pro " - "license, or are using JUCE under the GPL v3 license."); - - StringPairArray description; - description.set ("Report JUCE app usage", "This option controls the collection of usage data from users of this JUCE application."); - description.set ("Display the JUCE splash screen", "This option controls the display of the standard JUCE splash screen."); - - if (ProjucerApplication::getApp().isPaidOrGPL()) - { - props.add (new ChoicePropertyComponent (reportAppUsageValue, String ("Report JUCE App Usage") + " (" + licenseRequiredTagline + ")"), - description["Report JUCE app usage"] + " " + licenseRequiredInfo); - - props.add (new ChoicePropertyComponent (displaySplashScreenValue, String ("Display the JUCE Splash Screen") + " (" + licenseRequiredTagline + ")"), - description["Display the JUCE splash screen"] + " " + licenseRequiredInfo); - } - else - { - StringArray options; - Array<var> vars; - - options.add (licenseRequiredTagline); - vars.add (var()); - - props.add (new ChoicePropertyComponent (Value(), "Report JUCE App Usage", options, vars), - description["Report JUCE app usage"] + " " + licenseRequiredInfo); - - props.add (new ChoicePropertyComponent (Value(), "Display the JUCE Splash Screen", options, vars), - description["Display the JUCE splash screen"] + " " + licenseRequiredInfo); - } - } - - props.add (new ChoicePropertyComponent (splashScreenColourValue, "Splash Screen Colour", - { "Dark", "Light" }, - { "Dark", "Light" }), + props.add (new ChoicePropertyComponent (useAppConfigValue, "Use Global AppConfig Header"), + "If enabled, the Projucer will generate module wrapper stubs which include AppConfig.h " + "and will include AppConfig.h in the JuceHeader.h. If disabled, all the settings that would " + "previously have been specified in the AppConfig.h will be injected via the build system instead, " + "which may simplify the includes in the project."); + + props.add (new ChoicePropertyComponent (addUsingNamespaceToJuceHeader, "Add \"using namespace juce\" to JuceHeader.h"), + "If enabled, the JuceHeader.h will include a \"using namepace juce\" statement. If disabled, " + "no such statement will be included. This setting used to be enabled by default, but it " + "is recommended to leave it disabled for new projects."); + + props.add (new ChoicePropertyComponent (displaySplashScreenValue, "Display the JUCE Splash Screen (required for closed source applications without an Indie or Pro JUCE license)"), + "This option controls the display of the standard JUCE splash screen. " + "In accordance with the terms of the JUCE 6 End-Use License Agreement (www.juce.com/juce-6-licence), " + "this option can only be disabled for closed source applications if you have a JUCE Indie or Pro " + "license, or are using JUCE under the GPL v3 license."); + + props.add (new ChoicePropertyComponentWithEnablement (splashScreenColourValue, displaySplashScreenValue, "Splash Screen Colour", + { "Dark", "Light" }, { "Dark", "Light" }), "Choose the colour of the JUCE splash screen."); + { StringArray projectTypeNames; Array<var> projectTypeCodes; - auto types = ProjectType::getAllTypes(); + auto types = build_tools::ProjectType::getAllTypes(); for (int i = 0; i < types.size(); ++i) { @@ -1035,8 +1348,8 @@ void Project::createPropertyEditors (PropertyListBuilder& props) "The namespace containing the binary assets."); props.add (new ChoicePropertyComponent (cppStandardValue, "C++ Language Standard", - { "C++11", "C++14", "C++17", "Use Latest" }, - { "11", "14", "17", "latest" }), + getCppStandardStrings(), + getCppStandardVars()), "The standard of the C++ language that will be used for compilation."); props.add (new TextPropertyComponent (preprocessorDefsValue, "Preprocessor Definitions", 32768, true), @@ -1145,33 +1458,6 @@ void Project::createAudioPluginPropertyEditors (PropertyListBuilder& props) } //============================================================================== -static StringArray getVersionSegments (const Project& p) -{ - auto segments = StringArray::fromTokens (p.getVersionString(), ",.", ""); - segments.trim(); - segments.removeEmptyStrings(); - return segments; -} - -int Project::getVersionAsHexInteger() const -{ - auto segments = getVersionSegments (*this); - - auto value = (segments[0].getIntValue() << 16) - + (segments[1].getIntValue() << 8) - + segments[2].getIntValue(); - - if (segments.size() > 3) - value = (value << 8) + segments[3].getIntValue(); - - return value; -} - -String Project::getVersionAsHex() const -{ - return "0x" + String::toHexString (getVersionAsHexInteger()); -} - File Project::getBinaryDataCppFile (int index) const { auto cpp = getGeneratedCodeFolder().getChildFile ("BinaryData.cpp"); @@ -1259,6 +1545,11 @@ bool Project::Item::isImageFile() const || getFile().hasFileExtension ("svg")); } +bool Project::Item::isSourceFile() const +{ + return isFile() && getFile().hasFileExtension (sourceFileExtensions); +} + Project::Item Project::Item::findItemWithID (const String& targetId) const { if (state [Ids::ID] == targetId) @@ -1314,6 +1605,9 @@ bool Project::Item::shouldInhibitWarnings() const { return state [Ids: bool Project::Item::isModuleCode() const { return belongsToModule; } +Value Project::Item::getShouldSkipPCHValue() { return state.getPropertyAsValue (Ids::skipPCH, getUndoManager()); } +bool Project::Item::shouldSkipPCH() const { return isModuleCode() || state [Ids::skipPCH]; } + Value Project::Item::getCompilerFlagSchemeValue() { return state.getPropertyAsValue (Ids::compilerFlagScheme, getUndoManager()); } String Project::Item::getCompilerFlagSchemeString() const { return state [Ids::compilerFlagScheme]; } @@ -1345,11 +1639,11 @@ File Project::Item::getFile() const void Project::Item::setFile (const File& file) { - setFile (RelativePath (project.getRelativePathForFile (file), RelativePath::projectFolder)); + setFile (build_tools::RelativePath (project.getRelativePathForFile (file), build_tools::RelativePath::projectFolder)); jassert (getFile() == file); } -void Project::Item::setFile (const RelativePath& file) +void Project::Item::setFile (const build_tools::RelativePath& file) { jassert (isFile()); state.setProperty (Ids::file, file.toUnixStyle(), getUndoManager()); @@ -1371,7 +1665,7 @@ bool Project::Item::renameFile (const File& newFile) return false; } -bool Project::Item::containsChildForFile (const RelativePath& file) const +bool Project::Item::containsChildForFile (const build_tools::RelativePath& file) const { return state.getChildWithProperty (Ids::file, file.toUnixStyle()).isValid(); } @@ -1565,7 +1859,7 @@ bool Project::Item::addFileAtIndex (const File& file, int insertIndex, const boo { auto group = addNewSubGroup (file.getFileName(), insertIndex); - for (DirectoryIterator iter (file, false, "*", File::findFilesAndDirectories); iter.next();) + for (const auto& iter : RangedDirectoryIterator (file, false, "*", File::findFilesAndDirectories)) if (! project.getMainGroup().findItemForFile (iter.getFile()).isValid()) group.addFileRetainingSortOrder (iter.getFile(), shouldCompile); } @@ -1611,7 +1905,7 @@ void Project::Item::addFileUnchecked (const File& file, int insertIndex, const b } } -bool Project::Item::addRelativeFile (const RelativePath& file, int insertIndex, bool shouldCompile) +bool Project::Item::addRelativeFile (const build_tools::RelativePath& file, int insertIndex, bool shouldCompile) { Item item (project, ValueTree (Ids::FILE), belongsToModule); item.initialiseMissingProperties(); @@ -1755,8 +2049,8 @@ static String getCompanyNameOrDefault (StringRef str) String Project::getDefaultBundleIdentifierString() const { - return "com." + CodeHelpers::makeValidIdentifier (getCompanyNameOrDefault (getCompanyNameString()), false, true, false) - + "." + CodeHelpers::makeValidIdentifier (getProjectNameString(), false, true, false); + return "com." + build_tools::makeValidIdentifier (getCompanyNameOrDefault (getCompanyNameString()), false, true, false) + + "." + build_tools::makeValidIdentifier (getProjectNameString(), false, true, false); } String Project::getDefaultPluginManufacturerString() const @@ -1858,7 +2152,7 @@ int Project::getRTASCategory() const noexcept return res; } -String Project::getIAATypeCode() +String Project::getIAATypeCode() const { String s; if (pluginWantsMidiInput()) @@ -1878,7 +2172,7 @@ String Project::getIAATypeCode() return s; } -String Project::getIAAPluginName() +String Project::getIAAPluginName() const { auto s = getPluginManufacturerString(); s << ": "; @@ -1889,17 +2183,17 @@ String Project::getIAAPluginName() //============================================================================== bool Project::isAUPluginHost() { - return getEnabledModules().isModuleEnabled ("juce_audio_processors") && isConfigFlagEnabled ("JUCE_PLUGINHOST_AU"); + return getEnabledModules().isModuleEnabled ("juce_audio_processors") && isConfigFlagEnabled ("JUCE_PLUGINHOST_AU", false); } bool Project::isVSTPluginHost() { - return getEnabledModules().isModuleEnabled ("juce_audio_processors") && isConfigFlagEnabled ("JUCE_PLUGINHOST_VST"); + return getEnabledModules().isModuleEnabled ("juce_audio_processors") && isConfigFlagEnabled ("JUCE_PLUGINHOST_VST", false); } bool Project::isVST3PluginHost() { - return getEnabledModules().isModuleEnabled ("juce_audio_processors") && isConfigFlagEnabled ("JUCE_PLUGINHOST_VST3"); + return getEnabledModules().isModuleEnabled ("juce_audio_processors") && isConfigFlagEnabled ("JUCE_PLUGINHOST_VST3", false); } //============================================================================== @@ -2020,12 +2314,12 @@ Array<var> Project::getDefaultRTASCategories() const noexcept } //============================================================================== -EnabledModuleList& Project::getEnabledModules() +EnabledModulesList& Project::getEnabledModules() { - if (enabledModuleList == nullptr) - enabledModuleList.reset (new EnabledModuleList (*this, projectRoot.getOrCreateChildWithName (Ids::MODULES, nullptr))); + if (enabledModulesList == nullptr) + enabledModulesList.reset (new EnabledModulesList (*this, projectRoot.getOrCreateChildWithName (Ids::MODULES, nullptr))); - return *enabledModuleList; + return *enabledModulesList; } static StringArray getModulePathsFromExporters (Project& project, bool onlyThisOS) @@ -2087,37 +2381,32 @@ static Array<File> getExporterModulePathsToScan (Project& project) return files; } -AvailableModuleList& Project::getExporterPathsModuleList() -{ - return *exporterPathsModuleList; -} - void Project::rescanExporterPathModules (bool async) { if (async) - exporterPathsModuleList->scanPathsAsync (getExporterModulePathsToScan (*this)); + exporterPathsModulesList.scanPathsAsync (getExporterModulePathsToScan (*this)); else - exporterPathsModuleList->scanPaths (getExporterModulePathsToScan (*this)); + exporterPathsModulesList.scanPaths (getExporterModulePathsToScan (*this)); } -AvailableModuleList::ModuleIDAndFolder Project::getModuleWithID (const String& id) +AvailableModulesList::ModuleIDAndFolder Project::getModuleWithID (const String& id) { if (! getEnabledModules().shouldUseGlobalPath (id)) { - const auto& mod = exporterPathsModuleList->getModuleWithID (id); + const auto& mod = exporterPathsModulesList.getModuleWithID (id); if (mod.second != File()) return mod; } - const auto& list = (isJUCEModule (id) ? ProjucerApplication::getApp().getJUCEPathModuleList().getAllModules() - : ProjucerApplication::getApp().getUserPathsModuleList().getAllModules()); + const auto& list = (isJUCEModule (id) ? ProjucerApplication::getApp().getJUCEPathModulesList().getAllModules() + : ProjucerApplication::getApp().getUserPathsModulesList().getAllModules()); for (auto& m : list) if (m.first == id) return m; - return exporterPathsModuleList->getModuleWithID (id); + return exporterPathsModulesList.getModuleWithID (id); } //============================================================================== @@ -2131,18 +2420,18 @@ int Project::getNumExporters() return getExporters().getNumChildren(); } -ProjectExporter* Project::createExporter (int index) +std::unique_ptr<ProjectExporter> Project::createExporter (int index) { jassert (index >= 0 && index < getNumExporters()); - return ProjectExporter::createExporter (*this, getExporters().getChild (index)); + return ProjectExporter::createExporterFromSettings (*this, getExporters().getChild (index)); } -void Project::addNewExporter (const String& exporterName) +void Project::addNewExporter (const Identifier& exporterIdentifier) { - std::unique_ptr<ProjectExporter> exp (ProjectExporter::createNewExporter (*this, exporterName)); + std::unique_ptr<ProjectExporter> exp (ProjectExporter::createNewExporter (*this, exporterIdentifier)); exp->getTargetLocationValue() = exp->getTargetLocationString() - + getUniqueTargetFolderSuffixForExporter (exp->getName(), exp->getTargetLocationString()); + + getUniqueTargetFolderSuffixForExporter (exporterIdentifier, exp->getTargetLocationString()); auto exportersTree = getExporters(); exportersTree.appendChild (exp->settings, getUndoManagerFor (exportersTree)); @@ -2150,21 +2439,20 @@ void Project::addNewExporter (const String& exporterName) void Project::createExporterForCurrentPlatform() { - addNewExporter (ProjectExporter::getCurrentPlatformExporterName()); + addNewExporter (ProjectExporter::getCurrentPlatformExporterTypeInfo().identifier); } -String Project::getUniqueTargetFolderSuffixForExporter (const String& exporterName, const String& base) +String Project::getUniqueTargetFolderSuffixForExporter (const Identifier& exporterIdentifier, const String& base) { StringArray buildFolders; auto exportersTree = getExporters(); - auto type = ProjectExporter::getValueTreeNameForExporter (exporterName); for (int i = 0; i < exportersTree.getNumChildren(); ++i) { auto exporterNode = exportersTree.getChild (i); - if (exporterNode.getType() == Identifier (type)) + if (exporterNode.getType() == exporterIdentifier) buildFolders.add (exporterNode.getProperty ("targetFolder").toString()); } @@ -2186,28 +2474,151 @@ String Project::getUniqueTargetFolderSuffixForExporter (const String& exporterNa } //============================================================================== -bool Project::shouldSendGUIBuilderAnalyticsEvent() noexcept +StringPairArray Project::getAppConfigDefs() { - if (! hasSentGUIBuilderAnalyticsEvent) + StringPairArray result; + result.set ("JUCE_DISPLAY_SPLASH_SCREEN", shouldDisplaySplashScreen() ? "1" : "0"); + result.set ("JUCE_USE_DARK_SPLASH_SCREEN", getSplashScreenColourString() == "Dark" ? "1" : "0"); + result.set ("JUCE_PROJUCER_VERSION", "0x" + String::toHexString (ProjectInfo::versionNumber)); + + OwnedArray<LibraryModule> modules; + getEnabledModules().createRequiredModules (modules); + + for (auto& m : modules) + result.set ("JUCE_MODULE_AVAILABLE_" + m->getID(), "1"); + + result.set ("JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED", "1"); + + for (auto& m : modules) { - hasSentGUIBuilderAnalyticsEvent = true; - return true; + OwnedArray<Project::ConfigFlag> flags; + m->getConfigFlags (*this, flags); + + for (auto* flag : flags) + if (! flag->value.isUsingDefault()) + result.set (flag->symbol, flag->value.get() ? "1" : "0"); } - return false; + result.addArray (getAudioPluginFlags()); + + const auto& type = getProjectType(); + const auto isStandaloneApplication = (! type.isAudioPlugin() && ! type.isDynamicLibrary()); + + const auto standaloneValue = [&] + { + if (result.containsKey ("JucePlugin_Name") && result.containsKey ("JucePlugin_Build_Standalone")) + return "JucePlugin_Build_Standalone"; + + return isStandaloneApplication ? "1" : "0"; + }(); + + result.set ("JUCE_STANDALONE_APPLICATION", standaloneValue); + + return result; } -//============================================================================== -String Project::getFileTemplate (const String& templateName) +StringPairArray Project::getAudioPluginFlags() const { - int dataSize; - - if (auto* data = BinaryData::getNamedResource (templateName.toUTF8(), dataSize)) - return String::fromUTF8 (data, dataSize); + if (! isAudioPluginProject()) + return {}; - jassertfalse; - return {}; + const auto boolToString = [] (bool b) { return b ? "1" : "0"; }; + + const auto toStringLiteral = [] (const String& v) + { + return CppTokeniserFunctions::addEscapeChars (v).quoted(); + }; + + const auto countMaxPluginChannels = [] (const String& configString, bool isInput) + { + auto configs = StringArray::fromTokens (configString, ", {}", {}); + configs.trim(); + configs.removeEmptyStrings(); + jassert ((configs.size() & 1) == 0); // looks like a syntax error in the configs? + + int maxVal = 0; + + for (int i = (isInput ? 0 : 1); i < configs.size(); i += 2) + maxVal = jmax (maxVal, configs[i].getIntValue()); + + return maxVal; + }; + + const auto toCharLiteral = [] (const String& v) + { + auto fourCharCode = v.substring (0, 4); + uint32 hexRepresentation = 0; + + for (int i = 0; i < 4; ++i) + hexRepresentation = (hexRepresentation << 8u) + | (static_cast<unsigned int> (fourCharCode[i]) & 0xffu); + + return "0x" + String::toHexString (static_cast<int> (hexRepresentation)); + }; + + StringPairArray flags; + flags.set ("JucePlugin_Build_VST", boolToString (shouldBuildVST())); + flags.set ("JucePlugin_Build_VST3", boolToString (shouldBuildVST3())); + flags.set ("JucePlugin_Build_AU", boolToString (shouldBuildAU())); + flags.set ("JucePlugin_Build_AUv3", boolToString (shouldBuildAUv3())); + flags.set ("JucePlugin_Build_RTAS", boolToString (shouldBuildRTAS())); + flags.set ("JucePlugin_Build_AAX", boolToString (shouldBuildAAX())); + flags.set ("JucePlugin_Build_Standalone", boolToString (shouldBuildStandalonePlugin())); + flags.set ("JucePlugin_Build_Unity", boolToString (shouldBuildUnityPlugin())); + flags.set ("JucePlugin_Enable_IAA", boolToString (shouldEnableIAA())); + flags.set ("JucePlugin_Name", toStringLiteral (getPluginNameString())); + flags.set ("JucePlugin_Desc", toStringLiteral (getPluginDescriptionString())); + flags.set ("JucePlugin_Manufacturer", toStringLiteral (getPluginManufacturerString())); + flags.set ("JucePlugin_ManufacturerWebsite", toStringLiteral (getCompanyWebsiteString())); + flags.set ("JucePlugin_ManufacturerEmail", toStringLiteral (getCompanyEmailString())); + flags.set ("JucePlugin_ManufacturerCode", toCharLiteral (getPluginManufacturerCodeString())); + flags.set ("JucePlugin_PluginCode", toCharLiteral (getPluginCodeString())); + flags.set ("JucePlugin_IsSynth", boolToString (isPluginSynth())); + flags.set ("JucePlugin_WantsMidiInput", boolToString (pluginWantsMidiInput())); + flags.set ("JucePlugin_ProducesMidiOutput", boolToString (pluginProducesMidiOutput())); + flags.set ("JucePlugin_IsMidiEffect", boolToString (isPluginMidiEffect())); + flags.set ("JucePlugin_EditorRequiresKeyboardFocus", boolToString (pluginEditorNeedsKeyFocus())); + flags.set ("JucePlugin_Version", getVersionString()); + flags.set ("JucePlugin_VersionCode", getVersionAsHex()); + flags.set ("JucePlugin_VersionString", toStringLiteral (getVersionString())); + flags.set ("JucePlugin_VSTUniqueID", "JucePlugin_PluginCode"); + flags.set ("JucePlugin_VSTCategory", getVSTCategoryString()); + flags.set ("JucePlugin_Vst3Category", toStringLiteral (getVST3CategoryString())); + flags.set ("JucePlugin_AUMainType", getAUMainTypeString()); + flags.set ("JucePlugin_AUSubType", "JucePlugin_PluginCode"); + flags.set ("JucePlugin_AUExportPrefix", getPluginAUExportPrefixString()); + flags.set ("JucePlugin_AUExportPrefixQuoted", toStringLiteral (getPluginAUExportPrefixString())); + flags.set ("JucePlugin_AUManufacturerCode", "JucePlugin_ManufacturerCode"); + flags.set ("JucePlugin_CFBundleIdentifier", getBundleIdentifierString()); + flags.set ("JucePlugin_RTASCategory", String (getRTASCategory())); + flags.set ("JucePlugin_RTASManufacturerCode", "JucePlugin_ManufacturerCode"); + flags.set ("JucePlugin_RTASProductId", "JucePlugin_PluginCode"); + flags.set ("JucePlugin_RTASDisableBypass", boolToString (isPluginRTASBypassDisabled())); + flags.set ("JucePlugin_RTASDisableMultiMono", boolToString (isPluginRTASMultiMonoDisabled())); + flags.set ("JucePlugin_AAXIdentifier", getAAXIdentifierString()); + flags.set ("JucePlugin_AAXManufacturerCode", "JucePlugin_ManufacturerCode"); + flags.set ("JucePlugin_AAXProductId", "JucePlugin_PluginCode"); + flags.set ("JucePlugin_AAXCategory", String (getAAXCategory())); + flags.set ("JucePlugin_AAXDisableBypass", boolToString (isPluginAAXBypassDisabled())); + flags.set ("JucePlugin_AAXDisableMultiMono", boolToString (isPluginAAXMultiMonoDisabled())); + flags.set ("JucePlugin_IAAType", toCharLiteral (getIAATypeCode())); + flags.set ("JucePlugin_IAASubType", "JucePlugin_PluginCode"); + flags.set ("JucePlugin_IAAName", getIAAPluginName().quoted()); + flags.set ("JucePlugin_VSTNumMidiInputs", getVSTNumMIDIInputsString()); + flags.set ("JucePlugin_VSTNumMidiOutputs", getVSTNumMIDIOutputsString()); + + { + String plugInChannelConfig = getPluginChannelConfigsString(); + + if (plugInChannelConfig.isNotEmpty()) + { + flags.set ("JucePlugin_MaxNumInputChannels", String (countMaxPluginChannels (plugInChannelConfig, true))); + flags.set ("JucePlugin_MaxNumOutputChannels", String (countMaxPluginChannels (plugInChannelConfig, false))); + flags.set ("JucePlugin_PreferredChannelConfigurations", plugInChannelConfig); + } + } + return flags; } //============================================================================== @@ -2219,7 +2630,7 @@ bool Project::ExporterIterator::next() if (++index >= project.getNumExporters()) return false; - exporter.reset (project.createExporter (index)); + exporter = project.createExporter (index); if (exporter == nullptr) { diff --git a/extras/Projucer/Source/Project/jucer_Project.h b/extras/Projucer/Source/Project/jucer_Project.h index 80711e8b..f2b352d4 100644 --- a/extras/Projucer/Source/Project/jucer_Project.h +++ b/extras/Projucer/Source/Project/jucer_Project.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -26,18 +25,97 @@ #pragma once -#include "jucer_ProjectType.h" +#include "../Application/UserAccount/jucer_LicenseController.h" +#include "Modules/jucer_AvailableModulesList.h" class ProjectExporter; class LibraryModule; -class EnabledModuleList; -class AvailableModuleList; -class ProjectContentComponent; +class EnabledModulesList; class CompileEngineSettings; +namespace ProjectMessages +{ + namespace Ids + { + #define DECLARE_ID(name) static const Identifier name (#name) + + DECLARE_ID (projectMessages); + + DECLARE_ID (incompatibleLicense); + DECLARE_ID (cppStandard); + DECLARE_ID (moduleNotFound); + DECLARE_ID (jucePath); + DECLARE_ID (jucerFileModified); + DECLARE_ID (missingModuleDependencies); + DECLARE_ID (oldProjucer); + DECLARE_ID (cLion); + DECLARE_ID (newVersionAvailable); + + DECLARE_ID (notification); + DECLARE_ID (warning); + + DECLARE_ID (isVisible); + + #undef DECLARE_ID + } + + inline Identifier getTypeForMessage (const Identifier& message) + { + static Identifier warnings[] = { Ids::incompatibleLicense, Ids::cppStandard, Ids::moduleNotFound, + Ids::jucePath, Ids::jucerFileModified, Ids::missingModuleDependencies, + Ids::oldProjucer, Ids::cLion }; + + if (std::find (std::begin (warnings), std::end (warnings), message) != std::end (warnings)) + return Ids::warning; + + if (message == Ids::newVersionAvailable) + return Ids::notification; + + jassertfalse; + return {}; + } + + inline String getTitleForMessage (const Identifier& message) + { + if (message == Ids::incompatibleLicense) return "Incompatible License and Splash Screen Setting"; + if (message == Ids::cppStandard) return "C++ Standard"; + if (message == Ids::moduleNotFound) return "Module Not Found"; + if (message == Ids::jucePath) return "JUCE Path"; + if (message == Ids::jucerFileModified) return "Project File Modified"; + if (message == Ids::missingModuleDependencies) return "Missing Module Dependencies"; + if (message == Ids::oldProjucer) return "Projucer Out of Date"; + if (message == Ids::newVersionAvailable) return "New Version Available"; + if (message == Ids::cLion) return "Deprecated Exporter"; + + jassertfalse; + return {}; + } + + inline String getDescriptionForMessage (const Identifier& message) + { + if (message == Ids::incompatibleLicense) return "Save and export is disabled."; + if (message == Ids::cppStandard) return "Module(s) have a higher C++ standard requirement than the project."; + if (message == Ids::moduleNotFound) return "Module(s) could not be found at the specified paths."; + if (message == Ids::jucePath) return "The path to your JUCE folder is incorrect."; + if (message == Ids::jucerFileModified) return "The .jucer file has been modified since the last save."; + if (message == Ids::missingModuleDependencies) return "Module(s) have missing dependencies."; + if (message == Ids::oldProjucer) return "The version of the Projucer you are using is out of date."; + if (message == Ids::newVersionAvailable) return "A new version of JUCE is available to download."; + if (message == Ids::cLion) return "The CLion exporter is deprecated. Use JUCE's CMake support instead."; + + jassertfalse; + return {}; + } + + using MessageAction = std::pair<String, std::function<void()>>; +} + //============================================================================== class Project : public FileBasedDocument, - public ValueTree::Listener + private ValueTree::Listener, + private LicenseController::LicenseStateListener, + private ChangeListener, + private AvailableModulesList::Listener { public: //============================================================================== @@ -45,12 +123,14 @@ public: ~Project() override; //============================================================================== - // FileBasedDocument stuff.. String getDocumentTitle() override; Result loadDocument (const File& file) override; Result saveDocument (const File& file) override; - Result saveProject (const File& file, bool isCommandLineApp); - Result saveResourcesOnly (const File& file); + + Result saveProject (ProjectExporter* exporterToSave = nullptr); + Result saveResourcesOnly(); + Result openProjectInIDE (ProjectExporter& exporterToOpen, bool saveFirst); + File getLastDocumentOpened() override; void setLastDocumentOpened (const File& file) override; @@ -68,6 +148,7 @@ public: File getBinaryDataHeaderFile() const { return getBinaryDataCppFile (0).withFileExtension (".h"); } static String getAppConfigFilename() { return "AppConfig.h"; } + static String getPluginDefinesFilename() { return "JucePluginDefines.h"; } static String getJuceSourceHFilename() { return "JuceHeader.h"; } //============================================================================== @@ -89,7 +170,7 @@ public: Value getProjectValue (const Identifier& name) { return projectRoot.getPropertyAsValue (name, getUndoManagerFor (projectRoot)); } var getProjectVar (const Identifier& name) const { return projectRoot.getProperty (name); } - const ProjectType& getProjectType() const; + const build_tools::ProjectType& getProjectType() const; String getProjectTypeString() const { return projectTypeValue.get(); } void setProjectType (const String& newProjectType) { projectTypeValue = newProjectType; } @@ -100,8 +181,8 @@ public: String getProjectLineFeed() const { return projectLineFeedValue.get(); } String getVersionString() const { return versionValue.get(); } - String getVersionAsHex() const; - int getVersionAsHexInteger() const; + String getVersionAsHex() const { return build_tools::getVersionAsHex (getVersionString()); } + int getVersionAsHexInteger() const { return build_tools::getVersionAsHexInteger (getVersionString()); } void setProjectVersion (const String& newVersion) { versionValue = newVersion; } String getBundleIdentifierString() const { return bundleIdentifierValue.get(); } @@ -123,17 +204,22 @@ public: String getBinaryDataNamespaceString() const { return binaryDataNamespaceValue.get(); } bool shouldDisplaySplashScreen() const { return displaySplashScreenValue.get(); } - bool shouldReportAppUsage() const { return reportAppUsageValue.get(); } String getSplashScreenColourString() const { return splashScreenColourValue.get(); } + static StringArray getCppStandardStrings() { return { "C++11", "C++14", "C++17", "Use Latest" }; } + static Array<var> getCppStandardVars() { return { "11", "14", "17", "latest" }; } + String getCppStandardString() const { return cppStandardValue.get(); } StringArray getCompilerFlagSchemes() const; void addCompilerFlagScheme (const String&); void removeCompilerFlagScheme (const String&); - String getPostExportShellCommandPosixString() const { return postExportShellCommandPosixValue.get(); } - String getPostExportShellCommandWinString() const { return postExportShellCommandWinValue.get(); } + String getPostExportShellCommandPosixString() const { return postExportShellCommandPosixValue.get(); } + String getPostExportShellCommandWinString() const { return postExportShellCommandWinValue.get(); } + + bool shouldUseAppConfig() const { return useAppConfigValue.get(); } + bool shouldAddUsingNamespaceToJuceHeader() const { return addUsingNamespaceToJuceHeader.get(); } //============================================================================== String getPluginNameString() const { return pluginNameValue.get(); } @@ -207,8 +293,8 @@ public: int getAAXCategory() const noexcept; int getRTASCategory() const noexcept; - String getIAATypeCode(); - String getIAAPluginName(); + String getIAATypeCode() const; + String getIAAPluginName() const; String getUnityScriptName() const { return addUnityPluginPrefixIfNecessary (getProjectNameString()) + "_UnityScript.cs"; } static String addUnityPluginPrefixIfNecessary (const String& name) @@ -225,12 +311,15 @@ public: bool isVST3PluginHost(); //============================================================================== - bool shouldBuildTargetType (ProjectType::Target::Type targetType) const noexcept; - static ProjectType::Target::Type getTargetTypeFromFilePath (const File& file, bool returnSharedTargetIfNoValidSuffix); + bool shouldBuildTargetType (build_tools::ProjectType::Target::Type targetType) const noexcept; + static build_tools::ProjectType::Target::Type getTargetTypeFromFilePath (const File& file, bool returnSharedTargetIfNoValidSuffix); //============================================================================== void updateDeprecatedProjectSettingsInteractively(); + StringPairArray getAppConfigDefs(); + StringPairArray getAudioPluginFlags() const; + //============================================================================== class Item { @@ -252,6 +341,7 @@ public: bool isGroup() const; bool isMainGroup() const; bool isImageFile() const; + bool isSourceFile() const; String getID() const; void setID (const String& newID); @@ -266,7 +356,7 @@ public: File getFile() const; String getFilePath() const; void setFile (const File& file); - void setFile (const RelativePath& file); + void setFile (const build_tools::RelativePath& file); File determineGroupFolder() const; bool renameFile (const File& newFile); @@ -286,6 +376,9 @@ public: bool isModuleCode() const; + Value getShouldSkipPCHValue(); + bool shouldSkipPCH() const; + Value getCompilerFlagSchemeValue(); String getCompilerFlagSchemeString() const; @@ -303,11 +396,11 @@ public: bool addFileAtIndex (const File& file, int insertIndex, bool shouldCompile); bool addFileRetainingSortOrder (const File& file, bool shouldCompile); void addFileUnchecked (const File& file, int insertIndex, bool shouldCompile); - bool addRelativeFile (const RelativePath& file, int insertIndex, bool shouldCompile); + bool addRelativeFile (const build_tools::RelativePath& file, int insertIndex, bool shouldCompile); void removeItemFromProject(); void sortAlphabetically (bool keepGroupsAtStart, bool recursive); Item findItemForFile (const File& file) const; - bool containsChildForFile (const RelativePath& file) const; + bool containsChildForFile (const build_tools::RelativePath& file) const; Item getParent() const; Item createCopy(); @@ -334,8 +427,8 @@ public: //============================================================================== ValueTree getExporters(); int getNumExporters(); - ProjectExporter* createExporter (int index); - void addNewExporter (const String& exporterName); + std::unique_ptr<ProjectExporter> createExporter (int index); + void addNewExporter (const Identifier& exporterIdentifier); void createExporterForCurrentPlatform(); struct ExporterIterator @@ -367,25 +460,16 @@ public: bool isConfigFlagEnabled (const String& name, bool defaultIsEnabled = false) const; //============================================================================== - EnabledModuleList& getEnabledModules(); + EnabledModulesList& getEnabledModules(); - AvailableModuleList& getExporterPathsModuleList(); + AvailableModulesList& getExporterPathsModulesList() { return exporterPathsModulesList; } void rescanExporterPathModules (bool async = false); std::pair<String, File> getModuleWithID (const String&); - //============================================================================== - String getFileTemplate (const String& templateName); - //============================================================================== PropertiesFile& getStoredProperties() const; - //============================================================================== - void valueTreePropertyChanged (ValueTree&, const Identifier&) override; - void valueTreeChildAdded (ValueTree&, ValueTree&) override; - void valueTreeChildRemoved (ValueTree&, ValueTree&, int) override; - void valueTreeChildOrderChanged (ValueTree&, int, int) override; - //============================================================================== UndoManager* getUndoManagerFor (const ValueTree&) const { return nullptr; } UndoManager* getUndoManager() const { return nullptr; } @@ -394,38 +478,68 @@ public: static const char* projectFileExtension; //============================================================================== - bool hasProjectBeenModified(); - void updateModificationTime() { modificationTime = getFile().getLastModificationTime(); } + bool updateCachedFileState(); + String getCachedFileStateContent() const noexcept { return cachedFileState.second; } - //============================================================================== - String getUniqueTargetFolderSuffixForExporter (const String& exporterName, const String& baseTargetFolder); + String serialiseProjectXml (std::unique_ptr<XmlElement>) const; //============================================================================== - bool isCurrentlySaving() const noexcept { return isSaving; } - bool shouldWaitAfterSaving = false; - String specifiedExporterToSave = {}; + String getUniqueTargetFolderSuffixForExporter (const Identifier& exporterIdentifier, const String& baseTargetFolder); //============================================================================== + bool isCurrentlySaving() const noexcept { return isSaving; } + bool isTemporaryProject() const noexcept { return tempDirectory != File(); } File getTemporaryDirectory() const noexcept { return tempDirectory; } void setTemporaryDirectory (const File&) noexcept; - void setOpenInIDEAfterSaving (bool open) noexcept { openInIDEAfterSaving = open; } - bool shouldOpenInIDEAfterSaving() const noexcept { return openInIDEAfterSaving; } + //============================================================================== + CompileEngineSettings& getCompileEngineSettings() { return *compileEngineSettings; } //============================================================================== - bool shouldSendGUIBuilderAnalyticsEvent() noexcept; + ValueTree getProjectMessages() const { return projectMessages; } + + void addProjectMessage (const Identifier& messageToAdd, std::vector<ProjectMessages::MessageAction>&& messageActions); + void removeProjectMessage (const Identifier& messageToRemove); + + std::vector<ProjectMessages::MessageAction> getMessageActions (const Identifier& message); //============================================================================== - CompileEngineSettings& getCompileEngineSettings() { return *compileEngineSettings; } + bool hasIncompatibleLicenseTypeAndSplashScreenSetting() const; + bool isFileModificationCheckPending() const; + bool isSaveAndExportDisabled() const; private: + //============================================================================== + void valueTreePropertyChanged (ValueTree&, const Identifier&) override; + void valueTreeChildAdded (ValueTree&, ValueTree&) override; + void valueTreeChildRemoved (ValueTree&, ValueTree&, int) override; + void valueTreeChildOrderChanged (ValueTree&, int, int) override; + + //============================================================================== + struct ProjectFileModificationPoller : private Timer + { + ProjectFileModificationPoller (Project& p); + bool isCheckPending() const noexcept { return pending; } + + private: + void timerCallback() override; + void reset(); + + void resaveProject(); + void reloadProjectFromDisk(); + + Project& project; + bool pending = false; + }; + + //============================================================================== ValueTree projectRoot { Ids::JUCERPROJECT }; ValueWithDefault projectNameValue, projectUIDValue, projectLineFeedValue, projectTypeValue, versionValue, bundleIdentifierValue, companyNameValue, - companyCopyrightValue, companyWebsiteValue, companyEmailValue, displaySplashScreenValue, reportAppUsageValue, splashScreenColourValue, cppStandardValue, + companyCopyrightValue, companyWebsiteValue, companyEmailValue, displaySplashScreenValue, splashScreenColourValue, cppStandardValue, headerSearchPathsValue, preprocessorDefsValue, userNotesValue, maxBinaryFileSizeValue, includeBinaryDataInJuceHeaderValue, binaryDataNamespaceValue, - compilerFlagSchemesValue, postExportShellCommandPosixValue, postExportShellCommandWinValue; + compilerFlagSchemesValue, postExportShellCommandPosixValue, postExportShellCommandWinValue, useAppConfigValue, addUsingNamespaceToJuceHeader; ValueWithDefault pluginFormatsValue, pluginNameValue, pluginDescriptionValue, pluginManufacturerValue, pluginManufacturerCodeValue, pluginCodeValue, pluginChannelConfigsValue, pluginCharacteristicsValue, pluginAUExportPrefixValue, pluginAAXIdentifierValue, @@ -434,8 +548,12 @@ private: //============================================================================== std::unique_ptr<CompileEngineSettings> compileEngineSettings; - std::unique_ptr<EnabledModuleList> enabledModuleList; - std::unique_ptr<AvailableModuleList> exporterPathsModuleList; + std::unique_ptr<EnabledModulesList> enabledModulesList; + + AvailableModulesList exporterPathsModulesList; + + //============================================================================== + void updateDeprecatedProjectSettings(); //============================================================================== bool shouldWriteLegacyPluginFormatSettings = false; @@ -452,20 +570,14 @@ private: void updatePluginCategories(); //============================================================================== - File tempDirectory = {}; - bool openInIDEAfterSaving = false; + File tempDirectory; + std::pair<Time, String> cachedFileState; - void askUserWhereToSaveProject(); - void moveTemporaryDirectory (const File&); - bool saveProjectRootToFile(); - - //============================================================================== - bool hasSentGUIBuilderAnalyticsEvent = false; + void saveAndMoveTemporaryProject (bool openInIDE); //============================================================================== friend class Item; bool isSaving = false; - Time modificationTime; StringPairArray parsedPreprocessorDefs; //============================================================================== @@ -488,7 +600,29 @@ private: void moveOldPropertyFromProjectToAllExporters (Identifier name); void removeDefunctExporters(); void updateOldModulePaths(); - void warnAboutOldProjucerVersion(); + //============================================================================== + void licenseStateChanged() override; + void changeListenerCallback (ChangeBroadcaster*) override; + void availableModulesChanged (AvailableModulesList*) override; + + void updateLicenseWarning(); + void updateJUCEPathWarning(); + + void updateModuleWarnings(); + void updateExporterWarnings(); + void updateCppStandardWarning (bool showWarning); + void updateMissingModuleDependenciesWarning (bool showWarning); + void updateOldProjucerWarning (bool showWarning); + void updateCLionWarning (bool showWarning); + void updateModuleNotFoundWarning (bool showWarning); + + ValueTree projectMessages { ProjectMessages::Ids::projectMessages, {}, + { { ProjectMessages::Ids::notification, {} }, { ProjectMessages::Ids::warning, {} } } }; + std::map<Identifier, std::vector<ProjectMessages::MessageAction>> messageActions; + + ProjectFileModificationPoller fileModificationPoller { *this }; + + //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Project) }; diff --git a/extras/Projucer/Source/Project/jucer_ProjectType.h b/extras/Projucer/Source/Project/jucer_ProjectType.h deleted file mode 100644 index 14c318a2..00000000 --- a/extras/Projucer/Source/Project/jucer_ProjectType.h +++ /dev/null @@ -1,212 +0,0 @@ -/* - ============================================================================== - - 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. - - ============================================================================== -*/ - -#pragma once - -class Project; -class ProjectExporter; - -//============================================================================== -class ProjectType -{ -public: - //============================================================================== - virtual ~ProjectType(); - - const String& getType() const noexcept { return type; } - const String& getDescription() const noexcept { return desc; } - - //============================================================================== - static Array<ProjectType*> getAllTypes(); - static const ProjectType* findType (const String& typeCode); - - //============================================================================== - virtual bool isStaticLibrary() const { return false; } - virtual bool isDynamicLibrary() const { return false; } - virtual bool isGUIApplication() const { return false; } - virtual bool isCommandLineApp() const { return false; } - virtual bool isAudioPlugin() const { return false; } - - //============================================================================== - struct Target - { - enum Type - { - GUIApp = 0, - ConsoleApp = 1, - StaticLibrary = 2, - DynamicLibrary = 3, - - VSTPlugIn = 10, - VST3PlugIn = 11, - AAXPlugIn = 12, - RTASPlugIn = 13, - AudioUnitPlugIn = 14, - AudioUnitv3PlugIn = 15, - StandalonePlugIn = 16, - UnityPlugIn = 17, - - SharedCodeTarget = 20, // internal - AggregateTarget = 21, - - unspecified = 30 - }; - - enum TargetFileType - { - executable = 0, - staticLibrary = 1, - sharedLibraryOrDLL = 2, - pluginBundle = 3, - macOSAppex = 4, - unknown = 5 - }; - - //============================================================================== - Target (Type targetType) : type (targetType) {} - - const char* getName() const noexcept; - TargetFileType getTargetFileType() const noexcept; - - const Type type; - - private: - //============================================================================== - Target& operator= (const Target&) = delete; - }; - - virtual bool supportsTargetType (Target::Type /*targetType*/) const { return false; } - -protected: - ProjectType (const String& type, const String& desc); - -private: - const String type, desc; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProjectType) -}; - -//============================================================================== -inline ProjectType::ProjectType (const String& t, const String& d) - : type (t), desc (d) -{ -} - -inline ProjectType::~ProjectType() -{ - getAllTypes().removeFirstMatchingValue (this); -} - -inline const ProjectType* ProjectType::findType (const String& typeCode) -{ - const auto& types = getAllTypes(); - - for (auto i = types.size(); --i >= 0;) - if (types.getUnchecked(i)->getType() == typeCode) - return types.getUnchecked(i); - - jassertfalse; - return nullptr; -} - -//============================================================================== -struct ProjectType_GUIApp : public ProjectType -{ - ProjectType_GUIApp() : ProjectType (getTypeName(), "GUI Application") {} - - static const char* getTypeName() noexcept { return "guiapp"; } - bool isGUIApplication() const override { return true; } - bool supportsTargetType (Target::Type targetType) const override { return (targetType == Target::GUIApp); } -}; - -struct ProjectType_ConsoleApp : public ProjectType -{ - ProjectType_ConsoleApp() : ProjectType (getTypeName(), "Console Application") {} - - static const char* getTypeName() noexcept { return "consoleapp"; } - bool isCommandLineApp() const override { return true; } - bool supportsTargetType (Target::Type targetType) const override { return (targetType == Target::ConsoleApp); } -}; - -struct ProjectType_StaticLibrary : public ProjectType -{ - ProjectType_StaticLibrary() : ProjectType (getTypeName(), "Static Library") {} - - static const char* getTypeName() noexcept { return "library"; } - bool isStaticLibrary() const override { return true; } - bool supportsTargetType (Target::Type targetType) const override { return (targetType == Target::StaticLibrary); } -}; - -struct ProjectType_DLL : public ProjectType -{ - ProjectType_DLL() : ProjectType (getTypeName(), "Dynamic Library") {} - - static const char* getTypeName() noexcept { return "dll"; } - bool isDynamicLibrary() const override { return true; } - bool supportsTargetType (Target::Type targetType) const override { return (targetType == Target::DynamicLibrary); } -}; - -struct ProjectType_AudioPlugin : public ProjectType -{ - ProjectType_AudioPlugin() : ProjectType (getTypeName(), "Audio Plug-in") {} - - static const char* getTypeName() noexcept { return "audioplug"; } - bool isAudioPlugin() const override { return true; } - - bool supportsTargetType (Target::Type targetType) const override - { - switch (targetType) - { - case Target::VSTPlugIn: - case Target::VST3PlugIn: - case Target::AAXPlugIn: - case Target::RTASPlugIn: - case Target::AudioUnitPlugIn: - case Target::AudioUnitv3PlugIn: - case Target::StandalonePlugIn: - case Target::UnityPlugIn: - case Target::SharedCodeTarget: - case Target::AggregateTarget: - return true; - default: - break; - } - - return false; - } -}; - -//============================================================================== -inline Array<ProjectType*> ProjectType::getAllTypes() -{ - static ProjectType_GUIApp guiApp; - static ProjectType_ConsoleApp consoleApp; - static ProjectType_StaticLibrary staticLib; - static ProjectType_DLL dll; - static ProjectType_AudioPlugin plugin; - - return Array<ProjectType*>(&guiApp, &consoleApp, &staticLib, &dll, &plugin); -} diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Android.h b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Android.h index bed3870d..304078a0 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Android.h +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Android.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -49,24 +48,16 @@ public: bool canCopeWithDuplicateFiles() override { return false; } bool supportsUserDefinedConfigurations() const override { return true; } - bool supportsTargetType (ProjectType::Target::Type type) const override - { - switch (type) - { - case ProjectType::Target::GUIApp: - case ProjectType::Target::StaticLibrary: - case ProjectType::Target::DynamicLibrary: - case ProjectType::Target::StandalonePlugIn: - return true; - default: - break; - } + String getNewLineString() const override { return "\n"; } - return false; + bool supportsTargetType (build_tools::ProjectType::Target::Type type) const override + { + return type == build_tools::ProjectType::Target::GUIApp || type == build_tools::ProjectType::Target::StaticLibrary + || type == build_tools::ProjectType::Target::DynamicLibrary || type == build_tools::ProjectType::Target::StandalonePlugIn; } //============================================================================== - void addPlatformSpecificSettingsForProjectType (const ProjectType&) override + void addPlatformSpecificSettingsForProjectType (const build_tools::ProjectType&) override { // no-op. } @@ -81,17 +72,19 @@ public: createOtherExporterProperties (props); } - static const char* getName() { return "Android"; } - static const char* getValueTreeTypeName() { return "ANDROIDSTUDIO"; } - static const char* getDefaultActivityClass() { return "com.roli.juce.JuceActivity"; } - static const char* getDefaultApplicationClass() { return "com.roli.juce.JuceApp"; } + static String getDisplayName() { return "Android"; } + static String getValueTreeTypeName() { return "ANDROIDSTUDIO"; } + static String getTargetFolderName() { return "Android"; } + + static const char* getDefaultActivityClass() { return "com.rmsl.juce.JuceActivity"; } + static const char* getDefaultApplicationClass() { return "com.rmsl.juce.JuceApp"; } static AndroidProjectExporter* createForSettings (Project& projectToUse, const ValueTree& settingsToUse) { if (settingsToUse.hasType (getValueTreeTypeName())) return new AndroidProjectExporter (projectToUse, settingsToUse); - return nullptr; + return {}; } //============================================================================== @@ -119,7 +112,7 @@ public: androidGradleSettingsContent (settings, Ids::androidGradleSettingsContent, getUndoManager()), androidVersionCode (settings, Ids::androidVersionCode, getUndoManager(), "1"), androidMinimumSDK (settings, Ids::androidMinimumSDK, getUndoManager(), "16"), - androidTargetSDK (settings, Ids::androidTargetSDK, getUndoManager(), "28"), + androidTargetSDK (settings, Ids::androidTargetSDK, getUndoManager(), "29"), androidTheme (settings, Ids::androidTheme, getUndoManager()), androidExtraAssetsFolder (settings, Ids::androidExtraAssetsFolder, getUndoManager()), androidOboeRepositoryPath (settings, Ids::androidOboeRepositoryPath, getUndoManager()), @@ -140,14 +133,13 @@ public: androidKeyStorePass (settings, Ids::androidKeyStorePass, getUndoManager(), "android"), androidKeyAlias (settings, Ids::androidKeyAlias, getUndoManager(), "androiddebugkey"), androidKeyAliasPass (settings, Ids::androidKeyAliasPass, getUndoManager(), "android"), - gradleVersion (settings, Ids::gradleVersion, getUndoManager(), "5.4.1"), + gradleVersion (settings, Ids::gradleVersion, getUndoManager(), "6.1.1"), gradleToolchain (settings, Ids::gradleToolchain, getUndoManager(), "clang"), - androidPluginVersion (settings, Ids::androidPluginVersion, getUndoManager(), "3.5.3"), + androidPluginVersion (settings, Ids::androidPluginVersion, getUndoManager(), "4.0.0"), AndroidExecutable (getAppSettings().getStoredPath (Ids::androidStudioExePath, TargetOS::getThisOS()).get().toString()) { - name = getName(); - - targetLocationValue.setDefault (getDefaultBuildsRootFolder() + getTargetFolderForExporter (getValueTreeTypeName())); + name = getDisplayName(); + targetLocationValue.setDefault (getDefaultBuildsRootFolder() + getTargetFolderName()); } //============================================================================== @@ -246,20 +238,20 @@ public: void writeFile (const File& gradleProjectFolder, const String& filePath, const String& fileContent) const { - MemoryOutputStream outStream; - outStream.setNewLineString ("\n"); - - outStream << fileContent; - overwriteFileIfDifferentOrThrow (gradleProjectFolder.getChildFile (filePath), outStream); + build_tools::writeStreamToFile (gradleProjectFolder.getChildFile (filePath), [&] (MemoryOutputStream& mo) + { + mo.setNewLineString (getNewLineString()); + mo << fileContent; + }); } void writeBinaryFile (const File& gradleProjectFolder, const String& filePath, const char* binaryData, const int binarySize) const { - MemoryOutputStream outStream; - outStream.setNewLineString ("\n"); - - outStream.write (binaryData, static_cast<size_t> (binarySize)); - overwriteFileIfDifferentOrThrow (gradleProjectFolder.getChildFile (filePath), outStream); + build_tools::writeStreamToFile (gradleProjectFolder.getChildFile (filePath), [&] (MemoryOutputStream& mo) + { + mo.setNewLineString (getNewLineString()); + mo.write (binaryData, static_cast<size_t> (binarySize)); + }); } protected: @@ -348,212 +340,247 @@ protected: private: void writeCmakeFile (const File& file) const { - MemoryOutputStream mo; - mo.setNewLineString ("\n"); - - mo << "# Automatically generated makefile, created by the Projucer" << newLine - << "# Don't edit this file! Your changes will be overwritten when you re-save the Projucer project!" << newLine - << newLine; + build_tools::writeStreamToFile (file, [&] (MemoryOutputStream& mo) + { + mo.setNewLineString (getNewLineString()); - mo << "cmake_minimum_required(VERSION 3.4.1)" << newLine << newLine; + mo << "# Automatically generated makefile, created by the Projucer" << newLine + << "# Don't edit this file! Your changes will be overwritten when you re-save the Projucer project!" << newLine + << newLine; - if (! isLibrary()) - mo << "SET(BINARY_NAME \"juce_jni\")" << newLine << newLine; + mo << "cmake_minimum_required(VERSION 3.4.1)" << newLine << newLine; - if (project.getConfigFlag ("JUCE_USE_ANDROID_OBOE").get()) - { - String oboePath (androidOboeRepositoryPath.get().toString().trim().quoted()); + if (! isLibrary()) + mo << "set(BINARY_NAME \"juce_jni\")" << newLine << newLine; - mo << "SET(OBOE_DIR " << oboePath << ")" << newLine << newLine; - mo << "add_subdirectory (${OBOE_DIR} ./oboe)" << newLine << newLine; - } + auto useOboe = project.getEnabledModules().isModuleEnabled ("juce_audio_devices") + && project.isConfigFlagEnabled ("JUCE_USE_ANDROID_OBOE", true); - String cpufeaturesPath ("${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c"); - mo << "add_library(\"cpufeatures\" STATIC \"" << cpufeaturesPath << "\")" << newLine - << "set_source_files_properties(\"" << cpufeaturesPath << "\" PROPERTIES COMPILE_FLAGS \"-Wno-sign-conversion -Wno-gnu-statement-expression\")" << newLine << newLine; + if (useOboe) + { + auto oboePath = [&] + { + auto oboeDir = androidOboeRepositoryPath.get().toString().trim(); - { - auto projectDefines = getEscapedPreprocessorDefs (getProjectPreprocessorDefs()); - if (projectDefines.size() > 0) - mo << "add_definitions(" << projectDefines.joinIntoString (" ") << ")" << newLine << newLine; - } + if (oboeDir.isEmpty()) + oboeDir = getModuleFolderRelativeToProject ("juce_audio_devices").getChildFile ("native") + .getChildFile ("oboe") + .rebased (getProject().getProjectFolder(), getTargetFolder(), + build_tools::RelativePath::buildTargetFolder) + .toUnixStyle(); - { - mo << "include_directories( AFTER" << newLine; + // CMakeLists.txt is in the "app" subfolder + if (! build_tools::isAbsolutePath (oboeDir)) + oboeDir = "../" + oboeDir; - for (auto& path : extraSearchPaths) - mo << " \"" << escapeDirectoryForCmake (path) << "\"" << newLine; + return expandHomeFolderToken (oboeDir); + }(); - mo << " \"${ANDROID_NDK}/sources/android/cpufeatures\"" << newLine; + mo << "set(OBOE_DIR " << oboePath.quoted() << ")" << newLine << newLine; + mo << "add_subdirectory (${OBOE_DIR} ./oboe)" << newLine << newLine; + } - if (project.getConfigFlag ("JUCE_USE_ANDROID_OBOE").get()) - mo << " \"${OBOE_DIR}/include\"" << newLine; + String cpufeaturesPath ("${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c"); + mo << "add_library(\"cpufeatures\" STATIC \"" << cpufeaturesPath << "\")" << newLine + << "set_source_files_properties(\"" << cpufeaturesPath << "\" PROPERTIES COMPILE_FLAGS \"-Wno-sign-conversion -Wno-gnu-statement-expression\")" << newLine << newLine; - mo << ")" << newLine << newLine; - } + { + auto projectDefines = getEscapedPreprocessorDefs (getProjectPreprocessorDefs()); + if (projectDefines.size() > 0) + mo << "add_definitions(" << projectDefines.joinIntoString (" ") << ")" << newLine << newLine; + } - auto cfgExtraLinkerFlags = getExtraLinkerFlagsString(); - if (cfgExtraLinkerFlags.isNotEmpty()) - { - mo << "SET( JUCE_LDFLAGS \"" << cfgExtraLinkerFlags.replace ("\"", "\\\"") << "\")" << newLine; - mo << "SET( CMAKE_SHARED_LINKER_FLAGS \"${CMAKE_EXE_LINKER_FLAGS} ${JUCE_LDFLAGS}\")" << newLine << newLine; - } + { + mo << "include_directories( AFTER" << newLine; - mo << "enable_language(ASM)" << newLine << newLine; + for (auto& path : extraSearchPaths) + mo << " \"" << escapeDirectoryForCmake (path) << "\"" << newLine; - auto userLibraries = StringArray::fromTokens (getExternalLibrariesString(), ";", ""); - userLibraries.addArray (androidLibs); + mo << " \"${ANDROID_NDK}/sources/android/cpufeatures\"" << newLine; - if (getNumConfigurations() > 0) - { - bool first = true; + mo << ")" << newLine << newLine; + } - for (ConstConfigIterator config (*this); config.next();) + auto cfgExtraLinkerFlags = getExtraLinkerFlagsString(); + if (cfgExtraLinkerFlags.isNotEmpty()) { - auto& cfg = dynamic_cast<const AndroidBuildConfiguration&> (*config); - auto libSearchPaths = cfg.getLibrarySearchPaths(); - auto cfgDefines = getConfigPreprocessorDefs (cfg); - auto cfgHeaderPaths = cfg.getHeaderSearchPaths(); - auto cfgLibraryPaths = cfg.getLibrarySearchPaths(); + mo << "set( JUCE_LDFLAGS \"" << cfgExtraLinkerFlags.replace ("\"", "\\\"") << "\")" << newLine; + mo << "set( CMAKE_SHARED_LINKER_FLAGS \"${CMAKE_EXE_LINKER_FLAGS} ${JUCE_LDFLAGS}\")" << newLine << newLine; + } - if (! isLibrary() && libSearchPaths.size() == 0 && cfgDefines.size() == 0 - && cfgHeaderPaths.size() == 0 && cfgLibraryPaths.size() == 0) - continue; + mo << "enable_language(ASM)" << newLine << newLine; - mo << (first ? "IF" : "ELSEIF") << "(JUCE_BUILD_CONFIGURATION MATCHES \"" << cfg.getProductFlavourCMakeIdentifier() <<"\")" << newLine; + auto userLibraries = StringArray::fromTokens (getExternalLibrariesString(), ";", ""); + userLibraries.addArray (androidLibs); - if (isLibrary()) + if (getNumConfigurations() > 0) + { + bool first = true; + + for (ConstConfigIterator config (*this); config.next();) { - mo << " SET(BINARY_NAME \"" << getNativeModuleBinaryName (cfg) << "\")" << newLine; + auto& cfg = dynamic_cast<const AndroidBuildConfiguration&> (*config); + auto libSearchPaths = cfg.getLibrarySearchPaths(); + auto cfgDefines = getConfigPreprocessorDefs (cfg); + auto cfgHeaderPaths = cfg.getHeaderSearchPaths(); + auto cfgLibraryPaths = cfg.getLibrarySearchPaths(); - auto binaryLocation = cfg.getTargetBinaryRelativePathString(); + if (! isLibrary() && libSearchPaths.size() == 0 && cfgDefines.size() == 0 + && cfgHeaderPaths.size() == 0 && cfgLibraryPaths.size() == 0) + continue; - if (binaryLocation.isNotEmpty()) + mo << (first ? "if" : "elseif") << "(JUCE_BUILD_CONFIGURATION MATCHES \"" << cfg.getProductFlavourCMakeIdentifier() <<"\")" << newLine; + + if (isLibrary()) { - auto locationRelativeToCmake = RelativePath (binaryLocation, RelativePath::projectFolder) - .rebased (getProject().getFile().getParentDirectory(), - file.getParentDirectory(), RelativePath::buildTargetFolder); + mo << " set(BINARY_NAME \"" << getNativeModuleBinaryName (cfg) << "\")" << newLine; + + auto binaryLocation = cfg.getTargetBinaryRelativePathString(); - mo << " SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY \"" << "../../../../" << locationRelativeToCmake.toUnixStyle() << "\")" << newLine; + if (binaryLocation.isNotEmpty()) + { + auto locationRelativeToCmake = build_tools::RelativePath (binaryLocation, build_tools::RelativePath::projectFolder) + .rebased (getProject().getFile().getParentDirectory(), + file.getParentDirectory(), build_tools::RelativePath::buildTargetFolder); + + mo << " set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY \"" << "../../../../" << locationRelativeToCmake.toUnixStyle() << "\")" << newLine; + } } - } - writeCmakePathLines (mo, " ", "link_directories(", libSearchPaths); + writeCmakePathLines (mo, " ", "link_directories(", libSearchPaths); - if (cfgDefines.size() > 0) - mo << " add_definitions(" << getEscapedPreprocessorDefs (cfgDefines).joinIntoString (" ") << ")" << newLine; + if (cfgDefines.size() > 0) + mo << " add_definitions(" << getEscapedPreprocessorDefs (cfgDefines).joinIntoString (" ") << ")" << newLine; - writeCmakePathLines (mo, " ", "include_directories( AFTER", cfgHeaderPaths); + writeCmakePathLines (mo, " ", "include_directories( AFTER", cfgHeaderPaths); - if (userLibraries.size() > 0) - { - for (auto& lib : userLibraries) + if (userLibraries.size() > 0) { - String findLibraryCmd; - findLibraryCmd << "find_library(" << lib.toLowerCase().replaceCharacter (L' ', L'_') - << " \"" << lib << "\" PATHS"; + for (auto& lib : userLibraries) + { + String findLibraryCmd; + findLibraryCmd << "find_library(" << lib.toLowerCase().replaceCharacter (L' ', L'_') + << " \"" << lib << "\" PATHS"; - writeCmakePathLines (mo, " ", findLibraryCmd, cfgLibraryPaths, " NO_CMAKE_FIND_ROOT_PATH)"); + writeCmakePathLines (mo, " ", findLibraryCmd, cfgLibraryPaths, " NO_CMAKE_FIND_ROOT_PATH)"); + } + + mo << newLine; + } + + if (cfg.isLinkTimeOptimisationEnabled()) + { + // There's no MIPS support for LTO + String mipsCondition ("NOT (ANDROID_ABI STREQUAL \"mips\" OR ANDROID_ABI STREQUAL \"mips64\")"); + mo << " if(" << mipsCondition << ")" << newLine; + StringArray cmakeVariables ("CMAKE_C_FLAGS", "CMAKE_CXX_FLAGS", "CMAKE_EXE_LINKER_FLAGS"); + + for (auto& variable : cmakeVariables) + { + auto configVariable = variable + "_" + cfg.getProductFlavourCMakeIdentifier(); + mo << " set(" << configVariable << " \"${" << configVariable << "} -flto\")" << newLine; + } + + mo << " endif()" << newLine; } - mo << newLine; + first = false; } - if (cfg.isLinkTimeOptimisationEnabled()) + if (! first) { - // There's no MIPS support for LTO - String mipsCondition ("NOT (ANDROID_ABI STREQUAL \"mips\" OR ANDROID_ABI STREQUAL \"mips64\")"); - mo << " if(" << mipsCondition << ")" << newLine; - StringArray cmakeVariables ("CMAKE_C_FLAGS", "CMAKE_CXX_FLAGS", "CMAKE_EXE_LINKER_FLAGS"); + ProjectExporter::BuildConfiguration::Ptr config (getConfiguration(0)); - for (auto& variable : cmakeVariables) + if (config) { - auto configVariable = variable + "_" + cfg.getProductFlavourCMakeIdentifier(); - mo << " SET(" << configVariable << " \"${" << configVariable << "} -flto\")" << newLine; + if (dynamic_cast<const AndroidBuildConfiguration*> (config.get()) != nullptr) + { + mo << "else()" << newLine; + mo << " message( FATAL_ERROR \"No matching build-configuration found.\" )" << newLine; + mo << "endif()" << newLine << newLine; + } } - - mo << " ENDIF(" << mipsCondition << ")" << newLine; } - - first = false; } - if (! first) + Array<build_tools::RelativePath> excludeFromBuild; + Array<std::pair<build_tools::RelativePath, String>> extraCompilerFlags; + + mo << "add_library( ${BINARY_NAME}" << newLine; + mo << newLine; + mo << " " << (getProject().getProjectType().isStaticLibrary() ? "STATIC" : "SHARED") << newLine; + mo << newLine; + addCompileUnits (mo, excludeFromBuild, extraCompilerFlags); + mo << ")" << newLine << newLine; + + if (excludeFromBuild.size() > 0) { - ProjectExporter::BuildConfiguration::Ptr config (getConfiguration(0)); + for (auto& exclude : excludeFromBuild) + mo << "set_source_files_properties(\"" << exclude.toUnixStyle() << "\" PROPERTIES HEADER_FILE_ONLY TRUE)" << newLine; - if (config) - { - if (auto* cfg = dynamic_cast<const AndroidBuildConfiguration*> (config.get())) - { - mo << "ELSE(JUCE_BUILD_CONFIGURATION MATCHES \"" << cfg->getProductFlavourCMakeIdentifier() <<"\")" << newLine; - mo << " MESSAGE( FATAL_ERROR \"No matching build-configuration found.\" )" << newLine; - mo << "ENDIF(JUCE_BUILD_CONFIGURATION MATCHES \"" << cfg->getProductFlavourCMakeIdentifier() <<"\")" << newLine << newLine; - } - } + mo << newLine; } - } - Array<RelativePath> excludeFromBuild; - Array<std::pair<RelativePath, String>> extraCompilerFlags; + if (! extraCompilerFlags.isEmpty()) + { + for (auto& extra : extraCompilerFlags) + mo << "set_source_files_properties(\"" << extra.first.toUnixStyle() << "\" PROPERTIES COMPILE_FLAGS " << extra.second << " )" << newLine; - mo << "add_library( ${BINARY_NAME}" << newLine; - mo << newLine; - mo << " " << (getProject().getProjectType().isStaticLibrary() ? "STATIC" : "SHARED") << newLine; - mo << newLine; - addCompileUnits (mo, excludeFromBuild, extraCompilerFlags); - mo << ")" << newLine << newLine; + mo << newLine; + } - if (excludeFromBuild.size() > 0) - { - for (auto& exclude : excludeFromBuild) - mo << "set_source_files_properties(\"" << exclude.toUnixStyle() << "\" PROPERTIES HEADER_FILE_ONLY TRUE)" << newLine; + auto flags = getProjectCompilerFlags(); - mo << newLine; - } + if (flags.size() > 0) + mo << "target_compile_options( ${BINARY_NAME} PRIVATE " << flags.joinIntoString (" ") << " )" << newLine << newLine; - if (! extraCompilerFlags.isEmpty()) - { - for (auto& extra : extraCompilerFlags) - mo << "set_source_files_properties(\"" << extra.first.toUnixStyle() << "\" PROPERTIES COMPILE_FLAGS " << extra.second << " )" << newLine; + for (ConstConfigIterator config (*this); config.next();) + { + auto& cfg = dynamic_cast<const AndroidBuildConfiguration&> (*config); - mo << newLine; - } + mo << "if( JUCE_BUILD_CONFIGURATION MATCHES \"" << cfg.getProductFlavourCMakeIdentifier() << "\" )" << newLine; + mo << " target_compile_options( ${BINARY_NAME} PRIVATE"; - auto libraries = getAndroidLibraries(); - if (libraries.size() > 0) - { - for (auto& lib : libraries) - mo << "find_library(" << lib.toLowerCase().replaceCharacter (L' ', L'_') << " \"" << lib << "\")" << newLine; + for (auto& flag : cfg.getRecommendedCompilerWarningFlags()) + mo << " " << flag; - mo << newLine; - } + mo << ")" << newLine; + mo << "endif()" << newLine << newLine; + } - libraries.addArray (userLibraries); - mo << "target_link_libraries( ${BINARY_NAME}"; - if (libraries.size() > 0) - { - mo << newLine << newLine; + auto libraries = getAndroidLibraries(); + if (libraries.size() > 0) + { + for (auto& lib : libraries) + mo << "find_library(" << lib.toLowerCase().replaceCharacter (L' ', L'_') << " \"" << lib << "\")" << newLine; - for (auto& lib : libraries) - mo << " ${" << lib.toLowerCase().replaceCharacter (L' ', L'_') << "}" << newLine; + mo << newLine; + } - mo << " \"cpufeatures\"" << newLine; - } + libraries.addArray (userLibraries); + mo << "target_link_libraries( ${BINARY_NAME}"; + if (libraries.size() > 0) + { + mo << newLine << newLine; - if (project.getConfigFlag ("JUCE_USE_ANDROID_OBOE").get()) - mo << " \"oboe\"" << newLine; + for (auto& lib : libraries) + mo << " ${" << lib.toLowerCase().replaceCharacter (L' ', L'_') << "}" << newLine; - mo << ")" << newLine; + mo << " \"cpufeatures\"" << newLine; + } + + if (useOboe) + mo << " \"oboe\"" << newLine; - overwriteFileIfDifferentOrThrow (file, mo); + mo << ")" << newLine; + }); } //============================================================================== String getGradleSettingsFileContent() const { MemoryOutputStream mo; - mo.setNewLineString ("\n"); + mo.setNewLineString (getNewLineString()); mo << "rootProject.name = " << "\'" << projectName << "\'" << newLine; mo << (isLibrary() ? "include ':lib'" : "include ':app'"); @@ -569,7 +596,7 @@ private: String getProjectBuildGradleFileContent() const { MemoryOutputStream mo; - mo.setNewLineString ("\n"); + mo.setNewLineString (getNewLineString()); mo << "buildscript {" << newLine; mo << " repositories {" << newLine; @@ -596,7 +623,7 @@ private: String getAppBuildGradleFileContent (const OwnedArray<LibraryModule>& modules) const { MemoryOutputStream mo; - mo.setNewLineString ("\n"); + mo.setNewLineString (getNewLineString()); mo << "apply plugin: 'com.android." << (isLibrary() ? "library" : "application") << "'" << newLine << newLine; @@ -628,7 +655,7 @@ private: String getAndroidProductFlavours() const { MemoryOutputStream mo; - mo.setNewLineString ("\n"); + mo.setNewLineString (getNewLineString()); mo << " flavorDimensions \"default\"" << newLine; mo << " productFlavors {" << newLine; @@ -658,9 +685,6 @@ private: mo << ", \"-DCMAKE_CXX_FLAGS_" << (cfg.isDebug() ? "DEBUG" : "RELEASE") << "=-O" << cfg.getGCCOptimisationFlag(); - for (auto& flag : cfg.getRecommendedCompilerWarningFlags()) - mo << " " << flag; - mo << "\"" << ", \"-DCMAKE_C_FLAGS_" << (cfg.isDebug() ? "DEBUG" : "RELEASE") << "=-O" << cfg.getGCCOptimisationFlag() @@ -680,7 +704,7 @@ private: String getAndroidSigningConfig() const { MemoryOutputStream mo; - mo.setNewLineString ("\n"); + mo.setNewLineString (getNewLineString()); auto keyStoreFilePath = androidKeyStore.get().toString().replace ("${user.home}", "${System.properties['user.home']}") .replace ("/", "${File.separator}"); @@ -702,13 +726,11 @@ private: { auto bundleIdentifier = project.getBundleIdentifierString().toLowerCase(); auto cmakeDefs = getCmakeDefinitions(); - auto cFlags = getProjectCompilerFlags(); - auto cxxFlags = getProjectCxxCompilerFlags(); auto minSdkVersion = static_cast<int> (androidMinimumSDK.get()); auto targetSdkVersion = static_cast<int> (androidTargetSDK.get()); MemoryOutputStream mo; - mo.setNewLineString ("\n"); + mo.setNewLineString (getNewLineString()); mo << " defaultConfig {" << newLine; @@ -723,12 +745,6 @@ private: mo << " arguments " << cmakeDefs.joinIntoString (", ") << newLine; - if (cFlags.size() > 0) - mo << " cFlags " << cFlags.joinIntoString (", ") << newLine; - - if (cxxFlags.size() > 0) - mo << " cppFlags " << cxxFlags.joinIntoString (", ") << newLine; - mo << " }" << newLine; mo << " }" << newLine; mo << " }" << newLine; @@ -739,7 +755,7 @@ private: String getAndroidBuildTypes() const { MemoryOutputStream mo; - mo.setNewLineString ("\n"); + mo.setNewLineString (getNewLineString()); mo << " buildTypes {" << newLine; @@ -770,7 +786,7 @@ private: String getAndroidVariantFilter() const { MemoryOutputStream mo; - mo.setNewLineString ("\n"); + mo.setNewLineString (getNewLineString()); mo << " variantFilter { variant ->" << newLine; mo << " def names = variant.flavors*.name" << newLine; @@ -793,7 +809,7 @@ private: String getAndroidProjectRepositories() const { MemoryOutputStream mo; - mo.setNewLineString ("\n"); + mo.setNewLineString (getNewLineString()); auto repositories = StringArray::fromLines (androidProjectRepositories.get().toString()); @@ -813,7 +829,7 @@ private: String getAndroidRepositories() const { MemoryOutputStream mo; - mo.setNewLineString ("\n"); + mo.setNewLineString (getNewLineString()); auto repositories = StringArray::fromLines (androidRepositories.get().toString()); @@ -830,7 +846,7 @@ private: String getAndroidDependencies() const { MemoryOutputStream mo; - mo.setNewLineString ("\n"); + mo.setNewLineString (getNewLineString()); mo << " dependencies {" << newLine; @@ -857,7 +873,7 @@ private: String getApplyPlugins() const { MemoryOutputStream mo; - mo.setNewLineString ("\n"); + mo.setNewLineString (getNewLineString()); if (areRemoteNotificationsEnabled()) mo << "apply plugin: 'com.google.gms.google-services'" << newLine; @@ -871,7 +887,7 @@ private: { auto appFolder = getTargetFolder().getChildFile ("app"); - RelativePath relativePath (source, appFolder, RelativePath::buildTargetFolder); + build_tools::RelativePath relativePath (source, appFolder, build_tools::RelativePath::buildTargetFolder); javaSourceSets.add (relativePath.toUnixStyle()); } } @@ -885,7 +901,7 @@ private: if (m->getID() == moduleID) { auto javaFolder = m->getFolder().getChildFile ("native").getChildFile ("javaopt"); - addModuleJavaFolderToSourceSet (javaSourceSets, javaFolder.getChildFile("app")); + addModuleJavaFolderToSourceSet (javaSourceSets, javaFolder.getChildFile ("app")); return; } } @@ -900,13 +916,14 @@ private: { auto javaFolder = module->getFolder().getChildFile ("native").getChildFile ("javacore"); - addModuleJavaFolderToSourceSet (javaSourceSets, javaFolder.getChildFile("init")); + addModuleJavaFolderToSourceSet (javaSourceSets, javaFolder.getChildFile ("init")); if (! isLibrary()) - addModuleJavaFolderToSourceSet (javaSourceSets, javaFolder.getChildFile("app")); + addModuleJavaFolderToSourceSet (javaSourceSets, javaFolder.getChildFile ("app")); } - if (project.getEnabledModules().isModuleEnabled ("juce_gui_basics") && getActivityClassString() == getDefaultActivityClass()) + if (project.getEnabledModules().isModuleEnabled ("juce_gui_basics") + && (getActivityClassString() == getDefaultActivityClass() || isContentSharingEnabled())) addOptJavaFolderToSourceSetsForModule (javaSourceSets, modules, "juce_gui_basics"); if (areRemoteNotificationsEnabled()) @@ -916,12 +933,12 @@ private: addOptJavaFolderToSourceSetsForModule (javaSourceSets, modules, "juce_product_unlocking"); MemoryOutputStream mo; - mo.setNewLineString ("\n"); + mo.setNewLineString (getNewLineString()); mo << " sourceSets {" << newLine; - mo << getSourceSetStringFor ("main.java.srcDirs", javaSourceSets); + mo << getSourceSetStringFor ("main.java.srcDirs", javaSourceSets, getNewLineString()); mo << newLine; - mo << getSourceSetStringFor ("main.res.srcDirs", resourceSets); + mo << getSourceSetStringFor ("main.res.srcDirs", resourceSets, getNewLineString()); mo << " }" << newLine; return mo.toString(); @@ -941,9 +958,9 @@ private: { auto appFolder = getTargetFolder().getChildFile ("app"); - auto relativePath = RelativePath (folder, RelativePath::projectFolder) + auto relativePath = build_tools::RelativePath (folder, build_tools::RelativePath::projectFolder) .rebased (getProject().getProjectFolder(), appFolder, - RelativePath::buildTargetFolder); + build_tools::RelativePath::buildTargetFolder); sourceSets.add (relativePath.toUnixStyle()); } @@ -952,7 +969,7 @@ private: return sourceSets; } - static String getSourceSetStringFor (const String& type, const StringArray& srcDirs) + static String getSourceSetStringFor (const String& type, const StringArray& srcDirs, const String& newLineString) { String s; @@ -972,7 +989,7 @@ private: s << "]" << newLine; - return replaceLineFeeds (s, "\n"); + return replaceLineFeeds (s, newLineString); } //============================================================================== @@ -980,10 +997,9 @@ private: { String props; - props << "ndk.dir=" << sanitisePath (getAppSettings().getStoredPath (Ids::androidNDKPath, TargetOS::getThisOS()).get().toString()) << newLine - << "sdk.dir=" << sanitisePath (getAppSettings().getStoredPath (Ids::androidSDKPath, TargetOS::getThisOS()).get().toString()) << newLine; + props << "sdk.dir=" << sanitisePath (getAppSettings().getStoredPath (Ids::androidSDKPath, TargetOS::getThisOS()).get().toString()) << newLine; - return replaceLineFeeds (props, "\n"); + return replaceLineFeeds (props, getNewLineString()); } String getGradleWrapperPropertiesFileContent() const @@ -1040,13 +1056,13 @@ private: props.add (new TextPropertyComponent (androidCustomActivityClass, "Custom Android Activity", 256, false), "If not empty, specifies the Android Activity class name stored in the app's manifest which " "should be used instead of Android's default Activity. If you specify a custom Activity " - "then you should implement onNewIntent() function like the one in com.roli.juce.JuceActivity, if " + "then you should implement onNewIntent() function like the one in com.rmsl.juce.JuceActivity, if " "you wish to be able to handle push notification events."); props.add (new TextPropertyComponent (androidCustomApplicationClass, "Custom Android Application", 256, false), "If not empty, specifies the Android Application class name stored in the app's manifest which " "should be used instead of JUCE's default JuceApp class. If you specify a custom App then you must " - "call com.roli.juce.Java.initialiseJUCE somewhere in your code before calling any JUCE functions."); + "call com.rmsl.juce.Java.initialiseJUCE somewhere in your code before calling any JUCE functions."); props.add (new TextPropertyComponent (androidVersionCode, "Android Version Code", 32, false), "An integer value that represents the version of the application code, relative to other versions."); @@ -1064,9 +1080,10 @@ private: //============================================================================== void createManifestExporterProperties (PropertyListBuilder& props) { - props.add (new TextPropertyComponent (androidOboeRepositoryPath, "Oboe Repository Path", 2048, false), - "Path to the root of Oboe repository. Make sure to point Oboe repository to " - "commit with SHA c5c3cc17f78974bf005bf33a2de1a093ac55cc07 before building."); + props.add (new TextPropertyComponent (androidOboeRepositoryPath, "Custom Oboe Repository", 2048, false), + "Path to the root of Oboe repository. This path can be absolute, or relative to the build directory. " + "Make sure to point Oboe repository to commit with SHA c5c3cc17f78974bf005bf33a2de1a093ac55cc07 before building. " + "Leave blank to use the version of Oboe distributed with JUCE."); props.add (new ChoicePropertyComponent (androidInternetNeeded, "Internet Access"), "If enabled, this will set the android.permission.INTERNET flag in the manifest."); @@ -1223,6 +1240,8 @@ private: bool isInAppBillingEnabled() const { return androidInAppBillingPermission.get(); } + bool isContentSharingEnabled() const { return androidEnableContentSharing.get(); } + String getJNIActivityClassName() const { return getActivityClassString().replaceCharacter ('.', '/'); @@ -1282,34 +1301,33 @@ private: { createDirectoryOrThrow (file.getParentDirectory()); - PNGImageFormat png; - - MemoryOutputStream mo; - mo.setNewLineString ("\n"); + build_tools::writeStreamToFile (file, [&] (MemoryOutputStream& mo) + { + mo.setNewLineString (getNewLineString()); - if (! png.writeImageToStream (im, mo)) - throw SaveError ("Can't generate Android icon file"); + PNGImageFormat png; - overwriteFileIfDifferentOrThrow (file, mo); + if (! png.writeImageToStream (im, mo)) + throw build_tools::SaveError ("Can't generate Android icon file"); + }); } } void writeIcons (const File& folder) const { - std::unique_ptr<Drawable> bigIcon (getBigIcon()); - std::unique_ptr<Drawable> smallIcon (getSmallIcon()); + const auto icons = getIcons(); - if (bigIcon != nullptr && smallIcon != nullptr) + if (icons.big != nullptr && icons.small != nullptr) { - auto step = jmax (bigIcon->getWidth(), bigIcon->getHeight()) / 8; - writeIcon (folder.getChildFile ("drawable-xhdpi/icon.png"), getBestIconForSize (step * 8, false)); - writeIcon (folder.getChildFile ("drawable-hdpi/icon.png"), getBestIconForSize (step * 6, false)); - writeIcon (folder.getChildFile ("drawable-mdpi/icon.png"), getBestIconForSize (step * 4, false)); - writeIcon (folder.getChildFile ("drawable-ldpi/icon.png"), getBestIconForSize (step * 3, false)); + auto step = jmax (icons.big->getWidth(), icons.big->getHeight()) / 8; + writeIcon (folder.getChildFile ("drawable-xhdpi/icon.png"), build_tools::getBestIconForSize (icons, step * 8, false)); + writeIcon (folder.getChildFile ("drawable-hdpi/icon.png"), build_tools::getBestIconForSize (icons, step * 6, false)); + writeIcon (folder.getChildFile ("drawable-mdpi/icon.png"), build_tools::getBestIconForSize (icons, step * 4, false)); + writeIcon (folder.getChildFile ("drawable-ldpi/icon.png"), build_tools::getBestIconForSize (icons, step * 3, false)); } - else if (auto* icon = (bigIcon != nullptr ? bigIcon.get() : smallIcon.get())) + else if (auto* icon = (icons.big != nullptr ? icons.big.get() : icons.small.get())) { - writeIcon (folder.getChildFile ("drawable-mdpi/icon.png"), rescaleImageForIcon (*icon, icon->getWidth())); + writeIcon (folder.getChildFile ("drawable-mdpi/icon.png"), build_tools::rescaleImageForIcon (*icon, icon->getWidth())); } } @@ -1333,17 +1351,17 @@ private: //============================================================================== void addCompileUnits (const Project::Item& projectItem, MemoryOutputStream& mo, - Array<RelativePath>& excludeFromBuild, Array<std::pair<RelativePath, String>>& extraCompilerFlags) const + Array<build_tools::RelativePath>& excludeFromBuild, Array<std::pair<build_tools::RelativePath, String>>& extraCompilerFlags) const { if (projectItem.isGroup()) { for (int i = 0; i < projectItem.getNumChildren(); ++i) - addCompileUnits (projectItem.getChild(i), mo, excludeFromBuild, extraCompilerFlags); + addCompileUnits (projectItem.getChild (i), mo, excludeFromBuild, extraCompilerFlags); } else if (projectItem.shouldBeAddedToTargetProject() && projectItem.shouldBeAddedToTargetExporter (*this)) { auto f = projectItem.getFile(); - RelativePath file (f, getTargetFolder().getChildFile ("app"), RelativePath::buildTargetFolder); + build_tools::RelativePath file (f, getTargetFolder().getChildFile ("app"), build_tools::RelativePath::buildTargetFolder); auto targetType = getProject().getTargetTypeFromFilePath (f, true); @@ -1351,8 +1369,8 @@ private: if ((! projectItem.shouldBeCompiled()) || (! shouldFileBeCompiledByDefault (f)) || (getProject().isAudioPluginProject() - && targetType != ProjectType::Target::SharedCodeTarget - && targetType != ProjectType::Target::StandalonePlugIn)) + && targetType != build_tools::ProjectType::Target::SharedCodeTarget + && targetType != build_tools::ProjectType::Target::StandalonePlugIn)) { excludeFromBuild.add (file); } @@ -1366,8 +1384,8 @@ private: } } - void addCompileUnits (MemoryOutputStream& mo, Array<RelativePath>& excludeFromBuild, - Array<std::pair<RelativePath, String>>& extraCompilerFlags) const + void addCompileUnits (MemoryOutputStream& mo, Array<build_tools::RelativePath>& excludeFromBuild, + Array<std::pair<build_tools::RelativePath, String>>& extraCompilerFlags) const { for (int i = 0; i < getAllGroups().size(); ++i) addCompileUnits (getAllGroups().getReference(i), mo, excludeFromBuild, extraCompilerFlags); @@ -1388,6 +1406,19 @@ private: cmakeArgs.add ("\"-DANDROID_ARM_MODE=arm\""); cmakeArgs.add ("\"-DANDROID_ARM_NEON=TRUE\""); + auto cppStandard = [this] + { + auto projectStandard = project.getCppStandardString(); + + if (projectStandard == "latest") + return String ("17"); + + return projectStandard; + }(); + + cmakeArgs.add ("\"-DCMAKE_CXX_STANDARD=" + cppStandard + "\""); + cmakeArgs.add ("\"-DCMAKE_CXX_EXTENSIONS=" + String (shouldUseGNUExtensions() ? "ON" : "OFF") + "\""); + return cmakeArgs; } @@ -1400,22 +1431,6 @@ private: return cFlags; } - StringArray getAndroidCxxCompilerFlags() const - { - auto cxxFlags = getAndroidCompilerFlags(); - - auto cppStandard = project.getCppStandardString(); - - if (cppStandard == "latest" || cppStandard == "17") // C++17 flag isn't supported yet so use 1z for now - cppStandard = "1z"; - - cppStandard = "-std=" + String (shouldUseGNUExtensions() ? "gnu++" : "c++") + cppStandard; - - cxxFlags.add (cppStandard.quoted()); - - return cxxFlags; - } - StringArray getProjectCompilerFlags() const { auto cFlags = getAndroidCompilerFlags(); @@ -1423,13 +1438,6 @@ private: return cFlags; } - StringArray getProjectCxxCompilerFlags() const - { - auto cxxFlags = getAndroidCxxCompilerFlags(); - cxxFlags.addArray (getEscapedFlags (StringArray::fromTokens (getExtraCompilerFlagsString(), true))); - return cxxFlags; - } - //============================================================================== StringPairArray getAndroidPreprocessorDefs() const { @@ -1447,13 +1455,16 @@ private: if (isInAppBillingEnabled()) defines.set ("JUCE_IN_APP_PURCHASES", "1"); + if (isContentSharingEnabled()) + defines.set ("JUCE_CONTENT_SHARING", "1"); + if (supportsGLv3()) defines.set ("JUCE_ANDROID_GL_ES_VERSION_3_0", "1"); if (areRemoteNotificationsEnabled()) { - defines.set ("JUCE_FIREBASE_INSTANCE_ID_SERVICE_CLASSNAME", "com_roli_juce_JuceFirebaseInstanceIdService"); - defines.set ("JUCE_FIREBASE_MESSAGING_SERVICE_CLASSNAME", "com_roli_juce_JuceFirebaseMessagingService"); + defines.set ("JUCE_FIREBASE_INSTANCE_ID_SERVICE_CLASSNAME", "com_rmsl_juce_JuceFirebaseInstanceIdService"); + defines.set ("JUCE_FIREBASE_MESSAGING_SERVICE_CLASSNAME", "com_rmsl_juce_JuceFirebaseMessagingService"); } return defines; @@ -1468,7 +1479,7 @@ private: StringPairArray getConfigPreprocessorDefs (const BuildConfiguration& config) const { - auto cfgDefines = config.getUniquePreprocessorDefs(); + auto cfgDefines = getAllPreprocessorDefs (config, build_tools::ProjectType::Target::unspecified); if (config.isDebug()) { @@ -1509,8 +1520,8 @@ private: String escapeDirectoryForCmake (const String& path) const { auto relative = - RelativePath (path, RelativePath::buildTargetFolder) - .rebased (getTargetFolder(), getTargetFolder().getChildFile ("app"), RelativePath::buildTargetFolder); + build_tools::RelativePath (path, build_tools::RelativePath::buildTargetFolder) + .rebased (getTargetFolder(), getTargetFolder().getChildFile ("app"), build_tools::RelativePath::buildTargetFolder); return relative.toUnixStyle(); } @@ -1541,7 +1552,8 @@ private: if (value.isNotEmpty()) { value = value.replace ("\"", "\\\""); - if (value.containsChar (L' ')) + + if (value.containsChar (L' ') && ! value.startsWith ("\\\"") && ! value.endsWith ("\\\"")) value = "\\\"" + value + "\\\""; escaped += ("=" + value); @@ -1612,6 +1624,7 @@ private: screens->setAttribute ("android:normalScreens", "true"); screens->setAttribute ("android:largeScreens", "true"); screens->setAttribute ("android:anyDensity", "true"); + screens->setAttribute ("android:xlargeScreens", "true"); } } } @@ -1758,12 +1771,12 @@ private: if (areRemoteNotificationsEnabled()) { auto* service = application.createNewChildElement ("service"); - service->setAttribute ("android:name", "com.roli.juce.JuceFirebaseMessagingService"); + service->setAttribute ("android:name", "com.rmsl.juce.JuceFirebaseMessagingService"); auto* intentFilter = service->createNewChildElement ("intent-filter"); intentFilter->createNewChildElement ("action")->setAttribute ("android:name", "com.google.firebase.MESSAGING_EVENT"); service = application.createNewChildElement ("service"); - service->setAttribute ("android:name", "com.roli.juce.JuceFirebaseInstanceIdService"); + service->setAttribute ("android:name", "com.rmsl.juce.JuceFirebaseInstanceIdService"); intentFilter = service->createNewChildElement ("intent-filter"); intentFilter->createNewChildElement ("action")->setAttribute ("android:name", "com.google.firebase.INSTANCE_ID_EVENT"); @@ -1775,14 +1788,14 @@ private: void createProviderElement (XmlElement& application) const { - if (androidEnableContentSharing.get()) + if (isContentSharingEnabled()) { auto* provider = application.createNewChildElement ("provider"); - provider->setAttribute ("android:name", "com.roli.juce.JuceSharingContentProvider"); + provider->setAttribute ("android:name", "com.rmsl.juce.JuceSharingContentProvider"); provider->setAttribute ("android:authorities", project.getBundleIdentifierString().toLowerCase() + ".sharingcontentprovider"); provider->setAttribute ("android:grantUriPermissions", "true"); - provider->setAttribute ("android:exported", "false"); + provider->setAttribute ("android:exported", "true"); } } @@ -1822,7 +1835,7 @@ private: { s.add ("android.permission.BLUETOOTH"); s.add ("android.permission.BLUETOOTH_ADMIN"); - s.add ("android.permission.ACCESS_COARSE_LOCATION"); + s.add ("android.permission.ACCESS_FINE_LOCATION"); } if (androidExternalReadPermission.get()) @@ -1867,13 +1880,3 @@ private: JUCE_DECLARE_NON_COPYABLE (AndroidProjectExporter) }; - -inline ProjectExporter* createAndroidExporter (Project& p, const ValueTree& t) -{ - return new AndroidProjectExporter (p, t); -} - -inline ProjectExporter* createAndroidExporterForSetting (Project& p, const ValueTree& t) -{ - return AndroidProjectExporter::createForSettings (p, t); -} diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_CLion.h b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_CLion.h index df743afd..a01fdf78 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_CLion.h +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_CLion.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -54,8 +53,9 @@ protected: public: //============================================================================== - static const char* getName() { return "CLion (beta)"; } - static const char* getValueTreeTypeName() { return "CLION"; } + static String getDisplayName() { return "CLion [Deprecated]"; } + static String getValueTreeTypeName() { return "CLION"; } + static String getTargetFolderName() { return "CLion"; } static CLionProjectExporter* createForSettings (Project& projectToUse, const ValueTree& settingsToUse) { @@ -75,9 +75,8 @@ public: //============================================================================== CLionProjectExporter (Project& p, const ValueTree& t) : ProjectExporter (p, t) { - name = getName(); - - targetLocationValue.setDefault (getDefaultBuildsRootFolder() + getTargetFolderForExporter (getValueTreeTypeName())); + name = getDisplayName(); + targetLocationValue.setDefault (getDefaultBuildsRootFolder() + getTargetFolderName()); } //============================================================================== @@ -98,19 +97,21 @@ public: bool isOSX() const override { return false; } bool isiOS() const override { return false; } - bool supportsTargetType (ProjectType::Target::Type) const override { return true; } + String getNewLineString() const override { return "\n"; } + + bool supportsTargetType (build_tools::ProjectType::Target::Type) const override { return true; } - void addPlatformSpecificSettingsForProjectType (const ProjectType&) override {} + void addPlatformSpecificSettingsForProjectType (const build_tools::ProjectType&) override {} //============================================================================== bool canLaunchProject() override { #if JUCE_MAC - static Identifier exporterName ("XCODE_MAC"); + static Identifier exporterName (XcodeProjectExporter::getValueTreeTypeNameMac()); #elif JUCE_WINDOWS - static Identifier exporterName ("CODEBLOCKS_WINDOWS"); + static Identifier exporterName (CodeBlocksProjectExporter::getValueTreeTypeNameWindows()); #elif JUCE_LINUX - static Identifier exporterName ("LINUX_MAKE"); + static Identifier exporterName (MakefileProjectExporter::getValueTreeTypeName()); #else static Identifier exporterName; #endif @@ -130,19 +131,31 @@ public: { String description; - description << "The " << getName() << " exporter produces a single CMakeLists.txt file with " + description << "*****" << newLine + << newLine + << "This exporter is deprecated." << newLine + << newLine + << "CLion can open any CMake-based projects and JUCE's direct CMake support provides a much more " + << "flexible way of configuring CMake. To get started using JUCE with CMake please see the guide in " + << "the 'docs/CMake API.md' file in the JUCE source code." << newLine + << newLine + << "This exporter will no longer be updated and will eventually be removed from the Projucer." << newLine + << newLine + << "*****" << newLine + << newLine + << "This CLion exporter produces a single CMakeLists.txt file with " << "multiple platform dependent sections, where the configuration for each section " << "is inherited from other exporters added to this project." << newLine << newLine << "The exporters which provide the CLion configuration for the corresponding platform are:" << newLine << newLine; - for (auto& exporterName : getExporterNames()) + for (auto& exporterInfo : getExporterTypeInfos()) { - std::unique_ptr<ProjectExporter> exporter (createNewExporter (getProject(), exporterName)); + std::unique_ptr<ProjectExporter> exporter (createNewExporter (getProject(), exporterInfo.identifier)); if (isExporterSupported (*exporter)) - description << exporter->getName() << newLine; + description << exporterInfo.displayName << newLine; } description << newLine @@ -159,7 +172,7 @@ public: { for (Project::ExporterIterator exporter (getProject()); exporter.next();) if (isExporterSupported (*exporter)) - properties.add (new BooleanPropertyComponent (getExporterEnabledValue (*exporter), "Import settings from exporter", exporter->getName()), + properties.add (new BooleanPropertyComponent (getExporterEnabledValue (*exporter), "Import settings from exporter", exporter->getUniqueName()), "If this is enabled then settings from the corresponding exporter will " "be used in the generated CMakeLists.txt"); } @@ -168,28 +181,27 @@ public: void create (const OwnedArray<LibraryModule>&) const override { - MemoryOutputStream out; - out.setNewLineString ("\n"); - - out << "# Automatically generated CMakeLists, created by the Projucer" << newLine - << "# Do not edit this file! Your changes will be overwritten when you re-save the Projucer project!" << newLine - << newLine; + // We'll append to this later. + build_tools::writeStreamToFile (getTargetFolder().getChildFile ("CMakeLists.txt"), [this] (MemoryOutputStream& mo) + { + mo.setNewLineString (getNewLineString()); - out << "cmake_minimum_required (VERSION 3.4.1)" << newLine - << newLine; + mo << "# Automatically generated CMakeLists, created by the Projucer" << newLine + << "# Do not edit this file! Your changes will be overwritten when you re-save the Projucer project!" << newLine + << newLine; - out << "if (NOT CMAKE_BUILD_TYPE)" << newLine - << " set (CMAKE_BUILD_TYPE \"Debug\" CACHE STRING \"Choose the type of build.\" FORCE)" << newLine - << "endif (NOT CMAKE_BUILD_TYPE)" << newLine - << newLine; + mo << "cmake_minimum_required (VERSION 3.4.1)" << newLine + << newLine; - // We'll append to this later. - overwriteFileIfDifferentOrThrow (getTargetFolder().getChildFile ("CMakeLists.txt"), out); + mo << "if (NOT CMAKE_BUILD_TYPE)" << newLine + << " set (CMAKE_BUILD_TYPE \"Debug\" CACHE STRING \"Choose the type of build.\" FORCE)" << newLine + << "endif (NOT CMAKE_BUILD_TYPE)" << newLine + << newLine; + }); // CMake has stopped adding PkgInfo files to bundles, so we need to do it manually - MemoryOutputStream pkgInfoOut; - pkgInfoOut << "BNDL????"; - overwriteFileIfDifferentOrThrow (getTargetFolder().getChildFile ("PkgInfo"), out); + build_tools::writeStreamToFile (getTargetFolder().getChildFile ("PkgInfo"), + [] (MemoryOutputStream& mo) { mo << "BNDL????"; }); } void writeCMakeListsExporterSection (ProjectExporter* exporter) const @@ -201,10 +213,10 @@ public: getTargetFolder().getChildFile ("CMakeLists.txt").loadFileAsData (existingContent); MemoryOutputStream out (existingContent, true); - out.setNewLineString ("\n"); + out.setNewLineString (getNewLineString()); out << "###############################################################################" << newLine - << "# " << exporter->getName() << newLine + << "# " << exporter->getUniqueName() << newLine << "###############################################################################" << newLine << newLine; @@ -226,7 +238,7 @@ public: out << "endif()" << newLine << newLine; - overwriteFileIfDifferentOrThrow (getTargetFolder().getChildFile ("CMakeLists.txt"), out); + build_tools::overwriteFileIfDifferentOrThrow (getTargetFolder().getChildFile ("CMakeLists.txt"), out); } private: @@ -296,7 +308,7 @@ private: return setCMakeVariable (variableName, "${" + variableName + "} " + value); } - static String getTargetVarName (ProjectType::Target& target) + static String getTargetVarName (build_tools::ProjectType::Target& target) { return String (target.getName()).toUpperCase().replaceCharacter (L' ', L'_'); } @@ -314,9 +326,10 @@ private: else if (projectItem.shouldBeAddedToTargetProject() && projectItem.shouldBeAddedToTargetExporter (*this) && getProject().getTargetTypeFromFilePath (projectItem.getFile(), true) == targetType ) { - auto path = RelativePath (projectItem.getFile(), exporter.getTargetFolder(), RelativePath::buildTargetFolder).toUnixStyle(); + auto path = build_tools::RelativePath (projectItem.getFile(), exporter.getTargetFolder(), build_tools::RelativePath::buildTargetFolder).toUnixStyle(); - fileInfoList.push_back (std::make_tuple (path, projectItem.shouldBeCompiled(), + fileInfoList.push_back (std::make_tuple (path, + projectItem.shouldBeCompiled(), exporter.compilerFlagSchemesMap[projectItem.getCompilerFlagSchemeString()].get().toString())); } } @@ -326,8 +339,8 @@ private: { for (auto* target : exporter.targets) { - if (target->type == ProjectType::Target::Type::AggregateTarget - || target->type == ProjectType::Target::Type::AudioUnitv3PlugIn) + if (target->type == build_tools::ProjectType::Target::Type::AggregateTarget + || target->type == build_tools::ProjectType::Target::Type::AudioUnitv3PlugIn) continue; String functionName; @@ -335,27 +348,31 @@ private: switch (target->getTargetFileType()) { - case ProjectType::Target::TargetFileType::executable: + case build_tools::ProjectType::Target::TargetFileType::executable: functionName = "add_executable"; if (exporter.isCodeBlocks() && exporter.isWindows() - && target->type != ProjectType::Target::Type::ConsoleApp) + && target->type != + build_tools::ProjectType::Target::Type::ConsoleApp) properties.add ("WIN32"); break; - case ProjectType::Target::TargetFileType::staticLibrary: - case ProjectType::Target::TargetFileType::sharedLibraryOrDLL: - case ProjectType::Target::TargetFileType::pluginBundle: + case build_tools::ProjectType::Target::TargetFileType::staticLibrary: + case build_tools::ProjectType::Target::TargetFileType::sharedLibraryOrDLL: + case build_tools::ProjectType::Target::TargetFileType::pluginBundle: functionName = "add_library"; - if (target->getTargetFileType() == ProjectType::Target::TargetFileType::staticLibrary) + if (target->getTargetFileType() == + build_tools::ProjectType::Target::TargetFileType::staticLibrary) properties.add ("STATIC"); - else if (target->getTargetFileType() == ProjectType::Target::TargetFileType::sharedLibraryOrDLL) + else if (target->getTargetFileType() == build_tools::ProjectType::Target::TargetFileType::sharedLibraryOrDLL) properties.add ("SHARED"); else properties.add ("MODULE"); break; + case build_tools::ProjectType::Target::TargetFileType::macOSAppex: + case build_tools::ProjectType::Target::TargetFileType::unknown: default: continue; } @@ -374,15 +391,17 @@ private: for (auto& fileInfo : fileInfoList) out << " " << std::get<0> (fileInfo).quoted() << newLine; - auto isCMakeBundle = exporter.isXcode() && target->getTargetFileType() == ProjectType::Target::TargetFileType::pluginBundle; + auto isCMakeBundle = exporter.isXcode() + && target->getTargetFileType() == build_tools::ProjectType::Target::TargetFileType::pluginBundle; auto pkgInfoPath = String ("PkgInfo").quoted(); if (isCMakeBundle) out << " " << pkgInfoPath << newLine; - auto xcodeIcnsFilePath = [&] () -> String + auto xcodeIcnsFilePath = [&]() -> String { - if (exporter.isXcode() && target->getTargetFileType() == ProjectType::Target::TargetFileType::executable) + if (exporter.isXcode() + && target->getTargetFileType() == build_tools::ProjectType::Target::TargetFileType::executable) { StringArray pathComponents = { "..", "MacOSX", "Icon.icns" }; auto xcodeIcnsFile = getTargetFolder(); @@ -400,7 +419,8 @@ private: if (xcodeIcnsFilePath.isNotEmpty()) out << " " << xcodeIcnsFilePath << newLine; - if (exporter.isCodeBlocks() && target->getTargetFileType() == ProjectType::Target::TargetFileType::executable) + if (exporter.isCodeBlocks() + && target->getTargetFileType() == build_tools::ProjectType::Target::TargetFileType::executable) { StringArray pathComponents = { "..", "CodeBlocksWindows", "resources.rc" }; auto windowsRcFile = getTargetFolder(); @@ -447,13 +467,8 @@ private: out << "find_package (PkgConfig REQUIRED)" << newLine; - StringArray cmakePkgconfigPackages; - - for (auto& package : exporter.getPackages()) - { - cmakePkgconfigPackages.add (package.toUpperCase()); - out << "pkg_search_module (" << cmakePkgconfigPackages.strings.getLast() << " REQUIRED " << package << ")" << newLine; - } + for (auto& package : exporter.getCompilePackages()) + out << "pkg_search_module (" << package.toUpperCase() << " REQUIRED " << package << ")" << newLine; out << newLine; @@ -461,10 +476,10 @@ private: for (auto* target : exporter.targets) { - if (target->type == ProjectType::Target::Type::AggregateTarget) + if (target->type == build_tools::ProjectType::Target::Type::AggregateTarget) continue; - if (target->getTargetFileType() == ProjectType::Target::TargetFileType::pluginBundle) + if (target->getTargetFileType() == build_tools::ProjectType::Target::TargetFileType::pluginBundle) out << "set_target_properties (" << getTargetVarName (*target) << " PROPERTIES PREFIX \"\")" << newLine; out << "set_target_properties (" << getTargetVarName (*target) << " PROPERTIES SUFFIX \"" << target->getTargetFileSuffix() << "\")" << newLine @@ -492,8 +507,8 @@ private: for (auto& path : exporter.getHeaderSearchPaths (config)) out << " " << path.quoted() << newLine; - for (auto& package : cmakePkgconfigPackages) - out << " ${" << package << "_INCLUDE_DIRS}" << newLine; + for (auto& package : exporter.getCompilePackages()) + out << " ${" << package.toUpperCase() << "_INCLUDE_DIRS}" << newLine; out << ")" << newLine << newLine; @@ -514,7 +529,7 @@ private: for (auto* target : exporter.targets) { - if (target->type == ProjectType::Target::Type::AggregateTarget) + if (target->type == build_tools::ProjectType::Target::Type::AggregateTarget) continue; auto targetVarName = getTargetVarName (*target); @@ -558,8 +573,8 @@ private: out << "target_link_libraries (" << targetVarName << " PRIVATE" << newLine; - if (target->getTargetFileType() == ProjectType::Target::TargetFileType::pluginBundle - || target->type == ProjectType::Target::Type::StandalonePlugIn) + if (target->getTargetFileType() == build_tools::ProjectType::Target::TargetFileType::pluginBundle + || target->type == build_tools::ProjectType::Target::Type::StandalonePlugIn) out << " SHARED_CODE" << newLine; out << " " << exporter.getArchFlags (config) << newLine; @@ -573,13 +588,13 @@ private: for (auto& lib : cmakeFoundLibraries) out << " " << lib << newLine; - for (auto& package : cmakePkgconfigPackages) - out << " ${" << package << "_LIBRARIES}" << newLine; + for (auto& package : exporter.getLinkPackages()) + out << " ${" << package.toUpperCase() << "_LIBRARIES}" << newLine; out << ")" << newLine << newLine; - if (target->getTargetFileType() == ProjectType::Target::TargetFileType::pluginBundle - || target->type == ProjectType::Target::Type::StandalonePlugIn) + if (target->getTargetFileType() == build_tools::ProjectType::Target::TargetFileType::pluginBundle + || target->type == build_tools::ProjectType::Target::Type::StandalonePlugIn) out << "add_dependencies (" << targetVarName << " " << "SHARED_CODE)" << newLine << newLine; } @@ -613,7 +628,7 @@ private: for (auto* target : exporter.targets) { - if (target->type == ProjectType::Target::Type::AggregateTarget) + if (target->type == build_tools::ProjectType::Target::Type::AggregateTarget) continue; out << "set_target_properties (" << getTargetVarName (*target) << " PROPERTIES PREFIX \"\")" << newLine @@ -643,7 +658,7 @@ private: for (auto* target : exporter.targets) { - if (target->type == ProjectType::Target::Type::AggregateTarget) + if (target->type == build_tools::ProjectType::Target::Type::AggregateTarget) continue; auto targetVarName = getTargetVarName (*target); @@ -680,8 +695,8 @@ private: out << "target_link_libraries (" << targetVarName << " PRIVATE" << newLine; - if (target->getTargetFileType() == ProjectType::Target::TargetFileType::pluginBundle - || target->type == ProjectType::Target::Type::StandalonePlugIn) + if (target->getTargetFileType() == build_tools::ProjectType::Target::TargetFileType::pluginBundle + || target->type == build_tools::ProjectType::Target::Type::StandalonePlugIn) out << " SHARED_CODE" << newLine << " -L." << newLine; @@ -727,9 +742,9 @@ private: for (auto* target : exporter.targets) { - if (target->getTargetFileType() == ProjectType::Target::TargetFileType::macOSAppex - || target->type == ProjectType::Target::Type::AggregateTarget - || target->type == ProjectType::Target::Type::AudioUnitv3PlugIn) + if (target->getTargetFileType() == build_tools::ProjectType::Target::TargetFileType::macOSAppex + || target->type == build_tools::ProjectType::Target::Type::AggregateTarget + || target->type == build_tools::ProjectType::Target::Type::AudioUnitv3PlugIn) continue; auto targetAttributes = target->getTargetSettings (config); @@ -751,19 +766,19 @@ private: for (auto* target : exporter.targets) { - if (target->getTargetFileType() == ProjectType::Target::TargetFileType::macOSAppex - || target->type == ProjectType::Target::Type::AggregateTarget - || target->type == ProjectType::Target::Type::AudioUnitv3PlugIn) + if (target->getTargetFileType() == build_tools::ProjectType::Target::TargetFileType::macOSAppex + || target->type == build_tools::ProjectType::Target::Type::AggregateTarget + || target->type == build_tools::ProjectType::Target::Type::AudioUnitv3PlugIn) continue; - if (target->type == ProjectType::Target::Type::AudioUnitPlugIn) + if (target->type == build_tools::ProjectType::Target::Type::AudioUnitPlugIn) out << "find_program (RC_COMPILER Rez NO_DEFAULT_PATHS PATHS \"/Applications/Xcode.app/Contents/Developer/usr/bin\")" << newLine << "if (NOT RC_COMPILER)" << newLine << " message (WARNING \"failed to find Rez; older resource-based AU plug-ins may not work correctly\")" << newLine << "endif (NOT RC_COMPILER)" << newLine << newLine; - if (target->getTargetFileType() == ProjectType::Target::TargetFileType::staticLibrary - || target->getTargetFileType() == ProjectType::Target::TargetFileType::sharedLibraryOrDLL) + if (target->getTargetFileType() == build_tools::ProjectType::Target::TargetFileType::staticLibrary + || target->getTargetFileType() == build_tools::ProjectType::Target::TargetFileType::sharedLibraryOrDLL) out << "set_target_properties (" << getTargetVarName (*target) << " PROPERTIES SUFFIX \"" << target->xcodeBundleExtension << "\")" << newLine << newLine; } @@ -794,9 +809,9 @@ private: for (auto* target : exporter.targets) { - if (target->getTargetFileType() == ProjectType::Target::TargetFileType::macOSAppex - || target->type == ProjectType::Target::Type::AggregateTarget - || target->type == ProjectType::Target::Type::AudioUnitv3PlugIn) + if (target->getTargetFileType() == build_tools::ProjectType::Target::TargetFileType::macOSAppex + || target->type == build_tools::ProjectType::Target::Type::AggregateTarget + || target->type == build_tools::ProjectType::Target::Type::AudioUnitv3PlugIn) continue; auto targetVarName = getTargetVarName (*target); @@ -828,7 +843,7 @@ private: if (targetAttributeKeys.contains ("GCC_PREPROCESSOR_DEFINITIONS")) { - defines.addTokens (targetAttributes["GCC_PREPROCESSOR_DEFINITIONS"], "() ,\t", {}); + defines.addTokens (targetAttributes["GCC_PREPROCESSOR_DEFINITIONS"], "(),\t", {}); defines.removeEmptyStrings(); targetAttributeKeys.removeString ("GCC_PREPROCESSOR_DEFINITIONS"); } @@ -836,7 +851,7 @@ private: out << "target_compile_definitions (" << targetVarName << " PRIVATE" << newLine; for (auto& def : defines) - out << " " << def << newLine; + out << " " << def.replace ("\\\\\\\"", "\\\"").replace ("\\\\ ", " ") << newLine; out << ")" << newLine << newLine; @@ -951,7 +966,7 @@ private: targetAttributeKeys.removeString ("OTHER_LDFLAGS"); } - if (target->type == ProjectType::Target::Type::AudioUnitPlugIn) + if (target->type == build_tools::ProjectType::Target::Type::AudioUnitPlugIn) { String rezFlags; @@ -971,7 +986,7 @@ private: auto sdkVersion = config.getOSXSDKVersionString().upToFirstOccurrenceOf (" ", false, false); auto sysroot = "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX" + sdkVersion + ".sdk"; - RelativePath rFile ("JuceLibraryCode/include_juce_audio_plugin_client_AU.r", RelativePath::projectFolder); + build_tools::RelativePath rFile ("JuceLibraryCode/include_juce_audio_plugin_client_AU.r", build_tools::RelativePath::projectFolder); rFile = rebaseFromProjectFolderToBuildTarget (rFile); out << "if (RC_COMPILER)" << newLine @@ -1066,16 +1081,31 @@ private: if (! shouldUseGNUExtensions()) out << " CXX_EXTENSIONS OFF" << newLine; + if (targetAttributeKeys.contains ("MTL_HEADER_SEARCH_PATHS")) + { + auto pathsString = targetAttributes["MTL_HEADER_SEARCH_PATHS"].trim().substring (1).dropLastCharacters (1); + + pathsString = pathsString.replace ("\"$(inherited)\"", {}) + .replace ("$(HOME)", "$ENV{HOME}") + .replace ("~", "$ENV{HOME}"); + + auto paths = StringArray::fromTokens (pathsString, ",\"\t\\", {}); + paths.removeEmptyStrings(); + + out << " XCODE_ATTRIBUTE_MTL_HEADER_SEARCH_PATHS" << " " << paths.joinIntoString (" ").quoted() << newLine; + targetAttributeKeys.removeString ("MTL_HEADER_SEARCH_PATHS"); + } + for (auto& key : targetAttributeKeys) out << " XCODE_ATTRIBUTE_" << key << " " << targetAttributes[key] << newLine; - if (target->getTargetFileType() == ProjectType::Target::TargetFileType::executable - || target->getTargetFileType() == ProjectType::Target::TargetFileType::pluginBundle) + if (target->getTargetFileType() == build_tools::ProjectType::Target::TargetFileType::executable + || target->getTargetFileType() == build_tools::ProjectType::Target::TargetFileType::pluginBundle) { out << " MACOSX_BUNDLE_INFO_PLIST " << targetAttributes.getValue ("INFOPLIST_FILE", "\"\"") << newLine << " XCODE_ATTRIBUTE_PRODUCT_NAME " << binaryName.quoted() << newLine; - if (target->getTargetFileType() == ProjectType::Target::TargetFileType::executable) + if (target->getTargetFileType() == build_tools::ProjectType::Target::TargetFileType::executable) { out << " MACOSX_BUNDLE TRUE" << newLine; } @@ -1091,8 +1121,8 @@ private: out << "target_link_libraries (" << targetVarName << " PRIVATE" << newLine; - if (target->getTargetFileType() == ProjectType::Target::TargetFileType::pluginBundle - || target->type == ProjectType::Target::Type::StandalonePlugIn) + if (target->getTargetFileType() == build_tools::ProjectType::Target::TargetFileType::pluginBundle + || target->type == build_tools::ProjectType::Target::Type::StandalonePlugIn) out << " SHARED_CODE" << newLine; for (auto& path : libSearchPaths) @@ -1106,10 +1136,10 @@ private: out << ")" << newLine << newLine; - if (target->getTargetFileType() == ProjectType::Target::TargetFileType::pluginBundle - || target->type == ProjectType::Target::Type::StandalonePlugIn) + if (target->getTargetFileType() == build_tools::ProjectType::Target::TargetFileType::pluginBundle + || target->type == build_tools::ProjectType::Target::Type::StandalonePlugIn) { - if (target->getTargetFileType() == ProjectType::Target::TargetFileType::pluginBundle + if (target->getTargetFileType() == build_tools::ProjectType::Target::TargetFileType::pluginBundle && targetAttributeKeys.contains("INSTALL_PATH")) { auto installPath = targetAttributes["INSTALL_PATH"].unquoted().replace ("$(HOME)", "$ENV{HOME}"); diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_CodeBlocks.h b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_CodeBlocks.h index c43928e6..c6af8a08 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_CodeBlocks.h +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_CodeBlocks.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -39,39 +38,24 @@ public: }; //============================================================================== - static const char* getNameWindows() noexcept { return "Code::Blocks (Windows)"; } - static const char* getNameLinux() noexcept { return "Code::Blocks (Linux)"; } + static String getDisplayNameWindows() { return "Code::Blocks (Windows)"; } + static String getDisplayNameLinux() { return "Code::Blocks (Linux)"; } - static const char* getName (CodeBlocksOS os) noexcept - { - if (os == windowsTarget) return getNameWindows(); - if (os == linuxTarget) return getNameLinux(); + static String getValueTreeTypeNameWindows() { return "CODEBLOCKS_WINDOWS"; } + static String getValueTreeTypeNameLinux() { return "CODEBLOCKS_LINUX"; } - // currently no other OSes supported by Codeblocks exporter! - jassertfalse; - return "Code::Blocks (Unknown OS)"; - } - - //============================================================================== - static const char* getValueTreeTypeName (CodeBlocksOS os) - { - if (os == windowsTarget) return "CODEBLOCKS_WINDOWS"; - if (os == linuxTarget) return "CODEBLOCKS_LINUX"; - - // currently no other OSes supported by Codeblocks exporter! - jassertfalse; - return "CODEBLOCKS_UNKNOWN_OS"; - } + static String getTargetFolderNameWindows() { return "CodeBlocksWindows"; } + static String getTargetFolderNameLinux() { return "CodeBlocksLinux"; } //============================================================================== static CodeBlocksProjectExporter* createForSettings (Project& projectToUse, const ValueTree& settingsToUse) { // this will also import legacy jucer files where CodeBlocks only worked for Windows, // had valueTreetTypeName "CODEBLOCKS", and there was no OS distinction - if (settingsToUse.hasType (getValueTreeTypeName (windowsTarget)) || settingsToUse.hasType ("CODEBLOCKS")) + if (settingsToUse.hasType (getValueTreeTypeNameWindows()) || settingsToUse.hasType ("CODEBLOCKS")) return new CodeBlocksProjectExporter (projectToUse, settingsToUse, windowsTarget); - if (settingsToUse.hasType (getValueTreeTypeName (linuxTarget))) + if (settingsToUse.hasType (getValueTreeTypeNameLinux())) return new CodeBlocksProjectExporter (projectToUse, settingsToUse, linuxTarget); return nullptr; @@ -81,12 +65,17 @@ public: CodeBlocksProjectExporter (Project& p, const ValueTree& t, CodeBlocksOS codeBlocksOs) : ProjectExporter (p, t), os (codeBlocksOs) { - name = getName (os); - - targetLocationValue.setDefault (getDefaultBuildsRootFolder() + getTargetFolderForExporter (getValueTreeTypeName (os))); - if (isWindows()) + { + name = getDisplayNameWindows(); + targetLocationValue.setDefault (getDefaultBuildsRootFolder() + getTargetFolderNameWindows()); targetPlatformValue.referTo (settings, Ids::codeBlocksWindowsTarget, getUndoManager()); + } + else + { + name = getDisplayNameLinux(); + targetLocationValue.setDefault (getDefaultBuildsRootFolder() + getTargetFolderNameLinux()); + } } //============================================================================== @@ -109,19 +98,28 @@ public: bool isOSX() const override { return false; } bool isiOS() const override { return false; } - bool supportsTargetType (ProjectType::Target::Type type) const override + String getNewLineString() const override { return isWindows() ? "\r\n" : "\n"; } + + bool supportsTargetType (build_tools::ProjectType::Target::Type type) const override { switch (type) { - case ProjectType::Target::StandalonePlugIn: - case ProjectType::Target::GUIApp: - case ProjectType::Target::ConsoleApp: - case ProjectType::Target::StaticLibrary: - case ProjectType::Target::SharedCodeTarget: - case ProjectType::Target::AggregateTarget: - case ProjectType::Target::VSTPlugIn: - case ProjectType::Target::DynamicLibrary: + case build_tools::ProjectType::Target::StandalonePlugIn: + case build_tools::ProjectType::Target::GUIApp: + case build_tools::ProjectType::Target::ConsoleApp: + case build_tools::ProjectType::Target::StaticLibrary: + case build_tools::ProjectType::Target::SharedCodeTarget: + case build_tools::ProjectType::Target::AggregateTarget: + case build_tools::ProjectType::Target::VSTPlugIn: + case build_tools::ProjectType::Target::DynamicLibrary: return true; + case build_tools::ProjectType::Target::AAXPlugIn: + case build_tools::ProjectType::Target::RTASPlugIn: + case build_tools::ProjectType::Target::UnityPlugIn: + case build_tools::ProjectType::Target::VST3PlugIn: + case build_tools::ProjectType::Target::AudioUnitPlugIn: + case build_tools::ProjectType::Target::AudioUnitv3PlugIn: + case build_tools::ProjectType::Target::unspecified: default: break; } @@ -155,25 +153,20 @@ public: } //============================================================================== - void addPlatformSpecificSettingsForProjectType (const ProjectType&) override + void addPlatformSpecificSettingsForProjectType (const build_tools::ProjectType&) override { // add shared code target first as order matters for Codeblocks - if (shouldBuildTargetType (ProjectType::Target::SharedCodeTarget)) - targets.add (new CodeBlocksTarget (*this, ProjectType::Target::SharedCodeTarget)); + if (shouldBuildTargetType (build_tools::ProjectType::Target::SharedCodeTarget)) + targets.add (new CodeBlocksTarget (*this, build_tools::ProjectType::Target::SharedCodeTarget)); - //ProjectType::Target::SharedCodeTarget - callForAllSupportedTargets ([this] (ProjectType::Target::Type targetType) + //resource::ProjectType::Target::SharedCodeTarget + callForAllSupportedTargets ([this] (build_tools::ProjectType::Target::Type targetType) { - if (targetType == ProjectType::Target::SharedCodeTarget) + if (targetType == build_tools::ProjectType::Target::SharedCodeTarget) return; - if (auto* target = new CodeBlocksTarget (*this, targetType)) - { - if (targetType == ProjectType::Target::AggregateTarget) - targets.insert (0, target); - else - targets.add (target); - } + targets.insert (targetType == build_tools::ProjectType::Target::AggregateTarget ? 0 : -1, + new CodeBlocksTarget (*this, targetType)); }); // If you hit this assert, you tried to generate a project for an exporter @@ -246,17 +239,18 @@ private: } //============================================================================== - class CodeBlocksTarget : public ProjectType::Target + class CodeBlocksTarget : public build_tools::ProjectType::Target { public: - CodeBlocksTarget (const CodeBlocksProjectExporter& e, ProjectType::Target::Type typeToUse) - : ProjectType::Target (typeToUse), + CodeBlocksTarget (const CodeBlocksProjectExporter& e, + build_tools::ProjectType::Target::Type typeToUse) + : Target (typeToUse), exporter (e) {} String getTargetNameForConfiguration (const BuildConfiguration& config) const { - if (type == ProjectType::Target::AggregateTarget) + if (type == build_tools::ProjectType::Target::AggregateTarget) return config.getName(); return getName() + String (" | ") + config.getName(); @@ -274,6 +268,8 @@ private: case staticLibrary: return ".lib"; case sharedLibraryOrDLL: case pluginBundle: return ".dll"; + case macOSAppex: + case unknown: default: break; } @@ -284,17 +280,10 @@ private: { case executable: return {}; case staticLibrary: return ".a"; - case sharedLibraryOrDLL: return ".so"; - case pluginBundle: - switch (type) - { - case VSTPlugIn: return ".so"; - default: break; - } - - return ".so"; - + case sharedLibraryOrDLL: return ".so"; + case macOSAppex: + case unknown: default: break; } @@ -312,28 +301,6 @@ private: }; //============================================================================== - - StringArray getPackages() const - { - auto result = linuxPackages; - - if (project.getEnabledModules().isModuleEnabled ("juce_gui_extra") - && project.isConfigFlagEnabled ("JUCE_WEB_BROWSER", true)) - { - result.add ("webkit2gtk-4.0"); - result.add ("gtk+-x11-3.0"); - } - - if (project.getEnabledModules().isModuleEnabled ("juce_core") - && project.isConfigFlagEnabled ("JUCE_USE_CURL", true) - && ! project.isConfigFlagEnabled ("JUCE_LOAD_CURL_SYMBOLS_LAZILY", false)) - result.add ("libcurl"); - - result.removeDuplicates (false); - - return result; - } - void addVersion (XmlElement& xml) const { auto* fileVersion = xml.createNewChildElement ("FileVersion"); @@ -435,19 +402,20 @@ private: if (target.isDynamicLibrary() || getProject().isAudioPluginProject()) flags.add ("-fPIC"); - auto packages = getPackages(); + auto packages = config.exporter.getLinuxPackages (PackageDependencyType::compile); - if (packages.size() > 0) + if (! packages.isEmpty()) { auto pkgconfigFlags = String ("`pkg-config --cflags"); - for (auto p : packages) + + for (auto& p : packages) pkgconfigFlags << " " << p; pkgconfigFlags << "`"; flags.add (pkgconfigFlags); } - if (linuxLibs.contains("pthread")) + if (linuxLibs.contains ("pthread")) flags.add ("-pthread"); } @@ -469,14 +437,14 @@ private: flags.addTokens (replacePreprocessorTokens (config, getExtraLinkerFlagsString()).trim(), " \n", "\"'"); - auto packages = getPackages(); - if (config.exporter.isLinux()) { if (target.isDynamicLibrary()) flags.add ("-shared"); - if (packages.size() > 0) + auto packages = config.exporter.getLinuxPackages (PackageDependencyType::link); + + if (! packages.isEmpty()) { String pkgconfigLibs ("`pkg-config --libs"); @@ -495,8 +463,8 @@ private: { auto librarySearchPaths = config.getLibrarySearchPaths(); - if (getProject().isAudioPluginProject() && target.type != ProjectType::Target::SharedCodeTarget) - librarySearchPaths.add (RelativePath (getSharedCodePath (config), RelativePath::buildTargetFolder).getParentDirectory().toUnixStyle().quoted()); + if (getProject().isAudioPluginProject() && target.type != build_tools::ProjectType::Target::SharedCodeTarget) + librarySearchPaths.add (build_tools::RelativePath (getSharedCodePath (config), build_tools::RelativePath::buildTargetFolder).getParentDirectory().toUnixStyle().quoted()); return librarySearchPaths; } @@ -521,24 +489,12 @@ private: return getCleanedStringArray (paths); } - static int getTypeIndex (const ProjectType::Target::Type& type) + static int getTypeIndex (const build_tools::ProjectType::Target::Type& type) { - switch (type) - { - case ProjectType::Target::GUIApp: - case ProjectType::Target::StandalonePlugIn: - return 0; - case ProjectType::Target::ConsoleApp: - return 1; - case ProjectType::Target::StaticLibrary: - case ProjectType::Target::SharedCodeTarget: - return 2; - case ProjectType::Target::DynamicLibrary: - case ProjectType::Target::VSTPlugIn: - return 3; - default: - break; - } + if (type == build_tools::ProjectType::Target::GUIApp || type == build_tools::ProjectType::Target::StandalonePlugIn) return 0; + if (type == build_tools::ProjectType::Target::ConsoleApp) return 1; + if (type == build_tools::ProjectType::Target::StaticLibrary || type == build_tools::ProjectType::Target::SharedCodeTarget) return 2; + if (type == build_tools::ProjectType::Target::DynamicLibrary || type == build_tools::ProjectType::Target::VSTPlugIn) return 3; return 0; } @@ -548,8 +504,8 @@ private: String outputPath; if (config.getTargetBinaryRelativePathString().isNotEmpty()) { - RelativePath binaryPath (config.getTargetBinaryRelativePathString(), RelativePath::projectFolder); - binaryPath = binaryPath.rebased (projectFolder, getTargetFolder(), RelativePath::buildTargetFolder); + build_tools::RelativePath binaryPath (config.getTargetBinaryRelativePathString(), build_tools::RelativePath::projectFolder); + binaryPath = binaryPath.rebased (projectFolder, getTargetFolder(), build_tools::RelativePath::buildTargetFolder); outputPath = config.getTargetBinaryRelativePathString(); } else @@ -562,8 +518,8 @@ private: String getSharedCodePath (const BuildConfiguration& config) const { - auto outputPath = getOutputPathForTarget (getTargetWithType (ProjectType::Target::SharedCodeTarget), config); - RelativePath path (outputPath, RelativePath::buildTargetFolder); + auto outputPath = getOutputPathForTarget (getTargetWithType (build_tools::ProjectType::Target::SharedCodeTarget), config); + build_tools::RelativePath path (outputPath, build_tools::RelativePath::buildTargetFolder); auto filename = path.getFileName(); if (isLinux()) @@ -583,7 +539,7 @@ private: if (isLinux()) { - bool keepPrefix = (target.type == ProjectType::Target::VSTPlugIn); + bool keepPrefix = (target.type == build_tools::ProjectType::Target::VSTPlugIn); output->setAttribute ("prefix_auto", keepPrefix ? 0 : 1); } @@ -601,7 +557,7 @@ private: xml.createNewChildElement ("Option")->setAttribute ("type", getTypeIndex (target.type)); xml.createNewChildElement ("Option")->setAttribute ("compiler", "gcc"); - if (getProject().isAudioPluginProject() && target.type != ProjectType::Target::SharedCodeTarget) + if (getProject().isAudioPluginProject() && target.type != build_tools::ProjectType::Target::SharedCodeTarget) xml.createNewChildElement ("Option")->setAttribute ("external_deps", getSharedCodePath (config)); { @@ -635,7 +591,7 @@ private: { auto* linker = xml.createNewChildElement ("Linker"); - if (getProject().isAudioPluginProject() && target.type != ProjectType::Target::SharedCodeTarget) + if (getProject().isAudioPluginProject() && target.type != build_tools::ProjectType::Target::SharedCodeTarget) setAddOption (*linker, "option", getSharedCodePath (config).quoted()); for (auto& flag : getLinkerFlags (config, target)) @@ -647,7 +603,8 @@ private: setAddOption (*linker, "library", lib); for (auto& path : getLinkerSearchPaths (config, target)) - setAddOption (*linker, "directory", replacePreprocessorDefs (getAllPreprocessorDefs(), path)); + setAddOption (*linker, "directory", + build_tools::replacePreprocessorDefs (getAllPreprocessorDefs(), path)); } } @@ -657,7 +614,7 @@ private: for (ConstConfigIterator config (*this); config.next();) for (auto target : targets) - if (target->type != ProjectType::Target::AggregateTarget) + if (target->type != build_tools::ProjectType::Target::AggregateTarget) createBuildTarget (*build->createNewChildElement ("Target"), *target, *config); } @@ -670,12 +627,12 @@ private: StringArray allTargets; for (auto target : targets) - if (target->type != ProjectType::Target::AggregateTarget) + if (target->type != build_tools::ProjectType::Target::AggregateTarget) allTargets.add (target->getTargetNameForConfiguration (*config)); for (auto target : targets) { - if (target->type == ProjectType::Target::AggregateTarget) + if (target->type == build_tools::ProjectType::Target::AggregateTarget) { auto* configTarget = virtualTargets->createNewChildElement ("Add"); @@ -711,7 +668,7 @@ private: result = getCleanedStringArray (result); for (auto& option : result) - option = replacePreprocessorDefs (getAllPreprocessorDefs(), option); + option = build_tools::replacePreprocessorDefs (getAllPreprocessorDefs(), option); return result; } @@ -724,7 +681,7 @@ private: setAddOption (*linker, "library", lib); } - CodeBlocksTarget& getTargetWithType (ProjectType::Target::Type type) const + CodeBlocksTarget& getTargetWithType (build_tools::ProjectType::Target::Type type) const { CodeBlocksTarget* nonAggregrateTarget = nullptr; @@ -733,7 +690,7 @@ private: if (target->type == type) return *target; - if (target->type != ProjectType::Target::AggregateTarget) + if (target->type != build_tools::ProjectType::Target::AggregateTarget) nonAggregrateTarget = target; } @@ -748,10 +705,10 @@ private: CodeBlocksTarget& getMainTarget() const { if (getProject().isAudioPluginProject()) - return getTargetWithType (ProjectType::Target::SharedCodeTarget); + return getTargetWithType (build_tools::ProjectType::Target::SharedCodeTarget); for (auto* target : targets) - if (target->type != ProjectType::Target::AggregateTarget) + if (target->type != build_tools::ProjectType::Target::AggregateTarget) return *target; jassertfalse; @@ -764,7 +721,7 @@ private: if (getProject().isAudioPluginProject()) { if (! projectItem.shouldBeCompiled()) - return getTargetWithType (ProjectType::Target::SharedCodeTarget); + return getTargetWithType (build_tools::ProjectType::Target::SharedCodeTarget); return getTargetWithType (getProject().getTargetTypeFromFilePath (projectItem.getFile(), true)); } @@ -781,7 +738,7 @@ private: } else if (projectItem.shouldBeAddedToTargetProject() && projectItem.shouldBeAddedToTargetExporter (*this)) { - RelativePath file (projectItem.getFile(), getTargetFolder(), RelativePath::buildTargetFolder); + build_tools::RelativePath file (projectItem.getFile(), getTargetFolder(), build_tools::RelativePath::buildTargetFolder); auto* unit = xml.createNewChildElement ("Unit"); unit->setAttribute ("filename", file.toUnixStyle()); @@ -825,8 +782,11 @@ private: if (hasResourceFile()) { - auto iconFile = getTargetFolder().getChildFile ("icon.ico"); - MSVCProjectExporterBase::writeIconFile (*this, iconFile); + const auto iconFile = getTargetFolder().getChildFile ("icon.ico"); + + if (! build_tools::asArray (getIcons()).isEmpty()) + build_tools::writeWinIcon (getIcons(), iconFile); + auto rcFile = getTargetFolder().getChildFile ("resources.rc"); MSVCProjectExporterBase::createRCFile (project, iconFile, rcFile); diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_MSVC.h b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_MSVC.h index bf46cb1f..b22f3366 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_MSVC.h +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_MSVC.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -39,8 +38,6 @@ public: manifestFileValue (settings, Ids::msvcManifestFile, getUndoManager()) { targetLocationValue.setDefault (getDefaultBuildsRootFolder() + folderName); - - updateOldSettings(); } virtual int getVisualStudioVersion() const = 0; @@ -63,49 +60,62 @@ public: "Specifies the version of the platform toolset that will be used when building this project."); } - void addIPPLibraryProperty (PropertyListBuilder& props) - { - props.add (new ChoicePropertyComponent (IPPLibraryValue, "Use IPP Library", - { "No", "Yes (Default Linking)", "Multi-Threaded Static Library", "Single-Threaded Static Library", "Multi-Threaded DLL", "Single-Threaded DLL" }, - { var(), "true", "Parallel_Static", "Sequential", "Parallel_Dynamic", "Sequential_Dynamic" }), - "Enable this to use Intel's Integrated Performance Primitives library."); - } - - void addWindowsTargetPlatformProperties (PropertyListBuilder& props) - { - auto isWindows10SDK = getVisualStudioVersion() > 14; - - props.add (new TextPropertyComponent (targetPlatformVersion, "Windows Target Platform", 20, false), - String ("Specifies the version of the Windows SDK that will be used when building this project. ") - + (isWindows10SDK ? "Leave this field empty to use the latest Windows 10 SDK installed on the build machine." - : "The default value for this exporter is " + getDefaultWindowsTargetPlatformVersion())); - } - void create (const OwnedArray<LibraryModule>&) const override { createResourcesAndIcon(); + createPackagesConfigFile(); for (int i = 0; i < targets.size(); ++i) if (auto* target = targets[i]) target->writeProjectFile(); + build_tools::writeStreamToFile (getSLNFile(), [&] (MemoryOutputStream& mo) { - MemoryOutputStream mo; writeSolutionFile (mo, "11.00", getSolutionComment()); + }); + } + + //============================================================================== + void updateDeprecatedSettings() override + { + { + auto oldStylePrebuildCommand = getSettingString (Ids::prebuildCommand); + settings.removeProperty (Ids::prebuildCommand, nullptr); + + if (oldStylePrebuildCommand.isNotEmpty()) + for (ConfigIterator config (*this); config.next();) + dynamic_cast<MSVCBuildConfiguration&> (*config).getValue (Ids::prebuildCommand) = oldStylePrebuildCommand; + } + + { + auto oldStyleLibName = getSettingString ("libraryName_Debug"); + settings.removeProperty ("libraryName_Debug", nullptr); + + if (oldStyleLibName.isNotEmpty()) + for (ConfigIterator config (*this); config.next();) + if (config->isDebug()) + config->getValue (Ids::targetName) = oldStyleLibName; + } + + { + auto oldStyleLibName = getSettingString ("libraryName_Release"); + settings.removeProperty ("libraryName_Release", nullptr); - overwriteFileIfDifferentOrThrow (getSLNFile(), mo); + if (oldStyleLibName.isNotEmpty()) + for (ConfigIterator config (*this); config.next();) + if (! config->isDebug()) + config->getValue (Ids::targetName) = oldStyleLibName; } + + for (ConfigIterator i (*this); i.next();) + dynamic_cast<MSVCBuildConfiguration&> (*i).updateOldLTOSetting(); } - //============================================================================== void initialiseDependencyPathValues() override { vstLegacyPathValueWrapper.init ({ settings, Ids::vstLegacyFolder, nullptr }, getAppSettings().getStoredPath (Ids::vstLegacyPath, TargetOS::windows), TargetOS::windows); - vst3PathValueWrapper.init ({ settings, Ids::vst3Folder, nullptr }, - getAppSettings().getStoredPath (Ids::vst3Path, TargetOS::windows), TargetOS::windows); - aaxPathValueWrapper.init ({ settings, Ids::aaxFolder, nullptr }, getAppSettings().getStoredPath (Ids::aaxPath, TargetOS::windows), TargetOS::windows); @@ -141,9 +151,6 @@ public: aaxBinaryLocation (config, Ids::aaxBinaryLocation, getUndoManager()), unityPluginBinaryLocation (config, Ids::unityPluginBinaryLocation, getUndoManager(), {}) { - if (! isDebug()) - updateOldLTOSetting(); - setPluginBinaryCopyLocationDefaults(); optimisationLevelValue.setDefault (isDebug() ? optimisationOff : optimiseFull); @@ -284,6 +291,12 @@ public: return result; } + void updateOldLTOSetting() + { + if (! isDebug() && config.getPropertyAsValue ("wholeProgramOptimisation", nullptr) != Value()) + linkTimeOptimisationValue = (static_cast<int> (config ["wholeProgramOptimisation"]) == 0); + } + private: ValueWithDefault warningLevelValue, warningsAreErrorsValue, prebuildCommandValue, postbuildCommandValue, generateDebugSymbolsValue, generateManifestValue, enableIncrementalLinkingValue, useRuntimeLibDLLValue, multiProcessorCompilationValue, @@ -295,15 +308,9 @@ public: Value architectureValueToListenTo; //============================================================================== - void updateOldLTOSetting() - { - if (config.getPropertyAsValue ("wholeProgramOptimisation", nullptr) != Value()) - linkTimeOptimisationValue = (static_cast<int> (config ["wholeProgramOptimisation"]) == 0); - } - void addVisualStudioPluginInstallPathProperties (PropertyListBuilder& props) { - auto isBuildingAnyPlugins = (project.shouldBuildVST() || project.shouldBuildVST3() || project.shouldBuildRTAS() + auto isBuildingAnyPlugins = (project.shouldBuildVST() || project.shouldBuildVST3() || project.shouldBuildRTAS() || project.shouldBuildAAX() || project.shouldBuildUnityPlugin()); if (isBuildingAnyPlugins) @@ -356,11 +363,11 @@ public: }; //============================================================================== - class MSVCTargetBase : public ProjectType::Target + class MSVCTargetBase : public build_tools::ProjectType::Target { public: - MSVCTargetBase (ProjectType::Target::Type targetType, const MSVCProjectExporterBase& exporter) - : ProjectType::Target (targetType), owner (exporter) + MSVCTargetBase (build_tools::ProjectType::Target::Type targetType, const MSVCProjectExporterBase& exporter) + : build_tools::ProjectType::Target (targetType), owner (exporter) { projectGuid = createGUID (owner.getProject().getProjectUIDString() + getName()); } @@ -467,18 +474,18 @@ public: { auto* outdir = props->createNewChildElement ("OutDir"); setConditionAttribute (*outdir, config); - outdir->addTextElement (FileHelpers::windowsStylePath (getConfigTargetPath (config)) + "\\"); + outdir->addTextElement (build_tools::windowsStylePath (getConfigTargetPath (config)) + "\\"); } { - auto* intdir = props->createNewChildElement("IntDir"); + auto* intdir = props->createNewChildElement ("IntDir"); setConditionAttribute (*intdir, config); auto intermediatesPath = getIntermediatesPath (config); if (! intermediatesPath.endsWithChar (L'\\')) intermediatesPath += L'\\'; - intdir->addTextElement (FileHelpers::windowsStylePath (intermediatesPath)); + intdir->addTextElement (build_tools::windowsStylePath (intermediatesPath)); } @@ -549,7 +556,7 @@ public: cl->createNewChildElement ("RuntimeLibrary")->addTextElement (config.isUsingRuntimeLibDLL() ? (isDebug ? "MultiThreadedDebugDLL" : "MultiThreadedDLL") : (isDebug ? "MultiThreadedDebug" : "MultiThreaded")); cl->createNewChildElement ("RuntimeTypeInfo")->addTextElement ("true"); - cl->createNewChildElement ("PrecompiledHeader"); + cl->createNewChildElement ("PrecompiledHeader")->addTextElement ("NotUsing"); cl->createNewChildElement ("AssemblerListingLocation")->addTextElement ("$(IntDir)\\"); cl->createNewChildElement ("ObjectFileName")->addTextElement ("$(IntDir)\\"); cl->createNewChildElement ("ProgramDataBaseFileName")->addTextElement ("$(IntDir)\\"); @@ -618,6 +625,9 @@ public: link->createNewChildElement ("LargeAddressAware")->addTextElement ("true"); + if (config.isLinkTimeOptimisationEnabled()) + link->createNewChildElement ("LinkTimeCodeGeneration")->addTextElement ("UseLinkTimeCodeGeneration"); + if (additionalDependencies.isNotEmpty()) link->createNewChildElement ("AdditionalDependencies")->addTextElement (additionalDependencies); @@ -654,13 +664,13 @@ public: } auto manifestFile = getOwner().getManifestPath(); - if (manifestFile.getRoot() != RelativePath::unknown) + if (manifestFile.getRoot() != build_tools::RelativePath::unknown) { auto* bsc = group->createNewChildElement ("Manifest"); bsc->createNewChildElement ("AdditionalManifestFiles") ->addTextElement (manifestFile.rebased (getOwner().getProject().getFile().getParentDirectory(), getOwner().getTargetFolder(), - RelativePath::buildTargetFolder).toWindowsStyle()); + build_tools::RelativePath::buildTargetFolder).toWindowsStyle()); } if (getTargetFileType() == staticLibrary && ! config.is64Bit()) @@ -688,6 +698,8 @@ public: auto* cppFiles = projectXml.createNewChildElement ("ItemGroup"); auto* headerFiles = projectXml.createNewChildElement ("ItemGroup"); + writePrecompiledHeaderFiles (*cppFiles); + for (int i = 0; i < getOwner().getAllGroups().size(); ++i) { auto& group = getOwner().getAllGroups().getReference (i); @@ -703,6 +715,12 @@ public: e->setAttribute ("Include", prependDot (getOwner().iconFile.getFileName())); } + if (getOwner().packagesConfigFile.existsAsFile()) + { + auto* e = otherFilesGroup->createNewChildElement ("None"); + e->setAttribute ("Include", getOwner().packagesConfigFile.getFileName()); + } + if (otherFilesGroup->getFirstChildElement() != nullptr) projectXml.addChildElement (otherFilesGroup.release()); @@ -719,27 +737,85 @@ public: } { - auto* e = projectXml.createNewChildElement ("ImportGroup"); - e->setAttribute ("Label", "ExtensionTargets"); + auto* importGroup = projectXml.createNewChildElement ("ImportGroup"); + importGroup->setAttribute ("Label", "ExtensionTargets"); + + if (owner.shouldAddWebView2Package()) + { + auto packageTargetsPath = "packages\\" + getWebView2PackageName() + "." + getWebView2PackageVersion() + + "\\build\\native\\" + getWebView2PackageName() + ".targets"; + + auto* e = importGroup->createNewChildElement ("Import"); + e->setAttribute ("Project", packageTargetsPath); + e->setAttribute ("Condition", "Exists('" + packageTargetsPath + "')"); + } } } String getProjectType() const { - switch (getTargetFileType()) - { - case executable: - return "Application"; - case staticLibrary: - return "StaticLibrary"; - default: - break; - } + auto targetFileType = getTargetFileType(); + + if (targetFileType == executable) return "Application"; + if (targetFileType == staticLibrary) return "StaticLibrary"; return "DynamicLibrary"; } //============================================================================== + static void setSourceFilePCHSettings (XmlElement& element, const File& pchFile, const String& option, const BuildConfiguration& config) + { + auto setConfigConditionAttribute = [&config] (XmlElement* elementToSet) -> XmlElement* + { + setConditionAttribute (*elementToSet, config); + return elementToSet; + }; + + setConfigConditionAttribute (element.createNewChildElement ("PrecompiledHeader"))->addTextElement (option); + setConfigConditionAttribute (element.createNewChildElement ("PrecompiledHeaderFile"))->addTextElement (pchFile.getFileName()); + setConfigConditionAttribute (element.createNewChildElement ("PrecompiledHeaderOutputFile"))->addTextElement ("$(Platform)\\$(Configuration)\\JucePrecompiledHeader.pch"); + setConfigConditionAttribute (element.createNewChildElement ("ForcedIncludeFiles"))->addTextElement (pchFile.getFileName()); + } + + void writePrecompiledHeaderFiles (XmlElement& cpps) const + { + for (ConstConfigIterator config (owner); config.next();) + { + if (config->shouldUsePrecompiledHeaderFile()) + { + auto pchFileContent = config->getPrecompiledHeaderFileContent(); + + if (pchFileContent.isNotEmpty()) + { + auto pchFile = owner.getTargetFolder().getChildFile (config->getPrecompiledHeaderFilename()).withFileExtension (".h"); + + build_tools::writeStreamToFile (pchFile, [&] (MemoryOutputStream& mo) + { + mo << pchFileContent; + }); + + auto pchSourceFile = pchFile.withFileExtension (".cpp"); + + build_tools::writeStreamToFile (pchSourceFile, [this] (MemoryOutputStream& mo) + { + mo.setNewLineString (owner.getNewLineString()); + + writeAutoGenWarningComment (mo); + + mo << " This is an empty source file generated by JUCE required for Visual Studio PCH." << newLine + << newLine + << "*/" << newLine + << newLine; + }); + + auto* pchSourceElement = cpps.createNewChildElement ("ClCompile"); + pchSourceElement->setAttribute ("Include", prependDot (pchSourceFile.getFileName())); + setSourceFilePCHSettings (*pchSourceElement, pchFile, "Create", *config); + } + } + } + } + void addFilesToCompile (const Project::Item& projectItem, XmlElement& cpps, XmlElement& headers, XmlElement& otherFiles) const { auto targetType = (getOwner().getProject().isAudioPluginProject() ? type : SharedCodeTarget); @@ -752,32 +828,43 @@ public: else if (projectItem.shouldBeAddedToTargetProject() && projectItem.shouldBeAddedToTargetExporter (getOwner()) && getOwner().getProject().getTargetTypeFromFilePath (projectItem.getFile(), true) == targetType) { - RelativePath path (projectItem.getFile(), getOwner().getTargetFolder(), RelativePath::buildTargetFolder); + build_tools::RelativePath path (projectItem.getFile(), getOwner().getTargetFolder(), build_tools::RelativePath::buildTargetFolder); - jassert (path.getRoot() == RelativePath::buildTargetFolder); + jassert (path.getRoot() == build_tools::RelativePath::buildTargetFolder); if (path.hasFileExtension (cOrCppFileExtensions) || path.hasFileExtension (asmFileExtensions)) { - if (targetType == SharedCodeTarget || projectItem.shouldBeCompiled()) - { - auto* e = cpps.createNewChildElement ("ClCompile"); - e->setAttribute ("Include", path.toWindowsStyle()); + auto* e = cpps.createNewChildElement ("ClCompile"); + e->setAttribute ("Include", path.toWindowsStyle()); - if (shouldUseStdCall (path)) - e->createNewChildElement ("CallingConvention")->addTextElement ("StdCall"); + if (shouldUseStdCall (path)) + e->createNewChildElement ("CallingConvention")->addTextElement ("StdCall"); - if (projectItem.shouldBeCompiled()) - { - auto extraCompilerFlags = owner.compilerFlagSchemesMap[projectItem.getCompilerFlagSchemeString()].get().toString(); + if (projectItem.shouldBeCompiled()) + { + auto extraCompilerFlags = owner.compilerFlagSchemesMap[projectItem.getCompilerFlagSchemeString()].get().toString(); - if (extraCompilerFlags.isNotEmpty()) - e->createNewChildElement ("AdditionalOptions")->addTextElement (extraCompilerFlags + " %(AdditionalOptions)"); - } - else + if (extraCompilerFlags.isNotEmpty()) + e->createNewChildElement ("AdditionalOptions")->addTextElement (extraCompilerFlags + " %(AdditionalOptions)"); + + if (! projectItem.shouldSkipPCH()) { - e->createNewChildElement ("ExcludedFromBuild")->addTextElement ("true"); + for (ConstConfigIterator i (owner); i.next();) + { + if (i->shouldUsePrecompiledHeaderFile()) + { + auto pchFile = owner.getTargetFolder().getChildFile (i->getPrecompiledHeaderFilename()).withFileExtension (".h"); + + if (pchFile.existsAsFile()) + setSourceFilePCHSettings (*e, pchFile, "Use", *i); + } + } } } + else + { + e->createNewChildElement ("ExcludedFromBuild")->addTextElement ("true"); + } } else if (path.hasFileExtension (headerFileExtensions)) { @@ -790,7 +877,7 @@ public: } } - void setConditionAttribute (XmlElement& xml, const BuildConfiguration& config) const + static void setConditionAttribute (XmlElement& xml, const BuildConfiguration& config) { auto& msvcConfig = dynamic_cast<const MSVCBuildConfiguration&> (config); xml.setAttribute ("Condition", "'$(Configuration)|$(Platform)'=='" + msvcConfig.createMSVCConfigName() + "'"); @@ -804,7 +891,7 @@ public: e->createNewChildElement ("UniqueIdentifier")->addTextElement (createGUID (path + "_guidpathsaltxhsdf")); } - void addFileToFilter (const RelativePath& file, const String& groupPath, + void addFileToFilter (const build_tools::RelativePath& file, const String& groupPath, XmlElement& cpps, XmlElement& headers, XmlElement& otherFiles) const { XmlElement* e = nullptr; @@ -816,7 +903,7 @@ public: else e = otherFiles.createNewChildElement ("None"); - jassert (file.getRoot() == RelativePath::buildTargetFolder); + jassert (file.getRoot() == build_tools::RelativePath::buildTargetFolder); e->setAttribute ("Include", file.toWindowsStyle()); e->createNewChildElement ("Filter")->addTextElement (groupPath); } @@ -841,33 +928,17 @@ public: return filesWereAdded; } - else if (projectItem.shouldBeAddedToTargetProject() && projectItem.shouldBeAddedToTargetExporter (getOwner())) - { - RelativePath relativePath (projectItem.getFile(), getOwner().getTargetFolder(), RelativePath::buildTargetFolder); - - jassert (relativePath.getRoot() == RelativePath::buildTargetFolder); - - if (getOwner().getProject().getTargetTypeFromFilePath (projectItem.getFile(), true) == targetType - && (targetType == SharedCodeTarget || projectItem.shouldBeCompiled())) - { - addFileToFilter (relativePath, path.upToLastOccurrenceOf ("\\", false, false), cpps, headers, otherFiles); - return true; - } - } - - return false; - } - - bool addFilesToFilter (const Array<RelativePath>& files, const String& path, - XmlElement& cpps, XmlElement& headers, XmlElement& otherFiles, XmlElement& groups) - { - if (files.size() > 0) + else if (projectItem.shouldBeAddedToTargetProject() + && projectItem.shouldBeAddedToTargetExporter (getOwner()) + && getOwner().getProject().getTargetTypeFromFilePath (projectItem.getFile(), true) == targetType) { - addFilterGroup (groups, path); + build_tools::RelativePath relativePath (projectItem.getFile(), + getOwner().getTargetFolder(), + build_tools::RelativePath::buildTargetFolder); - for (int i = 0; i < files.size(); ++i) - addFileToFilter (files.getReference(i), path, cpps, headers, otherFiles); + jassert (relativePath.getRoot() == build_tools::RelativePath::buildTargetFolder); + addFileToFilter (relativePath, path.upToLastOccurrenceOf ("\\", false, false), cpps, headers, otherFiles); return true; } @@ -899,6 +970,12 @@ public: e->createNewChildElement ("Filter")->addTextElement (ProjectSaver::getJuceCodeGroupName()); } + if (getOwner().packagesConfigFile.existsAsFile()) + { + auto* e = otherFilesGroup->createNewChildElement ("None"); + e->setAttribute ("Include", getOwner().packagesConfigFile.getFileName()); + } + if (otherFilesGroup->getFirstChildElement() != nullptr) filterXml.addChildElement (otherFilesGroup.release()); @@ -936,12 +1013,14 @@ public: if (binaryPath.isEmpty()) return "$(SolutionDir)$(Platform)\\$(Configuration)"; - RelativePath binaryRelPath (binaryPath, RelativePath::projectFolder); + build_tools::RelativePath binaryRelPath (binaryPath, build_tools::RelativePath::projectFolder); if (binaryRelPath.isAbsolute()) return binaryRelPath.toWindowsStyle(); - return prependDot (binaryRelPath.rebased (getOwner().projectFolder, getOwner().getTargetFolder(), RelativePath::buildTargetFolder) + return prependDot (binaryRelPath.rebased (getOwner().projectFolder, + getOwner().getTargetFolder(), + build_tools::RelativePath::buildTargetFolder) .toWindowsStyle()); } @@ -977,25 +1056,17 @@ public: { auto fileType = getTargetFileType(); - switch (fileType) - { - case executable: return ".exe"; - case staticLibrary: return ".lib"; - case sharedLibraryOrDLL: return ".dll"; - - case pluginBundle: - switch (type) - { - case VST3PlugIn: return ".vst3"; - case AAXPlugIn: return ".aaxdll"; - case RTASPlugIn: return ".dpm"; - default: break; - } + if (fileType == executable) return ".exe"; + if (fileType == staticLibrary) return ".lib"; + if (fileType == sharedLibraryOrDLL) return ".dll"; - return ".dll"; + if (fileType == pluginBundle) + { + if (type == VST3PlugIn) return ".vst3"; + if (type == AAXPlugIn) return ".aaxdll"; + if (type == RTASPlugIn) return ".dpm"; - default: - break; + return ".dll"; } return {}; @@ -1046,15 +1117,15 @@ public: } //============================================================================== - RelativePath getAAXIconFile() const + build_tools::RelativePath getAAXIconFile() const { - RelativePath aaxSDK (owner.getAAXPathString(), RelativePath::projectFolder); - RelativePath projectIcon ("icon.ico", RelativePath::buildTargetFolder); + build_tools::RelativePath aaxSDK (owner.getAAXPathString(), build_tools::RelativePath::projectFolder); + build_tools::RelativePath projectIcon ("icon.ico", build_tools::RelativePath::buildTargetFolder); if (getOwner().getTargetFolder().getChildFile ("icon.ico").existsAsFile()) return projectIcon.rebased (getOwner().getTargetFolder(), getOwner().getProject().getProjectFolder(), - RelativePath::projectFolder); + build_tools::RelativePath::projectFolder); return aaxSDK.getChildFile ("Utilities").getChildFile ("PlugIn.ico"); } @@ -1063,10 +1134,10 @@ public: { if (type == AAXPlugIn) { - RelativePath aaxSDK (owner.getAAXPathString(), RelativePath::projectFolder); - RelativePath aaxLibsFolder = aaxSDK.getChildFile ("Libs"); - RelativePath bundleScript = aaxSDK.getChildFile ("Utilities").getChildFile ("CreatePackage.bat"); - RelativePath iconFilePath = getAAXIconFile(); + build_tools::RelativePath aaxSDK (owner.getAAXPathString(), build_tools::RelativePath::projectFolder); + build_tools::RelativePath aaxLibsFolder = aaxSDK.getChildFile ("Libs"); + build_tools::RelativePath bundleScript = aaxSDK.getChildFile ("Utilities").getChildFile ("CreatePackage.bat"); + build_tools::RelativePath iconFilePath = getAAXIconFile(); auto outputFilename = config.getOutputFilename (".aaxplugin", true, false); auto bundleDir = getOwner().getOutDirFile (config, outputFilename); @@ -1085,9 +1156,9 @@ public: } else if (type == UnityPlugIn) { - RelativePath scriptPath (config.project.getGeneratedCodeFolder().getChildFile (config.project.getUnityScriptName()), - getOwner().getTargetFolder(), - RelativePath::projectFolder); + build_tools::RelativePath scriptPath (config.project.getGeneratedCodeFolder().getChildFile (config.project.getUnityScriptName()), + getOwner().getTargetFolder(), + build_tools::RelativePath::projectFolder); auto pkgScript = String ("copy /Y ") + scriptPath.toWindowsStyle().quoted() + " \"$(OutDir)\""; @@ -1150,22 +1221,15 @@ public: void addExtraPreprocessorDefines (StringPairArray& defines) const { - switch (type) + if (type == AAXPlugIn) { - case AAXPlugIn: - { - auto aaxLibsFolder = RelativePath (owner.getAAXPathString(), RelativePath::projectFolder).getChildFile ("Libs"); - defines.set ("JucePlugin_AAXLibs_path", createRebasedPath (aaxLibsFolder)); - } - break; - case RTASPlugIn: - { - RelativePath rtasFolder (owner.getRTASPathString(), RelativePath::projectFolder); - defines.set ("JucePlugin_WinBag_path", createRebasedPath (rtasFolder.getChildFile ("WinBag"))); - } - break; - default: - break; + auto aaxLibsFolder = build_tools::RelativePath (owner.getAAXPathString(), build_tools::RelativePath::projectFolder).getChildFile ("Libs"); + defines.set ("JucePlugin_AAXLibs_path", createRebasedPath (aaxLibsFolder)); + } + else if (type == RTASPlugIn) + { + build_tools::RelativePath rtasFolder (owner.getRTASPathString(), build_tools::RelativePath::projectFolder); + defines.set ("JucePlugin_WinBag_path", createRebasedPath (rtasFolder.getChildFile ("WinBag"))); } } @@ -1182,7 +1246,7 @@ public: StringArray searchPaths; if (type == RTASPlugIn) { - RelativePath rtasFolder (owner.getRTASPathString(), RelativePath::projectFolder); + build_tools::RelativePath rtasFolder (owner.getRTASPathString(), build_tools::RelativePath::projectFolder); static const char* p[] = { "AlturaPorts/TDMPlugins/PluginLibrary/EffectClasses", "AlturaPorts/TDMPlugins/PluginLibrary/ProcessClasses", @@ -1280,12 +1344,12 @@ public: auto& exp = getOwner(); auto moduleDefPath - = RelativePath (exp.getPathForModuleString ("juce_audio_plugin_client"), RelativePath::projectFolder) + = build_tools::RelativePath (exp.getPathForModuleString ("juce_audio_plugin_client"), build_tools::RelativePath::projectFolder) .getChildFile ("juce_audio_plugin_client").getChildFile ("RTAS").getChildFile ("juce_RTAS_WinExports.def"); return prependDot (moduleDefPath.rebased (exp.getProject().getProjectFolder(), - exp.getTargetFolder(), - RelativePath::buildTargetFolder).toWindowsStyle()); + exp.getTargetFolder(), + build_tools::RelativePath::buildTargetFolder).toWindowsStyle()); } return {}; @@ -1294,7 +1358,7 @@ public: File getVCProjFile() const { return getOwner().getProjectFile (getProjectFileSuffix(), getName()); } File getVCProjFiltersFile() const { return getOwner().getProjectFile (getFiltersFileSuffix(), getName()); } - String createRebasedPath (const RelativePath& path) const { return getOwner().createRebasedPath (path); } + String createRebasedPath (const build_tools::RelativePath& path) const { return getOwner().createRebasedPath (path); } void addWindowsTargetPlatformToConfig (XmlElement& e) const { @@ -1319,40 +1383,47 @@ public: }; //============================================================================== - bool usesMMFiles() const override { return false; } - bool canCopeWithDuplicateFiles() override { return false; } - bool supportsUserDefinedConfigurations() const override { return true; } - - bool isXcode() const override { return false; } - bool isVisualStudio() const override { return true; } - bool isCodeBlocks() const override { return false; } - bool isMakefile() const override { return false; } - bool isAndroidStudio() const override { return false; } - bool isCLion() const override { return false; } - - bool isAndroid() const override { return false; } - bool isWindows() const override { return true; } - bool isLinux() const override { return false; } - bool isOSX() const override { return false; } - bool isiOS() const override { return false; } - - bool supportsTargetType (ProjectType::Target::Type type) const override + bool usesMMFiles() const override { return false; } + bool canCopeWithDuplicateFiles() override { return false; } + bool supportsUserDefinedConfigurations() const override { return true; } + + bool isXcode() const override { return false; } + bool isVisualStudio() const override { return true; } + bool isCodeBlocks() const override { return false; } + bool isMakefile() const override { return false; } + bool isAndroidStudio() const override { return false; } + bool isCLion() const override { return false; } + + bool isAndroid() const override { return false; } + bool isWindows() const override { return true; } + bool isLinux() const override { return false; } + bool isOSX() const override { return false; } + bool isiOS() const override { return false; } + + bool supportsPrecompiledHeaders() const override { return true; } + + String getNewLineString() const override { return "\r\n"; } + + bool supportsTargetType (build_tools::ProjectType::Target::Type type) const override { switch (type) { - case ProjectType::Target::StandalonePlugIn: - case ProjectType::Target::GUIApp: - case ProjectType::Target::ConsoleApp: - case ProjectType::Target::StaticLibrary: - case ProjectType::Target::SharedCodeTarget: - case ProjectType::Target::AggregateTarget: - case ProjectType::Target::VSTPlugIn: - case ProjectType::Target::VST3PlugIn: - case ProjectType::Target::AAXPlugIn: - case ProjectType::Target::RTASPlugIn: - case ProjectType::Target::UnityPlugIn: - case ProjectType::Target::DynamicLibrary: + case build_tools::ProjectType::Target::StandalonePlugIn: + case build_tools::ProjectType::Target::GUIApp: + case build_tools::ProjectType::Target::ConsoleApp: + case build_tools::ProjectType::Target::StaticLibrary: + case build_tools::ProjectType::Target::SharedCodeTarget: + case build_tools::ProjectType::Target::AggregateTarget: + case build_tools::ProjectType::Target::VSTPlugIn: + case build_tools::ProjectType::Target::VST3PlugIn: + case build_tools::ProjectType::Target::AAXPlugIn: + case build_tools::ProjectType::Target::RTASPlugIn: + case build_tools::ProjectType::Target::UnityPlugIn: + case build_tools::ProjectType::Target::DynamicLibrary: return true; + case build_tools::ProjectType::Target::AudioUnitPlugIn: + case build_tools::ProjectType::Target::AudioUnitv3PlugIn: + case build_tools::ProjectType::Target::unspecified: default: break; } @@ -1361,12 +1432,12 @@ public: } //============================================================================== - RelativePath getManifestPath() const + build_tools::RelativePath getManifestPath() const { auto path = manifestFileValue.get().toString(); - return path.isEmpty() ? RelativePath() - : RelativePath (path, RelativePath::projectFolder); + return path.isEmpty() ? build_tools::RelativePath() + : build_tools::RelativePath (path, build_tools::RelativePath::projectFolder); } //============================================================================== @@ -1392,6 +1463,20 @@ public: { props.add (new TextPropertyComponent (manifestFileValue, "Manifest file", 8192, false), "Path to a manifest input file which should be linked into your binary (path is relative to jucer file)."); + + props.add (new ChoicePropertyComponent (IPPLibraryValue, "Use IPP Library", + { "No", "Yes (Default Linking)", "Multi-Threaded Static Library", "Single-Threaded Static Library", "Multi-Threaded DLL", "Single-Threaded DLL" }, + { var(), "true", "Parallel_Static", "Sequential", "Parallel_Dynamic", "Sequential_Dynamic" }), + "Enable this to use Intel's Integrated Performance Primitives library."); + + { + auto isWindows10SDK = getVisualStudioVersion() > 14; + + props.add (new TextPropertyComponent (targetPlatformVersion, "Windows Target Platform", 20, false), + String ("Specifies the version of the Windows SDK that will be used when building this project. ") + + (isWindows10SDK ? "Leave this field empty to use the latest Windows 10 SDK installed on the build machine." + : "The default value for this exporter is " + getDefaultWindowsTargetPlatformVersion())); + } } enum OptimisationLevel @@ -1403,20 +1488,17 @@ public: }; //============================================================================== - void addPlatformSpecificSettingsForProjectType (const ProjectType& type) override + void addPlatformSpecificSettingsForProjectType (const build_tools::ProjectType& type) override { msvcExtraPreprocessorDefs.set ("_CRT_SECURE_NO_WARNINGS", ""); if (type.isCommandLineApp()) msvcExtraPreprocessorDefs.set("_CONSOLE", ""); - callForAllSupportedTargets ([this] (ProjectType::Target::Type targetType) + callForAllSupportedTargets ([this] (build_tools::ProjectType::Target::Type targetType) { - if (MSVCTargetBase* target = new MSVCTargetBase (targetType, *this)) - { - if (targetType != ProjectType::Target::AggregateTarget) - targets.add (target); - } + if (targetType != build_tools::ProjectType::Target::AggregateTarget) + targets.add (new MSVCTargetBase (targetType, *this)); }); // If you hit this assert, you tried to generate a project for an exporter @@ -1427,13 +1509,13 @@ public: const MSVCTargetBase* getSharedCodeTarget() const { for (auto target : targets) - if (target->type == ProjectType::Target::SharedCodeTarget) + if (target->type == build_tools::ProjectType::Target::SharedCodeTarget) return target; return nullptr; } - bool hasTarget (ProjectType::Target::Type type) const + bool hasTarget (build_tools::ProjectType::Target::Type type) const { for (auto target : targets) if (target->type == type) @@ -1442,97 +1524,21 @@ public: return false; } - static void writeIconFile (const ProjectExporter& exporter, const File& iconFile) - { - Array<Image> images; - int sizes[] = { 16, 32, 48, 256 }; - - for (int i = 0; i < numElementsInArray (sizes); ++i) - { - auto im = exporter.getBestIconForSize (sizes[i], true); - - if (im.isValid()) - images.add (im); - } - - if (images.size() > 0) - { - MemoryOutputStream mo; - writeIconFile (images, mo); - overwriteFileIfDifferentOrThrow (iconFile, mo); - } - } - - static void writeRCValue (MemoryOutputStream& mo, const String& n, const String& value) - { - if (value.isNotEmpty()) - mo << " VALUE \"" << n << "\", \"" - << CppTokeniserFunctions::addEscapeChars (value) << "\\0\"" << newLine; - } - static void createRCFile (const Project& p, const File& iconFile, const File& rcFile) { - auto version = p.getVersionString(); - - MemoryOutputStream mo; - - mo << "#ifdef JUCE_USER_DEFINED_RC_FILE" << newLine - << " #include JUCE_USER_DEFINED_RC_FILE" << newLine - << "#else" << newLine - << newLine - << "#undef WIN32_LEAN_AND_MEAN" << newLine - << "#define WIN32_LEAN_AND_MEAN" << newLine - << "#include <windows.h>" << newLine - << newLine - << "VS_VERSION_INFO VERSIONINFO" << newLine - << "FILEVERSION " << getCommaSeparatedVersionNumber (version) << newLine - << "BEGIN" << newLine - << " BLOCK \"StringFileInfo\"" << newLine - << " BEGIN" << newLine - << " BLOCK \"040904E4\"" << newLine - << " BEGIN" << newLine; - - writeRCValue (mo, "CompanyName", p.getCompanyNameString()); - writeRCValue (mo, "LegalCopyright", p.getCompanyCopyrightString()); - writeRCValue (mo, "FileDescription", p.getProjectNameString()); - writeRCValue (mo, "FileVersion", version); - writeRCValue (mo, "ProductName", p.getProjectNameString()); - writeRCValue (mo, "ProductVersion", version); - - mo << " END" << newLine - << " END" << newLine - << newLine - << " BLOCK \"VarFileInfo\"" << newLine - << " BEGIN" << newLine - << " VALUE \"Translation\", 0x409, 1252" << newLine - << " END" << newLine - << "END" << newLine - << newLine - << "#endif" << newLine; - - if (iconFile.existsAsFile()) - mo << newLine - << "IDI_ICON1 ICON DISCARDABLE " << iconFile.getFileName().quoted() - << newLine - << "IDI_ICON2 ICON DISCARDABLE " << iconFile.getFileName().quoted(); - - overwriteFileIfDifferentOrThrow (rcFile, mo); - } - - static String getCommaSeparatedVersionNumber (const String& version) - { - auto versionParts = StringArray::fromTokens (version, ",.", ""); - versionParts.trim(); - versionParts.removeEmptyStrings(); - while (versionParts.size() < 4) - versionParts.add ("0"); - - return versionParts.joinIntoString (","); + build_tools::ResourceRcOptions resourceRc; + resourceRc.version = p.getVersionString(); + resourceRc.companyName = p.getCompanyNameString(); + resourceRc.companyCopyright = p.getCompanyCopyrightString(); + resourceRc.projectName = p.getProjectNameString(); + resourceRc.icon = iconFile; + + resourceRc.write (rcFile); } private: //============================================================================== - String createRebasedPath (const RelativePath& path) const + String createRebasedPath (const build_tools::RelativePath& path) const { auto rebasedPath = rebaseFromProjectFolderToBuildTarget (path).toWindowsStyle(); @@ -1543,7 +1549,7 @@ private: protected: //============================================================================== - mutable File rcFile, iconFile; + mutable File rcFile, iconFile, packagesConfigFile; OwnedArray<MSVCTargetBase> targets; ValueWithDefault IPPLibraryValue, platformToolsetValue, targetPlatformVersion, manifestFileValue; @@ -1565,44 +1571,12 @@ protected: if (File::isAbsolutePath (file) || file.startsWithChar ('$')) prefix = ""; - return prefix + FileHelpers::windowsStylePath (file); + return prefix + build_tools::windowsStylePath (file); } String getIntDirFile (const BuildConfiguration& config, const String& file) const { return prependIfNotAbsolute (replacePreprocessorTokens (config, file), "$(IntDir)\\"); } String getOutDirFile (const BuildConfiguration& config, const String& file) const { return prependIfNotAbsolute (replacePreprocessorTokens (config, file), "$(OutDir)\\"); } - void updateOldSettings() - { - { - auto oldStylePrebuildCommand = getSettingString (Ids::prebuildCommand); - settings.removeProperty (Ids::prebuildCommand, nullptr); - - if (oldStylePrebuildCommand.isNotEmpty()) - for (ConfigIterator config (*this); config.next();) - dynamic_cast<MSVCBuildConfiguration&> (*config).getValue (Ids::prebuildCommand) = oldStylePrebuildCommand; - } - - { - auto oldStyleLibName = getSettingString ("libraryName_Debug"); - settings.removeProperty ("libraryName_Debug", nullptr); - - if (oldStyleLibName.isNotEmpty()) - for (ConfigIterator config (*this); config.next();) - if (config->isDebug()) - config->getValue (Ids::targetName) = oldStyleLibName; - } - - { - auto oldStyleLibName = getSettingString ("libraryName_Release"); - settings.removeProperty ("libraryName_Release", nullptr); - - if (oldStyleLibName.isNotEmpty()) - for (ConfigIterator config (*this); config.next();) - if (! config->isDebug()) - config->getValue (Ids::targetName) = oldStyleLibName; - } - } - BuildConfiguration::Ptr createBuildConfig (const ValueTree& v) const override { return *new MSVCBuildConfiguration (project, v, *this); @@ -1621,7 +1595,7 @@ protected: for (int i = 0; i < targets.size(); ++i) if (auto* target = targets[i]) - if (target->type == ProjectType::Target::SharedCodeTarget) + if (target->type == build_tools::ProjectType::Target::SharedCodeTarget) return target->getProjectGuid(); return {}; @@ -1638,13 +1612,13 @@ protected: { if (auto* target = targets[i]) { - if (sharedCodeGuid.isEmpty() || (addingOtherTargets != 0) == (target->type != ProjectType::Target::StandalonePlugIn)) + if (sharedCodeGuid.isEmpty() || (addingOtherTargets != 0) == (target->type != build_tools::ProjectType::Target::StandalonePlugIn)) { out << "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"" << projectName << " - " << target->getName() << "\", \"" << target->getVCProjFile().getFileName() << "\", \"" << target->getProjectGuid() << '"' << newLine; - if (sharedCodeGuid.isNotEmpty() && target->type != ProjectType::Target::SharedCodeTarget) + if (sharedCodeGuid.isNotEmpty() && target->type != build_tools::ProjectType::Target::SharedCodeTarget) out << "\tProjectSection(ProjectDependencies) = postProject" << newLine << "\t\t" << sharedCodeGuid << " = " << sharedCodeGuid << newLine << "\tEndProjectSection" << newLine; @@ -1698,140 +1672,58 @@ protected: } //============================================================================== - static void writeBMPImage (const Image& image, const int w, const int h, MemoryOutputStream& out) + bool hasResourceFile() const { - int maskStride = (w / 8 + 3) & ~3; - - out.writeInt (40); // bitmapinfoheader size - out.writeInt (w); - out.writeInt (h * 2); - out.writeShort (1); // planes - out.writeShort (32); // bits - out.writeInt (0); // compression - out.writeInt ((h * w * 4) + (h * maskStride)); // size image - out.writeInt (0); // x pixels per meter - out.writeInt (0); // y pixels per meter - out.writeInt (0); // clr used - out.writeInt (0); // clr important - - Image::BitmapData bitmap (image, Image::BitmapData::readOnly); - int alphaThreshold = 5; - - int y; - for (y = h; --y >= 0;) - { - for (int x = 0; x < w; ++x) - { - auto pixel = bitmap.getPixelColour (x, y); - - if (pixel.getAlpha() <= alphaThreshold) - { - out.writeInt (0); - } - else - { - out.writeByte ((char) pixel.getBlue()); - out.writeByte ((char) pixel.getGreen()); - out.writeByte ((char) pixel.getRed()); - out.writeByte ((char) pixel.getAlpha()); - } - } - } - - for (y = h; --y >= 0;) - { - int mask = 0, count = 0; - - for (int x = 0; x < w; ++x) - { - auto pixel = bitmap.getPixelColour (x, y); - - mask <<= 1; - if (pixel.getAlpha() <= alphaThreshold) - mask |= 1; - - if (++count == 8) - { - out.writeByte ((char) mask); - count = 0; - mask = 0; - } - } - - if (mask != 0) - out.writeByte ((char) mask); - - for (int i = maskStride - w / 8; --i >= 0;) - out.writeByte (0); - } + return ! projectType.isStaticLibrary(); } - static void writeIconFile (const Array<Image>& images, MemoryOutputStream& out) + void createResourcesAndIcon() const { - out.writeShort (0); // reserved - out.writeShort (1); // .ico tag - out.writeShort ((short) images.size()); - - MemoryOutputStream dataBlock; - - int imageDirEntrySize = 16; - int dataBlockStart = 6 + images.size() * imageDirEntrySize; - - for (int i = 0; i < images.size(); ++i) + if (hasResourceFile()) { - auto oldDataSize = dataBlock.getDataSize(); - - auto& image = images.getReference (i); - auto w = image.getWidth(); - auto h = image.getHeight(); - - if (w >= 256 || h >= 256) - { - PNGImageFormat pngFormat; - pngFormat.writeImageToStream (image, dataBlock); - } - else - { - writeBMPImage (image, w, h, dataBlock); - } - - out.writeByte ((char) w); - out.writeByte ((char) h); - out.writeByte (0); - out.writeByte (0); - out.writeShort (1); // colour planes - out.writeShort (32); // bits per pixel - out.writeInt ((int) (dataBlock.getDataSize() - oldDataSize)); - out.writeInt (dataBlockStart + (int) oldDataSize); + iconFile = getTargetFolder().getChildFile ("icon.ico"); + build_tools::writeWinIcon (getIcons(), iconFile); + rcFile = getTargetFolder().getChildFile ("resources.rc"); + createRCFile (project, iconFile, rcFile); } - - jassert (out.getPosition() == dataBlockStart); - out << dataBlock; } - bool hasResourceFile() const + bool shouldAddWebView2Package() const { - return ! projectType.isStaticLibrary(); + return project.getEnabledModules().isModuleEnabled ("juce_gui_extra") + && project.isConfigFlagEnabled ("JUCE_USE_WIN_WEBVIEW2", false); } - void createResourcesAndIcon() const + static String getWebView2PackageName() { return "Microsoft.Web.WebView2"; } + static String getWebView2PackageVersion() { return "0.9.488"; } + + void createPackagesConfigFile() const { - if (hasResourceFile()) + if (shouldAddWebView2Package()) { - iconFile = getTargetFolder().getChildFile ("icon.ico"); - writeIconFile (*this, iconFile); - rcFile = getTargetFolder().getChildFile ("resources.rc"); - createRCFile (project, iconFile, rcFile); + packagesConfigFile = getTargetFolder().getChildFile ("packages.config"); + + build_tools::writeStreamToFile (packagesConfigFile, [] (MemoryOutputStream& mo) + { + mo.setNewLineString ("\r\n"); + + mo << "<?xml version=\"1.0\" encoding=\"utf-8\"?>" << newLine + << "<packages>" << newLine + << "\t" << "<package id=" << getWebView2PackageName().quoted() + << " version=" << getWebView2PackageVersion().quoted() + << " />" << newLine + << "</packages>" << newLine; + }); } } static String prependDot (const String& filename) { - return FileHelpers::isAbsolutePath (filename) ? filename + return build_tools::isAbsolutePath (filename) ? filename : (".\\" + filename); } - static bool shouldUseStdCall (const RelativePath& path) + static bool shouldUseStdCall (const build_tools::RelativePath& path) { return path.getFileNameWithoutExtension().startsWithIgnoreCase ("include_juce_audio_plugin_client_RTAS_"); } @@ -1854,16 +1746,18 @@ class MSVCProjectExporterVC2015 : public MSVCProjectExporterBase { public: MSVCProjectExporterVC2015 (Project& p, const ValueTree& t) - : MSVCProjectExporterBase (p, t, getTargetFolderForExporter (getValueTreeTypeName())) + : MSVCProjectExporterBase (p, t, getTargetFolderName()) { - name = getName(); + name = getDisplayName(); targetPlatformVersion.setDefault (getDefaultWindowsTargetPlatformVersion()); platformToolsetValue.setDefault (getDefaultToolset()); } - static const char* getName() { return "Visual Studio 2015"; } - static const char* getValueTreeTypeName() { return "VS2015"; } + static String getDisplayName() { return "Visual Studio 2015"; } + static String getValueTreeTypeName() { return "VS2015"; } + static String getTargetFolderName() { return "VisualStudio2015"; } + int getVisualStudioVersion() const override { return 14; } String getSolutionComment() const override { return "# Visual Studio 2015"; } String getToolsVersion() const override { return "14.0"; } @@ -1880,15 +1774,11 @@ public: void createExporterProperties (PropertyListBuilder& props) override { - MSVCProjectExporterBase::createExporterProperties (props); - static const char* toolsetNames[] = { "v140", "v140_xp", "CTP_Nov2013" }; const var toolsets[] = { "v140", "v140_xp", "CTP_Nov2013" }; addToolsetProperty (props, toolsetNames, toolsets, numElementsInArray (toolsets)); - addIPPLibraryProperty (props); - - addWindowsTargetPlatformProperties (props); + MSVCProjectExporterBase::createExporterProperties (props); } JUCE_DECLARE_NON_COPYABLE (MSVCProjectExporterVC2015) @@ -1899,16 +1789,18 @@ class MSVCProjectExporterVC2017 : public MSVCProjectExporterBase { public: MSVCProjectExporterVC2017 (Project& p, const ValueTree& t) - : MSVCProjectExporterBase (p, t, getTargetFolderForExporter (getValueTreeTypeName())) + : MSVCProjectExporterBase (p, t, getTargetFolderName()) { - name = getName(); + name = getDisplayName(); targetPlatformVersion.setDefault (getDefaultWindowsTargetPlatformVersion()); platformToolsetValue.setDefault (getDefaultToolset()); } - static const char* getName() { return "Visual Studio 2017"; } - static const char* getValueTreeTypeName() { return "VS2017"; } + static String getDisplayName() { return "Visual Studio 2017"; } + static String getValueTreeTypeName() { return "VS2017"; } + static String getTargetFolderName() { return "VisualStudio2017"; } + int getVisualStudioVersion() const override { return 15; } String getSolutionComment() const override { return "# Visual Studio 2017"; } String getToolsVersion() const override { return "15.0"; } @@ -1925,15 +1817,11 @@ public: void createExporterProperties (PropertyListBuilder& props) override { - MSVCProjectExporterBase::createExporterProperties (props); - static const char* toolsetNames[] = { "v140", "v140_xp", "v141", "v141_xp" }; const var toolsets[] = { "v140", "v140_xp", "v141", "v141_xp" }; addToolsetProperty (props, toolsetNames, toolsets, numElementsInArray (toolsets)); - addIPPLibraryProperty (props); - - addWindowsTargetPlatformProperties (props); + MSVCProjectExporterBase::createExporterProperties (props); } JUCE_DECLARE_NON_COPYABLE (MSVCProjectExporterVC2017) @@ -1944,16 +1832,18 @@ class MSVCProjectExporterVC2019 : public MSVCProjectExporterBase { public: MSVCProjectExporterVC2019 (Project& p, const ValueTree& t) - : MSVCProjectExporterBase (p, t, getTargetFolderForExporter (getValueTreeTypeName())) + : MSVCProjectExporterBase (p, t, getTargetFolderName()) { - name = getName(); + name = getDisplayName(); targetPlatformVersion.setDefault (getDefaultWindowsTargetPlatformVersion()); platformToolsetValue.setDefault (getDefaultToolset()); } - static const char* getName() { return "Visual Studio 2019"; } - static const char* getValueTreeTypeName() { return "VS2019"; } + static String getDisplayName() { return "Visual Studio 2019"; } + static String getValueTreeTypeName() { return "VS2019"; } + static String getTargetFolderName() { return "VisualStudio2019"; } + int getVisualStudioVersion() const override { return 16; } String getSolutionComment() const override { return "# Visual Studio 2019"; } String getToolsVersion() const override { return "16.0"; } @@ -1970,15 +1860,11 @@ public: void createExporterProperties (PropertyListBuilder& props) override { - MSVCProjectExporterBase::createExporterProperties (props); - static const char* toolsetNames[] = { "v140", "v140_xp", "v141", "v141_xp", "v142" }; const var toolsets[] = { "v140", "v140_xp", "v141", "v141_xp", "v142" }; addToolsetProperty (props, toolsetNames, toolsets, numElementsInArray (toolsets)); - addIPPLibraryProperty (props); - - addWindowsTargetPlatformProperties (props); + MSVCProjectExporterBase::createExporterProperties (props); } JUCE_DECLARE_NON_COPYABLE (MSVCProjectExporterVC2019) diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Make.h b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Make.h index 515c50ee..86c33e79 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Make.h +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Make.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -37,7 +36,11 @@ protected: public: MakeBuildConfiguration (Project& p, const ValueTree& settings, const ProjectExporter& e) : BuildConfiguration (p, settings, e), - architectureTypeValue (config, Ids::linuxArchitecture, getUndoManager(), String()) + architectureTypeValue (config, Ids::linuxArchitecture, getUndoManager(), String()), + pluginBinaryCopyStepValue (config, Ids::enablePluginBinaryCopyStep, getUndoManager(), true), + vstBinaryLocation (config, Ids::vstBinaryLocation, getUndoManager(), "$(HOME)/.vst"), + vst3BinaryLocation (config, Ids::vst3BinaryLocation, getUndoManager(), "$(HOME)/.vst3"), + unityPluginBinaryLocation (config, Ids::unityPluginBinaryLocation, getUndoManager(), "$(HOME)/UnityPlugins") { linkTimeOptimisationValue.setDefault (false); optimisationLevelValue.setDefault (isDebug() ? gccO0 : gccO3); @@ -52,6 +55,29 @@ protected: { "<None>", "Native", "32-bit (-m32)", "64-bit (-m64)", "ARM v6", "ARM v7" }, { { String() }, "-march=native", "-m32", "-m64", "-march=armv6", "-march=armv7" }), "Specifies the 32/64-bit architecture to use."); + + auto isBuildingAnyPlugins = (project.shouldBuildVST() || project.shouldBuildVST3() || project.shouldBuildUnityPlugin()); + + if (isBuildingAnyPlugins) + { + props.add (new ChoicePropertyComponent (pluginBinaryCopyStepValue, "Enable Plugin Copy Step"), + "Enable this to copy plugin binaries to a specified folder after building."); + + if (project.shouldBuildVST3()) + props.add (new TextPropertyComponentWithEnablement (vst3BinaryLocation, pluginBinaryCopyStepValue, "VST3 Binary Location", + 1024, false), + "The folder in which the compiled VST3 binary should be placed."); + + if (project.shouldBuildUnityPlugin()) + props.add (new TextPropertyComponentWithEnablement (unityPluginBinaryLocation, pluginBinaryCopyStepValue, "Unity Binary Location", + 1024, false), + "The folder in which the compiled Unity plugin binary and associated C# GUI script should be placed."); + + if (project.shouldBuildVST()) + props.add (new TextPropertyComponentWithEnablement (vstBinaryLocation, pluginBinaryCopyStepValue, "VST (Legacy) Binary Location", + 1024, false), + "The folder in which the compiled legacy VST binary should be placed."); + } } String getModuleLibraryArchName() const override @@ -71,10 +97,16 @@ protected: return "${JUCE_ARCH_LABEL}"; } - String getArchitectureTypeString() const { return architectureTypeValue.get(); } + String getArchitectureTypeString() const { return architectureTypeValue.get(); } + + bool isPluginBinaryCopyStepEnabled() const { return pluginBinaryCopyStepValue.get(); } + String getVSTBinaryLocationString() const { return vstBinaryLocation.get(); } + String getVST3BinaryLocationString() const { return vst3BinaryLocation.get(); } + String getUnityPluginBinaryLocationString() const { return unityPluginBinaryLocation.get(); } + private: //============================================================================== - ValueWithDefault architectureTypeValue; + ValueWithDefault architectureTypeValue, pluginBinaryCopyStepValue, vstBinaryLocation, vst3BinaryLocation, unityPluginBinaryLocation; }; BuildConfiguration::Ptr createBuildConfig (const ValueTree& tree) const override @@ -84,11 +116,11 @@ protected: public: //============================================================================== - class MakefileTarget : public ProjectType::Target + class MakefileTarget : public build_tools::ProjectType::Target { public: - MakefileTarget (ProjectType::Target::Type targetType, const MakefileProjectExporter& exporter) - : ProjectType::Target (targetType), owner (exporter) + MakefileTarget (build_tools::ProjectType::Target::Type targetType, const MakefileProjectExporter& exporter) + : build_tools::ProjectType::Target (targetType), owner (exporter) {} StringArray getCompilerFlags() const @@ -122,7 +154,7 @@ public: StringPairArray getDefines (const BuildConfiguration& config) const { StringPairArray result; - auto commonOptionKeys = owner.getAllPreprocessorDefs (config, ProjectType::Target::unspecified).getAllKeys(); + auto commonOptionKeys = owner.getAllPreprocessorDefs (config, build_tools::ProjectType::Target::unspecified).getAllKeys(); auto targetSpecific = owner.getAllPreprocessorDefs (config, type); for (auto& key : targetSpecific.getAllKeys()) @@ -137,17 +169,11 @@ public: if (type == AggregateTarget) // the aggregate target should not specify any settings at all! return {}; // it just defines dependencies on the other targets. - StringArray defines; - auto defs = getDefines (config); - - for (auto& key : defs.getAllKeys()) - defines.add ("-D" + key + "=" + defs[key]); - StringArray s; auto cppflagsVarName = "JUCE_CPPFLAGS_" + getTargetVarName(); - s.add (cppflagsVarName + " := " + defines.joinIntoString (" ")); + s.add (cppflagsVarName + " := " + createGCCPreprocessorFlags (getDefines (config))); auto cflags = getCompilerFlags(); @@ -168,22 +194,53 @@ public: else targetName = targetName.upToLastOccurrenceOf (".", false, false) + getTargetFileSuffix(); + if (type == VST3PlugIn) + { + s.add ("JUCE_VST3DIR := " + escapeSpaces (targetName).upToLastOccurrenceOf (".", false, false) + ".vst3"); + s.add ("VST3_PLATFORM_ARCH := $(shell $(CXX) make_helpers/arch_detection.cpp 2>&1 | tr '\\n' ' ' | sed \"s/.*JUCE_ARCH \\([a-zA-Z0-9_-]*\\).*/\\1/\")"); + s.add ("JUCE_VST3SUBDIR := Contents/$(VST3_PLATFORM_ARCH)-linux"); + + targetName = "$(JUCE_VST3DIR)/$(JUCE_VST3SUBDIR)/" + targetName; + } + else if (type == UnityPlugIn) + { + s.add ("JUCE_UNITYDIR := Unity"); + targetName = "$(JUCE_UNITYDIR)/" + targetName; + } + s.add ("JUCE_TARGET_" + getTargetVarName() + String (" := ") + escapeSpaces (targetName)); + if (config.isPluginBinaryCopyStepEnabled() && (type == VST3PlugIn || type == VSTPlugIn || type == UnityPlugIn)) + { + String copyCmd ("JUCE_COPYCMD_" + getTargetVarName() + String (" := $(JUCE_OUTDIR)/")); + + if (type == VST3PlugIn) + { + s.add ("JUCE_VST3DESTDIR := " + config.getVST3BinaryLocationString()); + s.add (copyCmd + "$(JUCE_VST3DIR) $(JUCE_VST3DESTDIR)"); + } + else if (type == VSTPlugIn) + { + s.add ("JUCE_VSTDESTDIR := " + config.getVSTBinaryLocationString()); + s.add (copyCmd + escapeSpaces (targetName) + " $(JUCE_VSTDESTDIR)"); + } + else if (type == UnityPlugIn) + { + s.add ("JUCE_UNITYDESTDIR := " + config.getUnityPluginBinaryLocationString()); + s.add (copyCmd + "$(JUCE_UNITYDIR)/. $(JUCE_UNITYDESTDIR)"); + } + } + return s; } String getTargetFileSuffix() const { - switch (type) - { - case VSTPlugIn: - case UnityPlugIn: - case DynamicLibrary: return ".so"; - case SharedCodeTarget: - case StaticLibrary: return ".a"; - default: break; - } + if (type == VSTPlugIn || type == VST3PlugIn || type == UnityPlugIn || type == DynamicLibrary) + return ".so"; + + if (type == SharedCodeTarget || type == StaticLibrary) + return ".a"; return {}; } @@ -198,7 +255,8 @@ public: out << "OBJECTS_" + getTargetVarName() + String (" := \\") << newLine; for (auto& f : filesToCompile) - out << " $(JUCE_OBJDIR)/" << escapeSpaces (owner.getObjectFileFor ({ f.first, owner.getTargetFolder(), RelativePath::buildTargetFolder })) << " \\" << newLine; + out << " $(JUCE_OBJDIR)/" << escapeSpaces (owner.getObjectFileFor ({ f.first, owner.getTargetFolder(), build_tools::RelativePath::buildTargetFolder })) + << " \\" << newLine; out << newLine; } @@ -210,14 +268,14 @@ public: for (auto& f : filesToCompile) { - RelativePath relativePath (f.first, owner.getTargetFolder(), RelativePath::buildTargetFolder); + build_tools::RelativePath relativePath (f.first, owner.getTargetFolder(), build_tools::RelativePath::buildTargetFolder); out << "$(JUCE_OBJDIR)/" << escapeSpaces (owner.getObjectFileFor (relativePath)) << ": " << escapeSpaces (relativePath.toUnixStyle()) << newLine << "\t-$(V_AT)mkdir -p $(JUCE_OBJDIR)" << newLine << "\t@echo \"Compiling " << relativePath.getFileName() << "\"" << newLine << (relativePath.hasFileExtension ("c;s;S") ? "\t$(V_AT)$(CC) $(JUCE_CFLAGS) " : "\t$(V_AT)$(CXX) $(JUCE_CXXFLAGS) ") << "$(" << cppflagsVarName << ") $(" << cflagsVarName << ")" - << (f.second.isNotEmpty() ? " $(" + owner.getCompilerFlagSchemeVariableName (f.second) + ")" : "") << " -o \"$@\" -c \"$<\"" << newLine + << (f.second.isNotEmpty() ? " $(" + owner.getCompilerFlagSchemeVariableName (f.second) + ")" : "") << " -o \"$@\" -c \"$<\"" << newLine << newLine; } } @@ -260,16 +318,10 @@ public: << "\t-$(V_AT)mkdir -p $(JUCE_LIBDIR)" << newLine << "\t-$(V_AT)mkdir -p $(JUCE_OUTDIR)" << newLine; - if (type == UnityPlugIn) - { - auto scriptName = owner.getProject().getUnityScriptName(); - - RelativePath scriptPath (owner.getProject().getGeneratedCodeFolder().getChildFile (scriptName), - owner.getTargetFolder(), - RelativePath::projectFolder); - - out << "\t-$(V_AT)cp " + scriptPath.toUnixStyle() + " $(JUCE_OUTDIR)/" + scriptName << newLine; - } + if (type == VST3PlugIn) + out << "\t-$(V_AT)mkdir -p $(JUCE_OUTDIR)/$(JUCE_VST3DIR)/$(JUCE_VST3SUBDIR)" << newLine; + else if (type == UnityPlugIn) + out << "\t-$(V_AT)mkdir -p $(JUCE_OUTDIR)/$(JUCE_UNITYDIR)" << newLine; if (owner.projectType.isStaticLibrary() || type == SharedCodeTarget) { @@ -293,6 +345,29 @@ public: out << "$(RESOURCES) $(TARGET_ARCH)" << newLine; } + if (type == VST3PlugIn) + { + out << "\t-$(V_AT)mkdir -p $(JUCE_VST3DESTDIR)" << newLine + << "\t-$(V_AT)cp -R $(JUCE_COPYCMD_VST3)" << newLine; + } + else if (type == VSTPlugIn) + { + out << "\t-$(V_AT)mkdir -p $(JUCE_VSTDESTDIR)" << newLine + << "\t-$(V_AT)cp -R $(JUCE_COPYCMD_VST)" << newLine; + } + else if (type == UnityPlugIn) + { + auto scriptName = owner.getProject().getUnityScriptName(); + + build_tools::RelativePath scriptPath (owner.getProject().getGeneratedCodeFolder().getChildFile (scriptName), + owner.getTargetFolder(), + build_tools::RelativePath::projectFolder); + + out << "\t-$(V_AT)cp " + scriptPath.toUnixStyle() + " $(JUCE_OUTDIR)/$(JUCE_UNITYDIR)" << newLine + << "\t-$(V_AT)mkdir -p $(JUCE_UNITYDESTDIR)" << newLine + << "\t-$(V_AT)cp -R $(JUCE_COPYCMD_UNITY_PLUGIN)" << newLine; + } + out << newLine; } @@ -300,10 +375,9 @@ public: }; //============================================================================== - static const char* getNameLinux() { return "Linux Makefile"; } - static const char* getValueTreeTypeName() { return "LINUX_MAKE"; } - - String getExtraPkgConfigString() const { return extraPkgConfigValue.get(); } + static String getDisplayName() { return "Linux Makefile"; } + static String getValueTreeTypeName() { return "LINUX_MAKE"; } + static String getTargetFolderName() { return "LinuxMakefile"; } static MakefileProjectExporter* createForSettings (Project& projectToUse, const ValueTree& settingsToUse) { @@ -318,9 +392,8 @@ public: : ProjectExporter (p, t), extraPkgConfigValue (settings, Ids::linuxExtraPkgConfig, getUndoManager()) { - name = getNameLinux(); - - targetLocationValue.setDefault (getDefaultBuildsRootFolder() + getTargetFolderForExporter (getValueTreeTypeName())); + name = getDisplayName(); + targetLocationValue.setDefault (getDefaultBuildsRootFolder() + getTargetFolderName()); } //============================================================================== @@ -343,20 +416,28 @@ public: bool isOSX() const override { return false; } bool isiOS() const override { return false; } - bool supportsTargetType (ProjectType::Target::Type type) const override + String getNewLineString() const override { return "\n"; } + + bool supportsTargetType (build_tools::ProjectType::Target::Type type) const override { switch (type) { - case ProjectType::Target::GUIApp: - case ProjectType::Target::ConsoleApp: - case ProjectType::Target::StaticLibrary: - case ProjectType::Target::SharedCodeTarget: - case ProjectType::Target::AggregateTarget: - case ProjectType::Target::VSTPlugIn: - case ProjectType::Target::StandalonePlugIn: - case ProjectType::Target::DynamicLibrary: - case ProjectType::Target::UnityPlugIn: + case build_tools::ProjectType::Target::GUIApp: + case build_tools::ProjectType::Target::ConsoleApp: + case build_tools::ProjectType::Target::StaticLibrary: + case build_tools::ProjectType::Target::SharedCodeTarget: + case build_tools::ProjectType::Target::AggregateTarget: + case build_tools::ProjectType::Target::VSTPlugIn: + case build_tools::ProjectType::Target::VST3PlugIn: + case build_tools::ProjectType::Target::StandalonePlugIn: + case build_tools::ProjectType::Target::DynamicLibrary: + case build_tools::ProjectType::Target::UnityPlugIn: return true; + case build_tools::ProjectType::Target::AAXPlugIn: + case build_tools::ProjectType::Target::RTASPlugIn: + case build_tools::ProjectType::Target::AudioUnitPlugIn: + case build_tools::ProjectType::Target::AudioUnitv3PlugIn: + case build_tools::ProjectType::Target::unspecified: default: break; } @@ -383,8 +464,8 @@ public: { auto fileType = target->getTargetFileType(); - if (fileType == ProjectType::Target::sharedLibraryOrDLL - || fileType == ProjectType::Target::pluginBundle) + if (fileType == build_tools::ProjectType::Target::sharedLibraryOrDLL + || fileType == build_tools::ProjectType::Target::pluginBundle) return true; } @@ -394,26 +475,28 @@ public: //============================================================================== void create (const OwnedArray<LibraryModule>&) const override { - MemoryOutputStream mo; - mo.setNewLineString ("\n"); - - writeMakefile (mo); + build_tools::writeStreamToFile (getTargetFolder().getChildFile ("Makefile"), [&] (MemoryOutputStream& mo) + { + mo.setNewLineString (getNewLineString()); + writeMakefile (mo); + }); - overwriteFileIfDifferentOrThrow (getTargetFolder().getChildFile ("Makefile"), mo); + if (project.shouldBuildVST3()) + { + auto helperDir = getTargetFolder().getChildFile ("make_helpers"); + helperDir.createDirectory(); + build_tools::overwriteFileIfDifferentOrThrow (helperDir.getChildFile ("arch_detection.cpp"), + BinaryData::juce_runtime_arch_detection_cpp); + } } //============================================================================== - void addPlatformSpecificSettingsForProjectType (const ProjectType&) override + void addPlatformSpecificSettingsForProjectType (const build_tools::ProjectType&) override { - callForAllSupportedTargets ([this] (ProjectType::Target::Type targetType) + callForAllSupportedTargets ([this] (build_tools::ProjectType::Target::Type targetType) { - if (MakefileTarget* target = new MakefileTarget (targetType, *this)) - { - if (targetType == ProjectType::Target::AggregateTarget) - targets.insert (0, target); - else - targets.add (target); - } + targets.insert (targetType == build_tools::ProjectType::Target::AggregateTarget ? 0 : -1, + new MakefileTarget (targetType, *this)); }); // If you hit this assert, you tried to generate a project for an exporter @@ -441,50 +524,51 @@ private: result.set ("NDEBUG", "1"); } - result = mergePreprocessorDefs (result, getAllPreprocessorDefs (config, ProjectType::Target::unspecified)); + result = mergePreprocessorDefs (result, getAllPreprocessorDefs (config, build_tools::ProjectType::Target::unspecified)); return result; } - StringArray getPackages() const + StringArray getExtraPkgConfigPackages() const { - StringArray packages; - packages.addTokens (getExtraPkgConfigString(), " ", "\"'"); + auto packages = StringArray::fromTokens (extraPkgConfigValue.get().toString(), " ", "\"'"); packages.removeEmptyStrings(); - packages.addArray (linuxPackages); + return packages; + } - if (isWebBrowserComponentEnabled()) - { - packages.add ("webkit2gtk-4.0"); - packages.add ("gtk+-x11-3.0"); - } + StringArray getCompilePackages() const + { + auto packages = getLinuxPackages (PackageDependencyType::compile); + packages.addArray (getExtraPkgConfigPackages()); - // don't add libcurl if curl symbols are loaded at runtime - if (isCurlEnabled() && ! isLoadCurlSymbolsLazilyEnabled()) - packages.add ("libcurl"); + return packages; + } - packages.removeDuplicates (false); + StringArray getLinkPackages() const + { + auto packages = getLinuxPackages (PackageDependencyType::link); + packages.addArray (getExtraPkgConfigPackages()); return packages; } String getPreprocessorPkgConfigFlags() const { - auto packages = getPackages(); + auto compilePackages = getCompilePackages(); - if (packages.size() > 0) - return "$(shell pkg-config --cflags " + packages.joinIntoString (" ") + ")"; + if (compilePackages.size() > 0) + return "$(shell pkg-config --cflags " + compilePackages.joinIntoString (" ") + ")"; return {}; } String getLinkerPkgConfigFlags() const { - auto packages = getPackages(); + auto linkPackages = getLinkPackages(); - if (packages.size() > 0) - return "$(shell pkg-config --libs " + packages.joinIntoString (" ") + ")"; + if (linkPackages.size() > 0) + return "$(shell pkg-config --libs " + linkPackages.joinIntoString (" ") + ")"; return {}; } @@ -493,7 +577,7 @@ private: { StringArray result; - if (linuxLibs.contains("pthread")) + if (linuxLibs.contains ("pthread")) result.add ("-pthread"); return result; @@ -553,7 +637,7 @@ private: StringArray result; for (auto& path : searchPaths) - result.add (FileHelpers::unixStylePath (replacePreprocessorTokens (config, path))); + result.add (build_tools::unixStylePath (replacePreprocessorTokens (config, path))); return result; } @@ -585,8 +669,7 @@ private: { auto result = makefileExtraLinkerFlags; - if (! config.isDebug()) - result.add ("-fvisibility=hidden"); + result.add ("-fvisibility=hidden"); if (config.isLinkTimeOptimisationEnabled()) result.add ("-flto"); @@ -599,34 +682,10 @@ private: return result; } - bool isWebBrowserComponentEnabled() const - { - static String guiExtrasModule ("juce_gui_extra"); - - return (project.getEnabledModules().isModuleEnabled (guiExtrasModule) - && project.isConfigFlagEnabled ("JUCE_WEB_BROWSER", true)); - } - - bool isCurlEnabled() const - { - static String juceCoreModule ("juce_core"); - - return (project.getEnabledModules().isModuleEnabled (juceCoreModule) - && project.isConfigFlagEnabled ("JUCE_USE_CURL", true)); - } - - bool isLoadCurlSymbolsLazilyEnabled() const - { - static String juceCoreModule ("juce_core"); - - return (project.getEnabledModules().isModuleEnabled (juceCoreModule) - && project.isConfigFlagEnabled ("JUCE_LOAD_CURL_SYMBOLS_LAZILY", false)); - } - //============================================================================== void writeDefineFlags (OutputStream& out, const MakeBuildConfiguration& config) const { - out << createGCCPreprocessorFlags (mergePreprocessorDefs (getDefines (config), getAllPreprocessorDefs (config, ProjectType::Target::unspecified))); + out << createGCCPreprocessorFlags (mergePreprocessorDefs (getDefines (config), getAllPreprocessorDefs (config, build_tools::ProjectType::Target::unspecified))); } void writePkgConfigFlags (OutputStream& out) const @@ -692,7 +751,7 @@ private: { if (auto* target = targets.getUnchecked (i)) { - if (target->type == ProjectType::Target::AggregateTarget) + if (target->type == build_tools::ProjectType::Target::AggregateTarget) { StringArray dependencies; MemoryOutputStream subTargetLines; @@ -703,7 +762,7 @@ private: if (auto* dependency = targets.getUnchecked (j)) { - if (dependency->type != ProjectType::Target::SharedCodeTarget) + if (dependency->type != build_tools::ProjectType::Target::SharedCodeTarget) { auto phonyName = dependency->getPhonyName(); @@ -735,8 +794,8 @@ private: if (config.getTargetBinaryRelativePathString().isNotEmpty()) { - RelativePath binaryPath (config.getTargetBinaryRelativePathString(), RelativePath::projectFolder); - outputDir = binaryPath.rebased (projectFolder, getTargetFolder(), RelativePath::buildTargetFolder).toUnixStyle(); + build_tools::RelativePath binaryPath (config.getTargetBinaryRelativePathString(), build_tools::RelativePath::projectFolder); + outputDir = binaryPath.rebased (projectFolder, getTargetFolder(), build_tools::RelativePath::buildTargetFolder).toUnixStyle(); } out << "ifeq ($(CONFIG)," << escapeSpaces (config.getName()) << ")" << newLine @@ -797,7 +856,7 @@ private: { if (auto* target = targets.getUnchecked (i)) { - if (target->type == ProjectType::Target::AggregateTarget) + if (target->type == build_tools::ProjectType::Target::AggregateTarget) continue; out << "-include $(OBJECTS_" << target->getTargetVarName() @@ -899,7 +958,9 @@ private: writeCompilerFlagSchemes (out, filesToCompile); - auto getFilesForTarget = [] (const Array<std::pair<File, String>>& files, MakefileTarget* target, const Project& p) -> Array<std::pair<File, String>> + auto getFilesForTarget = [] (const Array<std::pair<File, String>>& files, + MakefileTarget* target, + const Project& p) -> Array<std::pair<File, String>> { Array<std::pair<File, String>> targetFiles; @@ -917,7 +978,7 @@ private: out << getPhonyTargetLine() << newLine << newLine; - writeTargetLines (out, getPackages()); + writeTargetLines (out, getLinkPackages()); for (auto target : targets) target->addFiles (out, getFilesForTarget (filesToCompile, target, project)); @@ -943,7 +1004,7 @@ private: return "-march=native"; } - String getObjectFileFor (const RelativePath& file) const + String getObjectFileFor (const build_tools::RelativePath& file) const { return file.getFileNameWithoutExtension() + "_" + String::toHexString (file.toUnixStyle().hashCode()) + ".o"; @@ -959,8 +1020,8 @@ private: return phonyTargetLine.toString(); for (auto target : targets) - if (target->type != ProjectType::Target::SharedCodeTarget - && target->type != ProjectType::Target::AggregateTarget) + if (target->type != build_tools::ProjectType::Target::SharedCodeTarget + && target->type != build_tools::ProjectType::Target::AggregateTarget) phonyTargetLine << " " << target->getPhonyName(); return phonyTargetLine.toString(); diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Xcode.h b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Xcode.h index a9c9cde9..f918ef0f 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Xcode.h +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Xcode.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -32,36 +31,76 @@ namespace { static const char* const iOSDefaultVersion = "9.3"; - static const StringArray iOSVersions { "7.0", "7.1", "8.0", "8.1", "8.2", "8.3", "8.4", - "9.0", "9.1", "9.2", "9.3", "10.0", "10.1", "10.2", "10.3", - "11.0", "12.0", "13.0" }; + static const StringArray iOSVersions { "9.0", "9.1", "9.2", "9.3", "10.0", "10.1", "10.2", "10.3", + "11.0", "12.0", "13.0", "14.0" }; + + enum class MacOSVersion + { + v10_7, + v10_8, + v10_9, + v10_10, + v10_11, + v10_12, + v10_13, + v10_14, + v10_15, + v10_16, + v11_0, + }; + + static const char* const getName (MacOSVersion m) + { + switch (m) + { + case MacOSVersion::v10_7: return "10.7"; + case MacOSVersion::v10_8: return "10.8"; + case MacOSVersion::v10_9: return "10.9"; + case MacOSVersion::v10_10: return "10.10"; + case MacOSVersion::v10_11: return "10.11"; + case MacOSVersion::v10_12: return "10.12"; + case MacOSVersion::v10_13: return "10.13"; + case MacOSVersion::v10_14: return "10.14"; + case MacOSVersion::v10_15: return "10.15"; + case MacOSVersion::v10_16: return "10.16"; + case MacOSVersion::v11_0: return "11.0"; + default: break; + } + + jassertfalse; + return ""; + } - static const int oldestDeploymentTarget = 7; - static const int defaultDeploymentTarget = 11; - static const int oldestSDKVersion = 11; - static const int currentSDKVersion = 15; - static const int minimumAUv3SDKVersion = 11; + static String getDisplayName (MacOSVersion m) { return getName (m) + String (" SDK"); } + static String getRootName (MacOSVersion m) { return String ("macosx") + getName (m); } - static String getVersionName (int version) { return "10." + String (version); } - static String getSDKDisplayName (int version) { return getVersionName (version) + " SDK"; } - static String getSDKRootName (int version) { return "macosx" + getVersionName (version); } + constexpr auto nextMacOSVersion = (MacOSVersion) ((int) MacOSVersion::v11_0 + 1); + constexpr auto oldestDeploymentTarget = MacOSVersion::v10_7; + constexpr auto macOSDefaultVersion = MacOSVersion::v10_11; + constexpr auto oldestSDKVersion = MacOSVersion::v10_11; + constexpr auto minimumAUv3SDKVersion = MacOSVersion::v10_11; + + static MacOSVersion& operator++ (MacOSVersion& m) + { + return m = (MacOSVersion) ((int) m + 1); + } static String getOSXSDKVersion (const String& sdkVersion) { - for (int v = oldestSDKVersion; v <= currentSDKVersion; ++v) - if (sdkVersion == getSDKDisplayName (v)) - return getSDKRootName (v); + for (auto v = oldestSDKVersion; v != nextMacOSVersion; ++v) + if (sdkVersion == getDisplayName (v)) + return getRootName (v); return "macosx"; } - template<class ContainerType> - static ContainerType getSDKChoiceList (int oldestVersion, bool displayName) + template <class ContainerType> + static ContainerType getSDKChoiceList (MacOSVersion oldestVersion, bool displayName) { ContainerType container; - for (int v = oldestVersion; v <= currentSDKVersion; ++v) - container.add (displayName ? getSDKDisplayName (v) : getVersionName (v)); + for (auto v = oldestVersion; v != nextMacOSVersion; ++v) + container.add (displayName ? getDisplayName (v) : getName (v)); return container; } @@ -78,9 +117,14 @@ class XcodeProjectExporter : public ProjectExporter { public: //============================================================================== - static const char* getNameMac() { return "Xcode (MacOSX)"; } - static const char* getNameiOS() { return "Xcode (iOS)"; } - static const char* getValueTreeTypeName (bool iOS) { return iOS ? "XCODE_IPHONE" : "XCODE_MAC"; } + static String getDisplayNameMac() { return "Xcode (macOS)"; } + static String getDisplayNameiOS() { return "Xcode (iOS)"; } + + static String getTargetFolderNameMac() { return "MacOSX"; } + static String getTargetFolderNameiOS() { return "iOS"; } + + static String getValueTreeTypeNameMac() { return "XCODE_MAC"; } + static String getValueTreeTypeNameiOS() { return "XCODE_IPHONE"; } //============================================================================== XcodeProjectExporter (Project& p, const ValueTree& t, const bool isIOS) @@ -91,6 +135,7 @@ public: pListPrefixHeaderValue (settings, Ids::pListPrefixHeader, getUndoManager()), pListPreprocessValue (settings, Ids::pListPreprocess, getUndoManager()), subprojectsValue (settings, Ids::xcodeSubprojects, getUndoManager()), + validArchsValue (settings, Ids::xcodeValidArchs, getUndoManager(), getAllArchs(), ","), extraFrameworksValue (settings, Ids::extraFrameworks, getUndoManager()), frameworkSearchPathsValue (settings, Ids::frameworkSearchPaths, getUndoManager()), extraCustomFrameworksValue (settings, Ids::extraCustomFrameworks, getUndoManager()), @@ -99,8 +144,8 @@ public: prebuildCommandValue (settings, Ids::prebuildCommand, getUndoManager()), duplicateAppExResourcesFolderValue (settings, Ids::duplicateAppExResourcesFolder, getUndoManager(), true), iosDeviceFamilyValue (settings, Ids::iosDeviceFamily, getUndoManager(), "1,2"), - iPhoneScreenOrientationValue (settings, Ids::iPhoneScreenOrientation, getUndoManager(), "portraitlandscape"), - iPadScreenOrientationValue (settings, Ids::iPadScreenOrientation, getUndoManager(), "portraitlandscape"), + iPhoneScreenOrientationValue (settings, Ids::iPhoneScreenOrientation, getUndoManager(), getDefaultScreenOrientations(), ","), + iPadScreenOrientationValue (settings, Ids::iPadScreenOrientation, getUndoManager(), getDefaultScreenOrientations(), ","), customXcodeResourceFoldersValue (settings, Ids::customXcodeResourceFolders, getUndoManager()), customXcassetsFolderValue (settings, Ids::customXcassetsFolder, getUndoManager()), appSandboxValue (settings, Ids::appSandbox, getUndoManager()), @@ -114,14 +159,18 @@ 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(), + bluetoothPermissionNeededValue (settings, Ids::iosBluetoothPermissionNeeded, getUndoManager()), + bluetoothPermissionTextValue (settings, Ids::iosBluetoothPermissionText, getUndoManager(), "This app requires access to Bluetooth to function correctly."), + sendAppleEventsPermissionNeededValue (settings, Ids::sendAppleEventsPermissionNeeded, getUndoManager()), + sendAppleEventsPermissionTextValue (settings, Ids::sendAppleEventsPermissionText, getUndoManager(), + "This app requires the ability to send Apple events to function correctly."), uiFileSharingEnabledValue (settings, Ids::UIFileSharingEnabled, getUndoManager()), uiSupportsDocumentBrowserValue (settings, Ids::UISupportsDocumentBrowser, getUndoManager()), uiStatusBarHiddenValue (settings, Ids::UIStatusBarHidden, getUndoManager()), documentExtensionsValue (settings, Ids::documentExtensions, getUndoManager()), iosInAppPurchasesValue (settings, Ids::iosInAppPurchases, getUndoManager()), + iosContentSharingValue (settings, Ids::iosContentSharing, getUndoManager(), true), iosBackgroundAudioValue (settings, Ids::iosBackgroundAudio, getUndoManager()), iosBackgroundBleValue (settings, Ids::iosBackgroundBle, getUndoManager()), iosPushNotificationsValue (settings, Ids::iosPushNotifications, getUndoManager()), @@ -132,82 +181,104 @@ public: keepCustomXcodeSchemesValue (settings, Ids::keepCustomXcodeSchemes, getUndoManager()), useHeaderMapValue (settings, Ids::useHeaderMap, getUndoManager()), customLaunchStoryboardValue (settings, Ids::customLaunchStoryboard, getUndoManager()), - exporterBundleIdentifierValue (settings, Ids::bundleIdentifier, getUndoManager()) + exporterBundleIdentifierValue (settings, Ids::bundleIdentifier, getUndoManager()), + suppressPlistResourceUsage (settings, Ids::suppressPlistResourceUsage, getUndoManager()) { - name = iOS ? getNameiOS() : getNameMac(); - - targetLocationValue.setDefault (getDefaultBuildsRootFolder() + getTargetFolderForExporter (getValueTreeTypeName (isIOS))); + if (iOS) + { + name = getDisplayNameiOS(); + targetLocationValue.setDefault (getDefaultBuildsRootFolder() + getTargetFolderNameiOS()); + } + else + { + name = getDisplayNameMac(); + targetLocationValue.setDefault (getDefaultBuildsRootFolder() + getTargetFolderNameMac()); + } } static XcodeProjectExporter* createForSettings (Project& projectToUse, const ValueTree& settingsToUse) { - if (settingsToUse.hasType (getValueTreeTypeName (false))) return new XcodeProjectExporter (projectToUse, settingsToUse, false); - if (settingsToUse.hasType (getValueTreeTypeName (true))) return new XcodeProjectExporter (projectToUse, settingsToUse, true); + if (settingsToUse.hasType (getValueTreeTypeNameMac())) return new XcodeProjectExporter (projectToUse, settingsToUse, false); + if (settingsToUse.hasType (getValueTreeTypeNameiOS())) return new XcodeProjectExporter (projectToUse, settingsToUse, true); return nullptr; } //============================================================================== - String getPListToMergeString() const { return customPListValue.get(); } - String getPListPrefixHeaderString() const { return pListPrefixHeaderValue.get(); } - bool isPListPreprocessEnabled() const { return pListPreprocessValue.get(); } + String getPListToMergeString() const { return customPListValue.get(); } + String getPListPrefixHeaderString() const { return pListPrefixHeaderValue.get(); } + bool isPListPreprocessEnabled() const { return pListPreprocessValue.get(); } + + String getSubprojectsString() const { return subprojectsValue.get(); } + + String getExtraFrameworksString() const { return extraFrameworksValue.get(); } + String getFrameworkSearchPathsString() const { return frameworkSearchPathsValue.get(); } + String getExtraCustomFrameworksString() const { return extraCustomFrameworksValue.get(); } + String getEmbeddedFrameworksString() const { return embeddedFrameworksValue.get(); } - String getSubprojectsString() const { return subprojectsValue.get(); } + String getPostBuildScript() const { return postbuildCommandValue.get(); } + String getPreBuildScript() const { return prebuildCommandValue.get(); } - String getExtraFrameworksString() const { return extraFrameworksValue.get(); } - String getFrameworkSearchPathsString() const { return frameworkSearchPathsValue.get(); } - String getExtraCustomFrameworksString() const { return extraCustomFrameworksValue.get(); } - String getEmbeddedFrameworksString() const { return embeddedFrameworksValue.get(); } + bool shouldDuplicateAppExResourcesFolder() const { return duplicateAppExResourcesFolderValue.get(); } - String getPostBuildScript() const { return postbuildCommandValue.get(); } - String getPreBuildScript() const { return prebuildCommandValue.get(); } + String getDeviceFamilyString() const { return iosDeviceFamilyValue.get(); } - bool shouldDuplicateAppExResourcesFolder() const { return duplicateAppExResourcesFolderValue.get(); } + Array<var> getDefaultScreenOrientations() const { return { "UIInterfaceOrientationPortrait", + "UIInterfaceOrientationLandscapeLeft", + "UIInterfaceOrientationLandscapeRight" }; } - String getDeviceFamilyString() const { return iosDeviceFamilyValue.get(); } + Array<var> getAllArchs() const { return { "i386", "x86_64", "arm64", "arm64e"}; } - String getiPhoneScreenOrientationString() const { return iPhoneScreenOrientationValue.get(); } - String getiPadScreenOrientationString() const { return iPadScreenOrientationValue.get(); } + Array<var> getiPhoneScreenOrientations() const { return *iPhoneScreenOrientationValue.get().getArray(); } + Array<var> getiPadScreenOrientations() const { return *iPadScreenOrientationValue.get().getArray(); } - String getCustomResourceFoldersString() const { return customXcodeResourceFoldersValue.get().toString().replaceCharacters ("\r\n", "::"); } - String getCustomXcassetsFolderString() const { return customXcassetsFolderValue.get(); } - String getCustomLaunchStoryboardString() const { return customLaunchStoryboardValue.get(); } - bool shouldAddStoryboardToProject() const { return getCustomLaunchStoryboardString().isNotEmpty() || getCustomXcassetsFolderString().isEmpty(); } + String getCustomResourceFoldersString() const { return customXcodeResourceFoldersValue.get().toString().replaceCharacters ("\r\n", "::"); } + String getCustomXcassetsFolderString() const { return customXcassetsFolderValue.get(); } + String getCustomLaunchStoryboardString() const { return customLaunchStoryboardValue.get(); } + bool shouldAddStoryboardToProject() const { return getCustomLaunchStoryboardString().isNotEmpty() || getCustomXcassetsFolderString().isEmpty(); } - bool isHardenedRuntimeEnabled() const { return hardenedRuntimeValue.get(); } - Array<var> getHardenedRuntimeOptions() const { return *hardenedRuntimeOptionsValue.get().getArray(); } + bool isHardenedRuntimeEnabled() const { return hardenedRuntimeValue.get(); } + Array<var> getHardenedRuntimeOptions() const { return *hardenedRuntimeOptionsValue.get().getArray(); } - bool isAppSandboxEnabled() const { return appSandboxValue.get(); } - bool isAppSandboxInhertianceEnabled() const { return appSandboxInheritanceValue.get(); } - Array<var> getAppSandboxOptions() const { return *appSandboxOptionsValue.get().getArray(); } + bool isAppSandboxEnabled() const { return appSandboxValue.get(); } + bool isAppSandboxInhertianceEnabled() const { return appSandboxInheritanceValue.get(); } + Array<var> getAppSandboxOptions() const { return *appSandboxOptionsValue.get().getArray(); } - bool isMicrophonePermissionEnabled() const { return microphonePermissionNeededValue.get(); } - String getMicrophonePermissionsTextString() const { return microphonePermissionsTextValue.get(); } + Array<var> getValidArchs() const { return *validArchsValue.get().getArray(); } - bool isCameraPermissionEnabled() const { return cameraPermissionNeededValue.get(); } - String getCameraPermissionTextString() const { return cameraPermissionTextValue.get(); } + bool isMicrophonePermissionEnabled() const { return microphonePermissionNeededValue.get(); } + String getMicrophonePermissionsTextString() const { return microphonePermissionsTextValue.get(); } - bool isBluetoothPermissionEnabled() const { return iosBluetoothPermissionNeededValue.get(); } - String getBluetoothPermissionTextString() const { return iosBluetoothPermissionTextValue.get(); } + bool isCameraPermissionEnabled() const { return cameraPermissionNeededValue.get(); } + String getCameraPermissionTextString() const { return cameraPermissionTextValue.get(); } - bool isInAppPurchasesEnabled() const { return iosInAppPurchasesValue.get(); } - bool isBackgroundAudioEnabled() const { return iosBackgroundAudioValue.get(); } - bool isBackgroundBleEnabled() const { return iosBackgroundBleValue.get(); } - bool isPushNotificationsEnabled() const { return iosPushNotificationsValue.get(); } - bool isAppGroupsEnabled() const { return iosAppGroupsValue.get(); } - bool isiCloudPermissionsEnabled() const { return iCloudPermissionsValue.get(); } - bool isFileSharingEnabled() const { return uiFileSharingEnabledValue.get(); } - bool isDocumentBrowserEnabled() const { return uiSupportsDocumentBrowserValue.get(); } - bool isStatusBarHidden() const { return uiStatusBarHiddenValue.get(); } + bool isBluetoothPermissionEnabled() const { return bluetoothPermissionNeededValue.get(); } + String getBluetoothPermissionTextString() const { return bluetoothPermissionTextValue.get(); } - String getDocumentExtensionsString() const { return documentExtensionsValue.get(); } + bool isSendAppleEventsPermissionEnabled() const { return sendAppleEventsPermissionNeededValue.get(); } + String getSendAppleEventsPermissionTextString() const { return sendAppleEventsPermissionTextValue.get(); } - bool shouldKeepCustomXcodeSchemes() const { return keepCustomXcodeSchemesValue.get(); } + bool isInAppPurchasesEnabled() const { return iosInAppPurchasesValue.get(); } + bool isContentSharingEnabled() const { return iosContentSharingValue.get(); } + bool isBackgroundAudioEnabled() const { return iosBackgroundAudioValue.get(); } + bool isBackgroundBleEnabled() const { return iosBackgroundBleValue.get(); } + bool isPushNotificationsEnabled() const { return iosPushNotificationsValue.get(); } + bool isAppGroupsEnabled() const { return iosAppGroupsValue.get(); } + bool isiCloudPermissionsEnabled() const { return iCloudPermissionsValue.get(); } + bool isFileSharingEnabled() const { return uiFileSharingEnabledValue.get(); } + bool isDocumentBrowserEnabled() const { return uiSupportsDocumentBrowserValue.get(); } + bool isStatusBarHidden() const { return uiStatusBarHiddenValue.get(); } - String getDevelopmentTeamIDString() const { return iosDevelopmentTeamIDValue.get(); } - String getAppGroupIdString() const { return iosAppGroupsIDValue.get(); } + bool getSuppressPlistResourceUsage() const { return suppressPlistResourceUsage.get(); } - String getDefaultLaunchStoryboardName() const { jassert (iOS); return "LaunchScreen"; } + String getDocumentExtensionsString() const { return documentExtensionsValue.get(); } + + bool shouldKeepCustomXcodeSchemes() const { return keepCustomXcodeSchemesValue.get(); } + + String getDevelopmentTeamIDString() const { return iosDevelopmentTeamIDValue.get(); } + String getAppGroupIdString() const { return iosAppGroupsIDValue.get(); } + + String getDefaultLaunchStoryboardName() const { return "LaunchScreen"; } //============================================================================== bool usesMMFiles() const override { return true; } @@ -227,26 +298,31 @@ public: bool isOSX() const override { return ! iOS; } bool isiOS() const override { return iOS; } - bool supportsTargetType (ProjectType::Target::Type type) const override + bool supportsPrecompiledHeaders() const override { return true; } + + String getNewLineString() const override { return "\n"; } + + bool supportsTargetType (build_tools::ProjectType::Target::Type type) const override { switch (type) { - case ProjectType::Target::AudioUnitv3PlugIn: - case ProjectType::Target::StandalonePlugIn: - case ProjectType::Target::GUIApp: - case ProjectType::Target::StaticLibrary: - case ProjectType::Target::DynamicLibrary: - case ProjectType::Target::SharedCodeTarget: - case ProjectType::Target::AggregateTarget: + case build_tools::ProjectType::Target::AudioUnitv3PlugIn: + case build_tools::ProjectType::Target::StandalonePlugIn: + case build_tools::ProjectType::Target::GUIApp: + case build_tools::ProjectType::Target::StaticLibrary: + case build_tools::ProjectType::Target::DynamicLibrary: + case build_tools::ProjectType::Target::SharedCodeTarget: + case build_tools::ProjectType::Target::AggregateTarget: return true; - case ProjectType::Target::ConsoleApp: - case ProjectType::Target::VSTPlugIn: - case ProjectType::Target::VST3PlugIn: - case ProjectType::Target::AAXPlugIn: - case ProjectType::Target::RTASPlugIn: - case ProjectType::Target::AudioUnitPlugIn: - case ProjectType::Target::UnityPlugIn: + case build_tools::ProjectType::Target::ConsoleApp: + case build_tools::ProjectType::Target::VSTPlugIn: + case build_tools::ProjectType::Target::VST3PlugIn: + case build_tools::ProjectType::Target::AAXPlugIn: + case build_tools::ProjectType::Target::RTASPlugIn: + case build_tools::ProjectType::Target::AudioUnitPlugIn: + case build_tools::ProjectType::Target::UnityPlugIn: return ! iOS; + case build_tools::ProjectType::Target::unspecified: default: break; } @@ -287,15 +363,16 @@ public: "The device family to target."); { - StringArray orientationStrings { "Portrait and Landscape", "Portrait", "Landscape" }; - Array<var> orientationValues { "portraitlandscape", "portrait", "landscape"}; + StringArray orientationStrings { "Portrait", "Portrait Upside Down", + "Landscape Left", "Landscape Right" }; + + Array<var> orientationVars { "UIInterfaceOrientationPortrait", "UIInterfaceOrientationPortraitUpsideDown", + "UIInterfaceOrientationLandscapeLeft", "UIInterfaceOrientationLandscapeRight" }; - props.add (new ChoicePropertyComponent (iPhoneScreenOrientationValue, "iPhone Screen Orientation", - orientationStrings, orientationValues), + props.add (new MultiChoicePropertyComponent (iPhoneScreenOrientationValue, "iPhone Screen Orientation", orientationStrings, orientationVars), "The screen orientations that this app should support on iPhones."); - props.add (new ChoicePropertyComponent (iPadScreenOrientationValue, "iPad Screen Orientation", - orientationStrings, orientationValues), + props.add (new MultiChoicePropertyComponent (iPadScreenOrientationValue, "iPad Screen Orientation", orientationStrings, orientationVars), "The screen orientations that this app should support on iPads."); } @@ -317,6 +394,10 @@ public: if (isOSX()) { + props.add (new MultiChoicePropertyComponent (validArchsValue, "Valid Architectures", getAllArchs(), getAllArchs()), + "The full set of architectures which this project may target. " + "Each configuration will build for the intersection of this property, and the per-configuration macOS Architecture property"); + props.add (new ChoicePropertyComponent (appSandboxValue, "Use App Sandbox"), "Enable this to use the app sandbox."); @@ -431,15 +512,23 @@ public: "Camera Access Text", 1024, false), "A short description of why your app requires camera access."); - if (iOS) + props.add (new ChoicePropertyComponent (bluetoothPermissionNeededValue, "Bluetooth Access"), + "Enable this to allow your app to use Bluetooth on iOS 13.0 and above, and macOS 11.0 and above. " + "The user of your app will be prompted to grant Bluetooth access permissions."); + + props.add (new TextPropertyComponentWithEnablement (bluetoothPermissionTextValue, bluetoothPermissionNeededValue, + "Bluetooth Access Text", 1024, false), + "A short description of why your app requires Bluetooth 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 ChoicePropertyComponent (sendAppleEventsPermissionNeededValue, "Send Apple Events"), + "Enable this to allow your app to send Apple events. " + "The user of your app will be prompted to grant permissions to control other apps."); - props.add (new TextPropertyComponentWithEnablement (iosBluetoothPermissionTextValue, iosBluetoothPermissionNeededValue, - "Bluetooth Access Text", 1024, false), - "A short description of why your app requires Bluetooth access."); + props.add (new TextPropertyComponentWithEnablement (sendAppleEventsPermissionTextValue, sendAppleEventsPermissionNeededValue, + "Send Apple Events Text", 1024, false), + "A short description of why your app requires the ability to send Apple events."); } props.add (new ChoicePropertyComponent (iosInAppPurchasesValue, "In-App Purchases Capability"), @@ -448,6 +537,9 @@ public: if (iOS) { + props.add (new ChoicePropertyComponent (iosContentSharingValue, "Content Sharing"), + "Enable this to allow your app to share content with other apps."); + props.add (new ChoicePropertyComponent (iosBackgroundAudioValue, "Audio Background Capability"), "Enable this to grant your app the capability to access audio when in background mode. " "This permission is required if your app creates a MIDI input or output device."); @@ -478,6 +570,12 @@ public: props.add (new TextPropertyComponent (pListPrefixHeaderValue, "PList Prefix Header", 512, false), "Header file containing definitions used in plist file (see PList Preprocess)."); + props.add (new ChoicePropertyComponent (suppressPlistResourceUsage, "Suppress AudioUnit Plist resourceUsage Key"), + "Suppress the resourceUsage key in the target's generated Plist. This is useful for AU" + " plugins that must access resources which cannot be declared in the resourceUsage block, such" + " as UNIX domain sockets. In particular, PACE-protected AU plugins may require this option to be enabled" + " in order for the plugin to load in GarageBand."); + props.add (new TextPropertyComponent (extraFrameworksValue, "Extra System Frameworks", 2048, false), "A comma-separated list of extra system frameworks that should be added to the build. " "(Don't include the .framework extension in the name)" @@ -497,6 +595,7 @@ public: props.add (new TextPropertyComponent (subprojectsValue, "Xcode Subprojects", 8192, true), "Paths to Xcode projects that should be added to the build (one per line). " + "These can be absolute or relative to the build directory. " "The names of the required build products can be specified after a colon, comma separated, " "e.g. \"path/to/MySubProject.xcodeproj: MySubProject, OtherTarget\". " "If no build products are specified, all build products associated with a subproject will be added."); @@ -565,13 +664,8 @@ public: createObjects(); - auto projectFile = projectBundle.getChildFile ("project.pbxproj"); - - { - MemoryOutputStream mo; - writeProjectFile (mo); - overwriteFileIfDifferentOrThrow (projectFile, mo); - } + build_tools::writeStreamToFile (projectBundle.getChildFile ("project.pbxproj"), + [this] (MemoryOutputStream& mo) { writeProjectFile (mo); }); writeInfoPlistFiles(); @@ -584,17 +678,12 @@ public: } //============================================================================== - void addPlatformSpecificSettingsForProjectType (const ProjectType&) override + void addPlatformSpecificSettingsForProjectType (const build_tools::ProjectType&) override { - callForAllSupportedTargets ([this] (ProjectType::Target::Type targetType) + callForAllSupportedTargets ([this] (build_tools::ProjectType::Target::Type targetType) { - if (auto* target = new XcodeTarget (targetType, *this)) - { - if (targetType == ProjectType::Target::AggregateTarget) - targets.insert (0, target); - else - targets.add (target); - } + targets.insert (targetType == build_tools::ProjectType::Target::AggregateTarget ? 0 : -1, + new XcodeTarget (targetType, *this)); }); // If you hit this assert, you tried to generate a project for an exporter @@ -602,12 +691,18 @@ public: jassert (targets.size() > 0); } - void updateDeprecatedProjectSettingsInteractively() override + void updateDeprecatedSettings() override + { + if (iOS) + updateOldOrientationSettings(); + } + + void updateDeprecatedSettingsInteractively() override { if (hasInvalidPostBuildScript()) { String alertWindowText = iOS ? "Your Xcode (iOS) Exporter settings use an invalid post-build script. Click 'Update' to remove it." - : "Your Xcode (OSX) Exporter settings use a pre-JUCE 4.2 post-build script to move the plug-in binaries to their plug-in install folders.\n\n" + : "Your Xcode (macOS) Exporter settings use a pre-JUCE 4.2 post-build script to move the plug-in binaries to their plug-in install folders.\n\n" "Since JUCE 4.2, this is instead done using \"AU/VST/VST2/AAX/RTAS Binary Location\" in the Xcode (OS X) configuration settings.\n\n" "Click 'Update' to remove the script (otherwise your plug-in may not compile correctly)."; @@ -630,9 +725,6 @@ public: vstLegacyPathValueWrapper.init ({ settings, Ids::vstLegacyFolder, nullptr }, getAppSettings().getStoredPath (Ids::vstLegacyPath, TargetOS::osx), TargetOS::osx); - vst3PathValueWrapper.init ({ settings, Ids::vst3Folder, nullptr }, - getAppSettings().getStoredPath (Ids::vst3Path, TargetOS::osx), TargetOS::osx); - aaxPathValueWrapper.init ({ settings, Ids::aaxFolder, nullptr }, getAppSettings().getStoredPath (Ids::aaxPath, TargetOS::osx), TargetOS::osx); @@ -649,7 +741,7 @@ protected: : BuildConfiguration (p, t, e), iOS (isIOS), osxSDKVersion (config, Ids::osxSDK, getUndoManager()), - osxDeploymentTarget (config, Ids::osxCompatibility, getUndoManager(), getSDKDisplayName (defaultDeploymentTarget)), + osxDeploymentTarget (config, Ids::osxCompatibility, getUndoManager(), getDisplayName (macOSDefaultVersion)), iosDeploymentTarget (config, Ids::iosCompatibility, getUndoManager(), iOSDefaultVersion), osxArchitecture (config, Ids::osxArchitecture, getUndoManager(), osxArch_Default), customXcodeFlags (config, Ids::customXcodeFlags, getUndoManager()), @@ -692,23 +784,23 @@ protected: } else { - props.add (new ChoicePropertyComponent (osxSDKVersion, "OSX Base SDK Version", getSDKChoiceList<StringArray> (oldestSDKVersion, true), - getSDKChoiceList<Array<var>> (oldestSDKVersion, true)), + props.add (new ChoicePropertyComponent (osxSDKVersion, "macOS Base SDK Version", getSDKChoiceList<StringArray> (oldestSDKVersion, true), + getSDKChoiceList<Array<var>> (oldestSDKVersion, true)), "The version of the macOS SDK to link against. If \"Default\" is selected then the Xcode default will be used."); - props.add (new ChoicePropertyComponent (osxDeploymentTarget, "OSX Deployment Target", getSDKChoiceList<StringArray> (oldestDeploymentTarget, false), - getSDKChoiceList<Array<var>> (oldestDeploymentTarget, true)), - "The minimum version of OSX that the target binary will be compatible with."); + props.add (new ChoicePropertyComponent (osxDeploymentTarget, "macOS Deployment Target", getSDKChoiceList<StringArray> (oldestDeploymentTarget, false), + getSDKChoiceList<Array<var>> (oldestDeploymentTarget, true)), + "The minimum version of macOS that the target binary will be compatible with."); - props.add (new ChoicePropertyComponent (osxArchitecture, "OSX Architecture", - { "Native architecture of build machine", "Universal Binary (32-bit)", "Universal Binary (32/64-bit)", "64-bit Intel" }, - { osxArch_Native, osxArch_32BitUniversal, osxArch_64BitUniversal, osxArch_64Bit }), - "The type of OSX binary that will be produced."); + props.add (new ChoicePropertyComponent (osxArchitecture, "macOS Architecture", + { "Native architecture of build machine", "Standard 32-bit", "Standard 32/64-bit", "Standard 64-bit" }, + { osxArch_Native, osxArch_32BitUniversal, osxArch_64BitUniversal, osxArch_64Bit }), + "The type of macOS binary that will be produced."); } props.add (new TextPropertyComponent (customXcodeFlags, "Custom Xcode Flags", 8192, true), "A comma-separated list of custom Xcode setting flags which will be appended to the list of generated flags, " - "e.g. MACOSX_DEPLOYMENT_TARGET_i386 = 10.5, VALID_ARCHS = \"ppc i386 x86_64\""); + "e.g. MACOSX_DEPLOYMENT_TARGET_i386 = 10.5"); props.add (new TextPropertyComponent (plistPreprocessorDefinitions, "PList Preprocessor Definitions", 2048, true), "Preprocessor definitions used during PList preprocessing (see PList Preprocess)."); @@ -850,18 +942,16 @@ public: }; //============================================================================== - struct XcodeTarget : ProjectType::Target + struct XcodeTarget : build_tools::ProjectType::Target { //============================================================================== - XcodeTarget (ProjectType::Target::Type targetType, const XcodeProjectExporter& exporter) - : ProjectType::Target (targetType), + XcodeTarget (build_tools::ProjectType::Target::Type targetType, const XcodeProjectExporter& exporter) + : Target (targetType), owner (exporter) { switch (type) { case GUIApp: - xcodePackageType = "APPL"; - xcodeBundleSignature = "????"; xcodeFileType = "wrapper.application"; xcodeBundleExtension = ".app"; xcodeProductType = "com.apple.product-type.application"; @@ -890,8 +980,6 @@ public: break; case VSTPlugIn: - xcodePackageType = "BNDL"; - xcodeBundleSignature = "????"; xcodeFileType = "wrapper.cfbundle"; xcodeBundleExtension = ".vst"; xcodeProductType = "com.apple.product-type.bundle"; @@ -899,8 +987,6 @@ public: break; case VST3PlugIn: - xcodePackageType = "BNDL"; - xcodeBundleSignature = "????"; xcodeFileType = "wrapper.cfbundle"; xcodeBundleExtension = ".vst3"; xcodeProductType = "com.apple.product-type.bundle"; @@ -908,8 +994,6 @@ public: break; case AudioUnitPlugIn: - xcodePackageType = "BNDL"; - xcodeBundleSignature = "????"; xcodeFileType = "wrapper.cfbundle"; xcodeBundleExtension = ".component"; xcodeProductType = "com.apple.product-type.bundle"; @@ -919,8 +1003,6 @@ public: break; case StandalonePlugIn: - xcodePackageType = "APPL"; - xcodeBundleSignature = "????"; xcodeFileType = "wrapper.application"; xcodeBundleExtension = ".app"; xcodeProductType = "com.apple.product-type.application"; @@ -928,8 +1010,6 @@ public: break; case AudioUnitv3PlugIn: - xcodePackageType = "XPC!"; - xcodeBundleSignature = "????"; xcodeFileType = "wrapper.app-extension"; xcodeBundleExtension = ".appex"; xcodeBundleIDSubPath = "AUv3"; @@ -940,8 +1020,6 @@ public: break; case AAXPlugIn: - xcodePackageType = "TDMw"; - xcodeBundleSignature = "PTul"; xcodeFileType = "wrapper.cfbundle"; xcodeBundleExtension = ".aaxplugin"; xcodeProductType = "com.apple.product-type.bundle"; @@ -949,8 +1027,6 @@ public: break; case RTASPlugIn: - xcodePackageType = "TDMw"; - xcodeBundleSignature = "PTul"; xcodeFileType = "wrapper.cfbundle"; xcodeBundleExtension = ".dpm"; xcodeProductType = "com.apple.product-type.bundle"; @@ -958,8 +1034,6 @@ public: break; case UnityPlugIn: - xcodePackageType = "BNDL"; - xcodeBundleSignature = "????"; xcodeFileType = "wrapper.cfbundle"; xcodeBundleExtension = ".bundle"; xcodeProductType = "com.apple.product-type.bundle"; @@ -977,6 +1051,7 @@ public: xcodeCopyToProductInstallPathAfterBuild = false; break; + case unspecified: default: // unknown target type! jassertfalse; @@ -1004,21 +1079,21 @@ public: return String (getName()).replace (" ", "_") + String (".entitlements"); } - String xcodePackageType, xcodeBundleSignature, xcodeBundleExtension; + String xcodeBundleExtension; String xcodeProductType, xcodeFileType; String xcodeOtherRezFlags, xcodeBundleIDSubPath; bool xcodeCopyToProductInstallPathAfterBuild; StringArray xcodeFrameworks, xcodeLibs; Array<XmlElement> xcodeExtraPListEntries; - StringArray frameworkIDs, buildPhaseIDs, configIDs, sourceIDs, rezFileIDs; + StringArray frameworkIDs, buildPhaseIDs, configIDs, sourceIDs, rezFileIDs, dependencyIDs; StringArray frameworkNames; - String dependencyID, mainBuildProductID; + String mainBuildProductID; File infoPlistFile; struct SourceFileInfo { - RelativePath path; + build_tools::RelativePath path; bool shouldBeCompiled = false; }; @@ -1038,9 +1113,11 @@ public: { SourceFileInfo info; - info.path = RelativePath (projectItem.getFile(), owner.getTargetFolder(), RelativePath::buildTargetFolder); + info.path = build_tools::RelativePath (projectItem.getFile(), + owner.getTargetFolder(), + build_tools::RelativePath::buildTargetFolder); - jassert (info.path.getRoot() == RelativePath::buildTargetFolder); + jassert (info.path.getRoot() == build_tools::RelativePath::buildTargetFolder); if (targetType == SharedCodeTarget || projectItem.shouldBeCompiled()) info.shouldBeCompiled = projectItem.shouldBeCompiled(); @@ -1057,7 +1134,7 @@ public: jassert (xcodeFileType.isNotEmpty()); jassert (xcodeBundleExtension.isEmpty() || xcodeBundleExtension.startsWithChar ('.')); - if (ProjectExporter::BuildConfiguration::Ptr config = owner.getConfiguration(0)) + if (ProjectExporter::BuildConfiguration::Ptr config = owner.getConfiguration (0)) { auto productName = owner.replacePreprocessorTokens (*config, config->getTargetBinaryNameString (type == UnityPlugIn)); @@ -1083,24 +1160,42 @@ public: } //============================================================================== - void addDependency() + String addDependencyFor (const XcodeTarget& dependentTarget) { - jassert (dependencyID.isEmpty()); - - dependencyID = owner.createID (String ("__dependency") + getName()); + auto dependencyID = owner.createID (String ("__dependency") + getName() + dependentTarget.getName()); auto* v = new ValueTree (dependencyID); v->setProperty ("isa", "PBXTargetDependency", nullptr); v->setProperty ("target", getID(), nullptr); - owner.misc.add (v); + owner.pbxTargetDependencies.add (v); + return dependencyID; } - String getDependencyID() const + void addDependencies() { - jassert (dependencyID.isNotEmpty()); + if (! owner.project.isAudioPluginProject()) + return; - return dependencyID; + if (type == XcodeTarget::StandalonePlugIn) // depends on AUv3 and shared code + { + if (auto* auv3Target = owner.getTargetOfType (XcodeTarget::AudioUnitv3PlugIn)) + dependencyIDs.add (auv3Target->addDependencyFor (*this)); + + if (auto* sharedCodeTarget = owner.getTargetOfType (XcodeTarget::SharedCodeTarget)) + dependencyIDs.add (sharedCodeTarget->addDependencyFor (*this)); + } + else if (type == XcodeTarget::AggregateTarget) // depends on all other targets + { + for (auto* target : owner.targets) + if (target->type != XcodeTarget::AggregateTarget) + dependencyIDs.add (target->addDependencyFor (*this)); + } + else if (type != XcodeTarget::SharedCodeTarget) // shared code doesn't depend on anything; all other targets depend only on the shared code + { + if (auto* sharedCodeTarget = owner.getTargetOfType (XcodeTarget::SharedCodeTarget)) + dependencyIDs.add (sharedCodeTarget->addDependencyFor (*this)); + } } //============================================================================== @@ -1222,6 +1317,33 @@ public: return bundleIdentifier; } + StringPairArray getConfigPreprocessorDefs (const XcodeBuildConfiguration& config) const + { + StringPairArray defines; + + if (config.isDebug()) + { + defines.set ("_DEBUG", "1"); + defines.set ("DEBUG", "1"); + } + else + { + defines.set ("_NDEBUG", "1"); + defines.set ("NDEBUG", "1"); + } + + if (owner.isInAppPurchasesEnabled()) + defines.set ("JUCE_IN_APP_PURCHASES", "1"); + + if (owner.iOS && owner.isContentSharingEnabled()) + defines.set ("JUCE_CONTENT_SHARING", "1"); + + if (owner.isPushNotificationsEnabled()) + defines.set ("JUCE_PUSH_NOTIFICATIONS", "1"); + + return mergePreprocessorDefs (defines, owner.getAllPreprocessorDefs (config, type)); + } + //============================================================================== StringPairArray getTargetSettings (const XcodeBuildConfiguration& config) const { @@ -1248,7 +1370,25 @@ public: else if (arch == osxArch_64BitUniversal) s.set ("ARCHS", "\"$(ARCHS_STANDARD_32_64_BIT)\""); else if (arch == osxArch_64Bit) s.set ("ARCHS", "\"$(ARCHS_STANDARD_64_BIT)\""); + if (! owner.isiOS()) + { + auto validArchs = owner.getValidArchs(); + + if (! validArchs.isEmpty()) + { + const auto joined = std::accumulate (validArchs.begin(), + validArchs.end(), + String(), + [] (String str, const var& v) { return str + v.toString() + " "; }); + + s.set ("VALID_ARCHS", joined.trim().quoted()); + } + } + StringArray headerPaths (getHeaderSearchPaths (config)); + + s.set ("MTL_HEADER_SEARCH_PATHS", indentParenthesisedList (headerPaths, 1)); + headerPaths.add ("\"$(inherited)\""); s.set ("HEADER_SEARCH_PATHS", indentParenthesisedList (headerPaths, 1)); s.set ("USE_HEADERMAP", String (static_cast<bool> (config.exporter.settings.getProperty ("useHeaderMap")) ? "YES" : "NO")); @@ -1260,6 +1400,23 @@ public: s.set ("GCC_OPTIMIZATION_LEVEL", config.getGCCOptimisationFlag()); + if (config.shouldUsePrecompiledHeaderFile()) + { + s.set ("GCC_PRECOMPILE_PREFIX_HEADER", "YES"); + + auto pchFileContent = config.getPrecompiledHeaderFileContent(); + + if (pchFileContent.isNotEmpty()) + { + auto pchFilename = config.getPrecompiledHeaderFilename() + ".h"; + + build_tools::writeStreamToFile (owner.getTargetFolder().getChildFile (pchFilename), + [&] (MemoryOutputStream& mo) { mo << pchFileContent; }); + + s.set ("GCC_PREFIX_HEADER", pchFilename); + } + } + if (shouldCreatePList()) { s.set ("INFOPLIST_FILE", infoPlistFile.getFileName()); @@ -1341,8 +1498,11 @@ public: // (= for audio plug-ins) or using a custom binary path (for everything else), but not both (= conflict!) jassert (! xcodeCopyToProductInstallPathAfterBuild); - RelativePath binaryPath (config.getTargetBinaryRelativePathString(), RelativePath::projectFolder); - configurationBuildDir = sanitisePath (binaryPath.rebased (owner.projectFolder, owner.getTargetFolder(), RelativePath::buildTargetFolder) + build_tools::RelativePath binaryPath (config.getTargetBinaryRelativePathString(), + build_tools::RelativePath::projectFolder); + configurationBuildDir = sanitisePath (binaryPath.rebased (owner.projectFolder, + owner.getTargetFolder(), + build_tools::RelativePath::buildTargetFolder) .toUnixStyle()); } @@ -1414,52 +1574,38 @@ public: libPaths.add ("\"\\\"" + p + "\\\"\""); s.set ("LIBRARY_SEARCH_PATHS", indentParenthesisedList (libPaths, 1)); - } } - StringPairArray defines; - if (config.isDebug()) { - defines.set ("_DEBUG", "1"); - defines.set ("DEBUG", "1"); s.set ("COPY_PHASE_STRIP", "NO"); s.set ("GCC_DYNAMIC_NO_PIC", "NO"); } else { - defines.set ("_NDEBUG", "1"); - defines.set ("NDEBUG", "1"); s.set ("GCC_GENERATE_DEBUGGING_SYMBOLS", "NO"); - s.set ("GCC_SYMBOLS_PRIVATE_EXTERN", "YES"); s.set ("DEAD_CODE_STRIPPING", "YES"); } if (type != Target::SharedCodeTarget && type != Target::StaticLibrary && type != Target::DynamicLibrary - && config.isStripLocalSymbolsEnabled()) + && config.isStripLocalSymbolsEnabled()) { s.set ("STRIPFLAGS", "\"-x\""); s.set ("DEPLOYMENT_POSTPROCESSING", "YES"); s.set ("SEPARATE_STRIP", "YES"); } - if (owner.isInAppPurchasesEnabled()) - defines.set ("JUCE_IN_APP_PURCHASES", "1"); - - if (owner.isPushNotificationsEnabled()) - defines.set ("JUCE_PUSH_NOTIFICATIONS", "1"); - - defines = mergePreprocessorDefs (defines, owner.getAllPreprocessorDefs (config, type)); - StringArray defsList; + const auto defines = getConfigPreprocessorDefs (config); + for (int i = 0; i < defines.size(); ++i) { auto def = defines.getAllKeys()[i]; auto value = defines.getAllValues()[i]; if (value.isNotEmpty()) - def << "=" << value.replace ("\"", "\\\\\\\""); + def << "=" << value.replace ("\"", "\\\\\\\"").replace (" ", "\\\\ "); defsList.add ("\"" + def + "\""); } @@ -1492,6 +1638,12 @@ public: case AAXPlugIn: return config.isPluginBinaryCopyStepEnabled() ? config.getAAXBinaryLocationString() : String(); case UnityPlugIn: return config.isPluginBinaryCopyStepEnabled() ? config.getUnityPluginBinaryLocationString() : String(); case SharedCodeTarget: return owner.isiOS() ? "@executable_path/Frameworks" : "@executable_path/../Frameworks"; + case StaticLibrary: + case DynamicLibrary: + case AudioUnitv3PlugIn: + case StandalonePlugIn: + case AggregateTarget: + case unspecified: default: return {}; } } @@ -1504,7 +1656,7 @@ public: if (type != Target::SharedCodeTarget) { - Array<RelativePath> extraLibs; + Array<build_tools::RelativePath> extraLibs; addExtraLibsForTargetType (config, extraLibs); @@ -1520,7 +1672,7 @@ public: { auto productName = getStaticLibbedFilename (owner.replacePreprocessorTokens (config, config.getTargetBinaryNameString())); - RelativePath sharedCodelib (productName, RelativePath::buildTargetFolder); + build_tools::RelativePath sharedCodelib (productName, build_tools::RelativePath::buildTargetFolder); flags.add (getLinkerFlagForLib (sharedCodelib.getFileNameWithoutExtension())); } } @@ -1538,188 +1690,70 @@ public: flags = getCleanedStringArray (flags); } - //========================================================================== c + //========================================================================== void writeInfoPlistFile() const { if (! shouldCreatePList()) return; - auto plist = parseXML (owner.getPListToMergeString()); - - if (plist == nullptr || ! plist->hasTagName ("plist")) - plist.reset (new XmlElement ("plist")); - - auto* dict = plist->getChildByName ("dict"); - - if (dict == nullptr) - dict = plist->createNewChildElement ("dict"); - - if (owner.isMicrophonePermissionEnabled()) - addPlistDictionaryKey (dict, "NSMicrophoneUsageDescription", owner.getMicrophonePermissionsTextString()); - - if (owner.isCameraPermissionEnabled()) - addPlistDictionaryKey (dict, "NSCameraUsageDescription", owner.getCameraPermissionTextString()); - - 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) - addPlistDictionaryKeyBool (dict, "UIViewControllerBasedStatusBarAppearance", false); - - if (owner.shouldAddStoryboardToProject()) - { - auto customStoryboard = owner.getCustomLaunchStoryboardString(); - - addPlistDictionaryKey (dict, "UILaunchStoryboardName", customStoryboard.isNotEmpty() ? customStoryboard.fromLastOccurrenceOf ("/", false, false) - .upToLastOccurrenceOf (".storyboard", false, false) - : owner.getDefaultLaunchStoryboardName()); - } - } - - addPlistDictionaryKey (dict, "CFBundleExecutable", "${EXECUTABLE_NAME}"); - - if (! owner.iOS) // (NB: on iOS this causes error ITMS-90032 during publishing) - addPlistDictionaryKey (dict, "CFBundleIconFile", owner.iconFile.exists() ? owner.iconFile.getFileName() : String()); - - addPlistDictionaryKey (dict, "CFBundleIdentifier", getBundleIdentifier()); - addPlistDictionaryKey (dict, "CFBundleName", owner.projectName); - - // needed by NSExtension on iOS - addPlistDictionaryKey (dict, "CFBundleDisplayName", owner.projectName); - addPlistDictionaryKey (dict, "CFBundlePackageType", xcodePackageType); - addPlistDictionaryKey (dict, "CFBundleSignature", xcodeBundleSignature); - addPlistDictionaryKey (dict, "CFBundleShortVersionString", owner.project.getVersionString()); - addPlistDictionaryKey (dict, "CFBundleVersion", owner.project.getVersionString()); - addPlistDictionaryKey (dict, "NSHumanReadableCopyright", owner.project.getCompanyCopyrightString()); - addPlistDictionaryKeyBool (dict, "NSHighResolutionCapable", true); - - auto documentExtensions = StringArray::fromTokens (replacePreprocessorDefs (owner.getAllPreprocessorDefs(), - owner.getDocumentExtensionsString()), ",", {}); - documentExtensions.trim(); - documentExtensions.removeEmptyStrings (true); - - if (documentExtensions.size() > 0 && type != AudioUnitv3PlugIn) - { - dict->createNewChildElement ("key")->addTextElement ("CFBundleDocumentTypes"); - auto* dict2 = dict->createNewChildElement ("array")->createNewChildElement ("dict"); - XmlElement* arrayTag = nullptr; - - for (auto ex : documentExtensions) - { - if (ex.startsWithChar ('.')) - ex = ex.substring (1); - - if (arrayTag == nullptr) - { - dict2->createNewChildElement ("key")->addTextElement ("CFBundleTypeExtensions"); - arrayTag = dict2->createNewChildElement ("array"); - - addPlistDictionaryKey (dict2, "CFBundleTypeName", ex); - addPlistDictionaryKey (dict2, "CFBundleTypeRole", "Editor"); - addPlistDictionaryKey (dict2, "CFBundleTypeIconFile", "Icon"); - addPlistDictionaryKey (dict2, "NSPersistentStoreTypeKey", "XML"); - } - - arrayTag->createNewChildElement ("string")->addTextElement (ex); - } - } - - if (owner.isFileSharingEnabled() && type != AudioUnitv3PlugIn) - addPlistDictionaryKeyBool (dict, "UIFileSharingEnabled", true); - - if (owner.isDocumentBrowserEnabled()) - addPlistDictionaryKeyBool (dict, "UISupportsDocumentBrowser", true); - - if (owner.isStatusBarHidden() && type != AudioUnitv3PlugIn) - addPlistDictionaryKeyBool (dict, "UIStatusBarHidden", true); - - if (owner.iOS) - { - if (type != AudioUnitv3PlugIn) - { - // Forcing full screen disables the split screen feature and prevents error ITMS-90475 - addPlistDictionaryKeyBool (dict, "UIRequiresFullScreen", true); - addPlistDictionaryKeyBool (dict, "UIStatusBarHidden", true); - - addIosScreenOrientations (dict); - addIosBackgroundModes (dict); - } - - if (type == StandalonePlugIn && owner.getProject().shouldEnableIAA()) - { - XmlElement audioComponentsPlistKey ("key"); - audioComponentsPlistKey.addTextElement ("AudioComponents"); - - dict->addChildElement (new XmlElement (audioComponentsPlistKey)); - - XmlElement audioComponentsPlistEntry ("array"); - auto* audioComponentsDict = audioComponentsPlistEntry.createNewChildElement ("dict"); - - addPlistDictionaryKey (audioComponentsDict, "name", owner.project.getIAAPluginName()); - addPlistDictionaryKey (audioComponentsDict, "manufacturer", owner.project.getPluginManufacturerCodeString().substring (0, 4)); - addPlistDictionaryKey (audioComponentsDict, "type", owner.project.getIAATypeCode()); - addPlistDictionaryKey (audioComponentsDict, "subtype", owner.project.getPluginCodeString().substring (0, 4)); - addPlistDictionaryKeyInt (audioComponentsDict, "version", owner.project.getVersionAsHexInteger()); - - dict->addChildElement (new XmlElement (audioComponentsPlistEntry)); - } - } - - for (auto& e : xcodeExtraPListEntries) - dict->addChildElement (new XmlElement (e)); + build_tools::PlistOptions options; + + options.type = type; + options.executableName = "${EXECUTABLE_NAME}"; + options.bundleIdentifier = getBundleIdentifier(); + options.plistToMerge = owner.getPListToMergeString(); + options.iOS = owner.iOS; + options.microphonePermissionEnabled = owner.isMicrophonePermissionEnabled(); + options.microphonePermissionText = owner.getMicrophonePermissionsTextString(); + options.cameraPermissionEnabled = owner.isCameraPermissionEnabled(); + options.cameraPermissionText = owner.getCameraPermissionTextString(); + options.bluetoothPermissionEnabled = owner.isBluetoothPermissionEnabled(); + options.bluetoothPermissionText = owner.getBluetoothPermissionTextString(); + options.sendAppleEventsPermissionEnabled = owner.isSendAppleEventsPermissionEnabled(); + options.sendAppleEventsPermissionText = owner.getSendAppleEventsPermissionTextString(); + options.shouldAddStoryboardToProject = owner.shouldAddStoryboardToProject(); + options.iconFile = owner.iconFile; + options.projectName = owner.projectName; + options.version = owner.project.getVersionString(); + options.companyCopyright = owner.project.getCompanyCopyrightString(); + options.allPreprocessorDefs = owner.getAllPreprocessorDefs(); + options.documentExtensions = owner.getDocumentExtensionsString(); + options.fileSharingEnabled = owner.isFileSharingEnabled(); + options.documentBrowserEnabled = owner.isDocumentBrowserEnabled(); + options.statusBarHidden = owner.isStatusBarHidden(); + options.backgroundAudioEnabled = owner.isBackgroundAudioEnabled(); + options.backgroundBleEnabled = owner.isBackgroundBleEnabled(); + options.pushNotificationsEnabled = owner.isPushNotificationsEnabled(); + options.enableIAA = owner.project.shouldEnableIAA(); + options.IAAPluginName = owner.project.getIAAPluginName(); + options.pluginManufacturerCode = owner.project.getPluginManufacturerCodeString(); + options.IAATypeCode = owner.project.getIAATypeCode(); + options.pluginCode = owner.project.getPluginCodeString(); + options.versionAsHex = owner.project.getVersionAsHexInteger(); + options.iPhoneScreenOrientations = owner.getiPhoneScreenOrientations(); + options.iPadScreenOrientations = owner.getiPadScreenOrientations(); + + options.storyboardName = [&] + { + const auto customLaunchStoryboard = owner.getCustomLaunchStoryboardString(); - MemoryOutputStream mo; - XmlElement::TextFormat format; - format.dtd = "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"; - plist->writeTo (mo, format); - overwriteFileIfDifferentOrThrow (infoPlistFile, mo); - } - - //============================================================================== - void addIosScreenOrientations (XmlElement* dict) const - { - String screenOrientations[2] = { owner.getiPhoneScreenOrientationString(), owner.getiPadScreenOrientationString() }; - String plistSuffix[2] = { "", "~ipad" }; - auto orientationsAreTheSame = ( screenOrientations[0] == screenOrientations[1] ); - - for (int i = 0; i < (orientationsAreTheSame ? 1 : 2); ++i) - { - StringArray iOSOrientations; - - if (screenOrientations[i].contains ("portrait")) { iOSOrientations.add ("UIInterfaceOrientationPortrait"); } - if (screenOrientations[i].contains ("landscape")) { iOSOrientations.add ("UIInterfaceOrientationLandscapeLeft"); iOSOrientations.add ("UIInterfaceOrientationLandscapeRight"); } - - addArrayToPlist (dict, String ("UISupportedInterfaceOrientations") + plistSuffix[i], iOSOrientations); - } - - } - - //============================================================================== - void addIosBackgroundModes (XmlElement* dict) const - { - StringArray iosBackgroundModes; - if (owner.isBackgroundAudioEnabled()) iosBackgroundModes.add ("audio"); - if (owner.isBackgroundBleEnabled()) iosBackgroundModes.add ("bluetooth-central"); - if (owner.isPushNotificationsEnabled()) iosBackgroundModes.add ("remote-notification"); + if (customLaunchStoryboard.isEmpty()) + return owner.getDefaultLaunchStoryboardName(); - addArrayToPlist (dict, "UIBackgroundModes", iosBackgroundModes); - } + return customLaunchStoryboard.fromLastOccurrenceOf ("/", false, false) + .upToLastOccurrenceOf (".storyboard", false, false); + }(); - //============================================================================== - static void addArrayToPlist (XmlElement* dict, String arrayKey, const StringArray& arrayElements) - { - dict->createNewChildElement ("key")->addTextElement (arrayKey); - auto* plistStringArray = dict->createNewChildElement ("array"); + options.pluginName = owner.project.getPluginNameString(); + options.pluginManufacturer = owner.project.getPluginManufacturerString(); + options.pluginDescription = owner.project.getPluginDescriptionString(); + options.pluginAUExportPrefix = owner.project.getPluginAUExportPrefixString(); + options.auMainType = owner.project.getAUMainTypeString(); + options.isAuSandboxSafe = owner.project.isAUSandBoxSafe(); + options.isPluginSynth = owner.project.isPluginSynth(); + options.suppressResourceUsage = owner.getSuppressPlistResourceUsage(); - for (auto& e : arrayElements) - plistStringArray->createNewChildElement ("string")->addTextElement (e); + options.write (infoPlistFile); } //============================================================================== @@ -1771,7 +1805,7 @@ public: { // Needed to compile .r files paths.add (owner.getModuleFolderRelativeToProject ("juce_audio_plugin_client") - .rebased (owner.projectFolder, owner.getTargetFolder(), RelativePath::buildTargetFolder) + .rebased (owner.projectFolder, owner.getTargetFolder(), build_tools::RelativePath::buildTargetFolder) .toUnixStyle()); } @@ -1796,48 +1830,6 @@ public: " -I \\\"$(DEVELOPER_DIR)/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/AudioUnit.framework/Headers\\\""; xcodeFrameworks.addArray ({ "AudioUnit", "CoreAudioKit" }); - - XmlElement plistKey ("key"); - plistKey.addTextElement ("AudioComponents"); - - XmlElement plistEntry ("array"); - auto* dict = plistEntry.createNewChildElement ("dict"); - - auto pluginManufacturerCode = owner.project.getPluginManufacturerCodeString().substring (0, 4); - auto pluginSubType = owner.project.getPluginCodeString().substring (0, 4); - - if (pluginManufacturerCode.toLowerCase() == pluginManufacturerCode) - { - throw SaveError ("AudioUnit plugin code identifiers invalid!\n\n" - "You have used only lower case letters in your AU plugin manufacturer identifier. " - "You must have at least one uppercase letter in your AU plugin manufacturer " - "identifier code."); - } - - addPlistDictionaryKey (dict, "name", owner.project.getPluginManufacturerString() - + ": " + owner.project.getPluginNameString()); - addPlistDictionaryKey (dict, "description", owner.project.getPluginDescriptionString()); - addPlistDictionaryKey (dict, "factoryFunction", owner.project.getPluginAUExportPrefixString() + "Factory"); - addPlistDictionaryKey (dict, "manufacturer", pluginManufacturerCode); - addPlistDictionaryKey (dict, "type", owner.project.getAUMainTypeString().removeCharacters ("'")); - addPlistDictionaryKey (dict, "subtype", pluginSubType); - addPlistDictionaryKeyInt (dict, "version", owner.project.getVersionAsHexInteger()); - - if (owner.project.isAUSandBoxSafe()) - { - addPlistDictionaryKeyBool (dict, "sandboxSafe", true); - } - else - { - dict->createNewChildElement ("key")->addTextElement ("resourceUsage"); - auto* resourceUsageDict = dict->createNewChildElement ("dict"); - - addPlistDictionaryKeyBool (resourceUsageDict, "network.client", true); - addPlistDictionaryKeyBool (resourceUsageDict, "temporary-exception.files.all.read-write", true); - } - - xcodeExtraPListEntries.add (plistKey); - xcodeExtraPListEntries.add (plistEntry); } void addExtraAudioUnitv3PlugInTargetSettings() @@ -1846,47 +1838,13 @@ public: if (owner.isOSX()) xcodeFrameworks.add ("AudioUnit"); - - XmlElement plistKey ("key"); - plistKey.addTextElement ("NSExtension"); - - XmlElement plistEntry ("dict"); - - addPlistDictionaryKey (&plistEntry, "NSExtensionPrincipalClass", owner.project.getPluginAUExportPrefixString() + "FactoryAUv3"); - addPlistDictionaryKey (&plistEntry, "NSExtensionPointIdentifier", "com.apple.AudioUnit-UI"); - plistEntry.createNewChildElement ("key")->addTextElement ("NSExtensionAttributes"); - - auto* dict = plistEntry.createNewChildElement ("dict"); - dict->createNewChildElement ("key")->addTextElement ("AudioComponents"); - auto* componentArray = dict->createNewChildElement ("array"); - - auto* componentDict = componentArray->createNewChildElement ("dict"); - - addPlistDictionaryKey (componentDict, "name", owner.project.getPluginManufacturerString() - + ": " + owner.project.getPluginNameString()); - addPlistDictionaryKey (componentDict, "description", owner.project.getPluginDescriptionString()); - addPlistDictionaryKey (componentDict, "factoryFunction",owner.project. getPluginAUExportPrefixString() + "FactoryAUv3"); - addPlistDictionaryKey (componentDict, "manufacturer", owner.project.getPluginManufacturerCodeString().substring (0, 4)); - addPlistDictionaryKey (componentDict, "type", owner.project.getAUMainTypeString().removeCharacters ("'")); - addPlistDictionaryKey (componentDict, "subtype", owner.project.getPluginCodeString().substring (0, 4)); - addPlistDictionaryKeyInt (componentDict, "version", owner.project.getVersionAsHexInteger()); - addPlistDictionaryKeyBool (componentDict, "sandboxSafe", true); - - componentDict->createNewChildElement ("key")->addTextElement ("tags"); - auto* tagsArray = componentDict->createNewChildElement ("array"); - - tagsArray->createNewChildElement ("string") - ->addTextElement (static_cast<bool> (owner.project.isPluginSynth()) ? "Synth" : "Effects"); - - xcodeExtraPListEntries.add (plistKey); - xcodeExtraPListEntries.add (plistEntry); } - void addExtraLibsForTargetType (const BuildConfiguration& config, Array<RelativePath>& extraLibs) const + void addExtraLibsForTargetType (const BuildConfiguration& config, Array<build_tools::RelativePath>& extraLibs) const { if (type == AAXPlugIn) { - auto aaxLibsFolder = RelativePath (owner.getAAXPathString(), RelativePath::projectFolder).getChildFile ("Libs"); + auto aaxLibsFolder = build_tools::RelativePath (owner.getAAXPathString(), build_tools::RelativePath::projectFolder).getChildFile ("Libs"); String libraryPath (config.isDebug() ? "Debug" : "Release"); libraryPath += "/libAAXLibrary_libcpp.a"; @@ -1895,7 +1853,7 @@ public: } else if (type == RTASPlugIn) { - RelativePath rtasFolder (owner.getRTASPathString(), RelativePath::projectFolder); + build_tools::RelativePath rtasFolder (owner.getRTASPathString(), build_tools::RelativePath::projectFolder); extraLibs.add (rtasFolder.getChildFile ("MacBag/Libs/Debug/libPluginLibrary.a")); extraLibs.add (rtasFolder.getChildFile ("MacBag/Libs/Release/libPluginLibrary.a")); @@ -1908,7 +1866,7 @@ public: if (type == RTASPlugIn) { - RelativePath rtasFolder (owner.getRTASPathString(), RelativePath::projectFolder); + build_tools::RelativePath rtasFolder (owner.getRTASPathString(), build_tools::RelativePath::projectFolder); targetExtraSearchPaths.add ("$(DEVELOPER_DIR)/Headers/FlatCarbon"); targetExtraSearchPaths.add ("$(SDKROOT)/Developer/Headers/FlatCarbon"); @@ -1952,13 +1910,14 @@ public: String getOSXDeploymentTarget (const String& deploymentTarget) const { - auto minVersion = (type == Target::AudioUnitv3PlugIn ? minimumAUv3SDKVersion : oldestDeploymentTarget); + auto minVersion = (type == Target::AudioUnitv3PlugIn ? minimumAUv3SDKVersion + : oldestDeploymentTarget); - for (int v = minVersion; v <= currentSDKVersion; ++v) - if (deploymentTarget == getSDKDisplayName (v)) - return getVersionName (v); + for (auto v = minVersion; v != nextMacOSVersion; ++v) + if (deploymentTarget == getDisplayName (v)) + return ::getName (v); - return getVersionName (minVersion); + return ::getName (minVersion); } //============================================================================== @@ -1977,7 +1936,7 @@ private: bool xcodeCanUseDwarf; OwnedArray<XcodeTarget> targets; - mutable OwnedArray<ValueTree> pbxBuildFiles, pbxFileReferences, pbxGroups, misc, projectConfigs, targetConfigs; + mutable OwnedArray<ValueTree> pbxBuildFiles, pbxFileReferences, pbxGroups, pbxTargetDependencies, misc, projectConfigs, targetConfigs; mutable StringArray resourceIDs, sourceIDs, targetIDs; mutable StringArray frameworkFileIDs, embeddedFrameworkIDs, rezFileIDs, resourceFileRefs, subprojectFileIDs; mutable Array<std::pair<String, String>> subprojectReferences; @@ -1988,17 +1947,21 @@ private: ValueWithDefault customPListValue, pListPrefixHeaderValue, pListPreprocessValue, subprojectsValue, + validArchsValue, extraFrameworksValue, frameworkSearchPathsValue, extraCustomFrameworksValue, embeddedFrameworksValue, postbuildCommandValue, prebuildCommandValue, duplicateAppExResourcesFolderValue, iosDeviceFamilyValue, iPhoneScreenOrientationValue, iPadScreenOrientationValue, customXcodeResourceFoldersValue, customXcassetsFolderValue, appSandboxValue, appSandboxInheritanceValue, appSandboxOptionsValue, hardenedRuntimeValue, hardenedRuntimeOptionsValue, - microphonePermissionNeededValue, microphonePermissionsTextValue, cameraPermissionNeededValue, cameraPermissionTextValue, iosBluetoothPermissionNeededValue, iosBluetoothPermissionTextValue, + microphonePermissionNeededValue, microphonePermissionsTextValue, + cameraPermissionNeededValue, cameraPermissionTextValue, + bluetoothPermissionNeededValue, bluetoothPermissionTextValue, + sendAppleEventsPermissionNeededValue, sendAppleEventsPermissionTextValue, uiFileSharingEnabledValue, uiSupportsDocumentBrowserValue, uiStatusBarHiddenValue, documentExtensionsValue, iosInAppPurchasesValue, - iosBackgroundAudioValue, iosBackgroundBleValue, iosPushNotificationsValue, iosAppGroupsValue, iCloudPermissionsValue, + iosContentSharingValue, iosBackgroundAudioValue, iosBackgroundBleValue, iosPushNotificationsValue, iosAppGroupsValue, iCloudPermissionsValue, iosDevelopmentTeamIDValue, iosAppGroupsIDValue, keepCustomXcodeSchemesValue, useHeaderMapValue, customLaunchStoryboardValue, - exporterBundleIdentifierValue; + exporterBundleIdentifierValue, suppressPlistResourceUsage; static String sanitisePath (const String& path) { @@ -2042,9 +2005,8 @@ private: if (customLaunchStoryboard.isEmpty()) writeDefaultLaunchStoryboardFile(); else if (getProject().getProjectFolder().getChildFile (customLaunchStoryboard).existsAsFile()) - addLaunchStoryboardFileReference (RelativePath (customLaunchStoryboard, RelativePath::projectFolder) - .rebased (getProject().getProjectFolder(), getTargetFolder(), RelativePath::buildTargetFolder) - .toUnixStyle()); + addLaunchStoryboardFileReference (build_tools::RelativePath (customLaunchStoryboard, build_tools::RelativePath::projectFolder) + .rebased (getProject().getProjectFolder(), getTargetFolder(), build_tools::RelativePath::buildTargetFolder)); } } else @@ -2075,6 +2037,8 @@ private: { for (auto* target : targets) { + target->addDependencies(); + if (target->type == XcodeTarget::AggregateTarget) continue; @@ -2091,7 +2055,6 @@ private: target->mainBuildProductID = fileID; pbxBuildFiles.add (v); - target->addDependency(); } } @@ -2104,7 +2067,7 @@ private: if (target->shouldCreatePList()) { - RelativePath plistPath (target->infoPlistFile, getTargetFolder(), RelativePath::buildTargetFolder); + build_tools::RelativePath plistPath (target->infoPlistFile, getTargetFolder(), build_tools::RelativePath::buildTargetFolder); addFileReference (plistPath.toUnixStyle()); resourceFileRefs.add (createFileRefID (plistPath)); } @@ -2113,13 +2076,14 @@ private: void addNibFiles() const { - MemoryOutputStream nib; - nib.write (BinaryData::RecentFilesMenuTemplate_nib, BinaryData::RecentFilesMenuTemplate_nibSize); - overwriteFileIfDifferentOrThrow (menuNibFile, nib); + build_tools::writeStreamToFile (menuNibFile, [&] (MemoryOutputStream& mo) + { + mo.write (BinaryData::RecentFilesMenuTemplate_nib, BinaryData::RecentFilesMenuTemplate_nibSize); + }); - RelativePath menuNibPath (menuNibFile, getTargetFolder(), RelativePath::buildTargetFolder); + build_tools::RelativePath menuNibPath (menuNibFile, getTargetFolder(), build_tools::RelativePath::buildTargetFolder); addFileReference (menuNibPath.toUnixStyle()); - resourceIDs.add (addBuildFile (menuNibPath, false, false)); + resourceIDs.add (addBuildFile (FileOptions().withRelativePath (menuNibPath))); resourceFileRefs.add (createFileRefID (menuNibPath)); } @@ -2127,9 +2091,9 @@ private: { if (iconFile.exists()) { - RelativePath iconPath (iconFile, getTargetFolder(), RelativePath::buildTargetFolder); + build_tools::RelativePath iconPath (iconFile, getTargetFolder(), build_tools::RelativePath::buildTargetFolder); addFileReference (iconPath.toUnixStyle()); - resourceIDs.add (addBuildFile (iconPath, false, false)); + resourceIDs.add (addBuildFile (FileOptions().withRelativePath (iconPath))); resourceFileRefs.add (createFileRefID (iconPath)); } } @@ -2276,13 +2240,14 @@ private: { if (auto* unityTarget = getTargetOfType (XcodeTarget::UnityPlugIn)) { - RelativePath scriptPath (getProject().getGeneratedCodeFolder().getChildFile (getProject().getUnityScriptName()), - getTargetFolder(), - RelativePath::buildTargetFolder); + build_tools::RelativePath scriptPath (getProject().getGeneratedCodeFolder().getChildFile (getProject().getUnityScriptName()), + getTargetFolder(), + build_tools::RelativePath::buildTargetFolder); auto path = scriptPath.toUnixStyle(); auto refID = addFileReference (path); - auto fileID = addBuildFile (path, refID, false, false); + auto fileID = addBuildFile (FileOptions().withPath (path) + .withFileRefID (refID)); resourceIDs.add (fileID); resourceFileRefs.add (refID); @@ -2291,32 +2256,8 @@ private: } } - static Image fixMacIconImageSize (Drawable& image) - { - const int validSizes[] = { 16, 32, 64, 128, 256, 512, 1024 }; - - auto w = image.getWidth(); - auto h = image.getHeight(); - - int bestSize = 16; - - for (int size : validSizes) - { - if (w == h && w == size) - { - bestSize = w; - break; - } - - if (jmax (w, h) > size) - bestSize = size; - } - - return rescaleImageForIcon (image, bestSize); - } - //============================================================================== - XcodeTarget* getTargetOfType (ProjectType::Target::Type type) const + XcodeTarget* getTargetOfType (build_tools::ProjectType::Target::Type type) const { for (auto& target : targets) if (target->type == type) @@ -2337,7 +2278,7 @@ private: v->setProperty ("buildPhases", indentParenthesisedList (target.buildPhaseIDs), nullptr); v->setProperty ("buildRules", "( )", nullptr); - v->setProperty ("dependencies", indentParenthesisedList (getTargetDependencies (target)), nullptr); + v->setProperty ("dependencies", indentParenthesisedList (target.dependencyIDs), nullptr); v->setProperty (Ids::name, target.getXcodeSchemeName(), nullptr); v->setProperty ("productName", projectName, nullptr); @@ -2354,163 +2295,38 @@ private: misc.add (v); } - StringArray getTargetDependencies (const XcodeTarget& target) const - { - StringArray dependencies; - - if (project.isAudioPluginProject()) - { - if (target.type == XcodeTarget::StandalonePlugIn) // depends on AUv3 and shared code - { - if (auto* auv3Target = getTargetOfType (XcodeTarget::AudioUnitv3PlugIn)) - dependencies.add (auv3Target->getDependencyID()); - - if (auto* sharedCodeTarget = getTargetOfType (XcodeTarget::SharedCodeTarget)) - dependencies.add (sharedCodeTarget->getDependencyID()); - } - else if (target.type == XcodeTarget::AggregateTarget) // depends on all other targets - { - for (int i = 1; i < targets.size(); ++i) - dependencies.add (targets[i]->getDependencyID()); - } - else if (target.type != XcodeTarget::SharedCodeTarget) // shared code doesn't depend on anything; all other targets depend only on the shared code - { - if (auto* sharedCodeTarget = getTargetOfType (XcodeTarget::SharedCodeTarget)) - dependencies.add (sharedCodeTarget->getDependencyID()); - } - } - - return dependencies; - } - - static void writeIconData (MemoryOutputStream& out, const Image& image, const char* type) - { - MemoryOutputStream pngData; - PNGImageFormat pngFormat; - pngFormat.writeImageToStream (image, pngData); - - out.write (type, 4); - out.writeIntBigEndian (8 + (int) pngData.getDataSize()); - out << pngData; - } - - void writeIcnsFile (const OwnedArray<Drawable>& images, OutputStream& out) const - { - MemoryOutputStream data; - auto smallest = std::numeric_limits<int>::max(); - Drawable* smallestImage = nullptr; - - for (int i = 0; i < images.size(); ++i) - { - auto image = fixMacIconImageSize (*images.getUnchecked (i)); - jassert (image.getWidth() == image.getHeight()); - - if (image.getWidth() < smallest) - { - smallest = image.getWidth(); - smallestImage = images.getUnchecked(i); - } - - switch (image.getWidth()) - { - case 16: writeIconData (data, image, "icp4"); break; - case 32: writeIconData (data, image, "icp5"); break; - case 64: writeIconData (data, image, "icp6"); break; - case 128: writeIconData (data, image, "ic07"); break; - case 256: writeIconData (data, image, "ic08"); break; - case 512: writeIconData (data, image, "ic09"); break; - case 1024: writeIconData (data, image, "ic10"); break; - default: break; - } - } - - jassert (data.getDataSize() > 0); // no suitable sized images? - - // If you only supply a 1024 image, the file doesn't work on 10.8, so we need - // to force a smaller one in there too.. - if (smallest > 512 && smallestImage != nullptr) - writeIconData (data, rescaleImageForIcon (*smallestImage, 512), "ic09"); - - out.write ("icns", 4); - out.writeIntBigEndian ((int) data.getDataSize() + 8); - out << data; - } - - void getIconImages (OwnedArray<Drawable>& images) const - { - if (auto icon = getBigIcon()) - images.add (std::move (icon)); - - if (auto icon = getSmallIcon()) - images.add (std::move (icon)); - } - - void createiOSIconFiles (File appIconSet) const - { - OwnedArray<Drawable> images; - getIconImages (images); - - if (images.size() > 0) - { - for (auto& type : getiOSAppIconTypes()) - { - auto image = rescaleImageForIcon (*images.getFirst(), type.size); - - if (image.hasAlphaChannel()) - { - Image background (Image::RGB, image.getWidth(), image.getHeight(), false); - Graphics g (background); - g.fillAll (Colours::white); - - g.drawImageWithin (image, 0, 0, image.getWidth(), image.getHeight(), - RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize); - - image = background; - } - - MemoryOutputStream pngData; - PNGImageFormat pngFormat; - pngFormat.writeImageToStream (image, pngData); - - overwriteFileIfDifferentOrThrow (appIconSet.getChildFile (type.filename), pngData); - } - } - } - void createIconFile() const { - OwnedArray<Drawable> images; - getIconImages (images); + const auto icons = getIcons(); - if (images.size() > 0) + if (! build_tools::asArray (icons).isEmpty()) { - MemoryOutputStream mo; - writeIcnsFile (images, mo); - iconFile = getTargetFolder().getChildFile ("Icon.icns"); - overwriteFileIfDifferentOrThrow (iconFile, mo); + build_tools::writeMacIcon (icons, iconFile); } } void writeWorkspaceSettings() const { - auto settingsFile = getProjectBundle().getChildFile ("project.xcworkspace") - .getChildFile ("xcshareddata") - .getChildFile ("WorkspaceSettings.xcsettings"); - - MemoryOutputStream mo; - mo.setNewLineString ("\n"); + const auto settingsFile = getProjectBundle().getChildFile ("project.xcworkspace") + .getChildFile ("xcshareddata") + .getChildFile ("WorkspaceSettings.xcsettings"); - mo << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << newLine - << "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">" << newLine - << "<plist version=\"1.0\">" << newLine - << "<dict>" << newLine - << "\t" << "<key>BuildSystemType</key>" << newLine - << "\t" << "<string>Original</string>" << newLine - << "</dict>" << newLine - << "</plist>" << newLine; + build_tools::writeStreamToFile (settingsFile, [this] (MemoryOutputStream& mo) + { + mo.setNewLineString (getNewLineString()); - overwriteFileIfDifferentOrThrow (settingsFile, mo); + mo << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << newLine + << "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">" << newLine + << "<plist version=\"1.0\">" << newLine + << "<dict>" << newLine + << "\t" << "<key>BuildSystemType</key>" << newLine + << "\t" << "<string>Original</string>" << newLine + << "\t" << "<key>DisableBuildSystemDeprecationWarning</key>" << newLine + << "\t" << "<true/>" << newLine + << "</dict>" << newLine + << "</plist>" << newLine; + }); } void writeInfoPlistFiles() const @@ -2522,9 +2338,9 @@ private: // Delete .rsrc files in folder but don't follow sym-links void deleteRsrcFiles (const File& folder) const { - for (DirectoryIterator di (folder, false, "*", File::findFilesAndDirectories); di.next();) + for (const auto& di : RangedDirectoryIterator (folder, false, "*", File::findFilesAndDirectories)) { - auto& entry = di.getFile(); + const auto& entry = di.getFile(); if (! entry.isSymbolicLink()) { @@ -2544,13 +2360,13 @@ private: return "-l" + library.replace (" ", "\\\\ ").replace ("\"", "\\\\\"").replace ("\'", "\\\\\'").upToLastOccurrenceOf (".", false, false); } - String getSearchPathForStaticLibrary (const RelativePath& library) const + String getSearchPathForStaticLibrary (const build_tools::RelativePath& library) const { auto searchPath = library.toUnixStyle().upToLastOccurrenceOf ("/", false, false); if (! library.isAbsolute()) { - auto srcRoot = rebaseFromProjectFolderToBuildTarget (RelativePath (".", RelativePath::projectFolder)).toUnixStyle(); + auto srcRoot = rebaseFromProjectFolderToBuildTarget (build_tools::RelativePath (".", build_tools::RelativePath::projectFolder)).toUnixStyle(); if (srcRoot.endsWith ("/.")) srcRoot = srcRoot.dropLastCharacters (2); if (! srcRoot.endsWithChar ('/')) srcRoot << '/'; @@ -2609,21 +2425,14 @@ private: s.set ("CLANG_WARN_UNREACHABLE_CODE", "YES"); s.set ("CLANG_WARN__DUPLICATE_METHOD_MATCH", "YES"); s.set ("WARNING_CFLAGS", "\"-Wreorder\""); + s.set ("GCC_INLINES_ARE_PRIVATE_EXTERN", projectType.isStaticLibrary() ? "NO" : "YES"); - if (projectType.isStaticLibrary()) - { - s.set ("GCC_INLINES_ARE_PRIVATE_EXTERN", "NO"); - s.set ("GCC_SYMBOLS_PRIVATE_EXTERN", "NO"); - } - else - { - s.set ("GCC_INLINES_ARE_PRIVATE_EXTERN", "YES"); - } + // GCC_SYMBOLS_PRIVATE_EXTERN only takes effect if ENABLE_TESTABILITY is off + s.set ("ENABLE_TESTABILITY", "NO"); + s.set ("GCC_SYMBOLS_PRIVATE_EXTERN", "YES"); if (config.isDebug()) { - s.set ("ENABLE_TESTABILITY", "YES"); - if (config.getOSXArchitectureString() == osxArch_Default) s.set ("ONLY_ACTIVE_ARCH", "YES"); } @@ -2662,8 +2471,12 @@ private: if (iOS && isPushNotificationsEnabled()) xcodeFrameworks.addIfNotAlreadyThere ("UserNotifications"); - if (isiOS() && project.getConfigFlag ("JUCE_USE_CAMERA").get()) + if (iOS + && project.getEnabledModules().isModuleEnabled ("juce_video") + && project.isConfigFlagEnabled ("JUCE_USE_CAMERA", false)) + { xcodeFrameworks.addIfNotAlreadyThere ("ImageIO"); + } xcodeFrameworks.addTokens (getExtraFrameworksString(), ",;", "\"'"); xcodeFrameworks.trim(); @@ -2777,24 +2590,8 @@ private: for (const auto& subprojectInfo : subprojects) { - String subprojectPath (subprojectInfo.first); - - if (! subprojectPath.endsWith (".xcodeproj")) - subprojectPath += ".xcodeproj"; - - File subprojectFile; - - if (File::isAbsolutePath (subprojectPath)) - { - subprojectFile = subprojectPath; - } - else - { - subprojectFile = getProject().getProjectFolder().getChildFile (subprojectPath); - - RelativePath p (subprojectPath, RelativePath::projectFolder); - subprojectPath = p.rebased (getProject().getProjectFolder(), getTargetFolder(), RelativePath::buildTargetFolder).toUnixStyle(); - } + auto subprojectFile = getTargetFolder().getChildFile (subprojectInfo.first.endsWith (".xcodeproj") ? subprojectInfo.first + : subprojectInfo.first + ".xcodeproj"); if (! subprojectFile.isDirectory()) continue; @@ -2805,7 +2602,7 @@ private: if (! subprojectInfo.second.isEmpty()) { auto newEnd = std::remove_if (availableBuildProducts.begin(), availableBuildProducts.end(), - [&subprojectInfo](const std::pair<String, String> &item) + [&subprojectInfo] (const std::pair<String, String> &item) { return ! subprojectInfo.second.contains (item.first); }); @@ -2815,7 +2612,11 @@ private: if (availableBuildProducts.empty()) continue; - auto subprojectFileType = getFileType (RelativePath (subprojectPath, RelativePath::projectFolder)); + auto subprojectPath = build_tools::RelativePath (subprojectFile, + getTargetFolder(), + build_tools::RelativePath::buildTargetFolder).toUnixStyle(); + + auto subprojectFileType = getFileType (subprojectPath); auto subprojectFileID = addFileOrFolderReference (subprojectPath, "<group>", subprojectFileType); subprojectFileIDs.add (subprojectFileID); @@ -2823,7 +2624,7 @@ private: for (auto& buildProduct : availableBuildProducts) { - auto buildProductFileType = getFileType (RelativePath (buildProduct.second, RelativePath::projectFolder)); + auto buildProductFileType = getFileType (buildProduct.second); auto containerID = addContainerItemProxy (subprojectFileID, buildProduct.first); auto proxyID = addReferenceProxy (containerID, buildProduct.second, buildProductFileType); @@ -2831,7 +2632,9 @@ private: if (buildProductFileType == "archive.ar" || buildProductFileType == "wrapper.framework") { - auto buildFileID = addBuildFile (buildProduct.second, proxyID, false, true); + auto buildFileID = addBuildFile (FileOptions().withPath (buildProduct.second) + .withFileRefID (proxyID) + .withInhibitWarningsEnabled (true)); for (auto& target : targets) target->frameworkIDs.add (buildFileID); @@ -2851,7 +2654,7 @@ private: } } - auto productGroupID = createFileRefID (subprojectPath + "_products"); + auto productGroupID = createFileRefID (subprojectFile.getFullPathName() + "_products"); addGroup (productGroupID, "Products", proxyIDs); subprojectReferences.add ({ productGroupID, subprojectFileID }); @@ -2863,22 +2666,24 @@ private: auto customXcassetsPath = getCustomXcassetsFolderString(); if (customXcassetsPath.isEmpty()) - createXcassetsFolderFromIcons(); + addDefaultXcassetsFolders(); else addCustomResourceFolder (customXcassetsPath, "folder.assetcatalog"); } void addCustomResourceFolder (String folderPathRelativeToProjectFolder, const String fileType = "folder") const { - auto folderPath = RelativePath (folderPathRelativeToProjectFolder, RelativePath::projectFolder) - .rebased (projectFolder, getTargetFolder(), RelativePath::buildTargetFolder) + auto folderPath = build_tools::RelativePath (folderPathRelativeToProjectFolder, build_tools::RelativePath::projectFolder) + .rebased (projectFolder, getTargetFolder(), build_tools::RelativePath::buildTargetFolder) .toUnixStyle(); auto fileRefID = createFileRefID (folderPath); addFileOrFolderReference (folderPath, "<group>", fileType); - resourceIDs.add (addBuildFile (folderPath, fileRefID, false, false)); + resourceIDs.add (addBuildFile (FileOptions().withPath (folderPath) + .withFileRefID (fileRefID))); + resourceFileRefs.add (createFileRefID (folderPath)); } @@ -2895,6 +2700,7 @@ private: objects.addArray (pbxBuildFiles); objects.addArray (pbxFileReferences); objects.addArray (pbxGroups); + objects.addArray (pbxTargetDependencies); objects.addArray (targetConfigs); objects.addArray (projectConfigs); objects.addArray (misc); @@ -2922,42 +2728,10 @@ private: output << "\t};\n\trootObject = " << createID ("__root") << ";\n}\n"; } - String addBuildFile (const String& path, const String& fileRefID, bool addToSourceBuildPhase, bool inhibitWarnings, - XcodeTarget* xcodeTarget = nullptr, String compilerFlags = {}) const - { - auto fileID = createID (path + "buildref"); - - if (addToSourceBuildPhase) - { - if (xcodeTarget != nullptr) - xcodeTarget->sourceIDs.add (fileID); - else - sourceIDs.add (fileID); - } - - auto* v = new ValueTree (fileID); - v->setProperty ("isa", "PBXBuildFile", nullptr); - v->setProperty ("fileRef", fileRefID, nullptr); - - if (inhibitWarnings) - compilerFlags += " -w"; - - if (compilerFlags.isNotEmpty()) - v->setProperty ("settings", "{ COMPILER_FLAGS = \"" + compilerFlags.trim() + "\"; }", nullptr); - - pbxBuildFiles.add (v); - return fileID; - } - - String addBuildFile (const RelativePath& path, bool addToSourceBuildPhase, bool inhibitWarnings, XcodeTarget* xcodeTarget = nullptr) const - { - return addBuildFile (path.toUnixStyle(), createFileRefID (path), addToSourceBuildPhase, inhibitWarnings, xcodeTarget); - } - String addFileReference (String pathString) const { String sourceTree ("SOURCE_ROOT"); - RelativePath path (pathString, RelativePath::unknown); + build_tools::RelativePath path (pathString, build_tools::RelativePath::unknown); if (pathString.startsWith ("${")) { @@ -2969,9 +2743,7 @@ private: sourceTree = "<absolute>"; } - auto fileType = getFileType (path); - - return addFileOrFolderReference (pathString, sourceTree, fileType); + return addFileOrFolderReference (pathString, sourceTree, getFileType (pathString)); } void checkAndAddFileReference (std::unique_ptr<ValueTree> v) const @@ -3045,8 +2817,34 @@ public: } private: - static String getFileType (const RelativePath& file) + struct FileOptions + { + FileOptions& withPath (const String& p) { path = p; return *this; } + FileOptions& withRelativePath (const build_tools::RelativePath& p) { path = p.toUnixStyle(); return *this; } + FileOptions& withFileRefID (const String& fid) { fileRefID = fid; return *this; } + FileOptions& withCompilerFlags (const String& f) { compilerFlags = f; return *this; } + FileOptions& withCompilationEnabled (bool e) { compile = e; return *this; } + FileOptions& withAddToBinaryResourcesEnabled (bool e) { addToBinaryResources = e; return *this; } + FileOptions& withAddToXcodeResourcesEnabled (bool e) { addToXcodeResources = e; return *this; } + FileOptions& withInhibitWarningsEnabled (bool e) { inhibitWarnings = e; return *this; } + FileOptions& withSkipPCHEnabled (bool e) { skipPCH = e; return *this; } + FileOptions& withXcodeTarget (XcodeTarget* t) { xcodeTarget = t; return *this; } + + String path; + String fileRefID; + String compilerFlags; + bool compile = false; + bool addToBinaryResources = false; + bool addToXcodeResources = false; + bool inhibitWarnings = false; + bool skipPCH = false; + XcodeTarget* xcodeTarget = nullptr; + }; + + static String getFileType (const String& filePath) { + build_tools::RelativePath file (filePath, build_tools::RelativePath::unknown); + if (file.hasFileExtension (cppFileExtensions)) return "sourcecode.cpp.cpp"; if (file.hasFileExtension (".mm")) return "sourcecode.cpp.objcpp"; if (file.hasFileExtension (".m")) return "sourcecode.c.objc"; @@ -3070,23 +2868,17 @@ private: return "file" + file.getFileExtension(); } - String addFile (const RelativePath& path, bool shouldBeCompiled, bool shouldBeAddedToBinaryResources, - bool shouldBeAddedToXcodeResources, bool inhibitWarnings, XcodeTarget* xcodeTarget, const String& compilerFlags) const + String addFile (const FileOptions& opts) const { - auto pathAsString = path.toUnixStyle(); - auto refID = addFileReference (path.toUnixStyle()); + auto refID = addFileReference (opts.path); - if (shouldBeCompiled) - { - addBuildFile (pathAsString, refID, true, inhibitWarnings, xcodeTarget, compilerFlags); - } - else if (! shouldBeAddedToBinaryResources || shouldBeAddedToXcodeResources) + if (opts.compile || opts.addToXcodeResources) { - auto fileType = getFileType (path); + auto fileID = addBuildFile (FileOptions (opts).withFileRefID (refID)); - if (shouldBeAddedToXcodeResources) + if (opts.addToXcodeResources) { - resourceIDs.add (addBuildFile (pathAsString, refID, false, false)); + resourceIDs.add (fileID); resourceFileRefs.add (refID); } } @@ -3094,119 +2886,82 @@ private: return refID; } - String addRezFile (const Project::Item& projectItem, const RelativePath& path) const + String addBuildFile (const FileOptions& opts) const { - auto pathAsString = path.toUnixStyle(); - auto refID = addFileReference (path.toUnixStyle()); + auto fileID = createID (opts.path + "buildref"); - if (projectItem.isModuleCode()) + if (opts.compile) { - if (auto* xcodeTarget = getTargetOfType (getProject().getTargetTypeFromFilePath (projectItem.getFile(), false))) - { - auto rezFileID = addBuildFile (pathAsString, refID, false, false, xcodeTarget); - xcodeTarget->rezFileIDs.add (rezFileID); - - return refID; - } + if (opts.xcodeTarget != nullptr) + opts.xcodeTarget->sourceIDs.add (fileID); + else + sourceIDs.add (fileID); } - return {}; - } - - StringPairArray getEntitlements (XcodeTarget& target) const - { - StringPairArray entitlements; - - if (project.isAudioPluginProject()) - { - if (isiOS() && project.shouldEnableIAA()) - entitlements.set ("inter-app-audio", "<true/>"); - } - else - { - if (isPushNotificationsEnabled()) - entitlements.set (isiOS() ? "aps-environment" - : "com.apple.developer.aps-environment", - "<string>development</string>"); - } + auto* v = new ValueTree (fileID); + v->setProperty ("isa", "PBXBuildFile", nullptr); + v->setProperty ("fileRef", opts.fileRefID.isEmpty() ? createFileRefID (opts.path) + : opts.fileRefID, + nullptr); - if (isAppGroupsEnabled()) + auto compilerFlags = [&opts] { - auto appGroups = StringArray::fromTokens (getAppGroupIdString(), ";", {}); - auto groups = String ("<array>"); - - for (auto group : appGroups) - groups += "\n\t\t<string>" + group.trim() + "</string>"; + return (opts.compilerFlags + + (opts.inhibitWarnings ? " -w" : String()) + + (opts.skipPCH ? " -D" + BuildConfiguration::getSkipPrecompiledHeaderDefine() : String())).trim(); + }(); - groups += "\n\t</array>"; + if (compilerFlags.isNotEmpty()) + v->setProperty ("settings", "{ COMPILER_FLAGS = \"" + compilerFlags + "\"; }", nullptr); - entitlements.set ("com.apple.security.application-groups", groups); - } + pbxBuildFiles.add (v); + return fileID; + } - if (isHardenedRuntimeEnabled()) - for (auto& option : getHardenedRuntimeOptions()) - entitlements.set (option, "<true/>"); + String addRezFile (const Project::Item& projectItem, const build_tools::RelativePath& path) const + { + auto refID = addFileReference (path.toUnixStyle()); - if (isAppSandboxEnabled() || (project.isAudioPluginProject() && target.type == XcodeTarget::AudioUnitv3PlugIn)) + if (projectItem.isModuleCode()) { - entitlements.set ("com.apple.security.app-sandbox", "<true/>"); - - if (isAppSandboxInhertianceEnabled()) + if (auto* xcodeTarget = getTargetOfType (getProject().getTargetTypeFromFilePath (projectItem.getFile(), false))) { - // no other sandbox options can be specified if sandbox inheritance is enabled! - jassert (getAppSandboxOptions().isEmpty()); - - entitlements.set ("com.apple.security.inherit", "<true/>"); - } - - if (isAppSandboxEnabled()) - for (auto& option : getAppSandboxOptions()) - entitlements.set (option, "<true/>"); - } + auto rezFileID = addBuildFile (FileOptions().withRelativePath (path) + .withFileRefID (refID) + .withXcodeTarget (xcodeTarget)); - if (isiOS() && isiCloudPermissionsEnabled()) - { - entitlements.set ("com.apple.developer.icloud-container-identifiers", - "<array>\n" - " <string>iCloud.$(CFBundleIdentifier)</string>\n" - " </array>"); - - entitlements.set ("com.apple.developer.icloud-services", - "<array>\n" - " <string>CloudDocuments</string>\n" - " </array>"); + xcodeTarget->rezFileIDs.add (rezFileID); - entitlements.set ("com.apple.developer.ubiquity-container-identifiers", - "<array>\n" - " <string>iCloud.$(CFBundleIdentifier)</string>\n" - " </array>"); + return refID; + } } - return entitlements; + return {}; } void addEntitlementsFile (XcodeTarget& target) const { - String content = - "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" - "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n" - "<plist version=\"1.0\">\n" - "<dict>\n"; - - auto entitlements = getEntitlements (target); + build_tools::EntitlementOptions options; - for (auto& key : entitlements.getAllKeys()) - content += "\t<key>" + key + "</key>\n" - "\t" + entitlements[key] + "\n"; + options.type = target.type; + options.isiOS = isiOS(); + options.isAudioPluginProject = project.isAudioPluginProject(); + options.shouldEnableIAA = project.shouldEnableIAA(); + options.isiCloudPermissionsEnabled = isiCloudPermissionsEnabled(); + options.isPushNotificationsEnabled = isPushNotificationsEnabled(); + options.isAppGroupsEnabled = isAppGroupsEnabled(); + options.isHardenedRuntimeEnabled = isHardenedRuntimeEnabled(); + options.isAppSandboxEnabled = isAppSandboxEnabled(); + options.isAppSandboxInhertianceEnabled = isAppSandboxInhertianceEnabled(); + options.appGroupIdString = getAppGroupIdString(); + options.hardenedRuntimeOptions = getHardenedRuntimeOptions(); + options.appSandboxOptions = getAppSandboxOptions(); - content += "</dict>\n" - "</plist>\n"; + const auto entitlementsFile = getTargetFolder().getChildFile (target.getEntitlementsFilename()); + build_tools::overwriteFileIfDifferentOrThrow (entitlementsFile, options.getEntitlementsFileContent()); - auto entitlementsFile = getTargetFolder().getChildFile (target.getEntitlementsFilename()); - overwriteFileIfDifferentOrThrow (entitlementsFile, content); - - RelativePath entitlementsPath (entitlementsFile, getTargetFolder(), RelativePath::buildTargetFolder); - addFile (entitlementsPath, false, false, false, false, nullptr, {}); + build_tools::RelativePath entitlementsPath (entitlementsFile, getTargetFolder(), build_tools::RelativePath::buildTargetFolder); + addFile (FileOptions().withRelativePath (entitlementsPath)); } String addProjectItem (const Project::Item& projectItem) const @@ -3236,12 +2991,12 @@ private: if (projectItem.shouldBeAddedToTargetProject() && projectItem.shouldBeAddedToTargetExporter (*this)) { auto itemPath = projectItem.getFilePath(); - RelativePath path; + build_tools::RelativePath path; if (itemPath.startsWith ("${")) - path = RelativePath (itemPath, RelativePath::unknown); + path = build_tools::RelativePath (itemPath, build_tools::RelativePath::unknown); else - path = RelativePath (projectItem.getFile(), getTargetFolder(), RelativePath::buildTargetFolder); + path = build_tools::RelativePath (projectItem.getFile(), getTargetFolder(), build_tools::RelativePath::buildTargetFolder); if (path.hasFileExtension (".r")) return addRezFile (projectItem, path); @@ -3250,12 +3005,14 @@ private: if (projectItem.isModuleCode() && projectItem.shouldBeCompiled()) xcodeTarget = getTargetOfType (project.getTargetTypeFromFilePath (projectItem.getFile(), false)); - return addFile (path, projectItem.shouldBeCompiled(), - projectItem.shouldBeAddedToBinaryResources(), - projectItem.shouldBeAddedToXcodeResources(), - projectItem.shouldInhibitWarnings(), - xcodeTarget, - compilerFlagSchemesMap[projectItem.getCompilerFlagSchemeString()].get()); + return addFile (FileOptions().withRelativePath (path) + .withCompilerFlags (compilerFlagSchemesMap[projectItem.getCompilerFlagSchemeString()].get()) + .withCompilationEnabled (projectItem.shouldBeCompiled()) + .withAddToBinaryResourcesEnabled (projectItem.shouldBeAddedToBinaryResources()) + .withAddToXcodeResourcesEnabled (projectItem.shouldBeAddedToXcodeResources()) + .withInhibitWarningsEnabled (projectItem.shouldInhibitWarnings()) + .withSkipPCHEnabled (isPCHEnabledForAnyConfigurations() && projectItem.shouldSkipPCH()) + .withXcodeTarget (xcodeTarget)); } return {}; @@ -3277,7 +3034,8 @@ private: addFileReference (((File::isAbsolutePath (frameworkName) || isRelativePath) ? "" : "${SDKROOT}/") + path); frameworkFileIDs.add (fileRefID); - return addBuildFile (path, fileRefID, false, false); + return addBuildFile (FileOptions().withPath (path) + .withFileRefID (fileRefID)); } String addCustomFramework (String frameworkPath) const @@ -3287,19 +3045,20 @@ private: auto fileRefID = createFileRefID (frameworkPath); - auto fileType = getFileType (RelativePath (frameworkPath, RelativePath::projectFolder)); + auto fileType = getFileType (frameworkPath); addFileOrFolderReference (frameworkPath, "<group>", fileType); frameworkFileIDs.add (fileRefID); - return addBuildFile (frameworkPath, fileRefID, false, false); + return addBuildFile (FileOptions().withPath (frameworkPath) + .withFileRefID (fileRefID)); } String addEmbeddedFramework (const String& path) const { auto fileRefID = createFileRefID (path); - auto fileType = getFileType (RelativePath (path, RelativePath::projectFolder)); + auto fileType = getFileType (path); addFileOrFolderReference (path, "<group>", fileType); auto fileID = createID (path + "buildref"); @@ -3477,72 +3236,11 @@ private: return false; } - //============================================================================== - struct AppIconType - { - const char* idiom; - const char* sizeString; - const char* filename; - const char* scale; - int size; - }; - - static Array<AppIconType> getiOSAppIconTypes() - { - AppIconType types[] = - { - { "iphone", "20x20", "Icon-Notification-20@2x.png", "2x", 40 }, - { "iphone", "20x20", "Icon-Notification-20@3x.png", "3x", 60 }, - { "iphone", "29x29", "Icon-29.png", "1x", 29 }, - { "iphone", "29x29", "Icon-29@2x.png", "2x", 58 }, - { "iphone", "29x29", "Icon-29@3x.png", "3x", 87 }, - { "iphone", "40x40", "Icon-Spotlight-40@2x.png", "2x", 80 }, - { "iphone", "40x40", "Icon-Spotlight-40@3x.png", "3x", 120 }, - { "iphone", "57x57", "Icon.png", "1x", 57 }, - { "iphone", "57x57", "Icon@2x.png", "2x", 114 }, - { "iphone", "60x60", "Icon-60@2x.png", "2x", 120 }, - { "iphone", "60x60", "Icon-@3x.png", "3x", 180 }, - { "ipad", "20x20", "Icon-Notifications-20.png", "1x", 20 }, - { "ipad", "20x20", "Icon-Notifications-20@2x.png", "2x", 40 }, - { "ipad", "29x29", "Icon-Small-1.png", "1x", 29 }, - { "ipad", "29x29", "Icon-Small@2x-1.png", "2x", 58 }, - { "ipad", "40x40", "Icon-Spotlight-40.png", "1x", 40 }, - { "ipad", "40x40", "Icon-Spotlight-40@2x-1.png", "2x", 80 }, - { "ipad", "50x50", "Icon-Small-50.png", "1x", 50 }, - { "ipad", "50x50", "Icon-Small-50@2x.png", "2x", 100 }, - { "ipad", "72x72", "Icon-72.png", "1x", 72 }, - { "ipad", "72x72", "Icon-72@2x.png", "2x", 144 }, - { "ipad", "76x76", "Icon-76.png", "1x", 76 }, - { "ipad", "76x76", "Icon-76@2x.png", "2x", 152 }, - { "ipad", "83.5x83.5", "Icon-83.5@2x.png", "2x", 167 }, - { "ios-marketing", "1024x1024", "Icon-AppStore-1024.png", "1x", 1024 } - }; - - return Array<AppIconType> (types, numElementsInArray (types)); - } - - static String getiOSAppIconContents() - { - var images; - - for (auto& type : getiOSAppIconTypes()) - { - DynamicObject::Ptr d (new DynamicObject()); - d->setProperty ("idiom", type.idiom); - d->setProperty ("size", type.sizeString); - d->setProperty ("filename", type.filename); - d->setProperty ("scale", type.scale); - images.append (var (d.get())); - } - - return getiOSAssetContents (images); - } - String getProjectObjectAttributes() const { String attributes; - attributes << "{ LastUpgradeCheck = 1100; " + attributes << "{ LastUpgradeCheck = 1200; " << "ORGANIZATIONNAME = " << getProject().getCompanyNameString().quoted() <<"; "; @@ -3562,141 +3260,39 @@ private: } //============================================================================== - struct ImageType - { - const char* orientation; - const char* idiom; - const char* subtype; - const char* extent; - const char* scale; - const char* filename; - int width; - int height; - }; - - static Array<ImageType> getiOSLaunchImageTypes() - { - ImageType types[] = - { - { "portrait", "iphone", nullptr, "full-screen", "2x", "LaunchImage-iphone-2x.png", 640, 960 }, - { "portrait", "iphone", "retina4", "full-screen", "2x", "LaunchImage-iphone-retina4.png", 640, 1136 }, - { "portrait", "ipad", nullptr, "full-screen", "1x", "LaunchImage-ipad-portrait-1x.png", 768, 1024 }, - { "landscape","ipad", nullptr, "full-screen", "1x", "LaunchImage-ipad-landscape-1x.png", 1024, 768 }, - { "portrait", "ipad", nullptr, "full-screen", "2x", "LaunchImage-ipad-portrait-2x.png", 1536, 2048 }, - { "landscape","ipad", nullptr, "full-screen", "2x", "LaunchImage-ipad-landscape-2x.png", 2048, 1536 } - }; - - return Array<ImageType> (types, numElementsInArray (types)); - } - - static String getiOSLaunchImageContents() + void writeDefaultLaunchStoryboardFile() const { - var images; + const auto storyboardFile = getTargetFolder().getChildFile (getDefaultLaunchStoryboardName() + ".storyboard"); - for (auto& type : getiOSLaunchImageTypes()) + build_tools::writeStreamToFile (storyboardFile, [&] (MemoryOutputStream& mo) { - DynamicObject::Ptr d (new DynamicObject()); - d->setProperty ("orientation", type.orientation); - d->setProperty ("idiom", type.idiom); - d->setProperty ("extent", type.extent); - d->setProperty ("minimum-system-version", "7.0"); - d->setProperty ("scale", type.scale); - d->setProperty ("filename", type.filename); - - if (type.subtype != nullptr) - d->setProperty ("subtype", type.subtype); - - images.append (var (d.get())); - } - - return getiOSAssetContents (images); - } - - static void createiOSLaunchImageFiles (const File& launchImageSet) - { - for (auto& type : getiOSLaunchImageTypes()) - { - Image image (Image::ARGB, type.width, type.height, true); // (empty black image) - image.clear (image.getBounds(), Colours::black); - - MemoryOutputStream pngData; - PNGImageFormat pngFormat; - pngFormat.writeImageToStream (image, pngData); - overwriteFileIfDifferentOrThrow (launchImageSet.getChildFile (type.filename), pngData); - } - } - - //============================================================================== - static String getiOSAssetContents (var images) - { - DynamicObject::Ptr v (new DynamicObject()); + mo << String (BinaryData::LaunchScreen_storyboard); + }); - var info (new DynamicObject()); - info.getDynamicObject()->setProperty ("version", 1); - info.getDynamicObject()->setProperty ("author", "xcode"); - - v->setProperty ("images", images); - v->setProperty ("info", info); - - return JSON::toString (var (v.get())); + addLaunchStoryboardFileReference (build_tools::RelativePath (storyboardFile, + getTargetFolder(), + build_tools::RelativePath::buildTargetFolder)); } - void writeDefaultLaunchStoryboardFile() const + void addLaunchStoryboardFileReference (const build_tools::RelativePath& relativePath) const { - auto storyboardFile = getTargetFolder().getChildFile (getDefaultLaunchStoryboardName() + ".storyboard"); - - MemoryOutputStream mo; - mo.setNewLineString ("\n"); - - mo << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << newLine - << "<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"14460.31\" " - << "targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" launchScreen=\"YES\" useTraitCollections=\"YES\" " - << "useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"01J-lp-oVM\">" << newLine - << " <scenes>" << newLine - << " <scene sceneID=\"EHf-IW-A2E\">" << newLine - << " <objects>" << newLine - << " <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"iYj-Kq-Ea1\" userLabel=\"\" sceneMemberID=\"firstResponder\"/>" << newLine - << " <viewController id=\"01J-lp-oVM\" sceneMemberID=\"viewController\">" << newLine - << " <view key=\"view\" contentMode=\"scaleToFill\" id=\"Ze5-6b-2t3\">" << newLine - << " <autoresizingMask key=\"autoresizingMask\"/>" << newLine - << " <color key=\"backgroundColor\" red=\"0\" green=\"0\" blue=\"0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>" << newLine - << " </view>" << newLine - << " </viewController>" << newLine - << " </objects>" << newLine - << " </scene>" << newLine - << " </scenes>" << newLine - << "</document>" << newLine; - - overwriteFileIfDifferentOrThrow (storyboardFile, mo); - - addLaunchStoryboardFileReference (RelativePath (storyboardFile, getTargetFolder(), RelativePath::buildTargetFolder).toUnixStyle()); - } + auto path = relativePath.toUnixStyle(); - void addLaunchStoryboardFileReference (const String& relativePath) const - { - auto refID = addFileReference (relativePath); - auto fileID = addBuildFile (relativePath, refID, false, false); + auto refID = addFileReference (path); + auto fileID = addBuildFile (FileOptions().withPath (path) + .withFileRefID (refID)); resourceIDs.add (fileID); resourceFileRefs.add (refID); } - void createXcassetsFolderFromIcons() const + void addDefaultXcassetsFolders() const { - auto assets = getTargetFolder().getChildFile (project.getProjectFilenameRootString()) - .getChildFile ("Images.xcassets"); - auto iconSet = assets.getChildFile ("AppIcon.appiconset"); - auto launchImage = assets.getChildFile ("LaunchImage.launchimage"); - - overwriteFileIfDifferentOrThrow (iconSet.getChildFile ("Contents.json"), getiOSAppIconContents()); - createiOSIconFiles (iconSet); - - overwriteFileIfDifferentOrThrow (launchImage.getChildFile ("Contents.json"), getiOSLaunchImageContents()); - createiOSLaunchImageFiles (launchImage); - - RelativePath assetsPath (assets, getTargetFolder(), RelativePath::buildTargetFolder); + const auto assetsPath = build_tools::createXcassetsFolderFromIcons (getIcons(), + getTargetFolder(), + project.getProjectFilenameRootString()); addFileReference (assetsPath.toUnixStyle()); - resourceIDs.add (addBuildFile (assetsPath, false, false)); + resourceIDs.add (addBuildFile (FileOptions().withRelativePath (assetsPath))); resourceFileRefs.add (createFileRefID (assetsPath)); } @@ -3728,14 +3324,45 @@ private: return MD5 (rootString.toUTF8()).toHexString().substring (0, 24).toUpperCase(); } - String createFileRefID (const RelativePath& path) const { return createFileRefID (path.toUnixStyle()); } - String createFileRefID (const String& path) const { return createID ("__fileref_" + path); } - String getIDForGroup (const Project::Item& item) const { return createID (item.getID()); } + String createFileRefID (const build_tools::RelativePath& path) const { return createFileRefID (path.toUnixStyle()); } + String createFileRefID (const String& path) const { return createID ("__fileref_" + path); } + String getIDForGroup (const Project::Item& item) const { return createID (item.getID()); } bool shouldFileBeCompiledByDefault (const File& file) const override { return file.hasFileExtension (sourceFileExtensions); } + //============================================================================== + void updateOldOrientationSettings() + { + jassert (iOS); + + StringArray orientationSettingStrings { getSetting (Ids::iPhoneScreenOrientation).getValue().toString(), + getSetting (Ids::iPadScreenOrientation).getValue().toString() }; + + for (int i = 0; i < 2; ++i) + { + auto& settingsString = orientationSettingStrings[i]; + + if (settingsString.isNotEmpty()) + { + Array<var> orientations; + + if (settingsString.contains ("portrait")) orientations.add ("UIInterfaceOrientationPortrait"); + if (settingsString.contains ("landscape")) orientations.addArray ({ "UIInterfaceOrientationLandscapeLeft", + "UIInterfaceOrientationLandscapeRight" }); + + if (! orientations.isEmpty()) + { + if (i == 0) + iPhoneScreenOrientationValue = orientations; + else + iPadScreenOrientationValue = orientations; + } + } + } + } + JUCE_DECLARE_NON_COPYABLE (XcodeProjectExporter) }; diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.cpp b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.cpp index 4274dd6c..544073a0 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.cpp +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -39,201 +38,152 @@ #include "../Utility/UI/PropertyComponents/jucer_FilePathPropertyComponent.h" //============================================================================== -static void addType (Array<ProjectExporter::ExporterTypeInfo>& list, - const char* name, const void* iconData, int iconDataSize) +std::vector<ProjectExporter::ExporterTypeInfo> ProjectExporter::getExporterTypeInfos() { - ProjectExporter::ExporterTypeInfo type = { name, iconData, iconDataSize }; - list.add (type); -} - -Array<ProjectExporter::ExporterTypeInfo> ProjectExporter::getExporterTypes() -{ - Array<ProjectExporter::ExporterTypeInfo> types; - - addType (types, XcodeProjectExporter::getNameMac(), BinaryData::export_xcode_svg, BinaryData::export_xcode_svgSize); - addType (types, XcodeProjectExporter::getNameiOS(), BinaryData::export_xcode_svg, BinaryData::export_xcode_svgSize); - addType (types, MSVCProjectExporterVC2019::getName(), BinaryData::export_visualStudio_svg, BinaryData::export_visualStudio_svgSize); - addType (types, MSVCProjectExporterVC2017::getName(), BinaryData::export_visualStudio_svg, BinaryData::export_visualStudio_svgSize); - addType (types, MSVCProjectExporterVC2015::getName(), BinaryData::export_visualStudio_svg, BinaryData::export_visualStudio_svgSize); - addType (types, MakefileProjectExporter::getNameLinux(), BinaryData::export_linux_svg, BinaryData::export_linux_svgSize); - addType (types, AndroidProjectExporter::getName(), BinaryData::export_android_svg, BinaryData::export_android_svgSize); - addType (types, CodeBlocksProjectExporter::getNameWindows(), BinaryData::export_codeBlocks_svg, BinaryData::export_codeBlocks_svgSize); - addType (types, CodeBlocksProjectExporter::getNameLinux(), BinaryData::export_codeBlocks_svg, BinaryData::export_codeBlocks_svgSize); - addType (types, CLionProjectExporter::getName(), BinaryData::export_clion_svg, BinaryData::export_clion_svgSize); - - return types; -} - -ProjectExporter* ProjectExporter::createNewExporter (Project& project, const int index) -{ - ProjectExporter* exp = nullptr; - - switch (index) + auto createIcon = [] (const void* iconData, size_t iconDataSize) { - case 0: exp = new XcodeProjectExporter (project, ValueTree (XcodeProjectExporter ::getValueTreeTypeName (false)), false); break; - case 1: exp = new XcodeProjectExporter (project, ValueTree (XcodeProjectExporter ::getValueTreeTypeName (true)), true); break; - case 2: exp = new MSVCProjectExporterVC2019 (project, ValueTree (MSVCProjectExporterVC2019 ::getValueTreeTypeName())); break; - case 3: exp = new MSVCProjectExporterVC2017 (project, ValueTree (MSVCProjectExporterVC2017 ::getValueTreeTypeName())); break; - case 4: exp = new MSVCProjectExporterVC2015 (project, ValueTree (MSVCProjectExporterVC2015 ::getValueTreeTypeName())); break; - case 5: exp = new MakefileProjectExporter (project, ValueTree (MakefileProjectExporter ::getValueTreeTypeName())); break; - case 6: exp = new AndroidProjectExporter (project, ValueTree (AndroidProjectExporter ::getValueTreeTypeName())); break; - case 7: exp = new CodeBlocksProjectExporter (project, ValueTree (CodeBlocksProjectExporter ::getValueTreeTypeName (CodeBlocksProjectExporter::windowsTarget)), CodeBlocksProjectExporter::windowsTarget); break; - case 8: exp = new CodeBlocksProjectExporter (project, ValueTree (CodeBlocksProjectExporter ::getValueTreeTypeName (CodeBlocksProjectExporter::linuxTarget)), CodeBlocksProjectExporter::linuxTarget); break; - case 9: exp = new CLionProjectExporter (project, ValueTree (CLionProjectExporter ::getValueTreeTypeName())); break; - } + Image image (Image::ARGB, 200, 200, true); + Graphics g (image); - exp->createDefaultConfigs(); - exp->createDefaultModulePaths(); + std::unique_ptr<Drawable> svgDrawable (Drawable::createFromImageData (iconData, iconDataSize)); - return exp; -} + svgDrawable->drawWithin (g, image.getBounds().toFloat(), RectanglePlacement::fillDestination, 1.0f); -StringArray ProjectExporter::getExporterNames() -{ - StringArray s; - - for (auto& e : getExporterTypes()) - s.add (e.name); - - return s; -} + return image; + }; -StringArray ProjectExporter::getExporterValueTreeNames() -{ - StringArray s; + using namespace BinaryData; - for (auto& n : getExporterNames()) - s.add (getValueTreeNameForExporter (n)); + static std::vector<ProjectExporter::ExporterTypeInfo> infos + { + { XcodeProjectExporter::getValueTreeTypeNameMac(), + XcodeProjectExporter::getDisplayNameMac(), + XcodeProjectExporter::getTargetFolderNameMac(), + createIcon (export_xcode_svg, (size_t) export_xcode_svgSize) }, + { XcodeProjectExporter::getValueTreeTypeNameiOS(), + XcodeProjectExporter::getDisplayNameiOS(), + XcodeProjectExporter::getTargetFolderNameiOS(), + createIcon (export_xcode_svg, (size_t) export_xcode_svgSize) }, + + { MSVCProjectExporterVC2019::getValueTreeTypeName(), + MSVCProjectExporterVC2019::getDisplayName(), + MSVCProjectExporterVC2019::getTargetFolderName(), + createIcon (export_visualStudio_svg, export_visualStudio_svgSize) }, + { MSVCProjectExporterVC2017::getValueTreeTypeName(), + MSVCProjectExporterVC2017::getDisplayName(), + MSVCProjectExporterVC2017::getTargetFolderName(), + createIcon (export_visualStudio_svg, export_visualStudio_svgSize) }, + { MSVCProjectExporterVC2015::getValueTreeTypeName(), + MSVCProjectExporterVC2015::getDisplayName(), + MSVCProjectExporterVC2015::getTargetFolderName(), + createIcon (export_visualStudio_svg, export_visualStudio_svgSize) }, + + { MakefileProjectExporter::getValueTreeTypeName(), + MakefileProjectExporter::getDisplayName(), + MakefileProjectExporter::getTargetFolderName(), + createIcon (export_linux_svg, export_linux_svgSize) }, + + { AndroidProjectExporter::getValueTreeTypeName(), + AndroidProjectExporter::getDisplayName(), + AndroidProjectExporter::getTargetFolderName(), + createIcon (export_android_svg, export_android_svgSize) }, + + { CodeBlocksProjectExporter::getValueTreeTypeNameWindows(), + CodeBlocksProjectExporter::getDisplayNameWindows(), + CodeBlocksProjectExporter::getTargetFolderNameWindows(), + createIcon (export_codeBlocks_svg, export_codeBlocks_svgSize) }, + { CodeBlocksProjectExporter::getValueTreeTypeNameLinux(), + CodeBlocksProjectExporter::getDisplayNameLinux(), + CodeBlocksProjectExporter::getTargetFolderNameLinux(), + createIcon (export_codeBlocks_svg, export_codeBlocks_svgSize) }, + + { CLionProjectExporter::getValueTreeTypeName(), + CLionProjectExporter::getDisplayName(), + CLionProjectExporter::getTargetFolderName(), + createIcon (export_clion_svg, export_clion_svgSize) } + }; - return s; + return infos; } -String ProjectExporter::getValueTreeNameForExporter (const String& exporterName) +ProjectExporter::ExporterTypeInfo ProjectExporter::getTypeInfoForExporter (const Identifier& exporterIdentifier) { - if (exporterName == XcodeProjectExporter::getNameMac()) - return XcodeProjectExporter::getValueTreeTypeName (false); - - if (exporterName == XcodeProjectExporter::getNameiOS()) - return XcodeProjectExporter::getValueTreeTypeName (true); + auto typeInfos = getExporterTypeInfos(); - if (exporterName == MSVCProjectExporterVC2019::getName()) - return MSVCProjectExporterVC2019::getValueTreeTypeName(); - - if (exporterName == MSVCProjectExporterVC2017::getName()) - return MSVCProjectExporterVC2017::getValueTreeTypeName(); - - if (exporterName == MSVCProjectExporterVC2015::getName()) - return MSVCProjectExporterVC2015::getValueTreeTypeName(); - - if (exporterName == MakefileProjectExporter::getNameLinux()) - return MakefileProjectExporter::getValueTreeTypeName(); - - if (exporterName == AndroidProjectExporter::getName()) - return AndroidProjectExporter::getValueTreeTypeName(); - - if (exporterName == CodeBlocksProjectExporter::getNameLinux()) - return CodeBlocksProjectExporter::getValueTreeTypeName (CodeBlocksProjectExporter::CodeBlocksOS::linuxTarget); + auto predicate = [exporterIdentifier] (const ProjectExporter::ExporterTypeInfo& info) + { + return info.identifier == exporterIdentifier; + }; - if (exporterName == CodeBlocksProjectExporter::getNameWindows()) - return CodeBlocksProjectExporter::getValueTreeTypeName (CodeBlocksProjectExporter::CodeBlocksOS::windowsTarget); + auto iter = std::find_if (typeInfos.begin(), typeInfos.end(), + std::move (predicate)); - if (exporterName == CLionProjectExporter::getName()) - return CLionProjectExporter::getValueTreeTypeName(); + if (iter != typeInfos.end()) + return *iter; return {}; } -String ProjectExporter::getTargetFolderForExporter (const String& exporterValueTreeName) +ProjectExporter::ExporterTypeInfo ProjectExporter::getCurrentPlatformExporterTypeInfo() { - if (exporterValueTreeName == "XCODE_MAC") return "MacOSX"; - if (exporterValueTreeName == "XCODE_IPHONE") return "iOS"; - if (exporterValueTreeName == "VS2019") return "VisualStudio2019"; - if (exporterValueTreeName == "VS2017") return "VisualStudio2017"; - if (exporterValueTreeName == "VS2015") return "VisualStudio2015"; - if (exporterValueTreeName == "LINUX_MAKE") return "LinuxMakefile"; - if (exporterValueTreeName == "ANDROIDSTUDIO") return "Android"; - if (exporterValueTreeName == "CODEBLOCKS_WINDOWS") return "CodeBlocksWindows"; - if (exporterValueTreeName == "CODEBLOCKS_LINUX") return "CodeBlocksLinux"; - if (exporterValueTreeName == "CLION") return "CLion"; - - return {}; + #if JUCE_MAC + return ProjectExporter::getTypeInfoForExporter (XcodeProjectExporter::getValueTreeTypeNameMac()); + #elif JUCE_WINDOWS + return ProjectExporter::getTypeInfoForExporter (MSVCProjectExporterVC2019::getValueTreeTypeName()); + #elif JUCE_LINUX + return ProjectExporter::getTypeInfoForExporter (MakefileProjectExporter::getValueTreeTypeName()); + #else + #error "unknown platform!" + #endif } -StringArray ProjectExporter::getAllDefaultBuildsFolders() +std::unique_ptr<ProjectExporter> ProjectExporter::createNewExporter (Project& project, const Identifier& exporterIdentifier) { - StringArray folders; + auto exporter = createExporterFromSettings (project, ValueTree (exporterIdentifier)); + jassert (exporter != nullptr); - folders.add (getDefaultBuildsRootFolder() + "iOS"); - folders.add (getDefaultBuildsRootFolder() + "MacOSX"); - folders.add (getDefaultBuildsRootFolder() + "VisualStudio2019"); - folders.add (getDefaultBuildsRootFolder() + "VisualStudio2017"); - folders.add (getDefaultBuildsRootFolder() + "VisualStudio2015"); - folders.add (getDefaultBuildsRootFolder() + "LinuxMakefile"); - folders.add (getDefaultBuildsRootFolder() + "CodeBlocksWindows"); - folders.add (getDefaultBuildsRootFolder() + "CodeBlocksLinux"); - folders.add (getDefaultBuildsRootFolder() + "Android"); - folders.add (getDefaultBuildsRootFolder() + "CLion"); - - return folders; -} + exporter->createDefaultConfigs(); + exporter->createDefaultModulePaths(); -String ProjectExporter::getCurrentPlatformExporterName() -{ - #if JUCE_MAC - return XcodeProjectExporter::getNameMac(); - #elif JUCE_WINDOWS - return MSVCProjectExporterVC2019::getName(); - #elif JUCE_LINUX - return MakefileProjectExporter::getNameLinux(); - #else - #error // huh? - #endif + return exporter; } -ProjectExporter* ProjectExporter::createNewExporter (Project& project, const String& name) +std::unique_ptr<ProjectExporter> ProjectExporter::createExporterFromSettings (Project& project, const ValueTree& settings) { - return createNewExporter (project, getExporterNames().indexOf (name)); -} + std::unique_ptr<ProjectExporter> exporter; -ProjectExporter* ProjectExporter::createExporter (Project& project, const ValueTree& settings) -{ - ProjectExporter* exp = MSVCProjectExporterVC2019 ::createForSettings (project, settings); - if (exp == nullptr) exp = MSVCProjectExporterVC2017 ::createForSettings (project, settings); - if (exp == nullptr) exp = MSVCProjectExporterVC2015 ::createForSettings (project, settings); - if (exp == nullptr) exp = XcodeProjectExporter ::createForSettings (project, settings); - if (exp == nullptr) exp = MakefileProjectExporter ::createForSettings (project, settings); - if (exp == nullptr) exp = AndroidProjectExporter ::createForSettings (project, settings); - if (exp == nullptr) exp = CodeBlocksProjectExporter ::createForSettings (project, settings); - if (exp == nullptr) exp = CLionProjectExporter ::createForSettings (project, settings); + exporter.reset (XcodeProjectExporter::createForSettings (project, settings)); + if (exporter == nullptr) exporter.reset (MSVCProjectExporterVC2019::createForSettings (project, settings)); + if (exporter == nullptr) exporter.reset (MSVCProjectExporterVC2017::createForSettings (project, settings)); + if (exporter == nullptr) exporter.reset (MSVCProjectExporterVC2015::createForSettings (project, settings)); + if (exporter == nullptr) exporter.reset (MakefileProjectExporter::createForSettings (project, settings)); + if (exporter == nullptr) exporter.reset (AndroidProjectExporter::createForSettings (project, settings)); + if (exporter == nullptr) exporter.reset (CodeBlocksProjectExporter::createForSettings (project, settings)); + if (exporter == nullptr) exporter.reset (CLionProjectExporter::createForSettings (project, settings)); - jassert (exp != nullptr); - return exp; + jassert (exporter != nullptr); + return exporter; } bool ProjectExporter::canProjectBeLaunched (Project* project) { if (project != nullptr) { - const char* types[] = + static Identifier types[] { - #if JUCE_MAC - XcodeProjectExporter::getValueTreeTypeName (false), - XcodeProjectExporter::getValueTreeTypeName (true), - #elif JUCE_WINDOWS - MSVCProjectExporterVC2019::getValueTreeTypeName(), - MSVCProjectExporterVC2017::getValueTreeTypeName(), - MSVCProjectExporterVC2015::getValueTreeTypeName(), - #elif JUCE_LINUX - // (this doesn't currently launch.. not really sure what it would do on linux) - //MakefileProjectExporter::getValueTreeTypeName(), - #endif - AndroidProjectExporter::getValueTreeTypeName(), - - nullptr + #if JUCE_MAC + XcodeProjectExporter::getValueTreeTypeNameMac(), + XcodeProjectExporter::getValueTreeTypeNameiOS(), + #elif JUCE_WINDOWS + MSVCProjectExporterVC2019::getValueTreeTypeName(), + MSVCProjectExporterVC2017::getValueTreeTypeName(), + MSVCProjectExporterVC2015::getValueTreeTypeName(), + #endif + AndroidProjectExporter::getValueTreeTypeName() }; - for (const char** type = types; *type != nullptr; ++type) - if (project->getExporters().getChildWithName (*type).isValid()) + for (auto& exporterIdentifier : types) + if (project->getExporters().getChildWithName (exporterIdentifier).isValid()) return true; } @@ -262,16 +212,23 @@ ProjectExporter::ProjectExporter (Project& p, const ValueTree& state) updateCompilerFlagValues(); } -ProjectExporter::~ProjectExporter() +String ProjectExporter::getUniqueName() const { -} + auto targetLocationString = getTargetLocationString(); + auto defaultBuildsRootFolder = getDefaultBuildsRootFolder(); -void ProjectExporter::updateDeprecatedProjectSettingsInteractively() {} + auto typeInfos = getExporterTypeInfos(); -String ProjectExporter::getName() const -{ - if (! getAllDefaultBuildsFolders().contains (getTargetLocationString())) - return name + " - " + getTargetLocationString(); + auto predicate = [targetLocationString, defaultBuildsRootFolder] (const ProjectExporter::ExporterTypeInfo& info) + { + return defaultBuildsRootFolder + info.targetFolder == targetLocationString; + }; + + auto iter = std::find_if (typeInfos.begin(), typeInfos.end(), + std::move (predicate)); + + if (iter == typeInfos.end()) + return name + " - " + targetLocationString; return name; } @@ -281,9 +238,9 @@ File ProjectExporter::getTargetFolder() const return project.resolveFilename (getTargetLocationString()); } -RelativePath ProjectExporter::rebaseFromProjectFolderToBuildTarget (const RelativePath& path) const +build_tools::RelativePath ProjectExporter::rebaseFromProjectFolderToBuildTarget (const build_tools::RelativePath& path) const { - return path.rebased (project.getProjectFolder(), getTargetFolder(), RelativePath::buildTargetFolder); + return path.rebased (project.getProjectFolder(), getTargetFolder(), build_tools::RelativePath::buildTargetFolder); } bool ProjectExporter::shouldFileBeCompiledByDefault (const File& file) const @@ -309,32 +266,24 @@ void ProjectExporter::createPropertyEditors (PropertyListBuilder& props) "The location of the folder in which the " + name + " project will be created. " "This path can be absolute, but it's much more sensible to make it relative to the jucer project directory."); - if ((shouldBuildTargetType (ProjectType::Target::VSTPlugIn) && project.shouldBuildVST()) || (project.isVSTPluginHost() && supportsTargetType (ProjectType::Target::VSTPlugIn))) + if ((shouldBuildTargetType (build_tools::ProjectType::Target::VSTPlugIn) && project.shouldBuildVST()) || (project.isVSTPluginHost() && supportsTargetType (build_tools::ProjectType::Target::VSTPlugIn))) { - props.add (new FilePathPropertyComponent (vstLegacyPathValueWrapper.wrappedValue, "VST (Legacy) SDK Folder", true, + props.add (new FilePathPropertyComponent (vstLegacyPathValueWrapper.getWrappedValueWithDefault(), "VST (Legacy) SDK Folder", true, getTargetOSForExporter() == TargetOS::getThisOS(), "*", project.getProjectFolder()), "If you're building a VST plug-in or host, you can use this field to override the global VST (Legacy) SDK path with a project-specific path. " "This can be an absolute path, or a path relative to the Projucer project file."); } - if ((shouldBuildTargetType (ProjectType::Target::VST3PlugIn) && project.shouldBuildVST3()) || (project.isVST3PluginHost() && supportsTargetType (ProjectType::Target::VST3PlugIn))) + if (shouldBuildTargetType (build_tools::ProjectType::Target::AAXPlugIn) && project.shouldBuildAAX()) { - props.add (new FilePathPropertyComponent (vst3PathValueWrapper.wrappedValue, "VST3 SDK Folder", true, - getTargetOSForExporter() == TargetOS::getThisOS(), "*", project.getProjectFolder()), - "If you're building a VST3 plug-in or host, you can use this field to override the global VST3 SDK path with a project-specific path. " - "This can be an absolute path, or a path relative to the Projucer project file."); - } - - if (shouldBuildTargetType (ProjectType::Target::AAXPlugIn) && project.shouldBuildAAX()) - { - props.add (new FilePathPropertyComponent (aaxPathValueWrapper.wrappedValue, "AAX SDK Folder", true, + props.add (new FilePathPropertyComponent (aaxPathValueWrapper.getWrappedValueWithDefault(), "AAX SDK Folder", true, getTargetOSForExporter() == TargetOS::getThisOS(), "*", project.getProjectFolder()), "If you're building an AAX plug-in, this must be the folder containing the AAX SDK. This can be an absolute path, or a path relative to the Projucer project file."); } - if (shouldBuildTargetType (ProjectType::Target::RTASPlugIn) && project.shouldBuildRTAS()) + if (shouldBuildTargetType (build_tools::ProjectType::Target::RTASPlugIn) && project.shouldBuildRTAS()) { - props.add (new FilePathPropertyComponent (rtasPathValueWrapper.wrappedValue, "RTAS SDK Folder", true, + props.add (new FilePathPropertyComponent (rtasPathValueWrapper.getWrappedValueWithDefault(), "RTAS SDK Folder", true, getTargetOSForExporter() == TargetOS::getThisOS(), "*", project.getProjectFolder()), "If you're building an RTAS plug-in, this must be the folder containing the RTAS SDK. This can be an absolute path, or a path relative to the Projucer project file."); } @@ -397,7 +346,7 @@ void ProjectExporter::createIconProperties (PropertyListBuilder& props) } //============================================================================== -void ProjectExporter::addSettingsForProjectType (const ProjectType& type) +void ProjectExporter::addSettingsForProjectType (const build_tools::ProjectType& type) { addVSTPathsIfPluginOrHost(); @@ -409,17 +358,19 @@ void ProjectExporter::addSettingsForProjectType (const ProjectType& type) void ProjectExporter::addVSTPathsIfPluginOrHost() { - if (((shouldBuildTargetType (ProjectType::Target::VSTPlugIn) && project.shouldBuildVST()) || project.isVSTPluginHost()) - || ((shouldBuildTargetType (ProjectType::Target::VST3PlugIn) && project.shouldBuildVST3()) || project.isVST3PluginHost())) + if (((shouldBuildTargetType (build_tools::ProjectType::Target::VSTPlugIn) && project.shouldBuildVST()) || project.isVSTPluginHost()) + || ((shouldBuildTargetType (build_tools::ProjectType::Target::VST3PlugIn) && project.shouldBuildVST3()) || project.isVST3PluginHost())) { addLegacyVSTFolderToPathIfSpecified(); - addVST3FolderToPath(); + + if (! project.isConfigFlagEnabled ("JUCE_CUSTOM_VST3_SDK")) + addToExtraSearchPaths (getInternalVST3SDKPath(), 0); } } void ProjectExporter::addCommonAudioPluginSettings() { - if (shouldBuildTargetType (ProjectType::Target::AAXPlugIn)) + if (shouldBuildTargetType (build_tools::ProjectType::Target::AAXPlugIn)) addAAXFoldersToPath(); // Note: RTAS paths are platform-dependent, impl -> addPlatformSpecificSettingsForProjectType @@ -430,33 +381,23 @@ void ProjectExporter::addLegacyVSTFolderToPathIfSpecified() auto vstFolder = getVSTLegacyPathString(); if (vstFolder.isNotEmpty()) - addToExtraSearchPaths (RelativePath (vstFolder, RelativePath::projectFolder), 0); + addToExtraSearchPaths (build_tools::RelativePath (vstFolder, build_tools::RelativePath::projectFolder), 0); } -RelativePath ProjectExporter::getInternalVST3SDKPath() +build_tools::RelativePath ProjectExporter::getInternalVST3SDKPath() { return getModuleFolderRelativeToProject ("juce_audio_processors") .getChildFile ("format_types") .getChildFile ("VST3_SDK"); } -void ProjectExporter::addVST3FolderToPath() -{ - auto vst3Folder = getVST3PathString(); - - if (vst3Folder.isNotEmpty()) - addToExtraSearchPaths (RelativePath (vst3Folder, RelativePath::projectFolder), 0); - else - addToExtraSearchPaths (getInternalVST3SDKPath(), 0); -} - void ProjectExporter::addAAXFoldersToPath() { auto aaxFolder = getAAXPathString(); if (aaxFolder.isNotEmpty()) { - RelativePath aaxFolderPath (aaxFolder, RelativePath::projectFolder); + build_tools::RelativePath aaxFolderPath (aaxFolder, build_tools::RelativePath::projectFolder); addToExtraSearchPaths (aaxFolderPath); addToExtraSearchPaths (aaxFolderPath.getChildFile ("Interfaces")); @@ -465,13 +406,16 @@ void ProjectExporter::addAAXFoldersToPath() } //============================================================================== -StringPairArray ProjectExporter::getAllPreprocessorDefs (const BuildConfiguration& config, const ProjectType::Target::Type targetType) const +StringPairArray ProjectExporter::getAllPreprocessorDefs (const BuildConfiguration& config, const build_tools::ProjectType::Target::Type targetType) const { auto defs = mergePreprocessorDefs (config.getAllPreprocessorDefs(), parsePreprocessorDefs (getExporterPreprocessorDefsString())); addDefaultPreprocessorDefs (defs); addTargetSpecificPreprocessorDefs (defs, targetType); + if (! project.shouldUseAppConfig()) + defs = mergePreprocessorDefs (project.getAppConfigDefs(), defs); + return defs; } @@ -480,30 +424,31 @@ StringPairArray ProjectExporter::getAllPreprocessorDefs() const auto defs = mergePreprocessorDefs (project.getPreprocessorDefs(), parsePreprocessorDefs (getExporterPreprocessorDefsString())); addDefaultPreprocessorDefs (defs); + return defs; } -void ProjectExporter::addTargetSpecificPreprocessorDefs (StringPairArray& defs, const ProjectType::Target::Type targetType) const +void ProjectExporter::addTargetSpecificPreprocessorDefs (StringPairArray& defs, const build_tools::ProjectType::Target::Type targetType) const { - std::pair<String, ProjectType::Target::Type> targetFlags[] = { - {"JucePlugin_Build_VST", ProjectType::Target::VSTPlugIn}, - {"JucePlugin_Build_VST3", ProjectType::Target::VST3PlugIn}, - {"JucePlugin_Build_AU", ProjectType::Target::AudioUnitPlugIn}, - {"JucePlugin_Build_AUv3", ProjectType::Target::AudioUnitv3PlugIn}, - {"JucePlugin_Build_RTAS", ProjectType::Target::RTASPlugIn}, - {"JucePlugin_Build_AAX", ProjectType::Target::AAXPlugIn}, - {"JucePlugin_Build_Standalone", ProjectType::Target::StandalonePlugIn}, - {"JucePlugin_Build_Unity", ProjectType::Target::UnityPlugIn} + std::pair<String, build_tools::ProjectType::Target::Type> targetFlags[] = { + {"JucePlugin_Build_VST", build_tools::ProjectType::Target::VSTPlugIn}, + {"JucePlugin_Build_VST3", build_tools::ProjectType::Target::VST3PlugIn}, + {"JucePlugin_Build_AU", build_tools::ProjectType::Target::AudioUnitPlugIn}, + {"JucePlugin_Build_AUv3", build_tools::ProjectType::Target::AudioUnitv3PlugIn}, + {"JucePlugin_Build_RTAS", build_tools::ProjectType::Target::RTASPlugIn}, + {"JucePlugin_Build_AAX", build_tools::ProjectType::Target::AAXPlugIn}, + {"JucePlugin_Build_Standalone", build_tools::ProjectType::Target::StandalonePlugIn}, + {"JucePlugin_Build_Unity", build_tools::ProjectType::Target::UnityPlugIn} }; - if (targetType == ProjectType::Target::SharedCodeTarget) + if (targetType == build_tools::ProjectType::Target::SharedCodeTarget) { for (auto& flag : targetFlags) defs.set (flag.first, (shouldBuildTargetType (flag.second) ? "1" : "0")); defs.set ("JUCE_SHARED_CODE", "1"); } - else if (targetType != ProjectType::Target::unspecified) + else if (targetType != build_tools::ProjectType::Target::unspecified) { for (auto& flag : targetFlags) defs.set (flag.first, (targetType == flag.second ? "1" : "0")); @@ -520,7 +465,8 @@ void ProjectExporter::addDefaultPreprocessorDefs (StringPairArray& defs) const String ProjectExporter::replacePreprocessorTokens (const ProjectExporter::BuildConfiguration& config, const String& sourceString) const { - return replacePreprocessorDefs (getAllPreprocessorDefs (config, ProjectType::Target::unspecified), sourceString); + return build_tools::replacePreprocessorDefs (getAllPreprocessorDefs (config, + build_tools::ProjectType::Target::unspecified), sourceString); } void ProjectExporter::copyMainGroupFromProject() @@ -541,9 +487,56 @@ Project::Item& ProjectExporter::getModulesGroup() return *modulesGroup; } -void ProjectExporter::addProjectPathToBuildPathList (StringArray& pathList, const RelativePath& pathFromProjectFolder, int index) const +//============================================================================== +static bool isWebBrowserComponentEnabled (Project& project) +{ + static String guiExtrasModule ("juce_gui_extra"); + + return (project.getEnabledModules().isModuleEnabled (guiExtrasModule) + && project.isConfigFlagEnabled ("JUCE_WEB_BROWSER", true)); +} + +static bool isCurlEnabled (Project& project) +{ + static String juceCoreModule ("juce_core"); + + return (project.getEnabledModules().isModuleEnabled (juceCoreModule) + && project.isConfigFlagEnabled ("JUCE_USE_CURL", true)); +} + +static bool isLoadCurlSymbolsLazilyEnabled (Project& project) { - auto localPath = RelativePath (rebaseFromProjectFolderToBuildTarget (pathFromProjectFolder)); + static String juceCoreModule ("juce_core"); + + return (project.getEnabledModules().isModuleEnabled (juceCoreModule) + && project.isConfigFlagEnabled ("JUCE_LOAD_CURL_SYMBOLS_LAZILY", false)); +} + +StringArray ProjectExporter::getLinuxPackages (PackageDependencyType type) const +{ + auto packages = linuxPackages; + + // don't add libcurl if curl symbols are loaded at runtime + if (isCurlEnabled (project) && ! isLoadCurlSymbolsLazilyEnabled (project)) + packages.add ("libcurl"); + + if (isWebBrowserComponentEnabled (project) && type == PackageDependencyType::compile) + { + packages.add ("webkit2gtk-4.0"); + packages.add ("gtk+-x11-3.0"); + } + + packages.removeEmptyStrings(); + packages.removeDuplicates (false); + + return packages; +} + +void ProjectExporter::addProjectPathToBuildPathList (StringArray& pathList, + const build_tools::RelativePath& pathFromProjectFolder, + int index) const +{ + auto localPath = build_tools::RelativePath (rebaseFromProjectFolderToBuildTarget (pathFromProjectFolder)); auto path = isVisualStudio() ? localPath.toWindowsStyle() : localPath.toUnixStyle(); @@ -551,12 +544,12 @@ void ProjectExporter::addProjectPathToBuildPathList (StringArray& pathList, cons pathList.insert (index, path); } -void ProjectExporter::addToModuleLibPaths (const RelativePath& pathFromProjectFolder) +void ProjectExporter::addToModuleLibPaths (const build_tools::RelativePath& pathFromProjectFolder) { addProjectPathToBuildPathList (moduleLibSearchPaths, pathFromProjectFolder); } -void ProjectExporter::addToExtraSearchPaths (const RelativePath& pathFromProjectFolder, int index) +void ProjectExporter::addToExtraSearchPaths (const build_tools::RelativePath& pathFromProjectFolder, int index) { addProjectPathToBuildPathList (extraSearchPaths, pathFromProjectFolder, index); } @@ -615,18 +608,18 @@ TargetOS::OS ProjectExporter::getTargetOSForExporter() const return targetOS; } -RelativePath ProjectExporter::getModuleFolderRelativeToProject (const String& moduleID) const +build_tools::RelativePath ProjectExporter::getModuleFolderRelativeToProject (const String& moduleID) const { if (project.getEnabledModules().shouldCopyModuleFilesLocally (moduleID)) - return RelativePath (project.getRelativePathForFile (project.getLocalModuleFolder (moduleID)), - RelativePath::projectFolder); + return build_tools::RelativePath (project.getRelativePathForFile (project.getLocalModuleFolder (moduleID)), + build_tools::RelativePath::projectFolder); auto path = getPathForModuleString (moduleID); if (path.isEmpty()) return getLegacyModulePath (moduleID).getChildFile (moduleID); - return RelativePath (path, RelativePath::projectFolder).getChildFile (moduleID); + return build_tools::RelativePath (path, build_tools::RelativePath::projectFolder).getChildFile (moduleID); } String ProjectExporter::getLegacyModulePath() const @@ -634,19 +627,19 @@ String ProjectExporter::getLegacyModulePath() const return getSettingString ("juceFolder"); } -RelativePath ProjectExporter::getLegacyModulePath (const String& moduleID) const +build_tools::RelativePath ProjectExporter::getLegacyModulePath (const String& moduleID) const { if (project.getEnabledModules().shouldCopyModuleFilesLocally (moduleID)) - return RelativePath (project.getRelativePathForFile (project.getGeneratedCodeFolder() - .getChildFile ("modules") - .getChildFile (moduleID)), RelativePath::projectFolder); + return build_tools::RelativePath (project.getRelativePathForFile (project.getGeneratedCodeFolder() + .getChildFile ("modules") + .getChildFile (moduleID)), build_tools::RelativePath::projectFolder); auto oldJucePath = getLegacyModulePath(); if (oldJucePath.isEmpty()) - return RelativePath(); + return build_tools::RelativePath(); - RelativePath p (oldJucePath, RelativePath::projectFolder); + build_tools::RelativePath p (oldJucePath, build_tools::RelativePath::projectFolder); if (p.getFileName() != "modules") p = p.getChildFile ("modules"); @@ -820,64 +813,6 @@ std::unique_ptr<Drawable> ProjectExporter::getSmallIcon() const return project.getMainGroup().findItemWithID (settings [Ids::smallIcon]).loadAsImageFile(); } -Image ProjectExporter::getBestIconForSize (int size, bool returnNullIfNothingBigEnough) const -{ - Drawable* im = nullptr; - - auto im1 = getSmallIcon(); - auto im2 = getBigIcon(); - - if (im1 != nullptr && im2 != nullptr) - { - if (im1->getWidth() >= size && im2->getWidth() >= size) - im = im1->getWidth() < im2->getWidth() ? im1.get() : im2.get(); - else if (im1->getWidth() >= size) - im = im1.get(); - else if (im2->getWidth() >= size) - im = im2.get(); - } - else - { - im = im1 != nullptr ? im1.get() : im2.get(); - } - - if (im == nullptr) - return {}; - - if (returnNullIfNothingBigEnough && im->getWidth() < size && im->getHeight() < size) - return {}; - - return rescaleImageForIcon (*im, size); -} - -Image ProjectExporter::rescaleImageForIcon (Drawable& d, const int size) -{ - if (auto* drawableImage = dynamic_cast<DrawableImage*> (&d)) - { - auto im = SoftwareImageType().convert (drawableImage->getImage()); - - if (im.getWidth() == size && im.getHeight() == size) - return im; - - // (scale it down in stages for better resampling) - while (im.getWidth() > 2 * size && im.getHeight() > 2 * size) - im = im.rescaled (im.getWidth() / 2, - im.getHeight() / 2); - - Image newIm (Image::ARGB, size, size, true, SoftwareImageType()); - Graphics g (newIm); - g.drawImageWithin (im, 0, 0, size, size, - RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize, false); - return newIm; - } - - Image im (Image::ARGB, size, size, true, SoftwareImageType()); - Graphics g (im); - d.drawWithin (g, im.getBounds().toFloat(), RectanglePlacement::centred, 1.0f); - return im; -} - - //============================================================================== ProjectExporter::ConfigIterator::ConfigIterator (ProjectExporter& e) : index (-1), exporter (e) @@ -910,28 +845,34 @@ bool ProjectExporter::ConstConfigIterator::next() //============================================================================== ProjectExporter::BuildConfiguration::BuildConfiguration (Project& p, const ValueTree& configNode, const ProjectExporter& e) : config (configNode), project (p), exporter (e), - isDebugValue (config, Ids::isDebug, getUndoManager(), getValue (Ids::isDebug)), - configNameValue (config, Ids::name, getUndoManager(), "Build Configuration"), - targetNameValue (config, Ids::targetName, getUndoManager(), project.getProjectFilenameRootString()), - targetBinaryPathValue (config, Ids::binaryPath, getUndoManager()), - recommendedWarningsValue (config, Ids::recommendedWarnings, getUndoManager()), - optimisationLevelValue (config, Ids::optimisation, getUndoManager()), - linkTimeOptimisationValue (config, Ids::linkTimeOptimisation, getUndoManager(), ! isDebug()), - ppDefinesValue (config, Ids::defines, getUndoManager()), - headerSearchPathValue (config, Ids::headerPath, getUndoManager()), - librarySearchPathValue (config, Ids::libraryPath, getUndoManager()), - userNotesValue (config, Ids::userNotes, getUndoManager()) + isDebugValue (config, Ids::isDebug, getUndoManager(), getValue (Ids::isDebug)), + configNameValue (config, Ids::name, getUndoManager(), "Build Configuration"), + targetNameValue (config, Ids::targetName, getUndoManager(), project.getProjectFilenameRootString()), + targetBinaryPathValue (config, Ids::binaryPath, getUndoManager()), + recommendedWarningsValue (config, Ids::recommendedWarnings, getUndoManager()), + optimisationLevelValue (config, Ids::optimisation, getUndoManager()), + linkTimeOptimisationValue (config, Ids::linkTimeOptimisation, getUndoManager(), ! isDebug()), + ppDefinesValue (config, Ids::defines, getUndoManager()), + headerSearchPathValue (config, Ids::headerPath, getUndoManager()), + librarySearchPathValue (config, Ids::libraryPath, getUndoManager()), + userNotesValue (config, Ids::userNotes, getUndoManager()), + usePrecompiledHeaderFileValue (config, Ids::usePrecompiledHeaderFile, getUndoManager(), false), + precompiledHeaderFileValue (config, Ids::precompiledHeaderFile, getUndoManager()) { recommendedCompilerWarningFlags["LLVM"] = { "-Wall", "-Wshadow-all", "-Wshorten-64-to-32", "-Wstrict-aliasing", "-Wuninitialized", "-Wunused-parameter", "-Wconversion", "-Wsign-compare", "-Wint-conversion", "-Wconditional-uninitialized", "-Woverloaded-virtual", "-Wreorder", "-Wconstant-conversion", "-Wsign-conversion", "-Wunused-private-field", "-Wbool-conversion", "-Wextra-semi", "-Wunreachable-code", "-Wzero-as-null-pointer-constant", "-Wcast-align", "-Winconsistent-missing-destructor-override", "-Wshift-sign-overflow", "-Wnullable-to-nonnull-conversion", - "-Wno-missing-field-initializers", "-Wno-ignored-qualifiers" }; + "-Wno-missing-field-initializers", "-Wno-ignored-qualifiers", + "-Wswitch-enum" + }; recommendedCompilerWarningFlags["GCC"] = { "-Wall", "-Wextra", "-Wstrict-aliasing", "-Wuninitialized", "-Wunused-parameter", "-Wsign-compare", "-Woverloaded-virtual", "-Wreorder", "-Wsign-conversion", "-Wunreachable-code", "-Wzero-as-null-pointer-constant", "-Wcast-align", "-Wno-implicit-fallthrough", - "-Wno-maybe-uninitialized", "-Wno-missing-field-initializers", "-Wno-ignored-qualifiers" }; + "-Wno-maybe-uninitialized", "-Wno-missing-field-initializers", "-Wno-ignored-qualifiers", + "-Wswitch-enum", "-Wredundant-decls" + }; recommendedCompilerWarningFlags["GCC-7"] = recommendedCompilerWarningFlags["GCC"]; recommendedCompilerWarningFlags["GCC-7"].add ("-Wno-strict-overflow"); } @@ -1021,6 +962,22 @@ void ProjectExporter::BuildConfiguration::createPropertyEditors (PropertyListBui props.add (new ChoicePropertyComponent (linkTimeOptimisationValue, "Link-Time Optimisation"), "Enable this to perform link-time code optimisation. This is recommended for release builds."); + if (exporter.supportsPrecompiledHeaders()) + { + props.add (new ChoicePropertyComponent (usePrecompiledHeaderFileValue, "Use Precompiled Header"), + "Enable this to turn on precompiled header support for this configuration. Use the setting " + "below to specify the header file to use."); + + auto quotedHeaderFileName = (getPrecompiledHeaderFilename() + ".h").quoted(); + + props.add (new FilePathPropertyComponentWithEnablement (precompiledHeaderFileValue, usePrecompiledHeaderFileValue, + "Precompiled Header File", false, true, "*", project.getProjectFolder()), + "Specify an input header file that will be used to generate a file named " + quotedHeaderFileName + " which is used to generate the " + "PCH file artefact for this exporter configuration. This file can be an absolute path, or relative to the jucer project folder. " + "The " + quotedHeaderFileName + " file will be force included to all source files unless the \"Skip PCH\" setting has been enabled. " + "The generated header will be written on project save and placed in the target folder for this exporter."); + } + createConfigProperties (props); props.add (new TextPropertyComponent (userNotesValue, "Notes", 32768, true), @@ -1071,6 +1028,31 @@ StringArray ProjectExporter::BuildConfiguration::getLibrarySearchPaths() const return s; } +String ProjectExporter::BuildConfiguration::getPrecompiledHeaderFileContent() const +{ + if (shouldUsePrecompiledHeaderFile()) + { + auto f = project.getProjectFolder().getChildFile (precompiledHeaderFileValue.get().toString()); + + if (f.existsAsFile() && f.hasFileExtension (headerFileExtensions)) + { + MemoryOutputStream content; + content.setNewLineString (exporter.getNewLineString()); + + writeAutoGenWarningComment (content); + + content << "*/" << newLine << newLine + << "#ifndef " << getSkipPrecompiledHeaderDefine() << newLine << newLine + << f.loadFileAsString() << newLine + << "#endif" << newLine; + + return content.toString(); + } + } + + return {}; +} + String ProjectExporter::getExternalLibraryFlags (const BuildConfiguration& config) const { auto libraries = StringArray::fromTokens (getExternalLibrariesString(), ";\n", "\"'"); diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.h b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.h index 2b75226d..5ba198e5 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.h +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -28,6 +27,8 @@ #include "../Project/jucer_Project.h" #include "../Utility/UI/PropertyComponents/jucer_PropertyComponentsWithEnablement.h" +#include "../Utility/Helpers/jucer_ValueWithDefaultWrapper.h" +#include "../Project/Modules/jucer_Modules.h" class ProjectSaver; @@ -36,40 +37,26 @@ class ProjectExporter : private Value::Listener { public: ProjectExporter (Project&, const ValueTree& settings); - virtual ~ProjectExporter() override; + virtual ~ProjectExporter() override = default; + //============================================================================== struct ExporterTypeInfo { - String name; - const void* iconData; - int iconDataSize; - - Image getIcon() const - { - Image image (Image::ARGB, 200, 200, true); - Graphics g (image); + Identifier identifier; + String displayName; + String targetFolder; - std::unique_ptr<Drawable> svgDrawable (Drawable::createFromImageData (iconData, (size_t) iconDataSize)); - - svgDrawable->drawWithin (g, image.getBounds().toFloat(), RectanglePlacement::fillDestination, 1.0f); - - return image; - } + Image icon; }; - static StringArray getExporterNames(); - static StringArray getExporterValueTreeNames(); - static Array<ExporterTypeInfo> getExporterTypes(); - static String getValueTreeNameForExporter (const String& exporterName); - static String getTargetFolderForExporter (const String& exporterValueTreeName); - static StringArray getAllDefaultBuildsFolders(); + static std::vector<ExporterTypeInfo> getExporterTypeInfos(); + static ExporterTypeInfo getTypeInfoForExporter (const Identifier& exporterIdentifier); + static ExporterTypeInfo getCurrentPlatformExporterTypeInfo(); - static ProjectExporter* createNewExporter (Project&, const int index); - static ProjectExporter* createNewExporter (Project&, const String& name); - static ProjectExporter* createExporter (Project&, const ValueTree& settings); - static bool canProjectBeLaunched (Project*); + static std::unique_ptr<ProjectExporter> createNewExporter (Project&, const Identifier& exporterIdentifier); + static std::unique_ptr<ProjectExporter> createExporterFromSettings (Project&, const ValueTree& settings); - static String getCurrentPlatformExporterName(); + static bool canProjectBeLaunched (Project*); //============================================================================== // capabilities of exporter @@ -81,8 +68,9 @@ public: virtual bool shouldFileBeCompiledByDefault (const File& path) const; virtual bool canCopeWithDuplicateFiles() = 0; virtual bool supportsUserDefinedConfigurations() const = 0; // false if exporter only supports two configs Debug and Release - virtual void updateDeprecatedProjectSettingsInteractively(); - virtual void initialiseDependencyPathValues() {} + virtual void updateDeprecatedSettings() {} + virtual void updateDeprecatedSettingsInteractively() {} + virtual void initialiseDependencyPathValues() {} // IDE targeted by exporter virtual bool isXcode() const = 0; @@ -99,22 +87,25 @@ public: virtual bool isOSX() const = 0; virtual bool isiOS() const = 0; - virtual String getDescription() { return {}; } + virtual String getNewLineString() const = 0; + virtual String getDescription() { return {}; } + + virtual bool supportsPrecompiledHeaders() const { return false; } //============================================================================== // cross-platform audio plug-ins supported by exporter - virtual bool supportsTargetType (ProjectType::Target::Type type) const = 0; + virtual bool supportsTargetType (build_tools::ProjectType::Target::Type type) const = 0; - inline bool shouldBuildTargetType (ProjectType::Target::Type type) const + inline bool shouldBuildTargetType (build_tools::ProjectType::Target::Type type) const { return project.shouldBuildTargetType (type) && supportsTargetType (type); } - inline void callForAllSupportedTargets (std::function<void (ProjectType::Target::Type)> callback) + inline void callForAllSupportedTargets (std::function<void (build_tools::ProjectType::Target::Type)> callback) { - for (int i = 0; i < ProjectType::Target::unspecified; ++i) - if (shouldBuildTargetType (static_cast<ProjectType::Target::Type> (i))) - callback (static_cast<ProjectType::Target::Type> (i)); + for (int i = 0; i < build_tools::ProjectType::Target::unspecified; ++i) + if (shouldBuildTargetType (static_cast<build_tools::ProjectType::Target::Type> (i))) + callback (static_cast<build_tools::ProjectType::Target::Type> (i)); } //============================================================================== @@ -132,7 +123,7 @@ public: } //============================================================================== - String getName() const; + String getUniqueName() const; File getTargetFolder() const; Project& getProject() noexcept { return project; } @@ -153,10 +144,9 @@ public: bool shouldUseGNUExtensions() const { return gnuExtensionsValue.get(); } - String getVSTLegacyPathString() const { return vstLegacyPathValueWrapper.wrappedValue.get(); } - String getVST3PathString() const { return vst3PathValueWrapper.wrappedValue.get(); } - String getAAXPathString() const { return aaxPathValueWrapper.wrappedValue.get(); } - String getRTASPathString() const { return rtasPathValueWrapper.wrappedValue.get(); } + String getVSTLegacyPathString() const { return vstLegacyPathValueWrapper.getCurrentValue(); } + String getAAXPathString() const { return aaxPathValueWrapper.getCurrentValue(); } + String getRTASPathString() const { return rtasPathValueWrapper.getCurrentValue(); } // NB: this is the path to the parent "modules" folder that contains the named module, not the // module folder itself. @@ -166,22 +156,22 @@ public: TargetOS::OS getTargetOSForExporter() const; - RelativePath getLegacyModulePath (const String& moduleID) const; + build_tools::RelativePath getLegacyModulePath (const String& moduleID) const; String getLegacyModulePath() const; // Returns a path to the actual module folder itself - RelativePath getModuleFolderRelativeToProject (const String& moduleID) const; + build_tools::RelativePath getModuleFolderRelativeToProject (const String& moduleID) const; void updateOldModulePaths(); - RelativePath rebaseFromProjectFolderToBuildTarget (const RelativePath& path) const; - void addToExtraSearchPaths (const RelativePath& pathFromProjectFolder, int index = -1); - void addToModuleLibPaths (const RelativePath& pathFromProjectFolder); + build_tools::RelativePath rebaseFromProjectFolderToBuildTarget (const build_tools::RelativePath& path) const; + void addToExtraSearchPaths (const build_tools::RelativePath& pathFromProjectFolder, int index = -1); + void addToModuleLibPaths (const build_tools::RelativePath& pathFromProjectFolder); - void addProjectPathToBuildPathList (StringArray&, const RelativePath&, int index = -1) const; + void addProjectPathToBuildPathList (StringArray&, const build_tools::RelativePath&, int index = -1) const; std::unique_ptr<Drawable> getBigIcon() const; std::unique_ptr<Drawable> getSmallIcon() const; - Image getBestIconForSize (int size, bool returnNullIfNothingBigEnough) const; + build_tools::Icons getIcons() const { return { getSmallIcon(), getBigIcon() }; } String getExporterIdentifierMacro() const { @@ -190,21 +180,8 @@ public: } // An exception that can be thrown by the create() method. - class SaveError - { - public: - SaveError (const String& error) : message (error) - {} - - SaveError (const File& fileThatFailedToWrite) - : message ("Can't write to the file: " + fileThatFailedToWrite.getFullPathName()) - {} - - String message; - }; - void createPropertyEditors (PropertyListBuilder&); - void addSettingsForProjectType (const ProjectType&); + void addSettingsForProjectType (const build_tools::ProjectType&); //============================================================================== void copyMainGroupFromProject(); @@ -215,6 +192,14 @@ public: //============================================================================== StringArray linuxLibs, linuxPackages, makefileExtraLinkerFlags; + enum class PackageDependencyType + { + compile, + link + }; + + StringArray getLinuxPackages (PackageDependencyType type) const; + //============================================================================== StringPairArray msvcExtraPreprocessorDefs; String msvcDelayLoadedDLLs; @@ -264,7 +249,12 @@ public: String getLibrarySearchPathString() const { return librarySearchPathValue.get(); } StringArray getLibrarySearchPaths() const; - String getGCCLibraryPathFlags() const; + + String getPrecompiledHeaderFilename() const { return "JucePrecompiledHeader_" + getName(); } + static String getSkipPrecompiledHeaderDefine() { return "JUCE_SKIP_PRECOMPILED_HEADER"; } + + bool shouldUsePrecompiledHeaderFile() const { return usePrecompiledHeaderFileValue.get(); } + String getPrecompiledHeaderFileContent() const; //============================================================================== Value getValue (const Identifier& nm) { return config.getPropertyAsValue (nm, getUndoManager()); } @@ -285,7 +275,8 @@ public: protected: ValueWithDefault isDebugValue, configNameValue, targetNameValue, targetBinaryPathValue, recommendedWarningsValue, optimisationLevelValue, - linkTimeOptimisationValue, ppDefinesValue, headerSearchPathValue, librarySearchPathValue, userNotesValue; + linkTimeOptimisationValue, ppDefinesValue, headerSearchPathValue, librarySearchPathValue, userNotesValue, + usePrecompiledHeaderFileValue, precompiledHeaderFileValue; private: std::map<String, StringArray> recommendedCompilerWarningFlags; @@ -347,11 +338,11 @@ public: String getExporterPreprocessorDefsString() const { return extraPPDefsValue.get(); } // includes exporter, project + config defs - StringPairArray getAllPreprocessorDefs (const BuildConfiguration& config, const ProjectType::Target::Type targetType) const; - // includes exporter + project defs.. + StringPairArray getAllPreprocessorDefs (const BuildConfiguration& config, const build_tools::ProjectType::Target::Type targetType) const; + // includes exporter + project defs StringPairArray getAllPreprocessorDefs() const; - void addTargetSpecificPreprocessorDefs (StringPairArray& defs, const ProjectType::Target::Type targetType) const; + void addTargetSpecificPreprocessorDefs (StringPairArray& defs, const build_tools::ProjectType::Target::Type targetType) const; String replacePreprocessorTokens (const BuildConfiguration&, const String& sourceString) const; @@ -367,46 +358,26 @@ public: gccOfast = 6 }; + bool isPCHEnabledForAnyConfigurations() const + { + if (supportsPrecompiledHeaders()) + for (ConstConfigIterator config (*this); config.next();) + if (config->shouldUsePrecompiledHeaderFile()) + return true; + + return false; + } + protected: //============================================================================== String name; Project& project; - const ProjectType& projectType; + const build_tools::ProjectType& projectType; const String projectName; const File projectFolder; //============================================================================== - // Wraps a ValueWithDefault object that has a default which depends on a global value. - // Used for the VST3, RTAS and AAX project-specific path options. - struct ValueWithDefaultWrapper : public Value::Listener - { - void init (const ValueWithDefault& vwd, ValueWithDefault global, TargetOS::OS targetOS) - { - wrappedValue = vwd; - globalValue = global.getPropertyAsValue(); - globalIdentifier = global.getPropertyID(); - os = targetOS; - - if (wrappedValue.get() == var()) - wrappedValue.resetToDefault(); - - globalValue.addListener (this); - valueChanged (globalValue); - } - - void valueChanged (Value&) override - { - wrappedValue.setDefault (getAppSettings().getStoredPath (globalIdentifier, os).get()); - } - - ValueWithDefault wrappedValue; - Value globalValue; - - Identifier globalIdentifier; - TargetOS::OS os; - }; - - ValueWithDefaultWrapper vstLegacyPathValueWrapper, vst3PathValueWrapper, rtasPathValueWrapper, aaxPathValueWrapper; + ValueWithDefaultWrapper vstLegacyPathValueWrapper, rtasPathValueWrapper, aaxPathValueWrapper; ValueWithDefault targetLocationValue, extraCompilerFlagsValue, extraLinkerFlagsValue, externalLibrariesValue, userNotesValue, gnuExtensionsValue, bigIconValue, smallIconValue, extraPPDefsValue; @@ -426,25 +397,13 @@ protected: static String getStaticLibbedFilename (String name) { return addSuffix (addLibPrefix (name), ".a"); } static String getDynamicLibbedFilename (String name) { return addSuffix (addLibPrefix (name), ".so"); } - virtual void addPlatformSpecificSettingsForProjectType (const ProjectType&) = 0; + virtual void addPlatformSpecificSettingsForProjectType (const build_tools::ProjectType&) = 0; //============================================================================== - static void overwriteFileIfDifferentOrThrow (const File& file, const MemoryOutputStream& newData) - { - if (! FileHelpers::overwriteFileWithNewDataIfDifferent (file, newData)) - throw SaveError (file); - } - - static void overwriteFileIfDifferentOrThrow (const File& file, const String& newData) - { - if (! FileHelpers::overwriteFileWithNewDataIfDifferent (file, newData)) - throw SaveError (file); - } - static void createDirectoryOrThrow (const File& dirToCreate) { if (! dirToCreate.createDirectory()) - throw SaveError ("Can't create folder: " + dirToCreate.getFullPathName()); + throw build_tools::SaveError ("Can't create folder: " + dirToCreate.getFullPathName()); } static void writeXmlOrThrow (const XmlElement& xml, const File& file, const String& encoding, @@ -457,11 +416,9 @@ protected: MemoryOutputStream mo (8192); xml.writeTo (mo, format); - overwriteFileIfDifferentOrThrow (file, mo); + build_tools::overwriteFileIfDifferentOrThrow (file, mo); } - static Image rescaleImageForIcon (Drawable&, int iconSize); - private: //============================================================================== void valueChanged (Value&) override { updateCompilerFlagValues(); } @@ -485,8 +442,7 @@ private: void addVSTPathsIfPluginOrHost(); void addCommonAudioPluginSettings(); void addLegacyVSTFolderToPathIfSpecified(); - RelativePath getInternalVST3SDKPath(); - void addVST3FolderToPath(); + build_tools::RelativePath getInternalVST3SDKPath(); void addAAXFoldersToPath(); JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProjectExporter) diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectSaver.cpp b/extras/Projucer/Source/ProjectSaving/jucer_ProjectSaver.cpp index cbfb88b9..be84d1b1 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectSaver.cpp +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectSaver.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -24,119 +23,655 @@ ============================================================================== */ -#include "../Application/jucer_Headers.h" #include "jucer_ProjectSaver.h" - #include "jucer_ProjectExport_CLion.h" +#include "../Application/jucer_Application.h" + +static constexpr const char* generatedGroupID = "__jucelibfiles"; +static constexpr const char* generatedGroupUID = "__generatedcode__"; + +constexpr int jucerFormatVersion = 1; //============================================================================== -namespace +ProjectSaver::ProjectSaver (Project& p) + : project (p), + generatedCodeFolder (project.getGeneratedCodeFolder()), + generatedFilesGroup (Project::Item::createGroup (project, getJuceCodeGroupName(), generatedGroupUID, true)), + projectLineFeed (project.getProjectLineFeed()) +{ + generatedFilesGroup.setID (generatedGroupID); +} + +Result ProjectSaver::save (ProjectExporter* exporterToSave) +{ + if (! ProjucerApplication::getApp().isRunningCommandLine) + { + SaveThreadWithProgressWindow thread (*this, exporterToSave); + thread.runThread(); + + return thread.result; + } + + return saveProject (exporterToSave); +} + +Result ProjectSaver::saveResourcesOnly() +{ + writeBinaryDataFiles(); + + if (! errors.isEmpty()) + return Result::fail (errors[0]); + + return Result::ok(); +} + +void ProjectSaver::saveBasicProjectItems (const OwnedArray<LibraryModule>& modules, const String& appConfigUserContent) { - inline int countMaxPluginChannels (const String& configString, bool isInput) + writePluginDefines(); + writeAppConfigFile (modules, appConfigUserContent); + writeBinaryDataFiles(); + writeAppHeader (modules); + writeModuleCppWrappers (modules); +} + +Result ProjectSaver::saveContentNeededForLiveBuild() +{ + auto modules = getModules(); + + if (errors.isEmpty()) + { + saveBasicProjectItems (modules, loadUserContentFromAppConfig()); + return Result::ok(); + } + + return Result::fail (errors[0]); +} + +Project::Item ProjectSaver::addFileToGeneratedGroup (const File& file) +{ + auto item = generatedFilesGroup.findItemForFile (file); + + if (item.isValid()) + return item; + + generatedFilesGroup.addFileAtIndex (file, -1, true); + return generatedFilesGroup.findItemForFile (file); +} + +bool ProjectSaver::copyFolder (const File& source, const File& dest) +{ + if (source.isDirectory() && dest.createDirectory()) { - auto configs = StringArray::fromTokens (configString, ", {}", {}); - configs.trim(); - configs.removeEmptyStrings(); - jassert ((configs.size() & 1) == 0); // looks like a syntax error in the configs? + for (auto& f : source.findChildFiles (File::findFiles, false)) + { + auto target = dest.getChildFile (f.getFileName()); + filesCreated.add (target); - int maxVal = 0; + if (! f.copyFileTo (target)) + return false; + } - for (int i = (isInput ? 0 : 1); i < configs.size(); i += 2) - maxVal = jmax (maxVal, configs[i].getIntValue()); + for (auto& f : source.findChildFiles (File::findDirectories, false)) + { + auto name = f.getFileName(); - return maxVal; + if (name == ".git" || name == ".svn" || name == ".cvs") + continue; + + if (! copyFolder (f, dest.getChildFile (f.getFileName()))) + return false; + } + + return true; + } + + return false; +} + +//============================================================================== +Project::Item ProjectSaver::saveGeneratedFile (const String& filePath, const MemoryOutputStream& newData) +{ + if (! generatedCodeFolder.createDirectory()) + { + addError ("Couldn't create folder: " + generatedCodeFolder.getFullPathName()); + return Project::Item (project, {}, false); + } + + auto file = generatedCodeFolder.getChildFile (filePath); + + if (replaceFileIfDifferent (file, newData)) + return addFileToGeneratedGroup (file); + + return { project, {}, true }; +} + +bool ProjectSaver::replaceFileIfDifferent (const File& f, const MemoryOutputStream& newData) +{ + filesCreated.add (f); + + if (! build_tools::overwriteFileWithNewDataIfDifferent (f, newData)) + { + addError ("Can't write to file: " + f.getFullPathName()); + return false; + } + + return true; +} + +bool ProjectSaver::deleteUnwantedFilesIn (const File& parent) +{ + // Recursively clears out any files in a folder that we didn't create, but avoids + // any folders containing hidden files that might be used by version-control systems. + auto shouldFileBeKept = [] (const String& filename) + { + static StringArray filesToKeep (".svn", ".cvs", "CMakeLists.txt"); + return filesToKeep.contains (filename); + }; + + bool folderIsNowEmpty = true; + Array<File> filesToDelete; + + for (const auto& i : RangedDirectoryIterator (parent, false, "*", File::findFilesAndDirectories)) + { + auto f = i.getFile(); + + if (filesCreated.contains (f) || shouldFileBeKept (f.getFileName())) + { + folderIsNowEmpty = false; + } + else if (i.isDirectory()) + { + if (deleteUnwantedFilesIn (f)) + filesToDelete.add (f); + else + folderIsNowEmpty = false; + } + else + { + filesToDelete.add (f); + } } - inline String boolToString (bool b) + for (int j = filesToDelete.size(); --j >= 0;) + filesToDelete.getReference (j).deleteRecursively(); + + return folderIsNowEmpty; +} + +//============================================================================== +void ProjectSaver::addError (const String& message) +{ + const ScopedLock sl (errorLock); + errors.add (message); +} + +//============================================================================== +File ProjectSaver::getAppConfigFile() const +{ + return generatedCodeFolder.getChildFile (Project::getAppConfigFilename()); +} + +File ProjectSaver::getPluginDefinesFile() const +{ + return generatedCodeFolder.getChildFile (Project::getPluginDefinesFilename()); +} + +String ProjectSaver::loadUserContentFromAppConfig() const +{ + StringArray userContent; + bool foundCodeSection = false; + auto lines = StringArray::fromLines (getAppConfigFile().loadFileAsString()); + + for (int i = 0; i < lines.size(); ++i) { - return b ? "1" : "0"; + if (lines[i].contains ("[BEGIN_USER_CODE_SECTION]")) + { + for (int j = i + 1; j < lines.size() && ! lines[j].contains ("[END_USER_CODE_SECTION]"); ++j) + userContent.add (lines[j]); + + foundCodeSection = true; + break; + } } - inline String toStringLiteral (const String& v) + if (! foundCodeSection) { - return CppTokeniserFunctions::addEscapeChars (v).quoted(); + userContent.add ({}); + userContent.add ("// (You can add your own code in this section, and the Projucer will not overwrite it)"); + userContent.add ({}); } - inline String toCharLiteral (const String& v) + return userContent.joinIntoString (projectLineFeed) + projectLineFeed; +} + +//============================================================================== +OwnedArray<LibraryModule> ProjectSaver::getModules() +{ + OwnedArray<LibraryModule> modules; + project.getEnabledModules().createRequiredModules (modules); + + auto isCommandLine = ProjucerApplication::getApp().isRunningCommandLine; + + for (auto* module : modules) { - auto fourCharCode = v.substring (0, 4); - uint32 hexRepresentation = 0; + if (! module->isValid()) + { + addError (String ("At least one of your JUCE module paths is invalid!\n") + + (isCommandLine ? "Please ensure each module path points to the correct JUCE modules folder." + : "Please go to the Modules settings page and ensure each path points to the correct JUCE modules folder.")); - for (int i = 0; i < 4; ++i) - hexRepresentation = (hexRepresentation << 8u) - | (static_cast<unsigned int> (fourCharCode[i]) & 0xffu); + return {}; + } - return "0x" + String::toHexString (static_cast<int> (hexRepresentation)) - + " // " - + CppTokeniserFunctions::addEscapeChars (fourCharCode).quoted ('\''); + if (project.getEnabledModules().getExtraDependenciesNeeded (module->getID()).size() > 0) + { + addError (String ("At least one of your modules has missing dependencies!\n") + + (isCommandLine ? "Please add the required dependencies, or run the command again with the \"--fix-missing-dependencies\" option." + : "Please go to the settings page of the highlighted modules and add the required dependencies.")); + + return {}; + } } + + return modules; } //============================================================================== -void ProjectSaver::writePluginCharacteristicsFile() -{ - StringPairArray flags; - flags.set ("JucePlugin_Build_VST", boolToString (project.shouldBuildVST())); - flags.set ("JucePlugin_Build_VST3", boolToString (project.shouldBuildVST3())); - flags.set ("JucePlugin_Build_AU", boolToString (project.shouldBuildAU())); - flags.set ("JucePlugin_Build_AUv3", boolToString (project.shouldBuildAUv3())); - flags.set ("JucePlugin_Build_RTAS", boolToString (project.shouldBuildRTAS())); - flags.set ("JucePlugin_Build_AAX", boolToString (project.shouldBuildAAX())); - flags.set ("JucePlugin_Build_Standalone", boolToString (project.shouldBuildStandalonePlugin())); - flags.set ("JucePlugin_Build_Unity", boolToString (project.shouldBuildUnityPlugin())); - flags.set ("JucePlugin_Enable_IAA", boolToString (project.shouldEnableIAA())); - flags.set ("JucePlugin_Name", toStringLiteral (project.getPluginNameString())); - flags.set ("JucePlugin_Desc", toStringLiteral (project.getPluginDescriptionString())); - flags.set ("JucePlugin_Manufacturer", toStringLiteral (project.getPluginManufacturerString())); - flags.set ("JucePlugin_ManufacturerWebsite", toStringLiteral (project.getCompanyWebsiteString())); - flags.set ("JucePlugin_ManufacturerEmail", toStringLiteral (project.getCompanyEmailString())); - flags.set ("JucePlugin_ManufacturerCode", toCharLiteral (project.getPluginManufacturerCodeString())); - flags.set ("JucePlugin_PluginCode", toCharLiteral (project.getPluginCodeString())); - flags.set ("JucePlugin_IsSynth", boolToString (project.isPluginSynth())); - flags.set ("JucePlugin_WantsMidiInput", boolToString (project.pluginWantsMidiInput())); - flags.set ("JucePlugin_ProducesMidiOutput", boolToString (project.pluginProducesMidiOutput())); - flags.set ("JucePlugin_IsMidiEffect", boolToString (project.isPluginMidiEffect())); - flags.set ("JucePlugin_EditorRequiresKeyboardFocus", boolToString (project.pluginEditorNeedsKeyFocus())); - flags.set ("JucePlugin_Version", project.getVersionString()); - flags.set ("JucePlugin_VersionCode", project.getVersionAsHex()); - flags.set ("JucePlugin_VersionString", toStringLiteral (project.getVersionString())); - flags.set ("JucePlugin_VSTUniqueID", "JucePlugin_PluginCode"); - flags.set ("JucePlugin_VSTCategory", project.getVSTCategoryString()); - flags.set ("JucePlugin_Vst3Category", toStringLiteral (project.getVST3CategoryString())); - flags.set ("JucePlugin_AUMainType", project.getAUMainTypeString()); - flags.set ("JucePlugin_AUSubType", "JucePlugin_PluginCode"); - flags.set ("JucePlugin_AUExportPrefix", project.getPluginAUExportPrefixString()); - flags.set ("JucePlugin_AUExportPrefixQuoted", toStringLiteral (project.getPluginAUExportPrefixString())); - flags.set ("JucePlugin_AUManufacturerCode", "JucePlugin_ManufacturerCode"); - flags.set ("JucePlugin_CFBundleIdentifier", project.getBundleIdentifierString()); - flags.set ("JucePlugin_RTASCategory", String (project.getRTASCategory())); - flags.set ("JucePlugin_RTASManufacturerCode", "JucePlugin_ManufacturerCode"); - flags.set ("JucePlugin_RTASProductId", "JucePlugin_PluginCode"); - flags.set ("JucePlugin_RTASDisableBypass", boolToString (project.isPluginRTASBypassDisabled())); - flags.set ("JucePlugin_RTASDisableMultiMono", boolToString (project.isPluginRTASMultiMonoDisabled())); - flags.set ("JucePlugin_AAXIdentifier", project.getAAXIdentifierString()); - flags.set ("JucePlugin_AAXManufacturerCode", "JucePlugin_ManufacturerCode"); - flags.set ("JucePlugin_AAXProductId", "JucePlugin_PluginCode"); - flags.set ("JucePlugin_AAXCategory", String (project.getAAXCategory())); - flags.set ("JucePlugin_AAXDisableBypass", boolToString (project.isPluginAAXBypassDisabled())); - flags.set ("JucePlugin_AAXDisableMultiMono", boolToString (project.isPluginAAXMultiMonoDisabled())); - flags.set ("JucePlugin_IAAType", toCharLiteral (project.getIAATypeCode())); - flags.set ("JucePlugin_IAASubType", "JucePlugin_PluginCode"); - flags.set ("JucePlugin_IAAName", project.getIAAPluginName().quoted()); - flags.set ("JucePlugin_VSTNumMidiInputs", project.getVSTNumMIDIInputsString()); - flags.set ("JucePlugin_VSTNumMidiOutputs", project.getVSTNumMIDIOutputsString()); - - { - String plugInChannelConfig = project.getPluginChannelConfigsString(); - - if (plugInChannelConfig.isNotEmpty()) - { - flags.set ("JucePlugin_MaxNumInputChannels", String (countMaxPluginChannels (plugInChannelConfig, true))); - flags.set ("JucePlugin_MaxNumOutputChannels", String (countMaxPluginChannels (plugInChannelConfig, false))); - flags.set ("JucePlugin_PreferredChannelConfigurations", plugInChannelConfig); +Result ProjectSaver::saveProject (ProjectExporter* specifiedExporterToSave) +{ + if (project.getNumExporters() == 0) + { + return Result::fail ("No exporters found!\n" + "Please add an exporter before saving."); + } + + auto oldProjectFile = project.getFile(); + auto modules = getModules(); + + if (errors.isEmpty()) + { + if (project.isAudioPluginProject()) + { + if (project.shouldBuildUnityPlugin()) + writeUnityScriptFile(); + } + + saveBasicProjectItems (modules, loadUserContentFromAppConfig()); + writeProjects (modules, specifiedExporterToSave); + writeProjectFile(); + + runPostExportScript(); + + if (generatedCodeFolder.exists()) + { + writeReadmeFile(); + deleteUnwantedFilesIn (generatedCodeFolder); } + + if (errors.isEmpty()) + return Result::ok(); } + project.setFile (oldProjectFile); + return Result::fail (errors[0]); +} + +//============================================================================== +void ProjectSaver::writePluginDefines (MemoryOutputStream& out) const +{ + const auto pluginDefines = getAudioPluginDefines(); + + if (pluginDefines.isEmpty()) + return; + + writeAutoGenWarningComment (out); + + out << "*/" << newLine << newLine + << "#pragma once" << newLine << newLine + << pluginDefines << newLine; +} + +void ProjectSaver::writeProjectFile() +{ + auto root = project.getProjectRoot(); + + root.removeProperty ("jucerVersion", nullptr); + + if ((int) root.getProperty (Ids::jucerFormatVersion, -1) != jucerFormatVersion) + root.setProperty (Ids::jucerFormatVersion, jucerFormatVersion, nullptr); + + project.updateCachedFileState(); + + auto newSerialisedXml = project.serialiseProjectXml (root.createXml()); + jassert (newSerialisedXml.isNotEmpty()); + + if (newSerialisedXml != project.getCachedFileStateContent()) + { + project.getFile().replaceWithText (newSerialisedXml); + project.updateCachedFileState(); + } +} + +void ProjectSaver::writeAppConfig (MemoryOutputStream& out, const OwnedArray<LibraryModule>& modules, const String& userContent) +{ + if (! project.shouldUseAppConfig()) + return; + + writeAutoGenWarningComment (out); + + out << " There's a section below where you can add your own custom code safely, and the" << newLine + << " Projucer will preserve the contents of that block, but the best way to change" << newLine + << " any of these definitions is by using the Projucer's project settings." << newLine + << newLine + << " Any commented-out settings will assume their default values." << newLine + << newLine + << "*/" << newLine + << newLine; + + out << "#pragma once" << newLine + << newLine + << "//==============================================================================" << newLine + << "// [BEGIN_USER_CODE_SECTION]" << newLine + << userContent + << "// [END_USER_CODE_SECTION]" << newLine; + + if (getPluginDefinesFile().existsAsFile() && getAudioPluginDefines().isNotEmpty()) + out << newLine << CodeHelpers::createIncludeStatement (Project::getPluginDefinesFilename()) << newLine; + + out << newLine + << "/*" << newLine + << " ==============================================================================" << newLine + << newLine + << " In accordance with the terms of the JUCE 6 End-Use License Agreement, the" << newLine + << " JUCE Code in SECTION A cannot be removed, changed or otherwise rendered" << newLine + << " ineffective unless you have a JUCE Indie or Pro license, or are using JUCE" << newLine + << " under the GPL v3 license." << newLine + << newLine + << " End User License Agreement: www.juce.com/juce-6-licence" << newLine + << newLine + << " ==============================================================================" << newLine + << "*/" << newLine + << newLine + << "// BEGIN SECTION A" << newLine + << newLine + << "#ifndef JUCE_DISPLAY_SPLASH_SCREEN" << newLine + << " #define JUCE_DISPLAY_SPLASH_SCREEN " << (project.shouldDisplaySplashScreen() ? "1" : "0") << newLine + << "#endif" << newLine << newLine + << "// END SECTION A" << newLine + << 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; + + auto longestModuleName = [&modules]() + { + int longest = 0; + + for (auto* module : modules) + longest = jmax (longest, module->getID().length()); + + return longest; + }(); + + for (auto* module : modules) + { + out << "#define JUCE_MODULE_AVAILABLE_" << module->getID() + << String::repeatedString (" ", longestModuleName + 5 - module->getID().length()) << " 1" << newLine; + } + + out << newLine << "#define JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED 1" << newLine; + + for (auto* module : modules) + { + OwnedArray<Project::ConfigFlag> flags; + module->getConfigFlags (project, flags); + + if (flags.size() > 0) + { + out << newLine + << "//==============================================================================" << newLine + << "// " << module->getID() << " flags:" << newLine; + + for (auto* flag : flags) + { + out << newLine + << "#ifndef " << flag->symbol + << newLine + << (flag->value.isUsingDefault() ? " //#define " : " #define ") << flag->symbol << " " << (flag->value.get() ? "1" : "0") + << newLine + << "#endif" + << newLine; + } + } + } + + auto& type = project.getProjectType(); + auto isStandaloneApplication = (! type.isAudioPlugin() && ! type.isDynamicLibrary()); + + out << newLine + << "//==============================================================================" << newLine + << "#ifndef JUCE_STANDALONE_APPLICATION" << newLine + << " #if defined(JucePlugin_Name) && defined(JucePlugin_Build_Standalone)" << newLine + << " #define JUCE_STANDALONE_APPLICATION JucePlugin_Build_Standalone" << newLine + << " #else" << newLine + << " #define JUCE_STANDALONE_APPLICATION " << (isStandaloneApplication ? "1" : "0") << newLine + << " #endif" << newLine + << "#endif" << newLine; +} + +template <typename WriterCallback> +void ProjectSaver::writeOrRemoveGeneratedFile (const String& name, WriterCallback&& writerCallback) +{ + MemoryOutputStream mem; + mem.setNewLineString (projectLineFeed); + + writerCallback (mem); + + if (mem.getDataSize() != 0) + { + saveGeneratedFile (name, mem); + return; + } + + const auto destFile = generatedCodeFolder.getChildFile (name); + + if (destFile.existsAsFile()) + { + if (! destFile.deleteFile()) + addError ("Couldn't remove unnecessary file: " + destFile.getFullPathName()); + } +} + +void ProjectSaver::writePluginDefines() +{ + writeOrRemoveGeneratedFile (Project::getPluginDefinesFilename(), [&] (MemoryOutputStream& mem) + { + writePluginDefines (mem); + }); +} + +void ProjectSaver::writeAppConfigFile (const OwnedArray<LibraryModule>& modules, const String& userContent) +{ + writeOrRemoveGeneratedFile (Project::getAppConfigFilename(), [&] (MemoryOutputStream& mem) + { + writeAppConfig (mem, modules, userContent); + }); +} + +void ProjectSaver::writeAppHeader (MemoryOutputStream& out, const OwnedArray<LibraryModule>& modules) +{ + writeAutoGenWarningComment (out); + + out << " This is the header file that your files should include in order to get all the" << newLine + << " JUCE library headers. You should avoid including the JUCE headers directly in" << newLine + << " your own source files, because that wouldn't pick up the correct configuration" << newLine + << " options for your app." << newLine + << newLine + << "*/" << newLine << newLine; + + out << "#pragma once" << newLine << newLine; + + if (getAppConfigFile().exists() && project.shouldUseAppConfig()) + out << CodeHelpers::createIncludeStatement (Project::getAppConfigFilename()) << newLine; + + if (modules.size() > 0) + { + out << newLine; + + for (auto* module : modules) + module->writeIncludes (*this, out); + + out << newLine; + } + + if (hasBinaryData && project.shouldIncludeBinaryInJuceHeader()) + out << CodeHelpers::createIncludeStatement (project.getBinaryDataHeaderFile(), getAppConfigFile()) << 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 (project.shouldAddUsingNamespaceToJuceHeader()) + out << "#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 + << " using namespace juce;" << newLine + << "#endif" << newLine; + + out << newLine + << "#if ! JUCE_DONT_DECLARE_PROJECTINFO" << newLine + << "namespace ProjectInfo" << newLine + << "{" << newLine + << " const char* const projectName = " << CppTokeniserFunctions::addEscapeChars (project.getProjectNameString()).quoted() << ";" << newLine + << " const char* const companyName = " << CppTokeniserFunctions::addEscapeChars (project.getCompanyNameString()).quoted() << ";" << newLine + << " const char* const versionString = " << CppTokeniserFunctions::addEscapeChars (project.getVersionString()).quoted() << ";" << newLine + << " const int versionNumber = " << project.getVersionAsHex() << ";" << newLine + << "}" << newLine + << "#endif" << newLine; +} + +void ProjectSaver::writeAppHeader (const OwnedArray<LibraryModule>& modules) +{ + MemoryOutputStream mem; + mem.setNewLineString (projectLineFeed); + + writeAppHeader (mem, modules); + saveGeneratedFile (Project::getJuceSourceHFilename(), mem); +} + +void ProjectSaver::writeModuleCppWrappers (const OwnedArray<LibraryModule>& modules) +{ + for (auto* module : modules) + { + for (auto& cu : module->getAllCompileUnits()) + { + MemoryOutputStream mem; + mem.setNewLineString (projectLineFeed); + + writeAutoGenWarningComment (mem); + + mem << "*/" << newLine << newLine; + + if (project.shouldUseAppConfig()) + mem << "#include " << Project::getAppConfigFilename().quoted() << newLine; + + mem << "#include <"; + + if (cu.file.getFileExtension() != ".r") // .r files are included without the path + mem << module->getID() << "/"; + + mem << cu.file.getFileName() << ">" << newLine; + + replaceFileIfDifferent (generatedCodeFolder.getChildFile (cu.getFilenameForProxyFile()), mem); + } + } +} + +void ProjectSaver::writeBinaryDataFiles() +{ + auto binaryDataH = project.getBinaryDataHeaderFile(); + + JucerResourceFile resourceFile (project); + + if (resourceFile.getNumFiles() > 0) + { + auto dataNamespace = project.getBinaryDataNamespaceString().trim(); + + if (dataNamespace.isEmpty()) + dataNamespace = "BinaryData"; + + resourceFile.setClassName (dataNamespace); + + auto maxSize = project.getMaxBinaryFileSize(); + + if (maxSize <= 0) + maxSize = 10 * 1024 * 1024; + + Array<File> binaryDataFiles; + auto r = resourceFile.write (maxSize); + + if (r.result.wasOk()) + { + hasBinaryData = true; + + for (auto& f : r.filesCreated) + { + filesCreated.add (f); + generatedFilesGroup.addFileRetainingSortOrder (f, ! f.hasFileExtension (".h")); + } + } + else + { + addError (r.result.getErrorMessage()); + } + } + else + { + for (int i = 20; --i >= 0;) + project.getBinaryDataCppFile (i).deleteFile(); + + binaryDataH.deleteFile(); + } +} + +void ProjectSaver::writeReadmeFile() +{ + MemoryOutputStream out; + out.setNewLineString (projectLineFeed); + + out << newLine + << " Important Note!!" << newLine + << " ================" << newLine + << newLine + << "The purpose of this folder is to contain files that are auto-generated by the Projucer," << newLine + << "and ALL files in this folder will be mercilessly DELETED and completely re-written whenever" << newLine + << "the Projucer saves your project." << newLine + << newLine + << "Therefore, it's a bad idea to make any manual changes to the files in here, or to" << newLine + << "put any of your own files in here if you don't want to lose them. (Of course you may choose" << newLine + << "to add the folder's contents to your version-control system so that you can re-merge your own" << newLine + << "modifications after the Projucer has saved its changes)." << newLine; + + replaceFileIfDifferent (generatedCodeFolder.getChildFile ("ReadMe.txt"), out); +} + +String ProjectSaver::getAudioPluginDefines() const +{ + const auto flags = project.getAudioPluginFlags(); + + if (flags.size() == 0) + return {}; + MemoryOutputStream mem; mem.setNewLineString (projectLineFeed); @@ -152,10 +687,30 @@ void ProjectSaver::writePluginCharacteristicsFile() << "#endif" << newLine; } - setExtraAppConfigFileContent (mem.toString()); + return mem.toString().trim(); +} + +void ProjectSaver::writeUnityScriptFile() +{ + auto unityScriptContents = replaceLineFeeds (BinaryData::UnityPluginGUIScript_cs_in, + projectLineFeed); + + auto projectName = Project::addUnityPluginPrefixIfNecessary (project.getProjectNameString()); + + unityScriptContents = unityScriptContents.replace ("${plugin_class_name}", projectName.replace (" ", "_")) + .replace ("${plugin_name}", projectName) + .replace ("${plugin_vendor}", project.getPluginManufacturerString()) + .replace ("${plugin_description}", project.getPluginDescriptionString()); + + auto f = generatedCodeFolder.getChildFile (project.getUnityScriptName()); + + MemoryOutputStream out; + out << unityScriptContents; + + replaceFileIfDifferent (f, out); } -void ProjectSaver::writeProjects (const OwnedArray<LibraryModule>& modules, const String& specifiedExporterToSave, bool isCommandLineApp) +void ProjectSaver::writeProjects (const OwnedArray<LibraryModule>& modules, ProjectExporter* specifiedExporterToSave) { ThreadPool threadPool; @@ -163,46 +718,49 @@ void ProjectSaver::writeProjects (const OwnedArray<LibraryModule>& modules, cons auto originalGeneratedGroup = generatedFilesGroup.state.createCopy(); CLionProjectExporter* clionExporter = nullptr; - OwnedArray<ProjectExporter> exporters; + std::vector<std::unique_ptr<ProjectExporter>> exporters; try { for (Project::ExporterIterator exp (project); exp.next();) { - if (specifiedExporterToSave.isNotEmpty() && exp->getName() != specifiedExporterToSave) + if (specifiedExporterToSave != nullptr && exp->getUniqueName() != specifiedExporterToSave->getUniqueName()) continue; - auto exporter = exporters.add (std::move (exp.exporter)); + exporters.push_back (std::move (exp.exporter)); + } + for (auto& exporter : exporters) + { exporter->initialiseDependencyPathValues(); if (exporter->getTargetFolder().createDirectory()) { if (exporter->isCLion()) { - clionExporter = dynamic_cast<CLionProjectExporter*> (exporter); + clionExporter = dynamic_cast<CLionProjectExporter*> (exporter.get()); } else { exporter->copyMainGroupFromProject(); exporter->settings = exporter->settings.createCopy(); - exporter->addToExtraSearchPaths (RelativePath ("JuceLibraryCode", RelativePath::projectFolder)); + exporter->addToExtraSearchPaths (build_tools::RelativePath ("JuceLibraryCode", build_tools::RelativePath::projectFolder)); generatedFilesGroup.state = originalGeneratedGroup.createCopy(); exporter->addSettingsForProjectType (project.getProjectType()); - for (auto& module: modules) + for (auto* module : modules) module->addSettingsForModuleToExporter (*exporter, *this); generatedFilesGroup.sortAlphabetically (true, true); exporter->getAllGroups().add (generatedFilesGroup); } - if (isCommandLineApp) - saveExporter (exporter, modules); + if (ProjucerApplication::getApp().isRunningCommandLine) + saveExporter (*exporter, modules); else - threadPool.addJob (new ExporterJob (*this, exporter, modules), true); + threadPool.addJob ([this, &exporter, &modules] { saveExporter (*exporter, modules); }); } else { @@ -210,20 +768,81 @@ void ProjectSaver::writeProjects (const OwnedArray<LibraryModule>& modules, cons } } } - catch (ProjectExporter::SaveError& saveError) + catch (build_tools::SaveError& saveError) { addError (saveError.message); } - if (! isCommandLineApp) - while (threadPool.getNumJobs() > 0) - Thread::sleep (10); + while (threadPool.getNumJobs() > 0) + Thread::sleep (10); if (clionExporter != nullptr) { - for (auto* exporter : exporters) - clionExporter->writeCMakeListsExporterSection (exporter); + for (auto& exporter : exporters) + clionExporter->writeCMakeListsExporterSection (exporter.get()); + + std::cout << "Finished saving: " << clionExporter->getUniqueName() << std::endl; + } +} + +void ProjectSaver::runPostExportScript() +{ + #if JUCE_WINDOWS + auto cmdString = project.getPostExportShellCommandWinString(); + #else + auto cmdString = project.getPostExportShellCommandPosixString(); + #endif + + auto shellCommand = cmdString.replace ("%%1%%", project.getProjectFolder().getFullPathName()); + + if (shellCommand.isNotEmpty()) + { + #if JUCE_WINDOWS + StringArray argList ("cmd.exe", "/c"); + #else + StringArray argList ("/bin/sh", "-c"); + #endif + + argList.add (shellCommand); + ChildProcess shellProcess; + + if (! shellProcess.start (argList)) + { + addError ("Failed to run shell command: " + argList.joinIntoString (" ")); + return; + } - std::cout << "Finished saving: " << clionExporter->getName() << std::endl; + if (! shellProcess.waitForProcessToFinish (10000)) + { + addError ("Timeout running shell command: " + argList.joinIntoString (" ")); + return; + } + + auto exitCode = shellProcess.getExitCode(); + + if (exitCode != 0) + addError ("Shell command: " + argList.joinIntoString (" ") + " failed with exit code: " + String (exitCode)); + } +} + +void ProjectSaver::saveExporter (ProjectExporter& exporter, const OwnedArray<LibraryModule>& modules) +{ + try + { + exporter.create (modules); + + if (! exporter.isCLion()) + { + auto outputString = "Finished saving: " + exporter.getUniqueName(); + + if (MessageManager::getInstance()->isThisTheMessageThread()) + std::cout << outputString << std::endl; + else + MessageManager::callAsync ([outputString] { std::cout << outputString << std::endl; }); + } + } + catch (build_tools::SaveError& error) + { + addError (error.message); } } diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectSaver.h b/extras/Projucer/Source/ProjectSaving/jucer_ProjectSaver.h index ec3ae4a0..e3d0348c 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectSaver.h +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectSaver.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -26,777 +25,102 @@ #pragma once +#include "../Application/jucer_Headers.h" #include "jucer_ResourceFile.h" -#include "../Project/jucer_Module.h" +#include "../Project/Modules/jucer_Modules.h" #include "jucer_ProjectExporter.h" //============================================================================== class ProjectSaver { public: - ProjectSaver (Project& p, const File& file) - : project (p), - projectFile (file), - generatedCodeFolder (project.getGeneratedCodeFolder()), - generatedFilesGroup (Project::Item::createGroup (project, getJuceCodeGroupName(), "__generatedcode__", true)) - { - generatedFilesGroup.setID (getGeneratedGroupID()); - } + ProjectSaver (Project& projectToSave); + + Result save (ProjectExporter* exporterToSave = nullptr); + Result saveResourcesOnly(); + void saveBasicProjectItems (const OwnedArray<LibraryModule>& modules, const String& appConfigUserContent); + Result saveContentNeededForLiveBuild(); + + Project& getProject() { return project; } + + Project::Item addFileToGeneratedGroup (const File& file); + bool copyFolder (const File& source, const File& dest); - struct SaveThread : public ThreadWithProgressWindow + static String getJuceCodeGroupName() { return "JUCE Library Code"; } + +private: + //============================================================================== + struct SaveThreadWithProgressWindow : public ThreadWithProgressWindow { public: - SaveThread (ProjectSaver& ps, bool wait, const String& exp) + SaveThreadWithProgressWindow (ProjectSaver& ps, ProjectExporter* exporterToSave) : ThreadWithProgressWindow ("Saving...", true, false), saver (ps), - shouldWaitAfterSaving (wait), - specifiedExporterToSave (exp) + specifiedExporterToSave (exporterToSave) {} void run() override { setProgress (-1); - result = saver.save (false, shouldWaitAfterSaving, specifiedExporterToSave); + result = saver.saveProject (specifiedExporterToSave); } ProjectSaver& saver; Result result = Result::ok(); - bool shouldWaitAfterSaving; - String specifiedExporterToSave; + ProjectExporter* specifiedExporterToSave; - JUCE_DECLARE_NON_COPYABLE (SaveThread) + JUCE_DECLARE_NON_COPYABLE (SaveThreadWithProgressWindow) }; - Result save (bool showProgressBox, bool waitAfterSaving, const String& specifiedExporterToSave) - { - if (showProgressBox) - { - SaveThread thread (*this, waitAfterSaving, specifiedExporterToSave); - thread.runThread(); - return thread.result; - } - - projectLineFeed = project.getProjectLineFeed(); - - auto appConfigUserContent = loadUserContentFromAppConfig(); - - auto oldFile = project.getFile(); - project.setFile (projectFile); + //============================================================================== + Project::Item saveGeneratedFile (const String& filePath, const MemoryOutputStream& newData); + bool replaceFileIfDifferent (const File& f, const MemoryOutputStream& newData); + bool deleteUnwantedFilesIn (const File& parent); - OwnedArray<LibraryModule> modules; - project.getEnabledModules().createRequiredModules (modules); - - checkModuleValidity (modules); - - if (errors.size() == 0) - { - writeMainProjectFile(); - project.updateModificationTime(); + void addError (const String& message); - auto projectRootHash = project.getProjectRoot().toXmlString().hashCode(); + File getAppConfigFile() const; + File getPluginDefinesFile() const; - if (project.isAudioPluginProject()) - { - writePluginCharacteristicsFile(); - - if (project.shouldBuildUnityPlugin()) - writeUnityScriptFile(); - } - - writeAppConfigFile (modules, appConfigUserContent); - writeBinaryDataFiles(); - writeAppHeader (modules); - writeModuleCppWrappers (modules); - writeProjects (modules, specifiedExporterToSave, ! showProgressBox); - runPostExportScript(); - - // if the project root has changed after writing the other files then re-save it - if (project.getProjectRoot().toXmlString().hashCode() != projectRootHash) - { - writeMainProjectFile(); - project.updateModificationTime(); - } - - if (generatedCodeFolder.exists()) - { - writeReadmeFile(); - deleteUnwantedFilesIn (generatedCodeFolder); - } - - if (errors.size() == 0) - { - // Workaround for a bug where Xcode thinks the project is invalid if opened immediately - // after writing - if (waitAfterSaving) - Thread::sleep (2000); - - return Result::ok(); - } - } - - project.setFile (oldFile); - return Result::fail (errors[0]); - } - - Result saveResourcesOnly() - { - writeBinaryDataFiles(); - - if (errors.size() > 0) - return Result::fail (errors[0]); - - return Result::ok(); - } - - Result saveContentNeededForLiveBuild() - { - OwnedArray<LibraryModule> modules; - project.getEnabledModules().createRequiredModules (modules); + String loadUserContentFromAppConfig() const; + String getAudioPluginDefines() const; + OwnedArray<LibraryModule> getModules(); - checkModuleValidity (modules); + Result saveProject (ProjectExporter* specifiedExporterToSave); - if (errors.size() == 0) - { - if (project.isAudioPluginProject()) - writePluginCharacteristicsFile(); - - writeAppConfigFile (modules, loadUserContentFromAppConfig()); - writeBinaryDataFiles(); - writeAppHeader (modules); - writeModuleCppWrappers (modules); - - return Result::ok(); - } - - return Result::fail (errors[0]); - } - - Project::Item saveGeneratedFile (const String& filePath, const MemoryOutputStream& newData) - { - if (! generatedCodeFolder.createDirectory()) - { - addError ("Couldn't create folder: " + generatedCodeFolder.getFullPathName()); - return Project::Item (project, ValueTree(), false); - } - - auto file = generatedCodeFolder.getChildFile (filePath); - - if (replaceFileIfDifferent (file, newData)) - return addFileToGeneratedGroup (file); - - return { project, {}, true }; - } - - Project::Item addFileToGeneratedGroup (const File& file) - { - auto item = generatedFilesGroup.findItemForFile (file); - - if (item.isValid()) - return item; - - generatedFilesGroup.addFileAtIndex (file, -1, true); - return generatedFilesGroup.findItemForFile (file); - } - - void setExtraAppConfigFileContent (const String& content) - { - extraAppConfigContent = content; - } - - static void writeAutoGenWarningComment (OutputStream& out) - { - out << "/*" << newLine << newLine - << " IMPORTANT! This file is auto-generated each time you save your" << newLine - << " project - if you alter its contents, your changes may be overwritten!" << newLine - << newLine; - } - - static const char* getGeneratedGroupID() noexcept { return "__jucelibfiles"; } - Project::Item& getGeneratedCodeGroup() { return generatedFilesGroup; } - - static String getJuceCodeGroupName() { return "JUCE Library Code"; } - - File getGeneratedCodeFolder() const { return generatedCodeFolder; } - - bool replaceFileIfDifferent (const File& f, const MemoryOutputStream& newData) - { - filesCreated.add (f); - - if (! FileHelpers::overwriteFileWithNewDataIfDifferent (f, newData)) - { - addError ("Can't write to file: " + f.getFullPathName()); - return false; - } + template <typename WriterCallback> + void writeOrRemoveGeneratedFile (const String& name, WriterCallback&& writerCallback); - return true; - } + void writePluginDefines (MemoryOutputStream& outStream) const; + void writePluginDefines(); + void writeAppConfigFile (const OwnedArray<LibraryModule>& modules, const String& userContent); - static bool shouldFolderBeIgnoredWhenCopying (const File& f) - { - return f.getFileName() == ".git" || f.getFileName() == ".svn" || f.getFileName() == ".cvs"; - } - - bool copyFolder (const File& source, const File& dest) - { - if (source.isDirectory() && dest.createDirectory()) - { - for (auto& f : source.findChildFiles (File::findFiles, false)) - { - auto target = dest.getChildFile (f.getFileName()); - filesCreated.add (target); - - if (! f.copyFileTo (target)) - return false; - } - - for (auto& f : source.findChildFiles (File::findDirectories, false)) - if (! shouldFolderBeIgnoredWhenCopying (f)) - if (! copyFolder (f, dest.getChildFile (f.getFileName()))) - return false; - - return true; - } - - return false; - } + void writeProjectFile(); + void writeAppConfig (MemoryOutputStream& outStream, const OwnedArray<LibraryModule>& modules, const String& userContent); + void writeAppHeader (MemoryOutputStream& outStream, const OwnedArray<LibraryModule>& modules); + void writeAppHeader (const OwnedArray<LibraryModule>& modules); + void writeModuleCppWrappers (const OwnedArray<LibraryModule>& modules); + void writeBinaryDataFiles(); + void writeReadmeFile(); + void writePluginCharacteristicsFile(); + void writeUnityScriptFile(); + void writeProjects (const OwnedArray<LibraryModule>&, ProjectExporter*); + void runPostExportScript(); + void saveExporter (ProjectExporter& exporter, const OwnedArray<LibraryModule>& modules); + //============================================================================== Project& project; - SortedSet<File> filesCreated; -private: - const File projectFile, generatedCodeFolder; + File generatedCodeFolder; Project::Item generatedFilesGroup; - String extraAppConfigContent; - StringArray errors; + SortedSet<File> filesCreated; + String projectLineFeed; + CriticalSection errorLock; + StringArray errors; - File appConfigFile; bool hasBinaryData = false; - String projectLineFeed = "\r\n"; - - // Recursively clears out any files in a folder that we didn't create, but avoids - // any folders containing hidden files that might be used by version-control systems. - bool deleteUnwantedFilesIn (const File& parent) - { - bool folderIsNowEmpty = true; - DirectoryIterator i (parent, false, "*", File::findFilesAndDirectories); - Array<File> filesToDelete; - - bool isFolder; - while (i.next (&isFolder, nullptr, nullptr, nullptr, nullptr, nullptr)) - { - auto f = i.getFile(); - - if (filesCreated.contains (f) || shouldFileBeKept (f.getFileName())) - { - folderIsNowEmpty = false; - } - else if (isFolder) - { - if (deleteUnwantedFilesIn (f)) - filesToDelete.add (f); - else - folderIsNowEmpty = false; - } - else - { - filesToDelete.add (f); - } - } - - for (int j = filesToDelete.size(); --j >= 0;) - filesToDelete.getReference(j).deleteRecursively(); - - return folderIsNowEmpty; - } - - static bool shouldFileBeKept (const String& filename) - { - static const char* filesToKeep[] = { ".svn", ".cvs", "CMakeLists.txt" }; - - for (auto* f : filesToKeep) - if (filename == f) - return true; - - return false; - } - - void writeMainProjectFile() - { - if (auto xml = project.getProjectRoot().createXml()) - { - XmlElement::TextFormat format; - format.newLineChars = projectLineFeed.toRawUTF8(); - - MemoryOutputStream mo (8192); - xml->writeTo (mo, format); - replaceFileIfDifferent (projectFile, mo); - } - else - { - jassertfalse; - } - } - - static int findLongestModuleName (const OwnedArray<LibraryModule>& modules) - { - int longest = 0; - - for (auto& m : modules) - longest = jmax (longest, m->getID().length()); - - return longest; - } - - File getAppConfigFile() const { return generatedCodeFolder.getChildFile (Project::getAppConfigFilename()); } - - String loadUserContentFromAppConfig() const - { - StringArray userContent; - bool foundCodeSection = false; - auto lines = StringArray::fromLines (getAppConfigFile().loadFileAsString()); - - for (int i = 0; i < lines.size(); ++i) - { - if (lines[i].contains ("[BEGIN_USER_CODE_SECTION]")) - { - for (int j = i + 1; j < lines.size() && ! lines[j].contains ("[END_USER_CODE_SECTION]"); ++j) - userContent.add (lines[j]); - - foundCodeSection = true; - break; - } - } - - if (! foundCodeSection) - { - userContent.add ({}); - userContent.add ("// (You can add your own code in this section, and the Projucer will not overwrite it)"); - userContent.add ({}); - } - - return userContent.joinIntoString (projectLineFeed) + projectLineFeed; - } - - void checkModuleValidity (OwnedArray<LibraryModule>& modules) - { - if (project.getNumExporters() == 0) - { - addError ("No exporters found!\n" - "Please add an exporter before saving."); - return; - } - - for (auto moduleIter = modules.begin(); moduleIter != modules.end(); ++moduleIter) - { - if (auto* module = *moduleIter) - { - if (! module->isValid()) - { - addError ("At least one of your JUCE module paths is invalid!\n" - "Please go to the Modules settings page and ensure each path points to the correct JUCE modules folder."); - return; - } - - if (project.getEnabledModules().getExtraDependenciesNeeded (module->getID()).size() > 0) - { - addError ("At least one of your modules has missing dependencies!\n" - "Please go to the settings page of the highlighted modules and add the required dependencies."); - return; - } - } - else - { - // this should never happen! - jassertfalse; - } - } - } - - void writeAppConfig (MemoryOutputStream& out, const OwnedArray<LibraryModule>& modules, const String& userContent) - { - writeAutoGenWarningComment (out); - out << " There's a section below where you can add your own custom code safely, and the" << newLine - << " Projucer will preserve the contents of that block, but the best way to change" << newLine - << " any of these definitions is by using the Projucer's project settings." << newLine - << newLine - << " Any commented-out settings will assume their default values." << newLine - << newLine - << "*/" << newLine - << newLine; - - out << "#pragma once" << newLine - << newLine - << "//==============================================================================" << newLine - << "// [BEGIN_USER_CODE_SECTION]" << newLine - << userContent - << "// [END_USER_CODE_SECTION]" << newLine; - - out << newLine - << "/*" << newLine - << " ==============================================================================" << newLine - << newLine - << " In accordance with the terms of the JUCE 5 End-Use License Agreement, the" << newLine - << " JUCE Code in SECTION A cannot be removed, changed or otherwise rendered" << newLine - << " ineffective unless you have a JUCE Indie or Pro license, or are using JUCE" << newLine - << " under the GPL v3 license." << newLine - << newLine - << " End User License Agreement: www.juce.com/juce-5-licence" << newLine - << newLine - << " ==============================================================================" << newLine - << "*/" << newLine - << newLine - << "// BEGIN SECTION A" << newLine - << newLine - << "#ifndef JUCE_DISPLAY_SPLASH_SCREEN" << newLine - << " #define JUCE_DISPLAY_SPLASH_SCREEN " << (project.shouldDisplaySplashScreen() ? "1" : "0") << newLine - << "#endif" << newLine << newLine - - << "#ifndef JUCE_REPORT_APP_USAGE" << newLine - << " #define JUCE_REPORT_APP_USAGE " << (project.shouldReportAppUsage() ? "1" : "0") << newLine - << "#endif" << newLine - << newLine - << "// END SECTION A" << newLine - << 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; - - auto longestName = findLongestModuleName (modules); - - for (auto& m : modules) - out << "#define JUCE_MODULE_AVAILABLE_" << m->getID() - << String::repeatedString (" ", longestName + 5 - m->getID().length()) << " 1" << newLine; - - out << newLine << "#define JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED 1" << newLine; - - for (auto& m : modules) - { - OwnedArray<Project::ConfigFlag> flags; - m->getConfigFlags (project, flags); - - if (flags.size() > 0) - { - out << newLine - << "//==============================================================================" << newLine - << "// " << m->getID() << " flags:" << newLine; - - for (auto* flag : flags) - { - out << newLine - << "#ifndef " << flag->symbol - << newLine - << (flag->value.isUsingDefault() ? " //#define " : " #define ") << flag->symbol << " " << (flag->value.get() ? "1" : "0") - << newLine - << "#endif" - << newLine; - } - } - } - - if (extraAppConfigContent.isNotEmpty()) - out << newLine << extraAppConfigContent.trimEnd() << newLine; - - { - auto& type = project.getProjectType(); - - auto isStandaloneApplication = (! type.isAudioPlugin() && ! type.isDynamicLibrary()); - - out << newLine - << "//==============================================================================" << newLine - << "#ifndef JUCE_STANDALONE_APPLICATION" << newLine - << " #if defined(JucePlugin_Name) && defined(JucePlugin_Build_Standalone)" << newLine - << " #define JUCE_STANDALONE_APPLICATION JucePlugin_Build_Standalone" << newLine - << " #else" << newLine - << " #define JUCE_STANDALONE_APPLICATION " << (isStandaloneApplication ? "1" : "0") << newLine - << " #endif" << newLine - << "#endif" << newLine; - } - } - - void writeAppConfigFile (const OwnedArray<LibraryModule>& modules, const String& userContent) - { - appConfigFile = getAppConfigFile(); - - MemoryOutputStream mem; - mem.setNewLineString (projectLineFeed); - - writeAppConfig (mem, modules, userContent); - saveGeneratedFile (Project::getAppConfigFilename(), mem); - } - - void writeAppHeader (MemoryOutputStream& out, const OwnedArray<LibraryModule>& modules) - { - writeAutoGenWarningComment (out); - - out << " This is the header file that your files should include in order to get all the" << newLine - << " JUCE library headers. You should avoid including the JUCE headers directly in" << newLine - << " your own source files, because that wouldn't pick up the correct configuration" << newLine - << " options for your app." << newLine - << newLine - << "*/" << newLine << newLine; - - out << "#pragma once" << newLine << newLine; - - if (appConfigFile.exists()) - out << CodeHelpers::createIncludeStatement (Project::getAppConfigFilename()) << newLine; - - if (modules.size() > 0) - { - out << newLine; - - for (int i = 0; i < modules.size(); ++i) - modules.getUnchecked(i)->writeIncludes (*this, out); - - out << newLine; - } - - if (hasBinaryData && project.shouldIncludeBinaryInJuceHeader()) - 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 - << " using namespace juce;" << newLine - << "#endif" << newLine - << newLine - << "#if ! JUCE_DONT_DECLARE_PROJECTINFO" << newLine - << "namespace ProjectInfo" << newLine - << "{" << newLine - << " const char* const projectName = " << CppTokeniserFunctions::addEscapeChars (project.getProjectNameString()).quoted() << ";" << newLine - << " const char* const companyName = " << CppTokeniserFunctions::addEscapeChars (project.getCompanyNameString()).quoted() << ";" << newLine - << " const char* const versionString = " << CppTokeniserFunctions::addEscapeChars (project.getVersionString()).quoted() << ";" << newLine - << " const int versionNumber = " << project.getVersionAsHex() << ";" << newLine - << "}" << newLine - << "#endif" << newLine; - } - - void writeAppHeader (const OwnedArray<LibraryModule>& modules) - { - MemoryOutputStream mem; - mem.setNewLineString (projectLineFeed); - - writeAppHeader (mem, modules); - saveGeneratedFile (Project::getJuceSourceHFilename(), mem); - } - - void writeModuleCppWrappers (const OwnedArray<LibraryModule>& modules) - { - for (auto* module : modules) - { - for (auto& cu : module->getAllCompileUnits()) - { - MemoryOutputStream mem; - mem.setNewLineString (projectLineFeed); - - writeAutoGenWarningComment (mem); - - mem << "*/" << newLine - << newLine - << "#include " << Project::getAppConfigFilename().quoted() << newLine - << "#include <"; - - if (cu.file.getFileExtension() != ".r") // .r files are included without the path - mem << module->getID() << "/"; - - mem << cu.file.getFileName() << ">" << newLine; - - replaceFileIfDifferent (generatedCodeFolder.getChildFile (cu.getFilenameForProxyFile()), mem); - } - } - } - - void writeBinaryDataFiles() - { - auto binaryDataH = project.getBinaryDataHeaderFile(); - - ResourceFile resourceFile (project); - - if (resourceFile.getNumFiles() > 0) - { - auto dataNamespace = project.getBinaryDataNamespaceString().trim(); - - if (dataNamespace.isEmpty()) - dataNamespace = "BinaryData"; - - resourceFile.setClassName (dataNamespace); - - Array<File> binaryDataFiles; - - auto maxSize = project.getMaxBinaryFileSize(); - - if (maxSize <= 0) - maxSize = 10 * 1024 * 1024; - - auto r = resourceFile.write (binaryDataFiles, maxSize); - - if (r.wasOk()) - { - hasBinaryData = true; - - for (auto& f : binaryDataFiles) - { - filesCreated.add (f); - generatedFilesGroup.addFileRetainingSortOrder (f, ! f.hasFileExtension (".h")); - } - } - else - { - addError (r.getErrorMessage()); - } - } - else - { - for (int i = 20; --i >= 0;) - project.getBinaryDataCppFile (i).deleteFile(); - - binaryDataH.deleteFile(); - } - } - - void writeReadmeFile() - { - MemoryOutputStream out; - out.setNewLineString (projectLineFeed); - - out << newLine - << " Important Note!!" << newLine - << " ================" << newLine - << newLine - << "The purpose of this folder is to contain files that are auto-generated by the Projucer," << newLine - << "and ALL files in this folder will be mercilessly DELETED and completely re-written whenever" << newLine - << "the Projucer saves your project." << newLine - << newLine - << "Therefore, it's a bad idea to make any manual changes to the files in here, or to" << newLine - << "put any of your own files in here if you don't want to lose them. (Of course you may choose" << newLine - << "to add the folder's contents to your version-control system so that you can re-merge your own" << newLine - << "modifications after the Projucer has saved its changes)." << newLine; - - replaceFileIfDifferent (generatedCodeFolder.getChildFile ("ReadMe.txt"), out); - } - - void addError (const String& message) - { - const ScopedLock sl (errorLock); - errors.add (message); - } - - void writePluginCharacteristicsFile(); - - void writeUnityScriptFile() - { - auto unityScriptContents = replaceLineFeeds (BinaryData::jucer_UnityPluginGUIScript_cs, - projectLineFeed); - - auto projectName = Project::addUnityPluginPrefixIfNecessary (project.getProjectNameString()); - - unityScriptContents = unityScriptContents.replace ("%%plugin_class_name%%", projectName.replace (" ", "_")) - .replace ("%%plugin_name%%", projectName) - .replace ("%%plugin_vendor%%", project.getPluginManufacturerString()) - .replace ("%%plugin_description%%", project.getPluginDescriptionString()); - - auto f = getGeneratedCodeFolder().getChildFile (project.getUnityScriptName()); - - MemoryOutputStream out; - out << unityScriptContents; - - replaceFileIfDifferent (f, out); - } - - void writeProjects (const OwnedArray<LibraryModule>&, const String&, bool); - - void runPostExportScript() - { - #if JUCE_WINDOWS - auto cmdString = project.getPostExportShellCommandWinString(); - #else - auto cmdString = project.getPostExportShellCommandPosixString(); - #endif - - auto shellCommand = cmdString.replace ("%%1%%", project.getProjectFolder().getFullPathName()); - - if (shellCommand.isNotEmpty()) - { - #if JUCE_WINDOWS - StringArray argList ("cmd.exe", "/c"); - #else - StringArray argList ("/bin/sh", "-c"); - #endif - - argList.add (shellCommand); - ChildProcess shellProcess; - - if (! shellProcess.start (argList)) - { - addError ("Failed to run shell command: " + argList.joinIntoString (" ")); - return; - } - - if (! shellProcess.waitForProcessToFinish (10000)) - { - addError ("Timeout running shell command: " + argList.joinIntoString (" ")); - return; - } - - auto exitCode = shellProcess.getExitCode(); - - if (exitCode != 0) - addError ("Shell command: " + argList.joinIntoString (" ") + " failed with exit code: " + String (exitCode)); - } - } - - void saveExporter (ProjectExporter* exporter, const OwnedArray<LibraryModule>& modules) - { - try - { - exporter->create (modules); - - if (! exporter->isCLion()) - std::cout << "Finished saving: " << exporter->getName() << std::endl; - } - catch (ProjectExporter::SaveError& error) - { - addError (error.message); - } - } - - class ExporterJob : public ThreadPoolJob - { - public: - ExporterJob (ProjectSaver& ps, ProjectExporter* pe, - const OwnedArray<LibraryModule>& moduleList) - : ThreadPoolJob ("export"), - owner (ps), exporter (pe), modules (moduleList) - { - } - - JobStatus runJob() override - { - owner.saveExporter (exporter.get(), modules); - return jobHasFinished; - } - - private: - ProjectSaver& owner; - std::unique_ptr<ProjectExporter> exporter; - const OwnedArray<LibraryModule>& modules; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ExporterJob) - }; - + //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProjectSaver) }; diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ResourceFile.cpp b/extras/Projucer/Source/ProjectSaving/jucer_ResourceFile.cpp index 4d98354f..f5a14dca 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ResourceFile.cpp +++ b/extras/Projucer/Source/ProjectSaving/jucer_ResourceFile.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -27,20 +26,18 @@ #include "../Application/jucer_Headers.h" #include "jucer_ResourceFile.h" -static const char* resourceFileIdentifierString = "JUCER_BINARY_RESOURCE"; - //============================================================================== -ResourceFile::ResourceFile (Project& p) : project (p) +JucerResourceFile::JucerResourceFile (Project& p) : project (p) { addResourcesFromProjectItem (project.getMainGroup()); } -ResourceFile::~ResourceFile() +JucerResourceFile::~JucerResourceFile() { } //============================================================================== -void ResourceFile::addResourcesFromProjectItem (const Project::Item& projectItem) +void JucerResourceFile::addResourcesFromProjectItem (const Project::Item& projectItem) { if (projectItem.isGroup()) { @@ -53,258 +50,3 @@ void ResourceFile::addResourcesFromProjectItem (const Project::Item& projectItem addFile (projectItem.getFile()); } } - -//============================================================================== -void ResourceFile::setClassName (const String& name) -{ - className = name; -} - -void ResourceFile::addFile (const File& file) -{ - files.add (file); - - auto variableNameRoot = CodeHelpers::makeBinaryDataIdentifierName (file); - auto variableName = variableNameRoot; - - int suffix = 2; - while (variableNames.contains (variableName)) - variableName = variableNameRoot + String (suffix++); - - variableNames.add (variableName); -} - -String ResourceFile::getDataVariableFor (const File& file) const -{ - jassert (files.indexOf (file) >= 0); - return variableNames [files.indexOf (file)]; -} - -String ResourceFile::getSizeVariableFor (const File& file) const -{ - jassert (files.indexOf (file) >= 0); - return variableNames [files.indexOf (file)] + "Size"; -} - -int64 ResourceFile::getTotalDataSize() const -{ - int64 total = 0; - - for (int i = 0; i < files.size(); ++i) - total += files.getReference(i).getSize(); - - return total; -} - -static void writeComment (MemoryOutputStream& mo) -{ - mo << newLine << newLine - << " This is an auto-generated file: Any edits you make may be overwritten!" << newLine - << newLine - << "*/" << newLine - << newLine; -} - -Result ResourceFile::writeHeader (MemoryOutputStream& header) -{ - header << "/* ========================================================================================="; - writeComment (header); - header << "#pragma once" << newLine - << newLine - << "namespace " << className << newLine - << "{" << newLine; - - for (int i = 0; i < files.size(); ++i) - { - auto& file = files.getReference(i); - - if (! file.existsAsFile()) - return Result::fail ("Can't open resource file: " + file.getFullPathName()); - - auto dataSize = file.getSize(); - - auto variableName = variableNames[i]; - - FileInputStream fileStream (file); - - if (fileStream.openedOk()) - { - header << " extern const char* " << variableName << ";" << newLine; - header << " const int " << variableName << "Size = " << (int) dataSize << ";" << newLine << newLine; - } - } - - header << " // Number of elements in the namedResourceList and originalFileNames arrays." << newLine - << " const int namedResourceListSize = " << files.size() << ";" << newLine - << newLine - << " // Points to the start of a list of resource names." << newLine - << " extern const char* namedResourceList[];" << newLine - << newLine - << " // Points to the start of a list of resource filenames." << newLine - << " extern const char* originalFilenames[];" << newLine - << newLine - << " // If you provide the name of one of the binary resource variables above, this function will" << newLine - << " // return the corresponding data and its size (or a null pointer if the name isn't found)." << newLine - << " const char* getNamedResource (const char* resourceNameUTF8, int& dataSizeInBytes);" << newLine - << newLine - << " // If you provide the name of one of the binary resource variables above, this function will" << newLine - << " // return the corresponding original, non-mangled filename (or a null pointer if the name isn't found)." << newLine - << " const char* getNamedResourceOriginalFilename (const char* resourceNameUTF8);" << newLine - << "}" << newLine; - - return Result::ok(); -} - -Result ResourceFile::writeCpp (MemoryOutputStream& cpp, const File& headerFile, int& i, const int maxFileSize) -{ - bool isFirstFile = (i == 0); - - cpp << "/* ==================================== " << resourceFileIdentifierString << " ===================================="; - writeComment (cpp); - cpp << "namespace " << className << newLine - << "{" << newLine; - - while (i < files.size()) - { - auto& file = files.getReference(i); - auto variableName = variableNames[i]; - - FileInputStream fileStream (file); - - if (fileStream.openedOk()) - { - auto tempVariable = "temp_binary_data_" + String (i); - - cpp << newLine << "//================== " << file.getFileName() << " ==================" << newLine - << "static const unsigned char " << tempVariable << "[] =" << newLine; - - { - MemoryBlock data; - fileStream.readIntoMemoryBlock (data); - CodeHelpers::writeDataAsCppLiteral (data, cpp, true, true); - } - - cpp << newLine << newLine - << "const char* " << variableName << " = (const char*) " << tempVariable << ";" << newLine; - } - - ++i; - - if (cpp.getPosition() > maxFileSize) - break; - } - - if (isFirstFile) - { - if (i < files.size()) - { - cpp << newLine - << "}" << newLine - << newLine - << "#include \"" << headerFile.getFileName() << "\"" << newLine - << newLine - << "namespace " << className << newLine - << "{"; - } - - cpp << newLine - << newLine - << "const char* getNamedResource (const char* resourceNameUTF8, int& numBytes)" << newLine - << "{" << newLine; - - StringArray returnCodes; - for (auto& file : files) - { - auto dataSize = file.getSize(); - returnCodes.add ("numBytes = " + String (dataSize) + "; return " + variableNames[files.indexOf (file)] + ";"); - } - - CodeHelpers::createStringMatcher (cpp, "resourceNameUTF8", variableNames, returnCodes, 4); - - cpp << " numBytes = 0;" << newLine - << " return nullptr;" << newLine - << "}" << newLine - << newLine; - - cpp << "const char* namedResourceList[] =" << newLine - << "{" << newLine; - - for (int j = 0; j < files.size(); ++j) - cpp << " " << variableNames[j].quoted() << (j < files.size() - 1 ? "," : "") << newLine; - - cpp << "};" << newLine << newLine; - - cpp << "const char* originalFilenames[] =" << newLine - << "{" << newLine; - - for (auto& f : files) - cpp << " " << f.getFileName().quoted() << (files.indexOf (f) < files.size() - 1 ? "," : "") << newLine; - - cpp << "};" << newLine << newLine; - - cpp << "const char* getNamedResourceOriginalFilename (const char* resourceNameUTF8)" << newLine - << "{" << newLine - << " for (unsigned int i = 0; i < (sizeof (namedResourceList) / sizeof (namedResourceList[0])); ++i)" << newLine - << " {" << newLine - << " if (namedResourceList[i] == resourceNameUTF8)" << newLine - << " return originalFilenames[i];" << newLine - << " }" << newLine - << newLine - << " return nullptr;" << newLine - << "}" << newLine - << newLine; - } - - cpp << "}" << newLine; - - return Result::ok(); -} - -Result ResourceFile::write (Array<File>& filesCreated, const int maxFileSize) -{ - auto projectLineFeed = project.getProjectLineFeed(); - - auto headerFile = project.getBinaryDataHeaderFile(); - - { - MemoryOutputStream mo; - mo.setNewLineString (projectLineFeed); - - auto r = writeHeader (mo); - - if (r.failed()) - return r; - - if (! FileHelpers::overwriteFileWithNewDataIfDifferent (headerFile, mo)) - return Result::fail ("Can't write to file: " + headerFile.getFullPathName()); - - filesCreated.add (headerFile); - } - - int i = 0; - int fileIndex = 0; - - for (;;) - { - auto cpp = project.getBinaryDataCppFile (fileIndex); - - MemoryOutputStream mo; - mo.setNewLineString (projectLineFeed); - - auto r = writeCpp (mo, headerFile, i, maxFileSize); - - if (r.failed()) - return r; - - if (! FileHelpers::overwriteFileWithNewDataIfDifferent (cpp, mo)) - return Result::fail ("Can't write to file: " + cpp.getFullPathName()); - - filesCreated.add (cpp); - ++fileIndex; - - if (i >= files.size()) - break; - } - - return Result::ok(); -} diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ResourceFile.h b/extras/Projucer/Source/ProjectSaving/jucer_ResourceFile.h index 30ed2e26..7caaa057 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ResourceFile.h +++ b/extras/Projucer/Source/ProjectSaving/jucer_ResourceFile.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -29,38 +28,40 @@ #include "../Project/jucer_Project.h" //============================================================================== -class ResourceFile +class JucerResourceFile { public: //============================================================================== - ResourceFile (Project& project); - ~ResourceFile(); + explicit JucerResourceFile (Project& project); + ~JucerResourceFile(); //============================================================================== - void setClassName (const String& className); - String getClassName() const { return className; } + void setClassName (const String& className) { resourceFile.setClassName (className); } + String getClassName() const { return resourceFile.getClassName(); } - void addFile (const File& file); - String getDataVariableFor (const File& file) const; - String getSizeVariableFor (const File& file) const; + void addFile (const File& file) { resourceFile.addFile (file); } + String getDataVariableFor (const File& file) const { return resourceFile.getDataVariableFor (file); } + String getSizeVariableFor (const File& file) const { return resourceFile.getSizeVariableFor (file); } - int getNumFiles() const { return files.size(); } - const File& getFile (int index) const { return files.getReference (index); } + int getNumFiles() const { return resourceFile.getNumFiles(); } + const File& getFile (int index) const { return resourceFile.getFile (index); } - int64 getTotalDataSize() const; + int64 getTotalDataSize() const { return resourceFile.getTotalDataSize(); } - Result write (Array<File>& filesCreated, int maxFileSize); + build_tools::ResourceFile::WriteResult write (int maxFileSize) + { + return resourceFile.write (maxFileSize, + project.getProjectLineFeed(), + project.getBinaryDataHeaderFile(), + [this] (int index) { return project.getBinaryDataCppFile (index); }); + } //============================================================================== private: - Array<File> files; - StringArray variableNames; - Project& project; - String className { "BinaryData" }; - - Result writeHeader (MemoryOutputStream&); - Result writeCpp (MemoryOutputStream&, const File& headerFile, int& index, int maxFileSize); void addResourcesFromProjectItem (const Project::Item& node); - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ResourceFile) + Project& project; + build_tools::ResourceFile resourceFile; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (JucerResourceFile) }; diff --git a/extras/Projucer/Source/ProjectSaving/jucer_XcodeProjectParser.h b/extras/Projucer/Source/ProjectSaving/jucer_XcodeProjectParser.h index 9335be73..f2490eb7 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_XcodeProjectParser.h +++ b/extras/Projucer/Source/ProjectSaving/jucer_XcodeProjectParser.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -200,10 +199,14 @@ private: case '{': ++braceDepth; break; + case '}': if (--braceDepth == 0) return content.substr ((size_t) std::distance (content.begin(), start), (size_t) std::distance (start, ptr)); + + default: + break; } } diff --git a/extras/Projucer/Source/Settings/jucer_AppearanceSettings.cpp b/extras/Projucer/Source/Settings/jucer_AppearanceSettings.cpp index 67a87775..6d0b56cf 100644 --- a/extras/Projucer/Source/Settings/jucer_AppearanceSettings.cpp +++ b/extras/Projucer/Source/Settings/jucer_AppearanceSettings.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/Settings/jucer_AppearanceSettings.h b/extras/Projucer/Source/Settings/jucer_AppearanceSettings.h index 00003f0d..7a315f2b 100644 --- a/extras/Projucer/Source/Settings/jucer_AppearanceSettings.h +++ b/extras/Projucer/Source/Settings/jucer_AppearanceSettings.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/Settings/jucer_StoredSettings.cpp b/extras/Projucer/Source/Settings/jucer_StoredSettings.cpp index 74f751e7..9727c775 100644 --- a/extras/Projucer/Source/Settings/jucer_StoredSettings.cpp +++ b/extras/Projucer/Source/Settings/jucer_StoredSettings.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -181,8 +180,7 @@ void StoredSettings::updateOldProjectSettingsFiles() auto newProjectSettingsDir = projucerSettingsDirectory.getChildFile ("ProjectSettings"); newProjectSettingsDir.createDirectory(); - DirectoryIterator iter (projucerSettingsDirectory, false, "*.settings"); - while (iter.next()) + for (const auto& iter : RangedDirectoryIterator (projucerSettingsDirectory, false, "*.settings")) { auto f = iter.getFile(); auto oldFileName = f.getFileName(); @@ -281,10 +279,6 @@ static bool isGlobalPathValid (const File& relativeTo, const Identifier& key, co { fileToCheckFor = "pluginterfaces/vst2.x/aeffect.h"; } - if (key == Ids::vst3Path) - { - fileToCheckFor = "base/source/baseiids.cpp"; - } else if (key == Ids::rtasPath) { fileToCheckFor = "AlturaPorts/TDMPlugIns/PlugInLibrary/EffectClasses/CEffectProcessMIDI.cpp"; @@ -301,14 +295,6 @@ static bool isGlobalPathValid (const File& relativeTo, const Identifier& key, co fileToCheckFor = "platform-tools/adb"; #endif } - else if (key == Ids::androidNDKPath) - { - #if JUCE_WINDOWS - fileToCheckFor = "ndk-depends.cmd"; - #else - fileToCheckFor = "ndk-depends"; - #endif - } else if (key == Ids::defaultJuceModulePath) { fileToCheckFor = "juce_core"; @@ -363,18 +349,9 @@ void StoredSettings::checkJUCEPaths() projectDefaults.getPropertyAsValue (Ids::defaultJuceModulePath, nullptr) = File (juceFolder).getChildFile ("modules").getFullPathName(); } -bool StoredSettings::shouldAskUserToSetJUCEPath() noexcept +bool StoredSettings::isJUCEPathIncorrect() { - if (! isGlobalPathValid ({}, Ids::jucePath, getStoredPath (Ids::jucePath, TargetOS::getThisOS()).get().toString()) - && getGlobalProperties().getValue ("dontAskAboutJUCEPath", {}).isEmpty()) - return true; - - return false; -} - -void StoredSettings::setDontAskAboutJUCEPathAgain() noexcept -{ - getGlobalProperties().setValue ("dontAskAboutJUCEPath", 1); + return ! isGlobalPathValid ({}, Ids::jucePath, getStoredPath (Ids::jucePath, TargetOS::getThisOS()).get().toString()); } static String getFallbackPathForOS (const Identifier& key, DependencyPathOS os) @@ -391,7 +368,7 @@ static String getFallbackPathForOS (const Identifier& key, DependencyPathOS os) { return (os == TargetOS::windows ? "C:\\modules" : "~/modules"); } - else if (key == Ids::vstLegacyPath || key == Ids::vst3Path) + else if (key == Ids::vstLegacyPath) { return {}; } @@ -416,10 +393,6 @@ static String getFallbackPathForOS (const Identifier& key, DependencyPathOS os) jassertfalse; return {}; } - else if (key == Ids::androidNDKPath) - { - return getFallbackPathForOS (Ids::androidSDKPath, os) + File::getSeparatorChar() + "ndk-bundle"; - } else if (key == Ids::clionExePath) { if (os == TargetOS::windows) diff --git a/extras/Projucer/Source/Settings/jucer_StoredSettings.h b/extras/Projucer/Source/Settings/jucer_StoredSettings.h index b4744a30..16f69c12 100644 --- a/extras/Projucer/Source/Settings/jucer_StoredSettings.h +++ b/extras/Projucer/Source/Settings/jucer_StoredSettings.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -30,7 +29,7 @@ #include "jucer_AppearanceSettings.h" //============================================================================== -class StoredSettings : public ValueTree::Listener +class StoredSettings : private ValueTree::Listener { public: StoredSettings(); @@ -63,9 +62,7 @@ public: //============================================================================== ValueWithDefault getStoredPath (const Identifier& key, DependencyPathOS os); - - bool shouldAskUserToSetJUCEPath() noexcept; - void setDontAskAboutJUCEPathAgain() noexcept; + bool isJUCEPathIncorrect(); //============================================================================== AppearanceSettings appearance; diff --git a/extras/Projucer/Source/Utility/Helpers/jucer_CodeHelpers.cpp b/extras/Projucer/Source/Utility/Helpers/jucer_CodeHelpers.cpp index 18a1a799..92d7caa7 100644 --- a/extras/Projucer/Source/Utility/Helpers/jucer_CodeHelpers.cpp +++ b/extras/Projucer/Source/Utility/Helpers/jucer_CodeHelpers.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -68,63 +67,10 @@ namespace CodeHelpers return lines.joinIntoString (newLine); } - String makeValidIdentifier (String s, bool capitalise, bool removeColons, bool allowTemplates, bool allowAsterisks) - { - if (s.isEmpty()) - return "unknown"; - - if (removeColons) - s = s.replaceCharacters (".,;:/@", "______"); - else - s = s.replaceCharacters (".,;/@", "_____"); - - for (int i = s.length(); --i > 0;) - if (CharacterFunctions::isLetter (s[i]) - && CharacterFunctions::isLetter (s[i - 1]) - && CharacterFunctions::isUpperCase (s[i]) - && ! CharacterFunctions::isUpperCase (s[i - 1])) - s = s.substring (0, i) + " " + s.substring (i); - - String allowedChars ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_ 0123456789"); - if (allowTemplates) - allowedChars += "<>"; - - if (! removeColons) - allowedChars += ":"; - - if (allowAsterisks) - allowedChars += "*"; - - StringArray words; - words.addTokens (s.retainCharacters (allowedChars), false); - words.trim(); - - auto n = words[0]; - - if (capitalise) - n = n.toLowerCase(); - - for (int i = 1; i < words.size(); ++i) - { - if (capitalise && words[i].length() > 1) - n << words[i].substring (0, 1).toUpperCase() - << words[i].substring (1).toLowerCase(); - else - n << words[i]; - } - - if (CharacterFunctions::isDigit (n[0])) - n = "_" + n; - - if (CPlusPlusCodeTokeniser::isReservedKeyword (n)) - n << '_'; - - return n; - } String createIncludeStatement (const File& includeFile, const File& targetFile) { - return createIncludeStatement (FileHelpers::unixStylePath (FileHelpers::getRelativePathFrom (includeFile, targetFile.getParentDirectory()))); + return createIncludeStatement (build_tools::unixStylePath (build_tools::getRelativePathFrom (includeFile, targetFile.getParentDirectory()))); } String createIncludeStatement (const String& includePath) @@ -140,18 +86,10 @@ namespace CodeHelpers return "#include <" + includedFilename + ">"; } - String makeBinaryDataIdentifierName (const File& file) - { - return makeValidIdentifier (file.getFileName() - .replaceCharacters (" .", "__") - .retainCharacters ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_0123456789"), - false, true, false); - } - String stringLiteral (const String& text, int maxLineLength) { if (text.isEmpty()) - return "String()"; + return "juce::String()"; StringArray lines; @@ -204,7 +142,7 @@ namespace CodeHelpers String result (lines.joinIntoString (newLine)); if (! CharPointer_ASCII::isValidString (text.toUTF8(), std::numeric_limits<int>::max())) - result = "CharPointer_UTF8 (" + result + ")"; + result = "juce::CharPointer_UTF8 (" + result + ")"; return result; } @@ -269,31 +207,31 @@ namespace CodeHelpers for (int i = 0; i < numElementsInArray (colourNames) - 1; ++i) if (col == colours[i]) - return "Colours::" + String (colourNames[i]); + return "juce::Colours::" + String (colourNames[i]); - return "Colour (0x" + hexString8Digits ((int) col.getARGB()) + ')'; + return "juce::Colour (0x" + build_tools::hexString8Digits ((int) col.getARGB()) + ')'; } String justificationToCode (Justification justification) { switch (justification.getFlags()) { - case Justification::centred: return "Justification::centred"; - case Justification::centredLeft: return "Justification::centredLeft"; - case Justification::centredRight: return "Justification::centredRight"; - case Justification::centredTop: return "Justification::centredTop"; - case Justification::centredBottom: return "Justification::centredBottom"; - case Justification::topLeft: return "Justification::topLeft"; - case Justification::topRight: return "Justification::topRight"; - case Justification::bottomLeft: return "Justification::bottomLeft"; - case Justification::bottomRight: return "Justification::bottomRight"; - case Justification::left: return "Justification::left"; - case Justification::right: return "Justification::right"; - case Justification::horizontallyCentred: return "Justification::horizontallyCentred"; - case Justification::top: return "Justification::top"; - case Justification::bottom: return "Justification::bottom"; - case Justification::verticallyCentred: return "Justification::verticallyCentred"; - case Justification::horizontallyJustified: return "Justification::horizontallyJustified"; + case Justification::centred: return "juce::Justification::centred"; + case Justification::centredLeft: return "juce::Justification::centredLeft"; + case Justification::centredRight: return "juce::Justification::centredRight"; + case Justification::centredTop: return "juce::Justification::centredTop"; + case Justification::centredBottom: return "juce::Justification::centredBottom"; + case Justification::topLeft: return "juce::Justification::topLeft"; + case Justification::topRight: return "juce::Justification::topRight"; + case Justification::bottomLeft: return "juce::Justification::bottomLeft"; + case Justification::bottomRight: return "juce::Justification::bottomRight"; + case Justification::left: return "juce::Justification::left"; + case Justification::right: return "juce::Justification::right"; + case Justification::horizontallyCentred: return "juce::Justification::horizontallyCentred"; + case Justification::top: return "juce::Justification::top"; + case Justification::bottom: return "juce::Justification::bottom"; + case Justification::verticallyCentred: return "juce::Justification::verticallyCentred"; + case Justification::horizontallyJustified: return "juce::Justification::horizontallyJustified"; default: break; } @@ -301,141 +239,7 @@ namespace CodeHelpers return "Justification (" + String (justification.getFlags()) + ")"; } - void writeDataAsCppLiteral (const MemoryBlock& mb, OutputStream& out, - bool breakAtNewLines, bool allowStringBreaks) - { - const int maxCharsOnLine = 250; - - auto data = (const unsigned char*) mb.getData(); - int charsOnLine = 0; - - bool canUseStringLiteral = mb.getSize() < 32768; // MS compilers can't handle big string literals.. - - if (canUseStringLiteral) - { - unsigned int numEscaped = 0; - - for (size_t i = 0; i < mb.getSize(); ++i) - { - auto num = (unsigned int) data[i]; - - if (! ((num >= 32 && num < 127) || num == '\t' || num == '\r' || num == '\n')) - { - if (++numEscaped > mb.getSize() / 4) - { - canUseStringLiteral = false; - break; - } - } - } - } - - if (! canUseStringLiteral) - { - out << "{ "; - - for (size_t i = 0; i < mb.getSize(); ++i) - { - auto num = (int) (unsigned int) data[i]; - out << num << ','; - - charsOnLine += 2; - - if (num >= 10) - { - ++charsOnLine; - - if (num >= 100) - ++charsOnLine; - } - - if (charsOnLine >= maxCharsOnLine) - { - charsOnLine = 0; - out << newLine; - } - } - - out << "0,0 };"; - } - else - { - out << "\""; - CppTokeniserFunctions::writeEscapeChars (out, (const char*) data, (int) mb.getSize(), - maxCharsOnLine, breakAtNewLines, false, allowStringBreaks); - out << "\";"; - } - } - //============================================================================== - static unsigned int calculateHash (const String& s, const unsigned int hashMultiplier) - { - auto t = s.toUTF8(); - unsigned int hash = 0; - - while (*t != 0) - hash = hashMultiplier * hash + (unsigned int) *t++; - - return hash; - } - - static unsigned int findBestHashMultiplier (const StringArray& strings) - { - unsigned int v = 31; - - for (;;) - { - SortedSet<unsigned int> hashes; - bool collision = false; - - for (int i = strings.size(); --i >= 0;) - { - auto hash = calculateHash (strings[i], v); - - if (hashes.contains (hash)) - { - collision = true; - break; - } - - hashes.add (hash); - } - - if (! collision) - break; - - v += 2; - } - - return v; - } - - void createStringMatcher (OutputStream& out, const String& utf8PointerVariable, - const StringArray& strings, const StringArray& codeToExecute, const int indentLevel) - { - jassert (strings.size() == codeToExecute.size()); - auto indent = String::repeatedString (" ", indentLevel); - auto hashMultiplier = findBestHashMultiplier (strings); - - out << indent << "unsigned int hash = 0;" << newLine - << newLine - << indent << "if (" << utf8PointerVariable << " != nullptr)" << newLine - << indent << " while (*" << utf8PointerVariable << " != 0)" << newLine - << indent << " hash = " << (int) hashMultiplier << " * hash + (unsigned int) *" << utf8PointerVariable << "++;" << newLine - << newLine - << indent << "switch (hash)" << newLine - << indent << "{" << newLine; - - for (int i = 0; i < strings.size(); ++i) - { - out << indent << " case 0x" << hexString8Digits ((int) calculateHash (strings[i], hashMultiplier)) - << ": " << codeToExecute[i] << newLine; - } - - out << indent << " default: break;" << newLine - << indent << "}" << newLine << newLine; - } - String getLeadingWhitespace (String line) { line = line.removeCharacters (line.endsWith ("\r\n") ? "\r\n" : "\n"); diff --git a/extras/Projucer/Source/Utility/Helpers/jucer_CodeHelpers.h b/extras/Projucer/Source/Utility/Helpers/jucer_CodeHelpers.h index 5947e083..652dde6e 100644 --- a/extras/Projucer/Source/Utility/Helpers/jucer_CodeHelpers.h +++ b/extras/Projucer/Source/Utility/Helpers/jucer_CodeHelpers.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -32,9 +31,6 @@ namespace CodeHelpers { String indent (const String& code, int numSpaces, bool indentFirstLine); String unindent (const String& code, int numSpaces); - String makeValidIdentifier (String s, bool capitalise, bool removeColons, - bool allowTemplates, bool allowAsterisks = false); - String makeBinaryDataIdentifierName (const File& file); String createIncludeStatement (const File& includedFile, const File& targetFile); String createIncludeStatement (const String& includePath); @@ -49,12 +45,6 @@ namespace CodeHelpers String alignFunctionCallParams (const String& call, const StringArray& parameters, int maxLineLength); - void writeDataAsCppLiteral (const MemoryBlock& data, OutputStream& out, - bool breakAtNewLines, bool allowStringBreaks); - - void createStringMatcher (OutputStream& out, const String& utf8PointerVariable, - const StringArray& strings, const StringArray& codeToExecute, int indentLevel); - String getLeadingWhitespace (String line); int getBraceCount (String::CharPointerType line); bool getIndentForCurrentBlock (CodeDocument::Position pos, const String& tab, diff --git a/extras/Projucer/Source/Utility/Helpers/jucer_Colours.h b/extras/Projucer/Source/Utility/Helpers/jucer_Colours.h index fa684c54..d7f58164 100644 --- a/extras/Projucer/Source/Utility/Helpers/jucer_Colours.h +++ b/extras/Projucer/Source/Utility/Helpers/jucer_Colours.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/Utility/Helpers/jucer_FileHelpers.cpp b/extras/Projucer/Source/Utility/Helpers/jucer_FileHelpers.cpp index f0e0d1c6..3efca27e 100644 --- a/extras/Projucer/Source/Utility/Helpers/jucer_FileHelpers.cpp +++ b/extras/Projucer/Source/Utility/Helpers/jucer_FileHelpers.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -30,104 +29,19 @@ //============================================================================== namespace FileHelpers { - static uint64 calculateMemoryHashCode (const void* data, size_t numBytes) - { - uint64 t = 0; - - for (size_t i = 0; i < numBytes; ++i) - t = t * 65599 + static_cast<const uint8*> (data)[i]; - - return t; - } - - uint64 calculateStreamHashCode (InputStream& in) - { - uint64 t = 0; - - const int bufferSize = 4096; - HeapBlock<uint8> buffer; - buffer.malloc (bufferSize); - - for (;;) - { - auto num = in.read (buffer, bufferSize); - - if (num <= 0) - break; - - for (int i = 0; i < num; ++i) - t = t * 65599 + buffer[i]; - } - - return t; - } - - uint64 calculateFileHashCode (const File& file) - { - std::unique_ptr<FileInputStream> stream (file.createInputStream()); - return stream != nullptr ? calculateStreamHashCode (*stream) : 0; - } - - bool overwriteFileWithNewDataIfDifferent (const File& file, const void* data, size_t numBytes) - { - if (file.getSize() == (int64) numBytes - && calculateMemoryHashCode (data, numBytes) == calculateFileHashCode (file)) - return true; - - if (file.exists()) - return file.replaceWithData (data, numBytes); - - return file.getParentDirectory().createDirectory() && file.appendData (data, numBytes); - } - - bool overwriteFileWithNewDataIfDifferent (const File& file, const MemoryOutputStream& newData) - { - return overwriteFileWithNewDataIfDifferent (file, newData.getData(), newData.getDataSize()); - } - - bool overwriteFileWithNewDataIfDifferent (const File& file, const String& newData) - { - const char* const utf8 = newData.toUTF8(); - return overwriteFileWithNewDataIfDifferent (file, utf8, strlen (utf8)); - } - bool containsAnyNonHiddenFiles (const File& folder) { - DirectoryIterator di (folder, false); - - while (di.next()) + for (const auto& di : RangedDirectoryIterator (folder, false)) if (! di.getFile().isHidden()) return true; return false; } - String unixStylePath (const String& path) { return path.replaceCharacter ('\\', '/'); } - String windowsStylePath (const String& path) { return path.replaceCharacter ('/', '\\'); } - - String currentOSStylePath (const String& path) - { - #if JUCE_WINDOWS - return windowsStylePath (path); - #else - return unixStylePath (path); - #endif - } - - bool isAbsolutePath (const String& path) - { - return File::isAbsolutePath (path) - || path.startsWithChar ('/') // (needed because File::isAbsolutePath will ignore forward-slashes on Windows) - || path.startsWithChar ('$') - || path.startsWithChar ('~') - || (CharacterFunctions::isLetter (path[0]) && path[1] == ':') - || path.startsWithIgnoreCase ("smb:"); - } - bool shouldPathsBeRelative (String path1, String path2) { - path1 = unixStylePath (path1); - path2 = unixStylePath (path2); + path1 = build_tools::unixStylePath (path1); + path2 = build_tools::unixStylePath (path2); const int len = jmin (path1.length(), path2.length()); int commonBitLength = 0; @@ -143,17 +57,6 @@ namespace FileHelpers return path1.substring (0, commonBitLength).removeCharacters ("/:").isNotEmpty(); } - String getRelativePathFrom (const File& file, const File& sourceFolder) - { - #if ! JUCE_WINDOWS - // On a non-windows machine, we can't know if a drive-letter path may be relative or not. - if (CharacterFunctions::isLetter (file.getFullPathName()[0]) && file.getFullPathName()[1] == ':') - return file.getFullPathName(); - #endif - - return file.getRelativePathFrom (sourceFolder); - } - // removes "/../" bits from the middle of the path String simplifyPath (String::CharPointerType p) { diff --git a/extras/Projucer/Source/Utility/Helpers/jucer_FileHelpers.h b/extras/Projucer/Source/Utility/Helpers/jucer_FileHelpers.h index be67380b..6c69bf5a 100644 --- a/extras/Projucer/Source/Utility/Helpers/jucer_FileHelpers.h +++ b/extras/Projucer/Source/Utility/Helpers/jucer_FileHelpers.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -30,24 +29,9 @@ //============================================================================== namespace FileHelpers { - uint64 calculateStreamHashCode (InputStream&); - uint64 calculateFileHashCode (const File&); - - bool overwriteFileWithNewDataIfDifferent (const File& file, const void* data, size_t numBytes); - bool overwriteFileWithNewDataIfDifferent (const File& file, const MemoryOutputStream& newData); - bool overwriteFileWithNewDataIfDifferent (const File& file, const String& newData); - bool containsAnyNonHiddenFiles (const File& folder); - String unixStylePath (const String& path); - String windowsStylePath (const String& path); - String currentOSStylePath (const String& path); - bool shouldPathsBeRelative (String path1, String path2); - bool isAbsolutePath (const String& path); - - // A windows-aware version of File::getRelativePath() - String getRelativePathFrom (const File& file, const File& sourceFolder); // removes "/../" bits from the middle of the path String simplifyPath (String::CharPointerType path); @@ -55,15 +39,15 @@ namespace FileHelpers } //============================================================================== -const char* const sourceFileExtensions = "cpp;mm;m;c;cc;cxx;swift;s;asm;r"; +const char* const sourceFileExtensions = "cpp;mm;m;metal;c;cc;cxx;swift;s;asm;r"; const char* const headerFileExtensions = "h;hpp;hxx;hh;inl"; const char* const cOrCppFileExtensions = "cpp;cc;cxx;c"; const char* const cppFileExtensions = "cpp;cc;cxx"; const char* const objCFileExtensions = "mm;m"; const char* const asmFileExtensions = "s;S;asm"; -const char* const sourceOrHeaderFileExtensions = "cpp;mm;m;c;cc;cxx;swift;s;S;asm;h;hpp;hxx;hh;inl"; -const char* const browseableFileExtensions = "cpp;mm;m;c;cc;cxx;swift;s;S;asm;h;hpp;hxx;hh;inl;txt;md;rtf"; -const char* const fileTypesToCompileByDefault = "cpp;mm;c;m;cc;cxx;swift;s;S;asm;r"; +const char* const sourceOrHeaderFileExtensions = "cpp;mm;m;metal;c;cc;cxx;swift;s;S;asm;h;hpp;hxx;hh;inl"; +const char* const browseableFileExtensions = "cpp;mm;m;metal;c;cc;cxx;swift;s;S;asm;h;hpp;hxx;hh;inl;txt;md;rtf"; +const char* const fileTypesToCompileByDefault = "cpp;mm;m;metal;c;cc;cxx;swift;s;S;asm;r"; //============================================================================== struct FileModificationDetector @@ -77,14 +61,14 @@ struct FileModificationDetector { return fileModificationTime != file.getLastModificationTime() && (fileSize != file.getSize() - || FileHelpers::calculateFileHashCode (file) != fileHashCode); + || build_tools::calculateFileHashCode (file) != fileHashCode); } void updateHash() { fileModificationTime = file.getLastModificationTime(); fileSize = file.getSize(); - fileHashCode = FileHelpers::calculateFileHashCode (file); + fileHashCode = build_tools::calculateFileHashCode (file); } private: diff --git a/extras/Projucer/Source/Utility/Helpers/jucer_MiscUtilities.cpp b/extras/Projucer/Source/Utility/Helpers/jucer_MiscUtilities.cpp index a9bb75fa..599ce449 100644 --- a/extras/Projucer/Source/Utility/Helpers/jucer_MiscUtilities.cpp +++ b/extras/Projucer/Source/Utility/Helpers/jucer_MiscUtilities.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -87,11 +86,6 @@ String createAlphaNumericUID() return uid; } -String hexString8Digits (int value) -{ - return String::toHexString (value).paddedLeft ('0', 8); -} - String createGUID (const String& seed) { auto hex = MD5 ((seed + "_guidsalt").toUTF8()).toHexString().toUpperCase(); @@ -185,25 +179,12 @@ String createGCCPreprocessorFlags (const StringPairArray& defs) if (value.isNotEmpty()) def << "=" << value; - s += " -D" + def; + s += " \"" + ("-D" + def).replace ("\"", "\\\"") + "\""; } return s; } -String replacePreprocessorDefs (const StringPairArray& definitions, String sourceString) -{ - for (int i = 0; i < definitions.size(); ++i) - { - const String key (definitions.getAllKeys()[i]); - const String value (definitions.getAllValues()[i]); - - sourceString = sourceString.replace ("${" + key + "}", value); - } - - return sourceString; -} - StringArray getSearchPathsFromString (const String& searchPath) { StringArray s; @@ -225,58 +206,6 @@ StringArray getCleanedStringArray (StringArray s) return s; } -//============================================================================== -static bool keyFoundAndNotSequentialDuplicate (XmlElement* xml, const String& key) -{ - forEachXmlChildElementWithTagName (*xml, element, "key") - { - if (element->getAllSubText().trim().equalsIgnoreCase (key)) - { - if (element->getNextElement() != nullptr && element->getNextElement()->hasTagName ("key")) - { - // found broken plist format (sequential duplicate), fix by removing - xml->removeChildElement (element, true); - return false; - } - - // key found (not sequential duplicate) - return true; - } - } - - // key not found - return false; -} - -static bool addKeyIfNotFound (XmlElement* xml, const String& key) -{ - if (! keyFoundAndNotSequentialDuplicate (xml, key)) - { - xml->createNewChildElement ("key")->addTextElement (key); - return true; - } - - return false; -} - -void addPlistDictionaryKey (XmlElement* xml, const String& key, const String& value) -{ - if (addKeyIfNotFound (xml, key)) - xml->createNewChildElement ("string")->addTextElement (value); -} - -void addPlistDictionaryKeyBool (XmlElement* xml, const String& key, const bool value) -{ - if (addKeyIfNotFound (xml, key)) - xml->createNewChildElement (value ? "true" : "false"); -} - -void addPlistDictionaryKeyInt (XmlElement* xml, const String& key, int value) -{ - if (addKeyIfNotFound (xml, key)) - xml->createNewChildElement ("integer")->addTextElement (String (value)); -} - //============================================================================== void autoScrollForMouseEvent (const MouseEvent& e, bool scrollX, bool scrollY) { @@ -319,6 +248,15 @@ bool fileNeedsCppSyntaxHighlighting (const File& file) && String (fileStart).trimStart().startsWith ("// -*- C++ -*-"); } +//============================================================================== +void writeAutoGenWarningComment (OutputStream& outStream) +{ + outStream << "/*" << newLine << newLine + << " IMPORTANT! This file is auto-generated each time you save your" << newLine + << " project - if you alter its contents, your changes may be overwritten!" << newLine + << newLine; +} + //============================================================================== StringArray getJUCEModules() noexcept { @@ -357,37 +295,43 @@ bool isJUCEModule (const String& moduleID) noexcept StringArray getModulesRequiredForConsole() noexcept { - return { "juce_core", - "juce_data_structures", - "juce_events" - }; + return + { + "juce_core", + "juce_data_structures", + "juce_events" + }; } StringArray getModulesRequiredForComponent() noexcept { - return { "juce_core", - "juce_data_structures", - "juce_events", - "juce_graphics", - "juce_gui_basics" - }; + return + { + "juce_core", + "juce_data_structures", + "juce_events", + "juce_graphics", + "juce_gui_basics" + }; } StringArray getModulesRequiredForAudioProcessor() noexcept { - return { "juce_audio_basics", - "juce_audio_devices", - "juce_audio_formats", - "juce_audio_plugin_client", - "juce_audio_processors", - "juce_audio_utils", - "juce_core", - "juce_data_structures", - "juce_events", - "juce_graphics", - "juce_gui_basics", - "juce_gui_extra" - }; + return + { + "juce_audio_basics", + "juce_audio_devices", + "juce_audio_formats", + "juce_audio_plugin_client", + "juce_audio_processors", + "juce_audio_utils", + "juce_core", + "juce_data_structures", + "juce_events", + "juce_graphics", + "juce_gui_basics", + "juce_gui_extra" + }; } bool isPIPFile (const File& file) noexcept @@ -421,6 +365,71 @@ bool isJUCEModulesFolder (const File& f) return f.isDirectory() && f.getChildFile ("juce_core").isDirectory(); } +//============================================================================== +static bool isDivider (const String& line) +{ + auto afterIndent = line.trim(); + + if (afterIndent.startsWith ("//") && afterIndent.length() > 20) + { + afterIndent = afterIndent.substring (5); + + if (afterIndent.containsOnly ("=") + || afterIndent.containsOnly ("/") + || afterIndent.containsOnly ("-")) + { + return true; + } + } + + return false; +} + +static int getIndexOfCommentBlockStart (const StringArray& lines, int endIndex) +{ + auto endLine = lines[endIndex]; + + if (endLine.contains ("*/")) + { + for (int i = endIndex; i >= 0; --i) + if (lines[i].contains ("/*")) + return i; + } + + if (endLine.trim().startsWith ("//") && ! isDivider (endLine)) + { + for (int i = endIndex; i >= 0; --i) + if (! lines[i].startsWith ("//") || isDivider (lines[i])) + return i + 1; + } + + return -1; +} + +int findBestLineToScrollToForClass (StringArray lines, const String& className, bool isPlugin) +{ + for (auto line : lines) + { + if (line.contains ("struct " + className) || line.contains ("class " + className) + || (isPlugin && line.contains ("public AudioProcessor") && ! line.contains ("AudioProcessorEditor"))) + { + auto index = lines.indexOf (line); + + auto commentBlockStartIndex = getIndexOfCommentBlockStart (lines, index - 1); + + if (commentBlockStartIndex != -1) + index = commentBlockStartIndex; + + if (isDivider (lines[index - 1])) + index -= 1; + + return index; + } + } + + return 0; +} + //============================================================================== static var parseJUCEHeaderMetadata (const StringArray& lines) { diff --git a/extras/Projucer/Source/Utility/Helpers/jucer_MiscUtilities.h b/extras/Projucer/Source/Utility/Helpers/jucer_MiscUtilities.h index db6742da..81e7ee0d 100644 --- a/extras/Projucer/Source/Utility/Helpers/jucer_MiscUtilities.h +++ b/extras/Projucer/Source/Utility/Helpers/jucer_MiscUtilities.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -37,8 +36,6 @@ var parseJUCEHeaderMetadata (const File&); String trimCommentCharsFromStartOfLine (const String& line); -String hexString8Digits (int value); - String createAlphaNumericUID(); String createGUID (const String& seed); // Turns a seed into a windows GUID @@ -48,7 +45,6 @@ String addQuotesIfContainsSpaces (const String& text); StringPairArray parsePreprocessorDefs (const String& defs); StringPairArray mergePreprocessorDefs (StringPairArray inheritedDefs, const StringPairArray& overridingDefs); String createGCCPreprocessorFlags (const StringPairArray& defs); -String replacePreprocessorDefs (const StringPairArray& definitions, String sourceString); StringArray getCleanedStringArray (StringArray); StringArray getSearchPathsFromString (const String& searchPath); @@ -56,12 +52,10 @@ StringArray getCommaOrWhitespaceSeparatedItems (const String&); void setValueIfVoid (Value value, const var& defaultValue); -void addPlistDictionaryKey (XmlElement* xml, const String& key, const String& value); -void addPlistDictionaryKeyBool (XmlElement* xml, const String& key, bool value); -void addPlistDictionaryKeyInt (XmlElement* xml, const String& key, int value); - bool fileNeedsCppSyntaxHighlighting (const File& file); +void writeAutoGenWarningComment (OutputStream& outStream); + StringArray getJUCEModules() noexcept; bool isJUCEModule (const String& moduleID) noexcept; @@ -70,6 +64,7 @@ StringArray getModulesRequiredForComponent() noexcept; StringArray getModulesRequiredForAudioProcessor() noexcept; bool isPIPFile (const File&) noexcept; +int findBestLineToScrollToForClass (StringArray, const String&, bool isPlugin = false); bool isValidJUCEExamplesDirectory (const File&) noexcept; @@ -120,7 +115,7 @@ struct PropertyListBuilder // A ValueSource which takes an input source, and forwards any changes in it. // This class is a handy way to create sources which re-map a value. class ValueSourceFilter : public Value::ValueSource, - public Value::Listener + private Value::Listener { public: ValueSourceFilter (const Value& source) : sourceValue (source) @@ -128,10 +123,11 @@ public: sourceValue.addListener (this); } - void valueChanged (Value&) override { sendChangeMessage (true); } - protected: Value sourceValue; +private: + void valueChanged (Value&) override { sendChangeMessage (true); } + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ValueSourceFilter) }; diff --git a/extras/Projucer/Source/Wizards/jucer_NewFileWizard.cpp b/extras/Projucer/Source/Utility/Helpers/jucer_NewFileWizard.cpp similarity index 83% rename from extras/Projucer/Source/Wizards/jucer_NewFileWizard.cpp rename to extras/Projucer/Source/Utility/Helpers/jucer_NewFileWizard.cpp index 83143003..53566ff1 100644 --- a/extras/Projucer/Source/Wizards/jucer_NewFileWizard.cpp +++ b/extras/Projucer/Source/Utility/Helpers/jucer_NewFileWizard.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -24,27 +23,34 @@ ============================================================================== */ -#include "../Application/jucer_Headers.h" +#include "../../Application/jucer_Headers.h" #include "jucer_NewFileWizard.h" -NewFileWizard::Type* createGUIComponentWizard(); - //============================================================================== namespace { static String fillInBasicTemplateFields (const File& file, const Project::Item& item, const char* templateName) { - return replaceLineFeeds (item.project.getFileTemplate (templateName) - .replace ("%%filename%%", file.getFileName(), false) - .replace ("%%date%%", Time::getCurrentTime().toString (true, true, true), false) - .replace ("%%author%%", SystemStats::getFullUserName(), false) - .replace ("%%include_corresponding_header%%", CodeHelpers::createIncludeStatement (file.withFileExtension (".h"), file)), - item.project.getProjectLineFeed()); + int dataSize; + + if (auto* data = BinaryData::getNamedResource (templateName, dataSize)) + { + auto fileTemplate = String::fromUTF8 (data, dataSize); + + return replaceLineFeeds (fileTemplate.replace ("%%filename%%", file.getFileName(), false) + .replace ("%%date%%", Time::getCurrentTime().toString (true, true, true), false) + .replace ("%%author%%", SystemStats::getFullUserName(), false) + .replace ("%%include_corresponding_header%%", CodeHelpers::createIncludeStatement (file.withFileExtension (".h"), file)), + item.project.getProjectLineFeed()); + } + + jassertfalse; + return {}; } static bool fillInNewCppFileTemplate (const File& file, const Project::Item& item, const char* templateName) { - return FileHelpers::overwriteFileWithNewDataIfDifferent (file, fillInBasicTemplateFields (file, item, templateName)); + return build_tools::overwriteFileWithNewDataIfDifferent (file, fillInBasicTemplateFields (file, item, templateName)); } const int menuBaseID = 0x12d83f0; @@ -153,7 +159,7 @@ public: const String className (aw.getTextEditorContents (getClassNameFieldName()).trim()); - if (className == CodeHelpers::makeValidIdentifier (className, false, true, false)) + if (className == build_tools::makeValidIdentifier (className, false, true, false)) { const File newFile (askUserToChooseNewFile (className + ".h", "*.h;*.cpp", parent)); @@ -174,7 +180,7 @@ public: content = replaceLineFeeds (content, parent.project.getProjectLineFeed()); - if (FileHelpers::overwriteFileWithNewDataIfDifferent (newFile, content)) + if (build_tools::overwriteFileWithNewDataIfDifferent (newFile, content)) { parent.addFileRetainingSortOrder (newFile, true); return true; @@ -240,7 +246,6 @@ NewFileWizard::NewFileWizard() registerWizard (new NewCppAndHeaderFileWizard()); registerWizard (new NewComponentFileWizard()); registerWizard (new NewSingleFileComponentFileWizard()); - registerWizard (createGUIComponentWizard()); } NewFileWizard::~NewFileWizard() diff --git a/extras/Projucer/Source/Wizards/jucer_NewFileWizard.h b/extras/Projucer/Source/Utility/Helpers/jucer_NewFileWizard.h similarity index 82% rename from extras/Projucer/Source/Wizards/jucer_NewFileWizard.h rename to extras/Projucer/Source/Utility/Helpers/jucer_NewFileWizard.h index aa77d286..ac9836d9 100644 --- a/extras/Projucer/Source/Wizards/jucer_NewFileWizard.h +++ b/extras/Projucer/Source/Utility/Helpers/jucer_NewFileWizard.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -26,7 +25,7 @@ #pragma once -#include "../Project/jucer_Project.h" +#include "../../Project/jucer_Project.h" //============================================================================== class NewFileWizard diff --git a/extras/Projucer/Source/Utility/Helpers/jucer_PresetIDs.h b/extras/Projucer/Source/Utility/Helpers/jucer_PresetIDs.h index 54012f3f..b2cc9329 100644 --- a/extras/Projucer/Source/Utility/Helpers/jucer_PresetIDs.h +++ b/extras/Projucer/Source/Utility/Helpers/jucer_PresetIDs.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -31,7 +30,7 @@ // Handy list of static Identifiers.. namespace Ids { - #define DECLARE_ID(name) const Identifier name (#name) + #define DECLARE_ID(name) const Identifier name (#name) DECLARE_ID (name); DECLARE_ID (file); @@ -48,8 +47,11 @@ namespace Ids DECLARE_ID (companyCopyright); DECLARE_ID (companyWebsite); DECLARE_ID (companyEmail); + DECLARE_ID (useAppConfig); + DECLARE_ID (addUsingNamespaceToJuceHeader); + DECLARE_ID (usePrecompiledHeaderFile); + DECLARE_ID (precompiledHeaderFile); DECLARE_ID (displaySplashScreen); - DECLARE_ID (reportAppUsage); DECLARE_ID (splashScreenColour); DECLARE_ID (position); DECLARE_ID (source); @@ -73,7 +75,6 @@ namespace Ids DECLARE_ID (rtasFolder); DECLARE_ID (auFolder); DECLARE_ID (vstLegacyPath); - DECLARE_ID (vst3Path); DECLARE_ID (rtasPath); DECLARE_ID (aaxPath); DECLARE_ID (flags); @@ -150,7 +151,6 @@ namespace Ids DECLARE_ID (msvcModuleDefinitionFile); DECLARE_ID (bigIcon); DECLARE_ID (smallIcon); - DECLARE_ID (jucerVersion); DECLARE_ID (prebuildCommand); DECLARE_ID (postbuildCommand); DECLARE_ID (generateManifest); @@ -162,8 +162,10 @@ namespace Ids DECLARE_ID (aaxFolder); DECLARE_ID (compile); DECLARE_ID (noWarnings); + DECLARE_ID (skipPCH); DECLARE_ID (resource); DECLARE_ID (xcodeResource); + DECLARE_ID (xcodeValidArchs); DECLARE_ID (className); DECLARE_ID (classDesc); DECLARE_ID (controlPoint); @@ -195,6 +197,8 @@ namespace Ids DECLARE_ID (microphonePermissionsText); DECLARE_ID (cameraPermissionNeeded); DECLARE_ID (cameraPermissionText); + DECLARE_ID (sendAppleEventsPermissionNeeded); + DECLARE_ID (sendAppleEventsPermissionText); DECLARE_ID (androidJavaLibs); DECLARE_ID (androidAdditionalJavaFolders); DECLARE_ID (androidAdditionalResourceFolders); @@ -212,7 +216,6 @@ namespace Ids DECLARE_ID (androidCustomApplicationClass); DECLARE_ID (androidVersionCode); DECLARE_ID (androidSDKPath); - DECLARE_ID (androidNDKPath); DECLARE_ID (androidOboeRepositoryPath); DECLARE_ID (androidInternetNeeded); DECLARE_ID (androidArchitectures); @@ -246,6 +249,7 @@ namespace Ids DECLARE_ID (iPadScreenOrientation); DECLARE_ID (iosScreenOrientation); DECLARE_ID (iosInAppPurchases); + DECLARE_ID (iosContentSharing); DECLARE_ID (iosBackgroundAudio); DECLARE_ID (iosBackgroundBle); DECLARE_ID (iosPushNotifications); @@ -333,6 +337,8 @@ namespace Ids DECLARE_ID (pluginCode); DECLARE_ID (pluginChannelConfigs); DECLARE_ID (pluginCharacteristicsValue); + DECLARE_ID (pluginCharacteristics); + DECLARE_ID (extraPluginFormats); DECLARE_ID (pluginIsSynth); DECLARE_ID (pluginWantsMidiIn); DECLARE_ID (pluginProducesMidiOut); @@ -351,6 +357,7 @@ namespace Ids DECLARE_ID (pluginAAXDisableMultiMono); DECLARE_ID (pluginVSTNumMidiInputs); DECLARE_ID (pluginVSTNumMidiOutputs); + DECLARE_ID (suppressPlistResourceUsage); DECLARE_ID (exporters); DECLARE_ID (website); DECLARE_ID (mainClass); @@ -362,8 +369,12 @@ namespace Ids DECLARE_ID (compilerFlagSchemes); DECLARE_ID (compilerFlagScheme); DECLARE_ID (dontQueryForUpdate); + DECLARE_ID (dontAskAboutJUCEPath); DECLARE_ID (postExportShellCommandPosix); DECLARE_ID (postExportShellCommandWin); + DECLARE_ID (liveBuildEnabled); + DECLARE_ID (guiEditorEnabled); + DECLARE_ID (jucerFormatVersion); const Identifier ID ("id"); const Identifier ID_uppercase ("ID"); diff --git a/extras/Projucer/Source/Utility/Helpers/jucer_RelativePath.h b/extras/Projucer/Source/Utility/Helpers/jucer_RelativePath.h deleted file mode 100644 index 00c3ded8..00000000 --- a/extras/Projucer/Source/Utility/Helpers/jucer_RelativePath.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - ============================================================================== - - 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. - - ============================================================================== -*/ - -#pragma once - - -//============================================================================== -/** Manipulates a cross-platform partial file path. (Needed because File is designed - for absolute paths on the active OS) -*/ -class RelativePath -{ -public: - //============================================================================== - enum RootFolder - { - unknown, - projectFolder, - buildTargetFolder - }; - - //============================================================================== - RelativePath() - : root (unknown) - {} - - RelativePath (const String& relPath, const RootFolder rootType) - : path (FileHelpers::unixStylePath (relPath)), root (rootType) - { - } - - RelativePath (const File& file, const File& rootFolder, const RootFolder rootType) - : path (FileHelpers::unixStylePath (FileHelpers::getRelativePathFrom (file, rootFolder))), root (rootType) - { - } - - RootFolder getRoot() const { return root; } - - String toUnixStyle() const { return FileHelpers::unixStylePath (path); } - String toWindowsStyle() const { return FileHelpers::windowsStylePath (path); } - - String getFileName() const { return getFakeFile().getFileName(); } - String getFileNameWithoutExtension() const { return getFakeFile().getFileNameWithoutExtension(); } - - String getFileExtension() const { return getFakeFile().getFileExtension(); } - bool hasFileExtension (juce::StringRef extension) const { return getFakeFile().hasFileExtension (extension); } - bool isAbsolute() const { return FileHelpers::isAbsolutePath (path); } - - RelativePath withFileExtension (const String& extension) const - { - return RelativePath (path.upToLastOccurrenceOf (".", ! extension.startsWithChar ('.'), false) + extension, root); - } - - RelativePath getParentDirectory() const - { - String p (path); - if (path.endsWithChar ('/')) - p = p.dropLastCharacters (1); - - return RelativePath (p.upToLastOccurrenceOf ("/", false, false), root); - } - - RelativePath getChildFile (const String& subpath) const - { - if (FileHelpers::isAbsolutePath (subpath)) - return RelativePath (subpath, root); - - String p (toUnixStyle()); - if (! p.endsWithChar ('/')) - p << '/'; - - return RelativePath (p + subpath, root); - } - - RelativePath rebased (const File& originalRoot, const File& newRoot, const RootFolder newRootType) const - { - if (isAbsolute()) - return RelativePath (path, newRootType); - - return RelativePath (FileHelpers::getRelativePathFrom (originalRoot.getChildFile (toUnixStyle()), newRoot), newRootType); - } - -private: - //============================================================================== - String path; - RootFolder root; - - File getFakeFile() const - { - #if JUCE_WINDOWS - if (FileHelpers::isAbsolutePath (path)) - { - // This is a hack to convert unix-style absolute paths into valid absolute Windows paths to avoid hitting - // an assertion in File::parseAbsolutePath(). - if (path.startsWithChar (L'/') || path.startsWithChar (L'$') || path.startsWithChar (L'~')) - return File (String ("C:\\") + FileHelpers::windowsStylePath (path.substring (1))); - - return File (path); - } - #endif - - // This method gets called very often, so we'll cache this directory. - static const File currentWorkingDirectory (File::getCurrentWorkingDirectory()); - return currentWorkingDirectory.getChildFile (path); - } -}; diff --git a/extras/Projucer/Source/Utility/Helpers/jucer_TranslationHelpers.h b/extras/Projucer/Source/Utility/Helpers/jucer_TranslationHelpers.h index fa2524b8..3f64d786 100644 --- a/extras/Projucer/Source/Utility/Helpers/jucer_TranslationHelpers.h +++ b/extras/Projucer/Source/Utility/Helpers/jucer_TranslationHelpers.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -125,7 +124,7 @@ struct TranslationHelpers break; ++p; - c = (juce_wchar) ((c << 4) + digitValue); + c = (c << 4) + (juce_wchar) digitValue; } break; @@ -136,12 +135,12 @@ struct TranslationHelpers for (int i = 4; --i >= 0;) { - const int digitValue = *p - '0'; + const auto digitValue = (int) (*p - '0'); if (digitValue < 0 || digitValue > 7) break; ++p; - c = (juce_wchar) ((c << 3) + digitValue); + c = (c << 3) + (juce_wchar) digitValue; } break; @@ -169,9 +168,9 @@ struct TranslationHelpers static void scanFolderForTranslations (StringArray& strings, const File& root) { - for (DirectoryIterator i (root, true); i.next();) + for (const auto& i : RangedDirectoryIterator (root, true)) { - const auto file (i.getFile()); + const auto file = i.getFile(); if (file.hasFileExtension (sourceOrHeaderFileExtensions)) scanFileForTranslations(strings, file); diff --git a/extras/Projucer/Source/Utility/Helpers/jucer_ValueSourceHelpers.h b/extras/Projucer/Source/Utility/Helpers/jucer_ValueSourceHelpers.h index f314122e..2e4cdfed 100644 --- a/extras/Projucer/Source/Utility/Helpers/jucer_ValueSourceHelpers.h +++ b/extras/Projucer/Source/Utility/Helpers/jucer_ValueSourceHelpers.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/Utility/Helpers/jucer_ValueWithDefaultWrapper.h b/extras/Projucer/Source/Utility/Helpers/jucer_ValueWithDefaultWrapper.h new file mode 100644 index 00000000..24197878 --- /dev/null +++ b/extras/Projucer/Source/Utility/Helpers/jucer_ValueWithDefaultWrapper.h @@ -0,0 +1,73 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +#pragma once + + +//============================================================================== +/** + Wraps a ValueWithDefault object that has a default which depends on a global value. +*/ +class ValueWithDefaultWrapper : private Value::Listener +{ +public: + ValueWithDefaultWrapper() = default; + + void init (const ValueWithDefault& vwd, ValueWithDefault global, TargetOS::OS targetOS) + { + wrappedValue = vwd; + globalValue = global.getPropertyAsValue(); + globalIdentifier = global.getPropertyID(); + os = targetOS; + + if (wrappedValue.get() == var()) + wrappedValue.resetToDefault(); + + globalValue.addListener (this); + valueChanged (globalValue); + } + + ValueWithDefault& getWrappedValueWithDefault() + { + return wrappedValue; + } + + var getCurrentValue() const + { + return wrappedValue.get(); + } + +private: + void valueChanged (Value&) override + { + wrappedValue.setDefault (getAppSettings().getStoredPath (globalIdentifier, os).get()); + } + + ValueWithDefault wrappedValue; + Value globalValue; + + Identifier globalIdentifier; + TargetOS::OS os; +}; diff --git a/extras/Projucer/Source/Utility/Helpers/jucer_VersionInfo.cpp b/extras/Projucer/Source/Utility/Helpers/jucer_VersionInfo.cpp index 63cefab1..deb5817b 100644 --- a/extras/Projucer/Source/Utility/Helpers/jucer_VersionInfo.cpp +++ b/extras/Projucer/Source/Utility/Helpers/jucer_VersionInfo.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -27,6 +26,13 @@ #include "../../Application/jucer_Headers.h" #include "jucer_VersionInfo.h" + +VersionInfo::VersionInfo (String versionIn, String releaseNotesIn, std::vector<Asset> assetsIn) + : versionString (std::move (versionIn)), + releaseNotes (std::move (releaseNotesIn)), + assets (std::move (assetsIn)) +{} + std::unique_ptr<VersionInfo> VersionInfo::fetchFromUpdateServer (const String& versionString) { return fetch ("tags/" + versionString); @@ -44,7 +50,7 @@ std::unique_ptr<InputStream> VersionInfo::createInputStreamForAsset (const Asset return std::unique_ptr<InputStream> (downloadUrl.createInputStream (false, nullptr, nullptr, "Accept: application/octet-stream", - 0, &responseHeaders, &statusCode, 1)); + 5000, &responseHeaders, &statusCode, 1)); } bool VersionInfo::isNewerVersionThanCurrent() @@ -69,8 +75,8 @@ bool VersionInfo::isNewerVersionThanCurrent() std::unique_ptr<VersionInfo> VersionInfo::fetch (const String& endpoint) { - URL latestVersionURL ("https://api.github.com/repos/WeAreROLI/JUCE/releases/" + endpoint); - std::unique_ptr<InputStream> inStream (latestVersionURL.createInputStream (false)); + URL latestVersionURL ("https://api.github.com/repos/juce-framework/JUCE/releases/" + endpoint); + std::unique_ptr<InputStream> inStream (latestVersionURL.createInputStream (false, nullptr, nullptr, {}, 5000)); if (inStream == nullptr) return nullptr; @@ -111,5 +117,5 @@ std::unique_ptr<VersionInfo> VersionInfo::fetch (const String& endpoint) } } - return std::unique_ptr<VersionInfo> (new VersionInfo ({ versionString, releaseNotes, std::move (parsedAssets) })); + return std::unique_ptr<VersionInfo> (new VersionInfo { versionString, releaseNotes, std::move (parsedAssets) }); } diff --git a/extras/Projucer/Source/Utility/Helpers/jucer_VersionInfo.h b/extras/Projucer/Source/Utility/Helpers/jucer_VersionInfo.h index 68ec8e71..65f67a4d 100644 --- a/extras/Projucer/Source/Utility/Helpers/jucer_VersionInfo.h +++ b/extras/Projucer/Source/Utility/Helpers/jucer_VersionInfo.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -48,7 +47,7 @@ public: const std::vector<Asset> assets; private: - VersionInfo() = default; + VersionInfo (String version, String releaseNotes, std::vector<Asset> assets); static std::unique_ptr<VersionInfo> fetch (const String&); }; diff --git a/extras/Projucer/Source/Utility/PIPs/jucer_PIPGenerator.cpp b/extras/Projucer/Source/Utility/PIPs/jucer_PIPGenerator.cpp index 6e219fe6..bc800c5d 100644 --- a/extras/Projucer/Source/Utility/PIPs/jucer_PIPGenerator.cpp +++ b/extras/Projucer/Source/Utility/PIPs/jucer_PIPGenerator.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -26,21 +25,11 @@ #include "../../Application/jucer_Headers.h" #include "../../ProjectSaving/jucer_ProjectExporter.h" +#include "../../ProjectSaving/jucer_ProjectExport_Xcode.h" +#include "../../ProjectSaving/jucer_ProjectExport_Android.h" #include "jucer_PIPGenerator.h" -#include "../../Project/jucer_Module.h" //============================================================================== -static String removeEnclosed (const String& input, const String& start, const String& end) -{ - auto startIndex = input.indexOf (start); - auto endIndex = input.indexOf (end) + end.length(); - - if (startIndex != -1 && endIndex != -1) - return input.replaceSection (startIndex, endIndex - startIndex, {}); - - return input; -} - static void ensureSingleNewLineAfterIncludes (StringArray& lines) { int lastIncludeIndex = -1; @@ -87,15 +76,16 @@ static bool isJUCEExample (const File& pipFile) return false; } -static bool isValidExporterName (StringRef exporterName) +static bool isValidExporterIdentifier (const Identifier& exporterIdentifier) { - return ProjectExporter::getExporterValueTreeNames().contains (exporterName, true); + return ProjectExporter::getTypeInfoForExporter (exporterIdentifier).identifier.toString().isNotEmpty(); } -static bool exporterRequiresExampleAssets (const String& exporterName, const String& projectName) +static bool exporterRequiresExampleAssets (const Identifier& exporterIdentifier, const String& projectName) { - return (exporterName == "XCODE_IPHONE" || exporterName == "ANDROIDSTUDIO") - || (exporterName == "XCODE_MAC" && projectName == "AUv3SynthPlugin"); + return (exporterIdentifier.toString() == XcodeProjectExporter::getValueTreeTypeNameiOS() + || exporterIdentifier.toString() == AndroidProjectExporter::getValueTreeTypeName()) + || (exporterIdentifier.toString() == XcodeProjectExporter::getValueTreeTypeNameMac() && projectName == "AUv3SynthPlugin"); } //============================================================================== @@ -119,12 +109,12 @@ PIPGenerator::PIPGenerator (const File& pip, const File& output, const File& juc auto isClipboard = (pip.getParentDirectory().getFileName() == "Clipboard" && pip.getParentDirectory().getParentDirectory().getFileName() == "PIPs"); - outputDirectory = outputDirectory.getChildFile (metadata[Ids::name].toString()); + outputDirectory = outputDirectory.getChildFile (metadata[Ids::name].toString()).getNonexistentSibling(); useLocalCopy = metadata[Ids::useLocalCopy].toString().trim().getIntValue() == 1 || isClipboard; if (userModulesPath != File()) { - availableUserModules.reset (new AvailableModuleList()); + availableUserModules.reset (new AvailableModulesList()); availableUserModules->scanPaths ({ userModulesPath }); } } @@ -245,13 +235,13 @@ ValueTree PIPGenerator::createBuildConfigChild (bool isDebug) return child; } -ValueTree PIPGenerator::createExporterChild (const String& exporterName) +ValueTree PIPGenerator::createExporterChild (const Identifier& exporterIdentifier) { - ValueTree exporter (exporterName); + ValueTree exporter (exporterIdentifier); - exporter.setProperty (Ids::targetFolder, "Builds/" + ProjectExporter::getTargetFolderForExporter (exporterName), nullptr); + exporter.setProperty (Ids::targetFolder, "Builds/" + ProjectExporter::getTypeInfoForExporter (exporterIdentifier).targetFolder, nullptr); - if (isJUCEExample (pipFile) && exporterRequiresExampleAssets (exporterName, metadata[Ids::name])) + if (isJUCEExample (pipFile) && exporterRequiresExampleAssets (exporterIdentifier, metadata[Ids::name])) { auto examplesDir = getExamplesDirectory(); @@ -259,8 +249,8 @@ ValueTree PIPGenerator::createExporterChild (const String& exporterName) { auto assetsDirectoryPath = examplesDir.getChildFile ("Assets").getFullPathName(); - exporter.setProperty (exporterName == "ANDROIDSTUDIO" ? Ids::androidExtraAssetsFolder - : Ids::customXcodeResourceFolders, + exporter.setProperty (exporterIdentifier.toString() == AndroidProjectExporter::getValueTreeTypeName() ? Ids::androidExtraAssetsFolder + : Ids::customXcodeResourceFolders, assetsDirectoryPath, nullptr); } else @@ -315,7 +305,7 @@ void PIPGenerator::addExporters (ValueTree& jucerTree) { e = e.trim().toUpperCase(); - if (isValidExporterName (e)) + if (isValidExporterIdentifier (e)) exportersTree.addChild (createExporterChild (e), -1, nullptr); } @@ -329,15 +319,6 @@ void PIPGenerator::addModules (ValueTree& jucerTree) auto modules = StringArray::fromTokens (metadata[Ids::dependencies_].toString(), ",", {}); modules.trim(); - auto projectType = metadata[Ids::type].toString(); - - if (projectType == "Console") - modules.mergeArray (getModulesRequiredForConsole()); - else if (projectType == "Component") - modules.mergeArray (getModulesRequiredForComponent()); - else if (projectType == "AudioProcessor") - modules.mergeArray (getModulesRequiredForAudioProcessor()); - for (auto& m : modules) modulesTree.addChild (createModuleChild (m.trim()), -1, nullptr); @@ -346,11 +327,17 @@ void PIPGenerator::addModules (ValueTree& jucerTree) Result PIPGenerator::setProjectSettings (ValueTree& jucerTree) { - jucerTree.setProperty (Ids::name, metadata[Ids::name], nullptr); - jucerTree.setProperty (Ids::companyName, metadata[Ids::vendor], nullptr); - jucerTree.setProperty (Ids::version, metadata[Ids::version], nullptr); - jucerTree.setProperty (Ids::userNotes, metadata[Ids::description], nullptr); - jucerTree.setProperty (Ids::companyWebsite, metadata[Ids::website], nullptr); + auto setPropertyIfNotEmpty = [&jucerTree] (const Identifier& name, const var& value) + { + if (value != var()) + jucerTree.setProperty (name, value, nullptr); + }; + + setPropertyIfNotEmpty (Ids::name, metadata[Ids::name]); + setPropertyIfNotEmpty (Ids::companyName, metadata[Ids::vendor]); + setPropertyIfNotEmpty (Ids::version, metadata[Ids::version]); + setPropertyIfNotEmpty (Ids::userNotes, metadata[Ids::description]); + setPropertyIfNotEmpty (Ids::companyWebsite, metadata[Ids::website]); auto defines = metadata[Ids::defines].toString(); @@ -370,35 +357,45 @@ Result PIPGenerator::setProjectSettings (ValueTree& jucerTree) : "\"File->Global Paths...\"") + " menu item."); } + + jucerTree.setProperty (Ids::displaySplashScreen, true, nullptr); } - jucerTree.setProperty (Ids::defines, defines, nullptr); + setPropertyIfNotEmpty (Ids::defines, defines); auto type = metadata[Ids::type].toString(); if (type == "Console") { - jucerTree.setProperty (Ids::projectType, "consoleapp", nullptr); + jucerTree.setProperty (Ids::projectType, build_tools::ProjectType_ConsoleApp::getTypeName(), nullptr); } else if (type == "Component") { - jucerTree.setProperty (Ids::projectType, "guiapp", nullptr); + jucerTree.setProperty (Ids::projectType, build_tools::ProjectType_GUIApp::getTypeName(), nullptr); } else if (type == "AudioProcessor") { - jucerTree.setProperty (Ids::projectType, "audioplug", nullptr); - jucerTree.setProperty (Ids::pluginManufacturer, metadata[Ids::vendor], nullptr); + jucerTree.setProperty (Ids::projectType, build_tools::ProjectType_AudioPlugin::getTypeName(), nullptr); jucerTree.setProperty (Ids::pluginAUIsSandboxSafe, "1", nullptr); + setPropertyIfNotEmpty (Ids::pluginManufacturer, metadata[Ids::vendor]); + StringArray pluginFormatsToBuild (Ids::buildVST3.toString(), Ids::buildAU.toString(), Ids::buildStandalone.toString()); pluginFormatsToBuild.addArray (getExtraPluginFormatsToBuild()); jucerTree.setProperty (Ids::pluginFormats, pluginFormatsToBuild.joinIntoString (","), nullptr); - if (! getPluginCharacteristics().isEmpty()) - jucerTree.setProperty (Ids::pluginCharacteristicsValue, getPluginCharacteristics().joinIntoString (","), nullptr); + const auto characteristics = metadata[Ids::pluginCharacteristics].toString(); + + if (characteristics.isNotEmpty()) + jucerTree.setProperty (Ids::pluginCharacteristicsValue, + characteristics.removeCharacters (" \t\n\r"), + nullptr); } + jucerTree.setProperty (Ids::useAppConfig, false, nullptr); + jucerTree.setProperty (Ids::addUsingNamespaceToJuceHeader, true, nullptr); + return Result::ok(); } @@ -423,52 +420,40 @@ void PIPGenerator::setModuleFlags (ValueTree& jucerTree) String PIPGenerator::getMainFileTextForType() { - String mainTemplate (BinaryData::jucer_PIPMain_cpp); + const auto type = metadata[Ids::type].toString(); - auto includeFilename = [&] + const auto mainTemplate = [&] { - if (useLocalCopy) return pipFile.getFileName(); - if (isTemp) return pipFile.getFullPathName(); + if (type == "Console") + return String (BinaryData::PIPConsole_cpp_in); - return RelativePath (pipFile, outputDirectory.getChildFile ("Source"), RelativePath::unknown).toUnixStyle(); - }(); - - mainTemplate = mainTemplate.replace ("%%filename%%", includeFilename) - .replace ("%%include_juce%%", CodeHelpers::createIncludePathIncludeStatement (Project::getJuceSourceHFilename())); + if (type == "Component") + return String (BinaryData::PIPComponent_cpp_in) + .replace ("${JUCE_PIP_NAME}", metadata[Ids::name].toString()) + .replace ("${PROJECT_VERSION}", metadata[Ids::version].toString()) + .replace ("${JUCE_PIP_MAIN_CLASS}", metadata[Ids::mainClass].toString()); - auto type = metadata[Ids::type].toString(); - - if (type == "Console") - { - mainTemplate = removeEnclosed (mainTemplate, "%%component_begin%%", "%%component_end%%"); - mainTemplate = removeEnclosed (mainTemplate, "%%audioprocessor_begin%%", "%%audioprocessor_end%%"); - mainTemplate = mainTemplate.replace ("%%console_begin%%", {}).replace ("%%console_end%%", {}); + if (type == "AudioProcessor") + return String (BinaryData::PIPAudioProcessor_cpp_in) + .replace ("${JUCE_PIP_MAIN_CLASS}", metadata[Ids::mainClass].toString()); - return ensureCorrectWhitespace (mainTemplate); - } - else if (type == "Component") - { - mainTemplate = removeEnclosed (mainTemplate, "%%audioprocessor_begin%%", "%%audioprocessor_end%%"); - mainTemplate = removeEnclosed (mainTemplate, "%%console_begin%%", "%%console_end%%"); - mainTemplate = mainTemplate.replace ("%%component_begin%%", {}).replace ("%%component_end%%", {}); + return String{}; + }(); - mainTemplate = mainTemplate.replace ("%%project_name%%", metadata[Ids::name].toString()); - mainTemplate = mainTemplate.replace ("%%project_version%%", metadata[Ids::version].toString()); + if (mainTemplate.isEmpty()) + return {}; - return ensureCorrectWhitespace (mainTemplate.replace ("%%startup%%", "mainWindow.reset (new MainWindow (" + metadata[Ids::name].toString().quoted() - + ", new " + metadata[Ids::mainClass].toString() + "(), *this));") - .replace ("%%shutdown%%", "mainWindow = nullptr;")); - } - else if (type == "AudioProcessor") + const auto includeFilename = [&] { - mainTemplate = removeEnclosed (mainTemplate, "%%component_begin%%", "%%component_end%%"); - mainTemplate = removeEnclosed (mainTemplate, "%%console_begin%%", "%%console_end%%"); - mainTemplate = mainTemplate.replace ("%%audioprocessor_begin%%", {}).replace ("%%audioprocessor_end%%", {}); + if (useLocalCopy) return pipFile.getFileName(); + if (isTemp) return pipFile.getFullPathName(); - return ensureCorrectWhitespace (mainTemplate.replace ("%%class_name%%", metadata[Ids::mainClass].toString())); - } + return build_tools::RelativePath (pipFile, + outputDirectory.getChildFile ("Source"), + build_tools::RelativePath::unknown).toUnixStyle(); + }(); - return {}; + return ensureCorrectWhitespace (mainTemplate.replace ("${JUCE_PIP_HEADER}", includeFilename)); } //============================================================================== @@ -510,35 +495,20 @@ bool PIPGenerator::copyRelativeFileToLocalSourceDirectory (const File& fileToCop StringArray PIPGenerator::getExtraPluginFormatsToBuild() const { - auto name = metadata[Ids::name].toString(); - - if (name == "AUv3SynthPlugin" || name == "AudioPluginDemo") - return { Ids::buildAUv3.toString() }; - else if (name == "InterAppAudioEffectPlugin") - return { Ids::enableIAA.toString() }; + auto tokens = StringArray::fromTokens (metadata[Ids::extraPluginFormats].toString(), ",", {}); - return {}; -} + for (auto& token : tokens) + { + token = [&] + { + if (token == "IAA") + return Ids::enableIAA.toString(); -StringArray PIPGenerator::getPluginCharacteristics() const -{ - auto name = metadata[Ids::name].toString(); - - if (name == "AudioPluginDemo") - return { Ids::pluginIsSynth.toString(), - Ids::pluginWantsMidiIn.toString(), - Ids::pluginProducesMidiOut.toString(), - Ids::pluginEditorRequiresKeys.toString() }; - else if (name == "AUv3SynthPlugin" || name == "MultiOutSynthPlugin") - return { Ids::pluginIsSynth.toString(), - Ids::pluginWantsMidiIn.toString(), - Ids::pluginIsSynth.toString() }; - else if (name == "ArpeggiatorPlugin") - return { Ids::pluginWantsMidiIn.toString(), - Ids::pluginProducesMidiOut.toString(), - Ids::pluginIsMidiEffectPlugin.toString() }; + return "build" + token; + }(); + } - return {}; + return tokens; } String PIPGenerator::getPathForModule (const String& moduleID) const @@ -550,7 +520,9 @@ String PIPGenerator::getPathForModule (const String& moduleID) const if (isTemp) return juceModulesPath.getFullPathName(); - return RelativePath (juceModulesPath, outputDirectory, RelativePath::projectFolder).toUnixStyle(); + return build_tools::RelativePath (juceModulesPath, + outputDirectory, + build_tools::RelativePath::projectFolder).toUnixStyle(); } } else if (availableUserModules != nullptr) @@ -560,7 +532,9 @@ String PIPGenerator::getPathForModule (const String& moduleID) const if (isTemp) return moduleRoot.getFullPathName(); - return RelativePath (moduleRoot , outputDirectory, RelativePath::projectFolder).toUnixStyle(); + return build_tools::RelativePath (moduleRoot, + outputDirectory, + build_tools::RelativePath::projectFolder).toUnixStyle(); } return {}; diff --git a/extras/Projucer/Source/Utility/PIPs/jucer_PIPGenerator.h b/extras/Projucer/Source/Utility/PIPs/jucer_PIPGenerator.h index dcd99d94..a85c7392 100644 --- a/extras/Projucer/Source/Utility/PIPs/jucer_PIPGenerator.h +++ b/extras/Projucer/Source/Utility/PIPs/jucer_PIPGenerator.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -27,6 +26,7 @@ #pragma once #include "../Helpers/jucer_MiscUtilities.h" +#include "../../Project/Modules/jucer_AvailableModulesList.h" //============================================================================== class PIPGenerator @@ -37,8 +37,8 @@ public: //============================================================================== bool hasValidPIP() const noexcept { return ! metadata[Ids::name].toString().isEmpty(); } - File getJucerFile() noexcept { return outputDirectory.getChildFile (metadata[Ids::name].toString() + ".jucer"); } - File getPIPFile() noexcept { return useLocalCopy ? outputDirectory.getChildFile ("Source").getChildFile (pipFile.getFileName()) : pipFile; } + File getJucerFile() const noexcept { return outputDirectory.getChildFile (metadata[Ids::name].toString() + ".jucer"); } + File getPIPFile() const noexcept { return useLocalCopy ? outputDirectory.getChildFile ("Source").getChildFile (pipFile.getFileName()) : pipFile; } String getMainClassName() const noexcept { return metadata[Ids::mainClass]; } @@ -55,7 +55,7 @@ private: ValueTree createModulePathChild (const String& moduleID); ValueTree createBuildConfigChild (bool isDebug); - ValueTree createExporterChild (const String& exporterName); + ValueTree createExporterChild (const Identifier& exporterIdentifier); ValueTree createModuleChild (const String& moduleID); void addExporters (ValueTree& jucerTree); @@ -72,20 +72,15 @@ private: bool copyRelativeFileToLocalSourceDirectory (const File&) const noexcept; StringArray getExtraPluginFormatsToBuild() const; - StringArray getPluginCharacteristics() const; String getPathForModule (const String&) const; File getExamplesDirectory() const; //============================================================================== File pipFile, outputDirectory, juceModulesPath, userModulesPath; - - std::unique_ptr<AvailableModuleList> availableUserModules; - + std::unique_ptr<AvailableModulesList> availableUserModules; var metadata; - - bool isTemp = false; - bool useLocalCopy = false; + bool isTemp = false, useLocalCopy = false; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PIPGenerator) }; diff --git a/extras/Projucer/Source/Utility/UI/PropertyComponents/jucer_ColourPropertyComponent.h b/extras/Projucer/Source/Utility/UI/PropertyComponents/jucer_ColourPropertyComponent.h index 6800f041..c853747d 100644 --- a/extras/Projucer/Source/Utility/UI/PropertyComponents/jucer_ColourPropertyComponent.h +++ b/extras/Projucer/Source/Utility/UI/PropertyComponents/jucer_ColourPropertyComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -51,7 +50,7 @@ private: a colour selector when you click it. */ struct ColourEditorComponent : public Component, - public Value::Listener + private Value::Listener { ColourEditorComponent (UndoManager* um, const Value& colour, Colour defaultCol, const bool canReset) @@ -72,7 +71,7 @@ private: Colour (0xffffffff).overlaidWith (colour)); g.setColour (Colours::white.overlaidWith (colour).contrasting()); - g.setFont (Font (getHeight() * 0.6f, Font::bold)); + g.setFont (Font ((float) getHeight() * 0.6f, Font::bold)); g.drawFittedText (colour.toDisplayString (true), getLocalBounds().reduced (2, 1), Justification::centred, 1); } @@ -117,12 +116,14 @@ private: if (undoManager != nullptr) undoManager->beginNewTransaction(); - CallOutBox::launchAsynchronously (new PopupColourSelector (colourValue, - defaultColour, - canResetToDefault), - getScreenBounds(), nullptr); + CallOutBox::launchAsynchronously (std::make_unique<PopupColourSelector> (colourValue, + defaultColour, + canResetToDefault), + getScreenBounds(), + nullptr); } + private: void valueChanged (Value&) override { refresh(); @@ -139,8 +140,8 @@ private: //============================================================================== struct PopupColourSelector : public Component, - public ChangeListener, - public Value::Listener + private ChangeListener, + private Value::Listener { PopupColourSelector (const Value& colour, Colour defaultCol, @@ -201,6 +202,7 @@ private: } } + private: void changeListenerCallback (ChangeBroadcaster*) override { if (selector.getCurrentColour() != getColour()) @@ -212,7 +214,6 @@ private: selector.setCurrentColour (getColour()); } - private: StoredSettings::ColourSelectorWithSwatches selector; TextButton defaultButton; Value colourValue; diff --git a/extras/Projucer/Source/Utility/UI/PropertyComponents/jucer_FilePathPropertyComponent.h b/extras/Projucer/Source/Utility/UI/PropertyComponents/jucer_FilePathPropertyComponent.h index 7acd7ae4..8a0b24eb 100644 --- a/extras/Projucer/Source/Utility/UI/PropertyComponents/jucer_FilePathPropertyComponent.h +++ b/extras/Projucer/Source/Utility/UI/PropertyComponents/jucer_FilePathPropertyComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -35,7 +34,7 @@ */ class FilePathPropertyComponent : public PropertyComponent, public FileDragAndDropTarget, - private Value::Listener + protected Value::Listener { public: FilePathPropertyComponent (Value valueToControl, const String& propertyName, bool isDir, bool thisOS = true, @@ -93,6 +92,12 @@ public: repaint(); } +protected: + void valueChanged (Value&) override + { + updateEditorColour(); + } + private: //============================================================================== void init() @@ -166,11 +171,6 @@ private: } } - void valueChanged (Value&) override - { - updateEditorColour(); - } - void lookAndFeelChanged() override { browseButton.setColour (TextButton::buttonColourId, findColour (secondaryButtonBackgroundColourId)); @@ -192,3 +192,40 @@ private: //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FilePathPropertyComponent) }; + +//============================================================================== +class FilePathPropertyComponentWithEnablement : public FilePathPropertyComponent +{ +public: + FilePathPropertyComponentWithEnablement (ValueWithDefault& valueToControl, + ValueWithDefault valueToListenTo, + const String& propertyName, + bool isDir, + bool thisOS = true, + const String& wildcardsToUse = "*", + const File& relativeRoot = File()) + : FilePathPropertyComponent (valueToControl, + propertyName, + isDir, + thisOS, + wildcardsToUse, + relativeRoot), + valueWithDefault (valueToListenTo), + value (valueToListenTo.getPropertyAsValue()) + { + value.addListener (this); + valueChanged (value); + } + + ~FilePathPropertyComponentWithEnablement() override { value.removeListener (this); } + +private: + void valueChanged (Value& v) override + { + FilePathPropertyComponent::valueChanged (v); + setEnabled (valueWithDefault.get()); + } + + ValueWithDefault valueWithDefault; + Value value; +}; diff --git a/extras/Projucer/Source/Utility/UI/PropertyComponents/jucer_LabelPropertyComponent.h b/extras/Projucer/Source/Utility/UI/PropertyComponents/jucer_LabelPropertyComponent.h index 196ec37c..ae710ab7 100644 --- a/extras/Projucer/Source/Utility/UI/PropertyComponents/jucer_LabelPropertyComponent.h +++ b/extras/Projucer/Source/Utility/UI/PropertyComponents/jucer_LabelPropertyComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/Utility/UI/PropertyComponents/jucer_PropertyComponentsWithEnablement.h b/extras/Projucer/Source/Utility/UI/PropertyComponents/jucer_PropertyComponentsWithEnablement.h index 2137e620..664b2edd 100644 --- a/extras/Projucer/Source/Utility/UI/PropertyComponents/jucer_PropertyComponentsWithEnablement.h +++ b/extras/Projucer/Source/Utility/UI/PropertyComponents/jucer_PropertyComponentsWithEnablement.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/Utility/UI/jucer_IconButton.h b/extras/Projucer/Source/Utility/UI/jucer_IconButton.h index dac86adc..e3a475d1 100644 --- a/extras/Projucer/Source/Utility/UI/jucer_IconButton.h +++ b/extras/Projucer/Source/Utility/UI/jucer_IconButton.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -28,19 +27,52 @@ //============================================================================== -struct IconButton : public Button +class IconButton : public Button { - IconButton (String name, const Path* p) - : Button (name), - icon (p, Colours::transparentBlack) +public: + IconButton (String buttonName, Image imageToDisplay) + : Button (buttonName), + iconImage (imageToDisplay) { - lookAndFeelChanged(); - setTooltip (name); + setTooltip (buttonName); + } + + IconButton (String buttonName, Path pathToDisplay) + : Button (buttonName), + iconPath (pathToDisplay), + iconImage (createImageFromPath (iconPath)) + { + setTooltip (buttonName); + } + + void setImage (Image newImage) + { + iconImage = newImage; + repaint(); + } + + void setPath (Path newPath) + { + iconImage = createImageFromPath (newPath); + repaint(); + } + + void setBackgroundColour (Colour backgroundColourToUse) + { + backgroundColour = backgroundColourToUse; + usingNonDefaultBackgroundColour = true; + } + + void setIconInset (int newIconInset) + { + iconInset = newIconInset; + repaint(); } void paintButton (Graphics& g, bool isMouseOverButton, bool isButtonDown) override { - auto alpha = 1.0f; + float alpha = 1.0f; + if (! isEnabled()) { isMouseOverButton = false; @@ -49,43 +81,56 @@ struct IconButton : public Button alpha = 0.2f; } - auto backgroundColour = isIDEButton ? Colours::white - : isUserButton ? findColour (userButtonBackgroundColourId) - : findColour (defaultButtonBackgroundColourId); + auto fill = isButtonDown ? backgroundColour.darker (0.5f) + : isMouseOverButton ? backgroundColour.darker (0.2f) + : backgroundColour; - backgroundColour = isButtonDown ? backgroundColour.darker (0.5f) - : isMouseOverButton ? backgroundColour.darker (0.2f) - : backgroundColour; - - auto bounds = getLocalBounds().toFloat(); + auto bounds = getLocalBounds(); if (isButtonDown) bounds.reduce (2, 2); Path ellipse; - ellipse.addEllipse (bounds); - g.reduceClipRegion(ellipse); + ellipse.addEllipse (bounds.toFloat()); + g.reduceClipRegion (ellipse); - g.setColour (backgroundColour.withAlpha (alpha)); + g.setColour (fill.withAlpha (alpha)); g.fillAll(); - if (iconImage != Image()) - { - if (isIDEButton) - bounds.reduce (7, 7); + g.setOpacity (alpha); + g.drawImage (iconImage, bounds.reduced (iconInset).toFloat(), RectanglePlacement::fillDestination, false); + } - g.setOpacity (alpha); - g.drawImage (iconImage, bounds, RectanglePlacement::fillDestination, false); - } - else - { - icon.withColour (findColour (defaultIconColourId).withAlpha (alpha)).draw (g, bounds.reduced (2, 2), false); - } +private: + void lookAndFeelChanged() override + { + if (! usingNonDefaultBackgroundColour) + backgroundColour = findColour (defaultButtonBackgroundColourId); + + if (iconPath != Path()) + iconImage = createImageFromPath (iconPath); + + repaint(); + } + + Image createImageFromPath (Path path) + { + Image image (Image::ARGB, 250, 250, true); + Graphics g (image); + + g.setColour (findColour (defaultIconColourId)); + + g.fillPath (path, RectanglePlacement (RectanglePlacement::centred) + .getTransformToFit (path.getBounds(), image.getBounds().toFloat())); + + return image; } - Icon icon; + Path iconPath; Image iconImage; + Colour backgroundColour { findColour (defaultButtonBackgroundColourId) }; + bool usingNonDefaultBackgroundColour = false; + int iconInset = 2; - bool isIDEButton = false; - bool isUserButton = false; + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (IconButton) }; diff --git a/extras/Projucer/Source/Utility/UI/jucer_Icons.cpp b/extras/Projucer/Source/Utility/UI/jucer_Icons.cpp index 34c14634..26530897 100644 --- a/extras/Projucer/Source/Utility/UI/jucer_Icons.cpp +++ b/extras/Projucer/Source/Utility/UI/jucer_Icons.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -1523,29 +1522,6 @@ const uint8 clion[] = { 110,109,0,0,0,0,0,0,0,0,98,0,0,0,0,170,170,38,67,0,0,0,0 0,192,218,67,98,0,128,44,67,0,192,218,67,0,0,220,66,0,192,218,67,252,255,61,66,0,192,218,67,98,252,255,61,66,170,138,213,67,252,255,61,66,84,85,208,67,252,255,61,66,254,31,203,67,99,101,0,0 }; } -/*static void convertSVGPathToCppData (const String& pathString) -{ - XmlElement svg ("svg"); - XmlElement* path = svg.createNewChildElement ("path"); - path->setAttribute ("d", pathString); - - std::unique_ptr<Drawable> d (Drawable::createFromSVG (svg)); - DrawablePath* dp = dynamic_cast<DrawablePath*> (d->getChildComponent(0)); - jassert (dp != nullptr); - Path p (dp->getPath()); - - p.applyTransform (RectanglePlacement (RectanglePlacement::centred).getTransformToFit (p.getBounds(), - Rectangle<float> (500.0f, 500.0f))); - - MemoryOutputStream data; - p.writePathToStream (data); - - MemoryOutputStream out; - CodeHelpers::writeDataAsCppLiteral (data.getMemoryBlock(), out, false, true); - - DBG (out.toString() << newLine); -}*/ - Icons::Icons() { #define JUCE_LOAD_PATH_DATA(name) \ diff --git a/extras/Projucer/Source/Utility/UI/jucer_Icons.h b/extras/Projucer/Source/Utility/UI/jucer_Icons.h index 1f7a6fb0..e1530f66 100644 --- a/extras/Projucer/Source/Utility/UI/jucer_Icons.h +++ b/extras/Projucer/Source/Utility/UI/jucer_Icons.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -30,18 +29,22 @@ //============================================================================== struct Icon { - Icon() : path (nullptr) {} - Icon (const Path& p, Colour c) : path (&p), colour (c) {} - Icon (const Path* p, Colour c) : path (p), colour (c) {} + Icon() = default; + + Icon (const Path& pathToUse, Colour pathColour) + : path (pathToUse), + colour (pathColour) + { + } void draw (Graphics& g, const juce::Rectangle<float>& area, bool isCrossedOut) const { - if (path != nullptr) + if (! path.isEmpty()) { g.setColour (colour); const RectanglePlacement placement (RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize); - g.fillPath (*path, placement.getTransformToFit (path->getBounds(), area)); + g.fillPath (path, placement.getTransformToFit (path.getBounds(), area)); if (isCrossedOut) { @@ -62,7 +65,7 @@ struct Icon return Icon (path, newColour); } - const Path* path; + Path path; Colour colour; }; diff --git a/extras/Projucer/Source/Utility/UI/jucer_JucerTreeViewBase.cpp b/extras/Projucer/Source/Utility/UI/jucer_JucerTreeViewBase.cpp index 617f3b69..cfb31074 100644 --- a/extras/Projucer/Source/Utility/UI/jucer_JucerTreeViewBase.cpp +++ b/extras/Projucer/Source/Utility/UI/jucer_JucerTreeViewBase.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -81,7 +80,7 @@ void JucerTreeViewBase::refreshSubItems() Font JucerTreeViewBase::getFont() const { - return Font (getItemHeight() * 0.6f); + return Font ((float) getItemHeight() * 0.6f); } void JucerTreeViewBase::paintOpenCloseButton (Graphics& g, const Rectangle<float>& area, Colour /*backgroundColour*/, bool isMouseOver) @@ -228,7 +227,7 @@ ProjectContentComponent* JucerTreeViewBase::getProjectContentComponent() const class JucerTreeViewBase::ItemSelectionTimer : public Timer { public: - ItemSelectionTimer (JucerTreeViewBase& tvb) : owner (tvb) {} + explicit ItemSelectionTimer (JucerTreeViewBase& tvb) : owner (tvb) {} void timerCallback() override { owner.invokeShowDocument(); } diff --git a/extras/Projucer/Source/Utility/UI/jucer_JucerTreeViewBase.h b/extras/Projucer/Source/Utility/UI/jucer_JucerTreeViewBase.h index 3f63af51..f20c08c1 100644 --- a/extras/Projucer/Source/Utility/UI/jucer_JucerTreeViewBase.h +++ b/extras/Projucer/Source/Utility/UI/jucer_JucerTreeViewBase.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -215,7 +214,7 @@ public: auto bounds = getLocalBounds().toFloat(); auto iconBounds = bounds.removeFromLeft ((float) iconWidth).reduced (7, 5); - bounds.removeFromRight (buttons.size() * bounds.getHeight()); + bounds.removeFromRight ((float) buttons.size() * bounds.getHeight()); item.paintIcon (g, iconBounds); item.paintContent (g, bounds.toNearestInt()); diff --git a/extras/Projucer/Source/Utility/UI/jucer_ProjucerLookAndFeel.cpp b/extras/Projucer/Source/Utility/UI/jucer_ProjucerLookAndFeel.cpp index f95f9e80..24ef85dc 100644 --- a/extras/Projucer/Source/Utility/UI/jucer_ProjucerLookAndFeel.cpp +++ b/extras/Projucer/Source/Utility/UI/jucer_ProjucerLookAndFeel.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -26,7 +25,10 @@ #include "../../Application/jucer_Headers.h" #include "jucer_ProjucerLookAndFeel.h" -#include "../../Application/jucer_Application.h" + +#ifndef BUILDING_JUCE_COMPILEENGINE + #include "../../Project/UI/jucer_ProjectContentComponent.h" +#endif //============================================================================== ProjucerLookAndFeel::ProjucerLookAndFeel() @@ -46,26 +48,42 @@ void ProjucerLookAndFeel::drawTabButton (TabBarButton& button, Graphics& g, bool g.fillRect (area); const auto alpha = button.isEnabled() ? ((isMouseOver || isMouseDown) ? 1.0f : 0.8f) : 0.3f; + auto textColour = findColour (defaultTextColourId).withMultipliedAlpha (alpha); #ifndef BUILDING_JUCE_COMPILEENGINE auto iconColour = findColour (button.isFrontTab() ? activeTabIconColourId : inactiveTabIconColourId); - if (button.getName() == "Project") - { - auto icon = Icon (getIcons().closedFolder, iconColour.withMultipliedAlpha (alpha)); - icon.draw (g, button.getTextArea().reduced (8, 8).toFloat(), false); - } - else if (button.getName() == "Build") + auto isProjectTab = button.getName() == ProjectContentComponent::getProjectTabName(); + auto isBuildTab = button.getName() == ProjectContentComponent::getBuildTabName(); + + if (isProjectTab || isBuildTab) { - auto icon = Icon (getIcons().buildTab, iconColour.withMultipliedAlpha (alpha)); - icon.draw (g, button.getTextArea().reduced (8, 8).toFloat(), false); + auto icon = Icon (isProjectTab ? getIcons().closedFolder : getIcons().buildTab, + iconColour.withMultipliedAlpha (alpha)); + + auto isSingleTab = (button.getTabbedButtonBar().getNumTabs() == 1); + + if (isSingleTab) + { + auto activeArea = button.getActiveArea().reduced (5); + + activeArea.removeFromLeft (15); + icon.draw (g, activeArea.removeFromLeft (activeArea.getHeight()).toFloat(), false); + activeArea.removeFromLeft (10); + + g.setColour (textColour); + g.drawFittedText (isProjectTab ? ProjectContentComponent::getProjectTabName() : ProjectContentComponent::getBuildTabName(), + activeArea, Justification::centredLeft, 1); + } + else + { + icon.draw (g, button.getTextArea().reduced (8, 8).toFloat(), false); + } } else #endif { - auto textColour = findColour (defaultTextColourId).withMultipliedAlpha (alpha); - TextLayout textLayout; LookAndFeel_V3::createTabTextLayout (button, (float) area.getWidth(), (float) area.getHeight(), textColour, textLayout); @@ -188,7 +206,7 @@ void ProjucerLookAndFeel::drawToggleButton (Graphics& g, ToggleButton& button, b { bounds.removeFromLeft (5); - const auto fontSize = jmin (15.0f, button.getHeight() * 0.75f); + const auto fontSize = jmin (15.0f, (float) button.getHeight() * 0.75f); g.setFont (fontSize); g.setColour (isPropertyComponentChild ? findColour (widgetTextColourId) @@ -457,7 +475,7 @@ Path ProjucerLookAndFeel::getArrowPath (Rectangle<float> arrowZone, const int di if (filled) path.closeSubPath(); - path.applyTransform (AffineTransform::rotation (direction * MathConstants<float>::halfPi, + path.applyTransform (AffineTransform::rotation ((float) direction * MathConstants<float>::halfPi, arrowZone.getCentreX(), arrowZone.getCentreY())); return path; diff --git a/extras/Projucer/Source/Utility/UI/jucer_ProjucerLookAndFeel.h b/extras/Projucer/Source/Utility/UI/jucer_ProjucerLookAndFeel.h index 58fae338..33b25809 100644 --- a/extras/Projucer/Source/Utility/UI/jucer_ProjucerLookAndFeel.h +++ b/extras/Projucer/Source/Utility/UI/jucer_ProjucerLookAndFeel.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/Utility/UI/jucer_SlidingPanelComponent.cpp b/extras/Projucer/Source/Utility/UI/jucer_SlidingPanelComponent.cpp index 8480ab30..3b8536c3 100644 --- a/extras/Projucer/Source/Utility/UI/jucer_SlidingPanelComponent.cpp +++ b/extras/Projucer/Source/Utility/UI/jucer_SlidingPanelComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/Utility/UI/jucer_SlidingPanelComponent.h b/extras/Projucer/Source/Utility/UI/jucer_SlidingPanelComponent.h index 5a994105..23438a24 100644 --- a/extras/Projucer/Source/Utility/UI/jucer_SlidingPanelComponent.h +++ b/extras/Projucer/Source/Utility/UI/jucer_SlidingPanelComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/extras/Projucer/Source/Utility/UI/jucer_UserSettingsPopup.h b/extras/Projucer/Source/Utility/UI/jucer_UserSettingsPopup.h deleted file mode 100644 index 36e60047..00000000 --- a/extras/Projucer/Source/Utility/UI/jucer_UserSettingsPopup.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - ============================================================================== - - 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. - - ============================================================================== -*/ - -#pragma once - -#include "../../Licenses/jucer_LicenseController.h" -#include "../../Application/jucer_Application.h" - -//============================================================================== -class UserSettingsPopup : public Component - #if ! JUCER_ENABLE_GPL_MODE - , private LicenseController::StateChangedCallback - #endif -{ -public: - UserSettingsPopup (bool isShownInsideWebview) - #if ! JUCER_ENABLE_GPL_MODE - : isInsideWebview (isShownInsideWebview) - #endif - { - #if JUCER_ENABLE_GPL_MODE - ignoreUnused (isShownInsideWebview); - #endif - - auto standardFont = Font (16.0f); - - loggedInUsernameLabel.reset (new Label ("Username Label")); - addAndMakeVisible (loggedInUsernameLabel.get()); - - loggedInUsernameLabel->setFont (standardFont); - loggedInUsernameLabel->setJustificationType (Justification::centred); - loggedInUsernameLabel->setMinimumHorizontalScale (0.75f); - - #if JUCER_ENABLE_GPL_MODE - loggedInUsernameLabel->setText ("GPL Mode: Re-compile with JUCER_ENABLE_GPL_MODE=0 to enable login!", - NotificationType::dontSendNotification); - #else - licenseTypeLabel.reset (new Label ("License Type Label")); - addAndMakeVisible (licenseTypeLabel.get()); - - licenseTypeLabel->setFont (standardFont); - licenseTypeLabel->setJustificationType (Justification::centred); - licenseTypeLabel->setMinimumHorizontalScale (1.0f); - - logoutButton.reset (new TextButton (isInsideWebview ? "Select different account..." : "Sign out")); - addAndMakeVisible (logoutButton.get()); - logoutButton->setColour (TextButton::buttonColourId, findColour (secondaryButtonBackgroundColourId)); - - logoutButton->onClick = [this] - { - dismissCalloutBox(); - ProjucerApplication::getApp().doLogout(); - }; - - if (! isInsideWebview) - { - switchLicenseButton.reset (new TextButton ("Switch License")); - addAndMakeVisible (switchLicenseButton.get()); - switchLicenseButton->onClick = [this] - { - dismissCalloutBox(); - - if (auto* controller = ProjucerApplication::getApp().licenseController.get()) - controller->chooseNewLicense(); - }; - } - - if (auto* controller = ProjucerApplication::getApp().licenseController.get()) - licenseStateChanged (controller->getState()); - #endif - } - - void paint (Graphics& g) override - { - g.fillAll (findColour (secondaryBackgroundColourId)); - } - - void resized() override - { - auto bounds = getLocalBounds().reduced (10); - - #if JUCER_ENABLE_GPL_MODE - loggedInUsernameLabel->setBounds (bounds); - #else - loggedInUsernameLabel->setBounds (bounds.removeFromTop (hasLicenseType ? 25 : 75)); - - if (hasLicenseType) - { - bounds.removeFromTop (10); - licenseTypeLabel->setBounds (bounds.removeFromTop (25)); - } - - bounds.removeFromBottom (5); - auto buttonArea = bounds.removeFromBottom (40); - - if (! isInsideWebview) - switchLicenseButton->setBounds (buttonArea.removeFromRight (buttonArea.getWidth() / 2).reduced (2)); - - logoutButton->setBounds (buttonArea.reduced (2)); - #endif - } - -private: - //============================================================================== - void dismissCalloutBox() - { - if (auto* parent = findParentComponentOfClass<CallOutBox>()) - parent->dismiss(); - } - - #if ! JUCER_ENABLE_GPL_MODE - void licenseStateChanged (const LicenseState& state) override - { - hasLicenseType = (state.type != LicenseState::Type::noLicenseChosenYet); - licenseTypeLabel->setVisible (hasLicenseType); - loggedInUsernameLabel->setText (state.username, NotificationType::dontSendNotification); - licenseTypeLabel->setText (LicenseState::licenseTypeToString (state.type), NotificationType::dontSendNotification); - } - - void lookAndFeelChanged() override - { - if (logoutButton != nullptr) - logoutButton->setColour (TextButton::buttonColourId, findColour (secondaryButtonBackgroundColourId)); - } - #endif - - //============================================================================== - std::unique_ptr<Label> loggedInUsernameLabel; - - #if ! JUCER_ENABLE_GPL_MODE - std::unique_ptr<Label> licenseTypeLabel; - std::unique_ptr<TextButton> logoutButton, switchLicenseButton; - bool hasLicenseType = false; - bool isInsideWebview; - #endif - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (UserSettingsPopup) -}; diff --git a/extras/Projucer/Source/Wizards/jucer_NewProjectWizard.h b/extras/Projucer/Source/Wizards/jucer_NewProjectWizard.h deleted file mode 100644 index aaa50fc6..00000000 --- a/extras/Projucer/Source/Wizards/jucer_NewProjectWizard.h +++ /dev/null @@ -1,204 +0,0 @@ -/* - ============================================================================== - - 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. - - ============================================================================== -*/ - -#pragma once - - -//============================================================================== -static void setExecutableNameForAllTargets (Project& project, const String& exeName) -{ - for (Project::ExporterIterator exporter (project); exporter.next();) - for (ProjectExporter::ConfigIterator config (*exporter); config.next();) - config->getValue (Ids::targetName) = exeName; -} - -static Project::Item createSourceGroup (Project& project) -{ - return project.getMainGroup().addNewSubGroup ("Source", 0); -} - -static File& getLastWizardFolder() -{ - if (getAppSettings().lastWizardFolder.isDirectory()) - return getAppSettings().lastWizardFolder; - - #if JUCE_WINDOWS - static File lastFolderFallback (File::getSpecialLocation (File::userDocumentsDirectory)); - #else - static File lastFolderFallback (File::getSpecialLocation (File::userHomeDirectory)); - #endif - - return lastFolderFallback; -} - -//============================================================================== -struct NewProjectWizard -{ - NewProjectWizard() {} - virtual ~NewProjectWizard() {} - - //============================================================================== - virtual String getName() const = 0; - virtual String getDescription() const = 0; - virtual const char* getIcon() const = 0; - - virtual StringArray getFileCreationOptions() { return {}; } - virtual Result processResultsFromSetupItems (WizardComp&) { return Result::ok(); } - - virtual bool initialiseProject (Project& project) = 0; - - virtual StringArray getDefaultModules() - { - return - { - "juce_core", - "juce_events", - "juce_graphics", - "juce_data_structures", - "juce_gui_basics", - "juce_gui_extra", - "juce_cryptography", - "juce_opengl", - "juce_audio_basics", - "juce_audio_devices", - "juce_audio_formats", - "juce_audio_processors" - }; - } - - String appTitle; - File targetFolder, projectFile, modulesFolder; - WizardComp* ownerWizardComp; - StringArray failedFiles; - - bool selectJuceFolder() - { - return ModulesFolderPathBox::selectJuceFolder (modulesFolder); - } - - //============================================================================== - Project* runWizard (WizardComp& wc, - const String& projectName, - const File& target, - bool useGlobalPath) - { - ownerWizardComp = &wc; - appTitle = projectName; - targetFolder = target; - - if (! targetFolder.exists()) - { - if (! targetFolder.createDirectory()) - failedFiles.add (targetFolder.getFullPathName()); - } - else if (FileHelpers::containsAnyNonHiddenFiles (targetFolder)) - { - if (! AlertWindow::showOkCancelBox (AlertWindow::InfoIcon, - TRANS("New JUCE Project"), - TRANS("You chose the folder:\n\nXFLDRX\n\n").replace ("XFLDRX", targetFolder.getFullPathName()) - + TRANS("This folder isn't empty - are you sure you want to create the project there?") - + "\n\n" - + TRANS("Any existing files with the same names may be overwritten by the new files."))) - return nullptr; - } - - projectFile = targetFolder.getChildFile (File::createLegalFileName (appTitle)) - .withFileExtension (Project::projectFileExtension); - - std::unique_ptr<Project> project (new Project (projectFile)); - - if (failedFiles.size() == 0) - { - project->setFile (projectFile); - project->setTitle (appTitle); - - if (! initialiseProject (*project)) - return nullptr; - - project->getConfigFlag ("JUCE_STRICT_REFCOUNTEDPOINTER") = true; - - addExporters (*project, wc); - addDefaultModules (*project, useGlobalPath); - - if (project->save (false, true) != FileBasedDocument::savedOk) - return nullptr; - - project->setChangedFlag (false); - } - - if (failedFiles.size() > 0) - { - AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon, - TRANS("Errors in Creating Project!"), - TRANS("The following files couldn't be written:") - + "\n\n" - + failedFiles.joinIntoString ("\n", 0, 10)); - return nullptr; - } - - StringPairArray data; - data.set ("label", "Project Type = " + project->getProjectTypeString()); - - Analytics::getInstance()->logEvent ("Project Setting", data, ProjucerAnalyticsEvent::projectEvent); - - return project.release(); - } - - //============================================================================== - File getSourceFilesFolder() const - { - return projectFile.getSiblingFile ("Source"); - } - - void createSourceFolder() - { - if (! getSourceFilesFolder().createDirectory()) - failedFiles.add (getSourceFilesFolder().getFullPathName()); - } - - void addDefaultModules (Project& project, bool useGlobalPath) - { - auto defaultModules = getDefaultModules(); - - AvailableModuleList list; - list.scanPaths ({ modulesFolder }); - - for (auto& mod : list.getAllModules()) - if (defaultModules.contains (mod.first)) - project.getEnabledModules().addModule (mod.second, false, useGlobalPath, false); - } - - void addExporters (Project& project, WizardComp& wizardComp) - { - StringArray types (wizardComp.platformTargets.getSelectedPlatforms()); - - for (int i = 0; i < types.size(); ++i) - project.addNewExporter (types[i]); - - if (project.getNumExporters() == 0) - project.createExporterForCurrentPlatform(); - } -}; diff --git a/extras/Projucer/Source/Wizards/jucer_NewProjectWizardClasses.cpp b/extras/Projucer/Source/Wizards/jucer_NewProjectWizardClasses.cpp deleted file mode 100644 index 4ef0c600..00000000 --- a/extras/Projucer/Source/Wizards/jucer_NewProjectWizardClasses.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* - ============================================================================== - - 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. - - ============================================================================== -*/ - -#include "../Application/jucer_Headers.h" -#include "jucer_NewProjectWizardClasses.h" -#include "../ProjectSaving/jucer_ProjectExporter.h" -#include "../Utility/UI/jucer_SlidingPanelComponent.h" - -struct NewProjectWizardClasses -{ - class WizardComp; - #include "jucer_NewProjectWizard.h" - - #include "jucer_ProjectWizard_GUIApp.h" - #include "jucer_ProjectWizard_Console.h" - #include "jucer_ProjectWizard_AudioPlugin.h" - #include "jucer_ProjectWizard_StaticLibrary.h" - #include "jucer_ProjectWizard_DLL.h" - #include "jucer_ProjectWizard_openGL.h" - #include "jucer_ProjectWizard_Animated.h" - #include "jucer_ProjectWizard_AudioApp.h" - #include "jucer_ProjectWizard_Blank.h" - - #include "jucer_NewProjectWizardComponent.h" - #include "jucer_TemplateThumbnailsComponent.h" - #include "jucer_StartPageComponent.h" - - //============================================================================== - static int getNumWizards() noexcept - { - return 9; - } - - static std::unique_ptr<NewProjectWizard> createWizardType (int index) - { - switch (index) - { - case 0: return std::unique_ptr<NewProjectWizard> (new NewProjectWizardClasses::GUIAppWizard()); - case 1: return std::unique_ptr<NewProjectWizard> (new NewProjectWizardClasses::AnimatedAppWizard()); - case 2: return std::unique_ptr<NewProjectWizard> (new NewProjectWizardClasses::OpenGLAppWizard()); - case 3: return std::unique_ptr<NewProjectWizard> (new NewProjectWizardClasses::ConsoleAppWizard()); - case 4: return std::unique_ptr<NewProjectWizard> (new NewProjectWizardClasses::AudioAppWizard()); - case 5: return std::unique_ptr<NewProjectWizard> (new NewProjectWizardClasses::AudioPluginAppWizard()); - case 6: return std::unique_ptr<NewProjectWizard> (new NewProjectWizardClasses::StaticLibraryWizard()); - case 7: return std::unique_ptr<NewProjectWizard> (new NewProjectWizardClasses::DynamicLibraryWizard()); - case 8: return std::unique_ptr<NewProjectWizard> (new NewProjectWizardClasses::BlankAppWizard()); - default: jassertfalse; break; - } - - return {}; - } - - static StringArray getWizardNames() - { - StringArray s; - - for (int i = 0; i < getNumWizards(); ++i) - s.add (createWizardType (i)->getName()); - - return s; - } -}; - -Component* createNewProjectWizardComponent() -{ - return new NewProjectWizardClasses::StartPageComponent(); -} diff --git a/extras/Projucer/Source/Wizards/jucer_NewProjectWizardComponent.h b/extras/Projucer/Source/Wizards/jucer_NewProjectWizardComponent.h deleted file mode 100644 index 8c83da37..00000000 --- a/extras/Projucer/Source/Wizards/jucer_NewProjectWizardComponent.h +++ /dev/null @@ -1,515 +0,0 @@ -/* - ============================================================================== - - 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. - - ============================================================================== -*/ - -#pragma once - - -//============================================================================== -class ModulesFolderPathBox : public Component -{ -public: - ModulesFolderPathBox (String initialFileOrDirectory) - : currentPathBox ("currentPathBox"), - openFolderButton (TRANS("...")), - modulesLabel (String(), TRANS("Modules Folder") + ":"), - useGlobalPathsToggle ("Use global module path") - { - if (initialFileOrDirectory.isEmpty()) - initialFileOrDirectory = getAppSettings().getStoredPath (Ids::defaultJuceModulePath, TargetOS::getThisOS()).get().toString(); - - setModulesFolder (initialFileOrDirectory); - - addAndMakeVisible (currentPathBox); - currentPathBox.setEditableText (true); - currentPathBox.onChange = [this] { setModulesFolder (File::getCurrentWorkingDirectory() - .getChildFile (currentPathBox.getText())); }; - - addAndMakeVisible (openFolderButton); - openFolderButton.setTooltip (TRANS ("Select JUCE modules folder")); - openFolderButton.onClick = [this] { selectJuceFolder(); }; - - addAndMakeVisible (modulesLabel); - modulesLabel.attachToComponent (&currentPathBox, true); - - auto updateEnablement = [this] - { - isUsingGlobalPaths = useGlobalPathsToggle.getToggleState(); - - currentPathBox.setEnabled (! isUsingGlobalPaths); - openFolderButton.setEnabled (! isUsingGlobalPaths); - modulesLabel.setEnabled (! isUsingGlobalPaths); - }; - - addAndMakeVisible (useGlobalPathsToggle); - useGlobalPathsToggle.setToggleState (true, sendNotification); - useGlobalPathsToggle.onClick = [updateEnablement] { updateEnablement(); }; - - updateEnablement(); - } - - void resized() override - { - auto b = getLocalBounds(); - - auto topSlice = b.removeFromTop (b.getHeight() / 2); - - openFolderButton.setBounds (topSlice.removeFromRight (30)); - modulesLabel.setBounds (topSlice.removeFromLeft (110)); - currentPathBox.setBounds (topSlice); - - b.removeFromTop (5); - useGlobalPathsToggle.setBounds (b.translated (20, 0)); - } - - static bool selectJuceFolder (File& result) - { - for (;;) - { - FileChooser fc ("Select your JUCE modules folder...", - { getAppSettings().getStoredPath (Ids::defaultJuceModulePath, TargetOS::getThisOS()).get().toString() }, - "*"); - - if (! fc.browseForDirectory()) - return false; - - if (isJUCEModulesFolder (fc.getResult())) - { - result = fc.getResult(); - return true; - } - - AlertWindow::showMessageBox (AlertWindow::WarningIcon, - "Not a valid JUCE modules folder!", - "Please select the folder containing your juce_* modules!\n\n" - "This is required so that the new project can be given some essential core modules."); - } - } - - void selectJuceFolder() - { - File result; - - if (selectJuceFolder (result)) - setModulesFolder (result); - } - - void setModulesFolder (const File& newFolder) - { - if (modulesFolder != newFolder) - { - modulesFolder = newFolder; - currentPathBox.setText (modulesFolder.getFullPathName(), dontSendNotification); - } - } - - File modulesFolder; - bool isUsingGlobalPaths = true; - -private: - ComboBox currentPathBox; - TextButton openFolderButton; - Label modulesLabel; - ToggleButton useGlobalPathsToggle; -}; - - -/** The target platforms chooser for the chosen template. */ -class PlatformTargetsComp : public Component, - private ListBoxModel -{ -public: - PlatformTargetsComp() - { - setOpaque (false); - - const Array<ProjectExporter::ExporterTypeInfo> types (ProjectExporter::getExporterTypes()); - - for (auto& type : types) - { - platforms.add (new PlatformType { type.getIcon(), type.name }); - addAndMakeVisible (toggles.add (new ToggleButton (String()))); - } - - listBox.setRowHeight (30); - listBox.setModel (this); - listBox.setOpaque (false); - listBox.setMultipleSelectionEnabled (true); - listBox.setClickingTogglesRowSelection (true); - listBox.setColour (ListBox::backgroundColourId, Colours::transparentBlack); - addAndMakeVisible (listBox); - - selectDefaultExporterIfNoneSelected(); - } - - StringArray getSelectedPlatforms() const - { - StringArray list; - - for (int i = 0; i < platforms.size(); ++i) - if (listBox.isRowSelected (i)) - list.add (platforms.getUnchecked(i)->name); - - return list; - } - - void selectDefaultExporterIfNoneSelected() - { - if (listBox.getNumSelectedRows() == 0) - { - for (int i = platforms.size(); --i >= 0;) - { - if (platforms.getUnchecked(i)->name == ProjectExporter::getCurrentPlatformExporterName()) - { - listBox.selectRow (i); - break; - } - } - } - } - - void resized() override - { - listBox.setBounds (getLocalBounds()); - } - - int getNumRows() override - { - return platforms.size(); - } - - void paintListBoxItem (int rowNumber, Graphics& g, int width, int height, bool rowIsSelected) override - { - ignoreUnused (width); - - if (auto* platform = platforms[rowNumber]) - { - auto bounds = getLocalBounds().withHeight (height).withTrimmedBottom (1); - g.setColour (findColour (rowNumber % 2 == 0 ? widgetBackgroundColourId - : secondaryWidgetBackgroundColourId)); - g.fillRect (bounds); - - bounds.removeFromLeft (10); - - auto toggleBounds = bounds.removeFromLeft (height); - drawToggle (g, toggleBounds, rowIsSelected); - - auto iconBounds = bounds.removeFromLeft (height).reduced (5); - - g.drawImageWithin (platform->icon, iconBounds.getX(), iconBounds.getY(), iconBounds.getWidth(), - iconBounds.getHeight(), RectanglePlacement::fillDestination); - - bounds.removeFromLeft (10); - g.setColour (findColour (widgetTextColourId)); - g.drawFittedText (platform->name, bounds, Justification::centredLeft, 1); - } - } - - void selectedRowsChanged (int) override - { - selectDefaultExporterIfNoneSelected(); - } - -private: - struct PlatformType - { - Image icon; - String name; - }; - - void drawToggle (Graphics& g, Rectangle<int> bounds, bool isToggled) - { - auto sideLength = jmin (bounds.getWidth(), bounds.getHeight()); - - bounds = bounds.withSizeKeepingCentre (sideLength, sideLength).reduced (4); - - g.setColour (findColour (ToggleButton::tickDisabledColourId)); - g.drawRoundedRectangle (bounds.toFloat(), 2.0f, 1.0f); - - if (isToggled) - { - g.setColour (findColour (ToggleButton::tickColourId)); - const auto tick = getTickShape (0.75f); - g.fillPath (tick, tick.getTransformToScaleToFit (bounds.reduced (4, 5).toFloat(), false)); - } - } - - Path getTickShape (float height) - { - static const unsigned char pathData[] = { 110,109,32,210,202,64,126,183,148,64,108,39,244,247,64,245,76,124,64,108,178,131,27,65,246,76,252,64,108,175,242,4,65,246,76,252, - 64,108,236,5,68,65,0,0,160,180,108,240,150,90,65,21,136,52,63,108,48,59,16,65,0,0,32,65,108,32,210,202,64,126,183,148,64, 99,101,0,0 }; - - Path path; - path.loadPathFromData (pathData, sizeof (pathData)); - path.scaleToFit (0, 0, height * 2.0f, height, true); - - return path; - } - - ListBox listBox; - OwnedArray<PlatformType> platforms; - OwnedArray<ToggleButton> toggles; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PlatformTargetsComp) -}; - - - -//============================================================================== -/** - The Component for project creation. - Features a file browser to select project destination and - a list box of platform targets to generate. -*/ -class WizardComp : public Component, - private FileBrowserListener -{ -public: - WizardComp() - : platformTargets(), - projectName (TRANS("Project name")), - modulesPathBox (getAppSettings().getStoredPath (Ids::defaultJuceModulePath, TargetOS::getThisOS()).get().toString()) - { - setOpaque (false); - - addChildAndSetID (&projectName, "projectName"); - projectName.setText ("NewProject"); - nameLabel.attachToComponent (&projectName, true); - projectName.onTextChange = [this] - { - updateCreateButton(); - fileBrowser.setFileName (File::createLegalFileName (projectName.getText())); - }; - - addChildAndSetID (&projectType, "projectType"); - projectType.addItemList (getWizardNames(), 1); - projectType.setSelectedId (1, dontSendNotification); - typeLabel.attachToComponent (&projectType, true); - projectType.onChange = [this] { updateFileCreationTypes(); }; - - addChildAndSetID (&fileOutline, "fileOutline"); - fileOutline.setColour (GroupComponent::outlineColourId, Colours::black.withAlpha (0.2f)); - fileOutline.setTextLabelPosition (Justification::centred); - - addChildAndSetID (&targetsOutline, "targetsOutline"); - targetsOutline.setColour (GroupComponent::outlineColourId, Colours::black.withAlpha (0.2f)); - targetsOutline.setTextLabelPosition (Justification::centred); - - addChildAndSetID (&platformTargets, "platformTargets"); - - addChildAndSetID (&fileBrowser, "fileBrowser"); - fileBrowser.setFilenameBoxLabel ("Folder:"); - fileBrowser.setFileName (File::createLegalFileName (projectName.getText())); - fileBrowser.addListener (this); - - addChildAndSetID (&createButton, "createButton"); - createButton.onClick = [this] { createProject(); }; - - addChildAndSetID (&cancelButton, "cancelButton"); - cancelButton.addShortcut (KeyPress (KeyPress::escapeKey)); - cancelButton.onClick = [this] { returnToTemplatesPage(); }; - - addChildAndSetID (&modulesPathBox, "modulesPathBox"); - - addChildAndSetID (&filesToCreate, "filesToCreate"); - filesToCreateLabel.attachToComponent (&filesToCreate, true); - - updateFileCreationTypes(); - updateCreateButton(); - - lookAndFeelChanged(); - } - - void paint (Graphics& g) override - { - g.fillAll (findColour (backgroundColourId)); - } - - void resized() override - { - auto r = getLocalBounds(); - - auto left = r.removeFromLeft (getWidth() / 2).reduced (15); - auto right = r.reduced (15); - - projectName.setBounds (left.removeFromTop (22).withTrimmedLeft (120)); - left.removeFromTop (20); - projectType.setBounds (left.removeFromTop (22).withTrimmedLeft (120)); - left.removeFromTop (20); - fileOutline.setBounds (left); - fileBrowser.setBounds (left.reduced (25)); - - auto buttons = right.removeFromBottom (30); - right.removeFromBottom (10); - createButton.setBounds (buttons.removeFromRight (130)); - buttons.removeFromRight (10); - cancelButton.setBounds (buttons.removeFromRight (130)); - - filesToCreate.setBounds (right.removeFromTop (22).withTrimmedLeft (150)); - right.removeFromTop (20); - modulesPathBox.setBounds (right.removeFromTop (50)); - right.removeFromTop (20); - - targetsOutline.setBounds (right); - platformTargets.setBounds (right.reduced (25)); - } - - void returnToTemplatesPage() - { - if (auto* parent = findParentComponentOfClass<SlidingPanelComponent>()) - { - if (parent->getNumTabs() > 0) - parent->goToTab (parent->getCurrentTabIndex() - 1); - } - else - { - jassertfalse; - } - } - - void createProject() - { - auto* mw = Component::findParentComponentOfClass<MainWindow>(); - jassert (mw != nullptr); - - std::unique_ptr<NewProjectWizardClasses::NewProjectWizard> wizard = createWizard(); - - if (wizard != nullptr) - { - Result result (wizard->processResultsFromSetupItems (*this)); - - if (result.failed()) - { - AlertWindow::showMessageBox (AlertWindow::WarningIcon, - TRANS("Create Project"), - result.getErrorMessage()); - return; - } - - - wizard->modulesFolder = modulesPathBox.isUsingGlobalPaths ? File (getAppSettings().getStoredPath (Ids::defaultJuceModulePath, TargetOS::getThisOS()).get().toString()) - : modulesPathBox.modulesFolder; - - if (! isJUCEModulesFolder (wizard->modulesFolder)) - { - if (modulesPathBox.isUsingGlobalPaths) - AlertWindow::showMessageBox (AlertWindow::AlertIconType::WarningIcon, "Invalid Global Path", - "Your global JUCE module search path is invalid. Please select the folder containing your JUCE modules " - "to set as the default path."); - - if (! wizard->selectJuceFolder()) - return; - - if (modulesPathBox.isUsingGlobalPaths) - { - getAppSettings().getStoredPath (Ids::defaultJuceModulePath, TargetOS::getThisOS()).setValue (wizard->modulesFolder.getFullPathName(), nullptr); - ProjucerApplication::getApp().rescanJUCEPathModules(); - } - } - - auto projectDir = fileBrowser.getSelectedFile (0); - std::unique_ptr<Project> project (wizard->runWizard (*this, projectName.getText(), - projectDir, - modulesPathBox.isUsingGlobalPaths)); - - if (project != nullptr) - { - mw->setProject (std::move (project)); - getAppSettings().lastWizardFolder = projectDir.getParentDirectory(); - } - } - } - - void updateFileCreationTypes() - { - StringArray items; - - std::unique_ptr<NewProjectWizardClasses::NewProjectWizard> wizard = createWizard(); - - if (wizard != nullptr) - items = wizard->getFileCreationOptions(); - - filesToCreate.clear(); - filesToCreate.addItemList (items, 1); - filesToCreate.setSelectedId (1, dontSendNotification); - } - - void selectionChanged() override {} - - void fileClicked (const File&, const MouseEvent&) override {} - void fileDoubleClicked (const File&) override {} - - void browserRootChanged (const File&) override - { - fileBrowser.setFileName (File::createLegalFileName (projectName.getText())); - } - - int getFileCreationComboID() const - { - return filesToCreate.getSelectedItemIndex(); - } - - ComboBox projectType, filesToCreate; - PlatformTargetsComp platformTargets; - -private: - TextEditor projectName; - - Label nameLabel { {}, TRANS("Project Name") + ":" }; - Label typeLabel { {}, TRANS("Project Type") + ":" }; - Label filesToCreateLabel { {}, TRANS("Files to Auto-Generate") + ":" }; - - FileBrowserComponent fileBrowser { FileBrowserComponent::saveMode - | FileBrowserComponent::canSelectDirectories - | FileBrowserComponent::doNotClearFileNameOnRootChange, - NewProjectWizardClasses::getLastWizardFolder(), nullptr, nullptr }; - - GroupComponent fileOutline { {}, TRANS("Project Folder") + ":" }; - GroupComponent targetsOutline { {}, TRANS("Target Platforms") + ":" }; - - TextButton createButton { TRANS("Create") + "..." }; - TextButton cancelButton { TRANS("Cancel") }; - ModulesFolderPathBox modulesPathBox; - - std::unique_ptr<NewProjectWizardClasses::NewProjectWizard> createWizard() - { - return createWizardType (projectType.getSelectedItemIndex()); - } - - void updateCreateButton() - { - createButton.setEnabled (projectName.getText().trim().isNotEmpty()); - } - - void lookAndFeelChanged() override - { - projectName.setColour (TextEditor::backgroundColourId, findColour (backgroundColourId)); - projectName.setColour (TextEditor::textColourId, findColour (defaultTextColourId)); - projectName.setColour (TextEditor::outlineColourId, findColour (defaultTextColourId)); - projectName.applyFontToAllText (projectName.getFont()); - - fileBrowser.resized(); - } -}; diff --git a/extras/Projucer/Source/Wizards/jucer_ProjectWizard_Animated.h b/extras/Projucer/Source/Wizards/jucer_ProjectWizard_Animated.h deleted file mode 100644 index 5dbd0d38..00000000 --- a/extras/Projucer/Source/Wizards/jucer_ProjectWizard_Animated.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - ============================================================================== - - 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. - - ============================================================================== -*/ - -#pragma once - - -//============================================================================== -struct AnimatedAppWizard : public NewProjectWizard -{ - AnimatedAppWizard() {} - - String getName() const override { return TRANS("Animated Application"); } - String getDescription() const override { return TRANS("Creates an application which draws an animated graphical display."); } - const char* getIcon() const override { return BinaryData::wizard_AnimatedApp_svg; } - - StringArray getFileCreationOptions() override - { - return { "Create header and implementation files", - "Create header file only" }; - } - - Result processResultsFromSetupItems (WizardComp& setupComp) override - { - createCppFile = false; - - switch (setupComp.getFileCreationComboID()) - { - case 0: createCppFile = true; break; - case 1: break; - default: jassertfalse; break; - } - - return Result::ok(); - } - - bool initialiseProject (Project& project) override - { - createSourceFolder(); - - File mainCppFile = getSourceFilesFolder().getChildFile ("Main.cpp"); - File contentCompCpp = getSourceFilesFolder().getChildFile ("MainComponent.cpp"); - File contentCompH = contentCompCpp.withFileExtension (".h"); - String contentCompName = "MainComponent"; - - project.setProjectType (ProjectType_GUIApp::getTypeName()); - - Project::Item sourceGroup (createSourceGroup (project)); - - setExecutableNameForAllTargets (project, File::createLegalFileName (appTitle)); - - auto juceHeaderInclude = CodeHelpers::createIncludePathIncludeStatement (Project::getJuceSourceHFilename()); - auto appHeaders = juceHeaderInclude + newLine + CodeHelpers::createIncludeStatement (contentCompH, mainCppFile); - - // create main window - String windowH = project.getFileTemplate (createCppFile ? "jucer_AnimatedComponentTemplate_h" - : "jucer_AnimatedComponentSimpleTemplate_h") - .replace ("%%include_juce%%", juceHeaderInclude) - .replace ("%%content_component_class%%", contentCompName, false); - - if (! FileHelpers::overwriteFileWithNewDataIfDifferent (contentCompH, windowH)) - failedFiles.add (contentCompH.getFullPathName()); - - sourceGroup.addFileAtIndex (contentCompH, -1, false); - - if (createCppFile) - { - String windowCpp = project.getFileTemplate ("jucer_AnimatedComponentTemplate_cpp") - .replace ("%%include_juce%%", juceHeaderInclude) - .replace ("%%include_corresponding_header%%", CodeHelpers::createIncludeStatement (contentCompH, contentCompCpp), false) - .replace ("%%content_component_class%%", contentCompName, false); - - if (! FileHelpers::overwriteFileWithNewDataIfDifferent (contentCompCpp, windowCpp)) - failedFiles.add (contentCompCpp.getFullPathName()); - - sourceGroup.addFileAtIndex (contentCompCpp, -1, true); - } - - // create main cpp - String mainCpp = project.getFileTemplate ("jucer_MainTemplate_SimpleWindow_cpp") - .replace ("%%app_headers%%", appHeaders, false) - .replace ("%%app_class_name%%", CodeHelpers::makeValidIdentifier (appTitle + "Application", false, true, false), false) - .replace ("%%content_component_class%%", contentCompName, false) - .replace ("%%allow_more_than_one_instance%%", "true", false); - - if (! FileHelpers::overwriteFileWithNewDataIfDifferent (mainCppFile, mainCpp)) - failedFiles.add (mainCppFile.getFullPathName()); - - sourceGroup.addFileAtIndex (mainCppFile,-1, true); - - return true; - } - -private: - bool createCppFile; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AnimatedAppWizard) -}; diff --git a/extras/Projucer/Source/Wizards/jucer_ProjectWizard_AudioApp.h b/extras/Projucer/Source/Wizards/jucer_ProjectWizard_AudioApp.h deleted file mode 100644 index 45eed357..00000000 --- a/extras/Projucer/Source/Wizards/jucer_ProjectWizard_AudioApp.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - ============================================================================== - - 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. - - ============================================================================== -*/ - -#pragma once - - -//============================================================================== -struct AudioAppWizard : public NewProjectWizard -{ - AudioAppWizard() {} - - String getName() const override { return TRANS("Audio Application"); } - String getDescription() const override { return TRANS("Creates a JUCE application with a single window component and audio and MIDI in/out functions."); } - const char* getIcon() const override { return BinaryData::wizard_AudioApp_svg; } - - StringArray getFileCreationOptions() override - { - return { "Create header and implementation files", - "Create header file only" }; - } - - Result processResultsFromSetupItems (WizardComp& setupComp) override - { - createCppFile = false; - - switch (setupComp.getFileCreationComboID()) - { - case 0: createCppFile = true; break; - case 1: break; - default: jassertfalse; break; - } - - return Result::ok(); - } - - bool initialiseProject (Project& project) override - { - createSourceFolder(); - - File mainCppFile = getSourceFilesFolder().getChildFile ("Main.cpp"); - File contentCompCpp = getSourceFilesFolder().getChildFile ("MainComponent.cpp"); - File contentCompH = contentCompCpp.withFileExtension (".h"); - String contentCompName = "MainComponent"; - - project.setProjectType (ProjectType_GUIApp::getTypeName()); - - Project::Item sourceGroup (createSourceGroup (project)); - - setExecutableNameForAllTargets (project, File::createLegalFileName (appTitle)); - - auto juceHeaderInclude = CodeHelpers::createIncludePathIncludeStatement (Project::getJuceSourceHFilename()); - auto appHeaders = juceHeaderInclude + newLine + CodeHelpers::createIncludeStatement (contentCompH, mainCppFile); - - // create main window - String windowH = project.getFileTemplate (createCppFile ? "jucer_AudioComponentTemplate_h" - : "jucer_AudioComponentSimpleTemplate_h") - .replace ("%%include_juce%%", juceHeaderInclude) - .replace ("%%content_component_class%%", contentCompName, false); - - if (! FileHelpers::overwriteFileWithNewDataIfDifferent (contentCompH, windowH)) - failedFiles.add (contentCompH.getFullPathName()); - - sourceGroup.addFileAtIndex (contentCompH, -1, false); - - if (createCppFile) - { - String windowCpp = project.getFileTemplate ("jucer_AudioComponentTemplate_cpp") - .replace ("%%include_juce%%", juceHeaderInclude) - .replace ("%%include_corresponding_header%%", CodeHelpers::createIncludeStatement (contentCompH, contentCompCpp), false) - .replace ("%%content_component_class%%", contentCompName, false); - - - - if (! FileHelpers::overwriteFileWithNewDataIfDifferent (contentCompCpp, windowCpp)) - failedFiles.add (contentCompCpp.getFullPathName()); - - sourceGroup.addFileAtIndex (contentCompCpp, -1, true); - } - - // create main cpp - String mainCpp = project.getFileTemplate ("jucer_MainTemplate_SimpleWindow_cpp") - .replace ("%%app_headers%%", appHeaders, false) - .replace ("%%app_class_name%%", CodeHelpers::makeValidIdentifier (appTitle + "Application", false, true, false), false) - .replace ("%%content_component_class%%", contentCompName, false) - .replace ("%%allow_more_than_one_instance%%", "true", false); - - if (! FileHelpers::overwriteFileWithNewDataIfDifferent (mainCppFile, mainCpp)) - failedFiles.add (mainCppFile.getFullPathName()); - - sourceGroup.addFileAtIndex (mainCppFile, -1, true); - - return true; - } - - StringArray getDefaultModules() override - { - StringArray s (NewProjectWizard::getDefaultModules()); - s.addIfNotAlreadyThere ("juce_audio_utils"); - return s; - } - -private: - bool createCppFile; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioAppWizard) -}; diff --git a/extras/Projucer/Source/Wizards/jucer_ProjectWizard_AudioPlugin.h b/extras/Projucer/Source/Wizards/jucer_ProjectWizard_AudioPlugin.h deleted file mode 100644 index 767efd83..00000000 --- a/extras/Projucer/Source/Wizards/jucer_ProjectWizard_AudioPlugin.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - ============================================================================== - - 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. - - ============================================================================== -*/ - -#pragma once - - -//============================================================================== -struct AudioPluginAppWizard : public NewProjectWizard -{ - AudioPluginAppWizard() {} - - String getName() const override { return TRANS("Audio Plug-In"); } - String getDescription() const override { return TRANS("Creates a VST/AU/RTAS/AAX audio plug-in. This template features a single window GUI and Audio/MIDI IO functions."); } - const char* getIcon() const override { return BinaryData::wizard_AudioPlugin_svg; } - - StringArray getDefaultModules() override - { - StringArray s (NewProjectWizard::getDefaultModules()); - s.add ("juce_audio_plugin_client"); - s.add ("juce_audio_utils"); - - return s; - } - - bool initialiseProject (Project& project) override - { - createSourceFolder(); - - String filterClassName = CodeHelpers::makeValidIdentifier (appTitle, true, true, false) + "AudioProcessor"; - filterClassName = filterClassName.substring (0, 1).toUpperCase() + filterClassName.substring (1); - String editorClassName = filterClassName + "Editor"; - - File filterCppFile = getSourceFilesFolder().getChildFile ("PluginProcessor.cpp"); - File filterHFile = filterCppFile.withFileExtension (".h"); - File editorCppFile = getSourceFilesFolder().getChildFile ("PluginEditor.cpp"); - File editorHFile = editorCppFile.withFileExtension (".h"); - - project.setProjectType (ProjectType_AudioPlugin::getTypeName()); - - setExecutableNameForAllTargets (project, File::createLegalFileName (appTitle)); - - auto juceHeaderInclude = CodeHelpers::createIncludePathIncludeStatement (Project::getJuceSourceHFilename()); - - String filterCpp = project.getFileTemplate ("jucer_AudioPluginFilterTemplate_cpp") - .replace ("%%filter_headers%%", CodeHelpers::createIncludeStatement (filterHFile, filterCppFile) - + newLine + CodeHelpers::createIncludeStatement (editorHFile, filterCppFile), false) - .replace ("%%filter_class_name%%", filterClassName, false) - .replace ("%%editor_class_name%%", editorClassName, false); - - String filterH = project.getFileTemplate ("jucer_AudioPluginFilterTemplate_h") - .replace ("%%app_headers%%", juceHeaderInclude, false) - .replace ("%%filter_class_name%%", filterClassName, false); - - String editorCpp = project.getFileTemplate ("jucer_AudioPluginEditorTemplate_cpp") - .replace ("%%editor_cpp_headers%%", CodeHelpers::createIncludeStatement (filterHFile, filterCppFile) - + newLine + CodeHelpers::createIncludeStatement (editorHFile, filterCppFile), false) - .replace ("%%filter_class_name%%", filterClassName, false) - .replace ("%%editor_class_name%%", editorClassName, false); - - String editorH = project.getFileTemplate ("jucer_AudioPluginEditorTemplate_h") - .replace ("%%editor_headers%%", juceHeaderInclude + newLine + CodeHelpers::createIncludeStatement (filterHFile, filterCppFile), false) - .replace ("%%filter_class_name%%", filterClassName, false) - .replace ("%%editor_class_name%%", editorClassName, false); - - if (! FileHelpers::overwriteFileWithNewDataIfDifferent (filterCppFile, filterCpp)) - failedFiles.add (filterCppFile.getFullPathName()); - - if (! FileHelpers::overwriteFileWithNewDataIfDifferent (filterHFile, filterH)) - failedFiles.add (filterHFile.getFullPathName()); - - if (! FileHelpers::overwriteFileWithNewDataIfDifferent (editorCppFile, editorCpp)) - failedFiles.add (editorCppFile.getFullPathName()); - - if (! FileHelpers::overwriteFileWithNewDataIfDifferent (editorHFile, editorH)) - failedFiles.add (editorHFile.getFullPathName()); - - Project::Item sourceGroup (createSourceGroup (project)); - - sourceGroup.addFileAtIndex (filterCppFile, -1, true); - sourceGroup.addFileAtIndex (filterHFile, -1, false); - sourceGroup.addFileAtIndex (editorCppFile, -1, true); - sourceGroup.addFileAtIndex (editorHFile, -1, false); - - project.getConfigFlag ("JUCE_VST3_CAN_REPLACE_VST2") = 0; - - return true; - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioPluginAppWizard) -}; diff --git a/extras/Projucer/Source/Wizards/jucer_ProjectWizard_Blank.h b/extras/Projucer/Source/Wizards/jucer_ProjectWizard_Blank.h deleted file mode 100644 index 0cdfb9e9..00000000 --- a/extras/Projucer/Source/Wizards/jucer_ProjectWizard_Blank.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - ============================================================================== - - 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. - - ============================================================================== -*/ - -#pragma once - - -//============================================================================== -struct BlankAppWizard : public NewProjectWizard -{ - BlankAppWizard() {} - - String getName() const override { return TRANS("Empty Application"); } - String getDescription() const override { return TRANS("Creates a blank JUCE GUI application."); } - const char* getIcon() const override { return BinaryData::wizard_GUI_svg; } - - bool initialiseProject (Project& project) override - { - createSourceFolder(); - project.setProjectType (ProjectType_GUIApp::getTypeName()); - Project::Item sourceGroup (createSourceGroup (project)); - setExecutableNameForAllTargets (project, File::createLegalFileName (appTitle)); - - return true; - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BlankAppWizard) -}; diff --git a/extras/Projucer/Source/Wizards/jucer_ProjectWizard_Console.h b/extras/Projucer/Source/Wizards/jucer_ProjectWizard_Console.h deleted file mode 100644 index 3aba175c..00000000 --- a/extras/Projucer/Source/Wizards/jucer_ProjectWizard_Console.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - ============================================================================== - - 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. - - ============================================================================== -*/ - -#pragma once - - -//============================================================================== -struct ConsoleAppWizard : public NewProjectWizard -{ - ConsoleAppWizard() {} - - String getName() const override { return TRANS("Console Application"); } - String getDescription() const override { return TRANS("Creates a command-line application without GUI support."); } - const char* getIcon() const override { return BinaryData::wizard_ConsoleApp_svg; } - - StringArray getFileCreationOptions() override - { - return { "Create a Main.cpp file", - "Don't create any files" }; - } - - Result processResultsFromSetupItems (WizardComp& setupComp) override - { - createMainCpp = false; - - switch (setupComp.getFileCreationComboID()) - { - case 0: createMainCpp = true; break; - case 1: break; - default: jassertfalse; break; - } - - return Result::ok(); - } - - bool initialiseProject (Project& project) override - { - createSourceFolder(); - - project.setProjectType (ProjectType_ConsoleApp::getTypeName()); - - Project::Item sourceGroup (createSourceGroup (project)); - - setExecutableNameForAllTargets (project, File::createLegalFileName (appTitle)); - - if (createMainCpp) - { - File mainCppFile = getSourceFilesFolder().getChildFile ("Main.cpp"); - - String mainCpp = project.getFileTemplate ("jucer_MainConsoleAppTemplate_cpp") - .replace ("%%app_headers%%", CodeHelpers::createIncludePathIncludeStatement (Project::getJuceSourceHFilename()), false); - - if (! FileHelpers::overwriteFileWithNewDataIfDifferent (mainCppFile, mainCpp)) - failedFiles.add (mainCppFile.getFullPathName()); - - sourceGroup.addFileAtIndex (mainCppFile, -1, true); - } - - return true; - } - -private: - bool createMainCpp; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ConsoleAppWizard) -}; diff --git a/extras/Projucer/Source/Wizards/jucer_ProjectWizard_DLL.h b/extras/Projucer/Source/Wizards/jucer_ProjectWizard_DLL.h deleted file mode 100644 index 53878cbd..00000000 --- a/extras/Projucer/Source/Wizards/jucer_ProjectWizard_DLL.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - ============================================================================== - - 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. - - ============================================================================== -*/ - -#pragma once - - -//============================================================================== -struct DynamicLibraryWizard : public NewProjectWizard -{ - DynamicLibraryWizard() {} - - String getName() const override { return TRANS("Dynamic Library"); } - String getDescription() const override { return TRANS("Creates a Dynamic Library template with support for all JUCE features."); } - const char* getIcon() const override { return BinaryData::wizard_DLL_svg; } - - bool initialiseProject (Project& project) override - { - createSourceFolder(); - project.setProjectType (ProjectType_DLL::getTypeName()); - createSourceGroup (project); - setExecutableNameForAllTargets (project, File::createLegalFileName (appTitle)); - - return true; - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DynamicLibraryWizard) -}; diff --git a/extras/Projucer/Source/Wizards/jucer_ProjectWizard_GUIApp.h b/extras/Projucer/Source/Wizards/jucer_ProjectWizard_GUIApp.h deleted file mode 100644 index 710ae576..00000000 --- a/extras/Projucer/Source/Wizards/jucer_ProjectWizard_GUIApp.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - ============================================================================== - - 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. - - ============================================================================== -*/ - -#pragma once - - -//============================================================================== -struct GUIAppWizard : public NewProjectWizard -{ - GUIAppWizard() {} - - String getName() const override { return TRANS("GUI Application"); } - String getDescription() const override { return TRANS("Creates a blank JUCE application with a single window component."); } - const char* getIcon() const override { return BinaryData::wizard_GUI_svg; } - - StringArray getFileCreationOptions() override - { - return { "Create a Main.cpp file with header and implementation files", - "Create a Main.cpp file with header file only", - "Create a Main.cpp file only", - "Don't create any files" }; - } - - Result processResultsFromSetupItems (WizardComp& setupComp) override - { - createMainCpp = createWindow = createCppFile = false; - - switch (setupComp.getFileCreationComboID()) - { - case 0: createMainCpp = createWindow = createCppFile = true; break; - case 1: createMainCpp = createWindow = true; break; - case 2: createMainCpp = true; break; - case 3: break; - default: jassertfalse; break; - } - - return Result::ok(); - } - - bool initialiseProject (Project& project) override - { - createSourceFolder(); - - File mainCppFile = getSourceFilesFolder().getChildFile ("Main.cpp"); - File contentCompCpp = getSourceFilesFolder().getChildFile ("MainComponent.cpp"); - File contentCompH = contentCompCpp.withFileExtension (".h"); - String contentCompName = "MainComponent"; - - project.setProjectType (ProjectType_GUIApp::getTypeName()); - - Project::Item sourceGroup (createSourceGroup (project)); - - setExecutableNameForAllTargets (project, File::createLegalFileName (appTitle)); - - auto juceHeaderInclude = CodeHelpers::createIncludePathIncludeStatement (Project::getJuceSourceHFilename()); - auto appHeaders = juceHeaderInclude; - - if (createWindow) - { - appHeaders << newLine << CodeHelpers::createIncludeStatement (contentCompH, mainCppFile); - - String windowH = project.getFileTemplate (createCppFile ? "jucer_ContentCompTemplate_h" - : "jucer_ContentCompSimpleTemplate_h") - .replace ("%%include_juce%%", juceHeaderInclude) - .replace ("%%content_component_class%%", contentCompName, false); - - if (! FileHelpers::overwriteFileWithNewDataIfDifferent (contentCompH, windowH)) - failedFiles.add (contentCompH.getFullPathName()); - - sourceGroup.addFileAtIndex (contentCompH, -1, false); - - if (createCppFile) - { - String windowCpp = project.getFileTemplate ("jucer_ContentCompTemplate_cpp") - .replace ("%%include_juce%%", juceHeaderInclude) - .replace ("%%include_corresponding_header%%", CodeHelpers::createIncludeStatement (contentCompH, contentCompCpp), false) - .replace ("%%content_component_class%%", contentCompName, false); - - if (! FileHelpers::overwriteFileWithNewDataIfDifferent (contentCompCpp, windowCpp)) - failedFiles.add (contentCompCpp.getFullPathName()); - - sourceGroup.addFileAtIndex (contentCompCpp, -1, true); - } - } - - if (createMainCpp) - { - String mainCpp = project.getFileTemplate (createWindow ? "jucer_MainTemplate_Window_cpp" - : "jucer_MainTemplate_NoWindow_cpp") - .replace ("%%app_headers%%", appHeaders, false) - .replace ("%%app_class_name%%", CodeHelpers::makeValidIdentifier (appTitle + "Application", false, true, false), false) - .replace ("%%content_component_class%%", contentCompName, false) - .replace ("%%allow_more_than_one_instance%%", "true", false); - - if (! FileHelpers::overwriteFileWithNewDataIfDifferent (mainCppFile, mainCpp)) - failedFiles.add (mainCppFile.getFullPathName()); - - sourceGroup.addFileAtIndex (mainCppFile, -1, true); - } - - return true; - } - -private: - bool createMainCpp, createWindow, createCppFile; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GUIAppWizard) -}; diff --git a/extras/Projucer/Source/Wizards/jucer_ProjectWizard_StaticLibrary.h b/extras/Projucer/Source/Wizards/jucer_ProjectWizard_StaticLibrary.h deleted file mode 100644 index 8d5cceb6..00000000 --- a/extras/Projucer/Source/Wizards/jucer_ProjectWizard_StaticLibrary.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - ============================================================================== - - 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. - - ============================================================================== -*/ - -#pragma once - - -//============================================================================== -struct StaticLibraryWizard : public NewProjectWizard -{ - StaticLibraryWizard() {} - - String getName() const override { return TRANS("Static Library"); } - String getDescription() const override { return TRANS("Creates a static library."); } - const char* getIcon() const override { return BinaryData::wizard_StaticLibrary_svg; } - - bool initialiseProject (Project& project) override - { - createSourceFolder(); - project.setProjectType (ProjectType_StaticLibrary::getTypeName()); - createSourceGroup (project); - setExecutableNameForAllTargets (project, File::createLegalFileName (appTitle)); - - return true; - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (StaticLibraryWizard) -}; diff --git a/extras/Projucer/Source/Wizards/jucer_ProjectWizard_openGL.h b/extras/Projucer/Source/Wizards/jucer_ProjectWizard_openGL.h deleted file mode 100644 index 29b092b2..00000000 --- a/extras/Projucer/Source/Wizards/jucer_ProjectWizard_openGL.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - ============================================================================== - - 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. - - ============================================================================== -*/ - -#pragma once - - -//============================================================================== -struct OpenGLAppWizard : public NewProjectWizard -{ - OpenGLAppWizard() {} - - String getName() const override { return TRANS("OpenGL Application"); } - String getDescription() const override { return TRANS("Creates a blank JUCE application with a single window component. This component supports openGL drawing features including 3D model import and GLSL shaders."); } - const char* getIcon() const override { return BinaryData::wizard_OpenGL_svg; } - - StringArray getFileCreationOptions() override - { - return { "Create header and implementation files", - "Create header file only" }; - } - - Result processResultsFromSetupItems (WizardComp& setupComp) override - { - createCppFile = false; - - switch (setupComp.getFileCreationComboID()) - { - case 0: createCppFile = true; break; - case 1: break; - default: jassertfalse; break; - } - - return Result::ok(); - } - - bool initialiseProject (Project& project) override - { - createSourceFolder(); - - File mainCppFile = getSourceFilesFolder().getChildFile ("Main.cpp"); - File contentCompCpp = getSourceFilesFolder().getChildFile ("MainComponent.cpp"); - File contentCompH = contentCompCpp.withFileExtension (".h"); - String contentCompName = "MainComponent"; - - project.setProjectType (ProjectType_GUIApp::getTypeName()); - - Project::Item sourceGroup (createSourceGroup (project)); - - setExecutableNameForAllTargets (project, File::createLegalFileName (appTitle)); - - auto juceHeaderInclude = CodeHelpers::createIncludePathIncludeStatement (Project::getJuceSourceHFilename()); - auto appHeaders = juceHeaderInclude + newLine + CodeHelpers::createIncludeStatement (contentCompH, mainCppFile); - - // create main window - String windowH = project.getFileTemplate (createCppFile ? "jucer_OpenGLComponentTemplate_h" - : "jucer_OpenGLComponentSimpleTemplate_h") - .replace ("%%include_juce%%", juceHeaderInclude) - .replace ("%%content_component_class%%", contentCompName, false); - - if (! FileHelpers::overwriteFileWithNewDataIfDifferent (contentCompH, windowH)) - failedFiles.add (contentCompH.getFullPathName()); - - sourceGroup.addFileAtIndex (contentCompH, -1, false); - - if (createCppFile) - { - String windowCpp = project.getFileTemplate ("jucer_OpenGLComponentTemplate_cpp") - .replace ("%%include_juce%%", juceHeaderInclude) - .replace ("%%include_corresponding_header%%", CodeHelpers::createIncludeStatement (contentCompH, contentCompCpp), false) - .replace ("%%content_component_class%%", contentCompName, false); - - if (! FileHelpers::overwriteFileWithNewDataIfDifferent (contentCompCpp, windowCpp)) - failedFiles.add (contentCompCpp.getFullPathName()); - - sourceGroup.addFileAtIndex (contentCompCpp, -1, true); - } - - // create main cpp - String mainCpp = project.getFileTemplate ("jucer_MainTemplate_SimpleWindow_cpp") - .replace ("%%app_headers%%", appHeaders, false) - .replace ("%%app_class_name%%", CodeHelpers::makeValidIdentifier (appTitle + "Application", false, true, false), false) - .replace ("%%content_component_class%%", contentCompName, false) - .replace ("%%allow_more_than_one_instance%%", "true", false); - - if (! FileHelpers::overwriteFileWithNewDataIfDifferent (mainCppFile, mainCpp)) - failedFiles.add (mainCppFile.getFullPathName()); - - sourceGroup.addFileAtIndex (mainCppFile, -1, true); - - return true; - } - -private: - bool createCppFile; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OpenGLAppWizard) -}; diff --git a/extras/Projucer/Source/Wizards/jucer_StartPageComponent.h b/extras/Projucer/Source/Wizards/jucer_StartPageComponent.h deleted file mode 100644 index 40fade93..00000000 --- a/extras/Projucer/Source/Wizards/jucer_StartPageComponent.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - ============================================================================== - - 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. - - ============================================================================== -*/ - -#pragma once - - -//============================================================================== -class StartPageComponent : public Component -{ -public: - StartPageComponent() - { - setSize (900, 650); - - WizardComp* projectWizard = new WizardComp(); - - panel.addTab ("Create New Project", new TemplateTileBrowser (projectWizard), true); - panel.addTab ("New Project Options", projectWizard, true); - - addAndMakeVisible (panel); - } - - void paint (Graphics& g) override - { - g.fillAll (findColour (backgroundColourId)); - } - - void resized() override - { - panel.setBounds (getLocalBounds()); - } - -private: - SlidingPanelComponent panel; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (StartPageComponent) -}; diff --git a/extras/Projucer/Source/Wizards/jucer_TemplateThumbnailsComponent.h b/extras/Projucer/Source/Wizards/jucer_TemplateThumbnailsComponent.h deleted file mode 100644 index 1706f538..00000000 --- a/extras/Projucer/Source/Wizards/jucer_TemplateThumbnailsComponent.h +++ /dev/null @@ -1,266 +0,0 @@ -/* - ============================================================================== - - 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. - - ============================================================================== -*/ - -#pragma once - - -//============================================================================== -/** - Template option tile button. - The drawable button object class for the tile icons and buttons in the TemplateTileBrowser -*/ -class TemplateOptionButton : public DrawableButton -{ -public: - TemplateOptionButton (const String& buttonName, ButtonStyle buttonStyle, const char* thumbSvg) - : DrawableButton (buttonName, buttonStyle) - { - // svg for thumbnail icon - auto svg = parseXML (thumbSvg); - jassert (svg != nullptr); - thumb = Drawable::createFromSVG (*svg); - - // svg for thumbnail background highlight - auto backSvg = parseXML (BinaryData::wizard_Highlight_svg); - jassert (backSvg != nullptr); - hoverBackground = Drawable::createFromSVG (*backSvg); - - name = buttonName; - - description = "<insert description>"; - } - - void paintButton (Graphics& g, bool isMouseOverButton, bool /*isButtonDown*/) override - { - const Rectangle<float> r (getLocalBounds().toFloat()); - const Colour buttonColour (0xffA35E93); - - if (isMouseOverButton) - { - if (getStyle() == ImageFitted) - { - hoverBackground->drawWithin (g, r, RectanglePlacement::centred, 1.0); - thumb->drawWithin (g, r, RectanglePlacement::centred, 1.0); - } - else - { - g.setColour (buttonColour.withAlpha (0.3f)); - g.fillRoundedRectangle (r.reduced (2.0f, 2.0f), 10.0f); - g.setColour (buttonColour); - g.drawRoundedRectangle (r.reduced (2.0f, 2.0f), 10.0f, 2.0f); - } - } - else - { - if (getStyle() == ImageFitted) - { - thumb->drawWithin (g, r, RectanglePlacement::centred, 1.0); - } - else - { - g.setColour (buttonColour); - g.drawRoundedRectangle (r.reduced (2.0f, 2.0f), 10.0f, 2.0f); - } - } - - Rectangle<float> textTarget; - - // center the text for the text buttons or position the text in the image buttons - if (getStyle() != ImageFitted) - { - textTarget = getLocalBounds().toFloat(); - } - else - { - textTarget = RectanglePlacement (RectanglePlacement::centred).appliedTo (thumb->getDrawableBounds(), r); - textTarget = textTarget.removeFromBottom (textTarget.getHeight() * 0.3f); - } - - g.setColour (findColour (defaultTextColourId)); - g.drawText (name, textTarget, Justification::centred, true); - } - - void resized() override - { - thumb->setBoundsToFit (getLocalBounds(), Justification::centred, false); - } - - void setDescription (String descript) noexcept - { - description = descript; - } - - String getDescription() const noexcept - { - return description; - } - -private: - void clicked() override - { - StringPairArray data; - data.set ("label", getName()); - - Analytics::getInstance()->logEvent ("Start Page Button", data, ProjucerAnalyticsEvent::startPageEvent); - } - - using DrawableButton::clicked; - - std::unique_ptr<Drawable> thumb, hoverBackground; - String name, description; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TemplateOptionButton) -}; - - - -//============================================================================== -/** - Project Template Component for front page. - Features multiple icon buttons to select the type of project template -*/ -class TemplateTileBrowser : public Component -{ -public: - TemplateTileBrowser (WizardComp* projectWizard) - { - const int numWizardButtons = getNumWizards() - 1; // ( - 1 because the last one is blank) - - for (int i = 0; i < numWizardButtons; ++i) - { - auto wizard = createWizardType (i); - - TemplateOptionButton* b = new TemplateOptionButton (wizard->getName(), - TemplateOptionButton::ImageFitted, - wizard->getIcon()); - optionButtons.add (b); - addAndMakeVisible (b); - b->setDescription (wizard->getDescription()); - b->onClick = [this, b] { showWizardButton (b); }; - b->onStateChange = [this] { repaint(); }; - } - - // Handle Open Project button functionality - ApplicationCommandManager& commandManager = ProjucerApplication::getCommandManager(); - - addAndMakeVisible (blankProjectButton); - addAndMakeVisible (openProjectButton); - addAndMakeVisible (browseDemosButton); - addAndMakeVisible (viewTutorialsButton); - - blankProjectButton.onClick = [this] { createBlankProject(); }; - openProjectButton.setCommandToTrigger (&commandManager, CommandIDs::open, true); - browseDemosButton.setCommandToTrigger (&commandManager, CommandIDs::launchDemoRunner, true); - viewTutorialsButton.setCommandToTrigger (&commandManager, CommandIDs::showTutorials, true); - - newProjectWizard = projectWizard; - } - - void paint (Graphics& g) override - { - g.setColour (findColour (contentHeaderBackgroundColourId)); - g.fillRect (getLocalBounds().removeFromTop (60)); - - g.setColour (Colours::white); - g.setFont (20.0f); - g.drawText ("Create New Project", 0, 0, getWidth(), 60, Justification::centred, true); - - auto descriptionBox = (getLocalBounds().reduced (30).removeFromBottom (50)); - - g.setColour (findColour (defaultTextColourId)); - g.setFont (15.0f); - - for (int i = 0; i < optionButtons.size(); ++i) - if (optionButtons.getUnchecked(i)->isOver()) - g.drawFittedText (optionButtons.getUnchecked(i)->getDescription(), descriptionBox, Justification::centredBottom, 5, 1.0f); - } - - void resized() override - { - auto bounds = getLocalBounds().reduced (40, 0); - bounds.removeFromTop (60); - - { - auto optionBounds = bounds.removeFromTop (roundToInt (bounds.getHeight() * 0.65f)); - - auto topSlice = optionBounds.removeFromTop (optionBounds.getHeight() / 2).reduced (0, 10); - auto bottomSlice = optionBounds.reduced (0, 10); - - const int numHorizontal = 4; - - for (int i = 0; i < optionButtons.size(); ++i) - { - auto& sliceToUse = (i < numHorizontal ? topSlice : bottomSlice); - - optionButtons.getUnchecked (i)->setBounds (sliceToUse.removeFromLeft (sliceToUse.getWidth() / (4 - (i % 4))).reduced (10, 0)); - } - } - - bounds.removeFromTop (20); - auto topButtonBounds = bounds.removeFromTop (50); - - openProjectButton.setBounds (topButtonBounds.reduced (80, 0)); - - bounds.removeFromTop (10); - auto bottomButtonBounds = bounds.removeFromTop (35); - - blankProjectButton.setBounds (bottomButtonBounds.removeFromLeft (bottomButtonBounds.getWidth() / 3).reduced (10, 0)); - browseDemosButton.setBounds (bottomButtonBounds.removeFromLeft (bottomButtonBounds.getWidth() / 2).reduced (10, 0)); - viewTutorialsButton.setBounds (bottomButtonBounds.removeFromLeft (bottomButtonBounds.getWidth()).reduced (10, 0)); - } - - void showWizard (const String& name) - { - newProjectWizard->projectType.setText (name); - - if (SlidingPanelComponent* parent = findParentComponentOfClass<SlidingPanelComponent>()) - parent->goToTab (1); - else - jassertfalse; - } - - void createBlankProject() - { - showWizard (BlankAppWizard().getName()); - } - -private: - OwnedArray<TemplateOptionButton> optionButtons; - NewProjectWizardClasses::WizardComp* newProjectWizard; - - TemplateOptionButton blankProjectButton { "Create Blank Project", TemplateOptionButton::ImageOnButtonBackground, BinaryData::wizard_Openfile_svg }, - openProjectButton { "Open Existing Project", TemplateOptionButton::ImageOnButtonBackground, BinaryData::wizard_Openfile_svg }, - browseDemosButton { "Browse JUCE Demos", TemplateOptionButton::ImageOnButtonBackground, BinaryData::wizard_Openfile_svg }, - viewTutorialsButton { "View JUCE Tutorials", TemplateOptionButton::ImageOnButtonBackground, BinaryData::wizard_Openfile_svg }; - - void showWizardButton (Button* b) - { - if (dynamic_cast<TemplateOptionButton*> (b) != nullptr) - showWizard (b->getButtonText()); - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TemplateTileBrowser) -}; diff --git a/extras/UnitTestRunner/Builds/LinuxMakefile/Makefile b/extras/UnitTestRunner/Builds/LinuxMakefile/Makefile index 091f7798..0e5d4789 100644 --- a/extras/UnitTestRunner/Builds/LinuxMakefile/Makefile +++ b/extras/UnitTestRunner/Builds/LinuxMakefile/Makefile @@ -35,13 +35,13 @@ ifeq ($(CONFIG),Debug) TARGET_ARCH := endif - JUCE_CPPFLAGS := $(DEPFLAGS) -DLINUX=1 -DDEBUG=1 -D_DEBUG=1 -DJUCE_UNIT_TESTS=1 -DJUCER_LINUX_MAKE_6D53C8B4=1 -DJUCE_APP_VERSION=1.0.0 -DJUCE_APP_VERSION_HEX=0x10000 $(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_CONSOLEAPP := -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_CPPFLAGS := $(DEPFLAGS) "-DLINUX=1" "-DDEBUG=1" "-D_DEBUG=1" "-DJUCE_DISPLAY_SPLASH_SCREEN=0" "-DJUCE_USE_DARK_SPLASH_SCREEN=1" "-DJUCE_PROJUCER_VERSION=0x60005" "-DJUCE_MODULE_AVAILABLE_juce_analytics=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_devices=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_formats=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_processors=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_utils=1" "-DJUCE_MODULE_AVAILABLE_juce_blocks_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_core=1" "-DJUCE_MODULE_AVAILABLE_juce_cryptography=1" "-DJUCE_MODULE_AVAILABLE_juce_data_structures=1" "-DJUCE_MODULE_AVAILABLE_juce_dsp=1" "-DJUCE_MODULE_AVAILABLE_juce_events=1" "-DJUCE_MODULE_AVAILABLE_juce_graphics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_extra=1" "-DJUCE_MODULE_AVAILABLE_juce_opengl=1" "-DJUCE_MODULE_AVAILABLE_juce_osc=1" "-DJUCE_MODULE_AVAILABLE_juce_product_unlocking=1" "-DJUCE_MODULE_AVAILABLE_juce_video=1" "-DJUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1" "-DJUCE_STRICT_REFCOUNTEDPOINTER=1" "-DJUCE_STANDALONE_APPLICATION=1" "-DJUCE_UNIT_TESTS=1" "-DJUCER_LINUX_MAKE_6D53C8B4=1" "-DJUCE_APP_VERSION=1.0.0" "-DJUCE_APP_VERSION_HEX=0x10000" $(shell pkg-config --cflags alsa freetype2 libcurl webkit2gtk-4.0 gtk+-x11-3.0) -pthread -I../../JuceLibraryCode -I../../../../modules $(CPPFLAGS) + JUCE_CPPFLAGS_CONSOLEAPP := "-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_CONSOLEAPP := UnitTestRunner JUCE_CFLAGS += $(JUCE_CPPFLAGS) $(TARGET_ARCH) -g -ggdb -O0 $(CFLAGS) JUCE_CXXFLAGS += $(JUCE_CFLAGS) -std=c++14 $(CXXFLAGS) - JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) -L/usr/X11R6/lib/ $(shell pkg-config --libs alsa x11 xinerama xext freetype2 webkit2gtk-4.0 gtk+-x11-3.0 libcurl) -lrt -ldl -lpthread -lGL $(LDFLAGS) + JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) $(shell pkg-config --libs alsa freetype2 libcurl) -fvisibility=hidden -lrt -ldl -lpthread -lGL $(LDFLAGS) CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(TARGET) $(JUCE_OBJDIR) endif @@ -56,13 +56,13 @@ ifeq ($(CONFIG),Release) TARGET_ARCH := endif - JUCE_CPPFLAGS := $(DEPFLAGS) -DLINUX=1 -DNDEBUG=1 -DJUCE_UNIT_TESTS=1 -DJUCER_LINUX_MAKE_6D53C8B4=1 -DJUCE_APP_VERSION=1.0.0 -DJUCE_APP_VERSION_HEX=0x10000 $(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_CONSOLEAPP := -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_CPPFLAGS := $(DEPFLAGS) "-DLINUX=1" "-DNDEBUG=1" "-DJUCE_DISPLAY_SPLASH_SCREEN=0" "-DJUCE_USE_DARK_SPLASH_SCREEN=1" "-DJUCE_PROJUCER_VERSION=0x60005" "-DJUCE_MODULE_AVAILABLE_juce_analytics=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_devices=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_formats=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_processors=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_utils=1" "-DJUCE_MODULE_AVAILABLE_juce_blocks_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_core=1" "-DJUCE_MODULE_AVAILABLE_juce_cryptography=1" "-DJUCE_MODULE_AVAILABLE_juce_data_structures=1" "-DJUCE_MODULE_AVAILABLE_juce_dsp=1" "-DJUCE_MODULE_AVAILABLE_juce_events=1" "-DJUCE_MODULE_AVAILABLE_juce_graphics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_extra=1" "-DJUCE_MODULE_AVAILABLE_juce_opengl=1" "-DJUCE_MODULE_AVAILABLE_juce_osc=1" "-DJUCE_MODULE_AVAILABLE_juce_product_unlocking=1" "-DJUCE_MODULE_AVAILABLE_juce_video=1" "-DJUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1" "-DJUCE_STRICT_REFCOUNTEDPOINTER=1" "-DJUCE_STANDALONE_APPLICATION=1" "-DJUCE_UNIT_TESTS=1" "-DJUCER_LINUX_MAKE_6D53C8B4=1" "-DJUCE_APP_VERSION=1.0.0" "-DJUCE_APP_VERSION_HEX=0x10000" $(shell pkg-config --cflags alsa freetype2 libcurl webkit2gtk-4.0 gtk+-x11-3.0) -pthread -I../../JuceLibraryCode -I../../../../modules $(CPPFLAGS) + JUCE_CPPFLAGS_CONSOLEAPP := "-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_CONSOLEAPP := UnitTestRunner JUCE_CFLAGS += $(JUCE_CPPFLAGS) $(TARGET_ARCH) -O3 $(CFLAGS) JUCE_CXXFLAGS += $(JUCE_CFLAGS) -std=c++14 $(CXXFLAGS) - JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) -L/usr/X11R6/lib/ $(shell pkg-config --libs alsa x11 xinerama xext freetype2 webkit2gtk-4.0 gtk+-x11-3.0 libcurl) -fvisibility=hidden -lrt -ldl -lpthread -lGL $(LDFLAGS) + JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) $(shell pkg-config --libs alsa freetype2 libcurl) -fvisibility=hidden -lrt -ldl -lpthread -lGL $(LDFLAGS) CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(TARGET) $(JUCE_OBJDIR) endif @@ -95,7 +95,7 @@ all : $(JUCE_OUTDIR)/$(JUCE_TARGET_CONSOLEAPP) $(JUCE_OUTDIR)/$(JUCE_TARGET_CONSOLEAPP) : $(OBJECTS_CONSOLEAPP) $(RESOURCES) @command -v pkg-config >/dev/null 2>&1 || { echo >&2 "pkg-config not installed. Please, install it."; exit 1; } - @pkg-config --print-errors alsa x11 xinerama xext freetype2 webkit2gtk-4.0 gtk+-x11-3.0 libcurl + @pkg-config --print-errors alsa freetype2 libcurl @echo Linking "UnitTestRunner - ConsoleApp" -$(V_AT)mkdir -p $(JUCE_BINDIR) -$(V_AT)mkdir -p $(JUCE_LIBDIR) diff --git a/extras/UnitTestRunner/Builds/MacOSX/ConsoleApp.entitlements b/extras/UnitTestRunner/Builds/MacOSX/ConsoleApp.entitlements deleted file mode 100644 index 6631ffa6..00000000 --- a/extras/UnitTestRunner/Builds/MacOSX/ConsoleApp.entitlements +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> -</dict> -</plist> diff --git a/extras/UnitTestRunner/Builds/MacOSX/UnitTestRunner.xcodeproj/project.pbxproj b/extras/UnitTestRunner/Builds/MacOSX/UnitTestRunner.xcodeproj/project.pbxproj index 5ac149dc..721ef81c 100644 --- a/extras/UnitTestRunner/Builds/MacOSX/UnitTestRunner.xcodeproj/project.pbxproj +++ b/extras/UnitTestRunner/Builds/MacOSX/UnitTestRunner.xcodeproj/project.pbxproj @@ -53,6 +53,10 @@ isa = PBXBuildFile; fileRef = B4202EE1243A8FCA29996D05; }; + EB8BBB7D2DBDB1092CE236E9 = { + isa = PBXBuildFile; + fileRef = D484C08AF83E4D2DFA030F1A; + }; 263250D6F359CE403B0566FF = { isa = PBXBuildFile; fileRef = 8C449538B266A891147103D6; @@ -475,13 +479,6 @@ path = "../../JuceLibraryCode/include_juce_product_unlocking.mm"; sourceTree = "SOURCE_ROOT"; }; - BDE2CEC1C2F9C0EA2FDEDEEC = { - isa = PBXFileReference; - lastKnownFileType = sourcecode.c.h; - name = AppConfig.h; - path = ../../JuceLibraryCode/AppConfig.h; - sourceTree = "SOURCE_ROOT"; - }; C0531453A002C480280C5F05 = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; @@ -510,6 +507,13 @@ path = "../../../../modules/juce_dsp"; sourceTree = "SOURCE_ROOT"; }; + D484C08AF83E4D2DFA030F1A = { + isa = PBXFileReference; + lastKnownFileType = wrapper.framework; + name = Foundation.framework; + path = System/Library/Frameworks/Foundation.framework; + sourceTree = SDKROOT; + }; D6F54293A21405C783852645 = { isa = PBXFileReference; lastKnownFileType = file; @@ -604,7 +608,6 @@ 3F7D4D52FAA229344338F40C = { isa = PBXGroup; children = ( - BDE2CEC1C2F9C0EA2FDEDEEC, 324682B2C8B9B4ACD9711A7A, 4BD792956FE7C22CB8FB691D, 00CDB93410EA5AECBA5ADA95, @@ -651,6 +654,7 @@ 8ED5AB2E4E106FB97C033C5B, 04C1B8BF62AA09E62B362913, B4202EE1243A8FCA29996D05, + D484C08AF83E4D2DFA030F1A, 8C449538B266A891147103D6, FCB76958E12B2D7F8277CD59, F260758DB97CF0F5C85218C1, @@ -695,6 +699,31 @@ GCC_PREPROCESSOR_DEFINITIONS = ( "_DEBUG=1", "DEBUG=1", + "JUCE_DISPLAY_SPLASH_SCREEN=0", + "JUCE_USE_DARK_SPLASH_SCREEN=1", + "JUCE_PROJUCER_VERSION=0x60005", + "JUCE_MODULE_AVAILABLE_juce_analytics=1", + "JUCE_MODULE_AVAILABLE_juce_audio_basics=1", + "JUCE_MODULE_AVAILABLE_juce_audio_devices=1", + "JUCE_MODULE_AVAILABLE_juce_audio_formats=1", + "JUCE_MODULE_AVAILABLE_juce_audio_processors=1", + "JUCE_MODULE_AVAILABLE_juce_audio_utils=1", + "JUCE_MODULE_AVAILABLE_juce_blocks_basics=1", + "JUCE_MODULE_AVAILABLE_juce_core=1", + "JUCE_MODULE_AVAILABLE_juce_cryptography=1", + "JUCE_MODULE_AVAILABLE_juce_data_structures=1", + "JUCE_MODULE_AVAILABLE_juce_dsp=1", + "JUCE_MODULE_AVAILABLE_juce_events=1", + "JUCE_MODULE_AVAILABLE_juce_graphics=1", + "JUCE_MODULE_AVAILABLE_juce_gui_basics=1", + "JUCE_MODULE_AVAILABLE_juce_gui_extra=1", + "JUCE_MODULE_AVAILABLE_juce_opengl=1", + "JUCE_MODULE_AVAILABLE_juce_osc=1", + "JUCE_MODULE_AVAILABLE_juce_product_unlocking=1", + "JUCE_MODULE_AVAILABLE_juce_video=1", + "JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1", + "JUCE_STRICT_REFCOUNTEDPOINTER=1", + "JUCE_STANDALONE_APPLICATION=1", "JUCE_UNIT_TESTS=1", "JUCER_XCODE_MAC_F6D2F4CF=1", "JUCE_APP_VERSION=1.0.0", @@ -716,10 +745,15 @@ ); INSTALL_PATH = "/usr/bin"; MACOSX_DEPLOYMENT_TARGET = 10.10; - OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow-all -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wunreachable-code -Wzero-as-null-pointer-constant -Wcast-align -Winconsistent-missing-destructor-override -Wshift-sign-overflow -Wnullable-to-nonnull-conversion -Wno-missing-field-initializers -Wno-ignored-qualifiers"; - PRODUCT_BUNDLE_IDENTIFIER = com.roli.UnitTestRunner; + MTL_HEADER_SEARCH_PATHS = ( + "../../JuceLibraryCode", + "../../../../modules", + ); + OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow-all -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wunreachable-code -Wzero-as-null-pointer-constant -Wcast-align -Winconsistent-missing-destructor-override -Wshift-sign-overflow -Wnullable-to-nonnull-conversion -Wno-missing-field-initializers -Wno-ignored-qualifiers -Wswitch-enum"; + PRODUCT_BUNDLE_IDENTIFIER = com.juce.UnitTestRunner; PRODUCT_NAME = "UnitTestRunner"; USE_HEADERMAP = NO; + VALID_ARCHS = "i386 x86_64 arm64 arm64e"; }; name = Debug; }; @@ -738,6 +772,31 @@ GCC_PREPROCESSOR_DEFINITIONS = ( "_NDEBUG=1", "NDEBUG=1", + "JUCE_DISPLAY_SPLASH_SCREEN=0", + "JUCE_USE_DARK_SPLASH_SCREEN=1", + "JUCE_PROJUCER_VERSION=0x60005", + "JUCE_MODULE_AVAILABLE_juce_analytics=1", + "JUCE_MODULE_AVAILABLE_juce_audio_basics=1", + "JUCE_MODULE_AVAILABLE_juce_audio_devices=1", + "JUCE_MODULE_AVAILABLE_juce_audio_formats=1", + "JUCE_MODULE_AVAILABLE_juce_audio_processors=1", + "JUCE_MODULE_AVAILABLE_juce_audio_utils=1", + "JUCE_MODULE_AVAILABLE_juce_blocks_basics=1", + "JUCE_MODULE_AVAILABLE_juce_core=1", + "JUCE_MODULE_AVAILABLE_juce_cryptography=1", + "JUCE_MODULE_AVAILABLE_juce_data_structures=1", + "JUCE_MODULE_AVAILABLE_juce_dsp=1", + "JUCE_MODULE_AVAILABLE_juce_events=1", + "JUCE_MODULE_AVAILABLE_juce_graphics=1", + "JUCE_MODULE_AVAILABLE_juce_gui_basics=1", + "JUCE_MODULE_AVAILABLE_juce_gui_extra=1", + "JUCE_MODULE_AVAILABLE_juce_opengl=1", + "JUCE_MODULE_AVAILABLE_juce_osc=1", + "JUCE_MODULE_AVAILABLE_juce_product_unlocking=1", + "JUCE_MODULE_AVAILABLE_juce_video=1", + "JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1", + "JUCE_STRICT_REFCOUNTEDPOINTER=1", + "JUCE_STANDALONE_APPLICATION=1", "JUCE_UNIT_TESTS=1", "JUCER_XCODE_MAC_F6D2F4CF=1", "JUCE_APP_VERSION=1.0.0", @@ -751,7 +810,6 @@ "JucePlugin_Build_Standalone=0", "JucePlugin_Build_Unity=0", ); - GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; HEADER_SEARCH_PATHS = ( "../../JuceLibraryCode", @@ -761,10 +819,15 @@ INSTALL_PATH = "/usr/bin"; LLVM_LTO = YES; MACOSX_DEPLOYMENT_TARGET = 10.10; - OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow-all -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wunreachable-code -Wzero-as-null-pointer-constant -Wcast-align -Winconsistent-missing-destructor-override -Wshift-sign-overflow -Wnullable-to-nonnull-conversion -Wno-missing-field-initializers -Wno-ignored-qualifiers"; - PRODUCT_BUNDLE_IDENTIFIER = com.roli.UnitTestRunner; + MTL_HEADER_SEARCH_PATHS = ( + "../../JuceLibraryCode", + "../../../../modules", + ); + OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow-all -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wunreachable-code -Wzero-as-null-pointer-constant -Wcast-align -Winconsistent-missing-destructor-override -Wshift-sign-overflow -Wnullable-to-nonnull-conversion -Wno-missing-field-initializers -Wno-ignored-qualifiers -Wswitch-enum"; + PRODUCT_BUNDLE_IDENTIFIER = com.juce.UnitTestRunner; PRODUCT_NAME = "UnitTestRunner"; USE_HEADERMAP = NO; + VALID_ARCHS = "i386 x86_64 arm64 arm64e"; }; name = Release; }; @@ -793,11 +856,12 @@ CODE_SIGN_IDENTITY = ""; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; + ENABLE_TESTABILITY = NO; GCC_C_LANGUAGE_STANDARD = c11; GCC_INLINES_ARE_PRIVATE_EXTERN = YES; GCC_MODEL_TUNING = G5; GCC_NO_COMMON_BLOCKS = YES; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; @@ -841,10 +905,12 @@ CODE_SIGN_IDENTITY = ""; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = NO; GCC_C_LANGUAGE_STANDARD = c11; GCC_INLINES_ARE_PRIVATE_EXTERN = YES; GCC_MODEL_TUNING = G5; GCC_NO_COMMON_BLOCKS = YES; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; @@ -862,10 +928,6 @@ }; name = Release; }; - E65171E718EA0C7E237860FA = { - isa = PBXTargetDependency; - target = B0D62ED1051EE9DFD49F6321; - }; 18FC121B1014F7999CD135D3 = { isa = XCConfigurationList; buildConfigurations = ( @@ -934,6 +996,7 @@ 0C1B9B95BC99382C313BEABC, 8D51903C59161885903F60CC, 32010EA67EEFE024B9CE1CB5, + EB8BBB7D2DBDB1092CE236E9, 263250D6F359CE403B0566FF, 17A09B4AF453B148CD7349F4, 1A038A2954FB9A4F208BE3F2, @@ -959,7 +1022,7 @@ E1E93F2B4B2D17E011395520 = { isa = PBXProject; buildConfigurationList = 18FC121B1014F7999CD135D3; - attributes = { LastUpgradeCheck = 1100; ORGANIZATIONNAME = "ROLI Ltd."; }; + attributes = { LastUpgradeCheck = 1200; ORGANIZATIONNAME = "Raw Material Software Limited"; }; compatibilityVersion = "Xcode 3.2"; hasScannedForEncodings = 0; mainGroup = 99F3717D3FEAFDCA3C22E868; diff --git a/extras/UnitTestRunner/Builds/MacOSX/UnitTestRunner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/extras/UnitTestRunner/Builds/MacOSX/UnitTestRunner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings index 949b6789..f2e3cbe8 100644 --- a/extras/UnitTestRunner/Builds/MacOSX/UnitTestRunner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ b/extras/UnitTestRunner/Builds/MacOSX/UnitTestRunner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -4,5 +4,7 @@ <dict> <key>BuildSystemType</key> <string>Original</string> + <key>DisableBuildSystemDeprecationWarning</key> + <true/> </dict> </plist> diff --git a/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj index a6ada508..cb48740e 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj +++ b/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj @@ -64,10 +64,10 @@ <Optimization>Disabled</Optimization> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_CONSOLE;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCE_UNIT_TESTS=1;JUCER_VS2017_78A5024=1;JUCE_APP_VERSION=1.0.0;JUCE_APP_VERSION_HEX=0x10000;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_CONSOLE;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCE_DISPLAY_SPLASH_SCREEN=0;JUCE_USE_DARK_SPLASH_SCREEN=1;JUCE_PROJUCER_VERSION=0x60005;JUCE_MODULE_AVAILABLE_juce_analytics=1;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_audio_formats=1;JUCE_MODULE_AVAILABLE_juce_audio_processors=1;JUCE_MODULE_AVAILABLE_juce_audio_utils=1;JUCE_MODULE_AVAILABLE_juce_blocks_basics=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_dsp=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_MODULE_AVAILABLE_juce_opengl=1;JUCE_MODULE_AVAILABLE_juce_osc=1;JUCE_MODULE_AVAILABLE_juce_product_unlocking=1;JUCE_MODULE_AVAILABLE_juce_video=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_STRICT_REFCOUNTEDPOINTER=1;JUCE_STANDALONE_APPLICATION=1;JUCE_UNIT_TESTS=1;JUCER_VS2017_78A5024=1;JUCE_APP_VERSION=1.0.0;JUCE_APP_VERSION_HEX=0x10000;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> <RuntimeTypeInfo>true</RuntimeTypeInfo> - <PrecompiledHeader/> + <PrecompiledHeader>NotUsing</PrecompiledHeader> <AssemblerListingLocation>$(IntDir)\</AssemblerListingLocation> <ObjectFileName>$(IntDir)\</ObjectFileName> <ProgramDataBaseFileName>$(IntDir)\</ProgramDataBaseFileName> @@ -107,10 +107,10 @@ <ClCompile> <Optimization>Full</Optimization> <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_CONSOLE;WIN32;_WINDOWS;NDEBUG;JUCE_UNIT_TESTS=1;JUCER_VS2017_78A5024=1;JUCE_APP_VERSION=1.0.0;JUCE_APP_VERSION_HEX=0x10000;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_CONSOLE;WIN32;_WINDOWS;NDEBUG;JUCE_DISPLAY_SPLASH_SCREEN=0;JUCE_USE_DARK_SPLASH_SCREEN=1;JUCE_PROJUCER_VERSION=0x60005;JUCE_MODULE_AVAILABLE_juce_analytics=1;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_audio_formats=1;JUCE_MODULE_AVAILABLE_juce_audio_processors=1;JUCE_MODULE_AVAILABLE_juce_audio_utils=1;JUCE_MODULE_AVAILABLE_juce_blocks_basics=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_dsp=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_MODULE_AVAILABLE_juce_opengl=1;JUCE_MODULE_AVAILABLE_juce_osc=1;JUCE_MODULE_AVAILABLE_juce_product_unlocking=1;JUCE_MODULE_AVAILABLE_juce_video=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_STRICT_REFCOUNTEDPOINTER=1;JUCE_STANDALONE_APPLICATION=1;JUCE_UNIT_TESTS=1;JUCER_VS2017_78A5024=1;JUCE_APP_VERSION=1.0.0;JUCE_APP_VERSION_HEX=0x10000;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> <RuntimeTypeInfo>true</RuntimeTypeInfo> - <PrecompiledHeader/> + <PrecompiledHeader>NotUsing</PrecompiledHeader> <AssemblerListingLocation>$(IntDir)\</AssemblerListingLocation> <ObjectFileName>$(IntDir)\</ObjectFileName> <ProgramDataBaseFileName>$(IntDir)\</ProgramDataBaseFileName> @@ -134,6 +134,7 @@ <OptimizeReferences>true</OptimizeReferences> <EnableCOMDATFolding>true</EnableCOMDATFolding> <LargeAddressAware>true</LargeAddressAware> + <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> </Link> <Bscmake> <SuppressStartupBanner>true</SuppressStartupBanner> @@ -239,10 +240,10 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_basics\synthesisers\juce_Synthesiser.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_CatmullRomInterpolator.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Interpolators.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_LagrangeInterpolator.cpp"> @@ -251,6 +252,9 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_SmoothedValue.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_WindowedSincInterpolator.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_basics\juce_audio_basics.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -269,6 +273,153 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_devices\midi_io\juce_MidiMessageCollector.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AAudioLoader.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AudioStreamAAudio.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioSourceCaller.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioStream.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioStreamBuilder.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\DataConversionFlowGraph.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FilterAudioStream.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockAdapter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockReader.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockWriter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\LatencyTuner.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\QuirksManager.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceFloatCaller.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceI16Caller.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\StabilizedCallback.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Trace.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Utilities.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Version.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoBuffer.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoController.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerBase.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerIndirect.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\IntegerRatio.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\LinearResampler.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\MultiChannelResampler.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResampler.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerMono.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerStereo.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResampler.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResamplerStereo.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ClipToRange.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\FlowGraphNode.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ManyToMultiConverter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\MonoToMultiConverter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\RampLinear.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SampleRateConverter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkFloat.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI16.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI24.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceFloat.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI16.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI24.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioInputStreamOpenSLES.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioOutputStreamOpenSLES.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamBuffered.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamOpenSLES.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\EngineOpenSLES.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OpenSLESUtilities.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OutputMixerOpenSLES.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_android_Audio.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -368,70 +519,73 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\libFLAC\window_flac.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\analysis.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\analysis.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\bitrate.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\bitrate.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\block.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\block.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codebook.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codebook.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\envelope.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\envelope.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\floor0.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\floor0.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\floor1.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\floor1.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\info.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\info.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lpc.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lpc.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lsp.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lsp.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mapping0.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mapping0.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mdct.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mdct.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\psy.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\misc.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\registry.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\psy.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\res0.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\registry.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\sharedbook.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\res0.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\smallft.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\sharedbook.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\synthesis.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\smallft.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\vorbisenc.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\synthesis.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\vorbisfile.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\vorbisenc.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\window.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\vorbisfile.c"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\window.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\bitwise.c"> @@ -626,6 +780,9 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioProcessorValueTreeState.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_ParameterAttachments.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_RangedAudioParameter.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -782,6 +939,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_FileSearchPath.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -809,6 +969,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_MemoryBlock.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -1088,6 +1251,9 @@ <ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_AudioBlock_test.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_FixedSizeFunction_test.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_SIMDRegister_test.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -1097,6 +1263,9 @@ <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_Convolution.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_Convolution_test.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_FFT.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -1130,21 +1299,60 @@ <ClCompile Include="..\..\..\..\modules\juce_dsp\native\juce_sse_SIMDNativeOps.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_BallisticsFilter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_DelayLine.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_DryWetMixer.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_FIRFilter.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_FIRFilter_test.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_FirstOrderTPTFilter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_IIRFilter.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_LadderFilter.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_LinkwitzRileyFilter.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_Oversampling.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_Panner.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessorChain_test.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_StateVariableTPTFilter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_Chorus.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_Compressor.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_LadderFilter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_Limiter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_NoiseGate.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_Phaser.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_dsp\juce_dsp.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -1757,6 +1965,15 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_MouseListener.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_DragAndDrop.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_android_ContentSharer.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -1775,13 +1992,7 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_FileChooser.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.cpp"> - <ExcludedFromBuild>true</ExcludedFromBuild> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Clipboard.cpp"> - <ExcludedFromBuild>true</ExcludedFromBuild> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Windowing.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_Windowing.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_win32_DragAndDrop.cpp"> @@ -1985,6 +2196,9 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_ActiveXComponent.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_HWNDComponent.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_SystemTrayIcon.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -2141,10 +2355,10 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_basics\sources\juce_ToneGeneratorAudioSource.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\synthesisers\juce_Synthesiser.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_ADSR.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_CatmullRomInterpolator.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Decibels.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_GenericInterpolator.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_LagrangeInterpolator.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Interpolators.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Reverb.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_SmoothedValue.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\juce_audio_basics.h"/> @@ -2154,6 +2368,66 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_devices\audio_io\juce_SystemAudioVolume.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\midi_io\juce_MidiDevices.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\midi_io\juce_MidiMessageCollector.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStream.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamBase.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamBuilder.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamCallback.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Definitions.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\LatencyTuner.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Oboe.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\ResultWithValue.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\StabilizedCallback.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Utilities.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Version.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AAudioLoader.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AudioStreamAAudio.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioClock.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioSourceCaller.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\DataConversionFlowGraph.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FilterAudioStream.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockAdapter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockReader.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockWriter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\MonotonicCounter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\OboeDebug.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\QuirksManager.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceFloatCaller.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceI16Caller.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Trace.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoBuffer.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoController.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerBase.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerIndirect.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\HyperbolicCosineWindow.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\IntegerRatio.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\KaiserWindow.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\LinearResampler.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\MultiChannelResampler.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResampler.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerMono.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerStereo.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResampler.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResamplerStereo.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ClipToRange.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\FlowGraphNode.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ManyToMultiConverter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\MonoToMultiConverter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\RampLinear.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SampleRateConverter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkFloat.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI16.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI24.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceFloat.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI16.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI24.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioInputStreamOpenSLES.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioOutputStreamOpenSLES.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamBuffered.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamOpenSLES.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\EngineOpenSLES.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OpenSLESUtilities.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OutputMixerOpenSLES.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\juce_android_HighPerformanceAudioHelpers.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\juce_ios_Audio.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\juce_MidiDataConcatenator.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\sources\juce_AudioSourcePlayer.h"/> @@ -2191,50 +2465,51 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\stream_decoder.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\stream_encoder.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\win_utf8_io.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled\res_books_51.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled\res_books_stereo.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\floor\floor_books.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\uncoupled\res_books_uncoupled.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\floor_all.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_8.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_11.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_16.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_44.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_8.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_16.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44p51.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44u.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_8.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_11.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_16.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_22.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_32.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44p51.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44u.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_X.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\backends.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\bitrate.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codebook.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codec_internal.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\envelope.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\highlevel.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup_data.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lpc.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lsp.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\masking.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mdct.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\misc.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\os.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\psy.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\registry.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\scales.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\smallft.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\window.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled\res_books_51.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled\res_books_stereo.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\floor\floor_books.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\uncoupled\res_books_uncoupled.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\floor_all.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_8.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_11.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_16.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_44.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_8.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_16.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44p51.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44u.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_8.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_11.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_16.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_22.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_32.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44p51.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44u.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_X.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\backends.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\bitrate.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codebook.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codec_internal.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\envelope.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\highlevel.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup_data.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lpc.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lsp.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\masking.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mdct.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\misc.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\os.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\psy.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\registry.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\scales.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\smallft.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\window.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\codec.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\config_types.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\crctable.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\ogg.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\os_types.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\vorbisenc.h"/> @@ -2323,6 +2598,7 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst\vsteditcontroller.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst\vstparameters.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst\vstpresetfile.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_AU_Shared.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_AudioUnitPluginFormat.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LADSPAPluginFormat.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_VST3Common.h"/> @@ -2349,6 +2625,7 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioParameterInt.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioProcessorParameterWithID.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioProcessorValueTreeState.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_ParameterAttachments.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_RangedAudioParameter.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\juce_audio_processors.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_utils\audio_cd\juce_AudioCDBurner.h"/> @@ -2413,6 +2690,7 @@ <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_FileOutputStream.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_FileSearchPath.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_MemoryMappedFile.h"/> + <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_WildcardFileFilter.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\javascript\juce_Javascript.h"/> @@ -2426,6 +2704,7 @@ <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_Random.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_Range.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_StatisticsAccumulator.h"/> + <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_Atomic.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_ByteOrder.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_ContainerDeletePolicy.h"/> @@ -2468,6 +2747,7 @@ <ClInclude Include="..\..\..\..\modules\juce_core\streams\juce_SubregionStream.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\streams\juce_URLInputSource.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerSupport.h"/> + <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerWarnings.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_PlatformDefs.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_StandardHeader.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_SystemStats.h"/> @@ -2543,6 +2823,7 @@ <ClInclude Include="..\..\..\..\modules\juce_data_structures\values\juce_ValueWithDefault.h"/> <ClInclude Include="..\..\..\..\modules\juce_data_structures\juce_data_structures.h"/> <ClInclude Include="..\..\..\..\modules\juce_dsp\containers\juce_AudioBlock.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\containers\juce_FixedSizeFunction.h"/> <ClInclude Include="..\..\..\..\modules\juce_dsp\containers\juce_SIMDRegister.h"/> <ClInclude Include="..\..\..\..\modules\juce_dsp\containers\juce_SIMDRegister_Impl.h"/> <ClInclude Include="..\..\..\..\modules\juce_dsp\filter_design\juce_FilterDesign.h"/> @@ -2560,21 +2841,33 @@ <ClInclude Include="..\..\..\..\modules\juce_dsp\native\juce_fallback_SIMDNativeOps.h"/> <ClInclude Include="..\..\..\..\modules\juce_dsp\native\juce_neon_SIMDNativeOps.h"/> <ClInclude Include="..\..\..\..\modules\juce_dsp\native\juce_sse_SIMDNativeOps.h"/> - <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_Bias.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_BallisticsFilter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_DelayLine.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_DryWetMixer.h"/> <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_FIRFilter.h"/> - <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_Gain.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_FirstOrderTPTFilter.h"/> <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_IIRFilter.h"/> <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_IIRFilter_Impl.h"/> - <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_LadderFilter.h"/> - <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_Oscillator.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_LinkwitzRileyFilter.h"/> <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_Oversampling.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_Panner.h"/> <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessContext.h"/> <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessorChain.h"/> <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessorDuplicator.h"/> <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessorWrapper.h"/> - <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_Reverb.h"/> <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_StateVariableFilter.h"/> - <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_WaveShaper.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_StateVariableTPTFilter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Bias.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Chorus.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Compressor.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Gain.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_LadderFilter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Limiter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_NoiseGate.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Oscillator.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Phaser.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Reverb.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_WaveShaper.h"/> <ClInclude Include="..\..\..\..\modules\juce_dsp\juce_dsp.h"/> <ClInclude Include="..\..\..\..\modules\juce_events\broadcasters\juce_ActionBroadcaster.h"/> <ClInclude Include="..\..\..\..\modules\juce_events\broadcasters\juce_ActionListener.h"/> @@ -2758,7 +3051,8 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_SelectedItemSet.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_TextDragAndDropTarget.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_TooltipClient.h"/> - <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.h"/> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.h"/> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_MultiTouchMapper.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\positioning\juce_MarkerList.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\positioning\juce_RelativeCoordinate.h"/> @@ -2810,6 +3104,7 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ActiveXControlComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"/> + <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_HWNDComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_NSViewComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ScopedDPIAwarenessDisabler.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_UIViewComponent.h"/> @@ -2875,11 +3170,13 @@ <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_win32_Video.h"/> <ClInclude Include="..\..\..\..\modules\juce_video\playback\juce_VideoComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_video\juce_video.h"/> - <ClInclude Include="..\..\JuceLibraryCode\AppConfig.h"/> <ClInclude Include="..\..\JuceLibraryCode\JuceHeader.h"/> </ItemGroup> <ItemGroup> + <None Include="..\..\..\..\modules\juce_audio_devices\native\oboe\CMakeLists.txt"/> + <None Include="..\..\..\..\modules\juce_audio_devices\native\oboe\readme.md"/> <None Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\Flac Licence.txt"/> + <None Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\README.md"/> <None Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\Ogg Vorbis Licence.txt"/> <None Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\base\LICENSE.txt"/> <None Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\base\README.md"/> diff --git a/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj.filters index e7fc4f99..9c9ed055 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj.filters +++ b/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj.filters @@ -50,6 +50,36 @@ <Filter Include="JUCE Modules\juce_audio_devices\midi_io"> <UniqueIdentifier>{092EFC17-7C95-7E04-0ACA-0D61A462EE81}</UniqueIdentifier> </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\include\oboe"> + <UniqueIdentifier>{285118C6-8FDA-7DCE-BEF4-FFB2120876C5}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\include"> + <UniqueIdentifier>{69ED6B61-9B8D-D47E-E4A6-2E9F9A94A75A}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\aaudio"> + <UniqueIdentifier>{7CDB7CD1-BB96-F593-3C78-1E06182B5839}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\common"> + <UniqueIdentifier>{B0A708DE-B4CF-196B-14FB-DC8221509B8E}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\fifo"> + <UniqueIdentifier>{34F46ADE-EE31-227A-A69E-7732E70145F1}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler"> + <UniqueIdentifier>{BB9B3C77-17FB-E994-8B75-88F1727E4655}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph"> + <UniqueIdentifier>{C0971D77-2F14-190A-E2AE-89D6285F4D5A}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\opensles"> + <UniqueIdentifier>{AABEA333-6524-8891-51C7-6DAEB5700628}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src"> + <UniqueIdentifier>{F2D29337-983E-BAD7-7B5C-E0AB3D53D404}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe"> + <UniqueIdentifier>{C674B0FB-1FC0-2986-94B1-083845018994}</UniqueIdentifier> + </Filter> <Filter Include="JUCE Modules\juce_audio_devices\native"> <UniqueIdentifier>{0AFC1CE8-F6E6-9817-8C21-8432B2A375DA}</UniqueIdentifier> </Filter> @@ -74,26 +104,26 @@ <Filter Include="JUCE Modules\juce_audio_formats\codecs\flac"> <UniqueIdentifier>{9EB3EC7F-2AB7-DDAA-3C05-DF382B728D3F}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled"> - <UniqueIdentifier>{02D37B85-7DE2-C8E7-A274-A5A0FBE99D69}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled"> + <UniqueIdentifier>{6B9FBFDC-1D10-6246-356D-00FF4535CECB}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\floor"> - <UniqueIdentifier>{DAF3BAAF-5207-4C34-61B9-A97DDC930D50}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\floor"> + <UniqueIdentifier>{D6FCFC8E-7136-9109-78C0-91A3EB4C443F}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\uncoupled"> - <UniqueIdentifier>{C7885588-8436-4C21-DC1E-58879BF53BDC}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\uncoupled"> + <UniqueIdentifier>{EBF18AC1-F0ED-937A-2824-4307CE2ADAF7}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books"> - <UniqueIdentifier>{E4ECEA39-0EFF-2443-91B3-1E5DA7AD5AE4}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books"> + <UniqueIdentifier>{5A0F7922-2EFB-6465-57E4-A445B804EFB5}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes"> - <UniqueIdentifier>{210B8D25-68E0-32C3-1449-6A40F109C5E9}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes"> + <UniqueIdentifier>{4EC45416-0E7C-7567-6F75-D0C8CEE7DC4F}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib"> - <UniqueIdentifier>{378AD911-E8E4-D230-E76B-34542849509D}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib"> + <UniqueIdentifier>{C2985031-0496-55B5-41A8-BAB99E53D89D}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2"> - <UniqueIdentifier>{F6CED5B6-0A8C-56D2-C1AC-DED6BE774A13}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7"> + <UniqueIdentifier>{FB4AB426-7009-0036-BB75-E34256AA7C89}</UniqueIdentifier> </Filter> <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis"> <UniqueIdentifier>{E684D858-09E8-0251-8E86-5657129641E1}</UniqueIdentifier> @@ -308,6 +338,9 @@ <Filter Include="JUCE Modules\juce_dsp\processors"> <UniqueIdentifier>{DDF4BA73-8578-406D-21F8-06B9BC70BFEA}</UniqueIdentifier> </Filter> + <Filter Include="JUCE Modules\juce_dsp\widgets"> + <UniqueIdentifier>{73374573-0194-9A6E-461A-A81EEB511C26}</UniqueIdentifier> + </Filter> <Filter Include="JUCE Modules\juce_dsp"> <UniqueIdentifier>{5DD60D0E-B16A-0BED-EDC4-C56E6960CA9E}</UniqueIdentifier> </Filter> @@ -404,6 +437,9 @@ <Filter Include="JUCE Modules\juce_gui_basics\mouse"> <UniqueIdentifier>{FE3CB19C-EF43-5CF5-DAF0-09D4E43D0AB9}</UniqueIdentifier> </Filter> + <Filter Include="JUCE Modules\juce_gui_basics\native\x11"> + <UniqueIdentifier>{FE7E6CD5-C7A0-DB20-4E7E-D6E7F08C4578}</UniqueIdentifier> + </Filter> <Filter Include="JUCE Modules\juce_gui_basics\native"> <UniqueIdentifier>{895C2D33-E08D-B1BA-BB36-FC4CA65090C8}</UniqueIdentifier> </Filter> @@ -592,10 +628,10 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_basics\synthesisers\juce_Synthesiser.cpp"> <Filter>JUCE Modules\juce_audio_basics\synthesisers</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_CatmullRomInterpolator.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.cpp"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Interpolators.cpp"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_LagrangeInterpolator.cpp"> @@ -604,6 +640,9 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_SmoothedValue.cpp"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_WindowedSincInterpolator.cpp"> + <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_basics\juce_audio_basics.cpp"> <Filter>JUCE Modules\juce_audio_basics</Filter> </ClCompile> @@ -625,6 +664,153 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_devices\midi_io\juce_MidiMessageCollector.cpp"> <Filter>JUCE Modules\juce_audio_devices\midi_io</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AAudioLoader.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\aaudio</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AudioStreamAAudio.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\aaudio</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioSourceCaller.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioStream.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioStreamBuilder.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\DataConversionFlowGraph.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FilterAudioStream.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockAdapter.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockReader.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockWriter.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\LatencyTuner.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\QuirksManager.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceFloatCaller.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceI16Caller.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\StabilizedCallback.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Trace.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Utilities.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Version.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoBuffer.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoController.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerBase.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerIndirect.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\IntegerRatio.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\LinearResampler.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\MultiChannelResampler.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResampler.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerMono.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerStereo.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResampler.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResamplerStereo.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ClipToRange.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\FlowGraphNode.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ManyToMultiConverter.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\MonoToMultiConverter.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\RampLinear.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SampleRateConverter.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkFloat.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI16.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI24.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceFloat.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI16.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI24.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioInputStreamOpenSLES.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioOutputStreamOpenSLES.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamBuffered.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamOpenSLES.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\EngineOpenSLES.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OpenSLESUtilities.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OutputMixerOpenSLES.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_android_Audio.cpp"> <Filter>JUCE Modules\juce_audio_devices\native</Filter> </ClCompile> @@ -727,71 +913,74 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\libFLAC\window_flac.c"> <Filter>JUCE Modules\juce_audio_formats\codecs\flac\libFLAC</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\analysis.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\analysis.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\bitrate.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\bitrate.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\block.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\block.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codebook.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codebook.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\envelope.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\envelope.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\floor0.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\floor0.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\floor1.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\floor1.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\info.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\info.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lpc.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lpc.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lsp.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lsp.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mapping0.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mapping0.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mdct.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mdct.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\misc.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\psy.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\psy.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\registry.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\registry.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\res0.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\res0.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\sharedbook.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\sharedbook.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\smallft.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\smallft.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\synthesis.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\synthesis.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\vorbisenc.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\vorbisenc.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\vorbisfile.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\vorbisfile.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\window.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\window.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\bitwise.c"> <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> @@ -991,6 +1180,9 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioProcessorValueTreeState.cpp"> <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_ParameterAttachments.cpp"> + <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_RangedAudioParameter.cpp"> <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> </ClCompile> @@ -1165,6 +1357,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_FileSearchPath.cpp"> <Filter>JUCE Modules\juce_core\files</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.cpp"> + <Filter>JUCE Modules\juce_core\files</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.cpp"> <Filter>JUCE Modules\juce_core\files</Filter> </ClCompile> @@ -1192,6 +1387,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> <Filter>JUCE Modules\juce_core\maths</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.cpp"> + <Filter>JUCE Modules\juce_core\memory</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_MemoryBlock.cpp"> <Filter>JUCE Modules\juce_core\memory</Filter> </ClCompile> @@ -1495,6 +1693,9 @@ <ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_AudioBlock_test.cpp"> <Filter>JUCE Modules\juce_dsp\containers</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_FixedSizeFunction_test.cpp"> + <Filter>JUCE Modules\juce_dsp\containers</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_SIMDRegister_test.cpp"> <Filter>JUCE Modules\juce_dsp\containers</Filter> </ClCompile> @@ -1504,6 +1705,9 @@ <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_Convolution.cpp"> <Filter>JUCE Modules\juce_dsp\frequency</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_Convolution_test.cpp"> + <Filter>JUCE Modules\juce_dsp\frequency</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_FFT.cpp"> <Filter>JUCE Modules\juce_dsp\frequency</Filter> </ClCompile> @@ -1537,21 +1741,60 @@ <ClCompile Include="..\..\..\..\modules\juce_dsp\native\juce_sse_SIMDNativeOps.cpp"> <Filter>JUCE Modules\juce_dsp\native</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_BallisticsFilter.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_DelayLine.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_DryWetMixer.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_FIRFilter.cpp"> <Filter>JUCE Modules\juce_dsp\processors</Filter> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_FIRFilter_test.cpp"> <Filter>JUCE Modules\juce_dsp\processors</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_FirstOrderTPTFilter.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_IIRFilter.cpp"> <Filter>JUCE Modules\juce_dsp\processors</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_LadderFilter.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_LinkwitzRileyFilter.cpp"> <Filter>JUCE Modules\juce_dsp\processors</Filter> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_Oversampling.cpp"> <Filter>JUCE Modules\juce_dsp\processors</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_Panner.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessorChain_test.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_StateVariableTPTFilter.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_Chorus.cpp"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_Compressor.cpp"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_LadderFilter.cpp"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_Limiter.cpp"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_NoiseGate.cpp"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_Phaser.cpp"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_dsp\juce_dsp.cpp"> <Filter>JUCE Modules\juce_dsp</Filter> </ClCompile> @@ -2185,6 +2428,15 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_MouseListener.cpp"> <Filter>JUCE Modules\juce_gui_basics\mouse</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_DragAndDrop.cpp"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.cpp"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.cpp"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_android_ContentSharer.cpp"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> </ClCompile> @@ -2212,13 +2464,7 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_FileChooser.cpp"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.cpp"> - <Filter>JUCE Modules\juce_gui_basics\native</Filter> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Clipboard.cpp"> - <Filter>JUCE Modules\juce_gui_basics\native</Filter> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Windowing.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_Windowing.cpp"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_mac_FileChooser.mm"> @@ -2452,6 +2698,9 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_ActiveXComponent.cpp"> <Filter>JUCE Modules\juce_gui_extra\native</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_HWNDComponent.cpp"> + <Filter>JUCE Modules\juce_gui_extra\native</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_SystemTrayIcon.cpp"> <Filter>JUCE Modules\juce_gui_extra\native</Filter> </ClCompile> @@ -2736,16 +2985,16 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_ADSR.h"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_CatmullRomInterpolator.h"> + <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Decibels.h"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Decibels.h"> + <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_GenericInterpolator.h"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.h"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_LagrangeInterpolator.h"> + <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Interpolators.h"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Reverb.h"> @@ -2775,6 +3024,186 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_devices\midi_io\juce_MidiMessageCollector.h"> <Filter>JUCE Modules\juce_audio_devices\midi_io</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStream.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamBase.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamBuilder.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamCallback.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Definitions.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\LatencyTuner.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Oboe.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\ResultWithValue.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\StabilizedCallback.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Utilities.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Version.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AAudioLoader.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\aaudio</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AudioStreamAAudio.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\aaudio</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioClock.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioSourceCaller.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\DataConversionFlowGraph.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FilterAudioStream.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockAdapter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockReader.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockWriter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\MonotonicCounter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\OboeDebug.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\QuirksManager.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceFloatCaller.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceI16Caller.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Trace.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoBuffer.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoController.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerBase.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerIndirect.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\HyperbolicCosineWindow.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\IntegerRatio.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\KaiserWindow.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\LinearResampler.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\MultiChannelResampler.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResampler.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerMono.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerStereo.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResampler.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResamplerStereo.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ClipToRange.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\FlowGraphNode.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ManyToMultiConverter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\MonoToMultiConverter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\RampLinear.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SampleRateConverter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkFloat.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI16.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI24.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceFloat.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI16.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI24.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioInputStreamOpenSLES.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioOutputStreamOpenSLES.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamBuffered.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamOpenSLES.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\EngineOpenSLES.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OpenSLESUtilities.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OutputMixerOpenSLES.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\juce_android_HighPerformanceAudioHelpers.h"> + <Filter>JUCE Modules\juce_audio_devices\native</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\juce_ios_Audio.h"> <Filter>JUCE Modules\juce_audio_devices\native</Filter> </ClInclude> @@ -2886,131 +3315,131 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\win_utf8_io.h"> <Filter>JUCE Modules\juce_audio_formats\codecs\flac</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled\res_books_51.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled\res_books_51.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled\res_books_stereo.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled\res_books_stereo.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\floor\floor_books.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\floor</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\floor\floor_books.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\floor</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\uncoupled\res_books_uncoupled.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\uncoupled</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\uncoupled\res_books_uncoupled.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\uncoupled</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\floor_all.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\floor_all.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_8.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_8.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_11.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_11.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_16.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_16.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_44.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_44.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_8.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_8.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_16.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_16.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44p51.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44p51.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44u.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44u.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_8.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_8.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_11.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_11.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_16.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_16.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_22.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_22.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_32.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_32.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44p51.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44p51.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44u.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44u.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_X.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_X.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\backends.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\backends.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\bitrate.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\bitrate.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codebook.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codebook.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codec_internal.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codec_internal.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\envelope.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\envelope.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\highlevel.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\highlevel.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup_data.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup_data.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lpc.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lpc.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lsp.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lsp.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\masking.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\masking.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mdct.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mdct.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\misc.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\misc.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\os.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\os.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\psy.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\psy.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\registry.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\registry.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\scales.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\scales.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\smallft.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\smallft.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\window.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\window.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\codec.h"> <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> @@ -3018,6 +3447,9 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\config_types.h"> <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\crctable.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\ogg.h"> <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> </ClInclude> @@ -3282,6 +3714,9 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst\vstpresetfile.h"> <Filter>JUCE Modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_AU_Shared.h"> + <Filter>JUCE Modules\juce_audio_processors\format_types</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_AudioUnitPluginFormat.h"> <Filter>JUCE Modules\juce_audio_processors\format_types</Filter> </ClInclude> @@ -3360,6 +3795,9 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioProcessorValueTreeState.h"> <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_ParameterAttachments.h"> + <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_RangedAudioParameter.h"> <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> </ClInclude> @@ -3552,6 +3990,9 @@ <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_MemoryMappedFile.h"> <Filter>JUCE Modules\juce_core\files</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.h"> + <Filter>JUCE Modules\juce_core\files</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.h"> <Filter>JUCE Modules\juce_core\files</Filter> </ClInclude> @@ -3591,6 +4032,9 @@ <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_StatisticsAccumulator.h"> <Filter>JUCE Modules\juce_core\maths</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.h"> + <Filter>JUCE Modules\juce_core\memory</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_Atomic.h"> <Filter>JUCE Modules\juce_core\memory</Filter> </ClInclude> @@ -3717,6 +4161,9 @@ <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerSupport.h"> <Filter>JUCE Modules\juce_core\system</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerWarnings.h"> + <Filter>JUCE Modules\juce_core\system</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_PlatformDefs.h"> <Filter>JUCE Modules\juce_core\system</Filter> </ClInclude> @@ -3942,6 +4389,9 @@ <ClInclude Include="..\..\..\..\modules\juce_dsp\containers\juce_AudioBlock.h"> <Filter>JUCE Modules\juce_dsp\containers</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\containers\juce_FixedSizeFunction.h"> + <Filter>JUCE Modules\juce_dsp\containers</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_dsp\containers\juce_SIMDRegister.h"> <Filter>JUCE Modules\juce_dsp\containers</Filter> </ClInclude> @@ -3993,13 +4443,19 @@ <ClInclude Include="..\..\..\..\modules\juce_dsp\native\juce_sse_SIMDNativeOps.h"> <Filter>JUCE Modules\juce_dsp\native</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_Bias.h"> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_BallisticsFilter.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_DelayLine.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_DryWetMixer.h"> <Filter>JUCE Modules\juce_dsp\processors</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_FIRFilter.h"> <Filter>JUCE Modules\juce_dsp\processors</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_Gain.h"> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_FirstOrderTPTFilter.h"> <Filter>JUCE Modules\juce_dsp\processors</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_IIRFilter.h"> @@ -4008,13 +4464,13 @@ <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_IIRFilter_Impl.h"> <Filter>JUCE Modules\juce_dsp\processors</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_LadderFilter.h"> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_LinkwitzRileyFilter.h"> <Filter>JUCE Modules\juce_dsp\processors</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_Oscillator.h"> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_Oversampling.h"> <Filter>JUCE Modules\juce_dsp\processors</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_Oversampling.h"> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_Panner.h"> <Filter>JUCE Modules\juce_dsp\processors</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessContext.h"> @@ -4029,15 +4485,45 @@ <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessorWrapper.h"> <Filter>JUCE Modules\juce_dsp\processors</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_Reverb.h"> - <Filter>JUCE Modules\juce_dsp\processors</Filter> - </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_StateVariableFilter.h"> <Filter>JUCE Modules\juce_dsp\processors</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_WaveShaper.h"> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_StateVariableTPTFilter.h"> <Filter>JUCE Modules\juce_dsp\processors</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Bias.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Chorus.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Compressor.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Gain.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_LadderFilter.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Limiter.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_NoiseGate.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Oscillator.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Phaser.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Reverb.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_WaveShaper.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_dsp\juce_dsp.h"> <Filter>JUCE Modules\juce_dsp</Filter> </ClInclude> @@ -4587,8 +5073,11 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_TooltipClient.h"> <Filter>JUCE Modules\juce_gui_basics\mouse</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.h"> - <Filter>JUCE Modules\juce_gui_basics\native</Filter> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.h"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.h"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_MultiTouchMapper.h"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> @@ -4743,6 +5232,9 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"> <Filter>JUCE Modules\juce_gui_extra\embedding</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_HWNDComponent.h"> + <Filter>JUCE Modules\juce_gui_extra\embedding</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_NSViewComponent.h"> <Filter>JUCE Modules\juce_gui_extra\embedding</Filter> </ClInclude> @@ -4938,17 +5430,23 @@ <ClInclude Include="..\..\..\..\modules\juce_video\juce_video.h"> <Filter>JUCE Modules\juce_video</Filter> </ClInclude> - <ClInclude Include="..\..\JuceLibraryCode\AppConfig.h"> - <Filter>JUCE Library Code</Filter> - </ClInclude> <ClInclude Include="..\..\JuceLibraryCode\JuceHeader.h"> <Filter>JUCE Library Code</Filter> </ClInclude> </ItemGroup> <ItemGroup> + <None Include="..\..\..\..\modules\juce_audio_devices\native\oboe\CMakeLists.txt"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe</Filter> + </None> + <None Include="..\..\..\..\modules\juce_audio_devices\native\oboe\readme.md"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe</Filter> + </None> <None Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\Flac Licence.txt"> <Filter>JUCE Modules\juce_audio_formats\codecs\flac</Filter> </None> + <None Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\README.md"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7</Filter> + </None> <None Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\Ogg Vorbis Licence.txt"> <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> </None> diff --git a/extras/UnitTestRunner/Builds/VisualStudio2017/resources.rc b/extras/UnitTestRunner/Builds/VisualStudio2017/resources.rc index 3874e39c..6bd2e42e 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2017/resources.rc +++ b/extras/UnitTestRunner/Builds/VisualStudio2017/resources.rc @@ -1,3 +1,5 @@ +#pragma code_page(65001) + #ifdef JUCE_USER_DEFINED_RC_FILE #include JUCE_USER_DEFINED_RC_FILE #else @@ -13,8 +15,8 @@ BEGIN BEGIN BLOCK "040904E4" BEGIN - VALUE "CompanyName", "ROLI Ltd.\0" - VALUE "LegalCopyright", "ROLI Ltd.\0" + VALUE "CompanyName", "Raw Material Software Limited\0" + VALUE "LegalCopyright", "Raw Material Software Limited\0" VALUE "FileDescription", "UnitTestRunner\0" VALUE "FileVersion", "1.0.0\0" VALUE "ProductName", "UnitTestRunner\0" diff --git a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj index 9da5d1f4..b41f71e3 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj +++ b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj @@ -64,10 +64,10 @@ <Optimization>Disabled</Optimization> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_CONSOLE;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCE_UNIT_TESTS=1;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=1.0.0;JUCE_APP_VERSION_HEX=0x10000;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_CONSOLE;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCE_DISPLAY_SPLASH_SCREEN=0;JUCE_USE_DARK_SPLASH_SCREEN=1;JUCE_PROJUCER_VERSION=0x60005;JUCE_MODULE_AVAILABLE_juce_analytics=1;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_audio_formats=1;JUCE_MODULE_AVAILABLE_juce_audio_processors=1;JUCE_MODULE_AVAILABLE_juce_audio_utils=1;JUCE_MODULE_AVAILABLE_juce_blocks_basics=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_dsp=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_MODULE_AVAILABLE_juce_opengl=1;JUCE_MODULE_AVAILABLE_juce_osc=1;JUCE_MODULE_AVAILABLE_juce_product_unlocking=1;JUCE_MODULE_AVAILABLE_juce_video=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_STRICT_REFCOUNTEDPOINTER=1;JUCE_STANDALONE_APPLICATION=1;JUCE_UNIT_TESTS=1;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=1.0.0;JUCE_APP_VERSION_HEX=0x10000;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> <RuntimeTypeInfo>true</RuntimeTypeInfo> - <PrecompiledHeader/> + <PrecompiledHeader>NotUsing</PrecompiledHeader> <AssemblerListingLocation>$(IntDir)\</AssemblerListingLocation> <ObjectFileName>$(IntDir)\</ObjectFileName> <ProgramDataBaseFileName>$(IntDir)\</ProgramDataBaseFileName> @@ -107,10 +107,10 @@ <ClCompile> <Optimization>Full</Optimization> <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_CONSOLE;WIN32;_WINDOWS;NDEBUG;JUCE_UNIT_TESTS=1;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=1.0.0;JUCE_APP_VERSION_HEX=0x10000;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_CONSOLE;WIN32;_WINDOWS;NDEBUG;JUCE_DISPLAY_SPLASH_SCREEN=0;JUCE_USE_DARK_SPLASH_SCREEN=1;JUCE_PROJUCER_VERSION=0x60005;JUCE_MODULE_AVAILABLE_juce_analytics=1;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_audio_formats=1;JUCE_MODULE_AVAILABLE_juce_audio_processors=1;JUCE_MODULE_AVAILABLE_juce_audio_utils=1;JUCE_MODULE_AVAILABLE_juce_blocks_basics=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_dsp=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_MODULE_AVAILABLE_juce_opengl=1;JUCE_MODULE_AVAILABLE_juce_osc=1;JUCE_MODULE_AVAILABLE_juce_product_unlocking=1;JUCE_MODULE_AVAILABLE_juce_video=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_STRICT_REFCOUNTEDPOINTER=1;JUCE_STANDALONE_APPLICATION=1;JUCE_UNIT_TESTS=1;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=1.0.0;JUCE_APP_VERSION_HEX=0x10000;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> <RuntimeTypeInfo>true</RuntimeTypeInfo> - <PrecompiledHeader/> + <PrecompiledHeader>NotUsing</PrecompiledHeader> <AssemblerListingLocation>$(IntDir)\</AssemblerListingLocation> <ObjectFileName>$(IntDir)\</ObjectFileName> <ProgramDataBaseFileName>$(IntDir)\</ProgramDataBaseFileName> @@ -134,6 +134,7 @@ <OptimizeReferences>true</OptimizeReferences> <EnableCOMDATFolding>true</EnableCOMDATFolding> <LargeAddressAware>true</LargeAddressAware> + <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> </Link> <Bscmake> <SuppressStartupBanner>true</SuppressStartupBanner> @@ -239,10 +240,10 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_basics\synthesisers\juce_Synthesiser.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_CatmullRomInterpolator.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Interpolators.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_LagrangeInterpolator.cpp"> @@ -251,6 +252,9 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_SmoothedValue.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_WindowedSincInterpolator.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_basics\juce_audio_basics.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -269,6 +273,153 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_devices\midi_io\juce_MidiMessageCollector.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AAudioLoader.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AudioStreamAAudio.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioSourceCaller.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioStream.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioStreamBuilder.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\DataConversionFlowGraph.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FilterAudioStream.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockAdapter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockReader.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockWriter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\LatencyTuner.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\QuirksManager.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceFloatCaller.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceI16Caller.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\StabilizedCallback.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Trace.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Utilities.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Version.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoBuffer.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoController.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerBase.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerIndirect.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\IntegerRatio.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\LinearResampler.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\MultiChannelResampler.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResampler.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerMono.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerStereo.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResampler.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResamplerStereo.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ClipToRange.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\FlowGraphNode.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ManyToMultiConverter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\MonoToMultiConverter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\RampLinear.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SampleRateConverter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkFloat.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI16.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI24.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceFloat.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI16.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI24.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioInputStreamOpenSLES.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioOutputStreamOpenSLES.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamBuffered.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamOpenSLES.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\EngineOpenSLES.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OpenSLESUtilities.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OutputMixerOpenSLES.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_android_Audio.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -368,70 +519,73 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\libFLAC\window_flac.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\analysis.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\analysis.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\bitrate.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\bitrate.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\block.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\block.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codebook.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codebook.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\envelope.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\envelope.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\floor0.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\floor0.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\floor1.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\floor1.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\info.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\info.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lpc.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lpc.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lsp.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lsp.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mapping0.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mapping0.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mdct.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mdct.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\psy.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\misc.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\registry.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\psy.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\res0.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\registry.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\sharedbook.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\res0.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\smallft.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\sharedbook.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\synthesis.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\smallft.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\vorbisenc.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\synthesis.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\vorbisfile.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\vorbisenc.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\window.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\vorbisfile.c"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\window.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\bitwise.c"> @@ -626,6 +780,9 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioProcessorValueTreeState.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_ParameterAttachments.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_RangedAudioParameter.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -782,6 +939,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_FileSearchPath.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -809,6 +969,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_MemoryBlock.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -1088,6 +1251,9 @@ <ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_AudioBlock_test.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_FixedSizeFunction_test.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_SIMDRegister_test.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -1097,6 +1263,9 @@ <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_Convolution.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_Convolution_test.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_FFT.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -1130,21 +1299,60 @@ <ClCompile Include="..\..\..\..\modules\juce_dsp\native\juce_sse_SIMDNativeOps.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_BallisticsFilter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_DelayLine.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_DryWetMixer.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_FIRFilter.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_FIRFilter_test.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_FirstOrderTPTFilter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_IIRFilter.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_LadderFilter.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_LinkwitzRileyFilter.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_Oversampling.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_Panner.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessorChain_test.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_StateVariableTPTFilter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_Chorus.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_Compressor.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_LadderFilter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_Limiter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_NoiseGate.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_Phaser.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_dsp\juce_dsp.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -1757,6 +1965,15 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_MouseListener.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_DragAndDrop.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_android_ContentSharer.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -1775,13 +1992,7 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_FileChooser.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.cpp"> - <ExcludedFromBuild>true</ExcludedFromBuild> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Clipboard.cpp"> - <ExcludedFromBuild>true</ExcludedFromBuild> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Windowing.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_Windowing.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_win32_DragAndDrop.cpp"> @@ -1985,6 +2196,9 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_ActiveXComponent.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_HWNDComponent.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_SystemTrayIcon.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -2141,10 +2355,10 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_basics\sources\juce_ToneGeneratorAudioSource.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\synthesisers\juce_Synthesiser.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_ADSR.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_CatmullRomInterpolator.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Decibels.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_GenericInterpolator.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_LagrangeInterpolator.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Interpolators.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Reverb.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_SmoothedValue.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\juce_audio_basics.h"/> @@ -2154,6 +2368,66 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_devices\audio_io\juce_SystemAudioVolume.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\midi_io\juce_MidiDevices.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\midi_io\juce_MidiMessageCollector.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStream.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamBase.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamBuilder.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamCallback.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Definitions.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\LatencyTuner.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Oboe.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\ResultWithValue.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\StabilizedCallback.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Utilities.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Version.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AAudioLoader.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AudioStreamAAudio.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioClock.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioSourceCaller.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\DataConversionFlowGraph.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FilterAudioStream.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockAdapter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockReader.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockWriter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\MonotonicCounter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\OboeDebug.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\QuirksManager.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceFloatCaller.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceI16Caller.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Trace.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoBuffer.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoController.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerBase.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerIndirect.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\HyperbolicCosineWindow.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\IntegerRatio.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\KaiserWindow.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\LinearResampler.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\MultiChannelResampler.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResampler.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerMono.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerStereo.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResampler.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResamplerStereo.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ClipToRange.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\FlowGraphNode.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ManyToMultiConverter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\MonoToMultiConverter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\RampLinear.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SampleRateConverter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkFloat.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI16.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI24.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceFloat.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI16.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI24.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioInputStreamOpenSLES.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioOutputStreamOpenSLES.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamBuffered.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamOpenSLES.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\EngineOpenSLES.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OpenSLESUtilities.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OutputMixerOpenSLES.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\juce_android_HighPerformanceAudioHelpers.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\juce_ios_Audio.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\juce_MidiDataConcatenator.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\sources\juce_AudioSourcePlayer.h"/> @@ -2191,50 +2465,51 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\stream_decoder.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\stream_encoder.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\win_utf8_io.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled\res_books_51.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled\res_books_stereo.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\floor\floor_books.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\uncoupled\res_books_uncoupled.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\floor_all.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_8.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_11.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_16.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_44.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_8.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_16.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44p51.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44u.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_8.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_11.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_16.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_22.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_32.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44p51.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44u.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_X.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\backends.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\bitrate.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codebook.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codec_internal.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\envelope.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\highlevel.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup_data.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lpc.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lsp.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\masking.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mdct.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\misc.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\os.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\psy.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\registry.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\scales.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\smallft.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\window.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled\res_books_51.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled\res_books_stereo.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\floor\floor_books.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\uncoupled\res_books_uncoupled.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\floor_all.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_8.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_11.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_16.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_44.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_8.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_16.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44p51.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44u.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_8.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_11.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_16.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_22.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_32.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44p51.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44u.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_X.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\backends.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\bitrate.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codebook.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codec_internal.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\envelope.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\highlevel.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup_data.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lpc.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lsp.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\masking.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mdct.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\misc.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\os.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\psy.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\registry.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\scales.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\smallft.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\window.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\codec.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\config_types.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\crctable.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\ogg.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\os_types.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\vorbisenc.h"/> @@ -2323,6 +2598,7 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst\vsteditcontroller.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst\vstparameters.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst\vstpresetfile.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_AU_Shared.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_AudioUnitPluginFormat.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LADSPAPluginFormat.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_VST3Common.h"/> @@ -2349,6 +2625,7 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioParameterInt.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioProcessorParameterWithID.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioProcessorValueTreeState.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_ParameterAttachments.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_RangedAudioParameter.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\juce_audio_processors.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_utils\audio_cd\juce_AudioCDBurner.h"/> @@ -2413,6 +2690,7 @@ <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_FileOutputStream.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_FileSearchPath.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_MemoryMappedFile.h"/> + <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_WildcardFileFilter.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\javascript\juce_Javascript.h"/> @@ -2426,6 +2704,7 @@ <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_Random.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_Range.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_StatisticsAccumulator.h"/> + <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_Atomic.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_ByteOrder.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_ContainerDeletePolicy.h"/> @@ -2468,6 +2747,7 @@ <ClInclude Include="..\..\..\..\modules\juce_core\streams\juce_SubregionStream.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\streams\juce_URLInputSource.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerSupport.h"/> + <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerWarnings.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_PlatformDefs.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_StandardHeader.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_SystemStats.h"/> @@ -2543,6 +2823,7 @@ <ClInclude Include="..\..\..\..\modules\juce_data_structures\values\juce_ValueWithDefault.h"/> <ClInclude Include="..\..\..\..\modules\juce_data_structures\juce_data_structures.h"/> <ClInclude Include="..\..\..\..\modules\juce_dsp\containers\juce_AudioBlock.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\containers\juce_FixedSizeFunction.h"/> <ClInclude Include="..\..\..\..\modules\juce_dsp\containers\juce_SIMDRegister.h"/> <ClInclude Include="..\..\..\..\modules\juce_dsp\containers\juce_SIMDRegister_Impl.h"/> <ClInclude Include="..\..\..\..\modules\juce_dsp\filter_design\juce_FilterDesign.h"/> @@ -2560,21 +2841,33 @@ <ClInclude Include="..\..\..\..\modules\juce_dsp\native\juce_fallback_SIMDNativeOps.h"/> <ClInclude Include="..\..\..\..\modules\juce_dsp\native\juce_neon_SIMDNativeOps.h"/> <ClInclude Include="..\..\..\..\modules\juce_dsp\native\juce_sse_SIMDNativeOps.h"/> - <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_Bias.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_BallisticsFilter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_DelayLine.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_DryWetMixer.h"/> <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_FIRFilter.h"/> - <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_Gain.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_FirstOrderTPTFilter.h"/> <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_IIRFilter.h"/> <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_IIRFilter_Impl.h"/> - <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_LadderFilter.h"/> - <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_Oscillator.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_LinkwitzRileyFilter.h"/> <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_Oversampling.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_Panner.h"/> <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessContext.h"/> <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessorChain.h"/> <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessorDuplicator.h"/> <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessorWrapper.h"/> - <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_Reverb.h"/> <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_StateVariableFilter.h"/> - <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_WaveShaper.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_StateVariableTPTFilter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Bias.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Chorus.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Compressor.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Gain.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_LadderFilter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Limiter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_NoiseGate.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Oscillator.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Phaser.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Reverb.h"/> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_WaveShaper.h"/> <ClInclude Include="..\..\..\..\modules\juce_dsp\juce_dsp.h"/> <ClInclude Include="..\..\..\..\modules\juce_events\broadcasters\juce_ActionBroadcaster.h"/> <ClInclude Include="..\..\..\..\modules\juce_events\broadcasters\juce_ActionListener.h"/> @@ -2758,7 +3051,8 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_SelectedItemSet.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_TextDragAndDropTarget.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_TooltipClient.h"/> - <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.h"/> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.h"/> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_MultiTouchMapper.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\positioning\juce_MarkerList.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\positioning\juce_RelativeCoordinate.h"/> @@ -2810,6 +3104,7 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ActiveXControlComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"/> + <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_HWNDComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_NSViewComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ScopedDPIAwarenessDisabler.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_UIViewComponent.h"/> @@ -2875,11 +3170,13 @@ <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_win32_Video.h"/> <ClInclude Include="..\..\..\..\modules\juce_video\playback\juce_VideoComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_video\juce_video.h"/> - <ClInclude Include="..\..\JuceLibraryCode\AppConfig.h"/> <ClInclude Include="..\..\JuceLibraryCode\JuceHeader.h"/> </ItemGroup> <ItemGroup> + <None Include="..\..\..\..\modules\juce_audio_devices\native\oboe\CMakeLists.txt"/> + <None Include="..\..\..\..\modules\juce_audio_devices\native\oboe\readme.md"/> <None Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\Flac Licence.txt"/> + <None Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\README.md"/> <None Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\Ogg Vorbis Licence.txt"/> <None Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\base\LICENSE.txt"/> <None Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\base\README.md"/> diff --git a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters index 968333e7..bd6ce4f9 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters +++ b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters @@ -50,6 +50,36 @@ <Filter Include="JUCE Modules\juce_audio_devices\midi_io"> <UniqueIdentifier>{092EFC17-7C95-7E04-0ACA-0D61A462EE81}</UniqueIdentifier> </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\include\oboe"> + <UniqueIdentifier>{285118C6-8FDA-7DCE-BEF4-FFB2120876C5}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\include"> + <UniqueIdentifier>{69ED6B61-9B8D-D47E-E4A6-2E9F9A94A75A}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\aaudio"> + <UniqueIdentifier>{7CDB7CD1-BB96-F593-3C78-1E06182B5839}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\common"> + <UniqueIdentifier>{B0A708DE-B4CF-196B-14FB-DC8221509B8E}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\fifo"> + <UniqueIdentifier>{34F46ADE-EE31-227A-A69E-7732E70145F1}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler"> + <UniqueIdentifier>{BB9B3C77-17FB-E994-8B75-88F1727E4655}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph"> + <UniqueIdentifier>{C0971D77-2F14-190A-E2AE-89D6285F4D5A}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\opensles"> + <UniqueIdentifier>{AABEA333-6524-8891-51C7-6DAEB5700628}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src"> + <UniqueIdentifier>{F2D29337-983E-BAD7-7B5C-E0AB3D53D404}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe"> + <UniqueIdentifier>{C674B0FB-1FC0-2986-94B1-083845018994}</UniqueIdentifier> + </Filter> <Filter Include="JUCE Modules\juce_audio_devices\native"> <UniqueIdentifier>{0AFC1CE8-F6E6-9817-8C21-8432B2A375DA}</UniqueIdentifier> </Filter> @@ -74,26 +104,26 @@ <Filter Include="JUCE Modules\juce_audio_formats\codecs\flac"> <UniqueIdentifier>{9EB3EC7F-2AB7-DDAA-3C05-DF382B728D3F}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled"> - <UniqueIdentifier>{02D37B85-7DE2-C8E7-A274-A5A0FBE99D69}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled"> + <UniqueIdentifier>{6B9FBFDC-1D10-6246-356D-00FF4535CECB}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\floor"> - <UniqueIdentifier>{DAF3BAAF-5207-4C34-61B9-A97DDC930D50}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\floor"> + <UniqueIdentifier>{D6FCFC8E-7136-9109-78C0-91A3EB4C443F}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\uncoupled"> - <UniqueIdentifier>{C7885588-8436-4C21-DC1E-58879BF53BDC}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\uncoupled"> + <UniqueIdentifier>{EBF18AC1-F0ED-937A-2824-4307CE2ADAF7}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books"> - <UniqueIdentifier>{E4ECEA39-0EFF-2443-91B3-1E5DA7AD5AE4}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books"> + <UniqueIdentifier>{5A0F7922-2EFB-6465-57E4-A445B804EFB5}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes"> - <UniqueIdentifier>{210B8D25-68E0-32C3-1449-6A40F109C5E9}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes"> + <UniqueIdentifier>{4EC45416-0E7C-7567-6F75-D0C8CEE7DC4F}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib"> - <UniqueIdentifier>{378AD911-E8E4-D230-E76B-34542849509D}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib"> + <UniqueIdentifier>{C2985031-0496-55B5-41A8-BAB99E53D89D}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2"> - <UniqueIdentifier>{F6CED5B6-0A8C-56D2-C1AC-DED6BE774A13}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7"> + <UniqueIdentifier>{FB4AB426-7009-0036-BB75-E34256AA7C89}</UniqueIdentifier> </Filter> <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis"> <UniqueIdentifier>{E684D858-09E8-0251-8E86-5657129641E1}</UniqueIdentifier> @@ -308,6 +338,9 @@ <Filter Include="JUCE Modules\juce_dsp\processors"> <UniqueIdentifier>{DDF4BA73-8578-406D-21F8-06B9BC70BFEA}</UniqueIdentifier> </Filter> + <Filter Include="JUCE Modules\juce_dsp\widgets"> + <UniqueIdentifier>{73374573-0194-9A6E-461A-A81EEB511C26}</UniqueIdentifier> + </Filter> <Filter Include="JUCE Modules\juce_dsp"> <UniqueIdentifier>{5DD60D0E-B16A-0BED-EDC4-C56E6960CA9E}</UniqueIdentifier> </Filter> @@ -404,6 +437,9 @@ <Filter Include="JUCE Modules\juce_gui_basics\mouse"> <UniqueIdentifier>{FE3CB19C-EF43-5CF5-DAF0-09D4E43D0AB9}</UniqueIdentifier> </Filter> + <Filter Include="JUCE Modules\juce_gui_basics\native\x11"> + <UniqueIdentifier>{FE7E6CD5-C7A0-DB20-4E7E-D6E7F08C4578}</UniqueIdentifier> + </Filter> <Filter Include="JUCE Modules\juce_gui_basics\native"> <UniqueIdentifier>{895C2D33-E08D-B1BA-BB36-FC4CA65090C8}</UniqueIdentifier> </Filter> @@ -592,10 +628,10 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_basics\synthesisers\juce_Synthesiser.cpp"> <Filter>JUCE Modules\juce_audio_basics\synthesisers</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_CatmullRomInterpolator.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.cpp"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Interpolators.cpp"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_LagrangeInterpolator.cpp"> @@ -604,6 +640,9 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_SmoothedValue.cpp"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_WindowedSincInterpolator.cpp"> + <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_basics\juce_audio_basics.cpp"> <Filter>JUCE Modules\juce_audio_basics</Filter> </ClCompile> @@ -625,6 +664,153 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_devices\midi_io\juce_MidiMessageCollector.cpp"> <Filter>JUCE Modules\juce_audio_devices\midi_io</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AAudioLoader.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\aaudio</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AudioStreamAAudio.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\aaudio</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioSourceCaller.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioStream.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioStreamBuilder.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\DataConversionFlowGraph.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FilterAudioStream.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockAdapter.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockReader.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockWriter.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\LatencyTuner.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\QuirksManager.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceFloatCaller.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceI16Caller.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\StabilizedCallback.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Trace.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Utilities.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Version.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoBuffer.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoController.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerBase.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerIndirect.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\IntegerRatio.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\LinearResampler.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\MultiChannelResampler.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResampler.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerMono.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerStereo.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResampler.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResamplerStereo.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ClipToRange.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\FlowGraphNode.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ManyToMultiConverter.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\MonoToMultiConverter.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\RampLinear.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SampleRateConverter.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkFloat.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI16.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI24.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceFloat.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI16.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI24.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioInputStreamOpenSLES.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioOutputStreamOpenSLES.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamBuffered.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamOpenSLES.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\EngineOpenSLES.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OpenSLESUtilities.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OutputMixerOpenSLES.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_android_Audio.cpp"> <Filter>JUCE Modules\juce_audio_devices\native</Filter> </ClCompile> @@ -727,71 +913,74 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\libFLAC\window_flac.c"> <Filter>JUCE Modules\juce_audio_formats\codecs\flac\libFLAC</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\analysis.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\analysis.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\bitrate.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\bitrate.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\block.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\block.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codebook.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codebook.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\envelope.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\envelope.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\floor0.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\floor0.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\floor1.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\floor1.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\info.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\info.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lpc.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lpc.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lsp.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lsp.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mapping0.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mapping0.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mdct.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mdct.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\misc.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\psy.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\psy.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\registry.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\registry.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\res0.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\res0.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\sharedbook.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\sharedbook.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\smallft.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\smallft.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\synthesis.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\synthesis.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\vorbisenc.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\vorbisenc.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\vorbisfile.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\vorbisfile.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\window.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\window.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\bitwise.c"> <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> @@ -991,6 +1180,9 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioProcessorValueTreeState.cpp"> <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_ParameterAttachments.cpp"> + <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_RangedAudioParameter.cpp"> <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> </ClCompile> @@ -1165,6 +1357,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_FileSearchPath.cpp"> <Filter>JUCE Modules\juce_core\files</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.cpp"> + <Filter>JUCE Modules\juce_core\files</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.cpp"> <Filter>JUCE Modules\juce_core\files</Filter> </ClCompile> @@ -1192,6 +1387,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> <Filter>JUCE Modules\juce_core\maths</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.cpp"> + <Filter>JUCE Modules\juce_core\memory</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_MemoryBlock.cpp"> <Filter>JUCE Modules\juce_core\memory</Filter> </ClCompile> @@ -1495,6 +1693,9 @@ <ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_AudioBlock_test.cpp"> <Filter>JUCE Modules\juce_dsp\containers</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_FixedSizeFunction_test.cpp"> + <Filter>JUCE Modules\juce_dsp\containers</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_dsp\containers\juce_SIMDRegister_test.cpp"> <Filter>JUCE Modules\juce_dsp\containers</Filter> </ClCompile> @@ -1504,6 +1705,9 @@ <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_Convolution.cpp"> <Filter>JUCE Modules\juce_dsp\frequency</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_Convolution_test.cpp"> + <Filter>JUCE Modules\juce_dsp\frequency</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_dsp\frequency\juce_FFT.cpp"> <Filter>JUCE Modules\juce_dsp\frequency</Filter> </ClCompile> @@ -1537,21 +1741,60 @@ <ClCompile Include="..\..\..\..\modules\juce_dsp\native\juce_sse_SIMDNativeOps.cpp"> <Filter>JUCE Modules\juce_dsp\native</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_BallisticsFilter.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_DelayLine.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_DryWetMixer.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_FIRFilter.cpp"> <Filter>JUCE Modules\juce_dsp\processors</Filter> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_FIRFilter_test.cpp"> <Filter>JUCE Modules\juce_dsp\processors</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_FirstOrderTPTFilter.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_IIRFilter.cpp"> <Filter>JUCE Modules\juce_dsp\processors</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_LadderFilter.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_LinkwitzRileyFilter.cpp"> <Filter>JUCE Modules\juce_dsp\processors</Filter> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_Oversampling.cpp"> <Filter>JUCE Modules\juce_dsp\processors</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_Panner.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessorChain_test.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\processors\juce_StateVariableTPTFilter.cpp"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_Chorus.cpp"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_Compressor.cpp"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_LadderFilter.cpp"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_Limiter.cpp"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_NoiseGate.cpp"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_dsp\widgets\juce_Phaser.cpp"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_dsp\juce_dsp.cpp"> <Filter>JUCE Modules\juce_dsp</Filter> </ClCompile> @@ -2185,6 +2428,15 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_MouseListener.cpp"> <Filter>JUCE Modules\juce_gui_basics\mouse</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_DragAndDrop.cpp"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.cpp"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.cpp"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_android_ContentSharer.cpp"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> </ClCompile> @@ -2212,13 +2464,7 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_FileChooser.cpp"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.cpp"> - <Filter>JUCE Modules\juce_gui_basics\native</Filter> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Clipboard.cpp"> - <Filter>JUCE Modules\juce_gui_basics\native</Filter> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Windowing.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_Windowing.cpp"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_mac_FileChooser.mm"> @@ -2452,6 +2698,9 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_ActiveXComponent.cpp"> <Filter>JUCE Modules\juce_gui_extra\native</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_HWNDComponent.cpp"> + <Filter>JUCE Modules\juce_gui_extra\native</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_SystemTrayIcon.cpp"> <Filter>JUCE Modules\juce_gui_extra\native</Filter> </ClCompile> @@ -2736,16 +2985,16 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_ADSR.h"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_CatmullRomInterpolator.h"> + <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Decibels.h"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Decibels.h"> + <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_GenericInterpolator.h"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.h"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_LagrangeInterpolator.h"> + <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Interpolators.h"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Reverb.h"> @@ -2775,6 +3024,186 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_devices\midi_io\juce_MidiMessageCollector.h"> <Filter>JUCE Modules\juce_audio_devices\midi_io</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStream.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamBase.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamBuilder.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamCallback.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Definitions.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\LatencyTuner.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Oboe.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\ResultWithValue.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\StabilizedCallback.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Utilities.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Version.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AAudioLoader.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\aaudio</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AudioStreamAAudio.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\aaudio</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioClock.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioSourceCaller.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\DataConversionFlowGraph.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FilterAudioStream.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockAdapter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockReader.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockWriter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\MonotonicCounter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\OboeDebug.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\QuirksManager.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceFloatCaller.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceI16Caller.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Trace.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoBuffer.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoController.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerBase.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerIndirect.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\HyperbolicCosineWindow.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\IntegerRatio.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\KaiserWindow.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\LinearResampler.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\MultiChannelResampler.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResampler.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerMono.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerStereo.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResampler.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResamplerStereo.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ClipToRange.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\FlowGraphNode.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ManyToMultiConverter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\MonoToMultiConverter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\RampLinear.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SampleRateConverter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkFloat.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI16.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI24.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceFloat.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI16.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI24.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioInputStreamOpenSLES.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioOutputStreamOpenSLES.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamBuffered.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamOpenSLES.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\EngineOpenSLES.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OpenSLESUtilities.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OutputMixerOpenSLES.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\juce_android_HighPerformanceAudioHelpers.h"> + <Filter>JUCE Modules\juce_audio_devices\native</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\juce_ios_Audio.h"> <Filter>JUCE Modules\juce_audio_devices\native</Filter> </ClInclude> @@ -2886,131 +3315,131 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\win_utf8_io.h"> <Filter>JUCE Modules\juce_audio_formats\codecs\flac</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled\res_books_51.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled\res_books_51.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled\res_books_stereo.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled\res_books_stereo.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\floor\floor_books.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\floor</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\floor\floor_books.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\floor</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\uncoupled\res_books_uncoupled.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\uncoupled</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\uncoupled\res_books_uncoupled.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\uncoupled</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\floor_all.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\floor_all.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_8.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_8.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_11.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_11.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_16.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_16.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_44.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_44.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_8.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_8.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_16.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_16.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44p51.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44p51.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44u.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44u.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_8.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_8.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_11.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_11.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_16.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_16.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_22.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_22.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_32.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_32.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44p51.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44p51.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44u.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44u.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_X.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_X.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\backends.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\backends.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\bitrate.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\bitrate.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codebook.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codebook.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codec_internal.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codec_internal.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\envelope.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\envelope.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\highlevel.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\highlevel.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup_data.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup_data.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lpc.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lpc.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lsp.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lsp.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\masking.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\masking.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mdct.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mdct.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\misc.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\misc.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\os.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\os.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\psy.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\psy.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\registry.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\registry.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\scales.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\scales.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\smallft.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\smallft.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\window.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\window.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\codec.h"> <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> @@ -3018,6 +3447,9 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\config_types.h"> <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\crctable.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\ogg.h"> <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> </ClInclude> @@ -3282,6 +3714,9 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst\vstpresetfile.h"> <Filter>JUCE Modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_AU_Shared.h"> + <Filter>JUCE Modules\juce_audio_processors\format_types</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_AudioUnitPluginFormat.h"> <Filter>JUCE Modules\juce_audio_processors\format_types</Filter> </ClInclude> @@ -3360,6 +3795,9 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioProcessorValueTreeState.h"> <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_ParameterAttachments.h"> + <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_RangedAudioParameter.h"> <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> </ClInclude> @@ -3552,6 +3990,9 @@ <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_MemoryMappedFile.h"> <Filter>JUCE Modules\juce_core\files</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.h"> + <Filter>JUCE Modules\juce_core\files</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.h"> <Filter>JUCE Modules\juce_core\files</Filter> </ClInclude> @@ -3591,6 +4032,9 @@ <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_StatisticsAccumulator.h"> <Filter>JUCE Modules\juce_core\maths</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.h"> + <Filter>JUCE Modules\juce_core\memory</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_Atomic.h"> <Filter>JUCE Modules\juce_core\memory</Filter> </ClInclude> @@ -3717,6 +4161,9 @@ <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerSupport.h"> <Filter>JUCE Modules\juce_core\system</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerWarnings.h"> + <Filter>JUCE Modules\juce_core\system</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_PlatformDefs.h"> <Filter>JUCE Modules\juce_core\system</Filter> </ClInclude> @@ -3942,6 +4389,9 @@ <ClInclude Include="..\..\..\..\modules\juce_dsp\containers\juce_AudioBlock.h"> <Filter>JUCE Modules\juce_dsp\containers</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\containers\juce_FixedSizeFunction.h"> + <Filter>JUCE Modules\juce_dsp\containers</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_dsp\containers\juce_SIMDRegister.h"> <Filter>JUCE Modules\juce_dsp\containers</Filter> </ClInclude> @@ -3993,13 +4443,19 @@ <ClInclude Include="..\..\..\..\modules\juce_dsp\native\juce_sse_SIMDNativeOps.h"> <Filter>JUCE Modules\juce_dsp\native</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_Bias.h"> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_BallisticsFilter.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_DelayLine.h"> + <Filter>JUCE Modules\juce_dsp\processors</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_DryWetMixer.h"> <Filter>JUCE Modules\juce_dsp\processors</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_FIRFilter.h"> <Filter>JUCE Modules\juce_dsp\processors</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_Gain.h"> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_FirstOrderTPTFilter.h"> <Filter>JUCE Modules\juce_dsp\processors</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_IIRFilter.h"> @@ -4008,13 +4464,13 @@ <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_IIRFilter_Impl.h"> <Filter>JUCE Modules\juce_dsp\processors</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_LadderFilter.h"> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_LinkwitzRileyFilter.h"> <Filter>JUCE Modules\juce_dsp\processors</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_Oscillator.h"> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_Oversampling.h"> <Filter>JUCE Modules\juce_dsp\processors</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_Oversampling.h"> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_Panner.h"> <Filter>JUCE Modules\juce_dsp\processors</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessContext.h"> @@ -4029,15 +4485,45 @@ <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_ProcessorWrapper.h"> <Filter>JUCE Modules\juce_dsp\processors</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_Reverb.h"> - <Filter>JUCE Modules\juce_dsp\processors</Filter> - </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_StateVariableFilter.h"> <Filter>JUCE Modules\juce_dsp\processors</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_WaveShaper.h"> + <ClInclude Include="..\..\..\..\modules\juce_dsp\processors\juce_StateVariableTPTFilter.h"> <Filter>JUCE Modules\juce_dsp\processors</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Bias.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Chorus.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Compressor.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Gain.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_LadderFilter.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Limiter.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_NoiseGate.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Oscillator.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Phaser.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_Reverb.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_dsp\widgets\juce_WaveShaper.h"> + <Filter>JUCE Modules\juce_dsp\widgets</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_dsp\juce_dsp.h"> <Filter>JUCE Modules\juce_dsp</Filter> </ClInclude> @@ -4587,8 +5073,11 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_TooltipClient.h"> <Filter>JUCE Modules\juce_gui_basics\mouse</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.h"> - <Filter>JUCE Modules\juce_gui_basics\native</Filter> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.h"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.h"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_MultiTouchMapper.h"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> @@ -4743,6 +5232,9 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"> <Filter>JUCE Modules\juce_gui_extra\embedding</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_HWNDComponent.h"> + <Filter>JUCE Modules\juce_gui_extra\embedding</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_NSViewComponent.h"> <Filter>JUCE Modules\juce_gui_extra\embedding</Filter> </ClInclude> @@ -4938,17 +5430,23 @@ <ClInclude Include="..\..\..\..\modules\juce_video\juce_video.h"> <Filter>JUCE Modules\juce_video</Filter> </ClInclude> - <ClInclude Include="..\..\JuceLibraryCode\AppConfig.h"> - <Filter>JUCE Library Code</Filter> - </ClInclude> <ClInclude Include="..\..\JuceLibraryCode\JuceHeader.h"> <Filter>JUCE Library Code</Filter> </ClInclude> </ItemGroup> <ItemGroup> + <None Include="..\..\..\..\modules\juce_audio_devices\native\oboe\CMakeLists.txt"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe</Filter> + </None> + <None Include="..\..\..\..\modules\juce_audio_devices\native\oboe\readme.md"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe</Filter> + </None> <None Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\Flac Licence.txt"> <Filter>JUCE Modules\juce_audio_formats\codecs\flac</Filter> </None> + <None Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\README.md"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7</Filter> + </None> <None Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\Ogg Vorbis Licence.txt"> <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> </None> diff --git a/extras/UnitTestRunner/Builds/VisualStudio2019/resources.rc b/extras/UnitTestRunner/Builds/VisualStudio2019/resources.rc index 3874e39c..6bd2e42e 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2019/resources.rc +++ b/extras/UnitTestRunner/Builds/VisualStudio2019/resources.rc @@ -1,3 +1,5 @@ +#pragma code_page(65001) + #ifdef JUCE_USER_DEFINED_RC_FILE #include JUCE_USER_DEFINED_RC_FILE #else @@ -13,8 +15,8 @@ BEGIN BEGIN BLOCK "040904E4" BEGIN - VALUE "CompanyName", "ROLI Ltd.\0" - VALUE "LegalCopyright", "ROLI Ltd.\0" + VALUE "CompanyName", "Raw Material Software Limited\0" + VALUE "LegalCopyright", "Raw Material Software Limited\0" VALUE "FileDescription", "UnitTestRunner\0" VALUE "FileVersion", "1.0.0\0" VALUE "ProductName", "UnitTestRunner\0" diff --git a/extras/UnitTestRunner/CMakeLists.txt b/extras/UnitTestRunner/CMakeLists.txt new file mode 100644 index 00000000..1c99f54d --- /dev/null +++ b/extras/UnitTestRunner/CMakeLists.txt @@ -0,0 +1,46 @@ +# ============================================================================== +# +# This file is part of the JUCE library. +# Copyright (c) 2020 - Raw Material Software Limited +# +# JUCE is an open source library subject to commercial or open-source +# licensing. +# +# By using JUCE, you agree to the terms of both the JUCE 6 End-User License +# Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). +# +# End User License Agreement: www.juce.com/juce-6-licence +# Privacy Policy: www.juce.com/juce-privacy-policy +# +# Or: You may also use this code under the terms of the GPL v3 (see +# www.gnu.org/licenses). +# +# JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER +# EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE +# DISCLAIMED. +# +# ============================================================================== + +juce_add_console_app(UnitTestRunner) + +juce_generate_juce_header(UnitTestRunner) + +target_sources(UnitTestRunner PRIVATE Source/Main.cpp) + +target_compile_definitions(UnitTestRunner PRIVATE + JUCE_UNIT_TESTS=1 + JUCE_USE_CURL=0 + JUCE_WEB_BROWSER=0) + +target_link_libraries(UnitTestRunner PRIVATE + juce::juce_analytics + juce::juce_audio_utils + juce::juce_blocks_basics + juce::juce_dsp + juce::juce_opengl + juce::juce_osc + juce::juce_product_unlocking + juce::juce_video + juce::juce_recommended_config_flags + juce::juce_recommended_lto_flags + juce::juce_recommended_warning_flags) diff --git a/extras/UnitTestRunner/JuceLibraryCode/AppConfig.h b/extras/UnitTestRunner/JuceLibraryCode/AppConfig.h deleted file mode 100644 index db8b0ac3..00000000 --- a/extras/UnitTestRunner/JuceLibraryCode/AppConfig.h +++ /dev/null @@ -1,323 +0,0 @@ -/* - - IMPORTANT! This file is auto-generated each time you save your - project - if you alter its contents, your changes may be overwritten! - - There's a section below where you can add your own custom code safely, and the - Projucer will preserve the contents of that block, but the best way to change - any of these definitions is by using the Projucer's project settings. - - Any commented-out settings will assume their default values. - -*/ - -#pragma once - -//============================================================================== -// [BEGIN_USER_CODE_SECTION] - -// (You can add your own code in this section, and the Projucer will not overwrite it) - -// [END_USER_CODE_SECTION] - -/* - ============================================================================== - - In accordance with the terms of the JUCE 5 End-Use License Agreement, the - JUCE Code in SECTION A cannot be removed, changed or otherwise rendered - ineffective unless you have a JUCE Indie or Pro license, or are using JUCE - under the GPL v3 license. - - End User License Agreement: www.juce.com/juce-5-licence - - ============================================================================== -*/ - -// BEGIN SECTION A - -#ifndef JUCE_DISPLAY_SPLASH_SCREEN - #define JUCE_DISPLAY_SPLASH_SCREEN 0 -#endif - -#ifndef JUCE_REPORT_APP_USAGE - #define JUCE_REPORT_APP_USAGE 0 -#endif - -// END SECTION A - -#define JUCE_USE_DARK_SPLASH_SCREEN 1 - -#define JUCE_PROJUCER_VERSION 0x50407 - -//============================================================================== -#define JUCE_MODULE_AVAILABLE_juce_analytics 1 -#define JUCE_MODULE_AVAILABLE_juce_audio_basics 1 -#define JUCE_MODULE_AVAILABLE_juce_audio_devices 1 -#define JUCE_MODULE_AVAILABLE_juce_audio_formats 1 -#define JUCE_MODULE_AVAILABLE_juce_audio_processors 1 -#define JUCE_MODULE_AVAILABLE_juce_audio_utils 1 -#define JUCE_MODULE_AVAILABLE_juce_blocks_basics 1 -#define JUCE_MODULE_AVAILABLE_juce_core 1 -#define JUCE_MODULE_AVAILABLE_juce_cryptography 1 -#define JUCE_MODULE_AVAILABLE_juce_data_structures 1 -#define JUCE_MODULE_AVAILABLE_juce_dsp 1 -#define JUCE_MODULE_AVAILABLE_juce_events 1 -#define JUCE_MODULE_AVAILABLE_juce_graphics 1 -#define JUCE_MODULE_AVAILABLE_juce_gui_basics 1 -#define JUCE_MODULE_AVAILABLE_juce_gui_extra 1 -#define JUCE_MODULE_AVAILABLE_juce_opengl 1 -#define JUCE_MODULE_AVAILABLE_juce_osc 1 -#define JUCE_MODULE_AVAILABLE_juce_product_unlocking 1 -#define JUCE_MODULE_AVAILABLE_juce_video 1 - -#define JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED 1 - -//============================================================================== -// juce_audio_devices flags: - -#ifndef JUCE_USE_WINRT_MIDI - //#define JUCE_USE_WINRT_MIDI 0 -#endif - -#ifndef JUCE_ASIO - //#define JUCE_ASIO 0 -#endif - -#ifndef JUCE_WASAPI - //#define JUCE_WASAPI 1 -#endif - -#ifndef JUCE_WASAPI_EXCLUSIVE - //#define JUCE_WASAPI_EXCLUSIVE 0 -#endif - -#ifndef JUCE_DIRECTSOUND - //#define JUCE_DIRECTSOUND 1 -#endif - -#ifndef JUCE_ALSA - //#define JUCE_ALSA 1 -#endif - -#ifndef JUCE_JACK - //#define JUCE_JACK 0 -#endif - -#ifndef JUCE_BELA - //#define JUCE_BELA 0 -#endif - -#ifndef JUCE_USE_ANDROID_OBOE - //#define JUCE_USE_ANDROID_OBOE 0 -#endif - -#ifndef JUCE_USE_ANDROID_OPENSLES - //#define JUCE_USE_ANDROID_OPENSLES 0 -#endif - -#ifndef JUCE_DISABLE_AUDIO_MIXING_WITH_OTHER_APPS - //#define JUCE_DISABLE_AUDIO_MIXING_WITH_OTHER_APPS 0 -#endif - -//============================================================================== -// juce_audio_formats flags: - -#ifndef JUCE_USE_FLAC - //#define JUCE_USE_FLAC 1 -#endif - -#ifndef JUCE_USE_OGGVORBIS - //#define JUCE_USE_OGGVORBIS 1 -#endif - -#ifndef JUCE_USE_MP3AUDIOFORMAT - //#define JUCE_USE_MP3AUDIOFORMAT 0 -#endif - -#ifndef JUCE_USE_LAME_AUDIO_FORMAT - //#define JUCE_USE_LAME_AUDIO_FORMAT 0 -#endif - -#ifndef JUCE_USE_WINDOWS_MEDIA_FORMAT - //#define JUCE_USE_WINDOWS_MEDIA_FORMAT 1 -#endif - -//============================================================================== -// juce_audio_processors flags: - -#ifndef JUCE_PLUGINHOST_VST - //#define JUCE_PLUGINHOST_VST 0 -#endif - -#ifndef JUCE_PLUGINHOST_VST3 - //#define JUCE_PLUGINHOST_VST3 0 -#endif - -#ifndef JUCE_PLUGINHOST_AU - //#define JUCE_PLUGINHOST_AU 0 -#endif - -#ifndef JUCE_PLUGINHOST_LADSPA - //#define JUCE_PLUGINHOST_LADSPA 0 -#endif - -//============================================================================== -// juce_audio_utils flags: - -#ifndef JUCE_USE_CDREADER - //#define JUCE_USE_CDREADER 0 -#endif - -#ifndef JUCE_USE_CDBURNER - //#define JUCE_USE_CDBURNER 0 -#endif - -//============================================================================== -// juce_core flags: - -#ifndef JUCE_FORCE_DEBUG - //#define JUCE_FORCE_DEBUG 0 -#endif - -#ifndef JUCE_LOG_ASSERTIONS - //#define JUCE_LOG_ASSERTIONS 0 -#endif - -#ifndef JUCE_CHECK_MEMORY_LEAKS - //#define JUCE_CHECK_MEMORY_LEAKS 1 -#endif - -#ifndef JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES - //#define JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES 0 -#endif - -#ifndef JUCE_INCLUDE_ZLIB_CODE - //#define JUCE_INCLUDE_ZLIB_CODE 1 -#endif - -#ifndef JUCE_USE_CURL - //#define JUCE_USE_CURL 1 -#endif - -#ifndef JUCE_LOAD_CURL_SYMBOLS_LAZILY - //#define JUCE_LOAD_CURL_SYMBOLS_LAZILY 0 -#endif - -#ifndef JUCE_CATCH_UNHANDLED_EXCEPTIONS - //#define JUCE_CATCH_UNHANDLED_EXCEPTIONS 0 -#endif - -#ifndef JUCE_ALLOW_STATIC_NULL_VARIABLES - //#define JUCE_ALLOW_STATIC_NULL_VARIABLES 0 -#endif - -#ifndef JUCE_STRICT_REFCOUNTEDPOINTER - #define JUCE_STRICT_REFCOUNTEDPOINTER 1 -#endif - -//============================================================================== -// juce_dsp flags: - -#ifndef JUCE_ASSERTION_FIRFILTER - //#define JUCE_ASSERTION_FIRFILTER 1 -#endif - -#ifndef JUCE_DSP_USE_INTEL_MKL - //#define JUCE_DSP_USE_INTEL_MKL 0 -#endif - -#ifndef JUCE_DSP_USE_SHARED_FFTW - //#define JUCE_DSP_USE_SHARED_FFTW 0 -#endif - -#ifndef JUCE_DSP_USE_STATIC_FFTW - //#define JUCE_DSP_USE_STATIC_FFTW 0 -#endif - -#ifndef JUCE_DSP_ENABLE_SNAP_TO_ZERO - //#define JUCE_DSP_ENABLE_SNAP_TO_ZERO 1 -#endif - -//============================================================================== -// juce_events flags: - -#ifndef JUCE_EXECUTE_APP_SUSPEND_ON_BACKGROUND_TASK - //#define JUCE_EXECUTE_APP_SUSPEND_ON_BACKGROUND_TASK 0 -#endif - -//============================================================================== -// juce_graphics flags: - -#ifndef JUCE_USE_COREIMAGE_LOADER - //#define JUCE_USE_COREIMAGE_LOADER 1 -#endif - -#ifndef JUCE_USE_DIRECTWRITE - //#define JUCE_USE_DIRECTWRITE 1 -#endif - -#ifndef JUCE_DISABLE_COREGRAPHICS_FONT_SMOOTHING - //#define JUCE_DISABLE_COREGRAPHICS_FONT_SMOOTHING 0 -#endif - -//============================================================================== -// juce_gui_basics flags: - -#ifndef JUCE_ENABLE_REPAINT_DEBUGGING - //#define JUCE_ENABLE_REPAINT_DEBUGGING 0 -#endif - -#ifndef JUCE_USE_XRANDR - //#define JUCE_USE_XRANDR 1 -#endif - -#ifndef JUCE_USE_XINERAMA - //#define JUCE_USE_XINERAMA 1 -#endif - -#ifndef JUCE_USE_XSHM - //#define JUCE_USE_XSHM 1 -#endif - -#ifndef JUCE_USE_XRENDER - //#define JUCE_USE_XRENDER 0 -#endif - -#ifndef JUCE_USE_XCURSOR - //#define JUCE_USE_XCURSOR 1 -#endif - -#ifndef JUCE_WIN_PER_MONITOR_DPI_AWARE - //#define JUCE_WIN_PER_MONITOR_DPI_AWARE 1 -#endif - -//============================================================================== -// juce_gui_extra flags: - -#ifndef JUCE_WEB_BROWSER - //#define JUCE_WEB_BROWSER 1 -#endif - -#ifndef JUCE_ENABLE_LIVE_CONSTANT_EDITOR - //#define JUCE_ENABLE_LIVE_CONSTANT_EDITOR 0 -#endif - -//============================================================================== -// juce_video flags: - -#ifndef JUCE_USE_CAMERA - //#define JUCE_USE_CAMERA 0 -#endif - -#ifndef JUCE_SYNC_VIDEO_VOLUME_WITH_OS_MEDIA_VOLUME - //#define JUCE_SYNC_VIDEO_VOLUME_WITH_OS_MEDIA_VOLUME 1 -#endif - -//============================================================================== -#ifndef JUCE_STANDALONE_APPLICATION - #if defined(JucePlugin_Name) && defined(JucePlugin_Build_Standalone) - #define JUCE_STANDALONE_APPLICATION JucePlugin_Build_Standalone - #else - #define JUCE_STANDALONE_APPLICATION 1 - #endif -#endif diff --git a/extras/UnitTestRunner/JuceLibraryCode/JuceHeader.h b/extras/UnitTestRunner/JuceLibraryCode/JuceHeader.h index 1b016eba..a2b23ab4 100644 --- a/extras/UnitTestRunner/JuceLibraryCode/JuceHeader.h +++ b/extras/UnitTestRunner/JuceLibraryCode/JuceHeader.h @@ -12,7 +12,6 @@ #pragma once -#include "AppConfig.h" #include <juce_analytics/juce_analytics.h> #include <juce_audio_basics/juce_audio_basics.h> @@ -54,7 +53,7 @@ namespace ProjectInfo { const char* const projectName = "UnitTestRunner"; - const char* const companyName = "ROLI Ltd."; + const char* const companyName = "Raw Material Software Limited"; const char* const versionString = "1.0.0"; const int versionNumber = 0x10000; } diff --git a/extras/UnitTestRunner/JuceLibraryCode/include_juce_analytics.cpp b/extras/UnitTestRunner/JuceLibraryCode/include_juce_analytics.cpp index 3dfd4d21..cda0f939 100644 --- a/extras/UnitTestRunner/JuceLibraryCode/include_juce_analytics.cpp +++ b/extras/UnitTestRunner/JuceLibraryCode/include_juce_analytics.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_analytics/juce_analytics.cpp> diff --git a/extras/UnitTestRunner/JuceLibraryCode/include_juce_audio_basics.cpp b/extras/UnitTestRunner/JuceLibraryCode/include_juce_audio_basics.cpp index 41869487..e5c3ae92 100644 --- a/extras/UnitTestRunner/JuceLibraryCode/include_juce_audio_basics.cpp +++ b/extras/UnitTestRunner/JuceLibraryCode/include_juce_audio_basics.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_basics/juce_audio_basics.cpp> diff --git a/extras/UnitTestRunner/JuceLibraryCode/include_juce_audio_basics.mm b/extras/UnitTestRunner/JuceLibraryCode/include_juce_audio_basics.mm index e0e6c577..c7f36c64 100644 --- a/extras/UnitTestRunner/JuceLibraryCode/include_juce_audio_basics.mm +++ b/extras/UnitTestRunner/JuceLibraryCode/include_juce_audio_basics.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_basics/juce_audio_basics.mm> diff --git a/extras/UnitTestRunner/JuceLibraryCode/include_juce_audio_devices.cpp b/extras/UnitTestRunner/JuceLibraryCode/include_juce_audio_devices.cpp index fb5c2219..29b774fd 100644 --- a/extras/UnitTestRunner/JuceLibraryCode/include_juce_audio_devices.cpp +++ b/extras/UnitTestRunner/JuceLibraryCode/include_juce_audio_devices.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_devices/juce_audio_devices.cpp> diff --git a/extras/UnitTestRunner/JuceLibraryCode/include_juce_audio_devices.mm b/extras/UnitTestRunner/JuceLibraryCode/include_juce_audio_devices.mm index e58b67ea..287da26e 100644 --- a/extras/UnitTestRunner/JuceLibraryCode/include_juce_audio_devices.mm +++ b/extras/UnitTestRunner/JuceLibraryCode/include_juce_audio_devices.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_devices/juce_audio_devices.mm> diff --git a/extras/UnitTestRunner/JuceLibraryCode/include_juce_audio_formats.cpp b/extras/UnitTestRunner/JuceLibraryCode/include_juce_audio_formats.cpp index a3c61170..8dac3325 100644 --- a/extras/UnitTestRunner/JuceLibraryCode/include_juce_audio_formats.cpp +++ b/extras/UnitTestRunner/JuceLibraryCode/include_juce_audio_formats.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_formats/juce_audio_formats.cpp> diff --git a/extras/UnitTestRunner/JuceLibraryCode/include_juce_audio_formats.mm b/extras/UnitTestRunner/JuceLibraryCode/include_juce_audio_formats.mm index f325b8fb..79e6a22f 100644 --- a/extras/UnitTestRunner/JuceLibraryCode/include_juce_audio_formats.mm +++ b/extras/UnitTestRunner/JuceLibraryCode/include_juce_audio_formats.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_formats/juce_audio_formats.mm> diff --git a/extras/UnitTestRunner/JuceLibraryCode/include_juce_audio_processors.cpp b/extras/UnitTestRunner/JuceLibraryCode/include_juce_audio_processors.cpp index bfe172ed..217d330a 100644 --- a/extras/UnitTestRunner/JuceLibraryCode/include_juce_audio_processors.cpp +++ b/extras/UnitTestRunner/JuceLibraryCode/include_juce_audio_processors.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_processors/juce_audio_processors.cpp> diff --git a/extras/UnitTestRunner/JuceLibraryCode/include_juce_audio_processors.mm b/extras/UnitTestRunner/JuceLibraryCode/include_juce_audio_processors.mm index b80ae901..1f7cc419 100644 --- a/extras/UnitTestRunner/JuceLibraryCode/include_juce_audio_processors.mm +++ b/extras/UnitTestRunner/JuceLibraryCode/include_juce_audio_processors.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_processors/juce_audio_processors.mm> diff --git a/extras/UnitTestRunner/JuceLibraryCode/include_juce_audio_utils.cpp b/extras/UnitTestRunner/JuceLibraryCode/include_juce_audio_utils.cpp index 97bd2c56..046bf31d 100644 --- a/extras/UnitTestRunner/JuceLibraryCode/include_juce_audio_utils.cpp +++ b/extras/UnitTestRunner/JuceLibraryCode/include_juce_audio_utils.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_utils/juce_audio_utils.cpp> diff --git a/extras/UnitTestRunner/JuceLibraryCode/include_juce_audio_utils.mm b/extras/UnitTestRunner/JuceLibraryCode/include_juce_audio_utils.mm index 8eae7c6e..a3f746dc 100644 --- a/extras/UnitTestRunner/JuceLibraryCode/include_juce_audio_utils.mm +++ b/extras/UnitTestRunner/JuceLibraryCode/include_juce_audio_utils.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_utils/juce_audio_utils.mm> diff --git a/extras/UnitTestRunner/JuceLibraryCode/include_juce_blocks_basics.cpp b/extras/UnitTestRunner/JuceLibraryCode/include_juce_blocks_basics.cpp index 6ab147fb..fb50ac3c 100644 --- a/extras/UnitTestRunner/JuceLibraryCode/include_juce_blocks_basics.cpp +++ b/extras/UnitTestRunner/JuceLibraryCode/include_juce_blocks_basics.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_blocks_basics/juce_blocks_basics.cpp> diff --git a/extras/UnitTestRunner/JuceLibraryCode/include_juce_core.cpp b/extras/UnitTestRunner/JuceLibraryCode/include_juce_core.cpp index d0ce1636..84fe988c 100644 --- a/extras/UnitTestRunner/JuceLibraryCode/include_juce_core.cpp +++ b/extras/UnitTestRunner/JuceLibraryCode/include_juce_core.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_core/juce_core.cpp> diff --git a/extras/UnitTestRunner/JuceLibraryCode/include_juce_core.mm b/extras/UnitTestRunner/JuceLibraryCode/include_juce_core.mm index 72b10bf8..9ee67bf6 100644 --- a/extras/UnitTestRunner/JuceLibraryCode/include_juce_core.mm +++ b/extras/UnitTestRunner/JuceLibraryCode/include_juce_core.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_core/juce_core.mm> diff --git a/extras/UnitTestRunner/JuceLibraryCode/include_juce_cryptography.cpp b/extras/UnitTestRunner/JuceLibraryCode/include_juce_cryptography.cpp index 10b3401d..ee7d9085 100644 --- a/extras/UnitTestRunner/JuceLibraryCode/include_juce_cryptography.cpp +++ b/extras/UnitTestRunner/JuceLibraryCode/include_juce_cryptography.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_cryptography/juce_cryptography.cpp> diff --git a/extras/UnitTestRunner/JuceLibraryCode/include_juce_cryptography.mm b/extras/UnitTestRunner/JuceLibraryCode/include_juce_cryptography.mm index 9311ea0f..03ee05f4 100644 --- a/extras/UnitTestRunner/JuceLibraryCode/include_juce_cryptography.mm +++ b/extras/UnitTestRunner/JuceLibraryCode/include_juce_cryptography.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_cryptography/juce_cryptography.mm> diff --git a/extras/UnitTestRunner/JuceLibraryCode/include_juce_data_structures.cpp b/extras/UnitTestRunner/JuceLibraryCode/include_juce_data_structures.cpp index 9315aa16..152980ae 100644 --- a/extras/UnitTestRunner/JuceLibraryCode/include_juce_data_structures.cpp +++ b/extras/UnitTestRunner/JuceLibraryCode/include_juce_data_structures.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_data_structures/juce_data_structures.cpp> diff --git a/extras/UnitTestRunner/JuceLibraryCode/include_juce_data_structures.mm b/extras/UnitTestRunner/JuceLibraryCode/include_juce_data_structures.mm index 695ec439..02b9711c 100644 --- a/extras/UnitTestRunner/JuceLibraryCode/include_juce_data_structures.mm +++ b/extras/UnitTestRunner/JuceLibraryCode/include_juce_data_structures.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_data_structures/juce_data_structures.mm> diff --git a/extras/UnitTestRunner/JuceLibraryCode/include_juce_dsp.cpp b/extras/UnitTestRunner/JuceLibraryCode/include_juce_dsp.cpp index 430d943f..0f0af659 100644 --- a/extras/UnitTestRunner/JuceLibraryCode/include_juce_dsp.cpp +++ b/extras/UnitTestRunner/JuceLibraryCode/include_juce_dsp.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_dsp/juce_dsp.cpp> diff --git a/extras/UnitTestRunner/JuceLibraryCode/include_juce_dsp.mm b/extras/UnitTestRunner/JuceLibraryCode/include_juce_dsp.mm index 1dea5d08..a5cb956c 100644 --- a/extras/UnitTestRunner/JuceLibraryCode/include_juce_dsp.mm +++ b/extras/UnitTestRunner/JuceLibraryCode/include_juce_dsp.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_dsp/juce_dsp.mm> diff --git a/extras/UnitTestRunner/JuceLibraryCode/include_juce_events.cpp b/extras/UnitTestRunner/JuceLibraryCode/include_juce_events.cpp index 1bba110a..39268e2b 100644 --- a/extras/UnitTestRunner/JuceLibraryCode/include_juce_events.cpp +++ b/extras/UnitTestRunner/JuceLibraryCode/include_juce_events.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_events/juce_events.cpp> diff --git a/extras/UnitTestRunner/JuceLibraryCode/include_juce_events.mm b/extras/UnitTestRunner/JuceLibraryCode/include_juce_events.mm index 4cc34fc4..191a9987 100644 --- a/extras/UnitTestRunner/JuceLibraryCode/include_juce_events.mm +++ b/extras/UnitTestRunner/JuceLibraryCode/include_juce_events.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_events/juce_events.mm> diff --git a/extras/UnitTestRunner/JuceLibraryCode/include_juce_graphics.cpp b/extras/UnitTestRunner/JuceLibraryCode/include_juce_graphics.cpp index 319c76de..8ccabef9 100644 --- a/extras/UnitTestRunner/JuceLibraryCode/include_juce_graphics.cpp +++ b/extras/UnitTestRunner/JuceLibraryCode/include_juce_graphics.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_graphics/juce_graphics.cpp> diff --git a/extras/UnitTestRunner/JuceLibraryCode/include_juce_graphics.mm b/extras/UnitTestRunner/JuceLibraryCode/include_juce_graphics.mm index b28e6dd0..6bb7456d 100644 --- a/extras/UnitTestRunner/JuceLibraryCode/include_juce_graphics.mm +++ b/extras/UnitTestRunner/JuceLibraryCode/include_juce_graphics.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_graphics/juce_graphics.mm> diff --git a/extras/UnitTestRunner/JuceLibraryCode/include_juce_gui_basics.cpp b/extras/UnitTestRunner/JuceLibraryCode/include_juce_gui_basics.cpp index 216c76bb..71d04b24 100644 --- a/extras/UnitTestRunner/JuceLibraryCode/include_juce_gui_basics.cpp +++ b/extras/UnitTestRunner/JuceLibraryCode/include_juce_gui_basics.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_gui_basics/juce_gui_basics.cpp> diff --git a/extras/UnitTestRunner/JuceLibraryCode/include_juce_gui_basics.mm b/extras/UnitTestRunner/JuceLibraryCode/include_juce_gui_basics.mm index 6a9726fa..e449e0b7 100644 --- a/extras/UnitTestRunner/JuceLibraryCode/include_juce_gui_basics.mm +++ b/extras/UnitTestRunner/JuceLibraryCode/include_juce_gui_basics.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_gui_basics/juce_gui_basics.mm> diff --git a/extras/UnitTestRunner/JuceLibraryCode/include_juce_gui_extra.cpp b/extras/UnitTestRunner/JuceLibraryCode/include_juce_gui_extra.cpp index 7226e198..a33ece00 100644 --- a/extras/UnitTestRunner/JuceLibraryCode/include_juce_gui_extra.cpp +++ b/extras/UnitTestRunner/JuceLibraryCode/include_juce_gui_extra.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_gui_extra/juce_gui_extra.cpp> diff --git a/extras/UnitTestRunner/JuceLibraryCode/include_juce_gui_extra.mm b/extras/UnitTestRunner/JuceLibraryCode/include_juce_gui_extra.mm index c9b6c3bf..6dacee3a 100644 --- a/extras/UnitTestRunner/JuceLibraryCode/include_juce_gui_extra.mm +++ b/extras/UnitTestRunner/JuceLibraryCode/include_juce_gui_extra.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_gui_extra/juce_gui_extra.mm> diff --git a/extras/UnitTestRunner/JuceLibraryCode/include_juce_opengl.cpp b/extras/UnitTestRunner/JuceLibraryCode/include_juce_opengl.cpp index d9895bce..e6541a42 100644 --- a/extras/UnitTestRunner/JuceLibraryCode/include_juce_opengl.cpp +++ b/extras/UnitTestRunner/JuceLibraryCode/include_juce_opengl.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_opengl/juce_opengl.cpp> diff --git a/extras/UnitTestRunner/JuceLibraryCode/include_juce_opengl.mm b/extras/UnitTestRunner/JuceLibraryCode/include_juce_opengl.mm index 6c2c32d0..793619ea 100644 --- a/extras/UnitTestRunner/JuceLibraryCode/include_juce_opengl.mm +++ b/extras/UnitTestRunner/JuceLibraryCode/include_juce_opengl.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_opengl/juce_opengl.mm> diff --git a/extras/UnitTestRunner/JuceLibraryCode/include_juce_osc.cpp b/extras/UnitTestRunner/JuceLibraryCode/include_juce_osc.cpp index 0c3b9ae9..7eadead5 100644 --- a/extras/UnitTestRunner/JuceLibraryCode/include_juce_osc.cpp +++ b/extras/UnitTestRunner/JuceLibraryCode/include_juce_osc.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_osc/juce_osc.cpp> diff --git a/extras/UnitTestRunner/JuceLibraryCode/include_juce_product_unlocking.cpp b/extras/UnitTestRunner/JuceLibraryCode/include_juce_product_unlocking.cpp index f3fcd328..ebb62e21 100644 --- a/extras/UnitTestRunner/JuceLibraryCode/include_juce_product_unlocking.cpp +++ b/extras/UnitTestRunner/JuceLibraryCode/include_juce_product_unlocking.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_product_unlocking/juce_product_unlocking.cpp> diff --git a/extras/UnitTestRunner/JuceLibraryCode/include_juce_product_unlocking.mm b/extras/UnitTestRunner/JuceLibraryCode/include_juce_product_unlocking.mm index 25aa7eaf..12010f18 100644 --- a/extras/UnitTestRunner/JuceLibraryCode/include_juce_product_unlocking.mm +++ b/extras/UnitTestRunner/JuceLibraryCode/include_juce_product_unlocking.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_product_unlocking/juce_product_unlocking.mm> diff --git a/extras/UnitTestRunner/JuceLibraryCode/include_juce_video.cpp b/extras/UnitTestRunner/JuceLibraryCode/include_juce_video.cpp index bdf22ee1..29c12835 100644 --- a/extras/UnitTestRunner/JuceLibraryCode/include_juce_video.cpp +++ b/extras/UnitTestRunner/JuceLibraryCode/include_juce_video.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_video/juce_video.cpp> diff --git a/extras/UnitTestRunner/JuceLibraryCode/include_juce_video.mm b/extras/UnitTestRunner/JuceLibraryCode/include_juce_video.mm index 3da705bc..082e1adb 100644 --- a/extras/UnitTestRunner/JuceLibraryCode/include_juce_video.mm +++ b/extras/UnitTestRunner/JuceLibraryCode/include_juce_video.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_video/juce_video.mm> diff --git a/extras/UnitTestRunner/Source/Main.cpp b/extras/UnitTestRunner/Source/Main.cpp index 3c9a56ad..35e0feff 100644 --- a/extras/UnitTestRunner/Source/Main.cpp +++ b/extras/UnitTestRunner/Source/Main.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -73,8 +72,20 @@ int main (int argc, char **argv) ConsoleUnitTestRunner runner; - auto seed = (args.containsOption ("--seed") ? args.getValueForOption ("--seed").getLargeIntValue() - : Random::getSystemRandom().nextInt64()); + auto seed = [&args] + { + if (args.containsOption ("--seed")) + { + auto seedValueString = args.getValueForOption ("--seed"); + + if (seedValueString.startsWith ("0x")) + return seedValueString.getHexValue64(); + + return seedValueString.getLargeIntValue(); + } + + return Random::getSystemRandom().nextInt64(); + }(); if (args.containsOption ("--category")) runner.runTestsInCategory (args.getValueForOption ("--category"), seed); diff --git a/extras/UnitTestRunner/UnitTestRunner.jucer b/extras/UnitTestRunner/UnitTestRunner.jucer index 4e3f3afc..973f7418 100644 --- a/extras/UnitTestRunner/UnitTestRunner.jucer +++ b/extras/UnitTestRunner/UnitTestRunner.jucer @@ -1,8 +1,9 @@ <?xml version="1.0" encoding="UTF-8"?> -<JUCERPROJECT id="Z2Xzcp" name="UnitTestRunner" projectType="consoleapp" bundleIdentifier="com.roli.UnitTestRunner" - jucerVersion="5.4.7" defines="JUCE_UNIT_TESTS=1" displaySplashScreen="0" - reportAppUsage="0" companyName="ROLI Ltd." companyCopyright="ROLI Ltd."> +<JUCERPROJECT id="Z2Xzcp" name="UnitTestRunner" projectType="consoleapp" bundleIdentifier="com.juce.UnitTestRunner" + defines="JUCE_UNIT_TESTS=1" displaySplashScreen="0" reportAppUsage="0" + companyName="Raw Material Software Limited" companyCopyright="Raw Material Software Limited" + useAppConfig="0" addUsingNamespaceToJuceHeader="1" jucerFormatVersion="1"> <MAINGROUP id="GZdWCU" name="UnitTestRunner"> <GROUP id="{22894462-E1A9-036F-ED94-B51A50C87552}" name="Source"> <FILE id="ynaYaM" name="Main.cpp" compile="1" resource="0" file="Source/Main.cpp"/> @@ -12,9 +13,9 @@ <XCODE_MAC targetFolder="Builds/MacOSX"> <CONFIGURATIONS> <CONFIGURATION name="Debug" osxCompatibility="10.10 SDK" isDebug="1" targetName="UnitTestRunner" - cppLanguageStandard="gnu++14" recommendedWarnings="LLVM"/> + recommendedWarnings="LLVM"/> <CONFIGURATION name="Release" osxCompatibility="10.10 SDK" isDebug="0" targetName="UnitTestRunner" - cppLanguageStandard="gnu++14" recommendedWarnings="LLVM"/> + recommendedWarnings="LLVM"/> </CONFIGURATIONS> <MODULEPATHS> <MODULEPATH id="juce_core" path="../../modules"/> @@ -40,8 +41,8 @@ </XCODE_MAC> <LINUX_MAKE targetFolder="Builds/LinuxMakefile"> <CONFIGURATIONS> - <CONFIGURATION name="Debug" libraryPath="/usr/X11R6/lib/" isDebug="1" targetName="UnitTestRunner"/> - <CONFIGURATION name="Release" libraryPath="/usr/X11R6/lib/" isDebug="0" targetName="UnitTestRunner"/> + <CONFIGURATION name="Debug" isDebug="1" targetName="UnitTestRunner"/> + <CONFIGURATION name="Release" isDebug="0" targetName="UnitTestRunner"/> </CONFIGURATIONS> <MODULEPATHS> <MODULEPATH id="juce_core" path="../../modules"/> diff --git a/extras/WindowsDLL/Builds/VisualStudio2019/WindowsDLL_StaticLibrary.vcxproj b/extras/WindowsDLL/Builds/VisualStudio2019/WindowsDLL_StaticLibrary.vcxproj index 44747945..0d61cd2f 100644 --- a/extras/WindowsDLL/Builds/VisualStudio2019/WindowsDLL_StaticLibrary.vcxproj +++ b/extras/WindowsDLL/Builds/VisualStudio2019/WindowsDLL_StaticLibrary.vcxproj @@ -64,10 +64,10 @@ <Optimization>Disabled</Optimization> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCE_DLL_BUILD=1;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=1.0.0;JUCE_APP_VERSION_HEX=0x10000;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;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCE_DISPLAY_SPLASH_SCREEN=0;JUCE_USE_DARK_SPLASH_SCREEN=1;JUCE_PROJUCER_VERSION=0x60005;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_audio_formats=1;JUCE_MODULE_AVAILABLE_juce_audio_processors=1;JUCE_MODULE_AVAILABLE_juce_audio_utils=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_MODULE_AVAILABLE_juce_opengl=1;JUCE_MODULE_AVAILABLE_juce_video=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_STANDALONE_APPLICATION=1;JUCE_DLL_BUILD=1;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=1.0.0;JUCE_APP_VERSION_HEX=0x10000;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;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> <RuntimeTypeInfo>true</RuntimeTypeInfo> - <PrecompiledHeader/> + <PrecompiledHeader>NotUsing</PrecompiledHeader> <AssemblerListingLocation>$(IntDir)\</AssemblerListingLocation> <ObjectFileName>$(IntDir)\</ObjectFileName> <ProgramDataBaseFileName>$(IntDir)\</ProgramDataBaseFileName> @@ -105,10 +105,10 @@ <ClCompile> <Optimization>Full</Optimization> <AdditionalIncludeDirectories>..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCE_DLL_BUILD=1;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=1.0.0;JUCE_APP_VERSION_HEX=0x10000;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;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCE_DISPLAY_SPLASH_SCREEN=0;JUCE_USE_DARK_SPLASH_SCREEN=1;JUCE_PROJUCER_VERSION=0x60005;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_audio_formats=1;JUCE_MODULE_AVAILABLE_juce_audio_processors=1;JUCE_MODULE_AVAILABLE_juce_audio_utils=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_MODULE_AVAILABLE_juce_opengl=1;JUCE_MODULE_AVAILABLE_juce_video=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_STANDALONE_APPLICATION=1;JUCE_DLL_BUILD=1;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=1.0.0;JUCE_APP_VERSION_HEX=0x10000;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;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> <RuntimeTypeInfo>true</RuntimeTypeInfo> - <PrecompiledHeader/> + <PrecompiledHeader>NotUsing</PrecompiledHeader> <AssemblerListingLocation>$(IntDir)\</AssemblerListingLocation> <ObjectFileName>$(IntDir)\</ObjectFileName> <ProgramDataBaseFileName>$(IntDir)\</ProgramDataBaseFileName> @@ -130,6 +130,7 @@ <OptimizeReferences>true</OptimizeReferences> <EnableCOMDATFolding>true</EnableCOMDATFolding> <LargeAddressAware>true</LargeAddressAware> + <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> </Link> <Bscmake> <SuppressStartupBanner>true</SuppressStartupBanner> @@ -222,10 +223,10 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_basics\synthesisers\juce_Synthesiser.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_CatmullRomInterpolator.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Interpolators.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_LagrangeInterpolator.cpp"> @@ -234,6 +235,9 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_SmoothedValue.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_WindowedSincInterpolator.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_basics\juce_audio_basics.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -252,6 +256,153 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_devices\midi_io\juce_MidiMessageCollector.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AAudioLoader.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AudioStreamAAudio.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioSourceCaller.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioStream.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioStreamBuilder.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\DataConversionFlowGraph.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FilterAudioStream.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockAdapter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockReader.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockWriter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\LatencyTuner.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\QuirksManager.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceFloatCaller.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceI16Caller.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\StabilizedCallback.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Trace.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Utilities.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Version.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoBuffer.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoController.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerBase.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerIndirect.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\IntegerRatio.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\LinearResampler.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\MultiChannelResampler.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResampler.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerMono.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerStereo.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResampler.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResamplerStereo.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ClipToRange.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\FlowGraphNode.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ManyToMultiConverter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\MonoToMultiConverter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\RampLinear.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SampleRateConverter.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkFloat.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI16.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI24.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceFloat.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI16.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI24.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioInputStreamOpenSLES.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioOutputStreamOpenSLES.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamBuffered.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamOpenSLES.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\EngineOpenSLES.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OpenSLESUtilities.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OutputMixerOpenSLES.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_android_Audio.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -351,70 +502,73 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\libFLAC\window_flac.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\analysis.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\analysis.c"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\bitrate.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\bitrate.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\block.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\block.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codebook.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codebook.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\envelope.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\envelope.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\floor0.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\floor0.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\floor1.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\floor1.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\info.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\info.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lpc.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lpc.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lsp.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lsp.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mapping0.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mapping0.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mdct.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mdct.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\misc.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\psy.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\psy.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\registry.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\registry.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\res0.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\res0.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\sharedbook.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\sharedbook.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\smallft.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\smallft.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\synthesis.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\synthesis.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\vorbisenc.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\vorbisenc.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\vorbisfile.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\vorbisfile.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\window.c"> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\window.c"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\bitwise.c"> @@ -609,6 +763,9 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioProcessorValueTreeState.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_ParameterAttachments.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_RangedAudioParameter.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -711,6 +868,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_FileSearchPath.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -738,6 +898,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_MemoryBlock.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -1623,6 +1786,15 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_MouseListener.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_DragAndDrop.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_android_ContentSharer.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -1641,13 +1813,7 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_FileChooser.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.cpp"> - <ExcludedFromBuild>true</ExcludedFromBuild> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Clipboard.cpp"> - <ExcludedFromBuild>true</ExcludedFromBuild> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Windowing.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_Windowing.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_win32_DragAndDrop.cpp"> @@ -1851,6 +2017,9 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_ActiveXComponent.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_HWNDComponent.cpp"> + <ExcludedFromBuild>true</ExcludedFromBuild> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_SystemTrayIcon.cpp"> <ExcludedFromBuild>true</ExcludedFromBuild> </ClCompile> @@ -1949,10 +2118,10 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_basics\sources\juce_ToneGeneratorAudioSource.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\synthesisers\juce_Synthesiser.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_ADSR.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_CatmullRomInterpolator.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Decibels.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_GenericInterpolator.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_LagrangeInterpolator.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Interpolators.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Reverb.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_SmoothedValue.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\juce_audio_basics.h"/> @@ -1962,6 +2131,66 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_devices\audio_io\juce_SystemAudioVolume.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\midi_io\juce_MidiDevices.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\midi_io\juce_MidiMessageCollector.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStream.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamBase.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamBuilder.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamCallback.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Definitions.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\LatencyTuner.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Oboe.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\ResultWithValue.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\StabilizedCallback.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Utilities.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Version.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AAudioLoader.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AudioStreamAAudio.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioClock.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioSourceCaller.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\DataConversionFlowGraph.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FilterAudioStream.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockAdapter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockReader.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockWriter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\MonotonicCounter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\OboeDebug.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\QuirksManager.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceFloatCaller.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceI16Caller.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Trace.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoBuffer.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoController.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerBase.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerIndirect.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\HyperbolicCosineWindow.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\IntegerRatio.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\KaiserWindow.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\LinearResampler.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\MultiChannelResampler.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResampler.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerMono.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerStereo.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResampler.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResamplerStereo.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ClipToRange.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\FlowGraphNode.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ManyToMultiConverter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\MonoToMultiConverter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\RampLinear.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SampleRateConverter.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkFloat.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI16.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI24.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceFloat.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI16.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI24.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioInputStreamOpenSLES.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioOutputStreamOpenSLES.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamBuffered.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamOpenSLES.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\EngineOpenSLES.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OpenSLESUtilities.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OutputMixerOpenSLES.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\juce_android_HighPerformanceAudioHelpers.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\juce_ios_Audio.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\juce_MidiDataConcatenator.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\sources\juce_AudioSourcePlayer.h"/> @@ -1999,50 +2228,51 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\stream_decoder.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\stream_encoder.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\win_utf8_io.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled\res_books_51.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled\res_books_stereo.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\floor\floor_books.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\uncoupled\res_books_uncoupled.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\floor_all.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_8.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_11.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_16.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_44.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_8.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_16.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44p51.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44u.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_8.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_11.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_16.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_22.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_32.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44p51.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44u.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_X.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\backends.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\bitrate.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codebook.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codec_internal.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\envelope.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\highlevel.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup_data.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lpc.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lsp.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\masking.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mdct.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\misc.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\os.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\psy.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\registry.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\scales.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\smallft.h"/> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\window.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled\res_books_51.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled\res_books_stereo.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\floor\floor_books.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\uncoupled\res_books_uncoupled.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\floor_all.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_8.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_11.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_16.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_44.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_8.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_16.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44p51.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44u.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_8.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_11.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_16.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_22.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_32.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44p51.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44u.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_X.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\backends.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\bitrate.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codebook.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codec_internal.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\envelope.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\highlevel.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup_data.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lpc.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lsp.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\masking.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mdct.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\misc.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\os.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\psy.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\registry.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\scales.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\smallft.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\window.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\codec.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\config_types.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\crctable.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\ogg.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\os_types.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\vorbisenc.h"/> @@ -2131,6 +2361,7 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst\vsteditcontroller.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst\vstparameters.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst\vstpresetfile.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_AU_Shared.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_AudioUnitPluginFormat.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_LADSPAPluginFormat.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_VST3Common.h"/> @@ -2157,6 +2388,7 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioParameterInt.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioProcessorParameterWithID.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioProcessorValueTreeState.h"/> + <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_ParameterAttachments.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_RangedAudioParameter.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\juce_audio_processors.h"/> <ClInclude Include="..\..\..\..\modules\juce_audio_utils\audio_cd\juce_AudioCDBurner.h"/> @@ -2196,6 +2428,7 @@ <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_FileOutputStream.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_FileSearchPath.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_MemoryMappedFile.h"/> + <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_WildcardFileFilter.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\javascript\juce_Javascript.h"/> @@ -2209,6 +2442,7 @@ <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_Random.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_Range.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_StatisticsAccumulator.h"/> + <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_Atomic.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_ByteOrder.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_ContainerDeletePolicy.h"/> @@ -2251,6 +2485,7 @@ <ClInclude Include="..\..\..\..\modules\juce_core\streams\juce_SubregionStream.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\streams\juce_URLInputSource.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerSupport.h"/> + <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerWarnings.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_PlatformDefs.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_StandardHeader.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_SystemStats.h"/> @@ -2507,7 +2742,8 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_SelectedItemSet.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_TextDragAndDropTarget.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_TooltipClient.h"/> - <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.h"/> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.h"/> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_MultiTouchMapper.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\positioning\juce_MarkerList.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\positioning\juce_RelativeCoordinate.h"/> @@ -2559,6 +2795,7 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ActiveXControlComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"/> + <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_HWNDComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_NSViewComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ScopedDPIAwarenessDisabler.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_UIViewComponent.h"/> @@ -2609,11 +2846,13 @@ <ClInclude Include="..\..\..\..\modules\juce_video\native\juce_win32_Video.h"/> <ClInclude Include="..\..\..\..\modules\juce_video\playback\juce_VideoComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_video\juce_video.h"/> - <ClInclude Include="..\..\JuceLibraryCode\AppConfig.h"/> <ClInclude Include="..\..\JuceLibraryCode\JuceHeader.h"/> </ItemGroup> <ItemGroup> + <None Include="..\..\..\..\modules\juce_audio_devices\native\oboe\CMakeLists.txt"/> + <None Include="..\..\..\..\modules\juce_audio_devices\native\oboe\readme.md"/> <None Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\Flac Licence.txt"/> + <None Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\README.md"/> <None Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\Ogg Vorbis Licence.txt"/> <None Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\base\LICENSE.txt"/> <None Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\base\README.md"/> diff --git a/extras/WindowsDLL/Builds/VisualStudio2019/WindowsDLL_StaticLibrary.vcxproj.filters b/extras/WindowsDLL/Builds/VisualStudio2019/WindowsDLL_StaticLibrary.vcxproj.filters index b521de4d..ed7faae8 100644 --- a/extras/WindowsDLL/Builds/VisualStudio2019/WindowsDLL_StaticLibrary.vcxproj.filters +++ b/extras/WindowsDLL/Builds/VisualStudio2019/WindowsDLL_StaticLibrary.vcxproj.filters @@ -35,6 +35,36 @@ <Filter Include="JUCE Modules\juce_audio_devices\midi_io"> <UniqueIdentifier>{092EFC17-7C95-7E04-0ACA-0D61A462EE81}</UniqueIdentifier> </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\include\oboe"> + <UniqueIdentifier>{285118C6-8FDA-7DCE-BEF4-FFB2120876C5}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\include"> + <UniqueIdentifier>{69ED6B61-9B8D-D47E-E4A6-2E9F9A94A75A}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\aaudio"> + <UniqueIdentifier>{7CDB7CD1-BB96-F593-3C78-1E06182B5839}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\common"> + <UniqueIdentifier>{B0A708DE-B4CF-196B-14FB-DC8221509B8E}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\fifo"> + <UniqueIdentifier>{34F46ADE-EE31-227A-A69E-7732E70145F1}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler"> + <UniqueIdentifier>{BB9B3C77-17FB-E994-8B75-88F1727E4655}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph"> + <UniqueIdentifier>{C0971D77-2F14-190A-E2AE-89D6285F4D5A}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src\opensles"> + <UniqueIdentifier>{AABEA333-6524-8891-51C7-6DAEB5700628}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe\src"> + <UniqueIdentifier>{F2D29337-983E-BAD7-7B5C-E0AB3D53D404}</UniqueIdentifier> + </Filter> + <Filter Include="JUCE Modules\juce_audio_devices\native\oboe"> + <UniqueIdentifier>{C674B0FB-1FC0-2986-94B1-083845018994}</UniqueIdentifier> + </Filter> <Filter Include="JUCE Modules\juce_audio_devices\native"> <UniqueIdentifier>{0AFC1CE8-F6E6-9817-8C21-8432B2A375DA}</UniqueIdentifier> </Filter> @@ -59,26 +89,26 @@ <Filter Include="JUCE Modules\juce_audio_formats\codecs\flac"> <UniqueIdentifier>{9EB3EC7F-2AB7-DDAA-3C05-DF382B728D3F}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled"> - <UniqueIdentifier>{02D37B85-7DE2-C8E7-A274-A5A0FBE99D69}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled"> + <UniqueIdentifier>{6B9FBFDC-1D10-6246-356D-00FF4535CECB}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\floor"> - <UniqueIdentifier>{DAF3BAAF-5207-4C34-61B9-A97DDC930D50}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\floor"> + <UniqueIdentifier>{D6FCFC8E-7136-9109-78C0-91A3EB4C443F}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\uncoupled"> - <UniqueIdentifier>{C7885588-8436-4C21-DC1E-58879BF53BDC}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\uncoupled"> + <UniqueIdentifier>{EBF18AC1-F0ED-937A-2824-4307CE2ADAF7}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books"> - <UniqueIdentifier>{E4ECEA39-0EFF-2443-91B3-1E5DA7AD5AE4}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books"> + <UniqueIdentifier>{5A0F7922-2EFB-6465-57E4-A445B804EFB5}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes"> - <UniqueIdentifier>{210B8D25-68E0-32C3-1449-6A40F109C5E9}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes"> + <UniqueIdentifier>{4EC45416-0E7C-7567-6F75-D0C8CEE7DC4F}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib"> - <UniqueIdentifier>{378AD911-E8E4-D230-E76B-34542849509D}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib"> + <UniqueIdentifier>{C2985031-0496-55B5-41A8-BAB99E53D89D}</UniqueIdentifier> </Filter> - <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2"> - <UniqueIdentifier>{F6CED5B6-0A8C-56D2-C1AC-DED6BE774A13}</UniqueIdentifier> + <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7"> + <UniqueIdentifier>{FB4AB426-7009-0036-BB75-E34256AA7C89}</UniqueIdentifier> </Filter> <Filter Include="JUCE Modules\juce_audio_formats\codecs\oggvorbis"> <UniqueIdentifier>{E684D858-09E8-0251-8E86-5657129641E1}</UniqueIdentifier> @@ -347,6 +377,9 @@ <Filter Include="JUCE Modules\juce_gui_basics\mouse"> <UniqueIdentifier>{FE3CB19C-EF43-5CF5-DAF0-09D4E43D0AB9}</UniqueIdentifier> </Filter> + <Filter Include="JUCE Modules\juce_gui_basics\native\x11"> + <UniqueIdentifier>{FE7E6CD5-C7A0-DB20-4E7E-D6E7F08C4578}</UniqueIdentifier> + </Filter> <Filter Include="JUCE Modules\juce_gui_basics\native"> <UniqueIdentifier>{895C2D33-E08D-B1BA-BB36-FC4CA65090C8}</UniqueIdentifier> </Filter> @@ -502,10 +535,10 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_basics\synthesisers\juce_Synthesiser.cpp"> <Filter>JUCE Modules\juce_audio_basics\synthesisers</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_CatmullRomInterpolator.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.cpp"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Interpolators.cpp"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_LagrangeInterpolator.cpp"> @@ -514,6 +547,9 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_SmoothedValue.cpp"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_WindowedSincInterpolator.cpp"> + <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_basics\juce_audio_basics.cpp"> <Filter>JUCE Modules\juce_audio_basics</Filter> </ClCompile> @@ -535,6 +571,153 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_devices\midi_io\juce_MidiMessageCollector.cpp"> <Filter>JUCE Modules\juce_audio_devices\midi_io</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AAudioLoader.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\aaudio</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AudioStreamAAudio.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\aaudio</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioSourceCaller.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioStream.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioStreamBuilder.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\DataConversionFlowGraph.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FilterAudioStream.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockAdapter.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockReader.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockWriter.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\LatencyTuner.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\QuirksManager.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceFloatCaller.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceI16Caller.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\StabilizedCallback.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Trace.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Utilities.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Version.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoBuffer.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoController.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerBase.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerIndirect.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\IntegerRatio.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\LinearResampler.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\MultiChannelResampler.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResampler.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerMono.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerStereo.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResampler.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResamplerStereo.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ClipToRange.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\FlowGraphNode.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ManyToMultiConverter.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\MonoToMultiConverter.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\RampLinear.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SampleRateConverter.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkFloat.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI16.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI24.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceFloat.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI16.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI24.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioInputStreamOpenSLES.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioOutputStreamOpenSLES.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamBuffered.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamOpenSLES.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\EngineOpenSLES.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OpenSLESUtilities.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OutputMixerOpenSLES.cpp"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_devices\native\juce_android_Audio.cpp"> <Filter>JUCE Modules\juce_audio_devices\native</Filter> </ClCompile> @@ -637,71 +820,74 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\libFLAC\window_flac.c"> <Filter>JUCE Modules\juce_audio_formats\codecs\flac\libFLAC</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\analysis.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\analysis.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\bitrate.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\bitrate.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\block.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\block.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codebook.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codebook.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\envelope.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\envelope.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\floor0.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\floor0.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\floor1.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\floor1.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\info.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\info.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lpc.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lpc.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lsp.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lsp.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mapping0.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mapping0.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mdct.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mdct.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\misc.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\psy.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\psy.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\registry.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\registry.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\res0.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\res0.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\sharedbook.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\sharedbook.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\smallft.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\smallft.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\synthesis.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\synthesis.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\vorbisenc.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\vorbisenc.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\vorbisfile.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\vorbisfile.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\window.c"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\window.c"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\bitwise.c"> <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> @@ -901,6 +1087,9 @@ <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioProcessorValueTreeState.cpp"> <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_ParameterAttachments.cpp"> + <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_RangedAudioParameter.cpp"> <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> </ClCompile> @@ -1021,6 +1210,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_FileSearchPath.cpp"> <Filter>JUCE Modules\juce_core\files</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.cpp"> + <Filter>JUCE Modules\juce_core\files</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.cpp"> <Filter>JUCE Modules\juce_core\files</Filter> </ClCompile> @@ -1048,6 +1240,9 @@ <ClCompile Include="..\..\..\..\modules\juce_core\maths\juce_Random.cpp"> <Filter>JUCE Modules\juce_core\maths</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.cpp"> + <Filter>JUCE Modules\juce_core\memory</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_core\memory\juce_MemoryBlock.cpp"> <Filter>JUCE Modules\juce_core\memory</Filter> </ClCompile> @@ -1975,6 +2170,15 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_MouseListener.cpp"> <Filter>JUCE Modules\juce_gui_basics\mouse</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_DragAndDrop.cpp"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.cpp"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.cpp"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_android_ContentSharer.cpp"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> </ClCompile> @@ -2002,13 +2206,7 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_FileChooser.cpp"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.cpp"> - <Filter>JUCE Modules\juce_gui_basics\native</Filter> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Clipboard.cpp"> - <Filter>JUCE Modules\juce_gui_basics\native</Filter> - </ClCompile> - <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11_Windowing.cpp"> + <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_Windowing.cpp"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_basics\native\juce_mac_FileChooser.mm"> @@ -2242,6 +2440,9 @@ <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_ActiveXComponent.cpp"> <Filter>JUCE Modules\juce_gui_extra\native</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_HWNDComponent.cpp"> + <Filter>JUCE Modules\juce_gui_extra\native</Filter> + </ClCompile> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_win32_SystemTrayIcon.cpp"> <Filter>JUCE Modules\juce_gui_extra\native</Filter> </ClCompile> @@ -2445,16 +2646,16 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_ADSR.h"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_CatmullRomInterpolator.h"> + <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Decibels.h"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Decibels.h"> + <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_GenericInterpolator.h"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_IIRFilter.h"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_LagrangeInterpolator.h"> + <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Interpolators.h"> <Filter>JUCE Modules\juce_audio_basics\utilities</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_basics\utilities\juce_Reverb.h"> @@ -2484,6 +2685,186 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_devices\midi_io\juce_MidiMessageCollector.h"> <Filter>JUCE Modules\juce_audio_devices\midi_io</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStream.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamBase.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamBuilder.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\AudioStreamCallback.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Definitions.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\LatencyTuner.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Oboe.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\ResultWithValue.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\StabilizedCallback.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Utilities.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\include\oboe\Version.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\include\oboe</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AAudioLoader.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\aaudio</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\aaudio\AudioStreamAAudio.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\aaudio</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioClock.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\AudioSourceCaller.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\DataConversionFlowGraph.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FilterAudioStream.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockAdapter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockReader.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\FixedBlockWriter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\MonotonicCounter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\OboeDebug.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\QuirksManager.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceFloatCaller.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\SourceI16Caller.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\common\Trace.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\common</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoBuffer.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoController.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerBase.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\fifo\FifoControllerIndirect.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\fifo</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\HyperbolicCosineWindow.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\IntegerRatio.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\KaiserWindow.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\LinearResampler.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\MultiChannelResampler.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResampler.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerMono.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\PolyphaseResamplerStereo.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResampler.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\resampler\SincResamplerStereo.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ClipToRange.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\FlowGraphNode.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\ManyToMultiConverter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\MonoToMultiConverter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\RampLinear.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SampleRateConverter.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkFloat.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI16.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SinkI24.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceFloat.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI16.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\flowgraph\SourceI24.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioInputStreamOpenSLES.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioOutputStreamOpenSLES.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamBuffered.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\AudioStreamOpenSLES.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\EngineOpenSLES.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OpenSLESUtilities.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\oboe\src\opensles\OutputMixerOpenSLES.h"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe\src\opensles</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\juce_android_HighPerformanceAudioHelpers.h"> + <Filter>JUCE Modules\juce_audio_devices\native</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_devices\native\juce_ios_Audio.h"> <Filter>JUCE Modules\juce_audio_devices\native</Filter> </ClInclude> @@ -2595,131 +2976,131 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\win_utf8_io.h"> <Filter>JUCE Modules\juce_audio_formats\codecs\flac</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled\res_books_51.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled\res_books_51.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled\res_books_stereo.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\coupled</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled\res_books_stereo.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\coupled</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\floor\floor_books.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\floor</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\floor\floor_books.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\floor</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\uncoupled\res_books_uncoupled.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\books\uncoupled</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\uncoupled\res_books_uncoupled.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\books\uncoupled</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\floor_all.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\floor_all.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_8.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_8.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_11.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_11.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_16.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_16.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\psych_44.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\psych_44.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_8.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_8.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_16.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_16.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44p51.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44p51.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\residue_44u.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\residue_44u.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_8.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_8.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_11.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_11.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_16.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_16.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_22.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_22.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_32.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_32.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44p51.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44p51.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_44u.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_44u.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes\setup_X.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\modes</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes\setup_X.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\modes</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\backends.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\backends.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\bitrate.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\bitrate.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codebook.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codebook.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\codec_internal.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\codec_internal.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\envelope.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\envelope.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\highlevel.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\highlevel.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lookup_data.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lookup_data.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lpc.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lpc.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\lsp.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\lsp.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\masking.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\masking.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\mdct.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\mdct.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\misc.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\misc.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\os.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\os.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\psy.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\psy.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\registry.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\registry.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\scales.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\scales.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\smallft.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\smallft.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib\window.h"> - <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.2\lib</Filter> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib\window.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\lib</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\codec.h"> <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> @@ -2727,6 +3108,9 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\config_types.h"> <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\crctable.h"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\ogg.h"> <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> </ClInclude> @@ -2991,6 +3375,9 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst\vstpresetfile.h"> <Filter>JUCE Modules\juce_audio_processors\format_types\VST3_SDK\public.sdk\source\vst</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_AU_Shared.h"> + <Filter>JUCE Modules\juce_audio_processors\format_types</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\format_types\juce_AudioUnitPluginFormat.h"> <Filter>JUCE Modules\juce_audio_processors\format_types</Filter> </ClInclude> @@ -3069,6 +3456,9 @@ <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_AudioProcessorValueTreeState.h"> <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_ParameterAttachments.h"> + <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_audio_processors\utilities\juce_RangedAudioParameter.h"> <Filter>JUCE Modules\juce_audio_processors\utilities</Filter> </ClInclude> @@ -3186,6 +3576,9 @@ <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_MemoryMappedFile.h"> <Filter>JUCE Modules\juce_core\files</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_RangedDirectoryIterator.h"> + <Filter>JUCE Modules\juce_core\files</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_core\files\juce_TemporaryFile.h"> <Filter>JUCE Modules\juce_core\files</Filter> </ClInclude> @@ -3225,6 +3618,9 @@ <ClInclude Include="..\..\..\..\modules\juce_core\maths\juce_StatisticsAccumulator.h"> <Filter>JUCE Modules\juce_core\maths</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_AllocationHooks.h"> + <Filter>JUCE Modules\juce_core\memory</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_core\memory\juce_Atomic.h"> <Filter>JUCE Modules\juce_core\memory</Filter> </ClInclude> @@ -3351,6 +3747,9 @@ <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerSupport.h"> <Filter>JUCE Modules\juce_core\system</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_CompilerWarnings.h"> + <Filter>JUCE Modules\juce_core\system</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_core\system\juce_PlatformDefs.h"> <Filter>JUCE Modules\juce_core\system</Filter> </ClInclude> @@ -4119,8 +4518,11 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_basics\mouse\juce_TooltipClient.h"> <Filter>JUCE Modules\juce_gui_basics\mouse</Filter> </ClInclude> - <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_linux_X11.h"> - <Filter>JUCE Modules\juce_gui_basics\native</Filter> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_X11_Symbols.h"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\x11\juce_linux_XWindowSystem.h"> + <Filter>JUCE Modules\juce_gui_basics\native\x11</Filter> </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_gui_basics\native\juce_MultiTouchMapper.h"> <Filter>JUCE Modules\juce_gui_basics\native</Filter> @@ -4275,6 +4677,9 @@ <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"> <Filter>JUCE Modules\juce_gui_extra\embedding</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_HWNDComponent.h"> + <Filter>JUCE Modules\juce_gui_extra\embedding</Filter> + </ClInclude> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_NSViewComponent.h"> <Filter>JUCE Modules\juce_gui_extra\embedding</Filter> </ClInclude> @@ -4425,17 +4830,23 @@ <ClInclude Include="..\..\..\..\modules\juce_video\juce_video.h"> <Filter>JUCE Modules\juce_video</Filter> </ClInclude> - <ClInclude Include="..\..\JuceLibraryCode\AppConfig.h"> - <Filter>JUCE Library Code</Filter> - </ClInclude> <ClInclude Include="..\..\JuceLibraryCode\JuceHeader.h"> <Filter>JUCE Library Code</Filter> </ClInclude> </ItemGroup> <ItemGroup> + <None Include="..\..\..\..\modules\juce_audio_devices\native\oboe\CMakeLists.txt"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe</Filter> + </None> + <None Include="..\..\..\..\modules\juce_audio_devices\native\oboe\readme.md"> + <Filter>JUCE Modules\juce_audio_devices\native\oboe</Filter> + </None> <None Include="..\..\..\..\modules\juce_audio_formats\codecs\flac\Flac Licence.txt"> <Filter>JUCE Modules\juce_audio_formats\codecs\flac</Filter> </None> + <None Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7\README.md"> + <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7</Filter> + </None> <None Include="..\..\..\..\modules\juce_audio_formats\codecs\oggvorbis\Ogg Vorbis Licence.txt"> <Filter>JUCE Modules\juce_audio_formats\codecs\oggvorbis</Filter> </None> diff --git a/extras/WindowsDLL/JuceLibraryCode/AppConfig.h b/extras/WindowsDLL/JuceLibraryCode/AppConfig.h deleted file mode 100644 index fee59eb7..00000000 --- a/extras/WindowsDLL/JuceLibraryCode/AppConfig.h +++ /dev/null @@ -1,295 +0,0 @@ -/* - - IMPORTANT! This file is auto-generated each time you save your - project - if you alter its contents, your changes may be overwritten! - - There's a section below where you can add your own custom code safely, and the - Projucer will preserve the contents of that block, but the best way to change - any of these definitions is by using the Projucer's project settings. - - Any commented-out settings will assume their default values. - -*/ - -#pragma once - -//============================================================================== -// [BEGIN_USER_CODE_SECTION] - -// (You can add your own code in this section, and the Projucer will not overwrite it) - -// [END_USER_CODE_SECTION] - -/* - ============================================================================== - - In accordance with the terms of the JUCE 5 End-Use License Agreement, the - JUCE Code in SECTION A cannot be removed, changed or otherwise rendered - ineffective unless you have a JUCE Indie or Pro license, or are using JUCE - under the GPL v3 license. - - End User License Agreement: www.juce.com/juce-5-licence - - ============================================================================== -*/ - -// BEGIN SECTION A - -#ifndef JUCE_DISPLAY_SPLASH_SCREEN - #define JUCE_DISPLAY_SPLASH_SCREEN 0 -#endif - -#ifndef JUCE_REPORT_APP_USAGE - #define JUCE_REPORT_APP_USAGE 0 -#endif - -// END SECTION A - -#define JUCE_USE_DARK_SPLASH_SCREEN 1 - -#define JUCE_PROJUCER_VERSION 0x50407 - -//============================================================================== -#define JUCE_MODULE_AVAILABLE_juce_audio_basics 1 -#define JUCE_MODULE_AVAILABLE_juce_audio_devices 1 -#define JUCE_MODULE_AVAILABLE_juce_audio_formats 1 -#define JUCE_MODULE_AVAILABLE_juce_audio_processors 1 -#define JUCE_MODULE_AVAILABLE_juce_audio_utils 1 -#define JUCE_MODULE_AVAILABLE_juce_core 1 -#define JUCE_MODULE_AVAILABLE_juce_cryptography 1 -#define JUCE_MODULE_AVAILABLE_juce_data_structures 1 -#define JUCE_MODULE_AVAILABLE_juce_events 1 -#define JUCE_MODULE_AVAILABLE_juce_graphics 1 -#define JUCE_MODULE_AVAILABLE_juce_gui_basics 1 -#define JUCE_MODULE_AVAILABLE_juce_gui_extra 1 -#define JUCE_MODULE_AVAILABLE_juce_opengl 1 -#define JUCE_MODULE_AVAILABLE_juce_video 1 - -#define JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED 1 - -//============================================================================== -// juce_audio_devices flags: - -#ifndef JUCE_USE_WINRT_MIDI - //#define JUCE_USE_WINRT_MIDI 0 -#endif - -#ifndef JUCE_ASIO - //#define JUCE_ASIO 0 -#endif - -#ifndef JUCE_WASAPI - //#define JUCE_WASAPI 1 -#endif - -#ifndef JUCE_WASAPI_EXCLUSIVE - //#define JUCE_WASAPI_EXCLUSIVE 0 -#endif - -#ifndef JUCE_DIRECTSOUND - //#define JUCE_DIRECTSOUND 1 -#endif - -#ifndef JUCE_ALSA - //#define JUCE_ALSA 1 -#endif - -#ifndef JUCE_JACK - //#define JUCE_JACK 0 -#endif - -#ifndef JUCE_BELA - //#define JUCE_BELA 0 -#endif - -#ifndef JUCE_USE_ANDROID_OBOE - //#define JUCE_USE_ANDROID_OBOE 0 -#endif - -#ifndef JUCE_USE_ANDROID_OPENSLES - //#define JUCE_USE_ANDROID_OPENSLES 0 -#endif - -#ifndef JUCE_DISABLE_AUDIO_MIXING_WITH_OTHER_APPS - //#define JUCE_DISABLE_AUDIO_MIXING_WITH_OTHER_APPS 0 -#endif - -//============================================================================== -// juce_audio_formats flags: - -#ifndef JUCE_USE_FLAC - //#define JUCE_USE_FLAC 1 -#endif - -#ifndef JUCE_USE_OGGVORBIS - //#define JUCE_USE_OGGVORBIS 1 -#endif - -#ifndef JUCE_USE_MP3AUDIOFORMAT - //#define JUCE_USE_MP3AUDIOFORMAT 0 -#endif - -#ifndef JUCE_USE_LAME_AUDIO_FORMAT - //#define JUCE_USE_LAME_AUDIO_FORMAT 0 -#endif - -#ifndef JUCE_USE_WINDOWS_MEDIA_FORMAT - //#define JUCE_USE_WINDOWS_MEDIA_FORMAT 1 -#endif - -//============================================================================== -// juce_audio_processors flags: - -#ifndef JUCE_PLUGINHOST_VST - //#define JUCE_PLUGINHOST_VST 0 -#endif - -#ifndef JUCE_PLUGINHOST_VST3 - //#define JUCE_PLUGINHOST_VST3 0 -#endif - -#ifndef JUCE_PLUGINHOST_AU - //#define JUCE_PLUGINHOST_AU 0 -#endif - -#ifndef JUCE_PLUGINHOST_LADSPA - //#define JUCE_PLUGINHOST_LADSPA 0 -#endif - -//============================================================================== -// juce_audio_utils flags: - -#ifndef JUCE_USE_CDREADER - //#define JUCE_USE_CDREADER 0 -#endif - -#ifndef JUCE_USE_CDBURNER - //#define JUCE_USE_CDBURNER 0 -#endif - -//============================================================================== -// juce_core flags: - -#ifndef JUCE_FORCE_DEBUG - //#define JUCE_FORCE_DEBUG 0 -#endif - -#ifndef JUCE_LOG_ASSERTIONS - //#define JUCE_LOG_ASSERTIONS 0 -#endif - -#ifndef JUCE_CHECK_MEMORY_LEAKS - //#define JUCE_CHECK_MEMORY_LEAKS 1 -#endif - -#ifndef JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES - //#define JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES 0 -#endif - -#ifndef JUCE_INCLUDE_ZLIB_CODE - //#define JUCE_INCLUDE_ZLIB_CODE 1 -#endif - -#ifndef JUCE_USE_CURL - //#define JUCE_USE_CURL 1 -#endif - -#ifndef JUCE_LOAD_CURL_SYMBOLS_LAZILY - //#define JUCE_LOAD_CURL_SYMBOLS_LAZILY 0 -#endif - -#ifndef JUCE_CATCH_UNHANDLED_EXCEPTIONS - //#define JUCE_CATCH_UNHANDLED_EXCEPTIONS 0 -#endif - -#ifndef JUCE_ALLOW_STATIC_NULL_VARIABLES - //#define JUCE_ALLOW_STATIC_NULL_VARIABLES 0 -#endif - -#ifndef JUCE_STRICT_REFCOUNTEDPOINTER - //#define JUCE_STRICT_REFCOUNTEDPOINTER 0 -#endif - -//============================================================================== -// juce_events flags: - -#ifndef JUCE_EXECUTE_APP_SUSPEND_ON_BACKGROUND_TASK - //#define JUCE_EXECUTE_APP_SUSPEND_ON_BACKGROUND_TASK 0 -#endif - -//============================================================================== -// juce_graphics flags: - -#ifndef JUCE_USE_COREIMAGE_LOADER - //#define JUCE_USE_COREIMAGE_LOADER 1 -#endif - -#ifndef JUCE_USE_DIRECTWRITE - //#define JUCE_USE_DIRECTWRITE 1 -#endif - -#ifndef JUCE_DISABLE_COREGRAPHICS_FONT_SMOOTHING - //#define JUCE_DISABLE_COREGRAPHICS_FONT_SMOOTHING 0 -#endif - -//============================================================================== -// juce_gui_basics flags: - -#ifndef JUCE_ENABLE_REPAINT_DEBUGGING - //#define JUCE_ENABLE_REPAINT_DEBUGGING 0 -#endif - -#ifndef JUCE_USE_XRANDR - //#define JUCE_USE_XRANDR 1 -#endif - -#ifndef JUCE_USE_XINERAMA - //#define JUCE_USE_XINERAMA 1 -#endif - -#ifndef JUCE_USE_XSHM - //#define JUCE_USE_XSHM 1 -#endif - -#ifndef JUCE_USE_XRENDER - //#define JUCE_USE_XRENDER 0 -#endif - -#ifndef JUCE_USE_XCURSOR - //#define JUCE_USE_XCURSOR 1 -#endif - -#ifndef JUCE_WIN_PER_MONITOR_DPI_AWARE - //#define JUCE_WIN_PER_MONITOR_DPI_AWARE 1 -#endif - -//============================================================================== -// juce_gui_extra flags: - -#ifndef JUCE_WEB_BROWSER - //#define JUCE_WEB_BROWSER 1 -#endif - -#ifndef JUCE_ENABLE_LIVE_CONSTANT_EDITOR - //#define JUCE_ENABLE_LIVE_CONSTANT_EDITOR 0 -#endif - -//============================================================================== -// juce_video flags: - -#ifndef JUCE_USE_CAMERA - //#define JUCE_USE_CAMERA 0 -#endif - -#ifndef JUCE_SYNC_VIDEO_VOLUME_WITH_OS_MEDIA_VOLUME - //#define JUCE_SYNC_VIDEO_VOLUME_WITH_OS_MEDIA_VOLUME 1 -#endif - -//============================================================================== -#ifndef JUCE_STANDALONE_APPLICATION - #if defined(JucePlugin_Name) && defined(JucePlugin_Build_Standalone) - #define JUCE_STANDALONE_APPLICATION JucePlugin_Build_Standalone - #else - #define JUCE_STANDALONE_APPLICATION 1 - #endif -#endif diff --git a/extras/WindowsDLL/JuceLibraryCode/JuceHeader.h b/extras/WindowsDLL/JuceLibraryCode/JuceHeader.h index 91fef65b..1175e306 100644 --- a/extras/WindowsDLL/JuceLibraryCode/JuceHeader.h +++ b/extras/WindowsDLL/JuceLibraryCode/JuceHeader.h @@ -12,7 +12,6 @@ #pragma once -#include "AppConfig.h" #include <juce_audio_basics/juce_audio_basics.h> #include <juce_audio_devices/juce_audio_devices.h> @@ -49,7 +48,7 @@ namespace ProjectInfo { const char* const projectName = "WindowsDLL"; - const char* const companyName = "ROLI Ltd."; + const char* const companyName = "Raw Material Software Limited"; const char* const versionString = "1.0.0"; const int versionNumber = 0x10000; } diff --git a/extras/WindowsDLL/JuceLibraryCode/include_juce_audio_basics.cpp b/extras/WindowsDLL/JuceLibraryCode/include_juce_audio_basics.cpp index 41869487..e5c3ae92 100644 --- a/extras/WindowsDLL/JuceLibraryCode/include_juce_audio_basics.cpp +++ b/extras/WindowsDLL/JuceLibraryCode/include_juce_audio_basics.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_basics/juce_audio_basics.cpp> diff --git a/extras/WindowsDLL/JuceLibraryCode/include_juce_audio_basics.mm b/extras/WindowsDLL/JuceLibraryCode/include_juce_audio_basics.mm index e0e6c577..c7f36c64 100644 --- a/extras/WindowsDLL/JuceLibraryCode/include_juce_audio_basics.mm +++ b/extras/WindowsDLL/JuceLibraryCode/include_juce_audio_basics.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_basics/juce_audio_basics.mm> diff --git a/extras/WindowsDLL/JuceLibraryCode/include_juce_audio_devices.cpp b/extras/WindowsDLL/JuceLibraryCode/include_juce_audio_devices.cpp index fb5c2219..29b774fd 100644 --- a/extras/WindowsDLL/JuceLibraryCode/include_juce_audio_devices.cpp +++ b/extras/WindowsDLL/JuceLibraryCode/include_juce_audio_devices.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_devices/juce_audio_devices.cpp> diff --git a/extras/WindowsDLL/JuceLibraryCode/include_juce_audio_devices.mm b/extras/WindowsDLL/JuceLibraryCode/include_juce_audio_devices.mm index e58b67ea..287da26e 100644 --- a/extras/WindowsDLL/JuceLibraryCode/include_juce_audio_devices.mm +++ b/extras/WindowsDLL/JuceLibraryCode/include_juce_audio_devices.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_devices/juce_audio_devices.mm> diff --git a/extras/WindowsDLL/JuceLibraryCode/include_juce_audio_formats.cpp b/extras/WindowsDLL/JuceLibraryCode/include_juce_audio_formats.cpp index a3c61170..8dac3325 100644 --- a/extras/WindowsDLL/JuceLibraryCode/include_juce_audio_formats.cpp +++ b/extras/WindowsDLL/JuceLibraryCode/include_juce_audio_formats.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_formats/juce_audio_formats.cpp> diff --git a/extras/WindowsDLL/JuceLibraryCode/include_juce_audio_formats.mm b/extras/WindowsDLL/JuceLibraryCode/include_juce_audio_formats.mm index f325b8fb..79e6a22f 100644 --- a/extras/WindowsDLL/JuceLibraryCode/include_juce_audio_formats.mm +++ b/extras/WindowsDLL/JuceLibraryCode/include_juce_audio_formats.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_formats/juce_audio_formats.mm> diff --git a/extras/WindowsDLL/JuceLibraryCode/include_juce_audio_processors.cpp b/extras/WindowsDLL/JuceLibraryCode/include_juce_audio_processors.cpp index bfe172ed..217d330a 100644 --- a/extras/WindowsDLL/JuceLibraryCode/include_juce_audio_processors.cpp +++ b/extras/WindowsDLL/JuceLibraryCode/include_juce_audio_processors.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_processors/juce_audio_processors.cpp> diff --git a/extras/WindowsDLL/JuceLibraryCode/include_juce_audio_processors.mm b/extras/WindowsDLL/JuceLibraryCode/include_juce_audio_processors.mm index b80ae901..1f7cc419 100644 --- a/extras/WindowsDLL/JuceLibraryCode/include_juce_audio_processors.mm +++ b/extras/WindowsDLL/JuceLibraryCode/include_juce_audio_processors.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_processors/juce_audio_processors.mm> diff --git a/extras/WindowsDLL/JuceLibraryCode/include_juce_audio_utils.cpp b/extras/WindowsDLL/JuceLibraryCode/include_juce_audio_utils.cpp index 97bd2c56..046bf31d 100644 --- a/extras/WindowsDLL/JuceLibraryCode/include_juce_audio_utils.cpp +++ b/extras/WindowsDLL/JuceLibraryCode/include_juce_audio_utils.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_utils/juce_audio_utils.cpp> diff --git a/extras/WindowsDLL/JuceLibraryCode/include_juce_audio_utils.mm b/extras/WindowsDLL/JuceLibraryCode/include_juce_audio_utils.mm index 8eae7c6e..a3f746dc 100644 --- a/extras/WindowsDLL/JuceLibraryCode/include_juce_audio_utils.mm +++ b/extras/WindowsDLL/JuceLibraryCode/include_juce_audio_utils.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_audio_utils/juce_audio_utils.mm> diff --git a/extras/WindowsDLL/JuceLibraryCode/include_juce_core.cpp b/extras/WindowsDLL/JuceLibraryCode/include_juce_core.cpp index d0ce1636..84fe988c 100644 --- a/extras/WindowsDLL/JuceLibraryCode/include_juce_core.cpp +++ b/extras/WindowsDLL/JuceLibraryCode/include_juce_core.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_core/juce_core.cpp> diff --git a/extras/WindowsDLL/JuceLibraryCode/include_juce_core.mm b/extras/WindowsDLL/JuceLibraryCode/include_juce_core.mm index 72b10bf8..9ee67bf6 100644 --- a/extras/WindowsDLL/JuceLibraryCode/include_juce_core.mm +++ b/extras/WindowsDLL/JuceLibraryCode/include_juce_core.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_core/juce_core.mm> diff --git a/extras/WindowsDLL/JuceLibraryCode/include_juce_cryptography.cpp b/extras/WindowsDLL/JuceLibraryCode/include_juce_cryptography.cpp index 10b3401d..ee7d9085 100644 --- a/extras/WindowsDLL/JuceLibraryCode/include_juce_cryptography.cpp +++ b/extras/WindowsDLL/JuceLibraryCode/include_juce_cryptography.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_cryptography/juce_cryptography.cpp> diff --git a/extras/WindowsDLL/JuceLibraryCode/include_juce_cryptography.mm b/extras/WindowsDLL/JuceLibraryCode/include_juce_cryptography.mm index 9311ea0f..03ee05f4 100644 --- a/extras/WindowsDLL/JuceLibraryCode/include_juce_cryptography.mm +++ b/extras/WindowsDLL/JuceLibraryCode/include_juce_cryptography.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_cryptography/juce_cryptography.mm> diff --git a/extras/WindowsDLL/JuceLibraryCode/include_juce_data_structures.cpp b/extras/WindowsDLL/JuceLibraryCode/include_juce_data_structures.cpp index 9315aa16..152980ae 100644 --- a/extras/WindowsDLL/JuceLibraryCode/include_juce_data_structures.cpp +++ b/extras/WindowsDLL/JuceLibraryCode/include_juce_data_structures.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_data_structures/juce_data_structures.cpp> diff --git a/extras/WindowsDLL/JuceLibraryCode/include_juce_data_structures.mm b/extras/WindowsDLL/JuceLibraryCode/include_juce_data_structures.mm index 695ec439..02b9711c 100644 --- a/extras/WindowsDLL/JuceLibraryCode/include_juce_data_structures.mm +++ b/extras/WindowsDLL/JuceLibraryCode/include_juce_data_structures.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_data_structures/juce_data_structures.mm> diff --git a/extras/WindowsDLL/JuceLibraryCode/include_juce_events.cpp b/extras/WindowsDLL/JuceLibraryCode/include_juce_events.cpp index 1bba110a..39268e2b 100644 --- a/extras/WindowsDLL/JuceLibraryCode/include_juce_events.cpp +++ b/extras/WindowsDLL/JuceLibraryCode/include_juce_events.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_events/juce_events.cpp> diff --git a/extras/WindowsDLL/JuceLibraryCode/include_juce_events.mm b/extras/WindowsDLL/JuceLibraryCode/include_juce_events.mm index 4cc34fc4..191a9987 100644 --- a/extras/WindowsDLL/JuceLibraryCode/include_juce_events.mm +++ b/extras/WindowsDLL/JuceLibraryCode/include_juce_events.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_events/juce_events.mm> diff --git a/extras/WindowsDLL/JuceLibraryCode/include_juce_graphics.cpp b/extras/WindowsDLL/JuceLibraryCode/include_juce_graphics.cpp index 319c76de..8ccabef9 100644 --- a/extras/WindowsDLL/JuceLibraryCode/include_juce_graphics.cpp +++ b/extras/WindowsDLL/JuceLibraryCode/include_juce_graphics.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_graphics/juce_graphics.cpp> diff --git a/extras/WindowsDLL/JuceLibraryCode/include_juce_graphics.mm b/extras/WindowsDLL/JuceLibraryCode/include_juce_graphics.mm index b28e6dd0..6bb7456d 100644 --- a/extras/WindowsDLL/JuceLibraryCode/include_juce_graphics.mm +++ b/extras/WindowsDLL/JuceLibraryCode/include_juce_graphics.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_graphics/juce_graphics.mm> diff --git a/extras/WindowsDLL/JuceLibraryCode/include_juce_gui_basics.cpp b/extras/WindowsDLL/JuceLibraryCode/include_juce_gui_basics.cpp index 216c76bb..71d04b24 100644 --- a/extras/WindowsDLL/JuceLibraryCode/include_juce_gui_basics.cpp +++ b/extras/WindowsDLL/JuceLibraryCode/include_juce_gui_basics.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_gui_basics/juce_gui_basics.cpp> diff --git a/extras/WindowsDLL/JuceLibraryCode/include_juce_gui_basics.mm b/extras/WindowsDLL/JuceLibraryCode/include_juce_gui_basics.mm index 6a9726fa..e449e0b7 100644 --- a/extras/WindowsDLL/JuceLibraryCode/include_juce_gui_basics.mm +++ b/extras/WindowsDLL/JuceLibraryCode/include_juce_gui_basics.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_gui_basics/juce_gui_basics.mm> diff --git a/extras/WindowsDLL/JuceLibraryCode/include_juce_gui_extra.cpp b/extras/WindowsDLL/JuceLibraryCode/include_juce_gui_extra.cpp index 7226e198..a33ece00 100644 --- a/extras/WindowsDLL/JuceLibraryCode/include_juce_gui_extra.cpp +++ b/extras/WindowsDLL/JuceLibraryCode/include_juce_gui_extra.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_gui_extra/juce_gui_extra.cpp> diff --git a/extras/WindowsDLL/JuceLibraryCode/include_juce_gui_extra.mm b/extras/WindowsDLL/JuceLibraryCode/include_juce_gui_extra.mm index c9b6c3bf..6dacee3a 100644 --- a/extras/WindowsDLL/JuceLibraryCode/include_juce_gui_extra.mm +++ b/extras/WindowsDLL/JuceLibraryCode/include_juce_gui_extra.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_gui_extra/juce_gui_extra.mm> diff --git a/extras/WindowsDLL/JuceLibraryCode/include_juce_opengl.cpp b/extras/WindowsDLL/JuceLibraryCode/include_juce_opengl.cpp index d9895bce..e6541a42 100644 --- a/extras/WindowsDLL/JuceLibraryCode/include_juce_opengl.cpp +++ b/extras/WindowsDLL/JuceLibraryCode/include_juce_opengl.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_opengl/juce_opengl.cpp> diff --git a/extras/WindowsDLL/JuceLibraryCode/include_juce_opengl.mm b/extras/WindowsDLL/JuceLibraryCode/include_juce_opengl.mm index 6c2c32d0..793619ea 100644 --- a/extras/WindowsDLL/JuceLibraryCode/include_juce_opengl.mm +++ b/extras/WindowsDLL/JuceLibraryCode/include_juce_opengl.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_opengl/juce_opengl.mm> diff --git a/extras/WindowsDLL/JuceLibraryCode/include_juce_video.cpp b/extras/WindowsDLL/JuceLibraryCode/include_juce_video.cpp index bdf22ee1..29c12835 100644 --- a/extras/WindowsDLL/JuceLibraryCode/include_juce_video.cpp +++ b/extras/WindowsDLL/JuceLibraryCode/include_juce_video.cpp @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_video/juce_video.cpp> diff --git a/extras/WindowsDLL/JuceLibraryCode/include_juce_video.mm b/extras/WindowsDLL/JuceLibraryCode/include_juce_video.mm index 3da705bc..082e1adb 100644 --- a/extras/WindowsDLL/JuceLibraryCode/include_juce_video.mm +++ b/extras/WindowsDLL/JuceLibraryCode/include_juce_video.mm @@ -5,5 +5,4 @@ */ -#include "AppConfig.h" #include <juce_video/juce_video.mm> diff --git a/extras/WindowsDLL/WindowsDLL.jucer b/extras/WindowsDLL/WindowsDLL.jucer index 228a9bc6..c1bd847b 100644 --- a/extras/WindowsDLL/WindowsDLL.jucer +++ b/extras/WindowsDLL/WindowsDLL.jucer @@ -1,9 +1,10 @@ <?xml version="1.0" encoding="UTF-8"?> <JUCERPROJECT id="IvabE4" name="WindowsDLL" projectType="library" juceLinkage="none" - bundleIdentifier="com.roli.jucedll" jucerVersion="5.4.7" defines="JUCE_DLL_BUILD=1" - displaySplashScreen="0" reportAppUsage="0" companyName="ROLI Ltd." - companyCopyright="ROLI Ltd."> + bundleIdentifier="com.juce.jucedll" defines="JUCE_DLL_BUILD=1" + displaySplashScreen="0" reportAppUsage="0" companyName="Raw Material Software Limited" + companyCopyright="Raw Material Software Limited" useAppConfig="0" + addUsingNamespaceToJuceHeader="1" jucerFormatVersion="1"> <EXPORTFORMATS> <VS2019 targetFolder="Builds/VisualStudio2019"> <CONFIGURATIONS> diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt new file mode 100644 index 00000000..f37350cb --- /dev/null +++ b/modules/CMakeLists.txt @@ -0,0 +1,47 @@ +# ============================================================================== +# +# This file is part of the JUCE library. +# Copyright (c) 2020 - Raw Material Software Limited +# +# JUCE is an open source library subject to commercial or open-source +# licensing. +# +# By using JUCE, you agree to the terms of both the JUCE 6 End-User License +# Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). +# +# End User License Agreement: www.juce.com/juce-6-licence +# Privacy Policy: www.juce.com/juce-privacy-policy +# +# Or: You may also use this code under the terms of the GPL v3 (see +# www.gnu.org/licenses). +# +# JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER +# EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE +# DISCLAIMED. +# +# ============================================================================== + +juce_add_modules( + INSTALL_PATH "include/JUCE-${JUCE_VERSION}/modules" + ALIAS_NAMESPACE juce + juce_analytics + juce_audio_basics + juce_audio_devices + juce_audio_formats + juce_audio_plugin_client + juce_audio_processors + juce_audio_utils + juce_blocks_basics + juce_box2d + juce_core + juce_cryptography + juce_data_structures + juce_dsp + juce_events + juce_graphics + juce_gui_basics + juce_gui_extra + juce_opengl + juce_osc + juce_product_unlocking + juce_video) diff --git a/modules/juce_analytics/analytics/juce_Analytics.cpp b/modules/juce_analytics/analytics/juce_Analytics.cpp index 22e3b755..61b43cd5 100644 --- a/modules/juce_analytics/analytics/juce_Analytics.cpp +++ b/modules/juce_analytics/analytics/juce_Analytics.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_analytics/analytics/juce_Analytics.h b/modules/juce_analytics/analytics/juce_Analytics.h index 99a88a8b..d83b25be 100644 --- a/modules/juce_analytics/analytics/juce_Analytics.h +++ b/modules/juce_analytics/analytics/juce_Analytics.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_analytics/analytics/juce_ButtonTracker.cpp b/modules/juce_analytics/analytics/juce_ButtonTracker.cpp index 9ec6776e..6e586c08 100644 --- a/modules/juce_analytics/analytics/juce_ButtonTracker.cpp +++ b/modules/juce_analytics/analytics/juce_ButtonTracker.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_analytics/analytics/juce_ButtonTracker.h b/modules/juce_analytics/analytics/juce_ButtonTracker.h index a385c6ad..f2da6d41 100644 --- a/modules/juce_analytics/analytics/juce_ButtonTracker.h +++ b/modules/juce_analytics/analytics/juce_ButtonTracker.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_analytics/destinations/juce_AnalyticsDestination.h b/modules/juce_analytics/destinations/juce_AnalyticsDestination.h index d0855d82..46fd0882 100644 --- a/modules/juce_analytics/destinations/juce_AnalyticsDestination.h +++ b/modules/juce_analytics/destinations/juce_AnalyticsDestination.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_analytics/destinations/juce_ThreadedAnalyticsDestination.cpp b/modules/juce_analytics/destinations/juce_ThreadedAnalyticsDestination.cpp index 7c92bbba..da9df139 100644 --- a/modules/juce_analytics/destinations/juce_ThreadedAnalyticsDestination.cpp +++ b/modules/juce_analytics/destinations/juce_ThreadedAnalyticsDestination.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_analytics/destinations/juce_ThreadedAnalyticsDestination.h b/modules/juce_analytics/destinations/juce_ThreadedAnalyticsDestination.h index d6d0182f..c868a37f 100644 --- a/modules/juce_analytics/destinations/juce_ThreadedAnalyticsDestination.h +++ b/modules/juce_analytics/destinations/juce_ThreadedAnalyticsDestination.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_analytics/juce_analytics.cpp b/modules/juce_analytics/juce_analytics.cpp index f66a2049..a7c733b1 100644 --- a/modules/juce_analytics/juce_analytics.cpp +++ b/modules/juce_analytics/juce_analytics.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_analytics/juce_analytics.h b/modules/juce_analytics/juce_analytics.h index 36828075..81333385 100644 --- a/modules/juce_analytics/juce_analytics.h +++ b/modules/juce_analytics/juce_analytics.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -29,14 +28,14 @@ The block below describes the properties of this module, and is read by the Projucer to automatically generate project code that uses it. For details about the syntax and how to create or use a module, see the - JUCE Module Format.txt file. + JUCE Module Format.md file. BEGIN_JUCE_MODULE_DECLARATION ID: juce_analytics vendor: juce - version: 5.4.7 + version: 6.0.5 name: JUCE analytics classes description: Classes to collect analytics and send to destinations website: http://www.juce.com/juce @@ -52,7 +51,6 @@ #pragma once #define JUCE_ANALYTICS_H_INCLUDED -#include <queue> #include <juce_gui_basics/juce_gui_basics.h> #include "destinations/juce_AnalyticsDestination.h" diff --git a/modules/juce_audio_basics/audio_play_head/juce_AudioPlayHead.h b/modules/juce_audio_basics/audio_play_head/juce_AudioPlayHead.h index 70f3a2b4..ebbb68d9 100644 --- a/modules/juce_audio_basics/audio_play_head/juce_AudioPlayHead.h +++ b/modules/juce_audio_basics/audio_play_head/juce_AudioPlayHead.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -122,10 +122,35 @@ public: bool isLooping; //============================================================================== - bool operator== (const CurrentPositionInfo& other) const noexcept; - bool operator!= (const CurrentPositionInfo& other) const noexcept; - - void resetToDefault(); + bool operator== (const CurrentPositionInfo& other) const noexcept + { + return timeInSamples == other.timeInSamples + && ppqPosition == other.ppqPosition + && editOriginTime == other.editOriginTime + && ppqPositionOfLastBarStart == other.ppqPositionOfLastBarStart + && frameRate == other.frameRate + && isPlaying == other.isPlaying + && isRecording == other.isRecording + && bpm == other.bpm + && timeSigNumerator == other.timeSigNumerator + && timeSigDenominator == other.timeSigDenominator + && ppqLoopStart == other.ppqLoopStart + && ppqLoopEnd == other.ppqLoopEnd + && isLooping == other.isLooping; + } + + bool operator!= (const CurrentPositionInfo& other) const noexcept + { + return ! operator== (other); + } + + void resetToDefault() + { + zerostruct (*this); + timeSigNumerator = 4; + timeSigDenominator = 4; + bpm = 120; + } }; //============================================================================== diff --git a/modules/juce_audio_basics/buffers/juce_AudioChannelSet.cpp b/modules/juce_audio_basics/buffers/juce_AudioChannelSet.cpp index 40ba2992..425baf58 100644 --- a/modules/juce_audio_basics/buffers/juce_AudioChannelSet.cpp +++ b/modules/juce_audio_basics/buffers/juce_AudioChannelSet.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -87,15 +87,38 @@ String AudioChannelSet::getChannelTypeName (AudioChannelSet::ChannelType type) case ambisonicACN13: return NEEDS_TRANS("Ambisonic 13"); case ambisonicACN14: return NEEDS_TRANS("Ambisonic 14"); case ambisonicACN15: return NEEDS_TRANS("Ambisonic 15"); + case ambisonicACN16: return NEEDS_TRANS("Ambisonic 16"); + case ambisonicACN17: return NEEDS_TRANS("Ambisonic 17"); + case ambisonicACN18: return NEEDS_TRANS("Ambisonic 18"); + case ambisonicACN19: return NEEDS_TRANS("Ambisonic 19"); + case ambisonicACN20: return NEEDS_TRANS("Ambisonic 20"); + case ambisonicACN21: return NEEDS_TRANS("Ambisonic 21"); + case ambisonicACN22: return NEEDS_TRANS("Ambisonic 22"); + case ambisonicACN23: return NEEDS_TRANS("Ambisonic 23"); + case ambisonicACN24: return NEEDS_TRANS("Ambisonic 24"); + case ambisonicACN25: return NEEDS_TRANS("Ambisonic 25"); + case ambisonicACN26: return NEEDS_TRANS("Ambisonic 26"); + case ambisonicACN27: return NEEDS_TRANS("Ambisonic 27"); + case ambisonicACN28: return NEEDS_TRANS("Ambisonic 28"); + case ambisonicACN29: return NEEDS_TRANS("Ambisonic 29"); + case ambisonicACN30: return NEEDS_TRANS("Ambisonic 30"); + case ambisonicACN31: return NEEDS_TRANS("Ambisonic 31"); + case ambisonicACN32: return NEEDS_TRANS("Ambisonic 32"); + case ambisonicACN33: return NEEDS_TRANS("Ambisonic 33"); + case ambisonicACN34: return NEEDS_TRANS("Ambisonic 34"); + case ambisonicACN35: return NEEDS_TRANS("Ambisonic 35"); case bottomFrontLeft: return NEEDS_TRANS("Bottom Front Left"); case bottomFrontCentre: return NEEDS_TRANS("Bottom Front Centre"); case bottomFrontRight: return NEEDS_TRANS("Bottom Front Right"); + case proximityLeft: return NEEDS_TRANS("Proximity Left"); + case proximityRight: return NEEDS_TRANS("Proximity Right"); case bottomSideLeft: return NEEDS_TRANS("Bottom Side Left"); case bottomSideRight: return NEEDS_TRANS("Bottom Side Right"); case bottomRearLeft: return NEEDS_TRANS("Bottom Rear Left"); case bottomRearCentre: return NEEDS_TRANS("Bottom Rear Centre"); case bottomRearRight: return NEEDS_TRANS("Bottom Rear Right"); - case discreteChannel0: return NEEDS_TRANS("Discrete channel"); + case discreteChannel0: + case unknown: default: break; } @@ -148,16 +171,40 @@ String AudioChannelSet::getAbbreviatedChannelTypeName (AudioChannelSet::ChannelT case ambisonicACN13: return "ACN13"; case ambisonicACN14: return "ACN14"; case ambisonicACN15: return "ACN15"; + case ambisonicACN16: return "ACN16"; + case ambisonicACN17: return "ACN17"; + case ambisonicACN18: return "ACN18"; + case ambisonicACN19: return "ACN19"; + case ambisonicACN20: return "ACN20"; + case ambisonicACN21: return "ACN21"; + case ambisonicACN22: return "ACN22"; + case ambisonicACN23: return "ACN23"; + case ambisonicACN24: return "ACN24"; + case ambisonicACN25: return "ACN25"; + case ambisonicACN26: return "ACN26"; + case ambisonicACN27: return "ACN27"; + case ambisonicACN28: return "ACN28"; + case ambisonicACN29: return "ACN29"; + case ambisonicACN30: return "ACN30"; + case ambisonicACN31: return "ACN31"; + case ambisonicACN32: return "ACN32"; + case ambisonicACN33: return "ACN33"; + case ambisonicACN34: return "ACN34"; + case ambisonicACN35: return "ACN35"; case topSideLeft: return "Tsl"; case topSideRight: return "Tsr"; case bottomFrontLeft: return "Bfl"; case bottomFrontCentre: return "Bfc"; case bottomFrontRight: return "Bfr"; + case proximityLeft: return "Pl"; + case proximityRight: return "Pr"; case bottomSideLeft: return "Bsl"; case bottomSideRight: return "Bsr"; case bottomRearLeft: return "Brl"; case bottomRearCentre: return "Brc"; case bottomRearRight: return "Brr"; + case discreteChannel0: + case unknown: default: break; } @@ -216,6 +263,26 @@ AudioChannelSet::ChannelType AudioChannelSet::getChannelTypeFromAbbreviation (co if (abbr == "ACN13") return ambisonicACN13; if (abbr == "ACN14") return ambisonicACN14; if (abbr == "ACN15") return ambisonicACN15; + if (abbr == "ACN16") return ambisonicACN16; + if (abbr == "ACN17") return ambisonicACN17; + if (abbr == "ACN18") return ambisonicACN18; + if (abbr == "ACN19") return ambisonicACN19; + if (abbr == "ACN20") return ambisonicACN20; + if (abbr == "ACN21") return ambisonicACN21; + if (abbr == "ACN22") return ambisonicACN22; + if (abbr == "ACN23") return ambisonicACN23; + if (abbr == "ACN24") return ambisonicACN24; + if (abbr == "ACN25") return ambisonicACN25; + if (abbr == "ACN26") return ambisonicACN26; + if (abbr == "ACN27") return ambisonicACN27; + if (abbr == "ACN28") return ambisonicACN28; + if (abbr == "ACN29") return ambisonicACN29; + if (abbr == "ACN30") return ambisonicACN30; + if (abbr == "ACN31") return ambisonicACN31; + if (abbr == "ACN32") return ambisonicACN32; + if (abbr == "ACN33") return ambisonicACN33; + if (abbr == "ACN34") return ambisonicACN34; + if (abbr == "ACN35") return ambisonicACN35; if (abbr == "Tsl") return topSideLeft; if (abbr == "Tsr") return topSideRight; if (abbr == "Bfl") return bottomFrontLeft; diff --git a/modules/juce_audio_basics/buffers/juce_AudioChannelSet.h b/modules/juce_audio_basics/buffers/juce_AudioChannelSet.h index e9985a18..c6dbbad0 100644 --- a/modules/juce_audio_basics/buffers/juce_AudioChannelSet.h +++ b/modules/juce_audio_basics/buffers/juce_AudioChannelSet.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -369,7 +369,7 @@ public: bottomFrontCentre = 63, /**< Bottom Front Centre (Bfc) */ bottomFrontRight = 64, /**< Bottom Front Right (Bfr) */ - proxymityLeft = 65, /**< Proximity Left (Pl) */ + proximityLeft = 65, /**< Proximity Left (Pl) */ proximityRight = 66, /**< Proximity Right (Pr) */ bottomSideLeft = 67, /**< Bottom Side Left (Bsl) */ diff --git a/modules/juce_audio_basics/buffers/juce_AudioDataConverters.cpp b/modules/juce_audio_basics/buffers/juce_AudioDataConverters.cpp index a441a8f0..b54c5878 100644 --- a/modules/juce_audio_basics/buffers/juce_AudioDataConverters.cpp +++ b/modules/juce_audio_basics/buffers/juce_AudioDataConverters.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -32,7 +32,7 @@ void AudioDataConverters::convertFloatToInt16LE (const float* source, void* dest { for (int i = 0; i < numSamples; ++i) { - *reinterpret_cast<uint16*> (intData) = ByteOrder::swapIfBigEndian ((uint16) (short) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i]))); + *unalignedPointerCast<uint16*> (intData) = ByteOrder::swapIfBigEndian ((uint16) (short) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i]))); intData += destBytesPerSample; } } @@ -43,7 +43,7 @@ void AudioDataConverters::convertFloatToInt16LE (const float* source, void* dest for (int i = numSamples; --i >= 0;) { intData -= destBytesPerSample; - *reinterpret_cast<uint16*> (intData) = ByteOrder::swapIfBigEndian ((uint16) (short) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i]))); + *unalignedPointerCast<uint16*> (intData) = ByteOrder::swapIfBigEndian ((uint16) (short) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i]))); } } } @@ -57,7 +57,7 @@ void AudioDataConverters::convertFloatToInt16BE (const float* source, void* dest { for (int i = 0; i < numSamples; ++i) { - *reinterpret_cast<uint16*> (intData) = ByteOrder::swapIfLittleEndian ((uint16) (short) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i]))); + *unalignedPointerCast<uint16*> (intData) = ByteOrder::swapIfLittleEndian ((uint16) (short) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i]))); intData += destBytesPerSample; } } @@ -68,7 +68,7 @@ void AudioDataConverters::convertFloatToInt16BE (const float* source, void* dest for (int i = numSamples; --i >= 0;) { intData -= destBytesPerSample; - *reinterpret_cast<uint16*> (intData) = ByteOrder::swapIfLittleEndian ((uint16) (short) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i]))); + *unalignedPointerCast<uint16*> (intData) = ByteOrder::swapIfLittleEndian ((uint16) (short) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i]))); } } } @@ -132,7 +132,7 @@ void AudioDataConverters::convertFloatToInt32LE (const float* source, void* dest { for (int i = 0; i < numSamples; ++i) { - *reinterpret_cast<uint32*> (intData) = ByteOrder::swapIfBigEndian ((uint32) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i]))); + *unalignedPointerCast<uint32*> (intData) = ByteOrder::swapIfBigEndian ((uint32) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i]))); intData += destBytesPerSample; } } @@ -143,7 +143,7 @@ void AudioDataConverters::convertFloatToInt32LE (const float* source, void* dest for (int i = numSamples; --i >= 0;) { intData -= destBytesPerSample; - *reinterpret_cast<uint32*> (intData) = ByteOrder::swapIfBigEndian ((uint32) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i]))); + *unalignedPointerCast<uint32*> (intData) = ByteOrder::swapIfBigEndian ((uint32) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i]))); } } } @@ -157,7 +157,7 @@ void AudioDataConverters::convertFloatToInt32BE (const float* source, void* dest { for (int i = 0; i < numSamples; ++i) { - *reinterpret_cast<uint32*> (intData) = ByteOrder::swapIfLittleEndian ((uint32) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i]))); + *unalignedPointerCast<uint32*> (intData) = ByteOrder::swapIfLittleEndian ((uint32) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i]))); intData += destBytesPerSample; } } @@ -168,7 +168,7 @@ void AudioDataConverters::convertFloatToInt32BE (const float* source, void* dest for (int i = numSamples; --i >= 0;) { intData -= destBytesPerSample; - *reinterpret_cast<uint32*> (intData) = ByteOrder::swapIfLittleEndian ((uint32) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i]))); + *unalignedPointerCast<uint32*> (intData) = ByteOrder::swapIfLittleEndian ((uint32) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i]))); } } } @@ -181,10 +181,10 @@ void AudioDataConverters::convertFloatToFloat32LE (const float* source, void* de for (int i = 0; i < numSamples; ++i) { - *reinterpret_cast<float*> (d) = source[i]; + *unalignedPointerCast<float*> (d) = source[i]; #if JUCE_BIG_ENDIAN - *reinterpret_cast<uint32*> (d) = ByteOrder::swap (*reinterpret_cast<uint32*> (d)); + *unalignedPointerCast<uint32*> (d) = ByteOrder::swap (*unalignedPointerCast<uint32*> (d)); #endif d += destBytesPerSample; @@ -199,10 +199,10 @@ void AudioDataConverters::convertFloatToFloat32BE (const float* source, void* de for (int i = 0; i < numSamples; ++i) { - *reinterpret_cast<float*> (d) = source[i]; + *unalignedPointerCast<float*> (d) = source[i]; #if JUCE_LITTLE_ENDIAN - *reinterpret_cast<uint32*> (d) = ByteOrder::swap (*reinterpret_cast<uint32*> (d)); + *unalignedPointerCast<uint32*> (d) = ByteOrder::swap (*unalignedPointerCast<uint32*> (d)); #endif d += destBytesPerSample; @@ -219,7 +219,7 @@ void AudioDataConverters::convertInt16LEToFloat (const void* source, float* dest { for (int i = 0; i < numSamples; ++i) { - dest[i] = scale * (short) ByteOrder::swapIfBigEndian (*reinterpret_cast<const uint16*> (intData)); + dest[i] = scale * (short) ByteOrder::swapIfBigEndian (*unalignedPointerCast<const uint16*> (intData)); intData += srcBytesPerSample; } } @@ -230,7 +230,7 @@ void AudioDataConverters::convertInt16LEToFloat (const void* source, float* dest for (int i = numSamples; --i >= 0;) { intData -= srcBytesPerSample; - dest[i] = scale * (short) ByteOrder::swapIfBigEndian (*reinterpret_cast<const uint16*> (intData)); + dest[i] = scale * (short) ByteOrder::swapIfBigEndian (*unalignedPointerCast<const uint16*> (intData)); } } } @@ -244,7 +244,7 @@ void AudioDataConverters::convertInt16BEToFloat (const void* source, float* dest { for (int i = 0; i < numSamples; ++i) { - dest[i] = scale * (short) ByteOrder::swapIfLittleEndian (*reinterpret_cast<const uint16*> (intData)); + dest[i] = scale * (short) ByteOrder::swapIfLittleEndian (*unalignedPointerCast<const uint16*> (intData)); intData += srcBytesPerSample; } } @@ -255,7 +255,7 @@ void AudioDataConverters::convertInt16BEToFloat (const void* source, float* dest for (int i = numSamples; --i >= 0;) { intData -= srcBytesPerSample; - dest[i] = scale * (short) ByteOrder::swapIfLittleEndian (*reinterpret_cast<const uint16*> (intData)); + dest[i] = scale * (short) ByteOrder::swapIfLittleEndian (*unalignedPointerCast<const uint16*> (intData)); } } } @@ -319,7 +319,7 @@ void AudioDataConverters::convertInt32LEToFloat (const void* source, float* dest { for (int i = 0; i < numSamples; ++i) { - dest[i] = scale * (int) ByteOrder::swapIfBigEndian (*reinterpret_cast<const uint32*> (intData)); + dest[i] = scale * (float) ByteOrder::swapIfBigEndian (*unalignedPointerCast<const uint32*> (intData)); intData += srcBytesPerSample; } } @@ -330,7 +330,7 @@ void AudioDataConverters::convertInt32LEToFloat (const void* source, float* dest for (int i = numSamples; --i >= 0;) { intData -= srcBytesPerSample; - dest[i] = scale * (int) ByteOrder::swapIfBigEndian (*reinterpret_cast<const uint32*> (intData)); + dest[i] = scale * (float) ByteOrder::swapIfBigEndian (*unalignedPointerCast<const uint32*> (intData)); } } } @@ -344,7 +344,7 @@ void AudioDataConverters::convertInt32BEToFloat (const void* source, float* dest { for (int i = 0; i < numSamples; ++i) { - dest[i] = scale * (int) ByteOrder::swapIfLittleEndian (*reinterpret_cast<const uint32*> (intData)); + dest[i] = scale * (float) ByteOrder::swapIfLittleEndian (*unalignedPointerCast<const uint32*> (intData)); intData += srcBytesPerSample; } } @@ -355,7 +355,7 @@ void AudioDataConverters::convertInt32BEToFloat (const void* source, float* dest for (int i = numSamples; --i >= 0;) { intData -= srcBytesPerSample; - dest[i] = scale * (int) ByteOrder::swapIfLittleEndian (*reinterpret_cast<const uint32*> (intData)); + dest[i] = scale * (float) ByteOrder::swapIfLittleEndian (*unalignedPointerCast<const uint32*> (intData)); } } } @@ -366,10 +366,10 @@ void AudioDataConverters::convertFloat32LEToFloat (const void* source, float* de for (int i = 0; i < numSamples; ++i) { - dest[i] = *reinterpret_cast<const float*> (s); + dest[i] = *unalignedPointerCast<const float*> (s); #if JUCE_BIG_ENDIAN - auto d = reinterpret_cast<uint32*> (dest + i); + auto d = unalignedPointerCast<uint32*> (dest + i); *d = ByteOrder::swap (*d); #endif @@ -383,10 +383,10 @@ void AudioDataConverters::convertFloat32BEToFloat (const void* source, float* de for (int i = 0; i < numSamples; ++i) { - dest[i] = *reinterpret_cast<const float*> (s); + dest[i] = *unalignedPointerCast<const float*> (s); #if JUCE_LITTLE_ENDIAN - auto d = reinterpret_cast<uint32*> (dest + i); + auto d = unalignedPointerCast<uint32*> (dest + i); *d = ByteOrder::swap (*d); #endif diff --git a/modules/juce_audio_basics/buffers/juce_AudioDataConverters.h b/modules/juce_audio_basics/buffers/juce_AudioDataConverters.h index e8e1fed6..64ad8ec4 100644 --- a/modules/juce_audio_basics/buffers/juce_AudioDataConverters.h +++ b/modules/juce_audio_basics/buffers/juce_AudioDataConverters.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -69,22 +69,22 @@ public: class BigEndian { public: - template <class SampleFormatType> static inline float getAsFloat (SampleFormatType& s) noexcept { return s.getAsFloatBE(); } - template <class SampleFormatType> static inline void setAsFloat (SampleFormatType& s, float newValue) noexcept { s.setAsFloatBE (newValue); } - template <class SampleFormatType> static inline int32 getAsInt32 (SampleFormatType& s) noexcept { return s.getAsInt32BE(); } - template <class SampleFormatType> static inline void setAsInt32 (SampleFormatType& s, int32 newValue) noexcept { s.setAsInt32BE (newValue); } - template <class SourceType, class DestType> static inline void copyFrom (DestType& dest, SourceType& source) noexcept { dest.copyFromBE (source); } + template <class SampleFormatType> static float getAsFloat (SampleFormatType& s) noexcept { return s.getAsFloatBE(); } + template <class SampleFormatType> static void setAsFloat (SampleFormatType& s, float newValue) noexcept { s.setAsFloatBE (newValue); } + template <class SampleFormatType> static int32 getAsInt32 (SampleFormatType& s) noexcept { return s.getAsInt32BE(); } + template <class SampleFormatType> static void setAsInt32 (SampleFormatType& s, int32 newValue) noexcept { s.setAsInt32BE (newValue); } + template <class SourceType, class DestType> static void copyFrom (DestType& dest, SourceType& source) noexcept { dest.copyFromBE (source); } enum { isBigEndian = 1 }; }; class LittleEndian { public: - template <class SampleFormatType> static inline float getAsFloat (SampleFormatType& s) noexcept { return s.getAsFloatLE(); } - template <class SampleFormatType> static inline void setAsFloat (SampleFormatType& s, float newValue) noexcept { s.setAsFloatLE (newValue); } - template <class SampleFormatType> static inline int32 getAsInt32 (SampleFormatType& s) noexcept { return s.getAsInt32LE(); } - template <class SampleFormatType> static inline void setAsInt32 (SampleFormatType& s, int32 newValue) noexcept { s.setAsInt32LE (newValue); } - template <class SourceType, class DestType> static inline void copyFrom (DestType& dest, SourceType& source) noexcept { dest.copyFromLE (source); } + template <class SampleFormatType> static float getAsFloat (SampleFormatType& s) noexcept { return s.getAsFloatLE(); } + template <class SampleFormatType> static void setAsFloat (SampleFormatType& s, float newValue) noexcept { s.setAsFloatLE (newValue); } + template <class SampleFormatType> static int32 getAsInt32 (SampleFormatType& s) noexcept { return s.getAsInt32LE(); } + template <class SampleFormatType> static void setAsInt32 (SampleFormatType& s, int32 newValue) noexcept { s.setAsInt32LE (newValue); } + template <class SourceType, class DestType> static void copyFrom (DestType& dest, SourceType& source) noexcept { dest.copyFromLE (source); } enum { isBigEndian = 0 }; }; @@ -284,7 +284,7 @@ public: template <class SampleFormatType> inline void advanceData (SampleFormatType& s) noexcept { s.advance(); } template <class SampleFormatType> inline void advanceDataBy (SampleFormatType& s, int numSamples) noexcept { s.skip (numSamples); } template <class SampleFormatType> inline void clear (SampleFormatType& s, int numSamples) noexcept { s.clearMultiple (numSamples); } - template <class SampleFormatType> inline static int getNumBytesBetweenSamples (const SampleFormatType&) noexcept { return SampleFormatType::bytesPerSample; } + template <class SampleFormatType> static int getNumBytesBetweenSamples (const SampleFormatType&) noexcept { return SampleFormatType::bytesPerSample; } enum { isInterleavedType = 0, numInterleavedChannels = 1 }; }; @@ -309,7 +309,7 @@ public: { public: using VoidType = void; - static inline void* toVoidPtr (VoidType* v) noexcept { return v; } + static void* toVoidPtr (VoidType* v) noexcept { return v; } enum { isConst = 0 }; }; @@ -317,7 +317,7 @@ public: { public: using VoidType = const void; - static inline void* toVoidPtr (VoidType* v) noexcept { return const_cast<void*> (v); } + static void* toVoidPtr (VoidType* v) noexcept { return const_cast<void*> (v); } enum { isConst = 1 }; }; #endif @@ -528,8 +528,8 @@ public: if (v < mn) mn = v; } - return Range<float> (mn * (float) (1.0 / (1.0 + (double) Int32::maxValue)), - mx * (float) (1.0 / (1.0 + (double) Int32::maxValue))); + return Range<float> ((float) mn * (float) (1.0 / (1.0 + (double) Int32::maxValue)), + (float) mx * (float) (1.0 / (1.0 + (double) Int32::maxValue))); } /** Scans a block of data, returning the lowest and highest levels as floats */ diff --git a/modules/juce_audio_basics/buffers/juce_AudioProcessLoadMeasurer.cpp b/modules/juce_audio_basics/buffers/juce_AudioProcessLoadMeasurer.cpp index 17959493..0a617d7d 100644 --- a/modules/juce_audio_basics/buffers/juce_AudioProcessLoadMeasurer.cpp +++ b/modules/juce_audio_basics/buffers/juce_AudioProcessLoadMeasurer.cpp @@ -2,20 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 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). + 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 diff --git a/modules/juce_audio_basics/buffers/juce_AudioProcessLoadMeasurer.h b/modules/juce_audio_basics/buffers/juce_AudioProcessLoadMeasurer.h index 8cf59706..ffd113d6 100644 --- a/modules/juce_audio_basics/buffers/juce_AudioProcessLoadMeasurer.h +++ b/modules/juce_audio_basics/buffers/juce_AudioProcessLoadMeasurer.h @@ -2,20 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 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). + 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 diff --git a/modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.h b/modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.h index f4ab1df0..acd165ff 100644 --- a/modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.h +++ b/modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -23,6 +23,53 @@ namespace juce { +#ifndef DOXYGEN +/** The contents of this namespace are used to implement AudioBuffer and should + not be used elsewhere. Their interfaces (and existence) are liable to change! +*/ +namespace detail +{ + /** On iOS/arm7 the alignment of `double` is greater than the alignment of + `std::max_align_t`, so we can't trust max_align_t. Instead, we query + lots of primitive types and use the maximum alignment of all of them. + + We're putting this stuff outside AudioBuffer itself to avoid creating + unnecessary copies for each distinct template instantiation of + AudioBuffer. + + MSVC 2015 doesn't like when we write getMaxAlignment as a loop which + accumulates the max alignment (declarations not allowed in constexpr + function body) so instead we use this recursive version which + instantiates a zillion templates. + */ + + template <typename> struct Type {}; + + constexpr size_t getMaxAlignment() noexcept { return 0; } + + template <typename Head, typename... Tail> + constexpr size_t getMaxAlignment (Type<Head>, Type<Tail>... tail) noexcept + { + return jmax (alignof (Head), getMaxAlignment (tail...)); + } + + constexpr size_t maxAlignment = getMaxAlignment (Type<std::max_align_t>{}, + Type<void*>{}, + Type<float>{}, + Type<double>{}, + Type<long double>{}, + Type<short int>{}, + Type<int>{}, + Type<long int>{}, + Type<long long int>{}, + Type<bool>{}, + Type<char>{}, + Type<char16_t>{}, + Type<char32_t>{}, + Type<wchar_t>{}); +} // namespace detail +#endif + //============================================================================== /** A multi-channel buffer containing floating point audio samples. @@ -357,8 +404,8 @@ public: auto numSamplesToCopy = (size_t) jmin (newNumSamples, size); - auto newChannels = reinterpret_cast<Type**> (newData.get()); - auto newChan = reinterpret_cast<Type*> (newData + channelListSize); + auto newChannels = unalignedPointerCast<Type**> (newData.get()); + auto newChan = unalignedPointerCast<Type*> (newData + channelListSize); for (int j = 0; j < newNumChannels; ++j) { @@ -390,10 +437,10 @@ public: { allocatedBytes = newTotalBytes; allocatedData.allocate (newTotalBytes, clearExtraSpace || isClear); - channels = reinterpret_cast<Type**> (allocatedData.get()); + channels = unalignedPointerCast<Type**> (allocatedData.get()); } - auto* chan = reinterpret_cast<Type*> (allocatedData + channelListSize); + auto* chan = unalignedPointerCast<Type*> (allocatedData + channelListSize); for (int i = 0; i < newNumChannels; ++i) { @@ -1075,8 +1122,10 @@ private: void allocateData() { - static_assert (std::alignment_of<Type>::value <= std::alignment_of<std::max_align_t>::value, + #if ! JUCE_PROJUCER_LIVE_BUILD && (! JUCE_GCC || (__GNUC__ * 100 + __GNUC_MINOR__) >= 409) + static_assert (alignof (Type) <= detail::maxAlignment, "AudioBuffer cannot hold types with alignment requirements larger than that guaranteed by malloc"); + #endif jassert (size >= 0); auto channelListSize = (size_t) (numChannels + 1) * sizeof (Type*); @@ -1088,8 +1137,8 @@ private: allocatedBytes = (size_t) numChannels * (size_t) size * sizeof (Type) + channelListSize + 32; allocatedData.malloc (allocatedBytes); - channels = reinterpret_cast<Type**> (allocatedData.get()); - auto chan = reinterpret_cast<Type*> (allocatedData + channelListSize); + channels = unalignedPointerCast<Type**> (allocatedData.get()); + auto chan = unalignedPointerCast<Type*> (allocatedData + channelListSize); for (int i = 0; i < numChannels; ++i) { @@ -1113,7 +1162,7 @@ private: else { allocatedData.malloc (numChannels + 1, sizeof (Type*)); - channels = reinterpret_cast<Type**> (allocatedData.get()); + channels = unalignedPointerCast<Type**> (allocatedData.get()); } for (int i = 0; i < numChannels; ++i) diff --git a/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp b/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp index a01ad84a..5a761a30 100644 --- a/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp +++ b/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -30,7 +30,7 @@ namespace FloatVectorHelpers #define JUCE_INCREMENT_DEST dest += (16 / sizeof (*dest)); #if JUCE_USE_SSE_INTRINSICS - inline static bool isAligned (const void* p) noexcept + static bool isAligned (const void* p) noexcept { return (((pointer_sized_int) p) & 15) == 0; } diff --git a/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h b/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h index 4ad122b1..928815a6 100644 --- a/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h +++ b/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/juce_audio_basics.cpp b/modules/juce_audio_basics/juce_audio_basics.cpp index c142c6d6..9fe3e779 100644 --- a/modules/juce_audio_basics/juce_audio_basics.cpp +++ b/modules/juce_audio_basics/juce_audio_basics.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -59,7 +59,8 @@ #include "buffers/juce_AudioProcessLoadMeasurer.cpp" #include "utilities/juce_IIRFilter.cpp" #include "utilities/juce_LagrangeInterpolator.cpp" -#include "utilities/juce_CatmullRomInterpolator.cpp" +#include "utilities/juce_WindowedSincInterpolator.cpp" +#include "utilities/juce_Interpolators.cpp" #include "utilities/juce_SmoothedValue.cpp" #include "midi/juce_MidiBuffer.cpp" #include "midi/juce_MidiFile.cpp" diff --git a/modules/juce_audio_basics/juce_audio_basics.h b/modules/juce_audio_basics/juce_audio_basics.h index 93fd4c65..a3b3d41d 100644 --- a/modules/juce_audio_basics/juce_audio_basics.h +++ b/modules/juce_audio_basics/juce_audio_basics.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -25,14 +25,14 @@ The block below describes the properties of this module, and is read by the Projucer to automatically generate project code that uses it. For details about the syntax and how to create or use a module, see the - JUCE Module Format.txt file. + JUCE Module Format.md file. BEGIN_JUCE_MODULE_DECLARATION ID: juce_audio_basics vendor: juce - version: 5.4.7 + version: 6.0.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 @@ -88,8 +88,8 @@ #include "buffers/juce_AudioProcessLoadMeasurer.h" #include "utilities/juce_Decibels.h" #include "utilities/juce_IIRFilter.h" -#include "utilities/juce_LagrangeInterpolator.h" -#include "utilities/juce_CatmullRomInterpolator.h" +#include "utilities/juce_GenericInterpolator.h" +#include "utilities/juce_Interpolators.h" #include "utilities/juce_SmoothedValue.h" #include "utilities/juce_Reverb.h" #include "utilities/juce_ADSR.h" diff --git a/modules/juce_audio_basics/juce_audio_basics.mm b/modules/juce_audio_basics/juce_audio_basics.mm index 588078c3..27a6289c 100644 --- a/modules/juce_audio_basics/juce_audio_basics.mm +++ b/modules/juce_audio_basics/juce_audio_basics.mm @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/midi/juce_MidiBuffer.cpp b/modules/juce_audio_basics/midi/juce_MidiBuffer.cpp index 0501698b..cde16912 100644 --- a/modules/juce_audio_basics/midi/juce_MidiBuffer.cpp +++ b/modules/juce_audio_basics/midi/juce_MidiBuffer.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -60,9 +60,8 @@ namespace MidiBufferHelpers if (maxBytes == 1) return 1; - int n; - auto bytesLeft = MidiMessage::readVariableLengthVal (data + 1, n); - return jmin (maxBytes, n + 2 + bytesLeft); + const auto var = MidiMessage::readVariableLengthValue (data + 1, maxBytes - 1); + return jmin (maxBytes, var.value + 2 + var.bytesUsed); } if (byte >= 0x80) @@ -81,17 +80,27 @@ namespace MidiBufferHelpers } //============================================================================== -MidiBuffer::MidiBuffer() noexcept {} -MidiBuffer::~MidiBuffer() {} +MidiBufferIterator& MidiBufferIterator::operator++() noexcept +{ + data += sizeof (int32) + sizeof (uint16) + size_t (MidiBufferHelpers::getEventDataSize (data)); + return *this; +} -MidiBuffer::MidiBuffer (const MidiBuffer& other) noexcept : data (other.data) {} +MidiBufferIterator MidiBufferIterator::operator++ (int) noexcept +{ + auto copy = *this; + ++(*this); + return copy; +} -MidiBuffer& MidiBuffer::operator= (const MidiBuffer& other) noexcept +MidiBufferIterator::reference MidiBufferIterator::operator*() const noexcept { - data = other.data; - return *this; + return { data + sizeof (int32) + sizeof (uint16), + MidiBufferHelpers::getEventDataSize (data), + MidiBufferHelpers::getEventTime (data) }; } +//============================================================================== MidiBuffer::MidiBuffer (const MidiMessage& message) noexcept { addEvent (message, 0); @@ -138,16 +147,14 @@ void MidiBuffer::addEvent (const void* newData, int maxBytes, int sampleNumber) void MidiBuffer::addEvents (const MidiBuffer& otherBuffer, int startSample, int numSamples, int sampleDeltaToAdd) { - Iterator i (otherBuffer); - i.setNextSamplePosition (startSample); + for (auto i = otherBuffer.findNextSamplePosition (startSample); i != otherBuffer.cend(); ++i) + { + const auto metadata = *i; - const uint8* eventData; - int eventSize, position; + if (metadata.samplePosition >= startSample + numSamples && numSamples >= 0) + break; - while (i.getNextEvent (eventData, eventSize, position) - && (position < startSample + numSamples || numSamples < 0)) - { - addEvent (eventData, eventSize, position + sampleDeltaToAdd); + addEvent (metadata.data, metadata.numBytes, metadata.samplePosition + sampleDeltaToAdd); } } @@ -185,9 +192,17 @@ int MidiBuffer::getLastEventTime() const noexcept } } +MidiBufferIterator MidiBuffer::findNextSamplePosition (int samplePosition) const noexcept +{ + return std::find_if (cbegin(), cend(), [&] (const MidiMessageMetadata& metadata) noexcept + { + return metadata.samplePosition >= samplePosition; + }); +} + //============================================================================== MidiBuffer::Iterator::Iterator (const MidiBuffer& b) noexcept - : buffer (b), data (b.data.begin()) + : buffer (b), iterator (b.data.begin()) { } @@ -195,37 +210,29 @@ MidiBuffer::Iterator::~Iterator() noexcept {} void MidiBuffer::Iterator::setNextSamplePosition (int samplePosition) noexcept { - data = buffer.data.begin(); - auto dataEnd = buffer.data.end(); - - while (data < dataEnd && MidiBufferHelpers::getEventTime (data) < samplePosition) - data += MidiBufferHelpers::getEventTotalSize (data); + iterator = buffer.findNextSamplePosition (samplePosition); } bool MidiBuffer::Iterator::getNextEvent (const uint8*& midiData, int& numBytes, int& samplePosition) noexcept { - if (data >= buffer.data.end()) + if (iterator == buffer.cend()) return false; - samplePosition = MidiBufferHelpers::getEventTime (data); - auto itemSize = MidiBufferHelpers::getEventDataSize (data); - numBytes = itemSize; - midiData = data + sizeof (int32) + sizeof (uint16); - data += sizeof (int32) + sizeof (uint16) + (size_t) itemSize; - + const auto metadata = *iterator++; + midiData = metadata.data; + numBytes = metadata.numBytes; + samplePosition = metadata.samplePosition; return true; } bool MidiBuffer::Iterator::getNextEvent (MidiMessage& result, int& samplePosition) noexcept { - if (data >= buffer.data.end()) + if (iterator == buffer.cend()) return false; - samplePosition = MidiBufferHelpers::getEventTime (data); - auto itemSize = MidiBufferHelpers::getEventDataSize (data); - result = MidiMessage (data + sizeof (int32) + sizeof (uint16), itemSize, samplePosition); - data += sizeof (int32) + sizeof (uint16) + (size_t) itemSize; - + const auto metadata = *iterator++; + result = metadata.getMessage(); + samplePosition = metadata.samplePosition; return true; } diff --git a/modules/juce_audio_basics/midi/juce_MidiBuffer.h b/modules/juce_audio_basics/midi/juce_MidiBuffer.h index 8344a5ed..2c764af0 100644 --- a/modules/juce_audio_basics/midi/juce_MidiBuffer.h +++ b/modules/juce_audio_basics/midi/juce_MidiBuffer.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -23,6 +23,108 @@ namespace juce { +//============================================================================== +/** + A view of MIDI message data stored in a contiguous buffer. + + Instances of this class do *not* own the midi data bytes that they point to. + Instead, they expect the midi data to live in a separate buffer that outlives + the MidiMessageMetadata instance. + + @tags{Audio} +*/ +struct MidiMessageMetadata final +{ + MidiMessageMetadata() noexcept = default; + + MidiMessageMetadata (const uint8* dataIn, int numBytesIn, int positionIn) noexcept + : data (dataIn), numBytes (numBytesIn), samplePosition (positionIn) + { + } + + /** Constructs a new MidiMessage instance from the data that this object is viewing. + + Note that MidiMessage owns its data storage, whereas MidiMessageMetadata does not. + */ + MidiMessage getMessage() const { return MidiMessage (data, numBytes, samplePosition); } + + /** Pointer to the first byte of a MIDI message. */ + const uint8* data = nullptr; + + /** The number of bytes in the MIDI message. */ + int numBytes = 0; + + /** The MIDI message's timestamp. */ + int samplePosition = 0; +}; + +//============================================================================== +/** + An iterator to move over contiguous raw MIDI data, which Allows iterating + over a MidiBuffer using C++11 range-for syntax. + + In the following example, we log all three-byte messages in a midi buffer. + @code + void processBlock (AudioBuffer<float>&, MidiBuffer& midiBuffer) override + { + for (const MidiMessageMetadata metadata : midiBuffer) + if (metadata.numBytes == 3) + Logger::writeToLog (metadata.getMessage().getDescription()); + } + @endcode + + @tags{Audio} +*/ +class JUCE_API MidiBufferIterator +{ + using Ptr = const uint8*; + +public: + MidiBufferIterator() = default; + + /** Constructs an iterator pointing at the message starting at the byte `dataIn`. + `dataIn` must point to the start of a valid MIDI message. If it does not, + calling other member functions on the iterator will result in undefined + behaviour. + */ + explicit MidiBufferIterator (const uint8* dataIn) noexcept + : data (dataIn) + { + } + + using difference_type = std::iterator_traits<Ptr>::difference_type; + using value_type = MidiMessageMetadata; + using reference = MidiMessageMetadata; + using pointer = void; + using iterator_category = std::input_iterator_tag; + + /** Make this iterator point to the next message in the buffer. */ + MidiBufferIterator& operator++() noexcept; + + /** Create a copy of this object, make this iterator point to the next message in + the buffer, then return the copy. + */ + MidiBufferIterator operator++ (int) noexcept; + + /** Return true if this iterator points to the same message as another + iterator instance, otherwise return false. + */ + bool operator== (const MidiBufferIterator& other) const noexcept { return data == other.data; } + + /** Return false if this iterator points to the same message as another + iterator instance, otherwise returns true. + */ + bool operator!= (const MidiBufferIterator& other) const noexcept { return ! operator== (other); } + + /** Return an instance of MidiMessageMetadata which describes the message to which + the iterator is currently pointing. + */ + reference operator*() const noexcept; + +private: + Ptr data = nullptr; +}; + //============================================================================== /** Holds a sequence of time-stamped midi events. @@ -44,20 +146,11 @@ class JUCE_API MidiBuffer public: //============================================================================== /** Creates an empty MidiBuffer. */ - MidiBuffer() noexcept; + MidiBuffer() noexcept = default; /** Creates a MidiBuffer containing a single midi message. */ explicit MidiBuffer (const MidiMessage& message) noexcept; - /** Creates a copy of another MidiBuffer. */ - MidiBuffer (const MidiBuffer&) noexcept; - - /** Makes a copy of another MidiBuffer. */ - MidiBuffer& operator= (const MidiBuffer&) noexcept; - - /** Destructor */ - ~MidiBuffer(); - //============================================================================== /** Removes all events from the buffer. */ void clear() noexcept; @@ -70,7 +163,7 @@ public: void clear (int start, int numSamples); /** Returns true if the buffer is empty. - To actually retrieve the events, use a MidiBuffer::Iterator object + To actually retrieve the events, use a MidiBufferIterator object */ bool isEmpty() const noexcept; @@ -91,7 +184,7 @@ public: If an event is added whose sample position is the same as one or more events already in the buffer, the new event will be placed after the existing ones. - To retrieve events, use a MidiBuffer::Iterator object + To retrieve events, use a MidiBufferIterator object */ void addEvent (const MidiMessage& midiMessage, int sampleNumber); @@ -109,7 +202,7 @@ public: it'll actually only store 3 bytes. If the midi data is invalid, it might not add an event at all. - To retrieve events, use a MidiBuffer::Iterator object + To retrieve events, use a MidiBufferIterator object */ void addEvent (const void* rawMidiData, int maxBytesOfMidiData, @@ -158,6 +251,23 @@ public: */ void ensureSize (size_t minimumNumBytes); + /** Get a read-only iterator pointing to the beginning of this buffer. */ + MidiBufferIterator begin() const noexcept { return cbegin(); } + + /** Get a read-only iterator pointing one past the end of this buffer. */ + MidiBufferIterator end() const noexcept { return cend(); } + + /** Get a read-only iterator pointing to the beginning of this buffer. */ + MidiBufferIterator cbegin() const noexcept { return MidiBufferIterator (data.begin()); } + + /** Get a read-only iterator pointing one past the end of this buffer. */ + MidiBufferIterator cend() const noexcept { return MidiBufferIterator (data.end()); } + + /** Get an iterator pointing to the first event with a timestamp greater-than or + equal-to `samplePosition`. + */ + MidiBufferIterator findNextSamplePosition (int samplePosition) const noexcept; + //============================================================================== /** Used to iterate through the events in a MidiBuffer. @@ -171,8 +281,10 @@ public: { public: //============================================================================== - /** Creates an Iterator for this MidiBuffer. */ - Iterator (const MidiBuffer&) noexcept; + /** Creates an Iterator for this MidiBuffer. + This class has been deprecated in favour of MidiBufferIterator. + */ + JUCE_DEPRECATED (Iterator (const MidiBuffer&) noexcept); /** Creates a copy of an iterator. */ Iterator (const Iterator&) = default; @@ -218,7 +330,7 @@ public: private: //============================================================================== const MidiBuffer& buffer; - const uint8* data; + MidiBufferIterator iterator; }; /** The raw data holding this buffer. diff --git a/modules/juce_audio_basics/midi/juce_MidiFile.cpp b/modules/juce_audio_basics/midi/juce_MidiFile.cpp index 58cbf7c9..a4cd2796 100644 --- a/modules/juce_audio_basics/midi/juce_MidiFile.cpp +++ b/modules/juce_audio_basics/midi/juce_MidiFile.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -46,23 +46,77 @@ namespace MidiFileHelpers } } - static bool parseMidiHeader (const uint8* &data, short& timeFormat, short& fileType, short& numberOfTracks) noexcept + template <typename Value> + struct Optional { - auto ch = ByteOrder::bigEndianInt (data); - data += 4; + Optional() = default; - if (ch != ByteOrder::bigEndianInt ("MThd")) + Optional (const Value& v) + : value (v), valid (true) {} + + Value value = Value(); + bool valid = false; + }; + + template <typename Integral> + struct ReadTrait; + + template <> + struct ReadTrait<uint32> { static constexpr auto read = ByteOrder::bigEndianInt; }; + + template <> + struct ReadTrait<uint16> { static constexpr auto read = ByteOrder::bigEndianShort; }; + + template <typename Integral> + Optional<Integral> tryRead (const uint8*& data, size_t& remaining) + { + using Trait = ReadTrait<Integral>; + constexpr auto size = sizeof (Integral); + + if (remaining < size) + return {}; + + const Optional<Integral> result { Trait::read (data) }; + + data += size; + remaining -= size; + + return result; + } + + struct HeaderDetails + { + size_t bytesRead = 0; + short timeFormat = 0; + short fileType = 0; + short numberOfTracks = 0; + }; + + static Optional<HeaderDetails> parseMidiHeader (const uint8* const initialData, + const size_t maxSize) + { + auto* data = initialData; + auto remaining = maxSize; + + auto ch = tryRead<uint32> (data, remaining); + + if (! ch.valid) + return {}; + + if (ch.value != ByteOrder::bigEndianInt ("MThd")) { - bool ok = false; + auto ok = false; - if (ch == ByteOrder::bigEndianInt ("RIFF")) + if (ch.value == ByteOrder::bigEndianInt ("RIFF")) { for (int i = 0; i < 8; ++i) { - ch = ByteOrder::bigEndianInt (data); - data += 4; + ch = tryRead<uint32> (data, remaining); + + if (! ch.valid) + return {}; - if (ch == ByteOrder::bigEndianInt ("MThd")) + if (ch.value == ByteOrder::bigEndianInt ("MThd")) { ok = true; break; @@ -71,21 +125,37 @@ namespace MidiFileHelpers } if (! ok) - return false; + return {}; } - auto bytesRemaining = ByteOrder::bigEndianInt (data); - data += 4; - fileType = (short) ByteOrder::bigEndianShort (data); - data += 2; - numberOfTracks = (short) ByteOrder::bigEndianShort (data); - data += 2; - timeFormat = (short) ByteOrder::bigEndianShort (data); - data += 2; - bytesRemaining -= 6; - data += bytesRemaining; - - return true; + const auto bytesRemaining = tryRead<uint32> (data, remaining); + + if (! bytesRemaining.valid || bytesRemaining.value > remaining) + return {}; + + const auto optFileType = tryRead<uint16> (data, remaining); + + if (! optFileType.valid || 2 < optFileType.value) + return {}; + + const auto optNumTracks = tryRead<uint16> (data, remaining); + + if (! optNumTracks.valid || (optFileType.value == 0 && optNumTracks.value != 1)) + return {}; + + const auto optTimeFormat = tryRead<uint16> (data, remaining); + + if (! optTimeFormat.valid) + return {}; + + HeaderDetails result; + + result.fileType = (short) optFileType.value; + result.timeFormat = (short) optTimeFormat.value; + result.numberOfTracks = (short) optNumTracks.value; + result.bytesRead = maxSize - remaining; + + return { result }; } static double convertTicksToSeconds (double time, @@ -149,6 +219,47 @@ namespace MidiFileHelpers } } } + + static MidiMessageSequence readTrack (const uint8* data, int size) + { + double time = 0; + uint8 lastStatusByte = 0; + + MidiMessageSequence result; + + while (size > 0) + { + const auto delay = MidiMessage::readVariableLengthValue (data, (int) size); + + if (delay.bytesUsed == 0) + break; + + data += delay.bytesUsed; + size -= delay.bytesUsed; + time += delay.value; + + if (size <= 0) + break; + + int messSize = 0; + const MidiMessage mm (data, size, messSize, lastStatusByte, time); + + if (messSize <= 0) + break; + + size -= messSize; + data += messSize; + + result.addEvent (mm); + + auto firstByte = *(mm.getRawData()); + + if ((firstByte & 0xf0) != 0xf0) + lastStatusByte = firstByte; + } + + return result; + } } //============================================================================== @@ -253,78 +364,56 @@ bool MidiFile::readFrom (InputStream& sourceStream, bool createMatchingNoteOffs) const int maxSensibleMidiFileSize = 200 * 1024 * 1024; // (put a sanity-check on the file size, as midi files are generally small) - if (sourceStream.readIntoMemoryBlock (data, maxSensibleMidiFileSize)) - { - auto size = data.getSize(); - auto d = static_cast<const uint8*> (data.getData()); - short fileType, expectedTracks; - - if (size > 16 && MidiFileHelpers::parseMidiHeader (d, timeFormat, fileType, expectedTracks)) - { - size -= (size_t) (d - static_cast<const uint8*> (data.getData())); - int track = 0; - - for (;;) - { - auto chunkType = (int) ByteOrder::bigEndianInt (d); - d += 4; - auto chunkSize = (int) ByteOrder::bigEndianInt (d); - d += 4; + if (! sourceStream.readIntoMemoryBlock (data, maxSensibleMidiFileSize)) + return false; - if (chunkSize <= 0 || (size_t) chunkSize > size) - break; + auto size = data.getSize(); + auto d = static_cast<const uint8*> (data.getData()); - if (chunkType == (int) ByteOrder::bigEndianInt ("MTrk")) - readNextTrack (d, chunkSize, createMatchingNoteOffs); + const auto optHeader = MidiFileHelpers::parseMidiHeader (d, size); - if (++track >= expectedTracks) - break; + if (! optHeader.valid) + return false; - size -= (size_t) chunkSize + 8; - d += chunkSize; - } + const auto header = optHeader.value; + timeFormat = header.timeFormat; - return true; - } - } + d += header.bytesRead; + size -= (size_t) header.bytesRead; - return false; -} + for (int track = 0; track < header.numberOfTracks; ++track) + { + const auto optChunkType = MidiFileHelpers::tryRead<uint32> (d, size); -void MidiFile::readNextTrack (const uint8* data, int size, bool createMatchingNoteOffs) -{ - double time = 0; - uint8 lastStatusByte = 0; + if (! optChunkType.valid) + return false; - MidiMessageSequence result; + const auto optChunkSize = MidiFileHelpers::tryRead<uint32> (d, size); - while (size > 0) - { - int bytesUsed; - auto delay = MidiMessage::readVariableLengthVal (data, bytesUsed); - data += bytesUsed; - size -= bytesUsed; - time += delay; + if (! optChunkSize.valid) + return false; - int messSize = 0; - const MidiMessage mm (data, size, messSize, lastStatusByte, time); + const auto chunkSize = optChunkSize.value; - if (messSize <= 0) - break; + if (size < chunkSize) + return false; - size -= messSize; - data += messSize; + if (optChunkType.value == ByteOrder::bigEndianInt ("MTrk")) + readNextTrack (d, (int) chunkSize, createMatchingNoteOffs); - result.addEvent (mm); + size -= chunkSize; + d += chunkSize; + } - auto firstByte = *(mm.getRawData()); + return size == 0; +} - if ((firstByte & 0xf0) != 0xf0) - lastStatusByte = firstByte; - } +void MidiFile::readNextTrack (const uint8* data, int size, bool createMatchingNoteOffs) +{ + auto sequence = MidiFileHelpers::readTrack (data, size); // sort so that we put all the note-offs before note-ons that have the same time - std::stable_sort (result.list.begin(), result.list.end(), + std::stable_sort (sequence.list.begin(), sequence.list.end(), [] (const MidiMessageSequence::MidiEventHolder* a, const MidiMessageSequence::MidiEventHolder* b) { @@ -337,10 +426,10 @@ void MidiFile::readNextTrack (const uint8* data, int size, bool createMatchingNo return a->message.isNoteOff() && b->message.isNoteOn(); }); - addTrack (result); - if (createMatchingNoteOffs) - tracks.getLast()->updateMatchedPairs(); + sequence.updateMatchedPairs(); + + addTrack (sequence); } //============================================================================== @@ -443,4 +532,267 @@ bool MidiFile::writeTrack (OutputStream& mainOut, const MidiMessageSequence& ms) return true; } +//============================================================================== +//============================================================================== +#if JUCE_UNIT_TESTS + +struct MidiFileTest : public UnitTest +{ + MidiFileTest() + : UnitTest ("MidiFile", UnitTestCategories::midi) + {} + + void runTest() override + { + beginTest ("ReadTrack respects running status"); + { + const auto sequence = parseSequence ([] (OutputStream& os) + { + MidiFileHelpers::writeVariableLengthInt (os, 100); + writeBytes (os, { 0x90, 0x40, 0x40 }); + MidiFileHelpers::writeVariableLengthInt (os, 200); + writeBytes (os, { 0x40, 0x40 }); + MidiFileHelpers::writeVariableLengthInt (os, 300); + writeBytes (os, { 0xff, 0x2f, 0x00 }); + }); + + expectEquals (sequence.getNumEvents(), 3); + expect (sequence.getEventPointer (0)->message.isNoteOn()); + expect (sequence.getEventPointer (1)->message.isNoteOn()); + expect (sequence.getEventPointer (2)->message.isEndOfTrackMetaEvent()); + } + + beginTest ("ReadTrack returns available messages if input is truncated"); + { + { + const auto sequence = parseSequence ([] (OutputStream& os) + { + // Incomplete delta time + writeBytes (os, { 0xff }); + }); + + expectEquals (sequence.getNumEvents(), 0); + } + + { + const auto sequence = parseSequence ([] (OutputStream& os) + { + // Complete delta with no following event + MidiFileHelpers::writeVariableLengthInt (os, 0xffff); + }); + + expectEquals (sequence.getNumEvents(), 0); + } + + { + const auto sequence = parseSequence ([] (OutputStream& os) + { + // Complete delta with malformed following event + MidiFileHelpers::writeVariableLengthInt (os, 0xffff); + writeBytes (os, { 0x90, 0x40 }); + }); + + expectEquals (sequence.getNumEvents(), 1); + expect (sequence.getEventPointer (0)->message.isNoteOff()); + expectEquals (sequence.getEventPointer (0)->message.getNoteNumber(), 0x40); + expectEquals (sequence.getEventPointer (0)->message.getVelocity(), (uint8) 0x00); + } + } + + beginTest ("Header parsing works"); + { + { + // No data + const auto header = parseHeader ([] (OutputStream&) {}); + expect (! header.valid); + } + + { + // Invalid initial byte + const auto header = parseHeader ([] (OutputStream& os) + { + writeBytes (os, { 0xff }); + }); + + expect (! header.valid); + } + + { + // Type block, but no header data + const auto header = parseHeader ([] (OutputStream& os) + { + writeBytes (os, { 'M', 'T', 'h', 'd' }); + }); + + expect (! header.valid); + } + + { + // We (ll-formed header, but track type is 0 and channels != 1 + const auto header = parseHeader ([] (OutputStream& os) + { + writeBytes (os, { 'M', 'T', 'h', 'd', 0, 0, 0, 6, 0, 0, 0, 16, 0, 1 }); + }); + + expect (! header.valid); + } + + { + // Well-formed header, but track type is 5 + const auto header = parseHeader ([] (OutputStream& os) + { + writeBytes (os, { 'M', 'T', 'h', 'd', 0, 0, 0, 6, 0, 5, 0, 16, 0, 1 }); + }); + + expect (! header.valid); + } + + { + // Well-formed header + const auto header = parseHeader ([] (OutputStream& os) + { + writeBytes (os, { 'M', 'T', 'h', 'd', 0, 0, 0, 6, 0, 1, 0, 16, 0, 1 }); + }); + + expect (header.valid); + + expectEquals (header.value.fileType, (short) 1); + expectEquals (header.value.numberOfTracks, (short) 16); + expectEquals (header.value.timeFormat, (short) 1); + expectEquals ((int) header.value.bytesRead, 14); + } + } + + beginTest ("Read from stream"); + { + { + // Empty input + const auto file = parseFile ([] (OutputStream&) {}); + expect (! file.valid); + } + + { + // Malformed header + const auto file = parseFile ([] (OutputStream& os) + { + writeBytes (os, { 'M', 'T', 'h', 'd' }); + }); + + expect (! file.valid); + } + + { + // Header, no channels + const auto file = parseFile ([] (OutputStream& os) + { + writeBytes (os, { 'M', 'T', 'h', 'd', 0, 0, 0, 6, 0, 1, 0, 0, 0, 1 }); + }); + + expect (file.valid); + expectEquals (file.value.getNumTracks(), 0); + } + + { + // Header, one malformed channel + const auto file = parseFile ([] (OutputStream& os) + { + writeBytes (os, { 'M', 'T', 'h', 'd', 0, 0, 0, 6, 0, 1, 0, 1, 0, 1 }); + writeBytes (os, { 'M', 'T', 'r', '?' }); + }); + + expect (! file.valid); + } + + { + // Header, one channel with malformed message + const auto file = parseFile ([] (OutputStream& os) + { + writeBytes (os, { 'M', 'T', 'h', 'd', 0, 0, 0, 6, 0, 1, 0, 1, 0, 1 }); + writeBytes (os, { 'M', 'T', 'r', 'k', 0, 0, 0, 1, 0xff }); + }); + + expect (file.valid); + expectEquals (file.value.getNumTracks(), 1); + expectEquals (file.value.getTrack (0)->getNumEvents(), 0); + } + + { + // Header, one channel with incorrect length message + const auto file = parseFile ([] (OutputStream& os) + { + writeBytes (os, { 'M', 'T', 'h', 'd', 0, 0, 0, 6, 0, 1, 0, 1, 0, 1 }); + writeBytes (os, { 'M', 'T', 'r', 'k', 0x0f, 0, 0, 0, 0xff }); + }); + + expect (! file.valid); + } + + { + // Header, one channel, all well-formed + const auto file = parseFile ([] (OutputStream& os) + { + writeBytes (os, { 'M', 'T', 'h', 'd', 0, 0, 0, 6, 0, 1, 0, 1, 0, 1 }); + writeBytes (os, { 'M', 'T', 'r', 'k', 0, 0, 0, 4 }); + + MidiFileHelpers::writeVariableLengthInt (os, 0x0f); + writeBytes (os, { 0x80, 0x00, 0x00 }); + }); + + expect (file.valid); + expectEquals (file.value.getNumTracks(), 1); + + auto& track = *file.value.getTrack (0); + expectEquals (track.getNumEvents(), 1); + expect (track.getEventPointer (0)->message.isNoteOff()); + expectEquals (track.getEventPointer (0)->message.getTimeStamp(), (double) 0x0f); + } + } + } + + template <typename Fn> + static MidiMessageSequence parseSequence (Fn&& fn) + { + MemoryOutputStream os; + fn (os); + + return MidiFileHelpers::readTrack (reinterpret_cast<const uint8*> (os.getData()), + (int) os.getDataSize()); + } + + template <typename Fn> + static MidiFileHelpers::Optional<MidiFileHelpers::HeaderDetails> parseHeader (Fn&& fn) + { + MemoryOutputStream os; + fn (os); + + return MidiFileHelpers::parseMidiHeader (reinterpret_cast<const uint8*> (os.getData()), + os.getDataSize()); + } + + template <typename Fn> + static MidiFileHelpers::Optional<MidiFile> parseFile (Fn&& fn) + { + MemoryOutputStream os; + fn (os); + + MemoryInputStream is (os.getData(), os.getDataSize(), false); + MidiFile mf; + + if (mf.readFrom (is)) + return mf; + + return {}; + } + + static void writeBytes (OutputStream& os, const std::vector<uint8>& bytes) + { + for (const auto& byte : bytes) + os.writeByte ((char) byte); + } +}; + +static MidiFileTest midiFileTests; + +#endif + } // namespace juce diff --git a/modules/juce_audio_basics/midi/juce_MidiFile.h b/modules/juce_audio_basics/midi/juce_MidiFile.h index 0f3f9f00..3ab4229a 100644 --- a/modules/juce_audio_basics/midi/juce_MidiFile.h +++ b/modules/juce_audio_basics/midi/juce_MidiFile.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/midi/juce_MidiKeyboardState.cpp b/modules/juce_audio_basics/midi/juce_MidiKeyboardState.cpp index 68b8db06..8d9ad2cd 100644 --- a/modules/juce_audio_basics/midi/juce_MidiKeyboardState.cpp +++ b/modules/juce_audio_basics/midi/juce_MidiKeyboardState.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -75,10 +75,8 @@ void MidiKeyboardState::noteOnInternal (const int midiChannel, const int midiNo { if (isPositiveAndBelow (midiNoteNumber, 128)) { - noteStates [midiNoteNumber] |= (1 << (midiChannel - 1)); - - for (int i = listeners.size(); --i >= 0;) - listeners.getUnchecked(i)->handleNoteOn (this, midiChannel, midiNoteNumber, velocity); + noteStates[midiNoteNumber] = static_cast<uint16> (noteStates[midiNoteNumber] | (1 << (midiChannel - 1))); + listeners.call ([&] (Listener& l) { l.handleNoteOn (this, midiChannel, midiNoteNumber, velocity); }); } } @@ -100,10 +98,8 @@ void MidiKeyboardState::noteOffInternal (const int midiChannel, const int midiN { if (isNoteOn (midiChannel, midiNoteNumber)) { - noteStates [midiNoteNumber] &= ~(1 << (midiChannel - 1)); - - for (int i = listeners.size(); --i >= 0;) - listeners.getUnchecked(i)->handleNoteOff (this, midiChannel, midiNoteNumber, velocity); + noteStates[midiNoteNumber] = static_cast<uint16> (noteStates[midiNoteNumber] & ~(1 << (midiChannel - 1))); + listeners.call ([&] (Listener& l) { l.handleNoteOff (this, midiChannel, midiNoteNumber, velocity); }); } } @@ -145,25 +141,20 @@ void MidiKeyboardState::processNextMidiBuffer (MidiBuffer& buffer, const int numSamples, const bool injectIndirectEvents) { - MidiBuffer::Iterator i (buffer); - MidiMessage message; - int time; - const ScopedLock sl (lock); - while (i.getNextEvent (message, time)) - processNextMidiEvent (message); + for (const auto metadata : buffer) + processNextMidiEvent (metadata.getMessage()); if (injectIndirectEvents) { - MidiBuffer::Iterator i2 (eventsToAdd); const int firstEventToAdd = eventsToAdd.getFirstEventTime(); const double scaleFactor = numSamples / (double) (eventsToAdd.getLastEventTime() + 1 - firstEventToAdd); - while (i2.getNextEvent (message, time)) + for (const auto metadata : eventsToAdd) { - const int pos = jlimit (0, numSamples - 1, roundToInt ((time - firstEventToAdd) * scaleFactor)); - buffer.addEvent (message, startSample + pos); + const auto pos = jlimit (0, numSamples - 1, roundToInt ((metadata.samplePosition - firstEventToAdd) * scaleFactor)); + buffer.addEvent (metadata.getMessage(), startSample + pos); } } @@ -171,16 +162,16 @@ void MidiKeyboardState::processNextMidiBuffer (MidiBuffer& buffer, } //============================================================================== -void MidiKeyboardState::addListener (MidiKeyboardStateListener* const listener) +void MidiKeyboardState::addListener (Listener* listener) { const ScopedLock sl (lock); - listeners.addIfNotAlreadyThere (listener); + listeners.add (listener); } -void MidiKeyboardState::removeListener (MidiKeyboardStateListener* const listener) +void MidiKeyboardState::removeListener (Listener* listener) { const ScopedLock sl (lock); - listeners.removeFirstMatchingValue (listener); + listeners.remove (listener); } } // namespace juce diff --git a/modules/juce_audio_basics/midi/juce_MidiKeyboardState.h b/modules/juce_audio_basics/midi/juce_MidiKeyboardState.h index 47aaf692..61011dd6 100644 --- a/modules/juce_audio_basics/midi/juce_MidiKeyboardState.h +++ b/modules/juce_audio_basics/midi/juce_MidiKeyboardState.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -23,51 +23,6 @@ namespace juce { -class MidiKeyboardState; - - -//============================================================================== -/** - Receives events from a MidiKeyboardState object. - - @see MidiKeyboardState - - @tags{Audio} -*/ -class JUCE_API MidiKeyboardStateListener -{ -public: - //============================================================================== - MidiKeyboardStateListener() = default; - virtual ~MidiKeyboardStateListener() = default; - - //============================================================================== - /** Called when one of the MidiKeyboardState's keys is pressed. - - This will be called synchronously when the state is either processing a - buffer in its MidiKeyboardState::processNextMidiBuffer() method, or - when a note is being played with its MidiKeyboardState::noteOn() method. - - Note that this callback could happen from an audio callback thread, so be - careful not to block, and avoid any UI activity in the callback. - */ - virtual void handleNoteOn (MidiKeyboardState* source, - int midiChannel, int midiNoteNumber, float velocity) = 0; - - /** Called when one of the MidiKeyboardState's keys is released. - - This will be called synchronously when the state is either processing a - buffer in its MidiKeyboardState::processNextMidiBuffer() method, or - when a note is being played with its MidiKeyboardState::noteOff() method. - - Note that this callback could happen from an audio callback thread, so be - careful not to block, and avoid any UI activity in the callback. - */ - virtual void handleNoteOff (MidiKeyboardState* source, - int midiChannel, int midiNoteNumber, float velocity) = 0; -}; - - //============================================================================== /** Represents a piano keyboard, keeping track of which keys are currently pressed. @@ -180,27 +135,62 @@ public: bool injectIndirectEvents); //============================================================================== + /** Receives events from a MidiKeyboardState object. */ + class JUCE_API Listener + { + public: + //============================================================================== + virtual ~Listener() = default; + + //============================================================================== + /** Called when one of the MidiKeyboardState's keys is pressed. + + This will be called synchronously when the state is either processing a + buffer in its MidiKeyboardState::processNextMidiBuffer() method, or + when a note is being played with its MidiKeyboardState::noteOn() method. + + Note that this callback could happen from an audio callback thread, so be + careful not to block, and avoid any UI activity in the callback. + */ + virtual void handleNoteOn (MidiKeyboardState* source, + int midiChannel, int midiNoteNumber, float velocity) = 0; + + /** Called when one of the MidiKeyboardState's keys is released. + + This will be called synchronously when the state is either processing a + buffer in its MidiKeyboardState::processNextMidiBuffer() method, or + when a note is being played with its MidiKeyboardState::noteOff() method. + + Note that this callback could happen from an audio callback thread, so be + careful not to block, and avoid any UI activity in the callback. + */ + virtual void handleNoteOff (MidiKeyboardState* source, + int midiChannel, int midiNoteNumber, float velocity) = 0; + }; + /** Registers a listener for callbacks when keys go up or down. @see removeListener */ - void addListener (MidiKeyboardStateListener* listener); + void addListener (Listener* listener); /** Deregisters a listener. @see addListener */ - void removeListener (MidiKeyboardStateListener* listener); + void removeListener (Listener* listener); private: //============================================================================== CriticalSection lock; - uint16 noteStates [128]; + std::atomic<uint16> noteStates[128]; MidiBuffer eventsToAdd; - Array <MidiKeyboardStateListener*> listeners; + ListenerList<Listener> listeners; - void noteOnInternal (int midiChannel, int midiNoteNumber, float velocity); + void noteOnInternal (int midiChannel, int midiNoteNumber, float velocity); void noteOffInternal (int midiChannel, int midiNoteNumber, float velocity); JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiKeyboardState) }; +using MidiKeyboardStateListener = MidiKeyboardState::Listener; + } // namespace juce diff --git a/modules/juce_audio_basics/midi/juce_MidiMessage.cpp b/modules/juce_audio_basics/midi/juce_MidiMessage.cpp index 9ccccfac..c9513ee6 100644 --- a/modules/juce_audio_basics/midi/juce_MidiMessage.cpp +++ b/modules/juce_audio_basics/midi/juce_MidiMessage.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -57,6 +57,32 @@ uint16 MidiMessage::pitchbendToPitchwheelPos (const float pitchbend, } //============================================================================== +MidiMessage::VariableLengthValue MidiMessage::readVariableLengthValue (const uint8* data, int maxBytesToUse) noexcept +{ + uint32 v = 0; + + // The largest allowable variable-length value is 0x0f'ff'ff'ff which is + // represented by the 4-byte stream 0xff 0xff 0xff 0x7f. + // Longer bytestreams risk overflowing a 32-bit signed int. + const auto limit = jmin (maxBytesToUse, 4); + + for (int numBytesUsed = 0; numBytesUsed < limit; ++numBytesUsed) + { + const auto i = data[numBytesUsed]; + v = (v << 7) + (i & 0x7f); + + if (! (i & 0x80)) + return { (int) v, numBytesUsed + 1 }; + } + + // If this is hit, the input was malformed. Either there were not enough + // bytes of input to construct a full value, or no terminating byte was + // found. This implementation only supports variable-length values of up + // to four bytes. + jassertfalse; + return {}; +} + int MidiMessage::readVariableLengthVal (const uint8* data, int& numBytesUsed) noexcept { numBytesUsed = 0; @@ -224,16 +250,8 @@ MidiMessage::MidiMessage (const void* srcData, int sz, int& numBytesUsed, const } else if (byte == 0xff) { - if (sz == 1) - { - size = 1; - } - else - { - int n; - const int bytesLeft = readVariableLengthVal (src + 1, n); - size = jmin (sz + 1, n + 2 + bytesLeft); - } + const auto bytesLeft = readVariableLengthValue (src + 1, sz - 1); + size = jmin (sz + 1, bytesLeft.bytesUsed + 2 + bytesLeft.value); auto dest = allocateSpace (size); *dest = (uint8) byte; @@ -682,7 +700,7 @@ bool MidiMessage::isActiveSense() const noexcept { return *getRawData() == 0x int MidiMessage::getMetaEventType() const noexcept { auto data = getRawData(); - return *data != 0xff ? -1 : data[1]; + return (size < 2 || *data != 0xff) ? -1 : data[1]; } int MidiMessage::getMetaEventLength() const noexcept @@ -691,8 +709,8 @@ int MidiMessage::getMetaEventLength() const noexcept if (*data == 0xff) { - int n; - return jmin (size - 2, readVariableLengthVal (data + 2, n)); + const auto var = readVariableLengthValue (data + 2, size - 2); + return jmax (0, jmin (size - 2 - var.bytesUsed, var.value)); } return 0; @@ -702,10 +720,9 @@ const uint8* MidiMessage::getMetaEventData() const noexcept { jassert (isMetaEvent()); - int n; auto d = getRawData() + 2; - readVariableLengthVal (d, n); - return d + n; + const auto var = readVariableLengthValue (d, size - 2); + return d + var.bytesUsed; } bool MidiMessage::isTrackMetaEvent() const noexcept { return getMetaEventType() == 0; } @@ -1141,4 +1158,170 @@ const char* MidiMessage::getControllerName (const int n) return isPositiveAndBelow (n, numElementsInArray (names)) ? names[n] : nullptr; } +//============================================================================== +//============================================================================== +#if JUCE_UNIT_TESTS + +struct MidiMessageTest : public UnitTest +{ + MidiMessageTest() + : UnitTest ("MidiMessage", UnitTestCategories::midi) + {} + + void runTest() override + { + using std::begin; + using std::end; + + beginTest ("ReadVariableLengthValue should return valid, backward-compatible results"); + { + const std::vector<uint8> inputs[] + { + { 0x00 }, + { 0x40 }, + { 0x7f }, + { 0x81, 0x00 }, + { 0xc0, 0x00 }, + { 0xff, 0x7f }, + { 0x81, 0x80, 0x00 }, + { 0xc0, 0x80, 0x00 }, + { 0xff, 0xff, 0x7f }, + { 0x81, 0x80, 0x80, 0x00 }, + { 0xc0, 0x80, 0x80, 0x00 }, + { 0xff, 0xff, 0xff, 0x7f } + }; + + const int outputs[] + { + 0x00, + 0x40, + 0x7f, + 0x80, + 0x2000, + 0x3fff, + 0x4000, + 0x100000, + 0x1fffff, + 0x200000, + 0x8000000, + 0xfffffff, + }; + + expectEquals (std::distance (begin (inputs), end (inputs)), + std::distance (begin (outputs), end (outputs))); + + size_t index = 0; + + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wdeprecated-declarations") + JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4996) + + for (const auto& input : inputs) + { + auto copy = input; + + while (copy.size() < 16) + copy.push_back (0); + + const auto result = MidiMessage::readVariableLengthValue (copy.data(), + (int) copy.size()); + + expectEquals (result.value, outputs[index]); + expectEquals (result.bytesUsed, (int) inputs[index].size()); + + int legacyNumUsed = 0; + const auto legacyResult = MidiMessage::readVariableLengthVal (copy.data(), + legacyNumUsed); + + expectEquals (result.value, legacyResult); + expectEquals (result.bytesUsed, legacyNumUsed); + + ++index; + } + + JUCE_END_IGNORE_WARNINGS_GCC_LIKE + JUCE_END_IGNORE_WARNINGS_MSVC + } + + beginTest ("ReadVariableLengthVal should return 0 if input is truncated"); + { + for (size_t i = 0; i != 16; ++i) + { + std::vector<uint8> input; + input.resize (i, 0xFF); + + const auto result = MidiMessage::readVariableLengthValue (input.data(), + (int) input.size()); + + expectEquals (result.value, 0); + expectEquals (result.bytesUsed, 0); + } + } + + const std::vector<uint8> metaEvents[] + { + // Format is 0xff, followed by a 'kind' byte, followed by a variable-length + // 'data-length' value, followed by that many data bytes + { 0xff, 0x00, 0x02, 0x00, 0x00 }, // Sequence number + { 0xff, 0x01, 0x00 }, // Text event + { 0xff, 0x02, 0x00 }, // Copyright notice + { 0xff, 0x03, 0x00 }, // Track name + { 0xff, 0x04, 0x00 }, // Instrument name + { 0xff, 0x05, 0x00 }, // Lyric + { 0xff, 0x06, 0x00 }, // Marker + { 0xff, 0x07, 0x00 }, // Cue point + { 0xff, 0x20, 0x01, 0x00 }, // Channel prefix + { 0xff, 0x2f, 0x00 }, // End of track + { 0xff, 0x51, 0x03, 0x01, 0x02, 0x03 }, // Set tempo + { 0xff, 0x54, 0x05, 0x01, 0x02, 0x03, 0x04, 0x05 }, // SMPTE offset + { 0xff, 0x58, 0x04, 0x01, 0x02, 0x03, 0x04 }, // Time signature + { 0xff, 0x59, 0x02, 0x01, 0x02 }, // Key signature + { 0xff, 0x7f, 0x00 }, // Sequencer-specific + }; + + beginTest ("MidiMessage data constructor works for well-formed meta-events"); + { + const auto status = (uint8) 0x90; + + for (const auto& input : metaEvents) + { + int bytesUsed = 0; + const MidiMessage msg (input.data(), (int) input.size(), bytesUsed, status); + + expect (msg.isMetaEvent()); + expectEquals (msg.getMetaEventLength(), (int) input.size() - 3); + expectEquals (msg.getMetaEventType(), (int) input[1]); + } + } + + beginTest ("MidiMessage data constructor works for malformed meta-events"); + { + const auto status = (uint8) 0x90; + + const auto runTest = [&] (const std::vector<uint8>& input) + { + int bytesUsed = 0; + const MidiMessage msg (input.data(), (int) input.size(), bytesUsed, status); + + expect (msg.isMetaEvent()); + expectEquals (msg.getMetaEventLength(), jmax (0, (int) input.size() - 3)); + expectEquals (msg.getMetaEventType(), input.size() >= 2 ? input[1] : -1); + }; + + runTest ({ 0xff }); + + for (const auto& input : metaEvents) + { + auto copy = input; + copy[2] = 0x40; // Set the size of the message to more bytes than are present + + runTest (copy); + } + } + } +}; + +static MidiMessageTest midiMessageTests; + +#endif + } // namespace juce diff --git a/modules/juce_audio_basics/midi/juce_MidiMessage.h b/modules/juce_audio_basics/midi/juce_MidiMessage.h index 5628c3ae..d3370acc 100644 --- a/modules/juce_audio_basics/midi/juce_MidiMessage.h +++ b/modules/juce_audio_basics/midi/juce_MidiMessage.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -401,7 +401,7 @@ public: /** Returns true if the message is an aftertouch event. For aftertouch events, use the getNoteNumber() method to find out the key - that it applies to, and getAftertouchValue() to find out the amount. Use + that it applies to, and getAfterTouchValue() to find out the amount. Use getChannel() to find out the channel. @see getAftertouchValue, getNoteNumber @@ -858,11 +858,43 @@ public: //============================================================================== /** Reads a midi variable-length integer. + This signature has been deprecated in favour of the safer + readVariableLengthValue. + + The `data` argument indicates the data to read the number from, + and `numBytesUsed` is used as an out-parameter to indicate the number + of bytes that were read. + */ + JUCE_DEPRECATED (static int readVariableLengthVal (const uint8* data, + int& numBytesUsed) noexcept); + + /** Holds information about a variable-length value which was parsed + from a stream of bytes. + + A valid value requires that `bytesUsed` is greater than 0. + If `bytesUsed <= 0` this object should be considered invalid. + */ + struct VariableLengthValue + { + VariableLengthValue() = default; + + VariableLengthValue (int valueIn, int bytesUsedIn) + : value (valueIn), bytesUsed (bytesUsedIn) {} + + int value = 0; + int bytesUsed = 0; + }; + + /** Reads a midi variable-length integer, with protection against buffer overflow. + @param data the data to read the number from - @param numBytesUsed on return, this will be set to the number of bytes that were read + @param maxBytesToUse the number of bytes in the region following `data` + @returns a struct containing the parsed value, and the number + of bytes that were read. If parsing fails, both the + `value` and `bytesUsed` fields will be set to 0. */ - static int readVariableLengthVal (const uint8* data, - int& numBytesUsed) noexcept; + static VariableLengthValue readVariableLengthValue (const uint8* data, + int maxBytesToUse) noexcept; /** Based on the first byte of a short midi message, this uses a lookup table to return the message length (either 1, 2, or 3 bytes). diff --git a/modules/juce_audio_basics/midi/juce_MidiMessageSequence.cpp b/modules/juce_audio_basics/midi/juce_MidiMessageSequence.cpp index d74aa583..6759568c 100644 --- a/modules/juce_audio_basics/midi/juce_MidiMessageSequence.cpp +++ b/modules/juce_audio_basics/midi/juce_MidiMessageSequence.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/midi/juce_MidiMessageSequence.h b/modules/juce_audio_basics/midi/juce_MidiMessageSequence.h index 5d4187ea..325de2ec 100644 --- a/modules/juce_audio_basics/midi/juce_MidiMessageSequence.h +++ b/modules/juce_audio_basics/midi/juce_MidiMessageSequence.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/midi/juce_MidiRPN.cpp b/modules/juce_audio_basics/midi/juce_MidiRPN.cpp index 10e8e03a..f1c3d24f 100644 --- a/modules/juce_audio_basics/midi/juce_MidiRPN.cpp +++ b/modules/juce_audio_basics/midi/juce_MidiRPN.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -351,14 +351,13 @@ private: //============================================================================== void expectContainsRPN (const MidiBuffer& midiBuffer, MidiRPNMessage expected) { - MidiBuffer::Iterator iter (midiBuffer); - MidiMessage midiMessage; MidiRPNMessage result = MidiRPNMessage(); MidiRPNDetector detector; - int samplePosition; // not actually used, so no need to initialise. - while (iter.getNextEvent (midiMessage, samplePosition)) + for (const auto metadata : midiBuffer) { + const auto midiMessage = metadata.getMessage(); + if (detector.parseControllerMessage (midiMessage.getChannel(), midiMessage.getControllerNumber(), midiMessage.getControllerValue(), diff --git a/modules/juce_audio_basics/midi/juce_MidiRPN.h b/modules/juce_audio_basics/midi/juce_MidiRPN.h index 869afac7..dcf0ec47 100644 --- a/modules/juce_audio_basics/midi/juce_MidiRPN.h +++ b/modules/juce_audio_basics/midi/juce_MidiRPN.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/mpe/juce_MPEInstrument.cpp b/modules/juce_audio_basics/mpe/juce_MPEInstrument.cpp index df2e4660..aa155bcf 100644 --- a/modules/juce_audio_basics/mpe/juce_MPEInstrument.cpp +++ b/modules/juce_audio_basics/mpe/juce_MPEInstrument.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -336,8 +336,8 @@ void MPEInstrument::noteOff (int midiChannel, note->keyState = (note->keyState == MPENote::keyDownAndSustained) ? MPENote::sustained : MPENote::off; note->noteOffVelocity = midiNoteOffVelocity; - // If no more notes are playing on this channel, reset the dimension values - if (getLastNotePlayedPtr (midiChannel) == nullptr) + // If no more notes are playing on this channel in mpe mode, reset the dimension values + if (! legacyMode.isEnabled && getLastNotePlayedPtr (midiChannel) == nullptr) { pressureDimension.lastValueReceivedOnChannel[midiChannel - 1] = MPEValue::minValue(); pitchbendDimension.lastValueReceivedOnChannel[midiChannel - 1] = MPEValue::centreValue(); @@ -395,7 +395,7 @@ void MPEInstrument::polyAftertouch (int midiChannel, int midiNoteNumber, MPEValu MPEValue MPEInstrument::getInitialValueForNewNote (int midiChannel, MPEDimension& dimension) const { - if (getLastNotePlayedPtr (midiChannel) != nullptr) + if (! legacyMode.isEnabled && getLastNotePlayedPtr (midiChannel) != nullptr) return &dimension == &pressureDimension ? MPEValue::minValue() : MPEValue::centreValue(); return dimension.lastValueReceivedOnChannel[midiChannel - 1]; @@ -491,17 +491,19 @@ void MPEInstrument::updateNoteTotalPitchbend (MPENote& note) { if (legacyMode.isEnabled) { - note.totalPitchbendInSemitones = note.pitchbend.asSignedFloat() * legacyMode.pitchbendRange; + note.totalPitchbendInSemitones = note.pitchbend.asSignedFloat() * (float) legacyMode.pitchbendRange; } else { auto zone = zoneLayout.getLowerZone(); - if (! zone.isUsing (note.midiChannel)) + if (! zone.isActive() || ! zone.isUsing (note.midiChannel)) { - if (zoneLayout.getUpperZone().isUsing (note.midiChannel)) + auto upperZone = zoneLayout.getUpperZone(); + + if (upperZone.isActive() && upperZone.isUsing (note.midiChannel)) { - zone = zoneLayout.getUpperZone(); + zone = upperZone; } else { @@ -514,11 +516,11 @@ void MPEInstrument::updateNoteTotalPitchbend (MPENote& note) auto notePitchbendInSemitones = 0.0f; if (zone.isUsingChannelAsMemberChannel (note.midiChannel)) - notePitchbendInSemitones = note.pitchbend.asSignedFloat() * zone.perNotePitchbendRange; + notePitchbendInSemitones = note.pitchbend.asSignedFloat() * (float) zone.perNotePitchbendRange; auto masterPitchbendInSemitones = pitchbendDimension.lastValueReceivedOnChannel[zone.getMasterChannel() - 1] .asSignedFloat() - * zone.masterPitchbendRange; + * (float) zone.masterPitchbendRange; note.totalPitchbendInSemitones = notePitchbendInSemitones + masterPitchbendInSemitones; } @@ -576,11 +578,9 @@ void MPEInstrument::handleSustainOrSostenuto (int midiChannel, bool isDown, bool if (! isSostenuto) { - if (legacyMode.isEnabled) - { - isMemberChannelSustained[midiChannel - 1] = isDown; - } - else + isMemberChannelSustained[midiChannel - 1] = isDown; + + if (! legacyMode.isEnabled) { if (zone.isLowerZone()) for (auto i = zone.getFirstMemberChannel(); i <= zone.getLastMemberChannel(); ++i) @@ -1834,12 +1834,8 @@ public: buffer.addEvents (MPEMessages::setLowerZone (5), 0, -1, 0); buffer.addEvents (MPEMessages::setUpperZone (6), 0, -1, 0); - MidiBuffer::Iterator iter (buffer); - MidiMessage message; - int samplePosition; // not actually used, so no need to initialise. - - while (iter.getNextEvent (message, samplePosition)) - test.processNextMidiEvent (message); + for (const auto metadata : buffer) + test.processNextMidiEvent (metadata.getMessage()); expect (test.getZoneLayout().getLowerZone().isActive()); expect (test.getZoneLayout().getUpperZone().isActive()); diff --git a/modules/juce_audio_basics/mpe/juce_MPEInstrument.h b/modules/juce_audio_basics/mpe/juce_MPEInstrument.h index 91a0b2b3..26537025 100644 --- a/modules/juce_audio_basics/mpe/juce_MPEInstrument.h +++ b/modules/juce_audio_basics/mpe/juce_MPEInstrument.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/mpe/juce_MPEMessages.cpp b/modules/juce_audio_basics/mpe/juce_MPEMessages.cpp index 214df7cf..72b86d45 100644 --- a/modules/juce_audio_basics/mpe/juce_MPEMessages.cpp +++ b/modules/juce_audio_basics/mpe/juce_MPEMessages.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -216,14 +216,11 @@ private: void extractRawBinaryData (const MidiBuffer& midiBuffer, const uint8* bufferToCopyTo, std::size_t maxBytes) { std::size_t pos = 0; - MidiBuffer::Iterator iter (midiBuffer); - MidiMessage midiMessage; - int samplePosition; // Note: Not actually used, so no need to initialise. - while (iter.getNextEvent (midiMessage, samplePosition)) + for (const auto metadata : midiBuffer) { - const uint8* data = midiMessage.getRawData(); - std::size_t dataSize = (std::size_t) midiMessage.getRawDataSize(); + const uint8* data = metadata.data; + std::size_t dataSize = (std::size_t) metadata.numBytes; if (pos + dataSize > maxBytes) return; diff --git a/modules/juce_audio_basics/mpe/juce_MPEMessages.h b/modules/juce_audio_basics/mpe/juce_MPEMessages.h index 1275dacd..b27abcd3 100644 --- a/modules/juce_audio_basics/mpe/juce_MPEMessages.h +++ b/modules/juce_audio_basics/mpe/juce_MPEMessages.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/mpe/juce_MPENote.cpp b/modules/juce_audio_basics/mpe/juce_MPENote.cpp index 742c7786..32cd2988 100644 --- a/modules/juce_audio_basics/mpe/juce_MPENote.cpp +++ b/modules/juce_audio_basics/mpe/juce_MPENote.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/mpe/juce_MPENote.h b/modules/juce_audio_basics/mpe/juce_MPENote.h index 0a997451..baaba0fa 100644 --- a/modules/juce_audio_basics/mpe/juce_MPENote.h +++ b/modules/juce_audio_basics/mpe/juce_MPENote.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/mpe/juce_MPESynthesiser.cpp b/modules/juce_audio_basics/mpe/juce_MPESynthesiser.cpp index 8eaf95ce..ba07efb4 100644 --- a/modules/juce_audio_basics/mpe/juce_MPESynthesiser.cpp +++ b/modules/juce_audio_basics/mpe/juce_MPESynthesiser.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/mpe/juce_MPESynthesiser.h b/modules/juce_audio_basics/mpe/juce_MPESynthesiser.h index 8a999d66..f3b0696d 100644 --- a/modules/juce_audio_basics/mpe/juce_MPESynthesiser.h +++ b/modules/juce_audio_basics/mpe/juce_MPESynthesiser.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/mpe/juce_MPESynthesiserBase.cpp b/modules/juce_audio_basics/mpe/juce_MPESynthesiserBase.cpp index 51483f0e..acd03984 100644 --- a/modules/juce_audio_basics/mpe/juce_MPESynthesiserBase.cpp +++ b/modules/juce_audio_basics/mpe/juce_MPESynthesiserBase.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -110,48 +110,32 @@ void MPESynthesiserBase::renderNextBlock (AudioBuffer<floatType>& outputAudio, // you must set the sample rate before using this! jassert (sampleRate != 0); - MidiBuffer::Iterator midiIterator (inputMidi); - midiIterator.setNextSamplePosition (startSample); - - bool firstEvent = true; - int midiEventPos; - MidiMessage m; - const ScopedLock sl (noteStateLock); - while (numSamples > 0) - { - if (! midiIterator.getNextEvent (m, midiEventPos)) - { - renderNextSubBlock (outputAudio, startSample, numSamples); - return; - } + auto prevSample = startSample; + const auto endSample = startSample + numSamples; - auto samplesToNextMidiMessage = midiEventPos - startSample; + for (auto it = inputMidi.findNextSamplePosition (startSample); it != inputMidi.cend(); ++it) + { + const auto metadata = *it; - if (samplesToNextMidiMessage >= numSamples) - { - renderNextSubBlock (outputAudio, startSample, numSamples); - handleMidiEvent (m); + if (metadata.samplePosition >= endSample) break; - } - if (samplesToNextMidiMessage < ((firstEvent && ! subBlockSubdivisionIsStrict) ? 1 : minimumSubBlockSize)) + const auto smallBlockAllowed = (prevSample == startSample && ! subBlockSubdivisionIsStrict); + const auto thisBlockSize = smallBlockAllowed ? 1 : minimumSubBlockSize; + + if (metadata.samplePosition >= prevSample + thisBlockSize) { - handleMidiEvent (m); - continue; + renderNextSubBlock (outputAudio, prevSample, metadata.samplePosition - prevSample); + prevSample = metadata.samplePosition; } - firstEvent = false; - - renderNextSubBlock (outputAudio, startSample, samplesToNextMidiMessage); - handleMidiEvent (m); - startSample += samplesToNextMidiMessage; - numSamples -= samplesToNextMidiMessage; + handleMidiEvent (metadata.getMessage()); } - while (midiIterator.getNextEvent (m, midiEventPos)) - handleMidiEvent (m); + if (prevSample < endSample) + renderNextSubBlock (outputAudio, prevSample, endSample - prevSample); } // explicit instantiation for supported float types: @@ -177,4 +161,216 @@ void MPESynthesiserBase::setMinimumRenderingSubdivisionSize (int numSamples, boo subBlockSubdivisionIsStrict = shouldBeStrict; } +#if JUCE_UNIT_TESTS + +namespace +{ + class MpeSynthesiserBaseTests : public UnitTest + { + enum class CallbackKind { process, midi }; + + struct StartAndLength + { + StartAndLength (int s, int l) : start (s), length (l) {} + + int start = 0; + int length = 0; + + std::tuple<const int&, const int&> tie() const noexcept { return std::tie (start, length); } + + bool operator== (const StartAndLength& other) const noexcept { return tie() == other.tie(); } + bool operator!= (const StartAndLength& other) const noexcept { return tie() != other.tie(); } + + bool operator< (const StartAndLength& other) const noexcept { return tie() < other.tie(); } + }; + + struct Events + { + std::vector<StartAndLength> blocks; + std::vector<MidiMessage> messages; + std::vector<CallbackKind> order; + }; + + class MockSynthesiser : public MPESynthesiserBase + { + public: + Events events; + + void handleMidiEvent (const MidiMessage& m) override + { + events.messages.emplace_back (m); + events.order.emplace_back (CallbackKind::midi); + } + + private: + using MPESynthesiserBase::renderNextSubBlock; + + void renderNextSubBlock (AudioBuffer<float>&, + int startSample, + int numSamples) override + { + events.blocks.push_back ({ startSample, numSamples }); + events.order.emplace_back (CallbackKind::process); + } + }; + + static MidiBuffer makeTestBuffer (const int bufferLength) + { + MidiBuffer result; + + for (int i = 0; i != bufferLength; ++i) + result.addEvent ({}, i); + + return result; + } + + public: + MpeSynthesiserBaseTests() + : UnitTest ("MPE Synthesiser Base", UnitTestCategories::midi) {} + + void runTest() override + { + const auto sumBlockLengths = [] (const std::vector<StartAndLength>& b) + { + const auto addBlock = [] (int acc, const StartAndLength& info) { return acc + info.length; }; + return std::accumulate (b.begin(), b.end(), 0, addBlock); + }; + + beginTest ("Rendering sparse subblocks works"); + { + const int blockSize = 512; + const auto midi = [&] { MidiBuffer b; b.addEvent ({}, blockSize / 2); return b; }(); + AudioBuffer<float> audio (1, blockSize); + + const auto processEvents = [&] (int start, int length) + { + MockSynthesiser synth; + synth.setMinimumRenderingSubdivisionSize (1, false); + synth.setCurrentPlaybackSampleRate (44100); + synth.renderNextBlock (audio, midi, start, length); + return synth.events; + }; + + { + const auto e = processEvents (0, blockSize); + expect (e.blocks.size() == 2); + expect (e.messages.size() == 1); + expect (std::is_sorted (e.blocks.begin(), e.blocks.end())); + expect (sumBlockLengths (e.blocks) == blockSize); + expect (e.order == std::vector<CallbackKind> { CallbackKind::process, + CallbackKind::midi, + CallbackKind::process }); + } + } + + beginTest ("Rendering subblocks processes only contained midi events"); + { + const int blockSize = 512; + const auto midi = makeTestBuffer (blockSize); + AudioBuffer<float> audio (1, blockSize); + + const auto processEvents = [&] (int start, int length) + { + MockSynthesiser synth; + synth.setMinimumRenderingSubdivisionSize (1, false); + synth.setCurrentPlaybackSampleRate (44100); + synth.renderNextBlock (audio, midi, start, length); + return synth.events; + }; + + { + const int subBlockLength = 0; + const auto e = processEvents (0, subBlockLength); + expect (e.blocks.size() == 0); + expect (e.messages.size() == 0); + expect (std::is_sorted (e.blocks.begin(), e.blocks.end())); + expect (sumBlockLengths (e.blocks) == subBlockLength); + } + + { + const int subBlockLength = 0; + const auto e = processEvents (1, subBlockLength); + expect (e.blocks.size() == 0); + expect (e.messages.size() == 0); + expect (std::is_sorted (e.blocks.begin(), e.blocks.end())); + expect (sumBlockLengths (e.blocks) == subBlockLength); + } + + { + const int subBlockLength = 1; + const auto e = processEvents (1, subBlockLength); + expect (e.blocks.size() == 1); + expect (e.messages.size() == 1); + expect (std::is_sorted (e.blocks.begin(), e.blocks.end())); + expect (sumBlockLengths (e.blocks) == subBlockLength); + expect (e.order == std::vector<CallbackKind> { CallbackKind::midi, + CallbackKind::process }); + } + + { + const auto e = processEvents (0, blockSize); + expect (e.blocks.size() == blockSize); + expect (e.messages.size() == blockSize); + expect (std::is_sorted (e.blocks.begin(), e.blocks.end())); + expect (sumBlockLengths (e.blocks) == blockSize); + expect (e.order.front() == CallbackKind::midi); + } + } + + beginTest ("Subblocks respect their minimum size"); + { + const int blockSize = 512; + const auto midi = makeTestBuffer (blockSize); + AudioBuffer<float> audio (1, blockSize); + + const auto blockLengthsAreValid = [] (const std::vector<StartAndLength>& info, int minLength, bool strict) + { + if (info.size() <= 1) + return true; + + const auto lengthIsValid = [&] (const StartAndLength& s) { return minLength <= s.length; }; + const auto begin = strict ? info.begin() : std::next (info.begin()); + // The final block is allowed to be shorter than the minLength + return std::all_of (begin, std::prev (info.end()), lengthIsValid); + }; + + for (auto strict : { false, true }) + { + for (auto subblockSize : { 1, 16, 32, 64, 1024 }) + { + MockSynthesiser synth; + synth.setMinimumRenderingSubdivisionSize (subblockSize, strict); + synth.setCurrentPlaybackSampleRate (44100); + synth.renderNextBlock (audio, midi, 0, blockSize); + + const auto& e = synth.events; + expectWithinAbsoluteError (float (e.blocks.size()), + std::ceil ((float) blockSize / (float) subblockSize), + 1.0f); + expect (e.messages.size() == blockSize); + expect (std::is_sorted (e.blocks.begin(), e.blocks.end())); + expect (sumBlockLengths (e.blocks) == blockSize); + expect (blockLengthsAreValid (e.blocks, subblockSize, strict)); + } + } + + { + MockSynthesiser synth; + synth.setMinimumRenderingSubdivisionSize (32, true); + synth.setCurrentPlaybackSampleRate (44100); + synth.renderNextBlock (audio, MidiBuffer{}, 0, 16); + + expect (synth.events.blocks == std::vector<StartAndLength> { { 0, 16 } }); + expect (synth.events.order == std::vector<CallbackKind> { CallbackKind::process }); + expect (synth.events.messages.empty()); + } + } + } + }; + + MpeSynthesiserBaseTests mpeSynthesiserBaseTests; +} + +#endif + } // namespace juce diff --git a/modules/juce_audio_basics/mpe/juce_MPESynthesiserBase.h b/modules/juce_audio_basics/mpe/juce_MPESynthesiserBase.h index ca4c026e..3f5d3efa 100644 --- a/modules/juce_audio_basics/mpe/juce_MPESynthesiserBase.h +++ b/modules/juce_audio_basics/mpe/juce_MPESynthesiserBase.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -88,9 +88,14 @@ public: Call this to make sound. This will chop up the AudioBuffer into subBlock pieces separated by events in the MIDI buffer, and then call - processNextSubBlock on each one of them. In between you will get calls + renderNextSubBlock on each one of them. In between you will get calls to noteAdded/Changed/Finished, where you can update parameters that depend on those notes to use for your audio rendering. + + @param outputAudio Buffer into which audio will be rendered + @param inputMidi MIDI events to process + @param startSample The first sample to process in both buffers + @param numSamples The number of samples to process */ template <typename floatType> void renderNextBlock (AudioBuffer<floatType>& outputAudio, diff --git a/modules/juce_audio_basics/mpe/juce_MPESynthesiserVoice.cpp b/modules/juce_audio_basics/mpe/juce_MPESynthesiserVoice.cpp index b20e13d6..99179f05 100644 --- a/modules/juce_audio_basics/mpe/juce_MPESynthesiserVoice.cpp +++ b/modules/juce_audio_basics/mpe/juce_MPESynthesiserVoice.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/mpe/juce_MPESynthesiserVoice.h b/modules/juce_audio_basics/mpe/juce_MPESynthesiserVoice.h index febd84f0..d6ac2454 100644 --- a/modules/juce_audio_basics/mpe/juce_MPESynthesiserVoice.h +++ b/modules/juce_audio_basics/mpe/juce_MPESynthesiserVoice.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/mpe/juce_MPEUtils.cpp b/modules/juce_audio_basics/mpe/juce_MPEUtils.cpp index 8ebc185b..74b3c144 100644 --- a/modules/juce_audio_basics/mpe/juce_MPEUtils.cpp +++ b/modules/juce_audio_basics/mpe/juce_MPEUtils.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/mpe/juce_MPEUtils.h b/modules/juce_audio_basics/mpe/juce_MPEUtils.h index 3f5f7dd7..672bdafc 100644 --- a/modules/juce_audio_basics/mpe/juce_MPEUtils.h +++ b/modules/juce_audio_basics/mpe/juce_MPEUtils.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/mpe/juce_MPEValue.cpp b/modules/juce_audio_basics/mpe/juce_MPEValue.cpp index ccc20ab1..193d7fd2 100644 --- a/modules/juce_audio_basics/mpe/juce_MPEValue.cpp +++ b/modules/juce_audio_basics/mpe/juce_MPEValue.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/mpe/juce_MPEValue.h b/modules/juce_audio_basics/mpe/juce_MPEValue.h index 242d9c5c..cadad5e2 100644 --- a/modules/juce_audio_basics/mpe/juce_MPEValue.h +++ b/modules/juce_audio_basics/mpe/juce_MPEValue.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/mpe/juce_MPEZoneLayout.cpp b/modules/juce_audio_basics/mpe/juce_MPEZoneLayout.cpp index dfcba78e..0d43464e 100644 --- a/modules/juce_audio_basics/mpe/juce_MPEZoneLayout.cpp +++ b/modules/juce_audio_basics/mpe/juce_MPEZoneLayout.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -169,12 +169,8 @@ void MPEZoneLayout::processPitchbendRangeRpnMessage (MidiRPNMessage rpn) void MPEZoneLayout::processNextMidiBuffer (const MidiBuffer& buffer) { - MidiBuffer::Iterator iter (buffer); - MidiMessage message; - int samplePosition; // not actually used, so no need to initialise. - - while (iter.getNextEvent (message, samplePosition)) - processNextMidiEvent (message); + for (const auto metadata : buffer) + processNextMidiEvent (metadata.getMessage()); } //============================================================================== diff --git a/modules/juce_audio_basics/mpe/juce_MPEZoneLayout.h b/modules/juce_audio_basics/mpe/juce_MPEZoneLayout.h index 58523ee5..e378456f 100644 --- a/modules/juce_audio_basics/mpe/juce_MPEZoneLayout.h +++ b/modules/juce_audio_basics/mpe/juce_MPEZoneLayout.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/native/juce_mac_CoreAudioLayouts.h b/modules/juce_audio_basics/native/juce_mac_CoreAudioLayouts.h index fe79a371..ac5ce32d 100644 --- a/modules/juce_audio_basics/native/juce_mac_CoreAudioLayouts.h +++ b/modules/juce_audio_basics/native/juce_mac_CoreAudioLayouts.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/sources/juce_AudioSource.h b/modules/juce_audio_basics/sources/juce_AudioSource.h index 401c4f77..0122623b 100644 --- a/modules/juce_audio_basics/sources/juce_AudioSource.h +++ b/modules/juce_audio_basics/sources/juce_AudioSource.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/sources/juce_BufferingAudioSource.cpp b/modules/juce_audio_basics/sources/juce_BufferingAudioSource.cpp index 740d7ba8..9790ad2d 100644 --- a/modules/juce_audio_basics/sources/juce_BufferingAudioSource.cpp +++ b/modules/juce_audio_basics/sources/juce_BufferingAudioSource.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/sources/juce_BufferingAudioSource.h b/modules/juce_audio_basics/sources/juce_BufferingAudioSource.h index 44c755d3..b87977c5 100644 --- a/modules/juce_audio_basics/sources/juce_BufferingAudioSource.h +++ b/modules/juce_audio_basics/sources/juce_BufferingAudioSource.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/sources/juce_ChannelRemappingAudioSource.cpp b/modules/juce_audio_basics/sources/juce_ChannelRemappingAudioSource.cpp index d5263ac5..85a4bed0 100644 --- a/modules/juce_audio_basics/sources/juce_ChannelRemappingAudioSource.cpp +++ b/modules/juce_audio_basics/sources/juce_ChannelRemappingAudioSource.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/sources/juce_ChannelRemappingAudioSource.h b/modules/juce_audio_basics/sources/juce_ChannelRemappingAudioSource.h index 928a20c5..b226e390 100644 --- a/modules/juce_audio_basics/sources/juce_ChannelRemappingAudioSource.h +++ b/modules/juce_audio_basics/sources/juce_ChannelRemappingAudioSource.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.cpp b/modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.cpp index cbea3b8c..fdc99f1b 100644 --- a/modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.cpp +++ b/modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.h b/modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.h index e47e9e81..5ff22870 100644 --- a/modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.h +++ b/modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/sources/juce_MemoryAudioSource.cpp b/modules/juce_audio_basics/sources/juce_MemoryAudioSource.cpp index a987d7f5..abb1e1fd 100644 --- a/modules/juce_audio_basics/sources/juce_MemoryAudioSource.cpp +++ b/modules/juce_audio_basics/sources/juce_MemoryAudioSource.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -24,7 +24,7 @@ namespace juce { MemoryAudioSource::MemoryAudioSource (AudioBuffer<float>& bufferToUse, bool copyMemory, bool shouldLoop) - : isLooping (shouldLoop) + : isCurrentlyLooping (shouldLoop) { if (copyMemory) buffer.makeCopyOf (bufferToUse); @@ -50,7 +50,7 @@ void MemoryAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& bufferT auto n = buffer.getNumSamples(), m = bufferToFill.numSamples; int i; - for (i = position; (i < n || isLooping) && (pos < m); i += max) + for (i = position; (i < n || isCurrentlyLooping) && (pos < m); i += max) { max = jmin (m - pos, n - (i % n)); @@ -70,4 +70,31 @@ void MemoryAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& bufferT position = (i % n); } +//============================================================================== +void MemoryAudioSource::setNextReadPosition (int64 newPosition) +{ + position = (int) newPosition; +} + +int64 MemoryAudioSource::getNextReadPosition() const +{ + return position; +} + +int64 MemoryAudioSource::getTotalLength() const +{ + return buffer.getNumSamples(); +} + +//============================================================================== +bool MemoryAudioSource::isLooping() const +{ + return isCurrentlyLooping; +} + +void MemoryAudioSource::setLooping (bool shouldLoop) +{ + isCurrentlyLooping = shouldLoop; +} + } // namespace juce diff --git a/modules/juce_audio_basics/sources/juce_MemoryAudioSource.h b/modules/juce_audio_basics/sources/juce_MemoryAudioSource.h index d46bd4f4..414cc65c 100644 --- a/modules/juce_audio_basics/sources/juce_MemoryAudioSource.h +++ b/modules/juce_audio_basics/sources/juce_MemoryAudioSource.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -29,7 +29,7 @@ namespace juce @tags{Audio} */ -class JUCE_API MemoryAudioSource : public AudioSource +class JUCE_API MemoryAudioSource : public PositionableAudioSource { public: //============================================================================== @@ -52,11 +52,28 @@ public: /** Implementation of the AudioSource method. */ void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) override; + //============================================================================== + /** Implementation of the PositionableAudioSource method. */ + void setNextReadPosition (int64 newPosition) override; + + /** Implementation of the PositionableAudioSource method. */ + int64 getNextReadPosition() const override; + + /** Implementation of the PositionableAudioSource method. */ + int64 getTotalLength() const override; + + //============================================================================== + /** Implementation of the PositionableAudioSource method. */ + bool isLooping() const override; + + /** Implementation of the PositionableAudioSource method. */ + void setLooping (bool shouldLoop) override; + private: //============================================================================== AudioBuffer<float> buffer; int position = 0; - bool isLooping; + bool isCurrentlyLooping; //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MemoryAudioSource) diff --git a/modules/juce_audio_basics/sources/juce_MixerAudioSource.cpp b/modules/juce_audio_basics/sources/juce_MixerAudioSource.cpp index 96d9fe8a..0b4eda89 100644 --- a/modules/juce_audio_basics/sources/juce_MixerAudioSource.cpp +++ b/modules/juce_audio_basics/sources/juce_MixerAudioSource.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/sources/juce_MixerAudioSource.h b/modules/juce_audio_basics/sources/juce_MixerAudioSource.h index d3766f93..ed217643 100644 --- a/modules/juce_audio_basics/sources/juce_MixerAudioSource.h +++ b/modules/juce_audio_basics/sources/juce_MixerAudioSource.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/sources/juce_PositionableAudioSource.h b/modules/juce_audio_basics/sources/juce_PositionableAudioSource.h index df7ea363..2ec17d05 100644 --- a/modules/juce_audio_basics/sources/juce_PositionableAudioSource.h +++ b/modules/juce_audio_basics/sources/juce_PositionableAudioSource.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.cpp b/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.cpp index d123e4cf..90af1de2 100644 --- a/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.cpp +++ b/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.h b/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.h index 49b4974b..58f9d436 100644 --- a/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.h +++ b/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/sources/juce_ReverbAudioSource.cpp b/modules/juce_audio_basics/sources/juce_ReverbAudioSource.cpp index dd4e7ab0..2cd1c256 100644 --- a/modules/juce_audio_basics/sources/juce_ReverbAudioSource.cpp +++ b/modules/juce_audio_basics/sources/juce_ReverbAudioSource.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/sources/juce_ReverbAudioSource.h b/modules/juce_audio_basics/sources/juce_ReverbAudioSource.h index a22f4199..07fc8dc2 100644 --- a/modules/juce_audio_basics/sources/juce_ReverbAudioSource.h +++ b/modules/juce_audio_basics/sources/juce_ReverbAudioSource.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.cpp b/modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.cpp index 1707db7c..f3695cc7 100644 --- a/modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.cpp +++ b/modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.h b/modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.h index df04c899..92adec66 100644 --- a/modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.h +++ b/modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp b/modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp index 8c02bf24..388d9d26 100644 --- a/modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp +++ b/modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -163,18 +163,15 @@ void Synthesiser::processNextBlock (AudioBuffer<floatType>& outputAudio, jassert (sampleRate != 0); const int targetChannels = outputAudio.getNumChannels(); - MidiBuffer::Iterator midiIterator (midiData); - midiIterator.setNextSamplePosition (startSample); + auto midiIterator = midiData.findNextSamplePosition (startSample); bool firstEvent = true; - int midiEventPos; - MidiMessage m; const ScopedLock sl (lock); - while (numSamples > 0) + for (; numSamples > 0; ++midiIterator) { - if (! midiIterator.getNextEvent (m, midiEventPos)) + if (midiIterator == midiData.cend()) { if (targetChannels > 0) renderVoices (outputAudio, startSample, numSamples); @@ -182,20 +179,21 @@ void Synthesiser::processNextBlock (AudioBuffer<floatType>& outputAudio, return; } - const int samplesToNextMidiMessage = midiEventPos - startSample; + const auto metadata = *midiIterator; + const int samplesToNextMidiMessage = metadata.samplePosition - startSample; if (samplesToNextMidiMessage >= numSamples) { if (targetChannels > 0) renderVoices (outputAudio, startSample, numSamples); - handleMidiEvent (m); + handleMidiEvent (metadata.getMessage()); break; } if (samplesToNextMidiMessage < ((firstEvent && ! subBlockSubdivisionIsStrict) ? 1 : minimumSubBlockSize)) { - handleMidiEvent (m); + handleMidiEvent (metadata.getMessage()); continue; } @@ -204,13 +202,14 @@ void Synthesiser::processNextBlock (AudioBuffer<floatType>& outputAudio, if (targetChannels > 0) renderVoices (outputAudio, startSample, samplesToNextMidiMessage); - handleMidiEvent (m); + handleMidiEvent (metadata.getMessage()); startSample += samplesToNextMidiMessage; numSamples -= samplesToNextMidiMessage; } - while (midiIterator.getNextEvent (m, midiEventPos)) - handleMidiEvent (m); + std::for_each (midiIterator, + midiData.cend(), + [&] (const MidiMessageMetadata& meta) { handleMidiEvent (meta.getMessage()); }); } // explicit template instantiation diff --git a/modules/juce_audio_basics/synthesisers/juce_Synthesiser.h b/modules/juce_audio_basics/synthesisers/juce_Synthesiser.h index 7c39c814..aa8e33ab 100644 --- a/modules/juce_audio_basics/synthesisers/juce_Synthesiser.h +++ b/modules/juce_audio_basics/synthesisers/juce_Synthesiser.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/utilities/juce_ADSR.h b/modules/juce_audio_basics/utilities/juce_ADSR.h index 8f50ceef..a9dc3138 100644 --- a/modules/juce_audio_basics/utilities/juce_ADSR.h +++ b/modules/juce_audio_basics/utilities/juce_ADSR.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.cpp b/modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.cpp deleted file mode 100644 index c6f59d4a..00000000 --- a/modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* - ============================================================================== - - 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. - - 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 -{ - -struct CatmullRomAlgorithm -{ - static forcedinline float valueAtOffset (const float* const inputs, const float offset) noexcept - { - auto y0 = inputs[3]; - auto y1 = inputs[2]; - auto y2 = inputs[1]; - auto y3 = inputs[0]; - - auto halfY0 = 0.5f * y0; - auto halfY3 = 0.5f * y3; - - return y1 + offset * ((0.5f * y2 - halfY0) - + (offset * (((y0 + 2.0f * y2) - (halfY3 + 2.5f * y1)) - + (offset * ((halfY3 + 1.5f * y1) - (halfY0 + 1.5f * y2)))))); - } -}; - -CatmullRomInterpolator::CatmullRomInterpolator() noexcept { reset(); } -CatmullRomInterpolator::~CatmullRomInterpolator() noexcept {} - -void CatmullRomInterpolator::reset() noexcept -{ - subSamplePos = 1.0; - - for (auto& s : lastInputSamples) - s = 0; -} - -int CatmullRomInterpolator::process (double actualRatio, const float* in, float* out, int numOut, int available, int wrap) noexcept -{ - return interpolate<CatmullRomAlgorithm> (lastInputSamples, subSamplePos, actualRatio, in, out, numOut, available, wrap); -} - -int CatmullRomInterpolator::process (double actualRatio, const float* in, float* out, int numOut) noexcept -{ - return interpolate<CatmullRomAlgorithm> (lastInputSamples, subSamplePos, actualRatio, in, out, numOut); -} - -int CatmullRomInterpolator::processAdding (double actualRatio, const float* in, float* out, int numOut, int available, int wrap, float gain) noexcept -{ - return interpolateAdding<CatmullRomAlgorithm> (lastInputSamples, subSamplePos, actualRatio, in, out, numOut, available, wrap, gain); -} - -int CatmullRomInterpolator::processAdding (double actualRatio, const float* in, float* out, int numOut, float gain) noexcept -{ - return interpolateAdding<CatmullRomAlgorithm> (lastInputSamples, subSamplePos, actualRatio, in, out, numOut, gain); -} - -} // namespace juce diff --git a/modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.h b/modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.h deleted file mode 100644 index 2d89a34e..00000000 --- a/modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - ============================================================================== - - 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. - - 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 -{ - -/** - Interpolator for resampling a stream of floats using Catmull-Rom interpolation. - - Note that the resampler is stateful, so when there's a break in the continuity - of the input stream you're feeding it, you should call reset() before feeding - it any new data. And like with any other stateful filter, if you're resampling - multiple channels, make sure each one uses its own CatmullRomInterpolator - object. - - @see LagrangeInterpolator - - @tags{Audio} -*/ -class JUCE_API CatmullRomInterpolator -{ -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. - */ - void reset() noexcept; - - /** Resamples a stream of samples. - - @param speedRatio the number of input samples to use for each output sample - @param inputSamples the source data to read from. This must contain at - least (speedRatio * numOutputSamplesToProduce) samples. - @param outputSamples the buffer to write the results into - @param numOutputSamplesToProduce the number of output samples that should be created - - @returns the actual number of input samples that were used - */ - int process (double speedRatio, - const float* inputSamples, - float* outputSamples, - int numOutputSamplesToProduce) noexcept; - - /** Resamples a stream of samples. - - @param speedRatio the number of input samples to use for each output sample - @param inputSamples the source data to read from. This must contain at - least (speedRatio * numOutputSamplesToProduce) samples. - @param outputSamples the buffer to write the results into - @param numOutputSamplesToProduce the number of output samples that should be created - @param available the number of available input samples. If it needs more samples - than available, it either wraps back for wrapAround samples, or - it feeds zeroes - @param wrapAround if the stream exceeds available samples, it wraps back for - wrapAround samples. If wrapAround is set to 0, it will feed zeroes. - - @returns the actual number of input samples that were used - */ - int process (double speedRatio, - const float* inputSamples, - float* outputSamples, - int numOutputSamplesToProduce, - int available, - int wrapAround) noexcept; - - /** Resamples a stream of samples, adding the results to the output data - with a gain. - - @param speedRatio the number of input samples to use for each output sample - @param inputSamples the source data to read from. This must contain at - least (speedRatio * numOutputSamplesToProduce) samples. - @param outputSamples the buffer to write the results to - the result values will be added - to any pre-existing data in this buffer after being multiplied by - the gain factor - @param numOutputSamplesToProduce the number of output samples that should be created - @param gain a gain factor to multiply the resulting samples by before - adding them to the destination buffer - - @returns the actual number of input samples that were used - */ - int processAdding (double speedRatio, - const float* inputSamples, - float* outputSamples, - int numOutputSamplesToProduce, - float gain) noexcept; - - /** Resamples a stream of samples, adding the results to the output data - with a gain. - - @param speedRatio the number of input samples to use for each output sample - @param inputSamples the source data to read from. This must contain at - least (speedRatio * numOutputSamplesToProduce) samples. - @param outputSamples the buffer to write the results to - the result values will be added - to any pre-existing data in this buffer after being multiplied by - the gain factor - @param numOutputSamplesToProduce the number of output samples that should be created - @param available the number of available input samples. If it needs more samples - than available, it either wraps back for wrapAround samples, or - it feeds zeroes - @param wrapAround if the stream exceeds available samples, it wraps back for - wrapAround samples. If wrapAround is set to 0, it will feed zeroes. - @param gain a gain factor to multiply the resulting samples by before - adding them to the destination buffer - - @returns the actual number of input samples that were used - */ - int processAdding (double speedRatio, - const float* inputSamples, - float* outputSamples, - int numOutputSamplesToProduce, - int available, - int wrapAround, - float gain) noexcept; - -private: - float lastInputSamples[5]; - double subSamplePos; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CatmullRomInterpolator) -}; - -} // namespace juce diff --git a/modules/juce_audio_basics/utilities/juce_Decibels.h b/modules/juce_audio_basics/utilities/juce_Decibels.h index f1aa5ebd..601b30c0 100644 --- a/modules/juce_audio_basics/utilities/juce_Decibels.h +++ b/modules/juce_audio_basics/utilities/juce_Decibels.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/utilities/juce_GenericInterpolator.h b/modules/juce_audio_basics/utilities/juce_GenericInterpolator.h new file mode 100644 index 00000000..d2e43aca --- /dev/null +++ b/modules/juce_audio_basics/utilities/juce_GenericInterpolator.h @@ -0,0 +1,500 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ + +/** + An interpolator base class for resampling streams of floats. + + Note that the resamplers are stateful, so when there's a break in the continuity + of the input stream you're feeding it, you should call reset() before feeding + it any new data. And like with any other stateful filter, if you're resampling + multiple channels, make sure each one uses its own interpolator object. + + @see LagrangeInterpolator, CatmullRomInterpolator, WindowedSincInterpolator, + LinearInterpolator, ZeroOrderHoldInterpolator + + @tags{Audio} +*/ +template <class InterpolatorTraits, int memorySize> +class JUCE_API GenericInterpolator +{ +public: + GenericInterpolator() noexcept { reset(); } + + GenericInterpolator (GenericInterpolator&&) noexcept = default; + GenericInterpolator& operator= (GenericInterpolator&&) noexcept = default; + + /** Returns the latency of the interpolation algorithm in isolation. + + In the context of resampling the total latency of a process using + the interpolator is the base latency divided by the speed ratio. + */ + static constexpr float getBaseLatency() noexcept + { + return InterpolatorTraits::algorithmicLatency; + } + + /** Resets the state of the interpolator. + + Call this when there's a break in the continuity of the input data stream. + */ + void reset() noexcept + { + indexBuffer = 0; + subSamplePos = 1.0; + std::fill (std::begin (lastInputSamples), std::end (lastInputSamples), 0.0f); + } + + /** Resamples a stream of samples. + + @param speedRatio the number of input samples to use for each output sample + @param inputSamples the source data to read from. This must contain at + least (speedRatio * numOutputSamplesToProduce) samples. + @param outputSamples the buffer to write the results into + @param numOutputSamplesToProduce the number of output samples that should be created + + @returns the actual number of input samples that were used + */ + int process (double speedRatio, + const float* inputSamples, + float* outputSamples, + int numOutputSamplesToProduce) noexcept + { + return interpolate (speedRatio, inputSamples, outputSamples, numOutputSamplesToProduce); + } + + /** Resamples a stream of samples. + + @param speedRatio the number of input samples to use for each output sample + @param inputSamples the source data to read from. This must contain at + least (speedRatio * numOutputSamplesToProduce) samples. + @param outputSamples the buffer to write the results into + @param numOutputSamplesToProduce the number of output samples that should be created + @param numInputSamplesAvailable the number of available input samples. If it needs more samples + than available, it either wraps back for wrapAround samples, or + it feeds zeroes + @param wrapAround if the stream exceeds available samples, it wraps back for + wrapAround samples. If wrapAround is set to 0, it will feed zeroes. + + @returns the actual number of input samples that were used + */ + int process (double speedRatio, + const float* inputSamples, + float* outputSamples, + int numOutputSamplesToProduce, + int numInputSamplesAvailable, + int wrapAround) noexcept + { + return interpolate (speedRatio, inputSamples, outputSamples, + numOutputSamplesToProduce, numInputSamplesAvailable, wrapAround); + } + + /** Resamples a stream of samples, adding the results to the output data + with a gain. + + @param speedRatio the number of input samples to use for each output sample + @param inputSamples the source data to read from. This must contain at + least (speedRatio * numOutputSamplesToProduce) samples. + @param outputSamples the buffer to write the results to - the result values will be added + to any pre-existing data in this buffer after being multiplied by + the gain factor + @param numOutputSamplesToProduce the number of output samples that should be created + @param gain a gain factor to multiply the resulting samples by before + adding them to the destination buffer + + @returns the actual number of input samples that were used + */ + int processAdding (double speedRatio, + const float* inputSamples, + float* outputSamples, + int numOutputSamplesToProduce, + float gain) noexcept + { + return interpolateAdding (speedRatio, inputSamples, outputSamples, numOutputSamplesToProduce, gain); + } + + /** Resamples a stream of samples, adding the results to the output data + with a gain. + + @param speedRatio the number of input samples to use for each output sample + @param inputSamples the source data to read from. This must contain at + least (speedRatio * numOutputSamplesToProduce) samples. + @param outputSamples the buffer to write the results to - the result values will be added + to any pre-existing data in this buffer after being multiplied by + the gain factor + @param numOutputSamplesToProduce the number of output samples that should be created + @param numInputSamplesAvailable the number of available input samples. If it needs more samples + than available, it either wraps back for wrapAround samples, or + it feeds zeroes + @param wrapAround if the stream exceeds available samples, it wraps back for + wrapAround samples. If wrapAround is set to 0, it will feed zeroes. + @param gain a gain factor to multiply the resulting samples by before + adding them to the destination buffer + + @returns the actual number of input samples that were used + */ + int processAdding (double speedRatio, + const float* inputSamples, + float* outputSamples, + int numOutputSamplesToProduce, + int numInputSamplesAvailable, + int wrapAround, + float gain) noexcept + { + return interpolateAdding (speedRatio, inputSamples, outputSamples, + numOutputSamplesToProduce, numInputSamplesAvailable, wrapAround, gain); + } + +private: + //============================================================================== + forcedinline void pushInterpolationSample (float newValue) noexcept + { + lastInputSamples[indexBuffer] = newValue; + + if (++indexBuffer == memorySize) + indexBuffer = 0; + } + + forcedinline void pushInterpolationSamples (const float* input, + int numOutputSamplesToProduce) noexcept + { + if (numOutputSamplesToProduce >= memorySize) + { + const auto* const offsetInput = input + (numOutputSamplesToProduce - memorySize); + + for (int i = 0; i < memorySize; ++i) + pushInterpolationSample (offsetInput[i]); + } + else + { + for (int i = 0; i < numOutputSamplesToProduce; ++i) + pushInterpolationSample (input[i]); + } + } + + forcedinline void pushInterpolationSamples (const float* input, + int numOutputSamplesToProduce, + int numInputSamplesAvailable, + int wrapAround) noexcept + { + if (numOutputSamplesToProduce >= memorySize) + { + if (numInputSamplesAvailable >= memorySize) + { + pushInterpolationSamples (input, + numOutputSamplesToProduce); + } + else + { + pushInterpolationSamples (input + ((numOutputSamplesToProduce - numInputSamplesAvailable) - 1), + numInputSamplesAvailable); + + if (wrapAround > 0) + { + numOutputSamplesToProduce -= wrapAround; + + pushInterpolationSamples (input + ((numOutputSamplesToProduce - (memorySize - numInputSamplesAvailable)) - 1), + memorySize - numInputSamplesAvailable); + } + else + { + for (int i = numInputSamplesAvailable; i < memorySize; ++i) + pushInterpolationSample (0.0f); + } + } + } + else + { + if (numOutputSamplesToProduce > numInputSamplesAvailable) + { + for (int i = 0; i < numInputSamplesAvailable; ++i) + pushInterpolationSample (input[i]); + + const auto extraSamples = numOutputSamplesToProduce - numInputSamplesAvailable; + + if (wrapAround > 0) + { + const auto* const offsetInput = input + (numInputSamplesAvailable - wrapAround); + + for (int i = 0; i < extraSamples; ++i) + pushInterpolationSample (offsetInput[i]); + } + else + { + for (int i = 0; i < extraSamples; ++i) + pushInterpolationSample (0.0f); + } + } + else + { + for (int i = 0; i < numOutputSamplesToProduce; ++i) + pushInterpolationSample (input[i]); + } + } + } + + //============================================================================== + int interpolate (double speedRatio, + const float* input, + float* output, + int numOutputSamplesToProduce) noexcept + { + auto pos = subSamplePos; + int numUsed = 0; + + while (numOutputSamplesToProduce > 0) + { + while (pos >= 1.0) + { + pushInterpolationSample (input[numUsed++]); + pos -= 1.0; + } + + *output++ = InterpolatorTraits::valueAtOffset (lastInputSamples, (float) pos, indexBuffer); + pos += speedRatio; + --numOutputSamplesToProduce; + } + + subSamplePos = pos; + return numUsed; + } + + int interpolate (double speedRatio, + const float* input, float* output, + int numOutputSamplesToProduce, + int numInputSamplesAvailable, + int wrap) noexcept + { + auto originalIn = input; + auto pos = subSamplePos; + bool exceeded = false; + + if (speedRatio < 1.0) + { + for (int i = numOutputSamplesToProduce; --i >= 0;) + { + if (pos >= 1.0) + { + if (exceeded) + { + pushInterpolationSample (0.0f); + } + else + { + pushInterpolationSample (*input++); + + if (--numInputSamplesAvailable <= 0) + { + if (wrap > 0) + { + input -= wrap; + numInputSamplesAvailable += wrap; + } + else + { + exceeded = true; + } + } + } + + pos -= 1.0; + } + + *output++ = InterpolatorTraits::valueAtOffset (lastInputSamples, (float) pos, indexBuffer); + pos += speedRatio; + } + } + else + { + for (int i = numOutputSamplesToProduce; --i >= 0;) + { + while (pos < speedRatio) + { + if (exceeded) + { + pushInterpolationSample (0); + } + else + { + pushInterpolationSample (*input++); + + if (--numInputSamplesAvailable <= 0) + { + if (wrap > 0) + { + input -= wrap; + numInputSamplesAvailable += wrap; + } + else + { + exceeded = true; + } + } + } + + pos += 1.0; + } + + pos -= speedRatio; + *output++ = InterpolatorTraits::valueAtOffset (lastInputSamples, jmax (0.0f, 1.0f - (float) pos), indexBuffer); + } + } + + subSamplePos = pos; + + if (wrap == 0) + return (int) (input - originalIn); + + return ((int) (input - originalIn) + wrap) % wrap; + } + + int interpolateAdding (double speedRatio, + const float* input, + float* output, + int numOutputSamplesToProduce, + int numInputSamplesAvailable, + int wrap, + float gain) noexcept + { + auto originalIn = input; + auto pos = subSamplePos; + bool exceeded = false; + + if (speedRatio < 1.0) + { + for (int i = numOutputSamplesToProduce; --i >= 0;) + { + if (pos >= 1.0) + { + if (exceeded) + { + pushInterpolationSample (0.0); + } + else + { + pushInterpolationSample (*input++); + + if (--numInputSamplesAvailable <= 0) + { + if (wrap > 0) + { + input -= wrap; + numInputSamplesAvailable += wrap; + } + else + { + numInputSamplesAvailable = true; + } + } + } + + pos -= 1.0; + } + + *output++ += gain * InterpolatorTraits::valueAtOffset ((float) pos); + pos += speedRatio; + } + } + else + { + for (int i = numOutputSamplesToProduce; --i >= 0;) + { + while (pos < speedRatio) + { + if (exceeded) + { + pushInterpolationSample (0.0); + } + else + { + pushInterpolationSample (*input++); + + if (--numInputSamplesAvailable <= 0) + { + if (wrap > 0) + { + input -= wrap; + numInputSamplesAvailable += wrap; + } + else + { + exceeded = true; + } + } + } + + pos += 1.0; + } + + pos -= speedRatio; + *output++ += gain * InterpolatorTraits::valueAtOffset (lastInputSamples, jmax (0.0f, 1.0f - (float) pos), indexBuffer); + } + } + + subSamplePos = pos; + + if (wrap == 0) + return (int) (input - originalIn); + + return ((int) (input - originalIn) + wrap) % wrap; + } + + int interpolateAdding (double speedRatio, + const float* input, + float* output, + int numOutputSamplesToProduce, + float gain) noexcept + { + auto pos = subSamplePos; + int numUsed = 0; + + while (numOutputSamplesToProduce > 0) + { + while (pos >= 1.0) + { + pushInterpolationSample (input[numUsed++]); + pos -= 1.0; + } + + *output++ += gain * InterpolatorTraits::valueAtOffset (lastInputSamples, (float) pos, indexBuffer); + pos += speedRatio; + --numOutputSamplesToProduce; + } + + subSamplePos = pos; + return numUsed; + } + + //============================================================================== + float lastInputSamples[(size_t) memorySize]; + double subSamplePos = 1.0; + int indexBuffer = 0; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GenericInterpolator) +}; + +} // namespace juce diff --git a/modules/juce_audio_basics/utilities/juce_IIRFilter.cpp b/modules/juce_audio_basics/utilities/juce_IIRFilter.cpp index 392ccfc1..a1dc2526 100644 --- a/modules/juce_audio_basics/utilities/juce_IIRFilter.cpp +++ b/modules/juce_audio_basics/utilities/juce_IIRFilter.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/utilities/juce_IIRFilter.h b/modules/juce_audio_basics/utilities/juce_IIRFilter.h index 3b6e8cf5..2246d872 100644 --- a/modules/juce_audio_basics/utilities/juce_IIRFilter.h +++ b/modules/juce_audio_basics/utilities/juce_IIRFilter.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/utilities/juce_Interpolators.cpp b/modules/juce_audio_basics/utilities/juce_Interpolators.cpp new file mode 100644 index 00000000..b42e0c0b --- /dev/null +++ b/modules/juce_audio_basics/utilities/juce_Interpolators.cpp @@ -0,0 +1,191 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ + +#if JUCE_UNIT_TESTS + +class InterpolatorTests : public UnitTest +{ +public: + InterpolatorTests() + : UnitTest ("InterpolatorTests", UnitTestCategories::audio) + { + } + +private: + template<typename InterpolatorType> + void runInterplatorTests (const String& interpolatorName) + { + auto createGaussian = [] (std::vector<float>& destination, float scale, float centreInSamples, float width) + { + for (size_t i = 0; i < destination.size(); ++i) + { + auto x = (((float) i) - centreInSamples) * width; + destination[i] = std::exp (-(x * x)); + } + + FloatVectorOperations::multiply (destination.data(), scale, (int) destination.size()); + }; + + auto findGaussianPeak = [] (const std::vector<float>& input) -> float + { + auto max = std::max_element (std::begin (input), std::end (input)); + auto maxPrev = max - 1; + jassert (maxPrev >= std::begin (input)); + auto maxNext = max + 1; + jassert (maxNext < std::end (input)); + auto quadraticMaxLoc = (*maxPrev - *maxNext) / (2.0f * ((*maxNext + *maxPrev) - (2.0f * *max))); + return quadraticMaxLoc + (float) std::distance (std::begin (input), max); + }; + + auto expectAllElementsWithin = [this] (const std::vector<float>& v1, const std::vector<float>& v2, float tolerance) + { + expectEquals ((int) v1.size(), (int) v2.size()); + + for (size_t i = 0; i < v1.size(); ++i) + expectWithinAbsoluteError (v1[i], v2[i], tolerance); + }; + + InterpolatorType interpolator; + + constexpr size_t inputSize = 1001; + static_assert (inputSize > 800 + InterpolatorType::getBaseLatency(), + "The test InterpolatorTests input buffer is too small"); + + std::vector<float> input (inputSize); + constexpr auto inputGaussianMidpoint = (float) (inputSize - 1) / 2.0f; + constexpr auto inputGaussianValueAtEnds = 0.000001f; + const auto inputGaussianWidth = std::sqrt (-std::log (inputGaussianValueAtEnds)) / inputGaussianMidpoint; + + createGaussian (input, 1.0f, inputGaussianMidpoint, inputGaussianWidth); + + for (auto speedRatio : { 0.4, 0.8263, 1.0, 1.05, 1.2384, 1.6 }) + { + const auto expectedGaussianMidpoint = (inputGaussianMidpoint + InterpolatorType::getBaseLatency()) / (float) speedRatio; + const auto expectedGaussianWidth = inputGaussianWidth * (float) speedRatio; + + const auto outputBufferSize = (size_t) std::floor ((float) input.size() / speedRatio); + + for (int numBlocks : { 1, 5 }) + { + const auto inputBlockSize = (float) input.size() / (float) numBlocks; + const auto outputBlockSize = (int) std::floor (inputBlockSize / speedRatio); + + std::vector<float> output (outputBufferSize, std::numeric_limits<float>::min()); + + beginTest (interpolatorName + " process " + String (numBlocks) + " blocks ratio " + String (speedRatio)); + + interpolator.reset(); + + { + auto* inputPtr = input.data(); + auto* outputPtr = output.data(); + + for (int i = 0; i < numBlocks; ++i) + { + auto numInputSamplesRead = interpolator.process (speedRatio, inputPtr, outputPtr, outputBlockSize); + inputPtr += numInputSamplesRead; + outputPtr += outputBlockSize; + } + } + + expectWithinAbsoluteError (findGaussianPeak (output), expectedGaussianMidpoint, 0.1f); + + std::vector<float> expectedOutput (output.size()); + createGaussian (expectedOutput, 1.0f, expectedGaussianMidpoint, expectedGaussianWidth); + + expectAllElementsWithin (output, expectedOutput, 0.02f); + + beginTest (interpolatorName + " process adding " + String (numBlocks) + " blocks ratio " + String (speedRatio)); + + interpolator.reset(); + + constexpr float addingGain = 0.7384f; + + { + auto* inputPtr = input.data(); + auto* outputPtr = output.data(); + + for (int i = 0; i < numBlocks; ++i) + { + auto numInputSamplesRead = interpolator.processAdding (speedRatio, inputPtr, outputPtr, outputBlockSize, addingGain); + inputPtr += numInputSamplesRead; + outputPtr += outputBlockSize; + } + } + + expectWithinAbsoluteError (findGaussianPeak (output), expectedGaussianMidpoint, 0.1f); + + std::vector<float> additionalOutput (output.size()); + createGaussian (additionalOutput, addingGain, expectedGaussianMidpoint, expectedGaussianWidth); + FloatVectorOperations::add (expectedOutput.data(), additionalOutput.data(), (int) additionalOutput.size()); + + expectAllElementsWithin (output, expectedOutput, 0.02f); + } + + beginTest (interpolatorName + " process wrap 0 ratio " + String (speedRatio)); + + std::vector<float> doubleLengthOutput (2 * outputBufferSize, std::numeric_limits<float>::min()); + + interpolator.reset(); + interpolator.process (speedRatio, input.data(), doubleLengthOutput.data(), (int) doubleLengthOutput.size(), + (int) input.size(), 0); + + std::vector<float> expectedDoubleLengthOutput (doubleLengthOutput.size()); + createGaussian (expectedDoubleLengthOutput, 1.0f, expectedGaussianMidpoint, expectedGaussianWidth); + + expectAllElementsWithin (doubleLengthOutput, expectedDoubleLengthOutput, 0.02f); + + beginTest (interpolatorName + " process wrap double ratio " + String (speedRatio)); + + interpolator.reset(); + interpolator.process (speedRatio, input.data(), doubleLengthOutput.data(), (int) doubleLengthOutput.size(), + (int) input.size(), (int) input.size()); + + std::vector<float> secondGaussian (doubleLengthOutput.size()); + createGaussian (secondGaussian, 1.0f, expectedGaussianMidpoint + (float) outputBufferSize, expectedGaussianWidth); + FloatVectorOperations::add (expectedDoubleLengthOutput.data(), secondGaussian.data(), (int) expectedDoubleLengthOutput.size()); + + expectAllElementsWithin (doubleLengthOutput, expectedDoubleLengthOutput, 0.02f); + } + } + +public: + void runTest() override + { + runInterplatorTests<WindowedSincInterpolator> ("WindowedSincInterpolator"); + runInterplatorTests<LagrangeInterpolator> ("LagrangeInterpolator"); + runInterplatorTests<CatmullRomInterpolator> ("CatmullRomInterpolator"); + runInterplatorTests<LinearInterpolator> ("LinearInterpolator"); + } +}; + +static InterpolatorTests interpolatorTests; + +#endif + +} // namespace juce diff --git a/modules/juce_audio_basics/utilities/juce_Interpolators.h b/modules/juce_audio_basics/utilities/juce_Interpolators.h new file mode 100644 index 00000000..cdd2c875 --- /dev/null +++ b/modules/juce_audio_basics/utilities/juce_Interpolators.h @@ -0,0 +1,245 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ + +/** + A collection of different interpolators for resampling streams of floats. + + @see GenericInterpolator, WindowedSincInterpolator, LagrangeInterpolator, + CatmullRomInterpolator, LinearInterpolator, ZeroOrderHoldInterpolator + + @tags{Audio} +*/ +class Interpolators +{ +private: + struct WindowedSincTraits + { + static constexpr float algorithmicLatency = 100.0f; + + static forcedinline float windowedSinc (float firstFrac, int index) noexcept + { + auto index2 = index + 1; + auto frac = firstFrac; + + auto value1 = lookupTable[index]; + auto value2 = lookupTable[index2]; + + return value1 + (frac * (value2 - value1)); + } + + static forcedinline float valueAtOffset (const float* const inputs, const float offset, int indexBuffer) noexcept + { + const int numCrossings = 100; + const float floatCrossings = (float) numCrossings; + float result = 0.0f; + + auto samplePosition = indexBuffer; + float firstFrac = 0.0f; + float lastSincPosition = -1.0f; + int index = 0, sign = -1; + + for (int i = -numCrossings; i <= numCrossings; ++i) + { + auto sincPosition = (1.0f - offset) + (float) i; + + if (i == -numCrossings || (sincPosition >= 0 && lastSincPosition < 0)) + { + auto indexFloat = (sincPosition >= 0.f ? sincPosition : -sincPosition) * 100.0f; + auto indexFloored = std::floor (indexFloat); + index = (int) indexFloored; + firstFrac = indexFloat - indexFloored; + sign = (sincPosition < 0 ? -1 : 1); + } + + if (sincPosition == 0.0f) + result += inputs[samplePosition]; + else if (sincPosition < floatCrossings && sincPosition > -floatCrossings) + result += inputs[samplePosition] * windowedSinc (firstFrac, index); + + if (++samplePosition == numCrossings * 2) + samplePosition = 0; + + lastSincPosition = sincPosition; + index += 100 * sign; + } + + return result; + } + + static const float lookupTable[10001]; + }; + + struct LagrangeTraits + { + static constexpr float algorithmicLatency = 2.0f; + + static float valueAtOffset (const float*, float, int) noexcept; + }; + + struct CatmullRomTraits + { + //============================================================================== + static constexpr float algorithmicLatency = 2.0f; + + static forcedinline float valueAtOffset (const float* const inputs, const float offset, int index) noexcept + { + auto y0 = inputs[index]; if (++index == 4) index = 0; + auto y1 = inputs[index]; if (++index == 4) index = 0; + auto y2 = inputs[index]; if (++index == 4) index = 0; + auto y3 = inputs[index]; + + auto halfY0 = 0.5f * y0; + auto halfY3 = 0.5f * y3; + + return y1 + offset * ((0.5f * y2 - halfY0) + + (offset * (((y0 + 2.0f * y2) - (halfY3 + 2.5f * y1)) + + (offset * ((halfY3 + 1.5f * y1) - (halfY0 + 1.5f * y2)))))); + } + }; + + struct LinearTraits + { + static constexpr float algorithmicLatency = 1.0f; + + static forcedinline float valueAtOffset (const float* const inputs, const float offset, int index) noexcept + { + auto y0 = inputs[index]; + auto y1 = inputs[index == 0 ? 1 : 0]; + + return y1 * offset + y0 * (1.0f - offset); + } + }; + + struct ZeroOrderHoldTraits + { + static constexpr float algorithmicLatency = 0.0f; + + static forcedinline float valueAtOffset (const float* const inputs, const float, int) noexcept + { + return inputs[0]; + } + }; + +public: + using WindowedSinc = GenericInterpolator<WindowedSincTraits, 200>; + using Lagrange = GenericInterpolator<LagrangeTraits, 5>; + using CatmullRom = GenericInterpolator<CatmullRomTraits, 4>; + using Linear = GenericInterpolator<LinearTraits, 2>; + using ZeroOrderHold = GenericInterpolator<ZeroOrderHoldTraits, 1>; +}; + +//============================================================================== +/** + An interpolator for resampling a stream of floats using high order windowed + (hann) sinc interpolation, recommended for high quality resampling. + + Note that the resampler is stateful, so when there's a break in the continuity + of the input stream you're feeding it, you should call reset() before feeding + it any new data. And like with any other stateful filter, if you're resampling + multiple channels, make sure each one uses its own LinearInterpolator object. + + @see GenericInterpolator + + @see LagrangeInterpolator, CatmullRomInterpolator, LinearInterpolator, + ZeroOrderHoldInterpolator + + @tags{Audio} +*/ +using WindowedSincInterpolator = Interpolators::WindowedSinc; + +/** + An interpolator for resampling a stream of floats using 4-point lagrange interpolation. + + Note that the resampler is stateful, so when there's a break in the continuity + of the input stream you're feeding it, you should call reset() before feeding + it any new data. And like with any other stateful filter, if you're resampling + multiple channels, make sure each one uses its own LagrangeInterpolator object. + + @see GenericInterpolator + + @see CatmullRomInterpolator, WindowedSincInterpolator, LinearInterpolator, + ZeroOrderHoldInterpolator + + @tags{Audio} +*/ +using LagrangeInterpolator = Interpolators::Lagrange; + +/** + An interpolator for resampling a stream of floats using Catmull-Rom interpolation. + + Note that the resampler is stateful, so when there's a break in the continuity + of the input stream you're feeding it, you should call reset() before feeding + it any new data. And like with any other stateful filter, if you're resampling + multiple channels, make sure each one uses its own CatmullRomInterpolator object. + + @see GenericInterpolator + + @see LagrangeInterpolator, WindowedSincInterpolator, LinearInterpolator, + ZeroOrderHoldInterpolator + + @tags{Audio} +*/ +using CatmullRomInterpolator = Interpolators::CatmullRom; + +/** + An interpolator for resampling a stream of floats using linear interpolation. + + Note that the resampler is stateful, so when there's a break in the continuity + of the input stream you're feeding it, you should call reset() before feeding + it any new data. And like with any other stateful filter, if you're resampling + multiple channels, make sure each one uses its own LinearInterpolator object. + + @see GenericInterpolator + + @see LagrangeInterpolator, CatmullRomInterpolator, WindowedSincInterpolator, + ZeroOrderHoldInterpolator + + @tags{Audio} +*/ +using LinearInterpolator = Interpolators::Linear; + +/** + An interpolator for resampling a stream of floats using zero order hold + interpolation. + + Note that the resampler is stateful, so when there's a break in the continuity + of the input stream you're feeding it, you should call reset() before feeding + it any new data. And like with any other stateful filter, if you're resampling + multiple channels, make sure each one uses its own ZeroOrderHoldInterpolator + object. + + @see GenericInterpolator + + @see LagrangeInterpolator, CatmullRomInterpolator, WindowedSincInterpolator, + LinearInterpolator + + @tags{Audio} +*/ +using ZeroOrderHoldInterpolator = Interpolators::ZeroOrderHold; + +} // namespace juce diff --git a/modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.cpp b/modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.cpp index 952327c7..0fd5ce84 100644 --- a/modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.cpp +++ b/modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -23,381 +23,6 @@ namespace juce { -namespace -{ - static forcedinline void pushInterpolationSample (float* lastInputSamples, float newValue) noexcept - { - lastInputSamples[4] = lastInputSamples[3]; - lastInputSamples[3] = lastInputSamples[2]; - lastInputSamples[2] = lastInputSamples[1]; - lastInputSamples[1] = lastInputSamples[0]; - lastInputSamples[0] = newValue; - } - - static forcedinline void pushInterpolationSamples (float* lastInputSamples, const float* input, int numOut) noexcept - { - if (numOut >= 5) - { - for (int i = 0; i < 5; ++i) - lastInputSamples[i] = input[--numOut]; - } - else - { - for (int i = 0; i < numOut; ++i) - pushInterpolationSample (lastInputSamples, input[i]); - } - } - - static forcedinline void pushInterpolationSamples (float* lastInputSamples, const float* input, - int numOut, int available, int wrapAround) noexcept - { - if (numOut >= 5) - { - if (available >= 5) - { - for (int i = 0; i < 5; ++i) - lastInputSamples[i] = input[--numOut]; - } - else - { - for (int i = 0; i < available; ++i) - lastInputSamples[i] = input[--numOut]; - - if (wrapAround > 0) - { - numOut -= wrapAround; - - for (int i = available; i < 5; ++i) - lastInputSamples[i] = input[--numOut]; - } - else - { - for (int i = available; i < 5; ++i) - lastInputSamples[i] = 0.0f; - } - } - } - else - { - if (numOut > available) - { - for (int i = 0; i < available; ++i) - pushInterpolationSample (lastInputSamples, input[i]); - - if (wrapAround > 0) - { - for (int i = 0; i < numOut - available; ++i) - pushInterpolationSample (lastInputSamples, input[i + available - wrapAround]); - } - else - { - for (int i = 0; i < numOut - available; ++i) - pushInterpolationSample (lastInputSamples, 0); - } - } - else - { - for (int i = 0; i < numOut; ++i) - pushInterpolationSample (lastInputSamples, input[i]); - } - } - } - - template <typename InterpolatorType> - static int interpolate (float* lastInputSamples, double& subSamplePos, double actualRatio, - const float* in, float* out, int numOut) noexcept - { - auto pos = subSamplePos; - - if (actualRatio == 1.0 && pos == 1.0) - { - memcpy (out, in, (size_t) numOut * sizeof (float)); - pushInterpolationSamples (lastInputSamples, in, numOut); - return numOut; - } - - int numUsed = 0; - - while (numOut > 0) - { - while (pos >= 1.0) - { - pushInterpolationSample (lastInputSamples, in[numUsed++]); - pos -= 1.0; - } - - *out++ = InterpolatorType::valueAtOffset (lastInputSamples, (float) pos); - pos += actualRatio; - --numOut; - } - - subSamplePos = pos; - return numUsed; - } - - template <typename InterpolatorType> - static int interpolate (float* lastInputSamples, double& subSamplePos, double actualRatio, - const float* in, float* out, int numOut, int available, int wrap) noexcept - { - if (actualRatio == 1.0) - { - if (available >= numOut) - { - memcpy (out, in, (size_t) numOut * sizeof (float)); - pushInterpolationSamples (lastInputSamples, in, numOut, available, wrap); - } - else - { - memcpy (out, in, (size_t) available * sizeof (float)); - pushInterpolationSamples (lastInputSamples, in, numOut, available, wrap); - - if (wrap > 0) - { - memcpy (out + available, in + available - wrap, (size_t) (numOut - available) * sizeof (float)); - pushInterpolationSamples (lastInputSamples, in, numOut, available, wrap); - } - else - { - for (int i = 0; i < numOut - available; ++i) - pushInterpolationSample (lastInputSamples, 0); - } - } - - return numOut; - } - - auto originalIn = in; - auto pos = subSamplePos; - bool exceeded = false; - - if (actualRatio < 1.0) - { - for (int i = numOut; --i >= 0;) - { - if (pos >= 1.0) - { - if (exceeded) - { - pushInterpolationSample (lastInputSamples, 0); - } - else - { - pushInterpolationSample (lastInputSamples, *in++); - - if (--available <= 0) - { - if (wrap > 0) - { - in -= wrap; - available += wrap; - } - else - { - exceeded = true; - } - } - } - - pos -= 1.0; - } - - *out++ = InterpolatorType::valueAtOffset (lastInputSamples, (float) pos); - pos += actualRatio; - } - } - else - { - for (int i = numOut; --i >= 0;) - { - while (pos < actualRatio) - { - if (exceeded) - { - pushInterpolationSample (lastInputSamples, 0); - } - else - { - pushInterpolationSample (lastInputSamples, *in++); - - if (--available <= 0) - { - if (wrap > 0) - { - in -= wrap; - available += wrap; - } - else - { - exceeded = true; - } - } - } - - pos += 1.0; - } - - pos -= actualRatio; - *out++ = InterpolatorType::valueAtOffset (lastInputSamples, jmax (0.0f, 1.0f - (float) pos)); - } - } - - subSamplePos = pos; - - if (wrap == 0) - return (int) (in - originalIn); - - return ((int) (in - originalIn) + wrap) % wrap; - } - - template <typename InterpolatorType> - static int interpolateAdding (float* lastInputSamples, double& subSamplePos, double actualRatio, - const float* in, float* out, int numOut, - int available, int wrap, float gain) noexcept - { - if (actualRatio == 1.0) - { - if (available >= numOut) - { - FloatVectorOperations::addWithMultiply (out, in, gain, numOut); - pushInterpolationSamples (lastInputSamples, in, numOut, available, wrap); - } - else - { - FloatVectorOperations::addWithMultiply (out, in, gain, available); - pushInterpolationSamples (lastInputSamples, in, available, available, wrap); - - if (wrap > 0) - { - FloatVectorOperations::addWithMultiply (out, in - wrap, gain, numOut - available); - pushInterpolationSamples (lastInputSamples, in - wrap, numOut - available, available, wrap); - } - else - { - for (int i = 0; i < numOut-available; ++i) - pushInterpolationSample (lastInputSamples, 0.0); - } - } - - return numOut; - } - - auto originalIn = in; - auto pos = subSamplePos; - bool exceeded = false; - - if (actualRatio < 1.0) - { - for (int i = numOut; --i >= 0;) - { - if (pos >= 1.0) - { - if (exceeded) - { - pushInterpolationSample (lastInputSamples, 0.0); - } - else - { - pushInterpolationSample (lastInputSamples, *in++); - - if (--available <= 0) - { - if (wrap > 0) - { - in -= wrap; - available += wrap; - } - else - { - exceeded = true; - } - } - } - - pos -= 1.0; - } - - *out++ += gain * InterpolatorType::valueAtOffset (lastInputSamples, (float) pos); - pos += actualRatio; - } - } - else - { - for (int i = numOut; --i >= 0;) - { - while (pos < actualRatio) - { - if (exceeded) - { - pushInterpolationSample (lastInputSamples, 0.0); - } - else - { - pushInterpolationSample (lastInputSamples, *in++); - - if (--available <= 0) - { - if (wrap > 0) - { - in -= wrap; - available += wrap; - } - else - { - exceeded = true; - } - } - } - - pos += 1.0; - } - - pos -= actualRatio; - *out++ += gain * InterpolatorType::valueAtOffset (lastInputSamples, jmax (0.0f, 1.0f - (float) pos)); - } - } - - subSamplePos = pos; - - if (wrap == 0) - return (int) (in - originalIn); - - return ((int) (in - originalIn) + wrap) % wrap; - } - - template <typename InterpolatorType> - static int interpolateAdding (float* lastInputSamples, double& subSamplePos, double actualRatio, - const float* in, float* out, int numOut, float gain) noexcept - { - auto pos = subSamplePos; - - if (actualRatio == 1.0 && pos == 1.0) - { - FloatVectorOperations::addWithMultiply (out, in, gain, numOut); - pushInterpolationSamples (lastInputSamples, in, numOut); - return numOut; - } - - int numUsed = 0; - - while (numOut > 0) - { - while (pos >= 1.0) - { - pushInterpolationSample (lastInputSamples, in[numUsed++]); - pos -= 1.0; - } - - *out++ += gain * InterpolatorType::valueAtOffset (lastInputSamples, (float) pos); - pos += actualRatio; - --numOut; - } - - subSamplePos = pos; - return numUsed; - } -} - -//============================================================================== template <int k> struct LagrangeResampleHelper { @@ -410,58 +35,28 @@ struct LagrangeResampleHelper<0> static forcedinline void calc (float&, float) noexcept {} }; -struct LagrangeAlgorithm -{ - static forcedinline float valueAtOffset (const float* inputs, float offset) noexcept - { - return calcCoefficient<0> (inputs[4], offset) - + calcCoefficient<1> (inputs[3], offset) - + calcCoefficient<2> (inputs[2], offset) - + calcCoefficient<3> (inputs[1], offset) - + calcCoefficient<4> (inputs[0], offset); - } - - template <int k> - static forcedinline float calcCoefficient (float input, float offset) noexcept - { - LagrangeResampleHelper<0 - k>::calc (input, -2.0f - offset); - LagrangeResampleHelper<1 - k>::calc (input, -1.0f - offset); - LagrangeResampleHelper<2 - k>::calc (input, 0.0f - offset); - LagrangeResampleHelper<3 - k>::calc (input, 1.0f - offset); - LagrangeResampleHelper<4 - k>::calc (input, 2.0f - offset); - return input; - } -}; - -LagrangeInterpolator::LagrangeInterpolator() noexcept { reset(); } -LagrangeInterpolator::~LagrangeInterpolator() noexcept {} - -void LagrangeInterpolator::reset() noexcept -{ - subSamplePos = 1.0; - - for (auto& s : lastInputSamples) - s = 0; -} - -int LagrangeInterpolator::process (double actualRatio, const float* in, float* out, int numOut, int available, int wrap) noexcept -{ - return interpolate<LagrangeAlgorithm> (lastInputSamples, subSamplePos, actualRatio, in, out, numOut, available, wrap); +template <int k> +static float calcCoefficient (float input, float offset) noexcept +{ + LagrangeResampleHelper<0 - k>::calc (input, -2.0f - offset); + LagrangeResampleHelper<1 - k>::calc (input, -1.0f - offset); + LagrangeResampleHelper<2 - k>::calc (input, 0.0f - offset); + LagrangeResampleHelper<3 - k>::calc (input, 1.0f - offset); + LagrangeResampleHelper<4 - k>::calc (input, 2.0f - offset); + return input; } -int LagrangeInterpolator::process (double actualRatio, const float* in, float* out, int numOut) noexcept +float Interpolators::LagrangeTraits::valueAtOffset (const float* inputs, float offset, int index) noexcept { - return interpolate<LagrangeAlgorithm> (lastInputSamples, subSamplePos, actualRatio, in, out, numOut); -} + float result = 0.0f; -int LagrangeInterpolator::processAdding (double actualRatio, const float* in, float* out, int numOut, int available, int wrap, float gain) noexcept -{ - return interpolateAdding<LagrangeAlgorithm> (lastInputSamples, subSamplePos, actualRatio, in, out, numOut, available, wrap, gain); -} + result += calcCoefficient<0> (inputs[index], offset); if (++index == 5) index = 0; + result += calcCoefficient<1> (inputs[index], offset); if (++index == 5) index = 0; + result += calcCoefficient<2> (inputs[index], offset); if (++index == 5) index = 0; + result += calcCoefficient<3> (inputs[index], offset); if (++index == 5) index = 0; + result += calcCoefficient<4> (inputs[index], offset); -int LagrangeInterpolator::processAdding (double actualRatio, const float* in, float* out, int numOut, float gain) noexcept -{ - return interpolateAdding<LagrangeAlgorithm> (lastInputSamples, subSamplePos, actualRatio, in, out, numOut, gain); + return result; } } // namespace juce diff --git a/modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.h b/modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.h deleted file mode 100644 index 25598e75..00000000 --- a/modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - ============================================================================== - - 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. - - 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 -{ - -/** - Interpolator for resampling a stream of floats using 4-point lagrange interpolation. - - Note that the resampler is stateful, so when there's a break in the continuity - of the input stream you're feeding it, you should call reset() before feeding - it any new data. And like with any other stateful filter, if you're resampling - multiple channels, make sure each one uses its own LagrangeInterpolator - object. - - @see CatmullRomInterpolator - - @tags{Audio} -*/ -class JUCE_API LagrangeInterpolator -{ -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. - */ - void reset() noexcept; - - /** Resamples a stream of samples. - - @param speedRatio the number of input samples to use for each output sample - @param inputSamples the source data to read from. This must contain at - least (speedRatio * numOutputSamplesToProduce) samples. - @param outputSamples the buffer to write the results into - @param numOutputSamplesToProduce the number of output samples that should be created - - @returns the actual number of input samples that were used - */ - int process (double speedRatio, - const float* inputSamples, - float* outputSamples, - int numOutputSamplesToProduce) noexcept; - - /** Resamples a stream of samples. - - @param speedRatio the number of input samples to use for each output sample - @param inputSamples the source data to read from. This must contain at - least (speedRatio * numOutputSamplesToProduce) samples. - @param outputSamples the buffer to write the results into - @param numOutputSamplesToProduce the number of output samples that should be created - @param available the number of available input samples. If it needs more samples - than available, it either wraps back for wrapAround samples, or - it feeds zeroes - @param wrapAround if the stream exceeds available samples, it wraps back for - wrapAround samples. If wrapAround is set to 0, it will feed zeroes. - - @returns the actual number of input samples that were used - */ - int process (double speedRatio, - const float* inputSamples, - float* outputSamples, - int numOutputSamplesToProduce, - int available, - int wrapAround) noexcept; - - /** Resamples a stream of samples, adding the results to the output data - with a gain. - - @param speedRatio the number of input samples to use for each output sample - @param inputSamples the source data to read from. This must contain at - least (speedRatio * numOutputSamplesToProduce) samples. - @param outputSamples the buffer to write the results to - the result values will be added - to any pre-existing data in this buffer after being multiplied by - the gain factor - @param numOutputSamplesToProduce the number of output samples that should be created - @param gain a gain factor to multiply the resulting samples by before - adding them to the destination buffer - - @returns the actual number of input samples that were used - */ - int processAdding (double speedRatio, - const float* inputSamples, - float* outputSamples, - int numOutputSamplesToProduce, - float gain) noexcept; - - /** Resamples a stream of samples, adding the results to the output data - with a gain. - - @param speedRatio the number of input samples to use for each output sample - @param inputSamples the source data to read from. This must contain at - least (speedRatio * numOutputSamplesToProduce) samples. - @param outputSamples the buffer to write the results to - the result values will be added - to any pre-existing data in this buffer after being multiplied by - the gain factor - @param numOutputSamplesToProduce the number of output samples that should be created - @param available the number of available input samples. If it needs more samples - than available, it either wraps back for wrapAround samples, or - it feeds zeroes - @param wrapAround if the stream exceeds available samples, it wraps back for - wrapAround samples. If wrapAround is set to 0, it will feed zeroes. - @param gain a gain factor to multiply the resulting samples by before - adding them to the destination buffer - - @returns the actual number of input samples that were used - */ - int processAdding (double speedRatio, - const float* inputSamples, - float* outputSamples, - int numOutputSamplesToProduce, - int available, - int wrapAround, - float gain) noexcept; - -private: - float lastInputSamples[5]; - double subSamplePos; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LagrangeInterpolator) -}; - -} // namespace juce diff --git a/modules/juce_audio_basics/utilities/juce_Reverb.h b/modules/juce_audio_basics/utilities/juce_Reverb.h index 0ed72b80..cf46dcca 100644 --- a/modules/juce_audio_basics/utilities/juce_Reverb.h +++ b/modules/juce_audio_basics/utilities/juce_Reverb.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/utilities/juce_SmoothedValue.cpp b/modules/juce_audio_basics/utilities/juce_SmoothedValue.cpp index 643dfd19..cb581633 100644 --- a/modules/juce_audio_basics/utilities/juce_SmoothedValue.cpp +++ b/modules/juce_audio_basics/utilities/juce_SmoothedValue.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2018 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_basics/utilities/juce_SmoothedValue.h b/modules/juce_audio_basics/utilities/juce_SmoothedValue.h index a472fb00..7bcd5a18 100644 --- a/modules/juce_audio_basics/utilities/juce_SmoothedValue.h +++ b/modules/juce_audio_basics/utilities/juce_SmoothedValue.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -369,7 +369,7 @@ private: template <typename T = SmoothingType> MultiplicativeVoid<T> setStepSize() { - step = std::exp ((std::log (std::abs (this->target)) - std::log (std::abs (this->currentValue))) / this->countdown); + step = std::exp ((std::log (std::abs (this->target)) - std::log (std::abs (this->currentValue))) / (FloatType) this->countdown); } //============================================================================== @@ -522,8 +522,8 @@ public: return result; }; - auto compareData = [this](const AudioBuffer<float>& test, - const AudioBuffer<float>& reference) + auto compareData = [this] (const AudioBuffer<float>& test, + const AudioBuffer<float>& reference) { for (int i = 0; i < test.getNumSamples(); ++i) expectWithinAbsoluteError (test.getSample (0, i), diff --git a/modules/juce_audio_basics/utilities/juce_WindowedSincInterpolator.cpp b/modules/juce_audio_basics/utilities/juce_WindowedSincInterpolator.cpp new file mode 100644 index 00000000..c278e087 --- /dev/null +++ b/modules/juce_audio_basics/utilities/juce_WindowedSincInterpolator.cpp @@ -0,0 +1,10033 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ + +const float Interpolators::WindowedSincTraits::lookupTable[] { + 1.000000000000000000e+00f, + 9.998321499902942389e-01f, + 9.993287014045605376e-01f, + 9.984899584999463729e-01f, + 9.973164281284172539e-01f, + 9.958088193720359138e-01f, + 9.939680430327538785e-01f, + 9.917952109771142055e-01f, + 9.892916353363806481e-01f, + 9.864588275627174108e-01f, + 9.832984973421626806e-01f, + 9.798125513652424790e-01f, + 9.760030919561943907e-01f, + 9.718724155618675420e-01f, + 9.674230111014888722e-01f, + 9.626575581785837832e-01f, + 9.575789251564525983e-01f, + 9.521901670987075184e-01f, + 9.464945235764864462e-01f, + 9.404954163440536474e-01f, + 9.341964468846075675e-01f, + 9.276013938282199334e-01f, + 9.207142102439148657e-01f, + 9.135390208080165220e-01f, + 9.060801188509671755e-01f, + 8.983419632849326542e-01f, + 8.903291754145852277e-01f, + 8.820465356335611684e-01f, + 8.734989800091675916e-01f, + 8.646915967580026674e-01f, + 8.556296226152392270e-01f, + 8.463184391004026086e-01f, + 8.367635686825474206e-01f, + 8.269706708478274937e-01f, + 8.169455380725142435e-01f, + 8.066940917045994919e-01f, + 7.962223777571848515e-01f, + 7.855365626169290572e-01f, + 7.746429286708844675e-01f, + 7.635478698551215748e-01f, + 7.522578871285925395e-01f, + 7.407795838757467166e-01f, + 7.291196612414603262e-01f, + 7.172849134018910444e-01f, + 7.052822227749226958e-01f, + 6.931185551739007522e-01f, + 6.808009549084045320e-01f, + 6.683365398358420695e-01f, + 6.557324963676841589e-01f, + 6.429960744341879364e-01f, + 6.301345824114912286e-01f, + 6.171553820149802139e-01f, + 6.040658831628585856e-01f, + 5.908735388138642852e-01f, + 5.775858397830959667e-01f, + 5.642103095399239043e-01f, + 5.507544989919713752e-01f, + 5.372259812591544392e-01f, + 5.236323464417774742e-01f, + 5.099811963866732745e-01f, + 4.962801394553849055e-01f, + 4.825367852983662442e-01f, + 4.687587396391774686e-01f, + 4.549535990726381041e-01f, + 4.411289458808779762e-01f, + 4.272923428712149252e-01f, + 4.134513282397586642e-01f, + 3.996134104646188456e-01f, + 3.857860632325655903e-01f, + 3.719767204029549301e-01f, + 3.581927710127054132e-01f, + 3.444415543260631041e-01f, + 3.307303549328605707e-01f, + 3.170663978989262666e-01f, + 3.034568439722529765e-01f, + 2.899087848484924179e-01f, + 2.764292384992768636e-01f, + 2.630251445668272403e-01f, + 2.497033598282397682e-01f, + 2.364706537327855851e-01f, + 2.233337040154965702e-01f, + 2.102990923902373910e-01f, + 1.973733003254070084e-01f, + 1.845627049053287227e-01f, + 1.718735747803255554e-01f, + 1.593120662083951089e-01f, + 1.468842191913231343e-01f, + 1.345959537079954305e-01f, + 1.224530660475812854e-01f, + 1.104612252451845633e-01f, + 9.862596962246501786e-02f, + 8.695270343564839854e-02f, + 7.544669363325365308e-02f, + 6.411306672577052335e-02f, + 5.295680576943356810e-02f, + 4.198274746613558234e-02f, + 3.119557938143482229e-02f, + 2.059983728250635790e-02f, + 1.019990259779169663e-02f, + 3.897210076277699062e-17f, + -9.995804885990083877e-03f, + -1.978360764887690526e-02f, + -2.935966712899029663e-02f, + -3.872040732740943125e-02f, + -4.786241918501666498e-02f, + -5.678246223045373131e-02f, + -6.547746609606562573e-02f, + -7.394453190101335505e-02f, + -8.218093350085642346e-02f, + -9.018411860300616645e-02f, + -9.795170974756001181e-02f, + -1.054815051531433207e-01f, + -1.127714794274846111e-01f, + -1.198197841425640842e-01f, + -1.266247482742862418e-01f, + -1.331848785067307750e-01f, + -1.394988594011491723e-01f, + -1.455655534299787057e-01f, + -1.513840008762573630e-01f, + -1.569534195989277237e-01f, + -1.622732046646232218e-01f, + -1.673429278466408709e-01f, + -1.721623369919041413e-01f, + -1.767313552568272883e-01f, + -1.810500802130950160e-01f, + -1.851187828244720002e-01f, + -1.889379062958614630e-01f, + -1.925080647959259983e-01f, + -1.958300420546892351e-01f, + -1.989047898376287982e-01f, + -2.017334262978687787e-01f, + -2.043172342081740200e-01f, + -2.066576590745419495e-01f, + -2.087563071332755593e-01f, + -2.106149432335147065e-01f, + -2.122354886072851110e-01f, + -2.136200185292154441e-01f, + -2.147707598681500851e-01f, + -2.156900885329726125e-01f, + -2.163805268150296168e-01f, + -2.168447406296239166e-01f, + -2.170855366591212532e-01f, + -2.171058594002854003e-01f, + -2.169087881185291500e-01f, + -2.164975337118347498e-01f, + -2.158754354871634251e-01f, + -2.150459578522372073e-01f, + -2.140126869256352149e-01f, + -2.127793270682061255e-01f, + -2.113496973388519218e-01f, + -2.097277278777923137e-01f, + -2.079174562204673671e-01f, + -2.059230235452841895e-01f, + -2.037486708584572426e-01f, + -2.013987351192330633e-01f, + -1.988776453088292318e-01f, + -1.961899184464536705e-01f, + -1.933401555558005303e-01f, + -1.903330375854543621e-01f, + -1.871733212866534823e-01f, + -1.838658350518955764e-01f, + -1.804154747178837448e-01f, + -1.768271993363320083e-01f, + -1.731060269161642517e-01f, + -1.692570301406509103e-01f, + -1.652853320630413847e-01f, + -1.611961017842489241e-01f, + -1.569945501161558454e-01f, + -1.526859252341015438e-01f, + -1.482755083221153625e-01f, + -1.437686092144501160e-01f, + -1.391705620369629026e-01f, + -1.344867208518796264e-01f, + -1.297224553094619426e-01f, + -1.248831463100814054e-01f, + -1.199741816801844635e-01f, + -1.150009518656041618e-01f, + -1.099688456456556773e-01f, + -1.048832458714182708e-01f, + -9.974952523157622208e-02f, + -9.457304204915860379e-02f, + -8.935913611247510435e-02f, + -8.411312454351556334e-02f, + -7.884029770702483120e-02f, + -7.354591516343182700e-02f, + -6.823520166875686466e-02f, + -6.291334322457314832e-02f, + -5.758548318104762115e-02f, + -5.225671839602590713e-02f, + -4.693209545307914371e-02f, + -4.161660694135679156e-02f, + -3.631518780004174690e-02f, + -3.103271173013015527e-02f, + -2.577398767619723877e-02f, + -2.054375638074063329e-02f, + -1.534668701362280202e-02f, + -1.018737387906320201e-02f, + -5.070333202553640312e-03f, + -3.894325756689964161e-17f, + 5.019274968688979509e-03f, + 9.983228159422152803e-03f, + 1.488768611509041877e-02f, + 1.972856824609843865e-02f, + 2.450188951836063458e-02f, + 2.920376304695326483e-02f, + 3.383040259369500535e-02f, + 3.837812496701634851e-02f, + 4.284335232256628045e-02f, + 4.722261436309905386e-02f, + 5.151255043626536828e-02f, + 5.570991152903332494e-02f, + 5.981156215754928479e-02f, + 6.381448215134405411e-02f, + 6.771576833088721603e-02f, + 7.151263607757946117e-02f, + 7.520242079537053925e-02f, + 7.878257926329076954e-02f, + 8.225069087826682168e-02f, + 8.560445878770081563e-02f, + 8.884171091137989251e-02f, + 9.196040085238070538e-02f, + 9.495860869672850813e-02f, + 9.783454170166935859e-02f, + 1.005865348725034220e-01f, + 1.032130514280261008e-01f, + 1.057126831547209184e-01f, + 1.080841506499338051e-01f, + 1.103263034543625065e-01f, + 1.124381200742803483e-01f, + 1.144187078940081537e-01f, + 1.162673029792436336e-01f, + 1.179832697719408463e-01f, + 1.195661006775294716e-01f, + 1.210154155453490032e-01f, + 1.223309610432607719e-01f, + 1.235126099274892336e-01f, + 1.245603602088281303e-01f, + 1.254743342164319486e-01f, + 1.262547775604956901e-01f, + 1.269020579952085670e-01f, + 1.274166641834456049e-01f, + 1.277992043647412090e-01f, + 1.280504049281650791e-01f, + 1.281711088917953933e-01f, + 1.281622742905593748e-01f, + 1.280249724742810735e-01f, + 1.277603863178479460e-01f, + 1.273698083454741226e-01f, + 1.268546387711058931e-01f, + 1.262163834570771692e-01f, + 1.254566517931865743e-01f, + 1.245771544984256851e-01f, + 1.235797013476476885e-01f, + 1.224661988255190126e-01f, + 1.212386477101517479e-01f, + 1.198991405888646528e-01f, + 1.184498593085685503e-01f, + 1.168930723633207630e-01f, + 1.152311322216329759e-01f, + 1.134664725961638115e-01f, + 1.116016056584608895e-01f, + 1.096391192014578575e-01f, + 1.075816737524645378e-01f, + 1.054319996394198350e-01f, + 1.031928940132054995e-01f, + 1.008672178288464866e-01f, + 9.845789278844846448e-02f, + 9.596789824874003838e-02f, + 9.340026809611248759e-02f, + 9.075808759205977738e-02f, + 8.804449019193870407e-02f, + 8.526265433997994025e-02f, + 8.241580024348756084e-02f, + 7.950718662917011237e-02f, + 7.654010748455197799e-02f, + 7.351788878741070954e-02f, + 7.044388522618756643e-02f, + 6.732147691431115966e-02f, + 6.415406610136678567e-02f, + 6.094507388403559711e-02f, + 5.769793691971696753e-02f, + 5.441610414572558424e-02f, + 5.110303350694805208e-02f, + 4.776218869481312773e-02f, + 4.439703590041457065e-02f, + 4.101104058459904139e-02f, + 3.760766426780321608e-02f, + 3.419036134239462205e-02f, + 3.076257591024030361e-02f, + 2.732773864819467574e-02f, + 2.388926370415486722e-02f, + 2.045054562630352346e-02f, + 1.701495632810792399e-02f, + 1.358584209160797196e-02f, + 1.016652061148060233e-02f, + 6.760278082314462311e-03f, + 3.370366331490179130e-03f, + 3.889521720231377172e-17f, + -3.347646226505052690e-03f, + -6.669440334209695946e-03f, + -9.962295642995425485e-03f, + -1.322317341155379231e-02f, + -1.644908538369398501e-02f, + -1.963709627384800302e-02f, + -2.278432618984587571e-02f, + -2.588795299108807499e-02f, + -2.894521458031795724e-02f, + -3.195341112725825355e-02f, + -3.490990722244410177e-02f, + -3.781213395966125795e-02f, + -4.065759094545921132e-02f, + -4.344384823429099651e-02f, + -4.616854818789777049e-02f, + -4.882940725763235124e-02f, + -5.142421768849166769e-02f, + -5.395084914370364831e-02f, + -5.640725024878998073e-02f, + -5.879145005410169045e-02f, + -6.110155941490798270e-02f, + -6.333577228818905447e-02f, + -6.549236694536995917e-02f, + -6.756970710030717198e-02f, + -6.956624295191975171e-02f, + -7.148051214093797956e-02f, + -7.331114062032219325e-02f, + -7.505684343898266775e-02f, + -7.671642543851386886e-02f, + -7.828878186273431627e-02f, + -7.977289887990460238e-02f, + -8.116785401757553586e-02f, + -8.247281651009769066e-02f, + -8.368704755890117586e-02f, + -8.480990050573701533e-02f, + -8.584082091914502222e-02f, + -8.677934659449468291e-02f, + -8.762510746802033845e-02f, + -8.837782544534880658e-02f, + -8.903731414509374886e-02f, + -8.960347855816586105e-02f, + -9.007631462352130858e-02f, + -9.045590872114415981e-02f, + -9.074243708313121937e-02f, + -9.093616512381758055e-02f, + -9.103744668995188138e-02f, + -9.104672323199845818e-02f, + -9.096452289771120303e-02f, + -9.079145954918992067e-02f, + -9.052823170469484482e-02f, + -9.017562140655861758e-02f, + -8.973449301659575106e-02f, + -8.920579194047170701e-02f, + -8.859054328255137889e-02f, + -8.788985043280389542e-02f, + -8.710489358739707810e-02f, + -8.623692820466778708e-02f, + -8.528728339820713933e-02f, + -8.425736026884980689e-02f, + -8.314863017740434237e-02f, + -8.196263296000964871e-02f, + -8.070097508804566222e-02f, + -7.936532777456997700e-02f, + -7.795742502929374484e-02f, + -7.647906166414730755e-02f, + -7.493209125152387740e-02f, + -7.331842403732392877e-02f, + -7.164002481095702035e-02f, + -6.989891073448464831e-02f, + -6.809714913312167606e-02f, + -6.623685524933471680e-02f, + -6.432018996280304546e-02f, + -6.234935747852995286e-02f, + -6.032660298541026728e-02f, + -5.825421028757805930e-02f, + -5.613449941087523404e-02f, + -5.396982418679260179e-02f, + -5.176256981624846598e-02f, + -4.951515041557684460e-02f, + -4.723000654710355489e-02f, + -4.490960273669408059e-02f, + -4.255642498066016660e-02f, + -4.017297824440700660e-02f, + -3.776178395520819048e-02f, + -3.532537749148359496e-02f, + -3.286630567095341626e-02f, + -3.038712424003185350e-02f, + -2.789039536681189174e-02f, + -2.537868513997948439e-02f, + -2.285456107598123413e-02f, + -2.032058963675330288e-02f, + -1.777933376029512333e-02f, + -1.523335040635749593e-02f, + -1.268518811948355154e-02f, + -1.013738461162063884e-02f, + -7.592464366493653291e-03f, + -5.052936267896138492e-03f, + -2.521291254032028643e-03f, + -3.882802707905923401e-17f, + 2.508489369517248428e-03f, + 5.001753535334178304e-03f, + 7.477396204630696805e-03f, + 9.933050295659225093e-03f, + 1.236638008438947431e-02f, + 1.477508331123026167e-02f, + 1.715689324600980226e-02f, + 1.950958070945080572e-02f, + 2.183095604941610521e-02f, + 2.411887107025306037e-02f, + 2.637122091361803269e-02f, + 2.858594588921111249e-02f, + 3.076103325390444967e-02f, + 3.289451893780558772e-02f, + 3.498448921585006754e-02f, + 3.702908232357217388e-02f, + 3.902649001576798810e-02f, + 4.097495906681519057e-02f, + 4.287279271148002058e-02f, + 4.471835202509810703e-02f, + 4.651005724208144565e-02f, + 4.824638901176293154e-02f, + 4.992588959065285409e-02f, + 5.154716397024793756e-02f, + 5.310888093959532930e-02f, + 5.460977408187722010e-02f, + 5.604864270435185730e-02f, + 5.742435270104698924e-02f, + 5.873583734766929521e-02f, + 5.998209802826119652e-02f, + 6.116220489320042114e-02f, + 6.227529744820328728e-02f, + 6.332058507406373993e-02f, + 6.429734747692100738e-02f, + 6.520493506891764102e-02f, + 6.604276927917780704e-02f, + 6.681034279509827367e-02f, + 6.750721973401248299e-02f, + 6.813303574535393980e-02f, + 6.868749804350914034e-02f, + 6.917038537161544764e-02f, + 6.958154789662478190e-02f, + 6.992090703601620827e-02f, + 7.018845521660418973e-02f, + 7.038425556595274968e-02f, + 7.050844153696640693e-02f, + 7.056121646629046062e-02f, + 7.054285306721332083e-02f, + 7.045369285782319968e-02f, + 7.029414552522963988e-02f, + 7.006468822671796381e-02f, + 6.976586482876150075e-02f, + 6.939828508487122516e-02f, + 6.896262375331772831e-02f, + 6.845961965581227882e-02f, + 6.789007467828668541e-02f, + 6.725485271496202400e-02f, + 6.655487855694536270e-02f, + 6.579113672664134438e-02f, + 6.496467025931394745e-02f, + 6.407657943317585092e-02f, + 6.312802044942868174e-02f, + 6.212020406372047165e-02f, + 6.105439417052395401e-02f, + 5.993190634198172773e-02f, + 5.875410632280082118e-02f, + 5.752240848281407054e-02f, + 5.623827422886059496e-02f, + 5.490321037767217222e-02f, + 5.351876749147910922e-02f, + 5.208653817808057279e-02f, + 5.060815535715459945e-02f, + 4.908529049460156474e-02f, + 4.751965180674513900e-02f, + 4.591298243623419262e-02f, + 4.426705860150847993e-02f, + 4.258368772170978422e-02f, + 4.086470651893956557e-02f, + 3.911197909977250781e-02f, + 3.732739501795391546e-02f, + 3.551286732021802228e-02f, + 3.367033057717121886e-02f, + 3.180173890119344232e-02f, + 2.990906395331716441e-02f, + 2.799429294104273033e-02f, + 2.605942660905504957e-02f, + 2.410647722480178945e-02f, + 2.213746656089659454e-02f, + 2.015442387629913859e-02f, + 1.815938389822458268e-02f, + 1.615438480672493765e-02f, + 1.414146622387316317e-02f, + 1.212266720947206833e-02f, + 1.010002426519698848e-02f, + 8.075569349063350597e-03f, + 6.051327902095616530e-03f, + 4.029316889058113388e-03f, + 2.011542855081033601e-03f, + 3.874175350567572650e-17f, + -2.003331727797961342e-03f, + -3.996488516257723500e-03f, + -5.977524551525892349e-03f, + -7.944513855095518967e-03f, + -9.895552094544582400e-03f, + -1.182875836621732034e-02f, + -1.374227694822771975e-02f, + -1.563427902220560287e-02f, + -1.750296436223446397e-02f, + -1.934656298946970526e-02f, + -2.116333679096629727e-02f, + -2.295158110128149576e-02f, + -2.470962624546017145e-02f, + -2.643583904205206586e-02f, + -2.812862426485629452e-02f, + -2.978642606212655863e-02f, + -3.140772933202141265e-02f, + -3.299106105312992615e-02f, + -3.453499156894547506e-02f, + -3.603813582521487452e-02f, + -3.749915455913428036e-02f, + -3.891675543941802012e-02f, + -4.028969415631109691e-02f, + -4.161677546067264061e-02f, + -4.289685415130901208e-02f, + -4.412883600978426135e-02f, + -4.531167868199265092e-02f, + -4.644439250583275169e-02f, + -4.752604128436910269e-02f, + -4.855574300393437209e-02f, + -4.953267049666788130e-02f, + -5.045605204704892155e-02f, + -5.132517194203765898e-02f, + -5.213937096448940933e-02f, + -5.289804682956641274e-02f, + -5.360065456392785338e-02f, + -5.424670682753111178e-02f, + -5.483577417793748798e-02f, + -5.536748527706834150e-02f, + -5.584152704041558252e-02f, + -5.625764472876377403e-02f, + -5.661564198253816321e-02f, + -5.691538079894768037e-02f, + -5.715678145214542205e-02f, + -5.733982235668498573e-02f, + -5.746453987460405782e-02f, + -5.753102806651958639e-02f, + -5.753943838717312520e-02f, + -5.748997932591520116e-02f, + -5.738291599267093812e-02f, + -5.721856964997878298e-02f, + -5.699731719174516015e-02f, + -5.671959056940642507e-02f, + -5.638587616623912807e-02f, + -5.599671412060634040e-02f, + -5.555269759897443066e-02f, + -5.505447201958245385e-02f, + -5.450273422768755344e-02f, + -5.389823162335748846e-02f, + -5.324176124282154615e-02f, + -5.253416879443297688e-02f, + -5.177634765033799907e-02f, + -5.096923779498445384e-02f, + -5.011382473164045781e-02f, + -4.921113834813311411e-02f, + -4.826225174304939192e-02f, + -4.726828001367859577e-02f, + -4.623037900700535663e-02f, + -4.514974403509764561e-02f, + -4.402760855626140085e-02f, + -4.286524282336175162e-02f, + -4.166395250074144546e-02f, + -4.042507725118998224e-02f, + -3.914998929443946202e-02f, + -3.784009193869437848e-02f, + -3.649681808671064592e-02f, + -3.512162871797221836e-02f, + -3.371601134852347803e-02f, + -3.228147847003334792e-02f, + -3.081956596968622730e-02f, + -2.933183153250423780e-02f, + -2.781985302771665045e-02f, + -2.628522688080791453e-02f, + -2.472956643287790510e-02f, + -2.315450028896036058e-02f, + -2.156167065694567300e-02f, + -1.995273167876449386e-02f, + -1.832934775548567333e-02f, + -1.669319186798288307e-02f, + -1.504594389482788452e-02f, + -1.338928892906133400e-02f, + -1.172491559548742221e-02f, + -1.005451437013836664e-02f, + -8.379775903540833196e-03f, + -6.702389349412756978e-03f, + -5.024040700403363362e-03f, + -3.346411132483765802e-03f, + -1.671175359577019423e-03f, + -3.863648162376423474e-17f, + 1.665458043716377392e-03f, + 3.323553190096430274e-03f, + 4.972652767551836474e-03f, + 6.611138585273553490e-03f, + 8.237408484711907647e-03f, + 9.849877870182622078e-03f, + 1.144698121717139215e-02f, + 1.302717355693413029e-02f, + 1.458893193601275978e-02f, + 1.613075684932130729e-02f, + 1.765117364548211831e-02f, + 1.914873390312786527e-02f, + 2.062201677691140322e-02f, + 2.206963031200360678e-02f, + 2.349021272589388309e-02f, + 2.488243365633890924e-02f, + 2.624499537434637694e-02f, + 2.757663396111778922e-02f, + 2.887612044790845850e-02f, + 3.014226191780771530e-02f, + 3.137390256847804454e-02f, + 3.256992473493734719e-02f, + 3.372924987150486414e-02f, + 3.485083949207803955e-02f, + 3.593369606795079885e-02f, + 3.697686388242336919e-02f, + 3.797942984150279311e-02f, + 3.894052424003760504e-02f, + 3.985932148267041369e-02f, + 4.073504075904751942e-02f, + 4.156694667276145810e-02f, + 4.235434982355489736e-02f, + 4.309660734236082924e-02f, + 4.379312337879810030e-02f, + 4.444334954079259131e-02f, + 4.504678528604074556e-02f, + 4.560297826507851010e-02f, + 4.611152461576945721e-02f, + 4.657206920907153852e-02f, + 4.698430584599172510e-02f, + 4.734797740568404828e-02f, + 4.766287594469555827e-02f, + 4.792884274741274209e-02f, + 4.814576832780684268e-02f, + 4.831359238262550315e-02f, + 4.843230369622460174e-02f, + 4.850193999728014821e-02f, + 4.852258776766780329e-02f, + 4.849438200384208891e-02f, + 4.841750593109390294e-02f, + 4.829219067110925023e-02f, + 4.811871486329679509e-02f, + 4.789740424039561073e-02f, + 4.762863115891774468e-02f, + 4.731281408502291397e-02f, + 4.695041703646362502e-02f, + 4.654194898128217323e-02f, + 4.608796319397825969e-02f, + 4.558905656990844268e-02f, + 4.504586889871579902e-02f, + 4.445908209762516189e-02f, + 4.382941940547854798e-02f, + 4.315764453841920700e-02f, + 4.244456080816757376e-02f, + 4.169101020386845047e-02f, + 4.089787243851888271e-02f, + 4.006606396102018602e-02f, + 3.919653693492577279e-02f, + 3.829027818498920155e-02f, + 3.734830811264253092e-02f, + 3.637167958156230230e-02f, + 3.536147677450902915e-02f, + 3.431881402264831682e-02f, + 3.324483460858414924e-02f, + 3.214070954436337030e-02f, + 3.100763632572139938e-02f, + 2.984683766386852025e-02f, + 2.865956019612891231e-02f, + 2.744707317676135447e-02f, + 2.621066714931024125e-02f, + 2.495165260184606035e-02f, + 2.367135860646735895e-02f, + 2.237113144445156826e-02f, + 2.105233321844750261e-02f, + 1.971634045311482925e-02f, + 1.836454268561935055e-02f, + 1.699834104740382407e-02f, + 1.561914683865467043e-02f, + 1.422838009688787327e-02f, + 1.282746816108333576e-02f, + 1.141784423279322037e-02f, + 1.000094593564865818e-02f, + 8.578213874691159244e-03f, + 7.151090196945879447e-03f, + 5.721017154652988448e-03f, + 4.289435672562395829e-03f, + 2.857783920694851112e-03f, + 1.427495893958731022e-03f, + 3.851231532396259107e-17f, + -1.423282343340041833e-03f, + -2.840938099612009063e-03f, + -4.251563993045895384e-03f, + -5.653767874212517128e-03f, + -7.046170070757393038e-03f, + -8.427404721911885624e-03f, + -9.796121095514335672e-03f, + -1.115098488629330704e-02f, + -1.249067949418276348e-02f, + -1.381390728146736184e-02f, + -1.511939080757592098e-02f, + -1.640587404037048558e-02f, + -1.767212354279941791e-02f, + -1.891692963381457968e-02f, + -2.013910752248064540e-02f, + -2.133749841423027843e-02f, + -2.251097058825281272e-02f, + -2.365842044503514013e-02f, + -2.477877352310193029e-02f, + -2.587098548403953327e-02f, + -2.693404306491827341e-02f, + -2.796696499726556220e-02f, + -2.896880289177323695e-02f, + -2.993864208796185450e-02f, + -3.087560246806111269e-02f, + -3.177883923439979441e-02f, + -3.264754364963919769e-02f, + -3.348094373922329975e-02f, + -3.427830495545182432e-02f, + -3.503893080263100618e-02f, + -3.576216342278743660e-02f, + -3.644738414147634387e-02f, + -3.709401397325490235e-02f, + -3.770151408643012542e-02f, + -3.826938622673421719e-02f, + -3.879717309962135707e-02f, + -3.928445871091951203e-02f, + -3.973086866561512109e-02f, + -4.013607042458825630e-02f, + -4.049977351915948903e-02f, + -4.082172972334963124e-02f, + -4.110173318379706925e-02f, + -4.133962050731876392e-02f, + -4.153527080614199951e-02f, + -4.168860570087641604e-02f, + -4.179958928133744450e-02f, + -4.186822802537215615e-02f, + -4.189457067588118339e-02f, + -4.187870807626980357e-02f, + -4.182077296460211258e-02f, + -4.172093972677210633e-02f, + -4.157942410904505448e-02f, + -4.139648289036141487e-02f, + -4.117241351483449247e-02f, + -4.090755368491114791e-02f, + -4.060228091570139419e-02f, + -4.025701205102193148e-02f, + -3.987220274173181034e-02f, + -3.944834688697711200e-02f, + -3.898597603899465330e-02f, + -3.848565877215900932e-02f, + -3.794800001699184799e-02f, + -3.737364035988401112e-02f, + -3.676325530931268126e-02f, + -3.611755452936806637e-02f, + -3.543728104143289981e-02f, + -3.472321039488834166e-02f, + -3.397614980774645715e-02f, + -3.319693727813939621e-02f, + -3.238644066761971890e-02f, + -3.154555675725123631e-02f, + -3.067521027749671447e-02f, + -2.977635291292965100e-02f, + -2.884996228281870578e-02f, + -2.789704089865994302e-02f, + -2.691861509974309216e-02f, + -2.591573396786606143e-02f, + -2.488946822232386211e-02f, + -2.384090909631557051e-02f, + -2.277116719593108921e-02f, + -2.168137134289090454e-02f, + -2.057266740222485346e-02f, + -1.944621709609118537e-02f, + -1.830319680494362292e-02f, + -1.714479635726702186e-02f, + -1.597221780910678887e-02f, + -1.478667421462878662e-02f, + -1.358938838894852355e-02f, + -1.238159166447296011e-02f, + -1.116452264200503558e-02f, + -9.939425937859529617e-03f, + -8.707550928239674026e-03f, + -7.470150492127149849e-03f, + -6.228479753931915469e-03f, + -4.983794827149027815e-03f, + -3.737351560261789520e-03f, + -2.490404286130025371e-03f, + -1.244204576092051940e-03f, + -3.836937714341790683e-17f, + 1.240967106592762116e-03f, + 2.477460866896080867e-03f, + 3.708253077802783210e-03f, + 4.932124414085086068e-03f, + 6.147865620704987162e-03f, + 7.354278692082365058e-03f, + 8.550178037189383809e-03f, + 9.734391629351839964e-03f, + 1.090576213965407243e-02f, + 1.206314805286936957e-02f, + 1.320542476485127813e-02f, + 1.433148566034425815e-02f, + 1.544024317019840505e-02f, + 1.653062980698680531e-02f, + 1.760159917805776894e-02f, + 1.865212697506991868e-02f, + 1.968121193909236344e-02f, + 2.068787680036934112e-02f, + 2.167116919188432494e-02f, + 2.263016253588231996e-02f, + 2.356395690253657721e-02f, + 2.447167983997980412e-02f, + 2.535248717494724760e-02f, + 2.620556378330855113e-02f, + 2.703012432980111263e-02f, + 2.782541397630681687e-02f, + 2.859070905804561927e-02f, + 2.932531772709678214e-02f, + 3.002858056268817993e-02f, + 3.069987114772966194e-02f, + 3.133859661110379585e-02f, + 3.194419813525677804e-02f, + 3.251615142867379793e-02f, + 3.305396716285353975e-02f, + 3.355719137343705916e-02f, + 3.402540582517922518e-02f, + 3.445822834048845734e-02f, + 3.485531309129908523e-02f, + 3.521635085407364557e-02f, + 3.554106922777330868e-02f, + 3.582923281466892512e-02f, + 3.608064336390364585e-02f, + 3.629513987775428302e-02f, + 3.647259868057688842e-02f, + 3.661293345045708858e-02f, + 3.671609521362455969e-02f, + 3.678207230172601816e-02f, + 3.681089027208912096e-02f, + 3.680261179114461406e-02f, + 3.675733648121128072e-02f, + 3.667520073088332416e-02f, + 3.655637746929544379e-02f, + 3.640107590457612730e-02f, + 3.620954122683402165e-02f, + 3.598205427605740553e-02f, + 3.571893117533903733e-02f, + 3.542052292987402790e-02f, + 3.508721499220928547e-02f, + 3.471942679425710915e-02f, + 3.431761124661530937e-02f, + 3.388225420576965186e-02f, + 3.341387390978267646e-02f, + 3.291302038310394557e-02f, + 3.238027481116542705e-02f, + 3.181624888545521446e-02f, + 3.122158411978745787e-02f, + 3.059695113851780904e-02f, + 2.994304893747514948e-02f, + 2.926060411840791450e-02f, + 2.855037009776879506e-02f, + 2.781312629068145512e-02f, + 2.704967727096032129e-02f, + 2.626085190807075573e-02f, + 2.544750248194389483e-02f, + 2.461050377657450841e-02f, + 2.375075215335195958e-02f, + 2.286916460509363230e-02f, + 2.196667779176278423e-02f, + 2.104424705887289471e-02f, + 2.010284543959429265e-02f, + 1.914346264158977087e-02f, + 1.816710401962278246e-02f, + 1.717478953499241082e-02f, + 1.616755270285690979e-02f, + 1.514643952852146903e-02f, + 1.411250743377312315e-02f, + 1.306682417434898782e-02f, + 1.201046674963833320e-02f, + 1.094452030571538628e-02f, + 9.870077032812075643e-03f, + 8.788235058334580366e-03f, + 7.700097336538626325e-03f, + 6.606770535970839416e-03f, + 5.509363925787424780e-03f, + 4.408988262061687424e-03f, + 3.306754675183733866e-03f, + 2.203773559457802150e-03f, + 1.101153465996373331e-03f, + 3.820780814485725242e-17f, + -1.098585276486098786e-03f, + -2.193505935265162299e-03f, + -3.283671765059895803e-03f, + -4.367999845902193791e-03f, + -5.445415613796268477e-03f, + -6.514853914614496255e-03f, + -7.575260046206469533e-03f, + -8.625590787711353430e-03f, + -9.664815415077104843e-03f, + -1.069191670181151264e-02f, + -1.170589190400125879e-02f, + -1.270575372865473569e-02f, + -1.369053128444692319e-02f, + -1.465927101395613288e-02f, + -1.561103760651160084e-02f, + -1.654491489078413133e-02f, + -1.746000670628177626e-02f, + -1.835543775292705626e-02f, + -1.923035441792335376e-02f, + -2.008392557913836474e-02f, + -2.091534338425668146e-02f, + -2.172382400498286056e-02f, + -2.250860836560024739e-02f, + -2.326896284521650510e-02f, + -2.400417995305826127e-02f, + -2.471357897620288582e-02f, + -2.539650659916279848e-02f, + -2.605233749477112518e-02f, + -2.668047488584292248e-02f, + -2.728035107711810139e-02f, + -2.785142795702474916e-02f, + -2.839319746882786391e-02f, + -2.890518205076497357e-02f, + -2.938693504479734583e-02f, + -2.983804107364120342e-02f, + -3.025811638577266885e-02f, + -3.064680916813381298e-02f, + -3.100379982630099840e-02f, + -3.132880123190676103e-02f, + -3.162155893714221899e-02f, + -3.188185135619839294e-02f, + -3.210948991353843734e-02f, + -3.230431915892578026e-02f, + -3.246621684916723566e-02f, + -3.259509399656147777e-02f, + -3.269089488407847521e-02f, + -3.275359704732655475e-02f, + -3.278321122339819538e-02f, + -3.277978126671703824e-02f, + -3.274338403204220954e-02f, + -3.267412922481752885e-02f, + -3.257215921908560019e-02f, + -3.243764884321845982e-02f, + -3.227080513374773474e-02f, + -3.207186705760879664e-02f, + -3.184110520314317044e-02f, + -3.157882144023508447e-02f, + -3.128534854998637343e-02f, + -3.096104982436503894e-02f, + -3.060631863628960475e-02f, + -3.022157798064227172e-02f, + -2.980727998672943677e-02f, + -2.936390540273656549e-02f, + -2.889196305275088666e-02f, + -2.839198926695188710e-02f, + -2.786454728559313240e-02f, + -2.731022663742679185e-02f, + -2.672964249324305541e-02f, + -2.612343499522145479e-02f, + -2.549226856281475509e-02f, + -2.483683117590470071e-02f, + -2.415783363599420183e-02f, + -2.345600880621569531e-02f, + -2.273211083096061610e-02f, + -2.198691433594817182e-02f, + -2.122121360957183317e-02f, + -2.043582176638020914e-02f, + -1.963156989356096283e-02f, + -1.880930618131524887e-02f, + -1.796989503802343471e-02f, + -1.711421619111335238e-02f, + -1.624316377455840843e-02f, + -1.535764540394315113e-02f, + -1.445858124004167390e-02f, + -1.354690304186740787e-02f, + -1.262355321016035703e-02f, + -1.168948382228147259e-02f, + -1.074565565949768715e-02f, + -9.793037227638747358e-03f, + -8.832603772118776536e-03f, + -7.865336288311713595e-03f, + -6.892220528280442078e-03f, + -5.914246004853488010e-03f, + -4.932404994047567826e-03f, + -3.947691536835270382e-03f, + -2.961100441250685226e-03f, + -1.973626285828549223e-03f, + -9.862624253675238758e-04f, + -3.802776777737574016e-17f, + 9.841730514465974952e-04f, + 1.965272972826986615e-03f, + 2.942321165824257449e-03f, + 3.914345157906578068e-03f, + 4.880379562147291184e-03f, + 5.839467027964861424e-03f, + 6.790659181857343525e-03f, + 7.733017557214086520e-03f, + 8.665614512298646516e-03f, + 9.587534135515569239e-03f, + 1.049787313708307364e-02f, + 1.139574172625059875e-02f, + 1.228026447321984953e-02f, + 1.315058115493771343e-02f, + 1.400584758395503719e-02f, + 1.484523641955660424e-02f, + 1.566793796039387537e-02f, + 1.647316091786455577e-02f, + 1.726013316951060736e-02f, + 1.802810249172396087e-02f, + 1.877633727107054853e-02f, + 1.950412719356916028e-02f, + 2.021078391128274671e-02f, + 2.089564168560189075e-02f, + 2.155805800663082583e-02f, + 2.219741418810250791e-02f, + 2.281311593728354431e-02f, + 2.340459389934918671e-02f, + 2.397130417573897082e-02f, + 2.451272881602797882e-02f, + 2.502837628287757701e-02f, + 2.551778188965732330e-02f, + 2.598050821035589528e-02f, + 2.641614546142960138e-02f, + 2.682431185526281195e-02f, + 2.720465392494783932e-02f, + 2.755684682011533618e-02f, + 2.788059457358115292e-02f, + 2.817563033860144908e-02f, + 2.844171659655807607e-02f, + 2.867864533492812257e-02f, + 2.888623819541892568e-02f, + 2.906434659218049346e-02f, + 2.921285180003846058e-02f, + 2.933166501271905480e-02f, + 2.942072737106802074e-02f, + 2.948000996129596790e-02f, + 2.950951378331144459e-02f, + 2.950926968923310578e-02f, + 2.947933829220211049e-02f, + 2.941980984564465662e-02f, + 2.933080409316416587e-02f, + 2.921247008927130642e-02f, + 2.906498599118855983e-02f, + 2.888855882199470315e-02f, + 2.868342420540245102e-02f, + 2.844984607248968178e-02f, + 2.818811634073307634e-02f, + 2.789855456571845721e-02f, + 2.758150756593012731e-02f, + 2.723734902104646763e-02f, + 2.686647904419447314e-02f, + 2.646932372864202465e-02f, + 2.604633466943028636e-02f, + 2.559798846047255452e-02f, + 2.512478616767030437e-02f, + 2.462725277861903608e-02f, + 2.410593662949834029e-02f, + 2.356140880976381052e-02f, + 2.299426254527723104e-02f, + 2.240511256053460618e-02f, + 2.179459442066713701e-02f, + 2.116336385391225788e-02f, + 2.051209605527045191e-02f, + 1.984148497207598519e-02f, + 1.915224257223392679e-02f, + 1.844509809588383564e-02f, + 1.772079729127159706e-02f, + 1.698010163562099079e-02f, + 1.622378754181329208e-02f, + 1.545264555169341587e-02f, + 1.466747951683269359e-02f, + 1.386910576759178837e-02f, + 1.305835227133488388e-02f, + 1.223605778065572393e-02f, + 1.140307097248631669e-02f, + 1.056024957896441879e-02f, + 9.708459510942056905e-03f, + 8.848573975026030602e-03f, + 7.981472585042176035e-03f, + 7.108040468822868913e-03f, + 6.229167371217365738e-03f, + 5.345746754226499142e-03f, + 4.458674895167382204e-03f, + 3.568849983769900418e-03f, + 2.677171219111589007e-03f, + 1.784537907287459457e-03f, + 8.918485607199820456e-04f, + 1.375963414501481870e-16f, + -8.901135408467832598e-04f, + -1.777601304782279023e-03f, + -2.661576896985846409e-03f, + -3.541159164019371322e-03f, + -4.415473066061055551e-03f, + -5.283650541348036689e-03f, + -6.144831361984745034e-03f, + -6.998163980273221924e-03f, + -7.842806364743631908e-03f, + -8.677926825066678909e-03f, + -9.502704825047591716e-03f, + -1.031633178291084009e-02f, + -1.111801185810167188e-02f, + -1.190696272384546804e-02f, + -1.268241632471873645e-02f, + -1.344361961850560477e-02f, + -1.418983530162710137e-02f, + -1.492034251745096018e-02f, + -1.563443754680784656e-02f, + -1.633143448005669809e-02f, + -1.701066587006366121e-02f, + -1.767148336547917642e-02f, + -1.831325832371670168e-02f, + -1.893538240305999570e-02f, + -1.953726813334768359e-02f, + -2.011834946470413346e-02f, + -2.067808229381145821e-02f, + -2.121594496723701664e-02f, + -2.173143876136030342e-02f, + -2.222408833845995052e-02f, + -2.269344217855321158e-02f, + -2.313907298660076647e-02f, + -2.356057807471537494e-02f, + -2.395757971904149269e-02f, + -2.432972549099499809e-02f, + -2.467668856258116092e-02f, + -2.499816798553347250e-02f, + -2.529388894404376378e-02f, + -2.556360298088074245e-02f, + -2.580708819671996904e-02f, + -2.602414942253634608e-02f, + -2.621461836493719708e-02f, + -2.637835372434049752e-02f, + -2.651524128593106544e-02f, + -2.662519398335435120e-02f, + -2.670815193513444846e-02f, + -2.676408245383069331e-02f, + -2.679298002797401990e-02f, + -2.679486627685148323e-02f, + -2.676978987823442138e-02f, + -2.671782646917223933e-02f, + -2.663907852000062249e-02f, + -2.653367518173962297e-02f, + -2.640177210708273547e-02f, + -2.624355124520492619e-02f, + -2.605922061064226344e-02f, + -2.584901402652179520e-02f, + -2.561319084244592648e-02f, + -2.535203562735873287e-02f, + -2.506585783774740658e-02f, + -2.475499146155598143e-02f, + -2.441979463821075669e-02f, + -2.406064925518100819e-02f, + -2.367796052152183056e-02f, + -2.327215651886596973e-02f, + -2.284368773035500011e-02f, + -2.239302654802176329e-02f, + -2.192066675915328375e-02f, + -2.142712301218852727e-02f, + -2.091293026271947089e-02f, + -2.037864320018679606e-02f, + -1.982483565587724039e-02f, + -1.925209999284902343e-02f, + -1.866104647842747183e-02f, + -1.805230263992868914e-02f, + -1.742651260428690341e-02f, + -1.678433642227292188e-02f, + -1.612644937800953443e-02f, + -1.545354128449657159e-02f, + -1.476631576587938456e-02f, + -1.406548952719811375e-02f, + -1.335179161237267514e-02f, + -1.262596265118436090e-02f, + -1.188875409602925537e-02f, + -1.114092744922038150e-02f, + -1.038325348163284326e-02f, + -9.616511443484248786e-03f, + -8.841488268055055361e-03f, + -8.058977769158835736e-03f, + -7.269779833172840267e-03f, + -6.474699606447542784e-03f, + -5.674546678917565326e-03f, + -4.870134264732259473e-03f, + -4.062278380735639960e-03f, + -3.251797023616004832e-03f, + -2.439509346553158861e-03f, + -1.626234836185142018e-03f, + -8.127924907184056955e-04f, + -3.761300170173902632e-17f, + 8.113270716327609542e-04f, + 1.620376098912416430e-03f, + 2.426338204803805097e-03f, + 3.228409064469819033e-03f, + 4.025789703243586731e-03f, + 4.817687287821219300e-03f, + 5.603315909897037261e-03f, + 6.381897361469502858e-03f, + 7.152661901059502447e-03f, + 7.914849010088072581e-03f, + 8.667708138679361060e-03f, + 9.410499440156691597e-03f, + 1.014249449352174620e-02f, + 1.086297701321397788e-02f, + 1.157124354546169333e-02f, + 1.226660415055517636e-02f, + 1.294838307038302834e-02f, + 1.361591938058873304e-02f, + 1.426856762672633859e-02f, + 1.490569844380274823e-02f, + 1.552669915862028849e-02f, + 1.613097437434502304e-02f, + 1.671794653674912173e-02f, + 1.728705648159101563e-02f, + 1.783776396262254024e-02f, + 1.836954815972504512e-02f, + 1.888190816670458697e-02f, + 1.937436345829177120e-02f, + 1.984645433591701591e-02f, + 2.029774235185137846e-02f, + 2.072781071132718048e-02f, + 2.113626465227521484e-02f, + 2.152273180233675934e-02f, + 2.188686251283411544e-02f, + 2.222833016940416184e-02f, + 2.254683147902725865e-02f, + 2.284208673320283281e-02f, + 2.311384004705211576e-02f, + 2.336185957414964667e-02f, + 2.358593769691042299e-02f, + 2.378589119238579130e-02f, + 2.396156137334416389e-02f, + 2.411281420453805294e-02f, + 2.423954039408468888e-02f, + 2.434165545991162638e-02f, + 2.441909977124352010e-02f, + 2.447183856513244701e-02f, + 2.449986193805772303e-02f, + 2.450318481264677009e-02f, + 2.448184687959331640e-02f, + 2.443591251487354371e-02f, + 2.436547067238563694e-02f, + 2.427063475216228658e-02f, + 2.415154244432998407e-02f, + 2.400835554901284072e-02f, + 2.384125977240247538e-02f, + 2.365046449923850422e-02f, + 2.343620254196809860e-02f, + 2.319872986687494115e-02f, + 2.293832529749150265e-02f, + 2.265529019562997209e-02f, + 2.234994812038883921e-02f, + 2.202264446551434676e-02f, + 2.167374607551639937e-02f, + 2.130364084095871455e-02f, + 2.091273727336449839e-02f, + 2.050146406019705617e-02f, + 2.007026960039413541e-02f, + 1.961962152095459225e-02f, + 1.915000617509209774e-02f, + 1.866192812249098040e-02f, + 1.815590959221258585e-02f, + 1.763248992881976882e-02f, + 1.709222502230338045e-02f, + 1.653568672240555287e-02f, + 1.596346223795577085e-02f, + 1.537615352184286931e-02f, + 1.477437664226473150e-02f, + 1.415876114090650062e-02f, + 1.352994937871285740e-02f, + 1.288859586992923897e-02f, + 1.223536660509748700e-02f, + 1.157093836370297682e-02f, + 1.089599801717802338e-02f, + 1.021124182297453685e-02f, + 9.517374710428586071e-03f, + 8.815109559144568979e-03f, + 8.105166470632777995e-03f, + 7.388272033942047505e-03f, + 6.665158586030823715e-03f, + 5.936563467627156351e-03f, + 5.203228275329005968e-03f, + 4.465898110698729960e-03f, + 3.725320827109799334e-03f, + 2.982246275101344511e-03f, + 2.237425547001025122e-03f, + 1.491610221569002930e-03f, + 7.455516094238633746e-04f, + -4.603360121389620097e-17f, + -7.442960892099980894e-04f, + -1.486590660381493286e-03f, + -2.226140979308201089e-03f, + -2.962208314840183033e-03f, + -3.694058673076393295e-03f, + -4.420963525583790008e-03f, + -5.142200530928310413e-03f, + -5.857054248801788626e-03f, + -6.564816846046666980e-03f, + -7.264788793882578921e-03f, + -7.956279555653332503e-03f, + -8.638608264420137572e-03f, + -9.311104389740483545e-03f, + -9.973108392984011278e-03f, + -1.062397237054689761e-02f, + -1.126306068434249248e-02f, + -1.188975057895664926e-02f, + -1.250343278487292369e-02f, + -1.310351210718740250e-02f, + -1.368940799924666003e-02f, + -1.426055512066000397e-02f, + -1.481640387915378679e-02f, + -1.535642095575079358e-02f, + -1.588008981277712686e-02f, + -1.638691118421688533e-02f, + -1.687640354795164402e-02f, + -1.734810357944292433e-02f, + -1.780156658643218884e-02f, + -1.823636692425711220e-02f, + -1.865209839139694153e-02f, + -1.904837460488604042e-02f, + -1.942482935525157578e-02f, + -1.978111694065281395e-02f, + -2.011691247992323031e-02f, + -2.043191220423512186e-02f, + -2.072583372713042438e-02f, + -2.099841629268202337e-02f, + -2.124942100157323904e-02f, + -2.147863101490525214e-02f, + -2.168585173556427867e-02f, + -2.187091096700358173e-02f, + -2.203365904931835206e-02f, + -2.217396897251361007e-02f, + -2.229173646688911367e-02f, + -2.238688007048804385e-02f, + -2.245934117357874585e-02f, + -2.250908404016256636e-02f, + -2.253609580652320837e-02f, + -2.254038645685636430e-02f, + -2.252198877604117550e-02f, + -2.248095827963758273e-02f, + -2.241737312121652378e-02f, + -2.233133397715249616e-02f, + -2.222296390902992261e-02f, + -2.209240820383755882e-02f, + -2.193983419214646027e-02f, + -2.176543104448896288e-02f, + -2.156940954617817680e-02f, + -2.135200185082751848e-02f, + -2.111346121285143443e-02f, + -2.085406169924960626e-02f, + -2.057409788099558851e-02f, + -2.027388450437186615e-02f, + -1.995375614261341718e-02f, + -1.961406682823892828e-02f, + -1.925518966646928148e-02f, + -1.887751643015150166e-02f, + -1.848145713662151246e-02f, + -1.806743960696060095e-02f, + -1.763590900811298073e-02f, + -1.718732737835180352e-02f, + -1.672217313659431215e-02f, + -1.624094057608432493e-02f, + -1.574413934297350451e-02f, + -1.523229390034704089e-02f, + -1.470594297825480838e-02f, + -1.416563901031964515e-02f, + -1.361194755751050575e-02f, + -1.304544671967466062e-02f, + -1.246672653544142993e-02f, + -1.187638837111369521e-02f, + -1.127504429917872836e-02f, + -1.066331646707572613e-02f, + -1.004183645686986676e-02f, + -9.411244636485087758e-03f, + -8.772189503162801036e-03f, + -8.125327019812878665e-03f, + -7.471319944934195698e-03f, + -6.810837156787309839e-03f, + -6.144552972502608131e-03f, + -5.473146462815121210e-03f, + -4.797300763120759294e-03f, + -4.117702381546011793e-03f, + -3.435040504733359156e-03f, + -2.750006302037344939e-03f, + -2.063292228833295185e-03f, + -1.375591329636196821e-03f, + -6.875965417295367256e-04f, + -3.712671580871972529e-17f, + 6.865076563281155998e-04f, + 1.371237974366756743e-03f, + 2.053505374957837522e-03f, + 2.732627836105371629e-03f, + 3.407927571765508035e-03f, + 4.078731705322887272e-03f, + 4.744372937087731369e-03f, + 5.404190205152949872e-03f, + 6.057529338961288590e-03f, + 6.703743704936756392e-03f, + 7.342194843549852169e-03f, + 7.972253097187404283e-03f, + 8.593298228216065052e-03f, + 9.204720026634211766e-03f, + 9.805918906718476616e-03f, + 1.039630649208695898e-02f, + 1.097530618860973091e-02f, + 1.154235374461037682e-02f, + 1.209689779782041619e-02f, + 1.263840040855540407e-02f, + 1.316633757860326444e-02f, + 1.368019975532520915e-02f, + 1.417949232048846230e-02f, + 1.466373606336292788e-02f, + 1.513246763763515662e-02f, + 1.558524000170355243e-02f, + 1.602162284194235189e-02f, + 1.644120297853483154e-02f, + 1.684358475349722120e-02f, + 1.722839040053121898e-02f, + 1.759526039636302719e-02f, + 1.794385379324603749e-02f, + 1.827384853232209144e-02f, + 1.858494173755794940e-02f, + 1.887684998999094102e-02f, + 1.914930958204142525e-02f, + 1.940207675166573387e-02f, + 1.963492789614775663e-02f, + 1.984765976534554055e-02f, + 2.004008963423044992e-02f, + 2.021205545457873884e-02f, + 2.036341598569508388e-02f, + 2.049405090406888896e-02f, + 2.060386089188653500e-02f, + 2.069276770434292853e-02f, + 2.076071421571710346e-02f, + 2.080766444419874725e-02f, + 2.083360355547297926e-02f, + 2.083853784509219140e-02f, + 2.082249469968529276e-02f, + 2.078552253707531203e-02f, + 2.072769072539770024e-02f, + 2.064908948133232364e-02f, + 2.054982974758300454e-02f, + 2.043004304975895233e-02f, + 2.028988133283307627e-02f, + 2.012951677737172956e-02f, + 1.994914159575129214e-02f, + 1.974896780859568615e-02f, + 1.952922700168944689e-02f, + 1.929017006363938427e-02f, + 1.903206690457660832e-02f, + 1.875520615621007955e-02f, + 1.845989485356032758e-02f, + 1.814645809871968940e-02f, + 1.781523870700396292e-02f, + 1.746659683587628575e-02f, + 1.710090959704086561e-02f, + 1.671857065212146304e-02f, + 1.631998979235366534e-02f, + 1.590559250273780936e-02f, + 1.547581951111101986e-02f, + 1.503112632261381296e-02f, + 1.457198274004087128e-02f, + 1.409887237057541251e-02f, + 1.361229211942506165e-02f, + 1.311275167088374154e-02f, + 1.260077295736035038e-02f, + 1.207688961692321428e-02f, + 1.154164643992243444e-02f, + 1.099559880526047861e-02f, + 1.043931210689104556e-02f, + 9.873361171136581238e-03f, + 9.298329665421793330e-03f, + 8.714809499028142170e-03f, + 8.123400216482846645e-03f, + 7.524708384200954649e-03f, + 6.919346971004516206e-03f, + 6.307934723150263913e-03f, + 5.691095534499056308e-03f, + 5.069457812466930842e-03f, + 4.443653840398907248e-03f, + 3.814319137009273761e-03f, + 3.182091813536080255e-03f, + 2.547611929256090018e-03f, + 1.911520846010968415e-03f, + 1.274460582389453983e-03f, + 6.370731682176064472e-04f, + 1.081397080984820549e-16f, + -6.361188020413131080e-04f, + -1.270645034688974500e-03f, + -1.902943049573664223e-03f, + -2.532380387505061333e-03f, + -3.158328408659244208e-03f, + -3.780162917995376869e-03f, + -4.397264785285395425e-03f, + -5.009020559139008844e-03f, + -5.614823074421015914e-03f, + -6.214072052459541223e-03f, + -6.806174693455702487e-03f, + -7.390546260511059347e-03f, + -7.966610654700514993e-03f, + -8.533800980628097194e-03f, + -9.091560101911401459e-03f, + -9.639341186054086255e-03f, + -1.017660823817454450e-02f, + -1.070283662307290606e-02f, + -1.121751357513068974e-02f, + -1.172013869554890987e-02f, + -1.221022443644520679e-02f, + -1.268729657134461120e-02f, + -1.315089465161116758e-02f, + -1.360057244838422906e-02f, + -1.403589837959812528e-02f, + -1.445645592167801516e-02f, + -1.486184400552278267e-02f, + -1.525167739639943926e-02f, + -1.562558705739423154e-02f, + -1.598322049607744932e-02f, + -1.632424209406116086e-02f, + -1.664833341914373141e-02f, + -1.695519351975287997e-02f, + -1.724453920141957169e-02f, + -1.751610528503054487e-02f, + -1.776964484662796329e-02f, + -1.800492943854209438e-02f, + -1.822174929166297391e-02f, + -1.841991349867593691e-02f, + -1.859925017810457049e-02f, + -1.875960661902498217e-02f, + -1.890084940633438015e-02f, + -1.902286452647648438e-02f, + -1.912555745354639625e-02f, + -1.920885321571724064e-02f, + -1.927269644195031550e-02f, + -1.931705138897083646e-02f, + -1.934190194851057379e-02f, + -1.934725163483910423e-02f, + -1.933312355262460300e-02f, + -1.929956034518492611e-02f, + -1.924662412320928689e-02f, + -1.917439637405042932e-02f, + -1.908297785170610245e-02f, + -1.897248844762847511e-02f, + -1.884306704251837231e-02f, + -1.869487133928060194e-02f, + -1.852807767733529593e-02f, + -1.834288082849799481e-02f, + -1.813949377465985668e-02f, + -1.791814746751756518e-02f, + -1.767909057061923042e-02f, + -1.742258918401042023e-02f, + -1.714892655178226061e-02f, + -1.685840275283847015e-02f, + -1.655133437521590783e-02f, + -1.622805417430966263e-02f, + -1.588891071536682048e-02f, + -1.553426800063207637e-02f, + -1.516450508153929268e-02f, + -1.478001565636058098e-02f, + -1.438120765373634632e-02f, + -1.396850280252506793e-02f, + -1.354233618842332412e-02f, + -1.310315579781915797e-02f, + -1.265142204935544926e-02f, + -1.218760731368947504e-02f, + -1.171219542194896698e-02f, + -1.122568116339099642e-02f, + -1.072856977278602644e-02f, + -1.022137640805312678e-02f, + -9.704625618685933791e-03f, + -9.178850805514197561e-03f, + -8.644593672357078762e-03f, + -8.102403670126549079e-03f, + -7.552837433952721592e-03f, + -6.996458213902527305e-03f, + -6.433835299872929167e-03f, + -5.865543441244903435e-03f, + -5.292162261885334160e-03f, + -4.714275671091273240e-03f, + -4.132471271074346537e-03f, + -3.547339761581234756e-03f, + -2.959474342255256820e-03f, + -2.369470113338262643e-03f, + -1.777923475318417051e-03f, + -1.185431528126037071e-03f, + -5.925914704819672469e-04f, + -3.657082924657467151e-17f, + 5.917472853565048079e-04f, + 1.182056483865000056e-03f, + 1.770335984084810870e-03f, + 2.355997055758636289e-03f, + 2.938454436983550105e-03f, + 3.517126917070770645e-03f, + 4.091437914513436185e-03f, + 4.660816049491952121e-03f, + 5.224695710346304901e-03f, + 5.782517613461616614e-03f, + 6.333729356008878375e-03f, + 6.877785961000690458e-03f, + 7.414150414123792977e-03f, + 7.942294191823096386e-03f, + 8.461697780117830373e-03f, + 8.971851183644980604e-03f, + 9.472254424431190978e-03f, + 9.962418029908697709e-03f, + 1.044186350969892804e-02f, + 1.091012382070481734e-02f, + 1.136674382005683007e-02f, + 1.181128070548041059e-02f, + 1.224330444265740725e-02f, + 1.266239817917228644e-02f, + 1.306815864464697975e-02f, + 1.346019653668105442e-02f, + 1.383813689223166964e-02f, + 1.420161944407984794e-02f, + 1.455029896204724192e-02f, + 1.488384557864121625e-02f, + 1.520194509882482302e-02f, + 1.550429929362267742e-02f, + 1.579062617728919579e-02f, + 1.606066026778677283e-02f, + 1.631415283033408117e-02f, + 1.655087210380375498e-02f, + 1.677060350976731021e-02f, + 1.697314984400075458e-02f, + 1.715833145028389933e-02f, + 1.732598637634284386e-02f, + 1.747597051180499114e-02f, + 1.760815770805244929e-02f, + 1.772243987987905459e-02f, + 1.781872708887428242e-02f, + 1.789694760847562044e-02f, + 1.795704797064969285e-02f, + 1.799899299418070836e-02f, + 1.802276579456344244e-02f, + 1.802836777551610967e-02f, + 1.801581860214731406e-02f, + 1.798515615582916075e-02f, + 1.793643647084725012e-02f, + 1.786973365291627536e-02f, + 1.778513977966790505e-02f, + 1.768276478323590681e-02f, + 1.756273631508084576e-02f, + 1.742519959321422313e-02f, + 1.727031723200050592e-02f, + 1.709826905473061168e-02f, + 1.690925188917933447e-02f, + 1.670347934637539389e-02f, + 1.648118158282851561e-02f, + 1.624260504647542444e-02f, + 1.598801220662182665e-02f, + 1.571768126817298800e-02f, + 1.543190587046214431e-02f, + 1.513099477099881518e-02f, + 1.481527151447596842e-02f, + 1.448507408738769486e-02f, + 1.414075455862428936e-02f, + 1.378267870642391028e-02f, + 1.341122563207439514e-02f, + 1.302678736077021032e-02f, + 1.262976843004335811e-02f, + 1.222058546619729687e-02f, + 1.179966674918666268e-02f, + 1.136745176639336087e-02f, + 1.092439075576322714e-02f, + 1.047094423877575897e-02f, + 1.000758254372885632e-02f, + 9.534785319831791742e-03f, + 9.053041042603243369e-03f, + 8.562846511087114296e-03f, + 8.064706337396969349e-03f, + 7.559132429115091208e-03f, + 7.046643465073196971e-03f, + 6.527764365051815301e-03f, + 6.003025753936333010e-03f, + 5.472963420876755282e-03f, + 4.938117773999208156e-03f, + 4.399033291224269636e-03f, + 3.856257967746062627e-03f, + 3.310342760733056815e-03f, + 2.761841031809351716e-03f, + 2.211307987882755663e-03f, + 1.659300120877342261e-03f, + 1.106374646939666147e-03f, + 5.530889456780919066e-04f, + -2.562212629853384453e-17f, + -5.523361628926795478e-04f, + -1.103365028790336249e-03f, + -1.652534151487132074e-03f, + -2.199293704964780296e-03f, + -2.743097032196961139e-03f, + -3.283401190029548548e-03f, + -3.819667489593037233e-03f, + -4.351362031714790628e-03f, + -4.877956236795205104e-03f, + -5.398927368629055645e-03f, + -5.913759051650750720e-03f, + -6.421941781095417100e-03f, + -6.922973425571511859e-03f, + -7.416359721553146198e-03f, + -7.901614759304937882e-03f, + -8.378261459764673943e-03f, + -8.845832041915659832e-03f, + -9.303868480194682489e-03f, + -9.751922951488184790e-03f, + -1.018955827128389773e-02f, + -1.061634831855159944e-02f, + -1.103187844894640973e-02f, + -1.143574589593108516e-02f, + -1.182756015943418025e-02f, + -1.220694338166910739e-02f, + -1.257353070975459307e-02f, + -1.292697064479079137e-02f, + -1.326692537705756285e-02f, + -1.359307110701880525e-02f, + -1.390509835182837141e-02f, + -1.420271223705014962e-02f, + -1.448563277331862270e-02f, + -1.475359511768305730e-02f, + -1.500634981939290638e-02f, + -1.524366304989917265e-02f, + -1.546531681686134224e-02f, + -1.567110916196697012e-02f, + -1.586085434238630049e-02f, + -1.603438299570249595e-02f, + -1.619154228817324542e-02f, + -1.633219604619749049e-02f, + -1.645622487087768787e-02f, + -1.656352623558475859e-02f, + -1.665401456645098158e-02f, + -1.672762130573241662e-02f, + -1.678429495799975413e-02f, + -1.682400111913467597e-02f, + -1.684672248812496553e-02f, + -1.685245886166945525e-02f, + -1.684122711162113276e-02f, + -1.681306114531371312e-02f, + -1.676801184883415854e-02f, + -1.670614701332074833e-02f, + -1.662755124438308404e-02f, + -1.653232585475732791e-02f, + -1.642058874032645624e-02f, + -1.629247423965218475e-02f, + -1.614813297718115451e-02f, + -1.598773169030448180e-02f, + -1.581145304046532168e-02f, + -1.561949540852535824e-02f, + -1.541207267461631135e-02f, + -1.518941398271757108e-02f, + -1.495176349021716013e-02f, + -1.469938010272622657e-02f, + -1.443253719443338481e-02f, + -1.415152231429803349e-02f, + -1.385663687839711923e-02f, + -1.354819584875125403e-02f, + -1.322652739897053030e-02f, + -1.289197256707447573e-02f, + -1.254488489584905733e-02f, + -1.218563006111956712e-02f, + -1.181458548832869243e-02f, + -1.143213995781868463e-02f, + -1.103869319922974775e-02f, + -1.063465547543513724e-02f, + -1.022044715644565907e-02f, + -9.796498283722697084e-03f, + -9.363248125350869672e-03f, + -8.921144722528617441e-03f, + -8.470644427841999072e-03f, + -8.012211435799141551e-03f, + -7.546317306102053729e-03f, + -7.073440480148323294e-03f, + -6.594065791253660332e-03f, + -6.108683969096916598e-03f, + -5.617791138891340720e-03f, + -5.121888315793346122e-03f, + -4.621480895060380706e-03f, + -4.117078138476948368e-03f, + -3.609192657567809014e-03f, + -3.098339894123382839e-03f, + -2.585037598558611194e-03f, + -2.069805306636893476e-03f, + -1.553163815081216479e-03f, + -1.035634656603983328e-03f, + -5.177395748811913952e-04f, + -3.594753584560424697e-17f, + 5.170634750964393008e-04f, + 1.032931616641648070e-03f, + 1.547087070033249757e-03f, + 2.059014877257667187e-03f, + 2.568202991233530484e-03f, + 3.074142786564025911e-03f, + 3.576329566188138527e-03f, + 4.074263063429547048e-03f, + 4.567447938941549164e-03f, + 5.055394272060948803e-03f, + 5.537618046079833753e-03f, + 6.013641626959552108e-03f, + 6.482994235012814500e-03f, + 6.945212409090805589e-03f, + 7.399840462817311795e-03f, + 7.846430932424257321e-03f, + 8.284545015748243785e-03f, + 8.713753001960018382e-03f, + 9.133634691605685765e-03f, + 9.543779806553546671e-03f, + 9.943788389443802139e-03f, + 1.033327119225793331e-02f, + 1.071185005362884461e-02f, + 1.107915826452845684e-02f, + 1.143484092198099322e-02f, + 1.177855527046098826e-02f, + 1.210997103065078462e-02f, + 1.242877071524243864e-02f, + 1.273464993148456723e-02f, + 1.302731767018629021e-02f, + 1.330649658090683578e-02f, + 1.357192323307192076e-02f, + 1.382334836277147004e-02f, + 1.406053710501154602e-02f, + 1.428326921120452730e-02f, + 1.449133925169799296e-02f, + 1.468455680315914995e-02f, + 1.486274662064523792e-02f, + 1.502574879420732167e-02f, + 1.517341888988939583e-02f, + 1.530562807500203924e-02f, + 1.542226322756440338e-02f, + 1.552322702982500066e-02f, + 1.560843804578798157e-02f, + 1.567783078268716879e-02f, + 1.573135573636695247e-02f, + 1.576897942054480972e-02f, + 1.579068437994683369e-02f, + 1.579646918732351482e-02f, + 1.578634842436942021e-02f, + 1.576035264658639731e-02f, + 1.571852833214611861e-02f, + 1.566093781482364236e-02f, + 1.558765920108961048e-02f, + 1.549878627146459784e-02f, + 1.539442836625458041e-02f, + 1.527471025580193729e-02f, + 1.513977199540266459e-02f, + 1.498976876505400853e-02f, + 1.482487069421324286e-02f, + 1.464526267176276438e-02f, + 1.445114414139052512e-02f, + 1.424272888261022586e-02f, + 1.402024477765924718e-02f, + 1.378393356452596412e-02f, + 1.353405057637283200e-02f, + 1.327086446763305755e-02f, + 1.299465692707358656e-02f, + 1.270572237812851030e-02f, + 1.240436766682034841e-02f, + 1.209091173759783630e-02f, + 1.176568529743146629e-02f, + 1.142903046851825692e-02f, + 1.108130042995956500e-02f, + 1.072285904878491486e-02f, + 1.035408050070699311e-02f, + 9.975348881000042217e-03f, + 9.587057805905971689e-03f, + 9.189610004980062336e-03f, + 8.783416904796481281e-03f, + 8.368898204444107092e-03f, + 7.946481443246316417e-03f, + 7.516601561152745289e-03f, + 7.079700452249429281e-03f, + 6.636226511847269707e-03f, + 6.186634177609999508e-03f, + 5.731383465191587125e-03f, + 5.270939498854294337e-03f, + 4.805772037546594995e-03f, + 4.336354996921345552e-03f, + 3.863165967780911834e-03f, + 3.386685731435247395e-03f, + 2.907397772465186801e-03f, + 2.425787789381585267e-03f, + 1.942343203677738541e-03f, + 1.457552667765169528e-03f, + 9.719055722931030025e-04f, + 4.858915533437137995e-04f, + 8.998451329969168033e-17f, + -4.852804372203572384e-04f, + -9.694623365727714258e-04f, + -1.452059993443630213e-03f, + -1.932589906371710072e-03f, + -2.410571260246647390e-03f, + -2.885526406203937043e-03f, + -3.356981337736776681e-03f, + -3.824466162554774652e-03f, + -4.287515569716226875e-03f, + -4.745669291575628328e-03f, + -5.198472560085647988e-03f, + -5.645476557004205746e-03f, + -6.086238857560498199e-03f, + -6.520323867144547751e-03f, + -6.947303250588880534e-03f, + -7.366756353621596760e-03f, + -7.778270616075868595e-03f, + -8.181441976453041054e-03f, + -8.575875267442242128e-03f, + -8.961184602012178466e-03f, + -9.336993749696280778e-03f, + -9.702936502709572433e-03f, + -1.005865703153830532e-02f, + -1.040381022966105004e-02f, + -1.073806204706719697e-02f, + -1.106108981225218876e-02f, + -1.137258254238081648e-02f, + -1.167224124132068379e-02f, + -1.195977918526302392e-02f, + -1.223492219565827481e-02f, + -1.249740889920878534e-02f, + -1.274699097467286470e-02f, + -1.298343338624937185e-02f, + -1.320651460332445369e-02f, + -1.341602680637729757e-02f, + -1.361177607885452785e-02f, + -1.379358258483857035e-02f, + -1.396128073234834122e-02f, + -1.411471932212687332e-02f, + -1.425376168178382232e-02f, + -1.437828578517633127e-02f, + -1.448818435692682781e-02f, + -1.458336496199062575e-02f, + -1.466375008020243120e-02f, + -1.472927716574510063e-02f, + -1.477989869149929497e-02f, + -1.481558217824864229e-02f, + -1.483631020872940888e-02f, + -1.484208042652921528e-02f, + -1.483290551985472217e-02f, + -1.480881319020316278e-02f, + -1.476984610598764888e-02f, + -1.471606184118155226e-02f, + -1.464753279906179893e-02f, + -1.456434612114611976e-02f, + -1.446660358143379496e-02f, + -1.435442146607433973e-02f, + -1.422793043860267476e-02f, + -1.408727539089408773e-02f, + -1.393261528000593226e-02f, + -1.376412295108748671e-02f, + -1.358198494655285873e-02f, + -1.338640130172517699e-02f, + -1.317758532717458811e-02f, + -1.295576337798411137e-02f, + -1.272117461019173744e-02f, + -1.247407072466863269e-02f, + -1.221471569870679480e-02f, + -1.194338550559997762e-02f, + -1.166036782251413627e-02f, + -1.136596172695676817e-02f, + -1.106047738216157407e-02f, + -1.074423571171940345e-02f, + -1.041756806379570341e-02f, + -1.008081586528326509e-02f, + -9.734330266250949479e-03f, + -9.378471775056540852e-03f, + -9.013609884502808353e-03f, + -8.640122689421677812e-03f, + -8.258396496082181723e-03f, + -7.868825423824252902e-03f, + -7.471810999326916093e-03f, + -7.067761743930141109e-03f, + -6.657092754429278468e-03f, + -6.240225277775035030e-03f, + -5.817586280110769240e-03f, + -5.389608010588473400e-03f, + -4.956727560406810548e-03f, + -4.519386417521461217e-03f, + -4.078030017478383173e-03f, + -3.633107290827413370e-03f, + -3.185070207573783597e-03f, + -2.734373319130519765e-03f, + -2.281473298231648152e-03f, + -1.826828477275332062e-03f, + -1.370898385557953137e-03f, + -9.141432858685172996e-04f, + -4.570237109078288933e-04f, + -3.525929546010641032e-17f, + 4.564681634404971059e-04f, + 9.119222132217494076e-04f, + 1.365905160004667876e-03f, + 1.817962048792683442e-03f, + 2.267640413821652746e-03f, + 2.714490730398470830e-03f, + 3.158066863236440400e-03f, + 3.597926510843086571e-03f, + 4.033631645515631595e-03f, + 4.464748948511986122e-03f, + 4.890850239961540627e-03f, + 5.311512903093372658e-03f, + 5.726320302360849920e-03f, + 6.134862195051104215e-03f, + 6.536735135972274353e-03f, + 6.931542874822234357e-03f, + 7.318896745846920765e-03f, + 7.698416049407258259e-03f, + 8.069728425079554859e-03f, + 8.432470215927469551e-03f, + 8.786286823586514014e-03f, + 9.130833053819266409e-03f, + 9.465773452203021798e-03f, + 9.790782629625502387e-03f, + 1.010554557727417341e-02f, + 1.040975797081422800e-02f, + 1.070312646346415798e-02f, + 1.098536896768670043e-02f, + 1.125621492522658335e-02f, + 1.151540556523688447e-02f, + 1.176269415025001618e-02f, + 1.199784620976064760e-02f, + 1.222063976119941615e-02f, + 1.243086551809268608e-02f, + 1.262832708521319930e-02f, + 1.281284114054117608e-02f, + 1.298423760386959412e-02f, + 1.314235979189961462e-02f, + 1.328706455968696638e-02f, + 1.341822242831278503e-02f, + 1.353571769866840878e-02f, + 1.363944855125505048e-02f, + 1.372932713191544682e-02f, + 1.380527962342858322e-02f, + 1.386724630291150812e-02f, + 1.391518158498825965e-02f, + 1.394905405069915734e-02f, + 1.396884646213872837e-02f, + 1.397455576282423569e-02f, + 1.396619306381172501e-02f, + 1.394378361559041324e-02f, + 1.390736676580064946e-02f, + 1.385699590283483162e-02f, + 1.379273838539456926e-02f, + 1.371467545809203735e-02f, + 1.362290215319624312e-02f, + 1.351752717864009370e-02f, + 1.339867279241668298e-02f, + 1.326647466350721130e-02f, + 1.312108171949675703e-02f, + 1.296265598104565965e-02f, + 1.279137238340016282e-02f, + 1.260741858513507452e-02f, + 1.241099476433735194e-02f, + 1.220231340244982976e-02f, + 1.198159905600587605e-02f, + 1.174908811650030374e-02f, + 1.150502855865119002e-02f, + 1.124967967731822956e-02f, + 1.098331181335730246e-02f, + 1.070620606869824784e-02f, + 1.041865401094608894e-02f, + 1.012095736781302990e-02f, + 9.813427711702541953e-03f, + 9.496386134773091015e-03f, + 9.170162914817906255e-03f, + 8.835097172309763769e-03f, + 8.491536518964717603e-03f, + 8.139836698186228570e-03f, + 7.780361217764370299e-03f, + 7.413480975203700848e-03f, + 7.039573876068914819e-03f, + 6.659024445737531453e-03f, + 6.272223434958205251e-03f, + 5.879567419619150664e-03f, + 5.481458395132861143e-03f, + 5.078303365855517913e-03f, + 4.670513929954199853e-03f, + 4.258505860148748337e-03f, + 3.842698680752674144e-03f, + 3.423515241440691897e-03f, + 3.001381288178317595e-03f, + 2.576725031746534850e-03f, + 2.149976714294795244e-03f, + 1.721568174367767547e-03f, + 1.291932410834989269e-03f, + 8.615031461717679489e-04f, + 4.307143895238358311e-04f, + -1.330885637378024658e-17f, + -4.302067493707025154e-04f, + -8.594736065816692546e-04f, + -1.287369774051150230e-03f, + -1.713466340056074740e-03f, + -2.137336707761578608e-03f, + -2.558557021419832853e-03f, + -2.976706589314977430e-03f, + -3.391368303029395053e-03f, + -3.802129052617245642e-03f, + -4.208580137271933364e-03f, + -4.610317671079266870e-03f, + -5.006942983457264747e-03f, + -5.398063013881818258e-03f, + -5.783290700513624497e-03f, + -6.162245362338608992e-03f, + -6.534553074447273235e-03f, + -6.899847036085403514e-03f, + -7.257767931111701668e-03f, + -7.607964280510494219e-03f, + -7.950092786617034279e-03f, + -8.283818668712937539e-03f, + -8.608815989672613522e-03f, + -8.924767973335575449e-03f, + -9.231367312302321895e-03f, + -9.528316465851647404e-03f, + -9.815327947693202118e-03f, + -1.009212460327926254e-02f, + -1.035843987640591192e-02f, + -1.061401806485215774e-02f, + -1.085861456480968767e-02f, + -1.109199610387191955e-02f, + -1.131394096236322706e-02f, + -1.152423918279525498e-02f, + -1.172269276725893851e-02f, + -1.190911586256368677e-02f, + -1.208333493295382470e-02f, + -1.224518892024368394e-02f, + -1.239452939122312469e-02f, + -1.253122067220243524e-02f, + -1.265513997057455924e-02f, + -1.276617748328832784e-02f, + -1.286423649213934428e-02f, + -1.294923344579684485e-02f, + -1.302109802850088746e-02f, + -1.307977321537517543e-02f, + -1.312521531431613646e-02f, + -1.315739399443144331e-02f, + -1.317629230101505927e-02f, + -1.318190665705944176e-02f, + -1.317424685131877472e-02f, + -1.315333601295100296e-02f, + -1.311921057277957818e-02f, + -1.307192021122943054e-02f, + -1.301152779300470720e-02f, + -1.293810928858945414e-02f, + -1.285175368266549059e-02f, + -1.275256286955382679e-02f, + -1.264065153580123772e-02f, + -1.251614703004294733e-02f, + -1.237918922028838700e-02f, + -1.222993033878752925e-02f, + -1.206853481464722870e-02f, + -1.189517909438159854e-02f, + -1.171005145058865056e-02f, + -1.151335177896088170e-02f, + -1.130529138384659196e-02f, + -1.108609275258971849e-02f, + -1.085598931889009827e-02f, + -1.061522521543183453e-02f, + -1.036405501604320198e-02f, + -1.010274346765773629e-02f, + -9.831565212357994479e-03f, + -9.550804499793438818e-03f, + -9.260754890270634504e-03f, + -8.961718948827171807e-03f, + -8.654007930606116492e-03f, + -8.337941457855730515e-03f, + -8.013847188892069678e-03f, + -7.682060479362260927e-03f, + -7.342924036161159809e-03f, + -6.996787564356483392e-03f, + -6.644007407482657376e-03f, + -6.284946181578719530e-03f, + -5.919972403337297497e-03f, + -5.549460112752437578e-03f, + -5.173788490645978184e-03f, + -4.793341471466837367e-03f, + -4.408507351756223852e-03f, + -4.019678394675591307e-03f, + -3.627250431002364273e-03f, + -3.231622456996959773e-03f, + -2.833196229547020346e-03f, + -2.432375859003425757e-03f, + -2.029567400113351655e-03f, + -1.625178441472032017e-03f, + -1.219617693898372018e-03f, + -8.132945781564861155e-04f, + -4.066188124353766527e-04f, + -1.255183464083940188e-16f, + 4.061527825679167288e-04f, + 8.114313961304521613e-04f, + 1.215429048341218040e-03f, + 1.617740701170319395e-03f, + 2.017963476201877198e-03f, + 2.415697057295686061e-03f, + 2.810544090212879591e-03f, + 3.202110578810242990e-03f, + 3.590006277401872493e-03f, + 3.973845078907196904e-03f, + 4.353245398391843331e-03f, + 4.727830551627599208e-03f, + 5.097229128292139061e-03f, + 5.461075359441391712e-03f, + 5.819009478893136939e-03f, + 6.170678078162634105e-03f, + 6.515734454602445554e-03f, + 6.853838952405788033e-03f, + 7.184659296134813210e-03f, + 7.507870916452765928e-03f, + 7.823157267734456854e-03f, + 8.130210137252638636e-03f, + 8.428729945633239504e-03f, + 8.718426038289772001e-03f, + 8.999016967555456201e-03f, + 9.270230765236708165e-03f, + 9.531805205328850242e-03f, + 9.783488056638036182e-03f, + 1.002503732506817256e-02f, + 1.025622148534208536e-02f, + 1.047681970193385138e-02f, + 1.068662203900417294e-02f, + 1.088542965913968583e-02f, + 1.107305501070874297e-02f, + 1.124932200365959603e-02f, + 1.141406617359526365e-02f, + 1.156713483397583953e-02f, + 1.170838721630671625e-02f, + 1.183769459818636779e-02f, + 1.195494041909911376e-02f, + 1.206002038384902317e-02f, + 1.215284255354657367e-02f, + 1.223332742406933564e-02f, + 1.230140799193264051e-02f, + 1.235702980751857485e-02f, + 1.240015101562292471e-02f, + 1.243074238329506739e-02f, + 1.244878731495606579e-02f, + 1.245428185479465800e-02f, + 1.244723467645303394e-02f, + 1.242766706002694684e-02f, + 1.239561285641773217e-02f, + 1.235111843908625294e-02f, + 1.229424264327155618e-02f, + 1.222505669274922754e-02f, + 1.214364411421739454e-02f, + 1.205010063941019949e-02f, + 1.194453409505086793e-02f, + 1.182706428076905555e-02f, + 1.169782283511792108e-02f, + 1.155695308984023249e-02f, + 1.140460991254168763e-02f, + 1.124095953794393248e-02f, + 1.106617938789930186e-02f, + 1.088045788035994950e-02f, + 1.068399422750770586e-02f, + 1.047699822325738259e-02f, + 1.025969002036108101e-02f, + 1.003229989734856151e-02f, + 9.795068015547647028e-03f, + 9.548244166444083345e-03f, + 9.292087509640511306e-03f, + 9.026866301692599431e-03f, + 8.752857616103554630e-03f, + 8.470347054767179973e-03f, + 8.179628451162134981e-03f, + 7.881003565601285565e-03f, + 7.574781772854489656e-03f, + 7.261279742466121394e-03f, + 6.940821112095421283e-03f, + 6.613736154219424825e-03f, + 6.280361436535699012e-03f, + 5.941039476420039225e-03f, + 5.596118389785657496e-03f, + 5.245951534708952028e-03f, + 4.890897150183600751e-03f, + 4.531317990370226784e-03f, + 4.167580954717115850e-03f, + 3.800056714327025055e-03f, + 3.429119334948160357e-03f, + 3.055145896976142229e-03f, + 2.678516112847336220e-03f, + 2.299611942215314033e-03f, + 1.918817205297107184e-03f, + 1.536517194780740196e-03f, + 1.153098286686640977e-03f, + 7.689475505726472288e-04f, + 3.844523594784173275e-04f, + 7.713589460388476895e-17f, + -3.840227171148354263e-04f, + -7.672298454569775623e-04f, + -1.149236690145042554e-03f, + -1.529660193323781423e-03f, + -1.908119317586332020e-03f, + -2.284235426939436406e-03f, + -2.657632664926935610e-03f, + -3.027938329540865066e-03f, + -3.394783244538977351e-03f, + -3.757802126807970565e-03f, + -4.116633949400874508e-03f, + -4.470922299891161820e-03f, + -4.820315733689854894e-03f, + -5.164468121973136636e-03f, + -5.503038993878216732e-03f, + -5.835693872631364174e-03f, + -6.162104605273097113e-03f, + -6.481949685660806648e-03f, + -6.794914570427616589e-03f, + -7.100691987590134792e-03f, + -7.398982237502254970e-03f, + -7.689493485860325432e-03f, + -7.971942048476048787e-03f, + -8.246052667536663341e-03f, + -8.511558779087890353e-03f, + -8.768202771477389898e-03f, + -9.015736234510263528e-03f, + -9.253920199077345435e-03f, + -9.482525367023937612e-03f, + -9.701332331039827506e-03f, + -9.910131784361380508e-03f, + -1.010872472008433366e-02f, + -1.029692261989997165e-02f, + -1.047454763207558877e-02f, + -1.064143273851355688e-02f, + -1.079742191073151426e-02f, + -1.094237025462001418e-02f, + -1.107614414384500319e-02f, + -1.119862134177232113e-02f, + -1.130969111180511570e-02f, + -1.140925431603640253e-02f, + -1.149722350212928346e-02f, + -1.157352297835191959e-02f, + -1.163808887670370745e-02f, + -1.169086920408306425e-02f, + -1.173182388145829064e-02f, + -1.176092477101533564e-02f, + -1.177815569126870569e-02f, + -1.178351242013314648e-02f, + -1.177700268596670700e-02f, + -1.175864614660714416e-02f, + -1.172847435643616099e-02f, + -1.168653072151761875e-02f, + -1.163287044286803393e-02f, + -1.156756044792955386e-02f, + -1.149067931032693446e-02f, + -1.140231715800252288e-02f, + -1.130257556983401725e-02f, + -1.119156746085197413e-02f, + -1.106941695618434904e-02f, + -1.093625925386791653e-02f, + -1.079224047667651058e-02f, + -1.063751751312634955e-02f, + -1.047225784783175143e-02f, + -1.029663938139156396e-02f, + -1.011085024000046503e-02f, + -9.915088574987292874e-03f, + -9.709562352492116799e-03f, + -9.494489133505876546e-03f, + -9.270095844503068935e-03f, + -9.036618538908790590e-03f, + -8.794302149650478143e-03f, + -8.543400233051267126e-03f, + -8.284174704334627132e-03f, + -8.016895565012135613e-03f, + -7.741840622440153072e-03f, + -7.459295201834709003e-03f, + -7.169551851041272746e-03f, + -6.872910038367072844e-03f, + -6.569675843783693604e-03f, + -6.260161643820879619e-03f, + -5.944685790473217164e-03f, + -5.623572284449645554e-03f, + -5.297150443101252340e-03f, + -4.965754563364804634e-03f, + -4.629723580069068818e-03f, + -4.289400719951269245e-03f, + -3.945133151734599684e-03f, + -3.597271632626723118e-03f, + -3.246170151593960954e-03f, + -2.892185569777141942e-03f, + -2.535677258412258675e-03f, + -2.177006734621175950e-03f, + -1.816537295443911102e-03f, + -1.454633650479946480e-03f, + -1.091661553510198676e-03f, + -7.279874334719225624e-04f, + -3.639780251556599890e-04f, + -3.369908401361916715e-17f, + 3.635804026494091068e-04f, + 7.263977434430309238e-04f, + 1.088087749724279355e-03f, + 1.448287680655482423e-03f, + 1.806636690402828576e-03f, + 2.162776189022377980e-03f, + 2.516350200682577424e-03f, + 2.867005718868611067e-03f, + 3.214393058213963015e-03f, + 3.558166202608354332e-03f, + 3.897983149238446517e-03f, + 4.233506248216929377e-03f, + 4.564402537464701606e-03f, + 4.890344072516150664e-03f, + 5.211008250917694221e-03f, + 5.526078130903779376e-03f, + 5.835242744032488431e-03f, + 6.138197401474478412e-03f, + 6.434643993655418670e-03f, + 6.724291282955277560e-03f, + 7.006855189179749324e-03f, + 7.282059067523997259e-03f, + 7.549633978756757104e-03f, + 7.809318951363577316e-03f, + 8.060861235391183002e-03f, + 8.304016547750365032e-03f, + 8.538549308736993748e-03f, + 8.764232869544244173e-03f, + 8.980849730547869544e-03f, + 9.188191750152601561e-03f, + 9.386060344002900707e-03f, + 9.574266674365642868e-03f, + 9.752631829506541034e-03f, + 9.920986992890266226e-03f, + 1.007917360204479626e-02f, + 1.022704349694264145e-02f, + 1.036445905775955530e-02f, + 1.049129333188454291e-02f, + 1.060743015006561894e-02f, + 1.071276423158474926e-02f, + 1.080720127836987295e-02f, + 1.089065805795989307e-02f, + 1.096306247525190812e-02f, + 1.102435363297093844e-02f, + 1.107448188081278095e-02f, + 1.111340885322339295e-02f, + 1.114110749578882571e-02f, + 1.115756208022166719e-02f, + 1.116276820794095091e-02f, + 1.115673280225443556e-02f, + 1.113947408916339532e-02f, + 1.111102156682138194e-02f, + 1.107141596369005596e-02f, + 1.102070918544608043e-02f, + 1.095896425070500523e-02f, + 1.088625521563825124e-02f, + 1.080266708757151098e-02f, + 1.070829572766292780e-02f, + 1.060324774277076644e-02f, + 1.048764036663119362e-02f, + 1.036160133047638564e-02f, + 1.022526872323565802e-02f, + 1.007879084146987361e-02f, + 9.922326029202397854e-03f, + 9.756042507818011092e-03f, + 9.580118196210777107e-03f, + 9.394740521373458678e-03f, + 9.200106219628658571e-03f, + 8.996421128710744425e-03f, + 8.783899970919039138e-03f, + 8.562766127568535030e-03f, + 8.333251404975441923e-03f, + 8.095595792220260448e-03f, + 7.850047210942715306e-03f, + 7.596861257427847160e-03f, + 7.336300937249773911e-03f, + 7.068636392749921664e-03f, + 6.794144623630500764e-03f, + 6.513109200950242123e-03f, + 6.225819974820153910e-03f, + 5.932572776096196529e-03f, + 5.633669112378537902e-03f, + 5.329415858627153425e-03f, + 5.020124942711203311e-03f, + 4.706113026214525825e-03f, + 4.387701180821052503e-03f, + 4.065214560613866247e-03f, + 3.738982070617613389e-03f, + 3.409336031925057006e-03f, + 3.076611843746769430e-03f, + 2.741147642725723539e-03f, + 2.403283959864889810e-03f, + 2.063363375414229133e-03f, + 1.721730172063813159e-03f, + 1.378729986799676023e-03f, + 1.034709461766141576e-03f, + 6.900158944939007019e-04f, + 3.449968878405673157e-04f, + 0.000000000000000000e+00f, + -3.446276050693368302e-04f, + -6.885395064473497171e-04f, + -1.031390373933058213e-03f, + -1.372836314259132063e-03f, + -1.712535215489931510e-03f, + -2.050147089260192981e-03f, + -2.385334410513898287e-03f, + -2.717762454401503706e-03f, + -3.047099630002055894e-03f, + -3.373017810537275608e-03f, + -3.695192659748559091e-03f, + -4.013303954115152519e-03f, + -4.327035900590155311e-03f, + -4.636077449543945204e-03f, + -4.940122602601876300e-03f, + -5.238870715073626685e-03f, + -5.532026792676994140e-03f, + -5.819301782261442936e-03f, + -6.100412856246560135e-03f, + -6.375083690498107615e-03f, + -6.643044735364164385e-03f, + -6.904033479612515893e-03f, + -7.157794707005572452e-03f, + -7.404080745267220716e-03f, + -7.642651707196129220e-03f, + -7.873275723692764461e-03f, + -8.095729168475295640e-03f, + -8.309796874264679251e-03f, + -8.515272340233715279e-03f, + -8.711957930518144516e-03f, + -8.899665063600716020e-03f, + -9.078214392388751081e-03f, + -9.247435974810619408e-03f, + -9.407169434773821060e-03f, + -9.557264113329744237e-03f, + -9.697579209904895123e-03f, + -9.827983913467562213e-03f, + -9.948357523507136632e-03f, + -1.005858956071708186e-02f, + -1.015857986727966046e-02f, + -1.024823869666328068e-02f, + -1.032748679285360252e-02f, + -1.039625545894891021e-02f, + -1.045448661506321979e-02f, + -1.050213284548926623e-02f, + -1.053915743508587223e-02f, + -1.056553439486431802e-02f, + -1.058124847675941289e-02f, + -1.058629517758200196e-02f, + -1.058068073216014530e-02f, + -1.056442209568751386e-02f, + -1.053754691530808460e-02f, + -1.050009349097712034e-02f, + -1.045211072564902234e-02f, + -1.039365806485362080e-02f, + -1.032480542573286329e-02f, + -1.024563311561991173e-02f, + -1.015623174025468214e-02f, + -1.005670210173764852e-02f, + -9.947155086336527396e-03f, + -9.827711542269031153e-03f, + -9.698502147594538492e-03f, + -9.559667268359363368e-03f, + -9.411356807146858960e-03f, + -9.253730042196249908e-03f, + -9.086955457261344099e-03f, + -8.911210562389308004e-03f, + -8.726681705811039844e-03f, + -8.533563877139486997e-03f, + -8.332060502084964390e-03f, + -8.122383228901621996e-03f, + -7.904751706788885890e-03f, + -7.679393356479695225e-03f, + -7.446543133253041326e-03f, + -7.206443282618896044e-03f, + -6.959343088928202255e-03f, + -6.705498617166942392e-03f, + -6.445172448203926978e-03f, + -6.178633407762102944e-03f, + -5.906156289395311614e-03f, + -5.628021571754467968e-03f, + -5.344515130431467045e-03f, + -5.055927944681215189e-03f, + -4.762555799315829584e-03f, + -4.464698982081711544e-03f, + -4.162661976823887194e-03f, + -3.856753152753953674e-03f, + -3.547284450136960633e-03f, + -3.234571062715784710e-03f, + -2.918931117198290178e-03f, + -2.600685350131433544e-03f, + -2.280156782488628776e-03f, + -1.957670392303650399e-03f, + -1.633552785677109664e-03f, + -1.308131866494795974e-03f, + -9.817365051840280538e-04f, + -6.546962068479288350e-04f, + -3.273407791097072712e-04f, + 4.043570989833329463e-17f, + 3.269967137754016561e-04f, + 6.533206378577746144e-04f, + 9.786440702132328823e-04f, + 1.302640659735354979e-03f, + 1.624985733145793004e-03f, + 1.945356619862989578e-03f, + 2.263432974515657958e-03f, + 2.578897096781404205e-03f, + 2.891434248225943724e-03f, + 3.200732965834694743e-03f, + 3.506485371918194750e-03f, + 3.808387480088745985e-03f, + 4.106139497000982005e-03f, + 4.399446119558816405e-03f, + 4.688016827295758519e-03f, + 4.971566169637211575e-03f, + 5.249814047762459135e-03f, + 5.522485990789751178e-03f, + 5.789313426009380474e-03f, + 6.050033942903848549e-03f, + 6.304391550690290578e-03f, + 6.552136929139138963e-03f, + 6.793027672418951342e-03f, + 7.026828525731477169e-03f, + 7.253311614507366133e-03f, + 7.472256665937161355e-03f, + 7.683451222625906421e-03f, + 7.886690848162170725e-03f, + 8.081779324404252465e-03f, + 8.268528840294541229e-03f, + 8.446760172019297450e-03f, + 8.616302854343038317e-03f, + 8.776995342953978693e-03f, + 8.928685167666237238e-03f, + 9.071229076335495314e-03f, + 9.204493169351136636e-03f, + 9.328353024581554839e-03f, + 9.442693812655188201e-03f, + 9.547410402472212773e-03f, + 9.642407456851329745e-03f, + 9.727599518224548311e-03f, + 9.802911084305539202e-03f, + 9.868276673664756402e-03f, + 9.923640881156430005e-03f, + 9.968958423152556383e-03f, + 1.000419417254796474e-02f, + 1.002932318351319220e-02f, + 1.004433070597993659e-02f, + 1.004921218985568680e-02f, + 1.004397327897390071e-02f, + 1.002862979479642036e-02f, + 1.000320770989520693e-02f, + 9.967743111250705959e-03f, + 9.922282153414410666e-03f, + 9.866881001593018341e-03f, + 9.801605764722259168e-03f, + 9.726532418607795535e-03f, + 9.641746719220965420e-03f, + 9.547344106246909851e-03f, + 9.443429596991709252e-03f, + 9.330117670766156779e-03f, + 9.207532143871193647e-03f, + 9.075806035321471940e-03f, + 8.935081423451458893e-03f, + 8.785509293556969038e-03f, + 8.627249376736262007e-03f, + 8.460469980100025419e-03f, + 8.285347808531550937e-03f, + 8.102067778184653124e-03f, + 7.910822821914111069e-03f, + 7.711813686845882775e-03f, + 7.505248724294873164e-03f, + 7.291343672252590877e-03f, + 7.070321430670069122e-03f, + 6.842411829768484458e-03f, + 6.607851391620159567e-03f, + 6.366883085243799263e-03f, + 6.119756075469458441e-03f, + 5.866725465831302069e-03f, + 5.608052035751829104e-03f, + 5.344001972290637024e-03f, + 5.074846596729006530e-03f, + 4.800862086276046561e-03f, + 4.522329191175403912e-03f, + 4.239532947506496723e-03f, + 3.952762385971762653e-03f, + 3.662310236965878128e-03f, + 3.368472632229732935e-03f, + 3.071548803391624394e-03f, + 2.771840777700751261e-03f, + 2.469653071265261093e-03f, + 2.165292380101938724e-03f, + 1.859067269314046813e-03f, + 1.551287860709699411e-03f, + 1.242265519177247843e-03f, + 9.323125381350914204e-04f, + 6.217418243711637623e-04f, + 3.108665825923342669e-04f, + 6.717146213127583512e-17f, + -3.105450687918437651e-04f, + -6.204564161774286978e-04f, + -9.294227950051989944e-04f, + -1.237134230733572199e-03f, + -1.543282331983834290e-03f, + -1.847560599181306829e-03f, + -2.149664730972687243e-03f, + -2.449292928118728188e-03f, + -2.746146194552807982e-03f, + -3.039928635312416725e-03f, + -3.330347751041712323e-03f, + -3.617114728774667616e-03f, + -3.899944728711154593e-03f, + -4.178557166699342108e-03f, + -4.452675992145861683e-03f, + -4.722029961080219732e-03f, + -4.986352904100606331e-03f, + -5.245383988940638745e-03f, + -5.498867977395256908e-03f, + -5.746555476355140642e-03f, + -5.988203182702574526e-03f, + -6.223574121828233212e-03f, + -6.452437879537288590e-03f, + -6.674570827115577747e-03f, + -6.889756339339682574e-03f, + -7.097785005216259401e-03f, + -7.298454831247235333e-03f, + -7.491571437024912607e-03f, + -7.676948242966399882e-03f, + -7.854406650007556001e-03f, + -8.023776211084653054e-03f, + -8.184894794238147323e-03f, + -8.337608737184420971e-03f, + -8.481772993207853037e-03f, + -8.617251268236572961e-03f, + -8.743916148971660543e-03f, + -8.861649221950897853e-03f, + -8.970341183436947655e-03f, + -9.069891940027947907e-03f, + -9.160210699899310610e-03f, + -9.241216054595012552e-03f, + -9.312836051294730300e-03f, + -9.375008255495077131e-03f, + -9.427679804050792534e-03f, + -9.470807448532998427e-03f, + -9.504357588870533669e-03f, + -9.528306297250627166e-03f, + -9.542639332264922503e-03f, + -9.547352143296350749e-03f, + -9.542449865152758184e-03f, + -9.527947302962450418e-03f, + -9.503868907356978132e-03f, + -9.470248739975935248e-03f, + -9.427130429338478543e-03f, + -9.374567117135889846e-03f, + -9.312621395008722006e-03f, + -9.241365231882207529e-03f, + -9.160879891942457637e-03f, + -9.071255843345765041e-03f, + -8.972592657761846446e-03f, + -8.864998900862054027e-03f, + -8.748592013871738307e-03f, + -8.623498186314530051e-03f, + -8.489852220086737886e-03f, + -8.347797385005961690e-03f, + -8.197485265989208972e-03f, + -8.039075602022388231e-03f, + -7.872736117090798832e-03f, + -7.698642343250202899e-03f, + -7.516977436023509172e-03f, + -7.327931982316876480e-03f, + -7.131703801056546270e-03f, + -6.928497736752988953e-03f, + -6.718525446209536699e-03f, + -6.502005178594330234e-03f, + -6.279161549105892817e-03f, + -6.050225306465603983e-03f, + -5.815433094476260209e-03f, + -5.575027207895101936e-03f, + -5.329255342869666442e-03f, + -5.078370342195653343e-03f, + -4.822629935656748412e-03f, + -4.562296475713070905e-03f, + -4.297636668809446704e-03f, + -4.028921302576533685e-03f, + -3.756424969205551280e-03f, + -3.480425785277831575e-03f, + -3.201205108333276313e-03f, + -2.919047250469300383e-03f, + -2.634239189257616548e-03f, + -2.347070276275515198e-03f, + -2.057831943546030353e-03f, + -1.766817408183218516e-03f, + -1.474321375543928428e-03f, + -1.180639741184265909e-03f, + -8.860692919223937727e-04f, + -5.909074063099545391e-04f, + -2.954517548118973532e-04f, + -3.191480037364917763e-17f, + 2.951505029420960018e-04f, + 5.897030050987488040e-04f, + 8.833616617872707506e-04f, + 1.175831829311610932e-03f, + 1.466820360203527135e-03f, + 1.756035896659971941e-03f, + 2.043189161879899619e-03f, + 2.327993249011680189e-03f, + 2.610163907422230218e-03f, + 2.889419826001986703e-03f, + 3.165482913225662470e-03f, + 3.438078573687941564e-03f, + 3.706935980840707877e-03f, + 3.971788345662486015e-03f, + 4.232373180990945533e-03f, + 4.488432561260610569e-03f, + 4.739713377386114979e-03f, + 4.985967586540838471e-03f, + 5.226952456585757904e-03f, + 5.462430804905994176e-03f, + 5.692171231422111718e-03f, + 5.915948345547154125e-03f, + 6.133542986866762428e-03f, + 6.344742439328332831e-03f, + 6.549340638727800534e-03f, + 6.747138373295004030e-03f, + 6.937943477180526231e-03f, + 7.121571016657480234e-03f, + 7.297843468859207573e-03f, + 7.466590892878511958e-03f, + 7.627651093066531961e-03f, + 7.780869774372829901e-03f, + 7.926100689579733752e-03f, + 8.063205778290625028e-03f, + 8.192055297540449046e-03f, + 8.312527943906498212e-03f, + 8.424510967003927958e-03f, + 8.527900274261378949e-03f, + 8.622600526880391109e-03f, + 8.708525226889919993e-03f, + 8.785596795218742969e-03f, + 8.853746640715155422e-03f, + 8.912915220054325877e-03f, + 8.963052088482293539e-03f, + 9.004115941354405919e-03f, + 9.036074646436131896e-03f, + 9.058905266942841872e-03f, + 9.072594075305043249e-03f, + 9.077136557654227889e-03f, + 9.072537409034447248e-03f, + 9.058810519353838187e-03f, + 9.035978950099398527e-03f, + 9.004074901847999857e-03f, + 8.963139672615380235e-03f, + 8.913223607094592979e-03f, + 8.854386036843783780e-03f, + 8.786695211493011221e-03f, + 8.710228221048086500e-03f, + 8.625070909378744488e-03f, + 8.531317778987176914e-03f, + 8.429071887160986820e-03f, + 8.318444733624745513e-03f, + 8.199556139810507127e-03f, + 8.072534119878281914e-03f, + 7.937514743624142846e-03f, + 7.794641991421518389e-03f, + 7.644067601350621258e-03f, + 7.485950908677277416e-03f, + 7.320458677849650715e-03f, + 7.147764927190735675e-03f, + 6.968050746469218841e-03f, + 6.781504107540342781e-03f, + 6.588319668252944766e-03f, + 6.388698569828255708e-03f, + 6.182848227920212554e-03f, + 5.970982117573007432e-03f, + 5.753319552299874899e-03f, + 5.530085457510665325e-03f, + 5.301510138520690307e-03f, + 5.067829043382217347e-03f, + 4.829282520779390811e-03f, + 4.586115573237751521e-03f, + 4.338577605899722467e-03f, + 4.086922171123733884e-03f, + 3.831406709168724920e-03f, + 3.572292285227009461e-03f, + 3.309843323076701056e-03f, + 3.044327335621568181e-03f, + 2.776014652595465773e-03f, + 2.505178145706950243e-03f, + 2.232092951502079141e-03f, + 1.957036192228632423e-03f, + 1.680286694983667639e-03f, + 1.402124709426648972e-03f, + 1.122831624348555194e-03f, + 8.426896833769130903e-04f, + 5.619817001094690135e-04f, + 2.809907729590478470e-04f, + 0.000000000000000000e+00f, + -2.807078058981391780e-04f, + -5.608504013647517628e-04f, + -8.401463959614267896e-04f, + -1.118315534473937048e-03f, + -1.395078977776910336e-03f, + -1.670159581991349264e-03f, + -1.943282175656975462e-03f, + -2.214173834640201406e-03f, + -2.482564154505302687e-03f, + -2.748185520076693727e-03f, + -3.010773371923358872e-03f, + -3.270066469502342678e-03f, + -3.525807150696843618e-03f, + -3.777741587494939240e-03f, + -4.025620037552721069e-03f, + -4.269197091394013634e-03f, + -4.508231915003397400e-03f, + -4.742488487571064684e-03f, + -4.971735834156138824e-03f, + -5.195748253041122811e-03f, + -5.414305537549929381e-03f, + -5.627193192117104295e-03f, + -5.834202642391930586e-03f, + -6.035131439175642903e-03f, + -6.229783455990234309e-03f, + -6.417969080087524217e-03f, + -6.599505396713676100e-03f, + -6.774216366448439740e-03f, + -6.941932995450164623e-03f, + -7.102493498440299972e-03f, + -7.255743454271620582e-03f, + -7.401535953931983637e-03f, + -7.539731740839664825e-03f, + -7.670199343300234535e-03f, + -7.792815198996800620e-03f, + -7.907463771397596833e-03f, + -8.014037657972214804e-03f, + -8.112437690114479572e-03f, + -8.202573024681410890e-03f, + -8.284361227063144831e-03f, + -8.357728345709419457e-03f, + -8.422608978046395439e-03f, + -8.478946327725278564e-03f, + -8.526692253154843221e-03f, + -8.565807307276868815e-03f, + -8.596260768553768902e-03f, + -8.618030663145858153e-03f, + -8.631103778264705498e-03f, + -8.635475666698075314e-03f, + -8.631150642510639071e-03f, + -8.618141767933615305e-03f, + -8.596470831465410564e-03f, + -8.566168317214016212e-03f, + -8.527273365520683310e-03f, + -8.479833724913378445e-03f, + -8.423905695446994024e-03f, + -8.359554063495495263e-03f, + -8.286852028071115678e-03f, + -8.205881118751968267e-03f, + -8.116731105309984984e-03f, + -8.019499899138108831e-03f, + -7.914293446583613167e-03f, + -7.801225614304001070e-03f, + -7.680418066767507809e-03f, + -7.552000136030336853e-03f, + -7.416108683929066407e-03f, + -7.272887956833709935e-03f, + -7.122489433116511483e-03f, + -6.965071663495360846e-03f, + -6.800800104421189651e-03f, + -6.629846944682925639e-03f, + -6.452390925411476304e-03f, + -6.268617153670886545e-03f, + -6.078716909829352984e-03f, + -5.882887448911673298e-03f, + -5.681331796138239937e-03f, + -5.474258536861224822e-03f, + -5.261881601117059278e-03f, + -5.044420043014674268e-03f, + -4.822097815188827914e-03f, + -4.595143538549655710e-03f, + -4.363790267563028361e-03f, + -4.128275251306491068e-03f, + -3.888839690540101934e-03f, + -3.645728491045435640e-03f, + -3.399190013480753690e-03f, + -3.149475820010231263e-03f, + -2.896840417964342308e-03f, + -2.641541000791211135e-03f, + -2.383837186564273774e-03f, + -2.123990754310813977e-03f, + -1.862265378427587111e-03f, + -1.598926361455722204e-03f, + -1.334240365481033667e-03f, + -1.068475142436885140e-03f, + -8.018992635760308074e-04f, + -5.347818483891565765e-04f, + -2.673922932415280962e-04f, + -9.079959879021497232e-17f, + 2.671258950737993680e-04f, + 5.337167918945780664e-04f, + 7.995048963151187319e-04f, + 1.064223488808225876e-03f, + 1.327607191801307438e-03f, + 1.589392235393608270e-03f, + 1.849316721191365896e-03f, + 2.107120883999156515e-03f, + 2.362547351101621299e-03f, + 2.615341398882998439e-03f, + 2.865251206523531432e-03f, + 3.112028106524595324e-03f, + 3.355426831810707448e-03f, + 3.595205759164358736e-03f, + 3.831127148753331844e-03f, + 4.062957379511429948e-03f, + 4.290467180140932618e-03f, + 4.513431855509694376e-03f, + 4.731631508217054409e-03f, + 4.944851255114078407e-03f, + 5.152881438560737853e-03f, + 5.355517832217622683e-03f, + 5.552561841166678107e-03f, + 5.743820696166867384e-03f, + 5.929107641855835276e-03f, + 6.108242118712046975e-03f, + 6.281049938603144346e-03f, + 6.447363453748070593e-03f, + 6.607021718930415448e-03f, + 6.759870646807101223e-03f, + 6.905763156161545159e-03f, + 7.044559312960290212e-03f, + 7.176126464077911202e-03f, + 7.300339363562619553e-03f, + 7.417080291323936703e-03f, + 7.526239164128890706e-03f, + 7.627713638804527879e-03f, + 7.721409207549118775e-03f, + 7.807239285264657921e-03f, + 7.885125288831035251e-03f, + 7.954996708249086751e-03f, + 8.016791169590116797e-03f, + 8.070454489695856257e-03f, + 8.115940722582272102e-03f, + 8.153212197509116660e-03f, + 8.182239548684301991e-03f, + 8.203001736582492612e-03f, + 8.215486060864016227e-03f, + 8.219688164889776480e-03f, + 8.215612031835866150e-03f, + 8.203269972420074163e-03f, + 8.182682604260985149e-03f, + 8.153878822898639675e-03f, + 8.116895764514334491e-03f, + 8.071778760395010785e-03f, + 8.018581283196542925e-03f, + 7.957364885067841689e-03f, + 7.888199127706180952e-03f, + 7.811161504422274408e-03f, + 7.726337354300897436e-03f, + 7.633819768552089179e-03f, + 7.533709489153867997e-03f, + 7.426114799896956116e-03f, + 7.311151409948320190e-03f, + 7.188942330057568331e-03f, + 7.059617741539236935e-03f, + 6.923314858168461497e-03f, + 6.780177781137243509e-03f, + 6.630357347223709771e-03f, + 6.474010970332770391e-03f, + 6.311302476576784518e-03f, + 6.142401933065200215e-03f, + 5.967485470584375090e-03f, + 5.786735100350979578e-03f, + 5.600338525028452849e-03f, + 5.408488944204285429e-03f, + 5.211384854526987694e-03f, + 5.009229844711029882e-03f, + 4.802232385620449663e-03f, + 4.590605615646119360e-03f, + 4.374567121599736569e-03f, + 4.154338715345936607e-03f, + 3.930146206405986734e-03f, + 3.702219170760879478e-03f, + 3.470790716094145426e-03f, + 3.236097243712496643e-03f, + 2.998378207386371425e-03f, + 2.757875869357837798e-03f, + 2.514835053763304993e-03f, + 2.269502897720573724e-03f, + 2.022128600335697159e-03f, + 1.772963169880989280e-03f, + 1.522259169403208240e-03f, + 1.270270461017685608e-03f, + 1.017251949147536440e-03f, + 7.634593229678904650e-04f, + 5.091487983134088255e-04f, + 2.545768593114422170e-04f, + 5.893834195817279027e-17f, + -2.543255338102004309e-04f, + -5.081440021684953965e-04f, + -7.612004278544677463e-04f, + -1.013240852227075906e-03f, + -1.264012589796192692e-03f, + -1.513264481263194719e-03f, + -1.760747144774524840e-03f, + -2.006213225141300748e-03f, + -2.249417640770990170e-03f, + -2.490117828070589987e-03f, + -2.728073983073443527e-03f, + -2.963049300051106942e-03f, + -3.194810206873958253e-03f, + -3.423126596884991813e-03f, + -3.647772057057938316e-03f, + -3.868524092214752682e-03f, + -4.085164345078219975e-03f, + -4.297478811945374191e-03f, + -4.505258053766428641e-03f, + -4.708297402422947572e-03f, + -4.906397162001897849e-03f, + -5.099362804867554194e-03f, + -5.287005162340526442e-03f, + -5.469140609795000892e-03f, + -5.645591245996113387e-03f, + -5.816185066500464615e-03f, + -5.980756130952048950e-03f, + -6.139144724111944909e-03f, + -6.291197510464445995e-03f, + -6.436767682251153498e-03f, + -6.575715100791147336e-03f, + -6.707906430950256842e-03f, + -6.833215268632009988e-03f, + -6.951522261168058443e-03f, + -7.062715220494850468e-03f, + -7.166689229008634497e-03f, + -7.263346738000107591e-03f, + -7.352597658577248937e-03f, + -7.434359444991439289e-03f, + -7.508557170290937506e-03f, + -7.575123594233416392e-03f, + -7.633999223396016783e-03f, + -7.685132363431001340e-03f, + -7.728479163421451623e-03f, + -7.764003652300489888e-03f, + -7.791677767305085246e-03f, + -7.811481374443590177e-03f, + -7.823402280964399449e-03f, + -7.827436239820800487e-03f, + -7.823586946135632075e-03f, + -7.811866025676963803e-03f, + -7.792293015364394268e-03f, + -7.764895335833248320e-03f, + -7.729708256092200462e-03f, + -7.686774850317674296e-03f, + -7.636145946835978977e-03f, + -7.577880069352489409e-03f, + -7.512043370494353445e-03f, + -7.438709557741495296e-03f, + -7.357959811827293611e-03f, + -7.269882697699128586e-03f, + -7.174574068135403972e-03f, + -7.072136960122816021e-03f, + -6.962681484106240416e-03f, + -6.846324706228426420e-03f, + -6.723190523685911024e-03f, + -6.593409533333032847e-03f, + -6.457118893672204353e-03f, + -6.314462180376954545e-03f, + -6.165589235498591079e-03f, + -6.010656010514694655e-03f, + -5.849824403383760418e-03f, + -5.683262089774722935e-03f, + -5.511142348648704649e-03f, + -5.333643882371955774e-03f, + -5.150950631548067808e-03f, + -4.963251584760376527e-03f, + -4.770740583420043056e-03f, + -4.573616121923121738e-03f, + -4.372081143319735304e-03f, + -4.166342830707624179e-03f, + -3.956612394562757443e-03f, + -3.743104856225459159e-03f, + -3.526038827764110296e-03f, + -3.305636288440114059e-03f, + -3.082122358004176291e-03f, + -2.855725067054290869e-03f, + -2.626675124688376134e-03f, + -2.395205683690529615e-03f, + -2.161552103486554573e-03f, + -1.925951711112042913e-03f, + -1.688643560434465851e-03f, + -1.449868189872311657e-03f, + -1.209867378858563115e-03f, + -9.688839032931976462e-04f, + -7.271612902323416720e-04f, + -4.849435720621983882e-04f, + -2.424750404039046129e-04f, + -2.993458375907816894e-17f, + 2.422374771728505677e-04f, + 4.839937973155881718e-04f, + 7.250260894964933667e-04f, + 9.650924493755287268e-04f, + 1.203952181715645022e-03f, + 1.441366041441651457e-03f, + 1.677096473002762708e-03f, + 1.910907847800708860e-03f, + 2.142566699447316300e-03f, + 2.371841956615023273e-03f, + 2.598505173249376302e-03f, + 2.822330755915376365e-03f, + 3.043096188049002060e-03f, + 3.260582250895563590e-03f, + 3.474573240909645862e-03f, + 3.684857183408437892e-03f, + 3.891226042261025642e-03f, + 4.093475925410680442e-03f, + 4.291407286024813764e-03f, + 4.484825119075430515e-03f, + 4.673539153157502297e-03f, + 4.857364037355267616e-03f, + 5.036119522974105353e-03f, + 5.209630639960896592e-03f, + 5.377727867838498661e-03f, + 5.540247300990066084e-03f, + 5.697030808130492709e-03f, + 5.847926185810888196e-03f, + 5.992787305808217578e-03f, + 6.131474256255946623e-03f, + 6.263853476381850416e-03f, + 6.389797884721984053e-03f, + 6.509187000688825345e-03f, + 6.621907059378241700e-03f, + 6.727851119505293652e-03f, + 6.826919164367567169e-03f, + 6.919018195741605953e-03f, + 7.004062320623680518e-03f, + 7.081972830736373535e-03f, + 7.152678274725585150e-03f, + 7.216114522985169963e-03f, + 7.272224825048948307e-03f, + 7.320959859500953196e-03f, + 7.362277776360223042e-03f, + 7.396144231905143855e-03f, + 7.422532415909789162e-03f, + 7.441423071271871179e-03f, + 7.452804506020377015e-03f, + 7.456672597697913858e-03f, + 7.453030790120977571e-03f, + 7.441890082528809791e-03f, + 7.423269011139091954e-03f, + 7.397193623136587293e-03f, + 7.363697443128093892e-03f, + 7.322821432105069799e-03f, + 7.274613938962194541e-03f, + 7.219130644628227352e-03f, + 7.156434498872478629e-03f, + 7.086595649857397282e-03f, + 7.009691366515777115e-03f, + 6.925805953836947082e-03f, + 6.835030661154887534e-03f, + 6.737463583536625229e-03f, + 6.633209556377676723e-03f, + 6.522380043316587661e-03f, + 6.405093017587785986e-03f, + 6.281472836939533053e-03f, + 6.151650112247645033e-03f, + 6.015761569964638532e-03f, + 5.873949908548246022e-03f, + 5.726363649019010349e-03f, + 5.573156979804561387e-03f, + 5.414489596030440909e-03f, + 5.250526533426200064e-03f, + 5.081437997018541791e-03f, + 4.907399184788277351e-03f, + 4.728590106474792054e-03f, + 4.545195397714440512e-03f, + 4.357404129703668430e-03f, + 4.165409614584718312e-03f, + 3.969409206751546570e-03f, + 3.769604100281869798e-03f, + 3.566199122702250202e-03f, + 3.359402525296319511e-03f, + 3.149425770172853845e-03f, + 2.936483314308355533e-03f, + 2.720792390786955402e-03f, + 2.502572787458282825e-03f, + 2.282046623241240982e-03f, + 2.059438122297536054e-03f, + 1.834973386307630792e-03f, + 1.608880165078690333e-03f, + 1.381387625716168745e-03f, + 1.152726120594538663e-03f, + 9.231269543609431621e-04f, + 6.928221502061572470e-04f, + 4.620442156413446209e-04f, + 2.310259080137343159e-04f, + 0.000000000000000000e+00f, + -2.308009546876257196e-04f, + -4.611448551480424674e-04f, + -6.908002864531671621e-04f, + -9.195367518942560445e-04f, + -1.147124904077175120e-03f, + -1.373336774636224914e-03f, + -1.597946002337608667e-03f, + -1.820728059342699347e-03f, + -2.041460475406135615e-03f, + -2.259923059786094965e-03f, + -2.475898120643176686e-03f, + -2.689170681712491420e-03f, + -2.899528696030911467e-03f, + -3.106763256509465377e-03f, + -3.310668803139505106e-03f, + -3.511043326630707874e-03f, + -3.707688568276315544e-03f, + -3.900410215849520103e-03f, + -4.089018095338427944e-03f, + -4.273326358329034881e-03f, + -4.453153664852741063e-03f, + -4.628323361519555770e-03f, + -4.798663654760284072e-03f, + -4.964007779010489244e-03f, + -5.124194159669920833e-03f, + -5.279066570679284004e-03f, + -5.428474286561691883e-03f, + -5.572272228779376162e-03f, + -5.710321106265994241e-03f, + -5.842487549997011850e-03f, + -5.968644241469281582e-03f, + -6.088670034966893116e-03f, + -6.202450073495178670e-03f, + -6.309875898273007572e-03f, + -6.410845551679807824e-03f, + -6.505263673558881257e-03f, + -6.593041590787944613e-03f, + -6.674097400032071199e-03f, + -6.748356043603334110e-03f, + -6.815749378356467103e-03f, + -6.876216237559267495e-03f, + -6.929702485681070272e-03f, + -6.976161066051603243e-03f, + -7.015552041349363589e-03f, + -7.047842626885069371e-03f, + -7.073007216654443596e-03f, + -7.091027402140489926e-03f, + -7.101891983853740598e-03f, + -7.105596975605809294e-03f, + -7.102145601518914352e-03f, + -7.091548285781580294e-03f, + -7.073822635167690588e-03f, + -7.048993414343677349e-03f, + -7.017092513995498021e-03f, + -6.978158911814610725e-03f, + -6.932238626389115345e-03f, + -6.879384664053103844e-03f, + -6.819656958754997597e-03f, + -6.753122305011623888e-03f, + -6.679854284022603873e-03f, + -6.599933183026034100e-03f, + -6.513445907982721647e-03f, + -6.420485889683830161e-03f, + -6.321152983382738975e-03f, + -6.215553362058191117e-03f, + -6.103799403422135138e-03f, + -5.986009570792679216e-03f, + -5.862308287957658688e-03f, + -5.732825808160025433e-03f, + -5.597698077343937588e-03f, + -5.457066591803097846e-03f, + -5.311078250381432928e-03f, + -5.159885201379617314e-03f, + -5.003644684325990639e-03f, + -4.842518866777322309e-03f, + -4.676674676317842463e-03f, + -4.506283627929590085e-03f, + -4.331521646914106120e-03f, + -4.152568887545756218e-03f, + -3.969609547645198966e-03f, + -3.782831679262896318e-03f, + -3.592426995666025014e-03f, + -3.398590674828782209e-03f, + -3.201521159624679935e-03f, + -3.001419954927217991e-03f, + -2.798491421825367344e-03f, + -2.592942569162944196e-03f, + -2.384982842615481630e-03f, + -2.174823911519171114e-03f, + -1.962679453667881199e-03f, + -1.748764938296653790e-03f, + -1.533297407473102874e-03f, + -1.316495256117520629e-03f, + -1.098578010873439530e-03f, + -8.797661080547270916e-04f, + -6.602806708906880156e-04f, + -4.403432862964624440e-04f, + -2.201757813928862664e-04f, + 2.040351603294562245e-17f, + 2.199624206685035094e-04f, + 4.394902728878673139e-04f, + 6.583630006562409291e-04f, + 8.763609210572648189e-04f, + 1.093265444530637075e-03f, + 1.308859293828115375e-03f, + 1.522926721436776171e-03f, + 1.735253725253141800e-03f, + 1.945628262290407520e-03f, + 2.153840460208438813e-03f, + 2.359682826453400172e-03f, + 2.562950454799774267e-03f, + 2.763441229090153693e-03f, + 2.960956023969243955e-03f, + 3.155298902413077380e-03f, + 3.346277309858471712e-03f, + 3.533702264740658325e-03f, + 3.717388545249705484e-03f, + 3.897154872122122679e-03f, + 4.072824087288320731e-03f, + 4.244223328198080784e-03f, + 4.411184197655197183e-03f, + 4.573542928992711636e-03f, + 4.731140546427802310e-03f, + 4.883823020440311580e-03f, + 5.031441418021543807e-03f, + 5.173852047649186298e-03f, + 5.310916598845810341e-03f, + 5.442502276186440141e-03f, + 5.568481927626215550e-03f, + 5.688734167023349123e-03f, + 5.803143490740288873e-03f, + 5.911600388211953397e-03f, + 6.014001446374228968e-03f, + 6.110249447855176444e-03f, + 6.200253462834825341e-03f, + 6.283928934487773878e-03f, + 6.361197757929115161e-03f, + 6.431988352589909121e-03f, + 6.496235727955871307e-03f, + 6.553881542609762793e-03f, + 6.604874156524493181e-03f, + 6.649168676560485158e-03f, + 6.686726995128343919e-03f, + 6.717517821984657529e-03f, + 6.741516709135119897e-03f, + 6.758706068827057510e-03f, + 6.769075184619558622e-03f, + 6.772620215526905380e-03f, + 6.769344193237896226e-03f, + 6.759257012420358431e-03f, + 6.742375414127462462e-03f, + 6.718722962329050537e-03f, + 6.688330013598418541e-03f, + 6.651233679991463629e-03f, + 6.607477785162285504e-03f, + 6.557112813765961223e-03f, + 6.500195854205608435e-03f, + 6.436790534788347680e-03f, + 6.366966953360074857e-03f, + 6.290801600496780284e-03f, + 6.208377276335759996e-03f, + 6.119783001136048020e-03f, + 6.025113919665214118e-03f, + 5.924471199513612826e-03f, + 5.817961923445152776e-03f, + 5.705698975897815182e-03f, + 5.587800923754974829e-03f, + 5.464391891511682919e-03f, + 5.335601430968130686e-03f, + 5.201564385586319485e-03f, + 5.062420749651009438e-03f, + 4.918315522382780622e-03f, + 4.769398557154420036e-03f, + 4.615824405966431621e-03f, + 4.457752159344428866e-03f, + 4.295345281821967565e-03f, + 4.128771443180331673e-03f, + 3.958202345618636216e-03f, + 3.783813547031247577e-03f, + 3.605784280576109987e-03f, + 3.424297270716869252e-03f, + 3.239538545929211699e-03f, + 3.051697248262471695e-03f, + 2.860965439950404268e-03f, + 2.667537907270099533e-03f, + 2.471611961848510855e-03f, + 2.273387239617670301e-03f, + 2.073065497626217380e-03f, + 1.870850408910636978e-03f, + 1.666947355636944159e-03f, + 1.461563220720618573e-03f, + 1.254906178138427263e-03f, + 1.047185482141736864e-03f, + 8.386112555867926812e-04f, + 6.293942775949764364e-04f, + 4.197457707565461658e-04f, + 2.098771880941680316e-04f, + 5.182902902306673378e-17f, + -2.096745186397723764e-04f, + -4.189355009176130525e-04f, + -6.275726997620592390e-04f, + -8.353766989667140222e-04f, + -1.042139123179063390e-03f, + -1.247652846640042714e-03f, + -1.451712200463105501e-03f, + -1.654113178248326063e-03f, + -1.854653639823899535e-03f, + -2.053133512912701415e-03f, + -2.249354992523720179e-03f, + -2.443122737868256775e-03f, + -2.634244066605816777e-03f, + -2.822529146228016077e-03f, + -3.007791182387730897e-03f, + -3.189846603989948855e-03f, + -3.368515244858865266e-03f, + -3.543620521803565997e-03f, + -3.714989608904360665e-03f, + -3.882453607850389066e-03f, + -4.045847714158852700e-03f, + -4.205011379113398479e-03f, + -4.359788467263430063e-03f, + -4.510027409328340973e-03f, + -4.655581350359307320e-03f, + -4.796308293012311458e-03f, + -4.932071235793691541e-03f, + -5.062738306144363987e-03f, + -5.188182888232652744e-03f, + -5.308283745332808071e-03f, + -5.422925136671735008e-03f, + -5.531996928630324509e-03f, + -5.635394700194489362e-03f, + -5.733019842553966489e-03f, + -5.824779652754896557e-03f, + -5.910587421317968493e-03f, + -5.990362513738736391e-03f, + -6.064030445795148827e-03f, + -6.131522952591644815e-03f, + -6.192778051276466925e-03f, + -6.247740097375581447e-03f, + -6.296359834692139695e-03f, + -6.338594438727926730e-03f, + -6.374407553588771515e-03f, + -6.403769322343668378e-03f, + -6.426656410812841419e-03f, + -6.443052024767408938e-03f, + -6.452945920529682723e-03f, + -6.456334408969627466e-03f, + -6.453220352899971361e-03f, + -6.443613157878890461e-03f, + -6.427528756435856722e-03f, + -6.404989585742853347e-03f, + -6.376024558759821499e-03f, + -6.340669028889607886e-03f, + -6.298964748184136819e-03f, + -6.250959819150409338e-03f, + -6.196708640210494418e-03f, + -6.136271844877025546e-03f, + -6.069716234711278365e-03f, + -5.997114706136989597e-03f, + -5.918546171190292200e-03f, + -5.834095472290020540e-03f, + -5.743853291122007730e-03f, + -5.647916051732237638e-03f, + -5.546385817934258548e-03f, + -5.439370185137868373e-03f, + -5.326982166714451343e-03f, + -5.209340075018284791e-03f, + -5.086567397188134117e-03f, + -4.958792665860112768e-03f, + -4.826149324926455597e-03f, + -4.688775590479438843e-03f, + -4.546814307086526931e-03f, + -4.400412799544136007e-03f, + -4.249722720265064653e-03f, + -4.094899892456855747e-03f, + -3.936104149252287777e-03f, + -3.773499168959473186e-03f, + -3.607252306599120252e-03f, + -3.437534421903807366e-03f, + -3.264519703955130747e-03f, + -3.088385492637782913e-03f, + -2.909312097094693232e-03f, + -2.727482611368168587e-03f, + -2.543082727414555134e-03f, + -2.356300545685272984e-03f, + -2.167326383463741464e-03f, + -1.976352581158412423e-03f, + -1.783573306742843468e-03f, + -1.589184358546649181e-03f, + -1.393382966593760411e-03f, + -1.196367592691694598e-03f, + -9.983377294733853085e-04f, + -7.994936985940647280e-04f, + -6.000364482887320626e-04f, + -4.001673504937983648e-04f, + -2.000879977366511349e-04f, + -2.778966336884198701e-17f, + 1.998952182369787911e-04f, + 3.993966205749271080e-04f, + 5.983037606844037121e-04f, + 7.964169835089038611e-04f, + 9.935376254762236150e-04f, + 1.189468213520454305e-03f, + 1.384012662713176006e-03f, + 1.576976472307146200e-03f, + 1.768166919997466715e-03f, + 1.957393254204812128e-03f, + 2.144466884189903406e-03f, + 2.329201567810756240e-03f, + 2.511413596733711156e-03f, + 2.690921978917853227e-03f, + 2.867548618186650019e-03f, + 3.041118490714745520e-03f, + 3.211459818250186199e-03f, + 3.378404237904315821e-03f, + 3.541786968339587227e-03f, + 3.701446972192292979e-03f, + 3.857227114570970297e-03f, + 4.008974317473392411e-03f, + 4.156539709971333353e-03f, + 4.299778774016645676e-03f, + 4.438551485724410994e-03f, + 4.572722451997321066e-03f, + 4.702161042356552134e-03f, + 4.826741515851794284e-03f, + 4.946343142927884552e-03f, + 5.060850322128870871e-03f, + 5.170152691528663233e-03f, + 5.274145234779758183e-03f, + 5.372728381679093071e-03f, + 5.465808103155446809e-03f, + 5.553296000587267314e-03f, + 5.635109389366979755e-03f, + 5.711171376633489283e-03f, + 5.781410933099281717e-03f, + 5.845762958906964256e-03f, + 5.904168343452670387e-03f, + 5.956574019124233517e-03f, + 6.002933008903923832e-03f, + 6.043204467795012733e-03f, + 6.077353718035662794e-03f, + 6.105352278070978224e-03f, + 6.127177885260168266e-03f, + 6.142814512301600360e-03f, + 6.152252377365692929e-03f, + 6.155487947931146189e-03f, + 6.152523938326903176e-03f, + 6.143369300988309016e-03f, + 6.128039211442289080e-03f, + 6.106555047042762537e-03f, + 6.078944359483547284e-03f, + 6.045240841122706543e-03f, + 6.005484285157759554e-03f, + 5.959720539698134222e-03f, + 5.908001455786886062e-03f, + 5.850384829429483569e-03f, + 5.786934337694401610e-03f, + 5.717719468954846757e-03f, + 5.642815447348050774e-03f, + 5.562303151533275723e-03f, + 5.476269027836244349e-03f, + 5.384804997872509429e-03f, + 5.288008360747798245e-03f, + 5.185981689939928203e-03f, + 5.078832724969969611e-03f, + 4.966674257977718963e-03f, + 4.849624015320279195e-03f, + 4.727804534317043249e-03f, + 4.601343035271158316e-03f, + 4.470371288899312352e-03f, + 4.335025479308940791e-03f, + 4.195446062664641082e-03f, + 4.051777621689569946e-03f, + 3.904168716153416478e-03f, + 3.752771729500774690e-03f, + 3.597742711777335116e-03f, + 3.439241219017221893e-03f, + 3.277430149254536695e-03f, + 3.112475575329156242e-03f, + 2.944546574657440699e-03f, + 2.773815056141443278e-03f, + 2.600455584395403811e-03f, + 2.424645201466829776e-03f, + 2.246563246236072363e-03f, + 2.066391171676635035e-03f, + 1.884312360164382659e-03f, + 1.700511937020543225e-03f, + 1.515176582480621701e-03f, + 1.328494342278832389e-03f, + 1.140654437039362876e-03f, + 9.518470706689883707e-04f, + 7.622632379441338004e-04f, + 5.720945314859912732e-04f, + 3.815329483207086005e-04f, + 1.907706962172203138e-04f, + 0.000000000000000000e+00f, + -1.905870919690720166e-04f, + -3.807989009460705778e-04f, + -5.704443104011880719e-04f, + -7.593329578651235225e-04f, + -9.472754258310465579e-04f, + -1.134083431521770496e-03f, + -1.319570015332951216e-03f, + -1.503549727762363468e-03f, + -1.685838814639319377e-03f, + -1.866255400470208034e-03f, + -2.044619669715354044e-03f, + -2.220754045819160229e-03f, + -2.394483367813274831e-03f, + -2.565635064319175124e-03f, + -2.734039324775422008e-03f, + -2.899529267722648820e-03f, + -3.061941105977069883e-03f, + -3.221114308530460043e-03f, + -3.376891759017279938e-03f, + -3.529119910591425012e-03f, + -3.677648937060845960e-03f, + -3.822332880132129837e-03f, + -3.963029792618880109e-03f, + -4.099601877475613464e-03f, + -4.231915622519577709e-03f, + -4.359841930709697395e-03f, + -4.483256245856345398e-03f, + -4.602038673638307598e-03f, + -4.716074097811356024e-03f, + -4.825252291494681184e-03f, + -4.929468023428436492e-03f, + -5.028621159100716588e-03f, + -5.122616756646161500e-03f, + -5.211365157425208207e-03f, + -5.294782071198274320e-03f, + -5.372788655813301971e-03f, + -5.445311591332913613e-03f, + -5.512283148530877468e-03f, + -5.573641251695150671e-03f, + -5.629329535678900300e-03f, + -5.679297397148663600e-03f, + -5.723500039982650292e-03f, + -5.761898514779588421e-03f, + -5.794459752444061987e-03f, + -5.821156591819873563e-03f, + -5.841967801349767786e-03f, + -5.856878094745045400e-03f, + -5.865878140655318707e-03f, + -5.868964566334378651e-03f, + -5.866139955304165016e-03f, + -5.857412839025080524e-03f, + -5.842797682586693166e-03f, + -5.822314864439076185e-03f, + -5.795990650190794430e-03f, + -5.763857160505719661e-03f, + -5.725952333136686070e-03f, + -5.682319879139611715e-03f, + -5.633009233318153446e-03f, + -5.578075498953882598e-03f, + -5.517579386883428826e-03f, + -5.451587148989341623e-03f, + -5.380170506176684860e-03f, + -5.303406570913458962e-03f, + -5.221377764418140034e-03f, + -5.134171728582574354e-03f, + -5.041881232723846064e-03f, + -4.944604075264455272e-03f, + -4.842442980444399032e-03f, + -4.735505490173459210e-03f, + -4.623903851138305189e-03f, + -4.507754897281265882e-03f, + -4.387179927774727435e-03f, + -4.262304580617813123e-03f, + -4.133258701986374309e-03f, + -4.000176211472765767e-03f, + -3.863194963354634262e-03f, + -3.722456604035540191e-03f, + -3.578106425806113627e-03f, + -3.430293217074662122e-03f, + -3.279169109222944672e-03f, + -3.124889420243918709e-03f, + -2.967612495321265455e-03f, + -2.807499544515807202e-03f, + -2.644714477722959114e-03f, + -2.479423737071674658e-03f, + -2.311796126935456146e-03f, + -2.142002641728153745e-03f, + -1.970216291661061950e-03f, + -1.796611926638601179e-03f, + -1.621366058471044799e-03f, + -1.444656681584796090e-03f, + -1.266663092413158409e-03f, + -1.087565707650077398e-03f, + -9.075458815500990310e-04f, + -7.267857224613794324e-04f, + -5.454679087747773278e-04f, + -3.637755044768799673e-04f, + -1.818917744922234167e-04f, + -6.738072953108251659e-17f, + 1.817167060868667974e-04f, + 3.630755832968266678e-04f, + 5.438944072423667351e-04f, + 7.239916725462016735e-04f, + 9.031867748685456793e-04f, + 1.081300191851528036e-03f, + 1.258153662800393048e-03f, + 1.433570366922595502e-03f, + 1.607375099944760447e-03f, + 1.779394448933648617e-03f, + 1.949456965144877449e-03f, + 2.117393334728095468e-03f, + 2.283036547119419220e-03f, + 2.446222060952827054e-03f, + 2.606787967325983370e-03f, + 2.764575150259260348e-03f, + 2.919427444189183745e-03f, + 3.071191788339645758e-03f, + 3.219718377819110952e-03f, + 3.364860811295488155e-03f, + 3.506476235101599771e-03f, + 3.644425483631654871e-03f, + 3.778573215889237825e-03f, + 3.908788048053789092e-03f, + 4.034942681936477468e-03f, + 4.156914029198645506e-03f, + 4.274583331213595815e-03f, + 4.387836274453780008e-03f, + 4.496563101292173729e-03f, + 4.600658716111065936e-03f, + 4.700022786615127950e-03f, + 4.794559840251754780e-03f, + 4.884179355646818196e-03f, + 4.968795848967465581e-03f, + 5.048328955131142076e-03f, + 5.122703503783020661e-03f, + 5.191849589970850935e-03f, + 5.255702639451336616e-03f, + 5.314203468567116513e-03f, + 5.367298338639234223e-03f, + 5.414939004826021217e-03f, + 5.457082759404304449e-03f, + 5.493692469434578556e-03f, + 5.524736608777790041e-03f, + 5.550189284437050813e-03f, + 5.570030257202884111e-03f, + 5.584244956587067731e-03f, + 5.592824490035200498e-03f, + 5.595765646414466166e-03f, + 5.593070893778484716e-03f, + 5.584748371416978392e-03f, + 5.570811876203813663e-03f, + 5.551280843262597353e-03f, + 5.526180320974835580e-03f, + 5.495540940361090358e-03f, + 5.459398878871563054e-03f, + 5.417795818627875980e-03f, + 5.370778899163226178e-03f, + 5.318400664714218601e-03f, + 5.260719006122124147e-03f, + 5.197797097407722174e-03f, + 5.129703327088560444e-03f, + 5.056511224312396427e-03f, + 4.978299379887104678e-03f, + 4.895151362290443668e-03f, + 4.807155628749874669e-03f, + 4.714405431485941232e-03f, + 4.616998719219183103e-03f, + 4.515038034043206486e-03f, + 4.408630403773131437e-03f, + 4.297887229881802197e-03f, + 4.182924171140340805e-03f, + 4.063861023085189352e-03f, + 3.940821593436607748e-03f, + 3.813933573597338717e-03f, + 3.683328406365983000e-03f, + 3.549141150000212786e-03f, + 3.411510338771623577e-03f, + 3.270577840155389476e-03f, + 3.126488708801145999e-03f, + 2.979391037436725231e-03f, + 2.829435804855929236e-03f, + 2.676776721147767438e-03f, + 2.521570070325003087e-03f, + 2.363974550512310240e-03f, + 2.204151111858506946e-03f, + 2.042262792337711051e-03f, + 1.878474551605653284e-03f, + 1.712953103082745163e-03f, + 1.545866744432049548e-03f, + 1.377385186606322909e-03f, + 1.207679381635921347e-03f, + 1.036921349334177364e-03f, + 8.652840030934819777e-04f, + 6.929409749502218625e-04f, + 5.200664400946462904e-04f, + 3.468349410021595147e-04f, + 1.734212113648546741e-04f, + 4.550251594910668594e-17f, + -1.732541050876819561e-04f, + -3.461668523119788257e-04f, + -5.185645016036600878e-04f, + -6.902739988253162214e-04f, + -8.611231493274518678e-04f, + -1.030940790473021396e-03f, + -1.199556962955737344e-03f, + -1.366803080743145661e-03f, + -1.532512099472770496e-03f, + -1.696518683134078977e-03f, + -1.858659368870755474e-03f, + -2.018772729737835104e-03f, + -2.176699535252429873e-03f, + -2.332282909579588056e-03f, + -2.485368487193882845e-03f, + -2.635804565865009202e-03f, + -2.783442256814043243e-03f, + -2.928135631893509418e-03f, + -3.069741867644090218e-03f, + -3.208121386087987512e-03f, + -3.343137992118676207e-03f, + -3.474659007352662483e-03f, + -3.602555400312496166e-03f, + -3.726701912812024550e-03f, + -3.846977182422010779e-03f, + -3.963263860895238633e-03f, + -4.075448728436278055e-03f, + -4.183422803705368759e-03f, + -4.287081449448809645e-03f, + -4.386324473654241302e-03f, + -4.481056226133709602e-03f, + -4.571185690440540857e-03f, + -4.656626571033325307e-03f, + -4.737297375602708346e-03f, + -4.813121492483313744e-03f, + -4.884027263077780033e-03f, + -4.949948049224051072e-03f, + -5.010822295443905297e-03f, + -5.066593586014279949e-03f, + -5.117210696809050205e-03f, + -5.162627641864468188e-03f, + -5.202803714625973616e-03f, + -5.237703523840436977e-03f, + -5.267297024062328296e-03f, + -5.291559540748885272e-03f, + -5.310471789923680921e-03f, + -5.324019892394351271e-03f, + -5.332195382515387931e-03f, + -5.334995211492236412e-03f, + -5.332421745228884194e-03f, + -5.324482756726165410e-03f, + -5.311191413043757879e-03f, + -5.292566256844271830e-03f, + -5.268631182543137906e-03f, + -5.239415407093645990e-03f, + -5.204953435441478891e-03f, + -5.165285020688987344e-03f, + -5.120455119014034190e-03f, + -5.070513839394155328e-03f, + -5.015516388191593698e-03f, + -4.955523008659636248e-03f, + -4.890598915436772734e-03f, + -4.820814224098224007e-03f, + -4.746243875842361994e-03f, + -4.666967557390416105e-03f, + -4.583069616186550947e-03f, + -4.494638970986890303e-03f, + -4.401769017932832123e-03f, + -4.304557532207274433e-03f, + -4.203106565376605631e-03f, + -4.097522338526705075e-03f, + -3.987915131304275475e-03f, + -3.874399166978647214e-03f, + -3.757092493644813031e-03f, + -3.636116861689554780e-03f, + -3.511597597648849663e-03f, + -3.383663474586599915e-03f, + -3.252446579127917913e-03f, + -3.118082175285466148e-03f, + -2.980708565217376257e-03f, + -2.840466947061273412e-03f, + -2.697501269989864385e-03f, + -2.551958086636046431e-03f, + -2.403986403039817116e-03f, + -2.253737526269895732e-03f, + -2.101364909875016573e-03f, + -1.947023997324411840e-03f, + -1.790872063594110223e-03f, + -1.633068055064607060e-03f, + -1.473772427887728434e-03f, + -1.313146984991218642e-03f, + -1.151354711883460216e-03f, + -9.885596114266794344e-04f, + -8.249265377453095672e-04f, + -6.606210294368872974e-04f, + -4.958091422553860149e-04f, + -3.306572814353150912e-04f, + -1.653320338249910076e-04f, + -2.551386587880797004e-17f, + 1.651723734761380335e-04f, + 3.300189614740527827e-04f, + 4.943741272349469777e-04f, + 6.580728886553833265e-04f, + 8.209510837512715370e-04f, + 9.828455351376394825e-04f, + 1.143594213357676742e-03f, + 1.303036398898462693e-03f, + 1.461012842732159695e-03f, + 1.617365925221177182e-03f, + 1.771939813229538550e-03f, + 1.924580615284706168e-03f, + 2.075136534633631631e-03f, + 2.223458020043932865e-03f, + 2.369397914196333301e-03f, + 2.512811599526118631e-03f, + 2.653557141365132238e-03f, + 2.791495428245575894e-03f, + 2.926490309225380886e-03f, + 3.058408728100418372e-03f, + 3.187120854371934629e-03f, + 3.312500210839413109e-03f, + 3.434423797694213451e-03f, + 3.552772212992939740e-03f, + 3.667429769391414990e-03f, + 3.778284607026904680e-03f, + 3.885228802437357565e-03f, + 3.988158473412363458e-03f, + 4.086973879674651519e-03f, + 4.181579519293593741e-03f, + 4.271884220739164024e-03f, + 4.357801230486726615e-03f, + 4.439248296089245809e-03f, + 4.516147744637950996e-03f, + 4.588426556536215166e-03f, + 4.656016434517300413e-03f, + 4.718853867841324261e-03f, + 4.776880191610652533e-03f, + 4.830041641149988331e-03f, + 4.878289401399377341e-03f, + 4.921579651277259264e-03f, + 4.959873602972050821e-03f, + 4.993137536128673497e-03f, + 5.021342826899958915e-03f, + 5.044465971838839151e-03f, + 5.062488606612373584e-03f, + 5.075397519523472574e-03f, + 5.083184659832008616e-03f, + 5.085847140871759681e-03f, + 5.083387237965185726e-03f, + 5.075812381143095242e-03f, + 5.063135142681596430e-03f, + 5.045373219473861526e-03f, + 5.022549410259432613e-03f, + 4.994691587739028341e-03f, + 4.961832665607723673e-03f, + 4.924010560544767219e-03f, + 4.881268149203150074e-03f, + 4.833653220246830577e-03f, + 4.781218421489157218e-03f, + 4.724021202189871739e-03f, + 4.662123750573998575e-03f, + 4.595592926639679825e-03f, + 4.524500190327651952e-03f, + 4.448921525128770975e-03f, + 4.368937357210857936e-03f, + 4.284632470151218328e-03f, + 4.196095915364042757e-03f, + 4.103420918317851433e-03f, + 4.006704780641143562e-03f, + 3.906048778218370893e-03f, + 3.801558055383750991e-03f, + 3.693341515321936323e-03f, + 3.581511706790642402e-03f, + 3.466184707282398206e-03f, + 3.347480002746349489e-03f, + 3.225520363994377124e-03f, + 3.100431719920501098e-03f, + 2.972343027662367743e-03f, + 2.841386139839377056e-03f, + 2.707695669005051858e-03f, + 2.571408849450755249e-03f, + 2.432665396503416125e-03f, + 2.291607363462537170e-03f, + 2.148378996320580991e-03f, + 2.003126586416237656e-03f, + 1.855998321172221827e-03f, + 1.707144133066539190e-03f, + 1.556715546994994403e-03f, + 1.404865526175997237e-03f, + 1.251748316758327694e-03f, + 1.097519291286103453e-03f, + 9.423347911819565052e-04f, + 7.863519684062989651e-04f, + 6.297286264551491203e-04f, + 4.726230608546003620e-04f, + 3.151938993142525320e-04f, + 1.575999417021628837e-04f, + 7.784442283331923853e-17f, + -1.574472615986340432e-04f, + -3.145834862862096032e-04f, + -4.712507837750268031e-04f, + -6.272918888083930770e-04f, + -7.825503188873347447e-04f, + -9.368705310580024981e-04f, + -1.090098077600495973e-03f, + -1.242079760465078378e-03f, + -1.392663784299297746e-03f, + -1.541699907915918119e-03f, + -1.689039594049394563e-03f, + -1.834536157250591781e-03f, + -1.978044909775040876e-03f, + -2.119423305318431615e-03f, + -2.258531080456323715e-03f, + -2.395230393648445800e-03f, + -2.529385961670430668e-03f, + -2.660865193337756500e-03f, + -2.789538320388635587e-03f, + -2.915278525399034055e-03f, + -3.037962066602765791e-03f, + -3.157468399492973938e-03f, + -3.273680295087870538e-03f, + -3.386483954743054609e-03f, + -3.495769121399434042e-03f, + -3.601429187156589447e-03f, + -3.703361297068739032e-03f, + -3.801466449061457163e-03f, + -3.895649589871598342e-03f, + -3.985819706919274674e-03f, + -4.071889916022448409e-03f, + -4.153777544869190555e-03f, + -4.231404212169127994e-03f, + -4.304695902407762974e-03f, + -4.373583036132095911e-03f, + -4.438000535702448651e-03f, + -4.497887886447530723e-03f, + -4.553189193166368338e-03f, + -4.603853231924096880e-03f, + -4.649833497094323954e-03f, + -4.691088243605770480e-03f, + -4.727580524354188865e-03f, + -4.759278222747725245e-03f, + -4.786154080356886005e-03f, + -4.808185719646517267e-03f, + -4.825355661771149086e-03f, + -4.837651339421160553e-03f, + -4.845065104711230967e-03f, + -4.847594232107986685e-03f, + -4.845240916398877579e-03f, + -4.838012265708960952e-03f, + -4.825920289577491362e-03f, + -4.808981882111157055e-03f, + -4.787218800235539494e-03f, + -4.760657637071705889e-03f, + -4.729329790469200510e-03f, + -4.693271426731996689e-03f, + -4.652523439578401879e-03f, + -4.607131404381258066e-03f, + -4.557145527738585764e-03f, + -4.502620592430119431e-03f, + -4.443615897820203317e-03f, + -4.380195195770275780e-03f, + -4.312426622131352791e-03f, + -4.240382623888087031e-03f, + -4.164139882033739311e-03f, + -4.083779230256361775e-03f, + -3.999385569522737396e-03f, + -3.911047778650672546e-03f, + -3.818858620962382270e-03f, + -3.722914647117278510e-03f, + -3.623316094226521674e-03f, + -3.520166781352995246e-03f, + -3.413574001506695325e-03f, + -3.303648410246657133e-03f, + -3.190503911006380925e-03f, + -3.074257537259608274e-03f, + -2.955029331648956637e-03f, + -2.832942222203055620e-03f, + -2.708121895767779796e-03f, + -2.580696668782614736e-03f, + -2.450797355535883071e-03f, + -2.318557134031954108e-03f, + -2.184111409608732648e-03f, + -2.047597676446088772e-03f, + -1.909155377104432803e-03f, + -1.768925760238825853e-03f, + -1.627051736631422978e-03f, + -1.483677733692766133e-03f, + -1.338949548574867041e-03f, + -1.193014200049233526e-03f, + -1.046019779297893606e-03f, + -8.981152997709223890e-04f, + -7.494505462600843963e-04f, + -6.001759233424719181e-04f, + -4.504423033485727233e-04f, + -3.004008740059210055e-04f, + -1.502029859132318287e-04f, + 0.000000000000000000e+00f, + 1.500568648773128620e-04f, + 2.998166840477804458e-04f, + 4.491289786934320964e-04f, + 5.978438669215414185e-04f, + 7.458122140882831198e-04f, + 8.928857822246706166e-04f, + 1.038917378413064868e-03f, + 1.183761001968396554e-03f, + 1.327271990275858586e-03f, + 1.469307163138363920e-03f, + 1.609724965492229879e-03f, + 1.748385608347759190e-03f, + 1.885151207813307852e-03f, + 2.019885922067833454e-03f, + 2.152456086142171161e-03f, + 2.282730344379329916e-03f, + 2.410579780439001552e-03f, + 2.535878044720715069e-03f, + 2.658501479078634582e-03f, + 2.778329238704075124e-03f, + 2.895243411057801981e-03f, + 3.009129131734148907e-03f, + 3.119874697142386698e-03f, + 3.227371673896960082e-03f, + 3.331515004807996620e-03f, + 3.432203111369802693e-03f, + 3.529337992646119828e-03f, + 3.622825320457822695e-03f, + 3.712574530779899368e-03f, + 3.798498911258710829e-03f, + 3.880515684766671931e-03f, + 3.958546088913222558e-03f, + 4.032515451435444119e-03f, + 4.102353261397662619e-03f, + 4.167993236131739207e-03f, + 4.229373383854271966e-03f, + 4.286436061903056705e-03f, + 4.339128030537392315e-03f, + 4.387400502253299348e-03f, + 4.431209186566910548e-03f, + 4.470514330227219786e-03f, + 4.505280752820716751e-03f, + 4.535477877737257441e-03f, + 4.561079758469966522e-03f, + 4.582065100227887371e-03f, + 4.598417276843720300e-03f, + 4.610124342964186731e-03f, + 4.617179041515659735e-03f, + 4.619578806441900290e-03f, + 4.617325760715732842e-03f, + 4.610426709631436880e-03f, + 4.598893129389029603e-03f, + 4.582741150986642878e-03f, + 4.561991539441702728e-03f, + 4.536669668366456049e-03f, + 4.506805489927790190e-03f, + 4.472433500226501331e-03f, + 4.433592700134834745e-03f, + 4.390326551636334652e-03f, + 4.342682929716723365e-03f, + 4.290714069857965926e-03f, + 4.234476511192970805e-03f, + 4.174031035382547508e-03f, + 4.109442601280248290e-03f, + 4.040780275454714486e-03f, + 3.968117158643618379e-03f, + 3.891530308217908476e-03f, + 3.811100656737222755e-03f, + 3.726912926682747658e-03f, + 3.639055541457847723e-03f, + 3.547620532748325950e-03f, + 3.452703444340344142e-03f, + 3.354403232495308754e-03f, + 3.252822162986789261e-03f, + 3.148065704904799266e-03f, + 3.040242421338187288e-03f, + 2.929463857049219994e-03f, + 2.815844423254667064e-03f, + 2.699501279633036762e-03f, + 2.580554213680439322e-03f, + 2.459125517537331940e-03f, + 2.335339862413496597e-03f, + 2.209324170741059669e-03f, + 2.081207486184459728e-03f, + 1.951120841642063749e-03f, + 1.819197125372980488e-03f, + 1.685570945387657215e-03f, + 1.550378492237483022e-03f, + 1.413757400346775340e-03f, + 1.275846608024381462e-03f, + 1.136786216300893085e-03f, + 9.967173467317232399e-04f, + 8.557819983114523963e-04f, + 7.141229036455263310e-04f, + 5.718833845226121287e-04f, + 4.292072070347436501e-04f, + 2.862384363927389136e-04f, + 1.431212915810999909e-04f, + 3.976073045763746639e-17f, + -1.429813477578194541e-04f, + -2.856789428524072441e-04f, + -4.279494027150967353e-04f, + -5.696499149979476154e-04f, + -7.106383808068707187e-04f, + -8.507735570776003928e-04f, + -9.899151979507884221e-04f, + -1.127924195003721704e-03f, + -1.264662716200822120e-03f, + -1.399994343423132705e-03f, + -1.533784208438585678e-03f, + -1.665899127179875554e-03f, + -1.796207732195136955e-03f, + -1.924580603139482322e-03f, + -2.050890395178425665e-03f, + -2.175011965176371249e-03f, + -2.296822495544894628e-03f, + -2.416201615627299338e-03f, + -2.533031520501645515e-03f, + -2.647197087084067826e-03f, + -2.758585987417253894e-03f, + -2.867088799034697190e-03f, + -2.972599112290812313e-03f, + -3.075013634552971071e-03f, + -3.174232291152105818e-03f, + -3.270158322995199603e-03f, + -3.362698380743715538e-03f, + -3.451762615465765304e-03f, + -3.537264765675776721e-03f, + -3.619122240676629892e-03f, + -3.697256200123399950e-03f, + -3.771591629733630612e-03f, + -3.842057413070905456e-03f, + -3.908586399332766859e-03f, + -3.971115467079878135e-03f, + -4.029585583845121145e-03f, + -4.083941861567453452e-03f, + -4.134133607797787699e-03f, + -4.180114372630844115e-03f, + -4.221841991318395042e-03f, + -4.259278622526630094e-03f, + -4.292390782202119143e-03f, + -4.321149373017542893e-03f, + -4.345529709371441680e-03f, + -4.365511537920943770e-03f, + -4.381079053631709713e-03f, + -4.392220911332943636e-03f, + -4.398930232770211640e-03f, + -4.401204609153669053e-03f, + -4.399046099203249988e-03f, + -4.392461222697331344e-03f, + -4.381460949535757529e-03f, + -4.366060684332634563e-03f, + -4.346280246558699781e-03f, + -4.322143846257833419e-03f, + -4.293680055366262162e-03f, + -4.260921774667682412e-03f, + -4.223906196422148006e-03f, + -4.182674762710170135e-03f, + -4.137273119538274584e-03f, + -4.087751066756856698e-03f, + -4.034162503844153022e-03f, + -3.976565371615301513e-03f, + -3.915021589919383607e-03f, + -3.849596991390978259e-03f, + -3.780361251326535416e-03f, + -3.707387813760094821e-03f, + -3.630753813817203315e-03f, + -3.550539996427677474e-03f, + -3.466830631483622076e-03f, + -3.379713425530830959e-03f, + -3.289279430087042790e-03f, + -3.195622946681347856e-03f, + -3.098841428714084380e-03f, + -2.999035380240086535e-03f, + -2.896308251778681887e-03f, + -2.790766333258949596e-03f, + -2.682518644211763417e-03f, + -2.571676821320250696e-03f, + -2.458355003445216510e-03f, + -2.342669714244821622e-03f, + -2.224739742507099091e-03f, + -2.104686020319705697e-03f, + -1.982631499200445194e-03f, + -1.858701024317035294e-03f, + -1.733021206922603788e-03f, + -1.605720295138181623e-03f, + -1.476928043214278908e-03f, + -1.346775579404299638e-03f, + -1.215395272583683463e-03f, + -1.082920597750686208e-03f, + -9.494860005465256434e-04f, + -8.152267609301555324e-04f, + -6.802788561468293017e-04f, + -5.447788231302409367e-04f, + -4.088636204751821168e-04f, + -2.726704901212254279e-04f, + -1.363368188880890964e-04f, + -8.417792963206818356e-17f, + 1.362027052598085422e-04f, + 2.721343056259442508e-04f, + 4.076582175196397572e-04f, + 5.426384021722333592e-04f, + 6.769395020654857481e-04f, + 8.104269765506644935e-04f, + 9.429672365128469180e-04f, + 1.074427777944659190e-03f, + 1.204677314294974296e-03f, + 1.333585907462621518e-03f, + 1.461025097303440606e-03f, + 1.586868029520704633e-03f, + 1.710989581813802214e-03f, + 1.833266488158666763e-03f, + 1.953577461096326229e-03f, + 2.071803311908859517e-03f, + 2.187827068564226606e-03f, + 2.301534091313028798e-03f, + 2.412812185822113195e-03f, + 2.521551713735463440e-03f, + 2.627645700551932938e-03f, + 2.730989940714999460e-03f, + 2.831483099809944254e-03f, + 2.929026813770171413e-03f, + 3.023525784994855574e-03f, + 3.114887875283365529e-03f, + 3.203024195497624661e-03f, + 3.287849191864475069e-03f, + 3.369280728833792034e-03f, + 3.447240168413722491e-03f, + 3.521652445905853156e-03f, + 3.592446141966990254e-03f, + 3.659553550929970766e-03f, + 3.722910745317228355e-03f, + 3.782457636486660606e-03f, + 3.838138031351646592e-03f, + 3.889899685123011756e-03f, + 3.937694350023167832e-03f, + 3.981477819927187536e-03f, + 4.021209970890143003e-03f, + 4.056854797524065380e-03f, + 4.088380445191790516e-03f, + 4.115759237989136295e-03f, + 4.138967702491964246e-03f, + 4.157986587248014773e-03f, + 4.172800877997954669e-03f, + 4.183399808614909378e-03f, + 4.189776867755429235e-03f, + 4.191929801219356974e-03f, + 4.189860610020690324e-03f, + 4.183575544175400195e-03f, + 4.173085092216739442e-03f, + 4.158403966452908773e-03f, + 4.139551083985980491e-03f, + 4.116549543515387807e-03f, + 4.089426597953691074e-03f, + 4.058213622886065394e-03f, + 4.022946080909405378e-03f, + 3.983663481891361151e-03f, + 3.940409339192868857e-03f, + 3.893231121902388826e-03f, + 3.842180203134375367e-03f, + 3.787311804446883475e-03f, + 3.728684936439468408e-03f, + 3.666362335593461707e-03f, + 3.600410397423470070e-03f, + 3.530899106009756632e-03f, + 3.457901959986858006e-03f, + 3.381495895065876871e-03f, + 3.301761203172812187e-03f, + 3.218781448286551963e-03f, + 3.132643379065020751e-03f, + 3.043436838351391838e-03f, + 2.951254669653231681e-03f, + 2.856192620692367314e-03f, + 2.758349244126263259e-03f, + 2.657825795542260918e-03f, + 2.554726128830706305e-03f, + 2.449156589045835622e-03f, + 2.341225902863081770e-03f, + 2.231045066746887174e-03f, + 2.118727232942822086e-03f, + 2.004387593412520346e-03f, + 1.888143261828470910e-03f, + 1.770113153750305698e-03f, + 1.650417865105977249e-03f, + 1.529179549100039177e-03f, + 1.406521791675539998e-03f, + 1.282569485656734343e-03f, + 1.157448703700234525e-03f, + 1.031286570183274475e-03f, + 9.042111321594720934e-04f, + 7.763512295141050895e-04f, + 6.478363644484194097e-04f, + 5.187965704260827501e-04f, + 3.893622807153351221e-04f, + 2.596641966575497277e-04f, + 1.298331557961695734e-04f, + 0.000000000000000000e+00f, + -1.297045562884773494e-04f, + -2.591500575455231805e-04f, + -3.882064382682380425e-04f, + -5.167441535531211438e-04f, + -6.446343090221472215e-04f, + -7.717487899651593111e-04f, + -8.979603895682745050e-04f, + -1.023142936102136233e-03f, + -1.147171418941898315e-03f, + -1.269922113292209966e-03f, + -1.391272703494883479e-03f, + -1.511102404795431394e-03f, + -1.629292083446334978e-03f, + -1.745724375030405316e-03f, + -1.860283800883534306e-03f, + -1.972856882504857214e-03f, + -2.083332253837852453e-03f, + -2.191600771314119924e-03f, + -2.297555621549458339e-03f, + -2.401092426587344512e-03f, + -2.502109346584675646e-03f, + -2.600507179840733183e-03f, + -2.696189460070382710e-03f, + -2.789062550825482587e-03f, + -2.879035736973885838e-03f, + -2.966021313145917292e-03f, + -3.049934669061640530e-03f, + -3.130694371657468528e-03f, + -3.208222243931873989e-03f, + -3.282443440433375874e-03f, + -3.353286519319528813e-03f, + -3.420683510916569352e-03f, + -3.484569982714951809e-03f, + -3.544885100737864888e-03f, + -3.601571687225699116e-03f, + -3.654576274581390269e-03f, + -3.703849155525655665e-03f, + -3.749344429416276783e-03f, + -3.791020044687998507e-03f, + -3.828837837374106986e-03f, + -3.862763565674989016e-03f, + -3.892766940542859502e-03f, + -3.918821652255656887e-03f, + -3.940905392957132734e-03f, + -3.958999875144887486e-03f, + -3.973090846091481033e-03f, + -3.983168098188016350e-03f, + -3.989225475204148490e-03f, + -3.991260874462022705e-03f, + -3.989276244926093229e-03f, + -3.983277581214771101e-03f, + -3.973274913544052635e-03f, + -3.959282293617159831e-03f, + -3.941317776478633732e-03f, + -3.919403398354929027e-03f, + -3.893565150507910695e-03f, + -3.863832949131735649e-03f, + -3.830240601327010268e-03f, + -3.792825767190527789e-03f, + -3.751629918062933215e-03f, + -3.706698290979619330e-03f, + -3.658079839375025927e-03f, + -3.605827180092993720e-03f, + -3.549996536761576733e-03f, + -3.490647679591208329e-03f, + -3.427843861661717968e-03f, + -3.361651751765054510e-03f, + -3.292141363875685824e-03f, + -3.219385983321982822e-03f, + -3.143462089736679104e-03f, + -3.064449276867864478e-03f, + -2.982430169333176711e-03f, + -2.897490336404670141e-03f, + -2.809718202914781877e-03f, + -2.719204957374711431e-03f, + -2.626044457401114501e-03f, + -2.530333132549811032e-03f, + -2.432169884655409342e-03f, + -2.331655985780983504e-03f, + -2.228894973881932924e-03f, + -2.123992546292832913e-03f, + -2.017056451144963979e-03f, + -1.908196376826750383e-03f, + -1.797523839601251243e-03f, + -1.685152069494012198e-03f, + -1.571195894568736418e-03f, + -1.455771623709985587e-03f, + -1.338996928029888246e-03f, + -1.220990721022854842e-03f, + -1.101873037586910105e-03f, + -9.817649120378681756e-04f, + -8.607882552375694957e-04f, + -7.390657309618451016e-04f, + -6.167206316344765651e-04f, + -4.938767535509734369e-04f, + -3.706582717193119820e-04f, + -2.471896144450557429e-04f, + -1.235953377853419590e-04f, + -4.959890100963354769e-17f, + 1.234719638747178042e-04f, + 2.466963672028767455e-04f, + 3.695493965506171539e-04f, + 4.919077359883478268e-04f, + 6.136486907666624611e-04f, + 7.346503102443730469e-04f, + 8.547915099445561275e-04f, + 9.739521926155840070e-04f, + 1.092013368178181270e-03f, + 1.208857272437798046e-03f, + 1.324367484443061309e-03f, + 1.438429042375458577e-03f, + 1.550928557853214172e-03f, + 1.661754328537675893e-03f, + 1.770796448927353453e-03f, + 1.877946919233882935e-03f, + 1.983099752229050636e-03f, + 2.086151077959072422e-03f, + 2.186999246221175627e-03f, + 2.285544926703325219e-03f, + 2.381691206687666998e-03f, + 2.475343686220975951e-03f, + 2.566410570660377331e-03f, + 2.654802760502929671e-03f, + 2.740433938410591005e-03f, + 2.823220653347242176e-03f, + 2.903082401745072944e-03f, + 2.979941705620986828e-03f, + 3.053724187568778933e-03f, + 3.124358642553495477e-03f, + 3.191777106439702780e-03f, + 3.255914921186875855e-03f, + 3.316710796650810048e-03f, + 3.374106868931566437e-03f, + 3.428048755212193075e-03f, + 3.478485605037506118e-03f, + 3.525370147984284441e-03f, + 3.568658737678078504e-03f, + 3.608311392117048363e-03f, + 3.644291830264629207e-03f, + 3.676567504879116322e-03f, + 3.705109631549780621e-03f, + 3.729893213914910709e-03f, + 3.750897065039809040e-03f, + 3.768103824936940016e-03f, + 3.781499974214817122e-03f, + 3.791075843845443261e-03f, + 3.796825621044523733e-03f, + 3.798747351262270894e-03f, + 3.796842936286857866e-03f, + 3.791118128466208596e-03f, + 3.781582521057830042e-03f, + 3.768249534720393822e-03f, + 3.751136400164309208e-03f, + 3.730264136982911188e-03f, + 3.705657528689156911e-03f, + 3.677345093986788237e-03f, + 3.645359054308939216e-03f, + 3.609735297660244310e-03f, + 3.570513338802807409e-03f, + 3.527736275829614857e-03f, + 3.481450743173182798e-03f, + 3.431706861099539409e-03f, + 3.378558181742752180e-03f, + 3.322061631737472948e-03f, + 3.262277451510458420e-03f, + 3.199269131295992552e-03f, + 3.133103343942434792e-03f, + 3.063849874581625003e-03f, + 2.991581547234064588e-03f, + 2.916374148427355699e-03f, + 2.838306347908428270e-03f, + 2.757459616531154987e-03f, + 2.673918141405439829e-03f, + 2.587768738396670036e-03f, + 2.499100762065002874e-03f, + 2.408006013138405590e-03f, + 2.314578643615823259e-03f, + 2.218915059596944257e-03f, + 2.121113821939972673e-03f, + 2.021275544848643961e-03f, + 1.919502792494091415e-03f, + 1.815899973775997930e-03f, + 1.710573235331645401e-03f, + 1.603630352903246976e-03f, + 1.495180621172954036e-03f, + 1.385334742178912079e-03f, + 1.274204712426525677e-03f, + 1.161903708809525985e-03f, + 1.048545973456544876e-03f, + 9.342466976205273310e-04f, + 8.191219047299183901e-04f, + 7.032883327184241478e-04f, + 5.868633157534830069e-04f, + 4.699646654841184022e-04f, + 3.527105519262883665e-04f, + 2.352193841077147634e-04f, + 1.176096905914035935e-04f, + -1.816279043680416122e-17f, + -1.174912783408097822e-04f, + -2.347459735184355596e-04f, + -3.516462717890174536e-04f, + -4.680748348545702049e-04f, + -5.839149175424285850e-04f, + -6.990504847680064412e-04f, + -8.133663276656900908e-04f, + -9.267481787707859599e-04f, + -1.039082826136560620e-03f, + -1.150258226274457644e-03f, + -1.260163615803283491e-03f, + -1.368689621697415744e-03f, + -1.475728370022750873e-03f, + -1.581173593054908304e-03f, + -1.684920734670451118e-03f, + -1.786867053909769803e-03f, + -1.886911726606242201e-03f, + -1.984955944983589262e-03f, + -2.080903015122214511e-03f, + -2.174658452197730102e-03f, + -2.266130073399595744e-03f, + -2.355228088437774474e-03f, + -2.441865187547984182e-03f, + -2.525956626910913581e-03f, + -2.607420311401180066e-03f, + -2.686176874584755934e-03f, + -2.762149755888469640e-03f, + -2.835265274865544395e-03f, + -2.905452702486107687e-03f, + -2.972644329382842596e-03f, + -3.036775530987343309e-03f, + -3.097784829494083791e-03f, + -3.155613952592319516e-03f, + -3.210207888911055518e-03f, + -3.261514940123977010e-03f, + -3.309486769664863031e-03f, + -3.354078448008697769e-03f, + -3.395248494475826620e-03f, + -3.432958915520433179e-03f, + -3.467175239468593684e-03f, + -3.497866547674528641e-03f, + -3.525005502067194568e-03f, + -3.548568369062852102e-03f, + -3.568535039823742677e-03f, + -3.584889046845683540e-03f, + -3.597617576861870340e-03f, + -3.606711480053335483e-03f, + -3.612165275560820770e-03f, + -3.613977153296067668e-03f, + -3.612148972054406073e-03f, + -3.606686253934421674e-03f, + -3.597598175073908090e-03f, + -3.584897552715274240e-03f, + -3.568600828617066786e-03f, + -3.548728048831968108e-03f, + -3.525302839875490025e-03f, + -3.498352381312806562e-03f, + -3.467907374795066184e-03f, + -3.434002009579821546e-03f, + -3.396673924574244215e-03f, + -3.355964166942346574e-03f, + -3.311917147321609932e-03f, + -3.264580591697720767e-03f, + -3.214005489989122874e-03f, + -3.160246041396339717e-03f, + -3.103359596574423087e-03f, + -3.043406596690569153e-03f, + -2.980450509430481246e-03f, + -2.914557762021494861e-03f, + -2.845797671343432839e-03f, + -2.774242371199536934e-03f, + -2.699966736824086378e-03f, + -2.623048306706114718e-03f, + -2.543567201809550458e-03f, + -2.461606042274317591e-03f, + -2.377249861685521663e-03f, + -2.290586018998170062e-03f, + -2.201704108209648781e-03f, + -2.110695865872344850e-03f, + -2.017655076542951807e-03f, + -1.922677476264368895e-03f, + -1.825860654179994359e-03f, + -1.727303952382239390e-03f, + -1.627108364096408778e-03f, + -1.525376430304876962e-03f, + -1.422212134918130876e-03f, + -1.317720798598115244e-03f, + -1.212008971343053179e-03f, + -1.105184323943502606e-03f, + -9.973555384197396820e-04f, + -8.886321975514789584e-04f, + -7.791246736123785127e-04f, + -6.689440164231939519e-04f, + -5.582018408351800513e-04f, + -4.470102137591960715e-04f, + -3.354815408535864675e-04f, + -2.237284529868988829e-04f, + -1.118636925881364959e-04f, + -2.071470033548900873e-17f, + 1.117500000493719706e-04f, + 2.232739117441697070e-04f, + 3.344596811326808606e-04f, + 4.451957086194700233e-04f, + 5.553709608865004844e-04f, + 6.648750821302810846e-04f, + 7.735985045027994698e-04f, + 8.814325576476730742e-04f, + 9.882695772205538597e-04f, + 1.094003012286658312e-03f, + 1.198527531486872971e-03f, + 1.301739127868568706e-03f, + 1.403535222275920568e-03f, + 1.503814765196793968e-03f, + 1.602478336965568358e-03f, + 1.699428246223005749e-03f, + 1.794568626535442959e-03f, + 1.887805531077050170e-03f, + 1.979047025283286153e-03f, + 2.068203277383505716e-03f, + 2.155186646722974993e-03f, + 2.239911769789048289e-03f, + 2.322295643856428504e-03f, + 2.402257708169032186e-03f, + 2.479719922580636039e-03f, + 2.554606843576476966e-03f, + 2.626845697602746450e-03f, + 2.696366451631782273e-03f, + 2.763101880895990278e-03f, + 2.826987633724481735e-03f, + 2.887962293419586799e-03f, + 2.945967437115027624e-03f, + 3.000947691558917239e-03f, + 3.052850785768143008e-03f, + 3.101627600505197247e-03f, + 3.147232214530348154e-03f, + 3.189621947585512783e-03f, + 3.228757400070635542e-03f, + 3.264602489375515067e-03f, + 3.297124482833800954e-03f, + 3.326294027269616291e-03f, + 3.352085175110586929e-03f, + 3.374475407044334914e-03f, + 3.393445651198981165e-03f, + 3.408980298832289899e-03f, + 3.421067216516832533e-03f, + 3.429697754812713849e-03f, + 3.434866753422505335e-03f, + 3.436572542826982733e-03f, + 3.434816942403465419e-03f, + 3.429605255032289191e-03f, + 3.420946258200424379e-03f, + 3.408852191614762661e-03f, + 3.393338741341164321e-03f, + 3.374425020488695717e-03f, + 3.352133546462037709e-03f, + 3.326490214808674843e-03f, + 3.297524269690380733e-03f, + 3.265268271012441645e-03f, + 3.229758058246862303e-03f, + 3.191032710989869740e-03f, + 3.149134506296154788e-03f, + 3.104108872836428955e-03f, + 3.056004341927853838e-03f, + 3.004872495489709604e-03f, + 2.950767910979716115e-03f, + 2.893748103369611722e-03f, + 2.833873464221980509e-03f, + 2.771207197931811923e-03f, + 2.705815255200260967e-03f, + 2.637766263811031336e-03f, + 2.567131456780837821e-03f, + 2.493984597959450489e-03f, + 2.418401905157508119e-03f, + 2.340461970880830869e-03f, + 2.260245680754550089e-03f, + 2.177836129720765214e-03f, + 2.093318536097558535e-03f, + 2.006780153586758438e-03f, + 1.918310181321814228e-03f, + 1.827999672049080305e-03f, + 1.735941438535555485e-03f, + 1.642229958299797413e-03f, + 1.546961276764474095e-03f, + 1.450232908928234844e-03f, + 1.352143739658173346e-03f, + 1.252793922705604940e-03f, + 1.152284778546037915e-03f, + 1.050718691150112800e-03f, + 9.481990037877905493e-04f, + 8.448299139744811252e-04f, + 7.407163676634808108e-04f, + 6.359639527935932865e-04f, + 5.306787922987215612e-04f, + 4.249674366892458523e-04f, + 3.189367563120465432e-04f, + 2.126938333988559937e-04f, + 1.063458540127559251e-04f, + 5.580875061456703527e-17f, + -1.062366589427715403e-04f, + -2.122572729776368709e-04f, + -3.179553195023174803e-04f, + -4.232247100881988380e-04f, + -5.279598968701624921e-04f, + -6.320559782838149239e-04f, + -7.354088040427114292e-04f, + -8.379150792517338136e-04f, + -9.394724675511614224e-04f, + -1.039979693190289578e-03f, + -1.139336641928036893e-03f, + -1.237444460659308312e-03f, + -1.334205655669700157e-03f, + -1.429524189420069849e-03f, + -1.523305575764726449e-03f, + -1.615456973509339471e-03f, + -1.705887278216311432e-03f, + -1.794507212166710506e-03f, + -1.881229412389207739e-03f, + -1.965968516670845660e-03f, + -2.048641247464260805e-03f, + -2.129166493608392920e-03f, + -2.207465389784019332e-03f, + -2.283461393625221911e-03f, + -2.357080360412389282e-03f, + -2.428250615272878506e-03f, + -2.496903022820505004e-03f, + -2.562971054165676978e-03f, + -2.626390851230865024e-03f, + -2.687101288310514684e-03f, + -2.745044030815619023e-03f, + -2.800163591146226632e-03f, + -2.852407381639556275e-03f, + -2.901725764542836122e-03f, + -2.948072098963223399e-03f, + -2.991402784751522655e-03f, + -3.031677303277889764e-03f, + -3.068858255062130534e-03f, + -3.102911394223503531e-03f, + -3.133805659718869735e-03f, + -3.161513203341241758e-03f, + -3.186009414453190580e-03f, + -3.207272941434331694e-03f, + -3.225285709824096680e-03f, + -3.240032937145292686e-03f, + -3.251503144396590377e-03f, + -3.259688164206146245e-03f, + -3.264583145641404907e-03f, + -3.266186555673606436e-03f, + -3.264500177299172780e-03f, + -3.259529104323136660e-03f, + -3.251281732813429259e-03f, + -3.239769749237986739e-03f, + -3.225008115300036140e-03f, + -3.207015049490388476e-03f, + -3.185812005378460370e-03f, + -3.161423646667512952e-03f, + -3.133877819042292512e-03f, + -3.103205518841122348e-03f, + -3.069440858586877912e-03f, + -3.032621029414926759e-03f, + -2.992786260439455476e-03f, + -2.949979775101472298e-03f, + -2.904247744546611422e-03f, + -2.855639238081619617e-03f, + -2.804206170763586491e-03f, + -2.750003248176786843e-03f, + -2.693087908455917955e-03f, + -2.633520261617509212e-03f, + -2.571363026262532200e-03f, + -2.506681463717044551e-03f, + -2.439543309680427315e-03f, + -2.370018703451564571e-03f, + -2.298180114807654630e-03f, + -2.224102268611033526e-03f, + -2.147862067223294154e-03f, + -2.069538510805925442e-03f, + -1.989212615590480685e-03f, + -1.906967330203344566e-03f, + -1.822887450130181207e-03f, + -1.737059530408692877e-03f, + -1.649571796640214366e-03f, + -1.560514054410137245e-03f, + -1.469977597210741713e-03f, + -1.378055112961429048e-03f, + -1.284840589220490525e-03f, + -1.190429217186597059e-03f, + -1.094917294586464536e-03f, + -9.984021275502952091e-04f, + -9.009819315715012801e-04f, + -8.027557316540494606e-04f, + -7.038232617473004970e-04f, + -6.042848635718732616e-04f, + -5.042413849374186366e-04f, + -4.037940776560225800e-04f, + -3.030444951553179869e-04f, + -2.020943898931319878e-04f, + -1.010456106780149166e-04f, + 0.000000000000000000e+00f, + 1.009407085266458343e-04f, + 2.016749925046095251e-04f, + 3.021016427750876994e-04f, + 4.021198650188813296e-04f, + 5.016293808337416761e-04f, + 6.005305281877486908e-04f, + 6.987243611467527623e-04f, + 7.961127487778794053e-04f, + 8.925984731294979088e-04f, + 9.880853261891541211e-04f, + 1.082478205724416668e-03f, + 1.175683209910467547e-03f, + 1.267607730649530483e-03f, + 1.358160545491613001e-03f, + 1.447251908062810368e-03f, + 1.534793636914284342e-03f, + 1.620699202701525671e-03f, + 1.704883813609845864e-03f, + 1.787264498941020874e-03f, + 1.867760190778164960e-03f, + 1.946291803649916963e-03f, + 2.022782312115050697e-03f, + 2.097156826190940942e-03f, + 2.169342664553446445e-03f, + 2.239269425435684406e-03f, + 2.306869055157482768e-03f, + 2.372075914217887990e-03f, + 2.434826840887931946e-03f, + 2.495061212241576985e-03f, + 2.552721002565519828e-03f, + 2.607750839092839740e-03f, + 2.660098055006482071e-03f, + 2.709712739661699482e-03f, + 2.756547785980618080e-03f, + 2.800558934973623130e-03f, + 2.841704817345394509e-03f, + 2.879946992147500422e-03f, + 2.915249982440988770e-03f, + 2.947581307936787947e-03f, + 2.976911514583215936e-03f, + 3.003214201075224757e-03f, + 3.026466042260897698e-03f, + 3.046646809425394842e-03f, + 3.063739387434716906e-03f, + 3.077729788725812928e-03f, + 3.088607164131847160e-03f, + 3.096363810535085210e-03f, + 3.100995175343106407e-03f, + 3.102499857787075627e-03f, + 3.100879607044029155e-03f, + 3.096139317188489372e-03f, + 3.088287018981677665e-03f, + 3.077333868510032794e-03f, + 3.063294132687598148e-03f, + 3.046185171640329852e-03f, + 3.026027417993118994e-03f, + 3.002844353083898229e-03f, + 2.976662480131725321e-03f, + 2.947511294389127540e-03f, + 2.915423250312139825e-03f, + 2.880433725783904282e-03f, + 2.842580983431017543e-03f, + 2.801906129074849608e-03f, + 2.758453067362536676e-03f, + 2.712268454625132129e-03f, + 2.663401649013388741e-03f, + 2.611904657964648872e-03f, + 2.557832083055883686e-03f, + 2.501241062301404455e-03f, + 2.442191209956580140e-03f, + 2.380744553889864272e-03f, + 2.316965470589540683e-03f, + 2.250920617872494492e-03f, + 2.182678865366110329e-03f, + 2.112311222834577142e-03f, + 2.039890766424525773e-03f, + 1.965492562907071757e-03f, + 1.889193591993552652e-03f, + 1.811072666805763759e-03f, + 1.731210352583364151e-03f, + 1.649688883710983146e-03f, + 1.566592079150942642e-03f, + 1.482005256369143794e-03f, + 1.396015143841002710e-03f, + 1.308709792228250146e-03f, + 1.220178484316535592e-03f, + 1.130511643807194247e-03f, + 1.039800743054220596e-03f, + 9.481382098429354081e-04f, + 8.556173333027085976e-04f, + 7.623321690519257836e-04f, + 6.683774436695268453e-04f, + 5.738484585908526416e-04f, + 4.788409935259931006e-04f, + 3.834512094969080875e-04f, + 2.877755515921519335e-04f, + 1.919106515382334099e-04f, + 9.595323018441329955e-05f, + 2.961728936009675573e-17f, + -9.585243231666533902e-05f, + -1.915076630217971002e-04f, + -2.868695882022341873e-04f, + -3.818425002487855048e-04f, + -4.763311838281015891e-04f, + -5.702410112587507447e-04f, + -6.634780371952385403e-04f, + -7.559490925245654922e-04f, + -8.475618773830773632e-04f, + -9.382250532000561190e-04f, + -1.027848333675624067e-03f, + -1.116342574603918251e-03f, + -1.203619862451413194e-03f, + -1.289593601602254461e-03f, + -1.374178600184431222e-03f, + -1.457291154392131340e-03f, + -1.538849131220664879e-03f, + -1.618772049531532397e-03f, + -1.696981159369096662e-03f, + -1.773399519450076641e-03f, + -1.847952072749128047e-03f, + -1.920565720107696725e-03f, + -1.991169391792951045e-03f, + -2.059694116937665648e-03f, + -2.126073090792308593e-03f, + -2.190241739725098773e-03f, + -2.252137783906322643e-03f, + -2.311701297615694015e-03f, + -2.368874767115570264e-03f, + -2.423603146033716672e-03f, + -2.475833908202009024e-03f, + -2.525517097901476115e-03f, + -2.572605377465290739e-03f, + -2.617054072194128448e-03f, + -2.658821212542411203e-03f, + -2.697867573534989526e-03f, + -2.734156711378059063e-03f, + -2.767654997229715939e-03f, + -2.798331648100023990e-03f, + -2.826158754851514684e-03f, + -2.851111307275881745e-03f, + -2.873167216223860253e-03f, + -2.892307332769767248e-03f, + -2.908515464394205354e-03f, + -2.921778388171670463e-03f, + -2.932085860953250172e-03f, + -2.939430626537135362e-03f, + -2.943808419822793298e-03f, + -2.945217967948095782e-03f, + -2.943660988411156160e-03f, + -2.939142184182125771e-03f, + -2.931669235812944720e-03f, + -2.921252790556253757e-03f, + -2.907906448507473381e-03f, + -2.891646745787318507e-03f, + -2.872493134784635110e-03f, + -2.850467961482642393e-03f, + -2.825596439894601745e-03f, + -2.797906623637558873e-03f, + -2.767429374675792631e-03f, + -2.734198329268788634e-03f, + -2.698249861160541534e-03f, + -2.659623042050382122e-03f, + -2.618359599388156086e-03f, + -2.574503871538993439e-03f, + -2.528102760365492311e-03f, + -2.479205681277817097e-03f, + -2.427864510805224571e-03f, + -2.374133531743618380e-03f, + -2.318069375937653262e-03f, + -2.259730964756961977e-03f, + -2.199179447329721766e-03f, + -2.136478136597202548e-03f, + -2.071692443256429803e-03f, + -2.004889807660292528e-03f, + -1.936139629744864461e-03f, + -1.865513197057068430e-03f, + -1.793083610957797377e-03f, + -1.718925711075672356e-03f, + -1.643115998089900122e-03f, + -1.565732554922428339e-03f, + -1.486854966419205639e-03f, + -1.406564237604140694e-03f, + -1.324942710588779184e-03f, + -1.242073980223971008e-03f, + -1.158042808578502083e-03f, + -1.072935038332762650e-03f, + -9.868375051760999109e-04f, + -8.998379492968846009e-04f, + -8.120249260550908496e-04f, + -7.234877159284703501e-04f, + -6.343162338246114773e-04f, + -5.446009378495034713e-04f, + -4.544327376257831556e-04f, + -3.639029022542405989e-04f, + -2.731029680102384292e-04f, + -1.821246458690281339e-04f, + -9.105972895404852794e-05f, + 2.249668800172135414e-17f, + 9.096286107495146821e-05f, + 1.817373693953476012e-04f, + 2.722323270597744641e-04f, + 3.623569146858229449e-04f, + 4.520207824765948832e-04f, + 5.411341407166387263e-04f, + 6.296078496082298161e-04f, + 7.173535083574583433e-04f, + 8.042835434204669747e-04f, + 8.903112958232611450e-04f, + 9.753511074673767468e-04f, + 1.059318406334858621e-03f, + 1.142129790509272816e-03f, + 1.223703110928572564e-03f, + 1.303957552787602704e-03f, + 1.382813715509965393e-03f, + 1.460193691210495345e-03f, + 1.536021141570667560e-03f, + 1.610221373050487641e-03f, + 1.682721410364203859e-03f, + 1.753450068146556471e-03f, + 1.822338020740059362e-03f, + 1.889317870034044975e-03f, + 1.954324211290346669e-03f, + 2.017293696890905524e-03f, + 2.078165097944757213e-03f, + 2.136879363695696771e-03f, + 2.193379678672519300e-03f, + 2.247611517526280130e-03f, + 2.299522697502668928e-03f, + 2.349063428498731048e-03f, + 2.396186360655621055e-03f, + 2.440846629443004217e-03f, + 2.483001898191590853e-03f, + 2.522612398034211525e-03f, + 2.559640965217286051e-03f, + 2.594053075748732184e-03f, + 2.625816877349718484e-03f, + 2.654903218680989673e-03f, + 2.681285675817290850e-03f, + 2.704940575946320012e-03f, + 2.725847018271134597e-03f, + 2.743986892097757119e-03f, + 2.759344892093201339e-03f, + 2.771908530701254220e-03f, + 2.781668147706524256e-03f, + 2.788616916940388039e-03f, + 2.792750850124972248e-03f, + 2.794068797854331460e-03f, + 2.792572447715026187e-03f, + 2.788266319550961395e-03f, + 2.781157757880268772e-03f, + 2.771256921475067844e-03f, + 2.758576770117475430e-03f, + 2.743133048548284346e-03f, + 2.724944267627588904e-03f, + 2.704031682729127542e-03f, + 2.680419269393146536e-03f, + 2.654133696265428919e-03f, + 2.625204295352332774e-03f, + 2.593663029624824687e-03f, + 2.559544458007235838e-03f, + 2.522885697788194298e-03f, + 2.483726384495194266e-03f, + 2.442108629274998555e-03f, + 2.398076973826478078e-03f, + 2.351678342933034675e-03f, + 2.302961994645597293e-03f, + 2.251979468168421438e-03f, + 2.198784529503366135e-03f, + 2.143433114908959661e-03f, + 2.085983272233949380e-03f, + 2.026495100187157301e-03f, + 1.965030685606198105e-03f, + 1.901654038790769660e-03f, + 1.836431026968307709e-03f, + 1.769429305960019570e-03f, + 1.700718250118553624e-03f, + 1.630368880610306992e-03f, + 1.558453792115264015e-03f, + 1.485047078020867951e-03f, + 1.410224254186159386e-03f, + 1.334062181355563604e-03f, + 1.256638986300702377e-03f, + 1.178033981771610395e-03f, + 1.098327585339919834e-03f, + 1.017601237215742414e-03f, + 9.359373171227939204e-04f, + 8.534190603167809844e-04f, + 7.701304728322726310e-04f, + 6.861562460439943638e-04f, + 6.015816706295592760e-04f, + 5.164925500217144947e-04f, + 4.309751134365081789e-04f, + 3.451159285661133287e-04f, + 2.590018140253294793e-04f, + 1.727197516388577871e-04f, + 8.635679865857319275e-05f, + 0.000000000000000000e+00f, + -8.626369941502123060e-05f, + -1.723475421202091517e-04f, + -2.581650452840001070e-04f, + -3.436300875175078229e-04f, + -4.286569952255241947e-04f, + -5.131606284134141056e-04f, + -5.970564658633488713e-04f, + -6.802606895961190543e-04f, + -7.626902685335093437e-04f, + -8.442630412771376771e-04f, + -9.248977979226647274e-04f, + -1.004514360827295531e-03f, + -1.083033664249621842e-03f, + -1.160377832784585195e-03f, + -1.236470258513610188e-03f, + -1.311235676795854824e-03f, + -1.384600240623468786e-03f, + -1.456491593469362491e-03f, + -1.526838940554491693e-03f, + -1.595573118465392530e-03f, + -1.662626663052574382e-03f, + -1.727933875544430866e-03f, + -1.791430886811391570e-03f, + -1.853055719717038941e-03f, + -1.912748349496546643e-03f, + -1.970450762103117051e-03f, + -2.026107010465434590e-03f, + -2.079663268602624775e-03f, + -2.131067883544039959e-03f, + -2.180271425003505598e-03f, + -2.227226732761336536e-03f, + -2.271888961708070937e-03f, + -2.314215624507658369e-03f, + -2.354166631838931854e-03f, + -2.391704330178351379e-03f, + -2.426793537088085383e-03f, + -2.459401573976375491e-03f, + -2.489498296300512482e-03f, + -2.517056121184375189e-03f, + -2.542050052425464269e-03f, + -2.564457702869174776e-03f, + -2.584259314130737690e-03f, + -2.601437773647668344e-03f, + -2.615978629048301869e-03f, + -2.627870099825200655e-03f, + -2.637103086304351703e-03f, + -2.643671175903983435e-03f, + -2.647570646679886421e-03f, + -2.648800468156370640e-03f, + -2.647362299445082338e-03f, + -2.643260484656465709e-03f, + -2.636502045611470533e-03f, + -2.627096671863705067e-03f, + -2.615056708045107071e-03f, + -2.600397138550693873e-03f, + -2.583135569580662441e-03f, + -2.563292208561044304e-03f, + -2.540889840966167532e-03f, + -2.515953804569251093e-03f, + -2.488511961150026430e-03f, + -2.458594665690286458e-03f, + -2.426234733091499601e-03f, + -2.391467402450208560e-03f, + -2.354330298930778966e-03f, + -2.314863393275341449e-03f, + -2.273108958995205108e-03f, + -2.229111527288808303e-03f, + -2.182917839734724828e-03f, + -2.134576798809103074e-03f, + -2.084139416280047803e-03f, + -2.031658759533671622e-03f, + -1.977189895887380630e-03f, + -1.920789834949013144e-03f, + -1.862517469082529712e-03f, + -1.802433512041404706e-03f, + -1.740600435833956081e-03f, + -1.677082405886637763e-03f, + -1.611945214571482154e-03f, + -1.545256213167279678e-03f, + -1.477084242324090734e-03f, + -1.407499561103702770e-03f, + -1.336573774667974704e-03f, + -1.264379760689891439e-03f, + -1.190991594563459415e-03f, + -1.116484473487968287e-03f, + -1.040934639504879694e-03f, + -9.644193015667102938e-04f, + -8.870165567158059617e-04f, + -8.088053104554945427e-04f, + -7.298651963925226931e-04f, + -6.502764952346872223e-04f, + -5.701200532242376492e-04f, + -4.894772000905328905e-04f, + -4.084296666057908869e-04f, + -3.270595018261514210e-04f, + -2.454489901024086416e-04f, + -1.636805679449392656e-04f, + -8.183674082536929162e-05f, + -3.536521155687695770e-17f, + 8.174726056185484973e-05f, + 1.633228270606075061e-04f, + 2.446447484770642063e-04f, + 3.256314188286605011e-04f, + 4.062016589873803664e-04f, + 4.862747979789591962e-04f, + 5.657707536813316989e-04f, + 6.446101128410288350e-04f, + 7.227142103289445341e-04f, + 8.000052075557968854e-04f, + 8.764061699685609655e-04f, + 9.518411435521427575e-04f, + 1.026235230259113333e-03f, + 1.099514662293880982e-03f, + 1.171606875175669731e-03f, + 1.242440579510656730e-03f, + 1.311945831400333469e-03f, + 1.380054101417801157e-03f, + 1.446698342082995128e-03f, + 1.511813053771716119e-03f, + 1.575334348993146514e-03f, + 1.637200014972404940e-03f, + 1.697349574477985271e-03f, + 1.755724344834148822e-03f, + 1.812267495060354474e-03f, + 1.866924101083174007e-03f, + 1.919641198966668804e-03f, + 1.970367836109312640e-03f, + 2.019055120359112502e-03f, + 2.065656266998848294e-03f, + 2.110126643557067375e-03f, + 2.152423812401290867e-03f, + 2.192507571073842951e-03f, + 2.230339990331663483e-03f, + 2.265885449854030363e-03f, + 2.299110671585404518e-03f, + 2.329984750682085725e-03f, + 2.358479184033766222e-03f, + 2.384567896334751410e-03f, + 2.408227263680306953e-03f, + 2.429436134667956135e-03f, + 2.448175848984440826e-03f, + 2.464430253462965986e-03f, + 2.478185715597053772e-03f, + 2.489431134500083229e-03f, + 2.498157949302601787e-03f, + 2.504360144981462345e-03f, + 2.508034255617927130e-03f, + 2.509179365084111650e-03f, + 2.507797105160097621e-03f, + 2.503891651086268943e-03f, + 2.497469714558282327e-03f, + 2.488540534174480279e-03f, + 2.477115863348166615e-03f, + 2.463209955699809280e-03f, + 2.446839547946541571e-03f, + 2.428023840308957040e-03f, + 2.406784474457862241e-03f, + 2.383145509025629081e-03f, + 2.357133392709743602e-03f, + 2.328776934998069703e-03f, + 2.298107274548326535e-03f, + 2.265157845255661752e-03f, + 2.229964340045592890e-03f, + 2.192564672431069738e-03f, + 2.152998935874733330e-03f, + 2.111309361000000308e-03f, + 2.067540270696137036e-03f, + 2.021738033165410009e-03f, + 1.973951012961244755e-03f, + 1.924229520069206407e-03f, + 1.872625757084688284e-03f, + 1.819193764541884861e-03f, + 1.763989364451496421e-03f, + 1.707070102106509864e-03f, + 1.648495186215746637e-03f, + 1.588325427427724965e-03f, + 1.526623175309085347e-03f, + 1.463452253841756060e-03f, + 1.398877895506348739e-03f, + 1.332966674019096277e-03f, + 1.265786435792502209e-03f, + 1.197406230189095033e-03f, + 1.127896238640391496e-03f, + 1.057327702704293892e-03f, + 9.857728511335100193e-04f, + 9.133048260301522472e-04f, + 8.399976081621432457e-04f, + 7.659259415173617783e-04f, + 6.911652571721143201e-04f, + 6.157915965516007339e-04f, + 5.398815341610210556e-04f, + 4.635120998645952885e-04f, + 3.867607007918734689e-04f, + 3.097050429510698013e-04f, + 2.324230526274301040e-04f, + 1.549927976471593514e-04f, + 7.749240858556649941e-05f, + 0.000000000000000000e+00f, + -7.740640823447261787e-05f, + -1.546489694066701043e-04f, + -2.316500881890203695e-04f, + -3.083324985177912040e-04f, + -3.846193410553054690e-04f, + -4.604342401558712806e-04f, + -5.357013802596746321e-04f, + -6.103455816376617384e-04f, + -6.842923754112235652e-04f, + -7.574680777731551771e-04f, + -8.297998633349399841e-04f, + -9.012158375281924391e-04f, + -9.716451079872685803e-04f, + -1.041017854843918943e-03f, + -1.109265399862380090e-03f, + -1.176320274348555822e-03f, + -1.242116285764278049e-03f, + -1.306588582982534663e-03f, + -1.369673720118763302e-03f, + -1.431309718874978175e-03f, + -1.491436129336623072e-03f, + -1.549994089162047605e-03f, + -1.606926381106289162e-03f, + -1.662177488824047355e-03f, + -1.715693650896988340e-03f, + -1.767422913032514007e-03f, + -1.817315178384378135e-03f, + -1.865322255945725321e-03f, + -1.911397906968511154e-03f, + -1.955497889364013041e-03f, + -1.997580000042790960e-03f, + -2.037604115153256439e-03f, + -2.075532228180405718e-03f, + -2.111328485869323496e-03f, + -2.144959221939368461e-03f, + -2.176392988557203194e-03f, + -2.205600585540104519e-03f, + -2.232555087262260568e-03f, + -2.257231867239448825e-03f, + -2.279608620370068926e-03f, + -2.299665382812773017e-03f, + -2.317384549483214162e-03f, + -2.332750889154779940e-03f, + -2.345751557151114393e-03f, + -2.356376105620029086e-03f, + -2.364616491381328796e-03f, + -2.370467081343168980e-03f, + -2.373924655484415357e-03f, + -2.374988407402560224e-03f, + -2.373659942429402498e-03f, + -2.369943273319134042e-03f, + -2.363844813515844894e-03f, + -2.355373368009962363e-03f, + -2.344540121795531118e-03f, + -2.331358625942570734e-03f, + -2.315844781301389533e-03f, + -2.298016819857692100e-03f, + -2.277895283760072130e-03f, + -2.255503002043453362e-03f, + -2.230865065074793489e-03f, + -2.204008796749007838e-03f, + -2.174963724465795757e-03f, + -2.143761546920198904e-03f, + -2.110436099741713409e-03f, + -2.075023319018890790e-03f, + -2.037561202748555591e-03f, + -1.998089770251173809e-03f, + -1.956651019594995121e-03f, + -1.913288883074297899e-03f, + -1.868049180789196646e-03f, + -1.820979572375211594e-03f, + -1.772129506933642308e-03f, + -1.721550171215585189e-03f, + -1.669294436113043234e-03f, + -1.615416801513268677e-03f, + -1.559973339574200445e-03f, + -1.503021636479029855e-03f, + -1.444620732731039447e-03f, + -1.384831062049924873e-03f, + -1.323714388933566266e-03f, + -1.261333744948669490e-03f, + -1.197753363816366759e-03f, + -1.133038615360030133e-03f, + -1.067255938382161932e-03f, + -1.000472772539666867e-03f, + -9.327574892878164135e-04f, + -8.641793219624978621e-04f, + -7.948082950727303935e-04f, + -7.247151528757850725e-04f, + -6.539712873074342899e-04f, + -5.826486653404457788e-04f, + -5.108197558453200652e-04f, + -4.385574560281823480e-04f, + -3.659350175192179139e-04f, + -2.930259721875476224e-04f, + -2.199040577568145362e-04f, + -1.466431432977234172e-04f, + -7.331715467149604577e-05f, + -1.583863635030426600e-17f, + 7.323450476167464791e-05f, + 1.463127100768226222e-04f, + 2.191612068271459025e-04f, + 2.917068999868720029e-04f, + 3.638770818979462419e-04f, + 4.355995050724186771e-04f, + 5.068024544486168575e-04f, + 5.774148190301226381e-04f, + 6.473661628350382271e-04f, + 7.165867950855838104e-04f, + 7.850078395671508278e-04f, + 8.525613030890458839e-04f, + 9.191801429783286312e-04f, + 9.847983335396156852e-04f, + 1.049350931415344917e-03f, + 1.112774139782065014e-03f, + 1.175005371319211289e-03f, + 1.235983309887723515e-03f, + 1.295647970858855580e-03f, + 1.353940760033357088e-03f, + 1.410804531092786597e-03f, + 1.466183641527706851e-03f, + 1.520024006987588487e-03f, + 1.572273153999021768e-03f, + 1.622880271001914641e-03f, + 1.671796257653338251e-03f, + 1.718973772351856891e-03f, + 1.764367277935770294e-03f, + 1.807933085512109829e-03f, + 1.849629396373906774e-03f, + 1.889416341965344378e-03f, + 1.927256021857423661e-03f, + 1.963112539697747360e-03f, + 1.996952037100198536e-03f, + 2.028742725443338692e-03f, + 2.058454915547453749e-03f, + 2.086061045202587064e-03f, + 2.111535704522703519e-03f, + 2.134855659102633321e-03f, + 2.155999870956868715e-03f, + 2.174949517221738769e-03f, + 2.191688006604752131e-03f, + 2.206200993566935931e-03f, + 2.218476390226378162e-03f, + 2.228504375973802080e-03f, + 2.236277404792865950e-03f, + 2.241790210280533453e-03f, + 2.245039808364943448e-03f, + 2.246025497720799922e-03f, + 2.244748857884364644e-03f, + 2.241213745072582770e-03f, + 2.235426285713204824e-03f, + 2.227394867694926922e-03f, + 2.217130129349095119e-03f, + 2.204644946176507331e-03f, + 2.189954415335300473e-03f, + 2.173075837908174709e-03f, + 2.154028698969212043e-03f, + 2.132834645472967295e-03f, + 2.109517461990493593e-03f, + 2.084103044319416103e-03f, + 2.056619370996764975e-03f, + 2.027096472745798170e-03f, + 1.995566399890039318e-03f, + 1.962063187769620600e-03f, + 1.926622820196907150e-03f, + 1.889283190990552431e-03f, + 1.850084063629192947e-03f, + 1.809067029067121680e-03f, + 1.766275461756697642e-03f, + 1.721754473924256863e-03f, + 1.675550868146924400e-03f, + 1.627713088280349860e-03f, + 1.578291168789072458e-03f, + 1.527336682531643414e-03f, + 1.474902687055531115e-03f, + 1.421043669457084475e-03f, + 1.365815489864515746e-03f, + 1.309275323601538730e-03f, + 1.251481602091836709e-03f, + 1.192493952565831317e-03f, + 1.132373136630967277e-03f, + 1.071180987769143524e-03f, + 1.008980347826006095e-03f, + 9.458350025562797456e-04f, + 8.818096162916508503e-04f, + 8.169696657985963404e-04f, + 7.513813733923349223e-04f, + 6.851116393769219248e-04f, + 6.182279738784716289e-04f, + 5.507984281427341774e-04f, + 4.828915253653128263e-04f, + 4.145761911257870138e-04f, + 3.459216834955630552e-04f, + 2.769975228912344525e-04f, + 2.078734217432808354e-04f, + 1.386192140517258974e-04f, + 6.930478490043769405e-05f, + 3.850678557016620008e-17f, + -6.922536466905694359e-05f, + -1.383016930421246003e-04f, + -2.071595989147220697e-04f, + -2.757299955756169576e-04f, + -3.439441650576845872e-04f, + -4.117338269385969812e-04f, + -4.790312066215028815e-04f, + -5.457691030282071530e-04f, + -6.118809556363564821e-04f, + -6.773009107949520824e-04f, + -7.419638872516609194e-04f, + -8.058056408262444324e-04f, + -8.687628281669950792e-04f, + -9.307730695263674928e-04f, + -9.917750104935054486e-04f, + -1.051708382622899233e-03f, + -1.110514062899539038e-03f, + -1.168134131981801499e-03f, + -1.224511931164258289e-03f, + -1.279592118005431134e-03f, + -1.333320720565457380e-03f, + -1.385645190200188951e-03f, + -1.436514452861111955e-03f, + -1.485878958850318310e-03f, + -1.533690730982715860e-03f, + -1.579903411108077825e-03f, + -1.624472304948763358e-03f, + -1.667354425209425627e-03f, + -1.708508532916933748e-03f, + -1.747895176951601770e-03f, + -1.785476731731549735e-03f, + -1.821217433014094391e-03f, + -1.855083411780856367e-03f, + -1.887042726174312105e-03f, + -1.917065391455589646e-03f, + -1.945123407956183582e-03f, + -1.971190786997232842e-03f, + -1.995243574752887921e-03f, + -2.017259874035835007e-03f, + -2.037219863985523585e-03f, + -2.055105817641905350e-03f, + -2.070902117388888439e-03f, + -2.084595268254915961e-03f, + -2.096173909059424311e-03f, + -2.105628821396557989e-03f, + -2.112952936449467856e-03f, + -2.118141339630974854e-03f, + -2.121191273048350125e-03f, + -2.122102135792170319e-03f, + -2.120875482051600824e-03f, + -2.117515017060413347e-03f, + -2.112026590880362788e-03f, + -2.104418190030685459e-03f, + -2.094699926974599290e-03f, + -2.082884027475962168e-03f, + -2.068984815841183947e-03f, + -2.053018698063778860e-03f, + -2.035004142890892240e-03f, + -2.014961660833440929e-03f, + -1.992913781143200273e-03f, + -1.968885026782406667e-03f, + -1.942901887413728572e-03f, + -1.914992790439534482e-03f, + -1.885188070122604002e-03f, + -1.853519934820884200e-03f, + -1.820022432372197857e-03f, + -1.784731413665374862e-03f, + -1.747684494436782749e-03f, + -1.708921015333154415e-03f, + -1.668482000282380450e-03f, + -1.626410113216474832e-03f, + -1.582749613192508320e-03f, + -1.537546307957996655e-03f, + -1.490847506009852948e-03f, + -1.442701967196525136e-03f, + -1.393159851915445457e-03f, + -1.342272668957837298e-03f, + -1.290093222055339146e-03f, + -1.236675555184266412e-03f, + -1.182074896683267323e-03f, + -1.126347602242422363e-03f, + -1.069551096823031762e-03f, + -1.011743815566986619e-03f, + -9.529851437568570560e-04f, + -8.933353558887932458e-04f, + -8.328555539196910067e-04f, + -7.716076047526932357e-04f, + -7.096540770239413622e-04f, + -6.470581772568036877e-04f, + -5.838836854464510024e-04f, + -5.201948901420694023e-04f, + -4.560565230917139183e-04f, + -3.915336935171430800e-04f, + -3.266918220842130881e-04f, + -2.615965746362512961e-04f, + -1.963137957579778382e-04f, + -1.309094422360982627e-04f, + -6.544951648425400908e-05f, + 0.000000000000000000e+00f, + 6.537321308021720669e-05f, + 1.306043822607082607e-04f, + 1.956279867336831537e-04f, + 2.603787911287086792e-04f, + 3.247919108976276181e-04f, + 3.888028772701663366e-04f, + 4.523477017143444248e-04f, + 5.153629398383980818e-04f, + 5.777857546699370411e-04f, + 6.395539792487880222e-04f, + 7.006061784722651719e-04f, + 7.608817101308743870e-04f, + 8.203207850733748325e-04f, + 8.788645264429036270e-04f, + 9.364550279239102458e-04f, + 9.930354109440190161e-04f, + 1.048549880772794290e-03f, + 1.102943781463442676e-03f, + 1.156163649582898304e-03f, + 1.208157266677142242e-03f, + 1.258873710421226384e-03f, + 1.308263404403530459e-03f, + 1.356278166495282879e-03f, + 1.402871255759119157e-03f, + 1.447997417850374223e-03f, + 1.491612928867637770e-03f, + 1.533675637609531331e-03f, + 1.574145006197766577e-03f, + 1.612982149027046997e-03f, + 1.650149870004234296e-03f, + 1.685612698041884239e-03f, + 1.719336920772085442e-03f, + 1.751290616448417667e-03f, + 1.781443684006613678e-03f, + 1.809767871255424246e-03f, + 1.836236801171283600e-03f, + 1.860825996272981193e-03f, + 1.883512901053582605e-03f, + 1.904276902449677372e-03f, + 1.923099348328973467e-03f, + 1.939963563980765578e-03f, + 1.954854866594344254e-03f, + 1.967760577713456756e-03f, + 1.978670033656380715e-03f, + 1.987574593893788513e-03f, + 1.994467647378149553e-03f, + 1.999344616820692734e-03f, + 2.002202960914168783e-03f, + 2.003042174501439791e-03f, + 2.001863786692200525e-03f, + 1.998671356932133197e-03f, + 1.993470469030853877e-03f, + 1.986268723157068750e-03f, + 1.977075725811386266e-03f, + 1.965903077789286045e-03f, + 1.952764360148673750e-03f, + 1.937675118198656623e-03f, + 1.920652843527819766e-03f, + 1.901716954092479844e-03f, + 1.880888772387422731e-03f, + 1.858191501723117835e-03f, + 1.833650200635677813e-03f, + 1.807291755457605693e-03f, + 1.779144851079101806e-03f, + 1.749239939931425750e-03f, + 1.717609209225661468e-03f, + 1.684286546482327823e-03f, + 1.649307503388023569e-03f, + 1.612709258017795862e-03f, + 1.574530575463451180e-03f, + 1.534811766908859409e-03f, + 1.493594647195765511e-03f, + 1.450922490924287005e-03f, + 1.406839987134609086e-03f, + 1.361393192616601943e-03f, + 1.314629483896238502e-03f, + 1.266597507949261160e-03f, + 1.217347131692460890e-03f, + 1.166929390305300809e-03f, + 1.115396434435750447e-03f, + 1.062801476344078485e-03f, + 1.009198735040490926e-03f, + 9.546433804735578524e-04f, + 8.991914768259076738e-04f, + 8.428999249761178706e-04f, + 7.858264041852376820e-04f, + 7.280293130684387321e-04f, + 6.695677099108536621e-04f, + 6.105012523900892442e-04f, + 5.508901367652243143e-04f, + 4.907950365958332764e-04f, + 4.302770410520321762e-04f, + 3.693975928787344835e-04f, + 3.082184260775406768e-04f, + 2.468015033684312445e-04f, + 1.852089534950353614e-04f, + 1.235030084373483811e-04f, + 6.174594059430125743e-05f, + 2.096293806310516030e-17f, + -6.167264836248043244e-05f, + -1.232099870881719884e-04f, + -1.845502086537135426e-04f, + -2.456317774361367959e-04f, + -3.063934913834511463e-04f, + -3.667745432764744212e-04f, + -4.267145815201261821e-04f, + -4.861537704029955404e-04f, + -5.450328497660459227e-04f, + -6.032931940205293235e-04f, + -6.608768704559289274e-04f, + -7.177266967809564115e-04f, + -7.737862978399837359e-04f, + -8.290001614485750878e-04f, + -8.833136932931055871e-04f, + -9.366732708404333684e-04f, + -9.890262962043143858e-04f, + -1.040321247916032189e-03f, + -1.090507731549242732e-03f, + -1.139536529148920665e-03f, + -1.187359647415603143e-03f, + -1.233930364598734937e-03f, + -1.279203276052626528e-03f, + -1.323134338411260068e-03f, + -1.365680912338360217e-03f, + -1.406801803812153832e-03f, + -1.446457303904537337e-03f, + -1.484609227016050938e-03f, + -1.521220947530623618e-03f, + -1.556257434854668676e-03f, + -1.589685286806867721e-03f, + -1.621472761327541912e-03f, + -1.651589806477331930e-03f, + -1.680008088696766707e-03f, + -1.706701019300830170e-03f, + -1.731643779183499347e-03f, + -1.754813341709760346e-03f, + -1.776188493773842719e-03f, + -1.795749855005169008e-03f, + -1.813479895104255042e-03f, + -1.829362949293911016e-03f, + -1.843385231871876419e-03f, + -1.855534847853930556e-03f, + -1.865801802697809961e-03f, + -1.874178010100366288e-03f, + -1.880657297862605663e-03f, + -1.885235411818870100e-03f, + -1.887910017828480034e-03f, + -1.888680701830295272e-03f, + -1.887548967962307056e-03f, + -1.884518234750538193e-03f, + -1.879593829373407774e-03f, + -1.872782980009604853e-03f, + -1.864094806279484534e-03f, + -1.853540307791953041e-03f, + -1.841132350810590528e-03f, + -1.826885653054665781e-03f, + -1.810816766652771246e-03f, + -1.792944059268252940e-03f, + -1.773287693417722457e-03f, + -1.751869604005822220e-03f, + -1.728713474100759947e-03f, + -1.703844708977252705e-03f, + -1.677290408455194264e-03f, + -1.649079337563943938e-03f, + -1.619241895563655999e-03f, + -1.587810083356924057e-03f, + -1.554817469325785705e-03f, + -1.520299153629931172e-03f, + -1.484291731004316970e-03f, + -1.446833252095214512e-03f, + -1.407963183375834622e-03f, + -1.367722365683123140e-03f, + -1.326152971419345067e-03f, + -1.283298460463622734e-03f, + -1.239203534838731165e-03f, + -1.193914092180647360e-03f, + -1.147477178059556511e-03f, + -1.099940937201084957e-03f, + -1.051354563658511796e-03f, + -1.001768249987922176e-03f, + -9.512331354778615728e-04f, + -8.998012534875231673e-04f, + -8.475254779470752691e-04f, + -7.944594690758058310e-04f, + -7.406576183728511139e-04f, + -6.861749929372944591e-04f, + -6.310672791747117981e-04f, + -5.753907259474574801e-04f, + -5.192020872264638655e-04f, + -4.625585643030877768e-04f, + -4.055177476203069577e-04f, + -3.481375582814421167e-04f, + -2.904761892961940780e-04f, + -2.325920466240080111e-04f, + -1.745436900735062170e-04f, + -1.163897741181921285e-04f, + -5.818898868865390200e-05f, + -3.951477669352645278e-17f, + 5.811860852513058267e-05f, + 1.161083951789106388e-04f, + 1.739111186764226750e-04f, + 2.314687965911455317e-04f, + 2.887237634590489712e-04f, + 3.456187284925843007e-04f, + 4.020968328478077619e-04f, + 4.581017063869804681e-04f, + 5.135775238795969085e-04f, + 5.684690605867797827e-04f, + 6.227217471732920040e-04f, + 6.762817238922043568e-04f, + 7.290958939893588033e-04f, + 7.811119762742447376e-04f, + 8.322785568051721625e-04f, + 8.825451396379117895e-04f, + 9.318621965879654058e-04f, + 9.801812159573458638e-04f, + 1.027454750177579689e-03f, + 1.073636462323048543e-03f, + 1.118681171448473750e-03f, + 1.162544896706745696e-03f, + 1.205184900203477068e-03f, + 1.246559728547386213e-03f, + 1.286629253055807933e-03f, + 1.325354708576141497e-03f, + 1.362698730886437387e-03f, + 1.398625392638811350e-03f, + 1.433100237810905602e-03f, + 1.466090314633128333e-03f, + 1.497564206959974605e-03f, + 1.527492064055464794e-03f, + 1.555845628765160742e-03f, + 1.582598264047852974e-03f, + 1.607724977842486065e-03f, + 1.631202446246891868e-03f, + 1.653009034987472543e-03f, + 1.673124819160033650e-03f, + 1.691531601223876481e-03f, + 1.708212927233296189e-03f, + 1.723154101292263601e-03f, + 1.736342198219845579e-03f, + 1.747766074415657220e-03f, + 1.757416376916791541e-03f, + 1.765285550639219018e-03f, + 1.771367843798416159e-03f, + 1.775659311506234831e-03f, + 1.778157817542435270e-03f, + 1.778863034301330324e-03f, + 1.777776440915891046e-03f, + 1.774901319563383737e-03f, + 1.770242749958432374e-03f, + 1.763807602041371232e-03f, + 1.755604526871366649e-03f, + 1.745643945735682106e-03f, + 1.733938037488337493e-03f, + 1.720500724132964119e-03f, + 1.705347654666533944e-03f, + 1.688496187202536726e-03f, + 1.669965369393517111e-03f, + 1.649775917174820059e-03f, + 1.627950191853253523e-03f, + 1.604512175565338738e-03f, + 1.579487445132431861e-03f, + 1.552903144340421785e-03f, + 1.524787954674487571e-03f, + 1.495172064539795074e-03f, + 1.464087137001309370e-03f, + 1.431566276076835656e-03f, + 1.397643991619413597e-03f, + 1.362356162825694014e-03f, + 1.325740000408985944e-03f, + 1.287834007477042493e-03f, + 1.248677939155022100e-03f, + 1.208312760996174511e-03f, + 1.166780606223920529e-03f, + 1.124124731849302948e-03f, + 1.080389473709662384e-03f, + 1.035620200475557496e-03f, + 9.898632666728486313e-04f, + 9.431659647690965754e-04f, + 8.955764763732448116e-04f, + 8.471438225995464935e-04f, + 7.979178136459807611e-04f, + 7.479489976393288025e-04f, + 6.972886087997711303e-04f, + 6.459885149773112378e-04f, + 5.941011646141058575e-04f, + 5.416795331870154695e-04f, + 4.887770691848273815e-04f, + 4.354476396749826271e-04f, + 3.817454755153243395e-04f, + 3.277251162670002699e-04f, + 2.734413548635745875e-04f, + 2.189491820928326409e-04f, + 1.643037309479273775e-04f, + 1.095602209032437102e-04f, + 5.477390217168007973e-05f, + 0.000000000000000000e+00f, + -5.470634094252695156e-05f, + -1.092901120256077629e-04f, + -1.636964959141602542e-04f, + -2.178709215633056469e-04f, + -2.717591188977905368e-04f, + -3.253071731207118249e-04f, + -3.784615785968173970e-04f, + -4.311692922574608179e-04f, + -4.833777864735189634e-04f, + -5.350351013432206020e-04f, + -5.860898963437366797e-04f, + -6.364915012948296367e-04f, + -6.861899665835708047e-04f, + -7.351361126015605119e-04f, + -7.832815783443825139e-04f, + -8.305788691267564604e-04f, + -8.769814033650232248e-04f, + -9.224435583820854738e-04f, + -9.669207151891035966e-04f, + -1.010369302200565247e-03f, + -1.052746837839338510e-03f, + -1.094011971990893574e-03f, + -1.134124526265950332e-03f, + -1.173045533032109934e-03f, + -1.210737273177340265e-03f, + -1.247163312568430474e-03f, + -1.282288537169006893e-03f, + -1.316079186783988613e-03f, + -1.348502887397804448e-03f, + -1.379528682075299327e-03f, + -1.409127060396503806e-03f, + -1.437269986396952099e-03f, + -1.463930924987541645e-03f, + -1.489084866828790932e-03f, + -1.512708351636820334e-03f, + -1.534779489899245307e-03f, + -1.555277982980894256e-03f, + -1.574185141601471948e-03f, + -1.591483902668316052e-03f, + -1.607158844449279840e-03f, + -1.621196200072613954e-03f, + -1.633583869342330195e-03f, + -1.644311428859175465e-03f, + -1.653370140439019498e-03f, + -1.660752957822507871e-03f, + -1.666454531671149753e-03f, + -1.670471212846983723e-03f, + -1.672801053974688886e-03f, + -1.673443809286669515e-03f, + -1.672400932753375074e-03f, + -1.669675574502914881e-03f, + -1.665272575535695033e-03f, + -1.659198460741494619e-03f, + -1.651461430228174168e-03f, + -1.642071348972851856e-03f, + -1.631039734807969606e-03f, + -1.618379744756649665e-03f, + -1.604106159732930550e-03f, + -1.588235367624443381e-03f, + -1.570785344776701219e-03f, + -1.551775635899458553e-03f, + -1.531227332417528422e-03f, + -1.509163049289567434e-03f, + -1.485606900320671090e-03f, + -1.460584471994783983e-03f, + -1.434122795855729757e-03f, + -1.406250319466170913e-03f, + -1.376996875975918010e-03f, + -1.346393652331567652e-03f, + -1.314473156161391357e-03f, + -1.281269181370805988e-03f, + -1.246816772484174701e-03f, + -1.211152187770746713e-03f, + -1.174312861193657241e-03f, + -1.136337363221307049e-03f, + -1.097265360542288778e-03f, + -1.057137574726171045e-03f, + -1.015995739872469503e-03f, + -9.738825592923504131e-04f, + -9.308416612674603454e-04f, + -8.869175539322839185e-04f, + -8.421555793258690996e-04f, + -7.966018666606091347e-04f, + -7.503032848565528582e-04f, + -7.033073943892899100e-04f, + -6.556623985011526476e-04f, + -6.074170938261656567e-04f, + -5.586208204781806371e-04f, + -5.093234116545103949e-04f, + -4.595751428051017724e-04f, + -4.094266804203762987e-04f, + -3.589290304887579673e-04f, + -3.081334866766899275e-04f, + -2.570915782841462450e-04f, + -2.058550180275716367e-04f, + -1.544756497035134832e-04f, + -1.030053957862678347e-04f, + -5.149620501158499536e-05f, + -2.384103929205831118e-17f, + 5.143137502784089743e-05f, + 1.027462063910287337e-04f, + 1.538929628910742572e-04f, + 2.048203475057252935e-04f, + 2.554773487812054080e-04f, + 3.058132918724349066e-04f, + 3.557778891797814462e-04f, + 4.053212905313948854e-04f, + 4.543941328619231237e-04f, + 5.029475893377426772e-04f, + 5.509334178794880440e-04f, + 5.983040090345575221e-04f, + 6.450124331513995514e-04f, + 6.910124868096819382e-04f, + 7.362587384591508678e-04f, + 7.807065732238670707e-04f, + 8.243122368263766566e-04f, + 8.670328785894033810e-04f, + 9.088265934721979824e-04f, + 9.496524631011158801e-04f, + 9.894705957539746879e-04f, + 1.028242165258874252e-03f, + 1.065929448770301484e-03f, + 1.102495863385499807e-03f, + 1.137906001565360849e-03f, + 1.172125665326259570e-03f, + 1.205121899169577957e-03f, + 1.236863021717049538e-03f, + 1.267318656022278301e-03f, + 1.296459758529015880e-03f, + 1.324258646649080235e-03f, + 1.350689024933432675e-03f, + 1.375726009812287777e-03f, + 1.399346152880900310e-03f, + 1.421527462709165374e-03f, + 1.442249425155372978e-03f, + 1.461493022165247842e-03f, + 1.479240749039111274e-03f, + 1.495476630152138510e-03f, + 1.510186233113277763e-03f, + 1.523356681351052851e-03f, + 1.534976665115079944e-03f, + 1.545036450884612481e-03f, + 1.553527889176402723e-03f, + 1.560444420746071904e-03f, + 1.565781081178877019e-03f, + 1.569534503867175447e-03f, + 1.571702921373700117e-03f, + 1.572286165181262111e-03f, + 1.571285663831225405e-03f, + 1.568704439454675749e-03f, + 1.564547102701767346e-03f, + 1.558819846076479193e-03f, + 1.551530435685405255e-03f, + 1.542688201411057929e-03f, + 1.532304025521471613e-03f, + 1.520390329729599246e-03f, + 1.506961060717611732e-03f, + 1.492031674142519585e-03f, + 1.475619117141234709e-03f, + 1.457741809354577093e-03f, + 1.438419622491405236e-03f, + 1.417673858455001249e-03f, + 1.395527226055938864e-03f, + 1.372003816336560527e-03f, + 1.347129076533619364e-03f, + 1.320929782707246439e-03f, + 1.293434011065339607e-03f, + 1.264671108014265698e-03f, + 1.234671658967309224e-03f, + 1.203467455944029225e-03f, + 1.171091463995042447e-03f, + 1.137577786487074328e-03f, + 1.102961629284945943e-03f, + 1.067279263868331236e-03f, + 1.030567989421257843e-03f, + 9.928660939341588630e-04f, + 9.542128143592528474e-04f, + 9.146482958600143324e-04f, + 8.742135501974977914e-04f, + 8.329504132961628631e-04f, + 7.909015020336008844e-04f, + 7.481101702980445106e-04f, + 7.046204643591989737e-04f, + 6.604770775986386951e-04f, + 6.157253046455315841e-04f, + 5.704109949650640419e-04f, + 5.245805059471973005e-04f, + 4.782806555435268323e-04f, + 4.315586745004174507e-04f, + 3.844621582371941467e-04f, + 3.370390184187921768e-04f, + 2.893374342713311603e-04f, + 2.414058036903930554e-04f, + 1.932926941919554573e-04f, + 1.450467937548224429e-04f, + 9.671686160493662174e-05f, + 4.835167899075133784e-05f, + 0.000000000000000000e+00f, + -4.828949753345398863e-05f, + -9.646826098282474608e-05f, + -1.444879116922577944e-04f, + -1.923002935030318679e-04f, + -2.398575209931877504e-04f, + -2.871120273819045897e-04f, + -3.340166120515270496e-04f, + -3.805244876394365660e-04f, + -4.265893266524579085e-04f, + -4.721653075582231689e-04f, + -5.172071603070152717e-04f, + -5.616702112394265662e-04f, + -6.055104273346537417e-04f, + -6.486844597567101994e-04f, + -6.911496866543188596e-04f, + -7.328642551735467438e-04f, + -7.737871226406448826e-04f, + -8.138780968755867382e-04f, + -8.530978755963916508e-04f, + -8.914080848753665014e-04f, + -9.287713166103488344e-04f, + -9.651511649741133930e-04f, + -1.000512261806224762e-03f, + -1.034820310913592929e-03f, + -1.068042121246285314e-03f, + -1.100145638916268705e-03f, + -1.131099978028938862e-03f, + -1.160875450297352155e-03f, + -1.189443593411230841e-03f, + -1.216777198133303000e-03f, + -1.242850334097847032e-03f, + -1.267638374286776453e-03f, + -1.291118018160179043e-03f, + -1.313267313420094689e-03f, + -1.334065676387146760e-03f, + -1.353493910971104207e-03f, + -1.371534226218442407e-03f, + -1.388170252420803863e-03f, + -1.403387055769956442e-03f, + -1.417171151546464019e-03f, + -1.429510515830663278e-03f, + -1.440394595726007159e-03f, + -1.449814318086319878e-03f, + -1.457762096740287039e-03f, + -1.464231838207676094e-03f, + -1.469218945903567495e-03f, + -1.472720322828254208e-03f, + -1.474734372742105958e-03f, + -1.475260999826186192e-03f, + -1.474301606830856525e-03f, + -1.471859091716282196e-03f, + -1.467937842790105170e-03f, + -1.462543732349215952e-03f, + -1.455684108833884020e-03f, + -1.447367787504157772e-03f, + -1.437605039649846777e-03f, + -1.426407580346835237e-03f, + -1.413788554773978299e-03f, + -1.399762523106214953e-03f, + -1.384345444001102527e-03f, + -1.367554656697077568e-03f, + -1.349408861743359471e-03f, + -1.329928100382799265e-03f, + -1.309133732610135619e-03f, + -1.287048413929449148e-03f, + -1.263696070835965916e-03f, + -1.239101875048799527e-03f, + -1.213292216521904285e-03f, + -1.186294675262172631e-03f, + -1.158137991984896625e-03f, + -1.128852037637259912e-03f, + -1.098467781822281067e-03f, + -1.067017260156693896e-03f, + -1.034533540596639092e-03f, + -1.001050688766642752e-03f, + -9.666037323284525605e-04f, + -9.312286244263419952e-04f, + -8.949622062474039356e-04f, + -8.578421687353971186e-04f, + -8.199070134983350812e-04f, + -7.811960129497022435e-04f, + -7.417491697247534464e-04f, + -7.016071754140860680e-04f, + -6.608113686563731959e-04f, + -6.194036926336412294e-04f, + -5.774266520130750657e-04f, + -5.349232693788336665e-04f, + -4.919370411988257261e-04f, + -4.485118933715837031e-04f, + -4.046921363984502134e-04f, + -3.605224202266125153e-04f, + -3.160476888090664981e-04f, + -2.713131344280844096e-04f, + -2.263641518278198237e-04f, + -1.812462922031631745e-04f, + -1.360052170909635560e-04f, + -9.068665221087721649e-05f, + -4.533634130168751519e-05f, + -1.119205495635177410e-17f, + 4.527673019179228291e-05f, + 9.044832780293992876e-05f, + 1.354694371103048339e-04f, + 1.802949136270320799e-04f, + 2.248798693188531084e-04f, + 2.691797175024917524e-04f, + 3.131502173809525350e-04f, + 3.567475181720213820e-04f, + 3.999282027853717433e-04f, + 4.426493310053094079e-04f, + 4.848684821356317727e-04f, + 5.265437970650557525e-04f, + 5.676340197111919006e-04f, + 6.080985378017700815e-04f, + 6.478974229535403896e-04f, + 6.869914700090091119e-04f, + 7.253422355920121755e-04f, + 7.629120758449196762e-04f, + 7.996641833101642005e-04f, + 8.355626229197331365e-04f, + 8.705723670581514643e-04f, + 9.046593296642918905e-04f, + 9.377903993392572779e-04f, + 9.699334714277904395e-04f, + 1.001057479042750638e-03f, + 1.031132423002631329e-03f, + 1.060129400652862165e-03f, + 1.088020633543997301e-03f, + 1.114779493940055944e-03f, + 1.140380530131902001e-03f, + 1.164799490531472428e-03f, + 1.188013346524613607e-03f, + 1.210000314060736106e-03f, + 1.230739873959466437e-03f, + 1.250212790915166154e-03f, + 1.268401131182280697e-03f, + 1.285288278925214404e-03f, + 1.300858951217885064e-03f, + 1.315099211679921550e-03f, + 1.327996482737379275e-03f, + 1.339539556497333726e-03f, + 1.349718604227470977e-03f, + 1.358525184432789320e-03f, + 1.365952249523105658e-03f, + 1.371994151066654273e-03f, + 1.376646643626202498e-03f, + 1.379906887175804363e-03f, + 1.381773448097536276e-03f, + 1.382246298759191167e-03f, + 1.381326815675158054e-03f, + 1.379017776254279782e-03f, + 1.375323354139781646e-03f, + 1.370249113147892998e-03f, + 1.363801999813117269e-03f, + 1.355990334549495588e-03f, + 1.346823801438608650e-03f, + 1.336313436656531026e-03f, + 1.324471615553049963e-03f, + 1.311312038398147750e-03f, + 1.296849714811698206e-03f, + 1.281100946894079716e-03f, + 1.264083311076190895e-03f, + 1.245815638708950906e-03f, + 1.226317995413717370e-03f, + 1.205611659215808989e-03f, + 1.183719097484903357e-03f, + 1.160663942707366959e-03f, + 1.136470967116147033e-03f, + 1.111166056205482996e-03f, + 1.084776181158849176e-03f, + 1.057329370218964941e-03f, + 1.028854679030497465e-03f, + 9.993821599864546878e-04f, + 9.689428306109160735e-04f, + 9.375686410107936589e-04f, + 9.052924404308006949e-04f, + 8.721479429470286020e-04f, + 8.381696923342349089e-04f, + 8.033930261436254697e-04f, + 7.678540390285455838e-04f, + 7.315895453557641741e-04f, + 6.946370411414883386e-04f, + 6.570346653508382520e-04f, + 6.188211606008807691e-04f, + 5.800358333080047517e-04f, + 5.407185133199405181e-04f, + 5.009095130741225872e-04f, + 4.606495863245328032e-04f, + 4.199798864786004988e-04f, + 3.789419245869958758e-04f, + 3.375775270294791236e-04f, + 2.959287929392034368e-04f, + 2.540380514093228668e-04f, + 2.119478185249197815e-04f, + 1.697007542644115945e-04f, + 1.273396193133593797e-04f, + 8.490723183468631443e-05f, + 4.244642423929934338e-05f, + 2.489132717092975244e-17f, + -4.238930944730621606e-05f, + -8.467888767193799395e-05f, + -1.268262760429604032e-04f, + -1.687892163075062216e-04f, + -2.105256929093874817e-04f, + -2.519939750065616508e-04f, + -2.931526581448565673e-04f, + -3.339607055468352646e-04f, + -3.743774889740940815e-04f, + -4.143628291230573081e-04f, + -4.538770355138195783e-04f, + -4.928809458321817922e-04f, + -5.313359646865749471e-04f, + -5.692041017412580173e-04f, + -6.064480091878560880e-04f, + -6.430310185189792816e-04f, + -6.789171765674388570e-04f, + -7.140712807754315923e-04f, + -7.484589136597800171e-04f, + -7.820464764390349256e-04f, + -8.148012217900297898e-04f, + -8.466912857015470575e-04f, + -8.776857183947638259e-04f, + -9.077545142802680937e-04f, + -9.368686409224388084e-04f, + -9.650000669841776822e-04f, + -9.921217891239340544e-04f, + -1.018207857820698729e-03f, + -1.043233402101169816e-03f, + -1.067174653146455267e-03f, + -1.090008966755562705e-03f, + -1.111714844644859455e-03f, + -1.132271954563242268e-03f, + -1.151661149204728438e-03f, + -1.169864483900832875e-03f, + -1.186865233076385287e-03f, + -1.202647905454177829e-03f, + -1.217198257994649147e-03f, + -1.230503308558112416e-03f, + -1.242551347278776424e-03f, + -1.253331946640669171e-03f, + -1.262835970246984230e-03f, + -1.271055580275981447e-03f, + -1.277984243617538056e-03f, + -1.283616736686040089e-03f, + -1.287949148906458816e-03f, + -1.290978884872014988e-03f, + -1.292704665172990245e-03f, + -1.293126525897621585e-03f, + -1.292245816807471729e-03f, + -1.290065198190826342e-03f, + -1.286588636399150143e-03f, + -1.281821398072865732e-03f, + -1.275770043064026376e-03f, + -1.268442416064888972e-03f, + -1.259847636952461181e-03f, + -1.249996089860607850e-03f, + -1.238899410992382174e-03f, + -1.226570475186708736e-03f, + -1.213023381254520064e-03f, + -1.198273436100851744e-03f, + -1.182337137650689993e-03f, + -1.165232156597218035e-03f, + -1.146977316992536366e-03f, + -1.127592575702190524e-03f, + -1.107099000745486849e-03f, + -1.085518748545065719e-03f, + -1.062875040110370555e-03f, + -1.039192136180123365e-03f, + -1.014495311350580541e-03f, + -9.888108272168318318e-04f, + -9.621659045558878355e-04f, + -9.345886945805340160e-04f, + -9.061082492943768954e-04f, + -8.767544909794978232e-04f, + -8.465581808478967385e-04f, + -8.155508868906216624e-04f, + -7.837649509569552704e-04f, + -7.512334550985514227e-04f, + -7.179901872135618750e-04f, + -6.840696060258972568e-04f, + -6.495068054360894584e-04f, + -6.143374782808354653e-04f, + -5.785978795380620956e-04f, + -5.423247890156327302e-04f, + -5.055554735623122827e-04f, + -4.683276488392193763e-04f, + -4.306794406911591301e-04f, + -3.926493461576842912e-04f, + -3.542761941630523837e-04f, + -3.155991059257000266e-04f, + -2.766574551271435236e-04f, + -2.374908278813562743e-04f, + -1.981389825446179249e-04f, + -1.586418094068897395e-04f, + -1.190392903058594805e-04f, + -7.937145820385292140e-05f, + -3.967835676875259741e-05f, + 0.000000000000000000e+00f, + 3.962366806029014220e-05f, + 7.915281349029238485e-05f, + 1.185477524848153186e-04f, + 1.577689911456342596e-04f, + 1.967772650253714708e-04f, + 2.355335783858113143e-04f, + 2.739992431308870902e-04f, + 3.121359173761859267e-04f, + 3.499056436162521094e-04f, + 3.872708864514444720e-04f, + 4.241945698375216493e-04f, + 4.606401138207244462e-04f, + 4.965714707217308132e-04f, + 5.319531607333346764e-04f, + 5.667503068964558190e-04f, + 6.009286694197791883e-04f, + 6.344546793099163770e-04f, + 6.672954712786205531e-04f, + 6.994189158952225562e-04f, + 7.307936509524349481e-04f, + 7.613891120155314102e-04f, + 7.911755621249407519e-04f, + 8.201241206232327396e-04f, + 8.482067910791271214e-04f, + 8.753964882812977381e-04f, + 9.016670642761047145e-04f, + 9.269933334240764138e-04f, + 9.513510964518079316e-04f, + 9.747171634758099818e-04f, + 9.970693759769062425e-04f, + 1.018386627704094679e-03f, + 1.038648884488686591e-03f, + 1.057837202950029669e-03f, + 1.075933748075338925e-03f, + 1.092921809657792587e-03f, + 1.108785817577722472e-03f, + 1.123511355912956439e-03f, + 1.137085175865973829e-03f, + 1.149495207496349907e-03f, + 1.160730570248186353e-03f, + 1.170781582263828594e-03f, + 1.179639768475975034e-03f, + 1.187297867471814568e-03f, + 1.193749837123847697e-03f, + 1.198990858983596747e-03f, + 1.203017341435374133e-03f, + 1.205826921608644554e-03f, + 1.207418466048858175e-03f, + 1.207792070147742499e-03f, + 1.206949056335355347e-03f, + 1.204891971037466616e-03f, + 1.201624580403049501e-03f, + 1.197151864807891562e-03f, + 1.191480012141583498e-03f, + 1.184616409886339811e-03f, + 1.176569635997314197e-03f, + 1.167349448595342331e-03f, + 1.156966774484061893e-03f, + 1.145433696504678973e-03f, + 1.132763439742820021e-03f, + 1.118970356602857433e-03f, + 1.104069910766385543e-03f, + 1.088078660052710107e-03f, + 1.071014238199964868e-03f, + 1.052895335586819490e-03f, + 1.033741678915853354e-03f, + 1.013574009880266035e-03f, + 9.924140628370767443e-04f, + 9.702845415105564161e-04f, + 9.472090947510056159e-04f, + 9.232122913743140771e-04f, + 8.983195941091211278e-04f, + 8.725573326793036348e-04f, + 8.459526760497619287e-04f, + 8.185336038648948062e-04f, + 7.903288771097757327e-04f, + 7.613680080244982808e-04f, + 7.316812293033188221e-04f, + 7.012994626104158578e-04f, + 6.702542864450650520e-04f, + 6.385779033898540073e-04f, + 6.063031067753177393e-04f, + 5.734632467957093789e-04f, + 5.400921961110872679e-04f, + 5.062243149706446149e-04f, + 4.718944158933642270e-04f, + 4.371377279425392405e-04f, + 4.019898606301749847e-04f, + 3.664867674887073131e-04f, + 3.306647093468514844e-04f, + 2.945602173475719322e-04f, + 2.582100557452125193e-04f, + 2.216511845199241977e-04f, + 1.849207218476427064e-04f, + 1.480559064630949787e-04f, + 1.110940599542368509e-04f, + 7.407254902655125068e-05f, + 3.702874777472067589e-05f, + 1.371254292486084993e-17f, + -3.697641838836769948e-05f, + -7.386333685080383616e-05f, + -1.106237275354719183e-04f, + -1.472207424002393370e-04f, + -1.836177501005376326e-04f, + -2.197783726069668013e-04f, + -2.556665215157765151e-04f, + -2.912464340157351313e-04f, + -3.264827084761888032e-04f, + -3.613403396206332991e-04f, + -3.957847532506383946e-04f, + -4.297818404862966193e-04f, + -4.632979914890506846e-04f, + -4.963001286333401738e-04f, + -5.287557390949833508e-04f, + -5.606329068237270391e-04f, + -5.919003438689767176e-04f, + -6.225274210275311962e-04f, + -6.524841977839308848e-04f, + -6.817414515139428016e-04f, + -7.102707059225399746e-04f, + -7.380442586892487162e-04f, + -7.650352082938549928e-04f, + -7.912174799963587243e-04f, + -8.165658509465838124e-04f, + -8.410559743992581695e-04f, + -8.646644030108421603e-04f, + -8.873686111969257854e-04f, + -9.091470165279773525e-04f, + -9.299790001438900484e-04f, + -9.498449261678874270e-04f, + -9.687261601014614341e-04f, + -9.866050861835819630e-04f, + -1.003465123697943424e-03f, + -1.019290742213164363e-03f, + -1.034067475742384131e-03f, + -1.047781935809330650e-03f, + -1.060421823409143580e-03f, + -1.071975939853697006e-03f, + -1.082434196491879799e-03f, + -1.091787623296736802e-03f, + -1.100028376312290647e-03f, + -1.107149743954318269e-03f, + -1.113146152160276754e-03f, + -1.118013168384754657e-03f, + -1.121747504438212967e-03f, + -1.124347018167691677e-03f, + -1.125810713979439898e-03f, + -1.126138742204658245e-03f, + -1.125332397310586279e-03f, + -1.123394114960401657e-03f, + -1.120327467926549893e-03f, + -1.116137160863255560e-03f, + -1.110829023945101137e-03f, + -1.104410005379749494e-03f, + -1.096888162803940974e-03f, + -1.088272653573009452e-03f, + -1.078573723955405161e-03f, + -1.067802697244547546e-03f, + -1.055971960801616169e-03f, + -1.043094952043956310e-03f, + -1.029186143394582309e-03f, + -1.014261026209532400e-03f, + -9.983360937008427163e-04f, + -9.814288228736027086e-04f, + -9.635576554969104172e-04f, + -9.447419781291415113e-04f, + -9.250021012192831361e-04f, + -9.043592373064512696e-04f, + -8.828354783409939847e-04f, + -8.604537721515002468e-04f, + -8.372378980823497055e-04f, + -8.132124418277322840e-04f, + -7.884027694888517653e-04f, + -7.628350008812852896e-04f, + -7.365359821204960078e-04f, + -7.095332575148247155e-04f, + -6.818550407942288718e-04f, + -6.535301857058335630e-04f, + -6.245881560060952261e-04f, + -5.950589948810114296e-04f, + -5.649732938262623386e-04f, + -5.343621610190059943e-04f, + -5.032571892141756960e-04f, + -4.716904231986256981e-04f, + -4.396943268360438742e-04f, + -4.073017497369382724e-04f, + -3.745458935874993508e-04f, + -3.414602781722681792e-04f, + -3.080787071247825435e-04f, + -2.744352334413967037e-04f, + -2.405641247936734649e-04f, + -2.064998286741144789e-04f, + -1.722769374108738480e-04f, + -1.379301530872341895e-04f, + -1.034942524008109811e-04f, + -6.900405149830530008e-05f, + -3.449437082158992495e-05f, + 0.000000000000000000e+00f, + 3.444433717537312282e-05f, + 6.880401766040344078e-05f, + 1.030445539143494854e-04f, + 1.371316284694892038e-04f, + 1.710311282792226217e-04f, + 2.047091788099896501e-04f, + 2.381321778435391604e-04f, + 2.712668289555900309e-04f, + 3.040801746373052975e-04f, + 3.365396290272290244e-04f, + 3.686130102209533182e-04f, + 4.002685721262641268e-04f, + 4.314750358328316138e-04f, + 4.622016204652085376e-04f, + 4.924180734885345943e-04f, + 5.220947004376862242e-04f, + 5.512023940402758712e-04f, + 5.797126627053133911e-04f, + 6.075976583493116747e-04f, + 6.348302035331886400e-04f, + 6.613838178833868642e-04f, + 6.872327437713459134e-04f, + 7.123519712269649109e-04f, + 7.367172620617903596e-04f, + 7.603051731785161974e-04f, + 7.830930790451201724e-04f, + 8.050591933112499331e-04f, + 8.261825895472138482e-04f, + 8.464432210854224304e-04f, + 8.658219399455064280e-04f, + 8.843005148257124162e-04f, + 9.018616481435636715e-04f, + 9.184889921098693746e-04f, + 9.341671638215605540e-04f, + 9.488817593593959444e-04f, + 9.626193668776509334e-04f, + 9.753675786743276274e-04f, + 9.871150022309649764e-04f, + 9.978512702125698873e-04f, + 1.007567049418917103e-03f, + 1.016254048679934505e-03f, + 1.023905025688631211e-03f, + 1.030513792766163958e-03f, + 1.036075221554958858e-03f, + 1.040585246636590612e-03f, + 1.044040868072351400e-03f, + 1.046440152865581131e-03f, + 1.047782235345830204e-03f, + 1.048067316476006608e-03f, + 1.047296662084868128e-03f, + 1.045472600028134798e-03f, + 1.042598516282698499e-03f, + 1.038678849979428548e-03f, + 1.033719087381135097e-03f, + 1.027725754813292765e-03f, + 1.020706410556256006e-03f, + 1.012669635708591783e-03f, + 1.003625024032280683e-03f, + 9.935831707915917296e-04f, + 9.825556605982765750e-04f, + 9.705550542768091827e-04f, + 9.575948747645024592e-04f, + 9.436895920619294822e-04f, + 9.288546072504160834e-04f, + 9.131062355939434513e-04f, + 8.964616887440624146e-04f, + 8.789390560668727381e-04f, + 8.605572851122642768e-04f, + 8.413361612465680012e-04f, + 8.212962864701133696e-04f, + 8.004590574423870028e-04f, + 7.788466427383010891e-04f, + 7.564819593593443900e-04f, + 7.333886485245473975e-04f, + 7.095910507669888961e-04f, + 6.851141803613563976e-04f, + 6.599836991102931479e-04f, + 6.342258895159663982e-04f, + 6.078676273653686388e-04f, + 5.809363537579391706e-04f, + 5.534600466042048465e-04f, + 5.254671916251264134e-04f, + 4.969867528824211626e-04f, + 4.680481428698100464e-04f, + 4.386811921962611408e-04f, + 4.089161188926386807e-04f, + 3.787834973728029320e-04f, + 3.483142270813974271e-04f, + 3.175395008601156806e-04f, + 2.864907730651890965e-04f, + 2.551997274681527816e-04f, + 2.236982449728073510e-04f, + 1.920183711814943037e-04f, + 1.601922838431261954e-04f, + 1.282522602162407851e-04f, + 9.623064438038904595e-05f, + 6.415981452841493812e-05f, + 3.207215027289962711e-05f, + 0.000000000000000000e+00f, + -3.202435169696419165e-05f, + -6.396871647107672993e-05f, + -9.580103453013783627e-05f, + -1.274894067670554485e-04f, + -1.590021266806003833e-04f, + -1.903077120544014096e-04f, + -2.213749363623242509e-04f, + -2.521728598694509757e-04f, + -2.826708603974881218e-04f, + -3.128386637238008165e-04f, + -3.426463735844534645e-04f, + -3.720645012513128301e-04f, + -4.010639946537739552e-04f, + -4.296162670168992745e-04f, + -4.576932249873889727e-04f, + -4.852672962200506594e-04f, + -5.123114563973639067e-04f, + -5.387992556561681809e-04f, + -5.647048443954880668e-04f, + -5.900029984401524482e-04f, + -6.146691435362195647e-04f, + -6.386793791542513593e-04f, + -6.620105015772862009e-04f, + -6.846400262516423845e-04f, + -7.065462093789202968e-04f, + -7.277080687284316705e-04f, + -7.481054036504530087e-04f, + -7.677188142710961042e-04f, + -7.865297198508461448e-04f, + -8.045203762893993540e-04f, + -8.216738927602709611e-04f, + -8.379742474599812278e-04f, + -8.534063024570928127e-04f, + -8.679558176273523317e-04f, + -8.816094636625075804e-04f, + -8.943548341408386320e-04f, + -9.061804566487988806e-04f, + -9.170758029437478922e-04f, + -9.270312981492120604e-04f, + -9.360383289747114437e-04f, + -9.440892509532578013e-04f, + -9.511773946908641834e-04f, + -9.572970711231403289e-04f, + -9.624435757751192066e-04f, + -9.666131920216366113e-04f, + -9.698031933463969285e-04f, + -9.720118445989208052e-04f, + -9.732384022497203710e-04f, + -9.734831136448424821e-04f, + -9.727472152621121065e-04f, + -9.710329299722829204e-04f, + -9.683434633094111085e-04f, + -9.646829987556522013e-04f, + -9.600566920467877531e-04f, + -9.544706645056394391e-04f, + -9.479319954115860043e-04f, + -9.404487134153821952e-04f, + -9.320297870093062660e-04f, + -9.226851140636999115e-04f, + -9.124255104419481694e-04f, + -9.012626977066420320e-04f, + -8.892092899308199835e-04f, + -8.762787796288336881e-04f, + -8.624855228225505183e-04f, + -8.478447232590492723e-04f, + -8.323724157971091513e-04f, + -8.160854489806475048e-04f, + -7.990014668176755822e-04f, + -7.811388897844821115e-04f, + -7.625168950755145496e-04f, + -7.431553961197853112e-04f, + -7.230750213856750215e-04f, + -7.022970924967909898e-04f, + -6.808436016816696431e-04f, + -6.587371885813887371e-04f, + -6.360011164391399848e-04f, + -6.126592476972289288e-04f, + -5.887360190265250072e-04f, + -5.642564158146420091e-04f, + -5.392459461393457349e-04f, + -5.137306142544784474e-04f, + -4.877368936155090711e-04f, + -4.612916994728182745e-04f, + -4.344223610612315406e-04f, + -4.071565934140700962e-04f, + -3.795224688310699706e-04f, + -3.515483880292340994e-04f, + -3.232630510065746267e-04f, + -2.946954276481456654e-04f, + -2.658747281046207941e-04f, + -2.368303729738942764e-04f, + -2.075919633156370829e-04f, + -1.781892505295539549e-04f, + -1.486521061281701210e-04f, + -1.190104914343625921e-04f, + -8.929442723454692366e-05f, + -5.953396341846094902e-05f, + -2.975914863569874771e-05f, + -1.469383061752921166e-17f, + 2.971352712842046073e-05f, + 5.935156925200977569e-05f, + 8.888438470625297655e-05f, + 1.182823834615285115e-04f, + 1.475161567260801273e-04f, + 1.765565063211114430e-04f, + 2.053744737984555227e-04f, + 2.339413692715925134e-04f, + 2.622287999318306112e-04f, + 2.902086982211098056e-04f, + 3.178533496333097114e-04f, + 3.451354201170366942e-04f, + 3.720279830524620595e-04f, + 3.985045457759202716e-04f, + 4.245390756258103919e-04f, + 4.501060254847104552e-04f, + 4.751803587924769172e-04f, + 4.997375740056823846e-04f, + 5.237537284800026236e-04f, + 5.472054617520811680e-04f, + 5.700700181981503386e-04f, + 5.923252690478518056e-04f, + 6.139497337318547063e-04f, + 6.349226005425641405e-04f, + 6.552237465884745531e-04f, + 6.748337570230266303e-04f, + 6.937339435292449487e-04f, + 7.119063620434466517e-04f, + 7.293338297005069531e-04f, + 7.459999409853247188e-04f, + 7.618890830752056463e-04f, + 7.769864503587980151e-04f, + 7.912780581184908910e-04f, + 8.047507553635035353e-04f, + 8.173922368022044829e-04f, + 8.291910539426864280e-04f, + 8.401366253119868770e-04f, + 8.502192457848813112e-04f, + 8.594300950141066115e-04f, + 8.677612449551008961e-04f, + 8.752056664789573028e-04f, + 8.817572350682475763e-04f, + 8.874107355915474612e-04f, + 8.921618661531745048e-04f, + 8.960072410156486164e-04f, + 8.989443925934634261e-04f, + 9.009717725175072972e-04f, + 9.020887517705425190e-04f, + 9.022956198950072941e-04f, + 9.015935832754222229e-04f, + 8.999847624985231375e-04f, + 8.974721887952514209e-04f, + 8.940597995695863213e-04f, + 8.897524330201562462e-04f, + 8.845558218614805405e-04f, + 8.784765861525543331e-04f, + 8.715222252413793759e-04f, + 8.637011088350353069e-04f, + 8.550224672055297846e-04f, + 8.454963805427627172e-04f, + 8.351337674665857812e-04f, + 8.239463727109863026e-04f, + 8.119467539939648334e-04f, + 7.991482680876762579e-04f, + 7.855650561042518912e-04f, + 7.712120280131833138e-04f, + 7.561048464071653402e-04f, + 7.402599095340949053e-04f, + 7.236943336132475825e-04f, + 7.064259344547092496e-04f, + 6.884732084018442772e-04f, + 6.698553126167958562e-04f, + 6.505920447301977031e-04f, + 6.307038218764186291e-04f, + 6.102116591367832835e-04f, + 5.891371474128742191e-04f, + 5.675024307539662440e-04f, + 5.453301831613886286e-04f, + 5.226435848948802945e-04f, + 4.994662983050689653e-04f, + 4.758224432173879066e-04f, + 4.517365718931811943e-04f, + 4.272336435935402852e-04f, + 4.023389987724907877e-04f, + 3.770783329259057943e-04f, + 3.514776701234272852e-04f, + 3.255633362501970246e-04f, + 2.993619319860350001e-04f, + 2.729003055499868075e-04f, + 2.462055252376792419e-04f, + 2.193048517797492180e-04f, + 1.922257105497324930e-04f, + 1.649956636492767566e-04f, + 1.376423818992599316e-04f, + 1.101936167654500256e-04f, + 8.267717224668583544e-05f, + 5.512087675440251894e-05f, + 2.755255501160192006e-05f, + 0.000000000000000000e+00f, + -2.750905501689023422e-05f, + -5.494696436636345655e-05f, + -8.228619770668268139e-05f, + -1.094993676073878112e-04f, + -1.365592569419782647e-04f, + -1.634388460653853027e-04f, + -1.901113397495802181e-04f, + -2.165501938502928923e-04f, + -2.427291416781312899e-04f, + -2.686222200484022333e-04f, + -2.942037949834695591e-04f, + -3.194485870425304262e-04f, + -3.443316962534629451e-04f, + -3.688286266226424733e-04f, + -3.929153101984506676e-04f, + -4.165681306646761548e-04f, + -4.397639464411628790e-04f, + -4.624801132689337598e-04f, + -4.846945062576402791e-04f, + -5.063855413743057745e-04f, + -5.275321963523644251e-04f, + -5.481140310006175909e-04f, + -5.681112068929672181e-04f, + -5.875045064196726674e-04f, + -6.062753511821435647e-04f, + -6.244058197136283239e-04f, + -6.418786645088341578e-04f, + -6.586773283467862658e-04f, + -6.747859598912580702e-04f, + -6.901894285541135439e-04f, + -7.048733386080151741e-04f, + -7.188240425351924510e-04f, + -7.320286536001779053e-04f, + -7.444750576348447895e-04f, + -7.561519240253451084e-04f, + -7.670487158910010940e-04f, + -7.771556994460668971e-04f, + -7.864639525364079805e-04f, + -7.949653723436894259e-04f, + -8.026526822505372595e-04f, + -8.095194378612496173e-04f, + -8.155600321732297967e-04f, + -8.207696998952141061e-04f, + -8.251445209094316778e-04f, + -8.286814228754654961e-04f, + -8.313781829745840735e-04f, + -8.332334287941438105e-04f, + -8.342466383525489566e-04f, + -8.344181392661235552e-04f, + -8.337491070600727781e-04f, + -8.322415626266423810e-04f, + -8.298983688343719274e-04f, + -8.267232262932451212e-04f, + -8.227206682813439833e-04f, + -8.178960548394521293e-04f, + -8.122555660409656268e-04f, + -8.058061944451279162e-04f, + -7.985557367425892995e-04f, + -7.905127846029615362e-04f, + -7.816867147349541335e-04f, + -7.720876781703026525e-04f, + -7.617265887835813565e-04f, + -7.506151110607858345e-04f, + -7.387656471301075898e-04f, + -7.261913230692261566e-04f, + -7.129059745042091046e-04f, + -6.989241315155087344e-04f, + -6.842610028674840552e-04f, + -6.689324595785751861e-04f, + -6.529550178495424672e-04f, + -6.363458213682250285e-04f, + -6.191226230095402778e-04f, + -6.013037659503773147e-04f, + -5.829081642191303019e-04f, + -5.639552827005720349e-04f, + -5.444651166170623056e-04f, + -5.244581705078699748e-04f, + -5.039554367282136470e-04f, + -4.829783734907900630e-04f, + -4.615488824727865158e-04f, + -4.396892860113637874e-04f, + -4.174223039115742672e-04f, + -3.947710298905243330e-04f, + -3.717589076824774933e-04f, + -3.484097068291740662e-04f, + -3.247474981805008798e-04f, + -3.007966291308984577e-04f, + -2.765816986165605708e-04f, + -2.521275318992345573e-04f, + -2.274591551626225019e-04f, + -2.026017699469456171e-04f, + -1.775807274479320418e-04f, + -1.524215027065971577e-04f, + -1.271496687156270196e-04f, + -1.017908704690000349e-04f, + -7.637079898086366356e-05f, + -5.091516530030798363e-05f, + -2.544967454785041741e-05f, + 0.000000000000000000e+00f, + 2.540824275175630965e-05f, + 5.074952154213560791e-05f, + 7.599841324713188062e-05f, + 1.011296292473662763e-04f, + 1.261180407145145923e-04f, + 1.509387036954135824e-04f, + 1.755668839686425260e-04f, + 1.999780816492812915e-04f, + 2.241480555170535154e-04f, + 2.480528470440098191e-04f, + 2.716688040976286797e-04f, + 2.949726042963528197e-04f, + 3.179412779943405166e-04f, + 3.405522308726428231e-04f, + 3.627832661150276234e-04f, + 3.846126061465318354e-04f, + 4.060189139133383055e-04f, + 4.269813136835948837e-04f, + 4.474794113487838955e-04f, + 4.674933142057642490e-04f, + 4.870036502007597822e-04f, + 5.059915866164069404e-04f, + 5.244388481841380598e-04f, + 5.423277346042669565e-04f, + 5.596411374573758216e-04f, + 5.763625564908231172e-04f, + 5.924761152646927393e-04f, + 6.079665761428002836e-04f, + 6.228193546145188893e-04f, + 6.370205329341033923e-04f, + 6.505568730647005556e-04f, + 6.634158289153857567e-04f, + 6.755855578598123036e-04f, + 6.870549315261518814e-04f, + 6.978135458484613016e-04f, + 7.078517303707442540e-04f, + 7.171605567954273622e-04f, + 7.257318467687813622e-04f, + 7.335581788968564615e-04f, + 7.406328949860011826e-04f, + 7.469501055028914937e-04f, + 7.525046942499604482e-04f, + 7.572923222527377452e-04f, + 7.613094308564032336e-04f, + 7.645532440298472834e-04f, + 7.670217698761347402e-04f, + 7.687138013491711264e-04f, + 7.696289161771383436e-04f, + 7.697674759941319994e-04f, + 7.691306246821071795e-04f, + 7.677202859261749368e-04f, + 7.655391599869575776e-04f, + 7.625907196945825228e-04f, + 7.588792056696464167e-04f, + 7.544096207772237267e-04f, + 7.491877238207874951e-04f, + 7.432200224837051672e-04f, + 7.365137655266115572e-04f, + 7.290769342498153649e-04f, + 7.209182332305319723e-04f, + 7.120470803455674876e-04f, + 7.024735960906073294e-04f, + 6.922085922080986782e-04f, + 6.812635596364262705e-04f, + 6.696506557935362697e-04f, + 6.573826912090139371e-04f, + 6.444731155192746008e-04f, + 6.309360028408991924e-04f, + 6.167860365379857716e-04f, + 6.020384934000156665e-04f, + 5.867092272469688922e-04f, + 5.708146519793728339e-04f, + 5.543717240911742901e-04f, + 5.373979246641968867e-04f, + 5.199112408629773122e-04f, + 5.019301469495465393e-04f, + 4.834735848383831772e-04f, + 4.645609442115968056e-04f, + 4.452120422152791297e-04f, + 4.254471027583006421e-04f, + 4.052867354349356968e-04f, + 3.847519140935204570e-04f, + 3.638639550730222647e-04f, + 3.426444951302156034e-04f, + 3.211154690804265380e-04f, + 2.992990871745817845e-04f, + 2.772178122359930490e-04f, + 2.548943365805551777e-04f, + 2.323515587436648325e-04f, + 2.096125600378590220e-04f, + 1.867005809653108641e-04f, + 1.636389975088607706e-04f, + 1.404512973260482907e-04f, + 1.171610558701005774e-04f, + 9.379191246244331451e-05f, + 7.036754634058427660e-05f, + 4.691165270578145734e-05f, + 2.344791879487271815e-05f, + 1.447139493247874122e-17f, + -2.340850393945113271e-05f, + -4.675407264888852574e-05f, + -7.001328871061514335e-05f, + -9.316286111268942802e-05f, + -1.161796485306134486e-04f, + -1.390406824191185795e-04f, + -1.617231898906969537e-04f, + -1.842046163583829115e-04f, + -2.064626479199869254e-04f, + -2.284752334619991466e-04f, + -2.502206064611250252e-04f, + -2.716773064617690556e-04f, + -2.928242002086798895e-04f, + -3.136405024138114671e-04f, + -3.341057961368736713e-04f, + -3.542000527599929792e-04f, + -3.739036515368039746e-04f, + -3.931973986967992316e-04f, + -4.120625460867281776e-04f, + -4.304808093307158469e-04f, + -4.484343854917819923e-04f, + -4.659059702174845512e-04f, + -4.828787743535818602e-04f, + -4.993365400096493739e-04f, + -5.152635560612082175e-04f, + -5.306446730741198057e-04f, + -5.454653176364612647e-04f, + -5.597115060851909612e-04f, + -5.733698576140564907e-04f, + -5.864276067510603525e-04f, + -5.988726151936528234e-04f, + -6.106933829909588687e-04f, + -6.218790590626611069e-04f, + -6.324194510452570833e-04f, + -6.423050344567614702e-04f, + -6.515269611716821042e-04f, + -6.600770671990646883e-04f, + -6.679478797567967160e-04f, + -6.751326236362062069e-04f, + -6.816252268518211213e-04f, + -6.874203255717539112e-04f, + -6.925132683248836490e-04f, + -6.969001194819386376e-04f, + -7.005776620080852567e-04f, + -7.035433994855702167e-04f, + -7.057955574054943209e-04f, + -7.073330837287954750e-04f, + -7.081556487170125340e-04f, + -7.082636440342657963e-04f, + -7.076581811226278617e-04f, + -7.063410888537339193e-04f, + -7.043149104602236445e-04f, + -7.015828997513892445e-04f, + -6.981490166179902005e-04f, + -6.940179218320851728e-04f, + -6.891949711482260339e-04f, + -6.836862087132502142e-04f, + -6.774983597924347884e-04f, + -6.706388228206039545e-04f, + -6.631156607872861451e-04f, + -6.549375919657807231e-04f, + -6.461139799966924375e-04f, + -6.366548233369270175e-04f, + -6.265707440859499865e-04f, + -6.158729762017194510e-04f, + -6.045733531191070480e-04f, + -5.926842947843961179e-04f, + -5.802187941200323941e-04f, + -5.671904029341022849e-04f, + -5.536132172898791236e-04f, + -5.395018623509823539e-04f, + -5.248714767185811651e-04f, + -5.097376962770673765e-04f, + -4.941166375654838707e-04f, + -4.780248806924582670e-04f, + -4.614794518122551344e-04f, + -4.444978051810356389e-04f, + -4.270978048115207926e-04f, + -4.092977057456325968e-04f, + -3.911161349647420196e-04f, + -3.725720719571632062e-04f, + -3.536848289632427730e-04f, + -3.344740309187047944e-04f, + -3.149595951167335258e-04f, + -2.951617106099559715e-04f, + -2.751008173737486736e-04f, + -2.547975852520000407e-04f, + -2.342728927071314657e-04f, + -2.135478053963316245e-04f, + -1.926435545956132946e-04f, + -1.715815154940239279e-04f, + -1.503831853799458774e-04f, + -1.290701617419976258e-04f, + -1.076641203064520068e-04f, + -8.618679303362720165e-05f, + -6.465994609572296963e-05f, + -4.310535785803166131e-05f, + -2.154479688593094298e-05f, + 0.000000000000000000e+00f, + 2.150734959899484319e-05f, + 4.295564411312584395e-05f, + 6.432337281627700971e-05f, + 8.558914358778801847e-05f, + 1.067317042889163222e-04f, + 1.277299639610350547e-04f, + 1.485630138241603702e-04f, + 1.692101480553038985e-04f, + 1.896508843258684759e-04f, + 2.098649840776009373e-04f, + 2.298324725174021228e-04f, + 2.495336583111203762e-04f, + 2.689491529567958729e-04f, + 2.880598898186698250e-04f, + 3.068471428031533201e-04f, + 3.252925446583616268e-04f, + 3.433781048797137779e-04f, + 3.610862272039176181e-04f, + 3.783997266745809350e-04f, + 3.953018462627122791e-04f, + 4.117762730263829513e-04f, + 4.278071537938969346e-04f, + 4.433791103553099983e-04f, + 4.584772541480976356e-04f, + 4.730872004228363326e-04f, + 4.871950818755382503e-04f, + 5.007875617336743747e-04f, + 5.138518462839280912e-04f, + 5.263756968296791783e-04f, + 5.383474410673522387e-04f, + 5.497559838709404180e-04f, + 5.605908174750933934e-04f, + 5.708420310473718206e-04f, + 5.805003196410431958e-04f, + 5.895569925205944436e-04f, + 5.980039808525682747e-04f, + 6.058338447549957298e-04f, + 6.130397796995799755e-04f, + 6.196156222612016684e-04f, + 6.255558552100400158e-04f, + 6.308556119424503159e-04f, + 6.355106802471486953e-04f, + 6.395175054041730848e-04f, + 6.428731926145374613e-04f, + 6.455755087594301040e-04f, + 6.476228834882815982e-04f, + 6.490144096357687228e-04f, + 6.497498429685649897e-04f, + 6.498296012632502226e-04f, + 6.492547627174425229e-04f, + 6.480270636970132886e-04f, + 6.461488958227519508e-04f, + 6.436233024006336820e-04f, + 6.404539742004272803e-04f, + 6.366452445880759490e-04f, + 6.322020840178591873e-04f, + 6.271300938911197539e-04f, + 6.214354997887679231e-04f, + 6.151251440855713855e-04f, + 6.082064779547860164e-04f, + 6.006875527722377360e-04f, + 5.925770109296073186e-04f, + 5.838840760673158665e-04f, + 5.746185427377923640e-04f, + 5.647907655106131422e-04f, + 5.544116475315949552e-04f, + 5.434926285482021132e-04f, + 5.320456724144572097e-04f, + 5.200832540887690824e-04f, + 5.076183461388823585e-04f, + 4.946644047682729551e-04f, + 4.812353553790131599e-04f, + 4.673455776866451889e-04f, + 4.530098904026903664e-04f, + 4.382435355011193574e-04f, + 4.230621620855109567e-04f, + 4.074818098737383954e-04f, + 3.915188923177147684e-04f, + 3.751901793757405701e-04f, + 3.585127799555410831e-04f, + 3.415041240464490179e-04f, + 3.241819445590930424e-04f, + 3.065642588915733278e-04f, + 2.886693502413833915e-04f, + 2.705157486821331970e-04f, + 2.521222120247453859e-04f, + 2.335077064829918579e-04f, + 2.146913871629504706e-04f, + 1.956925783966609658e-04f, + 1.765307539399361904e-04f, + 1.572255170548387095e-04f, + 1.377965804968402466e-04f, + 1.182637464271945108e-04f, + 9.864688627111849629e-05f, + 7.896592054191218808e-05f, + 5.924079865161975436e-05f, + 3.949147872881094546e-05f, + 1.973790746354780164e-05f, + 0.000000000000000000e+00f, + -1.970238010284559686e-05f, + -3.934944082275756825e-05f, + -5.892148151755434546e-05f, + -7.839891264075306743e-05f, + -9.776227530943462282e-05f, + -1.169922607052078226e-04f, + -1.360697292888009540e-04f, + -1.549757298090502554e-04f, + -1.736915180877542444e-04f, + -1.921985755616629511e-04f, + -2.104786275631484471e-04f, + -2.285136613218662050e-04f, + -2.462859436695555878e-04f, + -2.637780384304916933e-04f, + -2.809728234808804288e-04f, + -2.978535074603023448e-04f, + -3.144036461191332854e-04f, + -3.306071582858338361e-04f, + -3.464483414389500442e-04f, + -3.619118868686585066e-04f, + -3.769828944131547489e-04f, + -3.916468867560180043e-04f, + -4.058898232707585751e-04f, + -4.196981133992728607e-04f, + -4.330586295517413042e-04f, + -4.459587195157615211e-04f, + -4.583862183627433859e-04f, + -4.703294598410216135e-04f, + -4.817772872445234334e-04f, + -4.927190637473565383e-04f, + -5.031446821946852560e-04f, + -5.130445743409007284e-04f, + -5.224097195269496782e-04f, + -5.312316527889542495e-04f, + -5.395024723908887479e-04f, + -5.472148467749195742e-04f, + -5.543620209233284749e-04f, + -5.609378221266176105e-04f, + -5.669366651531786106e-04f, + -5.723535568162687118e-04f, + -5.771840999348496837e-04f, + -5.814244966853034362e-04f, + -5.850715513418501545e-04f, + -5.881226724039281687e-04f, + -5.905758741095224786e-04f, + -5.924297773340420807e-04f, + -5.936836098749646720e-04f, + -5.943372061230182968e-04f, + -5.943910061214307226e-04f, + -5.938460540152537288e-04f, + -5.927039958934639209e-04f, + -5.909670770271131714e-04f, + -5.886381385074528462e-04f, + -5.857206132884568801e-04f, + -5.822185216389217429e-04f, + -5.781364660097343096e-04f, + -5.734796253225910197e-04f, + -5.682537486870293739e-04f, + -5.624651485531170217e-04f, + -5.561206933077393524e-04f, + -5.492277993230843978e-04f, + -5.417944224662266713e-04f, + -5.338290490794490428e-04f, + -5.253406864414295312e-04f, + -5.163388527197619636e-04f, + -5.068335664260176796e-04f, + -4.968353353848055896e-04f, + -4.863551452290165310e-04f, + -4.754044474335747460e-04f, + -4.639951469007321709e-04f, + -4.521395891103186892e-04f, + -4.398505468486206245e-04f, + -4.271412065301010948e-04f, + -4.140251541266666644e-04f, + -4.005163607192301599e-04f, + -3.866291676868795061e-04f, + -3.723782715496072680e-04f, + -3.577787084799967311e-04f, + -3.428458385006848889e-04f, + -3.275953293837695238e-04f, + -3.120431402691025606e-04f, + -2.962055050186841124e-04f, + -2.800989153242122590e-04f, + -2.637401035854408898e-04f, + -2.471460255771968360e-04f, + -2.303338429226980228e-04f, + -2.133209053914711568e-04f, + -1.961247330399053007e-04f, + -1.787629982130247515e-04f, + -1.612535074256399813e-04f, + -1.436141831415453836e-04f, + -1.258630454695097874e-04f, + -1.080181937944321024e-04f, + -9.009778836248835666e-05f, + -7.212003183910606612e-05f, + -5.410315085817400264e-05f, + -3.606537758129155149e-05f, + -1.802493128582126862e-05f, + -1.334841303324302416e-17f, + 1.799127779618168215e-05f, + 3.593083138609340919e-05f, + 5.380067592915723640e-05f, + 7.158293045321104055e-05f, + 8.925983570849392351e-05f, + 1.068137718653035880e-04f, + 1.242272760380188604e-04f, + 1.414830596179534239e-04f, + 1.585640253977377951e-04f, + 1.754532844705931341e-04f, + 1.921341728876877549e-04f, + 2.085902680570638303e-04f, + 2.248054048683053446e-04f, + 2.407636915270301768e-04f, + 2.564495250836037240e-04f, + 2.718476066412367303e-04f, + 2.869429562284523142e-04f, + 3.017209273216939929e-04f, + 3.161672210038205064e-04f, + 3.302678997451251666e-04f, + 3.440094007935225488e-04f, + 3.573785491609914131e-04f, + 3.703625701941320385e-04f, + 3.829491017167877117e-04f, + 3.951262057331397641e-04f, + 4.068823796806154101e-04f, + 4.182065672215850910e-04f, + 4.290881685642916978e-04f, + 4.395170503031860959e-04f, + 4.494835547696116843e-04f, + 4.589785088844519070e-04f, + 4.679932325046681232e-04f, + 4.765195462561217800e-04f, + 4.845497788459313506e-04f, + 4.920767738478327470e-04f, + 4.990938959546221661e-04f, + 5.055950366925160639e-04f, + 5.115746195925331957e-04f, + 5.170276048147706216e-04f, + 5.219494932218531839e-04f, + 5.263363298985630810e-04f, + 5.301847071150910407e-04f, + 5.334917667319233727e-04f, + 5.362552020450717756e-04f, + 5.384732590707796192e-04f, + 5.401447372694501321e-04f, + 5.412689897091851800e-04f, + 5.418459226697609071e-04f, + 5.418759946885404492e-04f, + 5.413602150503207117e-04f, + 5.403001417237128035e-04f, + 5.386978787471504403e-04f, + 5.365560730682539118e-04f, + 5.338779108407521986e-04f, + 5.306671131837313420e-04f, + 5.269279314085348852e-04f, + 5.226651417191434303e-04f, + 5.178840393923420668e-04f, + 5.125904324446496933e-04f, + 5.067906347932736285e-04f, + 5.004914589190106924e-04f, + 4.937002080395005770e-04f, + 4.864246678015905052e-04f, + 4.786730975021753222e-04f, + 4.704542208472601629e-04f, + 4.617772162595178012e-04f, + 4.526517067449197353e-04f, + 4.430877493295452938e-04f, + 4.330958240781504313e-04f, + 4.226868227062654973e-04f, + 4.118720367981569454e-04f, + 4.006631456434114435e-04f, + 3.890722037049972786e-04f, + 3.771116277322665187e-04f, + 3.647941835326885492e-04f, + 3.521329724160614195e-04f, + 3.391414173259668587e-04f, + 3.258332486726308631e-04f, + 3.122224898823369732e-04f, + 2.983234426785867904e-04f, + 2.841506721102148633e-04f, + 2.697189913421606591e-04f, + 2.550434462248571854e-04f, + 2.401392996580377489e-04f, + 2.250220157652570890e-04f, + 2.097072438956290921e-04f, + 1.942108024690222747e-04f, + 1.785486626815674697e-04f, + 1.627369320880489372e-04f, + 1.467918380782401184e-04f, + 1.307297112638300613e-04f, + 1.145669687930290083e-04f, + 9.832009760999397456e-05f, + 8.200563767584910741e-05f, + 6.564016516846416676e-05f, + 4.924027567815219766e-05f, + 3.282256741602081771e-05f, + 1.640362445206236378e-05f, + 0.000000000000000000e+00f, + -1.637180023455527615e-05f, + -3.269533462575305538e-05f, + -4.895424210242561722e-05f, + -6.513225850968472699e-05f, + -8.121323284108457146e-05f, + -9.718114332507469882e-05f, + -1.130201133496294995e-04f, + -1.287144272095247152e-04f, + -1.442485456605490041e-04f, + -1.596071212651732553e-04f, + -1.747750135148174182e-04f, + -1.897373037137282015e-04f, + -2.044793096097578128e-04f, + -2.189865997580020041e-04f, + -2.332450076030689249e-04f, + -2.472406452664517324e-04f, + -2.609599170254186065e-04f, + -2.743895324706472098e-04f, + -2.875165193297870496e-04f, + -3.003282359445427004e-04f, + -3.128123833895385809e-04f, + -3.249570172213065876e-04f, + -3.367505588461240803e-04f, + -3.481818064961628547e-04f, + -3.592399458034899098e-04f, + -3.699145599619731075e-04f, + -3.801956394677196631e-04f, + -3.900735914289291096e-04f, + -3.995392484366653077e-04f, + -4.085838769884034077e-04f, + -4.171991854566158182e-04f, + -4.253773315953880327e-04f, + -4.331109295782838197e-04f, + -4.403930565612024142e-04f, + -4.472172587646578920e-04f, + -4.535775570701503011e-04f, + -4.594684521259947778e-04f, + -4.648849289583206301e-04f, + -4.698224610836477188e-04f, + -4.742770141197898636e-04f, + -4.782450488924013302e-04f, + -4.817235240350806647e-04f, + -4.847098980813407910e-04f, + -4.872021310473242527e-04f, + -4.891986855046963432e-04f, + -4.906985271436078684e-04f, + -4.917011248261453924e-04f, + -4.922064501312485964e-04f, + -4.922149763925275263e-04f, + -4.917276772309548717e-04f, + -4.907460245849183233e-04f, + -4.892719862405896280e-04f, + -4.873080228661261920e-04f, + -4.848570845536456569e-04f, + -4.819226068734645927e-04f, + -4.785085064455284654e-04f, + -4.746191760334893435e-04f, + -4.702594791673116756e-04f, + -4.654347443007680212e-04f, + -4.601507585106936983e-04f, + -4.544137607452196142e-04f, + -4.482304346287416166e-04f, + -4.416079008317367900e-04f, + -4.345537090140839465e-04f, + -4.270758293507777911e-04f, + -4.191826436494728442e-04f, + -4.108829360697150140e-04f, + -4.021858834539161960e-04f, + -3.931010452806725248e-04f, + -3.836383532514024155e-04f, + -3.738081005214428367e-04f, + -3.636209305872444616e-04f, + -3.530878258416693307e-04f, + -3.422200958094793414e-04f, + -3.310293650756770912e-04f, + -3.195275609193634256e-04f, + -3.077269006664550737e-04f, + -2.956398787743567697e-04f, + -2.832792536622980853e-04f, + -2.706580343011211979e-04f, + -2.577894665766888188e-04f, + -2.446870194409517208e-04f, + -2.313643708652139079e-04f, + -2.178353936102799936e-04f, + -2.041141408280510209e-04f, + -1.902148315096290467e-04f, + -1.761518357948250199e-04f, + -1.619396601583952301e-04f, + -1.475929324880076194e-04f, + -1.331263870693465308e-04f, + -1.185548494938537772e-04f, + -1.038932215042936427e-04f, + -8.915646579370446799e-05f, + -7.435959077332714683e-05f, + -5.951763532474445284e-05f, + -4.464565355180115499e-05f, + -2.975869954784884257e-05f, + -1.487181219344128483e-05f, + 0.000000000000000000e+00f, + 1.484177398541613872e-05f, + 2.963860719904158576e-05f, + 4.437567248797690006e-05f, + 5.903823293163951847e-05f, + 7.361165654203178363e-05f, + 8.808143082849284827e-05f, + 1.024331772123446792e-04f, + 1.166526652770380289e-04f, + 1.307258268399512900e-04f, + 1.446387698318426075e-04f, + 1.583777919701953075e-04f, + 1.719293942132778794e-04f, + 1.852802939815504897e-04f, + 1.984174381336592573e-04f, + 2.113280156841942253e-04f, + 2.239994702510968052e-04f, + 2.364195122205586396e-04f, + 2.485761306175752138e-04f, + 2.604576046709465229e-04f, + 2.720525150615433867e-04f, + 2.833497548429932469e-04f, + 2.943385400246083098e-04f, + 3.050084198064263339e-04f, + 3.153492864566233744e-04f, + 3.253513848222112969e-04f, + 3.350053214640939868e-04f, + 3.443020734077864120e-04f, + 3.532329965021145852e-04f, + 3.617898333778522433e-04f, + 3.699647209993159932e-04f, + 3.777501978020017677e-04f, + 3.851392104098344126e-04f, + 3.921251199262121398e-04f, + 3.987017077932429100e-04f, + 4.048631812141973915e-04f, + 4.106041781344828734e-04f, + 4.159197717771173663e-04f, + 4.208054747289555891e-04f, + 4.252572425744124453e-04f, + 4.292714770740190195e-04f, + 4.328450288854669421e-04f, + 4.359751998253025848e-04f, + 4.386597446699808871e-04f, + 4.408968724953503567e-04f, + 4.426852475541531284e-04f, + 4.440239896916363025e-04f, + 4.449126742997511793e-04f, + 4.453513318109698395e-04f, + 4.453404467331309718e-04f, + 4.448809562272690614e-04f, + 4.439742482307769997e-04f, + 4.426221591287388775e-04f, + 4.408269709767168466e-04f, + 4.385914082787080990e-04f, + 4.359186343244749818e-04f, + 4.328122470908071003e-04f, + 4.292762747118040057e-04f, + 4.253151705236267433e-04f, + 4.209338076896006566e-04f, + 4.161374734119831350e-04f, + 4.109318627370653408e-04f, + 4.053230719607911351e-04f, + 3.993175916422970020e-04f, + 3.929222992332770761e-04f, + 3.861444513314888326e-04f, + 3.789916755669021876e-04f, + 3.714719621295073122e-04f, + 3.635936549481525153e-04f, + 3.553654425299459119e-04f, + 3.467963484702393361e-04f, + 3.378957216435445662e-04f, + 3.286732260858342197e-04f, + 3.191388305792130522e-04f, + 3.093027979500185209e-04f, + 2.991756740919330917e-04f, + 2.887682767254974537e-04f, + 2.780916839063471402e-04f, + 2.671572222938670333e-04f, + 2.559764551930417240e-04f, + 2.445611703817801011e-04f, + 2.329233677365916448e-04f, + 2.210752466696249048e-04f, + 2.090291933900031019e-04f, + 1.967977680028590282e-04f, + 1.843936914593410459e-04f, + 1.718298323712722203e-04f, + 1.591191937038941441e-04f, + 1.462748993604876967e-04f, + 1.333101806727993762e-04f, + 1.202383628109180238e-04f, + 1.070728511266315022e-04f, + 9.382711744432409014e-05f, + 8.051468631319089826e-05f, + 6.714912123485984206e-05f, + 5.374401088052293570e-05f, + 4.031295531131948081e-05f, + 2.686955221609669864e-05f, + 1.342738318029786585e-05f, + 0.000000000000000000e+00f, + -1.339908894537428966e-05f, + -2.675643224788563980e-05f, + -4.005864893978847017e-05f, + -5.329244186287420863e-05f, + -6.644461092502548262e-05f, + -7.950206623069222111e-05f, + -9.245184107248077213e-05f, + -1.052811047708897691e-04f, + -1.179771753494133872e-04f, + -1.305275320327536741e-04f, + -1.429198275556728382e-04f, + -1.551419002705676728e-04f, + -1.671817860417565296e-04f, + -1.790277299150954120e-04f, + -1.906681975514930251e-04f, + -2.020918864131418622e-04f, + -2.132877366918702598e-04f, + -2.242449419689906455e-04f, + -2.349529595963345725e-04f, + -2.454015207887385404e-04f, + -2.555806404182784557e-04f, + -2.654806265008874768e-04f, + -2.750920893665808145e-04f, + -2.844059505045345624e-04f, + -2.934134510748270851e-04f, + -3.021061600789069551e-04f, + -3.104759821811575835e-04f, + -3.185151651745712952e-04f, + -3.262163070835866359e-04f, + -3.335723628976332462e-04f, + -3.405766509294967594e-04f, + -3.472228587927296962e-04f, + -3.535050489929618660e-04f, + -3.594176641281607277e-04f, + -3.649555316935231171e-04f, + -3.701138684869255359e-04f, + -3.748882846112615666e-04f, + -3.792747870705806133e-04f, + -3.832697829571900684e-04f, + -3.868700822273337075e-04f, + -3.900729000635904330e-04f, + -3.928758588224299966e-04f, + -3.952769895658223660e-04f, + -3.972747331762911953e-04f, + -3.988679410551167681e-04f, + -4.000558754039121919e-04f, + -4.008382090901287695e-04f, + -4.012150250975650445e-04f, + -4.011868155632819922e-04f, + -4.007544804028019764e-04f, + -3.999193255258539845e-04f, + -3.986830606453539640e-04f, + -3.970477966826979296e-04f, + -3.950160427728647184e-04f, + -3.925907028732052292e-04f, + -3.897750719802241096e-04f, + -3.865728319589897214e-04f, + -3.829880469902513843e-04f, + -3.790251586406653394e-04f, + -3.746889805619719256e-04f, + -3.699846928252342087e-04f, + -3.649178358966703251e-04f, + -3.594943042620016315e-04f, + -3.537203397064425225e-04f, + -3.476025242579046902e-04f, + -3.411477728013451389e-04f, + -3.343633253723441497e-04f, + -3.272567391384403391e-04f, + -3.198358800770878963e-04f, + -3.121089143591786099e-04f, + -3.040842994476012479e-04f, + -2.957707749203746634e-04f, + -2.871773530283563362e-04f, + -2.783133089975229658e-04f, + -2.691881710862687534e-04f, + -2.598117104082893068e-04f, + -2.501939305319653465e-04f, + -2.403450568670490101e-04f, + -2.302755258500093155e-04f, + -2.199959739394581452e-04f, + -2.095172264330585757e-04f, + -1.988502861177488868e-04f, + -1.880063217650495839e-04f, + -1.769966564835590396e-04f, + -1.658327559405899988e-04f, + -1.545262164652106557e-04f, + -1.430887530451063164e-04f, + -1.315321872294559114e-04f, + -1.198684349503653277e-04f, + -1.081094942754574683e-04f, + -9.626743310399233169e-05f, + -8.435437681917366869e-05f, + -7.238249590935302358e-05f, + -6.036399357051934749e-05f, + -4.831109330284252872e-05f, + -3.623602651371357099e-05f, + -2.415102013999141309e-05f, + -1.206828430174254195e-05f, + 0.000000000000000000e+00f, + 1.204169312897504154e-05f, + 2.404470899092571738e-05f, + 3.599702712991723069e-05f, + 4.788670473170228393e-05f, + 5.970188852229866780e-05f, + 7.143082654988841410e-05f, + 8.306187983826528306e-05f, + 9.458353390051201588e-05f, + 1.059844101013897441e-04f, + 1.172532768573817302e-04f, + 1.283790606632529297e-04f, + 1.393508569345262404e-04f, + 1.501579406552106444e-04f, + 1.607897768203369465e-04f, + 1.712360306633601821e-04f, + 1.814865776584426626e-04f, + 1.915315132879176962e-04f, + 2.013611625657108102e-04f, + 2.109660893075433882e-04f, + 2.203371051389893943e-04f, + 2.294652782330296192e-04f, + 2.383419417686963803e-04f, + 2.469587021029656941e-04f, + 2.553074466481195588e-04f, + 2.633803514474035304e-04f, + 2.711698884419244454e-04f, + 2.786688324219942182e-04f, + 2.858702676567446673e-04f, + 2.927675941959327296e-04f, + 2.993545338382966954e-04f, + 3.056251357610912951e-04f, + 3.115737818059637109e-04f, + 3.171951914164931581e-04f, + 3.224844262232151398e-04f, + 3.274368942722000880e-04f, + 3.320483538937818360e-04f, + 3.363149172082760107e-04f, + 3.402330532659012994e-04f, + 3.437995908186134266e-04f, + 3.470117207218301322e-04f, + 3.498669979643943373e-04f, + 3.523633433256204432e-04f, + 3.544990446585373207e-04f, + 3.562727577988377661e-04f, + 3.576835070995022250e-04f, + 3.587306855913434921e-04f, + 3.594140547701693143e-04f, + 3.597337440115922912e-04f, + 3.596902496149280318e-04f, + 3.592844334779736470e-04f, + 3.585175214048202355e-04f, + 3.573911010492562368e-04f, + 3.559071194966300722e-04f, + 3.540678804874658795e-04f, + 3.518760412864115083e-04f, + 3.493346092005057690e-04f, + 3.464469377510762094e-04f, + 3.432167225039049318e-04f, + 3.396479965626749342e-04f, + 3.357451257309863640e-04f, + 3.315128033486363182e-04f, + 3.269560448080700604e-04f, + 3.220801817572939820e-04f, + 3.168908559958683816e-04f, + 3.113940130707873932e-04f, + 3.055958955794286277e-04f, + 2.995030361870785703e-04f, + 2.931222503666503615e-04f, + 2.864606288686135879e-04f, + 2.795255299294358681e-04f, + 2.723245712269062205e-04f, + 2.648656215911465348e-04f, + 2.571567924801972712e-04f, + 2.492064292294373924e-04f, + 2.410231020841035532e-04f, + 2.326155970245017573e-04f, + 2.239929063938051238e-04f, + 2.151642193382072939e-04f, + 2.061389120696203742e-04f, + 1.969265379611917521e-04f, + 1.875368174860041030e-04f, + 1.779796280096115294e-04f, + 1.682649934469443648e-04f, + 1.584030737944329339e-04f, + 1.484041545483235042e-04f, + 1.382786360200012393e-04f, + 1.280370225594695995e-04f, + 1.176899116981768777e-04f, + 1.072479832222307631e-04f, + 9.672198818729011848e-05f, + 8.612273788649634355e-05f, + 7.546109278254378857e-05f, + 6.474795141533576512e-05f, + 5.399423929640585659e-05f, + 4.321089780154245503e-05f, + 3.240887307268698056e-05f, + 2.159910494042194029e-05f, + 1.079251587830625557e-05f, + 0.000000000000000000e+00f, + -1.076758788963704548e-05f, + -2.149944317856241301e-05f, + -3.218482225573323713e-05f, + -4.281305323283309065e-05f, + -5.337354656864646082e-05f, + -6.385580558576757243e-05f, + -7.424943686907754835e-05f, + -8.454416053583386234e-05f, + -9.472982036711456591e-05f, + -1.047963937908457071e-04f, + -1.147340017065515562e-04f, + -1.245329181421548671e-04f, + -1.341835797335974307e-04f, + -1.436765950179864047e-04f, + -1.530027535312186607e-04f, + -1.621530347014577759e-04f, + -1.711186165298485740e-04f, + -1.798908840500873269e-04f, + -1.884614375589472831e-04f, + -1.968221006098050266e-04f, + -2.049649277617257863e-04f, + -2.128822120766777921e-04f, + -2.205664923580282378e-04f, + -2.280105601234851175e-04f, + -2.352074663059836263e-04f, + -2.421505276765508960e-04f, + -2.488333329829885750e-04f, + -2.552497487991398626e-04f, + -2.613939250791943547e-04f, + -2.672603004122885910e-04f, + -2.728436069726557201e-04f, + -2.781388751610882780e-04f, + -2.831414379336380212e-04f, + -2.878469348139965243e-04f, + -2.922513155861687336e-04f, + -2.963508436644055012e-04f, + -3.001420991378207152e-04f, + -3.036219814873026852e-04f, + -3.067877119727112443e-04f, + -3.096368356887807777e-04f, + -3.121672232883608046e-04f, + -3.143770723720249469e-04f, + -3.162649085434524054e-04f, + -3.178295861302663341e-04f, + -3.190702885703869526e-04f, + -3.199865284642772981e-04f, + -3.205781472938346467e-04f, + -3.208453148089736979e-04f, + -3.207885280832979214e-04f, + -3.204086102406083158e-04f, + -3.197067088542942777e-04f, + -3.186842940220061915e-04f, + -3.173431561183079385e-04f, + -3.156854032283730655e-04f, + -3.137134582660339763e-04f, + -3.114300557798812749e-04f, + -3.088382384513568856e-04f, + -3.059413532891418143e-04f, + -3.027430475243637962e-04f, + -2.992472642115744834e-04f, + -2.954582375405406932e-04f, + -2.913804878643640249e-04f, + -2.870188164496020400e-04f, + -2.823782999543770502e-04f, + -2.774642846407175700e-04f, + -2.722823803275761204e-04f, + -2.668384540913915862e-04f, + -2.611386237210131574e-04f, + -2.551892509343225957e-04f, + -2.489969343639438274e-04f, + -2.425685023197270455e-04f, + -2.359110053357878537e-04f, + -2.290317085103517163e-04f, + -2.219380836464229334e-04f, + -2.146378012019111564e-04f, + -2.071387220576676933e-04f, + -1.994488891124380440e-04f, + -1.915765187133722193e-04f, + -1.835299919314087671e-04f, + -1.753178456905652674e-04f, + -1.669487637607092330e-04f, + -1.584315676229787050e-04f, + -1.497752072176369788e-04f, + -1.409887515839194623e-04f, + -1.320813794016571026e-04f, + -1.230623694444957564e-04f, + -1.139410909545171644e-04f, + -1.047269939484425535e-04f, + -9.542959946509581922e-05f, + -8.605848976438549571e-05f, + -7.662329848777562182e-05f, + -6.713370079033298594e-05f, + -5.759940345433426073e-05f, + -4.803013499474702882e-05f, + -3.843563576630159076e-05f, + -2.882564808243503731e-05f, + -1.920990635599448016e-05f, + -9.598127271662273025e-06f, + 0.000000000000000000e+00f, + 9.574823537103811872e-06f, + 1.911673833977519833e-05f, + 2.861619593263633836e-05f, + 3.806371388693437398e-05f, + 4.744988525275912425e-05f, + 5.676538789203427777e-05f, + 6.600099370314859348e-05f, + 7.514757772787978142e-05f, + 8.419612713200058348e-05f, + 9.313775005050625494e-05f, + 1.019636842889295287e-04f, + 1.106653058722401322e-04f, + 1.192341374330203445e-04f, + 1.276618564308877656e-04f, + 1.359403031950059157e-04f, + 1.440614887822626452e-04f, + 1.520176026433699178e-04f, + 1.598010200896498841e-04f, + 1.674043095534119953e-04f, + 1.748202396351221399e-04f, + 1.820417859305353066e-04f, + 1.890621376316773902e-04f, + 1.958747038953250451e-04f, + 2.024731199731614757e-04f, + 2.088512530979652713e-04f, + 2.150032081205004760e-04f, + 2.209233328918379412e-04f, + 2.266062233865404583e-04f, + 2.320467285618302712e-04f, + 2.372399549487279324e-04f, + 2.421812709709947786e-04f, + 2.468663109882154221e-04f, + 2.512909790595921756e-04f, + 2.554514524253027516e-04f, + 2.593441847026279235e-04f, + 2.629659087941870811e-04f, + 2.663136395061924231e-04f, + 2.693846758746589278e-04f, + 2.721766031979693879e-04f, + 2.746872947744395253e-04f, + 2.769149133438811154e-04f, + 2.788579122323372257e-04f, + 2.805150361996677278e-04f, + 2.818853219897804355e-04f, + 2.829680985836939208e-04f, + 2.837629871559238016e-04f, + 2.842699007349416287e-04f, + 2.844890435688079782e-04f, + 2.844209101973068656e-04f, + 2.840662842322885578e-04f, + 2.834262368481505552e-04f, + 2.825021249847073845e-04f, + 2.812955892649861810e-04f, + 2.798085516307519159e-04f, + 2.780432126988811935e-04f, + 2.760020488419260187e-04f, + 2.736878089965273718e-04f, + 2.711035112035945611e-04f, + 2.682524388844043702e-04f, + 2.651381368570786159e-04f, + 2.617644070980710701e-04f, + 2.581353042536924927e-04f, + 2.542551309067299522e-04f, + 2.501284326036580432e-04f, + 2.457599926480392495e-04f, + 2.411548266659954384e-04f, + 2.363181769497842621e-04f, + 2.312555065858830860e-04f, + 2.259724933739240289e-04f, + 2.204750235432793924e-04f, + 2.147691852741365984e-04f, + 2.088612620301268357e-04f, + 2.027577257097531386e-04f, + 1.964652296239523634e-04f, + 1.899906013075300696e-04f, + 1.833408351718813763e-04f, + 1.765230850071902420e-04f, + 1.695446563417966825e-04f, + 1.624129986670188350e-04f, + 1.551356975356094168e-04f, + 1.477204665421056229e-04f, + 1.401751391936988090e-04f, + 1.325076606798998916e-04f, + 1.247260795497873826e-04f, + 1.168385393054425164e-04f, + 1.088532699203247078e-04f, + 1.007785792914005370e-04f, + 9.262284463377021455e-05f, + 8.439450382689701034e-05f, + 7.610204672104689636e-05f, + 6.775400641307872908e-05f, + 5.935895050042970316e-05f, + 5.092547232225660091e-05f, + 4.246218219656006581e-05f, + 3.397769866242637815e-05f, + 2.548063973595517562e-05f, + 1.697961418894217532e-05f, + 8.483212859017624744e-06f, + 0.000000000000000000e+00f, + -8.461495318869855788e-06f, + -1.689278775621859074e-05f, + -2.528544417573815790e-05f, + -3.363109204902172219e-05f, + -4.192142777555209638e-05f, + -5.014822491167240422e-05f, + -5.830334230039153014e-05f, + -6.637873209411312210e-05f, + -7.436644766219583183e-05f, + -8.225865137590645756e-05f, + -9.004762226295531552e-05f, + -9.772576352426085543e-05f, + -1.052856099056577086e-04f, + -1.127198349174101543e-04f, + -1.200212578946849995e-04f, + -1.271828508920051467e-04f, + -1.341977454053923206e-04f, + -1.410592389156038187e-04f, + -1.477608012463634826e-04f, + -1.542960807315748824e-04f, + -1.606589101858277410e-04f, + -1.668433126724388452e-04f, + -1.728435070639570102e-04f, + -1.786539133898150888e-04f, + -1.842691579663201804e-04f, + -1.896840783043778154e-04f, + -1.948937277903842115e-04f, + -1.998933801363103201e-04f, + -2.046785335949608540e-04f, + -2.092449149366440572e-04f, + -2.135884831840112908e-04f, + -2.177054331017576675e-04f, + -2.215921984383175921e-04f, + -2.252454549169022465e-04f, + -2.286621229734833933e-04f, + -2.318393702396226929e-04f, + -2.347746137681952429e-04f, + -2.374655220005397348e-04f, + -2.399100164736049493e-04f, + -2.421062732660711372e-04f, + -2.440527241826416158e-04f, + -2.457480576760017301e-04f, + -2.471912195061305153e-04f, + -2.483814131370483272e-04f, + -2.493180998712305895e-04f, + -2.500009987222372404e-04f, + -2.504300860263741746e-04f, + -2.506055947944560284e-04f, + -2.505280138049976969e-04f, + -2.501980864404289577e-04f, + -2.496168092681825537e-04f, + -2.487854303687649961e-04f, + -2.477054474131509354e-04f, + -2.463786054921205315e-04f, + -2.448068947003734946e-04f, + -2.429925474785403472e-04f, + -2.409380357163841445e-04f, + -2.386460676207832049e-04f, + -2.361195843522810752e-04f, + -2.333617564342224063e-04f, + -2.303759799387175490e-04f, + -2.271658724538751066e-04f, + -2.237352688370258271e-04f, + -2.200882167587254817e-04f, + -2.162289720426820811e-04f, + -2.121619938068343967e-04f, + -2.078919394110624542e-04f, + -2.034236592171233195e-04f, + -1.987621911667231361e-04f, + -1.939127551835801355e-04f, + -1.888807474057235954e-04f, + -1.836717342542969276e-04f, + -1.782914463453192841e-04f, + -1.727457722510192901e-04f, + -1.670407521174195056e-04f, + -1.611825711451174772e-04f, + -1.551775529402107034e-04f, + -1.490321527423956686e-04f, + -1.427529505375406372e-04f, + -1.363466440619829170e-04f, + -1.298200417059508136e-04f, + -1.231800553235984548e-04f, + -1.164336929571301011e-04f, + -1.095880514828144936e-04f, + -1.026503091863229081e-04f, + -9.562771827530503561e-05f, + -8.852759733689483329e-05f, + -8.135732374798783709e-05f, + -7.412432604604385269e-05f, + -6.683607626845965535e-05f, + -5.950008226812831386e-05f, + -5.212388001323979862e-05f, + -4.471502587911416735e-05f, + -3.728108893993130443e-05f, + -2.982964326820167396e-05f, + -2.236826024970074687e-05f, + -1.490450092183243395e-05f, + -7.445908342878064974e-06f, + 0.000000000000000000e+00f, + 7.425739736475704763e-06f, + 1.482386710490919136e-05f, + 2.218698638297385948e-05f, + 2.950775724944274754e-05f, + 3.677890207012403487e-05f, + 4.399321310054077095e-05f, + 5.114355959833892794e-05f, + 5.822289483842819512e-05f, + 6.522426302397340788e-05f, + 7.214080608657170231e-05f, + 7.896577036881257869e-05f, + 8.569251318300049464e-05f, + 9.231450923951847092e-05f, + 9.882535693872643605e-05f, + 1.052187845203471448e-04f, + 1.114886560645364380e-04f, + 1.176289773387779070e-04f, + 1.236339014852947521e-04f, + 1.294977345434665896e-04f, + 1.352149408021485982e-04f, + 1.407801479768994418e-04f, + 1.461881522073272849e-04f, + 1.514339228700169496e-04f, + 1.565126072024935349e-04f, + 1.614195347342348315e-04f, + 1.661502215206463087e-04f, + 1.707003741761581588e-04f, + 1.750658937030649676e-04f, + 1.792428791126197800e-04f, + 1.832276308353748221e-04f, + 1.870166539177443887e-04f, + 1.906066610022775826e-04f, + 1.939945750890921376e-04f, + 1.971775320762906734e-04f, + 2.001528830773817175e-04f, + 2.029181965139526369e-04f, + 2.054712599821023459e-04f, + 2.078100818912826861e-04f, + 2.099328928746136498e-04f, + 2.118381469697695253e-04f, + 2.135245225699071707e-04f, + 2.149909231442836445e-04f, + 2.162364777284813886e-04f, + 2.172605411843266446e-04f, + 2.180626942299304465e-04f, + 2.186427432404015815e-04f, + 2.190007198200883928e-04f, + 2.191368801473969510e-04f, + 2.190517040934920065e-04f, + 2.187458941163810658e-04f, + 2.182203739321322280e-04f, + 2.174762869651921987e-04f, + 2.165149945799773028e-04f, + 2.153380740961488441e-04f, + 2.139473165901802359e-04f, + 2.123447244860358321e-04f, + 2.105325089380130263e-04f, + 2.085130870089506230e-04f, + 2.062890786472634959e-04f, + 2.038633034664208931e-04f, + 2.012387773306926119e-04f, + 1.984187087511740796e-04f, + 1.954064950962511793e-04f, + 1.922057186209438458e-04f, + 1.888201423195703249e-04f, + 1.852537056065179267e-04f, + 1.815105198299485519e-04f, + 1.775948636234848943e-04f, + 1.735111781010148112e-04f, + 1.692640619000253591e-04f, + 1.648582660788071937e-04f, + 1.602986888732223973e-04f, + 1.555903703187100698e-04f, + 1.507384867433899029e-04f, + 1.457483451382290192e-04f, + 1.406253774102959029e-04f, + 1.353751345253480795e-04f, + 1.300032805459848623e-04f, + 1.245155865716643785e-04f, + 1.189179245871088876e-04f, + 1.132162612255646118e-04f, + 1.074166514535061193e-04f, + 1.015252321834391158e-04f, + 9.554821582143662340e-05f, + 8.949188375630919609e-05f, + 8.336257979698908499e-05f, + 7.716670356510142823e-05f, + 7.091070384951115571e-05f, + 6.460107192972675580e-05f, + 5.824433487497955288e-05f, + 5.184704882602284872e-05f, + 4.541579226631734119e-05f, + 3.895715928963878430e-05f, + 3.247775287090116139e-05f, + 2.598417814704357540e-05f, + 1.948303571479631031e-05f, + 1.298091495202827620e-05f, + 6.484387369576324119e-06f, + 0.000000000000000000e+00f, + -6.465731169933958513e-06f, + -1.290632771657884088e-05f, + -1.931535523998722761e-05f, + -2.568642976144864805e-05f, + -3.201322405145375435e-05f, + -3.828947388208588727e-05f, + -4.450898419751903002e-05f, + -5.066563519664518423e-05f, + -5.675338832188378036e-05f, + -6.276629214833436183e-05f, + -6.869848816762920277e-05f, + -7.454421646074183764e-05f, + -8.029782125450870081e-05f, + -8.595375635638307819e-05f, + -9.150659046230223595e-05f, + -9.695101233261035672e-05f, + -1.022818358312054416e-04f, + -1.074940048230266600e-04f, + -1.125825979255044379e-04f, + -1.175428331093993729e-04f, + -1.223700721448543901e-04f, + -1.270598248885527321e-04f, + -1.316077534080812585e-04f, + -1.360096759398110458e-04f, + -1.402615706766127137e-04f, + -1.443595793822601773e-04f, + -1.483000108290968150e-04f, + -1.520793440561845624e-04f, + -1.556942314450015955e-04f, + -1.591415016101448729e-04f, + -1.624181621026041017e-04f, + -1.655214019234404826e-04f, + -1.684485938457612995e-04f, + -1.711972965433097588e-04f, + -1.737652565239656850e-04f, + -1.761504098667907340e-04f, + -1.783508837614152301e-04f, + -1.803649978487851233e-04f, + -1.821912653624264543e-04f, + -1.838283940697296227e-04f, + -1.852752870127996935e-04f, + -1.865310430487398998e-04f, + -1.875949571893940915e-04f, + -1.884665207407716647e-04f, + -1.891454212426279299e-04f, + -1.896315422087889631e-04f, + -1.899249626691283926e-04f, + -1.900259565141956190e-04f, + -1.899349916437565312e-04f, + -1.896527289206770522e-04f, + -1.891800209317994808e-04f, + -1.885179105576068514e-04f, + -1.876676293527271906e-04f, + -1.866305957394497354e-04f, + -1.854084130166551892e-04f, + -1.840028671867227714e-04f, + -1.824159246031662005e-04f, + -1.806497294418971144e-04f, + -1.787066009992514435e-04f, + -1.765890308199928246e-04f, + -1.742996796587417414e-04f, + -1.718413742784095856e-04f, + -1.692171040893801167e-04f, + -1.664300176333031469e-04f, + -1.634834189156041844e-04f, + -1.603807635908042269e-04f, + -1.571256550050320762e-04f, + -1.537218401001562711e-04f, + -1.501732051841159817e-04f, + -1.464837715721702366e-04f, + -1.426576911038343165e-04f, + -1.386992415405413062e-04f, + -1.346128218489411334e-04f, + -1.304029473750683709e-04f, + -1.260742449145932711e-04f, + -1.216314476844448554e-04f, + -1.170793902013302941e-04f, + -1.124230030725036544e-04f, + -1.076673077044100317e-04f, + -1.028174109349222682e-04f, + -9.787849959470351147e-05f, + -9.285583500357369501e-05f, + -8.775474740762446567e-05f, + -8.258063036294733172e-05f, + -7.733893507179906781e-05f, + -7.203516467725131118e-05f, + -6.667486852207986337e-05f, + -6.126363637798329517e-05f, + -5.580709265104459485e-05f, + -5.031089056941896167e-05f, + -4.478070635923045353e-05f, + -3.922223341459007002e-05f, + -3.364117646783503998e-05f, + -2.804324576573561864e-05f, + -2.243415125772841104e-05f, + -1.681959680200483478e-05f, + -1.120527439532200600e-05f, + -5.596858432283831980e-06f, + 0.000000000000000000e+00f, + 5.579678786350002526e-06f, + 1.113659040131433947e-05f, + 1.666518747469618845e-05f, + 2.215996829939644689e-05f, + 2.761548227605910744e-05f, + 3.302633528924318619e-05f, + 3.838719500969946610e-05f, + 4.369279611777013815e-05f, + 4.893794544267782349e-05f, + 5.411752701278543923e-05f, + 5.922650701192542296e-05f, + 6.425993863709400348e-05f, + 6.921296685271543028e-05f, + 7.408083303713561935e-05f, + 7.885887951679374148e-05f, + 8.354255398385457916e-05f, + 8.812741379313725198e-05f, + 9.260913013432653981e-05f, + 9.698349207564205016e-05f, + 1.012464104751122735e-04f, + 1.053939217560361348e-04f, + 1.094221915430763865e-04f, + 1.133275181557522266e-04f, + 1.171063359561930271e-04f, + 1.207552185482215309e-04f, + 1.242708818248938415e-04f, + 1.276501868619005589e-04f, + 1.308901426543747110e-04f, + 1.339879086947369589e-04f, + 1.369407973894841402e-04f, + 1.397462763129272100e-04f, + 1.424019702960989549e-04f, + 1.449056633492160203e-04f, + 1.472553004161910543e-04f, + 1.494489889600180950e-04f, + 1.514850003778564957e-04f, + 1.533617712449332308e-04f, + 1.550779043865114734e-04f, + 1.566321697773859439e-04f, + 1.580235052684658486e-04f, + 1.592510171403173336e-04f, + 1.603139804835744661e-04f, + 1.612118394063934590e-04f, + 1.619442070692711196e-04f, + 1.625108655477295867e-04f, + 1.629117655235336551e-04f, + 1.631470258052963916e-04f, + 1.632169326794885361e-04f, + 1.631219390930484540e-04f, + 1.628626636689312806e-04f, + 1.624398895561451970e-04f, + 1.618545631159456772e-04f, + 1.611077924460503359e-04f, + 1.602008457448726990e-04f, + 1.591351495179624102e-04f, + 1.579122866289444445e-04f, + 1.565339941974661477e-04f, + 1.550021613467485204e-04f, + 1.533188268035131036e-04f, + 1.514861763532199430e-04f, + 1.495065401536325306e-04f, + 1.473823899099098260e-04f, + 1.451163359145451060e-04f, + 1.427111239555983182e-04f, + 1.401696320967573881e-04f, + 1.374948673329850774e-04f, + 1.346899621254734052e-04f, + 1.317581708198773619e-04f, + 1.287028659518289764e-04f, + 1.255275344438603485e-04f, + 1.222357736979611648e-04f, + 1.188312875880578206e-04f, + 1.153178823568962413e-04f, + 1.116994624217160199e-04f, + 1.079800260933631265e-04f, + 1.041636612134171070e-04f, + 1.002545407141449194e-04f, + 9.625691810593006150e-05f, + 9.217512289710953982e-05f, + 8.801355595103532931e-05f, + 8.377668478539886923e-05f, + 7.946903881866790591e-05f, + 7.509520456875234419e-05f, + 7.065982080891584666e-05f, + 6.616757368602117870e-05f, + 6.162319180617105993e-05f, + 5.703144129297408308e-05f, + 5.239712082341619980e-05f, + 4.772505664658922863e-05f, + 4.302009759036991954e-05f, + 3.828711006119116657e-05f, + 3.353097304204050925e-05f, + 2.875657309374543029e-05f, + 2.396879936476407346e-05f, + 1.917253861437825900e-05f, + 1.437267025445376776e-05f, + 9.574061414716567378e-06f, + 4.781562036525325622e-06f, + 0.000000000000000000e+00f, + -4.765823710467572352e-06f, + -9.511139797770952161e-06f, + -1.423121539568319248e-05f, + -1.892135876000095219e-05f, + -2.357692390252032815e-05f, + -2.819331516332007593e-05f, + -3.276599171692918774e-05f, + -3.729047200786769084e-05f, + -4.176233811142703061e-05f, + -4.617724001535500485e-05f, + -5.053089981838045005e-05f, + -5.481911584154466779e-05f, + -5.903776664846981624e-05f, + -6.318281497064232792e-05f, + -6.725031153416303120e-05f, + -7.123639878426539594e-05f, + -7.513731450417200934e-05f, + -7.894939532493793865e-05f, + -8.266908012303817257e-05f, + -8.629291330264409008e-05f, + -8.981754795950380526e-05f, + -9.323974892372517958e-05f, + -9.655639567864357899e-05f, + -9.976448515324246556e-05f, + -1.028611343856743177e-04f, + -1.058435830556215613e-04f, + -1.087091958832444314e-04f, + -1.114554648928591494e-04f, + -1.140800115393030879e-04f, + -1.165805886954139077e-04f, + -1.189550824989598954e-04f, + -1.212015140576370412e-04f, + -1.233180410108325074e-04f, + -1.253029589470822374e-04f, + -1.271547026761611632e-04f, + -1.288718473550913872e-04f, + -1.304531094673266076e-04f, + -1.318973476546234471e-04f, + -1.332035634012388348e-04f, + -1.343709015702383085e-04f, + -1.353986507918701350e-04f, + -1.362862437040613826e-04f, + -1.370332570453443202e-04f, + -1.376394116005415203e-04f, + -1.381045719998066825e-04f, + -1.384287463716805618e-04f, + -1.386120858510235900e-04f, + -1.386548839427931658e-04f, + -1.385575757428196932e-04f, + -1.383207370168273054e-04f, + -1.379450831391416433e-04f, + -1.374314678926119766e-04f, + -1.367808821314652607e-04f, + -1.359944523088843157e-04f, + -1.350734388713058730e-04f, + -1.340192345214945692e-04f, + -1.328333623526271043e-04f, + -1.315174738557150504e-04f, + -1.300733468028466666e-04f, + -1.285028830087897415e-04f, + -1.268081059737171702e-04f, + -1.249911584097946639e-04f, + -1.230542996545981637e-04f, + -1.209999029743675174e-04f, + -1.188304527602330177e-04f, + -1.165485416206351921e-04f, + -1.141568673732511950e-04f, + -1.116582299398947146e-04f, + -1.090555281478102406e-04f, + -1.063517564410224357e-04f, + -1.035500015053626303e-04f, + -1.006534388109464010e-04f, + -9.766532907587492868e-05f, + -9.458901465512266783e-05f, + -9.142791585846299308e-05f, + -8.818552720148400341e-05f, + -8.486541359380171191e-05f, + -8.147120646848431092e-05f, + -7.800659985692548243e-05f, + -7.447534641334087790e-05f, + -7.088125339309563760e-05f, + -6.722817858922308187e-05f, + -6.352002623131395697e-05f, + -5.976074285119170978e-05f, + -5.595431311967590562e-05f, + -5.210475565880340852e-05f, + -4.821611883387434797e-05f, + -4.429247652966449879e-05f, + -4.033792391527355533e-05f, + -3.635657320185136960e-05f, + -3.235254939766243925e-05f, + -2.832998606480489144e-05f, + -2.429302108193049522e-05f, + -2.024579241723850257e-05f, + -1.619243391613931063e-05f, + -1.213707110770494373e-05f, + -8.083817034238642389e-06f, + -4.036768108108601457e-06f, + 0.000000000000000000e+00f, + 4.022436437324076239e-06f, + 8.026519205701394352e-06f, + 1.200825915466515436e-05f, + 1.596370392708562708e-05f, + 1.988894185342372352e-05f, + 2.378010579081847397e-05f, + 2.763337690325799793e-05f, + 3.144498837921355557e-05f, + 3.521122908304340009e-05f, + 3.892844713680019853e-05f, + 4.259305342891470467e-05f, + 4.620152504646010591e-05f, + 4.975040862773826440e-05f, + 5.323632363207353587e-05f, + 5.665596552365893460e-05f, + 6.000610886662674704e-05f, + 6.328361032838766603e-05f, + 6.648541158852724214e-05f, + 6.960854215060292317e-05f, + 7.265012205430279883e-05f, + 7.560736448556652138e-05f, + 7.847757828228031152e-05f, + 8.125817033344999527e-05f, + 8.394664786969736913e-05f, + 8.654062064313692193e-05f, + 8.903780299482053388e-05f, + 9.143601580795497152e-05f, + 9.373318834539185970e-05f, + 9.592735996986403448e-05f, + 9.801668174559524367e-05f, + 9.999941792013674572e-05f, + 1.018739472852775956e-04f, + 1.036387644160876654e-04f, + 1.052924807872517206e-04f, + 1.068338257660048085e-04f, + 1.082616474810422510e-04f, + 1.095749135670224514e-04f, + 1.107727117842931974e-04f, + 1.118542505136681491e-04f, + 1.128188591261970936e-04f, + 1.136659882279879026e-04f, + 1.143952097802875201e-04f, + 1.150062170951232128e-04f, + 1.154988247069874726e-04f, + 1.158729681211121310e-04f, + 1.161287034390441527e-04f, + 1.162662068623534605e-04f, + 1.162857740754014629e-04f, + 1.161878195082552873e-04f, + 1.159728754809229666e-04f, + 1.156415912302182657e-04f, + 1.151947318206731616e-04f, + 1.146331769410351999e-04f, + 1.139579195879890020e-04f, + 1.131700646388664324e-04f, + 1.122708273152050117e-04f, + 1.112615315391279159e-04f, + 1.101436081846065776e-04f, + 1.089185932257956109e-04f, + 1.075881257847022211e-04f, + 1.061539460805467204e-04f, + 1.046178932833044002e-04f, + 1.029819032739389583e-04f, + 1.012480063139884254e-04f, + 9.941832462721362205e-05f, + 9.749506989611064225e-05f, + 9.548054067616838824e-05f, + 9.337711973079915206e-05f, + 9.118727129001866780e-05f, + 8.891353823589849862e-05f, + 8.655853921798483167e-05f, + 8.412496570189726970e-05f, + 8.161557895436345137e-05f, + 7.903320696801201077e-05f, + 7.638074132934370719e-05f, + 7.366113403320848053e-05f, + 7.087739424737539320e-05f, + 6.803258503057929422e-05f, + 6.512982000765911157e-05f, + 6.217226000532499622e-05f, + 5.916310965216279986e-05f, + 5.610561394646146512e-05f, + 5.300305479558382887e-05f, + 4.985874753042966284e-05f, + 4.667603739873827257e-05f, + 4.345829604087496334e-05f, + 4.020891795178530215e-05f, + 3.693131693280893166e-05f, + 3.362892253699031918e-05f, + 3.030517651164982165e-05f, + 2.696352924175526110e-05f, + 2.360743619783213642e-05f, + 2.024035439200125525e-05f, + 1.686573884576587145e-05f, + 1.348703907309045250e-05f, + 1.010769558241483277e-05f, + 6.731136401002770680e-06f, + 3.360773625198592391e-06f, + 0.000000000000000000e+00f, + -3.347814468650473784e-06f, + -6.679325865479849946e-06f, + -9.991219678161110501e-06f, + -1.328021406688385974e-05f, + -1.654306308815880257e-05f, + -1.977655986962290348e-05f, + -2.297753973280750991e-05f, + -2.614288326084785529e-05f, + -2.926951930822502027e-05f, + -3.235442794958472064e-05f, + -3.539464336494777658e-05f, + -3.838725665850617859e-05f, + -4.132941860839394398e-05f, + -4.421834234486570842e-05f, + -4.705130595439784442e-05f, + -4.982565500735158521e-05f, + -5.253880500681173683e-05f, + -5.518824375649152762e-05f, + -5.777153364550003561e-05f, + -6.028631384797333815e-05f, + -6.273030243562301752e-05f, + -6.510129840139457593e-05f, + -6.739718359242333320e-05f, + -6.961592455074339493e-05f, + -7.175557426013427060e-05f, + -7.381427379772556206e-05f, + -7.579025388895909592e-05f, + -7.768183636476383978e-05f, + -7.948743551975573677e-05f, + -8.120555937048918389e-05f, + -8.283481081280139394e-05f, + -8.437388867751212612e-05f, + -8.582158868373181084e-05f, + -8.717680428922131703e-05f, + -8.843852743731167663e-05f, + -8.960584920002047696e-05f, + -9.067796031711479563e-05f, + -9.165415163093462887e-05f, + -9.253381441698060807e-05f, + -9.331644061029057509e-05f, + -9.400162292779464348e-05f, + -9.458905488691879318e-05f, + -9.507853072082816524e-05f, + -9.546994519078202349e-05f, + -9.576329329621814776e-05f, + -9.595866988323466294e-05f, + -9.605626915229089865e-05f, + -9.605638406600895262e-05f, + -9.595940565808516048e-05f, + -9.576582224440011919e-05f, + -9.547621853752977987e-05f, + -9.509127466593055836e-05f, + -9.461176509920040452e-05f, + -9.403855748086969134e-05f, + -9.337261137029724230e-05f, + -9.261497689531161055e-05f, + -9.176679331735186228e-05f, + -9.082928751089830238e-05f, + -8.980377235912744038e-05f, + -8.869164506774372268e-05f, + -8.749438539906182540e-05f, + -8.621355382846783715e-05f, + -8.485078962544303713e-05f, + -8.340780886146616484e-05f, + -8.188640234708234958e-05f, + -8.028843350057289605e-05f, + -7.861583615068542543e-05f, + -7.687061227593963936e-05f, + -7.505482968307974337e-05f, + -7.317061962734104652e-05f, + -7.122017437715785402e-05f, + -6.920574472607888617e-05f, + -6.712963745464778354e-05f, + -6.499421274506274500e-05f, + -6.280188155146197997e-05f, + -6.055510292871261671e-05f, + -5.825638132264141731e-05f, + -5.590826382463881251e-05f, + -5.351333739358024485e-05f, + -5.107422604809699472e-05f, + -4.859358803218347312e-05f, + -4.607411295717206477e-05f, + -4.351851892309470621e-05f, + -4.092954962253340614e-05f, + -3.830997142993496893e-05f, + -3.566257047950555911e-05f, + -3.299014973471602795e-05f, + -3.029552605247514392e-05f, + -2.758152724501864632e-05f, + -2.485098914252425363e-05f, + -2.210675265954265012e-05f, + -1.935166086816063607e-05f, + -1.658855608095106957e-05f, + -1.382027694664882434e-05f, + -1.104965556150336744e-05f, + -8.279514599188903814e-06f, + -5.512664462229372086e-06f, + -2.751900457687248369e-06f, + 0.000000000000000000e+00f, + 2.740280156290214512e-06f, + 5.466206651186378539e-06f, + 8.175072218564196470e-06f, + 1.086419834758086399e-05f, + 1.353093790349696553e-05f, + 1.617267770547626131e-05f, + 1.878684105880902989e-05f, + 2.137089023916455868e-05f, + 2.392232892650095790e-05f, + 2.643870458635503993e-05f, + 2.891761079620682311e-05f, + 3.135668951483809152e-05f, + 3.375363329250938944e-05f, + 3.610618741995035084e-05f, + 3.841215201419369719e-05f, + 4.066938403936110963e-05f, + 4.287579926060773578e-05f, + 4.502937412942688007e-05f, + 4.712814759873801425e-05f, + 4.917022286611355612e-05f, + 5.115376904367083672e-05f, + 5.307702275320218851e-05f, + 5.493828964523271308e-05f, + 5.673594584069856022e-05f, + 5.846843929414990829e-05f, + 6.013429107736878215e-05f, + 6.173209658237591092e-05f, + 6.326052664298879500e-05f, + 6.471832857406342385e-05f, + 6.610432712770806260e-05f, + 6.741742536584356324e-05f, + 6.865660544852231900e-05f, + 6.982092933759627743e-05f, + 7.090953941532209665e-05f, + 7.192165901764468636e-05f, + 7.285659288195965404e-05f, + 7.371372750925019328e-05f, + 7.449253144060441825e-05f, + 7.519255544814984439e-05f, + 7.581343264061586552e-05f, + 7.635487848374452387e-05f, + 7.681669073589902474e-05f, + 7.719874929929503027e-05f, + 7.750101598737158502e-05f, + 7.772353420888149114e-05f, + 7.786642856940284227e-05f, + 7.792990439101760668e-05f, + 7.791424715101048608e-05f, + 7.781982184050777879e-05f, + 7.764707224406404028e-05f, + 7.739652014127399414e-05f, + 7.706876443157189042e-05f, + 7.666448018344928735e-05f, + 7.618441760939247533e-05f, + 7.562940096792763350e-05f, + 7.500032739420971781e-05f, + 7.429816566067238063e-05f, + 7.352395486933000228e-05f, + 7.267880307736313862e-05f, + 7.176388585770229430e-05f, + 7.078044479637946680e-05f, + 6.972978592846818902e-05f, + 6.861327811449984264e-05f, + 6.743235135927742136e-05f, + 6.618849507510502698e-05f, + 6.488325629143087644e-05f, + 6.351823781301141390e-05f, + 6.209509632871848778e-05f, + 6.061554047316198814e-05f, + 5.908132884331902243e-05f, + 5.749426797245979628e-05f, + 5.585621026359582951e-05f, + 5.416905188480572637e-05f, + 5.243473062876452025e-05f, + 5.065522373885282526e-05f, + 4.883254570422391761e-05f, + 4.696874602629149840e-05f, + 4.506590695899598622e-05f, + 4.312614122539617790e-05f, + 4.115158971296881845e-05f, + 3.914441915014531378e-05f, + 3.710681976655663884e-05f, + 3.504100293947658921e-05f, + 3.294919882896850676e-05f, + 3.083365400421063813e-05f, + 2.869662906354593466e-05f, + 2.654039625068195532e-05f, + 2.436723706957190895e-05f, + 2.217943990043698863e-05f, + 1.997929761939633796e-05f, + 1.776910522413144273e-05f, + 1.555115746807415747e-05f, + 1.332774650545313544e-05f, + 1.110115954964658368e-05f, + 8.873676547184104307e-06f, + 6.647567869740949601e-06f, + 4.425092026438055660e-06f, + 2.208493398703637141e-06f, + 0.000000000000000000e+00f, + -2.198178737447286155e-06f, + -4.383854146707416475e-06f, + -6.554860478846427014e-06f, + -8.709057022211050465e-06f, + -1.084433018625070958e-05f, + -1.295859554782643898e-05f, + -1.504979985813177589e-05f, + -1.711592300826502171e-05f, + -1.915497995162542054e-05f, + -2.116502258133142226e-05f, + -2.314414156091539193e-05f, + -2.509046810662869737e-05f, + -2.700217571967648383e-05f, + -2.887748186688327340e-05f, + -3.071464960822724050e-05f, + -3.251198916982059171e-05f, + -3.426785946094130863e-05f, + -3.598066953382340031e-05f, + -3.764887998489755495e-05f, + -3.927100429636594712e-05f, + -4.084561011694002843e-05f, + -4.237132048071104532e-05f, + -4.384681496316908579e-05f, + -4.527083077345597480e-05f, + -4.664216378202475170e-05f, + -4.795966948291004048e-05f, + -4.922226388992814933e-05f, + -5.042892436618977834e-05f, + -5.157869038634893284e-05f, + -5.267066423112145597e-05f, + -5.370401161365963874e-05f, + -5.467796223744639814e-05f, + -5.559181028545831532e-05f, + -5.644491484037703408e-05f, + -5.723670023577102494e-05f, + -5.796665633817722128e-05f, + -5.863433876011653090e-05f, + -5.923936900414046228e-05f, + -5.978143453809256339e-05f, + -6.026028880180132370e-05f, + -6.067575114554413853e-05f, + -6.102770670064889110e-05f, + -6.131610618268607763e-05f, + -6.154096562777286157e-05f, + -6.170236606257552899e-05f, + -6.180045310866599611e-05f, + -6.183543652194144397e-05f, + -6.180758966790510722e-05f, + -6.171724893364212428e-05f, + -6.156481307740533954e-05f, + -6.135074251677746099e-05f, + -6.107555855644340075e-05f, + -6.073984255665435130e-05f, + -6.034423504353361045e-05f, + -5.988943476241735355e-05f, + -5.937619767549151724e-05f, + -5.880533590502611506e-05f, + -5.817771662356323390e-05f, + -5.749426089246688652e-05f, + -5.675594245028995661e-05f, + -5.596378645244941432e-05f, + -5.511886816375996041e-05f, + -5.422231160540798414e-05f, + -5.327528815799189400e-05f, + -5.227901512228311736e-05f, + -5.123475423943163698e-05f, + -5.014381017231689294e-05f, + -4.900752894983425071e-05f, + -4.782729637590838818e-05f, + -4.660453640505390237e-05f, + -4.534070948633992719e-05f, + -4.403731087762476868e-05f, + -4.269586893198487468e-05f, + -4.131794335821765057e-05f, + -3.990512345738859756e-05f, + -3.845902633734535553e-05f, + -3.698129510720333325e-05f, + -3.547359705373742065e-05f, + -3.393762180168319212e-05f, + -3.237507945996893324e-05f, + -3.078769875582971604e-05f, + -2.917722515883962726e-05f, + -2.754541899685784069e-05f, + -2.589405356588684348e-05f, + -2.422491323584912912e-05f, + -2.253979155425681131e-05f, + -2.084048934980605179e-05f, + -1.912881283781196876e-05f, + -1.740657172949882254e-05f, + -1.567557734707370159e-05f, + -1.393764074653252662e-05f, + -1.219457085009355482e-05f, + -1.044817259020866579e-05f, + -8.700245066967668165e-06f, + -6.952579720797126885e-06f, + -5.206958522265940783e-06f, + -3.465152180804485261e-06f, + -1.728918374115329284e-06f, + 0.000000000000000000e+00f, + 1.719876547628855035e-06f, + 3.429003076962415618e-06f, + 5.125691268998652680e-06f, + 6.808274319193801364e-06f, + 8.475108548458095382e-06f, + 1.012457498199488445e-05f, + 1.175508089444992680e-05f, + 1.336506131998390598e-05f, + 1.495298052582536945e-05f, + 1.651733344796259886e-05f, + 1.805664708766448577e-05f, + 1.956948186756530129e-05f, + 2.105443294611633769e-05f, + 2.251013148919803211e-05f, + 2.393524589783997623e-05f, + 2.532848299093816370e-05f, + 2.668858914198573803e-05f, + 2.801435136885023771e-05f, + 2.930459837571368657e-05f, + 3.055820154629149815e-05f, + 3.177407588758812874e-05f, + 3.295118092341596186e-05f, + 3.408852153701416018e-05f, + 3.518514876214479022e-05f, + 3.624016052209482158e-05f, + 3.725270231609142734e-05f, + 3.822196785265903228e-05f, + 3.914719962953973575e-05f, + 4.002768945985303464e-05f, + 4.086277894419950948e-05f, + 4.165185988850534184e-05f, + 4.239437466744202404e-05f, + 4.308981653332471270e-05f, + 4.373772987044972097e-05f, + 4.433771039486739487e-05f, + 4.488940529969052062e-05f, + 4.539251334604474478e-05f, + 4.584678489985638750e-05f, + 4.625202191471458748e-05f, + 4.660807786111483166e-05f, + 4.691485760241596739e-05f, + 4.717231721794196576e-05f, + 4.738046377366677880e-05f, + 4.753935504100859647e-05f, + 4.764909916429116248e-05f, + 4.770985427749255010e-05f, + 4.772182807094424499e-05f, + 4.768527730869501094e-05f, + 4.760050729730926094e-05f, + 4.746787130690479115e-05f, + 4.728776994528908763e-05f, + 4.706065048609898603e-05f, + 4.678700615188301687e-05f, + 4.646737535312531160e-05f, + 4.610234088422814617e-05f, + 4.569252907753687694e-05f, + 4.523860891650402077e-05f, + 4.474129110914775088e-05f, + 4.420132712297902665e-05f, + 4.361950818261826370e-05f, + 4.299666423135587823e-05f, + 4.233366285792369062e-05f, + 4.163140818980473975e-05f, + 4.089083975440875428e-05f, + 4.011293130948711432e-05f, + 3.929868964417050821e-05f, + 3.844915335206358214e-05f, + 3.756539157780807174e-05f, + 3.664850273859330111e-05f, + 3.569961322208241148e-05f, + 3.471987606224959691e-05f, + 3.371046959463910820e-05f, + 3.267259609256267485e-05f, + 3.160748038579001628e-05f, + 3.051636846325336133e-05f, + 2.940052606132795206e-05f, + 2.826123723927484845e-05f, + 2.709980294337047645e-05f, + 2.591753956132967314e-05f, + 2.471577746857528420e-05f, + 2.349585956792650177e-05f, + 2.225913982430233876e-05f, + 2.100698179596996784e-05f, + 1.974075716392971998e-05f, + 1.846184426098673837e-05f, + 1.717162660205524496e-05f, + 1.587149141723013810e-05f, + 1.456282818918089089e-05f, + 1.324702719634344427e-05f, + 1.192547806344194722e-05f, + 1.059956832081574480e-05f, + 9.270681974018148597e-06f, + 7.940198085143243810e-06f, + 6.609489367292647408e-06f, + 5.279920793626897963e-06f, + 3.952848222338136709e-06f, + 2.629617038940430149e-06f, + 1.311560817197689786e-06f, + 0.000000000000000000e+00f, + -1.303759398535709597e-06f, + -2.598427068487143802e-06f, + -3.882729655845572457e-06f, + -5.155411989361711008e-06f, + -6.415238281346936499e-06f, + -7.660993301316896363e-06f, + -8.891483521387926858e-06f, + -1.010553823239075562e-05f, + -1.130201062965311224e-05f, + -1.247977886752223057e-05f, + -1.363774708165704589e-05f, + -1.477484637820374348e-05f, + -1.589003578899699857e-05f, + -1.698230319197812681e-05f, + -1.805066619602823882e-05f, + -1.909417298952157264e-05f, + -2.011190315188001194e-05f, + -2.110296842749134194e-05f, + -2.206651346138940222e-05f, + -2.300171649612773008e-05f, + -2.390779002935145109e-05f, + -2.478398143156065395e-05f, + -2.562957352368102888e-05f, + -2.644388511403268635e-05f, + -2.722627149437084187e-05f, + -2.797612489471199853e-05f, + -2.869287489668749573e-05f, + -2.937598880525030119e-05f, + -3.002497197854884801e-05f, + -3.063936811588928184e-05f, + -3.121875950370617492e-05f, + -3.176276721952791073e-05f, + -3.227105129396500970e-05f, + -3.274331083079011072e-05f, + -3.317928408523108317e-05f, + -3.357874850062376207e-05f, + -3.394152070364435874e-05f, + -3.426745645835545690e-05f, + -3.455645057935714278e-05f, + -3.480843680437391041e-05f, + -3.502338762665158155e-05f, + -3.520131408756888464e-05f, + -3.534226552992613248e-05f, + -3.544632931239619902e-05f, + -3.551363048567052514e-05f, + -3.554433143086765164e-05f, + -3.553863146080914930e-05f, + -3.549676638480726685e-05f, + -3.541900803763526229e-05f, + -3.530566377340024634e-05f, + -3.515707592505213643e-05f, + -3.497362123031461193e-05f, + -3.475571022484123395e-05f, + -3.450378660343666126e-05f, + -3.421832655021186221e-05f, + -3.389983803856685431e-05f, + -3.354886010192489469e-05f, + -3.316596207616956312e-05f, + -3.275174281475231333e-05f, + -3.230682987747619881e-05f, + -3.183187869396395209e-05f, + -3.132757170286612567e-05f, + -3.079461746785293406e-05f, + -3.023374977148131389e-05f, + -2.964572668803002056e-05f, + -2.903132963641206598e-05f, + -2.839136241429471749e-05f, + -2.772665021457329989e-05f, + -2.703803862533824987e-05f, + -2.632639261451207689e-05f, + -2.559259550032325886e-05f, + -2.483754790880125541e-05f, + -2.406216671948075119e-05f, + -2.326738400050288322e-05f, + -2.245414593433224767e-05f, + -2.162341173525594566e-05f, + -2.077615255991108366e-05f, + -1.991335041200381325e-05f, + -1.903599704245014085e-05f, + -1.814509284612314400e-05f, + -1.724164575641496121e-05f, + -1.632667013878813598e-05f, + -1.540118568453151252e-05f, + -1.446621630586251739e-05f, + -1.352278903357414166e-05f, + -1.257193291837421751e-05f, + -1.161467793707110403e-05f, + -1.065205390473139910e-05f, + -9.685089393960801953e-06f, + -8.714810662380517595e-06f, + -7.742240589422758301e-06f, + -6.768397623508250075e-06f, + -5.794294740669309052e-06f, + -4.820938415660515435e-06f, + -3.849327606567640099e-06f, + -2.880452753939940837e-06f, + -1.915294795392051711e-06f, + -9.548241966549667941e-07f, + 0.000000000000000000e+00f, + 9.482311090557935979e-07f, + 1.888935715883699196e-06f, + 2.821194570845099363e-06f, + 3.744103462554891212e-06f, + 4.656774069485003328e-06f, + 5.558334789141776895e-06f, + 6.447931544071930670e-06f, + 7.324728563978056132e-06f, + 8.187909143270469283e-06f, + 9.036676373374730734e-06f, + 9.870253849204916702e-06f, + 1.068788634918657437e-05f, + 1.148884048828036910e-05f, + 1.227240534347507200e-05f, + 1.303789305126774333e-05f, + 1.378463937664554480e-05f, + 1.451200425317579174e-05f, + 1.521937229378508572e-05f, + 1.590615327188085737e-05f, + 1.657178257248893217e-05f, + 1.721572161311536899e-05f, + 1.783745823408358416e-05f, + 1.843650705811206880e-05f, + 1.901240981896380926e-05f, + 1.956473565900515327e-05f, + 2.009308139556312985e-05f, + 2.059707175598756487e-05f, + 2.107635958138817672e-05f, + 2.153062599901698230e-05f, + 2.195958056332863746e-05f, + 2.236296136575796357e-05f, + 2.274053511332031568e-05f, + 2.309209717614148783e-05f, + 2.341747160407918292e-05f, + 2.371651111261625155e-05f, + 2.398909703825292155e-05f, + 2.423513926363566866e-05f, + 2.445457611271804443e-05f, + 2.464737421625526288e-05f, + 2.481352834797943618e-05f, + 2.495306123182613461e-05f, + 2.506602332061461824e-05f, + 2.515249254661017629e-05f, + 2.521257404442358010e-05f, + 2.524639984673718367e-05f, + 2.525412855336374039e-05f, + 2.523594497417534085e-05f, + 2.519205974646584022e-05f, + 2.512270892732973375e-05f, + 2.502815356166727978e-05f, + 2.490867922644573402e-05f, + 2.476459555187455187e-05f, + 2.459623572016065511e-05f, + 2.440395594254615678e-05f, + 2.418813491533502720e-05f, + 2.394917325564173359e-05f, + 2.368749291761338170e-05f, + 2.340353658988623544e-05f, + 2.309776707505748077e-05f, + 2.277066665197028110e-05f, + 2.242273642161569420e-05f, + 2.205449563747421783e-05f, + 2.166648102113158283e-05f, + 2.125924606400766132e-05f, + 2.083336031605244481e-05f, + 2.038940866226966761e-05f, + 1.992799058793915062e-05f, + 1.944971943340819870e-05f, + 1.895522163933315886e-05f, + 1.844513598326477953e-05f, + 1.792011280845339264e-05f, + 1.738081324577142443e-05f, + 1.682790842964813208e-05f, + 1.626207870890487679e-05f, + 1.568401285338399734e-05f, + 1.509440725727218157e-05f, + 1.449396513998789486e-05f, + 1.388339574554209775e-05f, + 1.326341354123314987e-05f, + 1.263473741656307925e-05f, + 1.199808988324299363e-05f, + 1.135419627714907315e-05f, + 1.070378396308057514e-05f, + 1.004758154317770732e-05f, + 9.386318069818621378e-06f, + 8.720722263832011000e-06f, + 8.051521738837318949e-06f, + 7.379442232510721810e-06f, + 6.705206845569983647e-06f, + 6.029535289243417829e-06f, + 5.353143142001254931e-06f, + 4.676741116269359137e-06f, + 4.001034335873452788e-06f, + 3.326721624913985331e-06f, + 2.654494808772660456e-06f, + 1.985038027915242428e-06f, + 1.319027065167622758e-06f, + 6.571286870779092537e-07f, + 0.000000000000000000e+00f, + -6.517121785112947791e-07f, + -1.297371932417118936e-06f, + -1.936354843466996782e-06f, + -2.568048570502482838e-06f, + -3.191853411264083243e-06f, + -3.807182846237992518e-06f, + -4.413464064061555844e-06f, + -5.010138468054313338e-06f, + -5.596662163456622115e-06f, + -6.172506424989349086e-06f, + -6.737158144353800846e-06f, + -7.290120257347119171e-06f, + -7.830912150263285036e-06f, + -8.359070045291263937e-06f, + -8.874147364643450859e-06f, + -9.375715073171476542e-06f, + -9.863361999259346438e-06f, + -1.033669513378841540e-05f, + -1.079533990703045404e-05f, + -1.123894044331291381e-05f, + -1.166715979335118242e-05f, + -1.207968014415581310e-05f, + -1.247620300645970784e-05f, + -1.285644937961374137e-05f, + -1.322015989395755990e-05f, + -1.356709493066716393e-05f, + -1.389703471911742539e-05f, + -1.420977941183009213e-05f, + -1.450514913708843372e-05f, + -1.478298402933197354e-05f, + -1.504314423747151812e-05f, + -1.528550991127199633e-05f, + -1.550998116600103277e-05f, + -1.571647802553678724e-05f, + -1.590494034416860253e-05f, + -1.607532770733858182e-05f, + -1.622761931159687079e-05f, + -1.636181382406056196e-05f, + -1.647792922169452577e-05f, + -1.657600261074252277e-05f, + -1.665609002666740320e-05f, + -1.671826621496820962e-05f, + -1.676262439326730422e-05f, + -1.678927599507833507e-05f, + -1.679835039567758540e-05f, + -1.678999462052671192e-05f, + -1.676437303670283319e-05f, + -1.672166702781419629e-05f, + -1.666207465288855371e-05f, + -1.658581028974159263e-05f, + -1.649310426334120225e-05f, + -1.638420245970092517e-05f, + -1.625936592584267462e-05f, + -1.611887045638726128e-05f, + -1.596300616733423785e-05f, + -1.579207705761010350e-05f, + -1.560640055896726747e-05f, + -1.540630707483150961e-05f, + -1.519213950869398463e-05f, + -1.496425278266009707e-05f, + -1.472301334677091966e-05f, + -1.446879867971653761e-05f, + -1.420199678156508936e-05f, + -1.392300565914552601e-05f, + -1.363223280470680123e-05f, + -1.333009466849801069e-05f, + -1.301701612590346651e-05f, + -1.269342993977575572e-05f, + -1.235977621860146935e-05f, + -1.201650187114281883e-05f, + -1.166406005819747346e-05f, + -1.130290964210320150e-05f, + -1.093351463463301477e-05f, + -1.055634364390535124e-05f, + -1.017186932094184607e-05f, + -9.780567806489146604e-06f, + -9.382918178734033738e-06f, + -8.979401902509168731e-06f, + -8.570502280611855256e-06f, + -8.156703907820469213e-06f, + -7.738492128206995299e-06f, + -7.316352496326938200e-06f, + -6.890770242859669408e-06f, + -6.462229745260318158e-06f, + -6.031214003986479169e-06f, + -5.598204124829813786e-06f, + -5.163678807894833656e-06f, + -4.728113843739430985e-06f, + -4.291981617188459184e-06f, + -3.855750619313580188e-06f, + -3.419884968058363287e-06f, + -2.984843937987475483e-06f, + -2.551081499598767520e-06f, + -2.119045868650204413e-06f, + -1.689179065920102918e-06f, + -1.261916487812816974e-06f, + -8.376864881983608732e-07f, + -4.169099718748218678e-07f, + 0.000000000000000000e+00f, + 4.126385921509365552e-07f, + 8.206095647815305072e-07f, + 1.223525630207122030e-06f, + 1.621008796236126059e-06f, + 2.012690696024970467e-06f, + 2.398212904138698659e-06f, + 2.777227238591446030e-06f, + 3.149396048634148933e-06f, + 3.514392488089205312e-06f, + 3.871900774045785298e-06f, + 4.221616430751789221e-06f, + 4.563246518543961347e-06f, + 4.896509847698758431e-06f, + 5.221137177081410397e-06f, + 5.536871397505274410e-06f, + 5.843467699721675325e-06f, + 6.140693726988073073e-06f, + 6.428329712173628339e-06f, + 6.706168599377329854e-06f, + 6.974016150064908968e-06f, + 7.231691033732799246e-06f, + 7.479024903134298036e-06f, + 7.715862454119090782e-06f, + 7.942061470155300043e-06f, + 8.157492851613173758e-06f, + 8.362040629923898268e-06f, + 8.555601966717204414e-06f, + 8.738087138086968224e-06f, + 8.909419504128689090e-06f, + 9.069535463915167161e-06f, + 9.218384396096766158e-06f, + 9.355928585322825753e-06f, + 9.482143134692021052e-06f, + 9.597015864467235791e-06f, + 9.700547197287537744e-06f, + 9.792750030137629163e-06f, + 9.873649593339112619e-06f, + 9.943283296844531363e-06f, + 1.000170056413215178e-05f, + 1.004896265399734296e-05f, + 1.008514247056514156e-05f, + 1.011032436185004009e-05f, + 1.012460390719635526e-05f, + 1.012808769395258744e-05f, + 1.012089308373725277e-05f, + 1.010314796865800678e-05f, + 1.007499051786728413e-05f, + 1.003656891483040004e-05f, + 9.988041085702172294e-06f, + 9.929574419209254656e-06f, + 9.861345478440398626e-06f, + 9.783539704959164481e-06f, + 9.696351115651413914e-06f, + 9.599981992730900805e-06f, + 9.494642567327615031e-06f, + 9.380550697087179814e-06f, + 9.257931538216254041e-06f, + 9.127017212404176378e-06f, + 8.988046469065492662e-06f, + 8.841264343334779069e-06f, + 8.686921810258770176e-06f, + 8.525275435626184639e-06f, + 8.356587023873447459e-06f, + 8.181123263510028723e-06f, + 7.999155370499712271e-06f, + 7.810958730038508927e-06f, + 7.616812537163261916e-06f, + 7.416999436624914182e-06f, + 7.211805162456990385e-06f, + 7.001518177666605594e-06f, + 6.786429314468350961e-06f, + 6.566831415485732412e-06f, + 6.343018976325844570e-06f, + 6.115287789940895410e-06f, + 5.883934593178742717e-06f, + 5.649256715913496299e-06f, + 5.411551733154688679e-06f, + 5.171117120509288493e-06f, + 4.928249913373739521e-06f, + 4.683246370226741163e-06f, + 4.436401640376830997e-06f, + 4.188009436517276560e-06f, + 3.938361712429462095e-06f, + 3.687748346167128183e-06f, + 3.436456829041018457e-06f, + 3.184771960722456336e-06f, + 2.932975550760869950e-06f, + 2.681346126811560784e-06f, + 2.430158649854029301e-06f, + 2.179684236669581299e-06f, + 1.930189889838635696e-06f, + 1.681938235501949860e-06f, + 1.435187269127313838e-06f, + 1.190190109498106053e-06f, + 9.471947611406282867e-07f, + 7.064438853882597620e-07f, + 4.681745802695258113e-07f, + 2.326181693934783062e-07f, + 0.000000000000000000e+00f, + -2.294607496822518279e-07f, + -4.555512536303946545e-07f, + -6.780652116471304469e-07f, + -8.968030132995199105e-07f, + -1.111571892074599649e-06f, + -1.322186069669318649e-06f, + -1.528466890336115189e-06f, + -1.730242945231773840e-06f, + -1.927350186716386900e-06f, + -2.119632032570274826e-06f, + -2.306939460105835373e-06f, + -2.489131090168029246e-06f, + -2.666073261019773634e-06f, + -2.837640092136482743e-06f, + -3.003713537930782497e-06f, + -3.164183431450152543e-06f, + -3.318947518098628411e-06f, + -3.467911479445268386e-06f, + -3.610988947198002060e-06f, + -3.748101507421474508e-06f, + -3.879178695106657928e-06f, + -4.004157979193569750e-06f, + -4.122984738168565981e-06f, + -4.235612226366478793e-06f, + -4.342001531119113841e-06f, + -4.442121520894592501e-06f, + -4.535948784595755533e-06f, + -4.623467562178467021e-06f, + -4.704669666773933905e-06f, + -4.779554398499982279e-06f, + -4.848128450155944567e-06f, + -4.910405805006164935e-06f, + -4.966407626865209352e-06f, + -5.016162142699305776e-06f, + -5.059704517976509766e-06f, + -5.097076724993110270e-06f, + -5.128327404419833975e-06f, + -5.153511720311018673e-06f, + -5.172691208831328023e-06f, + -5.185933620952477709e-06f, + -5.193312759386582571e-06f, + -5.194908310018822646e-06f, + -5.190805668113285727e-06f, + -5.181095759564734449e-06f, + -5.165874857474497392e-06f, + -5.145244394333831128e-06f, + -5.119310770095809750e-06f, + -5.088185156423761042e-06f, + -5.051983297406574915e-06f, + -5.010825307025710792e-06f, + -4.964835463670194371e-06f, + -4.914142001988321737e-06f, + -4.858876902370465571e-06f, + -4.799175678352467995e-06f, + -4.735177162236423786e-06f, + -4.667023289215640662e-06f, + -4.594858880296614592e-06f, + -4.518831424306328092e-06f, + -4.439090859272008081e-06f, + -4.355789353459791187e-06f, + -4.269081086352130785e-06f, + -4.179122029845473253e-06f, + -4.086069729946137843e-06f, + -3.990083089234567233e-06f, + -3.891322150369041671e-06f, + -3.789947880894861469e-06f, + -3.686121959618365274e-06f, + -3.580006564802584169e-06f, + -3.471764164435954700e-06f, + -3.361557308819947231e-06f, + -3.249548425715061173e-06f, + -3.135899618280506402e-06f, + -3.020772466037677946e-06f, + -2.904327829076243898e-06f, + -2.786725655720860965e-06f, + -2.668124793866750565e-06f, + -2.548682806187309839e-06f, + -2.428555789406447020e-06f, + -2.307898197824789105e-06f, + -2.186862671278643330e-06f, + -2.065599867705792124e-06f, + -1.944258300480321568e-06f, + -1.822984180674020067e-06f, + -1.701921264393156922e-06f, + -1.581210705329814697e-06f, + -1.460990912660235641e-06f, + -1.341397414412057306e-06f, + -1.222562726419054144e-06f, + -1.104616226963808055e-06f, + -9.876840372108532818e-07f, + -8.718889075168336299e-07f, + -7.573501096980523593e-07f, + -6.441833353263205178e-07f, + -5.325006001176824594e-07f, + -4.224101544649153790e-07f, + -3.140164001606101186e-07f, + -2.074198133468546951e-07f, + -1.027168737185703904e-07f, + 0.000000000000000000e+00f, + 1.006425082962560188e-07f, + 1.991265228250998696e-07f, + 2.953721320865672257e-07f, + 3.893036808413146083e-07f, + 4.808498032861632466e-07f, + 5.699434500219715067e-07f, + 6.565219088541263631e-07f, + 7.405268194708413983e-07f, + 8.219041820579037521e-07f, + 9.006043599106572324e-07f, + 9.765820761143821518e-07f, + 1.049796404370967154e-06f, + 1.120210754056259219e-06f, + 1.187792849601788622e-06f, + 1.252514704296207476e-06f, + 1.314352588615897804e-06f, + 1.373286993192450102e-06f, + 1.429302586538256487e-06f, + 1.482388167650501341e-06f, + 1.532536613626721034e-06f, + 1.579744822422699780e-06f, + 1.624013650897105724e-06f, + 1.665347848284486069e-06f, + 1.703755985248906983e-06f, + 1.739250378670976522e-06f, + 1.771847012329051112e-06f, + 1.801565453633872846e-06f, + 1.828428766587697603e-06f, + 1.852463421131862093e-06f, + 1.873699199062873253e-06f, + 1.892169096686314783e-06f, + 1.907909224391436775e-06f, + 1.920958703325515738e-06f, + 1.931359559352847449e-06f, + 1.939156614480256200e-06f, + 1.944397375938704227e-06f, + 1.947131923107859303e-06f, + 1.947412792470748310e-06f, + 1.945294860790306117e-06f, + 1.940835226696380303e-06f, + 1.934093090874000321e-06f, + 1.925129635041577493e-06f, + 1.914007899911128539e-06f, + 1.900792662316812488e-06f, + 1.885550311703490783e-06f, + 1.868348726157043199e-06f, + 1.849257148168054309e-06f, + 1.828346060309234932e-06f, + 1.805687061008333849e-06f, + 1.781352740599210893e-06f, + 1.755416557827082551e-06f, + 1.727952716981022353e-06f, + 1.699036045830707816e-06f, + 1.668741874531441462e-06f, + 1.637145915666299804e-06f, + 1.604324145587388401e-06f, + 1.570352687212907484e-06f, + 1.535307694438660471e-06f, + 1.499265238310532749e-06f, + 1.462301195107119339e-06f, + 1.424491136473709433e-06f, + 1.385910221746217664e-06f, + 1.346633092594916054e-06f, + 1.306733770119299951e-06f, + 1.266285554515691827e-06f, + 1.225360927433250136e-06f, + 1.184031457134546194e-06f, + 1.142367706564255042e-06f, + 1.100439144428898935e-06f, + 1.058314059384136389e-06f, + 1.016059477418145401e-06f, + 9.737410825169423452e-07f, + 9.314231406881861787e-07f, + 8.891684274188879932e-07f, + 8.470381586302859329e-07f, + 8.050919251930470272e-07f, + 7.633876310564211735e-07f, + 7.219814350382115897e-07f, + 6.809276963207535929e-07f, + 6.402789236869417325e-07f, + 6.000857285259880680e-07f, + 5.603967816352038095e-07f, + 5.212587738328753669e-07f, + 4.827163803963257315e-07f, + 4.448122293282582582e-07f, + 4.075868734547717757e-07f, + 3.710787663445438682e-07f, + 3.353242420407537163e-07f, + 3.003574985858815201e-07f, + 2.662105853160385845e-07f, + 2.329133938960602585e-07f, + 2.004936530600967300e-07f, + 1.689769270175546171e-07f, + 1.383866174786039171e-07f, + 1.087439692488582841e-07f, + 8.006807933651531888e-08f, + 5.237590951157132493e-08f, + 2.568230225109257904e-08f, + 0.000000000000000000e+00f, + -2.466033232770569548e-08f, + -4.829008168683121073e-08f, + -7.088265816141993268e-08f, + -9.243346323606733125e-08f, + -1.129398551695146863e-07f, + -1.324011115659184628e-07f, + -1.508183892432858115e-07f, + -1.681946815011221211e-07f, + -1.845347728928822297e-07f, + -1.998451916121546072e-07f, + -2.141341596039432244e-07f, + -2.274115405148332402e-07f, + -2.396887855988568836e-07f, + -2.509788776975187057e-07f, + -2.612962734148978839e-07f, + -2.706568436096965910e-07f, + -2.790778123294188281e-07f, + -2.865776943115482094e-07f, + -2.931762311773865084e-07f, + -2.988943264486187393e-07f, + -3.037539795124567178e-07f, + -3.077782186659332945e-07f, + -3.109910333676799518e-07f, + -3.134173058274048922e-07f, + -3.150827420621620873e-07f, + -3.160138025468559683e-07f, + -3.162376325911064067e-07f, + -3.157819925664867536e-07f, + -3.146751881132046538e-07f, + -3.129460004522320042e-07f, + -3.106236169256348513e-07f, + -3.077375618915215213e-07f, + -3.043176280902072482e-07f, + -3.003938086063936412e-07f, + -2.959962295410709180e-07f, + -2.911550835096173451e-07f, + -2.859005640803434774e-07f, + -2.802628012618049063e-07f, + -2.742717981466135591e-07f, + -2.679573688192066510e-07f, + -2.613490776251264430e-07f, + -2.544761799041636744e-07f, + -2.473675642799770811e-07f, + -2.400516965988118414e-07f, + -2.325565656058897010e-07f, + -2.249096304424925012e-07f, + -2.171377700460247078e-07f, + -2.092672345282480135e-07f, + -2.013235986056343617e-07f, + -1.933317171473633572e-07f, + -1.853156829093616031e-07f, + -1.772987865099094365e-07f, + -1.693034787059287238e-07f, + -1.613513350178359175e-07f, + -1.534630227503889525e-07f, + -1.456582704530633583e-07f, + -1.379558398535355063e-07f, + -1.303735002995515733e-07f, + -1.229280057368551819e-07f, + -1.156350742435759375e-07f, + -1.085093701420685361e-07f, + -1.015644887007500715e-07f, + -9.481294343366335435e-08f, + -8.826615600362021996e-08f, + -8.193444872566309993e-08f, + -7.582703966755611925e-08f, + -6.995204033572834065e-08f, + -6.431645593190529234e-08f, + -5.892618816136430419e-08f, + -5.378604056816772665e-08f, + -4.889972636892558379e-08f, + -4.426987875170946693e-08f, + -3.989806360360980105e-08f, + -3.578479462389621212e-08f, + -3.192955077725143908e-08f, + -2.833079603795987602e-08f, + -2.498600136841822765e-08f, + -2.189166887745841221e-08f, + -1.904335809309968632e-08f, + -1.643571428675994097e-08f, + -1.406249877778086397e-08f, + -1.191662114752070737e-08f, + -9.990173286071856191e-09f, + -8.274465192170869078e-09f, + -6.760062445140820835e-09f, + -5.436825263828806997e-09f, + -4.293949063640696908e-09f, + -3.320006422643590005e-09f, + -2.502990363837817991e-09f, + -1.830358857702062856e-09f, + -1.289080449029138733e-09f, + -8.656809086711142593e-10f, + -5.462908092693271412e-10f, + -3.166939230097100569e-10f, + -1.623763376571505723e-10f, + -6.857618579388846575e-11f, + -2.033388168720926172e-11f, + -2.542758678303834900e-12f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f, + 0.000000000000000000e+00f +}; + +} // namespace juce diff --git a/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp b/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp index 7c8625c5..bc472707 100644 --- a/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp +++ b/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -124,18 +124,29 @@ void AudioDeviceManager::audioDeviceListChanged() { if (currentAudioDevice != nullptr) { - auto isCurrentDeviceStillAvailable = [&] + auto currentDeviceStillAvailable = [&] { - for (auto* dt : availableDeviceTypes) - if (currentAudioDevice->getTypeName() == dt->getTypeName()) - for (auto& dn : dt->getDeviceNames()) - if (currentAudioDevice->getName() == dn) + auto currentTypeName = currentAudioDevice->getTypeName(); + auto currentDeviceName = currentAudioDevice->getName(); + + for (auto* deviceType : availableDeviceTypes) + { + if (currentTypeName == deviceType->getTypeName()) + { + for (auto& deviceName : deviceType->getDeviceNames (true)) + if (currentDeviceName == deviceName) return true; + for (auto& deviceName : deviceType->getDeviceNames (false)) + if (currentDeviceName == deviceName) + return true; + } + } + return false; - }; + }(); - if (! isCurrentDeviceStillAvailable()) + if (! currentDeviceStillAvailable) { closeAudioDevice(); @@ -166,8 +177,9 @@ static void addIfNotNull (OwnedArray<AudioIODeviceType>& list, AudioIODeviceType void AudioDeviceManager::createAudioDeviceTypes (OwnedArray<AudioIODeviceType>& list) { - addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_WASAPI (false)); - addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_WASAPI (true)); + addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_WASAPI (WASAPIDeviceMode::shared)); + addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_WASAPI (WASAPIDeviceMode::exclusive)); + addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_WASAPI (WASAPIDeviceMode::sharedLowLatency)); addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_DirectSound()); addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_ASIO()); addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_CoreAudio()); @@ -506,7 +518,7 @@ AudioIODeviceType* AudioDeviceManager::getCurrentDeviceTypeObject() const static void updateSetupChannels (AudioDeviceManager::AudioDeviceSetup& setup, int defaultNumIns, int defaultNumOuts) { - auto updateChannels = [](const String& deviceName, BigInteger& channels, int defaultNumChannels) + auto updateChannels = [] (const String& deviceName, BigInteger& channels, int defaultNumChannels) { if (deviceName.isEmpty()) { @@ -533,6 +545,8 @@ String AudioDeviceManager::setAudioDeviceSetup (const AudioDeviceSetup& newSetup else if (currentAudioDevice != nullptr) return {}; + stopDevice(); + if (getCurrentDeviceTypeObject() == nullptr || (newSetup.inputDeviceName.isEmpty() && newSetup.outputDeviceName.isEmpty())) { @@ -544,8 +558,6 @@ String AudioDeviceManager::setAudioDeviceSetup (const AudioDeviceSetup& newSetup return {}; } - stopDevice(); - String error; if (currentSetup.inputDeviceName != newSetup.inputDeviceName diff --git a/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.h b/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.h index b855d51e..ac490c0d 100644 --- a/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.h +++ b/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_devices/audio_io/juce_AudioIODevice.cpp b/modules/juce_audio_devices/audio_io/juce_AudioIODevice.cpp index 935de58d..3dc20383 100644 --- a/modules/juce_audio_devices/audio_io/juce_AudioIODevice.cpp +++ b/modules/juce_audio_devices/audio_io/juce_AudioIODevice.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_devices/audio_io/juce_AudioIODevice.h b/modules/juce_audio_devices/audio_io/juce_AudioIODevice.h index d835dd62..2e061933 100644 --- a/modules/juce_audio_devices/audio_io/juce_AudioIODevice.h +++ b/modules/juce_audio_devices/audio_io/juce_AudioIODevice.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.cpp b/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.cpp index 63f9e7fd..f591f481 100644 --- a/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.cpp +++ b/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -42,48 +42,105 @@ void AudioIODeviceType::callDeviceChangeListeners() } //============================================================================== -#if ! JUCE_MAC -AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_CoreAudio() { return nullptr; } +#if JUCE_MAC + AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_CoreAudio() { return new CoreAudioClasses::CoreAudioIODeviceType(); } +#else + AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_CoreAudio() { return nullptr; } #endif -#if ! JUCE_IOS -AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_iOSAudio() { return nullptr; } +#if JUCE_IOS + AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_iOSAudio() { return new iOSAudioIODeviceType(); } +#else + AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_iOSAudio() { return nullptr; } #endif -#if ! (JUCE_WINDOWS && JUCE_WASAPI) -AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_WASAPI (bool) { return nullptr; } +#if JUCE_WINDOWS && JUCE_WASAPI + AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_WASAPI (WASAPIDeviceMode deviceMode) + { + auto windowsVersion = SystemStats::getOperatingSystemType(); + + if (windowsVersion < SystemStats::WinVista + || (WasapiClasses::isLowLatencyMode (deviceMode) && windowsVersion < SystemStats::Windows10)) + return nullptr; + + return new WasapiClasses::WASAPIAudioIODeviceType (deviceMode); + } + + AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_WASAPI (bool exclusiveMode) + { + return createAudioIODeviceType_WASAPI (exclusiveMode ? WASAPIDeviceMode::exclusive + : WASAPIDeviceMode::shared); + } +#else + AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_WASAPI (WASAPIDeviceMode) { return nullptr; } + AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_WASAPI (bool) { return nullptr; } #endif -#if ! (JUCE_WINDOWS && JUCE_DIRECTSOUND) -AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_DirectSound() { return nullptr; } +#if JUCE_WINDOWS && JUCE_DIRECTSOUND + AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_DirectSound() { return new DSoundAudioIODeviceType(); } +#else + AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_DirectSound() { return nullptr; } #endif -#if ! (JUCE_WINDOWS && JUCE_ASIO) -AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_ASIO() { return nullptr; } +#if JUCE_WINDOWS && JUCE_ASIO + AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_ASIO() { return new ASIOAudioIODeviceType(); } +#else + AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_ASIO() { return nullptr; } #endif -#if ! (JUCE_LINUX && JUCE_ALSA) -AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_ALSA() { return nullptr; } +#if JUCE_LINUX && JUCE_ALSA + AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_ALSA() { return createAudioIODeviceType_ALSA_PCMDevices(); } +#else + AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_ALSA() { return nullptr; } #endif -#if ! (JUCE_LINUX && JUCE_JACK) -AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_JACK() { return nullptr; } +#if JUCE_LINUX && JUCE_JACK + AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_JACK() { return new JackAudioIODeviceType(); } +#else + AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_JACK() { return nullptr; } #endif -#if ! (JUCE_LINUX && JUCE_BELA) -AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_Bela() { return nullptr; } +#if JUCE_LINUX && JUCE_BELA + AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_Bela() { return new BelaAudioIODeviceType(); } +#else + AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_Bela() { return nullptr; } #endif -#if ! JUCE_ANDROID -AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_Android() { return nullptr; } +#if JUCE_ANDROID + AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_Android() + { + #if JUCE_USE_ANDROID_OBOE + if (isOboeAvailable()) + return nullptr; + #endif + + #if JUCE_USE_ANDROID_OPENSLES + if (isOpenSLAvailable()) + return nullptr; + #endif + + return new AndroidAudioIODeviceType(); + } +#else + AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_Android() { return nullptr; } #endif -#if ! (JUCE_ANDROID && JUCE_USE_ANDROID_OPENSLES) -AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_OpenSLES() { return nullptr; } +#if JUCE_ANDROID && JUCE_USE_ANDROID_OPENSLES + AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_OpenSLES() + { + return isOpenSLAvailable() ? new OpenSLAudioDeviceType() : nullptr; + } +#else + AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_OpenSLES() { return nullptr; } #endif -#if ! (JUCE_ANDROID && JUCE_USE_ANDROID_OBOE) -AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_Oboe() { return nullptr; } +#if JUCE_ANDROID && JUCE_USE_ANDROID_OBOE + AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_Oboe() + { + return isOboeAvailable() ? new OboeAudioIODeviceType() : nullptr; + } +#else + AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_Oboe() { return nullptr; } #endif } // namespace juce diff --git a/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.h b/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.h index b778e6a2..eca32bf9 100644 --- a/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.h +++ b/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -149,8 +149,8 @@ public: static AudioIODeviceType* createAudioIODeviceType_CoreAudio(); /** Creates an iOS device type if it's available on this platform, or returns null. */ static AudioIODeviceType* createAudioIODeviceType_iOSAudio(); - /** Creates a WASAPI device type if it's available on this platform, or returns null. */ - static AudioIODeviceType* createAudioIODeviceType_WASAPI (bool exclusiveMode); + /** Creates a WASAPI device type in the specified mode if it's available on this platform, or returns null. */ + static AudioIODeviceType* createAudioIODeviceType_WASAPI (WASAPIDeviceMode deviceMode); /** Creates a DirectSound device type if it's available on this platform, or returns null. */ static AudioIODeviceType* createAudioIODeviceType_DirectSound(); /** Creates an ASIO device type if it's available on this platform, or returns null. */ @@ -168,6 +168,9 @@ public: /** Creates a Bela device type if it's available on this platform, or returns null. */ static AudioIODeviceType* createAudioIODeviceType_Bela(); + /** This method has been deprecated. You should call the method which takes a WASAPIDeviceMode instead. */ + JUCE_DEPRECATED (static AudioIODeviceType* createAudioIODeviceType_WASAPI (bool exclusiveMode)); + protected: explicit AudioIODeviceType (const String& typeName); diff --git a/modules/juce_audio_devices/audio_io/juce_SystemAudioVolume.h b/modules/juce_audio_devices/audio_io/juce_SystemAudioVolume.h index a29537c5..6d8b7637 100644 --- a/modules/juce_audio_devices/audio_io/juce_SystemAudioVolume.h +++ b/modules/juce_audio_devices/audio_io/juce_SystemAudioVolume.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_devices/juce_audio_devices.cpp b/modules/juce_audio_devices/juce_audio_devices.cpp index a7f816e9..b3a315c9 100644 --- a/modules/juce_audio_devices/juce_audio_devices.cpp +++ b/modules/juce_audio_devices/juce_audio_devices.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -45,6 +45,8 @@ #include "juce_audio_devices.h" +#include "native/juce_MidiDataConcatenator.h" + //============================================================================== #if JUCE_MAC #define Point CarbonDummyPointName @@ -55,6 +57,9 @@ #undef Point #undef Component + #include "native/juce_mac_CoreAudio.cpp" + #include "native/juce_mac_CoreMidi.cpp" + #elif JUCE_IOS #import <AudioToolbox/AudioToolbox.h> #import <AVFoundation/AVFoundation.h> @@ -64,13 +69,21 @@ #import <CoreMIDI/MIDINetworkSession.h> #endif + #include "native/juce_ios_Audio.cpp" + #include "native/juce_mac_CoreMidi.cpp" + //============================================================================== #elif JUCE_WINDOWS #if JUCE_WASAPI #include <mmreg.h> + #include "native/juce_win32_WASAPI.cpp" + #endif + + #if JUCE_DIRECTSOUND + #include "native/juce_win32_DirectSound.cpp" #endif - #if JUCE_USE_WINRT_MIDI && JUCE_MSVC + #if JUCE_USE_WINRT_MIDI && (JUCE_MSVC || JUCE_CLANG) /* If you cannot find any of the header files below then you are probably attempting to use the Windows 10 Bluetooth Low Energy API. For this to work you need to install version 10.0.14393.0 of the Windows Standalone SDK and you may @@ -84,17 +97,17 @@ #include <windows.devices.midi.h> #include <windows.devices.enumeration.h> - #pragma warning (push) - #pragma warning (disable: 4265) + JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4265) #include <wrl/event.h> - #pragma warning (pop) + JUCE_END_IGNORE_WARNINGS_MSVC - #pragma warning (push) - #pragma warning (disable: 4467) + JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4467) #include <robuffer.h> - #pragma warning (pop) + JUCE_END_IGNORE_WARNINGS_MSVC #endif + #include "native/juce_win32_Midi.cpp" + #if JUCE_ASIO /* This is very frustrating - we only need to use a handful of definitions from a couple of the header files in Steinberg's ASIO SDK, and it'd be easy to copy @@ -116,6 +129,7 @@ needed - so to simplify things, you could just copy these into your JUCE directory). */ #include <iasiodrv.h> + #include "native/juce_win32_ASIO.cpp" #endif //============================================================================== @@ -130,6 +144,7 @@ just set the JUCE_ALSA flag to 0. */ #include <alsa/asoundlib.h> + #include "native/juce_linux_ALSA.cpp" #endif #if JUCE_JACK @@ -142,6 +157,7 @@ JUCE with low latency audio support, just set the JUCE_JACK flag to 0. */ #include <jack/jack.h> + #include "native/juce_linux_JackAudio.cpp" #endif #if JUCE_BELA @@ -151,93 +167,48 @@ */ #include <Bela.h> #include <Midi.h> + #include "native/juce_linux_Bela.cpp" #endif #undef SIZEOF -//============================================================================== -#elif JUCE_ANDROID - - #if JUCE_USE_ANDROID_OPENSLES - #include <SLES/OpenSLES.h> - #include <SLES/OpenSLES_Android.h> - #include <SLES/OpenSLES_AndroidConfiguration.h> - #endif - - #if JUCE_USE_ANDROID_OBOE - #if JUCE_USE_ANDROID_OPENSLES - #error "Oboe cannot be enabled at the same time as openSL! Please disable JUCE_USE_ANDROID_OPENSLES" - #endif - - #include <oboe/Oboe.h> + #if ! JUCE_BELA + #include "native/juce_linux_Midi.cpp" #endif -#endif - -#include "audio_io/juce_AudioDeviceManager.cpp" -#include "audio_io/juce_AudioIODevice.cpp" -#include "audio_io/juce_AudioIODeviceType.cpp" -#include "midi_io/juce_MidiMessageCollector.cpp" -#include "midi_io/juce_MidiDevices.cpp" -#include "sources/juce_AudioSourcePlayer.cpp" -#include "sources/juce_AudioTransportSource.cpp" -#include "native/juce_MidiDataConcatenator.h" - -//============================================================================== -#if JUCE_MAC - #include "native/juce_mac_CoreAudio.cpp" - #include "native/juce_mac_CoreMidi.cpp" - -//============================================================================== -#elif JUCE_IOS - #include "native/juce_ios_Audio.cpp" - #include "native/juce_mac_CoreMidi.cpp" - //============================================================================== -#elif JUCE_WINDOWS - - #if JUCE_WASAPI - #include "native/juce_win32_WASAPI.cpp" - #endif - - #if JUCE_DIRECTSOUND - #include "native/juce_win32_DirectSound.cpp" - #endif - - #include "native/juce_win32_Midi.cpp" +#elif JUCE_ANDROID - #if JUCE_ASIO - #include "native/juce_win32_ASIO.cpp" - #endif + #include "native/juce_android_Audio.cpp" + #include "native/juce_android_Midi.cpp" -//============================================================================== -#elif JUCE_LINUX - #if JUCE_ALSA - #include "native/juce_linux_ALSA.cpp" - #endif + #if JUCE_USE_ANDROID_OPENSLES || JUCE_USE_ANDROID_OBOE + #include "native/juce_android_HighPerformanceAudioHelpers.h" - #if JUCE_JACK - #include "native/juce_linux_JackAudio.cpp" - #endif + #if JUCE_USE_ANDROID_OPENSLES + #include <SLES/OpenSLES.h> + #include <SLES/OpenSLES_Android.h> + #include <SLES/OpenSLES_AndroidConfiguration.h> + #include "native/juce_android_OpenSL.cpp" + #endif - #if JUCE_BELA - #include "native/juce_linux_Bela.cpp" - #else - #include "native/juce_linux_Midi.cpp" - #endif + #if JUCE_USE_ANDROID_OBOE + #if JUCE_USE_ANDROID_OPENSLES + #error "Oboe cannot be enabled at the same time as openSL! Please disable JUCE_USE_ANDROID_OPENSLES" + #endif -//============================================================================== -#elif JUCE_ANDROID - #include "native/juce_android_Audio.cpp" - #include "native/juce_android_Midi.cpp" + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wunused-parameter", + "-Wzero-as-null-pointer-constant", + "-Winconsistent-missing-destructor-override", + "-Wshadow-field-in-constructor", + "-Wshadow-field") + #include <oboe/Oboe.h> + JUCE_END_IGNORE_WARNINGS_GCC_LIKE - #if JUCE_USE_ANDROID_OPENSLES - #include "native/juce_android_OpenSL.cpp" + #include "native/juce_android_Oboe.cpp" + #endif #endif - #if JUCE_USE_ANDROID_OBOE - #include "native/juce_android_Oboe.cpp" - #endif #endif #if ! JUCE_SYSTEMAUDIOVOL_IMPLEMENTED @@ -250,3 +221,11 @@ namespace juce bool JUCE_CALLTYPE SystemAudioVolume::setMuted (bool) { jassertfalse; return false; } } #endif + +#include "audio_io/juce_AudioDeviceManager.cpp" +#include "audio_io/juce_AudioIODevice.cpp" +#include "audio_io/juce_AudioIODeviceType.cpp" +#include "midi_io/juce_MidiMessageCollector.cpp" +#include "midi_io/juce_MidiDevices.cpp" +#include "sources/juce_AudioSourcePlayer.cpp" +#include "sources/juce_AudioTransportSource.cpp" diff --git a/modules/juce_audio_devices/juce_audio_devices.h b/modules/juce_audio_devices/juce_audio_devices.h index 1209d3c8..361427c1 100644 --- a/modules/juce_audio_devices/juce_audio_devices.h +++ b/modules/juce_audio_devices/juce_audio_devices.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -25,14 +25,14 @@ The block below describes the properties of this module, and is read by the Projucer to automatically generate project code that uses it. For details about the syntax and how to create or use a module, see the - JUCE Module Format.txt file. + JUCE Module Format.md file. BEGIN_JUCE_MODULE_DECLARATION ID: juce_audio_devices vendor: juce - version: 5.4.7 + version: 6.0.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 @@ -63,9 +63,8 @@ /** Config: JUCE_USE_WINRT_MIDI Enables the use of the Windows Runtime API for MIDI, allowing connections to Bluetooth Low Energy devices on Windows 10 version 1809 (October 2018 - Update) and later. If you enable this flag then older, unsupported, - versions of Windows will automatically fall back to using the regular - Win32 MIDI API. + Update) and later. If you enable this flag then older versions of Windows + will automatically fall back to using the regular Win32 MIDI API. You will need version 10.0.14393.0 of the Windows Standalone SDK to compile and you may need to add the path to the WinRT headers. The path to the @@ -89,21 +88,12 @@ #endif /** Config: JUCE_WASAPI - Enables WASAPI audio devices (Windows Vista and above). See also the - JUCE_WASAPI_EXCLUSIVE flag. + Enables WASAPI audio devices (Windows Vista and above). */ #ifndef JUCE_WASAPI #define JUCE_WASAPI 1 #endif -/** Config: JUCE_WASAPI_EXCLUSIVE - Enables WASAPI audio devices in exclusive mode (Windows Vista and above). -*/ -#ifndef JUCE_WASAPI_EXCLUSIVE - #define JUCE_WASAPI_EXCLUSIVE 0 -#endif - - /** Config: JUCE_DIRECTSOUND Enables DirectSound audio (MS Windows only). */ @@ -133,18 +123,10 @@ #endif /** Config: JUCE_USE_ANDROID_OBOE - *** - DEVELOPER PREVIEW - Oboe is currently in developer preview and - is in active development. This preview allows for early access - and evaluation for developers targeting Android platform. - *** - - Enables Oboe devices (Android only, API 16 or above). Requires - Oboe repository path to be specified in Android exporter. + Enables Oboe devices (Android only, API 16 or above). */ - #ifndef JUCE_USE_ANDROID_OBOE - #define JUCE_USE_ANDROID_OBOE 0 + #define JUCE_USE_ANDROID_OBOE 1 #endif #if JUCE_USE_ANDROID_OBOE && JUCE_ANDROID_API_VERSION < 16 @@ -152,6 +134,15 @@ #define JUCE_USE_ANDROID_OBOE 0 #endif +/** Config: JUCE_USE_OBOE_STABILIZED_CALLBACK + If JUCE_USE_ANDROID_OBOE is enabled, enabling this will wrap output audio + streams in the oboe::StabilizedCallback class. This class attempts to keep + the CPU spinning to avoid it being scaled down on certain devices. +*/ +#ifndef JUCE_USE_ANDROID_OBOE_STABILIZED_CALLBACK + #define JUCE_USE_ANDROID_OBOE_STABILIZED_CALLBACK 0 +#endif + /** Config: JUCE_USE_ANDROID_OPENSLES Enables OpenSLES devices (Android only). */ @@ -174,6 +165,22 @@ //============================================================================== #include "midi_io/juce_MidiDevices.h" #include "midi_io/juce_MidiMessageCollector.h" + +namespace juce +{ + /** Available modes for the WASAPI audio device. + + Pass one of these to the AudioIODeviceType::createAudioIODeviceType_WASAPI() + method to create a WASAPI AudioIODeviceType object in this mode. + */ + enum class WASAPIDeviceMode + { + shared, + exclusive, + sharedLowLatency + }; +} + #include "audio_io/juce_AudioIODevice.h" #include "audio_io/juce_AudioIODeviceType.h" #include "audio_io/juce_SystemAudioVolume.h" diff --git a/modules/juce_audio_devices/juce_audio_devices.mm b/modules/juce_audio_devices/juce_audio_devices.mm index 08951e32..c58ad3f9 100644 --- a/modules/juce_audio_devices/juce_audio_devices.mm +++ b/modules/juce_audio_devices/juce_audio_devices.mm @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_devices/midi_io/juce_MidiDevices.cpp b/modules/juce_audio_devices/midi_io/juce_MidiDevices.cpp index a5f761a2..df654376 100644 --- a/modules/juce_audio_devices/midi_io/juce_MidiDevices.cpp +++ b/modules/juce_audio_devices/midi_io/juce_MidiDevices.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -30,12 +30,8 @@ MidiOutput::MidiOutput (const String& deviceName, const String& deviceIdentifier void MidiOutput::sendBlockOfMessagesNow (const MidiBuffer& buffer) { - MidiBuffer::Iterator i (buffer); - MidiMessage message; - int samplePosition; // Note: Not actually used, so no need to initialise. - - while (i.getNextEvent (message, samplePosition)) - sendMessageNow (message); + for (const auto metadata : buffer) + sendMessageNow (metadata.getMessage()); } void MidiOutput::sendBlockOfMessages (const MidiBuffer& buffer, @@ -50,13 +46,10 @@ void MidiOutput::sendBlockOfMessages (const MidiBuffer& buffer, auto timeScaleFactor = 1000.0 / samplesPerSecondForBuffer; - const uint8* data; - int len, time; - - for (MidiBuffer::Iterator i (buffer); i.getNextEvent (data, len, time);) + for (const auto metadata : buffer) { - auto eventTime = millisecondCounterToStartAt + timeScaleFactor * time; - auto* m = new PendingMessage (data, len, eventTime); + auto eventTime = millisecondCounterToStartAt + timeScaleFactor * metadata.samplePosition; + auto* m = new PendingMessage (metadata.data, metadata.numBytes, eventTime); const ScopedLock sl (lock); diff --git a/modules/juce_audio_devices/midi_io/juce_MidiDevices.h b/modules/juce_audio_devices/midi_io/juce_MidiDevices.h index 054a376a..982e71c6 100644 --- a/modules/juce_audio_devices/midi_io/juce_MidiDevices.h +++ b/modules/juce_audio_devices/midi_io/juce_MidiDevices.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -164,12 +164,16 @@ public: /** Deprecated. */ static std::unique_ptr<MidiInput> openDevice (int, MidiInputCallback*); + /** @internal */ + class Pimpl; + private: //============================================================================== explicit MidiInput (const String&, const String&); MidiDeviceInfo deviceInfo; - void* internal = nullptr; + + std::unique_ptr<Pimpl> internal; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiInput) }; @@ -337,6 +341,11 @@ public: */ void stopBackgroundThread(); + /** Returns true if the background thread used to send blocks of data is running. + @see startBackgroundThread, stopBackgroundThread + */ + bool isBackgroundThreadRunning() const noexcept { return isThreadRunning(); } + //============================================================================== /** Deprecated. */ static StringArray getDevices(); @@ -345,6 +354,9 @@ public: /** Deprecated. */ static std::unique_ptr<MidiOutput> openDevice (int); + /** @internal */ + class Pimpl; + private: //============================================================================== struct PendingMessage @@ -363,7 +375,9 @@ private: void run() override; MidiDeviceInfo deviceInfo; - void* internal = nullptr; + + std::unique_ptr<Pimpl> internal; + CriticalSection lock; PendingMessage* firstMessage = nullptr; diff --git a/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.cpp b/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.cpp index 97f73303..5e837f5b 100644 --- a/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.cpp +++ b/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -90,33 +90,28 @@ void MidiMessageCollector::removeNextBlockOfMessages (MidiBuffer& destBuffer, int startSample = 0; int scale = 1 << 16; - const uint8* midiData; - int numBytes, samplePosition; - - MidiBuffer::Iterator iter (incomingMessages); - if (numSourceSamples > numSamples) { // if our list of events is longer than the buffer we're being // asked for, scale them down to squeeze them all in.. const int maxBlockLengthToUse = numSamples << 5; + auto iter = incomingMessages.cbegin(); + if (numSourceSamples > maxBlockLengthToUse) { startSample = numSourceSamples - maxBlockLengthToUse; numSourceSamples = maxBlockLengthToUse; - iter.setNextSamplePosition (startSample); + iter = incomingMessages.findNextSamplePosition (startSample); } scale = (numSamples << 10) / numSourceSamples; - while (iter.getNextEvent (midiData, numBytes, samplePosition)) + std::for_each (iter, incomingMessages.cend(), [&] (const MidiMessageMetadata& meta) { - samplePosition = ((samplePosition - startSample) * scale) >> 10; - - destBuffer.addEvent (midiData, numBytes, - jlimit (0, numSamples - 1, samplePosition)); - } + const auto pos = ((meta.samplePosition - startSample) * scale) >> 10; + destBuffer.addEvent (meta.data, meta.numBytes, jlimit (0, numSamples - 1, pos)); + }); } else { @@ -124,17 +119,20 @@ void MidiMessageCollector::removeNextBlockOfMessages (MidiBuffer& destBuffer, // towards the end of the buffer startSample = numSamples - numSourceSamples; - while (iter.getNextEvent (midiData, numBytes, samplePosition)) - { - destBuffer.addEvent (midiData, numBytes, - jlimit (0, numSamples - 1, samplePosition + startSample)); - } + for (const auto metadata : incomingMessages) + destBuffer.addEvent (metadata.data, metadata.numBytes, + jlimit (0, numSamples - 1, metadata.samplePosition + startSample)); } incomingMessages.clear(); } } +void MidiMessageCollector::ensureStorageAllocated (size_t bytes) +{ + incomingMessages.ensureSize (bytes); +} + //============================================================================== void MidiMessageCollector::handleNoteOn (MidiKeyboardState*, int midiChannel, int midiNoteNumber, float velocity) { diff --git a/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.h b/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.h index 6692a1b3..b9344e9f 100644 --- a/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.h +++ b/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -28,14 +28,14 @@ namespace juce Collects incoming realtime MIDI messages and turns them into blocks suitable for processing by a block-based audio callback. - The class can also be used as either a MidiKeyboardStateListener or a MidiInputCallback + The class can also be used as either a MidiKeyboardState::Listener or a MidiInputCallback so it can easily use a midi input or keyboard component as its source. @see MidiMessage, MidiInput @tags{Audio} */ -class JUCE_API MidiMessageCollector : public MidiKeyboardStateListener, +class JUCE_API MidiMessageCollector : public MidiKeyboardState::Listener, public MidiInputCallback { public: @@ -80,6 +80,14 @@ public: */ void removeNextBlockOfMessages (MidiBuffer& destBuffer, int numSamples); + /** Preallocates storage for collected messages. + + This can be called before audio processing begins to ensure that there + is sufficient space for the expected MIDI messages, in order to avoid + allocations within the audio callback. + */ + void ensureStorageAllocated (size_t bytes); + //============================================================================== /** @internal */ diff --git a/modules/juce_audio_devices/native/java/app/com/roli/juce/JuceMidiSupport.java b/modules/juce_audio_devices/native/java/app/com/rmsl/juce/JuceMidiSupport.java similarity index 94% rename from modules/juce_audio_devices/native/java/app/com/roli/juce/JuceMidiSupport.java rename to modules/juce_audio_devices/native/java/app/com/rmsl/juce/JuceMidiSupport.java index 713f3350..1520284f 100644 --- a/modules/juce_audio_devices/native/java/app/com/roli/juce/JuceMidiSupport.java +++ b/modules/juce_audio_devices/native/java/app/com/rmsl/juce/JuceMidiSupport.java @@ -1,4 +1,26 @@ -package com.roli.juce; +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + To use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +package com.rmsl.juce; import android.bluetooth.BluetoothAdapter; diff --git a/modules/juce_audio_devices/native/juce_MidiDataConcatenator.h b/modules/juce_audio_devices/native/juce_MidiDataConcatenator.h index 6fbe67a3..342c33c5 100644 --- a/modules/juce_audio_devices/native/juce_MidiDataConcatenator.h +++ b/modules/juce_audio_devices/native/juce_MidiDataConcatenator.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_devices/native/juce_android_Audio.cpp b/modules/juce_audio_devices/native/juce_android_Audio.cpp index ecfa7b94..79539882 100644 --- a/modules/juce_audio_devices/native/juce_android_Audio.cpp +++ b/modules/juce_audio_devices/native/juce_android_Audio.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -478,19 +478,4 @@ private: extern bool isOboeAvailable(); extern bool isOpenSLAvailable(); -AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_Android() -{ - #if JUCE_USE_ANDROID_OBOE - if (isOboeAvailable()) - return nullptr; - #endif - - #if JUCE_USE_ANDROID_OPENSLES - if (isOpenSLAvailable()) - return nullptr; - #endif - - return new AndroidAudioIODeviceType(); -} - } // namespace juce diff --git a/modules/juce_audio_devices/native/juce_android_HighPerformanceAudioHelpers.h b/modules/juce_audio_devices/native/juce_android_HighPerformanceAudioHelpers.h new file mode 100644 index 00000000..c87d6aea --- /dev/null +++ b/modules/juce_audio_devices/native/juce_android_HighPerformanceAudioHelpers.h @@ -0,0 +1,131 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + To use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ + +//============================================================================== +/** + Some shared helpers methods for using the high-performance audio paths on + Android devices (OpenSL and Oboe). + + @tags{Audio} +*/ +namespace AndroidHighPerformanceAudioHelpers +{ + //============================================================================== + static double getNativeSampleRate() + { + return audioManagerGetProperty ("android.media.property.OUTPUT_SAMPLE_RATE").getDoubleValue(); + } + + static int getNativeBufferSizeHint() + { + // This property is a hint of a native buffer size but it does not guarantee the size used. + auto deviceBufferSize = audioManagerGetProperty ("android.media.property.OUTPUT_FRAMES_PER_BUFFER").getIntValue(); + + if (deviceBufferSize == 0) + return 192; + + return deviceBufferSize; + } + + static bool isProAudioDevice() + { + static bool isSapaSupported = SystemStats::getDeviceManufacturer().containsIgnoreCase ("SAMSUNG") + && DynamicLibrary().open ("libapa_jni.so"); + + return androidHasSystemFeature ("android.hardware.audio.pro") || isSapaSupported; + } + + static bool hasLowLatencyAudioPath() + { + return androidHasSystemFeature ("android.hardware.audio.low_latency"); + } + + static bool canUseHighPerformanceAudioPath (int nativeBufferSize, int requestedBufferSize, int requestedSampleRate) + { + return ((requestedBufferSize % nativeBufferSize) == 0) + && (requestedSampleRate == getNativeSampleRate()) + && isProAudioDevice(); + } + + //============================================================================== + static int getMinimumBuffersToEnqueue (int nativeBufferSize, double requestedSampleRate) + { + if (canUseHighPerformanceAudioPath (nativeBufferSize, nativeBufferSize, (int) requestedSampleRate)) + { + // see https://developer.android.com/ndk/guides/audio/opensl/opensl-prog-notes.html#sandp + // "For Android 4.2 (API level 17) and earlier, a buffer count of two or more is required + // for lower latency. Beginning with Android 4.3 (API level 18), a buffer count of one + // is sufficient for lower latency." + return (getAndroidSDKVersion() >= 18 ? 1 : 2); + } + + // not using low-latency path so we can use the absolute minimum number of buffers to queue + return 1; + } + + static int buffersToQueueForBufferDuration (int nativeBufferSize, int bufferDurationInMs, double sampleRate) noexcept + { + auto maxBufferFrames = static_cast<int> (std::ceil (bufferDurationInMs * sampleRate / 1000.0)); + auto maxNumBuffers = static_cast<int> (std::ceil (static_cast<double> (maxBufferFrames) + / static_cast<double> (nativeBufferSize))); + + return jmax (getMinimumBuffersToEnqueue (nativeBufferSize, sampleRate), maxNumBuffers); + } + + static int getMaximumBuffersToEnqueue (int nativeBufferSize, double maximumSampleRate) noexcept + { + static constexpr int maxBufferSizeMs = 200; + + return jmax (8, buffersToQueueForBufferDuration (nativeBufferSize, maxBufferSizeMs, maximumSampleRate)); + } + + static Array<int> getAvailableBufferSizes (int nativeBufferSize, Array<double> availableSampleRates) + { + auto minBuffersToQueue = getMinimumBuffersToEnqueue (nativeBufferSize, getNativeSampleRate()); + auto maxBuffersToQueue = getMaximumBuffersToEnqueue (nativeBufferSize, findMaximum (availableSampleRates.getRawDataPointer(), + availableSampleRates.size())); + + Array<int> bufferSizes; + + for (int i = minBuffersToQueue; i <= maxBuffersToQueue; ++i) + bufferSizes.add (i * nativeBufferSize); + + return bufferSizes; + } + + static int getDefaultBufferSize (int nativeBufferSize, double currentSampleRate) + { + static constexpr int defaultBufferSizeForLowLatencyDeviceMs = 40; + static constexpr int defaultBufferSizeForStandardLatencyDeviceMs = 100; + + auto defaultBufferLength = (hasLowLatencyAudioPath() ? defaultBufferSizeForLowLatencyDeviceMs + : defaultBufferSizeForStandardLatencyDeviceMs); + + auto defaultBuffersToEnqueue = buffersToQueueForBufferDuration (nativeBufferSize, defaultBufferLength, currentSampleRate); + return defaultBuffersToEnqueue * nativeBufferSize; + } +} + +} // namespace juce diff --git a/modules/juce_audio_devices/native/juce_android_Midi.cpp b/modules/juce_audio_devices/native/juce_android_Midi.cpp index 2c63160d..94b687dd 100644 --- a/modules/juce_audio_devices/native/juce_android_Midi.cpp +++ b/modules/juce_audio_devices/native/juce_android_Midi.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -24,320 +24,319 @@ namespace juce { //============================================================================== -// This byte-code is generated from native/java/com/roli/juce/JuceMidiSupport.java with min sdk version 23 +// This byte-code is generated from native/java/com/rmsl/juce/JuceMidiSupport.java with min sdk version 23 // See juce_core/native/java/README.txt on how to generate this byte-code. static const uint8 javaMidiByteCode[] = -{31,139,8,8,116,138,97,92,0,3,74,97,118,97,68,101,120,66,121,116,101,67,111,100,101,46,100,101,120,0,149,124,9,124,219,197, -149,255,155,223,33,201,178,108,203,178,19,59,142,45,203,142,29,43,36,190,226,28,78,236,28,62,146,216,137,115,96,43,161,196,252,161, -138,173,36,10,182,228,88,114,14,216,46,161,7,9,45,44,148,35,77,41,165,180,92,225,40,176,20,10,109,129,210,66,91,216,101,129, -109,217,54,244,164,45,252,75,11,165,244,96,129,150,146,253,190,153,145,252,75,98,72,155,124,190,122,243,123,243,230,205,204,155, -55,111,222,252,164,100,56,182,207,219,212,178,144,238,255,216,139,247,126,127,96,206,252,159,157,251,212,223,22,175,248,196, -61,193,55,6,163,75,42,189,255,218,116,38,209,24,17,237,219,178,32,64,250,207,135,55,17,157,45,20,127,21,240,188,77,116,22,232, -43,46,162,16,232,187,94,162,123,152,230,18,229,128,166,11,137,174,95,78,116,13,52,188,93,79,244,87,224,239,128,209,64,100,3, -115,129,6,160,21,88,9,116,3,107,129,77,192,54,224,6,224,23,192,223,128,247,0,163,145,200,13,132,129,141,64,63,240,33,224,124,224, -34,224,114,224,38,224,86,224,14,224,30,224,126,224,235,192,163,192,227,192,83,192,31,128,226,38,162,197,192,54,224,106,224, -49,224,85,192,223,76,212,6,156,11,92,12,220,13,252,0,120,29,40,152,79,180,12,216,6,92,10,124,25,248,57,80,210,66,180,4,56,23,184, -24,56,12,220,5,124,7,120,1,248,61,96,44,128,237,128,79,1,143,2,127,2,66,11,137,18,192,253,192,111,128,105,139,136,22,1,91,129, -11,128,207,3,15,3,199,128,63,0,198,98,244,5,204,5,86,0,91,128,52,112,53,112,59,240,24,96,183,18,53,1,221,192,135,128,81,224, -98,224,48,112,23,240,8,240,44,96,45,65,127,64,24,88,1,244,3,215,2,183,3,15,2,63,7,126,9,188,12,252,14,120,3,120,27,120,23, -16,75,177,14,64,62,80,4,148,2,65,160,6,152,11,204,7,22,1,75,128,101,64,7,176,10,136,3,71,128,71,129,31,0,175,0,111,2,162,141,200, -11,20,0,165,192,108,160,5,88,1,172,1,206,6,38,128,75,129,207,1,255,14,60,14,60,3,28,3,126,7,252,9,120,7,112,183,67,15,80,9, -204,6,234,129,69,64,23,176,30,216,10,12,1,187,129,125,192,133,192,65,224,10,224,179,192,77,192,125,192,55,129,103,128,31,3,47,3, -127,4,222,1,172,101,208,15,172,0,122,129,17,224,114,224,26,224,75,192,221,192,253,192,55,129,39,128,231,128,159,1,239,0,211, -177,23,234,129,78,224,28,32,5,124,4,184,18,248,28,112,39,240,32,240,24,240,42,240,39,224,29,192,88,129,185,0,27,129,253,192,53, -192,93,192,3,192,183,129,255,6,126,13,252,30,120,23,200,91,137,249,3,97,96,49,176,18,88,11,108,2,6,129,115,129,33,32,14,140, -1,23,2,135,128,107,129,27,128,219,128,251,129,71,129,39,129,31,2,63,1,126,13,252,1,120,27,120,15,240,118,16,85,0,245,192,82,96, -57,208,5,244,0,27,128,205,192,121,64,12,216,5,140,3,151,0,95,0,30,0,158,6,94,6,222,2,188,157,68,51,128,57,192,74,224,76,96, -39,176,27,184,8,248,52,112,39,240,53,224,123,192,179,192,203,192,95,1,87,23,124,25,104,0,122,128,115,128,17,96,47,112,49,112,25, -112,53,240,5,224,86,224,27,192,143,128,55,128,255,5,222,5,220,221,68,133,192,76,96,46,176,16,232,6,54,0,231,2,49,96,23,240, -81,224,147,192,97,224,38,224,81,224,187,192,179,192,143,128,159,1,191,2,222,4,188,8,146,69,64,5,80,11,204,5,214,0,103,2,219,128, -36,112,17,112,25,112,21,240,89,224,102,224,43,192,55,128,111,1,255,9,252,16,248,41,240,18,240,7,224,109,192,88,13,123,1,11, -128,13,192,102,160,0,49,183,24,168,6,102,1,53,64,45,48,27,168,3,194,192,28,224,12,96,46,48,15,64,56,38,132,86,66,72,36,132,63,66, -152,35,132,52,66,200,34,132,40,66,88,34,132,30,66,104,33,132,13,194,246,39,108,89,194,86,35,108,7,130,91,19,92,142,176,132, -132,165,32,152,146,186,245,249,128,33,209,26,160,7,232,5,214,2,235,128,62,96,61,176,1,216,8,224,88,33,28,55,212,15,12,0,17,96,11, -240,33,96,16,248,127,192,121,124,254,0,219,128,97,32,6,108,7,70,128,127,1,46,2,14,0,23,3,31,5,62,6,124,156,148,77,50,127, -252,154,142,97,226,133,186,188,15,229,50,80,67,63,115,217,212,229,74,93,30,211,50,150,230,87,233,242,1,205,247,56,228,113,4,210,101, -154,159,171,249,51,129,60,224,26,205,207,119,244,85,224,40,7,28,242,197,90,158,203,165,142,182,101,142,190,202,245,216,88, -38,168,101,42,117,121,76,151,25,215,107,153,106,45,83,161,203,55,207,83,178,92,190,75,203,215,56,218,214,234,182,220,15,251,208, -67,122,12,13,142,113,54,58,198,214,228,24,27,151,31,155,167,242,2,46,63,57,111,146,159,177,103,179,67,79,179,99,252,92,126, -206,81,206,204,113,129,163,175,86,71,95,236,147,199,52,127,169,230,179,95,44,211,229,81,93,230,182,9,93,126,17,229,164,46,191,50, -79,229,52,92,254,11,202,187,117,217,194,230,216,167,203,62,148,199,117,185,20,229,148,46,135,80,222,163,203,243,80,222,171, -203,11,28,229,149,245,147,58,251,28,229,235,29,125,69,28,252,115,28,253,14,59,248,99,142,242,62,71,191,7,28,252,67,142,182,87,162, -188,63,211,151,67,254,40,202,23,232,242,189,142,182,207,57,198,195,107,151,145,127,210,193,31,115,148,31,118,244,245,4,202, -19,25,61,40,95,168,203,199,28,182,122,17,229,180,46,191,86,175,246,237,114,189,70,31,209,101,94,163,127,213,101,182,127,166,252, -152,131,159,241,159,14,221,150,203,157,14,127,232,114,248,67,183,230,207,212,229,107,164,207,55,209,131,164,232,10,193,109, -10,232,50,217,182,153,174,144,116,49,93,37,169,135,150,9,246,225,82,250,20,175,53,122,127,69,82,65,191,151,180,150,170,100,253, -108,154,43,56,46,20,75,185,42,205,175,210,252,89,250,153,233,38,193,123,204,162,207,16,83,63,253,69,82,85,95,163,235,107, -245,120,106,17,121,15,75,218,73,119,74,90,66,127,146,116,1,189,165,235,203,133,162,65,161,246,232,237,196,116,57,253,142,116,220, -23,28,251,43,233,211,92,134,228,155,196,177,206,67,79,72,106,210,119,37,181,233,199,196,177,206,77,95,144,180,154,30,209, -244,121,94,7,156,24,159,215,244,30,73,45,250,158,164,27,104,33,244,219,224,187,137,227,96,15,245,10,166,139,104,189,224,59,128,226, -123,179,212,75,71,36,205,161,85,168,247,105,61,121,186,62,15,156,35,146,230,82,151,80,180,91,112,140,204,163,111,17,211,42, -250,9,113,28,87,227,241,35,146,62,35,105,1,149,8,166,126,154,41,56,182,171,113,115,140,255,161,166,63,37,21,95,255,75,210,126,58, -38,105,33,189,160,249,92,95,172,245,22,227,148,90,9,61,211,244,184,74,112,42,61,37,105,19,77,19,76,151,210,116,73,151,81,179, -164,237,180,69,112,156,86,237,75,97,255,27,52,101,123,205,208,122,202,48,254,135,137,227,105,128,190,70,28,135,13,186,69,250, -225,42,89,207,126,167,168,160,199,37,173,165,255,148,116,51,125,95,210,53,36,164,191,206,165,66,73,231,81,64,210,51,169,70, -210,181,180,86,210,213,180,89,250,229,74,169,47,164,199,197,244,126,73,149,125,66,136,228,63,147,116,61,189,170,235,243,100,187, -62,42,146,116,29,117,10,197,239,209,180,79,250,245,10,169,183,74,235,173,210,122,171,180,222,42,173,175,74,183,175,210,237, -171,116,251,106,221,174,90,203,87,107,249,106,45,95,173,229,171,181,252,44,236,116,238,111,22,178,18,67,62,47,32,83,83,75,210,249, -100,75,186,144,92,154,186,53,63,95,211,2,73,155,201,175,105,177,220,111,157,82,111,13,250,191,78,210,106,250,182,164,46,250, -15,82,103,225,211,146,158,65,75,229,62,83,235,83,171,231,91,11,79,121,64,210,25,244,85,73,103,211,163,146,170,245,171,133,223, -60,41,233,22,122,86,210,205,244,156,166,255,45,105,17,253,64,210,26,250,31,73,103,210,143,36,93,66,30,217,95,43,229,104,234, -21,138,159,43,105,27,249,132,138,7,165,146,78,167,25,146,150,82,153,164,27,169,90,210,70,154,37,105,23,181,72,186,154,34,50,78, -212,203,121,204,70,230,117,175,142,19,191,144,241,225,12,204,92,81,183,164,211,232,155,146,150,209,99,196,103,253,92,201,111, -212,242,208,78,3,130,105,5,125,72,240,217,174,218,53,105,251,52,193,211,191,67,124,134,171,126,154,97,231,223,18,231,150,221, -82,174,5,158,207,251,97,129,110,183,0,114,135,244,243,245,250,249,70,73,235,232,53,253,60,95,168,60,96,141,164,17,234,23,156, -163,134,233,114,226,60,85,233,89,164,219,47,130,252,23,37,173,148,253,44,66,246,251,134,164,33,106,18,138,207,250,22,235,118, -139,117,255,139,117,63,139,117,63,139,117,63,173,24,255,207,137,105,144,222,35,206,59,212,184,150,106,218,166,245,180,33,219, -93,46,56,63,86,207,237,218,191,248,108,2,91,190,27,33,25,23,112,150,33,17,63,130,68,248,218,13,42,15,19,174,201,60,138,235,175, -68,253,51,27,212,115,72,183,103,254,135,231,41,122,35,234,127,167,235,171,116,125,147,163,254,33,212,207,222,168,234,103,105, -189,182,67,255,115,168,239,215,245,53,154,223,238,168,127,17,245,151,234,250,90,173,127,26,176,83,235,127,3,245,247,234,250,217, -186,157,115,252,43,33,23,222,164,158,235,28,227,203,212,111,66,125,167,174,231,28,252,195,184,24,236,88,175,228,198,53,189, -120,253,100,221,85,142,242,13,186,254,118,7,239,62,93,126,4,244,9,71,249,217,245,42,151,103,153,31,3,47,235,182,111,104,42,54,40, -26,208,180,78,211,118,77,7,52,29,222,48,217,215,94,205,251,232,6,214,109,200,242,185,171,213,61,99,204,159,135,231,106,248, -206,152,255,75,120,30,244,91,136,250,131,126,131,6,3,6,206,45,150,103,61,201,213,234,158,16,65,205,110,255,37,196,167,98,34,52, -130,181,246,202,187,129,165,229,246,172,86,119,136,221,178,23,159,72,132,12,236,39,200,250,109,249,204,231,129,137,58,150,253, -216,106,117,230,69,66,22,69,170,44,200,220,130,26,175,152,133,11,110,34,116,43,198,231,131,47,118,75,25,91,102,1,200,27,209, -102,58,219,220,127,59,250,244,137,113,255,109,220,198,104,53,242,192,59,138,50,183,241,81,32,144,104,90,2,79,10,191,145,175, -71,134,117,88,173,236,192,247,26,151,156,25,238,217,171,213,189,49,80,56,191,216,166,64,85,75,113,33,198,81,136,254,124,216,63, -185,20,105,230,113,241,45,202,103,36,66,55,193,119,3,29,45,197,149,136,95,211,168,204,56,159,118,135,154,193,155,108,17,56, -169,197,205,178,214,210,182,104,71,36,205,151,115,225,190,191,179,90,221,107,156,182,234,128,22,68,79,173,255,43,90,127,64,20,136, -72,179,178,188,144,146,255,34,45,21,126,211,11,77,172,253,127,86,171,119,156,129,146,128,75,235,131,30,47,149,89,208,99,231, -73,61,17,244,157,144,151,75,159,88,34,50,117,62,93,23,254,83,107,206,66,170,54,188,240,4,182,89,153,101,161,191,38,182,178,149, -8,249,113,6,85,155,121,168,11,192,114,137,80,49,178,101,230,79,195,45,215,103,5,106,185,20,161,89,233,149,232,161,0,173,125, -246,122,219,114,237,246,95,167,218,251,139,208,202,103,39,86,230,82,199,39,194,143,36,66,62,220,128,195,95,163,172,127,229,172, -81,119,210,19,253,235,34,248,87,62,242,52,151,242,249,53,234,30,58,230,111,64,155,193,89,57,52,88,227,162,193,90,47,109,157, -237,129,229,207,9,185,229,218,218,210,191,4,205,94,163,98,73,192,140,116,184,168,85,184,137,105,194,63,23,117,145,142,28,112,114, -36,141,116,122,209,215,191,194,206,131,93,208,217,229,130,150,60,189,2,1,189,2,225,87,84,60,98,221,66,212,227,248,18,114,76, -109,232,131,99,103,194,207,25,127,210,127,153,246,175,140,143,119,173,81,113,52,18,66,63,85,220,207,184,244,235,66,25,71,132,244, -203,222,53,106,175,6,96,57,161,121,27,215,76,250,106,62,230,207,119,247,205,107,212,222,90,150,235,163,129,139,61,228,62,224, -190,90,220,44,30,176,190,187,199,211,161,101,45,125,251,143,57,218,27,122,44,187,215,168,152,24,241,231,40,79,245,195,42,144, -216,236,119,75,95,225,231,68,104,30,198,23,240,159,227,119,159,208,246,130,15,104,219,154,109,91,207,109,41,211,150,199,194, -99,248,152,94,219,49,63,223,58,6,133,143,6,141,92,26,132,55,229,103,215,234,106,199,90,229,234,181,202,133,85,103,201,181,242, -233,181,242,97,173,242,178,107,5,61,93,185,255,196,90,29,205,174,85,239,148,107,117,111,118,173,208,79,85,222,148,107,245, -213,204,90,193,19,221,122,134,15,131,87,196,237,154,245,200,65,19,43,107,168,35,54,57,182,14,161,199,246,150,122,39,163,199,230, -205,172,247,15,28,235,149,225,189,224,224,153,114,148,200,103,214,168,247,56,131,162,0,246,100,171,14,26,249,50,78,171,183, -65,175,58,218,100,124,225,205,41,120,162,199,25,11,45,57,167,188,30,21,143,3,161,22,187,0,62,144,128,207,154,176,6,71,13,15,239, -95,196,157,143,200,219,204,164,158,242,158,83,117,135,167,224,45,152,130,183,178,231,196,249,241,159,190,41,120,91,28,60,91, -90,14,231,90,15,71,8,182,67,17,236,240,101,105,7,156,91,102,33,13,90,60,66,75,90,209,164,221,61,234,61,80,185,81,67,21,70,64,12, -54,7,176,242,119,163,6,62,219,236,199,122,21,72,154,128,207,10,93,226,104,195,146,126,60,23,66,194,43,105,194,95,170,249,133, -20,52,112,215,19,65,163,78,228,137,240,91,60,155,25,168,171,148,227,51,101,254,225,146,62,53,231,162,250,121,115,116,217,160, -127,235,81,57,105,185,137,177,152,145,126,232,54,102,17,211,132,127,6,199,76,145,240,87,203,211,44,176,160,165,115,58,184,85, -28,237,141,50,235,106,248,98,35,34,48,159,109,38,246,155,39,123,194,4,205,66,160,12,203,23,126,55,15,165,58,67,229,15,179,209, -178,94,251,146,192,253,43,227,191,119,245,168,250,136,223,159,245,107,174,185,175,39,115,190,171,209,200,248,235,87,111,10, -213,249,174,246,233,67,61,124,143,196,28,4,230,32,34,77,1,140,38,143,34,77,133,124,7,32,126,142,204,135,134,208,30,68,238,160,96, -255,15,138,58,82,125,22,201,190,138,177,111,212,89,254,120,143,122,135,26,176,198,252,181,176,220,96,164,152,6,183,20,195,34, -197,84,102,254,25,90,74,112,35,242,25,149,70,9,13,246,151,128,95,66,75,112,62,149,25,216,81,230,78,185,219,113,115,194,153,181, -8,62,240,57,62,19,250,103,224,105,1,158,174,146,79,165,39,212,149,157,240,52,77,234,75,248,103,179,229,169,202,12,24,11,231, -123,105,53,166,153,8,165,17,235,142,25,6,214,86,202,52,205,161,126,43,252,180,71,159,85,111,244,168,220,51,50,84,138,246,135,121, -103,88,156,135,88,228,53,91,205,38,153,135,88,114,220,65,138,32,168,85,154,126,105,83,115,114,133,205,192,194,150,129,223,28, -215,43,108,150,217,106,133,7,178,43,252,194,113,189,194,102,34,244,111,56,107,89,243,179,199,11,141,128,17,126,207,165,199,49, -173,87,189,31,143,116,150,65,255,23,120,30,198,184,255,14,77,111,3,229,86,51,229,120,12,169,185,145,34,93,144,13,221,32,199, -82,137,53,76,248,135,228,8,184,151,1,41,255,210,241,66,17,16,225,247,56,206,40,239,105,234,85,239,218,203,237,90,170,176,35,105, -158,245,17,158,173,53,171,179,147,207,130,180,178,3,230,236,18,50,35,115,161,174,213,154,46,123,118,65,123,165,25,164,99,136, -119,17,92,137,42,45,101,13,206,11,214,91,134,16,34,252,155,160,93,104,228,89,65,187,206,98,191,104,144,189,54,74,63,225,191,59, -122,213,59,250,114,11,253,195,87,70,57,215,50,7,7,166,83,208,154,92,237,68,232,124,138,241,76,212,138,152,60,14,83,142,35,40, -199,161,102,60,91,70,245,105,50,119,185,26,59,42,225,255,40,175,135,181,219,127,169,206,116,152,27,254,85,158,25,180,234,76,158, -39,91,113,86,19,103,164,159,101,43,98,46,200,72,77,30,39,71,140,197,217,61,182,136,92,122,55,93,165,215,165,220,192,120,141, -72,135,178,142,152,28,147,104,21,165,153,49,97,85,130,242,182,91,41,148,93,100,126,231,175,148,249,93,203,153,175,28,15,26,28, -111,2,20,254,187,138,56,106,47,213,201,158,194,196,121,39,247,123,103,175,250,14,162,220,139,62,189,173,254,98,10,204,72,52, -165,232,250,60,31,214,116,3,69,190,53,3,51,248,60,114,113,238,221,141,85,11,122,11,41,48,39,252,122,127,243,76,26,11,237,198,29, -216,231,110,117,47,161,200,30,140,197,133,200,232,106,129,84,43,252,181,191,185,2,109,103,34,239,246,33,207,206,193,109,33, -68,238,111,89,47,237,113,241,27,210,86,204,128,181,87,91,45,208,115,37,172,152,104,186,145,154,173,160,55,252,28,70,236,173,19, -170,125,25,183,247,180,122,126,123,188,26,231,224,24,130,255,99,173,225,95,5,189,152,217,195,36,239,243,93,152,17,127,247, -162,178,160,53,210,255,120,253,231,129,201,239,23,3,174,72,10,187,49,116,6,246,131,242,133,72,106,26,108,118,61,159,82,41,181,7, -212,202,223,33,179,77,182,182,45,125,186,68,90,219,150,30,208,168,100,177,7,138,228,106,242,30,216,6,249,240,111,213,154,7, -204,65,212,7,161,123,198,201,26,29,187,188,204,177,203,103,147,148,133,198,89,82,99,11,218,125,90,182,171,52,171,33,183,137,181, -255,122,112,207,12,200,77,21,49,170,51,186,148,47,152,130,90,17,49,152,86,154,150,60,153,76,199,147,75,62,101,162,74,41,235, -254,137,210,123,13,202,156,213,112,246,197,121,204,28,216,111,129,206,111,176,139,169,64,223,21,182,173,85,239,167,39,247,78,228, -135,211,169,106,71,192,20,11,23,78,180,96,175,185,236,132,63,196,209,199,83,117,41,184,11,22,94,83,131,200,232,65,30,31,148, -209,171,229,215,211,169,218,59,59,115,66,228,6,138,90,150,195,155,138,18,254,10,174,247,141,173,60,64,95,127,156,247,210,151,232, -152,105,9,177,32,252,139,128,25,254,227,49,211,22,98,97,248,153,66,195,214,123,251,208,90,181,87,2,161,114,129,21,133,231,95, -193,86,49,150,24,33,120,83,28,62,193,62,135,155,153,63,200,39,245,252,105,210,139,59,229,141,207,141,179,37,252,191,234,132,25, -11,237,210,178,22,115,95,13,138,128,204,3,121,190,51,49,38,158,77,142,180,67,69,54,167,253,252,90,229,119,1,255,88,40,33,111, -142,133,217,186,155,50,117,161,201,186,128,30,243,237,107,213,247,123,30,240,54,123,202,169,213,179,1,247,46,181,243,60,200,143, -34,185,176,230,195,1,143,184,116,225,83,107,97,183,220,156,128,161,119,180,135,219,244,231,205,164,150,99,75,136,109,12,205, -121,85,63,15,120,22,190,210,76,171,173,60,15,91,24,243,119,181,236,97,235,86,72,15,145,109,10,42,168,229,207,229,224,149,179,167, -216,108,39,248,54,246,83,126,38,79,240,148,229,252,77,158,34,71,80,95,105,55,243,14,183,3,117,225,251,143,121,60,34,252,220, -49,79,142,16,151,134,31,12,122,203,144,28,135,255,156,231,193,222,244,112,6,217,143,214,31,206,198,177,243,178,119,227,226,117, -234,59,56,142,172,93,50,42,201,40,230,184,115,23,56,238,220,179,101,44,133,55,24,45,253,111,28,103,107,241,25,98,105,159,155, -179,78,221,221,248,252,227,220,43,208,220,226,55,225,167,17,156,241,1,145,88,25,166,166,64,248,29,126,167,109,200,28,170,5,242, -55,114,60,203,131,85,243,210,98,6,239,86,15,91,209,3,235,4,220,129,28,190,241,69,124,101,184,45,126,146,207,152,124,246,139, -215,224,123,75,124,231,202,94,32,231,11,44,111,121,173,137,35,33,44,228,33,159,175,44,95,157,179,175,73,11,225,156,181,213,237, -28,145,193,82,250,148,127,245,161,109,171,175,157,38,121,55,128,231,115,87,186,45,7,239,139,224,85,231,214,72,142,7,254,230, -49,144,139,158,21,165,220,170,83,198,134,136,248,90,110,117,126,27,246,219,157,152,117,107,78,19,21,249,158,115,95,252,152,237, -231,156,17,59,121,229,93,244,168,63,152,151,159,25,143,143,117,240,14,120,140,124,222,86,47,188,234,46,65,238,199,42,97,77, -55,226,180,71,198,5,183,140,7,110,74,227,60,41,162,96,94,248,151,121,190,96,94,157,175,200,55,76,225,239,231,249,194,111,241,89, -49,129,21,226,239,215,216,155,14,103,115,185,35,226,162,250,27,196,17,193,121,159,33,115,237,7,215,169,239,225,202,221,176, -185,155,207,34,47,78,116,182,57,206,115,35,114,88,205,199,224,117,128,141,46,193,58,180,186,16,77,15,35,246,132,174,165,91,241, -188,196,85,75,39,202,221,0,57,159,171,210,197,81,118,88,230,2,39,214,127,17,245,172,161,218,19,164,177,166,249,116,212,228, -168,113,9,5,221,249,164,71,96,241,234,113,110,81,230,81,171,119,137,140,227,88,61,81,46,173,37,100,174,42,169,139,45,22,199,234, -182,218,240,173,1,21,51,91,77,143,142,162,42,122,114,212,244,82,248,217,60,87,248,191,242,92,65,119,157,75,157,169,156,87,140, -233,120,185,87,238,7,68,169,139,234,211,123,104,143,180,17,199,6,119,159,250,158,191,28,51,173,144,182,241,146,215,230,243,243, -108,249,254,103,125,54,54,71,4,122,23,22,5,138,3,211,90,144,248,4,172,200,181,234,68,177,229,217,116,135,166,242,140,194,138, -190,126,92,159,81,242,68,233,175,155,73,90,187,167,229,224,235,199,101,91,88,179,86,122,174,58,97,108,89,86,39,12,34,100,113, -248,233,86,225,209,55,25,117,139,137,92,203,107,243,25,212,6,93,200,197,237,160,171,206,86,115,61,91,238,245,173,217,119,99, -107,251,78,188,15,242,253,185,191,47,27,31,55,93,72,243,35,62,153,109,24,178,238,156,62,117,15,229,119,113,1,99,172,255,66,234, -242,115,125,142,220,239,6,13,247,169,223,84,4,138,56,246,241,174,225,53,226,111,45,57,35,51,169,192,80,39,56,191,67,116,195, -130,173,54,162,185,21,126,19,119,24,171,206,136,140,79,35,221,202,14,184,120,247,244,187,34,227,197,224,77,151,217,109,96,90,181, -107,22,252,101,11,237,113,39,86,226,4,140,249,144,213,96,197,29,237,100,43,17,180,196,252,240,127,240,189,245,32,133,255,170, -222,121,122,49,83,254,158,117,174,180,65,105,54,70,93,222,167,222,15,100,98,82,29,98,146,186,135,42,43,29,214,246,136,248,103, -200,221,207,239,166,148,95,88,244,133,62,245,219,15,158,163,87,238,12,142,110,106,39,69,14,171,168,114,171,228,227,30,115,88, -69,148,91,229,90,195,63,13,181,106,134,92,53,67,215,127,17,245,124,170,221,46,189,57,128,186,24,123,138,204,86,236,236,46,163, -236,46,98,207,135,44,172,11,223,235,58,225,214,225,74,132,246,98,87,168,108,33,232,14,223,175,188,62,79,148,185,112,147,242, -20,201,155,212,37,56,19,212,123,154,110,88,101,131,190,127,159,169,227,197,89,58,223,53,104,224,162,250,45,3,217,119,59,127,238, -115,190,219,57,91,204,164,115,140,114,58,219,172,144,111,173,212,173,211,92,175,222,201,7,196,18,196,220,2,156,35,151,203,204, -137,41,103,242,45,243,223,58,238,222,196,39,72,127,103,5,245,163,109,203,252,215,143,111,238,44,167,205,102,57,202,175,28,239, -239,156,9,62,78,205,249,191,58,30,40,12,255,34,243,142,15,231,197,122,245,125,68,53,238,11,253,29,51,233,251,129,3,160,21,84, -100,30,160,133,205,69,178,124,111,213,88,232,32,199,88,255,33,121,62,109,238,192,153,141,157,18,248,227,125,85,5,162,72,92,68, -225,63,64,235,95,213,13,25,103,227,122,237,247,176,89,37,16,196,92,50,239,144,26,215,171,156,66,205,55,95,199,82,131,22,172, -215,239,175,196,228,219,87,147,10,133,126,223,138,179,242,111,199,203,141,58,220,7,182,137,32,45,17,200,162,69,37,214,172,5,25, -121,28,156,160,228,135,95,201,228,248,133,82,135,208,223,149,8,153,193,152,186,175,13,235,213,119,52,101,164,238,200,134,236, -205,146,223,19,151,35,23,170,16,219,80,191,132,56,83,175,69,31,59,208,150,103,18,148,252,240,235,153,59,121,158,238,163,34,219, -71,185,252,13,172,252,158,65,219,130,231,122,99,64,125,199,116,20,244,222,236,175,108,213,159,135,245,115,70,158,127,99,245, -36,120,207,157,196,95,171,249,63,61,169,253,43,39,61,255,37,160,250,204,252,134,137,223,57,90,69,234,183,69,197,69,234,187,152, -242,34,245,155,9,31,232,78,173,55,14,90,131,231,243,65,231,21,169,223,126,44,0,109,47,58,81,127,207,73,207,130,244,247,89,164, -98,25,83,254,45,143,33,105,179,140,149,5,200,150,109,93,87,238,152,147,32,149,211,24,250,201,212,116,57,77,254,78,43,243,61, -146,33,105,147,124,158,173,249,93,89,57,159,110,171,126,101,162,250,90,145,109,47,247,80,22,211,101,236,50,180,141,76,135,173, -20,207,165,121,46,201,83,101,119,86,87,142,166,126,77,3,90,38,160,245,50,175,136,38,191,63,147,239,25,100,6,173,108,207,178, -252,125,242,108,221,47,127,151,59,91,239,197,90,252,181,52,245,235,248,176,68,183,89,162,239,36,44,215,174,247,210,114,93,183, -66,143,223,202,150,229,172,195,100,134,123,113,135,153,67,53,77,45,157,173,77,171,22,118,212,175,234,94,213,90,191,160,179,165, -165,190,99,241,194,230,250,69,93,171,90,22,172,234,90,208,181,184,9,166,69,190,214,62,52,18,79,196,211,203,201,213,174,168, -177,188,141,172,229,109,115,182,240,39,202,254,206,145,137,88,58,153,76,239,92,31,77,68,119,196,198,105,233,201,156,80,108,124, -60,57,190,52,52,148,156,24,25,14,37,146,233,208,142,88,58,148,149,10,245,173,10,165,134,162,137,4,218,174,248,199,218,14,199, -182,71,39,70,156,58,162,195,209,177,52,20,148,117,79,140,142,238,207,242,215,68,211,233,174,232,200,200,182,232,208,249,36,122, -201,232,237,35,179,183,175,143,42,123,55,134,86,237,27,138,141,165,227,73,4,243,157,241,145,88,104,104,36,153,138,39,118,132, -198,146,227,105,170,237,221,248,126,245,163,241,225,56,134,176,39,62,20,35,177,150,172,181,155,187,86,81,225,218,137,161,216, -122,212,244,38,198,38,210,155,88,69,32,195,218,56,145,206,240,124,25,158,124,42,206,60,13,76,140,113,175,13,187,162,123,162, -36,250,200,232,235,37,179,175,87,126,160,7,124,32,179,192,176,205,62,124,88,125,125,91,251,168,166,47,154,24,30,79,198,135,27, -183,101,102,219,152,157,119,135,50,71,27,205,250,32,169,110,57,135,54,170,250,32,33,54,97,27,205,57,157,72,198,202,109,212, -120,90,209,157,209,241,232,16,134,23,79,165,227,67,109,52,247,116,13,186,99,169,161,241,248,88,58,57,62,245,64,70,98,147,242,125, -177,1,229,75,83,207,29,162,92,63,57,218,247,209,199,66,171,227,35,24,100,77,231,68,124,100,152,245,77,101,166,19,68,63,80,164, -63,150,130,203,78,61,91,45,50,16,75,167,225,96,169,201,46,63,96,10,25,225,54,154,145,21,26,74,38,210,177,68,186,177,139,233, -62,116,86,153,173,26,141,13,199,163,141,236,186,141,236,112,153,165,159,247,193,2,189,137,237,201,26,118,85,46,56,135,243,190, -210,109,84,251,193,66,3,233,104,122,2,163,174,126,63,177,236,6,114,186,210,73,50,58,58,212,40,149,147,171,185,248,116,13,54, -38,84,147,141,99,177,68,108,184,15,30,24,147,190,18,58,77,195,15,152,251,228,238,118,174,255,73,66,253,177,161,88,124,15,235, -41,202,138,36,83,141,157,19,137,225,17,44,67,177,147,217,19,101,38,68,75,156,220,77,209,241,161,216,200,230,137,248,112,27,5, -178,21,19,233,248,72,99,95,114,199,41,188,77,209,248,184,163,175,44,175,141,54,159,202,108,63,141,155,156,54,62,224,32,104, -234,27,74,142,54,142,39,71,226,141,187,16,213,26,79,10,109,53,39,71,246,54,106,62,77,139,83,34,106,27,205,255,7,155,56,215,100, -222,63,216,70,73,247,157,70,122,210,42,89,31,124,223,19,167,141,186,255,105,109,147,28,118,209,72,52,117,254,233,13,117,138, -150,211,79,58,51,225,77,209,244,78,14,19,31,40,205,155,117,56,58,178,39,126,126,35,66,107,18,27,24,135,98,227,170,132,62,16,187, -70,162,41,108,232,224,20,50,189,28,137,117,125,213,20,245,235,99,163,219,180,64,12,34,21,83,136,12,196,119,36,16,49,198,177, -75,202,166,168,142,236,28,79,238,69,211,105,125,124,118,54,198,147,141,142,131,187,141,10,21,123,36,154,216,209,168,199,81,228, -96,245,34,78,74,123,5,28,204,141,219,118,197,134,210,39,242,6,210,227,152,105,182,27,201,147,93,71,183,241,254,45,119,176,199, -99,219,27,207,138,69,207,239,143,109,143,141,199,18,72,18,42,62,168,150,55,191,172,150,187,177,99,124,60,186,159,195,82,166, -167,19,185,109,212,53,21,187,253,159,89,237,229,124,232,77,169,228,148,233,46,207,26,97,82,52,117,34,175,39,154,194,142,30, -203,88,213,201,59,85,16,103,214,41,130,224,157,104,130,94,156,164,81,121,214,23,56,184,210,38,254,147,24,109,212,114,18,167,253, -180,7,240,242,19,245,202,238,11,29,140,72,124,148,29,98,218,201,44,181,21,11,79,217,107,212,113,10,107,234,164,213,113,154, -132,82,251,113,240,140,134,82,177,113,153,69,6,78,221,245,228,115,46,26,213,58,143,252,134,174,142,190,190,206,142,174,117,231, -69,206,222,180,234,188,245,29,145,174,158,243,250,54,14,68,72,108,33,99,11,178,198,45,200,115,173,45,189,91,123,201,181,101, -45,242,200,181,96,35,123,220,130,180,210,218,194,121,165,189,69,114,193,145,31,44,221,167,42,81,182,249,115,173,34,200,69,183, -108,37,129,244,19,202,12,228,157,198,96,39,85,15,158,62,21,170,31,252,167,82,139,154,127,64,28,123,119,112,138,125,122,2,51, -179,81,115,163,67,67,177,84,106,245,72,116,71,138,188,72,55,39,162,35,50,231,118,103,174,10,102,116,120,152,159,134,199,33,71, -62,221,123,111,98,56,182,15,173,213,147,108,225,141,142,141,233,140,138,92,209,148,242,196,109,39,165,218,84,150,229,244,173, -146,123,79,173,237,230,205,189,221,20,216,118,74,122,234,208,144,113,164,226,73,78,118,218,41,135,220,121,250,206,145,179,45, -221,161,71,237,217,150,86,114,16,211,165,20,31,232,48,1,185,182,165,249,48,34,123,27,103,147,228,27,210,167,82,100,255,88,140, -92,24,5,210,9,202,31,58,33,25,39,123,104,36,22,29,103,146,76,197,200,141,132,50,1,27,83,174,46,72,133,30,78,51,163,241,68,74, -178,101,105,93,108,191,20,150,54,242,233,66,36,185,25,58,108,236,130,68,154,196,48,121,135,179,121,60,185,244,92,60,138,194, -70,153,210,48,229,101,74,74,65,238,112,214,1,82,153,186,140,201,188,234,81,38,59,57,195,241,113,12,17,97,31,236,120,42,51,116, -87,108,55,150,62,69,57,114,83,118,37,135,97,192,88,230,128,160,134,237,81,92,237,134,67,233,100,104,104,60,22,77,199,66,219, -38,70,244,157,82,233,14,109,31,79,142,134,50,110,226,217,30,79,68,71,226,23,196,168,10,165,225,201,133,90,157,28,119,220,190,148, -112,37,139,100,54,244,84,2,246,246,248,56,156,201,183,29,38,26,206,44,184,151,59,84,110,76,214,14,54,120,14,127,42,99,152,136, -36,228,197,71,70,69,46,151,71,164,107,167,168,140,31,148,231,158,114,45,159,57,89,119,106,12,155,198,149,99,99,35,241,33,121, -170,102,188,189,8,236,83,6,93,234,100,58,115,122,169,229,212,139,24,121,192,150,103,47,21,162,212,173,238,238,153,109,147,35, -89,210,23,242,179,69,181,214,222,236,115,138,220,40,75,231,155,131,66,207,196,40,135,115,108,100,28,190,202,82,83,90,23,162,112, -44,73,134,165,6,214,75,213,40,240,1,121,138,49,54,68,71,153,217,219,157,162,186,83,101,100,22,122,138,96,248,84,65,149,123, -158,34,57,3,146,92,125,242,48,49,185,233,186,170,59,235,204,152,142,30,50,107,144,139,204,43,44,31,242,50,15,19,156,59,145,95,63, -242,49,193,205,186,165,189,149,63,72,209,241,228,88,108,60,29,71,63,5,120,236,143,141,38,211,177,76,208,0,99,64,30,69,58,90, -201,46,101,128,200,219,41,111,33,250,222,66,238,157,209,212,6,118,9,15,10,59,229,46,178,118,38,225,187,57,252,169,124,83,196,201, -140,15,239,35,43,206,102,182,227,114,17,115,226,217,247,33,185,241,84,118,242,252,208,165,118,104,12,19,141,167,86,141,142, -165,247,115,65,218,153,171,39,95,164,120,226,58,37,32,15,167,55,61,220,175,111,151,243,69,138,121,62,2,144,11,31,156,97,120,71, -146,136,117,42,144,187,71,181,135,91,124,158,144,119,52,107,102,42,28,61,101,27,228,143,158,176,10,148,59,234,8,196,198,232, -40,153,163,169,29,248,72,79,144,149,224,181,176,249,19,81,33,17,219,203,123,0,70,73,176,145,204,228,182,93,228,74,110,223,158, -194,112,2,201,68,103,52,61,180,115,50,7,73,81,9,246,216,9,129,23,79,137,29,176,68,241,201,21,236,230,52,237,100,238,89,227, -48,137,212,162,108,136,61,43,251,87,106,200,159,76,76,190,51,145,26,10,157,28,213,58,47,169,239,194,112,68,244,156,159,60,225,106, -204,125,58,159,187,99,35,209,253,96,23,100,216,236,72,123,156,114,42,8,100,38,226,78,38,86,143,76,164,118,146,47,153,88,159, -158,200,176,49,50,30,143,242,194,254,84,42,78,165,204,25,137,243,86,150,227,234,74,142,142,33,2,67,22,45,101,66,33,35,116,230, -73,89,16,198,69,54,148,144,246,210,174,155,234,230,152,143,43,54,100,139,224,242,137,147,98,20,121,153,169,203,121,92,158,116, -176,18,126,60,225,170,121,86,60,189,19,91,169,52,83,49,121,161,212,53,129,76,141,131,151,207,60,199,203,190,28,126,86,59,209, -147,204,228,117,57,153,18,2,20,6,199,135,88,114,178,137,157,220,203,33,179,104,12,238,119,242,4,202,166,96,14,164,99,99,145, -189,73,42,57,161,110,50,152,144,53,198,233,163,37,223,105,230,140,201,116,139,247,133,103,76,103,94,170,36,3,75,126,166,164,35, -150,172,145,217,103,94,166,164,54,186,172,144,81,34,63,83,138,36,87,227,172,35,123,76,206,214,228,45,60,125,60,182,131,223, -175,140,159,248,146,134,92,227,210,115,200,171,168,10,13,170,172,242,173,25,227,56,178,99,169,244,164,111,111,26,143,39,225,27, -251,185,173,92,126,247,184,222,72,96,164,247,68,71,200,26,103,95,50,199,39,18,84,152,202,102,161,250,61,26,21,165,28,217,115, -134,233,206,188,116,246,164,134,118,198,134,113,236,147,43,21,67,218,48,76,86,138,125,171,140,63,213,219,222,157,209,225,80,239, -198,208,100,222,224,225,58,54,51,21,96,143,119,57,83,171,92,48,216,83,215,115,144,204,231,7,157,9,78,196,135,81,185,147,47, -5,216,43,152,168,149,226,68,194,78,201,135,28,73,184,33,229,169,98,58,57,38,31,93,41,117,188,90,41,112,208,115,134,159,3,239,201, -172,114,122,103,28,198,224,207,154,38,84,224,194,130,70,163,99,228,78,39,229,173,141,60,233,164,206,41,166,77,36,166,242,174, -25,39,177,29,62,84,58,145,120,159,181,180,97,251,9,156,14,146,108,220,78,203,197,205,194,157,111,188,65,109,251,140,43,47,106, -171,167,141,226,147,96,80,175,36,7,77,58,44,44,254,71,96,249,116,155,16,100,89,15,25,75,135,221,249,199,77,122,208,200,219, -106,19,125,74,136,251,88,254,10,97,92,39,30,52,220,249,231,247,153,116,84,88,245,71,108,90,182,175,207,69,13,135,47,128,216,126, -169,238,144,84,215,176,47,68,17,241,61,195,61,15,162,87,8,179,193,168,216,107,236,168,232,51,197,167,69,78,195,39,27,182,154, -198,195,70,238,103,182,154,230,35,70,254,186,173,203,30,239,221,104,27,182,73,151,8,169,228,48,61,40,172,119,196,65,241,101,227, -87,120,108,175,199,159,118,250,181,32,119,197,134,15,175,219,95,95,111,76,84,84,154,244,21,209,64,223,6,51,191,189,157,14,25, -60,129,167,248,137,222,147,159,111,11,235,175,226,98,227,22,241,125,12,185,254,22,250,152,97,170,103,212,61,203,18,79,108,93, -70,47,100,10,215,26,166,234,80,117,71,79,24,83,116,118,131,161,58,123,65,118,118,139,252,124,96,82,237,134,243,140,11,51,162, -119,202,202,123,229,231,39,77,131,222,65,125,125,123,61,221,96,26,223,16,215,243,24,174,51,77,46,61,141,30,233,122,71,249,211, -92,126,218,120,15,50,203,214,125,134,110,228,199,219,84,213,151,28,229,163,92,254,155,42,223,202,229,175,27,178,124,51,119, -32,75,71,178,165,127,55,45,250,178,56,42,30,134,206,173,60,187,175,155,24,215,178,118,44,206,215,140,21,125,91,7,151,111,56,119, -121,189,77,198,190,54,23,209,11,178,178,47,110,138,151,69,209,254,199,229,130,214,159,107,147,45,102,86,46,161,223,113,45,189, -46,63,255,34,37,15,238,11,150,211,71,45,246,178,10,227,144,213,102,188,115,225,188,250,39,250,140,252,189,198,158,138,125,251, -246,237,143,163,27,209,165,244,45,93,110,11,122,219,150,203,44,2,126,203,120,83,84,118,28,116,118,245,61,238,201,54,232,144, -75,9,77,247,155,116,187,104,130,204,13,70,237,81,174,164,215,220,220,239,33,211,248,255,162,43,104,210,75,66,8,183,77,166,64,225, -113,203,100,141,194,176,133,139,68,174,77,46,81,105,155,245,82,227,147,150,184,27,230,88,22,175,28,180,140,59,141,133,131,162, -216,111,138,219,141,186,125,198,254,111,179,196,42,151,129,177,254,93,172,162,191,186,197,29,188,0,34,80,96,17,43,252,101,200, -166,153,149,103,208,79,44,243,118,241,75,241,42,87,182,155,57,247,24,162,207,52,161,162,241,160,81,51,207,216,92,97,155,118, -206,66,151,233,202,217,101,185,239,70,187,134,117,166,235,168,40,108,128,91,252,65,204,106,216,101,26,95,52,102,212,99,120,180, -205,54,176,117,110,109,198,140,76,219,101,187,141,221,48,62,90,186,92,238,93,166,231,55,98,154,148,18,166,139,12,95,5,132,32, -98,123,42,233,58,11,142,57,184,108,80,76,47,192,216,69,211,119,108,177,180,189,146,159,140,55,68,29,76,106,27,13,108,88,236,208, -202,142,190,125,23,92,106,211,96,59,253,208,45,167,142,121,223,107,44,220,122,216,36,216,251,126,158,123,32,126,203,158,37, -125,115,108,177,9,91,248,136,92,151,138,101,187,226,139,140,125,21,7,155,91,227,13,149,244,109,139,151,250,17,249,121,191,91,220, -10,53,251,77,55,38,190,236,1,185,108,65,211,248,147,16,183,222,106,90,208,134,217,222,109,8,76,218,60,106,136,93,235,76,251, -14,99,126,92,120,109,187,193,101,215,178,137,49,87,203,182,109,151,49,84,97,187,23,186,132,203,112,89,60,101,227,194,54,84,184, -140,146,181,44,5,63,251,181,219,184,219,184,157,29,160,184,192,164,219,140,186,243,49,192,235,92,232,209,157,127,97,57,61,227, -18,207,242,90,174,51,61,24,3,186,189,93,136,160,233,254,134,176,43,205,156,87,196,138,95,237,15,62,110,218,28,138,214,153,214, -181,98,254,173,194,99,187,235,209,79,249,94,30,192,253,102,46,188,233,1,81,232,183,115,131,198,112,5,6,97,223,98,121,223,226, -21,219,213,208,190,98,165,237,93,164,6,202,86,183,115,150,240,24,93,30,87,142,43,215,72,183,217,185,44,79,7,221,106,12,112,68, -244,254,196,161,227,188,13,237,195,70,240,102,219,12,26,219,43,208,51,198,246,184,41,212,48,8,195,56,104,217,178,143,62,151, -217,208,222,41,151,222,94,215,36,13,99,209,151,212,236,150,29,178,72,187,14,124,185,112,189,41,228,172,172,7,140,21,203,130,188, -29,120,161,15,137,194,130,96,53,214,186,125,249,32,154,195,170,193,114,24,232,41,151,218,241,151,219,6,187,41,74,87,217,130, -173,72,119,217,24,134,123,158,26,134,49,109,167,145,168,88,22,55,242,230,25,123,218,110,17,126,191,236,164,225,186,134,25,244, -61,41,152,31,167,107,92,114,177,183,210,211,106,187,26,225,157,198,96,197,178,67,7,57,174,216,232,248,28,219,192,10,195,142, -60,57,88,160,29,7,194,58,203,122,107,114,236,23,118,216,38,188,24,134,196,250,194,183,97,181,74,83,112,124,124,201,48,239,20,247, -136,79,233,240,78,111,27,226,128,225,174,104,153,241,213,122,147,110,52,234,232,143,28,58,177,253,76,196,253,166,251,108,106, -71,100,186,219,3,223,175,167,217,236,138,159,247,136,155,224,171,8,97,135,132,105,248,230,25,123,43,206,95,182,110,31,60,231, -10,89,147,127,176,214,184,160,66,113,140,176,248,145,81,90,103,204,49,62,33,172,156,191,137,146,92,99,46,56,229,86,201,185, -37,118,201,64,137,71,61,218,37,162,36,10,198,188,146,28,41,90,147,227,130,108,233,100,179,233,198,60,150,19,165,243,39,121,37,74, -121,173,226,24,224,228,79,22,227,147,114,59,140,51,184,173,81,90,83,58,43,211,221,57,178,247,154,201,254,153,113,102,201,234, -12,195,93,114,22,24,203,129,38,72,121,51,76,150,234,41,217,140,207,238,12,211,131,161,15,148,152,89,217,172,70,67,170,232,201, -48,92,96,76,202,200,193,121,49,184,93,106,112,174,210,218,210,217,165,85,165,161,210,202,210,106,81,98,9,83,228,152,101,6,254, -8,163,229,192,1,235,185,217,11,196,129,58,33,142,2,207,3,135,194,112,123,224,24,240,252,28,33,110,60,67,8,254,55,202,228,218, -116,177,135,196,20,32,219,200,113,233,223,225,8,90,118,241,1,235,227,243,172,143,26,200,81,238,159,39,172,35,245,66,60,84,111, -136,159,130,190,1,124,188,65,136,123,129,39,128,3,141,8,240,238,92,217,174,7,237,30,110,236,21,47,54,10,235,137,38,33,94,2,14, -53,11,113,61,240,34,240,151,102,50,132,55,223,16,87,134,182,64,244,208,252,179,196,209,249,66,60,12,60,7,188,4,28,105,17,226, -46,224,49,224,121,224,21,224,221,22,178,132,237,199,100,5,55,141,162,233,149,11,182,137,135,22,96,4,11,133,120,114,17,180,3,135, -22,147,219,29,40,86,98,250,239,14,200,62,191,216,48,46,91,34,140,107,150,154,198,187,75,133,241,110,155,105,220,181,204,107, -220,184,124,167,245,238,10,83,60,221,9,75,117,153,226,249,110,204,174,219,16,151,173,194,72,87,99,8,107,240,12,188,180,22,186, -215,163,143,13,224,3,87,110,52,196,189,27,193,223,4,75,156,9,235,158,9,11,24,51,5,255,57,32,208,225,145,129,139,49,169,1,76, -38,194,191,206,11,122,133,247,99,226,208,1,235,181,8,215,30,218,44,114,110,4,46,219,146,253,255,149,156,191,233,201,252,223,129, -252,91,149,204,255,31,200,191,83,201,252,31,130,252,59,149,16,169,255,71,144,127,171,147,249,191,4,93,52,249,255,9,154,126, -245,59,26,249,123,170,144,250,127,164,54,129,225,10,41,25,254,247,244,194,175,126,251,206,255,6,222,8,169,126,249,255,31,52,181, -60,255,27,109,43,164,126,151,196,255,142,219,14,169,241,241,191,193,39,173,135,255,77,62,255,152,71,254,155,184,77,68,255,7, -100,114,50,46,48,81,0,0,0,0}; +{31,139,8,8,43,113,161,94,0,3,106,97,118,97,77,105,100,105,66,121,116,101,67,111,100,101,46,100,101,120,0,149,124,11,124,220, +69,181,255,153,223,99,119,179,217,36,155,77,218,164,105,178,217,164,73,179,165,205,171,233,35,109,146,182,121,180,77,218,164,45, +201,182,72,195,5,183,201,182,217,146,236,134,236,166,180,114,189,20,244,210,162,168,40,80,65,177,162,2,242,18,81,65,80,17,81, +80,81,81,122,149,63,214,39,138,112,69,69,64,20,17,229,218,255,247,204,204,110,126,109,3,213,246,243,221,51,191,51,103,206,204, +156,57,115,230,204,111,183,29,141,237,247,54,181,44,167,234,195,55,252,236,231,159,31,184,160,244,71,71,143,188,248,212,248, +199,142,188,62,189,243,225,179,11,151,53,157,77,52,73,68,251,119,44,11,144,254,243,246,109,68,231,10,197,95,15,60,105,19,157,3, +250,188,139,40,4,250,134,151,232,179,76,115,137,114,64,211,133,68,55,174,33,186,22,26,254,86,79,244,119,224,255,0,163,129,200, +6,22,3,13,64,43,176,14,232,1,54,1,219,128,93,192,81,224,105,224,31,192,63,1,163,145,200,13,132,129,173,192,32,240,54,224,66, +224,82,224,125,192,167,128,91,129,59,128,207,2,247,2,95,6,30,2,30,1,190,3,188,4,20,55,17,173,4,118,1,215,0,15,3,127,0,252,205, +68,109,192,249,192,101,192,221,192,143,128,23,129,130,165,68,29,192,46,224,74,224,51,192,47,129,146,22,162,85,192,249,192,101, +192,17,224,46,224,155,192,79,128,63,2,198,50,216,14,120,47,240,16,240,10,16,90,78,148,0,238,5,126,11,204,89,65,180,2,216,9,188, +3,248,24,240,32,112,28,120,9,48,86,162,47,96,49,176,22,216,1,164,129,107,128,219,129,135,1,187,149,168,9,232,1,222,6,76,0,151, +1,71,128,187,128,175,2,79,0,214,42,244,7,132,129,181,192,32,112,29,112,59,112,63,240,75,224,215,192,115,192,239,129,151,129,191, +1,111,0,98,53,214,1,200,7,138,128,82,32,8,212,0,139,129,165,192,10,96,21,208,1,116,2,235,129,56,112,61,240,16,240,35,224,121, +224,85,64,180,17,121,129,2,160,20,88,8,180,0,107,129,141,192,185,192,52,112,37,240,81,224,115,192,35,192,15,128,227,192,239, +129,87,128,215,1,119,59,244,0,149,192,66,160,30,88,1,116,3,3,192,78,96,4,184,8,216,15,92,2,28,2,62,0,220,0,124,10,248,60,240,53, +224,7,192,79,129,231,128,63,1,175,3,86,7,244,3,107,129,62,96,28,120,31,112,45,240,73,224,110,224,94,224,107,192,163,192,49,224, +23,192,235,192,92,236,133,122,160,11,56,15,72,1,239,4,174,6,62,10,220,9,220,15,60,12,252,1,120,5,120,29,48,214,98,46,192,86, +224,0,112,45,112,23,112,31,240,13,224,127,128,223,0,127,4,222,0,242,214,97,254,64,24,88,9,172,3,54,1,219,128,97,224,124,96,4, +136,3,147,192,37,192,97,224,58,224,40,240,105,224,94,224,33,224,49,224,41,224,103,192,111,128,151,128,191,1,255,4,188,157,68, +21,64,61,176,26,88,3,116,3,189,192,22,96,59,112,1,16,3,246,2,83,192,21,192,199,129,251,128,199,129,231,128,215,0,111,23,209,60, +96,17,176,14,56,27,24,3,46,2,46,5,62,8,220,9,124,9,248,54,240,4,240,28,240,119,192,213,13,95,6,26,128,94,224,60,96,28,184,24, +184,12,184,10,184,6,248,56,112,43,240,21,224,199,192,203,192,95,129,55,0,119,15,81,33,48,31,88,12,44,7,122,128,45,192,249,64, +12,216,11,92,14,188,7,56,2,124,10,120,8,248,22,240,4,240,99,224,23,192,51,192,171,128,23,65,178,8,168,0,106,129,197,192,70,224, +108,96,23,144,4,46,5,174,2,62,4,220,0,220,12,124,1,248,10,240,117,224,123,192,83,192,207,129,103,129,151,128,191,1,198,6,216, +11,88,6,108,1,182,3,5,136,185,197,64,53,176,0,168,1,106,129,133,64,29,16,6,22,1,103,1,139,129,37,0,194,49,33,180,18,66,34,33, +252,17,194,28,33,164,17,66,22,33,68,17,194,18,33,244,16,66,11,33,108,16,182,63,97,203,18,182,26,97,59,16,220,154,224,114,132, +37,36,44,5,193,148,212,163,207,7,12,137,54,2,189,64,31,176,9,216,12,244,3,3,192,22,96,43,128,99,133,112,220,208,32,48,4,68,128, +29,192,219,128,97,224,63,128,11,248,252,1,118,1,163,64,12,216,13,140,3,255,9,92,10,28,4,46,3,46,7,222,5,188,155,148,77,50,127, +252,154,78,98,226,133,186,188,31,229,50,80,67,63,115,217,212,229,74,93,158,212,50,150,230,87,233,242,65,205,247,56,228,113,4, +210,85,154,159,171,249,243,129,60,224,90,205,207,119,244,85,224,40,7,28,242,197,90,158,203,165,142,182,101,142,190,202,245,216, +88,38,168,101,42,117,121,82,151,25,55,106,153,106,45,83,161,203,55,47,81,178,92,190,75,203,215,56,218,214,234,182,220,15,251, +208,3,122,12,13,142,113,54,58,198,214,228,24,27,151,31,94,162,242,2,46,63,182,100,134,159,177,103,179,67,79,179,99,252,92,62, +230,40,103,230,184,204,209,87,171,163,47,246,201,227,154,191,90,243,217,47,58,116,121,66,151,185,109,66,151,127,133,114,82,151, +159,95,162,114,26,46,255,5,229,139,116,217,194,230,216,175,203,62,148,167,116,185,20,229,148,46,135,80,222,167,203,75,80,190, +88,151,151,57,202,235,234,103,116,246,59,202,55,58,250,138,56,248,231,57,250,29,117,240,39,29,229,253,142,126,15,58,248,135,29, +109,175,70,249,64,166,47,135,252,109,40,191,67,151,239,113,180,61,230,24,15,175,93,70,254,49,7,127,210,81,126,208,209,215,163, +40,79,103,244,160,124,137,46,31,119,216,234,87,40,167,117,249,133,122,181,111,215,232,53,122,167,46,243,26,253,151,46,179,253, +51,229,135,29,252,140,255,116,234,182,92,238,114,248,67,183,195,31,122,52,127,190,46,95,43,125,190,137,238,39,69,215,10,110, +83,64,87,201,182,205,244,1,73,87,210,135,36,245,80,135,96,31,46,165,247,242,90,163,247,231,37,21,244,71,73,107,169,74,214,47,164, +197,130,227,66,177,148,171,210,252,42,205,95,160,159,153,110,19,188,199,44,250,48,49,245,211,95,36,85,245,53,186,190,86,143,167, +22,145,247,136,164,93,116,167,164,37,244,138,164,203,232,53,93,95,46,20,13,10,181,71,111,39,166,107,232,247,164,227,190,224, +216,95,73,31,228,50,36,95,37,142,117,30,122,84,82,147,190,37,169,77,63,37,142,117,110,250,184,164,213,244,85,77,159,228,117, +192,137,241,49,77,63,43,169,69,223,150,116,11,45,135,126,27,124,55,113,28,236,165,62,193,116,5,13,8,190,3,40,190,55,75,189,116, +189,164,57,180,30,245,62,173,39,79,215,231,129,115,189,164,185,212,45,20,237,17,28,35,243,232,235,196,180,138,126,70,28,199, +213,120,252,136,164,63,144,180,128,74,4,83,63,205,23,28,219,213,184,57,198,63,165,233,207,73,197,215,239,75,58,72,199,37,45,164, +159,104,62,215,23,107,189,197,56,165,214,65,207,28,61,174,18,156,74,223,145,180,137,230,8,166,171,105,174,164,29,212,44,105, +59,237,16,28,167,85,251,82,216,255,168,166,108,175,121,90,79,25,198,255,32,113,60,13,208,151,136,227,176,65,183,72,63,92,47,235, +217,239,20,21,244,136,164,181,244,61,73,183,211,15,37,221,72,66,250,235,98,42,148,116,9,5,36,61,155,106,36,221,68,155,36,221, +64,219,165,95,174,147,250,66,122,92,76,239,149,84,217,39,132,72,254,11,73,7,232,15,186,62,79,182,235,167,34,73,55,83,151,80,252, +94,77,251,165,95,175,149,122,171,180,222,42,173,183,74,235,173,210,250,170,116,251,42,221,190,74,183,175,214,237,170,181,124, +181,150,175,214,242,213,90,190,90,203,47,192,78,231,254,22,32,43,49,228,243,50,50,53,181,36,93,74,182,164,203,201,165,169,91, +243,243,53,45,144,180,153,252,154,22,203,253,214,37,245,214,160,255,143,72,90,77,223,144,212,69,223,37,117,22,62,46,233,89, +180,90,238,51,181,62,181,122,190,181,240,148,251,36,157,71,95,148,116,33,61,36,169,90,191,90,248,205,99,146,238,160,39,36,221,78, +199,52,253,31,73,139,232,71,146,214,208,255,147,116,62,253,88,210,85,228,145,253,181,82,142,166,94,161,248,185,146,182,145,79, +168,120,80,42,233,92,154,39,105,41,149,73,186,149,170,37,109,164,5,146,118,83,139,164,27,40,34,227,68,189,156,199,66,100,94, +247,232,56,241,180,140,15,103,97,230,138,186,37,157,67,95,147,180,140,30,38,62,235,23,75,126,163,150,135,118,26,18,76,43,232, +109,130,207,118,213,174,73,219,167,9,158,254,77,226,51,92,245,211,12,59,255,142,56,183,236,145,114,45,240,124,222,15,203,116, +187,101,144,59,172,159,111,212,207,55,73,90,71,47,232,231,165,66,229,1,27,37,141,208,160,224,28,53,76,239,35,206,83,149,158, +21,186,253,10,200,127,66,210,74,217,207,10,100,191,47,75,26,162,38,161,248,172,111,165,110,183,82,247,191,82,247,179,82,247,179, +82,247,211,138,241,255,146,152,6,233,159,196,121,135,26,215,106,77,219,180,158,54,100,187,107,4,231,199,234,185,93,251,23,159, +77,96,203,119,35,36,227,2,206,50,36,226,55,32,17,62,178,69,229,97,194,53,147,71,113,253,213,168,127,98,139,122,14,233,246,204, +127,251,18,69,111,66,253,31,116,125,149,174,111,114,212,63,128,250,186,173,170,126,129,214,107,59,244,31,67,253,144,174,175,209, +252,118,71,253,175,80,255,30,93,95,171,245,207,1,198,180,254,151,81,255,57,93,191,80,183,115,142,127,29,228,22,109,83,207, +117,142,241,101,234,183,161,190,91,215,115,14,30,197,197,96,108,64,201,165,52,189,124,96,166,238,26,71,249,227,186,254,14,7, +239,11,186,252,16,232,55,29,229,99,3,42,151,103,153,159,1,255,171,219,254,73,83,99,139,162,69,154,134,53,237,208,52,162,105,108, +203,76,95,251,53,239,93,91,88,183,33,203,231,111,80,247,140,73,127,30,158,171,225,59,147,254,79,226,121,216,111,33,234,15,251, +13,26,14,24,56,183,88,158,245,36,55,168,123,66,4,53,23,249,175,32,62,21,19,161,113,172,181,87,222,13,44,45,183,111,131,186,67, +92,36,123,241,137,68,200,192,126,130,172,223,150,207,124,30,152,168,99,217,119,109,80,103,94,36,100,81,164,202,130,204,45,168, +241,138,5,184,224,38,66,183,98,124,62,248,98,143,148,177,101,22,128,188,17,109,230,130,78,249,111,71,159,62,49,229,255,52,183, +49,90,141,60,240,110,67,153,219,248,40,16,72,52,173,130,39,133,95,206,215,35,35,58,186,65,217,129,239,53,46,57,51,220,179,55, +168,123,99,160,112,105,177,77,129,170,150,226,66,140,163,16,253,249,176,127,114,41,210,204,227,226,91,148,207,72,132,62,5,223, +13,116,182,20,87,34,126,205,161,50,227,66,186,40,212,12,222,76,139,192,41,45,110,150,181,150,182,69,59,34,105,190,156,11,247, +253,205,13,234,94,227,180,85,39,180,32,122,106,253,95,208,250,3,162,64,68,154,149,229,133,148,252,79,105,169,240,171,94,104,98, +237,79,109,80,239,56,3,37,1,151,214,7,61,94,42,179,160,199,206,147,122,34,232,59,33,47,151,62,177,74,100,234,124,186,46,252, +74,107,206,114,170,54,188,240,4,182,89,153,101,161,191,38,182,178,149,8,249,113,6,85,155,121,168,11,192,114,137,80,49,178,101, +230,207,193,45,215,103,5,106,185,20,161,5,233,117,232,161,0,173,125,246,128,109,185,46,242,127,68,181,247,23,161,149,207,78, +172,203,165,206,255,14,127,53,17,242,225,6,28,254,18,101,253,203,187,81,221,73,79,246,175,75,225,95,249,200,211,92,202,231,55, +170,123,232,164,191,1,109,134,23,228,208,112,141,139,134,107,189,180,115,161,7,150,63,47,228,150,107,107,75,255,18,84,183,81, +197,146,128,25,233,116,81,171,112,19,211,132,127,49,234,34,157,57,224,228,72,26,233,242,162,175,255,130,157,135,187,161,179,219, +5,45,121,122,5,2,122,5,194,207,171,120,196,186,133,168,199,241,37,228,152,218,209,7,199,206,132,159,51,254,164,255,42,237,95, +25,31,239,217,168,226,104,36,132,126,170,184,159,41,233,215,133,50,142,8,233,151,155,54,170,189,26,128,229,132,230,109,219,56, +227,171,249,152,63,223,221,119,108,84,123,171,35,215,71,67,151,121,200,125,208,125,141,184,89,220,103,125,107,159,167,83,203, +90,250,246,191,219,209,222,208,99,153,218,168,98,98,196,159,163,60,213,15,171,64,98,187,223,45,125,133,159,19,161,37,24,95,192, +127,158,223,125,82,219,75,222,162,109,107,182,109,61,183,165,76,91,30,11,143,225,221,122,109,39,253,124,235,24,22,62,26,54,114, +105,24,222,148,159,93,171,107,29,107,149,171,215,42,23,86,93,32,215,202,167,215,202,135,181,202,203,174,21,244,116,231,254, +27,107,117,123,118,173,250,102,93,171,207,101,215,10,253,84,229,205,186,86,247,103,214,10,158,232,214,51,252,42,120,69,220, +174,89,143,28,52,177,174,134,58,99,51,99,235,20,122,108,175,169,119,50,122,108,222,204,122,63,233,88,175,12,239,167,14,158,41,71, +137,115,110,163,122,143,51,44,10,96,79,182,234,176,145,47,227,180,122,27,244,130,163,77,198,23,254,58,11,207,232,117,198,66, +75,206,41,191,87,197,227,64,168,197,46,128,15,36,224,179,38,172,193,81,195,195,251,23,113,231,157,242,54,51,163,167,162,247,116, +221,139,102,225,45,159,133,215,217,123,242,252,248,207,192,44,188,115,28,60,91,90,14,231,90,47,71,8,182,67,17,236,240,25,105, +7,156,91,102,33,13,91,60,66,75,90,209,164,169,94,245,30,168,220,168,161,10,35,32,134,155,3,88,249,187,81,3,159,109,246,99,189, +10,36,77,192,103,133,46,113,180,97,73,63,158,11,33,225,149,52,225,47,213,252,66,10,26,184,235,137,160,81,39,242,68,248,53,158, +205,60,212,85,202,241,153,50,255,112,73,159,90,116,105,253,146,69,186,108,208,7,122,85,78,90,110,98,44,102,100,16,186,141,5, +196,52,225,159,199,49,83,36,252,213,242,52,11,44,107,233,154,11,110,21,71,123,163,204,186,6,190,216,136,8,204,103,155,137,253, +230,201,158,48,65,179,16,40,195,242,133,223,200,67,169,206,80,249,195,66,180,172,215,190,36,112,255,202,248,239,103,122,85,125, +196,239,207,250,53,215,124,161,55,115,190,171,209,200,248,235,87,111,10,213,249,174,246,233,151,122,249,30,137,57,8,204,65,68, +154,2,24,77,30,69,154,10,249,14,64,252,28,89,10,13,161,125,136,220,65,193,254,31,20,117,164,250,44,146,125,21,99,223,168,179, +252,209,94,245,14,53,96,77,250,107,97,185,225,72,49,13,239,40,134,69,138,169,204,252,51,180,148,224,70,228,51,42,141,18,26,30, +44,1,191,132,86,225,124,42,51,176,163,204,49,185,219,113,115,194,153,181,2,62,240,81,62,19,6,231,225,105,25,158,62,36,159,74, +79,170,43,59,233,105,142,212,151,240,47,100,203,83,149,25,48,150,47,245,210,6,76,51,17,74,35,214,29,55,12,172,173,148,105,90, +68,131,86,248,113,143,62,171,254,212,171,114,207,200,72,41,218,31,225,157,97,113,30,98,145,215,108,53,155,100,30,98,201,113,7, +41,130,160,86,105,250,165,77,205,153,21,54,3,203,91,134,126,123,66,175,176,89,102,171,21,30,202,174,240,79,78,232,21,54,19,161, +247,227,172,101,205,79,156,40,52,2,70,248,159,46,61,142,185,125,234,253,120,164,171,12,250,63,206,243,48,166,252,119,104,250, +105,80,110,53,95,142,199,144,154,27,41,210,13,217,208,81,57,150,74,172,97,194,63,34,71,192,189,12,73,249,103,79,20,138,128,8, +255,147,227,140,242,158,230,62,245,174,189,220,174,165,10,59,146,230,89,95,207,179,181,22,116,117,241,89,144,86,118,192,156,93, +66,102,100,46,212,181,90,115,101,207,46,104,175,52,131,116,28,241,46,130,43,81,165,165,172,193,121,193,128,101,8,33,194,191,13, +218,133,70,158,21,180,235,44,246,139,6,217,107,163,244,19,254,59,214,167,222,209,151,91,232,31,190,50,193,185,150,57,60,52, +151,130,214,204,106,39,66,23,82,140,103,162,86,196,228,113,152,114,28,65,57,14,53,227,133,50,170,207,145,185,203,53,216,81,9, +255,229,188,30,214,69,254,43,117,166,195,220,240,51,121,102,208,170,51,121,158,108,197,5,77,156,145,222,192,86,196,92,144,145, +154,60,78,142,24,43,179,123,108,5,185,244,110,186,70,175,75,185,129,241,26,145,78,101,29,49,51,38,209,42,74,51,99,194,170,4, +229,109,183,82,40,187,200,252,206,95,41,243,187,150,179,159,63,17,52,56,222,4,40,252,127,42,226,168,189,84,39,123,10,19,231,157, +220,239,93,125,234,59,136,114,47,250,244,182,250,139,41,48,47,209,148,162,27,243,124,88,211,45,20,249,250,60,204,224,99,200, +197,185,119,55,86,45,232,45,164,192,162,240,139,131,205,243,105,50,116,17,238,192,62,119,171,123,21,69,246,97,44,46,68,70,87,11, +164,90,225,175,131,205,21,104,59,31,121,183,15,121,118,14,110,11,33,114,127,221,122,118,159,139,223,144,182,98,6,172,189,218, +106,129,158,171,97,197,68,211,77,212,108,5,189,225,99,24,177,183,78,168,246,101,220,222,211,234,249,221,137,106,156,131,147,235, +122,233,225,214,240,51,65,47,102,246,32,201,251,124,55,102,196,223,189,168,44,104,163,244,63,94,255,122,48,249,253,98,192,21, +73,97,55,134,206,194,126,80,190,16,73,205,129,205,110,228,83,42,165,246,128,90,249,59,100,182,201,214,182,165,79,151,72,107,219, +210,3,26,149,44,246,64,145,92,77,222,3,187,32,31,254,157,90,243,128,57,140,250,32,116,207,59,85,163,99,151,151,57,118,249,66, +146,178,208,184,64,106,108,65,187,15,202,118,149,102,53,228,182,177,246,223,12,239,155,7,185,217,34,70,117,70,151,242,5,83,80, +43,34,6,211,74,211,146,39,147,233,120,114,201,167,76,84,41,101,221,63,83,122,175,69,153,179,26,206,190,56,143,89,4,251,45,211, +249,141,192,109,182,64,223,21,70,54,169,247,211,51,123,39,242,212,92,170,218,19,48,197,242,229,211,45,216,107,46,59,225,15,113, +244,241,84,93,9,238,178,229,215,214,32,50,122,144,199,7,101,244,106,249,205,92,170,246,46,204,156,16,185,129,162,150,53,240, +166,162,132,191,130,235,125,147,235,14,210,151,31,225,189,244,73,58,110,90,66,44,11,63,29,48,195,127,58,110,218,66,44,15,255,160, +208,176,245,222,190,114,147,218,43,129,80,185,192,138,194,243,63,192,86,49,86,25,33,120,83,28,62,193,62,135,155,153,63,200,39, +245,210,57,210,139,187,228,141,207,141,179,37,252,87,117,194,76,134,246,106,89,139,185,127,8,138,128,204,3,121,190,243,49,38, +158,77,142,180,67,69,54,167,61,186,73,249,93,192,63,25,74,200,155,99,97,182,238,230,76,93,104,166,46,160,199,124,199,38,245,253, +158,7,188,237,158,114,106,245,108,193,189,75,237,60,15,242,163,72,46,172,249,96,192,35,174,92,254,157,77,176,91,110,78,192, +208,59,218,195,109,6,243,230,83,203,241,85,196,54,134,230,188,170,95,6,60,203,159,111,166,13,86,158,135,45,140,249,187,90,246, +177,117,43,164,135,200,54,5,21,212,242,231,114,240,202,217,83,108,182,19,124,27,251,41,63,147,39,120,202,114,254,33,79,145,235, +81,95,105,55,243,14,183,3,117,225,123,143,123,60,34,124,236,184,39,71,136,43,195,247,7,189,101,72,142,195,127,206,243,96,111, +122,56,131,28,68,235,183,103,227,216,5,217,187,241,156,205,234,59,56,142,172,221,50,42,201,40,230,184,115,23,56,238,220,11,101, +44,133,55,24,45,131,47,159,96,107,241,25,98,105,159,59,107,179,186,187,241,249,199,185,87,160,185,197,111,194,79,35,56,227,3, +34,177,46,76,77,129,240,235,252,78,219,144,57,212,50,200,223,196,241,44,15,86,205,75,139,121,188,91,61,108,69,15,172,19,112,7, +114,248,198,23,241,149,225,182,248,30,62,99,242,217,47,94,128,239,173,242,157,47,123,129,156,47,176,166,229,133,38,142,132,176, +144,135,124,190,178,124,117,206,190,32,45,132,115,214,86,183,115,68,6,75,233,83,254,213,143,182,173,190,118,154,225,29,5,207, +231,174,116,91,14,222,39,192,171,206,173,145,28,15,252,205,99,32,23,61,39,74,185,85,167,141,13,17,241,133,220,234,252,54,236, +183,59,49,235,214,156,38,42,242,29,115,95,246,176,237,231,156,17,59,121,221,93,244,144,63,152,151,159,25,143,143,117,240,14,120, +152,124,222,86,47,188,234,46,65,238,135,43,97,77,55,226,180,71,198,5,183,140,7,110,74,227,60,41,162,96,94,248,215,121,190,96, +94,157,175,200,55,74,225,31,230,249,194,175,241,89,49,141,21,226,239,215,216,155,142,100,115,185,235,197,165,245,71,197,245,130, +243,62,67,230,218,15,108,86,223,195,149,187,97,115,55,159,69,94,156,232,108,115,156,231,70,228,136,154,143,193,235,0,27,93,129, +117,104,117,33,154,30,65,236,9,93,71,183,226,121,149,171,150,78,150,59,10,57,159,171,210,197,81,118,84,230,2,39,215,127,2,245, +172,161,218,19,164,201,166,165,116,155,201,81,227,10,10,186,243,73,143,192,226,213,227,220,162,204,163,86,239,10,25,199,177,122, +162,92,90,75,200,92,85,82,23,91,44,142,213,109,181,225,91,67,42,102,182,154,30,29,69,85,244,228,168,233,165,240,19,121,174, +240,247,243,92,65,119,157,75,157,169,156,87,76,234,120,121,177,220,15,136,82,151,214,167,247,209,62,105,35,142,13,158,126,245, +61,127,57,102,90,33,109,227,37,175,205,231,231,185,242,253,207,64,54,54,71,4,122,23,22,5,138,3,115,90,144,248,4,172,200,117, +234,68,177,229,217,116,135,166,242,140,194,138,190,120,66,159,81,242,68,25,172,155,79,90,187,167,229,208,139,39,100,91,88,179, +86,122,174,58,97,108,89,86,39,12,34,100,113,248,241,86,225,209,55,25,117,139,137,92,199,107,243,97,212,6,93,200,197,237,160, +171,206,86,115,61,87,238,245,157,217,119,99,155,251,79,190,15,242,253,121,168,63,27,31,183,93,66,75,35,62,153,109,24,178,238, +63,250,213,61,148,223,197,5,140,201,193,75,168,219,207,245,57,114,191,27,20,235,87,191,169,8,20,113,236,227,93,195,107,196,223, +90,114,70,102,82,129,161,78,112,126,135,232,134,5,91,109,68,115,43,252,42,238,48,86,157,17,153,154,67,186,149,29,112,241,238, +25,116,69,166,138,193,155,43,179,219,192,156,106,215,2,248,203,14,218,231,78,172,195,9,24,243,33,171,193,138,59,218,201,86,34, +104,137,165,225,239,242,189,245,16,133,255,174,222,121,122,49,83,254,158,117,177,180,65,105,54,70,189,191,95,189,31,200,196, +164,58,196,36,117,15,85,86,250,176,182,71,196,63,79,238,126,126,55,165,252,194,162,155,250,213,111,63,120,142,94,185,51,56,186, +169,157,20,57,162,162,202,173,146,143,123,204,17,21,81,110,149,107,13,255,52,212,170,25,114,213,12,93,255,9,212,243,169,118, +187,244,230,0,234,98,236,41,50,91,177,179,187,140,178,187,136,61,31,178,176,46,124,175,251,164,91,135,43,17,186,24,187,66,101, +11,65,119,248,94,229,245,121,162,204,133,155,148,167,72,222,164,174,192,153,160,222,211,244,192,42,91,244,253,251,108,29,47, +206,209,249,174,65,67,151,214,239,24,202,190,219,249,75,191,243,221,206,185,98,62,157,103,148,211,185,102,133,124,107,165,110, +157,214,128,122,39,31,16,171,16,115,11,112,142,188,79,102,78,76,57,147,111,89,250,218,9,247,54,62,65,6,187,42,104,16,109,91, +150,190,120,98,123,87,57,109,55,203,81,126,254,196,96,215,124,240,113,106,46,125,230,68,160,48,252,116,230,29,31,206,168,1,245, +125,68,53,238,11,131,157,243,233,135,129,131,160,21,84,100,30,164,229,205,69,178,124,79,213,100,232,16,199,88,255,97,121,62, +109,239,196,153,141,157,18,248,211,231,171,10,68,145,184,148,194,47,65,235,223,213,13,25,121,211,128,246,123,216,172,18,8,98,46, +153,119,72,77,3,42,167,80,243,205,215,177,212,160,229,3,250,253,149,152,121,251,106,82,161,208,239,91,113,86,254,227,68,185, +81,135,251,192,46,17,164,85,2,89,180,168,196,154,181,32,35,143,131,19,148,252,240,243,153,28,191,80,234,16,250,187,18,33,51,24, +83,247,181,117,64,125,71,83,70,234,142,108,200,222,44,249,61,113,57,114,161,10,177,11,245,171,136,51,245,90,244,177,7,109,121, +38,65,201,15,191,152,185,147,231,233,62,42,178,125,148,203,223,192,10,34,202,216,130,231,122,83,64,125,199,116,27,232,61,217, +95,217,170,63,15,234,231,140,60,255,198,234,49,240,142,157,194,223,164,249,63,63,165,253,243,167,60,255,37,160,250,204,252,134, +137,223,57,90,69,234,183,69,197,69,234,187,152,242,34,245,155,9,31,232,152,214,27,7,173,193,243,133,160,75,138,212,111,63,150, +129,182,23,157,172,191,247,148,103,65,250,251,44,82,177,140,41,255,150,199,144,180,89,198,202,2,100,203,182,174,43,119,204,73, +144,202,105,12,253,100,106,186,134,102,126,167,149,249,30,201,144,180,73,62,47,212,252,238,172,156,79,183,85,191,50,81,125,173, +205,182,103,152,89,204,149,177,203,208,54,50,29,182,82,60,151,230,185,36,79,149,221,89,93,57,154,250,53,13,104,153,128,214,43, +223,179,211,204,247,103,114,143,201,12,90,217,158,101,249,251,228,133,186,95,254,46,119,161,222,139,181,248,107,105,234,215, +241,97,149,110,179,74,223,73,88,174,93,239,165,53,186,110,173,30,191,149,45,203,89,135,201,12,247,225,14,179,136,106,154,90,186, +90,155,214,47,239,172,95,223,179,190,181,126,89,87,75,75,125,231,202,229,205,245,43,186,215,183,44,91,223,189,172,123,101, +19,76,139,124,173,125,100,60,158,136,167,215,144,171,93,81,99,77,27,89,107,218,22,237,224,79,148,253,93,227,211,177,116,50,153, +30,27,136,38,162,123,98,83,180,250,84,78,40,54,53,149,156,90,29,26,73,78,143,143,134,18,201,116,104,79,44,29,202,74,133,250, +215,135,82,35,209,68,2,109,215,254,107,109,71,99,187,163,211,227,78,29,209,209,232,100,26,10,202,122,166,39,38,14,100,249,27, +163,233,116,119,116,124,124,87,116,228,66,18,125,100,244,245,147,217,215,223,79,149,125,91,67,235,247,143,196,38,211,241,36,130, +249,88,124,60,22,26,25,79,166,226,137,61,161,201,228,84,154,106,251,182,190,89,253,68,124,52,142,33,236,139,143,196,72,108,34, +107,211,246,238,245,84,184,105,122,36,54,128,154,190,196,228,116,122,27,171,8,100,88,91,167,211,25,158,47,195,147,79,197,153, +167,161,233,73,238,181,97,111,116,95,148,68,63,25,253,125,100,246,247,201,15,244,128,15,100,22,24,182,217,143,15,171,191,127, +103,63,213,244,71,19,163,83,201,248,104,227,174,204,108,27,179,243,238,84,230,104,163,5,111,37,213,35,231,208,70,85,111,37,196, +38,108,163,69,103,18,201,88,185,141,26,207,40,58,22,157,138,142,96,120,241,84,58,62,210,70,139,207,212,160,39,150,26,153,138, +79,166,147,83,179,15,100,60,54,35,223,31,27,82,190,52,251,220,33,202,245,51,163,125,19,125,44,180,33,62,142,65,214,116,77,199, +199,71,89,223,108,102,58,73,244,45,69,6,99,41,184,236,236,179,213,34,67,177,116,26,14,150,154,233,242,45,166,144,17,110,163, +121,89,161,145,100,34,29,75,164,27,187,153,238,71,103,149,217,170,137,216,104,60,218,200,174,219,200,14,151,89,250,37,111,45,208, +151,216,157,172,97,87,229,130,115,56,111,42,221,70,181,111,45,52,148,142,166,167,49,234,234,55,19,203,110,32,167,43,157,34,163, +163,67,141,82,57,179,154,43,207,212,96,107,66,53,217,58,25,75,196,70,251,225,129,49,233,43,161,51,52,124,139,185,207,236,110, +231,250,159,34,52,24,27,137,197,247,177,158,162,172,72,50,213,216,53,157,24,29,199,50,20,59,153,189,81,102,66,180,196,201,221, +22,157,26,137,141,111,159,142,143,182,81,32,91,49,157,142,143,55,246,39,247,156,198,219,22,141,79,57,250,202,242,218,104,251, +233,204,246,51,184,201,25,227,3,14,130,166,254,145,228,68,227,212,68,106,188,113,47,162,90,227,41,161,173,230,212,200,222,70, +205,103,104,113,90,68,109,163,165,255,98,19,231,154,44,249,23,219,40,233,254,51,72,207,88,37,235,131,111,122,226,180,81,207,191, +173,109,134,195,46,26,137,166,46,60,179,161,78,211,114,230,73,103,38,188,45,154,30,227,48,241,150,210,188,89,71,163,227,251, +226,23,54,34,180,38,177,129,113,40,54,174,79,232,3,177,123,60,154,194,134,14,206,34,211,199,145,88,215,87,205,82,63,16,155,216, +165,5,98,16,169,152,69,100,40,190,39,129,136,49,133,93,82,54,75,117,100,108,42,121,49,154,206,233,231,179,179,49,158,108,116, +28,220,109,84,168,216,227,209,196,158,70,61,142,34,7,171,15,113,82,218,43,224,96,110,221,181,55,54,146,62,153,55,148,158,194, +76,179,221,72,158,236,58,186,139,247,111,185,131,61,21,219,221,120,78,44,122,225,96,108,119,108,42,150,64,146,80,241,86,181, +188,249,101,181,220,141,157,83,83,209,3,28,150,50,61,157,204,109,163,238,217,216,237,255,206,106,175,225,67,111,86,37,167,77,119, +77,214,8,51,162,169,147,121,189,209,20,118,244,100,198,170,78,222,233,130,56,179,78,19,4,239,100,19,244,225,36,141,202,179,190, +192,193,149,54,241,159,194,104,163,150,83,56,237,103,60,128,215,156,172,87,118,95,232,96,68,226,19,236,16,115,78,101,169,173, +88,120,218,94,163,206,211,88,179,39,173,142,211,36,148,58,128,131,103,34,148,138,77,201,44,50,112,250,174,39,159,115,209,168, +214,121,228,55,116,119,246,247,119,117,118,111,190,32,114,238,182,245,23,12,116,70,186,123,47,232,223,58,20,33,177,131,140,29, +200,26,119,32,207,181,118,244,237,236,35,215,142,77,200,35,55,129,141,236,113,7,210,74,107,7,231,149,246,14,201,5,71,126,176, +116,191,170,68,217,230,207,77,138,32,23,221,177,147,4,210,79,40,51,144,119,26,195,93,84,61,124,230,84,168,126,248,223,74,45,106, +254,5,113,236,221,225,89,246,233,73,204,204,70,205,141,142,140,196,82,169,13,227,209,61,41,242,34,221,156,142,142,203,156,219, +157,185,42,152,209,209,81,126,26,157,130,28,249,116,239,125,137,209,216,126,180,86,79,178,133,55,58,57,169,51,42,114,69,83,202, +19,119,157,146,106,83,89,150,211,191,94,238,61,181,182,219,183,247,245,80,96,215,105,233,169,67,67,198,145,138,103,56,217,105, +167,28,114,23,232,59,71,206,174,116,167,30,181,103,87,90,201,65,76,151,82,124,160,195,4,228,218,149,230,195,136,236,93,156,77, +146,111,68,159,74,145,3,147,49,114,97,20,72,39,40,127,228,164,100,156,236,145,241,88,116,138,73,50,21,35,55,18,202,4,108,76, +185,186,32,21,122,56,205,140,198,19,41,201,150,165,205,177,3,82,88,218,200,167,11,145,228,118,232,176,177,11,18,105,18,163,228, +29,205,230,241,228,210,115,241,40,10,27,101,74,163,148,151,41,41,5,185,163,89,7,72,101,234,50,38,243,170,71,153,236,228,140,198, +167,48,68,132,125,176,227,169,204,208,93,177,139,176,244,41,202,145,155,178,59,57,10,3,198,50,7,4,53,236,142,226,106,55,26, +74,39,67,35,83,177,104,58,22,218,53,61,174,239,148,74,119,104,247,84,114,34,148,113,19,207,238,120,34,58,30,127,71,140,170,80, +26,157,89,168,13,201,41,199,237,75,9,87,178,72,102,67,207,38,96,239,142,79,193,153,124,187,97,162,209,204,130,123,185,67,229, +198,100,237,97,131,231,240,167,50,134,137,72,66,94,124,100,84,228,114,121,92,186,118,138,202,248,65,121,238,105,215,242,249, +51,117,167,199,176,57,92,57,57,57,30,31,145,167,106,198,219,139,192,62,109,208,165,78,166,51,167,151,90,78,191,136,145,7,108,121, +246,82,33,74,61,234,238,158,217,54,57,146,37,125,33,63,91,84,107,237,205,62,167,200,141,178,116,190,69,40,244,78,79,112,56,199, +70,198,225,171,44,53,171,117,33,10,199,146,100,84,106,96,189,84,141,2,31,144,167,25,99,75,116,130,153,125,61,41,170,59,93,70, +102,161,167,9,134,79,23,84,185,231,105,146,243,32,201,213,167,14,19,147,155,171,171,122,178,206,140,233,232,33,179,6,185,200, +188,194,242,33,47,243,48,205,185,19,249,245,35,31,19,220,172,71,218,91,249,131,20,157,74,78,198,166,210,113,244,83,128,199,193, +216,68,50,29,203,4,13,48,134,228,81,164,163,149,236,82,6,136,188,49,121,11,209,247,22,114,143,69,83,91,216,37,60,40,140,201, +93,100,141,37,225,187,57,252,169,124,83,196,201,140,143,238,39,43,206,102,182,227,114,17,115,226,217,247,33,185,241,84,118,242, +252,208,173,118,104,12,19,141,167,214,79,76,166,15,112,65,218,153,171,103,94,164,120,226,58,37,32,15,167,55,189,220,175,111,175, +243,69,138,121,33,2,144,11,31,156,97,120,199,147,136,117,42,144,187,39,180,135,91,124,158,144,119,34,107,102,42,156,56,109, +27,228,79,156,180,10,148,59,225,8,196,198,196,4,153,19,169,61,248,72,79,147,149,224,181,176,249,19,81,33,17,187,152,247,0,140, +146,96,35,153,201,93,123,201,149,220,189,59,133,225,4,146,137,174,104,122,100,108,38,7,73,81,9,246,216,73,129,23,79,137,61,176, +68,241,169,21,236,230,52,231,84,238,57,83,48,137,212,162,108,136,61,43,251,87,106,200,159,76,204,188,51,145,26,10,157,28,213, +58,47,169,239,194,112,68,244,156,159,60,233,106,204,125,58,159,123,98,227,209,3,96,23,100,216,236,72,251,156,114,42,8,100,38, +226,78,38,54,140,79,167,198,200,151,76,12,164,167,51,108,140,140,199,163,188,112,48,149,138,83,41,115,198,227,188,149,229,184, +186,147,19,147,136,192,144,69,75,153,80,200,8,157,121,82,22,132,113,145,13,37,164,189,180,235,166,122,56,230,227,138,13,217, +34,184,124,226,148,24,69,94,102,234,114,30,151,103,28,172,132,31,79,186,106,158,19,79,143,97,43,149,102,42,102,46,148,186,38, +144,169,113,240,242,153,231,120,217,151,195,207,106,39,122,146,153,188,46,39,83,66,128,194,224,248,16,75,206,52,177,147,23,115, +200,44,154,132,251,157,58,129,178,89,152,67,233,216,100,228,226,36,149,156,84,55,19,76,200,154,228,244,209,146,239,52,115,38, +101,186,197,251,194,51,169,51,47,85,146,129,37,63,83,210,17,75,214,200,236,51,47,83,82,27,93,86,200,40,145,159,41,69,146,27,112, +214,145,61,41,103,107,242,22,158,59,21,219,195,239,87,166,78,126,73,67,174,41,233,57,228,85,84,133,6,85,86,249,214,188,41,28, +217,177,84,122,198,183,183,77,197,147,240,141,3,220,86,46,191,123,74,111,36,48,210,251,162,227,100,77,177,47,153,83,211,9,42, +76,101,179,80,253,30,141,138,82,142,236,57,195,116,103,94,58,123,82,35,99,177,81,28,251,228,74,197,144,54,140,146,149,98,223, +42,227,79,245,182,119,44,58,26,234,219,26,154,201,27,60,92,199,102,166,2,236,241,110,103,106,149,11,6,123,234,0,7,201,124,126, +208,153,224,116,124,20,149,99,124,41,192,94,193,68,173,20,39,18,118,74,62,228,72,194,13,41,79,21,211,201,73,249,232,74,169,227, +213,74,129,131,158,51,252,28,120,79,102,149,211,99,113,24,131,63,107,154,80,129,11,11,26,77,76,146,59,157,148,183,54,242,164, +147,58,167,152,51,157,152,205,187,230,157,194,118,248,80,233,116,226,77,214,210,134,237,167,113,58,72,178,117,55,69,196,205, +194,157,111,188,76,109,251,141,171,47,109,171,167,152,120,15,24,116,129,36,135,76,58,34,44,218,73,224,124,85,8,178,172,7,140,213, +163,238,252,19,38,221,111,228,237,180,137,62,33,196,231,89,254,22,97,124,68,220,111,184,243,47,236,55,233,54,97,213,95,111,83, +199,254,126,23,53,28,121,7,196,62,32,164,190,195,82,95,195,254,16,237,21,223,54,220,75,32,251,1,97,54,24,21,23,27,123,42,250, +77,241,65,145,211,240,158,134,157,166,241,160,145,251,225,157,166,249,85,35,127,243,206,142,71,250,182,218,134,109,210,141,74, +201,17,250,190,176,94,23,135,196,103,140,103,240,216,94,143,63,237,244,186,32,119,197,150,183,111,62,80,95,111,76,87,84,154, +244,5,209,64,199,193,204,111,111,167,163,6,207,224,105,126,162,107,101,249,253,134,245,119,113,153,113,139,248,33,198,92,127, +11,221,96,152,234,25,117,207,177,220,163,59,59,232,165,76,225,78,195,84,29,170,238,232,167,198,44,157,221,107,168,206,94,146, +29,124,69,126,126,111,70,237,150,11,140,75,50,162,95,151,149,223,146,159,55,153,6,6,143,65,180,215,211,189,166,241,21,113,35, +143,225,30,211,228,210,227,232,145,62,239,40,127,154,203,143,27,255,132,76,199,230,15,211,23,249,241,211,170,234,1,71,249,33, +46,255,67,149,31,228,242,151,13,89,254,50,119,32,75,119,103,75,223,54,45,250,140,184,77,60,8,157,59,121,118,199,76,140,171,163, +29,139,243,37,99,109,255,206,225,53,91,206,95,83,111,147,177,191,205,69,244,146,172,236,143,155,226,57,81,116,224,17,185,160, +245,231,219,100,139,249,149,171,232,160,197,83,122,183,252,124,15,127,118,28,218,31,44,167,235,45,118,179,10,227,176,213,102, +188,126,201,146,250,71,251,141,252,139,141,125,21,251,247,239,63,16,71,55,162,91,233,91,189,198,22,244,126,151,92,102,17,240, +91,198,171,162,178,243,144,179,171,111,115,79,182,65,71,181,208,92,191,73,183,139,38,200,28,53,106,111,227,74,186,220,195,253, +30,54,141,255,21,221,65,147,158,21,66,184,109,50,5,10,143,88,38,107,20,134,45,92,36,114,109,114,137,74,219,172,151,26,127,105, +137,187,97,142,142,120,229,176,101,220,105,44,31,22,197,126,83,220,110,212,237,55,14,124,131,37,214,187,12,140,245,255,196,122, +186,218,35,238,224,5,16,129,2,139,88,225,175,67,54,205,175,60,139,254,100,153,183,139,95,139,63,112,101,187,153,243,89,67,244, +155,38,84,52,30,50,106,150,24,219,43,108,211,206,89,238,50,93,57,123,45,247,221,104,215,176,217,116,221,38,10,27,224,22,47,137, +5,13,123,77,227,19,198,188,122,12,143,118,217,6,246,206,173,205,152,145,105,187,108,183,113,17,140,143,150,46,151,123,175,233, +249,173,152,35,165,132,233,34,195,87,1,33,136,216,158,74,186,7,54,175,24,238,24,22,115,11,48,118,209,244,77,91,172,110,175,228, +39,227,101,81,7,147,218,70,3,27,22,91,180,178,179,127,255,59,174,180,105,184,157,94,112,203,169,99,222,247,24,203,119,30,49, +177,3,138,238,229,185,7,226,183,236,91,213,191,200,22,219,176,135,239,182,217,228,21,29,123,227,43,140,253,21,135,154,91,227, +13,149,116,92,46,245,143,228,231,119,221,226,86,168,57,96,186,49,241,142,251,228,178,5,77,227,21,33,110,189,213,180,160,13,179, +189,219,16,152,180,121,155,33,246,110,54,237,59,140,165,113,225,181,237,6,151,93,203,38,198,92,45,219,182,93,198,72,133,237,94, +238,18,46,195,101,241,148,141,75,218,80,225,50,74,54,177,20,252,236,117,183,113,183,113,59,59,64,113,129,73,159,54,234,46,196, +0,239,113,161,71,119,254,37,229,244,172,75,60,193,107,185,217,244,96,12,232,246,118,33,130,166,251,43,194,174,52,115,158,23, +107,159,57,16,124,196,180,57,20,109,54,173,235,196,210,91,133,199,118,215,163,159,242,139,121,0,247,154,185,240,166,251,68,161, +223,206,13,26,163,21,24,132,125,139,229,125,141,87,108,111,67,251,218,117,182,119,133,26,40,91,221,206,89,197,99,116,121,92,57, +174,92,35,221,102,231,178,60,125,204,173,198,0,71,68,239,143,30,62,193,219,208,62,98,4,111,182,205,160,177,187,2,61,99,108, +143,152,66,13,131,48,140,67,150,45,251,232,119,153,13,237,93,114,233,237,205,77,210,48,22,61,160,102,215,113,216,34,237,58,240, +229,194,1,83,200,89,89,247,25,107,59,130,188,29,120,161,15,139,194,130,96,53,214,186,125,205,48,154,195,170,193,114,24,232, +105,151,218,241,159,178,13,118,83,148,110,179,5,91,145,224,224,71,132,123,137,26,134,49,103,204,72,84,116,196,141,188,37,198, +190,182,91,132,223,47,59,105,248,72,195,60,250,133,20,204,143,211,29,46,185,216,59,233,25,233,22,249,70,120,204,24,174,232,56, +124,136,227,138,141,142,207,179,13,172,48,236,200,147,131,5,218,113,34,108,182,172,215,102,198,126,73,167,109,194,139,97,72, +172,47,124,27,86,171,52,5,199,199,191,27,230,157,226,179,226,189,58,188,211,251,77,113,208,112,87,180,204,251,98,189,73,55,25, +117,116,136,163,16,182,159,73,191,17,77,159,183,169,29,145,233,81,236,251,138,122,106,103,87,252,130,71,124,10,190,138,16,118, +88,152,134,111,137,113,113,197,133,29,155,247,195,115,110,145,53,249,135,106,141,119,84,40,142,17,22,63,54,74,235,140,69,198, +127,11,43,231,31,162,36,215,88,12,78,185,85,114,126,137,93,50,84,226,81,143,118,137,40,137,130,177,164,36,71,138,214,228,184, +32,91,58,211,108,174,177,132,229,68,233,210,25,94,137,82,94,171,56,6,56,249,51,197,248,140,220,30,227,44,110,107,148,214,148, +46,200,116,119,158,236,189,102,166,127,102,156,93,178,33,195,112,151,156,3,198,26,160,9,82,222,12,147,165,122,75,182,227,179, +39,195,244,96,232,67,37,102,86,54,171,209,144,42,122,51,12,23,24,51,50,114,112,94,12,110,175,26,156,171,180,182,116,97,105,85, +105,168,180,178,180,90,148,88,194,20,57,102,153,129,63,194,104,57,120,208,58,182,112,153,56,88,39,196,109,192,147,192,225,48, +220,30,56,14,60,185,72,136,155,206,18,130,255,145,50,185,182,93,230,33,49,11,200,54,114,92,250,135,56,130,58,46,59,104,189,123, +137,117,185,65,107,196,189,75,132,117,125,189,16,15,212,27,226,231,160,47,3,239,110,16,226,30,224,81,224,96,35,2,188,59,87,182, +235,69,187,7,27,251,196,175,26,133,245,104,147,16,207,2,135,155,133,184,17,248,21,240,151,102,50,132,55,223,16,87,135,118,64, +244,240,210,115,196,109,75,133,120,16,56,6,60,11,92,223,34,196,93,192,195,192,147,192,243,192,27,45,100,9,219,143,201,10,110, +26,69,211,171,151,237,18,15,44,195,8,150,11,241,216,10,104,7,14,175,36,183,59,80,172,196,244,223,61,144,125,114,165,97,92,181, +74,24,215,174,54,141,55,86,11,227,141,54,211,184,171,195,107,220,180,102,204,122,99,173,41,30,239,130,165,186,77,241,100,15, +102,215,99,136,171,214,99,164,27,48,132,141,120,6,158,221,4,221,3,232,99,11,248,192,213,91,13,113,207,86,240,183,193,18,103,195, +186,103,195,2,198,124,193,127,14,10,116,120,253,208,101,152,212,16,38,19,225,159,231,5,189,194,251,46,113,248,160,245,66,132, +107,15,111,23,57,55,1,87,237,200,252,255,74,206,223,244,100,254,239,64,254,173,74,230,255,15,228,223,169,100,254,15,65,254,157, +74,136,212,255,35,200,191,213,201,252,95,130,46,154,249,255,4,77,191,250,29,141,252,61,85,72,253,63,82,219,192,112,133,148,12, +255,123,122,225,87,191,125,231,127,3,111,132,84,191,252,255,15,154,90,158,255,141,182,21,82,191,75,226,127,199,109,135,212,248, +248,223,224,147,214,195,255,38,159,127,204,195,124,254,127,15,255,63,171,27,97,244,48,81,0,0,0,0}; #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ - STATICMETHOD (getAndroidMidiDeviceManager, "getAndroidMidiDeviceManager", "(Landroid/content/Context;)Lcom/roli/juce/JuceMidiSupport$MidiDeviceManager;") \ - STATICMETHOD (getAndroidBluetoothManager, "getAndroidBluetoothManager", "(Landroid/content/Context;)Lcom/roli/juce/JuceMidiSupport$BluetoothManager;") + STATICMETHOD (getAndroidMidiDeviceManager, "getAndroidMidiDeviceManager", "(Landroid/content/Context;)Lcom/rmsl/juce/JuceMidiSupport$MidiDeviceManager;") \ + STATICMETHOD (getAndroidBluetoothManager, "getAndroidBluetoothManager", "(Landroid/content/Context;)Lcom/rmsl/juce/JuceMidiSupport$BluetoothManager;") -DECLARE_JNI_CLASS_WITH_BYTECODE (JuceMidiSupport, "com/roli/juce/JuceMidiSupport", 23, javaMidiByteCode, sizeof (javaMidiByteCode)) +DECLARE_JNI_CLASS_WITH_BYTECODE (JuceMidiSupport, "com/rmsl/juce/JuceMidiSupport", 23, javaMidiByteCode, sizeof (javaMidiByteCode)) #undef JNI_CLASS_MEMBERS #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ METHOD (getJuceAndroidMidiInputDeviceNameAndIDs, "getJuceAndroidMidiInputDeviceNameAndIDs", "()[Ljava/lang/String;") \ METHOD (getJuceAndroidMidiOutputDeviceNameAndIDs, "getJuceAndroidMidiOutputDeviceNameAndIDs", "()[Ljava/lang/String;") \ - METHOD (openMidiInputPortWithID, "openMidiInputPortWithID", "(IJ)Lcom/roli/juce/JuceMidiSupport$JuceMidiPort;") \ - METHOD (openMidiOutputPortWithID, "openMidiOutputPortWithID", "(I)Lcom/roli/juce/JuceMidiSupport$JuceMidiPort;") + METHOD (openMidiInputPortWithID, "openMidiInputPortWithID", "(IJ)Lcom/rmsl/juce/JuceMidiSupport$JuceMidiPort;") \ + METHOD (openMidiOutputPortWithID, "openMidiOutputPortWithID", "(I)Lcom/rmsl/juce/JuceMidiSupport$JuceMidiPort;") -DECLARE_JNI_CLASS_WITH_MIN_SDK (MidiDeviceManager, "com/roli/juce/JuceMidiSupport$MidiDeviceManager", 23) +DECLARE_JNI_CLASS_WITH_MIN_SDK (MidiDeviceManager, "com/rmsl/juce/JuceMidiSupport$MidiDeviceManager", 23) #undef JNI_CLASS_MEMBERS #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ @@ -347,21 +346,21 @@ DECLARE_JNI_CLASS_WITH_MIN_SDK (MidiDeviceManager, "com/roli/juce/JuceMidiSuppor METHOD (sendMidi, "sendMidi", "([BII)V") \ METHOD (getName, "getName", "()Ljava/lang/String;") -DECLARE_JNI_CLASS_WITH_MIN_SDK (JuceMidiPort, "com/roli/juce/JuceMidiSupport$JuceMidiPort", 23) +DECLARE_JNI_CLASS_WITH_MIN_SDK (JuceMidiPort, "com/rmsl/juce/JuceMidiSupport$JuceMidiPort", 23) #undef JNI_CLASS_MEMBERS //============================================================================== -class AndroidMidiInput +class MidiInput::Pimpl { public: - AndroidMidiInput (MidiInput* midiInput, int deviceID, juce::MidiInputCallback* midiInputCallback, jobject deviceManager) + Pimpl (MidiInput* midiInput, int deviceID, juce::MidiInputCallback* midiInputCallback, jobject deviceManager) : juceMidiInput (midiInput), callback (midiInputCallback), midiConcatenator (2048), javaMidiDevice (LocalRef<jobject>(getEnv()->CallObjectMethod (deviceManager, MidiDeviceManager.openMidiInputPortWithID, (jint) deviceID, (jlong) this))) { } - ~AndroidMidiInput() + ~Pimpl() { if (jobject d = javaMidiDevice.get()) { @@ -417,7 +416,7 @@ public: static void handleReceive (JNIEnv*, jobject, jlong host, jbyteArray byteArray, jint offset, jint len, jlong timestamp) { - auto* myself = reinterpret_cast<AndroidMidiInput*> (host); + auto* myself = reinterpret_cast<Pimpl*> (host); myself->handleMidi (byteArray, offset, len, timestamp); } @@ -430,15 +429,15 @@ private: }; //============================================================================== -class AndroidMidiOutput +class MidiOutput::Pimpl { public: - AndroidMidiOutput (const LocalRef<jobject>& midiDevice) + Pimpl (const LocalRef<jobject>& midiDevice) : javaMidiDevice (midiDevice) { } - ~AndroidMidiOutput() + ~Pimpl() { if (jobject d = javaMidiDevice.get()) { @@ -469,9 +468,9 @@ private: //============================================================================== #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ - CALLBACK (AndroidMidiInput::handleReceive, "handleReceive", "(J[BIIJ)V" ) + CALLBACK (MidiInput::Pimpl::handleReceive, "handleReceive", "(J[BIIJ)V" ) -DECLARE_JNI_CLASS_WITH_MIN_SDK (JuceMidiInputPort, "com/roli/juce/JuceMidiSupport$JuceMidiInputPort", 23) +DECLARE_JNI_CLASS_WITH_MIN_SDK (JuceMidiInputPort, "com/rmsl/juce/JuceMidiSupport$JuceMidiInputPort", 23) #undef JNI_CLASS_MEMBERS //============================================================================== @@ -510,11 +509,11 @@ public: return {}; } - AndroidMidiInput* openMidiInputPortWithID (int deviceID, MidiInput* juceMidiInput, juce::MidiInputCallback* callback) + MidiInput::Pimpl* openMidiInputPortWithID (int deviceID, MidiInput* juceMidiInput, juce::MidiInputCallback* callback) { if (auto dm = deviceManager.get()) { - std::unique_ptr<AndroidMidiInput> androidMidiInput (new AndroidMidiInput (juceMidiInput, deviceID, callback, dm)); + auto androidMidiInput = std::make_unique<MidiInput::Pimpl> (juceMidiInput, deviceID, callback, dm); if (androidMidiInput->isOpen()) return androidMidiInput.release(); @@ -523,11 +522,11 @@ public: return nullptr; } - AndroidMidiOutput* openMidiOutputPortWithID (int deviceID) + MidiOutput::Pimpl* openMidiOutputPortWithID (int deviceID) { if (auto dm = deviceManager.get()) if (auto javaMidiPort = getEnv()->CallObjectMethod (dm, MidiDeviceManager.openMidiOutputPortWithID, (jint) deviceID)) - return new AndroidMidiOutput (LocalRef<jobject>(javaMidiPort)); + return new MidiOutput::Pimpl (LocalRef<jobject>(javaMidiPort)); return nullptr; } @@ -565,7 +564,7 @@ std::unique_ptr<MidiInput> MidiInput::openDevice (const String& deviceIdentifier if (auto* port = manager.openMidiInputPortWithID (deviceIdentifier.getIntValue(), midiInput.get(), callback)) { - midiInput->internal = port; + midiInput->internal.reset (port); midiInput->setName (port->getName()); return midiInput; @@ -602,20 +601,17 @@ MidiInput::MidiInput (const String& deviceName, const String& deviceIdentifier) { } -MidiInput::~MidiInput() -{ - delete reinterpret_cast<AndroidMidiInput*> (internal); -} +MidiInput::~MidiInput() = default; void MidiInput::start() { - if (auto* mi = reinterpret_cast<AndroidMidiInput*> (internal)) + if (auto* mi = internal.get()) mi->start(); } void MidiInput::stop() { - if (auto* mi = reinterpret_cast<AndroidMidiInput*> (internal)) + if (auto* mi = internal.get()) mi->stop(); } @@ -647,7 +643,7 @@ std::unique_ptr<MidiOutput> MidiOutput::openDevice (const String& deviceIdentifi if (auto* port = manager.openMidiOutputPortWithID (deviceIdentifier.getIntValue())) { std::unique_ptr<MidiOutput> midiOutput (new MidiOutput ({}, deviceIdentifier)); - midiOutput->internal = port; + midiOutput->internal.reset (port); midiOutput->setName (port->getName()); return midiOutput; @@ -682,13 +678,11 @@ std::unique_ptr<MidiOutput> MidiOutput::openDevice (int index) MidiOutput::~MidiOutput() { stopBackgroundThread(); - - delete reinterpret_cast<AndroidMidiOutput*> (internal); } void MidiOutput::sendMessageNow (const MidiMessage& message) { - if (auto* androidMidi = reinterpret_cast<AndroidMidiOutput*>(internal)) + if (auto* androidMidi = internal.get()) { auto* env = getEnv(); auto messageSize = message.getRawDataSize(); diff --git a/modules/juce_audio_devices/native/juce_android_Oboe.cpp b/modules/juce_audio_devices/native/juce_android_Oboe.cpp index 4d202507..eb1de73d 100644 --- a/modules/juce_audio_devices/native/juce_android_Oboe.cpp +++ b/modules/juce_audio_devices/native/juce_android_Oboe.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2018 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -42,7 +42,7 @@ struct OboeAudioIODeviceBufferHelpers<int16> static constexpr int bitDepth() { return 16; } - static void referAudioBufferDirectlyToOboeIfPossible (int16*, AudioBuffer<float>&, int) {} + static bool referAudioBufferDirectlyToOboeIfPossible (int16*, AudioBuffer<float>&, int) { return false; } static void convertFromOboe (const int16* srcInterleaved, AudioBuffer<float>& audioBuffer, int numSamples) { @@ -78,49 +78,56 @@ struct OboeAudioIODeviceBufferHelpers<float> static constexpr int bitDepth() { return 32; } - static void referAudioBufferDirectlyToOboeIfPossible (float* nativeBuffer, AudioBuffer<float>& audioBuffer, int numSamples) + static bool referAudioBufferDirectlyToOboeIfPossible (float* nativeBuffer, AudioBuffer<float>& audioBuffer, int numSamples) { if (audioBuffer.getNumChannels() == 1) + { audioBuffer.setDataToReferTo (&nativeBuffer, 1, numSamples); + return true; + } + + return false; } static void convertFromOboe (const float* srcInterleaved, AudioBuffer<float>& audioBuffer, int numSamples) { - // No need to convert, we instructed the buffer to point to the src data directly already - if (audioBuffer.getNumChannels() == 1) - { - jassert (audioBuffer.getWritePointer (0) == srcInterleaved); - return; - } + auto numChannels = audioBuffer.getNumChannels(); - for (int i = 0; i < audioBuffer.getNumChannels(); ++i) + if (numChannels > 0) { - using DstSampleType = AudioData::Pointer<AudioData::Float32, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::NonConst>; - using SrcSampleType = AudioData::Pointer<AudioData::Float32, AudioData::NativeEndian, AudioData::Interleaved, AudioData::Const>; + // No need to convert, we instructed the buffer to point to the src data directly already + jassert (audioBuffer.getWritePointer (0) != srcInterleaved); - DstSampleType dstData (audioBuffer.getWritePointer (i)); - SrcSampleType srcData (srcInterleaved + i, audioBuffer.getNumChannels()); - dstData.convertSamples (srcData, numSamples); + for (int i = 0; i < numChannels; ++i) + { + using DstSampleType = AudioData::Pointer<AudioData::Float32, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::NonConst>; + using SrcSampleType = AudioData::Pointer<AudioData::Float32, AudioData::NativeEndian, AudioData::Interleaved, AudioData::Const>; + + DstSampleType dstData (audioBuffer.getWritePointer (i)); + SrcSampleType srcData (srcInterleaved + i, audioBuffer.getNumChannels()); + dstData.convertSamples (srcData, numSamples); + } } } static void convertToOboe (const AudioBuffer<float>& audioBuffer, float* dstInterleaved, int numSamples) { - // No need to convert, we instructed the buffer to point to the src data directly already - if (audioBuffer.getNumChannels() == 1) - { - jassert (audioBuffer.getReadPointer (0) == dstInterleaved); - return; - } + auto numChannels = audioBuffer.getNumChannels(); - for (int i = 0; i < audioBuffer.getNumChannels(); ++i) + if (numChannels > 0) { - using DstSampleType = AudioData::Pointer<AudioData::Float32, AudioData::NativeEndian, AudioData::Interleaved, AudioData::NonConst>; - using SrcSampleType = AudioData::Pointer<AudioData::Float32, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::Const>; + // No need to convert, we instructed the buffer to point to the src data directly already + jassert (audioBuffer.getReadPointer (0) != dstInterleaved); - DstSampleType dstData (dstInterleaved + i, audioBuffer.getNumChannels()); - SrcSampleType srcData (audioBuffer.getReadPointer (i)); - dstData.convertSamples (srcData, numSamples); + for (int i = 0; i < numChannels; ++i) + { + using DstSampleType = AudioData::Pointer<AudioData::Float32, AudioData::NativeEndian, AudioData::Interleaved, AudioData::NonConst>; + using SrcSampleType = AudioData::Pointer<AudioData::Float32, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::Const>; + + DstSampleType dstData (dstInterleaved + i, audioBuffer.getNumChannels()); + SrcSampleType srcData (audioBuffer.getReadPointer (i)); + dstData.convertSamples (srcData, numSamples); + } } } }; @@ -151,11 +158,9 @@ public: supportedOutputSampleRates (supportedOutputSampleRatesToUse), maxNumOutputChannels (maxNumOutputChannelsToUse) { - // At least an input or an output has to be supported by the device! - jassert (inputDeviceId != -1 || outputDeviceId != -1); } - ~OboeAudioIODevice() + ~OboeAudioIODevice() override { close(); } @@ -197,16 +202,7 @@ public: Array<int> getAvailableBufferSizes() override { - // we need to offer the lowest possible buffer size which - // is the native buffer size - const int defaultNumMultiples = 8; - const int nativeBufferSize = getNativeBufferSize(); - Array<int> bufferSizes; - - for (int i = 1; i < defaultNumMultiples; ++i) - bufferSizes.add (i * nativeBufferSize); - - return bufferSizes; + return AndroidHighPerformanceAudioHelpers::getAvailableBufferSizes (getNativeBufferSize(), getAvailableSampleRates()); } String open (const BigInteger& inputChannels, const BigInteger& outputChannels, @@ -215,8 +211,8 @@ public: close(); lastError.clear(); - sampleRate = (int) requestedSampleRate; + sampleRate = (int) (requestedSampleRate > 0 ? requestedSampleRate : AndroidHighPerformanceAudioHelpers::getNativeSampleRate()); actualBufferSize = (bufferSize <= 0) ? getDefaultBufferSize() : bufferSize; // The device may report no max, claiming "no limits". Pick sensible defaults. @@ -274,16 +270,12 @@ public: int getDefaultBufferSize() override { - // Only on a Pro-Audio device will we set the lowest possible buffer size - // by default. We need to be more conservative on other devices - // as they may be low-latency, but still have a crappy CPU. - return (isProAudioDevice() ? 1 : 6) - * getNativeBufferSize(); + return AndroidHighPerformanceAudioHelpers::getDefaultBufferSize (getNativeBufferSize(), getCurrentSampleRate()); } double getCurrentSampleRate() override { - return (sampleRate == 0.0 ? getNativeSampleRate() : sampleRate); + return (sampleRate == 0.0 ? AndroidHighPerformanceAudioHelpers::getNativeSampleRate() : sampleRate); } void start (AudioIODeviceCallback* newCallback) override @@ -375,10 +367,11 @@ private: { static const int standardRates[] = { 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 }; + Array<int> rates (standardRates, numElementsInArray (standardRates)); // make sure the native sample rate is part of the list - int native = (int) getNativeSampleRate(); + int native = (int) AndroidHighPerformanceAudioHelpers::getNativeSampleRate(); if (native != 0 && ! rates.contains (native)) rates.add (native); @@ -386,6 +379,39 @@ private: return rates; } + static int getNativeBufferSize() + { + auto bufferSizeHint = AndroidHighPerformanceAudioHelpers::getNativeBufferSizeHint(); + + // providing a callback is required on some devices to get a FAST track, so we pass an + // empty one to the temp stream to get the best available buffer size + struct DummyCallback : public oboe::AudioStreamCallback + { + oboe::DataCallbackResult onAudioReady (oboe::AudioStream*, void*, int32_t) override { return oboe::DataCallbackResult::Stop; } + }; + + DummyCallback callback; + + // NB: Exclusive mode could be rejected if a device is already opened in that mode, so to get + // reliable results, only use this function when a device is closed. + // We initially try to open a stream with a buffer size returned from + // android.media.property.OUTPUT_FRAMES_PER_BUFFER property, but then we verify the actual + // size after the stream is open. + OboeAudioIODevice::OboeStream tempStream (oboe::kUnspecified, + oboe::Direction::Output, + oboe::SharingMode::Exclusive, + 2, + getAndroidSDKVersion() >= 21 ? oboe::AudioFormat::Float : oboe::AudioFormat::I16, + (int) AndroidHighPerformanceAudioHelpers::getNativeSampleRate(), + bufferSizeHint, + &callback); + + if (auto* nativeStream = tempStream.getNativeStream()) + return nativeStream->getFramesPerBurst(); + + return bufferSizeHint; + } + void setCallback (AudioIODeviceCallback* callbackToUse) { if (! running) @@ -435,11 +461,11 @@ private: OboeStream (int deviceId, oboe::Direction direction, oboe::SharingMode sharingMode, int channelCount, oboe::AudioFormat format, - int32 sampleRate, int32 bufferSize, - oboe::AudioStreamCallback* callback = nullptr) + int32 sampleRateIn, int32 bufferSize, + oboe::AudioStreamCallback* callbackIn = nullptr) { open (deviceId, direction, sharingMode, channelCount, - format, sampleRate, bufferSize, callback); + format, sampleRateIn, bufferSize, callbackIn); } ~OboeStream() @@ -481,7 +507,7 @@ private: + "\nFramesPerCallback = " + String (stream->getFramesPerCallback()) + "\nBytesPerFrame = " + String (stream->getBytesPerFrame()) + "\nBytesPerSample = " + String (stream->getBytesPerSample()) - + "\nPerformanceMode = " + getOboeString (oboe::PerformanceMode::LowLatency) + + "\nPerformanceMode = " + getOboeString (stream->getPerformanceMode()) + "\ngetDeviceId = " + String (stream->getDeviceId())); } } @@ -511,10 +537,10 @@ private: void open (int deviceId, oboe::Direction direction, oboe::SharingMode sharingMode, int channelCount, oboe::AudioFormat format, - int32 sampleRate, int32 bufferSize, - oboe::AudioStreamCallback* callback = nullptr) + int32 newSampleRate, int32 newBufferSize, + oboe::AudioStreamCallback* newCallback = nullptr) { - oboe::DefaultStreamValues::FramesPerBurst = getDefaultFramesPerBurst(); + oboe::DefaultStreamValues::FramesPerBurst = AndroidHighPerformanceAudioHelpers::getNativeBufferSizeHint(); oboe::AudioStreamBuilder builder; @@ -526,9 +552,18 @@ private: builder.setSharingMode (sharingMode); builder.setChannelCount (channelCount); builder.setFormat (format); - builder.setSampleRate (sampleRate); + builder.setSampleRate (newSampleRate); builder.setPerformanceMode (oboe::PerformanceMode::LowLatency); - builder.setCallback (callback); + + #if JUCE_USE_ANDROID_OBOE_STABILIZED_CALLBACK + if (newCallback != nullptr) + { + stabilizedCallback = std::make_unique<oboe::StabilizedCallback> (newCallback); + builder.setCallback (stabilizedCallback.get()); + } + #else + builder.setCallback (newCallback); + #endif JUCE_OBOE_LOG (String ("Preparing Oboe stream with params:") + "\nAAudio supported = " + String (int (builder.isAAudioSupported())) @@ -538,17 +573,17 @@ private: + "\nSharingMode = " + getOboeString (sharingMode) + "\nChannelCount = " + String (channelCount) + "\nFormat = " + getOboeString (format) - + "\nSampleRate = " + String (sampleRate) + + "\nSampleRate = " + String (newSampleRate) + "\nPerformanceMode = " + getOboeString (oboe::PerformanceMode::LowLatency)); openResult = builder.openStream (&stream); JUCE_OBOE_LOG ("Building Oboe stream with result: " + getOboeString (openResult) + "\nStream state = " + (stream != nullptr ? getOboeString (stream->getState()) : String ("?"))); - if (stream != nullptr && bufferSize != 0) + if (stream != nullptr && newBufferSize != 0) { - JUCE_OBOE_LOG ("Setting the bufferSizeInFrames to " + String (bufferSize)); - stream->setBufferSizeInFrames (bufferSize); + JUCE_OBOE_LOG ("Setting the bufferSizeInFrames to " + String (newBufferSize)); + stream->setBufferSizeInFrames (newBufferSize); } JUCE_OBOE_LOG (String ("Stream details:") @@ -565,7 +600,7 @@ private: + "\nFramesPerCallback = " + (stream != nullptr ? String (stream->getFramesPerCallback()) : String ("?")) + "\nBytesPerFrame = " + (stream != nullptr ? String (stream->getBytesPerFrame()) : String ("?")) + "\nBytesPerSample = " + (stream != nullptr ? String (stream->getBytesPerSample()) : String ("?")) - + "\nPerformanceMode = " + getOboeString (oboe::PerformanceMode::LowLatency)); + + "\nPerformanceMode = " + (stream != nullptr ? getOboeString (stream->getPerformanceMode()) : String ("?"))); } void close() @@ -573,11 +608,15 @@ private: if (stream != nullptr) { oboe::Result result = stream->close(); + ignoreUnused (result); JUCE_OBOE_LOG ("Requested Oboe stream close with result: " + getOboeString (result)); } } oboe::AudioStream* stream = nullptr; + #if JUCE_USE_ANDROID_OBOE_STABILIZED_CALLBACK + std::unique_ptr<oboe::StabilizedCallback> stabilizedCallback; + #endif oboe::Result openResult; }; @@ -665,16 +704,16 @@ private: } // Not strictly required as these should not change, but recommended by Google anyway - void checkStreamSetup (OboeStream* stream, int deviceId, int numChannels, int sampleRate, - int bufferSize, oboe::AudioFormat format) + void checkStreamSetup (OboeStream* stream, int deviceId, int numChannels, int expectedSampleRate, + int expectedBufferSize, oboe::AudioFormat format) { if (auto* nativeStream = stream != nullptr ? stream->getNativeStream() : nullptr) { - ignoreUnused (deviceId, numChannels, sampleRate, bufferSize); + ignoreUnused (deviceId, numChannels, sampleRate, expectedBufferSize); ignoreUnused (streamFormat, bitDepth); - jassert (numChannels == nativeStream->getChannelCount()); - jassert (sampleRate == 0 || sampleRate == nativeStream->getSampleRate()); + jassert (numChannels == 0 || numChannels == nativeStream->getChannelCount()); + jassert (expectedSampleRate == 0 || expectedSampleRate == nativeStream->getSampleRate()); jassert (format == nativeStream->getFormat()); } } @@ -706,11 +745,11 @@ private: { public: OboeSessionImpl (OboeAudioIODevice& ownerToUse, - int inputDeviceId, int outputDeviceId, + int inputDeviceIdIn, int outputDeviceIdIn, int numInputChannelsToUse, int numOutputChannelsToUse, int sampleRateToUse, int bufferSizeToUse) : OboeSessionBase (ownerToUse, - inputDeviceId, outputDeviceId, + inputDeviceIdIn, outputDeviceIdIn, numInputChannelsToUse, numOutputChannelsToUse, sampleRateToUse, bufferSizeToUse, OboeAudioIODeviceBufferHelpers<SampleType>::oboeAudioFormat(), @@ -754,7 +793,7 @@ private: if (stream == nullptr || ! openedOk()) return false; - auto result = stream->getNativeStream()->getTimestamp (CLOCK_MONOTONIC, 0, 0); + auto result = stream->getNativeStream()->getTimestamp (CLOCK_MONOTONIC, nullptr, nullptr); return result != oboe::Result::ErrorUnimplemented; } @@ -768,7 +807,6 @@ private: // only output stream should be the master stream receiving callbacks jassert (stream->getDirection() == oboe::Direction::Output && stream == outputStream->getNativeStream()); - //----------------- // Read input from Oboe inputStreamSampleBuffer.clear(); inputStreamNativeBuffer.calloc (static_cast<size_t> (numInputChannels * bufferSize)); @@ -788,11 +826,13 @@ private: if (result) { - OboeAudioIODeviceBufferHelpers<SampleType>::referAudioBufferDirectlyToOboeIfPossible (inputStreamNativeBuffer.get(), - inputStreamSampleBuffer, - result.value()); + auto referringDirectlyToOboeData = OboeAudioIODeviceBufferHelpers<SampleType> + ::referAudioBufferDirectlyToOboeIfPossible (inputStreamNativeBuffer.get(), + inputStreamSampleBuffer, + result.value()); - OboeAudioIODeviceBufferHelpers<SampleType>::convertFromOboe (inputStreamNativeBuffer.get(), inputStreamSampleBuffer, result.value()); + if (! referringDirectlyToOboeData) + OboeAudioIODeviceBufferHelpers<SampleType>::convertFromOboe (inputStreamNativeBuffer.get(), inputStreamSampleBuffer, result.value()); } else { @@ -803,24 +843,24 @@ private: inputLatency = getLatencyFor (*inputStream); } - //----------------- // Setup output buffer - outputStreamSampleBuffer.clear(); + auto referringDirectlyToOboeData = OboeAudioIODeviceBufferHelpers<SampleType> + ::referAudioBufferDirectlyToOboeIfPossible (static_cast<SampleType*> (audioData), + outputStreamSampleBuffer, + numFrames); - OboeAudioIODeviceBufferHelpers<SampleType>::referAudioBufferDirectlyToOboeIfPossible (static_cast<SampleType*> (audioData), - outputStreamSampleBuffer, - numFrames); + if (! referringDirectlyToOboeData) + outputStreamSampleBuffer.clear(); - //----------------- // Process // NB: the number of samples read from the input can potentially differ from numFrames. owner.process (inputStreamSampleBuffer.getArrayOfReadPointers(), numInputChannels, outputStreamSampleBuffer.getArrayOfWritePointers(), numOutputChannels, numFrames); - //----------------- // Write output to Oboe - OboeAudioIODeviceBufferHelpers<SampleType>::convertToOboe (outputStreamSampleBuffer, static_cast<SampleType*> (audioData), numFrames); + if (! referringDirectlyToOboeData) + OboeAudioIODeviceBufferHelpers<SampleType>::convertToOboe (outputStreamSampleBuffer, static_cast<SampleType*> (audioData), numFrames); if (isOutputLatencyDetectionSupported) outputLatency = getLatencyFor (*outputStream); @@ -847,7 +887,7 @@ private: + "\nFramesPerCallback = " + (stream != nullptr ? String (stream->getFramesPerCallback()) : String ("?")) + "\nBytesPerFrame = " + (stream != nullptr ? String (stream->getBytesPerFrame()) : String ("?")) + "\nBytesPerSample = " + (stream != nullptr ? String (stream->getBytesPerSample()) : String ("?")) - + "\nPerformanceMode = " + getOboeString (oboe::PerformanceMode::LowLatency) + + "\nPerformanceMode = " + (stream != nullptr ? getOboeString (stream->getPerformanceMode()) : String ("?")) + "\ngetDeviceId = " + (stream != nullptr ? String (stream->getDeviceId()) : String ("?"))); } @@ -874,9 +914,7 @@ private: const int64_t appFrameIndex = isOutput ? nativeStream.getFramesWritten() : nativeStream.getFramesRead(); // Assume that the next frame will be processed at the current time - using namespace std::chrono; - int64_t appFrameAppTime = getCurrentTimeNanos();//duration_cast<nanoseconds> (steady_clock::now().time_since_epoch()).count(); - int64_t appFrameAppTime2 = duration_cast<nanoseconds> (steady_clock::now().time_since_epoch()).count(); + int64_t appFrameAppTime = getCurrentTimeNanos(); // Calculate the number of frames between app and hardware int64_t frameIndexDelta = appFrameIndex - hardwareFrameIndex; @@ -903,6 +941,8 @@ private: void onErrorBeforeClose (oboe::AudioStream* stream, oboe::Result error) override { + ignoreUnused (error); + // only output stream should be the master stream receiving callbacks jassert (stream->getDirection() == oboe::Direction::Output); @@ -928,7 +968,7 @@ private: Thread::sleep (1); outputStream = nullptr; - outputStream.reset (new OboeStream (-1, + outputStream.reset (new OboeStream (oboe::kUnspecified, oboe::Direction::Output, oboe::SharingMode::Exclusive, numOutputChannels, @@ -980,31 +1020,6 @@ private: bool running = false; - //============================================================================== - static double getNativeSampleRate() - { - return audioManagerGetProperty ("android.media.property.OUTPUT_SAMPLE_RATE").getDoubleValue(); - } - - static int getNativeBufferSize() - { - auto val = audioManagerGetProperty ("android.media.property.OUTPUT_FRAMES_PER_BUFFER").getIntValue(); - return val > 0 ? val : 512; - } - - static bool isProAudioDevice() - { - return androidHasSystemFeature ("android.hardware.audio.pro"); - } - - static int getDefaultFramesPerBurst() - { - // NB: this function only works for inbuilt speakers and headphones - auto framesPerBurstString = javaString (audioManagerGetProperty ("android.media.property.OUTPUT_FRAMES_PER_BUFFER")); - - return framesPerBurstString != 0 ? getEnv()->CallStaticIntMethod (JavaInteger, JavaInteger.parseInt, framesPerBurstString.get(), 10) : 192; - } - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OboeAudioIODevice) }; @@ -1060,9 +1075,6 @@ public: StringArray getDeviceNames (bool wantInputNames) const override { - if (inputDevices.isEmpty() && outputDevices.isEmpty()) - return StringArray (OboeAudioIODevice::oboeTypeName); - StringArray names; for (auto& device : wantInputNames ? inputDevices : outputDevices) @@ -1071,36 +1083,8 @@ public: return names; } - int getDefaultDeviceIndex (bool forInput) const override + int getDefaultDeviceIndex (bool) const override { - // No need to create a stream when only one default device is created. - if (! supportsDevicesInfo()) - return 0; - - if (forInput && (! RuntimePermissions::isGranted (RuntimePermissions::recordAudio))) - return 0; - - // Create stream with a default device ID and query the stream for its device ID - using OboeStream = OboeAudioIODevice::OboeStream; - - OboeStream tempStream (-1, - forInput ? oboe::Direction::Input : oboe::Direction::Output, - oboe::SharingMode::Shared, - forInput ? 1 : 2, - getAndroidSDKVersion() >= 21 ? oboe::AudioFormat::Float : oboe::AudioFormat::I16, - (int) OboeAudioIODevice::getNativeSampleRate(), - OboeAudioIODevice::getNativeBufferSize(), - nullptr); - - if (auto* nativeStream = tempStream.getNativeStream()) - { - auto& devices = forInput ? inputDevices : outputDevices; - - for (int i = 0; i < devices.size(); ++i) - if (devices.getReference (i).id == nativeStream->getDeviceId()) - return i; - } - return 0; } @@ -1129,12 +1113,8 @@ public: auto outputDeviceInfo = getDeviceInfoForName (outputDeviceName, false); auto inputDeviceInfo = getDeviceInfoForName (inputDeviceName, true); - if (outputDeviceInfo.name.isEmpty() && inputDeviceInfo.name.isEmpty()) - { - // Invalid device name passed. It must be one of the names returned by getDeviceNames(). - jassertfalse; + if (outputDeviceInfo.id < 0 && inputDeviceInfo.id < 0) return nullptr; - } auto& name = outputDeviceInfo.name.isNotEmpty() ? outputDeviceInfo.name : inputDeviceInfo.name; @@ -1158,24 +1138,22 @@ public: private: void checkAvailableDevices() { - if (! supportsDevicesInfo()) - { - auto sampleRates = OboeAudioIODevice::getDefaultSampleRates(); + auto sampleRates = OboeAudioIODevice::getDefaultSampleRates(); - inputDevices .add ({ OboeAudioIODevice::oboeTypeName, -1, sampleRates, 1 }); - outputDevices.add ({ OboeAudioIODevice::oboeTypeName, -1, sampleRates, 2 }); + inputDevices .add ({ "System Default (Input)", oboe::kUnspecified, sampleRates, 1 }); + outputDevices.add ({ "System Default (Output)", oboe::kUnspecified, sampleRates, 2 }); + if (! supportsDevicesInfo()) return; - } auto* env = getEnv(); jclass audioManagerClass = env->FindClass ("android/media/AudioManager"); // We should be really entering here only if API supports it. - jassert (audioManagerClass != 0); + jassert (audioManagerClass != nullptr); - if (audioManagerClass == 0) + if (audioManagerClass == nullptr) return; auto audioManager = LocalRef<jobject> (env->CallObjectMethod (getAppContext().get(), @@ -1202,6 +1180,8 @@ public: for (auto& device : inputDevices) { + ignoreUnused (device); + JUCE_OBOE_LOG ("name = " << device.name); JUCE_OBOE_LOG ("id = " << String (device.id)); JUCE_OBOE_LOG ("sample rates size = " << String (device.sampleRates.size())); @@ -1212,6 +1192,8 @@ public: for (auto& device : outputDevices) { + ignoreUnused (device); + JUCE_OBOE_LOG ("name = " << device.name); JUCE_OBOE_LOG ("id = " << String (device.id)); JUCE_OBOE_LOG ("sample rates size = " << String (device.sampleRates.size())); @@ -1238,9 +1220,13 @@ public: jmethodID getChannelCountsMethod = env->GetMethodID (deviceClass, "getChannelCounts", "()[I"); jmethodID isSourceMethod = env->GetMethodID (deviceClass, "isSource", "()Z"); - auto name = juceString ((jstring) env->CallObjectMethod (device, getProductNameMethod)); - name << deviceTypeToString (env->CallIntMethod (device, getTypeMethod)); - int id = env->CallIntMethod (device, getIdMethod); + auto deviceTypeString = deviceTypeToString (env->CallIntMethod (device, getTypeMethod)); + + if (deviceTypeString.isEmpty()) // unknown device + return; + + auto name = juceString ((jstring) env->CallObjectMethod (device, getProductNameMethod)) + " " + deviceTypeString; + auto id = env->CallIntMethod (device, getIdMethod); auto jSampleRates = LocalRef<jintArray> ((jintArray) env->CallObjectMethod (device, getSampleRatesMethod)); auto sampleRates = jintArrayToJuceArray (jSampleRates); @@ -1249,40 +1235,43 @@ public: auto channelCounts = jintArrayToJuceArray (jChannelCounts); int numChannels = channelCounts.isEmpty() ? -1 : channelCounts.getLast(); - bool isInput = env->CallBooleanMethod (device, isSourceMethod); + auto isInput = env->CallBooleanMethod (device, isSourceMethod); auto& devices = isInput ? inputDevices : outputDevices; devices.add ({ name, id, sampleRates, numChannels }); } - static const char* deviceTypeToString (int type) + static String deviceTypeToString (int type) { switch (type) { - case 0: return ""; - case 1: return " built-in earphone speaker"; - case 2: return " built-in speaker"; - case 3: return " wired headset"; - case 4: return " wired headphones"; - case 5: return " line analog"; - case 6: return " line digital"; - case 7: return " Bluetooth device typically used for telephony"; - case 8: return " Bluetooth device supporting the A2DP profile"; - case 9: return " HDMI"; - case 10: return " HDMI audio return channel"; - case 11: return " USB device"; - case 12: return " USB accessory"; - case 13: return " DOCK"; - case 14: return " FM"; - case 15: return " built-in microphone"; - case 16: return " FM tuner"; - case 17: return " TV tuner"; - case 18: return " telephony"; - case 19: return " auxiliary line-level connectors"; - case 20: return " IP"; - case 21: return " BUS"; - case 22: return " USB headset"; - default: jassertfalse; return ""; // type not supported yet, needs to be added! + case 0: return {}; + case 1: return "built-in earphone speaker"; + case 2: return "built-in speaker"; + case 3: return "wired headset"; + case 4: return "wired headphones"; + case 5: return "line analog"; + case 6: return "line digital"; + case 7: return "Bluetooth device typically used for telephony"; + case 8: return "Bluetooth device supporting the A2DP profile"; + case 9: return "HDMI"; + case 10: return "HDMI audio return channel"; + case 11: return "USB device"; + case 12: return "USB accessory"; + case 13: return "DOCK"; + case 14: return "FM"; + case 15: return "built-in microphone"; + case 16: return "FM tuner"; + case 17: return "TV tuner"; + case 18: return "telephony"; + case 19: return "auxiliary line-level connectors"; + case 20: return "IP"; + case 21: return "BUS"; + case 22: return "USB headset"; + case 23: return "hearing aid"; + case 24: return "built-in speaker safe"; + case 25: return {}; + default: jassertfalse; return {}; // type not supported yet, needs to be added! } } @@ -1290,7 +1279,7 @@ public: { auto* env = getEnv(); - jint* jArrayElems = env->GetIntArrayElements (jArray, 0); + jint* jArrayElems = env->GetIntArrayElements (jArray, nullptr); int numElems = env->GetArrayLength (jArray); Array<int> juceArray; @@ -1305,19 +1294,21 @@ public: struct DeviceInfo { String name; - int id; + int id = -1; Array<int> sampleRates; int numChannels; }; DeviceInfo getDeviceInfoForName (const String& name, bool isInput) { - if (name.isEmpty()) - return {}; - - for (auto& device : isInput ? inputDevices : outputDevices) - if (device.name == name) - return device; + if (name.isNotEmpty()) + { + for (auto& device : isInput ? inputDevices : outputDevices) + { + if (device.name == name) + return device; + } + } return {}; } @@ -1329,15 +1320,8 @@ public: const char* const OboeAudioIODevice::oboeTypeName = "Android Oboe"; - -//============================================================================== bool isOboeAvailable() { return OboeAudioIODeviceType::isOboeAvailable(); } -AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_Oboe() -{ - return isOboeAvailable() ? new OboeAudioIODeviceType() : nullptr; -} - //============================================================================== class OboeRealtimeThread : private oboe::AudioStreamCallback { @@ -1345,12 +1329,12 @@ class OboeRealtimeThread : private oboe::AudioStreamCallback public: OboeRealtimeThread() - : testStream (new OboeStream (-1, + : testStream (new OboeStream (oboe::kUnspecified, oboe::Direction::Output, oboe::SharingMode::Exclusive, 1, oboe::AudioFormat::Float, - (int) OboeAudioIODevice::getNativeSampleRate(), + (int) AndroidHighPerformanceAudioHelpers::getNativeSampleRate(), OboeAudioIODevice::getNativeBufferSize(), this)), formatUsed (oboe::AudioFormat::Float) @@ -1358,12 +1342,12 @@ public: // Fallback to I16 stream format if Float has not worked if (! testStream->openedOk()) { - testStream.reset (new OboeStream (-1, + testStream.reset (new OboeStream (oboe::kUnspecified, oboe::Direction::Output, oboe::SharingMode::Exclusive, 1, oboe::AudioFormat::I16, - (int) OboeAudioIODevice::getNativeSampleRate(), + (int) AndroidHighPerformanceAudioHelpers::getNativeSampleRate(), OboeAudioIODevice::getNativeBufferSize(), this)); @@ -1411,7 +1395,7 @@ public: threadEntryProc (threadUserPtr); threadEntryProc = nullptr; - MessageManager::callAsync ([this] () { delete this; }); + MessageManager::callAsync ([this]() { delete this; }); return oboe::DataCallbackResult::Stop; } @@ -1446,15 +1430,19 @@ private: oboe::AudioFormat formatUsed; }; +//============================================================================== pthread_t juce_createRealtimeAudioThread (void* (*entry) (void*), void* userPtr) { - std::unique_ptr<OboeRealtimeThread> thread (new OboeRealtimeThread()); + auto thread = std::make_unique<OboeRealtimeThread>(); if (! thread->isOk()) return {}; auto threadID = thread->startThread (entry, userPtr); - thread.release(); // the thread will de-allocate itself + + // the thread will de-allocate itself + thread.release(); + return threadID; } diff --git a/modules/juce_audio_devices/native/juce_android_OpenSL.cpp b/modules/juce_audio_devices/native/juce_android_OpenSL.cpp index 4a19f771..2bb38b40 100644 --- a/modules/juce_audio_devices/native/juce_android_OpenSL.cpp +++ b/modules/juce_audio_devices/native/juce_android_OpenSL.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -71,12 +71,11 @@ static void destroyObject (SLObjectType object) (*object)->Destroy (object); } -template <> -struct ContainerDeletePolicy<const SLObjectItf_* const> +struct SLObjectItfFree { - static void destroy (SLObjectItf object) + void operator() (SLObjectItf obj) const noexcept { - destroyObject (object); + destroyObject (obj); } }; @@ -112,7 +111,7 @@ private: ControlBlock() = default; ControlBlock (SLObjectItf o) : ptr (o) {} - std::unique_ptr<const SLObjectItf_* const> ptr; + std::unique_ptr<const SLObjectItf_* const, SLObjectItfFree> ptr; }; ReferenceCountedObjectPtr<ControlBlock> cb; @@ -852,10 +851,11 @@ public: static const double rates[] = { 8000.0, 11025.0, 12000.0, 16000.0, 22050.0, 24000.0, 32000.0, 44100.0, 48000.0 }; + Array<double> retval (rates, numElementsInArray (rates)); // make sure the native sample rate is part of the list - double native = getNativeSampleRate(); + double native = AndroidHighPerformanceAudioHelpers::getNativeSampleRate(); if (native != 0.0 && ! retval.contains (native)) retval.add (native); @@ -865,17 +865,8 @@ public: Array<int> getAvailableBufferSizes() override { - // we need to offer the lowest possible buffer size which - // is the native buffer size - auto nativeBufferSize = getNativeBufferSize(); - auto minBuffersToQueue = getMinimumBuffersToEnqueue(); - auto maxBuffersToQueue = getMaximumBuffersToEnqueue(); - - Array<int> retval; - for (int i = minBuffersToQueue; i <= maxBuffersToQueue; ++i) - retval.add (i * nativeBufferSize); - - return retval; + return AndroidHighPerformanceAudioHelpers::getAvailableBufferSizes (AndroidHighPerformanceAudioHelpers::getNativeBufferSizeHint(), + getAvailableSampleRates()); } String open (const BigInteger& inputChannels, @@ -887,15 +878,25 @@ public: lastError.clear(); - sampleRate = (int) (requestedSampleRate > 0 ? requestedSampleRate : getNativeSampleRate()); + sampleRate = (int) (requestedSampleRate > 0 ? requestedSampleRate : AndroidHighPerformanceAudioHelpers::getNativeSampleRate()); + auto preferredBufferSize = (bufferSize > 0) ? bufferSize : getDefaultBufferSize(); + + audioBuffersToEnqueue = [this, preferredBufferSize] + { + using namespace AndroidHighPerformanceAudioHelpers; + + auto nativeBufferSize = getNativeBufferSizeHint(); - auto totalPreferredBufferSize = (bufferSize <= 0) ? getDefaultBufferSize() : bufferSize; - auto nativeBufferSize = getNativeBufferSize(); - bool useHighPerformanceAudioPath = canUseHighPerformanceAudioPath (totalPreferredBufferSize, sampleRate); + if (canUseHighPerformanceAudioPath (nativeBufferSize, preferredBufferSize, sampleRate)) + return preferredBufferSize / nativeBufferSize; - audioBuffersToEnqueue = useHighPerformanceAudioPath ? (totalPreferredBufferSize / nativeBufferSize) : 1; - actualBufferSize = totalPreferredBufferSize / audioBuffersToEnqueue; - jassert ((actualBufferSize * audioBuffersToEnqueue) == totalPreferredBufferSize); + + return 1; + }(); + + actualBufferSize = preferredBufferSize / audioBuffersToEnqueue; + + jassert ((actualBufferSize * audioBuffersToEnqueue) == preferredBufferSize); activeOutputChans = outputChannels; activeOutputChans.setRange (2, activeOutputChans.getHighestBit(), false); @@ -934,8 +935,8 @@ public: DBG ("OpenSL: numInputChannels = " << numInputChannels << ", numOutputChannels = " << numOutputChannels - << ", nativeBufferSize = " << getNativeBufferSize() - << ", nativeSampleRate = " << getNativeSampleRate() + << ", nativeBufferSize = " << AndroidHighPerformanceAudioHelpers::getNativeBufferSizeHint() + << ", nativeSampleRate = " << AndroidHighPerformanceAudioHelpers::getNativeSampleRate() << ", actualBufferSize = " << actualBufferSize << ", audioBuffersToEnqueue = " << audioBuffersToEnqueue << ", sampleRate = " << sampleRate @@ -968,16 +969,13 @@ public: int getDefaultBufferSize() override { - auto defaultBufferLength = (hasLowLatencyAudioPath() ? defaultBufferSizeForLowLatencyDeviceMs - : defaultBufferSizeForStandardLatencyDeviceMs); - - auto defaultBuffersToEnqueue = buffersToQueueForBufferDuration (defaultBufferLength, getCurrentSampleRate()); - return defaultBuffersToEnqueue * getNativeBufferSize(); + return AndroidHighPerformanceAudioHelpers::getDefaultBufferSize (AndroidHighPerformanceAudioHelpers::getNativeBufferSizeHint(), + getCurrentSampleRate()); } double getCurrentSampleRate() override { - return (sampleRate == 0.0 ? getNativeSampleRate() : sampleRate); + return (sampleRate == 0.0 ? AndroidHighPerformanceAudioHelpers::getNativeSampleRate() : sampleRate); } void start (AudioIODeviceCallback* newCallback) override @@ -1048,91 +1046,6 @@ private: std::unique_ptr<OpenSLSession> session; - enum - { - defaultBufferSizeForLowLatencyDeviceMs = 40, - defaultBufferSizeForStandardLatencyDeviceMs = 100 - }; - - static int getMinimumBuffersToEnqueue (double sampleRateToCheck = getNativeSampleRate()) - { - if (canUseHighPerformanceAudioPath (getNativeBufferSize(), (int) sampleRateToCheck)) - { - // see https://developer.android.com/ndk/guides/audio/opensl/opensl-prog-notes.html#sandp - // "For Android 4.2 (API level 17) and earlier, a buffer count of two or more is required - // for lower latency. Beginning with Android 4.3 (API level 18), a buffer count of one - // is sufficient for lower latency." - return (getAndroidSDKVersion() >= 18 ? 1 : 2); - } - - // we will not use the low-latency path so we can use the absolute minimum number of buffers - // to queue - return 1; - } - - int getMaximumBuffersToEnqueue() noexcept - { - constexpr auto maxBufferSizeMs = 200; - - auto availableSampleRates = getAvailableSampleRates(); - auto maximumSampleRate = findMaximum(availableSampleRates.getRawDataPointer(), availableSampleRates.size()); - - // ensure we don't return something crazy small - return jmax (8, buffersToQueueForBufferDuration (maxBufferSizeMs, maximumSampleRate)); - } - - static int buffersToQueueForBufferDuration (int bufferDurationInMs, double sampleRate) noexcept - { - auto maxBufferFrames = static_cast<int> (std::ceil (bufferDurationInMs * sampleRate / 1000.0)); - auto maxNumBuffers = static_cast<int> (std::ceil (static_cast<double> (maxBufferFrames) - / static_cast<double> (getNativeBufferSize()))); - - return jmax (getMinimumBuffersToEnqueue (sampleRate), maxNumBuffers); - } - - //============================================================================== - static double getNativeSampleRate() - { - return audioManagerGetProperty ("android.media.property.OUTPUT_SAMPLE_RATE").getDoubleValue(); - } - - static int getNativeBufferSize() - { - const int val = audioManagerGetProperty ("android.media.property.OUTPUT_FRAMES_PER_BUFFER").getIntValue(); - return val > 0 ? val : 512; - } - - static bool isProAudioDevice() - { - return androidHasSystemFeature ("android.hardware.audio.pro") || isSapaSupported(); - } - - static bool hasLowLatencyAudioPath() - { - return androidHasSystemFeature ("android.hardware.audio.low_latency"); - } - - static bool canUseHighPerformanceAudioPath (int requestedBufferSize, int requestedSampleRate) - { - return ((requestedBufferSize % getNativeBufferSize()) == 0) - && (requestedSampleRate == getNativeSampleRate()) - && isProAudioDevice(); - } - - //============================================================================== - // Some minimum Sapa support to check if this device supports pro audio - static bool isSamsungDevice() - { - return SystemStats::getDeviceManufacturer().containsIgnoreCase ("SAMSUNG"); - } - - static bool isSapaSupported() - { - static bool supported = isSamsungDevice() && DynamicLibrary().open ("libapa_jni.so"); - - return supported; - } - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OpenSLAudioIODevice) }; @@ -1207,11 +1120,6 @@ const char* const OpenSLAudioIODevice::openSLTypeName = "Android OpenSL"; //============================================================================== bool isOpenSLAvailable() { return OpenSLAudioDeviceType::isOpenSLAvailable(); } -AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_OpenSLES() -{ - return isOpenSLAvailable() ? new OpenSLAudioDeviceType() : nullptr; -} - //============================================================================== class SLRealtimeThread { @@ -1263,7 +1171,7 @@ public: SLDataLocator_OutputMix outputMixLocator = {SL_DATALOCATOR_OUTPUTMIX, outputMix}; PCMDataFormatEx dataFormat; - BufferHelpers<int16>::initPCMDataFormat (dataFormat, 1, OpenSLAudioIODevice::getNativeSampleRate()); + BufferHelpers<int16>::initPCMDataFormat (dataFormat, 1, AndroidHighPerformanceAudioHelpers::getNativeSampleRate()); SLDataSource source = { &queueLocator, &dataFormat }; SLDataSink sink = { &outputMixLocator, nullptr }; @@ -1306,7 +1214,7 @@ public: } } - bool isOK() const { return queue != nullptr; } + bool isOk() const { return queue != nullptr; } pthread_t startThread (void* (*entry) (void*), void* userPtr) { @@ -1346,7 +1254,7 @@ public: threadEntryProc = nullptr; (*player)->SetPlayState (player, SL_PLAYSTATE_STOPPED); - MessageManager::callAsync ([this] () { delete this; }); + MessageManager::callAsync ([this]() { delete this; }); } } @@ -1365,7 +1273,7 @@ private: SlRef<SLPlayItf_> player; SlRef<SLAndroidSimpleBufferQueueItf_> queue; - int bufferSize = OpenSLAudioIODevice::getNativeBufferSize(); + int bufferSize = AndroidHighPerformanceAudioHelpers::getNativeBufferSizeHint(); HeapBlock<int16> buffer { HeapBlock<int16> (static_cast<size_t> (1 * bufferSize * numBuffers)) }; void* (*threadEntryProc) (void*) = nullptr; @@ -1376,14 +1284,15 @@ private: pthread_t threadID; }; +//============================================================================== pthread_t juce_createRealtimeAudioThread (void* (*entry) (void*), void* userPtr) { - std::unique_ptr<SLRealtimeThread> thread (new SLRealtimeThread); + auto thread = std::make_unique<SLRealtimeThread>(); - if (! thread->isOK()) - return 0; + if (! thread->isOk()) + return {}; - pthread_t threadID = thread->startThread (entry, userPtr); + auto threadID = thread->startThread (entry, userPtr); // the thread will de-allocate itself thread.release(); diff --git a/modules/juce_audio_devices/native/juce_ios_Audio.cpp b/modules/juce_audio_devices/native/juce_ios_Audio.cpp index 23da27ea..7de777d3 100644 --- a/modules/juce_audio_devices/native/juce_ios_Audio.cpp +++ b/modules/juce_audio_devices/native/juce_ios_Audio.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -671,6 +671,7 @@ struct iOSAudioIODevice::Pimpl : public AudioPlayHead, //============================================================================== #if JUCE_MODULE_AVAILABLE_juce_graphics + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wdeprecated-declarations") Image getIcon (int size) { if (interAppAudioConnected) @@ -681,6 +682,7 @@ struct iOSAudioIODevice::Pimpl : public AudioPlayHead, } return Image(); } + JUCE_END_IGNORE_WARNINGS_GCC_LIKE #endif void switchApplication() @@ -1429,12 +1431,6 @@ void iOSAudioIODeviceType::handleAsyncUpdate() callDeviceChangeListeners(); } -//============================================================================== -AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_iOSAudio() -{ - return new iOSAudioIODeviceType(); -} - //============================================================================== AudioSessionHolder::AudioSessionHolder() { nativeSession = [[iOSAudioSessionNative alloc] init: this]; } AudioSessionHolder::~AudioSessionHolder() { [nativeSession release]; } diff --git a/modules/juce_audio_devices/native/juce_ios_Audio.h b/modules/juce_audio_devices/native/juce_ios_Audio.h index 97ad3487..4d066e7a 100644 --- a/modules/juce_audio_devices/native/juce_ios_Audio.h +++ b/modules/juce_audio_devices/native/juce_ios_Audio.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_devices/native/juce_linux_ALSA.cpp b/modules/juce_audio_devices/native/juce_linux_ALSA.cpp index f126c1dc..323fe13e 100644 --- a/modules/juce_audio_devices/native/juce_linux_ALSA.cpp +++ b/modules/juce_audio_devices/native/juce_linux_ALSA.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -791,7 +791,7 @@ private: //============================================================================== const String inputId, outputId; std::unique_ptr<ALSADevice> outputDevice, inputDevice; - int numCallbacks = 0; + std::atomic<int> numCallbacks { 0 }; bool audioIoInProgress = false; CriticalSection callbackLock; @@ -1299,9 +1299,4 @@ AudioIODeviceType* createAudioIODeviceType_ALSA_PCMDevices() return new ALSAAudioIODeviceType (false, "ALSA"); } -AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_ALSA() -{ - return createAudioIODeviceType_ALSA_PCMDevices(); -} - } // namespace juce diff --git a/modules/juce_audio_devices/native/juce_linux_Bela.cpp b/modules/juce_audio_devices/native/juce_linux_Bela.cpp index 133e39bc..69bb5a09 100644 --- a/modules/juce_audio_devices/native/juce_linux_Bela.cpp +++ b/modules/juce_audio_devices/native/juce_linux_Bela.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -24,12 +24,12 @@ namespace juce { //============================================================================== -class BelaMidiInput +class MidiInput::Pimpl { public: - static Array<BelaMidiInput*> midiInputs; + static Array<Pimpl*> midiInputs; - BelaMidiInput (const String& port, MidiInput* input, MidiInputCallback* callback) + Pimpl (const String& port, MidiInput* input, MidiInputCallback* callback) : midiInput (input), midiPort (port), midiCallback (callback) { jassert (midiCallback != nullptr); @@ -38,7 +38,7 @@ public: buffer.resize (32); } - ~BelaMidiInput() + ~Pimpl() { stop(); midiInputs.removeAllInstancesOf (this); @@ -76,7 +76,7 @@ public: } if (receivedBytes > 0) - pushMidiData (receivedBytes); + pushMidiData ((int) receivedBytes); } static Array<MidiDeviceInfo> getDevices (bool input) @@ -141,7 +141,7 @@ private: snd_rawmidi_info_t* info; snd_rawmidi_info_alloca (&info); - snd_rawmidi_info_set_device (info, device); + snd_rawmidi_info_set_device (info, (unsigned int) device); snd_rawmidi_info_set_stream (info, input ? SND_RAWMIDI_STREAM_INPUT : SND_RAWMIDI_STREAM_OUTPUT); @@ -173,10 +173,10 @@ private: Midi midi; MidiDataConcatenator concatenator { 512 }; - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BelaMidiInput) + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Pimpl) }; -Array<BelaMidiInput*> BelaMidiInput::midiInputs; +Array<MidiInput::Pimpl*> MidiInput::Pimpl::midiInputs; //============================================================================== @@ -366,7 +366,7 @@ public: String getLastError() override { return lastError; } //============================================================================== - int getCurrentBufferSizeSamples() override { return actualBufferSize; } + int getCurrentBufferSizeSamples() override { return (int) actualBufferSize; } double getCurrentSampleRate() override { return 44100.0; } int getCurrentBitDepth() override { return 16; } BigInteger getActiveOutputChannels() const override { BigInteger b; b.setRange (0, actualNumberOfOutputs, true); return b; } @@ -384,8 +384,8 @@ private: bool setup (BelaContext& context) { actualBufferSize = context.audioFrames; - actualNumberOfInputs = context.audioInChannels + context.analogInChannels; - actualNumberOfOutputs = context.audioOutChannels + context.analogOutChannels; + actualNumberOfInputs = (int) (context.audioInChannels + context.analogInChannels); + actualNumberOfOutputs = (int) (context.audioOutChannels + context.analogOutChannels); isBelaOpen = true; firstCallback = true; @@ -405,7 +405,7 @@ private: ScopedLock lock (callbackLock); // Check for and process and midi - for (auto midiInput : BelaMidiInput::midiInputs) + for (auto midiInput : MidiInput::Pimpl::midiInputs) midiInput->poll(); if (callback != nullptr) @@ -413,27 +413,29 @@ private: jassert (context.audioFrames <= actualBufferSize); jassert ((context.flags & BELA_FLAG_INTERLEAVED) == 0); + using Frames = decltype (context.audioFrames); + // Setup channelInBuffers for (int ch = 0; ch < actualNumberOfInputs; ++ch) { if (ch < analogChannelStart) - channelInBuffer[ch] = &context.audioIn[ch * context.audioFrames]; + channelInBuffer[ch] = &context.audioIn[(Frames) ch * context.audioFrames]; else - channelInBuffer[ch] = &context.analogIn[(ch - analogChannelStart) * context.analogFrames]; + channelInBuffer[ch] = &context.analogIn[(Frames) (ch - analogChannelStart) * context.analogFrames]; } // Setup channelOutBuffers for (int ch = 0; ch < actualNumberOfOutputs; ++ch) { if (ch < analogChannelStart) - channelOutBuffer[ch] = &context.audioOut[ch * context.audioFrames]; + channelOutBuffer[ch] = &context.audioOut[(Frames) ch * context.audioFrames]; else - channelOutBuffer[ch] = &context.analogOut[(ch - analogChannelStart) * context.audioFrames]; + channelOutBuffer[ch] = &context.analogOut[(Frames) (ch - analogChannelStart) * context.audioFrames]; } callback->audioDeviceIOCallback (channelInBuffer.getData(), actualNumberOfInputs, channelOutBuffer.getData(), actualNumberOfOutputs, - context.audioFrames); + (int) context.audioFrames); } } @@ -521,25 +523,19 @@ struct BelaAudioIODeviceType : public AudioIODeviceType JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BelaAudioIODeviceType) }; -//============================================================================== -AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_Bela() -{ - return new BelaAudioIODeviceType(); -} - //============================================================================== MidiInput::MidiInput (const String& deviceName, const String& deviceID) : deviceInfo (deviceName, deviceID) { } -MidiInput::~MidiInput() { delete static_cast<BelaMidiInput*> (internal); } -void MidiInput::start() { static_cast<BelaMidiInput*> (internal)->start(); } -void MidiInput::stop() { static_cast<BelaMidiInput*> (internal)->stop(); } +MidiInput::~MidiInput() = default; +void MidiInput::start() { internal->start(); } +void MidiInput::stop() { internal->stop(); } Array<MidiDeviceInfo> MidiInput::getAvailableDevices() { - return BelaMidiInput::getDevices (true); + return Pimpl::getDevices (true); } MidiDeviceInfo MidiInput::getDefaultDevice() @@ -553,7 +549,7 @@ std::unique_ptr<MidiInput> MidiInput::openDevice (const String& deviceIdentifier return {}; std::unique_ptr<MidiInput> midiInput (new MidiInput (deviceIdentifier, deviceIdentifier)); - midiInput->internal = new BelaMidiInput (deviceIdentifier, midiInput.get(), callback); + midiInput->internal = std::make_unique<Pimpl> (deviceIdentifier, midiInput.get(), callback); return midiInput; } @@ -587,7 +583,8 @@ std::unique_ptr<MidiInput> MidiInput::openDevice (int index, MidiInputCallback* //============================================================================== // TODO: Add Bela MidiOutput support -MidiOutput::~MidiOutput() {} +class MidiOutput::Pimpl {}; +MidiOutput::~MidiOutput() = default; void MidiOutput::sendMessageNow (const MidiMessage&) {} Array<MidiDeviceInfo> MidiOutput::getAvailableDevices() { return {}; } MidiDeviceInfo MidiOutput::getDefaultDevice() { return {}; } diff --git a/modules/juce_audio_devices/native/juce_linux_JackAudio.cpp b/modules/juce_audio_devices/native/juce_linux_JackAudio.cpp index b916d7aa..2c353c67 100644 --- a/modules/juce_audio_devices/native/juce_linux_JackAudio.cpp +++ b/modules/juce_audio_devices/native/juce_linux_JackAudio.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -36,9 +36,11 @@ static void* juce_loadJackFunction (const char* const name) #define JUCE_DECL_JACK_FUNCTION(return_type, fn_name, argument_types, arguments) \ return_type fn_name argument_types \ { \ + using ReturnType = return_type; \ typedef return_type (*fn_type) argument_types; \ static fn_type fn = (fn_type) juce_loadJackFunction (#fn_name); \ - return (fn != nullptr) ? ((*fn) arguments) : (return_type) 0; \ + jassert (fn != nullptr); \ + return (fn != nullptr) ? ((*fn) arguments) : ReturnType(); \ } #define JUCE_DECL_VOID_JACK_FUNCTION(fn_name, argument_types, arguments) \ @@ -46,30 +48,35 @@ static void* juce_loadJackFunction (const char* const name) { \ typedef void (*fn_type) argument_types; \ static fn_type fn = (fn_type) juce_loadJackFunction (#fn_name); \ + jassert (fn != nullptr); \ if (fn != nullptr) (*fn) arguments; \ } //============================================================================== -JUCE_DECL_JACK_FUNCTION (jack_client_t*, jack_client_open, (const char* client_name, jack_options_t options, jack_status_t* status, ...), (client_name, options, status)); -JUCE_DECL_JACK_FUNCTION (int, jack_client_close, (jack_client_t *client), (client)); -JUCE_DECL_JACK_FUNCTION (int, jack_activate, (jack_client_t* client), (client)); -JUCE_DECL_JACK_FUNCTION (int, jack_deactivate, (jack_client_t* client), (client)); -JUCE_DECL_JACK_FUNCTION (jack_nframes_t, jack_get_buffer_size, (jack_client_t* client), (client)); -JUCE_DECL_JACK_FUNCTION (jack_nframes_t, jack_get_sample_rate, (jack_client_t* client), (client)); -JUCE_DECL_VOID_JACK_FUNCTION (jack_on_shutdown, (jack_client_t* client, void (*function)(void* arg), void* arg), (client, function, arg)); -JUCE_DECL_JACK_FUNCTION (void* , jack_port_get_buffer, (jack_port_t* port, jack_nframes_t nframes), (port, nframes)); -JUCE_DECL_JACK_FUNCTION (jack_nframes_t, jack_port_get_total_latency, (jack_client_t* client, jack_port_t* port), (client, port)); -JUCE_DECL_JACK_FUNCTION (jack_port_t* , jack_port_register, (jack_client_t* client, const char* port_name, const char* port_type, unsigned long flags, unsigned long buffer_size), (client, port_name, port_type, flags, buffer_size)); -JUCE_DECL_VOID_JACK_FUNCTION (jack_set_error_function, (void (*func)(const char*)), (func)); -JUCE_DECL_JACK_FUNCTION (int, jack_set_process_callback, (jack_client_t* client, JackProcessCallback process_callback, void* arg), (client, process_callback, arg)); -JUCE_DECL_JACK_FUNCTION (const char**, jack_get_ports, (jack_client_t* client, const char* port_name_pattern, const char* type_name_pattern, unsigned long flags), (client, port_name_pattern, type_name_pattern, flags)); -JUCE_DECL_JACK_FUNCTION (int, jack_connect, (jack_client_t* client, const char* source_port, const char* destination_port), (client, source_port, destination_port)); -JUCE_DECL_JACK_FUNCTION (const char*, jack_port_name, (const jack_port_t* port), (port)); -JUCE_DECL_JACK_FUNCTION (void*, jack_set_port_connect_callback, (jack_client_t* client, JackPortConnectCallback connect_callback, void* arg), (client, connect_callback, arg)); -JUCE_DECL_JACK_FUNCTION (jack_port_t* , jack_port_by_id, (jack_client_t* client, jack_port_id_t port_id), (client, port_id)); -JUCE_DECL_JACK_FUNCTION (int, jack_port_connected, (const jack_port_t* port), (port)); -JUCE_DECL_JACK_FUNCTION (int, jack_port_connected_to, (const jack_port_t* port, const char* port_name), (port, port_name)); -JUCE_DECL_JACK_FUNCTION (int, jack_set_xrun_callback, (jack_client_t* client, JackXRunCallback xrun_callback, void* arg), (client, xrun_callback, arg)); +JUCE_DECL_JACK_FUNCTION (jack_client_t*, jack_client_open, (const char* client_name, jack_options_t options, jack_status_t* status, ...), (client_name, options, status)) +JUCE_DECL_JACK_FUNCTION (int, jack_client_close, (jack_client_t *client), (client)) +JUCE_DECL_JACK_FUNCTION (int, jack_activate, (jack_client_t* client), (client)) +JUCE_DECL_JACK_FUNCTION (int, jack_deactivate, (jack_client_t* client), (client)) +JUCE_DECL_JACK_FUNCTION (jack_nframes_t, jack_get_buffer_size, (jack_client_t* client), (client)) +JUCE_DECL_JACK_FUNCTION (jack_nframes_t, jack_get_sample_rate, (jack_client_t* client), (client)) +JUCE_DECL_VOID_JACK_FUNCTION (jack_on_shutdown, (jack_client_t* client, void (*function)(void* arg), void* arg), (client, function, arg)) +JUCE_DECL_VOID_JACK_FUNCTION (jack_on_info_shutdown, (jack_client_t* client, JackInfoShutdownCallback function, void* arg), (client, function, arg)) +JUCE_DECL_JACK_FUNCTION (void* , jack_port_get_buffer, (jack_port_t* port, jack_nframes_t nframes), (port, nframes)) +JUCE_DECL_JACK_FUNCTION (jack_nframes_t, jack_port_get_total_latency, (jack_client_t* client, jack_port_t* port), (client, port)) +JUCE_DECL_JACK_FUNCTION (jack_port_t* , jack_port_register, (jack_client_t* client, const char* port_name, const char* port_type, unsigned long flags, unsigned long buffer_size), (client, port_name, port_type, flags, buffer_size)) +JUCE_DECL_VOID_JACK_FUNCTION (jack_set_error_function, (void (*func)(const char*)), (func)) +JUCE_DECL_JACK_FUNCTION (int, jack_set_process_callback, (jack_client_t* client, JackProcessCallback process_callback, void* arg), (client, process_callback, arg)) +JUCE_DECL_JACK_FUNCTION (const char**, jack_get_ports, (jack_client_t* client, const char* port_name_pattern, const char* type_name_pattern, unsigned long flags), (client, port_name_pattern, type_name_pattern, flags)) +JUCE_DECL_JACK_FUNCTION (int, jack_connect, (jack_client_t* client, const char* source_port, const char* destination_port), (client, source_port, destination_port)) +JUCE_DECL_JACK_FUNCTION (const char*, jack_port_name, (const jack_port_t* port), (port)) +JUCE_DECL_JACK_FUNCTION (void*, jack_set_port_connect_callback, (jack_client_t* client, JackPortConnectCallback connect_callback, void* arg), (client, connect_callback, arg)) +JUCE_DECL_JACK_FUNCTION (jack_port_t* , jack_port_by_id, (jack_client_t* client, jack_port_id_t port_id), (client, port_id)) +JUCE_DECL_JACK_FUNCTION (int, jack_port_connected, (const jack_port_t* port), (port)) +JUCE_DECL_JACK_FUNCTION (int, jack_port_connected_to, (const jack_port_t* port, const char* port_name), (port, port_name)) +JUCE_DECL_JACK_FUNCTION (int, jack_set_xrun_callback, (jack_client_t* client, JackXRunCallback xrun_callback, void* arg), (client, xrun_callback, arg)) +JUCE_DECL_JACK_FUNCTION (int, jack_port_flags, (const jack_port_t* port), (port)) +JUCE_DECL_JACK_FUNCTION (jack_port_t*, jack_port_by_name, (jack_client_t* client, const char* name), (client, name)) +JUCE_DECL_VOID_JACK_FUNCTION (jack_free, (void* ptr), (ptr)) #if JUCE_DEBUG #define JACK_LOGGING_ENABLED 1 @@ -115,56 +122,56 @@ namespace struct JackPortIterator { JackPortIterator (jack_client_t* const client, const bool forInput) - : ports (nullptr), index (-1) { if (client != nullptr) - ports = juce::jack_get_ports (client, nullptr, nullptr, - forInput ? JackPortIsOutput : JackPortIsInput); - // (NB: This looks like it's the wrong way round, but it is correct!) - } - - ~JackPortIterator() - { - ::free (ports); + ports.reset (juce::jack_get_ports (client, nullptr, nullptr, + forInput ? JackPortIsInput : JackPortIsOutput)); } bool next() { - if (ports == nullptr || ports [index + 1] == nullptr) + if (ports == nullptr || ports.get()[index + 1] == nullptr) return false; - name = CharPointer_UTF8 (ports[++index]); - clientName = name.upToFirstOccurrenceOf (":", false, false); + name = CharPointer_UTF8 (ports.get()[++index]); return true; } - const char** ports; - int index; + String getClientName() const + { + return name.upToFirstOccurrenceOf (":", false, false); + } + + String getChannelName() const + { + return name.fromFirstOccurrenceOf (":", false, false); + } + + struct Free + { + void operator() (const char** ptr) const noexcept { juce::jack_free (ptr); } + }; + + std::unique_ptr<const char*, Free> ports; + int index = -1; String name; - String clientName; }; -class JackAudioIODeviceType; -static Array<JackAudioIODeviceType*> activeDeviceTypes; - //============================================================================== class JackAudioIODevice : public AudioIODevice { public: - JackAudioIODevice (const String& deviceName, - const String& inId, - const String& outId) - : AudioIODevice (deviceName, "JACK"), - inputId (inId), - outputId (outId), - deviceIsOpen (false), - callback (nullptr), - totalNumberOfInputChannels (0), - totalNumberOfOutputChannels (0) - { - jassert (deviceName.isNotEmpty()); - - jack_status_t status; + JackAudioIODevice (const String& inName, + const String& outName, + std::function<void()> notifyIn) + : AudioIODevice (outName.isEmpty() ? inName : outName, "JACK"), + inputName (inName), + outputName (outName), + notifyChannelsChanged (std::move (notifyIn)) + { + jassert (outName.isNotEmpty() || inName.isNotEmpty()); + + jack_status_t status = {}; client = juce::jack_client_open (JUCE_JACK_CLIENT_NAME, JackNoStartServer, &status); if (client == nullptr) @@ -179,10 +186,10 @@ public: const StringArray inputChannels (getInputChannelNames()); for (int i = 0; i < inputChannels.size(); ++i) { - String inputName; - inputName << "in_" << ++totalNumberOfInputChannels; + String inputChannelName; + inputChannelName << "in_" << ++totalNumberOfInputChannels; - inputPorts.add (juce::jack_port_register (client, inputName.toUTF8(), + inputPorts.add (juce::jack_port_register (client, inputChannelName.toUTF8(), JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0)); } @@ -190,10 +197,10 @@ public: const StringArray outputChannels (getOutputChannelNames()); for (int i = 0; i < outputChannels.size(); ++i) { - String outputName; - outputName << "out_" << ++totalNumberOfOutputChannels; + String outputChannelName; + outputChannelName << "out_" << ++totalNumberOfOutputChannels; - outputPorts.add (juce::jack_port_register (client, outputName.toUTF8(), + outputPorts.add (juce::jack_port_register (client, outputChannelName.toUTF8(), JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)); } @@ -202,7 +209,7 @@ public: } } - ~JackAudioIODevice() + ~JackAudioIODevice() override { close(); if (client != nullptr) @@ -212,19 +219,19 @@ public: } } - StringArray getChannelNames (bool forInput) const + StringArray getChannelNames (const String& clientName, bool forInput) const { StringArray names; for (JackPortIterator i (client, forInput); i.next();) - if (i.clientName == getName()) - names.add (i.name.fromFirstOccurrenceOf (":", false, false)); + if (i.getClientName() == clientName) + names.add (i.getChannelName()); return names; } - StringArray getOutputChannelNames() override { return getChannelNames (false); } - StringArray getInputChannelNames() override { return getChannelNames (true); } + StringArray getOutputChannelNames() override { return getChannelNames (outputName, true); } + StringArray getInputChannelNames() override { return getChannelNames (inputName, false); } Array<double> getAvailableSampleRates() override { @@ -241,15 +248,29 @@ public: Array<int> sizes; if (client != nullptr) - sizes.add (juce::jack_get_buffer_size (client)); + sizes.add (static_cast<int> (juce::jack_get_buffer_size (client))); return sizes; } int getDefaultBufferSize() override { return getCurrentBufferSizeSamples(); } - int getCurrentBufferSizeSamples() override { return client != nullptr ? juce::jack_get_buffer_size (client) : 0; } - double getCurrentSampleRate() override { return client != nullptr ? juce::jack_get_sample_rate (client) : 0; } + int getCurrentBufferSizeSamples() override { return client != nullptr ? static_cast<int> (juce::jack_get_buffer_size (client)) : 0; } + double getCurrentSampleRate() override { return client != nullptr ? static_cast<int> (juce::jack_get_sample_rate (client)) : 0; } + + template <typename Fn> + void forEachClientChannel (const String& clientName, bool isInput, Fn&& fn) + { + auto index = 0; + for (JackPortIterator i (client, isInput); i.next();) + { + if (i.getClientName() != clientName) + continue; + + fn (i.ports.get()[i.index], index); + index += 1; + } + } String open (const BigInteger& inputChannels, const BigInteger& outputChannels, double /* sampleRate */, int /* bufferSizeSamples */) override @@ -263,38 +284,55 @@ public: lastError.clear(); close(); - xruns = 0; + xruns.store (0, std::memory_order_relaxed); juce::jack_set_process_callback (client, processCallback, this); juce::jack_set_port_connect_callback (client, portConnectCallback, this); juce::jack_on_shutdown (client, shutdownCallback, this); + juce::jack_on_info_shutdown (client, infoShutdownCallback, this); juce::jack_set_xrun_callback (client, xrunCallback, this); juce::jack_activate (client); deviceIsOpen = true; if (! inputChannels.isZero()) { - for (JackPortIterator i (client, true); i.next();) + forEachClientChannel (inputName, false, [&] (const char* portName, int index) { - if (inputChannels [i.index] && i.clientName == getName()) - { - int error = juce::jack_connect (client, i.ports[i.index], juce::jack_port_name ((jack_port_t*) inputPorts[i.index])); - if (error != 0) - JUCE_JACK_LOG ("Cannot connect input port " + String (i.index) + " (" + i.name + "), error " + String (error)); - } - } + if (! inputChannels[index]) + return; + + jassert (index < inputPorts.size()); + + const auto* source = portName; + const auto* inputPort = inputPorts[index]; + + jassert (juce::jack_port_flags (juce::jack_port_by_name (client, source)) & JackPortIsOutput); + jassert (juce::jack_port_flags (inputPort) & JackPortIsInput); + + auto error = juce::jack_connect (client, source, juce::jack_port_name (inputPort)); + if (error != 0) + JUCE_JACK_LOG ("Cannot connect input port " + String (index) + " (" + portName + "), error " + String (error)); + }); } if (! outputChannels.isZero()) { - for (JackPortIterator i (client, false); i.next();) + forEachClientChannel (outputName, true, [&] (const char* portName, int index) { - if (outputChannels [i.index] && i.clientName == getName()) - { - int error = juce::jack_connect (client, juce::jack_port_name ((jack_port_t*) outputPorts[i.index]), i.ports[i.index]); - if (error != 0) - JUCE_JACK_LOG ("Cannot connect output port " + String (i.index) + " (" + i.name + "), error " + String (error)); - } - } + if (! outputChannels[index]) + return; + + jassert (index < outputPorts.size()); + + const auto* outputPort = outputPorts[index]; + const auto* destination = portName; + + jassert (juce::jack_port_flags (outputPort) & JackPortIsOutput); + jassert (juce::jack_port_flags (juce::jack_port_by_name (client, destination)) & JackPortIsInput); + + auto error = juce::jack_connect (client, juce::jack_port_name (outputPort), destination); + if (error != 0) + JUCE_JACK_LOG ("Cannot connect output port " + String (index) + " (" + portName + "), error " + String (error)); + }); } updateActivePorts(); @@ -308,12 +346,15 @@ public: if (client != nullptr) { - juce::jack_deactivate (client); + const auto result = juce::jack_deactivate (client); + jassert (result == 0); + ignoreUnused (result); juce::jack_set_xrun_callback (client, xrunCallback, nullptr); juce::jack_set_process_callback (client, processCallback, nullptr); juce::jack_set_port_connect_callback (client, portConnectCallback, nullptr); juce::jack_on_shutdown (client, shutdownCallback, nullptr); + juce::jack_on_info_shutdown (client, infoShutdownCallback, nullptr); } deviceIsOpen = false; @@ -347,7 +388,7 @@ public: bool isPlaying() override { return callback != nullptr; } int getCurrentBitDepth() override { return 32; } String getLastError() override { return lastError; } - int getXRunCount() const noexcept override { return xruns; } + int getXRunCount() const noexcept override { return xruns.load (std::memory_order_relaxed); } BigInteger getActiveOutputChannels() const override { return activeOutputChannels; } BigInteger getActiveInputChannels() const override { return activeInputChannels; } @@ -357,7 +398,7 @@ public: int latency = 0; for (int i = 0; i < outputPorts.size(); i++) - latency = jmax (latency, (int) juce::jack_port_get_total_latency (client, (jack_port_t*) outputPorts [i])); + latency = jmax (latency, (int) juce::jack_port_get_total_latency (client, outputPorts[i])); return latency; } @@ -367,14 +408,36 @@ public: int latency = 0; for (int i = 0; i < inputPorts.size(); i++) - latency = jmax (latency, (int) juce::jack_port_get_total_latency (client, (jack_port_t*) inputPorts [i])); + latency = jmax (latency, (int) juce::jack_port_get_total_latency (client, inputPorts[i])); return latency; } - String inputId, outputId; + String inputName, outputName; private: + //============================================================================== + class MainThreadDispatcher : private AsyncUpdater + { + public: + explicit MainThreadDispatcher (JackAudioIODevice& device) : ref (device) {} + ~MainThreadDispatcher() override { cancelPendingUpdate(); } + + void updateActivePorts() + { + if (MessageManager::getInstance()->isThisTheMessageThread()) + handleAsyncUpdate(); + else + triggerAsyncUpdate(); + } + + private: + void handleAsyncUpdate() override { ref.updateActivePorts(); } + + JackAudioIODevice& ref; + }; + + //============================================================================== void process (const int numSamples) { int numActiveInChans = 0, numActiveOutChans = 0; @@ -382,17 +445,17 @@ private: for (int i = 0; i < totalNumberOfInputChannels; ++i) { if (activeInputChannels[i]) - if (jack_default_audio_sample_t* in - = (jack_default_audio_sample_t*) juce::jack_port_get_buffer ((jack_port_t*) inputPorts.getUnchecked(i), numSamples)) - inChans [numActiveInChans++] = (float*) in; + if (auto* in = (jack_default_audio_sample_t*) juce::jack_port_get_buffer (inputPorts.getUnchecked (i), + static_cast<jack_nframes_t> (numSamples))) + inChans[numActiveInChans++] = (float*) in; } for (int i = 0; i < totalNumberOfOutputChannels; ++i) { if (activeOutputChannels[i]) - if (jack_default_audio_sample_t* out - = (jack_default_audio_sample_t*) juce::jack_port_get_buffer ((jack_port_t*) outputPorts.getUnchecked(i), numSamples)) - outChans [numActiveOutChans++] = (float*) out; + if (auto* out = (jack_default_audio_sample_t*) juce::jack_port_get_buffer (outputPorts.getUnchecked (i), + static_cast<jack_nframes_t> (numSamples))) + outChans[numActiveOutChans++] = (float*) out; } const ScopedLock sl (callbackLock); @@ -406,14 +469,14 @@ private: else { for (int i = 0; i < numActiveOutChans; ++i) - zeromem (outChans[i], sizeof (float) * numSamples); + zeromem (outChans[i], static_cast<size_t> (numSamples) * sizeof (float)); } } static int processCallback (jack_nframes_t nframes, void* callbackArgument) { if (callbackArgument != nullptr) - ((JackAudioIODevice*) callbackArgument)->process (nframes); + ((JackAudioIODevice*) callbackArgument)->process (static_cast<int> (nframes)); return 0; } @@ -431,11 +494,11 @@ private: BigInteger newOutputChannels, newInputChannels; for (int i = 0; i < outputPorts.size(); ++i) - if (juce::jack_port_connected ((jack_port_t*) outputPorts.getUnchecked(i))) + if (juce::jack_port_connected (outputPorts.getUnchecked (i))) newOutputChannels.setBit (i); for (int i = 0; i < inputPorts.size(); ++i) - if (juce::jack_port_connected ((jack_port_t*) inputPorts.getUnchecked(i))) + if (juce::jack_port_connected (inputPorts.getUnchecked (i))) newInputChannels.setBit (i); if (newOutputChannels != activeOutputChannels @@ -451,14 +514,15 @@ private: if (oldCallback != nullptr) start (oldCallback); - sendDeviceChangedCallback(); + if (notifyChannelsChanged != nullptr) + notifyChannelsChanged(); } } static void portConnectCallback (jack_port_id_t, jack_port_id_t, int, void* arg) { if (JackAudioIODevice* device = static_cast<JackAudioIODevice*> (arg)) - device->updateActivePorts(); + device->mainThreadDispatcher.updateActivePorts(); } static void threadInitCallback (void* /* callbackArgument */) @@ -477,81 +541,76 @@ private: } } + static void infoShutdownCallback (jack_status_t code, const char* reason, void* arg) + { + jassert (code == 0); + ignoreUnused (code); + + JUCE_JACK_LOG ("Shutting down with message:"); + JUCE_JACK_LOG (reason); + ignoreUnused (reason); + + shutdownCallback (arg); + } + static void errorCallback (const char* msg) { JUCE_JACK_LOG ("JackAudioIODevice::errorCallback " + String (msg)); + ignoreUnused (msg); } - static void sendDeviceChangedCallback(); - - bool deviceIsOpen; - jack_client_t* client; + bool deviceIsOpen = false; + jack_client_t* client = nullptr; String lastError; - AudioIODeviceCallback* callback; + AudioIODeviceCallback* callback = nullptr; CriticalSection callbackLock; HeapBlock<float*> inChans, outChans; - int totalNumberOfInputChannels; - int totalNumberOfOutputChannels; - Array<void*> inputPorts, outputPorts; + int totalNumberOfInputChannels = 0; + int totalNumberOfOutputChannels = 0; + Array<jack_port_t*> inputPorts, outputPorts; BigInteger activeInputChannels, activeOutputChannels; - int xruns; -}; + std::atomic<int> xruns { 0 }; + std::function<void()> notifyChannelsChanged; + MainThreadDispatcher mainThreadDispatcher { *this }; +}; //============================================================================== +class JackAudioIODeviceType; + class JackAudioIODeviceType : public AudioIODeviceType { public: JackAudioIODeviceType() - : AudioIODeviceType ("JACK"), - hasScanned (false) - { - activeDeviceTypes.add (this); - } - - ~JackAudioIODeviceType() - { - activeDeviceTypes.removeFirstMatchingValue (this); - } + : AudioIODeviceType ("JACK") + {} void scanForDevices() { hasScanned = true; inputNames.clear(); - inputIds.clear(); outputNames.clear(); - outputIds.clear(); if (juce_libjackHandle == nullptr) juce_libjackHandle = dlopen ("libjack.so.0", RTLD_LAZY); if (juce_libjackHandle == nullptr) juce_libjackHandle = dlopen ("libjack.so", RTLD_LAZY); if (juce_libjackHandle == nullptr) return; - jack_status_t status; + jack_status_t status = {}; // open a dummy client - if (jack_client_t* const client = juce::jack_client_open ("JuceJackDummy", JackNoStartServer, &status)) + if (auto* const client = juce::jack_client_open ("JuceJackDummy", JackNoStartServer, &status)) { // scan for output devices for (JackPortIterator i (client, false); i.next();) - { - if (i.clientName != (JUCE_JACK_CLIENT_NAME) && ! inputNames.contains (i.clientName)) - { - inputNames.add (i.clientName); - inputIds.add (i.ports [i.index]); - } - } + if (i.getClientName() != (JUCE_JACK_CLIENT_NAME) && ! inputNames.contains (i.getClientName())) + inputNames.add (i.getClientName()); // scan for input devices for (JackPortIterator i (client, true); i.next();) - { - if (i.clientName != (JUCE_JACK_CLIENT_NAME) && ! outputNames.contains (i.clientName)) - { - outputNames.add (i.clientName); - outputIds.add (i.ports [i.index]); - } - } + if (i.getClientName() != (JUCE_JACK_CLIENT_NAME) && ! outputNames.contains (i.getClientName())) + outputNames.add (i.getClientName()); juce::jack_client_close (client); } @@ -580,8 +639,8 @@ public: jassert (hasScanned); // need to call scanForDevices() before doing this if (JackAudioIODevice* d = dynamic_cast<JackAudioIODevice*> (device)) - return asInput ? inputIds.indexOf (d->inputId) - : outputIds.indexOf (d->outputId); + return asInput ? inputNames.indexOf (d->inputName) + : outputNames.indexOf (d->outputName); return -1; } @@ -595,34 +654,17 @@ public: const int outputIndex = outputNames.indexOf (outputDeviceName); if (inputIndex >= 0 || outputIndex >= 0) - return new JackAudioIODevice (outputIndex >= 0 ? outputDeviceName - : inputDeviceName, - inputIds [inputIndex], - outputIds [outputIndex]); + return new JackAudioIODevice (inputDeviceName, outputDeviceName, + [this] { callDeviceChangeListeners(); }); return nullptr; } - void portConnectionChange() { callDeviceChangeListeners(); } - private: - StringArray inputNames, outputNames, inputIds, outputIds; - bool hasScanned; + StringArray inputNames, outputNames; + bool hasScanned = false; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (JackAudioIODeviceType) }; -void JackAudioIODevice::sendDeviceChangedCallback() -{ - for (int i = activeDeviceTypes.size(); --i >= 0;) - if (JackAudioIODeviceType* d = activeDeviceTypes[i]) - d->portConnectionChange(); -} - -//============================================================================== -AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_JACK() -{ - return new JackAudioIODeviceType(); -} - } // namespace juce diff --git a/modules/juce_audio_devices/native/juce_linux_Midi.cpp b/modules/juce_audio_devices/native/juce_linux_Midi.cpp index 8c70ed80..6fa0fbeb 100644 --- a/modules/juce_audio_devices/native/juce_linux_Midi.cpp +++ b/modules/juce_audio_devices/native/juce_linux_Midi.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -25,10 +25,6 @@ namespace juce #if JUCE_ALSA -//============================================================================== -namespace -{ - //============================================================================== class AlsaClient : public ReferenceCountedObject { @@ -453,9 +449,23 @@ static AlsaClient::Port* iterateMidiDevices (bool forInput, return port; } -} // namespace +struct AlsaPortPtr +{ + explicit AlsaPortPtr (AlsaClient::Port* p) + : ptr (p) {} + + ~AlsaPortPtr() noexcept { AlsaClient::getInstance()->deletePort (ptr); } + + AlsaClient::Port* ptr = nullptr; +}; //============================================================================== +class MidiInput::Pimpl : public AlsaPortPtr +{ +public: + using AlsaPortPtr::AlsaPortPtr; +}; + Array<MidiDeviceInfo> MidiInput::getAvailableDevices() { Array<MidiDeviceInfo> devices; @@ -485,7 +495,7 @@ std::unique_ptr<MidiInput> MidiInput::openDevice (const String& deviceIdentifier std::unique_ptr<MidiInput> midiInput (new MidiInput (port->portName, deviceIdentifier)); port->setupInput (midiInput.get(), callback); - midiInput->internal = port; + midiInput->internal = std::make_unique<Pimpl> (port); return midiInput; } @@ -501,7 +511,7 @@ std::unique_ptr<MidiInput> MidiInput::createNewDevice (const String& deviceName, std::unique_ptr<MidiInput> midiInput (new MidiInput (deviceName, getFormattedPortIdentifier (client->getId(), port->portId))); port->setupInput (midiInput.get(), callback); - midiInput->internal = port; + midiInput->internal = std::make_unique<Pimpl> (port); return midiInput; } @@ -536,20 +546,25 @@ MidiInput::MidiInput (const String& deviceName, const String& deviceIdentifier) MidiInput::~MidiInput() { stop(); - AlsaClient::getInstance()->deletePort (static_cast<AlsaClient::Port*> (internal)); } void MidiInput::start() { - static_cast<AlsaClient::Port*> (internal)->enableCallback (true); + internal->ptr->enableCallback (true); } void MidiInput::stop() { - static_cast<AlsaClient::Port*> (internal)->enableCallback (false); + internal->ptr->enableCallback (false); } //============================================================================== +class MidiOutput::Pimpl : public AlsaPortPtr +{ +public: + using AlsaPortPtr::AlsaPortPtr; +}; + Array<MidiDeviceInfo> MidiOutput::getAvailableDevices() { Array<MidiDeviceInfo> devices; @@ -577,7 +592,7 @@ std::unique_ptr<MidiOutput> MidiOutput::openDevice (const String& deviceIdentifi std::unique_ptr<MidiOutput> midiOutput (new MidiOutput (port->portName, deviceIdentifier)); port->setupOutput(); - midiOutput->internal = port; + midiOutput->internal = std::make_unique<Pimpl> (port); return midiOutput; } @@ -593,7 +608,7 @@ std::unique_ptr<MidiOutput> MidiOutput::createNewDevice (const String& deviceNam std::unique_ptr<MidiOutput> midiOutput (new MidiOutput (deviceName, getFormattedPortIdentifier (client->getId(), port->portId))); port->setupOutput(); - midiOutput->internal = port; + midiOutput->internal = std::make_unique<Pimpl> (port); return midiOutput; } @@ -623,17 +638,18 @@ std::unique_ptr<MidiOutput> MidiOutput::openDevice (int index) MidiOutput::~MidiOutput() { stopBackgroundThread(); - AlsaClient::getInstance()->deletePort (static_cast<AlsaClient::Port*> (internal)); } void MidiOutput::sendMessageNow (const MidiMessage& message) { - static_cast<AlsaClient::Port*> (internal)->sendMessageNow (message); + internal->ptr->sendMessageNow (message); } //============================================================================== #else +class MidiInput::Pimpl {}; + // (These are just stub functions if ALSA is unavailable...) MidiInput::MidiInput (const String& deviceName, const String& deviceID) : deviceInfo (deviceName, deviceID) @@ -651,6 +667,8 @@ StringArray MidiInput::getDevices() int MidiInput::getDefaultDeviceIndex() { return 0;} std::unique_ptr<MidiInput> MidiInput::openDevice (int, MidiInputCallback*) { return {}; } +class MidiOutput::Pimpl {}; + MidiOutput::~MidiOutput() {} void MidiOutput::sendMessageNow (const MidiMessage&) {} Array<MidiDeviceInfo> MidiOutput::getAvailableDevices() { return {}; } diff --git a/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp b/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp index 86b06404..feac8c3b 100644 --- a/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp +++ b/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -29,10 +29,7 @@ namespace juce #define JUCE_COREAUDIOLOG(a) #endif -#ifdef __clang__ - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wnonnull" // avoid some spurious 10.11 SDK warnings -#endif +JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wnonnull") //============================================================================== struct SystemVol @@ -124,9 +121,7 @@ private: } }; -#ifdef __clang__ - #pragma clang diagnostic pop -#endif +JUCE_END_IGNORE_WARNINGS_GCC_LIKE #define JUCE_SYSTEMAUDIOVOL_IMPLEMENTED 1 float JUCE_CALLTYPE SystemAudioVolume::getGain() { return SystemVol (kAudioHardwareServiceDeviceProperty_VirtualMasterVolume).getGain(); } @@ -1668,11 +1663,16 @@ private: void readInput (AudioBuffer<float>& buffer, const int numSamples, const int blockSizeMs) { for (auto* d : devices) - d->done = (d->numInputChans == 0); + d->done = (d->numInputChans == 0 || d->isWaitingForInput); - for (int tries = 5;;) + float totalWaitTimeMs = blockSizeMs * 5.0f; + constexpr int numReadAttempts = 6; + auto sumPower2s = [] (int maxPower) { return (1 << (maxPower + 1)) - 1; }; + float waitTime = totalWaitTimeMs / (float) sumPower2s (numReadAttempts - 2); + + for (int numReadAttemptsRemaining = numReadAttempts;;) { - bool anyRemaining = false; + bool anySamplesRemaining = false; for (auto* d : devices) { @@ -1684,17 +1684,20 @@ private: d->done = true; } else - anyRemaining = true; + { + anySamplesRemaining = true; + } } } - if (! anyRemaining) + if (! anySamplesRemaining) return; - if (--tries == 0) + if (--numReadAttemptsRemaining == 0) break; - wait (blockSizeMs); + wait (jmax (1, roundToInt (waitTime))); + waitTime *= 2.0f; } for (auto* d : devices) @@ -1722,7 +1725,9 @@ private: d->done = true; } else + { anyRemaining = true; + } } } @@ -1813,6 +1818,8 @@ private: numInputChans = useInputs ? device->getActiveInputChannels().countNumberOfSetBits() : 0; numOutputChans = useOutputs ? device->getActiveOutputChannels().countNumberOfSetBits() : 0; + isWaitingForInput = numInputChans > 0; + inputIndex = channelIndex; outputIndex = channelIndex + numInputChans; @@ -1897,6 +1904,8 @@ private: { if (numInputChannels > 0) { + isWaitingForInput = false; + int start1, size1, start2, size2; inputFifo.prepareToWrite (numSamples, start1, size1, start2, size2); @@ -1978,6 +1987,7 @@ private: std::unique_ptr<CoreAudioIODevice> device; int inputIndex = 0, numInputChans = 0, outputIndex = 0, numOutputChans = 0; bool useInputs = false, useOutputs = false; + std::atomic<bool> isWaitingForInput { false }; AbstractFifo inputFifo { 32 }, outputFifo { 32 }; bool done = false; @@ -2239,12 +2249,6 @@ private: }; -//============================================================================== -AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_CoreAudio() -{ - return new CoreAudioClasses::CoreAudioIODeviceType(); -} - #undef JUCE_COREAUDIOLOG } // namespace juce diff --git a/modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp b/modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp index 8b1e352d..704a0574 100644 --- a/modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp +++ b/modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -220,22 +220,9 @@ namespace CoreMidiHelpers if (! hasEnabledNetworkSession) { - 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; - } + MIDINetworkSession* session = [MIDINetworkSession defaultSession]; + session.enabled = YES; + session.connectionPolicy = MIDINetworkConnectionPolicy_Anyone; hasEnabledNetworkSession = true; } @@ -406,6 +393,12 @@ namespace CoreMidiHelpers } } +class MidiInput::Pimpl : public CoreMidiHelpers::MidiPortAndCallback +{ +public: + using MidiPortAndCallback::MidiPortAndCallback; +}; + //============================================================================== Array<MidiDeviceInfo> MidiInput::getAvailableDevices() { @@ -437,7 +430,7 @@ std::unique_ptr<MidiInput> MidiInput::openDevice (const String& deviceIdentifier if (CHECK_ERROR (MIDIObjectGetStringProperty (endpoint, kMIDIPropertyName, &cfName.cfString))) { MIDIPortRef port; - auto mpc = std::make_unique<MidiPortAndCallback> (*callback); + auto mpc = std::make_unique<Pimpl> (*callback); if (CHECK_ERROR (MIDIInputPortCreate (client, cfName.cfString, midiInputProc, mpc.get(), &port))) { @@ -448,10 +441,11 @@ std::unique_ptr<MidiInput> MidiInput::openDevice (const String& deviceIdentifier std::unique_ptr<MidiInput> midiInput (new MidiInput (endpointInfo.name, endpointInfo.identifier)); mpc->input = midiInput.get(); - midiInput->internal = mpc.get(); + auto* ptr = mpc.get(); + midiInput->internal = std::move (mpc); const ScopedLock sl (callbackLock); - activeCallbacks.add (mpc.release()); + activeCallbacks.add (ptr); return midiInput; } @@ -475,7 +469,7 @@ std::unique_ptr<MidiInput> MidiInput::createNewDevice (const String& deviceName, if (auto client = getGlobalMidiClient()) { - auto mpc = std::make_unique<MidiPortAndCallback> (*callback); + auto mpc = std::make_unique<Pimpl> (*callback); mpc->active = false; MIDIEndpointRef endpoint; @@ -504,10 +498,11 @@ std::unique_ptr<MidiInput> MidiInput::createNewDevice (const String& deviceName, std::unique_ptr<MidiInput> midiInput (new MidiInput (deviceName, String (deviceIdentifier))); mpc->input = midiInput.get(); - midiInput->internal = mpc.get(); + auto* ptr = mpc.get(); + midiInput->internal = std::move (mpc); const ScopedLock sl (callbackLock); - activeCallbacks.add (mpc.release()); + activeCallbacks.add (ptr); return midiInput; } @@ -542,24 +537,27 @@ MidiInput::MidiInput (const String& deviceName, const String& deviceIdentifier) { } -MidiInput::~MidiInput() -{ - delete static_cast<CoreMidiHelpers::MidiPortAndCallback*> (internal); -} +MidiInput::~MidiInput() = default; void MidiInput::start() { const ScopedLock sl (CoreMidiHelpers::callbackLock); - static_cast<CoreMidiHelpers::MidiPortAndCallback*> (internal)->active = true; + internal->active = true; } void MidiInput::stop() { const ScopedLock sl (CoreMidiHelpers::callbackLock); - static_cast<CoreMidiHelpers::MidiPortAndCallback*> (internal)->active = false; + internal->active = false; } //============================================================================== +class MidiOutput::Pimpl : public CoreMidiHelpers::MidiPortAndEndpoint +{ +public: + using MidiPortAndEndpoint::MidiPortAndEndpoint; +}; + Array<MidiDeviceInfo> MidiOutput::getAvailableDevices() { return CoreMidiHelpers::findDevices (false); @@ -594,7 +592,7 @@ std::unique_ptr<MidiOutput> MidiOutput::openDevice (const String& deviceIdentifi if (CHECK_ERROR (MIDIOutputPortCreate (client, cfName.cfString, &port))) { std::unique_ptr<MidiOutput> midiOutput (new MidiOutput (endpointInfo.name, endpointInfo.identifier)); - midiOutput->internal = new MidiPortAndEndpoint (port, endpoint); + midiOutput->internal = std::make_unique<Pimpl> (port, endpoint); return midiOutput; } @@ -635,7 +633,7 @@ std::unique_ptr<MidiOutput> MidiOutput::createNewDevice (const String& deviceNam if (CHECK_ERROR (MIDIObjectSetIntegerProperty (endpoint, kMIDIPropertyUniqueID, (SInt32) deviceIdentifier))) { std::unique_ptr<MidiOutput> midiOutput (new MidiOutput (deviceName, String (deviceIdentifier))); - midiOutput->internal = new MidiPortAndEndpoint (0, endpoint); + midiOutput->internal = std::make_unique<Pimpl> ((UInt32) 0, endpoint); return midiOutput; } @@ -668,8 +666,6 @@ std::unique_ptr<MidiOutput> MidiOutput::openDevice (int index) MidiOutput::~MidiOutput() { stopBackgroundThread(); - - delete static_cast<CoreMidiHelpers::MidiPortAndEndpoint*> (internal); } void MidiOutput::sendMessageNow (const MidiMessage& message) @@ -728,7 +724,7 @@ void MidiOutput::sendMessageNow (const MidiMessage& message) return; } - static_cast<CoreMidiHelpers::MidiPortAndEndpoint*> (internal)->send (packetToSend); + internal->send (packetToSend); } #undef CHECK_ERROR diff --git a/modules/juce_audio_devices/native/juce_win32_ASIO.cpp b/modules/juce_audio_devices/native/juce_win32_ASIO.cpp index 34f438f2..954a3c5a 100644 --- a/modules/juce_audio_devices/native/juce_win32_ASIO.cpp +++ b/modules/juce_audio_devices/native/juce_win32_ASIO.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -504,7 +504,7 @@ public: { inBuffers[n] = ioBufferSpace + (currentBlockSizeSamples * n); - ASIOChannelInfo channelInfo = { 0 }; + ASIOChannelInfo channelInfo = {}; channelInfo.channel = i; channelInfo.isInput = 1; asioObject->getChannelInfo (&channelInfo); @@ -526,7 +526,7 @@ public: { outBuffers[n] = ioBufferSpace + (currentBlockSizeSamples * (numActiveInputChans + n)); - ASIOChannelInfo channelInfo = { 0 }; + ASIOChannelInfo channelInfo = {}; channelInfo.channel = i; channelInfo.isInput = 0; asioObject->getChannelInfo (&channelInfo); @@ -673,10 +673,10 @@ public: lastCallback->audioDeviceStopped(); } - String getLastError() { return error; } - bool hasControlPanel() const { return true; } + String getLastError() override { return error; } + bool hasControlPanel() const override { return true; } - bool showControlPanel() + bool showControlPanel() override { JUCE_ASIO_LOG ("showing control panel"); @@ -767,7 +767,7 @@ private: bool deviceIsOpen = false, isStarted = false, buffersCreated = false; std::atomic<bool> calledback { false }; - bool littleEndian = false, postOutput = true, needToReset = false; + bool postOutput = true, needToReset = false; bool insideControlPanelModalLoop = false; bool shouldUsePreferredSize = false; int xruns = 0; @@ -785,7 +785,7 @@ private: String getChannelName (int index, bool isInput) const { - ASIOChannelInfo channelInfo = { 0 }; + ASIOChannelInfo channelInfo = {}; channelInfo.channel = index; channelInfo.isInput = isInput ? 1 : 0; asioObject->getChannelInfo (&channelInfo); @@ -1065,7 +1065,7 @@ private: for (int i = 0; i < totalNumOutputChans; ++i) { - ASIOChannelInfo channelInfo = { 0 }; + ASIOChannelInfo channelInfo = {}; channelInfo.channel = i; channelInfo.isInput = 0; asioObject->getChannelInfo (&channelInfo); @@ -1640,9 +1640,4 @@ void sendASIODeviceChangeToListeners (ASIOAudioIODeviceType* type) type->sendDeviceChangeToListeners(); } -AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_ASIO() -{ - return new ASIOAudioIODeviceType(); -} - } // namespace juce diff --git a/modules/juce_audio_devices/native/juce_win32_DirectSound.cpp b/modules/juce_audio_devices/native/juce_win32_DirectSound.cpp index fb6e97f0..742b0209 100644 --- a/modules/juce_audio_devices/native/juce_win32_DirectSound.cpp +++ b/modules/juce_audio_devices/native/juce_win32_DirectSound.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -291,7 +291,7 @@ public: { IDirectSoundBuffer* pPrimaryBuffer; - DSBUFFERDESC primaryDesc = { 0 }; + DSBUFFERDESC primaryDesc = {}; primaryDesc.dwSize = sizeof (DSBUFFERDESC); primaryDesc.dwFlags = 1 /* DSBCAPS_PRIMARYBUFFER */; primaryDesc.dwBufferBytes = 0; @@ -317,7 +317,7 @@ public: if (SUCCEEDED (hr)) { - DSBUFFERDESC secondaryDesc = { 0 }; + DSBUFFERDESC secondaryDesc = {}; secondaryDesc.dwSize = sizeof (DSBUFFERDESC); secondaryDesc.dwFlags = 0x8000 /* DSBCAPS_GLOBALFOCUS */ | 0x10000 /* DSBCAPS_GETCURRENTPOSITION2 */; @@ -518,7 +518,7 @@ private: bool firstPlayTime; int64 lastPlayTime, ticksPerBuffer; - static inline int convertInputValues (const float l, const float r) noexcept + static int convertInputValues (const float l, const float r) noexcept { return jlimit (-32768, 32767, roundToInt (32767.0f * r)) << 16 | (0xffff & jlimit (-32768, 32767, roundToInt (32767.0f * l))); @@ -598,7 +598,7 @@ public: wfFormat.nAvgBytesPerSec = wfFormat.nSamplesPerSec * wfFormat.nBlockAlign; wfFormat.cbSize = 0; - DSCBUFFERDESC captureDesc = { 0 }; + DSCBUFFERDESC captureDesc = {}; captureDesc.dwSize = sizeof (DSCBUFFERDESC); captureDesc.dwFlags = 0; captureDesc.dwBufferBytes = (DWORD) totalBytesPerBuffer; @@ -1282,10 +1282,4 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DSoundAudioIODeviceType) }; -//============================================================================== -AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_DirectSound() -{ - return new DSoundAudioIODeviceType(); -} - } // namespace juce diff --git a/modules/juce_audio_devices/native/juce_win32_Midi.cpp b/modules/juce_audio_devices/native/juce_win32_Midi.cpp index 5a39111a..bc03b9e2 100644 --- a/modules/juce_audio_devices/native/juce_win32_Midi.cpp +++ b/modules/juce_audio_devices/native/juce_win32_Midi.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -29,37 +29,39 @@ namespace juce { -struct MidiServiceType +class MidiInput::Pimpl { - struct InputWrapper - { - virtual ~InputWrapper() {} +public: + virtual ~Pimpl() noexcept = default; - virtual String getDeviceIdentifier() = 0; - virtual String getDeviceName() = 0; + virtual String getDeviceIdentifier() = 0; + virtual String getDeviceName() = 0; - virtual void start() = 0; - virtual void stop() = 0; - }; + virtual void start() = 0; + virtual void stop() = 0; +}; - struct OutputWrapper - { - virtual ~OutputWrapper() {} +class MidiOutput::Pimpl +{ +public: + virtual ~Pimpl() noexcept = default; - virtual String getDeviceIdentifier() = 0; - virtual String getDeviceName() = 0; + virtual String getDeviceIdentifier() = 0; + virtual String getDeviceName() = 0; - virtual void sendMessageNow (const MidiMessage&) = 0; - }; + virtual void sendMessageNow (const MidiMessage&) = 0; +}; - MidiServiceType() {} - virtual ~MidiServiceType() {} +struct MidiServiceType +{ + MidiServiceType() = default; + virtual ~MidiServiceType() noexcept = default; virtual Array<MidiDeviceInfo> getAvailableDevices (bool) = 0; virtual MidiDeviceInfo getDefaultDevice (bool) = 0; - virtual InputWrapper* createInputWrapper (MidiInput&, const String&, MidiInputCallback&) = 0; - virtual OutputWrapper* createOutputWrapper (const String&) = 0; + virtual MidiInput::Pimpl* createInputWrapper (MidiInput&, const String&, MidiInputCallback&) = 0; + virtual MidiOutput::Pimpl* createOutputWrapper (const String&) = 0; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiServiceType) }; @@ -82,12 +84,12 @@ struct Win32MidiService : public MidiServiceType, : Win32OutputWrapper::getDefaultDevice(); } - InputWrapper* createInputWrapper (MidiInput& input, const String& deviceIdentifier, MidiInputCallback& callback) override + MidiInput::Pimpl* createInputWrapper (MidiInput& input, const String& deviceIdentifier, MidiInputCallback& callback) override { return new Win32InputWrapper (*this, input, deviceIdentifier, callback); } - OutputWrapper* createOutputWrapper (const String& deviceIdentifier) override + MidiOutput::Pimpl* createOutputWrapper (const String& deviceIdentifier) override { return new Win32OutputWrapper (*this, deviceIdentifier); } @@ -384,7 +386,7 @@ private: } }; - struct Win32InputWrapper : public InputWrapper, + struct Win32InputWrapper : public MidiInput::Pimpl, public Win32MidiDeviceQuery<Win32InputWrapper> { Win32InputWrapper (Win32MidiService& parentService, MidiInput& midiInput, const String& deviceIdentifier, MidiInputCallback& c) @@ -450,7 +452,7 @@ private: for (UINT i = 0; i < midiInGetNumDevs(); ++i) { - MIDIINCAPS mc = { 0 }; + MIDIINCAPS mc = {}; if (midiInGetDevCaps (i, &mc, sizeof (mc)) == MMSYSERR_NOERROR) devices.add (mc); @@ -508,7 +510,7 @@ private: }; //============================================================================== - struct Win32OutputWrapper : public OutputWrapper, + struct Win32OutputWrapper : public MidiOutput::Pimpl, public Win32MidiDeviceQuery<Win32OutputWrapper> { Win32OutputWrapper (Win32MidiService& p, const String& deviceIdentifier) @@ -574,7 +576,7 @@ private: { if (message.getRawDataSize() > 3 || message.isSysEx()) { - MIDIHDR h = { 0 }; + MIDIHDR h = {}; h.lpData = (char*) message.getRawData(); h.dwBytesRecorded = h.dwBufferLength = (DWORD) message.getRawDataSize(); @@ -625,7 +627,7 @@ private: for (UINT i = 0; i < midiOutGetNumDevs(); ++i) { - MIDIOUTCAPS mc = { 0 }; + MIDIOUTCAPS mc = {}; if (midiOutGetDevCaps (i, &mc, sizeof (mc)) == MMSYSERR_NOERROR) devices.add (mc); @@ -763,12 +765,12 @@ public: : outputDeviceWatcher->getDefaultDevice(); } - InputWrapper* createInputWrapper (MidiInput& input, const String& deviceIdentifier, MidiInputCallback& callback) override + MidiInput::Pimpl* createInputWrapper (MidiInput& input, const String& deviceIdentifier, MidiInputCallback& callback) override { return new WinRTInputWrapper (*this, input, deviceIdentifier, callback); } - OutputWrapper* createOutputWrapper (const String& deviceIdentifier) override + MidiOutput::Pimpl* createOutputWrapper (const String& deviceIdentifier) override { return new WinRTOutputWrapper (*this, deviceIdentifier); } @@ -990,19 +992,19 @@ private: watcher->add_Added ( Callback<ITypedEventHandler<DeviceWatcher*, DeviceInformation*>> ( - [handlerPtr](IDeviceWatcher*, IDeviceInformation* info) { return handlerPtr->addDevice (info); } + [handlerPtr] (IDeviceWatcher*, IDeviceInformation* info) { return handlerPtr->addDevice (info); } ).Get(), &deviceAddedToken); watcher->add_Removed ( Callback<ITypedEventHandler<DeviceWatcher*, DeviceInformationUpdate*>> ( - [handlerPtr](IDeviceWatcher*, IDeviceInformationUpdate* infoUpdate) { return handlerPtr->removeDevice (infoUpdate); } + [handlerPtr] (IDeviceWatcher*, IDeviceInformationUpdate* infoUpdate) { return handlerPtr->removeDevice (infoUpdate); } ).Get(), &deviceRemovedToken); watcher->add_Updated ( Callback<ITypedEventHandler<DeviceWatcher*, DeviceInformationUpdate*>> ( - [handlerPtr](IDeviceWatcher*, IDeviceInformationUpdate* infoUpdate) { return handlerPtr->updateDevice (infoUpdate); } + [handlerPtr] (IDeviceWatcher*, IDeviceInformationUpdate* infoUpdate) { return handlerPtr->updateDevice (infoUpdate); } ).Get(), &deviceUpdatedToken); @@ -1118,7 +1120,7 @@ private: if (devices.contains (removedDeviceId)) { auto& info = devices.getReference (removedDeviceId); - listeners.call ([&info](Listener& l) { l.bleDeviceDisconnected (info.containerID); }); + listeners.call ([&info] (Listener& l) { l.bleDeviceDisconnected (info.containerID); }); devices.remove (removedDeviceId); JUCE_WINRT_MIDI_LOG ("Removed BLE device: " << removedDeviceId); } @@ -1165,7 +1167,7 @@ private: if (info.isConnected && ! isConnected) { JUCE_WINRT_MIDI_LOG ("BLE device connection status change: " << updatedDeviceId << " " << info.containerID << " " << (isConnected ? "connected" : "disconnected")); - listeners.call ([&info](Listener& l) { l.bleDeviceDisconnected (info.containerID); }); + listeners.call ([&info] (Listener& l) { l.bleDeviceDisconnected (info.containerID); }); } info.isConnected = isConnected; @@ -1554,7 +1556,7 @@ private: }; //============================================================================== - struct WinRTInputWrapper final : public InputWrapper, + struct WinRTInputWrapper final : public MidiInput::Pimpl, private WinRTIOWrapper<IMidiInPortStatics, IMidiInPort> { @@ -1580,7 +1582,7 @@ private: auto hr = midiPort->add_MessageReceived ( Callback<ITypedEventHandler<MidiInPort*, MidiMessageReceivedEventArgs*>> ( - [this](IMidiInPort*, IMidiMessageReceivedEventArgs* args) { return midiInMessageReceived (args); } + [this] (IMidiInPort*, IMidiMessageReceivedEventArgs* args) { return midiInMessageReceived (args); } ).Get(), &midiInMessageToken); @@ -1708,7 +1710,7 @@ private: }; //============================================================================== - struct WinRTOutputWrapper final : public OutputWrapper, + struct WinRTOutputWrapper final : public MidiOutput::Pimpl, private WinRTIOWrapper <IMidiOutPortStatics, IMidiOutPort> { WinRTOutputWrapper (WinRTMidiService& service, const String& deviceIdentifier) @@ -1865,7 +1867,7 @@ std::unique_ptr<MidiInput> MidiInput::openDevice (const String& deviceIdentifier return {}; std::unique_ptr<MidiInput> in (new MidiInput ({}, deviceIdentifier)); - std::unique_ptr<MidiServiceType::InputWrapper> wrapper; + std::unique_ptr<Pimpl> wrapper; try { @@ -1877,7 +1879,7 @@ std::unique_ptr<MidiInput> MidiInput::openDevice (const String& deviceIdentifier } in->setName (wrapper->getDeviceName()); - in->internal = wrapper.release(); + in->internal = std::move (wrapper); return in; } @@ -1907,13 +1909,10 @@ MidiInput::MidiInput (const String& deviceName, const String& deviceIdentifier) { } -MidiInput::~MidiInput() -{ - delete static_cast<MidiServiceType::InputWrapper*> (internal); -} +MidiInput::~MidiInput() = default; -void MidiInput::start() { static_cast<MidiServiceType::InputWrapper*> (internal)->start(); } -void MidiInput::stop() { static_cast<MidiServiceType::InputWrapper*> (internal)->stop(); } +void MidiInput::start() { internal->start(); } +void MidiInput::stop() { internal->stop(); } //============================================================================== Array<MidiDeviceInfo> MidiOutput::getAvailableDevices() @@ -1931,7 +1930,7 @@ std::unique_ptr<MidiOutput> MidiOutput::openDevice (const String& deviceIdentifi if (deviceIdentifier.isEmpty()) return {}; - std::unique_ptr<MidiServiceType::OutputWrapper> wrapper; + std::unique_ptr<Pimpl> wrapper; try { @@ -1945,7 +1944,7 @@ std::unique_ptr<MidiOutput> MidiOutput::openDevice (const String& deviceIdentifi std::unique_ptr<MidiOutput> out; out.reset (new MidiOutput (wrapper->getDeviceName(), deviceIdentifier)); - out->internal = wrapper.release(); + out->internal = std::move (wrapper); return out; } @@ -1973,12 +1972,11 @@ std::unique_ptr<MidiOutput> MidiOutput::openDevice (int index) MidiOutput::~MidiOutput() { stopBackgroundThread(); - delete static_cast<MidiServiceType::OutputWrapper*> (internal); } void MidiOutput::sendMessageNow (const MidiMessage& message) { - static_cast<MidiServiceType::OutputWrapper*> (internal)->sendMessageNow (message); + internal->sendMessageNow (message); } } // namespace juce diff --git a/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp b/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp old mode 100644 new mode 100755 index d7de74c4..38daf1cd --- a/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp +++ b/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -208,6 +208,29 @@ enum AUDCLNT_SHAREMODE AUDCLNT_SHAREMODE_EXCLUSIVE }; +enum AUDIO_STREAM_CATEGORY +{ + AudioCategory_Other = 0, + AudioCategory_ForegroundOnlyMedia, + AudioCategory_BackgroundCapableMedia, + AudioCategory_Communications, + AudioCategory_Alerts, + AudioCategory_SoundEffects, + AudioCategory_GameEffects, + AudioCategory_GameMedia, + AudioCategory_GameChat, + AudioCategory_Speech, + AudioCategory_Movie, + AudioCategory_Media +}; + +struct AudioClientProperties +{ + UINT32 cbSize; + BOOL bIsOffload; + AUDIO_STREAM_CATEGORY eCategory; +}; + JUCE_IUNKNOWNCLASS (IAudioClient, "1CB9AD4C-DBFA-4c32-B178-C2F568A703B2") { JUCE_COMCALL Initialize (AUDCLNT_SHAREMODE, DWORD, REFERENCE_TIME, REFERENCE_TIME, const WAVEFORMATEX*, LPCGUID) = 0; @@ -224,6 +247,20 @@ JUCE_IUNKNOWNCLASS (IAudioClient, "1CB9AD4C-DBFA-4c32-B178-C2F568A703B2") JUCE_COMCALL GetService (REFIID, void**) = 0; }; +JUCE_COMCLASS (IAudioClient2, "726778CD-F60A-4eda-82DE-E47610CD78AA") : public IAudioClient +{ + JUCE_COMCALL IsOffloadCapable (AUDIO_STREAM_CATEGORY, BOOL*) = 0; + JUCE_COMCALL SetClientProperties (const AudioClientProperties*) = 0; + JUCE_COMCALL GetBufferSizeLimits (const WAVEFORMATEX*, BOOL, REFERENCE_TIME*, REFERENCE_TIME*) = 0; +}; + +JUCE_COMCLASS (IAudioClient3, "1CB9AD4C-DBFA-4c32-B178-C2F568A703B2") : public IAudioClient2 +{ + JUCE_COMCALL GetSharedModeEnginePeriod (const WAVEFORMATEX*, UINT32*, UINT32*, UINT32*, UINT32*) = 0; + JUCE_COMCALL GetCurrentSharedModeEnginePeriod (WAVEFORMATEX**, UINT32*) = 0; + JUCE_COMCALL InitializeSharedAudioStream (DWORD, UINT32, const WAVEFORMATEX*, LPCGUID) = 0; +}; + JUCE_IUNKNOWNCLASS (IAudioCaptureClient, "C8ADBD64-E71E-48a0-A4DE-185C395CD317") { JUCE_COMCALL GetBuffer (BYTE**, UINT32*, DWORD*, UINT64*, UINT64*) = 0; @@ -322,87 +359,76 @@ String getDeviceID (IMMDevice* device) return s; } -EDataFlow getDataFlow (const ComSmartPtr<IMMDevice>& device) +static EDataFlow getDataFlow (const ComSmartPtr<IMMDevice>& device) { EDataFlow flow = eRender; - ComSmartPtr<IMMEndpoint> endPoint; - if (check (device.QueryInterface (endPoint))) - (void) check (endPoint->GetDataFlow (&flow)); + if (auto endpoint = device.getInterface<IMMEndpoint>()) + (void) check (endpoint->GetDataFlow (&flow)); return flow; } -int refTimeToSamples (const REFERENCE_TIME& t, double sampleRate) noexcept +static int refTimeToSamples (const REFERENCE_TIME& t, double sampleRate) noexcept { return roundToInt (sampleRate * ((double) t) * 0.0000001); } -REFERENCE_TIME samplesToRefTime (int numSamples, double sampleRate) noexcept +static REFERENCE_TIME samplesToRefTime (int numSamples, double sampleRate) noexcept { return (REFERENCE_TIME) ((numSamples * 10000.0 * 1000.0 / sampleRate) + 0.5); } -void copyWavFormat (WAVEFORMATEXTENSIBLE& dest, const WAVEFORMATEX* src) noexcept +static void copyWavFormat (WAVEFORMATEXTENSIBLE& dest, const WAVEFORMATEX* src) noexcept { memcpy (&dest, src, src->wFormatTag == WAVE_FORMAT_EXTENSIBLE ? sizeof (WAVEFORMATEXTENSIBLE) : sizeof (WAVEFORMATEX)); } +static bool isExclusiveMode (WASAPIDeviceMode deviceMode) noexcept +{ + return deviceMode == WASAPIDeviceMode::exclusive; +} + +static bool isLowLatencyMode (WASAPIDeviceMode deviceMode) noexcept +{ + return deviceMode == WASAPIDeviceMode::sharedLowLatency; +} + +static bool supportsSampleRateConversion (WASAPIDeviceMode deviceMode) noexcept +{ + return deviceMode == WASAPIDeviceMode::shared; +} + //============================================================================== class WASAPIDeviceBase { public: - WASAPIDeviceBase (const ComSmartPtr<IMMDevice>& d, bool exclusiveMode, std::function<void()>&& cb) - : device (d), useExclusiveMode (exclusiveMode), reopenCallback (cb) + WASAPIDeviceBase (const ComSmartPtr<IMMDevice>& d, WASAPIDeviceMode mode) + : device (d), + deviceMode (mode) { clientEvent = CreateEvent (nullptr, false, false, nullptr); ComSmartPtr<IAudioClient> tempClient (createClient()); + if (tempClient == nullptr) return; - REFERENCE_TIME defaultPeriod, minPeriod; - if (! check (tempClient->GetDevicePeriod (&defaultPeriod, &minPeriod))) - return; + WAVEFORMATEXTENSIBLE format; - WAVEFORMATEX* mixFormat = nullptr; - if (! check (tempClient->GetMixFormat (&mixFormat))) + if (! getClientMixFormat (tempClient, format)) return; - WAVEFORMATEXTENSIBLE format; - copyWavFormat (format, mixFormat); - CoTaskMemFree (mixFormat); - actualNumChannels = numChannels = format.Format.nChannels; defaultSampleRate = format.Format.nSamplesPerSec; - minBufferSize = refTimeToSamples (minPeriod, defaultSampleRate); - defaultBufferSize = refTimeToSamples (defaultPeriod, defaultSampleRate); - mixFormatChannelMask = format.dwChannelMask; - rates.addUsingDefaultSort (defaultSampleRate); + mixFormatChannelMask = format.dwChannelMask; - if (useExclusiveMode - && findSupportedFormat (tempClient, defaultSampleRate, format.dwChannelMask, format)) - { - // Got a format that is supported by the device so we can ask what sample rates are supported (in whatever format) - } - - for (auto rate : { 8000, 11025, 16000, 22050, 32000, - 44100, 48000, 88200, 96000, 176400, - 192000, 352800, 384000, 705600, 768000 }) - { - if (rates.contains (rate)) - continue; - - format.Format.nSamplesPerSec = (DWORD) rate; - format.Format.nAvgBytesPerSec = (DWORD) (format.Format.nSamplesPerSec * format.Format.nChannels * format.Format.wBitsPerSample / 8); + if (isExclusiveMode (deviceMode)) + findSupportedFormat (tempClient, defaultSampleRate, mixFormatChannelMask, format); - if (SUCCEEDED (tempClient->IsFormatSupported (useExclusiveMode ? AUDCLNT_SHAREMODE_EXCLUSIVE - : AUDCLNT_SHAREMODE_SHARED, - (WAVEFORMATEX*) &format, 0))) - if (! rates.contains (rate)) - rates.addUsingDefaultSort (rate); - } + querySupportedBufferSizes (format, tempClient); + querySupportedSampleRates (format, tempClient); } virtual ~WASAPIDeviceBase() @@ -429,7 +455,8 @@ public: && tryInitialisingWithBufferSize (bufferSizeSamples)) { sampleRateHasChanged = false; - shouldClose = false; + shouldShutdown = false; + channelMaps.clear(); for (int i = 0; i <= channels.getHighestBit(); ++i) @@ -468,27 +495,39 @@ public: sampleRateHasChanged = true; } - void deviceBecameInactive() + void deviceSessionBecameInactive() + { + isActive = false; + } + + void deviceSessionExpired() + { + shouldShutdown = true; + } + + void deviceSessionBecameActive() { - shouldClose = true; + isActive = true; } //============================================================================== ComSmartPtr<IMMDevice> device; ComSmartPtr<IAudioClient> client; + + WASAPIDeviceMode deviceMode; + double sampleRate = 0, defaultSampleRate = 0; int numChannels = 0, actualNumChannels = 0; int minBufferSize = 0, defaultBufferSize = 0, latencySamples = 0; + int lowLatencyBufferSizeMultiple = 0, lowLatencyMaxBufferSize = 0; DWORD mixFormatChannelMask = 0; - const bool useExclusiveMode; Array<double> rates; HANDLE clientEvent = {}; BigInteger channels; Array<int> channelMaps; UINT32 actualBufferSize = 0; int bytesPerSample = 0, bytesPerFrame = 0; - bool sampleRateHasChanged = false, shouldClose = false; - std::function<void()> reopenCallback; + std::atomic<bool> sampleRateHasChanged { false }, shouldShutdown { false }, isActive { true }; virtual void updateFormat (bool isFloat) = 0; @@ -504,13 +543,20 @@ private: JUCE_COMRESULT OnChannelVolumeChanged (DWORD, float*, DWORD, LPCGUID) { return S_OK; } JUCE_COMRESULT OnGroupingParamChanged (LPCGUID, LPCGUID) { return S_OK; } - JUCE_COMRESULT OnStateChanged(AudioSessionState state) + JUCE_COMRESULT OnStateChanged (AudioSessionState state) { - if (state == AudioSessionStateActive) - owner.reopenCallback(); - - if (state == AudioSessionStateInactive || state == AudioSessionStateExpired) - owner.deviceBecameInactive(); + switch (state) + { + case AudioSessionStateInactive: + owner.deviceSessionBecameInactive(); + break; + case AudioSessionStateExpired: + owner.deviceSessionExpired(); + break; + case AudioSessionStateActive: + owner.deviceSessionBecameActive(); + break; + } return S_OK; } @@ -565,6 +611,84 @@ private: return newClient; } + static bool getClientMixFormat (ComSmartPtr<IAudioClient>& client, WAVEFORMATEXTENSIBLE& format) + { + WAVEFORMATEX* mixFormat = nullptr; + + if (! check (client->GetMixFormat (&mixFormat))) + return false; + + copyWavFormat (format, mixFormat); + CoTaskMemFree (mixFormat); + + return true; + } + + //============================================================================== + void querySupportedBufferSizes (WAVEFORMATEXTENSIBLE format, ComSmartPtr<IAudioClient>& audioClient) + { + if (isLowLatencyMode (deviceMode)) + { + if (auto audioClient3 = audioClient.getInterface<IAudioClient3>()) + { + UINT32 defaultPeriod = 0, fundamentalPeriod = 0, minPeriod = 0, maxPeriod = 0; + + if (check (audioClient3->GetSharedModeEnginePeriod ((WAVEFORMATEX*) &format, + &defaultPeriod, + &fundamentalPeriod, + &minPeriod, + &maxPeriod))) + { + minBufferSize = minPeriod; + defaultBufferSize = defaultPeriod; + lowLatencyMaxBufferSize = maxPeriod; + lowLatencyBufferSizeMultiple = fundamentalPeriod; + } + } + } + else + { + REFERENCE_TIME defaultPeriod, minPeriod; + + if (! check (audioClient->GetDevicePeriod (&defaultPeriod, &minPeriod))) + return; + + minBufferSize = refTimeToSamples (minPeriod, defaultSampleRate); + defaultBufferSize = refTimeToSamples (defaultPeriod, defaultSampleRate); + } + } + + void querySupportedSampleRates (WAVEFORMATEXTENSIBLE format, ComSmartPtr<IAudioClient>& audioClient) + { + for (auto rate : { 8000, 11025, 16000, 22050, 32000, + 44100, 48000, 88200, 96000, 176400, + 192000, 352800, 384000, 705600, 768000 }) + { + if (rates.contains (rate)) + continue; + + format.Format.nSamplesPerSec = (DWORD) rate; + format.Format.nAvgBytesPerSec = (DWORD) (format.Format.nSamplesPerSec * format.Format.nChannels * format.Format.wBitsPerSample / 8); + + WAVEFORMATEX* nearestFormat = nullptr; + + if (SUCCEEDED (audioClient->IsFormatSupported (isExclusiveMode (deviceMode) ? AUDCLNT_SHAREMODE_EXCLUSIVE + : AUDCLNT_SHAREMODE_SHARED, + (WAVEFORMATEX*) &format, + isExclusiveMode (deviceMode) ? nullptr + : &nearestFormat))) + { + if (nearestFormat != nullptr) + rate = nearestFormat->nSamplesPerSec; + + if (! rates.contains (rate)) + rates.addUsingDefaultSort (rate); + } + + CoTaskMemFree (nearestFormat); + } + } + struct AudioSampleFormat { bool useFloat; @@ -596,22 +720,35 @@ private: format.SubFormat = sampleFormat.useFloat ? KSDATAFORMAT_SUBTYPE_IEEE_FLOAT : KSDATAFORMAT_SUBTYPE_PCM; format.dwChannelMask = newMixFormatChannelMask; - WAVEFORMATEXTENSIBLE* nearestFormat = nullptr; + WAVEFORMATEX* nearestFormat = nullptr; - HRESULT hr = clientToUse->IsFormatSupported (useExclusiveMode ? AUDCLNT_SHAREMODE_EXCLUSIVE - : AUDCLNT_SHAREMODE_SHARED, + HRESULT hr = clientToUse->IsFormatSupported (isExclusiveMode (deviceMode) ? AUDCLNT_SHAREMODE_EXCLUSIVE + : AUDCLNT_SHAREMODE_SHARED, (WAVEFORMATEX*) &format, - useExclusiveMode ? nullptr : (WAVEFORMATEX**) &nearestFormat); + isExclusiveMode (deviceMode) ? nullptr + : &nearestFormat); logFailure (hr); - if (hr == S_FALSE && format.Format.nSamplesPerSec == nearestFormat->Format.nSamplesPerSec) + auto supportsSRC = supportsSampleRateConversion (deviceMode); + + if (hr == S_FALSE + && nearestFormat != nullptr + && (format.Format.nSamplesPerSec == nearestFormat->nSamplesPerSec + || supportsSRC)) { - copyWavFormat (format, (const WAVEFORMATEX*) nearestFormat); + copyWavFormat (format, nearestFormat); + + if (supportsSRC) + { + format.Format.nSamplesPerSec = (DWORD) newSampleRate; + format.Format.nAvgBytesPerSec = (DWORD) (format.Format.nSamplesPerSec * format.Format.nBlockAlign); + } + hr = S_OK; } CoTaskMemFree (nearestFormat); - return check (hr); + return hr == S_OK; } bool findSupportedFormat (IAudioClient* clientToUse, double newSampleRate, @@ -635,50 +772,88 @@ private: return false; } - bool tryInitialisingWithBufferSize (int bufferSizeSamples) + DWORD getStreamFlags() { - WAVEFORMATEXTENSIBLE format; + DWORD streamFlags = 0x40000; /*AUDCLNT_STREAMFLAGS_EVENTCALLBACK*/ - if (findSupportedFormat (client, sampleRate, mixFormatChannelMask, format)) + if (supportsSampleRateConversion (deviceMode)) + streamFlags |= (0x80000000 /*AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM*/ + | 0x8000000); /*AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY*/ + + return streamFlags; + } + + bool initialiseLowLatencyClient (int bufferSizeSamples, WAVEFORMATEXTENSIBLE format) + { + if (auto audioClient3 = client.getInterface<IAudioClient3>()) + return check (audioClient3->InitializeSharedAudioStream (getStreamFlags(), + bufferSizeSamples, + (WAVEFORMATEX*) &format, + nullptr)); + + return false; + } + + bool initialiseStandardClient (int bufferSizeSamples, WAVEFORMATEXTENSIBLE format) + { + REFERENCE_TIME defaultPeriod = 0, minPeriod = 0; + + check (client->GetDevicePeriod (&defaultPeriod, &minPeriod)); + + if (isExclusiveMode (deviceMode) && bufferSizeSamples > 0) + defaultPeriod = jmax (minPeriod, samplesToRefTime (bufferSizeSamples, format.Format.nSamplesPerSec)); + + for (;;) { - REFERENCE_TIME defaultPeriod = 0, minPeriod = 0; + GUID session; + auto hr = client->Initialize (isExclusiveMode (deviceMode) ? AUDCLNT_SHAREMODE_EXCLUSIVE + : AUDCLNT_SHAREMODE_SHARED, + getStreamFlags(), + defaultPeriod, + isExclusiveMode (deviceMode) ? defaultPeriod : 0, + (WAVEFORMATEX*) &format, + &session); + + if (check (hr)) + return true; - check (client->GetDevicePeriod (&defaultPeriod, &minPeriod)); + // Handle the "alignment dance" : http://msdn.microsoft.com/en-us/library/windows/desktop/dd370875(v=vs.85).aspx (see Remarks) + if (hr != MAKE_HRESULT (1, 0x889, 0x19)) // AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED + break; - if (useExclusiveMode && bufferSizeSamples > 0) - defaultPeriod = jmax (minPeriod, samplesToRefTime (bufferSizeSamples, format.Format.nSamplesPerSec)); + UINT32 numFrames = 0; + if (! check (client->GetBufferSize (&numFrames))) + break; - for (;;) - { - GUID session; - HRESULT hr = client->Initialize (useExclusiveMode ? AUDCLNT_SHAREMODE_EXCLUSIVE : AUDCLNT_SHAREMODE_SHARED, - 0x40000 /*AUDCLNT_STREAMFLAGS_EVENTCALLBACK*/, - defaultPeriod, useExclusiveMode ? defaultPeriod : 0, (WAVEFORMATEX*) &format, &session); + // Recreate client + client = nullptr; + client = createClient(); - if (check (hr)) - { - actualNumChannels = format.Format.nChannels; - const bool isFloat = format.Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE && format.SubFormat == KSDATAFORMAT_SUBTYPE_IEEE_FLOAT; - bytesPerSample = format.Format.wBitsPerSample / 8; - bytesPerFrame = format.Format.nBlockAlign; + defaultPeriod = samplesToRefTime (numFrames, format.Format.nSamplesPerSec); + } - updateFormat (isFloat); - return true; - } + return false; + } - // Handle the "alignment dance" : http://msdn.microsoft.com/en-us/library/windows/desktop/dd370875(v=vs.85).aspx (see Remarks) - if (hr != MAKE_HRESULT (1, 0x889, 0x19)) // AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED - break; + bool tryInitialisingWithBufferSize (int bufferSizeSamples) + { + WAVEFORMATEXTENSIBLE format; - UINT32 numFrames = 0; - if (! check (client->GetBufferSize (&numFrames))) - break; + if (findSupportedFormat (client, sampleRate, mixFormatChannelMask, format)) + { + auto isInitialised = isLowLatencyMode (deviceMode) ? initialiseLowLatencyClient (bufferSizeSamples, format) + : initialiseStandardClient (bufferSizeSamples, format); + + if (isInitialised) + { + actualNumChannels = format.Format.nChannels; + const bool isFloat = format.Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE && format.SubFormat == KSDATAFORMAT_SUBTYPE_IEEE_FLOAT; + bytesPerSample = format.Format.wBitsPerSample / 8; + bytesPerFrame = format.Format.nBlockAlign; - // Recreate client - client = nullptr; - client = createClient(); + updateFormat (isFloat); - defaultPeriod = samplesToRefTime (numFrames, format.Format.nSamplesPerSec); + return true; } } @@ -692,8 +867,8 @@ private: class WASAPIInputDevice : public WASAPIDeviceBase { public: - WASAPIInputDevice (const ComSmartPtr<IMMDevice>& d, bool exclusiveMode, std::function<void()>&& reopenCallback) - : WASAPIDeviceBase (d, exclusiveMode, std::move (reopenCallback)) + WASAPIInputDevice (const ComSmartPtr<IMMDevice>& d, WASAPIDeviceMode mode) + : WASAPIDeviceBase (d, mode) { } @@ -746,6 +921,8 @@ public: return false; purgeInputBuffers(); + isActive = true; + return true; } @@ -853,8 +1030,8 @@ private: class WASAPIOutputDevice : public WASAPIDeviceBase { public: - WASAPIOutputDevice (const ComSmartPtr<IMMDevice>& d, bool exclusiveMode, std::function<void()>&& reopenCallback) - : WASAPIDeviceBase (d, exclusiveMode, std::move (reopenCallback)) + WASAPIOutputDevice (const ComSmartPtr<IMMDevice>& d, WASAPIDeviceMode mode) + : WASAPIDeviceBase (d, mode) { } @@ -899,7 +1076,12 @@ public: if (check (renderClient->GetBuffer (samplesToDo, &outputData))) renderClient->ReleaseBuffer (samplesToDo, AUDCLNT_BUFFERFLAGS_SILENT); - return check (client->Start()); + if (! check (client->Start())) + return false; + + isActive = true; + + return true; } int getNumSamplesAvailableToCopy() const @@ -907,7 +1089,7 @@ public: if (numChannels <= 0) return 0; - if (! useExclusiveMode) + if (! isExclusiveMode (deviceMode)) { UINT32 padding = 0; @@ -929,7 +1111,7 @@ public: while (bufferSize > 0) { // This is needed in order not to drop any input data if the output device endpoint buffer was full - if ((! useExclusiveMode) && inputDevice != nullptr + if ((! isExclusiveMode (deviceMode)) && inputDevice != nullptr && WaitForSingleObject (inputDevice->clientEvent, 0) == WAIT_OBJECT_0) inputDevice->handleDeviceBuffer(); @@ -944,7 +1126,7 @@ public: break; } - if (useExclusiveMode && WaitForSingleObject (clientEvent, 1000) == WAIT_TIMEOUT) + if (isExclusiveMode (deviceMode) && WaitForSingleObject (clientEvent, 1000) == WAIT_TIMEOUT) break; uint8* outputData = nullptr; @@ -978,12 +1160,12 @@ public: const String& typeName, const String& outputDeviceID, const String& inputDeviceID, - bool exclusiveMode) + WASAPIDeviceMode mode) : AudioIODevice (deviceName, typeName), Thread ("JUCE WASAPI"), outputDeviceId (outputDeviceID), inputDeviceId (inputDeviceID), - useExclusiveMode (exclusiveMode) + deviceMode (mode) { } @@ -1002,21 +1184,48 @@ public: { jassert (inputDevice != nullptr || outputDevice != nullptr); + sampleRates.clear(); + if (inputDevice != nullptr && outputDevice != nullptr) { defaultSampleRate = jmin (inputDevice->defaultSampleRate, outputDevice->defaultSampleRate); - minBufferSize = jmin (inputDevice->minBufferSize, outputDevice->minBufferSize); + minBufferSize = jmax (inputDevice->minBufferSize, outputDevice->minBufferSize); defaultBufferSize = jmax (inputDevice->defaultBufferSize, outputDevice->defaultBufferSize); - sampleRates = inputDevice->rates; - sampleRates.removeValuesNotIn (outputDevice->rates); + + if (isLowLatencyMode (deviceMode)) + { + lowLatencyMaxBufferSize = jmin (inputDevice->lowLatencyMaxBufferSize, outputDevice->lowLatencyMaxBufferSize); + lowLatencyBufferSizeMultiple = jmax (inputDevice->lowLatencyBufferSizeMultiple, outputDevice->lowLatencyBufferSizeMultiple); + } + + sampleRates.addArray (inputDevice->rates); + + if (supportsSampleRateConversion (deviceMode)) + { + for (auto r : outputDevice->rates) + if (! sampleRates.contains (r)) + sampleRates.addUsingDefaultSort (r); + } + else + { + sampleRates.removeValuesNotIn (outputDevice->rates); + } } else { - WASAPIDeviceBase* d = inputDevice != nullptr ? static_cast<WASAPIDeviceBase*> (inputDevice.get()) - : static_cast<WASAPIDeviceBase*> (outputDevice.get()); + auto* d = inputDevice != nullptr ? static_cast<WASAPIDeviceBase*> (inputDevice.get()) + : static_cast<WASAPIDeviceBase*> (outputDevice.get()); + defaultSampleRate = d->defaultSampleRate; minBufferSize = d->minBufferSize; defaultBufferSize = d->defaultBufferSize; + + if (isLowLatencyMode (deviceMode)) + { + lowLatencyMaxBufferSize = d->lowLatencyMaxBufferSize; + lowLatencyBufferSizeMultiple = d->lowLatencyBufferSizeMultiple; + } + sampleRates = d->rates; } @@ -1026,13 +1235,28 @@ public: if (minBufferSize != defaultBufferSize) bufferSizes.addUsingDefaultSort (minBufferSize); - int n = 64; - for (int i = 0; i < 40; ++i) + if (isLowLatencyMode (deviceMode)) + { + auto size = minBufferSize; + + while (size < lowLatencyMaxBufferSize) + { + size += lowLatencyBufferSizeMultiple; + + if (! bufferSizes.contains (size)) + bufferSizes.addUsingDefaultSort (size); + } + } + else { - if (n >= minBufferSize && n <= 2048 && ! bufferSizes.contains (n)) - bufferSizes.addUsingDefaultSort (n); + int n = 64; + for (int i = 0; i < 40; ++i) + { + if (n >= minBufferSize && n <= 2048 && ! bufferSizes.contains (n)) + bufferSizes.addUsingDefaultSort (n); - n += (n < 512) ? 32 : (n < 1024 ? 64 : 128); + n += (n < 512) ? 32 : (n < 1024 ? 64 : 128); + } } return true; @@ -1107,7 +1331,7 @@ public: return lastError; } - if (useExclusiveMode) + if (isExclusiveMode (deviceMode)) { // This is to make sure that the callback uses actualBufferSize in case of exclusive mode if (inputDevice != nullptr && outputDevice != nullptr && inputDevice->actualBufferSize != outputDevice->actualBufferSize) @@ -1124,7 +1348,8 @@ public: if (inputDevice != nullptr) ResetEvent (inputDevice->clientEvent); if (outputDevice != nullptr) ResetEvent (outputDevice->clientEvent); - deviceBecameInactive = false; + shouldShutdown = false; + deviceSampleRateChanged = false; startThread (8); Thread::sleep (5); @@ -1233,7 +1458,6 @@ public: auto bufferSize = currentBufferSizeSamples; auto numInputBuffers = getActiveInputChannels().countNumberOfSetBits(); auto numOutputBuffers = getActiveOutputChannels().countNumberOfSetBits(); - bool sampleRateHasChanged = false; AudioBuffer<float> ins (jmax (1, numInputBuffers), bufferSize + 32); AudioBuffer<float> outs (jmax (1, numOutputBuffers), bufferSize + 32); @@ -1244,14 +1468,23 @@ public: while (! threadShouldExit()) { - if (outputDevice != nullptr && outputDevice->shouldClose) - deviceBecameInactive = true; - - if (inputDevice != nullptr && ! deviceBecameInactive) + if ((outputDevice != nullptr && outputDevice->shouldShutdown) + || (inputDevice != nullptr && inputDevice->shouldShutdown)) { - if (inputDevice->shouldClose) - deviceBecameInactive = true; + shouldShutdown = true; + triggerAsyncUpdate(); + break; + } + + auto inputDeviceActive = (inputDevice != nullptr && inputDevice->isActive); + auto outputDeviceActive = (outputDevice != nullptr && outputDevice->isActive); + + if (! inputDeviceActive && ! outputDeviceActive) + continue; + + if (inputDeviceActive) + { if (outputDevice == nullptr) { if (WaitForSingleObject (inputDevice->clientEvent, 1000) == WAIT_TIMEOUT) @@ -1264,7 +1497,7 @@ public: } else { - if (useExclusiveMode && WaitForSingleObject (inputDevice->clientEvent, 0) == WAIT_OBJECT_0) + if (isExclusiveMode (deviceMode) && WaitForSingleObject (inputDevice->clientEvent, 0) == WAIT_OBJECT_0) inputDevice->handleDeviceBuffer(); } @@ -1272,12 +1505,13 @@ public: if (inputDevice->sampleRateHasChanged) { - sampleRateHasChanged = true; - sampleRateChangedByOutput = false; + deviceSampleRateChanged = true; + triggerAsyncUpdate(); + + break; } } - if (! deviceBecameInactive) { const ScopedTryLock sl (startStopLock); @@ -1288,7 +1522,7 @@ public: outs.clear(); } - if (outputDevice != nullptr && ! deviceBecameInactive) + if (outputDeviceActive) { // Note that this function is handed the input device so it can check for the event and make sure // the input reservoir is filled up correctly even when bufferSize > device actualBufferSize @@ -1296,15 +1530,11 @@ public: if (outputDevice->sampleRateHasChanged) { - sampleRateHasChanged = true; - sampleRateChangedByOutput = true; - } - } + deviceSampleRateChanged = true; + triggerAsyncUpdate(); - if (sampleRateHasChanged || deviceBecameInactive) - { - triggerAsyncUpdate(); - break; // Quit the thread... will restart it later! + break; + } } } } @@ -1317,9 +1547,10 @@ private: // Device stats... std::unique_ptr<WASAPIInputDevice> inputDevice; std::unique_ptr<WASAPIOutputDevice> outputDevice; - const bool useExclusiveMode; + WASAPIDeviceMode deviceMode; double defaultSampleRate = 0; int minBufferSize = 0, defaultBufferSize = 0; + int lowLatencyMaxBufferSize = 0, lowLatencyBufferSizeMultiple = 0; int latencyIn = 0, latencyOut = 0; Array<double> sampleRates; Array<int> bufferSizes; @@ -1332,7 +1563,7 @@ private: AudioIODeviceCallback* callback = {}; CriticalSection startStopLock; - bool sampleRateChangedByOutput = false, deviceBecameInactive = false; + std::atomic<bool> shouldShutdown { false }, deviceSampleRateChanged { false }; BigInteger lastKnownInputChannels, lastKnownOutputChannels; @@ -1368,57 +1599,54 @@ private: auto flow = getDataFlow (device); - auto deviceReopenCallback = [this] - { - if (deviceBecameInactive) - { - deviceBecameInactive = false; - MessageManager::callAsync ([this] { reopenDevices(); }); - } - }; - if (deviceId == inputDeviceId && flow == eCapture) - inputDevice.reset (new WASAPIInputDevice (device, useExclusiveMode, deviceReopenCallback)); + inputDevice.reset (new WASAPIInputDevice (device, deviceMode)); else if (deviceId == outputDeviceId && flow == eRender) - outputDevice.reset (new WASAPIOutputDevice (device, useExclusiveMode, deviceReopenCallback)); + outputDevice.reset (new WASAPIOutputDevice (device, deviceMode)); } return (outputDeviceId.isEmpty() || (outputDevice != nullptr && outputDevice->isOk())) && (inputDeviceId.isEmpty() || (inputDevice != nullptr && inputDevice->isOk())); } - void reopenDevices() + //============================================================================== + void handleAsyncUpdate() override { - outputDevice = nullptr; - inputDevice = nullptr; + auto closeDevices = [this] + { + close(); - initialise(); + outputDevice = nullptr; + inputDevice = nullptr; + }; - open (lastKnownInputChannels, lastKnownOutputChannels, - getChangedSampleRate(), currentBufferSizeSamples); + if (shouldShutdown) + { + closeDevices(); + } + else if (deviceSampleRateChanged) + { + auto sampleRateChangedByInput = (inputDevice != nullptr && inputDevice->sampleRateHasChanged); - start (callback); - } + closeDevices(); + initialise(); - //============================================================================== - void handleAsyncUpdate() override - { - stop(); + auto changedSampleRate = [this, sampleRateChangedByInput]() + { + if (inputDevice != nullptr && sampleRateChangedByInput) + return inputDevice->defaultSampleRate; - // sample rate change - if (! deviceBecameInactive) - reopenDevices(); - } + if (outputDevice != nullptr && ! sampleRateChangedByInput) + return outputDevice->defaultSampleRate; - double getChangedSampleRate() const - { - if (outputDevice != nullptr && sampleRateChangedByOutput) - return outputDevice->defaultSampleRate; + return 0.0; + }(); - if (inputDevice != nullptr && ! sampleRateChangedByOutput) - return inputDevice->defaultSampleRate; + open (lastKnownInputChannels, lastKnownOutputChannels, + changedSampleRate, currentBufferSizeSamples); - return 0.0; + start (callback); + } } //============================================================================== @@ -1431,10 +1659,10 @@ class WASAPIAudioIODeviceType : public AudioIODeviceType, private DeviceChangeDetector { public: - WASAPIAudioIODeviceType (bool exclusive) - : AudioIODeviceType (exclusive ? "Windows Audio (Exclusive Mode)" : "Windows Audio"), + WASAPIAudioIODeviceType (WASAPIDeviceMode mode) + : AudioIODeviceType (getDeviceTypename (mode)), DeviceChangeDetector (L"Windows Audio"), - exclusiveMode (exclusive) + deviceMode (mode) { } @@ -1502,7 +1730,7 @@ public: getTypeName(), outputDeviceIds [outputIndex], inputDeviceIds [inputIndex], - exclusiveMode)); + deviceMode)); if (! device->initialise()) device = nullptr; @@ -1516,7 +1744,7 @@ public: StringArray inputDeviceNames, inputDeviceIds; private: - const bool exclusiveMode; + WASAPIDeviceMode deviceMode; bool hasScanned = false; ComSmartPtr<IMMDeviceEnumerator> enumerator; @@ -1539,7 +1767,7 @@ private: HRESULT notify() { if (device != nullptr) - device->triggerAsyncDeviceChangeCallback(); + device->triggerAsyncDeviceChangeCallback(); return S_OK; } @@ -1671,6 +1899,17 @@ private: callDeviceChangeListeners(); } + //============================================================================== + static String getDeviceTypename (WASAPIDeviceMode mode) + { + if (mode == WASAPIDeviceMode::shared) return "Windows Audio"; + if (mode == WASAPIDeviceMode::sharedLowLatency) return "Windows Audio (Low Latency Mode)"; + if (mode == WASAPIDeviceMode::exclusive) return "Windows Audio (Exclusive Mode)"; + + jassertfalse; + return {}; + } + //============================================================================== JUCE_DECLARE_WEAK_REFERENCEABLE (WASAPIAudioIODeviceType) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WASAPIAudioIODeviceType) @@ -1729,19 +1968,6 @@ struct MMDeviceMasterVolume } -//============================================================================== -AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_WASAPI (bool exclusiveMode) -{ - #if ! JUCE_WASAPI_EXCLUSIVE - if (exclusiveMode) - return nullptr; - #endif - - return SystemStats::getOperatingSystemType() >= SystemStats::WinVista - ? new WasapiClasses::WASAPIAudioIODeviceType (exclusiveMode) - : nullptr; -} - //============================================================================== #define JUCE_SYSTEMAUDIOVOL_IMPLEMENTED 1 float JUCE_CALLTYPE SystemAudioVolume::getGain() { return WasapiClasses::MMDeviceMasterVolume().getGain(); } diff --git a/modules/juce_audio_devices/native/oboe/CMakeLists.txt b/modules/juce_audio_devices/native/oboe/CMakeLists.txt new file mode 100644 index 00000000..f05dd460 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/CMakeLists.txt @@ -0,0 +1,91 @@ +cmake_minimum_required(VERSION 3.4.1) + +# Set the name of the project and store it in PROJECT_NAME. Also set the following variables: +# PROJECT_SOURCE_DIR (usually the root directory where Oboe has been cloned e.g.) +# PROJECT_BINARY_DIR (usually the containing project's binary directory, +# e.g. ${OBOE_HOME}/samples/RhythmGame/.externalNativeBuild/cmake/ndkExtractorDebug/x86/oboe-bin) +project(oboe) + +set (oboe_sources + src/aaudio/AAudioLoader.cpp + src/aaudio/AudioStreamAAudio.cpp + src/common/AudioSourceCaller.cpp + src/common/AudioStream.cpp + src/common/AudioStreamBuilder.cpp + src/common/DataConversionFlowGraph.cpp + src/common/FilterAudioStream.cpp + src/common/FixedBlockAdapter.cpp + src/common/FixedBlockReader.cpp + src/common/FixedBlockWriter.cpp + src/common/LatencyTuner.cpp + src/common/SourceFloatCaller.cpp + src/common/SourceI16Caller.cpp + src/common/Utilities.cpp + src/common/QuirksManager.cpp + src/fifo/FifoBuffer.cpp + src/fifo/FifoController.cpp + src/fifo/FifoControllerBase.cpp + src/fifo/FifoControllerIndirect.cpp + src/flowgraph/FlowGraphNode.cpp + src/flowgraph/ClipToRange.cpp + src/flowgraph/ManyToMultiConverter.cpp + src/flowgraph/MonoToMultiConverter.cpp + src/flowgraph/RampLinear.cpp + src/flowgraph/SampleRateConverter.cpp + src/flowgraph/SinkFloat.cpp + src/flowgraph/SinkI16.cpp + src/flowgraph/SinkI24.cpp + src/flowgraph/SourceFloat.cpp + src/flowgraph/SourceI16.cpp + src/flowgraph/SourceI24.cpp + src/flowgraph/resampler/IntegerRatio.cpp + src/flowgraph/resampler/LinearResampler.cpp + src/flowgraph/resampler/MultiChannelResampler.cpp + src/flowgraph/resampler/PolyphaseResampler.cpp + src/flowgraph/resampler/PolyphaseResamplerMono.cpp + src/flowgraph/resampler/PolyphaseResamplerStereo.cpp + src/flowgraph/resampler/SincResampler.cpp + src/flowgraph/resampler/SincResamplerStereo.cpp + src/opensles/AudioInputStreamOpenSLES.cpp + src/opensles/AudioOutputStreamOpenSLES.cpp + src/opensles/AudioStreamBuffered.cpp + src/opensles/AudioStreamOpenSLES.cpp + src/opensles/EngineOpenSLES.cpp + src/opensles/OpenSLESUtilities.cpp + src/opensles/OutputMixerOpenSLES.cpp + src/common/StabilizedCallback.cpp + src/common/Trace.cpp + src/common/Version.cpp + ) + +add_library(oboe ${oboe_sources}) + +# Specify directories which the compiler should look for headers +target_include_directories(oboe + PRIVATE src + PUBLIC include) + +# JUCE CHANGE STARTS HERE + +# This comment provided for Apache License compliance. We've removed the extra warnings flags and +# the `-Werror` option, to avoid cases where compilers produce unexpected errors and fail the build. +# We've also removed the explicit `-std=c++14` compile option, and replaced it with a more +# cmake-friendly way of specifying the language standard. + +target_compile_options(oboe PRIVATE -Ofast) +set_target_properties(oboe PROPERTIES CXX_STANDARD 14 CXX_STANDARD_REQUIRED TRUE CXX_EXTENSIONS FALSE) + +# JUCE CHANGE ENDS HERE + +# Enable logging for debug builds +target_compile_definitions(oboe PUBLIC $<$<CONFIG:DEBUG>:OBOE_ENABLE_LOGGING=1>) + +target_link_libraries(oboe PRIVATE log OpenSLES) + +# When installing oboe put the libraries in the lib/<ABI> folder e.g. lib/arm64-v8a +install(TARGETS oboe + LIBRARY DESTINATION lib/${ANDROID_ABI} + ARCHIVE DESTINATION lib/${ANDROID_ABI}) + +# Also install the headers +install(DIRECTORY include/oboe DESTINATION include) diff --git a/modules/juce_audio_devices/native/oboe/LICENSE b/modules/juce_audio_devices/native/oboe/LICENSE new file mode 100755 index 00000000..d6456956 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/modules/juce_audio_devices/native/oboe/include/oboe/AudioStream.h b/modules/juce_audio_devices/native/oboe/include/oboe/AudioStream.h new file mode 100644 index 00000000..a158aafc --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/include/oboe/AudioStream.h @@ -0,0 +1,543 @@ +/* + * Copyright 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBOE_STREAM_H_ +#define OBOE_STREAM_H_ + +#include <atomic> +#include <cstdint> +#include <ctime> +#include <mutex> +#include "oboe/Definitions.h" +#include "oboe/ResultWithValue.h" +#include "oboe/AudioStreamBuilder.h" +#include "oboe/AudioStreamBase.h" + +/** WARNING - UNDER CONSTRUCTION - THIS API WILL CHANGE. */ + +namespace oboe { + +/** + * The default number of nanoseconds to wait for when performing state change operations on the + * stream, such as `start` and `stop`. + * + * @see oboe::AudioStream::start + */ +constexpr int64_t kDefaultTimeoutNanos = (2000 * kNanosPerMillisecond); + +/** + * Base class for Oboe C++ audio stream. + */ +class AudioStream : public AudioStreamBase { + friend class AudioStreamBuilder; // allow access to setWeakThis() and lockWeakThis() +public: + + AudioStream() {} + + /** + * Construct an `AudioStream` using the given `AudioStreamBuilder` + * + * @param builder containing all the stream's attributes + */ + explicit AudioStream(const AudioStreamBuilder &builder); + + virtual ~AudioStream() = default; + + /** + * Open a stream based on the current settings. + * + * Note that we do not recommend re-opening a stream that has been closed. + * TODO Should we prevent re-opening? + * + * @return + */ + virtual Result open() { + return Result::OK; // Called by subclasses. Might do more in the future. + } + + /** + * Close the stream and deallocate any resources from the open() call. + */ + virtual Result close(); + + /** + * Start the stream. This will block until the stream has been started, an error occurs + * or `timeoutNanoseconds` has been reached. + */ + virtual Result start(int64_t timeoutNanoseconds = kDefaultTimeoutNanos); + + /** + * Pause the stream. This will block until the stream has been paused, an error occurs + * or `timeoutNanoseconds` has been reached. + */ + virtual Result pause(int64_t timeoutNanoseconds = kDefaultTimeoutNanos); + + /** + * Flush the stream. This will block until the stream has been flushed, an error occurs + * or `timeoutNanoseconds` has been reached. + */ + virtual Result flush(int64_t timeoutNanoseconds = kDefaultTimeoutNanos); + + /** + * Stop the stream. This will block until the stream has been stopped, an error occurs + * or `timeoutNanoseconds` has been reached. + */ + virtual Result stop(int64_t timeoutNanoseconds = kDefaultTimeoutNanos); + + /* Asynchronous requests. + * Use waitForStateChange() if you need to wait for completion. + */ + + /** + * Start the stream asynchronously. Returns immediately (does not block). Equivalent to calling + * `start(0)`. + */ + virtual Result requestStart() = 0; + + /** + * Pause the stream asynchronously. Returns immediately (does not block). Equivalent to calling + * `pause(0)`. + */ + virtual Result requestPause() = 0; + + /** + * Flush the stream asynchronously. Returns immediately (does not block). Equivalent to calling + * `flush(0)`. + */ + virtual Result requestFlush() = 0; + + /** + * Stop the stream asynchronously. Returns immediately (does not block). Equivalent to calling + * `stop(0)`. + */ + virtual Result requestStop() = 0; + + /** + * Query the current state, eg. StreamState::Pausing + * + * @return state or a negative error. + */ + virtual StreamState getState() const = 0; + + /** + * Wait until the stream's current state no longer matches the input state. + * The input state is passed to avoid race conditions caused by the state + * changing between calls. + * + * Note that generally applications do not need to call this. It is considered + * an advanced technique and is mostly used for testing. + * + * <pre><code> + * int64_t timeoutNanos = 500 * kNanosPerMillisecond; // arbitrary 1/2 second + * StreamState currentState = stream->getState(); + * StreamState nextState = StreamState::Unknown; + * while (result == Result::OK && currentState != StreamState::Paused) { + * result = stream->waitForStateChange( + * currentState, &nextState, timeoutNanos); + * currentState = nextState; + * } + * </code></pre> + * + * If the state does not change within the timeout period then it will + * return ErrorTimeout. This is true even if timeoutNanoseconds is zero. + * + * @param inputState The state we want to change away from. + * @param nextState Pointer to a variable that will be set to the new state. + * @param timeoutNanoseconds The maximum time to wait in nanoseconds. + * @return Result::OK or a Result::Error. + */ + virtual Result waitForStateChange(StreamState inputState, + StreamState *nextState, + int64_t timeoutNanoseconds) = 0; + + /** + * This can be used to adjust the latency of the buffer by changing + * the threshold where blocking will occur. + * By combining this with getXRunCount(), the latency can be tuned + * at run-time for each device. + * + * This cannot be set higher than getBufferCapacity(). + * + * @param requestedFrames requested number of frames that can be filled without blocking + * @return the resulting buffer size in frames (obtained using value()) or an error (obtained + * using error()) + */ + virtual ResultWithValue<int32_t> setBufferSizeInFrames(int32_t /* requestedFrames */) { + return Result::ErrorUnimplemented; + } + + /** + * An XRun is an Underrun or an Overrun. + * During playing, an underrun will occur if the stream is not written in time + * and the system runs out of valid data. + * During recording, an overrun will occur if the stream is not read in time + * and there is no place to put the incoming data so it is discarded. + * + * An underrun or overrun can cause an audible "pop" or "glitch". + * + * @return a result which is either Result::OK with the xRun count as the value, or a + * Result::Error* code + */ + virtual ResultWithValue<int32_t> getXRunCount() const { + return ResultWithValue<int32_t>(Result::ErrorUnimplemented); + } + + /** + * @return true if XRun counts are supported on the stream + */ + virtual bool isXRunCountSupported() const = 0; + + /** + * Query the number of frames that are read or written by the endpoint at one time. + * + * @return burst size + */ + virtual int32_t getFramesPerBurst() = 0; + + /** + * Get the number of bytes in each audio frame. This is calculated using the channel count + * and the sample format. For example, a 2 channel floating point stream will have + * 2 * 4 = 8 bytes per frame. + * + * @return number of bytes in each audio frame. + */ + int32_t getBytesPerFrame() const { return mChannelCount * getBytesPerSample(); } + + /** + * Get the number of bytes per sample. This is calculated using the sample format. For example, + * a stream using 16-bit integer samples will have 2 bytes per sample. + * + * @return the number of bytes per sample. + */ + int32_t getBytesPerSample() const; + + /** + * The number of audio frames written into the stream. + * This monotonic counter will never get reset. + * + * @return the number of frames written so far + */ + virtual int64_t getFramesWritten(); + + /** + * The number of audio frames read from the stream. + * This monotonic counter will never get reset. + * + * @return the number of frames read so far + */ + virtual int64_t getFramesRead(); + + /** + * Calculate the latency of a stream based on getTimestamp(). + * + * Output latency is the time it takes for a given frame to travel from the + * app to some type of digital-to-analog converter. If the DAC is external, for example + * in a USB interface or a TV connected by HDMI, then there may be additional latency + * that the Android device is unaware of. + * + * Input latency is the time it takes to a given frame to travel from an analog-to-digital + * converter (ADC) to the app. + * + * Note that the latency of an OUTPUT stream will increase abruptly when you write data to it + * and then decrease slowly over time as the data is consumed. + * + * The latency of an INPUT stream will decrease abruptly when you read data from it + * and then increase slowly over time as more data arrives. + * + * The latency of an OUTPUT stream is generally higher than the INPUT latency + * because an app generally tries to keep the OUTPUT buffer full and the INPUT buffer empty. + * + * @return a ResultWithValue which has a result of Result::OK and a value containing the latency + * in milliseconds, or a result of Result::Error*. + */ + virtual ResultWithValue<double> calculateLatencyMillis() { + return ResultWithValue<double>(Result::ErrorUnimplemented); + } + + /** + * Get the estimated time that the frame at `framePosition` entered or left the audio processing + * pipeline. + * + * This can be used to coordinate events and interactions with the external environment, and to + * estimate the latency of an audio stream. An example of usage can be found in the hello-oboe + * sample (search for "calculateCurrentOutputLatencyMillis"). + * + * The time is based on the implementation's best effort, using whatever knowledge is available + * to the system, but cannot account for any delay unknown to the implementation. + * + * @deprecated since 1.0, use AudioStream::getTimestamp(clockid_t clockId) instead, which + * returns ResultWithValue + * @param clockId the type of clock to use e.g. CLOCK_MONOTONIC + * @param framePosition the frame number to query + * @param timeNanoseconds an output parameter which will contain the presentation timestamp + */ + virtual Result getTimestamp(clockid_t /* clockId */, + int64_t* /* framePosition */, + int64_t* /* timeNanoseconds */) { + return Result::ErrorUnimplemented; + } + + /** + * Get the estimated time that the frame at `framePosition` entered or left the audio processing + * pipeline. + * + * This can be used to coordinate events and interactions with the external environment, and to + * estimate the latency of an audio stream. An example of usage can be found in the hello-oboe + * sample (search for "calculateCurrentOutputLatencyMillis"). + * + * The time is based on the implementation's best effort, using whatever knowledge is available + * to the system, but cannot account for any delay unknown to the implementation. + * + * @param clockId the type of clock to use e.g. CLOCK_MONOTONIC + * @return a FrameTimestamp containing the position and time at which a particular audio frame + * entered or left the audio processing pipeline, or an error if the operation failed. + */ + virtual ResultWithValue<FrameTimestamp> getTimestamp(clockid_t /* clockId */); + + // ============== I/O =========================== + /** + * Write data from the supplied buffer into the stream. This method will block until the write + * is complete or it runs out of time. + * + * If `timeoutNanoseconds` is zero then this call will not wait. + * + * @param buffer The address of the first sample. + * @param numFrames Number of frames to write. Only complete frames will be written. + * @param timeoutNanoseconds Maximum number of nanoseconds to wait for completion. + * @return a ResultWithValue which has a result of Result::OK and a value containing the number + * of frames actually written, or result of Result::Error*. + */ + virtual ResultWithValue<int32_t> write(const void* /* buffer */, + int32_t /* numFrames */, + int64_t /* timeoutNanoseconds */ ) { + return ResultWithValue<int32_t>(Result::ErrorUnimplemented); + } + + /** + * Read data into the supplied buffer from the stream. This method will block until the read + * is complete or it runs out of time. + * + * If `timeoutNanoseconds` is zero then this call will not wait. + * + * @param buffer The address of the first sample. + * @param numFrames Number of frames to read. Only complete frames will be read. + * @param timeoutNanoseconds Maximum number of nanoseconds to wait for completion. + * @return a ResultWithValue which has a result of Result::OK and a value containing the number + * of frames actually read, or result of Result::Error*. + */ + virtual ResultWithValue<int32_t> read(void* /* buffer */, + int32_t /* numFrames */, + int64_t /* timeoutNanoseconds */) { + return ResultWithValue<int32_t>(Result::ErrorUnimplemented); + } + + /** + * Get the underlying audio API which the stream uses. + * + * @return the API that this stream uses. + */ + virtual AudioApi getAudioApi() const = 0; + + /** + * Returns true if the underlying audio API is AAudio. + * + * @return true if this stream is implemented using the AAudio API. + */ + bool usesAAudio() const { + return getAudioApi() == AudioApi::AAudio; + } + + /** + * Only for debugging. Do not use in production. + * If you need to call this method something is wrong. + * If you think you need it for production then please let us know + * so we can modify Oboe so that you don't need this. + * + * @return nullptr or a pointer to a stream from the system API + */ + virtual void *getUnderlyingStream() const { + return nullptr; + } + + /** + * Launch a thread that will stop the stream. + */ + void launchStopThread(); + + /** + * Update mFramesWritten. + * For internal use only. + */ + virtual void updateFramesWritten() = 0; + + /** + * Update mFramesRead. + * For internal use only. + */ + virtual void updateFramesRead() = 0; + + /* + * Swap old callback for new callback. + * This not atomic. + * This should only be used internally. + * @param streamCallback + * @return previous streamCallback + */ + AudioStreamCallback *swapCallback(AudioStreamCallback *streamCallback) { + AudioStreamCallback *previousCallback = mStreamCallback; + mStreamCallback = streamCallback; + return previousCallback; + } + + /** + * @return number of frames of data currently in the buffer + */ + ResultWithValue<int32_t> getAvailableFrames(); + + /** + * Wait until the stream has a minimum amount of data available in its buffer. + * This can be used with an EXCLUSIVE MMAP input stream to avoid reading data too close to + * the DSP write position, which may cause glitches. + * + * @param numFrames minimum frames available + * @param timeoutNanoseconds + * @return number of frames available, ErrorTimeout + */ + ResultWithValue<int32_t> waitForAvailableFrames(int32_t numFrames, + int64_t timeoutNanoseconds); + +protected: + + /** + * This is used to detect more than one error callback from a stream. + * These were bugs in some versions of Android that caused multiple error callbacks. + * Internal bug b/63087953 + * + * Calling this sets an atomic<bool> true and returns the previous value. + * + * @return false on first call, true on subsequent calls + */ + bool wasErrorCallbackCalled() { + return mErrorCallbackCalled.exchange(true); + } + + /** + * Wait for a transition from one state to another. + * @return OK if the endingState was observed, or ErrorUnexpectedState + * if any state that was not the startingState or endingState was observed + * or ErrorTimeout. + */ + virtual Result waitForStateTransition(StreamState startingState, + StreamState endingState, + int64_t timeoutNanoseconds); + + /** + * Override this to provide a default for when the application did not specify a callback. + * + * @param audioData + * @param numFrames + * @return result + */ + virtual DataCallbackResult onDefaultCallback(void* /* audioData */, int /* numFrames */) { + return DataCallbackResult::Stop; + } + + /** + * Override this to provide your own behaviour for the audio callback + * + * @param audioData container array which audio frames will be written into or read from + * @param numFrames number of frames which were read/written + * @return the result of the callback: stop or continue + * + */ + DataCallbackResult fireDataCallback(void *audioData, int numFrames); + + /** + * @return true if callbacks may be called + */ + bool isDataCallbackEnabled() { + return mDataCallbackEnabled; + } + + /** + * This can be set false internally to prevent callbacks + * after DataCallbackResult::Stop has been returned. + */ + void setDataCallbackEnabled(bool enabled) { + mDataCallbackEnabled = enabled; + } + + /* + * Set a weak_ptr to this stream from the shared_ptr so that we can + * later use a shared_ptr in the error callback. + */ + void setWeakThis(std::shared_ptr<oboe::AudioStream> &sharedStream) { + mWeakThis = sharedStream; + } + + /* + * Make a shared_ptr that will prevent this stream from being deleted. + */ + std::shared_ptr<oboe::AudioStream> lockWeakThis() { + return mWeakThis.lock(); + } + + std::weak_ptr<AudioStream> mWeakThis; // weak pointer to this object + + /** + * Number of frames which have been written into the stream + * + * This is signed integer to match the counters in AAudio. + * At audio rates, the counter will overflow in about six million years. + */ + std::atomic<int64_t> mFramesWritten{}; + + /** + * Number of frames which have been read from the stream. + * + * This is signed integer to match the counters in AAudio. + * At audio rates, the counter will overflow in about six million years. + */ + std::atomic<int64_t> mFramesRead{}; + + std::mutex mLock; // for synchronizing start/stop/close + + +private: + // Log the scheduler if it changes. + void checkScheduler(); + int mPreviousScheduler = -1; + + std::atomic<bool> mDataCallbackEnabled{false}; + std::atomic<bool> mErrorCallbackCalled{false}; + +}; + +/** + * This struct is a stateless functor which closes an AudioStream prior to its deletion. + * This means it can be used to safely delete a smart pointer referring to an open stream. + */ + struct StreamDeleterFunctor { + void operator()(AudioStream *audioStream) { + if (audioStream) { + audioStream->close(); + } + delete audioStream; + } + }; +} // namespace oboe + +#endif /* OBOE_STREAM_H_ */ diff --git a/modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamBase.h b/modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamBase.h new file mode 100644 index 00000000..4a6237df --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamBase.h @@ -0,0 +1,202 @@ +/* + * Copyright 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBOE_STREAM_BASE_H_ +#define OBOE_STREAM_BASE_H_ + +#include <memory> +#include "oboe/AudioStreamCallback.h" +#include "oboe/Definitions.h" + +namespace oboe { + +/** + * Base class containing parameters for audio streams and builders. + **/ +class AudioStreamBase { + +public: + + AudioStreamBase() {} + + virtual ~AudioStreamBase() = default; + + // This class only contains primitives so we can use default constructor and copy methods. + + /** + * Default copy constructor + */ + AudioStreamBase(const AudioStreamBase&) = default; + + /** + * Default assignment operator + */ + AudioStreamBase& operator=(const AudioStreamBase&) = default; + + /** + * @return number of channels, for example 2 for stereo, or kUnspecified + */ + int32_t getChannelCount() const { return mChannelCount; } + + /** + * @return Direction::Input or Direction::Output + */ + Direction getDirection() const { return mDirection; } + + /** + * @return sample rate for the stream or kUnspecified + */ + int32_t getSampleRate() const { return mSampleRate; } + + /** + * @return the number of frames in each callback or kUnspecified. + */ + int32_t getFramesPerCallback() const { return mFramesPerCallback; } + + /** + * @return the audio sample format (e.g. Float or I16) + */ + AudioFormat getFormat() const { return mFormat; } + + /** + * Query the maximum number of frames that can be filled without blocking. + * If the stream has been closed the last known value will be returned. + * + * @return buffer size + */ + virtual int32_t getBufferSizeInFrames() { return mBufferSizeInFrames; } + + /** + * @return capacityInFrames or kUnspecified + */ + virtual int32_t getBufferCapacityInFrames() const { return mBufferCapacityInFrames; } + + /** + * @return the sharing mode of the stream. + */ + SharingMode getSharingMode() const { return mSharingMode; } + + /** + * @return the performance mode of the stream. + */ + PerformanceMode getPerformanceMode() const { return mPerformanceMode; } + + /** + * @return the device ID of the stream. + */ + int32_t getDeviceId() const { return mDeviceId; } + + /** + * @return the callback object for this stream, if set. + */ + AudioStreamCallback* getCallback() const { + return mStreamCallback; + } + + /** + * @return the usage for this stream. + */ + Usage getUsage() const { return mUsage; } + + /** + * @return the stream's content type. + */ + ContentType getContentType() const { return mContentType; } + + /** + * @return the stream's input preset. + */ + InputPreset getInputPreset() const { return mInputPreset; } + + /** + * @return the stream's session ID allocation strategy (None or Allocate). + */ + SessionId getSessionId() const { return mSessionId; } + + /** + * @return true if Oboe can convert channel counts to achieve optimal results. + */ + bool isChannelConversionAllowed() const { + return mChannelConversionAllowed; + } + + /** + * @return true if Oboe can convert data formats to achieve optimal results. + */ + bool isFormatConversionAllowed() const { + return mFormatConversionAllowed; + } + + /** + * @return whether and how Oboe can convert sample rates to achieve optimal results. + */ + SampleRateConversionQuality getSampleRateConversionQuality() const { + return mSampleRateConversionQuality; + } + +protected: + + /** The callback which will be fired when new data is ready to be read/written **/ + AudioStreamCallback *mStreamCallback = nullptr; + /** Number of audio frames which will be requested in each callback */ + int32_t mFramesPerCallback = kUnspecified; + /** Stream channel count */ + int32_t mChannelCount = kUnspecified; + /** Stream sample rate */ + int32_t mSampleRate = kUnspecified; + /** Stream audio device ID */ + int32_t mDeviceId = kUnspecified; + /** Stream buffer capacity specified as a number of audio frames */ + int32_t mBufferCapacityInFrames = kUnspecified; + /** Stream buffer size specified as a number of audio frames */ + int32_t mBufferSizeInFrames = kUnspecified; + /** + * Number of frames which will be copied to/from the audio device in a single read/write + * operation + */ + int32_t mFramesPerBurst = kUnspecified; + + /** Stream sharing mode */ + SharingMode mSharingMode = SharingMode::Shared; + /** Format of audio frames */ + AudioFormat mFormat = AudioFormat::Unspecified; + /** Stream direction */ + Direction mDirection = Direction::Output; + /** Stream performance mode */ + PerformanceMode mPerformanceMode = PerformanceMode::None; + + /** Stream usage. Only active on Android 28+ */ + Usage mUsage = Usage::Media; + /** Stream content type. Only active on Android 28+ */ + ContentType mContentType = ContentType::Music; + /** Stream input preset. Only active on Android 28+ + * TODO InputPreset::Unspecified should be considered as a possible default alternative. + */ + InputPreset mInputPreset = InputPreset::VoiceRecognition; + /** Stream session ID allocation strategy. Only active on Android 28+ */ + SessionId mSessionId = SessionId::None; + + // Control whether Oboe can convert channel counts to achieve optimal results. + bool mChannelConversionAllowed = false; + // Control whether Oboe can convert data formats to achieve optimal results. + bool mFormatConversionAllowed = false; + // Control whether and how Oboe can convert sample rates to achieve optimal results. + SampleRateConversionQuality mSampleRateConversionQuality = SampleRateConversionQuality::None; +}; + +} // namespace oboe + +#endif /* OBOE_STREAM_BASE_H_ */ diff --git a/modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamBuilder.h b/modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamBuilder.h new file mode 100644 index 00000000..a1ea0a85 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamBuilder.h @@ -0,0 +1,438 @@ +/* + * Copyright 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBOE_STREAM_BUILDER_H_ +#define OBOE_STREAM_BUILDER_H_ + +#include "oboe/Definitions.h" +#include "oboe/AudioStreamBase.h" +#include "ResultWithValue.h" + +namespace oboe { + + // This depends on AudioStream, so we use forward declaration, it will close and delete the stream + struct StreamDeleterFunctor; + using ManagedStream = std::unique_ptr<AudioStream, StreamDeleterFunctor>; + +/** + * Factory class for an audio Stream. + */ +class AudioStreamBuilder : public AudioStreamBase { +public: + + AudioStreamBuilder() : AudioStreamBase() {} + + AudioStreamBuilder(const AudioStreamBase &audioStreamBase): AudioStreamBase(audioStreamBase) {} + + /** + * Request a specific number of channels. + * + * Default is kUnspecified. If the value is unspecified then + * the application should query for the actual value after the stream is opened. + */ + AudioStreamBuilder *setChannelCount(int channelCount) { + mChannelCount = channelCount; + return this; + } + + /** + * Request the direction for a stream. The default is Direction::Output. + * + * @param direction Direction::Output or Direction::Input + */ + AudioStreamBuilder *setDirection(Direction direction) { + mDirection = direction; + return this; + } + + /** + * Request a specific sample rate in Hz. + * + * Default is kUnspecified. If the value is unspecified then + * the application should query for the actual value after the stream is opened. + * + * Technically, this should be called the "frame rate" or "frames per second", + * because it refers to the number of complete frames transferred per second. + * But it is traditionally called "sample rate". Se we use that term. + * + */ + AudioStreamBuilder *setSampleRate(int32_t sampleRate) { + mSampleRate = sampleRate; + return this; + } + + /** + * Request a specific number of frames for the data callback. + * + * Default is kUnspecified. If the value is unspecified then + * the actual number may vary from callback to callback. + * + * If an application can handle a varying number of frames then we recommend + * leaving this unspecified. This allow the underlying API to optimize + * the callbacks. But if your application is, for example, doing FFTs or other block + * oriented operations, then call this function to get the sizes you need. + * + * @param framesPerCallback + * @return pointer to the builder so calls can be chained + */ + AudioStreamBuilder *setFramesPerCallback(int framesPerCallback) { + mFramesPerCallback = framesPerCallback; + return this; + } + + /** + * Request a sample data format, for example Format::Float. + * + * Default is Format::Unspecified. If the value is unspecified then + * the application should query for the actual value after the stream is opened. + */ + AudioStreamBuilder *setFormat(AudioFormat format) { + mFormat = format; + return this; + } + + /** + * Set the requested buffer capacity in frames. + * BufferCapacityInFrames is the maximum possible BufferSizeInFrames. + * + * The final stream capacity may differ. For AAudio it should be at least this big. + * For OpenSL ES, it could be smaller. + * + * Default is kUnspecified. + * + * @param bufferCapacityInFrames the desired buffer capacity in frames or kUnspecified + * @return pointer to the builder so calls can be chained + */ + AudioStreamBuilder *setBufferCapacityInFrames(int32_t bufferCapacityInFrames) { + mBufferCapacityInFrames = bufferCapacityInFrames; + return this; + } + + /** + * Get the audio API which will be requested when opening the stream. No guarantees that this is + * the API which will actually be used. Query the stream itself to find out the API which is + * being used. + * + * If you do not specify the API, then AAudio will be used if isAAudioRecommended() + * returns true. Otherwise OpenSL ES will be used. + * + * @return the requested audio API + */ + AudioApi getAudioApi() const { return mAudioApi; } + + /** + * If you leave this unspecified then Oboe will choose the best API + * for the device and SDK version at runtime. + * + * This should almost always be left unspecified, except for debugging purposes. + * Specifying AAudio will force Oboe to use AAudio on 8.0, which is extremely risky. + * Specifying OpenSLES should mainly be used to test legacy performance/functionality. + * + * If the caller requests AAudio and it is supported then AAudio will be used. + * + * @param audioApi Must be AudioApi::Unspecified, AudioApi::OpenSLES or AudioApi::AAudio. + * @return pointer to the builder so calls can be chained + */ + AudioStreamBuilder *setAudioApi(AudioApi audioApi) { + mAudioApi = audioApi; + return this; + } + + /** + * Is the AAudio API supported on this device? + * + * AAudio was introduced in the Oreo 8.0 release. + * + * @return true if supported + */ + static bool isAAudioSupported(); + + /** + * Is the AAudio API recommended this device? + * + * AAudio may be supported but not recommended because of version specific issues. + * AAudio is not recommended for Android 8.0 or earlier versions. + * + * @return true if recommended + */ + static bool isAAudioRecommended(); + + /** + * Request a mode for sharing the device. + * The requested sharing mode may not be available. + * So the application should query for the actual mode after the stream is opened. + * + * @param sharingMode SharingMode::Shared or SharingMode::Exclusive + * @return pointer to the builder so calls can be chained + */ + AudioStreamBuilder *setSharingMode(SharingMode sharingMode) { + mSharingMode = sharingMode; + return this; + } + + /** + * Request a performance level for the stream. + * This will determine the latency, the power consumption, and the level of + * protection from glitches. + * + * @param performanceMode for example, PerformanceMode::LowLatency + * @return pointer to the builder so calls can be chained + */ + AudioStreamBuilder *setPerformanceMode(PerformanceMode performanceMode) { + mPerformanceMode = performanceMode; + return this; + } + + + /** + * Set the intended use case for the stream. + * + * The system will use this information to optimize the behavior of the stream. + * This could, for example, affect how volume and focus is handled for the stream. + * + * The default, if you do not call this function, is Usage::Media. + * + * Added in API level 28. + * + * @param usage the desired usage, eg. Usage::Game + */ + AudioStreamBuilder *setUsage(Usage usage) { + mUsage = usage; + return this; + } + + /** + * Set the type of audio data that the stream will carry. + * + * The system will use this information to optimize the behavior of the stream. + * This could, for example, affect whether a stream is paused when a notification occurs. + * + * The default, if you do not call this function, is ContentType::Music. + * + * Added in API level 28. + * + * @param contentType the type of audio data, eg. ContentType::Speech + */ + AudioStreamBuilder *setContentType(ContentType contentType) { + mContentType = contentType; + return this; + } + + /** + * Set the input (capture) preset for the stream. + * + * The system will use this information to optimize the behavior of the stream. + * This could, for example, affect which microphones are used and how the + * recorded data is processed. + * + * The default, if you do not call this function, is InputPreset::VoiceRecognition. + * That is because VoiceRecognition is the preset with the lowest latency + * on many platforms. + * + * Added in API level 28. + * + * @param inputPreset the desired configuration for recording + */ + AudioStreamBuilder *setInputPreset(InputPreset inputPreset) { + mInputPreset = inputPreset; + return this; + } + + /** Set the requested session ID. + * + * The session ID can be used to associate a stream with effects processors. + * The effects are controlled using the Android AudioEffect Java API. + * + * The default, if you do not call this function, is SessionId::None. + * + * If set to SessionId::Allocate then a session ID will be allocated + * when the stream is opened. + * + * The allocated session ID can be obtained by calling AudioStream::getSessionId() + * and then used with this function when opening another stream. + * This allows effects to be shared between streams. + * + * Session IDs from Oboe can be used the Android Java APIs and vice versa. + * So a session ID from an Oboe stream can be passed to Java + * and effects applied using the Java AudioEffect API. + * + * Allocated session IDs will always be positive and nonzero. + * + * Added in API level 28. + * + * @param sessionId an allocated sessionID or SessionId::Allocate + */ + AudioStreamBuilder *setSessionId(SessionId sessionId) { + mSessionId = sessionId; + return this; + } + + /** + * Request a stream to a specific audio input/output device given an audio device ID. + * + * In most cases, the primary device will be the appropriate device to use, and the + * deviceId can be left kUnspecified. + * + * On Android, for example, the ID could be obtained from the Java AudioManager. + * AudioManager.getDevices() returns an array of AudioDeviceInfo[], which contains + * a getId() method (as well as other type information), that should be passed + * to this method. + * + * + * Note that when using OpenSL ES, this will be ignored and the created + * stream will have deviceId kUnspecified. + * + * @param deviceId device identifier or kUnspecified + * @return pointer to the builder so calls can be chained + */ + AudioStreamBuilder *setDeviceId(int32_t deviceId) { + mDeviceId = deviceId; + return this; + } + + /** + * Specifies an object to handle data or error related callbacks from the underlying API. + * + * <strong>Important: See AudioStreamCallback for restrictions on what may be called + * from the callback methods.</strong> + * + * When an error callback occurs, the associated stream will be stopped and closed in a separate thread. + * + * A note on why the streamCallback parameter is a raw pointer rather than a smart pointer: + * + * The caller should retain ownership of the object streamCallback points to. At first glance weak_ptr may seem like + * a good candidate for streamCallback as this implies temporary ownership. However, a weak_ptr can only be created + * from a shared_ptr. A shared_ptr incurs some performance overhead. The callback object is likely to be accessed + * every few milliseconds when the stream requires new data so this overhead is something we want to avoid. + * + * This leaves a raw pointer as the logical type choice. The only caveat being that the caller must not destroy + * the callback before the stream has been closed. + * + * @param streamCallback + * @return pointer to the builder so calls can be chained + */ + AudioStreamBuilder *setCallback(AudioStreamCallback *streamCallback) { + mStreamCallback = streamCallback; + return this; + } + + /** + * If true then Oboe might convert channel counts to achieve optimal results. + * On some versions of Android for example, stereo streams could not use a FAST track. + * So a mono stream might be used instead and duplicated to two channels. + * On some devices, mono streams might be broken, so a stereo stream might be opened + * and converted to mono. + * + * Default is true. + */ + AudioStreamBuilder *setChannelConversionAllowed(bool allowed) { + mChannelConversionAllowed = allowed; + return this; + } + + /** + * If true then Oboe might convert data formats to achieve optimal results. + * On some versions of Android, for example, a float stream could not get a + * low latency data path. So an I16 stream might be opened and converted to float. + * + * Default is true. + */ + AudioStreamBuilder *setFormatConversionAllowed(bool allowed) { + mFormatConversionAllowed = allowed; + return this; + } + + /** + * Specify the quality of the sample rate converter in Oboe. + * + * If set to None then Oboe will not do sample rate conversion. But the underlying APIs might + * still do sample rate conversion if you specify a sample rate. + * That can prevent you from getting a low latency stream. + * + * If you do the conversion in Oboe then you might still get a low latency stream. + * + * Default is SampleRateConversionQuality::None + */ + AudioStreamBuilder *setSampleRateConversionQuality(SampleRateConversionQuality quality) { + mSampleRateConversionQuality = quality; + return this; + } + + /** + * @return true if AAudio will be used based on the current settings. + */ + bool willUseAAudio() const { + return (mAudioApi == AudioApi::AAudio && isAAudioSupported()) + || (mAudioApi == AudioApi::Unspecified && isAAudioRecommended()); + } + + /** + * Create and open a stream object based on the current settings. + * + * The caller owns the pointer to the AudioStream object. + * + * @deprecated Use openStream(std::shared_ptr<oboe::AudioStream> &stream) instead. + * @param stream pointer to a variable to receive the stream address + * @return OBOE_OK if successful or a negative error code + */ + Result openStream(AudioStream **stream); + + /** + * Create and open a stream object based on the current settings. + * + * The caller shares the pointer to the AudioStream object. + * The shared_ptr is used internally by Oboe to prevent the stream from being + * deleted while it is being used by callbacks. + * + * @param stream reference to a shared_ptr to receive the stream address + * @return OBOE_OK if successful or a negative error code + */ + Result openStream(std::shared_ptr<oboe::AudioStream> &stream); + + /** + * Create and open a ManagedStream object based on the current builder state. + * + * The caller must create a unique ptr, and pass by reference so it can be + * modified to point to an opened stream. The caller owns the unique ptr, + * and it will be automatically closed and deleted when going out of scope. + * @param stream Reference to the ManagedStream (uniqueptr) used to keep track of stream + * @return OBOE_OK if successful or a negative error code. + */ + Result openManagedStream(ManagedStream &stream); + +private: + + /** + * @param other + * @return true if channels, format and sample rate match + */ + bool isCompatible(AudioStreamBase &other); + + /** + * Create an AudioStream object. The AudioStream must be opened before use. + * + * The caller owns the pointer. + * + * @return pointer to an AudioStream object or nullptr. + */ + oboe::AudioStream *build(); + + AudioApi mAudioApi = AudioApi::Unspecified; +}; + +} // namespace oboe + +#endif /* OBOE_STREAM_BUILDER_H_ */ diff --git a/modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamCallback.h b/modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamCallback.h new file mode 100644 index 00000000..f427693e --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamCallback.h @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBOE_STREAM_CALLBACK_H +#define OBOE_STREAM_CALLBACK_H + +#include "oboe/Definitions.h" + +namespace oboe { + +class AudioStream; + +/** + * AudioStreamCallback defines a callback interface for: + * + * 1) moving data to/from an audio stream using `onAudioReady` + * 2) being alerted when a stream has an error using `onError*` methods + * + */ +class AudioStreamCallback { +public: + virtual ~AudioStreamCallback() = default; + + /** + * A buffer is ready for processing. + * + * For an output stream, this function should render and write numFrames of data + * in the stream's current data format to the audioData buffer. + * + * For an input stream, this function should read and process numFrames of data + * from the audioData buffer. + * + * The audio data is passed through the buffer. So do NOT call read() or + * write() on the stream that is making the callback. + * + * Note that numFrames can vary unless AudioStreamBuilder::setFramesPerCallback() + * is called. + * + * Also note that this callback function should be considered a "real-time" function. + * It must not do anything that could cause an unbounded delay because that can cause the + * audio to glitch or pop. + * + * These are things the function should NOT do: + * <ul> + * <li>allocate memory using, for example, malloc() or new</li> + * <li>any file operations such as opening, closing, reading or writing</li> + * <li>any network operations such as streaming</li> + * <li>use any mutexes or other synchronization primitives</li> + * <li>sleep</li> + * <li>oboeStream->stop(), pause(), flush() or close()</li> + * <li>oboeStream->read()</li> + * <li>oboeStream->write()</li> + * </ul> + * + * The following are OK to call from the data callback: + * <ul> + * <li>oboeStream->get*()</li> + * <li>oboe::convertToText()</li> + * <li>oboeStream->setBufferSizeInFrames()</li> + * </ul> + * + * If you need to move data, eg. MIDI commands, in or out of the callback function then + * we recommend the use of non-blocking techniques such as an atomic FIFO. + * + * @param oboeStream pointer to the associated stream + * @param audioData buffer containing input data or a place to put output data + * @param numFrames number of frames to be processed + * @return DataCallbackResult::Continue or DataCallbackResult::Stop + */ + virtual DataCallbackResult onAudioReady( + AudioStream *oboeStream, + void *audioData, + int32_t numFrames) = 0; + + /** + * This will be called when an error occurs on a stream or when the stream is disconnected. + * + * Note that this will be called on a different thread than the onAudioReady() thread. + * This thread will be created by Oboe. + * + * The underlying stream will already be stopped by Oboe but not yet closed. + * So the stream can be queried. + * + * Do not close or delete the stream in this method because it will be + * closed after this method returns. + * + * @param oboeStream pointer to the associated stream + * @param error + */ + virtual void onErrorBeforeClose(AudioStream* /* oboeStream */, Result /* error */) {} + + /** + * This will be called when an error occurs on a stream or when the stream is disconnected. + * The underlying AAudio or OpenSL ES stream will already be stopped AND closed by Oboe. + * So the underlying stream cannot be referenced. + * But you can still query most parameters. + * + * This callback could be used to reopen a new stream on another device. + * You can safely delete the old AudioStream in this method. + * + * @param oboeStream pointer to the associated stream + * @param error + */ + virtual void onErrorAfterClose(AudioStream* /* oboeStream */, Result /* error */) {} + +}; + +} // namespace oboe + +#endif //OBOE_STREAM_CALLBACK_H diff --git a/modules/juce_audio_devices/native/oboe/include/oboe/Definitions.h b/modules/juce_audio_devices/native/oboe/include/oboe/Definitions.h new file mode 100644 index 00000000..8063a83c --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/include/oboe/Definitions.h @@ -0,0 +1,519 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBOE_DEFINITIONS_H +#define OBOE_DEFINITIONS_H + + +#include <cstdint> +#include <type_traits> + +// Oboe needs to be able to build on old NDKs so we use hard coded constants. +// The correctness of these constants is verified in "aaudio/AAudioLoader.cpp". + +namespace oboe { + + /** + * Represents any attribute, property or value which hasn't been specified. + */ + constexpr int32_t kUnspecified = 0; + + // TODO: Investigate using std::chrono + /** + * The number of nanoseconds in a microsecond. 1,000. + */ + constexpr int64_t kNanosPerMicrosecond = 1000; + + /** + * The number of nanoseconds in a millisecond. 1,000,000. + */ + constexpr int64_t kNanosPerMillisecond = kNanosPerMicrosecond * 1000; + + /** + * The number of milliseconds in a second. 1,000. + */ + constexpr int64_t kMillisPerSecond = 1000; + + /** + * The number of nanoseconds in a second. 1,000,000,000. + */ + constexpr int64_t kNanosPerSecond = kNanosPerMillisecond * kMillisPerSecond; + + /** + * The state of the audio stream. + */ + enum class StreamState : int32_t { // aaudio_stream_state_t + Uninitialized = 0, // AAUDIO_STREAM_STATE_UNINITIALIZED, + Unknown = 1, // AAUDIO_STREAM_STATE_UNKNOWN, + Open = 2, // AAUDIO_STREAM_STATE_OPEN, + Starting = 3, // AAUDIO_STREAM_STATE_STARTING, + Started = 4, // AAUDIO_STREAM_STATE_STARTED, + Pausing = 5, // AAUDIO_STREAM_STATE_PAUSING, + Paused = 6, // AAUDIO_STREAM_STATE_PAUSED, + Flushing = 7, // AAUDIO_STREAM_STATE_FLUSHING, + Flushed = 8, // AAUDIO_STREAM_STATE_FLUSHED, + Stopping = 9, // AAUDIO_STREAM_STATE_STOPPING, + Stopped = 10, // AAUDIO_STREAM_STATE_STOPPED, + Closing = 11, // AAUDIO_STREAM_STATE_CLOSING, + Closed = 12, // AAUDIO_STREAM_STATE_CLOSED, + Disconnected = 13, // AAUDIO_STREAM_STATE_DISCONNECTED, + }; + + /** + * The direction of the stream. + */ + enum class Direction : int32_t { // aaudio_direction_t + + /** + * Used for playback. + */ + Output = 0, // AAUDIO_DIRECTION_OUTPUT, + + /** + * Used for recording. + */ + Input = 1, // AAUDIO_DIRECTION_INPUT, + }; + + /** + * The format of audio samples. + */ + enum class AudioFormat : int32_t { // aaudio_format_t + /** + * Invalid format. + */ + Invalid = -1, // AAUDIO_FORMAT_INVALID, + + /** + * Unspecified format. Format will be decided by Oboe. + */ + Unspecified = 0, // AAUDIO_FORMAT_UNSPECIFIED, + + /** + * Signed 16-bit integers. + */ + I16 = 1, // AAUDIO_FORMAT_PCM_I16, + + /** + * Single precision floating points. + */ + Float = 2, // AAUDIO_FORMAT_PCM_FLOAT, + }; + + /** + * The result of an audio callback. + */ + enum class DataCallbackResult : int32_t { // aaudio_data_callback_result_t + // Indicates to the caller that the callbacks should continue. + Continue = 0, // AAUDIO_CALLBACK_RESULT_CONTINUE, + + // Indicates to the caller that the callbacks should stop immediately. + Stop = 1, // AAUDIO_CALLBACK_RESULT_STOP, + }; + + /** + * The result of an operation. All except the `OK` result indicates that an error occurred. + * The `Result` can be converted into a human readable string using `convertToText`. + */ + enum class Result : int32_t { // aaudio_result_t + OK = 0, // AAUDIO_OK + ErrorBase = -900, // AAUDIO_ERROR_BASE, + ErrorDisconnected = -899, // AAUDIO_ERROR_DISCONNECTED, + ErrorIllegalArgument = -898, // AAUDIO_ERROR_ILLEGAL_ARGUMENT, + ErrorInternal = -896, // AAUDIO_ERROR_INTERNAL, + ErrorInvalidState = -895, // AAUDIO_ERROR_INVALID_STATE, + ErrorInvalidHandle = -892, // AAUDIO_ERROR_INVALID_HANDLE, + ErrorUnimplemented = -890, // AAUDIO_ERROR_UNIMPLEMENTED, + ErrorUnavailable = -889, // AAUDIO_ERROR_UNAVAILABLE, + ErrorNoFreeHandles = -888, // AAUDIO_ERROR_NO_FREE_HANDLES, + ErrorNoMemory = -887, // AAUDIO_ERROR_NO_MEMORY, + ErrorNull = -886, // AAUDIO_ERROR_NULL, + ErrorTimeout = -885, // AAUDIO_ERROR_TIMEOUT, + ErrorWouldBlock = -884, // AAUDIO_ERROR_WOULD_BLOCK, + ErrorInvalidFormat = -883, // AAUDIO_ERROR_INVALID_FORMAT, + ErrorOutOfRange = -882, // AAUDIO_ERROR_OUT_OF_RANGE, + ErrorNoService = -881, // AAUDIO_ERROR_NO_SERVICE, + ErrorInvalidRate = -880, // AAUDIO_ERROR_INVALID_RATE, + // Reserved for future AAudio result types + Reserved1, + Reserved2, + Reserved3, + Reserved4, + Reserved5, + Reserved6, + Reserved7, + Reserved8, + Reserved9, + Reserved10, + ErrorClosed, + }; + + /** + * The sharing mode of the audio stream. + */ + enum class SharingMode : int32_t { // aaudio_sharing_mode_t + + /** + * This will be the only stream using a particular source or sink. + * This mode will provide the lowest possible latency. + * You should close EXCLUSIVE streams immediately when you are not using them. + * + * If you do not need the lowest possible latency then we recommend using Shared, + * which is the default. + */ + Exclusive = 0, // AAUDIO_SHARING_MODE_EXCLUSIVE, + + /** + * Multiple applications can share the same device. + * The data from output streams will be mixed by the audio service. + * The data for input streams will be distributed by the audio service. + * + * This will have higher latency than the EXCLUSIVE mode. + */ + Shared = 1, // AAUDIO_SHARING_MODE_SHARED, + }; + + /** + * The performance mode of the audio stream. + */ + enum class PerformanceMode : int32_t { // aaudio_performance_mode_t + + /** + * No particular performance needs. Default. + */ + None = 10, // AAUDIO_PERFORMANCE_MODE_NONE, + + /** + * Extending battery life is most important. + */ + PowerSaving = 11, // AAUDIO_PERFORMANCE_MODE_POWER_SAVING, + + /** + * Reducing latency is most important. + */ + LowLatency = 12, // AAUDIO_PERFORMANCE_MODE_LOW_LATENCY + }; + + /** + * The underlying audio API used by the audio stream. + */ + enum class AudioApi : int32_t { + /** + * Try to use AAudio. If not available then use OpenSL ES. + */ + Unspecified = kUnspecified, + + /** + * Use OpenSL ES. + */ + OpenSLES, + + /** + * Try to use AAudio. Fail if unavailable. + */ + AAudio + }; + + /** + * Specifies the quality of the sample rate conversion performed by Oboe. + * Higher quality will require more CPU load. + * Higher quality conversion will probably be implemented using a sinc based resampler. + */ + enum class SampleRateConversionQuality : int32_t { + /** + * No conversion by Oboe. Underlying APIs may still do conversion. + */ + None, + /** + * Fastest conversion but may not sound great. + * This may be implemented using bilinear interpolation. + */ + Fastest, + Low, + Medium, + High, + /** + * Highest quality conversion, which may be expensive in terms of CPU. + */ + Best, + }; + + /** + * The Usage attribute expresses *why* you are playing a sound, what is this sound used for. + * This information is used by certain platforms or routing policies + * to make more refined volume or routing decisions. + * + * Note that these match the equivalent values in AudioAttributes in the Android Java API. + * + * This attribute only has an effect on Android API 28+. + */ + enum class Usage : int32_t { // aaudio_usage_t + /** + * Use this for streaming media, music performance, video, podcasts, etcetera. + */ + Media = 1, // AAUDIO_USAGE_MEDIA + + /** + * Use this for voice over IP, telephony, etcetera. + */ + VoiceCommunication = 2, // AAUDIO_USAGE_VOICE_COMMUNICATION + + /** + * Use this for sounds associated with telephony such as busy tones, DTMF, etcetera. + */ + VoiceCommunicationSignalling = 3, // AAUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING + + /** + * Use this to demand the users attention. + */ + Alarm = 4, // AAUDIO_USAGE_ALARM + + /** + * Use this for notifying the user when a message has arrived or some + * other background event has occured. + */ + Notification = 5, // AAUDIO_USAGE_NOTIFICATION + + /** + * Use this when the phone rings. + */ + NotificationRingtone = 6, // AAUDIO_USAGE_NOTIFICATION_RINGTONE + + /** + * Use this to attract the users attention when, for example, the battery is low. + */ + NotificationEvent = 10, // AAUDIO_USAGE_NOTIFICATION_EVENT + + /** + * Use this for screen readers, etcetera. + */ + AssistanceAccessibility = 11, // AAUDIO_USAGE_ASSISTANCE_ACCESSIBILITY + + /** + * Use this for driving or navigation directions. + */ + AssistanceNavigationGuidance = 12, // AAUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE + + /** + * Use this for user interface sounds, beeps, etcetera. + */ + AssistanceSonification = 13, // AAUDIO_USAGE_ASSISTANCE_SONIFICATION + + /** + * Use this for game audio and sound effects. + */ + Game = 14, // AAUDIO_USAGE_GAME + + /** + * Use this for audio responses to user queries, audio instructions or help utterances. + */ + Assistant = 16, // AAUDIO_USAGE_ASSISTANT + }; + + + /** + * The ContentType attribute describes *what* you are playing. + * It expresses the general category of the content. This information is optional. + * But in case it is known (for instance {@link Movie} for a + * movie streaming service or {@link Speech} for + * an audio book application) this information might be used by the audio framework to + * enforce audio focus. + * + * Note that these match the equivalent values in AudioAttributes in the Android Java API. + * + * This attribute only has an effect on Android API 28+. + */ + enum ContentType : int32_t { // aaudio_content_type_t + + /** + * Use this for spoken voice, audio books, etcetera. + */ + Speech = 1, // AAUDIO_CONTENT_TYPE_SPEECH + + /** + * Use this for pre-recorded or live music. + */ + Music = 2, // AAUDIO_CONTENT_TYPE_MUSIC + + /** + * Use this for a movie or video soundtrack. + */ + Movie = 3, // AAUDIO_CONTENT_TYPE_MOVIE + + /** + * Use this for sound is designed to accompany a user action, + * such as a click or beep sound made when the user presses a button. + */ + Sonification = 4, // AAUDIO_CONTENT_TYPE_SONIFICATION + }; + + /** + * Defines the audio source. + * An audio source defines both a default physical source of audio signal, and a recording + * configuration. + * + * Note that these match the equivalent values in MediaRecorder.AudioSource in the Android Java API. + * + * This attribute only has an effect on Android API 28+. + */ + enum InputPreset : int32_t { // aaudio_input_preset_t + /** + * Use this preset when other presets do not apply. + */ + Generic = 1, // AAUDIO_INPUT_PRESET_GENERIC + + /** + * Use this preset when recording video. + */ + Camcorder = 5, // AAUDIO_INPUT_PRESET_CAMCORDER + + /** + * Use this preset when doing speech recognition. + */ + VoiceRecognition = 6, // AAUDIO_INPUT_PRESET_VOICE_RECOGNITION + + /** + * Use this preset when doing telephony or voice messaging. + */ + VoiceCommunication = 7, // AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION + + /** + * Use this preset to obtain an input with no effects. + * Note that this input will not have automatic gain control + * so the recorded volume may be very low. + */ + Unprocessed = 9, // AAUDIO_INPUT_PRESET_UNPROCESSED + + /** + * Use this preset for capturing audio meant to be processed in real time + * and played back for live performance (e.g karaoke). + * The capture path will minimize latency and coupling with playback path. + */ + VoicePerformance = 10, // AAUDIO_INPUT_PRESET_VOICE_PERFORMANCE + + }; + + /** + * This attribute can be used to allocate a session ID to the audio stream. + * + * This attribute only has an effect on Android API 28+. + */ + enum SessionId { + /** + * Do not allocate a session ID. + * Effects cannot be used with this stream. + * Default. + */ + None = -1, // AAUDIO_SESSION_ID_NONE + + /** + * Allocate a session ID that can be used to attach and control + * effects using the Java AudioEffects API. + * Note that the use of this flag may result in higher latency. + * + * Note that this matches the value of AudioManager.AUDIO_SESSION_ID_GENERATE. + */ + Allocate = 0, // AAUDIO_SESSION_ID_ALLOCATE + }; + + /** + * The channel count of the audio stream. The underlying type is `int32_t`. + * Use of this enum is convenient to avoid "magic" + * numbers when specifying the channel count. + * + * For example, you can write + * `builder.setChannelCount(ChannelCount::Stereo)` + * rather than `builder.setChannelCount(2)` + * + */ + enum ChannelCount : int32_t { + /** + * Audio channel count definition, use Mono or Stereo + */ + Unspecified = kUnspecified, + + /** + * Use this for mono audio + */ + Mono = 1, + + /** + * Use this for stereo audio. + */ + Stereo = 2, + }; + + /** + * On API 16 to 26 OpenSL ES will be used. When using OpenSL ES the optimal values for sampleRate and + * framesPerBurst are not known by the native code. + * On API 17+ these values should be obtained from the AudioManager using this code: + * + * <pre><code> + * // Note that this technique only works for built-in speakers and headphones. + * AudioManager myAudioMgr = (AudioManager) getSystemService(Context.AUDIO_SERVICE); + * String sampleRateStr = myAudioMgr.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE); + * int defaultSampleRate = Integer.parseInt(sampleRateStr); + * String framesPerBurstStr = myAudioMgr.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER); + * int defaultFramesPerBurst = Integer.parseInt(framesPerBurstStr); + * </code></pre> + * + * It can then be passed down to Oboe through JNI. + * + * AAudio will get the optimal framesPerBurst from the HAL and will ignore this value. + */ + class DefaultStreamValues { + + public: + + /** The default sample rate to use when opening new audio streams */ + static int32_t SampleRate; + /** The default frames per burst to use when opening new audio streams */ + static int32_t FramesPerBurst; + /** The default channel count to use when opening new audio streams */ + static int32_t ChannelCount; + + }; + + /** + * The time at which the frame at `position` was presented + */ + struct FrameTimestamp { + int64_t position; // in frames + int64_t timestamp; // in nanoseconds + }; + + class OboeGlobals { + public: + + static bool areWorkaroundsEnabled() { + return mWorkaroundsEnabled; + } + + /** + * Disable this when writing tests to reproduce bugs in AAudio or OpenSL ES + * that have workarounds in Oboe. + * @param enabled + */ + static void setWorkaroundsEnabled(bool enabled) { + mWorkaroundsEnabled = enabled; + } + + private: + static bool mWorkaroundsEnabled; + }; +} // namespace oboe + +#endif // OBOE_DEFINITIONS_H diff --git a/modules/juce_audio_devices/native/oboe/include/oboe/LatencyTuner.h b/modules/juce_audio_devices/native/oboe/include/oboe/LatencyTuner.h new file mode 100644 index 00000000..df472f56 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/include/oboe/LatencyTuner.h @@ -0,0 +1,118 @@ +/* + * Copyright 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBOE_LATENCY_TUNER_ +#define OBOE_LATENCY_TUNER_ + +#include <atomic> +#include <cstdint> +#include "oboe/Definitions.h" +#include "oboe/AudioStream.h" + +namespace oboe { + +/** + * LatencyTuner can be used to dynamically tune the latency of an output stream. + * It adjusts the stream's bufferSize by monitoring the number of underruns. + * + * This only affects the latency associated with the first level of buffering that is closest + * to the application. It does not affect low latency in the HAL, or touch latency in the UI. + * + * Call tune() right before returning from your data callback function if using callbacks. + * Call tune() right before calling write() if using blocking writes. + * + * If you want to see the ongoing results of this tuning process then call + * stream->getBufferSize() periodically. + * + */ +class LatencyTuner { +public: + + /** + * Construct a new LatencyTuner object which will act on the given audio stream + * + * @param stream the stream who's latency will be tuned + */ + explicit LatencyTuner(AudioStream &stream); + + /** + * Construct a new LatencyTuner object which will act on the given audio stream. + * + * @param stream the stream who's latency will be tuned + * @param the maximum buffer size which the tune() operation will set the buffer size to + */ + explicit LatencyTuner(AudioStream &stream, int32_t maximumBufferSize); + + /** + * Adjust the bufferSizeInFrames to optimize latency. + * It will start with a low latency and then raise it if an underrun occurs. + * + * Latency tuning is only supported for AAudio. + * + * @return OK or negative error, ErrorUnimplemented for OpenSL ES + */ + Result tune(); + + /** + * This may be called from another thread. Then tune() will call reset(), + * which will lower the latency to the minimum and then allow it to rise back up + * if there are glitches. + * + * This is typically called in response to a user decision to minimize latency. In other words, + * call this from a button handler. + */ + void requestReset(); + + /** + * @return true if the audio stream's buffer size is at the maximum value. If no maximum value + * was specified when constructing the LatencyTuner then the value of + * stream->getBufferCapacityInFrames is used + */ + bool isAtMaximumBufferSize(); + + +private: + + /** + * Drop the latency down to the minimum and then let it rise back up. + * This is useful if a glitch caused the latency to increase and it hasn't gone back down. + * + * This should only be called in the same thread as tune(). + */ + void reset(); + + enum class State { + Idle, + Active, + AtMax, + Unsupported + } ; + + // arbitrary number of calls to wait before bumping up the latency + static constexpr int32_t kIdleCount = 8; + + AudioStream &mStream; + State mState = State::Idle; + int32_t mMaxBufferSize = 0; + int32_t mPreviousXRuns = 0; + int32_t mIdleCountDown = 0; + std::atomic<int32_t> mLatencyTriggerRequests{0}; // TODO user atomic requester from AAudio + std::atomic<int32_t> mLatencyTriggerResponses{0}; +}; + +} // namespace oboe + +#endif // OBOE_LATENCY_TUNER_ diff --git a/modules/juce_audio_devices/native/oboe/include/oboe/Oboe.h b/modules/juce_audio_devices/native/oboe/include/oboe/Oboe.h new file mode 100644 index 00000000..c3a0bcab --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/include/oboe/Oboe.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBOE_OBOE_H +#define OBOE_OBOE_H + +/** + * \mainpage API reference + * + * All documentation is found in the <a href="namespaceoboe.html">oboe namespace section</a> + * + */ + +#include "oboe/Definitions.h" +#include "oboe/ResultWithValue.h" +#include "oboe/LatencyTuner.h" +#include "oboe/AudioStream.h" +#include "oboe/AudioStreamBase.h" +#include "oboe/AudioStreamBuilder.h" +#include "oboe/Utilities.h" +#include "oboe/Version.h" +#include "oboe/StabilizedCallback.h" + +#endif //OBOE_OBOE_H diff --git a/modules/juce_audio_devices/native/oboe/include/oboe/ResultWithValue.h b/modules/juce_audio_devices/native/oboe/include/oboe/ResultWithValue.h new file mode 100644 index 00000000..fcb1fac1 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/include/oboe/ResultWithValue.h @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBOE_RESULT_WITH_VALUE_H +#define OBOE_RESULT_WITH_VALUE_H + +#include "oboe/Definitions.h" +#include <iostream> +#include <sstream> + +namespace oboe { + +/** + * A ResultWithValue can store both the result of an operation (either OK or an error) and a value. + * + * It has been designed for cases where the caller needs to know whether an operation succeeded and, + * if it did, a value which was obtained during the operation. + * + * For example, when reading from a stream the caller needs to know the result of the read operation + * and, if it was successful, how many frames were read. Note that ResultWithValue can be evaluated + * as a boolean so it's simple to check whether the result is OK. + * + * <code> + * ResultWithValue<int32_t> resultOfRead = myStream.read(&buffer, numFrames, timeoutNanoseconds); + * + * if (resultOfRead) { + * LOGD("Frames read: %d", resultOfRead.value()); + * } else { + * LOGD("Error reading from stream: %s", resultOfRead.error()); + * } + * </code> + */ +template <typename T> +class ResultWithValue { +public: + + /** + * Construct a ResultWithValue containing an error result. + * + * @param error The error + */ + ResultWithValue(oboe::Result error) + : mValue{} + , mError(error) {} + + /** + * Construct a ResultWithValue containing an OK result and a value. + * + * @param value the value to store + */ + explicit ResultWithValue(T value) + : mValue(value) + , mError(oboe::Result::OK) {} + + /** + * Get the result. + * + * @return the result + */ + oboe::Result error() const { + return mError; + } + + /** + * Get the value + * @return + */ + T value() const { + return mValue; + } + + /** + * @return true if OK + */ + explicit operator bool() const { return mError == oboe::Result::OK; } + + /** + * Quick way to check for an error. + * + * The caller could write something like this: + * <code> + * if (!result) { printf("Got error %s\n", convertToText(result.error())); } + * </code> + * + * @return true if an error occurred + */ + bool operator !() const { return mError != oboe::Result::OK; } + + /** + * Implicitly convert to a Result. This enables easy comparison with Result values. Example: + * + * <code> + * ResultWithValue result = openStream(); + * if (result == Result::ErrorNoMemory){ // tell user they're out of memory } + * </code> + */ + operator Result() const { + return mError; + } + + /** + * Create a ResultWithValue from a number. If the number is positive the ResultWithValue will + * have a result of Result::OK and the value will contain the number. If the number is negative + * the result will be obtained from the negative number (numeric error codes can be found in + * AAudio.h) and the value will be null. + * + */ + static ResultWithValue<T> createBasedOnSign(T numericResult){ + + // Ensure that the type is either an integer or float + static_assert(std::is_arithmetic<T>::value, + "createBasedOnSign can only be called for numeric types (int or float)"); + + if (numericResult >= 0){ + return ResultWithValue<T>(numericResult); + } else { + return ResultWithValue<T>(static_cast<Result>(numericResult)); + } + } + +private: + const T mValue; + const oboe::Result mError; +}; + +/** + * If the result is `OK` then return the value, otherwise return a human-readable error message. + */ +template <typename T> +std::ostream& operator<<(std::ostream &strm, const ResultWithValue<T> &result) { + if (!result) { + strm << convertToText(result.error()); + } else { + strm << result.value(); + } + return strm; +} + +} // namespace oboe + + +#endif //OBOE_RESULT_WITH_VALUE_H diff --git a/modules/juce_audio_devices/native/oboe/include/oboe/StabilizedCallback.h b/modules/juce_audio_devices/native/oboe/include/oboe/StabilizedCallback.h new file mode 100644 index 00000000..3f1a6896 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/include/oboe/StabilizedCallback.h @@ -0,0 +1,75 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBOE_STABILIZEDCALLBACK_H +#define OBOE_STABILIZEDCALLBACK_H + +#include <cstdint> +#include "oboe/AudioStream.h" + +namespace oboe { + +class StabilizedCallback : public AudioStreamCallback { + +public: + explicit StabilizedCallback(AudioStreamCallback *callback); + + DataCallbackResult + onAudioReady(AudioStream *oboeStream, void *audioData, int32_t numFrames) override; + + void onErrorBeforeClose(AudioStream *oboeStream, Result error) override { + return mCallback->onErrorBeforeClose(oboeStream, error); + } + + void onErrorAfterClose(AudioStream *oboeStream, Result error) override { + + // Reset all fields now that the stream has been closed + mFrameCount = 0; + mEpochTimeNanos = 0; + mOpsPerNano = 1; + return mCallback->onErrorAfterClose(oboeStream, error); + } + +private: + + AudioStreamCallback *mCallback = nullptr; + int64_t mFrameCount = 0; + int64_t mEpochTimeNanos = 0; + double mOpsPerNano = 1; + + void generateLoad(int64_t durationNanos); +}; + +/** + * cpu_relax is an architecture specific method of telling the CPU that you don't want it to + * do much work. asm volatile keeps the compiler from optimising these instructions out. + */ +#if defined(__i386__) || defined(__x86_64__) +#define cpu_relax() asm volatile("rep; nop" ::: "memory"); + +#elif defined(__arm__) || defined(__mips__) + #define cpu_relax() asm volatile("":::"memory") + +#elif defined(__aarch64__) +#define cpu_relax() asm volatile("yield" ::: "memory") + +#else +#error "cpu_relax is not defined for this architecture" +#endif + +} + +#endif //OBOE_STABILIZEDCALLBACK_H diff --git a/modules/juce_audio_devices/native/oboe/include/oboe/Utilities.h b/modules/juce_audio_devices/native/oboe/include/oboe/Utilities.h new file mode 100644 index 00000000..2c270881 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/include/oboe/Utilities.h @@ -0,0 +1,87 @@ +/* + * Copyright 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBOE_UTILITIES_H +#define OBOE_UTILITIES_H + +#include <unistd.h> +#include <sys/types.h> +#include <string> +#include "oboe/Definitions.h" + +namespace oboe { + +/** + * Convert an array of floats to an array of 16-bit integers. + * + * @param source the input array. + * @param destination the output array. + * @param numSamples the number of values to convert. + */ +void convertFloatToPcm16(const float *source, int16_t *destination, int32_t numSamples); + +/** + * Convert an array of 16-bit integers to an array of floats. + * + * @param source the input array. + * @param destination the output array. + * @param numSamples the number of values to convert. + */ +void convertPcm16ToFloat(const int16_t *source, float *destination, int32_t numSamples); + +/** + * @return the size of a sample of the given format in bytes or 0 if format is invalid + */ +int32_t convertFormatToSizeInBytes(AudioFormat format); + +/** + * The text is the ASCII symbol corresponding to the supplied Oboe enum value, + * or an English message saying the value is unrecognized. + * This is intended for developers to use when debugging. + * It is not for displaying to users. + * + * @param input object to convert from. @see common/Utilities.cpp for concrete implementations + * @return text representation of an Oboe enum value. There is no need to call free on this. + */ +template <typename FromType> +const char * convertToText(FromType input); + +/** + * @param name + * @return the value of a named system property in a string or empty string + */ +std::string getPropertyString(const char * name); + +/** + * @param name + * @param defaultValue + * @return integer value associated with a property or the default value + */ +int getPropertyInteger(const char * name, int defaultValue); + +/** + * Return the version of the SDK that is currently running. + * + * For example, on Android, this would return 27 for Oreo 8.1. + * If the version number cannot be determined then this will return -1. + * + * @return version number or -1 + */ +int getSdkVersion(); + +} // namespace oboe + +#endif //OBOE_UTILITIES_H diff --git a/modules/juce_audio_devices/native/oboe/include/oboe/Version.h b/modules/juce_audio_devices/native/oboe/include/oboe/Version.h new file mode 100644 index 00000000..bdc12e4a --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/include/oboe/Version.h @@ -0,0 +1,92 @@ +/* + * Copyright 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBOE_VERSIONINFO_H +#define OBOE_VERSIONINFO_H + +#include <cstdint> + +/** + * A note on use of preprocessor defines: + * + * This is one of the few times when it's suitable to use preprocessor defines rather than constexpr + * Why? Because C++11 requires a lot of boilerplate code to convert integers into compile-time + * string literals. The preprocessor, despite it's lack of type checking, is more suited to the task + * + * See: https://stackoverflow.com/questions/6713420/c-convert-integer-to-string-at-compile-time/26824971#26824971 + * + */ + +// Type: 8-bit unsigned int. Min value: 0 Max value: 255. See below for description. +#define OBOE_VERSION_MAJOR 1 + +// Type: 8-bit unsigned int. Min value: 0 Max value: 255. See below for description. +#define OBOE_VERSION_MINOR 4 + +// Type: 16-bit unsigned int. Min value: 0 Max value: 65535. See below for description. +#define OBOE_VERSION_PATCH 2 + +#define OBOE_STRINGIFY(x) #x +#define OBOE_TOSTRING(x) OBOE_STRINGIFY(x) + +// Type: String literal. See below for description. +#define OBOE_VERSION_TEXT \ + OBOE_TOSTRING(OBOE_VERSION_MAJOR) "." \ + OBOE_TOSTRING(OBOE_VERSION_MINOR) "." \ + OBOE_TOSTRING(OBOE_VERSION_PATCH) + +// Type: 32-bit unsigned int. See below for description. +#define OBOE_VERSION_NUMBER ((OBOE_VERSION_MAJOR << 24) | (OBOE_VERSION_MINOR << 16) | OBOE_VERSION_PATCH) + +namespace oboe { + +const char * getVersionText(); + +/** + * Oboe versioning object + */ +struct Version { + /** + * This is incremented when we make breaking API changes. Based loosely on https://semver.org/. + */ + static constexpr uint8_t Major = OBOE_VERSION_MAJOR; + + /** + * This is incremented when we add backwards compatible functionality. Or set to zero when MAJOR is + * incremented. + */ + static constexpr uint8_t Minor = OBOE_VERSION_MINOR; + + /** + * This is incremented when we make backwards compatible bug fixes. Or set to zero when MINOR is + * incremented. + */ + static constexpr uint16_t Patch = OBOE_VERSION_PATCH; + + /** + * Version string in the form MAJOR.MINOR.PATCH. + */ + static constexpr const char * Text = OBOE_VERSION_TEXT; + + /** + * Integer representation of the current Oboe library version. This will always increase when the + * version number changes so can be compared using integer comparison. + */ + static constexpr uint32_t Number = OBOE_VERSION_NUMBER; +}; + +} // namespace oboe +#endif //OBOE_VERSIONINFO_H diff --git a/modules/juce_audio_devices/native/oboe/readme.md b/modules/juce_audio_devices/native/oboe/readme.md new file mode 100644 index 00000000..5446d4b8 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/readme.md @@ -0,0 +1,10 @@ +The files in this directory are reproduced from the official Oboe repository, which can be found at +github.com/google/oboe. + +These files are from tag 1.4.2 (55304d7). + +We've included only those parts of the original repository which are required to build the Oboe +library. Documentation, samples, tests, and other non-library items have been omitted. + +Files in this directory and below are licensed under the terms of the license in the LICENSE file +which you can find in the same directory as this readme. diff --git a/modules/juce_audio_devices/native/oboe/src/aaudio/AAudioLoader.cpp b/modules/juce_audio_devices/native/oboe/src/aaudio/AAudioLoader.cpp new file mode 100644 index 00000000..064633c6 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/aaudio/AAudioLoader.cpp @@ -0,0 +1,348 @@ +/* + * Copyright 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <dlfcn.h> +#include <oboe/Utilities.h> +#include "common/OboeDebug.h" +#include "AAudioLoader.h" + +#define LIB_AAUDIO_NAME "libaaudio.so" + +namespace oboe { + +AAudioLoader::~AAudioLoader() { + if (mLibHandle != nullptr) { + dlclose(mLibHandle); + mLibHandle = nullptr; + } +} + +AAudioLoader* AAudioLoader::getInstance() { + static AAudioLoader instance; + return &instance; +} + +int AAudioLoader::open() { + if (mLibHandle != nullptr) { + return 0; + } + + // Use RTLD_NOW to avoid the unpredictable behavior that RTLD_LAZY can cause. + // Also resolving all the links now will prevent a run-time penalty later. + mLibHandle = dlopen(LIB_AAUDIO_NAME, RTLD_NOW); + if (mLibHandle == nullptr) { + LOGI("AAudioLoader::open() could not find " LIB_AAUDIO_NAME); + return -1; // TODO review return code + } else { + LOGD("AAudioLoader(): dlopen(%s) returned %p", LIB_AAUDIO_NAME, mLibHandle); + } + + // Load all the function pointers. + createStreamBuilder = load_I_PPB("AAudio_createStreamBuilder"); + builder_openStream = load_I_PBPPS("AAudioStreamBuilder_openStream"); + + builder_setChannelCount = load_V_PBI("AAudioStreamBuilder_setChannelCount"); + if (builder_setChannelCount == nullptr) { + // Use old deprecated alias if needed. + builder_setChannelCount = load_V_PBI("AAudioStreamBuilder_setSamplesPerFrame"); + } + + builder_setBufferCapacityInFrames = load_V_PBI("AAudioStreamBuilder_setBufferCapacityInFrames"); + builder_setDeviceId = load_V_PBI("AAudioStreamBuilder_setDeviceId"); + builder_setDirection = load_V_PBI("AAudioStreamBuilder_setDirection"); + builder_setFormat = load_V_PBI("AAudioStreamBuilder_setFormat"); + builder_setFramesPerDataCallback = load_V_PBI("AAudioStreamBuilder_setFramesPerDataCallback"); + builder_setSharingMode = load_V_PBI("AAudioStreamBuilder_setSharingMode"); + builder_setPerformanceMode = load_V_PBI("AAudioStreamBuilder_setPerformanceMode"); + builder_setSampleRate = load_V_PBI("AAudioStreamBuilder_setSampleRate"); + + if (getSdkVersion() >= __ANDROID_API_P__){ + builder_setUsage = load_V_PBI("AAudioStreamBuilder_setUsage"); + builder_setContentType = load_V_PBI("AAudioStreamBuilder_setContentType"); + builder_setInputPreset = load_V_PBI("AAudioStreamBuilder_setInputPreset"); + builder_setSessionId = load_V_PBI("AAudioStreamBuilder_setSessionId"); + } + + builder_delete = load_I_PB("AAudioStreamBuilder_delete"); + + + builder_setDataCallback = load_V_PBPDPV("AAudioStreamBuilder_setDataCallback"); + builder_setErrorCallback = load_V_PBPEPV("AAudioStreamBuilder_setErrorCallback"); + + stream_read = load_I_PSPVIL("AAudioStream_read"); + + stream_write = load_I_PSCPVIL("AAudioStream_write"); + + stream_waitForStateChange = load_I_PSTPTL("AAudioStream_waitForStateChange"); + + stream_getTimestamp = load_I_PSKPLPL("AAudioStream_getTimestamp"); + + stream_isMMapUsed = load_B_PS("AAudioStream_isMMapUsed"); + + stream_getChannelCount = load_I_PS("AAudioStream_getChannelCount"); + if (stream_getChannelCount == nullptr) { + // Use old alias if needed. + stream_getChannelCount = load_I_PS("AAudioStream_getSamplesPerFrame"); + } + + stream_close = load_I_PS("AAudioStream_close"); + + stream_getBufferSize = load_I_PS("AAudioStream_getBufferSizeInFrames"); + stream_getDeviceId = load_I_PS("AAudioStream_getDeviceId"); + stream_getBufferCapacity = load_I_PS("AAudioStream_getBufferCapacityInFrames"); + stream_getFormat = load_F_PS("AAudioStream_getFormat"); + stream_getFramesPerBurst = load_I_PS("AAudioStream_getFramesPerBurst"); + stream_getFramesRead = load_L_PS("AAudioStream_getFramesRead"); + stream_getFramesWritten = load_L_PS("AAudioStream_getFramesWritten"); + stream_getPerformanceMode = load_I_PS("AAudioStream_getPerformanceMode"); + stream_getSampleRate = load_I_PS("AAudioStream_getSampleRate"); + stream_getSharingMode = load_I_PS("AAudioStream_getSharingMode"); + stream_getState = load_I_PS("AAudioStream_getState"); + stream_getXRunCount = load_I_PS("AAudioStream_getXRunCount"); + + stream_requestStart = load_I_PS("AAudioStream_requestStart"); + stream_requestPause = load_I_PS("AAudioStream_requestPause"); + stream_requestFlush = load_I_PS("AAudioStream_requestFlush"); + stream_requestStop = load_I_PS("AAudioStream_requestStop"); + + stream_setBufferSize = load_I_PSI("AAudioStream_setBufferSizeInFrames"); + + convertResultToText = load_CPH_I("AAudio_convertResultToText"); + + if (getSdkVersion() >= __ANDROID_API_P__){ + stream_getUsage = load_I_PS("AAudioStream_getUsage"); + stream_getContentType = load_I_PS("AAudioStream_getContentType"); + stream_getInputPreset = load_I_PS("AAudioStream_getInputPreset"); + stream_getSessionId = load_I_PS("AAudioStream_getSessionId"); + } + return 0; +} + +static void AAudioLoader_check(void *proc, const char *functionName) { + if (proc == nullptr) { + LOGW("AAudioLoader could not find %s", functionName); + } +} + +AAudioLoader::signature_I_PPB AAudioLoader::load_I_PPB(const char *functionName) { + void *proc = dlsym(mLibHandle, functionName); + AAudioLoader_check(proc, functionName); + return reinterpret_cast<signature_I_PPB>(proc); +} + +AAudioLoader::signature_CPH_I AAudioLoader::load_CPH_I(const char *functionName) { + void *proc = dlsym(mLibHandle, functionName); + AAudioLoader_check(proc, functionName); + return reinterpret_cast<signature_CPH_I>(proc); +} + +AAudioLoader::signature_V_PBI AAudioLoader::load_V_PBI(const char *functionName) { + void *proc = dlsym(mLibHandle, functionName); + AAudioLoader_check(proc, functionName); + return reinterpret_cast<signature_V_PBI>(proc); +} + +AAudioLoader::signature_V_PBPDPV AAudioLoader::load_V_PBPDPV(const char *functionName) { + void *proc = dlsym(mLibHandle, functionName); + AAudioLoader_check(proc, functionName); + return reinterpret_cast<signature_V_PBPDPV>(proc); +} + +AAudioLoader::signature_V_PBPEPV AAudioLoader::load_V_PBPEPV(const char *functionName) { + void *proc = dlsym(mLibHandle, functionName); + AAudioLoader_check(proc, functionName); + return reinterpret_cast<signature_V_PBPEPV>(proc); +} + +AAudioLoader::signature_I_PSI AAudioLoader::load_I_PSI(const char *functionName) { + void *proc = dlsym(mLibHandle, functionName); + AAudioLoader_check(proc, functionName); + return reinterpret_cast<signature_I_PSI>(proc); +} + +AAudioLoader::signature_I_PS AAudioLoader::load_I_PS(const char *functionName) { + void *proc = dlsym(mLibHandle, functionName); + AAudioLoader_check(proc, functionName); + return reinterpret_cast<signature_I_PS>(proc); +} + +AAudioLoader::signature_L_PS AAudioLoader::load_L_PS(const char *functionName) { + void *proc = dlsym(mLibHandle, functionName); + AAudioLoader_check(proc, functionName); + return reinterpret_cast<signature_L_PS>(proc); +} + +AAudioLoader::signature_F_PS AAudioLoader::load_F_PS(const char *functionName) { + void *proc = dlsym(mLibHandle, functionName); + AAudioLoader_check(proc, functionName); + return reinterpret_cast<signature_F_PS>(proc); +} + +AAudioLoader::signature_B_PS AAudioLoader::load_B_PS(const char *functionName) { + void *proc = dlsym(mLibHandle, functionName); + AAudioLoader_check(proc, functionName); + return reinterpret_cast<signature_B_PS>(proc); +} + +AAudioLoader::signature_I_PB AAudioLoader::load_I_PB(const char *functionName) { + void *proc = dlsym(mLibHandle, functionName); + AAudioLoader_check(proc, functionName); + return reinterpret_cast<signature_I_PB>(proc); +} + +AAudioLoader::signature_I_PBPPS AAudioLoader::load_I_PBPPS(const char *functionName) { + void *proc = dlsym(mLibHandle, functionName); + AAudioLoader_check(proc, functionName); + return reinterpret_cast<signature_I_PBPPS>(proc); +} + +AAudioLoader::signature_I_PSCPVIL AAudioLoader::load_I_PSCPVIL(const char *functionName) { + void *proc = dlsym(mLibHandle, functionName); + AAudioLoader_check(proc, functionName); + return reinterpret_cast<signature_I_PSCPVIL>(proc); +} + +AAudioLoader::signature_I_PSPVIL AAudioLoader::load_I_PSPVIL(const char *functionName) { + void *proc = dlsym(mLibHandle, functionName); + AAudioLoader_check(proc, functionName); + return reinterpret_cast<signature_I_PSPVIL>(proc); +} + +AAudioLoader::signature_I_PSTPTL AAudioLoader::load_I_PSTPTL(const char *functionName) { + void *proc = dlsym(mLibHandle, functionName); + AAudioLoader_check(proc, functionName); + return reinterpret_cast<signature_I_PSTPTL>(proc); +} + +AAudioLoader::signature_I_PSKPLPL AAudioLoader::load_I_PSKPLPL(const char *functionName) { + void *proc = dlsym(mLibHandle, functionName); + AAudioLoader_check(proc, functionName); + return reinterpret_cast<signature_I_PSKPLPL>(proc); +} + +// Ensure that all AAudio primitive data types are int32_t +#define ASSERT_INT32(type) static_assert(std::is_same<int32_t, type>::value, \ +#type" must be int32_t") + +#define ERRMSG "Oboe constants must match AAudio constants." + +// These asserts help verify that the Oboe definitions match the equivalent AAudio definitions. +// This code is in this .cpp file so it only gets tested once. +#ifdef AAUDIO_AAUDIO_H + + ASSERT_INT32(aaudio_stream_state_t); + ASSERT_INT32(aaudio_direction_t); + ASSERT_INT32(aaudio_format_t); + ASSERT_INT32(aaudio_data_callback_result_t); + ASSERT_INT32(aaudio_result_t); + ASSERT_INT32(aaudio_sharing_mode_t); + ASSERT_INT32(aaudio_performance_mode_t); + + static_assert((int32_t)StreamState::Uninitialized == AAUDIO_STREAM_STATE_UNINITIALIZED, ERRMSG); + static_assert((int32_t)StreamState::Unknown == AAUDIO_STREAM_STATE_UNKNOWN, ERRMSG); + static_assert((int32_t)StreamState::Open == AAUDIO_STREAM_STATE_OPEN, ERRMSG); + static_assert((int32_t)StreamState::Starting == AAUDIO_STREAM_STATE_STARTING, ERRMSG); + static_assert((int32_t)StreamState::Started == AAUDIO_STREAM_STATE_STARTED, ERRMSG); + static_assert((int32_t)StreamState::Pausing == AAUDIO_STREAM_STATE_PAUSING, ERRMSG); + static_assert((int32_t)StreamState::Paused == AAUDIO_STREAM_STATE_PAUSED, ERRMSG); + static_assert((int32_t)StreamState::Flushing == AAUDIO_STREAM_STATE_FLUSHING, ERRMSG); + static_assert((int32_t)StreamState::Flushed == AAUDIO_STREAM_STATE_FLUSHED, ERRMSG); + static_assert((int32_t)StreamState::Stopping == AAUDIO_STREAM_STATE_STOPPING, ERRMSG); + static_assert((int32_t)StreamState::Stopped == AAUDIO_STREAM_STATE_STOPPED, ERRMSG); + static_assert((int32_t)StreamState::Closing == AAUDIO_STREAM_STATE_CLOSING, ERRMSG); + static_assert((int32_t)StreamState::Closed == AAUDIO_STREAM_STATE_CLOSED, ERRMSG); + static_assert((int32_t)StreamState::Disconnected == AAUDIO_STREAM_STATE_DISCONNECTED, ERRMSG); + + static_assert((int32_t)Direction::Output == AAUDIO_DIRECTION_OUTPUT, ERRMSG); + static_assert((int32_t)Direction::Input == AAUDIO_DIRECTION_INPUT, ERRMSG); + + static_assert((int32_t)AudioFormat::Invalid == AAUDIO_FORMAT_INVALID, ERRMSG); + static_assert((int32_t)AudioFormat::Unspecified == AAUDIO_FORMAT_UNSPECIFIED, ERRMSG); + static_assert((int32_t)AudioFormat::I16 == AAUDIO_FORMAT_PCM_I16, ERRMSG); + static_assert((int32_t)AudioFormat::Float == AAUDIO_FORMAT_PCM_FLOAT, ERRMSG); + + static_assert((int32_t)DataCallbackResult::Continue == AAUDIO_CALLBACK_RESULT_CONTINUE, ERRMSG); + static_assert((int32_t)DataCallbackResult::Stop == AAUDIO_CALLBACK_RESULT_STOP, ERRMSG); + + static_assert((int32_t)Result::OK == AAUDIO_OK, ERRMSG); + static_assert((int32_t)Result::ErrorBase == AAUDIO_ERROR_BASE, ERRMSG); + static_assert((int32_t)Result::ErrorDisconnected == AAUDIO_ERROR_DISCONNECTED, ERRMSG); + static_assert((int32_t)Result::ErrorIllegalArgument == AAUDIO_ERROR_ILLEGAL_ARGUMENT, ERRMSG); + static_assert((int32_t)Result::ErrorInternal == AAUDIO_ERROR_INTERNAL, ERRMSG); + static_assert((int32_t)Result::ErrorInvalidState == AAUDIO_ERROR_INVALID_STATE, ERRMSG); + static_assert((int32_t)Result::ErrorInvalidHandle == AAUDIO_ERROR_INVALID_HANDLE, ERRMSG); + static_assert((int32_t)Result::ErrorUnimplemented == AAUDIO_ERROR_UNIMPLEMENTED, ERRMSG); + static_assert((int32_t)Result::ErrorUnavailable == AAUDIO_ERROR_UNAVAILABLE, ERRMSG); + static_assert((int32_t)Result::ErrorNoFreeHandles == AAUDIO_ERROR_NO_FREE_HANDLES, ERRMSG); + static_assert((int32_t)Result::ErrorNoMemory == AAUDIO_ERROR_NO_MEMORY, ERRMSG); + static_assert((int32_t)Result::ErrorNull == AAUDIO_ERROR_NULL, ERRMSG); + static_assert((int32_t)Result::ErrorTimeout == AAUDIO_ERROR_TIMEOUT, ERRMSG); + static_assert((int32_t)Result::ErrorWouldBlock == AAUDIO_ERROR_WOULD_BLOCK, ERRMSG); + static_assert((int32_t)Result::ErrorInvalidFormat == AAUDIO_ERROR_INVALID_FORMAT, ERRMSG); + static_assert((int32_t)Result::ErrorOutOfRange == AAUDIO_ERROR_OUT_OF_RANGE, ERRMSG); + static_assert((int32_t)Result::ErrorNoService == AAUDIO_ERROR_NO_SERVICE, ERRMSG); + static_assert((int32_t)Result::ErrorInvalidRate == AAUDIO_ERROR_INVALID_RATE, ERRMSG); + + static_assert((int32_t)SharingMode::Exclusive == AAUDIO_SHARING_MODE_EXCLUSIVE, ERRMSG); + static_assert((int32_t)SharingMode::Shared == AAUDIO_SHARING_MODE_SHARED, ERRMSG); + + static_assert((int32_t)PerformanceMode::None == AAUDIO_PERFORMANCE_MODE_NONE, ERRMSG); + static_assert((int32_t)PerformanceMode::PowerSaving + == AAUDIO_PERFORMANCE_MODE_POWER_SAVING, ERRMSG); + static_assert((int32_t)PerformanceMode::LowLatency + == AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, ERRMSG); +#endif + +// The aaudio_ usage, content and input_preset types were added in NDK 17, +// which is the first version to support Android Pie (API 28). +#if __NDK_MAJOR__ >= 17 + + ASSERT_INT32(aaudio_usage_t); + ASSERT_INT32(aaudio_content_type_t); + ASSERT_INT32(aaudio_input_preset_t); + + static_assert((int32_t)Usage::Media == AAUDIO_USAGE_MEDIA, ERRMSG); + static_assert((int32_t)Usage::VoiceCommunication == AAUDIO_USAGE_VOICE_COMMUNICATION, ERRMSG); + static_assert((int32_t)Usage::VoiceCommunicationSignalling + == AAUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING, ERRMSG); + static_assert((int32_t)Usage::Alarm == AAUDIO_USAGE_ALARM, ERRMSG); + static_assert((int32_t)Usage::Notification == AAUDIO_USAGE_NOTIFICATION, ERRMSG); + static_assert((int32_t)Usage::NotificationRingtone == AAUDIO_USAGE_NOTIFICATION_RINGTONE, ERRMSG); + static_assert((int32_t)Usage::NotificationEvent == AAUDIO_USAGE_NOTIFICATION_EVENT, ERRMSG); + static_assert((int32_t)Usage::AssistanceAccessibility == AAUDIO_USAGE_ASSISTANCE_ACCESSIBILITY, ERRMSG); + static_assert((int32_t)Usage::AssistanceNavigationGuidance + == AAUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE, ERRMSG); + static_assert((int32_t)Usage::AssistanceSonification == AAUDIO_USAGE_ASSISTANCE_SONIFICATION, ERRMSG); + static_assert((int32_t)Usage::Game == AAUDIO_USAGE_GAME, ERRMSG); + static_assert((int32_t)Usage::Assistant == AAUDIO_USAGE_ASSISTANT, ERRMSG); + + static_assert((int32_t)ContentType::Speech == AAUDIO_CONTENT_TYPE_SPEECH, ERRMSG); + static_assert((int32_t)ContentType::Music == AAUDIO_CONTENT_TYPE_MUSIC, ERRMSG); + static_assert((int32_t)ContentType::Movie == AAUDIO_CONTENT_TYPE_MOVIE, ERRMSG); + static_assert((int32_t)ContentType::Sonification == AAUDIO_CONTENT_TYPE_SONIFICATION, ERRMSG); + + static_assert((int32_t)InputPreset::Generic == AAUDIO_INPUT_PRESET_GENERIC, ERRMSG); + static_assert((int32_t)InputPreset::Camcorder == AAUDIO_INPUT_PRESET_CAMCORDER, ERRMSG); + static_assert((int32_t)InputPreset::VoiceRecognition == AAUDIO_INPUT_PRESET_VOICE_RECOGNITION, ERRMSG); + static_assert((int32_t)InputPreset::VoiceCommunication + == AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION, ERRMSG); + static_assert((int32_t)InputPreset::Unprocessed == AAUDIO_INPUT_PRESET_UNPROCESSED, ERRMSG); + + static_assert((int32_t)SessionId::None == AAUDIO_SESSION_ID_NONE, ERRMSG); + static_assert((int32_t)SessionId::Allocate == AAUDIO_SESSION_ID_ALLOCATE, ERRMSG); +#endif + +} // namespace oboe diff --git a/modules/juce_audio_devices/native/oboe/src/aaudio/AAudioLoader.h b/modules/juce_audio_devices/native/oboe/src/aaudio/AAudioLoader.h new file mode 100644 index 00000000..6f5bb950 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/aaudio/AAudioLoader.h @@ -0,0 +1,229 @@ +/* + * Copyright 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBOE_AAUDIO_LOADER_H_ +#define OBOE_AAUDIO_LOADER_H_ + +#include <unistd.h> +#include "oboe/Definitions.h" + +// If the NDK is before O then define this in your build +// so that AAudio.h will not be included. +#ifdef OBOE_NO_INCLUDE_AAUDIO + +// Define missing types from AAudio.h +typedef int32_t aaudio_stream_state_t; +typedef int32_t aaudio_direction_t; +typedef int32_t aaudio_format_t; +typedef int32_t aaudio_data_callback_result_t; +typedef int32_t aaudio_result_t; +typedef int32_t aaudio_sharing_mode_t; +typedef int32_t aaudio_performance_mode_t; + +typedef struct AAudioStreamStruct AAudioStream; +typedef struct AAudioStreamBuilderStruct AAudioStreamBuilder; + +typedef aaudio_data_callback_result_t (*AAudioStream_dataCallback)( + AAudioStream *stream, + void *userData, + void *audioData, + int32_t numFrames); + +typedef void (*AAudioStream_errorCallback)( + AAudioStream *stream, + void *userData, + aaudio_result_t error); + +// These were defined in P +typedef int32_t aaudio_usage_t; +typedef int32_t aaudio_content_type_t; +typedef int32_t aaudio_input_preset_t; +typedef int32_t aaudio_session_id_t; +#else +#include <aaudio/AAudio.h> +#include <android/ndk-version.h> +#endif + +#ifndef __NDK_MAJOR__ +#define __NDK_MAJOR__ 0 +#endif + +namespace oboe { + + +/** + * The AAudio API was not available in early versions of Android. + * To avoid linker errors, we dynamically link with the functions by name using dlsym(). + * On older versions this linkage will safely fail. + */ +class AAudioLoader { + public: + // Use signatures for common functions. + // Key to letter abbreviations. + // S = Stream + // B = Builder + // I = int32_t + // L = int64_t + // T = sTate + // K = clocKid_t + // P = Pointer to following data type + // C = Const prefix + // H = cHar + typedef int32_t (*signature_I_PPB)(AAudioStreamBuilder **builder); + + typedef const char * (*signature_CPH_I)(int32_t); + + typedef int32_t (*signature_I_PBPPS)(AAudioStreamBuilder *, + AAudioStream **stream); // AAudioStreamBuilder_open() + + typedef int32_t (*signature_I_PB)(AAudioStreamBuilder *); // AAudioStreamBuilder_delete() + // AAudioStreamBuilder_setSampleRate() + typedef void (*signature_V_PBI)(AAudioStreamBuilder *, int32_t); + + typedef int32_t (*signature_I_PS)(AAudioStream *); // AAudioStream_getSampleRate() + typedef int64_t (*signature_L_PS)(AAudioStream *); // AAudioStream_getFramesRead() + // AAudioStream_setBufferSizeInFrames() + typedef int32_t (*signature_I_PSI)(AAudioStream *, int32_t); + + typedef void (*signature_V_PBPDPV)(AAudioStreamBuilder *, + AAudioStream_dataCallback, + void *); + + typedef void (*signature_V_PBPEPV)(AAudioStreamBuilder *, + AAudioStream_errorCallback, + void *); + + typedef aaudio_format_t (*signature_F_PS)(AAudioStream *stream); + + typedef int32_t (*signature_I_PSPVIL)(AAudioStream *, void *, int32_t, int64_t); + typedef int32_t (*signature_I_PSCPVIL)(AAudioStream *, const void *, int32_t, int64_t); + + typedef int32_t (*signature_I_PSTPTL)(AAudioStream *, + aaudio_stream_state_t, + aaudio_stream_state_t *, + int64_t); + + typedef int32_t (*signature_I_PSKPLPL)(AAudioStream *, clockid_t, int64_t *, int64_t *); + + typedef bool (*signature_B_PS)(AAudioStream *); + + static AAudioLoader* getInstance(); // singleton + + /** + * Open the AAudio shared library and load the function pointers. + * This can be called multiple times. + * It should only be called from one thread. + * + * The destructor will clean up after the open. + * + * @return 0 if successful or negative error. + */ + int open(); + + // Function pointers into the AAudio shared library. + signature_I_PPB createStreamBuilder = nullptr; + + signature_I_PBPPS builder_openStream = nullptr; + + signature_V_PBI builder_setBufferCapacityInFrames = nullptr; + signature_V_PBI builder_setChannelCount = nullptr; + signature_V_PBI builder_setDeviceId = nullptr; + signature_V_PBI builder_setDirection = nullptr; + signature_V_PBI builder_setFormat = nullptr; + signature_V_PBI builder_setFramesPerDataCallback = nullptr; + signature_V_PBI builder_setPerformanceMode = nullptr; + signature_V_PBI builder_setSampleRate = nullptr; + signature_V_PBI builder_setSharingMode = nullptr; + + signature_V_PBI builder_setUsage = nullptr; + signature_V_PBI builder_setContentType = nullptr; + signature_V_PBI builder_setInputPreset = nullptr; + signature_V_PBI builder_setSessionId = nullptr; + + signature_V_PBPDPV builder_setDataCallback = nullptr; + signature_V_PBPEPV builder_setErrorCallback = nullptr; + + signature_I_PB builder_delete = nullptr; + + signature_F_PS stream_getFormat = nullptr; + + signature_I_PSPVIL stream_read = nullptr; + signature_I_PSCPVIL stream_write = nullptr; + + signature_I_PSTPTL stream_waitForStateChange = nullptr; + + signature_I_PSKPLPL stream_getTimestamp = nullptr; + + signature_B_PS stream_isMMapUsed = nullptr; + + signature_I_PS stream_close = nullptr; + + signature_I_PS stream_getChannelCount = nullptr; + signature_I_PS stream_getDeviceId = nullptr; + + signature_I_PS stream_getBufferSize = nullptr; + signature_I_PS stream_getBufferCapacity = nullptr; + signature_I_PS stream_getFramesPerBurst = nullptr; + signature_I_PS stream_getState = nullptr; + signature_I_PS stream_getPerformanceMode = nullptr; + signature_I_PS stream_getSampleRate = nullptr; + signature_I_PS stream_getSharingMode = nullptr; + signature_I_PS stream_getXRunCount = nullptr; + + signature_I_PSI stream_setBufferSize = nullptr; + signature_I_PS stream_requestStart = nullptr; + signature_I_PS stream_requestPause = nullptr; + signature_I_PS stream_requestFlush = nullptr; + signature_I_PS stream_requestStop = nullptr; + + signature_L_PS stream_getFramesRead = nullptr; + signature_L_PS stream_getFramesWritten = nullptr; + + signature_CPH_I convertResultToText = nullptr; + + signature_I_PS stream_getUsage = nullptr; + signature_I_PS stream_getContentType = nullptr; + signature_I_PS stream_getInputPreset = nullptr; + signature_I_PS stream_getSessionId = nullptr; + + private: + AAudioLoader() {} + ~AAudioLoader(); + + // Load function pointers for specific signatures. + signature_I_PPB load_I_PPB(const char *name); + signature_CPH_I load_CPH_I(const char *name); + signature_V_PBI load_V_PBI(const char *name); + signature_V_PBPDPV load_V_PBPDPV(const char *name); + signature_V_PBPEPV load_V_PBPEPV(const char *name); + signature_I_PB load_I_PB(const char *name); + signature_I_PBPPS load_I_PBPPS(const char *name); + signature_I_PS load_I_PS(const char *name); + signature_L_PS load_L_PS(const char *name); + signature_F_PS load_F_PS(const char *name); + signature_B_PS load_B_PS(const char *name); + signature_I_PSI load_I_PSI(const char *name); + signature_I_PSPVIL load_I_PSPVIL(const char *name); + signature_I_PSCPVIL load_I_PSCPVIL(const char *name); + signature_I_PSTPTL load_I_PSTPTL(const char *name); + signature_I_PSKPLPL load_I_PSKPLPL(const char *name); + + void *mLibHandle = nullptr; +}; + +} // namespace oboe + +#endif //OBOE_AAUDIO_LOADER_H_ diff --git a/modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.cpp b/modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.cpp new file mode 100644 index 00000000..52d85b9b --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.cpp @@ -0,0 +1,643 @@ +/* + * Copyright 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <cassert> +#include <stdint.h> +#include <stdlib.h> + +#include "aaudio/AAudioLoader.h" +#include "aaudio/AudioStreamAAudio.h" +#include "common/AudioClock.h" +#include "common/OboeDebug.h" +#include "oboe/Utilities.h" + +#ifdef __ANDROID__ +#include <sys/system_properties.h> +#include <common/QuirksManager.h> + +#endif + +#ifndef OBOE_FIX_FORCE_STARTING_TO_STARTED +// Workaround state problems in AAudio +// TODO Which versions does this occur in? Verify fixed in Q. +#define OBOE_FIX_FORCE_STARTING_TO_STARTED 1 +#endif // OBOE_FIX_FORCE_STARTING_TO_STARTED + +using namespace oboe; +AAudioLoader *AudioStreamAAudio::mLibLoader = nullptr; + +// 'C' wrapper for the data callback method +static aaudio_data_callback_result_t oboe_aaudio_data_callback_proc( + AAudioStream *stream, + void *userData, + void *audioData, + int32_t numFrames) { + + AudioStreamAAudio *oboeStream = reinterpret_cast<AudioStreamAAudio*>(userData); + if (oboeStream != nullptr) { + return static_cast<aaudio_data_callback_result_t>( + oboeStream->callOnAudioReady(stream, audioData, numFrames)); + + } else { + return static_cast<aaudio_data_callback_result_t>(DataCallbackResult::Stop); + } +} + +// This runs in its own thread. +// Only one of these threads will be launched from internalErrorCallback(). +// It calls app error callbacks from a static function in case the stream gets deleted. +static void oboe_aaudio_error_thread_proc(AudioStreamAAudio *oboeStream, + Result error) { + LOGD("%s() - entering >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>", __func__); + oboeStream->requestStop(); + if (oboeStream->getCallback() != nullptr) { + oboeStream->getCallback()->onErrorBeforeClose(oboeStream, error); + } + oboeStream->close(); + if (oboeStream->getCallback() != nullptr) { + // Warning, oboeStream may get deleted by this callback. + oboeStream->getCallback()->onErrorAfterClose(oboeStream, error); + } + LOGD("%s() - exiting <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<", __func__); +} + +// This runs in its own thread. +// Only one of these threads will be launched from internalErrorCallback(). +// Prevents deletion of the stream if the app is using AudioStreamBuilder::openSharedStream() +static void oboe_aaudio_error_thread_proc_shared(std::shared_ptr<AudioStream> sharedStream, + Result error) { + AudioStreamAAudio *oboeStream = reinterpret_cast<AudioStreamAAudio*>(sharedStream.get()); + oboe_aaudio_error_thread_proc(oboeStream, error); +} + +namespace oboe { + +/* + * Create a stream that uses Oboe Audio API. + */ +AudioStreamAAudio::AudioStreamAAudio(const AudioStreamBuilder &builder) + : AudioStream(builder) + , mAAudioStream(nullptr) { + mCallbackThreadEnabled.store(false); + isSupported(); +} + +bool AudioStreamAAudio::isSupported() { + mLibLoader = AAudioLoader::getInstance(); + int openResult = mLibLoader->open(); + return openResult == 0; +} + +// Static 'C' wrapper for the error callback method. +// Launch a thread to handle the error. +// That other thread can safely stop, close and delete the stream. +void AudioStreamAAudio::internalErrorCallback( + AAudioStream *stream, + void *userData, + aaudio_result_t error) { + AudioStreamAAudio *oboeStream = reinterpret_cast<AudioStreamAAudio*>(userData); + + // Prevents deletion of the stream if the app is using AudioStreamBuilder::openSharedStream() + std::shared_ptr<AudioStream> sharedStream = oboeStream->lockWeakThis(); + + // These checks should be enough because we assume that the stream close() + // will join() any active callback threads and will not allow new callbacks. + if (oboeStream->wasErrorCallbackCalled()) { // block extra error callbacks + LOGE("%s() multiple error callbacks called!", __func__); + } else if (stream != oboeStream->getUnderlyingStream()) { + LOGW("%s() stream already closed", __func__); // can happen if there are bugs + } else if (sharedStream) { + // Handle error on a separate thread using shared pointer. + std::thread t(oboe_aaudio_error_thread_proc_shared, sharedStream, + static_cast<Result>(error)); + t.detach(); + } else { + // Handle error on a separate thread. + std::thread t(oboe_aaudio_error_thread_proc, oboeStream, + static_cast<Result>(error)); + t.detach(); + } +} + +void AudioStreamAAudio::logUnsupportedAttributes() { + int sdkVersion = getSdkVersion(); + + // These attributes are not supported pre Android "P" + if (sdkVersion < __ANDROID_API_P__) { + if (mUsage != Usage::Media) { + LOGW("Usage [AudioStreamBuilder::setUsage()] " + "is not supported on AAudio streams running on pre-Android P versions."); + } + + if (mContentType != ContentType::Music) { + LOGW("ContentType [AudioStreamBuilder::setContentType()] " + "is not supported on AAudio streams running on pre-Android P versions."); + } + + if (mSessionId != SessionId::None) { + LOGW("SessionId [AudioStreamBuilder::setSessionId()] " + "is not supported on AAudio streams running on pre-Android P versions."); + } + } +} + +Result AudioStreamAAudio::open() { + Result result = Result::OK; + + if (mAAudioStream != nullptr) { + return Result::ErrorInvalidState; + } + + result = AudioStream::open(); + if (result != Result::OK) { + return result; + } + + AAudioStreamBuilder *aaudioBuilder; + result = static_cast<Result>(mLibLoader->createStreamBuilder(&aaudioBuilder)); + if (result != Result::OK) { + return result; + } + + // Do not set INPUT capacity below 4096 because that prevents us from getting a FAST track + // when using the Legacy data path. + // If the app requests > 4096 then we allow it but we are less likely to get LowLatency. + // See internal bug b/80308183 for more details. + // Fixed in Q but let's still clip the capacity because high input capacity + // does not increase latency. + int32_t capacity = mBufferCapacityInFrames; + constexpr int kCapacityRequiredForFastLegacyTrack = 4096; // matches value in AudioFinger + if (OboeGlobals::areWorkaroundsEnabled() + && mDirection == oboe::Direction::Input + && capacity != oboe::Unspecified + && capacity < kCapacityRequiredForFastLegacyTrack + && mPerformanceMode == oboe::PerformanceMode::LowLatency) { + capacity = kCapacityRequiredForFastLegacyTrack; + LOGD("AudioStreamAAudio.open() capacity changed from %d to %d for lower latency", + static_cast<int>(mBufferCapacityInFrames), capacity); + } + mLibLoader->builder_setBufferCapacityInFrames(aaudioBuilder, capacity); + + mLibLoader->builder_setChannelCount(aaudioBuilder, mChannelCount); + mLibLoader->builder_setDeviceId(aaudioBuilder, mDeviceId); + mLibLoader->builder_setDirection(aaudioBuilder, static_cast<aaudio_direction_t>(mDirection)); + mLibLoader->builder_setFormat(aaudioBuilder, static_cast<aaudio_format_t>(mFormat)); + mLibLoader->builder_setSampleRate(aaudioBuilder, mSampleRate); + mLibLoader->builder_setSharingMode(aaudioBuilder, + static_cast<aaudio_sharing_mode_t>(mSharingMode)); + mLibLoader->builder_setPerformanceMode(aaudioBuilder, + static_cast<aaudio_performance_mode_t>(mPerformanceMode)); + + // These were added in P so we have to check for the function pointer. + if (mLibLoader->builder_setUsage != nullptr) { + mLibLoader->builder_setUsage(aaudioBuilder, + static_cast<aaudio_usage_t>(mUsage)); + } + + if (mLibLoader->builder_setContentType != nullptr) { + mLibLoader->builder_setContentType(aaudioBuilder, + static_cast<aaudio_content_type_t>(mContentType)); + } + + if (mLibLoader->builder_setInputPreset != nullptr) { + mLibLoader->builder_setInputPreset(aaudioBuilder, + static_cast<aaudio_input_preset_t>(mInputPreset)); + } + + if (mLibLoader->builder_setSessionId != nullptr) { + mLibLoader->builder_setSessionId(aaudioBuilder, + static_cast<aaudio_session_id_t>(mSessionId)); + } + + // TODO get more parameters from the builder? + + if (mStreamCallback != nullptr) { + mLibLoader->builder_setDataCallback(aaudioBuilder, oboe_aaudio_data_callback_proc, this); + mLibLoader->builder_setFramesPerDataCallback(aaudioBuilder, getFramesPerCallback()); + // If the data callback is not being used then the write method will return an error + // and the app can stop and close the stream. + mLibLoader->builder_setErrorCallback(aaudioBuilder, internalErrorCallback, this); + } + + // ============= OPEN THE STREAM ================ + { + AAudioStream *stream = nullptr; + result = static_cast<Result>(mLibLoader->builder_openStream(aaudioBuilder, &stream)); + mAAudioStream.store(stream); + } + if (result != Result::OK) { + goto error2; + } + + // Query and cache the stream properties + mDeviceId = mLibLoader->stream_getDeviceId(mAAudioStream); + mChannelCount = mLibLoader->stream_getChannelCount(mAAudioStream); + mSampleRate = mLibLoader->stream_getSampleRate(mAAudioStream); + mFormat = static_cast<AudioFormat>(mLibLoader->stream_getFormat(mAAudioStream)); + mSharingMode = static_cast<SharingMode>(mLibLoader->stream_getSharingMode(mAAudioStream)); + mPerformanceMode = static_cast<PerformanceMode>( + mLibLoader->stream_getPerformanceMode(mAAudioStream)); + mBufferCapacityInFrames = mLibLoader->stream_getBufferCapacity(mAAudioStream); + mBufferSizeInFrames = mLibLoader->stream_getBufferSize(mAAudioStream); + + + // These were added in P so we have to check for the function pointer. + if (mLibLoader->stream_getUsage != nullptr) { + mUsage = static_cast<Usage>(mLibLoader->stream_getUsage(mAAudioStream)); + } + if (mLibLoader->stream_getContentType != nullptr) { + mContentType = static_cast<ContentType>(mLibLoader->stream_getContentType(mAAudioStream)); + } + if (mLibLoader->stream_getInputPreset != nullptr) { + mInputPreset = static_cast<InputPreset>(mLibLoader->stream_getInputPreset(mAAudioStream)); + } + if (mLibLoader->stream_getSessionId != nullptr) { + mSessionId = static_cast<SessionId>(mLibLoader->stream_getSessionId(mAAudioStream)); + } else { + mSessionId = SessionId::None; + } + + LOGD("AudioStreamAAudio.open() format=%d, sampleRate=%d, capacity = %d", + static_cast<int>(mFormat), static_cast<int>(mSampleRate), + static_cast<int>(mBufferCapacityInFrames)); + +error2: + mLibLoader->builder_delete(aaudioBuilder); + LOGD("AudioStreamAAudio.open: AAudioStream_Open() returned %s", + mLibLoader->convertResultToText(static_cast<aaudio_result_t>(result))); + return result; +} + +Result AudioStreamAAudio::close() { + // The main reason we have this mutex if to prevent a collision between a call + // by the application to stop a stream at the same time that an onError callback + // is being executed because of a disconnect. The close will delete the stream, + // which could otherwise cause the requestStop() to crash. + std::lock_guard<std::mutex> lock(mLock); + + AudioStream::close(); + + // This will delete the AAudio stream object so we need to null out the pointer. + AAudioStream *stream = mAAudioStream.exchange(nullptr); + if (stream != nullptr) { + return static_cast<Result>(mLibLoader->stream_close(stream)); + } else { + return Result::ErrorClosed; + } +} + +DataCallbackResult AudioStreamAAudio::callOnAudioReady(AAudioStream *stream, + void *audioData, + int32_t numFrames) { + DataCallbackResult result = fireDataCallback(audioData, numFrames); + if (result == DataCallbackResult::Continue) { + return result; + } else { + if (result == DataCallbackResult::Stop) { + LOGD("Oboe callback returned DataCallbackResult::Stop"); + } else { + LOGE("Oboe callback returned unexpected value = %d", result); + } + + if (getSdkVersion() <= __ANDROID_API_P__) { + launchStopThread(); + if (isMMapUsed()) { + return DataCallbackResult::Stop; + } else { + // Legacy stream <= API_P cannot be restarted after returning Stop. + return DataCallbackResult::Continue; + } + } else { + return DataCallbackResult::Stop; // OK >= API_Q + } + } +} + +Result AudioStreamAAudio::requestStart() { + std::lock_guard<std::mutex> lock(mLock); + AAudioStream *stream = mAAudioStream.load(); + if (stream != nullptr) { + // Avoid state machine errors in O_MR1. + if (getSdkVersion() <= __ANDROID_API_O_MR1__) { + StreamState state = static_cast<StreamState>(mLibLoader->stream_getState(stream)); + if (state == StreamState::Starting || state == StreamState::Started) { + // WARNING: On P, AAudio is returning ErrorInvalidState for Output and OK for Input. + return Result::OK; + } + } + if (mStreamCallback != nullptr) { // Was a callback requested? + setDataCallbackEnabled(true); + } + return static_cast<Result>(mLibLoader->stream_requestStart(stream)); + } else { + return Result::ErrorClosed; + } +} + +Result AudioStreamAAudio::requestPause() { + std::lock_guard<std::mutex> lock(mLock); + AAudioStream *stream = mAAudioStream.load(); + if (stream != nullptr) { + // Avoid state machine errors in O_MR1. + if (getSdkVersion() <= __ANDROID_API_O_MR1__) { + StreamState state = static_cast<StreamState>(mLibLoader->stream_getState(stream)); + if (state == StreamState::Pausing || state == StreamState::Paused) { + return Result::OK; + } + } + return static_cast<Result>(mLibLoader->stream_requestPause(stream)); + } else { + return Result::ErrorClosed; + } +} + +Result AudioStreamAAudio::requestFlush() { + std::lock_guard<std::mutex> lock(mLock); + AAudioStream *stream = mAAudioStream.load(); + if (stream != nullptr) { + // Avoid state machine errors in O_MR1. + if (getSdkVersion() <= __ANDROID_API_O_MR1__) { + StreamState state = static_cast<StreamState>(mLibLoader->stream_getState(stream)); + if (state == StreamState::Flushing || state == StreamState::Flushed) { + return Result::OK; + } + } + return static_cast<Result>(mLibLoader->stream_requestFlush(stream)); + } else { + return Result::ErrorClosed; + } +} + +Result AudioStreamAAudio::requestStop() { + std::lock_guard<std::mutex> lock(mLock); + AAudioStream *stream = mAAudioStream.load(); + if (stream != nullptr) { + // Avoid state machine errors in O_MR1. + if (getSdkVersion() <= __ANDROID_API_O_MR1__) { + StreamState state = static_cast<StreamState>(mLibLoader->stream_getState(stream)); + if (state == StreamState::Stopping || state == StreamState::Stopped) { + return Result::OK; + } + } + return static_cast<Result>(mLibLoader->stream_requestStop(stream)); + } else { + return Result::ErrorClosed; + } +} + +ResultWithValue<int32_t> AudioStreamAAudio::write(const void *buffer, + int32_t numFrames, + int64_t timeoutNanoseconds) { + AAudioStream *stream = mAAudioStream.load(); + if (stream != nullptr) { + int32_t result = mLibLoader->stream_write(mAAudioStream, buffer, + numFrames, timeoutNanoseconds); + return ResultWithValue<int32_t>::createBasedOnSign(result); + } else { + return ResultWithValue<int32_t>(Result::ErrorClosed); + } +} + +ResultWithValue<int32_t> AudioStreamAAudio::read(void *buffer, + int32_t numFrames, + int64_t timeoutNanoseconds) { + AAudioStream *stream = mAAudioStream.load(); + if (stream != nullptr) { + int32_t result = mLibLoader->stream_read(mAAudioStream, buffer, + numFrames, timeoutNanoseconds); + return ResultWithValue<int32_t>::createBasedOnSign(result); + } else { + return ResultWithValue<int32_t>(Result::ErrorClosed); + } +} + + +// AAudioStream_waitForStateChange() can crash if it is waiting on a stream and that stream +// is closed from another thread. We do not want to lock the stream for the duration of the call. +// So we call AAudioStream_waitForStateChange() with a timeout of zero so that it will not block. +// Then we can do our own sleep with the lock unlocked. +Result AudioStreamAAudio::waitForStateChange(StreamState currentState, + StreamState *nextState, + int64_t timeoutNanoseconds) { + Result oboeResult = Result::ErrorTimeout; + int64_t sleepTimeNanos = 20 * kNanosPerMillisecond; // arbitrary + aaudio_stream_state_t currentAAudioState = static_cast<aaudio_stream_state_t>(currentState); + + aaudio_result_t result = AAUDIO_OK; + int64_t timeLeftNanos = timeoutNanoseconds; + + mLock.lock(); + while (true) { + // Do we still have an AAudio stream? If not then stream must have been closed. + AAudioStream *stream = mAAudioStream.load(); + if (stream == nullptr) { + if (nextState != nullptr) { + *nextState = StreamState::Closed; + } + oboeResult = Result::ErrorClosed; + break; + } + + // Update and query state change with no blocking. + aaudio_stream_state_t aaudioNextState; + result = mLibLoader->stream_waitForStateChange( + mAAudioStream, + currentAAudioState, + &aaudioNextState, + 0); // timeout=0 for non-blocking + // AAudio will return AAUDIO_ERROR_TIMEOUT if timeout=0 and the state does not change. + if (result != AAUDIO_OK && result != AAUDIO_ERROR_TIMEOUT) { + oboeResult = static_cast<Result>(result); + break; + } +#if OBOE_FIX_FORCE_STARTING_TO_STARTED + if (OboeGlobals::areWorkaroundsEnabled() + && aaudioNextState == static_cast<aaudio_stream_state_t >(StreamState::Starting)) { + aaudioNextState = static_cast<aaudio_stream_state_t >(StreamState::Started); + } +#endif // OBOE_FIX_FORCE_STARTING_TO_STARTED + if (nextState != nullptr) { + *nextState = static_cast<StreamState>(aaudioNextState); + } + if (currentAAudioState != aaudioNextState) { // state changed? + oboeResult = Result::OK; + break; + } + + // Did we timeout or did user ask for non-blocking? + if (timeLeftNanos <= 0) { + break; + } + + // No change yet so sleep. + mLock.unlock(); // Don't sleep while locked. + if (sleepTimeNanos > timeLeftNanos) { + sleepTimeNanos = timeLeftNanos; // last little bit + } + AudioClock::sleepForNanos(sleepTimeNanos); + timeLeftNanos -= sleepTimeNanos; + mLock.lock(); + } + + mLock.unlock(); + return oboeResult; +} + +ResultWithValue<int32_t> AudioStreamAAudio::setBufferSizeInFrames(int32_t requestedFrames) { + + AAudioStream *stream = mAAudioStream.load(); + + if (stream != nullptr) { + int32_t adjustedFrames = requestedFrames; + if (adjustedFrames > mBufferCapacityInFrames) { + adjustedFrames = mBufferCapacityInFrames; + } + adjustedFrames = QuirksManager::getInstance().clipBufferSize(*this, adjustedFrames); + + int32_t newBufferSize = mLibLoader->stream_setBufferSize(mAAudioStream, adjustedFrames); + + // Cache the result if it's valid + if (newBufferSize > 0) mBufferSizeInFrames = newBufferSize; + + return ResultWithValue<int32_t>::createBasedOnSign(newBufferSize); + + } else { + return ResultWithValue<int32_t>(Result::ErrorClosed); + } +} + +StreamState AudioStreamAAudio::getState() const { + AAudioStream *stream = mAAudioStream.load(); + if (stream != nullptr) { + aaudio_stream_state_t aaudioState = mLibLoader->stream_getState(stream); +#if OBOE_FIX_FORCE_STARTING_TO_STARTED + if (OboeGlobals::areWorkaroundsEnabled() + && aaudioState == AAUDIO_STREAM_STATE_STARTING) { + aaudioState = AAUDIO_STREAM_STATE_STARTED; + } +#endif // OBOE_FIX_FORCE_STARTING_TO_STARTED + return static_cast<StreamState>(aaudioState); + } else { + return StreamState::Closed; + } +} + +int32_t AudioStreamAAudio::getBufferSizeInFrames() { + AAudioStream *stream = mAAudioStream.load(); + if (stream != nullptr) { + mBufferSizeInFrames = mLibLoader->stream_getBufferSize(stream); + } + return mBufferSizeInFrames; +} + +int32_t AudioStreamAAudio::getFramesPerBurst() { + AAudioStream *stream = mAAudioStream.load(); + if (stream != nullptr) { + mFramesPerBurst = mLibLoader->stream_getFramesPerBurst(stream); + } + return mFramesPerBurst; +} + +void AudioStreamAAudio::updateFramesRead() { + AAudioStream *stream = mAAudioStream.load(); + if (stream != nullptr) { + mFramesRead = mLibLoader->stream_getFramesRead(stream); + } +} + +void AudioStreamAAudio::updateFramesWritten() { + AAudioStream *stream = mAAudioStream.load(); + if (stream != nullptr) { + mFramesWritten = mLibLoader->stream_getFramesWritten(stream); + } +} + +ResultWithValue<int32_t> AudioStreamAAudio::getXRunCount() const { + AAudioStream *stream = mAAudioStream.load(); + if (stream != nullptr) { + return ResultWithValue<int32_t>::createBasedOnSign(mLibLoader->stream_getXRunCount(stream)); + } else { + return ResultWithValue<int32_t>(Result::ErrorNull); + } +} + +Result AudioStreamAAudio::getTimestamp(clockid_t clockId, + int64_t *framePosition, + int64_t *timeNanoseconds) { + AAudioStream *stream = mAAudioStream.load(); + if (stream != nullptr) { + if (getState() != StreamState::Started) { + return Result::ErrorInvalidState; + } + return static_cast<Result>(mLibLoader->stream_getTimestamp(stream, clockId, + framePosition, timeNanoseconds)); + } else { + return Result::ErrorNull; + } +} + +ResultWithValue<double> AudioStreamAAudio::calculateLatencyMillis() { + AAudioStream *stream = mAAudioStream.load(); + if (stream == nullptr) { + return ResultWithValue<double>(Result::ErrorClosed); + } + + // Get the time that a known audio frame was presented. + int64_t hardwareFrameIndex; + int64_t hardwareFrameHardwareTime; + auto result = getTimestamp(CLOCK_MONOTONIC, + &hardwareFrameIndex, + &hardwareFrameHardwareTime); + if (result != oboe::Result::OK) { + return ResultWithValue<double>(static_cast<Result>(result)); + } + + // Get counter closest to the app. + bool isOutput = (getDirection() == oboe::Direction::Output); + int64_t appFrameIndex = isOutput ? getFramesWritten() : getFramesRead(); + + // Assume that the next frame will be processed at the current time + using namespace std::chrono; + int64_t appFrameAppTime = + duration_cast<nanoseconds>(steady_clock::now().time_since_epoch()).count(); + + // Calculate the number of frames between app and hardware + int64_t frameIndexDelta = appFrameIndex - hardwareFrameIndex; + + // Calculate the time which the next frame will be or was presented + int64_t frameTimeDelta = (frameIndexDelta * oboe::kNanosPerSecond) / getSampleRate(); + int64_t appFrameHardwareTime = hardwareFrameHardwareTime + frameTimeDelta; + + // The current latency is the difference in time between when the current frame is at + // the app and when it is at the hardware. + double latencyNanos = static_cast<double>(isOutput + ? (appFrameHardwareTime - appFrameAppTime) // hardware is later + : (appFrameAppTime - appFrameHardwareTime)); // hardware is earlier + double latencyMillis = latencyNanos / kNanosPerMillisecond; + + return ResultWithValue<double>(latencyMillis); +} + +bool AudioStreamAAudio::isMMapUsed() { + AAudioStream *stream = mAAudioStream.load(); + if (stream != nullptr) { + return mLibLoader->stream_isMMapUsed(stream); + } else { + return false; + } +} + +} // namespace oboe diff --git a/modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.h b/modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.h new file mode 100644 index 00000000..6267328b --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.h @@ -0,0 +1,123 @@ +/* + * Copyright 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBOE_STREAM_AAUDIO_H_ +#define OBOE_STREAM_AAUDIO_H_ + +#include <atomic> +#include <mutex> +#include <thread> + +#include "oboe/AudioStreamBuilder.h" +#include "oboe/AudioStream.h" +#include "oboe/Definitions.h" +#include "AAudioLoader.h" + +namespace oboe { + +/** + * Implementation of OboeStream that uses AAudio. + * + * Do not create this class directly. + * Use an OboeStreamBuilder to create one. + */ +class AudioStreamAAudio : public AudioStream { +public: + AudioStreamAAudio(); + explicit AudioStreamAAudio(const AudioStreamBuilder &builder); + + virtual ~AudioStreamAAudio() = default; + + /** + * + * @return true if AAudio is supported on this device. + */ + static bool isSupported(); + + // These functions override methods in AudioStream. + // See AudioStream for documentation. + Result open() override; + Result close() override; + + Result requestStart() override; + Result requestPause() override; + Result requestFlush() override; + Result requestStop() override; + + ResultWithValue<int32_t> write(const void *buffer, + int32_t numFrames, + int64_t timeoutNanoseconds) override; + + ResultWithValue<int32_t> read(void *buffer, + int32_t numFrames, + int64_t timeoutNanoseconds) override; + + ResultWithValue<int32_t> setBufferSizeInFrames(int32_t requestedFrames) override; + int32_t getBufferSizeInFrames() override; + int32_t getFramesPerBurst() override; + ResultWithValue<int32_t> getXRunCount() const override; + bool isXRunCountSupported() const override { return true; } + + ResultWithValue<double> calculateLatencyMillis() override; + + Result waitForStateChange(StreamState currentState, + StreamState *nextState, + int64_t timeoutNanoseconds) override; + + Result getTimestamp(clockid_t clockId, + int64_t *framePosition, + int64_t *timeNanoseconds) override; + + StreamState getState() const override; + + AudioApi getAudioApi() const override { + return AudioApi::AAudio; + } + + DataCallbackResult callOnAudioReady(AAudioStream *stream, + void *audioData, + int32_t numFrames); + + bool isMMapUsed(); + +protected: + static void internalErrorCallback( + AAudioStream *stream, + void *userData, + aaudio_result_t error); + + void *getUnderlyingStream() const override { + return mAAudioStream.load(); + } + + void updateFramesRead() override; + void updateFramesWritten() override; + + void logUnsupportedAttributes(); + +private: + + std::atomic<bool> mCallbackThreadEnabled; + + // pointer to the underlying AAudio stream, valid if open, null if closed + std::atomic<AAudioStream *> mAAudioStream{nullptr}; + + static AAudioLoader *mLibLoader; +}; + +} // namespace oboe + +#endif // OBOE_STREAM_AAUDIO_H_ diff --git a/modules/juce_audio_devices/native/oboe/src/common/AudioClock.h b/modules/juce_audio_devices/native/oboe/src/common/AudioClock.h new file mode 100644 index 00000000..3fe20cb0 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/common/AudioClock.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBOE_AUDIO_CLOCK_H +#define OBOE_AUDIO_CLOCK_H + +#include <sys/types.h> +#include <ctime> +#include "oboe/Definitions.h" + +namespace oboe { + +// TODO: Move this class into the public headers because it is useful when calculating stream latency +class AudioClock { +public: + static int64_t getNanoseconds(clockid_t clockId = CLOCK_MONOTONIC) { + struct timespec time; + int result = clock_gettime(clockId, &time); + if (result < 0) { + return result; + } + return (time.tv_sec * kNanosPerSecond) + time.tv_nsec; + } + + /** + * Sleep until the specified time. + * + * @param nanoTime time to wake up + * @param clockId CLOCK_MONOTONIC is default + * @return 0 or a negative error, eg. -EINTR + */ + + static int sleepUntilNanoTime(int64_t nanoTime, clockid_t clockId = CLOCK_MONOTONIC) { + struct timespec time; + time.tv_sec = nanoTime / kNanosPerSecond; + time.tv_nsec = nanoTime - (time.tv_sec * kNanosPerSecond); + return 0 - clock_nanosleep(clockId, TIMER_ABSTIME, &time, NULL); + } + + /** + * Sleep for the specified number of nanoseconds in real-time. + * Return immediately with 0 if a negative nanoseconds is specified. + * + * @param nanoseconds time to sleep + * @param clockId CLOCK_REALTIME is default + * @return 0 or a negative error, eg. -EINTR + */ + + static int sleepForNanos(int64_t nanoseconds, clockid_t clockId = CLOCK_REALTIME) { + if (nanoseconds > 0) { + struct timespec time; + time.tv_sec = nanoseconds / kNanosPerSecond; + time.tv_nsec = nanoseconds - (time.tv_sec * kNanosPerSecond); + return 0 - clock_nanosleep(clockId, 0, &time, NULL); + } + return 0; + } +}; + +} // namespace oboe + +#endif //OBOE_AUDIO_CLOCK_H diff --git a/modules/juce_audio_devices/native/oboe/src/common/AudioSourceCaller.cpp b/modules/juce_audio_devices/native/oboe/src/common/AudioSourceCaller.cpp new file mode 100644 index 00000000..0180c226 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/common/AudioSourceCaller.cpp @@ -0,0 +1,38 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "AudioSourceCaller.h" + +using namespace oboe; +using namespace flowgraph; + +int32_t AudioSourceCaller::onProcessFixedBlock(uint8_t *buffer, int32_t numBytes) { + oboe::AudioStreamCallback *callback = mStream->getCallback(); + int32_t result = 0; + int32_t numFrames = numBytes / mStream->getBytesPerFrame(); + if (callback != nullptr) { + DataCallbackResult callbackResult = callback->onAudioReady(mStream, buffer, numFrames); + // onAudioReady() does not return the number of bytes processed so we have to assume all. + result = (callbackResult == DataCallbackResult::Continue) + ? numBytes + : -1; + } else { + auto readResult = mStream->read(buffer, numFrames, mTimeoutNanos); + if (!readResult) return (int32_t) readResult.error(); + result = readResult.value() * mStream->getBytesPerFrame(); + } + return result; +} diff --git a/modules/juce_audio_devices/native/oboe/src/common/AudioSourceCaller.h b/modules/juce_audio_devices/native/oboe/src/common/AudioSourceCaller.h new file mode 100644 index 00000000..d196d410 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/common/AudioSourceCaller.h @@ -0,0 +1,83 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBOE_AUDIO_SOURCE_CALLER_H +#define OBOE_AUDIO_SOURCE_CALLER_H + +#include "OboeDebug.h" +#include "oboe/Oboe.h" + +#include "flowgraph/FlowGraphNode.h" +#include "FixedBlockReader.h" + +namespace oboe { + +class AudioStreamCallback; +class AudioStream; + +/** + * For output streams that use a callback, call the application for more data. + * For input streams that do not use a callback, read from the stream. + */ +class AudioSourceCaller : public flowgraph::FlowGraphSource, public FixedBlockProcessor { +public: + AudioSourceCaller(int32_t channelCount, int32_t framesPerCallback, int32_t bytesPerSample) + : FlowGraphSource(channelCount) + , mBlockReader(*this) { + mBlockReader.open(channelCount * framesPerCallback * bytesPerSample); + } + + /** + * Set the stream to use as a source of data. + * @param stream + */ + void setStream(oboe::AudioStream *stream) { + mStream = stream; + } + + oboe::AudioStream *getStream() { + return mStream; + } + + /** + * Timeout value to use when calling audioStream->read(). + * @param timeoutNanos Zero for no timeout or time in nanoseconds. + */ + void setTimeoutNanos(int64_t timeoutNanos) { + mTimeoutNanos = timeoutNanos; + } + + int64_t getTimeoutNanos() const { + return mTimeoutNanos; + } + + /** + * Called internally for block size adaptation. + * @param buffer + * @param numBytes + * @return + */ + int32_t onProcessFixedBlock(uint8_t *buffer, int32_t numBytes) override; + +protected: + oboe::AudioStream *mStream = nullptr; + int64_t mTimeoutNanos = 0; + + FixedBlockReader mBlockReader; +}; + +} +#endif //OBOE_AUDIO_SOURCE_CALLER_H diff --git a/modules/juce_audio_devices/native/oboe/src/common/AudioStream.cpp b/modules/juce_audio_devices/native/oboe/src/common/AudioStream.cpp new file mode 100644 index 00000000..7bcd087c --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/common/AudioStream.cpp @@ -0,0 +1,211 @@ +/* + * Copyright 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <sys/types.h> +#include <pthread.h> +#include <thread> + +#include <oboe/AudioStream.h> +#include "OboeDebug.h" +#include "AudioClock.h" +#include <oboe/Utilities.h> + +namespace oboe { + +/* + * AudioStream + */ +AudioStream::AudioStream(const AudioStreamBuilder &builder) + : AudioStreamBase(builder) { +} + +Result AudioStream::close() { + // Update local counters so they can be read after the close. + updateFramesWritten(); + updateFramesRead(); + return Result::OK; +} + +// Call this from fireDataCallback() if you want to monitor CPU scheduler. +void AudioStream::checkScheduler() { + int scheduler = sched_getscheduler(0) & ~SCHED_RESET_ON_FORK; // for current thread + if (scheduler != mPreviousScheduler) { + LOGD("AudioStream::%s() scheduler = %s", __func__, + ((scheduler == SCHED_FIFO) ? "SCHED_FIFO" : + ((scheduler == SCHED_OTHER) ? "SCHED_OTHER" : + ((scheduler == SCHED_RR) ? "SCHED_RR" : "UNKNOWN"))) + ); + mPreviousScheduler = scheduler; + } +} + +DataCallbackResult AudioStream::fireDataCallback(void *audioData, int32_t numFrames) { + if (!isDataCallbackEnabled()) { + LOGW("AudioStream::%s() called with data callback disabled!", __func__); + return DataCallbackResult::Stop; // We should not be getting called any more. + } + + DataCallbackResult result; + if (mStreamCallback == nullptr) { + result = onDefaultCallback(audioData, numFrames); + } else { + result = mStreamCallback->onAudioReady(this, audioData, numFrames); + } + // On Oreo, we might get called after returning stop. + // So block that here. + setDataCallbackEnabled(result == DataCallbackResult::Continue); + + return result; +} + +Result AudioStream::waitForStateTransition(StreamState startingState, + StreamState endingState, + int64_t timeoutNanoseconds) +{ + StreamState state; + { + std::lock_guard<std::mutex> lock(mLock); + state = getState(); + if (state == StreamState::Closed) { + return Result::ErrorClosed; + } else if (state == StreamState::Disconnected) { + return Result::ErrorDisconnected; + } + } + + StreamState nextState = state; + // TODO Should this be a while()?! + if (state == startingState && state != endingState) { + Result result = waitForStateChange(state, &nextState, timeoutNanoseconds); + if (result != Result::OK) { + return result; + } + } + + if (nextState != endingState) { + return Result::ErrorInvalidState; + } else { + return Result::OK; + } +} + +Result AudioStream::start(int64_t timeoutNanoseconds) +{ + Result result = requestStart(); + if (result != Result::OK) return result; + if (timeoutNanoseconds <= 0) return result; + return waitForStateTransition(StreamState::Starting, + StreamState::Started, timeoutNanoseconds); +} + +Result AudioStream::pause(int64_t timeoutNanoseconds) +{ + Result result = requestPause(); + if (result != Result::OK) return result; + if (timeoutNanoseconds <= 0) return result; + return waitForStateTransition(StreamState::Pausing, + StreamState::Paused, timeoutNanoseconds); +} + +Result AudioStream::flush(int64_t timeoutNanoseconds) +{ + Result result = requestFlush(); + if (result != Result::OK) return result; + if (timeoutNanoseconds <= 0) return result; + return waitForStateTransition(StreamState::Flushing, + StreamState::Flushed, timeoutNanoseconds); +} + +Result AudioStream::stop(int64_t timeoutNanoseconds) +{ + Result result = requestStop(); + if (result != Result::OK) return result; + if (timeoutNanoseconds <= 0) return result; + return waitForStateTransition(StreamState::Stopping, + StreamState::Stopped, timeoutNanoseconds); +} + +int32_t AudioStream::getBytesPerSample() const { + return convertFormatToSizeInBytes(mFormat); +} + +int64_t AudioStream::getFramesRead() { + updateFramesRead(); + return mFramesRead; +} + +int64_t AudioStream::getFramesWritten() { + updateFramesWritten(); + return mFramesWritten; +} + +ResultWithValue<int32_t> AudioStream::getAvailableFrames() { + int64_t readCounter = getFramesRead(); + if (readCounter < 0) return ResultWithValue<int32_t>::createBasedOnSign(readCounter); + int64_t writeCounter = getFramesWritten(); + if (writeCounter < 0) return ResultWithValue<int32_t>::createBasedOnSign(writeCounter); + int32_t framesAvailable = writeCounter - readCounter; + return ResultWithValue<int32_t>(framesAvailable); +} + +ResultWithValue<int32_t> AudioStream::waitForAvailableFrames(int32_t numFrames, + int64_t timeoutNanoseconds) { + if (numFrames == 0) return Result::OK; + if (numFrames < 0) return Result::ErrorOutOfRange; + + int64_t framesAvailable = 0; + int64_t burstInNanos = getFramesPerBurst() * kNanosPerSecond / getSampleRate(); + bool ready = false; + int64_t deadline = AudioClock::getNanoseconds() + timeoutNanoseconds; + do { + ResultWithValue<int32_t> result = getAvailableFrames(); + if (!result) return result; + framesAvailable = result.value(); + ready = (framesAvailable >= numFrames); + if (!ready) { + int64_t now = AudioClock::getNanoseconds(); + if (now > deadline) break; + AudioClock::sleepForNanos(burstInNanos); + } + } while (!ready); + return (!ready) + ? ResultWithValue<int32_t>(Result::ErrorTimeout) + : ResultWithValue<int32_t>(framesAvailable); +} + +ResultWithValue<FrameTimestamp> AudioStream::getTimestamp(clockid_t clockId) { + FrameTimestamp frame; + Result result = getTimestamp(clockId, &frame.position, &frame.timestamp); + if (result == Result::OK){ + return ResultWithValue<FrameTimestamp>(frame); + } else { + return ResultWithValue<FrameTimestamp>(static_cast<Result>(result)); + } +} + +static void oboe_stop_thread_proc(AudioStream *oboeStream) { + if (oboeStream != nullptr) { + oboeStream->requestStop(); + } +} + +void AudioStream::launchStopThread() { + // Stop this stream on a separate thread + std::thread t(oboe_stop_thread_proc, this); + t.detach(); +} + +} // namespace oboe diff --git a/modules/juce_audio_devices/native/oboe/src/common/AudioStreamBuilder.cpp b/modules/juce_audio_devices/native/oboe/src/common/AudioStreamBuilder.cpp new file mode 100644 index 00000000..9f1e31b5 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/common/AudioStreamBuilder.cpp @@ -0,0 +1,201 @@ +/* + * Copyright 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <sys/types.h> + +#include "aaudio/AudioStreamAAudio.h" +#include "FilterAudioStream.h" +#include "OboeDebug.h" +#include "oboe/Oboe.h" +#include "oboe/AudioStreamBuilder.h" +#include "opensles/AudioInputStreamOpenSLES.h" +#include "opensles/AudioOutputStreamOpenSLES.h" +#include "opensles/AudioStreamOpenSLES.h" +#include "QuirksManager.h" + +bool oboe::OboeGlobals::mWorkaroundsEnabled = true; + +namespace oboe { + +/** + * The following default values are used when oboe does not have any better way of determining the optimal values + * for an audio stream. This can happen when: + * + * - Client is creating a stream on API < 26 (OpenSLES) but has not supplied the optimal sample + * rate and/or frames per burst + * - Client is creating a stream on API 16 (OpenSLES) where AudioManager.PROPERTY_OUTPUT_* values + * are not available + */ +int32_t DefaultStreamValues::SampleRate = 48000; // Common rate for mobile audio and video +int32_t DefaultStreamValues::FramesPerBurst = 192; // 4 msec at 48000 Hz +int32_t DefaultStreamValues::ChannelCount = 2; // Stereo + +constexpr int kBufferSizeInBurstsForLowLatencyStreams = 2; + +#ifndef OBOE_ENABLE_AAUDIO +// Set OBOE_ENABLE_AAUDIO to 0 if you want to disable the AAudio API. +// This might be useful if you want to force all the unit tests to use OpenSL ES. +#define OBOE_ENABLE_AAUDIO 1 +#endif + +bool AudioStreamBuilder::isAAudioSupported() { + return AudioStreamAAudio::isSupported() && OBOE_ENABLE_AAUDIO; +} + +bool AudioStreamBuilder::isAAudioRecommended() { + // See https://github.com/google/oboe/issues/40, + // AAudio may not be stable on Android O, depending on how it is used. + // To be safe, use AAudio only on O_MR1 and above. + return (getSdkVersion() >= __ANDROID_API_O_MR1__) && isAAudioSupported(); +} + +AudioStream *AudioStreamBuilder::build() { + AudioStream *stream = nullptr; + if (isAAudioRecommended() && mAudioApi != AudioApi::OpenSLES) { + stream = new AudioStreamAAudio(*this); + } else if (isAAudioSupported() && mAudioApi == AudioApi::AAudio) { + stream = new AudioStreamAAudio(*this); + LOGE("Creating AAudio stream on 8.0 because it was specified. This is error prone."); + } else { + if (getDirection() == oboe::Direction::Output) { + stream = new AudioOutputStreamOpenSLES(*this); + } else if (getDirection() == oboe::Direction::Input) { + stream = new AudioInputStreamOpenSLES(*this); + } + } + return stream; +} + +bool AudioStreamBuilder::isCompatible(AudioStreamBase &other) { + return getSampleRate() == other.getSampleRate() + && getFormat() == other.getFormat() + && getChannelCount() == other.getChannelCount(); +} + +Result AudioStreamBuilder::openStream(AudioStream **streamPP) { + Result result = Result::OK; + LOGI("%s() %s -------- %s --------", + __func__, getDirection() == Direction::Input ? "INPUT" : "OUTPUT", getVersionText()); + + if (streamPP == nullptr) { + return Result::ErrorNull; + } + *streamPP = nullptr; + + AudioStream *streamP = nullptr; + + // Maybe make a FilterInputStream. + AudioStreamBuilder childBuilder(*this); + // Check need for conversion and modify childBuilder for optimal stream. + bool conversionNeeded = QuirksManager::getInstance().isConversionNeeded(*this, childBuilder); + // Do we need to make a child stream and convert. + if (conversionNeeded) { + AudioStream *tempStream; + + result = childBuilder.openStream(&tempStream); + if (result != Result::OK) { + return result; + } + + if (isCompatible(*tempStream)) { + // Everything matches so we can just use the child stream directly. + *streamPP = tempStream; + return result; + } else { + AudioStreamBuilder parentBuilder = *this; + // Build a stream that is as close as possible to the childStream. + if (getFormat() == oboe::AudioFormat::Unspecified) { + parentBuilder.setFormat(tempStream->getFormat()); + } + if (getChannelCount() == oboe::Unspecified) { + parentBuilder.setChannelCount(tempStream->getChannelCount()); + } + if (getSampleRate() == oboe::Unspecified) { + parentBuilder.setSampleRate(tempStream->getSampleRate()); + } + + // Use childStream in a FilterAudioStream. + LOGI("%s() create a FilterAudioStream for data conversion.", __func__); + FilterAudioStream *filterStream = new FilterAudioStream(parentBuilder, tempStream); + result = filterStream->configureFlowGraph(); + if (result != Result::OK) { + filterStream->close(); + delete filterStream; + // Just open streamP the old way. + } else { + streamP = static_cast<AudioStream *>(filterStream); + } + } + } + + if (streamP == nullptr) { + streamP = build(); + if (streamP == nullptr) { + return Result::ErrorNull; + } + } + + result = streamP->open(); // TODO review API + if (result == Result::OK) { + + int32_t optimalBufferSize = -1; + // Use a reasonable default buffer size. + if (streamP->getDirection() == Direction::Input) { + // For input, small size does not improve latency because the stream is usually + // run close to empty. And a low size can result in XRuns so always use the maximum. + optimalBufferSize = streamP->getBufferCapacityInFrames(); + } else if (streamP->getPerformanceMode() == PerformanceMode::LowLatency + && streamP->getDirection() == Direction::Output) { // Output check is redundant. + optimalBufferSize = streamP->getFramesPerBurst() * + kBufferSizeInBurstsForLowLatencyStreams; + } + if (optimalBufferSize >= 0) { + auto setBufferResult = streamP->setBufferSizeInFrames(optimalBufferSize); + if (!setBufferResult) { + LOGW("Failed to setBufferSizeInFrames(%d). Error was %s", + optimalBufferSize, + convertToText(setBufferResult.error())); + } + } + + *streamPP = streamP; + } else { + delete streamP; + } + return result; +} + +Result AudioStreamBuilder::openManagedStream(oboe::ManagedStream &stream) { + stream.reset(); + AudioStream *streamptr; + auto result = openStream(&streamptr); + stream.reset(streamptr); + return result; +} + +Result AudioStreamBuilder::openStream(std::shared_ptr<AudioStream> &sharedStream) { + sharedStream.reset(); + AudioStream *streamptr; + auto result = openStream(&streamptr); + if (result == Result::OK) { + sharedStream.reset(streamptr); + // Save a weak_ptr in the stream for use with callbacks. + streamptr->setWeakThis(sharedStream); + } + return result; +} + +} // namespace oboe diff --git a/modules/juce_audio_devices/native/oboe/src/common/DataConversionFlowGraph.cpp b/modules/juce_audio_devices/native/oboe/src/common/DataConversionFlowGraph.cpp new file mode 100644 index 00000000..c15e92d2 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/common/DataConversionFlowGraph.cpp @@ -0,0 +1,215 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <memory> + +#include "OboeDebug.h" +#include "DataConversionFlowGraph.h" +#include "SourceFloatCaller.h" +#include "SourceI16Caller.h" + +#include <flowgraph/ClipToRange.h> +#include <flowgraph/MonoToMultiConverter.h> +#include <flowgraph/RampLinear.h> +#include <flowgraph/SinkFloat.h> +#include <flowgraph/SinkI16.h> +#include <flowgraph/SinkI24.h> +#include <flowgraph/SourceFloat.h> +#include <flowgraph/SourceI16.h> +#include <flowgraph/SourceI24.h> +#include <flowgraph/SampleRateConverter.h> + +using namespace oboe; +using namespace flowgraph; +using namespace resampler; + +void DataConversionFlowGraph::setSource(const void *buffer, int32_t numFrames) { + mSource->setData(buffer, numFrames); +} + +static MultiChannelResampler::Quality convertOboeSRQualityToMCR(SampleRateConversionQuality quality) { + switch (quality) { + case SampleRateConversionQuality::Fastest: + return MultiChannelResampler::Quality::Fastest; + case SampleRateConversionQuality::Low: + return MultiChannelResampler::Quality::Low; + default: + case SampleRateConversionQuality::Medium: + return MultiChannelResampler::Quality::Medium; + case SampleRateConversionQuality::High: + return MultiChannelResampler::Quality::High; + case SampleRateConversionQuality::Best: + return MultiChannelResampler::Quality::Best; + } +} + +// Chain together multiple processors. +// Callback Output +// Use SourceCaller that calls original app callback from the flowgraph. +// The child callback from FilteredAudioStream read()s from the flowgraph. +// Callback Input +// Child callback from FilteredAudioStream writes()s to the flowgraph. +// The output of the flowgraph goes through a BlockWriter to the app callback. +// Blocking Write +// Write buffer is set on an AudioSource. +// Data is pulled through the graph and written to the child stream. +// Blocking Read +// Reads in a loop from the flowgraph Sink to fill the read buffer. +// A SourceCaller then does a blocking read from the child Stream. +// +Result DataConversionFlowGraph::configure(AudioStream *sourceStream, AudioStream *sinkStream) { + + FlowGraphPortFloatOutput *lastOutput = nullptr; + + bool isOutput = sourceStream->getDirection() == Direction::Output; + bool isInput = !isOutput; + mFilterStream = isOutput ? sourceStream : sinkStream; + + AudioFormat sourceFormat = sourceStream->getFormat(); + int32_t sourceChannelCount = sourceStream->getChannelCount(); + int32_t sourceSampleRate = sourceStream->getSampleRate(); + + AudioFormat sinkFormat = sinkStream->getFormat(); + int32_t sinkChannelCount = sinkStream->getChannelCount(); + int32_t sinkSampleRate = sinkStream->getSampleRate(); + + LOGI("%s() flowgraph converts channels: %d to %d, format: %d to %d, rate: %d to %d, qual = %d", + __func__, + sourceChannelCount, sinkChannelCount, + sourceFormat, sinkFormat, + sourceSampleRate, sinkSampleRate, + sourceStream->getSampleRateConversionQuality()); + + int32_t framesPerCallback = (sourceStream->getFramesPerCallback() == kUnspecified) + ? sourceStream->getFramesPerBurst() + : sourceStream->getFramesPerCallback(); + // Source + // If OUTPUT and using a callback then call back to the app using a SourceCaller. + // If INPUT and NOT using a callback then read from the child stream using a SourceCaller. + if ((sourceStream->getCallback() != nullptr && isOutput) + || (sourceStream->getCallback() == nullptr && isInput)) { + switch (sourceFormat) { + case AudioFormat::Float: + mSourceCaller = std::make_unique<SourceFloatCaller>(sourceChannelCount, + framesPerCallback); + break; + case AudioFormat::I16: + mSourceCaller = std::make_unique<SourceI16Caller>(sourceChannelCount, + framesPerCallback); + break; + default: + LOGE("%s() Unsupported source caller format = %d", __func__, sourceFormat); + return Result::ErrorIllegalArgument; + } + mSourceCaller->setStream(sourceStream); + lastOutput = &mSourceCaller->output; + } else { + // If OUTPUT and NOT using a callback then write to the child stream using a BlockWriter. + // If INPUT and using a callback then write to the app using a BlockWriter. + switch (sourceFormat) { + case AudioFormat::Float: + mSource = std::make_unique<SourceFloat>(sourceChannelCount); + break; + case AudioFormat::I16: + mSource = std::make_unique<SourceI16>(sourceChannelCount); + break; + default: + LOGE("%s() Unsupported source format = %d", __func__, sourceFormat); + return Result::ErrorIllegalArgument; + } + if (isInput) { + // The BlockWriter is after the Sink so use the SinkStream size. + mBlockWriter.open(framesPerCallback * sinkStream->getBytesPerFrame()); + mAppBuffer = std::make_unique<uint8_t[]>( + kDefaultBufferSize * sinkStream->getBytesPerFrame()); + } + lastOutput = &mSource->output; + } + + // Sample Rate conversion + if (sourceSampleRate != sinkSampleRate) { + mResampler.reset(MultiChannelResampler::make(sourceChannelCount, + sourceSampleRate, + sinkSampleRate, + convertOboeSRQualityToMCR( + sourceStream->getSampleRateConversionQuality()))); + mRateConverter = std::make_unique<SampleRateConverter>(sourceChannelCount, + *mResampler.get()); + lastOutput->connect(&mRateConverter->input); + lastOutput = &mRateConverter->output; + } + + // Expand the number of channels if required. + if (sourceChannelCount == 1 && sinkChannelCount > 1) { + mChannelConverter = std::make_unique<MonoToMultiConverter>(sinkChannelCount); + lastOutput->connect(&mChannelConverter->input); + lastOutput = &mChannelConverter->output; + } else if (sourceChannelCount != sinkChannelCount) { + LOGW("%s() Channel reduction not supported.", __func__); + return Result::ErrorUnimplemented; // TODO + } + + // Sink + switch (sinkFormat) { + case AudioFormat::Float: + mSink = std::make_unique<SinkFloat>(sinkChannelCount); + break; + case AudioFormat::I16: + mSink = std::make_unique<SinkI16>(sinkChannelCount); + break; + default: + LOGE("%s() Unsupported sink format = %d", __func__, sinkFormat); + return Result::ErrorIllegalArgument;; + } + lastOutput->connect(&mSink->input); + + mFramePosition = 0; + + return Result::OK; +} + +int32_t DataConversionFlowGraph::read(void *buffer, int32_t numFrames, int64_t timeoutNanos) { + if (mSourceCaller) { + mSourceCaller->setTimeoutNanos(timeoutNanos); + } + int32_t numRead = mSink->read(mFramePosition, buffer, numFrames); + mFramePosition += numRead; + return numRead; +} + +// This is similar to pushing data through the flowgraph. +int32_t DataConversionFlowGraph::write(void *inputBuffer, int32_t numFrames) { + // Put the data from the input at the head of the flowgraph. + mSource->setData(inputBuffer, numFrames); + while (true) { + // Pull and read some data in app format into a small buffer. + int32_t framesRead = mSink->read(mFramePosition, mAppBuffer.get(), flowgraph::kDefaultBufferSize); + mFramePosition += framesRead; + if (framesRead <= 0) break; + // Write to a block adapter, which will call the destination whenever it has enough data. + int32_t bytesRead = mBlockWriter.write(mAppBuffer.get(), + framesRead * mFilterStream->getBytesPerFrame()); + if (bytesRead < 0) return bytesRead; // TODO review + } + return numFrames; +} + +int32_t DataConversionFlowGraph::onProcessFixedBlock(uint8_t *buffer, int32_t numBytes) { + int32_t numFrames = numBytes / mFilterStream->getBytesPerFrame(); + mCallbackResult = mFilterStream->getCallback()->onAudioReady(mFilterStream, buffer, numFrames); + // TODO handle STOP from callback, process data remaining in the block adapter + return numBytes; +} \ No newline at end of file diff --git a/modules/juce_audio_devices/native/oboe/src/common/DataConversionFlowGraph.h b/modules/juce_audio_devices/native/oboe/src/common/DataConversionFlowGraph.h new file mode 100644 index 00000000..b1d5ebe8 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/common/DataConversionFlowGraph.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBOE_OBOE_FLOW_GRAPH_H +#define OBOE_OBOE_FLOW_GRAPH_H + +#include <memory> +#include <stdint.h> +#include <sys/types.h> + +#include <flowgraph/MonoToMultiConverter.h> +#include <flowgraph/SampleRateConverter.h> +#include <oboe/Definitions.h> +#include "AudioSourceCaller.h" +#include "FixedBlockWriter.h" + +namespace oboe { + +class AudioStream; +class AudioSourceCaller; + +/** + * Convert PCM channels, format and sample rate for optimal latency. + */ +class DataConversionFlowGraph : public FixedBlockProcessor { +public: + + DataConversionFlowGraph() + : mBlockWriter(*this) {} + + void setSource(const void *buffer, int32_t numFrames); + + /** Connect several modules together to convert from source to sink. + * This should only be called once for each instance. + * + * @param sourceFormat + * @param sourceChannelCount + * @param sinkFormat + * @param sinkChannelCount + * @return + */ + oboe::Result configure(oboe::AudioStream *sourceStream, oboe::AudioStream *sinkStream); + + int32_t read(void *buffer, int32_t numFrames, int64_t timeoutNanos); + + int32_t write(void *buffer, int32_t numFrames); + + int32_t onProcessFixedBlock(uint8_t *buffer, int32_t numBytes) override; + + DataCallbackResult getDataCallbackResult() { + return mCallbackResult; + } + +private: + std::unique_ptr<flowgraph::FlowGraphSourceBuffered> mSource; + std::unique_ptr<AudioSourceCaller> mSourceCaller; + std::unique_ptr<flowgraph::MonoToMultiConverter> mChannelConverter; + std::unique_ptr<resampler::MultiChannelResampler> mResampler; + std::unique_ptr<flowgraph::SampleRateConverter> mRateConverter; + std::unique_ptr<flowgraph::FlowGraphSink> mSink; + + FixedBlockWriter mBlockWriter; + DataCallbackResult mCallbackResult = DataCallbackResult::Continue; + AudioStream *mFilterStream = nullptr; + std::unique_ptr<uint8_t[]> mAppBuffer; + + int64_t mFramePosition = 0; +}; + +} +#endif //OBOE_OBOE_FLOW_GRAPH_H diff --git a/modules/juce_audio_devices/native/oboe/src/common/FilterAudioStream.cpp b/modules/juce_audio_devices/native/oboe/src/common/FilterAudioStream.cpp new file mode 100644 index 00000000..a4715835 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/common/FilterAudioStream.cpp @@ -0,0 +1,92 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <memory> + +#include "FilterAudioStream.h" + +using namespace oboe; +using namespace flowgraph; + +// Output callback uses FixedBlockReader::read() +// <= SourceFloatCaller::onProcess() +// <=== DataConversionFlowGraph::read() +// <== FilterAudioStream::onAudioReady() +// +// Output blocking uses no block adapter because AAudio can accept +// writes of any size. It uses DataConversionFlowGraph::read() <== FilterAudioStream::write() <= app +// +// Input callback uses FixedBlockWriter::write() +// <= DataConversionFlowGraph::write() +// <= FilterAudioStream::onAudioReady() +// +// Input blocking uses FixedBlockReader::read() // TODO may not need block adapter +// <= SourceFloatCaller::onProcess() +// <=== SinkFloat::read() +// <= DataConversionFlowGraph::read() +// <== FilterAudioStream::read() +// <= app + +Result FilterAudioStream::configureFlowGraph() { + mFlowGraph = std::make_unique<DataConversionFlowGraph>(); + bool isOutput = getDirection() == Direction::Output; + + AudioStream *sourceStream = isOutput ? this : mChildStream.get(); + AudioStream *sinkStream = isOutput ? mChildStream.get() : this; + + mRateScaler = ((double) sourceStream->getSampleRate()) / sinkStream->getSampleRate(); + + return mFlowGraph->configure(sourceStream, sinkStream); +} + +// Put the data to be written at the source end of the flowgraph. +// Then read (pull) the data from the flowgraph and write it to the +// child stream. +ResultWithValue<int32_t> FilterAudioStream::write(const void *buffer, + int32_t numFrames, + int64_t timeoutNanoseconds) { + int32_t framesWritten = 0; + mFlowGraph->setSource(buffer, numFrames); + while (true) { + int32_t numRead = mFlowGraph->read(mBlockingBuffer.get(), + getFramesPerBurst(), + timeoutNanoseconds); + if (numRead < 0) { + return ResultWithValue<int32_t>::createBasedOnSign(numRead); + } + if (numRead == 0) { + break; // finished processing the source buffer + } + auto writeResult = mChildStream->write(mBlockingBuffer.get(), + numRead, + timeoutNanoseconds); + if (!writeResult) { + return writeResult; + } + framesWritten += writeResult.value(); + } + return ResultWithValue<int32_t>::createBasedOnSign(framesWritten); +} + +// Read (pull) the data we want from the sink end of the flowgraph. +// The necessary data will be read from the child stream using a flowgraph callback. +ResultWithValue<int32_t> FilterAudioStream::read(void *buffer, + int32_t numFrames, + int64_t timeoutNanoseconds) { + int32_t framesRead = mFlowGraph->read(buffer, numFrames, timeoutNanoseconds); + return ResultWithValue<int32_t>::createBasedOnSign(framesRead); +} + diff --git a/modules/juce_audio_devices/native/oboe/src/common/FilterAudioStream.h b/modules/juce_audio_devices/native/oboe/src/common/FilterAudioStream.h new file mode 100644 index 00000000..3949de77 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/common/FilterAudioStream.h @@ -0,0 +1,214 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBOE_FILTER_AUDIO_STREAM_H +#define OBOE_FILTER_AUDIO_STREAM_H + +#include <memory> +#include <oboe/AudioStream.h> +#include "DataConversionFlowGraph.h" + +namespace oboe { + +/** + * An AudioStream that wraps another AudioStream and provides audio data conversion. + * Operations may include channel conversion, data format conversion and/or sample rate conversion. + */ +class FilterAudioStream : public AudioStream, AudioStreamCallback { +public: + + /** + * Construct an `AudioStream` using the given `AudioStreamBuilder` and a child AudioStream. + * + * This should only be called internally by AudioStreamBuilder. + * Ownership of childStream will be passed to this object. + * + * @param builder containing all the stream's attributes + */ + FilterAudioStream(const AudioStreamBuilder &builder, AudioStream *childStream) + : AudioStream(builder) + , mChildStream(childStream) { + // Intercept the callback if used. + if (builder.getCallback() != nullptr) { + mStreamCallback = mChildStream->swapCallback(this); + } else { + const int size = childStream->getFramesPerBurst() * childStream->getBytesPerFrame(); + mBlockingBuffer = std::make_unique<uint8_t[]>(size); + } + + // Copy parameters that may not match builder. + mBufferCapacityInFrames = mChildStream->getBufferCapacityInFrames(); + mPerformanceMode = mChildStream->getPerformanceMode(); + } + + virtual ~FilterAudioStream() = default; + + AudioStream *getChildStream() const { + return mChildStream.get(); + } + + Result configureFlowGraph(); + + // Close child and parent. + Result close() override { + const Result result1 = mChildStream->close(); + const Result result2 = AudioStream::close(); + return (result1 != Result::OK ? result1 : result2); + } + + /** + * Start the stream asynchronously. Returns immediately (does not block). Equivalent to calling + * `start(0)`. + */ + Result requestStart() override { + return mChildStream->requestStart(); + } + + /** + * Pause the stream asynchronously. Returns immediately (does not block). Equivalent to calling + * `pause(0)`. + */ + Result requestPause() override { + return mChildStream->requestPause(); + } + + /** + * Flush the stream asynchronously. Returns immediately (does not block). Equivalent to calling + * `flush(0)`. + */ + Result requestFlush() override { + return mChildStream->requestFlush(); + } + + /** + * Stop the stream asynchronously. Returns immediately (does not block). Equivalent to calling + * `stop(0)`. + */ + Result requestStop() override { + return mChildStream->requestStop(); + } + + ResultWithValue<int32_t> read(void *buffer, + int32_t numFrames, + int64_t timeoutNanoseconds) override; + + ResultWithValue<int32_t> write(const void *buffer, + int32_t numFrames, + int64_t timeoutNanoseconds) override; + + StreamState getState() const override { + return mChildStream->getState(); + } + + Result waitForStateChange( + StreamState inputState, + StreamState *nextState, + int64_t timeoutNanoseconds) override { + return mChildStream->waitForStateChange(inputState, nextState, timeoutNanoseconds); + } + + bool isXRunCountSupported() const override { + return mChildStream->isXRunCountSupported(); + } + + int32_t getFramesPerBurst() override { + return mChildStream->getFramesPerBurst(); + } + + AudioApi getAudioApi() const override { + return mChildStream->getAudioApi(); + } + + void updateFramesWritten() override { + // TODO for output, just count local writes? + mFramesWritten = static_cast<int64_t>(mChildStream->getFramesWritten() * mRateScaler); + } + + void updateFramesRead() override { + // TODO for input, just count local reads? + mFramesRead = static_cast<int64_t>(mChildStream->getFramesRead() * mRateScaler); + } + + void *getUnderlyingStream() const override { + return mChildStream->getUnderlyingStream(); + } + + ResultWithValue<int32_t> setBufferSizeInFrames(int32_t requestedFrames) override { + return mChildStream->setBufferSizeInFrames(requestedFrames); + } + + int32_t getBufferSizeInFrames() override { + mBufferSizeInFrames = mChildStream->getBufferSizeInFrames(); + return mBufferSizeInFrames; + } + + ResultWithValue<int32_t> getXRunCount() const override { + return mChildStream->getXRunCount(); + } + + ResultWithValue<double> calculateLatencyMillis() override { + // This will automatically include the latency of the flowgraph? + return mChildStream->calculateLatencyMillis(); + } + + Result getTimestamp(clockid_t clockId, + int64_t *framePosition, + int64_t *timeNanoseconds) override { + int64_t childPosition = 0; + Result result = mChildStream->getTimestamp(clockId, &childPosition, timeNanoseconds); + *framePosition = childPosition * mRateScaler; + return result; + } + + DataCallbackResult onAudioReady(AudioStream *oboeStream, + void *audioData, + int32_t numFrames) override { + int32_t framesProcessed; + if (oboeStream->getDirection() == Direction::Output) { + framesProcessed = mFlowGraph->read(audioData, numFrames, 0 /* timeout */); + } else { + framesProcessed = mFlowGraph->write(audioData, numFrames); + } + return (framesProcessed < numFrames) + ? DataCallbackResult::Stop + : mFlowGraph->getDataCallbackResult(); + } + + void onErrorBeforeClose(AudioStream *oboeStream, Result error) override { + if (mStreamCallback != nullptr) { + mStreamCallback->onErrorBeforeClose(this, error); + } + } + + void onErrorAfterClose(AudioStream *oboeStream, Result error) override { + // Close this parent stream because the callback will only close the child. + AudioStream::close(); + if (mStreamCallback != nullptr) { + mStreamCallback->onErrorAfterClose(this, error); + } + } + +private: + + std::unique_ptr<AudioStream> mChildStream; // this stream wraps the child stream + std::unique_ptr<DataConversionFlowGraph> mFlowGraph; // for converting data + std::unique_ptr<uint8_t[]> mBlockingBuffer; // temp buffer for write() + double mRateScaler = 1.0; // ratio parent/child sample rates +}; + +} // oboe + +#endif //OBOE_FILTER_AUDIO_STREAM_H diff --git a/modules/juce_audio_devices/native/oboe/src/common/FixedBlockAdapter.cpp b/modules/juce_audio_devices/native/oboe/src/common/FixedBlockAdapter.cpp new file mode 100644 index 00000000..e14c2caa --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/common/FixedBlockAdapter.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdint.h> + +#include "FixedBlockAdapter.h" + +FixedBlockAdapter::~FixedBlockAdapter() { +} + +int32_t FixedBlockAdapter::open(int32_t bytesPerFixedBlock) +{ + mSize = bytesPerFixedBlock; + mStorage = std::make_unique<uint8_t[]>(bytesPerFixedBlock); + mPosition = 0; + return 0; +} + +int32_t FixedBlockAdapter::close() +{ + mStorage.reset(nullptr); + mSize = 0; + mPosition = 0; + return 0; +} diff --git a/modules/juce_audio_devices/native/oboe/src/common/FixedBlockAdapter.h b/modules/juce_audio_devices/native/oboe/src/common/FixedBlockAdapter.h new file mode 100644 index 00000000..76e961c9 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/common/FixedBlockAdapter.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AAUDIO_FIXED_BLOCK_ADAPTER_H +#define AAUDIO_FIXED_BLOCK_ADAPTER_H + +#include <memory> +#include <stdint.h> +#include <sys/types.h> + +/** + * Interface for a class that needs fixed-size blocks. + */ +class FixedBlockProcessor { +public: + virtual ~FixedBlockProcessor() = default; + /** + * + * @param buffer Pointer to first byte of data. + * @param numBytes This will be a fixed size specified in FixedBlockAdapter::open(). + * @return Number of bytes processed or a negative error code. + */ + virtual int32_t onProcessFixedBlock(uint8_t *buffer, int32_t numBytes) = 0; +}; + +/** + * Base class for a variable-to-fixed-size block adapter. + */ +class FixedBlockAdapter +{ +public: + FixedBlockAdapter(FixedBlockProcessor &fixedBlockProcessor) + : mFixedBlockProcessor(fixedBlockProcessor) {} + + virtual ~FixedBlockAdapter(); + + /** + * Allocate internal resources needed for buffering data. + */ + virtual int32_t open(int32_t bytesPerFixedBlock); + + /** + * Free internal resources. + */ + int32_t close(); + +protected: + FixedBlockProcessor &mFixedBlockProcessor; + std::unique_ptr<uint8_t[]> mStorage; // Store data here while assembling buffers. + int32_t mSize = 0; // Size in bytes of the fixed size buffer. + int32_t mPosition = 0; // Offset of the last byte read or written. +}; + +#endif /* AAUDIO_FIXED_BLOCK_ADAPTER_H */ diff --git a/modules/juce_audio_devices/native/oboe/src/common/FixedBlockReader.cpp b/modules/juce_audio_devices/native/oboe/src/common/FixedBlockReader.cpp new file mode 100644 index 00000000..62e9664d --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/common/FixedBlockReader.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdint.h> +#include <memory.h> + +#include "FixedBlockAdapter.h" + +#include "FixedBlockReader.h" + + +FixedBlockReader::FixedBlockReader(FixedBlockProcessor &fixedBlockProcessor) + : FixedBlockAdapter(fixedBlockProcessor) { + mPosition = mSize; +} + +int32_t FixedBlockReader::open(int32_t bytesPerFixedBlock) { + int32_t result = FixedBlockAdapter::open(bytesPerFixedBlock); + mPosition = 0; + mValid = 0; + return result; +} + +int32_t FixedBlockReader::readFromStorage(uint8_t *buffer, int32_t numBytes) { + int32_t bytesToRead = numBytes; + int32_t dataAvailable = mValid - mPosition; + if (bytesToRead > dataAvailable) { + bytesToRead = dataAvailable; + } + memcpy(buffer, mStorage.get() + mPosition, bytesToRead); + mPosition += bytesToRead; + return bytesToRead; +} + +int32_t FixedBlockReader::read(uint8_t *buffer, int32_t numBytes) { + int32_t bytesRead; + int32_t bytesLeft = numBytes; + while(bytesLeft > 0) { + if (mPosition < mValid) { + // Use up bytes currently in storage. + bytesRead = readFromStorage(buffer, bytesLeft); + buffer += bytesRead; + bytesLeft -= bytesRead; + } else if (bytesLeft >= mSize) { + // Nothing in storage. Read through if enough for a complete block. + bytesRead = mFixedBlockProcessor.onProcessFixedBlock(buffer, mSize); + if (bytesRead < 0) return bytesRead; + buffer += bytesRead; + bytesLeft -= bytesRead; + } else { + // Just need a partial block so we have to reload storage. + bytesRead = mFixedBlockProcessor.onProcessFixedBlock(mStorage.get(), mSize); + if (bytesRead < 0) return bytesRead; + mPosition = 0; + mValid = bytesRead; + if (bytesRead == 0) break; + } + } + return numBytes - bytesLeft; +} diff --git a/modules/juce_audio_devices/native/oboe/src/common/FixedBlockReader.h b/modules/juce_audio_devices/native/oboe/src/common/FixedBlockReader.h new file mode 100644 index 00000000..4cea9c8b --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/common/FixedBlockReader.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AAUDIO_FIXED_BLOCK_READER_H +#define AAUDIO_FIXED_BLOCK_READER_H + +#include <stdint.h> + +#include "FixedBlockAdapter.h" + +/** + * Read from a fixed-size block to a variable sized block. + * + * This can be used to convert a pull data flow from fixed sized buffers to variable sized buffers. + * An example would be an audio output callback that reads from the app. + */ +class FixedBlockReader : public FixedBlockAdapter +{ +public: + FixedBlockReader(FixedBlockProcessor &fixedBlockProcessor); + + virtual ~FixedBlockReader() = default; + + int32_t open(int32_t bytesPerFixedBlock) override; + + /** + * Read into a variable sized block. + * + * Note that if the fixed-sized blocks must be aligned, then the variable-sized blocks + * must have the same alignment. + * For example, if the fixed-size blocks must be a multiple of 8, then the variable-sized + * blocks must also be a multiple of 8. + * + * @param buffer + * @param numBytes + * @return Number of bytes read or a negative error code. + */ + int32_t read(uint8_t *buffer, int32_t numBytes); + +private: + int32_t readFromStorage(uint8_t *buffer, int32_t numBytes); + + int32_t mValid = 0; // Number of valid bytes in mStorage. +}; + + +#endif /* AAUDIO_FIXED_BLOCK_READER_H */ diff --git a/modules/juce_audio_devices/native/oboe/src/common/FixedBlockWriter.cpp b/modules/juce_audio_devices/native/oboe/src/common/FixedBlockWriter.cpp new file mode 100644 index 00000000..b3156097 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/common/FixedBlockWriter.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdint.h> +#include <memory.h> + +#include "FixedBlockAdapter.h" +#include "FixedBlockWriter.h" + +FixedBlockWriter::FixedBlockWriter(FixedBlockProcessor &fixedBlockProcessor) + : FixedBlockAdapter(fixedBlockProcessor) {} + + +int32_t FixedBlockWriter::writeToStorage(uint8_t *buffer, int32_t numBytes) { + int32_t bytesToStore = numBytes; + int32_t roomAvailable = mSize - mPosition; + if (bytesToStore > roomAvailable) { + bytesToStore = roomAvailable; + } + memcpy(mStorage.get() + mPosition, buffer, bytesToStore); + mPosition += bytesToStore; + return bytesToStore; +} + +int32_t FixedBlockWriter::write(uint8_t *buffer, int32_t numBytes) { + int32_t bytesLeft = numBytes; + + // If we already have data in storage then add to it. + if (mPosition > 0) { + int32_t bytesWritten = writeToStorage(buffer, bytesLeft); + buffer += bytesWritten; + bytesLeft -= bytesWritten; + // If storage full then flush it out + if (mPosition == mSize) { + bytesWritten = mFixedBlockProcessor.onProcessFixedBlock(mStorage.get(), mSize); + if (bytesWritten < 0) return bytesWritten; + mPosition = 0; + if (bytesWritten < mSize) { + // Only some of the data was written! This should not happen. + return -1; + } + } + } + + // Write through if enough for a complete block. + while(bytesLeft > mSize) { + int32_t bytesWritten = mFixedBlockProcessor.onProcessFixedBlock(buffer, mSize); + if (bytesWritten < 0) return bytesWritten; + buffer += bytesWritten; + bytesLeft -= bytesWritten; + } + + // Save any remaining partial blocks for next time. + if (bytesLeft > 0) { + int32_t bytesWritten = writeToStorage(buffer, bytesLeft); + bytesLeft -= bytesWritten; + } + + return numBytes - bytesLeft; +} diff --git a/modules/juce_audio_devices/native/oboe/src/common/FixedBlockWriter.h b/modules/juce_audio_devices/native/oboe/src/common/FixedBlockWriter.h new file mode 100644 index 00000000..6dea6ca9 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/common/FixedBlockWriter.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AAUDIO_FIXED_BLOCK_WRITER_H +#define AAUDIO_FIXED_BLOCK_WRITER_H + +#include <stdint.h> + +#include "FixedBlockAdapter.h" + +/** + * This can be used to convert a push data flow from variable sized buffers to fixed sized buffers. + * An example would be an audio input callback. + */ +class FixedBlockWriter : public FixedBlockAdapter +{ +public: + FixedBlockWriter(FixedBlockProcessor &fixedBlockProcessor); + + virtual ~FixedBlockWriter() = default; + + /** + * Write from a variable sized block. + * + * Note that if the fixed-sized blocks must be aligned, then the variable-sized blocks + * must have the same alignment. + * For example, if the fixed-size blocks must be a multiple of 8, then the variable-sized + * blocks must also be a multiple of 8. + * + * @param buffer + * @param numBytes + * @return Number of bytes written or a negative error code. + */ + int32_t write(uint8_t *buffer, int32_t numBytes); + +private: + + int32_t writeToStorage(uint8_t *buffer, int32_t numBytes); +}; + +#endif /* AAUDIO_FIXED_BLOCK_WRITER_H */ diff --git a/modules/juce_audio_devices/native/oboe/src/common/LatencyTuner.cpp b/modules/juce_audio_devices/native/oboe/src/common/LatencyTuner.cpp new file mode 100644 index 00000000..cce8e189 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/common/LatencyTuner.cpp @@ -0,0 +1,102 @@ +/* + * Copyright 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "oboe/LatencyTuner.h" + +using namespace oboe; + +LatencyTuner::LatencyTuner(AudioStream &stream) + : LatencyTuner(stream, stream.getBufferCapacityInFrames()){ + } + +LatencyTuner::LatencyTuner(oboe::AudioStream &stream, int32_t maximumBufferSize) + : mStream(stream) + , mMaxBufferSize(maximumBufferSize) { + reset(); +} + +Result LatencyTuner::tune() { + if (mState == State::Unsupported) { + return Result::ErrorUnimplemented; + } + + Result result = Result::OK; + + // Process reset requests. + int32_t numRequests = mLatencyTriggerRequests.load(); + if (numRequests != mLatencyTriggerResponses.load()) { + mLatencyTriggerResponses.store(numRequests); + reset(); + } + + // Set state to Active if the idle countdown has reached zero. + if (mState == State::Idle && --mIdleCountDown <= 0) { + mState = State::Active; + } + + // When state is Active attempt to change the buffer size if the number of xRuns has increased. + if (mState == State::Active) { + + auto xRunCountResult = mStream.getXRunCount(); + if (xRunCountResult == Result::OK) { + if ((xRunCountResult.value() - mPreviousXRuns) > 0) { + mPreviousXRuns = xRunCountResult.value(); + int32_t oldBufferSize = mStream.getBufferSizeInFrames(); + int32_t requestedBufferSize = oldBufferSize + mStream.getFramesPerBurst(); + + // Do not request more than the maximum buffer size (which was either user-specified + // or was from stream->getBufferCapacityInFrames()) + if (requestedBufferSize > mMaxBufferSize) requestedBufferSize = mMaxBufferSize; + + auto setBufferResult = mStream.setBufferSizeInFrames(requestedBufferSize); + if (setBufferResult != Result::OK) { + result = setBufferResult; + mState = State::Unsupported; + } else if (setBufferResult.value() == oldBufferSize) { + mState = State::AtMax; + } + } + } else { + mState = State::Unsupported; + } + } + + if (mState == State::Unsupported) { + result = Result::ErrorUnimplemented; + } + + if (mState == State::AtMax) { + result = Result::OK; + } + return result; +} + +void LatencyTuner::requestReset() { + if (mState != State::Unsupported) { + mLatencyTriggerRequests++; + } +} + +void LatencyTuner::reset() { + mState = State::Idle; + mIdleCountDown = kIdleCount; + // Set to minimal latency + mStream.setBufferSizeInFrames(2 * mStream.getFramesPerBurst()); +} + +bool LatencyTuner::isAtMaximumBufferSize() { + return mState == State::AtMax; +} diff --git a/modules/juce_audio_devices/native/oboe/src/common/MonotonicCounter.h b/modules/juce_audio_devices/native/oboe/src/common/MonotonicCounter.h new file mode 100644 index 00000000..00c979c5 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/common/MonotonicCounter.h @@ -0,0 +1,112 @@ +/* + * Copyright 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef COMMON_MONOTONIC_COUNTER_H +#define COMMON_MONOTONIC_COUNTER_H + +#include <cstdint> + +/** + * Maintain a 64-bit monotonic counter. + * Can be used to track a 32-bit counter that wraps or gets reset. + * + * Note that this is not atomic and has no interior locks. + * A caller will need to provide their own exterior locking + * if they need to use it from multiple threads. + */ +class MonotonicCounter { + +public: + MonotonicCounter() {} + virtual ~MonotonicCounter() {} + + /** + * @return current value of the counter + */ + int64_t get() const { + return mCounter64; + } + + /** + * set the current value of the counter + */ + void set(int64_t counter) { + mCounter64 = counter; + } + + /** + * Advance the counter if delta is positive. + * @return current value of the counter + */ + int64_t increment(int64_t delta) { + if (delta > 0) { + mCounter64 += delta; + } + return mCounter64; + } + + /** + * Advance the 64-bit counter if (current32 - previousCurrent32) > 0. + * This can be used to convert a 32-bit counter that may be wrapping into + * a monotonic 64-bit counter. + * + * This counter32 should NOT be allowed to advance by more than 0x7FFFFFFF between calls. + * Think of the wrapping counter like a sine wave. If the frequency of the signal + * is more than half the sampling rate (Nyquist rate) then you cannot measure it properly. + * If the counter wraps around every 24 hours then we should measure it with a period + * of less than 12 hours. + * + * @return current value of the 64-bit counter + */ + int64_t update32(int32_t counter32) { + int32_t delta = counter32 - mCounter32; + // protect against the mCounter64 going backwards + if (delta > 0) { + mCounter64 += delta; + mCounter32 = counter32; + } + return mCounter64; + } + + /** + * Reset the stored value of the 32-bit counter. + * This is used if your counter32 has been reset to zero. + */ + void reset32() { + mCounter32 = 0; + } + + /** + * Round 64-bit counter up to a multiple of the period. + * + * The period must be positive. + * + * @param period might be, for example, a buffer capacity + */ + void roundUp64(int32_t period) { + if (period > 0) { + int64_t numPeriods = (mCounter64 + period - 1) / period; + mCounter64 = numPeriods * period; + } + } + +private: + int64_t mCounter64 = 0; + int32_t mCounter32 = 0; +}; + + +#endif //COMMON_MONOTONIC_COUNTER_H diff --git a/modules/juce_audio_devices/native/oboe/src/common/OboeDebug.h b/modules/juce_audio_devices/native/oboe/src/common/OboeDebug.h new file mode 100644 index 00000000..dc7434c8 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/common/OboeDebug.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef OBOE_DEBUG_H +#define OBOE_DEBUG_H + +#include <android/log.h> + +#ifndef MODULE_NAME +#define MODULE_NAME "OboeAudio" +#endif + +// Always log INFO and errors. +#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, MODULE_NAME, __VA_ARGS__) +#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, MODULE_NAME, __VA_ARGS__) +#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, MODULE_NAME, __VA_ARGS__) +#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL, MODULE_NAME, __VA_ARGS__) + +#if OBOE_ENABLE_LOGGING +#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, MODULE_NAME, __VA_ARGS__) +#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, MODULE_NAME, __VA_ARGS__) +#else +#define LOGV(...) +#define LOGD(...) +#endif + +#endif //OBOE_DEBUG_H diff --git a/modules/juce_audio_devices/native/oboe/src/common/QuirksManager.cpp b/modules/juce_audio_devices/native/oboe/src/common/QuirksManager.cpp new file mode 100644 index 00000000..3df1bc4a --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/common/QuirksManager.cpp @@ -0,0 +1,138 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <oboe/AudioStreamBuilder.h> +#include <oboe/Oboe.h> + +#include "QuirksManager.h" + +using namespace oboe; + +int32_t QuirksManager::DeviceQuirks::clipBufferSize(AudioStream &stream, + int32_t requestedSize) { + if (!OboeGlobals::areWorkaroundsEnabled()) { + return requestedSize; + } + int bottomMargin = kDefaultBottomMarginInBursts; + int topMargin = kDefaultTopMarginInBursts; + if (isMMapUsed(stream)) { + if (stream.getSharingMode() == SharingMode::Exclusive) { + bottomMargin = getExclusiveBottomMarginInBursts(); + topMargin = getExclusiveTopMarginInBursts(); + } + } else { + bottomMargin = kLegacyBottomMarginInBursts; + } + + int32_t burst = stream.getFramesPerBurst(); + int32_t minSize = bottomMargin * burst; + int32_t adjustedSize = requestedSize; + if (adjustedSize < minSize ) { + adjustedSize = minSize; + } else { + int32_t maxSize = stream.getBufferCapacityInFrames() - (topMargin * burst); + if (adjustedSize > maxSize ) { + adjustedSize = maxSize; + } + } + return adjustedSize; +} + +class SamsungDeviceQuirks : public QuirksManager::DeviceQuirks { +public: + SamsungDeviceQuirks() { + std::string arch = getPropertyString("ro.arch"); + isExynos = (arch.rfind("exynos", 0) == 0); // starts with? + } + + virtual ~SamsungDeviceQuirks() = default; + + int32_t getExclusiveBottomMarginInBursts() const override { + // TODO Make this conditional on build version when MMAP timing improves. + return isExynos ? kBottomMarginExynos : kBottomMarginOther; + } + + int32_t getExclusiveTopMarginInBursts() const override { + return kTopMargin; + } + +private: + // Stay farther away from DSP position on Exynos devices. + static constexpr int32_t kBottomMarginExynos = 2; + static constexpr int32_t kBottomMarginOther = 1; + static constexpr int32_t kTopMargin = 1; + bool isExynos = false; +}; + +QuirksManager::QuirksManager() { + std::string manufacturer = getPropertyString("ro.product.manufacturer"); + if (manufacturer == "samsung") { + mDeviceQuirks = std::make_unique<SamsungDeviceQuirks>(); + } else { + mDeviceQuirks = std::make_unique<DeviceQuirks>(); + } +} + +bool QuirksManager::isConversionNeeded( + const AudioStreamBuilder &builder, + AudioStreamBuilder &childBuilder) { + bool conversionNeeded = false; + const bool isLowLatency = builder.getPerformanceMode() == PerformanceMode::LowLatency; + const bool isInput = builder.getDirection() == Direction::Input; + const bool isFloat = builder.getFormat() == AudioFormat::Float; + + // If a SAMPLE RATE is specified for low latency then let the native code choose an optimal rate. + // TODO There may be a problem if the devices supports low latency + // at a higher rate than the default. + if (builder.getSampleRate() != oboe::Unspecified + && builder.getSampleRateConversionQuality() != SampleRateConversionQuality::None + && isLowLatency + ) { + childBuilder.setSampleRate(oboe::Unspecified); // native API decides the best sample rate + conversionNeeded = true; + } + + // Data Format + // OpenSL ES and AAudio before P do not support FAST path for FLOAT capture. + if (isFloat + && isInput + && builder.isFormatConversionAllowed() + && isLowLatency + && (!builder.willUseAAudio() || (getSdkVersion() < __ANDROID_API_P__)) + ) { + childBuilder.setFormat(AudioFormat::I16); // needed for FAST track + conversionNeeded = true; + } + + // Channel Count + if (builder.getChannelCount() != oboe::Unspecified + && builder.isChannelConversionAllowed()) { + if (OboeGlobals::areWorkaroundsEnabled() + && builder.getChannelCount() == 2 // stereo? + && isInput + && isLowLatency + && (!builder.willUseAAudio() && (getSdkVersion() == __ANDROID_API_O__))) { + // Workaround for heap size regression in O. + // b/66967812 AudioRecord does not allow FAST track for stereo capture in O + childBuilder.setChannelCount(1); + conversionNeeded = true; + } + // Note that MMAP does not support mono in 8.1. But that would only matter on Pixel 1 + // phones and they have almost all been updated to 9.0. + } + + return conversionNeeded; +} diff --git a/modules/juce_audio_devices/native/oboe/src/common/QuirksManager.h b/modules/juce_audio_devices/native/oboe/src/common/QuirksManager.h new file mode 100644 index 00000000..a177764c --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/common/QuirksManager.h @@ -0,0 +1,110 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBOE_QUIRKS_MANAGER_H +#define OBOE_QUIRKS_MANAGER_H + +#include <memory> +#include <oboe/AudioStreamBuilder.h> +#include <aaudio/AudioStreamAAudio.h> + +namespace oboe { + +/** + * INTERNAL USE ONLY. + * + * Based on manufacturer, model and Android version number + * decide whether data conversion needs to occur. + * + * This also manages device and version specific workarounds. + */ + +class QuirksManager { +public: + + static QuirksManager &getInstance() { + static QuirksManager instance; // singleton + return instance; + } + + QuirksManager(); + virtual ~QuirksManager() = default; + + /** + * Do we need to do channel, format or rate conversion to provide a low latency + * stream for this builder? If so then provide a builder for the native child stream + * that will be used to get low latency. + * + * @param builder builder provided by application + * @param childBuilder modified builder appropriate for the underlying device + * @return true if conversion is needed + */ + bool isConversionNeeded(const AudioStreamBuilder &builder, AudioStreamBuilder &childBuilder); + + static bool isMMapUsed(AudioStream &stream) { + bool answer = false; + if (stream.getAudioApi() == AudioApi::AAudio) { + AudioStreamAAudio *streamAAudio = + reinterpret_cast<AudioStreamAAudio *>(&stream); + answer = streamAAudio->isMMapUsed(); + } + return answer; + } + + virtual int32_t clipBufferSize(AudioStream &stream, int32_t bufferSize) { + return mDeviceQuirks->clipBufferSize(stream, bufferSize); + } + + class DeviceQuirks { + public: + virtual ~DeviceQuirks() = default; + + /** + * Restrict buffer size. This is mainly to avoid glitches caused by MMAP + * timestamp inaccuracies. + * @param stream + * @param requestedSize + * @return + */ + int32_t clipBufferSize(AudioStream &stream, int32_t requestedSize); + + // Exclusive MMAP streams can have glitches because they are using a timing + // model of the DSP to control IO instead of direct synchronization. + virtual int32_t getExclusiveBottomMarginInBursts() const { + return kDefaultBottomMarginInBursts; + } + + virtual int32_t getExclusiveTopMarginInBursts() const { + return kDefaultTopMarginInBursts; + } + + static constexpr int32_t kDefaultBottomMarginInBursts = 0; + static constexpr int32_t kDefaultTopMarginInBursts = 0; + + // For Legacy streams, do not let the buffer go below one burst. + // b/129545119 | AAudio Legacy allows setBufferSizeInFrames too low + // Fixed in Q + static constexpr int32_t kLegacyBottomMarginInBursts = 1; + }; + +private: + + std::unique_ptr<DeviceQuirks> mDeviceQuirks{}; + +}; + +} +#endif //OBOE_QUIRKS_MANAGER_H diff --git a/modules/juce_audio_devices/native/oboe/src/common/SourceFloatCaller.cpp b/modules/juce_audio_devices/native/oboe/src/common/SourceFloatCaller.cpp new file mode 100644 index 00000000..631af853 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/common/SourceFloatCaller.cpp @@ -0,0 +1,30 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <algorithm> +#include <unistd.h> +#include "flowgraph/FlowGraphNode.h" +#include "SourceFloatCaller.h" + +using namespace oboe; +using namespace flowgraph; + +int32_t SourceFloatCaller::onProcess(int32_t numFrames) { + int32_t numBytes = mStream->getBytesPerFrame() * numFrames; + int32_t bytesRead = mBlockReader.read((uint8_t *) output.getBuffer(), numBytes); + int32_t framesRead = bytesRead / mStream->getBytesPerFrame(); + return framesRead; +} diff --git a/modules/juce_audio_devices/native/oboe/src/common/SourceFloatCaller.h b/modules/juce_audio_devices/native/oboe/src/common/SourceFloatCaller.h new file mode 100644 index 00000000..85a15855 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/common/SourceFloatCaller.h @@ -0,0 +1,44 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBOE_SOURCE_FLOAT_CALLER_H +#define OBOE_SOURCE_FLOAT_CALLER_H + +#include <unistd.h> +#include <sys/types.h> + +#include "flowgraph/FlowGraphNode.h" +#include "AudioSourceCaller.h" +#include "FixedBlockReader.h" + +namespace oboe { +/** + * AudioSource that uses callback to get more float data. + */ +class SourceFloatCaller : public AudioSourceCaller { +public: + SourceFloatCaller(int32_t channelCount, int32_t framesPerCallback) + : AudioSourceCaller(channelCount, framesPerCallback, (int32_t)sizeof(float)) {} + + int32_t onProcess(int32_t numFrames) override; + + const char *getName() override { + return "SourceFloatCaller"; + } +}; + +} +#endif //OBOE_SOURCE_FLOAT_CALLER_H diff --git a/modules/juce_audio_devices/native/oboe/src/common/SourceI16Caller.cpp b/modules/juce_audio_devices/native/oboe/src/common/SourceI16Caller.cpp new file mode 100644 index 00000000..2ab372b6 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/common/SourceI16Caller.cpp @@ -0,0 +1,47 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <algorithm> +#include <unistd.h> +#include "flowgraph/FlowGraphNode.h" +#include "SourceI16Caller.h" + +#if FLOWGRAPH_ANDROID_INTERNAL +#include <audio_utils/primitives.h> +#endif + +using namespace oboe; +using namespace flowgraph; + +int32_t SourceI16Caller::onProcess(int32_t numFrames) { + int32_t numBytes = mStream->getBytesPerFrame() * numFrames; + int32_t bytesRead = mBlockReader.read((uint8_t *) mConversionBuffer.get(), numBytes); + int32_t framesRead = bytesRead / mStream->getBytesPerFrame(); + + float *floatData = output.getBuffer(); + const int16_t *shortData = mConversionBuffer.get(); + int32_t numSamples = framesRead * output.getSamplesPerFrame(); + +#if FLOWGRAPH_ANDROID_INTERNAL + memcpy_to_float_from_i16(floatData, shortData, numSamples); +#else + for (int i = 0; i < numSamples; i++) { + *floatData++ = *shortData++ * (1.0f / 32768); + } +#endif + + return framesRead; +} diff --git a/modules/juce_audio_devices/native/oboe/src/common/SourceI16Caller.h b/modules/juce_audio_devices/native/oboe/src/common/SourceI16Caller.h new file mode 100644 index 00000000..22c1b9ab --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/common/SourceI16Caller.h @@ -0,0 +1,48 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBOE_SOURCE_I16_CALLER_H +#define OBOE_SOURCE_I16_CALLER_H + +#include <unistd.h> +#include <sys/types.h> + +#include "flowgraph/FlowGraphNode.h" +#include "AudioSourceCaller.h" +#include "FixedBlockReader.h" + +namespace oboe { +/** + * AudioSource that uses callback to get more data. + */ +class SourceI16Caller : public AudioSourceCaller { +public: + SourceI16Caller(int32_t channelCount, int32_t framesPerCallback) + : AudioSourceCaller(channelCount, framesPerCallback, sizeof(int16_t)) { + mConversionBuffer = std::make_unique<int16_t[]>(channelCount * output.getFramesPerBuffer()); + } + + int32_t onProcess(int32_t numFrames) override; + + const char *getName() override { + return "SourceI16Caller"; + } +private: + std::unique_ptr<int16_t[]> mConversionBuffer; +}; + +} +#endif //OBOE_SOURCE_I16_CALLER_H diff --git a/modules/juce_audio_devices/native/oboe/src/common/StabilizedCallback.cpp b/modules/juce_audio_devices/native/oboe/src/common/StabilizedCallback.cpp new file mode 100644 index 00000000..692db89b --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/common/StabilizedCallback.cpp @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "oboe/StabilizedCallback.h" +#include "common/AudioClock.h" +#include "common/Trace.h" + +constexpr int32_t kLoadGenerationStepSizeNanos = 20000; +constexpr float kPercentageOfCallbackToUse = 0.8; + +using namespace oboe; + +StabilizedCallback::StabilizedCallback(AudioStreamCallback *callback) : mCallback(callback){ + Trace::initialize(); +} + +/** + * An audio callback which attempts to do work for a fixed amount of time. + * + * @param oboeStream + * @param audioData + * @param numFrames + * @return + */ +DataCallbackResult +StabilizedCallback::onAudioReady(AudioStream *oboeStream, void *audioData, int32_t numFrames) { + + int64_t startTimeNanos = AudioClock::getNanoseconds(); + + if (mFrameCount == 0){ + mEpochTimeNanos = startTimeNanos; + } + + int64_t durationSinceEpochNanos = startTimeNanos - mEpochTimeNanos; + + // In an ideal world the callback start time will be exactly the same as the duration of the + // frames already read/written into the stream. In reality the callback can start early + // or late. By finding the delta we can calculate the target duration for our stabilized + // callback. + int64_t idealStartTimeNanos = (mFrameCount * kNanosPerSecond) / oboeStream->getSampleRate(); + int64_t lateStartNanos = durationSinceEpochNanos - idealStartTimeNanos; + + if (lateStartNanos < 0){ + // This was an early start which indicates that our previous epoch was a late callback. + // Update our epoch to this more accurate time. + mEpochTimeNanos = startTimeNanos; + mFrameCount = 0; + } + + int64_t numFramesAsNanos = (numFrames * kNanosPerSecond) / oboeStream->getSampleRate(); + int64_t targetDurationNanos = static_cast<int64_t>( + (numFramesAsNanos * kPercentageOfCallbackToUse) - lateStartNanos); + + Trace::beginSection("Actual load"); + DataCallbackResult result = mCallback->onAudioReady(oboeStream, audioData, numFrames); + Trace::endSection(); + + int64_t executionDurationNanos = AudioClock::getNanoseconds() - startTimeNanos; + int64_t stabilizingLoadDurationNanos = targetDurationNanos - executionDurationNanos; + + Trace::beginSection("Stabilized load for %lldns", stabilizingLoadDurationNanos); + generateLoad(stabilizingLoadDurationNanos); + Trace::endSection(); + + // Wraparound: At 48000 frames per second mFrameCount wraparound will occur after 6m years, + // significantly longer than the average lifetime of an Android phone. + mFrameCount += numFrames; + return result; +} + +void StabilizedCallback::generateLoad(int64_t durationNanos) { + + int64_t currentTimeNanos = AudioClock::getNanoseconds(); + int64_t deadlineTimeNanos = currentTimeNanos + durationNanos; + + // opsPerStep gives us an estimated number of operations which need to be run to fully utilize + // the CPU for a fixed amount of time (specified by kLoadGenerationStepSizeNanos). + // After each step the opsPerStep value is re-calculated based on the actual time taken to + // execute those operations. + auto opsPerStep = (int)(mOpsPerNano * kLoadGenerationStepSizeNanos); + int64_t stepDurationNanos = 0; + int64_t previousTimeNanos = 0; + + while (currentTimeNanos <= deadlineTimeNanos){ + + for (int i = 0; i < opsPerStep; i++) cpu_relax(); + + previousTimeNanos = currentTimeNanos; + currentTimeNanos = AudioClock::getNanoseconds(); + stepDurationNanos = currentTimeNanos - previousTimeNanos; + + // Calculate exponential moving average to smooth out values, this acts as a low pass filter. + // @see https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average + static const float kFilterCoefficient = 0.1; + auto measuredOpsPerNano = (double) opsPerStep / stepDurationNanos; + mOpsPerNano = kFilterCoefficient * measuredOpsPerNano + (1.0 - kFilterCoefficient) * mOpsPerNano; + opsPerStep = (int) (mOpsPerNano * kLoadGenerationStepSizeNanos); + } +} \ No newline at end of file diff --git a/modules/juce_audio_devices/native/oboe/src/common/Trace.cpp b/modules/juce_audio_devices/native/oboe/src/common/Trace.cpp new file mode 100644 index 00000000..5ed445b5 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/common/Trace.cpp @@ -0,0 +1,75 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <dlfcn.h> +#include <cstdio> +#include "Trace.h" +#include "OboeDebug.h" + +static char buffer[256]; + +// Tracing functions +static void *(*ATrace_beginSection)(const char *sectionName); + +static void *(*ATrace_endSection)(); + +typedef void *(*fp_ATrace_beginSection)(const char *sectionName); + +typedef void *(*fp_ATrace_endSection)(); + +bool Trace::mIsTracingSupported = false; + +void Trace::beginSection(const char *format, ...){ + + if (mIsTracingSupported) { + va_list va; + va_start(va, format); + vsprintf(buffer, format, va); + ATrace_beginSection(buffer); + va_end(va); + } else { + LOGE("Tracing is either not initialized (call Trace::initialize()) " + "or not supported on this device"); + } +} + +void Trace::endSection() { + + if (mIsTracingSupported) { + ATrace_endSection(); + } +} + +void Trace::initialize() { + + // Using dlsym allows us to use tracing on API 21+ without needing android/trace.h which wasn't + // published until API 23 + void *lib = dlopen("libandroid.so", RTLD_NOW | RTLD_LOCAL); + if (lib == nullptr) { + LOGE("Could not open libandroid.so to dynamically load tracing symbols"); + } else { + ATrace_beginSection = + reinterpret_cast<fp_ATrace_beginSection >( + dlsym(lib, "ATrace_beginSection")); + ATrace_endSection = + reinterpret_cast<fp_ATrace_endSection >( + dlsym(lib, "ATrace_endSection")); + + if (ATrace_beginSection != nullptr && ATrace_endSection != nullptr){ + mIsTracingSupported = true; + } + } +} \ No newline at end of file diff --git a/modules/juce_audio_devices/native/oboe/src/common/Trace.h b/modules/juce_audio_devices/native/oboe/src/common/Trace.h new file mode 100644 index 00000000..dad6c007 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/common/Trace.h @@ -0,0 +1,31 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBOE_TRACE_H +#define OBOE_TRACE_H + +class Trace { + +public: + static void beginSection(const char *format, ...); + static void endSection(); + static void initialize(); + +private: + static bool mIsTracingSupported; +}; + +#endif //OBOE_TRACE_H diff --git a/modules/juce_audio_devices/native/oboe/src/common/Utilities.cpp b/modules/juce_audio_devices/native/oboe/src/common/Utilities.cpp new file mode 100644 index 00000000..c3acf476 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/common/Utilities.cpp @@ -0,0 +1,305 @@ +/* + * Copyright 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include <stdlib.h> +#include <unistd.h> +#include <sstream> + +#ifdef __ANDROID__ +#include <sys/system_properties.h> +#endif + +#include <oboe/AudioStream.h> +#include "oboe/Definitions.h" +#include "oboe/Utilities.h" + +namespace oboe { + +constexpr float kScaleI16ToFloat = (1.0f / 32768.0f); + +void convertFloatToPcm16(const float *source, int16_t *destination, int32_t numSamples) { + for (int i = 0; i < numSamples; i++) { + float fval = source[i]; + fval += 1.0; // to avoid discontinuity at 0.0 caused by truncation + fval *= 32768.0f; + auto sample = static_cast<int32_t>(fval); + // clip to 16-bit range + if (sample < 0) sample = 0; + else if (sample > 0x0FFFF) sample = 0x0FFFF; + sample -= 32768; // center at zero + destination[i] = static_cast<int16_t>(sample); + } +} + +void convertPcm16ToFloat(const int16_t *source, float *destination, int32_t numSamples) { + for (int i = 0; i < numSamples; i++) { + destination[i] = source[i] * kScaleI16ToFloat; + } +} + +int32_t convertFormatToSizeInBytes(AudioFormat format) { + int32_t size = 0; + switch (format) { + case AudioFormat::I16: + size = sizeof(int16_t); + break; + case AudioFormat::Float: + size = sizeof(float); + break; + default: + break; + } + return size; +} + +template<> +const char *convertToText<Result>(Result returnCode) { + switch (returnCode) { + case Result::OK: return "OK"; + case Result::ErrorDisconnected: return "ErrorDisconnected"; + case Result::ErrorIllegalArgument: return "ErrorIllegalArgument"; + case Result::ErrorInternal: return "ErrorInternal"; + case Result::ErrorInvalidState: return "ErrorInvalidState"; + case Result::ErrorInvalidHandle: return "ErrorInvalidHandle"; + case Result::ErrorUnimplemented: return "ErrorUnimplemented"; + case Result::ErrorUnavailable: return "ErrorUnavailable"; + case Result::ErrorNoFreeHandles: return "ErrorNoFreeHandles"; + case Result::ErrorNoMemory: return "ErrorNoMemory"; + case Result::ErrorNull: return "ErrorNull"; + case Result::ErrorTimeout: return "ErrorTimeout"; + case Result::ErrorWouldBlock: return "ErrorWouldBlock"; + case Result::ErrorInvalidFormat: return "ErrorInvalidFormat"; + case Result::ErrorOutOfRange: return "ErrorOutOfRange"; + case Result::ErrorNoService: return "ErrorNoService"; + case Result::ErrorInvalidRate: return "ErrorInvalidRate"; + case Result::ErrorClosed: return "ErrorClosed"; + default: return "Unrecognized result"; + } +} + +template<> +const char *convertToText<AudioFormat>(AudioFormat format) { + switch (format) { + case AudioFormat::Invalid: return "Invalid"; + case AudioFormat::Unspecified: return "Unspecified"; + case AudioFormat::I16: return "I16"; + case AudioFormat::Float: return "Float"; + default: return "Unrecognized format"; + } +} + +template<> +const char *convertToText<PerformanceMode>(PerformanceMode mode) { + switch (mode) { + case PerformanceMode::LowLatency: return "LowLatency"; + case PerformanceMode::None: return "None"; + case PerformanceMode::PowerSaving: return "PowerSaving"; + default: return "Unrecognized performance mode"; + } +} + +template<> +const char *convertToText<SharingMode>(SharingMode mode) { + switch (mode) { + case SharingMode::Exclusive: return "Exclusive"; + case SharingMode::Shared: return "Shared"; + default: return "Unrecognized sharing mode"; + } +} + +template<> +const char *convertToText<DataCallbackResult>(DataCallbackResult result) { + switch (result) { + case DataCallbackResult::Continue: return "Continue"; + case DataCallbackResult::Stop: return "Stop"; + default: return "Unrecognized data callback result"; + } +} + +template<> +const char *convertToText<Direction>(Direction direction) { + switch (direction) { + case Direction::Input: return "Input"; + case Direction::Output: return "Output"; + default: return "Unrecognized direction"; + } +} + +template<> +const char *convertToText<StreamState>(StreamState state) { + switch (state) { + case StreamState::Closed: return "Closed"; + case StreamState::Closing: return "Closing"; + case StreamState::Disconnected: return "Disconnected"; + case StreamState::Flushed: return "Flushed"; + case StreamState::Flushing: return "Flushing"; + case StreamState::Open: return "Open"; + case StreamState::Paused: return "Paused"; + case StreamState::Pausing: return "Pausing"; + case StreamState::Started: return "Started"; + case StreamState::Starting: return "Starting"; + case StreamState::Stopped: return "Stopped"; + case StreamState::Stopping: return "Stopping"; + case StreamState::Uninitialized: return "Uninitialized"; + case StreamState::Unknown: return "Unknown"; + default: return "Unrecognized stream state"; + } +} + +template<> +const char *convertToText<AudioApi>(AudioApi audioApi) { + + switch (audioApi) { + case AudioApi::Unspecified: return "Unspecified"; + case AudioApi::OpenSLES: return "OpenSLES"; + case AudioApi::AAudio: return "AAudio"; + default: return "Unrecognized audio API"; + } +} + +template<> +const char *convertToText<AudioStream*>(AudioStream* stream) { + static std::string streamText; + std::stringstream s; + + s<<"StreamID: "<< static_cast<void*>(stream)<<std::endl + <<"DeviceId: "<<stream->getDeviceId()<<std::endl + <<"Direction: "<<oboe::convertToText(stream->getDirection())<<std::endl + <<"API type: "<<oboe::convertToText(stream->getAudioApi())<<std::endl + <<"BufferCapacity: "<<stream->getBufferCapacityInFrames()<<std::endl + <<"BufferSize: "<<stream->getBufferSizeInFrames()<<std::endl + <<"FramesPerBurst: "<< stream->getFramesPerBurst()<<std::endl + <<"FramesPerCallback: "<<stream->getFramesPerCallback()<<std::endl + <<"SampleRate: "<<stream->getSampleRate()<<std::endl + <<"ChannelCount: "<<stream->getChannelCount()<<std::endl + <<"Format: "<<oboe::convertToText(stream->getFormat())<<std::endl + <<"SharingMode: "<<oboe::convertToText(stream->getSharingMode())<<std::endl + <<"PerformanceMode: "<<oboe::convertToText(stream->getPerformanceMode()) + <<std::endl + <<"CurrentState: "<<oboe::convertToText(stream->getState())<<std::endl + <<"XRunCount: "<<stream->getXRunCount()<<std::endl + <<"FramesRead: "<<stream->getFramesRead()<<std::endl + <<"FramesWritten: "<<stream->getFramesWritten()<<std::endl; + + streamText = s.str(); + return streamText.c_str(); +} + +template<> +const char *convertToText<Usage>(Usage usage) { + + switch (usage) { + case Usage::Media: return "Media"; + case Usage::VoiceCommunication: return "VoiceCommunication"; + case Usage::VoiceCommunicationSignalling: return "VoiceCommunicationSignalling"; + case Usage::Alarm: return "Alarm"; + case Usage::Notification: return "Notification"; + case Usage::NotificationRingtone: return "NotificationRingtone"; + case Usage::NotificationEvent: return "NotificationEvent"; + case Usage::AssistanceAccessibility: return "AssistanceAccessibility"; + case Usage::AssistanceNavigationGuidance: return "AssistanceNavigationGuidance"; + case Usage::AssistanceSonification: return "AssistanceSonification"; + case Usage::Game: return "Game"; + case Usage::Assistant: return "Assistant"; + default: return "Unrecognized usage"; + } +} + +template<> +const char *convertToText<ContentType>(ContentType contentType) { + + switch (contentType) { + case ContentType::Speech: return "Speech"; + case ContentType::Music: return "Music"; + case ContentType::Movie: return "Movie"; + case ContentType::Sonification: return "Sonification"; + default: return "Unrecognized content type"; + } +} + +template<> +const char *convertToText<InputPreset>(InputPreset inputPreset) { + + switch (inputPreset) { + case InputPreset::Generic: return "Generic"; + case InputPreset::Camcorder: return "Camcorder"; + case InputPreset::VoiceRecognition: return "VoiceRecognition"; + case InputPreset::VoiceCommunication: return "VoiceCommunication"; + case InputPreset::Unprocessed: return "Unprocessed"; + case InputPreset::VoicePerformance: return "VoicePerformance"; + default: return "Unrecognized input preset"; + } +} + +template<> +const char *convertToText<SessionId>(SessionId sessionId) { + + switch (sessionId) { + case SessionId::None: return "None"; + case SessionId::Allocate: return "Allocate"; + default: return "Unrecognized session id"; + } +} + +template<> +const char *convertToText<ChannelCount>(ChannelCount channelCount) { + + switch (channelCount) { + case ChannelCount::Unspecified: return "Unspecified"; + case ChannelCount::Mono: return "Mono"; + case ChannelCount::Stereo: return "Stereo"; + default: return "Unrecognized channel count"; + } +} + +std::string getPropertyString(const char * name) { + std::string result; +#ifdef __ANDROID__ + char valueText[PROP_VALUE_MAX] = {0}; + if (__system_property_get(name, valueText) != 0) { + result = valueText; + } +#else + (void) name; +#endif + return result; +} + +int getPropertyInteger(const char * name, int defaultValue) { + int result = defaultValue; +#ifdef __ANDROID__ + char valueText[PROP_VALUE_MAX] = {0}; + if (__system_property_get(name, valueText) != 0) { + result = atoi(valueText); + } +#else + (void) name; +#endif + return result; +} + +int getSdkVersion() { + static int sCachedSdkVersion = -1; +#ifdef __ANDROID__ + if (sCachedSdkVersion == -1) { + sCachedSdkVersion = getPropertyInteger("ro.build.version.sdk", -1); + } +#endif + return sCachedSdkVersion; +} + +}// namespace oboe diff --git a/modules/juce_audio_devices/native/oboe/src/common/Version.cpp b/modules/juce_audio_devices/native/oboe/src/common/Version.cpp new file mode 100644 index 00000000..481bee76 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/common/Version.cpp @@ -0,0 +1,28 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "oboe/Version.h" + +namespace oboe { + + // This variable enables the version information to be read from the resulting binary e.g. + // by running `objdump -s --section=.data <binary>` + // Please do not optimize or change in any way. + char kVersionText[] = "OboeVersion" OBOE_VERSION_TEXT; + + const char * getVersionText(){ + return kVersionText; + } +} // namespace oboe diff --git a/modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.cpp b/modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.cpp new file mode 100644 index 00000000..8d6b03bb --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.cpp @@ -0,0 +1,182 @@ +/* + * Copyright 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdint.h> +#include <time.h> +#include <memory.h> +#include <cassert> +#include <algorithm> + +#include "common/OboeDebug.h" +#include "fifo/FifoControllerBase.h" +#include "fifo/FifoController.h" +#include "fifo/FifoControllerIndirect.h" +#include "fifo/FifoBuffer.h" +#include "common/AudioClock.h" + +namespace oboe { + +FifoBuffer::FifoBuffer(uint32_t bytesPerFrame, uint32_t capacityInFrames) + : mBytesPerFrame(bytesPerFrame) + , mStorage(nullptr) + , mFramesReadCount(0) + , mFramesUnderrunCount(0) +{ + mFifo = std::make_unique<FifoController>(capacityInFrames); + // allocate buffer + int32_t bytesPerBuffer = bytesPerFrame * capacityInFrames; + mStorage = new uint8_t[bytesPerBuffer]; + mStorageOwned = true; +} + +FifoBuffer::FifoBuffer( uint32_t bytesPerFrame, + uint32_t capacityInFrames, + std::atomic<uint64_t> *readCounterAddress, + std::atomic<uint64_t> *writeCounterAddress, + uint8_t *dataStorageAddress + ) + : mBytesPerFrame(bytesPerFrame) + , mStorage(dataStorageAddress) + , mFramesReadCount(0) + , mFramesUnderrunCount(0) +{ + mFifo = std::make_unique<FifoControllerIndirect>(capacityInFrames, + readCounterAddress, + writeCounterAddress); + mStorage = dataStorageAddress; + mStorageOwned = false; +} + +FifoBuffer::~FifoBuffer() { + if (mStorageOwned) { + delete[] mStorage; + } +} + +int32_t FifoBuffer::convertFramesToBytes(int32_t frames) { + return frames * mBytesPerFrame; +} + +int32_t FifoBuffer::read(void *buffer, int32_t numFrames) { + if (numFrames <= 0) { + return 0; + } + // safe because numFrames is guaranteed positive + uint32_t framesToRead = static_cast<uint32_t>(numFrames); + uint32_t framesAvailable = mFifo->getFullFramesAvailable(); + framesToRead = std::min(framesToRead, framesAvailable); + + uint32_t readIndex = mFifo->getReadIndex(); // ranges 0 to capacity + uint8_t *destination = reinterpret_cast<uint8_t *>(buffer); + uint8_t *source = &mStorage[convertFramesToBytes(readIndex)]; + if ((readIndex + framesToRead) > mFifo->getFrameCapacity()) { + // read in two parts, first part here is at the end of the mStorage buffer + int32_t frames1 = static_cast<int32_t>(mFifo->getFrameCapacity() - readIndex); + int32_t numBytes = convertFramesToBytes(frames1); + if (numBytes < 0) { + return static_cast<int32_t>(Result::ErrorOutOfRange); + } + memcpy(destination, source, static_cast<size_t>(numBytes)); + destination += numBytes; + // read second part, which is at the beginning of mStorage + source = &mStorage[0]; + int32_t frames2 = static_cast<uint32_t>(framesToRead - frames1); + numBytes = convertFramesToBytes(frames2); + if (numBytes < 0) { + return static_cast<int32_t>(Result::ErrorOutOfRange); + } + memcpy(destination, source, static_cast<size_t>(numBytes)); + } else { + // just read in one shot + int32_t numBytes = convertFramesToBytes(framesToRead); + if (numBytes < 0) { + return static_cast<int32_t>(Result::ErrorOutOfRange); + } + memcpy(destination, source, static_cast<size_t>(numBytes)); + } + mFifo->advanceReadIndex(framesToRead); + + return framesToRead; +} + +int32_t FifoBuffer::write(const void *buffer, int32_t numFrames) { + if (numFrames <= 0) { + return 0; + } + // Guaranteed positive. + uint32_t framesToWrite = static_cast<uint32_t>(numFrames); + uint32_t framesAvailable = mFifo->getEmptyFramesAvailable(); + framesToWrite = std::min(framesToWrite, framesAvailable); + + uint32_t writeIndex = mFifo->getWriteIndex(); + int byteIndex = convertFramesToBytes(writeIndex); + const uint8_t *source = reinterpret_cast<const uint8_t *>(buffer); + uint8_t *destination = &mStorage[byteIndex]; + if ((writeIndex + framesToWrite) > mFifo->getFrameCapacity()) { + // write in two parts, first part here + int32_t frames1 = static_cast<uint32_t>(mFifo->getFrameCapacity() - writeIndex); + int32_t numBytes = convertFramesToBytes(frames1); + if (numBytes < 0) { + return static_cast<int32_t>(Result::ErrorOutOfRange); + } + memcpy(destination, source, static_cast<size_t>(numBytes)); + // read second part + source += convertFramesToBytes(frames1); + destination = &mStorage[0]; + int frames2 = static_cast<uint32_t>(framesToWrite - frames1); + numBytes = convertFramesToBytes(frames2); + if (numBytes < 0) { + return static_cast<int32_t>(Result::ErrorOutOfRange); + } + memcpy(destination, source, static_cast<size_t>(numBytes)); + } else { + // just write in one shot + int32_t numBytes = convertFramesToBytes(framesToWrite); + if (numBytes < 0) { + return static_cast<int32_t>(Result::ErrorOutOfRange); + } + memcpy(destination, source, static_cast<size_t>(numBytes)); + } + mFifo->advanceWriteIndex(framesToWrite); + + return framesToWrite; +} + +int32_t FifoBuffer::readNow(void *buffer, int32_t numFrames) { + int32_t framesRead = read(buffer, numFrames); + if (framesRead < 0) { + return framesRead; + } + int32_t framesLeft = numFrames - framesRead; + mFramesReadCount += framesRead; + mFramesUnderrunCount += framesLeft; + // Zero out any samples we could not set. + if (framesLeft > 0) { + uint8_t *destination = reinterpret_cast<uint8_t *>(buffer); + destination += convertFramesToBytes(framesRead); // point to first byte not set + int32_t bytesToZero = convertFramesToBytes(framesLeft); + memset(destination, 0, static_cast<size_t>(bytesToZero)); + } + + return framesRead; +} + + +uint32_t FifoBuffer::getBufferCapacityInFrames() const { + return mFifo->getFrameCapacity(); +} + +} // namespace oboe diff --git a/modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.h b/modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.h new file mode 100644 index 00000000..80186208 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.h @@ -0,0 +1,99 @@ +/* + * Copyright 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBOE_FIFOPROCESSOR_H +#define OBOE_FIFOPROCESSOR_H + +#include <unistd.h> +#include <sys/types.h> + +#include "common/OboeDebug.h" +#include "FifoControllerBase.h" +#include "oboe/Definitions.h" + +namespace oboe { + +class FifoBuffer { +public: + FifoBuffer(uint32_t bytesPerFrame, uint32_t capacityInFrames); + + FifoBuffer(uint32_t bytesPerFrame, + uint32_t capacityInFrames, + std::atomic<uint64_t> *readCounterAddress, + std::atomic<uint64_t> *writeCounterAddress, + uint8_t *dataStorageAddress); + + ~FifoBuffer(); + + int32_t convertFramesToBytes(int32_t frames); + + /** + * Read framesToRead or, if not enough, then read as many as are available. + * @param destination + * @param framesToRead number of frames requested + * @return number of frames actually read + */ + int32_t read(void *destination, int32_t framesToRead); + + int32_t write(const void *source, int32_t framesToWrite); + + uint32_t getBufferCapacityInFrames() const; + + /** + * Calls read(). If all of the frames cannot be read then the remainder of the buffer + * is set to zero. + * + * @param destination + * @param framesToRead number of frames requested + * @return number of frames actually read + */ + int32_t readNow(void *destination, int32_t numFrames); + + uint32_t getFullFramesAvailable() { + return mFifo->getFullFramesAvailable(); + } + + uint32_t getBytesPerFrame() const { + return mBytesPerFrame; + } + + uint64_t getReadCounter() const { + return mFifo->getReadCounter(); + } + + void setReadCounter(uint64_t n) { + mFifo->setReadCounter(n); + } + + uint64_t getWriteCounter() { + return mFifo->getWriteCounter(); + } + void setWriteCounter(uint64_t n) { + mFifo->setWriteCounter(n); + } + +private: + uint32_t mBytesPerFrame; + uint8_t* mStorage; + bool mStorageOwned; // did this object allocate the storage? + std::unique_ptr<FifoControllerBase> mFifo; + uint64_t mFramesReadCount; + uint64_t mFramesUnderrunCount; +}; + +} // namespace oboe + +#endif //OBOE_FIFOPROCESSOR_H diff --git a/modules/juce_audio_devices/native/oboe/src/fifo/FifoController.cpp b/modules/juce_audio_devices/native/oboe/src/fifo/FifoController.cpp new file mode 100644 index 00000000..5590683b --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/fifo/FifoController.cpp @@ -0,0 +1,31 @@ +/* + * Copyright 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <cassert> +#include <sys/types.h> +#include "FifoControllerBase.h" +#include "FifoController.h" + +namespace oboe { + +FifoController::FifoController(uint32_t numFrames) + : FifoControllerBase(numFrames) +{ + setReadCounter(0); + setWriteCounter(0); +} + +} // namespace oboe diff --git a/modules/juce_audio_devices/native/oboe/src/fifo/FifoController.h b/modules/juce_audio_devices/native/oboe/src/fifo/FifoController.h new file mode 100644 index 00000000..6562e6de --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/fifo/FifoController.h @@ -0,0 +1,61 @@ +/* + * Copyright 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NATIVEOBOE_FIFOCONTROLLER_H +#define NATIVEOBOE_FIFOCONTROLLER_H + +#include <sys/types.h> +#include "FifoControllerBase.h" +#include <atomic> + +namespace oboe { + +/** + * A FifoControllerBase with counters contained in the class. + */ +class FifoController : public FifoControllerBase +{ +public: + FifoController(uint32_t bufferSize); + virtual ~FifoController() = default; + + virtual uint64_t getReadCounter() const override { + return mReadCounter.load(std::memory_order_acquire); + } + virtual void setReadCounter(uint64_t n) override { + mReadCounter.store(n, std::memory_order_release); + } + virtual void incrementReadCounter(uint64_t n) override { + mReadCounter.fetch_add(n, std::memory_order_acq_rel); + } + virtual uint64_t getWriteCounter() const override { + return mWriteCounter.load(std::memory_order_acquire); + } + virtual void setWriteCounter(uint64_t n) override { + mWriteCounter.store(n, std::memory_order_release); + } + virtual void incrementWriteCounter(uint64_t n) override { + mWriteCounter.fetch_add(n, std::memory_order_acq_rel); + } + +private: + std::atomic<uint64_t> mReadCounter{}; + std::atomic<uint64_t> mWriteCounter{}; +}; + +} // namespace oboe + +#endif //NATIVEOBOE_FIFOCONTROLLER_H diff --git a/modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.cpp b/modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.cpp new file mode 100644 index 00000000..6aceea0e --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.cpp @@ -0,0 +1,71 @@ +/* + * Copyright 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "FifoControllerBase.h" + +#include <cassert> +#include <sys/types.h> +#include <algorithm> +#include "FifoControllerBase.h" + +#include "common/OboeDebug.h" + +namespace oboe { + +FifoControllerBase::FifoControllerBase(uint32_t capacityInFrames) + : mTotalFrames(capacityInFrames) +{ + // Avoid ridiculously large buffers and the arithmetic wraparound issues that can follow. + assert(capacityInFrames <= (UINT32_MAX / 4)); +} + +uint32_t FifoControllerBase::getFullFramesAvailable() const { + uint64_t writeCounter = getWriteCounter(); + uint64_t readCounter = getReadCounter(); + if (readCounter > writeCounter) { + return 0; + } + uint64_t delta = writeCounter - readCounter; + if (delta >= mTotalFrames) { + return mTotalFrames; + } + // delta is now guaranteed to fit within the range of a uint32_t + return static_cast<uint32_t>(delta); +} + +uint32_t FifoControllerBase::getReadIndex() const { + // % works with non-power of two sizes + return static_cast<uint32_t>(getReadCounter() % mTotalFrames); +} + +void FifoControllerBase::advanceReadIndex(uint32_t numFrames) { + incrementReadCounter(numFrames); +} + +uint32_t FifoControllerBase::getEmptyFramesAvailable() const { + return static_cast<uint32_t>(mTotalFrames - getFullFramesAvailable()); +} + +uint32_t FifoControllerBase::getWriteIndex() const { + // % works with non-power of two sizes + return static_cast<uint32_t>(getWriteCounter() % mTotalFrames); +} + +void FifoControllerBase::advanceWriteIndex(uint32_t numFrames) { + incrementWriteCounter(numFrames); +} + +} // namespace oboe diff --git a/modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.h b/modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.h new file mode 100644 index 00000000..c8041e04 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.h @@ -0,0 +1,93 @@ +/* + * Copyright 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NATIVEOBOE_FIFOCONTROLLERBASE_H +#define NATIVEOBOE_FIFOCONTROLLERBASE_H + +#include <stdint.h> +#include <sys/types.h> + +namespace oboe { + +/** + * Manage the read/write indices of a circular buffer. + * + * The caller is responsible for reading and writing the actual data. + * Note that the span of available frames may not be contiguous. They + * may wrap around from the end to the beginning of the buffer. In that + * case the data must be read or written in at least two blocks of frames. + * + */ + +class FifoControllerBase { + +public: + /** + * @param totalFrames capacity of the circular buffer in frames. + */ + FifoControllerBase(uint32_t totalFrames); + + virtual ~FifoControllerBase() = default; + + /** + * The frames available to read will be calculated from the read and write counters. + * The result will be clipped to the capacity of the buffer. + * If the buffer has underflowed then this will return zero. + * @return number of valid frames available to read. + */ + uint32_t getFullFramesAvailable() const; + + /** + * The index in a circular buffer of the next frame to read. + */ + uint32_t getReadIndex() const; + + /** + * @param numFrames number of frames to advance the read index + */ + void advanceReadIndex(uint32_t numFrames); + + /** + * @return maximum number of frames that can be written without exceeding the threshold. + */ + uint32_t getEmptyFramesAvailable() const; + + /** + * The index in a circular buffer of the next frame to write. + */ + uint32_t getWriteIndex() const; + + /** + * @param numFrames number of frames to advance the write index + */ + void advanceWriteIndex(uint32_t numFrames); + + uint32_t getFrameCapacity() const { return mTotalFrames; } + + virtual uint64_t getReadCounter() const = 0; + virtual void setReadCounter(uint64_t n) = 0; + virtual void incrementReadCounter(uint64_t n) = 0; + virtual uint64_t getWriteCounter() const = 0; + virtual void setWriteCounter(uint64_t n) = 0; + virtual void incrementWriteCounter(uint64_t n) = 0; + +private: + uint32_t mTotalFrames; +}; + +} // namespace oboe + +#endif //NATIVEOBOE_FIFOCONTROLLERBASE_H diff --git a/modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.cpp b/modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.cpp new file mode 100644 index 00000000..f596461f --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.cpp @@ -0,0 +1,31 @@ +/* + * Copyright 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include "FifoControllerIndirect.h" + +namespace oboe { + +FifoControllerIndirect::FifoControllerIndirect(uint32_t numFrames, + std::atomic<uint64_t> *readCounterAddress, + std::atomic<uint64_t> *writeCounterAddress) + : FifoControllerBase(numFrames) + , mReadCounterAddress(readCounterAddress) + , mWriteCounterAddress(writeCounterAddress) +{ +} + +} diff --git a/modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.h b/modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.h new file mode 100644 index 00000000..216a28b5 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.h @@ -0,0 +1,64 @@ +/* + * Copyright 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NATIVEOBOE_FIFOCONTROLLERINDIRECT_H +#define NATIVEOBOE_FIFOCONTROLLERINDIRECT_H + +#include "FifoControllerBase.h" +#include <atomic> + +namespace oboe { + +/** + * A FifoControllerBase with counters external to the class. + */ +class FifoControllerIndirect : public FifoControllerBase { + +public: + FifoControllerIndirect(uint32_t bufferSize, + std::atomic<uint64_t> *readCounterAddress, + std::atomic<uint64_t> *writeCounterAddress); + virtual ~FifoControllerIndirect() = default; + + virtual uint64_t getReadCounter() const override { + return mReadCounterAddress->load(std::memory_order_acquire); + } + virtual void setReadCounter(uint64_t n) override { + mReadCounterAddress->store(n, std::memory_order_release); + } + virtual void incrementReadCounter(uint64_t n) override { + mReadCounterAddress->fetch_add(n, std::memory_order_acq_rel); + } + virtual uint64_t getWriteCounter() const override { + return mWriteCounterAddress->load(std::memory_order_acquire); + } + virtual void setWriteCounter(uint64_t n) override { + mWriteCounterAddress->store(n, std::memory_order_release); + } + virtual void incrementWriteCounter(uint64_t n) override { + mWriteCounterAddress->fetch_add(n, std::memory_order_acq_rel); + } + +private: + + std::atomic<uint64_t> *mReadCounterAddress; + std::atomic<uint64_t> *mWriteCounterAddress; + +}; + +} // namespace oboe + +#endif //NATIVEOBOE_FIFOCONTROLLERINDIRECT_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/ClipToRange.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/ClipToRange.cpp new file mode 100644 index 00000000..d2f8a02a --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/ClipToRange.cpp @@ -0,0 +1,38 @@ +/* + * Copyright 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <algorithm> +#include <unistd.h> +#include "FlowGraphNode.h" +#include "ClipToRange.h" + +using namespace flowgraph; + +ClipToRange::ClipToRange(int32_t channelCount) + : FlowGraphFilter(channelCount) { +} + +int32_t ClipToRange::onProcess(int32_t numFrames) { + const float *inputBuffer = input.getBuffer(); + float *outputBuffer = output.getBuffer(); + + int32_t numSamples = numFrames * output.getSamplesPerFrame(); + for (int32_t i = 0; i < numSamples; i++) { + *outputBuffer++ = std::min(mMaximum, std::max(mMinimum, *inputBuffer++)); + } + + return numFrames; +} diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/ClipToRange.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/ClipToRange.h new file mode 100644 index 00000000..22b78049 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/ClipToRange.h @@ -0,0 +1,68 @@ +/* + * Copyright 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FLOWGRAPH_CLIP_TO_RANGE_H +#define FLOWGRAPH_CLIP_TO_RANGE_H + +#include <atomic> +#include <unistd.h> +#include <sys/types.h> + +#include "FlowGraphNode.h" + +namespace flowgraph { + +// This is 3 dB, (10^(3/20)), to match the maximum headroom in AudioTrack for float data. +// It is designed to allow occasional transient peaks. +constexpr float kDefaultMaxHeadroom = 1.41253754f; +constexpr float kDefaultMinHeadroom = -kDefaultMaxHeadroom; + +class ClipToRange : public FlowGraphFilter { +public: + explicit ClipToRange(int32_t channelCount); + + virtual ~ClipToRange() = default; + + int32_t onProcess(int32_t numFrames) override; + + void setMinimum(float min) { + mMinimum = min; + } + + float getMinimum() const { + return mMinimum; + } + + void setMaximum(float min) { + mMaximum = min; + } + + float getMaximum() const { + return mMaximum; + } + + const char *getName() override { + return "ClipToRange"; + } + +private: + float mMinimum = kDefaultMinHeadroom; + float mMaximum = kDefaultMaxHeadroom; +}; + +} /* namespace flowgraph */ + +#endif //FLOWGRAPH_CLIP_TO_RANGE_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.cpp new file mode 100644 index 00000000..bb6ecc9f --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.cpp @@ -0,0 +1,111 @@ +/* + * Copyright 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "stdio.h" +#include <algorithm> +#include <sys/types.h> +#include "FlowGraphNode.h" + +using namespace flowgraph; + +/***************************************************************************/ +int32_t FlowGraphNode::pullData(int64_t framePosition, int32_t numFrames) { + int32_t frameCount = numFrames; + // Prevent recursion and multiple execution of nodes. + if (framePosition <= mLastFramePosition && !mBlockRecursion) { + mBlockRecursion = true; // for cyclic graphs + if (mDataPulledAutomatically) { + // Pull from all the upstream nodes. + for (auto &port : mInputPorts) { + // TODO fix bug of leaving unused data in some ports if using multiple AudioSource + frameCount = port.get().pullData(framePosition, frameCount); + } + } + if (frameCount > 0) { + frameCount = onProcess(frameCount); + } + mLastFramePosition += frameCount; + mBlockRecursion = false; + mLastFrameCount = frameCount; + } else { + frameCount = mLastFrameCount; + } + return frameCount; +} + +void FlowGraphNode::pullReset() { + if (!mBlockRecursion) { + mBlockRecursion = true; // for cyclic graphs + // Pull reset from all the upstream nodes. + for (auto &port : mInputPorts) { + port.get().pullReset(); + } + mBlockRecursion = false; + reset(); + } +} + +void FlowGraphNode::reset() { + mLastFrameCount = 0; +} + +/***************************************************************************/ +FlowGraphPortFloat::FlowGraphPortFloat(FlowGraphNode &parent, + int32_t samplesPerFrame, + int32_t framesPerBuffer) + : FlowGraphPort(parent, samplesPerFrame) + , mFramesPerBuffer(framesPerBuffer) + , mBuffer(nullptr) { + size_t numFloats = static_cast<size_t>(framesPerBuffer * getSamplesPerFrame()); + mBuffer = std::make_unique<float[]>(numFloats); +} + +/***************************************************************************/ +int32_t FlowGraphPortFloatOutput::pullData(int64_t framePosition, int32_t numFrames) { + numFrames = std::min(getFramesPerBuffer(), numFrames); + return mContainingNode.pullData(framePosition, numFrames); +} + +void FlowGraphPortFloatOutput::pullReset() { + mContainingNode.pullReset(); +} + +// These need to be in the .cpp file because of forward cross references. +void FlowGraphPortFloatOutput::connect(FlowGraphPortFloatInput *port) { + port->connect(this); +} + +void FlowGraphPortFloatOutput::disconnect(FlowGraphPortFloatInput *port) { + port->disconnect(this); +} + +/***************************************************************************/ +int32_t FlowGraphPortFloatInput::pullData(int64_t framePosition, int32_t numFrames) { + return (mConnected == nullptr) + ? std::min(getFramesPerBuffer(), numFrames) + : mConnected->pullData(framePosition, numFrames); +} +void FlowGraphPortFloatInput::pullReset() { + if (mConnected != nullptr) mConnected->pullReset(); +} + +float *FlowGraphPortFloatInput::getBuffer() { + if (mConnected == nullptr) { + return FlowGraphPortFloat::getBuffer(); // loaded using setValue() + } else { + return mConnected->getBuffer(); + } +} diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.h new file mode 100644 index 00000000..007131e4 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.h @@ -0,0 +1,422 @@ +/* + * Copyright 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * FlowGraph.h + * + * Processing node and ports that can be used in a simple data flow graph. + * This was designed to work with audio but could be used for other + * types of data. + */ + +#ifndef FLOWGRAPH_FLOW_GRAPH_NODE_H +#define FLOWGRAPH_FLOW_GRAPH_NODE_H + +#include <cassert> +#include <cstring> +#include <math.h> +#include <memory> +#include <sys/types.h> +#include <time.h> +#include <unistd.h> +#include <vector> + +// TODO Move these classes into separate files. +// TODO Review use of raw pointers for connect(). Maybe use smart pointers but need to avoid +// run-time deallocation in audio thread. + +// Set this to 1 if using it inside the Android framework. +// This code is kept here so that it can be moved easily between Oboe and AAudio. +#define FLOWGRAPH_ANDROID_INTERNAL 0 + +namespace flowgraph { + +// Default block size that can be overridden when the FlowGraphPortFloat is created. +// If it is too small then we will have too much overhead from switching between nodes. +// If it is too high then we will thrash the caches. +constexpr int kDefaultBufferSize = 8; // arbitrary + +class FlowGraphPort; +class FlowGraphPortFloatInput; + +/***************************************************************************/ +/** + * Base class for all nodes in the flowgraph. + */ +class FlowGraphNode { +public: + FlowGraphNode() {} + virtual ~FlowGraphNode() = default; + + /** + * Read from the input ports, + * generate multiple frames of data then write the results to the output ports. + * + * @param numFrames maximum number of frames requested for processing + * @return number of frames actually processed + */ + virtual int32_t onProcess(int32_t numFrames) = 0; + + /** + * If the framePosition is at or after the last frame position then call onProcess(). + * This prevents infinite recursion in case of cyclic graphs. + * It also prevents nodes upstream from a branch from being executed twice. + * + * @param framePosition + * @param numFrames + * @return number of frames valid + */ + int32_t pullData(int64_t framePosition, int32_t numFrames); + + /** + * Recursively reset all the nodes in the graph, starting from a Sink. + * + * This must not be called at the same time as pullData! + */ + void pullReset(); + + /** + * Reset framePosition counters. + */ + virtual void reset(); + + void addInputPort(FlowGraphPort &port) { + mInputPorts.push_back(port); + } + + bool isDataPulledAutomatically() const { + return mDataPulledAutomatically; + } + + /** + * Set true if you want the data pulled through the graph automatically. + * This is the default. + * + * Set false if you want to pull the data from the input ports in the onProcess() method. + * You might do this, for example, in a sample rate converting node. + * + * @param automatic + */ + void setDataPulledAutomatically(bool automatic) { + mDataPulledAutomatically = automatic; + } + + virtual const char *getName() { + return "FlowGraph"; + } + + int64_t getLastFramePosition() { + return mLastFramePosition; + } + +protected: + int64_t mLastFramePosition = 0; + + std::vector<std::reference_wrapper<FlowGraphPort>> mInputPorts; + +private: + bool mDataPulledAutomatically = true; + bool mBlockRecursion = false; + int32_t mLastFrameCount = 0; + +}; + +/***************************************************************************/ +/** + * This is a connector that allows data to flow between modules. + * + * The ports are the primary means of interacting with a module. + * So they are generally declared as public. + * + */ +class FlowGraphPort { +public: + FlowGraphPort(FlowGraphNode &parent, int32_t samplesPerFrame) + : mContainingNode(parent) + , mSamplesPerFrame(samplesPerFrame) { + } + + // Ports are often declared public. So let's make them non-copyable. + FlowGraphPort(const FlowGraphPort&) = delete; + FlowGraphPort& operator=(const FlowGraphPort&) = delete; + + int32_t getSamplesPerFrame() const { + return mSamplesPerFrame; + } + + virtual int32_t pullData(int64_t framePosition, int32_t numFrames) = 0; + + virtual void pullReset() {} + +protected: + FlowGraphNode &mContainingNode; + +private: + const int32_t mSamplesPerFrame = 1; +}; + +/***************************************************************************/ +/** + * This port contains a 32-bit float buffer that can contain several frames of data. + * Processing the data in a block improves performance. + * + * The size is framesPerBuffer * samplesPerFrame). + */ +class FlowGraphPortFloat : public FlowGraphPort { +public: + FlowGraphPortFloat(FlowGraphNode &parent, + int32_t samplesPerFrame, + int32_t framesPerBuffer = kDefaultBufferSize + ); + + virtual ~FlowGraphPortFloat() = default; + + int32_t getFramesPerBuffer() const { + return mFramesPerBuffer; + } + +protected: + + /** + * @return buffer internal to the port or from a connected port + */ + virtual float *getBuffer() { + return mBuffer.get(); + } + +private: + const int32_t mFramesPerBuffer = 1; + std::unique_ptr<float[]> mBuffer; // allocated in constructor +}; + +/***************************************************************************/ +/** + * The results of a node's processing are stored in the buffers of the output ports. + */ +class FlowGraphPortFloatOutput : public FlowGraphPortFloat { +public: + FlowGraphPortFloatOutput(FlowGraphNode &parent, int32_t samplesPerFrame) + : FlowGraphPortFloat(parent, samplesPerFrame) { + } + + virtual ~FlowGraphPortFloatOutput() = default; + + using FlowGraphPortFloat::getBuffer; + + /** + * Connect to the input of another module. + * An input port can only have one connection. + * An output port can have multiple connections. + * If you connect a second output port to an input port + * then it overwrites the previous connection. + * + * This not thread safe. Do not modify the graph topology from another thread while running. + * Also do not delete a module while it is connected to another port if the graph is running. + */ + void connect(FlowGraphPortFloatInput *port); + + /** + * Disconnect from the input of another module. + * This not thread safe. + */ + void disconnect(FlowGraphPortFloatInput *port); + + /** + * Call the parent module's onProcess() method. + * That may pull data from its inputs and recursively + * process the entire graph. + * @return number of frames actually pulled + */ + int32_t pullData(int64_t framePosition, int32_t numFrames) override; + + + void pullReset() override; + +}; + +/***************************************************************************/ + +/** + * An input port for streaming audio data. + * You can set a value that will be used for processing. + * If you connect an output port to this port then its value will be used instead. + */ +class FlowGraphPortFloatInput : public FlowGraphPortFloat { +public: + FlowGraphPortFloatInput(FlowGraphNode &parent, int32_t samplesPerFrame) + : FlowGraphPortFloat(parent, samplesPerFrame) { + // Add to parent so it can pull data from each input. + parent.addInputPort(*this); + } + + virtual ~FlowGraphPortFloatInput() = default; + + /** + * If connected to an output port then this will return + * that output ports buffers. + * If not connected then it returns the input ports own buffer + * which can be loaded using setValue(). + */ + float *getBuffer() override; + + /** + * Write every value of the float buffer. + * This value will be ignored if an output port is connected + * to this port. + */ + void setValue(float value) { + int numFloats = kDefaultBufferSize * getSamplesPerFrame(); + float *buffer = getBuffer(); + for (int i = 0; i < numFloats; i++) { + *buffer++ = value; + } + } + + /** + * Connect to the output of another module. + * An input port can only have one connection. + * An output port can have multiple connections. + * This not thread safe. + */ + void connect(FlowGraphPortFloatOutput *port) { + assert(getSamplesPerFrame() == port->getSamplesPerFrame()); + mConnected = port; + } + + void disconnect(FlowGraphPortFloatOutput *port) { + assert(mConnected == port); + (void) port; + mConnected = nullptr; + } + + void disconnect() { + mConnected = nullptr; + } + + /** + * Pull data from any output port that is connected. + */ + int32_t pullData(int64_t framePosition, int32_t numFrames) override; + + void pullReset() override; + +private: + FlowGraphPortFloatOutput *mConnected = nullptr; +}; + +/***************************************************************************/ + +/** + * Base class for an edge node in a graph that has no upstream nodes. + * It outputs data but does not consume data. + * By default, it will read its data from an external buffer. + */ +class FlowGraphSource : public FlowGraphNode { +public: + explicit FlowGraphSource(int32_t channelCount) + : output(*this, channelCount) { + } + + virtual ~FlowGraphSource() = default; + + FlowGraphPortFloatOutput output; +}; + +/***************************************************************************/ + +/** + * Base class for an edge node in a graph that has no upstream nodes. + * It outputs data but does not consume data. + * By default, it will read its data from an external buffer. + */ +class FlowGraphSourceBuffered : public FlowGraphSource { +public: + explicit FlowGraphSourceBuffered(int32_t channelCount) + : FlowGraphSource(channelCount) {} + + virtual ~FlowGraphSourceBuffered() = default; + + /** + * Specify buffer that the node will read from. + * + * @param data TODO Consider using std::shared_ptr. + * @param numFrames + */ + void setData(const void *data, int32_t numFrames) { + mData = data; + mSizeInFrames = numFrames; + mFrameIndex = 0; + } + +protected: + const void *mData = nullptr; + int32_t mSizeInFrames = 0; // number of frames in mData + int32_t mFrameIndex = 0; // index of next frame to be processed +}; + +/***************************************************************************/ +/** + * Base class for an edge node in a graph that has no downstream nodes. + * It consumes data but does not output data. + * This graph will be executed when data is read() from this node + * by pulling data from upstream nodes. + */ +class FlowGraphSink : public FlowGraphNode { +public: + explicit FlowGraphSink(int32_t channelCount) + : input(*this, channelCount) { + } + + virtual ~FlowGraphSink() = default; + + FlowGraphPortFloatInput input; + + /** + * Dummy processor. The work happens in the read() method. + * + * @param numFrames + * @return number of frames actually processed + */ + int32_t onProcess(int32_t numFrames) override { + return numFrames; + } + + virtual int32_t read(int64_t framePosition, void *data, int32_t numFrames) = 0; + +}; + +/***************************************************************************/ +/** + * Base class for a node that has an input and an output with the same number of channels. + * This may include traditional filters, eg. FIR, but also include + * any processing node that converts input to output. + */ +class FlowGraphFilter : public FlowGraphNode { +public: + explicit FlowGraphFilter(int32_t channelCount) + : input(*this, channelCount) + , output(*this, channelCount) { + } + + virtual ~FlowGraphFilter() = default; + + FlowGraphPortFloatInput input; + FlowGraphPortFloatOutput output; +}; + +} /* namespace flowgraph */ + +#endif /* FLOWGRAPH_FLOW_GRAPH_NODE_H */ diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.cpp new file mode 100644 index 00000000..879685e8 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.cpp @@ -0,0 +1,47 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <unistd.h> + +#include "ManyToMultiConverter.h" + +using namespace flowgraph; + +ManyToMultiConverter::ManyToMultiConverter(int32_t channelCount) + : inputs(channelCount) + , output(*this, channelCount) { + for (int i = 0; i < channelCount; i++) { + inputs[i] = std::make_unique<FlowGraphPortFloatInput>(*this, 1); + } +} + +int32_t ManyToMultiConverter::onProcess(int32_t numFrames) { + int32_t channelCount = output.getSamplesPerFrame(); + + for (int ch = 0; ch < channelCount; ch++) { + const float *inputBuffer = inputs[ch]->getBuffer(); + float *outputBuffer = output.getBuffer() + ch; + + for (int i = 0; i < numFrames; i++) { + // read one, write into the proper interleaved output channel + float sample = *inputBuffer++; + *outputBuffer = sample; + outputBuffer += channelCount; // advance to next multichannel frame + } + } + return numFrames; +} + diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.h new file mode 100644 index 00000000..eca4a8ed --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.h @@ -0,0 +1,49 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FLOWGRAPH_MANY_TO_MULTI_CONVERTER_H +#define FLOWGRAPH_MANY_TO_MULTI_CONVERTER_H + +#include <unistd.h> +#include <sys/types.h> +#include <vector> + +#include "FlowGraphNode.h" + +/** + * Combine multiple mono inputs into one interleaved multi-channel output. + */ +class ManyToMultiConverter : public flowgraph::FlowGraphNode { +public: + explicit ManyToMultiConverter(int32_t channelCount); + + virtual ~ManyToMultiConverter() = default; + + int32_t onProcess(int numFrames) override; + + void setEnabled(bool enabled) {} + + std::vector<std::unique_ptr<flowgraph::FlowGraphPortFloatInput>> inputs; + flowgraph::FlowGraphPortFloatOutput output; + + const char *getName() override { + return "ManyToMultiConverter"; + } + +private: +}; + +#endif //FLOWGRAPH_MANY_TO_MULTI_CONVERTER_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.cpp new file mode 100644 index 00000000..11cea788 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.cpp @@ -0,0 +1,43 @@ +/* + * Copyright 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <unistd.h> +#include "FlowGraphNode.h" +#include "MonoToMultiConverter.h" + +using namespace flowgraph; + +MonoToMultiConverter::MonoToMultiConverter(int32_t channelCount) + : input(*this, 1) + , output(*this, channelCount) { +} + +MonoToMultiConverter::~MonoToMultiConverter() { } + +int32_t MonoToMultiConverter::onProcess(int32_t numFrames) { + const float *inputBuffer = input.getBuffer(); + float *outputBuffer = output.getBuffer(); + int32_t channelCount = output.getSamplesPerFrame(); + for (int i = 0; i < numFrames; i++) { + // read one, write many + float sample = *inputBuffer++; + for (int channel = 0; channel < channelCount; channel++) { + *outputBuffer++ = sample; + } + } + return numFrames; +} + diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.h new file mode 100644 index 00000000..376f7a37 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.h @@ -0,0 +1,49 @@ +/* + * Copyright 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FLOWGRAPH_MONO_TO_MULTI_CONVERTER_H +#define FLOWGRAPH_MONO_TO_MULTI_CONVERTER_H + +#include <unistd.h> +#include <sys/types.h> + +#include "FlowGraphNode.h" + +namespace flowgraph { + +/** + * Convert a monophonic stream to a multi-channel stream + * with the same signal on each channel. + */ +class MonoToMultiConverter : public FlowGraphNode { +public: + explicit MonoToMultiConverter(int32_t channelCount); + + virtual ~MonoToMultiConverter(); + + int32_t onProcess(int32_t numFrames) override; + + const char *getName() override { + return "MonoToMultiConverter"; + } + + FlowGraphPortFloatInput input; + FlowGraphPortFloatOutput output; +}; + +} /* namespace flowgraph */ + +#endif //FLOWGRAPH_MONO_TO_MULTI_CONVERTER_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/RampLinear.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/RampLinear.cpp new file mode 100644 index 00000000..afef0181 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/RampLinear.cpp @@ -0,0 +1,77 @@ +/* + * Copyright 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <algorithm> +#include <unistd.h> +#include "FlowGraphNode.h" +#include "RampLinear.h" + +using namespace flowgraph; + +RampLinear::RampLinear(int32_t channelCount) + : FlowGraphFilter(channelCount) { + mTarget.store(1.0f); +} + +void RampLinear::setLengthInFrames(int32_t frames) { + mLengthInFrames = frames; +} + +void RampLinear::setTarget(float target) { + mTarget.store(target); +} + +float RampLinear::interpolateCurrent() { + return mLevelTo - (mRemaining * mScaler); +} + +int32_t RampLinear::onProcess(int32_t numFrames) { + const float *inputBuffer = input.getBuffer(); + float *outputBuffer = output.getBuffer(); + int32_t channelCount = output.getSamplesPerFrame(); + + float target = getTarget(); + if (target != mLevelTo) { + // Start new ramp. Continue from previous level. + mLevelFrom = interpolateCurrent(); + mLevelTo = target; + mRemaining = mLengthInFrames; + mScaler = (mLevelTo - mLevelFrom) / mLengthInFrames; // for interpolation + } + + int32_t framesLeft = numFrames; + + if (mRemaining > 0) { // Ramping? This doesn't happen very often. + int32_t framesToRamp = std::min(framesLeft, mRemaining); + framesLeft -= framesToRamp; + while (framesToRamp > 0) { + float currentLevel = interpolateCurrent(); + for (int ch = 0; ch < channelCount; ch++) { + *outputBuffer++ = *inputBuffer++ * currentLevel; + } + mRemaining--; + framesToRamp--; + } + } + + // Process any frames after the ramp. + int32_t samplesLeft = framesLeft * channelCount; + for (int i = 0; i < samplesLeft; i++) { + *outputBuffer++ = *inputBuffer++ * mLevelTo; + } + + return numFrames; +} diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/RampLinear.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/RampLinear.h new file mode 100644 index 00000000..f285704c --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/RampLinear.h @@ -0,0 +1,96 @@ +/* + * Copyright 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FLOWGRAPH_RAMP_LINEAR_H +#define FLOWGRAPH_RAMP_LINEAR_H + +#include <atomic> +#include <unistd.h> +#include <sys/types.h> + +#include "FlowGraphNode.h" + +namespace flowgraph { + +/** + * When the target is modified then the output will ramp smoothly + * between the original and the new target value. + * This can be used to smooth out control values and reduce pops. + * + * The target may be updated while a ramp is in progress, which will trigger + * a new ramp from the current value. + */ +class RampLinear : public FlowGraphFilter { +public: + explicit RampLinear(int32_t channelCount); + + virtual ~RampLinear() = default; + + int32_t onProcess(int32_t numFrames) override; + + /** + * This is used for the next ramp. + * Calling this does not affect a ramp that is in progress. + */ + void setLengthInFrames(int32_t frames); + + int32_t getLengthInFrames() const { + return mLengthInFrames; + } + + /** + * This may be safely called by another thread. + * @param target + */ + void setTarget(float target); + + float getTarget() const { + return mTarget.load(); + } + + /** + * Force the nextSegment to start from this level. + * + * WARNING: this can cause a discontinuity if called while the ramp is being used. + * Only call this when setting the initial ramp. + * + * @param level + */ + void forceCurrent(float level) { + mLevelFrom = level; + mLevelTo = level; + } + + const char *getName() override { + return "RampLinear"; + } + +private: + + float interpolateCurrent(); + + std::atomic<float> mTarget; + + int32_t mLengthInFrames = 48000.0f / 100.0f ; // 10 msec at 48000 Hz; + int32_t mRemaining = 0; + float mScaler = 0.0f; + float mLevelFrom = 0.0f; + float mLevelTo = 0.0f; +}; + +} /* namespace flowgraph */ + +#endif //FLOWGRAPH_RAMP_LINEAR_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/SampleRateConverter.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/SampleRateConverter.cpp new file mode 100644 index 00000000..708c684f --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/SampleRateConverter.cpp @@ -0,0 +1,64 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "SampleRateConverter.h" + +using namespace flowgraph; +using namespace resampler; + +SampleRateConverter::SampleRateConverter(int32_t channelCount, MultiChannelResampler &resampler) + : FlowGraphFilter(channelCount) + , mResampler(resampler) { + setDataPulledAutomatically(false); +} + +// Return true if there is a sample available. +bool SampleRateConverter::isInputAvailable() { + if (mInputCursor >= mNumValidInputFrames) { + mNumValidInputFrames = input.pullData(mInputFramePosition, input.getFramesPerBuffer()); + mInputFramePosition += mNumValidInputFrames; + mInputCursor = 0; + } + return (mInputCursor < mNumValidInputFrames); +} + +const float *SampleRateConverter::getNextInputFrame() { + const float *inputBuffer = input.getBuffer(); + return &inputBuffer[mInputCursor++ * input.getSamplesPerFrame()]; +} + +int32_t SampleRateConverter::onProcess(int32_t numFrames) { + float *outputBuffer = output.getBuffer(); + int32_t channelCount = output.getSamplesPerFrame(); + int framesLeft = numFrames; + while (framesLeft > 0) { + // Gather input samples as needed. + if(mResampler.isWriteNeeded()) { + if (isInputAvailable()) { + const float *frame = getNextInputFrame(); + mResampler.writeNextFrame(frame); + } else { + break; + } + } else { + // Output frame is interpolated from input samples. + mResampler.readNextFrame(outputBuffer); + outputBuffer += channelCount; + framesLeft--; + } + } + return numFrames - framesLeft; +} diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/SampleRateConverter.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/SampleRateConverter.h new file mode 100644 index 00000000..d940b22b --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/SampleRateConverter.h @@ -0,0 +1,56 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBOE_SAMPLE_RATE_CONVERTER_H +#define OBOE_SAMPLE_RATE_CONVERTER_H + +#include <unistd.h> +#include <sys/types.h> + +#include "FlowGraphNode.h" +#include "resampler/MultiChannelResampler.h" + +namespace flowgraph { + +class SampleRateConverter : public FlowGraphFilter { +public: + explicit SampleRateConverter(int32_t channelCount, resampler::MultiChannelResampler &mResampler); + + virtual ~SampleRateConverter() = default; + + int32_t onProcess(int32_t numFrames) override; + + const char *getName() override { + return "SampleRateConverter"; + } + +private: + + // Return true if there is a sample available. + bool isInputAvailable(); + + // This assumes data is available. Only call after calling isInputAvailable(). + const float *getNextInputFrame(); + + resampler::MultiChannelResampler &mResampler; + + int32_t mInputCursor = 0; + int32_t mNumValidInputFrames = 0; + int64_t mInputFramePosition = 0; // monotonic counter of input frames used for pullData + +}; +} /* namespace flowgraph */ +#endif //OBOE_SAMPLE_RATE_CONVERTER_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkFloat.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkFloat.cpp new file mode 100644 index 00000000..f830dafd --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkFloat.cpp @@ -0,0 +1,50 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <algorithm> +#include <unistd.h> +#include "FlowGraphNode.h" +#include "SinkFloat.h" + +using namespace flowgraph; + +SinkFloat::SinkFloat(int32_t channelCount) + : FlowGraphSink(channelCount) { +} + +int32_t SinkFloat::read(int64_t framePosition, void *data, int32_t numFrames) { + // printf("SinkFloat::read(,,%d)\n", numFrames); + float *floatData = (float *) data; + int32_t channelCount = input.getSamplesPerFrame(); + + int32_t framesLeft = numFrames; + while (framesLeft > 0) { + // Run the graph and pull data through the input port. + int32_t framesPulled = pullData(framePosition, framesLeft); + // printf("SinkFloat::read: framesLeft = %d, framesPulled = %d\n", framesLeft, framesPulled); + if (framesPulled <= 0) { + break; + } + const float *signal = input.getBuffer(); + int32_t numSamples = framesPulled * channelCount; + memcpy(floatData, signal, numSamples * sizeof(float)); + floatData += numSamples; + framesLeft -= framesPulled; + framePosition += framesPulled; + } + // printf("SinkFloat returning %d\n", numFrames - framesLeft); + return numFrames - framesLeft; +} diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkFloat.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkFloat.h new file mode 100644 index 00000000..b6474d18 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkFloat.h @@ -0,0 +1,44 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef FLOWGRAPH_SINK_FLOAT_H +#define FLOWGRAPH_SINK_FLOAT_H + +#include <unistd.h> +#include <sys/types.h> + +#include "FlowGraphNode.h" + +namespace flowgraph { + +/** + * AudioSink that lets you read data as 32-bit floats. + */ +class SinkFloat : public FlowGraphSink { +public: + explicit SinkFloat(int32_t channelCount); + + int32_t read(int64_t framePosition, void *data, int32_t numFrames) override; + + const char *getName() override { + return "SinkFloat"; + } +}; + +} /* namespace flowgraph */ + +#endif //FLOWGRAPH_SINK_FLOAT_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI16.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI16.cpp new file mode 100644 index 00000000..a5904e82 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI16.cpp @@ -0,0 +1,58 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <algorithm> +#include <unistd.h> + +#include "SinkI16.h" + +#if FLOWGRAPH_ANDROID_INTERNAL +#include <audio_utils/primitives.h> +#endif + +using namespace flowgraph; + +SinkI16::SinkI16(int32_t channelCount) + : FlowGraphSink(channelCount) {} + +int32_t SinkI16::read(int64_t framePosition, void *data, int32_t numFrames) { + int16_t *shortData = (int16_t *) data; + const int32_t channelCount = input.getSamplesPerFrame(); + + int32_t framesLeft = numFrames; + while (framesLeft > 0) { + // Run the graph and pull data through the input port. + int32_t framesRead = pullData(framePosition, framesLeft); + if (framesRead <= 0) { + break; + } + const float *signal = input.getBuffer(); + int32_t numSamples = framesRead * channelCount; +#if FLOWGRAPH_ANDROID_INTERNAL + memcpy_to_i16_from_float(shortData, signal, numSamples); + shortData += numSamples; + signal += numSamples; +#else + for (int i = 0; i < numSamples; i++) { + int32_t n = (int32_t) (*signal++ * 32768.0f); + *shortData++ = std::min(INT16_MAX, std::max(INT16_MIN, n)); // clip + } +#endif + framesLeft -= framesRead; + framePosition += framesRead; + } + return numFrames - framesLeft; +} diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI16.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI16.h new file mode 100644 index 00000000..2cfdfb0c --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI16.h @@ -0,0 +1,43 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FLOWGRAPH_SINK_I16_H +#define FLOWGRAPH_SINK_I16_H + +#include <unistd.h> +#include <sys/types.h> + +#include "FlowGraphNode.h" + +namespace flowgraph { + +/** + * AudioSink that lets you read data as 16-bit signed integers. + */ +class SinkI16 : public FlowGraphSink { +public: + explicit SinkI16(int32_t channelCount); + + int32_t read(int64_t framePosition, void *data, int32_t numFrames) override; + + const char *getName() override { + return "SinkI16"; + } +}; + +} /* namespace flowgraph */ + +#endif //FLOWGRAPH_SINK_I16_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI24.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI24.cpp new file mode 100644 index 00000000..b944b770 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI24.cpp @@ -0,0 +1,67 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <algorithm> +#include <unistd.h> + + +#include "FlowGraphNode.h" +#include "SinkI24.h" + +#if FLOWGRAPH_ANDROID_INTERNAL +#include <audio_utils/primitives.h> +#endif + +using namespace flowgraph; + +SinkI24::SinkI24(int32_t channelCount) + : FlowGraphSink(channelCount) {} + +int32_t SinkI24::read(int64_t framePosition, void *data, int32_t numFrames) { + uint8_t *byteData = (uint8_t *) data; + const int32_t channelCount = input.getSamplesPerFrame(); + + int32_t framesLeft = numFrames; + while (framesLeft > 0) { + // Run the graph and pull data through the input port. + int32_t framesRead = pullData(framePosition, framesLeft); + if (framesRead <= 0) { + break; + } + const float *floatData = input.getBuffer(); + int32_t numSamples = framesRead * channelCount; +#if FLOWGRAPH_ANDROID_INTERNAL + memcpy_to_p24_from_float(byteData, floatData, numSamples); + static const int kBytesPerI24Packed = 3; + byteData += numSamples * kBytesPerI24Packed; + floatData += numSamples; +#else + const int32_t kI24PackedMax = 0x007FFFFF; + const int32_t kI24PackedMin = 0xFF800000; + for (int i = 0; i < numSamples; i++) { + int32_t n = (int32_t) (*floatData++ * 0x00800000); + n = std::min(kI24PackedMax, std::max(kI24PackedMin, n)); // clip + // Write as a packed 24-bit integer in Little Endian format. + *byteData++ = (uint8_t) n; + *byteData++ = (uint8_t) (n >> 8); + *byteData++ = (uint8_t) (n >> 16); + } +#endif + framesLeft -= framesRead; + framePosition += framesRead; + } + return numFrames - framesLeft; +} diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI24.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI24.h new file mode 100644 index 00000000..7477c8d2 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI24.h @@ -0,0 +1,44 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FLOWGRAPH_SINK_I24_H +#define FLOWGRAPH_SINK_I24_H + +#include <unistd.h> +#include <sys/types.h> + +#include "FlowGraphNode.h" + +namespace flowgraph { + +/** + * AudioSink that lets you read data as packed 24-bit signed integers. + * The sample size is 3 bytes. + */ +class SinkI24 : public FlowGraphSink { +public: + explicit SinkI24(int32_t channelCount); + + int32_t read(int64_t framePosition, void *data, int32_t numFrames) override; + + const char *getName() override { + return "SinkI24"; + } +}; + +} /* namespace flowgraph */ + +#endif //FLOWGRAPH_SINK_I24_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceFloat.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceFloat.cpp new file mode 100644 index 00000000..f574d842 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceFloat.cpp @@ -0,0 +1,43 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "common/OboeDebug.h" +#include <algorithm> +#include <unistd.h> +#include "FlowGraphNode.h" +#include "SourceFloat.h" + +using namespace flowgraph; + +SourceFloat::SourceFloat(int32_t channelCount) + : FlowGraphSourceBuffered(channelCount) { +} + +int32_t SourceFloat::onProcess(int32_t numFrames) { + float *outputBuffer = output.getBuffer(); + int32_t channelCount = output.getSamplesPerFrame(); + + int32_t framesLeft = mSizeInFrames - mFrameIndex; + int32_t framesToProcess = std::min(numFrames, framesLeft); + int32_t numSamples = framesToProcess * channelCount; + + const float *floatBase = (float *) mData; + const float *floatData = &floatBase[mFrameIndex * channelCount]; + memcpy(outputBuffer, floatData, numSamples * sizeof(float)); + mFrameIndex += framesToProcess; + return framesToProcess; +} + diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceFloat.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceFloat.h new file mode 100644 index 00000000..4de1b41c --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceFloat.h @@ -0,0 +1,43 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FLOWGRAPH_SOURCE_FLOAT_H +#define FLOWGRAPH_SOURCE_FLOAT_H + +#include <unistd.h> +#include <sys/types.h> + +#include "FlowGraphNode.h" + +namespace flowgraph { + +/** + * AudioSource that reads a block of pre-defined float data. + */ +class SourceFloat : public FlowGraphSourceBuffered { +public: + explicit SourceFloat(int32_t channelCount); + + int32_t onProcess(int32_t numFrames) override; + + const char *getName() override { + return "SourceFloat"; + } +}; + +} /* namespace flowgraph */ + +#endif //FLOWGRAPH_SOURCE_FLOAT_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI16.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI16.cpp new file mode 100644 index 00000000..88130239 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI16.cpp @@ -0,0 +1,54 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <algorithm> +#include <unistd.h> + +#include "FlowGraphNode.h" +#include "SourceI16.h" + +#if FLOWGRAPH_ANDROID_INTERNAL +#include <audio_utils/primitives.h> +#endif + +using namespace flowgraph; + +SourceI16::SourceI16(int32_t channelCount) + : FlowGraphSourceBuffered(channelCount) { +} + +int32_t SourceI16::onProcess(int32_t numFrames) { + float *floatData = output.getBuffer(); + int32_t channelCount = output.getSamplesPerFrame(); + + int32_t framesLeft = mSizeInFrames - mFrameIndex; + int32_t framesToProcess = std::min(numFrames, framesLeft); + int32_t numSamples = framesToProcess * channelCount; + + const int16_t *shortBase = static_cast<const int16_t *>(mData); + const int16_t *shortData = &shortBase[mFrameIndex * channelCount]; + +#if FLOWGRAPH_ANDROID_INTERNAL + memcpy_to_float_from_i16(floatData, shortData, numSamples); +#else + for (int i = 0; i < numSamples; i++) { + *floatData++ = *shortData++ * (1.0f / 32768); + } +#endif + + mFrameIndex += framesToProcess; + return framesToProcess; +} \ No newline at end of file diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI16.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI16.h new file mode 100644 index 00000000..fe440b20 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI16.h @@ -0,0 +1,42 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FLOWGRAPH_SOURCE_I16_H +#define FLOWGRAPH_SOURCE_I16_H + +#include <unistd.h> +#include <sys/types.h> + +#include "FlowGraphNode.h" + +namespace flowgraph { +/** + * AudioSource that reads a block of pre-defined 16-bit integer data. + */ +class SourceI16 : public FlowGraphSourceBuffered { +public: + explicit SourceI16(int32_t channelCount); + + int32_t onProcess(int32_t numFrames) override; + + const char *getName() override { + return "SourceI16"; + } +}; + +} /* namespace flowgraph */ + +#endif //FLOWGRAPH_SOURCE_I16_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI24.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI24.cpp new file mode 100644 index 00000000..19758787 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI24.cpp @@ -0,0 +1,65 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <algorithm> +#include <unistd.h> + +#if FLOWGRAPH_ANDROID_INTERNAL +#include <audio_utils/primitives.h> +#endif + +#include "FlowGraphNode.h" +#include "SourceI24.h" + +using namespace flowgraph; + +constexpr int kBytesPerI24Packed = 3; + +SourceI24::SourceI24(int32_t channelCount) + : FlowGraphSourceBuffered(channelCount) { +} + +int32_t SourceI24::onProcess(int32_t numFrames) { + float *floatData = output.getBuffer(); + int32_t channelCount = output.getSamplesPerFrame(); + + int32_t framesLeft = mSizeInFrames - mFrameIndex; + int32_t framesToProcess = std::min(numFrames, framesLeft); + int32_t numSamples = framesToProcess * channelCount; + + const uint8_t *byteBase = (uint8_t *) mData; + const uint8_t *byteData = &byteBase[mFrameIndex * channelCount * kBytesPerI24Packed]; + +#if FLOWGRAPH_ANDROID_INTERNAL + memcpy_to_float_from_p24(floatData, byteData, numSamples); +#else + static const float scale = 1. / (float)(1UL << 31); + for (int i = 0; i < numSamples; i++) { + // Assemble the data assuming Little Endian format. + int32_t pad = byteData[2]; + pad <<= 8; + pad |= byteData[1]; + pad <<= 8; + pad |= byteData[0]; + pad <<= 8; // Shift to 32 bit data so the sign is correct. + byteData += kBytesPerI24Packed; + *floatData++ = pad * scale; // scale to range -1.0 to 1.0 + } +#endif + + mFrameIndex += framesToProcess; + return framesToProcess; +} \ No newline at end of file diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI24.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI24.h new file mode 100644 index 00000000..37795343 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI24.h @@ -0,0 +1,43 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FLOWGRAPH_SOURCE_I24_H +#define FLOWGRAPH_SOURCE_I24_H + +#include <unistd.h> +#include <sys/types.h> + +#include "FlowGraphNode.h" + +namespace flowgraph { + +/** + * AudioSource that reads a block of pre-defined 24-bit packed integer data. + */ +class SourceI24 : public FlowGraphSourceBuffered { +public: + explicit SourceI24(int32_t channelCount); + + int32_t onProcess(int32_t numFrames) override; + + const char *getName() override { + return "SourceI24"; + } +}; + +} /* namespace flowgraph */ + +#endif //FLOWGRAPH_SOURCE_I24_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/HyperbolicCosineWindow.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/HyperbolicCosineWindow.h new file mode 100644 index 00000000..f6479ae3 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/HyperbolicCosineWindow.h @@ -0,0 +1,68 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef RESAMPLER_HYPERBOLIC_COSINE_WINDOW_H +#define RESAMPLER_HYPERBOLIC_COSINE_WINDOW_H + +#include <math.h> + +namespace resampler { + +/** + * Calculate a HyperbolicCosineWindow window centered at 0. + * This can be used in place of a Kaiser window. + * + * The code is based on an anonymous contribution by "a concerned citizen": + * https://dsp.stackexchange.com/questions/37714/kaiser-window-approximation + */ +class HyperbolicCosineWindow { +public: + HyperbolicCosineWindow() { + setStopBandAttenuation(60); + } + + /** + * @param attenuation typical values range from 30 to 90 dB + * @return beta + */ + double setStopBandAttenuation(double attenuation) { + double alpha = ((-325.1e-6 * attenuation + 0.1677) * attenuation) - 3.149; + setAlpha(alpha); + return alpha; + } + + void setAlpha(double alpha) { + mAlpha = alpha; + mInverseCoshAlpha = 1.0 / cosh(alpha); + } + + /** + * @param x ranges from -1.0 to +1.0 + */ + double operator()(double x) { + double x2 = x * x; + if (x2 >= 1.0) return 0.0; + double w = mAlpha * sqrt(1.0 - x2); + return cosh(w) * mInverseCoshAlpha; + } + +private: + double mAlpha = 0.0; + double mInverseCoshAlpha = 1.0; +}; + +} // namespace resampler +#endif //RESAMPLER_HYPERBOLIC_COSINE_WINDOW_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/IntegerRatio.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/IntegerRatio.cpp new file mode 100644 index 00000000..4bd75b39 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/IntegerRatio.cpp @@ -0,0 +1,50 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "IntegerRatio.h" + +using namespace resampler; + +// Enough primes to cover the common sample rates. +static const int kPrimes[] = { + 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, + 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, + 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, + 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199}; + +void IntegerRatio::reduce() { + for (int prime : kPrimes) { + if (mNumerator < prime || mDenominator < prime) { + break; + } + + // Find biggest prime factor for numerator. + while (true) { + int top = mNumerator / prime; + int bottom = mDenominator / prime; + if ((top >= 1) + && (bottom >= 1) + && (top * prime == mNumerator) // divided evenly? + && (bottom * prime == mDenominator)) { + mNumerator = top; + mDenominator = bottom; + } else { + break; + } + } + + } +} diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/IntegerRatio.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/IntegerRatio.h new file mode 100644 index 00000000..fb390f10 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/IntegerRatio.h @@ -0,0 +1,52 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBOE_INTEGER_RATIO_H +#define OBOE_INTEGER_RATIO_H + +#include <sys/types.h> + +namespace resampler { + +/** + * Represent the ratio of two integers. + */ +class IntegerRatio { +public: + IntegerRatio(int32_t numerator, int32_t denominator) + : mNumerator(numerator), mDenominator(denominator) {} + + /** + * Reduce by removing common prime factors. + */ + void reduce(); + + int32_t getNumerator() { + return mNumerator; + } + + int32_t getDenominator() { + return mDenominator; + } + +private: + int32_t mNumerator; + int32_t mDenominator; +}; + +} + +#endif //OBOE_INTEGER_RATIO_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/KaiserWindow.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/KaiserWindow.h new file mode 100644 index 00000000..73dbc417 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/KaiserWindow.h @@ -0,0 +1,87 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef RESAMPLER_KAISER_WINDOW_H +#define RESAMPLER_KAISER_WINDOW_H + +#include <math.h> + +namespace resampler { + +/** + * Calculate a Kaiser window centered at 0. + */ +class KaiserWindow { +public: + KaiserWindow() { + setStopBandAttenuation(60); + } + + /** + * @param attenuation typical values range from 30 to 90 dB + * @return beta + */ + double setStopBandAttenuation(double attenuation) { + double beta = 0.0; + if (attenuation > 50) { + beta = 0.1102 * (attenuation - 8.7); + } else if (attenuation >= 21) { + double a21 = attenuation - 21; + beta = 0.5842 * pow(a21, 0.4) + (0.07886 * a21); + } + setBeta(beta); + return beta; + } + + void setBeta(double beta) { + mBeta = beta; + mInverseBesselBeta = 1.0 / bessel(beta); + } + + /** + * @param x ranges from -1.0 to +1.0 + */ + double operator()(double x) { + double x2 = x * x; + if (x2 >= 1.0) return 0.0; + double w = mBeta * sqrt(1.0 - x2); + return bessel(w) * mInverseBesselBeta; + } + + // Approximation of a + // modified zero order Bessel function of the first kind. + // Based on a discussion at: + // https://dsp.stackexchange.com/questions/37714/kaiser-window-approximation + static double bessel(double x) { + double y = cosh(0.970941817426052 * x); + y += cosh(0.8854560256532099 * x); + y += cosh(0.7485107481711011 * x); + y += cosh(0.5680647467311558 * x); + y += cosh(0.3546048870425356 * x); + y += cosh(0.120536680255323 * x); + y *= 2; + y += cosh(x); + y /= 13; + return y; + } + +private: + double mBeta = 0.0; + double mInverseBesselBeta = 1.0; +}; + +} // namespace resampler +#endif //RESAMPLER_KAISER_WINDOW_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/LinearResampler.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/LinearResampler.cpp new file mode 100644 index 00000000..a7748c10 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/LinearResampler.cpp @@ -0,0 +1,42 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "LinearResampler.h" + +using namespace resampler; + +LinearResampler::LinearResampler(const MultiChannelResampler::Builder &builder) + : MultiChannelResampler(builder) { + mPreviousFrame = std::make_unique<float[]>(getChannelCount()); + mCurrentFrame = std::make_unique<float[]>(getChannelCount()); +} + +void LinearResampler::writeFrame(const float *frame) { + memcpy(mPreviousFrame.get(), mCurrentFrame.get(), sizeof(float) * getChannelCount()); + memcpy(mCurrentFrame.get(), frame, sizeof(float) * getChannelCount()); +} + +void LinearResampler::readFrame(float *frame) { + float *previous = mPreviousFrame.get(); + float *current = mCurrentFrame.get(); + float phase = (float) getIntegerPhase() / mDenominator; + // iterate across samples in the frame + for (int channel = 0; channel < getChannelCount(); channel++) { + float f0 = *previous++; + float f1 = *current++; + *frame++ = f0 + (phase * (f1 - f0)); + } +} diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/LinearResampler.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/LinearResampler.h new file mode 100644 index 00000000..5dcc8813 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/LinearResampler.h @@ -0,0 +1,44 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBOE_LINEAR_RESAMPLER_H +#define OBOE_LINEAR_RESAMPLER_H + +#include <memory> +#include <sys/types.h> +#include <unistd.h> +#include "MultiChannelResampler.h" + +namespace resampler { + +/** + * Simple resampler that uses bi-linear interpolation. + */ +class LinearResampler : public MultiChannelResampler { +public: + LinearResampler(const MultiChannelResampler::Builder &builder); + + void writeFrame(const float *frame) override; + + void readFrame(float *frame) override; + +private: + std::unique_ptr<float[]> mPreviousFrame; + std::unique_ptr<float[]> mCurrentFrame; +}; + +} // namespace resampler +#endif //OBOE_LINEAR_RESAMPLER_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/MultiChannelResampler.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/MultiChannelResampler.cpp new file mode 100644 index 00000000..d6305207 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/MultiChannelResampler.cpp @@ -0,0 +1,171 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <math.h> + +#include "IntegerRatio.h" +#include "LinearResampler.h" +#include "MultiChannelResampler.h" +#include "PolyphaseResampler.h" +#include "PolyphaseResamplerMono.h" +#include "PolyphaseResamplerStereo.h" +#include "SincResampler.h" +#include "SincResamplerStereo.h" + +using namespace resampler; + +MultiChannelResampler::MultiChannelResampler(const MultiChannelResampler::Builder &builder) + : mNumTaps(builder.getNumTaps()) + , mX(builder.getChannelCount() * builder.getNumTaps() * 2) + , mSingleFrame(builder.getChannelCount()) + , mChannelCount(builder.getChannelCount()) + { + // Reduce sample rates to the smallest ratio. + // For example 44100/48000 would become 147/160. + IntegerRatio ratio(builder.getInputRate(), builder.getOutputRate()); + ratio.reduce(); + mNumerator = ratio.getNumerator(); + mDenominator = ratio.getDenominator(); + mIntegerPhase = mDenominator; +} + +// static factory method +MultiChannelResampler *MultiChannelResampler::make(int32_t channelCount, + int32_t inputRate, + int32_t outputRate, + Quality quality) { + Builder builder; + builder.setInputRate(inputRate); + builder.setOutputRate(outputRate); + builder.setChannelCount(channelCount); + + switch (quality) { + case Quality::Fastest: + builder.setNumTaps(2); + break; + case Quality::Low: + builder.setNumTaps(4); + break; + case Quality::Medium: + default: + builder.setNumTaps(8); + break; + case Quality::High: + builder.setNumTaps(16); + break; + case Quality::Best: + builder.setNumTaps(32); + break; + } + + // Set the cutoff frequency so that we do not get aliasing when down-sampling. + if (inputRate > outputRate) { + builder.setNormalizedCutoff(kDefaultNormalizedCutoff); + } + return builder.build(); +} + +MultiChannelResampler *MultiChannelResampler::Builder::build() { + if (getNumTaps() == 2) { + // Note that this does not do low pass filteringh. + return new LinearResampler(*this); + } + IntegerRatio ratio(getInputRate(), getOutputRate()); + ratio.reduce(); + bool usePolyphase = (getNumTaps() * ratio.getDenominator()) <= kMaxCoefficients; + if (usePolyphase) { + if (getChannelCount() == 1) { + return new PolyphaseResamplerMono(*this); + } else if (getChannelCount() == 2) { + return new PolyphaseResamplerStereo(*this); + } else { + return new PolyphaseResampler(*this); + } + } else { + // Use less optimized resampler that uses a float phaseIncrement. + // TODO mono resampler + if (getChannelCount() == 2) { + return new SincResamplerStereo(*this); + } else { + return new SincResampler(*this); + } + } +} + +void MultiChannelResampler::writeFrame(const float *frame) { + // Move cursor before write so that cursor points to last written frame in read. + if (--mCursor < 0) { + mCursor = getNumTaps() - 1; + } + float *dest = &mX[mCursor * getChannelCount()]; + int offset = getNumTaps() * getChannelCount(); + for (int channel = 0; channel < getChannelCount(); channel++) { + // Write twice so we avoid having to wrap when reading. + dest[channel] = dest[channel + offset] = frame[channel]; + } +} + +float MultiChannelResampler::sinc(float radians) { + if (abs(radians) < 1.0e-9) return 1.0f; // avoid divide by zero + return sinf(radians) / radians; // Sinc function +} + +// Generate coefficients in the order they will be used by readFrame(). +// This is more complicated but readFrame() is called repeatedly and should be optimized. +void MultiChannelResampler::generateCoefficients(int32_t inputRate, + int32_t outputRate, + int32_t numRows, + double phaseIncrement, + float normalizedCutoff) { + mCoefficients.resize(getNumTaps() * numRows); + int coefficientIndex = 0; + double phase = 0.0; // ranges from 0.0 to 1.0, fraction between samples + // Stretch the sinc function for low pass filtering. + const float cutoffScaler = normalizedCutoff * + ((outputRate < inputRate) + ? ((float)outputRate / inputRate) + : ((float)inputRate / outputRate)); + const int numTapsHalf = getNumTaps() / 2; // numTaps must be even. + const float numTapsHalfInverse = 1.0f / numTapsHalf; + for (int i = 0; i < numRows; i++) { + float tapPhase = phase - numTapsHalf; + float gain = 0.0; // sum of raw coefficients + int gainCursor = coefficientIndex; + for (int tap = 0; tap < getNumTaps(); tap++) { + float radians = tapPhase * M_PI; + +#if MCR_USE_KAISER + float window = mKaiserWindow(tapPhase * numTapsHalfInverse); +#else + float window = mCoshWindow(tapPhase * numTapsHalfInverse); +#endif + float coefficient = sinc(radians * cutoffScaler) * window; + mCoefficients.at(coefficientIndex++) = coefficient; + gain += coefficient; + tapPhase += 1.0; + } + phase += phaseIncrement; + while (phase >= 1.0) { + phase -= 1.0; + } + + // Correct for gain variations. + float gainCorrection = 1.0 / gain; // normalize the gain + for (int tap = 0; tap < getNumTaps(); tap++) { + mCoefficients.at(gainCursor + tap) *= gainCorrection; + } + } +} diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/MultiChannelResampler.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/MultiChannelResampler.h new file mode 100644 index 00000000..8b23d810 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/MultiChannelResampler.h @@ -0,0 +1,271 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBOE_MULTICHANNEL_RESAMPLER_H +#define OBOE_MULTICHANNEL_RESAMPLER_H + +#include <memory> +#include <vector> +#include <sys/types.h> +#include <unistd.h> + +#ifndef MCR_USE_KAISER +// It appears from the spectrogram that the HyperbolicCosine window leads to fewer artifacts. +// And it is faster to calculate. +#define MCR_USE_KAISER 0 +#endif + +#if MCR_USE_KAISER +#include "KaiserWindow.h" +#else +#include "HyperbolicCosineWindow.h" +#endif + +namespace resampler { + +class MultiChannelResampler { + +public: + + enum class Quality : int32_t { + Fastest, + Low, + Medium, + High, + Best, + }; + + class Builder { + public: + /** + * Construct an optimal resampler based on the specified parameters. + * @return address of a resampler + */ + MultiChannelResampler *build(); + + /** + * The number of taps in the resampling filter. + * More taps gives better quality but uses more CPU time. + * This typically ranges from 4 to 64. Default is 16. + * + * For polyphase filters, numTaps must be a multiple of four for loop unrolling. + * @param numTaps number of taps for the filter + * @return address of this builder for chaining calls + */ + Builder *setNumTaps(int32_t numTaps) { + mNumTaps = numTaps; + return this; + } + + /** + * Use 1 for mono, 2 for stereo, etc. Default is 1. + * + * @param channelCount number of channels + * @return address of this builder for chaining calls + */ + Builder *setChannelCount(int32_t channelCount) { + mChannelCount = channelCount; + return this; + } + + /** + * Default is 48000. + * + * @param inputRate sample rate of the input stream + * @return address of this builder for chaining calls + */ + Builder *setInputRate(int32_t inputRate) { + mInputRate = inputRate; + return this; + } + + /** + * Default is 48000. + * + * @param outputRate sample rate of the output stream + * @return address of this builder for chaining calls + */ + Builder *setOutputRate(int32_t outputRate) { + mOutputRate = outputRate; + return this; + } + + /** + * Set cutoff frequency relative to the Nyquist rate of the output sample rate. + * Set to 1.0 to match the Nyquist frequency. + * Set lower to reduce aliasing. + * Default is 0.70. + * + * @param normalizedCutoff anti-aliasing filter cutoff + * @return address of this builder for chaining calls + */ + Builder *setNormalizedCutoff(float normalizedCutoff) { + mNormalizedCutoff = normalizedCutoff; + return this; + } + + int32_t getNumTaps() const { + return mNumTaps; + } + + int32_t getChannelCount() const { + return mChannelCount; + } + + int32_t getInputRate() const { + return mInputRate; + } + + int32_t getOutputRate() const { + return mOutputRate; + } + + float getNormalizedCutoff() const { + return mNormalizedCutoff; + } + + protected: + int32_t mChannelCount = 1; + int32_t mNumTaps = 16; + int32_t mInputRate = 48000; + int32_t mOutputRate = 48000; + float mNormalizedCutoff = kDefaultNormalizedCutoff; + }; + + virtual ~MultiChannelResampler() = default; + + /** + * Factory method for making a resampler that is optimal for the given inputs. + * + * @param channelCount number of channels, 2 for stereo + * @param inputRate sample rate of the input stream + * @param outputRate sample rate of the output stream + * @param quality higher quality sounds better but uses more CPU + * @return an optimal resampler + */ + static MultiChannelResampler *make(int32_t channelCount, + int32_t inputRate, + int32_t outputRate, + Quality quality); + + bool isWriteNeeded() const { + return mIntegerPhase >= mDenominator; + } + + /** + * Write a frame containing N samples. + * + * @param frame pointer to the first sample in a frame + */ + void writeNextFrame(const float *frame) { + writeFrame(frame); + advanceWrite(); + } + + /** + * Read a frame containing N samples. + * + * @param frame pointer to the first sample in a frame + */ + void readNextFrame(float *frame) { + readFrame(frame); + advanceRead(); + } + + int getNumTaps() const { + return mNumTaps; + } + + int getChannelCount() const { + return mChannelCount; + } + + static float hammingWindow(float radians, float spread); + + static float sinc(float radians); + +protected: + + explicit MultiChannelResampler(const MultiChannelResampler::Builder &builder); + + /** + * Write a frame containing N samples. + * Call advanceWrite() after calling this. + * @param frame pointer to the first sample in a frame + */ + virtual void writeFrame(const float *frame); + + /** + * Read a frame containing N samples using interpolation. + * Call advanceRead() after calling this. + * @param frame pointer to the first sample in a frame + */ + virtual void readFrame(float *frame) = 0; + + void advanceWrite() { + mIntegerPhase -= mDenominator; + } + + void advanceRead() { + mIntegerPhase += mNumerator; + } + + /** + * Generate the filter coefficients in optimal order. + * @param inputRate sample rate of the input stream + * @param outputRate sample rate of the output stream + * @param numRows number of rows in the array that contain a set of tap coefficients + * @param phaseIncrement how much to increment the phase between rows + * @param normalizedCutoff filter cutoff frequency normalized to Nyquist rate of output + */ + void generateCoefficients(int32_t inputRate, + int32_t outputRate, + int32_t numRows, + double phaseIncrement, + float normalizedCutoff); + + + int32_t getIntegerPhase() { + return mIntegerPhase; + } + + static constexpr int kMaxCoefficients = 8 * 1024; + std::vector<float> mCoefficients; + + const int mNumTaps; + int mCursor = 0; + std::vector<float> mX; // delayed input values for the FIR + std::vector<float> mSingleFrame; // one frame for temporary use + int32_t mIntegerPhase = 0; + int32_t mNumerator = 0; + int32_t mDenominator = 0; + + +private: + +#if MCR_USE_KAISER + KaiserWindow mKaiserWindow; +#else + HyperbolicCosineWindow mCoshWindow; +#endif + + static constexpr float kDefaultNormalizedCutoff = 0.70f; + + const int mChannelCount; +}; + +} +#endif //OBOE_MULTICHANNEL_RESAMPLER_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResampler.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResampler.cpp new file mode 100644 index 00000000..4862ad8a --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResampler.cpp @@ -0,0 +1,61 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <math.h> +#include "IntegerRatio.h" +#include "PolyphaseResampler.h" + +using namespace resampler; + +PolyphaseResampler::PolyphaseResampler(const MultiChannelResampler::Builder &builder) + : MultiChannelResampler(builder) + { + assert((getNumTaps() % 4) == 0); // Required for loop unrolling. + + int32_t inputRate = builder.getInputRate(); + int32_t outputRate = builder.getOutputRate(); + + int32_t numRows = mDenominator; + double phaseIncrement = (double) inputRate / (double) outputRate; + generateCoefficients(inputRate, outputRate, + numRows, phaseIncrement, + builder.getNormalizedCutoff()); +} + +void PolyphaseResampler::readFrame(float *frame) { + // Clear accumulator for mixing. + std::fill(mSingleFrame.begin(), mSingleFrame.end(), 0.0); + +// printf("PolyphaseResampler: mCoefficientCursor = %4d\n", mCoefficientCursor); + // Multiply input times windowed sinc function. + float *coefficients = &mCoefficients[mCoefficientCursor]; + float *xFrame = &mX[mCursor * getChannelCount()]; + for (int i = 0; i < mNumTaps; i++) { + float coefficient = *coefficients++; +// printf("PolyphaseResampler: coeff = %10.6f, xFrame[0] = %10.6f\n", coefficient, xFrame[0]); + for (int channel = 0; channel < getChannelCount(); channel++) { + mSingleFrame[channel] += *xFrame++ * coefficient; + } + } + + // Advance and wrap through coefficients. + mCoefficientCursor = (mCoefficientCursor + mNumTaps) % mCoefficients.size(); + + // Copy accumulator to output. + for (int channel = 0; channel < getChannelCount(); channel++) { + frame[channel] = mSingleFrame[channel]; + } +} diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResampler.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResampler.h new file mode 100644 index 00000000..c7de1185 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResampler.h @@ -0,0 +1,51 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBOE_POLYPHASE_RESAMPLER_H +#define OBOE_POLYPHASE_RESAMPLER_H + +#include <memory> +#include <vector> +#include <sys/types.h> +#include <unistd.h> +#include "MultiChannelResampler.h" + +namespace resampler { +/** + * Resample that is optimized for a reduced ratio of sample rates. + * All of the coefficients for eacxh possible phase value are precalculated. + */ +class PolyphaseResampler : public MultiChannelResampler { +public: + /** + * + * @param builder containing lots of parameters + */ + explicit PolyphaseResampler(const MultiChannelResampler::Builder &builder); + + virtual ~PolyphaseResampler() = default; + + void readFrame(float *frame) override; + +protected: + + int32_t mCoefficientCursor = 0; + +}; + +} + +#endif //OBOE_POLYPHASE_RESAMPLER_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.cpp new file mode 100644 index 00000000..2dcdc8ec --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.cpp @@ -0,0 +1,62 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "PolyphaseResamplerMono.h" + +using namespace resampler; + +#define MONO 1 + +PolyphaseResamplerMono::PolyphaseResamplerMono(const MultiChannelResampler::Builder &builder) + : PolyphaseResampler(builder) { + assert(builder.getChannelCount() == MONO); +} + +void PolyphaseResamplerMono::writeFrame(const float *frame) { + // Move cursor before write so that cursor points to last written frame in read. + if (--mCursor < 0) { + mCursor = getNumTaps() - 1; + } + float *dest = &mX[mCursor * MONO]; + const int offset = mNumTaps * MONO; + // Write each channel twice so we avoid having to wrap when running the FIR. + const float sample = frame[0]; + // Put ordered writes together. + dest[0] = sample; + dest[offset] = sample; +} + +void PolyphaseResamplerMono::readFrame(float *frame) { + // Clear accumulator. + float sum = 0.0; + + // Multiply input times precomputed windowed sinc function. + const float *coefficients = &mCoefficients[mCoefficientCursor]; + float *xFrame = &mX[mCursor * MONO]; + const int numLoops = mNumTaps >> 2; // n/4 + for (int i = 0; i < numLoops; i++) { + // Manual loop unrolling, might get converted to SIMD. + sum += *xFrame++ * *coefficients++; + sum += *xFrame++ * *coefficients++; + sum += *xFrame++ * *coefficients++; + sum += *xFrame++ * *coefficients++; + } + + mCoefficientCursor = (mCoefficientCursor + mNumTaps) % mCoefficients.size(); + + // Copy accumulator to output. + frame[0] = sum; +} diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.h new file mode 100644 index 00000000..d97b513c --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.h @@ -0,0 +1,39 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBOE_POLYPHASE_RESAMPLER_MONO_H +#define OBOE_POLYPHASE_RESAMPLER_MONO_H + +#include <sys/types.h> +#include <unistd.h> +#include "PolyphaseResampler.h" + +namespace resampler { + +class PolyphaseResamplerMono : public PolyphaseResampler { +public: + explicit PolyphaseResamplerMono(const MultiChannelResampler::Builder &builder); + + virtual ~PolyphaseResamplerMono() = default; + + void writeFrame(const float *frame) override; + + void readFrame(float *frame) override; +}; + +} + +#endif //OBOE_POLYPHASE_RESAMPLER_MONO_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.cpp new file mode 100644 index 00000000..5c73a8e3 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.cpp @@ -0,0 +1,78 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "PolyphaseResamplerStereo.h" + +using namespace resampler; + +#define STEREO 2 + +PolyphaseResamplerStereo::PolyphaseResamplerStereo(const MultiChannelResampler::Builder &builder) + : PolyphaseResampler(builder) { + assert(builder.getChannelCount() == STEREO); +} + +void PolyphaseResamplerStereo::writeFrame(const float *frame) { + // Move cursor before write so that cursor points to last written frame in read. + if (--mCursor < 0) { + mCursor = getNumTaps() - 1; + } + float *dest = &mX[mCursor * STEREO]; + const int offset = mNumTaps * STEREO; + // Write each channel twice so we avoid having to wrap when running the FIR. + const float left = frame[0]; + const float right = frame[1]; + // Put ordered writes together. + dest[0] = left; + dest[1] = right; + dest[offset] = left; + dest[1 + offset] = right; +} + +void PolyphaseResamplerStereo::readFrame(float *frame) { + // Clear accumulators. + float left = 0.0; + float right = 0.0; + + // Multiply input times precomputed windowed sinc function. + const float *coefficients = &mCoefficients[mCoefficientCursor]; + float *xFrame = &mX[mCursor * STEREO]; + const int numLoops = mNumTaps >> 2; // n/4 + for (int i = 0; i < numLoops; i++) { + // Manual loop unrolling, might get converted to SIMD. + float coefficient = *coefficients++; + left += *xFrame++ * coefficient; + right += *xFrame++ * coefficient; + + coefficient = *coefficients++; // next tap + left += *xFrame++ * coefficient; + right += *xFrame++ * coefficient; + + coefficient = *coefficients++; // next tap + left += *xFrame++ * coefficient; + right += *xFrame++ * coefficient; + + coefficient = *coefficients++; // next tap + left += *xFrame++ * coefficient; + right += *xFrame++ * coefficient; + } + + mCoefficientCursor = (mCoefficientCursor + mNumTaps) % mCoefficients.size(); + + // Copy accumulators to output. + frame[0] = left; + frame[1] = right; +} diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.h new file mode 100644 index 00000000..3dfd4e2d --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.h @@ -0,0 +1,39 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBOE_POLYPHASE_RESAMPLER_STEREO_H +#define OBOE_POLYPHASE_RESAMPLER_STEREO_H + +#include <sys/types.h> +#include <unistd.h> +#include "PolyphaseResampler.h" + +namespace resampler { + +class PolyphaseResamplerStereo : public PolyphaseResampler { +public: + explicit PolyphaseResamplerStereo(const MultiChannelResampler::Builder &builder); + + virtual ~PolyphaseResamplerStereo() = default; + + void writeFrame(const float *frame) override; + + void readFrame(float *frame) override; +}; + +} + +#endif //OBOE_POLYPHASE_RESAMPLER_STEREO_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.cpp new file mode 100644 index 00000000..1084356d --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.cpp @@ -0,0 +1,76 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <math.h> +#include "SincResampler.h" + +using namespace resampler; + +SincResampler::SincResampler(const MultiChannelResampler::Builder &builder) + : MultiChannelResampler(builder) + , mSingleFrame2(builder.getChannelCount()) { + assert((getNumTaps() % 4) == 0); // Required for loop unrolling. + mNumRows = kMaxCoefficients / getNumTaps(); // no guard row needed +// printf("SincResampler: numRows = %d\n", mNumRows); + mPhaseScaler = (double) mNumRows / mDenominator; + double phaseIncrement = 1.0 / mNumRows; + generateCoefficients(builder.getInputRate(), + builder.getOutputRate(), + mNumRows, + phaseIncrement, + builder.getNormalizedCutoff()); +} + +void SincResampler::readFrame(float *frame) { + // Clear accumulator for mixing. + std::fill(mSingleFrame.begin(), mSingleFrame.end(), 0.0); + std::fill(mSingleFrame2.begin(), mSingleFrame2.end(), 0.0); + + // Determine indices into coefficients table. + double tablePhase = getIntegerPhase() * mPhaseScaler; + int index1 = static_cast<int>(floor(tablePhase)); + if (index1 >= mNumRows) { // no guard row needed because we wrap the indices + tablePhase -= mNumRows; + index1 -= mNumRows; + } + + int index2 = index1 + 1; + if (index2 >= mNumRows) { // no guard row needed because we wrap the indices + index2 -= mNumRows; + } + + float *coefficients1 = &mCoefficients[index1 * getNumTaps()]; + float *coefficients2 = &mCoefficients[index2 * getNumTaps()]; + + float *xFrame = &mX[mCursor * getChannelCount()]; + for (int i = 0; i < mNumTaps; i++) { + float coefficient1 = *coefficients1++; + float coefficient2 = *coefficients2++; + for (int channel = 0; channel < getChannelCount(); channel++) { + float sample = *xFrame++; + mSingleFrame[channel] += sample * coefficient1; + mSingleFrame2[channel] += sample * coefficient2; + } + } + + // Interpolate and copy to output. + float fraction = tablePhase - index1; + for (int channel = 0; channel < getChannelCount(); channel++) { + float low = mSingleFrame[channel]; + float high = mSingleFrame2[channel]; + frame[channel] = low + (fraction * (high - low)); + } +} diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.h new file mode 100644 index 00000000..6ab61c96 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.h @@ -0,0 +1,47 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBOE_SINC_RESAMPLER_H +#define OBOE_SINC_RESAMPLER_H + +#include <memory> +#include <sys/types.h> +#include <unistd.h> +#include "MultiChannelResampler.h" + +namespace resampler { + +/** + * Resampler that can interpolate between coefficients. + * This can be used to support arbitrary ratios. + */ +class SincResampler : public MultiChannelResampler { +public: + explicit SincResampler(const MultiChannelResampler::Builder &builder); + + virtual ~SincResampler() = default; + + void readFrame(float *frame) override; + +protected: + + std::vector<float> mSingleFrame2; // for interpolation + int32_t mNumRows = 0; + double mPhaseScaler = 1.0; +}; + +} +#endif //OBOE_SINC_RESAMPLER_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResamplerStereo.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResamplerStereo.cpp new file mode 100644 index 00000000..bde658a4 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResamplerStereo.cpp @@ -0,0 +1,80 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <math.h> + +#include "SincResamplerStereo.h" + +using namespace resampler; + +#define STEREO 2 + +SincResamplerStereo::SincResamplerStereo(const MultiChannelResampler::Builder &builder) + : SincResampler(builder) { + assert(builder.getChannelCount() == STEREO); +} + +void SincResamplerStereo::writeFrame(const float *frame) { + // Move cursor before write so that cursor points to last written frame in read. + if (--mCursor < 0) { + mCursor = getNumTaps() - 1; + } + float *dest = &mX[mCursor * STEREO]; + const int offset = mNumTaps * STEREO; + // Write each channel twice so we avoid having to wrap when running the FIR. + const float left = frame[0]; + const float right = frame[1]; + // Put ordered writes together. + dest[0] = left; + dest[1] = right; + dest[offset] = left; + dest[1 + offset] = right; +} + +// Multiply input times windowed sinc function. +void SincResamplerStereo::readFrame(float *frame) { + // Clear accumulator for mixing. + std::fill(mSingleFrame.begin(), mSingleFrame.end(), 0.0); + std::fill(mSingleFrame2.begin(), mSingleFrame2.end(), 0.0); + + // Determine indices into coefficients table. + double tablePhase = getIntegerPhase() * mPhaseScaler; + int index1 = static_cast<int>(floor(tablePhase)); + float *coefficients1 = &mCoefficients[index1 * getNumTaps()]; + int index2 = (index1 + 1); + if (index2 >= mNumRows) { // no guard row needed because we wrap the indices + index2 = 0; + } + float *coefficients2 = &mCoefficients[index2 * getNumTaps()]; + float *xFrame = &mX[mCursor * getChannelCount()]; + for (int i = 0; i < mNumTaps; i++) { + float coefficient1 = *coefficients1++; + float coefficient2 = *coefficients2++; + for (int channel = 0; channel < getChannelCount(); channel++) { + float sample = *xFrame++; + mSingleFrame[channel] += sample * coefficient1; + mSingleFrame2[channel] += sample * coefficient2; + } + } + + // Interpolate and copy to output. + float fraction = tablePhase - index1; + for (int channel = 0; channel < getChannelCount(); channel++) { + float low = mSingleFrame[channel]; + float high = mSingleFrame2[channel]; + frame[channel] = low + (fraction * (high - low)); + } +} diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResamplerStereo.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResamplerStereo.h new file mode 100644 index 00000000..7d66c26f --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResamplerStereo.h @@ -0,0 +1,39 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBOE_SINC_RESAMPLER_STEREO_H +#define OBOE_SINC_RESAMPLER_STEREO_H + +#include <sys/types.h> +#include <unistd.h> +#include "SincResampler.h" + +namespace resampler { + +class SincResamplerStereo : public SincResampler { +public: + explicit SincResamplerStereo(const MultiChannelResampler::Builder &builder); + + virtual ~SincResamplerStereo() = default; + + void writeFrame(const float *frame) override; + + void readFrame(float *frame) override; + +}; + +} +#endif //OBOE_SINC_RESAMPLER_STEREO_H diff --git a/modules/juce_audio_devices/native/oboe/src/opensles/AudioInputStreamOpenSLES.cpp b/modules/juce_audio_devices/native/oboe/src/opensles/AudioInputStreamOpenSLES.cpp new file mode 100644 index 00000000..fcad183b --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/opensles/AudioInputStreamOpenSLES.cpp @@ -0,0 +1,352 @@ +/* + * Copyright 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <cassert> + +#include <SLES/OpenSLES.h> +#include <SLES/OpenSLES_Android.h> + +#include "oboe/AudioStreamBuilder.h" +#include "AudioInputStreamOpenSLES.h" +#include "AudioStreamOpenSLES.h" +#include "OpenSLESUtilities.h" + +using namespace oboe; + +static SLuint32 OpenSLES_convertInputPreset(InputPreset oboePreset) { + SLuint32 openslPreset = SL_ANDROID_RECORDING_PRESET_NONE; + switch(oboePreset) { + case InputPreset::Generic: + openslPreset = SL_ANDROID_RECORDING_PRESET_GENERIC; + break; + case InputPreset::Camcorder: + openslPreset = SL_ANDROID_RECORDING_PRESET_CAMCORDER; + break; + case InputPreset::VoiceRecognition: + openslPreset = SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION; + break; + case InputPreset::VoiceCommunication: + openslPreset = SL_ANDROID_RECORDING_PRESET_VOICE_COMMUNICATION; + break; + case InputPreset::Unprocessed: + openslPreset = SL_ANDROID_RECORDING_PRESET_UNPROCESSED; + break; + default: + break; + } + return openslPreset; +} + +AudioInputStreamOpenSLES::AudioInputStreamOpenSLES(const AudioStreamBuilder &builder) + : AudioStreamOpenSLES(builder) { +} + +AudioInputStreamOpenSLES::~AudioInputStreamOpenSLES() { +} + +// Calculate masks specific to INPUT streams. +SLuint32 AudioInputStreamOpenSLES::channelCountToChannelMask(int channelCount) const { + // Derived from internal sles_channel_in_mask_from_count(chanCount); + // in "frameworks/wilhelm/src/android/channels.cpp". + // Yes, it seems strange to use SPEAKER constants to describe inputs. + // But that is how OpenSL ES does it internally. + switch (channelCount) { + case 1: + return SL_SPEAKER_FRONT_LEFT; + case 2: + return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; + default: + return channelCountToChannelMaskDefault(channelCount); + } +} + +Result AudioInputStreamOpenSLES::open() { + logUnsupportedAttributes(); + + SLAndroidConfigurationItf configItf = nullptr; + + if (getSdkVersion() < __ANDROID_API_M__ && mFormat == AudioFormat::Float){ + // TODO: Allow floating point format on API <23 using float->int16 converter + return Result::ErrorInvalidFormat; + } + + // If audio format is unspecified then choose a suitable default. + // API 23+: FLOAT + // API <23: INT16 + if (mFormat == AudioFormat::Unspecified){ + mFormat = (getSdkVersion() < __ANDROID_API_M__) ? + AudioFormat::I16 : AudioFormat::Float; + } + + Result oboeResult = AudioStreamOpenSLES::open(); + if (Result::OK != oboeResult) return oboeResult; + + SLuint32 bitsPerSample = static_cast<SLuint32>(getBytesPerSample() * kBitsPerByte); + + // configure audio sink + SLDataLocator_AndroidSimpleBufferQueue loc_bufq = { + SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, // locatorType + static_cast<SLuint32>(kBufferQueueLength)}; // numBuffers + + // Define the audio data format. + SLDataFormat_PCM format_pcm = { + SL_DATAFORMAT_PCM, // formatType + static_cast<SLuint32>(mChannelCount), // numChannels + static_cast<SLuint32>(mSampleRate * kMillisPerSecond), // milliSamplesPerSec + bitsPerSample, // bitsPerSample + bitsPerSample, // containerSize; + channelCountToChannelMask(mChannelCount), // channelMask + getDefaultByteOrder(), + }; + + SLDataSink audioSink = {&loc_bufq, &format_pcm}; + + /** + * API 23 (Marshmallow) introduced support for floating-point data representation and an + * extended data format type: SLAndroidDataFormat_PCM_EX for recording streams (playback streams + * got this in API 21). If running on API 23+ use this newer format type, creating it from our + * original format. + */ + SLAndroidDataFormat_PCM_EX format_pcm_ex; + if (getSdkVersion() >= __ANDROID_API_M__) { + SLuint32 representation = OpenSLES_ConvertFormatToRepresentation(getFormat()); + // Fill in the format structure. + format_pcm_ex = OpenSLES_createExtendedFormat(format_pcm, representation); + // Use in place of the previous format. + audioSink.pFormat = &format_pcm_ex; + } + + + // configure audio source + SLDataLocator_IODevice loc_dev = {SL_DATALOCATOR_IODEVICE, + SL_IODEVICE_AUDIOINPUT, + SL_DEFAULTDEVICEID_AUDIOINPUT, + NULL}; + SLDataSource audioSrc = {&loc_dev, NULL}; + + SLresult result = EngineOpenSLES::getInstance().createAudioRecorder(&mObjectInterface, + &audioSrc, + &audioSink); + + if (SL_RESULT_SUCCESS != result) { + LOGE("createAudioRecorder() result:%s", getSLErrStr(result)); + goto error; + } + + // Configure the stream. + result = (*mObjectInterface)->GetInterface(mObjectInterface, + SL_IID_ANDROIDCONFIGURATION, + &configItf); + + if (SL_RESULT_SUCCESS != result) { + LOGW("%s() GetInterface(SL_IID_ANDROIDCONFIGURATION) failed with %s", + __func__, getSLErrStr(result)); + } else { + SLuint32 presetValue = OpenSLES_convertInputPreset(getInputPreset()); + result = (*configItf)->SetConfiguration(configItf, + SL_ANDROID_KEY_RECORDING_PRESET, + &presetValue, + sizeof(SLuint32)); + if (SL_RESULT_SUCCESS != result + && presetValue != SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION) { + presetValue = SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION; + mInputPreset = InputPreset::VoiceRecognition; + (*configItf)->SetConfiguration(configItf, + SL_ANDROID_KEY_RECORDING_PRESET, + &presetValue, + sizeof(SLuint32)); + } + + result = configurePerformanceMode(configItf); + if (SL_RESULT_SUCCESS != result) { + goto error; + } + } + + result = (*mObjectInterface)->Realize(mObjectInterface, SL_BOOLEAN_FALSE); + if (SL_RESULT_SUCCESS != result) { + LOGE("Realize recorder object result:%s", getSLErrStr(result)); + goto error; + } + + result = (*mObjectInterface)->GetInterface(mObjectInterface, SL_IID_RECORD, &mRecordInterface); + if (SL_RESULT_SUCCESS != result) { + LOGE("GetInterface RECORD result:%s", getSLErrStr(result)); + goto error; + } + + result = AudioStreamOpenSLES::registerBufferQueueCallback(); + if (SL_RESULT_SUCCESS != result) { + goto error; + } + + result = updateStreamParameters(configItf); + if (SL_RESULT_SUCCESS != result) { + goto error; + } + + oboeResult = configureBufferSizes(mSampleRate); + if (Result::OK != oboeResult) { + goto error; + } + + allocateFifo(); + + setState(StreamState::Open); + return Result::OK; + +error: + return Result::ErrorInternal; // TODO convert error from SLES to OBOE +} + +Result AudioInputStreamOpenSLES::close() { + LOGD("AudioInputStreamOpenSLES::%s()", __func__); + mLock.lock(); + Result result = Result::OK; + if (getState() == StreamState::Closed){ + result = Result::ErrorClosed; + } else { + mLock.unlock(); // avoid recursive lock + requestStop(); + mLock.lock(); + // invalidate any interfaces + mRecordInterface = nullptr; + result = AudioStreamOpenSLES::close(); + } + mLock.unlock(); // avoid recursive lock + return result; +} + +Result AudioInputStreamOpenSLES::setRecordState_l(SLuint32 newState) { + LOGD("AudioInputStreamOpenSLES::%s(%u)", __func__, newState); + Result result = Result::OK; + + if (mRecordInterface == nullptr) { + LOGE("AudioInputStreamOpenSLES::%s() mRecordInterface is null", __func__); + return Result::ErrorInvalidState; + } + SLresult slResult = (*mRecordInterface)->SetRecordState(mRecordInterface, newState); + //LOGD("AudioInputStreamOpenSLES::%s(%u) returned %u", __func__, newState, slResult); + if (SL_RESULT_SUCCESS != slResult) { + LOGE("AudioInputStreamOpenSLES::%s(%u) returned error %s", + __func__, newState, getSLErrStr(slResult)); + result = Result::ErrorInternal; // TODO review + } + return result; +} + +Result AudioInputStreamOpenSLES::requestStart() { + LOGD("AudioInputStreamOpenSLES(): %s() called", __func__); + std::lock_guard<std::mutex> lock(mLock); + StreamState initialState = getState(); + switch (initialState) { + case StreamState::Starting: + case StreamState::Started: + return Result::OK; + case StreamState::Closed: + return Result::ErrorClosed; + default: + break; + } + + // We use a callback if the user requests one + // OR if we have an internal callback to fill the blocking IO buffer. + setDataCallbackEnabled(true); + + setState(StreamState::Starting); + Result result = setRecordState_l(SL_RECORDSTATE_RECORDING); + if (result == Result::OK) { + setState(StreamState::Started); + // Enqueue the first buffer to start the streaming. + // This does not call the callback function. + enqueueCallbackBuffer(mSimpleBufferQueueInterface); + } else { + setState(initialState); + } + return result; +} + + +Result AudioInputStreamOpenSLES::requestPause() { + LOGW("AudioInputStreamOpenSLES::%s() is intentionally not implemented for input " + "streams", __func__); + return Result::ErrorUnimplemented; // Matches AAudio behavior. +} + +Result AudioInputStreamOpenSLES::requestFlush() { + LOGW("AudioInputStreamOpenSLES::%s() is intentionally not implemented for input " + "streams", __func__); + return Result::ErrorUnimplemented; // Matches AAudio behavior. +} + +Result AudioInputStreamOpenSLES::requestStop() { + LOGD("AudioInputStreamOpenSLES(): %s() called", __func__); + + std::lock_guard<std::mutex> lock(mLock); + StreamState initialState = getState(); + switch (initialState) { + case StreamState::Stopping: + case StreamState::Stopped: + return Result::OK; + case StreamState::Closed: + return Result::ErrorClosed; + default: + break; + } + + setState(StreamState::Stopping); + + Result result = setRecordState_l(SL_RECORDSTATE_STOPPED); + if (result == Result::OK) { + mPositionMillis.reset32(); // OpenSL ES resets its millisecond position when stopped. + setState(StreamState::Stopped); + } else { + setState(initialState); + } + return result; +} + +void AudioInputStreamOpenSLES::updateFramesWritten() { + if (usingFIFO()) { + AudioStreamBuffered::updateFramesWritten(); + } else { + mFramesWritten = getFramesProcessedByServer(); + } +} + +Result AudioInputStreamOpenSLES::updateServiceFrameCounter() { + Result result = Result::OK; + // Avoid deadlock if another thread is trying to stop or close this stream + // and this is being called from a callback. + if (mLock.try_lock()) { + + if (mRecordInterface == nullptr) { + mLock.unlock(); + return Result::ErrorNull; + } + SLmillisecond msec = 0; + SLresult slResult = (*mRecordInterface)->GetPosition(mRecordInterface, &msec); + if (SL_RESULT_SUCCESS != slResult) { + LOGW("%s(): GetPosition() returned %s", __func__, getSLErrStr(slResult)); + // set result based on SLresult + result = Result::ErrorInternal; + } else { + mPositionMillis.update32(msec); + } + mLock.unlock(); + } + return result; +} diff --git a/modules/juce_audio_devices/native/oboe/src/opensles/AudioInputStreamOpenSLES.h b/modules/juce_audio_devices/native/oboe/src/opensles/AudioInputStreamOpenSLES.h new file mode 100644 index 00000000..7be1c96d --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/opensles/AudioInputStreamOpenSLES.h @@ -0,0 +1,65 @@ +/* + * Copyright 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AUDIO_INPUT_STREAM_OPENSL_ES_H_ +#define AUDIO_INPUT_STREAM_OPENSL_ES_H_ + + +#include <SLES/OpenSLES.h> +#include <SLES/OpenSLES_Android.h> + +#include "oboe/Oboe.h" +#include "AudioStreamOpenSLES.h" + +namespace oboe { + +/** + * INTERNAL USE ONLY + */ + +class AudioInputStreamOpenSLES : public AudioStreamOpenSLES { +public: + AudioInputStreamOpenSLES(); + explicit AudioInputStreamOpenSLES(const AudioStreamBuilder &builder); + + virtual ~AudioInputStreamOpenSLES(); + + Result open() override; + Result close() override; + + Result requestStart() override; + Result requestPause() override; + Result requestFlush() override; + Result requestStop() override; + +protected: + + Result updateServiceFrameCounter() override; + + void updateFramesWritten() override; + +private: + + SLuint32 channelCountToChannelMask(int chanCount) const; + + Result setRecordState_l(SLuint32 newState); + + SLRecordItf mRecordInterface = nullptr; +}; + +} // namespace oboe + +#endif //AUDIO_INPUT_STREAM_OPENSL_ES_H_ diff --git a/modules/juce_audio_devices/native/oboe/src/opensles/AudioOutputStreamOpenSLES.cpp b/modules/juce_audio_devices/native/oboe/src/opensles/AudioOutputStreamOpenSLES.cpp new file mode 100644 index 00000000..cdb88832 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/opensles/AudioOutputStreamOpenSLES.cpp @@ -0,0 +1,448 @@ +/* + * Copyright 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <cassert> + +#include <SLES/OpenSLES.h> +#include <SLES/OpenSLES_Android.h> +#include <common/AudioClock.h> + +#include "oboe/AudioStreamBuilder.h" +#include "AudioOutputStreamOpenSLES.h" +#include "AudioStreamOpenSLES.h" +#include "OpenSLESUtilities.h" +#include "OutputMixerOpenSLES.h" + +using namespace oboe; + +static SLuint32 OpenSLES_convertOutputUsage(Usage oboeUsage) { + SLuint32 openslStream = SL_ANDROID_STREAM_MEDIA; + switch(oboeUsage) { + case Usage::Media: + openslStream = SL_ANDROID_STREAM_MEDIA; + break; + case Usage::VoiceCommunication: + case Usage::VoiceCommunicationSignalling: + openslStream = SL_ANDROID_STREAM_VOICE; + break; + case Usage::Alarm: + openslStream = SL_ANDROID_STREAM_ALARM; + break; + case Usage::Notification: + case Usage::NotificationRingtone: + case Usage::NotificationEvent: + openslStream = SL_ANDROID_STREAM_NOTIFICATION; + break; + case Usage::AssistanceAccessibility: + case Usage::AssistanceNavigationGuidance: + case Usage::AssistanceSonification: + openslStream = SL_ANDROID_STREAM_SYSTEM; + break; + case Usage::Game: + openslStream = SL_ANDROID_STREAM_MEDIA; + break; + case Usage::Assistant: + default: + openslStream = SL_ANDROID_STREAM_SYSTEM; + break; + } + return openslStream; +} + +AudioOutputStreamOpenSLES::AudioOutputStreamOpenSLES(const AudioStreamBuilder &builder) + : AudioStreamOpenSLES(builder) { +} + +// These will wind up in <SLES/OpenSLES_Android.h> +constexpr int SL_ANDROID_SPEAKER_STEREO = (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT); + +constexpr int SL_ANDROID_SPEAKER_QUAD = (SL_ANDROID_SPEAKER_STEREO + | SL_SPEAKER_BACK_LEFT | SL_SPEAKER_BACK_RIGHT); + +constexpr int SL_ANDROID_SPEAKER_5DOT1 = (SL_ANDROID_SPEAKER_QUAD + | SL_SPEAKER_FRONT_CENTER | SL_SPEAKER_LOW_FREQUENCY); + +constexpr int SL_ANDROID_SPEAKER_7DOT1 = (SL_ANDROID_SPEAKER_5DOT1 | SL_SPEAKER_SIDE_LEFT + | SL_SPEAKER_SIDE_RIGHT); + +SLuint32 AudioOutputStreamOpenSLES::channelCountToChannelMask(int channelCount) const { + SLuint32 channelMask = 0; + + switch (channelCount) { + case 1: + channelMask = SL_SPEAKER_FRONT_CENTER; + break; + + case 2: + channelMask = SL_ANDROID_SPEAKER_STEREO; + break; + + case 4: // Quad + channelMask = SL_ANDROID_SPEAKER_QUAD; + break; + + case 6: // 5.1 + channelMask = SL_ANDROID_SPEAKER_5DOT1; + break; + + case 8: // 7.1 + channelMask = SL_ANDROID_SPEAKER_7DOT1; + break; + + default: + channelMask = channelCountToChannelMaskDefault(channelCount); + break; + } + return channelMask; +} + +Result AudioOutputStreamOpenSLES::open() { + logUnsupportedAttributes(); + + SLAndroidConfigurationItf configItf = nullptr; + + + if (getSdkVersion() < __ANDROID_API_L__ && mFormat == AudioFormat::Float){ + // TODO: Allow floating point format on API <21 using float->int16 converter + return Result::ErrorInvalidFormat; + } + + // If audio format is unspecified then choose a suitable default. + // API 21+: FLOAT + // API <21: INT16 + if (mFormat == AudioFormat::Unspecified){ + mFormat = (getSdkVersion() < __ANDROID_API_L__) ? + AudioFormat::I16 : AudioFormat::Float; + } + + Result oboeResult = AudioStreamOpenSLES::open(); + if (Result::OK != oboeResult) return oboeResult; + + SLresult result = OutputMixerOpenSL::getInstance().open(); + if (SL_RESULT_SUCCESS != result) { + AudioStreamOpenSLES::close(); + return Result::ErrorInternal; + } + + SLuint32 bitsPerSample = static_cast<SLuint32>(getBytesPerSample() * kBitsPerByte); + + // configure audio source + SLDataLocator_AndroidSimpleBufferQueue loc_bufq = { + SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, // locatorType + static_cast<SLuint32>(kBufferQueueLength)}; // numBuffers + + // Define the audio data format. + SLDataFormat_PCM format_pcm = { + SL_DATAFORMAT_PCM, // formatType + static_cast<SLuint32>(mChannelCount), // numChannels + static_cast<SLuint32>(mSampleRate * kMillisPerSecond), // milliSamplesPerSec + bitsPerSample, // bitsPerSample + bitsPerSample, // containerSize; + channelCountToChannelMask(mChannelCount), // channelMask + getDefaultByteOrder(), + }; + + SLDataSource audioSrc = {&loc_bufq, &format_pcm}; + + /** + * API 21 (Lollipop) introduced support for floating-point data representation and an extended + * data format type: SLAndroidDataFormat_PCM_EX. If running on API 21+ use this newer format + * type, creating it from our original format. + */ + SLAndroidDataFormat_PCM_EX format_pcm_ex; + if (getSdkVersion() >= __ANDROID_API_L__) { + SLuint32 representation = OpenSLES_ConvertFormatToRepresentation(getFormat()); + // Fill in the format structure. + format_pcm_ex = OpenSLES_createExtendedFormat(format_pcm, representation); + // Use in place of the previous format. + audioSrc.pFormat = &format_pcm_ex; + } + + result = OutputMixerOpenSL::getInstance().createAudioPlayer(&mObjectInterface, + &audioSrc); + if (SL_RESULT_SUCCESS != result) { + LOGE("createAudioPlayer() result:%s", getSLErrStr(result)); + goto error; + } + + // Configure the stream. + result = (*mObjectInterface)->GetInterface(mObjectInterface, + SL_IID_ANDROIDCONFIGURATION, + (void *)&configItf); + if (SL_RESULT_SUCCESS != result) { + LOGW("%s() GetInterface(SL_IID_ANDROIDCONFIGURATION) failed with %s", + __func__, getSLErrStr(result)); + } else { + result = configurePerformanceMode(configItf); + if (SL_RESULT_SUCCESS != result) { + goto error; + } + + SLuint32 presetValue = OpenSLES_convertOutputUsage(getUsage()); + result = (*configItf)->SetConfiguration(configItf, + SL_ANDROID_KEY_STREAM_TYPE, + &presetValue, + sizeof(presetValue)); + if (SL_RESULT_SUCCESS != result) { + goto error; + } + } + + result = (*mObjectInterface)->Realize(mObjectInterface, SL_BOOLEAN_FALSE); + if (SL_RESULT_SUCCESS != result) { + LOGE("Realize player object result:%s", getSLErrStr(result)); + goto error; + } + + result = (*mObjectInterface)->GetInterface(mObjectInterface, SL_IID_PLAY, &mPlayInterface); + if (SL_RESULT_SUCCESS != result) { + LOGE("GetInterface PLAY result:%s", getSLErrStr(result)); + goto error; + } + + result = AudioStreamOpenSLES::registerBufferQueueCallback(); + if (SL_RESULT_SUCCESS != result) { + goto error; + } + + result = updateStreamParameters(configItf); + if (SL_RESULT_SUCCESS != result) { + goto error; + } + + oboeResult = configureBufferSizes(mSampleRate); + if (Result::OK != oboeResult) { + goto error; + } + + allocateFifo(); + + setState(StreamState::Open); + return Result::OK; + +error: + return Result::ErrorInternal; // TODO convert error from SLES to OBOE +} + +Result AudioOutputStreamOpenSLES::onAfterDestroy() { + OutputMixerOpenSL::getInstance().close(); + return Result::OK; +} + +Result AudioOutputStreamOpenSLES::close() { + mLock.lock(); + Result result = Result::OK; + if (getState() == StreamState::Closed){ + result = Result::ErrorClosed; + } else { + mLock.unlock(); // avoid recursive lock + requestPause(); + mLock.lock(); + // invalidate any interfaces + mPlayInterface = nullptr; + result = AudioStreamOpenSLES::close(); + } + mLock.unlock(); // avoid recursive lock + return result; +} + +Result AudioOutputStreamOpenSLES::setPlayState_l(SLuint32 newState) { + + LOGD("AudioOutputStreamOpenSLES(): %s() called", __func__); + Result result = Result::OK; + + if (mPlayInterface == nullptr){ + LOGE("AudioOutputStreamOpenSLES::%s() mPlayInterface is null", __func__); + return Result::ErrorInvalidState; + } + + SLresult slResult = (*mPlayInterface)->SetPlayState(mPlayInterface, newState); + if (SL_RESULT_SUCCESS != slResult) { + LOGW("AudioOutputStreamOpenSLES(): %s() returned %s", __func__, getSLErrStr(slResult)); + result = Result::ErrorInternal; // TODO convert slResult to Result::Error + } + return result; +} + +Result AudioOutputStreamOpenSLES::requestStart() { + LOGD("AudioOutputStreamOpenSLES(): %s() called", __func__); + + mLock.lock(); + StreamState initialState = getState(); + switch (initialState) { + case StreamState::Starting: + case StreamState::Started: + mLock.unlock(); + return Result::OK; + case StreamState::Closed: + mLock.unlock(); + return Result::ErrorClosed; + default: + break; + } + + // We use a callback if the user requests one + // OR if we have an internal callback to read the blocking IO buffer. + setDataCallbackEnabled(true); + + setState(StreamState::Starting); + Result result = setPlayState_l(SL_PLAYSTATE_PLAYING); + if (result == Result::OK) { + setState(StreamState::Started); + mLock.unlock(); + if (getBufferDepth(mSimpleBufferQueueInterface) == 0) { + // Enqueue the first buffer if needed to start the streaming. + // This might call requestStop() so try to avoid a recursive lock. + processBufferCallback(mSimpleBufferQueueInterface); + } + } else { + setState(initialState); + mLock.unlock(); + } + return result; +} + +Result AudioOutputStreamOpenSLES::requestPause() { + LOGD("AudioOutputStreamOpenSLES(): %s() called", __func__); + + std::lock_guard<std::mutex> lock(mLock); + StreamState initialState = getState(); + switch (initialState) { + case StreamState::Pausing: + case StreamState::Paused: + return Result::OK; + case StreamState::Closed: + return Result::ErrorClosed; + default: + break; + } + + setState(StreamState::Pausing); + Result result = setPlayState_l(SL_PLAYSTATE_PAUSED); + if (result == Result::OK) { + // Note that OpenSL ES does NOT reset its millisecond position when OUTPUT is paused. + int64_t framesWritten = getFramesWritten(); + if (framesWritten >= 0) { + setFramesRead(framesWritten); + } + setState(StreamState::Paused); + } else { + setState(initialState); + } + return result; +} + +/** + * Flush/clear the queue buffers + */ +Result AudioOutputStreamOpenSLES::requestFlush() { + std::lock_guard<std::mutex> lock(mLock); + return requestFlush_l(); +} + +Result AudioOutputStreamOpenSLES::requestFlush_l() { + LOGD("AudioOutputStreamOpenSLES(): %s() called", __func__); + if (getState() == StreamState::Closed) { + return Result::ErrorClosed; + } + + Result result = Result::OK; + if (mPlayInterface == nullptr || mSimpleBufferQueueInterface == nullptr) { + result = Result::ErrorInvalidState; + } else { + SLresult slResult = (*mSimpleBufferQueueInterface)->Clear(mSimpleBufferQueueInterface); + if (slResult != SL_RESULT_SUCCESS){ + LOGW("Failed to clear buffer queue. OpenSLES error: %d", result); + result = Result::ErrorInternal; + } + } + return result; +} + +Result AudioOutputStreamOpenSLES::requestStop() { + LOGD("AudioOutputStreamOpenSLES(): %s() called", __func__); + + std::lock_guard<std::mutex> lock(mLock); + StreamState initialState = getState(); + switch (initialState) { + case StreamState::Stopping: + case StreamState::Stopped: + return Result::OK; + case StreamState::Closed: + return Result::ErrorClosed; + default: + break; + } + + setState(StreamState::Stopping); + + Result result = setPlayState_l(SL_PLAYSTATE_STOPPED); + if (result == Result::OK) { + + // Also clear the buffer queue so the old data won't be played if the stream is restarted. + // Call the _l function that expects to already be under a lock. + if (requestFlush_l() != Result::OK) { + LOGW("Failed to flush the stream. Error %s", convertToText(flush())); + } + + mPositionMillis.reset32(); // OpenSL ES resets its millisecond position when stopped. + int64_t framesWritten = getFramesWritten(); + if (framesWritten >= 0) { + setFramesRead(framesWritten); + } + setState(StreamState::Stopped); + } else { + setState(initialState); + } + return result; +} + +void AudioOutputStreamOpenSLES::setFramesRead(int64_t framesRead) { + int64_t millisWritten = framesRead * kMillisPerSecond / getSampleRate(); + mPositionMillis.set(millisWritten); +} + +void AudioOutputStreamOpenSLES::updateFramesRead() { + if (usingFIFO()) { + AudioStreamBuffered::updateFramesRead(); + } else { + mFramesRead = getFramesProcessedByServer(); + } +} + +Result AudioOutputStreamOpenSLES::updateServiceFrameCounter() { + Result result = Result::OK; + // Avoid deadlock if another thread is trying to stop or close this stream + // and this is being called from a callback. + if (mLock.try_lock()) { + + if (mPlayInterface == nullptr) { + mLock.unlock(); + return Result::ErrorNull; + } + SLmillisecond msec = 0; + SLresult slResult = (*mPlayInterface)->GetPosition(mPlayInterface, &msec); + if (SL_RESULT_SUCCESS != slResult) { + LOGW("%s(): GetPosition() returned %s", __func__, getSLErrStr(slResult)); + // set result based on SLresult + result = Result::ErrorInternal; + } else { + mPositionMillis.update32(msec); + } + mLock.unlock(); + } + return result; +} diff --git a/modules/juce_audio_devices/native/oboe/src/opensles/AudioOutputStreamOpenSLES.h b/modules/juce_audio_devices/native/oboe/src/opensles/AudioOutputStreamOpenSLES.h new file mode 100644 index 00000000..d74faf67 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/opensles/AudioOutputStreamOpenSLES.h @@ -0,0 +1,77 @@ +/* + * Copyright 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AUDIO_OUTPUT_STREAM_OPENSL_ES_H_ +#define AUDIO_OUTPUT_STREAM_OPENSL_ES_H_ + + +#include <SLES/OpenSLES.h> +#include <SLES/OpenSLES_Android.h> + +#include "oboe/Oboe.h" +#include "AudioStreamOpenSLES.h" + +namespace oboe { + +/** + * INTERNAL USE ONLY + */ +class AudioOutputStreamOpenSLES : public AudioStreamOpenSLES { +public: + AudioOutputStreamOpenSLES(); + explicit AudioOutputStreamOpenSLES(const AudioStreamBuilder &builder); + + virtual ~AudioOutputStreamOpenSLES() = default; + + Result open() override; + Result close() override; + + Result requestStart() override; + Result requestPause() override; + Result requestFlush() override; + Result requestStop() override; + +protected: + + void setFramesRead(int64_t framesRead); + + Result updateServiceFrameCounter() override; + + void updateFramesRead() override; + +private: + + SLuint32 channelCountToChannelMask(int chanCount) const; + + Result onAfterDestroy() override; + + Result requestFlush_l(); + + /** + * Set OpenSL ES PLAYSTATE. + * + * @param newState SL_PLAYSTATE_PAUSED, SL_PLAYSTATE_PLAYING, SL_PLAYSTATE_STOPPED + * @return + */ + Result setPlayState_l(SLuint32 newState); + + SLPlayItf mPlayInterface = nullptr; + +}; + +} // namespace oboe + +#endif //AUDIO_OUTPUT_STREAM_OPENSL_ES_H_ diff --git a/modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamBuffered.cpp b/modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamBuffered.cpp new file mode 100644 index 00000000..85b9f8e4 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamBuffered.cpp @@ -0,0 +1,266 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <memory> + +#include "oboe/Oboe.h" + +#include "opensles/AudioStreamBuffered.h" +#include "common/AudioClock.h" + +namespace oboe { + +constexpr int kDefaultBurstsPerBuffer = 16; // arbitrary, allows dynamic latency tuning +constexpr int kMinBurstsPerBuffer = 4; // arbitrary, allows dynamic latency tuning +constexpr int kMinFramesPerBuffer = 48 * 32; // arbitrary + +/* + * AudioStream with a FifoBuffer + */ +AudioStreamBuffered::AudioStreamBuffered(const AudioStreamBuilder &builder) + : AudioStream(builder) { +} + +void AudioStreamBuffered::allocateFifo() { + // If the caller does not provide a callback use our own internal + // callback that reads data from the FIFO. + if (usingFIFO()) { + // FIFO is configured with the same format and channels as the stream. + int32_t capacityFrames = getBufferCapacityInFrames(); + if (capacityFrames == oboe::kUnspecified) { + capacityFrames = getFramesPerBurst() * kDefaultBurstsPerBuffer; + } else { + int32_t minFramesPerBufferByBursts = getFramesPerBurst() * kMinBurstsPerBuffer; + if (capacityFrames <= minFramesPerBufferByBursts) { + capacityFrames = minFramesPerBufferByBursts; + } else { + capacityFrames = std::max(kMinFramesPerBuffer, capacityFrames); + // round up to nearest burst + int32_t numBursts = (capacityFrames + getFramesPerBurst() - 1) + / getFramesPerBurst(); + capacityFrames = numBursts * getFramesPerBurst(); + } + } + // TODO consider using std::make_unique if we require c++14 + mFifoBuffer.reset(new FifoBuffer(getBytesPerFrame(), capacityFrames)); + mBufferCapacityInFrames = capacityFrames; + } +} + +void AudioStreamBuffered::updateFramesWritten() { + if (mFifoBuffer) { + mFramesWritten = static_cast<int64_t>(mFifoBuffer->getWriteCounter()); + } // or else it will get updated by processBufferCallback() +} + +void AudioStreamBuffered::updateFramesRead() { + if (mFifoBuffer) { + mFramesRead = static_cast<int64_t>(mFifoBuffer->getReadCounter()); + } // or else it will get updated by processBufferCallback() +} + +// This is called by the OpenSL ES callback to read or write the back end of the FIFO. +DataCallbackResult AudioStreamBuffered::onDefaultCallback(void *audioData, int numFrames) { + int32_t framesTransferred = 0; + + if (getDirection() == oboe::Direction::Output) { + // Read from the FIFO and write to audioData, clear part of buffer if not enough data. + framesTransferred = mFifoBuffer->readNow(audioData, numFrames); + } else { + // Read from audioData and write to the FIFO + framesTransferred = mFifoBuffer->write(audioData, numFrames); // There is no writeNow() + } + + if (framesTransferred < numFrames) { + LOGD("AudioStreamBuffered::%s(): xrun! framesTransferred = %d, numFrames = %d", + __func__, framesTransferred, numFrames); + // TODO If we do not allow FIFO to wrap then our timestamps will drift when there is an XRun! + incrementXRunCount(); + } + markCallbackTime(static_cast<int32_t>(numFrames)); // so foreground knows how long to wait. + return DataCallbackResult::Continue; +} + +void AudioStreamBuffered::markCallbackTime(int32_t numFrames) { + mLastBackgroundSize = numFrames; + mBackgroundRanAtNanoseconds = AudioClock::getNanoseconds(); +} + +int64_t AudioStreamBuffered::predictNextCallbackTime() { + if (mBackgroundRanAtNanoseconds == 0) { + return 0; + } + int64_t nanosPerBuffer = (kNanosPerSecond * mLastBackgroundSize) / getSampleRate(); + const int64_t margin = 200 * kNanosPerMicrosecond; // arbitrary delay so we wake up just after + return mBackgroundRanAtNanoseconds + nanosPerBuffer + margin; +} + +// Common code for read/write. +// @return Result::OK with frames read/written, or Result::Error* +ResultWithValue<int32_t> AudioStreamBuffered::transfer(void *buffer, + int32_t numFrames, + int64_t timeoutNanoseconds) { + // Validate arguments. + if (buffer == nullptr) { + LOGE("AudioStreamBuffered::%s(): buffer is NULL", __func__); + return ResultWithValue<int32_t>(Result::ErrorNull); + } + if (numFrames < 0) { + LOGE("AudioStreamBuffered::%s(): numFrames is negative", __func__); + return ResultWithValue<int32_t>(Result::ErrorOutOfRange); + } else if (numFrames == 0) { + return ResultWithValue<int32_t>(numFrames); + } + if (timeoutNanoseconds < 0) { + LOGE("AudioStreamBuffered::%s(): timeoutNanoseconds is negative", __func__); + return ResultWithValue<int32_t>(Result::ErrorOutOfRange); + } + + int32_t result = 0; + uint8_t *data = reinterpret_cast<uint8_t *>(buffer); + int32_t framesLeft = numFrames; + int64_t timeToQuit = 0; + bool repeat = true; + + // Calculate when to timeout. + if (timeoutNanoseconds > 0) { + timeToQuit = AudioClock::getNanoseconds() + timeoutNanoseconds; + } + + // Loop until we get the data, or we have an error, or we timeout. + do { + // read or write + if (getDirection() == Direction::Input) { + result = mFifoBuffer->read(data, framesLeft); + } else { + // between zero and capacity + uint32_t fullFrames = mFifoBuffer->getFullFramesAvailable(); + // Do not write above threshold size. + int32_t emptyFrames = getBufferSizeInFrames() - static_cast<int32_t>(fullFrames); + int32_t framesToWrite = std::max(0, std::min(framesLeft, emptyFrames)); + result = mFifoBuffer->write(data, framesToWrite); + } + if (result > 0) { + data += mFifoBuffer->convertFramesToBytes(result); + framesLeft -= result; + } + + // If we need more data then sleep and try again. + if (framesLeft > 0 && result >= 0 && timeoutNanoseconds > 0) { + int64_t timeNow = AudioClock::getNanoseconds(); + if (timeNow >= timeToQuit) { + LOGE("AudioStreamBuffered::%s(): TIMEOUT", __func__); + repeat = false; // TIMEOUT + } else { + // Figure out how long to sleep. + int64_t sleepForNanos; + int64_t wakeTimeNanos = predictNextCallbackTime(); + if (wakeTimeNanos <= 0) { + // No estimate available. Sleep for one burst. + sleepForNanos = (getFramesPerBurst() * kNanosPerSecond) / getSampleRate(); + } else { + // Don't sleep past timeout. + if (wakeTimeNanos > timeToQuit) { + wakeTimeNanos = timeToQuit; + } + sleepForNanos = wakeTimeNanos - timeNow; + // Avoid rapid loop with no sleep. + const int64_t minSleepTime = kNanosPerMillisecond; // arbitrary + if (sleepForNanos < minSleepTime) { + sleepForNanos = minSleepTime; + } + } + + AudioClock::sleepForNanos(sleepForNanos); + } + + } else { + repeat = false; + } + } while(repeat); + + if (result < 0) { + return ResultWithValue<int32_t>(static_cast<Result>(result)); + } else { + int32_t framesWritten = numFrames - framesLeft; + return ResultWithValue<int32_t>(framesWritten); + } +} + +// Write to the FIFO so the callback can read from it. +ResultWithValue<int32_t> AudioStreamBuffered::write(const void *buffer, + int32_t numFrames, + int64_t timeoutNanoseconds) { + if (getState() == StreamState::Closed){ + return ResultWithValue<int32_t>(Result::ErrorClosed); + } + + if (getDirection() == Direction::Input) { + return ResultWithValue<int32_t>(Result::ErrorUnavailable); // TODO review, better error code? + } + updateServiceFrameCounter(); + return transfer(const_cast<void *>(buffer), numFrames, timeoutNanoseconds); +} + +// Read data from the FIFO that was written by the callback. +ResultWithValue<int32_t> AudioStreamBuffered::read(void *buffer, + int32_t numFrames, + int64_t timeoutNanoseconds) { + if (getState() == StreamState::Closed){ + return ResultWithValue<int32_t>(Result::ErrorClosed); + } + + if (getDirection() == Direction::Output) { + return ResultWithValue<int32_t>(Result::ErrorUnavailable); // TODO review, better error code? + } + updateServiceFrameCounter(); + return transfer(buffer, numFrames, timeoutNanoseconds); +} + +// Only supported when we are not using a callback. +ResultWithValue<int32_t> AudioStreamBuffered::setBufferSizeInFrames(int32_t requestedFrames) +{ + if (getState() == StreamState::Closed){ + return ResultWithValue<int32_t>(Result::ErrorClosed); + } + + if (!mFifoBuffer) { + return ResultWithValue<int32_t>(Result::ErrorUnimplemented); + } + + if (requestedFrames > mFifoBuffer->getBufferCapacityInFrames()) { + requestedFrames = mFifoBuffer->getBufferCapacityInFrames(); + } else if (requestedFrames < getFramesPerBurst()) { + requestedFrames = getFramesPerBurst(); + } + mBufferSizeInFrames = requestedFrames; + return ResultWithValue<int32_t>(requestedFrames); +} + +int32_t AudioStreamBuffered::getBufferCapacityInFrames() const { + if (mFifoBuffer) { + return mFifoBuffer->getBufferCapacityInFrames(); + } else { + return AudioStream::getBufferCapacityInFrames(); + } +} + +bool AudioStreamBuffered::isXRunCountSupported() const { + // XRun count is only supported if we're using blocking I/O (not callbacks) + return (getCallback() == nullptr); +} + +} // namespace oboe \ No newline at end of file diff --git a/modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamBuffered.h b/modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamBuffered.h new file mode 100644 index 00000000..5923e8db --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamBuffered.h @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBOE_STREAM_BUFFERED_H +#define OBOE_STREAM_BUFFERED_H + +#include <cstring> +#include <cassert> +#include "common/OboeDebug.h" +#include "oboe/AudioStream.h" +#include "oboe/AudioStreamCallback.h" +#include "fifo/FifoBuffer.h" + +namespace oboe { + +// A stream that contains a FIFO buffer. +// This is used to implement blocking reads and writes. +class AudioStreamBuffered : public AudioStream { +public: + + AudioStreamBuffered(); + explicit AudioStreamBuffered(const AudioStreamBuilder &builder); + + void allocateFifo(); + + + ResultWithValue<int32_t> write(const void *buffer, + int32_t numFrames, + int64_t timeoutNanoseconds) override; + + ResultWithValue<int32_t> read(void *buffer, + int32_t numFrames, + int64_t timeoutNanoseconds) override; + + ResultWithValue<int32_t> setBufferSizeInFrames(int32_t requestedFrames) override; + + int32_t getBufferCapacityInFrames() const override; + + ResultWithValue<int32_t> getXRunCount() const override { + return ResultWithValue<int32_t>(mXRunCount); + } + + bool isXRunCountSupported() const override; + +protected: + + DataCallbackResult onDefaultCallback(void *audioData, int numFrames) override; + + // If there is no callback then we need a FIFO between the App and OpenSL ES. + bool usingFIFO() const { return getCallback() == nullptr; } + + virtual Result updateServiceFrameCounter() = 0; + + void updateFramesRead() override; + void updateFramesWritten() override; + +private: + + int64_t predictNextCallbackTime(); + + void markCallbackTime(int32_t numFrames); + + // Read or write to the FIFO. + ResultWithValue<int32_t> transfer(void *buffer, int32_t numFrames, int64_t timeoutNanoseconds); + + void incrementXRunCount() { + ++mXRunCount; + } + + std::unique_ptr<FifoBuffer> mFifoBuffer{}; + + int64_t mBackgroundRanAtNanoseconds = 0; + int32_t mLastBackgroundSize = 0; + int32_t mXRunCount = 0; +}; + +} // namespace oboe + +#endif //OBOE_STREAM_BUFFERED_H diff --git a/modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamOpenSLES.cpp b/modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamOpenSLES.cpp new file mode 100644 index 00000000..3af1a30e --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamOpenSLES.cpp @@ -0,0 +1,396 @@ +/* Copyright 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <sys/types.h> +#include <cassert> +#include <android/log.h> + + +#include <SLES/OpenSLES.h> +#include <SLES/OpenSLES_Android.h> +#include <oboe/AudioStream.h> +#include <common/AudioClock.h> + +#include "common/OboeDebug.h" +#include "oboe/AudioStreamBuilder.h" +#include "AudioStreamOpenSLES.h" +#include "OpenSLESUtilities.h" + +using namespace oboe; + +AudioStreamOpenSLES::AudioStreamOpenSLES(const AudioStreamBuilder &builder) + : AudioStreamBuffered(builder) { + // OpenSL ES does not support device IDs. So overwrite value from builder. + mDeviceId = kUnspecified; + // OpenSL ES does not support session IDs. So overwrite value from builder. + mSessionId = SessionId::None; +} + +static constexpr int32_t kHighLatencyBufferSizeMillis = 20; // typical Android period +static constexpr SLuint32 kAudioChannelCountMax = 30; // TODO Why 30? +static constexpr SLuint32 SL_ANDROID_UNKNOWN_CHANNELMASK = 0; // Matches name used internally. + +SLuint32 AudioStreamOpenSLES::channelCountToChannelMaskDefault(int channelCount) const { + if (channelCount > kAudioChannelCountMax) { + return SL_ANDROID_UNKNOWN_CHANNELMASK; + } + + SLuint32 bitfield = (1 << channelCount) - 1; + + // Check for OS at run-time. + if(getSdkVersion() >= __ANDROID_API_N__) { + return SL_ANDROID_MAKE_INDEXED_CHANNEL_MASK(bitfield); + } + + // Indexed channels masks were added in N. + // For before N, the best we can do is use a positional channel mask. + return bitfield; +} + +static bool s_isLittleEndian() { + static uint32_t value = 1; + return (*reinterpret_cast<uint8_t *>(&value) == 1); // Does address point to LSB? +} + +SLuint32 AudioStreamOpenSLES::getDefaultByteOrder() { + return s_isLittleEndian() ? SL_BYTEORDER_LITTLEENDIAN : SL_BYTEORDER_BIGENDIAN; +} + +Result AudioStreamOpenSLES::open() { + + LOGI("AudioStreamOpenSLES::open() chans=%d, rate=%d", mChannelCount, mSampleRate); + + SLresult result = EngineOpenSLES::getInstance().open(); + if (SL_RESULT_SUCCESS != result) { + return Result::ErrorInternal; + } + + Result oboeResult = AudioStreamBuffered::open(); + if (oboeResult != Result::OK) { + return oboeResult; + } + // Convert to defaults if UNSPECIFIED + if (mSampleRate == kUnspecified) { + mSampleRate = DefaultStreamValues::SampleRate; + } + if (mChannelCount == kUnspecified) { + mChannelCount = DefaultStreamValues::ChannelCount; + } + + mSharingMode = SharingMode::Shared; + + return Result::OK; +} + +Result AudioStreamOpenSLES::configureBufferSizes(int32_t sampleRate) { + LOGD("AudioStreamOpenSLES:%s(%d) initial mFramesPerBurst = %d, mFramesPerCallback = %d", + __func__, sampleRate, mFramesPerBurst, mFramesPerCallback); + // Decide frames per burst based on hints from caller. + if (mFramesPerCallback != kUnspecified) { + // Requested framesPerCallback must be honored. + mFramesPerBurst = mFramesPerCallback; + } else { + mFramesPerBurst = DefaultStreamValues::FramesPerBurst; + + // Calculate the size of a fixed duration high latency buffer based on sample rate. + int32_t framesPerHighLatencyBuffer = + (kHighLatencyBufferSizeMillis * sampleRate) / kMillisPerSecond; + + // For high latency streams, use a larger buffer size. + // Performance Mode support was added in N_MR1 (7.1) + if (getSdkVersion() >= __ANDROID_API_N_MR1__ + && mPerformanceMode != PerformanceMode::LowLatency + && mFramesPerBurst < framesPerHighLatencyBuffer) { + // Find a multiple of framesPerBurst >= framesPerHighLatencyBuffer. + int32_t numBursts = (framesPerHighLatencyBuffer + mFramesPerBurst - 1) / mFramesPerBurst; + mFramesPerBurst *= numBursts; + LOGD("AudioStreamOpenSLES:%s() NOT low latency, set mFramesPerBurst = %d", + __func__, mFramesPerBurst); + } + mFramesPerCallback = mFramesPerBurst; + } + LOGD("AudioStreamOpenSLES:%s(%d) final mFramesPerBurst = %d, mFramesPerCallback = %d", + __func__, sampleRate, mFramesPerBurst, mFramesPerCallback); + + mBytesPerCallback = mFramesPerCallback * getBytesPerFrame(); + if (mBytesPerCallback <= 0) { + LOGE("AudioStreamOpenSLES::open() bytesPerCallback < 0 = %d, bad format?", + mBytesPerCallback); + return Result::ErrorInvalidFormat; // causing bytesPerFrame == 0 + } + + mCallbackBuffer = std::make_unique<uint8_t[]>(mBytesPerCallback); + + if (!usingFIFO()) { + mBufferCapacityInFrames = mFramesPerBurst * kBufferQueueLength; + mBufferSizeInFrames = mBufferCapacityInFrames; + } + + return Result::OK; +} + +SLuint32 AudioStreamOpenSLES::convertPerformanceMode(PerformanceMode oboeMode) const { + SLuint32 openslMode = SL_ANDROID_PERFORMANCE_NONE; + switch(oboeMode) { + case PerformanceMode::None: + openslMode = SL_ANDROID_PERFORMANCE_NONE; + break; + case PerformanceMode::LowLatency: + openslMode = (getSessionId() == SessionId::None) ? SL_ANDROID_PERFORMANCE_LATENCY : SL_ANDROID_PERFORMANCE_LATENCY_EFFECTS; + break; + case PerformanceMode::PowerSaving: + openslMode = SL_ANDROID_PERFORMANCE_POWER_SAVING; + break; + default: + break; + } + return openslMode; +} + +PerformanceMode AudioStreamOpenSLES::convertPerformanceMode(SLuint32 openslMode) const { + PerformanceMode oboeMode = PerformanceMode::None; + switch(openslMode) { + case SL_ANDROID_PERFORMANCE_NONE: + oboeMode = PerformanceMode::None; + break; + case SL_ANDROID_PERFORMANCE_LATENCY: + case SL_ANDROID_PERFORMANCE_LATENCY_EFFECTS: + oboeMode = PerformanceMode::LowLatency; + break; + case SL_ANDROID_PERFORMANCE_POWER_SAVING: + oboeMode = PerformanceMode::PowerSaving; + break; + default: + break; + } + return oboeMode; +} + +void AudioStreamOpenSLES::logUnsupportedAttributes() { + // Log unsupported attributes + // only report if changed from the default + + // Device ID + if (mDeviceId != kUnspecified) { + LOGW("Device ID [AudioStreamBuilder::setDeviceId()] " + "is not supported on OpenSLES streams."); + } + // Sharing Mode + if (mSharingMode != SharingMode::Shared) { + LOGW("SharingMode [AudioStreamBuilder::setSharingMode()] " + "is not supported on OpenSLES streams."); + } + // Performance Mode + int sdkVersion = getSdkVersion(); + if (mPerformanceMode != PerformanceMode::None && sdkVersion < __ANDROID_API_N_MR1__) { + LOGW("PerformanceMode [AudioStreamBuilder::setPerformanceMode()] " + "is not supported on OpenSLES streams running on pre-Android N-MR1 versions."); + } + // Content Type + if (mContentType != ContentType::Music) { + LOGW("ContentType [AudioStreamBuilder::setContentType()] " + "is not supported on OpenSLES streams."); + } + + // Session Id + if (mSessionId != SessionId::None) { + LOGW("SessionId [AudioStreamBuilder::setSessionId()] " + "is not supported on OpenSLES streams."); + } + + // Input Preset + if (mInputPreset != InputPreset::VoiceRecognition) { + LOGW("InputPreset [AudioStreamBuilder::setInputPreset()] " + "is not supported on OpenSLES streams."); + } +} + +SLresult AudioStreamOpenSLES::configurePerformanceMode(SLAndroidConfigurationItf configItf) { + + if (configItf == nullptr) { + LOGW("%s() called with NULL configuration", __func__); + mPerformanceMode = PerformanceMode::None; + return SL_RESULT_INTERNAL_ERROR; + } + if (getSdkVersion() < __ANDROID_API_N_MR1__) { + LOGW("%s() not supported until N_MR1", __func__); + mPerformanceMode = PerformanceMode::None; + return SL_RESULT_SUCCESS; + } + + SLresult result = SL_RESULT_SUCCESS; + SLuint32 performanceMode = convertPerformanceMode(getPerformanceMode()); + result = (*configItf)->SetConfiguration(configItf, SL_ANDROID_KEY_PERFORMANCE_MODE, + &performanceMode, sizeof(performanceMode)); + if (SL_RESULT_SUCCESS != result) { + LOGW("SetConfiguration(PERFORMANCE_MODE, SL %u) returned %s", + performanceMode, getSLErrStr(result)); + mPerformanceMode = PerformanceMode::None; + } + + return result; +} + +SLresult AudioStreamOpenSLES::updateStreamParameters(SLAndroidConfigurationItf configItf) { + SLresult result = SL_RESULT_SUCCESS; + if(getSdkVersion() >= __ANDROID_API_N_MR1__ && configItf != nullptr) { + SLuint32 performanceMode = 0; + SLuint32 performanceModeSize = sizeof(performanceMode); + result = (*configItf)->GetConfiguration(configItf, SL_ANDROID_KEY_PERFORMANCE_MODE, + &performanceModeSize, &performanceMode); + // A bug in GetConfiguration() before P caused a wrong result code to be returned. + if (getSdkVersion() <= __ANDROID_API_O_MR1__) { + result = SL_RESULT_SUCCESS; // Ignore actual result before P. + } + + if (SL_RESULT_SUCCESS != result) { + LOGW("GetConfiguration(SL_ANDROID_KEY_PERFORMANCE_MODE) returned %d", result); + mPerformanceMode = PerformanceMode::None; // If we can't query it then assume None. + } else { + mPerformanceMode = convertPerformanceMode(performanceMode); // convert SL to Oboe mode + } + } else { + mPerformanceMode = PerformanceMode::None; // If we can't query it then assume None. + } + return result; +} + +Result AudioStreamOpenSLES::close() { + if (mState == StreamState::Closed) { + return Result::ErrorClosed; + } + + AudioStreamBuffered::close(); + + onBeforeDestroy(); + + if (mObjectInterface != nullptr) { + (*mObjectInterface)->Destroy(mObjectInterface); + mObjectInterface = nullptr; + } + + onAfterDestroy(); + + mSimpleBufferQueueInterface = nullptr; + EngineOpenSLES::getInstance().close(); + + setState(StreamState::Closed); + return Result::OK; +} + +SLresult AudioStreamOpenSLES::enqueueCallbackBuffer(SLAndroidSimpleBufferQueueItf bq) { + return (*bq)->Enqueue(bq, mCallbackBuffer.get(), mBytesPerCallback); +} + +int32_t AudioStreamOpenSLES::getBufferDepth(SLAndroidSimpleBufferQueueItf bq) { + SLAndroidSimpleBufferQueueState queueState; + SLresult result = (*bq)->GetState(bq, &queueState); + return (result == SL_RESULT_SUCCESS) ? queueState.count : -1; +} + +void AudioStreamOpenSLES::processBufferCallback(SLAndroidSimpleBufferQueueItf bq) { + bool stopStream = false; + // Ask the app callback to process the buffer. + DataCallbackResult result = fireDataCallback(mCallbackBuffer.get(), mFramesPerCallback); + if (result == DataCallbackResult::Continue) { + // Pass the buffer to OpenSLES. + SLresult enqueueResult = enqueueCallbackBuffer(bq); + if (enqueueResult != SL_RESULT_SUCCESS) { + LOGE("%s() returned %d", __func__, enqueueResult); + stopStream = true; + } + // Update Oboe client position with frames handled by the callback. + if (getDirection() == Direction::Input) { + mFramesRead += mFramesPerCallback; + } else { + mFramesWritten += mFramesPerCallback; + } + } else if (result == DataCallbackResult::Stop) { + LOGD("Oboe callback returned Stop"); + stopStream = true; + } else { + LOGW("Oboe callback returned unexpected value = %d", result); + stopStream = true; + } + if (stopStream) { + requestStop(); + } +} + +// This callback handler is called every time a buffer has been processed by OpenSL ES. +static void bqCallbackGlue(SLAndroidSimpleBufferQueueItf bq, void *context) { + (reinterpret_cast<AudioStreamOpenSLES *>(context))->processBufferCallback(bq); +} + +SLresult AudioStreamOpenSLES::registerBufferQueueCallback() { + // The BufferQueue + SLresult result = (*mObjectInterface)->GetInterface(mObjectInterface, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, + &mSimpleBufferQueueInterface); + if (SL_RESULT_SUCCESS != result) { + LOGE("get buffer queue interface:%p result:%s", + mSimpleBufferQueueInterface, + getSLErrStr(result)); + } else { + // Register the BufferQueue callback + result = (*mSimpleBufferQueueInterface)->RegisterCallback(mSimpleBufferQueueInterface, + bqCallbackGlue, this); + if (SL_RESULT_SUCCESS != result) { + LOGE("RegisterCallback result:%s", getSLErrStr(result)); + } + } + return result; +} + +int32_t AudioStreamOpenSLES::getFramesPerBurst() { + return mFramesPerBurst; +} + +int64_t AudioStreamOpenSLES::getFramesProcessedByServer() { + updateServiceFrameCounter(); + int64_t millis64 = mPositionMillis.get(); + int64_t framesProcessed = millis64 * getSampleRate() / kMillisPerSecond; + return framesProcessed; +} + +Result AudioStreamOpenSLES::waitForStateChange(StreamState currentState, + StreamState *nextState, + int64_t timeoutNanoseconds) { + Result oboeResult = Result::ErrorTimeout; + int64_t sleepTimeNanos = 20 * kNanosPerMillisecond; // arbitrary + int64_t timeLeftNanos = timeoutNanoseconds; + + while (true) { + const StreamState state = getState(); // this does not require a lock + if (nextState != nullptr) { + *nextState = state; + } + if (currentState != state) { // state changed? + oboeResult = Result::OK; + break; + } + + // Did we timeout or did user ask for non-blocking? + if (timeoutNanoseconds <= 0) { + break; + } + + if (sleepTimeNanos > timeLeftNanos){ + sleepTimeNanos = timeLeftNanos; + } + AudioClock::sleepForNanos(sleepTimeNanos); + timeLeftNanos -= sleepTimeNanos; + } + + return oboeResult; +} diff --git a/modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamOpenSLES.h b/modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamOpenSLES.h new file mode 100644 index 00000000..81fdc63e --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamOpenSLES.h @@ -0,0 +1,132 @@ +/* + * Copyright 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBOE_AUDIO_STREAM_OPENSL_ES_H_ +#define OBOE_AUDIO_STREAM_OPENSL_ES_H_ + +#include <memory> + +#include <SLES/OpenSLES.h> +#include <SLES/OpenSLES_Android.h> + +#include "oboe/Oboe.h" +#include "common/MonotonicCounter.h" +#include "opensles/AudioStreamBuffered.h" +#include "opensles/EngineOpenSLES.h" + +namespace oboe { + +constexpr int kBitsPerByte = 8; +constexpr int kBufferQueueLength = 2; // double buffered for callbacks + +/** + * INTERNAL USE ONLY + * + * A stream that wraps OpenSL ES. + * + * Do not instantiate this class directly. + * Use an OboeStreamBuilder to create one. + */ + +class AudioStreamOpenSLES : public AudioStreamBuffered { +public: + + AudioStreamOpenSLES(); + explicit AudioStreamOpenSLES(const AudioStreamBuilder &builder); + + virtual ~AudioStreamOpenSLES() = default; + + virtual Result open() override; + virtual Result close() override; + + /** + * Query the current state, eg. OBOE_STREAM_STATE_PAUSING + * + * @return state or a negative error. + */ + StreamState getState() const override { return mState.load(); } + + int32_t getFramesPerBurst() override; + + + AudioApi getAudioApi() const override { + return AudioApi::OpenSLES; + } + + /** + * Process next OpenSL ES buffer. + * Called by by OpenSL ES framework. + * + * This is public, but don't call it directly. + */ + void processBufferCallback(SLAndroidSimpleBufferQueueItf bq); + + Result waitForStateChange(StreamState currentState, + StreamState *nextState, + int64_t timeoutNanoseconds) override; + +protected: + + SLuint32 channelCountToChannelMaskDefault(int channelCount) const; + + virtual Result onBeforeDestroy() { return Result::OK; } + virtual Result onAfterDestroy() { return Result::OK; } + + static SLuint32 getDefaultByteOrder(); + + SLresult registerBufferQueueCallback(); + + int32_t getBufferDepth(SLAndroidSimpleBufferQueueItf bq); + + SLresult enqueueCallbackBuffer(SLAndroidSimpleBufferQueueItf bq); + + SLresult configurePerformanceMode(SLAndroidConfigurationItf configItf); + + SLresult updateStreamParameters(SLAndroidConfigurationItf configItf); + + PerformanceMode convertPerformanceMode(SLuint32 openslMode) const; + SLuint32 convertPerformanceMode(PerformanceMode oboeMode) const; + + Result configureBufferSizes(int32_t sampleRate); + + void logUnsupportedAttributes(); + + /** + * Internal use only. + * Use this instead of directly setting the internal state variable. + */ + void setState(StreamState state) { + mState.store(state); + } + + int64_t getFramesProcessedByServer(); + + // OpenSLES stuff + SLObjectItf mObjectInterface = nullptr; + SLAndroidSimpleBufferQueueItf mSimpleBufferQueueInterface = nullptr; + + int32_t mBytesPerCallback = oboe::kUnspecified; + MonotonicCounter mPositionMillis; // for tracking OpenSL ES service position + +private: + std::unique_ptr<uint8_t[]> mCallbackBuffer; + std::atomic<StreamState> mState{StreamState::Uninitialized}; + +}; + +} // namespace oboe + +#endif // OBOE_AUDIO_STREAM_OPENSL_ES_H_ diff --git a/modules/juce_audio_devices/native/oboe/src/opensles/EngineOpenSLES.cpp b/modules/juce_audio_devices/native/oboe/src/opensles/EngineOpenSLES.cpp new file mode 100644 index 00000000..d82219ee --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/opensles/EngineOpenSLES.cpp @@ -0,0 +1,101 @@ +/* + * Copyright 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "common/OboeDebug.h" +#include "EngineOpenSLES.h" +#include "OpenSLESUtilities.h" + +using namespace oboe; + +EngineOpenSLES &EngineOpenSLES::getInstance() { + static EngineOpenSLES sInstance; + return sInstance; +} + +SLresult EngineOpenSLES::open() { + std::lock_guard<std::mutex> lock(mLock); + + SLresult result = SL_RESULT_SUCCESS; + if (mOpenCount++ == 0) { + + // create engine + result = slCreateEngine(&mEngineObject, 0, NULL, 0, NULL, NULL); + if (SL_RESULT_SUCCESS != result) { + LOGE("EngineOpenSLES - slCreateEngine() result:%s", getSLErrStr(result)); + goto error; + } + + // realize the engine + result = (*mEngineObject)->Realize(mEngineObject, SL_BOOLEAN_FALSE); + if (SL_RESULT_SUCCESS != result) { + LOGE("EngineOpenSLES - Realize() engine result:%s", getSLErrStr(result)); + goto error; + } + + // get the engine interface, which is needed in order to create other objects + result = (*mEngineObject)->GetInterface(mEngineObject, SL_IID_ENGINE, &mEngineInterface); + if (SL_RESULT_SUCCESS != result) { + LOGE("EngineOpenSLES - GetInterface() engine result:%s", getSLErrStr(result)); + goto error; + } + } + + return result; + +error: + close(); + return result; +} + +void EngineOpenSLES::close() { + std::lock_guard<std::mutex> lock(mLock); + if (--mOpenCount == 0) { + if (mEngineObject != nullptr) { + (*mEngineObject)->Destroy(mEngineObject); + mEngineObject = nullptr; + mEngineInterface = nullptr; + } + } +} + +SLresult EngineOpenSLES::createOutputMix(SLObjectItf *objectItf) { + return (*mEngineInterface)->CreateOutputMix(mEngineInterface, objectItf, 0, 0, 0); +} + +SLresult EngineOpenSLES::createAudioPlayer(SLObjectItf *objectItf, + SLDataSource *audioSource, + SLDataSink *audioSink) { + + const SLInterfaceID ids[] = {SL_IID_BUFFERQUEUE, SL_IID_ANDROIDCONFIGURATION}; + const SLboolean reqs[] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE}; + + return (*mEngineInterface)->CreateAudioPlayer(mEngineInterface, objectItf, audioSource, + audioSink, + sizeof(ids) / sizeof(ids[0]), ids, reqs); +} + +SLresult EngineOpenSLES::createAudioRecorder(SLObjectItf *objectItf, + SLDataSource *audioSource, + SLDataSink *audioSink) { + + const SLInterfaceID ids[] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_ANDROIDCONFIGURATION }; + const SLboolean reqs[] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE}; + + return (*mEngineInterface)->CreateAudioRecorder(mEngineInterface, objectItf, audioSource, + audioSink, + sizeof(ids) / sizeof(ids[0]), ids, reqs); +} + diff --git a/modules/juce_audio_devices/native/oboe/src/opensles/EngineOpenSLES.h b/modules/juce_audio_devices/native/oboe/src/opensles/EngineOpenSLES.h new file mode 100644 index 00000000..3d238a8c --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/opensles/EngineOpenSLES.h @@ -0,0 +1,65 @@ +/* + * Copyright 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBOE_ENGINE_OPENSLES_H +#define OBOE_ENGINE_OPENSLES_H + +#include <atomic> +#include <mutex> + +#include <SLES/OpenSLES.h> +#include <SLES/OpenSLES_Android.h> + +namespace oboe { + +/** + * INTERNAL USE ONLY + */ +class EngineOpenSLES { +public: + static EngineOpenSLES &getInstance(); + + SLresult open(); + + void close(); + + SLresult createOutputMix(SLObjectItf *objectItf); + + SLresult createAudioPlayer(SLObjectItf *objectItf, + SLDataSource *audioSource, + SLDataSink *audioSink); + SLresult createAudioRecorder(SLObjectItf *objectItf, + SLDataSource *audioSource, + SLDataSink *audioSink); + +private: + // Make this a safe Singleton + EngineOpenSLES()= default; + ~EngineOpenSLES()= default; + EngineOpenSLES(const EngineOpenSLES&)= delete; + EngineOpenSLES& operator=(const EngineOpenSLES&)= delete; + + std::mutex mLock; + int32_t mOpenCount = 0; + + SLObjectItf mEngineObject = nullptr; + SLEngineItf mEngineInterface = nullptr; +}; + +} // namespace oboe + + +#endif //OBOE_ENGINE_OPENSLES_H diff --git a/modules/juce_audio_devices/native/oboe/src/opensles/OpenSLESUtilities.cpp b/modules/juce_audio_devices/native/oboe/src/opensles/OpenSLESUtilities.cpp new file mode 100644 index 00000000..071c0d08 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/opensles/OpenSLESUtilities.cpp @@ -0,0 +1,93 @@ +/* + * Copyright 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "OpenSLESUtilities.h" + +namespace oboe { + +/* + * OSLES Helpers + */ + +const char *getSLErrStr(SLresult code) { + switch (code) { + case 0: + return "SL_RESULT_SUCCESS"; + case 1: + return "SL_RESULT_PRECONDITIONS_VIOLATE"; + case 2: + return "SL_RESULT_PARAMETER_INVALID"; + case 3: + return "SL_RESULT_MEMORY_FAILURE"; + case 4: + return "SL_RESULT_RESOURCE_ERROR"; + case 5: + return "SL_RESULT_RESOURCE_LOST"; + case 6: + return "SL_RESULT_IO_ERROR"; + case 7: + return "SL_RESULT_BUFFER_INSUFFICIENT"; + case 8: + return "SL_RESULT_CONTENT_CORRUPTED"; + case 9: + return "SL_RESULT_CONTENT_UNSUPPORTED"; + case 10: + return "SL_RESULT_CONTENT_NOT_FOUND"; + case 11: + return "SL_RESULT_PERMISSION_DENIED"; + case 12: + return "SL_RESULT_FEATURE_UNSUPPORTED"; + case 13: + return "SL_RESULT_INTERNAL_ERROR"; + case 14: + return "SL_RESULT_UNKNOWN_ERROR"; + case 15: + return "SL_RESULT_OPERATION_ABORTED"; + case 16: + return "SL_RESULT_CONTROL_LOST"; + default: + return "Unknown error"; + } +} + +SLAndroidDataFormat_PCM_EX OpenSLES_createExtendedFormat( + SLDataFormat_PCM format, SLuint32 representation) { + SLAndroidDataFormat_PCM_EX format_pcm_ex; + format_pcm_ex.formatType = SL_ANDROID_DATAFORMAT_PCM_EX; + format_pcm_ex.numChannels = format.numChannels; + format_pcm_ex.sampleRate = format.samplesPerSec; + format_pcm_ex.bitsPerSample = format.bitsPerSample; + format_pcm_ex.containerSize = format.containerSize; + format_pcm_ex.channelMask = format.channelMask; + format_pcm_ex.endianness = format.endianness; + format_pcm_ex.representation = representation; + return format_pcm_ex; +} + +SLuint32 OpenSLES_ConvertFormatToRepresentation(AudioFormat format) { + switch(format) { + case AudioFormat::I16: + return SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT; + case AudioFormat::Float: + return SL_ANDROID_PCM_REPRESENTATION_FLOAT; + case AudioFormat::Invalid: + case AudioFormat::Unspecified: + default: + return 0; + } +} + +} // namespace oboe diff --git a/modules/juce_audio_devices/native/oboe/src/opensles/OpenSLESUtilities.h b/modules/juce_audio_devices/native/oboe/src/opensles/OpenSLESUtilities.h new file mode 100644 index 00000000..50c0e2da --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/opensles/OpenSLESUtilities.h @@ -0,0 +1,44 @@ +/* + * Copyright 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBOE_OPENSLES_OPENSLESUTILITIES_H +#define OBOE_OPENSLES_OPENSLESUTILITIES_H + +#include <SLES/OpenSLES_Android.h> +#include "oboe/Oboe.h" + +namespace oboe { + +const char *getSLErrStr(SLresult code); + +/** + * Creates an extended PCM format from the supplied format and data representation. This method + * should only be called on Android devices with API level 21+. API 21 introduced the + * SLAndroidDataFormat_PCM_EX object which allows audio samples to be represented using + * single precision floating-point. + * + * @param format + * @param representation + * @return the extended PCM format + */ +SLAndroidDataFormat_PCM_EX OpenSLES_createExtendedFormat(SLDataFormat_PCM format, + SLuint32 representation); + +SLuint32 OpenSLES_ConvertFormatToRepresentation(AudioFormat format); + +} // namespace oboe + +#endif //OBOE_OPENSLES_OPENSLESUTILITIES_H diff --git a/modules/juce_audio_devices/native/oboe/src/opensles/OutputMixerOpenSLES.cpp b/modules/juce_audio_devices/native/oboe/src/opensles/OutputMixerOpenSLES.cpp new file mode 100644 index 00000000..e06f306b --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/opensles/OutputMixerOpenSLES.cpp @@ -0,0 +1,74 @@ +/* + * Copyright 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include "common/OboeDebug.h" +#include "EngineOpenSLES.h" +#include "OpenSLESUtilities.h" +#include "OutputMixerOpenSLES.h" + +using namespace oboe; + +OutputMixerOpenSL &OutputMixerOpenSL::getInstance() { + static OutputMixerOpenSL sInstance; + return sInstance; +} + +SLresult OutputMixerOpenSL::open() { + std::lock_guard<std::mutex> lock(mLock); + + SLresult result = SL_RESULT_SUCCESS; + if (mOpenCount++ == 0) { + // get the output mixer + result = EngineOpenSLES::getInstance().createOutputMix(&mOutputMixObject); + if (SL_RESULT_SUCCESS != result) { + LOGE("OutputMixerOpenSL() - createOutputMix() result:%s", getSLErrStr(result)); + goto error; + } + + // realize the output mix + result = (*mOutputMixObject)->Realize(mOutputMixObject, SL_BOOLEAN_FALSE); + if (SL_RESULT_SUCCESS != result) { + LOGE("OutputMixerOpenSL() - Realize() mOutputMixObject result:%s", getSLErrStr(result)); + goto error; + } + } + + return result; + +error: + close(); + return result; +} + +void OutputMixerOpenSL::close() { + std::lock_guard<std::mutex> lock(mLock); + + if (--mOpenCount == 0) { + // destroy output mix object, and invalidate all associated interfaces + if (mOutputMixObject != nullptr) { + (*mOutputMixObject)->Destroy(mOutputMixObject); + mOutputMixObject = nullptr; + } + } +} + +SLresult OutputMixerOpenSL::createAudioPlayer(SLObjectItf *objectItf, + SLDataSource *audioSource) { + SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, mOutputMixObject}; + SLDataSink audioSink = {&loc_outmix, NULL}; + return EngineOpenSLES::getInstance().createAudioPlayer(objectItf, audioSource, &audioSink); +} diff --git a/modules/juce_audio_devices/native/oboe/src/opensles/OutputMixerOpenSLES.h b/modules/juce_audio_devices/native/oboe/src/opensles/OutputMixerOpenSLES.h new file mode 100644 index 00000000..813fd018 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/opensles/OutputMixerOpenSLES.h @@ -0,0 +1,58 @@ +/* + * Copyright 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBOE_OUTPUT_MIXER_OPENSLES_H +#define OBOE_OUTPUT_MIXER_OPENSLES_H + +#include <atomic> +#include <mutex> + +#include <SLES/OpenSLES.h> +#include <SLES/OpenSLES_Android.h> + +namespace oboe { + +/** + * INTERNAL USE ONLY + */ + +class OutputMixerOpenSL { +public: + static OutputMixerOpenSL &getInstance(); + + SLresult open(); + + void close(); + + SLresult createAudioPlayer(SLObjectItf *objectItf, + SLDataSource *audioSource); + +private: + // Make this a safe Singleton + OutputMixerOpenSL()= default; + ~OutputMixerOpenSL()= default; + OutputMixerOpenSL(const OutputMixerOpenSL&)= delete; + OutputMixerOpenSL& operator=(const OutputMixerOpenSL&)= delete; + + std::mutex mLock; + int32_t mOpenCount = 0; + + SLObjectItf mOutputMixObject = nullptr; +}; + +} // namespace oboe + +#endif //OBOE_OUTPUT_MIXER_OPENSLES_H diff --git a/modules/juce_audio_devices/sources/juce_AudioSourcePlayer.cpp b/modules/juce_audio_devices/sources/juce_AudioSourcePlayer.cpp index 64833636..4968487f 100644 --- a/modules/juce_audio_devices/sources/juce_AudioSourcePlayer.cpp +++ b/modules/juce_audio_devices/sources/juce_AudioSourcePlayer.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_devices/sources/juce_AudioSourcePlayer.h b/modules/juce_audio_devices/sources/juce_AudioSourcePlayer.h index f1356022..7733a843 100644 --- a/modules/juce_audio_devices/sources/juce_AudioSourcePlayer.h +++ b/modules/juce_audio_devices/sources/juce_AudioSourcePlayer.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_devices/sources/juce_AudioTransportSource.cpp b/modules/juce_audio_devices/sources/juce_AudioTransportSource.cpp index 57c4c87c..9320c5cb 100644 --- a/modules/juce_audio_devices/sources/juce_AudioTransportSource.cpp +++ b/modules/juce_audio_devices/sources/juce_AudioTransportSource.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_devices/sources/juce_AudioTransportSource.h b/modules/juce_audio_devices/sources/juce_AudioTransportSource.h index 67c48699..c7341fe2 100644 --- a/modules/juce_audio_devices/sources/juce_AudioTransportSource.h +++ b/modules/juce_audio_devices/sources/juce_AudioTransportSource.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_audio_formats/codecs/juce_AiffAudioFormat.cpp b/modules/juce_audio_formats/codecs/juce_AiffAudioFormat.cpp index 18f65110..b2167cf4 100644 --- a/modules/juce_audio_formats/codecs/juce_AiffAudioFormat.cpp +++ b/modules/juce_audio_formats/codecs/juce_AiffAudioFormat.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -168,10 +167,11 @@ namespace AiffFileHelpers switch (key) { - case minor: keyString = "minor"; break; - case major: keyString = "major"; break; - case neither: keyString = "neither"; break; - case both: keyString = "both"; break; + case minor: keyString = "minor"; break; + case major: keyString = "major"; break; + case neither: keyString = "neither"; break; + case both: keyString = "both"; break; + default: break; } if (keyString != nullptr) @@ -334,7 +334,7 @@ namespace AiffFileHelpers out.writeIntBigEndian (offset); auto labelLength = jmin ((size_t) 254, label.getNumBytesAsUTF8()); // seems to need null terminator even though it's a pstring - out.writeByte ((char) labelLength + 1); + out.writeByte (static_cast<char> (labelLength + 1)); out.write (label.toUTF8(), labelLength); out.writeByte (0); @@ -367,7 +367,7 @@ namespace AiffFileHelpers auto comment = values.getValue (prefix + "Text", String()); auto commentLength = jmin (comment.getNumBytesAsUTF8(), (size_t) 65534); - out.writeShortBigEndian ((short) commentLength + 1); + out.writeShortBigEndian (static_cast<short> (commentLength + 1)); out.write (comment.toUTF8(), commentLength); out.writeByte (0); @@ -975,7 +975,7 @@ AudioFormatReader* AiffAudioFormat::createReaderFor (InputStream* sourceStream, MemoryMappedAudioFormatReader* AiffAudioFormat::createMemoryMappedReader (const File& file) { - return createMemoryMappedReader (file.createInputStream()); + return createMemoryMappedReader (file.createInputStream().release()); } MemoryMappedAudioFormatReader* AiffAudioFormat::createMemoryMappedReader (FileInputStream* fin) diff --git a/modules/juce_audio_formats/codecs/juce_AiffAudioFormat.h b/modules/juce_audio_formats/codecs/juce_AiffAudioFormat.h index 02138ea7..0b31235c 100644 --- a/modules/juce_audio_formats/codecs/juce_AiffAudioFormat.h +++ b/modules/juce_audio_formats/codecs/juce_AiffAudioFormat.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.cpp b/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.cpp index dd6737a8..8c60ed28 100644 --- a/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.cpp +++ b/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -26,7 +25,7 @@ #if JUCE_MAC || JUCE_IOS -#include "../../juce_audio_basics/native/juce_mac_CoreAudioLayouts.h" +#include <juce_audio_basics/native/juce_mac_CoreAudioLayouts.h> namespace juce { diff --git a/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.h b/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.h index 52798015..12db618f 100644 --- a/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.h +++ b/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.cpp b/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.cpp index 33453b81..fe680cba 100644 --- a/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.cpp +++ b/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -98,9 +97,8 @@ namespace FlacNamespace #define FLAC__NO_DLL 1 - #if JUCE_MSVC - #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4312 4505 4365 4005 4334 181 111) - #else + JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4312 4505 4365 4005 4334 181 111) + #if ! JUCE_MSVC #define HAVE_LROUND 1 #endif @@ -112,22 +110,15 @@ namespace FlacNamespace #define SIZE_MAX 0xffffffff #endif - #if JUCE_CLANG - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wconversion" - #pragma clang diagnostic ignored "-Wshadow" - #pragma clang diagnostic ignored "-Wdeprecated-register" - #if __has_warning("-Wzero-as-null-pointer-constant") - #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" - #endif - #endif - - #if JUCE_GCC - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - #pragma GCC diagnostic ignored "-Wconversion" - #pragma GCC diagnostic ignored "-Wsign-conversion" - #endif + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wconversion", + "-Wshadow", + "-Wdeprecated-register", + "-Wswitch-enum", + "-Wswitch-default", + "-Wimplicit-fallthrough", + "-Wzero-as-null-pointer-constant", + "-Wsign-conversion", + "-Wredundant-decls") #if JUCE_INTEL #if JUCE_32BIT @@ -165,13 +156,8 @@ namespace FlacNamespace #include <FLAC/all.h> #endif - #if JUCE_CLANG - #pragma clang diagnostic pop - #endif - - #if JUCE_GCC - #pragma GCC diagnostic pop - #endif + JUCE_END_IGNORE_WARNINGS_GCC_LIKE + JUCE_END_IGNORE_WARNINGS_MSVC } #undef max diff --git a/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.h b/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.h index ae0f2036..d39465c0 100644 --- a/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.h +++ b/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_formats/codecs/juce_LAMEEncoderAudioFormat.cpp b/modules/juce_audio_formats/codecs/juce_LAMEEncoderAudioFormat.cpp index b39dbbfc..39d874c7 100644 --- a/modules/juce_audio_formats/codecs/juce_LAMEEncoderAudioFormat.cpp +++ b/modules/juce_audio_formats/codecs/juce_LAMEEncoderAudioFormat.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -34,18 +33,18 @@ class LAMEEncoderAudioFormat::Writer : public AudioFormatWriter public: Writer (OutputStream* destStream, const String& formatName, const File& appFile, int vbr, int cbr, - double sampleRate, unsigned int numberOfChannels, - int bitsPerSample, const StringPairArray& metadata) - : AudioFormatWriter (destStream, formatName, sampleRate, - numberOfChannels, (unsigned int) bitsPerSample), + double sampleRateIn, unsigned int numberOfChannels, + int bitsPerSampleIn, const StringPairArray& metadata) + : AudioFormatWriter (destStream, formatName, sampleRateIn, + numberOfChannels, (unsigned int) bitsPerSampleIn), vbrLevel (vbr), cbrBitrate (cbr) { WavAudioFormat wavFormat; - if (auto* out = tempWav.getFile().createOutputStream()) + if (auto out = tempWav.getFile().createOutputStream()) { - writer.reset (wavFormat.createWriterFor (out, sampleRate, numChannels, - bitsPerSample, metadata, 0)); + writer.reset (wavFormat.createWriterFor (out.release(), sampleRateIn, numChannels, + bitsPerSampleIn, metadata, 0)); args.add (appFile.getFullPathName()); diff --git a/modules/juce_audio_formats/codecs/juce_LAMEEncoderAudioFormat.h b/modules/juce_audio_formats/codecs/juce_LAMEEncoderAudioFormat.h index 47b0f686..68b3fa13 100644 --- a/modules/juce_audio_formats/codecs/juce_LAMEEncoderAudioFormat.h +++ b/modules/juce_audio_formats/codecs/juce_LAMEEncoderAudioFormat.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_formats/codecs/juce_MP3AudioFormat.cpp b/modules/juce_audio_formats/codecs/juce_MP3AudioFormat.cpp index 93cd37f3..44bec28e 100644 --- a/modules/juce_audio_formats/codecs/juce_MP3AudioFormat.cpp +++ b/modules/juce_audio_formats/codecs/juce_MP3AudioFormat.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -30,8 +29,8 @@ namespace juce /* IMPORTANT DISCLAIMER: By choosing to enable the JUCE_USE_MP3AUDIOFORMAT flag and to compile this MP3 code into your software, you do so AT YOUR OWN RISK! By doing so, - you are agreeing that ROLI Ltd. is in no way responsible for any patent, copyright, - or other legal issues that you may suffer as a result. + you are agreeing that Raw Material Software Limited is in no way responsible for any patent, + copyright, or other legal issues that you may suffer as a result. The code in juce_MP3AudioFormat.cpp is NOT guaranteed to be free from infringements of 3rd-party intellectual property. If you wish to use it, please seek your own independent advice about the @@ -43,9 +42,12 @@ namespace juce namespace MP3Decoder { -struct AllocationTable { int16 bits, d; }; +struct AllocationTable +{ + int16 bits, d; +}; -const struct AllocationTable allocTable0[] = +constexpr AllocationTable allocTable0[] = { {4, 0}, {5, 3}, {3, -3}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {8, -127}, {9, -255}, {10, -511}, {11, -1023}, {12, -2047}, {13, -4095}, {14, -8191}, {15, -16383}, {16, -32767}, {4, 0}, {5, 3}, {3, -3}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {8, -127}, {9, -255}, {10, -511}, {11, -1023}, {12, -2047}, {13, -4095}, {14, -8191}, {15, -16383}, {16, -32767}, @@ -67,7 +69,7 @@ const struct AllocationTable allocTable0[] = {2, 0}, {5, 3}, {7, 5}, {16, -32767}, {2, 0}, {5, 3}, {7, 5}, {16, -32767}, {2, 0}, {5, 3}, {7, 5}, {16, -32767}, {2, 0}, {5, 3}, {7, 5}, {16, -32767} }; -const struct AllocationTable allocTable1[] = +constexpr AllocationTable allocTable1[] = { {4, 0}, {5, 3}, {3, -3}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {8, -127}, {9, -255}, {10, -511}, {11, -1023}, {12, -2047}, {13, -4095}, {14, -8191}, {15, -16383}, {16, -32767}, {4, 0}, {5, 3}, {3, -3}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {8, -127}, {9, -255}, {10, -511}, {11, -1023}, {12, -2047}, {13, -4095}, {14, -8191}, {15, -16383}, {16, -32767}, @@ -90,7 +92,7 @@ const struct AllocationTable allocTable1[] = {2, 0}, {5, 3}, {7, 5}, {16, -32767}, {2, 0}, {5, 3}, {7, 5}, {16, -32767}, {2, 0}, {5, 3}, {7, 5}, {16, -32767} }; -const struct AllocationTable allocTable2[] = +constexpr AllocationTable allocTable2[] = { {4, 0}, {5, 3}, {7, 5}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {8, -127}, {9, -255}, {10, -511}, {11, -1023}, {12, -2047}, {13, -4095}, {14, -8191}, {15, -16383}, {4, 0}, {5, 3}, {7, 5}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {8, -127}, {9, -255}, {10, -511}, {11, -1023}, {12, -2047}, {13, -4095}, {14, -8191}, {15, -16383}, @@ -99,7 +101,7 @@ const struct AllocationTable allocTable2[] = {3, 0}, {5, 3}, {7, 5}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {3, 0}, {5, 3}, {7, 5}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63} }; -const struct AllocationTable allocTable3[] = +constexpr AllocationTable allocTable3[] = { {4, 0}, {5, 3}, {7, 5}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {8, -127}, {9, -255}, {10, -511}, {11, -1023}, {12, -2047}, {13, -4095}, {14, -8191}, {15, -16383}, {4, 0}, {5, 3}, {7, 5}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {8, -127}, {9, -255}, {10, -511}, {11, -1023}, {12, -2047}, {13, -4095}, {14, -8191}, {15, -16383}, @@ -110,7 +112,7 @@ const struct AllocationTable allocTable3[] = {3, 0}, {5, 3}, {7, 5}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {3, 0}, {5, 3}, {7, 5}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63} }; -const struct AllocationTable allocTable4[] = +constexpr AllocationTable allocTable4[] = { {4, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {8, -127}, {9, -255}, {10, -511}, {11, -1023}, {12, -2047}, {13, -4095}, {14, -8191}, {4, 0}, {5, 3}, {7, 5}, {3, -3}, {10, 9}, {4, -7}, {5, -15}, {6, -31}, {7, -63}, {8, -127}, {9, -255}, {10, -511}, {11, -1023}, {12, -2047}, {13, -4095}, {14, -8191}, @@ -135,7 +137,7 @@ struct BandInfoStruct int16 shortDiff[13]; }; -const BandInfoStruct bandInfo[9] = +constexpr BandInfoStruct bandInfo[9] = { { {0, 4, 8, 12, 16, 20, 24, 30, 36, 44, 52, 62, 74, 90, 110, 134, 162, 196, 238, 288, 342, 418, 576}, {4, 4, 4, 4, 4, 4, 6, 6, 8, 8, 10, 12, 16, 20, 24, 28, 34, 42, 50, 54, 76, 158}, @@ -183,7 +185,7 @@ const BandInfoStruct bandInfo[9] = {8, 8, 8, 12, 16, 20, 24, 28, 36, 2, 2, 2, 26} } }; -const double decodeWindow[] = +constexpr double decodeWindow[] = { 0.000000000, -0.000015259, -0.000015259, -0.000015259, -0.000015259, -0.000015259, -0.000015259, -0.000030518, -0.000030518, -0.000030518, -0.000030518, -0.000045776, -0.000045776, -0.000061035, -0.000061035, -0.000076294, @@ -220,32 +222,32 @@ const double decodeWindow[] = 1.144989014 }; -const int16 huffmanTab0[] = { 0 }; -const int16 huffmanTab1[] = { -5,-3,-1,17,1,16,0 }; -const int16 huffmanTab2[] = { -15,-11,-9,-5,-3,-1,34,2,18,-1,33,32,17,-1,1,16,0 }; -const int16 huffmanTab3[] = { -13,-11,-9,-5,-3,-1,34,2,18,-1,33,32,16,17,-1,1,0 }; -const int16 huffmanTab5[] = { -29,-25,-23,-15,-7,-5,-3,-1,51,35,50,49,-3,-1,19,3,-1,48,34,-3,-1,18,33,-1,2,32,17,-1,1,16,0 }; -const int16 huffmanTab6[] = { -25,-19,-13,-9,-5,-3,-1,51,3,35,-1,50,48,-1,19,49,-3,-1,34,2,18,-3,-1,33,32,1,-1,17,-1,16,0 }; +constexpr int16 huffmanTab0[] = { 0 }; +constexpr int16 huffmanTab1[] = { -5,-3,-1,17,1,16,0 }; +constexpr int16 huffmanTab2[] = { -15,-11,-9,-5,-3,-1,34,2,18,-1,33,32,17,-1,1,16,0 }; +constexpr int16 huffmanTab3[] = { -13,-11,-9,-5,-3,-1,34,2,18,-1,33,32,16,17,-1,1,0 }; +constexpr int16 huffmanTab5[] = { -29,-25,-23,-15,-7,-5,-3,-1,51,35,50,49,-3,-1,19,3,-1,48,34,-3,-1,18,33,-1,2,32,17,-1,1,16,0 }; +constexpr int16 huffmanTab6[] = { -25,-19,-13,-9,-5,-3,-1,51,3,35,-1,50,48,-1,19,49,-3,-1,34,2,18,-3,-1,33,32,1,-1,17,-1,16,0 }; -const int16 huffmanTab7[] = +constexpr int16 huffmanTab7[] = { -69,-65,-57,-39,-29,-17,-11,-7,-3,-1,85,69,-1,84,83,-1,53,68,-3,-1,37,82,21,-5,-1,81,-1,5,52,-1,80,-1,67,51, -5,-3,-1,36,66,20,-1,65,64,-11,-7,-3,-1,4,35,-1,50,3,-1,19,49,-3,-1,48,34,18,-5,-1,33,-1,2,32,17,-1,1,16,0 }; -const int16 huffmanTab8[] = +constexpr int16 huffmanTab8[] = { -65,-63,-59,-45,-31,-19,-13,-7,-5,-3,-1,85,84,69,83,-3,-1,53,68,37,-3,-1,82,5,21,-5,-1,81,-1,52,67,-3,-1,80, 51,36,-5,-3,-1,66,20,65,-3,-1,4,64,-1,35,50,-9,-7,-3,-1,19,49,-1,3,48,34,-1,2,32,-1,18,33,17,-3,-1,1,16,0 }; -const int16 huffmanTab9[] = +constexpr int16 huffmanTab9[] = { -63,-53,-41,-29,-19,-11,-5,-3,-1,85,69,53,-1,83,-1,84,5,-3,-1,68,37,-1,82,21,-3,-1,81,52,-1,67,-1,80,4,-7,-3, -1,36,66,-1,51,64,-1,20,65,-5,-3,-1,35,50,19,-1,49,-1,3,48,-5,-3,-1,34,2,18,-1,33,32,-3,-1,17,1,-1,16,0 }; -const int16 huffmanTab10[] = +constexpr int16 huffmanTab10[] = { -125,-121,-111,-83,-55,-35,-21,-13,-7,-3,-1,119,103,-1,118,87,-3,-1,117,102,71,-3,-1,116,86,-1,101,55,-9,-3, -1,115,70,-3,-1,85,84,99,-1,39,114,-11,-5,-3,-1,100,7,112,-1,98,-1,69,53,-5,-1,6,-1,83,68,23,-17,-5,-1,113, @@ -253,7 +255,7 @@ const int16 huffmanTab10[] = 65,-3,-1,64,35,-1,50,3,-3,-1,19,49,-1,48,34,-7,-3,-1,18,33,-1,2,32,17,-1,1,16,0 }; -const int16 huffmanTab11[] = +constexpr int16 huffmanTab11[] = { -121,-113,-89,-59,-43,-27,-17,-7,-3,-1,119,103,-1,118,117,-3,-1,102,71,-1,116,-1,87,85,-5,-3,-1,86,101,55, -1,115,70,-9,-7,-3,-1,69,84,-1,53,83,39,-1,114,-1,100,7,-5,-1,113,-1,23,112,-3,-1,54,99,-1,96,-1,68,37,-13, @@ -261,7 +263,7 @@ const int16 huffmanTab11[] = -1,4,64,-1,35,50,-1,19,49,-5,-3,-1,3,48,34,33,-5,-1,18,-1,2,32,17,-3,-1,1,16,0 }; -const int16 huffmanTab12[] = +constexpr int16 huffmanTab12[] = { -115,-99,-73,-45,-27,-17,-9,-5,-3,-1,119,103,118,-1,87,117,-3,-1,102,71,-1,116,101,-3,-1,86,55,-3,-1,115, 85,39,-7,-3,-1,114,70,-1,100,23,-5,-1,113,-1,7,112,-1,54,99,-13,-9,-3,-1,69,84,-1,68,-1,6,5,-1,38,98,-5, @@ -269,7 +271,7 @@ const int16 huffmanTab12[] = 35,50,-11,-7,-5,-3,-1,64,3,48,19,-1,49,34,-1,18,33,-7,-5,-3,-1,2,32,0,17,-1,1,16 }; -const int16 huffmanTab13[] = +constexpr int16 huffmanTab13[] = { -509,-503,-475,-405,-333,-265,-205,-153,-115,-83,-53,-35,-21,-13,-9,-7,-5,-3,-1,254,252,253,237,255,-1,239,223, -3,-1,238,207,-1,222,191,-9,-3,-1,251,206,-1,220,-1,175,233,-1,236,221,-9,-5,-3,-1,250,205,190,-1,235,159,-3, @@ -289,7 +291,7 @@ const int16 huffmanTab13[] = -5,-1,65,-1,4,64,-3,-1,35,50,19,-3,-1,49,3,-1,48,34,-3,-1,18,33,-1,2,32,-3,-1,17,1,16,0 }; -const int16 huffmanTab15[] = +constexpr int16 huffmanTab15[] = { -495,-445,-355,-263,-183,-115,-77,-43,-27,-13,-7,-3,-1,255,239,-1,254,223,-1,238,-1,253,207,-7,-3,-1,252,222,-1, 237,191,-1,251,-1,206,236,-7,-3,-1,221,175,-1,250,190,-3,-1,235,205,-1,220,159,-15,-7,-3,-1,249,234,-1,189,219, @@ -309,7 +311,7 @@ const int16 huffmanTab15[] = 65,-1,20,4,-9,-3,-1,35,50,-3,-1,64,3,19,-3,-1,49,48,34,-9,-7,-3,-1,18,33,-1,2,32,17,-3,-1,1,16,0 }; -const int16 huffmanTab16[] = +constexpr int16 huffmanTab16[] = { -509,-503,-461,-323,-103,-37,-27,-15,-7,-3,-1,239,254,-1,223,253,-3,-1,207,252,-1,191,251,-5,-1,175,-1,250,159, -3,-1,249,248,143,-7,-3,-1,127,247,-1,111,246,255,-9,-5,-3,-1,95,245,79,-1,244,243,-53,-1,240,-1,63,-29,-19, @@ -329,7 +331,7 @@ const int16 huffmanTab16[] = 36,-3,-1,66,51,20,-5,-1,65,-1,4,64,-1,35,50,-3,-1,19,49,-3,-1,3,48,34,-3,-1,18,33,-1,2,32,-3,-1,17,1,16,0 }; -const int16 huffmanTab24[] = +constexpr int16 huffmanTab24[] = { -451,-117,-43,-25,-15,-7,-3,-1,239,254,-1,223,253,-3,-1,207,252,-1,191,251,-5,-1,250,-1,175,159,-1,249,248,-9, -5,-3,-1,143,127,247,-1,111,246,-3,-1,95,245,-1,79,244,-71,-7,-3,-1,63,243,-1,47,242,-5,-1,241,-1,31,240,-25,-9, @@ -354,7 +356,7 @@ struct BitsToTableMap const int16* table; }; -const BitsToTableMap huffmanTables1[] = +constexpr BitsToTableMap huffmanTables1[] = { { 0, huffmanTab0 }, { 0, huffmanTab1 }, { 0, huffmanTab2 }, { 0, huffmanTab3 }, { 0, huffmanTab0 }, { 0, huffmanTab5 }, { 0, huffmanTab6 }, { 0, huffmanTab7 }, @@ -366,10 +368,10 @@ const BitsToTableMap huffmanTables1[] = { 8, huffmanTab24 }, { 9, huffmanTab24 }, { 11, huffmanTab24 }, { 13, huffmanTab24 } }; -const int16 huffmanTabC0[] = { -29,-21,-13,-7,-3,-1,11,15,-1,13,14,-3,-1,7,5,9,-3,-1,6,3,-1,10,12,-3,-1,2,1,-1,4,8,0 }; -const int16 huffmanTabC1[] = { -15,-7,-3,-1,15,14,-1,13,12,-3,-1,11,10,-1,9,8,-7,-3,-1,7,6,-1,5,4,-3,-1,3,2,-1,1,0 }; +constexpr int16 huffmanTabC0[] = { -29,-21,-13,-7,-3,-1,11,15,-1,13,14,-3,-1,7,5,9,-3,-1,6,3,-1,10,12,-3,-1,2,1,-1,4,8,0 }; +constexpr int16 huffmanTabC1[] = { -15,-7,-3,-1,15,14,-1,13,12,-3,-1,11,10,-1,9,8,-7,-3,-1,7,6,-1,5,4,-3,-1,3,2,-1,1,0 }; -const BitsToTableMap huffmanTables2[] = { { 0, huffmanTabC0 }, { 0, huffmanTabC1 } }; +constexpr BitsToTableMap huffmanTables2[] = { { 0, huffmanTabC0 }, { 0, huffmanTabC1 } }; //============================================================================== struct VBRTagData @@ -386,7 +388,7 @@ struct VBRTagData const int sampleRateIndex = (data[2] >> 2) & 3; const int mode = (data[3] >> 6) & 3; - static const short bitRates[3][16] = + static constexpr short bitRates[3][16] = { { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1 }, // MPEG2 { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, -1 }, // MPEG1 @@ -469,7 +471,7 @@ struct MP3Frame void selectLayer2Table() { - static const int translate[3][2][16] = + static constexpr int translate[3][2][16] = { { { 0, 2, 2, 2, 2, 2, 2, 0, 0, 0, 1, 1, 1, 1, 1, 0 }, { 0, 2, 2, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } }, { { 0, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, @@ -477,7 +479,7 @@ struct MP3Frame }; static const AllocationTable* const tables[] = { allocTable0, allocTable1, allocTable2, allocTable3, allocTable4 }; - static const int8 limits[] = { 27, 30, 8, 12, 30 }; + static constexpr int8 limits[] = { 27, 30, 8, 12, 30 }; const int index = lsf ? 4 : translate[sampleRateIndex][2 - numChannels][bitrateIndex]; layer2SubBandLimit = limits[index]; @@ -503,13 +505,13 @@ struct MP3Frame padding = (header >> 9) & 1; mode = (header >> 6) & 3; modeExt = (header >> 4) & 3; - //extension = (header >> 8) & 1; + //extension = (header >> 8) & 1; //copyright = (header >> 3) & 1; //original = (header >> 2) & 1; //emphasis = header & 3; numChannels = (mode == 3) ? 1 : 2; - static const int frameSizes[2][3][16] = + static constexpr int frameSizes[2][3][16] = { { { 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448 }, { 0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 }, @@ -569,7 +571,7 @@ struct Constants default: break; } - static const uint8 dummy[] = { 0, 0, 0 }; + static constexpr uint8 dummy[] = { 0, 0, 0 }; return dummy; } @@ -643,7 +645,7 @@ private: { 21, 1, 22, 23, 0, 24, 25, 2, 26 } }; - static const int tableLengths[] = { 3, 5, 9 }; + static constexpr int tableLengths[] = { 3, 5, 9 }; static uint8* tables[] = { group3tab, group5tab, group9tab }; for (int i = 0; i < 3; ++i) @@ -663,7 +665,7 @@ private: for (int k = 0; k < 27; ++k) { - static const double multipliers[] = + static constexpr double multipliers[] = { 0, -2.0 / 3.0, 2.0 / 3.0, 2.0 / 7.0, 2.0 / 15.0, 2.0 / 31.0, 2.0 / 63.0, 2.0 / 127.0, 2.0 / 255.0, 2.0 / 511.0, 2.0 / 1023.0, 2.0 / 2047.0, 2.0 / 4095.0, 2.0 / 8191.0, 2.0 / 16383.0, 2.0 / 32767.0, 2.0 / 65535.0, @@ -688,7 +690,7 @@ private: for (i = 0; i < 8; ++i) { - static double Ci[] = { -0.6, -0.535, -0.33, -0.185, -0.095, -0.041, -0.0142, -0.0037 }; + static constexpr double Ci[] = { -0.6, -0.535, -0.33, -0.185, -0.095, -0.041, -0.0142, -0.0037 }; const double sq = sqrt (1.0 + Ci[i] * Ci[i]); antiAliasingCs[i] = (float) (1.0 / sq); antiAliasingCa[i] = (float) (Ci[i] / sq); @@ -716,7 +718,7 @@ private: for (j = 0; j < 4; ++j) { - static const int len[4] = { 36, 36, 12, 36 }; + static constexpr int len[4] = { 36, 36, 12, 36 }; for (i = 0; i < len[j]; i += 2) win1[j][i] = win[j][i]; for (i = 1; i < len[j]; i += 2) win1[j][i] = -win[j][i]; } @@ -1069,11 +1071,11 @@ struct Layer3SideInfo namespace DCT { enum { subBandLimit = 32 }; - static const float cos6_1 = 0.866025388f; - static const float cos6_2 = 0.5f; - static const float cos9[] = { 1.0f, 0.98480773f, 0.939692616f, 0.866025388f, 0.766044438f, 0.642787635f, 0.5f, 0.342020154f, 0.173648179f }; - static const float cos36[] = { 0.501909912f, 0.517638087f, 0.551688969f, 0.610387266f, 0.707106769f, 0.871723413f, 1.18310082f, 1.93185163f, 5.73685646f }; - static const float cos12[] = { 0.517638087f, 0.707106769f, 1.93185163f }; + static constexpr float cos6_1 = 0.866025388f; + static constexpr float cos6_2 = 0.5f; + static constexpr float cos9[] = { 1.0f, 0.98480773f, 0.939692616f, 0.866025388f, 0.766044438f, 0.642787635f, 0.5f, 0.342020154f, 0.173648179f }; + static constexpr float cos36[] = { 0.501909912f, 0.517638087f, 0.551688969f, 0.610387266f, 0.707106769f, 0.871723413f, 1.18310082f, 1.93185163f, 5.73685646f }; + static constexpr float cos12[] = { 0.517638087f, 0.707106769f, 1.93185163f }; inline void dct36_0 (int v, float* ts, float* out1, float* out2, const float* wintab, float sum0, float sum1) noexcept { @@ -1562,7 +1564,8 @@ struct MP3Stream } frameIndex = jmin (frameIndex & ~(storedStartPosInterval - 1), - frameStreamPositions.size() * storedStartPosInterval - 1); + (frameStreamPositions.size() - 1) * storedStartPosInterval); + stream.setPosition (frameStreamPositions.getUnchecked (frameIndex / storedStartPosInterval)); currentFrameIndex = frameIndex; reset(); @@ -1878,6 +1881,9 @@ private: *in0++ = *in1++; } break; + + default: + break; } } @@ -1962,8 +1968,8 @@ private: { const uint8 n0 = si.allocation[i][0]; const uint8 n1 = si.allocation[i][1]; - fraction[0][i] = n0 > 0 ? (float) ((-(1 << n0) + getBitsUint16 (n0 + 1) + 1) * constants.muls[n0 + 1][si.scaleFactor[i][0]]) : 0; - fraction[1][i] = n1 > 0 ? (float) ((-(1 << n1) + getBitsUint16 (n1 + 1) + 1) * constants.muls[n1 + 1][si.scaleFactor[i][1]]) : 0; + fraction[0][i] = n0 > 0 ? ((float) (-(1 << n0) + getBitsUint16 (n0 + 1) + 1) * constants.muls[n0 + 1][si.scaleFactor[i][0]]) : 0.0f; + fraction[1][i] = n1 > 0 ? ((float) (-(1 << n1) + getBitsUint16 (n1 + 1) + 1) * constants.muls[n1 + 1][si.scaleFactor[i][1]]) : 0.0f; } for (i = jsbound; i < 32; ++i) @@ -1973,8 +1979,8 @@ private: if (n > 0) { const uint32 w = ((uint32) -(1 << n) + getBitsUint16 (n + 1) + 1); - fraction[0][i] = (float) (w * constants.muls[n + 1][si.scaleFactor[i][0]]); - fraction[1][i] = (float) (w * constants.muls[n + 1][si.scaleFactor[i][1]]); + fraction[0][i] = ((float) w * constants.muls[n + 1][si.scaleFactor[i][0]]); + fraction[1][i] = ((float) w * constants.muls[n + 1][si.scaleFactor[i][1]]); } else fraction[0][i] = fraction[1][i] = 0; @@ -1988,7 +1994,7 @@ private: const uint8 j = si.scaleFactor[i][0]; if (n > 0) - fraction[0][i] = (float) ((-(1 << n) + getBitsUint16 (n + 1) + 1) * constants.muls[n + 1][j]); + fraction[0][i] = ((float) (-(1 << n) + getBitsUint16 (n + 1) + 1) * constants.muls[n + 1][j]); else fraction[0][i] = 0; } @@ -1998,8 +2004,8 @@ private: void layer2Step1 (SideInfoLayer2& si) noexcept { zerostruct (si); - const int sblimit = frame.layer2SubBandLimit; - const int jsbound = (frame.mode == 1) ? (frame.modeExt << 2) + 4 : frame.layer2SubBandLimit; + const auto sblimit = frame.layer2SubBandLimit; + const auto jsbound = (frame.mode == 1 ? jmin ((frame.modeExt << 2) + 4, sblimit) : sblimit); auto* allocTable = frame.allocationTable; uint8 scfsi[32][2]; @@ -2082,7 +2088,8 @@ private: void layer2Step2 (SideInfoLayer2& si, const int gr, float fraction[2][4][32]) noexcept { auto* allocTable = frame.allocationTable; - const int jsbound = (frame.mode == 1) ? (frame.modeExt << 2) + 4 : frame.layer2SubBandLimit; + auto sblimit = frame.layer2SubBandLimit; + const auto jsbound = (frame.mode == 1 ? jmin ((frame.modeExt << 2) + 4, sblimit) : sblimit); for (int i = 0; i < jsbound; ++i) { @@ -3106,7 +3113,7 @@ private: const int bytesPerFrame = stream.frame.frameSize + 4; if (bytesPerFrame == 417 || bytesPerFrame == 418) - numFrames = roundToInt ((streamSize - streamStartPos) / 417.95918); // more accurate for 128k + numFrames = roundToInt ((double) (streamSize - streamStartPos) / 417.95918); // more accurate for 128k else numFrames = (streamSize - streamStartPos) / bytesPerFrame; } diff --git a/modules/juce_audio_formats/codecs/juce_MP3AudioFormat.h b/modules/juce_audio_formats/codecs/juce_MP3AudioFormat.h index fee08403..22d9db6c 100644 --- a/modules/juce_audio_formats/codecs/juce_MP3AudioFormat.h +++ b/modules/juce_audio_formats/codecs/juce_MP3AudioFormat.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -35,8 +34,8 @@ namespace juce IMPORTANT DISCLAIMER: By choosing to enable the JUCE_USE_MP3AUDIOFORMAT flag and to compile the MP3 code into your software, you do so AT YOUR OWN RISK! By doing so, - you are agreeing that ROLI Ltd. is in no way responsible for any patent, copyright, - or other legal issues that you may suffer as a result. + you are agreeing that Raw Material Software Limited is in no way responsible for any patent, + copyright, or other legal issues that you may suffer as a result. The code in juce_MP3AudioFormat.cpp is NOT guaranteed to be free from infringements of 3rd-party intellectual property. If you wish to use it, please seek your own independent advice about the diff --git a/modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.cpp b/modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.cpp index f138d8c8..5649ccd5 100644 --- a/modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.cpp +++ b/modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -36,24 +35,21 @@ namespace juce namespace OggVorbisNamespace { #if JUCE_INCLUDE_OGGVORBIS_CODE || ! defined (JUCE_INCLUDE_OGGVORBIS_CODE) - #if JUCE_MSVC - #pragma warning (push) - #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706 4995 4365 4456 4457 4459) - #elif JUCE_CLANG - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wconversion" - #pragma clang diagnostic ignored "-Wshadow" - #pragma clang diagnostic ignored "-Wdeprecated-register" - #if __has_warning("-Wzero-as-null-pointer-constant") - #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" - #endif - #elif JUCE_GCC - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wconversion" - #pragma GCC diagnostic ignored "-Wshadow" - #pragma GCC diagnostic ignored "-Wsign-conversion" - #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - #endif + JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706 4995 4365 4456 4457 4459) + + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wconversion", + "-Wshadow", + "-Wfloat-conversion", + "-Wdeprecated-register", + "-Wdeprecated-declarations", + "-Wswitch-enum", + "-Wzero-as-null-pointer-constant", + "-Wsign-conversion", + "-Wswitch-default", + "-Wredundant-decls", + "-Wmisleading-indentation", + "-Wmissing-prototypes", + "-Wcast-align") #include "oggvorbis/vorbisenc.h" #include "oggvorbis/codec.h" @@ -61,35 +57,30 @@ namespace OggVorbisNamespace #include "oggvorbis/bitwise.c" #include "oggvorbis/framing.c" - #include "oggvorbis/libvorbis-1.3.2/lib/analysis.c" - #include "oggvorbis/libvorbis-1.3.2/lib/bitrate.c" - #include "oggvorbis/libvorbis-1.3.2/lib/block.c" - #include "oggvorbis/libvorbis-1.3.2/lib/codebook.c" - #include "oggvorbis/libvorbis-1.3.2/lib/envelope.c" - #include "oggvorbis/libvorbis-1.3.2/lib/floor0.c" - #include "oggvorbis/libvorbis-1.3.2/lib/floor1.c" - #include "oggvorbis/libvorbis-1.3.2/lib/info.c" - #include "oggvorbis/libvorbis-1.3.2/lib/lpc.c" - #include "oggvorbis/libvorbis-1.3.2/lib/lsp.c" - #include "oggvorbis/libvorbis-1.3.2/lib/mapping0.c" - #include "oggvorbis/libvorbis-1.3.2/lib/mdct.c" - #include "oggvorbis/libvorbis-1.3.2/lib/psy.c" - #include "oggvorbis/libvorbis-1.3.2/lib/registry.c" - #include "oggvorbis/libvorbis-1.3.2/lib/res0.c" - #include "oggvorbis/libvorbis-1.3.2/lib/sharedbook.c" - #include "oggvorbis/libvorbis-1.3.2/lib/smallft.c" - #include "oggvorbis/libvorbis-1.3.2/lib/synthesis.c" - #include "oggvorbis/libvorbis-1.3.2/lib/vorbisenc.c" - #include "oggvorbis/libvorbis-1.3.2/lib/vorbisfile.c" - #include "oggvorbis/libvorbis-1.3.2/lib/window.c" - - #if JUCE_MSVC - #pragma warning (pop) - #elif JUCE_CLANG - #pragma clang diagnostic pop - #elif JUCE_GCC - #pragma GCC diagnostic pop - #endif + #include "oggvorbis/libvorbis-1.3.7/lib/analysis.c" + #include "oggvorbis/libvorbis-1.3.7/lib/bitrate.c" + #include "oggvorbis/libvorbis-1.3.7/lib/block.c" + #include "oggvorbis/libvorbis-1.3.7/lib/codebook.c" + #include "oggvorbis/libvorbis-1.3.7/lib/envelope.c" + #include "oggvorbis/libvorbis-1.3.7/lib/floor0.c" + #include "oggvorbis/libvorbis-1.3.7/lib/floor1.c" + #include "oggvorbis/libvorbis-1.3.7/lib/info.c" + #include "oggvorbis/libvorbis-1.3.7/lib/lpc.c" + #include "oggvorbis/libvorbis-1.3.7/lib/lsp.c" + #include "oggvorbis/libvorbis-1.3.7/lib/mapping0.c" + #include "oggvorbis/libvorbis-1.3.7/lib/mdct.c" + #include "oggvorbis/libvorbis-1.3.7/lib/psy.c" + #include "oggvorbis/libvorbis-1.3.7/lib/registry.c" + #include "oggvorbis/libvorbis-1.3.7/lib/res0.c" + #include "oggvorbis/libvorbis-1.3.7/lib/sharedbook.c" + #include "oggvorbis/libvorbis-1.3.7/lib/smallft.c" + #include "oggvorbis/libvorbis-1.3.7/lib/synthesis.c" + #include "oggvorbis/libvorbis-1.3.7/lib/vorbisenc.c" + #include "oggvorbis/libvorbis-1.3.7/lib/vorbisfile.c" + #include "oggvorbis/libvorbis-1.3.7/lib/window.c" + + JUCE_END_IGNORE_WARNINGS_MSVC + JUCE_END_IGNORE_WARNINGS_GCC_LIKE #else #include <vorbis/vorbisenc.h> #include <vorbis/codec.h> @@ -146,7 +137,7 @@ public: lengthInSamples = (uint32) ov_pcm_total (&ovFile, -1); numChannels = (unsigned int) info->channels; bitsPerSample = 16; - sampleRate = info->rate; + sampleRate = (double) info->rate; reservoir.setSize ((int) numChannels, (int) jmin (lengthInSamples, (int64) 4096)); } @@ -208,7 +199,7 @@ public: while (numToRead > 0) { float** dataIn = nullptr; - auto samps = ov_read_float (&ovFile, &dataIn, numToRead, &bitStream); + auto samps = static_cast<int> (ov_read_float (&ovFile, &dataIn, numToRead, &bitStream)); if (samps <= 0) break; @@ -287,7 +278,7 @@ public: vorbis_info_init (&vi); if (vorbis_encode_init_vbr (&vi, (int) numChans, (int) rate, - jlimit (0.0f, 1.0f, qualityIndex * 0.1f)) == 0) + jlimit (0.0f, 1.0f, (float) qualityIndex * 0.1f)) == 0) { vorbis_comment_init (&vc); @@ -490,12 +481,12 @@ StringArray OggVorbisAudioFormat::getQualityOptions() int OggVorbisAudioFormat::estimateOggFileQuality (const File& source) { - if (auto* in = source.createInputStream()) + if (auto in = source.createInputStream()) { - if (auto r = std::unique_ptr<AudioFormatReader> (createReaderFor (in, true))) + if (auto r = std::unique_ptr<AudioFormatReader> (createReaderFor (in.release(), true))) { - auto lengthSecs = r->lengthInSamples / r->sampleRate; - auto approxBitsPerSecond = (int) (source.getSize() * 8 / lengthSecs); + auto lengthSecs = (double) r->lengthInSamples / r->sampleRate; + auto approxBitsPerSecond = (int) ((double) source.getSize() * 8 / lengthSecs); auto qualities = getQualityOptions(); int bestIndex = 0; diff --git a/modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.h b/modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.h index 7264e2d4..db4786d2 100644 --- a/modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.h +++ b/modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp b/modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp index 3515786a..f25261c2 100644 --- a/modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp +++ b/modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -157,8 +156,8 @@ const char* const WavAudioFormat::tracktionLoopInfo = "tracktion loop info"; //============================================================================== namespace WavFileHelpers { - JUCE_CONSTEXPR inline int chunkName (const char* name) noexcept { return (int) ByteOrder::littleEndianInt (name); } - JUCE_CONSTEXPR inline size_t roundUpSize (size_t sz) noexcept { return (sz + 3) & ~3u; } + constexpr inline int chunkName (const char* name) noexcept { return (int) ByteOrder::littleEndianInt (name); } + constexpr inline size_t roundUpSize (size_t sz) noexcept { return (sz + 3) & ~3u; } #if JUCE_MSVC #pragma pack (push, 1) @@ -1475,7 +1474,7 @@ private: output->writeShort ((short) numChannels); output->writeInt ((int) sampleRate); - output->writeInt ((int) (bytesPerFrame * sampleRate)); // nAvgBytesPerSec + output->writeInt ((int) ((double) bytesPerFrame * sampleRate)); // nAvgBytesPerSec output->writeShort ((short) bytesPerFrame); // nBlockAlign output->writeShort ((short) bitsPerSample); // wBitsPerSample @@ -1703,7 +1702,7 @@ AudioFormatReader* WavAudioFormat::createReaderFor (InputStream* sourceStream, b MemoryMappedAudioFormatReader* WavAudioFormat::createMemoryMappedReader (const File& file) { - return createMemoryMappedReader (file.createInputStream()); + return createMemoryMappedReader (file.createInputStream().release()); } MemoryMappedAudioFormatReader* WavAudioFormat::createMemoryMappedReader (FileInputStream* fin) @@ -1748,7 +1747,7 @@ namespace WavFileHelpers TemporaryFile tempFile (file); WavAudioFormat wav; - std::unique_ptr<AudioFormatReader> reader (wav.createReaderFor (file.createInputStream(), true)); + std::unique_ptr<AudioFormatReader> reader (wav.createReaderFor (file.createInputStream().release(), true)); if (reader != nullptr) { @@ -1781,7 +1780,7 @@ bool WavAudioFormat::replaceMetadataInFile (const File& wavFile, const StringPai { using namespace WavFileHelpers; - std::unique_ptr<WavAudioFormatReader> reader (static_cast<WavAudioFormatReader*> (createReaderFor (wavFile.createInputStream(), true))); + std::unique_ptr<WavAudioFormatReader> reader (static_cast<WavAudioFormatReader*> (createReaderFor (wavFile.createInputStream().release(), true))); if (reader != nullptr) { diff --git a/modules/juce_audio_formats/codecs/juce_WavAudioFormat.h b/modules/juce_audio_formats/codecs/juce_WavAudioFormat.h index 46394bee..55f5c4bf 100644 --- a/modules/juce_audio_formats/codecs/juce_WavAudioFormat.h +++ b/modules/juce_audio_formats/codecs/juce_WavAudioFormat.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.cpp b/modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.cpp index 34744425..0ceefa3b 100644 --- a/modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.cpp +++ b/modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -266,32 +265,23 @@ private: void scanFileForDetails() { - ComSmartPtr<IWMHeaderInfo> wmHeaderInfo; - HRESULT hr = wmSyncReader.QueryInterface (wmHeaderInfo); - - if (SUCCEEDED (hr)) + if (auto wmHeaderInfo = wmSyncReader.getInterface<IWMHeaderInfo>()) { QWORD lengthInNanoseconds = 0; WORD lengthOfLength = sizeof (lengthInNanoseconds); WORD streamNum = 0; WMT_ATTR_DATATYPE wmAttrDataType; - hr = wmHeaderInfo->GetAttributeByName (&streamNum, L"Duration", &wmAttrDataType, - (BYTE*) &lengthInNanoseconds, &lengthOfLength); - - ComSmartPtr<IWMProfile> wmProfile; - hr = wmSyncReader.QueryInterface (wmProfile); + wmHeaderInfo->GetAttributeByName (&streamNum, L"Duration", &wmAttrDataType, + (BYTE*) &lengthInNanoseconds, &lengthOfLength); - if (SUCCEEDED (hr)) + if (auto wmProfile = wmSyncReader.getInterface<IWMProfile>()) { ComSmartPtr<IWMStreamConfig> wmStreamConfig; - hr = wmProfile->GetStream (0, wmStreamConfig.resetAndGetPointerAddress()); + auto hr = wmProfile->GetStream (0, wmStreamConfig.resetAndGetPointerAddress()); if (SUCCEEDED (hr)) { - ComSmartPtr<IWMMediaProps> wmMediaProperties; - hr = wmStreamConfig.QueryInterface (wmMediaProperties); - - if (SUCCEEDED (hr)) + if (auto wmMediaProperties = wmStreamConfig.getInterface<IWMMediaProps>()) { DWORD sizeMediaType; hr = wmMediaProperties->GetMediaType (0, &sizeMediaType); diff --git a/modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.h b/modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.h index e2fe1263..5c35853c 100644 --- a/modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.h +++ b/modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_formats/format/juce_AudioFormat.cpp b/modules/juce_audio_formats/format/juce_AudioFormat.cpp index ca8bd2ad..2e2e62d3 100644 --- a/modules/juce_audio_formats/format/juce_AudioFormat.cpp +++ b/modules/juce_audio_formats/format/juce_AudioFormat.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_formats/format/juce_AudioFormat.h b/modules/juce_audio_formats/format/juce_AudioFormat.h index d3008572..c81b3d6b 100644 --- a/modules/juce_audio_formats/format/juce_AudioFormat.h +++ b/modules/juce_audio_formats/format/juce_AudioFormat.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_formats/format/juce_AudioFormatManager.cpp b/modules/juce_audio_formats/format/juce_AudioFormatManager.cpp index 76827199..2b5570ab 100644 --- a/modules/juce_audio_formats/format/juce_AudioFormatManager.cpp +++ b/modules/juce_audio_formats/format/juce_AudioFormatManager.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -126,14 +125,14 @@ AudioFormatReader* AudioFormatManager::createReaderFor (const File& file) for (auto* af : knownFormats) if (af->canHandleFile (file)) - if (auto* in = file.createInputStream()) - if (auto* r = af->createReaderFor (in, true)) + if (auto in = file.createInputStream()) + if (auto* r = af->createReaderFor (in.release(), true)) return r; return nullptr; } -AudioFormatReader* AudioFormatManager::createReaderFor (InputStream* audioFileStream) +AudioFormatReader* AudioFormatManager::createReaderFor (std::unique_ptr<InputStream> audioFileStream) { // you need to actually register some formats before the manager can // use them to open a file! @@ -141,22 +140,21 @@ AudioFormatReader* AudioFormatManager::createReaderFor (InputStream* audioFileSt if (audioFileStream != nullptr) { - std::unique_ptr<InputStream> in (audioFileStream); - auto originalStreamPos = in->getPosition(); + auto originalStreamPos = audioFileStream->getPosition(); for (auto* af : knownFormats) { - if (auto* r = af->createReaderFor (in.get(), false)) + if (auto* r = af->createReaderFor (audioFileStream.get(), false)) { - in.release(); + audioFileStream.release(); return r; } - in->setPosition (originalStreamPos); + audioFileStream->setPosition (originalStreamPos); // the stream that is passed-in must be capable of being repositioned so // that all the formats can have a go at opening it. - jassert (in->getPosition() == originalStreamPos); + jassert (audioFileStream->getPosition() == originalStreamPos); } } diff --git a/modules/juce_audio_formats/format/juce_AudioFormatManager.h b/modules/juce_audio_formats/format/juce_AudioFormatManager.h index 36140e83..dd838888 100644 --- a/modules/juce_audio_formats/format/juce_AudioFormatManager.h +++ b/modules/juce_audio_formats/format/juce_AudioFormatManager.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -67,7 +66,7 @@ public: /** Handy method to make it easy to register the formats that come with JUCE. This will add WAV and AIFF to the list, along with any other formats enabled - in either the Projucer or your application's AppConfig.h. + in either the Projucer or your application's preprocessor definitions. */ void registerBasicFormats(); @@ -138,7 +137,7 @@ public: If none of the registered formats can open the stream, it'll return nullptr. If it returns a reader, it's the caller's responsibility to delete the reader. */ - AudioFormatReader* createReaderFor (InputStream* audioFileStream); + AudioFormatReader* createReaderFor (std::unique_ptr<InputStream> audioFileStream); private: //============================================================================== diff --git a/modules/juce_audio_formats/format/juce_AudioFormatReader.cpp b/modules/juce_audio_formats/format/juce_AudioFormatReader.cpp index 65ef3fb7..3b667f0f 100644 --- a/modules/juce_audio_formats/format/juce_AudioFormatReader.cpp +++ b/modules/juce_audio_formats/format/juce_AudioFormatReader.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -39,9 +38,11 @@ AudioFormatReader::~AudioFormatReader() static void convertFixedToFloat (int* const* channels, int numChannels, int numSamples) { + constexpr auto scaleFactor = 1.0f / static_cast<float> (0x7fffffff); + for (int i = 0; i < numChannels; ++i) if (auto d = channels[i]) - FloatVectorOperations::convertFixedToFloat (reinterpret_cast<float*> (d), d, 1.0f / 0x7fffffff, numSamples); + FloatVectorOperations::convertFixedToFloat (reinterpret_cast<float*> (d), d, scaleFactor, numSamples); } bool AudioFormatReader::read (float* const* destChannels, int numDestChannels, @@ -234,8 +235,8 @@ void AudioFormatReader::readMaxLevels (int64 startSampleInFile, int64 numSamples { auto intRange = Range<int>::findMinAndMax (intBuffer[i], numToDo); - r = Range<float> (intRange.getStart() / (float) std::numeric_limits<int>::max(), - intRange.getEnd() / (float) std::numeric_limits<int>::max()); + r = Range<float> ((float) intRange.getStart() / (float) std::numeric_limits<int>::max(), + (float) intRange.getEnd() / (float) std::numeric_limits<int>::max()); } results[i] = isFirstBlock ? r : results[i].getUnionWith (r); diff --git a/modules/juce_audio_formats/format/juce_AudioFormatReader.h b/modules/juce_audio_formats/format/juce_AudioFormatReader.h index 9bc74a95..da06645b 100644 --- a/modules/juce_audio_formats/format/juce_AudioFormatReader.h +++ b/modules/juce_audio_formats/format/juce_AudioFormatReader.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_formats/format/juce_AudioFormatReaderSource.cpp b/modules/juce_audio_formats/format/juce_AudioFormatReaderSource.cpp index 9e6c5675..6ee9ce37 100644 --- a/modules/juce_audio_formats/format/juce_AudioFormatReaderSource.cpp +++ b/modules/juce_audio_formats/format/juce_AudioFormatReaderSource.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_formats/format/juce_AudioFormatReaderSource.h b/modules/juce_audio_formats/format/juce_AudioFormatReaderSource.h index 20a831fd..caa6c26b 100644 --- a/modules/juce_audio_formats/format/juce_AudioFormatReaderSource.h +++ b/modules/juce_audio_formats/format/juce_AudioFormatReaderSource.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_formats/format/juce_AudioFormatWriter.cpp b/modules/juce_audio_formats/format/juce_AudioFormatWriter.cpp index b8a726d9..afe3ee7c 100644 --- a/modules/juce_audio_formats/format/juce_AudioFormatWriter.cpp +++ b/modules/juce_audio_formats/format/juce_AudioFormatWriter.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -109,8 +108,10 @@ bool AudioFormatWriter::writeFromAudioReader (AudioFormatReader& reader, { void* const b = *bufferChan++; + constexpr auto scaleFactor = 1.0f / static_cast<float> (0x7fffffff); + if (isFloatingPoint()) - FloatVectorOperations::convertFixedToFloat ((float*) b, (int*) b, 1.0f / 0x7fffffff, numToDo); + FloatVectorOperations::convertFixedToFloat ((float*) b, (int*) b, scaleFactor, numToDo); else convertFloatsToInts ((int*) b, (float*) b, numToDo); } diff --git a/modules/juce_audio_formats/format/juce_AudioFormatWriter.h b/modules/juce_audio_formats/format/juce_AudioFormatWriter.h index 6c9f18db..367c6d64 100644 --- a/modules/juce_audio_formats/format/juce_AudioFormatWriter.h +++ b/modules/juce_audio_formats/format/juce_AudioFormatWriter.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_formats/format/juce_AudioSubsectionReader.cpp b/modules/juce_audio_formats/format/juce_AudioSubsectionReader.cpp index 94106e2c..5f9eef1d 100644 --- a/modules/juce_audio_formats/format/juce_AudioSubsectionReader.cpp +++ b/modules/juce_audio_formats/format/juce_AudioSubsectionReader.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_formats/format/juce_AudioSubsectionReader.h b/modules/juce_audio_formats/format/juce_AudioSubsectionReader.h index e3240cab..5e5f3d71 100644 --- a/modules/juce_audio_formats/format/juce_AudioSubsectionReader.h +++ b/modules/juce_audio_formats/format/juce_AudioSubsectionReader.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp b/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp index eda6f7f2..57d47675 100644 --- a/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp +++ b/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.h b/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.h index 96c8bb5c..19403c64 100644 --- a/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.h +++ b/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_formats/format/juce_MemoryMappedAudioFormatReader.h b/modules/juce_audio_formats/format/juce_MemoryMappedAudioFormatReader.h index e3fef6e3..45d9d324 100644 --- a/modules/juce_audio_formats/format/juce_MemoryMappedAudioFormatReader.h +++ b/modules/juce_audio_formats/format/juce_MemoryMappedAudioFormatReader.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_formats/juce_audio_formats.cpp b/modules/juce_audio_formats/juce_audio_formats.cpp index 7f930e7e..edba99dc 100644 --- a/modules/juce_audio_formats/juce_audio_formats.cpp +++ b/modules/juce_audio_formats/juce_audio_formats.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_formats/juce_audio_formats.h b/modules/juce_audio_formats/juce_audio_formats.h index 1247742b..257cef73 100644 --- a/modules/juce_audio_formats/juce_audio_formats.h +++ b/modules/juce_audio_formats/juce_audio_formats.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -29,14 +28,14 @@ The block below describes the properties of this module, and is read by the Projucer to automatically generate project code that uses it. For details about the syntax and how to create or use a module, see the - JUCE Module Format.txt file. + JUCE Module Format.md file. BEGIN_JUCE_MODULE_DECLARATION ID: juce_audio_formats vendor: juce - version: 5.4.7 + version: 6.0.5 name: JUCE audio file format codecs description: Classes for reading and writing various audio file formats. website: http://www.juce.com/juce @@ -79,8 +78,8 @@ Enables the software-based MP3AudioFormat class. IMPORTANT DISCLAIMER: By choosing to enable the JUCE_USE_MP3AUDIOFORMAT flag and to compile this MP3 code into your software, you do so AT YOUR OWN RISK! By doing so, you are agreeing - that ROLI Ltd. is in no way responsible for any patent, copyright, or other legal issues - that you may suffer as a result. + that Raw Material Software Limited is in no way responsible for any patent, copyright, or other + legal issues that you may suffer as a result. The code in juce_MP3AudioFormat.cpp is NOT guaranteed to be free from infringements of 3rd-party intellectual property. If you wish to use it, please seek your own independent advice about the diff --git a/modules/juce_audio_formats/juce_audio_formats.mm b/modules/juce_audio_formats/juce_audio_formats.mm index e817a504..c24c5a59 100644 --- a/modules/juce_audio_formats/juce_audio_formats.mm +++ b/modules/juce_audio_formats/juce_audio_formats.mm @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_formats/sampler/juce_Sampler.cpp b/modules/juce_audio_formats/sampler/juce_Sampler.cpp index 905791ae..77a0edb0 100644 --- a/modules/juce_audio_formats/sampler/juce_Sampler.cpp +++ b/modules/juce_audio_formats/sampler/juce_Sampler.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_formats/sampler/juce_Sampler.h b/modules/juce_audio_formats/sampler/juce_Sampler.h index 26b26683..111150a2 100644 --- a/modules/juce_audio_formats/sampler/juce_Sampler.h +++ b/modules/juce_audio_formats/sampler/juce_Sampler.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_plugin_client/AAX/juce_AAX_Modifier_Injector.h b/modules/juce_audio_plugin_client/AAX/juce_AAX_Modifier_Injector.h index eff64463..0f1d7ca1 100644 --- a/modules/juce_audio_plugin_client/AAX/juce_AAX_Modifier_Injector.h +++ b/modules/juce_audio_plugin_client/AAX/juce_AAX_Modifier_Injector.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). 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 9499b037..95a09132 100644 --- a/modules/juce_audio_plugin_client/AAX/juce_AAX_Wrapper.cpp +++ b/modules/juce_audio_plugin_client/AAX/juce_AAX_Wrapper.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -24,7 +23,7 @@ ============================================================================== */ -#include "../../juce_core/system/juce_TargetPlatform.h" +#include <juce_core/system/juce_TargetPlatform.h> #include "../utility/juce_CheckSettingMacros.h" #if JucePlugin_Build_AAX && (JUCE_INCLUDED_AAX_IN_MM || defined (_WIN32) || defined (_WIN64)) @@ -34,29 +33,18 @@ #include "../utility/juce_WindowsHooks.h" #include "../utility/juce_FakeMouseMoveGenerator.h" -#include "../../juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp" +#include <juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp> -#ifdef __clang__ - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wnon-virtual-dtor" - #pragma clang diagnostic ignored "-Wsign-conversion" - #pragma clang diagnostic ignored "-Wextra-semi" - #pragma clang diagnostic ignored "-Wshift-sign-overflow" - #if __has_warning("-Wpragma-pack") - #pragma clang diagnostic ignored "-Wpragma-pack" - #endif - #if __has_warning("-Wzero-as-null-pointer-constant") - #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" - #endif - #if __has_warning("-Winconsistent-missing-destructor-override") - #pragma clang diagnostic ignored "-Winconsistent-missing-destructor-override" - #endif -#endif - -#ifdef _MSC_VER - #pragma warning (push) - #pragma warning (disable : 4127 4512) -#endif +JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4127 4512 4996) +JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wnon-virtual-dtor", + "-Wsign-conversion", + "-Wextra-semi", + "-Wshift-sign-overflow", + "-Wpragma-pack", + "-Wzero-as-null-pointer-constant", + "-Winconsistent-missing-destructor-override", + "-Wfour-char-constants", + "-Wtautological-overlap-compare") #include <AAX_Version.h> @@ -90,13 +78,10 @@ static_assert (AAX_SDK_CURRENT_REVISION >= AAX_SDK_2p3p0_REVISION, "JUCE require #endif #endif -#ifdef _MSC_VER - #pragma warning (pop) -#endif +JUCE_END_IGNORE_WARNINGS_MSVC +JUCE_END_IGNORE_WARNINGS_GCC_LIKE -#ifdef __clang__ - #pragma clang diagnostic pop -#endif +JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wfour-char-constants") #if JUCE_WINDOWS #ifndef JucePlugin_AAXLibs_path @@ -300,7 +285,7 @@ namespace AAXClasses return AAX_eStemFormat_INT32_MAX; } - static inline AudioChannelSet channelSetFromStemFormat (AAX_EStemFormat format, bool ignoreLayout) noexcept + static AudioChannelSet channelSetFromStemFormat (AAX_EStemFormat format, bool ignoreLayout) noexcept { if (! ignoreLayout) { @@ -325,6 +310,12 @@ namespace AAXClasses case AAX_eStemFormat_Ambi_1_ACN: return AudioChannelSet::ambisonic (1); case AAX_eStemFormat_Ambi_2_ACN: return AudioChannelSet::ambisonic (2); case AAX_eStemFormat_Ambi_3_ACN: return AudioChannelSet::ambisonic (3); + case AAX_eStemFormat_Reserved_1: + case AAX_eStemFormat_Reserved_2: + case AAX_eStemFormat_Reserved_3: + case AAX_eStemFormatNum: + case AAX_eStemFormat_Any: + case AAX_eStemFormat_INT32_MAX: default: return AudioChannelSet::disabled(); } } @@ -341,6 +332,10 @@ namespace AAXClasses case AudioProcessorParameter::compressorLimiterGainReductionMeter: return AAX_eMeterType_CLGain; case AudioProcessorParameter::expanderGateGainReductionMeter: return AAX_eMeterType_EGGain; case AudioProcessorParameter::analysisMeter: return AAX_eMeterType_Analysis; + case AudioProcessorParameter::genericParameter: + case AudioProcessorParameter::inputGain: + case AudioProcessorParameter::outputGain: + case AudioProcessorParameter::otherMeter: default: return AAX_eMeterType_Other; } } @@ -353,6 +348,7 @@ namespace AAXClasses case AAX_eHighlightColor_Blue: return Colours::blue; case AAX_eHighlightColor_Green: return Colours::green; case AAX_eHighlightColor_Yellow: return Colours::yellow; + case AAX_eHighlightColor_Num: default: jassertfalse; break; } @@ -509,8 +505,9 @@ namespace AAXClasses { if (component != nullptr) { - viewSize->horz = (float) component->getWidth(); - viewSize->vert = (float) component->getHeight(); + *viewSize = convertToHostBounds ({ (float) component->getHeight(), + (float) component->getWidth() }); + return AAX_SUCCESS; } @@ -565,6 +562,18 @@ namespace AAXClasses int getParamIndexFromID (AAX_CParamID paramID) const noexcept; AAX_CParamID getAAXParamIDFromJuceIndex (int index) const noexcept; + //============================================================================== + static AAX_Point convertToHostBounds (AAX_Point pluginSize) + { + auto desktopScale = Desktop::getInstance().getGlobalScaleFactor(); + + if (approximatelyEqual (desktopScale, 1.0f)) + return pluginSize; + + return { pluginSize.vert * desktopScale, + pluginSize.horz * desktopScale }; + } + //============================================================================== struct ContentWrapperComponent : public Component { @@ -623,26 +632,39 @@ namespace AAXClasses void mouseUp (const MouseEvent& e) override { callMouseMethod (e, &AAX_IViewContainer::HandleParameterMouseUp); } void mouseDrag (const MouseEvent& e) override { callMouseMethod (e, &AAX_IViewContainer::HandleParameterMouseDrag); } - void childBoundsChanged (Component*) override + void parentSizeChanged() override { + resizeHostWindow(); + if (pluginEditor != nullptr) + pluginEditor->repaint(); + } + + void childBoundsChanged (Component*) override + { + if (resizeHostWindow()) + { + setSize (pluginEditor->getWidth(), pluginEditor->getHeight()); + lastValidSize = getBounds(); + } + else { - auto w = pluginEditor->getWidth(); - auto h = pluginEditor->getHeight(); + pluginEditor->setBoundsConstrained (pluginEditor->getBounds().withSize (lastValidSize.getWidth(), + lastValidSize.getHeight())); + } + } - AAX_Point newSize ((float) h, (float) w); + bool resizeHostWindow() + { + if (pluginEditor != nullptr) + { + auto newSize = convertToHostBounds ({ (float) pluginEditor->getHeight(), + (float) pluginEditor->getWidth() }); - if (owner.GetViewContainer()->SetViewSize (newSize) == AAX_SUCCESS) - { - setSize (w, h); - lastValidSize = getBounds(); - } - else - { - auto validSize = pluginEditor->getBounds().withSize (lastValidSize.getWidth(), lastValidSize.getHeight()); - pluginEditor->setBoundsConstrained (validSize); - } + return owner.GetViewContainer()->SetViewSize (newSize) == AAX_SUCCESS; } + + return false; } std::unique_ptr<AudioProcessorEditor> pluginEditor; @@ -1444,22 +1466,18 @@ namespace AAXClasses #if JucePlugin_ProducesMidiOutput || JucePlugin_IsMidiEffect { - const juce::uint8* midiEventData; - int midiEventSize, midiEventPosition; - MidiBuffer::Iterator i (midiBuffer); - AAX_CMidiPacket packet; packet.mIsImmediate = false; - while (i.getNextEvent (midiEventData, midiEventSize, midiEventPosition)) + for (const auto metadata : midiBuffer) { - jassert (isPositiveAndBelow (midiEventPosition, bufferSize)); + jassert (isPositiveAndBelow (metadata.samplePosition, bufferSize)); - if (midiEventSize <= 4) + if (metadata.numBytes <= 4) { - packet.mTimestamp = (uint32_t) midiEventPosition; - packet.mLength = (uint32_t) midiEventSize; - memcpy (packet.mData, midiEventData, (size_t) midiEventSize); + packet.mTimestamp = (uint32_t) metadata.samplePosition; + packet.mLength = (uint32_t) metadata.numBytes; + memcpy (packet.mData, metadata.data, (size_t) metadata.numBytes); check (midiNodesOut->PostMIDIPacket (&packet)); } @@ -2229,7 +2247,7 @@ namespace AAXClasses check (desc.AddProcessProc_Native (algorithmProcessCallback, properties)); } - static inline bool hostSupportsStemFormat (AAX_EStemFormat stemFormat, const AAX_IFeatureInfo* featureInfo) + static bool hostSupportsStemFormat (AAX_EStemFormat stemFormat, const AAX_IFeatureInfo* featureInfo) { if (featureInfo != nullptr) { @@ -2363,6 +2381,8 @@ AAX_Result JUCE_CDECL GetEffectDescriptions (AAX_ICollection* collection) return AAX_ERROR_NULL_OBJECT; } +JUCE_END_IGNORE_WARNINGS_GCC_LIKE + //============================================================================== #if _MSC_VER || JUCE_MINGW extern "C" BOOL WINAPI DllMain (HINSTANCE instance, DWORD reason, LPVOID) { if (reason == DLL_PROCESS_ATTACH) Process::setCurrentModuleInstanceHandle (instance); return true; } diff --git a/modules/juce_audio_plugin_client/RTAS/juce_RTAS_DigiCode1.cpp b/modules/juce_audio_plugin_client/RTAS/juce_RTAS_DigiCode1.cpp index c57fe701..63ddd11b 100644 --- a/modules/juce_audio_plugin_client/RTAS/juce_RTAS_DigiCode1.cpp +++ b/modules/juce_audio_plugin_client/RTAS/juce_RTAS_DigiCode1.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -26,7 +25,7 @@ #pragma once -#include "../../juce_core/system/juce_TargetPlatform.h" +#include <juce_core/system/juce_TargetPlatform.h> #include "../utility/juce_CheckSettingMacros.h" #if JucePlugin_Build_RTAS @@ -53,15 +52,12 @@ #undef UNICODE #endif -#ifdef __clang__ - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wnon-virtual-dtor" - #pragma clang diagnostic ignored "-Wcomment" - #pragma clang diagnostic ignored "-Wreorder" - #pragma clang diagnostic ignored "-Wextra-tokens" - #pragma clang diagnostic ignored "-Wunused-variable" - #pragma clang diagnostic ignored "-Wdeprecated" -#endif +JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wnon-virtual-dtor", + "-Wcomment", + "-Wreorder", + "-Wextra-tokens", + "-Wunused-variable", + "-Wdeprecated") #include <CEffectGroup.cpp> #include <CEffectGroupMIDI.cpp> @@ -72,8 +68,6 @@ #include <CEffectTypeRTAS.cpp> #include <ChunkDataParser.cpp> -#ifdef __clang__ - #pragma clang diagnostic pop -#endif +JUCE_END_IGNORE_WARNINGS_GCC_LIKE #endif diff --git a/modules/juce_audio_plugin_client/RTAS/juce_RTAS_DigiCode2.cpp b/modules/juce_audio_plugin_client/RTAS/juce_RTAS_DigiCode2.cpp index 6df4685a..671ee40b 100644 --- a/modules/juce_audio_plugin_client/RTAS/juce_RTAS_DigiCode2.cpp +++ b/modules/juce_audio_plugin_client/RTAS/juce_RTAS_DigiCode2.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -26,21 +25,18 @@ #pragma once -#include "../../juce_core/system/juce_TargetPlatform.h" +#include <juce_core/system/juce_TargetPlatform.h> #include "../utility/juce_CheckSettingMacros.h" #if JucePlugin_Build_RTAS #include "juce_RTAS_DigiCode_Header.h" -#ifdef __clang__ - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wcomment" - #pragma clang diagnostic ignored "-Wextra-tokens" - #pragma clang diagnostic ignored "-Wnon-virtual-dtor" - #pragma clang diagnostic ignored "-Wreorder" - #pragma clang diagnostic ignored "-Wdeprecated" -#endif +JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wcomment", + "-Wextra-tokens", + "-Wnon-virtual-dtor", + "-Wreorder", + "-Wdeprecated") /* This file is used to include and build the required digidesign CPP files without your project @@ -60,8 +56,6 @@ #include <CEffectProcessMIDI.cpp> #include <PlugInUtils.cpp> -#ifdef __clang__ - #pragma clang diagnostic pop -#endif +JUCE_END_IGNORE_WARNINGS_GCC_LIKE #endif diff --git a/modules/juce_audio_plugin_client/RTAS/juce_RTAS_DigiCode3.cpp b/modules/juce_audio_plugin_client/RTAS/juce_RTAS_DigiCode3.cpp index d023957c..cc31b78f 100644 --- a/modules/juce_audio_plugin_client/RTAS/juce_RTAS_DigiCode3.cpp +++ b/modules/juce_audio_plugin_client/RTAS/juce_RTAS_DigiCode3.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -26,7 +25,7 @@ #pragma once -#include "../../juce_core/system/juce_TargetPlatform.h" +#include <juce_core/system/juce_TargetPlatform.h> #include "../utility/juce_CheckSettingMacros.h" #if JucePlugin_Build_RTAS @@ -34,12 +33,7 @@ #include "../utility/juce_IncludeSystemHeaders.h" #include "juce_RTAS_DigiCode_Header.h" - #ifdef __clang__ - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wnon-virtual-dtor" - #pragma clang diagnostic ignored "-Wextra-tokens" - #pragma clang diagnostic ignored "-Wreorder" - #endif + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wnon-virtual-dtor", "-Wextra-tokens", "-Wreorder") /* This file is used to include and build the required digidesign CPP files without your project @@ -68,9 +62,7 @@ #include <Dispatcher.cpp> #endif - #ifdef __clang__ - #pragma clang diagnostic pop - #endif + JUCE_END_IGNORE_WARNINGS_GCC_LIKE #else diff --git a/modules/juce_audio_plugin_client/RTAS/juce_RTAS_DigiCode_Header.h b/modules/juce_audio_plugin_client/RTAS/juce_RTAS_DigiCode_Header.h index 5e2a3094..cb3929e3 100644 --- a/modules/juce_audio_plugin_client/RTAS/juce_RTAS_DigiCode_Header.h +++ b/modules/juce_audio_plugin_client/RTAS/juce_RTAS_DigiCode_Header.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_plugin_client/RTAS/juce_RTAS_MacUtilities.mm b/modules/juce_audio_plugin_client/RTAS/juce_RTAS_MacUtilities.mm index bd72e03b..482055f4 100644 --- a/modules/juce_audio_plugin_client/RTAS/juce_RTAS_MacUtilities.mm +++ b/modules/juce_audio_plugin_client/RTAS/juce_RTAS_MacUtilities.mm @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -24,7 +23,7 @@ ============================================================================== */ -#include "../../juce_core/system/juce_TargetPlatform.h" +#include <juce_core/system/juce_TargetPlatform.h> #include "../utility/juce_CheckSettingMacros.h" #if JucePlugin_Build_RTAS diff --git a/modules/juce_audio_plugin_client/RTAS/juce_RTAS_WinUtilities.cpp b/modules/juce_audio_plugin_client/RTAS/juce_RTAS_WinUtilities.cpp index 257c0e02..3f826e5d 100644 --- a/modules/juce_audio_plugin_client/RTAS/juce_RTAS_WinUtilities.cpp +++ b/modules/juce_audio_plugin_client/RTAS/juce_RTAS_WinUtilities.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -24,7 +23,7 @@ ============================================================================== */ -#include "../../juce_core/system/juce_TargetPlatform.h" +#include <juce_core/system/juce_TargetPlatform.h> #include "../utility/juce_CheckSettingMacros.h" #if JucePlugin_Build_RTAS diff --git a/modules/juce_audio_plugin_client/RTAS/juce_RTAS_Wrapper.cpp b/modules/juce_audio_plugin_client/RTAS/juce_RTAS_Wrapper.cpp index 65936bdd..c7d78029 100644 --- a/modules/juce_audio_plugin_client/RTAS/juce_RTAS_Wrapper.cpp +++ b/modules/juce_audio_plugin_client/RTAS/juce_RTAS_Wrapper.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -24,7 +23,7 @@ ============================================================================== */ -#include "../../juce_core/system/juce_TargetPlatform.h" +#include <juce_core/system/juce_TargetPlatform.h> #include "../utility/juce_CheckSettingMacros.h" #if JucePlugin_Build_RTAS @@ -45,12 +44,9 @@ #include <Mac2Win.H> #endif -#ifdef __clang__ - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Widiomatic-parentheses" - #pragma clang diagnostic ignored "-Wnon-virtual-dtor" - #pragma clang diagnostic ignored "-Wcomment" -#endif +JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Widiomatic-parentheses", + "-Wnon-virtual-dtor", + "-Wcomment") /* Note about include paths ------------------------ @@ -99,15 +95,10 @@ #include <FicProcessTokens.h> #include <ExternalVersionDefines.h> -#ifdef __clang__ - #pragma clang diagnostic pop -#endif +JUCE_END_IGNORE_WARNINGS_GCC_LIKE //============================================================================== -#ifdef _MSC_VER - #pragma pack (push, 8) - #pragma warning (disable: 4263 4264 4250) -#endif +JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4263 4264 4250) #include "../utility/juce_IncludeModuleHeaders.h" @@ -606,13 +597,9 @@ public: if (! midiEvents.isEmpty()) { #if JucePlugin_ProducesMidiOutput - const juce::uint8* midiEventData; - int midiEventSize, midiEventPosition; - MidiBuffer::Iterator i (midiEvents); - - while (i.getNextEvent (midiEventData, midiEventSize, midiEventPosition)) + for (const auto metadata : midiEvents) { - //jassert (midiEventPosition >= 0 && midiEventPosition < (int) numSamples); + //jassert (metadata.samplePosition >= 0 && metadata.samplePosition < (int) numSamples); } #elif JUCE_DEBUG || JUCE_LOG_ASSERTIONS // if your plugin creates midi messages, you'll need to set @@ -1061,4 +1048,6 @@ CProcessGroupInterface* CProcessGroup::CreateProcessGroup() return new JucePlugInGroup(); } +JUCE_END_IGNORE_WARNINGS_MSVC + #endif diff --git a/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterApp.cpp b/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterApp.cpp index 8b4376f4..48d5104c 100644 --- a/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterApp.cpp +++ b/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterApp.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -24,7 +23,7 @@ ============================================================================== */ -#include "../../juce_core/system/juce_TargetPlatform.h" +#include <juce_core/system/juce_TargetPlatform.h> #include "../utility/juce_CheckSettingMacros.h" #include "../utility/juce_IncludeSystemHeaders.h" @@ -41,8 +40,6 @@ // set it then by default we'll just create a simple one as below. #if ! JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP -extern juce::AudioProcessor* JUCE_CALLTYPE createPluginFilter(); - #include "juce_StandaloneFilterWindow.h" namespace juce @@ -159,7 +156,6 @@ void JUCE_CALLTYPE juce_switchToHostApplication() holder->switchToHostApplication(); } -#if JUCE_MODULE_AVAILABLE_juce_gui_basics Image JUCE_CALLTYPE juce_getIAAHostIcon (int size) { if (auto holder = StandalonePluginHolder::getInstance()) @@ -168,6 +164,5 @@ Image JUCE_CALLTYPE juce_getIAAHostIcon (int size) return Image(); } #endif -#endif #endif diff --git a/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h b/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h index 2069d93e..4add21d9 100644 --- a/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h +++ b/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -24,8 +23,10 @@ ============================================================================== */ -#if JUCE_MODULE_AVAILABLE_juce_audio_plugin_client -extern juce::AudioProcessor* JUCE_API JUCE_CALLTYPE createPluginFilterOfType (juce::AudioProcessor::WrapperType type); +#pragma once + +#ifndef DOXYGEN + #include "../utility/juce_CreatePluginFilter.h" #endif namespace juce @@ -123,15 +124,7 @@ public: //============================================================================== virtual void createPlugin() { - #if JUCE_MODULE_AVAILABLE_juce_audio_plugin_client - processor.reset (::createPluginFilterOfType (AudioProcessor::wrapperType_Standalone)); - #else - AudioProcessor::setTypeOfNextNewPlugin (AudioProcessor::wrapperType_Standalone); - processor.reset (createPluginFilter()); - AudioProcessor::setTypeOfNextNewPlugin (AudioProcessor::wrapperType_Undefined); - #endif - jassert (processor != nullptr); // Your createPluginFilter() function must return a valid object! - + processor.reset (createPluginFilterOfType (AudioProcessor::wrapperType_Standalone)); processor->disableNonMainBuses(); processor->setRateAndBufferSizeDetails (44100, 512); @@ -372,7 +365,6 @@ public: return false; } - #if JUCE_MODULE_AVAILABLE_juce_gui_basics Image getIAAHostIcon (int size) { #if JUCE_IOS && JucePlugin_Enable_IAA @@ -384,7 +376,6 @@ public: return {}; } - #endif static StandalonePluginHolder* getInstance(); @@ -559,7 +550,7 @@ private: @tags{Audio} */ class StandaloneFilterWindow : public DocumentWindow, - public Button::Listener + private Button::Listener { public: //============================================================================== @@ -666,20 +657,6 @@ public: JUCEApplicationBase::quit(); } - void buttonClicked (Button*) override - { - PopupMenu m; - m.addItem (1, TRANS("Audio/MIDI Settings...")); - m.addSeparator(); - m.addItem (2, TRANS("Save current state...")); - m.addItem (3, TRANS("Load a saved state...")); - m.addSeparator(); - m.addItem (4, TRANS("Reset to default state")); - - m.showMenuAsync (PopupMenu::Options(), - ModalCallbackFunction::forComponent (menuCallback, this)); - } - void handleMenuResult (int result) { switch (result) @@ -709,6 +686,20 @@ public: std::unique_ptr<StandalonePluginHolder> pluginHolder; private: + void buttonClicked (Button*) override + { + PopupMenu m; + m.addItem (1, TRANS("Audio/MIDI Settings...")); + m.addSeparator(); + m.addItem (2, TRANS("Save current state...")); + m.addItem (3, TRANS("Load a saved state...")); + m.addSeparator(); + m.addItem (4, TRANS("Reset to default state")); + + m.showMenuAsync (PopupMenu::Options(), + ModalCallbackFunction::forComponent (menuCallback, this)); + } + //============================================================================== class MainContentComponent : public Component, private Value::Listener, @@ -760,8 +751,9 @@ private: notification.setBounds (r.removeFromTop (NotificationArea::height)); if (editor != nullptr) - editor->setBounds (editor->getLocalArea (this, r) - .withPosition (r.getTopLeft().transformedBy (editor->getTransform().inverted()))); + editor->setBounds (editor->getLocalArea (this, r.toFloat()) + .withPosition (r.getTopLeft().toFloat().transformedBy (editor->getTransform().inverted())) + .toNearestInt()); } private: diff --git a/modules/juce_audio_plugin_client/Unity/juce_UnityPluginInterface.h b/modules/juce_audio_plugin_client/Unity/juce_UnityPluginInterface.h index a86daeee..aa2f471f 100644 --- a/modules/juce_audio_plugin_client/Unity/juce_UnityPluginInterface.h +++ b/modules/juce_audio_plugin_client/Unity/juce_UnityPluginInterface.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -87,6 +86,8 @@ enum UnityEventModifiers }; //============================================================================== +#ifndef DOXYGEN + struct UnityAudioSpatializerData { float listenerMatrix[16]; @@ -173,6 +174,8 @@ struct UnityAudioEffectDefinition getFloatBufferCallback getFloatBuffer; }; +#endif + //============================================================================== // Unity callback extern "C" UNITY_INTERFACE_EXPORT int UNITY_INTERFACE_API UnityGetAudioEffectDefinitions (UnityAudioEffectDefinition*** definitionsPtr); diff --git a/modules/juce_audio_plugin_client/Unity/juce_Unity_Wrapper.cpp b/modules/juce_audio_plugin_client/Unity/juce_Unity_Wrapper.cpp index f39efc46..c9c1831a 100644 --- a/modules/juce_audio_plugin_client/Unity/juce_Unity_Wrapper.cpp +++ b/modules/juce_audio_plugin_client/Unity/juce_Unity_Wrapper.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -24,11 +23,12 @@ ============================================================================== */ +#include <juce_core/system/juce_TargetPlatform.h> + #if JucePlugin_Build_Unity -#include "../../juce_core/system/juce_TargetPlatform.h" #include "../utility/juce_IncludeModuleHeaders.h" -#include "../../juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp" +#include <juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp> #if JUCE_WINDOWS #include "../utility/juce_IncludeSystemHeaders.h" @@ -60,6 +60,9 @@ public: Point<float> localToGlobal (Point<float> relativePosition) override { return relativePosition + getBounds().getPosition().toFloat(); } Point<float> globalToLocal (Point<float> screenPosition) override { return screenPosition - getBounds().getPosition().toFloat(); } + using ComponentPeer::localToGlobal; + using ComponentPeer::globalToLocal; + StringArray getAvailableRenderingEngines() override { return StringArray ("Software Renderer"); } void setBounds (const Rectangle<int>& newBounds, bool) override @@ -324,6 +327,8 @@ public: jassert (numConfigs > 0 && (configs[0][0] > 0 || configs[0][1] > 0)); + ignoreUnused (numConfigs); + pluginInstance->setPlayConfigDetails (configs[0][0], configs[0][1], state->sampleRate, samplesPerBlock); #else pluginInstance->setRateAndBufferSizeDetails (state->sampleRate, samplesPerBlock); @@ -374,10 +379,13 @@ public: auto* parameter = juceParameters.params[i]; auto& paramDef = parametersPtr.get()[i]; - strncpy (paramDef.name, parameter->getName (15).toRawUTF8(), 15); + const auto nameLength = (size_t) numElementsInArray (paramDef.name); + const auto unitLength = (size_t) numElementsInArray (paramDef.unit); + + parameter->getName ((int) nameLength - 1).copyToUTF8 (paramDef.name, nameLength); if (parameter->getLabel().isNotEmpty()) - strncpy (paramDef.unit, parameter->getLabel().toRawUTF8(), 15); + parameter->getLabel().copyToUTF8 (paramDef.unit, unitLength); parameterDescriptions.add (parameter->getName (15)); paramDef.description = parameterDescriptions[i].toRawUTF8(); @@ -552,7 +560,7 @@ namespace UnityCallbacks auto* pluginInstance = state->getEffectData<AudioProcessorUnityWrapper>(); *value = pluginInstance->getParameter (index); - strncpy (valueStr, pluginInstance->getParameterString (index).toRawUTF8(), 15); + pluginInstance->getParameterString (index).copyToUTF8 (valueStr, 15); return 0; } @@ -636,7 +644,7 @@ static void declareEffect (UnityAudioEffectDefinition& definition) if (! name.startsWithIgnoreCase ("audioplugin")) name = "audioplugin_" + name; - strcpy (definition.name, name.toRawUTF8()); + name.copyToUTF8 (definition.name, (size_t) numElementsInArray (definition.name)); definition.structSize = sizeof (UnityAudioEffectDefinition); definition.parameterStructSize = sizeof (UnityAudioParameterDefinition); diff --git a/modules/juce_audio_plugin_client/VST/juce_VSTCallbackHandler.h b/modules/juce_audio_plugin_client/VST/juce_VSTCallbackHandler.h index 62e08d92..8c616186 100644 --- a/modules/juce_audio_plugin_client/VST/juce_VSTCallbackHandler.h +++ b/modules/juce_audio_plugin_client/VST/juce_VSTCallbackHandler.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). 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 7f63093c..6c97aa24 100644 --- a/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp +++ b/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -24,14 +23,13 @@ ============================================================================== */ -#include "../../juce_core/system/juce_TargetPlatform.h" +#include <juce_core/system/juce_CompilerWarnings.h> +#include <juce_core/system/juce_TargetPlatform.h> #include "../utility/juce_CheckSettingMacros.h" #if JucePlugin_Build_VST -#ifdef _MSC_VER - #pragma warning (disable : 4996 4100) -#endif +JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4996 4100) #include "../utility/juce_IncludeSystemHeaders.h" #include <juce_core/juce_core.h> @@ -63,33 +61,18 @@ #define PRAGMA_ALIGN_SUPPORTED 1 #endif -#ifndef _MSC_VER +#if ! JUCE_MSVC #define __cdecl #endif -#if JUCE_CLANG - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wconversion" - #pragma clang diagnostic ignored "-Wshadow" - #pragma clang diagnostic ignored "-Wdeprecated-register" - #pragma clang diagnostic ignored "-Wunused-parameter" - #pragma clang diagnostic ignored "-Wdeprecated-writable-strings" - #pragma clang diagnostic ignored "-Wnon-virtual-dtor" - #if __has_warning("-Wzero-as-null-pointer-constant") - #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" - #endif -#endif - -#if JUCE_GCC - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wshadow" - #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" -#endif - -#ifdef _MSC_VER - #pragma warning (push) - #pragma warning (disable : 4458) -#endif +JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wconversion", + "-Wshadow", + "-Wdeprecated-register", + "-Wunused-parameter", + "-Wdeprecated-writable-strings", + "-Wnon-virtual-dtor", + "-Wzero-as-null-pointer-constant") +JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4458) #define VST_FORCE_DEPRECATED 0 @@ -105,41 +88,28 @@ namespace Vst2 #include "pluginterfaces/vst2.x/aeffectx.h" } -using namespace juce; - -#ifdef _MSC_VER - #pragma warning (pop) -#endif - -#if JUCE_CLANG - #pragma clang diagnostic pop -#endif - -#if JUCE_GCC - #pragma GCC diagnostic pop -#endif +JUCE_END_IGNORE_WARNINGS_MSVC +JUCE_END_IGNORE_WARNINGS_GCC_LIKE //============================================================================== -#ifdef _MSC_VER +#if JUCE_MSVC #pragma pack (push, 8) #endif #define JUCE_VSTINTERFACE_H_INCLUDED 1 +#define JUCE_GUI_BASICS_INCLUDE_XHEADERS 1 #include "../utility/juce_IncludeModuleHeaders.h" + +using namespace juce; + #include "../utility/juce_FakeMouseMoveGenerator.h" #include "../utility/juce_WindowsHooks.h" -#include "../../juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp" -#include "../../juce_audio_processors/format_types/juce_VSTCommon.h" +#include <juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp> +#include <juce_audio_processors/format_types/juce_VSTCommon.h> -#if JUCE_BIG_ENDIAN - #define JUCE_MULTICHAR_CONSTANT(a, b, c, d) (a | (((uint32) b) << 8) | (((uint32) c) << 16) | (((uint32) d) << 24)) -#else - #define JUCE_MULTICHAR_CONSTANT(a, b, c, d) (d | (((uint32) c) << 8) | (((uint32) b) << 16) | (((uint32) a) << 24)) -#endif - -#ifdef _MSC_VER +#ifdef JUCE_MSVC #pragma pack (pop) #endif @@ -162,6 +132,10 @@ namespace juce #endif #endif +#if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE + extern JUCE_API double getScaleFactorForWindow (HWND); +#endif + extern JUCE_API bool handleManufacturerSpecificVST2Opcode (int32, pointer_sized_int, void*, float); } @@ -241,7 +215,7 @@ struct SharedMessageThread : public Thread MessageManager::getInstance()->setCurrentThreadAsMessageThread(); - ScopedXDisplay xDisplay; + XWindowSystem::getInstance(); while ((! threadShouldExit()) && MessageManager::getInstance()->runDispatchLoopUntil (250)) {} @@ -550,15 +524,11 @@ public: outgoingEvents.ensureSize (numEvents); outgoingEvents.clear(); - const uint8* midiEventData; - int midiEventSize, midiEventPosition; - MidiBuffer::Iterator i (midiEvents); - - while (i.getNextEvent (midiEventData, midiEventSize, midiEventPosition)) + for (const auto metadata : midiEvents) { - jassert (midiEventPosition >= 0 && midiEventPosition < numSamples); + jassert (metadata.samplePosition >= 0 && metadata.samplePosition < numSamples); - outgoingEvents.addEvent (midiEventData, midiEventSize, midiEventPosition); + outgoingEvents.addEvent (metadata.data, metadata.numBytes, metadata.samplePosition); } // Send VST events to the host. @@ -897,210 +867,6 @@ public: } //============================================================================== - struct SpeakerMappings : private AudioChannelSet // (inheritance only to give easier access to items in the namespace) - { - struct Mapping - { - int32 vst2; - ChannelType channels[13]; - - bool matches (const Array<ChannelType>& chans) const noexcept - { - const int n = sizeof (channels) / sizeof (ChannelType); - - for (int i = 0; i < n; ++i) - { - if (channels[i] == unknown) return (i == chans.size()); - if (i == chans.size()) return (channels[i] == unknown); - - if (channels[i] != chans.getUnchecked(i)) - return false; - } - - return true; - } - }; - - static AudioChannelSet vstArrangementTypeToChannelSet (const Vst2::VstSpeakerArrangement& arr) - { - if (arr.type == Vst2::kSpeakerArrEmpty) return AudioChannelSet::disabled(); - if (arr.type == Vst2::kSpeakerArrMono) return AudioChannelSet::mono(); - if (arr.type == Vst2::kSpeakerArrStereo) return AudioChannelSet::stereo(); - if (arr.type == Vst2::kSpeakerArr30Cine) return AudioChannelSet::createLCR(); - if (arr.type == Vst2::kSpeakerArr30Music) return AudioChannelSet::createLRS(); - if (arr.type == Vst2::kSpeakerArr40Cine) return AudioChannelSet::createLCRS(); - if (arr.type == Vst2::kSpeakerArr50) return AudioChannelSet::create5point0(); - if (arr.type == Vst2::kSpeakerArr51) return AudioChannelSet::create5point1(); - if (arr.type == Vst2::kSpeakerArr60Cine) return AudioChannelSet::create6point0(); - if (arr.type == Vst2::kSpeakerArr61Cine) return AudioChannelSet::create6point1(); - if (arr.type == Vst2::kSpeakerArr60Music) return AudioChannelSet::create6point0Music(); - if (arr.type == Vst2::kSpeakerArr61Music) return AudioChannelSet::create6point1Music(); - if (arr.type == Vst2::kSpeakerArr70Music) return AudioChannelSet::create7point0(); - if (arr.type == Vst2::kSpeakerArr70Cine) return AudioChannelSet::create7point0SDDS(); - if (arr.type == Vst2::kSpeakerArr71Music) return AudioChannelSet::create7point1(); - if (arr.type == Vst2::kSpeakerArr71Cine) return AudioChannelSet::create7point1SDDS(); - if (arr.type == Vst2::kSpeakerArr40Music) return AudioChannelSet::quadraphonic(); - - for (auto* m = getMappings(); m->vst2 != Vst2::kSpeakerArrEmpty; ++m) - { - if (m->vst2 == arr.type) - { - AudioChannelSet s; - - for (int i = 0; m->channels[i] != 0; ++i) - s.addChannel (m->channels[i]); - - return s; - } - } - - return AudioChannelSet::discreteChannels (arr.numChannels); - } - - static int32 channelSetToVstArrangementType (AudioChannelSet channels) - { - if (channels == AudioChannelSet::disabled()) return Vst2::kSpeakerArrEmpty; - if (channels == AudioChannelSet::mono()) return Vst2::kSpeakerArrMono; - if (channels == AudioChannelSet::stereo()) return Vst2::kSpeakerArrStereo; - if (channels == AudioChannelSet::createLCR()) return Vst2::kSpeakerArr30Cine; - if (channels == AudioChannelSet::createLRS()) return Vst2::kSpeakerArr30Music; - if (channels == AudioChannelSet::createLCRS()) return Vst2::kSpeakerArr40Cine; - if (channels == AudioChannelSet::create5point0()) return Vst2::kSpeakerArr50; - if (channels == AudioChannelSet::create5point1()) return Vst2::kSpeakerArr51; - if (channels == AudioChannelSet::create6point0()) return Vst2::kSpeakerArr60Cine; - if (channels == AudioChannelSet::create6point1()) return Vst2::kSpeakerArr61Cine; - if (channels == AudioChannelSet::create6point0Music()) return Vst2::kSpeakerArr60Music; - if (channels == AudioChannelSet::create6point1Music()) return Vst2::kSpeakerArr61Music; - if (channels == AudioChannelSet::create7point0()) return Vst2::kSpeakerArr70Music; - if (channels == AudioChannelSet::create7point0SDDS()) return Vst2::kSpeakerArr70Cine; - if (channels == AudioChannelSet::create7point1()) return Vst2::kSpeakerArr71Music; - if (channels == AudioChannelSet::create7point1SDDS()) return Vst2::kSpeakerArr71Cine; - if (channels == AudioChannelSet::quadraphonic()) return Vst2::kSpeakerArr40Music; - - if (channels == AudioChannelSet::disabled()) - return Vst2::kSpeakerArrEmpty; - - auto chans = channels.getChannelTypes(); - - for (auto* m = getMappings(); m->vst2 != Vst2::kSpeakerArrEmpty; ++m) - if (m->matches (chans)) - return m->vst2; - - return Vst2::kSpeakerArrUserDefined; - } - - static void channelSetToVstArrangement (const AudioChannelSet& channels, Vst2::VstSpeakerArrangement& result) - { - result.type = channelSetToVstArrangementType (channels); - result.numChannels = channels.size(); - - for (int i = 0; i < result.numChannels; ++i) - { - auto& speaker = result.speakers[i]; - - zeromem (&speaker, sizeof (Vst2::VstSpeakerProperties)); - speaker.type = getSpeakerType (channels.getTypeOfChannel (i)); - } - } - - static const Mapping* getMappings() noexcept - { - static const Mapping mappings[] = - { - { Vst2::kSpeakerArrMono, { centre, unknown } }, - { Vst2::kSpeakerArrStereo, { left, right, unknown } }, - { Vst2::kSpeakerArrStereoSurround, { leftSurround, rightSurround, unknown } }, - { Vst2::kSpeakerArrStereoCenter, { leftCentre, rightCentre, unknown } }, - { Vst2::kSpeakerArrStereoSide, { leftSurroundRear, rightSurroundRear, unknown } }, - { Vst2::kSpeakerArrStereoCLfe, { centre, LFE, unknown } }, - { Vst2::kSpeakerArr30Cine, { left, right, centre, unknown } }, - { Vst2::kSpeakerArr30Music, { left, right, surround, unknown } }, - { Vst2::kSpeakerArr31Cine, { left, right, centre, LFE, unknown } }, - { Vst2::kSpeakerArr31Music, { left, right, LFE, surround, unknown } }, - { Vst2::kSpeakerArr40Cine, { left, right, centre, surround, unknown } }, - { Vst2::kSpeakerArr40Music, { left, right, leftSurround, rightSurround, unknown } }, - { Vst2::kSpeakerArr41Cine, { left, right, centre, LFE, surround, unknown } }, - { Vst2::kSpeakerArr41Music, { left, right, LFE, leftSurround, rightSurround, unknown } }, - { Vst2::kSpeakerArr50, { left, right, centre, leftSurround, rightSurround, unknown } }, - { Vst2::kSpeakerArr51, { left, right, centre, LFE, leftSurround, rightSurround, unknown } }, - { Vst2::kSpeakerArr60Cine, { left, right, centre, leftSurround, rightSurround, surround, unknown } }, - { Vst2::kSpeakerArr60Music, { left, right, leftSurround, rightSurround, leftSurroundRear, rightSurroundRear, unknown } }, - { Vst2::kSpeakerArr61Cine, { left, right, centre, LFE, leftSurround, rightSurround, surround, unknown } }, - { Vst2::kSpeakerArr61Music, { left, right, LFE, leftSurround, rightSurround, leftSurroundRear, rightSurroundRear, unknown } }, - { Vst2::kSpeakerArr70Cine, { left, right, centre, leftSurround, rightSurround, topFrontLeft, topFrontRight, unknown } }, - { Vst2::kSpeakerArr70Music, { left, right, centre, leftSurround, rightSurround, leftSurroundRear, rightSurroundRear, unknown } }, - { Vst2::kSpeakerArr71Cine, { left, right, centre, LFE, leftSurround, rightSurround, topFrontLeft, topFrontRight, unknown } }, - { Vst2::kSpeakerArr71Music, { left, right, centre, LFE, leftSurround, rightSurround, leftSurroundRear, rightSurroundRear, unknown } }, - { Vst2::kSpeakerArr80Cine, { left, right, centre, leftSurround, rightSurround, topFrontLeft, topFrontRight, surround, unknown } }, - { Vst2::kSpeakerArr80Music, { left, right, centre, leftSurround, rightSurround, surround, leftSurroundRear, rightSurroundRear, unknown } }, - { Vst2::kSpeakerArr81Cine, { left, right, centre, LFE, leftSurround, rightSurround, topFrontLeft, topFrontRight, surround, unknown } }, - { Vst2::kSpeakerArr81Music, { left, right, centre, LFE, leftSurround, rightSurround, surround, leftSurroundRear, rightSurroundRear, unknown } }, - { Vst2::kSpeakerArr102, { left, right, centre, LFE, leftSurround, rightSurround, topFrontLeft, topFrontCentre, topFrontRight, topRearLeft, topRearRight, LFE2, unknown } }, - { Vst2::kSpeakerArrEmpty, { unknown } } - }; - - return mappings; - } - - static inline int32 getSpeakerType (AudioChannelSet::ChannelType type) noexcept - { - switch (type) - { - case AudioChannelSet::left: return Vst2::kSpeakerL; - case AudioChannelSet::right: return Vst2::kSpeakerR; - case AudioChannelSet::centre: return Vst2::kSpeakerC; - case AudioChannelSet::LFE: return Vst2::kSpeakerLfe; - case AudioChannelSet::leftSurround: return Vst2::kSpeakerLs; - case AudioChannelSet::rightSurround: return Vst2::kSpeakerRs; - case AudioChannelSet::leftCentre: return Vst2::kSpeakerLc; - case AudioChannelSet::rightCentre: return Vst2::kSpeakerRc; - case AudioChannelSet::surround: return Vst2::kSpeakerS; - case AudioChannelSet::leftSurroundRear: return Vst2::kSpeakerSl; - case AudioChannelSet::rightSurroundRear: return Vst2::kSpeakerSr; - case AudioChannelSet::topMiddle: return Vst2::kSpeakerTm; - case AudioChannelSet::topFrontLeft: return Vst2::kSpeakerTfl; - case AudioChannelSet::topFrontCentre: return Vst2::kSpeakerTfc; - case AudioChannelSet::topFrontRight: return Vst2::kSpeakerTfr; - case AudioChannelSet::topRearLeft: return Vst2::kSpeakerTrl; - case AudioChannelSet::topRearCentre: return Vst2::kSpeakerTrc; - case AudioChannelSet::topRearRight: return Vst2::kSpeakerTrr; - case AudioChannelSet::LFE2: return Vst2::kSpeakerLfe2; - default: break; - } - - return 0; - } - - static inline AudioChannelSet::ChannelType getChannelType (int32 type) noexcept - { - switch (type) - { - case Vst2::kSpeakerL: return AudioChannelSet::left; - case Vst2::kSpeakerR: return AudioChannelSet::right; - case Vst2::kSpeakerC: return AudioChannelSet::centre; - case Vst2::kSpeakerLfe: return AudioChannelSet::LFE; - case Vst2::kSpeakerLs: return AudioChannelSet::leftSurround; - case Vst2::kSpeakerRs: return AudioChannelSet::rightSurround; - case Vst2::kSpeakerLc: return AudioChannelSet::leftCentre; - case Vst2::kSpeakerRc: return AudioChannelSet::rightCentre; - case Vst2::kSpeakerS: return AudioChannelSet::surround; - case Vst2::kSpeakerSl: return AudioChannelSet::leftSurroundRear; - case Vst2::kSpeakerSr: return AudioChannelSet::rightSurroundRear; - case Vst2::kSpeakerTm: return AudioChannelSet::topMiddle; - case Vst2::kSpeakerTfl: return AudioChannelSet::topFrontLeft; - case Vst2::kSpeakerTfc: return AudioChannelSet::topFrontCentre; - case Vst2::kSpeakerTfr: return AudioChannelSet::topFrontRight; - case Vst2::kSpeakerTrl: return AudioChannelSet::topRearLeft; - case Vst2::kSpeakerTrc: return AudioChannelSet::topRearCentre; - case Vst2::kSpeakerTrr: return AudioChannelSet::topRearRight; - case Vst2::kSpeakerLfe2: return AudioChannelSet::LFE2; - default: break; - } - - return AudioChannelSet::unknown; - } - }; - void timerCallback() override { if (shouldDeleteEditor) @@ -1268,6 +1034,9 @@ public: // A component to hold the AudioProcessorEditor, and cope with some housekeeping // chores when it changes or repaints. struct EditorCompWrapper : public Component + #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE + , public Timer + #endif { EditorCompWrapper (JuceVSTWrapper& w, AudioProcessorEditor& editor) : wrapper (w) @@ -1286,9 +1055,6 @@ public: #if JUCE_WINDOWS if (! getHostType().isReceptor()) addMouseListener (this, true); - #if JUCE_WIN_PER_MONITOR_DPI_AWARE - wrapper.editorScaleFactor = static_cast<float> (Desktop::getInstance().getDisplays().getMainDisplay().scale); - #endif #endif ignoreUnused (fakeMouseGenerator); @@ -1305,16 +1071,7 @@ public: void getEditorBounds (Vst2::ERect& bounds) { auto b = getSizeToContainChild(); - - bounds.top = 0; - bounds.left = 0; - bounds.bottom = (int16) b.getHeight(); - bounds.right = (int16) b.getWidth(); - - #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE - bounds.bottom = (int16) roundToInt (bounds.bottom * wrapper.editorScaleFactor); - bounds.right = (int16) roundToInt (bounds.right * wrapper.editorScaleFactor); - #endif + bounds = convertToHostBounds ({ 0, 0, (int16) b.getHeight(), (int16) b.getWidth() }); } void attachToHost (VstOpCodeArguments args) @@ -1326,17 +1083,24 @@ public: addToDesktop (0, args.ptr); hostWindow = (HWND) args.ptr; - if (auto* ed = getEditorComp()) - #if JUCE_WIN_PER_MONITOR_DPI_AWARE - if (auto* peer = ed->getPeer()) - wrapper.editorScaleFactor = (float) peer->getPlatformScaleFactor(); - #else - ed->setScaleFactor (wrapper.editorScaleFactor); - #endif + #if JUCE_WIN_PER_MONITOR_DPI_AWARE + checkHostWindowScaleFactor(); + startTimer (500); + #endif #elif JUCE_LINUX addToDesktop (0, args.ptr); hostWindow = (Window) args.ptr; - XReparentWindow (display.display, (Window) getWindowHandle(), hostWindow, 0, 0); + X11Symbols::getInstance()->xReparentWindow (display, (Window) getWindowHandle(), hostWindow, 0, 0); + + if (auto* peer = getPeer()) + { + auto screenBounds = peer->localToGlobal (peer->getBounds()); + + auto scale = Desktop::getInstance().getDisplays().getDisplayForRect (screenBounds, false)->scale + / Desktop::getInstance().getGlobalScaleFactor(); + + setContentScaleFactor ((float) scale); + } #else hostWindow = attachComponentToWindowRefVST (this, args.ptr, wrapper.useNSView); #endif @@ -1369,34 +1133,26 @@ public: AudioProcessorEditor* getEditorComp() const noexcept { - return dynamic_cast<AudioProcessorEditor*> (getChildComponent(0)); + return dynamic_cast<AudioProcessorEditor*> (getChildComponent (0)); } - #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE - void checkScaleFactorIsCorrect() + void resized() override { - if (auto* peer = getEditorComp()->getPeer()) - { - auto peerScaleFactor = (float) peer->getPlatformScaleFactor(); + auto newBounds = getLocalBounds(); - if (! approximatelyEqual (peerScaleFactor, wrapper.editorScaleFactor)) - wrapper.handleSetContentScaleFactor (peerScaleFactor); - } - } - #endif + #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE + if (! lastBounds.isEmpty() && isWithin (newBounds.toDouble().getAspectRatio(), lastBounds.toDouble().getAspectRatio(), 0.1)) + return; + + lastBounds = newBounds; + #endif - void resized() override - { if (auto* ed = getEditorComp()) { - #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE - checkScaleFactorIsCorrect(); - #endif - ed->setTopLeftPosition (0, 0); if (shouldResizeEditor) - ed->setBounds (ed->getLocalArea (this, getLocalBounds())); + ed->setBounds (ed->getLocalArea (this, newBounds)); updateWindowSize (false); } @@ -1407,6 +1163,11 @@ public: #endif } + void parentSizeChanged() override + { + updateWindowSize (true); + } + void childBoundsChanged (Component*) override { updateWindowSize (false); @@ -1445,9 +1206,12 @@ public: shouldResizeEditor = true; #else ignoreUnused (resizeEditor); - XResizeWindow (display.display, (Window) getWindowHandle(), - static_cast<unsigned int> (roundToInt (pos.getWidth() * wrapper.editorScaleFactor)), - static_cast<unsigned int> (roundToInt (pos.getHeight() * wrapper.editorScaleFactor))); + + auto scale = Desktop::getInstance().getGlobalScaleFactor(); + + X11Symbols::getInstance()->xResizeWindow (display, (Window) getWindowHandle(), + static_cast<unsigned int> (roundToInt ((float) pos.getWidth() * scale)), + static_cast<unsigned int> (roundToInt ((float) pos.getHeight() * scale))); #endif #if JUCE_MAC @@ -1459,6 +1223,10 @@ public: void resizeHostWindow (int newWidth, int newHeight) { + auto rect = convertToHostBounds ({ 0, 0, (int16) newHeight, (int16) newWidth }); + newWidth = rect.right - rect.left; + newHeight = rect.bottom - rect.top; + bool sizeWasSuccessful = false; if (auto host = wrapper.hostCallback) @@ -1467,11 +1235,6 @@ public: if (status == (pointer_sized_int) 1 || getHostType().isAbletonLive()) { - #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE - newWidth = roundToInt (newWidth * wrapper.editorScaleFactor); - newHeight = roundToInt (newHeight * wrapper.editorScaleFactor); - #endif - const ScopedValueSetter<bool> inSizeWindowSetter (isInSizeWindow, true); sizeWasSuccessful = (host (wrapper.getAEffect(), Vst2::audioMasterSizeWindow, @@ -1494,11 +1257,6 @@ public: int dh = 0; const int frameThickness = GetSystemMetrics (SM_CYFIXEDFRAME); - #if JUCE_WIN_PER_MONITOR_DPI_AWARE - newWidth = roundToInt (newWidth * wrapper.editorScaleFactor); - newHeight = roundToInt (newHeight * wrapper.editorScaleFactor); - #endif - HWND w = (HWND) getWindowHandle(); while (w != 0) @@ -1547,6 +1305,34 @@ public: } } + void setContentScaleFactor (float scale) + { + if (! approximatelyEqual (scale, editorScaleFactor)) + { + editorScaleFactor = scale; + + if (auto* ed = getEditorComp()) + ed->setScaleFactor (editorScaleFactor); + + updateWindowSize (true); + } + } + + #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE + void checkHostWindowScaleFactor() + { + auto hostWindowScale = (float) getScaleFactorForWindow (hostWindow); + + if (hostWindowScale > 0.0f && ! approximatelyEqual (hostWindowScale, editorScaleFactor)) + wrapper.handleSetContentScaleFactor (hostWindowScale); + } + + void timerCallback() override + { + checkHostWindowScaleFactor(); + } + #endif + #if JUCE_WINDOWS void mouseDown (const MouseEvent&) override { @@ -1572,20 +1358,39 @@ public: } #endif + //============================================================================== + static Vst2::ERect convertToHostBounds (const Vst2::ERect& rect) + { + auto desktopScale = Desktop::getInstance().getGlobalScaleFactor(); + + if (approximatelyEqual (desktopScale, 1.0f)) + return rect; + + return { (int16) roundToInt (rect.top * desktopScale), + (int16) roundToInt (rect.left * desktopScale), + (int16) roundToInt (rect.bottom * desktopScale), + (int16) roundToInt (rect.right * desktopScale) }; + } + //============================================================================== JuceVSTWrapper& wrapper; FakeMouseMoveGenerator fakeMouseGenerator; bool isInSizeWindow = false; bool shouldResizeEditor = true; + float editorScaleFactor = 1.0f; + #if JUCE_MAC void* hostWindow = nullptr; #elif JUCE_LINUX - ScopedXDisplay display; + ::Display* display = XWindowSystem::getInstance()->getDisplay(); Window hostWindow = {}; - #else + #elif JUCE_WINDOWS HWND hostWindow = {}; WindowsHooks hooks; + #if JUCE_WIN_PER_MONITOR_DPI_AWARE + juce::Rectangle<int> lastBounds; + #endif #endif JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (EditorCompWrapper) @@ -1601,7 +1406,7 @@ private: && (int32) hostCallback (&vstEffect, Vst2::audioMasterGetCurrentProcessLevel, 0, 0, nullptr, 0) == 4; } - static inline int32 convertHexVersionToDecimal (const unsigned int hexVersion) + static int32 convertHexVersionToDecimal (const unsigned int hexVersion) { #if JUCE_VST_RETURN_HEX_VERSION_NUMBER_DIRECTLY return (int32) hexVersion; @@ -2061,8 +1866,8 @@ private: if (handleManufacturerSpecificVST2Opcode (args.index, args.value, args.ptr, args.opt)) return 1; - if (args.index == JUCE_MULTICHAR_CONSTANT ('P', 'r', 'e', 'S') - && args.value == JUCE_MULTICHAR_CONSTANT ('A', 'e', 'C', 's')) + if (args.index == (int32) ByteOrder::bigEndianInt ("PreS") + && args.value == (int32) ByteOrder::bigEndianInt ("AeCs")) return handleSetContentScaleFactor (args.opt); if (args.index == Vst2::effGetParamDisplay) @@ -2077,7 +1882,7 @@ private: pointer_sized_int handleCanPlugInDo (VstOpCodeArguments args) { auto text = (const char*) args.ptr; - auto matches = [=](const char* s) { return strcmp (text, s) == 0; }; + auto matches = [=] (const char* s) { return strcmp (text, s) == 0; }; if (matches ("receiveVstEvents") || matches ("receiveVstMidiEvent") @@ -2219,18 +2024,10 @@ private: pointer_sized_int handleSetContentScaleFactor (float scale) { #if ! JUCE_MAC - if (! approximatelyEqual (scale, editorScaleFactor)) - { - editorScaleFactor = scale; + if (editorComp != nullptr) + editorComp->setContentScaleFactor (scale); - if (editorComp != nullptr) - #if JUCE_WINDOWS && ! JUCE_WIN_PER_MONITOR_DPI_AWARE - if (auto* ed = editorComp->getEditorComp()) - ed->setScaleFactor (scale); - #else - editorComp->updateWindowSize (true); - #endif - } + lastScaleFactorReceived = scale; #else ignoreUnused (scale); #endif @@ -2300,7 +2097,7 @@ private: VSTMidiEventList outgoingEvents; #if ! JUCE_MAC - float editorScaleFactor = 1.0f; + float lastScaleFactorReceived = 1.0f; #endif LegacyAudioParametersWrapper juceParameters; @@ -2352,7 +2149,7 @@ namespace if (auto* callbackHandler = dynamic_cast<VSTCallbackHandler*> (processor)) { - callbackHandler->handleVstHostCallbackAvailable ([audioMaster, aEffect](int32 opcode, int32 index, pointer_sized_int value, void* ptr, float opt) + callbackHandler->handleVstHostCallbackAvailable ([audioMaster, aEffect] (int32 opcode, int32 index, pointer_sized_int value, void* ptr, float opt) { return audioMaster (aEffect, opcode, index, value, ptr, opt); }); @@ -2431,7 +2228,7 @@ namespace return pluginEntryPoint (audioMaster); } - #ifndef JUCE_64BIT // (can't compile this on win64, but it's not needed anyway with VST2.4) + #if ! defined (JUCE_64BIT) && JUCE_MSVC // (can't compile this on win64, but it's not needed anyway with VST2.4) extern "C" __declspec (dllexport) int main (Vst2::audioMasterCallback audioMaster) { PluginHostType::jucePlugInClientCurrentWrapperType = AudioProcessor::wrapperType_VST; @@ -2449,4 +2246,6 @@ namespace } #endif +JUCE_END_IGNORE_WARNINGS_MSVC + #endif diff --git a/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.mm b/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.mm index 3672ab73..7c4887e7 100644 --- a/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.mm +++ b/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.mm @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -24,7 +23,7 @@ ============================================================================== */ -#include "../../juce_core/system/juce_TargetPlatform.h" +#include <juce_core/system/juce_TargetPlatform.h> #if JUCE_MAC 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 e0aca972..3e63d337 100644 --- a/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp +++ b/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -24,36 +23,49 @@ ============================================================================== */ -#include "../../juce_core/system/juce_TargetPlatform.h" +#include <juce_core/system/juce_CompilerWarnings.h> +#include <juce_core/system/juce_TargetPlatform.h> //============================================================================== -#if JucePlugin_Build_VST3 && (__APPLE_CPP__ || __APPLE_CC__ || _WIN32 || _WIN64) +#if JucePlugin_Build_VST3 && (JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX) + +#if JUCE_PLUGINHOST_VST3 + #if JUCE_MAC + #include <CoreFoundation/CoreFoundation.h> + #endif -#if JUCE_PLUGINHOST_VST3 && (JUCE_MAC || JUCE_WINDOWS) #undef JUCE_VST3HEADERS_INCLUDE_HEADERS_ONLY #define JUCE_VST3HEADERS_INCLUDE_HEADERS_ONLY 1 #endif -#include "../../juce_audio_processors/format_types/juce_VST3Headers.h" +#include <juce_audio_processors/format_types/juce_VST3Headers.h> #undef JUCE_VST3HEADERS_INCLUDE_HEADERS_ONLY +#define JUCE_GUI_BASICS_INCLUDE_XHEADERS 1 #include "../utility/juce_CheckSettingMacros.h" +#include "../utility/juce_IncludeSystemHeaders.h" #include "../utility/juce_IncludeModuleHeaders.h" #include "../utility/juce_WindowsHooks.h" #include "../utility/juce_FakeMouseMoveGenerator.h" -#include "../../juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp" -#include "../../juce_audio_processors/format_types/juce_VST3Common.h" +#include <juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp> +#include <juce_audio_processors/format_types/juce_VST3Common.h> #ifndef JUCE_VST3_CAN_REPLACE_VST2 #define JUCE_VST3_CAN_REPLACE_VST2 1 #endif #if JUCE_VST3_CAN_REPLACE_VST2 -namespace Vst2 -{ -#include "pluginterfaces/vst2.x/vstfxstore.h" -} + + #if ! JUCE_MSVC + #define __cdecl + #endif + + namespace Vst2 + { + #include "pluginterfaces/vst2.x/vstfxstore.h" + } + #endif #ifndef JUCE_VST3_EMULATE_MIDI_CC_WITH_PARAMETERS @@ -62,15 +74,10 @@ namespace Vst2 #endif #endif -#if JUCE_VST3_CAN_REPLACE_VST2 - #if JUCE_MSVC - #pragma warning (push) - #pragma warning (disable: 4514 4996) - #endif +#if JUCE_LINUX + #include <unordered_map> - #if JUCE_MSVC - #pragma warning (pop) - #endif + std::vector<std::pair<int, std::function<void (int)>>> getFdReadCallbacks(); #endif namespace juce @@ -80,14 +87,18 @@ using namespace Steinberg; //============================================================================== #if JUCE_MAC - extern void initialiseMacVST(); + extern void initialiseMacVST(); #if ! JUCE_64BIT extern void updateEditorCompBoundsVST (Component*); #endif - extern JUCE_API void* attachComponentToWindowRefVST (Component*, void* parentWindowOrView, bool isNSView); - extern JUCE_API void detachComponentFromWindowRefVST (Component*, void* nsWindow, bool isNSView); + extern JUCE_API void* attachComponentToWindowRefVST (Component*, void* parentWindowOrView, bool isNSView); + extern JUCE_API void detachComponentFromWindowRefVST (Component*, void* nsWindow, bool isNSView); +#endif + +#if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE + extern JUCE_API double getScaleFactorForWindow (HWND); #endif //============================================================================== @@ -355,16 +366,11 @@ public: static const FUID iid; //============================================================================== - #if JUCE_CLANG - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Winconsistent-missing-override" - #endif + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Winconsistent-missing-override") REFCOUNT_METHODS (ComponentBase) - #if JUCE_CLANG - #pragma clang diagnostic pop - #endif + JUCE_END_IGNORE_WARNINGS_GCC_LIKE tresult PLUGIN_API queryInterface (const TUID targetIID, void** obj) override { @@ -445,7 +451,7 @@ public: jassert (info.defaultNormalizedValue >= 0 && info.defaultNormalizedValue <= 1.0f); // Is this a meter? - if (((param.getCategory() & 0xffff0000) >> 16) == 2) + if ((((unsigned int) param.getCategory() & 0xffff0000) >> 16) == 2) info.flags = Vst::ParameterInfo::kIsReadOnly; else info.flags = param.isAutomatable() ? Vst::ParameterInfo::kCanAutomate : 0; @@ -458,11 +464,22 @@ public: virtual ~Param() override = default; - void updateParameterInfo() + bool updateParameterInfo() { - toString128 (info.title, param.getName (128)); - toString128 (info.shortTitle, param.getName (8)); - toString128 (info.units, param.getLabel()); + auto updateParamIfChanged = [] (Vst::String128& paramToUpdate, const String& newValue) + { + if (juce::toString (paramToUpdate) == newValue) + return false; + + toString128 (paramToUpdate, newValue); + return true; + }; + + auto anyUpdated = updateParamIfChanged (info.title, param.getName (128)); + anyUpdated |= updateParamIfChanged (info.shortTitle, param.getName (8)); + anyUpdated |= updateParamIfChanged (info.units, param.getLabel()); + + return anyUpdated; } bool setNormalized (Vst::ParamValue v) override @@ -892,21 +909,42 @@ public: void audioProcessorChanged (AudioProcessor*) override { - auto numParameters = parameters.getParameterCount(); + int32 flags = 0; - for (int32 i = 0; i < numParameters; ++i) + for (int32 i = 0; i < parameters.getParameterCount(); ++i) if (auto* param = dynamic_cast<Param*> (parameters.getParameterByIndex (i))) - param->updateParameterInfo(); + if (param->updateParameterInfo() && (flags & Vst::kParamTitlesChanged) == 0) + flags |= Vst::kParamTitlesChanged; if (auto* pluginInstance = getPluginInstance()) { - if (pluginInstance->getNumPrograms() > 1) - EditController::setParamNormalized (JuceAudioProcessor::paramPreset, static_cast<Vst::ParamValue> (pluginInstance->getCurrentProgram()) - / static_cast<Vst::ParamValue> (pluginInstance->getNumPrograms() - 1)); + auto newNumPrograms = pluginInstance->getNumPrograms(); + + if (newNumPrograms != lastNumPrograms) + { + if (newNumPrograms > 1) + { + auto paramValue = static_cast<Vst::ParamValue> (pluginInstance->getCurrentProgram()) + / static_cast<Vst::ParamValue> (pluginInstance->getNumPrograms() - 1); + + EditController::setParamNormalized (JuceAudioProcessor::paramPreset, paramValue); + flags |= Vst::kParamValuesChanged; + } + + lastNumPrograms = newNumPrograms; + } + + auto newLatencySamples = pluginInstance->getLatencySamples(); + + if (newLatencySamples != lastLatencySamples) + { + flags |= Vst::kLatencyChanged; + lastLatencySamples = newLatencySamples; + } } - if (componentHandler != nullptr && ! inSetupProcessing) - componentHandler->restartComponent (Vst::kLatencyChanged | Vst::kParamValuesChanged | Vst::kParamTitlesChanged); + if (flags != 0 && componentHandler != nullptr && ! inSetupProcessing) + componentHandler->restartComponent (flags); } void parameterValueChanged (int, float newValue) override @@ -952,7 +990,11 @@ private: std::atomic<bool> vst3IsPlaying { false }, inSetupProcessing { false }; + int lastNumPrograms = 0, lastLatencySamples = 0; + + #if ! JUCE_MAC float lastScaleFactorReceived = 1.0f; + #endif void setupParameters() { @@ -1028,6 +1070,9 @@ private: //============================================================================== class JuceVST3Editor : public Vst::EditorView, public Steinberg::IPlugViewContentScaleSupport, + #if JUCE_LINUX + public Steinberg::Linux::IEventHandler, + #endif private Timer { public: @@ -1035,13 +1080,14 @@ private: : Vst::EditorView (&ec, nullptr), owner (&ec), pluginInstance (p) { - editorScaleFactor = ec.lastScaleFactorReceived; - - component.reset (new ContentWrapperComponent (*this, p)); + createContentWrapperComponentIfNeeded(); #if JUCE_MAC if (getHostType().type == PluginHostType::SteinbergCubase10) cubase10Workaround.reset (new Cubase10WindowResizeWorkaround (*this)); + #else + if (! approximatelyEqual (editorScaleFactor, ec.lastScaleFactorReceived)) + setContentScaleFactor (ec.lastScaleFactorReceived); #endif } @@ -1053,6 +1099,20 @@ private: REFCOUNT_METHODS (Vst::EditorView) + //============================================================================== + #if JUCE_LINUX + void PLUGIN_API onFDIsSet (Steinberg::Linux::FileDescriptor fd) override + { + if (plugFrame != nullptr) + { + auto it = fdCallbackMap.find (fd); + + if (it != fdCallbackMap.end()) + it->second (fd); + } + } + #endif + //============================================================================== tresult PLUGIN_API isPlatformTypeSupported (FIDString type) override { @@ -1060,8 +1120,10 @@ private: { #if JUCE_WINDOWS if (strcmp (type, kPlatformTypeHWND) == 0) - #else + #elif JUCE_MAC if (strcmp (type, kPlatformTypeNSView) == 0 || strcmp (type, kPlatformTypeHIView) == 0) + #elif JUCE_LINUX + if (strcmp (type, kPlatformTypeX11EmbedWindowID) == 0) #endif return kResultTrue; } @@ -1074,27 +1136,37 @@ private: if (parent == nullptr || isPlatformTypeSupported (type) == kResultFalse) return kResultFalse; - if (component == nullptr) - component.reset (new ContentWrapperComponent (*this, pluginInstance)); + systemWindow = parent; + + createContentWrapperComponentIfNeeded(); - #if JUCE_WINDOWS + #if JUCE_WINDOWS || JUCE_LINUX component->addToDesktop (0, parent); component->setOpaque (true); component->setVisible (true); - #if JUCE_WIN_PER_MONITOR_DPI_AWARE - component->checkScaleFactorIsCorrect(); + + #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE + component->checkHostWindowScaleFactor(); + component->startTimer (500); + #endif + + #if JUCE_LINUX + if (auto* runLoop = getHostRunLoop()) + { + for (auto& cb : getFdReadCallbacks()) + { + fdCallbackMap[cb.first] = cb.second; + runLoop->registerEventHandler (this, cb.first); + } + } #endif + #else isNSView = (strcmp (type, kPlatformTypeNSView) == 0); macHostWindow = juce::attachComponentToWindowRefVST (component.get(), parent, isNSView); #endif - #if ! JUCE_MAC - setContentScaleFactor ((Steinberg::IPlugViewContentScaleSupport::ScaleFactor) editorScaleFactor); - #endif - component->resizeHostWindow(); - systemWindow = parent; attachedToParent(); // Life's too short to faff around with wave lab @@ -1110,6 +1182,11 @@ private: { #if JUCE_WINDOWS component->removeFromDesktop(); + #elif JUCE_LINUX + fdCallbackMap.clear(); + + if (auto* runLoop = getHostRunLoop()) + runLoop->unregisterEventHandler (this); #else if (macHostWindow != nullptr) { @@ -1128,45 +1205,26 @@ private: { if (newSize != nullptr) { - rect = *newSize; + rect = convertFromHostBounds (*newSize); if (component != nullptr) { auto w = rect.getWidth(); auto h = rect.getHeight(); - #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE - w = roundToInt (w / editorScaleFactor); - h = roundToInt (h / editorScaleFactor); - - if (getHostType().type == PluginHostType::SteinbergCubase10) - { - auto integerScaleFactor = (int) std::round (editorScaleFactor); - - // Workaround for Cubase 10 sending double-scaled bounds when opening editor - if (isWithin ((int) w, component->getWidth() * integerScaleFactor, 2) - && isWithin ((int) h, component->getHeight() * integerScaleFactor, 2)) - { - w /= integerScaleFactor; - h /= integerScaleFactor; - } - } - #endif - component->setSize (w, h); #if JUCE_MAC if (cubase10Workaround != nullptr) + { cubase10Workaround->triggerAsyncUpdate(); + } else #endif - if (auto* peer = component->getPeer()) - peer->updateBounds(); - - #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE - if (getHostType().type == PluginHostType::SteinbergCubase10) - component->resizeHostWindow(); - #endif + { + if (auto* peer = component->getPeer()) + peer->updateBounds(); + } } return kResultTrue; @@ -1180,16 +1238,9 @@ private: { if (size != nullptr && component != nullptr) { - auto w = component->getWidth(); - auto h = component->getHeight(); - - #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE - w = roundToInt (w * editorScaleFactor); - h = roundToInt (h * editorScaleFactor); - #endif - - *size = ViewRect (0, 0, w, h); + auto editorBounds = component->getSizeToContainChild(); + *size = convertToHostBounds ({ 0, 0, editorBounds.getWidth(), editorBounds.getHeight() }); return kResultTrue; } @@ -1200,7 +1251,8 @@ private: { if (component != nullptr) if (auto* editor = component->pluginEditor.get()) - return editor->isResizable() ? kResultTrue : kResultFalse; + if (editor->isResizable()) + return kResultTrue; return kResultFalse; } @@ -1213,21 +1265,18 @@ private: { if (auto* constrainer = editor->getConstrainer()) { - auto scale = editor->getTransform().getScaleFactor(); + *rectToCheck = convertFromHostBounds (*rectToCheck); - 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 transformScale = std::sqrt (std::abs (editor->getTransform().getDeterminant())); + + auto minW = (double) ((float) constrainer->getMinimumWidth() * transformScale); + auto maxW = (double) ((float) constrainer->getMaximumWidth() * transformScale); + auto minH = (double) ((float) constrainer->getMinimumHeight() * transformScale); + auto maxH = (double) ((float) constrainer->getMaximumHeight() * transformScale); auto width = (double) (rectToCheck->right - rectToCheck->left); auto height = (double) (rectToCheck->bottom - rectToCheck->top); - #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE - width /= editorScaleFactor; - height /= editorScaleFactor; - #endif - width = jlimit (minW, maxW, width); height = jlimit (minH, maxH, height); @@ -1267,13 +1316,10 @@ private: } } - #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE - width *= editorScaleFactor; - height *= editorScaleFactor; - #endif - rectToCheck->right = rectToCheck->left + roundToInt (width); rectToCheck->bottom = rectToCheck->top + roundToInt (height); + + *rectToCheck = convertToHostBounds (*rectToCheck); } } @@ -1287,33 +1333,35 @@ private: tresult PLUGIN_API setContentScaleFactor (Steinberg::IPlugViewContentScaleSupport::ScaleFactor factor) override { #if ! JUCE_MAC - auto hostType = getHostType().type; - - if (hostType == PluginHostType::SteinbergCubase10 || hostType == PluginHostType::FruityLoops) - { - if (component.get() != nullptr) - if (auto* peer = component->getPeer()) - factor = static_cast<Steinberg::IPlugViewContentScaleSupport::ScaleFactor> (peer->getPlatformScaleFactor()); - } - if (! approximatelyEqual ((float) factor, editorScaleFactor)) { - editorScaleFactor = (float) factor; + #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE + // Cubase 10 only sends integer scale factors, so correct this for fractional scales + if (getHostType().type == PluginHostType::SteinbergCubase10) + { + auto hostWindowScale = (Steinberg::IPlugViewContentScaleSupport::ScaleFactor) getScaleFactorForWindow ((HWND) systemWindow); - if (auto* o = owner.get()) - o->lastScaleFactorReceived = editorScaleFactor; + if (hostWindowScale > 0.0 && ! approximatelyEqual (factor, hostWindowScale)) + factor = hostWindowScale; + } + #endif - if (component == nullptr) - return kResultFalse; + editorScaleFactor = (float) factor; - #if JUCE_WINDOWS && ! JUCE_WIN_PER_MONITOR_DPI_AWARE - if (auto* ed = component->pluginEditor.get()) - ed->setScaleFactor ((float) factor); - #endif + if (owner != nullptr) + owner->lastScaleFactorReceived = editorScaleFactor; - component->resizeHostWindow(); - component->setTopLeftPosition (0, 0); - component->repaint(); + if (component != nullptr) + { + if (auto* editor = component->pluginEditor.get()) + { + editor->setScaleFactor (editorScaleFactor); + + component->resizeHostWindow(); + component->setTopLeftPosition (0, 0); + component->repaint(); + } + } } return kResultTrue; @@ -1333,41 +1381,77 @@ private: onSize (&viewRect); } + static ViewRect convertToHostBounds (ViewRect pluginRect) + { + auto desktopScale = Desktop::getInstance().getGlobalScaleFactor(); + + if (approximatelyEqual (desktopScale, 1.0f)) + return pluginRect; + + return { roundToInt ((float) pluginRect.left * desktopScale), + roundToInt ((float) pluginRect.top * desktopScale), + roundToInt ((float) pluginRect.right * desktopScale), + roundToInt ((float) pluginRect.bottom * desktopScale) }; + } + + static ViewRect convertFromHostBounds (ViewRect hostRect) + { + auto desktopScale = Desktop::getInstance().getGlobalScaleFactor(); + + if (approximatelyEqual (desktopScale, 1.0f)) + return hostRect; + + return { roundToInt ((float) hostRect.left / desktopScale), + roundToInt ((float) hostRect.top / desktopScale), + roundToInt ((float) hostRect.right / desktopScale), + roundToInt ((float) hostRect.bottom / desktopScale) }; + } + //============================================================================== struct ContentWrapperComponent : public Component + #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE + , public Timer + #endif { - ContentWrapperComponent (JuceVST3Editor& editor, AudioProcessor& plugin) - : pluginEditor (plugin.createEditorIfNeeded()), - owner (editor) + ContentWrapperComponent (JuceVST3Editor& editor) : owner (editor) { setOpaque (true); setBroughtToFrontOnMouseClick (true); - // if hasEditor() returns true then createEditorIfNeeded has to return a valid editor - jassert (pluginEditor != nullptr); + ignoreUnused (fakeMouseGenerator); + } + ~ContentWrapperComponent() override + { if (pluginEditor != nullptr) { - addAndMakeVisible (pluginEditor.get()); + PopupMenu::dismissAllActiveMenus(); + pluginEditor->processor.editorBeingDeleted (pluginEditor.get()); + } + } + + void createEditor (AudioProcessor& plugin) + { + pluginEditor.reset (plugin.createEditorIfNeeded()); + if (pluginEditor != nullptr) + { + addAndMakeVisible (pluginEditor.get()); pluginEditor->setTopLeftPosition (0, 0); + lastBounds = getSizeToContainChild(); - isResizingParentToFitChild = true; - setBounds (lastBounds); - isResizingParentToFitChild = false; + + { + const ScopedValueSetter<bool> resizingParentSetter (resizingParent, true); + setBounds (lastBounds); + } resizeHostWindow(); } - - ignoreUnused (fakeMouseGenerator); - } - - ~ContentWrapperComponent() override - { - if (pluginEditor != nullptr) + else { - PopupMenu::dismissAllActiveMenus(); - pluginEditor->processor.editorBeingDeleted (pluginEditor.get()); + // if hasEditor() returns true then createEditorIfNeeded has to return a valid editor + jassertfalse; } } @@ -1386,7 +1470,7 @@ private: void childBoundsChanged (Component*) override { - if (isResizingChildToFitParent) + if (resizingChild) return; auto b = getSizeToContainChild(); @@ -1394,46 +1478,38 @@ private: if (lastBounds != b) { lastBounds = b; - isResizingParentToFitChild = true; - resizeHostWindow(); - isResizingParentToFitChild = false; - } - } - #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE - void checkScaleFactorIsCorrect() - { - if (auto* peer = pluginEditor->getPeer()) - { - auto peerScaleFactor = (float) peer->getPlatformScaleFactor(); - - if (! approximatelyEqual (peerScaleFactor, owner.editorScaleFactor)) - owner.setContentScaleFactor (peerScaleFactor); + const ScopedValueSetter<bool> resizingParentSetter (resizingParent, true); + resizeHostWindow(); } } - #endif void resized() override { if (pluginEditor != nullptr) { - #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE - checkScaleFactorIsCorrect(); - #endif - - if (! isResizingParentToFitChild) + if (! resizingParent) { - lastBounds = getLocalBounds(); - isResizingChildToFitParent = true; + auto newBounds = getLocalBounds(); + + #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE + if (! lastBounds.isEmpty() && isWithin (newBounds.toDouble().getAspectRatio(), lastBounds.toDouble().getAspectRatio(), 0.1)) + return; + #endif + + lastBounds = newBounds; + + const ScopedValueSetter<bool> resizingChildSetter (resizingChild, true); if (auto* constrainer = pluginEditor->getConstrainer()) { auto aspectRatio = constrainer->getFixedAspectRatio(); - auto width = (double) lastBounds.getWidth(); - auto height = (double) lastBounds.getHeight(); if (aspectRatio != 0) { + auto width = (double) lastBounds.getWidth(); + auto height = (double) lastBounds.getHeight(); + if (width / height > aspectRatio) setBounds ({ 0, 0, roundToInt (height * aspectRatio), lastBounds.getHeight() }); else @@ -1443,11 +1519,19 @@ private: pluginEditor->setTopLeftPosition (0, 0); pluginEditor->setBounds (pluginEditor->getLocalArea (this, getLocalBounds())); - isResizingChildToFitParent = false; } } } + void parentSizeChanged() override + { + if (pluginEditor != nullptr) + { + resizeHostWindow(); + pluginEditor->repaint(); + } + } + void resizeHostWindow() { if (pluginEditor != nullptr) @@ -1463,41 +1547,61 @@ private: if (owner.plugFrame != nullptr) { - #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE - w = roundToInt (w * owner.editorScaleFactor); - h = roundToInt (h * owner.editorScaleFactor); - #endif - - ViewRect newSize (0, 0, w, h); + auto newSize = convertToHostBounds ({ 0, 0, b.getWidth(), b.getHeight() }); { - const ScopedValueSetter<bool> resizingParentSetter (isResizingParentToFitChild, true); + const ScopedValueSetter<bool> resizingParentSetter (resizingParent, true); owner.plugFrame->resizeView (&owner, &newSize); } #if JUCE_MAC if (host.isWavelab() || host.isReaper()) #else - if (host.isWavelab() || host.isAbletonLive()) + if (host.isWavelab() || host.isAbletonLive() || host.isBitwigStudio()) #endif setBounds (0, 0, w, h); } } } + #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE + void checkHostWindowScaleFactor() + { + auto hostWindowScale = (float) getScaleFactorForWindow ((HWND) owner.systemWindow); + + if (hostWindowScale > 0.0 && ! approximatelyEqual (hostWindowScale, owner.editorScaleFactor)) + owner.setContentScaleFactor (hostWindowScale); + } + + void timerCallback() override + { + checkHostWindowScaleFactor(); + } + #endif + std::unique_ptr<AudioProcessorEditor> pluginEditor; private: JuceVST3Editor& owner; FakeMouseMoveGenerator fakeMouseGenerator; Rectangle<int> lastBounds; - bool isResizingChildToFitParent = false; - bool isResizingParentToFitChild = false; + bool resizingChild = false, resizingParent = false; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ContentWrapperComponent) }; + void createContentWrapperComponentIfNeeded() + { + if (component == nullptr) + { + component.reset (new ContentWrapperComponent (*this)); + component->createEditor (pluginInstance); + } + } + //============================================================================== + ScopedJuceInitialiser_GUI libraryInitialiser; + ComSmartPtr<JuceVST3EditController> owner; AudioProcessor& pluginInstance; @@ -1525,12 +1629,27 @@ private: }; std::unique_ptr<Cubase10WindowResizeWorkaround> cubase10Workaround; - #endif - + #else float editorScaleFactor = 1.0f; - #if JUCE_WINDOWS - WindowsHooks hooks; + #if JUCE_WINDOWS + WindowsHooks hooks; + #elif JUCE_LINUX + std::unordered_map<int, std::function<void (int)>> fdCallbackMap; + + ::Display* display = XWindowSystem::getInstance()->getDisplay(); + + Steinberg::Linux::IRunLoop* getHostRunLoop() + { + Steinberg::Linux::IRunLoop* runLoop = nullptr; + + if (plugFrame != nullptr) + plugFrame->queryInterface (Steinberg::Linux::IRunLoop::iid, (void**) &runLoop); + + return runLoop; + } + #endif + #endif //============================================================================== @@ -1543,12 +1662,12 @@ private: namespace { template <typename FloatType> struct AudioBusPointerHelper {}; - template <> struct AudioBusPointerHelper<float> { static inline float** impl (Vst::AudioBusBuffers& data) noexcept { return data.channelBuffers32; } }; - template <> struct AudioBusPointerHelper<double> { static inline double** impl (Vst::AudioBusBuffers& data) noexcept { return data.channelBuffers64; } }; + template <> struct AudioBusPointerHelper<float> { static float** impl (Vst::AudioBusBuffers& data) noexcept { return data.channelBuffers32; } }; + template <> struct AudioBusPointerHelper<double> { static double** impl (Vst::AudioBusBuffers& data) noexcept { return data.channelBuffers64; } }; template <typename FloatType> struct ChooseBufferHelper {}; - template <> struct ChooseBufferHelper<float> { static inline AudioBuffer<float>& impl (AudioBuffer<float>& f, AudioBuffer<double>& ) noexcept { return f; } }; - template <> struct ChooseBufferHelper<double> { static inline AudioBuffer<double>& impl (AudioBuffer<float>& , AudioBuffer<double>& d) noexcept { return d; } }; + template <> struct ChooseBufferHelper<float> { static AudioBuffer<float>& impl (AudioBuffer<float>& f, AudioBuffer<double>& ) noexcept { return f; } }; + template <> struct ChooseBufferHelper<double> { static AudioBuffer<double>& impl (AudioBuffer<float>& , AudioBuffer<double>& d) noexcept { return d; } }; } @@ -1799,7 +1918,7 @@ public: void setStateInformation (const void* data, int sizeAsInt) { - int64 size = sizeAsInt; + auto size = (uint64) sizeAsInt; // Check if this data was written with a newer JUCE version // and if it has the JUCE private data magic code at the end @@ -1831,7 +1950,7 @@ public: } } - if (size >= 0) + if (size > 0) pluginInstance->setStateInformation (data, static_cast<int> (size)); } @@ -1839,25 +1958,25 @@ public: #if JUCE_VST3_CAN_REPLACE_VST2 bool loadVST2VstWBlock (const char* data, int size) { - jassert ('VstW' == htonl (*(juce::int32*) data)); - jassert (1 == htonl (*(juce::int32*) (data + 8))); // version should be 1 according to Steinberg's docs + jassert (ByteOrder::bigEndianInt ("VstW") == htonl ((uint32) readUnaligned<int32> (data))); + jassert (1 == htonl ((uint32) readUnaligned<int32> (data + 8))); // version should be 1 according to Steinberg's docs - auto headerLen = (int) htonl (*(juce::int32*) (data + 4)) + 8; + auto headerLen = (int) htonl ((uint32) readUnaligned<int32> (data + 4)) + 8; return loadVST2CcnKBlock (data + headerLen, size - headerLen); } bool loadVST2CcnKBlock (const char* data, int size) { - auto bank = (const Vst2::fxBank*) data; + auto* bank = reinterpret_cast<const Vst2::fxBank*> (data); - jassert ('CcnK' == htonl (bank->chunkMagic)); - jassert ('FBCh' == htonl (bank->fxMagic)); - jassert (htonl (bank->version) == 1 || htonl (bank->version) == 2); - jassert (JucePlugin_VSTUniqueID == htonl (bank->fxID)); + jassert (ByteOrder::bigEndianInt ("CcnK") == htonl ((uint32) bank->chunkMagic)); + jassert (ByteOrder::bigEndianInt ("FBCh") == htonl ((uint32) bank->fxMagic)); + jassert (htonl ((uint32) bank->version) == 1 || htonl ((uint32) bank->version) == 2); + jassert (JucePlugin_VSTUniqueID == htonl ((uint32) bank->fxID)); setStateInformation (bank->content.data.chunk, jmin ((int) (size - (bank->content.data.chunk - data)), - (int) htonl (bank->content.data.size))); + (int) htonl ((uint32) bank->content.data.size))); return true; } @@ -1886,7 +2005,7 @@ public: auto chunkOffset = ByteOrder::littleEndianInt64 (data + entryOffset + 4); auto chunkSize = ByteOrder::littleEndianInt64 (data + entryOffset + 12); - if (chunkOffset + chunkSize > static_cast<juce::uint64> (size)) + if (static_cast<uint64> (chunkOffset + chunkSize) > static_cast<uint64> (size)) { jassertfalse; return false; @@ -1904,12 +2023,12 @@ public: if (size < 4) return false; - auto header = htonl (*(juce::int32*) data); + auto header = htonl ((uint32) readUnaligned<int32> (data)); - if (header == 'VstW') + if (header == ByteOrder::bigEndianInt ("VstW")) return loadVST2VstWBlock (data, size); - if (header == 'CcnK') + if (header == ByteOrder::bigEndianInt ("CcnK")) return loadVST2CcnKBlock (data, size); if (memcmp (data, "VST3", 4) == 0) @@ -2020,19 +2139,19 @@ public: } #if JUCE_VST3_CAN_REPLACE_VST2 - static tresult writeVST2Int (IBStream* state, int n) - { - juce::int32 t = (juce::int32) htonl (n); - return state->write (&t, 4); - } - static tresult writeVST2Header (IBStream* state, bool bypassed) { - tresult status = writeVST2Int (state, 'VstW'); + auto writeVST2IntToState = [state] (uint32 n) + { + auto t = (int32) htonl (n); + return state->write (&t, 4); + }; + + auto status = writeVST2IntToState (ByteOrder::bigEndianInt ("VstW")); - if (status == kResultOk) status = writeVST2Int (state, 8); // header size - if (status == kResultOk) status = writeVST2Int (state, 1); // version - if (status == kResultOk) status = writeVST2Int (state, bypassed ? 1 : 0); // bypass + if (status == kResultOk) status = writeVST2IntToState (8); // header size + if (status == kResultOk) status = writeVST2IntToState (1); // version + if (status == kResultOk) status = writeVST2IntToState (bypassed ? 1 : 0); // bypass return status; } @@ -2043,7 +2162,7 @@ public: if (state == nullptr) return kInvalidArgument; - juce::MemoryBlock mem; + MemoryBlock mem; getStateInformation (mem); #if JUCE_VST3_CAN_REPLACE_VST2 @@ -2056,9 +2175,9 @@ public: Vst2::fxBank bank; zerostruct (bank); - bank.chunkMagic = (int32) htonl ('CcnK'); + bank.chunkMagic = (int32) htonl (ByteOrder::bigEndianInt ("CcnK")); bank.byteSize = (int32) htonl (bankBlockSize - 8 + (unsigned int) mem.getSize()); - bank.fxMagic = (int32) htonl ('FBCh'); + bank.fxMagic = (int32) htonl (ByteOrder::bigEndianInt ("FBCh")); bank.version = (int32) htonl (2); bank.fxID = (int32) htonl (JucePlugin_VSTUniqueID); bank.fxVersion = (int32) htonl (JucePlugin_VersionCode); @@ -2169,11 +2288,15 @@ public: if (type == Vst::kEvent) { + #if JucePlugin_WantsMidiInput if (dir == Vst::kInput) - return isMidiInputBusEnabled ? 1 : 0; + return 1; + #endif + #if JucePlugin_ProducesMidiOutput if (dir == Vst::kOutput) - return isMidiOutputBusEnabled ? 1 : 0; + return 1; + #endif } return 0; @@ -2254,15 +2377,23 @@ public: { if (type == Vst::kEvent) { - if (index != 0) - return kResultFalse; - - if (dir == Vst::kInput) + #if JucePlugin_WantsMidiInput + if (index == 0 && dir == Vst::kInput) + { isMidiInputBusEnabled = (state != 0); - else + return kResultTrue; + } + #endif + + #if JucePlugin_ProducesMidiOutput + if (index == 0 && dir == Vst::kOutput) + { isMidiOutputBusEnabled = (state != 0); + return kResultTrue; + } + #endif - return kResultTrue; + return kResultFalse; } if (type == Vst::kAudio) @@ -2506,7 +2637,7 @@ public: processParameterChanges (*data.inputParameterChanges); #if JucePlugin_WantsMidiInput - if (data.inputEvents != nullptr) + if (isMidiInputBusEnabled && data.inputEvents != nullptr) MidiEventList::toMidiBuffer (midiBuffer, *data.inputEvents); #endif @@ -2525,8 +2656,8 @@ public: else jassertfalse; #if JucePlugin_ProducesMidiOutput - if (data.outputEvents != nullptr) - MidiEventList::toEventList (*data.outputEvents, midiBuffer); + if (isMidiOutputBusEnabled && data.outputEvents != nullptr) + MidiEventList::pluginToHostEventList (*data.outputEvents, midiBuffer); #endif return kResultTrue; @@ -2564,17 +2695,16 @@ private: auto plugInOutputChannels = pluginInstance->getTotalNumOutputChannels(); // Wavelab workaround: wave-lab lies on the number of inputs/outputs so re-count here - int vstInputs; - for (vstInputs = 0; vstInputs < data.numInputs; ++vstInputs) - if (getPointerForAudioBus<FloatType> (data.inputs[vstInputs]) == nullptr - && data.inputs[vstInputs].numChannels > 0) - break; + const auto countValidChannels = [] (Vst::AudioBusBuffers* buffers, int32 num) + { + return int (std::distance (buffers, std::find_if (buffers, buffers + num, [] (Vst::AudioBusBuffers& buf) + { + return getPointerForAudioBus<FloatType> (buf) == nullptr && buf.numChannels > 0; + }))); + }; - int vstOutputs; - for (vstOutputs = 0; vstOutputs < data.numOutputs; ++vstOutputs) - if (getPointerForAudioBus<FloatType> (data.outputs[vstOutputs]) == nullptr - && data.outputs[vstOutputs].numChannels > 0) - break; + const auto vstInputs = countValidChannels (data.inputs, data.numInputs); + const auto vstOutputs = countValidChannels (data.outputs, data.numOutputs); { auto n = jmax (vstOutputs, getNumAudioBuses (false)); @@ -2803,15 +2933,10 @@ private: AudioBuffer<double> emptyBufferDouble; #if JucePlugin_WantsMidiInput - bool isMidiInputBusEnabled = true; - #else - bool isMidiInputBusEnabled = false; + std::atomic<bool> isMidiInputBusEnabled { true }; #endif - #if JucePlugin_ProducesMidiOutput - bool isMidiOutputBusEnabled = true; - #else - bool isMidiOutputBusEnabled = false; + std::atomic<bool> isMidiOutputBusEnabled { true }; #endif static const char* kJucePrivateDataIdentifier; @@ -2822,13 +2947,8 @@ private: const char* JuceVST3Component::kJucePrivateDataIdentifier = "JUCEPrivateData"; //============================================================================== -#if JUCE_MSVC - #pragma warning (push, 0) - #pragma warning (disable: 4310) -#elif JUCE_CLANG - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wall" -#endif +JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4310) +JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wall") DECLARE_CLASS_IID (JuceAudioProcessor, 0x0101ABAB, 0xABCDEF01, JucePlugin_ManufacturerCode, JucePlugin_PluginCode) DEF_CLASS_IID (JuceAudioProcessor) @@ -2851,13 +2971,11 @@ DEF_CLASS_IID (JuceAudioProcessor) DEF_CLASS_IID (JuceVST3Component) #endif -#if JUCE_MSVC - #pragma warning (pop) -#elif JUCE_CLANG - #pragma clang diagnostic pop -#endif +JUCE_END_IGNORE_WARNINGS_MSVC +JUCE_END_IGNORE_WARNINGS_GCC_LIKE //============================================================================== +bool initModule(); bool initModule() { #if JUCE_MAC @@ -2867,6 +2985,7 @@ bool initModule() return true; } +bool shutdownModule(); bool shutdownModule() { return true; @@ -2875,61 +2994,92 @@ bool shutdownModule() #undef JUCE_EXPORTED_FUNCTION #if JUCE_WINDOWS - extern "C" __declspec (dllexport) bool InitDll() { return initModule(); } - extern "C" __declspec (dllexport) bool ExitDll() { return shutdownModule(); } - #define JUCE_EXPORTED_FUNCTION - + #define JUCE_EXPORTED_FUNCTION #else - #define JUCE_EXPORTED_FUNCTION extern "C" __attribute__ ((visibility ("default"))) + #define JUCE_EXPORTED_FUNCTION extern "C" __attribute__ ((visibility("default"))) +#endif - CFBundleRef globalBundleInstance = nullptr; - juce::uint32 numBundleRefs = 0; - juce::Array<CFBundleRef> bundleRefs; +#if JUCE_WINDOWS + extern "C" __declspec (dllexport) bool InitDll() { return initModule(); } + extern "C" __declspec (dllexport) bool ExitDll() { return shutdownModule(); } +#elif JUCE_LINUX + void* moduleHandle = nullptr; + int moduleEntryCounter = 0; + + JUCE_EXPORTED_FUNCTION bool ModuleEntry (void* sharedLibraryHandle); + JUCE_EXPORTED_FUNCTION bool ModuleEntry (void* sharedLibraryHandle) + { + if (++moduleEntryCounter == 1) + { + moduleHandle = sharedLibraryHandle; + return initModule(); + } - enum { MaxPathLength = 2048 }; - char modulePath[MaxPathLength] = { 0 }; - void* moduleHandle = nullptr; + return true; + } - JUCE_EXPORTED_FUNCTION bool bundleEntry (CFBundleRef ref) - { - if (ref != nullptr) - { - ++numBundleRefs; - CFRetain (ref); + JUCE_EXPORTED_FUNCTION bool ModuleExit(); + JUCE_EXPORTED_FUNCTION bool ModuleExit() + { + if (--moduleEntryCounter == 0) + { + moduleHandle = nullptr; + return shutdownModule(); + } - bundleRefs.add (ref); + return true; + } +#elif JUCE_MAC + CFBundleRef globalBundleInstance = nullptr; + juce::uint32 numBundleRefs = 0; + juce::Array<CFBundleRef> bundleRefs; - if (moduleHandle == nullptr) - { - globalBundleInstance = ref; - moduleHandle = ref; + enum { MaxPathLength = 2048 }; + char modulePath[MaxPathLength] = { 0 }; + void* moduleHandle = nullptr; - CFURLRef tempURL = CFBundleCopyBundleURL (ref); - CFURLGetFileSystemRepresentation (tempURL, true, (UInt8*) modulePath, MaxPathLength); - CFRelease (tempURL); - } - } + JUCE_EXPORTED_FUNCTION bool bundleEntry (CFBundleRef ref); + JUCE_EXPORTED_FUNCTION bool bundleEntry (CFBundleRef ref) + { + if (ref != nullptr) + { + ++numBundleRefs; + CFRetain (ref); - return initModule(); - } + bundleRefs.add (ref); - JUCE_EXPORTED_FUNCTION bool bundleExit() - { - if (shutdownModule()) - { - if (--numBundleRefs == 0) - { - for (int i = 0; i < bundleRefs.size(); ++i) - CFRelease (bundleRefs.getUnchecked (i)); + if (moduleHandle == nullptr) + { + globalBundleInstance = ref; + moduleHandle = ref; - bundleRefs.clear(); - } + CFURLRef tempURL = CFBundleCopyBundleURL (ref); + CFURLGetFileSystemRepresentation (tempURL, true, (UInt8*) modulePath, MaxPathLength); + CFRelease (tempURL); + } + } - return true; - } + return initModule(); + } - return false; - } + JUCE_EXPORTED_FUNCTION bool bundleExit(); + JUCE_EXPORTED_FUNCTION bool bundleExit() + { + if (shutdownModule()) + { + if (--numBundleRefs == 0) + { + for (int i = 0; i < bundleRefs.size(); ++i) + CFRelease (bundleRefs.getUnchecked (i)); + + bundleRefs.clear(); + } + + return true; + } + + return false; + } #endif //============================================================================== @@ -3133,7 +3283,7 @@ private: if (entry->isUnicode) return kResultFalse; - memcpy (info, &entry->info2, sizeof (PClassInfoType)); + memcpy (info, (PClassInfoType*) &entry->info2, sizeof (PClassInfoType)); return kResultOk; } } @@ -3175,10 +3325,14 @@ JUCE_EXPORTED_FUNCTION IPluginFactory* PLUGIN_API GetPluginFactory() { PluginHostType::jucePlugInClientCurrentWrapperType = AudioProcessor::wrapperType_VST3; - #if JUCE_MSVC + #if JUCE_MSVC || (JUCE_WINDOWS && JUCE_CLANG) // Cunning trick to force this function to be exported. Life's too short to // faff around creating .def files for this kind of thing. - #pragma comment(linker, "/EXPORT:" __FUNCTION__ "=" __FUNCDNAME__) + #if JUCE_32BIT + #pragma comment(linker, "/EXPORT:GetPluginFactory=_GetPluginFactory@0") + #else + #pragma comment(linker, "/EXPORT:GetPluginFactory=GetPluginFactory") + #endif #endif if (globalFactory == nullptr) @@ -3218,7 +3372,7 @@ JUCE_EXPORTED_FUNCTION IPluginFactory* PLUGIN_API GetPluginFactory() } //============================================================================== -#if _MSC_VER || JUCE_MINGW +#if JUCE_WINDOWS extern "C" BOOL WINAPI DllMain (HINSTANCE instance, DWORD reason, LPVOID) { if (reason == DLL_PROCESS_ATTACH) Process::setCurrentModuleInstanceHandle (instance); return true; } #endif 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 5fce55a8..015844ee 100644 --- a/modules/juce_audio_plugin_client/juce_audio_plugin_client.h +++ b/modules/juce_audio_plugin_client/juce_audio_plugin_client.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -29,20 +28,20 @@ The block below describes the properties of this module, and is read by the Projucer to automatically generate project code that uses it. For details about the syntax and how to create or use a module, see the - JUCE Module Format.txt file. + JUCE Module Format.md file. BEGIN_JUCE_MODULE_DECLARATION ID: juce_audio_plugin_client vendor: juce - version: 5.4.7 + version: 6.0.5 name: JUCE audio plugin wrapper classes description: Classes for building VST, VST3, AudioUnit, AAX and RTAS plugins. website: http://www.juce.com/juce license: GPL/Commercial - dependencies: juce_gui_basics, juce_audio_basics, juce_audio_processors + dependencies: juce_audio_processors END_JUCE_MODULE_DECLARATION @@ -128,4 +127,5 @@ #endif #include "utility/juce_PluginHostType.h" +#include "utility/juce_CreatePluginFilter.h" #include "VST/juce_VSTCallbackHandler.h" diff --git a/modules/juce_audio_plugin_client/juce_audio_plugin_client_AAX.cpp b/modules/juce_audio_plugin_client/juce_audio_plugin_client_AAX.cpp index ba4f6833..872da717 100644 --- a/modules/juce_audio_plugin_client/juce_audio_plugin_client_AAX.cpp +++ b/modules/juce_audio_plugin_client/juce_audio_plugin_client_AAX.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_plugin_client/juce_audio_plugin_client_AAX.mm b/modules/juce_audio_plugin_client/juce_audio_plugin_client_AAX.mm index 40968796..e7b5d34d 100644 --- a/modules/juce_audio_plugin_client/juce_audio_plugin_client_AAX.mm +++ b/modules/juce_audio_plugin_client/juce_audio_plugin_client_AAX.mm @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU.r b/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU.r index 72623a82..c8cfc385 100644 --- a/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU.r +++ b/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU.r @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -28,13 +27,13 @@ #include <AudioUnit.r> //============================================================================== -/* The AppConfig.h file should be a file in your project, containing info to describe the - plugin's name, type, etc. The introjucer will generate this file automatically for you. +/* The JucePluginDefines file should be a file in your project, containing info to describe the + plugin's name, type, etc. The Projucer will generate this file automatically for you. You may need to adjust the include path of your project to make sure it can be found by this include statement. (Don't hack this file to change the include path) */ -#include "AppConfig.h" +#include "JucePluginDefines.h" //============================================================================== diff --git a/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU_1.mm b/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU_1.mm index df1b9310..c7217f94 100644 --- a/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU_1.mm +++ b/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU_1.mm @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU_2.mm b/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU_2.mm index 5b83f671..58fc62f8 100644 --- a/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU_2.mm +++ b/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU_2.mm @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -24,31 +23,30 @@ ============================================================================== */ +#include <juce_core/system/juce_TargetPlatform.h> + #if JucePlugin_Build_AU -#ifdef __clang__ - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wparentheses" - #pragma clang diagnostic ignored "-Wextra-tokens" - #pragma clang diagnostic ignored "-Wcomment" - #pragma clang diagnostic ignored "-Wconversion" - #pragma clang diagnostic ignored "-Wunused-parameter" - #pragma clang diagnostic ignored "-Wunused" - #pragma clang diagnostic ignored "-Wextra-semi" - #pragma clang diagnostic ignored "-Wformat-pedantic" - #pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments" - #pragma clang diagnostic ignored "-Wshadow-all" - #pragma clang diagnostic ignored "-Wcast-align" - #if __has_warning("-Wzero-as-null-pointer-constant") - #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" - #endif - #if __has_warning("-Wnullable-to-nonnull-conversion") - #pragma clang diagnostic ignored "-Wnullable-to-nonnull-conversion" - #endif - #if __has_warning("-Wignored-qualifiers") - #pragma clang diagnostic ignored "-Wignored-qualifiers" - #endif -#endif +#include <juce_core/system/juce_CompilerWarnings.h> + +JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wparentheses", + "-Wextra-tokens", + "-Wcomment", + "-Wconversion", + "-Wunused-parameter", + "-Wunused", + "-Wextra-semi", + "-Wformat-pedantic", + "-Wgnu-zero-variadic-macro-arguments", + "-Wshadow-all", + "-Wcast-align", + "-Wswitch-enum", + "-Wimplicit-fallthrough", + "-Wzero-as-null-pointer-constant", + "-Wnullable-to-nonnull-conversion", + "-Wignored-qualifiers", + "-Wfour-char-constants", + "-Wmissing-prototypes") // From MacOS 10.13 and iOS 11 Apple has (sensibly!) stopped defining a whole // set of functions with rather generic names. However, we still need a couple @@ -83,8 +81,6 @@ #undef verify #undef verify_noerr -#ifdef __clang__ - #pragma clang diagnostic pop -#endif +JUCE_END_IGNORE_WARNINGS_GCC_LIKE #endif diff --git a/modules/juce_audio_plugin_client/juce_audio_plugin_client_AUv3.mm b/modules/juce_audio_plugin_client/juce_audio_plugin_client_AUv3.mm index 04db62b9..11cd7352 100644 --- a/modules/juce_audio_plugin_client/juce_audio_plugin_client_AUv3.mm +++ b/modules/juce_audio_plugin_client/juce_audio_plugin_client_AUv3.mm @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_plugin_client/juce_audio_plugin_client_RTAS_1.cpp b/modules/juce_audio_plugin_client/juce_audio_plugin_client_RTAS_1.cpp index b0261869..77fd6207 100644 --- a/modules/juce_audio_plugin_client/juce_audio_plugin_client_RTAS_1.cpp +++ b/modules/juce_audio_plugin_client/juce_audio_plugin_client_RTAS_1.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_plugin_client/juce_audio_plugin_client_RTAS_2.cpp b/modules/juce_audio_plugin_client/juce_audio_plugin_client_RTAS_2.cpp index 3edb85d9..f1bcd904 100644 --- a/modules/juce_audio_plugin_client/juce_audio_plugin_client_RTAS_2.cpp +++ b/modules/juce_audio_plugin_client/juce_audio_plugin_client_RTAS_2.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_plugin_client/juce_audio_plugin_client_RTAS_3.cpp b/modules/juce_audio_plugin_client/juce_audio_plugin_client_RTAS_3.cpp index 34096ab6..42477b9b 100644 --- a/modules/juce_audio_plugin_client/juce_audio_plugin_client_RTAS_3.cpp +++ b/modules/juce_audio_plugin_client/juce_audio_plugin_client_RTAS_3.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_plugin_client/juce_audio_plugin_client_RTAS_4.cpp b/modules/juce_audio_plugin_client/juce_audio_plugin_client_RTAS_4.cpp index eae99b85..6fa1d7dc 100644 --- a/modules/juce_audio_plugin_client/juce_audio_plugin_client_RTAS_4.cpp +++ b/modules/juce_audio_plugin_client/juce_audio_plugin_client_RTAS_4.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_plugin_client/juce_audio_plugin_client_RTAS_utils.cpp b/modules/juce_audio_plugin_client/juce_audio_plugin_client_RTAS_utils.cpp index 5283c53c..d424fcc4 100644 --- a/modules/juce_audio_plugin_client/juce_audio_plugin_client_RTAS_utils.cpp +++ b/modules/juce_audio_plugin_client/juce_audio_plugin_client_RTAS_utils.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_plugin_client/juce_audio_plugin_client_RTAS_utils.mm b/modules/juce_audio_plugin_client/juce_audio_plugin_client_RTAS_utils.mm index 19a1eb1c..57ad81f3 100644 --- a/modules/juce_audio_plugin_client/juce_audio_plugin_client_RTAS_utils.mm +++ b/modules/juce_audio_plugin_client/juce_audio_plugin_client_RTAS_utils.mm @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_plugin_client/juce_audio_plugin_client_Standalone.cpp b/modules/juce_audio_plugin_client/juce_audio_plugin_client_Standalone.cpp index 19fa722a..98bac498 100644 --- a/modules/juce_audio_plugin_client/juce_audio_plugin_client_Standalone.cpp +++ b/modules/juce_audio_plugin_client/juce_audio_plugin_client_Standalone.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -24,6 +23,8 @@ ============================================================================== */ +#include <juce_core/system/juce_TargetPlatform.h> + #if JucePlugin_Build_Standalone #if ! JUCE_MODULE_AVAILABLE_juce_audio_utils diff --git a/modules/juce_audio_plugin_client/juce_audio_plugin_client_Unity.cpp b/modules/juce_audio_plugin_client/juce_audio_plugin_client_Unity.cpp index c0b31a60..04c59622 100644 --- a/modules/juce_audio_plugin_client/juce_audio_plugin_client_Unity.cpp +++ b/modules/juce_audio_plugin_client/juce_audio_plugin_client_Unity.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_plugin_client/juce_audio_plugin_client_VST2.cpp b/modules/juce_audio_plugin_client/juce_audio_plugin_client_VST2.cpp index 211106b3..2d8015ea 100644 --- a/modules/juce_audio_plugin_client/juce_audio_plugin_client_VST2.cpp +++ b/modules/juce_audio_plugin_client/juce_audio_plugin_client_VST2.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_plugin_client/juce_audio_plugin_client_VST3.cpp b/modules/juce_audio_plugin_client/juce_audio_plugin_client_VST3.cpp index f44c2522..a22bbb49 100644 --- a/modules/juce_audio_plugin_client/juce_audio_plugin_client_VST3.cpp +++ b/modules/juce_audio_plugin_client/juce_audio_plugin_client_VST3.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_plugin_client/juce_audio_plugin_client_VST_utils.mm b/modules/juce_audio_plugin_client/juce_audio_plugin_client_VST_utils.mm index 09d17ae6..ab1a4c86 100644 --- a/modules/juce_audio_plugin_client/juce_audio_plugin_client_VST_utils.mm +++ b/modules/juce_audio_plugin_client/juce_audio_plugin_client_VST_utils.mm @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_plugin_client/juce_audio_plugin_client_utils.cpp b/modules/juce_audio_plugin_client/juce_audio_plugin_client_utils.cpp index 38563ade..ea11fdbe 100644 --- a/modules/juce_audio_plugin_client/juce_audio_plugin_client_utils.cpp +++ b/modules/juce_audio_plugin_client/juce_audio_plugin_client_utils.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_plugin_client/utility/juce_CarbonVisibility.h b/modules/juce_audio_plugin_client/utility/juce_CarbonVisibility.h index 0d0f8aa9..f52c4e75 100644 --- a/modules/juce_audio_plugin_client/utility/juce_CarbonVisibility.h +++ b/modules/juce_audio_plugin_client/utility/juce_CarbonVisibility.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_plugin_client/utility/juce_CheckSettingMacros.h b/modules/juce_audio_plugin_client/utility/juce_CheckSettingMacros.h index b5278b17..6bea8430 100644 --- a/modules/juce_audio_plugin_client/utility/juce_CheckSettingMacros.h +++ b/modules/juce_audio_plugin_client/utility/juce_CheckSettingMacros.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -74,7 +73,7 @@ #define JucePlugin_Build_RTAS 0 #endif -#if ! (defined (_MSC_VER) || defined (__APPLE_CPP__) || defined (__APPLE_CC__)) +#if ! (defined (_MSC_VER) || defined (__APPLE_CPP__) || defined (__APPLE_CC__) || defined (LINUX) || defined (__linux__)) #undef JucePlugin_Build_VST3 #define JucePlugin_Build_VST3 0 #endif diff --git a/modules/juce_audio_plugin_client/utility/juce_CreatePluginFilter.h b/modules/juce_audio_plugin_client/utility/juce_CreatePluginFilter.h new file mode 100644 index 00000000..0722f52d --- /dev/null +++ b/modules/juce_audio_plugin_client/utility/juce_CreatePluginFilter.h @@ -0,0 +1,48 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +#pragma once + +/** Somewhere in the codebase of your plugin, you need to implement this function + and make it return a new instance of the filter subclass that you're building. +*/ +juce::AudioProcessor* JUCE_CALLTYPE createPluginFilter(); + +namespace juce +{ + +inline AudioProcessor* JUCE_API JUCE_CALLTYPE createPluginFilterOfType (AudioProcessor::WrapperType type) +{ + AudioProcessor::setTypeOfNextNewPlugin (type); + AudioProcessor* const pluginInstance = ::createPluginFilter(); + AudioProcessor::setTypeOfNextNewPlugin (AudioProcessor::wrapperType_Undefined); + + // your createPluginFilter() method must return an object! + jassert (pluginInstance != nullptr && pluginInstance->wrapperType == type); + + return pluginInstance; +} + +} // namespace juce diff --git a/modules/juce_audio_plugin_client/utility/juce_FakeMouseMoveGenerator.h b/modules/juce_audio_plugin_client/utility/juce_FakeMouseMoveGenerator.h index cb73184e..789cff55 100644 --- a/modules/juce_audio_plugin_client/utility/juce_FakeMouseMoveGenerator.h +++ b/modules/juce_audio_plugin_client/utility/juce_FakeMouseMoveGenerator.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -75,8 +74,12 @@ public: { if (! peer->isFocused()) { - peer->handleMouseEvent (MouseInputSource::InputSourceType::mouse, peer->globalToLocal (screenPos), mods, - MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, Time::currentTimeMillis()); + peer->handleMouseEvent (MouseInputSource::InputSourceType::mouse, + peer->globalToLocal (Desktop::getInstance().getMainMouseSource().getRawScreenPosition()), + mods, + MouseInputSource::invalidPressure, + MouseInputSource::invalidOrientation, + Time::currentTimeMillis()); } } @@ -88,8 +91,12 @@ public: { if (auto* peer = safeOldComponent->getPeer()) { - peer->handleMouseEvent (MouseInputSource::InputSourceType::mouse, MouseInputSource::offscreenMousePos, mods, - MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, Time::currentTimeMillis()); + peer->handleMouseEvent (MouseInputSource::InputSourceType::mouse, + MouseInputSource::offscreenMousePos, + mods, + MouseInputSource::invalidPressure, + MouseInputSource::invalidOrientation, + Time::currentTimeMillis()); } } diff --git a/modules/juce_audio_plugin_client/utility/juce_IncludeModuleHeaders.h b/modules/juce_audio_plugin_client/utility/juce_IncludeModuleHeaders.h index 701c4df9..4b36f6d6 100644 --- a/modules/juce_audio_plugin_client/utility/juce_IncludeModuleHeaders.h +++ b/modules/juce_audio_plugin_client/utility/juce_IncludeModuleHeaders.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -24,7 +23,8 @@ ============================================================================== */ -#include "../juce_audio_plugin_client.h" +#include <juce_audio_plugin_client/juce_audio_plugin_client.h> +#include "juce_CreatePluginFilter.h" namespace juce { @@ -42,5 +42,3 @@ namespace juce return hostType; } } - -extern juce::AudioProcessor* JUCE_API JUCE_CALLTYPE createPluginFilterOfType (juce::AudioProcessor::WrapperType); diff --git a/modules/juce_audio_plugin_client/utility/juce_IncludeSystemHeaders.h b/modules/juce_audio_plugin_client/utility/juce_IncludeSystemHeaders.h index 2c0f1298..b82650fa 100644 --- a/modules/juce_audio_plugin_client/utility/juce_IncludeSystemHeaders.h +++ b/modules/juce_audio_plugin_client/utility/juce_IncludeSystemHeaders.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -37,19 +36,11 @@ #ifdef __INTEL_COMPILER #pragma warning (disable : 1899) #endif - #elif JUCE_LINUX #include <float.h> #include <sys/time.h> - #include <X11/Xlib.h> - #include <X11/Xutil.h> - #include <X11/Xatom.h> - #undef Font - #undef KeyPress - #undef Drawable - #undef Time -#elif JUCE_ANDROID -#else + #include <arpa/inet.h> +#elif JUCE_MAC || JUCE_IOS #if ! (defined (JUCE_SUPPORT_CARBON) || defined (__LP64__)) #define JUCE_SUPPORT_CARBON 1 #endif diff --git a/modules/juce_audio_plugin_client/utility/juce_PluginHostType.h b/modules/juce_audio_plugin_client/utility/juce_PluginHostType.h index 11f5d8ff..1678c205 100644 --- a/modules/juce_audio_plugin_client/utility/juce_PluginHostType.h +++ b/modules/juce_audio_plugin_client/utility/juce_PluginHostType.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -260,6 +259,7 @@ public: case VBVSTScanner: return "VBVSTScanner"; case ViennaEnsemblePro: return "Vienna Ensemble Pro"; case WaveBurner: return "WaveBurner"; + case UnknownHost: default: break; } @@ -271,10 +271,8 @@ public: bool isInterAppAudioConnected() const; /** Switches to the host application when Inter-App Audio is used on iOS. */ void switchToHostApplication() const; - - #if JUCE_MODULE_AVAILABLE_juce_gui_basics + /** Gets the host app's icon when Inter-App Audio is used on iOS. */ Image getHostIcon (int size) const; - #endif //============================================================================== /** Returns the complete absolute path of the host application executable. */ @@ -302,7 +300,7 @@ public: #ifndef DOXYGEN // @internal static AudioProcessor::WrapperType jucePlugInClientCurrentWrapperType; - static std::function<bool(AudioProcessor&)> jucePlugInIsRunningInAudioSuiteFn; + static std::function<bool (AudioProcessor&)> jucePlugInIsRunningInAudioSuiteFn; #endif private: diff --git a/modules/juce_audio_plugin_client/utility/juce_PluginUtilities.cpp b/modules/juce_audio_plugin_client/utility/juce_PluginUtilities.cpp index e55db48f..e027e4a6 100644 --- a/modules/juce_audio_plugin_client/utility/juce_PluginUtilities.cpp +++ b/modules/juce_audio_plugin_client/utility/juce_PluginUtilities.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -28,162 +27,135 @@ #include <windows.h> #endif -#include "../../juce_core/system/juce_TargetPlatform.h" +#include <juce_core/system/juce_TargetPlatform.h> #include "../utility/juce_CheckSettingMacros.h" #include "juce_IncludeModuleHeaders.h" -using namespace juce; - namespace juce { AudioProcessor::WrapperType PluginHostType::jucePlugInClientCurrentWrapperType = AudioProcessor::wrapperType_Undefined; -std::function<bool(AudioProcessor&)> PluginHostType::jucePlugInIsRunningInAudioSuiteFn = nullptr; +std::function<bool (AudioProcessor&)> PluginHostType::jucePlugInIsRunningInAudioSuiteFn = nullptr; #if JucePlugin_Build_Unity bool juce_isRunningInUnity() { return PluginHostType::getPluginLoadedAs() == AudioProcessor::wrapperType_Unity; } #endif -#if JUCE_MODULE_AVAILABLE_juce_opengl && JucePlugin_Build_VST - bool juce_shouldDoubleScaleNativeGLWindow() - { - return PluginHostType::getPluginLoadedAs() == AudioProcessor::wrapperType_VST - && getHostType().type == PluginHostType::AbletonLive10; - } -#endif - #ifndef JUCE_VST3_CAN_REPLACE_VST2 #define JUCE_VST3_CAN_REPLACE_VST2 1 #endif -#if JucePlugin_Build_VST3 && (__APPLE_CPP__ || __APPLE_CC__ || _WIN32 || _WIN64) && JUCE_VST3_CAN_REPLACE_VST2 -#define VST3_REPLACEMENT_AVAILABLE 1 +#if JucePlugin_Build_VST3 && JUCE_VST3_CAN_REPLACE_VST2 && (JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX) + #define VST3_REPLACEMENT_AVAILABLE 1 -// NB: Nasty old-fashioned code in here because it's copied from the Steinberg example code. -void JUCE_API getUUIDForVST2ID (bool forControllerUID, uint8 uuid[16]) -{ - char uidString[33]; + // NB: Nasty old-fashioned code in here because it's copied from the Steinberg example code. + void JUCE_API getUUIDForVST2ID (bool forControllerUID, uint8 uuid[16]) + { + char uidString[33]; - const int vstfxid = (('V' << 16) | ('S' << 8) | (forControllerUID ? 'E' : 'T')); - char vstfxidStr[7] = { 0 }; - sprintf (vstfxidStr, "%06X", vstfxid); + const int vstfxid = (('V' << 16) | ('S' << 8) | (forControllerUID ? 'E' : 'T')); + char vstfxidStr[7] = { 0 }; + sprintf (vstfxidStr, "%06X", vstfxid); - strcpy (uidString, vstfxidStr); + strcpy (uidString, vstfxidStr); - char uidStr[9] = { 0 }; - sprintf (uidStr, "%08X", JucePlugin_VSTUniqueID); - strcat (uidString, uidStr); + char uidStr[9] = { 0 }; + sprintf (uidStr, "%08X", JucePlugin_VSTUniqueID); + strcat (uidString, uidStr); - char nameidStr[3] = { 0 }; - const size_t len = strlen (JucePlugin_Name); + char nameidStr[3] = { 0 }; + const size_t len = strlen (JucePlugin_Name); - for (size_t i = 0; i <= 8; ++i) - { - juce::uint8 c = i < len ? static_cast<juce::uint8> (JucePlugin_Name[i]) : 0; + for (size_t i = 0; i <= 8; ++i) + { + juce::uint8 c = i < len ? static_cast<juce::uint8> (JucePlugin_Name[i]) : 0; - if (c >= 'A' && c <= 'Z') - c += 'a' - 'A'; + if (c >= 'A' && c <= 'Z') + c += 'a' - 'A'; - sprintf (nameidStr, "%02X", c); - strcat (uidString, nameidStr); - } + sprintf (nameidStr, "%02X", c); + strcat (uidString, nameidStr); + } - unsigned long p0; - unsigned int p1, p2; - unsigned int p3[8]; + unsigned long p0; + unsigned int p1, p2; + unsigned int p3[8]; - #ifndef _MSC_VER - sscanf - #else - sscanf_s - #endif - (uidString, "%08lX%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X", - &p0, &p1, &p2, &p3[0], &p3[1], &p3[2], &p3[3], &p3[4], &p3[5], &p3[6], &p3[7]); - - union q0_u { - uint32 word; - uint8 bytes[4]; - } q0; - - union q1_u { - uint16 half; - uint8 bytes[2]; - } q1, q2; - - q0.word = static_cast<uint32> (p0); - q1.half = static_cast<uint16> (p1); - q2.half = static_cast<uint16> (p2); - - // VST3 doesn't use COM compatible UUIDs on non windows platforms - #ifndef _WIN32 - q0.word = ByteOrder::swap (q0.word); - q1.half = ByteOrder::swap (q1.half); - q2.half = ByteOrder::swap (q2.half); - #endif + #if ! JUCE_MSVC + sscanf + #else + sscanf_s + #endif + (uidString, "%08lX%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X", + &p0, &p1, &p2, &p3[0], &p3[1], &p3[2], &p3[3], &p3[4], &p3[5], &p3[6], &p3[7]); - for (int i = 0; i < 4; ++i) - uuid[i+0] = q0.bytes[i]; + union q0_u { + uint32 word; + uint8 bytes[4]; + } q0; - for (int i = 0; i < 2; ++i) - uuid[i+4] = q1.bytes[i]; + union q1_u { + uint16 half; + uint8 bytes[2]; + } q1, q2; - for (int i = 0; i < 2; ++i) - uuid[i+6] = q2.bytes[i]; + q0.word = static_cast<uint32> (p0); + q1.half = static_cast<uint16> (p1); + q2.half = static_cast<uint16> (p2); - for (int i = 0; i < 8; ++i) - uuid[i+8] = static_cast<uint8> (p3[i]); -} + // VST3 doesn't use COM compatible UUIDs on non windows platforms + #if ! JUCE_WINDOWS + q0.word = ByteOrder::swap (q0.word); + q1.half = ByteOrder::swap (q1.half); + q2.half = ByteOrder::swap (q2.half); + #endif + + for (int i = 0; i < 4; ++i) + uuid[i+0] = q0.bytes[i]; + + for (int i = 0; i < 2; ++i) + uuid[i+4] = q1.bytes[i]; + + for (int i = 0; i < 2; ++i) + uuid[i+6] = q2.bytes[i]; + + for (int i = 0; i < 8; ++i) + uuid[i+8] = static_cast<uint8> (p3[i]); + } #else -#define VST3_REPLACEMENT_AVAILABLE 0 + #define VST3_REPLACEMENT_AVAILABLE 0 #endif #if JucePlugin_Build_VST -bool JUCE_API handleManufacturerSpecificVST2Opcode (int32 index, pointer_sized_int value, void* ptr, float) -{ - #if VST3_REPLACEMENT_AVAILABLE - if ((index == 'stCA' || index == 'stCa') && value == 'FUID' && ptr != nullptr) - { - uint8 fuid[16]; - getUUIDForVST2ID (false, fuid); - ::memcpy (ptr, fuid, 16); - return true; - } - #else - ignoreUnused (index, value, ptr); - #endif - return false; -} + bool JUCE_API handleManufacturerSpecificVST2Opcode (int32 index, pointer_sized_int value, void* ptr, float) + { + #if VST3_REPLACEMENT_AVAILABLE + if ((index == (int32) ByteOrder::bigEndianInt ("stCA") || index == (int32) ByteOrder::bigEndianInt ("stCa")) + && value == (int32) ByteOrder::bigEndianInt ("FUID") && ptr != nullptr) + { + uint8 fuid[16]; + getUUIDForVST2ID (false, fuid); + ::memcpy (ptr, fuid, 16); + return true; + } + #else + ignoreUnused (index, value, ptr); + #endif + return false; + } #endif } // namespace juce -//============================================================================== -/** Somewhere in the codebase of your plugin, you need to implement this function - and make it return a new instance of the filter subclass that you're building. -*/ -extern AudioProcessor* JUCE_CALLTYPE createPluginFilter(); +using namespace juce; +//============================================================================== #if JucePlugin_Enable_IAA && JucePlugin_Build_Standalone && JUCE_IOS && (! JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP) extern bool JUCE_CALLTYPE juce_isInterAppAudioConnected(); extern void JUCE_CALLTYPE juce_switchToHostApplication(); - - #if JUCE_MODULE_AVAILABLE_juce_gui_basics extern Image JUCE_CALLTYPE juce_getIAAHostIcon (int); - #endif #endif -AudioProcessor* JUCE_API JUCE_CALLTYPE createPluginFilterOfType (AudioProcessor::WrapperType type) -{ - AudioProcessor::setTypeOfNextNewPlugin (type); - AudioProcessor* const pluginInstance = createPluginFilter(); - AudioProcessor::setTypeOfNextNewPlugin (AudioProcessor::wrapperType_Undefined); - - // your createPluginFilter() method must return an object! - jassert (pluginInstance != nullptr && pluginInstance->wrapperType == type); - - return pluginInstance; -} - bool PluginHostType::isInterAppAudioConnected() const { #if JucePlugin_Enable_IAA && JucePlugin_Build_Standalone && JUCE_IOS && (! JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP) @@ -216,7 +188,6 @@ bool PluginHostType::isInAAXAudioSuite (AudioProcessor& processor) return false; } -#if JUCE_MODULE_AVAILABLE_juce_gui_basics namespace juce { extern Image JUCE_API getIconFromApplication (const String&, const int); @@ -239,4 +210,3 @@ Image PluginHostType::getHostIcon (int size) const } } -#endif diff --git a/modules/juce_audio_plugin_client/utility/juce_WindowsHooks.h b/modules/juce_audio_plugin_client/utility/juce_WindowsHooks.h index 9407e7e7..64d07388 100644 --- a/modules/juce_audio_plugin_client/utility/juce_WindowsHooks.h +++ b/modules/juce_audio_plugin_client/utility/juce_WindowsHooks.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_processors/format/juce_AudioPluginFormat.cpp b/modules/juce_audio_processors/format/juce_AudioPluginFormat.cpp index c42d3fb7..6d728a34 100644 --- a/modules/juce_audio_processors/format/juce_AudioPluginFormat.cpp +++ b/modules/juce_audio_processors/format/juce_AudioPluginFormat.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_processors/format/juce_AudioPluginFormat.h b/modules/juce_audio_processors/format/juce_AudioPluginFormat.h index c7753e0b..f3bc8268 100644 --- a/modules/juce_audio_processors/format/juce_AudioPluginFormat.h +++ b/modules/juce_audio_processors/format/juce_AudioPluginFormat.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -75,7 +74,7 @@ public: String& errorMessage); /** A callback lambda that is passed to createPluginInstanceAsync() */ - using PluginCreationCallback = std::function<void(std::unique_ptr<AudioPluginInstance>, const String&)>; + using PluginCreationCallback = std::function<void (std::unique_ptr<AudioPluginInstance>, const String&)>; /** Tries to recreate a type from a previously generated PluginDescription. When the plugin has been created, it will be passed to the caller via an diff --git a/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.cpp b/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.cpp index a54d9d0d..20e7a508 100644 --- a/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.cpp +++ b/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -43,7 +42,7 @@ void AudioPluginFormatManager::addDefaultFormats() jassert (dynamic_cast<VSTPluginFormat*> (format) == nullptr); #endif - #if JUCE_PLUGINHOST_VST3 && (JUCE_MAC || JUCE_WINDOWS) + #if JUCE_PLUGINHOST_VST3 && (JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX) jassert (dynamic_cast<VST3PluginFormat*> (format) == nullptr); #endif @@ -65,7 +64,7 @@ void AudioPluginFormatManager::addDefaultFormats() formats.add (new VSTPluginFormat()); #endif - #if JUCE_PLUGINHOST_VST3 && (JUCE_MAC || JUCE_WINDOWS) + #if JUCE_PLUGINHOST_VST3 && (JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX) formats.add (new VST3PluginFormat()); #endif diff --git a/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.h b/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.h index 8ae1aa6e..65c12320 100644 --- a/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.h +++ b/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -72,8 +71,6 @@ public: /** Tries to load the type for this description, by trying all the formats that this manager knows about. - The caller is responsible for deleting the object that is returned. - If it can't load the plugin, it returns nullptr and leaves a message in the errorMessage string. diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fstring.cpp b/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fstring.cpp index e41cbae1..1f294c1a 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fstring.cpp +++ b/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fstring.cpp @@ -287,7 +287,6 @@ static inline int strnicmp16 (const Steinberg::char16* s1, const Steinberg::char //----------------------------------------------------------------------------- static inline int sprintf16 (Steinberg::char16* wcs, const Steinberg::char16* format, ...) { -#warning DEPRECATED No Linux implementation assert(false && "DEPRECATED No Linux implementation"); return 0; } @@ -311,7 +310,6 @@ static inline int vsnwprintf (Steinberg::char16* wcs, size_t maxlen, //----------------------------------------------------------------------------- static inline Steinberg::char16* strrchr16 (const Steinberg::char16* str, Steinberg::char16 c) { -#warning DEPRECATED No Linux implementation assert(false && "DEPRECATED No Linux implementation"); return nullptr; } @@ -1586,7 +1584,6 @@ char16 ConstString::toLower (char16 c) } return c; #elif SMTG_OS_LINUX - #warning DEPRECATED No Linux implementation assert(false && "DEPRECATED No Linux implementation"); return c; #else @@ -1615,7 +1612,6 @@ char16 ConstString::toUpper (char16 c) } return c; #elif SMTG_OS_LINUX - #warning DEPRECATED No Linux implementation assert(false && "DEPRECATED No Linux implementation"); return c; #else @@ -1913,8 +1909,7 @@ int32 ConstString::multiByteToWideString (char16* dest, const char8* source, int } } else - { -#warning DEPRECATED No Linux implementation + { assert(false && "DEPRECATED No Linux implementation"); } @@ -1994,8 +1989,7 @@ int32 ConstString::wideStringToMultiByte (char8* dest, const char16* wideString, } } else - { -#warning DEPRECATED No Linux implementation + { assert(false && "DEPRECATED No Linux implementation"); } return result; diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/base/funknown.cpp b/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/base/funknown.cpp index 0419bbc4..206a64af 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/base/funknown.cpp +++ b/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/base/funknown.cpp @@ -148,7 +148,6 @@ bool FUID::generate () return false; #else -#warning implement me! return false; #endif } diff --git a/modules/juce_audio_processors/format_types/juce_AU_Shared.h b/modules/juce_audio_processors/format_types/juce_AU_Shared.h index be95a65a..2dcbf39f 100644 --- a/modules/juce_audio_processors/format_types/juce_AU_Shared.h +++ b/modules/juce_audio_processors/format_types/juce_AU_Shared.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.h b/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.h index 7ac90dcd..c8d46706 100644 --- a/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.h +++ b/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm b/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm index 0136e58b..5d8eef93 100644 --- a/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm +++ b/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -40,8 +39,7 @@ #ifndef JUCE_SUPPORTS_AUv3 #if __OBJC2__ \ - && ((defined (MAC_OS_X_VERSION_10_11) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11)) \ - || (defined (__IPHONE_9_0) && (__IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_9_0))) + && (JUCE_IOS || (defined (MAC_OS_X_VERSION_10_11) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11))) #define JUCE_SUPPORTS_AUv3 1 #else #define JUCE_SUPPORTS_AUv3 0 @@ -52,8 +50,8 @@ #include <CoreAudioKit/AUViewController.h> #endif -#include "../../juce_audio_basics/native/juce_mac_CoreAudioLayouts.h" -#include "../../juce_audio_devices/native/juce_MidiDataConcatenator.h" +#include <juce_audio_basics/native/juce_mac_CoreAudioLayouts.h> +#include <juce_audio_devices/native/juce_MidiDataConcatenator.h> #include "juce_AU_Shared.h" namespace juce @@ -76,7 +74,7 @@ namespace AudioUnitFormatHelpers static ThreadLocalValue<int> insideCallback; #endif - String osTypeToString (OSType type) noexcept + static String osTypeToString (OSType type) noexcept { const juce_wchar s[4] = { (juce_wchar) ((type >> 24) & 0xff), (juce_wchar) ((type >> 16) & 0xff), @@ -85,7 +83,7 @@ namespace AudioUnitFormatHelpers return String (s, 4); } - OSType stringToOSType (String s) + static OSType stringToOSType (String s) { if (s.trim().length() >= 4) // (to avoid trimming leading spaces) s = s.trim(); @@ -100,7 +98,7 @@ namespace AudioUnitFormatHelpers static const char* auIdentifierPrefix = "AudioUnit:"; - String createPluginIdentifier (const AudioComponentDescription& desc) + static String createPluginIdentifier (const AudioComponentDescription& desc) { String s (auIdentifierPrefix); @@ -125,7 +123,7 @@ namespace AudioUnitFormatHelpers return s; } - void getNameAndManufacturer (AudioComponent comp, String& name, String& manufacturer) + static void getNameAndManufacturer (AudioComponent comp, String& name, String& manufacturer) { CFStringRef cfName; if (AudioComponentCopyName (comp, &cfName) == noErr) @@ -144,8 +142,8 @@ namespace AudioUnitFormatHelpers name = "<Unknown>"; } - bool getComponentDescFromIdentifier (const String& fileOrIdentifier, AudioComponentDescription& desc, - String& name, String& version, String& manufacturer) + static bool getComponentDescFromIdentifier (const String& fileOrIdentifier, AudioComponentDescription& desc, + String& name, String& version, String& manufacturer) { if (fileOrIdentifier.startsWithIgnoreCase (auIdentifierPrefix)) { @@ -190,8 +188,8 @@ namespace AudioUnitFormatHelpers return false; } - bool getComponentDescFromFile (const String& fileOrIdentifier, AudioComponentDescription& desc, - String& name, String& version, String& manufacturer) + static bool getComponentDescFromFile (const String& fileOrIdentifier, AudioComponentDescription& desc, + String& name, String& version, String& manufacturer) { zerostruct (desc); @@ -293,7 +291,7 @@ namespace AudioUnitFormatHelpers #endif } - const char* getCategory (OSType type) noexcept + static const char* getCategory (OSType type) noexcept { switch (type) { @@ -1080,17 +1078,14 @@ public: if (wantsMidiMessages) { - const uint8* midiEventData; - int midiEventSize, midiEventPosition; - - for (MidiBuffer::Iterator i (midiMessages); i.getNextEvent (midiEventData, midiEventSize, midiEventPosition);) + for (const auto metadata : midiMessages) { - if (midiEventSize <= 3) + if (metadata.numBytes <= 3) MusicDeviceMIDIEvent (audioUnit, - midiEventData[0], midiEventData[1], midiEventData[2], - (UInt32) midiEventPosition); + metadata.data[0], metadata.data[1], metadata.data[2], + (UInt32) metadata.samplePosition); else - MusicDeviceSysEx (audioUnit, midiEventData, (UInt32) midiEventSize); + MusicDeviceSysEx (audioUnit, metadata.data, (UInt32) metadata.numBytes); } midiMessages.clear(); @@ -1401,8 +1396,10 @@ public: if (audioUnit != nullptr) { UInt32 paramListSize = 0; - haveParameterList = AudioUnitGetPropertyInfo (audioUnit, kAudioUnitProperty_ParameterList, kAudioUnitScope_Global, - 0, &paramListSize, nullptr) == noErr; + auto err = AudioUnitGetPropertyInfo (audioUnit, kAudioUnitProperty_ParameterList, kAudioUnitScope_Global, + 0, &paramListSize, nullptr); + + haveParameterList = (paramListSize > 0 && err == noErr); if (! haveParameterList) return; @@ -1448,28 +1445,16 @@ public: || info.unit == kAudioUnitParameterUnit_Boolean); bool isBoolean = info.unit == kAudioUnitParameterUnit_Boolean; - String label; - - switch (info.unit) + auto label = [info]() -> String { - case kAudioUnitParameterUnit_Percent: - label = "%"; - break; - case kAudioUnitParameterUnit_Seconds: - label = "s"; - break; - case kAudioUnitParameterUnit_Hertz: - label = "Hz"; - break; - case kAudioUnitParameterUnit_Decibels: - label = "dB"; - break; - case kAudioUnitParameterUnit_Milliseconds: - label = "ms"; - break; - default: - break; - } + if (info.unit == kAudioUnitParameterUnit_Percent) return "%"; + if (info.unit == kAudioUnitParameterUnit_Seconds) return "s"; + if (info.unit == kAudioUnitParameterUnit_Hertz) return "Hz"; + if (info.unit == kAudioUnitParameterUnit_Decibels) return "dB"; + if (info.unit == kAudioUnitParameterUnit_Milliseconds) return "ms"; + + return {}; + }(); auto* parameter = new AUInstanceParameter (*this, ids[i], @@ -1830,6 +1815,7 @@ private: break; + case kAudioUnitEvent_PropertyChange: default: if (event.mArgument.mProperty.mPropertyID == kAudioUnitProperty_ParameterList) { @@ -2036,7 +2022,7 @@ private: } //============================================================================== - static inline UInt64 GetCurrentHostTime (int numSamples, double sampleRate, bool isAUv3) noexcept + static UInt64 GetCurrentHostTime (int numSamples, double sampleRate, bool isAUv3) noexcept { #if ! JUCE_IOS if (! isAUv3) diff --git a/modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp b/modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp index 960b3db8..19f1d7ac 100644 --- a/modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp +++ b/modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -691,9 +690,8 @@ StringArray LADSPAPluginFormat::searchPathsForPlugins (const FileSearchPath& dir void LADSPAPluginFormat::recursiveFileSearch (StringArray& results, const File& dir, const bool recursive) { - DirectoryIterator iter (dir, false, "*", File::findFilesAndDirectories); - while (iter.next()) + for (const auto& iter : RangedDirectoryIterator (dir, false, "*", File::findFilesAndDirectories)) { auto f = iter.getFile(); bool isPlugin = false; diff --git a/modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.h b/modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.h index 58feefc4..d7f39967 100644 --- a/modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.h +++ b/modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp b/modules/juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp index 5eb81292..c3bf144b 100644 --- a/modules/juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp +++ b/modules/juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -27,16 +26,8 @@ namespace juce { -#if JUCE_GCC - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#elif JUCE_CLANG - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wdeprecated-declarations" -#elif JUCE_MSVC - #pragma warning (push, 0) - #pragma warning (disable: 4996) -#endif +JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wdeprecated-declarations") +JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4996) class LegacyAudioParameter : public AudioProcessorParameter { @@ -176,12 +167,7 @@ private: bool legacyParamIDs = false, usingManagedParameters = false; }; -#if JUCE_GCC - #pragma GCC diagnostic pop -#elif JUCE_CLANG - #pragma clang diagnostic pop -#elif JUCE_MSVC - #pragma warning (pop) -#endif +JUCE_END_IGNORE_WARNINGS_GCC_LIKE +JUCE_END_IGNORE_WARNINGS_MSVC } // namespace juce diff --git a/modules/juce_audio_processors/format_types/juce_VST3Common.h b/modules/juce_audio_processors/format_types/juce_VST3Common.h index dc40caf6..8ee6db87 100644 --- a/modules/juce_audio_processors/format_types/juce_VST3Common.h +++ b/modules/juce_audio_processors/format_types/juce_VST3Common.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -93,8 +92,10 @@ inline Steinberg::Vst::TChar* toString (const juce::String& source) noexcept #if JUCE_WINDOWS static const Steinberg::FIDString defaultVST3WindowType = Steinberg::kPlatformTypeHWND; -#else +#elif JUCE_MAC static const Steinberg::FIDString defaultVST3WindowType = Steinberg::kPlatformTypeNSView; +#elif JUCE_LINUX + static const Steinberg::FIDString defaultVST3WindowType = Steinberg::kPlatformTypeX11EmbedWindowID; #endif @@ -111,45 +112,7 @@ static inline Steinberg::Vst::SpeakerArrangement getArrangementForBus (Steinberg return arrangement; } -/** For the sake of simplicity, there can only be 1 arrangement type per channel count. - i.e.: 4 channels == k31Cine OR k40Cine -*/ -static inline Steinberg::Vst::SpeakerArrangement getArrangementForNumChannels (int numChannels) noexcept -{ - using namespace Steinberg::Vst::SpeakerArr; - - switch (numChannels) - { - case 0: return kEmpty; - case 1: return kMono; - case 2: return kStereo; - case 3: return k30Cine; - case 4: return k31Cine; - case 5: return k50; - case 6: return k51; - case 7: return k61Cine; - case 8: return k71CineFullFront; - case 9: return k90; - case 10: return k91; - case 11: return k101; - case 12: return k111; - case 13: return k130; - case 14: return k131; - #if VST_VERSION >= 0x030608 - case 16: return kAmbi3rdOrderACN; - #endif - case 24: return (Steinberg::Vst::SpeakerArrangement) 1929904127; // k222 - default: break; - } - - jassert (numChannels >= 0); - - juce::BigInteger bi; - bi.setRange (0, jmin (numChannels, (int) (sizeof (Steinberg::Vst::SpeakerArrangement) * 8)), true); - return (Steinberg::Vst::SpeakerArrangement) bi.toInt64(); -} - -static inline Steinberg::Vst::Speaker getSpeakerType (const AudioChannelSet& set, AudioChannelSet::ChannelType type) noexcept +static Steinberg::Vst::Speaker getSpeakerType (const AudioChannelSet& set, AudioChannelSet::ChannelType type) noexcept { switch (type) { @@ -206,6 +169,29 @@ static inline Steinberg::Vst::Speaker getSpeakerType (const AudioChannelSet& set case AudioChannelSet::discreteChannel0: return Steinberg::Vst::kSpeakerM; + case AudioChannelSet::ambisonicACN16: + case AudioChannelSet::ambisonicACN17: + case AudioChannelSet::ambisonicACN18: + case AudioChannelSet::ambisonicACN19: + case AudioChannelSet::ambisonicACN20: + case AudioChannelSet::ambisonicACN21: + case AudioChannelSet::ambisonicACN22: + case AudioChannelSet::ambisonicACN23: + case AudioChannelSet::ambisonicACN24: + case AudioChannelSet::ambisonicACN25: + case AudioChannelSet::ambisonicACN26: + case AudioChannelSet::ambisonicACN27: + case AudioChannelSet::ambisonicACN28: + case AudioChannelSet::ambisonicACN29: + case AudioChannelSet::ambisonicACN30: + case AudioChannelSet::ambisonicACN31: + case AudioChannelSet::ambisonicACN32: + case AudioChannelSet::ambisonicACN33: + case AudioChannelSet::ambisonicACN34: + case AudioChannelSet::ambisonicACN35: + case AudioChannelSet::proximityLeft: + case AudioChannelSet::proximityRight: + case AudioChannelSet::unknown: default: break; } @@ -214,7 +200,7 @@ static inline Steinberg::Vst::Speaker getSpeakerType (const AudioChannelSet& set return (1ull << (channelIndex + 33ull /* last speaker in vst layout + 1 */)); } -static inline AudioChannelSet::ChannelType getChannelType (Steinberg::Vst::SpeakerArrangement arr, Steinberg::Vst::Speaker type) noexcept +static AudioChannelSet::ChannelType getChannelType (Steinberg::Vst::SpeakerArrangement arr, Steinberg::Vst::Speaker type) noexcept { switch (type) { @@ -279,7 +265,7 @@ static inline AudioChannelSet::ChannelType getChannelType (Steinberg::Vst::Speak return static_cast<AudioChannelSet::ChannelType> (static_cast<int> (AudioChannelSet::discreteChannel0) + 6 + (channelType - 33)); } -static inline Steinberg::Vst::SpeakerArrangement getVst3SpeakerArrangement (const AudioChannelSet& channels) noexcept +static Steinberg::Vst::SpeakerArrangement getVst3SpeakerArrangement (const AudioChannelSet& channels) noexcept { using namespace Steinberg::Vst::SpeakerArr; @@ -320,7 +306,7 @@ static inline Steinberg::Vst::SpeakerArrangement getVst3SpeakerArrangement (cons return result; } -static inline AudioChannelSet getChannelSetForSpeakerArrangement (Steinberg::Vst::SpeakerArrangement arr) noexcept +static AudioChannelSet getChannelSetForSpeakerArrangement (Steinberg::Vst::SpeakerArrangement arr) noexcept { using namespace Steinberg::Vst::SpeakerArr; @@ -415,8 +401,8 @@ private: class MidiEventList : public Steinberg::Vst::IEventList { public: - MidiEventList() {} - virtual ~MidiEventList() {} + MidiEventList() = default; + virtual ~MidiEventList() = default; JUCE_DECLARE_VST3_COM_REF_METHODS JUCE_DECLARE_VST3_COM_QUERY_METHODS @@ -453,66 +439,69 @@ public: //============================================================================== static void toMidiBuffer (MidiBuffer& result, Steinberg::Vst::IEventList& eventList) { - const int32 numEvents = eventList.getEventCount(); + const auto numEvents = eventList.getEventCount(); for (Steinberg::int32 i = 0; i < numEvents; ++i) { Steinberg::Vst::Event e; - if (eventList.getEvent (i, e) == Steinberg::kResultOk) - { - switch (e.type) - { - case Steinberg::Vst::Event::kNoteOnEvent: - result.addEvent (MidiMessage::noteOn (createSafeChannel (e.noteOn.channel), - createSafeNote (e.noteOn.pitch), - (Steinberg::uint8) denormaliseToMidiValue (e.noteOn.velocity)), - e.sampleOffset); - break; - - case Steinberg::Vst::Event::kNoteOffEvent: - result.addEvent (MidiMessage::noteOff (createSafeChannel (e.noteOff.channel), - createSafeNote (e.noteOff.pitch), - (Steinberg::uint8) denormaliseToMidiValue (e.noteOff.velocity)), - e.sampleOffset); - break; - - case Steinberg::Vst::Event::kPolyPressureEvent: - result.addEvent (MidiMessage::channelPressureChange (createSafeChannel (e.polyPressure.channel), - denormaliseToMidiValue (e.polyPressure.pressure)), - e.sampleOffset); - break; - - case Steinberg::Vst::Event::kDataEvent: - result.addEvent (MidiMessage::createSysExMessage (e.data.bytes, (int) e.data.size), - e.sampleOffset); - break; - - default: - break; - } - } + if (eventList.getEvent (i, e) != Steinberg::kResultOk) + continue; + + const auto message = toMidiMessage (e); + + if (message.isValid) + result.addEvent (message.item, e.sampleOffset); } } - static void toEventList (Steinberg::Vst::IEventList& result, MidiBuffer& midiBuffer, - Steinberg::Vst::IParameterChanges* parameterChanges = nullptr, - Steinberg::Vst::IMidiMapping* midiMapping = nullptr) + static void hostToPluginEventList (Steinberg::Vst::IEventList& result, MidiBuffer& midiBuffer, + Steinberg::Vst::IParameterChanges* parameterChanges, + Steinberg::Vst::IMidiMapping* midiMapping) { - MidiBuffer::Iterator iterator (midiBuffer); - const uint8* midiEventData = nullptr; - int midiEventSize = 0; - int midiEventPosition = 0; + toEventList (result, + midiBuffer, + parameterChanges, + midiMapping, + EventConversionKind::hostToPlugin); + } + static void pluginToHostEventList (Steinberg::Vst::IEventList& result, MidiBuffer& midiBuffer) + { + toEventList (result, + midiBuffer, + nullptr, + nullptr, + EventConversionKind::pluginToHost); + } + +private: + enum class EventConversionKind + { + // Hosted plugins don't expect to receive LegacyMIDICCEvents messages from the host, + // so if we're converting midi from the host to an eventlist, this mode will avoid + // converting to Legacy events where possible. + hostToPlugin, + + // If plugins generate MIDI internally, then where possible we should preserve + // these messages as LegacyMIDICCOut events. + pluginToHost + }; + + static void toEventList (Steinberg::Vst::IEventList& result, MidiBuffer& midiBuffer, + Steinberg::Vst::IParameterChanges* parameterChanges, + Steinberg::Vst::IMidiMapping* midiMapping, + EventConversionKind kind) + { enum { maxNumEvents = 2048 }; // Steinberg's Host Checker states that no more than 2048 events are allowed at once int numEvents = 0; - while (iterator.getNextEvent (midiEventData, midiEventSize, midiEventPosition)) + for (const auto metadata : midiBuffer) { if (++numEvents > maxNumEvents) break; - MidiMessage msg (midiEventData, midiEventSize); + auto msg = metadata.getMessage(); if (midiMapping != nullptr && parameterChanges != nullptr) { @@ -529,61 +518,25 @@ public: Steinberg::int32 ignore; if (auto* queue = parameterChanges->addParameterData (controlParamID, ignore)) - queue->addPoint (midiEventPosition, controlEvent.paramValue, ignore); + queue->addPoint (metadata.samplePosition, controlEvent.paramValue, ignore); } continue; } } - Steinberg::Vst::Event e{}; + auto maybeEvent = createVstEvent (msg, metadata.data, kind); - if (msg.isNoteOn()) - { - e.type = Steinberg::Vst::Event::kNoteOnEvent; - e.noteOn.channel = createSafeChannel (msg.getChannel()); - e.noteOn.pitch = createSafeNote (msg.getNoteNumber()); - e.noteOn.velocity = normaliseMidiValue (msg.getVelocity()); - e.noteOn.length = 0; - e.noteOn.tuning = 0.0f; - e.noteOn.noteId = -1; - } - else if (msg.isNoteOff()) - { - e.type = Steinberg::Vst::Event::kNoteOffEvent; - e.noteOff.channel = createSafeChannel (msg.getChannel()); - e.noteOff.pitch = createSafeNote (msg.getNoteNumber()); - e.noteOff.velocity = normaliseMidiValue (msg.getVelocity()); - e.noteOff.tuning = 0.0f; - e.noteOff.noteId = -1; - } - else if (msg.isSysEx()) - { - e.type = Steinberg::Vst::Event::kDataEvent; - e.data.bytes = midiEventData + 1; - e.data.size = (uint32) msg.getSysExDataSize(); - e.data.type = Steinberg::Vst::DataEvent::kMidiSysEx; - } - else if (msg.isChannelPressure()) - { - e.type = Steinberg::Vst::Event::kPolyPressureEvent; - e.polyPressure.channel = createSafeChannel (msg.getChannel()); - e.polyPressure.pitch = createSafeNote (msg.getNoteNumber()); - e.polyPressure.pressure = normaliseMidiValue (msg.getChannelPressureValue()); - } - else - { + if (! maybeEvent.isValid) continue; - } + auto& e = maybeEvent.item; e.busIndex = 0; - e.sampleOffset = midiEventPosition; - + e.sampleOffset = metadata.samplePosition; result.addEvent (e); } } -private: Array<Steinberg::Vst::Event, CriticalSection> events; Atomic<int> refCount; @@ -596,6 +549,240 @@ private: static float normaliseMidiValue (int value) noexcept { return jlimit (0.0f, 1.0f, (float) value / 127.0f); } static int denormaliseToMidiValue (float value) noexcept { return roundToInt (jlimit (0.0f, 127.0f, value * 127.0f)); } + static Steinberg::Vst::Event createNoteOnEvent (const MidiMessage& msg) noexcept + { + Steinberg::Vst::Event e{}; + e.type = Steinberg::Vst::Event::kNoteOnEvent; + e.noteOn.channel = createSafeChannel (msg.getChannel()); + e.noteOn.pitch = createSafeNote (msg.getNoteNumber()); + e.noteOn.velocity = normaliseMidiValue (msg.getVelocity()); + e.noteOn.length = 0; + e.noteOn.tuning = 0.0f; + e.noteOn.noteId = -1; + return e; + } + + static Steinberg::Vst::Event createNoteOffEvent (const MidiMessage& msg) noexcept + { + Steinberg::Vst::Event e{}; + e.type = Steinberg::Vst::Event::kNoteOffEvent; + e.noteOff.channel = createSafeChannel (msg.getChannel()); + e.noteOff.pitch = createSafeNote (msg.getNoteNumber()); + e.noteOff.velocity = normaliseMidiValue (msg.getVelocity()); + e.noteOff.tuning = 0.0f; + e.noteOff.noteId = -1; + return e; + } + + static Steinberg::Vst::Event createSysExEvent (const MidiMessage& msg, const uint8* midiEventData) noexcept + { + Steinberg::Vst::Event e{}; + e.type = Steinberg::Vst::Event::kDataEvent; + e.data.bytes = midiEventData + 1; + e.data.size = (uint32) msg.getSysExDataSize(); + e.data.type = Steinberg::Vst::DataEvent::kMidiSysEx; + return e; + } + + static Steinberg::Vst::Event createLegacyMIDIEvent (int channel, int controlNumber, int value, int value2 = 0) + { + Steinberg::Vst::Event e{}; + e.type = Steinberg::Vst::Event::kLegacyMIDICCOutEvent; + e.midiCCOut.channel = Steinberg::int8 (createSafeChannel (channel)); + e.midiCCOut.controlNumber = uint8 (jlimit (0, 255, controlNumber)); + e.midiCCOut.value = Steinberg::int8 (createSafeNote (value)); + e.midiCCOut.value2 = Steinberg::int8 (createSafeNote (value2)); + return e; + } + + static Steinberg::Vst::Event createPolyPressureEvent (const MidiMessage& msg) + { + Steinberg::Vst::Event e{}; + e.type = Steinberg::Vst::Event::kPolyPressureEvent; + e.polyPressure.channel = createSafeChannel (msg.getChannel()); + e.polyPressure.pitch = createSafeNote (msg.getNoteNumber()); + e.polyPressure.pressure = normaliseMidiValue (msg.getAfterTouchValue()); + e.polyPressure.noteId = -1; + return e; + } + + static Steinberg::Vst::Event createChannelPressureEvent (const MidiMessage& msg) noexcept + { + return createLegacyMIDIEvent (msg.getChannel(), + Steinberg::Vst::kAfterTouch, + msg.getChannelPressureValue()); + } + + static Steinberg::Vst::Event createControllerEvent (const MidiMessage& msg) noexcept + { + return createLegacyMIDIEvent (msg.getChannel(), + msg.getControllerNumber(), + msg.getControllerValue()); + } + + static Steinberg::Vst::Event createCtrlPolyPressureEvent (const MidiMessage& msg) noexcept + { + return createLegacyMIDIEvent (msg.getChannel(), + Steinberg::Vst::kCtrlPolyPressure, + msg.getNoteNumber(), + msg.getAfterTouchValue()); + } + + static Steinberg::Vst::Event createPitchWheelEvent (const MidiMessage& msg) noexcept + { + return createLegacyMIDIEvent (msg.getChannel(), + Steinberg::Vst::kPitchBend, + msg.getRawData()[1], + msg.getRawData()[2]); + } + + static Steinberg::Vst::Event createProgramChangeEvent (const MidiMessage& msg) noexcept + { + return createLegacyMIDIEvent (msg.getChannel(), + Steinberg::Vst::kCtrlProgramChange, + msg.getProgramChangeNumber()); + } + + static Steinberg::Vst::Event createCtrlQuarterFrameEvent (const MidiMessage& msg) noexcept + { + return createLegacyMIDIEvent (msg.getChannel(), + Steinberg::Vst::kCtrlQuarterFrame, + msg.getQuarterFrameValue()); + } + + template <typename Item> + struct BasicOptional final + { + BasicOptional() noexcept = default; + BasicOptional (const Item& i) noexcept : item { i }, isValid { true } {} + + Item item; + bool isValid{}; + }; + + static BasicOptional<Steinberg::Vst::Event> createVstEvent (const MidiMessage& msg, + const uint8* midiEventData, + EventConversionKind kind) noexcept + { + if (msg.isNoteOn()) + return createNoteOnEvent (msg); + + if (msg.isNoteOff()) + return createNoteOffEvent (msg); + + if (msg.isSysEx()) + return createSysExEvent (msg, midiEventData); + + if (msg.isChannelPressure()) + return createChannelPressureEvent (msg); + + if (msg.isPitchWheel()) + return createPitchWheelEvent (msg); + + if (msg.isProgramChange()) + return createProgramChangeEvent (msg); + + if (msg.isController()) + return createControllerEvent (msg); + + if (msg.isQuarterFrame()) + return createCtrlQuarterFrameEvent (msg); + + if (msg.isAftertouch()) + { + switch (kind) + { + case EventConversionKind::hostToPlugin: + return createPolyPressureEvent (msg); + + case EventConversionKind::pluginToHost: + return createCtrlPolyPressureEvent (msg); + } + + jassertfalse; + return {}; + } + + return {}; + } + + static BasicOptional<MidiMessage> toMidiMessage (const Steinberg::Vst::LegacyMIDICCOutEvent& e) + { + if (e.controlNumber <= 127) + return MidiMessage::controllerEvent (createSafeChannel (int16 (e.channel)), + createSafeNote (int16 (e.controlNumber)), + createSafeNote (int16 (e.value))); + + switch (e.controlNumber) + { + case Steinberg::Vst::kAfterTouch: + return MidiMessage::channelPressureChange (createSafeChannel (int16 (e.channel)), + createSafeNote (int16 (e.value))); + + case Steinberg::Vst::kPitchBend: + return MidiMessage::pitchWheel (createSafeChannel (int16 (e.channel)), + (e.value & 0x7f) | ((e.value2 & 0x7f) << 7)); + + case Steinberg::Vst::kCtrlProgramChange: + return MidiMessage::programChange (createSafeChannel (int16 (e.channel)), + createSafeNote (int16 (e.value))); + + case Steinberg::Vst::kCtrlQuarterFrame: + return MidiMessage::quarterFrame (createSafeChannel (int16 (e.channel)), + createSafeNote (int16 (e.value))); + + case Steinberg::Vst::kCtrlPolyPressure: + return MidiMessage::aftertouchChange (createSafeChannel (int16 (e.channel)), + createSafeNote (int16 (e.value)), + createSafeNote (int16 (e.value2))); + + default: + // If this is hit, we're trying to convert a LegacyMIDICCOutEvent with an unknown controlNumber. + jassertfalse; + return {}; + } + } + + static BasicOptional<MidiMessage> toMidiMessage (const Steinberg::Vst::Event& e) + { + switch (e.type) + { + case Steinberg::Vst::Event::kNoteOnEvent: + return MidiMessage::noteOn (createSafeChannel (e.noteOn.channel), + createSafeNote (e.noteOn.pitch), + (Steinberg::uint8) denormaliseToMidiValue (e.noteOn.velocity)); + + case Steinberg::Vst::Event::kNoteOffEvent: + return MidiMessage::noteOff (createSafeChannel (e.noteOff.channel), + createSafeNote (e.noteOff.pitch), + (Steinberg::uint8) denormaliseToMidiValue (e.noteOff.velocity)); + + case Steinberg::Vst::Event::kPolyPressureEvent: + return MidiMessage::aftertouchChange (createSafeChannel (e.polyPressure.channel), + createSafeNote (e.polyPressure.pitch), + (Steinberg::uint8) denormaliseToMidiValue (e.polyPressure.pressure)); + + case Steinberg::Vst::Event::kDataEvent: + return MidiMessage::createSysExMessage (e.data.bytes, (int) e.data.size); + + case Steinberg::Vst::Event::kLegacyMIDICCOutEvent: + return toMidiMessage (e.midiCCOut); + + case Steinberg::Vst::Event::kNoteExpressionValueEvent: + case Steinberg::Vst::Event::kNoteExpressionTextEvent: + case Steinberg::Vst::Event::kChordEvent: + case Steinberg::Vst::Event::kScaleEvent: + return {}; + + default: + break; + } + + // If this is hit, we've been sent an event type that doesn't exist in the VST3 spec. + jassertfalse; + return {}; + } + //============================================================================== struct Vst3MidiControlEvent { @@ -605,13 +792,26 @@ private: static bool toVst3ControlEvent (const MidiMessage& msg, Vst3MidiControlEvent& result) { - result.controllerNumber = -1; + if (msg.isController()) + { + result = { (Steinberg::Vst::CtrlNumber) msg.getControllerNumber(), msg.getControllerValue() / 127.0}; + return true; + } - if (msg.isController()) result = { (Steinberg::Vst::CtrlNumber) msg.getControllerNumber(), msg.getControllerValue() / 127.0}; - else if (msg.isPitchWheel()) result = { Steinberg::Vst::kPitchBend, msg.getPitchWheelValue() / 16383.0}; - else if (msg.isAftertouch()) result = { Steinberg::Vst::kAfterTouch, msg.getAfterTouchValue() / 127.0}; + if (msg.isPitchWheel()) + { + result = { Steinberg::Vst::kPitchBend, msg.getPitchWheelValue() / 16383.0}; + return true; + } - return (result.controllerNumber != -1); + if (msg.isChannelPressure()) + { + result = { Steinberg::Vst::kAfterTouch, msg.getChannelPressureValue() / 127.0}; + return true; + } + + result.controllerNumber = -1; + return false; } JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiEventList) @@ -624,8 +824,8 @@ struct VST3BufferExchange using Bus = Array<FloatType*>; using BusMap = Array<Bus>; - static inline void assignRawPointer (Steinberg::Vst::AudioBusBuffers& vstBuffers, float** raw) { vstBuffers.channelBuffers32 = raw; } - static inline void assignRawPointer (Steinberg::Vst::AudioBusBuffers& vstBuffers, double** raw) { vstBuffers.channelBuffers64 = raw; } + static void assignRawPointer (Steinberg::Vst::AudioBusBuffers& vstBuffers, float** raw) { vstBuffers.channelBuffers32 = raw; } + static void assignRawPointer (Steinberg::Vst::AudioBusBuffers& vstBuffers, double** raw) { vstBuffers.channelBuffers64 = raw; } /** Assigns a series of AudioBuffer's channels to an AudioBusBuffers' @warning For speed, does not check the channel count and offsets according to the AudioBuffer @@ -669,9 +869,9 @@ struct VST3BufferExchange channelIndexOffset += numChansForBus; } - static inline void mapBufferToBuses (Array<Steinberg::Vst::AudioBusBuffers>& result, BusMap& busMapToUse, - const Array<AudioChannelSet>& arrangements, - AudioBuffer<FloatType>& source) + static void mapBufferToBuses (Array<Steinberg::Vst::AudioBusBuffers>& result, BusMap& busMapToUse, + const Array<AudioChannelSet>& arrangements, + AudioBuffer<FloatType>& source) { int channelIndexOffset = 0; @@ -680,10 +880,10 @@ struct VST3BufferExchange arrangements.getUnchecked (i), source); } - static inline void mapBufferToBuses (Array<Steinberg::Vst::AudioBusBuffers>& result, - Steinberg::Vst::IAudioProcessor& processor, - BusMap& busMapToUse, bool isInput, int numBuses, - AudioBuffer<FloatType>& source) + static void mapBufferToBuses (Array<Steinberg::Vst::AudioBusBuffers>& result, + Steinberg::Vst::IAudioProcessor& processor, + BusMap& busMapToUse, bool isInput, int numBuses, + AudioBuffer<FloatType>& source) { int channelIndexOffset = 0; @@ -710,12 +910,12 @@ struct VST3FloatAndDoubleBusMapComposite template <> struct VST3FloatAndDoubleBusMapCompositeHelper<float> { - static inline VST3BufferExchange<float>::BusMap& get (VST3FloatAndDoubleBusMapComposite& impl) { return impl.floatVersion; } + static VST3BufferExchange<float>::BusMap& get (VST3FloatAndDoubleBusMapComposite& impl) { return impl.floatVersion; } }; template <> struct VST3FloatAndDoubleBusMapCompositeHelper<double> { - static inline VST3BufferExchange<double>::BusMap& get (VST3FloatAndDoubleBusMapComposite& impl) { return impl.doubleVersion; } + static VST3BufferExchange<double>::BusMap& get (VST3FloatAndDoubleBusMapComposite& impl) { return impl.doubleVersion; } }; } // namespace juce diff --git a/modules/juce_audio_processors/format_types/juce_VST3Headers.h b/modules/juce_audio_processors/format_types/juce_VST3Headers.h index f8b1351d..b9615db4 100644 --- a/modules/juce_audio_processors/format_types/juce_VST3Headers.h +++ b/modules/juce_audio_processors/format_types/juce_VST3Headers.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -25,53 +24,40 @@ */ // Wow, those Steinberg guys really don't worry too much about compiler warnings. -#if _MSC_VER - #pragma warning (disable: 4505) - #pragma warning (push, 0) - #pragma warning (disable: 4702) -#elif __clang__ - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wnon-virtual-dtor" - #pragma clang diagnostic ignored "-Wreorder" - #pragma clang diagnostic ignored "-Wunsequenced" - #pragma clang diagnostic ignored "-Wint-to-pointer-cast" - #pragma clang diagnostic ignored "-Wunused-parameter" - #pragma clang diagnostic ignored "-Wconversion" - #pragma clang diagnostic ignored "-Woverloaded-virtual" - #pragma clang diagnostic ignored "-Wshadow" - #pragma clang diagnostic ignored "-Wdeprecated-register" - #pragma clang diagnostic ignored "-Wunused-function" - #pragma clang diagnostic ignored "-Wsign-conversion" - #pragma clang diagnostic ignored "-Wsign-compare" - #pragma clang diagnostic ignored "-Wdelete-non-virtual-dtor" - #pragma clang diagnostic ignored "-Wdeprecated-declarations" - #pragma clang diagnostic ignored "-Wextra-semi" - #pragma clang diagnostic ignored "-Wmissing-braces" - #if __has_warning("-Wshadow-field") - #pragma clang diagnostic ignored "-Wshadow-field" - #endif - #if __has_warning("-Wpragma-pack") - #pragma clang diagnostic ignored "-Wpragma-pack" - #endif - #if __has_warning("-Wcomma") - #pragma clang diagnostic ignored "-Wcomma" - #endif - #if __has_warning("-Wzero-as-null-pointer-constant") - #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" - #endif - #if __has_warning("-Winconsistent-missing-destructor-override") - #pragma clang diagnostic ignored "-Winconsistent-missing-destructor-override" - #endif - #if __has_warning("-Wcast-align") - #pragma clang diagnostic ignored "-Wcast-align" - #endif - #if __has_warning("-Wignored-qualifiers") - #pragma clang diagnostic ignored "-Wignored-qualifiers" - #endif - #if __has_warning("-Wmissing-field-initializers") - #pragma clang diagnostic ignored "-Wmissing-field-initializers" - #endif -#endif +JUCE_BEGIN_IGNORE_WARNINGS_LEVEL_MSVC (0, 4505 4702) + +JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wnon-virtual-dtor", + "-Wreorder", + "-Wunsequenced", + "-Wint-to-pointer-cast", + "-Wunused-parameter", + "-Wconversion", + "-Woverloaded-virtual", + "-Wshadow", + "-Wdeprecated-register", + "-Wunused-function", + "-Wsign-conversion", + "-Wsign-compare", + "-Wdelete-non-virtual-dtor", + "-Wdeprecated-declarations", + "-Wextra-semi", + "-Wmissing-braces", + "-Wswitch-default", + "-Wshadow-field", + "-Wpragma-pack", + "-Wcomma", + "-Wzero-as-null-pointer-constant", + "-Winconsistent-missing-destructor-override", + "-Wcast-align", + "-Wignored-qualifiers", + "-Wmissing-field-initializers", + "-Wformat=", + "-Wformat", + "-Wpedantic", + "-Wextra", + "-Wclass-memaccess", + "-Wmissing-prototypes", + "-Wtype-limits") #undef DEVELOPMENT #define DEVELOPMENT 0 // This avoids a Clang warning in Steinberg code about unused values @@ -121,12 +107,14 @@ #include <base/source/fobject.cpp> #include <base/source/fstreamer.cpp> #include <base/source/fstring.cpp> -#if VST_VERSION >= 0x030608 - #include <base/thread/source/flock.cpp> - #include <pluginterfaces/base/coreiids.cpp> -#else - #include <base/source/flock.cpp> -#endif + + #if VST_VERSION >= 0x030608 + #include <base/thread/source/flock.cpp> + #include <pluginterfaces/base/coreiids.cpp> + #else + #include <base/source/flock.cpp> + #endif + #include <base/source/updatehandler.cpp> #include <pluginterfaces/base/conststringtable.cpp> #include <pluginterfaces/base/funknown.cpp> @@ -146,9 +134,10 @@ #include <public.sdk/source/vst/vstparameters.cpp> #include <public.sdk/source/vst/vstpresetfile.cpp> #include <public.sdk/source/vst/hosting/hostclasses.cpp> -#if VST_VERSION >= 0x03060c // 3.6.12 - #include <public.sdk/source/vst/hosting/pluginterfacesupport.cpp> -#endif + + #if VST_VERSION >= 0x03060c // 3.6.12 + #include <public.sdk/source/vst/hosting/pluginterfacesupport.cpp> + #endif //============================================================================== namespace Steinberg @@ -166,14 +155,15 @@ namespace Steinberg DEF_CLASS_IID (IPlugView) DEF_CLASS_IID (IPlugFrame) DEF_CLASS_IID (IPlugViewContentScaleSupport) + + #if JUCE_LINUX + DEF_CLASS_IID (Linux::IRunLoop) + #endif } -#endif //JUCE_VST3HEADERS_INCLUDE_HEADERS_ONLY +#endif // JUCE_VST3HEADERS_INCLUDE_HEADERS_ONLY -#if _MSC_VER - #pragma warning (pop) -#elif __clang__ - #pragma clang diagnostic pop -#endif +JUCE_END_IGNORE_WARNINGS_MSVC +JUCE_END_IGNORE_WARNINGS_GCC_LIKE #if JUCE_WINDOWS #include <windows.h> diff --git a/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp b/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp index 4e290c53..0b6abb60 100644 --- a/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp +++ b/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -24,7 +23,7 @@ ============================================================================== */ -#if JUCE_PLUGINHOST_VST3 && (JUCE_MAC || JUCE_WINDOWS) +#if JUCE_PLUGINHOST_VST3 && (JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX) #include "juce_VST3Headers.h" #include "juce_VST3Common.h" @@ -32,6 +31,10 @@ namespace juce { +#if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE + extern void setThreadDPIAwarenessForWindow (HWND); +#endif + using namespace Steinberg; //============================================================================== @@ -577,7 +580,7 @@ private: tresult PLUGIN_API setBinary (AttrID id, const void* data, Steinberg::uint32 size) override { - jassert (size >= 0 && (data != nullptr || size == 0)); + jassert (data != nullptr || size == 0); addMessageToQueue (id, MemoryBlock (data, (size_t) size)); return kResultTrue; } @@ -815,61 +818,43 @@ private: //============================================================================== struct DLLHandle { - DLLHandle (const String& modulePath) + DLLHandle (const File& fileToOpen) + : dllFile (fileToOpen) { - if (modulePath.trim().isNotEmpty()) - open (modulePath); + open(); } ~DLLHandle() { - typedef bool (PLUGIN_API *ExitModuleFn) (); - - #if JUCE_WINDOWS - releaseFactory(); - - if (auto exitFn = (ExitModuleFn) getFunction ("ExitDll")) - exitFn(); - - library.close(); - - #else + #if JUCE_MAC if (bundleRef != nullptr) + #endif { - releaseFactory(); + if (factory != nullptr) + factory->release(); + + using ExitModuleFn = bool (PLUGIN_API*) (); - if (auto exitFn = (ExitModuleFn) getFunction ("bundleExit")) + if (auto* exitFn = (ExitModuleFn) getFunction (exitFnName)) exitFn(); + #if JUCE_WINDOWS || JUCE_LINUX + library.close(); + #elif JUCE_MAC CFRelease (bundleRef); bundleRef = nullptr; + #endif } - #endif - } - - void open (const PluginDescription& description) - { - #if JUCE_WINDOWS - jassert (description.fileOrIdentifier.isNotEmpty()); - jassert (File (description.fileOrIdentifier).existsAsFile()); - library.open (description.fileOrIdentifier); - #else - open (description.fileOrIdentifier); - #endif } - /** @note The factory should begin with a refCount of 1, - so don't increment the reference count - (ie: don't use a ComSmartPtr in here)! - Its lifetime will be handled by this DllHandle, - when such will be destroyed. - - @see releaseFactory + //============================================================================== + /** The factory should begin with a refCount of 1, so don't increment the reference count + (ie: don't use a ComSmartPtr in here)! Its lifetime will be handled by this DLLHandle. */ IPluginFactory* JUCE_CALLTYPE getPluginFactory() { if (factory == nullptr) - if (auto proc = (GetFactoryProc) getFunction ("GetPluginFactory")) + if (auto* proc = (GetFactoryProc) getFunction (factoryFnName)) factory = proc(); // The plugin NEEDS to provide a factory to be able to be called a VST3! @@ -881,44 +866,62 @@ struct DLLHandle void* getFunction (const char* functionName) { - #if JUCE_WINDOWS + #if JUCE_WINDOWS || JUCE_LINUX return library.getFunction (functionName); - #else + #elif JUCE_MAC if (bundleRef == nullptr) return nullptr; - CFStringRef name = String (functionName).toCFString(); - void* fn = CFBundleGetFunctionPointerForName (bundleRef, name); - CFRelease (name); - return fn; + ScopedCFString name (functionName); + return CFBundleGetFunctionPointerForName (bundleRef, name.cfString); #endif } + File getFile() const noexcept { return dllFile; } + private: + File dllFile; IPluginFactory* factory = nullptr; - void releaseFactory() - { - if (factory != nullptr) - factory->release(); - } + static constexpr const char* factoryFnName = "GetPluginFactory"; #if JUCE_WINDOWS + static constexpr const char* entryFnName = "InitDll"; + static constexpr const char* exitFnName = "ExitDll"; + + using EntryProc = bool (PLUGIN_API*) (); + #elif JUCE_LINUX + static constexpr const char* entryFnName = "ModuleEntry"; + static constexpr const char* exitFnName = "ModuleExit"; + + using EntryProc = bool (PLUGIN_API*) (void*); + #elif JUCE_MAC + static constexpr const char* entryFnName = "bundleEntry"; + static constexpr const char* exitFnName = "bundleExit"; + + using EntryProc = bool (*) (CFBundleRef); + #endif + + //============================================================================== + #if JUCE_WINDOWS || JUCE_LINUX DynamicLibrary library; - bool open (const String& filePath) + bool open() { - if (library.open (filePath)) + if (library.open (dllFile.getFullPathName())) { - typedef bool (PLUGIN_API *InitModuleProc) (); - - if (auto proc = (InitModuleProc) getFunction ("InitDll")) + if (auto* proc = (EntryProc) getFunction (entryFnName)) { + #if JUCE_WINDOWS if (proc()) + #else + if (proc (library.getNativeHandle())) + #endif return true; } else { + // this is required for some plug-ins which don't export the dll entry point function return true; } @@ -927,16 +930,17 @@ private: return false; } - - #else + #elif JUCE_MAC CFBundleRef bundleRef; - bool open (const String& filePath) + bool open() { - const File file (filePath); - const char* const utf8 = file.getFullPathName().toRawUTF8(); + auto* utf8 = dllFile.getFullPathName().toRawUTF8(); - if (CFURLRef url = CFURLCreateFromFileSystemRepresentation (nullptr, (const UInt8*) utf8, (CFIndex) std::strlen (utf8), file.isDirectory())) + if (CFURLRef url = CFURLCreateFromFileSystemRepresentation (nullptr, + (const UInt8*) utf8, + (CFIndex) std::strlen (utf8), + dllFile.isDirectory())) { bundleRef = CFBundleCreate (kCFAllocatorDefault, url); CFRelease (url); @@ -947,17 +951,11 @@ private: if (CFBundleLoadExecutableAndReturnError (bundleRef, &error)) { - using BundleEntryProc = bool (*)(CFBundleRef); - - if (auto proc = (BundleEntryProc) getFunction ("bundleEntry")) + if (auto* proc = (EntryProc) getFunction (entryFnName)) { if (proc (bundleRef)) return true; } - else - { - return true; - } } if (error != nullptr) @@ -980,76 +978,120 @@ private: } #endif + //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DLLHandle) }; -//============================================================================== -struct VST3ModuleHandle : public ReferenceCountedObject +struct DLLHandleCache : public DeletedAtShutdown { - explicit VST3ModuleHandle (const File& pluginFile) : file (pluginFile) + DLLHandleCache() = default; + ~DLLHandleCache() override { clearSingletonInstance(); } + + JUCE_DECLARE_SINGLETON (DLLHandleCache, false) + + DLLHandle& findOrCreateHandle (const String& modulePath) { - getActiveModules().add (this); + #if JUCE_LINUX + File file (getDLLFileFromBundle (modulePath)); + #else + File file (modulePath); + #endif + + auto it = std::find_if (openHandles.begin(), openHandles.end(), + [&] (const std::unique_ptr<DLLHandle>& handle) + { + return file == handle->getFile(); + }); + + if (it != openHandles.end()) + return *it->get(); + + openHandles.push_back (std::make_unique<DLLHandle> (file)); + return *openHandles.back().get(); } - ~VST3ModuleHandle() +private: + #if JUCE_LINUX + File getDLLFileFromBundle (const String& bundlePath) const { - getActiveModules().removeFirstMatchingValue (this); + auto machineName = []() -> String + { + struct utsname unameData; + auto res = uname (&unameData); + + if (res != 0) + return {}; + + return unameData.machine; + }(); + + File file (bundlePath); + + return file.getChildFile ("Contents") + .getChildFile (machineName + "-linux") + .getChildFile (file.getFileNameWithoutExtension() + ".so"); } + #endif - /** - Since there is no apparent indication if a VST3 plugin is a shell or not, - we're stuck iterating through a VST3's factory, creating a description - for every housed plugin. - */ - static bool getAllDescriptionsForFile (OwnedArray<PluginDescription>& results, - const String& fileOrIdentifier) - { - DLLHandle tempModule (fileOrIdentifier); + std::vector<std::unique_ptr<DLLHandle>> openHandles; - ComSmartPtr<IPluginFactory> pluginFactory (tempModule.getPluginFactory()); + //============================================================================== + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DLLHandleCache) +}; - if (pluginFactory != nullptr) - { - ComSmartPtr<VST3HostContext> host (new VST3HostContext()); - DescriptionLister lister (host, pluginFactory); - auto result = lister.findDescriptionsAndPerform (File (fileOrIdentifier)); - results.addCopiesOf (lister.list); +JUCE_IMPLEMENT_SINGLETON (DLLHandleCache) - return result.wasOk(); +//============================================================================== +struct VST3ModuleHandle : public ReferenceCountedObject +{ + explicit VST3ModuleHandle (const File& pluginFile, const PluginDescription& pluginDesc) + : file (pluginFile) + { + if (open (pluginDesc)) + { + isOpen = true; + getActiveModules().add (this); } + } - jassertfalse; - return false; + ~VST3ModuleHandle() + { + if (isOpen) + getActiveModules().removeFirstMatchingValue (this); } //============================================================================== using Ptr = ReferenceCountedObjectPtr<VST3ModuleHandle>; - static VST3ModuleHandle::Ptr findOrCreateModule (const File& file, const PluginDescription& description) + static VST3ModuleHandle::Ptr findOrCreateModule (const File& file, + const PluginDescription& description) { for (auto* module : getActiveModules()) + { // VST3s are basically shells, you must therefore check their name along with their file: if (module->file == file && module->name == description.name) return module; + } - VST3ModuleHandle::Ptr m (new VST3ModuleHandle (file)); + VST3ModuleHandle::Ptr modulePtr (new VST3ModuleHandle (file, description)); - if (! m->open (file, description)) - m = nullptr; + if (! modulePtr->isOpen) + modulePtr = nullptr; - return m; + return modulePtr; } //============================================================================== - IPluginFactory* getPluginFactory() { return dllHandle->getPluginFactory(); } + IPluginFactory* getPluginFactory() + { + return DLLHandleCache::getInstance()->findOrCreateHandle (file.getFullPathName()).getPluginFactory(); + } - File file; - String name; + File getFile() const noexcept { return file; } + String getName() const noexcept { return name; } private: - std::unique_ptr<DLLHandle> dllHandle; - //============================================================================== static Array<VST3ModuleHandle*>& getActiveModules() { @@ -1058,11 +1100,10 @@ private: } //============================================================================== - bool open (const File& f, const PluginDescription& description) + bool open (const PluginDescription& description) { - dllHandle.reset (new DLLHandle (f.getFullPathName())); - - ComSmartPtr<IPluginFactory> pluginFactory (dllHandle->getPluginFactory()); + ComSmartPtr<IPluginFactory> pluginFactory (DLLHandleCache::getInstance()->findOrCreateHandle (file.getFullPathName()) + .getPluginFactory()); if (pluginFactory != nullptr) { @@ -1077,7 +1118,7 @@ private: continue; if (toString (info.name).trim() == description.name - && getHashForTUID (info.cid) == description.uid) + && getHashForTUID (info.cid) == description.uid) { name = description.name; return true; @@ -1088,15 +1129,19 @@ private: return false; } + File file; + String name; + bool isOpen = false; + + //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (VST3ModuleHandle) }; //============================================================================== struct VST3PluginWindow : public AudioProcessorEditor, public ComponentMovementWatcher, - #if ! JUCE_MAC + #if JUCE_WINDOWS || JUCE_LINUX public ComponentPeer::ScaleFactorListener, - public Timer, #endif public IPlugFrame { @@ -1111,20 +1156,26 @@ struct VST3PluginWindow : public AudioProcessorEditor, warnOnFailure (view->setFrame (this)); - Steinberg::IPlugViewContentScaleSupport* scaleInterface = nullptr; + #if ! JUCE_MAC view->queryInterface (Steinberg::IPlugViewContentScaleSupport::iid, (void**) &scaleInterface); - - if (scaleInterface != nullptr) - { - pluginRespondsToDPIChanges = true; - scaleInterface->release(); - } + #endif resizeToFit(); } ~VST3PluginWindow() override { + #if ! JUCE_MAC + if (scaleInterface != nullptr) + scaleInterface->release(); + + removeScaleFactorListeners(); + + #if JUCE_LINUX + embeddedComponent.removeClient(); + #endif + #endif + warnOnFailure (view->removed()); warnOnFailure (view->setFrame (nullptr)); @@ -1135,16 +1186,120 @@ struct VST3PluginWindow : public AudioProcessorEditor, #endif view = nullptr; + } - #if ! JUCE_MAC - for (int i = 0; i < ComponentPeer::getNumPeers(); ++i) - if (auto* p = ComponentPeer::getPeer (i)) - p->removeScaleFactorListener (this); - #endif + #if JUCE_LINUX + struct RunLoop final : public Steinberg::Linux::IRunLoop + { + ~RunLoop() + { + for (const auto& h : eventHandlers) + LinuxEventLoop::unregisterFdCallback (h.first); + } + + tresult PLUGIN_API registerEventHandler (Linux::IEventHandler* handler, + Linux::FileDescriptor fd) override + { + if (handler == nullptr || eventHandlers.find (fd) != eventHandlers.end()) + return kInvalidArgument; + + LinuxEventLoop::registerFdCallback (fd, [handler] (int descriptor) + { + handler->onFDIsSet (descriptor); + return true; + }); + + eventHandlers.emplace (fd, handler); + return kResultTrue; + } + + tresult PLUGIN_API unregisterEventHandler (Linux::IEventHandler* handler) override + { + if (handler == nullptr) + return kInvalidArgument; + + for (auto it = eventHandlers.begin(), end = eventHandlers.end(); it != end; ++it) + { + if (it->second == handler) + { + LinuxEventLoop::unregisterFdCallback (it->first); + eventHandlers.erase (it); + return kResultTrue; + } + } + + return kResultFalse; + } + + tresult PLUGIN_API registerTimer (Linux::ITimerHandler* handler, Linux::TimerInterval milliseconds) override + { + if (handler == nullptr || milliseconds == 0) + return kInvalidArgument; + + timerHandlers.push_back (std::make_unique<TimerCaller> (handler, (int) milliseconds)); + return kResultTrue; + } + + tresult PLUGIN_API unregisterTimer (Linux::ITimerHandler* handler) override + { + if (handler == nullptr) + return kInvalidArgument; + + for (auto it = timerHandlers.begin(), end = timerHandlers.end(); it != end; ++it) + { + if (it->get()->handler == handler) + { + timerHandlers.erase (it); + return kResultTrue; + } + } + + return kNotImplemented; + } + + uint32 PLUGIN_API addRef() override { return 1000; } + uint32 PLUGIN_API release() override { return 1000; } + tresult PLUGIN_API queryInterface (const TUID, void**) override { return kNoInterface; } + + std::unordered_map<Linux::FileDescriptor, Linux::IEventHandler*> eventHandlers; + + struct TimerCaller : public Timer + { + TimerCaller (Linux::ITimerHandler* h, int interval) : handler (h) + { + startTimer (interval); + } + + void timerCallback() override + { + handler->onTimer(); + } + + Linux::ITimerHandler* handler; + }; + std::vector<std::unique_ptr<TimerCaller>> timerHandlers; + }; + + RunLoop runLoop; + + Steinberg::tresult PLUGIN_API queryInterface (const Steinberg::TUID iid, void** obj) override + { + if (doUIDsMatch (iid, Steinberg::Linux::IRunLoop::iid)) + { + *obj = &runLoop; + return kResultTrue; + } + + jassertfalse; + *obj = nullptr; + + return Steinberg::kNotImplemented; } + #else + JUCE_DECLARE_VST3_COM_QUERY_METHODS + #endif JUCE_DECLARE_VST3_COM_REF_METHODS - JUCE_DECLARE_VST3_COM_QUERY_METHODS void paint (Graphics& g) override { @@ -1169,6 +1324,8 @@ struct VST3PluginWindow : public AudioProcessorEditor, void componentPeerChanged() override { #if ! JUCE_MAC + removeScaleFactorListeners(); + if (auto* topPeer = getTopLevelComponent()->getPeer()) topPeer->addScaleFactorListener (this); #endif @@ -1187,26 +1344,31 @@ struct VST3PluginWindow : public AudioProcessorEditor, auto pos = (topComp->getLocalPoint (this, Point<int>()) * nativeScaleFactor).roundToInt(); #endif - recursiveResize = true; + const ScopedValueSetter<bool> recursiveResizeSetter (recursiveResize, true); ViewRect rect; if (wasResized && view->canResize() == kResultTrue) { - rect.right = (Steinberg::int32) roundToInt (getWidth() * nativeScaleFactor); - rect.bottom = (Steinberg::int32) roundToInt (getHeight() * nativeScaleFactor); + rect.right = (Steinberg::int32) roundToInt ((float) getWidth() * nativeScaleFactor); + rect.bottom = (Steinberg::int32) roundToInt ((float) getHeight() * nativeScaleFactor); view->checkSizeConstraint (&rect); - auto w = roundToInt (rect.getWidth() / nativeScaleFactor); - auto h = roundToInt (rect.getHeight() / nativeScaleFactor); + auto w = roundToInt ((float) rect.getWidth() / nativeScaleFactor); + auto h = roundToInt ((float) rect.getHeight() / nativeScaleFactor); + setSize (w, h); #if JUCE_WINDOWS + #if JUCE_WIN_PER_MONITOR_DPI_AWARE + setThreadDPIAwarenessForWindow (pluginHandle); + #endif + SetWindowPos (pluginHandle, 0, pos.x, pos.y, rect.getWidth(), rect.getHeight(), isVisible() ? SWP_SHOWWINDOW : SWP_HIDEWINDOW); - #elif JUCE_MAC + #else embeddedComponent.setBounds (getLocalBounds()); #endif @@ -1217,84 +1379,47 @@ struct VST3PluginWindow : public AudioProcessorEditor, warnOnFailure (view->getSize (&rect)); #if JUCE_WINDOWS + #if JUCE_WIN_PER_MONITOR_DPI_AWARE + setThreadDPIAwarenessForWindow (pluginHandle); + #endif + SetWindowPos (pluginHandle, 0, pos.x, pos.y, rect.getWidth(), rect.getHeight(), isVisible() ? SWP_SHOWWINDOW : SWP_HIDEWINDOW); - #elif JUCE_MAC + #else embeddedComponent.setBounds (0, 0, (int) rect.getWidth(), (int) rect.getHeight()); #endif } // Some plugins don't update their cursor correctly when mousing out the window Desktop::getInstance().getMainMouseSource().forceMouseCursorUpdate(); - - recursiveResize = false; } } + using ComponentMovementWatcher::componentMovedOrResized; + void componentVisibilityChanged() override { attachPluginWindow(); - #if ! JUCE_MAC - if (auto* topPeer = getTopLevelComponent()->getPeer()) - nativeScaleFactorChanged ((float) topPeer->getPlatformScaleFactor()); - #endif - if (! hasDoneInitialResize) resizeToFit(); componentMovedOrResized (true, true); } - #if ! JUCE_MAC + using ComponentMovementWatcher::componentVisibilityChanged; + + #if JUCE_WINDOWS || JUCE_LINUX void nativeScaleFactorChanged (double newScaleFactor) override { - if (pluginHandle == nullptr || approximatelyEqual ((float) newScaleFactor, nativeScaleFactor)) + if (pluginHandle == 0 || approximatelyEqual ((float) newScaleFactor, nativeScaleFactor)) return; nativeScaleFactor = (float) newScaleFactor; - if (pluginRespondsToDPIChanges) - { - Steinberg::IPlugViewContentScaleSupport* scaleInterface = nullptr; - view->queryInterface (Steinberg::IPlugViewContentScaleSupport::iid, (void**) &scaleInterface); - - if (scaleInterface != nullptr) - { - scaleInterface->setContentScaleFactor ((Steinberg::IPlugViewContentScaleSupport::ScaleFactor) nativeScaleFactor); - scaleInterface->release(); - } - } - else - { - // If the plug-in doesn't respond to scale factor changes then we need to scale our window, but - // we can't do it immediately as it may cause a recursive resize loop so fire up a timer - startTimerHz (4); - } - } - - bool willCauseRecursiveResize (int w, int h) - { - auto newScreenBounds = Rectangle<int> (w, h).withPosition (getScreenPosition()); - - return Desktop::getInstance().getDisplays().findDisplayForRect (newScreenBounds).scale != nativeScaleFactor; - } - - void timerCallback() override - { - ViewRect rect; - warnOnFailure (view->getSize (&rect)); - - auto w = roundToInt ((rect.right - rect.left) / nativeScaleFactor); - auto h = roundToInt ((rect.bottom - rect.top) / nativeScaleFactor); - - if (willCauseRecursiveResize (w, h)) - return; - - // window can be resized safely now - stopTimer(); - setSize (w, h); + if (scaleInterface != nullptr) + scaleInterface->setContentScaleFactor ((Steinberg::IPlugViewContentScaleSupport::ScaleFactor) nativeScaleFactor); } #endif @@ -1309,12 +1434,11 @@ struct VST3PluginWindow : public AudioProcessorEditor, tresult PLUGIN_API resizeView (IPlugView* incomingView, ViewRect* newSize) override { - if (incomingView != nullptr - && newSize != nullptr - && incomingView == view) + if (incomingView != nullptr && newSize != nullptr && incomingView == view) { resizeWithRect (embeddedComponent, *newSize, nativeScaleFactor); setSize (embeddedComponent.getWidth(), embeddedComponent.getHeight()); + return kResultTrue; } @@ -1323,6 +1447,68 @@ struct VST3PluginWindow : public AudioProcessorEditor, } private: + //============================================================================== + static void resizeWithRect (Component& comp, const ViewRect& rect, float scaleFactor) + { + comp.setBounds (roundToInt ((float) rect.left / scaleFactor), + roundToInt ((float) rect.top / scaleFactor), + jmax (10, std::abs (roundToInt ((float) rect.getWidth() / scaleFactor))), + jmax (10, std::abs (roundToInt ((float) rect.getHeight() / scaleFactor)))); + } + + void attachPluginWindow() + { + #if JUCE_MAC + if (pluginHandle == nil) + #else + if (pluginHandle == 0) + #endif + { + #if JUCE_WINDOWS + if (auto* topComp = getTopLevelComponent()) + { + peer.reset (embeddedComponent.createNewPeer (0, topComp->getWindowHandle())); + pluginHandle = (HandleFormat) peer->getNativeHandle(); + nativeScaleFactor = (float) peer->getPlatformScaleFactor(); + } + #else + embeddedComponent.setBounds (getLocalBounds()); + addAndMakeVisible (embeddedComponent); + #if JUCE_MAC + pluginHandle = (HandleFormat) embeddedComponent.getView(); + jassert (pluginHandle != nil); + #elif JUCE_LINUX + pluginHandle = (HandleFormat) embeddedComponent.getHostWindowID(); + jassert (pluginHandle != 0); + #endif + #endif + + #if JUCE_MAC + if (pluginHandle != nil) + #else + if (pluginHandle != 0) + #endif + warnOnFailure (view->attached ((void*) pluginHandle, defaultVST3WindowType)); + } + + #if ! JUCE_MAC + if (auto* topPeer = getTopLevelComponent()->getPeer()) + { + nativeScaleFactor = 1.0f; // force update + nativeScaleFactorChanged ((float) topPeer->getPlatformScaleFactor()); + } + #endif + } + + #if ! JUCE_MAC + void removeScaleFactorListeners() + { + for (int i = 0; i < ComponentPeer::getNumPeers(); ++i) + if (auto* p = ComponentPeer::getPeer (i)) + p->removeScaleFactorListener (this); + } + #endif + //============================================================================== Atomic<int> refCount { 1 }; ComSmartPtr<IPlugView> view; @@ -1343,6 +1529,9 @@ private: #elif JUCE_MAC AutoResizingNSViewComponentWithParent embeddedComponent; using HandleFormat = NSView*; + #elif JUCE_LINUX + XEmbedComponent embeddedComponent { true, false }; + using HandleFormat = Window; #else Component embeddedComponent; using HandleFormat = void*; @@ -1351,50 +1540,18 @@ private: HandleFormat pluginHandle = {}; bool recursiveResize = false; + #if ! JUCE_MAC + Steinberg::IPlugViewContentScaleSupport* scaleInterface = nullptr; + #endif + float nativeScaleFactor = 1.0f; bool hasDoneInitialResize = false; - bool pluginRespondsToDPIChanges = false; //============================================================================== - static void resizeWithRect (Component& comp, const ViewRect& rect, float scaleFactor) - { - comp.setBounds (roundToInt (rect.left / scaleFactor), - roundToInt (rect.top / scaleFactor), - jmax (10, std::abs (roundToInt (rect.getWidth() / scaleFactor))), - jmax (10, std::abs (roundToInt (rect.getHeight() / scaleFactor)))); - } - - void attachPluginWindow() - { - if (pluginHandle == nullptr) - { - #if JUCE_WINDOWS - if (auto* topComp = getTopLevelComponent()) - peer.reset (embeddedComponent.createNewPeer (0, topComp->getWindowHandle())); - else - peer = nullptr; - - if (peer != nullptr) - pluginHandle = (HandleFormat) peer->getNativeHandle(); - #elif JUCE_MAC - embeddedComponent.setBounds (getLocalBounds()); - addAndMakeVisible (embeddedComponent); - pluginHandle = (NSView*) embeddedComponent.getView(); - jassert (pluginHandle != nil); - #endif - - if (pluginHandle != nullptr) - warnOnFailure (view->attached (pluginHandle, defaultVST3WindowType)); - } - } - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (VST3PluginWindow) }; -#if JUCE_MSVC - #pragma warning (push) - #pragma warning (disable: 4996) // warning about overriding deprecated methods -#endif +JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4996) // warning about overriding deprecated methods //============================================================================== struct VST3ComponentHolder @@ -1407,11 +1564,6 @@ struct VST3ComponentHolder ~VST3ComponentHolder() { terminate(); - - component = nullptr; - host = nullptr; - factory = nullptr; - module = nullptr; } // transfers ownership to the plugin instance! @@ -1457,7 +1609,7 @@ struct VST3ComponentHolder PFactoryInfo factoryInfo; factory->getFactoryInfo (&factoryInfo); - auto classIdx = getClassIndex (module->name); + auto classIdx = getClassIndex (module->getName()); if (classIdx >= 0) { @@ -1506,8 +1658,8 @@ struct VST3ComponentHolder if (component->getBusInfo (Vst::kAudio, Vst::kOutput, i, bus) == kResultOk) totalNumOutputChannels += ((bus.flags & Vst::BusInfo::kDefaultActive) != 0 ? bus.channelCount : 0); - createPluginDescription (description, module->file, - factoryInfo.vendor, module->name, + createPluginDescription (description, module->getFile(), + factoryInfo.vendor, module->getName(), info, info2.get(), infoW.get(), totalNumInputChannels, totalNumOutputChannels); @@ -1521,7 +1673,8 @@ struct VST3ComponentHolder //============================================================================== bool initialise() { - if (isComponentInitialised) return true; + if (isComponentInitialised) + return true; #if JUCE_WINDOWS // On Windows it's highly advisable to create your plugins using the message thread, @@ -1533,7 +1686,7 @@ struct VST3ComponentHolder factory = ComSmartPtr<IPluginFactory> (module->getPluginFactory()); int classIdx; - if ((classIdx = getClassIndex (module->name)) < 0) + if ((classIdx = getClassIndex (module->getName())) < 0) return false; PClassInfo info; @@ -1556,9 +1709,12 @@ struct VST3ComponentHolder void terminate() { if (isComponentInitialised) + { component->terminate(); + isComponentInitialised = false; + } - isComponentInitialised = false; + component = nullptr; } //============================================================================== @@ -1717,6 +1873,36 @@ public: } ~VST3PluginInstance() override + { + struct VST3Deleter : public CallbackMessage + { + VST3Deleter (VST3PluginInstance& inInstance, WaitableEvent& inEvent) + : vst3Instance (inInstance), completionSignal (inEvent) + {} + + void messageCallback() override + { + vst3Instance.cleanup(); + completionSignal.signal(); + } + + VST3PluginInstance& vst3Instance; + WaitableEvent& completionSignal; + }; + + if (MessageManager::getInstance()->isThisTheMessageThread()) + { + cleanup(); + } + else + { + WaitableEvent completionEvent; + (new VST3Deleter (*this, completionEvent))->post(); + completionEvent.wait(); + } + } + + void cleanup() { jassert (getActiveEditor() == nullptr); // You must delete any editors before deleting the plugin instance! @@ -1796,7 +1982,7 @@ public: const String getName() const override { auto& module = holder->module; - return module != nullptr ? module->name : String(); + return module != nullptr ? module->getName() : String(); } void repopulateArrangements (Array<Vst::SpeakerArrangement>& inputArrangements, Array<Vst::SpeakerArrangement>& outputArrangements) const @@ -1881,6 +2067,8 @@ public: setLatencySamples (jmax (0, (int) processor->getLatencySamples())); cachedBusLayouts = getBusesLayout(); + setStateForAllMidiBuses (true); + warnOnFailure (holder->component->setActive (true)); warnOnFailureIfImplemented (processor->setProcessing (true)); @@ -2005,6 +2193,7 @@ public: q->clear(); } + midiMessages.clear(); MidiEventList::toMidiBuffer (midiMessages, *midiOutputs); inputParameterChanges->clearAllQueues(); @@ -2067,8 +2256,13 @@ public: outputArrangements.add (getVst3SpeakerArrangement (requested.isDisabled() ? getBus (false, i)->getLastEnabledLayout() : requested)); } - if (processor->setBusArrangements (inputArrangements.getRawDataPointer(), inputArrangements.size(), - outputArrangements.getRawDataPointer(), outputArrangements.size()) != kResultTrue) + // Some plug-ins will crash if you pass a nullptr to setBusArrangements! + Vst::SpeakerArrangement nullArrangement = {}; + auto* inputArrangementData = inputArrangements.isEmpty() ? &nullArrangement : inputArrangements.getRawDataPointer(); + auto* outputArrangementData = outputArrangements.isEmpty() ? &nullArrangement : outputArrangements.getRawDataPointer(); + + if (processor->setBusArrangements (inputArrangementData, inputArrangements.size(), + outputArrangementData, outputArrangements.size()) != kResultTrue) return false; // check if the layout matches the request @@ -2239,10 +2433,17 @@ public: //============================================================================== int getNumPrograms() override { return programNames.size(); } - const String getProgramName (int index) override { return programNames[index]; } - int getCurrentProgram() override { return jmax (0, (int) editController->getParamNormalized (programParameterID) * (programNames.size() - 1)); } + const String getProgramName (int index) override { return index >= 0 ? programNames[index] : String(); } void changeProgramName (int, const String&) override {} + int getCurrentProgram() override + { + if (programNames.size() > 0 && editController != nullptr) + return jmax (0, roundToInt (editController->getParamNormalized (programParameterID) * (programNames.size() - 1))); + + return 0; + } + void setCurrentProgram (int program) override { if (programNames.size() > 0 && editController != nullptr) @@ -2587,7 +2788,7 @@ private: bypassParam = param; std::function<AudioProcessorParameterGroup*(Vst::UnitID)> findOrCreateGroup; - findOrCreateGroup = [&groupMap, &infoMap, &findOrCreateGroup](Vst::UnitID groupID) + findOrCreateGroup = [&groupMap, &infoMap, &findOrCreateGroup] (Vst::UnitID groupID) { auto existingGroup = groupMap.find (groupID); @@ -2769,9 +2970,10 @@ private: midiOutputs->clear(); if (acceptsMidi()) - MidiEventList::toEventList (*midiInputs, midiBuffer, - destination.inputParameterChanges, - midiMapping); + MidiEventList::hostToPluginEventList (*midiInputs, + midiBuffer, + destination.inputParameterChanges, + midiMapping); destination.inputEvents = midiInputs; destination.outputEvents = midiOutputs; @@ -2880,9 +3082,7 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (VST3PluginInstance) }; -#if JUCE_MSVC - #pragma warning (pop) -#endif +JUCE_END_IGNORE_WARNINGS_MSVC //============================================================================== AudioPluginInstance* VST3ComponentHolder::createPluginInstance() @@ -3107,7 +3307,29 @@ bool VST3PluginFormat::setStateFromVSTPresetFile (AudioPluginInstance* api, cons void VST3PluginFormat::findAllTypesForFile (OwnedArray<PluginDescription>& results, const String& fileOrIdentifier) { if (fileMightContainThisPluginType (fileOrIdentifier)) - VST3ModuleHandle::getAllDescriptionsForFile (results, fileOrIdentifier); + { + /** + Since there is no apparent indication if a VST3 plugin is a shell or not, + we're stuck iterating through a VST3's factory, creating a description + for every housed plugin. + */ + + ComSmartPtr<IPluginFactory> pluginFactory (DLLHandleCache::getInstance()->findOrCreateHandle (fileOrIdentifier) + .getPluginFactory()); + + if (pluginFactory != nullptr) + { + ComSmartPtr<VST3HostContext> host (new VST3HostContext()); + DescriptionLister lister (host, pluginFactory); + lister.findDescriptionsAndPerform (File (fileOrIdentifier)); + + results.addCopiesOf (lister.list); + } + else + { + jassertfalse; + } + } } void VST3PluginFormat::createPluginInstance (const PluginDescription& description, @@ -3156,7 +3378,7 @@ bool VST3PluginFormat::fileMightContainThisPluginType (const String& fileOrIdent auto f = File::createFileWithoutCheckingPath (fileOrIdentifier); return f.hasFileExtension (".vst3") - #if JUCE_MAC + #if JUCE_MAC || JUCE_LINUX && f.exists(); #else && f.existsAsFile(); @@ -3190,9 +3412,7 @@ StringArray VST3PluginFormat::searchPathsForPlugins (const FileSearchPath& direc void VST3PluginFormat::recursiveFileSearch (StringArray& results, const File& directory, const bool recursive) { - DirectoryIterator iter (directory, false, "*", File::findFilesAndDirectories); - - while (iter.next()) + for (const auto& iter : RangedDirectoryIterator (directory, false, "*", File::findFilesAndDirectories)) { auto f = iter.getFile(); bool isPlugin = false; @@ -3216,7 +3436,7 @@ FileSearchPath VST3PluginFormat::getDefaultLocationsToSearch() #elif JUCE_MAC return FileSearchPath ("/Library/Audio/Plug-Ins/VST3;~/Library/Audio/Plug-Ins/VST3"); #else - return FileSearchPath(); + return FileSearchPath ("/usr/lib/vst3/;/usr/local/lib/vst3/;~/.vst3/"); #endif } diff --git a/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.h b/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.h index ddbd41e7..789fac9b 100644 --- a/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.h +++ b/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -27,7 +26,7 @@ namespace juce { -#if (JUCE_PLUGINHOST_VST3 && (JUCE_MAC || JUCE_WINDOWS)) || DOXYGEN +#if (JUCE_PLUGINHOST_VST3 && (JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX)) || DOXYGEN /** Implements a plugin format for VST3s. diff --git a/modules/juce_audio_processors/format_types/juce_VSTCommon.h b/modules/juce_audio_processors/format_types/juce_VSTCommon.h index 1eea8e32..e3bd4edc 100644 --- a/modules/juce_audio_processors/format_types/juce_VSTCommon.h +++ b/modules/juce_audio_processors/format_types/juce_VSTCommon.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -27,13 +26,6 @@ namespace juce { -//============================================================================== -#if JUCE_BIG_ENDIAN - #define JUCE_MULTICHAR_CONSTANT(a, b, c, d) (a | (((uint32) b) << 8) | (((uint32) c) << 16) | (((uint32) d) << 24)) -#else - #define JUCE_MULTICHAR_CONSTANT(a, b, c, d) (d | (((uint32) c) << 8) | (((uint32) b) << 16) | (((uint32) a) << 24)) -#endif - //============================================================================== /** Structure for VST speaker mappings @@ -49,14 +41,14 @@ struct SpeakerMappings : private AudioChannelSet // (inheritance only to give e bool matches (const Array<ChannelType>& chans) const noexcept { - const int n = sizeof (channels) / sizeof (ChannelType); + auto n = static_cast<int> (sizeof (channels) / sizeof (ChannelType)); for (int i = 0; i < n; ++i) { if (channels[i] == unknown) return (i == chans.size()); if (i == chans.size()) return (channels[i] == unknown); - if (channels[i] != chans.getUnchecked(i)) + if (channels[i] != chans.getUnchecked (i)) return false; } @@ -125,27 +117,56 @@ struct SpeakerMappings : private AudioChannelSet // (inheritance only to give e else if (channels == AudioChannelSet::create7point1SDDS()) return Vst2::kSpeakerArr71Cine; else if (channels == AudioChannelSet::quadraphonic()) return Vst2::kSpeakerArr40Music; - Array<AudioChannelSet::ChannelType> chans (channels.getChannelTypes()); - if (channels == AudioChannelSet::disabled()) return Vst2::kSpeakerArrEmpty; - for (const Mapping* m = getMappings(); m->vst2 != Vst2::kSpeakerArrEmpty; ++m) + auto chans = channels.getChannelTypes(); + + for (auto* m = getMappings(); m->vst2 != Vst2::kSpeakerArrEmpty; ++m) if (m->matches (chans)) return m->vst2; return Vst2::kSpeakerArrUserDefined; } + static void channelSetToVstArrangement (const AudioChannelSet& channels, Vst2::VstSpeakerArrangement& result) + { + result.type = channelSetToVstArrangementType (channels); + result.numChannels = channels.size(); + + for (int i = 0; i < result.numChannels; ++i) + { + auto& speaker = result.speakers[i]; + + zeromem (&speaker, sizeof (Vst2::VstSpeakerProperties)); + speaker.type = getSpeakerType (channels.getTypeOfChannel (i)); + } + } + /** Class to hold a speaker configuration */ class VstSpeakerConfigurationHolder { public: - VstSpeakerConfigurationHolder() { clear(); } - VstSpeakerConfigurationHolder (const Vst2::VstSpeakerArrangement& vstConfig) { operator= (vstConfig); } - VstSpeakerConfigurationHolder (const VstSpeakerConfigurationHolder& other) { operator= (other.get()); } + VstSpeakerConfigurationHolder() + { + clear(); + } + + VstSpeakerConfigurationHolder (const Vst2::VstSpeakerArrangement& vstConfig) + { + operator= (vstConfig); + } + + VstSpeakerConfigurationHolder (const VstSpeakerConfigurationHolder& other) + { + operator= (other.get()); + } + VstSpeakerConfigurationHolder (VstSpeakerConfigurationHolder&& other) - : storage (std::move (other.storage)) { other.clear(); } + : storage (std::move (other.storage)) + { + other.clear(); + } VstSpeakerConfigurationHolder (const AudioChannelSet& channels) { @@ -241,45 +262,47 @@ struct SpeakerMappings : private AudioChannelSet // (inheritance only to give e { Vst2::kSpeakerArr71Music, { left, right, centre, LFE, leftSurround, rightSurround, leftSurroundRear, rightSurroundRear, unknown } }, { Vst2::kSpeakerArr80Cine, { left, right, centre, leftSurround, rightSurround, topFrontLeft, topFrontRight, surround, unknown } }, { Vst2::kSpeakerArr80Music, { left, right, centre, leftSurround, rightSurround, surround, leftSurroundRear, rightSurroundRear, unknown } }, - { Vst2::kSpeakerArr81Cine, { left, right, centre, LFE, leftSurround, rightSurround, topFrontLeft, topFrontRight, surround, unknown } }, - { Vst2::kSpeakerArr81Music, { left, right, centre, LFE, leftSurround, rightSurround, surround, leftSurroundRear, rightSurroundRear, unknown } }, - { Vst2::kSpeakerArr102, { left, right, centre, LFE, leftSurround, rightSurround, topFrontLeft, topFrontCentre, topFrontRight, topRearLeft, topRearRight, LFE2, unknown } }, + { Vst2::kSpeakerArr81Cine, { left, right, centre, LFE, leftSurround, rightSurround, topFrontLeft, topFrontRight, surround, unknown } }, + { Vst2::kSpeakerArr81Music, { left, right, centre, LFE, leftSurround, rightSurround, surround, leftSurroundRear, rightSurroundRear, unknown } }, + { Vst2::kSpeakerArr102, { left, right, centre, LFE, leftSurround, rightSurround, topFrontLeft, topFrontCentre, topFrontRight, topRearLeft, topRearRight, LFE2, unknown } }, { Vst2::kSpeakerArrEmpty, { unknown } } }; return mappings; } - static inline int32 getSpeakerType (AudioChannelSet::ChannelType type) noexcept + static int32 getSpeakerType (AudioChannelSet::ChannelType type) noexcept { - switch (type) + static const std::map<AudioChannelSet::ChannelType, int32> speakerTypeMap = { - case AudioChannelSet::left: return Vst2::kSpeakerL; - case AudioChannelSet::right: return Vst2::kSpeakerR; - case AudioChannelSet::centre: return Vst2::kSpeakerC; - case AudioChannelSet::LFE: return Vst2::kSpeakerLfe; - case AudioChannelSet::leftSurround: return Vst2::kSpeakerLs; - case AudioChannelSet::rightSurround: return Vst2::kSpeakerRs; - case AudioChannelSet::leftCentre: return Vst2::kSpeakerLc; - case AudioChannelSet::rightCentre: return Vst2::kSpeakerRc; - case AudioChannelSet::surround: return Vst2::kSpeakerS; - case AudioChannelSet::leftSurroundRear: return Vst2::kSpeakerSl; - case AudioChannelSet::rightSurroundRear: return Vst2::kSpeakerSr; - case AudioChannelSet::topMiddle: return Vst2::kSpeakerTm; - case AudioChannelSet::topFrontLeft: return Vst2::kSpeakerTfl; - case AudioChannelSet::topFrontCentre: return Vst2::kSpeakerTfc; - case AudioChannelSet::topFrontRight: return Vst2::kSpeakerTfr; - case AudioChannelSet::topRearLeft: return Vst2::kSpeakerTrl; - case AudioChannelSet::topRearCentre: return Vst2::kSpeakerTrc; - case AudioChannelSet::topRearRight: return Vst2::kSpeakerTrr; - case AudioChannelSet::LFE2: return Vst2::kSpeakerLfe2; - default: break; - } + { AudioChannelSet::left, Vst2::kSpeakerL }, + { AudioChannelSet::right, Vst2::kSpeakerR }, + { AudioChannelSet::centre, Vst2::kSpeakerC }, + { AudioChannelSet::LFE, Vst2::kSpeakerLfe }, + { AudioChannelSet::leftSurround, Vst2::kSpeakerLs }, + { AudioChannelSet::rightSurround, Vst2::kSpeakerRs }, + { AudioChannelSet::leftCentre, Vst2::kSpeakerLc }, + { AudioChannelSet::rightCentre, Vst2::kSpeakerRc }, + { AudioChannelSet::surround, Vst2::kSpeakerS }, + { AudioChannelSet::leftSurroundRear, Vst2::kSpeakerSl }, + { AudioChannelSet::rightSurroundRear, Vst2::kSpeakerSr }, + { AudioChannelSet::topMiddle, Vst2::kSpeakerTm }, + { AudioChannelSet::topFrontLeft, Vst2::kSpeakerTfl }, + { AudioChannelSet::topFrontCentre, Vst2::kSpeakerTfc }, + { AudioChannelSet::topFrontRight, Vst2::kSpeakerTfr }, + { AudioChannelSet::topRearLeft, Vst2::kSpeakerTrl }, + { AudioChannelSet::topRearCentre, Vst2::kSpeakerTrc }, + { AudioChannelSet::topRearRight, Vst2::kSpeakerTrr }, + { AudioChannelSet::LFE2, Vst2::kSpeakerLfe2 } + }; + + if (speakerTypeMap.find (type) == speakerTypeMap.end()) + return 0; - return 0; + return speakerTypeMap.at (type); } - static inline AudioChannelSet::ChannelType getChannelType (int32 type) noexcept + static AudioChannelSet::ChannelType getChannelType (int32 type) noexcept { switch (type) { diff --git a/modules/juce_audio_processors/format_types/juce_VSTMidiEventList.h b/modules/juce_audio_processors/format_types/juce_VSTMidiEventList.h index 3b6d3164..49f0d3b3 100644 --- a/modules/juce_audio_processors/format_types/juce_VSTMidiEventList.h +++ b/modules/juce_audio_processors/format_types/juce_VSTMidiEventList.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp b/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp index bdc935fc..23d7ae17 100644 --- a/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp +++ b/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -29,24 +28,13 @@ //============================================================================== #undef PRAGMA_ALIGN_SUPPORTED -#if JUCE_MSVC - #pragma warning (push) - #pragma warning (disable: 4996) -#elif ! JUCE_MINGW - #define __cdecl -#endif -#if JUCE_CLANG - #if __has_warning("-Wzero-as-null-pointer-constant") - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" - #endif +#if ! JUCE_MINGW && ! JUCE_MSVC + #define __cdecl #endif -#if JUCE_GCC - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" -#endif +JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wzero-as-null-pointer-constant") +JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4996) #define VST_FORCE_DEPRECATED 0 #define JUCE_VSTINTERFACE_H_INCLUDED 1 @@ -64,20 +52,10 @@ namespace Vst2 #include "juce_VSTCommon.h" -#if JUCE_MSVC - #pragma warning (pop) - #pragma warning (disable: 4355) // ("this" used in initialiser list warning) -#endif +JUCE_END_IGNORE_WARNINGS_GCC_LIKE +JUCE_END_IGNORE_WARNINGS_MSVC -#if JUCE_CLANG - #if __has_warning("-Wzero-as-null-pointer-constant") - #pragma clang diagnostic pop - #endif -#endif - -#if JUCE_GCC - #pragma GCC diagnostic pop -#endif +JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4355) #include "juce_VSTMidiEventList.h" @@ -104,6 +82,9 @@ namespace Vst2 //============================================================================== namespace juce { +#if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE + extern void setThreadDPIAwarenessForWindow (HWND); +#endif //============================================================================== namespace @@ -197,7 +178,7 @@ namespace #elif JUCE_LINUX || JUCE_IOS || JUCE_ANDROID timeval micro; gettimeofday (&micro, nullptr); - return micro.tv_usec * 1000.0; + return (double) micro.tv_usec * 1000.0; #elif JUCE_MAC UnsignedWide micro; Microseconds (&micro); @@ -263,10 +244,8 @@ namespace Window* childWindows; unsigned int numChildren = 0; - { - ScopedXDisplay xDisplay; - XQueryTree (xDisplay.display, windowToCheck, &rootWindow, &parentWindow, &childWindows, &numChildren); - } + X11Symbols::getInstance()->xQueryTree (XWindowSystem::getInstance()->getDisplay(), + windowToCheck, &rootWindow, &parentWindow, &childWindows, &numChildren); if (numChildren > 0) return childWindows [0]; @@ -467,8 +446,8 @@ private: } else { - entry->range.low = curEntry / (float) numEntries; - entry->range.high = (curEntry + 1) / (float) numEntries; + entry->range.low = (float) curEntry / (float) numEntries; + entry->range.high = (float) (curEntry + 1) / (float) numEntries; entry->range.inclusiveLow = true; entry->range.inclusiveHigh = (curEntry == numEntries - 1); @@ -846,10 +825,7 @@ private: static const int defaultVSTSampleRateValue = 44100; static const int defaultVSTBlockSizeValue = 512; -#if JUCE_MSVC - #pragma warning (push) - #pragma warning (disable: 4996) // warning about overriding deprecated methods -#endif +JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4996) //============================================================================== struct VSTPluginInstance : public AudioPluginInstance, @@ -1593,7 +1569,7 @@ struct VSTPluginInstance : public AudioPluginInstance, } } - return programNames [index]; + return {}; } void changeProgramName (int index, const String& newName) override @@ -2053,7 +2029,8 @@ private: String name; CriticalSection lock; std::atomic<bool> wantsMidiMessages { false }; - bool initialised = false, isPowerOn = false; + bool initialised = false; + std::atomic<bool> isPowerOn { false }; bool lastProcessBlockCallWasBypass = false, vstSupportsBypass = false; mutable StringArray programNames; AudioBuffer<float> outOfPlaceBuffer; @@ -2104,16 +2081,11 @@ private: pointer_sized_int getVSTTime() noexcept { - #if JUCE_MSVC - #pragma warning (push) - #pragma warning (disable: 4311) - #endif + JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4311) return (pointer_sized_int) &vstHostTime; - #if JUCE_MSVC - #pragma warning (pop) - #endif + JUCE_END_IGNORE_WARNINGS_MSVC } void handleIdle() @@ -2388,11 +2360,12 @@ private: case AudioPlayHead::fps30: setHostTimeFrameRate (Vst2::kVstSmpte30fps, 30.0, position.timeInSeconds); break; case AudioPlayHead::fps60: setHostTimeFrameRate (Vst2::kVstSmpte60fps, 60.0, position.timeInSeconds); break; - case AudioPlayHead::fps23976: setHostTimeFrameRateDrop (Vst2::kVstSmpte239fps, 24.0, position.timeInSeconds); break; - case AudioPlayHead::fps2997: setHostTimeFrameRateDrop (Vst2::kVstSmpte2997fps, 30.0, position.timeInSeconds); break; + case AudioPlayHead::fps23976: setHostTimeFrameRateDrop (Vst2::kVstSmpte239fps, 24.0, position.timeInSeconds); break; + case AudioPlayHead::fps2997: setHostTimeFrameRateDrop (Vst2::kVstSmpte2997fps, 30.0, position.timeInSeconds); break; case AudioPlayHead::fps2997drop: setHostTimeFrameRateDrop (Vst2::kVstSmpte2997dfps, 30.0, position.timeInSeconds); break; case AudioPlayHead::fps30drop: setHostTimeFrameRateDrop (Vst2::kVstSmpte30dfps, 30.0, position.timeInSeconds); break; - case AudioPlayHead::fps60drop: setHostTimeFrameRateDrop (Vst2::kVstSmpte599fps, 60.0, position.timeInSeconds); break; + case AudioPlayHead::fps60drop: setHostTimeFrameRateDrop (Vst2::kVstSmpte599fps, 60.0, position.timeInSeconds); break; + case AudioPlayHead::fpsUnknown: default: break; } @@ -2416,13 +2389,9 @@ private: midiEventsToSend.clear(); midiEventsToSend.ensureSize (1); - MidiBuffer::Iterator iter (midiMessages); - const uint8* midiData; - int numBytesOfMidiData, samplePosition; - - while (iter.getNextEvent (midiData, numBytesOfMidiData, samplePosition)) - midiEventsToSend.addEvent (midiData, numBytesOfMidiData, - jlimit (0, numSamples - 1, samplePosition)); + for (const auto metadata : midiMessages) + midiEventsToSend.addEvent (metadata.data, metadata.numBytes, + jlimit (0, numSamples - 1, metadata.samplePosition)); vstEffect->dispatcher (vstEffect, Vst2::effProcessEvents, 0, 0, midiEventsToSend.events, 0); } @@ -2711,16 +2680,20 @@ private: { switch (getVstCategory()) { - case Vst2::kPlugCategEffect: return "Effect"; - case Vst2::kPlugCategSynth: return "Synth"; - case Vst2::kPlugCategAnalysis: return "Analysis"; - case Vst2::kPlugCategMastering: return "Mastering"; - case Vst2::kPlugCategSpacializer: return "Spacial"; - case Vst2::kPlugCategRoomFx: return "Reverb"; - case Vst2::kPlugSurroundFx: return "Surround"; - case Vst2::kPlugCategRestoration: return "Restoration"; - case Vst2::kPlugCategGenerator: return "Tone generation"; - default: break; + case Vst2::kPlugCategEffect: return "Effect"; + case Vst2::kPlugCategSynth: return "Synth"; + case Vst2::kPlugCategAnalysis: return "Analysis"; + case Vst2::kPlugCategMastering: return "Mastering"; + case Vst2::kPlugCategSpacializer: return "Spacial"; + case Vst2::kPlugCategRoomFx: return "Reverb"; + case Vst2::kPlugSurroundFx: return "Surround"; + case Vst2::kPlugCategRestoration: return "Restoration"; + case Vst2::kPlugCategGenerator: return "Tone generation"; + case Vst2::kPlugCategOfflineProcess: return "Offline Process"; + case Vst2::kPlugCategShell: return "Shell"; + case Vst2::kPlugCategUnknown: return "Unknown"; + case Vst2::kPlugCategMaxCount: + default: break; } return nullptr; @@ -2775,9 +2748,7 @@ public: { #if JUCE_LINUX pluginWindow = None; - display = XWindowSystem::getInstance()->displayRef(); ignoreUnused (pluginRefusesToResize, alreadyInside); - #elif JUCE_MAC ignoreUnused (recursiveResize, pluginRefusesToResize, alreadyInside); @@ -2818,18 +2789,12 @@ public: carbonWrapper.reset(); #endif cocoaWrapper.reset(); - #elif JUCE_LINUX - display = XWindowSystem::getInstance()->displayUnref(); + #else + removeScaleFactorListeners(); #endif activeVSTWindows.removeFirstMatchingValue (this); plugin.editorBeingDeleted (this); - - #if ! JUCE_MAC - for (int i = 0; i < ComponentPeer::getNumPeers(); ++i) - if (auto* peer = ComponentPeer::getPeer (i)) - peer->removeScaleFactorListener (this); - #endif } //============================================================================== @@ -2871,8 +2836,9 @@ public: { auto clip = g.getClipBounds(); - XClearArea (display, pluginWindow, clip.getX(), clip.getY(), - static_cast<unsigned int> (clip.getWidth()), static_cast<unsigned int> (clip.getHeight()), True); + X11Symbols::getInstance()->xClearArea (display, pluginWindow, clip.getX(), clip.getY(), + static_cast<unsigned int> (clip.getWidth()), + static_cast<unsigned int> (clip.getHeight()), True); } #endif } @@ -2897,17 +2863,26 @@ public: #if JUCE_WINDOWS if (pluginHWND != 0) - MoveWindow (pluginHWND, pos.getX(), pos.getY(), roundToInt (getWidth() * nativeScaleFactor), roundToInt (getHeight() * nativeScaleFactor), TRUE); + { + #if JUCE_WIN_PER_MONITOR_DPI_AWARE + setThreadDPIAwarenessForWindow (pluginHWND); + #endif + + MoveWindow (pluginHWND, pos.getX(), pos.getY(), + roundToInt (getWidth() * nativeScaleFactor), + roundToInt (getHeight() * nativeScaleFactor), + TRUE); + } #elif JUCE_LINUX if (pluginWindow != 0) { - XMoveResizeWindow (display, pluginWindow, - pos.getX(), pos.getY(), - static_cast<unsigned int> (roundToInt (getWidth() * nativeScaleFactor)), - static_cast<unsigned int> (roundToInt (getHeight() * nativeScaleFactor))); + X11Symbols::getInstance()->xMoveResizeWindow (display, pluginWindow, + pos.getX(), pos.getY(), + static_cast<unsigned int> (roundToInt ((float) getWidth() * nativeScaleFactor)), + static_cast<unsigned int> (roundToInt ((float) getHeight() * nativeScaleFactor))); - XMapRaised (display, pluginWindow); - XFlush (display); + X11Symbols::getInstance()->xMapRaised (display, pluginWindow); + X11Symbols::getInstance()->xFlush (display); } #endif @@ -2928,7 +2903,13 @@ public: setScaleFactorAndDispatchMessage (peer->getPlatformScaleFactor()); #if JUCE_LINUX - MessageManager::callAsync ([this] { componentMovedOrResized (true, true); }); + SafePointer<VSTPluginWindow> safeThis (this); + + MessageManager::callAsync ([this, safeThis] + { + if (safeThis != nullptr) + componentMovedOrResized (true, true); + }); #else componentMovedOrResized (true, true); #endif @@ -2941,6 +2922,8 @@ public: closePluginWindow(); openPluginWindow(); + removeScaleFactorListeners(); + if (auto* peer = getTopLevelComponent()->getPeer()) peer->addScaleFactorListener (this); @@ -2950,16 +2933,6 @@ public: void nativeScaleFactorChanged (double newScaleFactor) override { setScaleFactorAndDispatchMessage (newScaleFactor); - - #if JUCE_WINDOWS - Vst2::ERect* rect = nullptr; - dispatch (Vst2::effEditGetRect, 0, 0, &rect, 0); - - if (! isWindowSizeCorrectForPlugin (roundToInt ((rect->right - rect->left) / nativeScaleFactor), - roundToInt ((rect->bottom - rect->top) / nativeScaleFactor))) - return; - #endif - componentMovedOrResized (true, true); } @@ -2972,8 +2945,8 @@ public: if (pluginRespondsToDPIChanges) dispatch (Vst2::effVendorSpecific, - JUCE_MULTICHAR_CONSTANT ('P', 'r', 'e', 'S'), - JUCE_MULTICHAR_CONSTANT ('A', 'e', 'C', 's'), + (int) ByteOrder::bigEndianInt ("PreS"), + (int) ByteOrder::bigEndianInt ("AeCs"), nullptr, nativeScaleFactor); } #endif @@ -3037,26 +3010,7 @@ public: } private: - VSTPluginInstance& plugin; - bool isOpen = false, recursiveResize = false; - bool pluginWantsKeys = false, pluginRefusesToResize = false, alreadyInside = false; - - #if ! JUCE_MAC - bool pluginRespondsToDPIChanges = false; - #endif - - #if ! JUCE_MAC - float nativeScaleFactor = 1.0f; - #if JUCE_WINDOWS - HWND pluginHWND = {}; - void* originalWndProc = {}; - int sizeCheckCount = 0; - #elif JUCE_LINUX - ::Display* display; - Window pluginWindow; - #endif - #endif - + //============================================================================== // This is a workaround for old Mackie plugins that crash if their // window is deleted more than once. bool shouldAvoidDeletingWindow() const @@ -3129,33 +3083,13 @@ private: if (auto* peer = getTopLevelComponent()->getPeer()) setScaleFactorAndDispatchMessage (peer->getPlatformScaleFactor()); - #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE - std::unique_ptr<ScopedDPIAwarenessDisabler> dpiDisabler; - - if (! pluginRespondsToDPIChanges) - dpiDisabler.reset (new ScopedDPIAwarenessDisabler()); - #endif - Vst2::ERect* rect = nullptr; - dispatch (Vst2::effEditGetRect, 0, 0, &rect, 0); - - #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE - // some plug-ins are fussy about this - dpiDisabler.reset (nullptr); - #endif - - dispatch (Vst2::effEditOpen, 0, 0, getWindowHandle(), 0); - - #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE - if (! pluginRespondsToDPIChanges) - dpiDisabler.reset (new ScopedDPIAwarenessDisabler()); - #endif - // do this before and after like in the steinberg example dispatch (Vst2::effEditGetRect, 0, 0, &rect, 0); + dispatch (Vst2::effEditOpen, 0, 0, getWindowHandle(), 0); + dispatch (Vst2::effEditGetRect, 0, 0, &rect, 0); // do this before and after like in the steinberg example dispatch (Vst2::effGetProgram, 0, 0, nullptr, 0); // also in steinberg code - // Install keyboard hooks pluginWantsKeys = (dispatch (Vst2::effKeysRequired, 0, 0, nullptr, 0) == 0); #if JUCE_WINDOWS @@ -3169,8 +3103,7 @@ private: return; } - #pragma warning (push) - #pragma warning (disable: 4244) + JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4244) if (! pluginWantsKeys) { @@ -3178,11 +3111,7 @@ private: SetWindowLongPtr (pluginHWND, GWLP_WNDPROC, (LONG_PTR) vstHookWndProc); } - #pragma warning (pop) - - #if JUCE_WIN_PER_MONITOR_DPI_AWARE - dpiDisabler.reset (nullptr); - #endif + JUCE_END_IGNORE_WARNINGS_MSVC RECT r; GetWindowRect (pluginHWND, &r); @@ -3200,6 +3129,10 @@ private: // very dodgy logic to decide which size is right. if (std::abs (rw - w) > 350 || std::abs (rh - h) > 350) { + #if JUCE_WIN_PER_MONITOR_DPI_AWARE + setThreadDPIAwarenessForWindow (pluginHWND); + #endif + SetWindowPos (pluginHWND, 0, 0, 0, roundToInt (rw * nativeScaleFactor), roundToInt (rh * nativeScaleFactor), SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER); @@ -3234,11 +3167,11 @@ private: } if (pluginWindow != 0) - XMapRaised (display, pluginWindow); + X11Symbols::getInstance()->xMapRaised (display, pluginWindow); #endif - w = roundToInt (w / nativeScaleFactor); - h = roundToInt (h / nativeScaleFactor); + w = roundToInt ((float) w / nativeScaleFactor); + h = roundToInt ((float) h / nativeScaleFactor); // double-check it's not too tiny w = jmax (w, 32); @@ -3253,6 +3186,13 @@ private: startTimer (18 + juce::Random::getSystemRandom().nextInt (5)); repaint(); } + + void removeScaleFactorListeners() + { + for (int i = 0; i < ComponentPeer::getNumPeers(); ++i) + if (auto* peer = ComponentPeer::getPeer (i)) + peer->removeScaleFactorListener (this); + } #endif //============================================================================== @@ -3270,11 +3210,10 @@ private: stopTimer(); #if JUCE_WINDOWS - #pragma warning (push) - #pragma warning (disable: 4244) + JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4244) if (originalWndProc != 0 && pluginHWND != 0 && IsWindow (pluginHWND)) SetWindowLongPtr (pluginHWND, GWLP_WNDPROC, (LONG_PTR) originalWndProc); - #pragma warning (pop) + JUCE_END_IGNORE_WARNINGS_MSVC originalWndProc = 0; pluginHWND = 0; @@ -3295,8 +3234,7 @@ private: bool willCauseRecursiveResize (int w, int h) { auto newScreenBounds = Rectangle<int> (w, h).withPosition (getScreenPosition()); - - return Desktop::getInstance().getDisplays().findDisplayForRect (newScreenBounds).scale != nativeScaleFactor; + return Desktop::getInstance().getDisplays().getDisplayForRect (newScreenBounds)->scale != nativeScaleFactor; } bool isWindowSizeCorrectForPlugin (int w, int h) @@ -3309,7 +3247,6 @@ private: void checkPluginWindowSize() { - #if JUCE_WIN_PER_MONITOR_DPI_AWARE if (! pluginRespondsToDPIChanges) { Vst2::ERect* rect = nullptr; @@ -3328,23 +3265,6 @@ private: sizeCheckCount = 0; } } - #else - { - RECT r; - GetWindowRect (pluginHWND, &r); - - auto w = r.right - r.left; - auto h = r.bottom - r.top; - - if (isShowing() && w > 0 && h > 0 - && (w != getWidth() || h != getHeight()) - && !pluginRefusesToResize) - { - setSize (w, h); - sizeCheckCount = 0; - } - } - #endif } // hooks to get keyboard events from VST windows.. @@ -3386,107 +3306,125 @@ private: #endif //============================================================================== - #if JUCE_MAC - #if JUCE_SUPPORT_CARBON - struct CarbonWrapperComponent : public CarbonViewWrapperComponent - { - CarbonWrapperComponent (VSTPluginWindow& w) : owner (w) - { - keepPluginWindowWhenHidden = w.shouldAvoidDeletingWindow(); - setRepaintsChildHIViewWhenCreated (w.shouldRepaintCarbonWindowWhenCreated()); - } - - ~CarbonWrapperComponent() - { - deleteWindow(); - } - - HIViewRef attachView (WindowRef windowRef, HIViewRef /*rootView*/) override - { - owner.openPluginWindow (windowRef); - return {}; - } - - void removeView (HIViewRef) override - { - if (owner.isOpen) - { - owner.isOpen = false; - owner.dispatch (Vst2::effEditClose, 0, 0, 0, 0); - owner.dispatch (Vst2::effEditSleep, 0, 0, 0, 0); - } - } - - bool getEmbeddedViewSize (int& w, int& h) override - { - Vst2::ERect* rect = nullptr; - owner.dispatch (Vst2::effEditGetRect, 0, 0, &rect, 0); - w = rect->right - rect->left; - h = rect->bottom - rect->top; - return true; - } - - void handleMouseDown (int x, int y) override - { - if (! alreadyInside) - { - alreadyInside = true; - getTopLevelComponent()->toFront (true); - owner.dispatch (Vst2::effEditMouse, x, y, 0, 0); - alreadyInside = false; - } - else - { - PostEvent (::mouseDown, 0); - } - } - - void handlePaint() override - { - if (auto* peer = getPeer()) - { - auto pos = peer->globalToLocal (getScreenPosition()); - Vst2::ERect r; - r.left = (int16) pos.getX(); - r.top = (int16) pos.getY(); - r.right = (int16) (r.left + getWidth()); - r.bottom = (int16) (r.top + getHeight()); - - owner.dispatch (Vst2::effEditDraw, 0, 0, &r, 0); - } - } + #if JUCE_MAC + #if JUCE_SUPPORT_CARBON + struct CarbonWrapperComponent : public CarbonViewWrapperComponent + { + CarbonWrapperComponent (VSTPluginWindow& w) : owner (w) + { + keepPluginWindowWhenHidden = w.shouldAvoidDeletingWindow(); + setRepaintsChildHIViewWhenCreated (w.shouldRepaintCarbonWindowWhenCreated()); + } + + ~CarbonWrapperComponent() + { + deleteWindow(); + } + + HIViewRef attachView (WindowRef windowRef, HIViewRef /*rootView*/) override + { + owner.openPluginWindow (windowRef); + return {}; + } + + void removeView (HIViewRef) override + { + if (owner.isOpen) + { + owner.isOpen = false; + owner.dispatch (Vst2::effEditClose, 0, 0, 0, 0); + owner.dispatch (Vst2::effEditSleep, 0, 0, 0, 0); + } + } + + bool getEmbeddedViewSize (int& w, int& h) override + { + Vst2::ERect* rect = nullptr; + owner.dispatch (Vst2::effEditGetRect, 0, 0, &rect, 0); + w = rect->right - rect->left; + h = rect->bottom - rect->top; + return true; + } + + void handleMouseDown (int x, int y) override + { + if (! alreadyInside) + { + alreadyInside = true; + getTopLevelComponent()->toFront (true); + owner.dispatch (Vst2::effEditMouse, x, y, 0, 0); + alreadyInside = false; + } + else + { + PostEvent (::mouseDown, 0); + } + } + + void handlePaint() override + { + if (auto* peer = getPeer()) + { + auto pos = peer->globalToLocal (getScreenPosition()); + Vst2::ERect r; + r.left = (int16) pos.getX(); + r.top = (int16) pos.getY(); + r.right = (int16) (r.left + getWidth()); + r.bottom = (int16) (r.top + getHeight()); + + owner.dispatch (Vst2::effEditDraw, 0, 0, &r, 0); + } + } + + private: + VSTPluginWindow& owner; + bool alreadyInside = false; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CarbonWrapperComponent) + }; + + friend struct CarbonWrapperComponent; + std::unique_ptr<CarbonWrapperComponent> carbonWrapper; + #endif + + std::unique_ptr<AutoResizingNSViewComponentWithParent> cocoaWrapper; + + void resized() override + { + #if JUCE_SUPPORT_CARBON + if (carbonWrapper != nullptr) + carbonWrapper->setSize (getWidth(), getHeight()); + #endif - private: - VSTPluginWindow& owner; - bool alreadyInside = false; + if (cocoaWrapper != nullptr) + cocoaWrapper->setSize (getWidth(), getHeight()); + } + #endif - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CarbonWrapperComponent) - }; + //============================================================================== + VSTPluginInstance& plugin; + bool isOpen = false, recursiveResize = false; + bool pluginWantsKeys = false, pluginRefusesToResize = false, alreadyInside = false; - friend struct CarbonWrapperComponent; - std::unique_ptr<CarbonWrapperComponent> carbonWrapper; + #if ! JUCE_MAC + bool pluginRespondsToDPIChanges = false; + float nativeScaleFactor = 1.0f; + #if JUCE_WINDOWS + HWND pluginHWND = {}; + void* originalWndProc = {}; + int sizeCheckCount = 0; + #elif JUCE_LINUX + ::Display* display = XWindowSystem::getInstance()->getDisplay(); + Window pluginWindow = 0; + #endif #endif - std::unique_ptr<AutoResizingNSViewComponentWithParent> cocoaWrapper; - - void resized() override - { - #if JUCE_SUPPORT_CARBON - if (carbonWrapper != nullptr) - carbonWrapper->setSize (getWidth(), getHeight()); - #endif - - if (cocoaWrapper != nullptr) - cocoaWrapper->setSize (getWidth(), getHeight()); - } - #endif - + //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (VSTPluginWindow) }; #endif -#if JUCE_MSVC - #pragma warning (pop) -#endif + +JUCE_END_IGNORE_WARNINGS_MSVC //============================================================================== AudioProcessorEditor* VSTPluginInstance::createEditor() @@ -3669,9 +3607,7 @@ void VSTPluginFormat::recursiveFileSearch (StringArray& results, const File& dir { // avoid allowing the dir iterator to be recursive, because we want to avoid letting it delve inside // .component or .vst directories. - DirectoryIterator iter (dir, false, "*", File::findFilesAndDirectories); - - while (iter.next()) + for (const auto& iter : RangedDirectoryIterator (dir, false, "*", File::findFilesAndDirectories)) { auto f = iter.getFile(); bool isPlugin = false; @@ -3701,7 +3637,6 @@ FileSearchPath VSTPluginFormat::getDefaultLocationsToSearch() FileSearchPath paths; paths.add (WindowsRegistry::getValue ("HKEY_LOCAL_MACHINE\\Software\\VST\\VSTPluginsPath")); paths.addIfNotAlreadyThere (programFiles + "\\Steinberg\\VstPlugins"); - paths.removeNonExistentPaths(); paths.addIfNotAlreadyThere (programFiles + "\\VstPlugins"); paths.removeRedundantPaths(); return paths; @@ -3808,4 +3743,6 @@ void VSTPluginFormat::aboutToScanVSTShellPlugin (const PluginDescription&) {} } // namespace juce +JUCE_END_IGNORE_WARNINGS_MSVC + #endif diff --git a/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.h b/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.h index 90e606a4..6e32d9af 100644 --- a/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.h +++ b/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_processors/juce_audio_processors.cpp b/modules/juce_audio_processors/juce_audio_processors.cpp index 26aef816..ac194a19 100644 --- a/modules/juce_audio_processors/juce_audio_processors.cpp +++ b/modules/juce_audio_processors/juce_audio_processors.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -35,6 +34,7 @@ #define JUCE_CORE_INCLUDE_NATIVE_HEADERS 1 #define JUCE_CORE_INCLUDE_OBJC_HELPERS 1 +#define JUCE_GUI_BASICS_INCLUDE_XHEADERS 1 #include "juce_audio_processors.h" #include <juce_gui_extra/juce_gui_extra.h> @@ -43,17 +43,18 @@ #if JUCE_MAC #if JUCE_SUPPORT_CARBON && (JUCE_PLUGINHOST_VST || JUCE_PLUGINHOST_AU) #include <Carbon/Carbon.h> - #include "../juce_gui_extra/native/juce_mac_CarbonViewWrapperComponent.h" + #include <juce_gui_extra/native/juce_mac_CarbonViewWrapperComponent.h> #endif #endif -#if JUCE_PLUGINHOST_VST && JUCE_LINUX +#if (JUCE_PLUGINHOST_VST || JUCE_PLUGINHOST_VST3) && JUCE_LINUX #include <X11/Xlib.h> #include <X11/Xutil.h> + #include <sys/utsname.h> #undef KeyPress #endif -#if ! JUCE_WINDOWS && ! JUCE_MAC +#if ! JUCE_WINDOWS && ! JUCE_MAC && ! JUCE_LINUX #undef JUCE_PLUGINHOST_VST3 #define JUCE_PLUGINHOST_VST3 0 #endif @@ -66,8 +67,10 @@ namespace juce { -static inline bool arrayContainsPlugin (const OwnedArray<PluginDescription>& list, - const PluginDescription& desc) +#if JUCE_PLUGINHOST_VST || (JUCE_PLUGINHOST_LADSPA && JUCE_LINUX) + +static bool arrayContainsPlugin (const OwnedArray<PluginDescription>& list, + const PluginDescription& desc) { for (auto* p : list) if (p->isDuplicateOf (desc)) @@ -76,6 +79,8 @@ static inline bool arrayContainsPlugin (const OwnedArray<PluginDescription>& lis return false; } +#endif + #if JUCE_MAC || JUCE_IOS #if JUCE_IOS @@ -129,12 +134,7 @@ struct AutoResizingNSViewComponentWithParent : public AutoResizingNSViewCompone } // namespace juce -#if JUCE_CLANG - #pragma clang diagnostic ignored "-Wdeprecated-declarations" - #if __has_warning("-Wcast-align") - #pragma clang diagnostic ignored "-Wcast-align" - #endif -#endif +JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wdeprecated-declarations", "-Wcast-align") #include "format/juce_AudioPluginFormat.cpp" #include "format/juce_AudioPluginFormatManager.cpp" @@ -159,4 +159,5 @@ struct AutoResizingNSViewComponentWithParent : public AutoResizingNSViewCompone #include "utilities/juce_AudioParameterInt.cpp" #include "utilities/juce_AudioParameterBool.cpp" #include "utilities/juce_AudioParameterChoice.cpp" +#include "utilities/juce_ParameterAttachments.cpp" #include "utilities/juce_AudioProcessorValueTreeState.cpp" diff --git a/modules/juce_audio_processors/juce_audio_processors.h b/modules/juce_audio_processors/juce_audio_processors.h index 972e60f0..67d5074c 100644 --- a/modules/juce_audio_processors/juce_audio_processors.h +++ b/modules/juce_audio_processors/juce_audio_processors.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -29,14 +28,14 @@ The block below describes the properties of this module, and is read by the Projucer to automatically generate project code that uses it. For details about the syntax and how to create or use a module, see the - JUCE Module Format.txt file. + JUCE Module Format.md file. BEGIN_JUCE_MODULE_DECLARATION ID: juce_audio_processors vendor: juce - version: 5.4.7 + version: 6.0.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 @@ -94,6 +93,15 @@ #define JUCE_PLUGINHOST_LADSPA 0 #endif +/** Config: JUCE_CUSTOM_VST3_SDK + If enabled, the embedded VST3 SDK in JUCE will not be added to the project and instead you should + add the path to your custom VST3 SDK to the project's header search paths. Most users shouldn't + need to enable this and should just use the version of the SDK included with JUCE. +*/ +#ifndef JUCE_CUSTOM_VST3_SDK + #define JUCE_CUSTOM_VST3_SDK 0 +#endif + #if ! (JUCE_PLUGINHOST_AU || JUCE_PLUGINHOST_VST || JUCE_PLUGINHOST_VST3 || JUCE_PLUGINHOST_LADSPA) // #error "You need to set either the JUCE_PLUGINHOST_AU and/or JUCE_PLUGINHOST_VST and/or JUCE_PLUGINHOST_VST3 and/or JUCE_PLUGINHOST_LADSPA flags if you're using this module!" #endif @@ -132,4 +140,5 @@ #include "utilities/juce_AudioParameterInt.h" #include "utilities/juce_AudioParameterBool.h" #include "utilities/juce_AudioParameterChoice.h" +#include "utilities/juce_ParameterAttachments.h" #include "utilities/juce_AudioProcessorValueTreeState.h" diff --git a/modules/juce_audio_processors/juce_audio_processors.mm b/modules/juce_audio_processors/juce_audio_processors.mm index 5d8fa4c6..db19d2a3 100644 --- a/modules/juce_audio_processors/juce_audio_processors.mm +++ b/modules/juce_audio_processors/juce_audio_processors.mm @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_processors/processors/juce_AudioPluginInstance.cpp b/modules/juce_audio_processors/processors/juce_AudioPluginInstance.cpp index da90159e..3164ec9c 100644 --- a/modules/juce_audio_processors/processors/juce_AudioPluginInstance.cpp +++ b/modules/juce_audio_processors/processors/juce_AudioPluginInstance.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_processors/processors/juce_AudioPluginInstance.h b/modules/juce_audio_processors/processors/juce_AudioPluginInstance.h index fa3825ca..79d76bd8 100644 --- a/modules/juce_audio_processors/processors/juce_AudioPluginInstance.h +++ b/modules/juce_audio_processors/processors/juce_AudioPluginInstance.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -27,13 +26,9 @@ namespace juce { -#if JUCE_MSVC - #pragma warning (push, 0) - - // MSVC does not like it if you override a deprecated method even if you - // keep the deprecation attribute. Other compilers are more forgiving. - #pragma warning (disable: 4996) -#endif +// MSVC does not like it if you override a deprecated method even if you +// keep the deprecation attribute. Other compilers are more forgiving. +JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4996) //============================================================================== /** @@ -126,8 +121,6 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioPluginInstance) }; -#if JUCE_MSVC - #pragma warning (pop) -#endif +JUCE_END_IGNORE_WARNINGS_MSVC } // namespace juce diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp b/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp index bd40623c..c8059913 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp +++ b/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -364,6 +363,7 @@ void AudioProcessor::setPlayConfigDetails (int newNumIns, int newNumOuts, double jassert (success && newNumIns == getTotalNumInputChannels() && newNumOuts == getTotalNumOutputChannels()); setRateAndBufferSizeDetails (newSampleRate, newBlockSize); + ignoreUnused (success); } void AudioProcessor::setRateAndBufferSizeDetails (double newSampleRate, int newBlockSize) noexcept @@ -780,7 +780,7 @@ void AudioProcessor::audioIOChanged (bool busNumberChanged, bool channelNumChang bus->updateChannelCount(); } - auto countTotalChannels = [](const OwnedArray<AudioProcessor::Bus>& buses) noexcept + auto countTotalChannels = [] (const OwnedArray<AudioProcessor::Bus>& buses) noexcept { int n = 0; @@ -1183,16 +1183,8 @@ const char* AudioProcessor::getWrapperTypeDescription (AudioProcessor::WrapperTy } //============================================================================== -#if JUCE_GCC - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#elif JUCE_CLANG - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wdeprecated-declarations" -#elif JUCE_MSVC - #pragma warning (push, 0) - #pragma warning (disable: 4996) -#endif +JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wdeprecated-declarations") +JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4996) void AudioProcessor::setParameterNotifyingHost (int parameterIndex, float newValue) { @@ -1427,13 +1419,8 @@ AudioProcessorParameter* AudioProcessor::getParamChecked (int index) const return p; } -#if JUCE_GCC - #pragma GCC diagnostic pop -#elif JUCE_CLANG - #pragma clang diagnostic pop -#elif JUCE_MSVC - #pragma warning (pop) -#endif +JUCE_END_IGNORE_WARNINGS_GCC_LIKE +JUCE_END_IGNORE_WARNINGS_MSVC //============================================================================== void AudioProcessorListener::audioProcessorParameterChangeGestureBegin (AudioProcessor*, int) {} @@ -1558,7 +1545,7 @@ StringArray AudioProcessorParameter::getAllValueStrings() const auto maxIndex = getNumSteps() - 1; for (int i = 0; i < getNumSteps(); ++i) - valueStrings.add (getText ((float) i / maxIndex, 1024)); + valueStrings.add (getText ((float) i / (float) maxIndex, 1024)); } return valueStrings; @@ -1576,35 +1563,4 @@ void AudioProcessorParameter::removeListener (AudioProcessorParameter::Listener* listeners.removeFirstMatchingValue (listenerToRemove); } -//============================================================================== -bool AudioPlayHead::CurrentPositionInfo::operator== (const CurrentPositionInfo& other) const noexcept -{ - return timeInSamples == other.timeInSamples - && ppqPosition == other.ppqPosition - && editOriginTime == other.editOriginTime - && ppqPositionOfLastBarStart == other.ppqPositionOfLastBarStart - && frameRate == other.frameRate - && isPlaying == other.isPlaying - && isRecording == other.isRecording - && bpm == other.bpm - && timeSigNumerator == other.timeSigNumerator - && timeSigDenominator == other.timeSigDenominator - && ppqLoopStart == other.ppqLoopStart - && ppqLoopEnd == other.ppqLoopEnd - && isLooping == other.isLooping; -} - -bool AudioPlayHead::CurrentPositionInfo::operator!= (const CurrentPositionInfo& other) const noexcept -{ - return ! operator== (other); -} - -void AudioPlayHead::CurrentPositionInfo::resetToDefault() -{ - zerostruct (*this); - timeSigNumerator = 4; - timeSigDenominator = 4; - bpm = 120; -} - } // namespace juce diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessor.h b/modules/juce_audio_processors/processors/juce_AudioProcessor.h index 836b09c7..02c3de12 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessor.h +++ b/modules/juce_audio_processors/processors/juce_AudioProcessor.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -1175,7 +1174,7 @@ public: Unknown = -1 }; - std::function<float(float)> curve; // a function which represents your curve (such as an eq) + std::function<float (float)> curve; // a function which represents your curve (such as an eq) Range<float> xRange, yRange; // the data range of your curve // For some curve types, your plug-in may already measure the current input and output values. @@ -1466,7 +1465,8 @@ private: Component::SafePointer<AudioProcessorEditor> activeEditor; double currentSampleRate = 0; int blockSize = 0, latencySamples = 0; - bool suspended = false, nonRealtime = false; + bool suspended = false; + std::atomic<bool> nonRealtime { false }; ProcessingPrecision processingPrecision = singlePrecision; CriticalSection callbackLock, listenerLock, activeEditorLock; diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.cpp b/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.cpp index 0c660ae6..b980441c 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.cpp +++ b/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -59,12 +58,12 @@ void AudioProcessorEditor::initialise() { /* ========================================================================== - In accordance with the terms of the JUCE 5 End-Use License Agreement, the + In accordance with the terms of the JUCE 6 End-Use License Agreement, the JUCE Code in SECTION A cannot be removed, changed or otherwise rendered ineffective unless you have a JUCE Indie or Pro license, or are using JUCE under the GPL v3 license. - End User License Agreement: www.juce.com/juce-5-licence + End User License Agreement: www.juce.com/juce-6-licence ========================================================================== */ @@ -173,6 +172,12 @@ void AudioProcessorEditor::setBoundsConstrained (Rectangle<int> newBounds) void AudioProcessorEditor::editorResized (bool wasResized) { + // The host needs to be able to rescale the plug-in editor and applying your own transform will + // obliterate it! If you want to scale the whole of your UI use Desktop::setGlobalScaleFactor(), + // or, for applying other transforms, consider putting the component you want to transform + // in a child of the editor and transform that instead. + jassert (getTransform() == hostScaleTransform); + if (wasResized) { bool resizerHidden = false; @@ -206,25 +211,23 @@ void AudioProcessorEditor::updatePeer() void AudioProcessorEditor::setScaleFactor (float newScale) { - setTransform (AffineTransform::scale (newScale)); + hostScaleTransform = AffineTransform::scale (newScale); + setTransform (hostScaleTransform); + editorResized (true); } //============================================================================== -#if JUCE_MODULE_AVAILABLE_juce_audio_plugin_client && JucePlugin_Build_Unity - typedef ComponentPeer* (*createUnityPeerFunctionType) (Component&); - createUnityPeerFunctionType juce_createUnityPeerFn = nullptr; -#endif +typedef ComponentPeer* (*createUnityPeerFunctionType) (Component&); +createUnityPeerFunctionType juce_createUnityPeerFn = nullptr; ComponentPeer* AudioProcessorEditor::createNewPeer (int styleFlags, void* nativeWindow) { - #if JUCE_MODULE_AVAILABLE_juce_audio_plugin_client && JucePlugin_Build_Unity if (juce_createUnityPeerFn != nullptr) { ignoreUnused (styleFlags, nativeWindow); return juce_createUnityPeerFn (*this); } - #endif return Component::createNewPeer (styleFlags, nativeWindow); } diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.h b/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.h index 623390ff..ff694b78 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.h +++ b/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -208,6 +207,7 @@ private: ComponentBoundsConstrainer defaultConstrainer; ComponentBoundsConstrainer* constrainer = {}; Component::SafePointer<Component> splashScreen; + AffineTransform hostScaleTransform; JUCE_DECLARE_NON_COPYABLE (AudioProcessorEditor) }; diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp b/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp index 1a016a9c..17c5af30 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp +++ b/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -27,6 +26,14 @@ namespace juce { +static void updateOnMessageThread (AsyncUpdater& updater) +{ + if (MessageManager::getInstance()->isThisTheMessageThread()) + updater.handleAsyncUpdate(); + else + updater.triggerAsyncUpdate(); +} + template <typename FloatType> struct GraphRenderSequence { @@ -901,7 +908,7 @@ void AudioProcessorGraph::topologyChanged() sendChangeMessage(); if (isPrepared) - triggerAsyncUpdate(); + updateOnMessageThread (*this); } void AudioProcessorGraph::clear() @@ -961,31 +968,31 @@ AudioProcessorGraph::Node::Ptr AudioProcessorGraph::addNode (std::unique_ptr<Aud return n; } -bool AudioProcessorGraph::removeNode (NodeID nodeId) +AudioProcessorGraph::Node::Ptr AudioProcessorGraph::removeNode (NodeID nodeId) { const ScopedLock sl (getCallbackLock()); for (int i = nodes.size(); --i >= 0;) { - if (nodes.getUnchecked(i)->nodeID == nodeId) + if (nodes.getUnchecked (i)->nodeID == nodeId) { disconnectNode (nodeId); - nodes.remove (i); + auto node = nodes.removeAndReturn (i); topologyChanged(); - return true; + return node; } } - return false; + return {}; } -bool AudioProcessorGraph::removeNode (Node* node) +AudioProcessorGraph::Node::Ptr AudioProcessorGraph::removeNode (Node* node) { if (node != nullptr) return removeNode (node->nodeID); jassertfalse; - return false; + return {}; } //============================================================================== @@ -1258,14 +1265,27 @@ void AudioProcessorGraph::prepareToPlay (double sampleRate, int estimatedSamples { const ScopedLock sl (getCallbackLock()); setRateAndBufferSizeDetails (sampleRate, estimatedSamplesPerBlock); + + const auto newPrepareSettings = [&] + { + PrepareSettings settings; + settings.precision = getProcessingPrecision(); + settings.sampleRate = sampleRate; + settings.blockSize = estimatedSamplesPerBlock; + settings.valid = true; + return settings; + }(); + + if (prepareSettings != newPrepareSettings) + { + unprepare(); + prepareSettings = newPrepareSettings; + } } clearRenderingSequence(); - if (MessageManager::getInstance()->isThisTheMessageThread()) - handleAsyncUpdate(); - else - triggerAsyncUpdate(); + updateOnMessageThread (*this); } bool AudioProcessorGraph::supportsDoublePrecisionProcessing() const @@ -1273,16 +1293,23 @@ bool AudioProcessorGraph::supportsDoublePrecisionProcessing() const return true; } -void AudioProcessorGraph::releaseResources() +void AudioProcessorGraph::unprepare() { - const ScopedLock sl (getCallbackLock()); - - cancelPendingUpdate(); + prepareSettings.valid = false; isPrepared = 0; for (auto* n : nodes) n->unprepare(); +} + +void AudioProcessorGraph::releaseResources() +{ + const ScopedLock sl (getCallbackLock()); + + cancelPendingUpdate(); + + unprepare(); if (renderSequenceFloat != nullptr) renderSequenceFloat->releaseBuffers(); @@ -1380,8 +1407,8 @@ const String AudioProcessorGraph::AudioGraphIOProcessor::getName() const { case audioOutputNode: return "Audio Output"; case audioInputNode: return "Audio Input"; - case midiOutputNode: return "Midi Output"; - case midiInputNode: return "Midi Input"; + case midiOutputNode: return "MIDI Output"; + case midiInputNode: return "MIDI Input"; default: break; } diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h b/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h index bb28badf..a60e67d8 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h +++ b/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -143,7 +142,7 @@ public: bool operator== (const Connection&) const noexcept; }; - const std::unique_ptr<AudioProcessor> processor; + std::unique_ptr<AudioProcessor> processor; Array<Connection> inputs, outputs; bool isPrepared = false; std::atomic<bool> bypassed { false }; @@ -239,12 +238,12 @@ public: /** Deletes a node within the graph which has the specified ID. This will also delete any connections that are attached to this node. */ - bool removeNode (NodeID); + Node::Ptr removeNode (NodeID); /** Deletes a node within the graph. This will also delete any connections that are attached to this node. */ - bool removeNode (Node*); + Node::Ptr removeNode (Node*); /** Returns the list of connections in the graph. */ std::vector<Connection> getConnections() const; @@ -404,6 +403,24 @@ public: void setStateInformation (const void* data, int sizeInBytes) override; private: + struct PrepareSettings + { + ProcessingPrecision precision = ProcessingPrecision::singlePrecision; + double sampleRate = 0.0; + int blockSize = 0; + bool valid = false; + + using Tied = std::tuple<const ProcessingPrecision&, + const double&, + const int&, + const bool&>; + + Tied tie() const noexcept { return std::tie (precision, sampleRate, blockSize, valid); } + + bool operator== (const PrepareSettings& other) const noexcept { return tie() == other.tie(); } + bool operator!= (const PrepareSettings& other) const noexcept { return tie() != other.tie(); } + }; + //============================================================================== ReferenceCountedArray<Node> nodes; NodeID lastNodeID = {}; @@ -413,11 +430,14 @@ private: std::unique_ptr<RenderSequenceFloat> renderSequenceFloat; std::unique_ptr<RenderSequenceDouble> renderSequenceDouble; + PrepareSettings prepareSettings; + friend class AudioGraphIOProcessor; std::atomic<bool> isPrepared { false }; void topologyChanged(); + void unprepare(); void handleAsyncUpdate() override; void clearRenderingSequence(); void buildRenderingSequence(); diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessorListener.h b/modules/juce_audio_processors/processors/juce_AudioProcessorListener.h index 0ea8bbf5..7e075b39 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessorListener.h +++ b/modules/juce_audio_processors/processors/juce_AudioProcessorListener.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h b/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h index 8552d7d3..f661dcb1 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h +++ b/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessorParameterGroup.cpp b/modules/juce_audio_processors/processors/juce_AudioProcessorParameterGroup.cpp index 62216b3c..3bb2e758 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessorParameterGroup.cpp +++ b/modules/juce_audio_processors/processors/juce_AudioProcessorParameterGroup.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessorParameterGroup.h b/modules/juce_audio_processors/processors/juce_AudioProcessorParameterGroup.h index 6c1580ad..7f26bb4f 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessorParameterGroup.h +++ b/modules/juce_audio_processors/processors/juce_AudioProcessorParameterGroup.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.cpp b/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.cpp index 08fb9a5d..1d1c0df1 100644 --- a/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.cpp +++ b/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -285,7 +284,7 @@ private: { // The parameter is producing some unexpected text, so we'll do // some linear interpolation. - index = roundToInt (getParameter().getValue() * (parameterValues.size() - 1)); + index = roundToInt (getParameter().getValue() * (float) (parameterValues.size() - 1)); } box.setSelectedItemIndex (index); diff --git a/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.h b/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.h index 8bd5880c..b56216e0 100644 --- a/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.h +++ b/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_processors/processors/juce_PluginDescription.cpp b/modules/juce_audio_processors/processors/juce_PluginDescription.cpp index b023b804..956f2de2 100644 --- a/modules/juce_audio_processors/processors/juce_PluginDescription.cpp +++ b/modules/juce_audio_processors/processors/juce_PluginDescription.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_processors/processors/juce_PluginDescription.h b/modules/juce_audio_processors/processors/juce_PluginDescription.h index 5129a8b7..bce3a41e 100644 --- a/modules/juce_audio_processors/processors/juce_PluginDescription.h +++ b/modules/juce_audio_processors/processors/juce_PluginDescription.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_processors/scanning/juce_KnownPluginList.cpp b/modules/juce_audio_processors/scanning/juce_KnownPluginList.cpp index f5cfdb25..1bfc7819 100644 --- a/modules/juce_audio_processors/scanning/juce_KnownPluginList.cpp +++ b/modules/juce_audio_processors/scanning/juce_KnownPluginList.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -297,6 +296,8 @@ struct PluginSorter case KnownPluginList::sortByFormat: diff = first.pluginFormatName.compare (second.pluginFormatName); break; case KnownPluginList::sortByFileSystemLocation: diff = lastPathPart (first.fileOrIdentifier).compare (lastPathPart (second.fileOrIdentifier)); break; case KnownPluginList::sortByInfoUpdateTime: diff = compare (first.lastInfoUpdateTime, second.lastInfoUpdateTime); break; + case KnownPluginList::sortAlphabetically: + case KnownPluginList::defaultOrder: default: break; } diff --git a/modules/juce_audio_processors/scanning/juce_KnownPluginList.h b/modules/juce_audio_processors/scanning/juce_KnownPluginList.h index 616508b2..9d9106a5 100644 --- a/modules/juce_audio_processors/scanning/juce_KnownPluginList.h +++ b/modules/juce_audio_processors/scanning/juce_KnownPluginList.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.cpp b/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.cpp index 670c9dee..9eab44c2 100644 --- a/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.cpp +++ b/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -78,7 +77,7 @@ String PluginDirectoryScanner::getNextPluginFileThatWillBeScanned() const void PluginDirectoryScanner::updateProgress() { - progress = (1.0f - nextIndex.get() / (float) filesOrIdentifiersToScan.size()); + progress = (1.0f - (float) nextIndex.get() / (float) filesOrIdentifiersToScan.size()); } bool PluginDirectoryScanner::scanNextFile (bool dontRescanIfAlreadyInList, diff --git a/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.h b/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.h index c26ef9b8..7da639b1 100644 --- a/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.h +++ b/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp b/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp index 2c120c4b..88c3f818 100644 --- a/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp +++ b/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -89,7 +88,7 @@ public: g.setColour (isBlacklisted ? Colours::red : columnId == nameCol ? defaultTextColour : defaultTextColour.interpolatedWith (Colours::transparentBlack, 0.3f)); - g.setFont (Font (height * 0.7f, Font::bold)); + g.setFont (Font ((float) height * 0.7f, Font::bold)); g.drawFittedText (text, 4, 0, width - 6, height, Justification::centredLeft, 1, 0.9f); } } @@ -263,7 +262,7 @@ static bool canShowFolderForPlugin (KnownPluginList& list, int index) static void showFolderForPlugin (KnownPluginList& list, int index) { if (canShowFolderForPlugin (list, index)) - File (list.getTypes()[index].fileOrIdentifier).getParentDirectory().startAsProcess(); + File (list.getTypes()[index].fileOrIdentifier).revealToUser(); } void PluginListComponent::removeMissingPlugins() diff --git a/modules/juce_audio_processors/scanning/juce_PluginListComponent.h b/modules/juce_audio_processors/scanning/juce_PluginListComponent.h index 7bcc429f..307f6fd8 100644 --- a/modules/juce_audio_processors/scanning/juce_PluginListComponent.h +++ b/modules/juce_audio_processors/scanning/juce_PluginListComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_processors/utilities/juce_AudioParameterBool.cpp b/modules/juce_audio_processors/utilities/juce_AudioParameterBool.cpp index ca3fcff6..4ba512dd 100644 --- a/modules/juce_audio_processors/utilities/juce_AudioParameterBool.cpp +++ b/modules/juce_audio_processors/utilities/juce_AudioParameterBool.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -29,8 +28,8 @@ namespace juce AudioParameterBool::AudioParameterBool (const String& idToUse, const String& nameToUse, bool def, const String& labelToUse, - std::function<String(bool, int)> stringFromBool, - std::function<bool(const String&)> boolFromString) + std::function<String (bool, int)> stringFromBool, + std::function<bool (const String&)> boolFromString) : RangedAudioParameter (idToUse, nameToUse, labelToUse), value (def ? 1.0f : 0.0f), defaultValue (value), diff --git a/modules/juce_audio_processors/utilities/juce_AudioParameterBool.h b/modules/juce_audio_processors/utilities/juce_AudioParameterBool.h index f43ec750..f4a7f2c4 100644 --- a/modules/juce_audio_processors/utilities/juce_AudioParameterBool.h +++ b/modules/juce_audio_processors/utilities/juce_AudioParameterBool.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -52,8 +51,8 @@ public: */ AudioParameterBool (const String& parameterID, const String& parameterName, bool defaultValue, const String& parameterLabel = String(), - std::function<String(bool value, int maximumStringLength)> stringFromBool = nullptr, - std::function<bool(const String& text)> boolFromString = nullptr); + std::function<String (bool value, int maximumStringLength)> stringFromBool = nullptr, + std::function<bool (const String& text)> boolFromString = nullptr); /** Destructor. */ ~AudioParameterBool() override; @@ -90,8 +89,8 @@ private: const NormalisableRange<float> range { 0.0f, 1.0f, 1.0f }; std::atomic<float> value; const float defaultValue; - std::function<String(bool, int)> stringFromBoolFunction; - std::function<bool(const String&)> boolFromStringFunction; + std::function<String (bool, int)> stringFromBoolFunction; + std::function<bool (const String&)> boolFromStringFunction; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioParameterBool) }; diff --git a/modules/juce_audio_processors/utilities/juce_AudioParameterChoice.cpp b/modules/juce_audio_processors/utilities/juce_AudioParameterChoice.cpp index 121f837d..05ae5856 100644 --- a/modules/juce_audio_processors/utilities/juce_AudioParameterChoice.cpp +++ b/modules/juce_audio_processors/utilities/juce_AudioParameterChoice.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -29,15 +28,15 @@ namespace juce AudioParameterChoice::AudioParameterChoice (const String& idToUse, const String& nameToUse, const StringArray& c, int def, const String& labelToUse, - std::function<String(int, int)> stringFromIndex, - std::function<int(const String&)> indexFromString) + std::function<String (int, int)> stringFromIndex, + std::function<int (const String&)> indexFromString) : RangedAudioParameter (idToUse, nameToUse, labelToUse), choices (c), range ([this] { - NormalisableRange<float> rangeWithInterval { 0.0f, choices.size() - 1.0f, - [](float, float end, float v) { return jlimit (0.0f, end, v * end); }, - [](float, float end, float v) { return jlimit (0.0f, 1.0f, v / end); }, - [](float start, float end, float v) { return (float) roundToInt (juce::jlimit (start, end, v)); } }; + NormalisableRange<float> rangeWithInterval { 0.0f, (float) choices.size() - 1.0f, + [] (float, float end, float v) { return jlimit (0.0f, end, v * end); }, + [] (float, float end, float v) { return jlimit (0.0f, 1.0f, v / end); }, + [] (float start, float end, float v) { return (float) roundToInt (juce::jlimit (start, end, v)); } }; rangeWithInterval.interval = 1.0f; return rangeWithInterval; }()), diff --git a/modules/juce_audio_processors/utilities/juce_AudioParameterChoice.h b/modules/juce_audio_processors/utilities/juce_AudioParameterChoice.h index e0d242db..818f3aca 100644 --- a/modules/juce_audio_processors/utilities/juce_AudioParameterChoice.h +++ b/modules/juce_audio_processors/utilities/juce_AudioParameterChoice.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -56,8 +55,8 @@ public: const StringArray& choices, int defaultItemIndex, const String& parameterLabel = String(), - std::function<String(int index, int maximumStringLength)> stringFromIndex = nullptr, - std::function<int(const String& text)> indexFromString = nullptr); + std::function<String (int index, int maximumStringLength)> stringFromIndex = nullptr, + std::function<int (const String& text)> indexFromString = nullptr); /** Destructor. */ ~AudioParameterChoice() override; @@ -102,8 +101,8 @@ private: const NormalisableRange<float> range; std::atomic<float> value; const float defaultValue; - std::function<String(int, int)> stringFromIndexFunction; - std::function<int(const String&)> indexFromStringFunction; + std::function<String (int, int)> stringFromIndexFunction; + std::function<int (const String&)> indexFromStringFunction; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioParameterChoice) }; diff --git a/modules/juce_audio_processors/utilities/juce_AudioParameterFloat.cpp b/modules/juce_audio_processors/utilities/juce_AudioParameterFloat.cpp index 894cf4ea..ccd31f5d 100644 --- a/modules/juce_audio_processors/utilities/juce_AudioParameterFloat.cpp +++ b/modules/juce_audio_processors/utilities/juce_AudioParameterFloat.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -30,8 +29,8 @@ namespace juce AudioParameterFloat::AudioParameterFloat (const String& idToUse, const String& nameToUse, NormalisableRange<float> r, float def, const String& labelToUse, Category categoryToUse, - std::function<String(float, int)> stringFromValue, - std::function<float(const String&)> valueFromString) + std::function<String (float, int)> stringFromValue, + std::function<float (const String&)> valueFromString) : RangedAudioParameter (idToUse, nameToUse, labelToUse, categoryToUse), range (r), value (def), defaultValue (def), stringFromValueFunction (stringFromValue), @@ -45,7 +44,7 @@ AudioParameterFloat::AudioParameterFloat (const String& idToUse, const String& n if (range.interval != 0.0f) { - if (approximatelyEqual (std::abs (range.interval - (int) range.interval), 0.0f)) + if (approximatelyEqual (std::abs (range.interval - std::floor (range.interval)), 0.0f)) return 0; auto v = std::abs (roundToInt (range.interval * pow (10, numDecimalPlaces))); diff --git a/modules/juce_audio_processors/utilities/juce_AudioParameterFloat.h b/modules/juce_audio_processors/utilities/juce_AudioParameterFloat.h index 62700c44..59b058f9 100644 --- a/modules/juce_audio_processors/utilities/juce_AudioParameterFloat.h +++ b/modules/juce_audio_processors/utilities/juce_AudioParameterFloat.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -59,8 +58,8 @@ public: float defaultValue, const String& parameterLabel = String(), Category parameterCategory = AudioProcessorParameter::genericParameter, - std::function<String(float value, int maximumStringLength)> stringFromValue = nullptr, - std::function<float(const String& text)> valueFromString = nullptr); + std::function<String (float value, int maximumStringLength)> stringFromValue = nullptr, + std::function<float (const String& text)> valueFromString = nullptr); /** Creates a AudioParameterFloat with an ID, name, and range. On creation, its value is set to the default value. @@ -108,8 +107,8 @@ private: std::atomic<float> value; const float defaultValue; - std::function<String(float, int)> stringFromValueFunction; - std::function<float(const String&)> valueFromStringFunction; + std::function<String (float, int)> stringFromValueFunction; + std::function<float (const String&)> valueFromStringFunction; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioParameterFloat) }; diff --git a/modules/juce_audio_processors/utilities/juce_AudioParameterInt.cpp b/modules/juce_audio_processors/utilities/juce_AudioParameterInt.cpp index 913bcf36..e0b1f424 100644 --- a/modules/juce_audio_processors/utilities/juce_AudioParameterInt.cpp +++ b/modules/juce_audio_processors/utilities/juce_AudioParameterInt.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -30,15 +29,15 @@ namespace juce AudioParameterInt::AudioParameterInt (const String& idToUse, const String& nameToUse, int minValue, int maxValue, int def, const String& labelToUse, - std::function<String(int, int)> stringFromInt, - std::function<int(const String&)> intFromString) + std::function<String (int, int)> stringFromInt, + std::function<int (const String&)> intFromString) : RangedAudioParameter (idToUse, nameToUse, labelToUse), range ([minValue, maxValue] { NormalisableRange<float> rangeWithInterval { (float) minValue, (float) maxValue, - [](float start, float end, float v) { return jlimit (start, end, v * (end - start) + start); }, - [](float start, float end, float v) { return jlimit (0.0f, 1.0f, (v - start) / (end - start)); }, - [](float start, float end, float v) { return (float) roundToInt (juce::jlimit (start, end, v)); } }; + [] (float start, float end, float v) { return jlimit (start, end, v * (end - start) + start); }, + [] (float start, float end, float v) { return jlimit (0.0f, 1.0f, (v - start) / (end - start)); }, + [] (float start, float end, float v) { return (float) roundToInt (juce::jlimit (start, end, v)); } }; rangeWithInterval.interval = 1.0f; return rangeWithInterval; }()), diff --git a/modules/juce_audio_processors/utilities/juce_AudioParameterInt.h b/modules/juce_audio_processors/utilities/juce_AudioParameterInt.h index 868e28ca..6e969e79 100644 --- a/modules/juce_audio_processors/utilities/juce_AudioParameterInt.h +++ b/modules/juce_audio_processors/utilities/juce_AudioParameterInt.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -57,8 +56,8 @@ public: int minValue, int maxValue, int defaultValue, const String& parameterLabel = String(), - std::function<String(int value, int maximumStringLength)> stringFromInt = nullptr, - std::function<int(const String& text)> intFromString = nullptr); + std::function<String (int value, int maximumStringLength)> stringFromInt = nullptr, + std::function<int (const String& text)> intFromString = nullptr); /** Destructor. */ ~AudioParameterInt() override; @@ -98,8 +97,8 @@ private: const NormalisableRange<float> range; std::atomic<float> value; const float defaultValue; - std::function<String(int, int)> stringFromIntFunction; - std::function<int(const String&)> intFromStringFunction; + std::function<String (int, int)> stringFromIntFunction; + std::function<int (const String&)> intFromStringFunction; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioParameterInt) }; diff --git a/modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.cpp b/modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.cpp index 666effdb..c8cb1081 100644 --- a/modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.cpp +++ b/modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.h b/modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.h index 23714e2b..9b43de7f 100644 --- a/modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.h +++ b/modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp b/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp index 252dad8f..b05ad8a0 100644 --- a/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp +++ b/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -33,8 +32,8 @@ AudioProcessorValueTreeState::Parameter::Parameter (const String& parameterID, const String& labelText, NormalisableRange<float> valueRange, float defaultParameterValue, - std::function<String(float)> valueToTextFunction, - std::function<float(const String&)> textToValueFunction, + std::function<String (float)> valueToTextFunction, + std::function<float (const String&)> textToValueFunction, bool isMetaParameter, bool isAutomatableParameter, bool isDiscrete, @@ -46,8 +45,8 @@ AudioProcessorValueTreeState::Parameter::Parameter (const String& parameterID, defaultParameterValue, labelText, parameterCategory, - valueToTextFunction == nullptr ? std::function<String(float v, int)>() - : [valueToTextFunction](float v, int) { return valueToTextFunction (v); }, + valueToTextFunction == nullptr ? std::function<String (float v, int)>() + : [valueToTextFunction] (float v, int) { return valueToTextFunction (v); }, std::move (textToValueFunction)), unsnappedDefault (valueRange.convertTo0to1 (defaultParameterValue)), metaParameter (isMetaParameter), @@ -163,7 +162,7 @@ private: return; unnormalisedValue = newValue; - listeners.call ([=](Listener& l) { l.parameterChanged (parameter.paramID, unnormalisedValue); }); + listeners.call ([=] (Listener& l) { l.parameterChanged (parameter.paramID, unnormalisedValue); }); listenersNeedCalling = false; needsUpdate = true; } @@ -186,11 +185,38 @@ private: parameter.setValueNotifyingHost (value); } + class LockedListeners + { + public: + template <typename Fn> + void call (Fn&& fn) + { + const CriticalSection::ScopedLockType lock (mutex); + listeners.call (std::forward<Fn> (fn)); + } + + void add (Listener* l) + { + const CriticalSection::ScopedLockType lock (mutex); + listeners.add (l); + } + + void remove (Listener* l) + { + const CriticalSection::ScopedLockType lock (mutex); + listeners.remove (l); + } + + private: + CriticalSection mutex; + ListenerList<Listener> listeners; + }; + RangedAudioParameter& parameter; - ListenerList<Listener> listeners; - std::atomic<float> unnormalisedValue{}; - std::atomic<bool> needsUpdate { true }; - bool listenersNeedCalling { true }, ignoreParameterChangedCallbacks { false }; + LockedListeners listeners; + std::atomic<float> unnormalisedValue { 0.0f }; + std::atomic<bool> needsUpdate { true }, listenersNeedCalling { true }; + bool ignoreParameterChangedCallbacks { false }; }; //============================================================================== @@ -269,8 +295,8 @@ RangedAudioParameter* AudioProcessorValueTreeState::createAndAddParameter (const const String& labelText, NormalisableRange<float> range, float defaultVal, - std::function<String(float)> valueToTextFunction, - std::function<float(const String&)> textToValueFunction, + std::function<String (float)> valueToTextFunction, + std::function<float (const String&)> textToValueFunction, bool isMetaParameter, bool isAutomatableParameter, bool isDiscreteParameter, @@ -458,305 +484,39 @@ void AudioProcessorValueTreeState::timerCallback() } //============================================================================== -struct AttachedControlBase : public AudioProcessorValueTreeState::Listener, - public AsyncUpdater +template <typename Attachment, typename Control> +std::unique_ptr<Attachment> makeAttachment (const AudioProcessorValueTreeState& stateToUse, + const String& parameterID, + Control& control) { - AttachedControlBase (AudioProcessorValueTreeState& s, const String& p) - : state (s), paramID (p), lastValue (0) - { - state.addParameterListener (paramID, this); - } - - void removeListener() - { - state.removeParameterListener (paramID, this); - } - - void setNewDenormalisedValue (float newDenormalisedValue) - { - if (auto* p = state.getParameter (paramID)) - { - const float newValue = state.getParameterRange (paramID) - .convertTo0to1 (newDenormalisedValue); - - if (p->getValue() != newValue) - p->setValueNotifyingHost (newValue); - } - } - - void sendInitialUpdate() - { - if (auto* v = state.getRawParameterValue (paramID)) - parameterChanged (paramID, *v); - } - - void parameterChanged (const String&, float newValue) override - { - lastValue = newValue; - - if (MessageManager::getInstance()->isThisTheMessageThread()) - { - cancelPendingUpdate(); - setValue (newValue); - } - else - { - triggerAsyncUpdate(); - } - } + if (auto* parameter = stateToUse.getParameter (parameterID)) + return std::make_unique<Attachment> (*parameter, control, stateToUse.undoManager); - void beginParameterChange() - { - if (auto* p = state.getParameter (paramID)) - { - if (state.undoManager != nullptr) - state.undoManager->beginNewTransaction(); - - p->beginChangeGesture(); - } - } - - void endParameterChange() - { - if (AudioProcessorParameter* p = state.getParameter (paramID)) - p->endChangeGesture(); - } - - void handleAsyncUpdate() override - { - setValue (lastValue); - } - - virtual void setValue (float) = 0; - - AudioProcessorValueTreeState& state; - String paramID; - float lastValue; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AttachedControlBase) -}; - -//============================================================================== -struct AudioProcessorValueTreeState::SliderAttachment::Pimpl : private AttachedControlBase, - private Slider::Listener -{ - Pimpl (AudioProcessorValueTreeState& s, const String& p, Slider& sl) - : AttachedControlBase (s, p), slider (sl), ignoreCallbacks (false) - { - NormalisableRange<float> range (state.getParameterRange (paramID)); - - if (auto* param = state.getParameterAdapter (paramID)) - { - slider.valueFromTextFunction = [param](const String& text) { return (double) param->getDenormalisedValueForText (text); }; - slider.textFromValueFunction = [param](double value) { return param->getTextForDenormalisedValue ((float) value); }; - slider.setDoubleClickReturnValue (true, range.convertFrom0to1 (param->getParameter().getDefaultValue())); - } - - auto convertFrom0To1Function = [range](double currentRangeStart, - double currentRangeEnd, - double normalisedValue) mutable - { - range.start = (float) currentRangeStart; - range.end = (float) currentRangeEnd; - return (double) range.convertFrom0to1 ((float) normalisedValue); - }; - - auto convertTo0To1Function = [range](double currentRangeStart, - double currentRangeEnd, - double mappedValue) mutable - { - range.start = (float) currentRangeStart; - range.end = (float) currentRangeEnd; - return (double) range.convertTo0to1 ((float) mappedValue); - }; - - auto snapToLegalValueFunction = [range](double currentRangeStart, - double currentRangeEnd, - double valueToSnap) mutable - { - range.start = (float) currentRangeStart; - range.end = (float) currentRangeEnd; - return (double) range.snapToLegalValue ((float) valueToSnap); - }; - - NormalisableRange<double> newRange { (double) range.start, - (double) range.end, - convertFrom0To1Function, - convertTo0To1Function, - snapToLegalValueFunction }; - newRange.interval = (double) range.interval; - newRange.skew = (double) range.skew; - - slider.setNormalisableRange (newRange); - - sendInitialUpdate(); - slider.addListener (this); - } - - ~Pimpl() override - { - slider.removeListener (this); - removeListener(); - } - - void setValue (float newValue) override - { - const ScopedLock selfCallbackLock (selfCallbackMutex); - - { - ScopedValueSetter<bool> svs (ignoreCallbacks, true); - slider.setValue (newValue, sendNotificationSync); - } - } - - void sliderValueChanged (Slider* s) override - { - const ScopedLock selfCallbackLock (selfCallbackMutex); - - if ((! ignoreCallbacks) && (! ModifierKeys::currentModifiers.isRightButtonDown())) - setNewDenormalisedValue ((float) s->getValue()); - } - - void sliderDragStarted (Slider*) override { beginParameterChange(); } - void sliderDragEnded (Slider*) override { endParameterChange(); } - - Slider& slider; - bool ignoreCallbacks; - CriticalSection selfCallbackMutex; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Pimpl) -}; - -AudioProcessorValueTreeState::SliderAttachment::SliderAttachment (AudioProcessorValueTreeState& s, const String& p, Slider& sl) - : pimpl (new Pimpl (s, p, sl)) -{ + jassertfalse; + return nullptr; } -AudioProcessorValueTreeState::SliderAttachment::~SliderAttachment() {} - -//============================================================================== -struct AudioProcessorValueTreeState::ComboBoxAttachment::Pimpl : private AttachedControlBase, - private ComboBox::Listener -{ - Pimpl (AudioProcessorValueTreeState& s, const String& p, ComboBox& c) - : AttachedControlBase (s, p), combo (c), ignoreCallbacks (false) - { - sendInitialUpdate(); - combo.addListener (this); - } - - ~Pimpl() override - { - combo.removeListener (this); - removeListener(); - } - - void setValue (float newValue) override - { - const ScopedLock selfCallbackLock (selfCallbackMutex); - - if (state.getParameter (paramID) != nullptr) - { - auto normValue = state.getParameterRange (paramID) - .convertTo0to1 (newValue); - auto index = roundToInt (normValue * (combo.getNumItems() - 1)); - - if (index != combo.getSelectedItemIndex()) - { - ScopedValueSetter<bool> svs (ignoreCallbacks, true); - combo.setSelectedItemIndex (index, sendNotificationSync); - } - } - } - - void comboBoxChanged (ComboBox*) override - { - const ScopedLock selfCallbackLock (selfCallbackMutex); - - if (! ignoreCallbacks) - { - if (auto* p = state.getParameter (paramID)) - { - auto newValue = (float) combo.getSelectedItemIndex() / (combo.getNumItems() - 1); - - if (p->getValue() != newValue) - { - beginParameterChange(); - p->setValueNotifyingHost (newValue); - endParameterChange(); - } - } - } - } - - ComboBox& combo; - bool ignoreCallbacks; - CriticalSection selfCallbackMutex; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Pimpl) -}; - -AudioProcessorValueTreeState::ComboBoxAttachment::ComboBoxAttachment (AudioProcessorValueTreeState& s, const String& p, ComboBox& c) - : pimpl (new Pimpl (s, p, c)) +AudioProcessorValueTreeState::SliderAttachment::SliderAttachment (AudioProcessorValueTreeState& stateToUse, + const String& parameterID, + Slider& slider) + : attachment (makeAttachment<SliderParameterAttachment> (stateToUse, parameterID, slider)) { } -AudioProcessorValueTreeState::ComboBoxAttachment::~ComboBoxAttachment() {} - -//============================================================================== -struct AudioProcessorValueTreeState::ButtonAttachment::Pimpl : private AttachedControlBase, - private Button::Listener +AudioProcessorValueTreeState::ComboBoxAttachment::ComboBoxAttachment (AudioProcessorValueTreeState& stateToUse, + const String& parameterID, + ComboBox& combo) + : attachment (makeAttachment<ComboBoxParameterAttachment> (stateToUse, parameterID, combo)) { - Pimpl (AudioProcessorValueTreeState& s, const String& p, Button& b) - : AttachedControlBase (s, p), button (b), ignoreCallbacks (false) - { - sendInitialUpdate(); - button.addListener (this); - } - - ~Pimpl() override - { - button.removeListener (this); - removeListener(); - } - - void setValue (float newValue) override - { - const ScopedLock selfCallbackLock (selfCallbackMutex); - - { - ScopedValueSetter<bool> svs (ignoreCallbacks, true); - button.setToggleState (newValue >= 0.5f, sendNotificationSync); - } - } - - void buttonClicked (Button* b) override - { - const ScopedLock selfCallbackLock (selfCallbackMutex); - - if (! ignoreCallbacks) - { - beginParameterChange(); - setNewDenormalisedValue (b->getToggleState() ? 1.0f : 0.0f); - endParameterChange(); - } - } - - Button& button; - bool ignoreCallbacks; - CriticalSection selfCallbackMutex; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Pimpl) -}; +} -AudioProcessorValueTreeState::ButtonAttachment::ButtonAttachment (AudioProcessorValueTreeState& s, const String& p, Button& b) - : pimpl (new Pimpl (s, p, b)) +AudioProcessorValueTreeState::ButtonAttachment::ButtonAttachment (AudioProcessorValueTreeState& stateToUse, + const String& parameterID, + Button& button) + : attachment (makeAttachment<ButtonParameterAttachment> (stateToUse, parameterID, button)) { } -AudioProcessorValueTreeState::ButtonAttachment::~ButtonAttachment() {} - - //============================================================================== //============================================================================== #if JUCE_UNIT_TESTS @@ -786,7 +546,7 @@ struct ParameterAdapterTests : public UnitTest beginTest ("Denormalised parameter values can be retrieved"); { - const auto test = [&](NormalisableRange<float> range, float value) + const auto test = [&] (NormalisableRange<float> range, float value) { AudioParameterFloat param ({}, {}, range, {}, {}); AudioProcessorValueTreeState::ParameterAdapter adapter (param); @@ -803,7 +563,7 @@ struct ParameterAdapterTests : public UnitTest beginTest ("Floats can be converted to text"); { - const auto test = [&](NormalisableRange<float> range, float value, String expected) + const auto test = [&] (NormalisableRange<float> range, float value, String expected) { AudioParameterFloat param ({}, {}, range, {}, {}); AudioProcessorValueTreeState::ParameterAdapter adapter (param); @@ -819,7 +579,7 @@ struct ParameterAdapterTests : public UnitTest beginTest ("Text can be converted to floats"); { - const auto test = [&](NormalisableRange<float> range, String text, float expected) + const auto test = [&] (NormalisableRange<float> range, String text, float expected) { AudioParameterFloat param ({}, {}, range, {}, {}); AudioProcessorValueTreeState::ParameterAdapter adapter (param); diff --git a/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h b/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h index f06a70ba..156e3ea0 100644 --- a/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h +++ b/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -176,18 +175,18 @@ public: std::make_unique<AudioParameterInt> ("b", "Parameter B", 0, 5, 2) }) @endcode - To add parameters programatically you can use the iterator-based ParameterLayout - constructor: + To add parameters programatically you can call `add` repeatedly on a + ParameterLayout instance: @code AudioProcessorValueTreeState::ParameterLayout createParameterLayout() { - std::vector<std::unique_ptr<AudioParameterInt>> params; + AudioProcessorValueTreeState::ParameterLayout layout; for (int i = 1; i < 9; ++i) - params.push_back (std::make_unique<AudioParameterInt> (String (i), String (i), 0, i, 0)); + layout.add (std::make_unique<AudioParameterInt> (String (i), String (i), 0, i, 0)); - return { params.begin(), params.end() }; + return layout; } YourAudioProcessor() @@ -262,8 +261,8 @@ public: const String& labelText, NormalisableRange<float> valueRange, float defaultValue, - std::function<String(float)> valueToTextFunction, - std::function<float(const String&)> textToValueFunction, + std::function<String (float)> valueToTextFunction, + std::function<float (const String&)> textToValueFunction, bool isMetaParameter = false, bool isAutomatableParameter = true, bool isDiscrete = false, @@ -361,11 +360,12 @@ public: /** Provides access to the undo manager that this object is using. */ UndoManager* const undoManager; - //============================================================================== private: + //============================================================================== class ParameterAdapter; public: + //============================================================================== /** A parameter class that maintains backwards compatibility with deprecated AudioProcessorValueTreeState functionality. @@ -401,8 +401,8 @@ public: const String& labelText, NormalisableRange<float> valueRange, float defaultValue, - std::function<String(float)> valueToTextFunction, - std::function<float(const String&)> textToValueFunction, + std::function<String (float)> valueToTextFunction, + std::function<float (const String&)> textToValueFunction, bool isMetaParameter = false, bool isAutomatableParameter = true, bool isDiscrete = false, @@ -424,7 +424,7 @@ public: const float unsnappedDefault; const bool metaParameter, automatable, discrete, boolean; - float lastValue = -1.0f; + std::atomic<float> lastValue { -1.0f }; friend class AudioProcessorValueTreeState::ParameterAdapter; }; @@ -441,14 +441,12 @@ public: class JUCE_API SliderAttachment { public: - SliderAttachment (AudioProcessorValueTreeState& stateToControl, + SliderAttachment (AudioProcessorValueTreeState& stateToUse, const String& parameterID, - Slider& sliderToControl); - ~SliderAttachment(); + Slider& slider); private: - struct Pimpl; - std::unique_ptr<Pimpl> pimpl; + std::unique_ptr<SliderParameterAttachment> attachment; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SliderAttachment) }; @@ -469,14 +467,12 @@ public: class JUCE_API ComboBoxAttachment { public: - ComboBoxAttachment (AudioProcessorValueTreeState& stateToControl, + ComboBoxAttachment (AudioProcessorValueTreeState& stateToUse, const String& parameterID, - ComboBox& comboBoxToControl); - ~ComboBoxAttachment(); + ComboBox& combo); private: - struct Pimpl; - std::unique_ptr<Pimpl> pimpl; + std::unique_ptr<ComboBoxParameterAttachment> attachment; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ComboBoxAttachment) }; @@ -492,14 +488,12 @@ public: class JUCE_API ButtonAttachment { public: - ButtonAttachment (AudioProcessorValueTreeState& stateToControl, + ButtonAttachment (AudioProcessorValueTreeState& stateToUse, const String& parameterID, - Button& buttonToControl); - ~ButtonAttachment(); + Button& button); private: - struct Pimpl; - std::unique_ptr<Pimpl> pimpl; + std::unique_ptr<ButtonParameterAttachment> attachment; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ButtonAttachment) }; @@ -527,7 +521,7 @@ private: @endcode */ JUCE_DEPRECATED (std::unique_ptr<RangedAudioParameter> createParameter (const String&, const String&, const String&, NormalisableRange<float>, - float, std::function<String(float)>, std::function<float(const String&)>, + float, std::function<String (float)>, std::function<float (const String&)>, bool, bool, bool, AudioProcessorParameter::Category, bool)); //============================================================================== diff --git a/modules/juce_audio_processors/utilities/juce_ParameterAttachments.cpp b/modules/juce_audio_processors/utilities/juce_ParameterAttachments.cpp new file mode 100644 index 00000000..c46a67d4 --- /dev/null +++ b/modules/juce_audio_processors/utilities/juce_ParameterAttachments.cpp @@ -0,0 +1,271 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ + +ParameterAttachment::ParameterAttachment (RangedAudioParameter& param, + std::function<void (float)> parameterChangedCallback, + UndoManager* um) + : parameter (param), + undoManager (um), + setValue (std::move (parameterChangedCallback)) +{ + parameter.addListener (this); +} + +ParameterAttachment::~ParameterAttachment() +{ + parameter.removeListener (this); + cancelPendingUpdate(); +} + +void ParameterAttachment::sendInitialUpdate() +{ + parameterValueChanged ({}, parameter.getValue()); +} + +void ParameterAttachment::setValueAsCompleteGesture (float newDenormalisedValue) +{ + callIfParameterValueChanged (newDenormalisedValue, [this] (float f) + { + beginGesture(); + parameter.setValueNotifyingHost (f); + endGesture(); + }); +} + +void ParameterAttachment::beginGesture() +{ + if (undoManager != nullptr) + undoManager->beginNewTransaction(); + + parameter.beginChangeGesture(); +} + +void ParameterAttachment::setValueAsPartOfGesture (float newDenormalisedValue) +{ + callIfParameterValueChanged (newDenormalisedValue, [this] (float f) + { + parameter.setValueNotifyingHost (f); + }); +} + +void ParameterAttachment::endGesture() +{ + parameter.endChangeGesture(); +} + +template <typename Callback> +void ParameterAttachment::callIfParameterValueChanged (float newDenormalisedValue, + Callback&& callback) +{ + const auto newValue = normalise (newDenormalisedValue); + + if (parameter.getValue() != newValue) + callback (newValue); +} + +void ParameterAttachment::parameterValueChanged (int, float newValue) +{ + lastValue = newValue; + + if (MessageManager::getInstance()->isThisTheMessageThread()) + { + cancelPendingUpdate(); + handleAsyncUpdate(); + } + else + { + triggerAsyncUpdate(); + } +} + +void ParameterAttachment::handleAsyncUpdate() +{ + if (setValue != nullptr) + setValue (parameter.convertFrom0to1 (lastValue)); +} + +//============================================================================== +SliderParameterAttachment::SliderParameterAttachment (RangedAudioParameter& param, + Slider& s, + UndoManager* um) + : slider (s), + attachment (param, [this] (float f) { setValue (f); }, um) +{ + slider.valueFromTextFunction = [&param] (const String& text) { return (double) param.convertFrom0to1 (param.getValueForText (text)); }; + slider.textFromValueFunction = [&param] (double value) { return param.getText (param.convertTo0to1 ((float) value), 0); }; + slider.setDoubleClickReturnValue (true, param.convertFrom0to1 (param.getDefaultValue())); + + auto range = param.getNormalisableRange(); + + auto convertFrom0To1Function = [range] (double currentRangeStart, + double currentRangeEnd, + double normalisedValue) mutable + { + range.start = (float) currentRangeStart; + range.end = (float) currentRangeEnd; + return (double) range.convertFrom0to1 ((float) normalisedValue); + }; + + auto convertTo0To1Function = [range] (double currentRangeStart, + double currentRangeEnd, + double mappedValue) mutable + { + range.start = (float) currentRangeStart; + range.end = (float) currentRangeEnd; + return (double) range.convertTo0to1 ((float) mappedValue); + }; + + auto snapToLegalValueFunction = [range] (double currentRangeStart, + double currentRangeEnd, + double mappedValue) mutable + { + range.start = (float) currentRangeStart; + range.end = (float) currentRangeEnd; + return (double) range.snapToLegalValue ((float) mappedValue); + }; + + NormalisableRange<double> newRange { (double) range.start, + (double) range.end, + std::move (convertFrom0To1Function), + std::move (convertTo0To1Function), + std::move (snapToLegalValueFunction) }; + newRange.interval = range.interval; + newRange.skew = range.skew; + newRange.symmetricSkew = range.symmetricSkew; + + slider.setNormalisableRange (newRange); + + sendInitialUpdate(); + slider.valueChanged(); + slider.addListener (this); +} + +SliderParameterAttachment::~SliderParameterAttachment() +{ + slider.removeListener (this); +} + +void SliderParameterAttachment::sendInitialUpdate() { attachment.sendInitialUpdate(); } + +void SliderParameterAttachment::setValue (float newValue) +{ + const ScopedValueSetter<bool> svs (ignoreCallbacks, true); + slider.setValue (newValue, sendNotificationSync); +} + +void SliderParameterAttachment::sliderValueChanged (Slider*) +{ + if (ignoreCallbacks || ModifierKeys::currentModifiers.isRightButtonDown()) + return; + + attachment.setValueAsPartOfGesture ((float) slider.getValue()); +} + +//============================================================================== +ComboBoxParameterAttachment::ComboBoxParameterAttachment (RangedAudioParameter& param, + ComboBox& c, + UndoManager* um) + : comboBox (c), + storedParameter (param), + attachment (param, [this] (float f) { setValue (f); }, um) +{ + sendInitialUpdate(); + comboBox.addListener (this); +} + +ComboBoxParameterAttachment::~ComboBoxParameterAttachment() +{ + comboBox.removeListener (this); +} + +void ComboBoxParameterAttachment::sendInitialUpdate() +{ + attachment.sendInitialUpdate(); +} + +void ComboBoxParameterAttachment::setValue (float newValue) +{ + const auto normValue = storedParameter.convertTo0to1 (newValue); + const auto index = roundToInt (normValue * (float) (comboBox.getNumItems() - 1)); + + if (index == comboBox.getSelectedItemIndex()) + return; + + const ScopedValueSetter<bool> svs (ignoreCallbacks, true); + comboBox.setSelectedItemIndex (index, sendNotificationSync); +} + +void ComboBoxParameterAttachment::comboBoxChanged (ComboBox*) +{ + if (ignoreCallbacks) + return; + + const auto numItems = comboBox.getNumItems(); + const auto selected = (float) comboBox.getSelectedItemIndex(); + const auto newValue = numItems > 1 ? selected / (float) (numItems - 1) + : 0.0f; + + attachment.setValueAsCompleteGesture (storedParameter.convertFrom0to1 (newValue)); +} + +//============================================================================== +ButtonParameterAttachment::ButtonParameterAttachment (RangedAudioParameter& param, + Button& b, + UndoManager* um) + : button (b), + attachment (param, [this] (float f) { setValue (f); }, um) +{ + sendInitialUpdate(); + button.addListener (this); +} + +ButtonParameterAttachment::~ButtonParameterAttachment() +{ + button.removeListener (this); +} + +void ButtonParameterAttachment::sendInitialUpdate() +{ + attachment.sendInitialUpdate(); +} + +void ButtonParameterAttachment::setValue (float newValue) +{ + const ScopedValueSetter<bool> svs (ignoreCallbacks, true); + button.setToggleState (newValue >= 0.5f, sendNotificationSync); +} + +void ButtonParameterAttachment::buttonClicked (Button*) +{ + if (ignoreCallbacks) + return; + + attachment.setValueAsCompleteGesture (button.getToggleState() ? 1.0f : 0.0f); +} + +} // namespace juce diff --git a/modules/juce_audio_processors/utilities/juce_ParameterAttachments.h b/modules/juce_audio_processors/utilities/juce_ParameterAttachments.h new file mode 100644 index 00000000..6079df66 --- /dev/null +++ b/modules/juce_audio_processors/utilities/juce_ParameterAttachments.h @@ -0,0 +1,251 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ + +/** Used to implement 'attachments' or 'controllers' that link a plug-in + parameter to a UI element. + + To implement a new attachment type, create a new class which includes an + instance of this class as a data member. Your class should pass a function + to the constructor of the ParameterAttachment, which will then be called on + the message thread when the parameter changes. You can use this function to + update the state of the UI control. Your class should also register as a + listener of the UI control and respond to respond to changes in the UI element + by calling either setValueAsCompleteGesture or beginGesture, + setValueAsPartOfGesture and endGesture. + + Make sure to call `sendInitialUpdate` at the end of your new attachment's + constructor, so that the UI immediately reflects the state of the parameter. + + @tags{Audio} +*/ +class ParameterAttachment : private AudioProcessorParameter::Listener, + private AsyncUpdater +{ +public: + /** Listens to a parameter and calls the the provided function in response to + parameter changes. If an undoManager is supplied `beginNewTransaction` will + be called on it whenever the UI requests a parameter change via this attachment. + + @param parameter The parameter to which this attachment will listen + @param parameterChangedCallback The function that will be called on the message thread in response + to parameter changes + @param undoManager The UndoManager that will be used to begin transactions when the UI + requests a parameter change. + */ + ParameterAttachment (RangedAudioParameter& parameter, + std::function<void (float)> parameterChangedCallback, + UndoManager* undoManager = nullptr); + + /** Destructor. */ + ~ParameterAttachment() override; + + /** Calls the parameterChangedCallback function that was registered in + the constructor, making the UI reflect the current parameter state. + + This function should be called after doing any necessary setup on + the UI control that is being managed (e.g. adding ComboBox entries, + making buttons toggle-able). + */ + void sendInitialUpdate(); + + /** Triggers a full gesture message on the managed parameter. + + Call this in the listener callback of the UI control in response + to a one-off change in the UI like a button-press. + */ + void setValueAsCompleteGesture (float newDenormalisedValue); + + /** Begins a gesture on the managed parameter. + + Call this when the UI is about to begin a continuous interaction, + like when the mouse button is pressed on a slider. + */ + void beginGesture(); + + /** Updates the parameter value during a gesture. + + Call this during a continuous interaction, like a slider value + changed callback. + */ + void setValueAsPartOfGesture (float newDenormalisedValue); + + /** Ends a gesture on the managed parameter. + + Call this when the UI has finished a continuous interaction, + like when the mouse button is released on a slider. + */ + void endGesture(); + +private: + float normalise (float f) const { return parameter.convertTo0to1 (f); } + + template <typename Callback> + void callIfParameterValueChanged (float newDenormalisedValue, Callback&& callback); + + void parameterValueChanged (int, float) override; + void parameterGestureChanged (int, bool) override {} + void handleAsyncUpdate() override; + + RangedAudioParameter& parameter; + std::atomic<float> lastValue { 0.0f }; + UndoManager* undoManager = nullptr; + std::function<void (float)> setValue; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ParameterAttachment) +}; + +//============================================================================== +/** An object of this class maintains a connection between a Slider and a + plug-in parameter. + + During the lifetime of this object it keeps the two things in sync, making + it easy to connect a slider to a parameter. When this object is deleted, the + connection is broken. Make sure that your parameter and Slider are not + deleted before this object! + + @tags{Audio} +*/ +class SliderParameterAttachment : private Slider::Listener +{ +public: + /** Creates a connection between a plug-in parameter and a Slider. + + @param parameter The parameter to use + @param slider The Slider to use + @param undoManager An optional UndoManager + */ + SliderParameterAttachment (RangedAudioParameter& parameter, Slider& slider, + UndoManager* undoManager = nullptr); + + /** Destructor. */ + ~SliderParameterAttachment() override; + + /** Call this after setting up your slider in the case where you need to do + extra setup after constructing this attachment. + */ + void sendInitialUpdate(); + +private: + void setValue (float newValue); + void sliderValueChanged (Slider*) override; + + void sliderDragStarted (Slider*) override { attachment.beginGesture(); } + void sliderDragEnded (Slider*) override { attachment.endGesture(); } + + Slider& slider; + ParameterAttachment attachment; + bool ignoreCallbacks = false; +}; + +//============================================================================== +/** An object of this class maintains a connection between a ComboBox and a + plug-in parameter. + + ComboBox items will be spaced linearly across the range of the parameter. For + example if the range is specified by NormalisableRange<float> (-0.5f, 0.5f, 0.5f) + and you add three items then the first will be mapped to a value of -0.5, the + second to 0, and the third to 0.5. + + During the lifetime of this object it keeps the two things in sync, making it + easy to connect a combo box to a parameter. When this object is deleted, the + connection is broken. Make sure that your parameter and ComboBox are not deleted + before this object! + + @tags{Audio} +*/ +class ComboBoxParameterAttachment : private ComboBox::Listener +{ +public: + /** Creates a connection between a plug-in parameter and a ComboBox. + + @param parameter The parameter to use + @param combo The ComboBox to use + @param undoManager An optional UndoManager + */ + ComboBoxParameterAttachment (RangedAudioParameter& parameter, ComboBox& combo, + UndoManager* undoManager = nullptr); + + /** Destructor. */ + ~ComboBoxParameterAttachment() override; + + /** Call this after setting up your combo box in the case where you need to do + extra setup after constructing this attachment. + */ + void sendInitialUpdate(); + +private: + void setValue (float newValue); + void comboBoxChanged (ComboBox*) override; + + ComboBox& comboBox; + RangedAudioParameter& storedParameter; + ParameterAttachment attachment; + bool ignoreCallbacks = false; +}; + +//============================================================================== +/** An object of this class maintains a connection between a Button and a + plug-in parameter. + + During the lifetime of this object it keeps the two things in sync, making it + easy to connect a button to a parameter. When this object is deleted, the + connection is broken. Make sure that your parameter and Button are not deleted + before this object! + + @tags{Audio} +*/ +class ButtonParameterAttachment : private Button::Listener +{ +public: + /** Creates a connection between a plug-in parameter and a Button. + + @param parameter The parameter to use + @param button The Button to use + @param undoManager An optional UndoManager + */ + ButtonParameterAttachment (RangedAudioParameter& parameter, Button& button, + UndoManager* undoManager = nullptr); + + /** Destructor. */ + ~ButtonParameterAttachment() override; + + /** Call this after setting up your button in the case where you need to do + extra setup after constructing this attachment. + */ + void sendInitialUpdate(); + +private: + void setValue (float newValue); + void buttonClicked (Button*) override; + + Button& button; + ParameterAttachment attachment; + bool ignoreCallbacks = false; +}; + +} // namespace juce diff --git a/modules/juce_audio_processors/utilities/juce_RangedAudioParameter.cpp b/modules/juce_audio_processors/utilities/juce_RangedAudioParameter.cpp index 69b7522d..99226e49 100644 --- a/modules/juce_audio_processors/utilities/juce_RangedAudioParameter.cpp +++ b/modules/juce_audio_processors/utilities/juce_RangedAudioParameter.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_processors/utilities/juce_RangedAudioParameter.h b/modules/juce_audio_processors/utilities/juce_RangedAudioParameter.h index 6ff66f18..30695fea 100644 --- a/modules/juce_audio_processors/utilities/juce_RangedAudioParameter.h +++ b/modules/juce_audio_processors/utilities/juce_RangedAudioParameter.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_utils/audio_cd/juce_AudioCDBurner.h b/modules/juce_audio_utils/audio_cd/juce_AudioCDBurner.h index b74019dd..2d82d3a6 100644 --- a/modules/juce_audio_utils/audio_cd/juce_AudioCDBurner.h +++ b/modules/juce_audio_utils/audio_cd/juce_AudioCDBurner.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_utils/audio_cd/juce_AudioCDReader.cpp b/modules/juce_audio_utils/audio_cd/juce_AudioCDReader.cpp index f632d65b..78f193e2 100644 --- a/modules/juce_audio_utils/audio_cd/juce_AudioCDReader.cpp +++ b/modules/juce_audio_utils/audio_cd/juce_AudioCDReader.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_utils/audio_cd/juce_AudioCDReader.h b/modules/juce_audio_utils/audio_cd/juce_AudioCDReader.h index 66a822f4..4b776d36 100644 --- a/modules/juce_audio_utils/audio_cd/juce_AudioCDReader.h +++ b/modules/juce_audio_utils/audio_cd/juce_AudioCDReader.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -67,7 +66,7 @@ public: //============================================================================== /** Destructor. */ - ~AudioCDReader(); + ~AudioCDReader() override; /** Implementation of the AudioFormatReader method. */ bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, diff --git a/modules/juce_audio_utils/gui/juce_AudioAppComponent.cpp b/modules/juce_audio_utils/gui/juce_AudioAppComponent.cpp index 78a0909e..a6a2177c 100644 --- a/modules/juce_audio_utils/gui/juce_AudioAppComponent.cpp +++ b/modules/juce_audio_utils/gui/juce_AudioAppComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_utils/gui/juce_AudioAppComponent.h b/modules/juce_audio_utils/gui/juce_AudioAppComponent.h index e64eeccc..4d3b828a 100644 --- a/modules/juce_audio_utils/gui/juce_AudioAppComponent.h +++ b/modules/juce_audio_utils/gui/juce_AudioAppComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.cpp b/modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.cpp index 780089e0..50cae68e 100644 --- a/modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.cpp +++ b/modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -110,12 +109,12 @@ public: bool enabled = deviceManager.isMidiInputDeviceEnabled (item.identifier); auto x = getTickX(); - auto tickW = height * 0.75f; + auto tickW = (float) height * 0.75f; - getLookAndFeel().drawTickBox (g, *this, x - tickW, (height - tickW) / 2, tickW, tickW, + getLookAndFeel().drawTickBox (g, *this, (float) x - tickW, ((float) height - tickW) * 0.5f, tickW, tickW, enabled, true, true, false); - g.setFont (height * 0.6f); + g.setFont ((float) height * 0.6f); g.setColour (findColour (ListBox::textColourId, true).withMultipliedAlpha (enabled ? 1.0f : 0.6f)); g.drawText (item.name, x + 5, 0, width - x - 5, height, Justification::centredLeft, true); } @@ -146,7 +145,7 @@ public: if (items.isEmpty()) { g.setColour (Colours::grey); - g.setFont (0.5f * getRowHeight()); + g.setFont (0.5f * (float) getRowHeight()); g.drawText (noItemsMessage, 0, 0, getWidth(), getHeight() / 2, Justification::centred, true); @@ -801,12 +800,12 @@ public: } auto x = getTickX(); - auto tickW = height * 0.75f; + auto tickW = (float) height * 0.75f; - getLookAndFeel().drawTickBox (g, *this, x - tickW, (height - tickW) / 2, tickW, tickW, + getLookAndFeel().drawTickBox (g, *this, (float) x - tickW, ((float) height - tickW) * 0.5f, tickW, tickW, enabled, true, true, false); - g.setFont (height * 0.6f); + g.setFont ((float) height * 0.6f); g.setColour (findColour (ListBox::textColourId, true).withMultipliedAlpha (enabled ? 1.0f : 0.6f)); g.drawText (item, x + 5, 0, width - x - 5, height, Justification::centredLeft, true); } @@ -837,7 +836,7 @@ public: if (items.isEmpty()) { g.setColour (Colours::grey); - g.setFont (0.5f * getRowHeight()); + g.setFont (0.5f * (float) getRowHeight()); g.drawText (noItemsMessage, 0, 0, getWidth(), getHeight() / 2, Justification::centred, true); diff --git a/modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.h b/modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.h index b323bbad..354d0de6 100644 --- a/modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.h +++ b/modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_utils/gui/juce_AudioThumbnail.cpp b/modules/juce_audio_utils/gui/juce_AudioThumbnail.cpp index 6d289d11..a02d92ec 100644 --- a/modules/juce_audio_utils/gui/juce_AudioThumbnail.cpp +++ b/modules/juce_audio_utils/gui/juce_AudioThumbnail.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -220,7 +219,7 @@ private: { if (reader == nullptr && source != nullptr) if (auto* audioFileStream = source->createInputStream()) - reader.reset (owner.formatManagerToUse.createReaderFor (audioFileStream)); + reader.reset (owner.formatManagerToUse.createReaderFor (std::unique_ptr<InputStream> (audioFileStream))); } bool readNextBlock() @@ -754,7 +753,7 @@ int AudioThumbnail::getNumChannels() const noexcept double AudioThumbnail::getTotalLength() const noexcept { - return sampleRate > 0 ? (totalSamples / sampleRate) : 0; + return sampleRate > 0 ? ((double) totalSamples / sampleRate) : 0.0; } bool AudioThumbnail::isFullyLoaded() const noexcept @@ -764,7 +763,7 @@ bool AudioThumbnail::isFullyLoaded() const noexcept double AudioThumbnail::getProportionComplete() const noexcept { - return jlimit (0.0, 1.0, numSamplesFinished / (double) jmax ((int64) 1, totalSamples.load())); + return jlimit (0.0, 1.0, (double) numSamplesFinished / (double) jmax ((int64) 1, totalSamples.load())); } int64 AudioThumbnail::getNumSamplesFinished() const noexcept @@ -780,7 +779,7 @@ float AudioThumbnail::getApproximatePeak() const for (auto* c : channels) peak = jmax (peak, c->getPeak()); - return jlimit (0, 127, peak) / 127.0f; + return (float) jlimit (0, 127, peak) / 127.0f; } void AudioThumbnail::getApproximateMinMax (double startTime, double endTime, int channelIndex, diff --git a/modules/juce_audio_utils/gui/juce_AudioThumbnail.h b/modules/juce_audio_utils/gui/juce_AudioThumbnail.h index 6dc133bb..7987e765 100644 --- a/modules/juce_audio_utils/gui/juce_AudioThumbnail.h +++ b/modules/juce_audio_utils/gui/juce_AudioThumbnail.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_utils/gui/juce_AudioThumbnailBase.h b/modules/juce_audio_utils/gui/juce_AudioThumbnailBase.h index 56a5fa9d..6c0d5727 100644 --- a/modules/juce_audio_utils/gui/juce_AudioThumbnailBase.h +++ b/modules/juce_audio_utils/gui/juce_AudioThumbnailBase.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_utils/gui/juce_AudioThumbnailCache.cpp b/modules/juce_audio_utils/gui/juce_AudioThumbnailCache.cpp index 7157cfbe..8685fb97 100644 --- a/modules/juce_audio_utils/gui/juce_AudioThumbnailCache.cpp +++ b/modules/juce_audio_utils/gui/juce_AudioThumbnailCache.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -155,7 +154,7 @@ void AudioThumbnailCache::removeThumb (const int64 hashCode) thumbs.remove (i); } -static inline int getThumbnailCacheFileMagicHeader() noexcept +static int getThumbnailCacheFileMagicHeader() noexcept { return (int) ByteOrder::littleEndianInt ("ThmC"); } diff --git a/modules/juce_audio_utils/gui/juce_AudioThumbnailCache.h b/modules/juce_audio_utils/gui/juce_AudioThumbnailCache.h index 3608fbc3..71a3d1af 100644 --- a/modules/juce_audio_utils/gui/juce_AudioThumbnailCache.h +++ b/modules/juce_audio_utils/gui/juce_AudioThumbnailCache.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_utils/gui/juce_AudioVisualiserComponent.cpp b/modules/juce_audio_utils/gui/juce_AudioVisualiserComponent.cpp index aeccf198..5bf3af77 100644 --- a/modules/juce_audio_utils/gui/juce_AudioVisualiserComponent.cpp +++ b/modules/juce_audio_utils/gui/juce_AudioVisualiserComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -179,7 +178,7 @@ void AudioVisualiserComponent::paint (Graphics& g) g.fillAll (backgroundColour); auto r = getLocalBounds().toFloat(); - auto channelHeight = r.getHeight() / channels.size(); + auto channelHeight = r.getHeight() / (float) channels.size(); g.setColour (waveformColour); diff --git a/modules/juce_audio_utils/gui/juce_AudioVisualiserComponent.h b/modules/juce_audio_utils/gui/juce_AudioVisualiserComponent.h index ca3a2c7c..7f4a69e0 100644 --- a/modules/juce_audio_utils/gui/juce_AudioVisualiserComponent.h +++ b/modules/juce_audio_utils/gui/juce_AudioVisualiserComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_utils/gui/juce_BluetoothMidiDevicePairingDialogue.h b/modules/juce_audio_utils/gui/juce_BluetoothMidiDevicePairingDialogue.h index a0aa70d0..f56b19d0 100644 --- a/modules/juce_audio_utils/gui/juce_BluetoothMidiDevicePairingDialogue.h +++ b/modules/juce_audio_utils/gui/juce_BluetoothMidiDevicePairingDialogue.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_utils/gui/juce_MidiKeyboardComponent.cpp b/modules/juce_audio_utils/gui/juce_MidiKeyboardComponent.cpp index 82f2c76c..5bbe5b2c 100644 --- a/modules/juce_audio_utils/gui/juce_MidiKeyboardComponent.cpp +++ b/modules/juce_audio_utils/gui/juce_MidiKeyboardComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -221,7 +220,7 @@ Range<float> MidiKeyboardComponent::getKeyPosition (int midiNoteNumber, float ta auto octave = midiNoteNumber / 12; auto note = midiNoteNumber % 12; - auto start = octave * 7.0f * targetKeyWidth + notePos[note] * targetKeyWidth; + auto start = (float) octave * 7.0f * targetKeyWidth + notePos[note] * targetKeyWidth; auto width = MidiMessage::isMidiNoteBlack (note) ? blackNoteWidthRatio * targetKeyWidth : targetKeyWidth; return { start, start + width }; @@ -249,8 +248,8 @@ Rectangle<float> MidiKeyboardComponent::getRectangleForKey (int note) const switch (orientation) { case horizontalKeyboard: return { x, 0, w, blackNoteLength }; - case verticalKeyboardFacingLeft: return { getWidth() - blackNoteLength, x, blackNoteLength, w }; - case verticalKeyboardFacingRight: return { 0, getHeight() - x - w, blackNoteLength, w }; + case verticalKeyboardFacingLeft: return { (float) getWidth() - blackNoteLength, x, blackNoteLength, w }; + case verticalKeyboardFacingRight: return { 0, (float) getHeight() - x - w, blackNoteLength, w }; default: jassertfalse; break; } } @@ -260,7 +259,7 @@ Rectangle<float> MidiKeyboardComponent::getRectangleForKey (int note) const { case horizontalKeyboard: return { x, 0, w, (float) getHeight() }; case verticalKeyboardFacingLeft: return { 0, x, (float) getWidth(), w }; - case verticalKeyboardFacingRight: return { 0, getHeight() - x - w, (float) getWidth(), w }; + case verticalKeyboardFacingRight: return { 0, (float) getHeight() - x - w, (float) getWidth(), w }; default: jassertfalse; break; } } @@ -296,9 +295,9 @@ int MidiKeyboardComponent::xyToNote (Point<float> pos, float& mousePositionVeloc p = { p.y, p.x }; if (orientation == verticalKeyboardFacingLeft) - p = { p.x, getWidth() - p.y }; + p = { p.x, (float) getWidth() - p.y }; else - p = { getHeight() - p.x, p.y }; + p = { (float) getHeight() - p.x, p.y }; } return remappedXYToNote (p + Point<float> (xOffset, 0), mousePositionVelocity); @@ -383,8 +382,8 @@ void MidiKeyboardComponent::paint (Graphics& g) if (orientation == verticalKeyboardFacingLeft) { - x1 = width - 1.0f; - x2 = width - 5.0f; + x1 = (float) width - 1.0f; + x2 = (float) width - 5.0f; } else if (orientation == verticalKeyboardFacingRight) x2 = 5.0f; @@ -401,7 +400,7 @@ void MidiKeyboardComponent::paint (Graphics& g) switch (orientation) { case horizontalKeyboard: g.fillRect (0.0f, 0.0f, x, 5.0f); break; - case verticalKeyboardFacingLeft: g.fillRect (width - 5.0f, 0.0f, 5.0f, x); break; + case verticalKeyboardFacingLeft: g.fillRect ((float) width - 5.0f, 0.0f, 5.0f, x); break; case verticalKeyboardFacingRight: g.fillRect (0.0f, 0.0f, 5.0f, x); break; default: break; } @@ -413,9 +412,9 @@ void MidiKeyboardComponent::paint (Graphics& g) switch (orientation) { - case horizontalKeyboard: g.fillRect (0.0f, height - 1.0f, x, 1.0f); break; + case horizontalKeyboard: g.fillRect (0.0f, (float) height - 1.0f, x, 1.0f); break; case verticalKeyboardFacingLeft: g.fillRect (0.0f, 0.0f, 1.0f, x); break; - case verticalKeyboardFacingRight: g.fillRect (width - 1.0f, 0.0f, 1.0f, x); break; + case verticalKeyboardFacingRight: g.fillRect ((float) width - 1.0f, 0.0f, 1.0f, x); break; default: break; } } @@ -562,7 +561,7 @@ void MidiKeyboardComponent::drawUpDownButton (Graphics& g, int w, int h, g.setColour (findColour (upDownButtonArrowColourId) .withAlpha (buttonDown ? 1.0f : (mouseOver ? 0.6f : 0.4f))); - g.fillPath (path, path.getTransformToScaleToFit (1.0f, 1.0f, w - 2.0f, h - 2.0f, true)); + g.fillPath (path, path.getTransformToScaleToFit (1.0f, 1.0f, (float) w - 2.0f, (float) h - 2.0f, true)); } void MidiKeyboardComponent::setBlackNoteLengthProportion (float ratio) noexcept @@ -579,7 +578,7 @@ void MidiKeyboardComponent::setBlackNoteLengthProportion (float ratio) noexcept float MidiKeyboardComponent::getBlackNoteLength() const noexcept { auto whiteNoteLength = orientation == horizontalKeyboard ? getHeight() : getWidth(); - return whiteNoteLength * blackNoteLengthRatio; + return (float) whiteNoteLength * blackNoteLengthRatio; } void MidiKeyboardComponent::setBlackNoteWidthProportion (float ratio) noexcept @@ -609,7 +608,7 @@ void MidiKeyboardComponent::resized() { auto kx1 = getKeyPos (rangeStart).getStart(); - if (kx2 - kx1 <= w) + if (kx2 - kx1 <= (float) w) { firstKey = (float) rangeStart; sendChangeMessage(); @@ -646,7 +645,7 @@ void MidiKeyboardComponent::resized() float mousePositionVelocity; auto spaceAvailable = w; - auto lastStartKey = remappedXYToNote ({ endOfLastKey - spaceAvailable, 0 }, mousePositionVelocity) + 1; + auto lastStartKey = remappedXYToNote ({ endOfLastKey - (float) spaceAvailable, 0 }, mousePositionVelocity) + 1; if (lastStartKey >= 0 && ((int) firstKey) > lastStartKey) { @@ -661,7 +660,7 @@ void MidiKeyboardComponent::resized() firstKey = (float) rangeStart; } - scrollUp->setVisible (canScroll && getKeyPos (rangeEnd).getStart() > w); + scrollUp->setVisible (canScroll && getKeyPos (rangeEnd).getStart() > (float) w); repaint(); } } diff --git a/modules/juce_audio_utils/gui/juce_MidiKeyboardComponent.h b/modules/juce_audio_utils/gui/juce_MidiKeyboardComponent.h index 6a76002f..fbf9811b 100644 --- a/modules/juce_audio_utils/gui/juce_MidiKeyboardComponent.h +++ b/modules/juce_audio_utils/gui/juce_MidiKeyboardComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -48,7 +47,7 @@ namespace juce @tags{Audio} */ class JUCE_API MidiKeyboardComponent : public Component, - public MidiKeyboardStateListener, + public MidiKeyboardState::Listener, public ChangeBroadcaster, private Timer { diff --git a/modules/juce_audio_utils/juce_audio_utils.cpp b/modules/juce_audio_utils/juce_audio_utils.cpp index 95ef694a..ce873805 100644 --- a/modules/juce_audio_utils/juce_audio_utils.cpp +++ b/modules/juce_audio_utils/juce_audio_utils.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_utils/juce_audio_utils.h b/modules/juce_audio_utils/juce_audio_utils.h index dd4f08dc..4f32a51a 100644 --- a/modules/juce_audio_utils/juce_audio_utils.h +++ b/modules/juce_audio_utils/juce_audio_utils.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -29,20 +28,20 @@ The block below describes the properties of this module, and is read by the Projucer to automatically generate project code that uses it. For details about the syntax and how to create or use a module, see the - JUCE Module Format.txt file. + JUCE Module Format.md file. BEGIN_JUCE_MODULE_DECLARATION ID: juce_audio_utils vendor: juce - version: 5.4.7 + version: 6.0.5 name: JUCE extra audio utility classes description: Classes for audio-related GUI and miscellaneous tasks. website: http://www.juce.com/juce license: GPL/Commercial - dependencies: juce_gui_extra, juce_audio_processors, juce_audio_formats, juce_audio_devices + dependencies: juce_audio_processors, juce_audio_formats, juce_audio_devices OSXFrameworks: CoreAudioKit DiscRecording iOSFrameworks: CoreAudioKit diff --git a/modules/juce_audio_utils/juce_audio_utils.mm b/modules/juce_audio_utils/juce_audio_utils.mm index e0a591cc..436d9c5e 100644 --- a/modules/juce_audio_utils/juce_audio_utils.mm +++ b/modules/juce_audio_utils/juce_audio_utils.mm @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_utils/native/juce_android_BluetoothMidiDevicePairingDialogue.cpp b/modules/juce_audio_utils/native/juce_android_BluetoothMidiDevicePairingDialogue.cpp index c981ad76..9f7cf1c1 100644 --- a/modules/juce_audio_utils/native/juce_android_BluetoothMidiDevicePairingDialogue.cpp +++ b/modules/juce_audio_utils/native/juce_android_BluetoothMidiDevicePairingDialogue.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -28,9 +27,9 @@ namespace juce { #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ - STATICMETHOD (getAndroidBluetoothManager, "getAndroidBluetoothManager", "(Landroid/content/Context;)Lcom/roli/juce/JuceMidiSupport$BluetoothManager;") + STATICMETHOD (getAndroidBluetoothManager, "getAndroidBluetoothManager", "(Landroid/content/Context;)Lcom/rmsl/juce/JuceMidiSupport$BluetoothManager;") -DECLARE_JNI_CLASS_WITH_MIN_SDK (AndroidJuceMidiSupport, "com/roli/juce/JuceMidiSupport", 23) +DECLARE_JNI_CLASS_WITH_MIN_SDK (AndroidJuceMidiSupport, "com/rmsl/juce/JuceMidiSupport", 23) #undef JNI_CLASS_MEMBERS #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ @@ -41,7 +40,7 @@ DECLARE_JNI_CLASS_WITH_MIN_SDK (AndroidJuceMidiSupport, "com/roli/juce/JuceMidiS METHOD (getBluetoothDeviceStatus, "getBluetoothDeviceStatus", "(Ljava/lang/String;)I") \ METHOD (startStopScan, "startStopScan", "(Z)V") -DECLARE_JNI_CLASS_WITH_MIN_SDK (AndroidBluetoothManager, "com/roli/juce/JuceMidiSupport$BluetoothManager", 23) +DECLARE_JNI_CLASS_WITH_MIN_SDK (AndroidBluetoothManager, "com/rmsl/juce/JuceMidiSupport$BluetoothManager", 23) #undef JNI_CLASS_MEMBERS //============================================================================== @@ -377,6 +376,7 @@ private: case AndroidBluetoothMidiInterface::paired: status = AndroidBluetoothMidiDevice::connected; break; + case AndroidBluetoothMidiInterface::unpaired: default: status = AndroidBluetoothMidiDevice::disconnected; } diff --git a/modules/juce_audio_utils/native/juce_ios_BluetoothMidiDevicePairingDialogue.mm b/modules/juce_audio_utils/native/juce_ios_BluetoothMidiDevicePairingDialogue.mm index 2b564aa1..dc81694f 100644 --- a/modules/juce_audio_utils/native/juce_ios_BluetoothMidiDevicePairingDialogue.mm +++ b/modules/juce_audio_utils/native/juce_ios_BluetoothMidiDevicePairingDialogue.mm @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_utils/native/juce_linux_AudioCDReader.cpp b/modules/juce_audio_utils/native/juce_linux_AudioCDReader.cpp index e9fe77dc..c6fba8e2 100644 --- a/modules/juce_audio_utils/native/juce_linux_AudioCDReader.cpp +++ b/modules/juce_audio_utils/native/juce_linux_AudioCDReader.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_utils/native/juce_linux_BluetoothMidiDevicePairingDialogue.cpp b/modules/juce_audio_utils/native/juce_linux_BluetoothMidiDevicePairingDialogue.cpp index 305c3a2c..aee48e37 100644 --- a/modules/juce_audio_utils/native/juce_linux_BluetoothMidiDevicePairingDialogue.cpp +++ b/modules/juce_audio_utils/native/juce_linux_BluetoothMidiDevicePairingDialogue.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_utils/native/juce_mac_AudioCDBurner.mm b/modules/juce_audio_utils/native/juce_mac_AudioCDBurner.mm index 79382604..bc3dcf22 100644 --- a/modules/juce_audio_utils/native/juce_mac_AudioCDBurner.mm +++ b/modules/juce_audio_utils/native/juce_mac_AudioCDBurner.mm @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -29,18 +28,17 @@ namespace juce const int kilobytesPerSecond1x = 176; -struct AudioTrackProducerClass : public ObjCClass <NSObject> +struct AudioTrackProducerClass : public ObjCClass<NSObject> { - AudioTrackProducerClass() : ObjCClass <NSObject> ("JUCEAudioTrackProducer_") + AudioTrackProducerClass() : ObjCClass<NSObject> ("JUCEAudioTrackProducer_") { addIvar<AudioSourceHolder*> ("source"); - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wundeclared-selector" + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wundeclared-selector") addMethod (@selector (initWithAudioSourceHolder:), initWithAudioSourceHolder, "@@:^v"); addMethod (@selector (verifyDataForTrack:intoBuffer:length:atAddress:blockSize:ioFlags:), produceDataForTrack, "I@:@^cIQI^I"); - #pragma clang diagnostic pop + JUCE_END_IGNORE_WARNINGS_GCC_LIKE addMethod (@selector (cleanupTrackAfterBurn:), cleanupTrackAfterBurn, "v@:@"); addMethod (@selector (cleanupTrackAfterVerification:), cleanupTrackAfterVerification, "c@:@"); @@ -75,7 +73,7 @@ struct AudioTrackProducerClass : public ObjCClass <NSObject> private: static id initWithAudioSourceHolder (id self, SEL, AudioSourceHolder* source) { - self = sendSuperclassMessage (self, @selector (init)); + self = sendSuperclassMessage<id> (self, @selector (init)); object_setInstanceVariable (self, "source", source); return self; } @@ -88,7 +86,7 @@ private: static void dealloc (id self, SEL) { delete getSource (self); - sendSuperclassMessage (self, @selector (dealloc)); + sendSuperclassMessage<void> (self, @selector (dealloc)); } static void cleanupTrackAfterBurn (id, SEL, DRTrack*) {} @@ -189,11 +187,10 @@ struct OpenDiskDevice static AudioTrackProducerClass cls; - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wundeclared-selector" + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wundeclared-selector") NSObject* producer = [cls.createInstance() performSelector: @selector (initWithAudioSourceHolder:) withObject: (id) new AudioTrackProducerClass::AudioSourceHolder (source, numFrames)]; - #pragma clang diagnostic pop + JUCE_END_IGNORE_WARNINGS_GCC_LIKE DRTrack* track = [[DRTrack alloc] initWithProducer: producer]; { @@ -275,7 +272,7 @@ struct OpenDiskDevice }; //============================================================================== -class AudioCDBurner::Pimpl : public Timer +class AudioCDBurner::Pimpl : private Timer { public: Pimpl (AudioCDBurner& b, int deviceIndex) : owner (b) @@ -288,22 +285,11 @@ public: } } - ~Pimpl() + ~Pimpl() override { stopTimer(); } - void timerCallback() override - { - const DiskState state = getDiskState(); - - if (state != lastState) - { - lastState = state; - owner.sendChangeMessage(); - } - } - DiskState getDiskState() const { if ([device->device isValid]) @@ -364,6 +350,17 @@ public: std::unique_ptr<OpenDiskDevice> device; private: + void timerCallback() override + { + const DiskState state = getDiskState(); + + if (state != lastState) + { + lastState = state; + owner.sendChangeMessage(); + } + } + DiskState lastState; AudioCDBurner& owner; }; diff --git a/modules/juce_audio_utils/native/juce_mac_AudioCDReader.mm b/modules/juce_audio_utils/native/juce_mac_AudioCDReader.mm index 6268396b..44e99251 100644 --- a/modules/juce_audio_utils/native/juce_mac_AudioCDReader.mm +++ b/modules/juce_audio_utils/native/juce_mac_AudioCDReader.mm @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -140,7 +139,7 @@ AudioCDReader* AudioCDReader::createReaderForCD (const int index) } AudioCDReader::AudioCDReader (const File& volume) - : AudioFormatReader (0, "CD Audio"), + : AudioFormatReader (nullptr, "CD Audio"), volumeDir (volume), currentReaderTrack (-1) { @@ -202,9 +201,9 @@ bool AudioCDReader::readSamples (int** destSamples, int numDestChannels, int sta { reader = nullptr; - if (FileInputStream* const in = tracks [track].createInputStream()) + if (auto in = tracks [track].createInputStream()) { - BufferedInputStream* const bin = new BufferedInputStream (in, 65536, true); + BufferedInputStream* const bin = new BufferedInputStream (in.release(), 65536, true); AiffAudioFormat format; reader.reset (format.createReaderFor (bin, true)); diff --git a/modules/juce_audio_utils/native/juce_mac_BluetoothMidiDevicePairingDialogue.mm b/modules/juce_audio_utils/native/juce_mac_BluetoothMidiDevicePairingDialogue.mm index eb1d1a13..39f442ac 100644 --- a/modules/juce_audio_utils/native/juce_mac_BluetoothMidiDevicePairingDialogue.mm +++ b/modules/juce_audio_utils/native/juce_mac_BluetoothMidiDevicePairingDialogue.mm @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -44,12 +43,11 @@ public: addIvar<Callbacks*> ("callbacks"); addIvar<CABTLEMIDIWindowController*> ("controller"); - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wundeclared-selector" + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wundeclared-selector") addMethod (@selector (initWithCallbacks:), initWithCallbacks, "@@:^v"); addMethod (@selector (show:), show, "v@:^v"); addMethod (@selector (receivedWindowWillClose:), receivedWindowWillClose, "v@:^v"); - #pragma clang diagnostic pop + JUCE_END_IGNORE_WARNINGS_GCC_LIKE addMethod (@selector (dealloc), dealloc, "v@:"); @@ -64,18 +62,17 @@ private: static id initWithCallbacks (id self, SEL, Callbacks* cbs) { - self = sendSuperclassMessage (self, @selector (init)); + self = sendSuperclassMessage<id> (self, @selector (init)); object_setInstanceVariable (self, "callbacks", cbs); object_setInstanceVariable (self, "controller", [CABTLEMIDIWindowController new]); - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wundeclared-selector" + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wundeclared-selector") [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector (receivedWindowWillClose:) name: @"NSWindowWillCloseNotification" object: [getController (self) window]]; - #pragma clang diagnostic pop + JUCE_END_IGNORE_WARNINGS_GCC_LIKE return self; } @@ -83,8 +80,7 @@ private: static void dealloc (id self, SEL) { [getController (self) release]; - - sendSuperclassMessage (self, @selector (dealloc)); + sendSuperclassMessage<void> (self, @selector (dealloc)); } static void show (id self, SEL, Rectangle<int>* bounds) @@ -145,13 +141,12 @@ public: callbacks.reset (new BluetoothMidiPairingWindowClass::Callbacks { std::move (exitCB), std::move (deletionCB) }); - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wundeclared-selector" + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wundeclared-selector") [window.get() performSelector: @selector (initWithCallbacks:) withObject: (id) callbacks.get()]; [window.get() performSelector: @selector (show:) withObject: (id) bounds]; - #pragma clang diagnostic pop + JUCE_END_IGNORE_WARNINGS_GCC_LIKE } private: diff --git a/modules/juce_audio_utils/native/juce_win32_AudioCDBurner.cpp b/modules/juce_audio_utils/native/juce_win32_AudioCDBurner.cpp index da880a27..c55e7ee1 100644 --- a/modules/juce_audio_utils/native/juce_win32_AudioCDBurner.cpp +++ b/modules/juce_audio_utils/native/juce_win32_AudioCDBurner.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_utils/native/juce_win32_AudioCDReader.cpp b/modules/juce_audio_utils/native/juce_win32_AudioCDReader.cpp index b0e081b2..0d50a35b 100644 --- a/modules/juce_audio_utils/native/juce_win32_AudioCDReader.cpp +++ b/modules/juce_audio_utils/native/juce_win32_AudioCDReader.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_utils/native/juce_win_BluetoothMidiDevicePairingDialogue.cpp b/modules/juce_audio_utils/native/juce_win_BluetoothMidiDevicePairingDialogue.cpp index d6e26401..5421dcc0 100644 --- a/modules/juce_audio_utils/native/juce_win_BluetoothMidiDevicePairingDialogue.cpp +++ b/modules/juce_audio_utils/native/juce_win_BluetoothMidiDevicePairingDialogue.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_utils/players/juce_AudioProcessorPlayer.cpp b/modules/juce_audio_utils/players/juce_AudioProcessorPlayer.cpp index 09861942..ec31b15f 100644 --- a/modules/juce_audio_utils/players/juce_AudioProcessorPlayer.cpp +++ b/modules/juce_audio_utils/players/juce_AudioProcessorPlayer.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -173,7 +172,18 @@ void AudioProcessorPlayer::audioDeviceIOCallback (const float** const inputChann } if (midiOutput != nullptr) - midiOutput->sendBlockOfMessagesNow (incomingMidi); + { + if (midiOutput->isBackgroundThreadRunning()) + { + midiOutput->sendBlockOfMessages (incomingMidi, + Time::getMillisecondCounterHiRes(), + sampleRate); + } + else + { + midiOutput->sendBlockOfMessagesNow (incomingMidi); + } + } return; } diff --git a/modules/juce_audio_utils/players/juce_AudioProcessorPlayer.h b/modules/juce_audio_utils/players/juce_AudioProcessorPlayer.h index 8349f82d..4458dd2a 100644 --- a/modules/juce_audio_utils/players/juce_AudioProcessorPlayer.h +++ b/modules/juce_audio_utils/players/juce_AudioProcessorPlayer.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_audio_utils/players/juce_SoundPlayer.cpp b/modules/juce_audio_utils/players/juce_SoundPlayer.cpp index 9df3ff3b..6b5bfbd5 100644 --- a/modules/juce_audio_utils/players/juce_SoundPlayer.cpp +++ b/modules/juce_audio_utils/players/juce_SoundPlayer.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -174,8 +173,8 @@ void SoundPlayer::play (const void* resourceData, size_t resourceSize) { if (resourceData != nullptr && resourceSize > 0) { - MemoryInputStream* mem = new MemoryInputStream (resourceData, resourceSize, false); - play (formatManager.createReaderFor (mem), true); + auto mem = std::make_unique<MemoryInputStream> (resourceData, resourceSize, false); + play (formatManager.createReaderFor (std::move (mem)), true); } } diff --git a/modules/juce_audio_utils/players/juce_SoundPlayer.h b/modules/juce_audio_utils/players/juce_SoundPlayer.h index 388f3b02..a985d5fa 100644 --- a/modules/juce_audio_utils/players/juce_SoundPlayer.h +++ b/modules/juce_audio_utils/players/juce_SoundPlayer.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_blocks_basics/blocks/juce_Block.cpp b/modules/juce_blocks_basics/blocks/juce_Block.cpp index 09f4d89f..ff014a5e 100644 --- a/modules/juce_blocks_basics/blocks/juce_Block.cpp +++ b/modules/juce_blocks_basics/blocks/juce_Block.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -74,9 +74,15 @@ bool Block::isControlBlock (Block::Type type) || type == Block::Type::developerControlBlock; } +void Block::addProgramLoadedListener (ProgramLoadedListener* listener) { programLoadedListeners.add (listener); } +void Block::removeProgramLoadedListener (ProgramLoadedListener* listener) { programLoadedListeners.remove (listener); } + void Block::addDataInputPortListener (DataInputPortListener* listener) { dataInputPortListeners.add (listener); } void Block::removeDataInputPortListener (DataInputPortListener* listener) { dataInputPortListeners.remove (listener); } +void Block::addConfigItemListener (ConfigItemListener* listener) { configItemListeners.add (listener); } +void Block::removeConfigItemListener (ConfigItemListener* listener) { configItemListeners.remove (listener); } + void Block::addProgramEventListener (ProgramEventListener* listener) { programEventListeners.add (listener); } void Block::removeProgramEventListener (ProgramEventListener* listener) { programEventListeners.remove (listener); } @@ -85,7 +91,6 @@ bool Block::ConnectionPort::operator== (const ConnectionPort& other) const noexc bool Block::ConnectionPort::operator!= (const ConnectionPort& other) const noexcept { return ! operator== (other); } Block::Program::Program (Block& b) : block (b) {} -Block::Program::~Program() {} //============================================================================== TouchSurface::TouchSurface (Block& b) : block (b) {} diff --git a/modules/juce_blocks_basics/blocks/juce_Block.h b/modules/juce_blocks_basics/blocks/juce_Block.h index b4717c94..a8b86f41 100644 --- a/modules/juce_blocks_basics/blocks/juce_Block.h +++ b/modules/juce_blocks_basics/blocks/juce_Block.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -148,7 +148,10 @@ public: virtual float getMillimetersPerUnit() const = 0; /** A simple struct representing the area of a block. */ - struct BlockArea { int x, y, width, height; }; + struct BlockArea + { + int x, y, width, height; + }; /** Returns the area that this block covers within the layout of the group as a whole. The coordinates are in logical block units, and are relative to the origin, which is the master block's top-left corner. @@ -232,11 +235,8 @@ public: /** A program that can be loaded onto a block. */ struct Program { - /** Creates a Program for the corresponding LEDGrid. */ Program (Block&); - - /** Destructor. */ - virtual ~Program(); + virtual ~Program() = default; /** Returns the LittleFoot program to execute on the BLOCKS device. */ virtual String getLittleFootProgram() = 0; @@ -251,12 +251,32 @@ public: The supplied Program's lifetime will be managed by this class, so do not use the Program in other places in your code. + + Optional parameter to determine if program is set temporarily or saved + to flash as the default prgram./ */ - virtual Result setProgram (Program*) = 0; + enum class ProgramPersistency { setAsTemp, setAsDefault }; + virtual Result setProgram (std::unique_ptr<Program>, + ProgramPersistency persistency = ProgramPersistency::setAsTemp) = 0; /** Returns a pointer to the currently loaded program. */ virtual Program* getProgram() const = 0; + /** Listener interface to be informed of program loaded events*/ + struct ProgramLoadedListener + { + virtual ~ProgramLoadedListener() = default; + + /** Called whenever a program has been loaded. */ + virtual void handleProgramLoaded (Block&) = 0; + }; + + /** Adds a new listener for program load completions. */ + void addProgramLoadedListener (ProgramLoadedListener*); + + /** Removes a listener for program load completions. */ + void removeProgramLoadedListener (ProgramLoadedListener*); + //============================================================================== /** A message that can be sent to the currently loaded program. */ struct ProgramEventMessage @@ -287,10 +307,10 @@ public: }; /** Adds a new listener for custom program events from the block. */ - virtual void addProgramEventListener (ProgramEventListener*); + void addProgramEventListener (ProgramEventListener*); /** Removes a listener for custom program events from the block. */ - virtual void removeProgramEventListener (ProgramEventListener*); + void removeProgramEventListener (ProgramEventListener*); //============================================================================== /** Returns the overall memory of the block. */ @@ -308,6 +328,20 @@ public: /** Sets multiple bits on the littlefoot heap. */ virtual void setDataBits (uint32 startBit, uint32 numBits, uint32 value) = 0; + /** Sets a single, 32 bit or less, value on the littlefoot heap. */ + template<typename Type> + void setData (uint32 offset, Type value) + { + const auto numBytes = sizeof (Type); + + for (auto byte = numBytes; --byte > 0u;) + { + auto v = *reinterpret_cast<unsigned*> (&value); + v = (v >> (numBytes - byte) * 8) & 0xFF; + setDataByte (offset + byte, uint8 (v)); + } + } + /** Gets a byte from the littlefoot heap. */ virtual uint8 getDataByte (size_t offset) = 0; @@ -332,7 +366,9 @@ public: options }; - ConfigMetaData() = default; + ConfigMetaData (uint32 itemIndex) + : item (itemIndex) + {} // Constructor to work around VS2015 bugs... ConfigMetaData (uint32 itemIndex, @@ -408,6 +444,24 @@ public: String group; }; + /** Listener interface to be informed of block config changes */ + struct ConfigItemListener + { + virtual ~ConfigItemListener() = default; + + /** Called whenever a config changes. */ + virtual void handleConfigItemChanged (Block&, const ConfigMetaData&, uint32 index) = 0; + + /*-* Callled following a config sync request*/ + virtual void handleConfigSyncEnded (Block&) = 0; + }; + + /** Adds a new listener for config item changes. */ + void addConfigItemListener (ConfigItemListener*); + + /** Removes a listener for config item changes. */ + void removeConfigItemListener (ConfigItemListener*); + /** Returns the maximum number of config items available */ virtual uint32 getMaxConfigIndex() = 0; @@ -449,17 +503,11 @@ public: //============================================================================== /** Allows the user to provide a function that will receive log messages from the block. */ - virtual void setLogger (std::function<void(const Block& block, const String&)> loggingCallback) = 0; + virtual void setLogger (std::function<void (const Block& block, const String&)> loggingCallback) = 0; /** Sends a firmware update packet to a block, and waits for a reply. Returns an error code. */ virtual bool sendFirmwareUpdatePacket (const uint8* data, uint8 size, - std::function<void(uint8, uint32)> packetAckCallback) = 0; - - /** Provides a callback that will be called when a config changes. */ - virtual void setConfigChangedCallback (std::function<void(Block&, const ConfigMetaData&, uint32)>) = 0; - - /** Provides a callback that will be called when a program has been loaded. */ - virtual void setProgramLoadedCallback (std::function<void(Block&)> programLoaded) = 0; + std::function<void (uint8, uint32)> packetAckCallback) = 0; //============================================================================== /** Interface for objects listening to input data port. */ @@ -491,8 +539,10 @@ protected: Block (const String& serialNumberToUse); Block (const String& serial, const String& version, const String& name); + ListenerList<ProgramLoadedListener> programLoadedListeners; + ListenerList<ProgramEventListener> programEventListeners; + ListenerList<ConfigItemListener> configItemListeners; ListenerList<DataInputPortListener> dataInputPortListeners; - ListenerList<ProgramEventListener> programEventListeners; private: //============================================================================== diff --git a/modules/juce_blocks_basics/blocks/juce_BlockConfigManager.h b/modules/juce_blocks_basics/blocks/juce_BlockConfigManager.h index b314ce8e..e578546a 100644 --- a/modules/juce_blocks_basics/blocks/juce_BlockConfigManager.h +++ b/modules/juce_blocks_basics/blocks/juce_BlockConfigManager.h @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited - Permission is granted to use this software under the terms of the ISC license - http://www.isc.org/downloads/software-support-policy/isc-license/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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. + 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. - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, - OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF - USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - OF THIS SOFTWARE. - - ----------------------------------------------------------------------------- - - To release a closed-source product which uses other parts of JUCE not - licensed under the ISC terms, commercial licenses are available: visit - www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -279,7 +271,7 @@ struct BlockConfigManager if (getIndexForItem (item, itemIndex)) return configList[itemIndex].toConfigMetaData(); - return {}; + return { static_cast<juce::uint32> (item) }; } void resetConfigListActiveStatus() diff --git a/modules/juce_blocks_basics/blocks/juce_BlocksVersion.cpp b/modules/juce_blocks_basics/blocks/juce_BlocksVersion.cpp index 884a0dbf..663c2000 100644 --- a/modules/juce_blocks_basics/blocks/juce_BlocksVersion.cpp +++ b/modules/juce_blocks_basics/blocks/juce_BlocksVersion.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -70,7 +70,7 @@ bool BlocksVersion::evaluate (const String& versionString) jassert (result); - auto toInt = [](const std::sub_match<const char*> match) + auto toInt = [] (const std::sub_match<const char*> match) { return std::atoi (match.str().c_str()); }; @@ -108,7 +108,7 @@ bool BlocksVersion::isGreaterThan (const BlocksVersion& other) const bool BlocksVersion::releaseTypeGreaterThan (const BlocksVersion& other) const { - auto getReleaseTypePriority = [](const BlocksVersion& version) + auto getReleaseTypePriority = [] (const BlocksVersion& version) { String releaseTypes[4] = { "alpha", "beta", "rc", {} }; diff --git a/modules/juce_blocks_basics/blocks/juce_BlocksVersion.h b/modules/juce_blocks_basics/blocks/juce_BlocksVersion.h index e20ad5f2..24524423 100644 --- a/modules/juce_blocks_basics/blocks/juce_BlocksVersion.h +++ b/modules/juce_blocks_basics/blocks/juce_BlocksVersion.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -25,6 +25,11 @@ namespace juce { +/** + Represents the version number of a block device. + + @tags{Blocks} +*/ struct BlocksVersion { public: diff --git a/modules/juce_blocks_basics/blocks/juce_ControlButton.h b/modules/juce_blocks_basics/blocks/juce_ControlButton.h index ec09b012..5cc77b6b 100644 --- a/modules/juce_blocks_basics/blocks/juce_ControlButton.h +++ b/modules/juce_blocks_basics/blocks/juce_ControlButton.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_blocks_basics/blocks/juce_LEDGrid.h b/modules/juce_blocks_basics/blocks/juce_LEDGrid.h index 192383f6..eaf279b3 100644 --- a/modules/juce_blocks_basics/blocks/juce_LEDGrid.h +++ b/modules/juce_blocks_basics/blocks/juce_LEDGrid.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_blocks_basics/blocks/juce_LEDRow.h b/modules/juce_blocks_basics/blocks/juce_LEDRow.h index c5e4eb54..f429ecab 100644 --- a/modules/juce_blocks_basics/blocks/juce_LEDRow.h +++ b/modules/juce_blocks_basics/blocks/juce_LEDRow.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_blocks_basics/blocks/juce_StatusLight.h b/modules/juce_blocks_basics/blocks/juce_StatusLight.h index c96307d7..2ac73478 100644 --- a/modules/juce_blocks_basics/blocks/juce_StatusLight.h +++ b/modules/juce_blocks_basics/blocks/juce_StatusLight.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_blocks_basics/blocks/juce_TouchList.h b/modules/juce_blocks_basics/blocks/juce_TouchList.h index 30ee8306..63a5ee68 100644 --- a/modules/juce_blocks_basics/blocks/juce_TouchList.h +++ b/modules/juce_blocks_basics/blocks/juce_TouchList.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_blocks_basics/blocks/juce_TouchSurface.h b/modules/juce_blocks_basics/blocks/juce_TouchSurface.h index c86b7499..280d2c12 100644 --- a/modules/juce_blocks_basics/blocks/juce_TouchSurface.h +++ b/modules/juce_blocks_basics/blocks/juce_TouchSurface.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_blocks_basics/juce_blocks_basics.cpp b/modules/juce_blocks_basics/juce_blocks_basics.cpp index 132dcfe0..74019a84 100644 --- a/modules/juce_blocks_basics/juce_blocks_basics.cpp +++ b/modules/juce_blocks_basics/juce_blocks_basics.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -22,12 +22,6 @@ #include "juce_blocks_basics.h" -#if ! JUCE_HAS_CONSTEXPR - #ifndef JUCE_DEMO_RUNNER - #error "The juce_blocks_basics module requires a compiler that supports constexpr" - #endif -#else - #include <regex> namespace juce @@ -48,5 +42,3 @@ namespace juce #include "topology/juce_RuleBasedTopologySource.cpp" #include "visualisers/juce_DrumPadLEDProgram.cpp" #include "visualisers/juce_BitmapLEDProgram.cpp" - -#endif diff --git a/modules/juce_blocks_basics/juce_blocks_basics.h b/modules/juce_blocks_basics/juce_blocks_basics.h index 2e58ee53..1058aa45 100644 --- a/modules/juce_blocks_basics/juce_blocks_basics.h +++ b/modules/juce_blocks_basics/juce_blocks_basics.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -25,21 +25,21 @@ The block below describes the properties of this module, and is read by the Projucer to automatically generate project code that uses it. For details about the syntax and how to create or use a module, see the - JUCE Module Format.txt file. + JUCE Module Format.md file. BEGIN_JUCE_MODULE_DECLARATION ID: juce_blocks_basics vendor: juce - version: 5.4.7 + version: 6.0.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 license: ISC minimumCppStandard: 14 - dependencies: juce_events juce_audio_devices + dependencies: juce_audio_devices END_JUCE_MODULE_DECLARATION @@ -52,12 +52,6 @@ #include <juce_events/juce_events.h> #include <juce_audio_devices/juce_audio_devices.h> -#if ! JUCE_HAS_CONSTEXPR - #ifndef JUCE_DEMO_RUNNER - #error "The juce_blocks_basics module requires a compiler that supports constexpr" - #endif -#else - namespace juce { class TouchSurface; @@ -89,5 +83,3 @@ namespace juce #include "littlefoot/juce_LittleFootRunner.h" #include "littlefoot/juce_LittleFootCompiler.h" } - -#endif diff --git a/modules/juce_blocks_basics/littlefoot/juce_LittleFootCompiler.h b/modules/juce_blocks_basics/littlefoot/juce_LittleFootCompiler.h index 174fa74e..6f3d1166 100644 --- a/modules/juce_blocks_basics/littlefoot/juce_LittleFootCompiler.h +++ b/modules/juce_blocks_basics/littlefoot/juce_LittleFootCompiler.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -20,10 +20,7 @@ ============================================================================== */ -#if JUCE_MSVC - #pragma warning (push) - #pragma warning (disable: 4702) -#endif +JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4702) namespace littlefoot { @@ -87,6 +84,31 @@ struct Compiler return Program (compiledObjectCode.begin(), (uint32) compiledObjectCode.size()); } + static File resolveIncludePath (String include, Array<File> searchPaths) + { + if (File::isAbsolutePath (include) && File (include).existsAsFile()) + return { include }; + + auto fileName = include.fromLastOccurrenceOf ("/", false, false); + + for (auto path : searchPaths) + { + if (path == File()) + continue; + + if (! path.isDirectory()) + path = path.getParentDirectory(); + + if (path.getChildFile (include).existsAsFile()) + return path.getChildFile (include); + + if (path.getChildFile (fileName).existsAsFile()) + return path.getChildFile (fileName); + } + + return {}; + } + /** After a successful call to compile(), this contains the bytecode generated. A littlefoot::Program object can be created directly from this array. */ @@ -522,27 +544,12 @@ private: return {}; } - if (File::isAbsolutePath (include) && File (include).existsAsFile()) - return { include }; - - auto fileName = include.fromLastOccurrenceOf ("/", false, false); + auto path = Compiler::resolveIncludePath (include, searchPaths); - for (auto path : searchPaths) - { - if (path == File()) - continue; - - if (! path.isDirectory()) - path = path.getParentDirectory(); - - if (path.getChildFile (include).existsAsFile()) - return path.getChildFile (include); - - if (path.getChildFile (fileName).existsAsFile()) - return path.getChildFile (fileName); - } + if (! path.existsAsFile()) + location.throwError ("File not found: " + include); - location.throwError ("File not found: " + include); + return path; } //TODO: should there be a max array size? @@ -2444,6 +2451,4 @@ private: } -#if JUCE_MSVC - #pragma warning (pop) -#endif +JUCE_END_IGNORE_WARNINGS_MSVC diff --git a/modules/juce_blocks_basics/littlefoot/juce_LittleFootRemoteHeap.h b/modules/juce_blocks_basics/littlefoot/juce_LittleFootRemoteHeap.h index 04524479..4a2372d8 100644 --- a/modules/juce_blocks_basics/littlefoot/juce_LittleFootRemoteHeap.h +++ b/modules/juce_blocks_basics/littlefoot/juce_LittleFootRemoteHeap.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_blocks_basics/littlefoot/juce_LittleFootRunner.h b/modules/juce_blocks_basics/littlefoot/juce_LittleFootRunner.h index aca029fe..95f901e1 100644 --- a/modules/juce_blocks_basics/littlefoot/juce_LittleFootRunner.h +++ b/modules/juce_blocks_basics/littlefoot/juce_LittleFootRunner.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -238,7 +238,7 @@ struct Program auto n = (uint16) size; for (uint32 i = 2; i < size; ++i) - n += (n * 2) + programStart[i]; + n = static_cast<uint16> (n + (n * 2) + programStart[i]); return n; } @@ -336,7 +336,8 @@ struct Program #undef LITTLEFOOT_OP_INT16 #undef LITTLEFOOT_OP_INT32 - default: s << "???"; break; + case OpCode::endOfOpcodes: + default: s << "???"; break; } return s; @@ -370,8 +371,11 @@ struct Program #undef LITTLEFOOT_OP_INT16 #undef LITTLEFOOT_OP_INT32 - default: jassertfalse; return 0; + case OpCode::endOfOpcodes: + default: jassertfalse; break; } + + return 0; } //============================================================================== @@ -676,6 +680,7 @@ struct Runner switch (op) { LITTLEFOOT_OPCODES (LITTLEFOOT_PERFORM_OP, LITTLEFOOT_PERFORM_OP_INT8, LITTLEFOOT_PERFORM_OP_INT16, LITTLEFOOT_PERFORM_OP_INT32) + case OpCode::endOfOpcodes: default: setError (ErrorCode::unknownInstruction); break; } diff --git a/modules/juce_blocks_basics/protocol/juce_BitPackingUtilities.h b/modules/juce_blocks_basics/protocol/juce_BitPackingUtilities.h index fe2eadb4..baad6b68 100644 --- a/modules/juce_blocks_basics/protocol/juce_BitPackingUtilities.h +++ b/modules/juce_blocks_basics/protocol/juce_BitPackingUtilities.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -39,7 +39,7 @@ static uint8 calculatePacketChecksum (const uint8* data, uint32 size) noexcept uint8 checksum = (uint8) size; for (uint32 i = 0; i < size; ++i) - checksum += checksum * 2 + data[i]; + checksum = static_cast<uint8> (checksum + (checksum * 2 + data[i])); return checksum & 0x7f; } @@ -79,8 +79,8 @@ struct IntegerWithBitSize : (uint32) (value >> (numBits - 8))); } - float toUnipolarFloat() const noexcept { return value / (float) maxValue; } - float toBipolarFloat() const noexcept { return static_cast<int32> (value << (32 - numBits)) / (float) 0x80000000u; } + float toUnipolarFloat() const noexcept { return (float) value / (float) maxValue; } + float toBipolarFloat() const noexcept { return (float) static_cast<int32> (value << (32 - numBits)) / (float) 0x80000000u; } static IntegerWithBitSize fromUnipolarFloat (float value) noexcept { @@ -181,7 +181,7 @@ struct Packed7BitArrayBuilder { const int bitsToDo = jmin (7 - bitsInCurrentByte, numBits); - data[bytesWritten] |= ((value & (uint32) ((1 << bitsToDo) - 1)) << bitsInCurrentByte); + data[bytesWritten] = static_cast<uint8> (data[bytesWritten] | ((value & (uint32) ((1 << bitsToDo) - 1)) << bitsInCurrentByte)); value >>= bitsToDo; numBits -= bitsToDo; bitsInCurrentByte += bitsToDo; diff --git a/modules/juce_blocks_basics/protocol/juce_BlockModels.h b/modules/juce_blocks_basics/protocol/juce_BlockModels.h index 709697ad..e4ecab7b 100644 --- a/modules/juce_blocks_basics/protocol/juce_BlockModels.h +++ b/modules/juce_blocks_basics/protocol/juce_BlockModels.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -345,14 +345,16 @@ static const char* getButtonNameForFunction (ControlButton::ButtonFunction fn) n case BF::button6: return "6"; case BF::button7: return "7"; - case BF::velocitySensitivity: return "Velocity Sensitivity"; - case BF::glideSensitivity: return "Glide Sensitivity"; - case BF::slideSensitivity: return "Slide Sensitivity"; - case BF::pressSensitivity: return "Press Sensitivity"; - case BF::liftSensitivity: return "Lift Sensitivity"; - case BF::fixedVelocity: return "Fixed Velocity"; - case BF::glideLock: return "Glide Lock"; - case BF::pianoMode: return "Piano Mode"; + case BF::velocitySensitivity: return "Velocity Sensitivity"; + case BF::glideSensitivity: return "Glide Sensitivity"; + case BF::slideSensitivity: return "Slide Sensitivity"; + case BF::pressSensitivity: return "Press Sensitivity"; + case BF::liftSensitivity: return "Lift Sensitivity"; + case BF::fixedVelocity: return "Fixed Velocity"; + case BF::glideLock: return "Glide Lock"; + case BF::pianoMode: return "Piano Mode"; + + default: break; } jassertfalse; diff --git a/modules/juce_blocks_basics/protocol/juce_BlocksProtocolDefinitions.h b/modules/juce_blocks_basics/protocol/juce_BlocksProtocolDefinitions.h index 7a80fe5a..43641c2b 100644 --- a/modules/juce_blocks_basics/protocol/juce_BlocksProtocolDefinitions.h +++ b/modules/juce_blocks_basics/protocol/juce_BlocksProtocolDefinitions.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_blocks_basics/protocol/juce_HostPacketBuilder.h b/modules/juce_blocks_basics/protocol/juce_HostPacketBuilder.h index 16e016dd..98efd3ec 100644 --- a/modules/juce_blocks_basics/protocol/juce_HostPacketBuilder.h +++ b/modules/juce_blocks_basics/protocol/juce_HostPacketBuilder.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_blocks_basics/protocol/juce_HostPacketDecoder.h b/modules/juce_blocks_basics/protocol/juce_HostPacketDecoder.h index 0304105e..b3a7e007 100644 --- a/modules/juce_blocks_basics/protocol/juce_HostPacketDecoder.h +++ b/modules/juce_blocks_basics/protocol/juce_HostPacketDecoder.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_blocks_basics/topology/internal/juce_BandwidthStatsLogger.cpp b/modules/juce_blocks_basics/topology/internal/juce_BandwidthStatsLogger.cpp index 41e24015..568cd10d 100644 --- a/modules/juce_blocks_basics/topology/internal/juce_BandwidthStatsLogger.cpp +++ b/modules/juce_blocks_basics/topology/internal/juce_BandwidthStatsLogger.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -67,7 +67,7 @@ namespace static PortIOStats inputStats { "Input" }, outputStats { "Output" }; static uint32 startTime = 0; - static inline void resetOnSecondBoundary() + static void resetOnSecondBoundary() { auto now = Time::getMillisecondCounter(); double elapsedSec = (now - startTime) / 1000.0; @@ -80,13 +80,13 @@ namespace } } - static inline void registerBytesOut (int numBytes) + static void registerBytesOut (int numBytes) { outputStats.registerMessage (numBytes); resetOnSecondBoundary(); } - static inline void registerBytesIn (int numBytes) + static void registerBytesIn (int numBytes) { inputStats.registerMessage (numBytes); resetOnSecondBoundary(); diff --git a/modules/juce_blocks_basics/topology/internal/juce_BlockImplementation.cpp b/modules/juce_blocks_basics/topology/internal/juce_BlockImplementation.cpp index 45dc0c07..05c3ca81 100644 --- a/modules/juce_blocks_basics/topology/internal/juce_BlockImplementation.cpp +++ b/modules/juce_blocks_basics/topology/internal/juce_BlockImplementation.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -30,7 +30,7 @@ struct BlockImplementation : public Block, { public: struct ControlButtonImplementation; - struct TouchSurfaceImsplementation; + struct TouchSurfaceImplementation; struct LEDGridImplementation; struct LEDRowImplementation; @@ -220,7 +220,10 @@ public: bool sendMessageToDevice (const PacketBuilder& builder) { if (detector != nullptr) + { + lastMessageSendTime = Time::getCurrentTime(); return detector->sendMessageToDevice (uid, builder); + } return false; } @@ -231,6 +234,11 @@ public: { return p.deviceControlMessage (commandID); }); } + void handleProgramEvent (const ProgramEventMessage& message) + { + programEventListeners.call ([&] (ProgramEventListener& l) { l.handleProgramEvent(*this, message); }); + } + void handleCustomMessage (Block::Timestamp, const int32* data) { ProgramEventMessage m; @@ -238,7 +246,7 @@ public: for (uint32 i = 0; i < BlocksProtocol::numProgramMessageInts; ++i) m.values[i] = data[i]; - programEventListeners.call ([&] (ProgramEventListener& l) { l.handleProgramEvent (*this, m); }); + handleProgramEvent (m); } static BlockImplementation* getFrom (Block* b) noexcept @@ -253,9 +261,9 @@ public: } //============================================================================== - std::function<void(const Block& block, const String&)> logger; + std::function<void (const Block& block, const String&)> logger; - void setLogger (std::function<void(const Block& block, const String&)> newLogger) override + void setLogger (std::function<void (const Block& block, const String&)> newLogger) override { logger = std::move (newLogger); } @@ -267,25 +275,37 @@ public: } //============================================================================== - Result setProgram (Program* newProgram) override + Result setProgram (std::unique_ptr<Program> newProgram, + ProgramPersistency persistency = ProgramPersistency::setAsTemp) override { - if (newProgram != nullptr && program.get() == newProgram) + auto doProgramsMatch = [&] { - jassertfalse; - return Result::ok(); - } + if (program == nullptr || newProgram == nullptr) + return false; - { - std::unique_ptr<Program> p (newProgram); + return program->getLittleFootProgram() == newProgram->getLittleFootProgram() + && program->getSearchPaths() == newProgram->getSearchPaths(); + }(); - if (program != nullptr - && newProgram != nullptr - && program->getLittleFootProgram() == newProgram->getLittleFootProgram()) - return Result::ok(); + if (doProgramsMatch) + { + if (isProgramLoaded) + { + MessageManager::callAsync ([blockRef = Block::Ptr (this), this] + { + programLoadedListeners.call ([&] (ProgramLoadedListener& l) { l.handleProgramLoaded (*this); }); + }); + } - std::swap (program, p); + return Result::ok(); } + program = std::move (newProgram); + return loadProgram (persistency); + } + + Result loadProgram (ProgramPersistency persistency) + { stopTimer(); programSize = 0; @@ -297,41 +317,50 @@ public: return Result::ok(); } - littlefoot::Compiler compiler; - compiler.addNativeFunctions (PhysicalTopologySource::getStandardLittleFootFunctions()); - - const auto err = compiler.compile (program->getLittleFootProgram(), 512, program->getSearchPaths()); + auto res = compileProgram(); - if (err.failed()) - return err; + if (res.failed()) + return res; - DBG ("Compiled littlefoot program, space needed: " - << (int) compiler.getCompiledProgram().getTotalSpaceNeeded() << " bytes"); - - if (compiler.getCompiledProgram().getTotalSpaceNeeded() > getMemorySize()) - return Result::fail ("Program too large!"); - - const auto size = (size_t) compiler.compiledObjectCode.size(); - programSize = (uint32) size; + programSize = (uint32) compiler.compiledObjectCode.size(); remoteHeap.resetDataRangeToUnknown (0, remoteHeap.blockSize); remoteHeap.clearTargetData(); remoteHeap.sendChanges (*this, true); - remoteHeap.resetDataRangeToUnknown (0, (uint32) size); - remoteHeap.setBytes (0, compiler.compiledObjectCode.begin(), size); + remoteHeap.resetDataRangeToUnknown (0, programSize); + remoteHeap.setBytes (0, compiler.compiledObjectCode.begin(), programSize); remoteHeap.sendChanges (*this, true); this->resetConfigListActiveStatus(); - if (auto changeCallback = this->configChangedCallback) - changeCallback (*this, {}, this->getMaxConfigIndex()); + const auto legacyProgramChangeConfigIndex = getMaxConfigIndex(); + handleConfigItemChanged ({ legacyProgramChangeConfigIndex }, legacyProgramChangeConfigIndex); + shouldSaveProgramAsDefault = persistency == ProgramPersistency::setAsDefault; startTimer (20); return Result::ok(); } + Result compileProgram() + { + compiler.addNativeFunctions (PhysicalTopologySource::getStandardLittleFootFunctions()); + + const auto err = compiler.compile (program->getLittleFootProgram(), 512, program->getSearchPaths()); + + if (err.failed()) + return err; + + DBG ("Compiled littlefoot program, space needed: " + << (int) compiler.getCompiledProgram().getTotalSpaceNeeded() << " bytes"); + + if (compiler.getCompiledProgram().getTotalSpaceNeeded() > getMemorySize()) + return Result::fail ("Program too large!"); + + return Result::ok(); + } + Program* getProgram() const override { return program.get(); } void sendProgramEvent (const ProgramEventMessage& message) override @@ -356,8 +385,7 @@ public: if (shouldSaveProgramAsDefault) doSaveProgramAsDefault(); - if (programLoadedCallback != nullptr) - programLoadedCallback (*this); + programLoadedListeners.call([&] (ProgramLoadedListener& l) { l.handleProgramLoaded (*this); }); } else { @@ -419,7 +447,7 @@ public: remoteHeap.handleACKFromDevice (*this, packetCounter); } - bool sendFirmwareUpdatePacket (const uint8* data, uint8 size, std::function<void(uint8, uint32)> callback) override + bool sendFirmwareUpdatePacket (const uint8* data, uint8 size, std::function<void (uint8, uint32)> callback) override { firmwarePacketAckCallback = nullptr; @@ -447,14 +475,14 @@ public: config.handleConfigUpdateMessage (item, value, min, max); } - void handleConfigSetMessage(int32 item, int32 value) + void handleConfigSetMessage (int32 item, int32 value) { config.handleConfigSetMessage (item, value); } void pingFromDevice() { - lastPingReceiveTime = Time::getCurrentTime(); + lastMessageReceiveTime = Time::getCurrentTime(); } MIDIDeviceConnection* getDeviceConnection() @@ -508,11 +536,8 @@ public: remoteHeap.sendChanges (*this, false); - if (lastPingSendTime < Time::getCurrentTime() - getPingInterval()) - { - lastPingSendTime = Time::getCurrentTime(); + if (lastMessageSendTime < Time::getCurrentTime() - getPingInterval()) sendCommandMessage (BlocksProtocol::ping); - } } RelativeTime getPingInterval() @@ -521,6 +546,16 @@ public: } //============================================================================== + void handleConfigItemChanged (const ConfigMetaData& data, uint32 index) + { + configItemListeners.call([&] (ConfigItemListener& l) { l.handleConfigItemChanged (*this, data, index); }); + } + + void handleConfigSyncEnded() + { + configItemListeners.call([&] (ConfigItemListener& l) { l.handleConfigSyncEnded (*this); }); + } + int32 getLocalConfigValue (uint32 item) override { initialiseDeviceIndexAndConnection(); @@ -580,16 +615,6 @@ public: config.resetConfigListActiveStatus(); } - void setConfigChangedCallback (std::function<void(Block&, const ConfigMetaData&, uint32)> configChanged) override - { - configChangedCallback = std::move (configChanged); - } - - void setProgramLoadedCallback (std::function<void(Block&)> programLoaded) override - { - programLoadedCallback = std::move (programLoaded); - } - bool setName (const String& newName) override { return buildAndSendPacket<128> ([&newName] (BlocksProtocol::HostPacketBuilder<128>& p) @@ -600,6 +625,12 @@ public: { buildAndSendPacket<32> ([] (BlocksProtocol::HostPacketBuilder<32>& p) { return p.addFactoryReset(); }); + + juce::Timer::callAfterDelay (5, [ref = WeakReference<BlockImplementation>(this)] + { + if (ref != nullptr) + ref->blockReset(); + }); } void blockReset() override @@ -654,18 +685,16 @@ public: RemoteHeapType remoteHeap; WeakReference<Detector> detector; - Time lastPingSendTime, lastPingReceiveTime; + Time lastMessageSendTime, lastMessageReceiveTime; BlockConfigManager config; - std::function<void(Block&, const ConfigMetaData&, uint32)> configChangedCallback; - - std::function<void(Block&)> programLoadedCallback; private: + littlefoot::Compiler compiler; std::unique_ptr<Program> program; uint32 programSize = 0; - std::function<void(uint8, uint32)> firmwarePacketAckCallback; + std::function<void (uint8, uint32)> firmwarePacketAckCallback; bool isMaster = false; Block::UID masterUID = {}; @@ -1035,7 +1064,7 @@ public: { if (block.getProgram() == nullptr) { - auto err = block.setProgram (new DefaultLEDGridProgram (block)); + auto err = block.setProgram (std::make_unique <DefaultLEDGridProgram> (block)); if (err.failed()) { @@ -1116,6 +1145,7 @@ public: private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BlockImplementation) + JUCE_DECLARE_WEAK_REFERENCEABLE (BlockImplementation) }; } // namespace juce diff --git a/modules/juce_blocks_basics/topology/internal/juce_BlockSerialReader.cpp b/modules/juce_blocks_basics/topology/internal/juce_BlockSerialReader.cpp index c4a94e92..8e41f759 100644 --- a/modules/juce_blocks_basics/topology/internal/juce_BlockSerialReader.cpp +++ b/modules/juce_blocks_basics/topology/internal/juce_BlockSerialReader.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2019 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_blocks_basics/topology/internal/juce_ConnectedDeviceGroup.cpp b/modules/juce_blocks_basics/topology/internal/juce_ConnectedDeviceGroup.cpp index 5d4c8615..d8419d04 100644 --- a/modules/juce_blocks_basics/topology/internal/juce_ConnectedDeviceGroup.cpp +++ b/modules/juce_blocks_basics/topology/internal/juce_ConnectedDeviceGroup.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -167,9 +167,9 @@ struct ConnectedDeviceGroup : private AsyncUpdater, TouchSurface::Touch touch; touch.index = (int) touchIndex.get(); - touch.x = position.x.toUnipolarFloat(); - touch.y = position.y.toUnipolarFloat(); - touch.z = position.z.toUnipolarFloat(); + touch.x = (float) position.x.toUnipolarFloat(); + touch.y = (float) position.y.toUnipolarFloat(); + touch.z = (float) position.z.toUnipolarFloat(); touch.xVelocity = velocity.vx.toBipolarFloat(); touch.yVelocity = velocity.vy.toBipolarFloat(); touch.zVelocity = velocity.vz.toBipolarFloat(); diff --git a/modules/juce_blocks_basics/topology/internal/juce_DepreciatedVersionReader.cpp b/modules/juce_blocks_basics/topology/internal/juce_DepreciatedVersionReader.cpp index f237ee19..31cdbf25 100644 --- a/modules/juce_blocks_basics/topology/internal/juce_DepreciatedVersionReader.cpp +++ b/modules/juce_blocks_basics/topology/internal/juce_DepreciatedVersionReader.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_blocks_basics/topology/internal/juce_Detector.cpp b/modules/juce_blocks_basics/topology/internal/juce_Detector.cpp index 9a0df53d..00129e80 100644 --- a/modules/juce_blocks_basics/topology/internal/juce_Detector.cpp +++ b/modules/juce_blocks_basics/topology/internal/juce_Detector.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -290,13 +290,10 @@ struct Detector : public ReferenceCountedObject, void notifyBlockOfConfigChange (BlockImpl& bi, uint32 item) { - if (auto configChangedCallback = bi.configChangedCallback) - { - if (item >= bi.getMaxConfigIndex()) - configChangedCallback (bi, {}, item); - else - configChangedCallback (bi, bi.getLocalConfigMetaData (item), item); - } + if (item >= bi.getMaxConfigIndex()) + bi.handleConfigItemChanged ({ item }, item); + else + bi.handleConfigItemChanged (bi.getLocalConfigMetaData (item), item); } void handleConfigSetMessage (Block::UID deviceID, int32 item, int32 value) @@ -311,7 +308,7 @@ struct Detector : public ReferenceCountedObject, void handleConfigFactorySyncEndMessage (Block::UID deviceID) { if (auto* bi = getBlockImplementationWithUID (deviceID)) - notifyBlockOfConfigChange (*bi, bi->getMaxConfigIndex()); + bi->handleConfigSyncEnded(); } void handleConfigFactorySyncResetMessage (Block::UID deviceID) @@ -353,10 +350,10 @@ struct Detector : public ReferenceCountedObject, { TouchSurface::Touch scaledEvent (touchEvent); - scaledEvent.x *= block->getWidth(); - scaledEvent.y *= block->getHeight(); - scaledEvent.startX *= block->getWidth(); - scaledEvent.startY *= block->getHeight(); + scaledEvent.x *= (float) block->getWidth(); + scaledEvent.y *= (float) block->getHeight(); + scaledEvent.startX *= (float) block->getWidth(); + scaledEvent.startY *= (float) block->getHeight(); surface->broadcastTouchChange (scaledEvent); } @@ -574,6 +571,7 @@ private: case Block::ConnectionPort::DeviceEdge::east: return 1; case Block::ConnectionPort::DeviceEdge::south: return 2; case Block::ConnectionPort::DeviceEdge::west: return 3; + default: break; } jassertfalse; @@ -632,6 +630,8 @@ private: case 3: // left of me delta = { -theirBounds.width, (myBounds.height - (myOffset + 1)) - theirOffset }; break; + default: + break; } { @@ -674,6 +674,7 @@ private: case Block::ConnectionPort::DeviceEdge::south: return "south"; case Block::ConnectionPort::DeviceEdge::east: return "east"; case Block::ConnectionPort::DeviceEdge::west: return "west"; + default: break; } return {}; diff --git a/modules/juce_blocks_basics/topology/internal/juce_DetectorHolder.cpp b/modules/juce_blocks_basics/topology/internal/juce_DetectorHolder.cpp index eab5583f..74127af6 100644 --- a/modules/juce_blocks_basics/topology/internal/juce_DetectorHolder.cpp +++ b/modules/juce_blocks_basics/topology/internal/juce_DetectorHolder.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_blocks_basics/topology/internal/juce_DeviceInfo.cpp b/modules/juce_blocks_basics/topology/internal/juce_DeviceInfo.cpp index e161b385..e068e43e 100644 --- a/modules/juce_blocks_basics/topology/internal/juce_DeviceInfo.cpp +++ b/modules/juce_blocks_basics/topology/internal/juce_DeviceInfo.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_blocks_basics/topology/internal/juce_MIDIDeviceDetector.cpp b/modules/juce_blocks_basics/topology/internal/juce_MIDIDeviceDetector.cpp index 725afb54..161a1245 100644 --- a/modules/juce_blocks_basics/topology/internal/juce_MIDIDeviceDetector.cpp +++ b/modules/juce_blocks_basics/topology/internal/juce_MIDIDeviceDetector.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_blocks_basics/topology/internal/juce_MidiDeviceConnection.cpp b/modules/juce_blocks_basics/topology/internal/juce_MidiDeviceConnection.cpp index 6861db66..34a6f1cb 100644 --- a/modules/juce_blocks_basics/topology/internal/juce_MidiDeviceConnection.cpp +++ b/modules/juce_blocks_basics/topology/internal/juce_MidiDeviceConnection.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_blocks_basics/topology/juce_BlockGraph.cpp b/modules/juce_blocks_basics/topology/juce_BlockGraph.cpp index 6293279a..f0da64db 100644 --- a/modules/juce_blocks_basics/topology/juce_BlockGraph.cpp +++ b/modules/juce_blocks_basics/topology/juce_BlockGraph.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2019 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -23,7 +23,7 @@ namespace juce { -BlockGraph::BlockGraph (const BlockTopology t, std::function<bool(Block::Ptr)> filterIn) +BlockGraph::BlockGraph (const BlockTopology t, std::function<bool (Block::Ptr)> filterIn) : topology (t), filter (std::move (filterIn)) { buildGraph(); diff --git a/modules/juce_blocks_basics/topology/juce_BlockGraph.h b/modules/juce_blocks_basics/topology/juce_BlockGraph.h index 989ec4e2..8bea4636 100644 --- a/modules/juce_blocks_basics/topology/juce_BlockGraph.h +++ b/modules/juce_blocks_basics/topology/juce_BlockGraph.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2019 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -36,7 +36,7 @@ public: /** Creates a BlockGraph object from a BlockTopology with an optional filter function. This will build a block graph of traversal paths for each master. */ - BlockGraph (const BlockTopology topology, std::function<bool(Block::Ptr block)> filter = nullptr); + BlockGraph (const BlockTopology topology, std::function<bool (Block::Ptr block)> filter = nullptr); BlockGraph (BlockGraph&&); using BlockTraversalPaths = Array<Block::Array, CriticalSection>; @@ -58,7 +58,7 @@ private: BlockTraversalPaths traversalPaths; // one path for each master block BlockTopology topology; - std::function<bool(Block::Ptr)> filter; + std::function<bool (Block::Ptr)> filter; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BlockGraph) }; diff --git a/modules/juce_blocks_basics/topology/juce_PhysicalTopologySource.cpp b/modules/juce_blocks_basics/topology/juce_PhysicalTopologySource.cpp index e08d54b8..8ee604d7 100644 --- a/modules/juce_blocks_basics/topology/juce_PhysicalTopologySource.cpp +++ b/modules/juce_blocks_basics/topology/juce_PhysicalTopologySource.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -113,7 +113,7 @@ void PhysicalTopologySource::setActive (bool shouldBeActive) detector.reset(); } - listeners.call ([](TopologySource::Listener& l){ l.topologyChanged(); }); + listeners.call ([] (TopologySource::Listener& l){ l.topologyChanged(); }); } bool PhysicalTopologySource::isActive() const diff --git a/modules/juce_blocks_basics/topology/juce_PhysicalTopologySource.h b/modules/juce_blocks_basics/topology/juce_PhysicalTopologySource.h index fa1be412..45889900 100644 --- a/modules/juce_blocks_basics/topology/juce_PhysicalTopologySource.h +++ b/modules/juce_blocks_basics/topology/juce_PhysicalTopologySource.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -52,7 +52,7 @@ public: bool isActive() const override; /** This method will tell, if an other PhysicalTopologySource has locked the Midi connection */ - bool isLockedFromOutside() const; + bool isLockedFromOutside() const override; //============================================================================== /** For custom transport systems, this represents a connected device */ @@ -62,7 +62,7 @@ public: virtual ~DeviceConnection(); virtual bool sendMessageToDevice (const void* data, size_t dataSize) = 0; - std::function<void(const void* data, size_t dataSize)> handleMessageFromDevice; + std::function<void (const void* data, size_t dataSize)> handleMessageFromDevice; }; /** For custom transport systems, this represents a connected device */ diff --git a/modules/juce_blocks_basics/topology/juce_RuleBasedTopologySource.cpp b/modules/juce_blocks_basics/topology/juce_RuleBasedTopologySource.cpp index c573c950..fad483f0 100644 --- a/modules/juce_blocks_basics/topology/juce_RuleBasedTopologySource.cpp +++ b/modules/juce_blocks_basics/topology/juce_RuleBasedTopologySource.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_blocks_basics/topology/juce_RuleBasedTopologySource.h b/modules/juce_blocks_basics/topology/juce_RuleBasedTopologySource.h index 1e6baffb..f580af1c 100644 --- a/modules/juce_blocks_basics/topology/juce_RuleBasedTopologySource.h +++ b/modules/juce_blocks_basics/topology/juce_RuleBasedTopologySource.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -79,6 +79,8 @@ public: /** Returns true, if the TopologySource is currently trying to connect the block devices */ bool isActive() const override; + bool isLockedFromOutside() const override { return false; } + private: //============================================================================== struct Internal; diff --git a/modules/juce_blocks_basics/topology/juce_Topology.h b/modules/juce_blocks_basics/topology/juce_Topology.h index 46c122ac..b287a884 100644 --- a/modules/juce_blocks_basics/topology/juce_Topology.h +++ b/modules/juce_blocks_basics/topology/juce_Topology.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_blocks_basics/topology/juce_TopologySource.h b/modules/juce_blocks_basics/topology/juce_TopologySource.h index d7360ba5..2333687e 100644 --- a/modules/juce_blocks_basics/topology/juce_TopologySource.h +++ b/modules/juce_blocks_basics/topology/juce_TopologySource.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -43,6 +43,9 @@ public: /** Returns true, if the TopologySource is currently trying to connect the block devices */ virtual bool isActive() const = 0; + /** Returns true if the topology is locked externally.*/ + virtual bool isLockedFromOutside() const = 0; + //============================================================================== /** Used to receive callbacks for topology changes */ struct Listener @@ -70,6 +73,12 @@ public: /** Invoke this to force touches-off on all physical devices. */ virtual void cancelAllActiveTouches() noexcept {} + /** Gets blocks from the current topology. */ + Block::Array getBlocks() const { return getCurrentTopology().blocks; } + + /**Gets a block with given uid from the current topology*/ + Block::Ptr getBlockWithUID (Block::UID uid) const { return getCurrentTopology().getBlockWithUID (uid); } + protected: //============================================================================== ListenerList<Listener> listeners; diff --git a/modules/juce_blocks_basics/visualisers/juce_BitmapLEDProgram.cpp b/modules/juce_blocks_basics/visualisers/juce_BitmapLEDProgram.cpp index f7d72257..1219e821 100644 --- a/modules/juce_blocks_basics/visualisers/juce_BitmapLEDProgram.cpp +++ b/modules/juce_blocks_basics/visualisers/juce_BitmapLEDProgram.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_blocks_basics/visualisers/juce_BitmapLEDProgram.h b/modules/juce_blocks_basics/visualisers/juce_BitmapLEDProgram.h index c2aa4d18..96f8c238 100644 --- a/modules/juce_blocks_basics/visualisers/juce_BitmapLEDProgram.h +++ b/modules/juce_blocks_basics/visualisers/juce_BitmapLEDProgram.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_blocks_basics/visualisers/juce_DrumPadLEDProgram.cpp b/modules/juce_blocks_basics/visualisers/juce_DrumPadLEDProgram.cpp index fbc126c4..444d7734 100644 --- a/modules/juce_blocks_basics/visualisers/juce_DrumPadLEDProgram.cpp +++ b/modules/juce_blocks_basics/visualisers/juce_DrumPadLEDProgram.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -27,14 +27,14 @@ DrumPadGridProgram::DrumPadGridProgram (Block& b) : Program (b) {} int DrumPadGridProgram::getPadIndex (float posX, float posY) const { - posX = jmin (0.99f, posX / block.getWidth()); - posY = jmin (0.99f, posY / block.getHeight()); + posX = jmin (0.99f, posX / (float) block.getWidth()); + posY = jmin (0.99f, posY / (float) block.getHeight()); const uint32 offset = block.getDataByte (visiblePads_byte) ? numColumns1_byte : numColumns0_byte; const int numColumns = block.getDataByte (offset + numColumns0_byte); const int numRows = block.getDataByte (offset + numRows0_byte); - return int (posX * numColumns) + int (posY * numRows) * numColumns; + return int (posX * (float) numColumns) + int (posY * (float) numRows) * numColumns; } void DrumPadGridProgram::startTouch (float startX, float startY) @@ -65,8 +65,8 @@ void DrumPadGridProgram::sendTouch (float x, float y, float z, LEDColour colour) Block::ProgramEventMessage e; e.values[0] = 0x20000000 - + (jlimit (0, 255, roundToInt (x * (255.0f / block.getWidth()))) << 16) - + (jlimit (0, 255, roundToInt (y * (255.0f / block.getHeight()))) << 8) + + (jlimit (0, 255, roundToInt (x * (255.0f / (float) block.getWidth()))) << 16) + + (jlimit (0, 255, roundToInt (y * (255.0f / (float) block.getHeight()))) << 8) + jlimit (0, 255, roundToInt (z * 255.0f)); e.values[1] = (int32) colour.getARGB(); diff --git a/modules/juce_blocks_basics/visualisers/juce_DrumPadLEDProgram.h b/modules/juce_blocks_basics/visualisers/juce_DrumPadLEDProgram.h index 481b6213..7db7ab1b 100644 --- a/modules/juce_blocks_basics/visualisers/juce_DrumPadLEDProgram.h +++ b/modules/juce_blocks_basics/visualisers/juce_DrumPadLEDProgram.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_box2d/box2d/Collision/b2DynamicTree.cpp b/modules/juce_box2d/box2d/Collision/b2DynamicTree.cpp index 7389fc0b..3287cf7c 100644 --- a/modules/juce_box2d/box2d/Collision/b2DynamicTree.cpp +++ b/modules/juce_box2d/box2d/Collision/b2DynamicTree.cpp @@ -642,6 +642,7 @@ void b2DynamicTree::ValidateMetrics(int32 index) const int32 height; height = 1 + b2Max(height1, height2); b2Assert(node->height == height); + juce::ignoreUnused (height); b2AABB aabb; aabb.Combine(m_nodes[child1].aabb, m_nodes[child2].aabb); diff --git a/modules/juce_box2d/box2d/Dynamics/b2Body.cpp b/modules/juce_box2d/box2d/Dynamics/b2Body.cpp index ce3f2ded..e0f18b20 100644 --- a/modules/juce_box2d/box2d/Dynamics/b2Body.cpp +++ b/modules/juce_box2d/box2d/Dynamics/b2Body.cpp @@ -224,6 +224,7 @@ void b2Body::DestroyFixture(b2Fixture* fixture) // You tried to remove a shape that is not attached to this body. b2Assert(found); + juce::ignoreUnused (found); // Destroy any contacts associated with the fixture. b2ContactEdge* edge = m_contactList; diff --git a/modules/juce_box2d/juce_box2d.cpp b/modules/juce_box2d/juce_box2d.cpp index 5673b384..334a5e39 100644 --- a/modules/juce_box2d/juce_box2d.cpp +++ b/modules/juce_box2d/juce_box2d.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -35,20 +34,14 @@ #include "juce_box2d.h" -#if defined JUCE_CLANG - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wsign-conversion" - #pragma clang diagnostic ignored "-Wfloat-conversion" - #pragma clang diagnostic ignored "-Wcast-align" - #if __has_warning("-Wzero-as-null-pointer-constant") - #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" - #endif -#elif defined JUCE_GCC - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wsign-conversion" - #pragma GCC diagnostic ignored "-Wunused-but-set-variable" - #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" -#endif +JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wconversion", + "-Wsign-conversion", + "-Wfloat-conversion", + "-Wcast-align", + "-Wswitch-enum", + "-Wswitch-default", + "-Wunused-but-set-variable", + "-Wzero-as-null-pointer-constant") #include <cstdarg> @@ -107,8 +100,4 @@ using uint32 = juce::uint32; #include "utils/juce_Box2DRenderer.cpp" -#if defined JUCE_CLANG - #pragma clang diagnostic pop -#elif defined JUCE_GCC - #pragma GCC diagnostic pop -#endif +JUCE_END_IGNORE_WARNINGS_GCC_LIKE diff --git a/modules/juce_box2d/juce_box2d.h b/modules/juce_box2d/juce_box2d.h index 05c21533..5db1fb9d 100644 --- a/modules/juce_box2d/juce_box2d.h +++ b/modules/juce_box2d/juce_box2d.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -29,14 +28,14 @@ The block below describes the properties of this module, and is read by the Projucer to automatically generate project code that uses it. For details about the syntax and how to create or use a module, see the - JUCE Module Format.txt file. + JUCE Module Format.md file. BEGIN_JUCE_MODULE_DECLARATION ID: juce_box2d vendor: juce - version: 5.4.7 + version: 6.0.5 name: JUCE wrapper for the Box2D physics engine description: The Box2D physics engine and some utility classes. website: http://www.juce.com/juce @@ -55,35 +54,17 @@ //============================================================================== #include <juce_graphics/juce_graphics.h> -#ifdef JUCE_CLANG - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wconversion" - #if __has_warning("-Wshadow-field") - #pragma clang diagnostic ignored "-Wshadow-field" - #endif - #if __has_warning("-Wzero-as-null-pointer-constant") - #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" - #endif -#endif - -#ifdef JUCE_GCC - #pragma GCC diagnostic ignored "-Wconversion" - #pragma GCC diagnostic ignored "-Wsign-conversion" - #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" -#endif +JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wconversion", + "-Wshadow-field", + "-Wzero-as-null-pointer-constant", + "-Wsign-conversion") #include <climits> #include <cfloat> #include "box2d/Box2D.h" -#ifdef JUCE_CLANG - #pragma clang diagnostic pop -#endif - -#ifdef JUCE_GCC - #pragma GCC diagnostic pop -#endif +JUCE_END_IGNORE_WARNINGS_GCC_LIKE #ifndef DOXYGEN // for some reason, Doxygen sees this as a re-definition of Box2DRenderer #include "utils/juce_Box2DRenderer.h" diff --git a/modules/juce_box2d/utils/juce_Box2DRenderer.cpp b/modules/juce_box2d/utils/juce_Box2DRenderer.cpp index 0988f0f0..3724f87d 100644 --- a/modules/juce_box2d/utils/juce_Box2DRenderer.cpp +++ b/modules/juce_box2d/utils/juce_Box2DRenderer.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_box2d/utils/juce_Box2DRenderer.h b/modules/juce_box2d/utils/juce_Box2DRenderer.h index e7ec4944..6c5731ae 100644 --- a/modules/juce_box2d/utils/juce_Box2DRenderer.h +++ b/modules/juce_box2d/utils/juce_Box2DRenderer.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_core/containers/juce_AbstractFifo.cpp b/modules/juce_core/containers/juce_AbstractFifo.cpp index 7917a220..320c867c 100644 --- a/modules/juce_core/containers/juce_AbstractFifo.cpp +++ b/modules/juce_core/containers/juce_AbstractFifo.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/containers/juce_AbstractFifo.h b/modules/juce_core/containers/juce_AbstractFifo.h index 2c46c4c7..392c7ac5 100644 --- a/modules/juce_core/containers/juce_AbstractFifo.h +++ b/modules/juce_core/containers/juce_AbstractFifo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/containers/juce_Array.h b/modules/juce_core/containers/juce_Array.h index a2a37186..85f833b1 100644 --- a/modules/juce_core/containers/juce_Array.h +++ b/modules/juce_core/containers/juce_Array.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/containers/juce_ArrayAllocationBase.h b/modules/juce_core/containers/juce_ArrayAllocationBase.h index b967c41c..7bba949c 100644 --- a/modules/juce_core/containers/juce_ArrayAllocationBase.h +++ b/modules/juce_core/containers/juce_ArrayAllocationBase.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/containers/juce_ArrayBase.cpp b/modules/juce_core/containers/juce_ArrayBase.cpp index 7a79da62..0ddd9b48 100644 --- a/modules/juce_core/containers/juce_ArrayBase.cpp +++ b/modules/juce_core/containers/juce_ArrayBase.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2018 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -87,14 +87,14 @@ namespace ArrayBaseTestsHelpers }; } -bool operator== (const ArrayBaseTestsHelpers::TriviallyCopyableType& tct, - const ArrayBaseTestsHelpers::NonTriviallyCopyableType& ntct) +static bool operator== (const ArrayBaseTestsHelpers::TriviallyCopyableType& tct, + const ArrayBaseTestsHelpers::NonTriviallyCopyableType& ntct) { return tct.getValue() == ntct.getValue(); } -bool operator== (const ArrayBaseTestsHelpers::NonTriviallyCopyableType& ntct, - const ArrayBaseTestsHelpers::TriviallyCopyableType& tct) +static bool operator== (const ArrayBaseTestsHelpers::NonTriviallyCopyableType& ntct, + const ArrayBaseTestsHelpers::TriviallyCopyableType& tct) { return tct == ntct; } diff --git a/modules/juce_core/containers/juce_ArrayBase.h b/modules/juce_core/containers/juce_ArrayBase.h index b4e7f38f..7d5c4d0b 100644 --- a/modules/juce_core/containers/juce_ArrayBase.h +++ b/modules/juce_core/containers/juce_ArrayBase.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/containers/juce_DynamicObject.cpp b/modules/juce_core/containers/juce_DynamicObject.cpp index 4d299ac0..e8d1289d 100644 --- a/modules/juce_core/containers/juce_DynamicObject.cpp +++ b/modules/juce_core/containers/juce_DynamicObject.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/containers/juce_DynamicObject.h b/modules/juce_core/containers/juce_DynamicObject.h index aed21086..d436906d 100644 --- a/modules/juce_core/containers/juce_DynamicObject.h +++ b/modules/juce_core/containers/juce_DynamicObject.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/containers/juce_ElementComparator.h b/modules/juce_core/containers/juce_ElementComparator.h index e8189920..3346730f 100644 --- a/modules/juce_core/containers/juce_ElementComparator.h +++ b/modules/juce_core/containers/juce_ElementComparator.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/containers/juce_HashMap.h b/modules/juce_core/containers/juce_HashMap.h index a5ab9ea7..72a55555 100644 --- a/modules/juce_core/containers/juce_HashMap.h +++ b/modules/juce_core/containers/juce_HashMap.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -489,7 +489,7 @@ private: return hash; } - static inline HashEntry* getEntry (HashEntry* firstEntry, KeyType keyToLookFor) noexcept + static HashEntry* getEntry (HashEntry* firstEntry, KeyType keyToLookFor) noexcept { for (auto* entry = firstEntry; entry != nullptr; entry = entry->nextEntry) if (entry->key == keyToLookFor) diff --git a/modules/juce_core/containers/juce_HashMap_test.cpp b/modules/juce_core/containers/juce_HashMap_test.cpp index fe581754..011a0b21 100644 --- a/modules/juce_core/containers/juce_HashMap_test.cpp +++ b/modules/juce_core/containers/juce_HashMap_test.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/containers/juce_LinkedListPointer.h b/modules/juce_core/containers/juce_LinkedListPointer.h index afa80b2a..1c2491aa 100644 --- a/modules/juce_core/containers/juce_LinkedListPointer.h +++ b/modules/juce_core/containers/juce_LinkedListPointer.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/containers/juce_ListenerList.h b/modules/juce_core/containers/juce_ListenerList.h index 93d73efa..bcfce075 100644 --- a/modules/juce_core/containers/juce_ListenerList.h +++ b/modules/juce_core/containers/juce_ListenerList.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/containers/juce_NamedValueSet.cpp b/modules/juce_core/containers/juce_NamedValueSet.cpp index b6b98286..78c84ae4 100644 --- a/modules/juce_core/containers/juce_NamedValueSet.cpp +++ b/modules/juce_core/containers/juce_NamedValueSet.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/containers/juce_NamedValueSet.h b/modules/juce_core/containers/juce_NamedValueSet.h index 9e8f153c..6fb6efae 100644 --- a/modules/juce_core/containers/juce_NamedValueSet.h +++ b/modules/juce_core/containers/juce_NamedValueSet.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/containers/juce_OwnedArray.cpp b/modules/juce_core/containers/juce_OwnedArray.cpp index 480c5eca..eb64a16d 100644 --- a/modules/juce_core/containers/juce_OwnedArray.cpp +++ b/modules/juce_core/containers/juce_OwnedArray.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/containers/juce_OwnedArray.h b/modules/juce_core/containers/juce_OwnedArray.h index f3e92668..166a7370 100644 --- a/modules/juce_core/containers/juce_OwnedArray.h +++ b/modules/juce_core/containers/juce_OwnedArray.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/containers/juce_PropertySet.cpp b/modules/juce_core/containers/juce_PropertySet.cpp index fe371272..49128257 100644 --- a/modules/juce_core/containers/juce_PropertySet.cpp +++ b/modules/juce_core/containers/juce_PropertySet.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -115,7 +115,7 @@ std::unique_ptr<XmlElement> PropertySet::getXmlValue (StringRef keyName) const return parseXML (getValue (keyName)); } -void PropertySet::setValue (const String& keyName, const var& v) +void PropertySet::setValue (StringRef keyName, const var& v) { jassert (keyName.isNotEmpty()); // shouldn't use an empty key name! @@ -148,7 +148,7 @@ void PropertySet::removeValue (StringRef keyName) } } -void PropertySet::setValue (const String& keyName, const XmlElement* xml) +void PropertySet::setValue (StringRef keyName, const XmlElement* xml) { setValue (keyName, xml == nullptr ? var() : var (xml->toString (XmlElement::TextFormat().singleLine().withoutHeader()))); diff --git a/modules/juce_core/containers/juce_PropertySet.h b/modules/juce_core/containers/juce_PropertySet.h index b14cabf5..9fd9d222 100644 --- a/modules/juce_core/containers/juce_PropertySet.h +++ b/modules/juce_core/containers/juce_PropertySet.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -104,8 +104,8 @@ public: /** Returns one of the properties as an XML element. - The result will a new XMLElement object that the caller must delete. If may return nullptr - if the key isn't found, or if the entry contains an string that isn't valid XML. + The result will a new XMLElement object. It may return nullptr if the key isn't found, + or if the entry contains an string that isn't valid XML. If the value isn't found in this set, then this will look for it in a fallback property set (if you've specified one with the setFallbackPropertySet() method), @@ -121,7 +121,7 @@ public: @param keyName the name of the property to set. (This mustn't be an empty string) @param value the new value to set it to */ - void setValue (const String& keyName, const var& value); + void setValue (StringRef keyName, const var& value); /** Sets a named property to an XML element. @@ -130,7 +130,7 @@ public: be set to an empty string @see getXmlValue */ - void setValue (const String& keyName, const XmlElement* xml); + void setValue (StringRef keyName, const XmlElement* xml); /** This copies all the values from a source PropertySet to this one. This won't remove any existing settings, it just adds any that it finds in the source set. diff --git a/modules/juce_core/containers/juce_ReferenceCountedArray.cpp b/modules/juce_core/containers/juce_ReferenceCountedArray.cpp index 75d6c8d8..8ef9c28f 100644 --- a/modules/juce_core/containers/juce_ReferenceCountedArray.cpp +++ b/modules/juce_core/containers/juce_ReferenceCountedArray.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2018 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/containers/juce_ReferenceCountedArray.h b/modules/juce_core/containers/juce_ReferenceCountedArray.h index 221c09e1..13fa55d3 100644 --- a/modules/juce_core/containers/juce_ReferenceCountedArray.h +++ b/modules/juce_core/containers/juce_ReferenceCountedArray.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/containers/juce_ScopedValueSetter.h b/modules/juce_core/containers/juce_ScopedValueSetter.h index 53f797dc..f1b0ae10 100644 --- a/modules/juce_core/containers/juce_ScopedValueSetter.h +++ b/modules/juce_core/containers/juce_ScopedValueSetter.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/containers/juce_SortedSet.h b/modules/juce_core/containers/juce_SortedSet.h index b3f7905f..6fe5c3c2 100644 --- a/modules/juce_core/containers/juce_SortedSet.h +++ b/modules/juce_core/containers/juce_SortedSet.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -23,10 +23,7 @@ namespace juce { -#if JUCE_MSVC - #pragma warning (push) - #pragma warning (disable: 4512) -#endif +JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4512) //============================================================================== /** @@ -380,7 +377,7 @@ public: @param valueToRemove the object to try to remove @see remove, removeRange */ - void removeValue (const ElementType valueToRemove) noexcept + void removeValue (const ElementType& valueToRemove) noexcept { const ScopedLockType lock (getLock()); data.remove (indexOf (valueToRemove)); @@ -487,8 +484,6 @@ private: Array<ElementType, TypeOfCriticalSectionToUse> data; }; -#if JUCE_MSVC - #pragma warning (pop) -#endif +JUCE_END_IGNORE_WARNINGS_MSVC } // namespace juce diff --git a/modules/juce_core/containers/juce_SparseSet.cpp b/modules/juce_core/containers/juce_SparseSet.cpp index cffb7b97..0e5a7ea6 100644 --- a/modules/juce_core/containers/juce_SparseSet.cpp +++ b/modules/juce_core/containers/juce_SparseSet.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2018 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/containers/juce_SparseSet.h b/modules/juce_core/containers/juce_SparseSet.h index 68cb51e5..4045af7f 100644 --- a/modules/juce_core/containers/juce_SparseSet.h +++ b/modules/juce_core/containers/juce_SparseSet.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/containers/juce_Variant.cpp b/modules/juce_core/containers/juce_Variant.cpp index cd308161..6e92b955 100644 --- a/modules/juce_core/containers/juce_Variant.cpp +++ b/modules/juce_core/containers/juce_Variant.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -257,8 +257,8 @@ public: } private: - static inline const String* getString (const ValueUnion& data) noexcept { return reinterpret_cast<const String*> (data.stringValue); } - static inline String* getString (ValueUnion& data) noexcept { return reinterpret_cast<String*> (data.stringValue); } + static const String* getString (const ValueUnion& data) noexcept { return unalignedPointerCast<const String*> (data.stringValue); } + static String* getString (ValueUnion& data) noexcept { return unalignedPointerCast<String*> (data.stringValue); } }; //============================================================================== diff --git a/modules/juce_core/containers/juce_Variant.h b/modules/juce_core/containers/juce_Variant.h index 2596576c..e58f3386 100644 --- a/modules/juce_core/containers/juce_Variant.h +++ b/modules/juce_core/containers/juce_Variant.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -54,7 +54,7 @@ public: int numArguments; }; - using NativeFunction = std::function<var(const NativeFunctionArgs&)>; + using NativeFunction = std::function<var (const NativeFunctionArgs&)>; //============================================================================== /** Creates a void variant. */ diff --git a/modules/juce_core/files/juce_DirectoryIterator.cpp b/modules/juce_core/files/juce_DirectoryIterator.cpp index 487301b7..37452e8c 100644 --- a/modules/juce_core/files/juce_DirectoryIterator.cpp +++ b/modules/juce_core/files/juce_DirectoryIterator.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -64,6 +64,9 @@ bool DirectoryIterator::next() return next (nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); } +JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wdeprecated-declarations") +JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4996) + bool DirectoryIterator::next (bool* isDirResult, bool* isHiddenResult, int64* fileSize, Time* modTime, Time* creationTime, bool* isReadOnly) { @@ -134,6 +137,9 @@ bool DirectoryIterator::next (bool* isDirResult, bool* isHiddenResult, int64* fi } } +JUCE_END_IGNORE_WARNINGS_GCC_LIKE +JUCE_END_IGNORE_WARNINGS_MSVC + const File& DirectoryIterator::getFile() const { if (subIterator != nullptr && subIterator->hasBeenAdvanced) @@ -153,10 +159,10 @@ float DirectoryIterator::getEstimatedProgress() const if (totalNumFiles <= 0) return 0.0f; - auto detailedIndex = (subIterator != nullptr) ? index + subIterator->getEstimatedProgress() + auto detailedIndex = (subIterator != nullptr) ? (float) index + subIterator->getEstimatedProgress() : (float) index; - return jlimit (0.0f, 1.0f, detailedIndex / totalNumFiles); + return jlimit (0.0f, 1.0f, detailedIndex / (float) totalNumFiles); } } // namespace juce diff --git a/modules/juce_core/files/juce_DirectoryIterator.h b/modules/juce_core/files/juce_DirectoryIterator.h index 2ad9d326..0988306e 100644 --- a/modules/juce_core/files/juce_DirectoryIterator.h +++ b/modules/juce_core/files/juce_DirectoryIterator.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -25,6 +25,8 @@ namespace juce //============================================================================== /** + This class is now deprecated in favour of RangedDirectoryIterator. + Searches through the files in a directory, returning each file that is found. A DirectoryIterator will search through a directory and its subdirectories using @@ -42,12 +44,15 @@ namespace juce It also provides an estimate of its progress, using a (highly inaccurate!) algorithm. @tags{Core} + @see RangedDirectoryIterator */ class JUCE_API DirectoryIterator final { public: //============================================================================== - /** Creates a DirectoryIterator for a given directory. + /** This class is now deprecated in favour of RangedDirectoryIterator. + + Creates a DirectoryIterator for a given directory. After creating one of these, call its next() method to get the first file - e.g. @code @@ -62,17 +67,12 @@ public: } @endcode - @param directory the directory to search in - @param isRecursive whether all the subdirectories should also be searched - @param wildCard the file pattern to match. This may contain multiple patterns - separated by a semi-colon or comma, e.g. "*.jpg;*.png" - @param whatToLookFor a value from the File::TypesOfFileToFind enum, specifying - whether to look for files, directories, or both. + @see RangedDirectoryIterator */ - DirectoryIterator (const File& directory, - bool isRecursive, - const String& wildCard = "*", - int whatToLookFor = File::findFiles); + JUCE_DEPRECATED (DirectoryIterator (const File& directory, + bool isRecursive, + const String& wildCard = "*", + int whatToLookFor = File::findFiles)); /** Destructor. */ ~DirectoryIterator(); diff --git a/modules/juce_core/files/juce_File.cpp b/modules/juce_core/files/juce_File.cpp index 7041ecd8..79d9d8e5 100644 --- a/modules/juce_core/files/juce_File.cpp +++ b/modules/juce_core/files/juce_File.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -485,7 +485,7 @@ String File::descriptionOfSizeInBytes (const int64 bytes) else if (bytes < 1024 * 1024 * 1024) { suffix = " MB"; divisor = 1024.0 * 1024.0; } else { suffix = " GB"; divisor = 1024.0 * 1024.0 * 1024.0; } - return (divisor > 0 ? String (bytes / divisor, 1) : String (bytes)) + suffix; + return (divisor > 0 ? String ((double) bytes / divisor, 1) : String (bytes)) + suffix; } //============================================================================== @@ -574,7 +574,7 @@ int File::findChildFiles (Array<File>& results, int whatToLookFor, bool searchRe { int total = 0; - for (DirectoryIterator di (*this, searchRecursively, wildcard, whatToLookFor); di.next();) + for (const auto& di : RangedDirectoryIterator (*this, searchRecursively, wildcard, whatToLookFor)) { results.add (di.getFile()); ++total; @@ -585,12 +585,10 @@ int File::findChildFiles (Array<File>& results, int whatToLookFor, bool searchRe int File::getNumberOfChildFiles (const int whatToLookFor, const String& wildCardPattern) const { - int total = 0; - - for (DirectoryIterator di (*this, false, wildCardPattern, whatToLookFor); di.next();) - ++total; - - return total; + return std::accumulate (RangedDirectoryIterator (*this, false, wildCardPattern, whatToLookFor), + RangedDirectoryIterator(), + 0, + [] (int acc, const DirectoryEntry&) { return acc + 1; }); } bool File::containsSubDirectories() const @@ -598,8 +596,7 @@ bool File::containsSubDirectories() const if (! isDirectory()) return false; - DirectoryIterator di (*this, false, "*", findDirectories); - return di.next(); + return RangedDirectoryIterator (*this, false, "*", findDirectories) != RangedDirectoryIterator(); } //============================================================================== @@ -726,22 +723,24 @@ bool File::startAsProcess (const String& parameters) const } //============================================================================== -FileInputStream* File::createInputStream() const +std::unique_ptr<FileInputStream> File::createInputStream() const { - std::unique_ptr<FileInputStream> fin (new FileInputStream (*this)); + auto fin = std::make_unique<FileInputStream> (*this); if (fin->openedOk()) - return fin.release(); + return fin; return nullptr; } -FileOutputStream* File::createOutputStream (size_t bufferSize) const +std::unique_ptr<FileOutputStream> File::createOutputStream (size_t bufferSize) const { - std::unique_ptr<FileOutputStream> out (new FileOutputStream (*this, bufferSize)); + auto fout = std::make_unique<FileOutputStream> (*this, bufferSize); + + if (fout->openedOk()) + return fout; - return out->failedToOpen() ? nullptr - : out.release(); + return nullptr; } //============================================================================== @@ -753,8 +752,8 @@ bool File::appendData (const void* const dataToAppend, if (numberOfBytes == 0) return true; - FileOutputStream out (*this, 8192); - return out.openedOk() && out.write (dataToAppend, numberOfBytes); + FileOutputStream fout (*this, 8192); + return fout.openedOk() && fout.write (dataToAppend, numberOfBytes); } bool File::replaceWithData (const void* const dataToWrite, @@ -770,12 +769,12 @@ bool File::replaceWithData (const void* const dataToWrite, bool File::appendText (const String& text, bool asUnicode, bool writeHeaderBytes, const char* lineFeed) const { - FileOutputStream out (*this); + FileOutputStream fout (*this); - if (out.failedToOpen()) + if (fout.failedToOpen()) return false; - return out.writeText (text, asUnicode, writeHeaderBytes, lineFeed); + return fout.writeText (text, asUnicode, writeHeaderBytes, lineFeed); } bool File::replaceWithText (const String& textToWrite, bool asUnicode, bool writeHeaderBytes, const char* lineFeed) const diff --git a/modules/juce_core/files/juce_File.h b/modules/juce_core/files/juce_File.h index e52b138a..17ccaba7 100644 --- a/modules/juce_core/files/juce_File.h +++ b/modules/juce_core/files/juce_File.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -20,6 +20,14 @@ ============================================================================== */ +#if ! DOXYGEN && (JUCE_MAC || JUCE_IOS) + #if __LP64__ + using OSType = unsigned int; + #else + using OSType = unsigned long; + #endif +#endif + namespace juce { @@ -566,7 +574,7 @@ public: @param wildCardPattern the filename pattern to search for, e.g. "*.txt" @returns the set of files that were found - @see getNumberOfChildFiles, DirectoryIterator + @see getNumberOfChildFiles, RangedDirectoryIterator */ Array<File> findChildFiles (int whatToLookFor, bool searchRecursively, @@ -594,7 +602,8 @@ public: is also added to this value, hidden files won't be counted @param wildCardPattern the filename pattern to search for, e.g. "*.txt" @returns the number of matches found - @see findChildFiles, DirectoryIterator + + @see findChildFiles, RangedDirectoryIterator */ int getNumberOfChildFiles (int whatToLookFor, const String& wildCardPattern = "*") const; @@ -622,7 +631,7 @@ public: start of the file), or nullptr if the file can't be opened for some reason @see createOutputStream, loadFileAsData */ - FileInputStream* createInputStream() const; + std::unique_ptr<FileInputStream> createInputStream() const; /** Creates a stream to write to this file. @@ -655,7 +664,7 @@ public: end of the file), or nullptr if the file can't be opened for some reason @see createInputStream, appendData, appendText */ - FileOutputStream* createOutputStream (size_t bufferSize = 0x8000) const; + std::unique_ptr<FileOutputStream> createOutputStream (size_t bufferSize = 0x8000) const; //============================================================================== /** Loads a file's contents into memory as a block of binary data. diff --git a/modules/juce_core/files/juce_FileFilter.cpp b/modules/juce_core/files/juce_FileFilter.cpp index 2d0cb624..5b9f48d2 100644 --- a/modules/juce_core/files/juce_FileFilter.cpp +++ b/modules/juce_core/files/juce_FileFilter.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/files/juce_FileFilter.h b/modules/juce_core/files/juce_FileFilter.h index c77cb4fb..a58fad41 100644 --- a/modules/juce_core/files/juce_FileFilter.h +++ b/modules/juce_core/files/juce_FileFilter.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/files/juce_FileInputStream.cpp b/modules/juce_core/files/juce_FileInputStream.cpp index 8f17e99c..f37d9d5f 100644 --- a/modules/juce_core/files/juce_FileInputStream.cpp +++ b/modules/juce_core/files/juce_FileInputStream.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -89,63 +89,84 @@ struct FileInputStreamTests : public UnitTest void runTest() override { + beginTest ("Open stream non-existent file"); + { + auto tempFile = File::createTempFile (".txt"); + expect (! tempFile.exists()); + + FileInputStream stream (tempFile); + expect (stream.failedToOpen()); + } + + beginTest ("Open stream existing file"); + { + auto tempFile = File::createTempFile (".txt"); + tempFile.create(); + expect (tempFile.exists()); + + FileInputStream stream (tempFile); + expect (stream.openedOk()); + } + const MemoryBlock data ("abcdefghijklmnopqrstuvwxyz", 26); File f (File::createTempFile (".txt")); f.appendData (data.getData(), data.getSize()); FileInputStream stream (f); beginTest ("Read"); - - expectEquals (stream.getPosition(), (int64) 0); - expectEquals (stream.getTotalLength(), (int64) data.getSize()); - expectEquals (stream.getNumBytesRemaining(), stream.getTotalLength()); - expect (! stream.isExhausted()); - - size_t numBytesRead = 0; - MemoryBlock readBuffer (data.getSize()); - - while (numBytesRead < data.getSize()) { - numBytesRead += (size_t) stream.read (&readBuffer[numBytesRead], 3); + expectEquals (stream.getPosition(), (int64) 0); + expectEquals (stream.getTotalLength(), (int64) data.getSize()); + expectEquals (stream.getNumBytesRemaining(), stream.getTotalLength()); + expect (! stream.isExhausted()); - expectEquals (stream.getPosition(), (int64) numBytesRead); - expectEquals (stream.getNumBytesRemaining(), (int64) (data.getSize() - numBytesRead)); - expect (stream.isExhausted() == (numBytesRead == data.getSize())); - } + size_t numBytesRead = 0; + MemoryBlock readBuffer (data.getSize()); - expectEquals (stream.getPosition(), (int64) data.getSize()); - expectEquals (stream.getNumBytesRemaining(), (int64) 0); - expect (stream.isExhausted()); + while (numBytesRead < data.getSize()) + { + numBytesRead += (size_t) stream.read (&readBuffer[numBytesRead], 3); - expect (readBuffer == data); + expectEquals (stream.getPosition(), (int64) numBytesRead); + expectEquals (stream.getNumBytesRemaining(), (int64) (data.getSize() - numBytesRead)); + expect (stream.isExhausted() == (numBytesRead == data.getSize())); + } - beginTest ("Skip"); + expectEquals (stream.getPosition(), (int64) data.getSize()); + expectEquals (stream.getNumBytesRemaining(), (int64) 0); + expect (stream.isExhausted()); - stream.setPosition (0); - expectEquals (stream.getPosition(), (int64) 0); - expectEquals (stream.getTotalLength(), (int64) data.getSize()); - expectEquals (stream.getNumBytesRemaining(), stream.getTotalLength()); - expect (! stream.isExhausted()); - - numBytesRead = 0; - const int numBytesToSkip = 5; + expect (readBuffer == data); + } - while (numBytesRead < data.getSize()) + beginTest ("Skip"); { - stream.skipNextBytes (numBytesToSkip); - numBytesRead += numBytesToSkip; - numBytesRead = std::min (numBytesRead, data.getSize()); - - expectEquals (stream.getPosition(), (int64) numBytesRead); - expectEquals (stream.getNumBytesRemaining(), (int64) (data.getSize() - numBytesRead)); - expect (stream.isExhausted() == (numBytesRead == data.getSize())); + stream.setPosition (0); + expectEquals (stream.getPosition(), (int64) 0); + expectEquals (stream.getTotalLength(), (int64) data.getSize()); + expectEquals (stream.getNumBytesRemaining(), stream.getTotalLength()); + expect (! stream.isExhausted()); + + size_t numBytesRead = 0; + const int numBytesToSkip = 5; + + while (numBytesRead < data.getSize()) + { + stream.skipNextBytes (numBytesToSkip); + numBytesRead += numBytesToSkip; + numBytesRead = std::min (numBytesRead, data.getSize()); + + expectEquals (stream.getPosition(), (int64) numBytesRead); + expectEquals (stream.getNumBytesRemaining(), (int64) (data.getSize() - numBytesRead)); + expect (stream.isExhausted() == (numBytesRead == data.getSize())); + } + + expectEquals (stream.getPosition(), (int64) data.getSize()); + expectEquals (stream.getNumBytesRemaining(), (int64) 0); + expect (stream.isExhausted()); + + f.deleteFile(); } - - expectEquals (stream.getPosition(), (int64) data.getSize()); - expectEquals (stream.getNumBytesRemaining(), (int64) 0); - expect (stream.isExhausted()); - - f.deleteFile(); } }; diff --git a/modules/juce_core/files/juce_FileInputStream.h b/modules/juce_core/files/juce_FileInputStream.h index 82d39b4a..f764fb2e 100644 --- a/modules/juce_core/files/juce_FileInputStream.h +++ b/modules/juce_core/files/juce_FileInputStream.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/files/juce_FileOutputStream.cpp b/modules/juce_core/files/juce_FileOutputStream.cpp index 84852832..b520be60 100644 --- a/modules/juce_core/files/juce_FileOutputStream.cpp +++ b/modules/juce_core/files/juce_FileOutputStream.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -23,8 +23,6 @@ namespace juce { -int64 juce_fileSetPosition (void* handle, int64 pos); - //============================================================================== FileOutputStream::FileOutputStream (const File& f, const size_t bufferSizeToUse) : file (f), diff --git a/modules/juce_core/files/juce_FileOutputStream.h b/modules/juce_core/files/juce_FileOutputStream.h index c621d4ea..21814c92 100644 --- a/modules/juce_core/files/juce_FileOutputStream.h +++ b/modules/juce_core/files/juce_FileOutputStream.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/files/juce_FileSearchPath.cpp b/modules/juce_core/files/juce_FileSearchPath.cpp index 4b71ff4f..a316bddf 100644 --- a/modules/juce_core/files/juce_FileSearchPath.cpp +++ b/modules/juce_core/files/juce_FileSearchPath.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/files/juce_FileSearchPath.h b/modules/juce_core/files/juce_FileSearchPath.h index 5a8d963f..4da5907d 100644 --- a/modules/juce_core/files/juce_FileSearchPath.h +++ b/modules/juce_core/files/juce_FileSearchPath.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/files/juce_MemoryMappedFile.h b/modules/juce_core/files/juce_MemoryMappedFile.h index 88a8688c..02771199 100644 --- a/modules/juce_core/files/juce_MemoryMappedFile.h +++ b/modules/juce_core/files/juce_MemoryMappedFile.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/files/juce_RangedDirectoryIterator.cpp b/modules/juce_core/files/juce_RangedDirectoryIterator.cpp new file mode 100644 index 00000000..43eac299 --- /dev/null +++ b/modules/juce_core/files/juce_RangedDirectoryIterator.cpp @@ -0,0 +1,77 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + To use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ + +float DirectoryEntry::getEstimatedProgress() const +{ + if (auto it = iterator.lock()) + return it->getEstimatedProgress(); + + return 0.0f; +} + +JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wdeprecated-declarations") +JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4996) + +// We implement this in terms of the deprecated DirectoryIterator, +// but the old DirectoryIterator might go away in the future! +RangedDirectoryIterator::RangedDirectoryIterator (const File& directory, + bool isRecursive, + const String& wildCard, + int whatToLookFor) + : iterator (new DirectoryIterator (directory, + isRecursive, + wildCard, + whatToLookFor)) +{ + entry.iterator = iterator; + increment(); +} + +JUCE_END_IGNORE_WARNINGS_GCC_LIKE +JUCE_END_IGNORE_WARNINGS_MSVC + +bool RangedDirectoryIterator::next() +{ + const auto result = iterator->next (&entry.directory, + &entry.hidden, + &entry.fileSize, + &entry.modTime, + &entry.creationTime, + &entry.readOnly); + if (result) + entry.file = iterator->getFile(); + else + entry = {}; + + return result; +} + +void RangedDirectoryIterator::increment() +{ + if (iterator != nullptr && ! next()) + iterator = nullptr; +} + +} // namespace juce diff --git a/modules/juce_core/files/juce_RangedDirectoryIterator.h b/modules/juce_core/files/juce_RangedDirectoryIterator.h new file mode 100644 index 00000000..416217f7 --- /dev/null +++ b/modules/juce_core/files/juce_RangedDirectoryIterator.h @@ -0,0 +1,181 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + To use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ + +//============================================================================== +/** + Describes the attributes of a file or folder. + + @tags{Core} +*/ +class DirectoryEntry final +{ +public: + /** The path to a file or folder. */ + File getFile() const { return file; } + + /** The time at which the item was last modified. */ + Time getModificationTime() const { return modTime; } + + /** The time at which the item was created. */ + Time getCreationTime() const { return creationTime; } + + /** The size of the item. */ + int64 getFileSize() const { return fileSize; } + + /** True if the item is a directory, false otherwise. */ + bool isDirectory() const { return directory; } + + /** True if the item is hidden, false otherwise. */ + bool isHidden() const { return hidden; } + + /** True if the item is read-only, false otherwise. */ + bool isReadOnly() const { return readOnly; } + + /** The estimated proportion of the range that has been visited + by the iterator, from 0.0 to 1.0. + */ + float getEstimatedProgress() const; + +private: + std::weak_ptr<DirectoryIterator> iterator; + File file; + Time modTime; + Time creationTime; + int64 fileSize = 0; + bool directory = false; + bool hidden = false; + bool readOnly = false; + + friend class RangedDirectoryIterator; +}; + +/** A convenience operator so that the expression `*it++` works correctly when + `it` is an instance of RangedDirectoryIterator. +*/ +inline const DirectoryEntry& operator* (const DirectoryEntry& e) noexcept { return e; } + +//============================================================================== +/** + Allows iterating over files and folders using C++11 range-for syntax. + + In the following example, we recursively find all hidden files in a + specific directory. + + @code + std::vector<File> hiddenFiles; + + for (DirectoryEntry entry : RangedDirectoryIterator (File ("/path/to/folder"), isRecursive)) + if (entry.isHidden()) + hiddenFiles.push_back (entry.getFile()); + @endcode + + @tags{Core} +*/ +class RangedDirectoryIterator final +{ +public: + using difference_type = std::ptrdiff_t; + using value_type = DirectoryEntry; + using reference = DirectoryEntry; + using pointer = void; + using iterator_category = std::input_iterator_tag; + + /** The default-constructed iterator acts as the 'end' sentinel. */ + RangedDirectoryIterator() = default; + + /** Creates a RangedDirectoryIterator for a given directory. + + The resulting iterator can be used directly in a 'range-for' expression. + + @param directory the directory to search in + @param isRecursive whether all the subdirectories should also be searched + @param wildCard the file pattern to match. This may contain multiple patterns + separated by a semi-colon or comma, e.g. "*.jpg;*.png" + @param whatToLookFor a value from the File::TypesOfFileToFind enum, specifying + whether to look for files, directories, or both. + */ + RangedDirectoryIterator (const File& directory, + bool isRecursive, + const String& wildCard = "*", + int whatToLookFor = File::findFiles); + + /** Returns true if both iterators are in their end/sentinel state, + otherwise returns false. + */ + bool operator== (const RangedDirectoryIterator& other) const noexcept + { + return iterator == nullptr && other.iterator == nullptr; + } + + /** Returns the inverse of operator== */ + bool operator!= (const RangedDirectoryIterator& other) const noexcept + { + return ! operator== (other); + } + + /** Return an object containing metadata about the file or folder to + which the iterator is currently pointing. + */ + const DirectoryEntry& operator* () const noexcept { return entry; } + const DirectoryEntry* operator->() const noexcept { return &entry; } + + /** Moves the iterator along to the next file. */ + RangedDirectoryIterator& operator++() + { + increment(); + return *this; + } + + /** Moves the iterator along to the next file. + + @returns an object containing metadata about the file or folder to + to which the iterator was previously pointing. + */ + DirectoryEntry operator++ (int) + { + auto result = *(*this); + ++(*this); + return result; + } + +private: + bool next(); + void increment(); + + std::shared_ptr<DirectoryIterator> iterator; + DirectoryEntry entry; +}; + +/** Returns the iterator that was passed in. + Provided for range-for compatibility. +*/ +inline RangedDirectoryIterator begin (const RangedDirectoryIterator& it) { return it; } + +/** Returns a default-constructed sentinel value. + Provided for range-for compatibility. +*/ +inline RangedDirectoryIterator end (const RangedDirectoryIterator&) { return {}; } + +} // namespace juce diff --git a/modules/juce_core/files/juce_TemporaryFile.cpp b/modules/juce_core/files/juce_TemporaryFile.cpp index d416015b..645ba055 100644 --- a/modules/juce_core/files/juce_TemporaryFile.cpp +++ b/modules/juce_core/files/juce_TemporaryFile.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/files/juce_TemporaryFile.h b/modules/juce_core/files/juce_TemporaryFile.h index 8629193b..bc3aebe2 100644 --- a/modules/juce_core/files/juce_TemporaryFile.h +++ b/modules/juce_core/files/juce_TemporaryFile.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/files/juce_WildcardFileFilter.cpp b/modules/juce_core/files/juce_WildcardFileFilter.cpp index 03e3085d..74f69d67 100644 --- a/modules/juce_core/files/juce_WildcardFileFilter.cpp +++ b/modules/juce_core/files/juce_WildcardFileFilter.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/files/juce_WildcardFileFilter.h b/modules/juce_core/files/juce_WildcardFileFilter.h index 505c1ff5..1e1b6766 100644 --- a/modules/juce_core/files/juce_WildcardFileFilter.h +++ b/modules/juce_core/files/juce_WildcardFileFilter.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/javascript/juce_JSON.cpp b/modules/juce_core/javascript/juce_JSON.cpp index b0837429..071fb00d 100644 --- a/modules/juce_core/javascript/juce_JSON.cpp +++ b/modules/juce_core/javascript/juce_JSON.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -126,6 +126,8 @@ struct JSONParser break; } + + default: break; } } diff --git a/modules/juce_core/javascript/juce_JSON.h b/modules/juce_core/javascript/juce_JSON.h index ff1588b9..21a48158 100644 --- a/modules/juce_core/javascript/juce_JSON.h +++ b/modules/juce_core/javascript/juce_JSON.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/javascript/juce_Javascript.cpp b/modules/juce_core/javascript/juce_Javascript.cpp index 4a92686c..9fe380c4 100644 --- a/modules/juce_core/javascript/juce_Javascript.cpp +++ b/modules/juce_core/javascript/juce_Javascript.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -54,10 +54,7 @@ namespace TokenTypes JUCE_DECLARE_JS_TOKEN (identifier, "$identifier") } -#if JUCE_MSVC - #pragma warning (push) - #pragma warning (disable: 4702) -#endif +JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4702) //============================================================================== struct JavascriptEngine::RootObject : public DynamicObject @@ -597,7 +594,7 @@ struct JavascriptEngine::RootObject : public DynamicObject { DivideOp (const CodeLocation& l, ExpPtr& a, ExpPtr& b) noexcept : BinaryOperator (l, a, b, TokenTypes::divide) {} var getWithDoubles (double a, double b) const override { return b != 0 ? a / b : std::numeric_limits<double>::infinity(); } - var getWithInts (int64 a, int64 b) const override { return b != 0 ? var (a / (double) b) : var (std::numeric_limits<double>::infinity()); } + var getWithInts (int64 a, int64 b) const override { return b != 0 ? var ((double) a / (double) b) : var (std::numeric_limits<double>::infinity()); } }; struct ModuloOp : public BinaryOperator @@ -817,7 +814,9 @@ struct JavascriptEngine::RootObject : public DynamicObject a.add (values.getUnchecked(i)->getResult (s)); // std::move() needed here for older compilers + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wredundant-move") return std::move (a); + JUCE_END_IGNORE_WARNINGS_GCC_LIKE } OwnedArray<Expression> values; @@ -1627,7 +1626,9 @@ struct JavascriptEngine::RootObject : public DynamicObject array->insert (start++, get (a, i)); // std::move() needed here for older compilers + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wredundant-move") return std::move (itemsRemoved); + JUCE_END_IGNORE_WARNINGS_GCC_LIKE } return var::undefined(); @@ -1913,8 +1914,6 @@ const NamedValueSet& JavascriptEngine::getRootObjectProperties() const noexcept return root->getProperties(); } -#if JUCE_MSVC - #pragma warning (pop) -#endif +JUCE_END_IGNORE_WARNINGS_MSVC } // namespace juce diff --git a/modules/juce_core/javascript/juce_Javascript.h b/modules/juce_core/javascript/juce_Javascript.h index dd8fb6a9..f52d95d7 100644 --- a/modules/juce_core/javascript/juce_Javascript.h +++ b/modules/juce_core/javascript/juce_Javascript.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/juce_core.cpp b/modules/juce_core/juce_core.cpp index a6a2ef76..914cae68 100644 --- a/modules/juce_core/juce_core.cpp +++ b/modules/juce_core/juce_core.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -53,10 +53,9 @@ #include <cstdio> #include <locale.h> #else - #pragma warning (push) - #pragma warning (disable: 4091) + JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4091) #include <Dbghelp.h> - #pragma warning (pop) + JUCE_END_IGNORE_WARNINGS_MSVC #if ! JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES #pragma comment (lib, "DbgHelp.lib") @@ -125,6 +124,7 @@ #include "containers/juce_ReferenceCountedArray.cpp" #include "containers/juce_SparseSet.cpp" #include "files/juce_DirectoryIterator.cpp" +#include "files/juce_RangedDirectoryIterator.cpp" #include "files/juce_File.cpp" #include "files/juce_FileInputStream.cpp" #include "files/juce_FileOutputStream.cpp" @@ -136,6 +136,7 @@ #include "maths/juce_Expression.cpp" #include "maths/juce_Random.cpp" #include "memory/juce_MemoryBlock.cpp" +#include "memory/juce_AllocationHooks.cpp" #include "misc/juce_RuntimePermissions.cpp" #include "misc/juce_Result.cpp" #include "misc/juce_Uuid.cpp" diff --git a/modules/juce_core/juce_core.h b/modules/juce_core/juce_core.h index 62d0dfa4..1f6ea804 100644 --- a/modules/juce_core/juce_core.h +++ b/modules/juce_core/juce_core.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -25,21 +25,21 @@ The block below describes the properties of this module, and is read by the Projucer to automatically generate project code that uses it. For details about the syntax and how to create or use a module, see the - JUCE Module Format.txt file. + JUCE Module Format.md file. BEGIN_JUCE_MODULE_DECLARATION ID: juce_core vendor: juce - version: 5.4.7 + version: 6.0.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 license: ISC dependencies: - OSXFrameworks: Cocoa IOKit + OSXFrameworks: Cocoa Foundation IOKit iOSFrameworks: Foundation linuxLibs: rt dl pthread mingwLibs: uuid wsock32 wininet version ole32 ws2_32 oleaut32 imm32 comdlg32 shlwapi rpcrt4 winmm @@ -177,6 +177,13 @@ #define JUCE_STRICT_REFCOUNTEDPOINTER 0 #endif +/** Config: JUCE_ENABLE_ALLOCATION_HOOKS + If enabled, this will add global allocation functions with built-in assertions, which may + help when debugging allocations in unit tests. +*/ +#ifndef JUCE_ENABLE_ALLOCATION_HOOKS + #define JUCE_ENABLE_ALLOCATION_HOOKS 0 +#endif #ifndef JUCE_STRING_UTF_TYPE #define JUCE_STRING_UTF_TYPE 8 @@ -217,19 +224,14 @@ namespace juce #include "memory/juce_Atomic.h" #include "text/juce_CharacterFunctions.h" -#if JUCE_MSVC - #pragma warning (push) - #pragma warning (disable: 4514 4996) -#endif +JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4514 4996) #include "text/juce_CharPointer_UTF8.h" #include "text/juce_CharPointer_UTF16.h" #include "text/juce_CharPointer_UTF32.h" #include "text/juce_CharPointer_ASCII.h" -#if JUCE_MSVC - #pragma warning (pop) -#endif +JUCE_END_IGNORE_WARNINGS_MSVC #include "text/juce_String.h" #include "text/juce_StringRef.h" @@ -288,6 +290,7 @@ namespace juce #include "streams/juce_InputSource.h" #include "files/juce_File.h" #include "files/juce_DirectoryIterator.h" +#include "files/juce_RangedDirectoryIterator.h" #include "files/juce_FileInputStream.h" #include "files/juce_FileOutputStream.h" #include "files/juce_FileSearchPath.h" @@ -334,6 +337,7 @@ namespace juce #include "zip/juce_ZipFile.h" #include "containers/juce_PropertySet.h" #include "memory/juce_SharedResourcePointer.h" +#include "memory/juce_AllocationHooks.h" #if JUCE_CORE_INCLUDE_OBJC_HELPERS && (JUCE_MAC || JUCE_IOS) #include "native/juce_osx_ObjCHelpers.h" @@ -375,11 +379,9 @@ namespace juce } #endif -#if JUCE_MSVC - #pragma warning (pop) +JUCE_END_IGNORE_WARNINGS_MSVC - // In DLL builds, need to disable this warnings for other modules - #if defined (JUCE_DLL_BUILD) || defined (JUCE_DLL) - #pragma warning (disable: 4251) - #endif +// In DLL builds, need to disable this warnings for other modules +#if defined (JUCE_DLL_BUILD) || defined (JUCE_DLL) + JUCE_IGNORE_MSVC (4251) #endif diff --git a/modules/juce_core/juce_core.mm b/modules/juce_core/juce_core.mm index 8e826696..c8100ed2 100644 --- a/modules/juce_core/juce_core.mm +++ b/modules/juce_core/juce_core.mm @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/logging/juce_FileLogger.cpp b/modules/juce_core/logging/juce_FileLogger.cpp index 7ec9dba6..85f27977 100644 --- a/modules/juce_core/logging/juce_FileLogger.cpp +++ b/modules/juce_core/logging/juce_FileLogger.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/logging/juce_FileLogger.h b/modules/juce_core/logging/juce_FileLogger.h index 50e5c874..5add0939 100644 --- a/modules/juce_core/logging/juce_FileLogger.h +++ b/modules/juce_core/logging/juce_FileLogger.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/logging/juce_Logger.cpp b/modules/juce_core/logging/juce_Logger.cpp index 3cb0d896..555c954a 100644 --- a/modules/juce_core/logging/juce_Logger.cpp +++ b/modules/juce_core/logging/juce_Logger.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/logging/juce_Logger.h b/modules/juce_core/logging/juce_Logger.h index 60218a3b..a7170bfd 100644 --- a/modules/juce_core/logging/juce_Logger.h +++ b/modules/juce_core/logging/juce_Logger.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/maths/juce_BigInteger.cpp b/modules/juce_core/maths/juce_BigInteger.cpp index fae2e2f0..5f23c78e 100644 --- a/modules/juce_core/maths/juce_BigInteger.cpp +++ b/modules/juce_core/maths/juce_BigInteger.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -551,7 +551,7 @@ BigInteger& BigInteger::operator*= (const BigInteger& other) { auto uv = (uint64) totalValues[i + j] + (uint64) values[j] * (uint64) mValues[i] + (uint64) c; totalValues[i + j] = (uint32) uv; - c = uv >> 32; + c = static_cast<uint32> (uv >> 32); } totalValues[i + n + 1] = c; diff --git a/modules/juce_core/maths/juce_BigInteger.h b/modules/juce_core/maths/juce_BigInteger.h index 3463f3cf..323c053e 100644 --- a/modules/juce_core/maths/juce_BigInteger.h +++ b/modules/juce_core/maths/juce_BigInteger.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/maths/juce_Expression.cpp b/modules/juce_core/maths/juce_Expression.cpp index 41a50360..edbb0743 100644 --- a/modules/juce_core/maths/juce_Expression.cpp +++ b/modules/juce_core/maths/juce_Expression.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -681,7 +681,7 @@ struct Expression::Helpers } //============================================================================== - static inline bool isDecimalDigit (const juce_wchar c) noexcept + static bool isDecimalDigit (const juce_wchar c) noexcept { return c >= '0' && c <= '9'; } diff --git a/modules/juce_core/maths/juce_Expression.h b/modules/juce_core/maths/juce_Expression.h index c825b691..f79aed79 100644 --- a/modules/juce_core/maths/juce_Expression.h +++ b/modules/juce_core/maths/juce_Expression.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/maths/juce_MathsFunctions.h b/modules/juce_core/maths/juce_MathsFunctions.h index 452a03d6..58ee1999 100644 --- a/modules/juce_core/maths/juce_MathsFunctions.h +++ b/modules/juce_core/maths/juce_MathsFunctions.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -91,33 +91,33 @@ using uint32 = unsigned int; /** Returns the larger of two values. */ template <typename Type> -JUCE_CONSTEXPR Type jmax (Type a, Type b) { return a < b ? b : a; } +constexpr Type jmax (Type a, Type b) { return a < b ? b : a; } /** Returns the larger of three values. */ template <typename Type> -JUCE_CONSTEXPR Type jmax (Type a, Type b, Type c) { return a < b ? (b < c ? c : b) : (a < c ? c : a); } +constexpr Type jmax (Type a, Type b, Type c) { return a < b ? (b < c ? c : b) : (a < c ? c : a); } /** Returns the larger of four values. */ template <typename Type> -JUCE_CONSTEXPR Type jmax (Type a, Type b, Type c, Type d) { return jmax (a, jmax (b, c, d)); } +constexpr Type jmax (Type a, Type b, Type c, Type d) { return jmax (a, jmax (b, c, d)); } /** Returns the smaller of two values. */ template <typename Type> -JUCE_CONSTEXPR Type jmin (Type a, Type b) { return b < a ? b : a; } +constexpr Type jmin (Type a, Type b) { return b < a ? b : a; } /** Returns the smaller of three values. */ template <typename Type> -JUCE_CONSTEXPR Type jmin (Type a, Type b, Type c) { return b < a ? (c < b ? c : b) : (c < a ? c : a); } +constexpr Type jmin (Type a, Type b, Type c) { return b < a ? (c < b ? c : b) : (c < a ? c : a); } /** Returns the smaller of four values. */ template <typename Type> -JUCE_CONSTEXPR Type jmin (Type a, Type b, Type c, Type d) { return jmin (a, jmin (b, c, d)); } +constexpr Type jmin (Type a, Type b, Type c, Type d) { return jmin (a, jmin (b, c, d)); } /** Remaps a normalised value (between 0 and 1) to a target range. This effectively returns (targetRangeMin + value0To1 * (targetRangeMax - targetRangeMin)). */ template <typename Type> -JUCE_CONSTEXPR Type jmap (Type value0To1, Type targetRangeMin, Type targetRangeMax) +constexpr Type jmap (Type value0To1, Type targetRangeMin, Type targetRangeMax) { return targetRangeMin + value0To1 * (targetRangeMax - targetRangeMin); } @@ -130,6 +130,50 @@ Type jmap (Type sourceValue, Type sourceRangeMin, Type sourceRangeMax, Type targ return targetRangeMin + ((targetRangeMax - targetRangeMin) * (sourceValue - sourceRangeMin)) / (sourceRangeMax - sourceRangeMin); } +/** Remaps a normalised value (between 0 and 1) to a logarithmic target range. + + The entire target range must be greater than zero. + + @see mapFromLog10 + + @code + mapToLog10 (0.5, 0.4, 40.0) == 4.0 + @endcode +*/ +template <typename Type> +Type mapToLog10 (Type value0To1, Type logRangeMin, Type logRangeMax) +{ + jassert (logRangeMin > 0); + jassert (logRangeMax > 0); + + auto logMin = std::log10 (logRangeMin); + auto logMax = std::log10 (logRangeMax); + + return std::pow ((Type) 10.0, value0To1 * (logMax - logMin) + logMin); +} + +/** Remaps a logarithmic value in a target range to a normalised value (between 0 and 1). + + The entire target range must be greater than zero. + + @see mapToLog10 + + @code + mapFromLog10 (4.0, 0.4, 40.0) == 0.5 + @endcode +*/ +template <typename Type> +Type mapFromLog10 (Type valueInLogRange, Type logRangeMin, Type logRangeMax) +{ + jassert (logRangeMin > 0); + jassert (logRangeMax > 0); + + auto logMin = std::log10 (logRangeMin); + auto logMax = std::log10 (logRangeMax); + + return (std::log10 (valueInLogRange) - logMin) / (logMax - logMin); +} + /** Scans an array of values, returning the minimum value that it contains. */ template <typename Type> Type findMinimum (const Type* data, int numValues) @@ -297,7 +341,7 @@ void ignoreUnused (Types&&...) noexcept {} @endcode */ template <typename Type, size_t N> -JUCE_CONSTEXPR int numElementsInArray (Type (&)[N]) noexcept { return N; } +constexpr int numElementsInArray (Type (&)[N]) noexcept { return N; } //============================================================================== // Some useful maths functions that aren't always present with all compilers and build settings. @@ -327,8 +371,6 @@ inline float juce_hypot (float a, float b) noexcept #endif //============================================================================== -#if JUCE_HAS_CONSTEXPR - /** Commonly used mathematical constants @tags{Core} @@ -352,71 +394,29 @@ struct MathConstants static constexpr FloatType sqrt2 = static_cast<FloatType> (1.4142135623730950488L); }; -#else - -/** Commonly used mathematical constants - - @tags{Core} -*/ -template <typename FloatType> -struct MathConstants -{ - /** A predefined value for Pi */ - static const FloatType pi; - - /** A predefined value for 2 * Pi */ - static const FloatType twoPi; - - /** A predefined value for Pi / 2 */ - static const FloatType halfPi; - - /** A predefined value for Euler's number */ - static const FloatType euler; - - /** A predefined value for sqrt(2) */ - static const FloatType sqrt2; -}; - -template <typename FloatType> -const FloatType MathConstants<FloatType>::pi = static_cast<FloatType> (3.141592653589793238L); - -template <typename FloatType> -const FloatType MathConstants<FloatType>::twoPi = static_cast<FloatType> (2 * 3.141592653589793238L); - -template <typename FloatType> -const FloatType MathConstants<FloatType>::halfPi = static_cast<FloatType> (3.141592653589793238L / 2); - -template <typename FloatType> -const FloatType MathConstants<FloatType>::euler = static_cast<FloatType> (2.71828182845904523536L); - -template <typename FloatType> -const FloatType MathConstants<FloatType>::sqrt2 = static_cast<FloatType> (1.4142135623730950488L); - -#endif - #ifndef DOXYGEN /** A double-precision constant for pi. @deprecated This is deprecated in favour of MathConstants<double>::pi. The reason is that "double_Pi" was a confusing name, and many people misused it, wrongly thinking it meant 2 * pi ! */ -const JUCE_CONSTEXPR double double_Pi = MathConstants<double>::pi; +const constexpr double double_Pi = MathConstants<double>::pi; /** A single-precision constant for pi. @deprecated This is deprecated in favour of MathConstants<float>::pi. The reason is that "double_Pi" was a confusing name, and many people misused it, wrongly thinking it meant 2 * pi ! */ -const JUCE_CONSTEXPR float float_Pi = MathConstants<float>::pi; +const constexpr float float_Pi = MathConstants<float>::pi; #endif /** Converts an angle in degrees to radians. */ template <typename FloatType> -JUCE_CONSTEXPR FloatType degreesToRadians (FloatType degrees) noexcept { return degrees * (MathConstants<FloatType>::pi / FloatType (180)); } +constexpr FloatType degreesToRadians (FloatType degrees) noexcept { return degrees * (MathConstants<FloatType>::pi / FloatType (180)); } /** Converts an angle in radians to degrees. */ template <typename FloatType> -JUCE_CONSTEXPR FloatType radiansToDegrees (FloatType radians) noexcept { return radians * (FloatType (180) / MathConstants<FloatType>::pi); } +constexpr FloatType radiansToDegrees (FloatType radians) noexcept { return radians * (FloatType (180) / MathConstants<FloatType>::pi); } //============================================================================== @@ -521,7 +521,8 @@ template <typename FloatType> unsigned int truncatePositiveToUnsignedInt (FloatType value) noexcept { jassert (value >= static_cast<FloatType> (0)); - jassert (static_cast<FloatType> (value) <= std::numeric_limits<unsigned int>::max()); + jassert (static_cast<FloatType> (value) + <= static_cast<FloatType> (std::numeric_limits<unsigned int>::max())); return static_cast<unsigned int> (value); } @@ -529,7 +530,7 @@ unsigned int truncatePositiveToUnsignedInt (FloatType value) noexcept //============================================================================== /** Returns true if the specified integer is a power-of-two. */ template <typename IntegerType> -JUCE_CONSTEXPR bool isPowerOfTwo (IntegerType value) +constexpr bool isPowerOfTwo (IntegerType value) { return (value & (value - 1)) == 0; } @@ -582,7 +583,7 @@ IntegerType negativeAwareModulo (IntegerType dividend, const IntegerType divisor /** Returns the square of its argument. */ template <typename NumericType> -inline JUCE_CONSTEXPR NumericType square (NumericType n) noexcept +inline constexpr NumericType square (NumericType n) noexcept { return n * n; } diff --git a/modules/juce_core/maths/juce_NormalisableRange.h b/modules/juce_core/maths/juce_NormalisableRange.h index eb2c8d9e..1375bb39 100644 --- a/modules/juce_core/maths/juce_NormalisableRange.h +++ b/modules/juce_core/maths/juce_NormalisableRange.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/maths/juce_Random.cpp b/modules/juce_core/maths/juce_Random.cpp index 21427042..c2b75d47 100644 --- a/modules/juce_core/maths/juce_Random.cpp +++ b/modules/juce_core/maths/juce_Random.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -105,7 +105,9 @@ bool Random::nextBool() noexcept float Random::nextFloat() noexcept { - return static_cast<uint32> (nextInt()) / (std::numeric_limits<uint32>::max() + 1.0f); + auto result = static_cast<float> (static_cast<uint32> (nextInt())) + / (static_cast<float> (std::numeric_limits<uint32>::max()) + 1.0f); + return result == 1.0f ? 1.0f - std::numeric_limits<float>::epsilon() : result; } double Random::nextDouble() noexcept diff --git a/modules/juce_core/maths/juce_Random.h b/modules/juce_core/maths/juce_Random.h index 06fc278a..2a24fa75 100644 --- a/modules/juce_core/maths/juce_Random.h +++ b/modules/juce_core/maths/juce_Random.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/maths/juce_Range.h b/modules/juce_core/maths/juce_Range.h index fc22853d..89ffc0c0 100644 --- a/modules/juce_core/maths/juce_Range.h +++ b/modules/juce_core/maths/juce_Range.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -41,22 +41,22 @@ class Range public: //============================================================================== /** Constructs an empty range. */ - JUCE_CONSTEXPR Range() = default; + constexpr Range() = default; /** Constructs a range with given start and end values. */ - JUCE_CONSTEXPR Range (const ValueType startValue, const ValueType endValue) noexcept + constexpr Range (const ValueType startValue, const ValueType endValue) noexcept : start (startValue), end (jmax (startValue, endValue)) { } /** Constructs a copy of another range. */ - JUCE_CONSTEXPR Range (const Range&) = default; + constexpr Range (const Range&) = default; /** Copies another range object. */ Range& operator= (const Range&) = default; /** Returns the range that lies between two positions (in either order). */ - JUCE_CONSTEXPR static Range between (const ValueType position1, const ValueType position2) noexcept + constexpr static Range between (const ValueType position1, const ValueType position2) noexcept { return position1 < position2 ? Range (position1, position2) : Range (position2, position1); @@ -70,23 +70,23 @@ public: } /** Returns a range with the specified start position and a length of zero. */ - JUCE_CONSTEXPR static Range emptyRange (const ValueType start) noexcept + constexpr static Range emptyRange (const ValueType start) noexcept { return Range (start, start); } //============================================================================== /** Returns the start of the range. */ - JUCE_CONSTEXPR inline ValueType getStart() const noexcept { return start; } + constexpr inline ValueType getStart() const noexcept { return start; } /** Returns the length of the range. */ - JUCE_CONSTEXPR inline ValueType getLength() const noexcept { return end - start; } + constexpr inline ValueType getLength() const noexcept { return end - start; } /** Returns the end of the range. */ - JUCE_CONSTEXPR inline ValueType getEnd() const noexcept { return end; } + constexpr inline ValueType getEnd() const noexcept { return end; } /** Returns true if the range has a length of zero. */ - JUCE_CONSTEXPR inline bool isEmpty() const noexcept { return start == end; } + constexpr inline bool isEmpty() const noexcept { return start == end; } //============================================================================== /** Changes the start position of the range, leaving the end position unchanged. @@ -104,13 +104,13 @@ public: If the new start position is higher than the current end of the range, the end point will be pushed along to equal it, returning an empty range at the new position. */ - JUCE_CONSTEXPR Range withStart (const ValueType newStart) const noexcept + constexpr Range withStart (const ValueType newStart) const noexcept { return Range (newStart, jmax (newStart, end)); } /** Returns a range with the same length as this one, but moved to have the given start position. */ - JUCE_CONSTEXPR Range movedToStartAt (const ValueType newStart) const noexcept + constexpr Range movedToStartAt (const ValueType newStart) const noexcept { return Range (newStart, end + (newStart - start)); } @@ -130,13 +130,13 @@ public: If the new end position is below the current start of the range, the start point will be pushed back to equal the new end point. */ - JUCE_CONSTEXPR Range withEnd (const ValueType newEnd) const noexcept + constexpr Range withEnd (const ValueType newEnd) const noexcept { return Range (jmin (start, newEnd), newEnd); } /** Returns a range with the same length as this one, but moved to have the given end position. */ - JUCE_CONSTEXPR Range movedToEndAt (const ValueType newEnd) const noexcept + constexpr Range movedToEndAt (const ValueType newEnd) const noexcept { return Range (start + (newEnd - end), newEnd); } @@ -152,7 +152,7 @@ public: /** Returns a range with the same start as this one, but a different length. Lengths less than zero are treated as zero. */ - JUCE_CONSTEXPR Range withLength (const ValueType newLength) const noexcept + constexpr Range withLength (const ValueType newLength) const noexcept { return Range (start, start + newLength); } @@ -161,7 +161,7 @@ public: given amount. @returns The returned range will be (start - amount, end + amount) */ - JUCE_CONSTEXPR Range expanded (ValueType amount) const noexcept + constexpr Range expanded (ValueType amount) const noexcept { return Range (start - amount, end + amount); } @@ -186,27 +186,27 @@ public: /** Returns a range that is equal to this one with an amount added to its start and end. */ - JUCE_CONSTEXPR Range operator+ (const ValueType amountToAdd) const noexcept + constexpr Range operator+ (const ValueType amountToAdd) const noexcept { return Range (start + amountToAdd, end + amountToAdd); } /** Returns a range that is equal to this one with the specified amount subtracted from its start and end. */ - JUCE_CONSTEXPR Range operator- (const ValueType amountToSubtract) const noexcept + constexpr Range operator- (const ValueType amountToSubtract) const noexcept { return Range (start - amountToSubtract, end - amountToSubtract); } - JUCE_CONSTEXPR bool operator== (Range other) const noexcept { return start == other.start && end == other.end; } - JUCE_CONSTEXPR bool operator!= (Range other) const noexcept { return start != other.start || end != other.end; } + constexpr bool operator== (Range other) const noexcept { return start == other.start && end == other.end; } + constexpr bool operator!= (Range other) const noexcept { return start != other.start || end != other.end; } //============================================================================== /** Returns true if the given position lies inside this range. When making this comparison, the start value is considered to be inclusive, and the end of the range exclusive. */ - JUCE_CONSTEXPR bool contains (const ValueType position) const noexcept + constexpr bool contains (const ValueType position) const noexcept { return start <= position && position < end; } @@ -218,34 +218,34 @@ public: } /** Returns true if the given range lies entirely inside this range. */ - JUCE_CONSTEXPR bool contains (Range other) const noexcept + constexpr bool contains (Range other) const noexcept { return start <= other.start && end >= other.end; } /** Returns true if the given range intersects this one. */ - JUCE_CONSTEXPR bool intersects (Range other) const noexcept + constexpr bool intersects (Range other) const noexcept { return other.start < end && start < other.end; } /** Returns the range that is the intersection of the two ranges, or an empty range with an undefined start position if they don't overlap. */ - JUCE_CONSTEXPR Range getIntersectionWith (Range other) const noexcept + constexpr Range getIntersectionWith (Range other) const noexcept { return Range (jmax (start, other.start), jmin (end, other.end)); } /** Returns the smallest range that contains both this one and the other one. */ - JUCE_CONSTEXPR Range getUnionWith (Range other) const noexcept + constexpr Range getUnionWith (Range other) const noexcept { return Range (jmin (start, other.start), jmax (end, other.end)); } /** Returns the smallest range that contains both this one and the given value. */ - JUCE_CONSTEXPR Range getUnionWith (const ValueType valueToInclude) const noexcept + constexpr Range getUnionWith (const ValueType valueToInclude) const noexcept { return Range (jmin (valueToInclude, start), jmax (valueToInclude, end)); diff --git a/modules/juce_core/maths/juce_StatisticsAccumulator.h b/modules/juce_core/maths/juce_StatisticsAccumulator.h index 4c62b138..99463fe8 100644 --- a/modules/juce_core/maths/juce_StatisticsAccumulator.h +++ b/modules/juce_core/maths/juce_StatisticsAccumulator.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/memory/juce_AllocationHooks.cpp b/modules/juce_core/memory/juce_AllocationHooks.cpp new file mode 100644 index 00000000..3c6cb6b3 --- /dev/null +++ b/modules/juce_core/memory/juce_AllocationHooks.cpp @@ -0,0 +1,104 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + To use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +#if JUCE_ENABLE_ALLOCATION_HOOKS + +namespace juce +{ + +static AllocationHooks& getAllocationHooksForThread() +{ + thread_local AllocationHooks hooks; + return hooks; +} + +void notifyAllocationHooksForThread() +{ + getAllocationHooksForThread().listenerList.call ([] (AllocationHooks::Listener& l) + { + l.newOrDeleteCalled(); + }); +} + +} + +void* operator new (size_t s) +{ + juce::notifyAllocationHooksForThread(); + return std::malloc (s); +} + +void* operator new[] (size_t s) +{ + juce::notifyAllocationHooksForThread(); + return std::malloc (s); +} + +void operator delete (void* p) noexcept +{ + juce::notifyAllocationHooksForThread(); + std::free (p); +} + +void operator delete[] (void* p) noexcept +{ + juce::notifyAllocationHooksForThread(); + std::free (p); +} + +#if JUCE_CXX14_IS_AVAILABLE + +void operator delete (void* p, size_t) noexcept +{ + juce::notifyAllocationHooksForThread(); + std::free (p); +} + +void operator delete[] (void* p, size_t) noexcept +{ + juce::notifyAllocationHooksForThread(); + std::free (p); +} + +#endif + +namespace juce +{ + +//============================================================================== +UnitTestAllocationChecker::UnitTestAllocationChecker (UnitTest& test) + : unitTest (test) +{ + getAllocationHooksForThread().addListener (this); +} + +UnitTestAllocationChecker::~UnitTestAllocationChecker() noexcept +{ + getAllocationHooksForThread().removeListener (this); + unitTest.expectEquals (calls, (size_t) 0, "new or delete was incorrectly called while allocation checker was active"); +} + +void UnitTestAllocationChecker::newOrDeleteCalled() noexcept { ++calls; } + +} + +#endif diff --git a/modules/juce_core/memory/juce_AllocationHooks.h b/modules/juce_core/memory/juce_AllocationHooks.h new file mode 100644 index 00000000..9dec58f0 --- /dev/null +++ b/modules/juce_core/memory/juce_AllocationHooks.h @@ -0,0 +1,73 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + To use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +#if JUCE_ENABLE_ALLOCATION_HOOKS + +namespace juce +{ + +class AllocationHooks +{ +public: + struct Listener + { + virtual ~Listener() noexcept = default; + virtual void newOrDeleteCalled() noexcept = 0; + }; + + void addListener (Listener* l) { listenerList.add (l); } + void removeListener (Listener* l) noexcept { listenerList.remove (l); } + +private: + friend void notifyAllocationHooksForThread(); + ListenerList<Listener> listenerList; +}; + +//============================================================================== +/** Scoped checker which will cause a unit test failure if any new/delete calls + are made during the lifetime of the UnitTestAllocationChecker. +*/ +class UnitTestAllocationChecker : private AllocationHooks::Listener +{ +public: + /** Create a checker which will log a failure to the passed test if + any calls to new/delete are made. + + Remember to call `UnitTest::beginTest` before constructing this checker! + */ + explicit UnitTestAllocationChecker (UnitTest& test); + + /** Will add a failure to the test if the number of new/delete calls during + this object's lifetime was greater than zero. + */ + ~UnitTestAllocationChecker() noexcept override; + +private: + void newOrDeleteCalled() noexcept override; + + UnitTest& unitTest; + size_t calls = 0; +}; + +} + +#endif diff --git a/modules/juce_core/memory/juce_Atomic.h b/modules/juce_core/memory/juce_Atomic.h index a6682dc0..9ef5c402 100644 --- a/modules/juce_core/memory/juce_Atomic.h +++ b/modules/juce_core/memory/juce_Atomic.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/memory/juce_ByteOrder.h b/modules/juce_core/memory/juce_ByteOrder.h index 95e28482..84ecad96 100644 --- a/modules/juce_core/memory/juce_ByteOrder.h +++ b/modules/juce_core/memory/juce_ByteOrder.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -20,6 +20,10 @@ ============================================================================== */ +#if ! DOXYGEN && (JUCE_MAC || JUCE_IOS) + #include <libkern/OSByteOrder.h> +#endif + namespace juce { @@ -34,10 +38,10 @@ class JUCE_API ByteOrder public: //============================================================================== /** Swaps the upper and lower bytes of a 16-bit integer. */ - JUCE_CONSTEXPR static uint16 swap (uint16 value) noexcept; + constexpr static uint16 swap (uint16 value) noexcept; /** Swaps the upper and lower bytes of a 16-bit integer. */ - JUCE_CONSTEXPR static int16 swap (int16 value) noexcept; + constexpr static int16 swap (int16 value) noexcept; /** Reverses the order of the 4 bytes in a 32-bit integer. */ static uint32 swap (uint32 value) noexcept; @@ -82,50 +86,50 @@ public: //============================================================================== /** Turns 4 bytes into a little-endian integer. */ - JUCE_CONSTEXPR static uint32 littleEndianInt (const void* bytes) noexcept; + constexpr static uint32 littleEndianInt (const void* bytes) noexcept; /** Turns 8 bytes into a little-endian integer. */ - JUCE_CONSTEXPR static uint64 littleEndianInt64 (const void* bytes) noexcept; + constexpr static uint64 littleEndianInt64 (const void* bytes) noexcept; /** Turns 2 bytes into a little-endian integer. */ - JUCE_CONSTEXPR static uint16 littleEndianShort (const void* bytes) noexcept; + constexpr static uint16 littleEndianShort (const void* bytes) noexcept; /** Converts 3 little-endian bytes into a signed 24-bit value (which is sign-extended to 32 bits). */ - JUCE_CONSTEXPR static int littleEndian24Bit (const void* bytes) noexcept; + constexpr static int littleEndian24Bit (const void* bytes) noexcept; /** Copies a 24-bit number to 3 little-endian bytes. */ static void littleEndian24BitToChars (int32 value, void* destBytes) noexcept; //============================================================================== /** Turns 4 bytes into a big-endian integer. */ - JUCE_CONSTEXPR static uint32 bigEndianInt (const void* bytes) noexcept; + constexpr static uint32 bigEndianInt (const void* bytes) noexcept; /** Turns 8 bytes into a big-endian integer. */ - JUCE_CONSTEXPR static uint64 bigEndianInt64 (const void* bytes) noexcept; + constexpr static uint64 bigEndianInt64 (const void* bytes) noexcept; /** Turns 2 bytes into a big-endian integer. */ - JUCE_CONSTEXPR static uint16 bigEndianShort (const void* bytes) noexcept; + constexpr static uint16 bigEndianShort (const void* bytes) noexcept; /** Converts 3 big-endian bytes into a signed 24-bit value (which is sign-extended to 32 bits). */ - JUCE_CONSTEXPR static int bigEndian24Bit (const void* bytes) noexcept; + constexpr static int bigEndian24Bit (const void* bytes) noexcept; /** Copies a 24-bit number to 3 big-endian bytes. */ static void bigEndian24BitToChars (int32 value, void* destBytes) noexcept; //============================================================================== /** Constructs a 16-bit integer from its constituent bytes, in order of significance. */ - JUCE_CONSTEXPR static uint16 makeInt (uint8 leastSig, uint8 mostSig) noexcept; + constexpr static uint16 makeInt (uint8 leastSig, uint8 mostSig) noexcept; /** Constructs a 32-bit integer from its constituent bytes, in order of significance. */ - JUCE_CONSTEXPR static uint32 makeInt (uint8 leastSig, uint8 byte1, uint8 byte2, uint8 mostSig) noexcept; + constexpr static uint32 makeInt (uint8 leastSig, uint8 byte1, uint8 byte2, uint8 mostSig) noexcept; /** Constructs a 64-bit integer from its constituent bytes, in order of significance. */ - JUCE_CONSTEXPR static uint64 makeInt (uint8 leastSig, uint8 byte1, uint8 byte2, uint8 byte3, - uint8 byte4, uint8 byte5, uint8 byte6, uint8 mostSig) noexcept; + constexpr static uint64 makeInt (uint8 leastSig, uint8 byte1, uint8 byte2, uint8 byte3, + uint8 byte4, uint8 byte5, uint8 byte6, uint8 mostSig) noexcept; //============================================================================== /** Returns true if the current CPU is big-endian. */ - JUCE_CONSTEXPR static bool isBigEndian() noexcept + constexpr static bool isBigEndian() noexcept { #if JUCE_LITTLE_ENDIAN return false; @@ -140,8 +144,8 @@ private: //============================================================================== -JUCE_CONSTEXPR inline uint16 ByteOrder::swap (uint16 v) noexcept { return static_cast<uint16> ((v << 8) | (v >> 8)); } -JUCE_CONSTEXPR inline int16 ByteOrder::swap (int16 v) noexcept { return static_cast<int16> (swap (static_cast<uint16> (v))); } +constexpr inline uint16 ByteOrder::swap (uint16 v) noexcept { return static_cast<uint16> ((v << 8) | (v >> 8)); } +constexpr inline int16 ByteOrder::swap (int16 v) noexcept { return static_cast<int16> (swap (static_cast<uint16> (v))); } inline int32 ByteOrder::swap (int32 v) noexcept { return static_cast<int32> (swap (static_cast<uint32> (v))); } inline int64 ByteOrder::swap (int64 v) noexcept { return static_cast<int64> (swap (static_cast<uint64> (v))); } inline float ByteOrder::swap (float v) noexcept { union { uint32 asUInt; float asFloat; } n; n.asFloat = v; n.asUInt = swap (n.asUInt); return n.asFloat; } @@ -178,41 +182,41 @@ inline uint64 ByteOrder::swap (uint64 value) noexcept #endif } -JUCE_CONSTEXPR inline uint16 ByteOrder::makeInt (uint8 b0, uint8 b1) noexcept +constexpr inline uint16 ByteOrder::makeInt (uint8 b0, uint8 b1) noexcept { return static_cast<uint16> (static_cast<uint16> (b0) | (static_cast<uint16> (b1) << 8)); } -JUCE_CONSTEXPR inline uint32 ByteOrder::makeInt (uint8 b0, uint8 b1, uint8 b2, uint8 b3) noexcept +constexpr inline uint32 ByteOrder::makeInt (uint8 b0, uint8 b1, uint8 b2, uint8 b3) noexcept { return static_cast<uint32> (b0) | (static_cast<uint32> (b1) << 8) | (static_cast<uint32> (b2) << 16) | (static_cast<uint32> (b3) << 24); } -JUCE_CONSTEXPR inline uint64 ByteOrder::makeInt (uint8 b0, uint8 b1, uint8 b2, uint8 b3, uint8 b4, uint8 b5, uint8 b6, uint8 b7) noexcept +constexpr inline uint64 ByteOrder::makeInt (uint8 b0, uint8 b1, uint8 b2, uint8 b3, uint8 b4, uint8 b5, uint8 b6, uint8 b7) noexcept { return static_cast<uint64> (b0) | (static_cast<uint64> (b1) << 8) | (static_cast<uint64> (b2) << 16) | (static_cast<uint64> (b3) << 24) | (static_cast<uint64> (b4) << 32) | (static_cast<uint64> (b5) << 40) | (static_cast<uint64> (b6) << 48) | (static_cast<uint64> (b7) << 56); } -JUCE_CONSTEXPR inline uint16 ByteOrder::littleEndianShort (const void* bytes) noexcept { return makeInt (static_cast<const uint8*> (bytes)[0], static_cast<const uint8*> (bytes)[1]); } -JUCE_CONSTEXPR inline uint32 ByteOrder::littleEndianInt (const void* bytes) noexcept { return makeInt (static_cast<const uint8*> (bytes)[0], static_cast<const uint8*> (bytes)[1], +constexpr inline uint16 ByteOrder::littleEndianShort (const void* bytes) noexcept { return makeInt (static_cast<const uint8*> (bytes)[0], static_cast<const uint8*> (bytes)[1]); } +constexpr inline uint32 ByteOrder::littleEndianInt (const void* bytes) noexcept { return makeInt (static_cast<const uint8*> (bytes)[0], static_cast<const uint8*> (bytes)[1], static_cast<const uint8*> (bytes)[2], static_cast<const uint8*> (bytes)[3]); } -JUCE_CONSTEXPR inline uint64 ByteOrder::littleEndianInt64 (const void* bytes) noexcept { return makeInt (static_cast<const uint8*> (bytes)[0], static_cast<const uint8*> (bytes)[1], +constexpr inline uint64 ByteOrder::littleEndianInt64 (const void* bytes) noexcept { return makeInt (static_cast<const uint8*> (bytes)[0], static_cast<const uint8*> (bytes)[1], static_cast<const uint8*> (bytes)[2], static_cast<const uint8*> (bytes)[3], static_cast<const uint8*> (bytes)[4], static_cast<const uint8*> (bytes)[5], static_cast<const uint8*> (bytes)[6], static_cast<const uint8*> (bytes)[7]); } -JUCE_CONSTEXPR inline uint16 ByteOrder::bigEndianShort (const void* bytes) noexcept { return makeInt (static_cast<const uint8*> (bytes)[1], static_cast<const uint8*> (bytes)[0]); } -JUCE_CONSTEXPR inline uint32 ByteOrder::bigEndianInt (const void* bytes) noexcept { return makeInt (static_cast<const uint8*> (bytes)[3], static_cast<const uint8*> (bytes)[2], +constexpr inline uint16 ByteOrder::bigEndianShort (const void* bytes) noexcept { return makeInt (static_cast<const uint8*> (bytes)[1], static_cast<const uint8*> (bytes)[0]); } +constexpr inline uint32 ByteOrder::bigEndianInt (const void* bytes) noexcept { return makeInt (static_cast<const uint8*> (bytes)[3], static_cast<const uint8*> (bytes)[2], static_cast<const uint8*> (bytes)[1], static_cast<const uint8*> (bytes)[0]); } -JUCE_CONSTEXPR inline uint64 ByteOrder::bigEndianInt64 (const void* bytes) noexcept { return makeInt (static_cast<const uint8*> (bytes)[7], static_cast<const uint8*> (bytes)[6], +constexpr inline uint64 ByteOrder::bigEndianInt64 (const void* bytes) noexcept { return makeInt (static_cast<const uint8*> (bytes)[7], static_cast<const uint8*> (bytes)[6], static_cast<const uint8*> (bytes)[5], static_cast<const uint8*> (bytes)[4], static_cast<const uint8*> (bytes)[3], static_cast<const uint8*> (bytes)[2], static_cast<const uint8*> (bytes)[1], static_cast<const uint8*> (bytes)[0]); } -JUCE_CONSTEXPR inline int32 ByteOrder::littleEndian24Bit (const void* bytes) noexcept { return (int32) ((((uint32) static_cast<const int8*> (bytes)[2]) << 16) | (((uint32) static_cast<const uint8*> (bytes)[1]) << 8) | ((uint32) static_cast<const uint8*> (bytes)[0])); } -JUCE_CONSTEXPR inline int32 ByteOrder::bigEndian24Bit (const void* bytes) noexcept { return (int32) ((((uint32) static_cast<const int8*> (bytes)[0]) << 16) | (((uint32) static_cast<const uint8*> (bytes)[1]) << 8) | ((uint32) static_cast<const uint8*> (bytes)[2])); } +constexpr inline int32 ByteOrder::littleEndian24Bit (const void* bytes) noexcept { return (int32) ((((uint32) static_cast<const int8*> (bytes)[2]) << 16) | (((uint32) static_cast<const uint8*> (bytes)[1]) << 8) | ((uint32) static_cast<const uint8*> (bytes)[0])); } +constexpr inline int32 ByteOrder::bigEndian24Bit (const void* bytes) noexcept { return (int32) ((((uint32) static_cast<const int8*> (bytes)[0]) << 16) | (((uint32) static_cast<const uint8*> (bytes)[1]) << 8) | ((uint32) static_cast<const uint8*> (bytes)[2])); } inline void ByteOrder::littleEndian24BitToChars (int32 value, void* destBytes) noexcept { static_cast<uint8*> (destBytes)[0] = (uint8) value; static_cast<uint8*> (destBytes)[1] = (uint8) (value >> 8); static_cast<uint8*> (destBytes)[2] = (uint8) (value >> 16); } inline void ByteOrder::bigEndian24BitToChars (int32 value, void* destBytes) noexcept { static_cast<uint8*> (destBytes)[0] = (uint8) (value >> 16); static_cast<uint8*> (destBytes)[1] = (uint8) (value >> 8); static_cast<uint8*> (destBytes)[2] = (uint8) value; } diff --git a/modules/juce_core/memory/juce_ContainerDeletePolicy.h b/modules/juce_core/memory/juce_ContainerDeletePolicy.h index 212b7cca..ab945842 100644 --- a/modules/juce_core/memory/juce_ContainerDeletePolicy.h +++ b/modules/juce_core/memory/juce_ContainerDeletePolicy.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/memory/juce_HeapBlock.h b/modules/juce_core/memory/juce_HeapBlock.h index e86f92a2..e935a521 100644 --- a/modules/juce_core/memory/juce_HeapBlock.h +++ b/modules/juce_core/memory/juce_HeapBlock.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/memory/juce_HeavyweightLeakedObjectDetector.h b/modules/juce_core/memory/juce_HeavyweightLeakedObjectDetector.h index 53ff48ff..06140abd 100644 --- a/modules/juce_core/memory/juce_HeavyweightLeakedObjectDetector.h +++ b/modules/juce_core/memory/juce_HeavyweightLeakedObjectDetector.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/memory/juce_LeakedObjectDetector.h b/modules/juce_core/memory/juce_LeakedObjectDetector.h index 5aa7e546..f14c7008 100644 --- a/modules/juce_core/memory/juce_LeakedObjectDetector.h +++ b/modules/juce_core/memory/juce_LeakedObjectDetector.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -46,6 +46,8 @@ public: LeakedObjectDetector() noexcept { ++(getCounter().numObjects); } LeakedObjectDetector (const LeakedObjectDetector&) noexcept { ++(getCounter().numObjects); } + LeakedObjectDetector& operator= (const LeakedObjectDetector&) noexcept = default; + ~LeakedObjectDetector() { if (--(getCounter().numObjects) < 0) diff --git a/modules/juce_core/memory/juce_Memory.h b/modules/juce_core/memory/juce_Memory.h index 6587d368..03c0de3c 100644 --- a/modules/juce_core/memory/juce_Memory.h +++ b/modules/juce_core/memory/juce_Memory.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -39,13 +39,6 @@ inline void zerostruct (Type& structure) noexcept { memset ((v template <typename Type> inline void deleteAndZero (Type& pointer) { delete pointer; pointer = nullptr; } -/** A handy function which adds a number of bytes to any type of pointer and returns the result. - This can be useful to avoid casting pointers to a char* and back when you want to move them by - a specific number of bytes, -*/ -template <typename Type, typename IntegerType> -inline Type* addBytesToPointer (Type* basePointer, IntegerType bytes) noexcept { return reinterpret_cast<Type*> (const_cast<char*> (reinterpret_cast<const char*> (basePointer)) + bytes); } - /** A handy function to round up a pointer to the nearest multiple of a given number of bytes. alignmentBytes must be a power of two. */ template <typename Type, typename IntegerType> @@ -83,6 +76,53 @@ inline void writeUnaligned (void* dstPtr, Type value) noexcept memcpy (dstPtr, &value, sizeof (Type)); } +//============================================================================== +/** Casts a pointer to another type via `void*`, which suppresses the cast-align + warning which sometimes arises when casting pointers to types with different + alignment. + You should only use this when you know for a fact that the input pointer points + to a region that has suitable alignment for `Type`, e.g. regions returned from + malloc/calloc that should be suitable for any non-over-aligned type. +*/ +template <typename Type, typename std::enable_if<std::is_pointer<Type>::value, int>::type = 0> +inline Type unalignedPointerCast (void* ptr) noexcept +{ + return reinterpret_cast<Type> (ptr); +} + +/** Casts a pointer to another type via `void*`, which suppresses the cast-align + warning which sometimes arises when casting pointers to types with different + alignment. + You should only use this when you know for a fact that the input pointer points + to a region that has suitable alignment for `Type`, e.g. regions returned from + malloc/calloc that should be suitable for any non-over-aligned type. +*/ +template <typename Type, typename std::enable_if<std::is_pointer<Type>::value, int>::type = 0> +inline Type unalignedPointerCast (const void* ptr) noexcept +{ + return reinterpret_cast<Type> (ptr); +} + +/** A handy function which adds a number of bytes to any type of pointer and returns the result. + This can be useful to avoid casting pointers to a char* and back when you want to move them by + a specific number of bytes, +*/ +template <typename Type, typename IntegerType> +inline Type* addBytesToPointer (Type* basePointer, IntegerType bytes) noexcept +{ + return unalignedPointerCast<Type*> (reinterpret_cast<char*> (basePointer) + bytes); +} + +/** A handy function which adds a number of bytes to any type of pointer and returns the result. + This can be useful to avoid casting pointers to a char* and back when you want to move them by + a specific number of bytes, +*/ +template <typename Type, typename IntegerType> +inline const Type* addBytesToPointer (const Type* basePointer, IntegerType bytes) noexcept +{ + return unalignedPointerCast<const Type*> (reinterpret_cast<const char*> (basePointer) + bytes); +} + //============================================================================== #if JUCE_MAC || JUCE_IOS || DOXYGEN diff --git a/modules/juce_core/memory/juce_MemoryBlock.cpp b/modules/juce_core/memory/juce_MemoryBlock.cpp index 8a87e33d..e565bb14 100644 --- a/modules/juce_core/memory/juce_MemoryBlock.cpp +++ b/modules/juce_core/memory/juce_MemoryBlock.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -321,7 +321,7 @@ void MemoryBlock::loadFromHexString (StringRef hex) for (;;) { - int byte = 0; + juce_wchar byte = 0; for (int loop = 2; --loop >= 0;) { diff --git a/modules/juce_core/memory/juce_MemoryBlock.h b/modules/juce_core/memory/juce_MemoryBlock.h index ceb28513..c5beedee 100644 --- a/modules/juce_core/memory/juce_MemoryBlock.h +++ b/modules/juce_core/memory/juce_MemoryBlock.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/memory/juce_OptionalScopedPointer.h b/modules/juce_core/memory/juce_OptionalScopedPointer.h index 1c21885e..74ceb47c 100644 --- a/modules/juce_core/memory/juce_OptionalScopedPointer.h +++ b/modules/juce_core/memory/juce_OptionalScopedPointer.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -49,7 +49,8 @@ public: OptionalScopedPointer just holds a normal pointer to the object, and won't delete it. */ OptionalScopedPointer (ObjectType* objectToHold, bool takeOwnership) - : object (objectToHold), shouldDelete (takeOwnership) + : object (objectToHold), + shouldDelete (takeOwnership) { } @@ -61,9 +62,21 @@ public: The flag to indicate whether or not to delete the managed object is also copied from the source object. */ - OptionalScopedPointer (OptionalScopedPointer& objectToTransferFrom) - : object (objectToTransferFrom.release()), - shouldDelete (objectToTransferFrom.shouldDelete) + OptionalScopedPointer (OptionalScopedPointer&& other) noexcept + : object (std::move (other.object)), + shouldDelete (std::move (other.shouldDelete)) + { + } + + /** Takes ownership of the object owned by `ptr`. */ + explicit OptionalScopedPointer (std::unique_ptr<ObjectType>&& ptr) noexcept + : OptionalScopedPointer (ptr.release(), true) + { + } + + /** Points to the same object as `ref`, but does not take ownership. */ + explicit OptionalScopedPointer (ObjectType& ref) noexcept + : OptionalScopedPointer (std::addressof (ref), false) { } @@ -75,15 +88,10 @@ public: The ownership flag that says whether or not to delete the managed object is also copied from the source object. */ - OptionalScopedPointer& operator= (OptionalScopedPointer& objectToTransferFrom) + OptionalScopedPointer& operator= (OptionalScopedPointer&& other) noexcept { - if (object != objectToTransferFrom.object) - { - reset(); - object.reset (objectToTransferFrom.object.release()); - } - - shouldDelete = objectToTransferFrom.shouldDelete; + swapWith (other); + other.reset(); return *this; } @@ -91,23 +99,23 @@ public: takeOwnership flag that was specified when the object was first passed into an OptionalScopedPointer constructor. */ - ~OptionalScopedPointer() + ~OptionalScopedPointer() noexcept { reset(); } //============================================================================== /** Returns the object that this pointer is managing. */ - inline operator ObjectType*() const noexcept { return object.get(); } + operator ObjectType*() const noexcept { return object.get(); } /** Returns the object that this pointer is managing. */ - inline ObjectType* get() const noexcept { return object.get(); } + ObjectType* get() const noexcept { return object.get(); } /** Returns the object that this pointer is managing. */ - inline ObjectType& operator*() const noexcept { return *object; } + ObjectType& operator*() const noexcept { return *object; } /** Lets you access methods and properties of the object that this pointer is holding. */ - inline ObjectType* operator->() const noexcept { return object.get(); } + ObjectType* operator->() const noexcept { return object.get(); } //============================================================================== /** Removes the current object from this OptionalScopedPointer without deleting it. @@ -118,7 +126,7 @@ public: /** Resets this pointer to null, possibly deleting the object that it holds, if it has ownership of it. */ - void reset() + void reset() noexcept { if (! shouldDelete) object.release(); @@ -170,8 +178,8 @@ public: */ void swapWith (OptionalScopedPointer<ObjectType>& other) noexcept { - object.swapWith (other.object); - std::swap (shouldDelete, other.shouldDelete); + std::swap (other.object, object); + std::swap (other.shouldDelete, shouldDelete); } private: diff --git a/modules/juce_core/memory/juce_ReferenceCountedObject.h b/modules/juce_core/memory/juce_ReferenceCountedObject.h index 575687d8..b4b01e33 100644 --- a/modules/juce_core/memory/juce_ReferenceCountedObject.h +++ b/modules/juce_core/memory/juce_ReferenceCountedObject.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/memory/juce_ScopedPointer.h b/modules/juce_core/memory/juce_ScopedPointer.h index 1ca6ff8f..aa030863 100644 --- a/modules/juce_core/memory/juce_ScopedPointer.h +++ b/modules/juce_core/memory/juce_ScopedPointer.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/memory/juce_SharedResourcePointer.h b/modules/juce_core/memory/juce_SharedResourcePointer.h index 998fd68a..4f23168d 100644 --- a/modules/juce_core/memory/juce_SharedResourcePointer.h +++ b/modules/juce_core/memory/juce_SharedResourcePointer.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -116,12 +116,10 @@ public: /** Returns the shared object. */ SharedObjectType& get() const noexcept { return *sharedObject; } - /** Returns the object that this pointer references. - The pointer returned may be a nullptr, of course. - */ + /** Returns the object that this pointer references. */ SharedObjectType& getObject() const noexcept { return *sharedObject; } - /** Returns the shared object. */ + /** Returns the shared object pointer. */ SharedObjectType* operator->() const noexcept { return sharedObject; } /** Returns the number of SharedResourcePointers that are currently holding the shared object. */ diff --git a/modules/juce_core/memory/juce_Singleton.h b/modules/juce_core/memory/juce_Singleton.h index 4bea3e92..8419c37b 100644 --- a/modules/juce_core/memory/juce_Singleton.h +++ b/modules/juce_core/memory/juce_Singleton.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/memory/juce_WeakReference.h b/modules/juce_core/memory/juce_WeakReference.h index 85f4d21d..64fae8d8 100644 --- a/modules/juce_core/memory/juce_WeakReference.h +++ b/modules/juce_core/memory/juce_WeakReference.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -201,7 +201,7 @@ public: private: SharedRef holder; - static inline SharedRef getRef (ObjectType* o) + static SharedRef getRef (ObjectType* o) { if (o != nullptr) return o->masterReference.getSharedPointer (o); diff --git a/modules/juce_core/misc/juce_ConsoleApplication.cpp b/modules/juce_core/misc/juce_ConsoleApplication.cpp index da5548b4..389131a3 100644 --- a/modules/juce_core/misc/juce_ConsoleApplication.cpp +++ b/modules/juce_core/misc/juce_ConsoleApplication.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -23,12 +23,12 @@ namespace juce { -static inline File resolveFilename (const String& name) +static File resolveFilename (const String& name) { return File::getCurrentWorkingDirectory().getChildFile (name.unquoted()); } -static inline File checkFileExists (const File& f) +static File checkFileExists (const File& f) { if (! f.exists()) ConsoleApplication::fail ("Could not find file: " + f.getFullPathName()); @@ -36,7 +36,7 @@ static inline File checkFileExists (const File& f) return f; } -static inline File checkFolderExists (const File& f) +static File checkFolderExists (const File& f) { if (! f.isDirectory()) ConsoleApplication::fail ("Could not find folder: " + f.getFullPathName()); @@ -44,7 +44,7 @@ static inline File checkFolderExists (const File& f) return f; } -static inline File resolveFilenameForOption (const ArgumentList& args, StringRef option, const String& filename) +static File resolveFilenameForOption (const ArgumentList& args, StringRef option, const String& filename) { if (filename.isEmpty()) { @@ -75,9 +75,9 @@ File ArgumentList::Argument::resolveAsExistingFolder() const return f; } -static inline bool isShortOptionFormat (StringRef s) { return s[0] == '-' && s[1] != '-'; } -static inline bool isLongOptionFormat (StringRef s) { return s[0] == '-' && s[1] == '-' && s[2] != '-'; } -static inline bool isOptionFormat (StringRef s) { return s[0] == '-'; } +static bool isShortOptionFormat (StringRef s) { return s[0] == '-' && s[1] != '-'; } +static bool isLongOptionFormat (StringRef s) { return s[0] == '-' && s[1] == '-' && s[2] != '-'; } +static bool isOptionFormat (StringRef s) { return s[0] == '-'; } bool ArgumentList::Argument::isLongOption() const { return isLongOptionFormat (text); } bool ArgumentList::Argument::isShortOption() const { return isShortOptionFormat (text); } @@ -141,7 +141,7 @@ ArgumentList::ArgumentList (String exeName, StringArray args) args.removeEmptyStrings(); for (auto& a : args) - arguments.add ({ a }); + arguments.add ({ a.unquoted() }); } ArgumentList::ArgumentList (int argc, char* argv[]) @@ -168,7 +168,7 @@ int ArgumentList::indexOfOption (StringRef option) const jassert (option == String (option).trim()); // passing non-trimmed strings will always fail to find a match! for (int i = 0; i < arguments.size(); ++i) - if (arguments.getReference(i) == option) + if (arguments.getReference (i) == option) return i; return -1; diff --git a/modules/juce_core/misc/juce_ConsoleApplication.h b/modules/juce_core/misc/juce_ConsoleApplication.h index a6440177..ae7b1b26 100644 --- a/modules/juce_core/misc/juce_ConsoleApplication.h +++ b/modules/juce_core/misc/juce_ConsoleApplication.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -264,7 +264,7 @@ struct ConsoleApplication String longDescription; /** The actual command that should be invoked to perform this action. */ - std::function<void(const ArgumentList&)> command; + std::function<void (const ArgumentList&)> command; }; //============================================================================== diff --git a/modules/juce_core/misc/juce_Result.cpp b/modules/juce_core/misc/juce_Result.cpp index f7278730..f15b4aa3 100644 --- a/modules/juce_core/misc/juce_Result.cpp +++ b/modules/juce_core/misc/juce_Result.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/misc/juce_Result.h b/modules/juce_core/misc/juce_Result.h index 5836b4e0..52cbb542 100644 --- a/modules/juce_core/misc/juce_Result.h +++ b/modules/juce_core/misc/juce_Result.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/misc/juce_RuntimePermissions.cpp b/modules/juce_core/misc/juce_RuntimePermissions.cpp index bf7306b5..99b186dc 100644 --- a/modules/juce_core/misc/juce_RuntimePermissions.cpp +++ b/modules/juce_core/misc/juce_RuntimePermissions.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/misc/juce_RuntimePermissions.h b/modules/juce_core/misc/juce_RuntimePermissions.h index 7cd9794b..caf08032 100644 --- a/modules/juce_core/misc/juce_RuntimePermissions.h +++ b/modules/juce_core/misc/juce_RuntimePermissions.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -91,7 +91,7 @@ public: //============================================================================== /** Function type of runtime permission request callbacks. */ - using Callback = std::function<void(bool)>; + using Callback = std::function<void (bool)>; //============================================================================== /** Call this method to request a runtime permission. diff --git a/modules/juce_core/misc/juce_Uuid.cpp b/modules/juce_core/misc/juce_Uuid.cpp index 5bb56d23..5883039e 100644 --- a/modules/juce_core/misc/juce_Uuid.cpp +++ b/modules/juce_core/misc/juce_Uuid.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/misc/juce_Uuid.h b/modules/juce_core/misc/juce_Uuid.h index 660c96fa..cb36c84b 100644 --- a/modules/juce_core/misc/juce_Uuid.h +++ b/modules/juce_core/misc/juce_Uuid.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/misc/juce_WindowsRegistry.h b/modules/juce_core/misc/juce_WindowsRegistry.h index be61c200..c8d955ef 100644 --- a/modules/juce_core/misc/juce_WindowsRegistry.h +++ b/modules/juce_core/misc/juce_WindowsRegistry.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/native/java/README.txt b/modules/juce_core/native/java/README.txt index d7cf93cc..55662d15 100644 --- a/modules/juce_core/native/java/README.txt +++ b/modules/juce_core/native/java/README.txt @@ -9,30 +9,31 @@ required for the Java source code you wish to compile. 2. If you are creating byte-code for new .java files, move the new files into the native/javacore/app folder of the module, or create one if it doesn't exist. Remember that .java files need to be in nested sub-folders which -resemble their package, i.e. a Java class com.roli.juce.HelloWorld.java -should be in the module's native/javacore/app/com/roli/juce folder. -If you wish to modify existing .java files in the JUCE modules then just rename -native/java to native/javacore. +resemble their package, i.e. a Java class com.rmsl.juce.HelloWorld.java should +be in the module's native/javacore/app/com/rmsl/juce folder. If you wish to +modify existing .java files in the JUCE modules then just rename native/java to +native/javacore. -3. Build your project with AS and run. The app will now use the source code in -the folder created in step 2 so you can debug your Java code this way. +3. Build your project with Android Studio and run. The app will now use the +source code in the folder created in step 2 so you can debug your Java code +this way. 4. Once everything is working rebuild your app in release mode. 5. Go to your app's Builds/Android folder. Inside there you will find -build/intermediates/javac/release_Release/compileRelease_ReleaseJavaWithJavac/classes. +build/intermediates/javac/release_Release/compileRelease_ReleaseJavaWithJavac/classes. Inside of that folder, you will find all your Java byte-code compiled classes. Remove any classes that you are not interested in (typically you'll find -Java.class, JuceApp.class and JuceSharingContentProvider.class which you will -probably want to remove). +Java.class and JuceApp.class which you will probably want to remove). -6. Inside of build/intermediates/javac/release_Release/compileRelease_ReleaseJavaWithJavac/classes +6. Inside of +build/intermediates/javac/release_Release/compileRelease_ReleaseJavaWithJavac/classes execute the following dx command: <path-to-your-android-sdk>/build-tools/<latest-build-tool-version>/dx --dex --verbose --min-sdk-version=<your-min-sdk-of-your-classes> --output /tmp/JavaDexByteCode.dex . (Replace <your-min-sdk-of-your-classes> with the minimal sdk version you used in step 1.) - + 7. gzip the output: gzip /tmp/JavaDexByteCode.dex diff --git a/modules/juce_core/native/java/app/com/roli/juce/FragmentOverlay.java b/modules/juce_core/native/java/app/com/rmsl/juce/FragmentOverlay.java similarity index 62% rename from modules/juce_core/native/java/app/com/roli/juce/FragmentOverlay.java rename to modules/juce_core/native/java/app/com/rmsl/juce/FragmentOverlay.java index 4b4a4191..92091730 100644 --- a/modules/juce_core/native/java/app/com/roli/juce/FragmentOverlay.java +++ b/modules/juce_core/native/java/app/com/rmsl/juce/FragmentOverlay.java @@ -1,4 +1,26 @@ -package com.roli.juce; +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + To use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +package com.rmsl.juce; import android.app.DialogFragment; import android.content.Intent; diff --git a/modules/juce_core/native/java/app/com/roli/juce/JuceHTTPStream.java b/modules/juce_core/native/java/app/com/rmsl/juce/JuceHTTPStream.java similarity index 90% rename from modules/juce_core/native/java/app/com/roli/juce/JuceHTTPStream.java rename to modules/juce_core/native/java/app/com/rmsl/juce/JuceHTTPStream.java index 887a66c2..261c779f 100644 --- a/modules/juce_core/native/java/app/com/roli/juce/JuceHTTPStream.java +++ b/modules/juce_core/native/java/app/com/rmsl/juce/JuceHTTPStream.java @@ -1,4 +1,26 @@ -package com.roli.juce; +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + To use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +package com.rmsl.juce; import java.lang.Runnable; import java.io.*; diff --git a/modules/juce_core/native/java/app/com/rmsl/juce/JuceInvocationHandler.java b/modules/juce_core/native/java/app/com/rmsl/juce/JuceInvocationHandler.java new file mode 100644 index 00000000..2fdb26db --- /dev/null +++ b/modules/juce_core/native/java/app/com/rmsl/juce/JuceInvocationHandler.java @@ -0,0 +1,60 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + To use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +package com.rmsl.juce; + +import java.lang.reflect.*; + +public class JuceInvocationHandler implements InvocationHandler +{ + public JuceInvocationHandler (long nativeContextRef) + { + nativeContext = nativeContextRef; + } + + public void clear() + { + nativeContext = 0; + } + + @Override + public void finalize() + { + if (nativeContext != 0) + dispatchFinalize (nativeContext); + } + + @Override + public Object invoke (Object proxy, Method method, Object[] args) throws Throwable + { + if (nativeContext != 0) + return dispatchInvoke (nativeContext, proxy, method, args); + + return null; + } + + //============================================================================== + private long nativeContext = 0; + + private native void dispatchFinalize (long nativeContextRef); + private native Object dispatchInvoke (long nativeContextRef, Object proxy, Method method, Object[] args); +} diff --git a/modules/juce_core/native/javacore/app/com/rmsl/juce/JuceApp.java b/modules/juce_core/native/javacore/app/com/rmsl/juce/JuceApp.java new file mode 100644 index 00000000..c48e27e9 --- /dev/null +++ b/modules/juce_core/native/javacore/app/com/rmsl/juce/JuceApp.java @@ -0,0 +1,37 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + To use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +package com.rmsl.juce; + +import com.rmsl.juce.Java; + +import android.app.Application; + +public class JuceApp extends Application +{ + @Override + public void onCreate() + { + super.onCreate(); + Java.initialiseJUCE (this); + } +} diff --git a/modules/juce_core/native/javacore/app/com/roli/juce/JuceApp.java b/modules/juce_core/native/javacore/app/com/roli/juce/JuceApp.java deleted file mode 100644 index bad37378..00000000 --- a/modules/juce_core/native/javacore/app/com/roli/juce/JuceApp.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.roli.juce; - -import com.roli.juce.Java; - -import android.app.Application; - -public class JuceApp extends Application -{ - @Override - public void onCreate () - { - super.onCreate (); - Java.initialiseJUCE (this); - } -} diff --git a/modules/juce_core/native/javacore/init/com/rmsl/juce/Java.java b/modules/juce_core/native/javacore/init/com/rmsl/juce/Java.java new file mode 100644 index 00000000..896d6bd9 --- /dev/null +++ b/modules/juce_core/native/javacore/init/com/rmsl/juce/Java.java @@ -0,0 +1,35 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + To use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +package com.rmsl.juce; + +import android.content.Context; + +public class Java +{ + static + { + System.loadLibrary ("juce_jni"); + } + + public native static void initialiseJUCE (Context appContext); +} diff --git a/modules/juce_core/native/javacore/init/com/roli/juce/Java.java b/modules/juce_core/native/javacore/init/com/roli/juce/Java.java deleted file mode 100644 index 3e3ccee0..00000000 --- a/modules/juce_core/native/javacore/init/com/roli/juce/Java.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.roli.juce; - -import android.content.Context; - -public class Java -{ - static - { - System.loadLibrary ("juce_jni"); - } - - public native static void initialiseJUCE (Context appContext); -} diff --git a/modules/juce_core/native/juce_BasicNativeHeaders.h b/modules/juce_core/native/juce_BasicNativeHeaders.h index 9ec827f2..306bb536 100644 --- a/modules/juce_core/native/juce_BasicNativeHeaders.h +++ b/modules/juce_core/native/juce_BasicNativeHeaders.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -82,6 +82,12 @@ #define NSAlertStyleInformational NSInformationalAlertStyle #define NSEventTypeTabletPoint NSTabletPoint #define NSEventTypeTabletProximity NSTabletProximity + #define NSEventTypeFlagsChanged NSFlagsChanged + #define NSEventTypeAppKitDefined NSAppKitDefined + #define NSEventTypeSystemDefined NSSystemDefined + #define NSEventTypeApplicationDefined NSApplicationDefined + #define NSEventTypePeriodic NSPeriodic + #define NSEventTypeSmartMagnify NSEventTypeSmartMagnify #endif #import <CoreAudio/HostTime.h> #include <sys/dir.h> @@ -126,7 +132,7 @@ #define STRICT 1 #define WIN32_LEAN_AND_MEAN 1 #if JUCE_MINGW - #define _WIN32_WINNT 0x0501 + #define _WIN32_WINNT 0x0600 #else #define _WIN32_WINNT 0x0602 #endif diff --git a/modules/juce_core/native/juce_android_Files.cpp b/modules/juce_core/native/juce_android_Files.cpp index 4163c59a..ef99443f 100644 --- a/modules/juce_core/native/juce_android_Files.cpp +++ b/modules/juce_core/native/juce_android_Files.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -319,9 +319,8 @@ private: return {}; auto rootFsDevice = info.st_dev; - DirectoryIterator iter (mountFolder, false, "*", File::findDirectories); - while (iter.next()) + for (const auto& iter : RangedDirectoryIterator (mountFolder, false, "*", File::findDirectories)) { auto candidate = iter.getFile(); diff --git a/modules/juce_core/native/juce_android_JNIHelpers.cpp b/modules/juce_core/native/juce_android_JNIHelpers.cpp index d9eb2633..53734691 100644 --- a/modules/juce_core/native/juce_android_JNIHelpers.cpp +++ b/modules/juce_core/native/juce_android_JNIHelpers.cpp @@ -1,51 +1,52 @@ /* - ============================================================================== + ============================================================================== - This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited - JUCE is an open source library subject to commercial or open-source - licensing. + 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. + 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. + 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 { //============================================================================== -static const uint8 invocationHandleByteCode[] = { -31,139,8,8,170,94,229,91,0,3,105,110,118,111,99,97,116,105,111,110,95,104,97,110,100,108,101,114,46,100,101,120,0,109, -148,75,107,19,81,20,199,207,189,119,38,169,181,109,98,218,138,72,23,81,20,68,193,169,218,130,144,42,130,162,53,140,15, -104,200,66,187,232,52,185,181,147,78,103,98,58,141,33,184,168,197,47,224,66,168,187,186,241,83,168,184,16,247,162,31,193, -69,151,174,220,40,234,255,62,154,4,237,192,239,62,206,57,115,30,115,239,153,186,236,12,79,95,154,165,159,187,91,95,227, -217,197,247,87,42,31,231,191,156,157,58,241,253,199,220,201,79,75,175,118,58,14,81,147,136,58,213,153,2,217,231,131,32, -154,32,35,63,164,246,0,102,244,13,48,48,129,33,139,121,138,153,125,5,131,131,119,82,204,203,156,168,1,214,65,10,186,224, -53,120,7,62,131,61,144,131,237,57,112,30,92,4,183,192,93,176,4,154,160,11,182,193,11,97,252,171,216,46,200,144,137,59, -100,243,26,6,35,0,46,9,166,116,131,155,89,113,159,27,125,214,214,116,216,174,23,185,241,89,208,181,8,173,99,240,48,106, -247,99,182,198,156,149,231,245,204,232,136,246,203,173,189,65,189,61,7,209,31,60,167,48,239,26,119,90,183,35,84,190,66, -175,201,230,218,204,43,201,81,172,30,76,131,25,66,180,190,133,169,81,107,139,164,243,112,123,25,154,253,194,53,232,17, -231,2,74,190,140,106,212,190,57,205,201,97,99,168,207,209,223,71,61,147,202,182,57,104,59,74,11,45,212,255,56,251,60,251, -50,251,166,157,81,81,71,80,83,129,206,252,238,133,239,101,162,242,72,237,217,186,246,251,171,106,51,248,242,162,183,218, -183,207,204,133,113,152,94,37,86,38,215,47,251,190,79,142,175,198,211,126,45,89,247,90,73,20,122,141,205,154,244,202,24, -110,199,237,164,22,164,97,18,207,7,113,61,146,173,18,29,247,235,65,212,14,215,188,32,142,147,84,235,188,202,106,43,121, -178,81,162,130,223,8,218,129,23,5,241,35,239,222,114,67,214,210,18,77,14,200,180,93,176,28,201,18,162,245,197,45,185,18, -193,214,59,48,218,255,102,119,100,186,154,212,75,196,170,196,171,101,26,127,120,64,84,183,22,201,160,69,249,122,184,209, -12,210,218,234,205,48,14,162,176,43,105,108,95,162,130,173,73,26,90,217,215,100,66,35,25,141,145,66,91,94,79,226,84,118, -82,114,219,65,180,41,137,115,54,62,197,142,57,196,132,186,86,207,182,156,95,156,111,115,98,10,182,43,4,123,43,24,219,19, -185,127,206,70,247,159,237,77,62,208,159,98,160,71,157,129,62,117,169,223,171,25,234,247,171,200,155,181,62,231,162,121, -231,169,178,41,26,185,186,207,44,111,228,234,142,243,162,137,171,250,219,41,246,239,56,217,181,190,251,214,167,250,127, -252,5,76,239,47,69,120,4,0,0}; +static const uint8 invocationHandleByteCode[] = +{31,139,8,8,215,115,161,94,0,3,105,110,118,111,99,97,116,105,111,110,72,97,110,100,108,101,66,121,116,101,67,111,100,101,46, +100,101,120,0,109,148,65,107,19,65,20,199,223,236,78,146,90,211,116,77,141,214,88,33,151,130,7,117,91,172,80,73,17,161,32,53,93, +17,108,233,65,5,217,38,155,102,219,237,110,220,108,99,172,8,173,40,42,244,36,245,226,65,232,165,138,7,15,226,65,193,147,120,244, +166,130,95,192,155,23,189,21,68,252,207,206,180,137,218,133,223,204,155,247,222,206,123,111,119,230,85,156,86,247,208,201, +83,84,121,127,155,63,122,245,209,24,205,141,63,156,124,186,176,229,110,12,151,158,157,126,219,76,39,136,234,68,212,154,25,201, +146,122,38,56,81,158,164,126,15,248,10,160,162,95,128,129,99,24,82,152,71,152,92,123,24,86,116,162,53,204,203,26,209,29,112, +15,108,128,231,224,37,248,2,126,128,4,252,6,192,56,184,6,102,65,21,220,2,171,224,1,120,2,94,128,215,224,29,248,0,62,129,111,224, +59,248,169,203,184,72,157,146,36,115,233,82,185,118,131,189,160,7,232,138,171,154,204,95,200,53,77,218,83,170,214,180,146, +35,77,238,153,139,107,212,99,27,35,141,122,213,218,80,181,239,83,250,108,60,51,234,139,247,213,148,191,68,188,61,13,149,208,142, +97,24,228,180,99,63,194,69,206,122,44,111,233,50,223,186,33,52,7,32,93,30,2,35,68,25,229,1,95,46,235,140,173,5,97,17,107,153, +97,154,203,245,212,89,216,17,103,24,33,71,81,141,88,215,135,52,226,44,131,90,121,252,141,250,184,172,109,170,222,233,219,67,83, +33,234,191,158,186,155,122,156,218,108,38,69,212,52,106,204,210,209,223,180,243,48,53,139,60,214,88,251,219,203,178,116,236, +223,165,190,117,50,254,15,42,243,49,215,119,163,51,196,74,148,47,45,149,157,243,126,51,40,219,145,27,248,19,182,95,241,156,240, +196,188,221,180,41,97,149,44,203,34,110,137,113,208,42,7,139,102,184,216,240,204,121,188,98,238,250,94,145,242,86,197,246,154, +238,130,105,251,126,16,197,54,115,186,22,6,55,26,69,202,90,98,91,211,179,253,57,243,226,236,188,83,142,138,148,235,208,197,126, +246,172,231,20,17,173,173,14,157,170,7,95,115,215,104,255,187,93,112,162,90,80,41,18,155,33,109,166,68,125,87,118,137,202,237, +112,174,65,137,178,231,216,33,25,21,183,81,183,163,114,237,156,235,219,158,187,236,80,102,91,35,66,46,56,212,85,221,182,36,93, +169,73,46,198,81,168,199,71,66,77,103,60,240,35,167,21,145,241,215,242,146,83,165,68,61,12,90,55,137,71,53,23,1,155,182,183, +132,237,216,193,84,70,203,23,181,185,210,113,156,146,84,102,146,246,99,188,127,153,14,235,253,185,94,72,155,164,105,236,208,0, +235,231,196,116,113,134,87,87,248,186,174,225,246,50,1,123,163,235,236,179,206,216,138,248,207,198,63,103,65,204,219,61,66,235, +232,19,122,71,175,224,29,253,34,65,237,158,145,164,118,223,208,13,41,199,231,170,32,223,89,23,62,5,169,23,247,135,25,82,31,223, +169,130,140,43,250,140,174,252,197,61,226,133,246,253,34,37,15,170,196,133,44,122,218,31,165,24,139,249,12,5,0,0,0,0}; //============================================================================== #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ @@ -61,26 +62,26 @@ static const uint8 invocationHandleByteCode[] = { CALLBACK (juce_invokeImplementer, "dispatchInvoke", "(JLjava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;") \ CALLBACK (juce_dispatchDelete, "dispatchFinalize", "(J)V") - DECLARE_JNI_CLASS_WITH_BYTECODE (JuceInvocationHandler, "com/roli/juce/JuceInvocationHandler", 10, invocationHandleByteCode, sizeof (invocationHandleByteCode)) + DECLARE_JNI_CLASS_WITH_BYTECODE (JuceInvocationHandler, "com/rmsl/juce/JuceInvocationHandler", 10, invocationHandleByteCode, sizeof (invocationHandleByteCode)) #undef JNI_CLASS_MEMBERS #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ METHOD (findClass, "findClass", "(Ljava/lang/String;)Ljava/lang/Class;") \ STATICMETHOD (getSystemClassLoader, "getSystemClassLoader", "()Ljava/lang/ClassLoader;") -DECLARE_JNI_CLASS (JavaClassLoader, "java/lang/ClassLoader") + DECLARE_JNI_CLASS (JavaClassLoader, "java/lang/ClassLoader") #undef JNI_CLASS_MEMBERS #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ METHOD (constructor, "<init>", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;)V") -DECLARE_JNI_CLASS (AndroidDexClassLoader, "dalvik/system/DexClassLoader") + DECLARE_JNI_CLASS (AndroidDexClassLoader, "dalvik/system/DexClassLoader") #undef JNI_CLASS_MEMBERS #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ METHOD (constructor, "<init>", "(Ljava/nio/ByteBuffer;Ljava/lang/ClassLoader;)V") -DECLARE_JNI_CLASS_WITH_MIN_SDK (AndroidInMemoryDexClassLoader, "dalvik/system/InMemoryDexClassLoader", 26) + DECLARE_JNI_CLASS_WITH_MIN_SDK (AndroidInMemoryDexClassLoader, "dalvik/system/InMemoryDexClassLoader", 26) #undef JNI_CLASS_MEMBERS //============================================================================== @@ -490,39 +491,38 @@ bool isPermissionDeclaredInManifest (const String& requestedPermission) } //============================================================================== -// This byte-code is generated from native/java/com/roli/juce/FragmentOverlay.java with min sdk version 16 +// This byte-code is generated from native/java/com/rmsl/juce/FragmentOverlay.java with min sdk version 16 // See juce_core/native/java/README.txt on how to generate this byte-code. static const uint8 javaFragmentOverlay[] = -{31,139,8,8,197,105,229,91,0,3,70,114,97,103,109,101,110,116,79,118,101,114,108,97,121,46,100,101,120,0,133,149,93,136, -28,69,16,199,171,231,243,62,39,235,93,60,206,243,244,214,136,73,4,201,156,104,32,186,107,184,36,34,236,58,248,145,11,251, -112,241,101,216,29,215,137,123,51,155,153,217,35,1,65,61,2,201,131,8,10,126,97,2,17,84,16,204,91,30,228,240,73,130,95,40, -104,124,9,137,47,9,248,230,23,8,65,52,130,255,234,238,201,133,35,226,178,191,169,234,234,238,170,234,154,158,238,78,116, -100,100,254,129,157,116,170,242,197,47,171,219,126,253,250,218,79,107,167,30,234,189,251,229,123,127,239,158,219,187,86, -124,127,193,33,234,19,209,145,214,131,19,164,127,187,96,187,151,148,125,4,108,22,74,214,33,241,167,179,120,84,32,63,213, -237,186,65,244,130,69,244,12,228,121,147,232,34,248,29,252,1,174,130,191,192,63,224,118,140,217,9,154,224,121,240,34,88, -5,39,192,171,224,117,240,14,56,13,62,0,31,129,51,224,51,240,21,56,15,46,128,203,224,55,240,39,112,108,162,105,48,15,30,6, -77,240,44,56,1,94,3,167,193,25,176,6,62,7,223,2,164,73,72,135,176,76,114,193,16,24,214,107,29,5,147,188,102,0,247,114, -125,199,48,216,214,109,210,99,92,173,143,105,253,21,140,25,215,250,219,208,61,173,191,15,125,147,214,63,54,85,221,88,255, -4,250,45,90,63,7,125,66,235,223,200,88,130,166,136,243,52,100,12,3,217,221,169,219,91,116,30,51,196,227,84,63,203,91,181, -156,38,53,255,54,41,77,154,149,210,161,59,164,84,126,108,172,120,78,74,139,170,82,186,116,151,158,191,69,74,155,238,38, -181,102,65,164,163,40,157,127,67,142,146,38,44,108,251,193,86,53,236,87,120,44,103,190,84,229,10,148,253,151,116,127,217, -147,84,28,140,243,80,71,75,190,131,43,182,90,255,34,54,220,20,130,221,15,55,187,208,187,152,161,38,135,197,49,241,134, -251,225,138,51,12,95,30,241,76,94,255,207,152,195,107,74,171,130,14,192,163,11,235,24,205,136,41,74,170,38,170,60,74,75, -11,240,184,112,163,71,87,182,251,11,136,251,180,39,223,163,138,127,245,127,226,187,50,254,184,140,207,181,229,189,195,19, -249,253,165,21,206,231,166,113,230,55,145,37,60,93,55,71,239,57,210,82,233,195,178,46,66,83,238,55,238,45,117,30,97,72, -221,210,99,156,122,156,196,197,110,218,252,88,22,118,151,163,164,120,114,37,202,122,225,209,29,135,194,149,144,68,131,68, -147,140,102,64,34,160,217,32,76,58,89,26,119,252,176,223,247,31,141,195,94,218,45,103,213,104,250,122,111,59,77,10,152, -252,134,20,53,154,188,222,147,230,254,222,65,210,233,69,53,154,11,218,233,178,159,165,189,216,63,52,104,71,254,134,240, -53,154,8,56,3,191,23,38,93,127,177,200,226,164,91,35,209,34,171,213,104,4,252,12,2,50,90,77,178,91,77,54,176,128,197,108, -53,217,12,14,54,104,242,224,77,92,216,237,94,154,71,228,182,251,253,3,207,197,57,89,157,176,8,201,237,196,249,114,156, -231,52,214,141,138,61,89,119,192,169,228,228,162,21,164,73,23,230,44,76,138,253,81,62,232,193,92,73,147,61,237,34,94,137, -139,163,202,68,83,27,45,79,132,104,69,52,148,38,251,178,40,44,34,242,74,77,247,204,164,201,254,232,240,32,202,139,167, -162,140,67,199,105,146,107,111,213,255,238,211,179,221,52,89,44,194,172,160,113,173,104,251,104,127,125,2,141,102,202, -201,190,180,19,209,72,38,231,75,221,206,11,78,201,42,184,0,46,185,158,113,95,141,118,64,62,94,167,237,230,214,109,211, -174,119,252,77,26,19,219,93,175,126,238,248,18,85,205,173,247,204,194,246,22,190,57,215,123,4,22,18,54,62,111,235,229, -151,172,31,45,123,21,39,201,13,216,226,154,101,138,147,182,33,190,3,39,29,72,103,124,195,55,207,178,188,19,120,63,150, -247,130,73,235,119,67,185,103,249,126,224,179,163,188,35,28,90,191,39,68,85,181,249,174,16,21,117,46,240,249,106,84,149, -127,190,63,76,61,134,207,21,62,160,68,121,230,84,148,206,247,211,191,48,134,254,198,216,6,0,0}; +{31,139,8,8,26,116,161,94,0,3,106,97,118,97,70,114,97,103,109,101,110,116,79,118,101,114,108,97,121,46,100,101,120,0,133,149, +77,136,28,69,20,199,255,53,253,181,159,179,147,221,184,140,235,198,140,43,70,197,224,172,104,36,56,99,216,152,32,204,100,226,71, +54,204,97,227,165,153,105,39,189,206,118,79,186,123,150,4,20,53,4,146,131,8,6,252,130,28,114,80,65,48,8,226,65,196,83,8,66,64, +65,146,75,252,184,152,179,160,160,4,17,5,255,175,187,58,27,150,136,195,252,250,189,122,245,234,189,170,215,213,85,93,239,248, +216,226,163,187,96,79,85,156,198,103,91,86,175,30,189,252,253,193,79,203,15,189,242,199,245,246,129,179,245,238,53,27,24,0,56, +222,126,108,26,250,183,155,182,7,145,217,199,200,86,149,201,58,37,255,248,156,143,18,229,87,186,93,47,0,47,155,192,11,148,87, +12,224,7,242,27,249,157,220,32,127,145,127,200,93,244,217,69,154,228,37,242,42,57,73,206,144,55,201,89,242,62,57,79,62,36,31, +147,11,228,34,185,76,174,144,107,228,103,242,43,249,147,216,22,80,38,139,228,9,210,36,47,146,51,228,45,114,158,92,32,95,146,175, +201,183,132,211,4,167,3,46,19,14,25,33,163,122,173,227,100,70,214,76,24,62,93,223,41,58,91,186,13,237,227,104,125,66,235,111, +208,103,82,235,239,81,47,106,253,3,234,83,90,255,196,200,234,38,250,23,212,183,104,253,18,245,105,173,127,147,230,82,152,133, +204,179,144,230,40,112,118,119,235,246,130,158,199,28,196,47,235,23,121,135,150,101,100,227,239,76,165,129,249,84,218,216,150, +202,44,142,197,21,111,79,165,137,74,42,29,220,163,199,47,164,210,194,189,200,214,172,0,157,37,211,229,55,98,103,210,160,69,108, +87,173,172,134,131,146,248,202,204,87,42,82,129,188,255,71,221,159,247,4,37,155,126,69,214,209,76,223,193,117,43,91,255,50,55, +220,44,147,61,194,48,187,217,187,28,177,38,199,212,41,245,182,243,209,186,61,202,88,69,200,72,89,255,47,28,35,107,10,43,10,135, +25,209,161,117,2,115,106,22,65,197,96,149,199,177,178,196,136,75,183,70,116,210,246,96,137,121,159,47,166,239,49,203,127,227, +127,242,59,105,254,201,52,191,212,86,246,142,12,148,247,23,150,100,62,183,205,179,56,5,83,21,117,221,108,189,231,160,101,166, +143,166,117,81,154,124,191,73,111,174,139,71,33,213,77,237,99,215,253,192,79,246,96,235,211,145,219,91,243,130,228,217,117,47, +234,187,39,30,94,117,215,93,168,6,84,19,133,102,11,170,133,249,150,27,116,163,208,239,86,221,193,160,186,223,119,251,97,47,31, +85,67,249,102,111,39,12,18,154,170,141,84,212,48,115,179,39,140,171,79,13,131,110,223,171,97,123,171,19,174,85,163,181,184,95, +93,29,118,188,234,166,244,53,76,183,100,6,213,190,27,244,170,203,73,228,7,189,26,84,27,102,187,209,104,201,179,213,66,161,221, +132,213,110,138,65,4,45,70,187,41,102,114,164,129,153,35,183,9,97,117,250,97,236,193,233,12,6,135,143,250,49,204,174,155,184, +112,186,126,188,230,199,49,38,122,94,178,55,234,13,101,42,49,28,182,90,97,208,163,57,114,131,228,144,23,15,251,52,151,194,96, +111,39,241,215,253,228,68,102,194,236,102,203,51,46,91,30,70,194,96,95,228,185,137,135,98,174,233,158,185,48,56,228,29,27,122, +113,242,156,23,73,106,63,12,98,29,173,242,223,125,122,180,19,6,203,137,27,37,152,212,138,182,143,15,54,6,96,60,202,130,236,11, +187,30,198,162,116,124,170,91,113,34,83,50,19,41,192,54,56,197,194,206,26,246,83,30,168,99,143,177,227,254,178,83,60,253,14,22, +212,3,78,177,126,233,244,10,30,55,118,220,55,79,219,187,216,73,167,39,105,129,178,248,121,155,175,191,102,254,100,90,39,121, +146,220,130,165,254,54,13,117,206,42,168,239,200,57,155,210,158,220,244,205,139,204,239,4,217,143,249,189,96,96,227,110,200,247, +172,220,15,114,118,228,119,132,141,141,123,66,85,178,182,220,21,170,148,157,11,114,190,22,42,89,124,185,63,12,237,35,231,138, +28,80,42,63,115,74,153,46,247,211,191,81,33,150,205,216,6,0,0,0,0}; //============================================================================== #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ @@ -533,7 +533,7 @@ static const uint8 javaFragmentOverlay[] = CALLBACK (FragmentOverlay::onStartNative, "onStartNative", "(J)V") \ CALLBACK (FragmentOverlay::onRequestPermissionsResultNative, "onRequestPermissionsResultNative", "(JI[Ljava/lang/String;[I)V") - DECLARE_JNI_CLASS_WITH_BYTECODE (JuceFragmentOverlay, "com/roli/juce/FragmentOverlay", 16, javaFragmentOverlay, sizeof(javaFragmentOverlay)) + DECLARE_JNI_CLASS_WITH_BYTECODE (JuceFragmentOverlay, "com/rmsl/juce/FragmentOverlay", 16, javaFragmentOverlay, sizeof(javaFragmentOverlay)) #undef JNI_CLASS_MEMBERS #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ @@ -620,7 +620,7 @@ class ActivityLauncher : public FragmentOverlay public: ActivityLauncher (const LocalRef<jobject>& intentToUse, int requestCodeToUse, - std::function<void(int, int, LocalRef<jobject>)> && callbackToUse) + std::function<void (int, int, LocalRef<jobject>)> && callbackToUse) : intent (intentToUse), requestCode (requestCodeToUse), callback (std::move (callbackToUse)) {} @@ -642,11 +642,11 @@ public: private: GlobalRef intent; int requestCode; - std::function<void(int, int, LocalRef<jobject>)> callback; + std::function<void (int, int, LocalRef<jobject>)> callback; }; void startAndroidActivityForResult (const LocalRef<jobject>& intent, int requestCode, - std::function<void(int, int, LocalRef<jobject>)> && callback) + std::function<void (int, int, LocalRef<jobject>)> && callback) { auto* activityLauncher = new ActivityLauncher (intent, requestCode, std::move (callback)); activityLauncher->open(); diff --git a/modules/juce_core/native/juce_android_JNIHelpers.h b/modules/juce_core/native/juce_android_JNIHelpers.h index edf7fadd..9e606ba5 100644 --- a/modules/juce_core/native/juce_android_JNIHelpers.h +++ b/modules/juce_core/native/juce_android_JNIHelpers.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -149,7 +149,7 @@ private: //============================================================================== jobject obj = nullptr; - static inline jobject retain (jobject obj, JNIEnv* env) + static jobject retain (jobject obj, JNIEnv* env) { return obj == nullptr ? nullptr : env->NewGlobalRef (obj); } @@ -983,7 +983,7 @@ public: //============================================================================== // Allows you to start an activity without requiring to have an activity void startAndroidActivityForResult (const LocalRef<jobject>& intent, int requestCode, - std::function<void(int, int, LocalRef<jobject>)> && callback); + std::function<void (int, int, LocalRef<jobject>)> && callback); //============================================================================== bool androidHasSystemFeature (const String& property); diff --git a/modules/juce_core/native/juce_android_Misc.cpp b/modules/juce_core/native/juce_android_Misc.cpp index 8ad39bed..21bc90ce 100644 --- a/modules/juce_core/native/juce_android_Misc.cpp +++ b/modules/juce_core/native/juce_android_Misc.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -25,7 +25,20 @@ namespace juce void Logger::outputDebugString (const String& text) { - __android_log_print (ANDROID_LOG_INFO, "JUCE", "%s", text.toUTF8().getAddress()); + char* data = text.toUTF8().getAddress(); + const size_t length = CharPointer_UTF8::getBytesRequiredFor (text.getCharPointer()); + const size_t chunkSize = 1023; + + size_t position = 0; + size_t numToRead = jmin (chunkSize, length); + + while (numToRead > 0) + { + __android_log_print (ANDROID_LOG_INFO, "JUCE", "%s", data + position); + + position += numToRead; + numToRead = jmin (chunkSize, length - position); + } } } // namespace juce diff --git a/modules/juce_core/native/juce_android_Network.cpp b/modules/juce_core/native/juce_android_Network.cpp index 8808d170..2ddd79f9 100644 --- a/modules/juce_core/native/juce_android_Network.cpp +++ b/modules/juce_core/native/juce_android_Network.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -24,165 +24,158 @@ namespace juce { //============================================================================== -// This byte-code is generated from native/java/com/roli/juce/JuceHTTPStream.java with min sdk version 16 +// This byte-code is generated from native/java/com/rmsl/juce/JuceHTTPStream.java with min sdk version 16 // See juce_core/native/java/README.txt on how to generate this byte-code. static const uint8 javaJuceHttpStream[] = -{31,139,8,8,96,105,229,91,0,3,74,117,99,101,72,84,84,80,83,116,114,101,97,109,46,100,101,120,0,125,154,11,124,84,213,157, -199,255,231,222,185,119,30,153,153,220,76,30,147,132,60,38,33,132,4,18,38,32,40,146,128,200,75,32,65,17,6,20,146,181,29, -50,23,50,48,220,9,51,119,32,88,84,64,171,212,218,74,173,86,250,82,139,88,105,87,91,171,237,214,86,187,109,197,118,219, -218,90,109,245,179,174,187,125,91,119,237,167,187,186,218,118,221,246,227,102,127,231,49,153,137,77,33,124,239,255,127, -254,231,127,206,61,143,255,121,204,36,41,123,34,208,119,193,18,58,123,73,224,169,145,163,171,22,29,152,124,110,71,248, -214,145,193,207,157,62,245,139,197,215,175,242,156,233,36,26,39,162,137,237,139,35,164,254,253,114,14,209,11,36,237,139, -192,183,116,162,56,228,9,15,81,61,228,147,38,209,149,144,71,188,68,200,34,79,128,104,101,19,81,10,242,205,90,162,63,130, -183,193,95,192,255,1,173,142,200,0,33,80,5,162,160,27,92,12,54,131,173,224,42,48,2,118,1,27,92,11,174,3,199,192,205,224, -86,112,59,56,5,206,128,179,224,41,240,10,104,140,18,45,3,215,128,27,193,253,224,187,224,183,128,161,193,49,112,17,184,28, -236,6,71,193,221,224,33,240,44,120,5,188,13,194,13,68,237,96,0,92,5,246,129,227,224,62,240,8,248,1,248,37,120,19,248,27, -137,174,6,105,112,45,248,4,120,2,188,6,106,102,161,14,112,13,56,2,62,9,254,5,76,130,30,140,211,213,96,20,236,6,123,129,3, -242,224,125,224,40,184,13,156,4,31,5,119,131,79,130,123,193,253,224,113,240,36,248,30,120,17,252,28,188,10,94,7,255,3, -222,1,70,51,81,16,68,65,12,244,128,53,96,59,24,3,215,130,219,192,167,193,3,224,9,112,14,252,24,188,10,254,2,204,22,244, -17,88,160,17,116,128,249,96,17,184,8,108,2,127,7,28,112,61,184,25,220,13,206,128,175,128,239,128,31,129,127,6,175,129,55, -193,36,240,181,18,213,129,78,208,15,46,3,27,193,86,240,94,176,23,28,2,71,193,9,112,23,184,23,60,0,30,6,143,129,175,129, -103,193,207,192,239,192,155,224,207,128,98,232,59,168,4,115,64,63,216,14,118,131,125,96,28,28,4,71,192,205,224,36,184,23, -60,0,190,0,190,9,94,4,63,3,191,6,255,14,254,12,188,109,68,179,65,31,88,9,182,128,221,96,63,112,193,17,112,2,124,28,60,8, -190,8,190,14,190,15,126,14,222,2,122,59,226,2,52,130,118,208,11,150,131,203,64,2,100,64,1,92,7,110,5,31,1,167,64,16,221, -178,0,194,138,16,62,132,233,37,76,15,97,40,73,117,153,80,61,193,149,102,131,14,128,229,75,88,214,52,23,116,129,110,48,15, -204,7,61,160,23,44,32,185,166,251,192,66,181,206,47,0,139,193,18,112,33,184,8,44,5,23,131,126,48,0,86,128,75,192,74,112, -41,88,5,214,128,117,224,50,176,30,108,4,91,192,54,176,29,92,69,178,31,197,127,33,37,151,98,111,8,43,125,101,153,190,30, -122,165,210,55,215,202,254,51,149,230,251,143,1,70,96,143,148,213,203,245,98,249,6,165,187,202,167,88,87,173,242,91,170, -236,181,202,94,173,244,35,202,30,45,179,71,149,189,70,233,55,65,175,83,250,109,202,94,175,236,181,74,95,170,244,134,50, -157,207,219,157,181,178,28,215,63,165,222,213,92,214,254,150,50,189,181,76,111,47,211,103,151,245,133,207,239,67,170,126, -62,199,93,170,206,121,202,135,207,67,175,210,7,149,206,251,114,133,210,191,12,125,72,233,79,150,233,125,101,58,111,255, -38,165,63,13,125,179,210,249,248,95,174,244,31,150,249,252,91,173,60,27,122,213,248,23,235,121,165,86,198,196,2,213,158, -173,74,255,61,236,9,165,187,170,47,11,213,123,117,204,244,247,136,203,5,244,28,164,7,35,103,11,89,75,123,132,236,161,180, -144,97,250,176,144,221,244,77,226,241,209,68,41,33,165,159,161,252,12,140,88,65,200,249,116,147,144,81,186,69,201,15,8, -41,235,49,240,190,59,72,198,217,105,33,25,125,78,200,56,125,94,200,122,250,130,144,125,244,13,33,139,239,197,154,87,242, -135,64,163,42,186,75,180,191,141,76,33,189,244,30,33,131,66,122,208,30,83,200,86,250,146,40,215,41,210,188,221,59,84,59, -71,133,172,163,221,66,154,52,166,236,7,132,244,211,97,33,13,186,65,201,99,42,255,164,144,58,61,36,100,43,61,172,198,225, -31,136,175,153,118,241,158,16,118,11,46,195,200,79,10,233,17,254,149,72,31,18,114,30,253,68,196,93,5,237,83,241,119,187, -136,189,86,81,46,138,113,217,165,228,135,72,198,246,199,132,92,64,95,23,178,146,190,45,164,37,100,61,86,212,136,144,17, -218,47,164,44,87,143,145,146,82,150,175,87,254,13,234,61,13,88,101,35,66,134,233,25,226,123,225,108,97,111,68,254,19,196, -215,83,43,57,66,250,232,90,33,27,233,125,42,125,68,200,0,93,79,114,221,29,21,50,74,199,133,140,209,99,66,118,211,151,149, -252,138,178,127,85,200,14,122,92,200,57,244,53,226,107,85,142,87,51,118,85,41,235,233,140,144,178,93,173,24,247,247,11, -25,164,123,136,239,205,33,154,32,190,63,7,233,58,37,111,36,190,158,103,145,75,124,45,55,208,157,196,215,113,51,125,139, -248,94,221,66,25,33,155,232,227,196,215,116,47,189,87,200,160,168,103,190,26,143,249,248,145,233,110,122,148,248,158,46, -237,92,222,45,228,124,122,86,165,127,76,242,142,70,36,215,22,223,35,170,32,31,199,198,117,229,28,105,247,148,229,247,169, -252,151,144,191,87,229,243,120,102,84,218,47,121,254,219,200,63,174,242,121,253,63,197,193,243,50,248,77,135,244,253,131, -146,239,116,240,117,128,251,4,124,67,115,164,45,170,100,167,146,151,40,185,126,14,175,75,23,250,167,176,233,249,32,135, -145,24,209,24,141,91,179,68,132,242,92,94,223,153,118,185,71,182,179,32,109,139,49,156,83,22,37,98,68,7,44,175,136,112, -199,234,19,114,60,86,141,18,85,108,122,222,2,33,187,222,228,109,99,226,125,15,183,203,126,58,22,183,4,69,31,77,252,240, -188,71,219,229,121,34,219,48,204,52,26,214,12,26,214,61,52,236,209,105,216,48,197,202,225,237,50,232,71,237,242,60,76, -244,121,80,23,223,105,3,56,63,107,41,177,80,167,102,150,232,51,209,82,31,113,25,137,228,98,235,17,35,45,76,250,94,46,74, -105,200,247,10,233,88,189,194,98,40,139,1,75,237,84,205,155,197,104,132,80,122,46,158,37,91,215,159,144,90,40,83,76,156, -16,132,213,171,3,46,153,58,187,116,113,206,243,158,47,17,82,71,219,47,184,33,116,225,114,172,204,0,241,81,122,165,93,238, -221,188,207,62,140,114,15,180,77,240,28,62,230,71,170,86,216,121,138,231,205,71,106,163,72,85,96,95,226,55,129,32,59,96, -93,198,199,145,13,31,11,208,200,173,149,52,252,193,8,13,223,22,164,29,31,170,163,225,15,215,208,240,237,213,20,249,239, -29,199,162,120,179,69,59,142,90,120,75,21,13,31,13,209,182,27,43,41,113,83,132,18,239,15,210,22,92,253,19,183,132,200, -123,204,123,199,65,175,95,213,232,69,207,53,117,35,168,154,45,227,47,129,185,173,18,177,233,21,49,82,15,123,158,199,135, -175,25,49,176,12,235,216,177,6,240,142,160,175,213,215,68,222,155,90,61,77,20,241,57,177,11,113,18,56,177,197,244,7,60, -47,194,179,209,119,53,180,86,156,3,65,45,162,183,117,45,185,49,78,235,124,154,222,232,215,97,111,166,83,20,48,151,155, -237,194,230,224,114,236,163,128,111,201,205,141,34,29,241,59,184,34,158,50,131,140,167,94,242,155,204,137,197,80,34,232, -229,158,94,120,46,247,97,22,251,46,166,26,239,75,186,206,186,158,79,156,13,161,214,165,104,195,210,96,132,34,245,78,108, -9,215,67,60,70,23,34,166,130,134,131,15,47,47,34,21,69,108,85,121,66,34,42,60,232,85,136,26,253,126,244,172,6,245,207, -245,201,59,206,85,124,70,217,172,61,213,56,23,2,208,15,205,150,247,139,254,112,45,69,194,237,168,193,251,25,246,168,247, -156,247,5,246,91,239,159,124,94,139,52,95,21,249,252,17,58,24,48,197,216,93,28,254,175,201,234,112,95,161,235,119,33,22, -161,174,183,229,216,86,201,122,27,43,68,140,135,233,19,179,249,12,227,126,228,59,201,34,53,17,61,241,128,159,154,141,196, -233,10,180,110,16,30,1,109,41,214,71,139,193,22,85,106,145,200,120,44,136,115,36,168,13,159,14,83,226,116,13,69,204,196, -131,94,120,46,226,35,226,29,244,106,166,180,174,209,52,115,241,241,159,82,68,155,94,130,251,198,81,107,80,203,89,171,149, -92,195,165,153,179,86,96,133,242,183,61,77,57,235,18,232,65,214,202,218,160,95,202,35,5,246,55,38,115,214,42,165,255,110, -50,241,96,53,70,174,1,209,218,133,121,43,122,181,106,81,204,65,55,118,221,160,214,232,243,8,253,56,226,164,209,175,81, -177,116,171,86,67,7,98,98,39,214,74,190,84,244,213,28,107,158,104,153,19,107,199,154,43,175,185,209,27,128,87,19,229,208, -206,139,181,179,147,165,26,99,20,241,230,98,43,145,35,61,15,88,13,178,14,171,81,140,225,142,211,81,234,186,61,36,198,177, -155,70,38,67,106,44,22,137,220,37,199,219,228,104,122,18,159,149,86,140,132,57,104,106,30,233,213,11,175,153,243,101,125, -139,39,103,158,139,110,90,54,25,210,90,140,185,90,72,75,156,249,107,15,143,57,247,93,115,218,77,113,148,232,166,158,73, -212,188,170,155,188,147,124,255,240,99,87,170,22,123,168,87,220,131,121,236,116,136,61,171,90,124,214,184,1,233,199,196, -222,19,18,103,44,63,243,159,83,126,255,170,236,191,80,233,255,84,233,55,196,174,205,232,29,81,111,53,249,152,180,27,55, -132,30,101,191,103,55,116,126,149,189,206,232,247,140,94,103,215,119,190,95,19,70,47,198,129,159,41,175,206,150,159,119, -34,90,98,171,143,154,245,196,149,50,90,25,5,216,82,134,104,213,189,109,56,37,174,12,80,59,246,244,241,62,70,9,51,23,91, -139,207,56,216,113,174,172,69,126,2,207,156,181,65,236,65,173,44,76,93,175,133,88,139,62,151,97,119,106,235,250,141,120, -254,82,158,165,13,240,225,235,206,135,247,206,85,251,172,70,157,90,117,247,156,158,26,232,94,62,23,24,12,126,103,168,198, -135,155,72,232,32,171,64,127,2,214,197,150,33,44,149,214,75,161,16,243,193,182,133,89,116,97,243,255,78,114,61,193,48,31, -250,154,42,166,87,179,94,198,111,151,139,172,26,170,102,11,148,142,177,101,113,165,195,159,93,32,244,11,172,151,85,233, -106,106,212,55,32,26,59,112,195,14,176,151,194,44,80,178,35,150,251,230,208,194,112,160,242,162,215,159,82,254,124,222, -47,16,253,117,172,229,92,250,139,254,78,223,92,250,85,101,176,162,184,187,158,162,246,32,180,190,126,186,173,130,251,6, -17,27,139,238,184,103,234,189,17,93,104,30,148,180,58,49,70,1,143,211,55,155,22,122,132,21,177,226,195,213,178,57,34,189, -203,231,165,82,140,70,75,164,155,38,38,49,218,17,140,118,128,91,186,105,188,172,141,189,240,230,169,109,122,37,201,247, -68,164,52,130,66,110,49,235,100,218,27,66,204,84,83,241,36,225,182,97,212,192,235,95,57,41,107,230,250,170,73,18,247,243, -185,104,233,205,106,255,187,91,204,163,135,62,13,233,133,198,239,125,124,247,127,74,165,117,186,11,91,228,41,118,195,172, -239,176,187,24,169,91,12,209,137,14,185,135,110,141,85,137,207,177,69,251,135,59,100,172,108,137,69,113,103,183,166,206, -179,59,213,125,41,130,29,221,15,111,15,126,62,209,33,63,27,226,76,220,133,157,86,75,36,195,180,148,249,137,203,136,238, -172,172,163,3,55,6,168,69,91,142,246,108,221,85,69,199,60,79,172,218,9,89,73,24,51,13,99,198,186,222,98,36,239,86,30,181, -134,26,85,92,206,154,58,255,27,88,168,137,199,44,67,116,106,244,88,135,252,238,160,29,37,18,7,112,255,200,97,47,206,227, -157,46,110,47,133,90,58,104,242,154,18,57,209,158,3,21,20,169,118,98,67,136,171,8,27,134,119,139,214,110,54,34,50,230, -163,46,199,234,33,126,67,146,109,137,136,27,17,19,223,79,48,241,51,7,111,144,55,212,103,202,250,206,191,75,228,255,52,42, -73,55,32,199,242,8,228,77,1,121,103,44,126,47,192,207,175,147,1,57,166,167,32,239,83,249,229,119,95,158,111,170,122,252, -74,242,239,15,206,42,223,14,85,95,157,146,81,245,222,162,140,171,250,226,170,78,63,201,207,58,113,225,209,39,62,191,68, -85,217,5,101,109,43,239,131,69,53,194,110,168,54,151,202,71,133,125,158,242,227,159,65,25,201,123,167,108,67,84,148,105, -130,165,7,189,233,86,246,102,85,46,78,197,241,96,24,222,46,194,133,141,45,35,109,89,140,216,0,153,3,105,39,237,174,32, -109,69,63,121,86,244,119,111,39,107,117,214,113,236,81,55,157,117,98,118,46,151,205,81,24,22,215,118,220,222,33,219,217, -227,142,81,237,154,116,126,116,202,105,75,193,113,146,187,50,54,177,13,164,109,24,34,125,195,208,6,242,224,129,253,112, -35,85,111,44,140,218,235,19,137,205,91,221,156,157,220,191,96,111,242,96,146,216,16,105,112,210,185,143,54,132,34,67,120, -120,135,134,118,14,13,161,130,128,82,184,174,13,237,164,250,161,164,147,202,101,211,169,184,107,79,184,241,4,30,219,220, -116,38,223,79,177,161,209,236,254,120,46,155,73,199,247,226,53,241,233,239,234,88,216,79,139,207,239,49,99,71,250,169, -229,188,165,250,169,125,40,149,204,28,76,239,139,39,29,39,235,38,121,225,248,90,103,52,147,205,167,157,61,171,51,201,60, -218,54,251,124,62,155,108,119,44,155,226,47,250,107,167,13,104,79,78,85,210,54,67,254,38,123,255,46,229,96,195,165,121,6, -151,173,233,61,78,210,45,228,208,149,198,25,178,19,99,185,236,33,81,148,207,70,60,157,141,175,42,236,222,109,231,236,212, -6,103,188,224,22,123,89,59,149,189,225,138,181,19,163,246,56,47,60,205,92,238,93,55,101,190,162,224,150,217,235,165,61, -147,116,246,196,87,143,37,115,91,237,3,5,219,25,181,167,42,18,57,101,245,87,151,153,55,32,238,246,216,57,62,211,211,141, -185,92,97,220,181,83,101,197,106,202,61,224,32,103,50,82,102,189,98,215,94,76,244,116,207,210,156,151,123,162,237,152, -164,233,109,151,54,57,80,253,212,48,67,78,58,147,226,89,229,21,97,164,237,100,106,122,87,197,232,203,119,54,73,179,99, -187,241,245,174,59,190,109,203,80,105,237,245,83,184,148,139,156,169,214,168,116,185,167,234,81,1,171,66,246,221,205,162, -33,86,153,117,40,157,119,167,154,33,44,155,146,227,29,107,29,55,119,184,159,54,205,100,30,248,235,241,120,87,125,51,120, -172,192,15,85,78,175,110,186,97,171,237,242,176,47,25,176,254,70,11,185,28,182,151,248,234,100,38,35,118,146,214,243,231, -247,83,207,223,114,64,96,193,135,143,74,89,104,116,207,236,189,118,194,30,45,188,203,181,243,124,174,89,4,111,238,96,154, -199,110,236,252,126,249,169,185,125,183,199,186,2,95,151,197,165,55,115,110,63,13,156,47,123,224,188,203,22,19,208,49, -115,105,25,140,235,146,163,104,32,102,125,254,204,94,136,157,253,233,209,248,165,66,172,202,102,51,118,18,227,50,111,102, -231,76,118,116,95,62,190,197,134,158,75,58,238,16,146,253,228,135,16,83,176,140,216,118,210,182,99,143,223,142,61,126,59, -246,120,19,15,190,215,35,177,147,2,219,203,246,249,237,59,137,237,36,109,231,70,0,57,188,10,108,160,234,225,25,86,165,54, -226,80,32,57,58,106,231,243,29,125,125,125,84,33,245,117,153,228,158,60,121,147,169,84,14,41,50,147,227,227,182,147,34, -239,174,100,222,222,150,203,144,185,75,140,22,121,70,17,70,100,142,138,88,33,131,239,200,54,249,177,225,143,39,115,118, -34,75,94,117,34,80,160,116,52,80,93,73,79,100,75,167,6,89,163,24,83,215,46,45,198,162,69,78,21,31,144,162,165,116,128,20, -45,50,37,124,42,213,136,22,135,142,204,148,61,154,77,217,84,147,178,119,39,11,25,119,218,228,241,220,140,237,218,20,72, -149,154,82,155,154,241,84,174,158,102,150,213,144,63,149,85,77,38,102,147,193,167,239,48,249,132,192,2,133,166,226,152, -140,221,105,59,147,130,200,20,242,99,164,239,65,102,13,30,197,133,134,23,168,46,133,97,93,203,111,11,42,93,137,244,122, -188,202,206,173,227,53,228,133,67,89,156,146,137,244,160,125,88,56,150,159,24,84,1,195,102,156,146,98,24,120,238,22,59, -63,158,117,242,24,100,140,7,175,38,129,131,44,163,238,34,188,26,236,134,228,131,220,158,204,20,108,178,198,146,249,85, -136,72,213,70,27,33,0,203,229,184,53,80,197,152,104,209,80,218,177,17,41,50,145,167,160,82,18,217,109,136,132,240,24,118, -226,45,252,144,202,187,171,247,167,168,122,122,90,58,5,184,81,181,151,165,201,155,118,82,246,196,21,187,169,34,93,214,67, -95,218,81,77,170,72,231,215,78,140,37,11,121,151,183,38,157,23,227,64,102,58,143,126,186,60,151,75,89,179,47,173,246,111, -242,236,205,166,17,7,25,217,79,15,95,106,228,113,146,251,49,165,142,125,104,117,114,116,204,78,201,233,220,140,85,74,33, -110,44,133,97,5,146,165,96,66,2,175,16,146,47,5,143,195,71,67,119,10,104,36,30,171,14,187,24,143,26,104,235,178,153,76, -246,144,157,218,98,167,210,57,212,36,173,83,169,68,86,58,80,195,76,86,53,126,89,44,187,178,134,232,89,116,85,31,199,219, -61,120,44,20,207,69,228,27,47,206,48,215,220,53,73,55,73,161,162,38,43,242,136,72,245,230,16,233,88,193,84,153,83,97,176, -94,77,91,205,187,12,178,148,9,43,150,11,233,185,2,222,157,71,188,86,225,161,218,147,72,239,183,121,115,42,96,90,147,149, -81,71,141,121,30,152,121,151,135,139,236,72,169,247,220,113,42,22,195,121,30,139,201,84,177,22,75,164,69,96,200,251,28, -69,74,150,205,57,140,67,206,61,76,70,126,60,147,118,33,220,100,14,115,14,225,22,242,20,144,82,132,116,101,73,151,125,8, -230,69,0,169,163,194,204,23,118,237,71,13,126,200,188,216,2,41,228,142,149,111,57,213,60,249,238,93,167,100,44,219,102, -194,48,150,47,194,74,164,183,150,191,204,227,142,165,17,39,252,217,209,71,126,23,93,197,48,109,194,242,157,82,85,156,186, -89,185,31,83,133,91,182,28,235,248,57,144,223,157,205,237,183,83,151,151,69,160,23,59,139,104,129,89,112,68,36,87,28,76, -102,58,138,43,193,56,40,150,137,113,40,135,232,39,109,162,143,142,104,223,103,228,13,211,81,254,156,92,54,64,71,120,234, -30,205,56,199,190,203,190,195,158,198,231,109,227,159,216,188,117,222,240,64,47,255,71,159,215,224,112,98,249,96,186,117, -100,112,120,240,154,97,109,188,121,109,219,57,170,243,143,220,201,30,98,31,96,207,176,111,178,71,216,25,246,65,230,13, -107,127,209,250,39,38,14,107,199,175,59,35,10,247,14,12,14,177,72,37,89,236,5,228,210,106,115,228,163,236,239,217,9,246, -3,225,253,138,238,249,36,107,30,28,184,100,159,174,221,194,22,49,166,235,31,98,108,249,9,221,124,144,177,207,78,232,236, -80,253,9,221,251,19,86,159,214,14,246,27,204,240,106,225,126,195,28,94,48,180,96,80,55,62,203,172,129,75,12,163,197,208, -12,189,85,167,124,211,0,205,243,79,85,255,143,236,139,236,126,118,43,94,210,59,135,85,69,209,230,94,173,162,191,141,126, -141,94,111,92,126,139,214,219,163,237,104,214,42,14,61,62,113,61,107,180,60,204,109,239,127,154,53,84,178,250,208,138,95, -177,250,106,131,241,42,195,56,52,13,226,218,220,19,95,190,230,71,125,90,203,243,6,105,187,250,207,117,124,76,179,250,233, -32,187,131,121,155,81,89,109,143,182,191,249,229,182,143,172,68,15,40,95,211,218,98,144,208,58,91,233,78,62,202,189,186, -245,37,22,111,211,67,167,25,27,234,213,190,77,61,134,165,93,218,108,90,31,56,172,87,125,131,49,86,95,117,78,15,159,69, -159,245,202,207,49,182,224,156,238,223,87,255,65,189,226,83,172,126,167,238,187,166,101,167,30,188,135,181,12,233,218, -179,172,62,206,44,235,240,3,90,104,135,97,173,68,215,125,70,176,85,15,228,155,52,103,163,17,48,53,211,103,6,77,235,125, -172,165,246,162,86,51,64,111,241,169,163,183,197,243,29,241,252,185,166,189,231,51,24,149,54,157,238,195,80,15,78,180, -247,238,213,38,154,7,232,25,158,253,71,157,198,141,229,123,7,90,119,234,230,129,89,3,13,134,73,199,117,246,105,62,117, -154,151,61,207,26,131,154,79,219,233,161,83,172,69,11,32,221,100,68,123,163,203,163,70,180,35,234,213,42,184,1,3,88,84, -170,52,19,74,189,33,138,248,78,177,104,133,44,227,137,174,86,37,68,210,31,101,209,197,209,206,232,122,84,37,51,124,154, -95,214,224,41,86,213,73,26,211,232,100,140,225,255,209,163,158,71,106,53,246,92,45,251,118,236,190,58,50,24,211,144,41, -126,200,115,236,168,231,201,58,131,253,71,29,85,153,94,175,198,34,226,71,228,49,109,218,143,72,155,240,127,164,158,157, -136,189,212,160,69,222,104,96,13,127,152,197,34,63,108,98,145,163,237,190,170,147,179,141,170,183,59,89,213,201,185,172, -234,44,120,18,60,210,197,170,206,116,139,239,148,168,236,187,6,46,139,127,187,197,191,31,40,254,253,86,241,123,11,254,55, -92,252,59,146,226,223,113,241,239,20,138,127,203,101,82,233,239,185,116,75,254,254,141,127,15,195,98,242,119,191,143,240, -239,79,98,210,135,255,254,144,89,165,223,41,106,49,249,94,254,247,95,186,242,231,191,195,243,196,72,252,238,137,255,126, -144,84,89,241,123,71,75,182,149,255,173,217,255,3,11,139,181,139,164,38,0,0}; +{31,139,8,8,71,116,161,94,0,3,106,97,118,97,74,117,99,101,72,116,116,112,83,116,114,101,97,109,46,100,101,120,0,125,154,11,124, +84,87,157,199,255,231,222,185,119,30,153,153,220,76,30,147,132,60,38,33,132,4,18,38,80,104,41,9,148,242,42,144,80,40,12,84,8, +91,29,50,23,50,48,185,19,102,238,64,168,180,133,62,233,67,75,223,184,86,173,72,45,186,85,171,86,173,182,174,109,105,93,31,181, +85,87,119,171,187,186,186,91,171,246,211,221,118,235,171,171,31,55,251,59,143,201,76,218,44,132,239,253,255,207,255,252,207, +185,231,241,63,143,153,36,101,79,4,250,46,88,66,151,94,114,238,181,147,179,244,212,201,205,225,159,190,152,158,247,165,219,39, +126,178,240,215,230,173,135,207,118,18,141,19,209,196,142,197,17,82,255,94,153,67,244,35,146,246,69,224,105,157,40,14,121,194, +67,84,15,249,148,73,116,5,228,81,47,17,178,200,19,32,90,211,68,148,130,124,171,150,232,15,224,109,240,23,240,191,64,171,35,50, +64,8,84,129,40,232,6,23,131,45,96,27,184,18,236,6,123,128,13,174,6,215,128,227,224,102,112,27,184,19,156,2,103,192,89,240,44, +120,5,52,70,137,150,129,171,192,13,224,19,224,155,224,87,128,161,193,49,112,17,184,28,236,5,199,192,3,224,81,240,34,120,5,188, +13,194,13,68,237,96,0,92,9,14,128,235,193,67,224,49,240,29,240,11,240,22,240,55,18,189,7,164,193,213,224,111,193,147,224,183, +160,102,22,234,0,87,129,163,224,195,224,39,96,18,244,96,156,222,3,70,192,94,176,31,56,32,15,222,15,142,129,59,192,73,112,15,120, +0,124,24,124,12,124,2,60,1,158,2,223,2,63,6,63,7,175,130,55,192,159,192,95,129,209,76,20,4,81,16,3,61,96,13,216,1,70,193,213, +224,14,240,17,240,48,120,18,156,3,47,129,87,193,95,128,217,130,62,2,11,52,130,14,48,31,44,2,23,129,77,224,111,128,3,174,5,55, +131,7,192,25,240,37,240,60,248,30,248,103,240,91,240,22,152,4,190,86,162,58,208,9,250,193,101,96,35,216,6,222,7,246,131,195,224, +24,56,1,238,3,31,3,15,131,207,128,47,130,175,130,23,193,207,192,107,224,45,240,103,64,49,244,29,84,130,57,160,31,236,0,123,193, +1,48,14,14,129,163,224,102,112,18,124,12,60,12,62,11,190,1,126,12,126,6,254,29,252,26,252,25,120,219,136,102,131,62,176,18, +108,5,123,193,24,112,193,81,112,2,124,8,60,2,62,7,190,6,190,13,126,14,126,7,244,118,196,5,104,4,237,160,23,44,7,151,129,4,200, +128,2,184,6,220,6,238,2,167,64,16,221,178,0,194,138,16,62,132,233,37,76,15,97,40,73,117,153,80,61,193,149,102,131,14,128,229, +75,88,214,52,23,116,129,110,48,15,204,7,61,160,23,44,32,185,166,251,192,66,181,206,47,0,139,193,18,112,33,184,8,44,5,23,131,126, +48,0,86,128,75,192,74,112,41,88,5,214,128,117,224,50,176,30,108,4,91,193,118,176,3,92,73,178,31,197,127,33,37,151,98,111,8, +43,125,101,153,190,30,122,165,210,183,212,202,254,51,149,230,251,143,1,118,195,30,41,171,151,235,197,242,13,74,119,149,79,177, +174,90,229,183,84,217,107,149,189,90,233,71,149,61,90,102,143,42,123,141,210,111,132,94,167,244,59,148,189,94,217,107,149,190, +84,233,13,101,58,159,183,123,107,101,57,174,63,168,222,213,92,214,254,150,50,189,181,76,111,47,211,103,151,245,133,207,239,163, +170,126,62,199,93,170,206,121,202,135,207,67,175,210,7,149,206,251,178,89,233,143,67,31,82,250,83,101,122,95,153,206,219,191, +73,233,207,65,223,162,116,62,254,151,43,253,133,50,159,127,173,149,103,67,175,26,255,98,61,175,212,202,152,88,160,218,179,77, +233,175,195,158,80,186,171,250,178,80,189,87,199,76,127,139,184,92,64,223,135,244,96,228,108,33,107,105,159,144,61,148,22,50, +76,31,20,178,155,190,65,60,62,154,40,37,164,244,51,148,159,129,17,43,8,57,159,110,20,50,74,183,40,121,171,144,178,30,3,239,187, +155,100,156,157,22,146,209,167,132,140,211,167,133,172,167,207,10,217,71,95,23,178,248,94,172,121,37,95,0,26,85,209,125,162, +253,109,100,10,233,165,247,10,25,20,210,131,246,152,66,182,210,231,69,185,78,145,230,237,222,169,218,57,34,100,29,237,21,210, +164,81,101,63,40,164,159,142,8,105,208,117,74,30,87,249,39,133,212,233,81,33,91,233,51,106,28,190,76,124,205,180,139,247,132, +176,91,112,25,70,126,82,72,143,240,175,68,250,176,144,243,232,135,34,238,42,232,128,138,191,59,69,236,181,138,114,81,140,203, +30,37,63,64,50,182,239,23,114,1,125,77,200,74,122,70,72,75,200,122,172,168,221,66,70,104,76,72,89,174,30,35,37,165,44,95,175, +252,27,212,123,26,176,202,118,11,25,166,239,18,223,11,103,11,123,35,242,159,36,190,158,90,201,17,210,71,87,11,217,72,239,87,233, +163,66,6,232,90,146,235,238,152,144,81,186,94,200,24,125,81,200,110,122,92,201,47,41,251,87,132,236,160,39,132,156,67,95,37, +190,86,229,120,53,99,87,149,178,158,206,8,41,219,213,138,113,191,73,200,32,125,148,248,222,28,162,9,226,251,115,144,174,81,242, +6,226,235,121,22,185,196,215,114,3,221,75,124,29,55,211,211,196,247,234,22,202,8,217,68,31,34,190,166,123,233,125,66,6,69,61, +243,213,120,204,199,143,76,119,211,23,136,239,233,210,206,229,3,66,206,167,23,85,250,37,146,119,52,34,185,182,248,30,81,5,249, +4,54,174,196,28,105,247,148,229,247,169,252,151,145,63,166,242,121,60,51,42,237,151,60,255,109,228,223,164,242,121,253,255,132, +131,231,103,224,213,14,233,251,39,37,249,97,164,65,248,33,173,57,210,214,168,100,183,146,171,148,28,156,195,235,210,133,254,32, +54,61,31,228,48,18,187,53,70,227,214,44,17,161,60,151,215,247,112,187,220,35,219,89,144,182,199,24,206,41,139,18,49,162,131, +150,87,68,184,99,245,9,57,30,171,70,137,42,54,61,111,129,144,93,111,241,182,49,241,190,207,182,203,126,58,22,183,4,69,31,77, +252,240,188,199,219,229,121,34,219,48,204,52,26,214,12,26,214,61,52,236,209,105,216,48,197,202,225,237,50,232,165,118,121,30,38, +250,60,168,139,239,180,1,156,159,181,148,88,168,83,51,75,244,153,104,169,143,184,140,68,114,177,245,136,145,22,38,125,47,23,165, +52,228,123,133,116,172,94,97,49,148,197,128,165,118,170,230,45,98,52,66,40,61,23,207,146,173,235,143,72,45,148,41,38,78,8, +194,234,213,1,151,76,157,93,186,56,231,121,207,151,8,169,163,237,23,92,23,186,112,57,86,102,128,248,40,189,218,46,247,110,222, +103,31,70,185,7,218,38,120,14,31,247,35,85,43,236,60,197,243,230,35,181,81,164,42,176,47,241,155,64,144,29,180,46,227,227,200, +134,143,7,104,247,109,149,52,124,123,132,134,239,8,210,206,15,212,209,240,7,107,104,248,206,106,138,252,247,206,227,81,188,217, +162,157,199,44,188,165,138,134,143,133,104,251,13,149,148,184,49,66,137,155,130,180,21,87,255,196,45,33,242,30,247,222,125, +200,235,87,53,122,209,115,77,221,8,170,103,203,248,75,96,110,171,68,108,122,69,140,52,194,158,231,241,225,107,70,12,44,195,58, +118,172,1,188,35,232,107,245,53,145,247,198,86,79,19,69,124,78,236,66,156,4,78,108,49,253,30,207,139,240,108,244,189,7,90,43, +206,129,160,22,209,219,186,150,220,16,167,117,62,77,111,244,235,176,55,211,41,10,152,203,205,118,97,115,112,57,246,81,192,183, +228,230,70,145,142,248,29,92,17,79,153,65,198,83,47,251,77,230,196,98,40,17,244,114,79,47,60,151,251,48,139,125,23,83,141,247, +101,93,103,93,63,72,156,13,161,214,165,104,195,210,96,132,34,245,78,108,9,215,67,60,70,23,34,166,130,134,131,15,47,63,70,42, +138,216,170,242,132,68,84,120,208,171,16,53,250,253,232,89,13,234,159,235,147,119,156,43,249,140,178,89,251,170,113,46,4,160,31, +153,45,239,23,253,225,90,138,132,219,81,131,247,227,236,11,222,115,222,31,177,95,121,255,232,243,90,164,249,170,200,231,143,208, +161,128,41,198,238,226,240,127,77,86,135,251,10,93,175,133,88,132,186,222,150,99,91,37,235,109,172,16,49,30,166,7,103,243, +25,198,216,251,78,178,72,77,68,79,60,236,167,102,35,113,186,2,173,27,132,71,64,91,138,245,209,98,176,69,149,90,36,50,30,11,226, +28,9,106,195,167,195,148,56,93,67,17,51,241,136,23,158,139,248,136,120,7,189,154,41,173,107,52,205,92,124,253,63,82,68,155, +94,130,251,198,81,107,80,203,89,171,149,92,195,165,153,179,86,96,133,242,183,61,71,57,235,18,232,65,214,202,218,160,95,202,35, +5,246,55,39,115,214,42,165,191,54,153,120,164,26,35,215,128,104,237,194,188,21,189,90,181,40,230,160,27,187,110,80,107,244,121, +132,126,61,226,164,209,175,81,177,116,171,86,67,7,99,98,39,214,74,190,84,244,213,28,107,158,104,153,19,107,199,154,43,175,185, +209,27,128,87,19,229,208,206,139,181,179,147,165,26,99,20,241,230,98,43,145,35,61,15,90,13,178,14,171,81,140,225,206,211,81, +234,186,51,36,198,177,155,118,79,134,212,88,44,18,185,75,174,111,147,163,233,73,124,82,90,49,18,230,160,169,121,164,87,47,188, +102,206,151,245,45,158,156,121,46,186,105,217,100,72,107,49,230,106,33,45,113,230,221,30,30,115,238,59,230,180,155,226,40,209, +77,61,147,168,121,85,55,121,39,249,254,225,199,174,84,45,246,80,175,184,7,243,216,233,16,123,86,181,248,172,113,29,210,95,20, +123,79,72,156,177,252,204,255,190,242,251,23,101,255,55,149,254,79,149,126,83,236,218,140,254,42,234,173,38,31,147,118,227,186, +208,23,216,235,236,186,206,175,176,55,24,189,206,232,13,118,109,231,77,154,48,122,49,14,252,76,249,205,108,249,121,39,162,37, +182,249,168,89,79,92,33,163,149,81,128,45,101,136,86,221,219,134,83,226,138,0,181,99,79,31,239,99,148,48,115,177,181,248,140, +131,29,231,138,90,228,39,240,204,89,27,196,30,212,202,194,212,245,219,16,107,209,231,50,236,78,109,93,255,33,158,191,144,103, +105,3,124,248,186,243,225,189,115,213,62,171,81,167,86,221,61,167,167,6,186,23,173,15,97,48,248,157,161,26,31,110,34,161,67,172, +2,253,9,88,23,91,134,176,84,90,47,135,66,204,7,219,86,102,209,133,205,255,51,201,245,4,195,124,232,107,170,152,94,205,122,25, +191,93,46,178,106,168,154,45,80,58,198,150,197,149,14,127,118,129,208,47,176,126,170,74,87,83,163,190,1,209,216,129,27,118,128, +189,28,102,129,146,29,177,220,55,135,22,134,3,149,23,189,241,172,242,231,243,126,129,232,175,99,45,231,210,95,244,119,250,230, +210,47,43,131,21,197,221,245,20,181,7,161,245,245,211,29,21,220,55,136,216,88,116,247,71,167,222,27,209,133,230,65,73,171,19, +99,20,240,56,125,179,105,161,71,88,17,43,62,92,45,155,35,210,187,124,94,42,197,104,180,68,186,105,98,18,163,29,193,104,7,184, +165,155,198,203,218,216,11,111,158,218,174,87,146,124,79,68,74,35,40,228,86,179,78,166,189,33,196,76,53,21,79,18,110,27,70,13, +188,254,149,147,178,102,174,175,154,36,113,63,159,139,150,222,172,246,191,7,196,60,122,232,35,144,94,104,252,222,199,119,255, +103,85,90,167,251,176,69,158,98,215,205,122,158,221,199,72,221,98,136,110,239,144,123,232,182,88,149,248,28,91,180,223,213,33, +99,101,107,44,138,59,187,53,117,158,61,208,33,239,75,17,236,232,126,120,123,248,59,59,228,103,67,156,137,123,176,211,106,137, +100,152,150,50,63,113,25,209,157,149,117,116,240,134,0,181,104,203,209,158,109,123,170,232,184,231,201,85,187,32,43,9,99,166, +97,204,88,215,239,24,201,187,149,71,173,161,70,21,151,179,166,206,255,6,22,106,226,49,203,16,157,26,125,185,67,126,119,208,142, +18,137,131,184,127,228,176,23,231,241,78,23,183,151,66,45,29,50,121,77,137,156,104,207,193,10,138,84,59,177,33,196,85,132,13, +195,187,69,107,55,27,17,25,243,81,151,99,245,16,191,33,201,182,68,196,141,136,137,239,39,152,248,153,131,55,200,27,234,139,101, +125,231,223,37,242,127,26,149,164,27,144,99,121,20,242,198,128,188,51,22,191,23,224,231,215,201,128,28,211,83,144,15,169,252, +242,187,47,207,55,85,61,126,37,249,247,7,103,149,111,135,170,175,78,201,168,122,111,81,198,85,125,113,85,167,159,228,103,157, +184,240,232,19,159,95,162,170,236,130,178,182,149,247,193,162,26,97,55,84,155,75,229,163,194,62,79,249,241,207,160,140,228,189, +83,182,33,42,202,52,193,210,131,222,116,43,123,179,42,23,167,226,120,48,12,111,23,225,194,198,150,145,182,44,70,108,128,204,129, +180,147,118,87,144,182,162,159,60,43,250,187,119,144,181,58,235,56,246,136,155,206,58,49,59,151,203,230,40,12,139,107,59,110, +239,144,237,236,115,71,169,118,77,58,63,50,229,180,181,224,56,201,61,25,155,216,6,210,54,12,145,190,97,104,3,121,240,192,126, +184,145,170,55,22,70,236,245,137,196,150,109,110,206,78,142,45,216,159,60,148,36,54,68,26,156,116,238,163,13,161,200,16,30,222, +161,161,93,67,67,168,32,160,20,174,107,67,187,168,126,40,233,164,114,217,116,42,238,218,19,110,60,129,199,118,55,157,201,247, +83,108,104,36,59,22,207,141,229,51,241,253,120,77,124,250,187,58,22,246,211,226,243,123,204,216,145,126,106,57,111,169,126,106, +31,74,37,51,135,210,7,226,73,199,201,186,73,94,56,190,214,25,201,100,243,105,103,223,234,76,50,143,182,205,62,159,207,38,219, +29,205,166,248,139,222,237,180,1,237,201,169,74,218,102,200,223,100,143,237,81,14,54,92,154,103,112,217,150,222,231,36,221,66, +14,93,105,156,33,59,49,154,203,30,22,69,249,108,196,211,217,248,170,194,222,189,118,206,78,109,112,198,11,110,177,151,181,83, +217,27,54,175,157,24,177,199,121,225,105,230,114,239,186,41,243,230,130,91,102,175,151,246,76,210,217,23,95,61,154,204,109,179, +15,22,108,103,196,158,170,72,228,148,213,95,93,102,222,128,184,219,103,231,248,76,79,55,230,114,133,113,215,78,149,21,171,41, +247,128,131,156,201,72,153,117,243,158,253,152,232,233,158,165,57,47,247,68,219,49,73,211,219,46,109,114,160,250,169,97,134,156, +116,38,197,179,202,43,194,72,219,201,212,244,174,138,209,151,239,108,146,102,199,118,227,235,93,119,124,251,214,161,210,218, +235,167,112,41,23,57,83,173,81,233,114,79,213,163,2,86,133,236,187,155,69,67,172,50,235,80,58,239,78,53,67,88,54,37,199,59,214, +58,110,238,72,63,109,154,201,60,240,238,241,120,71,125,51,120,172,192,15,85,78,175,110,186,97,155,237,242,176,47,25,176,254,70, +10,185,28,182,151,248,234,100,38,35,118,146,214,243,231,247,83,207,255,231,128,192,130,15,31,149,178,208,232,158,217,123,237, +132,61,82,120,135,107,231,249,92,179,8,222,220,161,52,143,221,216,249,253,242,83,115,251,78,143,117,5,190,46,139,75,111,230,220, +126,26,56,95,246,192,121,151,45,38,160,99,230,210,50,24,215,37,71,208,64,204,250,252,153,189,16,59,99,233,145,248,165,66,172, +202,102,51,118,18,227,50,111,102,231,76,118,228,64,62,190,213,134,158,75,58,238,16,146,253,228,135,16,83,176,140,216,14,210,118, +96,143,223,129,61,126,7,246,120,19,15,190,215,35,177,139,2,59,202,246,249,29,187,136,237,34,109,215,70,0,57,188,10,108,160, +234,225,25,86,165,182,219,161,64,114,100,196,206,231,59,250,250,250,168,66,234,235,50,201,125,121,242,38,83,169,28,82,100,38, +199,199,109,39,69,222,61,201,188,189,61,151,33,115,143,24,45,242,140,32,140,200,28,17,177,66,6,223,145,109,242,99,195,31,79,230, +236,68,150,188,234,68,160,64,233,104,160,186,146,158,200,150,78,13,178,70,48,166,174,93,90,140,69,139,156,42,62,32,69,75,233,0, +41,90,100,74,248,84,170,17,45,14,29,153,41,123,36,155,178,169,38,101,239,77,22,50,238,180,201,227,185,25,219,181,41,144,42, +53,165,54,53,227,169,92,61,205,44,171,33,127,42,171,154,76,204,38,131,79,223,17,242,9,129,5,10,77,197,49,25,123,211,118,38,5, +145,41,228,71,73,223,135,204,26,60,138,11,13,47,80,93,10,195,186,150,223,22,84,186,18,233,245,120,149,157,91,199,107,200,11,135, +178,56,37,19,233,65,251,136,112,44,63,49,168,2,134,45,56,37,197,48,240,220,173,118,126,60,235,228,49,200,24,15,94,77,2,7,89,70, +221,69,120,53,216,13,201,7,185,35,153,41,216,100,141,38,243,171,16,145,170,141,54,66,0,150,203,113,107,160,138,81,209,162,161, +180,99,35,82,100,34,79,65,165,36,178,219,17,9,225,81,236,196,91,249,33,149,119,87,143,165,168,122,122,90,58,5,184,81,181,151, +165,201,155,118,82,246,196,230,189,84,145,46,235,161,47,237,168,38,85,164,243,107,39,70,147,133,188,203,91,147,206,139,113,32, +51,157,71,63,93,158,203,165,172,217,151,86,251,55,121,246,103,211,136,131,140,236,167,135,47,53,242,56,201,49,76,169,99,31,94, +157,28,25,181,83,114,58,183,96,149,82,136,27,75,97,88,129,100,41,152,144,192,43,132,228,75,193,227,240,209,208,157,2,26,137, +199,170,35,46,198,163,6,218,186,108,38,147,61,108,167,182,218,169,116,14,53,73,235,84,42,145,149,14,212,48,147,85,141,95,22, +203,174,172,33,122,22,93,213,199,241,118,15,30,11,197,115,17,249,198,139,51,204,53,119,77,210,77,82,168,168,201,138,60,34,82,189, +57,68,58,86,48,85,230,84,24,172,87,211,86,243,14,131,44,101,194,138,229,66,122,174,128,119,231,17,175,85,120,168,246,36,210,99, +54,111,78,5,76,107,178,50,234,168,49,207,3,51,239,242,112,145,29,41,245,158,59,78,197,98,56,207,99,49,153,42,214,98,137,180, +8,12,121,159,163,72,201,178,37,135,113,200,185,71,200,200,143,103,210,46,132,155,204,97,206,33,220,66,158,2,82,138,144,174,44, +233,178,15,193,188,8,32,117,84,152,249,194,158,49,212,224,135,204,139,45,144,66,238,104,249,150,83,205,147,239,220,117,74,198, +178,109,38,12,99,249,34,172,68,122,91,249,203,60,238,104,26,113,194,159,29,125,228,119,209,85,12,211,38,44,223,41,85,197,169, +155,149,251,49,85,184,101,203,177,142,159,3,249,189,217,220,152,157,186,188,44,2,189,216,89,68,11,204,130,35,34,185,226,80,50, +211,81,92,9,198,33,177,76,140,195,57,68,63,105,19,125,116,55,211,190,205,200,27,166,251,249,115,114,217,0,44,60,249,184,102, +156,99,223,100,207,179,231,240,137,219,248,7,54,111,157,55,60,208,203,255,209,211,26,28,78,44,31,76,183,238,30,28,30,188,106,88, +27,111,94,219,118,142,122,252,187,239,101,143,178,91,217,119,217,55,216,99,236,12,187,157,121,195,218,95,180,254,137,137,35,218, +245,215,156,17,133,123,7,6,135,88,164,146,58,217,143,144,75,59,205,221,247,176,191,99,39,216,119,132,247,43,186,231,195,172, +121,112,224,146,3,186,118,11,91,196,152,174,127,128,177,229,39,116,243,17,198,62,57,161,179,195,245,39,116,239,15,89,125,90,59, +212,111,48,195,171,133,251,13,115,120,193,208,130,65,221,248,36,179,6,46,49,140,22,67,51,244,86,157,242,77,3,180,210,63,85, +253,223,179,207,177,79,176,219,240,146,222,57,172,42,138,54,247,106,21,253,109,244,54,122,187,113,249,45,90,111,143,182,179,89, +171,56,252,196,196,181,172,209,242,48,183,189,255,57,214,80,201,234,67,43,126,201,234,171,13,198,171,12,227,216,52,136,107, +115,79,60,126,213,247,250,180,150,31,24,164,237,233,63,215,113,191,102,245,211,29,140,221,205,188,205,168,173,182,71,27,107,254, +105,219,93,43,209,5,202,215,180,182,24,36,180,206,86,250,52,31,222,94,221,250,60,139,183,233,161,211,140,13,245,106,207,80, +143,97,105,151,54,155,214,173,71,244,170,175,51,198,234,171,206,233,225,179,232,180,94,249,41,198,22,156,211,253,7,234,111,215, +43,30,100,245,187,116,223,85,45,187,244,224,71,89,203,144,174,189,200,234,227,204,178,142,60,172,133,118,26,214,74,244,221, +103,4,91,245,64,190,73,115,54,26,1,83,51,125,102,208,180,222,207,90,106,47,106,53,3,116,171,206,39,247,131,226,121,143,120,254, +94,211,222,251,113,12,75,155,78,15,97,172,7,39,218,123,247,107,19,205,3,244,75,62,205,127,208,105,220,88,190,127,160,117,151, +110,30,156,53,208,96,152,116,74,103,31,225,115,167,121,217,15,88,99,80,243,105,187,60,116,138,181,104,1,164,155,140,104,111,116, +121,212,136,118,68,189,90,5,55,96,4,139,74,149,102,66,169,55,68,17,223,41,22,173,144,101,60,209,213,170,132,72,250,163,44, +186,56,218,25,93,143,170,100,134,79,243,203,26,60,197,170,58,73,99,26,157,140,49,252,63,118,204,243,88,173,198,190,95,203,158, +137,61,84,71,6,99,26,50,197,15,121,142,31,243,60,85,103,176,223,212,81,149,233,245,106,44,34,126,68,30,211,166,253,136,180,9, +255,199,234,217,137,216,203,13,90,228,205,6,214,240,251,89,44,242,66,19,139,28,107,247,85,157,156,109,84,189,221,201,170,78, +206,101,85,103,193,83,224,177,46,86,117,166,91,254,125,4,149,125,223,192,101,241,239,183,248,119,4,197,191,225,42,126,119,193, +255,142,139,127,79,82,252,91,46,254,189,66,241,239,185,76,42,253,77,151,110,201,223,193,241,239,98,88,76,254,254,247,49,254,29, +74,76,250,240,223,33,50,171,244,123,69,45,38,223,203,255,6,76,87,254,252,247,120,158,24,137,223,63,241,223,17,146,42,43,126, +247,104,201,182,242,191,55,251,63,108,101,104,241,168,38,0,0,0,0}; #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ METHOD (constructor, "<init>", "()V") \ @@ -193,7 +186,7 @@ DECLARE_JNI_CLASS (StringBuffer, "java/lang/StringBuffer") //============================================================================== #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ - STATICMETHOD (createHTTPStream, "createHTTPStream", "(Ljava/lang/String;Z[BLjava/lang/String;I[ILjava/lang/StringBuffer;ILjava/lang/String;)Lcom/roli/juce/JuceHTTPStream;") \ + STATICMETHOD (createHTTPStream, "createHTTPStream", "(Ljava/lang/String;Z[BLjava/lang/String;I[ILjava/lang/StringBuffer;ILjava/lang/String;)Lcom/rmsl/juce/JuceHTTPStream;") \ METHOD (connect, "connect", "()Z") \ METHOD (release, "release", "()V") \ METHOD (read, "read", "([BI)I") \ @@ -202,7 +195,7 @@ DECLARE_JNI_CLASS (StringBuffer, "java/lang/StringBuffer") METHOD (isExhausted, "isExhausted", "()Z") \ METHOD (setPosition, "setPosition", "(J)Z") \ -DECLARE_JNI_CLASS_WITH_BYTECODE (HTTPStream, "com/roli/juce/JuceHTTPStream", 16, javaJuceHttpStream, sizeof(javaJuceHttpStream)) +DECLARE_JNI_CLASS_WITH_BYTECODE (HTTPStream, "com/rmsl/juce/JuceHTTPStream", 16, javaJuceHttpStream, sizeof(javaJuceHttpStream)) #undef JNI_CLASS_MEMBERS //============================================================================== @@ -554,7 +547,7 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Pimpl) }; -URL::DownloadTask* URL::downloadToFile (const File& targetLocation, String extraHeaders, DownloadTask::Listener* listener, bool shouldUsePost) +std::unique_ptr<URL::DownloadTask> URL::downloadToFile (const File& targetLocation, String extraHeaders, DownloadTask::Listener* listener, bool shouldUsePost) { return URL::DownloadTask::createFallbackDownloader (*this, targetLocation, extraHeaders, listener, shouldUsePost); } diff --git a/modules/juce_core/native/juce_android_RuntimePermissions.cpp b/modules/juce_core/native/juce_android_RuntimePermissions.cpp index d4b1acf0..6d7f18fc 100644 --- a/modules/juce_core/native/juce_android_RuntimePermissions.cpp +++ b/modules/juce_core/native/juce_android_RuntimePermissions.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -28,11 +28,11 @@ static String jucePermissionToAndroidPermission (RuntimePermissions::PermissionI { switch (permission) { - case RuntimePermissions::recordAudio: return "android.permission.RECORD_AUDIO"; - case RuntimePermissions::bluetoothMidi: return "android.permission.ACCESS_COARSE_LOCATION"; - case RuntimePermissions::readExternalStorage: return "android.permission.READ_EXTERNAL_STORAGE"; - case RuntimePermissions::writeExternalStorage: return "android.permission.WRITE_EXTERNAL_STORAGE"; - case RuntimePermissions::camera: return "android.permission.CAMERA"; + case RuntimePermissions::recordAudio: return "android.permission.RECORD_AUDIO"; + case RuntimePermissions::bluetoothMidi: return "android.permission.ACCESS_FINE_LOCATION"; + case RuntimePermissions::readExternalStorage: return "android.permission.READ_EXTERNAL_STORAGE"; + case RuntimePermissions::writeExternalStorage: return "android.permission.WRITE_EXTERNAL_STORAGE"; + case RuntimePermissions::camera: return "android.permission.CAMERA"; } // invalid permission @@ -42,11 +42,11 @@ static String jucePermissionToAndroidPermission (RuntimePermissions::PermissionI static RuntimePermissions::PermissionID androidPermissionToJucePermission (const String& permission) { - if (permission == "android.permission.RECORD_AUDIO") return RuntimePermissions::recordAudio; - else if (permission == "android.permission.ACCESS_COARSE_LOCATION") return RuntimePermissions::bluetoothMidi; - else if (permission == "android.permission.READ_EXTERNAL_STORAGE") return RuntimePermissions::readExternalStorage; - else if (permission == "android.permission.WRITE_EXTERNAL_STORAGE") return RuntimePermissions::writeExternalStorage; - else if (permission == "android.permission.CAMERA") return RuntimePermissions::camera; + if (permission == "android.permission.RECORD_AUDIO") return RuntimePermissions::recordAudio; + else if (permission == "android.permission.ACCESS_FINE_LOCATION") return RuntimePermissions::bluetoothMidi; + else if (permission == "android.permission.READ_EXTERNAL_STORAGE") return RuntimePermissions::readExternalStorage; + else if (permission == "android.permission.WRITE_EXTERNAL_STORAGE") return RuntimePermissions::writeExternalStorage; + else if (permission == "android.permission.CAMERA") return RuntimePermissions::camera; return static_cast<RuntimePermissions::PermissionID> (-1); } diff --git a/modules/juce_core/native/juce_android_SystemStats.cpp b/modules/juce_core/native/juce_android_SystemStats.cpp index aa031b85..32248e07 100644 --- a/modules/juce_core/native/juce_android_SystemStats.cpp +++ b/modules/juce_core/native/juce_android_SystemStats.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -40,14 +40,14 @@ namespace AndroidStatsHelpers DECLARE_JNI_CLASS (JavaLocale, "java/util/Locale") #undef JNI_CLASS_MEMBERS - static inline String getSystemProperty (const String& name) + static String getSystemProperty (const String& name) { return juceString (LocalRef<jstring> ((jstring) getEnv()->CallStaticObjectMethod (SystemClass, SystemClass.getProperty, javaString (name).get()))); } - static inline String getLocaleValue (bool isRegion) + static String getLocaleValue (bool isRegion) { auto* env = getEnv(); LocalRef<jobject> locale (env->CallStaticObjectMethod (JavaLocale, JavaLocale.getDefault)); @@ -58,7 +58,7 @@ namespace AndroidStatsHelpers return juceString (LocalRef<jstring> ((jstring) stringResult)); } - static inline String getAndroidOsBuildValue (const char* fieldName) + static String getAndroidOsBuildValue (const char* fieldName) { return juceString (LocalRef<jstring> ((jstring) getEnv()->GetStaticObjectField ( AndroidBuild, getEnv()->GetStaticFieldID (AndroidBuild, fieldName, "Ljava/lang/String;")))); diff --git a/modules/juce_core/native/juce_android_Threads.cpp b/modules/juce_core/native/juce_android_Threads.cpp index 1b72686d..f9ba13b0 100644 --- a/modules/juce_core/native/juce_android_Threads.cpp +++ b/modules/juce_core/native/juce_android_Threads.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -71,7 +71,7 @@ extern "C" jint JNIEXPORT JNI_OnLoad (JavaVM* vm, void*) auto* env = getEnv(); // register the initialisation function - auto juceJavaClass = env->FindClass("com/roli/juce/Java"); + auto juceJavaClass = env->FindClass("com/rmsl/juce/Java"); if (juceJavaClass != nullptr) { @@ -83,7 +83,7 @@ extern "C" jint JNIEXPORT JNI_OnLoad (JavaVM* vm, void*) } else { - // com.roli.juce.Java class not found. Apparently this project is a library + // com.rmsl.juce.Java class not found. Apparently this project is a library // or was not generated by the Projucer. That's ok, the user will have to // call Thread::initialiseJUCE manually env->ExceptionClear(); diff --git a/modules/juce_core/native/juce_curl_Network.cpp b/modules/juce_core/native/juce_curl_Network.cpp index 27430b65..00d42835 100644 --- a/modules/juce_core/native/juce_curl_Network.cpp +++ b/modules/juce_core/native/juce_curl_Network.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -642,7 +642,7 @@ public: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Pimpl) }; -URL::DownloadTask* URL::downloadToFile (const File& targetLocation, String extraHeaders, DownloadTask::Listener* listener, bool shouldUsePost) +std::unique_ptr<URL::DownloadTask> URL::downloadToFile (const File& targetLocation, String extraHeaders, DownloadTask::Listener* listener, bool shouldUsePost) { return URL::DownloadTask::createFallbackDownloader (*this, targetLocation, extraHeaders, listener, shouldUsePost); } diff --git a/modules/juce_core/native/juce_linux_CommonFile.cpp b/modules/juce_core/native/juce_linux_CommonFile.cpp index d2d75e26..b0a85a3c 100644 --- a/modules/juce_core/native/juce_linux_CommonFile.cpp +++ b/modules/juce_core/native/juce_linux_CommonFile.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/native/juce_linux_Files.cpp b/modules/juce_core/native/juce_linux_Files.cpp index c51a97e6..d2a302e3 100644 --- a/modules/juce_core/native/juce_linux_Files.cpp +++ b/modules/juce_core/native/juce_linux_Files.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -136,7 +136,8 @@ File File::getSpecialLocation (const SpecialLocationType type) case invokedExecutableFile: if (juce_argv != nullptr && juce_argc > 0) return File (CharPointer_UTF8 (juce_argv[0])); - // deliberate fall-through... + // Falls through + JUCE_FALLTHROUGH case currentExecutableFile: case currentApplicationFile: @@ -144,6 +145,7 @@ File File::getSpecialLocation (const SpecialLocationType type) return juce_getExecutableFile(); #endif // deliberate fall-through if this is not a shared-library + JUCE_FALLTHROUGH case hostApplicationPath: { diff --git a/modules/juce_core/native/juce_linux_Network.cpp b/modules/juce_core/native/juce_linux_Network.cpp index 61e6f3a3..f3231391 100644 --- a/modules/juce_core/native/juce_linux_Network.cpp +++ b/modules/juce_core/native/juce_linux_Network.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -333,7 +333,7 @@ private: struct addrinfo* result = nullptr; - if (getaddrinfo (serverName.toUTF8(), String (port).toUTF8(), &hints, &result) != 0 || result == 0) + if (getaddrinfo (serverName.toUTF8(), String (port).toUTF8(), &hints, &result) != 0 || result == nullptr) return 0; { @@ -351,7 +351,7 @@ private: int receiveBufferSize = 16384; setsockopt (socketHandle, SOL_SOCKET, SO_RCVBUF, (char*) &receiveBufferSize, sizeof (receiveBufferSize)); - setsockopt (socketHandle, SOL_SOCKET, SO_KEEPALIVE, 0, 0); + setsockopt (socketHandle, SOL_SOCKET, SO_KEEPALIVE, nullptr, 0); #if JUCE_MAC setsockopt (socketHandle, SOL_SOCKET, SO_NOSIGPIPE, 0, 0); @@ -576,7 +576,7 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Pimpl) }; -URL::DownloadTask* URL::downloadToFile (const File& targetLocation, String extraHeaders, DownloadTask::Listener* listener, bool shouldUsePost) +std::unique_ptr<URL::DownloadTask> URL::downloadToFile (const File& targetLocation, String extraHeaders, DownloadTask::Listener* listener, bool shouldUsePost) { return URL::DownloadTask::createFallbackDownloader (*this, targetLocation, extraHeaders, listener, shouldUsePost); } diff --git a/modules/juce_core/native/juce_linux_SystemStats.cpp b/modules/juce_core/native/juce_linux_SystemStats.cpp index 7ba2b5ef..cd3068e6 100644 --- a/modules/juce_core/native/juce_linux_SystemStats.cpp +++ b/modules/juce_core/native/juce_linux_SystemStats.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -54,7 +54,7 @@ bool SystemStats::isOperatingSystem64Bit() } //============================================================================== -static inline String getCpuInfo (const char* key) +static String getCpuInfo (const char* key) { return readPosixConfigFileValue ("/proc/cpuinfo", key); } @@ -209,14 +209,14 @@ int64 Time::getHighResolutionTicksPerSecond() noexcept double Time::getMillisecondCounterHiRes() noexcept { - return getHighResolutionTicks() * 0.001; + return (double) getHighResolutionTicks() * 0.001; } bool Time::setSystemTimeToThisTime() const { timeval t; - t.tv_sec = millisSinceEpoch / 1000; - t.tv_usec = (millisSinceEpoch - t.tv_sec * 1000) * 1000; + t.tv_sec = decltype (timeval::tv_sec) (millisSinceEpoch / 1000); + t.tv_usec = decltype (timeval::tv_usec) ((millisSinceEpoch - t.tv_sec * 1000) * 1000); return settimeofday (&t, nullptr) == 0; } diff --git a/modules/juce_core/native/juce_linux_Threads.cpp b/modules/juce_core/native/juce_linux_Threads.cpp index 11ea9c5a..7c4c8896 100644 --- a/modules/juce_core/native/juce_linux_Threads.cpp +++ b/modules/juce_core/native/juce_linux_Threads.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/native/juce_mac_ClangBugWorkaround.h b/modules/juce_core/native/juce_mac_ClangBugWorkaround.h index eb02c171..4cb8b63a 100644 --- a/modules/juce_core/native/juce_mac_ClangBugWorkaround.h +++ b/modules/juce_core/native/juce_mac_ClangBugWorkaround.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/native/juce_mac_Files.mm b/modules/juce_core/native/juce_mac_Files.mm index 53031211..7766283b 100644 --- a/modules/juce_core/native/juce_mac_Files.mm +++ b/modules/juce_core/native/juce_mac_Files.mm @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -203,6 +203,7 @@ File File::getSpecialLocation (const SpecialLocationType type) if (juce_argv != nullptr && juce_argc > 0) return File::getCurrentWorkingDirectory().getChildFile (String (juce_argv[0])); // deliberate fall-through... + JUCE_FALLTHROUGH case currentExecutableFile: return juce_getExecutableFile(); @@ -424,13 +425,23 @@ bool JUCE_CALLTYPE Process::openDocument (const String& fileName, const String& StringArray params; params.addTokens (parameters, true); - NSMutableDictionary* dict = [[NSMutableDictionary new] autorelease]; - NSMutableArray* paramArray = [[NSMutableArray new] autorelease]; for (int i = 0; i < params.size(); ++i) [paramArray addObject: juceStringToNS (params[i])]; + #if (defined MAC_OS_X_VERSION_10_15) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_15 + auto config = [NSWorkspaceOpenConfiguration configuration]; + [config setCreatesNewApplicationInstance: YES]; + config.arguments = paramArray; + + [workspace openApplicationAtURL: filenameAsURL + configuration: config + completionHandler: nil]; + return true; + #else + NSMutableDictionary* dict = [[NSMutableDictionary new] autorelease]; + [dict setObject: paramArray forKey: nsStringLiteral ("NSWorkspaceLaunchConfigurationArguments")]; @@ -438,6 +449,7 @@ bool JUCE_CALLTYPE Process::openDocument (const String& fileName, const String& options: NSWorkspaceLaunchDefault | NSWorkspaceLaunchNewInstance configuration: dict error: nil]; + #endif } if (file.exists()) diff --git a/modules/juce_core/native/juce_mac_Network.mm b/modules/juce_core/native/juce_mac_Network.mm index d86baf45..a092a583 100644 --- a/modules/juce_core/native/juce_mac_Network.mm +++ b/modules/juce_core/native/juce_mac_Network.mm @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -192,11 +192,11 @@ public: while (numBytes > 0) { - const int available = jmin (numBytes, (int) [data length]); + const ScopedLock sl (dataLock); + auto available = jmin (numBytes, (int) [data length]); if (available > 0) { - const ScopedLock sl (dataLock); [data getBytes: dest length: (NSUInteger) available]; [data replaceBytesInRange: NSMakeRange (0, (NSUInteger) available) withBytes: nil length: 0]; @@ -209,6 +209,7 @@ public: if (hasFailed || hasFinished) break; + const ScopedUnlock ul (dataLock); Thread::sleep (1); } } @@ -647,12 +648,12 @@ struct BackgroundDownloadTask : public URL::DownloadTask HashMap<String, BackgroundDownloadTask*, DefaultHashFunctions, CriticalSection> BackgroundDownloadTask::activeSessions; -URL::DownloadTask* URL::downloadToFile (const File& targetLocation, String extraHeaders, DownloadTask::Listener* listener, bool usePostRequest) +std::unique_ptr<URL::DownloadTask> URL::downloadToFile (const File& targetLocation, String extraHeaders, DownloadTask::Listener* listener, bool usePostRequest) { std::unique_ptr<BackgroundDownloadTask> downloadTask (new BackgroundDownloadTask (*this, targetLocation, extraHeaders, listener, usePostRequest)); if (downloadTask->initOK() && downloadTask->connect()) - return downloadTask.release(); + return downloadTask; return nullptr; } @@ -662,7 +663,7 @@ void URL::DownloadTask::juce_iosURLSessionNotify (const String& identifier) BackgroundDownloadTask::invokeNotify (identifier); } #else -URL::DownloadTask* URL::downloadToFile (const File& targetLocation, String extraHeaders, DownloadTask::Listener* listener, bool usePost) +std::unique_ptr<URL::DownloadTask> URL::downloadToFile (const File& targetLocation, String extraHeaders, DownloadTask::Listener* listener, bool usePost) { return URL::DownloadTask::createFallbackDownloader (*this, targetLocation, extraHeaders, listener, usePost); } @@ -675,8 +676,7 @@ URL::DownloadTask* URL::downloadToFile (const File& targetLocation, String extra // so we'll turn off deprecation warnings. This code will be removed at some point // in the future. -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated" +JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wdeprecated") //============================================================================== class URLConnectionState : public Thread @@ -747,11 +747,11 @@ public: while (numBytes > 0) { - const int available = jmin (numBytes, (int) [data length]); + const ScopedLock sl (dataLock); + auto available = jmin (numBytes, (int) [data length]); if (available > 0) { - const ScopedLock sl (dataLock); [data getBytes: dest length: (NSUInteger) available]; [data replaceBytesInRange: NSMakeRange (0, (NSUInteger) available) withBytes: nil length: 0]; @@ -764,6 +764,7 @@ public: if (hasFailed || hasFinished) break; + const ScopedUnlock sul (dataLock); Thread::sleep (1); } } @@ -928,12 +929,12 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (URLConnectionState) }; -URL::DownloadTask* URL::downloadToFile (const File& targetLocation, String extraHeaders, DownloadTask::Listener* listener, bool shouldUsePost) +std::unique_ptr<URL::DownloadTask> URL::downloadToFile (const File& targetLocation, String extraHeaders, DownloadTask::Listener* listener, bool shouldUsePost) { return URL::DownloadTask::createFallbackDownloader (*this, targetLocation, extraHeaders, listener, shouldUsePost); } -#pragma clang diagnostic pop +JUCE_END_IGNORE_WARNINGS_GCC_LIKE #endif diff --git a/modules/juce_core/native/juce_mac_Strings.mm b/modules/juce_core/native/juce_mac_Strings.mm index 68f53972..fff2c7c1 100644 --- a/modules/juce_core/native/juce_mac_Strings.mm +++ b/modules/juce_core/native/juce_mac_Strings.mm @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/native/juce_mac_SystemStats.mm b/modules/juce_core/native/juce_mac_SystemStats.mm index 58888608..202896a5 100644 --- a/modules/juce_core/native/juce_mac_SystemStats.mm +++ b/modules/juce_core/native/juce_mac_SystemStats.mm @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -121,10 +121,21 @@ static String getOSXVersion() { JUCE_AUTORELEASEPOOL { - NSDictionary* dict = [NSDictionary dictionaryWithContentsOfFile: - nsStringLiteral ("/System/Library/CoreServices/SystemVersion.plist")]; + const String systemVersionPlist ("/System/Library/CoreServices/SystemVersion.plist"); - return nsStringToJuce ([dict objectForKey: nsStringLiteral ("ProductVersion")]); + #if (defined (MAC_OS_X_VERSION_10_13) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_13) + NSError* error = nullptr; + NSDictionary* dict = [NSDictionary dictionaryWithContentsOfURL: createNSURLFromFile (systemVersionPlist) + error: &error]; + #else + NSDictionary* dict = [NSDictionary dictionaryWithContentsOfFile: juceStringToNS (systemVersionPlist)]; + #endif + + if (dict != nullptr) + return nsStringToJuce (dict[nsStringLiteral ("ProductVersion")]); + + jassertfalse; + return {}; } } #endif @@ -137,11 +148,17 @@ SystemStats::OperatingSystemType SystemStats::getOperatingSystemType() StringArray parts; parts.addTokens (getOSXVersion(), ".", StringRef()); - jassert (parts[0].getIntValue() == 10); - const int major = parts[1].getIntValue(); - jassert (major > 2); + const auto major = parts[0].getIntValue(); + const auto minor = parts[1].getIntValue(); - return (OperatingSystemType) (major + MacOSX_10_4 - 4); + if (major == 10) + { + jassert (minor > 2); + return (OperatingSystemType) (minor + MacOSX_10_7 - 7); + } + + jassert (major == 11 && minor == 0); + return MacOSX_11_0; #endif } @@ -199,10 +216,8 @@ bool SystemStats::isOperatingSystem64Bit() { #if JUCE_IOS return false; - #elif JUCE_64BIT - return true; #else - return getOperatingSystemType() >= MacOSX_10_6; + return true; #endif } diff --git a/modules/juce_core/native/juce_mac_Threads.mm b/modules/juce_core/native/juce_mac_Threads.mm index bd8084cf..63255fc1 100644 --- a/modules/juce_core/native/juce_mac_Threads.mm +++ b/modules/juce_core/native/juce_mac_Threads.mm @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/native/juce_osx_ObjCHelpers.h b/modules/juce_core/native/juce_osx_ObjCHelpers.h index fca46928..112c6402 100644 --- a/modules/juce_core/native/juce_osx_ObjCHelpers.h +++ b/modules/juce_core/native/juce_osx_ObjCHelpers.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -27,37 +27,37 @@ namespace juce { //============================================================================== -static inline String nsStringToJuce (NSString* s) +inline String nsStringToJuce (NSString* s) { return CharPointer_UTF8 ([s UTF8String]); } -static inline NSString* juceStringToNS (const String& s) +inline NSString* juceStringToNS (const String& s) { return [NSString stringWithUTF8String: s.toUTF8()]; } -static inline NSString* nsStringLiteral (const char* const s) noexcept +inline NSString* nsStringLiteral (const char* const s) noexcept { return [NSString stringWithUTF8String: s]; } -static inline NSString* nsEmptyString() noexcept +inline NSString* nsEmptyString() noexcept { return [NSString string]; } -static inline NSURL* createNSURLFromFile (const String& f) +inline NSURL* createNSURLFromFile (const String& f) { return [NSURL fileURLWithPath: juceStringToNS (f)]; } -static inline NSURL* createNSURLFromFile (const File& f) +inline NSURL* createNSURLFromFile (const File& f) { return createNSURLFromFile (f.getFullPathName()); } -static inline NSArray* createNSArrayFromStringArray (const StringArray& strings) +inline NSArray* createNSArrayFromStringArray (const StringArray& strings) { auto array = [[NSMutableArray alloc] init]; @@ -67,9 +67,9 @@ static inline NSArray* createNSArrayFromStringArray (const StringArray& strings) return [array autorelease]; } -static NSArray* varArrayToNSArray (const var& varToParse); +inline NSArray* varArrayToNSArray (const var& varToParse); -static NSDictionary* varObjectToNSDictionary (const var& varToParse) +inline NSDictionary* varObjectToNSDictionary (const var& varToParse) { auto dictionary = [NSMutableDictionary dictionary]; @@ -109,7 +109,7 @@ static NSDictionary* varObjectToNSDictionary (const var& varToParse) return dictionary; } -static NSArray* varArrayToNSArray (const var& varToParse) +inline NSArray* varArrayToNSArray (const var& varToParse) { jassert (varToParse.isArray()); @@ -145,9 +145,9 @@ static NSArray* varArrayToNSArray (const var& varToParse) return array; } -static var nsObjectToVar (NSObject* array); +var nsObjectToVar (NSObject* array); -static var nsDictionaryToVar (NSDictionary* dictionary) +inline var nsDictionaryToVar (NSDictionary* dictionary) { DynamicObject::Ptr dynamicObject (new DynamicObject()); @@ -157,7 +157,7 @@ static var nsDictionaryToVar (NSDictionary* dictionary) return var (dynamicObject.get()); } -static var nsArrayToVar (NSArray* array) +inline var nsArrayToVar (NSArray* array) { Array<var> resultArray; @@ -167,7 +167,7 @@ static var nsArrayToVar (NSArray* array) return var (resultArray); } -static var nsObjectToVar (NSObject* obj) +inline var nsObjectToVar (NSObject* obj) { if ([obj isKindOfClass: [NSString class]]) return nsStringToJuce ((NSString*) obj); else if ([obj isKindOfClass: [NSNumber class]]) return nsStringToJuce ([(NSNumber*) obj stringValue]); @@ -184,7 +184,7 @@ static var nsObjectToVar (NSObject* obj) #if JUCE_MAC template <typename RectangleType> -static NSRect makeNSRect (const RectangleType& r) noexcept +NSRect makeNSRect (const RectangleType& r) noexcept { return NSMakeRect (static_cast<CGFloat> (r.getX()), static_cast<CGFloat> (r.getY()), @@ -192,28 +192,40 @@ static NSRect makeNSRect (const RectangleType& r) noexcept static_cast<CGFloat> (r.getHeight())); } #endif -#if JUCE_MAC || JUCE_IOS -// This is necessary as on iOS builds, some arguments may be passed on registers -// depending on the argument type. The re-cast objc_msgSendSuper to a function -// take the same arguments as the target method. -template <typename ReturnValue, typename... Params> -static inline ReturnValue ObjCMsgSendSuper (struct objc_super* s, SEL sel, Params... params) -{ - using SuperFn = ReturnValue (*)(struct objc_super*, SEL, Params...); - SuperFn fn = reinterpret_cast<SuperFn> (objc_msgSendSuper); - return fn (s, sel, params...); -} +#if JUCE_INTEL + template <typename T> + struct NeedsStret + { + #if JUCE_32BIT + static constexpr auto value = sizeof (T) > 8; + #else + static constexpr auto value = sizeof (T) > 16; + #endif + }; + + template<> + struct NeedsStret<void> { static constexpr auto value = false; }; + + template <typename T, bool b = NeedsStret<T>::value> + struct MetaSuperFn { static constexpr auto value = objc_msgSendSuper_stret; }; + + template <typename T> + struct MetaSuperFn<T, false> { static constexpr auto value = objc_msgSendSuper; }; +#else + template <typename> + struct MetaSuperFn { static constexpr auto value = objc_msgSendSuper; }; +#endif -// These hacks are a workaround for newer Xcode builds which by default prevent calls to these objc functions.. -typedef id (*MsgSendSuperFn) (struct objc_super*, SEL, ...); -static inline MsgSendSuperFn getMsgSendSuperFn() noexcept { return (MsgSendSuperFn) (void*) objc_msgSendSuper; } +template <typename SuperType, typename ReturnType, typename... Params> +static ReturnType ObjCMsgSendSuper (id self, SEL sel, Params... params) +{ + using SuperFn = ReturnType (*) (struct objc_super*, SEL, Params...); + const auto fn = reinterpret_cast<SuperFn> (MetaSuperFn<ReturnType>::value); -#if ! JUCE_IOS -typedef double (*MsgSendFPRetFn) (id, SEL op, ...); -static inline MsgSendFPRetFn getMsgSendFPRetFn() noexcept { return (MsgSendFPRetFn) (void*) objc_msgSend_fpret; } -#endif -#endif + objc_super s = { self, [SuperType class] }; + return fn (&s, sel, params...); +} //============================================================================== struct NSObjectDeleter @@ -235,7 +247,10 @@ struct ObjCClass ~ObjCClass() { - objc_disposeClassPair (cls); + auto kvoSubclassName = String ("NSKVONotifying_") + class_getName (cls); + + if (objc_getClass (kvoSubclassName.toUTF8()) == nullptr) + objc_disposeClassPair (cls); } void registerClass() @@ -286,13 +301,11 @@ struct ObjCClass jassert (b); ignoreUnused (b); } - #if JUCE_MAC || JUCE_IOS - static id sendSuperclassMessage (id self, SEL selector) + template <typename ReturnType, typename... Params> + static ReturnType sendSuperclassMessage (id self, SEL sel, Params... params) { - objc_super s = { self, [SuperclassType class] }; - return getMsgSendSuperFn() (&s, selector); + return ObjCMsgSendSuper<SuperclassType, ReturnType, Params...> (self, sel, params...); } - #endif template <typename Type> static Type getIvar (id self, const char* name) @@ -323,25 +336,20 @@ struct ObjCLifetimeManagedClass : public ObjCClass<NSObject> { addIvar<JuceClass*> ("cppObject"); - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wundeclared-selector" + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wundeclared-selector") addMethod (@selector (initWithJuceObject:), initWithJuceObject, "@@:@"); - #pragma clang diagnostic pop + JUCE_END_IGNORE_WARNINGS_GCC_LIKE addMethod (@selector (dealloc), dealloc, "v@:"); - registerClass(); } static id initWithJuceObject (id _self, SEL, JuceClass* obj) { - NSObject* self = _self; - - objc_super s = { self, [NSObject class] }; - self = ObjCMsgSendSuper<NSObject*> (&s, @selector(init)); - + NSObject* self = sendSuperclassMessage<NSObject*> (_self, @selector (init)); object_setInstanceVariable (self, "cppObject", obj); + return self; } @@ -353,11 +361,9 @@ struct ObjCLifetimeManagedClass : public ObjCClass<NSObject> object_setInstanceVariable (_self, "cppObject", nullptr); } - objc_super s = { _self, [NSObject class] }; - ObjCMsgSendSuper<void> (&s, @selector(dealloc)); + sendSuperclassMessage<void> (_self, @selector (dealloc)); } - static ObjCLifetimeManagedClass objCLifetimeManagedClass; }; @@ -370,10 +376,9 @@ ObjCLifetimeManagedClass<Class> ObjCLifetimeManagedClass<Class>::objCLifetimeMan template <typename Class> NSObject* createNSObjectFromJuceClass (Class* obj) { - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wobjc-method-access" + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wobjc-method-access") return [ObjCLifetimeManagedClass<Class>::objCLifetimeManagedClass.createInstance() initWithJuceObject:obj]; - #pragma clang diagnostic pop + JUCE_END_IGNORE_WARNINGS_GCC_LIKE } // Get the JUCE class instance that was tied to the life-time of an NSObject with the diff --git a/modules/juce_core/native/juce_posix_IPAddress.h b/modules/juce_core/native/juce_posix_IPAddress.h index 9cdb7724..41c83cd3 100644 --- a/modules/juce_core/native/juce_posix_IPAddress.h +++ b/modules/juce_core/native/juce_posix_IPAddress.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -71,8 +71,8 @@ namespace { if (ifa->ifa_addr->sa_family == AF_INET) { - auto interfaceAddressInfo = reinterpret_cast<sockaddr_in*> (ifa->ifa_addr); - auto broadcastAddressInfo = reinterpret_cast<sockaddr_in*> (ifa->ifa_dstaddr); + auto interfaceAddressInfo = unalignedPointerCast<sockaddr_in*> (ifa->ifa_addr); + auto broadcastAddressInfo = unalignedPointerCast<sockaddr_in*> (ifa->ifa_dstaddr); if (interfaceAddressInfo->sin_addr.s_addr != INADDR_NONE) { @@ -83,8 +83,8 @@ namespace } else if (ifa->ifa_addr->sa_family == AF_INET6) { - interfaceInfo.interfaceAddress = makeAddress (reinterpret_cast<sockaddr_in6*> (ifa->ifa_addr)); - interfaceInfo.broadcastAddress = makeAddress (reinterpret_cast<sockaddr_in6*> (ifa->ifa_dstaddr)); + interfaceInfo.interfaceAddress = makeAddress (unalignedPointerCast<sockaddr_in6*> (ifa->ifa_addr)); + interfaceInfo.broadcastAddress = makeAddress (unalignedPointerCast<sockaddr_in6*> (ifa->ifa_dstaddr)); return true; } } diff --git a/modules/juce_core/native/juce_posix_NamedPipe.cpp b/modules/juce_core/native/juce_posix_NamedPipe.cpp index 72b810a5..e48ad256 100644 --- a/modules/juce_core/native/juce_posix_NamedPipe.cpp +++ b/modules/juce_core/native/juce_posix_NamedPipe.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -154,7 +154,7 @@ private: bool openPipe (bool isInput, uint32 timeoutEnd) { auto& pipe = isInput ? pipeIn : pipeOut; - int flags = isInput ? O_RDWR | O_NONBLOCK : O_WRONLY; + int flags = (isInput ? O_RDWR : O_WRONLY) | O_NONBLOCK; const String& pipeName = isInput ? (createdPipe ? pipeInName : pipeOutName) : (createdPipe ? pipeOutName : pipeInName); @@ -181,14 +181,20 @@ private: void NamedPipe::close() { - if (pimpl != nullptr) { - pimpl->stopReadOperation = true; + ScopedReadLock sl (lock); - char buffer[1] = { 0 }; - ssize_t done = ::write (pimpl->pipeIn, buffer, 1); - ignoreUnused (done); + if (pimpl != nullptr) + { + pimpl->stopReadOperation = true; + char buffer[1] = { 0 }; + ssize_t done = ::write (pimpl->pipeIn, buffer, 1); + ignoreUnused (done); + } + } + + { ScopedWriteLock sl (lock); pimpl.reset(); } diff --git a/modules/juce_core/native/juce_posix_SharedCode.h b/modules/juce_core/native/juce_posix_SharedCode.h index 5d30962c..982db865 100644 --- a/modules/juce_core/native/juce_posix_SharedCode.h +++ b/modules/juce_core/native/juce_posix_SharedCode.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -415,7 +415,7 @@ int64 juce_fileSetPosition (void* handle, int64 pos) void FileInputStream::openHandle() { - auto f = open (file.getFullPathName().toUTF8(), O_RDONLY, 00644); + auto f = open (file.getFullPathName().toUTF8(), O_RDONLY); if (f != -1) fileHandle = fdToVoidPointer (f); @@ -452,7 +452,7 @@ void FileOutputStream::openHandle() { if (file.exists()) { - auto f = open (file.getFullPathName().toUTF8(), O_RDWR, 00644); + auto f = open (file.getFullPathName().toUTF8(), O_RDWR); if (f != -1) { @@ -475,7 +475,7 @@ void FileOutputStream::openHandle() } else { - auto f = open (file.getFullPathName().toUTF8(), O_RDWR + O_CREAT, 00644); + auto f = open (file.getFullPathName().toUTF8(), O_RDWR | O_CREAT, 00644); if (f != -1) fileHandle = fdToVoidPointer (f); @@ -543,8 +543,12 @@ void MemoryMappedFile::openInternal (const File& file, AccessMode mode, bool exc range.setStart (range.getStart() - (range.getStart() % pageSize)); } - fileHandle = open (file.getFullPathName().toUTF8(), - mode == readWrite ? (O_CREAT + O_RDWR) : O_RDONLY, 00644); + auto filename = file.getFullPathName().toUTF8(); + + if (mode == readWrite) + fileHandle = open (filename, O_CREAT | O_RDWR, 00644); + else + fileHandle = open (filename, O_RDONLY); if (fileHandle != -1) { @@ -1029,7 +1033,8 @@ void* DynamicLibrary::getFunction (const String& functionName) noexcept //============================================================================== -static inline String readPosixConfigFileValue (const char* file, const char* key) +#if JUCE_LINUX || JUCE_ANDROID +static String readPosixConfigFileValue (const char* file, const char* key) { StringArray lines; File (file).readLines (lines); @@ -1040,6 +1045,7 @@ static inline String readPosixConfigFileValue (const char* file, const char* key return {}; } +#endif //============================================================================== diff --git a/modules/juce_core/native/juce_win32_ComSmartPtr.h b/modules/juce_core/native/juce_win32_ComSmartPtr.h index 29b455d2..c9232c2e 100644 --- a/modules/juce_core/native/juce_win32_ComSmartPtr.h +++ b/modules/juce_core/native/juce_win32_ComSmartPtr.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -56,7 +56,7 @@ inline GUID uuidFromString (const char* s) noexcept for (uint32 digitIndex = 0; digitIndex < 32;) { - auto c = *s++; + auto c = (uint32) *s++; uint32 digit; if (c >= '0' && c <= '9') digit = c - '0'; @@ -114,7 +114,7 @@ public: HRESULT CoCreateInstance (REFCLSID classUUID, DWORD dwClsContext = CLSCTX_INPROC_SERVER) { - auto hr = ::CoCreateInstance (classUUID, 0, dwClsContext, __uuidof (ComClass), (void**) resetAndGetPointerAddress()); + auto hr = ::CoCreateInstance (classUUID, nullptr, dwClsContext, __uuidof (ComClass), (void**) resetAndGetPointerAddress()); jassert (hr != CO_E_NOTINITIALIZED); // You haven't called CoInitialize for the current thread! return hr; } @@ -134,6 +134,17 @@ public: return this->QueryInterface (__uuidof (OtherComClass), destObject); } + template<class OtherComClass> + ComSmartPtr<OtherComClass> getInterface() const + { + ComSmartPtr<OtherComClass> destObject; + + if (QueryInterface (destObject) == S_OK) + return destObject; + + return nullptr; + } + private: ComClass* p = nullptr; diff --git a/modules/juce_core/native/juce_win32_Files.cpp b/modules/juce_core/native/juce_win32_Files.cpp index bdc5029d..9547df8c 100644 --- a/modules/juce_core/native/juce_win32_Files.cpp +++ b/modules/juce_core/native/juce_win32_Files.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -131,7 +131,7 @@ namespace WindowsFileHelpers { WCHAR path[MAX_PATH + 256]; - if (SHGetSpecialFolderPath (0, path, type, FALSE)) + if (SHGetSpecialFolderPath (nullptr, path, type, FALSE)) return File (String (path)); return {}; @@ -147,7 +147,7 @@ namespace WindowsFileHelpers Result getResultForLastError() { - TCHAR messageBuffer[256] = { 0 }; + TCHAR messageBuffer[256] = {}; FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, GetLastError(), MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), @@ -239,7 +239,7 @@ bool File::moveToTrash() const doubleNullTermPath.calloc (numBytes, 1); fullPath.copyToUTF16 (doubleNullTermPath, numBytes); - SHFILEOPSTRUCT fos = { 0 }; + SHFILEOPSTRUCT fos = {}; fos.wFunc = FO_DELETE; fos.pFrom = doubleNullTermPath; fos.fFlags = FOF_ALLOWUNDO | FOF_NOERRORUI | FOF_SILENT | FOF_NOCONFIRMATION @@ -264,14 +264,14 @@ bool File::replaceInternal (const File& dest) const { return ReplaceFile (dest.getFullPathName().toWideCharPointer(), fullPath.toWideCharPointer(), - 0, REPLACEFILE_IGNORE_MERGE_ERRORS | 4 /*REPLACEFILE_IGNORE_ACL_ERRORS*/, + nullptr, REPLACEFILE_IGNORE_MERGE_ERRORS | 4 /*REPLACEFILE_IGNORE_ACL_ERRORS*/, nullptr, nullptr) != 0; } Result File::createDirectoryInternal (const String& fileName) const { - return CreateDirectory (fileName.toWideCharPointer(), 0) ? Result::ok() - : WindowsFileHelpers::getResultForLastError(); + return CreateDirectory (fileName.toWideCharPointer(), nullptr) ? Result::ok() + : WindowsFileHelpers::getResultForLastError(); } //============================================================================== @@ -287,8 +287,8 @@ int64 juce_fileSetPosition (void* handle, int64 pos) void FileInputStream::openHandle() { auto h = CreateFile (file.getFullPathName().toWideCharPointer(), - GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, - OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, 0); + GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, nullptr); if (h != INVALID_HANDLE_VALUE) fileHandle = (void*) h; @@ -303,11 +303,11 @@ FileInputStream::~FileInputStream() size_t FileInputStream::readInternal (void* buffer, size_t numBytes) { - if (fileHandle != 0) + if (fileHandle != nullptr) { DWORD actualNum = 0; - if (! ReadFile ((HANDLE) fileHandle, buffer, (DWORD) numBytes, &actualNum, 0)) + if (! ReadFile ((HANDLE) fileHandle, buffer, (DWORD) numBytes, &actualNum, nullptr)) status = WindowsFileHelpers::getResultForLastError(); return (size_t) actualNum; @@ -320,8 +320,8 @@ size_t FileInputStream::readInternal (void* buffer, size_t numBytes) void FileOutputStream::openHandle() { auto h = CreateFile (file.getFullPathName().toWideCharPointer(), - GENERIC_WRITE, FILE_SHARE_READ, 0, - OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); + GENERIC_WRITE, FILE_SHARE_READ, nullptr, + OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); if (h != INVALID_HANDLE_VALUE) { @@ -350,7 +350,7 @@ ssize_t FileOutputStream::writeInternal (const void* bufferToWrite, size_t numBy DWORD actualNum = 0; if (fileHandle != nullptr) - if (! WriteFile ((HANDLE) fileHandle, bufferToWrite, (DWORD) numBytes, &actualNum, 0)) + if (! WriteFile ((HANDLE) fileHandle, bufferToWrite, (DWORD) numBytes, &actualNum, nullptr)) status = WindowsFileHelpers::getResultForLastError(); return (ssize_t) actualNum; @@ -398,18 +398,18 @@ void MemoryMappedFile::openInternal (const File& file, AccessMode mode, bool exc } auto h = CreateFile (file.getFullPathName().toWideCharPointer(), accessMode, - exclusive ? 0 : (FILE_SHARE_READ | FILE_SHARE_DELETE | (mode == readWrite ? FILE_SHARE_WRITE : 0)), 0, - createType, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, 0); + exclusive ? 0 : (FILE_SHARE_READ | FILE_SHARE_DELETE | (mode == readWrite ? FILE_SHARE_WRITE : 0)), nullptr, + createType, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, nullptr); if (h != INVALID_HANDLE_VALUE) { fileHandle = (void*) h; - auto mappingHandle = CreateFileMapping (h, 0, protect, + auto mappingHandle = CreateFileMapping (h, nullptr, protect, (DWORD) (range.getEnd() >> 32), - (DWORD) range.getEnd(), 0); + (DWORD) range.getEnd(), nullptr); - if (mappingHandle != 0) + if (mappingHandle != nullptr) { address = MapViewOfFile (mappingHandle, access, (DWORD) (range.getStart() >> 32), (DWORD) range.getStart(), (SIZE_T) range.getLength()); @@ -465,8 +465,8 @@ bool File::setFileTimesInternal (int64 modificationTime, int64 accessTime, int64 bool ok = false; auto h = CreateFile (fullPath.toWideCharPointer(), - GENERIC_WRITE, FILE_SHARE_READ, 0, - OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); + GENERIC_WRITE, FILE_SHARE_READ, nullptr, + OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); if (h != INVALID_HANDLE_VALUE) { @@ -486,7 +486,7 @@ bool File::setFileTimesInternal (int64 modificationTime, int64 accessTime, int64 //============================================================================== void File::findFileSystemRoots (Array<File>& destArray) { - TCHAR buffer[2048] = { 0 }; + TCHAR buffer[2048] = {}; GetLogicalDriveStrings (2048, buffer); const TCHAR* n = buffer; @@ -512,7 +512,7 @@ String File::getVolumeLabel() const TCHAR dest[64]; if (! GetVolumeInformation (WindowsFileHelpers::getDriveFromPath (getFullPathName()).toWideCharPointer(), dest, - (DWORD) numElementsInArray (dest), 0, 0, 0, 0, 0)) + (DWORD) numElementsInArray (dest), nullptr, nullptr, nullptr, nullptr, 0)) dest[0] = 0; return dest; @@ -524,7 +524,7 @@ int File::getVolumeSerialNumber() const DWORD serialNum; if (! GetVolumeInformation (WindowsFileHelpers::getDriveFromPath (getFullPathName()).toWideCharPointer(), dest, - (DWORD) numElementsInArray (dest), &serialNum, 0, 0, 0, 0)) + (DWORD) numElementsInArray (dest), &serialNum, nullptr, nullptr, nullptr, 0)) return 0; return (int) serialNum; @@ -551,7 +551,7 @@ uint64 File::getFileIdentifier() const auto h = CreateFile (path.toWideCharPointer(), GENERIC_READ, FILE_SHARE_READ, nullptr, - OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); + OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr); if (h != INVALID_HANDLE_VALUE) { @@ -640,7 +640,7 @@ File JUCE_CALLTYPE File::getSpecialLocation (const SpecialLocationType type) return WindowsFileHelpers::getModuleFileName ((HINSTANCE) Process::getCurrentModuleInstanceHandle()); case hostApplicationPath: - return WindowsFileHelpers::getModuleFileName (0); + return WindowsFileHelpers::getModuleFileName (nullptr); default: jassertfalse; // unknown type? @@ -715,7 +715,7 @@ static String readWindowsLnkFile (File lnkFile, bool wantsAbsolutePath) if (SUCCEEDED (shellLink.CoCreateInstance (CLSID_ShellLink)) && SUCCEEDED (shellLink.QueryInterface (persistFile)) && SUCCEEDED (persistFile->Load (lnkFile.getFullPathName().toWideCharPointer(), STGM_READ)) - && (! wantsAbsolutePath || SUCCEEDED (shellLink->Resolve (0, SLR_ANY_MATCH | SLR_NO_UI)))) + && (! wantsAbsolutePath || SUCCEEDED (shellLink->Resolve (nullptr, SLR_ANY_MATCH | SLR_NO_UI)))) { WIN32_FIND_DATA winFindData; WCHAR resolvedPath[MAX_PATH]; @@ -741,7 +741,7 @@ static String readWindowsShortcutOrLink (const File& shortcut, bool wantsAbsolut HANDLE h = CreateFile (shortcut.getFullPathName().toWideCharPointer(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, - 0); + nullptr); if (h != INVALID_HANDLE_VALUE) { @@ -809,7 +809,7 @@ static String readWindowsShortcutOrLink (const File& shortcut, bool wantsAbsolut { HANDLE h = CreateFile (shortcut.getFullPathName().toWideCharPointer(), GENERIC_READ, FILE_SHARE_READ, nullptr, - OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); + OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr); if (h != INVALID_HANDLE_VALUE) { @@ -861,7 +861,7 @@ bool File::createShortcut (const String& description, const File& linkFileToCrea ComSmartPtr<IShellLink> shellLink; ComSmartPtr<IPersistFile> persistFile; - CoInitialize (0); + CoInitialize (nullptr); return SUCCEEDED (shellLink.CoCreateInstance (CLSID_ShellLink)) && SUCCEEDED (shellLink->SetPath (getFullPathName().toWideCharPointer())) @@ -945,8 +945,8 @@ bool DirectoryIterator::NativeIterator::next (String& filenameFound, //============================================================================== bool JUCE_CALLTYPE Process::openDocument (const String& fileName, const String& parameters) { - HINSTANCE hInstance = ShellExecute (0, 0, fileName.toWideCharPointer(), - parameters.toWideCharPointer(), 0, SW_SHOWDEFAULT); + HINSTANCE hInstance = ShellExecute (nullptr, nullptr, fileName.toWideCharPointer(), + parameters.toWideCharPointer(), nullptr, SW_SHOWDEFAULT); return hInstance > (HINSTANCE) 32; } @@ -975,14 +975,14 @@ public: Pimpl (const String& pipeName, const bool createPipe, bool mustNotExist) : filename ("\\\\.\\pipe\\" + File::createLegalFileName (pipeName)), pipeH (INVALID_HANDLE_VALUE), - cancelEvent (CreateEvent (0, FALSE, FALSE, 0)), + cancelEvent (CreateEvent (nullptr, TRUE, FALSE, nullptr)), connected (false), ownsPipe (createPipe), shouldStop (false) { if (createPipe) { pipeH = CreateNamedPipe (filename.toWideCharPointer(), PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, 0, - PIPE_UNLIMITED_INSTANCES, 4096, 4096, 0, 0); + PIPE_UNLIMITED_INSTANCES, 4096, 4096, 0, nullptr); if (mustNotExist && GetLastError() == ERROR_ALREADY_EXISTS) closePipeHandle(); @@ -1011,8 +1011,8 @@ public: if (pipeH == INVALID_HANDLE_VALUE) pipeH = CreateFile (filename.toWideCharPointer(), - GENERIC_READ | GENERIC_WRITE, 0, 0, - OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); + GENERIC_READ | GENERIC_WRITE, 0, nullptr, + OPEN_EXISTING, FILE_FLAG_OVERLAPPED, nullptr); } if (pipeH != INVALID_HANDLE_VALUE) @@ -1071,14 +1071,12 @@ public: return 0; OverlappedEvent over; - unsigned long numRead; + unsigned long numRead = 0; if (ReadFile (pipeH, destBuffer, (DWORD) maxBytesToRead, &numRead, &over.over)) return (int) numRead; - const DWORD lastError = GetLastError(); - - if (lastError == ERROR_IO_PENDING) + if (GetLastError() == ERROR_IO_PENDING) { if (! waitForIO (over, timeOutMilliseconds)) return -1; @@ -1087,7 +1085,9 @@ public: return (int) numRead; } - if (ownsPipe && (GetLastError() == ERROR_BROKEN_PIPE || GetLastError() == ERROR_PIPE_NOT_CONNECTED)) + const auto lastError = GetLastError(); + + if (ownsPipe && (lastError == ERROR_BROKEN_PIPE || lastError == ERROR_PIPE_NOT_CONNECTED)) disconnectPipe(); else break; @@ -1127,7 +1127,8 @@ public: const String filename; HANDLE pipeH, cancelEvent; - bool connected, ownsPipe, shouldStop; + bool connected, ownsPipe; + std::atomic<bool> shouldStop; CriticalSection createFileLock; private: @@ -1136,7 +1137,7 @@ private: OverlappedEvent() { zerostruct (over); - over.hEvent = CreateEvent (0, TRUE, FALSE, 0); + over.hEvent = CreateEvent (nullptr, TRUE, FALSE, nullptr); } ~OverlappedEvent() @@ -1150,11 +1151,14 @@ private: bool waitForIO (OverlappedEvent& over, int timeOutMilliseconds) { if (shouldStop) + { + CancelIo (pipeH); return false; + } HANDLE handles[] = { over.over.hEvent, cancelEvent }; - DWORD waitResult = WaitForMultipleObjects (2, handles, FALSE, - timeOutMilliseconds >= 0 ? timeOutMilliseconds + DWORD waitResult = WaitForMultipleObjects (numElementsInArray (handles), handles, FALSE, + timeOutMilliseconds >= 0 ? (DWORD) timeOutMilliseconds : INFINITE); if (waitResult == WAIT_OBJECT_0) @@ -1169,11 +1173,17 @@ private: void NamedPipe::close() { - if (pimpl != nullptr) { - pimpl->shouldStop = true; - SetEvent (pimpl->cancelEvent); + ScopedReadLock sl (lock); + + if (pimpl != nullptr) + { + pimpl->shouldStop = true; + SetEvent (pimpl->cancelEvent); + } + } + { ScopedWriteLock sl (lock); pimpl.reset(); } @@ -1181,22 +1191,19 @@ void NamedPipe::close() bool NamedPipe::openInternal (const String& pipeName, const bool createPipe, bool mustNotExist) { - pimpl.reset (new Pimpl (pipeName, createPipe, mustNotExist)); + auto newPimpl = std::make_unique<Pimpl> (pipeName, createPipe, mustNotExist); if (createPipe) { - if (pimpl->pipeH == INVALID_HANDLE_VALUE) - { - pimpl.reset(); + if (newPimpl->pipeH == INVALID_HANDLE_VALUE) return false; - } } - else if (! pimpl->connect (200)) + else if (! newPimpl->connect (200)) { - pimpl.reset(); return false; } + pimpl = std::move (newPimpl); return true; } diff --git a/modules/juce_core/native/juce_win32_Network.cpp b/modules/juce_core/native/juce_win32_Network.cpp index 34640f8f..c0289fc2 100644 --- a/modules/juce_core/native/juce_win32_Network.cpp +++ b/modules/juce_core/native/juce_win32_Network.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -90,7 +90,7 @@ public: { HeapBlock<char> buffer (bufferSizeBytes); - if (HttpQueryInfo (request, HTTP_QUERY_RAW_HEADERS_CRLF, buffer.getData(), &bufferSizeBytes, 0)) + if (HttpQueryInfo (request, HTTP_QUERY_RAW_HEADERS_CRLF, buffer.getData(), &bufferSizeBytes, nullptr)) { StringArray headersArray; headersArray.addLines (String (reinterpret_cast<const WCHAR*> (buffer.getData()))); @@ -116,7 +116,7 @@ public: DWORD status = 0; DWORD statusSize = sizeof (status); - if (HttpQueryInfo (request, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &status, &statusSize, 0)) + if (HttpQueryInfo (request, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &status, &statusSize, nullptr)) { statusCode = (int) status; @@ -151,10 +151,10 @@ public: break; } - return (request != 0); + return (request != nullptr); } - bool isError() const { return request == 0; } + bool isError() const { return request == nullptr; } bool isExhausted() { return finished; } int64 getPosition() { return position; } @@ -207,7 +207,7 @@ public: if (wantedPos != position) { finished = false; - position = (int64) InternetSetFilePointer (request, (LONG) wantedPos, 0, FILE_BEGIN, 0); + position = (int64) InternetSetFilePointer (request, (LONG) wantedPos, nullptr, FILE_BEGIN, 0); if (position == wantedPos) return true; @@ -232,7 +232,7 @@ private: //============================================================================== WebInputStream& owner; const URL url; - HINTERNET connection = 0, request = 0; + HINTERNET connection = nullptr, request = nullptr; String headers; MemoryBlock postData; int64 position = 0; @@ -249,25 +249,25 @@ private: { HINTERNET requestCopy = request; - request = 0; + request = nullptr; - if (requestCopy != 0) + if (requestCopy != nullptr) InternetCloseHandle (requestCopy); - if (connection != 0) + if (connection != nullptr) { InternetCloseHandle (connection); - connection = 0; + connection = nullptr; } } void createConnection (const String& address, WebInputStream::Listener* listener) { - static HINTERNET sessionHandle = InternetOpen (_T("juce"), INTERNET_OPEN_TYPE_PRECONFIG, 0, 0, 0); + static HINTERNET sessionHandle = InternetOpen (_T("juce"), INTERNET_OPEN_TYPE_PRECONFIG, nullptr, nullptr, 0); closeConnection(); - if (sessionHandle != 0) + if (sessionHandle != nullptr) { // break up the url.. const int fileNumChars = 65536; @@ -277,7 +277,7 @@ private: HeapBlock<TCHAR> file (fileNumChars), server (serverNumChars), username (usernameNumChars), password (passwordNumChars); - URL_COMPONENTS uc = { 0 }; + URL_COMPONENTS uc = {}; uc.dwStructSize = sizeof (uc); uc.lpszUrlPath = file; uc.dwUrlPathLength = fileNumChars; @@ -319,7 +319,7 @@ private: { const ScopedLock lock (createConnectionLock); - connection = hasBeenCancelled ? 0 + connection = hasBeenCancelled ? nullptr : InternetConnect (sessionHandle, uc.lpszHostName, uc.nPort, uc.lpszUserName, uc.lpszPassword, @@ -328,7 +328,7 @@ private: 0, 0); } - if (connection != 0) + if (connection != nullptr) { if (isFtp) request = FtpOpenFile (connection, uc.lpszUrlPath, GENERIC_READ, @@ -345,7 +345,7 @@ private: void sendHTTPRequest (INTERNET_BUFFERS& buffers, WebInputStream::Listener* listener) { - if (! HttpSendRequestEx (request, &buffers, 0, HSR_INITIATE, 0)) + if (! HttpSendRequestEx (request, &buffers, nullptr, HSR_INITIATE, 0)) return; int totalBytesSent = 0; @@ -362,7 +362,7 @@ private: return; } - totalBytesSent += bytesSent; + totalBytesSent += (int) bytesSent; if (listener != nullptr && ! listener->postDataSendProgress (owner, totalBytesSent, (int) postData.getSize())) @@ -386,14 +386,14 @@ private: { const ScopedLock lock (createConnectionLock); - request = hasBeenCancelled ? 0 + request = hasBeenCancelled ? nullptr : HttpOpenRequest (connection, httpRequestCmd.toWideCharPointer(), - uc.lpszUrlPath, 0, 0, mimeTypes, flags, 0); + uc.lpszUrlPath, nullptr, nullptr, mimeTypes, flags, 0); } - if (request != 0) + if (request != nullptr) { - INTERNET_BUFFERS buffers = { 0 }; + INTERNET_BUFFERS buffers = {}; buffers.dwStructSize = sizeof (INTERNET_BUFFERS); buffers.lpcszHeader = headers.toWideCharPointer(); buffers.dwHeadersLength = (DWORD) headers.length(); @@ -403,7 +403,7 @@ private: { sendHTTPRequest (buffers, listener); - if (HttpEndRequest (request, 0, 0, 0)) + if (HttpEndRequest (request, nullptr, 0, 0)) return true; return false; @@ -440,10 +440,10 @@ struct GetAdaptersAddressesHelper adaptersAddresses.malloc (1); ULONG len = sizeof (IP_ADAPTER_ADDRESSES); - if (getAdaptersAddresses (AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, adaptersAddresses, &len) == ERROR_BUFFER_OVERFLOW) + if (getAdaptersAddresses (AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr, adaptersAddresses, &len) == ERROR_BUFFER_OVERFLOW) adaptersAddresses.malloc (len, 1); - return getAdaptersAddresses (AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, adaptersAddresses, &len) == NO_ERROR; + return getAdaptersAddresses (AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr, adaptersAddresses, &len) == NO_ERROR; } HeapBlock<IP_ADAPTER_ADDRESSES> adaptersAddresses; @@ -476,12 +476,12 @@ namespace MACAddressHelpers DynamicLibrary dll ("netapi32.dll"); JUCE_LOAD_WINAPI_FUNCTION (dll, Netbios, NetbiosCall, UCHAR, (PNCB)) - if (NetbiosCall != 0) + if (NetbiosCall != nullptr) { - LANA_ENUM enums = { 0 }; + LANA_ENUM enums = {}; { - NCB ncb = { 0 }; + NCB ncb = {}; ncb.ncb_command = NCBENUM; ncb.ncb_buffer = (unsigned char*) &enums; ncb.ncb_length = sizeof (LANA_ENUM); @@ -490,13 +490,13 @@ namespace MACAddressHelpers for (int i = 0; i < enums.length; ++i) { - NCB ncb2 = { 0 }; + NCB ncb2 = {}; ncb2.ncb_command = NCBRESET; ncb2.ncb_lana_num = enums.lana[i]; if (NetbiosCall (&ncb2) == 0) { - NCB ncb = { 0 }; + NCB ncb = {}; memcpy (ncb.ncb_callname, "* ", NCBNAMSZ); ncb.ncb_command = NCBASTAT; ncb.ncb_lana_num = enums.lana[i]; @@ -608,11 +608,11 @@ bool JUCE_CALLTYPE Process::openEmailWithAttachments (const String& targetEmailA if (mapiSendMail == nullptr) return false; - MapiMessage message = { 0 }; + MapiMessage message = {}; message.lpszSubject = (LPSTR) emailSubject.toRawUTF8(); message.lpszNoteText = (LPSTR) bodyText.toRawUTF8(); - MapiRecipDesc recip = { 0 }; + MapiRecipDesc recip = {}; recip.ulRecipClass = MAPI_TO; String targetEmailAddress_ (targetEmailAddress); if (targetEmailAddress_.isEmpty()) @@ -636,7 +636,7 @@ bool JUCE_CALLTYPE Process::openEmailWithAttachments (const String& targetEmailA return mapiSendMail (0, 0, &message, MAPI_DIALOG | MAPI_LOGON_UI, 0) == SUCCESS_SUCCESS; } -URL::DownloadTask* URL::downloadToFile (const File& targetLocation, String extraHeaders, DownloadTask::Listener* listener, bool shouldUsePost) +std::unique_ptr<URL::DownloadTask> URL::downloadToFile (const File& targetLocation, String extraHeaders, DownloadTask::Listener* listener, bool shouldUsePost) { return URL::DownloadTask::createFallbackDownloader (*this, targetLocation, extraHeaders, listener, shouldUsePost); } diff --git a/modules/juce_core/native/juce_win32_Registry.cpp b/modules/juce_core/native/juce_win32_Registry.cpp index afd29824..c0d08630 100644 --- a/modules/juce_core/native/juce_win32_Registry.cpp +++ b/modules/juce_core/native/juce_win32_Registry.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -40,8 +40,8 @@ struct RegistryKeyWrapper DWORD result; if (createForWriting) - RegCreateKeyEx (rootKey, wideCharName, 0, 0, REG_OPTION_NON_VOLATILE, - KEY_WRITE | KEY_QUERY_VALUE | wow64Flags, 0, &key, &result); + RegCreateKeyEx (rootKey, wideCharName, 0, nullptr, REG_OPTION_NON_VOLATILE, + KEY_WRITE | KEY_QUERY_VALUE | wow64Flags, nullptr, &key, &result); else RegOpenKeyEx (rootKey, wideCharName, 0, KEY_READ | wow64Flags, &key); } @@ -65,7 +65,7 @@ struct RegistryKeyWrapper if (name.startsWithIgnoreCase ("HKU\\")) return HKEY_USERS; jassertfalse; // The name starts with an unknown root key (or maybe an old Win9x type) - return 0; + return nullptr; } static bool setValue (const String& regValuePath, const DWORD type, @@ -90,7 +90,7 @@ struct RegistryKeyWrapper result.setSize (bufferSize, false); DWORD type = REG_NONE; - auto err = RegQueryValueEx (key.key, key.wideCharValueName, 0, &type, + auto err = RegQueryValueEx (key.key, key.wideCharValueName, nullptr, &type, (LPBYTE) result.getData(), &bufferSize); if (err == ERROR_SUCCESS) @@ -138,7 +138,7 @@ struct RegistryKeyWrapper DWORD type = 0; auto result = RegQueryValueEx (key.key, key.wideCharValueName, - 0, &type, buffer, &bufferSize); + nullptr, &type, buffer, &bufferSize); return result == ERROR_SUCCESS || result == ERROR_MORE_DATA; } diff --git a/modules/juce_core/native/juce_win32_SystemStats.cpp b/modules/juce_core/native/juce_win32_SystemStats.cpp index bbdd2586..bbb2424b 100644 --- a/modules/juce_core/native/juce_win32_SystemStats.cpp +++ b/modules/juce_core/native/juce_win32_SystemStats.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -44,7 +44,8 @@ void Logger::outputDebugString (const String& text) #if JUCE_MINGW || JUCE_CLANG static void callCPUID (int result[4], uint32 type) { - uint32 la = result[0], lb = result[1], lc = result[2], ld = result[3]; + uint32 la = (uint32) result[0], lb = (uint32) result[1], + lc = (uint32) result[2], ld = (uint32) result[3]; asm ("mov %%ebx, %%esi \n\t" "cpuid \n\t" @@ -55,7 +56,8 @@ static void callCPUID (int result[4], uint32 type) #endif ); - result[0] = la; result[1] = lb; result[2] = lc; result[3] = ld; + result[0] = (int) la; result[1] = (int) lb; + result[2] = (int) lc; result[3] = (int) ld; } #else static void callCPUID (int result[4], int infoType) @@ -155,17 +157,17 @@ void CPUInformation::initialise() noexcept callCPUID (info, 7); - hasAVX2 = (info[1] & (1 << 5)) != 0; - hasAVX512F = (info[1] & (1u << 16)) != 0; - hasAVX512DQ = (info[1] & (1u << 17)) != 0; - hasAVX512IFMA = (info[1] & (1u << 21)) != 0; - hasAVX512PF = (info[1] & (1u << 26)) != 0; - hasAVX512ER = (info[1] & (1u << 27)) != 0; - hasAVX512CD = (info[1] & (1u << 28)) != 0; - hasAVX512BW = (info[1] & (1u << 30)) != 0; - hasAVX512VL = (info[1] & (1u << 31)) != 0; - hasAVX512VBMI = (info[2] & (1u << 1)) != 0; - hasAVX512VPOPCNTDQ = (info[2] & (1u << 14)) != 0; + hasAVX2 = ((unsigned int) info[1] & (1 << 5)) != 0; + hasAVX512F = ((unsigned int) info[1] & (1u << 16)) != 0; + hasAVX512DQ = ((unsigned int) info[1] & (1u << 17)) != 0; + hasAVX512IFMA = ((unsigned int) info[1] & (1u << 21)) != 0; + hasAVX512PF = ((unsigned int) info[1] & (1u << 26)) != 0; + hasAVX512ER = ((unsigned int) info[1] & (1u << 27)) != 0; + hasAVX512CD = ((unsigned int) info[1] & (1u << 28)) != 0; + hasAVX512BW = ((unsigned int) info[1] & (1u << 30)) != 0; + hasAVX512VL = ((unsigned int) info[1] & (1u << 31)) != 0; + hasAVX512VBMI = ((unsigned int) info[2] & (1u << 1)) != 0; + hasAVX512VPOPCNTDQ = ((unsigned int) info[2] & (1u << 14)) != 0; SYSTEM_INFO systemInfo; GetNativeSystemInfo (&systemInfo); @@ -215,7 +217,7 @@ static DebugFlagsInitialiser debugFlagsInitialiser; #else RTL_OSVERSIONINFOW getWindowsVersionInfo() { - RTL_OSVERSIONINFOW versionInfo = { 0 }; + RTL_OSVERSIONINFOW versionInfo = {}; if (auto* moduleHandle = ::GetModuleHandleW (L"ntdll.dll")) { @@ -227,7 +229,7 @@ static DebugFlagsInitialiser debugFlagsInitialiser; LONG STATUS_SUCCESS = 0; if (rtlGetVersion (&versionInfo) != STATUS_SUCCESS) - versionInfo = { 0 }; + versionInfo = {}; } } @@ -274,6 +276,23 @@ String SystemStats::getOperatingSystemName() case WinVista: name = "Windows Vista"; break; case WinXP: name = "Windows XP"; break; case Win2000: name = "Windows 2000"; break; + + case MacOSX: JUCE_FALLTHROUGH + case Windows: JUCE_FALLTHROUGH + case Linux: JUCE_FALLTHROUGH + case Android: JUCE_FALLTHROUGH + case iOS: JUCE_FALLTHROUGH + + case MacOSX_10_7: JUCE_FALLTHROUGH + case MacOSX_10_8: JUCE_FALLTHROUGH + case MacOSX_10_9: JUCE_FALLTHROUGH + case MacOSX_10_10: JUCE_FALLTHROUGH + case MacOSX_10_11: JUCE_FALLTHROUGH + case MacOSX_10_12: JUCE_FALLTHROUGH + case MacOSX_10_13: JUCE_FALLTHROUGH + case MacOSX_10_14: JUCE_FALLTHROUGH + + case UnknownOS: JUCE_FALLTHROUGH default: jassertfalse; break; // !! new type of OS? } diff --git a/modules/juce_core/native/juce_win32_Threads.cpp b/modules/juce_core/native/juce_win32_Threads.cpp index 749bf747..296ec455 100644 --- a/modules/juce_core/native/juce_win32_Threads.cpp +++ b/modules/juce_core/native/juce_win32_Threads.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -23,12 +23,12 @@ namespace juce { -HWND juce_messageWindowHandle = 0; // (this is used by other parts of the codebase) +HWND juce_messageWindowHandle = nullptr; // (this is used by other parts of the codebase) void* getUser32Function (const char* functionName) { HMODULE module = GetModuleHandleA ("user32.dll"); - jassert (module != 0); + jassert (module != nullptr); return (void*) GetProcAddress (module, functionName); } @@ -53,8 +53,8 @@ void JUCE_API juce_threadEntryPoint (void*); static unsigned int __stdcall threadEntryProc (void* userData) { - if (juce_messageWindowHandle != 0) - AttachThreadInput (GetWindowThreadProcessId (juce_messageWindowHandle, 0), + if (juce_messageWindowHandle != nullptr) + AttachThreadInput (GetWindowThreadProcessId (juce_messageWindowHandle, nullptr), GetCurrentThreadId(), TRUE); juce_threadEntryPoint (userData); @@ -66,7 +66,7 @@ static unsigned int __stdcall threadEntryProc (void* userData) void Thread::launchThread() { unsigned int newThreadId; - threadHandle = (void*) _beginthreadex (0, (unsigned int) threadStackSize, + threadHandle = (void*) _beginthreadex (nullptr, (unsigned int) threadStackSize, &threadEntryProc, this, 0, &newThreadId); threadId = (ThreadID) (pointer_sized_int) newThreadId; } @@ -74,13 +74,13 @@ void Thread::launchThread() void Thread::closeThreadHandle() { CloseHandle ((HANDLE) threadHandle.get()); - threadId = 0; - threadHandle = 0; + threadId = nullptr; + threadHandle = nullptr; } void Thread::killThread() { - if (threadHandle.get() != 0) + if (threadHandle.get() != nullptr) { #if JUCE_DEBUG OutputDebugStringA ("** Warning - Forced thread termination **\n"); @@ -132,7 +132,7 @@ bool Thread::setThreadPriority (void* handle, int priority) else if (priority < 9) pri = THREAD_PRIORITY_ABOVE_NORMAL; else if (priority < 10) pri = THREAD_PRIORITY_HIGHEST; - if (handle == 0) + if (handle == nullptr) handle = GetCurrentThread(); return SetThreadPriority (handle, pri) != FALSE; @@ -158,7 +158,7 @@ struct SleepEvent ~SleepEvent() noexcept { CloseHandle (handle); - handle = 0; + handle = nullptr; } HANDLE handle; @@ -170,7 +170,7 @@ void JUCE_CALLTYPE Thread::sleep (const int millisecs) { jassert (millisecs >= 0); - if (millisecs >= 10 || sleepEvent.handle == 0) + if (millisecs >= 10 || sleepEvent.handle == nullptr) Sleep ((DWORD) millisecs); else // unlike Sleep() this is guaranteed to return to the current thread after @@ -260,7 +260,7 @@ void JUCE_CALLTYPE Process::terminate() bool juce_isRunningInWine() { HMODULE ntdll = GetModuleHandleA ("ntdll"); - return ntdll != 0 && GetProcAddress (ntdll, "wine_get_version") != nullptr; + return ntdll != nullptr && GetProcAddress (ntdll, "wine_get_version") != nullptr; } //============================================================================== @@ -292,18 +292,18 @@ class InterProcessLock::Pimpl { public: Pimpl (String name, const int timeOutMillisecs) - : handle (0), refCount (1) + : handle (nullptr), refCount (1) { name = name.replaceCharacter ('\\', '/'); - handle = CreateMutexW (0, TRUE, ("Global\\" + name).toWideCharPointer()); + handle = CreateMutexW (nullptr, TRUE, ("Global\\" + name).toWideCharPointer()); // Not 100% sure why a global mutex sometimes can't be allocated, but if it fails, fall back to // a local one. (A local one also sometimes fails on other machines so neither type appears to be // universally reliable) - if (handle == 0) - handle = CreateMutexW (0, TRUE, ("Local\\" + name).toWideCharPointer()); + if (handle == nullptr) + handle = CreateMutexW (nullptr, TRUE, ("Local\\" + name).toWideCharPointer()); - if (handle != 0 && GetLastError() == ERROR_ALREADY_EXISTS) + if (handle != nullptr && GetLastError() == ERROR_ALREADY_EXISTS) { if (timeOutMillisecs == 0) { @@ -311,7 +311,7 @@ public: return; } - switch (WaitForSingleObject (handle, timeOutMillisecs < 0 ? INFINITE : timeOutMillisecs)) + switch (WaitForSingleObject (handle, timeOutMillisecs < 0 ? INFINITE : (DWORD) timeOutMillisecs)) { case WAIT_OBJECT_0: case WAIT_ABANDONED: @@ -332,11 +332,11 @@ public: void close() { - if (handle != 0) + if (handle != nullptr) { ReleaseMutex (handle); CloseHandle (handle); - handle = 0; + handle = nullptr; } } @@ -361,7 +361,7 @@ bool InterProcessLock::enter (const int timeOutMillisecs) { pimpl.reset (new Pimpl (name, timeOutMillisecs)); - if (pimpl->handle == 0) + if (pimpl->handle == nullptr) pimpl.reset(); } else @@ -388,20 +388,20 @@ class ChildProcess::ActiveProcess { public: ActiveProcess (const String& command, int streamFlags) - : ok (false), readPipe (0), writePipe (0) + : ok (false), readPipe (nullptr), writePipe (nullptr) { - SECURITY_ATTRIBUTES securityAtts = { 0 }; + SECURITY_ATTRIBUTES securityAtts = {}; securityAtts.nLength = sizeof (securityAtts); securityAtts.bInheritHandle = TRUE; if (CreatePipe (&readPipe, &writePipe, &securityAtts, 0) && SetHandleInformation (readPipe, HANDLE_FLAG_INHERIT, 0)) { - STARTUPINFOW startupInfo = { 0 }; + STARTUPINFOW startupInfo = {}; startupInfo.cb = sizeof (startupInfo); - startupInfo.hStdOutput = (streamFlags & wantStdOut) != 0 ? writePipe : 0; - startupInfo.hStdError = (streamFlags & wantStdErr) != 0 ? writePipe : 0; + startupInfo.hStdOutput = (streamFlags & wantStdOut) != 0 ? writePipe : nullptr; + startupInfo.hStdError = (streamFlags & wantStdErr) != 0 ? writePipe : nullptr; startupInfo.dwFlags = STARTF_USESTDHANDLES; ok = CreateProcess (nullptr, const_cast<LPWSTR> (command.toWideCharPointer()), @@ -418,10 +418,10 @@ public: CloseHandle (processInfo.hProcess); } - if (readPipe != 0) + if (readPipe != nullptr) CloseHandle (readPipe); - if (writePipe != 0) + if (writePipe != nullptr) CloseHandle (writePipe); } @@ -448,17 +448,17 @@ public: if (! isRunning()) break; - Thread::yield(); + Thread::sleep (1); } else { DWORD numRead = 0; - if (! ReadFile ((HANDLE) readPipe, dest, numToDo, &numRead, nullptr)) + if (! ReadFile ((HANDLE) readPipe, dest, (DWORD) numToDo, &numRead, nullptr)) break; - total += numRead; + total += (int) numRead; dest = addBytesToPointer (dest, numRead); - numNeeded -= numRead; + numNeeded -= (int) numRead; } } @@ -539,7 +539,7 @@ struct HighResolutionTimer::Pimpl { const int actualPeriod = jlimit ((int) tc.wPeriodMin, (int) tc.wPeriodMax, newPeriod); - timerID = timeSetEvent (actualPeriod, tc.wPeriodMin, callbackFunction, (DWORD_PTR) this, + timerID = timeSetEvent ((UINT) actualPeriod, tc.wPeriodMin, callbackFunction, (DWORD_PTR) this, TIME_PERIODIC | TIME_CALLBACK_FUNCTION | 0x100 /*TIME_KILL_SYNCHRONOUS*/); } } diff --git a/modules/juce_core/network/juce_IPAddress.cpp b/modules/juce_core/network/juce_IPAddress.cpp index 35b34431..641df10f 100644 --- a/modules/juce_core/network/juce_IPAddress.cpp +++ b/modules/juce_core/network/juce_IPAddress.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -90,10 +90,10 @@ IPAddress::IPAddress (uint16 a1, uint16 a2, uint16 a3, uint16 a4, IPAddress::IPAddress (uint32 n) noexcept : isIPv6 (false) { - address[0] = (n >> 24); - address[1] = (n >> 16) & 255; - address[2] = (n >> 8) & 255; - address[3] = (n & 255); + address[0] = static_cast<uint8> (n >> 24); + address[1] = static_cast<uint8> ((n >> 16) & 255); + address[2] = static_cast<uint8> ((n >> 8) & 255); + address[3] = static_cast<uint8> ((n & 255)); zeroUnusedBytes (address); } diff --git a/modules/juce_core/network/juce_IPAddress.h b/modules/juce_core/network/juce_IPAddress.h index 47e929ba..9387cf5a 100644 --- a/modules/juce_core/network/juce_IPAddress.h +++ b/modules/juce_core/network/juce_IPAddress.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/network/juce_MACAddress.cpp b/modules/juce_core/network/juce_MACAddress.cpp index cf703352..b1dcfffc 100644 --- a/modules/juce_core/network/juce_MACAddress.cpp +++ b/modules/juce_core/network/juce_MACAddress.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/network/juce_MACAddress.h b/modules/juce_core/network/juce_MACAddress.h index d174ba16..dcb176b0 100644 --- a/modules/juce_core/network/juce_MACAddress.h +++ b/modules/juce_core/network/juce_MACAddress.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/network/juce_NamedPipe.cpp b/modules/juce_core/network/juce_NamedPipe.cpp index 4333b80c..c39ac66d 100644 --- a/modules/juce_core/network/juce_NamedPipe.cpp +++ b/modules/juce_core/network/juce_NamedPipe.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -41,6 +41,7 @@ bool NamedPipe::openExisting (const String& pipeName) bool NamedPipe::isOpen() const { + ScopedReadLock sl (lock); return pimpl != nullptr; } @@ -55,6 +56,7 @@ bool NamedPipe::createNewPipe (const String& pipeName, bool mustNotExist) String NamedPipe::getName() const { + ScopedReadLock sl (lock); return currentPipeName; } @@ -75,7 +77,7 @@ public: void runTest() override { - const String pipeName ("TestPipe"); + const auto pipeName = "TestPipe" + String ((intptr_t) Thread::getCurrentThreadId()); beginTest ("Pre test cleanup"); { @@ -208,11 +210,6 @@ private: pipe.openExisting (pipeName); } - ~NamedPipeThread() - { - stopThread (100); - } - NamedPipe pipe; const String& pipeName; WaitableEvent& workCompleted; @@ -229,6 +226,11 @@ private: sendData (sData) {} + ~SenderThread() override + { + stopThread (100); + } + void run() override { result = pipe.write (&sendData, sizeof (sendData), 2000); @@ -246,6 +248,11 @@ private: : NamedPipeThread ("NamePipeSender", pName, shouldCreatePipe, completed) {} + ~ReceiverThread() override + { + stopThread (100); + } + void run() override { result = pipe.read (&recvData, sizeof (recvData), 2000); diff --git a/modules/juce_core/network/juce_NamedPipe.h b/modules/juce_core/network/juce_NamedPipe.h index 67c2cfad..0d30a9b1 100644 --- a/modules/juce_core/network/juce_NamedPipe.h +++ b/modules/juce_core/network/juce_NamedPipe.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/network/juce_Socket.cpp b/modules/juce_core/network/juce_Socket.cpp index 1e28be5a..64168aa7 100644 --- a/modules/juce_core/network/juce_Socket.cpp +++ b/modules/juce_core/network/juce_Socket.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -23,10 +23,7 @@ namespace juce { -#if JUCE_MSVC - #pragma warning (push) - #pragma warning (disable : 4127 4389 4018) -#endif +JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4127 4389 4018) #ifndef AI_NUMERICSERV // (missing in older Mac SDKs) #define AI_NUMERICSERV 0x1000 @@ -97,7 +94,7 @@ namespace SocketHelpers static void closeSocket (std::atomic<int>& handle, CriticalSection& readLock, bool isListener, int portNumber, std::atomic<bool>& connected) noexcept { - const SocketHandle h = handle.load(); + const auto h = (SocketHandle) handle.load(); handle = -1; #if JUCE_WINDOWS @@ -190,7 +187,7 @@ namespace SocketHelpers { #if JUCE_WINDOWS u_long nonBlocking = shouldBlock ? 0 : (u_long) 1; - return ioctlsocket (handle, FIONBIO, &nonBlocking) == 0; + return ioctlsocket (handle, (long) FIONBIO, &nonBlocking) == 0; #else int socketFlags = fcntl (handle, F_GETFL, 0); @@ -265,7 +262,7 @@ namespace SocketHelpers break; } - bytesRead += bytesThisTime; + bytesRead = static_cast<int> (bytesRead + bytesThisTime); if (! blockUntilSpecifiedAmountHasArrived) break; @@ -283,9 +280,9 @@ namespace SocketHelpers if (! lock.isLocked()) return -1; - auto hasErrorOccurred = [&handle] () -> bool + auto hasErrorOccurred = [&handle]() -> bool { - auto h = handle.load(); + auto h = (SocketHandle) handle.load(); if (h == invalidSocket) return true; @@ -318,9 +315,9 @@ namespace SocketHelpers fd_set rset, wset; FD_ZERO (&rset); - FD_SET (h, &rset); + FD_SET ((SOCKET) h, &rset); FD_ZERO (&wset); - FD_SET (h, &wset); + FD_SET ((SOCKET) h, &wset); fd_set* prset = forReading ? &rset : nullptr; fd_set* pwset = forReading ? nullptr : &wset; @@ -421,8 +418,9 @@ namespace SocketHelpers if (success) { - setSocketBlockingState (handle, true); - resetSocketOptions (handle, false, false); + auto h = (SocketHandle) handle.load(); + setSocketBlockingState (h, true); + resetSocketOptions (h, false, false); } } @@ -431,7 +429,7 @@ namespace SocketHelpers static void makeReusable (int handle) noexcept { - setOption (handle, SO_REUSEADDR, (int) 1); + setOption ((SocketHandle) handle, SO_REUSEADDR, (int) 1); } static bool multicast (int handle, const String& multicastIPAddress, @@ -446,7 +444,7 @@ namespace SocketHelpers if (interfaceIPAddress.isNotEmpty()) mreq.imr_interface.s_addr = inet_addr (interfaceIPAddress.toRawUTF8()); - return setsockopt (handle, IPPROTO_IP, + return setsockopt ((SocketHandle) handle, IPPROTO_IP, join ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP, (const char*) &mreq, sizeof (mreq)) == 0; @@ -468,7 +466,7 @@ StreamingSocket::StreamingSocket (const String& host, int portNum, int h) jassert (SocketHelpers::isValidPortNumber (portNum)); SocketHelpers::initSockets(); - SocketHelpers::resetSocketOptions (h, false, false); + SocketHelpers::resetSocketOptions ((SocketHandle) h, false, false); } StreamingSocket::~StreamingSocket() @@ -479,7 +477,7 @@ StreamingSocket::~StreamingSocket() //============================================================================== int StreamingSocket::read (void* destBuffer, int maxBytesToRead, bool shouldBlock) { - return (connected && ! isListener) ? SocketHelpers::readSocket (handle, destBuffer, maxBytesToRead, + return (connected && ! isListener) ? SocketHelpers::readSocket ((SocketHandle) handle.load(), destBuffer,maxBytesToRead, connected, shouldBlock, readLock) : -1; } @@ -489,7 +487,7 @@ int StreamingSocket::write (const void* sourceBuffer, int numBytesToWrite) if (isListener || ! connected) return -1; - return (int) ::send (handle, (const char*) sourceBuffer, (juce_recvsend_size_t) numBytesToWrite, 0); + return (int) ::send ((SocketHandle) handle.load(), (const char*) sourceBuffer, (juce_recvsend_size_t) numBytesToWrite, 0); } //============================================================================== @@ -509,12 +507,12 @@ bool StreamingSocket::bindToPort (int port, const String& addr) { jassert (SocketHelpers::isValidPortNumber (port)); - return SocketHelpers::bindSocket (handle, port, addr); + return SocketHelpers::bindSocket ((SocketHandle) handle.load(), port, addr); } int StreamingSocket::getBoundPort() const noexcept { - return SocketHelpers::getBoundPort (handle); + return SocketHelpers::getBoundPort ((SocketHandle) handle.load()); } bool StreamingSocket::connect (const String& remoteHostName, int remotePortNumber, int timeOutMillisecs) @@ -541,7 +539,7 @@ bool StreamingSocket::connect (const String& remoteHostName, int remotePortNumbe if (! connected) return false; - if (! SocketHelpers::resetSocketOptions (handle, false, false)) + if (! SocketHelpers::resetSocketOptions ((SocketHandle) handle.load(), false, false)) { close(); return false; @@ -582,8 +580,8 @@ bool StreamingSocket::createListener (int newPortNumber, const String& localHost SocketHelpers::makeReusable (handle); #endif - if (SocketHelpers::bindSocket (handle, portNumber, localHostName) - && listen (handle, SOMAXCONN) >= 0) + if (SocketHelpers::bindSocket ((SocketHandle) handle.load(), portNumber, localHostName) + && listen ((SocketHandle) handle.load(), SOMAXCONN) >= 0) { connected = true; return true; @@ -603,7 +601,7 @@ StreamingSocket* StreamingSocket::waitForNextConnection() const { struct sockaddr_storage address; juce_socklen_t len = sizeof (address); - auto newSocket = (int) accept (handle, (struct sockaddr*) &address, &len); + auto newSocket = (int) accept ((SocketHandle) handle.load(), (struct sockaddr*) &address, &len); if (newSocket >= 0 && connected) return new StreamingSocket (inet_ntoa (((struct sockaddr_in*) &address)->sin_addr), @@ -618,7 +616,7 @@ bool StreamingSocket::isLocal() const noexcept if (! isConnected()) return false; - IPAddress currentIP (SocketHelpers::getConnectedAddress (handle)); + IPAddress currentIP (SocketHelpers::getConnectedAddress ((SocketHandle) handle.load())); for (auto& a : IPAddress::getAllAddresses()) if (a == currentIP) @@ -638,7 +636,7 @@ DatagramSocket::DatagramSocket (bool canBroadcast) if (handle >= 0) { - SocketHelpers::resetSocketOptions (handle, true, canBroadcast); + SocketHelpers::resetSocketOptions ((SocketHandle) handle.load(), true, canBroadcast); SocketHelpers::makeReusable (handle); } } @@ -677,7 +675,7 @@ bool DatagramSocket::bindToPort (int port, const String& addr) if (handle < 0) return false; - if (SocketHelpers::bindSocket (handle, port, addr)) + if (SocketHelpers::bindSocket ((SocketHandle) handle.load(), port, addr)) { isBound = true; lastBindAddress = addr; @@ -689,7 +687,7 @@ bool DatagramSocket::bindToPort (int port, const String& addr) int DatagramSocket::getBoundPort() const noexcept { - return (handle >= 0 && isBound) ? SocketHelpers::getBoundPort (handle) : -1; + return (handle >= 0 && isBound) ? SocketHelpers::getBoundPort ((SocketHandle) handle.load()) : -1; } //============================================================================== @@ -707,7 +705,7 @@ int DatagramSocket::read (void* destBuffer, int maxBytesToRead, bool shouldBlock return -1; std::atomic<bool> connected { true }; - return SocketHelpers::readSocket (handle, destBuffer, maxBytesToRead, + return SocketHelpers::readSocket ((SocketHandle) handle.load(), destBuffer, maxBytesToRead, connected, shouldBlock, readLock); } @@ -717,7 +715,7 @@ int DatagramSocket::read (void* destBuffer, int maxBytesToRead, bool shouldBlock return -1; std::atomic<bool> connected { true }; - return SocketHelpers::readSocket (handle, destBuffer, maxBytesToRead, connected, + return SocketHelpers::readSocket ((SocketHandle) handle.load(), destBuffer, maxBytesToRead, connected, shouldBlock, readLock, &senderIPAddress, &senderPort); } @@ -744,7 +742,7 @@ int DatagramSocket::write (const String& remoteHostname, int remotePortNumber, lastServerPort = remotePortNumber; } - return (int) ::sendto (handle, (const char*) sourceBuffer, + return (int) ::sendto ((SocketHandle) handle.load(), (const char*) sourceBuffer, (juce_recvsend_size_t) numBytesToWrite, 0, info->ai_addr, (socklen_t) info->ai_addrlen); } @@ -770,7 +768,7 @@ bool DatagramSocket::setMulticastLoopbackEnabled (bool enable) if (handle < 0 || ! isBound) return false; - return SocketHelpers::setOption<bool> (handle, IPPROTO_IP, IP_MULTICAST_LOOP, enable); + return SocketHelpers::setOption<bool> ((SocketHandle) handle.load(), IPPROTO_IP, IP_MULTICAST_LOOP, enable); } bool DatagramSocket::setEnablePortReuse (bool enabled) @@ -779,7 +777,7 @@ bool DatagramSocket::setEnablePortReuse (bool enabled) ignoreUnused (enabled); #else if (handle >= 0) - return SocketHelpers::setOption (handle, + return SocketHelpers::setOption ((SocketHandle) handle.load(), #if JUCE_WINDOWS || JUCE_LINUX SO_REUSEADDR, // port re-use is implied by addr re-use on these platforms #else @@ -791,10 +789,7 @@ bool DatagramSocket::setEnablePortReuse (bool enabled) return false; } -#if JUCE_MSVC - #pragma warning (pop) -#endif - +JUCE_END_IGNORE_WARNINGS_MSVC //============================================================================== //============================================================================== @@ -819,7 +814,7 @@ struct SocketTests : public UnitTest expect (socketServer.isConnected() == false); expect (socketServer.getHostName().isEmpty()); expect (socketServer.getBoundPort() == -1); - expect (socketServer.getRawSocketHandle() == invalidSocket); + expect (static_cast<SocketHandle> (socketServer.getRawSocketHandle()) == invalidSocket); expect (socketServer.createListener (portNum, localHost.toString())); @@ -830,14 +825,14 @@ struct SocketTests : public UnitTest expect (socket.isConnected() == true); expect (socket.getHostName() == localHost.toString()); expect (socket.getBoundPort() != -1); - expect (socket.getRawSocketHandle() != invalidSocket); + expect (static_cast<SocketHandle> (socket.getRawSocketHandle()) != invalidSocket); socket.close(); expect (socket.isConnected() == false); expect (socket.getHostName().isEmpty()); expect (socket.getBoundPort() == -1); - expect (socket.getRawSocketHandle() == invalidSocket); + expect (static_cast<SocketHandle> (socket.getRawSocketHandle()) == invalidSocket); } beginTest ("DatagramSocket"); @@ -845,17 +840,17 @@ struct SocketTests : public UnitTest DatagramSocket socket; expect (socket.getBoundPort() == -1); - expect (socket.getRawSocketHandle() != invalidSocket); + expect (static_cast<SocketHandle> (socket.getRawSocketHandle()) != invalidSocket); expect (socket.bindToPort (portNum, localHost.toString())); expect (socket.getBoundPort() == portNum); - expect (socket.getRawSocketHandle() != invalidSocket); + expect (static_cast<SocketHandle> (socket.getRawSocketHandle()) != invalidSocket); socket.shutdown(); expect (socket.getBoundPort() == -1); - expect (socket.getRawSocketHandle() == invalidSocket); + expect (static_cast<SocketHandle> (socket.getRawSocketHandle()) == invalidSocket); } } }; diff --git a/modules/juce_core/network/juce_Socket.h b/modules/juce_core/network/juce_Socket.h index 2f30d0ce..029f8fa1 100644 --- a/modules/juce_core/network/juce_Socket.h +++ b/modules/juce_core/network/juce_Socket.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/network/juce_URL.cpp b/modules/juce_core/network/juce_URL.cpp index 56f2a3ce..36307db8 100644 --- a/modules/juce_core/network/juce_URL.cpp +++ b/modules/juce_core/network/juce_URL.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -26,13 +26,13 @@ namespace juce struct FallbackDownloadTask : public URL::DownloadTask, public Thread { - FallbackDownloadTask (FileOutputStream* outputStreamToUse, + FallbackDownloadTask (std::unique_ptr<FileOutputStream> outputStreamToUse, size_t bufferSizeToUse, - WebInputStream* streamToUse, + std::unique_ptr<WebInputStream> streamToUse, URL::DownloadTask::Listener* listenerToUse) : Thread ("DownloadTask thread"), - fileStream (outputStreamToUse), - stream (streamToUse), + fileStream (std::move (outputStreamToUse)), + stream (std::move (streamToUse)), bufferSize (bufferSizeToUse), buffer (bufferSize), listener (listenerToUse) @@ -110,22 +110,25 @@ void URL::DownloadTask::Listener::progress (DownloadTask*, int64, int64) {} URL::DownloadTask::Listener::~Listener() {} //============================================================================== -URL::DownloadTask* URL::DownloadTask::createFallbackDownloader (const URL& urlToUse, - const File& targetFileToUse, - const String& extraHeadersToUse, - Listener* listenerToUse, - bool usePostRequest) +std::unique_ptr<URL::DownloadTask> URL::DownloadTask::createFallbackDownloader (const URL& urlToUse, + const File& targetFileToUse, + const String& extraHeadersToUse, + Listener* listenerToUse, + bool usePostRequest) { const size_t bufferSize = 0x8000; targetFileToUse.deleteFile(); - if (auto outputStream = std::unique_ptr<FileOutputStream> (targetFileToUse.createOutputStream (bufferSize))) + if (auto outputStream = targetFileToUse.createOutputStream (bufferSize)) { - std::unique_ptr<WebInputStream> stream (new WebInputStream (urlToUse, usePostRequest)); + auto stream = std::make_unique<WebInputStream> (urlToUse, usePostRequest); stream->withExtraHeaders (extraHeadersToUse); if (stream->connect (nullptr)) - return new FallbackDownloadTask (outputStream.release(), bufferSize, stream.release(), listenerToUse); + return std::make_unique<FallbackDownloadTask> (std::move (outputStream), + bufferSize, + std::move (stream), + listenerToUse); } return nullptr; @@ -655,21 +658,21 @@ private: #endif //============================================================================== -InputStream* URL::createInputStream (bool usePostCommand, - OpenStreamProgressCallback* progressCallback, - void* progressCallbackContext, - String headers, - int timeOutMs, - StringPairArray* responseHeaders, - int* statusCode, - int numRedirectsToFollow, - String httpRequestCmd) const +std::unique_ptr<InputStream> URL::createInputStream (bool usePostCommand, + OpenStreamProgressCallback* progressCallback, + void* progressCallbackContext, + String headers, + int timeOutMs, + StringPairArray* responseHeaders, + int* statusCode, + int numRedirectsToFollow, + String httpRequestCmd) const { if (isLocalFile()) { #if JUCE_IOS // We may need to refresh the embedded bookmark. - return new iOSFileStreamWrapper<FileInputStream> (const_cast<URL&>(*this)); + return std::make_unique<iOSFileStreamWrapper<FileInputStream>> (const_cast<URL&>(*this)); #else return getLocalFile().createInputStream(); #endif @@ -717,27 +720,29 @@ InputStream* URL::createInputStream (bool usePostCommand, if (! success || wi->isError()) return nullptr; - return wi.release(); + // Older GCCs complain about binding unique_ptr<WebInputStream>&& to unique_ptr<InputStream> + // if we just `return wi` here. + return std::unique_ptr<InputStream> (std::move (wi)); } #if JUCE_ANDROID OutputStream* juce_CreateContentURIOutputStream (const URL&); #endif -OutputStream* URL::createOutputStream() const +std::unique_ptr<OutputStream> URL::createOutputStream() const { if (isLocalFile()) { #if JUCE_IOS // We may need to refresh the embedded bookmark. - return new iOSFileStreamWrapper<FileOutputStream> (const_cast<URL&> (*this)); + return std::make_unique<iOSFileStreamWrapper<FileOutputStream>> (const_cast<URL&> (*this)); #else - return new FileOutputStream (getLocalFile()); + return std::make_unique<FileOutputStream> (getLocalFile()); #endif } #if JUCE_ANDROID - return juce_CreateContentURIOutputStream (*this); + return std::unique_ptr<OutputStream> (juce_CreateContentURIOutputStream (*this)); #else return nullptr; #endif diff --git a/modules/juce_core/network/juce_URL.h b/modules/juce_core/network/juce_URL.h index 6e608822..9a573a7e 100644 --- a/modules/juce_core/network/juce_URL.h +++ b/modules/juce_core/network/juce_URL.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -337,25 +337,24 @@ public: returning a response (ignored for Android which follows up to 5 redirects) @param httpRequestCmd Specify which HTTP Request to use. If this is empty, then doPostRequest will determine the HTTP request. - @returns an input stream that the caller must delete, or a null pointer if there was an - error trying to open it. + @returns a valid input stream, or nullptr if there was an error trying to open it. */ - InputStream* createInputStream (bool doPostLikeRequest, - OpenStreamProgressCallback* progressCallback = nullptr, - void* progressCallbackContext = nullptr, - String extraHeaders = {}, - int connectionTimeOutMs = 0, - StringPairArray* responseHeaders = nullptr, - int* statusCode = nullptr, - int numRedirectsToFollow = 5, - String httpRequestCmd = {}) const; + std::unique_ptr<InputStream> createInputStream (bool doPostLikeRequest, + OpenStreamProgressCallback* progressCallback = nullptr, + void* progressCallbackContext = nullptr, + String extraHeaders = {}, + int connectionTimeOutMs = 0, + StringPairArray* responseHeaders = nullptr, + int* statusCode = nullptr, + int numRedirectsToFollow = 5, + String httpRequestCmd = {}) const; /** Attempts to open an output stream to a URL for writing This method can only be used for certain scheme types such as local files and content:// URIs on Android. */ - OutputStream* createOutputStream() const; + std::unique_ptr<OutputStream> createOutputStream() const; //============================================================================== /** Represents a download task. @@ -415,7 +414,7 @@ public: private: friend class URL; - static DownloadTask* createFallbackDownloader (const URL&, const File&, const String&, Listener*, bool); + static std::unique_ptr<DownloadTask> createFallbackDownloader (const URL&, const File&, const String&, Listener*, bool); public: #if JUCE_IOS @@ -436,10 +435,10 @@ public: using a native OS background network task. Such tasks automatically deal with network re-connections and continuing your download while your app is suspended. */ - DownloadTask* downloadToFile (const File& targetLocation, - String extraHeaders = String(), - DownloadTask::Listener* listener = nullptr, - bool usePostCommand = false); + std::unique_ptr<DownloadTask> downloadToFile (const File& targetLocation, + String extraHeaders = String(), + DownloadTask::Listener* listener = nullptr, + bool usePostCommand = false); //============================================================================== /** Tries to download the entire contents of this URL into a binary data block. @@ -479,9 +478,6 @@ public: If it fails, or if the text that it reads can't be parsed as XML, this will return nullptr. - When it returns a valid XmlElement object, the caller is responsible for deleting - this object when no longer needed. - Note that on some platforms (Android, for example) it's not permitted to do any network action from the message thread, so you must only call it from a background thread. diff --git a/modules/juce_core/network/juce_WebInputStream.cpp b/modules/juce_core/network/juce_WebInputStream.cpp index 6c32c722..38eda150 100644 --- a/modules/juce_core/network/juce_WebInputStream.cpp +++ b/modules/juce_core/network/juce_WebInputStream.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/network/juce_WebInputStream.h b/modules/juce_core/network/juce_WebInputStream.h index b4a81944..b8d4a54a 100644 --- a/modules/juce_core/network/juce_WebInputStream.h +++ b/modules/juce_core/network/juce_WebInputStream.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/streams/juce_BufferedInputStream.cpp b/modules/juce_core/streams/juce_BufferedInputStream.cpp index 5c525330..ddc2d23f 100644 --- a/modules/juce_core/streams/juce_BufferedInputStream.cpp +++ b/modules/juce_core/streams/juce_BufferedInputStream.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -23,7 +23,7 @@ namespace juce { -static inline int calcBufferStreamBufferSize (int requestedSize, InputStream* source) noexcept +static int calcBufferStreamBufferSize (int requestedSize, InputStream* source) noexcept { // You need to supply a real stream when creating a BufferedInputStream jassert (source != nullptr); diff --git a/modules/juce_core/streams/juce_BufferedInputStream.h b/modules/juce_core/streams/juce_BufferedInputStream.h index c1521bcf..42ca402f 100644 --- a/modules/juce_core/streams/juce_BufferedInputStream.h +++ b/modules/juce_core/streams/juce_BufferedInputStream.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/streams/juce_FileInputSource.cpp b/modules/juce_core/streams/juce_FileInputSource.cpp index feb4081a..6cd45a9b 100644 --- a/modules/juce_core/streams/juce_FileInputSource.cpp +++ b/modules/juce_core/streams/juce_FileInputSource.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -34,12 +34,12 @@ FileInputSource::~FileInputSource() InputStream* FileInputSource::createInputStream() { - return file.createInputStream(); + return file.createInputStream().release(); } InputStream* FileInputSource::createInputStreamFor (const String& relatedItemPath) { - return file.getSiblingFile (relatedItemPath).createInputStream(); + return file.getSiblingFile (relatedItemPath).createInputStream().release(); } int64 FileInputSource::hashCode() const diff --git a/modules/juce_core/streams/juce_FileInputSource.h b/modules/juce_core/streams/juce_FileInputSource.h index 01e72684..be49581b 100644 --- a/modules/juce_core/streams/juce_FileInputSource.h +++ b/modules/juce_core/streams/juce_FileInputSource.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/streams/juce_InputSource.h b/modules/juce_core/streams/juce_InputSource.h index 847de1e5..01f110d1 100644 --- a/modules/juce_core/streams/juce_InputSource.h +++ b/modules/juce_core/streams/juce_InputSource.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/streams/juce_InputStream.cpp b/modules/juce_core/streams/juce_InputStream.cpp index 79c66ac9..d68b3ded 100644 --- a/modules/juce_core/streams/juce_InputStream.cpp +++ b/modules/juce_core/streams/juce_InputStream.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/streams/juce_InputStream.h b/modules/juce_core/streams/juce_InputStream.h index 8d774795..95e69294 100644 --- a/modules/juce_core/streams/juce_InputStream.h +++ b/modules/juce_core/streams/juce_InputStream.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/streams/juce_MemoryInputStream.cpp b/modules/juce_core/streams/juce_MemoryInputStream.cpp index cd7aa09e..89924c57 100644 --- a/modules/juce_core/streams/juce_MemoryInputStream.cpp +++ b/modules/juce_core/streams/juce_MemoryInputStream.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -49,6 +49,7 @@ MemoryInputStream::MemoryInputStream (MemoryBlock&& source) : internalCopy (std::move (source)) { data = internalCopy.getData(); + dataSize = internalCopy.getSize(); } MemoryInputStream::~MemoryInputStream() diff --git a/modules/juce_core/streams/juce_MemoryInputStream.h b/modules/juce_core/streams/juce_MemoryInputStream.h index 01aef62a..970ff5cd 100644 --- a/modules/juce_core/streams/juce_MemoryInputStream.h +++ b/modules/juce_core/streams/juce_MemoryInputStream.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/streams/juce_MemoryOutputStream.cpp b/modules/juce_core/streams/juce_MemoryOutputStream.cpp index 1f320049..2f83dbd3 100644 --- a/modules/juce_core/streams/juce_MemoryOutputStream.cpp +++ b/modules/juce_core/streams/juce_MemoryOutputStream.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/streams/juce_MemoryOutputStream.h b/modules/juce_core/streams/juce_MemoryOutputStream.h index 231a7f5f..cc145acf 100644 --- a/modules/juce_core/streams/juce_MemoryOutputStream.h +++ b/modules/juce_core/streams/juce_MemoryOutputStream.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/streams/juce_OutputStream.cpp b/modules/juce_core/streams/juce_OutputStream.cpp index c2eb06f5..ca868fae 100644 --- a/modules/juce_core/streams/juce_OutputStream.cpp +++ b/modules/juce_core/streams/juce_OutputStream.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/streams/juce_OutputStream.h b/modules/juce_core/streams/juce_OutputStream.h index f41cbc12..80f78ed6 100644 --- a/modules/juce_core/streams/juce_OutputStream.h +++ b/modules/juce_core/streams/juce_OutputStream.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/streams/juce_SubregionStream.cpp b/modules/juce_core/streams/juce_SubregionStream.cpp index c787e1f0..84b444f5 100644 --- a/modules/juce_core/streams/juce_SubregionStream.cpp +++ b/modules/juce_core/streams/juce_SubregionStream.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/streams/juce_SubregionStream.h b/modules/juce_core/streams/juce_SubregionStream.h index 4b728d0a..006443c2 100644 --- a/modules/juce_core/streams/juce_SubregionStream.h +++ b/modules/juce_core/streams/juce_SubregionStream.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/streams/juce_URLInputSource.cpp b/modules/juce_core/streams/juce_URLInputSource.cpp index 0ecddbb9..07768f08 100644 --- a/modules/juce_core/streams/juce_URLInputSource.cpp +++ b/modules/juce_core/streams/juce_URLInputSource.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -39,7 +39,7 @@ URLInputSource::~URLInputSource() InputStream* URLInputSource::createInputStream() { - return u.createInputStream (false); + return u.createInputStream (false).release(); } InputStream* URLInputSource::createInputStreamFor (const String& relatedItemPath) @@ -48,7 +48,7 @@ InputStream* URLInputSource::createInputStreamFor (const String& relatedItemPath auto parent = sub.containsChar (L'/') ? sub.upToLastOccurrenceOf ("/", false, false) : String (); - return u.withNewSubPath (parent).getChildURL (relatedItemPath).createInputStream (false); + return u.withNewSubPath (parent).getChildURL (relatedItemPath).createInputStream (false).release(); } int64 URLInputSource::hashCode() const diff --git a/modules/juce_core/streams/juce_URLInputSource.h b/modules/juce_core/streams/juce_URLInputSource.h index c30dfa6d..1b16cdc8 100644 --- a/modules/juce_core/streams/juce_URLInputSource.h +++ b/modules/juce_core/streams/juce_URLInputSource.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/system/juce_CompilerSupport.h b/modules/juce_core/system/juce_CompilerSupport.h index 42712c73..e4d87ab9 100644 --- a/modules/juce_core/system/juce_CompilerSupport.h +++ b/modules/juce_core/system/juce_CompilerSupport.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -38,10 +38,6 @@ #error "JUCE requires that GCC has C++11 compatibility enabled" #endif - #if (__GNUC__ * 100 + __GNUC_MINOR__) >= 500 - #define JUCE_HAS_CONSTEXPR 1 - #endif - #ifndef JUCE_EXCEPTIONS_DISABLED #if ! __EXCEPTIONS #define JUCE_EXCEPTIONS_DISABLED 1 @@ -61,8 +57,6 @@ #error "JUCE requires Clang 3.3 or later" #endif - #define JUCE_HAS_CONSTEXPR 1 - #ifndef JUCE_COMPILER_SUPPORTS_ARC #define JUCE_COMPILER_SUPPORTS_ARC 1 #endif @@ -86,8 +80,6 @@ #error "JUCE requires Visual Studio 2015 or later" #endif - #define JUCE_HAS_CONSTEXPR 1 - #ifndef JUCE_EXCEPTIONS_DISABLED #if ! _CPPUNWIND #define JUCE_EXCEPTIONS_DISABLED 1 @@ -105,12 +97,6 @@ #endif //============================================================================== -#if JUCE_HAS_CONSTEXPR - #define JUCE_CONSTEXPR constexpr -#else - #define JUCE_CONSTEXPR -#endif - #if (! JUCE_MSVC) && (! JUCE_CXX14_IS_AVAILABLE) namespace std { @@ -122,6 +108,7 @@ namespace std } #endif +//============================================================================== #if ! DOXYGEN // These are old flags that are now supported on all compatible build targets #define JUCE_COMPILER_SUPPORTS_OVERRIDE_AND_FINAL 1 @@ -129,4 +116,5 @@ namespace std #define JUCE_COMPILER_SUPPORTS_INITIALIZER_LISTS 1 #define JUCE_COMPILER_SUPPORTS_NOEXCEPT 1 #define JUCE_DELETED_FUNCTION = delete + #define JUCE_CONSTEXPR constexpr #endif diff --git a/modules/juce_core/system/juce_CompilerWarnings.h b/modules/juce_core/system/juce_CompilerWarnings.h new file mode 100644 index 00000000..07cc1c56 --- /dev/null +++ b/modules/juce_core/system/juce_CompilerWarnings.h @@ -0,0 +1,200 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + To use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +#pragma once + +#include "juce_TargetPlatform.h" + +/** Return the Nth argument. By passing a variadic pack followed by N other + parameters, we can select one of those N parameter based on the length of + the parameter pack. +*/ +#define JUCE_NTH_ARG_(_00, _01, _02, _03, _04, _05, _06, _07, _08, _09, \ + _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, \ + _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, \ + _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, N, ...)\ + N + +#define JUCE_EACH_00_(FN) +#define JUCE_EACH_01_(FN, X) FN(X) +#define JUCE_EACH_02_(FN, X, ...) FN(X) JUCE_EACH_01_(FN, __VA_ARGS__) +#define JUCE_EACH_03_(FN, X, ...) FN(X) JUCE_EACH_02_(FN, __VA_ARGS__) +#define JUCE_EACH_04_(FN, X, ...) FN(X) JUCE_EACH_03_(FN, __VA_ARGS__) +#define JUCE_EACH_05_(FN, X, ...) FN(X) JUCE_EACH_04_(FN, __VA_ARGS__) +#define JUCE_EACH_06_(FN, X, ...) FN(X) JUCE_EACH_05_(FN, __VA_ARGS__) +#define JUCE_EACH_07_(FN, X, ...) FN(X) JUCE_EACH_06_(FN, __VA_ARGS__) +#define JUCE_EACH_08_(FN, X, ...) FN(X) JUCE_EACH_07_(FN, __VA_ARGS__) +#define JUCE_EACH_09_(FN, X, ...) FN(X) JUCE_EACH_08_(FN, __VA_ARGS__) +#define JUCE_EACH_10_(FN, X, ...) FN(X) JUCE_EACH_09_(FN, __VA_ARGS__) +#define JUCE_EACH_11_(FN, X, ...) FN(X) JUCE_EACH_10_(FN, __VA_ARGS__) +#define JUCE_EACH_12_(FN, X, ...) FN(X) JUCE_EACH_11_(FN, __VA_ARGS__) +#define JUCE_EACH_13_(FN, X, ...) FN(X) JUCE_EACH_12_(FN, __VA_ARGS__) +#define JUCE_EACH_14_(FN, X, ...) FN(X) JUCE_EACH_13_(FN, __VA_ARGS__) +#define JUCE_EACH_15_(FN, X, ...) FN(X) JUCE_EACH_14_(FN, __VA_ARGS__) +#define JUCE_EACH_16_(FN, X, ...) FN(X) JUCE_EACH_15_(FN, __VA_ARGS__) +#define JUCE_EACH_17_(FN, X, ...) FN(X) JUCE_EACH_16_(FN, __VA_ARGS__) +#define JUCE_EACH_18_(FN, X, ...) FN(X) JUCE_EACH_17_(FN, __VA_ARGS__) +#define JUCE_EACH_19_(FN, X, ...) FN(X) JUCE_EACH_18_(FN, __VA_ARGS__) +#define JUCE_EACH_20_(FN, X, ...) FN(X) JUCE_EACH_19_(FN, __VA_ARGS__) +#define JUCE_EACH_21_(FN, X, ...) FN(X) JUCE_EACH_20_(FN, __VA_ARGS__) +#define JUCE_EACH_22_(FN, X, ...) FN(X) JUCE_EACH_21_(FN, __VA_ARGS__) +#define JUCE_EACH_23_(FN, X, ...) FN(X) JUCE_EACH_22_(FN, __VA_ARGS__) +#define JUCE_EACH_24_(FN, X, ...) FN(X) JUCE_EACH_23_(FN, __VA_ARGS__) +#define JUCE_EACH_25_(FN, X, ...) FN(X) JUCE_EACH_24_(FN, __VA_ARGS__) +#define JUCE_EACH_26_(FN, X, ...) FN(X) JUCE_EACH_25_(FN, __VA_ARGS__) +#define JUCE_EACH_27_(FN, X, ...) FN(X) JUCE_EACH_26_(FN, __VA_ARGS__) +#define JUCE_EACH_28_(FN, X, ...) FN(X) JUCE_EACH_27_(FN, __VA_ARGS__) +#define JUCE_EACH_29_(FN, X, ...) FN(X) JUCE_EACH_28_(FN, __VA_ARGS__) +#define JUCE_EACH_30_(FN, X, ...) FN(X) JUCE_EACH_29_(FN, __VA_ARGS__) +#define JUCE_EACH_31_(FN, X, ...) FN(X) JUCE_EACH_30_(FN, __VA_ARGS__) +#define JUCE_EACH_32_(FN, X, ...) FN(X) JUCE_EACH_31_(FN, __VA_ARGS__) +#define JUCE_EACH_33_(FN, X, ...) FN(X) JUCE_EACH_32_(FN, __VA_ARGS__) +#define JUCE_EACH_34_(FN, X, ...) FN(X) JUCE_EACH_33_(FN, __VA_ARGS__) +#define JUCE_EACH_35_(FN, X, ...) FN(X) JUCE_EACH_34_(FN, __VA_ARGS__) +#define JUCE_EACH_36_(FN, X, ...) FN(X) JUCE_EACH_35_(FN, __VA_ARGS__) +#define JUCE_EACH_37_(FN, X, ...) FN(X) JUCE_EACH_36_(FN, __VA_ARGS__) +#define JUCE_EACH_38_(FN, X, ...) FN(X) JUCE_EACH_37_(FN, __VA_ARGS__) +#define JUCE_EACH_39_(FN, X, ...) FN(X) JUCE_EACH_38_(FN, __VA_ARGS__) + +/** Apply the macro FN to each of the other arguments. */ +#define JUCE_EACH(FN, ...) \ + JUCE_NTH_ARG_(, __VA_ARGS__, \ + JUCE_EACH_39_, \ + JUCE_EACH_38_, \ + JUCE_EACH_37_, \ + JUCE_EACH_36_, \ + JUCE_EACH_35_, \ + JUCE_EACH_34_, \ + JUCE_EACH_33_, \ + JUCE_EACH_32_, \ + JUCE_EACH_31_, \ + JUCE_EACH_30_, \ + JUCE_EACH_29_, \ + JUCE_EACH_28_, \ + JUCE_EACH_27_, \ + JUCE_EACH_26_, \ + JUCE_EACH_25_, \ + JUCE_EACH_24_, \ + JUCE_EACH_23_, \ + JUCE_EACH_22_, \ + JUCE_EACH_21_, \ + JUCE_EACH_20_, \ + JUCE_EACH_19_, \ + JUCE_EACH_18_, \ + JUCE_EACH_17_, \ + JUCE_EACH_16_, \ + JUCE_EACH_15_, \ + JUCE_EACH_14_, \ + JUCE_EACH_13_, \ + JUCE_EACH_12_, \ + JUCE_EACH_11_, \ + JUCE_EACH_10_, \ + JUCE_EACH_09_, \ + JUCE_EACH_08_, \ + JUCE_EACH_07_, \ + JUCE_EACH_06_, \ + JUCE_EACH_05_, \ + JUCE_EACH_04_, \ + JUCE_EACH_03_, \ + JUCE_EACH_02_, \ + JUCE_EACH_01_, \ + JUCE_EACH_00_) \ + (FN, __VA_ARGS__) + +/** Concatenate two tokens to form a new token. */ +#define JUCE_CONCAT_(a, b) a##b +#define JUCE_CONCAT(a, b) JUCE_CONCAT_(a, b) + +/** Quote the argument, turning it into a string. */ +#define JUCE_TO_STRING(x) #x + +#if JUCE_CLANG || JUCE_GCC + #define JUCE_IGNORE_GCC_IMPL_(compiler, warning) + #define JUCE_IGNORE_GCC_IMPL_0(compiler, warning) + #define JUCE_IGNORE_GCC_IMPL_1(compiler, warning) \ + _Pragma(JUCE_TO_STRING(compiler diagnostic ignored warning)) + + /** If 'warning' is recognised by this compiler, ignore it. */ + #if defined (__has_warning) + #define JUCE_IGNORE_GCC_LIKE(compiler, warning) \ + JUCE_CONCAT(JUCE_IGNORE_GCC_IMPL_, __has_warning(warning))(compiler, warning) + #else + #define JUCE_IGNORE_GCC_LIKE(compiler, warning) \ + JUCE_IGNORE_GCC_IMPL_1(compiler, warning) + #endif + + /** Ignore GCC/clang-specific warnings. */ + #define JUCE_IGNORE_GCC(warning) JUCE_IGNORE_GCC_LIKE(GCC, warning) + #define JUCE_IGNORE_clang(warning) JUCE_IGNORE_GCC_LIKE(clang, warning) + + #define JUCE_IGNORE_WARNINGS_GCC_LIKE(compiler, ...) \ + _Pragma(JUCE_TO_STRING(compiler diagnostic push)) \ + JUCE_EACH(JUCE_CONCAT(JUCE_IGNORE_, compiler), __VA_ARGS__) + + /** Push a new warning scope, and then ignore each warning for either clang + or gcc. If the compiler doesn't support __has_warning, we add -Wpragmas + as the first disabled warning because otherwise we might get complaints + about unknown warning options. + */ + #if defined (__has_warning) + #define JUCE_PUSH_WARNINGS_GCC_LIKE(compiler, ...) \ + JUCE_IGNORE_WARNINGS_GCC_LIKE(compiler, __VA_ARGS__) + #else + #define JUCE_PUSH_WARNINGS_GCC_LIKE(compiler, ...) \ + JUCE_IGNORE_WARNINGS_GCC_LIKE(compiler, "-Wpragmas", __VA_ARGS__) + #endif + + /** Pop the current warning scope. */ + #define JUCE_POP_WARNINGS_GCC_LIKE(compiler) \ + _Pragma(JUCE_TO_STRING(compiler diagnostic pop)) + + /** Push/pop warnings on compilers with gcc-like warning flags. + These macros expand to nothing on other compilers (like MSVC). + */ + #if JUCE_CLANG + #define JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE(...) JUCE_PUSH_WARNINGS_GCC_LIKE(clang, __VA_ARGS__) + #define JUCE_END_IGNORE_WARNINGS_GCC_LIKE JUCE_POP_WARNINGS_GCC_LIKE(clang) + #else + #define JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE(...) JUCE_PUSH_WARNINGS_GCC_LIKE(GCC, __VA_ARGS__) + #define JUCE_END_IGNORE_WARNINGS_GCC_LIKE JUCE_POP_WARNINGS_GCC_LIKE(GCC) + #endif +#else + #define JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE(...) + #define JUCE_END_IGNORE_WARNINGS_GCC_LIKE +#endif + +/** Push/pop warnings on MSVC. These macros expand to nothing on other + compilers (like clang and gcc). +*/ +#if JUCE_MSVC + #define JUCE_IGNORE_MSVC(warnings) __pragma(warning(disable:warnings)) + #define JUCE_BEGIN_IGNORE_WARNINGS_LEVEL_MSVC(level, warnings) \ + __pragma(warning(push, level)) JUCE_IGNORE_MSVC(warnings) + #define JUCE_BEGIN_IGNORE_WARNINGS_MSVC(warnings) \ + __pragma(warning(push)) JUCE_IGNORE_MSVC(warnings) + #define JUCE_END_IGNORE_WARNINGS_MSVC __pragma(warning(pop)) +#else + #define JUCE_IGNORE_MSVC(warnings) + #define JUCE_BEGIN_IGNORE_WARNINGS_LEVEL_MSVC(level, warnings) + #define JUCE_BEGIN_IGNORE_WARNINGS_MSVC(warnings) + #define JUCE_END_IGNORE_WARNINGS_MSVC +#endif diff --git a/modules/juce_core/system/juce_PlatformDefs.h b/modules/juce_core/system/juce_PlatformDefs.h index 1701582c..0016abfb 100644 --- a/modules/juce_core/system/juce_PlatformDefs.h +++ b/modules/juce_core/system/juce_PlatformDefs.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -20,6 +20,8 @@ ============================================================================== */ +#pragma once + namespace juce { @@ -37,7 +39,7 @@ namespace juce #endif /** This macro defines the C calling convention used as the standard for JUCE calls. */ -#if JUCE_MSVC +#if JUCE_WINDOWS #define JUCE_CALLTYPE __stdcall #define JUCE_CDECL __cdecl #else @@ -64,12 +66,14 @@ namespace juce @see jassert() */ #define JUCE_BREAK_IN_DEBUGGER { ::kill (0, SIGTRAP); } +#elif JUCE_MAC && JUCE_CLANG && JUCE_ARM + #define JUCE_BREAK_IN_DEBUGGER { __builtin_debugtrap(); } #elif JUCE_MSVC #ifndef __INTEL_COMPILER #pragma intrinsic (__debugbreak) #endif #define JUCE_BREAK_IN_DEBUGGER { __debugbreak(); } -#elif JUCE_GCC || JUCE_MAC +#elif JUCE_INTEL && (JUCE_GCC || JUCE_MAC) #if JUCE_NO_INLINE_ASM #define JUCE_BREAK_IN_DEBUGGER { } #else @@ -92,6 +96,26 @@ namespace juce #define JUCE_ANALYZER_NORETURN #endif +/** Used to silence Wimplicit-fallthrough on Clang and GCC where available + as there are a few places in the codebase where we need to do this + deliberately and want to ignore the warning. +*/ +#if JUCE_CLANG + #if __has_cpp_attribute(clang::fallthrough) + #define JUCE_FALLTHROUGH [[clang::fallthrough]]; + #else + #define JUCE_FALLTHROUGH + #endif +#elif JUCE_GCC + #if __GNUC__ >= 7 + #define JUCE_FALLTHROUGH [[gnu::fallthrough]]; + #else + #define JUCE_FALLTHROUGH + #endif +#else + #define JUCE_FALLTHROUGH +#endif + //============================================================================== #if JUCE_MSVC && ! DOXYGEN #define JUCE_BLOCK_WITH_FORCED_SEMICOLON(x) \ diff --git a/modules/juce_core/system/juce_StandardHeader.h b/modules/juce_core/system/juce_StandardHeader.h index 81490854..ff949799 100644 --- a/modules/juce_core/system/juce_StandardHeader.h +++ b/modules/juce_core/system/juce_StandardHeader.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -27,9 +27,9 @@ See also SystemStats::getJUCEVersion() for a string version. */ -#define JUCE_MAJOR_VERSION 5 -#define JUCE_MINOR_VERSION 4 -#define JUCE_BUILDNUMBER 7 +#define JUCE_MAJOR_VERSION 6 +#define JUCE_MINOR_VERSION 0 +#define JUCE_BUILDNUMBER 5 /** Current JUCE version number. @@ -43,35 +43,40 @@ //============================================================================== -#include <memory> -#include <cmath> -#include <vector> -#include <iostream> -#include <functional> #include <algorithm> -#include <limits> +#include <array> #include <atomic> -#include <sstream> +#include <cmath> +#include <condition_variable> +#include <cstddef> +#include <functional> #include <iomanip> +#include <iostream> +#include <limits> +#include <list> #include <map> -#include <cstddef> -#include <unordered_set> +#include <memory> #include <mutex> -#include <condition_variable> +#include <numeric> #include <queue> +#include <sstream> +#include <unordered_set> +#include <vector> //============================================================================== #include "juce_CompilerSupport.h" +#include "juce_CompilerWarnings.h" #include "juce_PlatformDefs.h" //============================================================================== // Now we'll include some common OS headers.. +JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4514 4245 4100) + #if JUCE_MSVC - #pragma warning (push) - #pragma warning (disable: 4514 4245 4100) #include <intrin.h> #endif + #if JUCE_MAC || JUCE_IOS #include <libkern/OSAtomic.h> #include <xlocale.h> @@ -97,9 +102,7 @@ #include <crtdbg.h> #endif -#if JUCE_MSVC - #pragma warning (pop) -#endif +JUCE_END_IGNORE_WARNINGS_MSVC #if JUCE_MINGW #include <cstring> @@ -108,7 +111,6 @@ #if JUCE_ANDROID #include <cstring> - #include <atomic> #include <byteswap.h> #endif diff --git a/modules/juce_core/system/juce_SystemStats.cpp b/modules/juce_core/system/juce_SystemStats.cpp index 2ea90f80..84712716 100644 --- a/modules/juce_core/system/juce_SystemStats.cpp +++ b/modules/juce_core/system/juce_SystemStats.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/system/juce_SystemStats.h b/modules/juce_core/system/juce_SystemStats.h index 7926c32b..3260af8e 100644 --- a/modules/juce_core/system/juce_SystemStats.h +++ b/modules/juce_core/system/juce_SystemStats.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -52,9 +52,6 @@ public: Android = 0x0800, iOS = 0x1000, - MacOSX_10_4 = MacOSX | 4, - MacOSX_10_5 = MacOSX | 5, - MacOSX_10_6 = MacOSX | 6, MacOSX_10_7 = MacOSX | 7, MacOSX_10_8 = MacOSX | 8, MacOSX_10_9 = MacOSX | 9, @@ -63,6 +60,8 @@ public: MacOSX_10_12 = MacOSX | 12, MacOSX_10_13 = MacOSX | 13, MacOSX_10_14 = MacOSX | 14, + MacOSX_10_15 = MacOSX | 15, + MacOSX_11_0 = MacOSX | 16, Win2000 = Windows | 1, WinXP = Windows | 2, diff --git a/modules/juce_core/system/juce_TargetPlatform.h b/modules/juce_core/system/juce_TargetPlatform.h index 4b9228d9..d0530b48 100644 --- a/modules/juce_core/system/juce_TargetPlatform.h +++ b/modules/juce_core/system/juce_TargetPlatform.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -58,7 +58,6 @@ //============================================================================== #if defined (_WIN32) || defined (_WIN64) - #define JUCE_WIN32 1 #define JUCE_WINDOWS 1 #elif defined (JUCE_ANDROID) #undef JUCE_ANDROID @@ -69,7 +68,8 @@ #define JUCE_LINUX 1 #elif defined (__APPLE_CPP__) || defined (__APPLE_CC__) #define CF_EXCLUDE_CSTD_HEADERS 1 - #include <CoreFoundation/CoreFoundation.h> // (needed to find out what platform we're using) + #include <TargetConditionals.h> // (needed to find out what platform we're using) + #include <AvailabilityMacros.h> #include "../native/juce_mac_ClangBugWorkaround.h" #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR diff --git a/modules/juce_core/text/juce_Base64.cpp b/modules/juce_core/text/juce_Base64.cpp index 902308ba..b154157b 100644 --- a/modules/juce_core/text/juce_Base64.cpp +++ b/modules/juce_core/text/juce_Base64.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/text/juce_Base64.h b/modules/juce_core/text/juce_Base64.h index 6e59a19e..446171bf 100644 --- a/modules/juce_core/text/juce_Base64.h +++ b/modules/juce_core/text/juce_Base64.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/text/juce_CharPointer_ASCII.h b/modules/juce_core/text/juce_CharPointer_ASCII.h index ca5c1050..597d6f2f 100644 --- a/modules/juce_core/text/juce_CharPointer_ASCII.h +++ b/modules/juce_core/text/juce_CharPointer_ASCII.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -182,7 +182,7 @@ public: /** Returns the number of bytes that would be needed to represent the given unicode character in this encoding format. */ - static inline size_t getBytesRequiredFor (const juce_wchar) noexcept + static size_t getBytesRequiredFor (const juce_wchar) noexcept { return 1; } diff --git a/modules/juce_core/text/juce_CharPointer_UTF16.h b/modules/juce_core/text/juce_CharPointer_UTF16.h index 54b08662..62cfce54 100644 --- a/modules/juce_core/text/juce_CharPointer_UTF16.h +++ b/modules/juce_core/text/juce_CharPointer_UTF16.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/text/juce_CharPointer_UTF32.h b/modules/juce_core/text/juce_CharPointer_UTF32.h index 836c7af0..da66024b 100644 --- a/modules/juce_core/text/juce_CharPointer_UTF32.h +++ b/modules/juce_core/text/juce_CharPointer_UTF32.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -186,7 +186,7 @@ public: /** Returns the number of bytes that would be needed to represent the given unicode character in this encoding format. */ - static inline size_t getBytesRequiredFor (juce_wchar) noexcept + static size_t getBytesRequiredFor (juce_wchar) noexcept { return sizeof (CharType); } diff --git a/modules/juce_core/text/juce_CharPointer_UTF8.h b/modules/juce_core/text/juce_CharPointer_UTF8.h index 09b86325..5aa42c42 100644 --- a/modules/juce_core/text/juce_CharPointer_UTF8.h +++ b/modules/juce_core/text/juce_CharPointer_UTF8.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -36,44 +36,44 @@ class CharPointer_UTF8 final public: using CharType = char; - inline explicit CharPointer_UTF8 (const CharType* rawPointer) noexcept + explicit CharPointer_UTF8 (const CharType* rawPointer) noexcept : data (const_cast<CharType*> (rawPointer)) { } - inline CharPointer_UTF8 (const CharPointer_UTF8& other) = default; + CharPointer_UTF8 (const CharPointer_UTF8& other) = default; - inline CharPointer_UTF8 operator= (CharPointer_UTF8 other) noexcept + CharPointer_UTF8 operator= (CharPointer_UTF8 other) noexcept { data = other.data; return *this; } - inline CharPointer_UTF8 operator= (const CharType* text) noexcept + CharPointer_UTF8 operator= (const CharType* text) noexcept { data = const_cast<CharType*> (text); return *this; } /** This is a pointer comparison, it doesn't compare the actual text. */ - inline bool operator== (CharPointer_UTF8 other) const noexcept { return data == other.data; } - inline bool operator!= (CharPointer_UTF8 other) const noexcept { return data != other.data; } - inline bool operator<= (CharPointer_UTF8 other) const noexcept { return data <= other.data; } - inline bool operator< (CharPointer_UTF8 other) const noexcept { return data < other.data; } - inline bool operator>= (CharPointer_UTF8 other) const noexcept { return data >= other.data; } - inline bool operator> (CharPointer_UTF8 other) const noexcept { return data > other.data; } + bool operator== (CharPointer_UTF8 other) const noexcept { return data == other.data; } + bool operator!= (CharPointer_UTF8 other) const noexcept { return data != other.data; } + bool operator<= (CharPointer_UTF8 other) const noexcept { return data <= other.data; } + bool operator< (CharPointer_UTF8 other) const noexcept { return data < other.data; } + bool operator>= (CharPointer_UTF8 other) const noexcept { return data >= other.data; } + bool operator> (CharPointer_UTF8 other) const noexcept { return data > other.data; } /** Returns the address that this pointer is pointing to. */ - inline CharType* getAddress() const noexcept { return data; } + CharType* getAddress() const noexcept { return data; } /** Returns the address that this pointer is pointing to. */ - inline operator const CharType*() const noexcept { return data; } + operator const CharType*() const noexcept { return data; } /** Returns true if this pointer is pointing to a null character. */ - inline bool isEmpty() const noexcept { return *data == 0; } + bool isEmpty() const noexcept { return *data == 0; } /** Returns true if this pointer is not pointing to a null character. */ - inline bool isNotEmpty() const noexcept { return *data != 0; } + bool isNotEmpty() const noexcept { return *data != 0; } /** Returns the unicode character that this pointer is pointing to. */ juce_wchar operator*() const noexcept @@ -124,7 +124,7 @@ public: while ((static_cast<uint8> (n) & bit) != 0 && bit > 0x8) { ++data; - bit >>= 1; + bit = static_cast<uint8> (bit >> 1); } } @@ -348,7 +348,7 @@ public: } /** Writes a null character to this string (leaving the pointer's position unchanged). */ - inline void writeNull() const noexcept + void writeNull() const noexcept { *data = 0; } diff --git a/modules/juce_core/text/juce_CharacterFunctions.cpp b/modules/juce_core/text/juce_CharacterFunctions.cpp index d1024f08..8341a8ca 100644 --- a/modules/juce_core/text/juce_CharacterFunctions.cpp +++ b/modules/juce_core/text/juce_CharacterFunctions.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -23,10 +23,7 @@ namespace juce { -#if JUCE_MSVC - #pragma warning (push) - #pragma warning (disable: 4514 4996) -#endif +JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4514 4996) juce_wchar CharacterFunctions::toUpperCase (const juce_wchar character) noexcept { @@ -56,9 +53,7 @@ bool CharacterFunctions::isLowerCase (const juce_wchar character) noexcept #endif } -#if JUCE_MSVC - #pragma warning (pop) -#endif +JUCE_END_IGNORE_WARNINGS_MSVC //============================================================================== bool CharacterFunctions::isWhitespace (const char character) noexcept diff --git a/modules/juce_core/text/juce_CharacterFunctions.h b/modules/juce_core/text/juce_CharacterFunctions.h index 53bc8146..76c9c5c7 100644 --- a/modules/juce_core/text/juce_CharacterFunctions.h +++ b/modules/juce_core/text/juce_CharacterFunctions.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -149,8 +149,8 @@ public: #if JUCE_MINGW bool isNegative = false; #else - JUCE_CONSTEXPR const int maxSignificantDigits = 17 + 1; // An additional digit for rounding - JUCE_CONSTEXPR const int bufferSize = maxSignificantDigits + 7 + 1; // -.E-XXX and a trailing null-terminator + constexpr const int maxSignificantDigits = 17 + 1; // An additional digit for rounding + constexpr const int bufferSize = maxSignificantDigits + 7 + 1; // -.E-XXX and a trailing null-terminator char buffer[(size_t) bufferSize] = {}; char* currentCharacter = &(buffer[0]); #endif @@ -166,9 +166,12 @@ public: #else *currentCharacter++ = '-'; #endif - // Fall-through.. + JUCE_FALLTHROUGH case '+': c = *++text; + break; + default: + break; } switch (c) @@ -184,6 +187,9 @@ public: if ((text[1] == 'n' || text[1] == 'N') && (text[2] == 'f' || text[2] == 'F')) return std::numeric_limits<double>::infinity(); break; + + default: + break; } #if JUCE_MINGW @@ -194,7 +200,7 @@ public: int exponent = 0, decPointIndex = 0, digit = 0; int lastDigit = 0, numSignificantDigits = 0; bool digitsFound = false; - JUCE_CONSTEXPR const int maxSignificantDigits = 17 + 1; + constexpr const int maxSignificantDigits = 17 + 1; for (;;) { @@ -274,7 +280,7 @@ public: switch (*++text) { - case '-': negativeExponent = true; // fall-through.. + case '-': negativeExponent = true; JUCE_FALLTHROUGH case '+': ++text; } @@ -337,7 +343,7 @@ public: c = *text; - auto writeExponentDigits = [](int exponent, char* destination) + auto writeExponentDigits = [] (int exponent, char* destination) { auto exponentDivisor = 100; @@ -359,8 +365,9 @@ public: switch (*++text) { - case '-': parsedExponentIsPositive = false; // Fall-through.. - case '+': ++text; + case '-': parsedExponentIsPositive = false; JUCE_FALLTHROUGH + case '+': ++text; break; + default: break; } int exponent = 0; @@ -544,7 +551,7 @@ public: } /** Compares two characters. */ - static inline int compare (juce_wchar char1, juce_wchar char2) noexcept + static int compare (juce_wchar char1, juce_wchar char2) noexcept { if (auto diff = static_cast<int> (char1) - static_cast<int> (char2)) return diff < 0 ? -1 : 1; @@ -589,7 +596,7 @@ public: } /** Compares two characters, using a case-independant match. */ - static inline int compareIgnoreCase (juce_wchar char1, juce_wchar char2) noexcept + static int compareIgnoreCase (juce_wchar char1, juce_wchar char2) noexcept { return char1 != char2 ? compare (toUpperCase (char1), toUpperCase (char2)) : 0; } diff --git a/modules/juce_core/text/juce_Identifier.cpp b/modules/juce_core/text/juce_Identifier.cpp index a56a364c..3e78fd52 100644 --- a/modules/juce_core/text/juce_Identifier.cpp +++ b/modules/juce_core/text/juce_Identifier.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/text/juce_Identifier.h b/modules/juce_core/text/juce_Identifier.h index f606e40d..af2408fb 100644 --- a/modules/juce_core/text/juce_Identifier.h +++ b/modules/juce_core/text/juce_Identifier.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/text/juce_LocalisedStrings.cpp b/modules/juce_core/text/juce_LocalisedStrings.cpp index d523cd9c..c0a7a459 100644 --- a/modules/juce_core/text/juce_LocalisedStrings.cpp +++ b/modules/juce_core/text/juce_LocalisedStrings.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/text/juce_LocalisedStrings.h b/modules/juce_core/text/juce_LocalisedStrings.h index 195341e0..04b2c348 100644 --- a/modules/juce_core/text/juce_LocalisedStrings.h +++ b/modules/juce_core/text/juce_LocalisedStrings.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/text/juce_NewLine.h b/modules/juce_core/text/juce_NewLine.h index 121e70aa..bc7e2de7 100644 --- a/modules/juce_core/text/juce_NewLine.h +++ b/modules/juce_core/text/juce_NewLine.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/text/juce_String.cpp b/modules/juce_core/text/juce_String.cpp index 1681c2c2..a685e6a6 100644 --- a/modules/juce_core/text/juce_String.cpp +++ b/modules/juce_core/text/juce_String.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -23,10 +23,7 @@ namespace juce { -#if JUCE_MSVC - #pragma warning (push) - #pragma warning (disable: 4514 4996) -#endif +JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4514 4996) NewLine newLine; @@ -42,7 +39,7 @@ NewLine newLine; using CharPointer_wchar_t = CharPointer_UTF32; #endif -static inline CharPointer_wchar_t castToCharPointer_wchar_t (const void* t) noexcept +static CharPointer_wchar_t castToCharPointer_wchar_t (const void* t) noexcept { return CharPointer_wchar_t (static_cast<const CharPointer_wchar_t::CharType*> (t)); } @@ -71,7 +68,7 @@ public: static CharPointerType createUninitialisedBytes (size_t numBytes) { numBytes = (numBytes + 3) & ~(size_t) 3; - auto s = reinterpret_cast<StringHolder*> (new char [sizeof (StringHolder) - sizeof (CharType) + numBytes]); + auto s = unalignedPointerCast<StringHolder*> (new char [sizeof (StringHolder) - sizeof (CharType) + numBytes]); s->refCount.value = 0; s->allocatedNumBytes = numBytes; return CharPointerType (s->text); @@ -160,7 +157,7 @@ public: ++(b->refCount); } - static inline void release (StringHolder* const b) noexcept + static void release (StringHolder* const b) noexcept { if (! isEmptyString (b)) if (--(b->refCount) == -1) @@ -172,7 +169,7 @@ public: release (bufferFromText (text)); } - static inline int getReferenceCount (const CharPointerType text) noexcept + static int getReferenceCount (const CharPointerType text) noexcept { return bufferFromText (text)->refCount.get() + 1; } @@ -210,14 +207,14 @@ public: CharType text[1]; private: - static inline StringHolder* bufferFromText (const CharPointerType text) noexcept + static StringHolder* bufferFromText (const CharPointerType text) noexcept { // (Can't use offsetof() here because of warnings about this not being a POD) - return reinterpret_cast<StringHolder*> (reinterpret_cast<char*> (text.getAddress()) + return unalignedPointerCast<StringHolder*> (reinterpret_cast<char*> (text.getAddress()) - (reinterpret_cast<size_t> (reinterpret_cast<StringHolder*> (128)->text) - 128)); } - static inline bool isEmptyString (StringHolder* other) + static bool isEmptyString (StringHolder* other) { return (other->refCount.get() & 0x30000000) != 0; } @@ -393,7 +390,7 @@ namespace NumberToStringConverters do { - *--t = '0' + (char) (v % 10); + *--t = static_cast<char> ('0' + (char) (v % 10)); v /= 10; } while (v > 0); @@ -815,9 +812,10 @@ namespace StringHelpers } } -String& String::operator+= (const int number) { return StringHelpers::operationAddAssign<int> (*this, number); } -String& String::operator+= (const int64 number) { return StringHelpers::operationAddAssign<int64> (*this, number); } -String& String::operator+= (const uint64 number) { return StringHelpers::operationAddAssign<uint64> (*this, number); } +String& String::operator+= (const int number) { return StringHelpers::operationAddAssign<int> (*this, number); } +String& String::operator+= (const long number) { return StringHelpers::operationAddAssign<long> (*this, number); } +String& String::operator+= (const int64 number) { return StringHelpers::operationAddAssign<int64> (*this, number); } +String& String::operator+= (const uint64 number) { return StringHelpers::operationAddAssign<uint64> (*this, number); } //============================================================================== JUCE_API String JUCE_CALLTYPE operator+ (const char* s1, const String& s2) { String s (s1); return s += s2; } @@ -1840,6 +1838,10 @@ String String::formattedRaw (const char* pf, ...) va_list args; va_start (args, pf); + #if JUCE_WINDOWS + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wdeprecated-declarations") + #endif + #if JUCE_ANDROID HeapBlock<char> temp (bufferSize); int num = (int) vsnprintf (temp.get(), bufferSize - 1, pf, args); @@ -1856,6 +1858,10 @@ String String::formattedRaw (const char* pf, ...) #endif (temp.get(), bufferSize - 1, wideCharVersion.toWideCharPointer(), args); #endif + + #if JUCE_WINDOWS + JUCE_END_IGNORE_WARNINGS_GCC_LIKE + #endif va_end (args); if (num > 0) @@ -1892,7 +1898,7 @@ int String::getTrailingIntValue() const noexcept break; } - n += static_cast<juce_wchar> (mult) * (*t - '0'); + n += (int) (((juce_wchar) mult) * (*t - '0')); mult *= 10; } @@ -1912,7 +1918,7 @@ static String hexToString (Type v) do { *--t = hexDigits [(int) (v & 15)]; - v >>= 4; + v = static_cast<Type> (v >> 4); } while (v != 0); @@ -1985,7 +1991,7 @@ String String::createStringFromData (const void* const unknownData, int size) StringCreationHelper builder ((size_t) numChars); - auto src = reinterpret_cast<const uint16*> (data + 2); + auto src = unalignedPointerCast<const uint16*> (data + 2); if (CharPointer_UTF16::isByteOrderMarkBigEndian (data)) { @@ -2055,19 +2061,19 @@ struct StringEncodingConverter template <> struct StringEncodingConverter<CharPointer_UTF8, CharPointer_UTF8> { - static CharPointer_UTF8 convert (const String& source) noexcept { return CharPointer_UTF8 (reinterpret_cast<CharPointer_UTF8::CharType*> (source.getCharPointer().getAddress())); } + static CharPointer_UTF8 convert (const String& source) noexcept { return CharPointer_UTF8 (unalignedPointerCast<CharPointer_UTF8::CharType*> (source.getCharPointer().getAddress())); } }; template <> struct StringEncodingConverter<CharPointer_UTF16, CharPointer_UTF16> { - static CharPointer_UTF16 convert (const String& source) noexcept { return CharPointer_UTF16 (reinterpret_cast<CharPointer_UTF16::CharType*> (source.getCharPointer().getAddress())); } + static CharPointer_UTF16 convert (const String& source) noexcept { return CharPointer_UTF16 (unalignedPointerCast<CharPointer_UTF16::CharType*> (source.getCharPointer().getAddress())); } }; template <> struct StringEncodingConverter<CharPointer_UTF32, CharPointer_UTF32> { - static CharPointer_UTF32 convert (const String& source) noexcept { return CharPointer_UTF32 (reinterpret_cast<CharPointer_UTF32::CharType*> (source.getCharPointer().getAddress())); } + static CharPointer_UTF32 convert (const String& source) noexcept { return CharPointer_UTF32 (unalignedPointerCast<CharPointer_UTF32::CharType*> (source.getCharPointer().getAddress())); } }; CharPointer_UTF8 String::toUTF8() const { return StringEncodingConverter<CharPointerType, CharPointer_UTF8 >::convert (*this); } @@ -2142,9 +2148,7 @@ String String::fromUTF8 (const char* const buffer, int bufferSizeBytes) return {}; } -#if JUCE_MSVC - #pragma warning (pop) -#endif +JUCE_END_IGNORE_WARNINGS_MSVC //============================================================================== StringRef::StringRef() noexcept : text ((const String::CharPointerType::CharType*) "\0\0\0") @@ -2935,6 +2939,17 @@ public: expectEquals (serialiseDouble (-test.first), "-" + test.second); } } + + { + beginTest ("Loops"); + + String str (CharPointer_UTF8 ("\xc2\xaf\\_(\xe3\x83\x84)_/\xc2\xaf")); + std::vector<juce_wchar> parts { 175, 92, 95, 40, 12484, 41, 95, 47, 175 }; + size_t index = 0; + + for (auto c : str) + expectEquals (c, parts[index++]); + } } }; diff --git a/modules/juce_core/text/juce_String.h b/modules/juce_core/text/juce_String.h index 3a5a52d2..b3eb7afe 100644 --- a/modules/juce_core/text/juce_String.h +++ b/modules/juce_core/text/juce_String.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -20,6 +20,20 @@ ============================================================================== */ +#if ! DOXYGEN && (JUCE_MAC || JUCE_IOS) + // Annoyingly we can only forward-declare a typedef by forward-declaring the + // aliased type + #if __has_attribute(objc_bridge) + #define JUCE_CF_BRIDGED_TYPE(T) __attribute__((objc_bridge(T))) + #else + #define JUCE_CF_BRIDGED_TYPE(T) + #endif + + typedef const struct JUCE_CF_BRIDGED_TYPE(NSString) __CFString * CFStringRef; + + #undef JUCE_CF_BRIDGED_TYPE +#endif + namespace juce { @@ -293,13 +307,13 @@ public: Note that there's also an isNotEmpty() method to help write readable code. @see containsNonWhitespaceChars() */ - inline bool isEmpty() const noexcept { return text.isEmpty(); } + bool isEmpty() const noexcept { return text.isEmpty(); } /** Returns true if the string contains at least one character. Note that there's also an isEmpty() method to help write readable code. @see containsNonWhitespaceChars() */ - inline bool isNotEmpty() const noexcept { return ! text.isEmpty(); } + bool isNotEmpty() const noexcept { return ! text.isEmpty(); } /** Resets this string to be empty. */ void clear() noexcept; @@ -905,6 +919,35 @@ public: template <typename... Args> static String formatted (const String& formatStr, Args... args) { return formattedRaw (formatStr.toRawUTF8(), args...); } + /** Returns an iterator pointing at the beginning of the string. */ + CharPointerType begin() const { return getCharPointer(); } + + /** Returns an iterator pointing at the terminating null of the string. + + Note that this has to find the terminating null before returning it, so prefer to + call this once before looping and then reuse the result, rather than calling 'end()' + each time through the loop. + + @code + String str = ...; + + // BEST + for (auto c : str) + DBG (c); + + // GOOD + for (auto ptr = str.begin(), end = str.end(); ptr != end; ++ptr) + DBG (*ptr); + + std::for_each (str.begin(), str.end(), [] (juce_wchar c) { DBG (c); }); + + // BAD + for (auto ptr = str.begin(); ptr != str.end(); ++ptr) + DBG (*ptr); + @endcode + */ + CharPointerType end() const { return begin().findTerminatingNull(); } + //============================================================================== // Numeric conversions.. @@ -1195,7 +1238,7 @@ public: that is returned must not be stored anywhere, as it can be deleted whenever the string changes. */ - inline CharPointerType getCharPointer() const noexcept { return text; } + CharPointerType getCharPointer() const noexcept { return text; } /** Returns a pointer to a UTF-8 version of this string. diff --git a/modules/juce_core/text/juce_StringArray.cpp b/modules/juce_core/text/juce_StringArray.cpp index 014d6b0a..8523dc96 100644 --- a/modules/juce_core/text/juce_StringArray.cpp +++ b/modules/juce_core/text/juce_StringArray.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/text/juce_StringArray.h b/modules/juce_core/text/juce_StringArray.h index f6292540..6f3670bd 100644 --- a/modules/juce_core/text/juce_StringArray.h +++ b/modules/juce_core/text/juce_StringArray.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/text/juce_StringPairArray.cpp b/modules/juce_core/text/juce_StringPairArray.cpp index e523cdc1..a906bf98 100644 --- a/modules/juce_core/text/juce_StringPairArray.cpp +++ b/modules/juce_core/text/juce_StringPairArray.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/text/juce_StringPairArray.h b/modules/juce_core/text/juce_StringPairArray.h index 1d8fb3a4..77d486c9 100644 --- a/modules/juce_core/text/juce_StringPairArray.h +++ b/modules/juce_core/text/juce_StringPairArray.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/text/juce_StringPool.cpp b/modules/juce_core/text/juce_StringPool.cpp index a9a11210..e4caa799 100644 --- a/modules/juce_core/text/juce_StringPool.cpp +++ b/modules/juce_core/text/juce_StringPool.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/text/juce_StringPool.h b/modules/juce_core/text/juce_StringPool.h index e6d181f3..ef37da78 100644 --- a/modules/juce_core/text/juce_StringPool.h +++ b/modules/juce_core/text/juce_StringPool.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/text/juce_StringRef.h b/modules/juce_core/text/juce_StringRef.h index db2c7264..6941eb8c 100644 --- a/modules/juce_core/text/juce_StringRef.h +++ b/modules/juce_core/text/juce_StringRef.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/text/juce_TextDiff.cpp b/modules/juce_core/text/juce_TextDiff.cpp index 89b0a9ef..8b662351 100644 --- a/modules/juce_core/text/juce_TextDiff.cpp +++ b/modules/juce_core/text/juce_TextDiff.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/text/juce_TextDiff.h b/modules/juce_core/text/juce_TextDiff.h index cf5cbb4a..482e8535 100644 --- a/modules/juce_core/text/juce_TextDiff.h +++ b/modules/juce_core/text/juce_TextDiff.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/threads/juce_ChildProcess.cpp b/modules/juce_core/threads/juce_ChildProcess.cpp index f734ef93..3b284c25 100644 --- a/modules/juce_core/threads/juce_ChildProcess.cpp +++ b/modules/juce_core/threads/juce_ChildProcess.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/threads/juce_ChildProcess.h b/modules/juce_core/threads/juce_ChildProcess.h index dc5feb20..47a26281 100644 --- a/modules/juce_core/threads/juce_ChildProcess.h +++ b/modules/juce_core/threads/juce_ChildProcess.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/threads/juce_CriticalSection.h b/modules/juce_core/threads/juce_CriticalSection.h index d8ae0f58..efd0eb11 100644 --- a/modules/juce_core/threads/juce_CriticalSection.h +++ b/modules/juce_core/threads/juce_CriticalSection.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/threads/juce_DynamicLibrary.h b/modules/juce_core/threads/juce_DynamicLibrary.h index e5a4d5ed..fc9d05c7 100644 --- a/modules/juce_core/threads/juce_DynamicLibrary.h +++ b/modules/juce_core/threads/juce_DynamicLibrary.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/threads/juce_HighResolutionTimer.cpp b/modules/juce_core/threads/juce_HighResolutionTimer.cpp index 7a7c5c0e..e03f6e81 100644 --- a/modules/juce_core/threads/juce_HighResolutionTimer.cpp +++ b/modules/juce_core/threads/juce_HighResolutionTimer.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/threads/juce_HighResolutionTimer.h b/modules/juce_core/threads/juce_HighResolutionTimer.h index 2ac0db3f..cd08f35d 100644 --- a/modules/juce_core/threads/juce_HighResolutionTimer.h +++ b/modules/juce_core/threads/juce_HighResolutionTimer.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/threads/juce_InterProcessLock.h b/modules/juce_core/threads/juce_InterProcessLock.h index 58f2e6d4..56ae9d0f 100644 --- a/modules/juce_core/threads/juce_InterProcessLock.h +++ b/modules/juce_core/threads/juce_InterProcessLock.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/threads/juce_Process.h b/modules/juce_core/threads/juce_Process.h index bc868ef7..17fa8aa4 100644 --- a/modules/juce_core/threads/juce_Process.h +++ b/modules/juce_core/threads/juce_Process.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/threads/juce_ReadWriteLock.cpp b/modules/juce_core/threads/juce_ReadWriteLock.cpp index 86f6afe2..ed8b5a28 100644 --- a/modules/juce_core/threads/juce_ReadWriteLock.cpp +++ b/modules/juce_core/threads/juce_ReadWriteLock.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/threads/juce_ReadWriteLock.h b/modules/juce_core/threads/juce_ReadWriteLock.h index 28c5b725..3d26f5f9 100644 --- a/modules/juce_core/threads/juce_ReadWriteLock.h +++ b/modules/juce_core/threads/juce_ReadWriteLock.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/threads/juce_ScopedLock.h b/modules/juce_core/threads/juce_ScopedLock.h index aeac94d7..a140f146 100644 --- a/modules/juce_core/threads/juce_ScopedLock.h +++ b/modules/juce_core/threads/juce_ScopedLock.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/threads/juce_ScopedReadLock.h b/modules/juce_core/threads/juce_ScopedReadLock.h index b12afd33..ae3c41ee 100644 --- a/modules/juce_core/threads/juce_ScopedReadLock.h +++ b/modules/juce_core/threads/juce_ScopedReadLock.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/threads/juce_ScopedWriteLock.h b/modules/juce_core/threads/juce_ScopedWriteLock.h index 3bfaf4b8..ccd07a33 100644 --- a/modules/juce_core/threads/juce_ScopedWriteLock.h +++ b/modules/juce_core/threads/juce_ScopedWriteLock.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/threads/juce_SpinLock.h b/modules/juce_core/threads/juce_SpinLock.h index f3328f00..14f7c6b0 100644 --- a/modules/juce_core/threads/juce_SpinLock.h +++ b/modules/juce_core/threads/juce_SpinLock.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -75,6 +75,9 @@ public: /** Provides the type of scoped unlocker to use with a SpinLock. */ using ScopedUnlockType = GenericScopedUnlock<SpinLock>; + /** Provides the type of scoped try-lock to use for locking a SpinLock. */ + using ScopedTryLockType = GenericScopedTryLock<SpinLock>; + private: //============================================================================== mutable Atomic<int> lock; diff --git a/modules/juce_core/threads/juce_Thread.cpp b/modules/juce_core/threads/juce_Thread.cpp index f3f8bb97..c31f56cb 100644 --- a/modules/juce_core/threads/juce_Thread.cpp +++ b/modules/juce_core/threads/juce_Thread.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -373,7 +373,7 @@ public: expect (ByteOrder::swap ((uint16) 0x1122) == 0x2211); expect (ByteOrder::swap ((uint32) 0x11223344) == 0x44332211); - expect (ByteOrder::swap ((uint64) 0x1122334455667788ULL) == 0x8877665544332211LL); + expect (ByteOrder::swap ((uint64) 0x1122334455667788ULL) == (uint64) 0x8877665544332211LL); beginTest ("Atomic int"); AtomicTester <int>::testInteger (*this); diff --git a/modules/juce_core/threads/juce_Thread.h b/modules/juce_core/threads/juce_Thread.h index bd9a7049..07776ed6 100644 --- a/modules/juce_core/threads/juce_Thread.h +++ b/modules/juce_core/threads/juce_Thread.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -352,7 +352,7 @@ public: following java method: @code - com.roli.juce.Java.initialiseJUCE (myContext); + com.rmsl.juce.Java.initialiseJUCE (myContext); @endcode Note that the above java method is only available in Android Studio projects @@ -361,7 +361,7 @@ public: your project: @code - package com.roli.juce; + package com.rmsl.juce; public class Java { diff --git a/modules/juce_core/threads/juce_ThreadLocalValue.h b/modules/juce_core/threads/juce_ThreadLocalValue.h index 17d1e025..1c88d248 100644 --- a/modules/juce_core/threads/juce_ThreadLocalValue.h +++ b/modules/juce_core/threads/juce_ThreadLocalValue.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/threads/juce_ThreadPool.cpp b/modules/juce_core/threads/juce_ThreadPool.cpp index db9cb8db..ce5ecf8b 100644 --- a/modules/juce_core/threads/juce_ThreadPool.cpp +++ b/modules/juce_core/threads/juce_ThreadPool.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/threads/juce_ThreadPool.h b/modules/juce_core/threads/juce_ThreadPool.h index 21973e13..0a36b7af 100644 --- a/modules/juce_core/threads/juce_ThreadPool.h +++ b/modules/juce_core/threads/juce_ThreadPool.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/threads/juce_TimeSliceThread.cpp b/modules/juce_core/threads/juce_TimeSliceThread.cpp index d5c4c227..ed1bbfe4 100644 --- a/modules/juce_core/threads/juce_TimeSliceThread.cpp +++ b/modules/juce_core/threads/juce_TimeSliceThread.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/threads/juce_TimeSliceThread.h b/modules/juce_core/threads/juce_TimeSliceThread.h index f661cff3..d74723d8 100644 --- a/modules/juce_core/threads/juce_TimeSliceThread.h +++ b/modules/juce_core/threads/juce_TimeSliceThread.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/threads/juce_WaitableEvent.cpp b/modules/juce_core/threads/juce_WaitableEvent.cpp index 8b01c4db..92a877d0 100644 --- a/modules/juce_core/threads/juce_WaitableEvent.cpp +++ b/modules/juce_core/threads/juce_WaitableEvent.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/threads/juce_WaitableEvent.h b/modules/juce_core/threads/juce_WaitableEvent.h index 3e31a977..52269f70 100644 --- a/modules/juce_core/threads/juce_WaitableEvent.h +++ b/modules/juce_core/threads/juce_WaitableEvent.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/time/juce_PerformanceCounter.cpp b/modules/juce_core/time/juce_PerformanceCounter.cpp index 5e15212d..546cbb30 100644 --- a/modules/juce_core/time/juce_PerformanceCounter.cpp +++ b/modules/juce_core/time/juce_PerformanceCounter.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -114,7 +114,7 @@ void PerformanceCounter::printStatistics() { const String desc (getStatisticsAndReset().toString()); - Logger::outputDebugString (desc); + Logger::writeToLog (desc); appendToFile (outputFile, desc); } @@ -124,7 +124,7 @@ PerformanceCounter::Statistics PerformanceCounter::getStatisticsAndReset() stats.clear(); if (s.numRuns > 0) - s.averageSeconds = s.totalSeconds / s.numRuns; + s.averageSeconds = s.totalSeconds / (float) s.numRuns; return s; } diff --git a/modules/juce_core/time/juce_PerformanceCounter.h b/modules/juce_core/time/juce_PerformanceCounter.h index 6a1d9a23..0b8a22ba 100644 --- a/modules/juce_core/time/juce_PerformanceCounter.h +++ b/modules/juce_core/time/juce_PerformanceCounter.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/time/juce_RelativeTime.cpp b/modules/juce_core/time/juce_RelativeTime.cpp index 0775054e..c9a2514b 100644 --- a/modules/juce_core/time/juce_RelativeTime.cpp +++ b/modules/juce_core/time/juce_RelativeTime.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -28,8 +28,8 @@ RelativeTime::RelativeTime (const RelativeTime& other) noexcept : numSeconds ( RelativeTime::~RelativeTime() noexcept {} //============================================================================== -RelativeTime RelativeTime::milliseconds (int milliseconds) noexcept { return RelativeTime (milliseconds * 0.001); } -RelativeTime RelativeTime::milliseconds (int64 milliseconds) noexcept { return RelativeTime (milliseconds * 0.001); } +RelativeTime RelativeTime::milliseconds (int milliseconds) noexcept { return RelativeTime ((double) milliseconds * 0.001); } +RelativeTime RelativeTime::milliseconds (int64 milliseconds) noexcept { return RelativeTime ((double) milliseconds * 0.001); } RelativeTime RelativeTime::seconds (double s) noexcept { return RelativeTime (s); } RelativeTime RelativeTime::minutes (double numberOfMinutes) noexcept { return RelativeTime (numberOfMinutes * 60.0); } RelativeTime RelativeTime::hours (double numberOfHours) noexcept { return RelativeTime (numberOfHours * (60.0 * 60.0)); } diff --git a/modules/juce_core/time/juce_RelativeTime.h b/modules/juce_core/time/juce_RelativeTime.h index e9741d22..e7d546ee 100644 --- a/modules/juce_core/time/juce_RelativeTime.h +++ b/modules/juce_core/time/juce_RelativeTime.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/time/juce_Time.cpp b/modules/juce_core/time/juce_Time.cpp index 4d7d5d16..ecbdbf14 100644 --- a/modules/juce_core/time/juce_Time.cpp +++ b/modules/juce_core/time/juce_Time.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -91,7 +91,7 @@ namespace TimeHelpers : (value - ((value / modulo) + 1) * modulo)); } - static inline String formatString (const String& format, const std::tm* const tm) + static String formatString (const String& format, const std::tm* const tm) { #if JUCE_ANDROID using StringType = CharPointer_UTF8; @@ -126,12 +126,12 @@ namespace TimeHelpers } //============================================================================== - static inline bool isLeapYear (int year) noexcept + static bool isLeapYear (int year) noexcept { return (year % 400 == 0) || ((year % 100 != 0) && (year % 4 == 0)); } - static inline int daysFromJan1 (int year, int month) noexcept + static int daysFromJan1 (int year, int month) noexcept { const short dayOfYear[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 }; @@ -139,18 +139,18 @@ namespace TimeHelpers return dayOfYear [(isLeapYear (year) ? 12 : 0) + month]; } - static inline int64 daysFromYear0 (int year) noexcept + static int64 daysFromYear0 (int year) noexcept { --year; return 365 * year + (year / 400) - (year / 100) + (year / 4); } - static inline int64 daysFrom1970 (int year) noexcept + static int64 daysFrom1970 (int year) noexcept { return daysFromYear0 (year) - daysFromYear0 (1970); } - static inline int64 daysFrom1970 (int year, int month) noexcept + static int64 daysFrom1970 (int year, int month) noexcept { if (month > 11) { @@ -169,7 +169,7 @@ namespace TimeHelpers // There's no posix function that does a UTC version of mktime, // so annoyingly we need to implement this manually.. - static inline int64 mktime_utc (const std::tm& t) noexcept + static int64 mktime_utc (const std::tm& t) noexcept { return 24 * 3600 * (daysFrom1970 (t.tm_year + 1900, t.tm_mon) + (t.tm_mday - 1)) + 3600 * t.tm_hour @@ -277,7 +277,7 @@ void Time::waitForMillisecondCounter (uint32 targetTime) noexcept //============================================================================== double Time::highResolutionTicksToSeconds (const int64 ticks) noexcept { - return ticks / (double) getHighResolutionTicksPerSecond(); + return (double) ticks / (double) getHighResolutionTicksPerSecond(); } int64 Time::secondsToHighResolutionTicks (const double seconds) noexcept diff --git a/modules/juce_core/time/juce_Time.h b/modules/juce_core/time/juce_Time.h index 72d9c2fd..aab745c1 100644 --- a/modules/juce_core/time/juce_Time.h +++ b/modules/juce_core/time/juce_Time.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/unit_tests/juce_UnitTest.cpp b/modules/juce_core/unit_tests/juce_UnitTest.cpp index c35a86a5..c80ecd82 100644 --- a/modules/juce_core/unit_tests/juce_UnitTest.cpp +++ b/modules/juce_core/unit_tests/juce_UnitTest.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -199,15 +199,11 @@ void UnitTestRunner::beginNewTest (UnitTest* const test, const String& subCatego endTest(); currentTest = test; - auto* r = new TestResult(); - results.add (r); - r->unitTestName = test->getName(); - r->subcategoryName = subCategory; - r->passes = 0; - r->failures = 0; + auto testName = test->getName(); + results.add (new TestResult (testName, subCategory)); logMessage ("-----------------------------------------------------------------"); - logMessage ("Starting test: " + r->unitTestName + " / " + subCategory + "..."); + logMessage ("Starting test: " + testName + " / " + subCategory + "..."); resultsUpdated(); } @@ -216,6 +212,8 @@ void UnitTestRunner::endTest() { if (auto* r = results.getLast()) { + r->endTime = Time::getCurrentTime(); + if (r->failures > 0) { String m ("FAILED!! "); diff --git a/modules/juce_core/unit_tests/juce_UnitTest.h b/modules/juce_core/unit_tests/juce_UnitTest.h index 4cf2646e..e843fe53 100644 --- a/modules/juce_core/unit_tests/juce_UnitTest.h +++ b/modules/juce_core/unit_tests/juce_UnitTest.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -376,18 +376,31 @@ public: */ struct TestResult { + TestResult() = default; + + explicit TestResult (const String& name, const String& subCategory) + : unitTestName (name), + subcategoryName (subCategory) + { + } + /** The main name of this test (i.e. the name of the UnitTest object being run). */ String unitTestName; /** The name of the current subcategory (i.e. the name that was set when UnitTest::beginTest() was called). */ String subcategoryName; /** The number of UnitTest::expect() calls that succeeded. */ - int passes; + int passes = 0; /** The number of UnitTest::expect() calls that failed. */ - int failures; + int failures = 0; /** A list of messages describing the failed tests. */ StringArray messages; + + /** The time at which this test was started. */ + Time startTime = Time::getCurrentTime(); + /** The time at which this test ended. */ + Time endTime; }; /** Returns the number of TestResult objects that have been performed. diff --git a/modules/juce_core/unit_tests/juce_UnitTestCategories.h b/modules/juce_core/unit_tests/juce_UnitTestCategories.h index fdc1d445..9f6fa6ca 100644 --- a/modules/juce_core/unit_tests/juce_UnitTestCategories.h +++ b/modules/juce_core/unit_tests/juce_UnitTestCategories.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -35,6 +35,7 @@ namespace UnitTestCategories static const String dsp { "DSP" }; static const String files { "Files" }; static const String function { "Function" }; + static const String graphics { "Graphics" }; static const String gui { "GUI" }; static const String json { "JSON" }; static const String maths { "Maths" }; diff --git a/modules/juce_core/xml/juce_XmlDocument.cpp b/modules/juce_core/xml/juce_XmlDocument.cpp index 040ebc01..eb472c3e 100644 --- a/modules/juce_core/xml/juce_XmlDocument.cpp +++ b/modules/juce_core/xml/juce_XmlDocument.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/xml/juce_XmlDocument.h b/modules/juce_core/xml/juce_XmlDocument.h index 0b200f05..ebc554de 100644 --- a/modules/juce_core/xml/juce_XmlDocument.h +++ b/modules/juce_core/xml/juce_XmlDocument.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -93,8 +93,7 @@ public: allows quick checking of large files to see if they contain the correct type of tag, without having to parse the entire file - @returns a new XmlElement which the caller will need to delete, or null if - there was an error. + @returns a new XmlElement, or nullptr if there was an error. @see getLastParseError, getDocumentElementIfTagMatches */ std::unique_ptr<XmlElement> getDocumentElement (bool onlyReadOuterDocumentElement = false); @@ -136,14 +135,14 @@ public: /** A handy static method that parses a file. This is a shortcut for creating an XmlDocument object and calling getDocumentElement() on it. An even better shortcut is the juce::parseXML() function, which returns a std::unique_ptr<XmlElement>! - @returns a new XmlElement which the caller will need to delete, or null if there was an error. + @returns a new XmlElement, or nullptr if there was an error. */ static std::unique_ptr<XmlElement> parse (const File& file); /** A handy static method that parses some XML data. This is a shortcut for creating an XmlDocument object and calling getDocumentElement() on it. An even better shortcut is the juce::parseXML() function, which returns a std::unique_ptr<XmlElement>! - @returns a new XmlElement which the caller will need to delete, or null if there was an error. + @returns a new XmlElement, or nullptr if there was an error. */ static std::unique_ptr<XmlElement> parse (const String& xmlData); diff --git a/modules/juce_core/xml/juce_XmlElement.cpp b/modules/juce_core/xml/juce_XmlElement.cpp index 1e3bdd4b..668c8c7a 100644 --- a/modules/juce_core/xml/juce_XmlElement.cpp +++ b/modules/juce_core/xml/juce_XmlElement.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -23,7 +23,7 @@ namespace juce { -inline static bool isValidXmlNameStartCharacter (juce_wchar character) noexcept +static bool isValidXmlNameStartCharacter (juce_wchar character) noexcept { return character == ':' || character == '_' @@ -43,7 +43,7 @@ inline static bool isValidXmlNameStartCharacter (juce_wchar character) noexcept || (character >= 0x10000 && character <= 0xeffff); } -inline static bool isValidXmlNameBodyCharacter (juce_wchar character) noexcept +static bool isValidXmlNameBodyCharacter (juce_wchar character) noexcept { return isValidXmlNameStartCharacter (character) || character == '-' @@ -237,7 +237,7 @@ namespace XmlOutputFunctions outputStream << (char) character; break; } - // Note: Deliberate fall-through here! + JUCE_FALLTHROUGH default: outputStream << "&#" << ((int) character) << ';'; break; diff --git a/modules/juce_core/xml/juce_XmlElement.h b/modules/juce_core/xml/juce_XmlElement.h index 91079cf1..d15c7ac9 100644 --- a/modules/juce_core/xml/juce_XmlElement.h +++ b/modules/juce_core/xml/juce_XmlElement.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/zip/juce_GZIPCompressorOutputStream.cpp b/modules/juce_core/zip/juce_GZIPCompressorOutputStream.cpp index 8551f2c9..3e8199e6 100644 --- a/modules/juce_core/zip/juce_GZIPCompressorOutputStream.cpp +++ b/modules/juce_core/zip/juce_GZIPCompressorOutputStream.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -92,7 +92,7 @@ private: { case Z_STREAM_END: finished = true; - // Deliberate fall-through.. + JUCE_FALLTHROUGH case Z_OK: { data += dataSize - stream.avail_in; diff --git a/modules/juce_core/zip/juce_GZIPCompressorOutputStream.h b/modules/juce_core/zip/juce_GZIPCompressorOutputStream.h index f9a06d9d..63ff6b9d 100644 --- a/modules/juce_core/zip/juce_GZIPCompressorOutputStream.h +++ b/modules/juce_core/zip/juce_GZIPCompressorOutputStream.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/zip/juce_GZIPDecompressorInputStream.cpp b/modules/juce_core/zip/juce_GZIPDecompressorInputStream.cpp index 624c4b1a..b3403d16 100644 --- a/modules/juce_core/zip/juce_GZIPDecompressorInputStream.cpp +++ b/modules/juce_core/zip/juce_GZIPDecompressorInputStream.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -23,34 +23,21 @@ namespace juce { -#if JUCE_MSVC - #pragma warning (push) - #pragma warning (disable: 4309 4305 4365) -#endif +JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4309 4305 4365) namespace zlibNamespace { #if JUCE_INCLUDE_ZLIB_CODE - #if JUCE_CLANG - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wconversion" - #pragma clang diagnostic ignored "-Wshadow" - #pragma clang diagnostic ignored "-Wdeprecated-register" - #if __has_warning("-Wzero-as-null-pointer-constant") - #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" - #endif - #if __has_warning("-Wcomma") - #pragma clang diagnostic ignored "-Wcomma" - #endif - #endif - - #if JUCE_GCC - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wconversion" - #pragma GCC diagnostic ignored "-Wsign-conversion" - #pragma GCC diagnostic ignored "-Wshadow" - #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - #endif + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wconversion", + "-Wsign-conversion", + "-Wshadow", + "-Wdeprecated-register", + "-Wswitch-enum", + "-Wswitch-default", + "-Wredundant-decls", + "-Wimplicit-fallthrough", + "-Wzero-as-null-pointer-constant", + "-Wcomma") #undef OS_CODE #undef fdopen @@ -83,13 +70,7 @@ namespace zlibNamespace #undef Dad #undef Len - #if JUCE_CLANG - #pragma clang diagnostic pop - #endif - - #if JUCE_GCC - #pragma GCC diagnostic pop - #endif + JUCE_END_IGNORE_WARNINGS_GCC_LIKE #else #include JUCE_ZLIB_INCLUDE_PATH @@ -104,9 +85,7 @@ namespace zlibNamespace #endif } -#if JUCE_MSVC - #pragma warning (pop) -#endif +JUCE_END_IGNORE_WARNINGS_MSVC //============================================================================== // internal helper object that holds the zlib structures so they don't have to be @@ -151,7 +130,7 @@ public: { case Z_STREAM_END: finished = true; - // deliberate fall-through + JUCE_FALLTHROUGH case Z_OK: data += dataSize - stream.avail_in; dataSize = (z_uInt) stream.avail_in; @@ -166,7 +145,7 @@ public: case Z_DATA_ERROR: case Z_MEM_ERROR: error = true; - + JUCE_FALLTHROUGH default: break; } diff --git a/modules/juce_core/zip/juce_GZIPDecompressorInputStream.h b/modules/juce_core/zip/juce_GZIPDecompressorInputStream.h index a5debf30..14edf85e 100644 --- a/modules/juce_core/zip/juce_GZIPDecompressorInputStream.h +++ b/modules/juce_core/zip/juce_GZIPDecompressorInputStream.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_core/zip/juce_ZipFile.cpp b/modules/juce_core/zip/juce_ZipFile.cpp index 4c492255..1bc025f5 100644 --- a/modules/juce_core/zip/juce_ZipFile.cpp +++ b/modules/juce_core/zip/juce_ZipFile.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -541,7 +541,7 @@ private: { if (stream == nullptr) { - stream.reset (file.createInputStream()); + stream = file.createInputStream(); if (stream == nullptr) return false; @@ -577,7 +577,7 @@ private: target.writeInt ((int) checksum); target.writeInt ((int) (uint32) compressedSize); target.writeInt ((int) (uint32) uncompressedSize); - target.writeShort ((short) storedPathname.toUTF8().sizeInBytes() - 1); + target.writeShort (static_cast<short> (storedPathname.toUTF8().sizeInBytes() - 1)); target.writeShort (0); // extra field length } diff --git a/modules/juce_core/zip/juce_ZipFile.h b/modules/juce_core/zip/juce_ZipFile.h index e3f8b764..d0a4baff 100644 --- a/modules/juce_core/zip/juce_ZipFile.h +++ b/modules/juce_core/zip/juce_ZipFile.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_cryptography/encryption/juce_BlowFish.cpp b/modules/juce_cryptography/encryption/juce_BlowFish.cpp index fb4fa22e..a56b9429 100644 --- a/modules/juce_cryptography/encryption/juce_BlowFish.cpp +++ b/modules/juce_cryptography/encryption/juce_BlowFish.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -338,7 +337,7 @@ bool BlowFish::apply (void* data, size_t size, void (BlowFish::*op) (uint32&, ui int BlowFish::pad (void* data, size_t size, size_t bufferSize) noexcept { // add padding according to https://tools.ietf.org/html/rfc2898#section-6.1.1 - const uint8 paddingSize = 8u - (size % 8u); + const uint8 paddingSize = static_cast<uint8> (8u - (size % 8u)); auto n = size + paddingSize; if (n > bufferSize) diff --git a/modules/juce_cryptography/encryption/juce_BlowFish.h b/modules/juce_cryptography/encryption/juce_BlowFish.h index 57ab8c63..12bcf4c8 100644 --- a/modules/juce_cryptography/encryption/juce_BlowFish.h +++ b/modules/juce_cryptography/encryption/juce_BlowFish.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_cryptography/encryption/juce_Primes.cpp b/modules/juce_cryptography/encryption/juce_Primes.cpp index 217f9815..b2aa0beb 100644 --- a/modules/juce_cryptography/encryption/juce_Primes.cpp +++ b/modules/juce_cryptography/encryption/juce_Primes.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_cryptography/encryption/juce_Primes.h b/modules/juce_cryptography/encryption/juce_Primes.h index a0bc3504..59f79e94 100644 --- a/modules/juce_cryptography/encryption/juce_Primes.h +++ b/modules/juce_cryptography/encryption/juce_Primes.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_cryptography/encryption/juce_RSAKey.cpp b/modules/juce_cryptography/encryption/juce_RSAKey.cpp index 8e5eb77d..e79cf4e9 100644 --- a/modules/juce_cryptography/encryption/juce_RSAKey.cpp +++ b/modules/juce_cryptography/encryption/juce_RSAKey.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_cryptography/encryption/juce_RSAKey.h b/modules/juce_cryptography/encryption/juce_RSAKey.h index b3ec74ee..1d9eedb8 100644 --- a/modules/juce_cryptography/encryption/juce_RSAKey.h +++ b/modules/juce_cryptography/encryption/juce_RSAKey.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_cryptography/hashing/juce_MD5.cpp b/modules/juce_cryptography/hashing/juce_MD5.cpp index f15bd271..b46ee022 100644 --- a/modules/juce_cryptography/hashing/juce_MD5.cpp +++ b/modules/juce_cryptography/hashing/juce_MD5.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -155,12 +154,12 @@ private: #endif } - static inline uint32_t rotateLeft (uint32_t x, uint32_t n) noexcept { return (x << n) | (x >> (32 - n)); } + static uint32_t rotateLeft (uint32_t x, uint32_t n) noexcept { return (x << n) | (x >> (32 - n)); } - static inline uint32_t F (uint32_t x, uint32_t y, uint32_t z) noexcept { return (x & y) | (~x & z); } - static inline uint32_t G (uint32_t x, uint32_t y, uint32_t z) noexcept { return (x & z) | (y & ~z); } - static inline uint32_t H (uint32_t x, uint32_t y, uint32_t z) noexcept { return x ^ y ^ z; } - static inline uint32_t I (uint32_t x, uint32_t y, uint32_t z) noexcept { return y ^ (x | ~z); } + static uint32_t F (uint32_t x, uint32_t y, uint32_t z) noexcept { return (x & y) | (~x & z); } + static uint32_t G (uint32_t x, uint32_t y, uint32_t z) noexcept { return (x & z) | (y & ~z); } + static uint32_t H (uint32_t x, uint32_t y, uint32_t z) noexcept { return x ^ y ^ z; } + static uint32_t I (uint32_t x, uint32_t y, uint32_t z) noexcept { return y ^ (x | ~z); } static void FF (uint32_t& a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac) noexcept { diff --git a/modules/juce_cryptography/hashing/juce_MD5.h b/modules/juce_cryptography/hashing/juce_MD5.h index b27084f4..da1e55cd 100644 --- a/modules/juce_cryptography/hashing/juce_MD5.h +++ b/modules/juce_cryptography/hashing/juce_MD5.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_cryptography/hashing/juce_SHA256.cpp b/modules/juce_cryptography/hashing/juce_SHA256.cpp index 6a952932..ce382955 100644 --- a/modules/juce_cryptography/hashing/juce_SHA256.cpp +++ b/modules/juce_cryptography/hashing/juce_SHA256.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -139,14 +138,14 @@ private: 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 }; uint64_t length = 0; - static inline uint32_t rotate (uint32_t x, uint32_t y) noexcept { return (x >> y) | (x << (32 - y)); } - static inline uint32_t ch (uint32_t x, uint32_t y, uint32_t z) noexcept { return z ^ ((y ^ z) & x); } - static inline uint32_t maj (uint32_t x, uint32_t y, uint32_t z) noexcept { return y ^ ((y ^ z) & (x ^ y)); } + static uint32_t rotate (uint32_t x, uint32_t y) noexcept { return (x >> y) | (x << (32 - y)); } + static uint32_t ch (uint32_t x, uint32_t y, uint32_t z) noexcept { return z ^ ((y ^ z) & x); } + static uint32_t maj (uint32_t x, uint32_t y, uint32_t z) noexcept { return y ^ ((y ^ z) & (x ^ y)); } - static inline uint32_t s0 (uint32_t x) noexcept { return rotate (x, 7) ^ rotate (x, 18) ^ (x >> 3); } - static inline uint32_t s1 (uint32_t x) noexcept { return rotate (x, 17) ^ rotate (x, 19) ^ (x >> 10); } - static inline uint32_t S0 (uint32_t x) noexcept { return rotate (x, 2) ^ rotate (x, 13) ^ rotate (x, 22); } - static inline uint32_t S1 (uint32_t x) noexcept { return rotate (x, 6) ^ rotate (x, 11) ^ rotate (x, 25); } + static uint32_t s0 (uint32_t x) noexcept { return rotate (x, 7) ^ rotate (x, 18) ^ (x >> 3); } + static uint32_t s1 (uint32_t x) noexcept { return rotate (x, 17) ^ rotate (x, 19) ^ (x >> 10); } + static uint32_t S0 (uint32_t x) noexcept { return rotate (x, 2) ^ rotate (x, 13) ^ rotate (x, 22); } + static uint32_t S1 (uint32_t x) noexcept { return rotate (x, 6) ^ rotate (x, 11) ^ rotate (x, 25); } }; //============================================================================== diff --git a/modules/juce_cryptography/hashing/juce_SHA256.h b/modules/juce_cryptography/hashing/juce_SHA256.h index fcef2144..74f615c6 100644 --- a/modules/juce_cryptography/hashing/juce_SHA256.h +++ b/modules/juce_cryptography/hashing/juce_SHA256.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_cryptography/hashing/juce_Whirlpool.cpp b/modules/juce_cryptography/hashing/juce_Whirlpool.cpp index 7365fe76..cfec0a69 100644 --- a/modules/juce_cryptography/hashing/juce_Whirlpool.cpp +++ b/modules/juce_cryptography/hashing/juce_Whirlpool.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -93,7 +92,7 @@ private: bufferBits = bufferPos = 0; } - buffer[bufferPos] = (uint8_t) (b << (8 - bufferRem)); + buffer[bufferPos] = static_cast<uint8_t> (b << (8 - bufferRem)); bufferBits += bufferRem; numBits -= 8; @@ -103,7 +102,7 @@ private: if (numBits > 0) { b = (source[sourcePos] << sourceGap) & 0xff; - buffer[bufferPos] |= (b >> bufferRem); + buffer[bufferPos] = static_cast<uint8_t> (buffer[bufferPos] | (b >> bufferRem)); } else { @@ -126,7 +125,7 @@ private: bufferBits = bufferPos = 0; } - buffer[bufferPos] = (uint8_t) (b << (8 - bufferRem)); + buffer[bufferPos] = static_cast<uint8_t> (b << (8 - bufferRem)); bufferBits += numBits; } } @@ -134,7 +133,8 @@ private: void finalize (uint8_t* result) noexcept { // append a '1'-bit - buffer[bufferPos++] |= 0x80u >> (bufferBits & 7); + buffer[bufferPos] = static_cast<uint8_t> (buffer[bufferPos] | (0x80u >> (bufferBits & 7))); + bufferPos++; // pad with zero bits to complete (N*(64*8) - (32*8)) bits if (bufferPos > 32) diff --git a/modules/juce_cryptography/hashing/juce_Whirlpool.h b/modules/juce_cryptography/hashing/juce_Whirlpool.h index 5834bb42..555f2126 100644 --- a/modules/juce_cryptography/hashing/juce_Whirlpool.h +++ b/modules/juce_cryptography/hashing/juce_Whirlpool.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_cryptography/juce_cryptography.cpp b/modules/juce_cryptography/juce_cryptography.cpp index e9cf86f3..f1d8f23c 100644 --- a/modules/juce_cryptography/juce_cryptography.cpp +++ b/modules/juce_cryptography/juce_cryptography.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_cryptography/juce_cryptography.h b/modules/juce_cryptography/juce_cryptography.h index f27c8369..1c2eebc7 100644 --- a/modules/juce_cryptography/juce_cryptography.h +++ b/modules/juce_cryptography/juce_cryptography.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -29,14 +28,14 @@ The block below describes the properties of this module, and is read by the Projucer to automatically generate project code that uses it. For details about the syntax and how to create or use a module, see the - JUCE Module Format.txt file. + JUCE Module Format.md file. BEGIN_JUCE_MODULE_DECLARATION ID: juce_cryptography vendor: juce - version: 5.4.7 + version: 6.0.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_cryptography/juce_cryptography.mm b/modules/juce_cryptography/juce_cryptography.mm index c28b6f9c..79d1b129 100644 --- a/modules/juce_cryptography/juce_cryptography.mm +++ b/modules/juce_cryptography/juce_cryptography.mm @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_data_structures/app_properties/juce_ApplicationProperties.cpp b/modules/juce_data_structures/app_properties/juce_ApplicationProperties.cpp index ba06f5b9..c770d190 100644 --- a/modules/juce_data_structures/app_properties/juce_ApplicationProperties.cpp +++ b/modules/juce_data_structures/app_properties/juce_ApplicationProperties.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_data_structures/app_properties/juce_ApplicationProperties.h b/modules/juce_data_structures/app_properties/juce_ApplicationProperties.h index 7d0aadf5..d1e487e5 100644 --- a/modules/juce_data_structures/app_properties/juce_ApplicationProperties.h +++ b/modules/juce_data_structures/app_properties/juce_ApplicationProperties.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_data_structures/app_properties/juce_PropertiesFile.cpp b/modules/juce_data_structures/app_properties/juce_PropertiesFile.cpp index 39b85dc6..7b437cb7 100644 --- a/modules/juce_data_structures/app_properties/juce_PropertiesFile.cpp +++ b/modules/juce_data_structures/app_properties/juce_PropertiesFile.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -29,13 +28,13 @@ namespace juce namespace PropertyFileConstants { - JUCE_CONSTEXPR static const int magicNumber = (int) ByteOrder::makeInt ('P', 'R', 'O', 'P'); - JUCE_CONSTEXPR static const int magicNumberCompressed = (int) ByteOrder::makeInt ('C', 'P', 'R', 'P'); + constexpr static const int magicNumber = (int) ByteOrder::makeInt ('P', 'R', 'O', 'P'); + constexpr static const int magicNumberCompressed = (int) ByteOrder::makeInt ('C', 'P', 'R', 'P'); - JUCE_CONSTEXPR static const char* const fileTag = "PROPERTIES"; - JUCE_CONSTEXPR static const char* const valueTag = "VALUE"; - JUCE_CONSTEXPR static const char* const nameAttribute = "name"; - JUCE_CONSTEXPR static const char* const valueAttribute = "val"; + constexpr static const char* const fileTag = "PROPERTIES"; + constexpr static const char* const valueTag = "VALUE"; + constexpr static const char* const nameAttribute = "name"; + constexpr static const char* const valueAttribute = "val"; } //============================================================================== diff --git a/modules/juce_data_structures/app_properties/juce_PropertiesFile.h b/modules/juce_data_structures/app_properties/juce_PropertiesFile.h index 8ef3ae0a..448cc7f8 100644 --- a/modules/juce_data_structures/app_properties/juce_PropertiesFile.h +++ b/modules/juce_data_structures/app_properties/juce_PropertiesFile.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_data_structures/juce_data_structures.cpp b/modules/juce_data_structures/juce_data_structures.cpp index 79a163e6..9ad4bbc6 100644 --- a/modules/juce_data_structures/juce_data_structures.cpp +++ b/modules/juce_data_structures/juce_data_structures.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_data_structures/juce_data_structures.h b/modules/juce_data_structures/juce_data_structures.h index 1def8be2..4669261d 100644 --- a/modules/juce_data_structures/juce_data_structures.h +++ b/modules/juce_data_structures/juce_data_structures.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -29,14 +28,14 @@ The block below describes the properties of this module, and is read by the Projucer to automatically generate project code that uses it. For details about the syntax and how to create or use a module, see the - JUCE Module Format.txt file. + JUCE Module Format.md file. BEGIN_JUCE_MODULE_DECLARATION ID: juce_data_structures vendor: juce - version: 5.4.7 + version: 6.0.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_data_structures/juce_data_structures.mm b/modules/juce_data_structures/juce_data_structures.mm index f7434ca8..06c479a4 100644 --- a/modules/juce_data_structures/juce_data_structures.mm +++ b/modules/juce_data_structures/juce_data_structures.mm @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_data_structures/undomanager/juce_UndoManager.cpp b/modules/juce_data_structures/undomanager/juce_UndoManager.cpp index d44b1b7f..69097965 100644 --- a/modules/juce_data_structures/undomanager/juce_UndoManager.cpp +++ b/modules/juce_data_structures/undomanager/juce_UndoManager.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_data_structures/undomanager/juce_UndoManager.h b/modules/juce_data_structures/undomanager/juce_UndoManager.h index 96319950..6ebfc56c 100644 --- a/modules/juce_data_structures/undomanager/juce_UndoManager.h +++ b/modules/juce_data_structures/undomanager/juce_UndoManager.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_data_structures/undomanager/juce_UndoableAction.h b/modules/juce_data_structures/undomanager/juce_UndoableAction.h index 62d1e6b9..1aee24c1 100644 --- a/modules/juce_data_structures/undomanager/juce_UndoableAction.h +++ b/modules/juce_data_structures/undomanager/juce_UndoableAction.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_data_structures/values/juce_CachedValue.cpp b/modules/juce_data_structures/values/juce_CachedValue.cpp index dbf070b4..8d22ccac 100644 --- a/modules/juce_data_structures/values/juce_CachedValue.cpp +++ b/modules/juce_data_structures/values/juce_CachedValue.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_data_structures/values/juce_CachedValue.h b/modules/juce_data_structures/values/juce_CachedValue.h index 6236e506..f0bcd45a 100644 --- a/modules/juce_data_structures/values/juce_CachedValue.h +++ b/modules/juce_data_structures/values/juce_CachedValue.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_data_structures/values/juce_Value.cpp b/modules/juce_data_structures/values/juce_Value.cpp index d67f9d2c..496527e5 100644 --- a/modules/juce_data_structures/values/juce_Value.cpp +++ b/modules/juce_data_structures/values/juce_Value.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_data_structures/values/juce_Value.h b/modules/juce_data_structures/values/juce_Value.h index 42590208..90babe87 100644 --- a/modules/juce_data_structures/values/juce_Value.h +++ b/modules/juce_data_structures/values/juce_Value.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_data_structures/values/juce_ValueTree.cpp b/modules/juce_data_structures/values/juce_ValueTree.cpp index e185d8d8..088f74d0 100644 --- a/modules/juce_data_structures/values/juce_ValueTree.cpp +++ b/modules/juce_data_structures/values/juce_ValueTree.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_data_structures/values/juce_ValueTree.h b/modules/juce_data_structures/values/juce_ValueTree.h index 0f4f725a..27e1826a 100644 --- a/modules/juce_data_structures/values/juce_ValueTree.h +++ b/modules/juce_data_structures/values/juce_ValueTree.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -427,7 +426,6 @@ public: /** Creates an XmlElement that holds a complete image of this tree and all its children. If this tree is invalid, this may return nullptr. Otherwise, the XML that is produced can be used to recreate a similar tree by calling ValueTree::fromXml(). - The caller must delete the object that is returned. @see fromXml, toXmlString */ std::unique_ptr<XmlElement> createXml() const; diff --git a/modules/juce_data_structures/values/juce_ValueTreeSynchroniser.cpp b/modules/juce_data_structures/values/juce_ValueTreeSynchroniser.cpp index 68cca268..1fb36fe8 100644 --- a/modules/juce_data_structures/values/juce_ValueTreeSynchroniser.cpp +++ b/modules/juce_data_structures/values/juce_ValueTreeSynchroniser.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -229,6 +228,9 @@ bool ValueTreeSynchroniser::applyChange (ValueTree& root, const void* data, size break; } + case ValueTreeSynchroniserHelpers::fullSync: + break; + default: jassertfalse; // Seem to have received some corrupt data? break; diff --git a/modules/juce_data_structures/values/juce_ValueTreeSynchroniser.h b/modules/juce_data_structures/values/juce_ValueTreeSynchroniser.h index 5d5a9835..095dadd0 100644 --- a/modules/juce_data_structures/values/juce_ValueTreeSynchroniser.h +++ b/modules/juce_data_structures/values/juce_ValueTreeSynchroniser.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_data_structures/values/juce_ValueWithDefault.cpp b/modules/juce_data_structures/values/juce_ValueWithDefault.cpp index 8cd16dfb..38a7539c 100644 --- a/modules/juce_data_structures/values/juce_ValueWithDefault.cpp +++ b/modules/juce_data_structures/values/juce_ValueWithDefault.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_data_structures/values/juce_ValueWithDefault.h b/modules/juce_data_structures/values/juce_ValueWithDefault.h index f3b58d39..8160cdda 100644 --- a/modules/juce_data_structures/values/juce_ValueWithDefault.h +++ b/modules/juce_data_structures/values/juce_ValueWithDefault.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -31,7 +30,7 @@ namespace juce /** This class acts as a wrapper around a property inside a ValueTree. - If the property inside the ValueTree is missing or empty the ValueWithDefault will automatically + If the property inside the ValueTree is missing the ValueWithDefault will automatically return a default value, which can be specified when initialising the ValueWithDefault. @tags{DataStructures} @@ -89,7 +88,7 @@ public: } //============================================================================== - /** Returns the current value of the property. If the property does not exist or is empty, + /** Returns the current value of the property. If the property does not exist this returns the default value. */ var get() const noexcept diff --git a/modules/juce_dsp/containers/juce_AudioBlock.h b/modules/juce_dsp/containers/juce_AudioBlock.h index b8c0074b..35cdaa15 100644 --- a/modules/juce_dsp/containers/juce_AudioBlock.h +++ b/modules/juce_dsp/containers/juce_AudioBlock.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -125,10 +124,10 @@ public: heapBlockToUseForAllocation.malloc (channelListBytes + extraBytes + channelSize * numberOfChannels); - auto* chanArray = reinterpret_cast<SampleType**> (heapBlockToUseForAllocation.getData()); + auto* chanArray = unalignedPointerCast<SampleType**> (heapBlockToUseForAllocation.getData()); channels = chanArray; - auto* data = reinterpret_cast<SampleType*> (addBytesToPointer (chanArray, channelListBytes)); + auto* data = unalignedPointerCast<SampleType*> (addBytesToPointer (chanArray, channelListBytes)); data = snapPointerToAlignment (data, alignmentInBytes); for (ChannelCountType i = 0; i < numChannels; ++i) @@ -151,6 +150,19 @@ public: { } + /** Creates an AudioBlock that points to the data in an AudioBuffer. + AudioBlock does not copy nor own the memory pointed to by dataToUse. + Therefore it is the user's responsibility to ensure that the buffer is retained + throughout the life-time of the AudioBlock without being modified. + */ + template <typename OtherSampleType> + constexpr AudioBlock (const AudioBuffer<OtherSampleType>& buffer) noexcept + : channels (buffer.getArrayOfReadPointers()), + numChannels (static_cast<ChannelCountType> (buffer.getNumChannels())), + numSamples (static_cast<size_t> (buffer.getNumSamples())) + { + } + /** Creates an AudioBlock that points to the data in an AudioBuffer. AudioBlock does not copy nor own the memory pointed to by dataToUse. Therefore it is the user's responsibility to ensure that the buffer is retained diff --git a/modules/juce_dsp/containers/juce_AudioBlock_test.cpp b/modules/juce_dsp/containers/juce_AudioBlock_test.cpp index ce86f05f..a337ebee 100644 --- a/modules/juce_dsp/containers/juce_AudioBlock_test.cpp +++ b/modules/juce_dsp/containers/juce_AudioBlock_test.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -300,7 +299,7 @@ public: beginTest ("Process"); { resetBlocks(); - AudioBlock<SampleType>::process (block, otherBlock, [](SampleType x) { return x + (NumericType) 1.0; }); + AudioBlock<SampleType>::process (block, otherBlock, [] (SampleType x) { return x + (NumericType) 1.0; }); expect (otherBlock.getSample (0, 4) == SampleType (6.0)); expect (otherBlock.getSample (1, 4) == SampleType (12.0)); } @@ -355,6 +354,7 @@ private: expectEquals (otherBuffer.getSample (1, 2), block.getSample (1, 3)); } + #if JUCE_USE_SIMD template <typename T = SampleType> SIMDVoid<T> copyingTests() { @@ -397,6 +397,7 @@ private: expectEquals (block.getSample (1, 3).get (1), numericData.getSample (1, (int) ((numSIMDElements * 2) + 1))); } } + #endif //============================================================================== template <typename T = SampleType> @@ -492,8 +493,11 @@ private: static AudioBlockUnitTests<float> audioBlockFloatUnitTests; static AudioBlockUnitTests<double> audioBlockDoubleUnitTests; + +#if JUCE_USE_SIMD static AudioBlockUnitTests<SIMDRegister<float>> audioBlockSIMDFloatUnitTests; static AudioBlockUnitTests<SIMDRegister<double>> audioBlockSIMDDoubleUnitTests; +#endif } // namespace dsp } // namespace juce diff --git a/modules/juce_dsp/containers/juce_FixedSizeFunction.h b/modules/juce_dsp/containers/juce_FixedSizeFunction.h new file mode 100644 index 00000000..d298c2d6 --- /dev/null +++ b/modules/juce_dsp/containers/juce_FixedSizeFunction.h @@ -0,0 +1,243 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +#ifndef DOXYGEN + +namespace detail +{ + template <typename Ret, typename... Args> + struct Vtable + { + using Storage = void*; + + using Move = void (*) (Storage, Storage); + using Call = Ret (*) (Storage, Args...); + using Clear = void (*) (Storage); + + constexpr Vtable (Move moveIn, Call callIn, Clear clearIn) noexcept + : move (moveIn), call (callIn), clear (clearIn) {} + + Move move = nullptr; + Call call = nullptr; + Clear clear = nullptr; + }; + + template <typename Fn> + void move (void* from, void* to) + { + new (to) Fn (std::move (*reinterpret_cast<Fn*> (from))); + } + + template <typename Fn, typename Ret, typename... Args> + typename std::enable_if<std::is_same<Ret, void>::value, Ret>::type call (void* s, Args... args) + { + (*reinterpret_cast<Fn*> (s)) (args...); + } + + template <typename Fn, typename Ret, typename... Args> + typename std::enable_if<! std::is_same<Ret, void>::value, Ret>::type call (void* s, Args... args) + { + return (*reinterpret_cast<Fn*> (s)) (std::forward<Args> (args)...); + } + + template <typename Fn> + void clear (void* s) + { + auto& fn = *reinterpret_cast<Fn*> (s); + fn.~Fn(); + // I know this looks insane, for some reason MSVC 14 sometimes thinks fn is unreferenced + juce::ignoreUnused (fn); + } + + template <typename Fn, typename Ret, typename... Args> + constexpr Vtable<Ret, Args...> makeVtable() + { + return { move <Fn>, call <Fn, Ret, Args...>, clear<Fn> }; + } +} // namespace detail + +template <size_t len, typename T> +class FixedSizeFunction; + +#endif + +/** + A type similar to `std::function` that holds a callable object. + + Unlike `std::function`, the callable object will always be stored in + a buffer of size `len` that is internal to the FixedSizeFunction instance. + This in turn means that creating a FixedSizeFunction instance will never allocate, + making FixedSizeFunctions suitable for use in realtime contexts. + + @tags{DSP} +*/ +template <size_t len, typename Ret, typename... Args> +class FixedSizeFunction<len, Ret (Args...)> +{ +private: + using Storage = typename std::aligned_storage<len>::type; + + template <typename Item> + using Decay = typename std::decay<Item>::type; + + template <typename Item, typename Fn = Decay<Item>> + using IntIfValidConversion = typename std::enable_if<sizeof (Fn) <= len + && alignof (Fn) <= alignof (Storage) + && ! std::is_same<FixedSizeFunction, Fn>::value, + int>::type; + +public: + /** Create an empty function. */ + FixedSizeFunction() noexcept = default; + + /** Create an empty function. */ + FixedSizeFunction (std::nullptr_t) noexcept + : FixedSizeFunction() {} + + FixedSizeFunction (const FixedSizeFunction&) = delete; + + /** Forwards the passed Callable into the internal storage buffer. */ + template <typename Callable, + typename Fn = Decay<Callable>, + IntIfValidConversion<Callable> = 0> + FixedSizeFunction (Callable&& callable) + { + static_assert (sizeof (Fn) <= len, + "The requested function cannot fit in this FixedSizeFunction"); + static_assert (alignof (Fn) <= alignof (Storage), + "FixedSizeFunction cannot accommodate the requested alignment requirements"); + + static constexpr auto vtableForCallable = detail::makeVtable<Fn, Ret, Args...>(); + vtable = &vtableForCallable; + + auto* ptr = new (&storage) Fn (std::forward<Callable> (callable)); + jassert ((void*) ptr == (void*) &storage); + juce::ignoreUnused (ptr); + } + + /** Move constructor. */ + FixedSizeFunction (FixedSizeFunction&& other) noexcept + : vtable (other.vtable) + { + move (std::move (other)); + } + + /** Converting constructor from smaller FixedSizeFunctions. */ + template <size_t otherLen, typename std::enable_if<(otherLen < len), int>::type = 0> + FixedSizeFunction (FixedSizeFunction<otherLen, Ret (Args...)>&& other) noexcept + : vtable (other.vtable) + { + move (std::move (other)); + } + + /** Nulls this instance. */ + FixedSizeFunction& operator= (std::nullptr_t) noexcept + { + return *this = FixedSizeFunction(); + } + + FixedSizeFunction& operator= (const FixedSizeFunction&) = delete; + + /** Assigns a new callable to this instance. */ + template <typename Callable, IntIfValidConversion<Callable> = 0> + FixedSizeFunction& operator= (Callable&& callable) + { + return *this = FixedSizeFunction (std::forward<Callable> (callable)); + } + + /** Move assignment from smaller FixedSizeFunctions. */ + template <size_t otherLen, typename std::enable_if<(otherLen < len), int>::type = 0> + FixedSizeFunction& operator= (FixedSizeFunction<otherLen, Ret (Args...)>&& other) noexcept + { + return *this = FixedSizeFunction (std::move (other)); + } + + /** Move assignment operator. */ + FixedSizeFunction& operator= (FixedSizeFunction&& other) noexcept + { + clear(); + vtable = other.vtable; + move (std::move (other)); + return *this; + } + + /** Destructor. */ + ~FixedSizeFunction() noexcept { clear(); } + + /** If this instance is currently storing a callable object, calls that object, + otherwise throws `std::bad_function_call`. + */ + Ret operator() (Args... args) const + { + if (vtable != nullptr) + return vtable->call (&storage, std::forward<Args> (args)...); + + throw std::bad_function_call(); + } + + /** Returns true if this instance currently holds a callable. */ + explicit operator bool() const noexcept { return vtable != nullptr; } + +private: + template <size_t, typename> + friend class FixedSizeFunction; + + void clear() noexcept + { + if (vtable != nullptr) + vtable->clear (&storage); + } + + template <size_t otherLen, typename T> + void move (FixedSizeFunction<otherLen, T>&& other) noexcept + { + if (vtable != nullptr) + vtable->move (&other.storage, &storage); + } + + const detail::Vtable<Ret, Args...>* vtable = nullptr; + mutable Storage storage; +}; + +template <size_t len, typename T> +bool operator!= (const FixedSizeFunction<len, T>& fn, std::nullptr_t) { return bool (fn); } + +template <size_t len, typename T> +bool operator!= (std::nullptr_t, const FixedSizeFunction<len, T>& fn) { return bool (fn); } + +template <size_t len, typename T> +bool operator== (const FixedSizeFunction<len, T>& fn, std::nullptr_t) { return ! (fn != nullptr); } + +template <size_t len, typename T> +bool operator== (std::nullptr_t, const FixedSizeFunction<len, T>& fn) { return ! (fn != nullptr); } + + +} +} diff --git a/modules/juce_dsp/containers/juce_FixedSizeFunction_test.cpp b/modules/juce_dsp/containers/juce_FixedSizeFunction_test.cpp new file mode 100644 index 00000000..e0b7ac43 --- /dev/null +++ b/modules/juce_dsp/containers/juce_FixedSizeFunction_test.cpp @@ -0,0 +1,352 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +#if JUCE_ENABLE_ALLOCATION_HOOKS +#define JUCE_FAIL_ON_ALLOCATION_IN_SCOPE const UnitTestAllocationChecker checker (*this) +#else +#define JUCE_FAIL_ON_ALLOCATION_IN_SCOPE +#endif + +namespace juce +{ +namespace dsp +{ +namespace +{ + +class ConstructCounts +{ + auto tie() const noexcept { return std::tie (constructions, copies, moves, calls, destructions); } + +public: + int constructions = 0; + int copies = 0; + int moves = 0; + int calls = 0; + int destructions = 0; + + ConstructCounts withConstructions (int i) const noexcept { auto c = *this; c.constructions = i; return c; } + ConstructCounts withCopies (int i) const noexcept { auto c = *this; c.copies = i; return c; } + ConstructCounts withMoves (int i) const noexcept { auto c = *this; c.moves = i; return c; } + ConstructCounts withCalls (int i) const noexcept { auto c = *this; c.calls = i; return c; } + ConstructCounts withDestructions (int i) const noexcept { auto c = *this; c.destructions = i; return c; } + + bool operator== (const ConstructCounts& other) const noexcept { return tie() == other.tie(); } + bool operator!= (const ConstructCounts& other) const noexcept { return tie() != other.tie(); } +}; + +String& operator<< (String& str, const ConstructCounts& c) +{ + return str << "{ constructions: " << c.constructions + << ", copies: " << c.copies + << ", moves: " << c.moves + << ", calls: " << c.calls + << ", destructions: " << c.destructions + << " }"; +} + +class FixedSizeFunctionTest : public UnitTest +{ + static void toggleBool (bool& b) { b = ! b; } + + struct ConstructCounter + { + explicit ConstructCounter (ConstructCounts& countsIn) + : counts (countsIn) {} + + ConstructCounter (const ConstructCounter& c) + : counts (c.counts) + { + counts.copies += 1; + } + + ConstructCounter (ConstructCounter&& c) noexcept + : counts (c.counts) + { + counts.moves += 1; + } + + ~ConstructCounter() noexcept { counts.destructions += 1; } + + void operator()() const noexcept { counts.calls += 1; } + + ConstructCounts& counts; + }; + +public: + FixedSizeFunctionTest() + : UnitTest ("Fixed Size Function", UnitTestCategories::dsp) + {} + + void runTest() override + { + beginTest ("Can be constructed and called from a lambda"); + { + JUCE_FAIL_ON_ALLOCATION_IN_SCOPE; + + const auto result = 5; + bool wasCalled = false; + const auto lambda = [&] { wasCalled = true; return result; }; + + const FixedSizeFunction<sizeof (lambda), int()> fn (lambda); + const auto out = fn(); + + expect (wasCalled); + expectEquals (result, out); + } + + beginTest ("void fn can be constructed from function with return value"); + { + JUCE_FAIL_ON_ALLOCATION_IN_SCOPE; + + bool wasCalled = false; + const auto lambda = [&] { wasCalled = true; return 5; }; + const FixedSizeFunction<sizeof (lambda), void()> fn (lambda); + + fn(); + expect (wasCalled); + } + + beginTest ("Can be constructed and called from a function pointer"); + { + JUCE_FAIL_ON_ALLOCATION_IN_SCOPE; + + bool state = false; + + const FixedSizeFunction<sizeof (void*), void (bool&)> fn (toggleBool); + + fn (state); + expect (state); + + fn (state); + expect (! state); + + fn (state); + expect (state); + } + + beginTest ("Default constructed functions throw if called"); + { + const auto a = FixedSizeFunction<8, void()>(); + expectThrowsType (a(), std::bad_function_call) + + const auto b = FixedSizeFunction<8, void()> (nullptr); + expectThrowsType (b(), std::bad_function_call) + } + + beginTest ("Functions can be moved"); + { + JUCE_FAIL_ON_ALLOCATION_IN_SCOPE; + + ConstructCounts counts; + + auto a = FixedSizeFunction<sizeof (ConstructCounter), void()> (ConstructCounter { counts }); + expectEquals (counts, ConstructCounts().withMoves (1).withDestructions (1)); // The temporary gets destroyed + + a(); + expectEquals (counts, ConstructCounts().withMoves (1).withDestructions (1).withCalls (1)); + + const auto b = std::move (a); + expectEquals (counts, ConstructCounts().withMoves (2).withDestructions (1).withCalls (1)); + + b(); + expectEquals (counts, ConstructCounts().withMoves (2).withDestructions (1).withCalls (2)); + + b(); + expectEquals (counts, ConstructCounts().withMoves (2).withDestructions (1).withCalls (3)); + } + + beginTest ("Functions are destructed properly"); + { + JUCE_FAIL_ON_ALLOCATION_IN_SCOPE; + + ConstructCounts counts; + const ConstructCounter toCopy { counts }; + + { + auto a = FixedSizeFunction<sizeof (ConstructCounter), void()> (toCopy); + expectEquals (counts, ConstructCounts().withCopies (1)); + } + + expectEquals (counts, ConstructCounts().withCopies (1).withDestructions (1)); + } + + beginTest ("Avoid destructing functions that fail to construct"); + { + struct BadConstructor + { + explicit BadConstructor (ConstructCounts& c) + : counts (c) + { + counts.constructions += 1; + throw std::runtime_error { "this was meant to happen" }; + } + + ~BadConstructor() noexcept { counts.destructions += 1; } + + void operator()() const noexcept { counts.calls += 1; } + + ConstructCounts& counts; + }; + + ConstructCounts counts; + + expectThrowsType ((FixedSizeFunction<sizeof (BadConstructor), void()> (BadConstructor { counts })), + std::runtime_error) + + expectEquals (counts, ConstructCounts().withConstructions (1)); + } + + beginTest ("Equality checks work"); + { + JUCE_FAIL_ON_ALLOCATION_IN_SCOPE; + + FixedSizeFunction<8, void()> a; + expect (! bool (a)); + expect (a == nullptr); + expect (nullptr == a); + expect (! (a != nullptr)); + expect (! (nullptr != a)); + + FixedSizeFunction<8, void()> b ([] {}); + expect (bool (b)); + expect (b != nullptr); + expect (nullptr != b); + expect (! (b == nullptr)); + expect (! (nullptr == b)); + } + + beginTest ("Functions can be cleared"); + { + JUCE_FAIL_ON_ALLOCATION_IN_SCOPE; + + FixedSizeFunction<8, void()> fn ([] {}); + expect (bool (fn)); + + fn = nullptr; + expect (! bool (fn)); + } + + beginTest ("Functions can be assigned"); + { + JUCE_FAIL_ON_ALLOCATION_IN_SCOPE; + + using Fn = FixedSizeFunction<8, void()>; + + int numCallsA = 0; + int numCallsB = 0; + + Fn x; + Fn y; + expect (! bool (x)); + expect (! bool (y)); + + x = [&] { numCallsA += 1; }; + y = [&] { numCallsB += 1; }; + expect (bool (x)); + expect (bool (y)); + + x(); + expectEquals (numCallsA, 1); + expectEquals (numCallsB, 0); + + y(); + expectEquals (numCallsA, 1); + expectEquals (numCallsB, 1); + + x = std::move (y); + expectEquals (numCallsA, 1); + expectEquals (numCallsB, 1); + + x(); + expectEquals (numCallsA, 1); + expectEquals (numCallsB, 2); + } + + beginTest ("Functions may mutate internal state"); + { + JUCE_FAIL_ON_ALLOCATION_IN_SCOPE; + + using Fn = FixedSizeFunction<64, void()>; + + Fn x; + expect (! bool (x)); + + int numCalls = 0; + x = [&numCalls, counter = 0]() mutable { counter += 1; numCalls = counter; }; + expect (bool (x)); + + expectEquals (numCalls, 0); + + x(); + expectEquals (numCalls, 1); + + x(); + expectEquals (numCalls, 2); + } + + beginTest ("Functions can sink move-only parameters"); + { + JUCE_FAIL_ON_ALLOCATION_IN_SCOPE; + + using Fn = FixedSizeFunction<64, int (std::unique_ptr<int>)>; + + auto value = 5; + auto ptr = std::make_unique<int> (value); + + Fn fn = [] (std::unique_ptr<int> p) { return *p; }; + + expect (value == fn (std::move (ptr))); + } + + beginTest ("Functions be converted from smaller functions"); + { + JUCE_FAIL_ON_ALLOCATION_IN_SCOPE; + + using SmallFn = FixedSizeFunction<20, void()>; + using LargeFn = FixedSizeFunction<21, void()>; + + bool smallCalled = false; + bool largeCalled = false; + + SmallFn small = [&smallCalled, a = std::array<char, 8>{}] { smallCalled = true; juce::ignoreUnused (a); }; + LargeFn large = [&largeCalled, a = std::array<char, 8>{}] { largeCalled = true; juce::ignoreUnused (a); }; + + large = std::move (small); + + large(); + + expect (smallCalled); + expect (! largeCalled); + } + } +}; + +FixedSizeFunctionTest fixedSizedFunctionTest; + +} +} +} +#undef JUCE_FAIL_ON_ALLOCATION_IN_SCOPE diff --git a/modules/juce_dsp/containers/juce_SIMDRegister.h b/modules/juce_dsp/containers/juce_SIMDRegister.h index 9cf82588..ea71c4ff 100644 --- a/modules/juce_dsp/containers/juce_SIMDRegister.h +++ b/modules/juce_dsp/containers/juce_SIMDRegister.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -127,14 +126,14 @@ struct SIMDRegister //============================================================================== /** Creates a new SIMDRegister from the corresponding scalar primitive. The scalar is extended to all elements of the vector. */ - inline static SIMDRegister JUCE_VECTOR_CALLTYPE expand (ElementType s) noexcept { return {CmplxOps::expand (s)}; } + static SIMDRegister JUCE_VECTOR_CALLTYPE expand (ElementType s) noexcept { return {CmplxOps::expand (s)}; } /** Creates a new SIMDRegister from the internal SIMD type (for example __mm128 for single-precision floating point on SSE architectures). */ - inline static SIMDRegister JUCE_VECTOR_CALLTYPE fromNative (vSIMDType a) noexcept { return {a}; } + static SIMDRegister JUCE_VECTOR_CALLTYPE fromNative (vSIMDType a) noexcept { return {a}; } /** Creates a new SIMDRegister from the first SIMDNumElements of a scalar array. */ - inline static SIMDRegister JUCE_VECTOR_CALLTYPE fromRawArray (const ElementType* a) noexcept + static SIMDRegister JUCE_VECTOR_CALLTYPE fromRawArray (const ElementType* a) noexcept { jassert (isSIMDAligned (a)); return {CmplxOps::load (a)}; @@ -283,43 +282,43 @@ struct SIMDRegister /** Returns a SIMDRegister of the corresponding integral type where each element has each bit set if the corresponding element of a is equal to the corresponding element of b, or zero otherwise. The result can then be used in bit operations defined above to avoid branches in vector SIMD code. */ - static inline vMaskType JUCE_VECTOR_CALLTYPE equal (SIMDRegister a, SIMDRegister b) noexcept { return toMaskType (NativeOps::equal (a.value, b.value)); } + static vMaskType JUCE_VECTOR_CALLTYPE equal (SIMDRegister a, SIMDRegister b) noexcept { return toMaskType (NativeOps::equal (a.value, b.value)); } /** Returns a SIMDRegister of the corresponding integral type where each element has each bit set if the corresponding element of a is not equal to the corresponding element of b, or zero otherwise. The result can then be used in bit operations defined above to avoid branches in vector SIMD code. */ - static inline vMaskType JUCE_VECTOR_CALLTYPE notEqual (SIMDRegister a, SIMDRegister b) noexcept { return toMaskType (NativeOps::notEqual (a.value, b.value)); } + static vMaskType JUCE_VECTOR_CALLTYPE notEqual (SIMDRegister a, SIMDRegister b) noexcept { return toMaskType (NativeOps::notEqual (a.value, b.value)); } /** Returns a SIMDRegister of the corresponding integral type where each element has each bit set if the corresponding element of a is less than to the corresponding element of b, or zero otherwise. The result can then be used in bit operations defined above to avoid branches in vector SIMD code. */ - static inline vMaskType JUCE_VECTOR_CALLTYPE lessThan (SIMDRegister a, SIMDRegister b) noexcept { return toMaskType (NativeOps::greaterThan (b.value, a.value)); } + static vMaskType JUCE_VECTOR_CALLTYPE lessThan (SIMDRegister a, SIMDRegister b) noexcept { return toMaskType (NativeOps::greaterThan (b.value, a.value)); } /** Returns a SIMDRegister of the corresponding integral type where each element has each bit set if the corresponding element of a is than or equal to the corresponding element of b, or zero otherwise. The result can then be used in bit operations defined above to avoid branches in vector SIMD code. */ - static inline vMaskType JUCE_VECTOR_CALLTYPE lessThanOrEqual (SIMDRegister a, SIMDRegister b) noexcept { return toMaskType (NativeOps::greaterThanOrEqual (b.value, a.value)); } + static vMaskType JUCE_VECTOR_CALLTYPE lessThanOrEqual (SIMDRegister a, SIMDRegister b) noexcept { return toMaskType (NativeOps::greaterThanOrEqual (b.value, a.value)); } /** Returns a SIMDRegister of the corresponding integral type where each element has each bit set if the corresponding element of a is greater than to the corresponding element of b, or zero otherwise. The result can then be used in bit operations defined above to avoid branches in vector SIMD code. */ - static inline vMaskType JUCE_VECTOR_CALLTYPE greaterThan (SIMDRegister a, SIMDRegister b) noexcept { return toMaskType (NativeOps::greaterThan (a.value, b.value)); } + static vMaskType JUCE_VECTOR_CALLTYPE greaterThan (SIMDRegister a, SIMDRegister b) noexcept { return toMaskType (NativeOps::greaterThan (a.value, b.value)); } /** Returns a SIMDRegister of the corresponding integral type where each element has each bit set if the corresponding element of a is greater than or equal to the corresponding element of b, or zero otherwise. The result can then be used in bit operations defined above to avoid branches in vector SIMD code. */ - static inline vMaskType JUCE_VECTOR_CALLTYPE greaterThanOrEqual (SIMDRegister a, SIMDRegister b) noexcept { return toMaskType (NativeOps::greaterThanOrEqual (a.value, b.value)); } + static vMaskType JUCE_VECTOR_CALLTYPE greaterThanOrEqual (SIMDRegister a, SIMDRegister b) noexcept { return toMaskType (NativeOps::greaterThanOrEqual (a.value, b.value)); } //============================================================================== /** Returns a new vector where each element is the minimum of the corresponding element of a and b. */ - static inline SIMDRegister JUCE_VECTOR_CALLTYPE min (SIMDRegister a, SIMDRegister b) noexcept { return { NativeOps::min (a.value, b.value) }; } + static SIMDRegister JUCE_VECTOR_CALLTYPE min (SIMDRegister a, SIMDRegister b) noexcept { return { NativeOps::min (a.value, b.value) }; } /** Returns a new vector where each element is the maximum of the corresponding element of a and b. */ - static inline SIMDRegister JUCE_VECTOR_CALLTYPE max (SIMDRegister a, SIMDRegister b) noexcept { return { NativeOps::max (a.value, b.value) }; } + static SIMDRegister JUCE_VECTOR_CALLTYPE max (SIMDRegister a, SIMDRegister b) noexcept { return { NativeOps::max (a.value, b.value) }; } //============================================================================== /** Multiplies b and c and adds the result to a. */ - static inline SIMDRegister JUCE_VECTOR_CALLTYPE multiplyAdd (SIMDRegister a, const SIMDRegister b, SIMDRegister c) noexcept + static SIMDRegister JUCE_VECTOR_CALLTYPE multiplyAdd (SIMDRegister a, const SIMDRegister b, SIMDRegister c) noexcept { return { CmplxOps::muladd (a.value, b.value, c.value) }; } @@ -331,18 +330,18 @@ struct SIMDRegister //============================================================================== /** Truncates each element to its integer part. Effectively discards the fractional part of each element. A.k.a. round to zero. */ - static inline SIMDRegister JUCE_VECTOR_CALLTYPE truncate (SIMDRegister a) noexcept { return { NativeOps::truncate (a.value) }; } + static SIMDRegister JUCE_VECTOR_CALLTYPE truncate (SIMDRegister a) noexcept { return { NativeOps::truncate (a.value) }; } //============================================================================== /** Returns the absolute value of each element. */ - static inline SIMDRegister JUCE_VECTOR_CALLTYPE abs (SIMDRegister a) noexcept + static SIMDRegister JUCE_VECTOR_CALLTYPE abs (SIMDRegister a) noexcept { return a - (a * (expand (ElementType (2)) & lessThan (a, expand (ElementType (0))))); } //============================================================================== /** Checks if the given pointer is sufficiently aligned for using SIMD operations. */ - static inline bool isSIMDAligned (const ElementType* ptr) noexcept + static bool isSIMDAligned (const ElementType* ptr) noexcept { uintptr_t bitmask = SIMDRegisterSize - 1; return (reinterpret_cast<uintptr_t> (ptr) & bitmask) == 0; @@ -353,13 +352,13 @@ struct SIMDRegister If the current position in memory is already aligned then this method will simply return the pointer. */ - static inline ElementType* getNextSIMDAlignedPtr (ElementType* ptr) noexcept + static ElementType* getNextSIMDAlignedPtr (ElementType* ptr) noexcept { return snapPointerToAlignment (ptr, SIMDRegisterSize); } private: - static inline vMaskType JUCE_VECTOR_CALLTYPE toMaskType (vSIMDType a) noexcept + static vMaskType JUCE_VECTOR_CALLTYPE toMaskType (vSIMDType a) noexcept { union { @@ -371,7 +370,7 @@ private: return vMaskType::fromNative (u.out); } - static inline vSIMDType JUCE_VECTOR_CALLTYPE toVecType (vMaskSIMDType a) noexcept + static vSIMDType JUCE_VECTOR_CALLTYPE toVecType (vMaskSIMDType a) noexcept { union { @@ -383,7 +382,7 @@ private: return u.out; } - static inline vSIMDType JUCE_VECTOR_CALLTYPE toVecType (MaskType a) noexcept + static vSIMDType JUCE_VECTOR_CALLTYPE toVecType (MaskType a) noexcept { union { diff --git a/modules/juce_dsp/containers/juce_SIMDRegister_Impl.h b/modules/juce_dsp/containers/juce_SIMDRegister_Impl.h index fb6a75e4..8b0d1a1b 100644 --- a/modules/juce_dsp/containers/juce_SIMDRegister_Impl.h +++ b/modules/juce_dsp/containers/juce_SIMDRegister_Impl.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -56,42 +55,42 @@ struct CmplxSIMDOps { using vSIMDType = typename SIMDNativeOps<Scalar>::vSIMDType; - static inline vSIMDType JUCE_VECTOR_CALLTYPE load (const Scalar* a) noexcept + static vSIMDType JUCE_VECTOR_CALLTYPE load (const Scalar* a) noexcept { return SIMDNativeOps<Scalar>::load (a); } - static inline void JUCE_VECTOR_CALLTYPE store (vSIMDType value, Scalar* dest) noexcept + static void JUCE_VECTOR_CALLTYPE store (vSIMDType value, Scalar* dest) noexcept { SIMDNativeOps<Scalar>::store (value, dest); } - static inline vSIMDType JUCE_VECTOR_CALLTYPE expand (Scalar s) noexcept + static vSIMDType JUCE_VECTOR_CALLTYPE expand (Scalar s) noexcept { return SIMDNativeOps<Scalar>::expand (s); } - static inline Scalar JUCE_VECTOR_CALLTYPE get (vSIMDType v, std::size_t i) noexcept + static Scalar JUCE_VECTOR_CALLTYPE get (vSIMDType v, std::size_t i) noexcept { return SIMDNativeOps<Scalar>::get (v, i); } - static inline vSIMDType JUCE_VECTOR_CALLTYPE set (vSIMDType v, std::size_t i, Scalar s) noexcept + static vSIMDType JUCE_VECTOR_CALLTYPE set (vSIMDType v, std::size_t i, Scalar s) noexcept { return SIMDNativeOps<Scalar>::set (v, i, s); } - static inline Scalar JUCE_VECTOR_CALLTYPE sum (vSIMDType a) noexcept + static Scalar JUCE_VECTOR_CALLTYPE sum (vSIMDType a) noexcept { return SIMDNativeOps<Scalar>::sum (a); } - static inline vSIMDType JUCE_VECTOR_CALLTYPE mul (vSIMDType a, vSIMDType b) noexcept + static vSIMDType JUCE_VECTOR_CALLTYPE mul (vSIMDType a, vSIMDType b) noexcept { return SIMDNativeOps<Scalar>::mul (a, b); } - static inline vSIMDType JUCE_VECTOR_CALLTYPE muladd (vSIMDType a, vSIMDType b, vSIMDType c) noexcept + static vSIMDType JUCE_VECTOR_CALLTYPE muladd (vSIMDType a, vSIMDType b, vSIMDType c) noexcept { return SIMDNativeOps<Scalar>::multiplyAdd (a, b, c); } @@ -103,17 +102,17 @@ struct CmplxSIMDOps<std::complex<Scalar>> { using vSIMDType = typename SIMDNativeOps<Scalar>::vSIMDType; - static inline vSIMDType JUCE_VECTOR_CALLTYPE load (const std::complex<Scalar>* a) noexcept + static vSIMDType JUCE_VECTOR_CALLTYPE load (const std::complex<Scalar>* a) noexcept { return SIMDNativeOps<Scalar>::load (reinterpret_cast<const Scalar*> (a)); } - static inline void JUCE_VECTOR_CALLTYPE store (vSIMDType value, std::complex<Scalar>* dest) noexcept + static void JUCE_VECTOR_CALLTYPE store (vSIMDType value, std::complex<Scalar>* dest) noexcept { SIMDNativeOps<Scalar>::store (value, reinterpret_cast<Scalar*> (dest)); } - static inline vSIMDType JUCE_VECTOR_CALLTYPE expand (std::complex<Scalar> s) noexcept + static vSIMDType JUCE_VECTOR_CALLTYPE expand (std::complex<Scalar> s) noexcept { const int n = sizeof (vSIMDType) / sizeof (Scalar); @@ -129,31 +128,31 @@ struct CmplxSIMDOps<std::complex<Scalar>> return u.v; } - static inline std::complex<Scalar> JUCE_VECTOR_CALLTYPE get (vSIMDType v, std::size_t i) noexcept + static std::complex<Scalar> JUCE_VECTOR_CALLTYPE get (vSIMDType v, std::size_t i) noexcept { auto j = i << 1; return std::complex<Scalar> (SIMDNativeOps<Scalar>::get (v, j), SIMDNativeOps<Scalar>::get (v, j + 1)); } - static inline vSIMDType JUCE_VECTOR_CALLTYPE set (vSIMDType v, std::size_t i, std::complex<Scalar> s) noexcept + static vSIMDType JUCE_VECTOR_CALLTYPE set (vSIMDType v, std::size_t i, std::complex<Scalar> s) noexcept { auto j = i << 1; return SIMDNativeOps<Scalar>::set (SIMDNativeOps<Scalar>::set (v, j, s.real()), j + 1, s.imag()); } - static inline std::complex<Scalar> JUCE_VECTOR_CALLTYPE sum (vSIMDType a) noexcept + static std::complex<Scalar> JUCE_VECTOR_CALLTYPE sum (vSIMDType a) noexcept { vSIMDType result = SIMDNativeOps<Scalar>::oddevensum (a); auto* ptr = reinterpret_cast<const Scalar*> (&result); return std::complex<Scalar> (ptr[0], ptr[1]); } - static inline vSIMDType JUCE_VECTOR_CALLTYPE mul (vSIMDType a, vSIMDType b) noexcept + static vSIMDType JUCE_VECTOR_CALLTYPE mul (vSIMDType a, vSIMDType b) noexcept { return SIMDNativeOps<Scalar>::cmplxmul (a, b); } - static inline vSIMDType JUCE_VECTOR_CALLTYPE muladd (vSIMDType a, vSIMDType b, vSIMDType c) noexcept + static vSIMDType JUCE_VECTOR_CALLTYPE muladd (vSIMDType a, vSIMDType b, vSIMDType c) noexcept { return SIMDNativeOps<Scalar>::add (a, SIMDNativeOps<Scalar>::cmplxmul (b, c)); } diff --git a/modules/juce_dsp/containers/juce_SIMDRegister_test.cpp b/modules/juce_dsp/containers/juce_SIMDRegister_test.cpp index ea2b4fa9..1e26f7fe 100644 --- a/modules/juce_dsp/containers/juce_SIMDRegister_test.cpp +++ b/modules/juce_dsp/containers/juce_SIMDRegister_test.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -751,7 +750,7 @@ public: copy (a, inArray); a = SIMDRegister<type>::abs (a); - auto calcAbs = [] (type x) -> type { return x >= type (0) ? x : -x; }; + auto calcAbs = [] (type x) -> type { return x >= type (0) ? x : type (-x); }; for (size_t j = 0; j < SIMDRegister<type>::SIMDNumElements; ++j) outArray[j] = calcAbs (inArray[j]); diff --git a/modules/juce_dsp/filter_design/juce_FilterDesign.cpp b/modules/juce_dsp/filter_design/juce_FilterDesign.cpp index dd323bb8..f1acc87a 100644 --- a/modules/juce_dsp/filter_design/juce_FilterDesign.cpp +++ b/modules/juce_dsp/filter_design/juce_FilterDesign.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -46,7 +45,7 @@ typename FIR::Coefficients<FloatType>::Ptr for (size_t i = 0; i <= order; ++i) { - if (i == order * 0.5) + if (i == order / 2) { c[i] = static_cast<FloatType> (normalisedFrequency * 2); } @@ -114,8 +113,8 @@ typename FIR::Coefficients<FloatType>::Ptr } else { - auto indice = MathConstants<double>::pi * (i - 0.5 * order); - auto indice2 = MathConstants<double>::pi * normalisedTransitionWidth * (i - 0.5 * order) / spline; + auto indice = MathConstants<double>::pi * ((double) i - 0.5 * (double) order); + auto indice2 = MathConstants<double>::pi * normalisedTransitionWidth * ((double) i - 0.5 * (double) order) / spline; c[i] = static_cast<FloatType> (std::sin (2 * indice * normalisedFrequency) / indice * std::pow (std::sin (indice2) / indice2, spline)); } @@ -154,19 +153,19 @@ typename FIR::Coefficients<FloatType>::Ptr Matrix<double> b (M + 1, 1), q (2 * M + 1, 1); - auto sinc = [](double x) { return x == 0 ? 1 : std::sin (x * MathConstants<double>::pi) - / (MathConstants<double>::pi * x); }; + auto sinc = [] (double x) { return x == 0 ? 1 : std::sin (x * MathConstants<double>::pi) + / (MathConstants<double>::pi * x); }; auto factorp = wp / MathConstants<double>::pi; auto factors = ws / MathConstants<double>::pi; for (size_t i = 0; i <= M; ++i) - b (i, 0) = factorp * sinc (factorp * i); + b (i, 0) = factorp * sinc (factorp * (double) i); q (0, 0) = factorp + stopBandWeight * (1.0 - factors); for (size_t i = 1; i <= 2 * M; ++i) - q (i, 0) = factorp * sinc (factorp * i) - stopBandWeight * factors * sinc (factors * i); + q (i, 0) = factorp * sinc (factorp * (double) i) - stopBandWeight * factors * sinc (factors * (double) i); auto Q1 = Matrix<double>::toeplitz (q, M + 1); auto Q2 = Matrix<double>::hankel (q, M + 1, 0); @@ -192,19 +191,19 @@ typename FIR::Coefficients<FloatType>::Ptr Matrix<double> qp (2 * M, 1); Matrix<double> qs (2 * M, 1); - auto sinc = [](double x) { return x == 0 ? 1 : std::sin (x * MathConstants<double>::pi) - / (MathConstants<double>::pi * x); }; + auto sinc = [] (double x) { return x == 0 ? 1 : std::sin (x * MathConstants<double>::pi) + / (MathConstants<double>::pi * x); }; auto factorp = wp / MathConstants<double>::pi; auto factors = ws / MathConstants<double>::pi; for (size_t i = 0; i < M; ++i) - b (i, 0) = factorp * sinc (factorp * (i + 0.5)); + b (i, 0) = factorp * sinc (factorp * ((double) i + 0.5)); for (size_t i = 0; i < 2 * M; ++i) { - qp (i, 0) = 0.25 * factorp * sinc (factorp * i); - qs (i, 0) = -0.25 * stopBandWeight * factors * sinc (factors * i); + qp (i, 0) = 0.25 * factorp * sinc (factorp * (double) i); + qs (i, 0) = -0.25 * stopBandWeight * factors * sinc (factors * (double) i); } auto Q1p = Matrix<double>::toeplitz (qp, M); @@ -553,7 +552,7 @@ ReferenceCountedArray<IIR::Coefficients<FloatType>> { arrayFilters.add (*IIR::Coefficients<FloatType>::makeFirstOrderLowPass (sampleRate, frequency)); - for (auto i = 0; i < order / 2; ++i) + for (int i = 0; i < order / 2; ++i) { auto Q = 1.0 / (2.0 * std::cos ((i + 1.0) * MathConstants<double>::pi / order)); arrayFilters.add (*IIR::Coefficients<FloatType>::makeLowPass (sampleRate, frequency, @@ -562,7 +561,7 @@ ReferenceCountedArray<IIR::Coefficients<FloatType>> } else { - for (auto i = 0; i < order / 2; ++i) + for (int i = 0; i < order / 2; ++i) { auto Q = 1.0 / (2.0 * std::cos ((2.0 * i + 1.0) * MathConstants<double>::pi / (order * 2.0))); arrayFilters.add (*IIR::Coefficients<FloatType>::makeLowPass (sampleRate, frequency, @@ -588,7 +587,7 @@ ReferenceCountedArray<IIR::Coefficients<FloatType>> { arrayFilters.add (*IIR::Coefficients<FloatType>::makeFirstOrderHighPass (sampleRate, frequency)); - for (auto i = 0; i < order / 2; ++i) + for (int i = 0; i < order / 2; ++i) { auto Q = 1.0 / (2.0 * std::cos ((i + 1.0) * MathConstants<double>::pi / order)); arrayFilters.add (*IIR::Coefficients<FloatType>::makeHighPass (sampleRate, frequency, @@ -597,7 +596,7 @@ ReferenceCountedArray<IIR::Coefficients<FloatType>> } else { - for (auto i = 0; i < order / 2; ++i) + for (int i = 0; i < order / 2; ++i) { auto Q = 1.0 / (2.0 * std::cos ((2.0 * i + 1.0) * MathConstants<double>::pi / (order * 2.0))); arrayFilters.add (*IIR::Coefficients<FloatType>::makeHighPass (sampleRate, frequency, diff --git a/modules/juce_dsp/filter_design/juce_FilterDesign.h b/modules/juce_dsp/filter_design/juce_FilterDesign.h index 28f8610b..0d659d24 100644 --- a/modules/juce_dsp/filter_design/juce_FilterDesign.h +++ b/modules/juce_dsp/filter_design/juce_FilterDesign.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_dsp/frequency/juce_Convolution.cpp b/modules/juce_dsp/frequency/juce_Convolution.cpp index 3288651c..42b6b6a4 100644 --- a/modules/juce_dsp/frequency/juce_Convolution.cpp +++ b/modules/juce_dsp/frequency/juce_Convolution.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -29,155 +28,183 @@ namespace juce namespace dsp { -/** This class is the convolution engine itself, processing only one channel at - a time of input signal. -*/ -struct ConvolutionEngine +template <typename Element> +class Queue { - ConvolutionEngine() = default; +public: + explicit Queue (int size) + : fifo (size), storage (static_cast<size_t> (size)) {} - //============================================================================== - struct ProcessingInformation + bool push (Element& element) noexcept { - enum class SourceType - { - sourceBinaryData, - sourceAudioFile, - sourceAudioBuffer, - sourceNone - }; + if (fifo.getFreeSpace() == 0) + return false; - SourceType sourceType = SourceType::sourceNone; + const auto writer = fifo.write (1); - const void* sourceData; - int sourceDataSize; - File fileImpulseResponse; + if (writer.blockSize1 != 0) + storage[static_cast<size_t> (writer.startIndex1)] = std::move (element); + else if (writer.blockSize2 != 0) + storage[static_cast<size_t> (writer.startIndex2)] = std::move (element); - double originalSampleRate; - int originalSize = 0; - int originalNumChannels = 1; + return true; + } - AudioBuffer<float>* buffer; + template <typename Fn> + void pop (Fn&& fn) { popN (1, std::forward<Fn> (fn)); } - bool wantsStereo = true; - bool wantsTrimming = true; - bool wantsNormalisation = true; - int64 wantedSize = 0; - int finalSize = 0; + template <typename Fn> + void popAll (Fn&& fn) { popN (fifo.getNumReady(), std::forward<Fn> (fn)); } - double sampleRate = 0; - size_t maximumBufferSize = 0; - }; + bool hasPendingMessages() const noexcept { return fifo.getNumReady() > 0; } - //============================================================================== - void reset() +private: + template <typename Fn> + void popN (int n, Fn&& fn) { - bufferInput.clear(); - bufferOverlap.clear(); - bufferTempOutput.clear(); + fifo.read (n).forEach ([&] (int index) + { + fn (storage[static_cast<size_t> (index)]); + }); + } - for (auto i = 0; i < buffersInputSegments.size(); ++i) - buffersInputSegments.getReference (i).clear(); + AbstractFifo fifo; + std::vector<Element> storage; +}; - currentSegment = 0; - inputDataPos = 0; - } +class BackgroundMessageQueue : private Thread +{ +public: + explicit BackgroundMessageQueue (int entries) + : Thread ("Convolution background loader"), queue (entries) + {} + + using IncomingCommand = FixedSizeFunction<400, void()>; - /** Initalize all the states and objects to perform the convolution. */ - void initializeConvolutionEngine (ProcessingInformation& info, int channel) + // Push functions here, and they'll be called later on a background thread. + // This function is wait-free. + // This function is only safe to call from a single thread at a time. + bool push (IncomingCommand& command) { return queue.push (command); } + + using Thread::startThread; + using Thread::stopThread; + +private: + void run() override { - blockSize = (size_t) nextPowerOfTwo ((int) info.maximumBufferSize); + while (! threadShouldExit()) + { + if (queue.hasPendingMessages()) + queue.pop ([] (IncomingCommand& command) { command(); command = nullptr;}); + else + sleep (10); + } + } - FFTSize = blockSize > 128 ? 2 * blockSize - : 4 * blockSize; + Queue<IncomingCommand> queue; - numSegments = ((size_t) info.finalSize) / (FFTSize - blockSize) + 1u; + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BackgroundMessageQueue) +}; - numInputSegments = (blockSize > 128 ? numSegments : 3 * numSegments); +struct ConvolutionMessageQueue::Impl : public BackgroundMessageQueue +{ + using BackgroundMessageQueue::BackgroundMessageQueue; +}; - FFTobject.reset (new FFT (roundToInt (std::log2 (FFTSize)))); +ConvolutionMessageQueue::ConvolutionMessageQueue() + : ConvolutionMessageQueue (1000) +{} - bufferInput.setSize (1, static_cast<int> (FFTSize)); - bufferOutput.setSize (1, static_cast<int> (FFTSize * 2)); - bufferTempOutput.setSize (1, static_cast<int> (FFTSize * 2)); - bufferOverlap.setSize (1, static_cast<int> (FFTSize)); +ConvolutionMessageQueue::ConvolutionMessageQueue (int entries) + : pimpl (std::make_unique<Impl> (entries)) +{ + pimpl->startThread(); +} + +ConvolutionMessageQueue::~ConvolutionMessageQueue() noexcept +{ + pimpl->stopThread (-1); +} + +ConvolutionMessageQueue::ConvolutionMessageQueue (ConvolutionMessageQueue&&) noexcept = default; +ConvolutionMessageQueue& ConvolutionMessageQueue::operator= (ConvolutionMessageQueue&&) noexcept = default; - buffersInputSegments.clear(); - buffersImpulseSegments.clear(); +//============================================================================== +struct ConvolutionEngine +{ + ConvolutionEngine (const float* samples, + size_t numSamples, + size_t maxBlockSize) + : blockSize ((size_t) nextPowerOfTwo ((int) maxBlockSize)), + fftSize (blockSize > 128 ? 2 * blockSize : 4 * blockSize), + fftObject (std::make_unique<FFT> (roundToInt (std::log2 (fftSize)))), + numSegments (numSamples / (fftSize - blockSize) + 1u), + numInputSegments ((blockSize > 128 ? numSegments : 3 * numSegments)), + bufferInput (1, static_cast<int> (fftSize)), + bufferOutput (1, static_cast<int> (fftSize * 2)), + bufferTempOutput (1, static_cast<int> (fftSize * 2)), + bufferOverlap (1, static_cast<int> (fftSize)) + { bufferOutput.clear(); - for (size_t i = 0; i < numInputSegments; ++i) + auto updateSegmentsIfNecessary = [this] (size_t numSegmentsToUpdate, + std::vector<AudioBuffer<float>>& segments) { - AudioBuffer<float> newInputSegment; - newInputSegment.setSize (1, static_cast<int> (FFTSize * 2)); - buffersInputSegments.add (newInputSegment); - } + if (numSegmentsToUpdate == 0 + || numSegmentsToUpdate != (size_t) segments.size() + || (size_t) segments[0].getNumSamples() != fftSize * 2) + { + segments.clear(); - for (auto i = 0u; i < numSegments; ++i) - { - AudioBuffer<float> newImpulseSegment; - newImpulseSegment.setSize (1, static_cast<int> (FFTSize * 2)); - buffersImpulseSegments.add (newImpulseSegment); - } + for (size_t i = 0; i < numSegmentsToUpdate; ++i) + segments.push_back ({ 1, static_cast<int> (fftSize * 2) }); + } + }; - std::unique_ptr<FFT> FFTTempObject (new FFT (roundToInt (std::log2 (FFTSize)))); + updateSegmentsIfNecessary (numInputSegments, buffersInputSegments); + updateSegmentsIfNecessary (numSegments, buffersImpulseSegments); - auto* channelData = info.buffer->getWritePointer (channel); + auto FFTTempObject = std::make_unique<FFT> (roundToInt (std::log2 (fftSize))); + size_t currentPtr = 0; - for (size_t n = 0; n < numSegments; ++n) + for (auto& buf : buffersImpulseSegments) { - buffersImpulseSegments.getReference (static_cast<int> (n)).clear(); + buf.clear(); - auto* impulseResponse = buffersImpulseSegments.getReference (static_cast<int> (n)).getWritePointer (0); + auto* impulseResponse = buf.getWritePointer (0); - if (n == 0) + if (&buf == &buffersImpulseSegments.front()) impulseResponse[0] = 1.0f; - for (size_t i = 0; i < FFTSize - blockSize; ++i) - if (i + n * (FFTSize - blockSize) < (size_t) info.finalSize) - impulseResponse[i] = channelData[i + n * (FFTSize - blockSize)]; + FloatVectorOperations::copy (impulseResponse, + samples + currentPtr, + static_cast<int> (jmin (fftSize - blockSize, numSamples - currentPtr))); FFTTempObject->performRealOnlyForwardTransform (impulseResponse); prepareForConvolution (impulseResponse); + + currentPtr += (fftSize - blockSize); } reset(); - - isReady = true; } - /** Copy the states of another engine. */ - void copyStateFromOtherEngine (const ConvolutionEngine& other) + void reset() { - if (FFTSize != other.FFTSize) - { - FFTobject.reset (new FFT (roundToInt (std::log2 (other.FFTSize)))); - FFTSize = other.FFTSize; - } - - currentSegment = other.currentSegment; - numInputSegments = other.numInputSegments; - numSegments = other.numSegments; - blockSize = other.blockSize; - inputDataPos = other.inputDataPos; - - bufferInput = other.bufferInput; - bufferTempOutput = other.bufferTempOutput; - bufferOutput = other.bufferOutput; + bufferInput.clear(); + bufferOverlap.clear(); + bufferTempOutput.clear(); + bufferOutput.clear(); - buffersInputSegments = other.buffersInputSegments; - buffersImpulseSegments = other.buffersImpulseSegments; - bufferOverlap = other.bufferOverlap; + for (auto& buf : buffersInputSegments) + buf.clear(); - isReady = true; + currentSegment = 0; + inputDataPos = 0; } - /** Performs the uniform partitioned convolution using FFT. */ void processSamples (const float* input, float* output, size_t numSamples) { - if (! isReady) - return; - // Overlap-add, zero latency convolution algorithm with uniform partitioning size_t numSamplesProcessed = 0; @@ -193,20 +220,18 @@ struct ConvolutionEngine const bool inputDataWasEmpty = (inputDataPos == 0); auto numSamplesToProcess = jmin (numSamples - numSamplesProcessed, blockSize - inputDataPos); - // copy the input samples FloatVectorOperations::copy (inputData + inputDataPos, input + numSamplesProcessed, static_cast<int> (numSamplesToProcess)); - auto* inputSegmentData = buffersInputSegments.getReference (static_cast<int> (currentSegment)).getWritePointer (0); - FloatVectorOperations::copy (inputSegmentData, inputData, static_cast<int> (FFTSize)); + auto* inputSegmentData = buffersInputSegments[currentSegment].getWritePointer (0); + FloatVectorOperations::copy (inputSegmentData, inputData, static_cast<int> (fftSize)); - // Forward FFT - FFTobject->performRealOnlyForwardTransform (inputSegmentData); + fftObject->performRealOnlyForwardTransform (inputSegmentData); prepareForConvolution (inputSegmentData); // Complex multiplication if (inputDataWasEmpty) { - FloatVectorOperations::fill (outputTempData, 0, static_cast<int> (FFTSize + 1)); + FloatVectorOperations::fill (outputTempData, 0, static_cast<int> (fftSize + 1)); auto index = currentSegment; @@ -217,25 +242,23 @@ struct ConvolutionEngine if (index >= numInputSegments) index -= numInputSegments; - convolutionProcessingAndAccumulate (buffersInputSegments.getReference (static_cast<int> (index)).getWritePointer (0), - buffersImpulseSegments.getReference (static_cast<int> (i)).getWritePointer (0), + convolutionProcessingAndAccumulate (buffersInputSegments[index].getWritePointer (0), + buffersImpulseSegments[i].getWritePointer (0), outputTempData); } } - FloatVectorOperations::copy (outputData, outputTempData, static_cast<int> (FFTSize + 1)); + FloatVectorOperations::copy (outputData, outputTempData, static_cast<int> (fftSize + 1)); - convolutionProcessingAndAccumulate (buffersInputSegments.getReference (static_cast<int> (currentSegment)).getWritePointer (0), - buffersImpulseSegments.getReference (0).getWritePointer (0), + convolutionProcessingAndAccumulate (inputSegmentData, + buffersImpulseSegments.front().getWritePointer (0), outputData); - // Inverse FFT updateSymmetricFrequencyDomainData (outputData); - FFTobject->performRealOnlyInverseTransform (outputData); + fftObject->performRealOnlyInverseTransform (outputData); // Add overlap - for (size_t i = 0; i < numSamplesToProcess; ++i) - output[i + numSamplesProcessed] = outputData[inputDataPos + i] + overlapData[inputDataPos + i]; + FloatVectorOperations::add (&output[numSamplesProcessed], &outputData[inputDataPos], &overlapData[inputDataPos], (int) numSamplesToProcess); // Input buffer full => Next block inputDataPos += numSamplesToProcess; @@ -243,17 +266,16 @@ struct ConvolutionEngine if (inputDataPos == blockSize) { // Input buffer is empty again now - FloatVectorOperations::fill (inputData, 0.0f, static_cast<int> (FFTSize)); + FloatVectorOperations::fill (inputData, 0.0f, static_cast<int> (fftSize)); inputDataPos = 0; // Extra step for segSize > blockSize - FloatVectorOperations::add (&(outputData[blockSize]), &(overlapData[blockSize]), static_cast<int> (FFTSize - 2 * blockSize)); + FloatVectorOperations::add (&(outputData[blockSize]), &(overlapData[blockSize]), static_cast<int> (fftSize - 2 * blockSize)); // Save the overlap - FloatVectorOperations::copy (overlapData, &(outputData[blockSize]), static_cast<int> (FFTSize - blockSize)); + FloatVectorOperations::copy (overlapData, &(outputData[blockSize]), static_cast<int> (fftSize - blockSize)); - // Update current segment currentSegment = (currentSegment > 0) ? (currentSegment - 1) : (numInputSegments - 1); } @@ -261,24 +283,102 @@ struct ConvolutionEngine } } - /** After each FFT, this function is called to allow convolution to be performed with only 4 SIMD functions calls. */ + void processSamplesWithAddedLatency (const float* input, float* output, size_t numSamples) + { + // Overlap-add, zero latency convolution algorithm with uniform partitioning + size_t numSamplesProcessed = 0; + + auto indexStep = numInputSegments / numSegments; + + auto* inputData = bufferInput.getWritePointer (0); + auto* outputTempData = bufferTempOutput.getWritePointer (0); + auto* outputData = bufferOutput.getWritePointer (0); + auto* overlapData = bufferOverlap.getWritePointer (0); + + while (numSamplesProcessed < numSamples) + { + auto numSamplesToProcess = jmin (numSamples - numSamplesProcessed, blockSize - inputDataPos); + + FloatVectorOperations::copy (inputData + inputDataPos, input + numSamplesProcessed, static_cast<int> (numSamplesToProcess)); + + FloatVectorOperations::copy (output + numSamplesProcessed, outputData + inputDataPos, static_cast<int> (numSamplesToProcess)); + + numSamplesProcessed += numSamplesToProcess; + inputDataPos += numSamplesToProcess; + + // processing itself when needed (with latency) + if (inputDataPos == blockSize) + { + // Copy input data in input segment + auto* inputSegmentData = buffersInputSegments[currentSegment].getWritePointer (0); + FloatVectorOperations::copy (inputSegmentData, inputData, static_cast<int> (fftSize)); + + fftObject->performRealOnlyForwardTransform (inputSegmentData); + prepareForConvolution (inputSegmentData); + + // Complex multiplication + FloatVectorOperations::fill (outputTempData, 0, static_cast<int> (fftSize + 1)); + + auto index = currentSegment; + + for (size_t i = 1; i < numSegments; ++i) + { + index += indexStep; + + if (index >= numInputSegments) + index -= numInputSegments; + + convolutionProcessingAndAccumulate (buffersInputSegments[index].getWritePointer (0), + buffersImpulseSegments[i].getWritePointer (0), + outputTempData); + } + + FloatVectorOperations::copy (outputData, outputTempData, static_cast<int> (fftSize + 1)); + + convolutionProcessingAndAccumulate (inputSegmentData, + buffersImpulseSegments.front().getWritePointer (0), + outputData); + + updateSymmetricFrequencyDomainData (outputData); + fftObject->performRealOnlyInverseTransform (outputData); + + // Add overlap + FloatVectorOperations::add (outputData, overlapData, static_cast<int> (blockSize)); + + // Input buffer is empty again now + FloatVectorOperations::fill (inputData, 0.0f, static_cast<int> (fftSize)); + + // Extra step for segSize > blockSize + FloatVectorOperations::add (&(outputData[blockSize]), &(overlapData[blockSize]), static_cast<int> (fftSize - 2 * blockSize)); + + // Save the overlap + FloatVectorOperations::copy (overlapData, &(outputData[blockSize]), static_cast<int> (fftSize - blockSize)); + + currentSegment = (currentSegment > 0) ? (currentSegment - 1) : (numInputSegments - 1); + + inputDataPos = 0; + } + } + } + + // After each FFT, this function is called to allow convolution to be performed with only 4 SIMD functions calls. void prepareForConvolution (float *samples) noexcept { - auto FFTSizeDiv2 = FFTSize / 2; + auto FFTSizeDiv2 = fftSize / 2; for (size_t i = 0; i < FFTSizeDiv2; i++) - samples[i] = samples[2 * i]; + samples[i] = samples[i << 1]; samples[FFTSizeDiv2] = 0; for (size_t i = 1; i < FFTSizeDiv2; i++) - samples[i + FFTSizeDiv2] = -samples[2 * (FFTSize - i) + 1]; + samples[i + FFTSizeDiv2] = -samples[((fftSize - i) << 1) + 1]; } - /** Does the convolution operation itself only on half of the frequency domain samples. */ + // Does the convolution operation itself only on half of the frequency domain samples. void convolutionProcessingAndAccumulate (const float *input, const float *impulse, float *output) { - auto FFTSizeDiv2 = FFTSize / 2; + auto FFTSizeDiv2 = fftSize / 2; FloatVectorOperations::addWithMultiply (output, input, impulse, static_cast<int> (FFTSizeDiv2)); FloatVectorOperations::subtractWithMultiply (output, &(input[FFTSizeDiv2]), &(impulse[FFTSizeDiv2]), static_cast<int> (FFTSizeDiv2)); @@ -286,929 +386,754 @@ struct ConvolutionEngine FloatVectorOperations::addWithMultiply (&(output[FFTSizeDiv2]), input, &(impulse[FFTSizeDiv2]), static_cast<int> (FFTSizeDiv2)); FloatVectorOperations::addWithMultiply (&(output[FFTSizeDiv2]), &(input[FFTSizeDiv2]), impulse, static_cast<int> (FFTSizeDiv2)); - output[FFTSize] += input[FFTSize] * impulse[FFTSize]; + output[fftSize] += input[fftSize] * impulse[fftSize]; } - /** Undo the re-organization of samples from the function prepareForConvolution. - Then, takes the conjugate of the frequency domain first half of samples, to fill the - second half, so that the inverse transform will return real samples in the time domain. - */ + // Undoes the re-organization of samples from the function prepareForConvolution. + // Then takes the conjugate of the frequency domain first half of samples to fill the + // second half, so that the inverse transform will return real samples in the time domain. void updateSymmetricFrequencyDomainData (float* samples) noexcept { - auto FFTSizeDiv2 = FFTSize / 2; + auto FFTSizeDiv2 = fftSize / 2; for (size_t i = 1; i < FFTSizeDiv2; i++) { - samples[2 * (FFTSize - i)] = samples[i]; - samples[2 * (FFTSize - i) + 1] = -samples[FFTSizeDiv2 + i]; + samples[(fftSize - i) << 1] = samples[i]; + samples[((fftSize - i) << 1) + 1] = -samples[FFTSizeDiv2 + i]; } samples[1] = 0.f; for (size_t i = 1; i < FFTSizeDiv2; i++) { - samples[2 * i] = samples[2 * (FFTSize - i)]; - samples[2 * i + 1] = -samples[2 * (FFTSize - i) + 1]; + samples[i << 1] = samples[(fftSize - i) << 1]; + samples[(i << 1) + 1] = -samples[((fftSize - i) << 1) + 1]; } } //============================================================================== - std::unique_ptr<FFT> FFTobject; - - size_t FFTSize = 0; - size_t currentSegment = 0, numInputSegments = 0, numSegments = 0, blockSize = 0, inputDataPos = 0; + const size_t blockSize; + const size_t fftSize; + const std::unique_ptr<FFT> fftObject; + const size_t numSegments; + const size_t numInputSegments; + size_t currentSegment = 0, inputDataPos = 0; AudioBuffer<float> bufferInput, bufferOutput, bufferTempOutput, bufferOverlap; - Array<AudioBuffer<float>> buffersInputSegments, buffersImpulseSegments; - - bool isReady = false; - - //============================================================================== - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ConvolutionEngine) + std::vector<AudioBuffer<float>> buffersInputSegments, buffersImpulseSegments; }; - - //============================================================================== -/** Manages all the changes requested by the main convolution engine, to minimize - the number of calls of the convolution engine initialization, and the potential - consequences of multiple quick calls to the function Convolution::loadImpulseResponse. -*/ -struct Convolution::Pimpl : private Thread +class MultichannelEngine { - enum class ChangeRequest +public: + MultichannelEngine (const AudioBuffer<float>& buf, + int maxBlockSize, + int maxBufferSize, + Convolution::NonUniform headSizeIn, + bool isZeroDelayIn) + : tailBuffer (1, maxBlockSize), + latency (isZeroDelayIn ? 0 : maxBufferSize), + irSize (buf.getNumSamples()), + blockSize (maxBlockSize), + isZeroDelay (isZeroDelayIn) { - changeEngine = 0, - changeSampleRate, - changeMaximumBufferSize, - changeSource, - changeImpulseResponseSize, - changeStereo, - changeTrimming, - changeNormalisation, - changeIgnore, - numChangeRequestTypes - }; - - using SourceType = ConvolutionEngine::ProcessingInformation::SourceType; + constexpr auto numChannels = 2; - //============================================================================== - Pimpl() : Thread ("Convolution"), abstractFifo (fifoSize) - { - abstractFifo.reset(); - fifoRequestsType.resize (fifoSize); - fifoRequestsParameter.resize (fifoSize); - - requestsType.resize (fifoSize); - requestsParameter.resize (fifoSize); + const auto makeEngine = [&] (int channel, int offset, int length, uint32 thisBlockSize) + { + return std::make_unique<ConvolutionEngine> (buf.getReadPointer (jmin (buf.getNumChannels() - 1, channel), offset), + length, + static_cast<size_t> (thisBlockSize)); + }; - for (auto i = 0; i < 4; ++i) - engines.add (new ConvolutionEngine()); + if (headSizeIn.headSizeInSamples == 0) + { + for (int i = 0; i < numChannels; ++i) + head.emplace_back (makeEngine (i, 0, buf.getNumSamples(), static_cast<uint32> (maxBufferSize))); + } + else + { + const auto size = jmin (buf.getNumSamples(), headSizeIn.headSizeInSamples); - currentInfo.maximumBufferSize = 0; - currentInfo.buffer = &impulseResponse; + for (int i = 0; i < numChannels; ++i) + head.emplace_back (makeEngine (i, 0, size, static_cast<uint32> (maxBufferSize))); - temporaryBuffer.setSize (2, static_cast<int> (maximumTimeInSamples), false, false, true); - impulseResponseOriginal.setSize (2, static_cast<int> (maximumTimeInSamples), false, false, true); - impulseResponse.setSize (2, static_cast<int> (maximumTimeInSamples), false, false, true); - } + const auto tailBufferSize = static_cast<uint32> (headSizeIn.headSizeInSamples + (isZeroDelay ? 0 : maxBufferSize)); - ~Pimpl() override - { - stopThread (10000); + if (size != buf.getNumSamples()) + for (int i = 0; i < numChannels; ++i) + tail.emplace_back (makeEngine (i, size, buf.getNumSamples() - size, tailBufferSize)); + } } - //============================================================================== - /** Inits the size of the interpolation buffer. */ - void initProcessing (int maximumBufferSize) + void reset() { - stopThread (1000); + for (const auto& e : head) + e->reset(); - interpolationBuffer.setSize (1, maximumBufferSize, false, false, true); - mustInterpolate = false; + for (const auto& e : tail) + e->reset(); } - //============================================================================== - /** Adds a new change request. */ - void addToFifo (ChangeRequest type, juce::var parameter) + void processSamples (const AudioBlock<const float>& input, AudioBlock<float>& output) { - int start1, size1, start2, size2; - abstractFifo.prepareToWrite (1, start1, size1, start2, size2); + const auto numChannels = jmin (head.size(), input.getNumChannels(), output.getNumChannels()); + const auto numSamples = jmin (input.getNumSamples(), output.getNumSamples()); - // If you hit this assertion then you have requested more impulse response - // changes than the Convolution class can handle. - jassert (size1 + size2 > 0); + const AudioBlock<float> fullTailBlock (tailBuffer); + const auto tailBlock = fullTailBlock.getSubBlock (0, (size_t) numSamples); - if (size1 > 0) - { - fifoRequestsType.setUnchecked (start1, type); - fifoRequestsParameter.setUnchecked (start1, parameter); - } + const auto isUniform = tail.empty(); - if (size2 > 0) + for (size_t channel = 0; channel < numChannels; ++channel) { - fifoRequestsType.setUnchecked (start2, type); - fifoRequestsParameter.setUnchecked (start2, parameter); - } - - abstractFifo.finishedWrite (size1 + size2); - } - - /** Adds a new array of change requests. */ - void addToFifo (ChangeRequest* types, juce::var* parameters, int numEntries) - { - int start1, size1, start2, size2; - abstractFifo.prepareToWrite (numEntries, start1, size1, start2, size2); - - // If you hit this assertion then you have requested more impulse response - // changes than the Convolution class can handle. - jassert (numEntries > 0 && size1 + size2 > 0); + if (! isUniform) + tail[channel]->processSamplesWithAddedLatency (input.getChannelPointer (channel), + tailBlock.getChannelPointer (0), + numSamples); + + if (isZeroDelay) + head[channel]->processSamples (input.getChannelPointer (channel), + output.getChannelPointer (channel), + numSamples); + else + head[channel]->processSamplesWithAddedLatency (input.getChannelPointer (channel), + output.getChannelPointer (channel), + numSamples); - if (size1 > 0) - { - for (auto i = 0; i < size1; ++i) - { - fifoRequestsType.setUnchecked (start1 + i, types[i]); - fifoRequestsParameter.setUnchecked (start1 + i, parameters[i]); - } + if (! isUniform) + output.getSingleChannelBlock (channel) += tailBlock; } - if (size2 > 0) - { - for (auto i = 0; i < size2; ++i) - { - fifoRequestsType.setUnchecked (start2 + i, types[i + size1]); - fifoRequestsParameter.setUnchecked (start2 + i, parameters[i + size1]); - } - } + const auto numOutputChannels = output.getNumChannels(); - abstractFifo.finishedWrite (size1 + size2); + for (auto i = numChannels; i < numOutputChannels; ++i) + output.getSingleChannelBlock (i).copyFrom (output.getSingleChannelBlock (0)); } - /** Reads requests from the fifo. */ - void readFromFifo (ChangeRequest& type, juce::var& parameter) - { - int start1, size1, start2, size2; - abstractFifo.prepareToRead (1, start1, size1, start2, size2); + int getIRSize() const noexcept { return irSize; } + int getLatency() const noexcept { return latency; } + int getBlockSize() const noexcept { return blockSize; } - if (size1 > 0) - { - type = fifoRequestsType[start1]; - parameter = fifoRequestsParameter[start1]; - } +private: + std::vector<std::unique_ptr<ConvolutionEngine>> head, tail; + AudioBuffer<float> tailBuffer; - if (size2 > 0) - { - type = fifoRequestsType[start2]; - parameter = fifoRequestsParameter[start2]; - } + const int latency; + const int irSize; + const int blockSize; + const bool isZeroDelay; +}; - abstractFifo.finishedRead (size1 + size2); - } +static AudioBuffer<float> fixNumChannels (const AudioBuffer<float>& buf, Convolution::Stereo stereo) +{ + const auto numChannels = jmin (buf.getNumChannels(), stereo == Convolution::Stereo::yes ? 2 : 1); + const auto numSamples = buf.getNumSamples(); - /** Returns the number of requests that still need to be processed. */ - int getNumRemainingEntries() const noexcept - { - return abstractFifo.getNumReady(); - } + AudioBuffer<float> result (numChannels, buf.getNumSamples()); - //============================================================================== - /** This function processes all the change requests to remove all the the - redundant ones, and to tell what kind of initialization must be done. + for (auto channel = 0; channel != numChannels; ++channel) + result.copyFrom (channel, 0, buf.getReadPointer (channel), numSamples); - Depending on the results, the convolution engines might be reset, or - simply updated, or they might not need any change at all. - */ - void processFifo() + if (result.getNumSamples() == 0 || result.getNumChannels() == 0) { - if (getNumRemainingEntries() == 0 || isThreadRunning() || mustInterpolate) - return; + result.setSize (1, 1); + result.setSample (0, 0, 1.0f); + } - auto numRequests = 0; + return result; +} - // retrieve the information from the FIFO for processing - while (getNumRemainingEntries() > 0 && numRequests < fifoSize) - { - ChangeRequest type = ChangeRequest::changeEngine; - juce::var parameter; +static AudioBuffer<float> trimImpulseResponse (const AudioBuffer<float>& buf) +{ + const auto thresholdTrim = Decibels::decibelsToGain (-80.0f); - readFromFifo (type, parameter); + const auto numChannels = buf.getNumChannels(); + const auto numSamples = buf.getNumSamples(); - requestsType.setUnchecked (numRequests, type); - requestsParameter.setUnchecked (numRequests, parameter); + std::ptrdiff_t offsetBegin = numSamples; + std::ptrdiff_t offsetEnd = numSamples; - numRequests++; - } - - // remove any useless messages - for (auto i = 0; i < (int) ChangeRequest::numChangeRequestTypes; ++i) + for (auto channel = 0; channel < numChannels; ++channel) + { + const auto indexAboveThreshold = [&] (auto begin, auto end) { - bool exists = false; - - for (auto n = numRequests; --n >= 0;) + return std::distance (begin, std::find_if (begin, end, [&] (float sample) { - if (requestsType[n] == (ChangeRequest) i) - { - if (! exists) - exists = true; - else - requestsType.setUnchecked (n, ChangeRequest::changeIgnore); - } - } - } + return std::abs (sample) >= thresholdTrim; + })); + }; - changeLevel = 0; + const auto channelBegin = buf.getReadPointer (channel); + const auto channelEnd = channelBegin + numSamples; + const auto itStart = indexAboveThreshold (channelBegin, channelEnd); + const auto itEnd = indexAboveThreshold (std::make_reverse_iterator (channelEnd), + std::make_reverse_iterator (channelBegin)); - for (auto n = 0; n < numRequests; ++n) - { - switch (requestsType[n]) - { - case ChangeRequest::changeEngine: - changeLevel = 3; - break; + offsetBegin = jmin (offsetBegin, itStart); + offsetEnd = jmin (offsetEnd, itEnd); + } - case ChangeRequest::changeSampleRate: - { - double newSampleRate = requestsParameter[n]; + if (offsetBegin == numSamples) + { + auto result = AudioBuffer<float> (numChannels, 1); + result.clear(); + return result; + } - if (currentInfo.sampleRate != newSampleRate) - changeLevel = 3; + const auto newLength = jmax (1, numSamples - static_cast<int> (offsetBegin + offsetEnd)); - currentInfo.sampleRate = newSampleRate; - } - break; + AudioBuffer<float> result (numChannels, newLength); - case ChangeRequest::changeMaximumBufferSize: - { - int newMaximumBufferSize = requestsParameter[n]; + for (auto channel = 0; channel < numChannels; ++channel) + { + result.copyFrom (channel, + 0, + buf.getReadPointer (channel, static_cast<int> (offsetBegin)), + result.getNumSamples()); + } - if (currentInfo.maximumBufferSize != (size_t) newMaximumBufferSize) - changeLevel = 3; + return result; +} - currentInfo.maximumBufferSize = (size_t) newMaximumBufferSize; - } - break; +static float calculateNormalisationFactor (float sumSquaredMagnitude) +{ + if (sumSquaredMagnitude < 1e-8f) + return 1.0f; - case ChangeRequest::changeSource: - { - auto* arrayParameters = requestsParameter[n].getArray(); - auto newSourceType = static_cast<SourceType> (static_cast<int> (arrayParameters->getUnchecked (0))); - - if (currentInfo.sourceType != newSourceType) - changeLevel = jmax (2, changeLevel); - - if (newSourceType == SourceType::sourceBinaryData) - { - auto& prm = arrayParameters->getRawDataPointer()[1]; - auto* newMemoryBlock = prm.getBinaryData(); - - auto* newPtr = newMemoryBlock->getData(); - auto newSize = (int) newMemoryBlock->getSize(); - - if (currentInfo.sourceData != newPtr || currentInfo.sourceDataSize != newSize) - changeLevel = jmax (2, changeLevel); - - currentInfo.sourceType = SourceType::sourceBinaryData; - currentInfo.sourceData = newPtr; - currentInfo.sourceDataSize = newSize; - currentInfo.fileImpulseResponse = File(); - } - else if (newSourceType == SourceType::sourceAudioFile) - { - File newFile (arrayParameters->getUnchecked (1).toString()); - - if (currentInfo.fileImpulseResponse != newFile) - changeLevel = jmax (2, changeLevel); - - currentInfo.sourceType = SourceType::sourceAudioFile; - currentInfo.fileImpulseResponse = newFile; - currentInfo.sourceData = nullptr; - currentInfo.sourceDataSize = 0; - } - else if (newSourceType == SourceType::sourceAudioBuffer) - { - double originalSampleRate (arrayParameters->getUnchecked (1)); - changeLevel = jmax (2, changeLevel); - - currentInfo.sourceType = SourceType::sourceAudioBuffer; - currentInfo.originalSampleRate = originalSampleRate; - currentInfo.fileImpulseResponse = File(); - currentInfo.sourceData = nullptr; - currentInfo.sourceDataSize = 0; - } - } - break; + return 0.125f / std::sqrt (sumSquaredMagnitude); +} - case ChangeRequest::changeImpulseResponseSize: - { - int64 newSize = requestsParameter[n]; +static void normaliseImpulseResponse (AudioBuffer<float>& buf) +{ + const auto numChannels = buf.getNumChannels(); + const auto numSamples = buf.getNumSamples(); + const auto channelPtrs = buf.getArrayOfWritePointers(); - if (currentInfo.wantedSize != newSize) - changeLevel = jmax (1, changeLevel); + const auto maxSumSquaredMag = std::accumulate (channelPtrs, channelPtrs + numChannels, 0.0f, [numSamples] (auto max, auto* channel) + { + return jmax (max, std::accumulate (channel, channel + numSamples, 0.0f, [] (auto sum, auto samp) + { + return sum + (samp * samp); + })); + }); - currentInfo.wantedSize = newSize; - } - break; + const auto normalisationFactor = calculateNormalisationFactor (maxSumSquaredMag); - case ChangeRequest::changeStereo: - { - bool newWantsStereo = requestsParameter[n]; + std::for_each (channelPtrs, channelPtrs + numChannels, [normalisationFactor, numSamples] (auto* channel) + { + FloatVectorOperations::multiply (channel, normalisationFactor, numSamples); + }); +} - if (currentInfo.wantsStereo != newWantsStereo) - changeLevel = jmax (0, changeLevel); +static AudioBuffer<float> resampleImpulseResponse (const AudioBuffer<float>& buf, + const double srcSampleRate, + const double destSampleRate) +{ + if (srcSampleRate == destSampleRate) + return buf; - currentInfo.wantsStereo = newWantsStereo; - } - break; + const auto factorReading = srcSampleRate / destSampleRate; - case ChangeRequest::changeTrimming: - { - bool newWantsTrimming = requestsParameter[n]; + AudioBuffer<float> original = buf; + MemoryAudioSource memorySource (original, false); + ResamplingAudioSource resamplingSource (&memorySource, false, buf.getNumChannels()); - if (currentInfo.wantsTrimming != newWantsTrimming) - changeLevel = jmax (1, changeLevel); + const auto finalSize = roundToInt (jmax (1.0, buf.getNumSamples() / factorReading)); + resamplingSource.setResamplingRatio (factorReading); + resamplingSource.prepareToPlay (finalSize, srcSampleRate); - currentInfo.wantsTrimming = newWantsTrimming; - } - break; + AudioBuffer<float> result (buf.getNumChannels(), finalSize); + resamplingSource.getNextAudioBlock ({ &result, 0, result.getNumSamples() }); - case ChangeRequest::changeNormalisation: - { - bool newWantsNormalisation = requestsParameter[n]; + return result; +} - if (currentInfo.wantsNormalisation != newWantsNormalisation) - changeLevel = jmax (1, changeLevel); +//============================================================================== +template <typename Element> +class TryLockedPtr +{ +public: + void set (std::unique_ptr<Element> p) + { + const SpinLock::ScopedLockType lock (mutex); + ptr = std::move (p); + } - currentInfo.wantsNormalisation = newWantsNormalisation; - } - break; + std::unique_ptr<MultichannelEngine> get() + { + const SpinLock::ScopedTryLockType lock (mutex); + return lock.isLocked() ? std::move (ptr) : nullptr; + } - case ChangeRequest::changeIgnore: - break; +private: + std::unique_ptr<Element> ptr; + SpinLock mutex; +}; - default: - jassertfalse; - break; - } - } +struct BufferWithSampleRate +{ + BufferWithSampleRate() = default; - if (currentInfo.sourceType == SourceType::sourceNone) - { - currentInfo.sourceType = SourceType::sourceAudioBuffer; + BufferWithSampleRate (AudioBuffer<float>&& bufferIn, double sampleRateIn) + : buffer (std::move (bufferIn)), sampleRate (sampleRateIn) {} - if (currentInfo.sampleRate == 0) - currentInfo.sampleRate = 44100; + AudioBuffer<float> buffer; + double sampleRate = 0.0; +}; - if (currentInfo.maximumBufferSize == 0) - currentInfo.maximumBufferSize = 128; +static BufferWithSampleRate loadStreamToBuffer (std::unique_ptr<InputStream> stream, size_t maxLength) +{ + AudioFormatManager manager; + manager.registerBasicFormats(); + std::unique_ptr<AudioFormatReader> formatReader (manager.createReaderFor (std::move (stream))); - currentInfo.originalSampleRate = currentInfo.sampleRate; - currentInfo.wantedSize = 1; - currentInfo.fileImpulseResponse = File(); - currentInfo.sourceData = nullptr; - currentInfo.sourceDataSize = 0; + if (formatReader == nullptr) + return {}; - AudioBuffer<float> newBuffer; - newBuffer.setSize (1, 1); - newBuffer.setSample (0, 0, 1.f); + const auto fileLength = static_cast<size_t> (formatReader->lengthInSamples); + const auto lengthToLoad = maxLength == 0 ? fileLength : jmin (maxLength, fileLength); - copyBufferToTemporaryLocation (newBuffer); - } + BufferWithSampleRate result { { jlimit (1, 2, static_cast<int> (formatReader->numChannels)), + static_cast<int> (lengthToLoad) }, + formatReader->sampleRate }; - // action depending on the change level - if (changeLevel == 3) - { - loadImpulseResponse(); - processImpulseResponse(); - initializeConvolutionEngines(); - } - else if (changeLevel > 0) - { - startThread(); - } - } + formatReader->read (result.buffer.getArrayOfWritePointers(), + result.buffer.getNumChannels(), + 0, + result.buffer.getNumSamples()); - //============================================================================== - /** This function copies a buffer to a temporary location, so that any external - audio source can be processed then in the dedicated thread. - */ - void copyBufferToTemporaryLocation (dsp::AudioBlock<float> block) - { - const SpinLock::ScopedLockType sl (processLock); + return result; +} - currentInfo.originalNumChannels = (block.getNumChannels() > 1 ? 2 : 1); - currentInfo.originalSize = (int) jmin ((size_t) maximumTimeInSamples, block.getNumSamples()); +// This class caches the data required to build a new convolution engine +// (in particular, impulse response data and a ProcessSpec). +// Calls to `setProcessSpec` and `setImpulseResponse` construct a +// new engine, which can be retrieved by calling `getEngine`. +class ConvolutionEngineFactory +{ +public: + ConvolutionEngineFactory (Convolution::Latency requiredLatency, + Convolution::NonUniform requiredHeadSize) + : latency { (requiredLatency.latencyInSamples <= 0) ? 0 : jmax (64, nextPowerOfTwo (requiredLatency.latencyInSamples)) }, + headSize { (requiredHeadSize.headSizeInSamples <= 0) ? 0 : jmax (64, nextPowerOfTwo (requiredHeadSize.headSizeInSamples)) }, + shouldBeZeroLatency (requiredLatency.latencyInSamples == 0) + {} + + // It is safe to call this method simultaneously with other public + // member functions. + void setProcessSpec (const ProcessSpec& spec) + { + const std::lock_guard<std::mutex> lock (mutex); + processSpec = spec; - for (auto channel = 0; channel < currentInfo.originalNumChannels; ++channel) - temporaryBuffer.copyFrom (channel, 0, block.getChannelPointer ((size_t) channel), (int) currentInfo.originalSize); + engine.set (makeEngine()); } - //============================================================================== - /** Resets the convolution engines states. */ - void reset() + // It is safe to call this method simultaneously with other public + // member functions. + void setImpulseResponse (BufferWithSampleRate&& buf, + Convolution::Stereo stereo, + Convolution::Trim trim, + Convolution::Normalise normalise) { - for (auto* e : engines) - e->reset(); + const std::lock_guard<std::mutex> lock (mutex); + wantsNormalise = normalise; + originalSampleRate = buf.sampleRate; - mustInterpolate = false; + impulseResponse = [&] + { + auto corrected = fixNumChannels (buf.buffer, stereo); + return trim == Convolution::Trim::yes ? trimImpulseResponse (corrected) : corrected; + }(); - processFifo(); + engine.set (makeEngine()); } - /** Convolution processing handling interpolation between previous and new states - of the convolution engines. - */ - void processSamples (const AudioBlock<const float>& input, AudioBlock<float>& output) - { - processFifo(); + // Returns the most recently-created engine, or nullptr + // if there is no pending engine, or if the engine is currently + // being updated by one of the setter methods. + // It is safe to call this simultaneously with other public + // member functions. + std::unique_ptr<MultichannelEngine> getEngine() { return engine.get(); } - size_t numChannels = jmin (input.getNumChannels(), (size_t) (currentInfo.wantsStereo ? 2 : 1)); - size_t numSamples = jmin (input.getNumSamples(), output.getNumSamples()); +private: + std::unique_ptr<MultichannelEngine> makeEngine() + { + auto resampled = resampleImpulseResponse (impulseResponse, originalSampleRate, processSpec.sampleRate); - if (mustInterpolate == false) - { - for (size_t channel = 0; channel < numChannels; ++channel) - engines[(int) channel]->processSamples (input.getChannelPointer (channel), output.getChannelPointer (channel), numSamples); - } - else - { - auto interpolated = dsp::AudioBlock<float> (interpolationBuffer).getSubBlock (0, numSamples); + if (wantsNormalise == Convolution::Normalise::yes) + normaliseImpulseResponse (resampled); - for (size_t channel = 0; channel < numChannels; ++channel) - { - auto&& buffer = output.getSingleChannelBlock (channel); + const auto currentLatency = jmax (processSpec.maximumBlockSize, (uint32) latency.latencyInSamples); + const auto maxBufferSize = shouldBeZeroLatency ? static_cast<int> (processSpec.maximumBlockSize) + : nextPowerOfTwo (static_cast<int> (currentLatency)); - interpolationBuffer.copyFrom (0, 0, input.getChannelPointer (channel), (int) numSamples); + return std::make_unique<MultichannelEngine> (resampled, + processSpec.maximumBlockSize, + maxBufferSize, + headSize, + shouldBeZeroLatency); + } - engines[(int) channel]->processSamples (input.getChannelPointer (channel), buffer.getChannelPointer (0), numSamples); - changeVolumes[channel].applyGain (buffer.getChannelPointer (0), (int) numSamples); + static AudioBuffer<float> makeImpulseBuffer() + { + AudioBuffer<float> result (1, 1); + result.setSample (0, 0, 1.0f); + return result; + } - auto* interPtr = interpolationBuffer.getWritePointer (0); - engines[(int) channel + 2]->processSamples (interPtr, interPtr, numSamples); - changeVolumes[channel + 2].applyGain (interPtr, (int) numSamples); + ProcessSpec processSpec { 44100.0, 128, 2 }; + AudioBuffer<float> impulseResponse = makeImpulseBuffer(); + double originalSampleRate = processSpec.sampleRate; + Convolution::Normalise wantsNormalise = Convolution::Normalise::no; + const Convolution::Latency latency; + const Convolution::NonUniform headSize; + const bool shouldBeZeroLatency; - buffer += interpolated; - } + TryLockedPtr<MultichannelEngine> engine; - if (input.getNumChannels() > 1 && currentInfo.wantsStereo == false) - { - auto&& buffer = output.getSingleChannelBlock (1); + mutable std::mutex mutex; +}; - changeVolumes[1].applyGain (buffer.getChannelPointer (0), (int) numSamples); - changeVolumes[3].applyGain (buffer.getChannelPointer (0), (int) numSamples); - } +static void setImpulseResponse (ConvolutionEngineFactory& factory, + const void* sourceData, + size_t sourceDataSize, + Convolution::Stereo stereo, + Convolution::Trim trim, + size_t size, + Convolution::Normalise normalise) +{ + factory.setImpulseResponse (loadStreamToBuffer (std::make_unique<MemoryInputStream> (sourceData, sourceDataSize, false), size), + stereo, trim, normalise); +} - if (changeVolumes[0].isSmoothing() == false) - { - mustInterpolate = false; +static void setImpulseResponse (ConvolutionEngineFactory& factory, + const File& fileImpulseResponse, + Convolution::Stereo stereo, + Convolution::Trim trim, + size_t size, + Convolution::Normalise normalise) +{ + factory.setImpulseResponse (loadStreamToBuffer (std::make_unique<FileInputStream> (fileImpulseResponse), size), + stereo, trim, normalise); +} - for (auto channel = 0; channel < 2; ++channel) - engines[channel]->copyStateFromOtherEngine (*engines[channel + 2]); - } - } +// This class acts as a destination for convolution engines which are loaded on +// a background thread. - if (input.getNumChannels() > 1 && currentInfo.wantsStereo == false) - output.getSingleChannelBlock (1).copyFrom (output.getSingleChannelBlock (0)); +// Deriving from `enable_shared_from_this` allows us to capture a reference to +// this object when adding commands to the background message queue. +// That way, we can avoid dangling references in the background thread in the case +// that a Convolution instance is deleted before the background message queue. +class ConvolutionEngineQueue : public std::enable_shared_from_this<ConvolutionEngineQueue> +{ +public: + ConvolutionEngineQueue (BackgroundMessageQueue& queue, + Convolution::Latency latencyIn, + Convolution::NonUniform headSizeIn) + : messageQueue (queue), factory (latencyIn, headSizeIn) {} + + void loadImpulseResponse (AudioBuffer<float>&& buffer, + double sr, + Convolution::Stereo stereo, + Convolution::Trim trim, + Convolution::Normalise normalise) + { + callLater ([b = std::move (buffer), sr, stereo, trim, normalise] (ConvolutionEngineFactory& f) mutable + { + f.setImpulseResponse ({ std::move (b), sr }, stereo, trim, normalise); + }); } - //============================================================================== - const int64 maximumTimeInSamples = 10 * 96000; - -private: - //============================================================================== - /** This the thread run function which does the preparation of data depending - on the requested change level. - */ - void run() override + void loadImpulseResponse (const void* sourceData, + size_t sourceDataSize, + Convolution::Stereo stereo, + Convolution::Trim trim, + size_t size, + Convolution::Normalise normalise) { - if (changeLevel == 2) + callLater ([sourceData, sourceDataSize, stereo, trim, size, normalise] (ConvolutionEngineFactory& f) mutable { - loadImpulseResponse(); - - if (isThreadRunning() && threadShouldExit()) - return; - } - - processImpulseResponse(); - - if (isThreadRunning() && threadShouldExit()) - return; - - initializeConvolutionEngines(); + setImpulseResponse (f, sourceData, sourceDataSize, stereo, trim, size, normalise); + }); } - /** Loads the impulse response from the requested audio source. */ - void loadImpulseResponse() + void loadImpulseResponse (const File& fileImpulseResponse, + Convolution::Stereo stereo, + Convolution::Trim trim, + size_t size, + Convolution::Normalise normalise) { - if (currentInfo.sourceType == SourceType::sourceBinaryData) - { - if (! (copyAudioStreamInAudioBuffer (new MemoryInputStream (currentInfo.sourceData, (size_t) currentInfo.sourceDataSize, false)))) - return; - } - else if (currentInfo.sourceType == SourceType::sourceAudioFile) - { - if (! (copyAudioStreamInAudioBuffer (new FileInputStream (currentInfo.fileImpulseResponse)))) - return; - } - else if (currentInfo.sourceType == SourceType::sourceAudioBuffer) + callLater ([fileImpulseResponse, stereo, trim, size, normalise] (ConvolutionEngineFactory& f) mutable { - copyBufferFromTemporaryLocation(); - } + setImpulseResponse (f, fileImpulseResponse, stereo, trim, size, normalise); + }); } - /** Processes the impulse response data with the requested treatments - and resampling if needed. - */ - void processImpulseResponse() + void prepare (const ProcessSpec& spec) { - trimAndResampleImpulseResponse (currentInfo.originalNumChannels, currentInfo.originalSampleRate, currentInfo.wantsTrimming); + factory.setProcessSpec (spec); + } - if (isThreadRunning() && threadShouldExit()) + // Call this regularly to try to resend any pending message. + // This allows us to always apply the most recently requested + // state (eventually), even if the message queue fills up. + void postPendingCommand() + { + if (pendingCommand == nullptr) return; - if (currentInfo.wantsNormalisation) - { - if (currentInfo.originalNumChannels > 1) - { - normaliseImpulseResponse (currentInfo.buffer->getWritePointer (0), (int) currentInfo.finalSize, 1.0); - normaliseImpulseResponse (currentInfo.buffer->getWritePointer (1), (int) currentInfo.finalSize, 1.0); - } - else - { - normaliseImpulseResponse (currentInfo.buffer->getWritePointer (0), (int) currentInfo.finalSize, 1.0); - } - } - - if (currentInfo.originalNumChannels == 1) - currentInfo.buffer->copyFrom (1, 0, *currentInfo.buffer, 0, 0, (int) currentInfo.finalSize); + if (messageQueue.push (pendingCommand)) + pendingCommand = nullptr; } - /** Converts the data from an audio file into a stereo audio buffer of floats, and - performs resampling if necessary. - */ - bool copyAudioStreamInAudioBuffer (InputStream* stream) - { - AudioFormatManager manager; - manager.registerBasicFormats(); - std::unique_ptr<AudioFormatReader> formatReader (manager.createReaderFor (stream)); + std::unique_ptr<MultichannelEngine> getEngine() { return factory.getEngine(); } + +private: - if (formatReader != nullptr) + template <typename Fn> + void callLater (Fn&& fn) + { + // If there was already a pending command (because the queue was full) we'll end up deleting it here. + // Not much we can do about that! + pendingCommand = [weak = weakFromThis(), callback = std::forward<Fn> (fn)]() mutable { - currentInfo.originalNumChannels = formatReader->numChannels > 1 ? 2 : 1; - currentInfo.originalSampleRate = formatReader->sampleRate; - currentInfo.originalSize = static_cast<int> (jmin (maximumTimeInSamples, formatReader->lengthInSamples)); + if (auto t = weak.lock()) + callback (t->factory); + }; - impulseResponseOriginal.clear(); - formatReader->read (&(impulseResponseOriginal), 0, (int) currentInfo.originalSize, 0, true, currentInfo.originalNumChannels > 1); + postPendingCommand(); + } - return true; - } + std::weak_ptr<ConvolutionEngineQueue> weakFromThis() { return shared_from_this(); } - return false; - } + BackgroundMessageQueue& messageQueue; + ConvolutionEngineFactory factory; + BackgroundMessageQueue::IncomingCommand pendingCommand; +}; - /** Copies a buffer from a temporary location to the impulseResponseOriginal - buffer for the sourceAudioBuffer. - */ - void copyBufferFromTemporaryLocation() +class CrossoverMixer +{ +public: + void reset() { - const SpinLock::ScopedLockType sl (processLock); - - for (auto channel = 0; channel < currentInfo.originalNumChannels; ++channel) - impulseResponseOriginal.copyFrom (channel, 0, temporaryBuffer, channel, 0, (int) currentInfo.originalSize); + smoother.setCurrentAndTargetValue (1.0f); } - /** Trim and resample the impulse response if needed. */ - void trimAndResampleImpulseResponse (int numChannels, double srcSampleRate, bool mustTrim) + void prepare (const ProcessSpec& spec) { - auto thresholdTrim = Decibels::decibelsToGain (-80.0f); - auto indexStart = 0; - auto indexEnd = currentInfo.originalSize - 1; + smoother.reset (spec.sampleRate, 0.05); + smootherBuffer.setSize (1, static_cast<int> (spec.maximumBlockSize)); + mixBuffer.setSize (static_cast<int> (spec.numChannels), static_cast<int> (spec.maximumBlockSize)); + reset(); + } - if (mustTrim) + template <typename ProcessCurrent, typename ProcessPrevious, typename NotifyDone> + void processSamples (const AudioBlock<const float>& input, + AudioBlock<float>& output, + ProcessCurrent&& current, + ProcessPrevious&& previous, + NotifyDone&& notifyDone) + { + if (smoother.isSmoothing()) { - indexStart = currentInfo.originalSize - 1; - indexEnd = 0; - - for (auto channel = 0; channel < numChannels; ++channel) - { - auto localIndexStart = 0; - auto localIndexEnd = currentInfo.originalSize - 1; + const auto numSamples = static_cast<int> (input.getNumSamples()); - auto* channelData = impulseResponseOriginal.getReadPointer (channel); + for (auto sample = 0; sample != numSamples; ++sample) + smootherBuffer.setSample (0, sample, smoother.getNextValue()); - while (localIndexStart < currentInfo.originalSize - 1 - && channelData[localIndexStart] <= thresholdTrim - && channelData[localIndexStart] >= -thresholdTrim) - ++localIndexStart; + AudioBlock<float> mixBlock (mixBuffer); + mixBlock.clear(); + previous (input, mixBlock); - while (localIndexEnd >= 0 - && channelData[localIndexEnd] <= thresholdTrim - && channelData[localIndexEnd] >= -thresholdTrim) - --localIndexEnd; - - indexStart = jmin (indexStart, localIndexStart); - indexEnd = jmax (indexEnd, localIndexEnd); + for (size_t channel = 0; channel != output.getNumChannels(); ++channel) + { + FloatVectorOperations::multiply (mixBlock.getChannelPointer (channel), + smootherBuffer.getReadPointer (0), + numSamples); } - if (indexStart > 0) - { - for (auto channel = 0; channel < numChannels; ++channel) - { - auto* channelData = impulseResponseOriginal.getWritePointer (channel); + FloatVectorOperations::multiply (smootherBuffer.getWritePointer (0), -1.0f, numSamples); + FloatVectorOperations::add (smootherBuffer.getWritePointer (0), 1.0f, numSamples); - for (auto i = 0; i < indexEnd - indexStart + 1; ++i) - channelData[i] = channelData[i + indexStart]; + current (input, output); - for (auto i = indexEnd - indexStart + 1; i < currentInfo.originalSize - 1; ++i) - channelData[i] = 0.0f; - } + for (size_t channel = 0; channel != output.getNumChannels(); ++channel) + { + FloatVectorOperations::multiply (output.getChannelPointer (channel), + smootherBuffer.getReadPointer (0), + numSamples); + FloatVectorOperations::add (output.getChannelPointer (channel), + mixBlock.getChannelPointer (channel), + numSamples); } - } - if (currentInfo.sampleRate == srcSampleRate) - { - // No resampling - currentInfo.finalSize = jmin (static_cast<int> (currentInfo.wantedSize), indexEnd - indexStart + 1); - - impulseResponse.clear(); - - for (auto channel = 0; channel < numChannels; ++channel) - impulseResponse.copyFrom (channel, 0, impulseResponseOriginal, channel, 0, (int) currentInfo.finalSize); + if (! smoother.isSmoothing()) + notifyDone(); } else { - // Resampling - auto factorReading = srcSampleRate / currentInfo.sampleRate; - currentInfo.finalSize = jmin (static_cast<int> (currentInfo.wantedSize), roundToInt ((indexEnd - indexStart + 1) / factorReading)); - - impulseResponse.clear(); - - MemoryAudioSource memorySource (impulseResponseOriginal, false); - ResamplingAudioSource resamplingSource (&memorySource, false, (int) numChannels); - - resamplingSource.setResamplingRatio (factorReading); - resamplingSource.prepareToPlay ((int) currentInfo.finalSize, currentInfo.sampleRate); - - AudioSourceChannelInfo info; - info.startSample = 0; - info.numSamples = (int) currentInfo.finalSize; - info.buffer = &impulseResponse; - - resamplingSource.getNextAudioBlock (info); + current (input, output); } - - // Filling the second channel with the first if necessary - if (numChannels == 1) - impulseResponse.copyFrom (1, 0, impulseResponse, 0, 0, (int) currentInfo.finalSize); } - /** Normalisation of the impulse response based on its energy. */ - void normaliseImpulseResponse (float* samples, int numSamples, double factorResampling) const + void beginTransition() { - auto magnitude = 0.0f; - - for (auto i = 0; i < numSamples; ++i) - magnitude += samples[i] * samples[i]; - - auto magnitudeInv = 1.0f / (4.0f * std::sqrt (magnitude)) * 0.5f * static_cast <float> (factorResampling); - - for (auto i = 0; i < numSamples; ++i) - samples[i] *= magnitudeInv; + smoother.setCurrentAndTargetValue (1.0f); + smoother.setTargetValue (0.0f); } - // ================================================================================================================ - /** Initializes the convolution engines depending on the provided sizes - and performs the FFT on the impulse responses. - */ - void initializeConvolutionEngines() - { - if (currentInfo.maximumBufferSize == 0) - return; - - if (changeLevel == 3) - { - for (auto i = 0; i < 2; ++i) - engines[i]->initializeConvolutionEngine (currentInfo, i); - - mustInterpolate = false; - } - else - { - for (auto i = 0; i < 2; ++i) - { - engines[i + 2]->initializeConvolutionEngine (currentInfo, i); - engines[i + 2]->reset(); +private: + LinearSmoothedValue<float> smoother; + AudioBuffer<float> smootherBuffer; + AudioBuffer<float> mixBuffer; +}; - if (isThreadRunning() && threadShouldExit()) - return; - } +using OptionalQueue = OptionalScopedPointer<ConvolutionMessageQueue>; - for (auto i = 0; i < 2; ++i) - { - changeVolumes[i].setTargetValue (1.0f); - changeVolumes[i].reset (currentInfo.sampleRate, 0.05); - changeVolumes[i].setTargetValue (0.0f); +class Convolution::Impl +{ +public: + Impl (Latency requiredLatency, + NonUniform requiredHeadSize, + OptionalQueue&& queue) + : messageQueue (std::move (queue)), + engineQueue (std::make_shared<ConvolutionEngineQueue> (*messageQueue->pimpl, + requiredLatency, + requiredHeadSize)) + {} - changeVolumes[i + 2].setTargetValue (0.0f); - changeVolumes[i + 2].reset (currentInfo.sampleRate, 0.05); - changeVolumes[i + 2].setTargetValue (1.0f); + void reset() + { + mixer.reset(); - } + if (currentEngine != nullptr) + currentEngine->reset(); - mustInterpolate = true; - } + destroyPreviousEngine(); } + void prepare (const ProcessSpec& spec) + { + mixer.prepare (spec); + engineQueue->prepare (spec); + currentEngine = engineQueue->getEngine(); + previousEngine = nullptr; + jassert (currentEngine != nullptr); + } - //============================================================================== - static constexpr int fifoSize = 1024; // the size of the fifo which handles all the change requests - AbstractFifo abstractFifo; // the abstract fifo - - Array<ChangeRequest> fifoRequestsType; // an array of ChangeRequest - Array<juce::var> fifoRequestsParameter; // an array of change parameters + void processSamples (const AudioBlock<const float>& input, AudioBlock<float>& output) + { + engineQueue->postPendingCommand(); + + if (previousEngine == nullptr) + installPendingEngine(); + + mixer.processSamples (input, + output, + [this] (const AudioBlock<const float>& in, AudioBlock<float>& out) + { + currentEngine->processSamples (in, out); + }, + [this] (const AudioBlock<const float>& in, AudioBlock<float>& out) + { + if (previousEngine != nullptr) + previousEngine->processSamples (in, out); + else + out.copyFrom (in); + }, + [this] { destroyPreviousEngine(); }); + } - Array<ChangeRequest> requestsType; // an array of ChangeRequest - Array<juce::var> requestsParameter; // an array of change parameters + int getCurrentIRSize() const { return currentEngine != nullptr ? currentEngine->getIRSize() : 0; } - int changeLevel = 0; // the current level of requested change in the convolution engine + int getLatency() const { return currentEngine != nullptr ? currentEngine->getLatency() : 0; } - //============================================================================== - ConvolutionEngine::ProcessingInformation currentInfo; // the information about the impulse response to load + void loadImpulseResponse (AudioBuffer<float>&& buffer, + double originalSampleRate, + Stereo stereo, + Trim trim, + Normalise normalise) + { + engineQueue->loadImpulseResponse (std::move (buffer), originalSampleRate, stereo, trim, normalise); + } - AudioBuffer<float> temporaryBuffer; // a temporary buffer that is used when the function copyAndLoadImpulseResponse is called in the main API - SpinLock processLock; // a necessary lock to use with this temporary buffer + void loadImpulseResponse (const void* sourceData, + size_t sourceDataSize, + Stereo stereo, + Trim trim, + size_t size, + Normalise normalise) + { + engineQueue->loadImpulseResponse (sourceData, sourceDataSize, stereo, trim, size, normalise); + } - AudioBuffer<float> impulseResponseOriginal; // a buffer with the original impulse response - AudioBuffer<float> impulseResponse; // a buffer with the impulse response trimmed, resampled, resized and normalised + void loadImpulseResponse (const File& fileImpulseResponse, + Stereo stereo, + Trim trim, + size_t size, + Normalise normalise) + { + engineQueue->loadImpulseResponse (fileImpulseResponse, stereo, trim, size, normalise); + } - //============================================================================== - OwnedArray<ConvolutionEngine> engines; // the 4 convolution engines being used +private: + void destroyPreviousEngine() + { + // If the queue is full, we'll destroy this straight away + BackgroundMessageQueue::IncomingCommand command = [p = std::move (previousEngine)]() mutable { p = nullptr; }; + messageQueue->pimpl->push (command); + } - AudioBuffer<float> interpolationBuffer; // a buffer to do the interpolation between the convolution engines 0-1 and 2-3 - LogRampedValue<float> changeVolumes[4]; // the volumes for each convolution engine during interpolation + void installNewEngine (std::unique_ptr<MultichannelEngine> newEngine) + { + destroyPreviousEngine(); + previousEngine = std::move (currentEngine); + currentEngine = std::move (newEngine); + mixer.beginTransition(); + } - bool mustInterpolate = false; // tells if the convolution engines outputs must be currently interpolated + void installPendingEngine() + { + if (auto newEngine = engineQueue->getEngine()) + installNewEngine (std::move (newEngine)); + } - //============================================================================== - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Pimpl) + OptionalQueue messageQueue; + std::shared_ptr<ConvolutionEngineQueue> engineQueue; + std::unique_ptr<MultichannelEngine> previousEngine, currentEngine; + CrossoverMixer mixer; }; - //============================================================================== -Convolution::Convolution() +void Convolution::Mixer::prepare (const ProcessSpec& spec) { - pimpl.reset (new Pimpl()); - pimpl->addToFifo (Convolution::Pimpl::ChangeRequest::changeEngine, juce::var (0)); -} - -Convolution::~Convolution() -{ -} - -void Convolution::loadImpulseResponse (const void* sourceData, size_t sourceDataSize, - bool wantsStereo, bool wantsTrimming, size_t size, - bool wantsNormalisation) -{ - if (sourceData == nullptr) - return; - - auto maximumSamples = (size_t) pimpl->maximumTimeInSamples; - auto wantedSize = (size == 0 ? maximumSamples : jmin (size, maximumSamples)); - - Pimpl::ChangeRequest types[] = { Pimpl::ChangeRequest::changeSource, - Pimpl::ChangeRequest::changeImpulseResponseSize, - Pimpl::ChangeRequest::changeStereo, - Pimpl::ChangeRequest::changeTrimming, - Pimpl::ChangeRequest::changeNormalisation }; - - Array<juce::var> sourceParameter; - - sourceParameter.add (juce::var ((int) ConvolutionEngine::ProcessingInformation::SourceType::sourceBinaryData)); - sourceParameter.add (juce::var (sourceData, sourceDataSize)); - - juce::var parameters[] = { juce::var (sourceParameter), - juce::var (static_cast<int64> (wantedSize)), - juce::var (wantsStereo), - juce::var (wantsTrimming), - juce::var (wantsNormalisation) }; - - pimpl->addToFifo (types, parameters, 5); -} - -void Convolution::loadImpulseResponse (const File& fileImpulseResponse, bool wantsStereo, - bool wantsTrimming, size_t size, bool wantsNormalisation) -{ - if (! fileImpulseResponse.existsAsFile()) - return; - - auto maximumSamples = (size_t) pimpl->maximumTimeInSamples; - auto wantedSize = (size == 0 ? maximumSamples : jmin (size, maximumSamples)); - - Pimpl::ChangeRequest types[] = { Pimpl::ChangeRequest::changeSource, - Pimpl::ChangeRequest::changeImpulseResponseSize, - Pimpl::ChangeRequest::changeStereo, - Pimpl::ChangeRequest::changeTrimming, - Pimpl::ChangeRequest::changeNormalisation }; - - Array<juce::var> sourceParameter; - - sourceParameter.add (juce::var ((int) ConvolutionEngine::ProcessingInformation::SourceType::sourceAudioFile)); - sourceParameter.add (juce::var (fileImpulseResponse.getFullPathName())); - - juce::var parameters[] = { juce::var (sourceParameter), - juce::var (static_cast<int64> (wantedSize)), - juce::var (wantsStereo), - juce::var (wantsTrimming), - juce::var (wantsNormalisation) }; - - pimpl->addToFifo (types, parameters, 5); -} - -void Convolution::copyAndLoadImpulseResponseFromBuffer (AudioBuffer<float>& buffer, - double bufferSampleRate, bool wantsStereo, bool wantsTrimming, bool wantsNormalisation, size_t size) -{ - copyAndLoadImpulseResponseFromBlock (AudioBlock<float> (buffer), bufferSampleRate, - wantsStereo, wantsTrimming, wantsNormalisation, size); -} - -void Convolution::copyAndLoadImpulseResponseFromBlock (AudioBlock<float> block, double bufferSampleRate, - bool wantsStereo, bool wantsTrimming, bool wantsNormalisation, size_t size) -{ - jassert (bufferSampleRate > 0); - - if (block.getNumSamples() == 0) - return; - - auto maximumSamples = (size_t) pimpl->maximumTimeInSamples; - auto wantedSize = (size == 0 ? maximumSamples : jmin (size, maximumSamples)); - - pimpl->copyBufferToTemporaryLocation (block); + for (auto& dry : volumeDry) + dry.reset (spec.sampleRate, 0.05); - Pimpl::ChangeRequest types[] = { Pimpl::ChangeRequest::changeSource, - Pimpl::ChangeRequest::changeImpulseResponseSize, - Pimpl::ChangeRequest::changeStereo, - Pimpl::ChangeRequest::changeTrimming, - Pimpl::ChangeRequest::changeNormalisation }; - - Array<juce::var> sourceParameter; - sourceParameter.add (juce::var ((int) ConvolutionEngine::ProcessingInformation::SourceType::sourceAudioBuffer)); - sourceParameter.add (juce::var (bufferSampleRate)); - - juce::var parameters[] = { juce::var (sourceParameter), - juce::var (static_cast<int64> (wantedSize)), - juce::var (wantsStereo), - juce::var (wantsTrimming), - juce::var (wantsNormalisation) }; - - pimpl->addToFifo (types, parameters, 5); -} - -void Convolution::prepare (const ProcessSpec& spec) -{ - jassert (isPositiveAndBelow (spec.numChannels, static_cast<uint32> (3))); // only mono and stereo is supported - - Pimpl::ChangeRequest types[] = { Pimpl::ChangeRequest::changeSampleRate, - Pimpl::ChangeRequest::changeMaximumBufferSize }; - - juce::var parameters[] = { juce::var (spec.sampleRate), - juce::var (static_cast<int> (spec.maximumBlockSize)) }; - - pimpl->addToFifo (types, parameters, 2); - pimpl->initProcessing (static_cast<int> (spec.maximumBlockSize)); - - for (size_t channel = 0; channel < spec.numChannels; ++channel) - { - volumeDry[channel].reset (spec.sampleRate, 0.05); - volumeWet[channel].reset (spec.sampleRate, 0.05); - } + for (auto& wet : volumeWet) + wet.reset (spec.sampleRate, 0.05); sampleRate = spec.sampleRate; - dryBuffer = AudioBlock<float> (dryBufferStorage, - jmin (spec.numChannels, 2u), - spec.maximumBlockSize); - isActive = true; -} + dryBlock = AudioBlock<float> (dryBlockStorage, + jmin (spec.numChannels, 2u), + spec.maximumBlockSize); -void Convolution::reset() noexcept -{ - dryBuffer.clear(); - pimpl->reset(); } -void Convolution::processSamples (const AudioBlock<const float>& input, AudioBlock<float>& output, bool isBypassed) noexcept +template <typename ProcessWet> +void Convolution::Mixer::processSamples (const AudioBlock<const float>& input, + AudioBlock<float>& output, + bool isBypassed, + ProcessWet&& processWet) noexcept { - if (! isActive) - return; - - jassert (input.getNumChannels() == output.getNumChannels()); - jassert (isPositiveAndBelow (input.getNumChannels(), static_cast<size_t> (3))); // only mono and stereo is supported - - auto numChannels = jmin (input.getNumChannels(), (size_t) 2); - auto numSamples = jmin (input.getNumSamples(), output.getNumSamples()); + const auto numChannels = jmin (input.getNumChannels(), volumeDry.size()); + const auto numSamples = jmin (input.getNumSamples(), output.getNumSamples()); - auto dry = dryBuffer.getSubsetChannelBlock (0, numChannels); + auto dry = dryBlock.getSubsetChannelBlock (0, numChannels); if (volumeDry[0].isSmoothing()) { @@ -1217,7 +1142,7 @@ void Convolution::processSamples (const AudioBlock<const float>& input, AudioBlo for (size_t channel = 0; channel < numChannels; ++channel) volumeDry[channel].applyGain (dry.getChannelPointer (channel), (int) numSamples); - pimpl->processSamples (input, output); + processWet (input, output); for (size_t channel = 0; channel < numChannels; ++channel) volumeWet[channel].applyGain (output.getChannelPointer (channel), (int) numSamples); @@ -1227,7 +1152,7 @@ void Convolution::processSamples (const AudioBlock<const float>& input, AudioBlo else { if (! currentIsBypassed) - pimpl->processSamples (input, output); + processWet (input, output); if (isBypassed != currentIsBypassed) { @@ -1247,5 +1172,105 @@ void Convolution::processSamples (const AudioBlock<const float>& input, AudioBlo } } +void Convolution::Mixer::reset() { dryBlock.clear(); } + +//============================================================================== +Convolution::Convolution() + : Convolution (Latency { 0 }) +{} + +Convolution::Convolution (ConvolutionMessageQueue& queue) + : Convolution (Latency { 0 }, queue) +{} + +Convolution::Convolution (const Latency& requiredLatency) + : Convolution (requiredLatency, + {}, + OptionalQueue { std::make_unique<ConvolutionMessageQueue>() }) +{} + +Convolution::Convolution (const NonUniform& nonUniform) + : Convolution ({}, + nonUniform, + OptionalQueue { std::make_unique<ConvolutionMessageQueue>() }) +{} + +Convolution::Convolution (const Latency& requiredLatency, ConvolutionMessageQueue& queue) + : Convolution (requiredLatency, {}, OptionalQueue { queue }) +{} + +Convolution::Convolution (const NonUniform& nonUniform, ConvolutionMessageQueue& queue) + : Convolution ({}, nonUniform, OptionalQueue { queue }) +{} + +Convolution::Convolution (const Latency& latency, + const NonUniform& nonUniform, + OptionalQueue&& queue) + : pimpl (std::make_unique<Impl> (latency, nonUniform, std::move (queue))) +{} + +Convolution::~Convolution() noexcept = default; + +void Convolution::loadImpulseResponse (const void* sourceData, + size_t sourceDataSize, + Stereo stereo, + Trim trim, + size_t size, + Normalise normalise) +{ + pimpl->loadImpulseResponse (sourceData, sourceDataSize, stereo, trim, size, normalise); +} + +void Convolution::loadImpulseResponse (const File& fileImpulseResponse, + Stereo stereo, + Trim trim, + size_t size, + Normalise normalise) +{ + pimpl->loadImpulseResponse (fileImpulseResponse, stereo, trim, size, normalise); +} + +void Convolution::loadImpulseResponse (AudioBuffer<float>&& buffer, + double originalSampleRate, + Stereo stereo, + Trim trim, + Normalise normalise) +{ + pimpl->loadImpulseResponse (std::move (buffer), originalSampleRate, stereo, trim, normalise); +} + +void Convolution::prepare (const ProcessSpec& spec) +{ + mixer.prepare (spec); + pimpl->prepare (spec); + isActive = true; +} + +void Convolution::reset() noexcept +{ + mixer.reset(); + pimpl->reset(); +} + +void Convolution::processSamples (const AudioBlock<const float>& input, + AudioBlock<float>& output, + bool isBypassed) noexcept +{ + if (! isActive) + return; + + jassert (input.getNumChannels() == output.getNumChannels()); + jassert (isPositiveAndBelow (input.getNumChannels(), static_cast<size_t> (3))); // only mono and stereo is supported + + mixer.processSamples (input, output, isBypassed, [this] (const auto& in, auto& out) + { + pimpl->processSamples (in, out); + }); +} + +int Convolution::getCurrentIRSize() const { return pimpl->getCurrentIRSize(); } + +int Convolution::getLatency() const { return pimpl->getLatency(); } + } // namespace dsp } // namespace juce diff --git a/modules/juce_dsp/frequency/juce_Convolution.h b/modules/juce_dsp/frequency/juce_Convolution.h index cdf2fe10..63e36407 100644 --- a/modules/juce_dsp/frequency/juce_Convolution.h +++ b/modules/juce_dsp/frequency/juce_Convolution.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -30,18 +29,73 @@ namespace dsp { /** - Performs stereo uniform-partitioned convolution of an input signal with an - impulse response in the frequency domain, using the juce FFT class. + Used by the Convolution to dispatch engine-update messages on a background + thread. - It provides some thread-safe functions to load impulse responses as well, - from audio files or memory on the fly without any noticeable artefacts, + May be shared between multiple Convolution instances. + + @tags{DSP} +*/ +class JUCE_API ConvolutionMessageQueue +{ +public: + /** Initialises the queue to a default size. + + If your Convolution is updated very frequently, or you are sharing + this queue between multiple Convolutions, consider using the alternative + constructor taking an explicit size argument. + */ + ConvolutionMessageQueue(); + ~ConvolutionMessageQueue() noexcept; + + /** Initialises the queue with the specified number of entries. + + In general, the number of required entries scales with the number + of Convolutions sharing the same Queue, and the frequency of updates + to those Convolutions. + */ + explicit ConvolutionMessageQueue (int numEntries); + + ConvolutionMessageQueue (ConvolutionMessageQueue&&) noexcept; + ConvolutionMessageQueue& operator= (ConvolutionMessageQueue&&) noexcept; + + ConvolutionMessageQueue (const ConvolutionMessageQueue&) = delete; + ConvolutionMessageQueue& operator= (const ConvolutionMessageQueue&) = delete; + +private: + struct Impl; + std::unique_ptr<Impl> pimpl; + + friend class Convolution; +}; + +/** + Performs stereo partitioned convolution of an input signal with an + impulse response in the frequency domain, using the JUCE FFT class. + + This class provides some thread-safe functions to load impulse responses + from audio files or memory on-the-fly without noticeable artefacts, performing resampling and trimming if necessary. - The processing is equivalent to the time domain convolution done in the - class FIRFilter, with a FIRFilter::Coefficients object having as - coefficients the samples of the impulse response. However, it is more - efficient in general to do frequency domain convolution when the size of - the impulse response is higher than 64 samples. + The processing performed by this class is equivalent to the time domain + convolution done in the FIRFilter class, with a FIRFilter::Coefficients + object having the samples of the impulse response as its coefficients. + However, in general it is more efficient to do frequency domain + convolution when the size of the impulse response is 64 samples or + greater. + + Note: The default operation of this class uses zero latency and a uniform + partitioned algorithm. If the impulse response size is large, or if the + algorithm is too CPU intensive, it is possible to use either a fixed + latency version of the algorithm, or a simple non-uniform partitioned + convolution algorithm. + + Threading: It is not safe to interleave calls to the methods of this + class. If you need to load new impulse responses during processing the + `load` calls must be synchronised with `process` calls, which in practice + means making the `load` call from the audio thread. The + `loadImpulseResponse` functions *are* wait-free and are therefore + suitable for use in a realtime context. @see FIRFilter, FIRFilter::Coefficients, FFT @@ -54,117 +108,191 @@ public: /** Initialises an object for performing convolution in the frequency domain. */ Convolution(); - /** Destructor. */ - ~Convolution(); + /** Initialises a convolution engine using a shared background message queue. + + IMPORTANT: the queue *must* remain alive throughout the lifetime of the + Convolution. + */ + explicit Convolution (ConvolutionMessageQueue& queue); + + /** Contains configuration information for a convolution with a fixed latency. */ + struct Latency { int latencyInSamples; }; + + /** Initialises an object for performing convolution with a fixed latency. + + If the requested latency is zero, the actual latency will also be zero. + For requested latencies greater than zero, the actual latency will + always at least as large as the requested latency. Using a fixed + non-zero latency can reduce the CPU consumption of the convolution + algorithm. + + @param requiredLatency the minimum latency + */ + explicit Convolution (const Latency& requiredLatency); + + /** Contains configuration information for a non-uniform convolution. */ + struct NonUniform { int headSizeInSamples; }; + + /** Initialises an object for performing convolution in the frequency domain + using a non-uniform partitioned algorithm. + + A requiredHeadSize of 256 samples or greater will improve the + efficiency of the processing for IR sizes of 4096 samples or greater + (recommended for reverberation IRs). + + @param requiredHeadSize the head IR size for two stage non-uniform + partitioned convolution + */ + explicit Convolution (const NonUniform& requiredHeadSize); + + /** Behaves the same as the constructor taking a single Latency argument, + but with a shared background message queue. + + IMPORTANT: the queue *must* remain alive throughout the lifetime of the + Convolution. + */ + Convolution (const Latency&, ConvolutionMessageQueue&); + + /** Behaves the same as the constructor taking a single NonUniform argument, + but with a shared background message queue. + + IMPORTANT: the queue *must* remain alive throughout the lifetime of the + Convolution. + */ + Convolution (const NonUniform&, ConvolutionMessageQueue&); + + ~Convolution() noexcept; //============================================================================== - /** Must be called before loading any impulse response, to provide to the - convolution the maximumBufferSize to handle, and the sample rate useful for - optional resampling. + /** Must be called before loading any impulse response. This provides the + maximumBufferSize and the sample rate required for any resampling. */ void prepare (const ProcessSpec&); - /** Resets the processing pipeline, ready to start a new stream of data. */ + /** Resets the processing pipeline ready to start a new stream of data. */ void reset() noexcept; - /** Performs the filter operation on the given set of samples, with optional + /** Performs the filter operation on the given set of samples with optional stereo processing. */ - template <typename ProcessContext> + template <typename ProcessContext, + std::enable_if_t<std::is_same<typename ProcessContext::SampleType, float>::value, int> = 0> void process (const ProcessContext& context) noexcept { - static_assert (std::is_same<typename ProcessContext::SampleType, float>::value, - "Convolution engine only supports single precision floating point data"); - processSamples (context.getInputBlock(), context.getOutputBlock(), context.isBypassed); } + //============================================================================== + enum class Stereo { no, yes }; + enum class Trim { no, yes }; + enum class Normalise { no, yes }; + //============================================================================== /** This function loads an impulse response audio file from memory, added in a JUCE project with the Projucer as binary data. It can load any of the audio formats registered in JUCE, and performs some resampling and pre-processing as well if needed. - Note: Obviously, don't try to use this function on float samples, since the - data is supposed to be an audio file in its binary format, and be sure that - the original data is not going to move at all its memory location during the - process !! + Note: Don't try to use this function on float samples, since the data is + expected to be an audio file in its binary format. Be sure that the original + data remains constant throughout the lifetime of the Convolution object, as + the loading process will happen on a background thread once this function has + returned. @param sourceData the block of data to use as the stream's source @param sourceDataSize the number of bytes in the source data block - @param wantsStereo requests to process both stereo channels or only one mono channel - @param wantsTrimming requests to trim the start and the end of the impulse response + @param isStereo selects either stereo or mono + @param requiresTrimming optionally trim the start and the end of the impulse response @param size the expected size for the impulse response after loading, can be - set to 0 for requesting maximum original impulse response size - @param wantsNormalisation requests to normalise the impulse response amplitude + set to 0 to requesting the original impulse response size + @param requiresNormalisation optionally normalise the impulse response amplitude */ void loadImpulseResponse (const void* sourceData, size_t sourceDataSize, - bool wantsStereo, bool wantsTrimming, size_t size, - bool wantsNormalisation = true); + Stereo isStereo, Trim requiresTrimming, size_t size, + Normalise requiresNormalisation = Normalise::yes); - /** This function loads an impulse response from an audio file on any drive. It - can load any of the audio formats registered in JUCE, and performs some - resampling and pre-processing as well if needed. + /** This function loads an impulse response from an audio file. It can load any + of the audio formats registered in JUCE, and performs some resampling and + pre-processing as well if needed. @param fileImpulseResponse the location of the audio file - @param wantsStereo requests to process both stereo channels or only one mono channel - @param wantsTrimming requests to trim the start and the end of the impulse response + @param isStereo selects either stereo or mono + @param requiresTrimming optionally trim the start and the end of the impulse response @param size the expected size for the impulse response after loading, can be - set to 0 for requesting maximum original impulse response size - @param wantsNormalisation requests to normalise the impulse response amplitude + set to 0 to requesting the original impulse response size + @param requiresNormalisation optionally normalise the impulse response amplitude */ void loadImpulseResponse (const File& fileImpulseResponse, - bool wantsStereo, bool wantsTrimming, size_t size, - bool wantsNormalisation = true); + Stereo isStereo, Trim requiresTrimming, size_t size, + Normalise requiresNormalisation = Normalise::yes); - /** This function loads an impulse response from an audio buffer, which is - copied before doing anything else. Performs some resampling and - pre-processing as well if needed. + /** This function loads an impulse response from an audio buffer. + To avoid memory allocation on the audio thread, this function takes + ownership of the buffer passed in. + + If calling this function during processing, make sure that the buffer is + not allocated on the audio thread (be careful of accidental copies!). + If you need to pass arbitrary/generated buffers it's recommended to + create these buffers on a separate thread and to use some wait-free + construct (a lock-free queue or a SpinLock/GenericScopedTryLock combination) + to transfer ownership to the audio thread without allocating. @param buffer the AudioBuffer to use @param bufferSampleRate the sampleRate of the data in the AudioBuffer - @param wantsStereo requests to process both stereo channels or only one mono channel - @param wantsTrimming requests to trim the start and the end of the impulse response - @param wantsNormalisation requests to normalise the impulse response amplitude - @param size the expected size for the impulse response after loading, can be - set to 0 for requesting maximum original impulse response size + @param isStereo selects either stereo or mono + @param requiresTrimming optionally trim the start and the end of the impulse response + @param requiresNormalisation optionally normalise the impulse response amplitude */ - void copyAndLoadImpulseResponseFromBuffer (AudioBuffer<float>& buffer, double bufferSampleRate, - bool wantsStereo, bool wantsTrimming, bool wantsNormalisation, - size_t size); + void loadImpulseResponse (AudioBuffer<float>&& buffer, double bufferSampleRate, + Stereo isStereo, Trim requiresTrimming, Normalise requiresNormalisation); - /** This function loads an impulse response from an audio block, which is - copied before doing anything else. Performs some resampling and - pre-processing as well if needed. + /** This function returns the size of the current IR in samples. */ + int getCurrentIRSize() const; - @param block the AudioBlock to use - @param bufferSampleRate the sampleRate of the data in the AudioBuffer - @param wantsStereo requests to process both stereo channels or only one channel - @param wantsTrimming requests to trim the start and the end of the impulse response - @param wantsNormalisation requests to normalise the impulse response amplitude - @param size the expected size for the impulse response after loading, - -1 for maximum length - */ - void copyAndLoadImpulseResponseFromBlock (AudioBlock<float> block, double bufferSampleRate, - bool wantsStereo, bool wantsTrimming, bool wantsNormalisation, - size_t size); + /** This function returns the current latency of the process in samples. + Note: This is the latency of the convolution engine, not the latency + associated with the current impulse response choice that has to be + considered separately (linear phase filters, for example). + */ + int getLatency() const; private: //============================================================================== - struct Pimpl; - std::unique_ptr<Pimpl> pimpl; + Convolution (const Latency&, + const NonUniform&, + OptionalScopedPointer<ConvolutionMessageQueue>&&); - //============================================================================== void processSamples (const AudioBlock<const float>&, AudioBlock<float>&, bool isBypassed) noexcept; + class Mixer + { + public: + void prepare (const ProcessSpec&); + + template <typename ProcessWet> + void processSamples (const AudioBlock<const float>&, + AudioBlock<float>&, + bool isBypassed, + ProcessWet&&) noexcept; + + void reset(); + + private: + std::array<SmoothedValue<float>, 2> volumeDry, volumeWet; + AudioBlock<float> dryBlock; + HeapBlock<char> dryBlockStorage; + double sampleRate = 0; + bool currentIsBypassed = false; + }; + + //============================================================================== + class Impl; + std::unique_ptr<Impl> pimpl; + //============================================================================== - double sampleRate; - bool currentIsBypassed = false; + Mixer mixer; bool isActive = false; - SmoothedValue<float> volumeDry[2], volumeWet[2]; - AudioBlock<float> dryBuffer; - HeapBlock<char> dryBufferStorage; //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Convolution) diff --git a/modules/juce_dsp/frequency/juce_Convolution_test.cpp b/modules/juce_dsp/frequency/juce_Convolution_test.cpp new file mode 100644 index 00000000..d7ec4b81 --- /dev/null +++ b/modules/juce_dsp/frequency/juce_Convolution_test.cpp @@ -0,0 +1,521 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +#if JUCE_ENABLE_ALLOCATION_HOOKS +#define JUCE_FAIL_ON_ALLOCATION_IN_SCOPE const UnitTestAllocationChecker checker (*this) +#else +#define JUCE_FAIL_ON_ALLOCATION_IN_SCOPE +#endif + +namespace juce +{ +namespace dsp +{ +namespace +{ + +class ConvolutionTest : public UnitTest +{ + template <typename Callback> + static void nTimes (int n, Callback&& callback) + { + for (auto i = 0; i < n; ++i) + callback(); + } + + static AudioBuffer<float> makeRamp (int length) + { + AudioBuffer<float> result (1, length); + result.clear(); + + const auto writePtr = result.getWritePointer (0); + std::fill (writePtr, writePtr + length, 1.0f); + result.applyGainRamp (0, length, 1.0f, 0.0f); + + return result; + } + + static AudioBuffer<float> makeStereoRamp (int length) + { + AudioBuffer<float> result (2, length); + result.clear(); + + auto** channels = result.getArrayOfWritePointers(); + std::for_each (channels, channels + result.getNumChannels(), [length] (auto* channel) + { + std::fill (channel, channel + length, 1.0f); + }); + + result.applyGainRamp (0, 0, length, 1.0f, 0.0f); + result.applyGainRamp (1, 0, length, 0.0f, 1.0f); + + return result; + } + + static void addDiracImpulse (const AudioBlock<float>& block) + { + block.clear(); + + for (size_t channel = 0; channel != block.getNumChannels(); ++channel) + block.setSample ((int) channel, 0, 1.0f); + } + + void checkForNans (const AudioBlock<float>& block) + { + for (size_t channel = 0; channel != block.getNumChannels(); ++channel) + for (size_t sample = 0; sample != block.getNumSamples(); ++sample) + expect (! std::isnan (block.getSample ((int) channel, (int) sample))); + } + + template <typename T> + void nonAllocatingExpectWithinAbsoluteError (const T& a, const T& b, const T& error) + { + expect (std::abs (a - b) < error); + } + + enum class InitSequence { prepareThenLoad, loadThenPrepare }; + + void checkLatency (const Convolution& convolution, const Convolution::Latency& latency) + { + const auto reportedLatency = convolution.getLatency(); + + if (latency.latencyInSamples == 0) + expect (reportedLatency == 0); + + expect (reportedLatency >= latency.latencyInSamples); + } + + void checkLatency (const Convolution&, const Convolution::NonUniform&) {} + + template <typename ConvolutionConfig> + void testConvolution (const ProcessSpec& spec, + const ConvolutionConfig& config, + const AudioBuffer<float>& ir, + double irSampleRate, + Convolution::Stereo stereo, + Convolution::Trim trim, + Convolution::Normalise normalise, + const AudioBlock<const float>& expectedResult, + InitSequence initSequence) + { + AudioBuffer<float> buffer (static_cast<int> (spec.numChannels), + static_cast<int> (spec.maximumBlockSize)); + AudioBlock<float> block { buffer }; + ProcessContextReplacing<float> context { block }; + + const auto numBlocksPerSecond = (int) std::ceil (spec.sampleRate / spec.maximumBlockSize); + const auto numBlocksForImpulse = (int) std::ceil ((double) expectedResult.getNumSamples() / spec.maximumBlockSize); + + AudioBuffer<float> outBuffer (static_cast<int> (spec.numChannels), + numBlocksForImpulse * static_cast<int> (spec.maximumBlockSize)); + + Convolution convolution (config); + + auto copiedIr = ir; + + if (initSequence == InitSequence::loadThenPrepare) + convolution.loadImpulseResponse (std::move (copiedIr), irSampleRate, stereo, trim, normalise); + + convolution.prepare (spec); + + JUCE_FAIL_ON_ALLOCATION_IN_SCOPE; + + if (initSequence == InitSequence::prepareThenLoad) + convolution.loadImpulseResponse (std::move (copiedIr), irSampleRate, stereo, trim, normalise); + + checkLatency (convolution, config); + + auto processBlocksWithDiracImpulse = [&] + { + for (auto i = 0; i != numBlocksForImpulse; ++i) + { + if (i == 0) + addDiracImpulse (block); + else + block.clear(); + + convolution.process (context); + + for (auto c = 0; c != static_cast<int> (spec.numChannels); ++c) + { + outBuffer.copyFrom (c, + i * static_cast<int> (spec.maximumBlockSize), + block.getChannelPointer (static_cast<size_t> (c)), + static_cast<int> (spec.maximumBlockSize)); + } + } + }; + + const auto time = Time::getMillisecondCounter(); + + // Wait 10 seconds to load the impulse response + while (Time::getMillisecondCounter() - time < 10'000) + { + processBlocksWithDiracImpulse(); + + // Check if the impulse response was loaded + if (block.getSample (0, 1) != 0.0f) + break; + } + + // At this point, our convolution should be loaded and the current IR size should + // match the expected result size + expect (convolution.getCurrentIRSize() == static_cast<int> (expectedResult.getNumSamples())); + + // Make sure we get any smoothing out of the way + nTimes (numBlocksPerSecond, processBlocksWithDiracImpulse); + + nTimes (5, [&] + { + processBlocksWithDiracImpulse(); + + const auto actualLatency = static_cast<size_t> (convolution.getLatency()); + + // The output should be the same as the IR + for (size_t c = 0; c != static_cast<size_t> (expectedResult.getNumChannels()); ++c) + { + for (size_t i = 0; i != static_cast<size_t> (expectedResult.getNumSamples()); ++i) + { + const auto equivalentSample = i + actualLatency; + + if (static_cast<int> (equivalentSample) >= outBuffer.getNumSamples()) + continue; + + nonAllocatingExpectWithinAbsoluteError (outBuffer.getSample ((int) c, (int) equivalentSample), + expectedResult.getSample ((int) c, (int) i), + 0.01f); + } + } + }); + } + + template <typename ConvolutionConfig> + void testConvolution (const ProcessSpec& spec, + const ConvolutionConfig& config, + const AudioBuffer<float>& ir, + double irSampleRate, + Convolution::Stereo stereo, + Convolution::Trim trim, + Convolution::Normalise normalise, + const AudioBlock<const float>& expectedResult) + { + for (const auto sequence : { InitSequence::prepareThenLoad, InitSequence::loadThenPrepare }) + testConvolution (spec, config, ir, irSampleRate, stereo, trim, normalise, expectedResult, sequence); + } + +public: + ConvolutionTest() + : UnitTest ("Convolution", UnitTestCategories::dsp) + {} + + void runTest() override + { + const ProcessSpec spec { 44100.0, 512, 2 }; + AudioBuffer<float> buffer (static_cast<int> (spec.numChannels), + static_cast<int> (spec.maximumBlockSize)); + AudioBlock<float> block { buffer }; + ProcessContextReplacing<float> context { block }; + + const auto impulseData = [] + { + Random random; + AudioBuffer<float> result (2, 1000); + + for (auto channel = 0; channel != result.getNumChannels(); ++channel) + for (auto sample = 0; sample != result.getNumSamples(); ++sample) + result.setSample (channel, sample, random.nextFloat()); + + return result; + }(); + + beginTest ("Impulse responses can be loaded without allocating on the audio thread"); + { + Convolution convolution; + convolution.prepare (spec); + + auto copy = impulseData; + + JUCE_FAIL_ON_ALLOCATION_IN_SCOPE; + + nTimes (100, [&] + { + convolution.loadImpulseResponse (std::move (copy), + 1000, + Convolution::Stereo::yes, + Convolution::Trim::yes, + Convolution::Normalise::no); + addDiracImpulse (block); + convolution.process (context); + checkForNans (block); + }); + } + + beginTest ("Convolution can be reset without allocating on the audio thread"); + { + Convolution convolution; + convolution.prepare (spec); + + auto copy = impulseData; + + convolution.loadImpulseResponse (std::move (copy), + 1000, + Convolution::Stereo::yes, + Convolution::Trim::yes, + Convolution::Normalise::yes); + + JUCE_FAIL_ON_ALLOCATION_IN_SCOPE; + + nTimes (100, [&] + { + addDiracImpulse (block); + convolution.reset(); + convolution.process (context); + convolution.reset(); + }); + + checkForNans (block); + } + + beginTest ("Completely empty IRs don't crash"); + { + AudioBuffer<float> emptyBuffer; + + Convolution convolution; + convolution.prepare (spec); + + auto copy = impulseData; + + convolution.loadImpulseResponse (std::move (copy), + 2000, + Convolution::Stereo::yes, + Convolution::Trim::yes, + Convolution::Normalise::yes); + + JUCE_FAIL_ON_ALLOCATION_IN_SCOPE; + + nTimes (100, [&] + { + addDiracImpulse (block); + convolution.reset(); + convolution.process (context); + convolution.reset(); + }); + + checkForNans (block); + } + + beginTest ("Short uniform convolutions work"); + { + const auto ramp = makeRamp (static_cast<int> (spec.maximumBlockSize) / 2); + testConvolution (spec, + Convolution::Latency { 0 }, + ramp, + spec.sampleRate, + Convolution::Stereo::yes, + Convolution::Trim::yes, + Convolution::Normalise::no, + ramp); + } + + beginTest ("Longer uniform convolutions work"); + { + const auto ramp = makeRamp (static_cast<int> (spec.maximumBlockSize) * 8); + testConvolution (spec, + Convolution::Latency { 0 }, + ramp, + spec.sampleRate, + Convolution::Stereo::yes, + Convolution::Trim::yes, + Convolution::Normalise::no, + ramp); + } + + beginTest ("Normalisation works"); + { + const auto ramp = makeRamp (static_cast<int> (spec.maximumBlockSize) * 8); + + auto copy = ramp; + const auto channels = copy.getArrayOfWritePointers(); + const auto numChannels = copy.getNumChannels(); + const auto numSamples = copy.getNumSamples(); + + const auto factor = 0.125f / std::sqrt (std::accumulate (channels, channels + numChannels, 0.0f, + [numSamples] (auto max, auto* channel) + { + return juce::jmax (max, std::accumulate (channel, channel + numSamples, 0.0f, + [] (auto sum, auto sample) + { + return sum + sample * sample; + })); + })); + + std::for_each (channels, channels + numChannels, [factor, numSamples] (auto* channel) + { + FloatVectorOperations::multiply (channel, factor, numSamples); + }); + + testConvolution (spec, + Convolution::Latency { 0 }, + ramp, + spec.sampleRate, + Convolution::Stereo::yes, + Convolution::Trim::yes, + Convolution::Normalise::yes, + copy); + } + + beginTest ("Stereo convolutions work"); + { + const auto ramp = makeStereoRamp (static_cast<int> (spec.maximumBlockSize) * 5); + testConvolution (spec, + Convolution::Latency { 0 }, + ramp, + spec.sampleRate, + Convolution::Stereo::yes, + Convolution::Trim::yes, + Convolution::Normalise::no, + ramp); + } + + beginTest ("Stereo IRs only use first channel if stereo is disabled"); + { + const auto length = static_cast<int> (spec.maximumBlockSize) * 5; + const auto ramp = makeStereoRamp (length); + + const float* channels[] { ramp.getReadPointer (0), ramp.getReadPointer (0) }; + + testConvolution (spec, + Convolution::Latency { 0 }, + ramp, + spec.sampleRate, + Convolution::Stereo::no, + Convolution::Trim::yes, + Convolution::Normalise::no, + AudioBlock<const float> (channels, numElementsInArray (channels), length)); + } + + beginTest ("IRs with extra silence are trimmed appropriately"); + { + const auto length = static_cast<int> (spec.maximumBlockSize) * 3; + const auto ramp = makeRamp (length); + AudioBuffer<float> paddedRamp (ramp.getNumChannels(), ramp.getNumSamples() * 2); + paddedRamp.clear(); + + const auto offset = (paddedRamp.getNumSamples() - ramp.getNumSamples()) / 2; + + for (auto channel = 0; channel != ramp.getNumChannels(); ++channel) + paddedRamp.copyFrom (channel, offset, ramp.getReadPointer (channel), length); + + testConvolution (spec, + Convolution::Latency { 0 }, + paddedRamp, + spec.sampleRate, + Convolution::Stereo::no, + Convolution::Trim::yes, + Convolution::Normalise::no, + ramp); + } + + beginTest ("IRs are resampled if their sample rate is different to the playback rate"); + { + for (const auto resampleRatio : { 0.1, 0.5, 2.0, 10.0 }) + { + const auto length = static_cast<int> (spec.maximumBlockSize) * 2; + const auto ramp = makeStereoRamp (length); + + const auto resampled = [&] + { + AudioBuffer<float> original = ramp; + MemoryAudioSource memorySource (original, false); + ResamplingAudioSource resamplingSource (&memorySource, false, original.getNumChannels()); + + const auto finalSize = roundToInt (original.getNumSamples() / resampleRatio); + resamplingSource.setResamplingRatio (resampleRatio); + resamplingSource.prepareToPlay (finalSize, spec.sampleRate * resampleRatio); + + AudioBuffer<float> result (original.getNumChannels(), finalSize); + resamplingSource.getNextAudioBlock ({ &result, 0, result.getNumSamples() }); + return result; + }(); + + testConvolution (spec, + Convolution::Latency { 0 }, + ramp, + spec.sampleRate * resampleRatio, + Convolution::Stereo::yes, + Convolution::Trim::yes, + Convolution::Normalise::no, + resampled); + } + } + + beginTest ("Non-uniform convolutions work"); + { + const auto ramp = makeRamp (static_cast<int> (spec.maximumBlockSize) * 8); + + for (auto headSize : { spec.maximumBlockSize / 2, spec.maximumBlockSize, spec.maximumBlockSize * 9 }) + { + testConvolution (spec, + Convolution::NonUniform { static_cast<int> (headSize) }, + ramp, + spec.sampleRate, + Convolution::Stereo::yes, + Convolution::Trim::yes, + Convolution::Normalise::no, + ramp); + } + } + + beginTest ("Convolutions with latency work"); + { + const auto ramp = makeRamp (static_cast<int> (spec.maximumBlockSize) * 8); + using BlockSize = decltype (spec.maximumBlockSize); + + for (auto latency : { /*static_cast<BlockSize> (0), + spec.maximumBlockSize / 3, + spec.maximumBlockSize, + spec.maximumBlockSize * 2, */ + static_cast<BlockSize> (spec.maximumBlockSize * 2.5) }) + { + testConvolution (spec, + Convolution::Latency { static_cast<int> (latency) }, + ramp, + spec.sampleRate, + Convolution::Stereo::yes, + Convolution::Trim::yes, + Convolution::Normalise::no, + ramp); + } + } + } +}; + +ConvolutionTest convolutionUnitTest; + +} +} +} + +#undef JUCE_FAIL_ON_ALLOCATION_IN_SCOPE diff --git a/modules/juce_dsp/frequency/juce_FFT.cpp b/modules/juce_dsp/frequency/juce_FFT.cpp index 9c47ab24..3d0c608a 100644 --- a/modules/juce_dsp/frequency/juce_FFT.cpp +++ b/modules/juce_dsp/frequency/juce_FFT.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -31,7 +30,7 @@ namespace dsp struct FFT::Instance { - virtual ~Instance() {} + virtual ~Instance() = default; virtual void perform (const Complex<float>* input, Complex<float>* output, bool inverse) const noexcept = 0; virtual void performRealOnlyForwardTransform (float*, bool) const noexcept = 0; virtual void performRealOnlyInverseTransform (float*) const noexcept = 0; @@ -46,7 +45,7 @@ struct FFT::Engine std::sort (list.begin(), list.end(), [] (Engine* a, Engine* b) { return b->enginePriority < a->enginePriority; }); } - virtual ~Engine() {} + virtual ~Engine() = default; virtual FFT::Instance* create (int order) const = 0; @@ -114,7 +113,7 @@ struct FFTFallback : public FFT::Instance { configInverse->perform (input, output); - const float scaleFactor = 1.0f / size; + const float scaleFactor = 1.0f / (float) size; for (int i = 0; i < size; ++i) output[i] *= scaleFactor; @@ -141,7 +140,7 @@ struct FFTFallback : public FFT::Instance else { HeapBlock<char> heapSpace (scratchSize); - performRealOnlyForwardTransform (reinterpret_cast<Complex<float>*> (heapSpace.getData()), d); + performRealOnlyForwardTransform (unalignedPointerCast<Complex<float>*> (heapSpace.getData()), d); } } @@ -159,7 +158,7 @@ struct FFTFallback : public FFT::Instance else { HeapBlock<char> heapSpace (scratchSize); - performRealOnlyInverseTransform (reinterpret_cast<Complex<float>*> (heapSpace.getData()), d); + performRealOnlyInverseTransform (unalignedPointerCast<Complex<float>*> (heapSpace.getData()), d); } } @@ -175,7 +174,7 @@ struct FFTFallback : public FFT::Instance { auto* input = reinterpret_cast<Complex<float>*> (d); - for (auto i = size >> 1; i < size; ++i) + for (int i = size >> 1; i < size; ++i) input[i] = std::conj (input[size - i]); perform (input, scratch, true); @@ -689,7 +688,7 @@ struct FFTWImpl : public FFT::Instance auto size = (1 << order); if (! ignoreNegativeFreqs) - for (auto i = size >> 1; i < size; ++i) + for (int i = size >> 1; i < size; ++i) out[i] = std::conj (out[size - i]); } @@ -788,7 +787,7 @@ struct IntelFFT : public FFT::Instance auto size = (1 << order); if (! ignoreNegativeFreqs) - for (auto i = size >> 1; i < size; ++i) + for (int i = size >> 1; i < size; ++i) out[i] = std::conj (out[size - i]); } @@ -804,6 +803,145 @@ struct IntelFFT : public FFT::Instance FFT::EngineImpl<IntelFFT> fftwEngine; #endif +//============================================================================== +//============================================================================== +// Visual Studio should define no more than one of these, depending on the +// setting at 'Project' > 'Properties' > 'Configuration Properties' > 'Intel +// Performance Libraries' > 'Use Intel(R) IPP' +#if _IPP_SEQUENTIAL_STATIC || _IPP_SEQUENTIAL_DYNAMIC || _IPP_PARALLEL_STATIC || _IPP_PARALLEL_DYNAMIC +class IntelPerformancePrimitivesFFT : public FFT::Instance +{ +public: + static constexpr auto priority = 9; + + static IntelPerformancePrimitivesFFT* create (const int order) + { + auto complexContext = Context<ComplexTraits>::create (order); + auto realContext = Context<RealTraits> ::create (order); + + if (complexContext.isValid() && realContext.isValid()) + return new IntelPerformancePrimitivesFFT (std::move (complexContext), std::move (realContext), order); + + return {}; + } + + void perform (const Complex<float>* input, Complex<float>* output, bool inverse) const noexcept override + { + if (inverse) + { + ippsFFTInv_CToC_32fc (reinterpret_cast<const Ipp32fc*> (input), + reinterpret_cast<Ipp32fc*> (output), + cplx.specPtr, + cplx.workBuf.get()); + } + else + { + ippsFFTFwd_CToC_32fc (reinterpret_cast<const Ipp32fc*> (input), + reinterpret_cast<Ipp32fc*> (output), + cplx.specPtr, + cplx.workBuf.get()); + } + } + + void performRealOnlyForwardTransform (float* inoutData, bool ignoreNegativeFreqs) const noexcept override + { + ippsFFTFwd_RToCCS_32f_I (inoutData, real.specPtr, real.workBuf.get()); + + if (order == 0) + return; + + auto* out = reinterpret_cast<Complex<float>*> (inoutData); + const auto size = (1 << order); + + if (! ignoreNegativeFreqs) + for (auto i = size >> 1; i < size; ++i) + out[i] = std::conj (out[size - i]); + } + + void performRealOnlyInverseTransform (float* inoutData) const noexcept override + { + ippsFFTInv_CCSToR_32f_I (inoutData, real.specPtr, real.workBuf.get()); + } + +private: + static constexpr auto flag = IPP_FFT_DIV_INV_BY_N; + static constexpr auto hint = ippAlgHintFast; + + struct IppFree + { + template <typename Ptr> + void operator() (Ptr* ptr) const noexcept { ippsFree (ptr); } + }; + + using IppPtr = std::unique_ptr<Ipp8u[], IppFree>; + + template <typename Traits> + struct Context + { + using SpecPtr = typename Traits::Spec*; + + static Context create (const int order) + { + int specSize = 0, initSize = 0, workSize = 0; + + if (Traits::getSize (order, flag, hint, &specSize, &initSize, &workSize) != ippStsNoErr) + return {}; + + const auto initBuf = IppPtr (ippsMalloc_8u (initSize)); + auto specBuf = IppPtr (ippsMalloc_8u (specSize)); + SpecPtr specPtr = nullptr; + + if (Traits::init (&specPtr, order, flag, hint, specBuf.get(), initBuf.get()) != ippStsNoErr) + return {}; + + if (reinterpret_cast<const Ipp8u*> (specPtr) != specBuf.get()) + return {}; + + return { std::move (specBuf), IppPtr (ippsMalloc_8u (workSize)), specPtr }; + } + + Context() noexcept = default; + + Context (IppPtr&& spec, IppPtr&& work, typename Traits::Spec* ptr) noexcept + : specBuf (std::move (spec)), workBuf (std::move (work)), specPtr (ptr) + {} + + bool isValid() const noexcept { return specPtr != nullptr; } + + IppPtr specBuf, workBuf; + SpecPtr specPtr = nullptr; + }; + + struct ComplexTraits + { + static constexpr auto getSize = ippsFFTGetSize_C_32fc; + static constexpr auto init = ippsFFTInit_C_32fc; + using Spec = IppsFFTSpec_C_32fc; + }; + + struct RealTraits + { + static constexpr auto getSize = ippsFFTGetSize_R_32f; + static constexpr auto init = ippsFFTInit_R_32f; + using Spec = IppsFFTSpec_R_32f; + }; + + IntelPerformancePrimitivesFFT (Context<ComplexTraits>&& complexToUse, + Context<RealTraits>&& realToUse, + const int orderToUse) + : cplx (std::move (complexToUse)), + real (std::move (realToUse)), + order (orderToUse) + {} + + Context<ComplexTraits> cplx; + Context<RealTraits> real; + int order = 0; +}; + +FFT::EngineImpl<IntelPerformancePrimitivesFFT> intelPerformancePrimitivesFFT; +#endif + //============================================================================== //============================================================================== FFT::FFT (int order) @@ -840,7 +978,7 @@ void FFT::performFrequencyOnlyForwardTransform (float* inputOutputData) const no performRealOnlyForwardTransform (inputOutputData); auto* out = reinterpret_cast<Complex<float>*> (inputOutputData); - for (auto i = 0; i < size; ++i) + for (int i = 0; i < size; ++i) inputOutputData[i] = std::abs (out[i]); zeromem (&inputOutputData[size], static_cast<size_t> (size) * sizeof (float)); diff --git a/modules/juce_dsp/frequency/juce_FFT.h b/modules/juce_dsp/frequency/juce_FFT.h index 883af17b..30ac0f81 100644 --- a/modules/juce_dsp/frequency/juce_FFT.h +++ b/modules/juce_dsp/frequency/juce_FFT.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_dsp/frequency/juce_FFT_test.cpp b/modules/juce_dsp/frequency/juce_FFT_test.cpp index 8fd9b9c5..5befd3d2 100644 --- a/modules/juce_dsp/frequency/juce_FFT_test.cpp +++ b/modules/juce_dsp/frequency/juce_FFT_test.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_dsp/frequency/juce_Windowing.cpp b/modules/juce_dsp/frequency/juce_Windowing.cpp index 6a2c62e3..13097817 100644 --- a/modules/juce_dsp/frequency/juce_Windowing.cpp +++ b/modules/juce_dsp/frequency/juce_Windowing.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -30,7 +29,7 @@ namespace dsp { template <typename FloatType> -static inline FloatType ncos (size_t order, size_t i, size_t size) noexcept +static FloatType ncos (size_t order, size_t i, size_t size) noexcept { return std::cos (static_cast<FloatType> (order * i) * MathConstants<FloatType>::pi / static_cast<FloatType> (size - 1)); @@ -137,14 +136,16 @@ void WindowingFunction<FloatType>::fillWindowingTables (FloatType* samples, size case kaiser: { const double factor = 1.0 / SpecialFunctions::besselI0 (beta); + const auto doubleSize = (double) size; for (size_t i = 0; i < size; ++i) - samples[i] = static_cast<FloatType> (SpecialFunctions::besselI0 (beta * std::sqrt (1.0 - std::pow ((i - 0.5 * (size - 1.0)) - / ( 0.5 * (size - 1.0)), 2.0))) + samples[i] = static_cast<FloatType> (SpecialFunctions::besselI0 (beta * std::sqrt (1.0 - std::pow (((double) i - 0.5 * (doubleSize - 1.0)) + / ( 0.5 * (doubleSize - 1.0)), 2.0))) * factor); } break; + case numWindowingMethods: default: jassertfalse; break; @@ -175,15 +176,16 @@ const char* WindowingFunction<FloatType>::getWindowingMethodName (WindowingMetho { switch (type) { - case rectangular: return "Rectangular"; - case triangular: return "Triangular"; - case hann: return "Hann"; - case hamming: return "Hamming"; - case blackman: return "Blackman"; - case blackmanHarris: return "Blackman-Harris"; - case flatTop: return "Flat Top"; - case kaiser: return "Kaiser"; - default: jassertfalse; return ""; + case rectangular: return "Rectangular"; + case triangular: return "Triangular"; + case hann: return "Hann"; + case hamming: return "Hamming"; + case blackman: return "Blackman"; + case blackmanHarris: return "Blackman-Harris"; + case flatTop: return "Flat Top"; + case kaiser: return "Kaiser"; + case numWindowingMethods: + default: jassertfalse; return ""; } } diff --git a/modules/juce_dsp/frequency/juce_Windowing.h b/modules/juce_dsp/frequency/juce_Windowing.h index 1c6be2d1..2aca0ad2 100644 --- a/modules/juce_dsp/frequency/juce_Windowing.h +++ b/modules/juce_dsp/frequency/juce_Windowing.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_dsp/juce_dsp.cpp b/modules/juce_dsp/juce_dsp.cpp index 0d61a417..9e297f03 100644 --- a/modules/juce_dsp/juce_dsp.cpp +++ b/modules/juce_dsp/juce_dsp.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -35,12 +34,6 @@ #include "juce_dsp.h" -#if ! JUCE_HAS_CONSTEXPR - #ifndef JUCE_DEMO_RUNNER - #error "The juce_dsp module requires a compiler that supports constexpr" - #endif -#else - #ifndef JUCE_USE_VDSP_FRAMEWORK #define JUCE_USE_VDSP_FRAMEWORK 1 #endif @@ -55,10 +48,24 @@ #include <mkl_dfti.h> #endif +#if _IPP_SEQUENTIAL_STATIC || _IPP_SEQUENTIAL_DYNAMIC || _IPP_PARALLEL_STATIC || _IPP_PARALLEL_DYNAMIC + #include <ippcore.h> + #include <ipps.h> + #define JUCE_IPP_AVAILABLE 1 +#endif + +#include "containers/juce_FixedSizeFunction.h" + #include "processors/juce_FIRFilter.cpp" #include "processors/juce_IIRFilter.cpp" -#include "processors/juce_LadderFilter.cpp" +#include "processors/juce_FirstOrderTPTFilter.cpp" +#include "processors/juce_Panner.cpp" #include "processors/juce_Oversampling.cpp" +#include "processors/juce_BallisticsFilter.cpp" +#include "processors/juce_LinkwitzRileyFilter.cpp" +#include "processors/juce_DelayLine.cpp" +#include "processors/juce_DryWetMixer.cpp" +#include "processors/juce_StateVariableTPTFilter.cpp" #include "maths/juce_SpecialFunctions.cpp" #include "maths/juce_Matrix.cpp" #include "maths/juce_LookupTable.cpp" @@ -66,6 +73,12 @@ #include "frequency/juce_Convolution.cpp" #include "frequency/juce_Windowing.cpp" #include "filter_design/juce_FilterDesign.cpp" +#include "widgets/juce_LadderFilter.cpp" +#include "widgets/juce_Compressor.cpp" +#include "widgets/juce_NoiseGate.cpp" +#include "widgets/juce_Limiter.cpp" +#include "widgets/juce_Phaser.cpp" +#include "widgets/juce_Chorus.cpp" #if JUCE_USE_SIMD #if defined(__i386__) || defined(__amd64__) || defined(_M_X64) || defined(_X86_) || defined(_M_IX86) @@ -90,8 +103,9 @@ #endif #include "containers/juce_AudioBlock_test.cpp" + #include "containers/juce_FixedSizeFunction_test.cpp" + #include "frequency/juce_Convolution_test.cpp" #include "frequency/juce_FFT_test.cpp" #include "processors/juce_FIRFilter_test.cpp" -#endif - + #include "processors/juce_ProcessorChain_test.cpp" #endif diff --git a/modules/juce_dsp/juce_dsp.h b/modules/juce_dsp/juce_dsp.h index 84f68c96..060494d3 100644 --- a/modules/juce_dsp/juce_dsp.h +++ b/modules/juce_dsp/juce_dsp.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -29,21 +28,21 @@ The block below describes the properties of this module, and is read by the Projucer to automatically generate project code that uses it. For details about the syntax and how to create or use a module, see the - JUCE Module Format.txt file. + JUCE Module Format.md file. BEGIN_JUCE_MODULE_DECLARATION ID: juce_dsp vendor: juce - version: 5.4.7 + version: 6.0.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 license: GPL/Commercial minimumCppStandard: 14 - dependencies: juce_audio_basics, juce_audio_formats + dependencies: juce_audio_formats OSXFrameworks: Accelerate iOSFrameworks: Accelerate @@ -59,12 +58,6 @@ #include <juce_audio_basics/juce_audio_basics.h> #include <juce_audio_formats/juce_audio_formats.h> -#if ! JUCE_HAS_CONSTEXPR - #ifndef JUCE_DEMO_RUNNER - #error "The juce_dsp module requires a compiler that supports constexpr" - #endif -#else - #if defined(_M_X64) || defined(__amd64__) || defined(__SSE2__) || (defined(_M_IX86_FP) && _M_IX86_FP == 2) #if defined(_M_X64) || defined(__amd64__) @@ -108,10 +101,7 @@ #endif #endif -#include <atomic> #include <complex> -#include <cmath> -#include <array> //============================================================================== @@ -257,19 +247,29 @@ namespace juce #include "processors/juce_ProcessorWrapper.h" #include "processors/juce_ProcessorChain.h" #include "processors/juce_ProcessorDuplicator.h" -#include "processors/juce_Bias.h" -#include "processors/juce_Gain.h" -#include "processors/juce_WaveShaper.h" #include "processors/juce_IIRFilter.h" #include "processors/juce_FIRFilter.h" -#include "processors/juce_Oscillator.h" -#include "processors/juce_LadderFilter.h" #include "processors/juce_StateVariableFilter.h" +#include "processors/juce_FirstOrderTPTFilter.h" +#include "processors/juce_Panner.h" +#include "processors/juce_DelayLine.h" #include "processors/juce_Oversampling.h" -#include "processors/juce_Reverb.h" +#include "processors/juce_BallisticsFilter.h" +#include "processors/juce_LinkwitzRileyFilter.h" +#include "processors/juce_DryWetMixer.h" +#include "processors/juce_StateVariableTPTFilter.h" #include "frequency/juce_FFT.h" #include "frequency/juce_Convolution.h" #include "frequency/juce_Windowing.h" #include "filter_design/juce_FilterDesign.h" - -#endif +#include "widgets/juce_Reverb.h" +#include "widgets/juce_Bias.h" +#include "widgets/juce_Gain.h" +#include "widgets/juce_WaveShaper.h" +#include "widgets/juce_Oscillator.h" +#include "widgets/juce_LadderFilter.h" +#include "widgets/juce_Compressor.h" +#include "widgets/juce_NoiseGate.h" +#include "widgets/juce_Limiter.h" +#include "widgets/juce_Phaser.h" +#include "widgets/juce_Chorus.h" diff --git a/modules/juce_dsp/juce_dsp.mm b/modules/juce_dsp/juce_dsp.mm index 7fe73444..9dc9631b 100644 --- a/modules/juce_dsp/juce_dsp.mm +++ b/modules/juce_dsp/juce_dsp.mm @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_dsp/maths/juce_FastMathApproximations.h b/modules/juce_dsp/maths/juce_FastMathApproximations.h index 22f26d95..818f6083 100644 --- a/modules/juce_dsp/maths/juce_FastMathApproximations.h +++ b/modules/juce_dsp/maths/juce_FastMathApproximations.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_dsp/maths/juce_LogRampedValue.h b/modules/juce_dsp/maths/juce_LogRampedValue.h index e32aca39..7af97758 100644 --- a/modules/juce_dsp/maths/juce_LogRampedValue.h +++ b/modules/juce_dsp/maths/juce_LogRampedValue.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_dsp/maths/juce_LogRampedValue_test.cpp b/modules/juce_dsp/maths/juce_LogRampedValue_test.cpp index bfe76eb8..a462f459 100644 --- a/modules/juce_dsp/maths/juce_LogRampedValue_test.cpp +++ b/modules/juce_dsp/maths/juce_LogRampedValue_test.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_dsp/maths/juce_LookupTable.cpp b/modules/juce_dsp/maths/juce_LookupTable.cpp index 817b18ad..cbd89b10 100644 --- a/modules/juce_dsp/maths/juce_LookupTable.cpp +++ b/modules/juce_dsp/maths/juce_LookupTable.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -36,7 +35,7 @@ LookupTable<FloatType>::LookupTable() } template <typename FloatType> -LookupTable<FloatType>::LookupTable (const std::function<FloatType(size_t)>& functionToApproximate, +LookupTable<FloatType>::LookupTable (const std::function<FloatType (size_t)>& functionToApproximate, size_t numPointsToUse) { initialise (functionToApproximate, numPointsToUse); @@ -44,7 +43,7 @@ LookupTable<FloatType>::LookupTable (const std::function<FloatType(size_t)>& fun //============================================================================== template <typename FloatType> -void LookupTable<FloatType>::initialise (const std::function<FloatType(size_t)>& functionToApproximate, +void LookupTable<FloatType>::initialise (const std::function<FloatType (size_t)>& functionToApproximate, size_t numPointsToUse) { data.resize (static_cast<int> (getRequiredBufferSize (numPointsToUse))); @@ -72,7 +71,7 @@ void LookupTable<FloatType>::prepare() noexcept } template <typename FloatType> -void LookupTableTransform<FloatType>::initialise (const std::function<FloatType(FloatType)>& functionToApproximate, +void LookupTableTransform<FloatType>::initialise (const std::function<FloatType (FloatType)>& functionToApproximate, FloatType minInputValueToUse, FloatType maxInputValueToUse, size_t numPoints) @@ -98,7 +97,7 @@ void LookupTableTransform<FloatType>::initialise (const std::function<FloatType( //============================================================================== template <typename FloatType> -double LookupTableTransform<FloatType>::calculateMaxRelativeError (const std::function<FloatType(FloatType)>& functionToApproximate, +double LookupTableTransform<FloatType>::calculateMaxRelativeError (const std::function<FloatType (FloatType)>& functionToApproximate, FloatType minInputValue, FloatType maxInputValue, size_t numPoints, diff --git a/modules/juce_dsp/maths/juce_LookupTable.h b/modules/juce_dsp/maths/juce_LookupTable.h index 88baf488..5ef84e20 100644 --- a/modules/juce_dsp/maths/juce_LookupTable.h +++ b/modules/juce_dsp/maths/juce_LookupTable.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -68,7 +67,7 @@ public: mapping from the integer range [0, numPointsToUse - 1]. @param numPointsToUse The number of pre-calculated values stored. */ - LookupTable (const std::function<FloatType(size_t)>& functionToApproximate, size_t numPointsToUse); + LookupTable (const std::function<FloatType (size_t)>& functionToApproximate, size_t numPointsToUse); /** Initialises or changes the parameters of a LookupTable object. @@ -80,7 +79,7 @@ public: mapping from the integer range [0, numPointsToUse - 1]. @param numPointsToUse The number of pre-calculated values stored. */ - void initialise (const std::function<FloatType(size_t)>& functionToApproximate, size_t numPointsToUse); + void initialise (const std::function<FloatType (size_t)>& functionToApproximate, size_t numPointsToUse); //============================================================================== /** Calculates the approximated value for the given index without range checking. @@ -123,7 +122,7 @@ public: */ FloatType get (FloatType index) const noexcept { - if (index >= getNumPoints()) + if (index >= (FloatType) getNumPoints()) index = static_cast<FloatType> (getGuardIndex()); else if (index < 0) index = {}; @@ -196,7 +195,7 @@ public: fail for values higher than this. @param numPoints The number of pre-calculated values stored. */ - LookupTableTransform (const std::function<FloatType(FloatType)>& functionToApproximate, + LookupTableTransform (const std::function<FloatType (FloatType)>& functionToApproximate, FloatType minInputValueToUse, FloatType maxInputValueToUse, size_t numPoints) @@ -215,7 +214,7 @@ public: fail for values higher than this. @param numPoints The number of pre-calculated values stored. */ - void initialise (const std::function<FloatType(FloatType)>& functionToApproximate, + void initialise (const std::function<FloatType (FloatType)>& functionToApproximate, FloatType minInputValueToUse, FloatType maxInputValueToUse, size_t numPoints); @@ -309,7 +308,7 @@ public: accuracy of the error calculation. If it's zero then 100 * numPoints will be used. */ - static double calculateMaxRelativeError (const std::function<FloatType(FloatType)>& functionToApproximate, + static double calculateMaxRelativeError (const std::function<FloatType (FloatType)>& functionToApproximate, FloatType minInputValue, FloatType maxInputValue, size_t numPoints, diff --git a/modules/juce_dsp/maths/juce_Matrix.cpp b/modules/juce_dsp/maths/juce_Matrix.cpp index 03b7a31f..84a51a18 100644 --- a/modules/juce_dsp/maths/juce_Matrix.cpp +++ b/modules/juce_dsp/maths/juce_Matrix.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_dsp/maths/juce_Matrix.h b/modules/juce_dsp/maths/juce_Matrix.h index ba33d7a7..8d6f43ab 100644 --- a/modules/juce_dsp/maths/juce_Matrix.h +++ b/modules/juce_dsp/maths/juce_Matrix.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -165,7 +164,7 @@ public: inline Matrix& hadarmard (const Matrix& other) noexcept { return apply (other, [] (ElementType a, ElementType b) { return a * b; } ); } /** Does a hadarmard product with a and b returns the result. */ - static inline Matrix hadarmard (const Matrix& a, const Matrix& b) { Matrix result (a); result.hadarmard (b); return result; } + static Matrix hadarmard (const Matrix& a, const Matrix& b) { Matrix result (a); result.hadarmard (b); return result; } //============================================================================== /** Compare to matrices with a given tolerance */ diff --git a/modules/juce_dsp/maths/juce_Matrix_test.cpp b/modules/juce_dsp/maths/juce_Matrix_test.cpp index 79815bd0..4a15a71a 100644 --- a/modules/juce_dsp/maths/juce_Matrix_test.cpp +++ b/modules/juce_dsp/maths/juce_Matrix_test.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_dsp/maths/juce_Phase.h b/modules/juce_dsp/maths/juce_Phase.h index b44bf7e9..4d593632 100644 --- a/modules/juce_dsp/maths/juce_Phase.h +++ b/modules/juce_dsp/maths/juce_Phase.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_dsp/maths/juce_Polynomial.h b/modules/juce_dsp/maths/juce_Polynomial.h index fb5ccbfd..e9ad836b 100644 --- a/modules/juce_dsp/maths/juce_Polynomial.h +++ b/modules/juce_dsp/maths/juce_Polynomial.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_dsp/maths/juce_SpecialFunctions.cpp b/modules/juce_dsp/maths/juce_SpecialFunctions.cpp index ac799743..5373bf52 100644 --- a/modules/juce_dsp/maths/juce_SpecialFunctions.cpp +++ b/modules/juce_dsp/maths/juce_SpecialFunctions.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_dsp/maths/juce_SpecialFunctions.h b/modules/juce_dsp/maths/juce_SpecialFunctions.h index 9a0291e2..7ed4e916 100644 --- a/modules/juce_dsp/maths/juce_SpecialFunctions.h +++ b/modules/juce_dsp/maths/juce_SpecialFunctions.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_dsp/native/juce_avx_SIMDNativeOps.cpp b/modules/juce_dsp/native/juce_avx_SIMDNativeOps.cpp index 25d47499..2f87732c 100644 --- a/modules/juce_dsp/native/juce_avx_SIMDNativeOps.cpp +++ b/modules/juce_dsp/native/juce_avx_SIMDNativeOps.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_dsp/native/juce_avx_SIMDNativeOps.h b/modules/juce_dsp/native/juce_avx_SIMDNativeOps.h index 270660b4..e51a4d81 100644 --- a/modules/juce_dsp/native/juce_avx_SIMDNativeOps.h +++ b/modules/juce_dsp/native/juce_avx_SIMDNativeOps.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -31,10 +30,7 @@ namespace dsp #ifndef DOXYGEN -#if JUCE_GCC && (__GNUC__ >= 6) - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wignored-attributes" -#endif +JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wignored-attributes") #ifdef _MSC_VER #define DECLARE_AVX_SIMD_CONST(type, name) \ @@ -659,9 +655,7 @@ struct SIMDNativeOps<uint64_t> #endif -#if JUCE_GCC && (__GNUC__ >= 6) - #pragma GCC diagnostic pop -#endif +JUCE_END_IGNORE_WARNINGS_GCC_LIKE } // namespace dsp } // namespace juce diff --git a/modules/juce_dsp/native/juce_fallback_SIMDNativeOps.h b/modules/juce_dsp/native/juce_fallback_SIMDNativeOps.h index e45b32e6..5c71495e 100644 --- a/modules/juce_dsp/native/juce_fallback_SIMDNativeOps.h +++ b/modules/juce_dsp/native/juce_fallback_SIMDNativeOps.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -115,7 +114,7 @@ struct SIMDFallbackOps auto retval = static_cast<ScalarType> (0); for (size_t i = 0; i < n; ++i) - retval += a.s[i]; + retval = static_cast<ScalarType> (retval + a.s[i]); return retval; } diff --git a/modules/juce_dsp/native/juce_neon_SIMDNativeOps.cpp b/modules/juce_dsp/native/juce_neon_SIMDNativeOps.cpp index 81935453..1219ed88 100644 --- a/modules/juce_dsp/native/juce_neon_SIMDNativeOps.cpp +++ b/modules/juce_dsp/native/juce_neon_SIMDNativeOps.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_dsp/native/juce_neon_SIMDNativeOps.h b/modules/juce_dsp/native/juce_neon_SIMDNativeOps.h index 4fc4997e..09188925 100644 --- a/modules/juce_dsp/native/juce_neon_SIMDNativeOps.h +++ b/modules/juce_dsp/native/juce_neon_SIMDNativeOps.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -31,10 +30,7 @@ namespace dsp #ifndef DOXYGEN -#if JUCE_GCC && (__GNUC__ >= 6) - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wignored-attributes" -#endif +JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wignored-attributes") #ifdef _MSC_VER #define DECLARE_NEON_SIMD_CONST(type, name) \ @@ -499,9 +495,7 @@ struct SIMDNativeOps<double> #endif -#if JUCE_GCC && (__GNUC__ >= 6) - #pragma GCC diagnostic pop -#endif +JUCE_END_IGNORE_WARNINGS_GCC_LIKE } // namespace dsp } // namespace juce diff --git a/modules/juce_dsp/native/juce_sse_SIMDNativeOps.cpp b/modules/juce_dsp/native/juce_sse_SIMDNativeOps.cpp index e1292312..1aade96f 100644 --- a/modules/juce_dsp/native/juce_sse_SIMDNativeOps.cpp +++ b/modules/juce_dsp/native/juce_sse_SIMDNativeOps.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_dsp/native/juce_sse_SIMDNativeOps.h b/modules/juce_dsp/native/juce_sse_SIMDNativeOps.h index afe32e69..7f64d433 100644 --- a/modules/juce_dsp/native/juce_sse_SIMDNativeOps.h +++ b/modules/juce_dsp/native/juce_sse_SIMDNativeOps.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -31,10 +30,7 @@ namespace dsp #ifndef DOXYGEN -#if JUCE_GCC && (__GNUC__ >= 6) - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wignored-attributes" -#endif +JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wignored-attributes") #ifdef _MSC_VER #define DECLARE_SSE_SIMD_CONST(type, name) \ @@ -727,9 +723,7 @@ struct SIMDNativeOps<uint64_t> #endif -#if JUCE_GCC && (__GNUC__ >= 6) - #pragma GCC diagnostic pop -#endif +JUCE_END_IGNORE_WARNINGS_GCC_LIKE } // namespace dsp } // namespace juce diff --git a/modules/juce_dsp/processors/juce_BallisticsFilter.cpp b/modules/juce_dsp/processors/juce_BallisticsFilter.cpp new file mode 100644 index 00000000..e9fcf5ee --- /dev/null +++ b/modules/juce_dsp/processors/juce_BallisticsFilter.cpp @@ -0,0 +1,130 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +//============================================================================== +template <typename SampleType> +BallisticsFilter<SampleType>::BallisticsFilter() +{ + setAttackTime (attackTime); + setReleaseTime (releaseTime); +} + +template <typename SampleType> +void BallisticsFilter<SampleType>::setAttackTime (SampleType attackTimeMs) +{ + attackTime = attackTimeMs; + cteAT = calculateLimitedCte (static_cast<SampleType> (attackTime)); +} + +template <typename SampleType> +void BallisticsFilter<SampleType>::setReleaseTime (SampleType releaseTimeMs) +{ + releaseTime = releaseTimeMs; + cteRL = calculateLimitedCte (static_cast<SampleType> (releaseTime)); +} + +template <typename SampleType> +void BallisticsFilter<SampleType>::setLevelCalculationType (LevelCalculationType newLevelType) +{ + levelType = newLevelType; + reset(); +} + +template <typename SampleType> +void BallisticsFilter<SampleType>::prepare (const ProcessSpec& spec) +{ + jassert (spec.sampleRate > 0); + jassert (spec.numChannels > 0); + + sampleRate = spec.sampleRate; + expFactor = -2.0 * MathConstants<double>::pi * 1000.0 / sampleRate; + + setAttackTime (attackTime); + setReleaseTime (releaseTime); + + yold.resize (spec.numChannels); + + reset(); +} + +template <typename SampleType> +void BallisticsFilter<SampleType>::reset() +{ + reset (0); +} + +template <typename SampleType> +void BallisticsFilter<SampleType>::reset (SampleType initialValue) +{ + for (auto& old : yold) + old = initialValue; +} + +template <typename SampleType> +SampleType BallisticsFilter<SampleType>::processSample (int channel, SampleType inputValue) +{ + jassert (isPositiveAndBelow (channel, yold.size())); + + if (levelType == LevelCalculationType::RMS) + inputValue *= inputValue; + else + inputValue = std::abs (inputValue); + + SampleType cte = (inputValue > yold[(size_t) channel] ? cteAT : cteRL); + + SampleType result = inputValue + cte * (yold[(size_t) channel] - inputValue); + yold[(size_t) channel] = result; + + if (levelType == LevelCalculationType::RMS) + return std::sqrt (result); + + return result; +} + +template <typename SampleType> +void BallisticsFilter<SampleType>::snapToZero() noexcept +{ + for (auto& old : yold) + util::snapToZero (old); +} + +template <typename SampleType> +SampleType BallisticsFilter<SampleType>::calculateLimitedCte (SampleType timeMs) const noexcept +{ + return timeMs < static_cast<SampleType> (1.0e-3) ? 0 + : static_cast<SampleType> (std::exp (expFactor / timeMs)); +} + +//============================================================================== +template class BallisticsFilter<float>; +template class BallisticsFilter<double>; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/processors/juce_BallisticsFilter.h b/modules/juce_dsp/processors/juce_BallisticsFilter.h new file mode 100644 index 00000000..07e23af9 --- /dev/null +++ b/modules/juce_dsp/processors/juce_BallisticsFilter.h @@ -0,0 +1,150 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +enum class BallisticsFilterLevelCalculationType +{ + peak, + RMS +}; + +/** + A processor to apply standard attack / release ballistics to an input signal. + This is useful in dynamics processors, envelope followers, modulated audio + effects and for smoothing animation in data visualisation. + + @tags{DSP} +*/ +template <typename SampleType> +class BallisticsFilter +{ +public: + //============================================================================== + using LevelCalculationType = BallisticsFilterLevelCalculationType; + + //============================================================================== + /** Constructor. */ + BallisticsFilter(); + + //============================================================================== + /** Sets the attack time in ms. + + Attack times less than 0.001 ms will be snapped to zero and very long attack + times will eventually saturate depending on the numerical precision used. + */ + void setAttackTime (SampleType attackTimeMs); + + /** Sets the release time in ms. + + Release times less than 0.001 ms will be snapped to zero and very long + release times will eventually saturate depending on the numerical precision + used. + */ + void setReleaseTime (SampleType releaseTimeMs); + + /** Sets how the filter levels are calculated. + + Level calculation in digital envelope followers is usually performed using + peak detection with a rectifier function (like std::abs) and filtering, + which returns an envelope dependant on the peak or maximum values of the + signal amplitude. + + To perform an estimation of the average value of the signal you can use + an RMS (root mean squared) implementation of the ballistics filter instead. + This is useful in some compressor and noise-gate designs, or in specific + types of volume meters. + */ + void setLevelCalculationType (LevelCalculationType newCalculationType); + + //============================================================================== + /** Initialises the filter. */ + void prepare (const ProcessSpec& spec); + + /** Resets the internal state variables of the filter. */ + void reset(); + + /** Resets the internal state variables of the filter to the given initial value. */ + void reset (SampleType initialValue); + + //============================================================================== + /** Processes the input and output samples supplied in the processing context. */ + template <typename ProcessContext> + void process (const ProcessContext& context) noexcept + { + const auto& inputBlock = context.getInputBlock(); + auto& outputBlock = context.getOutputBlock(); + const auto numChannels = outputBlock.getNumChannels(); + const auto numSamples = outputBlock.getNumSamples(); + + jassert (inputBlock.getNumChannels() <= yold.size()); + jassert (inputBlock.getNumChannels() == numChannels); + jassert (inputBlock.getNumSamples() == numSamples); + + if (context.isBypassed) + { + outputBlock.copyFrom (inputBlock); + return; + } + + for (size_t channel = 0; channel < numChannels; ++channel) + { + auto* inputSamples = inputBlock .getChannelPointer (channel); + auto* outputSamples = outputBlock.getChannelPointer (channel); + + for (size_t i = 0; i < numSamples; ++i) + outputSamples[i] = processSample ((int) channel, inputSamples[i]); + } + + #if JUCE_SNAP_TO_ZERO + snapToZero(); + #endif + } + + /** Processes one sample at a time on a given channel. */ + SampleType processSample (int channel, SampleType inputValue); + + /** Ensure that the state variables are rounded to zero if the state + variables are denormals. This is only needed if you are doing + sample by sample processing. + */ + void snapToZero() noexcept; + +private: + //============================================================================== + SampleType calculateLimitedCte (SampleType) const noexcept; + + //============================================================================== + std::vector<SampleType> yold; + double sampleRate = 44100.0, expFactor = -0.142; + SampleType attackTime = 1.0, releaseTime = 100.0, cteAT = 0.0, cteRL = 0.0; + LevelCalculationType levelType = LevelCalculationType::peak; +}; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/processors/juce_DelayLine.cpp b/modules/juce_dsp/processors/juce_DelayLine.cpp new file mode 100644 index 00000000..f3479907 --- /dev/null +++ b/modules/juce_dsp/processors/juce_DelayLine.cpp @@ -0,0 +1,128 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +//============================================================================== +template <typename SampleType, typename InterpolationType> +DelayLine<SampleType, InterpolationType>::DelayLine() + : DelayLine (0) +{ +} + +template <typename SampleType, typename InterpolationType> +DelayLine<SampleType, InterpolationType>::DelayLine (int maximumDelayInSamples) +{ + jassert (maximumDelayInSamples >= 0); + + totalSize = jmax (4, maximumDelayInSamples + 1); + sampleRate = 44100.0; +} + +//============================================================================== +template <typename SampleType, typename InterpolationType> +void DelayLine<SampleType, InterpolationType>::setDelay (SampleType newDelayInSamples) +{ + auto upperLimit = (SampleType) (totalSize - 1); + jassert (isPositiveAndNotGreaterThan (newDelayInSamples, upperLimit)); + + delay = jlimit ((SampleType) 0, upperLimit, newDelayInSamples); + delayInt = static_cast<int> (std::floor (delay)); + delayFrac = delay - (SampleType) delayInt; + + updateInternalVariables(); +} + +template <typename SampleType, typename InterpolationType> +SampleType DelayLine<SampleType, InterpolationType>::getDelay() const +{ + return delay; +} + +//============================================================================== +template <typename SampleType, typename InterpolationType> +void DelayLine<SampleType, InterpolationType>::prepare (const ProcessSpec& spec) +{ + jassert (spec.numChannels > 0); + + bufferData.setSize ((int) spec.numChannels, totalSize, false, false, true); + + writePos.resize (spec.numChannels); + readPos.resize (spec.numChannels); + + v.resize (spec.numChannels); + sampleRate = spec.sampleRate; + + reset(); +} + +template <typename SampleType, typename InterpolationType> +void DelayLine<SampleType, InterpolationType>::reset() +{ + for (auto vec : { &writePos, &readPos }) + std::fill (vec->begin(), vec->end(), 0); + + std::fill (v.begin(), v.end(), static_cast<SampleType> (0)); + + bufferData.clear(); +} + +//============================================================================== +template <typename SampleType, typename InterpolationType> +void DelayLine<SampleType, InterpolationType>::pushSample (int channel, SampleType sample) +{ + bufferData.setSample (channel, writePos[(size_t) channel], sample); + writePos[(size_t) channel] = (writePos[(size_t) channel] + totalSize - 1) % totalSize; +} + +template <typename SampleType, typename InterpolationType> +SampleType DelayLine<SampleType, InterpolationType>::popSample (int channel, SampleType delayInSamples, bool updateReadPointer) +{ + if (delayInSamples >= 0) + setDelay(delayInSamples); + + auto result = interpolateSample (channel); + + if (updateReadPointer) + readPos[(size_t) channel] = (readPos[(size_t) channel] + totalSize - 1) % totalSize; + + return result; +} + +//============================================================================== +template class DelayLine<float, DelayLineInterpolationTypes::None>; +template class DelayLine<double, DelayLineInterpolationTypes::None>; +template class DelayLine<float, DelayLineInterpolationTypes::Linear>; +template class DelayLine<double, DelayLineInterpolationTypes::Linear>; +template class DelayLine<float, DelayLineInterpolationTypes::Lagrange3rd>; +template class DelayLine<double, DelayLineInterpolationTypes::Lagrange3rd>; +template class DelayLine<float, DelayLineInterpolationTypes::Thiran>; +template class DelayLine<double, DelayLineInterpolationTypes::Thiran>; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/processors/juce_DelayLine.h b/modules/juce_dsp/processors/juce_DelayLine.h new file mode 100644 index 00000000..00950b72 --- /dev/null +++ b/modules/juce_dsp/processors/juce_DelayLine.h @@ -0,0 +1,324 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +//============================================================================== +/** + A collection of structs to pass as the template argument when setting the + interpolation type for the DelayLine class. +*/ +namespace DelayLineInterpolationTypes +{ + /** + No interpolation between successive samples in the delay line will be + performed. This is useful when the delay is a constant integer or to + create lo-fi audio effects. + + @tags{DSP} + */ + struct None {}; + + /** + Successive samples in the delay line will be linearly interpolated. This + type of interpolation has a low compuational cost where the delay can be + modulated in real time, but it also introduces a low-pass filtering effect + into your audio signal. + + @tags{DSP} + */ + struct Linear {}; + + /** + Successive samples in the delay line will be interpolated using a 3rd order + Lagrange interpolator. This method incurs more computational overhead than + linear interpolation but reduces the low-pass filtering effect whilst + remaining amenable to real time delay modulation. + + @tags{DSP} + */ + struct Lagrange3rd {}; + + /** + Successive samples in the delay line will be interpolated using 1st order + Thiran interpolation. This method is very efficient, and features a flat + amplitude frequency response in exchange for less accuracy in the phase + response. This interpolation method is stateful so is unsuitable for + applications requiring fast delay modulation. + + @tags{DSP} + */ + struct Thiran {}; +} + +//============================================================================== +/** + A delay line processor featuring several algorithms for the fractional delay + calculation, block processing, and sample-by-sample processing useful when + modulating the delay in real time or creating a standard delay effect with + feedback. + + Note: If you intend to change the delay in real time, you may want to smooth + changes to the delay systematically using either a ramp or a low-pass filter. + + @see SmoothedValue, FirstOrderTPTFilter + + @tags{DSP} +*/ +template <typename SampleType, typename InterpolationType = DelayLineInterpolationTypes::Linear> +class DelayLine +{ +public: + //============================================================================== + /** Default constructor. */ + DelayLine(); + + /** Constructor. */ + explicit DelayLine (int maximumDelayInSamples); + + //============================================================================== + /** Sets the delay in samples. */ + void setDelay (SampleType newDelayInSamples); + + /** Returns the current delay in samples. */ + SampleType getDelay() const; + + //============================================================================== + /** Initialises the processor. */ + void prepare (const ProcessSpec& spec); + + /** Resets the internal state variables of the processor. */ + void reset(); + + //============================================================================== + /** Pushes a single sample into one channel of the delay line. + + Use this function and popSample instead of process if you need to modulate + the delay in real time instead of using a fixed delay value, or if you want + to code a delay effect with a feedback loop. + + @see setDelay, popSample, process + */ + void pushSample (int channel, SampleType sample); + + /** Pops a single sample from one channel of the delay line. + + Use this function to modulate the delay in real time or implement standard + delay effects with feedback. + + @param channel the target channel for the delay line. + + @param delayInSamples sets the wanted fractional delay in samples, or -1 + to use the value being used before or set with + setDelay function. + + @param updateReadPointer should be set to true if you use the function + once for each sample, or false if you need + multi-tap delay capabilities. + + @see setDelay, pushSample, process + */ + SampleType popSample (int channel, SampleType delayInSamples = -1, bool updateReadPointer = true); + + //============================================================================== + /** Processes the input and output samples supplied in the processing context. + + Can be used for block processing when the delay is not going to change + during processing. The delay must first be set by calling setDelay. + + @see setDelay + */ + template <typename ProcessContext> + void process (const ProcessContext& context) noexcept + { + const auto& inputBlock = context.getInputBlock(); + auto& outputBlock = context.getOutputBlock(); + const auto numChannels = outputBlock.getNumChannels(); + const auto numSamples = outputBlock.getNumSamples(); + + jassert (inputBlock.getNumChannels() == numChannels); + jassert (inputBlock.getNumChannels() == writePos.size()); + jassert (inputBlock.getNumSamples() == numSamples); + + if (context.isBypassed) + { + outputBlock.copyFrom (inputBlock); + return; + } + + for (size_t channel = 0; channel < numChannels; ++channel) + { + auto* inputSamples = inputBlock.getChannelPointer (channel); + auto* outputSamples = outputBlock.getChannelPointer (channel); + + for (size_t i = 0; i < numSamples; ++i) + { + pushSample ((int) channel, inputSamples[i]); + outputSamples[i] = popSample ((int) channel); + } + } + } + +private: + //============================================================================== + template <typename T = InterpolationType> + typename std::enable_if <std::is_same <T, DelayLineInterpolationTypes::None>::value, SampleType>::type + interpolateSample (int channel) const + { + auto index = (readPos[(size_t) channel] + delayInt) % totalSize; + return bufferData.getSample (channel, index); + } + + template <typename T = InterpolationType> + typename std::enable_if <std::is_same <T, DelayLineInterpolationTypes::Linear>::value, SampleType>::type + interpolateSample (int channel) const + { + auto index1 = readPos[(size_t) channel] + delayInt; + auto index2 = index1 + 1; + + if (index2 >= totalSize) + { + index1 %= totalSize; + index2 %= totalSize; + } + + auto value1 = bufferData.getSample (channel, index1); + auto value2 = bufferData.getSample (channel, index2); + + return value1 + delayFrac * (value2 - value1); + } + + template <typename T = InterpolationType> + typename std::enable_if <std::is_same <T, DelayLineInterpolationTypes::Lagrange3rd>::value, SampleType>::type + interpolateSample (int channel) const + { + auto index1 = readPos[(size_t) channel] + delayInt; + auto index2 = index1 + 1; + auto index3 = index2 + 1; + auto index4 = index3 + 1; + + if (index4 >= totalSize) + { + index1 %= totalSize; + index2 %= totalSize; + index3 %= totalSize; + index4 %= totalSize; + } + + auto* samples = bufferData.getReadPointer (channel); + + auto value1 = samples[index1]; + auto value2 = samples[index2]; + auto value3 = samples[index3]; + auto value4 = samples[index4]; + + auto d1 = delayFrac - 1.f; + auto d2 = delayFrac - 2.f; + auto d3 = delayFrac - 3.f; + + auto c1 = -d1 * d2 * d3 / 6.f; + auto c2 = d2 * d3 * 0.5f; + auto c3 = -d1 * d3 * 0.5f; + auto c4 = d1 * d2 / 6.f; + + return value1 * c1 + delayFrac * (value2 * c2 + value3 * c3 + value4 * c4); + } + + template <typename T = InterpolationType> + typename std::enable_if <std::is_same <T, DelayLineInterpolationTypes::Thiran>::value, SampleType>::type + interpolateSample (int channel) + { + auto index1 = readPos[(size_t) channel] + delayInt; + auto index2 = index1 + 1; + + if (index2 >= totalSize) + { + index1 %= totalSize; + index2 %= totalSize; + } + + auto value1 = bufferData.getSample (channel, index1); + auto value2 = bufferData.getSample (channel, index2); + + auto output = delayFrac == 0 ? value1 : value2 + alpha * (value1 - v[(size_t) channel]); + v[(size_t) channel] = output; + + return output; + } + + //============================================================================== + template <typename T = InterpolationType> + typename std::enable_if <std::is_same <T, DelayLineInterpolationTypes::None>::value, void>::type + updateInternalVariables() + { + } + + template <typename T = InterpolationType> + typename std::enable_if <std::is_same <T, DelayLineInterpolationTypes::Linear>::value, void>::type + updateInternalVariables() + { + } + + template <typename T = InterpolationType> + typename std::enable_if <std::is_same <T, DelayLineInterpolationTypes::Lagrange3rd>::value, void>::type + updateInternalVariables() + { + if (delayInt >= 1) + { + delayFrac++; + delayInt--; + } + } + + template <typename T = InterpolationType> + typename std::enable_if <std::is_same <T, DelayLineInterpolationTypes::Thiran>::value, void>::type + updateInternalVariables() + { + if (delayFrac < (SampleType) 0.618 && delayInt >= 1) + { + delayFrac++; + delayInt--; + } + + alpha = (1 - delayFrac) / (1 + delayFrac); + } + + //============================================================================== + double sampleRate; + + //============================================================================== + AudioBuffer<SampleType> bufferData; + std::vector<SampleType> v; + std::vector<int> writePos, readPos; + SampleType delay = 0.0, delayFrac = 0.0; + int delayInt = 0, totalSize = 4; + SampleType alpha = 0.0; +}; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/processors/juce_DryWetMixer.cpp b/modules/juce_dsp/processors/juce_DryWetMixer.cpp new file mode 100644 index 00000000..21455d86 --- /dev/null +++ b/modules/juce_dsp/processors/juce_DryWetMixer.cpp @@ -0,0 +1,179 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +//============================================================================== +template <typename SampleType> +DryWetMixer<SampleType>::DryWetMixer() + : DryWetMixer (0) +{ +} + +template <typename SampleType> +DryWetMixer<SampleType>::DryWetMixer (int maximumWetLatencyInSamples) + : dryDelayLine (maximumWetLatencyInSamples) +{ + dryDelayLine.setDelay (0); + + update(); + reset(); +} + +//============================================================================== +template <typename SampleType> +void DryWetMixer<SampleType>::setMixingRule (MixingRule newRule) +{ + currentMixingRule = newRule; + update(); +} + +template <typename SampleType> +void DryWetMixer<SampleType>::setWetMixProportion (SampleType newWetMixProportion) +{ + jassert (isPositiveAndNotGreaterThan (newWetMixProportion, 1.0)); + + mix = jlimit (static_cast<SampleType> (0.0), static_cast<SampleType> (1.0), newWetMixProportion); + update(); +} + +template <typename SampleType> +void DryWetMixer<SampleType>::setWetLatency (SampleType wetLatencySamples) +{ + dryDelayLine.setDelay (wetLatencySamples); +} + +//============================================================================== +template <typename SampleType> +void DryWetMixer<SampleType>::prepare (const ProcessSpec& spec) +{ + jassert (spec.sampleRate > 0); + jassert (spec.numChannels > 0); + + sampleRate = spec.sampleRate; + + dryDelayLine.prepare (spec); + bufferDry.setSize ((int) spec.numChannels, (int) spec.maximumBlockSize, false, false, true); + + update(); + reset(); +} + +template <typename SampleType> +void DryWetMixer<SampleType>::reset() +{ + dryVolume.reset (sampleRate, 0.05); + wetVolume.reset (sampleRate, 0.05); + + dryDelayLine.reset(); +} + +//============================================================================== +template <typename SampleType> +void DryWetMixer<SampleType>::pushDrySamples (const AudioBlock<const SampleType> drySamples) +{ + jassert (drySamples.getNumChannels() <= (size_t) bufferDry.getNumChannels()); + + auto dryBlock = AudioBlock<SampleType> (bufferDry); + dryBlock = dryBlock.getSubsetChannelBlock (0, drySamples.getNumChannels()).getSubBlock (0, drySamples.getNumSamples()); + + auto context = ProcessContextNonReplacing<SampleType>(drySamples, dryBlock); + dryDelayLine.process (context); +} + +template <typename SampleType> +void DryWetMixer<SampleType>::mixWetSamples (AudioBlock<SampleType> inOutBlock) +{ + auto dryBlock = AudioBlock<SampleType> (bufferDry); + dryBlock = dryBlock.getSubsetChannelBlock (0, inOutBlock.getNumChannels()).getSubBlock (0, inOutBlock.getNumSamples()); + + dryBlock.multiplyBy (dryVolume); + inOutBlock.multiplyBy (wetVolume); + + inOutBlock.add (dryBlock); +} + +//============================================================================== +template <typename SampleType> +void DryWetMixer<SampleType>::update() +{ + SampleType dryValue, wetValue; + + switch (currentMixingRule) + { + case MixingRule::balanced: + dryValue = static_cast<SampleType> (2.0) * jmin (static_cast<SampleType> (0.5), static_cast<SampleType> (1.0) - mix); + wetValue = static_cast<SampleType> (2.0) * jmin (static_cast<SampleType> (0.5), mix); + break; + + case MixingRule::linear: + dryValue = static_cast<SampleType> (1.0) - mix; + wetValue = mix; + break; + + case MixingRule::sin3dB: + dryValue = static_cast<SampleType> (std::sin (0.5 * MathConstants<double>::pi * (1.0 - mix))); + wetValue = static_cast<SampleType> (std::sin (0.5 * MathConstants<double>::pi * mix)); + break; + + case MixingRule::sin4p5dB: + dryValue = static_cast<SampleType> (std::pow (std::sin (0.5 * MathConstants<double>::pi * (1.0 - mix)), 1.5)); + wetValue = static_cast<SampleType> (std::pow (std::sin (0.5 * MathConstants<double>::pi * mix), 1.5)); + break; + + case MixingRule::sin6dB: + dryValue = static_cast<SampleType> (std::pow (std::sin (0.5 * MathConstants<double>::pi * (1.0 - mix)), 2.0)); + wetValue = static_cast<SampleType> (std::pow (std::sin (0.5 * MathConstants<double>::pi * mix), 2.0)); + break; + + case MixingRule::squareRoot3dB: + dryValue = std::sqrt (static_cast<SampleType> (1.0) - mix); + wetValue = std::sqrt (mix); + break; + + case MixingRule::squareRoot4p5dB: + dryValue = static_cast<SampleType> (std::pow (std::sqrt (1.0 - mix), 1.5)); + wetValue = static_cast<SampleType> (std::pow (std::sqrt (mix), 1.5)); + break; + + default: + dryValue = jmin (static_cast<SampleType> (0.5), static_cast<SampleType> (1.0) - mix); + wetValue = jmin (static_cast<SampleType> (0.5), mix); + break; + } + + dryVolume.setTargetValue (dryValue); + wetVolume.setTargetValue (wetValue); +} + +//============================================================================== +template class DryWetMixer<float>; +template class DryWetMixer<double>; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/processors/juce_DryWetMixer.h b/modules/juce_dsp/processors/juce_DryWetMixer.h new file mode 100644 index 00000000..f2071501 --- /dev/null +++ b/modules/juce_dsp/processors/juce_DryWetMixer.h @@ -0,0 +1,118 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +enum class DryWetMixingRule +{ + linear, // dry volume is equal to 1 - wet volume + balanced, // both dry and wet are 1 when mix is 0.5, with dry decreasing to 0 + // above this value and wet decreasing to 0 below it + sin3dB, // alternate dry/wet mixing rule using the 3 dB sine panning rule + sin4p5dB, // alternate dry/wet mixing rule using the 4.5 dB sine panning rule + sin6dB, // alternate dry/wet mixing rule using the 6 dB sine panning rule + squareRoot3dB, // alternate dry/wet mixing rule using the regular 3 dB panning rule + squareRoot4p5dB // alternate dry/wet mixing rule using the regular 4.5 dB panning rule +}; + +/** + A processor to handle dry/wet mixing of two audio signals, where the wet signal + may have additional latency. + + Once a DryWetMixer object is configured, push the dry samples using pushDrySamples + and mix into the fully wet samples using mixWetSamples. + + @tags{DSP} +*/ +template <typename SampleType> +class DryWetMixer +{ +public: + //============================================================================== + using MixingRule = DryWetMixingRule; + + //============================================================================== + /** Default constructor. */ + DryWetMixer(); + + /** Constructor. */ + explicit DryWetMixer (int maximumWetLatencyInSamples); + + //============================================================================== + /** Sets the mix rule. */ + void setMixingRule (MixingRule newRule); + + /** Sets the current dry/wet mix proportion, with 0.0 being full dry and 1.0 + being fully wet. + */ + void setWetMixProportion (SampleType newWetMixProportion); + + /** Sets the relative latency of the wet signal path compared to the dry signal + path, and thus the amount of latency compensation that will be added to the + dry samples in this processor. + */ + void setWetLatency (SampleType wetLatencyInSamples); + + //============================================================================== + /** Initialises the processor. */ + void prepare (const ProcessSpec& spec); + + /** Resets the internal state variables of the processor. */ + void reset(); + + //============================================================================== + /** Copies the dry path samples into an internal delay line. */ + void pushDrySamples (const AudioBlock<const SampleType> drySamples); + + /** Mixes the supplied wet samples with the latency-compensated dry samples from + pushDrySamples. + + @param wetSamples Input: The AudioBlock references fully wet samples. + Output: The AudioBlock references the wet samples mixed + with the latency compensated dry samples. + + @see pushDrySamples + */ + void mixWetSamples (AudioBlock<SampleType> wetSamples); + +private: + //============================================================================== + void update(); + + //============================================================================== + SmoothedValue<SampleType, ValueSmoothingTypes::Linear> dryVolume, wetVolume; + DelayLine<SampleType, DelayLineInterpolationTypes::Thiran> dryDelayLine; + AudioBuffer<SampleType> bufferDry; + + SampleType mix = 1.0; + MixingRule currentMixingRule = MixingRule::linear; + double sampleRate = 44100.0; +}; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/processors/juce_FIRFilter.cpp b/modules/juce_dsp/processors/juce_FIRFilter.cpp index b0607783..7dc91f91 100644 --- a/modules/juce_dsp/processors/juce_FIRFilter.cpp +++ b/modules/juce_dsp/processors/juce_FIRFilter.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_dsp/processors/juce_FIRFilter.h b/modules/juce_dsp/processors/juce_FIRFilter.h index 6e1686a6..800eec7b 100644 --- a/modules/juce_dsp/processors/juce_FIRFilter.h +++ b/modules/juce_dsp/processors/juce_FIRFilter.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_dsp/processors/juce_FIRFilter_test.cpp b/modules/juce_dsp/processors/juce_FIRFilter_test.cpp index 33a54615..f139525b 100644 --- a/modules/juce_dsp/processors/juce_FIRFilter_test.cpp +++ b/modules/juce_dsp/processors/juce_FIRFilter_test.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_dsp/processors/juce_FirstOrderTPTFilter.cpp b/modules/juce_dsp/processors/juce_FirstOrderTPTFilter.cpp new file mode 100644 index 00000000..34c351a1 --- /dev/null +++ b/modules/juce_dsp/processors/juce_FirstOrderTPTFilter.cpp @@ -0,0 +1,121 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +//============================================================================== +template <typename SampleType> +FirstOrderTPTFilter<SampleType>::FirstOrderTPTFilter() +{ + update(); +} + +//============================================================================== +template <typename SampleType> +void FirstOrderTPTFilter<SampleType>::setType (Type newValue) +{ + filterType = newValue; +} + +template <typename SampleType> +void FirstOrderTPTFilter<SampleType>::setCutoffFrequency (SampleType newValue) +{ + jassert (isPositiveAndBelow (newValue, static_cast<SampleType> (sampleRate * 0.5))); + + cutoffFrequency = newValue; + update(); +} + +//============================================================================== +template <typename SampleType> +void FirstOrderTPTFilter<SampleType>::prepare (const ProcessSpec& spec) +{ + jassert (spec.sampleRate > 0); + jassert (spec.numChannels > 0); + + sampleRate = spec.sampleRate; + s1.resize (spec.numChannels); + + reset(); +} + +template <typename SampleType> +void FirstOrderTPTFilter<SampleType>::reset() +{ + reset (static_cast<SampleType> (0)); +} + +template <typename SampleType> +void FirstOrderTPTFilter<SampleType>::reset (SampleType newValue) +{ + std::fill (s1.begin(), s1.end(), newValue); +} + +//============================================================================== +template <typename SampleType> +SampleType FirstOrderTPTFilter<SampleType>::processSample (int channel, SampleType inputValue) +{ + auto& s = s1[(size_t) channel]; + + auto v = G * (inputValue - s); + auto y = v + s; + s = y + v; + + switch (filterType) + { + case Type::lowpass: return y; + case Type::highpass: return inputValue - y; + case Type::allpass: return 2 * y - inputValue; + default: break; + } + + jassertfalse; + return y; +} + +template <typename SampleType> +void FirstOrderTPTFilter<SampleType>::snapToZero() noexcept +{ + for (auto& s : s1) + util::snapToZero (s); +} + +//============================================================================== +template <typename SampleType> +void FirstOrderTPTFilter<SampleType>::update() +{ + auto g = SampleType (std::tan (juce::MathConstants<double>::pi * cutoffFrequency / sampleRate)); + G = g / (1 + g); +} + +//============================================================================== +template class FirstOrderTPTFilter<float>; +template class FirstOrderTPTFilter<double>; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/processors/juce_FirstOrderTPTFilter.h b/modules/juce_dsp/processors/juce_FirstOrderTPTFilter.h new file mode 100644 index 00000000..ec366556 --- /dev/null +++ b/modules/juce_dsp/processors/juce_FirstOrderTPTFilter.h @@ -0,0 +1,151 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +enum class FirstOrderTPTFilterType +{ + lowpass, + highpass, + allpass +}; + +//============================================================================== +/** + A first order filter class using the TPT (Topology-Preserving Transform) structure. + + This filter can be modulated at high rates without producing audio artefacts. See + Vadim Zavalishin's documentation about TPT structures for more information. + + Note: Using this class prevents some loud audio artefacts commonly encountered when + changing the cutoff frequency using of other filter simulation structures and IIR + filter classes. However, this class may still require additional smoothing for + cutoff frequency changes. + + see StateVariableFilter, IIRFilter, SmoothedValue + + @tags{DSP} +*/ +template <typename SampleType> +class FirstOrderTPTFilter +{ +public: + //============================================================================== + using Type = FirstOrderTPTFilterType; + + //============================================================================== + /** Constructor. */ + FirstOrderTPTFilter(); + + //============================================================================== + /** Sets the filter type. */ + void setType (Type newType); + + /** Sets the cutoff frequency of the filter. + + @param newFrequencyHz cutoff frequency in Hz. + */ + void setCutoffFrequency (SampleType newFrequencyHz); + + //============================================================================== + /** Returns the type of the filter. */ + Type getType() const noexcept { return filterType; } + + /** Returns the cutoff frequency of the filter. */ + SampleType getCutoffFrequency() const noexcept { return cutoffFrequency; } + + //============================================================================== + /** Initialises the filter. */ + void prepare (const ProcessSpec& spec); + + /** Resets the internal state variables of the filter. */ + void reset(); + + /** Resets the internal state variables of the filter to a given value. */ + void reset (SampleType newValue); + + //============================================================================== + /** Processes the input and output samples supplied in the processing context. */ + template <typename ProcessContext> + void process (const ProcessContext& context) noexcept + { + const auto& inputBlock = context.getInputBlock(); + auto& outputBlock = context.getOutputBlock(); + const auto numChannels = outputBlock.getNumChannels(); + const auto numSamples = outputBlock.getNumSamples(); + + jassert (inputBlock.getNumChannels() <= s1.size()); + jassert (inputBlock.getNumChannels() == numChannels); + jassert (inputBlock.getNumSamples() == numSamples); + + if (context.isBypassed) + { + outputBlock.copyFrom (inputBlock); + return; + } + + for (size_t channel = 0; channel < numChannels; ++channel) + { + auto* inputSamples = inputBlock .getChannelPointer (channel); + auto* outputSamples = outputBlock.getChannelPointer (channel); + + for (size_t i = 0; i < numSamples; ++i) + outputSamples[i] = processSample ((int) channel, inputSamples[i]); + } + + #if JUCE_SNAP_TO_ZERO + snapToZero(); + #endif + } + + //============================================================================== + /** Processes one sample at a time on a given channel. */ + SampleType processSample (int channel, SampleType inputValue); + + /** Ensure that the state variables are rounded to zero if the state + variables are denormals. This is only needed if you are doing + sample by sample processing. + */ + void snapToZero() noexcept; + +private: + //============================================================================== + void update(); + + //============================================================================== + SampleType G = 0; + std::vector<SampleType> s1 { 2 }; + double sampleRate = 44100.0; + + //============================================================================== + Type filterType = Type::lowpass; + SampleType cutoffFrequency = 1000.0; +}; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/processors/juce_IIRFilter.cpp b/modules/juce_dsp/processors/juce_IIRFilter.cpp index 359c5470..59b51fdb 100644 --- a/modules/juce_dsp/processors/juce_IIRFilter.cpp +++ b/modules/juce_dsp/processors/juce_IIRFilter.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_dsp/processors/juce_IIRFilter.h b/modules/juce_dsp/processors/juce_IIRFilter.h index f50999c2..bb05fdba 100644 --- a/modules/juce_dsp/processors/juce_IIRFilter.h +++ b/modules/juce_dsp/processors/juce_IIRFilter.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -94,7 +93,7 @@ namespace IIR Note that this clears the processing state, but the type of filter and its coefficients aren't changed. */ - void reset() { reset (SampleType {0}); } + void reset() { reset (SampleType {0}); } /** Resets the filter's processing pipeline to a specific value. @see reset @@ -113,6 +112,10 @@ namespace IIR processInternal<ProcessContext, true> (context); else processInternal<ProcessContext, false> (context); + + #if JUCE_SNAP_TO_ZERO + snapToZero(); + #endif } /** Processes a single sample, without any locking. diff --git a/modules/juce_dsp/processors/juce_IIRFilter_Impl.h b/modules/juce_dsp/processors/juce_IIRFilter_Impl.h index 37fb2aeb..2cef6014 100644 --- a/modules/juce_dsp/processors/juce_IIRFilter_Impl.h +++ b/modules/juce_dsp/processors/juce_IIRFilter_Impl.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_dsp/processors/juce_LadderFilter.cpp b/modules/juce_dsp/processors/juce_LadderFilter.cpp deleted file mode 100644 index 9829ba8e..00000000 --- a/modules/juce_dsp/processors/juce_LadderFilter.cpp +++ /dev/null @@ -1,170 +0,0 @@ -/* - ============================================================================== - - 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 -{ - -//============================================================================== -template <typename Type> -LadderFilter<Type>::LadderFilter() : state (2) -{ - setSampleRate (Type (1000)); // intentionally setting unrealistic default - // sample rate to catch missing initialisation bugs - setResonance (Type (0)); - setDrive (Type (1.2)); - setMode (Mode::LPF12); -} - -//============================================================================== -template <typename Type> -void LadderFilter<Type>::setMode (Mode newValue) noexcept -{ - switch (newValue) - { - case Mode::LPF12: A = {{ Type (0), Type (0), Type (1), Type (0), Type (0) }}; comp = Type (0.5); break; - case Mode::HPF12: A = {{ Type (1), Type (-2), Type (1), Type (0), Type (0) }}; comp = Type (0); break; - case Mode::LPF24: A = {{ Type (0), Type (0), Type (0), Type (0), Type (1) }}; comp = Type (0.5); break; - case Mode::HPF24: A = {{ Type (1), Type (-4), Type (6), Type (-4), Type (1) }}; comp = Type (0); break; - default: jassertfalse; break; - } - - static constexpr auto outputGain = Type (1.2); - - for (auto& a : A) - a *= outputGain; - - mode = newValue; - reset(); -} - -//============================================================================== -template <typename Type> -void LadderFilter<Type>::prepare (const juce::dsp::ProcessSpec& spec) -{ - setSampleRate (Type (spec.sampleRate)); - setNumChannels (spec.numChannels); - reset(); -} - -//============================================================================== -template <typename Type> -void LadderFilter<Type>::reset() noexcept -{ - for (auto& s : state) - s.fill (Type (0)); - - cutoffTransformSmoother.setCurrentAndTargetValue (cutoffTransformSmoother.getTargetValue()); - scaledResonanceSmoother.setCurrentAndTargetValue (scaledResonanceSmoother.getTargetValue()); -} - -//============================================================================== -template <typename Type> -void LadderFilter<Type>::setCutoffFrequencyHz (Type newValue) noexcept -{ - jassert (newValue > Type (0)); - cutoffFreqHz = newValue; - updateCutoffFreq(); -} - -//============================================================================== -template <typename Type> -void LadderFilter<Type>::setResonance (Type newValue) noexcept -{ - jassert (newValue >= Type (0) && newValue <= Type (1)); - resonance = newValue; - updateResonance(); -} - -//============================================================================== -template <typename Type> -void LadderFilter<Type>::setDrive (Type newValue) noexcept -{ - jassert (newValue >= Type (1)); - - drive = newValue; - gain = std::pow (drive, Type (-2.642)) * Type (0.6103) + Type (0.3903); - drive2 = drive * Type (0.04) + Type (0.96); - gain2 = std::pow (drive2, Type (-2.642)) * Type (0.6103) + Type (0.3903); -} - -//============================================================================== -template <typename Type> -Type LadderFilter<Type>::processSample (Type inputValue, size_t channelToUse) noexcept -{ - auto& s = state[channelToUse]; - - const auto a1 = cutoffTransformValue; - const auto g = a1 * Type (-1) + Type (1); - const auto b0 = g * Type (0.76923076923); - const auto b1 = g * Type (0.23076923076); - - const auto dx = gain * saturationLUT (drive * inputValue); - const auto a = dx + scaledResonanceValue * Type (-4) * (gain2 * saturationLUT (drive2 * s[4]) - dx * comp); - - const auto b = b1 * s[0] + a1 * s[1] + b0 * a; - const auto c = b1 * s[1] + a1 * s[2] + b0 * b; - const auto d = b1 * s[2] + a1 * s[3] + b0 * c; - const auto e = b1 * s[3] + a1 * s[4] + b0 * d; - - s[0] = a; - s[1] = b; - s[2] = c; - s[3] = d; - s[4] = e; - - return a * A[0] + b * A[1] + c * A[2] + d * A[3] + e * A[4]; -} - -//============================================================================== -template <typename Type> -void LadderFilter<Type>::updateSmoothers() noexcept -{ - cutoffTransformValue = cutoffTransformSmoother.getNextValue(); - scaledResonanceValue = scaledResonanceSmoother.getNextValue(); -} - -//============================================================================== -template <typename Type> -void LadderFilter<Type>::setSampleRate (Type newValue) noexcept -{ - jassert (newValue > Type (0)); - cutoffFreqScaler = Type (-2.0 * juce::MathConstants<double>::pi) / newValue; - - static constexpr Type smootherRampTimeSec = Type (0.05); - cutoffTransformSmoother.reset (newValue, smootherRampTimeSec); - scaledResonanceSmoother.reset (newValue, smootherRampTimeSec); - - updateCutoffFreq(); -} - -//============================================================================== -template class LadderFilter<float>; -template class LadderFilter<double>; - -} // namespace dsp -} // namespace juce diff --git a/modules/juce_dsp/processors/juce_LinkwitzRileyFilter.cpp b/modules/juce_dsp/processors/juce_LinkwitzRileyFilter.cpp new file mode 100644 index 00000000..716cabf1 --- /dev/null +++ b/modules/juce_dsp/processors/juce_LinkwitzRileyFilter.cpp @@ -0,0 +1,149 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +//============================================================================== +template <typename SampleType> +LinkwitzRileyFilter<SampleType>::LinkwitzRileyFilter() +{ + update(); +} + +//============================================================================== +template <typename SampleType> +void LinkwitzRileyFilter<SampleType>::setType (Type newType) +{ + filterType = newType; +} + +template <typename SampleType> +void LinkwitzRileyFilter<SampleType>::setCutoffFrequency (SampleType newCutoffFrequencyHz) +{ + jassert (isPositiveAndBelow (newCutoffFrequencyHz, static_cast<SampleType> (sampleRate * 0.5))); + + cutoffFrequency = newCutoffFrequencyHz; + update(); +} + +//============================================================================== +template <typename SampleType> +void LinkwitzRileyFilter<SampleType>::prepare (const ProcessSpec& spec) +{ + jassert (spec.sampleRate > 0); + jassert (spec.numChannels > 0); + + sampleRate = spec.sampleRate; + update(); + + s1.resize (spec.numChannels); + s2.resize (spec.numChannels); + s3.resize (spec.numChannels); + s4.resize (spec.numChannels); + + reset(); +} + +template <typename SampleType> +void LinkwitzRileyFilter<SampleType>::reset() +{ + for (auto s : { &s1, &s2, &s3, &s4 }) + std::fill (s->begin(), s->end(), static_cast<SampleType> (0)); +} + +template <typename SampleType> +void LinkwitzRileyFilter<SampleType>::snapToZero() noexcept +{ + for (auto s : { &s1, &s2, &s3, &s4 }) + for (auto& element : *s) + util::snapToZero (element); +} + +//============================================================================== +template <typename SampleType> +SampleType LinkwitzRileyFilter<SampleType>::processSample (int channel, SampleType inputValue) +{ + auto yH = (inputValue - (R2 + g) * s1[(size_t) channel] - s2[(size_t) channel]) * h; + + auto yB = g * yH + s1[(size_t) channel]; + s1[(size_t) channel] = g * yH + yB; + + auto yL = g * yB + s2[(size_t) channel]; + s2[(size_t) channel] = g * yB + yL; + + if (filterType == Type::allpass) + return yL - R2 * yB + yH; + + auto yH2 = ((filterType == Type::lowpass ? yL : yH) - (R2 + g) * s3[(size_t) channel] - s4[(size_t) channel]) * h; + + auto yB2 = g * yH2 + s3[(size_t) channel]; + s3[(size_t) channel] = g * yH2 + yB2; + + auto yL2 = g * yB2 + s4[(size_t) channel]; + s4[(size_t) channel] = g * yB2 + yL2; + + return filterType == Type::lowpass ? yL2 : yH2; +} + +template <typename SampleType> +void LinkwitzRileyFilter<SampleType>::processSample (int channel, SampleType inputValue, SampleType &outputLow, SampleType &outputHigh) +{ + auto yH = (inputValue - (R2 + g) * s1[(size_t) channel] - s2[(size_t) channel]) * h; + + auto yB = g * yH + s1[(size_t) channel]; + s1[(size_t) channel] = g * yH + yB; + + auto yL = g * yB + s2[(size_t) channel]; + s2[(size_t) channel] = g * yB + yL; + + auto yH2 = (yL - (R2 + g) * s3[(size_t) channel] - s4[(size_t) channel]) * h; + + auto yB2 = g * yH2 + s3[(size_t) channel]; + s3[(size_t) channel] = g * yH2 + yB2; + + auto yL2 = g * yB2 + s4[(size_t) channel]; + s4[(size_t) channel] = g * yB2 + yL2; + + outputLow = yL2; + outputHigh = yL - R2 * yB + yH - yL2; +} + +template <typename SampleType> +void LinkwitzRileyFilter<SampleType>::update() +{ + g = (SampleType) std::tan (MathConstants<double>::pi * cutoffFrequency / sampleRate); + R2 = (SampleType) std::sqrt (2.0); + h = (SampleType) (1.0 / (1.0 + R2 * g + g * g)); +} + +//============================================================================== +template class LinkwitzRileyFilter<float>; +template class LinkwitzRileyFilter<double>; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/processors/juce_LinkwitzRileyFilter.h b/modules/juce_dsp/processors/juce_LinkwitzRileyFilter.h new file mode 100644 index 00000000..d09e9309 --- /dev/null +++ b/modules/juce_dsp/processors/juce_LinkwitzRileyFilter.h @@ -0,0 +1,143 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +enum class LinkwitzRileyFilterType +{ + lowpass, + highpass, + allpass +}; + +/** + A filter class designed to perform multi-band separation using the TPT + (Topology-Preserving Transform) structure. + + Linkwitz-Riley filters are widely used in audio crossovers that have two outputs, + a low-pass and a high-pass, such that their sum is equivalent to an all-pass filter + with a flat magnitude frequency response. The Linkwitz-Riley filters available in + this class are designed to have a -24 dB/octave slope (LR 4th order). + + @tags{DSP} +*/ +template <typename SampleType> +class LinkwitzRileyFilter +{ +public: + //============================================================================== + using Type = LinkwitzRileyFilterType; + + //============================================================================== + /** Constructor. */ + LinkwitzRileyFilter(); + + //============================================================================== + /** Sets the filter type. */ + void setType (Type newType); + + /** Sets the cutoff frequency of the filter in Hz. */ + void setCutoffFrequency (SampleType newCutoffFrequencyHz); + + //============================================================================== + /** Returns the type of the filter. */ + Type getType() const noexcept { return filterType; } + + /** Returns the cutoff frequency of the filter. */ + SampleType getCutoffFrequency() const noexcept { return cutoffFrequency; } + + //============================================================================== + /** Initialises the filter. */ + void prepare (const ProcessSpec& spec); + + /** Resets the internal state variables of the filter. */ + void reset(); + + //============================================================================== + /** Processes the input and output samples supplied in the processing context. */ + template <typename ProcessContext> + void process (const ProcessContext& context) noexcept + { + const auto& inputBlock = context.getInputBlock(); + auto& outputBlock = context.getOutputBlock(); + const auto numChannels = outputBlock.getNumChannels(); + const auto numSamples = outputBlock.getNumSamples(); + + jassert (inputBlock.getNumChannels() <= s1.size()); + jassert (inputBlock.getNumChannels() == numChannels); + jassert (inputBlock.getNumSamples() == numSamples); + + if (context.isBypassed) + { + outputBlock.copyFrom (inputBlock); + return; + } + + for (size_t channel = 0; channel < numChannels; ++channel) + { + auto* inputSamples = inputBlock.getChannelPointer (channel); + auto* outputSamples = outputBlock.getChannelPointer (channel); + + for (size_t i = 0; i < numSamples; ++i) + outputSamples[i] = processSample ((int) channel, inputSamples[i]); + } + + #if JUCE_SNAP_TO_ZERO + snapToZero(); + #endif + } + + /** Performs the filter operation on a single sample at a time. */ + SampleType processSample (int channel, SampleType inputValue); + + /** Performs the filter operation on a single sample at a time, and returns both + the low-pass and the high-pass outputs of the TPT structure. + */ + void processSample (int channel, SampleType inputValue, SampleType &outputLow, SampleType &outputHigh); + + /** Ensure that the state variables are rounded to zero if the state + variables are denormals. This is only needed if you are doing + sample by sample processing. + */ + void snapToZero() noexcept; + +private: + //============================================================================== + void update(); + + //============================================================================== + SampleType g, R2, h; + std::vector<SampleType> s1, s2, s3, s4; + + double sampleRate = 44100.0; + SampleType cutoffFrequency = 2000.0; + Type filterType = Type::lowpass; +}; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/processors/juce_Oversampling.cpp b/modules/juce_dsp/processors/juce_Oversampling.cpp index 06cc7298..9e258990 100644 --- a/modules/juce_dsp/processors/juce_Oversampling.cpp +++ b/modules/juce_dsp/processors/juce_Oversampling.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -39,7 +38,7 @@ struct Oversampling<SampleType>::OversamplingStage virtual ~OversamplingStage() {} //============================================================================== - virtual SampleType getLatencyInSamples() = 0; + virtual SampleType getLatencyInSamples() const = 0; virtual void initProcessing (size_t maximumNumberOfSamplesBeforeOversampling) { @@ -78,7 +77,7 @@ struct OversamplingDummy : public Oversampling<SampleType>::OversamplingStage OversamplingDummy (size_t numChans) : ParentType (numChans, 1) {} //============================================================================== - SampleType getLatencyInSamples() override + SampleType getLatencyInSamples() const override { return 0; } @@ -139,7 +138,7 @@ struct Oversampling2TimesEquirippleFIR : public Oversampling<SampleType>::Overs } //============================================================================== - SampleType getLatencyInSamples() override + SampleType getLatencyInSamples() const override { return static_cast<SampleType> (coefficientsUp.getFilterOrder() + coefficientsDown.getFilterOrder()) * 0.5f; } @@ -300,7 +299,7 @@ struct Oversampling2TimesPolyphaseIIR : public Oversampling<SampleType>::Oversa } //============================================================================== - SampleType getLatencyInSamples() override + SampleType getLatencyInSamples() const override { return latency; } @@ -364,8 +363,9 @@ struct Oversampling2TimesPolyphaseIIR : public Oversampling<SampleType>::Oversa } } - // Snap To Zero + #if JUCE_SNAP_TO_ZERO snapToZero (true); + #endif } void processSamplesDown (AudioBlock<SampleType>& outputBlock) override @@ -422,8 +422,9 @@ struct Oversampling2TimesPolyphaseIIR : public Oversampling<SampleType>::Oversa delayDown.setUnchecked (static_cast<int> (channel), delay); } - // Snap To Zero + #if JUCE_SNAP_TO_ZERO snapToZero (false); + #endif } void snapToZero (bool snapUpProcessing) @@ -506,10 +507,10 @@ private: coeffs.coefficients.clear(); auto inversion = one / denominator[0]; - for (auto i = 0; i <= numerator.getOrder(); ++i) + for (int i = 0; i <= numerator.getOrder(); ++i) coeffs.coefficients.add (numerator[i] * inversion); - for (auto i = 1; i <= denominator.getOrder(); ++i) + for (int i = 1; i <= denominator.getOrder(); ++i) coeffs.coefficients.add (denominator[i] * inversion); return coeffs; @@ -539,8 +540,9 @@ Oversampling<SampleType>::Oversampling (size_t newNumChannels) template <typename SampleType> Oversampling<SampleType>::Oversampling (size_t newNumChannels, size_t newFactor, - FilterType newType, bool isMaximumQuality) - : numChannels (newNumChannels) + FilterType newType, bool isMaximumQuality, + bool useIntegerLatency) + : numChannels (newNumChannels), shouldUseIntegerLatency (useIntegerLatency) { jassert (isPositiveAndBelow (newFactor, 5) && numChannels > 0); @@ -561,8 +563,8 @@ Oversampling<SampleType>::Oversampling (size_t newNumChannels, size_t newFactor, auto gaindBFactorDown = (isMaximumQuality ? 10.0f : 8.0f); addOversamplingStage (FilterType::filterHalfBandPolyphaseIIR, - twUp, gaindBStartUp + gaindBFactorUp * n, - twDown, gaindBStartDown + gaindBFactorDown * n); + twUp, gaindBStartUp + gaindBFactorUp * (float) n, + twDown, gaindBStartDown + gaindBFactorDown * (float) n); } } else if (newType == FilterType::filterHalfBandFIREquiripple) @@ -578,8 +580,8 @@ Oversampling<SampleType>::Oversampling (size_t newNumChannels, size_t newFactor, auto gaindBFactorDown = (isMaximumQuality ? 10.0f : 8.0f); addOversamplingStage (FilterType::filterHalfBandFIREquiripple, - twUp, gaindBStartUp + gaindBFactorUp * n, - twDown, gaindBStartDown + gaindBFactorDown * n); + twUp, gaindBStartUp + gaindBFactorUp * (float) n, + twDown, gaindBStartDown + gaindBFactorDown * (float) n); } } } @@ -629,7 +631,20 @@ void Oversampling<SampleType>::clearOversamplingStages() //============================================================================== template <typename SampleType> -SampleType Oversampling<SampleType>::getLatencyInSamples() noexcept +void Oversampling<SampleType>::setUsingIntegerLatency (bool useIntegerLatency) noexcept +{ + shouldUseIntegerLatency = useIntegerLatency; +} + +template <typename SampleType> +SampleType Oversampling<SampleType>::getLatencyInSamples() const noexcept +{ + auto latency = getUncompensatedLatency(); + return shouldUseIntegerLatency ? latency + fractionalDelay : latency; +} + +template <typename SampleType> +SampleType Oversampling<SampleType>::getUncompensatedLatency() const noexcept { auto latency = static_cast<SampleType> (0); size_t order = 1; @@ -644,7 +659,7 @@ SampleType Oversampling<SampleType>::getLatencyInSamples() noexcept } template <typename SampleType> -size_t Oversampling<SampleType>::getOversamplingFactor() noexcept +size_t Oversampling<SampleType>::getOversamplingFactor() const noexcept { return factorOversampling; } @@ -662,6 +677,10 @@ void Oversampling<SampleType>::initProcessing (size_t maximumNumberOfSamplesBefo currentNumSamples *= stage->factor; } + ProcessSpec spec = { 0.0, (uint32) maximumNumberOfSamplesBeforeOversampling, (uint32) numChannels }; + delay.prepare (spec); + updateDelayLine(); + isReady = true; reset(); } @@ -674,6 +693,8 @@ void Oversampling<SampleType>::reset() noexcept if (isReady) for (auto* stage : stages) stage->reset(); + + delay.reset(); } template <typename SampleType> @@ -720,6 +741,26 @@ void Oversampling<SampleType>::processSamplesDown (AudioBlock<SampleType>& outpu } stages.getFirst()->processSamplesDown (outputBlock); + + if (shouldUseIntegerLatency && fractionalDelay > static_cast<SampleType> (0.0)) + { + auto context = ProcessContextReplacing<SampleType> (outputBlock); + delay.process (context); + } +} + +template <typename SampleType> +void Oversampling<SampleType>::updateDelayLine() +{ + auto latency = getUncompensatedLatency(); + fractionalDelay = static_cast<SampleType> (1.0) - (latency - std::floor (latency)); + + if (fractionalDelay == static_cast<SampleType> (1.0)) + fractionalDelay = static_cast<SampleType> (0.0); + else if (fractionalDelay < static_cast<SampleType> (0.618)) + fractionalDelay += static_cast<SampleType> (1.0); + + delay.setDelay (fractionalDelay); } template class Oversampling<float>; diff --git a/modules/juce_dsp/processors/juce_Oversampling.h b/modules/juce_dsp/processors/juce_Oversampling.h index 10c715a0..12fd03a6 100644 --- a/modules/juce_dsp/processors/juce_Oversampling.h +++ b/modules/juce_dsp/processors/juce_Oversampling.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -29,24 +28,23 @@ namespace juce namespace dsp { -//============================================================================== +//=============================================================================== /** - A processing class performing multi-channel oversampling. + A processor that performs multi-channel oversampling. - It can be configured to do 2 times, 4 times, 8 times or 16 times oversampling - using a multi-stage approach, either polyphase allpass IIR filters or FIR - filters for the filtering, and reports successfully the latency added by the - filter stages. + This class can be configured to do a factor of 2, 4, 8 or 16 times + oversampling, using multiple stages, with polyphase allpass IIR filters or FIR + filters, and latency compensation. The principle of oversampling is to increase the sample rate of a given - non-linear process, to prevent it from creating aliasing. Oversampling works - by upsampling N times the input signal, processing the upsampled signal - with the increased internal sample rate, and downsampling the result to get - back the original processing sample rate. - - Choose between FIR or IIR filtering depending on your needs in term of - latency and phase distortion. With FIR filters, the phase is linear but the - latency is maximised. With IIR filtering, the phase is compromised around the + non-linear process to prevent it from creating aliasing. Oversampling works + by upsampling the input signal N times, processing the upsampled signal + with the increased internal sample rate, then downsampling the result to get + back to the original sample rate. + + Choose between FIR or IIR filtering depending on your needs in terms of + latency and phase distortion. With FIR filters the phase is linear but the + latency is maximised. With IIR filtering the phase is compromised around the Nyquist frequency but the latency is minimised. @see FilterDesign. @@ -65,52 +63,62 @@ public: numFilterTypes }; - //============================================================================== - /** - Constructor of the oversampling class. All the processing parameters must be - provided at the creation of the oversampling object. - - @param numChannels the number of channels to process with this object - @param factor the processing will perform 2 ^ factor times oversampling - @param type the type of filter design employed for filtering during - oversampling - @param isMaxQuality if the oversampling is done using the maximum quality, - the filters will be more efficient, but the CPU load will - increase as well - */ - Oversampling (size_t numChannels, - size_t factor, - FilterType type, - bool isMaxQuality = true); + //=============================================================================== + /** The default constructor. - /** The default constructor of the oversampling class, which can be used to create an - empty object and then add the appropriate stages. - - Note: This creates a "dummy" oversampling stage, which needs to be removed first + Note: This creates a "dummy" oversampling stage, which needs to be removed before adding proper oversampling stages. + @param numChannels the number of channels to process with this object + @see clearOversamplingStages, addOversamplingStage */ explicit Oversampling (size_t numChannels = 1); + /** Constructor. + + @param numChannels the number of channels to process with this object + @param factor the processing will perform 2 ^ factor times oversampling + @param type the type of filter design employed for filtering during + oversampling + @param isMaxQuality if the oversampling is done using the maximum quality, where + the filters will be more efficient but the CPU load will + increase as well + @param useIntegerLatency if true this processor will add some fractional delay at the + end of the signal path to ensure that the overall latency of + the oversampling is an integer + */ + Oversampling (size_t numChannels, + size_t factor, + FilterType type, + bool isMaxQuality = true, + bool useIntegerLatency = false); + /** 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 - the latency to the DAW. + //=============================================================================== + /* Sets if this processor should add some fractional delay at the end of the signal + path to ensure that the overall latency of the oversampling is an integer. + */ + void setUsingIntegerLatency (bool shouldUseIntegerLatency) noexcept; + + /** Returns the latency in samples of the overall processing. You can use this + information in your main processor to compensate the additional latency + involved with the oversampling, for example with a dry / wet mixer, and to + report the latency to the DAW. - Note: The latency might not be integer, so you might need to round its value - or to compensate it properly in your processing code. + Note: If you have not opted to use an integer latency then the latency may not be + integer, so you might need to round its value or to compensate it properly in + your processing code since plug-ins can only report integer latency values in + samples to the DAW. */ - SampleType getLatencyInSamples() noexcept; + SampleType getLatencyInSamples() const noexcept; /** Returns the current oversampling factor. */ - size_t getOversamplingFactor() noexcept; + size_t getOversamplingFactor() const noexcept; - //============================================================================== + //=============================================================================== /** Must be called before any processing, to set the buffer sizes of the internal buffers of the oversampling processing. */ @@ -135,7 +143,7 @@ public: */ void processSamplesDown (AudioBlock<SampleType>& 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 +187,7 @@ public: */ void clearOversamplingStages(); - //============================================================================== + //=============================================================================== size_t factorOversampling = 1; size_t numChannels = 1; @@ -188,11 +196,17 @@ public: #endif private: - //============================================================================== + //=============================================================================== + void updateDelayLine(); + SampleType getUncompensatedLatency() const noexcept; + + //=============================================================================== OwnedArray<OversamplingStage> stages; - bool isReady = false; + bool isReady = false, shouldUseIntegerLatency = false; + DelayLine<SampleType, DelayLineInterpolationTypes::Thiran> delay { 8 }; + SampleType fractionalDelay = 0; - //============================================================================== + //=============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Oversampling) }; diff --git a/modules/juce_dsp/processors/juce_Panner.cpp b/modules/juce_dsp/processors/juce_Panner.cpp new file mode 100644 index 00000000..64721048 --- /dev/null +++ b/modules/juce_dsp/processors/juce_Panner.cpp @@ -0,0 +1,143 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +//============================================================================== +template <typename SampleType> +Panner<SampleType>::Panner() +{ + update(); + reset(); +} + +//============================================================================== +template <typename SampleType> +void Panner<SampleType>::setRule (Rule newRule) +{ + currentRule = newRule; + update(); +} + +template <typename SampleType> +void Panner<SampleType>::setPan (SampleType newPan) +{ + jassert (newPan >= -1.0 && newPan <= 1.0); + + pan = jlimit (static_cast<SampleType> (-1.0), static_cast<SampleType> (1.0), newPan); + update(); +} + +//============================================================================== +template <typename SampleType> +void Panner<SampleType>::prepare (const ProcessSpec& spec) +{ + jassert (spec.sampleRate > 0); + jassert (spec.numChannels > 0); + + sampleRate = spec.sampleRate; + + reset(); +} + +template <typename SampleType> +void Panner<SampleType>::reset() +{ + leftVolume .reset (sampleRate, 0.05); + rightVolume.reset (sampleRate, 0.05); +} + +//============================================================================== +template <typename SampleType> +void Panner<SampleType>::update() +{ + SampleType leftValue, rightValue, boostValue; + + auto normalisedPan = static_cast<SampleType> (0.5) * (pan + static_cast<SampleType> (1.0)); + + switch (currentRule) + { + case Rule::balanced: + leftValue = jmin (static_cast<SampleType> (0.5), static_cast<SampleType> (1.0) - normalisedPan); + rightValue = jmin (static_cast<SampleType> (0.5), normalisedPan); + boostValue = static_cast<SampleType> (2.0); + break; + + case Rule::linear: + leftValue = static_cast<SampleType> (1.0) - normalisedPan; + rightValue = normalisedPan; + boostValue = static_cast<SampleType> (2.0); + break; + + case Rule::sin3dB: + leftValue = static_cast<SampleType> (std::sin (0.5 * MathConstants<double>::pi * (1.0 - normalisedPan))); + rightValue = static_cast<SampleType> (std::sin (0.5 * MathConstants<double>::pi * normalisedPan)); + boostValue = std::sqrt (static_cast<SampleType> (2.0)); + break; + + case Rule::sin4p5dB: + leftValue = static_cast<SampleType> (std::pow (std::sin (0.5 * MathConstants<double>::pi * (1.0 - normalisedPan)), 1.5)); + rightValue = static_cast<SampleType> (std::pow (std::sin (0.5 * MathConstants<double>::pi * normalisedPan), 1.5)); + boostValue = static_cast<SampleType> (std::pow (2.0, 3.0 / 4.0)); + break; + + case Rule::sin6dB: + leftValue = static_cast<SampleType> (std::pow (std::sin (0.5 * MathConstants<double>::pi * (1.0 - normalisedPan)), 2.0)); + rightValue = static_cast<SampleType> (std::pow (std::sin (0.5 * MathConstants<double>::pi * normalisedPan), 2.0)); + boostValue = static_cast<SampleType> (2.0); + break; + + case Rule::squareRoot3dB: + leftValue = std::sqrt (static_cast<SampleType> (1.0) - normalisedPan); + rightValue = std::sqrt (normalisedPan); + boostValue = std::sqrt (static_cast<SampleType> (2.0)); + break; + + case Rule::squareRoot4p5dB: + leftValue = static_cast<SampleType> (std::pow (std::sqrt (1.0 - normalisedPan), 1.5)); + rightValue = static_cast<SampleType> (std::pow (std::sqrt (normalisedPan), 1.5)); + boostValue = static_cast<SampleType> (std::pow (2.0, 3.0 / 4.0)); + break; + + default: + leftValue = jmin (static_cast<SampleType> (0.5), static_cast<SampleType> (1.0) - normalisedPan); + rightValue = jmin (static_cast<SampleType> (0.5), normalisedPan); + boostValue = static_cast<SampleType> (2.0); + break; + } + + leftVolume .setTargetValue (leftValue * boostValue); + rightVolume.setTargetValue (rightValue * boostValue); +} + +//============================================================================== +template class Panner<float>; +template class Panner<double>; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/processors/juce_Panner.h b/modules/juce_dsp/processors/juce_Panner.h new file mode 100644 index 00000000..ac6da7ab --- /dev/null +++ b/modules/juce_dsp/processors/juce_Panner.h @@ -0,0 +1,122 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +enum class PannerRule +{ + linear, // regular 6 dB or linear panning rule, allows the panned sound to be + // perceived as having a constant level when summed to mono + balanced, // both left and right are 1 when pan value is 0.5, with left decreasing + // to 0 above this value and right decreasing to 0 below it + sin3dB, // alternate version of the regular 3 dB panning rule with a sine curve + sin4p5dB, // alternate version of the regular 4.5 dB panning rule with a sine curve + sin6dB, // alternate version of the regular 6 dB panning rule with a sine curve + squareRoot3dB, // regular 3 dB or constant power panning rule, allows the panned sound + // to be perceived as having a constant level regardless of the pan position + squareRoot4p5dB // regular 4.5 dB panning rule, a compromise option between 3 dB and 6 dB panning rules +}; + +/** + A processor to perform panning operations on stereo buffers. + + @tags{DSP} +*/ +template <typename SampleType> +class Panner +{ +public: + //============================================================================== + using Rule = PannerRule; + + //============================================================================== + /** Constructor. */ + Panner(); + + //============================================================================== + /** Sets the panning rule. */ + void setRule (Rule newRule); + + /** Sets the current panning value, between -1 (full left) and 1 (full right). */ + void setPan (SampleType newPan); + + //============================================================================== + /** Initialises the processor. */ + void prepare (const ProcessSpec& spec); + + /** Resets the internal state variables of the processor. */ + void reset(); + + //============================================================================== + /** Processes the input and output samples supplied in the processing context. */ + template <typename ProcessContext> + void process (const ProcessContext& context) noexcept + { + const auto& inputBlock = context.getInputBlock(); + auto& outputBlock = context.getOutputBlock(); + + const auto numInputChannels = inputBlock.getNumChannels(); + const auto numOutputChannels = outputBlock.getNumChannels(); + const auto numSamples = outputBlock.getNumSamples(); + + jassert (inputBlock.getNumSamples() == numSamples); + ignoreUnused (numSamples); + + if (numOutputChannels != 2 || numInputChannels == 0 || numInputChannels > 2) + return; + + if (numInputChannels == 2) + { + outputBlock.copyFrom (inputBlock); + } + else + { + outputBlock.getSingleChannelBlock (0).copyFrom (inputBlock); + outputBlock.getSingleChannelBlock (1).copyFrom (inputBlock); + } + + if (context.isBypassed) + return; + + outputBlock.getSingleChannelBlock (0).multiplyBy (leftVolume); + outputBlock.getSingleChannelBlock (1).multiplyBy (rightVolume); + } + +private: + //============================================================================== + void update(); + + //============================================================================== + Rule currentRule = Rule::balanced; + SampleType pan = 0.0; + SmoothedValue<SampleType> leftVolume, rightVolume; + double sampleRate = 44100.0; +}; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/processors/juce_ProcessContext.h b/modules/juce_dsp/processors/juce_ProcessContext.h index ca6873a9..f0562f20 100644 --- a/modules/juce_dsp/processors/juce_ProcessContext.h +++ b/modules/juce_dsp/processors/juce_ProcessContext.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_dsp/processors/juce_ProcessorChain.h b/modules/juce_dsp/processors/juce_ProcessorChain.h index 71fbb23a..364bc25d 100644 --- a/modules/juce_dsp/processors/juce_ProcessorChain.h +++ b/modules/juce_dsp/processors/juce_ProcessorChain.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -29,109 +28,131 @@ namespace juce namespace dsp { +//============================================================================== #ifndef DOXYGEN -namespace ProcessorHelpers // Internal helper classes used in building the ProcessorChain +/** The contents of this namespace are used to implement ProcessorChain and should + not be used elsewhere. Their interfaces (and existence) are liable to change! +*/ +namespace detail { - template <int arg> - struct AccessHelper + template <typename Fn, typename Tuple, size_t... Ix> + constexpr void forEachInTuple (Fn&& fn, Tuple&& tuple, std::index_sequence<Ix...>) + noexcept (noexcept (std::initializer_list<int> { (fn (std::get<Ix> (tuple), Ix), 0)... })) { - template <typename ProcessorType> - static auto& get (ProcessorType& a) noexcept { return AccessHelper<arg - 1>::get (a.processors); } - - template <typename ProcessorType> - static const auto& get (const ProcessorType& a) noexcept { return AccessHelper<arg - 1>::get (a.processors); } + (void) std::initializer_list<int> { ((void) fn (std::get<Ix> (tuple), Ix), 0)... }; + } - template <typename ProcessorType> - static void setBypassed (ProcessorType& a, bool bypassed) { AccessHelper<arg - 1>::setBypassed (a.processors, bypassed); } - }; + template <typename T> + using TupleIndexSequence = std::make_index_sequence<std::tuple_size<std::remove_cv_t<std::remove_reference_t<T>>>::value>; - template <> - struct AccessHelper<0> + template <typename Fn, typename Tuple> + constexpr void forEachInTuple (Fn&& fn, Tuple&& tuple) + noexcept (noexcept (forEachInTuple (std::forward<Fn> (fn), std::forward<Tuple> (tuple), TupleIndexSequence<Tuple>{}))) { - template <typename ProcessorType> - static auto& get (ProcessorType& a) noexcept { return a.getProcessor(); } + forEachInTuple (std::forward<Fn> (fn), std::forward<Tuple> (tuple), TupleIndexSequence<Tuple>{}); + } +} +#endif - template <typename ProcessorType> - static const auto& get (const ProcessorType& a) noexcept { return a.getProcessor(); } +/** This variadically-templated class lets you join together any number of processor + classes into a single processor which will call process() on them all in sequence. + + @tags{DSP} +*/ +template <typename... Processors> +class ProcessorChain +{ +public: + /** Get a reference to the processor at index `Index`. */ + template <int Index> auto& get() noexcept { return std::get<Index> (processors); } - template <typename ProcessorType> - static void setBypassed (ProcessorType& a, bool bypassed) { a.isBypassed = bypassed; } - }; + /** Get a reference to the processor at index `Index`. */ + template <int Index> const auto& get() const noexcept { return std::get<Index> (processors); } - //============================================================================== - template <bool isFirst, typename Processor, typename Subclass> - struct ChainElement + /** Set the processor at index `Index` to be bypassed or enabled. */ + template <int Index> + void setBypassed (bool b) noexcept { bypassed[(size_t) Index] = b; } + + /** Query whether the processor at index `Index` is bypassed. */ + template <int Index> + bool isBypassed() const noexcept { return bypassed[(size_t) Index]; } + + /** Prepare all inner processors with the provided `ProcessSpec`. */ + void prepare (const ProcessSpec& spec) { - void prepare (const ProcessSpec& spec) - { - processor.prepare (spec); - } + detail::forEachInTuple ([&] (auto& proc, size_t) { proc.prepare (spec); }, processors); + } + + /** Reset all inner processors. */ + void reset() + { + detail::forEachInTuple ([] (auto& proc, size_t) { proc.reset(); }, processors); + } - template <typename ProcessContext> - void process (const ProcessContext& context) noexcept + /** Process `context` through all inner processors in sequence. */ + template <typename ProcessContext> + void process (const ProcessContext& context) noexcept + { + detail::forEachInTuple ([&] (auto& proc, size_t index) noexcept { - if (context.usesSeparateInputAndOutputBlocks() && ! isFirst) + if (context.usesSeparateInputAndOutputBlocks() && index != 0) { jassert (context.getOutputBlock().getNumChannels() == context.getInputBlock().getNumChannels()); ProcessContextReplacing<typename ProcessContext::SampleType> replacingContext (context.getOutputBlock()); - replacingContext.isBypassed = (isBypassed || context.isBypassed); + replacingContext.isBypassed = (bypassed[index] || context.isBypassed); - processor.process (replacingContext); + proc.process (replacingContext); } else { ProcessContext contextCopy (context); - contextCopy.isBypassed = (isBypassed || context.isBypassed); + contextCopy.isBypassed = (bypassed[index] || context.isBypassed); - processor.process (contextCopy); + proc.process (contextCopy); } - } - - void reset() - { - processor.reset(); - } - - bool isBypassed = false; - Processor processor; + }, processors); + } - Processor& getProcessor() noexcept { return processor; } - const Processor& getProcessor() const noexcept { return processor; } - Subclass& getThis() noexcept { return *static_cast<Subclass*> (this); } - const Subclass& getThis() const noexcept { return *static_cast<const Subclass*> (this); } +private: + std::tuple<Processors...> processors; + std::array<bool, sizeof...(Processors)> bypassed { {} }; +}; - template <int arg> auto& get() noexcept { return AccessHelper<arg>::get (getThis()); } - template <int arg> const auto& get() const noexcept { return AccessHelper<arg>::get (getThis()); } - template <int arg> void setBypassed (bool bypassed) noexcept { AccessHelper<arg>::setBypassed (getThis(), bypassed); } - }; - - //============================================================================== - template <bool isFirst, typename FirstProcessor, typename... SubsequentProcessors> - struct ChainBase : public ChainElement<isFirst, FirstProcessor, ChainBase<isFirst, FirstProcessor, SubsequentProcessors...>> - { - using Base = ChainElement<isFirst, FirstProcessor, ChainBase<isFirst, FirstProcessor, SubsequentProcessors...>>; - - template <typename ProcessContext> - void process (const ProcessContext& context) noexcept { Base::process (context); processors.process (context); } - void prepare (const ProcessSpec& spec) { Base::prepare (spec); processors.prepare (spec); } - void reset() { Base::reset(); processors.reset(); } - - ChainBase<false, SubsequentProcessors...> processors; - }; +/** Non-member equivalent of ProcessorChain::get which avoids awkward + member template syntax. +*/ +template <int Index, typename... Processors> +inline auto& get (ProcessorChain<Processors...>& chain) noexcept +{ + return chain.template get<Index>(); +} - template <bool isFirst, typename ProcessorType> - struct ChainBase<isFirst, ProcessorType> : public ChainElement<isFirst, ProcessorType, ChainBase<isFirst, ProcessorType>> {}; +/** Non-member equivalent of ProcessorChain::get which avoids awkward + member template syntax. +*/ +template <int Index, typename... Processors> +inline auto& get (const ProcessorChain<Processors...>& chain) noexcept +{ + return chain.template get<Index>(); } -#endif +/** Non-member equivalent of ProcessorChain::setBypassed which avoids awkward + member template syntax. +*/ +template <int Index, typename... Processors> +inline void setBypassed (ProcessorChain<Processors...>& chain, bool bypassed) noexcept +{ + chain.template setBypassed<Index> (bypassed); +} -//============================================================================== -/** - This variadically-templated class lets you join together any number of processor - classes into a single processor which will call process() on them all in sequence. +/** Non-member equivalent of ProcessorChain::isBypassed which avoids awkward + member template syntax. */ -template <typename... Processors> -using ProcessorChain = ProcessorHelpers::ChainBase<true, Processors...>; +template <int Index, typename... Processors> +inline bool isBypassed (const ProcessorChain<Processors...>& chain) noexcept +{ + return chain.template isBypassed<Index>(); +} } // namespace dsp } // namespace juce diff --git a/modules/juce_dsp/processors/juce_ProcessorChain_test.cpp b/modules/juce_dsp/processors/juce_ProcessorChain_test.cpp new file mode 100644 index 00000000..4e4f6b12 --- /dev/null +++ b/modules/juce_dsp/processors/juce_ProcessorChain_test.cpp @@ -0,0 +1,141 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +class ProcessorChainTest : public UnitTest +{ + template <int AddValue> + struct MockProcessor + { + void prepare (const ProcessSpec&) noexcept { isPrepared = true; } + void reset() noexcept { isReset = true; } + + template <typename Context> + void process (const Context& context) noexcept + { + bufferWasClear = context.getInputBlock().getSample (0, 0) == 0; + + if (! context.isBypassed) + context.getOutputBlock().add (AddValue); + } + + bool isPrepared = false; + bool isReset = false; + bool bufferWasClear = false; + }; + +public: + ProcessorChainTest() + : UnitTest ("ProcessorChain", UnitTestCategories::dsp) {} + + void runTest() override + { + beginTest ("After calling setBypass, processor is bypassed"); + { + ProcessorChain<MockProcessor<1>, MockProcessor<2>> chain; + + setBypassed<0> (chain, true); + expect (isBypassed<0> (chain)); + setBypassed<0> (chain, false); + expect (! isBypassed<0> (chain)); + + setBypassed<1> (chain, true); + expect (isBypassed<1> (chain)); + setBypassed<1> (chain, false); + expect (! isBypassed<1> (chain)); + } + + beginTest ("After calling prepare, all processors are prepared"); + { + ProcessorChain<MockProcessor<1>, MockProcessor<2>> chain; + + expect (! get<0> (chain).isPrepared); + expect (! get<1> (chain).isPrepared); + + chain.prepare (ProcessSpec{}); + + expect (get<0> (chain).isPrepared); + expect (get<1> (chain).isPrepared); + } + + beginTest ("After calling reset, all processors are reset"); + { + ProcessorChain<MockProcessor<1>, MockProcessor<2>> chain; + + expect (! get<0> (chain).isReset); + expect (! get<1> (chain).isReset); + + chain.reset(); + + expect (get<0> (chain).isReset); + expect (get<1> (chain).isReset); + } + + beginTest ("After calling process, all processors contribute to processing"); + { + ProcessorChain<MockProcessor<1>, MockProcessor<2>> chain; + + AudioBuffer<float> buffer (1, 1); + AudioBlock<float> block (buffer); + ProcessContextReplacing<float> context (block); + + block.clear(); + chain.process (context); + expectEquals (buffer.getSample (0, 0), 3.0f); + expect (get<0> (chain).bufferWasClear); + expect (! get<1> (chain).bufferWasClear); + + setBypassed<0> (chain, true); + block.clear(); + chain.process (context); + expectEquals (buffer.getSample (0, 0), 2.0f); + expect (get<0> (chain).bufferWasClear); + expect (get<1> (chain).bufferWasClear); + + setBypassed<1> (chain, true); + block.clear(); + chain.process (context); + expectEquals (buffer.getSample (0, 0), 0.0f); + expect (get<0> (chain).bufferWasClear); + expect (get<1> (chain).bufferWasClear); + + setBypassed<0> (chain, false); + block.clear(); + chain.process (context); + expectEquals (buffer.getSample (0, 0), 1.0f); + expect (get<0> (chain).bufferWasClear); + expect (! get<1> (chain).bufferWasClear); + } + } +}; + +static ProcessorChainTest processorChainUnitTest; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/processors/juce_ProcessorDuplicator.h b/modules/juce_dsp/processors/juce_ProcessorDuplicator.h index fe693666..6fb0f993 100644 --- a/modules/juce_dsp/processors/juce_ProcessorDuplicator.h +++ b/modules/juce_dsp/processors/juce_ProcessorDuplicator.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_dsp/processors/juce_ProcessorWrapper.h b/modules/juce_dsp/processors/juce_ProcessorWrapper.h index e1521496..e4c35e57 100644 --- a/modules/juce_dsp/processors/juce_ProcessorWrapper.h +++ b/modules/juce_dsp/processors/juce_ProcessorWrapper.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_dsp/processors/juce_StateVariableFilter.h b/modules/juce_dsp/processors/juce_StateVariableFilter.h index 6f654845..c147f7e4 100644 --- a/modules/juce_dsp/processors/juce_StateVariableFilter.h +++ b/modules/juce_dsp/processors/juce_StateVariableFilter.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -39,14 +38,21 @@ namespace StateVariableFilter /** An IIR filter that can perform low, band and high-pass filtering on an audio - signal, with 12 dB of attenuation / octave, using a TPT structure, designed + signal, with 12 dB of attenuation per octave, using a TPT structure, designed for fast modulation (see Vadim Zavalishin's documentation about TPT structures for more information). Its behaviour is based on the analog state variable filter circuit. - Note: The bandpass here is not the one in the RBJ CookBook, its gain can be + Note: The bandpass here is not the one in the RBJ CookBook as its gain can be higher than 0 dB. For the classic 0 dB bandpass, we need to multiply the - result with R2 + result by R2. + + Note 2: Using this class prevents some loud audio artefacts commonly encountered when + changing the cutoff frequency using other filter simulation structures and IIR + filter classes. However, this class may still require additional smoothing for + cutoff frequency changes. + + see IIRFilter, SmoothedValue @tags{DSP} */ @@ -64,10 +70,19 @@ namespace StateVariableFilter using ParametersPtr = typename Parameters<NumericType>::Ptr; //============================================================================== - /** Creates a filter with default parameters. */ - Filter() : parameters (new Parameters<NumericType>) { reset(); } + /** Creates a filter with default parameters. + + The classes in the StateVariableFilter namespace are deprecated. you should + use the equivalent functionality in the StateVariableTPTFilter class. + */ + JUCE_DEPRECATED_WITH_BODY (Filter(), : parameters (new Parameters<NumericType>) { reset(); }) + + /** Creates a filter using some parameters. - Filter (ParametersPtr parametersToUse) : parameters (std::move (parametersToUse)) { reset(); } + The classes in the StateVariableFilter namespace are deprecated. you should + use the equivalent functionality in the StateVariableTPTFilter class. + */ + JUCE_DEPRECATED_WITH_BODY (Filter (ParametersPtr parametersToUse), : parameters (std::move (parametersToUse)) { reset(); }) /** Creates a copy of another filter. */ Filter (const Filter&) = default; @@ -145,7 +160,10 @@ namespace StateVariableFilter for (size_t i = 0 ; i < n; ++i) output[i] = processLoop<isBypassed, type> (input[i], state); + #if JUCE_SNAP_TO_ZERO snapToZero(); + #endif + *parameters = state; } @@ -181,6 +199,13 @@ namespace StateVariableFilter JUCE_LEAK_DETECTOR (Filter) }; + enum class StateVariableFilterType + { + lowPass, + bandPass, + highPass + }; + //============================================================================== /** Structure used for the state variable filter parameters. @@ -191,12 +216,7 @@ namespace StateVariableFilter struct Parameters : public ProcessorState { //============================================================================== - enum class Type - { - lowPass, - bandPass, - highPass - }; + using Type = StateVariableFilterType; //============================================================================== /** The type of the IIR filter */ diff --git a/modules/juce_dsp/processors/juce_StateVariableTPTFilter.cpp b/modules/juce_dsp/processors/juce_StateVariableTPTFilter.cpp new file mode 100644 index 00000000..3469694b --- /dev/null +++ b/modules/juce_dsp/processors/juce_StateVariableTPTFilter.cpp @@ -0,0 +1,137 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +//============================================================================== +template <typename SampleType> +StateVariableTPTFilter<SampleType>::StateVariableTPTFilter() +{ + update(); +} + +template <typename SampleType> +void StateVariableTPTFilter<SampleType>::setType (Type newValue) +{ + filterType = newValue; +} + +template <typename SampleType> +void StateVariableTPTFilter<SampleType>::setCutoffFrequency (SampleType newCutoffFrequencyHz) +{ + jassert (isPositiveAndBelow (newCutoffFrequencyHz, static_cast<SampleType> (sampleRate * 0.5))); + + cutoffFrequency = newCutoffFrequencyHz; + update(); +} + +template <typename SampleType> +void StateVariableTPTFilter<SampleType>::setResonance (SampleType newResonance) +{ + jassert (newResonance > static_cast<SampleType> (0)); + + resonance = newResonance; + update(); +} + +//============================================================================== +template <typename SampleType> +void StateVariableTPTFilter<SampleType>::prepare (const ProcessSpec& spec) +{ + jassert (spec.sampleRate > 0); + jassert (spec.numChannels > 0); + + sampleRate = spec.sampleRate; + + s1.resize (spec.numChannels); + s2.resize (spec.numChannels); + + reset(); + update(); +} + +template <typename SampleType> +void StateVariableTPTFilter<SampleType>::reset() +{ + reset (static_cast<SampleType> (0)); +} + +template <typename SampleType> +void StateVariableTPTFilter<SampleType>::reset (SampleType newValue) +{ + for (auto v : { &s1, &s2 }) + std::fill (v->begin(), v->end(), newValue); +} + +template <typename SampleType> +void StateVariableTPTFilter<SampleType>::snapToZero() noexcept +{ + for (auto v : { &s1, &s2 }) + for (auto& element : *v) + util::snapToZero (element); +} + +//============================================================================== +template <typename SampleType> +SampleType StateVariableTPTFilter<SampleType>::processSample (int channel, SampleType inputValue) +{ + auto& ls1 = s1[(size_t) channel]; + auto& ls2 = s2[(size_t) channel]; + + auto yHP = h * (inputValue - ls1 * (g + R2) - ls2); + + auto yBP = yHP * g + ls1; + ls1 = yHP * g + yBP; + + auto yLP = yBP * g + ls2; + ls2 = yBP * g + yLP; + + switch (filterType) + { + case Type::lowpass: return yLP; + case Type::bandpass: return yBP; + case Type::highpass: return yHP; + default: return yLP; + } +} + +//============================================================================== +template <typename SampleType> +void StateVariableTPTFilter<SampleType>::update() +{ + g = static_cast<SampleType> (std::tan (juce::MathConstants<double>::pi * cutoffFrequency / sampleRate)); + R2 = static_cast<SampleType> (1.0 / resonance); + h = static_cast<SampleType> (1.0 / (1.0 + R2 * g + g * g)); +} + +//============================================================================== +template class StateVariableTPTFilter<float>; +template class StateVariableTPTFilter<double>; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/processors/juce_StateVariableTPTFilter.h b/modules/juce_dsp/processors/juce_StateVariableTPTFilter.h new file mode 100644 index 00000000..32663063 --- /dev/null +++ b/modules/juce_dsp/processors/juce_StateVariableTPTFilter.h @@ -0,0 +1,166 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +enum class StateVariableTPTFilterType +{ + lowpass, + bandpass, + highpass +}; + +//============================================================================== +/** An IIR filter that can perform low, band and high-pass filtering on an audio + signal, with 12 dB of attenuation per octave, using a TPT structure, designed + for fast modulation (see Vadim Zavalishin's documentation about TPT + structures for more information). Its behaviour is based on the analog + state variable filter circuit. + + Note: The bandpass here is not the one in the RBJ CookBook as its gain can be + higher than 0 dB. For the classic 0 dB bandpass, we need to multiply the + result by R2. + + Note 2: Using this class prevents some loud audio artefacts commonly encountered when + changing the cutoff frequency using other filter simulation structures and IIR + filter classes. However, this class may still require additional smoothing for + cutoff frequency changes. + + see IIRFilter, SmoothedValue + + @tags{DSP} +*/ +template <typename SampleType> +class StateVariableTPTFilter +{ +public: + //============================================================================== + using Type = StateVariableTPTFilterType; + + //============================================================================== + /** Constructor. */ + StateVariableTPTFilter(); + + //============================================================================== + /** Sets the filter type. */ + void setType (Type newType); + + /** Sets the cutoff frequency of the filter. + + @param newFrequencyHz the new cutoff frequency in Hz. + */ + void setCutoffFrequency (SampleType newFrequencyHz); + + /** Sets the resonance of the filter. + + Note: The bandwidth of the resonance increases with the value of the + parameter. To have a standard 12 dB / octave filter, the value must be set + at 1 / sqrt(2). + */ + void setResonance (SampleType newResonance); + + //============================================================================== + /** Returns the type of the filter. */ + Type getType() const noexcept { return filterType; } + + /** Returns the cutoff frequency of the filter. */ + SampleType getCutoffFrequency() const noexcept { return cutoffFrequency; } + + /** Returns the resonance of the filter. */ + SampleType getResonance() const noexcept { return resonance; } + + //============================================================================== + /** Initialises the filter. */ + void prepare (const ProcessSpec& spec); + + /** Resets the internal state variables of the filter. */ + void reset(); + + /** Resets the internal state variables of the filter to a given value. */ + void reset (SampleType newValue); + + /** Ensure that the state variables are rounded to zero if the state + variables are denormals. This is only needed if you are doing + sample by sample processing. + */ + void snapToZero() noexcept; + + //============================================================================== + /** Processes the input and output samples supplied in the processing context. */ + template <typename ProcessContext> + void process (const ProcessContext& context) noexcept + { + const auto& inputBlock = context.getInputBlock(); + auto& outputBlock = context.getOutputBlock(); + const auto numChannels = outputBlock.getNumChannels(); + const auto numSamples = outputBlock.getNumSamples(); + + jassert (inputBlock.getNumChannels() <= s1.size()); + jassert (inputBlock.getNumChannels() == numChannels); + jassert (inputBlock.getNumSamples() == numSamples); + + if (context.isBypassed) + { + outputBlock.copyFrom (inputBlock); + return; + } + + for (size_t channel = 0; channel < numChannels; ++channel) + { + auto* inputSamples = inputBlock .getChannelPointer (channel); + auto* outputSamples = outputBlock.getChannelPointer (channel); + + for (size_t i = 0; i < numSamples; ++i) + outputSamples[i] = processSample ((int) channel, inputSamples[i]); + } + + #if JUCE_SNAP_TO_ZERO + snapToZero(); + #endif + } + + //============================================================================== + /** Processes one sample at a time on a given channel. */ + SampleType processSample (int channel, SampleType inputValue); + +private: + //============================================================================== + void update(); + + //============================================================================== + SampleType g, h, R2; + std::vector<SampleType> s1 { 2 }, s2 { 2 }; + + double sampleRate = 44100.0; + Type filterType = Type::lowpass; + SampleType cutoffFrequency = static_cast<SampleType> (1000.0), + resonance = static_cast<SampleType> (1.0 / std::sqrt (2.0)); +}; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/processors/juce_Bias.h b/modules/juce_dsp/widgets/juce_Bias.h similarity index 88% rename from modules/juce_dsp/processors/juce_Bias.h rename to modules/juce_dsp/widgets/juce_Bias.h index a279f617..77dee752 100644 --- a/modules/juce_dsp/processors/juce_Bias.h +++ b/modules/juce_dsp/widgets/juce_Bias.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -90,7 +89,7 @@ public: //============================================================================== /** Returns the result of processing a single sample. */ template <typename SampleType> - SampleType processSample (SampleType inputSample) const noexcept + SampleType processSample (SampleType inputSample) noexcept { return inputSample + bias.getNextValue(); } @@ -104,7 +103,7 @@ public: auto&& outBlock = context.getOutputBlock(); jassert (inBlock.getNumChannels() == outBlock.getNumChannels()); - jassert (inBlock.getNumSamples() == outBlock.getNumSamples()); + jassert (inBlock.getNumSamples() == outBlock.getNumSamples()); auto len = inBlock.getNumSamples(); auto numChannels = inBlock.getNumChannels(); diff --git a/modules/juce_dsp/widgets/juce_Chorus.cpp b/modules/juce_dsp/widgets/juce_Chorus.cpp new file mode 100644 index 00000000..c2711c55 --- /dev/null +++ b/modules/juce_dsp/widgets/juce_Chorus.cpp @@ -0,0 +1,138 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +//============================================================================== +template <typename SampleType> +Chorus<SampleType>::Chorus() +{ + auto oscFunction = [] (SampleType x) { return std::sin (x); }; + osc.initialise (oscFunction); + + dryWet.setMixingRule (DryWetMixingRule::linear); +} + +template <typename SampleType> +void Chorus<SampleType>::setRate (SampleType newRateHz) +{ + jassert (isPositiveAndBelow (newRateHz, static_cast<SampleType> (100.0))); + + rate = newRateHz; + update(); +} + +template <typename SampleType> +void Chorus<SampleType>::setDepth (SampleType newDepth) +{ + jassert (isPositiveAndNotGreaterThan (newDepth, static_cast<SampleType> (1.0))); + + depth = newDepth; + update(); +} + +template <typename SampleType> +void Chorus<SampleType>::setCentreDelay (SampleType newDelayMs) +{ + jassert (isPositiveAndBelow (newDelayMs, static_cast<SampleType> (100.0))); + + centreDelay = jlimit (static_cast<SampleType> (1.0), static_cast<SampleType> (100.0), newDelayMs); +} + +template <typename SampleType> +void Chorus<SampleType>::setFeedback (SampleType newFeedback) +{ + jassert (newFeedback >= static_cast<SampleType> (-1.0) && newFeedback <= static_cast<SampleType> (1.0)); + + feedback = newFeedback; + update(); +} + +template <typename SampleType> +void Chorus<SampleType>::setMix (SampleType newMix) +{ + jassert (isPositiveAndNotGreaterThan (newMix, static_cast<SampleType> (1.0))); + + mix = newMix; + update(); +} + +//============================================================================== +template <typename SampleType> +void Chorus<SampleType>::prepare (const ProcessSpec& spec) +{ + jassert (spec.sampleRate > 0); + jassert (spec.numChannels > 0); + + sampleRate = spec.sampleRate; + + delay.prepare (spec); + + dryWet.prepare (spec); + feedbackVolume.resize (spec.numChannels); + lastOutput.resize (spec.numChannels); + + osc.prepare (spec); + bufferDelayTimes.setSize (1, (int) spec.maximumBlockSize, false, false, true); + + update(); + reset(); +} + +template <typename SampleType> +void Chorus<SampleType>::reset() +{ + std::fill (lastOutput.begin(), lastOutput.end(), static_cast<SampleType> (0)); + + delay.reset(); + osc.reset(); + dryWet.reset(); + + oscVolume.reset (sampleRate, 0.05); + + for (auto& vol : feedbackVolume) + vol.reset (sampleRate, 0.05); +} + +template <typename SampleType> +void Chorus<SampleType>::update() +{ + osc.setFrequency (rate); + oscVolume.setTargetValue (depth * (SampleType) 0.5); + dryWet.setWetMixProportion (mix); + + for (auto& vol : feedbackVolume) + vol.setTargetValue (feedback); +} + +//============================================================================== +template class Chorus<float>; +template class Chorus<double>; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/widgets/juce_Chorus.h b/modules/juce_dsp/widgets/juce_Chorus.h new file mode 100644 index 00000000..273b1ee0 --- /dev/null +++ b/modules/juce_dsp/widgets/juce_Chorus.h @@ -0,0 +1,164 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +/** + A simple chorus DSP widget that modulates the delay of a delay line in order to + create sweeping notches in the magnitude frequency response. + + This audio effect can be controlled via the speed and depth of the LFO controlling + the frequency response, a mix control, a feedback control, and the centre delay + of the modulation. + + Note: To get classic chorus sounds try to use a centre delay time around 7-8 ms + with a low feeback volume and a low depth. This effect can also be used as a + flanger with a lower centre delay time and a lot of feedback, and as a vibrato + effect if the mix value is 1. + + @tags{DSP} +*/ +template <typename SampleType> +class Chorus +{ +public: + //============================================================================== + /** Constructor. */ + Chorus(); + + //============================================================================== + /** Sets the rate (in Hz) of the LFO modulating the chorus delay line. This rate + must be lower than 100 Hz. + */ + void setRate (SampleType newRateHz); + + /** Sets the volume of the LFO modulating the chorus delay line (between 0 and 1). + */ + void setDepth (SampleType newDepth); + + /** Sets the centre delay in milliseconds of the chorus delay line modulation. + This delay must be between 1 and 100 ms. + */ + void setCentreDelay (SampleType newDelayMs); + + /** Sets the feedback volume (between -1 and 1) of the chorus delay line. + Negative values can be used to get specific chorus sounds. + */ + void setFeedback (SampleType newFeedback); + + /** Sets the amount of dry and wet signal in the output of the chorus (between 0 + for full dry and 1 for full wet). + */ + void setMix (SampleType newMix); + + //============================================================================== + /** Initialises the processor. */ + void prepare (const ProcessSpec& spec); + + /** Resets the internal state variables of the processor. */ + void reset(); + + //============================================================================== + /** Processes the input and output samples supplied in the processing context. */ + template <typename ProcessContext> + void process (const ProcessContext& context) noexcept + { + const auto& inputBlock = context.getInputBlock(); + auto& outputBlock = context.getOutputBlock(); + const auto numChannels = outputBlock.getNumChannels(); + const auto numSamples = outputBlock.getNumSamples(); + + jassert (inputBlock.getNumChannels() == numChannels); + jassert (inputBlock.getNumChannels() == lastOutput.size()); + jassert (inputBlock.getNumSamples() == numSamples); + + if (context.isBypassed) + { + outputBlock.copyFrom (inputBlock); + return; + } + + auto delayValuesBlock = AudioBlock<SampleType>(bufferDelayTimes).getSubBlock (0, numSamples); + auto contextDelay = ProcessContextReplacing<SampleType> (delayValuesBlock); + delayValuesBlock.clear(); + + osc.process (contextDelay); + delayValuesBlock.multiplyBy (oscVolume); + + auto* delaySamples = bufferDelayTimes.getWritePointer (0); + + for (size_t i = 0; i < numSamples; ++i) + { + auto lfo = jmax (static_cast<SampleType> (1.0), maximumDelayModulation * delaySamples[i] + centreDelay); + delaySamples[i] = static_cast<SampleType> (lfo * sampleRate / 1000.0); + } + + dryWet.pushDrySamples (inputBlock); + + for (size_t channel = 0; channel < numChannels; ++channel) + { + auto* inputSamples = inputBlock .getChannelPointer (channel); + auto* outputSamples = outputBlock.getChannelPointer (channel); + + for (size_t i = 0; i < numSamples; ++i) + { + auto input = inputSamples[i]; + auto output = input - lastOutput[channel]; + + delay.pushSample ((int) channel, output); + delay.setDelay (delaySamples[i]); + output = delay.popSample ((int) channel); + + outputSamples[i] = output; + lastOutput[channel] = output * feedbackVolume[channel].getNextValue(); + } + } + + dryWet.mixWetSamples (outputBlock); + } + +private: + //============================================================================== + void update(); + + //============================================================================== + Oscillator<SampleType> osc; + DelayLine<SampleType, DelayLineInterpolationTypes::Linear> delay { 5000 }; + SmoothedValue<SampleType, ValueSmoothingTypes::Linear> oscVolume; + std::vector<SmoothedValue<SampleType, ValueSmoothingTypes::Linear>> feedbackVolume { 2 }; + DryWetMixer<SampleType> dryWet; + std::vector<SampleType> lastOutput { 2 }; + AudioBuffer<SampleType> bufferDelayTimes; + + double sampleRate = 44100.0; + SampleType rate = 1.0, depth = 0.25, feedback = 0.0, mix = 0.5, + centreDelay = 7.0, maximumDelayModulation = 20.0; +}; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/widgets/juce_Compressor.cpp b/modules/juce_dsp/widgets/juce_Compressor.cpp new file mode 100644 index 00000000..40564232 --- /dev/null +++ b/modules/juce_dsp/widgets/juce_Compressor.cpp @@ -0,0 +1,121 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +//============================================================================== +template <typename SampleType> +Compressor<SampleType>::Compressor() +{ + update(); +} + +//============================================================================== +template <typename SampleType> +void Compressor<SampleType>::setThreshold (SampleType newThreshold) +{ + thresholddB = newThreshold; + update(); +} + +template <typename SampleType> +void Compressor<SampleType>::setRatio (SampleType newRatio) +{ + jassert (newRatio >= static_cast<SampleType> (1.0)); + + ratio = newRatio; + update(); +} + +template <typename SampleType> +void Compressor<SampleType>::setAttack (SampleType newAttack) +{ + attackTime = newAttack; + update(); +} + +template <typename SampleType> +void Compressor<SampleType>::setRelease (SampleType newRelease) +{ + releaseTime = newRelease; + update(); +} + +//============================================================================== +template <typename SampleType> +void Compressor<SampleType>::prepare (const ProcessSpec& spec) +{ + jassert (spec.sampleRate > 0); + jassert (spec.numChannels > 0); + + sampleRate = spec.sampleRate; + + envelopeFilter.prepare (spec); + + update(); + reset(); +} + +template <typename SampleType> +void Compressor<SampleType>::reset() +{ + envelopeFilter.reset(); +} + +//============================================================================== +template <typename SampleType> +SampleType Compressor<SampleType>::processSample (int channel, SampleType inputValue) +{ + // Ballistics filter with peak rectifier + auto env = envelopeFilter.processSample (channel, inputValue); + + // VCA + auto gain = (env < threshold) ? static_cast<SampleType> (1.0) + : std::pow (env * thresholdInverse, ratioInverse - static_cast<SampleType> (1.0)); + + // Output + return gain * inputValue; +} + +template <typename SampleType> +void Compressor<SampleType>::update() +{ + threshold = Decibels::decibelsToGain (thresholddB, static_cast<SampleType> (-200.0)); + thresholdInverse = static_cast<SampleType> (1.0) / threshold; + ratioInverse = static_cast<SampleType> (1.0) / ratio; + + envelopeFilter.setAttackTime (attackTime); + envelopeFilter.setReleaseTime (releaseTime); +} + +//============================================================================== +template class Compressor<float>; +template class Compressor<double>; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/widgets/juce_Compressor.h b/modules/juce_dsp/widgets/juce_Compressor.h new file mode 100644 index 00000000..b9df60df --- /dev/null +++ b/modules/juce_dsp/widgets/juce_Compressor.h @@ -0,0 +1,110 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +/** + A simple compressor with standard threshold, ratio, attack time and release time + controls. + + @tags{DSP} +*/ +template <typename SampleType> +class Compressor +{ +public: + //============================================================================== + /** Constructor. */ + Compressor(); + + //============================================================================== + /** Sets the threshold in dB of the compressor.*/ + void setThreshold (SampleType newThreshold); + + /** Sets the ratio of the compressor (must be higher or equal to 1).*/ + void setRatio (SampleType newRatio); + + /** Sets the attack time in milliseconds of the compressor.*/ + void setAttack (SampleType newAttack); + + /** Sets the release time in milliseconds of the compressor.*/ + void setRelease (SampleType newRelease); + + //============================================================================== + /** Initialises the processor. */ + void prepare (const ProcessSpec& spec); + + /** Resets the internal state variables of the processor. */ + void reset(); + + //============================================================================== + /** Processes the input and output samples supplied in the processing context. */ + template <typename ProcessContext> + void process (const ProcessContext& context) noexcept + { + const auto& inputBlock = context.getInputBlock(); + auto& outputBlock = context.getOutputBlock(); + const auto numChannels = outputBlock.getNumChannels(); + const auto numSamples = outputBlock.getNumSamples(); + + jassert (inputBlock.getNumChannels() == numChannels); + jassert (inputBlock.getNumSamples() == numSamples); + + if (context.isBypassed) + { + outputBlock.copyFrom (inputBlock); + return; + } + + for (size_t channel = 0; channel < numChannels; ++channel) + { + auto* inputSamples = inputBlock .getChannelPointer (channel); + auto* outputSamples = outputBlock.getChannelPointer (channel); + + for (size_t i = 0; i < numSamples; ++i) + outputSamples[i] = processSample ((int) channel, inputSamples[i]); + } + } + + /** Performs the processing operation on a single sample at a time. */ + SampleType processSample (int channel, SampleType inputValue); + +private: + //============================================================================== + void update(); + + //============================================================================== + SampleType threshold, thresholdInverse, ratioInverse; + BallisticsFilter<SampleType> envelopeFilter; + + double sampleRate = 44100.0; + SampleType thresholddB = 0.0, ratio = 1.0, attackTime = 1.0, releaseTime = 100.0; +}; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/processors/juce_Gain.h b/modules/juce_dsp/widgets/juce_Gain.h similarity index 91% rename from modules/juce_dsp/processors/juce_Gain.h rename to modules/juce_dsp/widgets/juce_Gain.h index 21a3391d..adb03b14 100644 --- a/modules/juce_dsp/processors/juce_Gain.h +++ b/modules/juce_dsp/widgets/juce_Gain.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_dsp/widgets/juce_LadderFilter.cpp b/modules/juce_dsp/widgets/juce_LadderFilter.cpp new file mode 100644 index 00000000..c6fc8143 --- /dev/null +++ b/modules/juce_dsp/widgets/juce_LadderFilter.cpp @@ -0,0 +1,176 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +//============================================================================== +template <typename SampleType> +LadderFilter<SampleType>::LadderFilter() : state (2) +{ + setSampleRate (SampleType (1000)); // intentionally setting unrealistic default + // sample rate to catch missing initialisation bugs + setResonance (SampleType (0)); + setDrive (SampleType (1.2)); + + mode = Mode::LPF24; + setMode (Mode::LPF12); +} + +//============================================================================== +template <typename SampleType> +void LadderFilter<SampleType>::setMode (Mode newMode) noexcept +{ + if (newMode == mode) + return; + + switch (newMode) + { + case Mode::LPF12: A = {{ SampleType (0), SampleType (0), SampleType (1), SampleType (0), SampleType (0) }}; comp = SampleType (0.5); break; + case Mode::HPF12: A = {{ SampleType (1), SampleType (-2), SampleType (1), SampleType (0), SampleType (0) }}; comp = SampleType (0); break; + case Mode::BPF12: A = {{ SampleType (0), SampleType (0), SampleType (-1), SampleType (1), SampleType (0) }}; comp = SampleType (0.5); break; + case Mode::LPF24: A = {{ SampleType (0), SampleType (0), SampleType (0), SampleType (0), SampleType (1) }}; comp = SampleType (0.5); break; + case Mode::HPF24: A = {{ SampleType (1), SampleType (-4), SampleType (6), SampleType (-4), SampleType (1) }}; comp = SampleType (0); break; + case Mode::BPF24: A = {{ SampleType (0), SampleType (0), SampleType (1), SampleType (-2), SampleType (1) }}; comp = SampleType (0.5); break; + default: jassertfalse; break; + } + + static constexpr auto outputGain = SampleType (1.2); + + for (auto& a : A) + a *= outputGain; + + mode = newMode; + reset(); +} + +//============================================================================== +template <typename SampleType> +void LadderFilter<SampleType>::prepare (const ProcessSpec& spec) +{ + setSampleRate (SampleType (spec.sampleRate)); + setNumChannels (spec.numChannels); + reset(); +} + +//============================================================================== +template <typename SampleType> +void LadderFilter<SampleType>::reset() noexcept +{ + for (auto& s : state) + s.fill (SampleType (0)); + + cutoffTransformSmoother.setCurrentAndTargetValue (cutoffTransformSmoother.getTargetValue()); + scaledResonanceSmoother.setCurrentAndTargetValue (scaledResonanceSmoother.getTargetValue()); +} + +//============================================================================== +template <typename SampleType> +void LadderFilter<SampleType>::setCutoffFrequencyHz (SampleType newCutoff) noexcept +{ + jassert (newCutoff > SampleType (0)); + cutoffFreqHz = newCutoff; + updateCutoffFreq(); +} + +//============================================================================== +template <typename SampleType> +void LadderFilter<SampleType>::setResonance (SampleType newResonance) noexcept +{ + jassert (newResonance >= SampleType (0) && newResonance <= SampleType (1)); + resonance = newResonance; + updateResonance(); +} + +//============================================================================== +template <typename SampleType> +void LadderFilter<SampleType>::setDrive (SampleType newDrive) noexcept +{ + jassert (newDrive >= SampleType (1)); + + drive = newDrive; + gain = std::pow (drive, SampleType (-2.642)) * SampleType (0.6103) + SampleType (0.3903); + drive2 = drive * SampleType (0.04) + SampleType (0.96); + gain2 = std::pow (drive2, SampleType (-2.642)) * SampleType (0.6103) + SampleType (0.3903); +} + +//============================================================================== +template <typename SampleType> +SampleType LadderFilter<SampleType>::processSample (SampleType inputValue, size_t channelToUse) noexcept +{ + auto& s = state[channelToUse]; + + const auto a1 = cutoffTransformValue; + const auto g = a1 * SampleType (-1) + SampleType (1); + const auto b0 = g * SampleType (0.76923076923); + const auto b1 = g * SampleType (0.23076923076); + + const auto dx = gain * saturationLUT (drive * inputValue); + const auto a = dx + scaledResonanceValue * SampleType (-4) * (gain2 * saturationLUT (drive2 * s[4]) - dx * comp); + + const auto b = b1 * s[0] + a1 * s[1] + b0 * a; + const auto c = b1 * s[1] + a1 * s[2] + b0 * b; + const auto d = b1 * s[2] + a1 * s[3] + b0 * c; + const auto e = b1 * s[3] + a1 * s[4] + b0 * d; + + s[0] = a; + s[1] = b; + s[2] = c; + s[3] = d; + s[4] = e; + + return a * A[0] + b * A[1] + c * A[2] + d * A[3] + e * A[4]; +} + +//============================================================================== +template <typename SampleType> +void LadderFilter<SampleType>::updateSmoothers() noexcept +{ + cutoffTransformValue = cutoffTransformSmoother.getNextValue(); + scaledResonanceValue = scaledResonanceSmoother.getNextValue(); +} + +//============================================================================== +template <typename SampleType> +void LadderFilter<SampleType>::setSampleRate (SampleType newValue) noexcept +{ + jassert (newValue > SampleType (0)); + cutoffFreqScaler = SampleType (-2.0 * juce::MathConstants<double>::pi) / newValue; + + static constexpr SampleType smootherRampTimeSec = SampleType (0.05); + cutoffTransformSmoother.reset (newValue, smootherRampTimeSec); + scaledResonanceSmoother.reset (newValue, smootherRampTimeSec); + + updateCutoffFreq(); +} + +//============================================================================== +template class LadderFilter<float>; +template class LadderFilter<double>; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/processors/juce_LadderFilter.h b/modules/juce_dsp/widgets/juce_LadderFilter.h similarity index 55% rename from modules/juce_dsp/processors/juce_LadderFilter.h rename to modules/juce_dsp/widgets/juce_LadderFilter.h index 7b2e7a8a..d1b21122 100644 --- a/modules/juce_dsp/processors/juce_LadderFilter.h +++ b/modules/juce_dsp/widgets/juce_LadderFilter.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -29,62 +28,73 @@ namespace juce namespace dsp { +enum class LadderFilterMode +{ + LPF12, // low-pass 12 dB/octave + HPF12, // high-pass 12 dB/octave + BPF12, // band-pass 12 dB/octave + LPF24, // low-pass 24 dB/octave + HPF24, // high-pass 24 dB/octave + BPF24 // band-pass 24 dB/octave +}; + /** Multi-mode filter based on the Moog ladder filter. @tags{DSP} */ -template <typename Type> +template <typename SampleType> class LadderFilter { public: - enum class Mode - { - LPF12, // low-pass 12 dB/octave - HPF12, // high-pass 12 dB/octave - LPF24, // low-pass 24 dB/octave - HPF24 // high-pass 24 dB/octave - }; + //============================================================================== + using Mode = LadderFilterMode; //============================================================================== /** Creates an uninitialised filter. Call prepare() before first use. */ LadderFilter(); /** Enables or disables the filter. If disabled it will simply pass through the input signal. */ - void setEnabled (bool newValue) noexcept { enabled = newValue; } + void setEnabled (bool isEnabled) noexcept { enabled = isEnabled; } /** Sets filter mode. */ - void setMode (Mode newValue) noexcept; + void setMode (Mode newMode) noexcept; /** Initialises the filter. */ - void prepare (const juce::dsp::ProcessSpec& spec); + void prepare (const ProcessSpec& spec); /** Returns the current number of channels. */ - size_t getNumChannels() const noexcept { return state.size(); } + size_t getNumChannels() const noexcept { return state.size(); } /** Resets the internal state variables of the filter. */ void reset() noexcept; /** Sets the cutoff frequency of the filter. - @param newValue cutoff frequency in Hz */ - void setCutoffFrequencyHz (Type newValue) noexcept; + + @param newCutoff cutoff frequency in Hz + */ + void setCutoffFrequencyHz (SampleType newCutoff) noexcept; /** Sets the resonance of the filter. - @param newValue a value between 0 and 1; higher values increase the resonance and can result in self oscillation! */ - void setResonance (Type newValue) noexcept; + + @param newResonance a value between 0 and 1; higher values increase the resonance and can result in self oscillation! + */ + void setResonance (SampleType newResonance) noexcept; /** Sets the amount of saturation in the filter. - @param newValue saturation amount; it can be any number greater than or equal to one. Higher values result in more distortion.*/ - void setDrive (Type newValue) noexcept; + + @param newDrive saturation amount; it can be any number greater than or equal to one. Higher values result in more distortion. + */ + void setDrive (SampleType newDrive) noexcept; //============================================================================== template <typename ProcessContext> void process (const ProcessContext& context) noexcept { const auto& inputBlock = context.getInputBlock(); - auto& outputBlock = context.getOutputBlock(); + auto& outputBlock = context.getOutputBlock(); const auto numChannels = outputBlock.getNumChannels(); - const auto numSamples = outputBlock.getNumSamples(); + const auto numSamples = outputBlock.getNumSamples(); jassert (inputBlock.getNumChannels() <= getNumChannels()); jassert (inputBlock.getNumChannels() == numChannels); @@ -107,35 +117,36 @@ public: protected: //============================================================================== - Type processSample (Type inputValue, size_t channelToUse) noexcept; + SampleType processSample (SampleType inputValue, size_t channelToUse) noexcept; void updateSmoothers() noexcept; private: //============================================================================== - Type drive, drive2, gain, gain2, comp; + void setSampleRate (SampleType newValue) noexcept; + void setNumChannels (size_t newValue) { state.resize (newValue); } + void updateCutoffFreq() noexcept { cutoffTransformSmoother.setTargetValue (std::exp (cutoffFreqHz * cutoffFreqScaler)); } + void updateResonance() noexcept { scaledResonanceSmoother.setTargetValue (jmap (resonance, SampleType (0.1), SampleType (1.0))); } + + //============================================================================== + SampleType drive, drive2, gain, gain2, comp; static constexpr size_t numStates = 5; - std::vector<std::array<Type, numStates>> state; - std::array<Type, numStates> A; + std::vector<std::array<SampleType, numStates>> state; + std::array<SampleType, numStates> A; - SmoothedValue<Type> cutoffTransformSmoother, scaledResonanceSmoother; - Type cutoffTransformValue, scaledResonanceValue; + SmoothedValue<SampleType> cutoffTransformSmoother, scaledResonanceSmoother; + SampleType cutoffTransformValue, scaledResonanceValue; - LookupTableTransform<Type> saturationLUT { [] (Type x) { return std::tanh (x); }, Type (-5), Type (5), 128 }; + LookupTableTransform<SampleType> saturationLUT { [] (SampleType x) { return std::tanh (x); }, + SampleType (-5), SampleType (5), 128 }; - Type cutoffFreqHz { Type (200) }; - Type resonance; + SampleType cutoffFreqHz { SampleType (200) }; + SampleType resonance; - Type cutoffFreqScaler; + SampleType cutoffFreqScaler; Mode mode; bool enabled = true; - - //============================================================================== - void setSampleRate (Type newValue) noexcept; - void setNumChannels (size_t newValue) { state.resize (newValue); } - void updateCutoffFreq() noexcept { cutoffTransformSmoother.setTargetValue (std::exp (cutoffFreqHz * cutoffFreqScaler)); } - void updateResonance() noexcept { scaledResonanceSmoother.setTargetValue (jmap (resonance, Type (0.1), Type (1.0))); } }; } // namespace dsp diff --git a/modules/juce_dsp/widgets/juce_Limiter.cpp b/modules/juce_dsp/widgets/juce_Limiter.cpp new file mode 100644 index 00000000..6c41ded4 --- /dev/null +++ b/modules/juce_dsp/widgets/juce_Limiter.cpp @@ -0,0 +1,98 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +//============================================================================== +template <typename SampleType> +void Limiter<SampleType>::setThreshold (SampleType newThreshold) +{ + thresholddB = newThreshold; + update(); +} + +template <typename SampleType> +void Limiter<SampleType>::setRelease (SampleType newRelease) +{ + releaseTime = newRelease; + update(); +} + +//============================================================================== +template <typename SampleType> +void Limiter<SampleType>::prepare (const ProcessSpec& spec) +{ + jassert (spec.sampleRate > 0); + jassert (spec.numChannels > 0); + + sampleRate = spec.sampleRate; + + firstStageCompressor.prepare (spec); + secondStageCompressor.prepare (spec); + + update(); + reset(); +} + +template <typename SampleType> +void Limiter<SampleType>::reset() +{ + firstStageCompressor.reset(); + secondStageCompressor.reset(); + + outputVolume.reset (sampleRate, 0.001); +} + +//============================================================================== +template <typename SampleType> +void Limiter<SampleType>::update() +{ + firstStageCompressor.setThreshold ((SampleType) -10.0); + firstStageCompressor.setRatio ((SampleType) 4.0); + firstStageCompressor.setAttack ((SampleType) 2.0); + firstStageCompressor.setRelease ((SampleType) 200.0); + + secondStageCompressor.setThreshold (thresholddB); + secondStageCompressor.setRatio ((SampleType) 1000.0); + secondStageCompressor.setAttack ((SampleType) 0.001); + secondStageCompressor.setRelease (releaseTime); + + auto ratioInverse = (SampleType) (1.0 / 4.0); + + auto gain = (SampleType) std::pow (10.0, 10.0 * (1.0 - ratioInverse) / 40.0); + gain *= Decibels::decibelsToGain (-thresholddB, (SampleType) -100.0); + + outputVolume.setTargetValue (gain); +} + +//============================================================================== +template class Limiter<float>; +template class Limiter<double>; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/widgets/juce_Limiter.h b/modules/juce_dsp/widgets/juce_Limiter.h new file mode 100644 index 00000000..b951ffdb --- /dev/null +++ b/modules/juce_dsp/widgets/juce_Limiter.h @@ -0,0 +1,105 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +/** + A simple limiter with standard threshold and release time controls, featuring + two compressors and a hard clipper at 0 dB. + + @tags{DSP} +*/ +template <typename SampleType> +class Limiter +{ +public: + //============================================================================== + /** Constructor. */ + Limiter() = default; + + //============================================================================== + /** Sets the threshold in dB of the limiter.*/ + void setThreshold (SampleType newThreshold); + + /** Sets the release time in milliseconds of the limiter.*/ + void setRelease (SampleType newRelease); + + //============================================================================== + /** Initialises the processor. */ + void prepare (const ProcessSpec& spec); + + /** Resets the internal state variables of the processor. */ + void reset(); + + //============================================================================== + /** Processes the input and output samples supplied in the processing context. */ + template <typename ProcessContext> + void process (const ProcessContext& context) noexcept + { + const auto& inputBlock = context.getInputBlock(); + auto& outputBlock = context.getOutputBlock(); + const auto numChannels = outputBlock.getNumChannels(); + const auto numSamples = outputBlock.getNumSamples(); + + jassert (inputBlock.getNumChannels() == numChannels); + jassert (inputBlock.getNumSamples() == numSamples); + + if (context.isBypassed) + { + outputBlock.copyFrom (inputBlock); + return; + } + + firstStageCompressor.process (context); + + auto secondContext = ProcessContextReplacing<SampleType> (outputBlock); + secondStageCompressor.process (secondContext); + + outputBlock.multiplyBy (outputVolume); + + for (size_t channel = 0; channel < numChannels; ++channel) + { + FloatVectorOperations::clip (outputBlock.getChannelPointer (channel), outputBlock.getChannelPointer (channel), + (SampleType) -1.0, (SampleType) 1.0, (int) numSamples); + } + } + +private: + //============================================================================== + void update(); + + //============================================================================== + Compressor<SampleType> firstStageCompressor, secondStageCompressor; + SmoothedValue<SampleType, ValueSmoothingTypes::Linear> outputVolume; + + double sampleRate = 44100.0; + SampleType thresholddB = -10.0, releaseTime = 100.0; +}; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/widgets/juce_NoiseGate.cpp b/modules/juce_dsp/widgets/juce_NoiseGate.cpp new file mode 100644 index 00000000..af914bfa --- /dev/null +++ b/modules/juce_dsp/widgets/juce_NoiseGate.cpp @@ -0,0 +1,129 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +//============================================================================== +template <typename SampleType> +NoiseGate<SampleType>::NoiseGate() +{ + update(); + + RMSFilter.setLevelCalculationType (BallisticsFilterLevelCalculationType::RMS); + RMSFilter.setAttackTime (static_cast<SampleType> (0.0)); + RMSFilter.setReleaseTime (static_cast<SampleType> (50.0)); +} + +template <typename SampleType> +void NoiseGate<SampleType>::setThreshold (SampleType newValue) +{ + thresholddB = newValue; + update(); +} + +template <typename SampleType> +void NoiseGate<SampleType>::setRatio (SampleType newRatio) +{ + jassert (newRatio >= static_cast<SampleType> (1.0)); + + ratio = newRatio; + update(); +} + +template <typename SampleType> +void NoiseGate<SampleType>::setAttack (SampleType newAttack) +{ + attackTime = newAttack; + update(); +} + +template <typename SampleType> +void NoiseGate<SampleType>::setRelease (SampleType newRelease) +{ + releaseTime = newRelease; + update(); +} + +//============================================================================== +template <typename SampleType> +void NoiseGate<SampleType>::prepare (const ProcessSpec& spec) +{ + jassert (spec.sampleRate > 0); + jassert (spec.numChannels > 0); + + sampleRate = spec.sampleRate; + + RMSFilter.prepare (spec); + envelopeFilter.prepare (spec); + + update(); + reset(); +} + +template <typename SampleType> +void NoiseGate<SampleType>::reset() +{ + RMSFilter.reset(); + envelopeFilter.reset(); +} + +//============================================================================== +template <typename SampleType> +SampleType NoiseGate<SampleType>::processSample (int channel, SampleType sample) +{ + // RMS ballistics filter + auto env = RMSFilter.processSample (channel, sample); + + // Ballistics filter + env = envelopeFilter.processSample (channel, env); + + // VCA + auto gain = (env > threshold) ? static_cast<SampleType> (1.0) + : std::pow (env * thresholdInverse, currentRatio - static_cast<SampleType> (1.0)); + + // Output + return gain * sample; +} + +template <typename SampleType> +void NoiseGate<SampleType>::update() +{ + threshold = Decibels::decibelsToGain (thresholddB, static_cast<SampleType> (-200.0)); + thresholdInverse = static_cast<SampleType> (1.0) / threshold; + currentRatio = ratio; + + envelopeFilter.setAttackTime (attackTime); + envelopeFilter.setReleaseTime (releaseTime); +} + +//============================================================================== +template class NoiseGate<float>; +template class NoiseGate<double>; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/widgets/juce_NoiseGate.h b/modules/juce_dsp/widgets/juce_NoiseGate.h new file mode 100644 index 00000000..4975e734 --- /dev/null +++ b/modules/juce_dsp/widgets/juce_NoiseGate.h @@ -0,0 +1,110 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +/** + A simple noise gate with standard threshold, ratio, attack time and + release time controls. Can be used as an expander if the ratio is low. + + @tags{DSP} +*/ +template <typename SampleType> +class NoiseGate +{ +public: + //============================================================================== + /** Constructor. */ + NoiseGate(); + + //============================================================================== + /** Sets the threshold in dB of the noise-gate.*/ + void setThreshold (SampleType newThreshold); + + /** Sets the ratio of the noise-gate (must be higher or equal to 1).*/ + void setRatio (SampleType newRatio); + + /** Sets the attack time in milliseconds of the noise-gate.*/ + void setAttack (SampleType newAttack); + + /** Sets the release time in milliseconds of the noise-gate.*/ + void setRelease (SampleType newRelease); + + //============================================================================== + /** Initialises the processor. */ + void prepare (const ProcessSpec& spec); + + /** Resets the internal state variables of the processor. */ + void reset(); + + //============================================================================== + /** Processes the input and output samples supplied in the processing context. */ + template <typename ProcessContext> + void process (const ProcessContext& context) noexcept + { + const auto& inputBlock = context.getInputBlock(); + auto& outputBlock = context.getOutputBlock(); + const auto numChannels = outputBlock.getNumChannels(); + const auto numSamples = outputBlock.getNumSamples(); + + jassert (inputBlock.getNumChannels() == numChannels); + jassert (inputBlock.getNumSamples() == numSamples); + + if (context.isBypassed) + { + outputBlock.copyFrom (inputBlock); + return; + } + + for (size_t channel = 0; channel < numChannels; ++channel) + { + auto* inputSamples = inputBlock .getChannelPointer (channel); + auto* outputSamples = outputBlock.getChannelPointer (channel); + + for (size_t i = 0; i < numSamples; ++i) + outputSamples[i] = processSample ((int) channel, inputSamples[i]); + } + } + + /** Performs the processing operation on a single sample at a time. */ + SampleType processSample (int channel, SampleType inputValue); + +private: + //============================================================================== + void update(); + + //============================================================================== + SampleType threshold, thresholdInverse, currentRatio; + BallisticsFilter<SampleType> envelopeFilter, RMSFilter; + + double sampleRate = 44100.0; + SampleType thresholddB = -100, ratio = 10.0, attackTime = 1.0, releaseTime = 100.0; +}; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/processors/juce_Oscillator.h b/modules/juce_dsp/widgets/juce_Oscillator.h similarity index 91% rename from modules/juce_dsp/processors/juce_Oscillator.h rename to modules/juce_dsp/widgets/juce_Oscillator.h index c3bb2da3..1976da1f 100644 --- a/modules/juce_dsp/processors/juce_Oscillator.h +++ b/modules/juce_dsp/widgets/juce_Oscillator.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -51,7 +50,7 @@ public: If lookup table is not zero, then the function will be approximated with a lookup table. */ - Oscillator (const std::function<NumericType(NumericType)>& function, + Oscillator (const std::function<NumericType (NumericType)>& function, size_t lookupTableNumPoints = 0) { initialise (function, lookupTableNumPoints); @@ -61,7 +60,7 @@ public: bool isInitialised() const noexcept { return static_cast<bool> (generator); } /** Initialises the oscillator with a waveform. */ - void initialise (const std::function<NumericType(NumericType)>& function, + void initialise (const std::function<NumericType (NumericType)>& function, size_t lookupTableNumPoints = 0) { if (lookupTableNumPoints != 0) @@ -240,7 +239,7 @@ public: private: //============================================================================== - std::function<NumericType(NumericType)> generator; + std::function<NumericType (NumericType)> generator; std::unique_ptr<LookupTableTransform<NumericType>> lookupTable; Array<NumericType> rampBuffer; SmoothedValue<NumericType> frequency { static_cast<NumericType> (440.0) }; diff --git a/modules/juce_dsp/widgets/juce_Phaser.cpp b/modules/juce_dsp/widgets/juce_Phaser.cpp new file mode 100644 index 00000000..804d34fd --- /dev/null +++ b/modules/juce_dsp/widgets/juce_Phaser.cpp @@ -0,0 +1,154 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +//============================================================================== +template <typename SampleType> +Phaser<SampleType>::Phaser() +{ + auto oscFunction = [] (SampleType x) { return std::sin (x); }; + osc.initialise (oscFunction); + + for (auto n = 0; n < numStages; ++n) + { + filters.add (new FirstOrderTPTFilter<SampleType>()); + filters[n]->setType (FirstOrderTPTFilterType::allpass); + } + + dryWet.setMixingRule (DryWetMixingRule::linear); +} + +template <typename SampleType> +void Phaser<SampleType>::setRate (SampleType newRateHz) +{ + jassert (isPositiveAndBelow (newRateHz, static_cast<SampleType> (100.0))); + + rate = newRateHz; + update(); +} + +template <typename SampleType> +void Phaser<SampleType>::setDepth (SampleType newDepth) +{ + jassert (isPositiveAndNotGreaterThan (newDepth, static_cast<SampleType> (1.0))); + + depth = newDepth; + update(); +} + +template <typename SampleType> +void Phaser<SampleType>::setCentreFrequency (SampleType newCentreHz) +{ + jassert (isPositiveAndBelow (newCentreHz, static_cast<SampleType> (sampleRate * 0.5))); + + centreFrequency = newCentreHz; + normCentreFrequency = mapFromLog10 (centreFrequency, static_cast<SampleType> (20.0), static_cast<SampleType> (jmin (20000.0, 0.49 * sampleRate))); +} + +template <typename SampleType> +void Phaser<SampleType>::setFeedback (SampleType newFeedback) +{ + jassert (newFeedback >= static_cast<SampleType> (-1.0) && newFeedback <= static_cast<SampleType> (1.0)); + + feedback = newFeedback; + update(); +} + +template <typename SampleType> +void Phaser<SampleType>::setMix (SampleType newMix) +{ + jassert (isPositiveAndNotGreaterThan (newMix, static_cast<SampleType> (1.0))); + + mix = newMix; + update(); +} + +//============================================================================== +template <typename SampleType> +void Phaser<SampleType>::prepare (const ProcessSpec& spec) +{ + jassert (spec.sampleRate > 0); + jassert (spec.numChannels > 0); + + sampleRate = spec.sampleRate; + + for (auto n = 0; n < numStages; ++n) + filters[n]->prepare (spec); + + dryWet.prepare (spec); + feedbackVolume.resize (spec.numChannels); + lastOutput.resize (spec.numChannels); + + auto specDown = spec; + specDown.sampleRate /= (double) maxUpdateCounter; + specDown.maximumBlockSize = specDown.maximumBlockSize / (uint32) maxUpdateCounter + 1; + + osc.prepare (specDown); + bufferFrequency.setSize (1, (int) specDown.maximumBlockSize, false, false, true); + + update(); + reset(); +} + +template <typename SampleType> +void Phaser<SampleType>::reset() +{ + std::fill (lastOutput.begin(), lastOutput.end(), static_cast<SampleType> (0)); + + for (auto n = 0; n < numStages; ++n) + filters[n]->reset(); + + osc.reset(); + dryWet.reset(); + + oscVolume.reset (sampleRate / (double) maxUpdateCounter, 0.05); + + for (auto& vol : feedbackVolume) + vol.reset (sampleRate, 0.05); + + updateCounter = 0; +} + +template <typename SampleType> +void Phaser<SampleType>::update() +{ + osc.setFrequency (rate); + oscVolume.setTargetValue (depth * (SampleType) 0.5); + dryWet.setWetMixProportion (mix); + + for (auto& vol : feedbackVolume) + vol.setTargetValue (feedback); +} + +//============================================================================== +template class Phaser<float>; +template class Phaser<double>; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/widgets/juce_Phaser.h b/modules/juce_dsp/widgets/juce_Phaser.h new file mode 100644 index 00000000..a1745ccf --- /dev/null +++ b/modules/juce_dsp/widgets/juce_Phaser.h @@ -0,0 +1,206 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace dsp +{ + +/** + A 6 stage phaser that modulates first order all-pass filters to create sweeping + notches in the magnitude frequency response. + + This audio effect can be controlled with standard phaser parameters: the speed + and depth of the LFO controlling the frequency response, a mix control, a + feedback control, and the centre frequency of the modulation. + + @tags{DSP} +*/ +template <typename SampleType> +class Phaser +{ +public: + //============================================================================== + /** Constructor. */ + Phaser(); + + //============================================================================== + /** Sets the rate (in Hz) of the LFO modulating the phaser all-pass filters. This + rate must be lower than 100 Hz. + */ + void setRate (SampleType newRateHz); + + /** Sets the volume (between 0 and 1) of the LFO modulating the phaser all-pass + filters. + */ + void setDepth (SampleType newDepth); + + /** Sets the centre frequency (in Hz) of the phaser all-pass filters modulation. + */ + void setCentreFrequency (SampleType newCentreHz); + + /** Sets the feedback volume (between -1 and 1) of the phaser. Negative can be + used to get specific phaser sounds. + */ + void setFeedback (SampleType newFeedback); + + /** Sets the amount of dry and wet signal in the output of the phaser (between 0 + for full dry and 1 for full wet). + */ + void setMix (SampleType newMix); + + //============================================================================== + /** Initialises the processor. */ + void prepare (const ProcessSpec& spec); + + /** Resets the internal state variables of the processor. */ + void reset(); + + //============================================================================== + /** Processes the input and output samples supplied in the processing context. */ + template <typename ProcessContext> + void process (const ProcessContext& context) noexcept + { + const auto& inputBlock = context.getInputBlock(); + auto& outputBlock = context.getOutputBlock(); + const auto numChannels = outputBlock.getNumChannels(); + const auto numSamples = outputBlock.getNumSamples(); + + jassert (inputBlock.getNumChannels() == numChannels); + jassert (inputBlock.getNumChannels() == lastOutput.size()); + jassert (inputBlock.getNumSamples() == numSamples); + + if (context.isBypassed) + { + outputBlock.copyFrom (inputBlock); + return; + } + + int numSamplesDown = 0; + auto counter = updateCounter; + + for (size_t i = 0; i < numSamples; ++i) + { + if (counter == 0) + numSamplesDown++; + + counter++; + + if (counter == maxUpdateCounter) + counter = 0; + } + + if (numSamplesDown > 0) + { + auto freqBlock = AudioBlock<SampleType>(bufferFrequency).getSubBlock (0, (size_t) numSamplesDown); + auto contextFreq = ProcessContextReplacing<SampleType> (freqBlock); + freqBlock.clear(); + + osc.process (contextFreq); + freqBlock.multiplyBy (oscVolume); + } + + auto* freqSamples = bufferFrequency.getWritePointer (0); + + for (int i = 0; i < numSamplesDown; ++i) + { + auto lfo = jlimit (static_cast<SampleType> (0.0), + static_cast<SampleType> (1.0), + freqSamples[i] + normCentreFrequency); + + freqSamples[i] = mapToLog10 (lfo, static_cast<SampleType> (20.0), + static_cast<SampleType> (jmin (20000.0, 0.49 * sampleRate))); + } + + auto currentFrequency = filters[0]->getCutoffFrequency(); + dryWet.pushDrySamples (inputBlock); + + for (size_t channel = 0; channel < numChannels; ++channel) + { + counter = updateCounter; + int k = 0; + + auto* inputSamples = inputBlock .getChannelPointer (channel); + auto* outputSamples = outputBlock.getChannelPointer (channel); + + for (size_t i = 0; i < numSamples; ++i) + { + auto input = inputSamples[i]; + auto output = input - lastOutput[channel]; + + if (i == 0 && counter != 0) + for (int n = 0; n < numStages; ++n) + filters[n]->setCutoffFrequency (currentFrequency); + + if (counter == 0) + { + for (int n = 0; n < numStages; ++n) + filters[n]->setCutoffFrequency (freqSamples[k]); + + k++; + } + + for (int n = 0; n < numStages; ++n) + output = filters[n]->processSample ((int) channel, output); + + outputSamples[i] = output; + lastOutput[channel] = output * feedbackVolume[channel].getNextValue(); + + counter++; + + if (counter == maxUpdateCounter) + counter = 0; + } + } + + dryWet.mixWetSamples (outputBlock); + updateCounter = (updateCounter + (int) numSamples) % maxUpdateCounter; + } + +private: + //============================================================================== + void update(); + + //============================================================================== + Oscillator<SampleType> osc; + OwnedArray<FirstOrderTPTFilter<SampleType>> filters; + SmoothedValue<SampleType, ValueSmoothingTypes::Linear> oscVolume; + std::vector<SmoothedValue<SampleType, ValueSmoothingTypes::Linear>> feedbackVolume { 2 }; + DryWetMixer<SampleType> dryWet; + std::vector<SampleType> lastOutput { 2 }; + AudioBuffer<SampleType> bufferFrequency; + SampleType normCentreFrequency = 0.5; + double sampleRate = 44100.0; + + int updateCounter = 0; + static constexpr int maxUpdateCounter = 4; + + SampleType rate = 1.0, depth = 0.5, feedback = 0.0, mix = 0.5; + SampleType centreFrequency = 1300.0; + static constexpr int numStages = 6; +}; + +} // namespace dsp +} // namespace juce diff --git a/modules/juce_dsp/processors/juce_Reverb.h b/modules/juce_dsp/widgets/juce_Reverb.h similarity index 87% rename from modules/juce_dsp/processors/juce_Reverb.h rename to modules/juce_dsp/widgets/juce_Reverb.h index 3e75a55b..83034321 100644 --- a/modules/juce_dsp/processors/juce_Reverb.h +++ b/modules/juce_dsp/widgets/juce_Reverb.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -61,7 +60,7 @@ public: //============================================================================== /** Initialises the reverb. */ - void prepare (const juce::dsp::ProcessSpec& spec) + void prepare (const ProcessSpec& spec) { reverb.setSampleRate (spec.sampleRate); } diff --git a/modules/juce_dsp/processors/juce_WaveShaper.h b/modules/juce_dsp/widgets/juce_WaveShaper.h similarity index 85% rename from modules/juce_dsp/processors/juce_WaveShaper.h rename to modules/juce_dsp/widgets/juce_WaveShaper.h index 8a2c624a..6b708b76 100644 --- a/modules/juce_dsp/processors/juce_WaveShaper.h +++ b/modules/juce_dsp/widgets/juce_WaveShaper.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -74,7 +73,7 @@ struct WaveShaper //============================================================================== // Although clang supports C++17, their standard library still has no invoke_result // support. Remove the "|| JUCE_CLANG" once clang supports this properly! -#if (! JUCE_CXX17_IS_AVAILABLE) || JUCE_CLANG +#if (! JUCE_CXX17_IS_AVAILABLE) || (JUCE_CLANG && ! JUCE_WINDOWS) template <typename Functor> static WaveShaper<typename std::result_of<Functor>, Functor> CreateWaveShaper (Functor functionToUse) { return {functionToUse}; } #else diff --git a/modules/juce_events/broadcasters/juce_ActionBroadcaster.cpp b/modules/juce_events/broadcasters/juce_ActionBroadcaster.cpp index c900c00c..91885ed1 100644 --- a/modules/juce_events/broadcasters/juce_ActionBroadcaster.cpp +++ b/modules/juce_events/broadcasters/juce_ActionBroadcaster.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_events/broadcasters/juce_ActionBroadcaster.h b/modules/juce_events/broadcasters/juce_ActionBroadcaster.h index 3abbbbb1..0f5479d1 100644 --- a/modules/juce_events/broadcasters/juce_ActionBroadcaster.h +++ b/modules/juce_events/broadcasters/juce_ActionBroadcaster.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_events/broadcasters/juce_ActionListener.h b/modules/juce_events/broadcasters/juce_ActionListener.h index 65fcb395..64f34879 100644 --- a/modules/juce_events/broadcasters/juce_ActionListener.h +++ b/modules/juce_events/broadcasters/juce_ActionListener.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_events/broadcasters/juce_AsyncUpdater.cpp b/modules/juce_events/broadcasters/juce_AsyncUpdater.cpp index 66795e47..2daa2b92 100644 --- a/modules/juce_events/broadcasters/juce_AsyncUpdater.cpp +++ b/modules/juce_events/broadcasters/juce_AsyncUpdater.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_events/broadcasters/juce_AsyncUpdater.h b/modules/juce_events/broadcasters/juce_AsyncUpdater.h index 2b73f72e..094a9c14 100644 --- a/modules/juce_events/broadcasters/juce_AsyncUpdater.h +++ b/modules/juce_events/broadcasters/juce_AsyncUpdater.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_events/broadcasters/juce_ChangeBroadcaster.cpp b/modules/juce_events/broadcasters/juce_ChangeBroadcaster.cpp index 39ad7a58..cccb955a 100644 --- a/modules/juce_events/broadcasters/juce_ChangeBroadcaster.cpp +++ b/modules/juce_events/broadcasters/juce_ChangeBroadcaster.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_events/broadcasters/juce_ChangeBroadcaster.h b/modules/juce_events/broadcasters/juce_ChangeBroadcaster.h index 2bf5ecc3..bf97413d 100644 --- a/modules/juce_events/broadcasters/juce_ChangeBroadcaster.h +++ b/modules/juce_events/broadcasters/juce_ChangeBroadcaster.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_events/broadcasters/juce_ChangeListener.h b/modules/juce_events/broadcasters/juce_ChangeListener.h index 362ff155..668f3e86 100644 --- a/modules/juce_events/broadcasters/juce_ChangeListener.h +++ b/modules/juce_events/broadcasters/juce_ChangeListener.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_events/interprocess/juce_ConnectedChildProcess.cpp b/modules/juce_events/interprocess/juce_ConnectedChildProcess.cpp index ba8b27aa..5ca5a811 100644 --- a/modules/juce_events/interprocess/juce_ConnectedChildProcess.cpp +++ b/modules/juce_events/interprocess/juce_ConnectedChildProcess.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -30,7 +30,7 @@ static const char* killMessage = "__ipc_k_"; static const char* pingMessage = "__ipc_p_"; enum { specialMessageSize = 8, defaultTimeoutMs = 8000 }; -static inline bool isMessageType (const MemoryBlock& mb, const char* messageType) noexcept +static bool isMessageType (const MemoryBlock& mb, const char* messageType) noexcept { return mb.matches (messageType, (size_t) specialMessageSize); } diff --git a/modules/juce_events/interprocess/juce_ConnectedChildProcess.h b/modules/juce_events/interprocess/juce_ConnectedChildProcess.h index 5cd8564f..0b2e6660 100644 --- a/modules/juce_events/interprocess/juce_ConnectedChildProcess.h +++ b/modules/juce_events/interprocess/juce_ConnectedChildProcess.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_events/interprocess/juce_InterprocessConnection.cpp b/modules/juce_events/interprocess/juce_InterprocessConnection.cpp index 57c52915..aabd6314 100644 --- a/modules/juce_events/interprocess/juce_InterprocessConnection.cpp +++ b/modules/juce_events/interprocess/juce_InterprocessConnection.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -32,19 +32,64 @@ struct InterprocessConnection::ConnectionThread : public Thread JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ConnectionThread) }; +class SafeActionImpl +{ +public: + explicit SafeActionImpl (InterprocessConnection& p) + : ref (p) {} + + template <typename Fn> + void ifSafe (Fn&& fn) + { + const ScopedLock lock (mutex); + + if (safe) + fn (ref); + } + + void setSafe (bool s) + { + const ScopedLock lock (mutex); + safe = s; + } + + bool isSafe() + { + const ScopedLock lock (mutex); + return safe; + } + +private: + CriticalSection mutex; + InterprocessConnection& ref; + bool safe = false; +}; + +class InterprocessConnection::SafeAction : public SafeActionImpl +{ + using SafeActionImpl::SafeActionImpl; +}; + //============================================================================== InterprocessConnection::InterprocessConnection (bool callbacksOnMessageThread, uint32 magicMessageHeaderNumber) : useMessageThread (callbacksOnMessageThread), - magicMessageHeader (magicMessageHeaderNumber) + magicMessageHeader (magicMessageHeaderNumber), + safeAction (std::make_shared<SafeAction> (*this)) { thread.reset (new ConnectionThread (*this)); } InterprocessConnection::~InterprocessConnection() { + // You *must* call `disconnect` in the destructor of your derived class to ensure + // that any pending messages are not delivered. If the messages were delivered after + // destroying the derived class, we'd end up calling the pure virtual implementations + // of `messageReceived`, `connectionMade` and `connectionLost` which is definitely + // not a good idea! + jassert (! safeAction->isSafe()); + callbackConnectionState = false; - disconnect(); - masterReference.clear(); + disconnect (4000, Notify::no); thread.reset(); } @@ -54,18 +99,15 @@ bool InterprocessConnection::connectToSocket (const String& hostName, { disconnect(); - const ScopedLock sl (pipeAndSocketLock); - socket.reset (new StreamingSocket()); + auto s = std::make_unique<StreamingSocket>(); - if (socket->connect (hostName, portNumber, timeOutMillisecs)) + if (s->connect (hostName, portNumber, timeOutMillisecs)) { - threadIsRunning = true; - connectionMadeInt(); - thread->startThread(); + const ScopedWriteLock sl (pipeAndSocketLock); + initialiseWithSocket (std::move (s)); return true; } - socket.reset(); return false; } @@ -73,13 +115,13 @@ bool InterprocessConnection::connectToPipe (const String& pipeName, int timeoutM { disconnect(); - std::unique_ptr<NamedPipe> newPipe (new NamedPipe()); + auto newPipe = std::make_unique<NamedPipe>(); if (newPipe->openExisting (pipeName)) { - const ScopedLock sl (pipeAndSocketLock); + const ScopedWriteLock sl (pipeAndSocketLock); pipeReceiveMessageTimeout = timeoutMs; - initialiseWithPipe (newPipe.release()); + initialiseWithPipe (std::move (newPipe)); return true; } @@ -90,44 +132,49 @@ bool InterprocessConnection::createPipe (const String& pipeName, int timeoutMs, { disconnect(); - std::unique_ptr<NamedPipe> newPipe (new NamedPipe()); + auto newPipe = std::make_unique<NamedPipe>(); if (newPipe->createNewPipe (pipeName, mustNotExist)) { - const ScopedLock sl (pipeAndSocketLock); + const ScopedWriteLock sl (pipeAndSocketLock); pipeReceiveMessageTimeout = timeoutMs; - initialiseWithPipe (newPipe.release()); + initialiseWithPipe (std::move (newPipe)); return true; } return false; } -void InterprocessConnection::disconnect() +void InterprocessConnection::disconnect (int timeoutMs, Notify notify) { thread->signalThreadShouldExit(); { - const ScopedLock sl (pipeAndSocketLock); + const ScopedReadLock sl (pipeAndSocketLock); if (socket != nullptr) socket->close(); if (pipe != nullptr) pipe->close(); } - thread->stopThread (4000); + thread->stopThread (timeoutMs); deletePipeAndSocket(); - connectionLostInt(); + + if (notify == Notify::yes) + connectionLostInt(); + + callbackConnectionState = false; + safeAction->setSafe (false); } void InterprocessConnection::deletePipeAndSocket() { - const ScopedLock sl (pipeAndSocketLock); + const ScopedWriteLock sl (pipeAndSocketLock); socket.reset(); pipe.reset(); } bool InterprocessConnection::isConnected() const { - const ScopedLock sl (pipeAndSocketLock); + const ScopedReadLock sl (pipeAndSocketLock); return ((socket != nullptr && socket->isConnected()) || (pipe != nullptr && pipe->isOpen())) @@ -137,7 +184,7 @@ bool InterprocessConnection::isConnected() const String InterprocessConnection::getConnectedHostName() const { { - const ScopedLock sl (pipeAndSocketLock); + const ScopedReadLock sl (pipeAndSocketLock); if (pipe == nullptr && socket == nullptr) return {}; @@ -164,7 +211,7 @@ bool InterprocessConnection::sendMessage (const MemoryBlock& message) int InterprocessConnection::writeData (void* data, int dataSize) { - const ScopedLock sl (pipeAndSocketLock); + const ScopedReadLock sl (pipeAndSocketLock); if (socket != nullptr) return socket->write (data, dataSize); @@ -176,45 +223,47 @@ int InterprocessConnection::writeData (void* data, int dataSize) } //============================================================================== -void InterprocessConnection::initialiseWithSocket (StreamingSocket* newSocket) +void InterprocessConnection::initialise() { - jassert (socket == nullptr && pipe == nullptr); - socket.reset (newSocket); - + safeAction->setSafe (true); threadIsRunning = true; connectionMadeInt(); thread->startThread(); } -void InterprocessConnection::initialiseWithPipe (NamedPipe* newPipe) +void InterprocessConnection::initialiseWithSocket (std::unique_ptr<StreamingSocket> newSocket) { jassert (socket == nullptr && pipe == nullptr); - pipe.reset (newPipe); + socket = std::move (newSocket); + initialise(); +} - threadIsRunning = true; - connectionMadeInt(); - thread->startThread(); +void InterprocessConnection::initialiseWithPipe (std::unique_ptr<NamedPipe> newPipe) +{ + jassert (socket == nullptr && pipe == nullptr); + pipe = std::move (newPipe); + initialise(); } //============================================================================== struct ConnectionStateMessage : public MessageManager::MessageBase { - ConnectionStateMessage (InterprocessConnection* ipc, bool connected) noexcept - : owner (ipc), connectionMade (connected) + ConnectionStateMessage (std::shared_ptr<SafeActionImpl> ipc, bool connected) noexcept + : safeAction (ipc), connectionMade (connected) {} void messageCallback() override { - if (auto* ipc = owner.get()) + safeAction->ifSafe ([this] (InterprocessConnection& owner) { if (connectionMade) - ipc->connectionMade(); + owner.connectionMade(); else - ipc->connectionLost(); - } + owner.connectionLost(); + }); } - WeakReference<InterprocessConnection> owner; + std::shared_ptr<SafeActionImpl> safeAction; bool connectionMade; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ConnectionStateMessage) @@ -227,7 +276,7 @@ void InterprocessConnection::connectionMadeInt() callbackConnectionState = true; if (useMessageThread) - (new ConnectionStateMessage (this, true))->post(); + (new ConnectionStateMessage (safeAction, true))->post(); else connectionMade(); } @@ -240,7 +289,7 @@ void InterprocessConnection::connectionLostInt() callbackConnectionState = false; if (useMessageThread) - (new ConnectionStateMessage (this, false))->post(); + (new ConnectionStateMessage (safeAction, false))->post(); else connectionLost(); } @@ -248,17 +297,19 @@ void InterprocessConnection::connectionLostInt() struct DataDeliveryMessage : public Message { - DataDeliveryMessage (InterprocessConnection* ipc, const MemoryBlock& d) - : owner (ipc), data (d) + DataDeliveryMessage (std::shared_ptr<SafeActionImpl> ipc, const MemoryBlock& d) + : safeAction (ipc), data (d) {} void messageCallback() override { - if (auto* ipc = owner.get()) - ipc->messageReceived (data); + safeAction->ifSafe ([this] (InterprocessConnection& owner) + { + owner.messageReceived (data); + }); } - WeakReference<InterprocessConnection> owner; + std::shared_ptr<SafeActionImpl> safeAction; MemoryBlock data; }; @@ -267,7 +318,7 @@ void InterprocessConnection::deliverDataInt (const MemoryBlock& data) jassert (callbackConnectionState); if (useMessageThread) - (new DataDeliveryMessage (this, data))->post(); + (new DataDeliveryMessage (safeAction, data))->post(); else messageReceived (data); } @@ -275,6 +326,8 @@ void InterprocessConnection::deliverDataInt (const MemoryBlock& data) //============================================================================== int InterprocessConnection::readData (void* data, int num) { + const ScopedReadLock sl (pipeAndSocketLock); + if (socket != nullptr) return socket->read (data, num, true); diff --git a/modules/juce_events/interprocess/juce_InterprocessConnection.h b/modules/juce_events/interprocess/juce_InterprocessConnection.h index ea84e7d5..9f06adb2 100644 --- a/modules/juce_events/interprocess/juce_InterprocessConnection.h +++ b/modules/juce_events/interprocess/juce_InterprocessConnection.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -43,6 +43,9 @@ class MemoryBlock; To act as a socket server and create connections for one or more client, see the InterprocessConnectionServer class. + IMPORTANT NOTE: Your derived Connection class *must* call `disconnect` in its destructor + in order to cancel any pending messages before the class is destroyed. + @see InterprocessConnectionServer, Socket, NamedPipe @tags{Events} @@ -117,8 +120,18 @@ public: */ bool createPipe (const String& pipeName, int pipeReceiveMessageTimeoutMs, bool mustNotExist = false); - /** Disconnects and closes any currently-open sockets or pipes. */ - void disconnect(); + /** Whether the disconnect call should trigger callbacks. */ + enum class Notify { no, yes }; + + /** Disconnects and closes any currently-open sockets or pipes. + + Derived classes *must* call this in their destructors in order to avoid undefined + behaviour. + + @param timeoutMs the time in ms to wait before killing the thread by force + @param notify whether or not to call `connectionLost` + */ + void disconnect (int timeoutMs = -1, Notify notify = Notify::yes); /** True if a socket or pipe is currently active. */ bool isConnected() const; @@ -178,7 +191,7 @@ public: private: //============================================================================== - CriticalSection pipeAndSocketLock; + ReadWriteLock pipeAndSocketLock; std::unique_ptr<StreamingSocket> socket; std::unique_ptr<NamedPipe> pipe; bool callbackConnectionState = false; @@ -187,8 +200,9 @@ private: int pipeReceiveMessageTimeout = -1; friend class InterprocessConnectionServer; - void initialiseWithSocket (StreamingSocket*); - void initialiseWithPipe (NamedPipe*); + void initialise(); + void initialiseWithSocket (std::unique_ptr<StreamingSocket>); + void initialiseWithPipe (std::unique_ptr<NamedPipe>); void deletePipeAndSocket(); void connectionMadeInt(); void connectionLostInt(); @@ -200,10 +214,12 @@ private: std::unique_ptr<ConnectionThread> thread; std::atomic<bool> threadIsRunning { false }; + class SafeAction; + std::shared_ptr<SafeAction> safeAction; + void runThread(); int writeData (void*, int); - JUCE_DECLARE_WEAK_REFERENCEABLE (InterprocessConnection) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (InterprocessConnection) }; diff --git a/modules/juce_events/interprocess/juce_InterprocessConnectionServer.cpp b/modules/juce_events/interprocess/juce_InterprocessConnectionServer.cpp index 3ceb915d..cf79303a 100644 --- a/modules/juce_events/interprocess/juce_InterprocessConnectionServer.cpp +++ b/modules/juce_events/interprocess/juce_InterprocessConnectionServer.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -73,7 +73,7 @@ void InterprocessConnectionServer::run() if (clientSocket != nullptr) if (auto* newConnection = createConnectionObject()) - newConnection->initialiseWithSocket (clientSocket.release()); + newConnection->initialiseWithSocket (std::move (clientSocket)); } } diff --git a/modules/juce_events/interprocess/juce_InterprocessConnectionServer.h b/modules/juce_events/interprocess/juce_InterprocessConnectionServer.h index 2df7439e..3764d606 100644 --- a/modules/juce_events/interprocess/juce_InterprocessConnectionServer.h +++ b/modules/juce_events/interprocess/juce_InterprocessConnectionServer.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_events/interprocess/juce_NetworkServiceDiscovery.cpp b/modules/juce_events/interprocess/juce_NetworkServiceDiscovery.cpp index f2ddcc5c..c02d0ce7 100644 --- a/modules/juce_events/interprocess/juce_NetworkServiceDiscovery.cpp +++ b/modules/juce_events/interprocess/juce_NetworkServiceDiscovery.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -67,11 +67,20 @@ void NetworkServiceDiscovery::Advertiser::run() void NetworkServiceDiscovery::Advertiser::sendBroadcast() { - auto localAddress = IPAddress::getLocalAddress(); - message.setAttribute ("address", localAddress.toString()); - auto broadcastAddress = IPAddress::getInterfaceBroadcastAddress (localAddress); - auto data = message.toString (XmlElement::TextFormat().singleLine().withoutHeader()); - socket.write (broadcastAddress.toString(), broadcastPort, data.toRawUTF8(), (int) data.getNumBytesAsUTF8()); + static IPAddress local = IPAddress::local(); + + for (auto& address : IPAddress::getAllAddresses()) + { + if (address == local) + continue; + + message.setAttribute ("address", address.toString()); + + auto broadcastAddress = IPAddress::getInterfaceBroadcastAddress (address); + auto data = message.toString (XmlElement::TextFormat().singleLine().withoutHeader()); + + socket.write (broadcastAddress.toString(), broadcastPort, data.toRawUTF8(), (int) data.getNumBytesAsUTF8()); + } } //============================================================================== diff --git a/modules/juce_events/interprocess/juce_NetworkServiceDiscovery.h b/modules/juce_events/interprocess/juce_NetworkServiceDiscovery.h index 5c1fdcd8..227e78ca 100644 --- a/modules/juce_events/interprocess/juce_NetworkServiceDiscovery.h +++ b/modules/juce_events/interprocess/juce_NetworkServiceDiscovery.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_events/juce_events.cpp b/modules/juce_events/juce_events.cpp index a29883f9..884db8d7 100644 --- a/modules/juce_events/juce_events.cpp +++ b/modules/juce_events/juce_events.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -35,7 +35,7 @@ #define JUCE_CORE_INCLUDE_COM_SMART_PTR 1 #define JUCE_EVENTS_INCLUDE_WIN32_MESSAGE_WINDOW 1 -#if JUCE_USE_WINRT_MIDI +#if JUCE_USE_WINRT_MIDI || JUCE_USE_WIN_WEBVIEW2 #define JUCE_EVENTS_INCLUDE_WINRT_WRAPPER 1 #endif @@ -73,10 +73,7 @@ #include "native/juce_osx_MessageQueue.h" - #if JUCE_CLANG - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wundeclared-selector" - #endif + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wundeclared-selector") #if JUCE_MAC #include "native/juce_mac_MessageManager.mm" @@ -84,9 +81,7 @@ #include "native/juce_ios_MessageManager.mm" #endif - #if JUCE_CLANG - #pragma clang diagnostic pop - #endif + JUCE_END_IGNORE_WARNINGS_GCC_LIKE #elif JUCE_WINDOWS #include "native/juce_win32_Messaging.cpp" diff --git a/modules/juce_events/juce_events.h b/modules/juce_events/juce_events.h index 07b3ef54..14753324 100644 --- a/modules/juce_events/juce_events.h +++ b/modules/juce_events/juce_events.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -25,14 +25,14 @@ The block below describes the properties of this module, and is read by the Projucer to automatically generate project code that uses it. For details about the syntax and how to create or use a module, see the - JUCE Module Format.txt file. + JUCE Module Format.md file. BEGIN_JUCE_MODULE_DECLARATION ID: juce_events vendor: juce - version: 5.4.7 + version: 6.0.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 @@ -59,7 +59,7 @@ #define JUCE_EXECUTE_APP_SUSPEND_ON_BACKGROUND_TASK 0 #endif -#if JUCE_EVENTS_INCLUDE_WINRT_WRAPPER && JUCE_WINDOWS +#if JUCE_WINDOWS && JUCE_EVENTS_INCLUDE_WINRT_WRAPPER // If this header file is missing then you are probably attempting to use WinRT // functionality without the WinRT libraries installed on your system. Try installing // the latest Windows Standalone SDK and maybe also adding the path to the WinRT diff --git a/modules/juce_events/juce_events.mm b/modules/juce_events/juce_events.mm index 48a9163f..0c6396ee 100644 --- a/modules/juce_events/juce_events.mm +++ b/modules/juce_events/juce_events.mm @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_events/messages/juce_ApplicationBase.cpp b/modules/juce_events/messages/juce_ApplicationBase.cpp index bd10c170..209403ef 100644 --- a/modules/juce_events/messages/juce_ApplicationBase.cpp +++ b/modules/juce_events/messages/juce_ApplicationBase.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -175,7 +175,7 @@ StringArray JUCE_CALLTYPE JUCEApplicationBase::getCommandLineParameterArray() #else -#if JUCE_IOS +#if JUCE_IOS && JUCE_MODULE_AVAILABLE_juce_gui_basics extern int juce_iOSMain (int argc, const char* argv[], void* classPtr); #endif @@ -233,7 +233,7 @@ int JUCEApplicationBase::main (int argc, const char* argv[]) return juce_gtkWebkitMain (argc, argv); #endif - #if JUCE_IOS + #if JUCE_IOS && JUCE_MODULE_AVAILABLE_juce_gui_basics return juce_iOSMain (argc, argv, iOSCustomDelegate); #else diff --git a/modules/juce_events/messages/juce_ApplicationBase.h b/modules/juce_events/messages/juce_ApplicationBase.h index 1b286ca6..db2531f3 100644 --- a/modules/juce_events/messages/juce_ApplicationBase.h +++ b/modules/juce_events/messages/juce_ApplicationBase.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_events/messages/juce_CallbackMessage.h b/modules/juce_events/messages/juce_CallbackMessage.h index f1e2bab6..3ac51f6c 100644 --- a/modules/juce_events/messages/juce_CallbackMessage.h +++ b/modules/juce_events/messages/juce_CallbackMessage.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_events/messages/juce_DeletedAtShutdown.cpp b/modules/juce_events/messages/juce_DeletedAtShutdown.cpp index feede821..888a1e10 100644 --- a/modules/juce_events/messages/juce_DeletedAtShutdown.cpp +++ b/modules/juce_events/messages/juce_DeletedAtShutdown.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -43,12 +43,9 @@ DeletedAtShutdown::~DeletedAtShutdown() getDeletedAtShutdownObjects().removeFirstMatchingValue (this); } -#if JUCE_MSVC - // Disable unreachable code warning, in case the compiler manages to figure out that - // you have no classes of DeletedAtShutdown that could throw an exception in their destructor. - #pragma warning (push) - #pragma warning (disable: 4702) -#endif +// Disable unreachable code warning, in case the compiler manages to figure out that +// you have no classes of DeletedAtShutdown that could throw an exception in their destructor. +JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4702) void DeletedAtShutdown::deleteAll() { @@ -87,8 +84,6 @@ void DeletedAtShutdown::deleteAll() getDeletedAtShutdownObjects().clear(); // just to make sure the array doesn't have any memory still allocated } -#if JUCE_MSVC - #pragma warning (pop) -#endif +JUCE_END_IGNORE_WARNINGS_MSVC } // namespace juce diff --git a/modules/juce_events/messages/juce_DeletedAtShutdown.h b/modules/juce_events/messages/juce_DeletedAtShutdown.h index 4c785408..5203df7a 100644 --- a/modules/juce_events/messages/juce_DeletedAtShutdown.h +++ b/modules/juce_events/messages/juce_DeletedAtShutdown.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_events/messages/juce_Initialisation.h b/modules/juce_events/messages/juce_Initialisation.h index c5cb34db..2fc9b96c 100644 --- a/modules/juce_events/messages/juce_Initialisation.h +++ b/modules/juce_events/messages/juce_Initialisation.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_events/messages/juce_Message.h b/modules/juce_events/messages/juce_Message.h index 8218bf40..1aca7bf3 100644 --- a/modules/juce_events/messages/juce_Message.h +++ b/modules/juce_events/messages/juce_Message.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_events/messages/juce_MessageListener.cpp b/modules/juce_events/messages/juce_MessageListener.cpp index 4a71d166..1f58c916 100644 --- a/modules/juce_events/messages/juce_MessageListener.cpp +++ b/modules/juce_events/messages/juce_MessageListener.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_events/messages/juce_MessageListener.h b/modules/juce_events/messages/juce_MessageListener.h index 6923a9de..13652f40 100644 --- a/modules/juce_events/messages/juce_MessageListener.h +++ b/modules/juce_events/messages/juce_MessageListener.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_events/messages/juce_MessageManager.cpp b/modules/juce_events/messages/juce_MessageManager.cpp index 726554a9..88304524 100644 --- a/modules/juce_events/messages/juce_MessageManager.cpp +++ b/modules/juce_events/messages/juce_MessageManager.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -453,7 +453,6 @@ void MessageManagerLock::exitSignalSent() } //============================================================================== -JUCE_API void JUCE_CALLTYPE initialiseJuce_GUI(); JUCE_API void JUCE_CALLTYPE initialiseJuce_GUI() { JUCE_AUTORELEASEPOOL @@ -462,7 +461,6 @@ JUCE_API void JUCE_CALLTYPE initialiseJuce_GUI() } } -JUCE_API void JUCE_CALLTYPE shutdownJuce_GUI(); JUCE_API void JUCE_CALLTYPE shutdownJuce_GUI() { JUCE_AUTORELEASEPOOL diff --git a/modules/juce_events/messages/juce_MessageManager.h b/modules/juce_events/messages/juce_MessageManager.h index 22b2d189..ae723110 100644 --- a/modules/juce_events/messages/juce_MessageManager.h +++ b/modules/juce_events/messages/juce_MessageManager.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -28,11 +28,6 @@ class ThreadPoolJob; class ActionListener; class ActionBroadcaster; -//============================================================================== -#if JUCE_MODULE_AVAILABLE_juce_opengl -class OpenGLContext; -#endif - //============================================================================== /** See MessageManager::callFunctionOnMessageThread() for use of this function type. */ using MessageCallbackFunction = void* (void* userData); diff --git a/modules/juce_events/messages/juce_MountedVolumeListChangeDetector.h b/modules/juce_events/messages/juce_MountedVolumeListChangeDetector.h index d1bade84..93f4f002 100644 --- a/modules/juce_events/messages/juce_MountedVolumeListChangeDetector.h +++ b/modules/juce_events/messages/juce_MountedVolumeListChangeDetector.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_events/messages/juce_NotificationType.h b/modules/juce_events/messages/juce_NotificationType.h index 168ac5c6..7af5bb94 100644 --- a/modules/juce_events/messages/juce_NotificationType.h +++ b/modules/juce_events/messages/juce_NotificationType.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_events/native/juce_android_Messaging.cpp b/modules/juce_events/native/juce_android_Messaging.cpp index f563d990..c55f812b 100644 --- a/modules/juce_events/native/juce_android_Messaging.cpp +++ b/modules/juce_events/native/juce_android_Messaging.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_events/native/juce_ios_MessageManager.mm b/modules/juce_events/native/juce_ios_MessageManager.mm index bd955d07..dd2fb8e4 100644 --- a/modules/juce_events/native/juce_ios_MessageManager.mm +++ b/modules/juce_events/native/juce_ios_MessageManager.mm @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_events/native/juce_linux_EventLoop.h b/modules/juce_events/native/juce_linux_EventLoop.h index 4aac0967..e2be5da5 100644 --- a/modules/juce_events/native/juce_linux_EventLoop.h +++ b/modules/juce_events/native/juce_linux_EventLoop.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -38,7 +38,7 @@ namespace LinuxEventLoop file descriptor. The possible values for this are defined in <poll.h> */ - void registerFdCallback (int fd, std::function<void(int)> readCallback, short eventMask = 1 /*POLLIN*/); + void registerFdCallback (int fd, std::function<void (int)> 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 49b32b99..4aa44917 100644 --- a/modules/juce_events/native/juce_linux_Messaging.cpp +++ b/modules/juce_events/native/juce_linux_Messaging.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -114,13 +114,22 @@ struct InternalRunLoop public: InternalRunLoop() { - fdReadCallbacks.reserve (8); + fdReadCallbacks.reserve (16); } - void registerFdCallback (int fd, std::function<void(int)>&& cb, short eventMask) + void registerFdCallback (int fd, std::function<void (int)>&& cb, short eventMask) { const ScopedLock sl (lock); + if (shouldDeferModifyingReadCallbacks) + { + deferredReadCallbackModifications.emplace_back ([this, fd, cb, eventMask]() mutable + { + registerFdCallback (fd, std::move (cb), eventMask); + }); + return; + } + fdReadCallbacks.push_back ({ fd, std::move (cb) }); pfds.push_back ({ fd, eventMask, 0 }); } @@ -129,8 +138,14 @@ public: { const ScopedLock sl (lock); + if (shouldDeferModifyingReadCallbacks) + { + deferredReadCallbackModifications.emplace_back ([this, fd] { unregisterFdCallback (fd); }); + return; + } + { - auto removePredicate = [=] (const std::pair<int, std::function<void(int)>>& cb) { return cb.first == fd; }; + auto removePredicate = [=] (const std::pair<int, std::function<void (int)>>& cb) { return cb.first == fd; }; fdReadCallbacks.erase (std::remove_if (std::begin (fdReadCallbacks), std::end (fdReadCallbacks), removePredicate), std::end (fdReadCallbacks)); @@ -166,7 +181,23 @@ public: { if (fdAndCallback.first == fd) { - fdAndCallback.second (fd); + { + ScopedValueSetter<bool> insideFdReadCallback (shouldDeferModifyingReadCallbacks, true); + fdAndCallback.second (fd); + } + + if (! deferredReadCallbackModifications.empty()) + { + for (auto& deferredRegisterEvent : deferredReadCallbackModifications) + deferredRegisterEvent(); + + deferredReadCallbackModifications.clear(); + + // elements may have been removed from the fdReadCallbacks/pfds array so we really need + // to call poll again + return true; + } + eventWasSent = true; } } @@ -180,14 +211,23 @@ public: poll (&pfds.front(), static_cast<nfds_t> (pfds.size()), timeoutMs); } + std::vector<std::pair<int, std::function<void (int)>>> getFdReadCallbacks() + { + const ScopedLock sl (lock); + return fdReadCallbacks; + } + //============================================================================== JUCE_DECLARE_SINGLETON (InternalRunLoop, false) private: CriticalSection lock; - std::vector<std::pair<int, std::function<void(int)>>> fdReadCallbacks; + std::vector<std::pair<int, std::function<void (int)>>> fdReadCallbacks; std::vector<pollfd> pfds; + + bool shouldDeferModifyingReadCallbacks = false; + std::vector<std::function<void()>> deferredReadCallbackModifications; }; JUCE_IMPLEMENT_SINGLETON (InternalRunLoop) @@ -271,7 +311,7 @@ bool MessageManager::dispatchNextMessageOnSystemQueue (bool returnIfNoPendingMes } //============================================================================== -void LinuxEventLoop::registerFdCallback (int fd, std::function<void(int)> readCallback, short eventMask) +void LinuxEventLoop::registerFdCallback (int fd, std::function<void (int)> readCallback, short eventMask) { if (auto* runLoop = InternalRunLoop::getInstanceWithoutCreating()) runLoop->registerFdCallback (fd, std::move (readCallback), eventMask); @@ -284,3 +324,14 @@ void LinuxEventLoop::unregisterFdCallback (int fd) } } // namespace juce + +JUCE_API std::vector<std::pair<int, std::function<void (int)>>> getFdReadCallbacks() +{ + using namespace juce; + + if (auto* runLoop = InternalRunLoop::getInstanceWithoutCreating()) + return runLoop->getFdReadCallbacks(); + + jassertfalse; + return {}; +} diff --git a/modules/juce_events/native/juce_mac_MessageManager.mm b/modules/juce_events/native/juce_mac_MessageManager.mm index 36359d90..36352ab5 100644 --- a/modules/juce_events/native/juce_mac_MessageManager.mm +++ b/modules/juce_events/native/juce_mac_MessageManager.mm @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -144,7 +144,11 @@ private: { if (notification.userInfo != nil) { - NSUserNotification* userNotification = [notification.userInfo objectForKey: nsStringLiteral ("NSApplicationLaunchUserNotificationKey")]; + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wdeprecated-declarations") + // NSUserNotification is deprecated from macOS 11, but there doesn't seem to be a + // replacement for NSApplicationLaunchUserNotificationKey returning a non-deprecated type + NSUserNotification* userNotification = notification.userInfo[NSApplicationLaunchUserNotificationKey]; + JUCE_END_IGNORE_WARNINGS_GCC_LIKE if (userNotification != nil && userNotification.userInfo != nil) didReceiveRemoteNotification (self, nil, [NSApplication sharedApplication], userNotification.userInfo); diff --git a/modules/juce_events/native/juce_osx_MessageQueue.h b/modules/juce_events/native/juce_osx_MessageQueue.h index 32f24fde..2d2ac367 100644 --- a/modules/juce_events/native/juce_osx_MessageQueue.h +++ b/modules/juce_events/native/juce_osx_MessageQueue.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_events/native/juce_win32_HiddenMessageWindow.h b/modules/juce_events/native/juce_win32_HiddenMessageWindow.h index 9135d99b..6f8d9b8b 100644 --- a/modules/juce_events/native/juce_win32_HiddenMessageWindow.h +++ b/modules/juce_events/native/juce_win32_HiddenMessageWindow.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -34,7 +34,7 @@ public: HMODULE moduleHandle = (HMODULE) Process::getCurrentModuleInstanceHandle(); - WNDCLASSEX wc = { 0 }; + WNDCLASSEX wc = {}; wc.cbSize = sizeof (wc); wc.lpfnWndProc = wndProc; wc.cbWndExtra = 4; @@ -45,14 +45,15 @@ public: jassert (atom != 0); hwnd = CreateWindow (getClassNameFromAtom(), messageWindowName, - 0, 0, 0, 0, 0, 0, 0, moduleHandle, 0); - jassert (hwnd != 0); + 0, 0, 0, 0, 0, + nullptr, nullptr, moduleHandle, nullptr); + jassert (hwnd != nullptr); } ~HiddenMessageWindow() { DestroyWindow (hwnd); - UnregisterClass (getClassNameFromAtom(), 0); + UnregisterClass (getClassNameFromAtom(), nullptr); } inline HWND getHWND() const noexcept { return hwnd; } diff --git a/modules/juce_events/native/juce_win32_Messaging.cpp b/modules/juce_events/native/juce_win32_Messaging.cpp index e0f8945a..baec1555 100644 --- a/modules/juce_events/native/juce_win32_Messaging.cpp +++ b/modules/juce_events/native/juce_win32_Messaging.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -51,7 +51,7 @@ public: ~InternalMessageQueue() { - juce_messageWindowHandle = 0; + juce_messageWindowHandle = nullptr; clearSingletonInstance(); } @@ -69,7 +69,7 @@ public: { COPYDATASTRUCT data; data.dwData = broadcastMessageMagicNumber; - data.cbData = (localCopy.length() + 1) * sizeof (CharPointer_UTF32::CharType); + data.cbData = ((size_t) localCopy.length() + 1) * sizeof (CharPointer_UTF32::CharType); data.lpData = (void*) localCopy.toUTF32().getAddress(); DWORD_PTR result; @@ -109,10 +109,10 @@ public: { MSG m; - if (returnIfNoPendingMessages && ! PeekMessage (&m, (HWND) 0, 0, 0, PM_NOREMOVE)) + if (returnIfNoPendingMessages && ! PeekMessage (&m, nullptr, 0, 0, PM_NOREMOVE)) return false; - if (GetMessage (&m, (HWND) 0, 0, 0) >= 0) + if (GetMessage (&m, nullptr, 0, 0) >= 0) { #if JUCE_MODULE_AVAILABLE_juce_gui_extra if (juce_offerEventToActiveXControl (m) != S_FALSE) @@ -137,7 +137,7 @@ public: // currently on a juce window, pass the kb focus over.. auto currentFocus = GetFocus(); - if (currentFocus == 0 || JuceWindowIdentifier::isJUCEWindow (currentFocus)) + if (currentFocus == nullptr || JuceWindowIdentifier::isJUCEWindow (currentFocus)) SetFocus (m.hwnd); } @@ -288,7 +288,7 @@ void MessageManager::broadcastMessage (const String& value) //============================================================================== void MessageManager::doPlatformSpecificInitialisation() { - OleInitialize (0); + OleInitialize (nullptr); InternalMessageQueue::getInstance(); } diff --git a/modules/juce_events/native/juce_win32_WinRTWrapper.cpp b/modules/juce_events/native/juce_win32_WinRTWrapper.cpp index c90fdaff..5d9bf8f7 100644 --- a/modules/juce_events/native/juce_win32_WinRTWrapper.cpp +++ b/modules/juce_events/native/juce_win32_WinRTWrapper.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_events/native/juce_win32_WinRTWrapper.h b/modules/juce_events/native/juce_win32_WinRTWrapper.h index db25d933..3133b391 100644 --- a/modules/juce_events/native/juce_win32_WinRTWrapper.h +++ b/modules/juce_events/native/juce_win32_WinRTWrapper.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -51,6 +51,7 @@ public: ~ComPtr() { release(); } operator ComClass*() const noexcept { return p; } + ComClass* get() const noexcept { return p; } ComClass& operator*() const noexcept { return *p; } ComClass* operator->() const noexcept { return p; } diff --git a/modules/juce_events/timers/juce_MultiTimer.cpp b/modules/juce_events/timers/juce_MultiTimer.cpp index 3f73eb3d..6174dd4b 100644 --- a/modules/juce_events/timers/juce_MultiTimer.cpp +++ b/modules/juce_events/timers/juce_MultiTimer.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_events/timers/juce_MultiTimer.h b/modules/juce_events/timers/juce_MultiTimer.h index 44df949c..034967c4 100644 --- a/modules/juce_events/timers/juce_MultiTimer.h +++ b/modules/juce_events/timers/juce_MultiTimer.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_events/timers/juce_Timer.cpp b/modules/juce_events/timers/juce_Timer.cpp index 9ec3958f..e1c3459e 100644 --- a/modules/juce_events/timers/juce_Timer.cpp +++ b/modules/juce_events/timers/juce_Timer.cpp @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. @@ -136,7 +136,7 @@ public: callTimers(); } - static inline void add (Timer* tim) noexcept + static void add (Timer* tim) noexcept { if (instance == nullptr) instance = new TimerThread(); @@ -144,13 +144,13 @@ public: instance->addTimer (tim); } - static inline void remove (Timer* tim) noexcept + static void remove (Timer* tim) noexcept { if (instance != nullptr) instance->removeTimer (tim); } - static inline void resetCounter (Timer* tim) noexcept + static void resetCounter (Timer* tim) noexcept { if (instance != nullptr) instance->resetTimerCounter (tim); @@ -187,7 +187,7 @@ private: // Trying to add a timer that's already here - shouldn't get to this point, // so if you get this assertion, let me know! jassert (std::find_if (timers.begin(), timers.end(), - [t](TimerCountdown i) { return i.timer == t; }) == timers.end()); + [t] (TimerCountdown i) { return i.timer == t; }) == timers.end()); auto pos = timers.size(); @@ -317,6 +317,14 @@ Timer::Timer (const Timer&) noexcept {} Timer::~Timer() { + // If you're destroying a timer on a background thread, make sure the timer has + // been stopped before execution reaches this point. A simple way to achieve this + // is to add a call to `stopTimer()` to the destructor of your class which inherits + // from Timer. + jassert (! isTimerRunning() + || MessageManager::getInstanceWithoutCreating() == nullptr + || MessageManager::getInstanceWithoutCreating()->currentThreadHasLockedMessageManager()); + stopTimer(); } diff --git a/modules/juce_events/timers/juce_Timer.h b/modules/juce_events/timers/juce_Timer.h index e1203a4b..4e5e7bcd 100644 --- a/modules/juce_events/timers/juce_Timer.h +++ b/modules/juce_events/timers/juce_Timer.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. diff --git a/modules/juce_graphics/colour/juce_Colour.cpp b/modules/juce_graphics/colour/juce_Colour.cpp index c9634ec9..007a2f36 100644 --- a/modules/juce_graphics/colour/juce_Colour.cpp +++ b/modules/juce_graphics/colour/juce_Colour.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -29,58 +28,121 @@ namespace juce namespace ColourHelpers { - static uint8 floatToUInt8 (const float n) noexcept + static uint8 floatToUInt8 (float n) noexcept { - return n <= 0.0f ? 0 : (n >= 1.0f ? 255 : static_cast<uint8> (n * 255.996f)); + return n <= 0.0f ? 0 : (n >= 1.0f ? 255 : (uint8) roundToInt (n * 255.0f)); + } + + static float getHue (Colour col) + { + auto r = (int) col.getRed(); + auto g = (int) col.getGreen(); + auto b = (int) col.getBlue(); + + auto hi = jmax (r, g, b); + auto lo = jmin (r, g, b); + + float hue = 0.0f; + + if (hi > 0) + { + auto invDiff = 1.0f / (float) (hi - lo); + + auto red = (float) (hi - r) * invDiff; + auto green = (float) (hi - g) * invDiff; + auto blue = (float) (hi - b) * invDiff; + + if (r == hi) hue = blue - green; + else if (g == hi) hue = 2.0f + red - blue; + else hue = 4.0f + green - red; + + hue *= 1.0f / 6.0f; + + if (hue < 0.0f) + hue += 1.0f; + } + + return hue; } //============================================================================== - struct HSB + struct HSL { - HSB (Colour col) noexcept + HSL (Colour col) noexcept { - const int r = col.getRed(); - const int g = col.getGreen(); - const int b = col.getBlue(); + auto r = (int) col.getRed(); + auto g = (int) col.getGreen(); + auto b = (int) col.getBlue(); - const int hi = jmax (r, g, b); - const int lo = jmin (r, g, b); + auto hi = jmax (r, g, b); + auto lo = jmin (r, g, b); - if (hi != 0) + if (hi > 0) { - saturation = (hi - lo) / (float) hi; - - if (saturation > 0) - { - const float invDiff = 1.0f / (hi - lo); - - const float red = (hi - r) * invDiff; - const float green = (hi - g) * invDiff; - const float blue = (hi - b) * invDiff; - - if (r == hi) - hue = blue - green; - else if (g == hi) - hue = 2.0f + red - blue; - else - hue = 4.0f + green - red; - - hue *= 1.0f / 6.0f; - - if (hue < 0) - ++hue; - } - else - { - hue = 0; - } + lightness = ((float) (hi + lo) / 2.0f) / 255.0f; + + if (lightness > 0.0f) + hue = getHue (col); + + saturation = (float) (hi - lo) / (1.0f - std::abs ((2.0f * lightness) - 1.0f)); } - else + } + + Colour toColour (Colour original) const noexcept + { + return Colour::fromHSL (hue, saturation, lightness, original.getAlpha()); + } + + static PixelARGB toRGB (float h, float s, float l, uint8 alpha) noexcept + { + auto v = l < 0.5f ? l * (1.0f + s) : l + s - (l * s); + + if (approximatelyEqual (v, 0.0f)) + return PixelARGB (alpha, 0, 0, 0); + + auto min = (2.0f * l) - v; + auto sv = (v - min) / v; + + h = ((h - std::floor (h)) * 360.0f) / 60.0f; + auto f = h - std::floor (h); + auto vsf = v * sv * f; + auto mid1 = min + vsf; + auto mid2 = v - vsf; + + if (h < 1.0f) return PixelARGB (alpha, floatToUInt8 (v), floatToUInt8 (mid1), floatToUInt8 (min)); + else if (h < 2.0f) return PixelARGB (alpha, floatToUInt8 (mid2), floatToUInt8 (v), floatToUInt8 (min)); + else if (h < 3.0f) return PixelARGB (alpha, floatToUInt8 (min), floatToUInt8 (v), floatToUInt8 (mid1)); + else if (h < 4.0f) return PixelARGB (alpha, floatToUInt8 (min), floatToUInt8 (mid2), floatToUInt8 (v)); + else if (h < 5.0f) return PixelARGB (alpha, floatToUInt8 (mid1), floatToUInt8 (min), floatToUInt8 (v)); + else if (h < 6.0f) return PixelARGB (alpha, floatToUInt8 (v), floatToUInt8 (min), floatToUInt8 (mid2)); + + return PixelARGB (alpha, 0, 0, 0); + } + + float hue = 0.0f, saturation = 0.0f, lightness = 0.0f; + }; + + //============================================================================== + struct HSB + { + HSB (Colour col) noexcept + { + auto r = (int) col.getRed(); + auto g = (int) col.getGreen(); + auto b = (int) col.getBlue(); + + auto hi = jmax (r, g, b); + auto lo = jmin (r, g, b); + + if (hi > 0) { - saturation = hue = 0; - } + saturation = (float) (hi - lo) / (float) hi; + + if (saturation > 0.0f) + hue = getHue (col); - brightness = hi / 255.0f; + brightness = (float) hi / 255.0f; + } } Colour toColour (Colour original) const noexcept @@ -88,18 +150,18 @@ namespace ColourHelpers return Colour (hue, saturation, brightness, original.getAlpha()); } - static PixelARGB toRGB (float h, float s, float v, const uint8 alpha) noexcept + static PixelARGB toRGB (float h, float s, float v, uint8 alpha) noexcept { v = jlimit (0.0f, 255.0f, v * 255.0f); - const uint8 intV = (uint8) roundToInt (v); + auto intV = (uint8) roundToInt (v); if (s <= 0) return PixelARGB (alpha, intV, intV, intV); s = jmin (1.0f, s); - h = (h - std::floor (h)) * 6.0f + 0.00001f; // need a small adjustment to compensate for rounding errors - const float f = h - std::floor (h); - const uint8 x = (uint8) roundToInt (v * (1.0f - s)); + h = ((h - std::floor (h)) * 360.0f) / 60.0f; + auto f = h - std::floor (h); + auto x = (uint8) roundToInt (v * (1.0f - s)); if (h < 1.0f) return PixelARGB (alpha, intV, (uint8) roundToInt (v * (1.0f - (s * (1.0f - f)))), x); if (h < 2.0f) return PixelARGB (alpha, (uint8) roundToInt (v * (1.0f - s * f)), intV, x); @@ -109,7 +171,7 @@ namespace ColourHelpers return PixelARGB (alpha, intV, x, (uint8) roundToInt (v * (1.0f - s * f))); } - float hue, saturation, brightness; + float hue = 0.0f, saturation = 0.0f, brightness = 0.0f; }; //============================================================================== @@ -117,9 +179,9 @@ namespace ColourHelpers { YIQ (Colour c) noexcept { - const float r = c.getFloatRed(); - const float g = c.getFloatGreen(); - const float b = c.getFloatBlue(); + auto r = c.getFloatRed(); + auto g = c.getFloatGreen(); + auto b = c.getFloatBlue(); y = 0.2999f * r + 0.5870f * g + 0.1140f * b; i = 0.5957f * r - 0.2744f * g - 0.3212f * b; @@ -135,7 +197,7 @@ namespace ColourHelpers alpha); } - float y, i, q, alpha; + float y = 0.0f, i = 0.0f, q = 0.0f, alpha = 0.0f; }; } @@ -144,54 +206,65 @@ bool Colour::operator== (const Colour& other) const noexcept { return argb.ge bool Colour::operator!= (const Colour& other) const noexcept { return argb.getNativeARGB() != other.argb.getNativeARGB(); } //============================================================================== -Colour::Colour (const uint32 col) noexcept - : argb ((col >> 24) & 0xff, (col >> 16) & 0xff, (col >> 8) & 0xff, col & 0xff) +Colour::Colour (uint32 col) noexcept + : argb (static_cast<uint8> ((col >> 24) & 0xff), + static_cast<uint8> ((col >> 16) & 0xff), + static_cast<uint8> ((col >> 8) & 0xff), + static_cast<uint8> (col & 0xff)) { } -Colour::Colour (const uint8 red, const uint8 green, const uint8 blue) noexcept +Colour::Colour (uint8 red, uint8 green, uint8 blue) noexcept { argb.setARGB (0xff, red, green, blue); } -Colour Colour::fromRGB (const uint8 red, const uint8 green, const uint8 blue) noexcept +Colour Colour::fromRGB (uint8 red, uint8 green, uint8 blue) noexcept { return Colour (red, green, blue); } -Colour::Colour (const uint8 red, const uint8 green, const uint8 blue, const uint8 alpha) noexcept +Colour::Colour (uint8 red, uint8 green, uint8 blue, uint8 alpha) noexcept { argb.setARGB (alpha, red, green, blue); } -Colour Colour::fromRGBA (const uint8 red, const uint8 green, const uint8 blue, const uint8 alpha) noexcept +Colour Colour::fromRGBA (uint8 red, uint8 green, uint8 blue, uint8 alpha) noexcept { return Colour (red, green, blue, alpha); } -Colour::Colour (const uint8 red, const uint8 green, const uint8 blue, const float alpha) noexcept +Colour::Colour (uint8 red, uint8 green, uint8 blue, float alpha) noexcept { argb.setARGB (ColourHelpers::floatToUInt8 (alpha), red, green, blue); } -Colour Colour::fromFloatRGBA (const float red, const float green, const float blue, const float alpha) noexcept +Colour Colour::fromFloatRGBA (float red, float green, float blue, float alpha) noexcept { return Colour (ColourHelpers::floatToUInt8 (red), ColourHelpers::floatToUInt8 (green), ColourHelpers::floatToUInt8 (blue), alpha); } -Colour::Colour (const float hue, const float saturation, const float brightness, const float alpha) noexcept +Colour::Colour (float hue, float saturation, float brightness, float alpha) noexcept : argb (ColourHelpers::HSB::toRGB (hue, saturation, brightness, ColourHelpers::floatToUInt8 (alpha))) { } -Colour Colour::fromHSV (const float hue, const float saturation, const float brightness, const float alpha) noexcept +Colour Colour::fromHSV (float hue, float saturation, float brightness, float alpha) noexcept { return Colour (hue, saturation, brightness, alpha); } -Colour::Colour (const float hue, const float saturation, const float brightness, const uint8 alpha) noexcept +Colour Colour::fromHSL (float hue, float saturation, float lightness, float alpha) noexcept +{ + Colour hslColour; + hslColour.argb = ColourHelpers::HSL::toRGB (hue, saturation, lightness, ColourHelpers::floatToUInt8 (alpha)); + + return hslColour; +} + +Colour::Colour (float hue, float saturation, float brightness, uint8 alpha) noexcept : argb (ColourHelpers::HSB::toRGB (hue, saturation, brightness, alpha)) { } @@ -235,14 +308,14 @@ bool Colour::isOpaque() const noexcept return getAlpha() == 0xff; } -Colour Colour::withAlpha (const uint8 newAlpha) const noexcept +Colour Colour::withAlpha (uint8 newAlpha) const noexcept { PixelARGB newCol (argb); newCol.setAlpha (newAlpha); return Colour (newCol); } -Colour Colour::withAlpha (const float newAlpha) const noexcept +Colour Colour::withAlpha (float newAlpha) const noexcept { jassert (newAlpha >= 0 && newAlpha <= 1.0f); @@ -251,7 +324,7 @@ Colour Colour::withAlpha (const float newAlpha) const noexcept return Colour (newCol); } -Colour Colour::withMultipliedAlpha (const float alphaMultiplier) const noexcept +Colour Colour::withMultipliedAlpha (float alphaMultiplier) const noexcept { jassert (alphaMultiplier >= 0); @@ -263,18 +336,18 @@ Colour Colour::withMultipliedAlpha (const float alphaMultiplier) const noexcept //============================================================================== Colour Colour::overlaidWith (Colour src) const noexcept { - const int destAlpha = getAlpha(); + auto destAlpha = getAlpha(); if (destAlpha <= 0) return src; - const int invA = 0xff - (int) src.getAlpha(); - const int resA = 0xff - (((0xff - destAlpha) * invA) >> 8); + auto invA = 0xff - (int) src.getAlpha(); + auto resA = 0xff - (((0xff - destAlpha) * invA) >> 8); if (resA <= 0) return *this; - const int da = (invA * destAlpha) / resA; + auto da = (invA * destAlpha) / resA; return Colour ((uint8) (src.getRed() + ((((int) getRed() - src.getRed()) * da) >> 8)), (uint8) (src.getGreen() + ((((int) getGreen() - src.getGreen()) * da) >> 8)), @@ -291,7 +364,7 @@ Colour Colour::interpolatedWith (Colour other, float proportionOfOther) const no return other; PixelARGB c1 (getPixelARGB()); - const PixelARGB c2 (other.getPixelARGB()); + PixelARGB c2 (other.getPixelARGB()); c1.tween (c2, (uint32) roundToInt (proportionOfOther * 255.0f)); c1.unpremultiply(); @@ -307,20 +380,34 @@ float Colour::getFloatAlpha() const noexcept { return getAlpha() / 255.0f; } //============================================================================== void Colour::getHSB (float& h, float& s, float& v) const noexcept { - const ColourHelpers::HSB hsb (*this); + ColourHelpers::HSB hsb (*this); h = hsb.hue; s = hsb.saturation; v = hsb.brightness; } +void Colour::getHSL (float& h, float& s, float& l) const noexcept +{ + ColourHelpers::HSL hsl (*this); + h = hsl.hue; + s = hsl.saturation; + l = hsl.lightness; +} + float Colour::getHue() const noexcept { return ColourHelpers::HSB (*this).hue; } float Colour::getSaturation() const noexcept { return ColourHelpers::HSB (*this).saturation; } float Colour::getBrightness() const noexcept { return ColourHelpers::HSB (*this).brightness; } +float Colour::getSaturationHSL() const noexcept { return ColourHelpers::HSL (*this).saturation; } +float Colour::getLightness() const noexcept { return ColourHelpers::HSL (*this).lightness; } + Colour Colour::withHue (float h) const noexcept { ColourHelpers::HSB hsb (*this); hsb.hue = h; return hsb.toColour (*this); } Colour Colour::withSaturation (float s) const noexcept { ColourHelpers::HSB hsb (*this); hsb.saturation = s; return hsb.toColour (*this); } Colour Colour::withBrightness (float v) const noexcept { ColourHelpers::HSB hsb (*this); hsb.brightness = v; return hsb.toColour (*this); } +Colour Colour::withSaturationHSL (float s) const noexcept { ColourHelpers::HSL hsl (*this); hsl.saturation = s; return hsl.toColour (*this); } +Colour Colour::withLightness (float l) const noexcept { ColourHelpers::HSL hsl (*this); hsl.lightness = l; return hsl.toColour (*this); } + float Colour::getPerceivedBrightness() const noexcept { return std::sqrt (0.241f * square (getFloatRed()) @@ -329,27 +416,41 @@ float Colour::getPerceivedBrightness() const noexcept } //============================================================================== -Colour Colour::withRotatedHue (const float amountToRotate) const noexcept +Colour Colour::withRotatedHue (float amountToRotate) const noexcept { ColourHelpers::HSB hsb (*this); hsb.hue += amountToRotate; return hsb.toColour (*this); } -Colour Colour::withMultipliedSaturation (const float amount) const noexcept +Colour Colour::withMultipliedSaturation (float amount) const noexcept { ColourHelpers::HSB hsb (*this); hsb.saturation = jmin (1.0f, hsb.saturation * amount); return hsb.toColour (*this); } -Colour Colour::withMultipliedBrightness (const float amount) const noexcept +Colour Colour::withMultipliedSaturationHSL (float amount) const noexcept +{ + ColourHelpers::HSL hsl (*this); + hsl.saturation = jmin (1.0f, hsl.saturation * amount); + return hsl.toColour (*this); +} + +Colour Colour::withMultipliedBrightness (float amount) const noexcept { ColourHelpers::HSB hsb (*this); hsb.brightness = jmin (1.0f, hsb.brightness * amount); return hsb.toColour (*this); } +Colour Colour::withMultipliedLightness (float amount) const noexcept +{ + ColourHelpers::HSL hsl (*this); + hsl.lightness = jmin (1.0f, hsl.lightness * amount); + return hsl.toColour (*this); +} + //============================================================================== Colour Colour::brighter (float amount) const noexcept { @@ -372,14 +473,14 @@ Colour Colour::darker (float amount) const noexcept } //============================================================================== -Colour Colour::greyLevel (const float brightness) noexcept +Colour Colour::greyLevel (float brightness) noexcept { - const uint8 level = ColourHelpers::floatToUInt8 (brightness); + auto level = ColourHelpers::floatToUInt8 (brightness); return Colour (level, level, level); } //============================================================================== -Colour Colour::contrasting (const float amount) const noexcept +Colour Colour::contrasting (float amount) const noexcept { return overlaidWith ((getPerceivedBrightness() >= 0.5f ? Colours::black @@ -388,14 +489,14 @@ Colour Colour::contrasting (const float amount) const noexcept Colour Colour::contrasting (Colour target, float minContrast) const noexcept { - const ColourHelpers::YIQ bg (*this); + ColourHelpers::YIQ bg (*this); ColourHelpers::YIQ fg (target); if (std::abs (bg.y - fg.y) >= minContrast) return target; - const float y1 = jmax (0.0f, bg.y - minContrast); - const float y2 = jmin (1.0f, bg.y + minContrast); + auto y1 = jmax (0.0f, bg.y - minContrast); + auto y2 = jmin (1.0f, bg.y + minContrast); fg.y = (std::abs (y1 - bg.y) > std::abs (y2 - bg.y)) ? y1 : y2; return fg.toColour(); @@ -404,16 +505,15 @@ Colour Colour::contrasting (Colour target, float minContrast) const noexcept Colour Colour::contrasting (Colour colour1, Colour colour2) noexcept { - const float b1 = colour1.getPerceivedBrightness(); - const float b2 = colour2.getPerceivedBrightness(); - float best = 0.0f; - float bestDist = 0.0f; + auto b1 = colour1.getPerceivedBrightness(); + auto b2 = colour2.getPerceivedBrightness(); + float best = 0.0f, bestDist = 0.0f; for (float i = 0.0f; i < 1.0f; i += 0.02f) { - const float d1 = std::abs (i - b1); - const float d2 = std::abs (i - b2); - const float dist = jmin (d1, d2, 1.0f - d1, 1.0f - d2); + auto d1 = std::abs (i - b1); + auto d2 = std::abs (i - b2); + auto dist = jmin (d1, d2, 1.0f - d1, 1.0f - d2); if (dist > bestDist) { @@ -444,4 +544,159 @@ String Colour::toDisplayString (const bool includeAlphaValue) const .toUpperCase(); } + +//============================================================================== +//============================================================================== +#if JUCE_UNIT_TESTS + +class ColourTests : public UnitTest +{ +public: + ColourTests() + : UnitTest ("Colour", UnitTestCategories::graphics) + {} + + void runTest() override + { + auto testColour = [this] (Colour colour, + uint8 expectedRed, uint8 expectedGreen, uint8 expectedBlue, + uint8 expectedAlpha = 255, float expectedFloatAlpha = 1.0f) + { + expectEquals (colour.getRed(), expectedRed); + expectEquals (colour.getGreen(), expectedGreen); + expectEquals (colour.getBlue(), expectedBlue); + expectEquals (colour.getAlpha(), expectedAlpha); + expectEquals (colour.getFloatAlpha(), expectedFloatAlpha); + }; + + beginTest ("Constructors"); + { + Colour c1; + testColour (c1, (uint8) 0, (uint8) 0, (uint8) 0, (uint8) 0, 0.0f); + + Colour c2 ((uint32) 0); + testColour (c2, (uint8) 0, (uint8) 0, (uint8) 0, (uint8) 0, 0.0f); + + Colour c3 ((uint32) 0xffffffff); + testColour (c3, (uint8) 255, (uint8) 255, (uint8) 255, (uint8) 255, 1.0f); + + Colour c4 (0, 0, 0); + testColour (c4, (uint8) 0, (uint8) 0, (uint8) 0, (uint8) 255, 1.0f); + + Colour c5 (255, 255, 255); + testColour (c5, (uint8) 255, (uint8) 255, (uint8) 255, (uint8) 255, 1.0f); + + Colour c6 ((uint8) 0, (uint8) 0, (uint8) 0, (uint8) 0); + testColour (c6, (uint8) 0, (uint8) 0, (uint8) 0, (uint8) 0, 0.0f); + + Colour c7 ((uint8) 255, (uint8) 255, (uint8) 255, (uint8) 255); + testColour (c7, (uint8) 255, (uint8) 255, (uint8) 255, (uint8) 255, 1.0f); + + Colour c8 ((uint8) 0, (uint8) 0, (uint8) 0, 0.0f); + testColour (c8, (uint8) 0, (uint8) 0, (uint8) 0, (uint8) 0, 0.0f); + + Colour c9 ((uint8) 255, (uint8) 255, (uint8) 255, 1.0f); + testColour (c9, (uint8) 255, (uint8) 255, (uint8) 255, (uint8) 255, 1.0f); + } + + beginTest ("HSV"); + { + // black + testColour (Colour::fromHSV (0.0f, 0.0f, 0.0f, 1.0f), 0, 0, 0); + // white + testColour (Colour::fromHSV (0.0f, 0.0f, 1.0f, 1.0f), 255, 255, 255); + // red + testColour (Colour::fromHSV (0.0f, 1.0f, 1.0f, 1.0f), 255, 0, 0); + testColour (Colour::fromHSV (1.0f, 1.0f, 1.0f, 1.0f), 255, 0, 0); + // lime + testColour (Colour::fromHSV (120 / 360.0f, 1.0f, 1.0f, 1.0f), 0, 255, 0); + // blue + testColour (Colour::fromHSV (240 / 360.0f, 1.0f, 1.0f, 1.0f), 0, 0, 255); + // yellow + testColour (Colour::fromHSV (60 / 360.0f, 1.0f, 1.0f, 1.0f), 255, 255, 0); + // cyan + testColour (Colour::fromHSV (180 / 360.0f, 1.0f, 1.0f, 1.0f), 0, 255, 255); + // magenta + testColour (Colour::fromHSV (300 / 360.0f, 1.0f, 1.0f, 1.0f), 255, 0, 255); + // silver + testColour (Colour::fromHSV (0.0f, 0.0f, 0.75f, 1.0f), 191, 191, 191); + // grey + testColour (Colour::fromHSV (0.0f, 0.0f, 0.5f, 1.0f), 128, 128, 128); + // maroon + testColour (Colour::fromHSV (0.0f, 1.0f, 0.5f, 1.0f), 128, 0, 0); + // olive + testColour (Colour::fromHSV (60 / 360.0f, 1.0f, 0.5f, 1.0f), 128, 128, 0); + // green + testColour (Colour::fromHSV (120 / 360.0f, 1.0f, 0.5f, 1.0f), 0, 128, 0); + // purple + testColour (Colour::fromHSV (300 / 360.0f, 1.0f, 0.5f, 1.0f), 128, 0, 128); + // teal + testColour (Colour::fromHSV (180 / 360.0f, 1.0f, 0.5f, 1.0f), 0, 128, 128); + // navy + testColour (Colour::fromHSV (240 / 360.0f, 1.0f, 0.5f, 1.0f), 0, 0, 128); + } + + beginTest ("HSL"); + { + // black + testColour (Colour::fromHSL (0.0f, 0.0f, 0.0f, 1.0f), 0, 0, 0); + // white + testColour (Colour::fromHSL (0.0f, 0.0f, 1.0f, 1.0f), 255, 255, 255); + // red + testColour (Colour::fromHSL (0.0f, 1.0f, 0.5f, 1.0f), 255, 0, 0); + testColour (Colour::fromHSL (1.0f, 1.0f, 0.5f, 1.0f), 255, 0, 0); + // lime + testColour (Colour::fromHSL (120 / 360.0f, 1.0f, 0.5f, 1.0f), 0, 255, 0); + // blue + testColour (Colour::fromHSL (240 / 360.0f, 1.0f, 0.5f, 1.0f), 0, 0, 255); + // yellow + testColour (Colour::fromHSL (60 / 360.0f, 1.0f, 0.5f, 1.0f), 255, 255, 0); + // cyan + testColour (Colour::fromHSL (180 / 360.0f, 1.0f, 0.5f, 1.0f), 0, 255, 255); + // magenta + testColour (Colour::fromHSL (300 / 360.0f, 1.0f, 0.5f, 1.0f), 255, 0, 255); + // silver + testColour (Colour::fromHSL (0.0f, 0.0f, 0.75f, 1.0f), 191, 191, 191); + // grey + testColour (Colour::fromHSL (0.0f, 0.0f, 0.5f, 1.0f), 128, 128, 128); + // maroon + testColour (Colour::fromHSL (0.0f, 1.0f, 0.25f, 1.0f), 128, 0, 0); + // olive + testColour (Colour::fromHSL (60 / 360.0f, 1.0f, 0.25f, 1.0f), 128, 128, 0); + // green + testColour (Colour::fromHSL (120 / 360.0f, 1.0f, 0.25f, 1.0f), 0, 128, 0); + // purple + testColour (Colour::fromHSL (300 / 360.0f, 1.0f, 0.25f, 1.0f), 128, 0, 128); + // teal + testColour (Colour::fromHSL (180 / 360.0f, 1.0f, 0.25f, 1.0f), 0, 128, 128); + // navy + testColour (Colour::fromHSL (240 / 360.0f, 1.0f, 0.25f, 1.0f), 0, 0, 128); + } + + beginTest ("Modifiers"); + { + Colour red (255, 0, 0); + testColour (red, 255, 0, 0); + + testColour (red.withHue (120.0f / 360.0f), 0, 255, 0); + testColour (red.withSaturation (0.5f), 255, 128, 128); + testColour (red.withSaturationHSL (0.5f), 191, 64, 64); + testColour (red.withBrightness (0.5f), 128, 0, 0); + testColour (red.withLightness (1.0f), 255, 255, 255); + testColour (red.withRotatedHue (120.0f / 360.0f), 0, 255, 0); + testColour (red.withRotatedHue (480.0f / 360.0f), 0, 255, 0); + testColour (red.withRotatedHue (-240.0f / 360.0f), 0, 255, 0); + testColour (red.withRotatedHue (-600.0f / 360.0f), 0, 255, 0); + testColour (red.withMultipliedSaturation (0.0f), 255, 255, 255); + testColour (red.withMultipliedSaturationHSL (0.0f), 128, 128, 128); + testColour (red.withMultipliedBrightness (0.5f), 128, 0, 0); + testColour (red.withMultipliedLightness (2.0f), 255, 255, 255); + } + } +}; + +static ColourTests colourTests; + +#endif + } // namespace juce diff --git a/modules/juce_graphics/colour/juce_Colour.h b/modules/juce_graphics/colour/juce_Colour.h index 8117e9ae..82e23292 100644 --- a/modules/juce_graphics/colour/juce_Colour.h +++ b/modules/juce_graphics/colour/juce_Colour.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -118,6 +117,26 @@ public: float brightness, float alpha) noexcept; + /** Creates a colour using floating point hue, saturation, brightness and alpha values. + + All values must be between 0.0 and 1.0. + Numbers outside the valid range will be clipped. + */ + static Colour fromHSV (float hue, + float saturation, + float brightness, + float alpha) noexcept; + + /** Creates a colour using floating point hue, saturation, lightness and alpha values. + + All values must be between 0.0 and 1.0. + Numbers outside the valid range will be clipped. + */ + static Colour fromHSL (float hue, + float saturation, + float lightness, + float alpha) noexcept; + /** Creates a colour using a PixelARGB object. This function assumes that the argb pixel is not premultiplied. */ @@ -131,17 +150,6 @@ public: */ Colour (PixelAlpha alpha) noexcept; - /** Creates a colour using floating point hue, saturation and brightness values, and an 8-bit alpha. - - The floating point values must be between 0.0 and 1.0. - An alpha of 0x00 is completely transparent, alpha of 0xff is opaque. - Values outside the valid range will be clipped. - */ - static Colour fromHSV (float hue, - float saturation, - float brightness, - float alpha) noexcept; - /** Destructor. */ ~Colour() = default; @@ -254,11 +262,21 @@ public: */ float getSaturation() const noexcept; + /** Returns the colour's saturation component as represented in the HSL colour space. + The value returned is in the range 0.0 to 1.0 + */ + float getSaturationHSL() const noexcept; + /** Returns the colour's brightness component. The value returned is in the range 0.0 to 1.0 */ float getBrightness() const noexcept; + /** Returns the colour's lightness component. + The value returned is in the range 0.0 to 1.0 + */ + float getLightness() const noexcept; + /** Returns a skewed brightness value, adjusted to better reflect the way the human eye responds to different colour channels. This makes it better than getBrightness() for comparing differences in brightness. @@ -272,6 +290,13 @@ public: float& saturation, float& brightness) const noexcept; + /** Returns the colour's hue, saturation and lightness components all at once. + The values returned are in the range 0.0 to 1.0 + */ + void getHSL (float& hue, + float& saturation, + float& lightness) const noexcept; + //============================================================================== /** Returns a copy of this colour with a different hue. */ Colour withHue (float newHue) const noexcept; @@ -279,11 +304,19 @@ public: /** Returns a copy of this colour with a different saturation. */ Colour withSaturation (float newSaturation) const noexcept; + /** Returns a copy of this colour with a different saturation in the HSL colour space. */ + Colour withSaturationHSL (float newSaturation) const noexcept; + /** Returns a copy of this colour with a different brightness. @see brighter, darker, withMultipliedBrightness */ Colour withBrightness (float newBrightness) const noexcept; + /** Returns a copy of this colour with a different lightness. + @see lighter, darker, withMultipliedLightness + */ + Colour withLightness (float newLightness) const noexcept; + /** Returns a copy of this colour with its hue rotated. The new colour's hue is ((this->getHue() + amountToRotate) % 1.0) @see brighter, darker, withMultipliedBrightness @@ -296,12 +329,26 @@ public: */ Colour withMultipliedSaturation (float multiplier) const noexcept; + /** Returns a copy of this colour with its saturation multiplied by the given value. + The new colour's saturation is (this->getSaturation() * multiplier) + (the result is clipped to legal limits). + + This will be in the HSL colour space. + */ + Colour withMultipliedSaturationHSL (float multiplier) const noexcept; + /** Returns a copy of this colour with its brightness multiplied by the given value. The new colour's brightness is (this->getBrightness() * multiplier) (the result is clipped to legal limits). */ Colour withMultipliedBrightness (float amount) const noexcept; + /** Returns a copy of this colour with its lightness multiplied by the given value. + The new colour's lightness is (this->lightness() * multiplier) + (the result is clipped to legal limits). + */ + Colour withMultipliedLightness (float amount) const noexcept; + //============================================================================== /** Returns a brighter version of this colour. @param amountBrighter how much brighter to make it - a value from 0 to 1.0 where 0 is diff --git a/modules/juce_graphics/colour/juce_ColourGradient.cpp b/modules/juce_graphics/colour/juce_ColourGradient.cpp index a0b100ed..95c4020e 100644 --- a/modules/juce_graphics/colour/juce_ColourGradient.cpp +++ b/modules/juce_graphics/colour/juce_ColourGradient.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/colour/juce_ColourGradient.h b/modules/juce_graphics/colour/juce_ColourGradient.h index 33bafde1..f49f27b7 100644 --- a/modules/juce_graphics/colour/juce_ColourGradient.h +++ b/modules/juce_graphics/colour/juce_ColourGradient.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/colour/juce_Colours.cpp b/modules/juce_graphics/colour/juce_Colours.cpp index 926157bc..03242a65 100644 --- a/modules/juce_graphics/colour/juce_Colours.cpp +++ b/modules/juce_graphics/colour/juce_Colours.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/colour/juce_Colours.h b/modules/juce_graphics/colour/juce_Colours.h index 370f6b44..78d51d20 100644 --- a/modules/juce_graphics/colour/juce_Colours.h +++ b/modules/juce_graphics/colour/juce_Colours.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/colour/juce_FillType.cpp b/modules/juce_graphics/colour/juce_FillType.cpp index 746b0179..4e13e404 100644 --- a/modules/juce_graphics/colour/juce_FillType.cpp +++ b/modules/juce_graphics/colour/juce_FillType.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/colour/juce_FillType.h b/modules/juce_graphics/colour/juce_FillType.h index 4b180949..6c8ceb51 100644 --- a/modules/juce_graphics/colour/juce_FillType.h +++ b/modules/juce_graphics/colour/juce_FillType.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/colour/juce_PixelFormats.h b/modules/juce_graphics/colour/juce_PixelFormats.h index 934c61c4..2f7f7bf4 100644 --- a/modules/juce_graphics/colour/juce_PixelFormats.h +++ b/modules/juce_graphics/colour/juce_PixelFormats.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/contexts/juce_GraphicsContext.cpp b/modules/juce_graphics/contexts/juce_GraphicsContext.cpp index bab4475c..d82dd34b 100644 --- a/modules/juce_graphics/contexts/juce_GraphicsContext.cpp +++ b/modules/juce_graphics/contexts/juce_GraphicsContext.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -533,10 +532,10 @@ void Graphics::fillCheckerBoard (Rectangle<float> area, float checkWidth, float if (! clipped.isEmpty()) { - const int checkNumX = (int) ((clipped.getX() - area.getX()) / checkWidth); - const int checkNumY = (int) ((clipped.getY() - area.getY()) / checkHeight); - const float startX = area.getX() + checkNumX * checkWidth; - const float startY = area.getY() + checkNumY * checkHeight; + const int checkNumX = (int) (((float) clipped.getX() - area.getX()) / checkWidth); + const int checkNumY = (int) (((float) clipped.getY() - area.getY()) / checkHeight); + const float startX = area.getX() + (float) checkNumX * checkWidth; + const float startY = area.getY() + (float) checkNumY * checkHeight; const float right = (float) clipped.getRight(); const float bottom = (float) clipped.getBottom(); @@ -667,7 +666,7 @@ void Graphics::drawImage (const Image& imageToDraw, { if (imageToDraw.isValid() && context.clipRegionIntersects (coordsToRectangle (dx, dy, dw, dh))) drawImageTransformed (imageToDraw.getClippedImage (coordsToRectangle (sx, sy, sw, sh)), - AffineTransform::scale (dw / (float) sw, dh / (float) sh) + AffineTransform::scale ((float) dw / (float) sw, (float) dh / (float) sh) .translated ((float) dx, (float) dy), fillAlphaChannelWithCurrentBrush); } diff --git a/modules/juce_graphics/contexts/juce_GraphicsContext.h b/modules/juce_graphics/contexts/juce_GraphicsContext.h index e0563407..3de34ad6 100644 --- a/modules/juce_graphics/contexts/juce_GraphicsContext.h +++ b/modules/juce_graphics/contexts/juce_GraphicsContext.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/contexts/juce_LowLevelGraphicsContext.h b/modules/juce_graphics/contexts/juce_LowLevelGraphicsContext.h index e4aff7ba..a647b886 100644 --- a/modules/juce_graphics/contexts/juce_LowLevelGraphicsContext.h +++ b/modules/juce_graphics/contexts/juce_LowLevelGraphicsContext.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.cpp b/modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.cpp index cf850678..f66dde13 100644 --- a/modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.cpp +++ b/modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -51,12 +50,12 @@ LowLevelGraphicsPostScriptRenderer::LowLevelGraphicsPostScriptRenderer (OutputSt stateStack.add (new SavedState()); stateStack.getLast()->clip = Rectangle<int> (totalWidth_, totalHeight_); - const float scale = jmin ((520.0f / totalWidth_), (750.0f / totalHeight)); + const float scale = jmin ((520.0f / (float) totalWidth_), (750.0f / (float) totalHeight)); out << "%!PS-Adobe-3.0 EPSF-3.0" "\n%%BoundingBox: 0 0 600 824" "\n%%Pages: 0" - "\n%%Creator: ROLI Ltd. JUCE" + "\n%%Creator: Raw Material Software Limited - JUCE" "\n%%Title: " << documentTitle << "\n%%CreationDate: none" "\n%%LanguageLevel: 2" diff --git a/modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.h b/modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.h index fdda3d81..d8e3509e 100644 --- a/modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.h +++ b/modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp b/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp index a32e9077..84ff197e 100644 --- a/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp +++ b/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h b/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h index 403b3031..eec16e90 100644 --- a/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h +++ b/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/effects/juce_DropShadowEffect.cpp b/modules/juce_graphics/effects/juce_DropShadowEffect.cpp index 1b5491b7..3502902b 100644 --- a/modules/juce_graphics/effects/juce_DropShadowEffect.cpp +++ b/modules/juce_graphics/effects/juce_DropShadowEffect.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -27,7 +26,7 @@ namespace juce { -static inline void blurDataTriplets (uint8* d, int num, const int delta) noexcept +static void blurDataTriplets (uint8* d, int num, const int delta) noexcept { uint32 last = d[0]; d[0] = (uint8) ((d[0] + d[delta] + 1) / 3); @@ -134,8 +133,8 @@ void DropShadow::drawForRectangle (Graphics& g, const Rectangle<int>& targetArea for (float i = 0.05f; i < 1.0f; i += 0.1f) cg.addColour (1.0 - i, colour.withMultipliedAlpha (i * i)); - const float radiusInset = radius / 2.0f; - const float expandedRadius = radius + radiusInset; + const float radiusInset = (float) radius / 2.0f; + const float expandedRadius = (float) radius + radiusInset; auto area = targetArea.toFloat().reduced (radiusInset) + offset.toFloat(); @@ -170,10 +169,10 @@ void DropShadowEffect::setShadowProperties (const DropShadow& newShadow) void DropShadowEffect::applyEffect (Image& image, Graphics& g, float scaleFactor, float alpha) { DropShadow s (shadow); - s.radius = roundToInt (s.radius * scaleFactor); + s.radius = roundToInt ((float) s.radius * scaleFactor); s.colour = s.colour.withMultipliedAlpha (alpha); - s.offset.x = roundToInt (s.offset.x * scaleFactor); - s.offset.y = roundToInt (s.offset.y * scaleFactor); + s.offset.x = roundToInt ((float) s.offset.x * scaleFactor); + s.offset.y = roundToInt ((float) s.offset.y * scaleFactor); s.drawForImage (g, image); diff --git a/modules/juce_graphics/effects/juce_DropShadowEffect.h b/modules/juce_graphics/effects/juce_DropShadowEffect.h index 574e2848..db8e0b9b 100644 --- a/modules/juce_graphics/effects/juce_DropShadowEffect.h +++ b/modules/juce_graphics/effects/juce_DropShadowEffect.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/effects/juce_GlowEffect.cpp b/modules/juce_graphics/effects/juce_GlowEffect.cpp index 4e1ee32c..c8c0ee20 100644 --- a/modules/juce_graphics/effects/juce_GlowEffect.cpp +++ b/modules/juce_graphics/effects/juce_GlowEffect.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/effects/juce_GlowEffect.h b/modules/juce_graphics/effects/juce_GlowEffect.h index e391ab34..340c4f14 100644 --- a/modules/juce_graphics/effects/juce_GlowEffect.h +++ b/modules/juce_graphics/effects/juce_GlowEffect.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/effects/juce_ImageEffectFilter.h b/modules/juce_graphics/effects/juce_ImageEffectFilter.h index fa103d26..05494e8f 100644 --- a/modules/juce_graphics/effects/juce_ImageEffectFilter.h +++ b/modules/juce_graphics/effects/juce_ImageEffectFilter.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/fonts/juce_AttributedString.cpp b/modules/juce_graphics/fonts/juce_AttributedString.cpp index 829b3c4c..2a2ef4b7 100644 --- a/modules/juce_graphics/fonts/juce_AttributedString.cpp +++ b/modules/juce_graphics/fonts/juce_AttributedString.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/fonts/juce_AttributedString.h b/modules/juce_graphics/fonts/juce_AttributedString.h index 0854df38..9721939a 100644 --- a/modules/juce_graphics/fonts/juce_AttributedString.h +++ b/modules/juce_graphics/fonts/juce_AttributedString.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/fonts/juce_CustomTypeface.cpp b/modules/juce_graphics/fonts/juce_CustomTypeface.cpp index 1f31a303..4a42cf84 100644 --- a/modules/juce_graphics/fonts/juce_CustomTypeface.cpp +++ b/modules/juce_graphics/fonts/juce_CustomTypeface.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/fonts/juce_CustomTypeface.h b/modules/juce_graphics/fonts/juce_CustomTypeface.h index b0eb86c5..8fdacda9 100644 --- a/modules/juce_graphics/fonts/juce_CustomTypeface.h +++ b/modules/juce_graphics/fonts/juce_CustomTypeface.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/fonts/juce_Font.cpp b/modules/juce_graphics/fonts/juce_Font.cpp index fc61328f..4a08265e 100644 --- a/modules/juce_graphics/fonts/juce_Font.cpp +++ b/modules/juce_graphics/fonts/juce_Font.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -80,24 +79,26 @@ public: Typeface::Ptr findTypefaceFor (const Font& font) { - const ScopedReadLock slr (lock); - - auto faceName = font.getTypefaceName(); - auto faceStyle = font.getTypefaceStyle(); + const auto faceName = font.getTypefaceName(); + const auto faceStyle = font.getTypefaceStyle(); jassert (faceName.isNotEmpty()); - for (int i = faces.size(); --i >= 0;) { - CachedFace& face = faces.getReference(i); + const ScopedReadLock slr (lock); - if (face.typefaceName == faceName - && face.typefaceStyle == faceStyle - && face.typeface != nullptr - && face.typeface->isSuitableForFont (font)) + for (int i = faces.size(); --i >= 0;) { - face.lastUsageCount = ++counter; - return face.typeface; + CachedFace& face = faces.getReference(i); + + if (face.typefaceName == faceName + && face.typefaceStyle == faceStyle + && face.typeface != nullptr + && face.typeface->isSuitableForFont (font)) + { + face.lastUsageCount = ++counter; + return face.typeface; + } } } @@ -635,7 +636,7 @@ float Font::getStringWidthFloat (const String& text) const auto w = getTypeface()->getStringWidth (text); if (font->kerning != 0.0f) - w += font->kerning * text.length(); + w += font->kerning * (float) text.length(); return w * font->height * font->horizontalScale; } @@ -656,7 +657,7 @@ void Font::getGlyphPositions (const String& text, Array<int>& glyphs, Array<floa if (font->kerning != 0.0f) { for (int i = 0; i < num; ++i) - x[i] = (x[i] + i * font->kerning) * scale; + x[i] = (x[i] + (float) i * font->kerning) * scale; } else { diff --git a/modules/juce_graphics/fonts/juce_Font.h b/modules/juce_graphics/fonts/juce_Font.h index 0b514738..0d72f57b 100644 --- a/modules/juce_graphics/fonts/juce_Font.h +++ b/modules/juce_graphics/fonts/juce_Font.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -304,7 +303,6 @@ public: /** Returns true if the font is underlined. */ bool isUnderlined() const noexcept; - //============================================================================== /** Returns the font's horizontal scale. A value of 1.0 is the normal scale, less than this will be narrower, greater @@ -465,7 +463,6 @@ public: */ static Font fromString (const String& fontDescription); - private: //============================================================================== class SharedFontInternal; diff --git a/modules/juce_graphics/fonts/juce_GlyphArrangement.cpp b/modules/juce_graphics/fonts/juce_GlyphArrangement.cpp index 148c655e..50984ac1 100644 --- a/modules/juce_graphics/fonts/juce_GlyphArrangement.cpp +++ b/modules/juce_graphics/fonts/juce_GlyphArrangement.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -41,7 +40,7 @@ PositionedGlyph::PositionedGlyph (const Font& font_, juce_wchar character_, int PositionedGlyph::~PositionedGlyph() {} -static inline void drawGlyphWithFont (Graphics& g, int glyph, const Font& font, AffineTransform t) +static void drawGlyphWithFont (Graphics& g, int glyph, const Font& font, AffineTransform t) { auto& context = g.getInternalContext(); context.setFont (font); @@ -544,7 +543,7 @@ void GlyphArrangement::spreadOutLine (int start, int num, float targetWidth) } } -static inline bool isBreakableGlyph (const PositionedGlyph& g) noexcept +static bool isBreakableGlyph (const PositionedGlyph& g) noexcept { return g.isWhitespace() || g.getCharacter() == '-'; } @@ -582,7 +581,7 @@ void GlyphArrangement::splitLines (const String& text, Font font, int startIndex // allowing for unevenness in the lengths due to differently sized words. const float lineLengthUnevennessAllowance = 80.0f; - if (numLines > (lineWidth + lineLengthUnevennessAllowance) / width || newFontHeight < 8.0f) + if ((float) numLines > (lineWidth + lineLengthUnevennessAllowance) / width || newFontHeight < 8.0f) break; } @@ -592,7 +591,7 @@ void GlyphArrangement::splitLines (const String& text, Font font, int startIndex int lineIndex = 0; auto lineY = y; auto widthPerLine = jmin (width / minimumHorizontalScale, - lineWidth / numLines); + lineWidth / (float) numLines); while (lineY < y + height) { diff --git a/modules/juce_graphics/fonts/juce_GlyphArrangement.h b/modules/juce_graphics/fonts/juce_GlyphArrangement.h index 7aa7e807..18500f53 100644 --- a/modules/juce_graphics/fonts/juce_GlyphArrangement.h +++ b/modules/juce_graphics/fonts/juce_GlyphArrangement.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/fonts/juce_TextLayout.cpp b/modules/juce_graphics/fonts/juce_TextLayout.cpp index 2cd8f78f..3755e7e5 100644 --- a/modules/juce_graphics/fonts/juce_TextLayout.cpp +++ b/modules/juce_graphics/fonts/juce_TextLayout.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -225,8 +224,8 @@ void TextLayout::draw (Graphics& g, Rectangle<float> area) const context.saveState(); auto clip = context.getClipBounds(); - auto clipTop = clip.getY() - origin.y; - auto clipBottom = clip.getBottom() - origin.y; + auto clipTop = (float) clip.getY() - origin.y; + auto clipBottom = (float) clip.getBottom() - origin.y; for (auto& line : *this) { diff --git a/modules/juce_graphics/fonts/juce_TextLayout.h b/modules/juce_graphics/fonts/juce_TextLayout.h index c1eef2ee..e466bf4d 100644 --- a/modules/juce_graphics/fonts/juce_TextLayout.h +++ b/modules/juce_graphics/fonts/juce_TextLayout.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/fonts/juce_Typeface.cpp b/modules/juce_graphics/fonts/juce_Typeface.cpp index fdd86f18..71e2baba 100644 --- a/modules/juce_graphics/fonts/juce_Typeface.cpp +++ b/modules/juce_graphics/fonts/juce_Typeface.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -243,7 +242,7 @@ private: } } - return num < 4 ? 0.0f : total / (num * (float) standardHeight); + return num < 4 ? 0.0f : total / ((float) num * (float) standardHeight); } enum { standardHeight = 100 }; diff --git a/modules/juce_graphics/fonts/juce_Typeface.h b/modules/juce_graphics/fonts/juce_Typeface.h index 663c29c2..cd6f9c6c 100644 --- a/modules/juce_graphics/fonts/juce_Typeface.h +++ b/modules/juce_graphics/fonts/juce_Typeface.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/geometry/juce_AffineTransform.cpp b/modules/juce_graphics/geometry/juce_AffineTransform.cpp index 588253f0..b70945ef 100644 --- a/modules/juce_graphics/geometry/juce_AffineTransform.cpp +++ b/modules/juce_graphics/geometry/juce_AffineTransform.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -187,9 +186,9 @@ AffineTransform AffineTransform::verticalFlip (float height) noexcept AffineTransform AffineTransform::inverted() const noexcept { - double determinant = (mat00 * mat11 - mat10 * mat01); + double determinant = getDeterminant(); - if (determinant != 0) + if (! approximatelyEqual (determinant, 0.0)) { determinant = 1.0 / determinant; @@ -236,9 +235,46 @@ bool AffineTransform::isOnlyTranslation() const noexcept && mat11 == 1.0f; } +float AffineTransform::getDeterminant() const noexcept +{ + return (mat00 * mat11) - (mat01 * mat10); +} + float AffineTransform::getScaleFactor() const noexcept { return (std::abs (mat00) + std::abs (mat11)) / 2.0f; } + +//============================================================================== +//============================================================================== +#if JUCE_UNIT_TESTS + +class AffineTransformTests : public UnitTest +{ +public: + AffineTransformTests() + : UnitTest ("AffineTransform", UnitTestCategories::maths) + {} + + void runTest() override + { + beginTest ("Determinant"); + { + constexpr float scale1 = 1.5f, scale2 = 1.3f; + + auto transform = AffineTransform::scale (scale1) + .followedBy (AffineTransform::rotation (degreesToRadians (72.0f))) + .followedBy (AffineTransform::translation (100.0f, 20.0f)) + .followedBy (AffineTransform::scale (scale2)); + + expect (approximatelyEqual (std::sqrt (std::abs (transform.getDeterminant())), scale1 * scale2)); + } + } +}; + +static AffineTransformTests timeTests; + +#endif + } // namespace juce diff --git a/modules/juce_graphics/geometry/juce_AffineTransform.h b/modules/juce_graphics/geometry/juce_AffineTransform.h index 06452d49..f37ff506 100644 --- a/modules/juce_graphics/geometry/juce_AffineTransform.h +++ b/modules/juce_graphics/geometry/juce_AffineTransform.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -264,11 +263,23 @@ public: */ float getTranslationY() const noexcept { return mat12; } - /** Returns the approximate scale factor by which lengths will be transformed. + /** Returns the determinant of the transform. */ + float getDeterminant() const noexcept; + + /** This method has been deprecated. + + You can calculate the scale factor using: + @code + std::sqrt (std::abs (AffineTransform::getDeterminant())) + @endcode + + This method produces incorrect values for transforms containing rotations. + + Returns the approximate scale factor by which lengths will be transformed. Obviously a length may be scaled by entirely different amounts depending on its direction, so this is only appropriate as a rough guide. */ - float getScaleFactor() const noexcept; + JUCE_DEPRECATED (float getScaleFactor() const noexcept); /* A ready-to-use identity transform - now deprecated. @deprecated If you need an identity transform, just use AffineTransform() or {}. diff --git a/modules/juce_graphics/geometry/juce_BorderSize.h b/modules/juce_graphics/geometry/juce_BorderSize.h index 8f954a76..0fea60d3 100644 --- a/modules/juce_graphics/geometry/juce_BorderSize.h +++ b/modules/juce_graphics/geometry/juce_BorderSize.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/geometry/juce_EdgeTable.cpp b/modules/juce_graphics/geometry/juce_EdgeTable.cpp index 220f4bcc..123bfefc 100644 --- a/modules/juce_graphics/geometry/juce_EdgeTable.cpp +++ b/modules/juce_graphics/geometry/juce_EdgeTable.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/geometry/juce_EdgeTable.h b/modules/juce_graphics/geometry/juce_EdgeTable.h index 071eb1c4..8f474a53 100644 --- a/modules/juce_graphics/geometry/juce_EdgeTable.h +++ b/modules/juce_graphics/geometry/juce_EdgeTable.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/geometry/juce_Line.h b/modules/juce_graphics/geometry/juce_Line.h index b9b3db01..ad258e5f 100644 --- a/modules/juce_graphics/geometry/juce_Line.h +++ b/modules/juce_graphics/geometry/juce_Line.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/geometry/juce_Parallelogram.h b/modules/juce_graphics/geometry/juce_Parallelogram.h index f55e38d1..a8bde9d1 100644 --- a/modules/juce_graphics/geometry/juce_Parallelogram.h +++ b/modules/juce_graphics/geometry/juce_Parallelogram.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -166,7 +165,10 @@ public: Parallelogram transformedBy (const AffineTransform& transform) const noexcept { auto p = *this; - transform.transformPoints (p.topLeft, p.topRight, p.bottomLeft); + transform.transformPoints (p.topLeft.x, p.topLeft.y, + p.topRight.x, p.topRight.y, + p.bottomLeft.x, p.bottomLeft.y); + return p; } diff --git a/modules/juce_graphics/geometry/juce_Path.cpp b/modules/juce_graphics/geometry/juce_Path.cpp index df639786..eb7d04ef 100644 --- a/modules/juce_graphics/geometry/juce_Path.cpp +++ b/modules/juce_graphics/geometry/juce_Path.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -68,7 +67,7 @@ const float Path::closeSubPathMarker = 100005.0f; const float Path::defaultToleranceForTesting = 1.0f; const float Path::defaultToleranceForMeasurement = 0.6f; -static inline bool isMarker (float value, float marker) noexcept +static bool isMarker (float value, float marker) noexcept { return value == marker; } @@ -616,11 +615,11 @@ void Path::addPolygon (Point<float> centre, int numberOfSides, if (numberOfSides > 1) { - auto angleBetweenPoints = MathConstants<float>::twoPi / numberOfSides; + auto angleBetweenPoints = MathConstants<float>::twoPi / (float) numberOfSides; for (int i = 0; i < numberOfSides; ++i) { - auto angle = startAngle + i * angleBetweenPoints; + auto angle = startAngle + (float) i * angleBetweenPoints; auto p = centre.getPointOnCircumference (radius, angle); if (i == 0) @@ -640,11 +639,11 @@ void Path::addStar (Point<float> centre, int numberOfPoints, float innerRadius, if (numberOfPoints > 1) { - auto angleBetweenPoints = MathConstants<float>::twoPi / numberOfPoints; + auto angleBetweenPoints = MathConstants<float>::twoPi / (float) numberOfPoints; for (int i = 0; i < numberOfPoints; ++i) { - auto angle = startAngle + i * angleBetweenPoints; + auto angle = startAngle + (float) i * angleBetweenPoints; auto p = centre.getPointOnCircumference (outerRadius, angle); if (i == 0) diff --git a/modules/juce_graphics/geometry/juce_Path.h b/modules/juce_graphics/geometry/juce_Path.h index e0cf526d..b9a5ee5f 100644 --- a/modules/juce_graphics/geometry/juce_Path.h +++ b/modules/juce_graphics/geometry/juce_Path.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/geometry/juce_PathIterator.cpp b/modules/juce_graphics/geometry/juce_PathIterator.cpp index d695bcfc..0141b0a1 100644 --- a/modules/juce_graphics/geometry/juce_PathIterator.cpp +++ b/modules/juce_graphics/geometry/juce_PathIterator.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -72,7 +71,7 @@ bool PathFlatteningIterator::next() { float type; - if (stackPos == stackBase) + if (stackPos == stackBase.get()) { if (source == path.data.end()) return false; @@ -137,7 +136,7 @@ bool PathFlatteningIterator::next() { ++subPathIndex; - closesSubPath = stackPos == stackBase + closesSubPath = stackPos == stackBase.get() && source != path.data.end() && *source == Path::closeSubPathMarker && x2 == subPathCloseX diff --git a/modules/juce_graphics/geometry/juce_PathIterator.h b/modules/juce_graphics/geometry/juce_PathIterator.h index c1583b52..7eb82088 100644 --- a/modules/juce_graphics/geometry/juce_PathIterator.h +++ b/modules/juce_graphics/geometry/juce_PathIterator.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/geometry/juce_PathStrokeType.cpp b/modules/juce_graphics/geometry/juce_PathStrokeType.cpp index c24afbdc..16852647 100644 --- a/modules/juce_graphics/geometry/juce_PathStrokeType.cpp +++ b/modules/juce_graphics/geometry/juce_PathStrokeType.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/geometry/juce_PathStrokeType.h b/modules/juce_graphics/geometry/juce_PathStrokeType.h index b94b7af1..268086f5 100644 --- a/modules/juce_graphics/geometry/juce_PathStrokeType.h +++ b/modules/juce_graphics/geometry/juce_PathStrokeType.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/geometry/juce_Point.h b/modules/juce_graphics/geometry/juce_Point.h index 3bf9c266..dc89cf76 100644 --- a/modules/juce_graphics/geometry/juce_Point.h +++ b/modules/juce_graphics/geometry/juce_Point.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -43,101 +42,111 @@ class Point { public: /** Creates a point at the origin */ - JUCE_CONSTEXPR Point() = default; + constexpr Point() = default; /** Creates a copy of another point. */ - JUCE_CONSTEXPR Point (const Point&) = default; + constexpr Point (const Point&) = default; /** Creates a point from an (x, y) position. */ - JUCE_CONSTEXPR Point (ValueType initialX, ValueType initialY) noexcept : x (initialX), y (initialY) {} + constexpr Point (ValueType initialX, ValueType initialY) noexcept : x (initialX), y (initialY) {} //============================================================================== /** Copies this point from another one. */ Point& operator= (const Point&) = default; - JUCE_CONSTEXPR inline bool operator== (Point other) const noexcept { return x == other.x && y == other.y; } - JUCE_CONSTEXPR inline bool operator!= (Point other) const noexcept { return x != other.x || y != other.y; } + constexpr inline bool operator== (Point other) const noexcept { return x == other.x && y == other.y; } + constexpr inline bool operator!= (Point other) const noexcept { return x != other.x || y != other.y; } /** Returns true if the point is (0, 0). */ - JUCE_CONSTEXPR bool isOrigin() const noexcept { return x == ValueType() && y == ValueType(); } + constexpr bool isOrigin() const noexcept { return x == ValueType() && y == ValueType(); } /** Returns true if the coordinates are finite values. */ - JUCE_CONSTEXPR inline bool isFinite() const noexcept { return juce_isfinite(x) && juce_isfinite(y); } + constexpr inline bool isFinite() const noexcept { return juce_isfinite(x) && juce_isfinite(y); } /** Returns the point's x coordinate. */ - JUCE_CONSTEXPR inline ValueType getX() const noexcept { return x; } + constexpr inline ValueType getX() const noexcept { return x; } /** Returns the point's y coordinate. */ - JUCE_CONSTEXPR inline ValueType getY() const noexcept { return y; } + constexpr inline ValueType getY() const noexcept { return y; } /** Sets the point's x coordinate. */ - inline void setX (ValueType newX) noexcept { x = newX; } + inline void setX (ValueType newX) noexcept { x = newX; } /** Sets the point's y coordinate. */ - inline void setY (ValueType newY) noexcept { y = newY; } + inline void setY (ValueType newY) noexcept { y = newY; } /** Returns a point which has the same Y position as this one, but a new X. */ - JUCE_CONSTEXPR Point withX (ValueType newX) const noexcept { return Point (newX, y); } + constexpr Point withX (ValueType newX) const noexcept { return Point (newX, y); } /** Returns a point which has the same X position as this one, but a new Y. */ - JUCE_CONSTEXPR Point withY (ValueType newY) const noexcept { return Point (x, newY); } + constexpr Point withY (ValueType newY) const noexcept { return Point (x, newY); } /** Changes the point's x and y coordinates. */ - void setXY (ValueType newX, ValueType newY) noexcept { x = newX; y = newY; } + void setXY (ValueType newX, ValueType newY) noexcept { x = newX; y = newY; } /** Adds a pair of coordinates to this value. */ - void addXY (ValueType xToAdd, ValueType yToAdd) noexcept { x += xToAdd; y += yToAdd; } + void addXY (ValueType xToAdd, ValueType yToAdd) noexcept { x += xToAdd; y += yToAdd; } //============================================================================== /** Returns a point with a given offset from this one. */ - JUCE_CONSTEXPR Point translated (ValueType deltaX, ValueType deltaY) const noexcept { return Point (x + deltaX, y + deltaY); } + constexpr Point translated (ValueType deltaX, ValueType deltaY) const noexcept { return Point (x + deltaX, y + deltaY); } /** Adds two points together */ - JUCE_CONSTEXPR Point operator+ (Point other) const noexcept { return Point (x + other.x, y + other.y); } + constexpr Point operator+ (Point other) const noexcept { return Point (x + other.x, y + other.y); } /** Adds another point's coordinates to this one */ - Point& operator+= (Point other) noexcept { x += other.x; y += other.y; return *this; } + Point& operator+= (Point other) noexcept { x += other.x; y += other.y; return *this; } /** Subtracts one points from another */ - JUCE_CONSTEXPR Point operator- (Point other) const noexcept { return Point (x - other.x, y - other.y); } + constexpr Point operator- (Point other) const noexcept { return Point (x - other.x, y - other.y); } /** Subtracts another point's coordinates to this one */ - Point& operator-= (Point other) noexcept { x -= other.x; y -= other.y; return *this; } + Point& operator-= (Point other) noexcept { x -= other.x; y -= other.y; return *this; } /** Multiplies two points together */ template <typename OtherType> - JUCE_CONSTEXPR Point operator* (Point<OtherType> other) const noexcept { return Point ((ValueType) (x * other.x), (ValueType) (y * other.y)); } + constexpr Point operator* (Point<OtherType> other) const noexcept { return Point ((ValueType) (x * other.x), (ValueType) (y * other.y)); } /** Multiplies another point's coordinates to this one */ template <typename OtherType> - Point& operator*= (Point<OtherType> other) noexcept { *this = *this * other; return *this; } + Point& operator*= (Point<OtherType> other) noexcept { *this = *this * other; return *this; } /** Divides one point by another */ template <typename OtherType> - JUCE_CONSTEXPR Point operator/ (Point<OtherType> other) const noexcept { return Point ((ValueType) (x / other.x), (ValueType) (y / other.y)); } + constexpr Point operator/ (Point<OtherType> other) const noexcept { return Point ((ValueType) (x / other.x), (ValueType) (y / other.y)); } /** Divides this point's coordinates by another */ template <typename OtherType> - Point& operator/= (Point<OtherType> other) noexcept { *this = *this / other; return *this; } + Point& operator/= (Point<OtherType> other) noexcept { *this = *this / other; return *this; } /** Returns a point whose coordinates are multiplied by a given scalar value. */ - template <typename FloatType> - JUCE_CONSTEXPR Point operator* (FloatType multiplier) const noexcept { return Point ((ValueType) (x * multiplier), (ValueType) (y * multiplier)); } + template <typename OtherType> + constexpr Point operator* (OtherType multiplier) const noexcept + { + using CommonType = typename std::common_type<ValueType, OtherType>::type; + return Point ((ValueType) ((CommonType) x * (CommonType) multiplier), + (ValueType) ((CommonType) y * (CommonType) multiplier)); + } /** Returns a point whose coordinates are divided by a given scalar value. */ - template <typename FloatType> - JUCE_CONSTEXPR Point operator/ (FloatType divisor) const noexcept { return Point ((ValueType) (x / divisor), (ValueType) (y / divisor)); } + template <typename OtherType> + constexpr Point operator/ (OtherType divisor) const noexcept + { + using CommonType = typename std::common_type<ValueType, OtherType>::type; + return Point ((ValueType) ((CommonType) x / (CommonType) divisor), + (ValueType) ((CommonType) y / (CommonType) divisor)); + } /** Multiplies the point's coordinates by a scalar value. */ template <typename FloatType> - Point& operator*= (FloatType multiplier) noexcept { x = (ValueType) (x * multiplier); y = (ValueType) (y * multiplier); return *this; } + Point& operator*= (FloatType multiplier) noexcept { x = (ValueType) (x * multiplier); y = (ValueType) (y * multiplier); return *this; } /** Divides the point's coordinates by a scalar value. */ template <typename FloatType> - Point& operator/= (FloatType divisor) noexcept { x = (ValueType) (x / divisor); y = (ValueType) (y / divisor); return *this; } + Point& operator/= (FloatType divisor) noexcept { x = (ValueType) (x / divisor); y = (ValueType) (y / divisor); return *this; } /** Returns the inverse of this point. */ - JUCE_CONSTEXPR Point operator-() const noexcept { return Point (-x, -y); } + constexpr Point operator-() const noexcept { return Point (-x, -y); } //============================================================================== /** This type will be double if the Point's type is double, otherwise it will be float. */ @@ -145,16 +154,16 @@ public: //============================================================================== /** Returns the straight-line distance between this point and the origin. */ - ValueType getDistanceFromOrigin() const noexcept { return juce_hypot (x, y); } + ValueType getDistanceFromOrigin() const noexcept { return juce_hypot (x, y); } /** Returns the straight-line distance between this point and another one. */ - ValueType getDistanceFrom (Point other) const noexcept { return juce_hypot (x - other.x, y - other.y); } + ValueType getDistanceFrom (Point other) const noexcept { return juce_hypot (x - other.x, y - other.y); } /** Returns the square of the straight-line distance between this point and the origin. */ - JUCE_CONSTEXPR ValueType getDistanceSquaredFromOrigin() const noexcept { return x * x + y * y; } + constexpr ValueType getDistanceSquaredFromOrigin() const noexcept { return x * x + y * y; } /** Returns the square of the straight-line distance between this point and another one. */ - JUCE_CONSTEXPR ValueType getDistanceSquaredFrom (Point other) const noexcept { return (*this - other).getDistanceSquaredFromOrigin(); } + constexpr ValueType getDistanceSquaredFrom (Point other) const noexcept { return (*this - other).getDistanceSquaredFromOrigin(); } /** Returns the angle from this point to another one. @@ -200,7 +209,7 @@ public: } /** Returns the dot-product of two points (x1 * x2 + y1 * y2). */ - JUCE_CONSTEXPR FloatType getDotProduct (Point other) const noexcept { return x * other.x + y * other.y; } + constexpr FloatType getDotProduct (Point other) const noexcept { return x * other.x + y * other.y; } //============================================================================== /** Uses a transform to change the point's coordinates. @@ -213,22 +222,22 @@ public: /** Returns the position of this point, if it is transformed by a given AffineTransform. */ Point transformedBy (const AffineTransform& transform) const noexcept { - return Point (static_cast<ValueType> (transform.mat00 * x + transform.mat01 * y + transform.mat02), - static_cast<ValueType> (transform.mat10 * x + transform.mat11 * y + transform.mat12)); + return Point (static_cast<ValueType> (transform.mat00 * (float) x + transform.mat01 * (float) y + transform.mat02), + static_cast<ValueType> (transform.mat10 * (float) x + transform.mat11 * (float) y + transform.mat12)); } //============================================================================== /** Casts this point to a Point<int> object. */ - JUCE_CONSTEXPR Point<int> toInt() const noexcept { return Point<int> (static_cast<int> (x), static_cast<int> (y)); } + constexpr Point<int> toInt() const noexcept { return Point<int> (static_cast<int> (x), static_cast<int> (y)); } /** Casts this point to a Point<float> object. */ - JUCE_CONSTEXPR Point<float> toFloat() const noexcept { return Point<float> (static_cast<float> (x), static_cast<float> (y)); } + constexpr Point<float> toFloat() const noexcept { return Point<float> (static_cast<float> (x), static_cast<float> (y)); } /** Casts this point to a Point<double> object. */ - JUCE_CONSTEXPR Point<double> toDouble() const noexcept { return Point<double> (static_cast<double> (x), static_cast<double> (y)); } + constexpr Point<double> toDouble() const noexcept { return Point<double> (static_cast<double> (x), static_cast<double> (y)); } /** Casts this point to a Point<int> object using roundToInt() to convert the values. */ - JUCE_CONSTEXPR Point<int> roundToInt() const noexcept { return Point<int> (juce::roundToInt (x), juce::roundToInt (y)); } + constexpr Point<int> roundToInt() const noexcept { return Point<int> (juce::roundToInt (x), juce::roundToInt (y)); } /** Returns the point as a string in the form "x, y". */ String toString() const { return String (x) + ", " + String (y); } diff --git a/modules/juce_graphics/geometry/juce_Rectangle.h b/modules/juce_graphics/geometry/juce_Rectangle.h index 6c833c97..ac1fa8d3 100644 --- a/modules/juce_graphics/geometry/juce_Rectangle.h +++ b/modules/juce_graphics/geometry/juce_Rectangle.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -350,10 +349,10 @@ public: template <typename FloatType> Rectangle operator*= (FloatType scaleFactor) noexcept { - Rectangle<FloatType> (pos.x * scaleFactor, - pos.y * scaleFactor, - w * scaleFactor, - h * scaleFactor).copyWithRounding (*this); + Rectangle<FloatType> ((FloatType) pos.x * scaleFactor, + (FloatType) pos.y * scaleFactor, + (FloatType) w * scaleFactor, + (FloatType) h * scaleFactor).copyWithRounding (*this); return *this; } @@ -365,10 +364,10 @@ public: template <typename FloatType> Rectangle operator*= (Point<FloatType> scaleFactor) noexcept { - Rectangle<FloatType> (pos.x * scaleFactor.x, - pos.y * scaleFactor.y, - w * scaleFactor.x, - h * scaleFactor.y).copyWithRounding (*this); + Rectangle<FloatType> ((FloatType) pos.x * scaleFactor.x, + (FloatType) pos.y * scaleFactor.y, + (FloatType) w * scaleFactor.x, + (FloatType) h * scaleFactor.y).copyWithRounding (*this); return *this; } @@ -385,10 +384,10 @@ public: template <typename FloatType> Rectangle operator/= (FloatType scaleFactor) noexcept { - Rectangle<FloatType> (pos.x / scaleFactor, - pos.y / scaleFactor, - w / scaleFactor, - h / scaleFactor).copyWithRounding (*this); + Rectangle<FloatType> ((FloatType) pos.x / scaleFactor, + (FloatType) pos.y / scaleFactor, + (FloatType) w / scaleFactor, + (FloatType) h / scaleFactor).copyWithRounding (*this); return *this; } @@ -396,10 +395,10 @@ public: template <typename FloatType> Rectangle operator/= (Point<FloatType> scaleFactor) noexcept { - Rectangle<FloatType> (pos.x / scaleFactor.x, - pos.y / scaleFactor.y, - w / scaleFactor.x, - h / scaleFactor.y).copyWithRounding (*this); + Rectangle<FloatType> ((FloatType) pos.x / scaleFactor.x, + (FloatType) pos.y / scaleFactor.y, + (FloatType) w / scaleFactor.x, + (FloatType) h / scaleFactor.y).copyWithRounding (*this); return *this; } @@ -507,7 +506,7 @@ public: by the specified amount and returning the section that was removed. E.g. if this rectangle is (100, 100, 300, 300) and amountToRemove is 50, this will - return (250, 100, 50, 300) and leave this rectangle as (100, 100, 250, 300). + return (350, 100, 50, 300) and leave this rectangle as (100, 100, 250, 300). If amountToRemove is greater than the width of this rectangle, it'll be clipped to that value. @@ -524,7 +523,7 @@ public: by the specified amount and returning the section that was removed. E.g. if this rectangle is (100, 100, 300, 300) and amountToRemove is 50, this will - return (100, 250, 300, 50) and leave this rectangle as (100, 100, 300, 250). + return (100, 350, 300, 50) and leave this rectangle as (100, 100, 300, 250). If amountToRemove is greater than the height of this rectangle, it'll be clipped to that value. @@ -553,22 +552,22 @@ public: template <typename FloatType> Point<ValueType> getRelativePoint (FloatType relativeX, FloatType relativeY) const noexcept { - return { pos.x + static_cast<ValueType> (w * relativeX), - pos.y + static_cast<ValueType> (h * relativeY) }; + return { pos.x + static_cast<ValueType> ((FloatType) w * relativeX), + pos.y + static_cast<ValueType> ((FloatType) h * relativeY) }; } /** Returns a proportion of the width of this rectangle. */ template <typename FloatType> ValueType proportionOfWidth (FloatType proportion) const noexcept { - return static_cast<ValueType> (w * proportion); + return static_cast<ValueType> ((FloatType) w * proportion); } /** Returns a proportion of the height of this rectangle. */ template <typename FloatType> ValueType proportionOfHeight (FloatType proportion) const noexcept { - return static_cast<ValueType> (h * proportion); + return static_cast<ValueType> ((FloatType) h * proportion); } /** Returns a rectangle based on some proportional coordinates relative to this one. @@ -751,10 +750,11 @@ public: switch (inside) { - case 1 + 2 + 8: w = r - otherR; pos.x = otherR; return true; - case 1 + 2 + 4: h = b - otherB; pos.y = otherB; return true; - case 2 + 4 + 8: w = other.pos.x - pos.x; return true; - case 1 + 4 + 8: h = other.pos.y - pos.y; return true; + case 1 + 2 + 8: w = r - otherR; pos.x = otherR; return true; + case 1 + 2 + 4: h = b - otherB; pos.y = otherB; return true; + case 2 + 4 + 8: w = other.pos.x - pos.x; return true; + case 1 + 4 + 8: h = other.pos.y - pos.y; return true; + default: break; } return false; diff --git a/modules/juce_graphics/geometry/juce_RectangleList.h b/modules/juce_graphics/geometry/juce_RectangleList.h index 81bd2f5e..783caf2f 100644 --- a/modules/juce_graphics/geometry/juce_RectangleList.h +++ b/modules/juce_graphics/geometry/juce_RectangleList.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/image_formats/juce_GIFLoader.cpp b/modules/juce_graphics/image_formats/juce_GIFLoader.cpp index adec9cdc..5875e491 100644 --- a/modules/juce_graphics/image_formats/juce_GIFLoader.cpp +++ b/modules/juce_graphics/image_formats/juce_GIFLoader.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/image_formats/juce_JPEGLoader.cpp b/modules/juce_graphics/image_formats/juce_JPEGLoader.cpp index 413e519e..58a61bdc 100644 --- a/modules/juce_graphics/image_formats/juce_JPEGLoader.cpp +++ b/modules/juce_graphics/image_formats/juce_JPEGLoader.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -27,10 +26,7 @@ namespace juce { -#if JUCE_MSVC - #pragma warning (push) - #pragma warning (disable: 4365) -#endif +JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4365) namespace jpeglibNamespace { @@ -39,28 +35,17 @@ namespace jpeglibNamespace typedef unsigned char boolean; #endif - #if JUCE_CLANG - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wconversion" - #pragma clang diagnostic ignored "-Wdeprecated-register" - #pragma clang diagnostic ignored "-Wcast-align" - #if __has_warning("-Wzero-as-null-pointer-constant") - #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" - #endif - #if __has_warning("-Wcomma") - #pragma clang diagnostic ignored "-Wcomma" - #endif - #endif - - #if JUCE_GCC - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wconversion" - #pragma GCC diagnostic ignored "-Wsign-conversion" - #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - #if __GNUC__ > 5 - #pragma GCC diagnostic ignored "-Wshift-negative-value" - #endif - #endif + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wconversion", + "-Wdeprecated-register", + "-Wdeprecated-declarations", + "-Wsign-conversion", + "-Wcast-align", + "-Wswitch-enum", + "-Wswitch-default", + "-Wimplicit-fallthrough", + "-Wzero-as-null-pointer-constant", + "-Wshift-negative-value", + "-Wcomma") #define JPEG_INTERNALS #undef FAR @@ -135,13 +120,7 @@ namespace jpeglibNamespace #include "jpglib/jutils.c" #include "jpglib/transupp.c" - #if JUCE_CLANG - #pragma clang diagnostic pop - #endif - - #if JUCE_GCC - #pragma GCC diagnostic pop - #endif + JUCE_END_IGNORE_WARNINGS_GCC_LIKE #else #define JPEG_INTERNALS #undef FAR @@ -152,9 +131,7 @@ namespace jpeglibNamespace #undef max #undef min -#if JUCE_MSVC - #pragma warning (pop) -#endif +JUCE_END_IGNORE_WARNINGS_MSVC //============================================================================== namespace JPEGHelpers diff --git a/modules/juce_graphics/image_formats/juce_PNGLoader.cpp b/modules/juce_graphics/image_formats/juce_PNGLoader.cpp index 8afd94f2..79418fb8 100644 --- a/modules/juce_graphics/image_formats/juce_PNGLoader.cpp +++ b/modules/juce_graphics/image_formats/juce_PNGLoader.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -27,20 +26,16 @@ namespace juce { -#if JUCE_MSVC - #pragma warning (push) - #pragma warning (disable: 4390 4611 4365 4267) - #ifdef __INTEL_COMPILER - #pragma warning (disable: 2544 2545) - #endif -#endif +JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4390 4611 4365 4267 4616 2544 2545) namespace zlibNamespace { #if JUCE_INCLUDE_ZLIB_CODE #undef OS_CODE #undef fdopen - #include "../../juce_core/zip/zlib/zlib.h" + #define ZLIB_INTERNAL + #define NO_DUMMY_DECL + #include <juce_core/zip/zlib/zlib.h> #undef OS_CODE #else #include JUCE_ZLIB_INCLUDE_PATH @@ -63,22 +58,11 @@ namespace pnglibNamespace using std::free; #endif - #if JUCE_CLANG - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wsign-conversion" - #if __has_warning("-Wzero-as-null-pointer-constant") - #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" - #endif - #if __has_warning("-Wcomma") - #pragma clang diagnostic ignored "-Wcomma" - #endif - #endif - - #if JUCE_GCC - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wsign-conversion" - #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - #endif + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wsign-conversion", + "-Wimplicit-fallthrough", + "-Wtautological-constant-out-of-range-compare", + "-Wzero-as-null-pointer-constant", + "-Wcomma") #undef check using std::abs; @@ -326,13 +310,7 @@ namespace pnglibNamespace #include "pnglib/pngwtran.c" #include "pnglib/pngwutil.c" - #if JUCE_CLANG - #pragma clang diagnostic pop - #endif - - #if JUCE_GCC - #pragma GCC diagnostic pop - #endif + JUCE_END_IGNORE_WARNINGS_GCC_LIKE #else extern "C" @@ -347,9 +325,7 @@ namespace pnglibNamespace #undef min #undef fdopen -#if JUCE_MSVC - #pragma warning (pop) -#endif +JUCE_END_IGNORE_WARNINGS_MSVC //============================================================================== namespace PNGHelpers @@ -380,10 +356,7 @@ namespace PNGHelpers static void JUCE_CDECL warningCallback (png_structp, png_const_charp) {} - #if JUCE_MSVC - #pragma warning (push) - #pragma warning (disable: 4611) // (warning about setjmp) - #endif + JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4611) static bool readHeader (InputStream& in, png_structp pngReadStruct, png_infop pngInfoStruct, jmp_buf& errorJumpBuf, png_uint_32& width, png_uint_32& height, int& bitDepth, int& colorType, int& interlaceType) noexcept @@ -435,9 +408,7 @@ namespace PNGHelpers return false; } - #if JUCE_MSVC - #pragma warning (pop) - #endif + JUCE_END_IGNORE_WARNINGS_MSVC static Image createImageFromData (bool hasAlphaChan, int width, int height, png_bytepp rows) { diff --git a/modules/juce_graphics/images/juce_Image.cpp b/modules/juce_graphics/images/juce_Image.cpp index b3ac8fe8..f6560e30 100644 --- a/modules/juce_graphics/images/juce_Image.cpp +++ b/modules/juce_graphics/images/juce_Image.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -310,8 +309,8 @@ Image Image::rescaled (int newWidth, int newHeight, Graphics::ResamplingQuality Graphics g (newImage); g.setImageResamplingQuality (quality); - g.drawImageTransformed (*this, AffineTransform::scale (newWidth / (float) image->width, - newHeight / (float) image->height), false); + g.drawImageTransformed (*this, AffineTransform::scale ((float) newWidth / (float) image->width, + (float) newHeight / (float) image->height), false); return newImage; } @@ -426,6 +425,7 @@ Colour Image::BitmapData::getPixelColour (int x, int y) const noexcept case Image::ARGB: return Colour ( ((const PixelARGB*) pixel)->getUnpremultiplied()); case Image::RGB: return Colour (*((const PixelRGB*) pixel)); case Image::SingleChannel: return Colour (*((const PixelAlpha*) pixel)); + case Image::UnknownFormat: default: jassertfalse; break; } @@ -444,6 +444,7 @@ void Image::BitmapData::setPixelColour (int x, int y, Colour colour) const noexc case Image::ARGB: ((PixelARGB*) pixel)->set (col); break; case Image::RGB: ((PixelRGB*) pixel)->set (col); break; case Image::SingleChannel: ((PixelAlpha*) pixel)->set (col); break; + case Image::UnknownFormat: default: jassertfalse; break; } } @@ -521,6 +522,7 @@ static void performPixelOp (const Image::BitmapData& data, const PixelOperation& case Image::ARGB: PixelIterator<PixelARGB> ::iterate (data, pixelOp); break; case Image::RGB: PixelIterator<PixelRGB> ::iterate (data, pixelOp); break; case Image::SingleChannel: PixelIterator<PixelAlpha>::iterate (data, pixelOp); break; + case Image::UnknownFormat: default: jassertfalse; break; } } @@ -660,7 +662,7 @@ void Image::moveImageSection (int dx, int dy, auto dst = destData.getPixelPointer (dx - minX, dy - minY); auto src = destData.getPixelPointer (sx - minX, sy - minY); - auto lineSize = (size_t) (destData.pixelStride * w); + auto lineSize = (size_t) destData.pixelStride * (size_t) w; if (dy > sy) { diff --git a/modules/juce_graphics/images/juce_Image.h b/modules/juce_graphics/images/juce_Image.h index 746a738b..4170d3e3 100644 --- a/modules/juce_graphics/images/juce_Image.h +++ b/modules/juce_graphics/images/juce_Image.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/images/juce_ImageCache.cpp b/modules/juce_graphics/images/juce_ImageCache.cpp index fed286cc..cfe2dfa4 100644 --- a/modules/juce_graphics/images/juce_ImageCache.cpp +++ b/modules/juce_graphics/images/juce_ImageCache.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/images/juce_ImageCache.h b/modules/juce_graphics/images/juce_ImageCache.h index 99e4543e..09554cf4 100644 --- a/modules/juce_graphics/images/juce_ImageCache.h +++ b/modules/juce_graphics/images/juce_ImageCache.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/images/juce_ImageConvolutionKernel.cpp b/modules/juce_graphics/images/juce_ImageConvolutionKernel.cpp index d3c8a4cf..396a1684 100644 --- a/modules/juce_graphics/images/juce_ImageConvolutionKernel.cpp +++ b/modules/juce_graphics/images/juce_ImageConvolutionKernel.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/images/juce_ImageConvolutionKernel.h b/modules/juce_graphics/images/juce_ImageConvolutionKernel.h index 8383ce40..2a79316b 100644 --- a/modules/juce_graphics/images/juce_ImageConvolutionKernel.h +++ b/modules/juce_graphics/images/juce_ImageConvolutionKernel.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/images/juce_ImageFileFormat.cpp b/modules/juce_graphics/images/juce_ImageFileFormat.cpp index 12ad6afb..5d8eaca1 100644 --- a/modules/juce_graphics/images/juce_ImageFileFormat.cpp +++ b/modules/juce_graphics/images/juce_ImageFileFormat.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/images/juce_ImageFileFormat.h b/modules/juce_graphics/images/juce_ImageFileFormat.h index c4be97cf..0749084d 100644 --- a/modules/juce_graphics/images/juce_ImageFileFormat.h +++ b/modules/juce_graphics/images/juce_ImageFileFormat.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/juce_graphics.cpp b/modules/juce_graphics/juce_graphics.cpp index baed232a..4b2bd321 100644 --- a/modules/juce_graphics/juce_graphics.cpp +++ b/modules/juce_graphics/juce_graphics.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -47,10 +46,7 @@ #elif JUCE_WINDOWS // get rid of some warnings in Window's own headers - #ifdef JUCE_MSVC - #pragma warning (push) - #pragma warning (disable : 4458) - #endif + JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4458) #if JUCE_MINGW && JUCE_USE_DIRECTWRITE #warning "DirectWrite not currently implemented with mingw..." @@ -73,18 +69,12 @@ #include <unordered_map> - #ifdef JUCE_MSVC - #pragma warning (pop) - #endif + JUCE_END_IGNORE_WARNINGS_MSVC #elif JUCE_IOS #import <QuartzCore/QuartzCore.h> #import <CoreText/CoreText.h> - #if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_3_2 - #error "JUCE no longer supports targets earlier than iOS 3.2" - #endif - #elif JUCE_LINUX #ifndef JUCE_USE_FREETYPE #define JUCE_USE_FREETYPE 1 diff --git a/modules/juce_graphics/juce_graphics.h b/modules/juce_graphics/juce_graphics.h index 054be147..8331b1de 100644 --- a/modules/juce_graphics/juce_graphics.h +++ b/modules/juce_graphics/juce_graphics.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -29,14 +28,14 @@ The block below describes the properties of this module, and is read by the Projucer to automatically generate project code that uses it. For details about the syntax and how to create or use a module, see the - JUCE Module Format.txt file. + JUCE Module Format.md file. BEGIN_JUCE_MODULE_DECLARATION ID: juce_graphics vendor: juce - version: 5.4.7 + version: 6.0.5 name: JUCE graphics classes description: Classes for 2D vector graphics, image loading/saving, font handling, etc. website: http://www.juce.com/juce @@ -45,7 +44,7 @@ dependencies: juce_events OSXFrameworks: Cocoa QuartzCore iOSFrameworks: CoreGraphics CoreImage CoreText QuartzCore - linuxPackages: x11 xinerama xext freetype2 + linuxPackages: freetype2 END_JUCE_MODULE_DECLARATION @@ -80,7 +79,7 @@ /** Config: JUCE_DISABLE_COREGRAPHICS_FONT_SMOOTHING - Setting this flag will turn off CoreGraphics font smoothing, which some people + Setting this flag will turn off CoreGraphics font smoothing on macOS, which some people find makes the text too 'fat' for their taste. */ #ifndef JUCE_DISABLE_COREGRAPHICS_FONT_SMOOTHING diff --git a/modules/juce_graphics/juce_graphics.mm b/modules/juce_graphics/juce_graphics.mm index bfdf9cb7..5dc07873 100644 --- a/modules/juce_graphics/juce_graphics.mm +++ b/modules/juce_graphics/juce_graphics.mm @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/native/juce_RenderingHelpers.h b/modules/juce_graphics/native/juce_RenderingHelpers.h index 0d1ce924..f2b55022 100644 --- a/modules/juce_graphics/native/juce_RenderingHelpers.h +++ b/modules/juce_graphics/native/juce_RenderingHelpers.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -27,10 +26,7 @@ namespace juce { -#if JUCE_MSVC - #pragma warning (push) - #pragma warning (disable: 4127) // "expression is constant" warning -#endif +JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4127) namespace RenderingHelpers { @@ -96,7 +92,7 @@ public: float getPhysicalPixelScaleFactor() const noexcept { - return isOnlyTranslated ? 1.0f : std::abs (complexTransform.getScaleFactor()); + return isOnlyTranslated ? 1.0f : std::sqrt (std::abs (complexTransform.getDeterminant())); } void moveOriginInDeviceSpace (Point<int> delta) noexcept @@ -1426,6 +1422,8 @@ namespace EdgeTableFillers if (tiledFill) { TransformedImageFill<PixelARGB, PixelRGB, true> r (destData, srcData, transform, alpha, quality); iter.iterate (r); } else { TransformedImageFill<PixelARGB, PixelRGB, false> r (destData, srcData, transform, alpha, quality); iter.iterate (r); } break; + case Image::SingleChannel: + case Image::UnknownFormat: default: if (tiledFill) { TransformedImageFill<PixelARGB, PixelAlpha, true> r (destData, srcData, transform, alpha, quality); iter.iterate (r); } else { TransformedImageFill<PixelARGB, PixelAlpha, false> r (destData, srcData, transform, alpha, quality); iter.iterate (r); } @@ -1434,6 +1432,7 @@ namespace EdgeTableFillers break; case Image::RGB: + { switch (srcData.pixelFormat) { case Image::ARGB: @@ -1444,13 +1443,18 @@ namespace EdgeTableFillers if (tiledFill) { TransformedImageFill<PixelRGB, PixelRGB, true> r (destData, srcData, transform, alpha, quality); iter.iterate (r); } else { TransformedImageFill<PixelRGB, PixelRGB, false> r (destData, srcData, transform, alpha, quality); iter.iterate (r); } break; + case Image::SingleChannel: + case Image::UnknownFormat: default: if (tiledFill) { TransformedImageFill<PixelRGB, PixelAlpha, true> r (destData, srcData, transform, alpha, quality); iter.iterate (r); } else { TransformedImageFill<PixelRGB, PixelAlpha, false> r (destData, srcData, transform, alpha, quality); iter.iterate (r); } break; } break; + } + case Image::SingleChannel: + case Image::UnknownFormat: default: switch (srcData.pixelFormat) { @@ -1462,6 +1466,8 @@ namespace EdgeTableFillers if (tiledFill) { TransformedImageFill<PixelAlpha, PixelRGB, true> r (destData, srcData, transform, alpha, quality); iter.iterate (r); } else { TransformedImageFill<PixelAlpha, PixelRGB, false> r (destData, srcData, transform, alpha, quality); iter.iterate (r); } break; + case Image::SingleChannel: + case Image::UnknownFormat: default: if (tiledFill) { TransformedImageFill<PixelAlpha, PixelAlpha, true> r (destData, srcData, transform, alpha, quality); iter.iterate (r); } else { TransformedImageFill<PixelAlpha, PixelAlpha, false> r (destData, srcData, transform, alpha, quality); iter.iterate (r); } @@ -1487,6 +1493,8 @@ namespace EdgeTableFillers if (tiledFill) { ImageFill<PixelARGB, PixelRGB, true> r (destData, srcData, alpha, x, y); iter.iterate (r); } else { ImageFill<PixelARGB, PixelRGB, false> r (destData, srcData, alpha, x, y); iter.iterate (r); } break; + case Image::SingleChannel: + case Image::UnknownFormat: default: if (tiledFill) { ImageFill<PixelARGB, PixelAlpha, true> r (destData, srcData, alpha, x, y); iter.iterate (r); } else { ImageFill<PixelARGB, PixelAlpha, false> r (destData, srcData, alpha, x, y); iter.iterate (r); } @@ -1505,6 +1513,8 @@ namespace EdgeTableFillers if (tiledFill) { ImageFill<PixelRGB, PixelRGB, true> r (destData, srcData, alpha, x, y); iter.iterate (r); } else { ImageFill<PixelRGB, PixelRGB, false> r (destData, srcData, alpha, x, y); iter.iterate (r); } break; + case Image::SingleChannel: + case Image::UnknownFormat: default: if (tiledFill) { ImageFill<PixelRGB, PixelAlpha, true> r (destData, srcData, alpha, x, y); iter.iterate (r); } else { ImageFill<PixelRGB, PixelAlpha, false> r (destData, srcData, alpha, x, y); iter.iterate (r); } @@ -1512,6 +1522,8 @@ namespace EdgeTableFillers } break; + case Image::SingleChannel: + case Image::UnknownFormat: default: switch (srcData.pixelFormat) { @@ -1523,6 +1535,8 @@ namespace EdgeTableFillers if (tiledFill) { ImageFill<PixelAlpha, PixelRGB, true> r (destData, srcData, alpha, x, y); iter.iterate (r); } else { ImageFill<PixelAlpha, PixelRGB, false> r (destData, srcData, alpha, x, y); iter.iterate (r); } break; + case Image::SingleChannel: + case Image::UnknownFormat: default: if (tiledFill) { ImageFill<PixelAlpha, PixelAlpha, true> r (destData, srcData, alpha, x, y); iter.iterate (r); } else { ImageFill<PixelAlpha, PixelAlpha, false> r (destData, srcData, alpha, x, y); iter.iterate (r); } @@ -2589,6 +2603,8 @@ public: { case Image::ARGB: EdgeTableFillers::renderSolidFill (iter, destData, colour, replaceContents, (PixelARGB*) nullptr); break; case Image::RGB: EdgeTableFillers::renderSolidFill (iter, destData, colour, replaceContents, (PixelRGB*) nullptr); break; + case Image::SingleChannel: + case Image::UnknownFormat: default: EdgeTableFillers::renderSolidFill (iter, destData, colour, replaceContents, (PixelAlpha*) nullptr); break; } } @@ -2606,6 +2622,8 @@ public: { case Image::ARGB: EdgeTableFillers::renderGradient (iter, destData, gradient, trans, lookupTable, numLookupEntries, isIdentity, (PixelARGB*) nullptr); break; case Image::RGB: EdgeTableFillers::renderGradient (iter, destData, gradient, trans, lookupTable, numLookupEntries, isIdentity, (PixelRGB*) nullptr); break; + case Image::SingleChannel: + case Image::UnknownFormat: default: EdgeTableFillers::renderGradient (iter, destData, gradient, trans, lookupTable, numLookupEntries, isIdentity, (PixelAlpha*) nullptr); break; } } @@ -2718,8 +2736,6 @@ protected: } -#if JUCE_MSVC - #pragma warning (pop) -#endif +JUCE_END_IGNORE_WARNINGS_MSVC } // namespace juce diff --git a/modules/juce_graphics/native/juce_android_Fonts.cpp b/modules/juce_graphics/native/juce_android_Fonts.cpp index e0f5ed44..f6a2e0c0 100644 --- a/modules/juce_graphics/native/juce_android_Fonts.cpp +++ b/modules/juce_graphics/native/juce_android_Fonts.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -459,7 +458,7 @@ private: static File getCacheDirectory() { - static File result = [] () + static File result = []() { auto appContext = getAppContext(); diff --git a/modules/juce_graphics/native/juce_android_GraphicsContext.cpp b/modules/juce_graphics/native/juce_android_GraphicsContext.cpp index ec3a14fc..a49000f4 100644 --- a/modules/juce_graphics/native/juce_android_GraphicsContext.cpp +++ b/modules/juce_graphics/native/juce_android_GraphicsContext.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/native/juce_android_IconHelpers.cpp b/modules/juce_graphics/native/juce_android_IconHelpers.cpp index 3a11f8e3..b89815dd 100644 --- a/modules/juce_graphics/native/juce_android_IconHelpers.cpp +++ b/modules/juce_graphics/native/juce_android_IconHelpers.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/native/juce_freetype_Fonts.cpp b/modules/juce_graphics/native/juce_freetype_Fonts.cpp index d73cf98c..a74e630c 100644 --- a/modules/juce_graphics/native/juce_freetype_Fonts.cpp +++ b/modules/juce_graphics/native/juce_freetype_Fonts.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -198,9 +197,7 @@ public: { for (auto& path : paths) { - DirectoryIterator iter (File::getCurrentWorkingDirectory().getChildFile (path), true); - - while (iter.next()) + for (const auto& iter : RangedDirectoryIterator (File::getCurrentWorkingDirectory().getChildFile (path), true)) if (iter.getFile().hasFileExtension ("ttf;pfb;pcf;otf")) scanFont (iter.getFile()); } @@ -328,7 +325,7 @@ public: if (getGlyphShape (destShape, face->glyph->outline, scale)) { - addGlyph (character, destShape, face->glyph->metrics.horiAdvance * scale); + addGlyph (character, destShape, (float) face->glyph->metrics.horiAdvance * scale); if ((face->face_flags & FT_FACE_FLAG_KERNING) != 0) addKerning (face, (uint32) character, glyphIndex); @@ -358,15 +355,15 @@ private: for (int p = startPoint; p <= endPoint; ++p) { - auto x = scaleX * points[p].x; - auto y = scaleY * points[p].y; + auto x = scaleX * (float) points[p].x; + auto y = scaleY * (float) points[p].y; if (p == startPoint) { if (FT_CURVE_TAG (tags[p]) == FT_Curve_Tag_Conic) { - auto x2 = scaleX * points [endPoint].x; - auto y2 = scaleY * points [endPoint].y; + auto x2 = scaleX * (float) points[endPoint].x; + auto y2 = scaleY * (float) points[endPoint].y; if (FT_CURVE_TAG (tags[endPoint]) != FT_Curve_Tag_On) { @@ -390,8 +387,8 @@ private: else if (FT_CURVE_TAG (tags[p]) == FT_Curve_Tag_Conic) { const int nextIndex = (p == endPoint) ? startPoint : p + 1; - auto x2 = scaleX * points [nextIndex].x; - auto y2 = scaleY * points [nextIndex].y; + auto x2 = scaleX * (float) points[nextIndex].x; + auto y2 = scaleY * (float) points[nextIndex].y; if (FT_CURVE_TAG (tags [nextIndex]) == FT_Curve_Tag_Conic) { @@ -415,10 +412,10 @@ private: || FT_CURVE_TAG (tags[next2]) != FT_Curve_Tag_On) return false; - auto x2 = scaleX * points [next1].x; - auto y2 = scaleY * points [next1].y; - auto x3 = scaleX * points [next2].x; - auto y3 = scaleY * points [next2].y; + auto x2 = scaleX * (float) points[next1].x; + auto y2 = scaleY * (float) points[next1].y; + auto x3 = scaleX * (float) points[next2].x; + auto y3 = scaleY * (float) points[next2].y; destShape.cubicTo (x, y, x2, y2, x3, y3); p += 2; @@ -444,7 +441,7 @@ private: if (FT_Get_Kerning (face, glyphIndex, rightGlyphIndex, ft_kerning_unscaled, &kerning) == 0 && kerning.x != 0) - addKerningPair ((juce_wchar) character, (juce_wchar) rightCharCode, kerning.x / height); + addKerningPair ((juce_wchar) character, (juce_wchar) rightCharCode, (float) kerning.x / height); rightCharCode = FT_Get_Next_Char (face, rightCharCode, &rightGlyphIndex); } diff --git a/modules/juce_graphics/native/juce_linux_Fonts.cpp b/modules/juce_graphics/native/juce_linux_Fonts.cpp index bff6dfac..a5cfd584 100644 --- a/modules/juce_graphics/native/juce_linux_Fonts.cpp +++ b/modules/juce_graphics/native/juce_linux_Fonts.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/native/juce_linux_IconHelpers.cpp b/modules/juce_graphics/native/juce_linux_IconHelpers.cpp index 3a11f8e3..b89815dd 100644 --- a/modules/juce_graphics/native/juce_linux_IconHelpers.cpp +++ b/modules/juce_graphics/native/juce_linux_IconHelpers.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.h b/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.h index 910304d4..07f7b57c 100644 --- a/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.h +++ b/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -27,11 +26,46 @@ namespace juce { +namespace detail +{ + struct ColorSpaceDelete + { + void operator() (CGColorSpaceRef ptr) const noexcept { CGColorSpaceRelease (ptr); } + }; + + struct ContextDelete + { + void operator() (CGContextRef ptr) const noexcept { CGContextRelease (ptr); } + }; + + struct DataProviderDelete + { + void operator() (CGDataProviderRef ptr) const noexcept { CGDataProviderRelease (ptr); } + }; + + struct ImageDelete + { + void operator() (CGImageRef ptr) const noexcept { CGImageRelease (ptr); } + }; + + struct GradientDelete + { + void operator() (CGGradientRef ptr) const noexcept { CGGradientRelease (ptr); } + }; + + //============================================================================== + using ColorSpacePtr = std::unique_ptr<CGColorSpace, ColorSpaceDelete>; + using ContextPtr = std::unique_ptr<CGContext, ContextDelete>; + using DataProviderPtr = std::unique_ptr<CGDataProvider, DataProviderDelete>; + using ImagePtr = std::unique_ptr<CGImage, ImageDelete>; + using GradientPtr = std::unique_ptr<CGGradient, GradientDelete>; +} + //============================================================================== class CoreGraphicsContext : public LowLevelGraphicsContext { public: - CoreGraphicsContext (CGContextRef context, float flipHeight, float targetScale); + CoreGraphicsContext (CGContextRef context, float flipHeight); ~CoreGraphicsContext() override; //============================================================================== @@ -75,10 +109,10 @@ public: bool drawTextLayout (const AttributedString&, const Rectangle<float>&) override; private: - CGContextRef context; + //============================================================================== + detail::ContextPtr context; const CGFloat flipHeight; - float targetScale; - CGColorSpaceRef rgbColourSpace, greyColourSpace; + detail::ColorSpacePtr rgbColourSpace, greyColourSpace; mutable Rectangle<int> lastClipRect; mutable bool lastClipRectIsValid = false; @@ -95,7 +129,7 @@ private: CGFontRef fontRef = {}; CGAffineTransform textMatrix = CGAffineTransformIdentity, inverseTextMatrix = CGAffineTransformIdentity; - CGGradientRef gradient = {}; + detail::GradientPtr gradient = {}; }; std::unique_ptr<SavedState> state; diff --git a/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm b/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm index cfc23932..98ae5f56 100644 --- a/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm +++ b/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -51,22 +50,23 @@ public: imageDataHolder->data.allocate (numComponents, clearImage); - CGColorSpaceRef colourSpace = (format == Image::SingleChannel) ? CGColorSpaceCreateDeviceGray() - : CGColorSpaceCreateDeviceRGB(); + auto colourSpace = detail::ColorSpacePtr { CGColorSpaceCreateWithName ((format == Image::SingleChannel) ? kCGColorSpaceGenericGrayGamma2_2 + : kCGColorSpaceSRGB) }; - context = CGBitmapContextCreate (imageDataHolder->data, (size_t) width, (size_t) height, 8, (size_t) lineStride, - colourSpace, getCGImageFlags (format)); - - CGColorSpaceRelease (colourSpace); + context = detail::ContextPtr { CGBitmapContextCreate (imageDataHolder->data, (size_t) width, (size_t) height, 8, (size_t) lineStride, + colourSpace.get(), getCGImageFlags (format)) }; } - ~CoreGraphicsPixelData() override; + ~CoreGraphicsPixelData() override + { + freeCachedImageRef(); + } std::unique_ptr<LowLevelGraphicsContext> createLowLevelContext() override { freeCachedImageRef(); sendDataChangeMessage(); - return std::make_unique<CoreGraphicsContext> (context, height, 1.0f); + return std::make_unique<CoreGraphicsContext> (context.get(), height); } void initialiseBitmapData (Image::BitmapData& bitmap, int x, int y, Image::BitmapData::ReadWriteMode mode) override @@ -99,14 +99,14 @@ public: if (cgim != nullptr && cgim->cachedImageRef != nullptr) { - CGImageRetain (cgim->cachedImageRef); - return cgim->cachedImageRef; + CGImageRetain (cgim->cachedImageRef.get()); + return cgim->cachedImageRef.get(); } CGImageRef ref = createImage (juceImage, colourSpace, false); if (cgim != nullptr) - cgim->cachedImageRef = CGImageRetain (ref); + cgim->cachedImageRef.reset (CGImageRetain (ref)); return ref; } @@ -114,17 +114,17 @@ public: static CGImageRef createImage (const Image& juceImage, CGColorSpaceRef colourSpace, bool mustOutliveSource) { const Image::BitmapData srcData (juceImage, Image::BitmapData::readOnly); - CGDataProviderRef provider; + detail::DataProviderPtr provider; if (mustOutliveSource) { CFDataRef data = CFDataCreate (nullptr, (const UInt8*) srcData.data, (CFIndex) ((size_t) srcData.lineStride * (size_t) srcData.height)); - provider = CGDataProviderCreateWithCFData (data); + provider = detail::DataProviderPtr { CGDataProviderCreateWithCFData (data) }; CFRelease (data); } else { - auto* imageDataContainer = [](const Image& img) -> HeapBlockContainer::Ptr* + auto* imageDataContainer = [] (const Image& img) -> HeapBlockContainer::Ptr* { if (auto* cgim = dynamic_cast<CoreGraphicsPixelData*> (img.getPixelData())) return new HeapBlockContainer::Ptr (cgim->imageDataHolder); @@ -132,10 +132,10 @@ public: return nullptr; } (juceImage); - provider = CGDataProviderCreateWithData (imageDataContainer, - srcData.data, - (size_t) srcData.lineStride * (size_t) srcData.height, - [] (void * __nullable info, const void*, size_t) { delete (HeapBlockContainer::Ptr*) info; }); + provider = detail::DataProviderPtr { CGDataProviderCreateWithData (imageDataContainer, + srcData.data, + (size_t) srcData.lineStride * (size_t) srcData.height, + [] (void * __nullable info, const void*, size_t) { delete (HeapBlockContainer::Ptr*) info; }) }; } CGImageRef imageRef = CGImageCreate ((size_t) srcData.width, @@ -143,16 +143,15 @@ public: 8, (size_t) srcData.pixelStride * 8, (size_t) srcData.lineStride, - colourSpace, getCGImageFlags (juceImage.getFormat()), provider, + colourSpace, getCGImageFlags (juceImage.getFormat()), provider.get(), nullptr, true, kCGRenderingIntentDefault); - CGDataProviderRelease (provider); return imageRef; } //============================================================================== - CGContextRef context; - CGImageRef cachedImageRef = {}; + detail::ContextPtr context; + detail::ImagePtr cachedImageRef; struct HeapBlockContainer : public ReferenceCountedObject { @@ -166,11 +165,7 @@ public: private: void freeCachedImageRef() { - if (cachedImageRef != CGImageRef()) - { - CGImageRelease (cachedImageRef); - cachedImageRef = {}; - } + cachedImageRef.reset(); } static CGBitmapInfo getCGImageFlags (const Image::PixelFormat& format) @@ -185,57 +180,57 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CoreGraphicsPixelData) }; -// The following implementation is outside of the class definition to avoid spurious -// warning messages when dynamically loading libraries at runtime on macOS -CoreGraphicsPixelData::~CoreGraphicsPixelData() -{ - freeCachedImageRef(); - CGContextRelease (context); -} - ImagePixelData::Ptr NativeImageType::create (Image::PixelFormat format, int width, int height, bool clearImage) const { return *new CoreGraphicsPixelData (format == Image::RGB ? Image::ARGB : format, width, height, clearImage); } //============================================================================== -CoreGraphicsContext::CoreGraphicsContext (CGContextRef c, float h, float scale) +struct ScopedCGContextState +{ + explicit ScopedCGContextState (CGContextRef c) : context (c) { CGContextSaveGState (context); } + ~ScopedCGContextState() { CGContextRestoreGState (context); } + + CGContextRef context; +}; + +//============================================================================== +CoreGraphicsContext::CoreGraphicsContext (CGContextRef c, float h) : context (c), flipHeight (h), - targetScale (scale), state (new SavedState()) { - CGContextRetain (context); - CGContextSaveGState (context); + CGContextRetain (context.get()); + CGContextSaveGState (context.get()); + #if JUCE_MAC bool enableFontSmoothing - #if JUCE_DISABLE_COREGRAPHICS_FONT_SMOOTHING - = false; - #else - = true; - #endif - - CGContextSetShouldSmoothFonts (context, enableFontSmoothing); - CGContextSetAllowsFontSmoothing (context, enableFontSmoothing); - CGContextSetShouldAntialias (context, true); - CGContextSetBlendMode (context, kCGBlendModeNormal); - rgbColourSpace = CGColorSpaceCreateDeviceRGB(); - greyColourSpace = CGColorSpaceCreateDeviceGray(); + #if JUCE_DISABLE_COREGRAPHICS_FONT_SMOOTHING + = false; + #else + = true; + #endif + + CGContextSetShouldSmoothFonts (context.get(), enableFontSmoothing); + CGContextSetAllowsFontSmoothing (context.get(), enableFontSmoothing); + #endif + + CGContextSetShouldAntialias (context.get(), true); + CGContextSetBlendMode (context.get(), kCGBlendModeNormal); + rgbColourSpace.reset (CGColorSpaceCreateWithName (kCGColorSpaceSRGB)); + greyColourSpace.reset (CGColorSpaceCreateWithName (kCGColorSpaceGenericGrayGamma2_2)); setFont (Font()); } CoreGraphicsContext::~CoreGraphicsContext() { - CGContextRestoreGState (context); - CGContextRelease (context); - CGColorSpaceRelease (rgbColourSpace); - CGColorSpaceRelease (greyColourSpace); + CGContextRestoreGState (context.get()); } //============================================================================== void CoreGraphicsContext::setOrigin (Point<int> o) { - CGContextTranslateCTM (context, o.x, -o.y); + CGContextTranslateCTM (context.get(), o.x, -o.y); if (lastClipRectIsValid) lastClipRect.translate (-o.x, -o.y); @@ -250,20 +245,20 @@ void CoreGraphicsContext::addTransform (const AffineTransform& transform) lastClipRectIsValid = false; jassert (getPhysicalPixelScaleFactor() > 0.0f); - jassert (getPhysicalPixelScaleFactor() > 0.0f); } float CoreGraphicsContext::getPhysicalPixelScaleFactor() { - auto t = CGContextGetCTM (context); + auto t = CGContextGetUserSpaceToDeviceSpaceTransform (context.get()); + auto determinant = (t.a * t.d) - (t.c * t.b); - return targetScale * (float) (juce_hypot (t.a, t.c) + juce_hypot (t.b, t.d)) / 2.0f; + return (float) std::sqrt (std::abs (determinant)); } bool CoreGraphicsContext::clipToRectangle (const Rectangle<int>& r) { - CGContextClipToRect (context, CGRectMake (r.getX(), flipHeight - r.getBottom(), - r.getWidth(), r.getHeight())); + CGContextClipToRect (context.get(), CGRectMake (r.getX(), flipHeight - r.getBottom(), + r.getWidth(), r.getHeight())); if (lastClipRectIsValid) { @@ -282,7 +277,7 @@ bool CoreGraphicsContext::clipToRectangleListWithoutTest (const RectangleList<in { if (clipRegion.isEmpty()) { - CGContextClipToRect (context, CGRectZero); + CGContextClipToRect (context.get(), CGRectZero); lastClipRectIsValid = true; lastClipRect = Rectangle<int>(); return false; @@ -295,7 +290,7 @@ bool CoreGraphicsContext::clipToRectangleListWithoutTest (const RectangleList<in for (auto& r : clipRegion) rects[i++] = CGRectMake (r.getX(), flipHeight - r.getBottom(), r.getWidth(), r.getHeight()); - CGContextClipToRects (context, rects, numRects); + CGContextClipToRects (context.get(), rects, numRects); lastClipRectIsValid = false; return true; } @@ -317,9 +312,9 @@ void CoreGraphicsContext::clipToPath (const Path& path, const AffineTransform& t createPath (path, transform); if (path.isUsingNonZeroWinding()) - CGContextClip (context); + CGContextClip (context.get()); else - CGContextEOClip (context); + CGContextEOClip (context.get()); lastClipRectIsValid = false; } @@ -333,19 +328,18 @@ void CoreGraphicsContext::clipToImageAlpha (const Image& sourceImage, const Affi if (sourceImage.getFormat() != Image::SingleChannel) singleChannelImage = sourceImage.convertedToFormat (Image::SingleChannel); - CGImageRef image = CoreGraphicsPixelData::createImage (singleChannelImage, greyColourSpace, true); + auto image = detail::ImagePtr { CoreGraphicsPixelData::createImage (singleChannelImage, greyColourSpace.get(), true) }; flip(); auto t = AffineTransform::verticalFlip (sourceImage.getHeight()).followedBy (transform); applyTransform (t); auto r = convertToCGRect (sourceImage.getBounds()); - CGContextClipToMask (context, r, image); + CGContextClipToMask (context.get(), r, image.get()); applyTransform (t.inverted()); flip(); - CGImageRelease (image); lastClipRectIsValid = false; } } @@ -359,7 +353,7 @@ Rectangle<int> CoreGraphicsContext::getClipBounds() const { if (! lastClipRectIsValid) { - auto bounds = CGRectIntegral (CGContextGetClipBoundingBox (context)); + auto bounds = CGRectIntegral (CGContextGetClipBoundingBox (context.get())); lastClipRectIsValid = true; lastClipRect.setBounds (roundToInt (bounds.origin.x), @@ -379,18 +373,18 @@ bool CoreGraphicsContext::isClipEmpty() const //============================================================================== void CoreGraphicsContext::saveState() { - CGContextSaveGState (context); + CGContextSaveGState (context.get()); stateStack.add (new SavedState (*state)); } void CoreGraphicsContext::restoreState() { - CGContextRestoreGState (context); + CGContextRestoreGState (context.get()); if (auto* top = stateStack.getLast()) { state.reset (top); - CGContextSetTextMatrix (context, state->textMatrix); + CGContextSetTextMatrix (context.get(), state->textMatrix); stateStack.removeLast (1, false); lastClipRectIsValid = false; @@ -404,13 +398,13 @@ void CoreGraphicsContext::restoreState() void CoreGraphicsContext::beginTransparencyLayer (float opacity) { saveState(); - CGContextSetAlpha (context, opacity); - CGContextBeginTransparencyLayer (context, nullptr); + CGContextSetAlpha (context.get(), opacity); + CGContextBeginTransparencyLayer (context.get(), nullptr); } void CoreGraphicsContext::endTransparencyLayer() { - CGContextEndTransparencyLayer (context); + CGContextEndTransparencyLayer (context.get()); restoreState(); } @@ -421,9 +415,9 @@ void CoreGraphicsContext::setFill (const FillType& fillType) if (fillType.isColour()) { - CGContextSetRGBFillColor (context, fillType.colour.getFloatRed(), fillType.colour.getFloatGreen(), + CGContextSetRGBFillColor (context.get(), fillType.colour.getFloatRed(), fillType.colour.getFloatGreen(), fillType.colour.getFloatBlue(), fillType.colour.getFloatAlpha()); - CGContextSetAlpha (context, 1.0f); + CGContextSetAlpha (context.get(), 1.0f); } } @@ -437,9 +431,9 @@ void CoreGraphicsContext::setInterpolationQuality (Graphics::ResamplingQuality q { switch (quality) { - case Graphics::lowResamplingQuality: CGContextSetInterpolationQuality (context, kCGInterpolationNone); return; - case Graphics::mediumResamplingQuality: CGContextSetInterpolationQuality (context, kCGInterpolationMedium); return; - case Graphics::highResamplingQuality: CGContextSetInterpolationQuality (context, kCGInterpolationHigh); return; + case Graphics::lowResamplingQuality: CGContextSetInterpolationQuality (context.get(), kCGInterpolationNone); return; + case Graphics::mediumResamplingQuality: CGContextSetInterpolationQuality (context.get(), kCGInterpolationMedium); return; + case Graphics::highResamplingQuality: CGContextSetInterpolationQuality (context.get(), kCGInterpolationHigh); return; default: return; } } @@ -459,36 +453,33 @@ void CoreGraphicsContext::fillCGRect (const CGRect& cgRect, bool replaceExisting { if (replaceExistingContents) { - CGContextSetBlendMode (context, kCGBlendModeCopy); + CGContextSetBlendMode (context.get(), kCGBlendModeCopy); fillCGRect (cgRect, false); - CGContextSetBlendMode (context, kCGBlendModeNormal); + CGContextSetBlendMode (context.get(), kCGBlendModeNormal); } else { if (state->fillType.isColour()) { - CGContextFillRect (context, cgRect); - } - else if (state->fillType.isGradient()) - { - CGContextSaveGState (context); - CGContextClipToRect (context, cgRect); - drawGradient(); - CGContextRestoreGState (context); + CGContextFillRect (context.get(), cgRect); } else { - CGContextSaveGState (context); - CGContextClipToRect (context, cgRect); - drawImage (state->fillType.image, state->fillType.transform, true); - CGContextRestoreGState (context); + ScopedCGContextState scopedState (context.get()); + + CGContextClipToRect (context.get(), cgRect); + + if (state->fillType.isGradient()) + drawGradient(); + else + drawImage (state->fillType.image, state->fillType.transform, true); } } } void CoreGraphicsContext::fillPath (const Path& path, const AffineTransform& transform) { - CGContextSaveGState (context); + ScopedCGContextState scopedState (context.get()); if (state->fillType.isColour()) { @@ -497,26 +488,24 @@ void CoreGraphicsContext::fillPath (const Path& path, const AffineTransform& tra createPath (path); if (path.isUsingNonZeroWinding()) - CGContextFillPath (context); + CGContextFillPath (context.get()); else - CGContextEOFillPath (context); + CGContextEOFillPath (context.get()); } else { createPath (path, transform); if (path.isUsingNonZeroWinding()) - CGContextClip (context); + CGContextClip (context.get()); else - CGContextEOClip (context); + CGContextEOClip (context.get()); if (state->fillType.isGradient()) drawGradient(); else drawImage (state->fillType.image, state->fillType.transform, true); } - - CGContextRestoreGState (context); } void CoreGraphicsContext::drawImage (const Image& sourceImage, const AffineTransform& transform) @@ -529,12 +518,12 @@ void CoreGraphicsContext::drawImage (const Image& sourceImage, const AffineTrans auto iw = sourceImage.getWidth(); auto ih = sourceImage.getHeight(); - auto colourSpace = sourceImage.getFormat() == Image::PixelFormat::SingleChannel ? greyColourSpace - : rgbColourSpace; - CGImageRef image = CoreGraphicsPixelData::getCachedImageRef (sourceImage, colourSpace); + auto colourSpace = sourceImage.getFormat() == Image::PixelFormat::SingleChannel ? greyColourSpace.get() + : rgbColourSpace.get(); + auto image = detail::ImagePtr { CoreGraphicsPixelData::getCachedImageRef (sourceImage, colourSpace) }; - CGContextSaveGState (context); - CGContextSetAlpha (context, state->fillType.getOpacity()); + ScopedCGContextState scopedState (context.get()); + CGContextSetAlpha (context.get(), state->fillType.getOpacity()); flip(); applyTransform (AffineTransform::verticalFlip (ih).followedBy (transform)); @@ -543,18 +532,18 @@ void CoreGraphicsContext::drawImage (const Image& sourceImage, const AffineTrans if (fillEntireClipAsTiles) { #if JUCE_IOS - CGContextDrawTiledImage (context, imageRect, image); + CGContextDrawTiledImage (context.get(), imageRect, image.get()); #else // There's a bug in CGContextDrawTiledImage that makes it incredibly slow // if it's doing a transformation - it's quicker to just draw lots of images manually if (&CGContextDrawTiledImage != nullptr && transform.isOnlyTranslation()) { - CGContextDrawTiledImage (context, imageRect, image); + CGContextDrawTiledImage (context.get(), imageRect, image.get()); } else { // Fallback to manually doing a tiled fill - auto clip = CGRectIntegral (CGContextGetClipBoundingBox (context)); + auto clip = CGRectIntegral (CGContextGetClipBoundingBox (context.get())); int x = 0, y = 0; while (x > clip.origin.x) x -= iw; @@ -566,7 +555,7 @@ void CoreGraphicsContext::drawImage (const Image& sourceImage, const AffineTrans while (y < bottom) { for (int x2 = x; x2 < right; x2 += iw) - CGContextDrawImage (context, CGRectMake (x2, y, iw, ih), image); + CGContextDrawImage (context.get(), CGRectMake (x2, y, iw, ih), image.get()); y += ih; } @@ -575,11 +564,8 @@ void CoreGraphicsContext::drawImage (const Image& sourceImage, const AffineTrans } else { - CGContextDrawImage (context, imageRect, image); + CGContextDrawImage (context.get(), imageRect, image.get()); } - - CGImageRelease (image); // (This causes a memory bug in iOS sim 3.0 - try upgrading to a later version if you hit this) - CGContextRestoreGState (context); } //============================================================================== @@ -601,21 +587,18 @@ void CoreGraphicsContext::fillRectList (const RectangleList<float>& list) if (state->fillType.isColour()) { - CGContextFillRects (context, rects, num); - } - else if (state->fillType.isGradient()) - { - CGContextSaveGState (context); - CGContextClipToRects (context, rects, num); - drawGradient(); - CGContextRestoreGState (context); + CGContextFillRects (context.get(), rects, num); } else { - CGContextSaveGState (context); - CGContextClipToRects (context, rects, num); - drawImage (state->fillType.image, state->fillType.transform, true); - CGContextRestoreGState (context); + ScopedCGContextState scopedState (context.get()); + + CGContextClipToRects (context.get(), rects, num); + + if (state->fillType.isGradient()) + drawGradient(); + else + drawImage (state->fillType.image, state->fillType.transform, true); } } @@ -629,12 +612,12 @@ void CoreGraphicsContext::setFont (const Font& newFont) if (auto osxTypeface = dynamic_cast<OSXTypeface*> (state->font.getTypeface())) { state->fontRef = osxTypeface->fontRef; - CGContextSetFont (context, state->fontRef); - CGContextSetFontSize (context, state->font.getHeight() * osxTypeface->fontHeightToPointsFactor); + CGContextSetFont (context.get(), state->fontRef); + CGContextSetFontSize (context.get(), state->font.getHeight() * osxTypeface->fontHeightToPointsFactor); state->textMatrix = osxTypeface->renderingTransform; state->textMatrix.a *= state->font.getHorizontalScale(); - CGContextSetTextMatrix (context, state->textMatrix); + CGContextSetTextMatrix (context.get(), state->textMatrix); state->inverseTextMatrix = CGAffineTransformInvert (state->textMatrix); } } @@ -649,7 +632,7 @@ void CoreGraphicsContext::drawGlyph (int glyphNumber, const AffineTransform& tra { if (state->fontRef != nullptr && state->fillType.isColour()) { - auto cgTransformIsOnlyTranslation = [](CGAffineTransform t) + auto cgTransformIsOnlyTranslation = [] (CGAffineTransform t) { return t.a == 1.0f && t.d == 1.0f && t.b == 0.0f && t.c == 0.0f; }; @@ -661,24 +644,22 @@ void CoreGraphicsContext::drawGlyph (int glyphNumber, const AffineTransform& tra CGGlyph glyphs[1] = { (CGGlyph) glyphNumber }; CGPoint positions[1] = { { x, flipHeight - roundToInt (y) } }; - CGContextShowGlyphsAtPositions (context, glyphs, positions, 1); + CGContextShowGlyphsAtPositions (context.get(), glyphs, positions, 1); } else { - CGContextSaveGState (context); + ScopedCGContextState scopedState (context.get()); flip(); applyTransform (transform); - CGContextConcatCTM (context, state->inverseTextMatrix); + CGContextConcatCTM (context.get(), state->inverseTextMatrix); auto cgTransform = state->textMatrix; cgTransform.d = -cgTransform.d; - CGContextConcatCTM (context, cgTransform); + CGContextConcatCTM (context.get(), cgTransform); CGGlyph glyphs[1] = { (CGGlyph) glyphNumber }; CGPoint positions[1] = { { 0.0f, 0.0f } }; - CGContextShowGlyphsAtPositions (context, glyphs, positions, 1); - - CGContextRestoreGState (context); + CGContextShowGlyphsAtPositions (context.get(), glyphs, positions, 1); } } else @@ -694,7 +675,7 @@ void CoreGraphicsContext::drawGlyph (int glyphNumber, const AffineTransform& tra bool CoreGraphicsContext::drawTextLayout (const AttributedString& text, const Rectangle<float>& area) { - CoreTextTypeLayout::drawToCGContext (text, area, context, (float) flipHeight); + CoreTextTypeLayout::drawToCGContext (text, area, context.get(), (float) flipHeight); return true; } @@ -706,27 +687,18 @@ CoreGraphicsContext::SavedState::SavedState() CoreGraphicsContext::SavedState::SavedState (const SavedState& other) : fillType (other.fillType), font (other.font), fontRef (other.fontRef), textMatrix (other.textMatrix), inverseTextMatrix (other.inverseTextMatrix), - gradient (other.gradient) + gradient (other.gradient.get()) { if (gradient != nullptr) - CGGradientRetain (gradient); + CGGradientRetain (gradient.get()); } -CoreGraphicsContext::SavedState::~SavedState() -{ - if (gradient != nullptr) - CGGradientRelease (gradient); -} +CoreGraphicsContext::SavedState::~SavedState() = default; void CoreGraphicsContext::SavedState::setFill (const FillType& newFill) { fillType = newFill; - - if (gradient != nullptr) - { - CGGradientRelease (gradient); - gradient = nullptr; - } + gradient = nullptr; } static CGGradientRef createGradient (const ColourGradient& g, CGColorSpaceRef colourSpace) @@ -758,37 +730,37 @@ void CoreGraphicsContext::drawGradient() { flip(); applyTransform (state->fillType.transform); - CGContextSetAlpha (context, state->fillType.getOpacity()); + CGContextSetAlpha (context.get(), state->fillType.getOpacity()); auto& g = *state->fillType.gradient; if (state->gradient == nullptr) - state->gradient = createGradient (g, rgbColourSpace); + state->gradient.reset (createGradient (g, rgbColourSpace.get())); auto p1 = convertToCGPoint (g.point1); auto p2 = convertToCGPoint (g.point2); if (g.isRadial) - CGContextDrawRadialGradient (context, state->gradient, p1, 0, p1, g.point1.getDistanceFrom (g.point2), + CGContextDrawRadialGradient (context.get(), state->gradient.get(), p1, 0, p1, g.point1.getDistanceFrom (g.point2), kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation); else - CGContextDrawLinearGradient (context, state->gradient, p1, p2, + CGContextDrawLinearGradient (context.get(), state->gradient.get(), p1, p2, kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation); } void CoreGraphicsContext::createPath (const Path& path) const { - CGContextBeginPath (context); + CGContextBeginPath (context.get()); for (Path::Iterator i (path); i.next();) { switch (i.elementType) { - case Path::Iterator::startNewSubPath: CGContextMoveToPoint (context, i.x1, i.y1); break; - case Path::Iterator::lineTo: CGContextAddLineToPoint (context, i.x1, i.y1); break; - case Path::Iterator::quadraticTo: CGContextAddQuadCurveToPoint (context, i.x1, i.y1, i.x2, i.y2); break; - case Path::Iterator::cubicTo: CGContextAddCurveToPoint (context, i.x1, i.y1, i.x2, i.y2, i.x3, i.y3); break; - case Path::Iterator::closePath: CGContextClosePath (context); break; + case Path::Iterator::startNewSubPath: CGContextMoveToPoint (context.get(), i.x1, i.y1); break; + case Path::Iterator::lineTo: CGContextAddLineToPoint (context.get(), i.x1, i.y1); break; + case Path::Iterator::quadraticTo: CGContextAddQuadCurveToPoint (context.get(), i.x1, i.y1, i.x2, i.y2); break; + case Path::Iterator::cubicTo: CGContextAddCurveToPoint (context.get(), i.x1, i.y1, i.x2, i.y2, i.x3, i.y3); break; + case Path::Iterator::closePath: CGContextClosePath (context.get()); break; default: jassertfalse; break; } } @@ -796,7 +768,7 @@ void CoreGraphicsContext::createPath (const Path& path) const void CoreGraphicsContext::createPath (const Path& path, const AffineTransform& transform) const { - CGContextBeginPath (context); + CGContextBeginPath (context.get()); for (Path::Iterator i (path); i.next();) { @@ -804,22 +776,22 @@ void CoreGraphicsContext::createPath (const Path& path, const AffineTransform& t { case Path::Iterator::startNewSubPath: transform.transformPoint (i.x1, i.y1); - CGContextMoveToPoint (context, i.x1, flipHeight - i.y1); + CGContextMoveToPoint (context.get(), i.x1, flipHeight - i.y1); break; case Path::Iterator::lineTo: transform.transformPoint (i.x1, i.y1); - CGContextAddLineToPoint (context, i.x1, flipHeight - i.y1); + CGContextAddLineToPoint (context.get(), i.x1, flipHeight - i.y1); break; case Path::Iterator::quadraticTo: transform.transformPoints (i.x1, i.y1, i.x2, i.y2); - CGContextAddQuadCurveToPoint (context, i.x1, flipHeight - i.y1, i.x2, flipHeight - i.y2); + CGContextAddQuadCurveToPoint (context.get(), i.x1, flipHeight - i.y1, i.x2, flipHeight - i.y2); break; case Path::Iterator::cubicTo: transform.transformPoints (i.x1, i.y1, i.x2, i.y2, i.x3, i.y3); - CGContextAddCurveToPoint (context, i.x1, flipHeight - i.y1, i.x2, flipHeight - i.y2, i.x3, flipHeight - i.y3); + CGContextAddCurveToPoint (context.get(), i.x1, flipHeight - i.y1, i.x2, flipHeight - i.y2, i.x3, flipHeight - i.y3); break; case Path::Iterator::closePath: - CGContextClosePath (context); break; + CGContextClosePath (context.get()); break; default: jassertfalse; break; @@ -829,7 +801,7 @@ void CoreGraphicsContext::createPath (const Path& path, const AffineTransform& t void CoreGraphicsContext::flip() const { - CGContextConcatCTM (context, CGAffineTransformMake (1, 0, 0, -1, 0, flipHeight)); + CGContextConcatCTM (context.get(), CGAffineTransformMake (1, 0, 0, -1, 0, flipHeight)); } void CoreGraphicsContext::applyTransform (const AffineTransform& transform) const @@ -841,7 +813,7 @@ void CoreGraphicsContext::applyTransform (const AffineTransform& transform) cons t.d = transform.mat11; t.tx = transform.mat02; t.ty = transform.mat12; - CGContextConcatCTM (context, t); + CGContextConcatCTM (context.get(), t); } //============================================================================== @@ -869,12 +841,11 @@ Image juce_loadWithCoreImage (InputStream& input) CGImageRef loadedImage = uiImage.CGImage; #else - auto provider = CGDataProviderCreateWithData (new MemoryBlockHolder::Ptr (memBlockHolder), - memBlockHolder->block.getData(), - memBlockHolder->block.getSize(), - [] (void * __nullable info, const void*, size_t) { delete (MemoryBlockHolder::Ptr*) info; }); - auto imageSource = CGImageSourceCreateWithDataProvider (provider, nullptr); - CGDataProviderRelease (provider); + auto provider = detail::DataProviderPtr { CGDataProviderCreateWithData (new MemoryBlockHolder::Ptr (memBlockHolder), + memBlockHolder->block.getData(), + memBlockHolder->block.getSize(), + [] (void * __nullable info, const void*, size_t) { delete (MemoryBlockHolder::Ptr*) info; }) }; + auto imageSource = CGImageSourceCreateWithDataProvider (provider.get(), nullptr); if (imageSource != nullptr) { @@ -897,8 +868,8 @@ Image juce_loadWithCoreImage (InputStream& input) auto cgImage = dynamic_cast<CoreGraphicsPixelData*> (image.getPixelData()); jassert (cgImage != nullptr); // if USE_COREGRAPHICS_RENDERING is set, the CoreGraphicsPixelData class should have been used. - CGContextDrawImage (cgImage->context, convertToCGRect (image.getBounds()), loadedImage); - CGContextFlush (cgImage->context); + CGContextDrawImage (cgImage->context.get(), convertToCGRect (image.getBounds()), loadedImage); + CGContextFlush (cgImage->context.get()); #if ! JUCE_IOS CFRelease (loadedImage); @@ -921,9 +892,9 @@ Image juce_createImageFromCIImage (CIImage* im, int w, int h) { auto cgImage = new CoreGraphicsPixelData (Image::ARGB, w, h, false); - CIContext* cic = [CIContext contextWithCGContext: cgImage->context options: nil]; + CIContext* cic = [CIContext contextWithCGContext: cgImage->context.get() options: nil]; [cic drawImage: im inRect: CGRectMake (0, 0, w, h) fromRect: CGRectMake (0, 0, w, h)]; - CGContextFlush (cgImage->context); + CGContextFlush (cgImage->context.get()); return Image (*cgImage); } @@ -937,7 +908,7 @@ CGImageRef juce_createCoreGraphicsImage (const Image& juceImage, CGColorSpaceRef CGContextRef juce_getImageContext (const Image& image) { if (auto cgi = dynamic_cast<CoreGraphicsPixelData*> (image.getPixelData())) - return cgi->context; + return cgi->context.get(); jassertfalse; return {}; @@ -966,15 +937,13 @@ CGContextRef juce_getImageContext (const Image& image) auto requiredSize = NSMakeSize (image.getWidth() / scaleFactor, image.getHeight() / scaleFactor); [im setSize: requiredSize]; - auto colourSpace = CGColorSpaceCreateDeviceRGB(); - auto imageRef = juce_createCoreGraphicsImage (image, colourSpace, true); - CGColorSpaceRelease (colourSpace); + auto colourSpace = detail::ColorSpacePtr { CGColorSpaceCreateWithName (kCGColorSpaceSRGB) }; + auto imageRef = detail::ImagePtr { juce_createCoreGraphicsImage (image, colourSpace.get(), true) }; - NSBitmapImageRep* imageRep = [[NSBitmapImageRep alloc] initWithCGImage: imageRef]; + NSBitmapImageRep* imageRep = [[NSBitmapImageRep alloc] initWithCGImage: imageRef.get()]; [imageRep setSize: requiredSize]; [im addRepresentation: imageRep]; [imageRep release]; - CGImageRelease (imageRef); return im; } } diff --git a/modules/juce_graphics/native/juce_mac_CoreGraphicsHelpers.h b/modules/juce_graphics/native/juce_mac_CoreGraphicsHelpers.h index 5e57a5f9..d4fa0c3c 100644 --- a/modules/juce_graphics/native/juce_mac_CoreGraphicsHelpers.h +++ b/modules/juce_graphics/native/juce_mac_CoreGraphicsHelpers.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/native/juce_mac_Fonts.mm b/modules/juce_graphics/native/juce_mac_Fonts.mm index 12b4e25d..735314b3 100644 --- a/modules/juce_graphics/native/juce_mac_Fonts.mm +++ b/modules/juce_graphics/native/juce_mac_Fonts.mm @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -189,6 +188,7 @@ namespace CoreTextTypeLayout { case AttributedString::none: return kCTLineBreakByClipping; case AttributedString::byChar: return kCTLineBreakByCharWrapping; + case AttributedString::byWord: default: return kCTLineBreakByWordWrapping; } } @@ -199,6 +199,7 @@ namespace CoreTextTypeLayout { case AttributedString::rightToLeft: return kCTWritingDirectionRightToLeft; case AttributedString::leftToRight: return kCTWritingDirectionLeftToRight; + case AttributedString::natural: default: return kCTWritingDirectionNatural; } } @@ -207,7 +208,7 @@ namespace CoreTextTypeLayout static CFAttributedStringRef createCFAttributedString (const AttributedString& text) { #if JUCE_IOS - auto rgbColourSpace = CGColorSpaceCreateDeviceRGB(); + auto rgbColourSpace = CGColorSpaceCreateWithName (kCGColorSpaceSRGB); #endif auto attribString = CFAttributedStringCreateMutable (kCFAllocatorDefault, 0); @@ -233,6 +234,15 @@ namespace CoreTextTypeLayout ctFontRef = getFontWithPointSize (ctFontRef, attr.font.getHeight() * getHeightToPointsFactor (ctFontRef)); CFAttributedStringSetAttribute (attribString, range, kCTFontAttributeName, ctFontRef); + if (attr.font.isUnderlined()) + { + auto underline = kCTUnderlineStyleSingle; + + auto numberRef = CFNumberCreate (nullptr, kCFNumberIntType, &underline); + CFAttributedStringSetAttribute (attribString, range, kCTUnderlineStyleAttributeName, numberRef); + CFRelease (numberRef); + } + auto extraKerning = attr.font.getExtraKerningFactor(); if (extraKerning != 0) @@ -462,6 +472,26 @@ namespace CoreTextTypeLayout String::fromCFString (cfsFontStyle), (float) (CTFontGetSize (ctRunFont) / fontHeightToPointsFactor)); + auto isUnderlined = [&] + { + CFNumberRef underlineStyle; + + if (CFDictionaryGetValueIfPresent (runAttributes, kCTUnderlineStyleAttributeName, (const void**) &underlineStyle)) + { + if (CFGetTypeID (underlineStyle) == CFNumberGetTypeID()) + { + int value = 0; + CFNumberGetValue (underlineStyle, kCFNumberLongType, (void*) &value); + + return value != 0; + } + } + + return false; + }(); + + glyphRun->font.setUnderline (isUnderlined); + CFRelease (cfsFontStyle); CFRelease (cfsFontFamily); } @@ -584,10 +614,24 @@ public: CFRelease (numberRef); } - // The implementation of at least one overridden function needs to be outside - // of the class definition to avoid spurious warning messages when dynamically - // loading libraries at runtime on macOS... - ~OSXTypeface() override; + ~OSXTypeface() override + { + if (attributedStringAtts != nullptr) + CFRelease (attributedStringAtts); + + if (fontRef != nullptr) + { + #if JUCE_MAC && defined (MAC_OS_X_VERSION_10_8) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_8 + if (dataCopy.getSize() != 0) + CTFontManagerUnregisterGraphicsFont (fontRef, nullptr); + #endif + + CGFontRelease (fontRef); + } + + if (ctFontRef != nullptr) + CFRelease (ctFontRef); + } float getAscent() const override { return ascent; } float getDescent() const override { return 1.0f - ascent; } @@ -717,25 +761,6 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OSXTypeface) }; -OSXTypeface::~OSXTypeface() -{ - if (attributedStringAtts != nullptr) - CFRelease (attributedStringAtts); - - if (fontRef != nullptr) - { - #if JUCE_MAC && defined (MAC_OS_X_VERSION_10_8) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_8 - if (dataCopy.getSize() != 0) - CTFontManagerUnregisterGraphicsFont (fontRef, nullptr); - #endif - - CGFontRelease (fontRef); - } - - if (ctFontRef != nullptr) - CFRelease (ctFontRef); -} - CTFontRef getCTFontFromTypeface (const Font& f) { if (auto* tf = dynamic_cast<OSXTypeface*> (f.getTypeface())) diff --git a/modules/juce_graphics/native/juce_mac_IconHelpers.cpp b/modules/juce_graphics/native/juce_mac_IconHelpers.cpp index 5f449253..b90ebb46 100644 --- a/modules/juce_graphics/native/juce_mac_IconHelpers.cpp +++ b/modules/juce_graphics/native/juce_mac_IconHelpers.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/native/juce_win32_Direct2DGraphicsContext.cpp b/modules/juce_graphics/native/juce_win32_Direct2DGraphicsContext.cpp index 3913247b..8ca777b5 100644 --- a/modules/juce_graphics/native/juce_win32_Direct2DGraphicsContext.cpp +++ b/modules/juce_graphics/native/juce_win32_Direct2DGraphicsContext.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -580,7 +579,7 @@ void Direct2DLowLevelGraphicsContext::addTransform (const AffineTransform& trans float Direct2DLowLevelGraphicsContext::getPhysicalPixelScaleFactor() { - return currentState->transform.getScaleFactor(); + return std::sqrt (std::abs (currentState->transform.getDeterminant())); } bool Direct2DLowLevelGraphicsContext::clipToRectangle (const Rectangle<int>& r) diff --git a/modules/juce_graphics/native/juce_win32_Direct2DGraphicsContext.h b/modules/juce_graphics/native/juce_win32_Direct2DGraphicsContext.h index ff39e064..6830621c 100644 --- a/modules/juce_graphics/native/juce_win32_Direct2DGraphicsContext.h +++ b/modules/juce_graphics/native/juce_win32_Direct2DGraphicsContext.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/native/juce_win32_DirectWriteTypeLayout.cpp b/modules/juce_graphics/native/juce_win32_DirectWriteTypeLayout.cpp index cc2b4f8a..2e9875e3 100644 --- a/modules/juce_graphics/native/juce_win32_DirectWriteTypeLayout.cpp +++ b/modules/juce_graphics/native/juce_win32_DirectWriteTypeLayout.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -441,7 +440,10 @@ bool TextLayout::createNativeLayout (const AttributedString& text) SharedResourcePointer<Direct2DFactories> factories; - if (factories->d2dFactory != nullptr && factories->systemFonts != nullptr) + if (factories->d2dFactory != nullptr + && factories->directWriteFactory != nullptr + && factories->systemFonts != nullptr + && factories->directWriteRenderTarget != nullptr) { DirectWriteTypeLayout::createLayout (*this, text, *factories->directWriteFactory, diff --git a/modules/juce_graphics/native/juce_win32_DirectWriteTypeface.cpp b/modules/juce_graphics/native/juce_win32_DirectWriteTypeface.cpp index 7ffea03a..4f1abee9 100644 --- a/modules/juce_graphics/native/juce_win32_DirectWriteTypeface.cpp +++ b/modules/juce_graphics/native/juce_win32_DirectWriteTypeface.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/native/juce_win32_Fonts.cpp b/modules/juce_graphics/native/juce_win32_Fonts.cpp index a2108249..3f95a456 100644 --- a/modules/juce_graphics/native/juce_win32_Fonts.cpp +++ b/modules/juce_graphics/native/juce_win32_Fonts.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -97,12 +96,12 @@ namespace TTFNameExtractor { input.setPosition (directoryOffset); - NamingTable namingTable = { 0 }; + NamingTable namingTable = {}; input.read (&namingTable, sizeof (namingTable)); for (int i = 0; i < (int) ByteOrder::swapIfLittleEndian (namingTable.numberOfNameRecords); ++i) { - NameRecord nameRecord = { 0 }; + NameRecord nameRecord = {}; input.read (&nameRecord, sizeof (nameRecord)); if (ByteOrder::swapIfLittleEndian (nameRecord.nameID) == 4) @@ -120,7 +119,7 @@ namespace TTFNameExtractor static String getTypefaceNameFromFile (MemoryInputStream& input) { - OffsetTable offsetTable = { 0 }; + OffsetTable offsetTable = {}; input.read (&offsetTable, sizeof (offsetTable)); for (int i = 0; i < (int) ByteOrder::swapIfLittleEndian (offsetTable.numTables); ++i) @@ -154,7 +153,7 @@ namespace FontEnumerators { if (lpelfe != nullptr && (type & RASTER_FONTTYPE) == 0) { - LOGFONTW lf = { 0 }; + LOGFONTW lf = {}; lf.lfWeight = FW_DONTCARE; lf.lfOutPrecision = OUT_OUTLINE_PRECIS; lf.lfQuality = DEFAULT_QUALITY; @@ -165,7 +164,7 @@ namespace FontEnumerators const String fontName (lpelfe->elfLogFont.lfFaceName); fontName.copyToUTF16 (lf.lfFaceName, sizeof (lf.lfFaceName)); - auto dc = CreateCompatibleDC (0); + auto dc = CreateCompatibleDC (nullptr); EnumFontFamiliesEx (dc, &lf, (FONTENUMPROCW) &fontEnum2, lParam, 0); DeleteDC (dc); } @@ -198,10 +197,10 @@ StringArray Font::findAllTypefaceNames() else #endif { - auto dc = CreateCompatibleDC (0); + auto dc = CreateCompatibleDC (nullptr); { - LOGFONTW lf = { 0 }; + LOGFONTW lf = {}; lf.lfWeight = FW_DONTCARE; lf.lfOutPrecision = OUT_OUTLINE_PRECIS; lf.lfQuality = DEFAULT_QUALITY; @@ -340,10 +339,10 @@ public: SelectObject (dc, previousFontH); // Replacing the previous font before deleting the DC avoids a warning in BoundsChecker DeleteDC (dc); - if (fontH != 0) + if (fontH != nullptr) DeleteObject (fontH); - if (memoryFont != 0) + if (memoryFont != nullptr) RemoveFontMemResourceEx (memoryFont); } @@ -400,13 +399,13 @@ public: GLYPHMETRICS gm; // (although GetGlyphOutline returns a DWORD, it may be -1 on failure, so treat it as signed int..) auto bufSize = (int) GetGlyphOutline (dc, (UINT) glyphNumber, GGO_NATIVE | GGO_GLYPH_INDEX, - &gm, 0, 0, &identityMatrix); + &gm, 0, nullptr, &identityMatrix); if (bufSize > 0) { HeapBlock<char> data (bufSize); GetGlyphOutline (dc, (UINT) glyphNumber, GGO_NATIVE | GGO_GLYPH_INDEX, &gm, - bufSize, data, &identityMatrix); + (DWORD) bufSize, data, &identityMatrix); auto pheader = reinterpret_cast<const TTPOLYGONHEADER*> (data.getData()); @@ -464,7 +463,7 @@ private: static const MAT2 identityMatrix; HFONT fontH = {}; HGDIOBJ previousFontH = {}; - HDC dc { CreateCompatibleDC (0) }; + HDC dc { CreateCompatibleDC (nullptr) }; TEXTMETRIC tm; HANDLE memoryFont = {}; float ascent = 1.0f, heightToPointsFactor = 1.0f; @@ -481,7 +480,7 @@ private: SetMapperFlags (dc, 0); SetMapMode (dc, MM_TEXT); - LOGFONTW lf = { 0 }; + LOGFONTW lf = {}; lf.lfCharSet = DEFAULT_CHARSET; lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; lf.lfOutPrecision = OUT_OUTLINE_PRECIS; @@ -494,17 +493,17 @@ private: auto standardSizedFont = CreateFontIndirect (&lf); - if (standardSizedFont != 0) + if (standardSizedFont != nullptr) { - if ((previousFontH = SelectObject (dc, standardSizedFont)) != 0) + if ((previousFontH = SelectObject (dc, standardSizedFont)) != nullptr) { fontH = standardSizedFont; OUTLINETEXTMETRIC otm; if (GetOutlineTextMetrics (dc, sizeof (otm), &otm) != 0) { - heightInPoints = otm.otmEMSquare; - lf.lfHeight = -(int) heightInPoints; + heightInPoints = (int) otm.otmEMSquare; + lf.lfHeight = -heightInPoints; fontH = CreateFontIndirect (&lf); SelectObject (dc, fontH); @@ -527,7 +526,7 @@ private: void createKerningPairs (HDC hdc, std::unordered_map<int, int>& glyphsForChars, float height) { HeapBlock<KERNINGPAIR> rawKerning; - auto numKPs = GetKerningPairs (hdc, 0, 0); + auto numKPs = GetKerningPairs (hdc, 0, nullptr); rawKerning.calloc (numKPs); GetKerningPairs (hdc, numKPs, rawKerning); @@ -578,7 +577,7 @@ private: { GLYPHMETRICS gm; gm.gmCellIncX = 0; - GetGlyphOutline (dc, (UINT) glyphNumber, GGO_NATIVE | GGO_GLYPH_INDEX, &gm, 0, 0, &identityMatrix); + GetGlyphOutline (dc, (UINT) glyphNumber, GGO_NATIVE | GGO_GLYPH_INDEX, &gm, 0, nullptr, &identityMatrix); return gm.gmCellIncX; } diff --git a/modules/juce_graphics/native/juce_win32_IconHelpers.cpp b/modules/juce_graphics/native/juce_win32_IconHelpers.cpp index 3a11f8e3..b89815dd 100644 --- a/modules/juce_graphics/native/juce_win32_IconHelpers.cpp +++ b/modules/juce_graphics/native/juce_win32_IconHelpers.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/placement/juce_Justification.h b/modules/juce_graphics/placement/juce_Justification.h index cd4a143d..3e223633 100644 --- a/modules/juce_graphics/placement/juce_Justification.h +++ b/modules/juce_graphics/placement/juce_Justification.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/placement/juce_RectanglePlacement.cpp b/modules/juce_graphics/placement/juce_RectanglePlacement.cpp index 05bcc806..8652727a 100644 --- a/modules/juce_graphics/placement/juce_RectanglePlacement.cpp +++ b/modules/juce_graphics/placement/juce_RectanglePlacement.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_graphics/placement/juce_RectanglePlacement.h b/modules/juce_graphics/placement/juce_RectanglePlacement.h index 16ab8f30..bdb1b088 100644 --- a/modules/juce_graphics/placement/juce_RectanglePlacement.h +++ b/modules/juce_graphics/placement/juce_RectanglePlacement.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/application/juce_Application.cpp b/modules/juce_gui_basics/application/juce_Application.cpp index efa5242b..88eb39cd 100644 --- a/modules/juce_gui_basics/application/juce_Application.cpp +++ b/modules/juce_gui_basics/application/juce_Application.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/application/juce_Application.h b/modules/juce_gui_basics/application/juce_Application.h index ca95913d..b2fb7ccf 100644 --- a/modules/juce_gui_basics/application/juce_Application.h +++ b/modules/juce_gui_basics/application/juce_Application.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -128,7 +127,7 @@ public: permitted to run (except on OSX where the OS automatically stops you launching a second instance of an app without explicitly starting it from the command-line). - If it's false, the second instance won't start, but it you will still get a + If it's false, the second instance won't start, but you will still get a callback to anotherInstanceStarted() to tell you about this - which gives you a chance to react to what the user was trying to do. */ diff --git a/modules/juce_gui_basics/buttons/juce_ArrowButton.cpp b/modules/juce_gui_basics/buttons/juce_ArrowButton.cpp index cbf72036..81463ed4 100644 --- a/modules/juce_gui_basics/buttons/juce_ArrowButton.cpp +++ b/modules/juce_gui_basics/buttons/juce_ArrowButton.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -41,7 +40,7 @@ void ArrowButton::paintButton (Graphics& g, bool /*shouldDrawButtonAsHighlighted Path p (path); const float offset = shouldDrawButtonAsDown ? 1.0f : 0.0f; - p.applyTransform (path.getTransformToScaleToFit (offset, offset, getWidth() - 3.0f, getHeight() - 3.0f, false)); + p.applyTransform (path.getTransformToScaleToFit (offset, offset, (float) getWidth() - 3.0f, (float) getHeight() - 3.0f, false)); DropShadow (Colours::black.withAlpha (0.3f), shouldDrawButtonAsDown ? 2 : 4, Point<int>()).drawForPath (g, p); diff --git a/modules/juce_gui_basics/buttons/juce_ArrowButton.h b/modules/juce_gui_basics/buttons/juce_ArrowButton.h index c7b1f488..3c40d1c6 100644 --- a/modules/juce_gui_basics/buttons/juce_ArrowButton.h +++ b/modules/juce_gui_basics/buttons/juce_ArrowButton.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/buttons/juce_Button.cpp b/modules/juce_gui_basics/buttons/juce_Button.cpp index 0cd942d0..1df2d6e2 100644 --- a/modules/juce_gui_basics/buttons/juce_Button.cpp +++ b/modules/juce_gui_basics/buttons/juce_Button.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/buttons/juce_Button.h b/modules/juce_gui_basics/buttons/juce_Button.h index 6e2e99ed..34107600 100644 --- a/modules/juce_gui_basics/buttons/juce_Button.h +++ b/modules/juce_gui_basics/buttons/juce_Button.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/buttons/juce_DrawableButton.cpp b/modules/juce_gui_basics/buttons/juce_DrawableButton.cpp index 44b5f1ba..5fb3925a 100644 --- a/modules/juce_gui_basics/buttons/juce_DrawableButton.cpp +++ b/modules/juce_gui_basics/buttons/juce_DrawableButton.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/buttons/juce_DrawableButton.h b/modules/juce_gui_basics/buttons/juce_DrawableButton.h index b8bf21b9..db9f0901 100644 --- a/modules/juce_gui_basics/buttons/juce_DrawableButton.h +++ b/modules/juce_gui_basics/buttons/juce_DrawableButton.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/buttons/juce_HyperlinkButton.cpp b/modules/juce_gui_basics/buttons/juce_HyperlinkButton.cpp index 562bbb5f..81664b2d 100644 --- a/modules/juce_gui_basics/buttons/juce_HyperlinkButton.cpp +++ b/modules/juce_gui_basics/buttons/juce_HyperlinkButton.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -72,7 +71,7 @@ void HyperlinkButton::setURL (const URL& newURL) noexcept Font HyperlinkButton::getFontToUse() const { if (resizeFont) - return font.withHeight (getHeight() * 0.7f); + return font.withHeight ((float) getHeight() * 0.7f); return font; } diff --git a/modules/juce_gui_basics/buttons/juce_HyperlinkButton.h b/modules/juce_gui_basics/buttons/juce_HyperlinkButton.h index f0ecb696..ab10af19 100644 --- a/modules/juce_gui_basics/buttons/juce_HyperlinkButton.h +++ b/modules/juce_gui_basics/buttons/juce_HyperlinkButton.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/buttons/juce_ImageButton.cpp b/modules/juce_gui_basics/buttons/juce_ImageButton.cpp index 46e47c4b..f3fac83d 100644 --- a/modules/juce_gui_basics/buttons/juce_ImageButton.cpp +++ b/modules/juce_gui_basics/buttons/juce_ImageButton.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -134,18 +133,18 @@ void ImageButton::paintButton (Graphics& g, if (preserveProportions) { int newW, newH; - const float imRatio = ih / (float) iw; - const float destRatio = h / (float) w; + const float imRatio = (float) ih / (float) iw; + const float destRatio = (float) h / (float) w; if (imRatio > destRatio) { - newW = roundToInt (h / imRatio); + newW = roundToInt ((float) h / imRatio); newH = h; } else { newW = w; - newH = roundToInt (w * imRatio); + newH = roundToInt ((float) w * imRatio); } x = (w - newW) / 2; diff --git a/modules/juce_gui_basics/buttons/juce_ImageButton.h b/modules/juce_gui_basics/buttons/juce_ImageButton.h index d2565851..ab20fd9f 100644 --- a/modules/juce_gui_basics/buttons/juce_ImageButton.h +++ b/modules/juce_gui_basics/buttons/juce_ImageButton.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/buttons/juce_ShapeButton.cpp b/modules/juce_gui_basics/buttons/juce_ShapeButton.cpp index 115d3d0a..31454463 100644 --- a/modules/juce_gui_basics/buttons/juce_ShapeButton.cpp +++ b/modules/juce_gui_basics/buttons/juce_ShapeButton.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/buttons/juce_ShapeButton.h b/modules/juce_gui_basics/buttons/juce_ShapeButton.h index 609df7b5..6863b1ca 100644 --- a/modules/juce_gui_basics/buttons/juce_ShapeButton.h +++ b/modules/juce_gui_basics/buttons/juce_ShapeButton.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/buttons/juce_TextButton.cpp b/modules/juce_gui_basics/buttons/juce_TextButton.cpp index 79de98e8..70427b52 100644 --- a/modules/juce_gui_basics/buttons/juce_TextButton.cpp +++ b/modules/juce_gui_basics/buttons/juce_TextButton.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/buttons/juce_TextButton.h b/modules/juce_gui_basics/buttons/juce_TextButton.h index 98ca4be7..5ae1cffe 100644 --- a/modules/juce_gui_basics/buttons/juce_TextButton.h +++ b/modules/juce_gui_basics/buttons/juce_TextButton.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/buttons/juce_ToggleButton.cpp b/modules/juce_gui_basics/buttons/juce_ToggleButton.cpp index 35052031..0c556c4e 100644 --- a/modules/juce_gui_basics/buttons/juce_ToggleButton.cpp +++ b/modules/juce_gui_basics/buttons/juce_ToggleButton.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/buttons/juce_ToggleButton.h b/modules/juce_gui_basics/buttons/juce_ToggleButton.h index 3282a64a..3f27376b 100644 --- a/modules/juce_gui_basics/buttons/juce_ToggleButton.h +++ b/modules/juce_gui_basics/buttons/juce_ToggleButton.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/buttons/juce_ToolbarButton.cpp b/modules/juce_gui_basics/buttons/juce_ToolbarButton.cpp index c5e3765d..3f44add3 100644 --- a/modules/juce_gui_basics/buttons/juce_ToolbarButton.cpp +++ b/modules/juce_gui_basics/buttons/juce_ToolbarButton.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/buttons/juce_ToolbarButton.h b/modules/juce_gui_basics/buttons/juce_ToolbarButton.h index f527811b..cc300637 100644 --- a/modules/juce_gui_basics/buttons/juce_ToolbarButton.h +++ b/modules/juce_gui_basics/buttons/juce_ToolbarButton.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/commands/juce_ApplicationCommandID.h b/modules/juce_gui_basics/commands/juce_ApplicationCommandID.h index 85ae5060..639b87a1 100644 --- a/modules/juce_gui_basics/commands/juce_ApplicationCommandID.h +++ b/modules/juce_gui_basics/commands/juce_ApplicationCommandID.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/commands/juce_ApplicationCommandInfo.cpp b/modules/juce_gui_basics/commands/juce_ApplicationCommandInfo.cpp index 6599fdd9..13202350 100644 --- a/modules/juce_gui_basics/commands/juce_ApplicationCommandInfo.cpp +++ b/modules/juce_gui_basics/commands/juce_ApplicationCommandInfo.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/commands/juce_ApplicationCommandInfo.h b/modules/juce_gui_basics/commands/juce_ApplicationCommandInfo.h index 0076a6db..a1ef6929 100644 --- a/modules/juce_gui_basics/commands/juce_ApplicationCommandInfo.h +++ b/modules/juce_gui_basics/commands/juce_ApplicationCommandInfo.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/commands/juce_ApplicationCommandManager.cpp b/modules/juce_gui_basics/commands/juce_ApplicationCommandManager.cpp index 9e3aa868..4940e52a 100644 --- a/modules/juce_gui_basics/commands/juce_ApplicationCommandManager.cpp +++ b/modules/juce_gui_basics/commands/juce_ApplicationCommandManager.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/commands/juce_ApplicationCommandManager.h b/modules/juce_gui_basics/commands/juce_ApplicationCommandManager.h index 3e8d27a7..0965e3d5 100644 --- a/modules/juce_gui_basics/commands/juce_ApplicationCommandManager.h +++ b/modules/juce_gui_basics/commands/juce_ApplicationCommandManager.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.cpp b/modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.cpp index c074dfc7..c89056ba 100644 --- a/modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.cpp +++ b/modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.h b/modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.h index 1de76209..5544b627 100644 --- a/modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.h +++ b/modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/commands/juce_KeyPressMappingSet.cpp b/modules/juce_gui_basics/commands/juce_KeyPressMappingSet.cpp index de6852e8..cebdfe80 100644 --- a/modules/juce_gui_basics/commands/juce_KeyPressMappingSet.cpp +++ b/modules/juce_gui_basics/commands/juce_KeyPressMappingSet.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/commands/juce_KeyPressMappingSet.h b/modules/juce_gui_basics/commands/juce_KeyPressMappingSet.h index ff813ae0..bb46a66c 100644 --- a/modules/juce_gui_basics/commands/juce_KeyPressMappingSet.h +++ b/modules/juce_gui_basics/commands/juce_KeyPressMappingSet.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -194,8 +193,6 @@ public: This will produce a lump of XML that can be later reloaded using restoreFromXml() to recreate the current mapping state. - The object that is returned must be deleted by the caller. - @param saveDifferencesFromDefaultSet if this is false, then all keypresses will be saved into the XML. If it's true, then the XML will only store the differences between the current mappings and diff --git a/modules/juce_gui_basics/components/juce_CachedComponentImage.h b/modules/juce_gui_basics/components/juce_CachedComponentImage.h index 2a19691b..09910be0 100644 --- a/modules/juce_gui_basics/components/juce_CachedComponentImage.h +++ b/modules/juce_gui_basics/components/juce_CachedComponentImage.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/components/juce_Component.cpp b/modules/juce_gui_basics/components/juce_Component.cpp index d7734de4..48f81603 100644 --- a/modules/juce_gui_basics/components/juce_Component.cpp +++ b/modules/juce_gui_basics/components/juce_Component.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -203,18 +202,34 @@ struct ScalingHelpers // judder when moving windows static Rectangle<int> unscaledScreenPosToScaled (float scale, Rectangle<int> pos) noexcept { - return scale != 1.0f ? Rectangle<int> (roundToInt (pos.getX() / scale), - roundToInt (pos.getY() / scale), - roundToInt (pos.getWidth() / scale), - roundToInt (pos.getHeight() / scale)) : pos; + return scale != 1.0f ? Rectangle<int> (roundToInt ((float) pos.getX() / scale), + roundToInt ((float) pos.getY() / scale), + roundToInt ((float) pos.getWidth() / scale), + roundToInt ((float) pos.getHeight() / scale)) : pos; } static Rectangle<int> scaledScreenPosToUnscaled (float scale, Rectangle<int> pos) noexcept { - return scale != 1.0f ? Rectangle<int> (roundToInt (pos.getX() * scale), - roundToInt (pos.getY() * scale), - roundToInt (pos.getWidth() * scale), - roundToInt (pos.getHeight() * scale)) : pos; + return scale != 1.0f ? Rectangle<int> (roundToInt ((float) pos.getX() * scale), + roundToInt ((float) pos.getY() * scale), + roundToInt ((float) pos.getWidth() * scale), + roundToInt ((float) pos.getHeight() * scale)) : pos; + } + + static Rectangle<float> unscaledScreenPosToScaled (float scale, Rectangle<float> pos) noexcept + { + return scale != 1.0f ? Rectangle<float> (pos.getX() / scale, + pos.getY() / scale, + pos.getWidth() / scale, + pos.getHeight() / scale) : pos; + } + + static Rectangle<float> scaledScreenPosToUnscaled (float scale, Rectangle<float> pos) noexcept + { + return scale != 1.0f ? Rectangle<float> (pos.getX() * scale, + pos.getY() * scale, + pos.getWidth() * scale, + pos.getHeight() * scale) : pos; } template <typename PointOrRect> @@ -286,7 +301,7 @@ struct Component::ComponentHelpers } //============================================================================== - static inline bool hitTest (Component& comp, Point<int> localPoint) + static bool hitTest (Component& comp, Point<int> localPoint) { return isPositiveAndBelow (localPoint.x, comp.getWidth()) && isPositiveAndBelow (localPoint.y, comp.getHeight()) @@ -437,7 +452,7 @@ struct Component::ComponentHelpers if (auto* p = comp.getParentComponent()) return p->getLocalBounds(); - return Desktop::getInstance().getDisplays().getMainDisplay().userArea; + return Desktop::getInstance().getDisplays().getPrimaryDisplay()->userArea; } static void releaseAllCachedImageResources (Component& c) @@ -767,7 +782,7 @@ bool Component::isOpaque() const noexcept //============================================================================== struct StandardCachedComponentImage : public CachedComponentImage { - StandardCachedComponentImage (Component& c) noexcept : owner (c), scale (1.0f) {} + StandardCachedComponentImage (Component& c) noexcept : owner (c) {} void paint (Graphics& g) override { @@ -809,8 +824,8 @@ struct StandardCachedComponentImage : public CachedComponentImage validArea = compBounds; g.setColour (Colours::black.withAlpha (owner.getAlpha())); - g.drawImageTransformed (image, AffineTransform::scale (compBounds.getWidth() / (float) imageBounds.getWidth(), - compBounds.getHeight() / (float) imageBounds.getHeight()), false); + g.drawImageTransformed (image, AffineTransform::scale ((float) compBounds.getWidth() / (float) imageBounds.getWidth(), + (float) compBounds.getHeight() / (float) imageBounds.getHeight()), false); } bool invalidateAll() override { validArea.clear(); return true; } @@ -821,7 +836,7 @@ private: Image image; RectangleList<int> validArea; Component& owner; - float scale; + float scale = 1.0f; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (StandardCachedComponentImage) }; @@ -1027,8 +1042,8 @@ bool Component::isAlwaysOnTop() const noexcept } //============================================================================== -int Component::proportionOfWidth (float proportion) const noexcept { return roundToInt (proportion * boundsRelativeToParent.getWidth()); } -int Component::proportionOfHeight (float proportion) const noexcept { return roundToInt (proportion * boundsRelativeToParent.getHeight()); } +int Component::proportionOfWidth (float proportion) const noexcept { return roundToInt (proportion * (float) boundsRelativeToParent.getWidth()); } +int Component::proportionOfHeight (float proportion) const noexcept { return roundToInt (proportion * (float) boundsRelativeToParent.getHeight()); } int Component::getParentWidth() const noexcept { @@ -1044,7 +1059,7 @@ int Component::getParentHeight() const noexcept Rectangle<int> Component::getParentMonitorArea() const { - return Desktop::getInstance().getDisplays().findDisplayForRect (getScreenBounds()).userArea; + return Desktop::getInstance().getDisplays().getDisplayForRect (getScreenBounds())->userArea; } int Component::getScreenX() const { return getScreenPosition().x; } @@ -1052,13 +1067,15 @@ int Component::getScreenY() const { return getScreenPositi Point<int> Component::getScreenPosition() const { return localPointToGlobal (Point<int>()); } Rectangle<int> Component::getScreenBounds() const { return localAreaToGlobal (getLocalBounds()); } -Point<int> Component::getLocalPoint (const Component* source, Point<int> point) const { return ComponentHelpers::convertCoordinate (this, source, point); } -Point<float> Component::getLocalPoint (const Component* source, Point<float> point) const { return ComponentHelpers::convertCoordinate (this, source, point); } -Rectangle<int> Component::getLocalArea (const Component* source, Rectangle<int> area) const { return ComponentHelpers::convertCoordinate (this, source, area); } +Point<int> Component::getLocalPoint (const Component* source, Point<int> point) const { return ComponentHelpers::convertCoordinate (this, source, point); } +Point<float> Component::getLocalPoint (const Component* source, Point<float> point) const { return ComponentHelpers::convertCoordinate (this, source, point); } +Rectangle<int> Component::getLocalArea (const Component* source, Rectangle<int> area) const { return ComponentHelpers::convertCoordinate (this, source, area); } +Rectangle<float> Component::getLocalArea (const Component* source, Rectangle<float> area) const { return ComponentHelpers::convertCoordinate (this, source, area); } -Point<int> Component::localPointToGlobal (Point<int> point) const { return ComponentHelpers::convertCoordinate (nullptr, this, point); } -Point<float> Component::localPointToGlobal (Point<float> point) const { return ComponentHelpers::convertCoordinate (nullptr, this, point); } -Rectangle<int> Component::localAreaToGlobal (Rectangle<int> area) const { return ComponentHelpers::convertCoordinate (nullptr, this, area); } +Point<int> Component::localPointToGlobal (Point<int> point) const { return ComponentHelpers::convertCoordinate (nullptr, this, point); } +Point<float> Component::localPointToGlobal (Point<float> point) const { return ComponentHelpers::convertCoordinate (nullptr, this, point); } +Rectangle<int> Component::localAreaToGlobal (Rectangle<int> area) const { return ComponentHelpers::convertCoordinate (nullptr, this, area); } +Rectangle<float> Component::localAreaToGlobal (Rectangle<float> area) const { return ComponentHelpers::convertCoordinate (nullptr, this, area); } //============================================================================== void Component::setBounds (int x, int y, int w, int h) @@ -1180,8 +1197,8 @@ void Component::setCentrePosition (int x, int y) { setCentrePosition ({ x void Component::setCentreRelative (float x, float y) { - setCentrePosition (roundToInt (getParentWidth() * x), - roundToInt (getParentHeight() * y)); + setCentrePosition (roundToInt ((float) getParentWidth() * x), + roundToInt ((float) getParentHeight() * y)); } void Component::setBoundsRelative (Rectangle<float> target) @@ -1300,7 +1317,8 @@ float Component::getApproximateScaleFactorForComponent (Component* targetCompone transform = transform.scaled (target->getDesktopScaleFactor()); } - return (transform.getScaleFactor() / Desktop::getInstance().getGlobalScaleFactor()); + auto transformScale = std::sqrt (std::abs (transform.getDeterminant())); + return transformScale / Desktop::getInstance().getGlobalScaleFactor(); } //============================================================================== @@ -1854,8 +1872,8 @@ void Component::internalRepaintUnchecked (Rectangle<int> area, bool isEntireComp { // Tweak the scaling so that the component's integer size exactly aligns with the peer's scaled size auto peerBounds = peer->getBounds(); - auto scaled = area * Point<float> (peerBounds.getWidth() / (float) getWidth(), - peerBounds.getHeight() / (float) getHeight()); + auto scaled = area * Point<float> ((float) peerBounds.getWidth() / (float) getWidth(), + (float) peerBounds.getHeight() / (float) getHeight()); peer->repaint (affineTransform != nullptr ? scaled.transformedBy (*affineTransform) : scaled); } @@ -1981,8 +1999,8 @@ void Component::paintEntireComponent (Graphics& g, bool ignoreAlphaLevel) scaledBounds.getWidth(), scaledBounds.getHeight(), ! flags.opaqueFlag); { Graphics g2 (effectImage); - g2.addTransform (AffineTransform::scale (scaledBounds.getWidth() / (float) getWidth(), - scaledBounds.getHeight() / (float) getHeight())); + g2.addTransform (AffineTransform::scale ((float) scaledBounds.getWidth() / (float) getWidth(), + (float) scaledBounds.getHeight() / (float) getHeight())); paintComponentAndChildren (g2); } @@ -2032,16 +2050,16 @@ Image Component::createComponentSnapshot (Rectangle<int> areaToGrab, if (r.isEmpty()) return {}; - auto w = roundToInt (scaleFactor * r.getWidth()); - auto h = roundToInt (scaleFactor * r.getHeight()); + auto w = roundToInt (scaleFactor * (float) r.getWidth()); + auto h = roundToInt (scaleFactor * (float) r.getHeight()); Image image (flags.opaqueFlag ? Image::RGB : Image::ARGB, w, h, true); Graphics g (image); if (w != getWidth() || h != getHeight()) - g.addTransform (AffineTransform::scale (w / (float) r.getWidth(), - h / (float) r.getHeight())); + g.addTransform (AffineTransform::scale ((float) w / (float) r.getWidth(), + (float) h / (float) r.getHeight())); g.setOrigin (-r.getPosition()); paintEntireComponent (g, true); diff --git a/modules/juce_gui_basics/components/juce_Component.h b/modules/juce_gui_basics/components/juce_Component.h index 72d82cf0..5dbeb7a0 100644 --- a/modules/juce_gui_basics/components/juce_Component.h +++ b/modules/juce_gui_basics/components/juce_Component.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -370,6 +369,19 @@ public: Rectangle<int> getLocalArea (const Component* sourceComponent, Rectangle<int> areaRelativeToSourceComponent) const; + /** Converts a rectangle to be relative to this component's coordinate space. + + This takes a rectangle that is relative to a different component, and returns its position relative + to this component. If the sourceComponent parameter is null, the source rectangle is assumed to be + a screen coordinate. + + If you've used setTransform() to apply one or more transforms to components, then the source rectangle + may not actually be rectangular when converted to the target space, so in that situation this will return + the smallest rectangle that fully contains the transformed area. + */ + Rectangle<float> getLocalArea (const Component* sourceComponent, + Rectangle<float> areaRelativeToSourceComponent) const; + /** Converts a point relative to this component's top-left into a screen coordinate. @see getLocalPoint, localAreaToGlobal */ @@ -389,6 +401,15 @@ public: */ Rectangle<int> localAreaToGlobal (Rectangle<int> localArea) const; + /** Converts a rectangle from this component's coordinate space to a screen coordinate. + + If you've used setTransform() to apply one or more transforms to components, then the source rectangle + may not actually be rectangular when converted to the target space, so in that situation this will return + the smallest rectangle that fully contains the transformed area. + @see getLocalPoint, localPointToGlobal + */ + Rectangle<float> localAreaToGlobal (Rectangle<float> localArea) const; + //============================================================================== /** Moves the component to a new position. diff --git a/modules/juce_gui_basics/components/juce_ComponentListener.cpp b/modules/juce_gui_basics/components/juce_ComponentListener.cpp index 55a56233..479937d3 100644 --- a/modules/juce_gui_basics/components/juce_ComponentListener.cpp +++ b/modules/juce_gui_basics/components/juce_ComponentListener.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/components/juce_ComponentListener.h b/modules/juce_gui_basics/components/juce_ComponentListener.h index b9da77f0..da8e5654 100644 --- a/modules/juce_gui_basics/components/juce_ComponentListener.h +++ b/modules/juce_gui_basics/components/juce_ComponentListener.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/components/juce_ModalComponentManager.cpp b/modules/juce_gui_basics/components/juce_ModalComponentManager.cpp index 4b1eee70..ce106bba 100644 --- a/modules/juce_gui_basics/components/juce_ModalComponentManager.cpp +++ b/modules/juce_gui_basics/components/juce_ModalComponentManager.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -287,7 +286,7 @@ int ModalComponentManager::runEventLoopForCurrentComponent() //============================================================================== struct LambdaCallback : public ModalComponentManager::Callback { - LambdaCallback (std::function<void(int)> fn) noexcept : function (fn) {} + LambdaCallback (std::function<void (int)> fn) noexcept : function (fn) {} void modalStateFinished (int result) override { @@ -295,12 +294,12 @@ struct LambdaCallback : public ModalComponentManager::Callback function (result); } - std::function<void(int)> function; + std::function<void (int)> function; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LambdaCallback) }; -ModalComponentManager::Callback* ModalCallbackFunction::create (std::function<void(int)> f) +ModalComponentManager::Callback* ModalCallbackFunction::create (std::function<void (int)> f) { return new LambdaCallback (f); } diff --git a/modules/juce_gui_basics/components/juce_ModalComponentManager.h b/modules/juce_gui_basics/components/juce_ModalComponentManager.h index cb9c3bcd..996c5754 100644 --- a/modules/juce_gui_basics/components/juce_ModalComponentManager.h +++ b/modules/juce_gui_basics/components/juce_ModalComponentManager.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -170,7 +169,7 @@ public: @see ModalComponentManager::Callback */ - static ModalComponentManager::Callback* create (std::function<void(int)>); + static ModalComponentManager::Callback* create (std::function<void (int)>); //============================================================================== /** This is a utility function to create a ModalComponentManager::Callback that will diff --git a/modules/juce_gui_basics/desktop/juce_Desktop.cpp b/modules/juce_gui_basics/desktop/juce_Desktop.cpp index 3cfb54e6..047bf1b1 100644 --- a/modules/juce_gui_basics/desktop/juce_Desktop.cpp +++ b/modules/juce_gui_basics/desktop/juce_Desktop.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -332,4 +331,9 @@ void Desktop::setGlobalScaleFactor (float newScaleFactor) noexcept } } +bool Desktop::isHeadless() const noexcept +{ + return displays->displays.isEmpty(); +} + } // namespace juce diff --git a/modules/juce_gui_basics/desktop/juce_Desktop.h b/modules/juce_gui_basics/desktop/juce_Desktop.h index 41b375e1..895fd546 100644 --- a/modules/juce_gui_basics/desktop/juce_Desktop.h +++ b/modules/juce_gui_basics/desktop/juce_Desktop.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -326,6 +325,10 @@ public: bool isOrientationEnabled (DisplayOrientation orientation) const noexcept; //============================================================================== + /** Returns the Displays object representing the connected displays. + + @see Displays + */ const Displays& getDisplays() const noexcept { return *displays; } //============================================================================== @@ -348,6 +351,10 @@ public: static bool isOSXDarkModeActive(); #endif + //============================================================================== + /** Returns true on a headless system where there are no connected displays. */ + bool isHeadless() const noexcept; + private: //============================================================================== static Desktop* instance; diff --git a/modules/juce_gui_basics/desktop/juce_Displays.cpp b/modules/juce_gui_basics/desktop/juce_Displays.cpp index ad226c4f..5bc47848 100644 --- a/modules/juce_gui_basics/desktop/juce_Displays.cpp +++ b/modules/juce_gui_basics/desktop/juce_Displays.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -37,10 +36,10 @@ void Displays::init (Desktop& desktop) findDisplays (desktop.getGlobalScaleFactor()); } -const Displays::Display& Displays::findDisplayForRect (Rectangle<int> rect, bool isPhysical) const noexcept +const Displays::Display* Displays::getDisplayForRect (Rectangle<int> rect, bool isPhysical) const noexcept { int maxArea = -1; - const Display* retVal = nullptr; + const Display* foundDisplay = nullptr; for (auto& display : displays) { @@ -55,17 +54,17 @@ const Displays::Display& Displays::findDisplayForRect (Rectangle<int> rect, bool if (area >= maxArea) { maxArea = area; - retVal = &display; + foundDisplay = &display; } } - return *retVal; + return foundDisplay; } -const Displays::Display& Displays::findDisplayForPoint (Point<int> point, bool isPhysical) const noexcept +const Displays::Display* Displays::getDisplayForPoint (Point<int> point, bool isPhysical) const noexcept { auto minDistance = std::numeric_limits<int>::max(); - const Display* retVal = nullptr; + const Display* foundDisplay = nullptr; for (auto& display : displays) { @@ -75,78 +74,89 @@ const Displays::Display& Displays::findDisplayForPoint (Point<int> point, bool i displayArea = (displayArea.withZeroOrigin() * display.scale) + display.topLeftPhysical; if (displayArea.contains (point)) - return display; + return &display; auto distance = displayArea.getCentre().getDistanceFrom (point); + if (distance <= minDistance) { minDistance = distance; - retVal = &display; + foundDisplay = &display; } } - return *retVal; + return foundDisplay; } Rectangle<int> Displays::physicalToLogical (Rectangle<int> rect, const Display* useScaleFactorOfDisplay) const noexcept { - auto& display = useScaleFactorOfDisplay != nullptr ? *useScaleFactorOfDisplay - : findDisplayForRect (rect, true); + const auto* display = useScaleFactorOfDisplay != nullptr ? useScaleFactorOfDisplay + : getDisplayForRect (rect, true); + + if (display == nullptr) + return rect; auto globalScale = Desktop::getInstance().getGlobalScaleFactor(); - return ((rect.toFloat() - display.topLeftPhysical.toFloat()) / (display.scale / globalScale)).toNearestInt() + (display.totalArea.getTopLeft() * globalScale); + return ((rect.toFloat() - display->topLeftPhysical.toFloat()) / (display->scale / globalScale)).toNearestInt() + (display->totalArea.getTopLeft() * globalScale); } Rectangle<int> Displays::logicalToPhysical (Rectangle<int> rect, const Display* useScaleFactorOfDisplay) const noexcept { - auto& display = useScaleFactorOfDisplay != nullptr ? *useScaleFactorOfDisplay - : findDisplayForRect (rect, false); + const auto* display = useScaleFactorOfDisplay != nullptr ? useScaleFactorOfDisplay + : getDisplayForRect (rect, false); + + if (display == nullptr) + return rect; auto globalScale = Desktop::getInstance().getGlobalScaleFactor(); - return ((rect.toFloat() - (display.totalArea.getTopLeft().toFloat() * globalScale)) * (display.scale / globalScale)).toNearestInt() + display.topLeftPhysical; + return ((rect.toFloat() - (display->totalArea.getTopLeft().toFloat() * globalScale)) * (display->scale / globalScale)).toNearestInt() + display->topLeftPhysical; } template <typename ValueType> Point<ValueType> Displays::physicalToLogical (Point<ValueType> point, const Display* useScaleFactorOfDisplay) const noexcept { - auto& display = useScaleFactorOfDisplay != nullptr ? *useScaleFactorOfDisplay - : findDisplayForPoint (point.roundToInt(), true); + const auto* display = useScaleFactorOfDisplay != nullptr ? useScaleFactorOfDisplay + : getDisplayForPoint (point.roundToInt(), true); + + if (display == nullptr) + return point; auto globalScale = Desktop::getInstance().getGlobalScaleFactor(); - Point<ValueType> logicalTopLeft (static_cast<ValueType> (display.totalArea.getX()), static_cast<ValueType> (display.totalArea.getY())); - Point<ValueType> physicalTopLeft (static_cast<ValueType> (display.topLeftPhysical.getX()), static_cast<ValueType> (display.topLeftPhysical.getY())); + Point<ValueType> logicalTopLeft (static_cast<ValueType> (display->totalArea.getX()), static_cast<ValueType> (display->totalArea.getY())); + Point<ValueType> physicalTopLeft (static_cast<ValueType> (display->topLeftPhysical.getX()), static_cast<ValueType> (display->topLeftPhysical.getY())); - return ((point - physicalTopLeft) / (display.scale / globalScale)) + (logicalTopLeft * globalScale); + return ((point - physicalTopLeft) / (display->scale / globalScale)) + (logicalTopLeft * globalScale); } template <typename ValueType> Point<ValueType> Displays::logicalToPhysical (Point<ValueType> point, const Display* useScaleFactorOfDisplay) const noexcept { - auto& display = useScaleFactorOfDisplay != nullptr ? *useScaleFactorOfDisplay - : findDisplayForPoint (point.roundToInt(), false); + const auto* display = useScaleFactorOfDisplay != nullptr ? useScaleFactorOfDisplay + : getDisplayForPoint (point.roundToInt(), false); + + if (display == nullptr) + return point; auto globalScale = Desktop::getInstance().getGlobalScaleFactor(); - Point<ValueType> logicalTopLeft (static_cast<ValueType> (display.totalArea.getX()), static_cast<ValueType> (display.totalArea.getY())); - Point<ValueType> physicalTopLeft (static_cast<ValueType> (display.topLeftPhysical.getX()), static_cast<ValueType> (display.topLeftPhysical.getY())); + Point<ValueType> logicalTopLeft (static_cast<ValueType> (display->totalArea.getX()), static_cast<ValueType> (display->totalArea.getY())); + Point<ValueType> physicalTopLeft (static_cast<ValueType> (display->topLeftPhysical.getX()), static_cast<ValueType> (display->topLeftPhysical.getY())); - return ((point - (logicalTopLeft * globalScale)) * (display.scale / globalScale)) + physicalTopLeft; + return ((point - (logicalTopLeft * globalScale)) * (display->scale / globalScale)) + physicalTopLeft; } -const Displays::Display& Displays::getMainDisplay() const noexcept +const Displays::Display* Displays::getPrimaryDisplay() const noexcept { JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED for (auto& d : displays) if (d.isMain) - return d; + return &d; - // no main display! - jassertfalse; - return displays.getReference (0); + return nullptr; } RectangleList<int> Displays::getRectangleList (bool userAreasOnly) const @@ -194,33 +204,6 @@ bool operator== (const Displays::Display& d1, const Displays::Display& d2) noexc bool operator!= (const Displays::Display& d1, const Displays::Display& d2) noexcept; bool operator!= (const Displays::Display& d1, const Displays::Display& d2) noexcept { return ! (d1 == d2); } -// Deprecated method -const Displays::Display& Displays::getDisplayContaining (Point<int> position) const noexcept -{ - JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED - const auto* best = &displays.getReference (0); - auto bestDistance = std::numeric_limits<int>::max(); - - for (auto& d : displays) - { - if (d.totalArea.contains (position)) - { - best = &d; - break; - } - - auto distance = d.totalArea.getCentre().getDistanceFrom (position); - - if (distance < bestDistance) - { - bestDistance = distance; - best = &d; - } - } - - return *best; -} - //============================================================================== // These methods are used for converting the totalArea and userArea Rectangles in Display from physical to logical // pixels. We do this by constructing a graph of connected displays where the root node has position (0, 0); this can be @@ -386,4 +369,56 @@ void Displays::updateToLogical() template Point<float> Displays::logicalToPhysical (Point<float>, const Display*) const noexcept; #endif +//============================================================================== +// Deprecated methods +const Displays::Display& Displays::getDisplayContaining (Point<int> position) const noexcept +{ + JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED + const auto* best = &displays.getReference (0); + auto bestDistance = std::numeric_limits<int>::max(); + + for (auto& d : displays) + { + if (d.totalArea.contains (position)) + { + best = &d; + break; + } + + auto distance = d.totalArea.getCentre().getDistanceFrom (position); + + if (distance < bestDistance) + { + bestDistance = distance; + best = &d; + } + } + + return *best; +} + +const Displays::Display& Displays::findDisplayForRect (Rectangle<int> rect, bool isPhysical) const noexcept +{ + if (auto* display = getDisplayForRect (rect, isPhysical)) + return *display; + + return emptyDisplay; +} + +const Displays::Display& Displays::findDisplayForPoint (Point<int> point, bool isPhysical) const noexcept +{ + if (auto* display = getDisplayForPoint (point, isPhysical)) + return *display; + + return emptyDisplay; +} + +const Displays::Display& Displays::getMainDisplay() const noexcept +{ + if (auto* display = getPrimaryDisplay()) + return *display; + + return emptyDisplay; +} + } // namespace juce diff --git a/modules/juce_gui_basics/desktop/juce_Displays.h b/modules/juce_gui_basics/desktop/juce_Displays.h index 1aa3f683..7e1281bb 100644 --- a/modules/juce_gui_basics/desktop/juce_Displays.h +++ b/modules/juce_gui_basics/desktop/juce_Displays.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -80,39 +79,41 @@ public: If useScaleFactorOfDisplay is not null then its scale factor will be used for the conversion regardless of the display that the Rectangle to be converted is on. */ - Rectangle<int> physicalToLogical (Rectangle<int>, const Display* useScaleFactorOfDisplay = nullptr) const noexcept; + Rectangle<int> physicalToLogical (Rectangle<int> physicalRect, const Display* useScaleFactorOfDisplay = nullptr) const noexcept; /** Converts a Rectangle from logical to physical pixels. If useScaleFactorOfDisplay is not null then its scale factor will be used for the conversion regardless of the display that the Rectangle to be converted is on. */ - Rectangle<int> logicalToPhysical (Rectangle<int>, const Display* useScaleFactorOfDisplay = nullptr) const noexcept; + Rectangle<int> logicalToPhysical (Rectangle<int> logicalRect, const Display* useScaleFactorOfDisplay = nullptr) const noexcept; /** Converts a Point from physical to logical pixels. */ template <typename ValueType> - Point<ValueType> physicalToLogical (Point<ValueType>, const Display* useScaleFactorOfDisplay = nullptr) const noexcept; + Point<ValueType> physicalToLogical (Point<ValueType> physicalPoint, const Display* useScaleFactorOfDisplay = nullptr) const noexcept; /** Converts a Point from logical to physical pixels. */ template <typename ValueType> - Point<ValueType> logicalToPhysical (Point<ValueType>, const Display* useScaleFactorOfDisplay = nullptr) const noexcept; + Point<ValueType> logicalToPhysical (Point<ValueType> logicalPoint, const Display* useScaleFactorOfDisplay = nullptr) const noexcept; /** Returns the Display object representing the display containing a given Rectangle (either - in logical or physical pixels). + in logical or physical pixels), or nullptr if there are no connected displays. If the Rectangle lies outside all the displays then the nearest one will be returned. */ - const Display& findDisplayForRect (Rectangle<int>, bool isPhysical = false) const noexcept; + const Display* getDisplayForRect (Rectangle<int> rect, bool isPhysical = false) const noexcept; /** Returns the Display object representing the display containing a given Point (either - in logical or physical pixels). + in logical or physical pixels), or nullptr if there are no connected displays. If the Point lies outside all the displays then the nearest one will be returned. */ - const Display& findDisplayForPoint (Point<int>, bool isPhysical = false) const noexcept; + const Display* getDisplayForPoint (Point<int> point, bool isPhysical = false) const noexcept; - /** Returns the Display object representing the display acting as the user's main screen. */ - const Display& getMainDisplay() const noexcept; + /** Returns the Display object representing the display acting as the user's main screen, or nullptr + if there are no connected displays. + */ + const Display* getPrimaryDisplay() const noexcept; /** Returns a RectangleList made up of all the displays in LOGICAL pixels. */ RectangleList<int> getRectangleList (bool userAreasOnly) const; @@ -128,9 +129,15 @@ public: void refresh(); /** @internal */ ~Displays() = default; - // This method has been deprecated - use the findDisplayForPoint() or findDisplayForRect() methods instead + // This method has been deprecated - use the getDisplayForPoint() or getDisplayForRect() methods instead // as they can deal with converting between logical and physical pixels JUCE_DEPRECATED (const Display& getDisplayContaining (Point<int> position) const noexcept); + + // These methods have been deprecated - use the methods which return a Display* instead as they will return + // nullptr on headless systems with no connected displays + JUCE_DEPRECATED (const Display& findDisplayForRect (Rectangle<int>, bool isPhysical = false) const noexcept); + JUCE_DEPRECATED (const Display& findDisplayForPoint (Point<int>, bool isPhysical = false) const noexcept); + JUCE_DEPRECATED (const Display& getMainDisplay() const noexcept); #endif private: @@ -140,6 +147,8 @@ private: void findDisplays (float masterScale); void updateToLogical(); + + Display emptyDisplay; }; } // namespace juce diff --git a/modules/juce_gui_basics/drawables/juce_Drawable.cpp b/modules/juce_gui_basics/drawables/juce_Drawable.cpp index 06fdbe00..a9bcbb18 100644 --- a/modules/juce_gui_basics/drawables/juce_Drawable.cpp +++ b/modules/juce_gui_basics/drawables/juce_Drawable.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/drawables/juce_Drawable.h b/modules/juce_gui_basics/drawables/juce_Drawable.h index 56ac7dfb..2cddd85d 100644 --- a/modules/juce_gui_basics/drawables/juce_Drawable.h +++ b/modules/juce_gui_basics/drawables/juce_Drawable.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -152,8 +151,7 @@ public: /** Attempts to parse an SVG (Scalable Vector Graphics) document, and to turn this into a Drawable tree. - The object returned must be deleted by the caller. If something goes wrong - while parsing, it may return nullptr. + If something goes wrong while parsing, it may return nullptr. SVG is a pretty large and complex spec, and this doesn't aim to be a full implementation, but it can return the basic vector objects. @@ -163,8 +161,7 @@ public: /** Attempts to parse an SVG (Scalable Vector Graphics) document from a file, and to turn this into a Drawable tree. - The object returned must be deleted by the caller. If something goes wrong - while parsing, it may return nullptr. + If something goes wrong while parsing, it may return nullptr. SVG is a pretty large and complex spec, and this doesn't aim to be a full implementation, but it can return the basic vector objects. diff --git a/modules/juce_gui_basics/drawables/juce_DrawableComposite.cpp b/modules/juce_gui_basics/drawables/juce_DrawableComposite.cpp index 8cddf73d..ae4257df 100644 --- a/modules/juce_gui_basics/drawables/juce_DrawableComposite.cpp +++ b/modules/juce_gui_basics/drawables/juce_DrawableComposite.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/drawables/juce_DrawableComposite.h b/modules/juce_gui_basics/drawables/juce_DrawableComposite.h index b80ee9ec..c76d0d21 100644 --- a/modules/juce_gui_basics/drawables/juce_DrawableComposite.h +++ b/modules/juce_gui_basics/drawables/juce_DrawableComposite.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/drawables/juce_DrawableImage.cpp b/modules/juce_gui_basics/drawables/juce_DrawableImage.cpp index 95df7111..958444d4 100644 --- a/modules/juce_gui_basics/drawables/juce_DrawableImage.cpp +++ b/modules/juce_gui_basics/drawables/juce_DrawableImage.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/drawables/juce_DrawableImage.h b/modules/juce_gui_basics/drawables/juce_DrawableImage.h index 0f146ac5..f2c7f4cc 100644 --- a/modules/juce_gui_basics/drawables/juce_DrawableImage.h +++ b/modules/juce_gui_basics/drawables/juce_DrawableImage.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/drawables/juce_DrawablePath.cpp b/modules/juce_gui_basics/drawables/juce_DrawablePath.cpp index eadadc3a..fd9919de 100644 --- a/modules/juce_gui_basics/drawables/juce_DrawablePath.cpp +++ b/modules/juce_gui_basics/drawables/juce_DrawablePath.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/drawables/juce_DrawablePath.h b/modules/juce_gui_basics/drawables/juce_DrawablePath.h index 14b80f5e..244850d5 100644 --- a/modules/juce_gui_basics/drawables/juce_DrawablePath.h +++ b/modules/juce_gui_basics/drawables/juce_DrawablePath.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/drawables/juce_DrawableRectangle.cpp b/modules/juce_gui_basics/drawables/juce_DrawableRectangle.cpp index 04773e1f..299df35e 100644 --- a/modules/juce_gui_basics/drawables/juce_DrawableRectangle.cpp +++ b/modules/juce_gui_basics/drawables/juce_DrawableRectangle.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/drawables/juce_DrawableRectangle.h b/modules/juce_gui_basics/drawables/juce_DrawableRectangle.h index 198572e6..3176e16c 100644 --- a/modules/juce_gui_basics/drawables/juce_DrawableRectangle.h +++ b/modules/juce_gui_basics/drawables/juce_DrawableRectangle.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/drawables/juce_DrawableShape.cpp b/modules/juce_gui_basics/drawables/juce_DrawableShape.cpp index 23f82432..ca399dbd 100644 --- a/modules/juce_gui_basics/drawables/juce_DrawableShape.cpp +++ b/modules/juce_gui_basics/drawables/juce_DrawableShape.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/drawables/juce_DrawableShape.h b/modules/juce_gui_basics/drawables/juce_DrawableShape.h index 53ae2793..f729c30e 100644 --- a/modules/juce_gui_basics/drawables/juce_DrawableShape.h +++ b/modules/juce_gui_basics/drawables/juce_DrawableShape.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/drawables/juce_DrawableText.cpp b/modules/juce_gui_basics/drawables/juce_DrawableText.cpp index 2041c1b9..e444ea33 100644 --- a/modules/juce_gui_basics/drawables/juce_DrawableText.cpp +++ b/modules/juce_gui_basics/drawables/juce_DrawableText.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/drawables/juce_DrawableText.h b/modules/juce_gui_basics/drawables/juce_DrawableText.h index 2b263f96..6eb84f93 100644 --- a/modules/juce_gui_basics/drawables/juce_DrawableText.h +++ b/modules/juce_gui_basics/drawables/juce_DrawableText.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/drawables/juce_SVGParser.cpp b/modules/juce_gui_basics/drawables/juce_SVGParser.cpp index d425a893..867a5c39 100644 --- a/modules/juce_gui_basics/drawables/juce_SVGParser.cpp +++ b/modules/juce_gui_basics/drawables/juce_SVGParser.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -369,7 +368,7 @@ public: if (parseNextNumber (d, num, false)) { - auto angle = degreesToRadians (num.getFloatValue()); + auto angle = degreesToRadians (parseSafeFloat (num)); if (parseNextFlag (d, flagValue)) { @@ -461,7 +460,7 @@ private: } //============================================================================== - void parseSubElements (const XmlPath& xml, DrawableComposite& parentDrawable, const bool shouldParseClip = true) + void parseSubElements (const XmlPath& xml, DrawableComposite& parentDrawable, bool shouldParseClip = true) { forEachXmlChildElement (*xml, e) { @@ -619,7 +618,7 @@ private: line.lineTo (x2, y2); } - void parsePolygon (const XmlPath& xml, const bool isPolyline, Path& path) const + void parsePolygon (const XmlPath& xml, bool isPolyline, Path& path) const { auto pointsAtt = xml->getStringAttribute ("points"); auto points = pointsAtt.getCharPointer(); @@ -684,7 +683,7 @@ private: //============================================================================== Drawable* parseShape (const XmlPath& xml, Path& path, - const bool shouldParseTransform = true, + bool shouldParseTransform = true, AffineTransform* additonalTransform = nullptr) const { if (shouldParseTransform && xml->hasAttribute ("transform")) @@ -836,14 +835,14 @@ private: auto col = parseColour (fillXml.getChild (e), "stop-color", Colours::black); auto opacity = getStyleAttribute (fillXml.getChild (e), "stop-opacity", "1"); - col = col.withMultipliedAlpha (jlimit (0.0f, 1.0f, opacity.getFloatValue())); + col = col.withMultipliedAlpha (jlimit (0.0f, 1.0f, parseSafeFloat (opacity))); - double offset = e->getDoubleAttribute ("offset"); + auto offset = parseSafeFloat (e->getStringAttribute ("offset")); if (e->getStringAttribute ("offset").containsChar ('%')) - offset *= 0.01; + offset *= 0.01f; - cg.addColour (jlimit (0.0, 1.0, offset), col); + cg.addColour (jlimit (0.0f, 1.0f, offset), col); result = true; } } @@ -984,10 +983,10 @@ private: float opacity = 1.0f; if (overallOpacity.isNotEmpty()) - opacity = jlimit (0.0f, 1.0f, overallOpacity.getFloatValue()); + opacity = jlimit (0.0f, 1.0f, parseSafeFloat (overallOpacity)); if (fillOpacity.isNotEmpty()) - opacity *= (jlimit (0.0f, 1.0f, fillOpacity.getFloatValue())); + opacity *= jlimit (0.0f, 1.0f, parseSafeFloat (fillOpacity)); String fill (getStyleAttribute (xml, fillAttribute)); String urlID = parseURL (fill); @@ -1024,7 +1023,8 @@ private: float getStrokeWidth (const String& strokeWidth) const noexcept { - return transform.getScaleFactor() * getCoordLength (strokeWidth, viewBoxW); + auto transformScale = std::sqrt (std::abs (transform.getDeterminant())); + return transformScale * getCoordLength (strokeWidth, viewBoxW); } PathStrokeType getStrokeFor (const XmlPath& xml) const @@ -1035,11 +1035,10 @@ private: } //============================================================================== - Drawable* useText (const XmlPath& xml) const { - auto translation = AffineTransform::translation ((float) xml->getDoubleAttribute ("x", 0.0), - (float) xml->getDoubleAttribute ("y", 0.0)); + auto translation = AffineTransform::translation (parseSafeFloat (xml->getStringAttribute ("x")), + parseSafeFloat (xml->getStringAttribute ("y"))); UseTextOp op = { this, &translation, nullptr }; @@ -1099,7 +1098,7 @@ private: dt->setTransform (transform); dt->setColour (parseColour (xml, "fill", Colours::black) - .withMultipliedAlpha (getStyleAttribute (xml, "fill-opacity", "1").getFloatValue())); + .withMultipliedAlpha (parseSafeFloat (getStyleAttribute (xml, "fill-opacity", "1")))); Rectangle<float> bounds (xCoords[0], yCoords[0] - font.getAscent(), font.getStringWidthFloat (text), font.getHeight()); @@ -1138,8 +1137,8 @@ private: //============================================================================== Drawable* useImage (const XmlPath& xml) const { - auto translation = AffineTransform::translation ((float) xml->getDoubleAttribute ("x", 0.0), - (float) xml->getDoubleAttribute ("y", 0.0)); + auto translation = AffineTransform::translation (parseSafeFloat (xml->getStringAttribute ("x")), + parseSafeFloat (xml->getStringAttribute ("y"))); UseImageOp op = { this, &translation, nullptr }; @@ -1197,7 +1196,7 @@ private: auto linkedFile = originalFile.getParentDirectory().getChildFile (link); if (linkedFile.existsAsFile()) - inputStream.reset (linkedFile.createInputStream()); + inputStream = linkedFile.createInputStream(); } if (inputStream != nullptr) @@ -1210,10 +1209,13 @@ private: setCommonAttributes (*di, xml); - Rectangle<float> imageBounds ((float) xml->getDoubleAttribute ("x", 0.0), (float) xml->getDoubleAttribute ("y", 0.0), - (float) xml->getDoubleAttribute ("width", image.getWidth()), (float) xml->getDoubleAttribute ("height", image.getHeight())); + Rectangle<float> imageBounds (parseSafeFloat (xml->getStringAttribute ("x")), + parseSafeFloat (xml->getStringAttribute ("y")), + parseSafeFloat (xml->getStringAttribute ("width", String (image.getWidth()))), + parseSafeFloat (xml->getStringAttribute ("height", String (image.getHeight())))); - di->setImage (image.rescaled ((int) imageBounds.getWidth(), (int) imageBounds.getHeight())); + di->setImage (image.rescaled ((int) imageBounds.getWidth(), + (int) imageBounds.getHeight())); di->setTransformToFit (imageBounds, RectanglePlacement (parsePlacementFlags (xml->getStringAttribute ("preserveAspectRatio").trim()))); @@ -1237,7 +1239,7 @@ private: } //============================================================================== - bool parseCoord (String::CharPointerType& s, float& value, const bool allowUnits, const bool isX) const + bool parseCoord (String::CharPointerType& s, float& value, bool allowUnits, bool isX) const { String number; @@ -1251,13 +1253,13 @@ private: return true; } - bool parseCoords (String::CharPointerType& s, Point<float>& p, const bool allowUnits) const + bool parseCoords (String::CharPointerType& s, Point<float>& p, bool allowUnits) const { return parseCoord (s, p.x, allowUnits, true) && parseCoord (s, p.y, allowUnits, false); } - bool parseCoordsOrSkip (String::CharPointerType& s, Point<float>& p, const bool allowUnits) const + bool parseCoordsOrSkip (String::CharPointerType& s, Point<float>& p, bool allowUnits) const { if (parseCoords (s, p, allowUnits)) return true; @@ -1268,8 +1270,8 @@ private: float getCoordLength (const String& s, const float sizeForProportions) const noexcept { - float n = s.getFloatValue(); - const int len = s.length(); + auto n = parseSafeFloat (s); + auto len = s.length(); if (len > 2) { @@ -1293,7 +1295,7 @@ private: return getCoordLength (xml->getStringAttribute (attName), sizeForProportions); } - void getCoordList (Array<float>& coords, const String& list, bool allowUnits, const bool isX) const + void getCoordList (Array<float>& coords, const String& list, bool allowUnits, bool isX) const { auto text = list.getCharPointer(); float value; @@ -1302,6 +1304,12 @@ private: coords.add (value); } + static float parseSafeFloat (const String& s) + { + auto n = s.getFloatValue(); + return (std::isnan (n) || std::isinf (n)) ? 0.0f : n; + } + //============================================================================== void parseCSSStyle (const XmlPath& xml) { @@ -1452,7 +1460,7 @@ private: return CharacterFunctions::isDigit (c) || c == '-' || c == '+'; } - static bool parseNextNumber (String::CharPointerType& text, String& value, const bool allowUnits) + static bool parseNextNumber (String::CharPointerType& text, String& value, bool allowUnits) { auto s = text; @@ -1525,16 +1533,18 @@ private: if (text.startsWithChar ('#')) { - uint32 hex[6] = { 0 }; + uint32 hex[8] = { 0 }; + hex[6] = hex[7] = 15; + int numChars = 0; auto s = text.getCharPointer(); - while (numChars < 6) + while (numChars < 8) { auto hexValue = CharacterFunctions::getHexDigitValue (*++s); if (hexValue >= 0) - hex [numChars++] = (uint32) hexValue; + hex[numChars++] = (uint32) hexValue; else break; } @@ -1546,30 +1556,53 @@ private: return Colour ((uint8) ((hex[0] << 4) + hex[1]), (uint8) ((hex[2] << 4) + hex[3]), - (uint8) ((hex[4] << 4) + hex[5])); + (uint8) ((hex[4] << 4) + hex[5]), + (uint8) ((hex[6] << 4) + hex[7])); } - if (text.startsWith ("rgb")) + if (text.startsWith ("rgb") || text.startsWith ("hsl")) { - auto openBracket = text.indexOfChar ('('); - auto closeBracket = text.indexOfChar (openBracket, ')'); + auto tokens = [&text] + { + auto openBracket = text.indexOfChar ('('); + auto closeBracket = text.indexOfChar (openBracket, ')'); - if (openBracket >= 3 && closeBracket > openBracket) + StringArray arr; + + if (openBracket >= 3 && closeBracket > openBracket) + { + arr.addTokens (text.substring (openBracket + 1, closeBracket), ",", ""); + arr.trim(); + arr.removeEmptyStrings(); + } + + return arr; + }(); + + auto alpha = [&tokens, &text] { - StringArray tokens; - tokens.addTokens (text.substring (openBracket + 1, closeBracket), ",", ""); - tokens.trim(); - tokens.removeEmptyStrings(); - - if (tokens[0].containsChar ('%')) - return Colour ((uint8) roundToInt (2.55 * tokens[0].getDoubleValue()), - (uint8) roundToInt (2.55 * tokens[1].getDoubleValue()), - (uint8) roundToInt (2.55 * tokens[2].getDoubleValue())); - - return Colour ((uint8) tokens[0].getIntValue(), - (uint8) tokens[1].getIntValue(), - (uint8) tokens[2].getIntValue()); - } + if ((text.startsWith ("rgba") || text.startsWith ("hsla")) && tokens.size() == 4) + return parseSafeFloat (tokens[3]); + + return 1.0f; + }(); + + if (text.startsWith ("hsl")) + return Colour::fromHSL (parseSafeFloat (tokens[0]) / 360.0f, + parseSafeFloat (tokens[1]) / 100.0f, + parseSafeFloat (tokens[2]) / 100.0f, + alpha); + + if (tokens[0].containsChar ('%')) + return Colour ((uint8) roundToInt (2.55f * parseSafeFloat (tokens[0])), + (uint8) roundToInt (2.55f * parseSafeFloat (tokens[1])), + (uint8) roundToInt (2.55f * parseSafeFloat (tokens[2])), + alpha); + + return Colour ((uint8) tokens[0].getIntValue(), + (uint8) tokens[1].getIntValue(), + (uint8) tokens[2].getIntValue(), + alpha); } if (text == "inherit") @@ -1598,7 +1631,7 @@ private: float numbers[6]; for (int i = 0; i < numElementsInArray (numbers); ++i) - numbers[i] = tokens[i].getFloatValue(); + numbers[i] = parseSafeFloat (tokens[i]); AffineTransform trans; diff --git a/modules/juce_gui_basics/filebrowser/juce_ContentSharer.cpp b/modules/juce_gui_basics/filebrowser/juce_ContentSharer.cpp index ac2c4430..eef5d0cc 100644 --- a/modules/juce_gui_basics/filebrowser/juce_ContentSharer.cpp +++ b/modules/juce_gui_basics/filebrowser/juce_ContentSharer.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -27,7 +26,7 @@ namespace juce { -#if JUCE_IOS || JUCE_ANDROID +#if JUCE_CONTENT_SHARING //============================================================================== class ContentSharer::PrepareImagesThread : private Thread { @@ -77,7 +76,7 @@ private: void finish() { - MessageManager::callAsync ([this] () { owner.filesToSharePrepared(); }); + MessageManager::callAsync ([this]() { owner.filesToSharePrepared(); }); } ContentSharer& owner; @@ -137,7 +136,7 @@ private: void finish() { - MessageManager::callAsync ([this] () { owner.filesToSharePrepared(); }); + MessageManager::callAsync ([this]() { owner.filesToSharePrepared(); }); } ContentSharer& owner; @@ -152,9 +151,9 @@ ContentSharer::ContentSharer() {} ContentSharer::~ContentSharer() { clearSingletonInstance(); } void ContentSharer::shareFiles (const Array<URL>& files, - std::function<void(bool, const String&)> callbackToUse) + std::function<void (bool, const String&)> callbackToUse) { - #if JUCE_IOS || JUCE_ANDROID + #if JUCE_CONTENT_SHARING startNewShare (callbackToUse); pimpl->shareFiles (files); #else @@ -168,8 +167,8 @@ void ContentSharer::shareFiles (const Array<URL>& files, #endif } -#if JUCE_IOS || JUCE_ANDROID -void ContentSharer::startNewShare (std::function<void(bool, const String&)> callbackToUse) +#if JUCE_CONTENT_SHARING +void ContentSharer::startNewShare (std::function<void (bool, const String&)> callbackToUse) { // You should not start another sharing operation before the previous one is finished. // Forcibly stopping a previous sharing operation is rarely a good idea! @@ -190,9 +189,9 @@ void ContentSharer::startNewShare (std::function<void(bool, const String&)> call #endif void ContentSharer::shareText (const String& text, - std::function<void(bool, const String&)> callbackToUse) + std::function<void (bool, const String&)> callbackToUse) { - #if JUCE_IOS || JUCE_ANDROID + #if JUCE_CONTENT_SHARING startNewShare (callbackToUse); pimpl->shareText (text); #else @@ -207,10 +206,10 @@ void ContentSharer::shareText (const String& text, } void ContentSharer::shareImages (const Array<Image>& images, - std::function<void(bool, const String&)> callbackToUse, + std::function<void (bool, const String&)> callbackToUse, ImageFileFormat* imageFileFormatToUse) { - #if JUCE_IOS || JUCE_ANDROID + #if JUCE_CONTENT_SHARING startNewShare (callbackToUse); prepareImagesThread.reset (new PrepareImagesThread (*this, images, imageFileFormatToUse)); #else @@ -224,7 +223,7 @@ void ContentSharer::shareImages (const Array<Image>& images, #endif } -#if JUCE_IOS || JUCE_ANDROID +#if JUCE_CONTENT_SHARING void ContentSharer::filesToSharePrepared() { Array<URL> urls; @@ -240,9 +239,9 @@ void ContentSharer::filesToSharePrepared() #endif void ContentSharer::shareData (const MemoryBlock& mb, - std::function<void(bool, const String&)> callbackToUse) + std::function<void (bool, const String&)> callbackToUse) { - #if JUCE_IOS || JUCE_ANDROID + #if JUCE_CONTENT_SHARING startNewShare (callbackToUse); prepareDataThread.reset (new PrepareDataThread (*this, mb)); #else @@ -257,12 +256,12 @@ void ContentSharer::sharingFinished (bool succeeded, const String& errorDescript { deleteTemporaryFiles(); - std::function<void(bool, String)> cb; + std::function<void (bool, String)> cb; std::swap (cb, callback); String error (errorDescription); - #if JUCE_IOS || JUCE_ANDROID + #if JUCE_CONTENT_SHARING pimpl.reset(); #endif diff --git a/modules/juce_gui_basics/filebrowser/juce_ContentSharer.h b/modules/juce_gui_basics/filebrowser/juce_ContentSharer.h index a486c2b3..e72e1499 100644 --- a/modules/juce_gui_basics/filebrowser/juce_ContentSharer.h +++ b/modules/juce_gui_basics/filebrowser/juce_ContentSharer.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -35,7 +34,7 @@ namespace juce @tags{GUI} */ -class JUCE_API ContentSharer +class JUCE_API ContentSharer : public DeletedAtShutdown { public: JUCE_DECLARE_SINGLETON (ContentSharer, false) @@ -53,7 +52,7 @@ public: succeeded. Also, the optional error message is always empty on Android. */ void shareFiles (const Array<URL>& files, - std::function<void(bool /*success*/, const String& /*error*/)> callback); + std::function<void (bool /*success*/, const String& /*error*/)> callback); /** Shares the given text. @@ -63,7 +62,7 @@ public: succeeded. Also, the optional error message is always empty on Android. */ void shareText (const String& text, - std::function<void(bool /*success*/, const String& /*error*/)> callback); + std::function<void (bool /*success*/, const String& /*error*/)> callback); /** A convenience function to share an image. This is useful when you have images loaded in memory. The images will be written to temporary files first, so if @@ -87,7 +86,7 @@ public: succeeded. Also, the optional error message is always empty on Android. */ void shareImages (const Array<Image>& images, - std::function<void(bool /*success*/, const String& /*error*/)> callback, + std::function<void (bool /*success*/, const String& /*error*/)> callback, ImageFileFormat* imageFileFormatToUse = nullptr); /** A convenience function to share arbitrary data. The data will be written @@ -100,7 +99,7 @@ public: succeeded. Also, the optional error message is always empty on Android. */ void shareData (const MemoryBlock& mb, - std::function<void(bool /*success*/, const String& /*error*/)> callback); + std::function<void (bool /*success*/, const String& /*error*/)> callback); private: ContentSharer(); @@ -108,9 +107,9 @@ private: Array<File> temporaryFiles; - std::function<void(bool, String)> callback; + std::function<void (bool, String)> callback; - #if JUCE_IOS || JUCE_ANDROID + #if JUCE_CONTENT_SHARING struct Pimpl { virtual ~Pimpl() {} @@ -121,7 +120,7 @@ private: std::unique_ptr<Pimpl> pimpl; Pimpl* createPimpl(); - void startNewShare (std::function<void(bool, const String&)>); + void startNewShare (std::function<void (bool, const String&)>); class ContentSharerNativeImpl; friend class ContentSharerNativeImpl; diff --git a/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.cpp b/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.cpp index ff42121c..81907c9a 100644 --- a/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.cpp +++ b/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.h b/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.h index 7089b37f..d09dac5b 100644 --- a/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.h +++ b/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.cpp b/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.cpp index eecdc46b..6976073e 100644 --- a/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.cpp +++ b/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -89,14 +88,14 @@ void DirectoryContentsList::stopSearching() { shouldStop = true; thread.removeTimeSliceClient (this); - fileFindHandle.reset(); + fileFindHandle = nullptr; } void DirectoryContentsList::clear() { stopSearching(); - if (files.size() > 0) + if (! files.isEmpty()) { files.clear(); changed(); @@ -111,7 +110,7 @@ void DirectoryContentsList::refresh() if (root.isDirectory()) { - fileFindHandle.reset (new DirectoryIterator (root, false, "*", fileTypeFlags)); + fileFindHandle = std::make_unique<RangedDirectoryIterator> (root, false, "*", fileTypeFlags); shouldStop = false; thread.addTimeSliceClient (this); } @@ -204,15 +203,16 @@ bool DirectoryContentsList::checkNextFile (bool& hasChanged) { if (fileFindHandle != nullptr) { - bool fileFoundIsDir, isHidden, isReadOnly; - int64 fileSize; - Time modTime, creationTime; - - if (fileFindHandle->next (&fileFoundIsDir, &isHidden, &fileSize, - &modTime, &creationTime, &isReadOnly)) + if (*fileFindHandle != RangedDirectoryIterator()) { - if (addFile (fileFindHandle->getFile(), fileFoundIsDir, - fileSize, modTime, creationTime, isReadOnly)) + const auto entry = *(*fileFindHandle)++; + + if (addFile (entry.getFile(), + entry.isDirectory(), + entry.getFileSize(), + entry.getModificationTime(), + entry.getCreationTime(), + entry.isReadOnly())) { hasChanged = true; } @@ -220,7 +220,7 @@ bool DirectoryContentsList::checkNextFile (bool& hasChanged) return true; } - fileFindHandle.reset(); + fileFindHandle = nullptr; if (! wasEmpty && files.isEmpty()) hasChanged = true; diff --git a/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.h b/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.h index d17f1f5b..691155ae 100644 --- a/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.h +++ b/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -208,7 +207,7 @@ private: CriticalSection fileListLock; OwnedArray<FileInfo> files; - std::unique_ptr<DirectoryIterator> fileFindHandle; + std::unique_ptr<RangedDirectoryIterator> fileFindHandle; std::atomic<bool> shouldStop { true }; bool wasEmpty = true; diff --git a/modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.cpp b/modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.cpp index 94e3a40e..f7de6d62 100644 --- a/modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.cpp +++ b/modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -113,11 +112,6 @@ FileBrowserComponent::FileBrowserComponent (int flags_, addAndMakeVisible (fileLabel); fileLabel.attachToComponent (&filenameBox, true); - goUpButton.reset (getLookAndFeel().createFileBrowserGoUpButton()); - addAndMakeVisible (goUpButton.get()); - goUpButton->onClick = [this] { goUp(); }; - goUpButton->setTooltip (TRANS ("Go up to parent directory")); - if (previewComp != nullptr) addAndMakeVisible (previewComp); @@ -359,12 +353,24 @@ void FileBrowserComponent::resized() //============================================================================== void FileBrowserComponent::lookAndFeelChanged() { + goUpButton.reset (getLookAndFeel().createFileBrowserGoUpButton()); + + if (auto* buttonPtr = goUpButton.get()) + { + addAndMakeVisible (*buttonPtr); + buttonPtr->onClick = [this] { goUp(); }; + buttonPtr->setTooltip (TRANS ("Go up to parent directory")); + } + currentPathBox.setColour (ComboBox::backgroundColourId, findColour (currentPathBoxBackgroundColourId)); currentPathBox.setColour (ComboBox::textColourId, findColour (currentPathBoxTextColourId)); currentPathBox.setColour (ComboBox::arrowColourId, findColour (currentPathBoxArrowColourId)); filenameBox.setColour (TextEditor::backgroundColourId, findColour (filenameBoxBackgroundColourId)); - filenameBox.setColour (TextEditor::textColourId, findColour (filenameBoxTextColourId)); + filenameBox.applyColourToAllText (findColour (filenameBoxTextColourId)); + + resized(); + repaint(); } //============================================================================== diff --git a/modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.h b/modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.h index ce632496..4d25ec32 100644 --- a/modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.h +++ b/modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/filebrowser/juce_FileBrowserListener.h b/modules/juce_gui_basics/filebrowser/juce_FileBrowserListener.h index ef22c523..e4689075 100644 --- a/modules/juce_gui_basics/filebrowser/juce_FileBrowserListener.h +++ b/modules/juce_gui_basics/filebrowser/juce_FileBrowserListener.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/filebrowser/juce_FileChooser.cpp b/modules/juce_gui_basics/filebrowser/juce_FileChooser.cpp index 78b64841..661c02a3 100644 --- a/modules/juce_gui_basics/filebrowser/juce_FileChooser.cpp +++ b/modules/juce_gui_basics/filebrowser/juce_FileChooser.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -169,7 +168,7 @@ bool FileChooser::showDialog (const int flags, FilePreviewComponent* const previ } #endif -void FileChooser::launchAsync (int flags, std::function<void(const FileChooser&)> callback, +void FileChooser::launchAsync (int flags, std::function<void (const FileChooser&)> callback, FilePreviewComponent* previewComp) { // You must specify a callback when using launchAsync @@ -254,7 +253,7 @@ URL FileChooser::getURLResult() const void FileChooser::finished (const Array<URL>& asyncResults) { - std::function<void(const FileChooser&)> callback; + std::function<void (const FileChooser&)> callback; std::swap (callback, asyncCallback); results = asyncResults; diff --git a/modules/juce_gui_basics/filebrowser/juce_FileChooser.h b/modules/juce_gui_basics/filebrowser/juce_FileChooser.h index c834593f..48e8deb8 100644 --- a/modules/juce_gui_basics/filebrowser/juce_FileChooser.h +++ b/modules/juce_gui_basics/filebrowser/juce_FileChooser.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -209,7 +208,7 @@ public: the lifetime of the file-chooser. */ void launchAsync (int flags, - std::function<void(const FileChooser&)>, + std::function<void (const FileChooser&)>, FilePreviewComponent* previewComponent = nullptr); //============================================================================== @@ -310,7 +309,7 @@ private: Array<URL> results; const bool useNativeDialogBox; const bool treatFilePackagesAsDirs; - std::function<void(const FileChooser&)> asyncCallback; + std::function<void (const FileChooser&)> asyncCallback; //============================================================================== void finished (const Array<URL>&); diff --git a/modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.cpp b/modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.cpp index ca32b00e..5158a7df 100644 --- a/modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.cpp +++ b/modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -64,7 +63,7 @@ public: auto area = getLocalBounds(); text.createLayout (getLookAndFeel().createFileChooserHeaderText (getName(), instructions), - getWidth() - 12.0f); + (float) getWidth() - 12.0f); area.removeFromTop (roundToInt (text.getHeight()) + 10); diff --git a/modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.h b/modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.h index c6f3b02a..5fbf6c88 100644 --- a/modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.h +++ b/modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/filebrowser/juce_FileListComponent.cpp b/modules/juce_gui_basics/filebrowser/juce_FileListComponent.cpp index b3e0376c..b3a85d42 100644 --- a/modules/juce_gui_basics/filebrowser/juce_FileListComponent.cpp +++ b/modules/juce_gui_basics/filebrowser/juce_FileListComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/filebrowser/juce_FileListComponent.h b/modules/juce_gui_basics/filebrowser/juce_FileListComponent.h index c57317b6..450e6c8e 100644 --- a/modules/juce_gui_basics/filebrowser/juce_FileListComponent.h +++ b/modules/juce_gui_basics/filebrowser/juce_FileListComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/filebrowser/juce_FilePreviewComponent.h b/modules/juce_gui_basics/filebrowser/juce_FilePreviewComponent.h index d5263daf..135df17e 100644 --- a/modules/juce_gui_basics/filebrowser/juce_FilePreviewComponent.h +++ b/modules/juce_gui_basics/filebrowser/juce_FilePreviewComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/filebrowser/juce_FileSearchPathListComponent.cpp b/modules/juce_gui_basics/filebrowser/juce_FileSearchPathListComponent.cpp index 190affd7..70ef0c42 100644 --- a/modules/juce_gui_basics/filebrowser/juce_FileSearchPathListComponent.cpp +++ b/modules/juce_gui_basics/filebrowser/juce_FileSearchPathListComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -130,7 +129,7 @@ void FileSearchPathListComponent::paintListBoxItem (int rowNumber, Graphics& g, g.fillAll (findColour (TextEditor::highlightColourId)); g.setColour (findColour (ListBox::textColourId)); - Font f (height * 0.7f); + Font f ((float) height * 0.7f); f.setHorizontalScale (0.9f); g.setFont (f); diff --git a/modules/juce_gui_basics/filebrowser/juce_FileSearchPathListComponent.h b/modules/juce_gui_basics/filebrowser/juce_FileSearchPathListComponent.h index 7033af38..26f21c07 100644 --- a/modules/juce_gui_basics/filebrowser/juce_FileSearchPathListComponent.h +++ b/modules/juce_gui_basics/filebrowser/juce_FileSearchPathListComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/filebrowser/juce_FileTreeComponent.cpp b/modules/juce_gui_basics/filebrowser/juce_FileTreeComponent.cpp index f1a3c300..b7c81369 100644 --- a/modules/juce_gui_basics/filebrowser/juce_FileTreeComponent.cpp +++ b/modules/juce_gui_basics/filebrowser/juce_FileTreeComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -27,8 +26,6 @@ namespace juce { -Image juce_createIconForFile (const File&); - //============================================================================== class FileListTreeItem : public TreeViewItem, private TimeSliceClient, @@ -118,8 +115,7 @@ public: { removeSubContentsList(); - OptionalScopedPointer<DirectoryContentsList> newPointer (newList, canDeleteList); - subContentsList = newPointer; + subContentsList = OptionalScopedPointer<DirectoryContentsList> (newList, canDeleteList); newList->addChangeListener (this); } diff --git a/modules/juce_gui_basics/filebrowser/juce_FileTreeComponent.h b/modules/juce_gui_basics/filebrowser/juce_FileTreeComponent.h index 93cbd48d..956bde23 100644 --- a/modules/juce_gui_basics/filebrowser/juce_FileTreeComponent.h +++ b/modules/juce_gui_basics/filebrowser/juce_FileTreeComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/filebrowser/juce_FilenameComponent.cpp b/modules/juce_gui_basics/filebrowser/juce_FilenameComponent.cpp index 4fefe7c3..48512ba8 100644 --- a/modules/juce_gui_basics/filebrowser/juce_FilenameComponent.cpp +++ b/modules/juce_gui_basics/filebrowser/juce_FilenameComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/filebrowser/juce_FilenameComponent.h b/modules/juce_gui_basics/filebrowser/juce_FilenameComponent.h index dc93e40f..68042f17 100644 --- a/modules/juce_gui_basics/filebrowser/juce_FilenameComponent.h +++ b/modules/juce_gui_basics/filebrowser/juce_FilenameComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/filebrowser/juce_ImagePreviewComponent.cpp b/modules/juce_gui_basics/filebrowser/juce_ImagePreviewComponent.cpp index 5d65ae86..1b37973a 100644 --- a/modules/juce_gui_basics/filebrowser/juce_ImagePreviewComponent.cpp +++ b/modules/juce_gui_basics/filebrowser/juce_ImagePreviewComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/filebrowser/juce_ImagePreviewComponent.h b/modules/juce_gui_basics/filebrowser/juce_ImagePreviewComponent.h index 79c88c42..d2e625b8 100644 --- a/modules/juce_gui_basics/filebrowser/juce_ImagePreviewComponent.h +++ b/modules/juce_gui_basics/filebrowser/juce_ImagePreviewComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/juce_gui_basics.cpp b/modules/juce_gui_basics/juce_gui_basics.cpp index 9143cec5..056ff591 100644 --- a/modules/juce_gui_basics/juce_gui_basics.cpp +++ b/modules/juce_gui_basics/juce_gui_basics.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -41,6 +40,7 @@ #define JUCE_CORE_INCLUDE_NATIVE_HEADERS 1 #define JUCE_EVENTS_INCLUDE_WIN32_MESSAGE_WINDOW 1 #define JUCE_GRAPHICS_INCLUDE_COREGRAPHICS_HELPERS 1 +#define JUCE_GUI_BASICS_INCLUDE_XHEADERS 1 #include "juce_gui_basics.h" @@ -87,48 +87,6 @@ #pragma comment (lib, "D2d1.lib") #endif #endif - -//============================================================================== -#elif JUCE_LINUX - #include <X11/Xlib.h> - #include <X11/Xatom.h> - #include <X11/Xresource.h> - #include <X11/Xutil.h> - #include <X11/Xmd.h> - #include <X11/keysym.h> - #include <X11/XKBlib.h> - #include <X11/cursorfont.h> - #include <unistd.h> - - #if JUCE_USE_XRANDR - /* If you're trying to use Xrandr, you'll need to install the "libxrandr-dev" package.. */ - #include <X11/extensions/Xrandr.h> - #endif - - #if JUCE_USE_XINERAMA - /* If you're trying to use Xinerama, you'll need to install the "libxinerama-dev" package.. */ - #include <X11/extensions/Xinerama.h> - #endif - - #if JUCE_USE_XSHM - #include <X11/extensions/XShm.h> - #include <sys/shm.h> - #include <sys/ipc.h> - #endif - - #if JUCE_USE_XRENDER - // If you're missing these headers, try installing the libxrender-dev and libxcomposite-dev - #include <X11/extensions/Xrender.h> - #include <X11/extensions/Xcomposite.h> - #endif - - #if JUCE_USE_XCURSOR - // If you're missing this header, try installing the libxcursor-dev package - #include <X11/Xcursor/Xcursor.h> - #endif - - #undef SIZEOF - #undef KeyPress #endif #include <set> @@ -263,27 +221,25 @@ namespace juce #include "misc/juce_JUCESplashScreen.cpp" #include "layout/juce_FlexBox.cpp" -#if JUCE_HAS_CONSTEXPR - #include "layout/juce_GridItem.cpp" - #include "layout/juce_Grid.cpp" -#endif +#include "layout/juce_GridItem.cpp" +#include "layout/juce_Grid.cpp" #if JUCE_IOS || JUCE_WINDOWS #include "native/juce_MultiTouchMapper.h" #endif #if JUCE_MAC || JUCE_IOS - - #if JUCE_CLANG - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wundeclared-selector" - #endif + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wundeclared-selector") #if JUCE_IOS #include "native/juce_ios_UIViewComponentPeer.mm" #include "native/juce_ios_Windowing.mm" #include "native/juce_ios_FileChooser.mm" - #include "native/juce_ios_ContentSharer.cpp" + + #if JUCE_CONTENT_SHARING + #include "native/juce_ios_ContentSharer.cpp" + #endif + #else #include "native/juce_mac_NSViewComponentPeer.mm" #include "native/juce_mac_Windowing.mm" @@ -291,9 +247,7 @@ namespace juce #include "native/juce_mac_FileChooser.mm" #endif - #if JUCE_CLANG - #pragma clang diagnostic pop - #endif + JUCE_END_IGNORE_WARNINGS_GCC_LIKE #include "native/juce_mac_MouseCursor.mm" @@ -303,19 +257,15 @@ namespace juce #include "native/juce_win32_FileChooser.cpp" #elif JUCE_LINUX - #include "native/juce_linux_X11.cpp" - #include "native/juce_linux_X11_Clipboard.cpp" + #include "native/x11/juce_linux_X11_Symbols.cpp" + #include "native/x11/juce_linux_X11_DragAndDrop.cpp" - #if JUCE_GCC - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - #endif + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wzero-as-null-pointer-constant") - #include "native/juce_linux_X11_Windowing.cpp" + #include "native/juce_linux_Windowing.cpp" + #include "native/x11/juce_linux_XWindowSystem.cpp" - #if JUCE_GCC - #pragma GCC diagnostic pop - #endif + JUCE_END_IGNORE_WARNINGS_GCC_LIKE #include "native/juce_linux_FileChooser.cpp" @@ -323,6 +273,9 @@ namespace juce #include "native/juce_android_Windowing.cpp" #include "native/juce_common_MimeTypes.cpp" #include "native/juce_android_FileChooser.cpp" - #include "native/juce_android_ContentSharer.cpp" + + #if JUCE_CONTENT_SHARING + #include "native/juce_android_ContentSharer.cpp" + #endif #endif diff --git a/modules/juce_gui_basics/juce_gui_basics.h b/modules/juce_gui_basics/juce_gui_basics.h index dbe42b28..52dd174a 100644 --- a/modules/juce_gui_basics/juce_gui_basics.h +++ b/modules/juce_gui_basics/juce_gui_basics.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -29,14 +28,14 @@ The block below describes the properties of this module, and is read by the Projucer to automatically generate project code that uses it. For details about the syntax and how to create or use a module, see the - JUCE Module Format.txt file. + JUCE Module Format.md file. BEGIN_JUCE_MODULE_DECLARATION ID: juce_gui_basics vendor: juce - version: 5.4.7 + version: 6.0.5 name: JUCE GUI core classes description: Basic user-interface components and related classes. website: http://www.juce.com/juce @@ -44,8 +43,7 @@ dependencies: juce_graphics juce_data_structures OSXFrameworks: Cocoa Carbon QuartzCore - iOSFrameworks: UIKit MobileCoreServices - linuxPackages: x11 xinerama xext + iOSFrameworks: UIKit CoreServices END_JUCE_MODULE_DECLARATION @@ -159,9 +157,7 @@ namespace juce class Displays; class FlexBox; - #if JUCE_HAS_CONSTEXPR - class Grid; - #endif + class Grid; } #include "mouse/juce_MouseCursor.h" @@ -299,13 +295,55 @@ namespace juce #include "mouse/juce_LassoComponent.h" #if JUCE_LINUX - #include "native/juce_linux_X11.h" + #if JUCE_GUI_BASICS_INCLUDE_XHEADERS + // If you're missing these headers, you need to install the libx11-dev package + #include <X11/Xlib.h> + #include <X11/Xatom.h> + #include <X11/Xresource.h> + #include <X11/Xutil.h> + #include <X11/Xmd.h> + #include <X11/keysym.h> + #include <X11/XKBlib.h> + #include <X11/cursorfont.h> + #include <unistd.h> + + #if JUCE_USE_XRANDR + // If you're missing this header, you need to install the libxrandr-dev package + #include <X11/extensions/Xrandr.h> + #endif + + #if JUCE_USE_XINERAMA + // If you're missing this header, you need to install the libxinerama-dev package + #include <X11/extensions/Xinerama.h> + #endif + + #if JUCE_USE_XSHM + #include <X11/extensions/XShm.h> + #include <sys/shm.h> + #include <sys/ipc.h> + #endif + + #if JUCE_USE_XRENDER + // If you're missing these headers, you need to install the libxrender-dev and libxcomposite-dev packages + #include <X11/extensions/Xrender.h> + #include <X11/extensions/Xcomposite.h> + #endif + + #if JUCE_USE_XCURSOR + // If you're missing this header, you need to install the libxcursor-dev package + #include <X11/Xcursor/Xcursor.h> + #endif + + #undef SIZEOF + #undef KeyPress + + #include "native/x11/juce_linux_XWindowSystem.h" + #include "native/x11/juce_linux_X11_Symbols.h" + #endif #endif #include "layout/juce_FlexItem.h" #include "layout/juce_FlexBox.h" -#if JUCE_HAS_CONSTEXPR - #include "layout/juce_GridItem.h" - #include "layout/juce_Grid.h" -#endif +#include "layout/juce_GridItem.h" +#include "layout/juce_Grid.h" diff --git a/modules/juce_gui_basics/juce_gui_basics.mm b/modules/juce_gui_basics/juce_gui_basics.mm index 3b11197f..769404c3 100644 --- a/modules/juce_gui_basics/juce_gui_basics.mm +++ b/modules/juce_gui_basics/juce_gui_basics.mm @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/keyboard/juce_CaretComponent.cpp b/modules/juce_gui_basics/keyboard/juce_CaretComponent.cpp index c1e0d1e9..7c6b83fb 100644 --- a/modules/juce_gui_basics/keyboard/juce_CaretComponent.cpp +++ b/modules/juce_gui_basics/keyboard/juce_CaretComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/keyboard/juce_CaretComponent.h b/modules/juce_gui_basics/keyboard/juce_CaretComponent.h index 2ceaa61b..a10b26c6 100644 --- a/modules/juce_gui_basics/keyboard/juce_CaretComponent.h +++ b/modules/juce_gui_basics/keyboard/juce_CaretComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/keyboard/juce_KeyListener.cpp b/modules/juce_gui_basics/keyboard/juce_KeyListener.cpp index 43c5bdb7..6ec38c21 100644 --- a/modules/juce_gui_basics/keyboard/juce_KeyListener.cpp +++ b/modules/juce_gui_basics/keyboard/juce_KeyListener.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/keyboard/juce_KeyListener.h b/modules/juce_gui_basics/keyboard/juce_KeyListener.h index c434e01b..d0f18fe9 100644 --- a/modules/juce_gui_basics/keyboard/juce_KeyListener.h +++ b/modules/juce_gui_basics/keyboard/juce_KeyListener.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/keyboard/juce_KeyPress.cpp b/modules/juce_gui_basics/keyboard/juce_KeyPress.cpp index e5f8a0f6..732303cb 100644 --- a/modules/juce_gui_basics/keyboard/juce_KeyPress.cpp +++ b/modules/juce_gui_basics/keyboard/juce_KeyPress.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/keyboard/juce_KeyPress.h b/modules/juce_gui_basics/keyboard/juce_KeyPress.h index d9ed4266..e9c1d014 100644 --- a/modules/juce_gui_basics/keyboard/juce_KeyPress.h +++ b/modules/juce_gui_basics/keyboard/juce_KeyPress.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -135,7 +134,7 @@ public: //============================================================================== /** Converts a textual key description to a KeyPress. - This attempts to decode a textual version of a keypress, e.g. "CTRL + C" or "SPACE". + This attempts to decode a textual version of a keypress, e.g. "ctrl + c" or "spacebar". This isn't designed to cope with any kind of input, but should be given the strings that are created by the getTextDescription() method. @@ -148,7 +147,7 @@ public: /** Creates a textual description of the key combination. - e.g. "CTRL + C" or "DELETE". + e.g. "ctrl + c" or "delete". To store a keypress in a file, use this method, along with createFromDescription() to retrieve it later. diff --git a/modules/juce_gui_basics/keyboard/juce_KeyboardFocusTraverser.cpp b/modules/juce_gui_basics/keyboard/juce_KeyboardFocusTraverser.cpp index a1fbf941..73b558df 100644 --- a/modules/juce_gui_basics/keyboard/juce_KeyboardFocusTraverser.cpp +++ b/modules/juce_gui_basics/keyboard/juce_KeyboardFocusTraverser.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/keyboard/juce_KeyboardFocusTraverser.h b/modules/juce_gui_basics/keyboard/juce_KeyboardFocusTraverser.h index a92bcc8f..eccfc259 100644 --- a/modules/juce_gui_basics/keyboard/juce_KeyboardFocusTraverser.h +++ b/modules/juce_gui_basics/keyboard/juce_KeyboardFocusTraverser.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/keyboard/juce_ModifierKeys.cpp b/modules/juce_gui_basics/keyboard/juce_ModifierKeys.cpp index 4af3471c..d636499e 100644 --- a/modules/juce_gui_basics/keyboard/juce_ModifierKeys.cpp +++ b/modules/juce_gui_basics/keyboard/juce_ModifierKeys.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/keyboard/juce_ModifierKeys.h b/modules/juce_gui_basics/keyboard/juce_ModifierKeys.h index ba8c813a..b4eb4488 100644 --- a/modules/juce_gui_basics/keyboard/juce_ModifierKeys.h +++ b/modules/juce_gui_basics/keyboard/juce_ModifierKeys.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/keyboard/juce_SystemClipboard.h b/modules/juce_gui_basics/keyboard/juce_SystemClipboard.h index 0cf97cd9..77f2b16b 100644 --- a/modules/juce_gui_basics/keyboard/juce_SystemClipboard.h +++ b/modules/juce_gui_basics/keyboard/juce_SystemClipboard.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/keyboard/juce_TextEditorKeyMapper.h b/modules/juce_gui_basics/keyboard/juce_TextEditorKeyMapper.h index 0c9789a1..1ba59e43 100644 --- a/modules/juce_gui_basics/keyboard/juce_TextEditorKeyMapper.h +++ b/modules/juce_gui_basics/keyboard/juce_TextEditorKeyMapper.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/keyboard/juce_TextInputTarget.h b/modules/juce_gui_basics/keyboard/juce_TextInputTarget.h index a5043dbc..249b20ea 100644 --- a/modules/juce_gui_basics/keyboard/juce_TextInputTarget.h +++ b/modules/juce_gui_basics/keyboard/juce_TextInputTarget.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/layout/juce_AnimatedPosition.h b/modules/juce_gui_basics/layout/juce_AnimatedPosition.h index e3d34fbf..cc75fc55 100644 --- a/modules/juce_gui_basics/layout/juce_AnimatedPosition.h +++ b/modules/juce_gui_basics/layout/juce_AnimatedPosition.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/layout/juce_AnimatedPositionBehaviours.h b/modules/juce_gui_basics/layout/juce_AnimatedPositionBehaviours.h index f75eaec7..a4ec21a8 100644 --- a/modules/juce_gui_basics/layout/juce_AnimatedPositionBehaviours.h +++ b/modules/juce_gui_basics/layout/juce_AnimatedPositionBehaviours.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/layout/juce_ComponentAnimator.cpp b/modules/juce_gui_basics/layout/juce_ComponentAnimator.cpp index 9306a1c8..06603058 100644 --- a/modules/juce_gui_basics/layout/juce_ComponentAnimator.cpp +++ b/modules/juce_gui_basics/layout/juce_ComponentAnimator.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -164,7 +163,7 @@ public: else jassertfalse; // seem to be trying to animate a component that's not visible.. - auto scale = (float) Desktop::getInstance().getDisplays().findDisplayForRect (getScreenBounds()).scale + auto scale = (float) Desktop::getInstance().getDisplays().getDisplayForRect (getScreenBounds())->scale * Component::getApproximateScaleFactorForComponent (&c); image = c.createComponentSnapshot (c.getLocalBounds(), false, scale); @@ -176,8 +175,8 @@ public: void paint (Graphics& g) override { g.setOpacity (1.0f); - g.drawImageTransformed (image, AffineTransform::scale (getWidth() / (float) image.getWidth(), - getHeight() / (float) image.getHeight()), false); + g.drawImageTransformed (image, AffineTransform::scale ((float) getWidth() / (float) jmax (1, image.getWidth()), + (float) getHeight() / (float) jmax (1, image.getHeight())), false); } private: diff --git a/modules/juce_gui_basics/layout/juce_ComponentAnimator.h b/modules/juce_gui_basics/layout/juce_ComponentAnimator.h index e6f2be8b..b5fe424d 100644 --- a/modules/juce_gui_basics/layout/juce_ComponentAnimator.h +++ b/modules/juce_gui_basics/layout/juce_ComponentAnimator.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/layout/juce_ComponentBoundsConstrainer.cpp b/modules/juce_gui_basics/layout/juce_ComponentBoundsConstrainer.cpp index 50486cdb..9ea63b21 100644 --- a/modules/juce_gui_basics/layout/juce_ComponentBoundsConstrainer.cpp +++ b/modules/juce_gui_basics/layout/juce_ComponentBoundsConstrainer.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -117,7 +116,7 @@ void ComponentBoundsConstrainer::setBoundsForComponent (Component* component, if (auto* peer = component->getPeer()) border = peer->getFrameSize(); - auto screenBounds = Desktop::getInstance().getDisplays().findDisplayForPoint (targetBounds.getCentre()).userArea; + auto screenBounds = Desktop::getInstance().getDisplays().getDisplayForPoint (targetBounds.getCentre())->userArea; limits = component->getLocalArea (nullptr, screenBounds) + component->getPosition(); } diff --git a/modules/juce_gui_basics/layout/juce_ComponentBoundsConstrainer.h b/modules/juce_gui_basics/layout/juce_ComponentBoundsConstrainer.h index 50633698..ce9eb3ff 100644 --- a/modules/juce_gui_basics/layout/juce_ComponentBoundsConstrainer.h +++ b/modules/juce_gui_basics/layout/juce_ComponentBoundsConstrainer.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/layout/juce_ComponentBuilder.cpp b/modules/juce_gui_basics/layout/juce_ComponentBuilder.cpp index 603e2f1f..a8caf626 100644 --- a/modules/juce_gui_basics/layout/juce_ComponentBuilder.cpp +++ b/modules/juce_gui_basics/layout/juce_ComponentBuilder.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/layout/juce_ComponentBuilder.h b/modules/juce_gui_basics/layout/juce_ComponentBuilder.h index 7a4cadaa..2b4b1969 100644 --- a/modules/juce_gui_basics/layout/juce_ComponentBuilder.h +++ b/modules/juce_gui_basics/layout/juce_ComponentBuilder.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.cpp b/modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.cpp index 448891b7..45d897e0 100644 --- a/modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.cpp +++ b/modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.h b/modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.h index 0e3107bb..02bfbcf4 100644 --- a/modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.h +++ b/modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/layout/juce_ConcertinaPanel.cpp b/modules/juce_gui_basics/layout/juce_ConcertinaPanel.cpp index 30ca8151..ed56282f 100644 --- a/modules/juce_gui_basics/layout/juce_ConcertinaPanel.cpp +++ b/modules/juce_gui_basics/layout/juce_ConcertinaPanel.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/layout/juce_ConcertinaPanel.h b/modules/juce_gui_basics/layout/juce_ConcertinaPanel.h index f6e0d66c..5bd717e0 100644 --- a/modules/juce_gui_basics/layout/juce_ConcertinaPanel.h +++ b/modules/juce_gui_basics/layout/juce_ConcertinaPanel.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/layout/juce_FlexBox.cpp b/modules/juce_gui_basics/layout/juce_FlexBox.cpp index 6163c9a3..6cd91c87 100644 --- a/modules/juce_gui_basics/layout/juce_FlexBox.cpp +++ b/modules/juce_gui_basics/layout/juce_FlexBox.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/layout/juce_FlexBox.h b/modules/juce_gui_basics/layout/juce_FlexBox.h index 4fc090e0..1d685a3c 100644 --- a/modules/juce_gui_basics/layout/juce_FlexBox.h +++ b/modules/juce_gui_basics/layout/juce_FlexBox.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/layout/juce_FlexItem.h b/modules/juce_gui_basics/layout/juce_FlexItem.h index 7b625aa5..6d96c5c7 100644 --- a/modules/juce_gui_basics/layout/juce_FlexItem.h +++ b/modules/juce_gui_basics/layout/juce_FlexItem.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/layout/juce_Grid.cpp b/modules/juce_gui_basics/layout/juce_Grid.cpp index e239e80c..82e43805 100644 --- a/modules/juce_gui_basics/layout/juce_Grid.cpp +++ b/modules/juce_gui_basics/layout/juce_Grid.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -441,25 +440,25 @@ struct Grid::PlacementHelpers if (alignContent == Grid::AlignContent::spaceBetween) { - const auto shift = ((rowNumber - 1) * (calculation.remainingHeight / float(numberOfRows - 1))); + const auto shift = ((float) (rowNumber - 1) * (calculation.remainingHeight / float(numberOfRows - 1))); area.setY (area.getY() + shift); } if (justifyContent == Grid::JustifyContent::spaceBetween) { - const auto shift = ((columnNumber - 1) * (calculation.remainingWidth / float(numberOfColumns - 1))); + const auto shift = ((float) (columnNumber - 1) * (calculation.remainingWidth / float(numberOfColumns - 1))); area.setX (area.getX() + shift); } if (alignContent == Grid::AlignContent::spaceEvenly) { - const auto shift = (rowNumber * (calculation.remainingHeight / float(numberOfRows + 1))); + const auto shift = ((float) rowNumber * (calculation.remainingHeight / float(numberOfRows + 1))); area.setY (area.getY() + shift); } if (justifyContent == Grid::JustifyContent::spaceEvenly) { - const auto shift = (columnNumber * (calculation.remainingWidth / float(numberOfColumns + 1))); + const auto shift = ((float) columnNumber * (calculation.remainingWidth / float(numberOfColumns + 1))); area.setX (area.getX() + shift); } @@ -467,7 +466,7 @@ struct Grid::PlacementHelpers { const auto inbetweenShift = calculation.remainingHeight / float(numberOfRows); const auto sidesShift = inbetweenShift / 2; - auto shift = (rowNumber - 1) * inbetweenShift + sidesShift; + auto shift = (float) (rowNumber - 1) * inbetweenShift + sidesShift; area.setY (area.getY() + shift); } @@ -476,7 +475,7 @@ struct Grid::PlacementHelpers { const auto inbetweenShift = calculation.remainingWidth / float(numberOfColumns); const auto sidesShift = inbetweenShift / 2; - auto shift = (columnNumber - 1) * inbetweenShift + sidesShift; + auto shift = (float) (columnNumber - 1) * inbetweenShift + sidesShift; area.setX (area.getX() + shift); } @@ -855,9 +854,9 @@ struct Grid::AutoPlacement Array<Grid::TrackInfo>& rows, const ItemPlacementArray& itemPlacementArray) { - auto isSpan = [](Grid::PlacementHelpers::LineRange r) -> bool { return std::abs (r.end - r.start) > 1; }; + auto isSpan = [] (Grid::PlacementHelpers::LineRange r) -> bool { return std::abs (r.end - r.start) > 1; }; - auto getHighestItemOnRow = [isSpan](int rowNumber, const ItemPlacementArray& itemPlacementArrayToUse) -> float + auto getHighestItemOnRow = [isSpan] (int rowNumber, const ItemPlacementArray& itemPlacementArrayToUse) -> float { float highestRowSize = 0.0f; @@ -868,7 +867,7 @@ struct Grid::AutoPlacement return highestRowSize; }; - auto getHighestItemOnColumn = [isSpan](int rowNumber, const ItemPlacementArray& itemPlacementArrayToUse) -> float + auto getHighestItemOnColumn = [isSpan] (int rowNumber, const ItemPlacementArray& itemPlacementArrayToUse) -> float { float highestColumnSize = 0.0f; for (const auto& i : itemPlacementArrayToUse) diff --git a/modules/juce_gui_basics/layout/juce_Grid.h b/modules/juce_gui_basics/layout/juce_Grid.h index 64c5d3e0..f7bac7ad 100644 --- a/modules/juce_gui_basics/layout/juce_Grid.h +++ b/modules/juce_gui_basics/layout/juce_Grid.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/layout/juce_GridItem.cpp b/modules/juce_gui_basics/layout/juce_GridItem.cpp index f85e0d85..9cb29bc9 100644 --- a/modules/juce_gui_basics/layout/juce_GridItem.cpp +++ b/modules/juce_gui_basics/layout/juce_GridItem.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/layout/juce_GridItem.h b/modules/juce_gui_basics/layout/juce_GridItem.h index 93613348..8dffbf36 100644 --- a/modules/juce_gui_basics/layout/juce_GridItem.h +++ b/modules/juce_gui_basics/layout/juce_GridItem.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/layout/juce_GroupComponent.cpp b/modules/juce_gui_basics/layout/juce_GroupComponent.cpp index c6323770..7ce52c77 100644 --- a/modules/juce_gui_basics/layout/juce_GroupComponent.cpp +++ b/modules/juce_gui_basics/layout/juce_GroupComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/layout/juce_GroupComponent.h b/modules/juce_gui_basics/layout/juce_GroupComponent.h index 2b00badd..c966a311 100644 --- a/modules/juce_gui_basics/layout/juce_GroupComponent.h +++ b/modules/juce_gui_basics/layout/juce_GroupComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/layout/juce_MultiDocumentPanel.cpp b/modules/juce_gui_basics/layout/juce_MultiDocumentPanel.cpp index 6988e43a..218b6b6f 100644 --- a/modules/juce_gui_basics/layout/juce_MultiDocumentPanel.cpp +++ b/modules/juce_gui_basics/layout/juce_MultiDocumentPanel.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/layout/juce_MultiDocumentPanel.h b/modules/juce_gui_basics/layout/juce_MultiDocumentPanel.h index c1b1f8bd..4ff2f330 100644 --- a/modules/juce_gui_basics/layout/juce_MultiDocumentPanel.h +++ b/modules/juce_gui_basics/layout/juce_MultiDocumentPanel.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/layout/juce_ResizableBorderComponent.cpp b/modules/juce_gui_basics/layout/juce_ResizableBorderComponent.cpp index 4e346b41..9f77521a 100644 --- a/modules/juce_gui_basics/layout/juce_ResizableBorderComponent.cpp +++ b/modules/juce_gui_basics/layout/juce_ResizableBorderComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/layout/juce_ResizableBorderComponent.h b/modules/juce_gui_basics/layout/juce_ResizableBorderComponent.h index 4939336d..d4274ef7 100644 --- a/modules/juce_gui_basics/layout/juce_ResizableBorderComponent.h +++ b/modules/juce_gui_basics/layout/juce_ResizableBorderComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -105,7 +104,7 @@ public: }; //============================================================================== - /** Creates a Zone from a combination of the flags in \enum Zones. */ + /** Creates a Zone from a combination of the flags in zoneFlags. */ explicit Zone (int zoneFlags) noexcept; Zone() noexcept; diff --git a/modules/juce_gui_basics/layout/juce_ResizableCornerComponent.cpp b/modules/juce_gui_basics/layout/juce_ResizableCornerComponent.cpp index e9350bf4..59b23abd 100644 --- a/modules/juce_gui_basics/layout/juce_ResizableCornerComponent.cpp +++ b/modules/juce_gui_basics/layout/juce_ResizableCornerComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/layout/juce_ResizableCornerComponent.h b/modules/juce_gui_basics/layout/juce_ResizableCornerComponent.h index c77c85c2..2d5ce443 100644 --- a/modules/juce_gui_basics/layout/juce_ResizableCornerComponent.h +++ b/modules/juce_gui_basics/layout/juce_ResizableCornerComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/layout/juce_ResizableEdgeComponent.cpp b/modules/juce_gui_basics/layout/juce_ResizableEdgeComponent.cpp index a62fbc3b..1a32a657 100644 --- a/modules/juce_gui_basics/layout/juce_ResizableEdgeComponent.cpp +++ b/modules/juce_gui_basics/layout/juce_ResizableEdgeComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/layout/juce_ResizableEdgeComponent.h b/modules/juce_gui_basics/layout/juce_ResizableEdgeComponent.h index f66549a1..69126ba2 100644 --- a/modules/juce_gui_basics/layout/juce_ResizableEdgeComponent.h +++ b/modules/juce_gui_basics/layout/juce_ResizableEdgeComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -38,7 +37,7 @@ namespace juce edge. Make sure you reposition the resizer component each time the parent's size changes, to keep it in the correct position. - @see ResizbleBorderComponent, ResizableCornerComponent + @see ResizableBorderComponent, ResizableCornerComponent @tags{GUI} */ diff --git a/modules/juce_gui_basics/layout/juce_ScrollBar.cpp b/modules/juce_gui_basics/layout/juce_ScrollBar.cpp index 62602d96..ddf1374d 100644 --- a/modules/juce_gui_basics/layout/juce_ScrollBar.cpp +++ b/modules/juce_gui_basics/layout/juce_ScrollBar.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/layout/juce_ScrollBar.h b/modules/juce_gui_basics/layout/juce_ScrollBar.h index fd229a47..1b5e9edb 100644 --- a/modules/juce_gui_basics/layout/juce_ScrollBar.h +++ b/modules/juce_gui_basics/layout/juce_ScrollBar.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/layout/juce_SidePanel.cpp b/modules/juce_gui_basics/layout/juce_SidePanel.cpp index 04a10dbb..c42fff17 100644 --- a/modules/juce_gui_basics/layout/juce_SidePanel.cpp +++ b/modules/juce_gui_basics/layout/juce_SidePanel.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/layout/juce_SidePanel.h b/modules/juce_gui_basics/layout/juce_SidePanel.h index 263f55ef..b531be08 100644 --- a/modules/juce_gui_basics/layout/juce_SidePanel.h +++ b/modules/juce_gui_basics/layout/juce_SidePanel.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -190,7 +189,7 @@ public: std::function<void()> onPanelMove; /** You can assign a lambda to this callback object and it will be called when the panel is shown or hidden. */ - std::function<void(bool)> onPanelShowHide; + std::function<void (bool)> onPanelShowHide; private: //============================================================================== diff --git a/modules/juce_gui_basics/layout/juce_StretchableLayoutManager.cpp b/modules/juce_gui_basics/layout/juce_StretchableLayoutManager.cpp index fee36cae..2d0d25e5 100644 --- a/modules/juce_gui_basics/layout/juce_StretchableLayoutManager.cpp +++ b/modules/juce_gui_basics/layout/juce_StretchableLayoutManager.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/layout/juce_StretchableLayoutManager.h b/modules/juce_gui_basics/layout/juce_StretchableLayoutManager.h index 32f10b19..bc7512db 100644 --- a/modules/juce_gui_basics/layout/juce_StretchableLayoutManager.h +++ b/modules/juce_gui_basics/layout/juce_StretchableLayoutManager.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/layout/juce_StretchableLayoutResizerBar.cpp b/modules/juce_gui_basics/layout/juce_StretchableLayoutResizerBar.cpp index dd009a7b..297fe7e5 100644 --- a/modules/juce_gui_basics/layout/juce_StretchableLayoutResizerBar.cpp +++ b/modules/juce_gui_basics/layout/juce_StretchableLayoutResizerBar.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/layout/juce_StretchableLayoutResizerBar.h b/modules/juce_gui_basics/layout/juce_StretchableLayoutResizerBar.h index 1e6bde36..2e0a5889 100644 --- a/modules/juce_gui_basics/layout/juce_StretchableLayoutResizerBar.h +++ b/modules/juce_gui_basics/layout/juce_StretchableLayoutResizerBar.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/layout/juce_StretchableObjectResizer.cpp b/modules/juce_gui_basics/layout/juce_StretchableObjectResizer.cpp index bf56dea7..3b85e53f 100644 --- a/modules/juce_gui_basics/layout/juce_StretchableObjectResizer.cpp +++ b/modules/juce_gui_basics/layout/juce_StretchableObjectResizer.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/layout/juce_StretchableObjectResizer.h b/modules/juce_gui_basics/layout/juce_StretchableObjectResizer.h index fe23771b..577b8f96 100644 --- a/modules/juce_gui_basics/layout/juce_StretchableObjectResizer.h +++ b/modules/juce_gui_basics/layout/juce_StretchableObjectResizer.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/layout/juce_TabbedButtonBar.cpp b/modules/juce_gui_basics/layout/juce_TabbedButtonBar.cpp index b45309cd..5c7cb9a7 100644 --- a/modules/juce_gui_basics/layout/juce_TabbedButtonBar.cpp +++ b/modules/juce_gui_basics/layout/juce_TabbedButtonBar.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/layout/juce_TabbedButtonBar.h b/modules/juce_gui_basics/layout/juce_TabbedButtonBar.h index 942ca5b4..48b962f9 100644 --- a/modules/juce_gui_basics/layout/juce_TabbedButtonBar.h +++ b/modules/juce_gui_basics/layout/juce_TabbedButtonBar.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/layout/juce_TabbedComponent.cpp b/modules/juce_gui_basics/layout/juce_TabbedComponent.cpp index 437c497d..4c602433 100644 --- a/modules/juce_gui_basics/layout/juce_TabbedComponent.cpp +++ b/modules/juce_gui_basics/layout/juce_TabbedComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -86,7 +85,6 @@ struct TabbedComponent::ButtonBar : public TabbedButtonBar JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ButtonBar) }; - //============================================================================== TabbedComponent::TabbedComponent (TabbedButtonBar::Orientation orientation) { diff --git a/modules/juce_gui_basics/layout/juce_TabbedComponent.h b/modules/juce_gui_basics/layout/juce_TabbedComponent.h index 7b43c787..e79c0b90 100644 --- a/modules/juce_gui_basics/layout/juce_TabbedComponent.h +++ b/modules/juce_gui_basics/layout/juce_TabbedComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/layout/juce_Viewport.cpp b/modules/juce_gui_basics/layout/juce_Viewport.cpp index 5dd8c252..e37dd362 100644 --- a/modules/juce_gui_basics/layout/juce_Viewport.cpp +++ b/modules/juce_gui_basics/layout/juce_Viewport.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -532,7 +531,7 @@ static int rescaleMouseWheelDistance (float distance, int singleStepSize) noexce if (distance == 0.0f) return 0; - distance *= 14.0f * singleStepSize; + distance *= 14.0f * (float) singleStepSize; return roundToInt (distance < 0 ? jmin (distance, -1.0f) : jmax (distance, 1.0f)); diff --git a/modules/juce_gui_basics/layout/juce_Viewport.h b/modules/juce_gui_basics/layout/juce_Viewport.h index 9ceddd6f..c91f337c 100644 --- a/modules/juce_gui_basics/layout/juce_Viewport.h +++ b/modules/juce_gui_basics/layout/juce_Viewport.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.cpp b/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.cpp index 553bbe02..f0bd1e12 100644 --- a/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.cpp +++ b/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.h b/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.h index 31d6e38e..a6210160 100644 --- a/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.h +++ b/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.cpp b/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.cpp index c4361fc7..738fed8c 100644 --- a/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.cpp +++ b/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -58,13 +57,13 @@ void LookAndFeel_V1::drawButtonBackground (Graphics& g, Button& button, const Co const int height = button.getHeight(); const float indent = 2.0f; - const int cornerSize = jmin (roundToInt (width * 0.4f), - roundToInt (height * 0.4f)); + const int cornerSize = jmin (roundToInt ((float) width * 0.4f), + roundToInt ((float) height * 0.4f)); Path p; p.addRoundedRectangle (indent, indent, - width - indent * 2.0f, - height - indent * 2.0f, + (float) width - indent * 2.0f, + (float) height - indent * 2.0f, (float) cornerSize); Colour bc (backgroundColour.withMultipliedSaturation (0.3f)); @@ -128,7 +127,7 @@ void LookAndFeel_V1::drawToggleButton (Graphics& g, ToggleButton& button, bool s const int tickWidth = jmin (20, button.getHeight() - 4); - drawTickBox (g, button, 4.0f, (button.getHeight() - tickWidth) * 0.5f, + drawTickBox (g, button, 4.0f, (float) (button.getHeight() - tickWidth) * 0.5f, (float) tickWidth, (float) tickWidth, button.getToggleState(), button.isEnabled(), @@ -136,7 +135,7 @@ void LookAndFeel_V1::drawToggleButton (Graphics& g, ToggleButton& button, bool s shouldDrawButtonAsDown); g.setColour (button.findColour (ToggleButton::textColourId)); - g.setFont (jmin (15.0f, button.getHeight() * 0.6f)); + g.setFont (jmin (15.0f, (float) button.getHeight() * 0.6f)); if (! button.isEnabled()) g.setOpacity (0.5f); @@ -172,7 +171,7 @@ void LookAndFeel_V1::drawProgressBar (Graphics& g, ProgressBar& progressBar, if (textToShow.isNotEmpty()) { g.setColour (Colour::contrasting (background, foreground)); - g.setFont (height * 0.6f); + g.setFont ((float) height * 0.6f); g.drawText (textToShow, 0, 0, width, height, Justification::centred, false); } @@ -192,22 +191,25 @@ void LookAndFeel_V1::drawScrollbarButton (Graphics& g, ScrollBar& bar, Path p; + const auto w = (float) width; + const auto h = (float) height; + if (buttonDirection == 0) - p.addTriangle (width * 0.5f, height * 0.2f, - width * 0.1f, height * 0.7f, - width * 0.9f, height * 0.7f); + p.addTriangle (w * 0.5f, h * 0.2f, + w * 0.1f, h * 0.7f, + w * 0.9f, h * 0.7f); else if (buttonDirection == 1) - p.addTriangle (width * 0.8f, height * 0.5f, - width * 0.3f, height * 0.1f, - width * 0.3f, height * 0.9f); + p.addTriangle (w * 0.8f, h * 0.5f, + w * 0.3f, h * 0.1f, + w * 0.3f, h * 0.9f); else if (buttonDirection == 2) - p.addTriangle (width * 0.5f, height * 0.8f, - width * 0.1f, height * 0.3f, - width * 0.9f, height * 0.3f); + p.addTriangle (w * 0.5f, h * 0.8f, + w * 0.1f, h * 0.3f, + w * 0.9f, h * 0.3f); else if (buttonDirection == 3) - p.addTriangle (width * 0.2f, height * 0.5f, - width * 0.7f, height * 0.1f, - width * 0.7f, height * 0.9f); + p.addTriangle (w * 0.2f, h * 0.5f, + w * 0.7f, h * 0.1f, + w * 0.7f, h * 0.9f); if (shouldDrawButtonAsDown) g.setColour (Colours::white); @@ -232,15 +234,15 @@ void LookAndFeel_V1::drawScrollbar (Graphics& g, ScrollBar& bar, g.setColour (bar.findColour (ScrollBar::thumbColourId) .withAlpha ((isMouseOver || isMouseDown) ? 0.4f : 0.15f)); - if (thumbSize > 0.0f) + if ((float) thumbSize > 0.0f) { Rectangle<int> thumb; if (isScrollbarVertical) { width -= 2; - g.fillRect (x + roundToInt (width * 0.35f), y, - roundToInt (width * 0.3f), height); + g.fillRect (x + roundToInt ((float) width * 0.35f), y, + roundToInt ((float) width * 0.3f), height); thumb.setBounds (x + 1, thumbStartPosition, width - 2, thumbSize); @@ -248,8 +250,8 @@ void LookAndFeel_V1::drawScrollbar (Graphics& g, ScrollBar& bar, else { height -= 2; - g.fillRect (x, y + roundToInt (height * 0.35f), - width, roundToInt (height * 0.3f)); + g.fillRect (x, y + roundToInt ((float) height * 0.35f), + width, roundToInt ((float) height * 0.3f)); thumb.setBounds (thumbStartPosition, y + 1, thumbSize, height - 2); @@ -267,20 +269,20 @@ void LookAndFeel_V1::drawScrollbar (Graphics& g, ScrollBar& bar, { for (int i = 3; --i >= 0;) { - const float linePos = thumbStartPosition + thumbSize / 2 + (i - 1) * 4.0f; + const float linePos = (float) thumbStartPosition + (float) thumbSize * 0.5f + (float) (i - 1) * 4.0f; g.setColour (Colours::black.withAlpha (0.15f)); if (isScrollbarVertical) { - g.drawLine (x + width * 0.2f, linePos, width * 0.8f, linePos); + g.drawLine ((float) x + (float) width * 0.2f, linePos, (float) width * 0.8f, linePos); g.setColour (Colours::white.withAlpha (0.15f)); - g.drawLine (width * 0.2f, linePos - 1, width * 0.8f, linePos - 1); + g.drawLine ((float) width * 0.2f, linePos - 1.0f, (float) width * 0.8f, linePos - 1.0f); } else { - g.drawLine (linePos, height * 0.2f, linePos, height * 0.8f); + g.drawLine (linePos, (float) height * 0.2f, linePos, (float) height * 0.8f); g.setColour (Colours::white.withAlpha (0.15f)); - g.drawLine (linePos - 1, height * 0.2f, linePos - 1, height * 0.8f); + g.drawLine (linePos - 1.0f, (float) height * 0.2f, linePos - 1.0f, (float) height * 0.8f); } } } @@ -336,16 +338,21 @@ void LookAndFeel_V1::drawComboBox (Graphics& g, int width, int height, const float arrowX = 0.2f; const float arrowH = 0.3f; + const auto x = (float) buttonX; + const auto y = (float) buttonY; + const auto w = (float) buttonW; + const auto h = (float) buttonH; + if (box.isEnabled()) { Path p; - p.addTriangle (buttonX + buttonW * 0.5f, buttonY + buttonH * (0.45f - arrowH), - buttonX + buttonW * (1.0f - arrowX), buttonY + buttonH * 0.45f, - buttonX + buttonW * arrowX, buttonY + buttonH * 0.45f); + p.addTriangle (x + w * 0.5f, y + h * (0.45f - arrowH), + x + w * (1.0f - arrowX), y + h * 0.45f, + x + w * arrowX, y + h * 0.45f); - p.addTriangle (buttonX + buttonW * 0.5f, buttonY + buttonH * (0.55f + arrowH), - buttonX + buttonW * (1.0f - arrowX), buttonY + buttonH * 0.55f, - buttonX + buttonW * arrowX, buttonY + buttonH * 0.55f); + p.addTriangle (x + w * 0.5f, y + h * (0.55f + arrowH), + x + w * (1.0f - arrowX), y + h * 0.55f, + x + w * arrowX, y + h * 0.55f); g.setColour (box.findColour ((isButtonDown) ? ComboBox::backgroundColourId : ComboBox::buttonColourId)); @@ -355,7 +362,7 @@ void LookAndFeel_V1::drawComboBox (Graphics& g, int width, int height, Font LookAndFeel_V1::getComboBoxFont (ComboBox& box) { - Font f (jmin (15.0f, box.getHeight() * 0.85f)); + Font f (jmin (15.0f, (float) box.getHeight() * 0.85f)); f.setHorizontalScale (0.9f); return f; } @@ -395,13 +402,13 @@ void LookAndFeel_V1::drawLinearSlider (Graphics& g, if (slider.isHorizontal()) { - g.fillRect (x, y + roundToInt (h * 0.6f), - w, roundToInt (h * 0.2f)); + g.fillRect (x, y + roundToInt ((float) h * 0.6f), + w, roundToInt ((float) h * 0.2f)); } else { - g.fillRect (x + roundToInt (w * 0.5f - jmin (3.0f, w * 0.1f)), y, - jmin (4, roundToInt (w * 0.2f)), h); + g.fillRect (x + roundToInt ((float) w * 0.5f - jmin (3.0f, (float) w * 0.1f)), y, + jmin (4, roundToInt ((float) w * 0.2f)), h); } float alpha = 0.35f; @@ -414,41 +421,47 @@ void LookAndFeel_V1::drawLinearSlider (Graphics& g, if (style == Slider::TwoValueVertical || style == Slider::ThreeValueVertical) { - drawTriangle (g, x + w * 0.5f + jmin (4.0f, w * 0.3f), minSliderPos, - x + w * 0.5f - jmin (8.0f, w * 0.4f), minSliderPos - 7.0f, - x + w * 0.5f - jmin (8.0f, w * 0.4f), minSliderPos, + drawTriangle (g, + (float) x + (float) w * 0.5f + jmin (4.0f, (float) w * 0.3f), minSliderPos, + (float) x + (float) w * 0.5f - jmin (8.0f, (float) w * 0.4f), minSliderPos - 7.0f, + (float) x + (float) w * 0.5f - jmin (8.0f, (float) w * 0.4f), minSliderPos, fill, outline); - drawTriangle (g, x + w * 0.5f + jmin (4.0f, w * 0.3f), maxSliderPos, - x + w * 0.5f - jmin (8.0f, w * 0.4f), maxSliderPos, - x + w * 0.5f - jmin (8.0f, w * 0.4f), maxSliderPos + 7.0f, + drawTriangle (g, + (float) x + (float) w * 0.5f + jmin (4.0f, (float) w * 0.3f), maxSliderPos, + (float) x + (float) w * 0.5f - jmin (8.0f, (float) w * 0.4f), maxSliderPos, + (float) x + (float) w * 0.5f - jmin (8.0f, (float) w * 0.4f), maxSliderPos + 7.0f, fill, outline); } else if (style == Slider::TwoValueHorizontal || style == Slider::ThreeValueHorizontal) { - drawTriangle (g, minSliderPos, y + h * 0.6f - jmin (4.0f, h * 0.3f), - minSliderPos - 7.0f, y + h * 0.9f , - minSliderPos, y + h * 0.9f, + drawTriangle (g, + minSliderPos, (float) y + (float) h * 0.6f - jmin (4.0f, (float) h * 0.3f), + minSliderPos - 7.0f, (float) y + (float) h * 0.9f, + minSliderPos, (float) y + (float) h * 0.9f, fill, outline); - drawTriangle (g, maxSliderPos, y + h * 0.6f - jmin (4.0f, h * 0.3f), - maxSliderPos, y + h * 0.9f, - maxSliderPos + 7.0f, y + h * 0.9f, + drawTriangle (g, + maxSliderPos, (float) y + (float) h * 0.6f - jmin (4.0f, (float) h * 0.3f), + maxSliderPos, (float) y + (float) h * 0.9f, + maxSliderPos + 7.0f, (float) y + (float) h * 0.9f, fill, outline); } if (style == Slider::LinearHorizontal || style == Slider::ThreeValueHorizontal) { - drawTriangle (g, sliderPos, y + h * 0.9f, - sliderPos - 7.0f, y + h * 0.2f, - sliderPos + 7.0f, y + h * 0.2f, + drawTriangle (g, + sliderPos, (float) y + (float) h * 0.9f, + sliderPos - 7.0f, (float) y + (float) h * 0.2f, + sliderPos + 7.0f, (float) y + (float) h * 0.2f, fill, outline); } else if (style == Slider::LinearVertical || style == Slider::ThreeValueVertical) { - drawTriangle (g, x + w * 0.5f - jmin (4.0f, w * 0.3f), sliderPos, - x + w * 0.5f + jmin (8.0f, w * 0.4f), sliderPos - 7.0f, - x + w * 0.5f + jmin (8.0f, w * 0.4f), sliderPos + 7.0f, + drawTriangle (g, + (float) x + (float) w * 0.5f - jmin (4.0f, (float) w * 0.3f), sliderPos, + (float) x + (float) w * 0.5f + jmin (8.0f, (float) w * 0.4f), sliderPos - 7.0f, + (float) x + (float) w * 0.5f + jmin (8.0f, (float) w * 0.4f), sliderPos + 7.0f, fill, outline); } } @@ -478,14 +491,14 @@ void LookAndFeel_V1::drawCornerResizer (Graphics& g, int w, int h, bool isMouseO g.setColour ((isMouseOver || isMouseDragging) ? Colours::lightgrey : Colours::darkgrey); - const float lineThickness = jmin (w, h) * 0.1f; + const float lineThickness = (float) jmin (w, h) * 0.1f; for (float i = 0.0f; i < 1.0f; i += 0.3f) { - g.drawLine (w * i, - h + 1.0f, - w + 1.0f, - h * i, + g.drawLine ((float) w * i, + (float) h + 1.0f, + (float) w + 1.0f, + (float) h * i, lineThickness); } } diff --git a/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.h b/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.h index bf3feb72..b6c05aed 100644 --- a/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.h +++ b/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.cpp b/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.cpp index 1818f73f..7e7af1da 100644 --- a/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.cpp +++ b/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -262,8 +261,8 @@ void LookAndFeel_V2::drawButtonBackground (Graphics& g, drawGlassLozenge (g, indentL, indentT, - width - indentL - indentR, - height - indentT - indentB, + (float) width - indentL - indentR, + (float) height - indentT - indentB, baseColour, outlineThickness, -1.0f, button.isConnectedOnLeft(), button.isConnectedOnRight(), @@ -273,7 +272,7 @@ void LookAndFeel_V2::drawButtonBackground (Graphics& g, Font LookAndFeel_V2::getTextButtonFont (TextButton&, int buttonHeight) { - return Font (jmin (15.0f, buttonHeight * 0.6f)); + return Font (jmin (15.0f, (float) buttonHeight * 0.6f)); } int LookAndFeel_V2::getTextButtonWidthToFitText (TextButton& b, int buttonHeight) @@ -345,10 +344,10 @@ void LookAndFeel_V2::drawToggleButton (Graphics& g, ToggleButton& button, g.drawRect (0, 0, button.getWidth(), button.getHeight()); } - float fontSize = jmin (15.0f, button.getHeight() * 0.75f); + float fontSize = jmin (15.0f, (float) button.getHeight() * 0.75f); const float tickWidth = fontSize * 1.1f; - drawTickBox (g, button, 4.0f, (button.getHeight() - tickWidth) * 0.5f, + drawTickBox (g, button, 4.0f, ((float) button.getHeight() - tickWidth) * 0.5f, tickWidth, tickWidth, button.getToggleState(), button.isEnabled(), @@ -369,7 +368,7 @@ void LookAndFeel_V2::drawToggleButton (Graphics& g, ToggleButton& button, void LookAndFeel_V2::changeToggleButtonWidthToFitText (ToggleButton& button) { - auto fontSize = jmin (15.0f, button.getHeight() * 0.75f); + auto fontSize = jmin (15.0f, (float) button.getHeight() * 0.75f); auto tickWidth = fontSize * 1.1f; Font font (fontSize); @@ -469,7 +468,7 @@ void LookAndFeel_V2::drawAlertBox (Graphics& g, AlertWindow& alert, colour = 0x55ff5555; character = '!'; - icon.addTriangle (iconRect.getX() + iconRect.getWidth() * 0.5f, (float) iconRect.getY(), + icon.addTriangle ((float) iconRect.getX() + (float) iconRect.getWidth() * 0.5f, (float) iconRect.getY(), (float) iconRect.getRight(), (float) iconRect.getBottom(), (float) iconRect.getX(), (float) iconRect.getBottom()); @@ -484,7 +483,7 @@ void LookAndFeel_V2::drawAlertBox (Graphics& g, AlertWindow& alert, } GlyphArrangement ga; - ga.addFittedText (Font (iconRect.getHeight() * 0.9f, Font::bold), + ga.addFittedText (Font ((float) iconRect.getHeight() * 0.9f, Font::bold), String::charToString ((juce_wchar) (uint8) character), (float) iconRect.getX(), (float) iconRect.getY(), (float) iconRect.getWidth(), (float) iconRect.getHeight(), @@ -578,11 +577,11 @@ void LookAndFeel_V2::drawProgressBar (Graphics& g, ProgressBar& progressBar, Path p; - for (float x = (float) (- position); x < width + stripeWidth; x += stripeWidth) + for (float x = (float) (- position); x < (float) (width + stripeWidth); x += (float) stripeWidth) p.addQuadrilateral (x, 0.0f, - x + stripeWidth * 0.5f, 0.0f, + x + (float) stripeWidth * 0.5f, 0.0f, x, (float) height, - x - stripeWidth * 0.5f, (float) height); + x - (float) stripeWidth * 0.5f, (float) height); Image im (Image::ARGB, width, height, true); @@ -603,7 +602,7 @@ void LookAndFeel_V2::drawProgressBar (Graphics& g, ProgressBar& progressBar, if (textToShow.isNotEmpty()) { g.setColour (Colour::contrasting (background, foreground)); - g.setFont (height * 0.6f); + g.setFont ((float) height * 0.6f); g.drawText (textToShow, 0, 0, width, height, Justification::centred, false); } @@ -611,15 +610,15 @@ void LookAndFeel_V2::drawProgressBar (Graphics& g, ProgressBar& progressBar, void LookAndFeel_V2::drawSpinningWaitAnimation (Graphics& g, const Colour& colour, int x, int y, int w, int h) { - const float radius = jmin (w, h) * 0.4f; + const float radius = (float) jmin (w, h) * 0.4f; const float thickness = radius * 0.15f; Path p; p.addRoundedRectangle (radius * 0.4f, thickness * -0.5f, radius * 0.6f, thickness, thickness * 0.5f); - const float cx = x + w * 0.5f; - const float cy = y + h * 0.5f; + const float cx = (float) x + (float) w * 0.5f; + const float cy = (float) y + (float) h * 0.5f; const uint32 animationIndex = (Time::getMillisecondCounter() / (1000 / 10)) % 12; @@ -627,8 +626,8 @@ void LookAndFeel_V2::drawSpinningWaitAnimation (Graphics& g, const Colour& colou { const uint32 n = (i + 12 - animationIndex) % 12; - g.setColour (colour.withMultipliedAlpha ((n + 1) / 12.0f)); - g.fillPath (p, AffineTransform::rotation (i * (MathConstants<float>::pi / 6.0f)) + g.setColour (colour.withMultipliedAlpha ((float) (n + 1) / 12.0f)); + g.fillPath (p, AffineTransform::rotation ((float) i * (MathConstants<float>::pi / 6.0f)) .translated (cx, cy)); } } @@ -651,22 +650,25 @@ void LookAndFeel_V2::drawScrollbarButton (Graphics& g, ScrollBar& scrollbar, { Path p; + const auto w = (float) width; + const auto h = (float) height; + if (buttonDirection == 0) - p.addTriangle (width * 0.5f, height * 0.2f, - width * 0.1f, height * 0.7f, - width * 0.9f, height * 0.7f); + p.addTriangle (w * 0.5f, h * 0.2f, + w * 0.1f, h * 0.7f, + w * 0.9f, h * 0.7f); else if (buttonDirection == 1) - p.addTriangle (width * 0.8f, height * 0.5f, - width * 0.3f, height * 0.1f, - width * 0.3f, height * 0.9f); + p.addTriangle (w * 0.8f, h * 0.5f, + w * 0.3f, h * 0.1f, + w * 0.3f, h * 0.9f); else if (buttonDirection == 2) - p.addTriangle (width * 0.5f, height * 0.8f, - width * 0.1f, height * 0.3f, - width * 0.9f, height * 0.3f); + p.addTriangle (w * 0.5f, h * 0.8f, + w * 0.1f, h * 0.3f, + w * 0.9f, h * 0.3f); else if (buttonDirection == 3) - p.addTriangle (width * 0.2f, height * 0.5f, - width * 0.7f, height * 0.1f, - width * 0.7f, height * 0.9f); + p.addTriangle (w * 0.2f, h * 0.5f, + w * 0.7f, h * 0.1f, + w * 0.7f, h * 0.9f); if (shouldDrawButtonAsDown) g.setColour (scrollbar.findColour (ScrollBar::thumbColourId).contrasting (0.2f)); @@ -702,37 +704,37 @@ void LookAndFeel_V2::drawScrollbar (Graphics& g, if (isScrollbarVertical) { - slotPath.addRoundedRectangle (x + slotIndent, - y + slotIndent, - width - slotIndentx2, - height - slotIndentx2, - (width - slotIndentx2) * 0.5f); + slotPath.addRoundedRectangle ((float) x + slotIndent, + (float) y + slotIndent, + (float) width - slotIndentx2, + (float) height - slotIndentx2, + ((float) width - slotIndentx2) * 0.5f); if (thumbSize > 0) - thumbPath.addRoundedRectangle (x + thumbIndent, - thumbStartPosition + thumbIndent, - width - thumbIndentx2, - thumbSize - thumbIndentx2, - (width - thumbIndentx2) * 0.5f); + thumbPath.addRoundedRectangle ((float) x + thumbIndent, + (float) thumbStartPosition + thumbIndent, + (float) width - thumbIndentx2, + (float) thumbSize - thumbIndentx2, + ((float) width - thumbIndentx2) * 0.5f); gx1 = (float) x; - gx2 = x + width * 0.7f; + gx2 = (float) x + (float) width * 0.7f; } else { - slotPath.addRoundedRectangle (x + slotIndent, - y + slotIndent, - width - slotIndentx2, - height - slotIndentx2, - (height - slotIndentx2) * 0.5f); + slotPath.addRoundedRectangle ((float) x + slotIndent, + (float) y + slotIndent, + (float) width - slotIndentx2, + (float) height - slotIndentx2, + ((float) height - slotIndentx2) * 0.5f); if (thumbSize > 0) - thumbPath.addRoundedRectangle (thumbStartPosition + thumbIndent, - y + thumbIndent, - thumbSize - thumbIndentx2, - height - thumbIndentx2, - (height - thumbIndentx2) * 0.5f); + thumbPath.addRoundedRectangle ((float) thumbStartPosition + thumbIndent, + (float) y + thumbIndent, + (float) thumbSize - thumbIndentx2, + (float) height - thumbIndentx2, + ((float) height - thumbIndentx2) * 0.5f); gy1 = (float) y; - gy2 = y + height * 0.7f; + gy2 = (float) y + (float) height * 0.7f; } const Colour thumbColour (scrollbar.findColour (ScrollBar::thumbColourId)); @@ -755,13 +757,13 @@ void LookAndFeel_V2::drawScrollbar (Graphics& g, if (isScrollbarVertical) { - gx1 = x + width * 0.6f; - gx2 = (float) x + width; + gx1 = (float) x + (float) width * 0.6f; + gx2 = (float) x + (float) width; } else { - gy1 = y + height * 0.6f; - gy2 = (float) y + height; + gy1 = (float) y + (float) height * 0.6f; + gy2 = (float) y + (float) height; } g.setGradientFill (ColourGradient (Colours::transparentBlack,gx1, gy1, @@ -827,13 +829,13 @@ void LookAndFeel_V2::drawTreeviewPlusMinusBox (Graphics& g, const Rectangle<floa g.setColour (Colour (0x80000000)); g.drawRect (boxArea); - auto size = boxSize / 2 + 1.0f; + auto size = (float) boxSize * 0.5f + 1.0f; auto centre = (float) (boxSize / 2); - g.fillRect (x + (boxSize - size) * 0.5f, y + centre, size, 1.0f); + g.fillRect ((float) x + ((float) boxSize - size) * 0.5f, (float) y + centre, size, 1.0f); if (! isOpen) - g.fillRect (x + centre, y + (boxSize - size) * 0.5f, 1.0f, size); + g.fillRect ((float) x + centre, (float) y + ((float) boxSize - size) * 0.5f, 1.0f, size); } bool LookAndFeel_V2::areLinesDrawnForTreeView (TreeView&) @@ -880,14 +882,28 @@ void LookAndFeel_V2::getIdealPopupMenuItemSize (const String& text, const bool i { Font font (getPopupMenuFont()); - if (standardMenuItemHeight > 0 && font.getHeight() > standardMenuItemHeight / 1.3f) - font.setHeight (standardMenuItemHeight / 1.3f); + if (standardMenuItemHeight > 0 && font.getHeight() > (float) standardMenuItemHeight / 1.3f) + font.setHeight ((float) standardMenuItemHeight / 1.3f); idealHeight = standardMenuItemHeight > 0 ? standardMenuItemHeight : roundToInt (font.getHeight() * 1.3f); idealWidth = font.getStringWidth (text) + idealHeight * 2; } } +void LookAndFeel_V2::getIdealPopupMenuItemSizeWithOptions (const String& text, + bool isSeparator, + int standardMenuItemHeight, + int& idealWidth, + int& idealHeight, + const PopupMenu::Options&) +{ + getIdealPopupMenuItemSize (text, + isSeparator, + standardMenuItemHeight, + idealWidth, + idealHeight); +} + void LookAndFeel_V2::drawPopupMenuBackground (Graphics& g, int width, int height) { auto background = findColour (PopupMenu::backgroundColourId); @@ -904,21 +920,29 @@ void LookAndFeel_V2::drawPopupMenuBackground (Graphics& g, int width, int height #endif } +void LookAndFeel_V2::drawPopupMenuBackgroundWithOptions (Graphics& g, + int width, + int height, + const PopupMenu::Options&) +{ + drawPopupMenuBackground (g, width, height); +} + void LookAndFeel_V2::drawPopupMenuUpDownArrow (Graphics& g, int width, int height, bool isScrollUpArrow) { auto background = findColour (PopupMenu::backgroundColourId); - g.setGradientFill (ColourGradient (background, 0.0f, height * 0.5f, + g.setGradientFill (ColourGradient (background, 0.0f, (float) height * 0.5f, background.withAlpha (0.0f), 0.0f, isScrollUpArrow ? ((float) height) : 0.0f, false)); g.fillRect (1, 1, width - 2, height - 2); - auto hw = width * 0.5f; - auto arrowW = height * 0.3f; - auto y1 = height * (isScrollUpArrow ? 0.6f : 0.3f); - auto y2 = height * (isScrollUpArrow ? 0.3f : 0.6f); + auto hw = (float) width * 0.5f; + auto arrowW = (float) height * 0.3f; + auto y1 = (float) height * (isScrollUpArrow ? 0.6f : 0.3f); + auto y2 = (float) height * (isScrollUpArrow ? 0.3f : 0.6f); Path p; p.addTriangle (hw - arrowW, y1, @@ -929,6 +953,14 @@ void LookAndFeel_V2::drawPopupMenuUpDownArrow (Graphics& g, int width, int heigh g.fillPath (p); } +void LookAndFeel_V2::drawPopupMenuUpDownArrowWithOptions (Graphics& g, + int width, int height, + bool isScrollUpArrow, + const PopupMenu::Options&) +{ + drawPopupMenuUpDownArrow (g, width, height, isScrollUpArrow); +} + void LookAndFeel_V2::drawPopupMenuItem (Graphics& g, const Rectangle<int>& area, const bool isSeparator, const bool isActive, const bool isHighlighted, const bool isTicked, @@ -973,7 +1005,7 @@ void LookAndFeel_V2::drawPopupMenuItem (Graphics& g, const Rectangle<int>& area, Font font (getPopupMenuFont()); - auto maxFontHeight = area.getHeight() / 1.3f; + auto maxFontHeight = (float) area.getHeight() / 1.3f; if (font.getHeight() > maxFontHeight) font.setHeight (maxFontHeight); @@ -1022,16 +1054,47 @@ void LookAndFeel_V2::drawPopupMenuItem (Graphics& g, const Rectangle<int>& area, } } -void LookAndFeel_V2::drawPopupMenuSectionHeader (Graphics& g, const Rectangle<int>& area, const String& sectionName) +void LookAndFeel_V2::drawPopupMenuItemWithOptions (Graphics& g, const Rectangle<int>& area, + bool isHighlighted, + const PopupMenu::Item& item, + const PopupMenu::Options&) +{ + const auto colour = item.colour != Colour() ? &item.colour : nullptr; + const auto hasSubMenu = item.subMenu != nullptr + && (item.itemID == 0 || item.subMenu->getNumItems() > 0); + + drawPopupMenuItem (g, + area, + item.isSeparator, + item.isEnabled, + isHighlighted, + item.isTicked, + hasSubMenu, + item.text, + item.shortcutKeyDescription, + item.image.get(), + colour); +} + +void LookAndFeel_V2::drawPopupMenuSectionHeader (Graphics& g, + const Rectangle<int>& area, + const String& sectionName) { g.setFont (getPopupMenuFont().boldened()); g.setColour (findColour (PopupMenu::headerTextColourId)); g.drawFittedText (sectionName, - area.getX() + 12, area.getY(), area.getWidth() - 16, (int) (area.getHeight() * 0.8f), + area.getX() + 12, area.getY(), area.getWidth() - 16, (int) ((float) area.getHeight() * 0.8f), Justification::bottomLeft, 1); } +void LookAndFeel_V2::drawPopupMenuSectionHeaderWithOptions (Graphics& g, const Rectangle<int>& area, + const String& sectionName, + const PopupMenu::Options&) +{ + drawPopupMenuSectionHeader (g, area, sectionName); +} + //============================================================================== int LookAndFeel_V2::getMenuWindowFlags() { @@ -1044,7 +1107,7 @@ void LookAndFeel_V2::drawMenuBarBackground (Graphics& g, int width, int height, false, false, false); if (menuBar.isEnabled()) - drawShinyButtonShape (g, -4.0f, 0.0f, width + 8.0f, (float) height, + drawShinyButtonShape (g, -4.0f, 0.0f, (float) width + 8.0f, (float) height, 0.0f, baseColour, 0.4f, true, true, true, true); else g.fillAll (baseColour); @@ -1052,7 +1115,7 @@ void LookAndFeel_V2::drawMenuBarBackground (Graphics& g, int width, int height, Font LookAndFeel_V2::getMenuBarFont (MenuBarComponent& menuBar, int /*itemIndex*/, const String& /*itemText*/) { - return Font (menuBar.getHeight() * 0.7f); + return Font ((float) menuBar.getHeight() * 0.7f); } int LookAndFeel_V2::getMenuBarItemWidth (MenuBarComponent& menuBar, int itemIndex, const String& itemText) @@ -1096,6 +1159,20 @@ bool LookAndFeel_V2::shouldPopupMenuScaleWithTargetComponent (const PopupMenu::O int LookAndFeel_V2::getPopupMenuBorderSize() { return 2; } +int LookAndFeel_V2::getPopupMenuBorderSizeWithOptions (const PopupMenu::Options&) +{ + return getPopupMenuBorderSize(); +} + +void LookAndFeel_V2::drawPopupMenuColumnSeparatorWithOptions (Graphics&, + const Rectangle<int>&, + const PopupMenu::Options&) {} + +int LookAndFeel_V2::getPopupMenuColumnSeparatorWidthWithOptions (const PopupMenu::Options&) +{ + return 0; +} + //============================================================================== void LookAndFeel_V2::fillTextEditorBackground (Graphics& g, int /*width*/, int /*height*/, TextEditor& textEditor) { @@ -1159,8 +1236,8 @@ void LookAndFeel_V2::drawComboBox (Graphics& g, int width, int height, const boo .withMultipliedAlpha (box.isEnabled() ? 1.0f : 0.5f); drawGlassLozenge (g, - buttonX + outlineThickness, buttonY + outlineThickness, - buttonW - outlineThickness * 2.0f, buttonH - outlineThickness * 2.0f, + (float) buttonX + outlineThickness, (float) buttonY + outlineThickness, + (float) buttonW - outlineThickness * 2.0f, (float) buttonH - outlineThickness * 2.0f, baseColour, outlineThickness, -1.0f, true, true, true, true); @@ -1169,14 +1246,19 @@ void LookAndFeel_V2::drawComboBox (Graphics& g, int width, int height, const boo const float arrowX = 0.3f; const float arrowH = 0.2f; + const auto x = (float) buttonX; + const auto y = (float) buttonY; + const auto w = (float) buttonW; + const auto h = (float) buttonH; + Path p; - p.addTriangle (buttonX + buttonW * 0.5f, buttonY + buttonH * (0.45f - arrowH), - buttonX + buttonW * (1.0f - arrowX), buttonY + buttonH * 0.45f, - buttonX + buttonW * arrowX, buttonY + buttonH * 0.45f); + p.addTriangle (x + w * 0.5f, y + h * (0.45f - arrowH), + x + w * (1.0f - arrowX), y + h * 0.45f, + x + w * arrowX, y + h * 0.45f); - p.addTriangle (buttonX + buttonW * 0.5f, buttonY + buttonH * (0.55f + arrowH), - buttonX + buttonW * (1.0f - arrowX), buttonY + buttonH * 0.55f, - buttonX + buttonW * arrowX, buttonY + buttonH * 0.55f); + p.addTriangle (x + w * 0.5f, y + h * (0.55f + arrowH), + x + w * (1.0f - arrowX), y + h * 0.55f, + x + w * arrowX, y + h * 0.55f); g.setColour (box.findColour (ComboBox::arrowColourId)); g.fillPath (p); @@ -1185,7 +1267,7 @@ void LookAndFeel_V2::drawComboBox (Graphics& g, int width, int height, const boo Font LookAndFeel_V2::getComboBoxFont (ComboBox& box) { - return Font (jmin (15.0f, box.getHeight() * 0.85f)); + return Font (jmin (15.0f, (float) box.getHeight() * 0.85f)); } Label* LookAndFeel_V2::createComboBoxTextBox (ComboBox&) @@ -1222,7 +1304,7 @@ void LookAndFeel_V2::drawComboBoxTextWhenNothingSelected (Graphics& g, ComboBox& auto textArea = getLabelBorderSize (label).subtractedFrom (label.getLocalBounds()); g.drawFittedText (box.getTextWhenNothingSelected(), textArea, label.getJustificationType(), - jmax (1, (int) (textArea.getHeight() / font.getHeight())), + jmax (1, (int) ((float) textArea.getHeight() / font.getHeight())), label.getMinimumHorizontalScale()); } @@ -1247,7 +1329,7 @@ void LookAndFeel_V2::drawLabel (Graphics& g, Label& label) auto textArea = getLabelBorderSize (label).subtractedFrom (label.getLocalBounds()); g.drawFittedText (label.getText(), textArea, label.getJustificationType(), - jmax (1, (int) (textArea.getHeight() / font.getHeight())), + jmax (1, (int) ((float) textArea.getHeight() / font.getHeight())), label.getMinimumHorizontalScale()); g.setColour (label.findColour (Label::outlineColourId).withMultipliedAlpha (alpha)); @@ -1281,24 +1363,24 @@ void LookAndFeel_V2::drawLinearSliderBackground (Graphics& g, int x, int y, int if (slider.isHorizontal()) { - const float iy = y + height * 0.5f - sliderRadius * 0.5f; + const float iy = (float) y + (float) height * 0.5f - sliderRadius * 0.5f; const float ih = sliderRadius; g.setGradientFill (ColourGradient::vertical (gradCol1, iy, gradCol2, iy + ih)); - indent.addRoundedRectangle (x - sliderRadius * 0.5f, iy, - width + sliderRadius, ih, + indent.addRoundedRectangle ((float) x - sliderRadius * 0.5f, iy, + (float) width + sliderRadius, ih, 5.0f); } else { - const float ix = x + width * 0.5f - sliderRadius * 0.5f; + const float ix = (float) x + (float) width * 0.5f - sliderRadius * 0.5f; const float iw = sliderRadius; g.setGradientFill (ColourGradient::horizontal (gradCol1, ix, gradCol2, ix + iw)); - indent.addRoundedRectangle (ix, y - sliderRadius * 0.5f, - iw, height + sliderRadius, + indent.addRoundedRectangle (ix, (float) y - sliderRadius * 0.5f, + iw, (float) height + sliderRadius, 5.0f); } @@ -1327,13 +1409,13 @@ void LookAndFeel_V2::drawLinearSliderThumb (Graphics& g, int x, int y, int width if (style == Slider::LinearVertical) { - kx = x + width * 0.5f; + kx = (float) x + (float) width * 0.5f; ky = sliderPos; } else { kx = sliderPos; - ky = y + height * 0.5f; + ky = (float) y + (float) height * 0.5f; } drawGlassSphere (g, @@ -1346,7 +1428,7 @@ void LookAndFeel_V2::drawLinearSliderThumb (Graphics& g, int x, int y, int width { if (style == Slider::ThreeValueVertical) { - drawGlassSphere (g, x + width * 0.5f - sliderRadius, + drawGlassSphere (g, (float) x + (float) width * 0.5f - sliderRadius, sliderPos - sliderRadius, sliderRadius * 2.0f, knobColour, outlineThickness); @@ -1354,33 +1436,44 @@ void LookAndFeel_V2::drawLinearSliderThumb (Graphics& g, int x, int y, int width else if (style == Slider::ThreeValueHorizontal) { drawGlassSphere (g,sliderPos - sliderRadius, - y + height * 0.5f - sliderRadius, + (float) y + (float) height * 0.5f - sliderRadius, sliderRadius * 2.0f, knobColour, outlineThickness); } if (style == Slider::TwoValueVertical || style == Slider::ThreeValueVertical) { - auto sr = jmin (sliderRadius, width * 0.4f); + auto sr = jmin (sliderRadius, (float) width * 0.4f); - drawGlassPointer (g, jmax (0.0f, x + width * 0.5f - sliderRadius * 2.0f), + drawGlassPointer (g, jmax (0.0f, (float) x + (float) width * 0.5f - sliderRadius * 2.0f), minSliderPos - sliderRadius, sliderRadius * 2.0f, knobColour, outlineThickness, 1); - drawGlassPointer (g, jmin (x + width - sliderRadius * 2.0f, x + width * 0.5f), maxSliderPos - sr, - sliderRadius * 2.0f, knobColour, outlineThickness, 3); + drawGlassPointer (g, + jmin ((float) x + (float) width - sliderRadius * 2.0f, + (float) x + (float) width * 0.5f), + maxSliderPos - sr, + sliderRadius * 2.0f, + knobColour, + outlineThickness, + 3); } else if (style == Slider::TwoValueHorizontal || style == Slider::ThreeValueHorizontal) { - auto sr = jmin (sliderRadius, height * 0.4f); + auto sr = jmin (sliderRadius, (float) height * 0.4f); drawGlassPointer (g, minSliderPos - sr, - jmax (0.0f, y + height * 0.5f - sliderRadius * 2.0f), + jmax (0.0f, (float) y + (float) height * 0.5f - sliderRadius * 2.0f), sliderRadius * 2.0f, knobColour, outlineThickness, 2); - drawGlassPointer (g, maxSliderPos - sliderRadius, - jmin (y + height - sliderRadius * 2.0f, y + height * 0.5f), - sliderRadius * 2.0f, knobColour, outlineThickness, 4); + drawGlassPointer (g, + maxSliderPos - sliderRadius, + jmin ((float) y + (float) height - sliderRadius * 2.0f, + (float) y + (float) height * 0.5f), + sliderRadius * 2.0f, + knobColour, + outlineThickness, + 4); } } } @@ -1405,8 +1498,8 @@ void LookAndFeel_V2::drawLinearSlider (Graphics& g, int x, int y, int width, int style == Slider::LinearBarVertical ? sliderPos : (float) y, style == Slider::LinearBarVertical ? (float) width - : (sliderPos - x), - style == Slider::LinearBarVertical ? (height - sliderPos) + : (sliderPos - (float) x), + style == Slider::LinearBarVertical ? ((float) height - sliderPos) : (float) height, 0.0f, baseColour, slider.isEnabled() ? 0.9f : 0.3f, @@ -1429,9 +1522,9 @@ int LookAndFeel_V2::getSliderThumbRadius (Slider& slider) void LookAndFeel_V2::drawRotarySlider (Graphics& g, int x, int y, int width, int height, float sliderPos, const float rotaryStartAngle, const float rotaryEndAngle, Slider& slider) { - const float radius = jmin (width / 2, height / 2) - 2.0f; - const float centreX = x + width * 0.5f; - const float centreY = y + height * 0.5f; + const float radius = jmin ((float) width * 0.5f, (float) height * 0.5f) - 2.0f; + const float centreX = (float) x + (float) width * 0.5f; + const float centreY = (float) y + (float) height * 0.5f; const float rx = centreX - radius; const float ry = centreY - radius; const float rw = radius * 2.0f; @@ -1673,7 +1766,7 @@ void LookAndFeel_V2::drawConcertinaPanelHeader (Graphics& g, const Rectangle<int g.drawRect (area); g.setColour (Colours::white); - g.setFont (Font (area.getHeight() * 0.7f).boldened()); + g.setFont (Font ((float) area.getHeight() * 0.7f).boldened()); g.drawFittedText (panel.getName(), 4, 0, area.getWidth() - 6, area.getHeight(), Justification::centredLeft, 1); } @@ -1707,24 +1800,24 @@ void LookAndFeel_V2::drawImageButton (Graphics& g, Image* image, //============================================================================== void LookAndFeel_V2::drawCornerResizer (Graphics& g, int w, int h, bool /*isMouseOver*/, bool /*isMouseDragging*/) { - auto lineThickness = jmin (w, h) * 0.075f; + auto lineThickness = jmin ((float) w, (float) h) * 0.075f; for (float i = 0.0f; i < 1.0f; i += 0.3f) { g.setColour (Colours::lightgrey); - g.drawLine (w * i, - h + 1.0f, - w + 1.0f, - h * i, + g.drawLine ((float) w * i, + (float) h + 1.0f, + (float) w + 1.0f, + (float) h * i, lineThickness); g.setColour (Colours::darkgrey); - g.drawLine (w * i + lineThickness, - h + 1.0f, - w + 1.0f, - h * i + lineThickness, + g.drawLine ((float) w * i + lineThickness, + (float) h + 1.0f, + (float) w + 1.0f, + (float) h * i + lineThickness, lineThickness); } } @@ -1773,7 +1866,7 @@ void LookAndFeel_V2::drawDocumentWindowTitleBar (DocumentWindow& window, Graphic window.getBackgroundColour().contrasting (isActive ? 0.15f : 0.05f), (float) h)); g.fillAll(); - Font font (h * 0.65f, Font::bold); + Font font ((float) h * 0.65f, Font::bold); g.setFont (font); int textW = font.getStringWidth (window.getName()); @@ -1837,12 +1930,12 @@ public: if (getWidth() < getHeight()) { diam = (float) getWidth(); - y = (getHeight() - getWidth()) * 0.5f; + y = (float) (getHeight() - getWidth()) * 0.5f; } else { diam = (float) getHeight(); - y = (getWidth() - getHeight()) * 0.5f; + y = (float) (getWidth() - getHeight()) * 0.5f; } x += diam * 0.05f; @@ -1973,9 +2066,9 @@ void LookAndFeel_V2::drawStretchableLayoutResizerBar (Graphics& g, int w, int h, alpha = 1.0f; } - auto cx = w * 0.5f; - auto cy = h * 0.5f; - auto cr = jmin (w, h) * 0.4f; + auto cx = (float) w * 0.5f; + auto cy = (float) h * 0.5f; + auto cr = (float) jmin (w, h) * 0.4f; g.setGradientFill (ColourGradient (Colours::white.withAlpha (alpha), cx + cr * 0.1f, cy + cr, Colours::black.withAlpha (alpha), cx, cy - cr * 4.0f, @@ -1999,12 +2092,15 @@ void LookAndFeel_V2::drawGroupComponentOutline (Graphics& g, int width, int heig Path p; auto x = indent; auto y = f.getAscent() - 3.0f; - auto w = jmax (0.0f, width - x * 2.0f); - auto h = jmax (0.0f, height - y - indent); + auto w = jmax (0.0f, (float) width - x * 2.0f); + auto h = jmax (0.0f, (float) height - y - indent); cs = jmin (cs, w * 0.5f, h * 0.5f); auto cs2 = 2.0f * cs; - auto textW = text.isEmpty() ? 0 : jlimit (0.0f, jmax (0.0f, w - cs2 - textEdgeGap * 2), f.getStringWidth (text) + textEdgeGap * 2.0f); + auto textW = text.isEmpty() ? 0 + : jlimit (0.0f, + jmax (0.0f, w - cs2 - textEdgeGap * 2), + (float) f.getStringWidth (text) + textEdgeGap * 2.0f); auto textX = cs + textEdgeGap; if (position.testFlags (Justification::horizontallyCentred)) @@ -2057,7 +2153,7 @@ int LookAndFeel_V2::getTabButtonSpaceAroundImage() int LookAndFeel_V2::getTabButtonBestWidth (TabBarButton& button, int tabDepth) { - int width = Font (tabDepth * 0.6f).getStringWidth (button.getButtonText().trim()) + int width = Font ((float) tabDepth * 0.6f).getStringWidth (button.getButtonText().trim()) + getTabButtonOverlap (tabDepth) * 2; if (auto* extraComponent = button.getExtraComponent()) @@ -2143,6 +2239,7 @@ void LookAndFeel_V2::createTabButtonShape (TabBarButton& button, Path& p, bool / p.lineTo (-overhang, -overhang); break; + case TabbedButtonBar::TabsAtTop: default: p.startNewSubPath (0.0f, h); p.lineTo (indent, 0.0f); @@ -2257,26 +2354,26 @@ void LookAndFeel_V2::drawTabAreaBehindFrontButton (TabbedButtonBar& bar, Graphic { case TabbedButtonBar::TabsAtLeft: gradient.point1.x = (float) w; - gradient.point2.x = w * (1.0f - shadowSize); + gradient.point2.x = (float) w * (1.0f - shadowSize); shadowRect.setBounds ((int) gradient.point2.x, 0, w - (int) gradient.point2.x, h); line.setBounds (w - 1, 0, 1, h); break; case TabbedButtonBar::TabsAtRight: - gradient.point2.x = w * shadowSize; + gradient.point2.x = (float) w * shadowSize; shadowRect.setBounds (0, 0, (int) gradient.point2.x, h); line.setBounds (0, 0, 1, h); break; case TabbedButtonBar::TabsAtTop: gradient.point1.y = (float) h; - gradient.point2.y = h * (1.0f - shadowSize); + gradient.point2.y = (float) h * (1.0f - shadowSize); shadowRect.setBounds (0, (int) gradient.point2.y, w, h - (int) gradient.point2.y); line.setBounds (0, h - 1, w, 1); break; case TabbedButtonBar::TabsAtBottom: - gradient.point2.y = h * shadowSize; + gradient.point2.y = (float) h * shadowSize; shadowRect.setBounds (0, 0, w, (int) gradient.point2.y); line.setBounds (0, 0, w, 1); break; @@ -2381,7 +2478,7 @@ void LookAndFeel_V2::drawTableHeaderColumn (Graphics& g, TableHeaderComponent& h } g.setColour (header.findColour (TableHeaderComponent::textColourId)); - g.setFont (Font (height * 0.5f, Font::bold)); + g.setFont (Font ((float) height * 0.5f, Font::bold)); g.drawFittedText (columnName, area, Justification::centredLeft, 1); } @@ -2403,8 +2500,8 @@ void LookAndFeel_V2::paintToolbarBackground (Graphics& g, int w, int h, Toolbar& g.setGradientFill (ColourGradient (background, 0.0f, 0.0f, background.darker (0.1f), - toolbar.isVertical() ? w - 1.0f : 0.0f, - toolbar.isVertical() ? 0.0f : h - 1.0f, + toolbar.isVertical() ? (float) w - 1.0f : 0.0f, + toolbar.isVertical() ? 0.0f : (float) h - 1.0f, false)); g.fillAll(); } @@ -2430,7 +2527,7 @@ void LookAndFeel_V2::paintToolbarButtonLabel (Graphics& g, int x, int y, int wid g.setColour (component.findColour (Toolbar::labelTextColourId, true) .withAlpha (component.isEnabled() ? 1.0f : 0.25f)); - auto fontHeight = jmin (14.0f, height * 0.85f); + auto fontHeight = jmin (14.0f, (float) height * 0.85f); g.setFont (fontHeight); g.drawFittedText (text, @@ -2443,15 +2540,15 @@ void LookAndFeel_V2::paintToolbarButtonLabel (Graphics& g, int x, int y, int wid void LookAndFeel_V2::drawPropertyPanelSectionHeader (Graphics& g, const String& name, bool isOpen, int width, int height) { - auto buttonSize = height * 0.75f; - auto buttonIndent = (height - buttonSize) * 0.5f; + auto buttonSize = (float) height * 0.75f; + auto buttonIndent = ((float) height - buttonSize) * 0.5f; drawTreeviewPlusMinusBox (g, Rectangle<float> (buttonIndent, buttonIndent, buttonSize, buttonSize), Colours::white, isOpen, false); auto textX = (int) (buttonIndent * 2.0f + buttonSize + 2.0f); g.setColour (Colours::black); - g.setFont (Font (height * 0.7f, Font::bold)); + g.setFont (Font ((float) height * 0.7f, Font::bold)); g.drawText (name, textX, 0, width - textX - 4, height, Justification::centredLeft, true); } @@ -2466,7 +2563,7 @@ void LookAndFeel_V2::drawPropertyComponentLabel (Graphics& g, int, int height, P g.setColour (component.findColour (PropertyComponent::labelTextColourId) .withMultipliedAlpha (component.isEnabled() ? 1.0f : 0.6f)); - g.setFont (jmin (height, 24) * 0.65f); + g.setFont ((float) jmin (height, 24) * 0.65f); auto r = getPropertyComponentContentPosition (component); @@ -2558,7 +2655,7 @@ void LookAndFeel_V2::drawFileBrowserRow (Graphics& g, int width, int height, { if (auto* d = isDirectory ? getDefaultFolderImage() : getDefaultDocumentFileImage()) - d->drawWithin (g, Rectangle<float> (2.0f, 2.0f, x - 4.0f, height - 4.0f), + d->drawWithin (g, Rectangle<float> (2.0f, 2.0f, x - 4.0f, (float) height - 4.0f), RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize, 1.0f); } @@ -2569,18 +2666,18 @@ void LookAndFeel_V2::drawFileBrowserRow (Graphics& g, int width, int height, g.setColour (fileListComp != nullptr ? fileListComp->findColour (DirectoryContentsDisplayComponent::textColourId) : findColour (DirectoryContentsDisplayComponent::textColourId)); - g.setFont (height * 0.7f); + g.setFont ((float) height * 0.7f); if (width > 450 && ! isDirectory) { - auto sizeX = roundToInt (width * 0.7f); - auto dateX = roundToInt (width * 0.8f); + auto sizeX = roundToInt ((float) width * 0.7f); + auto dateX = roundToInt ((float) width * 0.8f); g.drawFittedText (filename, x, 0, sizeX - x, height, Justification::centredLeft, 1); - g.setFont (height * 0.5f); + g.setFont ((float) height * 0.5f); g.setColour (Colours::darkgrey); if (! isDirectory) @@ -2746,11 +2843,11 @@ void LookAndFeel_V2::drawLevelMeter (Graphics& g, int width, int height, float l g.setColour (Colours::white.withAlpha (0.7f)); g.fillRoundedRectangle (0.0f, 0.0f, (float) width, (float) height, 3.0f); g.setColour (Colours::black.withAlpha (0.2f)); - g.drawRoundedRectangle (1.0f, 1.0f, width - 2.0f, height - 2.0f, 3.0f, 1.0f); + g.drawRoundedRectangle (1.0f, 1.0f, (float) width - 2.0f, (float) height - 2.0f, 3.0f, 1.0f); const int totalBlocks = 7; const int numBlocks = roundToInt (totalBlocks * level); - auto w = (width - 6.0f) / (float) totalBlocks; + auto w = ((float) width - 6.0f) / (float) totalBlocks; for (int i = 0; i < totalBlocks; ++i) { @@ -2760,7 +2857,11 @@ void LookAndFeel_V2::drawLevelMeter (Graphics& g, int width, int height, float l g.setColour (i < totalBlocks - 1 ? Colours::blue.withAlpha (0.5f) : Colours::red); - g.fillRoundedRectangle (3.0f + i * w + w * 0.1f, 3.0f, w * 0.8f, height - 6.0f, w * 0.4f); + g.fillRoundedRectangle (3.0f + (float) i * w + w * 0.1f, + 3.0f, + (float) w * 0.8f, + (float) height - 6.0f, + (float) w * 0.4f); } } @@ -2781,7 +2882,7 @@ void LookAndFeel_V2::drawKeymapChangeButton (Graphics& g, int width, int height, } g.setColour (textColour); - g.setFont (height * 0.6f); + g.setFont ((float) height * 0.6f); g.drawFittedText (keyDescription, 3, 0, width - 6, height, Justification::centred, 1); @@ -2799,7 +2900,7 @@ void LookAndFeel_V2::drawKeymapChangeButton (Graphics& g, int width, int height, p.setUsingNonZeroWinding (false); g.setColour (textColour.withAlpha (button.isDown() ? 0.7f : (button.isOver() ? 0.5f : 0.3f))); - g.fillPath (p, p.getTransformToScaleToFit (2.0f, 2.0f, width - 4.0f, height - 4.0f, true)); + g.fillPath (p, p.getTransformToScaleToFit (2.0f, 2.0f, (float) width - 4.0f, (float) height - 4.0f, true)); } if (button.hasKeyboardFocus (false)) @@ -2838,7 +2939,7 @@ void LookAndFeel_V2::drawBevel (Graphics& g, const int x, const int y, const int for (int i = bevelThickness; --i >= 0;) { - const float op = useGradient ? (sharpEdgeOnOutside ? bevelThickness - i : i) / (float) bevelThickness + const float op = useGradient ? (float) (sharpEdgeOnOutside ? bevelThickness - i : i) / (float) bevelThickness : 1.0f; context.setFill (topLeftColour.withMultipliedAlpha (op)); @@ -2941,7 +3042,9 @@ void LookAndFeel_V2::drawGlassPointer (Graphics& g, p.lineTo (x, y + diameter * 0.6f); p.closeSubPath(); - p.applyTransform (AffineTransform::rotation (direction * MathConstants<float>::halfPi, x + diameter * 0.5f, y + diameter * 0.5f)); + p.applyTransform (AffineTransform::rotation ((float) direction * MathConstants<float>::halfPi, + x + diameter * 0.5f, + y + diameter * 0.5f)); { ColourGradient cg (Colours::white.overlaidWith (colour.withMultipliedAlpha (0.3f)), 0, y, diff --git a/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.h b/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.h index b1113325..8d07e8ce 100644 --- a/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.h +++ b/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -156,21 +155,47 @@ public: //============================================================================== void drawPopupMenuBackground (Graphics&, int width, int height) override; + void drawPopupMenuBackgroundWithOptions (Graphics&, + int width, + int height, + const PopupMenu::Options&) override; void drawPopupMenuItem (Graphics&, const Rectangle<int>& area, bool isSeparator, bool isActive, bool isHighlighted, bool isTicked, bool hasSubMenu, const String& text, const String& shortcutKeyText, const Drawable* icon, const Colour* textColour) override; + void drawPopupMenuItemWithOptions (Graphics&, const Rectangle<int>& area, + bool isHighlighted, + const PopupMenu::Item& item, + const PopupMenu::Options&) override; + void drawPopupMenuSectionHeader (Graphics&, const Rectangle<int>& area, const String& sectionName) override; + void drawPopupMenuSectionHeaderWithOptions (Graphics&, const Rectangle<int>& area, + const String& sectionName, + const PopupMenu::Options&) override; + Font getPopupMenuFont() override; void drawPopupMenuUpDownArrow (Graphics&, int width, int height, bool isScrollUpArrow) override; + void drawPopupMenuUpDownArrowWithOptions (Graphics&, + int width, int height, + bool isScrollUpArrow, + const PopupMenu::Options&) override; + void getIdealPopupMenuItemSize (const String& text, bool isSeparator, int standardMenuItemHeight, int& idealWidth, int& idealHeight) override; + + void getIdealPopupMenuItemSizeWithOptions (const String& text, + bool isSeparator, + int standardMenuItemHeight, + int& idealWidth, + int& idealHeight, + const PopupMenu::Options&) override; + int getMenuWindowFlags() override; void preparePopupMenuWindow (Component&) override; @@ -190,6 +215,14 @@ public: int getPopupMenuBorderSize() override; + int getPopupMenuBorderSizeWithOptions (const PopupMenu::Options&) override; + + void drawPopupMenuColumnSeparatorWithOptions (Graphics& g, + const Rectangle<int>& bounds, + const PopupMenu::Options&) override; + + int getPopupMenuColumnSeparatorWidthWithOptions (const PopupMenu::Options&) override; + //============================================================================== void drawComboBox (Graphics&, int width, int height, bool isMouseButtonDown, int buttonX, int buttonY, int buttonW, int buttonH, diff --git a/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V3.cpp b/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V3.cpp index 5eeacf77..99930bc2 100644 --- a/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V3.cpp +++ b/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V3.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -65,15 +64,15 @@ void LookAndFeel_V3::drawScrollbar (Graphics& g, ScrollBar& scrollbar, int x, in if (thumbSize > 0) { - const float thumbIndent = (isScrollbarVertical ? width : height) * 0.25f; + const float thumbIndent = (float) (isScrollbarVertical ? width : height) * 0.25f; const float thumbIndentx2 = thumbIndent * 2.0f; if (isScrollbarVertical) - thumbPath.addRoundedRectangle (x + thumbIndent, thumbStartPosition + thumbIndent, - width - thumbIndentx2, thumbSize - thumbIndentx2, (width - thumbIndentx2) * 0.5f); + thumbPath.addRoundedRectangle ((float) x + thumbIndent, (float) thumbStartPosition + thumbIndent, + (float) width - thumbIndentx2, (float) thumbSize - thumbIndentx2, ((float) width - thumbIndentx2) * 0.5f); else - thumbPath.addRoundedRectangle (thumbStartPosition + thumbIndent, y + thumbIndent, - thumbSize - thumbIndentx2, height - thumbIndentx2, (height - thumbIndentx2) * 0.5f); + thumbPath.addRoundedRectangle ((float) thumbStartPosition + thumbIndent, (float) y + thumbIndent, + (float) thumbSize - thumbIndentx2, (float) height - thumbIndentx2, ((float) height - thumbIndentx2) * 0.5f); } Colour thumbCol (scrollbar.findColour (ScrollBar::thumbColourId, true)); @@ -103,7 +102,7 @@ void LookAndFeel_V3::drawConcertinaPanelHeader (Graphics& g, const Rectangle<int g.fillRect (area.withTop (area.getBottom() - 1)); g.setColour (bkg.contrasting()); - g.setFont (Font (area.getHeight() * 0.6f).boldened()); + g.setFont (Font ((float) area.getHeight() * 0.6f).boldened()); g.drawFittedText (panel.getName(), 4, 0, area.getWidth() - 6, area.getHeight(), Justification::centredLeft, 1); } @@ -138,8 +137,8 @@ void LookAndFeel_V3::drawButtonBackground (Graphics& g, Button& button, const Co const bool flatOnTop = button.isConnectedOnTop(); const bool flatOnBottom = button.isConnectedOnBottom(); - const float width = button.getWidth() - 1.0f; - const float height = button.getHeight() - 1.0f; + const float width = (float) button.getWidth() - 1.0f; + const float height = (float) button.getHeight() - 1.0f; if (width > 0 && height > 0) { @@ -282,26 +281,26 @@ void LookAndFeel_V3::drawTabAreaBehindFrontButton (TabbedButtonBar& bar, Graphic { case TabbedButtonBar::TabsAtLeft: gradient.point1.x = (float) w; - gradient.point2.x = w * (1.0f - shadowSize); + gradient.point2.x = (float) w * (1.0f - shadowSize); shadowRect.setBounds ((int) gradient.point2.x, 0, w - (int) gradient.point2.x, h); line.setBounds (w - 1, 0, 1, h); break; case TabbedButtonBar::TabsAtRight: - gradient.point2.x = w * shadowSize; + gradient.point2.x = (float) w * shadowSize; shadowRect.setBounds (0, 0, (int) gradient.point2.x, h); line.setBounds (0, 0, 1, h); break; case TabbedButtonBar::TabsAtTop: gradient.point1.y = (float) h; - gradient.point2.y = h * (1.0f - shadowSize); + gradient.point2.y = (float) h * (1.0f - shadowSize); shadowRect.setBounds (0, (int) gradient.point2.y, w, h - (int) gradient.point2.y); line.setBounds (0, h - 1, w, 1); break; case TabbedButtonBar::TabsAtBottom: - gradient.point2.y = h * shadowSize; + gradient.point2.y = (float) h * shadowSize; shadowRect.setBounds (0, 0, w, (int) gradient.point2.y); line.setBounds (0, 0, w, 1); break; @@ -372,14 +371,19 @@ void LookAndFeel_V3::drawComboBox (Graphics& g, int width, int height, const boo const float arrowX = 0.3f; const float arrowH = 0.2f; + const auto x = (float) buttonX; + const auto y = (float) buttonY; + const auto w = (float) buttonW; + const auto h = (float) buttonH; + Path p; - p.addTriangle (buttonX + buttonW * 0.5f, buttonY + buttonH * (0.45f - arrowH), - buttonX + buttonW * (1.0f - arrowX), buttonY + buttonH * 0.45f, - buttonX + buttonW * arrowX, buttonY + buttonH * 0.45f); + p.addTriangle (x + w * 0.5f, y + h * (0.45f - arrowH), + x + w * (1.0f - arrowX), y + h * 0.45f, + x + w * arrowX, y + h * 0.45f); - p.addTriangle (buttonX + buttonW * 0.5f, buttonY + buttonH * (0.55f + arrowH), - buttonX + buttonW * (1.0f - arrowX), buttonY + buttonH * 0.55f, - buttonX + buttonW * arrowX, buttonY + buttonH * 0.55f); + p.addTriangle (x + w * 0.5f, y + h * (0.55f + arrowH), + x + w * (1.0f - arrowX), y + h * 0.55f, + x + w * arrowX, y + h * 0.55f); g.setColour (box.findColour (ComboBox::arrowColourId).withMultipliedAlpha (box.isEnabled() ? 1.0f : 0.3f)); g.fillPath (p); @@ -439,19 +443,19 @@ void LookAndFeel_V3::drawLinearSliderBackground (Graphics& g, int x, int y, int if (slider.isHorizontal()) { - auto iy = y + height * 0.5f - sliderRadius * 0.5f; + auto iy = (float) y + (float) height * 0.5f - sliderRadius * 0.5f; g.setGradientFill (ColourGradient::vertical (gradCol1, iy, gradCol2, iy + sliderRadius)); - indent.addRoundedRectangle (x - sliderRadius * 0.5f, iy, width + sliderRadius, sliderRadius, 5.0f); + indent.addRoundedRectangle ((float) x - sliderRadius * 0.5f, iy, (float) width + sliderRadius, sliderRadius, 5.0f); } else { - auto ix = x + width * 0.5f - sliderRadius * 0.5f; + auto ix = (float) x + (float) width * 0.5f - sliderRadius * 0.5f; g.setGradientFill (ColourGradient::horizontal (gradCol1, ix, gradCol2, ix + sliderRadius)); - indent.addRoundedRectangle (ix, y - sliderRadius * 0.5f, sliderRadius, height + sliderRadius, 5.0f); + indent.addRoundedRectangle (ix, (float) y - sliderRadius * 0.5f, sliderRadius, (float) height + sliderRadius, 5.0f); } g.fillPath (indent); @@ -501,7 +505,7 @@ void LookAndFeel_V3::drawKeymapChangeButton (Graphics& g, int width, int height, } g.setColour (textColour); - g.setFont (height * 0.6f); + g.setFont ((float) height * 0.6f); g.drawFittedText (keyDescription, 4, 0, width - 8, height, Justification::centred, 1); } else @@ -517,7 +521,7 @@ void LookAndFeel_V3::drawKeymapChangeButton (Graphics& g, int width, int height, p.setUsingNonZeroWinding (false); g.setColour (textColour.darker(0.1f).withAlpha (button.isDown() ? 0.7f : (button.isOver() ? 0.5f : 0.3f))); - g.fillPath (p, p.getTransformToScaleToFit (2.0f, 2.0f, width - 4.0f, height - 4.0f, true)); + g.fillPath (p, p.getTransformToScaleToFit (2.0f, 2.0f, (float) width - 4.0f, (float) height - 4.0f, true)); } if (button.hasKeyboardFocus (false)) @@ -543,7 +547,7 @@ public: if (ResizableWindow* rw = findParentComponentOfClass<ResizableWindow>()) background = rw->getBackgroundColour(); - const float cx = getWidth() * 0.5f, cy = getHeight() * 0.5f; + const float cx = (float) getWidth() * 0.5f, cy = (float) getHeight() * 0.5f; const float diam = jmin (cx, cy) * (shouldDrawButtonAsDown ? 0.60f : 0.65f); g.setColour (background); diff --git a/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V3.h b/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V3.h index 6cc2797f..530ee3af 100644 --- a/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V3.h +++ b/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V3.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V4.cpp b/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V4.cpp index f119b84c..21042d0b 100644 --- a/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V4.cpp +++ b/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V4.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -139,7 +138,7 @@ public: auto reducedRect = Justification (Justification::centred) .appliedToRectangle (Rectangle<int> (getHeight(), getHeight()), getLocalBounds()) .toFloat() - .reduced (getHeight() * 0.3f); + .reduced ((float) getHeight() * 0.3f); g.fillPath (p, p.getTransformToScaleToFit (reducedRect, true)); } @@ -238,7 +237,7 @@ void LookAndFeel_V4::drawDocumentWindowTitleBar (DocumentWindow& window, Graphic g.setColour (getCurrentColourScheme().getUIColour (ColourScheme::widgetBackground)); g.fillAll(); - Font font (h * 0.65f, Font::plain); + Font font ((float) h * 0.65f, Font::plain); g.setFont (font); auto textW = font.getStringWidth (window.getName()); @@ -278,7 +277,7 @@ void LookAndFeel_V4::drawDocumentWindowTitleBar (DocumentWindow& window, Graphic //============================================================================== Font LookAndFeel_V4::getTextButtonFont (TextButton&, int buttonHeight) { - return { jmin (16.0f, buttonHeight * 0.6f) }; + return { jmin (16.0f, (float) buttonHeight * 0.6f) }; } void LookAndFeel_V4::drawButtonBackground (Graphics& g, @@ -331,10 +330,10 @@ void LookAndFeel_V4::drawButtonBackground (Graphics& g, void LookAndFeel_V4::drawToggleButton (Graphics& g, ToggleButton& button, bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) { - auto fontSize = jmin (15.0f, button.getHeight() * 0.75f); + auto fontSize = jmin (15.0f, (float) button.getHeight() * 0.75f); auto tickWidth = fontSize * 1.1f; - drawTickBox (g, button, 4.0f, (button.getHeight() - tickWidth) * 0.5f, + drawTickBox (g, button, 4.0f, ((float) button.getHeight() - tickWidth) * 0.5f, tickWidth, tickWidth, button.getToggleState(), button.isEnabled(), @@ -377,7 +376,7 @@ void LookAndFeel_V4::drawTickBox (Graphics& g, Component& component, void LookAndFeel_V4::changeToggleButtonWidthToFitText (ToggleButton& button) { - auto fontSize = jmin (15.0f, button.getHeight() * 0.75f); + auto fontSize = jmin (15.0f, (float) button.getHeight() * 0.75f); auto tickWidth = fontSize * 1.1f; Font font (fontSize); @@ -442,7 +441,7 @@ void LookAndFeel_V4::drawAlertBox (Graphics& g, AlertWindow& alert, { character = '!'; - icon.addTriangle (iconRect.getX() + iconRect.getWidth() * 0.5f, (float) iconRect.getY(), + icon.addTriangle ((float) iconRect.getX() + (float) iconRect.getWidth() * 0.5f, (float) iconRect.getY(), static_cast<float> (iconRect.getRight()), static_cast<float> (iconRect.getBottom()), static_cast<float> (iconRect.getX()), static_cast<float> (iconRect.getBottom())); @@ -458,7 +457,7 @@ void LookAndFeel_V4::drawAlertBox (Graphics& g, AlertWindow& alert, } GlyphArrangement ga; - ga.addFittedText ({ iconRect.getHeight() * 0.9f, Font::bold }, + ga.addFittedText ({ (float) iconRect.getHeight() * 0.9f, Font::bold }, String::charToString ((juce_wchar) (uint8) character), static_cast<float> (iconRect.getX()), static_cast<float> (iconRect.getY()), static_cast<float> (iconRect.getWidth()), static_cast<float> (iconRect.getHeight()), @@ -505,17 +504,17 @@ void LookAndFeel_V4::drawLinearProgressBar (Graphics& g, ProgressBar& progressBa auto barBounds = progressBar.getLocalBounds().toFloat(); g.setColour (background); - g.fillRoundedRectangle (barBounds, progressBar.getHeight() * 0.5f); + g.fillRoundedRectangle (barBounds, (float) progressBar.getHeight() * 0.5f); if (progress >= 0.0f && progress <= 1.0f) { Path p; - p.addRoundedRectangle (barBounds, progressBar.getHeight() * 0.5f); + p.addRoundedRectangle (barBounds, (float) progressBar.getHeight() * 0.5f); g.reduceClipRegion (p); barBounds.setWidth (barBounds.getWidth() * (float) progress); g.setColour (foreground); - g.fillRoundedRectangle (barBounds, progressBar.getHeight() * 0.5f); + g.fillRoundedRectangle (barBounds, (float) progressBar.getHeight() * 0.5f); } else { @@ -527,18 +526,18 @@ void LookAndFeel_V4::drawLinearProgressBar (Graphics& g, ProgressBar& progressBa Path p; - for (auto x = static_cast<float> (-position); x < width + stripeWidth; x += stripeWidth) + for (auto x = static_cast<float> (-position); x < (float) (width + stripeWidth); x += (float) stripeWidth) p.addQuadrilateral (x, 0.0f, - x + stripeWidth * 0.5f, 0.0f, + x + (float) stripeWidth * 0.5f, 0.0f, x, static_cast<float> (height), - x - stripeWidth * 0.5f, static_cast<float> (height)); + x - (float) stripeWidth * 0.5f, static_cast<float> (height)); Image im (Image::ARGB, width, height, true); { Graphics g2 (im); g2.setColour (foreground); - g2.fillRoundedRectangle (barBounds, progressBar.getHeight() * 0.5f); + g2.fillRoundedRectangle (barBounds, (float) progressBar.getHeight() * 0.5f); } g.setTiledImageFill (im, 0, 0, 0.85f); @@ -548,7 +547,7 @@ void LookAndFeel_V4::drawLinearProgressBar (Graphics& g, ProgressBar& progressBa if (textToShow.isNotEmpty()) { g.setColour (Colour::contrasting (background, foreground)); - g.setFont (height * 0.6f); + g.setFont ((float) height * 0.6f); g.drawText (textToShow, 0, 0, width, height, Justification::centred, false); } @@ -771,7 +770,7 @@ void LookAndFeel_V4::drawPopupMenuItem (Graphics& g, const Rectangle<int>& area, if (isSeparator) { auto r = area.reduced (5, 0); - r.removeFromTop (roundToInt ((r.getHeight() * 0.5f) - 0.5f)); + r.removeFromTop (roundToInt (((float) r.getHeight() * 0.5f) - 0.5f)); g.setColour (findColour (PopupMenu::textColourId).withAlpha (0.3f)); g.fillRect (r.removeFromTop (1)); @@ -799,7 +798,7 @@ void LookAndFeel_V4::drawPopupMenuItem (Graphics& g, const Rectangle<int>& area, auto font = getPopupMenuFont(); - auto maxFontHeight = r.getHeight() / 1.3f; + auto maxFontHeight = (float) r.getHeight() / 1.3f; if (font.getHeight() > maxFontHeight) font.setHeight (maxFontHeight); @@ -861,8 +860,8 @@ void LookAndFeel_V4::getIdealPopupMenuItemSize (const String& text, const bool i { auto font = getPopupMenuFont(); - if (standardMenuItemHeight > 0 && font.getHeight() > standardMenuItemHeight / 1.3f) - font.setHeight (standardMenuItemHeight / 1.3f); + if (standardMenuItemHeight > 0 && font.getHeight() > (float) standardMenuItemHeight / 1.3f) + font.setHeight ((float) standardMenuItemHeight / 1.3f); idealHeight = standardMenuItemHeight > 0 ? standardMenuItemHeight : roundToInt (font.getHeight() * 1.3f); idealWidth = font.getStringWidth (text) + idealHeight * 2; @@ -923,9 +922,9 @@ void LookAndFeel_V4::drawComboBox (Graphics& g, int width, int height, bool, Rectangle<int> arrowZone (width - 30, 0, 20, height); Path path; - path.startNewSubPath (arrowZone.getX() + 3.0f, arrowZone.getCentreY() - 2.0f); - path.lineTo (static_cast<float> (arrowZone.getCentreX()), arrowZone.getCentreY() + 3.0f); - path.lineTo (arrowZone.getRight() - 3.0f, arrowZone.getCentreY() - 2.0f); + path.startNewSubPath ((float) arrowZone.getX() + 3.0f, (float) arrowZone.getCentreY() - 2.0f); + path.lineTo ((float) arrowZone.getCentreX(), (float) arrowZone.getCentreY() + 3.0f); + path.lineTo ((float) arrowZone.getRight() - 3.0f, (float) arrowZone.getCentreY() - 2.0f); g.setColour (box.findColour (ComboBox::arrowColourId).withAlpha ((box.isEnabled() ? 0.9f : 0.2f))); g.strokePath (path, PathStrokeType (2.0f)); @@ -933,7 +932,7 @@ void LookAndFeel_V4::drawComboBox (Graphics& g, int width, int height, bool, Font LookAndFeel_V4::getComboBoxFont (ComboBox& box) { - return { jmin (16.0f, box.getHeight() * 0.85f) }; + return { jmin (16.0f, (float) box.getHeight() * 0.85f) }; } void LookAndFeel_V4::positionComboBoxText (ComboBox& box, Label& label) @@ -948,8 +947,8 @@ void LookAndFeel_V4::positionComboBoxText (ComboBox& box, Label& label) //============================================================================== int LookAndFeel_V4::getSliderThumbRadius (Slider& slider) { - return jmin (12, slider.isHorizontal() ? static_cast<int> (slider.getHeight() * 0.5f) - : static_cast<int> (slider.getWidth() * 0.5f)); + return jmin (12, slider.isHorizontal() ? static_cast<int> ((float) slider.getHeight() * 0.5f) + : static_cast<int> ((float) slider.getWidth() * 0.5f)); } void LookAndFeel_V4::drawLinearSlider (Graphics& g, int x, int y, int width, int height, @@ -961,21 +960,21 @@ void LookAndFeel_V4::drawLinearSlider (Graphics& g, int x, int y, int width, int if (slider.isBar()) { g.setColour (slider.findColour (Slider::trackColourId)); - g.fillRect (slider.isHorizontal() ? Rectangle<float> (static_cast<float> (x), y + 0.5f, sliderPos - x, height - 1.0f) - : Rectangle<float> (x + 0.5f, sliderPos, width - 1.0f, y + (height - sliderPos))); + g.fillRect (slider.isHorizontal() ? Rectangle<float> (static_cast<float> (x), (float) y + 0.5f, sliderPos - (float) x, (float) height - 1.0f) + : Rectangle<float> ((float) x + 0.5f, sliderPos, (float) width - 1.0f, (float) y + ((float) height - sliderPos))); } else { auto isTwoVal = (style == Slider::SliderStyle::TwoValueVertical || style == Slider::SliderStyle::TwoValueHorizontal); auto isThreeVal = (style == Slider::SliderStyle::ThreeValueVertical || style == Slider::SliderStyle::ThreeValueHorizontal); - auto trackWidth = jmin (6.0f, slider.isHorizontal() ? height * 0.25f : width * 0.25f); + auto trackWidth = jmin (6.0f, slider.isHorizontal() ? (float) height * 0.25f : (float) width * 0.25f); - Point<float> startPoint (slider.isHorizontal() ? x : x + width * 0.5f, - slider.isHorizontal() ? y + height * 0.5f : height + y); + Point<float> startPoint (slider.isHorizontal() ? (float) x : (float) x + (float) width * 0.5f, + slider.isHorizontal() ? (float) y + (float) height * 0.5f : (float) (height + y)); - Point<float> endPoint (slider.isHorizontal() ? width + x : startPoint.x, - slider.isHorizontal() ? startPoint.y : y); + Point<float> endPoint (slider.isHorizontal() ? (float) (width + x) : startPoint.x, + slider.isHorizontal() ? startPoint.y : (float) y); Path backgroundTrack; backgroundTrack.startNewSubPath (startPoint); @@ -988,20 +987,20 @@ void LookAndFeel_V4::drawLinearSlider (Graphics& g, int x, int y, int width, int if (isTwoVal || isThreeVal) { - minPoint = { slider.isHorizontal() ? minSliderPos : width * 0.5f, - slider.isHorizontal() ? height * 0.5f : minSliderPos }; + minPoint = { slider.isHorizontal() ? minSliderPos : (float) width * 0.5f, + slider.isHorizontal() ? (float) height * 0.5f : minSliderPos }; if (isThreeVal) - thumbPoint = { slider.isHorizontal() ? sliderPos : width * 0.5f, - slider.isHorizontal() ? height * 0.5f : sliderPos }; + thumbPoint = { slider.isHorizontal() ? sliderPos : (float) width * 0.5f, + slider.isHorizontal() ? (float) height * 0.5f : sliderPos }; - maxPoint = { slider.isHorizontal() ? maxSliderPos : width * 0.5f, - slider.isHorizontal() ? height * 0.5f : maxSliderPos }; + maxPoint = { slider.isHorizontal() ? maxSliderPos : (float) width * 0.5f, + slider.isHorizontal() ? (float) height * 0.5f : maxSliderPos }; } else { - auto kx = slider.isHorizontal() ? sliderPos : (x + width * 0.5f); - auto ky = slider.isHorizontal() ? (y + height * 0.5f) : sliderPos; + auto kx = slider.isHorizontal() ? sliderPos : ((float) x + (float) width * 0.5f); + auto ky = slider.isHorizontal() ? ((float) y + (float) height * 0.5f) : sliderPos; minPoint = startPoint; maxPoint = { kx, ky }; @@ -1022,26 +1021,26 @@ void LookAndFeel_V4::drawLinearSlider (Graphics& g, int x, int y, int width, int if (isTwoVal || isThreeVal) { - auto sr = jmin (trackWidth, (slider.isHorizontal() ? height : width) * 0.4f); + auto sr = jmin (trackWidth, (slider.isHorizontal() ? (float) height : (float) width) * 0.4f); auto pointerColour = slider.findColour (Slider::thumbColourId); if (slider.isHorizontal()) { drawPointer (g, minSliderPos - sr, - jmax (0.0f, y + height * 0.5f - trackWidth * 2.0f), + jmax (0.0f, (float) y + (float) height * 0.5f - trackWidth * 2.0f), trackWidth * 2.0f, pointerColour, 2); drawPointer (g, maxSliderPos - trackWidth, - jmin (y + height - trackWidth * 2.0f, y + height * 0.5f), + jmin ((float) (y + height) - trackWidth * 2.0f, (float) y + (float) height * 0.5f), trackWidth * 2.0f, pointerColour, 4); } else { - drawPointer (g, jmax (0.0f, x + width * 0.5f - trackWidth * 2.0f), + drawPointer (g, jmax (0.0f, (float) x + (float) width * 0.5f - trackWidth * 2.0f), minSliderPos - trackWidth, trackWidth * 2.0f, pointerColour, 1); - drawPointer (g, jmin (x + width - trackWidth * 2.0f, x + width * 0.5f), maxSliderPos - sr, + drawPointer (g, jmin ((float) (x + width) - trackWidth * 2.0f, (float) x + (float) width * 0.5f), maxSliderPos - sr, trackWidth * 2.0f, pointerColour, 3); } } @@ -1109,7 +1108,7 @@ void LookAndFeel_V4::drawPointer (Graphics& g, const float x, const float y, con p.lineTo (x, y + diameter * 0.6f); p.closeSubPath(); - p.applyTransform (AffineTransform::rotation (direction * MathConstants<float>::halfPi, + p.applyTransform (AffineTransform::rotation ((float) direction * MathConstants<float>::halfPi, x + diameter * 0.5f, y + diameter * 0.5f)); g.setColour (colour); g.fillPath (p); @@ -1174,10 +1173,10 @@ void LookAndFeel_V4::drawLevelMeter (Graphics& g, int width, int height, float l g.fillRoundedRectangle (0.0f, 0.0f, static_cast<float> (width), static_cast<float> (height), outerCornerSize); auto doubleOuterBorderWidth = 2.0f * outerBorderWidth; - auto numBlocks = roundToInt (totalBlocks * level); + auto numBlocks = roundToInt ((float) totalBlocks * level); - auto blockWidth = (width - doubleOuterBorderWidth) / static_cast<float> (totalBlocks); - auto blockHeight = height - doubleOuterBorderWidth; + auto blockWidth = ((float) width - doubleOuterBorderWidth) / static_cast<float> (totalBlocks); + auto blockHeight = (float) height - doubleOuterBorderWidth; auto blockRectWidth = (1.0f - 2.0f * spacingFraction) * blockWidth; auto blockRectSpacing = spacingFraction * blockWidth; @@ -1193,7 +1192,7 @@ void LookAndFeel_V4::drawLevelMeter (Graphics& g, int width, int height, float l else g.setColour (i < totalBlocks - 1 ? c : Colours::red); - g.fillRoundedRectangle (outerBorderWidth + (i * blockWidth) + blockRectSpacing, + g.fillRoundedRectangle (outerBorderWidth + ((float) i * blockWidth) + blockRectSpacing, outerBorderWidth, blockRectWidth, blockHeight, @@ -1208,8 +1207,8 @@ void LookAndFeel_V4::paintToolbarBackground (Graphics& g, int w, int h, Toolbar& g.setGradientFill ({ background, 0.0f, 0.0f, background.darker (0.2f), - toolbar.isVertical() ? w - 1.0f : 0.0f, - toolbar.isVertical() ? 0.0f : h - 1.0f, + toolbar.isVertical() ? (float) w - 1.0f : 0.0f, + toolbar.isVertical() ? 0.0f : (float) h - 1.0f, false }); g.fillAll(); } @@ -1223,7 +1222,7 @@ void LookAndFeel_V4::paintToolbarButtonLabel (Graphics& g, int x, int y, int wid g.setColour (baseTextColour.withAlpha (component.isEnabled() ? 1.0f : 0.25f)); - auto fontHeight = jmin (14.0f, height * 0.85f); + auto fontHeight = jmin (14.0f, (float) height * 0.85f); g.setFont (fontHeight); g.drawFittedText (text, @@ -1236,8 +1235,8 @@ void LookAndFeel_V4::paintToolbarButtonLabel (Graphics& g, int x, int y, int wid void LookAndFeel_V4::drawPropertyPanelSectionHeader (Graphics& g, const String& name, bool isOpen, int width, int height) { - auto buttonSize = height * 0.75f; - auto buttonIndent = (height - buttonSize) * 0.5f; + auto buttonSize = (float) height * 0.75f; + auto buttonIndent = ((float) height - buttonSize) * 0.5f; drawTreeviewPlusMinusBox (g, { buttonIndent, buttonIndent, buttonSize, buttonSize }, findColour (ResizableWindow::backgroundColourId), isOpen, false); @@ -1246,7 +1245,7 @@ void LookAndFeel_V4::drawPropertyPanelSectionHeader (Graphics& g, const String& g.setColour (findColour (PropertyComponent::labelTextColourId)); - g.setFont ({ height * 0.7f, Font::bold }); + g.setFont ({ (float) height * 0.7f, Font::bold }); g.drawText (name, textX, 0, width - textX - 4, height, Justification::centredLeft, true); } @@ -1265,7 +1264,7 @@ void LookAndFeel_V4::drawPropertyComponentLabel (Graphics& g, int width, int hei g.setColour (component.findColour (PropertyComponent::labelTextColourId) .withMultipliedAlpha (component.isEnabled() ? 1.0f : 0.6f)); - g.setFont (jmin (height, 24) * 0.65f); + g.setFont ((float) jmin (height, 24) * 0.65f); auto r = getPropertyComponentContentPosition (component); diff --git a/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V4.h b/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V4.h index 722ad234..6b5bcaf5 100644 --- a/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V4.h +++ b/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V4.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/menus/juce_BurgerMenuComponent.cpp b/modules/juce_gui_basics/menus/juce_BurgerMenuComponent.cpp index bf301dbd..0ab18d7d 100644 --- a/modules/juce_gui_basics/menus/juce_BurgerMenuComponent.cpp +++ b/modules/juce_gui_basics/menus/juce_BurgerMenuComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -64,9 +63,7 @@ struct CustomMenuBarItemHolder : public Component //============================================================================== BurgerMenuComponent::BurgerMenuComponent (MenuBarModel* modelToUse) { - auto& lf = getLookAndFeel(); - - listBox.setRowHeight (roundToInt (lf.getPopupMenuFont().getHeight() * 2.0f)); + lookAndFeelChanged(); listBox.addMouseListener (this, true); setModel (modelToUse); @@ -291,4 +288,9 @@ void BurgerMenuComponent::handleCommandMessage (int commandID) } } +void BurgerMenuComponent::lookAndFeelChanged() +{ + listBox.setRowHeight (roundToInt (getLookAndFeel().getPopupMenuFont().getHeight() * 2.0f)); +} + } // namespace juce diff --git a/modules/juce_gui_basics/menus/juce_BurgerMenuComponent.h b/modules/juce_gui_basics/menus/juce_BurgerMenuComponent.h index 09407a4e..7812f46f 100644 --- a/modules/juce_gui_basics/menus/juce_BurgerMenuComponent.h +++ b/modules/juce_gui_basics/menus/juce_BurgerMenuComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -70,6 +69,9 @@ public: /** Returns the current burger menu model being used. */ MenuBarModel* getModel() const noexcept; + /** @internal */ + void lookAndFeelChanged() override; + private: //============================================================================== struct Row diff --git a/modules/juce_gui_basics/menus/juce_MenuBarComponent.cpp b/modules/juce_gui_basics/menus/juce_MenuBarComponent.cpp index b24072ac..0bdbea83 100644 --- a/modules/juce_gui_basics/menus/juce_MenuBarComponent.cpp +++ b/modules/juce_gui_basics/menus/juce_MenuBarComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/menus/juce_MenuBarComponent.h b/modules/juce_gui_basics/menus/juce_MenuBarComponent.h index 9d98e583..ac3aef8a 100644 --- a/modules/juce_gui_basics/menus/juce_MenuBarComponent.h +++ b/modules/juce_gui_basics/menus/juce_MenuBarComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/menus/juce_MenuBarModel.cpp b/modules/juce_gui_basics/menus/juce_MenuBarModel.cpp index e7272247..cc921dc4 100644 --- a/modules/juce_gui_basics/menus/juce_MenuBarModel.cpp +++ b/modules/juce_gui_basics/menus/juce_MenuBarModel.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/menus/juce_MenuBarModel.h b/modules/juce_gui_basics/menus/juce_MenuBarModel.h index d496b206..07d6cdb6 100644 --- a/modules/juce_gui_basics/menus/juce_MenuBarModel.h +++ b/modules/juce_gui_basics/menus/juce_MenuBarModel.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/menus/juce_PopupMenu.cpp b/modules/juce_gui_basics/menus/juce_PopupMenu.cpp index 3e273179..833aa217 100644 --- a/modules/juce_gui_basics/menus/juce_PopupMenu.cpp +++ b/modules/juce_gui_basics/menus/juce_PopupMenu.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -44,37 +43,51 @@ struct MenuWindow; static bool canBeTriggered (const PopupMenu::Item& item) noexcept { return item.isEnabled && item.itemID != 0 && ! item.isSectionHeader; } static bool hasActiveSubMenu (const PopupMenu::Item& item) noexcept { return item.isEnabled && item.subMenu != nullptr && item.subMenu->items.size() > 0; } -static const Colour* getColour (const PopupMenu::Item& item) noexcept { return item.colour != Colour() ? &item.colour : nullptr; } -static bool hasSubMenu (const PopupMenu::Item& item) noexcept { return item.subMenu != nullptr && (item.itemID == 0 || item.subMenu->getNumItems() > 0); } //============================================================================== struct HeaderItemComponent : public PopupMenu::CustomComponent { - HeaderItemComponent (const String& name) : PopupMenu::CustomComponent (false) + HeaderItemComponent (const String& name, const Options& opts) + : CustomComponent (false), options (opts) { setName (name); } - void paint (Graphics& g) override; + void paint (Graphics& g) override + { + getLookAndFeel().drawPopupMenuSectionHeaderWithOptions (g, + getLocalBounds(), + getName(), + options); + } void getIdealSize (int& idealWidth, int& idealHeight) override { - getLookAndFeel().getIdealPopupMenuItemSize (getName(), false, -1, idealWidth, idealHeight); + getLookAndFeel().getIdealPopupMenuItemSizeWithOptions (getName(), + false, + -1, + idealWidth, + idealHeight, + options); idealHeight += idealHeight / 2; idealWidth += idealWidth / 4; } + const Options& options; + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (HeaderItemComponent) }; //============================================================================== struct ItemComponent : public Component { - ItemComponent (const PopupMenu::Item& i, int standardItemHeight, MenuWindow& parent) - : item (i), customComp (i.customComponent) + ItemComponent (const PopupMenu::Item& i, + const PopupMenu::Options& o, + MenuWindow& parent) + : item (i), options (o), customComp (i.customComponent) { if (item.isSectionHeader) - customComp = *new HeaderItemComponent (item.text); + customComp = *new HeaderItemComponent (item.text, options); if (customComp != nullptr) { @@ -88,44 +101,48 @@ struct ItemComponent : public Component int itemW = 80; int itemH = 16; - getIdealSize (itemW, itemH, standardItemHeight); + getIdealSize (itemW, itemH, options.getStandardItemHeight()); setSize (itemW, jlimit (1, 600, itemH)); addMouseListener (&parent, false); } - ~ItemComponent() override; + ~ItemComponent() override + { + if (customComp != nullptr) + setItem (*customComp, nullptr); + + removeChildComponent (customComp.get()); + } void getIdealSize (int& idealWidth, int& idealHeight, const int standardItemHeight) { if (customComp != nullptr) customComp->getIdealSize (idealWidth, idealHeight); else - getLookAndFeel().getIdealPopupMenuItemSize (getTextForMeasurement(), - item.isSeparator, - standardItemHeight, - idealWidth, idealHeight); + getLookAndFeel().getIdealPopupMenuItemSizeWithOptions (getTextForMeasurement(), + item.isSeparator, + standardItemHeight, + idealWidth, idealHeight, + options); } void paint (Graphics& g) override { if (customComp == nullptr) - getLookAndFeel().drawPopupMenuItem (g, getLocalBounds(), - item.isSeparator, - item.isEnabled, - isHighlighted, - item.isTicked, - hasSubMenu (item), - item.text, - item.shortcutKeyDescription, - item.image.get(), - getColour (item)); + getLookAndFeel().drawPopupMenuItemWithOptions (g, getLocalBounds(), + isHighlighted, + item, + options); } void resized() override { if (auto* child = getChildComponent (0)) - child->setBounds (getLocalBounds().reduced (getLookAndFeel().getPopupMenuBorderSize(), 0)); + { + const auto border = getLookAndFeel().getPopupMenuBorderSizeWithOptions (options); + child->setBounds (getLocalBounds().reduced (border, 0)); + } } void setHighlighted (bool shouldBeHighlighted) @@ -146,6 +163,7 @@ struct ItemComponent : public Component PopupMenu::Item item; private: + const PopupMenu::Options& options; // NB: we use a copy of the one from the item info in case we're using our own section comp ReferenceCountedObjectPtr<CustomComponent> customComp; bool isHighlighted = false; @@ -208,11 +226,25 @@ struct MenuWindow : public Component setLookAndFeel (parent != nullptr ? &(parent->getLookAndFeel()) : menu.lookAndFeel.get()); + auto& lf = getLookAndFeel(); parentComponent = lf.getParentComponentForMenuOptions (options); const_cast<Options&>(options) = options.withParentComponent (parentComponent); + if (parentComponent != nullptr) + { + parentComponent->addChildComponent (this); + } + else + { + addToDesktop (ComponentPeer::windowIsTemporary + | ComponentPeer::windowIgnoresKeyPresses + | lf.getMenuWindowFlags()); + + Desktop::getInstance().addGlobalMouseListener (this); + } + if (parentComponent == nullptr && parentWindow == nullptr && lf.shouldPopupMenuScaleWithTargetComponent (options)) if (auto* targetComponent = options.getTargetComponent()) scaleFactor = Component::getApproximateScaleFactorForComponent (targetComponent); @@ -220,12 +252,12 @@ struct MenuWindow : public Component setOpaque (lf.findColour (PopupMenu::backgroundColourId).isOpaque() || ! Desktop::canUseSemiTransparentWindows()); - for (size_t i = 0; i < menu.items.size(); ++i) + for (int i = 0; i < menu.items.size(); ++i) { - auto& item = menu.items[i]; + auto& item = menu.items.getReference (i); if (i + 1 < menu.items.size() || ! item.isSeparator) - items.add (new ItemComponent (item, options.getStandardItemHeight(), *this)); + items.add (new ItemComponent (item, options, *this)); } auto targetArea = options.getTargetScreenArea() / scaleFactor; @@ -245,26 +277,19 @@ struct MenuWindow : public Component resizeToBestWindowPos(); - if (parentComponent != nullptr) - { - parentComponent->addChildComponent (this); - } - else - { - addToDesktop (ComponentPeer::windowIsTemporary - | ComponentPeer::windowIgnoresKeyPresses - | lf.getMenuWindowFlags()); - - Desktop::getInstance().addGlobalMouseListener (this); - } - getActiveWindows().add (this); lf.preparePopupMenuWindow (*this); getMouseState (Desktop::getInstance().getMainMouseSource()); // forces creation of a mouse source watcher for the main mouse } - ~MenuWindow() override; + ~MenuWindow() override + { + getActiveWindows().removeFirstMatchingValue (this); + Desktop::getInstance().removeGlobalMouseListener (this); + activeSubMenu.reset(); + items.clear(); + } //============================================================================== void paint (Graphics& g) override @@ -272,7 +297,26 @@ struct MenuWindow : public Component if (isOpaque()) g.fillAll (Colours::white); - getLookAndFeel().drawPopupMenuBackground (g, getWidth(), getHeight()); + auto& theme = getLookAndFeel(); + theme.drawPopupMenuBackgroundWithOptions (g, getWidth(), getHeight(), options); + + if (columnWidths.isEmpty()) + return; + + const auto separatorWidth = theme.getPopupMenuColumnSeparatorWidthWithOptions (options); + const auto border = theme.getPopupMenuBorderSizeWithOptions (options); + + auto currentX = 0; + + std::for_each (columnWidths.begin(), std::prev (columnWidths.end()), [&] (int width) + { + const Rectangle<int> separator (currentX + width, + border, + separatorWidth, + getHeight() - border * 2); + theme.drawPopupMenuColumnSeparatorWithOptions (g, separator, options); + currentX += width + separatorWidth; + }); } void paintOverChildren (Graphics& g) override @@ -281,17 +325,27 @@ struct MenuWindow : public Component if (parentComponent != nullptr) lf.drawResizableFrame (g, getWidth(), getHeight(), - BorderSize<int> (getLookAndFeel().getPopupMenuBorderSize())); + BorderSize<int> (getLookAndFeel().getPopupMenuBorderSizeWithOptions (options))); if (canScroll()) { if (isTopScrollZoneActive()) - lf.drawPopupMenuUpDownArrow (g, getWidth(), PopupMenuSettings::scrollZone, true); + { + lf.drawPopupMenuUpDownArrowWithOptions (g, + getWidth(), + PopupMenuSettings::scrollZone, + true, + options); + } if (isBottomScrollZoneActive()) { g.setOrigin (0, getHeight() - PopupMenuSettings::scrollZone); - lf.drawPopupMenuUpDownArrow (g, getWidth(), PopupMenuSettings::scrollZone, false); + lf.drawPopupMenuUpDownArrowWithOptions (g, + getWidth(), + PopupMenuSettings::scrollZone, + false, + options); } } } @@ -368,11 +422,11 @@ struct MenuWindow : public Component { if (key.isKeyCode (KeyPress::downKey)) { - selectNextItem (1); + selectNextItem (MenuSelectionDirection::forwards); } else if (key.isKeyCode (KeyPress::upKey)) { - selectNextItem (-1); + selectNextItem (MenuSelectionDirection::backwards); } else if (key.isKeyCode (KeyPress::leftKey)) { @@ -400,14 +454,14 @@ struct MenuWindow : public Component if (showSubMenuFor (currentChild)) { if (isSubMenuVisible()) - activeSubMenu->selectNextItem (1); + activeSubMenu->selectNextItem (MenuSelectionDirection::current); } else if (componentAttachedTo != nullptr) { componentAttachedTo->keyPressed (key); } } - else if (key.isKeyCode (KeyPress::returnKey)) + else if (key.isKeyCode (KeyPress::returnKey) || key.isKeyCode (KeyPress::spaceKey)) { triggerCurrentlyHighlightedItem(); } @@ -595,11 +649,11 @@ struct MenuWindow : public Component if (relativeTo != nullptr) targetPoint = relativeTo->localPointToGlobal (targetPoint); - auto parentArea = Desktop::getInstance().getDisplays().findDisplayForPoint (targetPoint * scaleFactor) + auto parentArea = Desktop::getInstance().getDisplays().getDisplayForPoint (targetPoint * scaleFactor) #if JUCE_MAC || JUCE_ANDROID - .userArea; + ->userArea; #else - .totalArea; // on windows, don't stop the menu overlapping the taskbar + ->totalArea; // on windows, don't stop the menu overlapping the taskbar #endif if (parentComponent == nullptr) @@ -607,7 +661,7 @@ struct MenuWindow : public Component return parentComponent->getLocalArea (nullptr, parentComponent->getScreenBounds() - .reduced (getLookAndFeel().getPopupMenuBorderSize()) + .reduced (getLookAndFeel().getPopupMenuBorderSizeWithOptions (options)) .getIntersection (parentArea)); } @@ -676,7 +730,7 @@ struct MenuWindow : public Component x = tendTowardsRight ? jmin (parentArea.getRight() - widthToUse - 4, target.getRight()) : jmax (parentArea.getX() + 4, target.getX() - widthToUse); - if (getLookAndFeel().getPopupMenuBorderSize() == 0) // workaround for dismissing the window on mouse up when border size is 0 + if (getLookAndFeel().getPopupMenuBorderSizeWithOptions (options) == 0) // workaround for dismissing the window on mouse up when border size is 0 x += tendTowardsRight ? 1 : -1; y = target.getCentreY() > parentArea.getCentreY() ? jmax (parentArea.getY(), target.getBottom() - heightToUse) @@ -694,6 +748,28 @@ struct MenuWindow : public Component } void layoutMenuItems (const int maxMenuW, const int maxMenuH, int& width, int& height) + { + // Ensure we don't try to add an empty column after the final item + if (auto* last = items.getLast()) + last->item.shouldBreakAfter = false; + + const auto isBreak = [] (const ItemComponent* item) { return item->item.shouldBreakAfter; }; + const auto numBreaks = static_cast<int> (std::count_if (items.begin(), items.end(), isBreak)); + numColumns = numBreaks + 1; + + if (numBreaks == 0) + insertColumnBreaks (maxMenuW, maxMenuH); + + workOutManualSize (maxMenuW); + auto actualH = jmin (contentHeight, maxMenuH); + + needsToScroll = contentHeight > actualH; + + width = updateYPositions(); + height = actualH + getLookAndFeel().getPopupMenuBorderSizeWithOptions (options) * 2; + } + + void insertColumnBreaks (const int maxMenuW, const int maxMenuH) { numColumns = options.getMinimumNumColumns(); contentHeight = 0; @@ -712,24 +788,74 @@ struct MenuWindow : public Component } if (totalW > maxMenuW / 2 - || contentHeight < maxMenuH - || numColumns >= maximumNumColumns) + || contentHeight < maxMenuH + || numColumns >= maximumNumColumns) break; ++numColumns; } - auto actualH = jmin (contentHeight, maxMenuH); + const auto itemsPerColumn = (items.size() + numColumns - 1) / numColumns; - needsToScroll = contentHeight > actualH; + for (auto i = 0;; i += itemsPerColumn) + { + const auto breakIndex = i + itemsPerColumn - 1; - width = updateYPositions(); - height = actualH + getLookAndFeel().getPopupMenuBorderSize() * 2; + if (breakIndex >= items.size()) + break; + + items[breakIndex]->item.shouldBreakAfter = true; + } + + if (! items.isEmpty()) + (*std::prev (items.end()))->item.shouldBreakAfter = false; + } + + int correctColumnWidths (const int maxMenuW) + { + auto totalW = std::accumulate (columnWidths.begin(), columnWidths.end(), 0); + const auto minWidth = jmin (maxMenuW, options.getMinimumWidth()); + + if (totalW < minWidth) + { + totalW = minWidth; + + for (auto& column : columnWidths) + column = totalW / numColumns; + } + + return totalW; + } + + void workOutManualSize (const int maxMenuW) + { + contentHeight = 0; + columnWidths.clear(); + + for (auto it = items.begin(), end = items.end(); it != end;) + { + const auto isBreak = [] (const ItemComponent* item) { return item->item.shouldBreakAfter; }; + const auto nextBreak = std::find_if (it, end, isBreak); + const auto columnEnd = nextBreak == end ? end : std::next (nextBreak); + + const auto getMaxWidth = [] (int acc, const ItemComponent* item) { return jmax (acc, item->getWidth()); }; + const auto colW = std::accumulate (it, columnEnd, options.getStandardItemHeight(), getMaxWidth); + const auto adjustedColW = jmin (maxMenuW / jmax (1, numColumns - 2), + colW + getLookAndFeel().getPopupMenuBorderSizeWithOptions (options) * 2); + + const auto sumHeight = [] (int acc, const ItemComponent* item) { return acc + item->getHeight(); }; + const auto colH = std::accumulate (it, columnEnd, 0, sumHeight); + + contentHeight = jmax (contentHeight, colH); + columnWidths.add (adjustedColW); + it = columnEnd; + } + + correctColumnWidths (maxMenuW); } int workOutBestSize (const int maxMenuW) { - int totalW = 0; contentHeight = 0; int childNum = 0; @@ -746,27 +872,16 @@ struct MenuWindow : public Component colH += items.getUnchecked (childNum + i)->getHeight(); } - colW = jmin (maxMenuW / jmax (1, numColumns - 2), colW + getLookAndFeel().getPopupMenuBorderSize() * 2); + colW = jmin (maxMenuW / jmax (1, numColumns - 2), + colW + getLookAndFeel().getPopupMenuBorderSizeWithOptions (options) * 2); columnWidths.set (col, colW); - totalW += colW; contentHeight = jmax (contentHeight, colH); childNum += numChildren; } - // width must never be larger than the screen - auto minWidth = jmin (maxMenuW, options.getMinimumWidth()); - - if (totalW < minWidth) - { - totalW = minWidth; - - for (int col = 0; col < numColumns; ++col) - columnWidths.set (0, totalW / numColumns); - } - - return totalW; + return correctColumnWidths (maxMenuW); } void ensureItemIsVisible (const int itemID, int wantedY) @@ -840,11 +955,21 @@ struct MenuWindow : public Component { childYOffset += delta; - if (delta < 0) - childYOffset = jmax (childYOffset, 0); - else if (delta > 0) - childYOffset = jmin (childYOffset, - contentHeight - windowPos.getHeight() + getLookAndFeel().getPopupMenuBorderSize()); + childYOffset = [&] + { + if (delta < 0) + return jmax (childYOffset, 0); + + if (delta > 0) + { + const auto limit = contentHeight + - windowPos.getHeight() + + getLookAndFeel().getPopupMenuBorderSizeWithOptions (options); + return jmin (childYOffset, limit); + } + + return childYOffset; + }(); updateYPositions(); } @@ -859,29 +984,31 @@ struct MenuWindow : public Component int updateYPositions() { - int x = 0; - int childNum = 0; + const auto separatorWidth = getLookAndFeel().getPopupMenuColumnSeparatorWidthWithOptions (options); + const auto initialY = getLookAndFeel().getPopupMenuBorderSizeWithOptions (options) + - (childYOffset + (getY() - windowPos.getY())); - for (int col = 0; col < numColumns; ++col) - { - auto numChildren = jmin (items.size() - childNum, - (items.size() + numColumns - 1) / numColumns); + auto col = 0; + auto x = 0; + auto y = initialY; - auto colW = columnWidths[col]; - auto y = getLookAndFeel().getPopupMenuBorderSize() - (childYOffset + (getY() - windowPos.getY())); + for (const auto& item : items) + { + jassert (col < columnWidths.size()); + const auto columnWidth = columnWidths[col]; + item->setBounds (x, y, columnWidth, item->getHeight()); + y += item->getHeight(); - for (int i = 0; i < numChildren; ++i) + if (item->item.shouldBreakAfter) { - auto* c = items.getUnchecked (childNum + i); - c->setBounds (x, y, colW, c->getHeight()); - y += c->getHeight(); + col += 1; + x += columnWidth + separatorWidth; + y = initialY; } - - x += colW; - childNum += numChildren; } - return x; + return std::accumulate (columnWidths.begin(), columnWidths.end(), 0) + + (separatorWidth * (columnWidths.size() - 1)); } void setCurrentlyHighlightedChild (ItemComponent* child) @@ -934,24 +1061,46 @@ struct MenuWindow : public Component } } - void selectNextItem (int delta) + enum class MenuSelectionDirection + { + forwards, + backwards, + current + }; + + void selectNextItem (MenuSelectionDirection direction) { disableTimerUntilMouseMoves(); - auto start = jmax (0, items.indexOf (currentChild)); + auto start = [&] + { + auto index = items.indexOf (currentChild); + + if (index >= 0) + return index; + + return direction == MenuSelectionDirection::backwards ? items.size() - 1 + : 0; + }(); + + auto preIncrement = (direction != MenuSelectionDirection::current && currentChild != nullptr); for (int i = items.size(); --i >= 0;) { - start += delta; + if (preIncrement) + start += (direction == MenuSelectionDirection::backwards ? -1 : 1); if (auto* mic = items.getUnchecked ((start + items.size()) % items.size())) { if (canBeTriggered (mic->item) || hasActiveSubMenu (mic->item)) { setCurrentlyHighlightedChild (mic); - break; + return; } } + + if (! preIncrement) + preIncrement = true; } } @@ -998,7 +1147,14 @@ public: startTimerHz (20); } - void handleMouseEvent (const MouseEvent& e); + void handleMouseEvent (const MouseEvent& e) + { + if (! window.windowIsStillValid()) + return; + + startTimerHz (20); + handleMousePosition (e.getScreenPosition()); + } void timerCallback() override { @@ -1156,7 +1312,7 @@ private: else { oldGlobalPos += Point<int> (2, 0); - subX += itemScreenBounds.getWidth(); + subX += (float) itemScreenBounds.getWidth(); } Path areaTowardsSubMenu; @@ -1228,7 +1384,11 @@ struct NormalComponentWrapper : public PopupMenu::CustomComponent addAndMakeVisible (comp); } - void getIdealSize (int& idealWidth, int& idealHeight) override; + void getIdealSize (int& idealWidth, int& idealHeight) override + { + idealWidth = width; + idealHeight = height; + } void resized() override { @@ -1243,49 +1403,7 @@ struct NormalComponentWrapper : public PopupMenu::CustomComponent }; -// The following implementations are outside of the class definitions to avoid spurious -// warning messages when dynamically loading libraries at runtime on macOS -void PopupMenu::HelperClasses::HeaderItemComponent::paint (Graphics& g) -{ - getLookAndFeel().drawPopupMenuSectionHeader (g, getLocalBounds(), getName()); -} - -PopupMenu::HelperClasses::ItemComponent::~ItemComponent() -{ - if (customComp != nullptr) - setItem (*customComp, nullptr); - - removeChildComponent (customComp.get()); -} - -PopupMenu::HelperClasses::MenuWindow::~MenuWindow() -{ - getActiveWindows().removeFirstMatchingValue (this); - Desktop::getInstance().removeGlobalMouseListener (this); - activeSubMenu.reset(); - items.clear(); -} - -void PopupMenu::HelperClasses::MouseSourceState::handleMouseEvent (const MouseEvent& e) -{ - if (! window.windowIsStillValid()) - return; - - startTimerHz (20); - handleMousePosition (e.getScreenPosition()); -} - -void PopupMenu::HelperClasses::NormalComponentWrapper::getIdealSize (int& idealWidth, int& idealHeight) -{ - idealWidth = width; - idealHeight = height; -} - //============================================================================== -PopupMenu::PopupMenu() -{ -} - PopupMenu::PopupMenu (const PopupMenu& other) : items (other.items), lookAndFeel (other.lookAndFeel) @@ -1344,9 +1462,9 @@ PopupMenu::Item::Item (const Item& other) isEnabled (other.isEnabled), isTicked (other.isTicked), isSeparator (other.isSeparator), - isSectionHeader (other.isSectionHeader) -{ -} + isSectionHeader (other.isSectionHeader), + shouldBreakAfter (other.shouldBreakAfter) +{} PopupMenu::Item& PopupMenu::Item::operator= (const Item& other) { @@ -1364,6 +1482,7 @@ PopupMenu::Item& PopupMenu::Item::operator= (const Item& other) isTicked = other.isTicked; isSeparator = other.isSeparator; isSectionHeader = other.isSectionHeader; + shouldBreakAfter = other.shouldBreakAfter; return *this; } @@ -1459,7 +1578,7 @@ void PopupMenu::addItem (Item newItem) || newItem.isSeparator || newItem.isSectionHeader || newItem.subMenu != nullptr); - items.push_back (std::move (newItem)); + items.add (std::move (newItem)); } void PopupMenu::addItem (String itemText, std::function<void()> action) @@ -1608,7 +1727,7 @@ void PopupMenu::addSubMenu (String subMenuName, PopupMenu subMenu, bool isActive void PopupMenu::addSeparator() { - if (items.size() > 0 && ! items.back().isSeparator) + if (items.size() > 0 && ! items.getLast().isSeparator) { Item i; i.isSeparator = true; @@ -1624,6 +1743,12 @@ void PopupMenu::addSectionHeader (String title) addItem (std::move (i)); } +void PopupMenu::addColumnBreak() +{ + if (! items.isEmpty()) + std::prev (items.end())->shouldBreakAfter = true; +} + //============================================================================== PopupMenu::Options::Options() { @@ -1713,11 +1838,11 @@ PopupMenu::Options PopupMenu::Options::withPreferredPopupDirection (PopupDirecti Component* PopupMenu::createWindow (const Options& options, ApplicationCommandManager** managerOfChosenCommand) const { - return items.empty() ? nullptr - : new HelperClasses::MenuWindow (*this, nullptr, options, - ! options.getTargetScreenArea().isEmpty(), - ModifierKeys::currentModifiers.isAnyMouseButtonDown(), - managerOfChosenCommand); + return items.isEmpty() ? nullptr + : new HelperClasses::MenuWindow (*this, nullptr, options, + ! options.getTargetScreenArea().isEmpty(), + ModifierKeys::currentModifiers.isAnyMouseButtonDown(), + managerOfChosenCommand); } //============================================================================== @@ -1813,7 +1938,7 @@ void PopupMenu::showMenuAsync (const Options& options, ModalComponentManager::Ca showWithOptionalCallback (options, userCallback, false); } -void PopupMenu::showMenuAsync (const Options& options, std::function<void(int)> userCallback) +void PopupMenu::showMenuAsync (const Options& options, std::function<void (int)> userCallback) { showWithOptionalCallback (options, ModalCallbackFunction::create (userCallback), false); } @@ -1985,7 +2110,7 @@ bool PopupMenu::MenuItemIterator::next() if (index.size() == 0 || menus.getLast()->items.size() == 0) return false; - currentItem = const_cast<PopupMenu::Item*> (&(menus.getLast()->items[(size_t) index.getLast()])); + currentItem = const_cast<PopupMenu::Item*> (&(menus.getLast()->items.getReference (index.getLast()))); if (searchRecursively && currentItem->subMenu != nullptr) { @@ -2015,4 +2140,23 @@ PopupMenu::Item& PopupMenu::MenuItemIterator::getItem() const return *(currentItem); } +void PopupMenu::LookAndFeelMethods::drawPopupMenuBackground (Graphics&, int, int) {} + +void PopupMenu::LookAndFeelMethods::drawPopupMenuItem (Graphics&, const Rectangle<int>&, + bool, bool, bool, + bool, bool, + const String&, + const String&, + const Drawable*, + const Colour*) {} + +void PopupMenu::LookAndFeelMethods::drawPopupMenuSectionHeader (Graphics&, const Rectangle<int>&, + const String&) {} + +void PopupMenu::LookAndFeelMethods::drawPopupMenuUpDownArrow (Graphics&, int, int, bool) {} + +void PopupMenu::LookAndFeelMethods::getIdealPopupMenuItemSize (const String&, bool, int, int&, int&) {} + +int PopupMenu::LookAndFeelMethods::getPopupMenuBorderSize() { return 0; } + } // namespace juce diff --git a/modules/juce_gui_basics/menus/juce_PopupMenu.h b/modules/juce_gui_basics/menus/juce_PopupMenu.h index 60bedebf..04bafe87 100644 --- a/modules/juce_gui_basics/menus/juce_PopupMenu.h +++ b/modules/juce_gui_basics/menus/juce_PopupMenu.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -82,7 +81,7 @@ class JUCE_API PopupMenu public: //============================================================================== /** Creates an empty popup menu. */ - PopupMenu(); + PopupMenu() = default; /** Creates a copy of another menu. */ PopupMenu (const PopupMenu&); @@ -180,6 +179,9 @@ public: /** True if this menu item is a section header. */ bool isSectionHeader = false; + /** True if this is the final item in the current column. */ + bool shouldBreakAfter = false; + /** Sets the isTicked flag (and returns a reference to this item to allow chaining). */ Item& setTicked (bool shouldBeTicked = true) & noexcept; /** Sets the isEnabled flag (and returns a reference to this item to allow chaining). */ @@ -411,6 +413,15 @@ public: */ void addSectionHeader (String title); + /** Adds a column break to the menu, to help break it up into sections. + Subsequent items will be placed in a new column, rather than being appended + to the current column. + + If a menu contains explicit column breaks, the menu will never add additional + breaks. + */ + void addColumnBreak(); + /** Returns the number of items that the menu currently contains. (This doesn't count separators). */ @@ -572,7 +583,7 @@ public: /** Runs the menu asynchronously, with a user-provided callback that will receive the result. */ void showMenuAsync (const Options& options, - std::function<void(int)> callback); + std::function<void (int)> callback); //============================================================================== /** Closes any menus that are currently open. @@ -754,7 +765,13 @@ public: virtual ~LookAndFeelMethods() = default; /** Fills the background of a popup menu component. */ - virtual void drawPopupMenuBackground (Graphics&, int width, int height) = 0; + virtual void drawPopupMenuBackground (Graphics&, int width, int height); + + /** Fills the background of a popup menu component. */ + virtual void drawPopupMenuBackgroundWithOptions (Graphics&, + int width, + int height, + const Options&) = 0; /** Draws one of the items in a popup menu. */ virtual void drawPopupMenuItem (Graphics&, const Rectangle<int>& area, @@ -763,24 +780,47 @@ public: const String& text, const String& shortcutKeyText, const Drawable* icon, - const Colour* textColour) = 0; + const Colour* textColour); + + /** Draws one of the items in a popup menu. */ + virtual void drawPopupMenuItemWithOptions (Graphics&, const Rectangle<int>& area, + bool isHighlighted, + const Item& item, + const Options&) = 0; + + virtual void drawPopupMenuSectionHeader (Graphics&, const Rectangle<int>&, + const String&); - virtual void drawPopupMenuSectionHeader (Graphics&, const Rectangle<int>& area, - const String& sectionName) = 0; + virtual void drawPopupMenuSectionHeaderWithOptions (Graphics&, const Rectangle<int>& area, + const String& sectionName, + const Options&) = 0; /** Returns the size and style of font to use in popup menus. */ virtual Font getPopupMenuFont() = 0; virtual void drawPopupMenuUpDownArrow (Graphics&, int width, int height, - bool isScrollUpArrow) = 0; + bool isScrollUpArrow); + + virtual void drawPopupMenuUpDownArrowWithOptions (Graphics&, + int width, int height, + bool isScrollUpArrow, + const Options&) = 0; /** Finds the best size for an item in a popup menu. */ virtual void getIdealPopupMenuItemSize (const String& text, bool isSeparator, int standardMenuItemHeight, int& idealWidth, - int& idealHeight) = 0; + int& idealHeight); + + /** Finds the best size for an item in a popup menu. */ + virtual void getIdealPopupMenuItemSizeWithOptions (const String& text, + bool isSeparator, + int standardMenuItemHeight, + int& idealWidth, + int& idealHeight, + const Options&) = 0; virtual int getMenuWindowFlags() = 0; @@ -802,15 +842,30 @@ public: bool isMouseOverBar, MenuBarComponent&) = 0; - virtual Component* getParentComponentForMenuOptions (const PopupMenu::Options& options) = 0; + virtual Component* getParentComponentForMenuOptions (const Options& options) = 0; virtual void preparePopupMenuWindow (Component& newWindow) = 0; /** Return true if you want your popup menus to scale with the target component's AffineTransform - or scale factor */ - virtual bool shouldPopupMenuScaleWithTargetComponent (const PopupMenu::Options& options) = 0; + or scale factor + */ + virtual bool shouldPopupMenuScaleWithTargetComponent (const Options& options) = 0; + + virtual int getPopupMenuBorderSize(); + + virtual int getPopupMenuBorderSizeWithOptions (const Options&) = 0; + + /** Implement this to draw some custom decoration between the columns of the popup menu. + + `getPopupMenuColumnSeparatorWidthWithOptions` must return a positive value in order + to display the separator. + */ + virtual void drawPopupMenuColumnSeparatorWithOptions (Graphics& g, + const Rectangle<int>& bounds, + const Options&) = 0; - virtual int getPopupMenuBorderSize() = 0; + /** Return the amount of space that should be left between popup menu columns. */ + virtual int getPopupMenuColumnSeparatorWidthWithOptions (const Options&) = 0; }; private: @@ -820,7 +875,7 @@ private: friend struct HelperClasses; friend class MenuBarComponent; - std::vector<Item> items; + Array<Item> items; WeakReference<LookAndFeel> lookAndFeel; Component* createWindow (const Options&, ApplicationCommandManager**) const; diff --git a/modules/juce_gui_basics/misc/juce_BubbleComponent.cpp b/modules/juce_gui_basics/misc/juce_BubbleComponent.cpp index 833e3546..7c084864 100644 --- a/modules/juce_gui_basics/misc/juce_BubbleComponent.cpp +++ b/modules/juce_gui_basics/misc/juce_BubbleComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/misc/juce_BubbleComponent.h b/modules/juce_gui_basics/misc/juce_BubbleComponent.h index 4aab911f..f086c8ff 100644 --- a/modules/juce_gui_basics/misc/juce_BubbleComponent.h +++ b/modules/juce_gui_basics/misc/juce_BubbleComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/misc/juce_DropShadower.cpp b/modules/juce_gui_basics/misc/juce_DropShadower.cpp index 8f4fcb07..c8bfe629 100644 --- a/modules/juce_gui_basics/misc/juce_DropShadower.cpp +++ b/modules/juce_gui_basics/misc/juce_DropShadower.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/misc/juce_DropShadower.h b/modules/juce_gui_basics/misc/juce_DropShadower.h index 0aba4450..f28b5f2d 100644 --- a/modules/juce_gui_basics/misc/juce_DropShadower.h +++ b/modules/juce_gui_basics/misc/juce_DropShadower.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/misc/juce_JUCESplashScreen.cpp b/modules/juce_gui_basics/misc/juce_JUCESplashScreen.cpp index 3c0b527a..42763266 100644 --- a/modules/juce_gui_basics/misc/juce_JUCESplashScreen.cpp +++ b/modules/juce_gui_basics/misc/juce_JUCESplashScreen.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -30,22 +29,18 @@ namespace juce /* ============================================================================== - In accordance with the terms of the JUCE 5 End-Use License Agreement, the + In accordance with the terms of the JUCE 6 End-Use License Agreement, the JUCE Code in SECTION A cannot be removed, changed or otherwise rendered ineffective unless you have a JUCE Indie or Pro license, or are using JUCE under the GPL v3 license. - End User License Agreement: www.juce.com/juce-5-licence + End User License Agreement: www.juce.com/juce-6-licence ============================================================================== */ // BEGIN SECTION A -#if ! defined (JUCE_REPORT_APP_USAGE) - #define JUCE_REPORT_APP_USAGE 1 -#endif - #if ! defined (JUCE_DISPLAY_SPLASH_SCREEN) #define JUCE_DISPLAY_SPLASH_SCREEN 1 #endif @@ -57,8 +52,7 @@ namespace juce static const int millisecondsToDisplaySplash = 2000, splashScreenFadeOutTime = 2000; static const int splashScreenLogoWidth = 123, splashScreenLogoHeight = 63; static uint32 splashDisplayTime = 0; -static bool splashHasStartedFading = false, appUsageReported = false; - +static bool splashHasStartedFading = false; static Rectangle<float> getLogoArea (Rectangle<float> parentRect) { @@ -67,175 +61,11 @@ static Rectangle<float> getLogoArea (Rectangle<float> parentRect) .removeFromBottom ((float) splashScreenLogoHeight); } -//============================================================================== -struct ReportingThread; - -struct ReportingThreadContainer : public ChangeListener, - public DeletedAtShutdown -{ - ReportingThreadContainer() {} - ~ReportingThreadContainer() override { clearSingletonInstance(); } - - void sendReport (String, String&, StringPairArray&); - void changeListenerCallback (ChangeBroadcaster*) override; - - std::unique_ptr<ReportingThread> reportingThread; - - JUCE_DECLARE_SINGLETON_SINGLETHREADED_MINIMAL (ReportingThreadContainer) -}; - -JUCE_IMPLEMENT_SINGLETON (ReportingThreadContainer) - -//============================================================================== -struct ReportingThread : public Thread, - private ChangeBroadcaster -{ - ReportingThread (ReportingThreadContainer& container, - String& address, - String& userAgent, - StringPairArray& parameters) - : Thread ("JUCE app usage reporting"), - threadContainer (container), - headers ("User-Agent: " + userAgent) - { - StringArray postData; - - for (auto& key : parameters.getAllKeys()) - if (parameters[key].isNotEmpty()) - postData.add (key + "=" + URL::addEscapeChars (parameters[key], true)); - - url = URL (address).withPOSTData (postData.joinIntoString ("&")); - - addChangeListener (&threadContainer); - } - - ~ReportingThread() override - { - removeChangeListener (&threadContainer); - - if (webStream != nullptr) - webStream->cancel(); - - stopThread (2000); - } - - void run() override - { - webStream.reset (new WebInputStream (url, true)); - webStream->withExtraHeaders (headers); - webStream->connect (nullptr); - - sendChangeMessage(); - } - -private: - ReportingThreadContainer& threadContainer; - URL url; - String headers; - std::unique_ptr<WebInputStream> webStream; -}; - -//============================================================================== -void ReportingThreadContainer::sendReport (String address, String& userAgent, StringPairArray& parameters) -{ - reportingThread.reset (new ReportingThread (*this, address, userAgent, parameters)); - reportingThread->startThread(); -} - -void ReportingThreadContainer::changeListenerCallback (ChangeBroadcaster*) -{ - reportingThread.reset(); -} - //============================================================================== JUCESplashScreen::JUCESplashScreen (Component& parent) { ignoreUnused (parent); - #if JUCE_REPORT_APP_USAGE - if (! appUsageReported) - { - const ScopedTryLock appUsageReportingLock (appUsageReporting); - - if (appUsageReportingLock.isLocked() && ! appUsageReported) - { - const auto deviceDescription = SystemStats::getDeviceDescription(); - const auto deviceString = SystemStats::getDeviceIdentifiers().joinIntoString (":"); - const auto deviceIdentifier = String::toHexString (deviceString.hashCode64()); - const auto osName = SystemStats::getOperatingSystemName(); - - StringPairArray data; - - data.set ("v", "1"); - data.set ("tid", "UA-19759318-3"); - data.set ("cid", deviceIdentifier); - data.set ("t", "event"); - data.set ("ec", "info"); - data.set ("ea", "appStarted"); - - data.set ("cd1", SystemStats::getJUCEVersion()); - data.set ("cd2", osName); - data.set ("cd3", deviceDescription); - data.set ("cd4", deviceIdentifier); - - String appType, appName, appVersion, appManufacturer; - - #if defined(JucePlugin_Name) - appType = "Plugin"; - appName = JucePlugin_Name; - appVersion = JucePlugin_VersionString; - appManufacturer = JucePlugin_Manufacturer; - #else - if (JUCEApplicationBase::isStandaloneApp()) - { - appType = "Application"; - - if (auto* app = JUCEApplicationBase::getInstance()) - { - appName = app->getApplicationName(); - appVersion = app->getApplicationVersion(); - } - } - else - { - appType = "Library"; - } - #endif - - data.set ("cd5", appType); - data.set ("cd6", appName); - data.set ("cd7", appVersion); - data.set ("cd8", appManufacturer); - - data.set ("an", appName); - data.set ("av", appVersion); - - auto agentCPUVendor = SystemStats::getCpuVendor(); - - if (agentCPUVendor.isEmpty()) - agentCPUVendor = "CPU"; - - auto agentOSName = osName.replaceCharacter ('.', '_') - .replace ("iOS", "iPhone OS"); - #if JUCE_IOS - agentOSName << " like Mac OS X"; - #endif - - String userAgent; - userAgent << "Mozilla/5.0 (" - << deviceDescription << ";" - << agentCPUVendor << " " << agentOSName << ";" - << SystemStats::getDisplayLanguage() << ")"; - - ReportingThreadContainer::getInstance()->sendReport ("https://www.google-analytics.com/collect", userAgent, data); - - appUsageReported = true; - } - } - #else - ignoreUnused (appUsageReported); - #endif - #if JUCE_DISPLAY_SPLASH_SCREEN if (splashDisplayTime == 0 || Time::getMillisecondCounter() < splashDisplayTime + (uint32) millisecondsToDisplaySplash) @@ -252,10 +82,6 @@ JUCESplashScreen::JUCESplashScreen (Component& parent) } } -JUCESplashScreen::~JUCESplashScreen() -{ -} - std::unique_ptr<Drawable> JUCESplashScreen::getSplashScreenLogo() { const char* svgData = R"JUCESPLASHSCREEN( diff --git a/modules/juce_gui_basics/misc/juce_JUCESplashScreen.h b/modules/juce_gui_basics/misc/juce_JUCESplashScreen.h index 3f84aa98..3767fc30 100644 --- a/modules/juce_gui_basics/misc/juce_JUCESplashScreen.h +++ b/modules/juce_gui_basics/misc/juce_JUCESplashScreen.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -27,12 +26,12 @@ /* ============================================================================== - In accordance with the terms of the JUCE 5 End-Use License Agreement, the + In accordance with the terms of the JUCE 6 End-Use License Agreement, the JUCE Code in SECTION A cannot be removed, changed or otherwise rendered ineffective unless you have a JUCE Indie or Pro license, or are using JUCE under the GPL v3 license. - End User License Agreement: www.juce.com/juce-5-licence + End User License Agreement: www.juce.com/juce-6-licence ============================================================================== */ @@ -53,7 +52,6 @@ class JUCE_API JUCESplashScreen : public Component, { public: JUCESplashScreen (Component& parentToAddTo); - ~JUCESplashScreen() override; static std::unique_ptr<Drawable> getSplashScreenLogo(); @@ -66,7 +64,6 @@ private: void mouseUp (const MouseEvent&) override; std::unique_ptr<Drawable> content; - CriticalSection appUsageReporting; ComponentAnimator fader; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (JUCESplashScreen) diff --git a/modules/juce_gui_basics/mouse/juce_ComponentDragger.cpp b/modules/juce_gui_basics/mouse/juce_ComponentDragger.cpp index 8814b327..75dbdf96 100644 --- a/modules/juce_gui_basics/mouse/juce_ComponentDragger.cpp +++ b/modules/juce_gui_basics/mouse/juce_ComponentDragger.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/mouse/juce_ComponentDragger.h b/modules/juce_gui_basics/mouse/juce_ComponentDragger.h index f8e0cb22..b4374038 100644 --- a/modules/juce_gui_basics/mouse/juce_ComponentDragger.h +++ b/modules/juce_gui_basics/mouse/juce_ComponentDragger.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/mouse/juce_DragAndDropContainer.cpp b/modules/juce_gui_basics/mouse/juce_DragAndDropContainer.cpp index cff272c0..77ef5943 100644 --- a/modules/juce_gui_basics/mouse/juce_DragAndDropContainer.cpp +++ b/modules/juce_gui_basics/mouse/juce_DragAndDropContainer.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -439,7 +438,7 @@ void DragAndDropContainer::startDragging (const var& sourceDescription, if (distance > lo) { auto alpha = (distance > hi) ? 0 - : (hi - distance) / (float) (hi - lo) + : (float) (hi - distance) / (float) (hi - lo) + random.nextFloat() * 0.008f; dragImage.multiplyAlphaAt (x, y, alpha); diff --git a/modules/juce_gui_basics/mouse/juce_DragAndDropContainer.h b/modules/juce_gui_basics/mouse/juce_DragAndDropContainer.h index a03c5362..f1c6d5ad 100644 --- a/modules/juce_gui_basics/mouse/juce_DragAndDropContainer.h +++ b/modules/juce_gui_basics/mouse/juce_DragAndDropContainer.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/mouse/juce_DragAndDropTarget.h b/modules/juce_gui_basics/mouse/juce_DragAndDropTarget.h index 8ba892c3..a160b2ca 100644 --- a/modules/juce_gui_basics/mouse/juce_DragAndDropTarget.h +++ b/modules/juce_gui_basics/mouse/juce_DragAndDropTarget.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/mouse/juce_FileDragAndDropTarget.h b/modules/juce_gui_basics/mouse/juce_FileDragAndDropTarget.h index d3bc5597..6431651d 100644 --- a/modules/juce_gui_basics/mouse/juce_FileDragAndDropTarget.h +++ b/modules/juce_gui_basics/mouse/juce_FileDragAndDropTarget.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/mouse/juce_LassoComponent.h b/modules/juce_gui_basics/mouse/juce_LassoComponent.h index c89b97c7..a28b8724 100644 --- a/modules/juce_gui_basics/mouse/juce_LassoComponent.h +++ b/modules/juce_gui_basics/mouse/juce_LassoComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/mouse/juce_MouseCursor.cpp b/modules/juce_gui_basics/mouse/juce_MouseCursor.cpp index dd93e90e..88ed9ae4 100644 --- a/modules/juce_gui_basics/mouse/juce_MouseCursor.cpp +++ b/modules/juce_gui_basics/mouse/juce_MouseCursor.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/mouse/juce_MouseCursor.h b/modules/juce_gui_basics/mouse/juce_MouseCursor.h index e64c75bc..9f48cef6 100644 --- a/modules/juce_gui_basics/mouse/juce_MouseCursor.h +++ b/modules/juce_gui_basics/mouse/juce_MouseCursor.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/mouse/juce_MouseEvent.cpp b/modules/juce_gui_basics/mouse/juce_MouseEvent.cpp index 79abd536..d0923b0a 100644 --- a/modules/juce_gui_basics/mouse/juce_MouseEvent.cpp +++ b/modules/juce_gui_basics/mouse/juce_MouseEvent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/mouse/juce_MouseEvent.h b/modules/juce_gui_basics/mouse/juce_MouseEvent.h index 2af4a9c3..d63c2a49 100644 --- a/modules/juce_gui_basics/mouse/juce_MouseEvent.h +++ b/modules/juce_gui_basics/mouse/juce_MouseEvent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/mouse/juce_MouseInactivityDetector.cpp b/modules/juce_gui_basics/mouse/juce_MouseInactivityDetector.cpp index b5053e45..a69dc64e 100644 --- a/modules/juce_gui_basics/mouse/juce_MouseInactivityDetector.cpp +++ b/modules/juce_gui_basics/mouse/juce_MouseInactivityDetector.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/mouse/juce_MouseInactivityDetector.h b/modules/juce_gui_basics/mouse/juce_MouseInactivityDetector.h index 17035e5b..404cbc34 100644 --- a/modules/juce_gui_basics/mouse/juce_MouseInactivityDetector.h +++ b/modules/juce_gui_basics/mouse/juce_MouseInactivityDetector.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp b/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp index e9c378a4..a8c2c283 100644 --- a/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp +++ b/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -539,8 +538,8 @@ private: bool canBePartOfMultipleClickWith (const RecentMouseDown& other, int maxTimeBetweenMs) const noexcept { return time - other.time < RelativeTime::milliseconds (maxTimeBetweenMs) - && std::abs (position.x - other.position.x) < getPositionToleranceForInputType() - && std::abs (position.y - other.position.y) < getPositionToleranceForInputType() + && std::abs (position.x - other.position.x) < (float) getPositionToleranceForInputType() + && std::abs (position.y - other.position.y) < (float) getPositionToleranceForInputType() && buttons == other.buttons && peerID == other.peerID; } diff --git a/modules/juce_gui_basics/mouse/juce_MouseInputSource.h b/modules/juce_gui_basics/mouse/juce_MouseInputSource.h index 5fd7b2ca..0763b094 100644 --- a/modules/juce_gui_basics/mouse/juce_MouseInputSource.h +++ b/modules/juce_gui_basics/mouse/juce_MouseInputSource.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/mouse/juce_MouseListener.cpp b/modules/juce_gui_basics/mouse/juce_MouseListener.cpp index 133dad43..e9cf1126 100644 --- a/modules/juce_gui_basics/mouse/juce_MouseListener.cpp +++ b/modules/juce_gui_basics/mouse/juce_MouseListener.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/mouse/juce_MouseListener.h b/modules/juce_gui_basics/mouse/juce_MouseListener.h index 52f98383..ca95126b 100644 --- a/modules/juce_gui_basics/mouse/juce_MouseListener.h +++ b/modules/juce_gui_basics/mouse/juce_MouseListener.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/mouse/juce_SelectedItemSet.h b/modules/juce_gui_basics/mouse/juce_SelectedItemSet.h index 40f9bb59..05ae0039 100644 --- a/modules/juce_gui_basics/mouse/juce_SelectedItemSet.h +++ b/modules/juce_gui_basics/mouse/juce_SelectedItemSet.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/mouse/juce_TextDragAndDropTarget.h b/modules/juce_gui_basics/mouse/juce_TextDragAndDropTarget.h index b1ffd28d..d3f4e243 100644 --- a/modules/juce_gui_basics/mouse/juce_TextDragAndDropTarget.h +++ b/modules/juce_gui_basics/mouse/juce_TextDragAndDropTarget.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/mouse/juce_TooltipClient.h b/modules/juce_gui_basics/mouse/juce_TooltipClient.h index 1cbc2c9c..601e0ea9 100644 --- a/modules/juce_gui_basics/mouse/juce_TooltipClient.h +++ b/modules/juce_gui_basics/mouse/juce_TooltipClient.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/native/java/app/com/roli/juce/ComponentPeerView.java b/modules/juce_gui_basics/native/java/app/com/rmsl/juce/ComponentPeerView.java similarity index 90% rename from modules/juce_gui_basics/native/java/app/com/roli/juce/ComponentPeerView.java rename to modules/juce_gui_basics/native/java/app/com/rmsl/juce/ComponentPeerView.java index 9a43aa5e..823d66be 100644 --- a/modules/juce_gui_basics/native/java/app/com/roli/juce/ComponentPeerView.java +++ b/modules/juce_gui_basics/native/java/app/com/rmsl/juce/ComponentPeerView.java @@ -1,4 +1,29 @@ -package com.roli.juce; +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +package com.rmsl.juce; import android.app.Activity; import android.app.Application; diff --git a/modules/juce_gui_basics/native/java/app/com/rmsl/juce/JuceContentProviderCursor.java b/modules/juce_gui_basics/native/java/app/com/rmsl/juce/JuceContentProviderCursor.java new file mode 100644 index 00000000..5cae807f --- /dev/null +++ b/modules/juce_gui_basics/native/java/app/com/rmsl/juce/JuceContentProviderCursor.java @@ -0,0 +1,53 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +package com.rmsl.juce; + +import android.database.Cursor; +import android.database.MatrixCursor; + +import java.lang.String; + +public final class JuceContentProviderCursor extends MatrixCursor +{ + public JuceContentProviderCursor (long hostToUse, String[] columnNames) + { + super (columnNames); + + host = hostToUse; + } + + @Override + public void close () + { + super.close (); + + contentSharerCursorClosed (host); + } + + private native void contentSharerCursorClosed (long host); + + private long host; +} diff --git a/modules/juce_gui_basics/native/java/app/com/rmsl/juce/JuceContentProviderFileObserver.java b/modules/juce_gui_basics/native/java/app/com/rmsl/juce/JuceContentProviderFileObserver.java new file mode 100644 index 00000000..50241255 --- /dev/null +++ b/modules/juce_gui_basics/native/java/app/com/rmsl/juce/JuceContentProviderFileObserver.java @@ -0,0 +1,49 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +package com.rmsl.juce; + +import android.os.FileObserver; + +import java.lang.String; + +public final class JuceContentProviderFileObserver extends FileObserver +{ + public JuceContentProviderFileObserver (long hostToUse, String path, int mask) + { + super (path, mask); + + host = hostToUse; + } + + public void onEvent (int event, String path) + { + contentSharerFileObserverEvent (host, event, path); + } + + private long host; + + private native void contentSharerFileObserverEvent (long host, int event, String path); +} diff --git a/modules/juce_gui_basics/native/javaopt/app/com/rmsl/juce/JuceActivity.java b/modules/juce_gui_basics/native/javaopt/app/com/rmsl/juce/JuceActivity.java new file mode 100644 index 00000000..f62ff4d6 --- /dev/null +++ b/modules/juce_gui_basics/native/javaopt/app/com/rmsl/juce/JuceActivity.java @@ -0,0 +1,45 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +package com.rmsl.juce; + +import android.app.Activity; +import android.content.Intent; + +//============================================================================== +public class JuceActivity extends Activity +{ + //============================================================================== + private native void appNewIntent (Intent intent); + + @Override + protected void onNewIntent (Intent intent) + { + super.onNewIntent(intent); + setIntent(intent); + + appNewIntent (intent); + } +} diff --git a/modules/juce_gui_basics/native/javacore/app/com/roli/juce/JuceSharingContentProvider.java b/modules/juce_gui_basics/native/javaopt/app/com/rmsl/juce/JuceSharingContentProvider.java similarity index 62% rename from modules/juce_gui_basics/native/javacore/app/com/roli/juce/JuceSharingContentProvider.java rename to modules/juce_gui_basics/native/javaopt/app/com/rmsl/juce/JuceSharingContentProvider.java index bcf0718a..15f62b14 100644 --- a/modules/juce_gui_basics/native/javacore/app/com/roli/juce/JuceSharingContentProvider.java +++ b/modules/juce_gui_basics/native/javaopt/app/com/rmsl/juce/JuceSharingContentProvider.java @@ -1,4 +1,29 @@ -package com.roli.juce; +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +package com.rmsl.juce; import android.content.ContentProvider; import android.content.ContentValues; @@ -16,52 +41,10 @@ public final class JuceSharingContentProvider extends ContentProvider { private Object lock = new Object (); - private native Cursor contentSharerQuery (Uri uri, String[] projection, String selection, - String[] selectionArgs, String sortOrder); + private native Cursor contentSharerQuery (Uri uri, String[] projection); private native AssetFileDescriptor contentSharerOpenFile (Uri uri, String mode); private native String[] contentSharerGetStreamTypes (Uri uri, String mimeTypeFilter); - public final class ProviderFileObserver extends FileObserver - { - public ProviderFileObserver (long hostToUse, String path, int mask) - { - super (path, mask); - - host = hostToUse; - } - - public void onEvent (int event, String path) - { - contentSharerFileObserverEvent (host, event, path); - } - - private long host; - - private native void contentSharerFileObserverEvent (long host, int event, String path); - } - - public final class ProviderCursor extends MatrixCursor - { - ProviderCursor (long hostToUse, String[] columnNames) - { - super (columnNames); - - host = hostToUse; - } - - @Override - public void close () - { - super.close (); - - contentSharerCursorClosed (host); - } - - private native void contentSharerCursorClosed (long host); - - private long host; - } - @Override public boolean onCreate () { @@ -74,7 +57,7 @@ public final class JuceSharingContentProvider extends ContentProvider { synchronized (lock) { - return contentSharerQuery (url, projection, selection, selectionArgs, sortOrder); + return contentSharerQuery (url, projection); } } diff --git a/modules/juce_gui_basics/native/javaopt/app/com/roli/juce/JuceActivity.java b/modules/juce_gui_basics/native/javaopt/app/com/roli/juce/JuceActivity.java deleted file mode 100644 index c8db5f74..00000000 --- a/modules/juce_gui_basics/native/javaopt/app/com/roli/juce/JuceActivity.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.roli.juce; - -import android.app.Activity; -import android.content.Intent; - -//============================================================================== -public class JuceActivity extends Activity -{ - //============================================================================== - private native void appNewIntent (Intent intent); - - @Override - protected void onNewIntent (Intent intent) - { - super.onNewIntent(intent); - setIntent(intent); - - appNewIntent (intent); - } -} \ No newline at end of file diff --git a/modules/juce_gui_basics/native/juce_MultiTouchMapper.h b/modules/juce_gui_basics/native/juce_MultiTouchMapper.h index aed39fb2..d6e1493c 100644 --- a/modules/juce_gui_basics/native/juce_MultiTouchMapper.h +++ b/modules/juce_gui_basics/native/juce_MultiTouchMapper.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -24,12 +23,7 @@ ============================================================================== */ -#if JUCE_CLANG - #if __has_warning("-Wzero-as-null-pointer-constant") - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" - #endif -#endif +JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wzero-as-null-pointer-constant") namespace juce { @@ -110,8 +104,4 @@ private: } // namespace juce -#if JUCE_CLANG - #if __has_warning("-Wzero-as-null-pointer-constant") - #pragma clang diagnostic pop - #endif -#endif +JUCE_END_IGNORE_WARNINGS_GCC_LIKE diff --git a/modules/juce_gui_basics/native/juce_android_ContentSharer.cpp b/modules/juce_gui_basics/native/juce_android_ContentSharer.cpp index 6773956c..813a2bd0 100644 --- a/modules/juce_gui_basics/native/juce_android_ContentSharer.cpp +++ b/modules/juce_gui_basics/native/juce_android_ContentSharer.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -27,60 +26,46 @@ namespace juce { //============================================================================== -// This byte-code is generated from native/javacore/app/com/roli/juce/JuceSharingContentProvider.java with min sdk version 16 +// This byte-code is generated from native/java/app/com/rmsl/juce/JuceContentProviderCursor.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,96,160,247,93,0,3,74,97,118,97,68,101,120,66,121,116,101,67,111,100,101,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,0,0}; +static const uint8 javaJuceContentProviderCursor[] = +{31,139,8,8,191,114,161,94,0,3,106,97,118,97,74,117,99,101,67,111,110,116,101,110,116,80,114,111,118,105,100,101,114,67,117, +114,115,111,114,46,100,101,120,0,117,147,177,111,211,64,20,198,223,157,157,148,150,54,164,192,208,14,64,144,16,18,67,235,138,2, +75,40,162,10,44,150,65,149,2,25,218,233,176,173,198,37,241,69,182,19,121,96,160,21,136,37,19,98,234,80,85,149,152,88,24,248, +3,24,146,63,130,141,137,129,13,169,99,7,190,203,157,33,18,194,210,207,247,222,229,189,239,157,206,95,130,48,159,91,91,191,75,227, +60,200,143,134,239,247,151,62,189,43,175,127,249,246,235,241,215,241,112,231,231,193,237,135,22,81,143,136,242,214,157,139, +100,158,99,78,84,37,189,95,2,159,129,13,70,128,129,83,179,127,102,242,27,120,157,129,71,224,16,156,128,143,96,12,126,128,69,232, +93,6,75,224,10,184,14,238,129,13,224,130,16,188,4,3,174,245,44,51,79,205,152,53,171,101,206,86,54,241,27,20,206,152,120,136, +248,156,137,63,32,134,12,45,76,206,166,187,148,230,28,169,125,62,201,249,159,156,209,188,201,23,77,93,241,187,122,134,38,40,225, +52,42,124,197,245,252,94,141,104,147,182,113,95,21,76,208,83,222,114,125,86,89,101,168,109,162,162,183,134,46,86,249,71,215, +158,228,54,149,239,71,113,148,61,32,230,210,85,183,239,135,13,25,103,97,156,109,37,114,16,5,97,210,232,39,169,76,86,247,196,64, +208,53,79,196,65,34,163,192,9,68,38,94,136,52,116,158,136,44,137,114,93,84,167,91,158,47,187,78,210,77,59,206,30,164,156,255, +234,213,137,181,136,183,92,178,90,174,135,192,163,75,59,158,154,225,116,68,188,235,52,33,26,239,214,169,228,119,100,26,210,121, +95,118,250,221,248,169,232,134,41,45,251,90,176,217,22,73,33,215,80,101,1,217,109,153,102,52,171,222,207,228,115,52,218,89, +59,74,233,38,191,48,63,83,217,88,161,85,194,178,141,139,224,184,28,190,255,218,30,113,126,192,201,98,223,249,130,185,27,54,181, +22,222,227,83,254,43,60,49,50,235,180,15,11,47,150,167,252,200,106,186,95,121,146,85,255,122,134,215,180,190,242,169,101,106, +212,119,165,154,238,157,124,243,170,142,213,255,224,55,143,234,50,200,64,3,0,0,0,0}; + +// This byte-code is generated from native/java/app/com/rmsl/juce/JuceContentProviderFileObserver.java with min sdk version 16 +// See juce_core/native/java/README.txt on how to generate this byte-code. +static const uint8 javaJuceContentProviderFileObserver[] = +{31,139,8,8,194,122,161,94,0,3,106,97,118,97,74,117,99,101,67,111,110,116,101,110,116,80,114,111,118,105,100,101,114,70,105, +108,101,79,98,115,101,114,118,101,114,46,100,101,120,0,133,147,205,107,19,65,24,198,223,249,72,98,171,46,105,235,69,16,201,65,81, +68,221,136,10,66,84,144,250,65,194,130,197,212,32,5,15,155,100,104,182,38,187,97,119,141,241,32,126,30,196,147,23,79,246,216, +131,120,202,77,169,80,212,191,64,193,66,143,30,60,138,255,130,62,179,51,165,219,147,129,223,188,239,188,239,204,179,179,179,79, +186,106,60,93,61,123,158,54,159,255,248,112,97,210,120,124,98,237,251,177,7,109,245,115,253,225,198,159,47,243,171,135,198,130, +104,72,68,227,214,185,89,178,191,45,78,116,128,76,189,8,62,3,169,235,128,129,61,204,204,203,204,204,171,24,142,99,207,2,226, +4,124,4,159,192,6,248,5,254,130,42,250,87,193,13,224,129,91,224,14,184,11,30,129,23,224,21,120,3,222,130,53,240,158,27,125,110, +159,95,176,231,41,233,51,216,249,75,44,152,178,249,107,228,211,54,95,69,190,215,230,239,144,11,40,57,153,150,200,222,81,100, +170,166,190,47,139,68,51,185,200,237,93,8,27,191,218,66,17,138,186,54,225,230,44,195,42,209,149,194,18,238,206,201,58,250,121, +235,182,215,172,160,191,200,137,159,113,172,158,204,246,50,251,62,38,151,89,103,251,29,139,23,131,48,72,47,19,171,19,107,208, +145,198,253,142,154,143,194,84,133,233,66,28,141,130,174,138,175,7,125,117,179,157,168,120,164,226,211,43,254,200,167,131,158, +31,118,227,40,232,186,81,226,230,219,53,114,189,78,52,112,227,65,210,119,87,32,229,254,71,175,70,179,158,150,116,251,126,184, +236,54,211,56,8,151,107,196,90,36,90,117,143,100,171,97,70,175,142,2,134,195,29,35,213,236,249,241,110,161,107,35,148,169,160, +178,32,123,81,146,210,148,30,23,163,219,137,34,57,240,147,123,84,138,66,179,76,14,253,180,71,50,237,5,9,29,21,229,185,153,146, +115,233,20,157,228,206,92,201,89,194,21,113,70,156,61,125,34,191,113,246,12,223,143,253,198,101,237,183,223,133,229,226,182,103, +121,206,183,34,231,93,153,243,111,129,118,60,92,164,29,31,179,138,217,175,189,204,202,102,141,246,24,175,24,125,237,111,97, +215,104,15,80,197,236,205,252,81,54,185,254,255,252,3,243,31,208,130,120,3,0,0,0,0}; //============================================================================== #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ @@ -127,7 +112,6 @@ public: : owner (ownerToUse), cursor (GlobalRef (LocalRef<jobject> (env->NewObject (JuceContentProviderCursor, JuceContentProviderCursor.constructor, - contentProvider.get(), reinterpret_cast<jlong> (this), resultColumns.get())))) { @@ -156,13 +140,13 @@ private: //============================================================================== #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ METHOD (addRow, "addRow", "([Ljava/lang/Object;)V") \ - METHOD (constructor, "<init>", "(Lcom/roli/juce/JuceSharingContentProvider;J[Ljava/lang/String;)V") \ + METHOD (constructor, "<init>", "(J[Ljava/lang/String;)V") \ CALLBACK (contentSharerCursorClosed, "contentSharerCursorClosed", "(J)V") \ - DECLARE_JNI_CLASS (JuceContentProviderCursor, "com/roli/juce/JuceSharingContentProvider$ProviderCursor") + DECLARE_JNI_CLASS_WITH_BYTECODE (JuceContentProviderCursor, "com/rmsl/juce/JuceContentProviderCursor", 16, javaJuceContentProviderCursor, sizeof (javaJuceContentProviderCursor)) #undef JNI_CLASS_MEMBERS - static void JNICALL contentSharerCursorClosed(JNIEnv*, jobject, jlong host) + static void JNICALL contentSharerCursorClosed (JNIEnv*, jobject, jlong host) { if (auto* myself = reinterpret_cast<AndroidContentSharerCursor*> (host)) myself->cursorClosed(); @@ -190,7 +174,6 @@ public: filepath (filepathToUse), fileObserver (GlobalRef (LocalRef<jobject> (env->NewObject (JuceContentProviderFileObserver, JuceContentProviderFileObserver.constructor, - contentProvider.get(), reinterpret_cast<jlong> (this), javaString (filepath).get(), open | access | closeWrite | closeNoWrite)))) @@ -244,12 +227,12 @@ private: //============================================================================== #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ - METHOD (constructor, "<init>", "(Lcom/roli/juce/JuceSharingContentProvider;JLjava/lang/String;I)V") \ + METHOD (constructor, "<init>", "(JLjava/lang/String;I)V") \ METHOD (startWatching, "startWatching", "()V") \ METHOD (stopWatching, "stopWatching", "()V") \ CALLBACK (contentSharerFileObserverEvent, "contentSharerFileObserverEvent", "(JILjava/lang/String;)V") \ - DECLARE_JNI_CLASS (JuceContentProviderFileObserver, "com/roli/juce/JuceSharingContentProvider$ProviderFileObserver") + DECLARE_JNI_CLASS_WITH_BYTECODE (JuceContentProviderFileObserver, "com/rmsl/juce/JuceContentProviderFileObserver", 16, javaJuceContentProviderFileObserver, sizeof (javaJuceContentProviderFileObserver)) #undef JNI_CLASS_MEMBERS static void JNICALL contentSharerFileObserverEvent (JNIEnv*, jobject /*fileObserver*/, jlong host, int event, jstring path) @@ -550,11 +533,8 @@ public: } jobject query (const LocalRef<jobject>& contentProvider, const LocalRef<jobject>& uri, - const LocalRef<jobjectArray>& projection, const LocalRef<jobject>& selection, - const LocalRef<jobjectArray>& selectionArgs, const LocalRef<jobject>& sortOrder) + const LocalRef<jobjectArray>& projection) { - ignoreUnused (selection, selectionArgs, sortOrder); - StringArray requestedColumns = javaStringArrayToJuce (projection); StringArray supportedColumns = getSupportedColumns(); @@ -804,6 +784,48 @@ private: return assetFileDescriptors.getReference (assetFileDescriptors.size() - 1).get(); } + StringArray filterMimeTypes (const StringArray& mimeTypes, const String& filter) + { + String filterToUse (filter.removeCharacters ("*")); + + if (filterToUse.isEmpty() || filterToUse == "/") + return mimeTypes; + + StringArray result; + + for (const auto& type : mimeTypes) + if (String (type).contains (filterToUse)) + result.add (type); + + return result; + } + + String getCommonMimeType (const StringArray& mimeTypes) + { + if (mimeTypes.isEmpty()) + return "*/*"; + + auto commonMime = mimeTypes[0]; + bool lookForCommonGroup = false; + + for (int i = 1; i < mimeTypes.size(); ++i) + { + if (mimeTypes[i] == commonMime) + continue; + + if (! lookForCommonGroup) + { + lookForCommonGroup = true; + commonMime = commonMime.upToFirstOccurrenceOf ("/", true, false); + } + + if (! mimeTypes[i].startsWith (commonMime)) + return "*/*"; + } + + return lookForCommonGroup ? commonMime + "*" : commonMime; + } + ContentSharer& owner; String packageName; String uriBase; @@ -829,26 +851,19 @@ private: //============================================================================== #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ - CALLBACK (contentSharerQuery, "contentSharerQuery", "(Landroid/net/Uri;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;") \ + CALLBACK (contentSharerQuery, "contentSharerQuery", "(Landroid/net/Uri;[Ljava/lang/String;)Landroid/database/Cursor;") \ CALLBACK (contentSharerOpenFile, "contentSharerOpenFile", "(Landroid/net/Uri;Ljava/lang/String;)Landroid/content/res/AssetFileDescriptor;") \ 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_MIN_SDK (JuceSharingContentProvider, "com/rmsl/juce/JuceSharingContentProvider", 16) #undef JNI_CLASS_MEMBERS - static jobject JNICALL contentSharerQuery (JNIEnv*, jobject contentProvider, jobject uri, jobjectArray projection, - jobject selection, jobjectArray selectionArgs, jobject sortOrder) + static jobject JNICALL contentSharerQuery (JNIEnv*, jobject contentProvider, jobject uri, jobjectArray projection) { if (auto *pimpl = (ContentSharer::ContentSharerNativeImpl *) ContentSharer::getInstance ()->pimpl.get ()) return pimpl->query (LocalRef<jobject> (static_cast<jobject> (contentProvider)), LocalRef<jobject> (static_cast<jobject> (uri)), - LocalRef<jobjectArray> ( - static_cast<jobjectArray> (projection)), - LocalRef<jobject> (static_cast<jobject> (selection)), - LocalRef<jobjectArray> ( - static_cast<jobjectArray> (selectionArgs)), - LocalRef<jobject> (static_cast<jobject> (sortOrder))); + LocalRef<jobjectArray> (static_cast<jobjectArray> (projection))); return nullptr; } diff --git a/modules/juce_gui_basics/native/juce_android_FileChooser.cpp b/modules/juce_gui_basics/native/juce_android_FileChooser.cpp index 4ba5f507..35d7f60e 100644 --- a/modules/juce_gui_basics/native/juce_android_FileChooser.cpp +++ b/modules/juce_gui_basics/native/juce_android_FileChooser.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/native/juce_android_Windowing.cpp b/modules/juce_gui_basics/native/juce_android_Windowing.cpp index 7b1d1ec5..4cb678ad 100644 --- a/modules/juce_gui_basics/native/juce_android_Windowing.cpp +++ b/modules/juce_gui_basics/native/juce_android_Windowing.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -26,164 +25,164 @@ namespace juce { -// This byte-code is generated from native/java/com/roli/juce/ComponentPeerView.java with min sdk version 16 +// This byte-code is generated from native/java/com/rmsl/juce/ComponentPeerView.java with min sdk version 16 // See juce_core/native/java/README.txt on how to generate this byte-code. static const uint8 javaComponentPeerView[] = -{31,139,8,8,1,253,119,92,0,3,74,97,118,97,68,101,120,66,121,116,101,67,111,100,101,46,100,101,120,0,165,154,11,124,92,85,157, -199,255,231,220,121,36,147,201,100,50,73,147,54,153,180,147,164,73,167,109,154,76,120,53,37,41,244,25,72,155,210,71,166,149,38, -69,184,153,185,73,166,157,220,59,157,153,36,141,226,82,144,109,171,86,165,110,69,150,151,168,149,15,98,87,237,46,32,91,193,237, -242,80,116,81,1,69,235,10,88,93,92,1,31,31,100,203,218,207,234,210,253,157,115,207,36,183,47,81,55,253,124,231,255,63,255,243, -63,239,115,254,231,76,154,164,177,203,23,187,248,82,170,47,249,108,247,151,235,94,184,235,163,155,215,44,254,82,229,169,135,223, -24,25,51,30,92,117,226,206,101,11,136,50,68,180,107,203,37,33,82,63,55,206,39,250,21,217,246,118,16,118,17,45,134,60,1,89, -9,153,247,18,25,144,149,69,68,26,100,87,9,209,161,217,68,119,67,254,176,154,232,56,56,1,78,129,63,128,211,128,207,36,242,128, -98,80,10,154,193,124,176,8,180,131,203,192,53,224,86,240,105,112,20,188,8,222,6,51,102,17,45,3,253,32,7,246,129,123,193,87,193, -247,193,59,160,162,6,117,1,3,236,1,143,128,151,65,113,45,81,7,216,13,190,6,94,1,60,76,212,0,86,131,235,65,22,220,14,30,3,207, -131,147,160,168,142,104,30,232,4,219,193,30,176,31,220,9,238,1,159,1,15,128,195,224,33,112,20,28,3,79,131,111,129,239,130,239, -131,227,224,21,240,115,240,6,248,13,120,11,156,2,255,11,24,230,205,3,124,32,0,26,192,98,176,18,172,7,3,96,24,228,192,110,176, -15,124,18,124,26,28,5,143,131,231,192,113,112,2,188,6,126,7,78,1,247,28,162,16,104,0,237,224,114,176,28,92,5,214,128,141,224, -122,176,29,220,12,110,3,119,130,251,193,67,224,95,192,15,192,79,193,155,224,29,224,141,16,5,65,29,104,3,87,130,56,72,128,28,56, -0,62,5,238,1,247,129,35,224,73,240,34,120,21,252,14,120,235,137,102,130,249,160,3,172,6,235,193,8,200,130,93,224,253,96,47, -216,15,238,1,135,193,227,224,25,240,67,240,10,120,3,156,4,167,65,81,3,81,61,136,129,197,160,27,244,130,56,216,6,174,7,6,48,65, -30,188,15,124,20,124,22,60,4,190,9,94,5,191,7,190,70,162,70,176,16,92,14,214,128,205,32,9,70,193,4,216,3,14,130,187,193,231, -193,151,193,35,224,9,240,45,240,44,120,19,4,230,98,255,130,26,176,0,116,128,141,64,7,22,248,16,184,15,60,14,190,13,126,12,126, -1,222,6,90,19,214,15,52,128,118,176,22,108,4,91,129,14,134,65,26,100,193,141,224,38,176,7,124,28,124,18,220,15,142,128,39,193, -247,192,11,224,69,240,99,240,114,147,125,118,221,0,199,153,2,160,12,4,65,57,16,193,160,130,236,243,62,3,84,1,28,99,194,113,36, -28,55,194,209,162,90,17,27,0,182,49,97,187,17,182,7,97,121,9,203,65,152,70,194,240,9,195,32,52,69,205,96,30,136,2,132,23,66, -216,161,133,160,5,44,2,173,160,13,196,84,204,185,8,92,12,46,1,151,130,14,112,21,88,7,174,1,235,193,6,178,199,80,248,113,41,121, -107,149,61,46,166,210,30,165,11,187,24,43,87,246,34,165,239,135,221,167,252,196,143,95,229,29,84,246,128,178,251,212,188,20, -244,25,14,127,49,47,119,87,217,186,152,147,67,170,108,189,242,41,81,115,33,250,80,170,230,227,176,242,23,250,67,202,63,170,252, -75,213,28,61,86,101,143,125,161,178,47,81,186,168,231,114,165,63,5,189,83,233,207,65,239,82,250,113,232,75,149,254,26,244,43, -148,126,18,250,149,133,58,177,168,203,148,94,4,125,133,210,131,14,251,76,135,30,129,190,74,233,81,135,253,18,135,222,229,208, -87,57,234,236,117,216,227,208,87,42,125,155,195,158,175,154,214,197,28,46,87,122,210,81,79,218,225,47,230,109,117,161,44,236, -221,74,191,209,225,179,223,161,31,172,182,247,81,139,154,207,171,149,126,55,236,61,74,63,4,125,141,210,191,2,189,87,233,143,66, -95,171,244,99,14,251,51,14,251,115,213,98,77,25,93,71,182,252,137,156,226,8,93,171,228,199,165,100,244,9,37,15,42,249,73,37, -111,87,242,83,202,255,62,18,103,173,133,62,45,101,45,253,152,196,185,11,211,113,37,127,38,101,13,189,74,98,223,113,186,77,202, -90,186,87,202,22,250,154,148,37,244,117,185,255,234,233,50,18,103,163,142,158,32,177,223,61,52,42,101,144,222,7,89,140,19,207, -164,92,68,79,147,216,143,245,50,93,162,236,37,56,61,223,144,227,178,211,101,104,47,45,101,57,153,42,253,126,177,119,148,61,136, -19,185,83,165,199,164,212,104,156,236,24,51,161,228,46,41,25,237,86,242,102,18,103,140,83,86,202,6,186,137,68,28,154,45,219, -171,64,84,120,88,202,118,122,68,202,25,244,207,36,206,97,51,245,43,249,36,137,88,213,36,253,103,33,130,124,76,202,70,250,150, -148,151,210,247,229,60,206,147,249,53,168,225,33,57,127,243,101,186,22,246,141,74,110,146,210,79,125,82,86,208,15,148,124,81, -206,231,28,233,31,198,76,198,165,140,210,102,41,43,104,155,146,186,148,49,249,78,10,163,165,29,82,122,228,155,42,172,198,23,70, -212,203,73,89,76,147,82,250,232,70,149,255,1,41,139,232,111,164,180,231,33,140,145,125,80,201,91,149,252,91,41,103,210,30,37, -247,42,251,62,41,171,233,67,74,126,88,201,143,72,57,139,246,75,217,70,119,41,121,183,148,97,122,80,237,159,47,42,121,88,201,127, -80,249,95,82,233,47,43,249,21,181,191,142,72,25,161,127,148,178,137,254,73,74,123,189,194,106,189,68,250,171,106,95,62,42, -165,189,126,97,68,249,163,82,46,164,111,42,249,140,148,115,233,223,164,172,164,239,72,185,128,190,171,210,223,83,126,207,41,249, -188,202,127,65,141,255,231,36,98,111,136,242,82,94,70,119,202,253,31,160,19,36,226,173,189,127,155,17,101,45,18,49,87,163, -65,41,57,125,142,68,220,45,163,191,39,251,142,35,178,227,179,136,75,226,174,88,5,121,64,5,233,90,181,135,155,149,159,200,143, -35,255,144,202,23,247,64,57,217,247,232,141,170,124,18,242,217,232,180,255,117,208,147,81,251,30,51,33,199,192,77,81,251,190, -218,39,237,92,234,39,154,196,185,196,123,48,84,66,153,224,13,176,133,104,91,208,39,239,166,34,164,68,249,215,225,51,32,218,243, -84,82,3,247,195,175,8,165,227,185,18,138,95,236,39,51,120,17,188,252,44,68,75,88,215,180,53,114,25,78,199,180,79,12,62,62,109, -19,174,170,77,77,140,142,196,15,144,230,186,244,134,26,218,156,243,81,135,86,69,33,109,27,180,130,127,60,95,66,59,131,77,56,231, -126,215,206,224,124,200,18,215,206,216,2,90,233,22,254,75,52,47,45,190,193,77,161,10,81,38,128,182,102,96,45,204,96,37,250, -123,118,27,209,239,138,251,91,147,115,18,104,182,223,34,3,33,191,26,107,3,214,34,19,137,96,182,7,130,1,26,168,40,149,227,102, -242,31,222,30,205,246,221,159,9,138,149,8,76,217,155,167,236,243,164,157,171,23,65,107,179,61,223,241,96,169,92,31,13,118,209, -238,101,205,246,125,28,143,148,162,151,226,245,129,17,214,139,126,215,160,229,192,148,223,210,11,250,213,74,191,0,226,130,24, -201,42,248,137,125,31,242,132,102,100,34,85,244,5,106,112,137,213,243,160,87,3,7,17,221,92,181,148,193,131,245,96,241,192,193, -32,190,101,185,81,195,123,233,16,249,92,29,174,235,104,142,79,164,241,34,167,254,187,203,160,245,83,138,182,221,133,72,27,233, -163,173,248,140,203,207,205,216,169,13,216,25,153,160,24,81,133,171,146,26,151,47,162,102,38,226,152,25,113,161,63,113,209,146, -219,135,249,115,147,168,209,139,152,21,210,204,160,142,82,126,87,141,251,219,20,106,110,28,106,163,144,119,176,168,130,214,21, -121,188,161,234,112,81,137,212,204,216,117,20,247,248,181,14,173,146,66,60,52,183,113,85,140,66,238,157,193,235,49,58,191,103, -157,199,229,14,205,8,73,105,198,146,244,119,46,204,65,16,107,139,122,231,184,236,222,31,164,232,103,74,93,209,147,224,45,240, -38,248,119,112,28,75,46,223,150,211,63,187,175,164,191,40,125,246,143,157,47,238,237,42,196,35,131,236,251,132,107,141,183,178, -134,91,216,252,221,140,207,219,199,154,246,48,123,189,197,207,131,106,31,244,69,202,228,57,22,251,79,164,143,20,246,77,172,139, -234,53,177,154,246,249,58,170,246,101,223,178,50,170,226,242,157,202,151,32,39,32,45,153,216,18,114,177,232,255,76,215,255, -68,179,253,14,21,111,231,126,180,17,80,109,136,159,103,154,237,243,31,10,150,77,237,203,23,84,127,54,7,203,101,59,92,237,227, -31,53,219,111,67,51,120,137,56,57,120,3,186,100,185,16,69,223,209,84,125,47,55,219,49,35,32,203,217,47,220,95,56,108,30,216,132, -231,175,223,101,12,139,213,24,10,254,111,191,139,127,199,212,152,237,126,188,115,158,126,120,230,157,107,43,117,216,92,170,173, -202,121,246,123,57,196,68,228,29,136,113,178,165,70,91,219,17,69,222,220,26,243,210,214,152,71,89,139,177,127,240,98,15,110, -141,185,144,95,132,83,80,133,254,224,14,98,229,106,188,98,238,27,231,217,49,248,252,253,143,175,8,81,102,211,50,114,109,140,158, -18,223,13,52,185,238,11,47,88,230,226,213,167,79,203,113,47,107,37,151,46,202,20,195,46,218,233,152,103,127,119,9,5,251,6, -81,10,213,180,51,238,90,194,176,82,152,191,22,175,248,238,36,114,204,96,9,226,181,143,101,54,94,78,205,185,232,127,89,177,106, -26,47,242,81,244,183,102,112,33,122,29,125,67,76,146,221,143,194,119,45,241,157,163,84,225,67,142,104,111,211,60,251,123,83, -136,77,181,199,209,30,74,150,177,37,222,98,180,83,140,190,249,120,168,241,162,139,188,100,45,155,73,227,119,248,88,244,45,19, -119,6,206,61,239,224,191,57,93,208,205,200,32,218,240,201,254,101,54,160,95,90,168,60,250,178,61,31,162,173,244,60,251,187,206, -153,243,97,143,76,216,196,152,60,104,43,179,169,19,51,25,10,70,223,182,223,150,226,103,210,177,206,197,228,150,245,237,85,243, -107,93,59,139,226,227,206,90,59,208,166,189,175,182,97,95,217,223,73,185,252,46,118,7,202,132,81,81,223,243,240,214,196,236, -50,77,206,46,43,99,102,208,143,250,125,197,102,80,220,11,37,222,23,15,156,166,133,236,191,229,236,68,127,215,247,2,78,10,51,113, -254,102,35,178,154,65,17,161,125,110,19,103,12,210,227,125,126,188,104,169,184,77,203,163,47,189,187,231,149,182,231,55,223, -221,243,10,120,154,65,113,23,248,74,66,229,139,107,23,80,168,190,49,220,138,152,216,142,183,76,168,230,210,163,245,36,106,17, -117,124,73,212,17,9,9,201,66,238,85,110,191,251,150,205,223,152,97,70,42,108,75,213,42,143,223,115,203,208,55,170,10,245,30,247, -97,37,79,160,31,31,172,100,116,154,232,225,3,63,243,177,162,37,190,153,244,231,142,96,62,13,157,118,246,231,175,233,137,168,41, -250,147,191,188,7,75,85,15,154,254,223,61,88,42,123,128,101,102,94,185,215,196,222,18,177,161,77,73,17,83,196,251,62,39,247, -30,151,119,114,105,212,254,93,3,250,136,27,208,139,221,95,163,61,75,161,202,198,85,184,1,221,131,30,220,128,242,54,187,142,46, -114,249,217,18,212,28,192,185,139,190,3,254,24,10,53,54,224,254,211,196,253,87,132,59,110,157,139,107,226,222,219,201,163,191, -45,229,209,95,131,55,192,107,98,191,151,163,111,226,125,232,23,145,136,207,171,106,154,169,53,70,27,90,230,47,112,196,192,197, -209,233,179,161,41,235,149,81,251,157,215,193,189,56,95,102,228,90,120,4,40,180,44,250,7,49,62,59,78,94,29,181,127,55,98,6,219, -228,139,174,134,223,1,79,142,216,233,199,55,147,89,212,129,200,97,6,19,56,161,62,182,148,85,96,182,205,216,28,138,97,196,151, -74,127,51,54,155,130,174,120,123,16,111,183,70,89,127,33,39,196,205,88,29,5,185,157,55,87,204,239,91,246,239,117,157,63,15,156, -149,126,244,172,180,24,83,37,217,247,91,57,122,193,148,205,254,206,100,203,34,37,171,149,172,85,254,205,136,162,34,29,85,233, -40,86,211,69,133,183,158,125,31,114,181,214,133,123,147,171,181,46,220,151,182,238,149,191,115,225,146,22,135,93,200,82,153,118, -169,182,61,42,207,3,63,174,108,94,37,139,149,244,171,178,1,244,200,94,95,117,127,171,50,97,181,126,226,59,146,200,111,81,125, -108,113,244,91,176,72,201,86,85,158,169,183,133,144,101,83,182,50,213,150,93,46,56,213,150,122,215,138,190,118,165,204,84,254, -10,170,90,105,141,102,44,211,48,243,27,12,35,187,37,101,76,180,110,215,199,117,98,221,196,187,123,136,245,16,239,129,88,67,124, -77,47,85,175,53,38,7,45,61,155,92,149,202,141,166,114,185,222,84,46,111,152,70,150,88,47,241,94,184,246,246,146,214,139,143, -170,94,221,76,102,173,84,178,77,207,100,218,150,39,242,169,241,84,126,178,147,46,57,211,158,201,164,83,9,61,159,178,204,185,5, -159,222,212,144,145,152,76,164,141,149,122,58,61,168,39,118,228,58,105,214,133,74,57,179,18,150,137,190,228,219,86,10,185,43, -239,204,26,206,234,153,145,84,34,215,182,82,55,199,117,84,56,251,60,89,86,218,202,118,167,210,121,35,123,225,252,117,122,62,155, -218,213,73,243,255,100,254,25,85,205,60,215,117,131,158,50,209,191,234,115,115,54,25,9,100,84,76,101,88,185,182,21,99,102, -50,109,116,82,165,211,216,179,34,101,38,69,237,211,117,140,99,229,218,176,60,171,199,13,81,121,205,153,25,235,44,49,93,42,111, -254,153,121,98,205,231,174,55,187,173,196,88,110,229,136,110,14,27,133,101,117,118,101,202,213,57,164,41,227,85,89,107,44,211, -73,151,157,155,19,207,26,198,250,193,156,145,29,55,178,104,229,170,180,53,168,167,123,245,73,107,44,63,221,204,156,63,93,174, -147,90,207,116,72,153,153,177,252,168,145,31,177,146,109,43,244,156,209,35,210,88,120,19,243,39,183,69,211,133,253,87,39,83,121, -43,219,99,14,89,157,180,224,194,110,231,84,185,232,93,124,215,73,125,157,110,234,195,162,199,221,189,9,107,180,45,107,165,83, -109,219,199,18,70,219,57,199,108,238,5,206,210,220,51,71,190,228,175,173,167,147,234,223,173,104,39,53,244,38,245,244,120,106, -71,155,110,154,86,94,158,169,182,213,102,34,109,229,82,230,240,202,180,158,147,135,229,92,159,30,204,75,86,229,215,159,39,127, -157,49,58,168,28,140,156,216,49,34,166,180,165,177,185,218,176,197,178,125,198,206,49,195,76,96,91,151,59,115,236,250,26,28, -166,158,116,218,24,214,211,203,19,9,35,151,91,189,43,97,100,236,197,152,123,30,159,236,240,216,40,6,231,240,170,112,122,33,42, -12,219,179,50,109,188,198,234,27,75,140,216,43,231,40,23,114,184,172,31,220,46,15,101,157,195,214,103,36,198,178,136,85,23,40, -210,135,32,96,14,139,29,51,109,203,26,67,105,212,131,110,140,91,118,236,138,235,217,97,195,217,219,154,243,184,219,93,195,171, -56,190,117,195,106,242,59,183,6,177,45,196,183,244,144,123,75,15,126,160,174,33,207,150,53,61,221,221,107,200,5,217,35,62,69, -56,222,178,166,31,153,66,233,93,35,62,164,214,143,220,222,126,4,245,45,253,40,213,47,107,96,253,164,245,139,114,248,232,21,42, -98,122,191,80,68,96,31,192,117,48,208,67,161,129,115,215,171,98,224,60,211,229,211,229,146,205,141,197,98,83,122,187,67,191, -200,161,95,236,208,47,129,94,98,235,221,105,125,56,71,30,93,158,63,97,20,178,87,31,52,210,84,164,171,219,130,102,233,201,228, -249,163,10,177,65,42,23,23,200,138,177,124,222,50,55,100,81,165,145,36,207,160,133,228,40,164,12,172,228,73,200,59,129,188,9, -25,250,146,228,198,221,163,103,169,36,97,37,141,13,22,34,245,242,188,72,76,69,119,10,200,68,60,171,155,185,33,43,59,74,165,226, -230,65,72,207,73,111,84,100,95,64,168,200,26,67,218,149,76,13,13,17,51,200,109,136,240,75,254,161,233,64,155,164,98,236,129, -229,246,8,103,8,117,250,110,83,247,24,149,194,44,206,12,134,108,100,115,84,36,146,98,226,201,39,52,229,228,23,91,73,84,31,79, -141,26,178,210,171,141,212,240,72,158,42,160,246,170,29,183,222,236,75,96,3,153,50,223,222,89,84,6,85,246,27,167,85,118,215,63, -109,232,73,146,23,169,77,250,196,181,5,101,43,149,8,197,178,242,34,126,80,16,137,190,73,204,247,104,31,246,100,42,97,80,0,150, -205,102,74,76,158,232,180,108,255,236,112,46,135,180,37,149,75,13,166,210,98,13,69,153,247,224,66,179,38,226,214,14,116,47,60, -149,150,78,105,3,145,45,147,214,39,187,179,58,6,231,66,238,181,242,115,43,177,17,42,195,68,98,29,49,113,27,244,49,177,192,193, -41,195,38,35,135,136,48,101,89,49,181,23,168,212,182,32,114,174,178,38,176,183,166,146,155,51,84,57,149,144,81,245,234,84,50, -137,62,169,102,214,89,104,67,150,57,195,144,213,135,11,117,74,3,170,81,117,202,187,158,138,70,244,156,188,95,169,122,36,149,52, -250,172,161,188,188,51,186,179,214,168,61,82,184,192,49,46,214,210,53,98,229,242,196,82,228,195,90,174,151,193,33,71,90,106, -116,148,202,196,147,45,165,167,87,234,153,220,58,204,48,149,42,67,159,145,94,109,38,167,242,145,236,203,235,217,60,21,203,91, -42,62,153,49,200,47,213,235,237,27,139,60,41,196,161,29,6,154,200,245,152,185,188,142,88,76,69,169,220,250,140,142,192,140,98, -57,53,243,228,221,97,76,174,20,77,85,239,184,192,211,175,180,144,209,55,34,230,197,157,150,39,180,20,235,101,100,69,203,215,224, -202,33,87,218,24,202,147,39,109,152,195,249,17,242,168,94,48,147,92,166,88,83,175,105,76,92,35,23,215,74,39,71,228,231,4,149, -91,102,225,81,184,50,107,232,121,172,100,197,180,105,149,145,203,103,173,73,177,188,211,70,181,5,28,37,11,123,160,118,218,212 -,167,143,27,133,65,99,154,242,134,211,95,206,219,153,85,244,229,173,76,6,166,106,156,73,217,143,179,158,6,228,177,76,236,128, -9,42,181,156,143,40,10,88,103,196,37,42,182,204,194,134,43,149,234,186,177,116,62,149,17,147,44,147,216,52,69,34,192,73,103,120, -244,165,222,103,20,194,132,31,247,133,133,171,74,158,113,52,104,175,147,215,150,248,50,137,34,203,243,121,132,7,119,70,110, -56,95,70,207,194,83,30,82,119,70,198,37,150,165,134,172,49,44,150,45,123,225,199,54,133,179,198,168,53,110,216,61,95,111,158, -21,83,221,89,25,85,180,156,145,167,64,78,196,159,169,167,46,249,145,150,227,215,197,198,169,118,166,122,236,222,203,61,43,138, -57,30,76,178,88,111,97,179,208,76,164,206,251,22,165,25,185,66,172,217,156,114,4,143,218,243,154,197,83,71,71,220,206,217,209, -71,238,173,210,220,25,81,199,87,72,166,237,62,189,39,149,78,95,99,229,229,74,250,115,216,203,133,8,128,130,72,77,157,89,56,139, -61,98,247,11,247,60,178,177,65,166,147,51,115,118,111,122,166,219,82,35,117,229,71,82,184,208,196,231,220,152,146,237,176,138, -144,173,161,14,168,98,10,138,198,242,67,29,50,120,178,113,114,143,235,105,177,210,82,172,31,34,151,120,124,82,153,248,116,238, -143,98,97,136,91,155,115,6,5,199,207,14,183,190,241,233,81,179,9,98,187,136,239,138,129,118,98,147,116,132,51,242,6,250,187,232, -81,124,227,109,25,208,248,19,172,116,175,198,142,177,138,57,26,165,120,235,174,223,111,239,98,229,229,169,46,158,171,235,162, -251,56,167,87,153,55,192,47,223,202,175,154,88,68,247,112,246,58,146,231,200,251,81,89,224,33,250,162,45,102,107,195,143,179, -3,204,219,194,159,167,78,254,91,54,193,159,252,192,196,62,198,221,190,229,139,186,90,187,186,174,24,208,40,233,187,81,99,70,107, -215,253,245,154,246,121,182,144,85,207,136,205,214,248,103,25,103,229,213,110,206,55,214,185,201,205,220,154,199,199,23,30,114, -251,60,228,97,30,238,209,22,44,224,227,45,110,190,128,231,90,104,150,221,244,44,254,58,123,67,40,39,196,192,62,28,38,92,94, -129,181,244,136,198,95,99,191,18,246,237,72,211,97,77,124,190,164,241,254,235,33,127,168,177,126,136,99,82,160,200,47,165,242, -145,48,61,167,28,126,110,59,124,219,22,255,193,217,215,153,183,110,237,218,69,253,107,251,91,73,103,55,200,82,183,104,252,167, -236,99,104,226,35,181,139,232,117,198,239,101,59,188,117,123,121,168,142,103,234,120,89,39,31,59,180,141,79,174,161,253,92,187, -151,141,32,139,151,238,225,227,117,183,15,108,223,171,209,43,140,247,211,45,92,150,9,236,141,132,111,167,63,112,183,254,57, -246,18,123,154,189,23,77,190,197,93,191,100,31,100,15,178,47,160,254,165,123,251,105,82,58,242,103,168,142,31,189,169,110,173, -86,124,45,239,213,188,63,97,26,127,146,182,242,101,45,172,162,44,102,19,236,213,74,238,103,124,105,151,230,255,87,214,182,148, -49,205,247,9,198,23,177,112,233,149,110,159,219,223,238,46,217,238,241,181,178,138,42,254,254,206,46,143,127,41,171,155,33,236, -103,26,121,55,171,11,208,1,141,253,39,218,143,104,236,71,88,162,80,21,247,183,240,209,58,108,148,237,209,217,110,18,178,185, -209,77,63,139,45,160,143,106,236,1,49,217,71,52,182,205,27,72,133,233,59,140,189,12,195,83,26,29,100,53,173,219,215,238,186,97, -214,94,226,117,236,167,108,102,45,159,205,183,184,248,253,172,122,177,109,8,75,67,8,134,98,62,7,134,48,155,89,83,80,106,137, -51,230,227,236,182,72,100,247,110,215,177,234,122,246,106,53,105,30,242,223,22,193,94,225,13,55,239,118,29,158,197,246,69,94, -18,31,39,197,199,254,26,198,15,129,103,107,200,85,54,171,140,51,249,47,10,199,147,53,200,62,56,27,31,135,103,187,110,225,84,12, -216,159,65,24,44,100,79,205,102,236,36,184,109,78,37,59,52,135,177,199,192,9,112,18,236,139,48,246,40,120,13,252,17,220,86,207, -216,33,112,10,28,110,128,31,120,174,17,101,230,50,215,41,176,191,137,177,99,77,46,182,111,1,99,7,23,114,246,0,120,118,97,208, -241,251,176,130,44,252,93,165,248,125,78,225,111,43,197,239,127,10,127,95,233,162,233,191,177,20,191,63,42,252,157,101,225,119, -84,226,111,45,181,160,173,139,223,203,177,136,253,119,69,199,160,123,34,182,93,252,31,53,11,218,191,67,147,255,111,29,177,219, -21,127,155,169,41,127,241,255,201,174,136,93,175,248,63,104,82,101,229,255,109,7,237,190,138,191,3,253,63,65,69,100,73,64,42,0,0,0,0}; +{31,139,8,8,174,115,161,94,0,3,106,97,118,97,67,111,109,112,111,110,101,110,116,80,101,101,114,86,105,101,119,46,100,101,120,0, +165,154,9,120,91,213,149,199,207,189,79,139,45,203,178,44,111,137,45,39,242,26,37,113,108,153,0,113,176,3,89,77,157,56,100,177, +146,18,59,52,60,75,207,182,18,249,61,69,146,237,4,232,16,150,38,41,100,90,104,3,221,82,186,165,25,74,51,109,153,161,148,73,75, +39,3,101,107,25,26,104,233,164,45,75,232,199,180,64,7,62,160,105,203,116,33,243,191,247,93,217,202,86,218,142,252,253,116,206, +59,247,220,253,222,115,175,100,197,141,29,158,200,252,139,40,84,84,16,62,178,99,227,93,78,119,55,171,63,246,210,255,110,45,251, +64,100,247,111,158,226,203,231,16,165,136,104,199,198,11,3,164,94,187,102,19,253,154,108,123,59,8,58,136,22,64,158,128,44,135, +204,186,137,12,200,242,2,34,13,178,171,136,232,238,25,68,7,32,127,82,69,116,28,156,0,239,128,63,130,83,128,79,35,114,129,66,80, +12,154,193,108,48,15,180,131,139,193,21,224,102,240,57,112,4,60,11,126,11,42,166,19,45,6,253,32,3,246,130,187,192,183,192,143, +192,187,160,172,26,101,1,3,236,6,247,131,231,65,97,13,81,7,216,5,190,13,94,0,60,72,84,15,86,128,45,32,13,238,4,223,1,79,131,147, +160,160,150,104,22,232,4,91,193,110,176,15,124,26,124,22,124,1,220,13,14,131,251,192,17,112,20,60,2,158,0,79,129,31,129,227, +224,5,240,11,240,26,120,29,188,13,222,1,127,6,12,227,230,2,30,224,3,245,96,1,88,6,214,128,1,48,12,50,96,23,216,11,238,0,159,3, +71,192,131,224,24,56,14,78,128,87,192,91,224,29,224,156,73,20,0,245,160,29,92,2,150,128,203,193,74,176,14,108,1,91,193,13,224, +54,240,105,112,8,220,7,254,29,252,24,188,8,222,4,239,2,119,136,200,15,106,65,27,184,12,68,65,12,100,192,237,224,19,224,179,224, +243,224,94,240,48,120,22,188,12,222,2,238,58,162,105,96,54,232,0,43,192,26,48,2,210,96,7,184,22,236,1,251,192,103,193,97,240, +32,120,28,252,4,188,0,94,3,39,193,41,80,80,79,84,7,34,96,1,232,6,189,32,10,54,131,45,192,0,38,200,130,107,192,63,130,47,130,251, +192,99,224,101,240,123,224,105,32,106,0,115,193,37,96,37,216,0,226,96,20,76,128,221,96,63,56,0,190,12,190,14,238,7,15,129, +39,192,147,224,77,224,107,196,250,5,213,96,14,232,0,235,128,14,44,240,97,240,121,240,32,248,62,248,41,248,111,240,91,160,53,97, +254,64,61,104,7,171,192,58,176,9,232,96,24,36,65,26,92,7,174,7,187,193,71,193,29,224,16,184,23,60,12,126,8,158,1,207,130,159, +130,231,155,236,189,235,4,216,206,228,3,37,192,15,74,129,8,6,101,100,239,247,10,80,9,176,141,9,219,145,176,221,8,91,139,106,68, +108,0,88,198,132,229,70,88,30,132,233,37,76,7,97,24,9,221,39,116,131,80,21,53,131,89,32,12,16,94,8,97,135,230,130,22,48,15, +180,130,54,16,81,49,231,2,48,31,92,8,46,2,29,224,114,176,26,92,1,214,128,181,100,247,33,247,114,40,121,115,165,221,47,166,158, +93,74,23,118,209,87,174,236,5,74,223,7,187,71,249,137,151,87,165,237,87,118,159,178,123,212,184,228,244,138,60,127,49,46,7,42, +109,93,140,201,65,149,183,78,249,20,169,177,16,109,40,86,227,113,88,249,11,253,62,229,31,86,254,197,106,140,190,83,105,247,125, +174,178,47,84,186,40,231,18,165,127,15,122,167,210,143,65,239,82,250,113,232,139,148,254,10,244,75,149,126,18,250,101,185,50, +49,169,139,149,94,0,125,169,210,253,121,246,105,121,122,8,250,114,165,135,243,236,23,230,233,93,121,250,242,188,50,123,243,236, +81,232,203,148,190,57,207,158,173,156,210,197,24,46,81,122,60,175,156,100,158,191,24,183,21,185,188,176,119,43,253,186,60,159, +125,121,250,254,42,123,29,181,168,241,124,159,210,15,192,222,163,244,131,208,87,42,253,27,208,123,149,254,0,244,85,74,63,154, +103,127,60,207,126,172,74,204,41,163,171,200,150,63,151,67,28,162,43,149,252,168,148,140,62,166,228,126,37,239,80,242,78,37,63, +161,252,63,79,98,175,181,208,231,164,172,161,159,146,216,119,65,58,174,228,75,82,86,211,203,36,214,29,167,219,164,172,161,187, +164,108,161,111,75,89,68,223,149,235,175,142,46,38,177,55,106,233,33,18,235,221,69,163,82,250,233,26,200,66,236,120,38,229,60, +122,132,196,122,172,147,207,69,202,94,132,221,243,168,236,151,253,92,130,250,146,82,150,146,169,158,175,21,107,71,217,253,216, +145,219,213,243,152,148,26,141,147,29,99,38,148,220,33,37,163,93,74,222,64,98,143,113,74,75,89,79,215,147,136,67,51,100,125, +101,136,10,223,148,178,157,238,151,178,130,254,141,196,62,108,166,126,37,31,38,17,171,154,164,255,116,68,144,143,72,217,64,79, +72,121,17,253,72,142,227,44,153,94,141,18,238,147,227,55,91,62,215,192,190,78,201,245,82,122,169,79,202,50,250,177,146,207,202, +241,156,41,253,131,24,201,168,148,97,218,32,101,25,109,86,82,151,50,34,239,73,65,212,180,77,74,151,188,83,5,85,255,130,136,122, +25,41,11,105,167,148,30,186,78,165,127,80,202,2,250,7,41,237,113,8,162,103,55,41,121,179,146,31,146,114,26,237,86,114,143,178, +239,149,178,138,62,172,228,45,74,222,42,229,116,218,39,101,27,125,70,201,3,82,6,233,30,181,126,190,170,228,97,37,255,89,165,127, +77,61,127,93,201,111,168,245,117,175,148,33,250,23,41,155,232,95,165,180,231,43,168,230,75,60,127,75,173,203,7,164,180,231, +47,136,40,127,68,202,185,244,152,146,143,75,217,72,63,144,178,156,254,83,202,57,244,148,122,254,161,242,59,166,228,211,42,253, +25,213,255,95,144,136,189,1,202,74,121,49,125,90,174,127,31,157,32,17,111,237,245,219,140,40,107,145,136,185,26,13,74,201,233, +75,36,226,110,9,125,138,236,51,142,200,142,207,34,46,137,179,98,57,228,199,85,144,174,81,107,184,89,249,137,244,40,210,15,169, +116,113,14,148,146,125,142,94,167,242,199,33,159,10,79,249,111,129,62,20,182,207,177,20,228,4,184,33,108,159,87,183,72,59,151, +250,137,38,177,47,113,31,12,20,81,202,127,53,108,1,218,236,247,200,179,169,0,79,34,255,171,240,25,16,245,185,202,169,158,123, +225,87,128,220,209,76,17,69,231,123,201,244,95,0,47,47,11,208,66,214,53,101,13,93,140,221,49,229,19,129,143,71,91,143,163,106, +125,19,163,123,163,183,147,230,184,232,234,106,218,144,241,80,135,86,73,1,109,51,180,156,127,52,91,68,219,253,77,216,231,94,199, +118,255,108,200,34,199,246,200,28,90,230,20,254,11,53,55,45,184,218,73,129,50,145,199,135,186,42,48,23,166,191,28,237,61,179, +142,240,83,226,252,214,228,152,248,154,237,187,200,64,192,171,250,90,143,185,72,133,66,24,237,1,191,143,6,202,138,101,191,153, +252,195,221,163,217,62,251,83,126,49,19,190,73,123,243,164,125,150,180,115,117,35,104,109,182,199,59,234,47,150,243,163,193, +46,234,189,184,217,62,143,163,161,98,180,82,220,62,208,195,58,209,238,106,212,236,155,244,91,116,94,191,26,233,231,67,92,16,61, +89,14,63,177,238,3,174,64,69,42,84,73,95,161,122,135,152,61,23,90,53,176,31,209,205,81,67,41,92,88,247,23,14,236,247,227,83, +150,19,37,124,128,14,146,199,209,225,184,138,102,122,196,51,110,228,212,127,160,4,90,63,37,104,243,103,16,105,67,125,180,9,239, +81,249,190,1,43,181,30,43,35,229,23,61,42,115,148,83,195,146,121,212,204,68,28,51,67,14,180,39,42,106,114,122,48,126,78,18, +37,186,17,179,2,154,233,215,145,203,235,168,118,126,159,2,205,13,67,109,20,112,15,22,148,209,234,2,151,59,80,21,44,40,146,154, +25,185,138,162,46,175,214,161,149,83,128,7,26,27,150,71,40,224,220,238,223,130,222,121,93,171,93,14,103,160,34,32,165,25,137, +211,199,29,24,3,63,230,22,229,206,116,216,173,223,79,225,47,20,59,194,39,193,219,224,77,240,51,112,28,83,46,239,150,83,175,93, +151,209,223,244,124,230,203,78,23,231,118,37,226,145,65,246,121,194,181,134,155,89,253,141,108,246,46,198,103,237,101,77,187, +153,61,223,226,117,143,90,7,125,161,18,185,143,197,250,19,207,247,230,214,77,164,139,234,52,49,155,246,254,58,162,214,101,223, +226,18,170,228,242,158,202,23,34,197,39,45,169,200,66,114,176,240,31,166,202,127,168,217,190,135,138,187,115,63,234,240,169, +58,196,235,241,102,123,255,7,252,37,147,235,242,25,213,158,13,254,82,89,15,87,235,248,120,179,125,55,52,253,23,138,157,131,59, +160,67,230,11,80,248,93,77,149,247,66,179,29,51,124,50,159,125,195,253,101,158,205,5,155,240,124,253,61,250,176,64,245,33,231, +255,187,247,240,239,152,236,179,221,142,83,231,104,135,123,214,217,54,95,158,205,161,234,170,152,101,223,151,3,76,68,222,129,8, +39,91,106,180,169,29,81,228,205,77,17,55,109,138,184,148,181,16,235,7,55,118,255,166,136,3,233,5,216,5,149,104,15,206,32,86, +170,250,43,198,190,113,150,29,131,207,221,254,232,210,0,165,214,47,38,199,186,240,59,226,179,129,38,231,189,229,188,121,230,175, +56,117,74,246,123,113,43,57,116,145,167,16,118,81,207,194,89,246,103,151,128,191,111,16,185,80,76,59,227,142,133,12,51,133, +241,107,113,139,207,78,34,197,244,23,33,94,123,88,106,221,37,212,156,9,255,198,138,84,209,120,129,135,194,111,152,254,185,104, +117,248,53,49,72,118,59,114,159,181,196,103,142,98,133,7,41,162,190,190,89,246,231,166,0,155,172,143,163,62,228,44,97,11,221, +133,168,167,16,109,243,240,64,195,5,23,184,201,90,60,141,198,63,233,97,225,183,77,156,25,216,247,188,131,191,126,42,167,155,161, +65,212,225,145,237,75,173,69,187,180,64,105,248,121,123,60,68,93,163,179,236,207,58,167,143,135,221,51,97,19,125,114,161,174, +212,250,78,140,100,192,31,254,173,125,183,20,175,107,242,230,185,144,156,178,188,189,106,124,173,43,167,83,116,60,191,212,14, +212,105,175,171,205,88,87,246,103,82,46,63,139,125,10,121,130,40,168,239,105,120,107,98,116,153,38,71,151,149,48,211,239,69,249, +158,66,211,47,206,133,34,247,179,183,159,162,185,236,119,114,116,194,111,245,61,131,157,194,76,236,191,25,136,172,166,95,68,104, +143,211,196,30,131,116,185,159,30,47,88,36,78,211,210,240,115,239,237,121,153,237,249,216,123,123,94,10,79,211,47,206,2,79, +81,160,116,65,205,28,10,212,53,4,91,17,19,219,113,151,9,84,95,116,164,142,68,41,162,140,175,137,50,66,1,33,89,192,185,220,233, +117,222,184,225,209,10,51,84,102,91,42,151,187,188,174,27,135,30,173,204,149,123,220,131,153,60,129,118,220,84,206,232,20,209, +55,111,127,201,195,10,22,122,166,209,95,219,131,217,52,116,42,191,61,127,79,75,68,73,225,159,255,237,45,88,164,90,208,244,255, +110,193,34,217,2,76,51,115,203,181,38,214,150,136,13,109,74,138,152,34,238,247,25,185,246,184,60,147,75,194,246,119,13,104,35, +78,64,55,86,127,181,246,36,5,202,27,150,227,4,116,14,186,112,2,202,211,236,42,186,192,225,101,11,81,178,15,251,46,252,46,248,83, +32,208,80,143,243,79,19,231,95,1,206,184,213,14,174,137,115,111,59,15,191,81,204,195,255,3,94,3,175,136,245,94,138,182,137, +251,161,87,68,34,62,171,178,105,154,214,16,174,111,153,61,39,47,6,46,12,79,237,13,77,89,151,132,237,123,94,7,119,99,127,153,161, +43,225,225,163,192,226,240,31,69,255,236,56,185,50,108,127,55,98,250,219,228,141,174,154,127,18,158,28,177,211,139,79,38,211, +169,3,145,195,244,199,176,67,61,108,17,43,195,104,155,145,153,20,65,143,47,146,254,102,100,6,249,29,209,118,63,238,110,13,178, +252,92,74,128,155,145,90,242,115,59,173,81,140,239,219,246,247,186,249,175,187,207,120,126,224,140,103,209,167,114,178,207,183, +82,180,130,41,155,253,153,201,150,5,74,86,41,89,163,252,155,17,69,197,115,88,61,135,49,155,14,202,221,245,236,243,144,171,185, +206,157,155,92,205,117,238,188,180,117,183,252,206,133,75,90,242,236,66,22,203,103,135,170,219,165,210,92,240,227,202,230,86, +178,80,73,175,202,235,67,139,236,249,85,231,183,202,19,84,243,39,62,35,137,244,22,213,198,150,188,118,11,230,41,217,170,242,51, +117,183,16,178,100,210,86,162,234,178,243,249,39,235,82,247,90,209,214,174,132,153,200,94,74,149,203,172,209,148,101,26,102, +118,173,97,164,55,38,140,137,214,173,250,184,78,172,155,120,119,15,177,30,226,61,16,43,137,175,236,165,170,85,198,206,65,75,79, +199,151,39,50,163,137,76,166,55,145,201,26,166,145,38,214,75,188,23,174,189,189,164,245,226,173,178,87,55,227,105,43,17,111, +211,83,169,182,37,177,108,98,60,145,221,217,73,23,158,110,79,165,146,137,152,158,77,88,102,99,206,167,55,49,100,196,118,198,146, +198,50,61,153,28,212,99,219,50,157,52,253,124,185,242,147,98,150,137,182,100,219,150,9,185,35,155,159,52,156,214,83,35,137, +88,166,109,153,110,142,235,40,112,198,57,146,172,164,149,238,78,36,179,70,250,252,233,171,245,108,58,177,163,147,102,255,197, +244,211,138,154,118,182,235,90,61,97,162,125,85,103,167,172,55,98,72,40,155,76,176,50,109,75,199,204,120,210,232,164,242,124, +99,207,210,132,25,23,165,79,149,49,142,153,107,195,244,172,24,55,68,225,213,167,39,172,182,196,112,169,180,217,167,167,137,57, +111,92,99,118,91,177,177,204,178,17,221,28,54,114,211,154,223,148,73,215,252,46,77,26,47,79,91,99,169,78,186,248,236,148,104, +218,48,214,12,102,140,244,184,145,70,45,151,39,173,65,61,217,171,239,180,198,178,83,213,204,252,203,249,58,169,245,116,135,132, +153,26,203,142,26,217,17,43,222,182,84,207,24,61,226,25,19,111,98,252,228,178,104,58,191,255,138,120,34,107,165,123,204,33, +171,147,230,156,223,237,172,34,231,189,135,239,106,169,175,214,77,125,88,180,184,187,55,102,141,182,165,71,51,201,182,173,99,49, +163,237,172,109,214,120,158,189,212,120,122,207,23,254,189,229,116,82,221,123,101,237,164,250,222,184,158,28,79,108,107,211, +77,211,202,202,61,213,182,194,140,37,173,76,194,28,94,150,212,51,114,179,156,237,211,131,113,73,171,244,186,115,164,175,54,70,7, +149,131,145,17,43,70,196,148,182,36,22,87,27,150,88,186,207,216,62,102,152,49,44,235,210,252,20,187,188,250,60,83,79,50,105, +12,235,201,37,177,152,145,201,172,216,17,51,82,246,100,52,158,195,39,61,60,54,138,206,229,121,149,229,123,33,42,12,219,163,50, +101,188,194,234,27,139,141,216,51,151,151,47,144,231,178,102,112,171,220,148,181,121,182,62,35,54,150,70,172,58,79,150,62,4, +1,115,88,172,152,41,91,218,24,74,162,28,52,99,220,178,99,87,84,79,15,27,249,173,173,62,135,187,221,52,220,138,163,155,214,174, +32,111,254,210,32,182,145,248,198,30,114,110,236,193,11,234,74,114,109,92,217,211,221,189,146,28,144,61,226,93,132,227,141,43, +251,145,40,148,222,149,226,77,106,253,72,237,237,71,80,223,216,143,92,253,178,4,214,79,90,191,200,135,183,94,161,34,166,247,11, +69,4,246,1,28,7,3,61,20,24,56,123,190,202,6,206,49,92,30,93,78,89,99,36,18,153,212,219,243,244,11,242,244,249,121,250,133,208, +139,108,189,59,169,15,103,200,165,203,253,39,140,66,246,234,131,70,146,10,116,117,90,208,116,61,30,63,119,84,33,54,72,165,226, +0,89,58,150,205,90,230,218,52,138,52,226,228,26,180,240,56,10,41,3,43,185,98,242,76,32,119,76,134,190,56,57,113,246,232,105, +42,138,89,113,99,173,133,72,189,36,43,30,38,163,59,249,228,67,52,173,155,153,33,43,61,74,197,226,228,65,72,207,72,111,20,100,31, +64,40,200,26,195,179,35,158,24,26,34,102,144,211,16,225,151,188,67,83,129,54,78,133,88,3,75,236,30,86,8,117,234,108,83,231, +24,21,195,44,246,12,186,108,164,51,84,32,30,197,192,147,71,104,202,201,43,150,146,40,62,154,24,53,100,161,239,51,18,195,35,89, +42,131,218,171,86,220,26,179,47,134,5,100,202,116,123,101,81,9,84,217,110,236,86,217,92,239,148,161,39,78,110,60,173,215,39, +174,204,41,155,168,72,40,150,149,21,241,131,252,120,232,219,137,241,30,237,195,154,76,196,12,242,193,178,193,76,136,193,19,141, +150,245,159,25,206,101,151,54,38,50,137,193,68,82,204,161,200,243,126,28,104,214,68,212,218,134,230,5,39,159,165,83,210,64, +100,75,37,245,157,221,105,29,157,115,32,245,74,249,190,137,216,8,149,96,32,49,143,24,184,181,250,152,152,96,255,164,97,189,145, +65,68,152,180,44,157,92,11,84,108,91,16,57,151,91,19,88,91,147,143,27,82,84,62,249,32,163,234,251,18,241,56,218,164,170,89, +109,161,14,153,231,52,67,90,31,206,149,41,13,40,70,149,41,207,122,42,24,209,51,242,124,165,170,145,68,220,232,179,134,178,242, +204,232,78,91,163,118,79,225,2,199,168,152,75,199,136,149,201,18,75,144,7,115,185,70,6,135,12,105,137,209,81,42,17,87,182,132, +158,92,166,167,50,171,49,194,84,172,12,125,70,114,133,25,159,76,199,99,95,86,79,103,169,80,158,82,209,157,41,131,188,82,221,98, +159,88,228,74,32,14,109,51,80,69,166,199,204,100,117,196,98,42,72,100,214,164,116,4,102,100,203,168,145,39,247,54,99,231,50, +81,85,213,182,243,92,253,138,115,9,125,35,98,92,156,73,185,67,139,49,95,70,90,212,124,5,142,28,114,36,141,161,44,185,146,134,57, +156,29,33,151,106,5,51,201,97,138,57,117,155,198,196,21,114,114,173,100,124,68,190,79,80,169,101,230,46,133,203,210,134,158, +197,76,150,77,153,150,27,153,108,218,218,41,166,119,202,168,150,64,94,206,220,26,168,153,50,245,233,227,70,174,211,24,166,172, +145,239,47,199,237,244,34,250,178,86,42,5,83,21,246,164,108,199,25,87,3,114,89,38,86,192,4,21,91,249,151,40,242,89,167,197,37, +42,180,204,220,130,43,150,234,234,177,100,54,145,18,131,44,31,177,104,10,68,128,147,206,240,232,75,92,99,228,194,132,23,231,133, +133,163,74,238,113,84,104,207,147,219,150,248,48,137,44,75,178,89,132,7,103,74,46,56,79,74,79,195,83,110,82,103,74,198,37, +150,166,250,180,49,44,166,45,125,254,203,54,5,211,198,168,53,110,216,45,95,99,158,17,83,157,105,25,85,180,140,145,37,95,70,196, +159,201,171,46,121,241,44,251,175,139,133,83,149,255,212,99,183,94,174,89,145,45,239,194,36,179,245,230,22,11,77,195,211,57, +239,162,84,145,201,197,154,13,137,188,224,81,115,78,179,184,234,232,136,219,25,59,250,200,181,85,156,57,45,234,120,114,143,73, +187,77,239,79,36,147,87,88,89,57,147,222,12,214,114,46,2,32,35,158,38,247,44,156,197,26,177,219,133,115,30,201,88,32,83,143, +211,50,118,107,122,166,234,82,61,117,100,71,18,56,208,196,123,99,68,201,118,88,69,200,214,80,6,84,49,4,5,99,217,161,14,25,60, +217,56,57,199,245,164,152,105,41,214,12,145,67,92,62,169,68,188,231,175,143,66,97,136,90,27,50,6,249,199,207,12,183,158,241,169, +94,179,9,98,59,136,239,136,128,118,98,59,233,7,156,145,219,215,223,69,207,224,19,111,203,128,198,31,98,197,123,52,118,148,149, +205,212,40,193,91,119,252,126,107,23,43,45,77,116,241,76,109,23,29,225,156,94,102,110,31,191,100,19,191,124,98,30,125,139,179, +87,241,120,150,60,138,194,124,247,209,35,182,232,208,134,31,100,183,51,119,11,127,154,58,249,27,108,130,63,252,193,137,189,140, +59,61,75,230,117,181,118,117,93,58,160,81,220,115,157,198,140,214,174,67,117,154,246,101,54,151,85,85,68,102,104,252,139,140, +179,210,42,39,231,235,106,157,228,100,78,205,229,225,115,15,58,61,46,114,49,23,119,105,115,230,240,241,22,39,159,195,51,45,52, +223,174,122,62,127,149,189,38,148,63,136,142,221,18,164,52,196,42,58,166,241,87,216,175,133,253,102,97,167,71,53,241,254,59, +141,247,111,129,124,83,99,253,16,63,147,2,121,110,112,8,229,214,32,189,166,28,254,100,59,188,108,139,63,115,246,93,230,174,93, +181,106,94,255,170,254,86,186,150,93,45,115,29,208,248,139,236,35,168,227,214,154,121,116,19,231,119,177,109,238,218,61,60,80, +203,83,181,188,164,147,143,29,220,204,119,174,164,67,92,187,139,141,32,137,23,239,230,227,181,119,14,108,221,163,209,11,140,247, +211,1,59,143,111,79,40,120,39,221,161,57,245,47,177,231,216,35,236,3,168,114,159,230,248,21,187,137,221,195,190,130,242,23, +237,233,167,143,51,233,201,31,167,90,126,228,250,218,85,90,225,149,188,87,115,255,156,105,252,97,218,196,23,183,176,178,146,136 +,141,191,87,43,58,196,248,162,46,205,251,31,172,109,17,99,154,231,99,140,207,99,193,226,203,156,30,167,183,221,89,180,213,229, +105,101,101,149,252,218,206,46,151,119,17,171,173,16,246,211,141,188,155,213,250,232,171,26,251,37,26,16,210,216,127,97,146,2, +149,220,219,194,71,107,177,84,182,134,103,56,73,200,230,6,39,189,20,153,67,255,164,177,187,197,112,255,64,99,155,221,190,68, +144,126,197,216,243,48,124,79,163,253,172,186,117,235,170,29,87,79,223,67,188,150,189,200,166,213,240,25,124,163,131,31,98,85, +11,108,67,80,26,2,48,20,242,153,48,4,217,180,234,156,82,67,156,49,15,103,183,133,66,187,118,57,142,86,213,177,151,171,72,115, +145,247,182,16,86,11,175,191,97,151,227,240,116,182,55,244,156,120,59,41,222,246,85,51,126,16,60,89,77,142,146,233,37,156,201, +191,48,28,79,86,35,121,255,12,188,29,158,225,184,145,83,33,96,127,5,65,48,151,125,111,6,99,39,193,109,51,203,217,193,153,140, +125,7,156,0,39,193,222,16,99,15,128,87,192,159,192,109,117,140,29,4,239,128,195,245,240,3,199,26,144,167,145,57,222,1,251,154, +24,59,218,228,96,123,231,48,182,127,46,103,119,131,39,231,218,223,221,228,190,19,203,201,220,111,43,197,119,58,185,223,87,138, +239,128,114,191,177,116,208,212,239,44,197,119,72,185,223,90,230,190,167,18,191,183,212,252,182,46,190,155,99,33,251,183,69,71, +161,187,66,182,93,252,159,154,249,237,239,209,228,255,174,67,118,189,226,247,153,154,242,23,255,83,118,132,236,114,197,255, +161,73,229,149,255,223,246,219,109,21,191,5,253,63,31,222,169,74,68,42,0,0,0,0}; //============================================================================== #if JUCE_PUSH_NOTIFICATIONS && JUCE_MODULE_AVAILABLE_juce_gui_extra @@ -196,8 +195,6 @@ static const uint8 javaComponentPeerView[] = extern void juce_firebaseRemoteMessageSendError (void*, void*); #endif -extern void juce_contentSharingCompleted (int); - //============================================================================== #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ METHOD (create, "<init>", "(II)V") @@ -261,7 +258,7 @@ public: fullScreen (false), navBarsHidden (false), sizeAllocated (0), - scale ((float) Desktop::getInstance().getDisplays().getMainDisplay().scale) + scale ((float) Desktop::getInstance().getDisplays().getPrimaryDisplay()->scale) { auto* env = getEnv(); @@ -549,7 +546,7 @@ public: setNavBarsHidden (false); } - Rectangle<int> r (shouldBeFullScreen ? Desktop::getInstance().getDisplays().getMainDisplay().userArea + Rectangle<int> r (shouldBeFullScreen ? Desktop::getInstance().getDisplays().getPrimaryDisplay()->userArea : lastNonFullscreenBounds); if ((! shouldBeFullScreen) && r.isEmpty()) @@ -926,7 +923,7 @@ private: CALLBACK (handleAppPausedJni, "handleAppPaused", "(J)V") \ CALLBACK (handleAppResumedJni, "handleAppResumed", "(J)V") \ - DECLARE_JNI_CLASS_WITH_BYTECODE (ComponentPeerView, "com/roli/juce/ComponentPeerView", 16, javaComponentPeerView, sizeof (javaComponentPeerView)) + DECLARE_JNI_CLASS_WITH_BYTECODE (ComponentPeerView, "com/rmsl/juce/ComponentPeerView", 16, javaComponentPeerView, sizeof (javaComponentPeerView)) #undef JNI_CLASS_MEMBERS static void JNICALL handlePaintJni (JNIEnv*, jobject /*view*/, jlong host, jobject canvas, jobject paint) { if (auto* myself = reinterpret_cast<AndroidComponentPeer*> (host)) myself->handlePaintCallback (canvas, paint); } @@ -1291,7 +1288,7 @@ int JUCE_CALLTYPE NativeMessageBox::showYesNoBox (AlertWindow::AlertIconType /*i } //============================================================================== -static bool androidScreenSaverEnabled = false; +static bool androidScreenSaverEnabled = true; void Desktop::setScreenSaverEnabled (bool shouldEnable) { @@ -1306,7 +1303,7 @@ void Desktop::setScreenSaverEnabled (bool shouldEnable) auto* env = getEnv(); LocalRef<jobject> mainWindow (env->CallObjectMethod (activity.get(), AndroidActivity.getWindow)); - env->CallVoidMethod(mainWindow.get(), AndroidWindow.setFlags, shouldEnable ? FLAG_KEEP_SCREEN_ON : 0, FLAG_KEEP_SCREEN_ON); + env->CallVoidMethod (mainWindow.get(), AndroidWindow.setFlags, shouldEnable ? 0 : FLAG_KEEP_SCREEN_ON, FLAG_KEEP_SCREEN_ON); } androidScreenSaverEnabled = shouldEnable; @@ -1431,7 +1428,7 @@ public: if (newBounds != oldBounds) { auto& displays = Desktop::getInstance().getDisplays(); - auto& mainDisplay = displays.getMainDisplay(); + auto& mainDisplay = *displays.getPrimaryDisplay(); Rectangle<int> userArea = newBounds / mainDisplay.scale; diff --git a/modules/juce_gui_basics/native/juce_common_MimeTypes.cpp b/modules/juce_gui_basics/native/juce_common_MimeTypes.cpp index c4ba4610..3a3f017d 100644 --- a/modules/juce_gui_basics/native/juce_common_MimeTypes.cpp +++ b/modules/juce_gui_basics/native/juce_common_MimeTypes.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -45,48 +44,6 @@ static StringArray getMimeTypesForFileExtension (const String& fileExtension) return result; } -static StringArray filterMimeTypes (const StringArray& mimeTypes, const String& filter) -{ - String filterToUse (filter.removeCharacters ("*")); - - if (filterToUse.isEmpty() || filterToUse == "/") - return mimeTypes; - - StringArray result; - - for (const auto& type : mimeTypes) - if (String (type).contains (filterToUse)) - result.add (type); - - return result; -} - -static String getCommonMimeType (const StringArray& mimeTypes) -{ - if (mimeTypes.isEmpty()) - return "*/*"; - - auto commonMime = mimeTypes[0]; - bool lookForCommonGroup = false; - - for (int i = 1; i < mimeTypes.size(); ++i) - { - if (mimeTypes[i] == commonMime) - continue; - - if (! lookForCommonGroup) - { - lookForCommonGroup = true; - commonMime = commonMime.upToFirstOccurrenceOf ("/", true, false); - } - - if (! mimeTypes[i].startsWith (commonMime)) - return "*/*"; - } - - return lookForCommonGroup ? commonMime + "*" : commonMime; -} - //============================================================================== MimeTypeTableEntry MimeTypeTableEntry::table[641] = { diff --git a/modules/juce_gui_basics/native/juce_ios_ContentSharer.cpp b/modules/juce_gui_basics/native/juce_ios_ContentSharer.cpp index f9c26a0d..8aa6603c 100644 --- a/modules/juce_gui_basics/native/juce_ios_ContentSharer.cpp +++ b/modules/juce_gui_basics/native/juce_ios_ContentSharer.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -121,10 +120,11 @@ private: controller.get().modalTransitionStyle = UIModalTransitionStyleCoverVertical; - auto bounds = Desktop::getInstance().getDisplays().getMainDisplay().userArea; + auto bounds = Desktop::getInstance().getDisplays().getPrimaryDisplay()->userArea; setBounds (bounds); setAlwaysOnTop (true); + setVisible (true); addToDesktop (0); enterModalState (true, diff --git a/modules/juce_gui_basics/native/juce_ios_FileChooser.mm b/modules/juce_gui_basics/native/juce_ios_FileChooser.mm index ed481968..542db4c5 100644 --- a/modules/juce_gui_basics/native/juce_ios_FileChooser.mm +++ b/modules/juce_gui_basics/native/juce_ios_FileChooser.mm @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -27,19 +26,27 @@ namespace juce { -class FileChooser::Native : private Component, - public FileChooser::Pimpl +#if ! (defined (__IPHONE_15_0) && __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_15_0) + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wdeprecated-declarations") + #define JUCE_DEPRECATION_IGNORED 1 +#endif + +class FileChooser::Native : public FileChooser::Pimpl, + public Component, + private AsyncUpdater { public: Native (FileChooser& fileChooser, int flags) : owner (fileChooser) { - String firstFileExtension; - - static FileChooserDelegateClass cls; - delegate.reset ([cls.createInstance() init]); + static FileChooserDelegateClass delegateClass; + delegate.reset ([delegateClass.createInstance() init]); FileChooserDelegateClass::setOwner (delegate.get(), this); + static FileChooserControllerClass controllerClass; + auto* controllerClassInstance = controllerClass.createInstance(); + + String firstFileExtension; auto utTypeArray = createNSArrayFromStringArray (getUTTypesForWildcards (owner.filters, firstFileExtension)); if ((flags & FileBrowserComponent::saveMode) != 0) @@ -70,47 +77,51 @@ public: } auto url = [[NSURL alloc] initFileURLWithPath: juceStringToNS (currentFileOrDirectory.getFullPathName())]; - controller.reset ([[UIDocumentPickerViewController alloc] initWithURL: url - inMode: pickerMode]); + + controller.reset ([controllerClassInstance initWithURL: url + inMode: pickerMode]); + [url release]; } else { - controller.reset ([[UIDocumentPickerViewController alloc] initWithDocumentTypes: utTypeArray - inMode: UIDocumentPickerModeOpen]); + controller.reset ([controllerClassInstance initWithDocumentTypes: utTypeArray + inMode: UIDocumentPickerModeOpen]); } + FileChooserControllerClass::setOwner (controller.get(), this); + [controller.get() setDelegate: delegate.get()]; [controller.get() setModalTransitionStyle: UIModalTransitionStyleCrossDissolve]; setOpaque (false); - if (SystemStats::isRunningInAppExtensionSandbox()) + if (fileChooser.parent != nullptr) { - if (fileChooser.parent != nullptr) - { - [controller.get() setModalPresentationStyle:UIModalPresentationFullScreen]; + [controller.get() setModalPresentationStyle: UIModalPresentationFullScreen]; - auto chooserBounds = fileChooser.parent->getBounds(); - setBounds (chooserBounds); + auto chooserBounds = fileChooser.parent->getBounds(); + setBounds (chooserBounds); - setAlwaysOnTop (true); - fileChooser.parent->addAndMakeVisible (this); - } - else + setAlwaysOnTop (true); + fileChooser.parent->addAndMakeVisible (this); + } + else + { + if (SystemStats::isRunningInAppExtensionSandbox()) { // Opening a native top-level window in an AUv3 is not allowed (sandboxing). You need to specify a // parent component (for example your editor) to parent the native file chooser window. To do this // specify a parent component in the FileChooser's constructor! - jassert (fileChooser.parent != nullptr); + jassertfalse; + return; } - } - else - { - auto chooserBounds = Desktop::getInstance().getDisplays().getMainDisplay().userArea; + + auto chooserBounds = Desktop::getInstance().getDisplays().getPrimaryDisplay()->userArea; setBounds (chooserBounds); setAlwaysOnTop (true); + setVisible (true); addToDesktop (0); } } @@ -132,8 +143,6 @@ public: #endif } -private: - //============================================================================== void parentHierarchyChanged() override { auto* newPeer = dynamic_cast<UIViewComponentPeer*> (getPeer()); @@ -142,11 +151,23 @@ private: { peer = newPeer; - if (auto* parentController = peer->controller) - [parentController showViewController: controller.get() sender: parentController]; + if (peer != nullptr) + { + if (auto* parentController = peer->controller) + [parentController showViewController: controller.get() sender: parentController]; + + peer->toFront (false); + } } } +private: + //============================================================================== + void handleAsyncUpdate() override + { + pickerWasCancelled(); + } + //============================================================================== static StringArray getUTTypesForWildcards (const String& filterWildcards, String& firstExtension) { @@ -183,7 +204,9 @@ private: } } else + { result.add ("public.data"); + } return result; } @@ -208,6 +231,8 @@ private: //============================================================================== void didPickDocumentAtURL (NSURL* url) { + cancelPendingUpdate(); + bool isWriting = controller.get().documentPickerMode == UIDocumentPickerModeExportToService | controller.get().documentPickerMode == UIDocumentPickerModeMoveToService; @@ -219,7 +244,7 @@ private: NSArray<NSFileAccessIntent*>* intents = @[fileAccessIntent]; - auto fileCoordinator = [[NSFileCoordinator alloc] initWithFilePresenter: nil]; + auto fileCoordinator = [[[NSFileCoordinator alloc] initWithFilePresenter: nil] autorelease]; [fileCoordinator coordinateAccessWithIntents: intents queue: [NSOperationQueue mainQueue] byAccessor: ^(NSError* err) { @@ -268,9 +293,9 @@ private: void pickerWasCancelled() { - Array<URL> chooserResults; + cancelPendingUpdate(); - owner.finished (chooserResults); + owner.finished ({}); exitModalState (0); } @@ -295,21 +320,40 @@ private: //============================================================================== static void didPickDocumentAtURL (id self, SEL, UIDocumentPickerViewController*, NSURL* url) { - auto picker = getOwner (self); - - if (picker != nullptr) + if (auto* picker = getOwner (self)) picker->didPickDocumentAtURL (url); } static void documentPickerWasCancelled (id self, SEL, UIDocumentPickerViewController*) { - auto picker = getOwner (self); - - if (picker != nullptr) + if (auto* picker = getOwner (self)) picker->pickerWasCancelled(); } }; + struct FileChooserControllerClass : public ObjCClass<UIDocumentPickerViewController> + { + FileChooserControllerClass() : ObjCClass<UIDocumentPickerViewController> ("FileChooserController_") + { + addIvar<Native*> ("owner"); + addMethod (@selector (viewDidDisappear:), viewDidDisappear, "v@:@c"); + + registerClass(); + } + + static void setOwner (id self, Native* owner) { object_setInstanceVariable (self, "owner", owner); } + static Native* getOwner (id self) { return getIvar<Native*> (self, "owner"); } + + //============================================================================== + static void viewDidDisappear (id self, SEL, BOOL animated) + { + sendSuperclassMessage<void> (self, @selector (viewDidDisappear:), animated); + + if (auto* picker = getOwner (self)) + picker->triggerAsyncUpdate(); + } + }; + //============================================================================== FileChooser& owner; std::unique_ptr<NSObject<UIDocumentPickerDelegate>, NSObjectDeleter> delegate; @@ -317,6 +361,7 @@ private: UIViewComponentPeer* peer = nullptr; static FileChooserDelegateClass fileChooserDelegateClass; + static FileChooserControllerClass fileChooserControllerClass; //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Native) @@ -338,4 +383,10 @@ FileChooser::Pimpl* FileChooser::showPlatformDialog (FileChooser& owner, int fla return new FileChooser::Native (owner, flags); } +#if JUCE_DEPRECATION_IGNORED + JUCE_END_IGNORE_WARNINGS_GCC_LIKE +#endif + +#undef JUCE_DEPRECATION_IGNORED + } // namespace juce diff --git a/modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm b/modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm index e15f423b..1daab29f 100644 --- a/modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm +++ b/modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -29,12 +28,15 @@ namespace juce class UIViewComponentPeer; -// The way rotation works changed in iOS8.. -static bool isUsingOldRotationMethod() noexcept +static UIInterfaceOrientation getWindowOrientation() { - static bool isPreV8 = ([[[UIDevice currentDevice] systemVersion] compare: @"8.0" - options: NSNumericSearch] == NSOrderedAscending); - return isPreV8; + UIApplication* sharedApplication = [UIApplication sharedApplication]; + + #if (defined (__IPHONE_13_0) && __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_13_0) + return [[[[sharedApplication windows] firstObject] windowScene] interfaceOrientation]; + #else + return [sharedApplication statusBarOrientation]; + #endif } namespace Orientations @@ -47,6 +49,7 @@ namespace Orientations case UIInterfaceOrientationPortraitUpsideDown: return Desktop::upsideDown; case UIInterfaceOrientationLandscapeLeft: return Desktop::rotatedClockwise; case UIInterfaceOrientationLandscapeRight: return Desktop::rotatedAntiClockwise; + case UIInterfaceOrientationUnknown: default: jassertfalse; // unknown orientation! } @@ -61,32 +64,18 @@ namespace Orientations case Desktop::upsideDown: return UIInterfaceOrientationPortraitUpsideDown; case Desktop::rotatedClockwise: return UIInterfaceOrientationLandscapeLeft; case Desktop::rotatedAntiClockwise: return UIInterfaceOrientationLandscapeRight; + case Desktop::allOrientations: default: jassertfalse; // unknown orientation! } return UIInterfaceOrientationPortrait; } - static CGAffineTransform getCGTransformFor (const Desktop::DisplayOrientation orientation) noexcept - { - if (isUsingOldRotationMethod()) - { - switch (orientation) - { - case Desktop::upsideDown: return CGAffineTransformMake (-1, 0, 0, -1, 0, 0); - case Desktop::rotatedClockwise: return CGAffineTransformMake (0, -1, 1, 0, 0, 0); - case Desktop::rotatedAntiClockwise: return CGAffineTransformMake (0, 1, -1, 0, 0, 0); - default: break; - } - } - - return CGAffineTransformIdentity; - } static NSUInteger getSupportedOrientations() { NSUInteger allowed = 0; - Desktop& d = Desktop::getInstance(); + auto& d = Desktop::getInstance(); if (d.isOrientationEnabled (Desktop::upright)) allowed |= UIInterfaceOrientationMaskPortrait; if (d.isOrientationEnabled (Desktop::upsideDown)) allowed |= UIInterfaceOrientationMaskPortraitUpsideDown; @@ -97,6 +86,23 @@ namespace Orientations } } +struct AsyncBoundsUpdater : public AsyncUpdater +{ + AsyncBoundsUpdater (UIViewController* vc) + : viewController (vc) + { + } + + ~AsyncBoundsUpdater() override + { + cancelPendingUpdate(); + } + + void handleAsyncUpdate() override; + + UIViewController* viewController; +}; + //============================================================================== } // namespace juce @@ -130,8 +136,12 @@ using namespace juce; //============================================================================== @interface JuceUIViewController : UIViewController { +@public + std::unique_ptr<AsyncBoundsUpdater> boundsUpdater; } +- (JuceUIViewController*) init; + - (NSUInteger) supportedInterfaceOrientations; - (BOOL) shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation) interfaceOrientation; - (void) willRotateToInterfaceOrientation: (UIInterfaceOrientation) toInterfaceOrientation duration: (NSTimeInterval) duration; @@ -165,12 +175,10 @@ namespace juce struct UIViewPeerControllerReceiver { - virtual ~UIViewPeerControllerReceiver(); + virtual ~UIViewPeerControllerReceiver() = default; virtual void setViewController (UIViewController*) = 0; }; -UIViewPeerControllerReceiver::~UIViewPeerControllerReceiver() {} - class UIViewComponentPeer : public ComponentPeer, public FocusChangeListener, public UIViewPeerControllerReceiver @@ -194,8 +202,8 @@ public: Rectangle<int> getBounds() const override { return getBounds (! isSharedWindow); } Rectangle<int> getBounds (bool global) const; Point<float> localToGlobal (Point<float> relativePosition) override; - using ComponentPeer::localToGlobal; Point<float> globalToLocal (Point<float> screenPosition) override; + using ComponentPeer::localToGlobal; using ComponentPeer::globalToLocal; void setAlpha (float newAlpha) override; void setMinimised (bool) override {} @@ -224,7 +232,7 @@ public: void updateHiddenTextContent (TextInputTarget*); void globalFocusChanged (Component*) override; - void updateTransformAndScreenBounds(); + void updateScreenBounds(); void handleTouches (UIEvent*, bool isDown, bool isUp, bool isCancel); @@ -233,10 +241,11 @@ public: void performAnyPendingRepaintsNow() override; //============================================================================== - UIWindow* window; - JuceUIView* view; - UIViewController* controller; - bool isSharedWindow, fullScreen, insideDrawRect, isAppex; + UIWindow* window = nil; + JuceUIView* view = nil; + UIViewController* controller = nil; + const bool isSharedWindow, isAppex; + bool fullScreen = false, insideDrawRect = false; static int64 getMouseTime (UIEvent* e) noexcept { @@ -244,71 +253,10 @@ public: + (int64) ([e timestamp] * 1000.0); } - static Rectangle<int> rotatedScreenPosToReal (const Rectangle<int>& r) - { - if (! SystemStats::isRunningInAppExtensionSandbox() && isUsingOldRotationMethod()) - { - const Rectangle<int> screen (convertToRectInt ([UIScreen mainScreen].bounds)); - - switch ([[UIApplication sharedApplication] statusBarOrientation]) - { - case UIInterfaceOrientationPortrait: - return r; - - case UIInterfaceOrientationPortraitUpsideDown: - return Rectangle<int> (screen.getWidth() - r.getRight(), screen.getHeight() - r.getBottom(), - r.getWidth(), r.getHeight()); - - case UIInterfaceOrientationLandscapeLeft: - return Rectangle<int> (r.getY(), screen.getHeight() - r.getRight(), - r.getHeight(), r.getWidth()); - - case UIInterfaceOrientationLandscapeRight: - return Rectangle<int> (screen.getWidth() - r.getBottom(), r.getX(), - r.getHeight(), r.getWidth()); - - default: jassertfalse; // unknown orientation! - } - } - - return r; - } - - static Rectangle<int> realScreenPosToRotated (const Rectangle<int>& r) - { - if (! SystemStats::isRunningInAppExtensionSandbox() && isUsingOldRotationMethod()) - { - const Rectangle<int> screen (convertToRectInt ([UIScreen mainScreen].bounds)); - - switch ([[UIApplication sharedApplication] statusBarOrientation]) - { - case UIInterfaceOrientationPortrait: - return r; - - case UIInterfaceOrientationPortraitUpsideDown: - return Rectangle<int> (screen.getWidth() - r.getRight(), screen.getHeight() - r.getBottom(), - r.getWidth(), r.getHeight()); - - case UIInterfaceOrientationLandscapeLeft: - return Rectangle<int> (screen.getHeight() - r.getBottom(), r.getX(), - r.getHeight(), r.getWidth()); - - case UIInterfaceOrientationLandscapeRight: - return Rectangle<int> (r.getY(), screen.getWidth() - r.getRight(), - r.getHeight(), r.getWidth()); - - default: jassertfalse; // unknown orientation! - } - } - - return r; - } - static MultiTouchMapper<UITouch*> currentTouches; private: - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (UIViewComponentPeer) - + //============================================================================== class AsyncRepaintMessage : public CallbackMessage { public: @@ -326,6 +274,9 @@ private: peer->repaint (rect); } }; + + //============================================================================== + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (UIViewComponentPeer) }; static void sendScreenBoundsUpdate (JuceUIViewController* c) @@ -333,7 +284,12 @@ static void sendScreenBoundsUpdate (JuceUIViewController* c) JuceUIView* juceView = (JuceUIView*) [c view]; if (juceView != nil && juceView->owner != nullptr) - juceView->owner->updateTransformAndScreenBounds(); + juceView->owner->updateScreenBounds(); +} + +void AsyncBoundsUpdater::handleAsyncUpdate() +{ + sendScreenBoundsUpdate ((JuceUIViewController*) viewController); } static bool isKioskModeView (JuceUIViewController* c) @@ -352,6 +308,15 @@ MultiTouchMapper<UITouch*> UIViewComponentPeer::currentTouches; //============================================================================== @implementation JuceUIViewController +- (JuceUIViewController*) init +{ + self = [super init]; + + boundsUpdater = std::make_unique<AsyncBoundsUpdater> (self); + + return self; +} + - (NSUInteger) supportedInterfaceOrientations { return Orientations::getSupportedOrientations(); @@ -384,7 +349,8 @@ MultiTouchMapper<UITouch*> UIViewComponentPeer::currentTouches; // On some devices the screen-size isn't yet updated at this point, so also trigger another // async update to double-check.. - MessageManager::callAsync ([=] { sendScreenBoundsUpdate (self); }); + if (boundsUpdater != nullptr) + boundsUpdater->triggerAsyncUpdate(); } - (BOOL) prefersStatusBarHidden @@ -562,14 +528,9 @@ bool KeyPress::isKeyCurrentlyDown (int) Point<float> juce_lastMousePos; //============================================================================== -UIViewComponentPeer::UIViewComponentPeer (Component& comp, const int windowStyleFlags, UIView* viewToAttachTo) +UIViewComponentPeer::UIViewComponentPeer (Component& comp, int windowStyleFlags, UIView* viewToAttachTo) : ComponentPeer (comp, windowStyleFlags), - window (nil), - view (nil), - controller (nil), isSharedWindow (viewToAttachTo != nil), - fullScreen (false), - insideDrawRect (false), isAppex (SystemStats::isRunningInAppExtensionSandbox()) { CGRect r = convertToCGRect (component.getBounds()); @@ -580,7 +541,6 @@ UIViewComponentPeer::UIViewComponentPeer (Component& comp, const int windowStyle view.hidden = true; view.opaque = component.isOpaque(); view.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent: 0]; - view.transform = CGAffineTransformIdentity; if (isSharedWindow) { @@ -589,7 +549,7 @@ UIViewComponentPeer::UIViewComponentPeer (Component& comp, const int windowStyle } else { - r = convertToCGRect (rotatedScreenPosToReal (component.getBounds())); + r = convertToCGRect (component.getBounds()); r.origin.y = [UIScreen mainScreen].bounds.size.height - (r.origin.y + r.size.height); window = [[JuceUIWindow alloc] initWithFrame: r]; @@ -600,7 +560,6 @@ UIViewComponentPeer::UIViewComponentPeer (Component& comp, const int windowStyle window.rootViewController = controller; window.hidden = true; - window.transform = Orientations::getCGTransformFor (Desktop::getInstance().getCurrentOrientation()); window.opaque = component.isOpaque(); window.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent: 0]; @@ -608,8 +567,6 @@ UIViewComponentPeer::UIViewComponentPeer (Component& comp, const int windowStyle window.windowLevel = UIWindowLevelAlert; view.frame = CGRectMake (0, 0, r.size.width, r.size.height); - - [window addSubview: view]; } setTitle (component.getName()); @@ -623,6 +580,8 @@ UIViewComponentPeer::~UIViewComponentPeer() currentTouches.deleteAllTouchesForPeer (this); Desktop::getInstance().removeFocusChangeListener (this); + ((JuceUIViewController*) controller)->boundsUpdater = nullptr; + view->owner = nullptr; [view removeFromSuperview]; [view release]; @@ -664,7 +623,7 @@ void UIViewComponentPeer::setBounds (const Rectangle<int>& newBounds, const bool } else { - window.frame = convertToCGRect (rotatedScreenPosToReal (newBounds)); + window.frame = convertToCGRect (newBounds); view.frame = CGRectMake (0, 0, (CGFloat) newBounds.getWidth(), (CGFloat) newBounds.getHeight()); handleMovedOrResized(); @@ -673,14 +632,20 @@ void UIViewComponentPeer::setBounds (const Rectangle<int>& newBounds, const bool Rectangle<int> UIViewComponentPeer::getBounds (const bool global) const { - CGRect r = view.frame; + auto r = view.frame; - if (global && view.window != nil) + if (global) { - r = [view convertRect: r toView: view.window]; - r = [view.window convertRect: r toWindow: nil]; - - return realScreenPosToRotated (convertToRectInt (r)); + if (view.window != nil) + { + r = [view convertRect: r toView: view.window]; + r = [view.window convertRect: r toWindow: nil]; + } + else if (window != nil) + { + r.origin.x += window.frame.origin.x; + r.origin.y += window.frame.origin.y; + } } return convertToRectInt (r); @@ -705,8 +670,8 @@ void UIViewComponentPeer::setFullScreen (bool shouldBeFullScreen) { if (! isSharedWindow) { - Rectangle<int> r (shouldBeFullScreen ? Desktop::getInstance().getDisplays().getMainDisplay().userArea - : lastNonFullscreenBounds); + auto r = shouldBeFullScreen ? Desktop::getInstance().getDisplays().getPrimaryDisplay()->userArea + : lastNonFullscreenBounds; if ((! shouldBeFullScreen) && r.isEmpty()) r = getBounds(); @@ -719,16 +684,14 @@ void UIViewComponentPeer::setFullScreen (bool shouldBeFullScreen) } } -void UIViewComponentPeer::updateTransformAndScreenBounds() +void UIViewComponentPeer::updateScreenBounds() { - Desktop& desktop = Desktop::getInstance(); - const Rectangle<int> oldArea (component.getBounds()); - const Rectangle<int> oldDesktop (desktop.getDisplays().getMainDisplay().userArea); + auto& desktop = Desktop::getInstance(); - const_cast<Displays&> (desktop.getDisplays()).refresh(); + auto oldArea = component.getBounds(); + auto oldDesktop = desktop.getDisplays().getPrimaryDisplay()->userArea; - window.transform = Orientations::getCGTransformFor (desktop.getCurrentOrientation()); - view.transform = CGAffineTransformIdentity; + const_cast<Displays&> (desktop.getDisplays()).refresh(); if (fullScreen) { @@ -738,13 +701,13 @@ void UIViewComponentPeer::updateTransformAndScreenBounds() else if (! isSharedWindow) { // this will re-centre the window, but leave its size unchanged - const float centreRelX = oldArea.getCentreX() / (float) oldDesktop.getWidth(); - const float centreRelY = oldArea.getCentreY() / (float) oldDesktop.getHeight(); + auto centreRelX = oldArea.getCentreX() / (float) oldDesktop.getWidth(); + auto centreRelY = oldArea.getCentreY() / (float) oldDesktop.getHeight(); - const Rectangle<int> newDesktop (desktop.getDisplays().getMainDisplay().userArea); + auto newDesktop = desktop.getDisplays().getPrimaryDisplay()->userArea; - const int x = ((int) (newDesktop.getWidth() * centreRelX)) - (oldArea.getWidth() / 2); - const int y = ((int) (newDesktop.getHeight() * centreRelY)) - (oldArea.getHeight() / 2); + auto x = ((int) (newDesktop.getWidth() * centreRelX)) - (oldArea.getWidth() / 2); + auto y = ((int) (newDesktop.getHeight() * centreRelY)) - (oldArea.getHeight() / 2); component.setBounds (oldArea.withPosition (x, y)); } @@ -754,13 +717,8 @@ void UIViewComponentPeer::updateTransformAndScreenBounds() bool UIViewComponentPeer::contains (Point<int> localPos, bool trueIfInAChildWindow) const { - { - Rectangle<int> localBounds = - ScalingHelpers::scaledScreenPosToUnscaled (component, component.getLocalBounds()); - - if (! localBounds.contains (localPos)) - return false; - } + if (! ScalingHelpers::scaledScreenPosToUnscaled (component, component.getLocalBounds()).contains (localPos)) + return false; UIView* v = [view hitTest: convertToCGPoint (localPos) withEvent: nil]; @@ -790,16 +748,10 @@ void UIViewComponentPeer::toFront (bool makeActiveWindow) void UIViewComponentPeer::toBehind (ComponentPeer* other) { - if (UIViewComponentPeer* const otherPeer = dynamic_cast<UIViewComponentPeer*> (other)) + if (auto* otherPeer = dynamic_cast<UIViewComponentPeer*> (other)) { if (isSharedWindow) - { [[view superview] insertSubview: view belowSubview: otherPeer->view]; - } - else - { - // don't know how to do this - } } else { @@ -815,23 +767,17 @@ void UIViewComponentPeer::setIcon (const Image& /*newIcon*/) //============================================================================== static float getMaximumTouchForce (UITouch* touch) noexcept { - #if defined (__IPHONE_9_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_9_0 if ([touch respondsToSelector: @selector (maximumPossibleForce)]) return (float) touch.maximumPossibleForce; - #endif - ignoreUnused (touch); return 0.0f; } static float getTouchForce (UITouch* touch) noexcept { - #if defined (__IPHONE_9_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_9_0 if ([touch respondsToSelector: @selector (force)]) return (float) touch.force; - #endif - ignoreUnused (touch); return 0.0f; } @@ -842,19 +788,19 @@ void UIViewComponentPeer::handleTouches (UIEvent* event, const bool isDown, cons for (unsigned int i = 0; i < [touches count]; ++i) { UITouch* touch = [touches objectAtIndex: i]; - const float maximumForce = getMaximumTouchForce (touch); + auto maximumForce = getMaximumTouchForce (touch); if ([touch phase] == UITouchPhaseStationary && maximumForce <= 0) continue; CGPoint p = [touch locationInView: view]; - const Point<float> pos (static_cast<float> (p.x), static_cast<float> (p.y)); + Point<float> pos ((float) p.x, (float) p.y); juce_lastMousePos = pos + getBounds (true).getPosition().toFloat(); - const int64 time = getMouseTime (event); - const int touchIndex = currentTouches.getIndexOfTouch (this, touch); + auto time = getMouseTime (event); + auto touchIndex = currentTouches.getIndexOfTouch (this, touch); - ModifierKeys modsToSend (ModifierKeys::currentModifiers); + auto modsToSend = ModifierKeys::currentModifiers; if (isDown) { @@ -890,8 +836,8 @@ void UIViewComponentPeer::handleTouches (UIEvent* event, const bool isDown, cons } // NB: some devices return 0 or 1.0 if pressure is unknown, so we'll clip our value to a believable range: - float pressure = maximumForce > 0 ? jlimit (0.0001f, 0.9999f, getTouchForce (touch) / maximumForce) - : MouseInputSource::invalidPressure; + auto pressure = maximumForce > 0 ? jlimit (0.0001f, 0.9999f, getTouchForce (touch) / maximumForce) + : MouseInputSource::invalidPressure; handleMouseEvent (MouseInputSource::InputSourceType::touch, pos, modsToSend, pressure, MouseInputSource::invalidOrientation, time, { }, touchIndex); @@ -957,18 +903,13 @@ void UIViewComponentPeer::textInputRequired (Point<int>, TextInputTarget&) { } -static bool isIOS4_1() noexcept -{ - return [[[UIDevice currentDevice] systemVersion] doubleValue] >= 4.1; -} - static UIKeyboardType getUIKeyboardType (TextInputTarget::VirtualKeyboardType type) noexcept { switch (type) { case TextInputTarget::textKeyboard: return UIKeyboardTypeAlphabet; - case TextInputTarget::numericKeyboard: return isIOS4_1() ? UIKeyboardTypeNumberPad : UIKeyboardTypeNumbersAndPunctuation; - case TextInputTarget::decimalKeyboard: return isIOS4_1() ? UIKeyboardTypeDecimalPad : UIKeyboardTypeNumbersAndPunctuation; + case TextInputTarget::numericKeyboard: return UIKeyboardTypeNumbersAndPunctuation; + case TextInputTarget::decimalKeyboard: return UIKeyboardTypeNumbersAndPunctuation; case TextInputTarget::urlKeyboard: return UIKeyboardTypeURL; case TextInputTarget::emailAddressKeyboard: return UIKeyboardTypeEmailAddress; case TextInputTarget::phoneNumberKeyboard: return UIKeyboardTypePhonePad; @@ -987,9 +928,9 @@ void UIViewComponentPeer::updateHiddenTextContent (TextInputTarget* target) BOOL UIViewComponentPeer::textViewReplaceCharacters (Range<int> range, const String& text) { - if (TextInputTarget* const target = findCurrentTextInputTarget()) + if (auto* target = findCurrentTextInputTarget()) { - const Range<int> currentSelection (target->getHighlightedRegion()); + auto currentSelection = target->getHighlightedRegion(); if (range.getLength() == 1 && text.isEmpty()) // (detect backspace) if (currentSelection.isEmpty()) @@ -1008,15 +949,16 @@ BOOL UIViewComponentPeer::textViewReplaceCharacters (Range<int> range, const Str void UIViewComponentPeer::globalFocusChanged (Component*) { - if (TextInputTarget* const target = findCurrentTextInputTarget()) + if (auto* target = findCurrentTextInputTarget()) { - Component* comp = dynamic_cast<Component*> (target); - - Point<int> pos (component.getLocalPoint (comp, Point<int>())); - view->hiddenTextView.frame = CGRectMake (pos.x, pos.y, 0, 0); + if (auto* comp = dynamic_cast<Component*> (target)) + { + auto pos = component.getLocalPoint (comp, Point<int>()); + view->hiddenTextView.frame = CGRectMake (pos.x, pos.y, 0, 0); - updateHiddenTextContent (target); - [view->hiddenTextView becomeFirstResponder]; + updateHiddenTextContent (target); + [view->hiddenTextView becomeFirstResponder]; + } } else { @@ -1024,7 +966,6 @@ void UIViewComponentPeer::globalFocusChanged (Component*) } } - //============================================================================== void UIViewComponentPeer::drawRect (CGRect r) { @@ -1037,10 +978,7 @@ void UIViewComponentPeer::drawRect (CGRect r) CGContextClearRect (cg, CGContextGetClipBoundingBox (cg)); CGContextConcatCTM (cg, CGAffineTransformMake (1, 0, 0, -1, 0, getComponent().getHeight())); - - // NB the CTM on iOS already includes a factor for the display scale, so - // we'll tell the context that the scale is 1.0 to avoid it using it twice - CoreGraphicsContext g (cg, getComponent().getHeight(), 1.0f); + CoreGraphicsContext g (cg, getComponent().getHeight()); insideDrawRect = true; handlePaint (g); @@ -1057,9 +995,9 @@ void Desktop::setKioskComponent (Component* kioskModeComp, bool enableOrDisable, { displays->refresh(); - if (ComponentPeer* peer = kioskModeComp->getPeer()) + if (auto* peer = kioskModeComp->getPeer()) { - if (UIViewComponentPeer* uiViewPeer = dynamic_cast<UIViewComponentPeer*> (peer)) + if (auto* uiViewPeer = dynamic_cast<UIViewComponentPeer*> (peer)) [uiViewPeer->controller setNeedsStatusBarAppearanceUpdate]; peer->setFullScreen (enableOrDisable); @@ -1071,21 +1009,18 @@ void Desktop::allowedOrientationsChanged() // if the current orientation isn't allowed anymore then switch orientations if (! isOrientationEnabled (getCurrentOrientation())) { - DisplayOrientation orientations[] = { upright, upsideDown, rotatedClockwise, rotatedAntiClockwise }; - - const int n = sizeof (orientations) / sizeof (DisplayOrientation); - int i; - - for (i = 0; i < n; ++i) - if (isOrientationEnabled (orientations[i])) - break; - + auto newOrientation = [this] + { + for (auto orientation : { upright, upsideDown, rotatedClockwise, rotatedAntiClockwise }) + if (isOrientationEnabled (orientation)) + return orientation; - // you need to support at least one orientation - jassert (i < n); - i = jmin (n - 1, i); + // you need to support at least one orientation + jassertfalse; + return upright; + }(); - NSNumber *value = [NSNumber numberWithInt: (int) Orientations::convertFromJuce (orientations[i])]; + NSNumber* value = [NSNumber numberWithInt: (int) Orientations::convertFromJuce (newOrientation)]; [[UIDevice currentDevice] setValue:value forKey:@"orientation"]; [value release]; } @@ -1110,77 +1045,77 @@ ComponentPeer* Component::createNewPeer (int styleFlags, void* windowToAttachTo) } //============================================================================== -const int KeyPress::spaceKey = ' '; -const int KeyPress::returnKey = 0x0d; -const int KeyPress::escapeKey = 0x1b; -const int KeyPress::backspaceKey = 0x7f; -const int KeyPress::leftKey = 0x1000; -const int KeyPress::rightKey = 0x1001; -const int KeyPress::upKey = 0x1002; -const int KeyPress::downKey = 0x1003; -const int KeyPress::pageUpKey = 0x1004; -const int KeyPress::pageDownKey = 0x1005; -const int KeyPress::endKey = 0x1006; -const int KeyPress::homeKey = 0x1007; -const int KeyPress::deleteKey = 0x1008; -const int KeyPress::insertKey = -1; -const int KeyPress::tabKey = 9; -const int KeyPress::F1Key = 0x2001; -const int KeyPress::F2Key = 0x2002; -const int KeyPress::F3Key = 0x2003; -const int KeyPress::F4Key = 0x2004; -const int KeyPress::F5Key = 0x2005; -const int KeyPress::F6Key = 0x2006; -const int KeyPress::F7Key = 0x2007; -const int KeyPress::F8Key = 0x2008; -const int KeyPress::F9Key = 0x2009; -const int KeyPress::F10Key = 0x200a; -const int KeyPress::F11Key = 0x200b; -const int KeyPress::F12Key = 0x200c; -const int KeyPress::F13Key = 0x200d; -const int KeyPress::F14Key = 0x200e; -const int KeyPress::F15Key = 0x200f; -const int KeyPress::F16Key = 0x2010; -const int KeyPress::F17Key = 0x2011; -const int KeyPress::F18Key = 0x2012; -const int KeyPress::F19Key = 0x2013; -const int KeyPress::F20Key = 0x2014; -const int KeyPress::F21Key = 0x2015; -const int KeyPress::F22Key = 0x2016; -const int KeyPress::F23Key = 0x2017; -const int KeyPress::F24Key = 0x2018; -const int KeyPress::F25Key = 0x2019; -const int KeyPress::F26Key = 0x201a; -const int KeyPress::F27Key = 0x201b; -const int KeyPress::F28Key = 0x201c; -const int KeyPress::F29Key = 0x201d; -const int KeyPress::F30Key = 0x201e; -const int KeyPress::F31Key = 0x201f; -const int KeyPress::F32Key = 0x2020; -const int KeyPress::F33Key = 0x2021; -const int KeyPress::F34Key = 0x2022; -const int KeyPress::F35Key = 0x2023; -const int KeyPress::numberPad0 = 0x30020; -const int KeyPress::numberPad1 = 0x30021; -const int KeyPress::numberPad2 = 0x30022; -const int KeyPress::numberPad3 = 0x30023; -const int KeyPress::numberPad4 = 0x30024; -const int KeyPress::numberPad5 = 0x30025; -const int KeyPress::numberPad6 = 0x30026; -const int KeyPress::numberPad7 = 0x30027; -const int KeyPress::numberPad8 = 0x30028; -const int KeyPress::numberPad9 = 0x30029; -const int KeyPress::numberPadAdd = 0x3002a; -const int KeyPress::numberPadSubtract = 0x3002b; -const int KeyPress::numberPadMultiply = 0x3002c; -const int KeyPress::numberPadDivide = 0x3002d; -const int KeyPress::numberPadSeparator = 0x3002e; -const int KeyPress::numberPadDecimalPoint = 0x3002f; -const int KeyPress::numberPadEquals = 0x30030; -const int KeyPress::numberPadDelete = 0x30031; -const int KeyPress::playKey = 0x30000; -const int KeyPress::stopKey = 0x30001; -const int KeyPress::fastForwardKey = 0x30002; -const int KeyPress::rewindKey = 0x30003; +const int KeyPress::spaceKey = ' '; +const int KeyPress::returnKey = 0x0d; +const int KeyPress::escapeKey = 0x1b; +const int KeyPress::backspaceKey = 0x7f; +const int KeyPress::leftKey = 0x1000; +const int KeyPress::rightKey = 0x1001; +const int KeyPress::upKey = 0x1002; +const int KeyPress::downKey = 0x1003; +const int KeyPress::pageUpKey = 0x1004; +const int KeyPress::pageDownKey = 0x1005; +const int KeyPress::endKey = 0x1006; +const int KeyPress::homeKey = 0x1007; +const int KeyPress::deleteKey = 0x1008; +const int KeyPress::insertKey = -1; +const int KeyPress::tabKey = 9; +const int KeyPress::F1Key = 0x2001; +const int KeyPress::F2Key = 0x2002; +const int KeyPress::F3Key = 0x2003; +const int KeyPress::F4Key = 0x2004; +const int KeyPress::F5Key = 0x2005; +const int KeyPress::F6Key = 0x2006; +const int KeyPress::F7Key = 0x2007; +const int KeyPress::F8Key = 0x2008; +const int KeyPress::F9Key = 0x2009; +const int KeyPress::F10Key = 0x200a; +const int KeyPress::F11Key = 0x200b; +const int KeyPress::F12Key = 0x200c; +const int KeyPress::F13Key = 0x200d; +const int KeyPress::F14Key = 0x200e; +const int KeyPress::F15Key = 0x200f; +const int KeyPress::F16Key = 0x2010; +const int KeyPress::F17Key = 0x2011; +const int KeyPress::F18Key = 0x2012; +const int KeyPress::F19Key = 0x2013; +const int KeyPress::F20Key = 0x2014; +const int KeyPress::F21Key = 0x2015; +const int KeyPress::F22Key = 0x2016; +const int KeyPress::F23Key = 0x2017; +const int KeyPress::F24Key = 0x2018; +const int KeyPress::F25Key = 0x2019; +const int KeyPress::F26Key = 0x201a; +const int KeyPress::F27Key = 0x201b; +const int KeyPress::F28Key = 0x201c; +const int KeyPress::F29Key = 0x201d; +const int KeyPress::F30Key = 0x201e; +const int KeyPress::F31Key = 0x201f; +const int KeyPress::F32Key = 0x2020; +const int KeyPress::F33Key = 0x2021; +const int KeyPress::F34Key = 0x2022; +const int KeyPress::F35Key = 0x2023; +const int KeyPress::numberPad0 = 0x30020; +const int KeyPress::numberPad1 = 0x30021; +const int KeyPress::numberPad2 = 0x30022; +const int KeyPress::numberPad3 = 0x30023; +const int KeyPress::numberPad4 = 0x30024; +const int KeyPress::numberPad5 = 0x30025; +const int KeyPress::numberPad6 = 0x30026; +const int KeyPress::numberPad7 = 0x30027; +const int KeyPress::numberPad8 = 0x30028; +const int KeyPress::numberPad9 = 0x30029; +const int KeyPress::numberPadAdd = 0x3002a; +const int KeyPress::numberPadSubtract = 0x3002b; +const int KeyPress::numberPadMultiply = 0x3002c; +const int KeyPress::numberPadDivide = 0x3002d; +const int KeyPress::numberPadSeparator = 0x3002e; +const int KeyPress::numberPadDecimalPoint = 0x3002f; +const int KeyPress::numberPadEquals = 0x30030; +const int KeyPress::numberPadDelete = 0x30031; +const int KeyPress::playKey = 0x30000; +const int KeyPress::stopKey = 0x30001; +const int KeyPress::fastForwardKey = 0x30002; +const int KeyPress::rewindKey = 0x30003; } // namespace juce diff --git a/modules/juce_gui_basics/native/juce_ios_Windowing.mm b/modules/juce_gui_basics/native/juce_ios_Windowing.mm index c5f1bd69..82c9452f 100644 --- a/modules/juce_gui_basics/native/juce_ios_Windowing.mm +++ b/modules/juce_gui_basics/native/juce_ios_Windowing.mm @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -30,7 +29,7 @@ namespace juce struct AppInactivityCallback // NB: careful, this declaration is duplicated in other modules { - virtual ~AppInactivityCallback() {} + virtual ~AppInactivityCallback() = default; virtual void appBecomingInactive() = 0; }; @@ -435,30 +434,6 @@ void LookAndFeel::playAlertSound() } //============================================================================== -class iOSMessageBox; - -#if defined (__IPHONE_8_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_8_0 - #define JUCE_USE_NEW_IOS_ALERTWINDOW 1 -#endif - -#if ! JUCE_USE_NEW_IOS_ALERTWINDOW - } // (juce namespace) - - @interface JuceAlertBoxDelegate : NSObject <UIAlertViewDelegate> - { - @public - iOSMessageBox* owner; - } - - - (void) alertView: (UIAlertView*) alertView clickedButtonAtIndex: (NSInteger) buttonIndex; - - @end - - namespace juce - { -#endif - - class iOSMessageBox { public: @@ -467,7 +442,6 @@ public: ModalComponentManager::Callback* cb, const bool async) : result (0), resultReceived (false), callback (cb), isAsync (async) { - #if JUCE_USE_NEW_IOS_ALERTWINDOW if (currentlyFocusedPeer != nullptr) { UIAlertController* alert = [UIAlertController alertControllerWithTitle: juceStringToNS (title) @@ -487,27 +461,6 @@ public: // have at least one window on screen when you use this jassertfalse; } - - #else - delegate = [[JuceAlertBoxDelegate alloc] init]; - delegate->owner = this; - - alert = [[UIAlertView alloc] initWithTitle: juceStringToNS (title) - message: juceStringToNS (message) - delegate: delegate - cancelButtonTitle: button1 - otherButtonTitles: button2, button3, nil]; - [alert retain]; - [alert show]; - #endif - } - - ~iOSMessageBox() - { - #if ! JUCE_USE_NEW_IOS_ALERTWINDOW - [alert release]; - [delegate release]; - #endif } int getResult() @@ -516,11 +469,7 @@ public: JUCE_AUTORELEASEPOOL { - #if JUCE_USE_NEW_IOS_ALERTWINDOW while (! resultReceived) - #else - while (! (alert.hidden || resultReceived)) - #endif [[NSRunLoop mainRunLoop] runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.01]]; } @@ -545,7 +494,6 @@ private: std::unique_ptr<ModalComponentManager::Callback> callback; const bool isAsync; - #if JUCE_USE_NEW_IOS_ALERTWINDOW void addButton (UIAlertController* alert, NSString* text, int index) { if (text != nil) @@ -553,33 +501,10 @@ private: style: UIAlertActionStyleDefault handler: ^(UIAlertAction*) { this->buttonClicked (index); }]]; } - #else - UIAlertView* alert; - JuceAlertBoxDelegate* delegate; - #endif JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (iOSMessageBox) }; - -#if ! JUCE_USE_NEW_IOS_ALERTWINDOW - } // (juce namespace) - - @implementation JuceAlertBoxDelegate - - - (void) alertView: (UIAlertView*) alertView clickedButtonAtIndex: (NSInteger) buttonIndex - { - owner->buttonClicked ((int) buttonIndex); - alertView.hidden = true; - } - - @end - - namespace juce - { -#endif - - //============================================================================== #if JUCE_MODAL_LOOPS_PERMITTED void JUCE_CALLTYPE NativeMessageBox::showMessageBox (AlertWindow::AlertIconType /*iconType*/, @@ -731,7 +656,7 @@ double Desktop::getDefaultMasterScale() Desktop::DisplayOrientation Desktop::getCurrentOrientation() const { UIInterfaceOrientation orientation = SystemStats::isRunningInAppExtensionSandbox() ? UIInterfaceOrientationPortrait - : [[UIApplication sharedApplication] statusBarOrientation]; + : getWindowOrientation(); return Orientations::convertToJuce (orientation); } @@ -743,13 +668,9 @@ void Displays::findDisplays (float masterScale) UIScreen* s = [UIScreen mainScreen]; Display d; - d.userArea = d.totalArea = UIViewComponentPeer::realScreenPosToRotated (convertToRectInt ([s bounds])) / masterScale; + d.userArea = d.totalArea = convertToRectInt ([s bounds]) / masterScale; d.isMain = true; - d.scale = masterScale; - - if ([s respondsToSelector: @selector (scale)]) - d.scale *= s.scale; - + d.scale = masterScale * s.scale; d.dpi = 160 * d.scale; displays.add (d); diff --git a/modules/juce_gui_basics/native/juce_linux_FileChooser.cpp b/modules/juce_gui_basics/native/juce_linux_FileChooser.cpp index cc87e2e1..97327c59 100644 --- a/modules/juce_gui_basics/native/juce_linux_FileChooser.cpp +++ b/modules/juce_gui_basics/native/juce_linux_FileChooser.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -27,16 +26,18 @@ namespace juce { -static bool exeIsAvailable (const char* const executable) +static bool exeIsAvailable (String executable) { ChildProcess child; - const bool ok = child.start ("which " + String (executable)) - && child.readAllProcessOutput().trim().isNotEmpty(); - child.waitForProcessToFinish (60 * 1000); - return ok; -} + if (child.start ("which " + executable)) + { + child.waitForProcessToFinish (60 * 1000); + return (child.getExitCode() == 0); + } + return false; +} class FileChooser::Native : public FileChooser::Pimpl, private Timer @@ -68,7 +69,7 @@ public: child.start (args, ChildProcess::wantStdOut); while (child.isRunning()) - if (! MessageManager::getInstance()->runDispatchLoopUntil(20)) + if (! MessageManager::getInstance()->runDispatchLoopUntil (20)) break; finish (false); @@ -187,7 +188,7 @@ private: } args.add (startPath.getFullPathName()); - args.add (owner.filters.replaceCharacter (';', ' ')); + args.add ("(" + owner.filters.replaceCharacter (';', ' ') + ")"); } void addZenityArgs() @@ -218,8 +219,7 @@ private: StringArray tokens; tokens.addTokens (owner.filters, ";,|", "\""); - for (int i = 0; i < tokens.size(); ++i) - args.add ("--file-filter=" + tokens[i]); + args.add ("--file-filter=" + tokens.joinIntoString (" ")); } if (owner.startingFile.isDirectory()) diff --git a/modules/juce_gui_basics/native/juce_linux_Windowing.cpp b/modules/juce_gui_basics/native/juce_linux_Windowing.cpp new file mode 100644 index 00000000..11446731 --- /dev/null +++ b/modules/juce_gui_basics/native/juce_linux_Windowing.cpp @@ -0,0 +1,696 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ + +//============================================================================== +static int numAlwaysOnTopPeers = 0; +bool juce_areThereAnyAlwaysOnTopWindows() { return numAlwaysOnTopPeers > 0; } + +//============================================================================== +template<typename WindowHandleType> +class LinuxComponentPeer : public ComponentPeer +{ +public: + LinuxComponentPeer (Component& comp, int windowStyleFlags, WindowHandleType parentToAddTo) + : ComponentPeer (comp, windowStyleFlags), + isAlwaysOnTop (comp.isAlwaysOnTop()) + { + // it's dangerous to create a window on a thread other than the message thread.. + JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED + + if (isAlwaysOnTop) + ++numAlwaysOnTopPeers; + + repainter = std::make_unique<LinuxRepaintManager> (*this); + + windowH = XWindowSystem::getInstance()->createWindow (parentToAddTo, this); + parentWindow = parentToAddTo; + + setTitle (component.getName()); + + getNativeRealtimeModifiers = []() -> ModifierKeys { return XWindowSystem::getInstance()->getNativeRealtimeModifiers(); }; + } + + ~LinuxComponentPeer() override + { + // it's dangerous to delete a window on a thread other than the message thread.. + JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED + + repainter = nullptr; + XWindowSystem::getInstance()->destroyWindow (windowH); + + if (isAlwaysOnTop) + --numAlwaysOnTopPeers; + } + + //============================================================================== + void* getNativeHandle() const override + { + return (void*) windowH; + } + + //============================================================================== + void setBounds (const Rectangle<int>& newBounds, bool isNowFullScreen) override + { + bounds = newBounds.withSize (jmax (1, newBounds.getWidth()), + jmax (1, newBounds.getHeight())); + + updateScaleFactorFromNewBounds (bounds, false); + + auto physicalBounds = (parentWindow == 0 ? Desktop::getInstance().getDisplays().logicalToPhysical (bounds) + : bounds * currentScaleFactor); + + WeakReference<Component> deletionChecker (&component); + + XWindowSystem::getInstance()->setBounds (windowH, physicalBounds, isNowFullScreen); + + fullScreen = isNowFullScreen; + + if (deletionChecker != nullptr) + { + updateBorderSize(); + handleMovedOrResized(); + } + } + + Point<int> getScreenPosition (bool physical) const + { + auto parentPosition = XWindowSystem::getInstance()->getParentScreenPosition(); + + auto screenBounds = (parentWindow == 0 ? bounds + : bounds.translated (parentPosition.x, parentPosition.y)); + + if (physical) + return Desktop::getInstance().getDisplays().logicalToPhysical (screenBounds.getTopLeft()); + + return screenBounds.getTopLeft(); + } + + Rectangle<int> getBounds() const override + { + return bounds; + } + + BorderSize<int> getFrameSize() const override + { + return windowBorder; + } + + Point<float> localToGlobal (Point<float> relativePosition) override + { + return relativePosition + getScreenPosition (false).toFloat(); + } + + Point<float> globalToLocal (Point<float> screenPosition) override + { + return screenPosition - getScreenPosition (false).toFloat(); + } + + using ComponentPeer::localToGlobal; + using ComponentPeer::globalToLocal; + + //============================================================================== + StringArray getAvailableRenderingEngines() override + { + return { "Software Renderer" }; + } + + void setVisible (bool shouldBeVisible) override + { + XWindowSystem::getInstance()->setVisible (windowH, shouldBeVisible); + } + + void setTitle (const String& title) override + { + XWindowSystem::getInstance()->setTitle (windowH, title); + } + + void setMinimised (bool shouldBeMinimised) override + { + if (shouldBeMinimised) + XWindowSystem::getInstance()->setMinimised (windowH, shouldBeMinimised); + else + setVisible (true); + } + + bool isMinimised() const override + { + return XWindowSystem::getInstance()->isMinimised (windowH); + } + + void setFullScreen (bool shouldBeFullScreen) override + { + auto r = lastNonFullscreenBounds; // (get a copy of this before de-minimising) + + setMinimised (false); + + if (fullScreen != shouldBeFullScreen) + { + if (shouldBeFullScreen) + r = Desktop::getInstance().getDisplays().getPrimaryDisplay()->userArea; + + if (! r.isEmpty()) + setBounds (ScalingHelpers::scaledScreenPosToUnscaled (component, r), shouldBeFullScreen); + + component.repaint(); + } + } + + bool isFullScreen() const override + { + return fullScreen; + } + + bool contains (Point<int> localPos, bool trueIfInAChildWindow) const override + { + if (! bounds.withZeroOrigin().contains (localPos)) + return false; + + for (int i = Desktop::getInstance().getNumComponents(); --i >= 0;) + { + auto* c = Desktop::getInstance().getComponent (i); + + if (c == &component) + break; + + if (! c->isVisible()) + continue; + + if (auto* peer = c->getPeer()) + if (peer->contains (localPos + bounds.getPosition() - peer->getBounds().getPosition(), true)) + return false; + } + + if (trueIfInAChildWindow) + return true; + + return XWindowSystem::getInstance()->contains (windowH, localPos * currentScaleFactor); + } + + void toFront (bool makeActive) override + { + if (makeActive) + { + setVisible (true); + grabFocus(); + } + + XWindowSystem::getInstance()->toFront (windowH, makeActive); + handleBroughtToFront(); + } + + void toBehind (ComponentPeer* other) override + { + if (auto* otherPeer = dynamic_cast<LinuxComponentPeer*> (other)) + { + if (otherPeer->styleFlags & windowIsTemporary) + return; + + setMinimised (false); + XWindowSystem::getInstance()->toBehind (windowH, otherPeer->windowH); + } + else + { + jassertfalse; // wrong type of window? + } + } + + bool isFocused() const override + { + return XWindowSystem::getInstance()->isFocused (windowH); + } + + void grabFocus() override + { + if (XWindowSystem::getInstance()->grabFocus (windowH)) + isActiveApplication = true; + } + + //============================================================================== + void repaint (const Rectangle<int>& area) override + { + repainter->repaint (area.getIntersection (bounds.withZeroOrigin())); + } + + void performAnyPendingRepaintsNow() override + { + repainter->performAnyPendingRepaintsNow(); + } + + void setIcon (const Image& newIcon) override + { + XWindowSystem::getInstance()->setIcon (windowH, newIcon); + } + + double getPlatformScaleFactor() const noexcept override + { + return currentScaleFactor; + } + + void setAlpha (float) override {} + bool setAlwaysOnTop (bool) override { return false; } + void textInputRequired (Point<int>, TextInputTarget&) override {} + + //============================================================================== + void addOpenGLRepaintListener (Component* dummy) + { + if (dummy != nullptr) + glRepaintListeners.addIfNotAlreadyThere (dummy); + } + + void removeOpenGLRepaintListener (Component* dummy) + { + if (dummy != nullptr) + glRepaintListeners.removeAllInstancesOf (dummy); + } + + void repaintOpenGLContexts() + { + for (auto* c : glRepaintListeners) + c->handleCommandMessage (0); + } + + //============================================================================== + WindowHandleType getParentWindow() { return parentWindow; } + void setParentWindow (WindowHandleType newParent) { parentWindow = newParent; } + + //============================================================================== + void updateWindowBounds() + { + jassert (windowH != 0); + if (windowH != 0) + { + auto physicalBounds = XWindowSystem::getInstance()->getWindowBounds (windowH, parentWindow); + + updateScaleFactorFromNewBounds (physicalBounds, true); + + bounds = (parentWindow == 0 ? Desktop::getInstance().getDisplays().physicalToLogical (physicalBounds) + : physicalBounds / currentScaleFactor); + } + } + + void updateBorderSize() + { + if ((styleFlags & windowHasTitleBar) == 0) + windowBorder = {}; + else if (windowBorder.getTopAndBottom() == 0 && windowBorder.getLeftAndRight() == 0) + windowBorder = XWindowSystem::getInstance()->getBorderSize (windowH); + } + + //============================================================================== + static bool isActiveApplication; + bool focused = false; + +private: + //============================================================================== + class LinuxRepaintManager : public Timer + { + public: + LinuxRepaintManager (LinuxComponentPeer& p) + : peer (p), + isSemiTransparentWindow ((peer.getStyleFlags() & ComponentPeer::windowIsSemiTransparent) != 0) + { + } + + void timerCallback() override + { + XWindowSystem::getInstance()->processPendingPaintsForWindow (peer.windowH); + + if (XWindowSystem::getInstance()->getNumPaintsPendingForWindow (peer.windowH) > 0) + return; + + if (! regionsNeedingRepaint.isEmpty()) + { + stopTimer(); + performAnyPendingRepaintsNow(); + } + else if (Time::getApproximateMillisecondCounter() > lastTimeImageUsed + 3000) + { + stopTimer(); + image = Image(); + } + } + + void repaint (Rectangle<int> area) + { + if (! isTimerRunning()) + startTimer (repaintTimerPeriod); + + regionsNeedingRepaint.add (area * peer.currentScaleFactor); + } + + void performAnyPendingRepaintsNow() + { + if (XWindowSystem::getInstance()->getNumPaintsPendingForWindow (peer.windowH) > 0) + { + startTimer (repaintTimerPeriod); + return; + } + + auto originalRepaintRegion = regionsNeedingRepaint; + regionsNeedingRepaint.clear(); + auto totalArea = originalRepaintRegion.getBounds(); + + if (! totalArea.isEmpty()) + { + if (image.isNull() || image.getWidth() < totalArea.getWidth() + || image.getHeight() < totalArea.getHeight()) + { + image = XWindowSystem::getInstance()->createImage (isSemiTransparentWindow, + totalArea.getWidth(), totalArea.getHeight(), + useARGBImagesForRendering); + } + + startTimer (repaintTimerPeriod); + + RectangleList<int> adjustedList (originalRepaintRegion); + adjustedList.offsetAll (-totalArea.getX(), -totalArea.getY()); + + if (XWindowSystem::getInstance()->canUseARGBImages()) + for (auto& i : originalRepaintRegion) + image.clear (i - totalArea.getPosition()); + + { + auto context = peer.getComponent().getLookAndFeel() + .createGraphicsContext (image, -totalArea.getPosition(), adjustedList); + + context->addTransform (AffineTransform::scale ((float) peer.currentScaleFactor)); + peer.handlePaint (*context); + } + + for (auto& i : originalRepaintRegion) + XWindowSystem::getInstance()->blitToWindow (peer.windowH, image, i, totalArea); + } + + lastTimeImageUsed = Time::getApproximateMillisecondCounter(); + startTimer (repaintTimerPeriod); + } + + private: + enum { repaintTimerPeriod = 1000 / 100 }; + + LinuxComponentPeer& peer; + const bool isSemiTransparentWindow; + Image image; + uint32 lastTimeImageUsed = 0; + RectangleList<int> regionsNeedingRepaint; + + bool useARGBImagesForRendering = XWindowSystem::getInstance()->canUseARGBImages(); + + JUCE_DECLARE_NON_COPYABLE (LinuxRepaintManager) + }; + + //============================================================================== + void updateScaleFactorFromNewBounds (const Rectangle<int>& newBounds, bool isPhysical) + { + if (! JUCEApplicationBase::isStandaloneApp()) + return; + + Point<int> translation = (parentWindow != 0 ? getScreenPosition (isPhysical) : Point<int>()); + + auto newScaleFactor = Desktop::getInstance().getDisplays().getDisplayForRect (newBounds.translated (translation.x, translation.y), isPhysical)->scale + / Desktop::getInstance().getGlobalScaleFactor(); + + if (! approximatelyEqual (newScaleFactor, currentScaleFactor)) + { + currentScaleFactor = newScaleFactor; + scaleFactorListeners.call ([&] (ScaleFactorListener& l) { l.nativeScaleFactorChanged (currentScaleFactor); }); + } + } + + //============================================================================== + std::unique_ptr<LinuxRepaintManager> repainter; + + WindowHandleType windowH = {}, parentWindow = {}, keyProxy = {}; + Rectangle<int> bounds; + BorderSize<int> windowBorder; + bool fullScreen = false, isAlwaysOnTop = false; + double currentScaleFactor = 1.0; + Array<Component*> glRepaintListeners; + + //============================================================================== + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LinuxComponentPeer) +}; + +template<typename WindowHandleType> +bool LinuxComponentPeer<WindowHandleType>::isActiveApplication = false; + +//============================================================================== +ComponentPeer* Component::createNewPeer (int styleFlags, void* nativeWindowToAttachTo) +{ + return new LinuxComponentPeer<::Window> (*this, styleFlags, (::Window) nativeWindowToAttachTo); +} + +//============================================================================== +JUCE_API bool JUCE_CALLTYPE Process::isForegroundProcess() { return LinuxComponentPeer<::Window>::isActiveApplication; } + +JUCE_API void JUCE_CALLTYPE Process::makeForegroundProcess() {} +JUCE_API void JUCE_CALLTYPE Process::hide() {} + +//============================================================================== +void Desktop::setKioskComponent (Component* comp, bool enableOrDisable, bool) +{ + if (enableOrDisable) + comp->setBounds (getDisplays().getDisplayForRect (comp->getScreenBounds())->totalArea); +} + +void Displays::findDisplays (float masterScale) +{ + if (XWindowSystem::getInstance()->getDisplay() != nullptr) + { + displays = XWindowSystem::getInstance()->findDisplays (masterScale); + + if (! displays.isEmpty()) + updateToLogical(); + } +} + +bool Desktop::canUseSemiTransparentWindows() noexcept +{ + return XWindowSystem::getInstance()->canUseSemiTransparentWindows(); +} + +static bool screenSaverAllowed = true; + +void Desktop::setScreenSaverEnabled (bool isEnabled) +{ + if (screenSaverAllowed != isEnabled) + { + screenSaverAllowed = isEnabled; + XWindowSystem::getInstance()->setScreenSaverEnabled (screenSaverAllowed); + } +} + +bool Desktop::isScreenSaverEnabled() +{ + return screenSaverAllowed; +} + +double Desktop::getDefaultMasterScale() { return 1.0; } + +Desktop::DisplayOrientation Desktop::getCurrentOrientation() const { return upright; } +void Desktop::allowedOrientationsChanged() {} + +//============================================================================== +bool MouseInputSource::SourceList::addSource() +{ + if (sources.isEmpty()) + { + addSource (0, MouseInputSource::InputSourceType::mouse); + return true; + } + + return false; +} + +bool MouseInputSource::SourceList::canUseTouch() +{ + return false; +} + +Point<float> MouseInputSource::getCurrentRawMousePosition() +{ + return Desktop::getInstance().getDisplays().physicalToLogical (XWindowSystem::getInstance()->getCurrentMousePosition()); +} + +void MouseInputSource::setRawMousePosition (Point<float> newPosition) +{ + XWindowSystem::getInstance()->setMousePosition (Desktop::getInstance().getDisplays().logicalToPhysical (newPosition)); +} + +//============================================================================== +void* CustomMouseCursorInfo::create() const +{ + return XWindowSystem::getInstance()->createCustomMouseCursorInfo (image, hotspot); +} + +void MouseCursor::deleteMouseCursor (void* cursorHandle, bool) +{ + if (cursorHandle != nullptr) + XWindowSystem::getInstance()->deleteMouseCursor (cursorHandle); +} + +void* MouseCursor::createStandardMouseCursor (MouseCursor::StandardCursorType type) +{ + return XWindowSystem::getInstance()->createStandardMouseCursor (type); +} + +void MouseCursor::showInWindow (ComponentPeer* peer) const +{ + if (peer != nullptr) + XWindowSystem::getInstance()->showCursor ((::Window) peer->getNativeHandle(), getHandle()); +} + +//============================================================================== +template<typename WindowHandleType> +static LinuxComponentPeer<WindowHandleType>* getPeerForDragEvent (Component* sourceComp) +{ + if (sourceComp == nullptr) + if (auto* draggingSource = Desktop::getInstance().getDraggingMouseSource (0)) + sourceComp = draggingSource->getComponentUnderMouse(); + + if (sourceComp != nullptr) + if (auto* lp = dynamic_cast<LinuxComponentPeer<::Window>*> (sourceComp->getPeer())) + return lp; + + jassertfalse; // This method must be called in response to a component's mouseDown or mouseDrag event! + return nullptr; +} + +bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& files, bool canMoveFiles, + Component* sourceComp, std::function<void()> callback) +{ + if (files.isEmpty()) + return false; + + if (auto* peer = getPeerForDragEvent<::Window> (sourceComp)) + return XWindowSystem::getInstance()->externalDragFileInit (peer, files, canMoveFiles, std::move (callback)); + + // This method must be called in response to a component's mouseDown or mouseDrag event! + jassertfalse; + return false; +} + +bool DragAndDropContainer::performExternalDragDropOfText (const String& text, Component* sourceComp, + std::function<void()> callback) +{ + if (text.isEmpty()) + return false; + + if (auto* peer = getPeerForDragEvent<::Window> (sourceComp)) + return XWindowSystem::getInstance()->externalDragTextInit (peer, text, std::move (callback)); + + // This method must be called in response to a component's mouseDown or mouseDrag event! + jassertfalse; + return false; +} + +//============================================================================== +void SystemClipboard::copyTextToClipboard (const String& clipText) +{ + XWindowSystem::getInstance()->copyTextToClipboard (clipText); +} + +String SystemClipboard::getTextFromClipboard() +{ + return XWindowSystem::getInstance()->getTextFromClipboard(); +} + +//============================================================================== +bool KeyPress::isKeyCurrentlyDown (int keyCode) +{ + return XWindowSystem::getInstance()->isKeyCurrentlyDown (keyCode); +} + +void LookAndFeel::playAlertSound() +{ + std::cout << "\a" << std::flush; +} + +//============================================================================== +#if JUCE_MODAL_LOOPS_PERMITTED +void JUCE_CALLTYPE NativeMessageBox::showMessageBox (AlertWindow::AlertIconType iconType, + const String& title, const String& message, + Component*) +{ + AlertWindow::showMessageBox (iconType, title, message); +} +#endif + +void JUCE_CALLTYPE NativeMessageBox::showMessageBoxAsync (AlertWindow::AlertIconType iconType, + const String& title, const String& message, + Component* associatedComponent, + ModalComponentManager::Callback* callback) +{ + AlertWindow::showMessageBoxAsync (iconType, title, message, {}, associatedComponent, callback); +} + +bool JUCE_CALLTYPE NativeMessageBox::showOkCancelBox (AlertWindow::AlertIconType iconType, + const String& title, const String& message, + Component* associatedComponent, + ModalComponentManager::Callback* callback) +{ + return AlertWindow::showOkCancelBox (iconType, title, message, {}, {}, associatedComponent, callback); +} + +int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (AlertWindow::AlertIconType iconType, + const String& title, const String& message, + Component* associatedComponent, + ModalComponentManager::Callback* callback) +{ + return AlertWindow::showYesNoCancelBox (iconType, title, message, {}, {}, {}, + associatedComponent, callback); +} + +int JUCE_CALLTYPE NativeMessageBox::showYesNoBox (AlertWindow::AlertIconType iconType, + const String& title, const String& message, + Component* associatedComponent, + ModalComponentManager::Callback* callback) +{ + return AlertWindow::showOkCancelBox (iconType, title, message, TRANS ("Yes"), TRANS ("No"), + associatedComponent, callback); +} + +//============================================================================== +Image juce_createIconForFile (const File&) +{ + return {}; +} + +void juce_LinuxAddRepaintListener (ComponentPeer* peer, Component* dummy) +{ + if (auto* linuxPeer = dynamic_cast<LinuxComponentPeer<::Window>*> (peer)) + linuxPeer->addOpenGLRepaintListener (dummy); +} + +void juce_LinuxRemoveRepaintListener (ComponentPeer* peer, Component* dummy) +{ + if (auto* linuxPeer = dynamic_cast<LinuxComponentPeer<::Window>*> (peer)) + linuxPeer->removeOpenGLRepaintListener (dummy); +} + +} // namespace juce diff --git a/modules/juce_gui_basics/native/juce_linux_X11.cpp b/modules/juce_gui_basics/native/juce_linux_X11.cpp deleted file mode 100644 index a2ceb670..00000000 --- a/modules/juce_gui_basics/native/juce_linux_X11.cpp +++ /dev/null @@ -1,339 +0,0 @@ -/* - ============================================================================== - - 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 -{ - -typedef void (*WindowMessageReceiveCallback) (XEvent&); -WindowMessageReceiveCallback dispatchWindowMessage = nullptr; - -typedef void (*SelectionRequestCallback) (XSelectionRequestEvent&); -SelectionRequestCallback handleSelectionRequest = nullptr; - -::Window juce_messageWindowHandle; -XContext windowHandleXContext; - -//============================================================================== -namespace X11ErrorHandling -{ - static XErrorHandler oldErrorHandler = {}; - static XIOErrorHandler oldIOErrorHandler = {}; - - //============================================================================== - // Usually happens when client-server connection is broken - int ioErrorHandler (::Display*) - { - DBG ("ERROR: connection to X server broken.. terminating."); - - if (JUCEApplicationBase::isStandaloneApp()) - MessageManager::getInstance()->stopDispatchLoop(); - - return 0; - } - - - int errorHandler (::Display* display, XErrorEvent* event) - { - ignoreUnused (display, event); - - #if JUCE_DEBUG_XERRORS - char errorStr[64] = { 0 }; - char requestStr[64] = { 0 }; - - XGetErrorText (display, event->error_code, errorStr, 64); - XGetErrorDatabaseText (display, "XRequest", String (event->request_code).toUTF8(), "Unknown", requestStr, 64); - DBG ("ERROR: X returned " << errorStr << " for operation " << requestStr); - #endif - - return 0; - } - - void installXErrorHandlers() - { - oldIOErrorHandler = XSetIOErrorHandler (ioErrorHandler); - oldErrorHandler = XSetErrorHandler (errorHandler); - } - - void removeXErrorHandlers() - { - XSetIOErrorHandler (oldIOErrorHandler); - oldIOErrorHandler = {}; - - XSetErrorHandler (oldErrorHandler); - oldErrorHandler = {}; - } -} - -//============================================================================== -XWindowSystem::XWindowSystem() noexcept -{ - if (JUCEApplicationBase::isStandaloneApp()) - { - // Initialise xlib for multiple thread support - static bool initThreadCalled = false; - - if (! initThreadCalled) - { - if (! XInitThreads()) - { - // This is fatal! Print error and closedown - Logger::outputDebugString ("Failed to initialise xlib thread support."); - Process::terminate(); - return; - } - - initThreadCalled = true; - } - - X11ErrorHandling::installXErrorHandlers(); - } -} - -XWindowSystem::~XWindowSystem() noexcept -{ - if (JUCEApplicationBase::isStandaloneApp()) - X11ErrorHandling::removeXErrorHandlers(); - - clearSingletonInstance(); -} - -::Display* XWindowSystem::displayRef() noexcept -{ - if (++displayCount == 1) - { - jassert (display == nullptr); - - String displayName (getenv ("DISPLAY")); - - if (displayName.isEmpty()) - displayName = ":0.0"; - - // it seems that on some systems XOpenDisplay will occasionally - // fail the first time, but succeed on a second attempt.. - for (int retries = 2; --retries >= 0;) - { - display = XOpenDisplay (displayName.toUTF8()); - - if (display != nullptr) - break; - } - - initialiseXDisplay(); - } - - return display; -} - -::Display* XWindowSystem::displayUnref() noexcept -{ - jassert (display != nullptr); - jassert (displayCount.get() > 0); - - if (--displayCount == 0) - { - destroyXDisplay(); - XCloseDisplay (display); - display = nullptr; - } - - return display; -} - -void XWindowSystem::initialiseXDisplay() noexcept -{ - // This is fatal! Print error and closedown - if (display == nullptr) - { - Logger::outputDebugString ("Failed to connect to the X Server."); - Process::terminate(); - } - - // Create a context to store user data associated with Windows we create - windowHandleXContext = XUniqueContext(); - - // We're only interested in client messages for this window, which are always sent - XSetWindowAttributes swa; - swa.event_mask = NoEventMask; - - // Create our message window (this will never be mapped) - const int screen = DefaultScreen (display); - juce_messageWindowHandle = XCreateWindow (display, RootWindow (display, screen), - 0, 0, 1, 1, 0, 0, InputOnly, - DefaultVisual (display, screen), - CWEventMask, &swa); - - XSync (display, False); - - // Setup input event handler - int fd = XConnectionNumber (display); - - LinuxEventLoop::registerFdCallback (fd, - [this](int) - { - do - { - XEvent evt; - - { - ScopedXLock xlock (display); - - if (! XPending (display)) - return; - - XNextEvent (display, &evt); - } - - if (evt.type == SelectionRequest && evt.xany.window == juce_messageWindowHandle - && handleSelectionRequest != nullptr) - { - handleSelectionRequest (evt.xselectionrequest); - } - else if (evt.xany.window != juce_messageWindowHandle - && dispatchWindowMessage != nullptr) - { - dispatchWindowMessage (evt); - } - - } while (display != nullptr); - }); -} - -void XWindowSystem::destroyXDisplay() noexcept -{ - ScopedXLock xlock (display); - XDestroyWindow (display, juce_messageWindowHandle); - juce_messageWindowHandle = 0; - XSync (display, True); - LinuxEventLoop::unregisterFdCallback (XConnectionNumber (display)); -} - -JUCE_IMPLEMENT_SINGLETON (XWindowSystem) - -//============================================================================== -ScopedXDisplay::ScopedXDisplay() : display (XWindowSystem::getInstance()->displayRef()) -{ -} - -ScopedXDisplay::~ScopedXDisplay() -{ - XWindowSystem::getInstance()->displayUnref(); -} - -//============================================================================== -ScopedXLock::ScopedXLock (::Display* d) : display (d) -{ - if (display != nullptr) - XLockDisplay (display); -} - -ScopedXLock::~ScopedXLock() -{ - if (display != nullptr) - XUnlockDisplay (display); -} - -//============================================================================== -Atoms::Atoms (::Display* display) -{ - protocols = getIfExists (display, "WM_PROTOCOLS"); - protocolList [TAKE_FOCUS] = getIfExists (display, "WM_TAKE_FOCUS"); - protocolList [DELETE_WINDOW] = getIfExists (display, "WM_DELETE_WINDOW"); - protocolList [PING] = getIfExists (display, "_NET_WM_PING"); - changeState = getIfExists (display, "WM_CHANGE_STATE"); - state = getIfExists (display, "WM_STATE"); - userTime = getCreating (display, "_NET_WM_USER_TIME"); - activeWin = getCreating (display, "_NET_ACTIVE_WINDOW"); - pid = getCreating (display, "_NET_WM_PID"); - windowType = getIfExists (display, "_NET_WM_WINDOW_TYPE"); - windowState = getIfExists (display, "_NET_WM_STATE"); - - XdndAware = getCreating (display, "XdndAware"); - XdndEnter = getCreating (display, "XdndEnter"); - XdndLeave = getCreating (display, "XdndLeave"); - XdndPosition = getCreating (display, "XdndPosition"); - XdndStatus = getCreating (display, "XdndStatus"); - XdndDrop = getCreating (display, "XdndDrop"); - XdndFinished = getCreating (display, "XdndFinished"); - XdndSelection = getCreating (display, "XdndSelection"); - - XdndTypeList = getCreating (display, "XdndTypeList"); - XdndActionList = getCreating (display, "XdndActionList"); - XdndActionCopy = getCreating (display, "XdndActionCopy"); - XdndActionPrivate = getCreating (display, "XdndActionPrivate"); - XdndActionDescription = getCreating (display, "XdndActionDescription"); - - XembedMsgType = getCreating (display, "_XEMBED"); - XembedInfo = getCreating (display, "_XEMBED_INFO"); - - allowedMimeTypes[0] = getCreating (display, "UTF8_STRING"); - allowedMimeTypes[1] = getCreating (display, "text/plain;charset=utf-8"); - allowedMimeTypes[2] = getCreating (display, "text/plain"); - allowedMimeTypes[3] = getCreating (display, "text/uri-list"); - - allowedActions[0] = getCreating (display, "XdndActionMove"); - allowedActions[1] = XdndActionCopy; - allowedActions[2] = getCreating (display, "XdndActionLink"); - allowedActions[3] = getCreating (display, "XdndActionAsk"); - allowedActions[4] = XdndActionPrivate; -} - -Atom Atoms::getIfExists (::Display* display, const char* name) { return XInternAtom (display, name, True); } -Atom Atoms::getCreating (::Display* display, const char* name) { return XInternAtom (display, name, False); } - -String Atoms::getName (::Display* display, const Atom atom) -{ - if (atom == None) - return "None"; - - return String (XGetAtomName (display, atom)); -} - -bool Atoms::isMimeTypeFile (::Display* display, const Atom atom) -{ - return getName (display, atom).equalsIgnoreCase ("text/uri-list"); -} - - -const unsigned long Atoms::DndVersion = 3; - -//============================================================================== -GetXProperty::GetXProperty (::Display* display, Window window, Atom atom, - long offset, long length, bool shouldDelete, - Atom requestedType) -{ - success = (XGetWindowProperty (display, window, atom, offset, length, - (Bool) shouldDelete, requestedType, &actualType, - &actualFormat, &numItems, &bytesLeft, &data) == Success) - && data != nullptr; -} - -GetXProperty::~GetXProperty() -{ - if (data != nullptr) - XFree (data); -} - -} // namespace juce diff --git a/modules/juce_gui_basics/native/juce_linux_X11.h b/modules/juce_gui_basics/native/juce_linux_X11.h deleted file mode 100644 index a6a5b4f3..00000000 --- a/modules/juce_gui_basics/native/juce_linux_X11.h +++ /dev/null @@ -1,177 +0,0 @@ -/* - ============================================================================== - - 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. - - ============================================================================== -*/ - -struct _XDisplay; - -namespace juce -{ - -typedef ::_XDisplay* XDisplay; - -typedef unsigned long AtomType; -typedef unsigned long WindowType; - - -//============================================================================== -class XWindowSystem : public DeletedAtShutdown -{ -public: - XDisplay displayRef() noexcept; - XDisplay displayUnref() noexcept; - - JUCE_DECLARE_SINGLETON (XWindowSystem, false) - -private: - XDisplay display = {}; - Atomic<int> displayCount; - - XWindowSystem() noexcept; - ~XWindowSystem() noexcept; - - void initialiseXDisplay() noexcept; - void destroyXDisplay() noexcept; -}; - -//============================================================================== -/** Creates and holds a reference to the X display. - - @tags{GUI} -*/ -struct ScopedXDisplay -{ - ScopedXDisplay(); - ~ScopedXDisplay(); - - const XDisplay display; -}; - -//============================================================================== -/** A handy class that uses XLockDisplay and XUnlockDisplay to lock the X server - using RAII (Only available in Linux!). - - @tags{GUI} -*/ -class ScopedXLock -{ -public: - /** Creating a ScopedXLock object locks the X display. - This uses XLockDisplay() to grab the display that JUCE is using. - */ - ScopedXLock (XDisplay); - - /** Deleting a ScopedXLock object unlocks the X display. - This calls XUnlockDisplay() to release the lock. - */ - ~ScopedXLock(); - -private: - // defined in juce_linux_X11.h - XDisplay display; -}; - -//============================================================================== -struct Atoms -{ - Atoms (XDisplay); - - enum ProtocolItems - { - TAKE_FOCUS = 0, - DELETE_WINDOW = 1, - PING = 2 - }; - - AtomType protocols, protocolList[3], changeState, state, userTime, - activeWin, pid, windowType, windowState, - XdndAware, XdndEnter, XdndLeave, XdndPosition, XdndStatus, - XdndDrop, XdndFinished, XdndSelection, XdndTypeList, XdndActionList, - XdndActionDescription, XdndActionCopy, XdndActionPrivate, - XembedMsgType, XembedInfo, - allowedActions[5], - allowedMimeTypes[4]; - - static const unsigned long DndVersion; - - static AtomType getIfExists (XDisplay, const char* name); - static AtomType getCreating (XDisplay, const char* name); - - static String getName (XDisplay, AtomType); - - static bool isMimeTypeFile (XDisplay, AtomType); -}; - -//============================================================================== -struct GetXProperty -{ - GetXProperty (XDisplay, WindowType, AtomType, - long offset, long length, bool shouldDelete, - AtomType requestedType); - - ~GetXProperty(); - - bool success; - unsigned char* data = nullptr; - unsigned long numItems, bytesLeft; - AtomType actualType; - int actualFormat; -}; - -//============================================================================== -enum -{ - maxXEmbedVersionToSupport = 0 -}; - -enum -{ - XEMBED_MAPPED = (1<<0) -}; - -enum -{ - XEMBED_EMBEDDED_NOTIFY = 0, - XEMBED_WINDOW_ACTIVATE = 1, - XEMBED_WINDOW_DEACTIVATE = 2, - XEMBED_REQUEST_FOCUS = 3, - XEMBED_FOCUS_IN = 4, - XEMBED_FOCUS_OUT = 5, - XEMBED_FOCUS_NEXT = 6, - XEMBED_FOCUS_PREV = 7, - XEMBED_MODALITY_ON = 10, - XEMBED_MODALITY_OFF = 11, - XEMBED_REGISTER_ACCELERATOR = 12, - XEMBED_UNREGISTER_ACCELERATOR = 13, - XEMBED_ACTIVATE_ACCELERATOR = 14 -}; - -enum -{ - XEMBED_FOCUS_CURRENT = 0, - XEMBED_FOCUS_FIRST = 1, - XEMBED_FOCUS_LAST = 2 -}; - -} // namespace juce diff --git a/modules/juce_gui_basics/native/juce_linux_X11_Clipboard.cpp b/modules/juce_gui_basics/native/juce_linux_X11_Clipboard.cpp deleted file mode 100644 index 8c3427b0..00000000 --- a/modules/juce_gui_basics/native/juce_linux_X11_Clipboard.cpp +++ /dev/null @@ -1,280 +0,0 @@ -/* - ============================================================================== - - 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 -{ - -extern ::Window juce_messageWindowHandle; - -namespace ClipboardHelpers -{ - static String localClipboardContent; - static Atom atom_UTF8_STRING; - static Atom atom_CLIPBOARD; - static Atom atom_TARGETS; - - //============================================================================== - static void initSelectionAtoms (::Display* display) - { - static bool isInitialised = false; - - if (! isInitialised) - { - isInitialised = true; - - atom_UTF8_STRING = Atoms::getCreating (display, "UTF8_STRING"); - atom_CLIPBOARD = Atoms::getCreating (display, "CLIPBOARD"); - atom_TARGETS = Atoms::getCreating (display, "TARGETS"); - } - } - - //============================================================================== - // Read the content of a window property as either a locale-dependent string or an utf8 string - // works only for strings shorter than 1000000 bytes - static String readWindowProperty (::Display* display, Window window, Atom prop) - { - String returnData; - - if (display != nullptr) - { - char* clipData; - Atom actualType; - int actualFormat; - unsigned long numItems, bytesLeft; - - if (XGetWindowProperty (display, window, prop, - 0L /* offset */, 1000000 /* length (max) */, False, - AnyPropertyType /* format */, - &actualType, &actualFormat, &numItems, &bytesLeft, - (unsigned char**) &clipData) == Success) - { - if (actualType == atom_UTF8_STRING && actualFormat == 8) - returnData = String::fromUTF8 (clipData, (int) numItems); - else if (actualType == XA_STRING && actualFormat == 8) - returnData = String (clipData, numItems); - - if (clipData != nullptr) - XFree (clipData); - - jassert (bytesLeft == 0 || numItems == 1000000); - } - - XDeleteProperty (display, window, prop); - } - - return returnData; - } - - //============================================================================== - // Send a SelectionRequest to the window owning the selection and waits for its answer (with a timeout) */ - static bool requestSelectionContent (::Display* display, String& selectionContent, - Atom selection, Atom requestedFormat) - { - Atom property_name = XInternAtom (display, "JUCE_SEL", false); - - // The selection owner will be asked to set the JUCE_SEL property on the - // juce_messageWindowHandle with the selection content - XConvertSelection (display, selection, requestedFormat, property_name, - juce_messageWindowHandle, CurrentTime); - - int count = 50; // will wait at most for 200 ms - - while (--count >= 0) - { - XEvent event; - - if (XCheckTypedWindowEvent (display, juce_messageWindowHandle, SelectionNotify, &event)) - { - if (event.xselection.property == property_name) - { - jassert (event.xselection.requestor == juce_messageWindowHandle); - - selectionContent = readWindowProperty (display, event.xselection.requestor, - event.xselection.property); - return true; - } - - return false; // the format we asked for was denied.. (event.xselection.property == None) - } - - // not very elegant.. we could do a select() or something like that... - // however clipboard content requesting is inherently slow on x11, it - // often takes 50ms or more so... - Thread::sleep (4); - } - - return false; - } - - //============================================================================== - // Called from the event loop in juce_linux_Messaging in response to SelectionRequest events - static void handleSelection (XSelectionRequestEvent& evt) - { - ClipboardHelpers::initSelectionAtoms (evt.display); - - // the selection content is sent to the target window as a window property - XSelectionEvent reply; - reply.type = SelectionNotify; - reply.display = evt.display; - reply.requestor = evt.requestor; - reply.selection = evt.selection; - reply.target = evt.target; - reply.property = None; // == "fail" - reply.time = evt.time; - - HeapBlock<char> data; - int propertyFormat = 0; - size_t numDataItems = 0; - - if (evt.selection == XA_PRIMARY || evt.selection == ClipboardHelpers::atom_CLIPBOARD) - { - if (evt.target == XA_STRING || evt.target == ClipboardHelpers::atom_UTF8_STRING) - { - // translate to utf8 - numDataItems = ClipboardHelpers::localClipboardContent.getNumBytesAsUTF8() + 1; - data.calloc (numDataItems + 1); - ClipboardHelpers::localClipboardContent.copyToUTF8 (data, numDataItems); - propertyFormat = 8; // bits/item - } - else if (evt.target == ClipboardHelpers::atom_TARGETS) - { - // another application wants to know what we are able to send - numDataItems = 2; - propertyFormat = 32; // atoms are 32-bit - data.calloc (numDataItems * 4); - Atom* atoms = reinterpret_cast<Atom*> (data.getData()); - atoms[0] = ClipboardHelpers::atom_UTF8_STRING; - atoms[1] = XA_STRING; - - evt.target = XA_ATOM; - } - } - else - { - DBG ("requested unsupported clipboard"); - } - - if (data != nullptr) - { - const size_t maxReasonableSelectionSize = 1000000; - - // for very big chunks of data, we should use the "INCR" protocol , which is a pain in the *ss - if (evt.property != None && numDataItems < maxReasonableSelectionSize) - { - XChangeProperty (evt.display, evt.requestor, - evt.property, evt.target, - propertyFormat /* 8 or 32 */, PropModeReplace, - reinterpret_cast<const unsigned char*> (data.getData()), (int) numDataItems); - reply.property = evt.property; // " == success" - } - } - - XSendEvent (evt.display, evt.requestor, 0, NoEventMask, (XEvent*) &reply); - } -} - -//============================================================================== -typedef void (*SelectionRequestCallback) (XSelectionRequestEvent&); -extern SelectionRequestCallback handleSelectionRequest; - -struct ClipboardCallbackInitialiser -{ - ClipboardCallbackInitialiser() - { - handleSelectionRequest = ClipboardHelpers::handleSelection; - } -}; - -static ClipboardCallbackInitialiser clipboardInitialiser; - -//============================================================================== -void SystemClipboard::copyTextToClipboard (const String& clipText) -{ - ScopedXDisplay xDisplay; - - if (auto display = xDisplay.display) - { - ClipboardHelpers::initSelectionAtoms (display); - ClipboardHelpers::localClipboardContent = clipText; - - XSetSelectionOwner (display, XA_PRIMARY, juce_messageWindowHandle, CurrentTime); - XSetSelectionOwner (display, ClipboardHelpers::atom_CLIPBOARD, juce_messageWindowHandle, CurrentTime); - } -} - -String SystemClipboard::getTextFromClipboard() -{ - String content; - ScopedXDisplay xDisplay; - - if (auto display = xDisplay.display) - { - ClipboardHelpers::initSelectionAtoms (display); - - /* 1) try to read from the "CLIPBOARD" selection first (the "high - level" clipboard that is supposed to be filled by ctrl-C - etc). When a clipboard manager is running, the content of this - selection is preserved even when the original selection owner - exits. - - 2) and then try to read from "PRIMARY" selection (the "legacy" selection - filled by good old x11 apps such as xterm) - */ - Atom selection = XA_PRIMARY; - Window selectionOwner = None; - - if ((selectionOwner = XGetSelectionOwner (display, selection)) == None) - { - selection = ClipboardHelpers::atom_CLIPBOARD; - selectionOwner = XGetSelectionOwner (display, selection); - } - - if (selectionOwner != None) - { - if (selectionOwner == juce_messageWindowHandle) - { - content = ClipboardHelpers::localClipboardContent; - } - else - { - // first try: we want an utf8 string - bool ok = ClipboardHelpers::requestSelectionContent (display, content, - selection, ClipboardHelpers::atom_UTF8_STRING); - - if (! ok) - { - // second chance, ask for a good old locale-dependent string .. - ok = ClipboardHelpers::requestSelectionContent (display, content, - selection, XA_STRING); - } - } - } - } - - return content; -} - -} // namespace juce diff --git a/modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp b/modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp deleted file mode 100644 index 51068ad4..00000000 --- a/modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp +++ /dev/null @@ -1,4174 +0,0 @@ -/* - ============================================================================== - - 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 -{ - -#if JUCE_DEBUG && ! defined (JUCE_DEBUG_XERRORS) - #define JUCE_DEBUG_XERRORS 1 -#endif - -#if JUCE_MODULE_AVAILABLE_juce_gui_extra - #define JUCE_X11_SUPPORTS_XEMBED 1 -#else - #define JUCE_X11_SUPPORTS_XEMBED 0 -#endif - -#if JUCE_X11_SUPPORTS_XEMBED -bool juce_handleXEmbedEvent (ComponentPeer*, void*); -unsigned long juce_getCurrentFocusWindow (ComponentPeer*); -#endif - -extern WindowMessageReceiveCallback dispatchWindowMessage; - -extern XContext windowHandleXContext; - -//=============================== X11 - Keys =================================== - -namespace Keys -{ - enum MouseButtons - { - NoButton = 0, - LeftButton = 1, - MiddleButton = 2, - RightButton = 3, - WheelUp = 4, - WheelDown = 5 - }; - - static int AltMask = 0; - static int NumLockMask = 0; - static bool numLock = false; - static bool capsLock = false; - static char keyStates [32]; - static const int extendedKeyModifier = 0x10000000; -} - -bool KeyPress::isKeyCurrentlyDown (int keyCode) -{ - ScopedXDisplay xDisplay; - - if (auto display = xDisplay.display) - { - int keysym; - - if (keyCode & Keys::extendedKeyModifier) - { - keysym = 0xff00 | (keyCode & 0xff); - } - else - { - keysym = keyCode; - - if (keysym == (XK_Tab & 0xff) - || keysym == (XK_Return & 0xff) - || keysym == (XK_Escape & 0xff) - || keysym == (XK_BackSpace & 0xff)) - { - keysym |= 0xff00; - } - } - - ScopedXLock xlock (display); - - const int keycode = XKeysymToKeycode (display, (KeySym) keysym); - const int keybyte = keycode >> 3; - const int keybit = (1 << (keycode & 7)); - - return (Keys::keyStates [keybyte] & keybit) != 0; - } - - return false; -} - -//============================================================================== - -const int KeyPress::spaceKey = XK_space & 0xff; -const int KeyPress::returnKey = XK_Return & 0xff; -const int KeyPress::escapeKey = XK_Escape & 0xff; -const int KeyPress::backspaceKey = XK_BackSpace & 0xff; -const int KeyPress::leftKey = (XK_Left & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::rightKey = (XK_Right & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::upKey = (XK_Up & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::downKey = (XK_Down & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::pageUpKey = (XK_Page_Up & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::pageDownKey = (XK_Page_Down & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::endKey = (XK_End & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::homeKey = (XK_Home & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::insertKey = (XK_Insert & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::deleteKey = (XK_Delete & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::tabKey = XK_Tab & 0xff; -const int KeyPress::F1Key = (XK_F1 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F2Key = (XK_F2 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F3Key = (XK_F3 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F4Key = (XK_F4 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F5Key = (XK_F5 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F6Key = (XK_F6 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F7Key = (XK_F7 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F8Key = (XK_F8 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F9Key = (XK_F9 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F10Key = (XK_F10 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F11Key = (XK_F11 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F12Key = (XK_F12 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F13Key = (XK_F13 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F14Key = (XK_F14 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F15Key = (XK_F15 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F16Key = (XK_F16 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F17Key = (XK_F17 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F18Key = (XK_F18 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F19Key = (XK_F19 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F20Key = (XK_F20 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F21Key = (XK_F21 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F22Key = (XK_F22 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F23Key = (XK_F23 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F24Key = (XK_F24 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F25Key = (XK_F25 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F26Key = (XK_F26 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F27Key = (XK_F27 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F28Key = (XK_F28 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F29Key = (XK_F29 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F30Key = (XK_F30 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F31Key = (XK_F31 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F32Key = (XK_F32 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F33Key = (XK_F33 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F34Key = (XK_F34 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F35Key = (XK_F35 & 0xff) | Keys::extendedKeyModifier; - -const int KeyPress::numberPad0 = (XK_KP_0 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::numberPad1 = (XK_KP_1 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::numberPad2 = (XK_KP_2 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::numberPad3 = (XK_KP_3 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::numberPad4 = (XK_KP_4 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::numberPad5 = (XK_KP_5 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::numberPad6 = (XK_KP_6 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::numberPad7 = (XK_KP_7 & 0xff)| Keys::extendedKeyModifier; -const int KeyPress::numberPad8 = (XK_KP_8 & 0xff)| Keys::extendedKeyModifier; -const int KeyPress::numberPad9 = (XK_KP_9 & 0xff)| Keys::extendedKeyModifier; -const int KeyPress::numberPadAdd = (XK_KP_Add & 0xff)| Keys::extendedKeyModifier; -const int KeyPress::numberPadSubtract = (XK_KP_Subtract & 0xff)| Keys::extendedKeyModifier; -const int KeyPress::numberPadMultiply = (XK_KP_Multiply & 0xff)| Keys::extendedKeyModifier; -const int KeyPress::numberPadDivide = (XK_KP_Divide & 0xff)| Keys::extendedKeyModifier; -const int KeyPress::numberPadSeparator = (XK_KP_Separator & 0xff)| Keys::extendedKeyModifier; -const int KeyPress::numberPadDecimalPoint = (XK_KP_Decimal & 0xff)| Keys::extendedKeyModifier; -const int KeyPress::numberPadEquals = (XK_KP_Equal & 0xff)| Keys::extendedKeyModifier; -const int KeyPress::numberPadDelete = (XK_KP_Delete & 0xff)| Keys::extendedKeyModifier; -const int KeyPress::playKey = ((int) 0xffeeff00) | Keys::extendedKeyModifier; -const int KeyPress::stopKey = ((int) 0xffeeff01) | Keys::extendedKeyModifier; -const int KeyPress::fastForwardKey = ((int) 0xffeeff02) | Keys::extendedKeyModifier; -const int KeyPress::rewindKey = ((int) 0xffeeff03) | Keys::extendedKeyModifier; - -//================================== X11 - Shm ================================= - -#if JUCE_USE_XSHM -namespace XSHMHelpers -{ - static int trappedErrorCode = 0; - - extern "C" int errorTrapHandler (Display*, XErrorEvent* err) - { - trappedErrorCode = err->error_code; - return 0; - } - - static bool isShmAvailable (::Display* display) noexcept - { - static bool isChecked = false; - static bool isAvailable = false; - - if (! isChecked) - { - isChecked = true; - - if (display != nullptr) - { - int major, minor; - Bool pixmaps; - - ScopedXLock xlock (display); - - if (XShmQueryVersion (display, &major, &minor, &pixmaps)) - { - trappedErrorCode = 0; - XErrorHandler oldHandler = XSetErrorHandler (errorTrapHandler); - - XShmSegmentInfo segmentInfo; - zerostruct (segmentInfo); - - if (auto* xImage = XShmCreateImage (display, DefaultVisual (display, DefaultScreen (display)), - 24, ZPixmap, nullptr, &segmentInfo, 50, 50)) - { - if ((segmentInfo.shmid = shmget (IPC_PRIVATE, - (size_t) (xImage->bytes_per_line * xImage->height), - IPC_CREAT | 0777)) >= 0) - { - segmentInfo.shmaddr = (char*) shmat (segmentInfo.shmid, nullptr, 0); - - if (segmentInfo.shmaddr != (void*) -1) - { - segmentInfo.readOnly = False; - xImage->data = segmentInfo.shmaddr; - XSync (display, False); - - if (XShmAttach (display, &segmentInfo) != 0) - { - XSync (display, False); - XShmDetach (display, &segmentInfo); - - isAvailable = true; - } - } - - XFlush (display); - XDestroyImage (xImage); - - shmdt (segmentInfo.shmaddr); - } - - shmctl (segmentInfo.shmid, IPC_RMID, nullptr); - - XSetErrorHandler (oldHandler); - if (trappedErrorCode != 0) - isAvailable = false; - } - } - } - } - - return isAvailable; - } -} -#endif - -//=============================== X11 - Render ================================= - -#if JUCE_USE_XRENDER -namespace XRender -{ - typedef Status (*tXRenderQueryVersion) (Display*, int*, int*); - typedef XRenderPictFormat* (*tXRenderFindStandardFormat) (Display*, int); - typedef XRenderPictFormat* (*tXRenderFindFormat) (Display*, unsigned long, XRenderPictFormat*, int); - typedef XRenderPictFormat* (*tXRenderFindVisualFormat) (Display*, Visual*); - - static tXRenderQueryVersion xRenderQueryVersion = nullptr; - static tXRenderFindStandardFormat xRenderFindStandardFormat = nullptr; - static tXRenderFindFormat xRenderFindFormat = nullptr; - static tXRenderFindVisualFormat xRenderFindVisualFormat = nullptr; - - static bool isAvailable (::Display* display) - { - static bool hasLoaded = false; - - if (! hasLoaded) - { - if (display != nullptr) - { - hasLoaded = true; - - ScopedXLock xlock (display); - - if (void* h = dlopen ("libXrender.so.1", RTLD_GLOBAL | RTLD_NOW)) - { - xRenderQueryVersion = (tXRenderQueryVersion) dlsym (h, "XRenderQueryVersion"); - xRenderFindStandardFormat = (tXRenderFindStandardFormat) dlsym (h, "XRenderFindStandardFormat"); - xRenderFindFormat = (tXRenderFindFormat) dlsym (h, "XRenderFindFormat"); - xRenderFindVisualFormat = (tXRenderFindVisualFormat) dlsym (h, "XRenderFindVisualFormat"); - } - - if (xRenderQueryVersion != nullptr - && xRenderFindStandardFormat != nullptr - && xRenderFindFormat != nullptr - && xRenderFindVisualFormat != nullptr) - { - int major, minor; - if (xRenderQueryVersion (display, &major, &minor)) - return true; - } - } - - xRenderQueryVersion = nullptr; - } - - return xRenderQueryVersion != nullptr; - } - - static bool hasCompositingWindowManager (::Display* display) noexcept - { - return display != nullptr - && XGetSelectionOwner (display, Atoms::getCreating (display, "_NET_WM_CM_S0")) != 0; - } - - static XRenderPictFormat* findPictureFormat (::Display* display) - { - ScopedXLock xlock (display); - XRenderPictFormat* pictFormat = nullptr; - - if (isAvailable (display)) - { - pictFormat = xRenderFindStandardFormat (display, PictStandardARGB32); - - if (pictFormat == nullptr) - { - XRenderPictFormat desiredFormat; - desiredFormat.type = PictTypeDirect; - desiredFormat.depth = 32; - - desiredFormat.direct.alphaMask = 0xff; - desiredFormat.direct.redMask = 0xff; - desiredFormat.direct.greenMask = 0xff; - desiredFormat.direct.blueMask = 0xff; - - desiredFormat.direct.alpha = 24; - desiredFormat.direct.red = 16; - desiredFormat.direct.green = 8; - desiredFormat.direct.blue = 0; - - pictFormat = xRenderFindFormat (display, - PictFormatType | PictFormatDepth - | PictFormatRedMask | PictFormatRed - | PictFormatGreenMask | PictFormatGreen - | PictFormatBlueMask | PictFormatBlue - | PictFormatAlphaMask | PictFormatAlpha, - &desiredFormat, - 0); - } - } - - return pictFormat; - } -} -#endif - -//================================ X11 - Visuals =============================== - -namespace Visuals -{ - static Visual* findVisualWithDepth (::Display* display, int desiredDepth) noexcept - { - ScopedXLock xlock (display); - - Visual* visual = nullptr; - int numVisuals = 0; - long desiredMask = VisualNoMask; - XVisualInfo desiredVisual; - - desiredVisual.screen = DefaultScreen (display); - desiredVisual.depth = desiredDepth; - - desiredMask = VisualScreenMask | VisualDepthMask; - - if (desiredDepth == 32) - { - desiredVisual.c_class = TrueColor; - desiredVisual.red_mask = 0x00FF0000; - desiredVisual.green_mask = 0x0000FF00; - desiredVisual.blue_mask = 0x000000FF; - desiredVisual.bits_per_rgb = 8; - - desiredMask |= VisualClassMask; - desiredMask |= VisualRedMaskMask; - desiredMask |= VisualGreenMaskMask; - desiredMask |= VisualBlueMaskMask; - desiredMask |= VisualBitsPerRGBMask; - } - - if (auto* xvinfos = XGetVisualInfo (display, desiredMask, &desiredVisual, &numVisuals)) - { - for (int i = 0; i < numVisuals; i++) - { - if (xvinfos[i].depth == desiredDepth) - { - visual = xvinfos[i].visual; - break; - } - } - - XFree (xvinfos); - } - - return visual; - } - - static Visual* findVisualFormat (::Display* display, int desiredDepth, int& matchedDepth) noexcept - { - Visual* visual = nullptr; - - if (desiredDepth == 32) - { - #if JUCE_USE_XSHM - if (XSHMHelpers::isShmAvailable (display)) - { - #if JUCE_USE_XRENDER - if (XRender::isAvailable (display)) - { - if (auto pictFormat = XRender::findPictureFormat (display)) - { - int numVisuals = 0; - XVisualInfo desiredVisual; - desiredVisual.screen = DefaultScreen (display); - desiredVisual.depth = 32; - desiredVisual.bits_per_rgb = 8; - - if (auto xvinfos = XGetVisualInfo (display, - VisualScreenMask | VisualDepthMask | VisualBitsPerRGBMask, - &desiredVisual, &numVisuals)) - { - for (int i = 0; i < numVisuals; ++i) - { - auto pictVisualFormat = XRender::xRenderFindVisualFormat (display, xvinfos[i].visual); - - if (pictVisualFormat != nullptr - && pictVisualFormat->type == PictTypeDirect - && pictVisualFormat->direct.alphaMask) - { - visual = xvinfos[i].visual; - matchedDepth = 32; - break; - } - } - - XFree (xvinfos); - } - } - } - #endif - if (visual == nullptr) - { - visual = findVisualWithDepth (display, 32); - - if (visual != nullptr) - matchedDepth = 32; - } - } - #endif - } - - if (visual == nullptr && desiredDepth >= 24) - { - visual = findVisualWithDepth (display, 24); - - if (visual != nullptr) - matchedDepth = 24; - } - - if (visual == nullptr && desiredDepth >= 16) - { - visual = findVisualWithDepth (display, 16); - - if (visual != nullptr) - matchedDepth = 16; - } - - return visual; - } -} - -//================================= X11 - Bitmap =============================== - -class XBitmapImage : public ImagePixelData -{ -public: - XBitmapImage (::Display* d, Image::PixelFormat format, int w, int h, - bool clearImage, unsigned int imageDepth_, Visual* visual) - : ImagePixelData (format, w, h), - imageDepth (imageDepth_), - display (d) - { - jassert (format == Image::RGB || format == Image::ARGB); - - pixelStride = (format == Image::RGB) ? 3 : 4; - lineStride = ((w * pixelStride + 3) & ~3); - - ScopedXLock xlock (display); - - #if JUCE_USE_XSHM - usingXShm = false; - - if ((imageDepth > 16) && XSHMHelpers::isShmAvailable (display)) - { - zerostruct (segmentInfo); - - segmentInfo.shmid = -1; - segmentInfo.shmaddr = (char *) -1; - segmentInfo.readOnly = False; - - xImage = XShmCreateImage (display, visual, imageDepth, ZPixmap, nullptr, - &segmentInfo, (unsigned int) w, (unsigned int) h); - - if (xImage != nullptr) - { - if ((segmentInfo.shmid = shmget (IPC_PRIVATE, - (size_t) (xImage->bytes_per_line * xImage->height), - IPC_CREAT | 0777)) >= 0) - { - if (segmentInfo.shmid != -1) - { - segmentInfo.shmaddr = (char*) shmat (segmentInfo.shmid, nullptr, 0); - - if (segmentInfo.shmaddr != (void*) -1) - { - segmentInfo.readOnly = False; - - xImage->data = segmentInfo.shmaddr; - imageData = (uint8*) segmentInfo.shmaddr; - - if (XShmAttach (display, &segmentInfo) != 0) - usingXShm = true; - else - jassertfalse; - } - else - { - shmctl (segmentInfo.shmid, IPC_RMID, nullptr); - } - } - } - } - } - - if (! isUsingXShm()) - #endif - { - imageDataAllocated.allocate ((size_t) (lineStride * h), format == Image::ARGB && clearImage); - imageData = imageDataAllocated; - - xImage = (XImage*) ::calloc (1, sizeof (XImage)); - - xImage->width = w; - xImage->height = h; - xImage->xoffset = 0; - xImage->format = ZPixmap; - xImage->data = (char*) imageData; - xImage->byte_order = ImageByteOrder (display); - xImage->bitmap_unit = BitmapUnit (display); - xImage->bitmap_bit_order = BitmapBitOrder (display); - xImage->bitmap_pad = 32; - xImage->depth = pixelStride * 8; - xImage->bytes_per_line = lineStride; - xImage->bits_per_pixel = pixelStride * 8; - xImage->red_mask = 0x00FF0000; - xImage->green_mask = 0x0000FF00; - xImage->blue_mask = 0x000000FF; - - if (imageDepth == 16) - { - const int pixStride = 2; - const int stride = ((w * pixStride + 3) & ~3); - - imageData16Bit.malloc (stride * h); - xImage->data = imageData16Bit; - xImage->bitmap_pad = 16; - xImage->depth = pixStride * 8; - xImage->bytes_per_line = stride; - xImage->bits_per_pixel = pixStride * 8; - xImage->red_mask = visual->red_mask; - xImage->green_mask = visual->green_mask; - xImage->blue_mask = visual->blue_mask; - } - - if (! XInitImage (xImage)) - jassertfalse; - } - } - - ~XBitmapImage() override - { - ScopedXLock xlock (display); - - if (gc != None) - XFreeGC (display, gc); - - #if JUCE_USE_XSHM - if (isUsingXShm()) - { - XShmDetach (display, &segmentInfo); - - XFlush (display); - XDestroyImage (xImage); - - shmdt (segmentInfo.shmaddr); - shmctl (segmentInfo.shmid, IPC_RMID, nullptr); - } - else - #endif - { - xImage->data = nullptr; - XDestroyImage (xImage); - } - } - - std::unique_ptr<LowLevelGraphicsContext> createLowLevelContext() override - { - sendDataChangeMessage(); - return std::make_unique<LowLevelGraphicsSoftwareRenderer> (Image (this)); - } - - void initialiseBitmapData (Image::BitmapData& bitmap, int x, int y, - Image::BitmapData::ReadWriteMode mode) override - { - bitmap.data = imageData + x * pixelStride + y * lineStride; - bitmap.pixelFormat = pixelFormat; - bitmap.lineStride = lineStride; - bitmap.pixelStride = pixelStride; - - if (mode != Image::BitmapData::readOnly) - sendDataChangeMessage(); - } - - ImagePixelData::Ptr clone() override - { - jassertfalse; - return nullptr; - } - - std::unique_ptr<ImageType> createType() const override { return std::make_unique<NativeImageType>(); } - - void blitToWindow (Window window, int dx, int dy, - unsigned int dw, unsigned int dh, int sx, int sy) - { - ScopedXLock xlock (display); - - if (gc == None) - { - XGCValues gcvalues; - gcvalues.foreground = None; - gcvalues.background = None; - gcvalues.function = GXcopy; - gcvalues.plane_mask = AllPlanes; - gcvalues.clip_mask = None; - gcvalues.graphics_exposures = False; - - gc = XCreateGC (display, window, - GCBackground | GCForeground | GCFunction | GCPlaneMask | GCClipMask | GCGraphicsExposures, - &gcvalues); - } - - if (imageDepth == 16) - { - auto rMask = (uint32) xImage->red_mask; - auto gMask = (uint32) xImage->green_mask; - auto bMask = (uint32) xImage->blue_mask; - auto rShiftL = (uint32) jmax (0, getShiftNeeded (rMask)); - auto rShiftR = (uint32) jmax (0, -getShiftNeeded (rMask)); - auto gShiftL = (uint32) jmax (0, getShiftNeeded (gMask)); - auto gShiftR = (uint32) jmax (0, -getShiftNeeded (gMask)); - auto bShiftL = (uint32) jmax (0, getShiftNeeded (bMask)); - auto bShiftR = (uint32) jmax (0, -getShiftNeeded (bMask)); - - const Image::BitmapData srcData (Image (this), Image::BitmapData::readOnly); - - for (int y = sy; y < sy + (int)dh; ++y) - { - const uint8* p = srcData.getPixelPointer (sx, y); - - for (int x = sx; x < sx + (int)dw; ++x) - { - auto* pixel = (const PixelRGB*) p; - p += srcData.pixelStride; - - XPutPixel (xImage, x, y, - (((((uint32) pixel->getRed()) << rShiftL) >> rShiftR) & rMask) - | (((((uint32) pixel->getGreen()) << gShiftL) >> gShiftR) & gMask) - | (((((uint32) pixel->getBlue()) << bShiftL) >> bShiftR) & bMask)); - } - } - } - - // blit results to screen. - #if JUCE_USE_XSHM - if (isUsingXShm()) - XShmPutImage (display, (::Drawable) window, gc, xImage, sx, sy, dx, dy, dw, dh, True); - else - #endif - XPutImage (display, (::Drawable) window, gc, xImage, sx, sy, dx, dy, dw, dh); - } - - #if JUCE_USE_XSHM - bool isUsingXShm() const noexcept { return usingXShm; } - #endif - -private: - //============================================================================== - XImage* xImage = {}; - const unsigned int imageDepth; - HeapBlock<uint8> imageDataAllocated; - HeapBlock<char> imageData16Bit; - int pixelStride, lineStride; - uint8* imageData = {}; - GC gc = None; - ::Display* display = {}; - - #if JUCE_USE_XSHM - XShmSegmentInfo segmentInfo; - bool usingXShm; - #endif - - static int getShiftNeeded (const uint32 mask) noexcept - { - for (int i = 32; --i >= 0;) - if (((mask >> i) & 1) != 0) - return i - 7; - - jassertfalse; - return 0; - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (XBitmapImage) -}; - -//============================================================================== -#if JUCE_USE_XINERAMA -static Array<XineramaScreenInfo> XineramaQueryDisplays (::Display* display) -{ - typedef Bool (*tXineramaIsActive) (::Display*); - typedef XineramaScreenInfo* (*tXineramaQueryScreens) (::Display*, int*); - - int major_opcode, first_event, first_error; - - if (XQueryExtension (display, "XINERAMA", &major_opcode, &first_event, &first_error)) - { - static void* libXinerama = nullptr; - static tXineramaIsActive isActiveFuncPtr = nullptr; - static tXineramaQueryScreens xineramaQueryScreens = nullptr; - - if (libXinerama == nullptr) - { - libXinerama = dlopen ("libXinerama.so", RTLD_GLOBAL | RTLD_NOW); - - if (libXinerama == nullptr) - libXinerama = dlopen ("libXinerama.so.1", RTLD_GLOBAL | RTLD_NOW); - - if (libXinerama != nullptr) - { - isActiveFuncPtr = (tXineramaIsActive) dlsym (libXinerama, "XineramaIsActive"); - xineramaQueryScreens = (tXineramaQueryScreens) dlsym (libXinerama, "XineramaQueryScreens"); - } - } - - if (isActiveFuncPtr != nullptr && xineramaQueryScreens != nullptr && isActiveFuncPtr (display) != 0) - { - int numScreens; - - if (auto* xinfo = xineramaQueryScreens (display, &numScreens)) - { - Array<XineramaScreenInfo> infos (xinfo, numScreens); - XFree (xinfo); - - return infos; - } - } - } - - return {}; -} -#endif - -//============================================================================== -#if JUCE_USE_XRANDR -class XRandrWrapper -{ -private: - XRandrWrapper() - { - if (libXrandr == nullptr) - { - libXrandr = dlopen ("libXrandr.so", RTLD_GLOBAL | RTLD_NOW); - - if (libXrandr == nullptr) - libXrandr = dlopen ("libXrandr.so.2", RTLD_GLOBAL | RTLD_NOW); - - if (libXrandr != nullptr) - { - getScreenResourcesPtr = (tXRRGetScreenResources) dlsym (libXrandr, "XRRGetScreenResources"); - freeScreenResourcesPtr = (tXRRFreeScreenResources) dlsym (libXrandr, "XRRFreeScreenResources"); - getOutputInfoPtr = (tXRRGetOutputInfo) dlsym (libXrandr, "XRRGetOutputInfo"); - freeOutputInfoPtr = (tXRRFreeOutputInfo) dlsym (libXrandr, "XRRFreeOutputInfo"); - getCrtcInfoPtr = (tXRRGetCrtcInfo) dlsym (libXrandr, "XRRGetCrtcInfo"); - freeCrtcInfoPtr = (tXRRFreeCrtcInfo) dlsym (libXrandr, "XRRFreeCrtcInfo"); - getOutputPrimaryPtr = (tXRRGetOutputPrimary) dlsym (libXrandr, "XRRGetOutputPrimary"); - } - } - } - -public: - //============================================================================== - static XRandrWrapper& getInstance() - { - static XRandrWrapper xrandr; - return xrandr; - } - - //============================================================================== - XRRScreenResources* getScreenResources (::Display* display, ::Window window) - { - if (getScreenResourcesPtr != nullptr) - return getScreenResourcesPtr (display, window); - - return nullptr; - } - - XRROutputInfo* getOutputInfo (::Display* display, XRRScreenResources* resources, RROutput output) - { - if (getOutputInfoPtr != nullptr) - return getOutputInfoPtr (display, resources, output); - - return nullptr; - } - - XRRCrtcInfo* getCrtcInfo (::Display* display, XRRScreenResources* resources, RRCrtc crtc) - { - if (getCrtcInfoPtr != nullptr) - return getCrtcInfoPtr (display, resources, crtc); - - return nullptr; - } - - RROutput getOutputPrimary (::Display* display, ::Window window) - { - if (getOutputPrimaryPtr != nullptr) - return getOutputPrimaryPtr (display, window); - - return 0; - } - - //============================================================================== - void freeScreenResources (XRRScreenResources* ptr) - { - if (freeScreenResourcesPtr != nullptr) - freeScreenResourcesPtr (ptr); - } - - void freeOutputInfo (XRROutputInfo* ptr) - { - if (freeOutputInfoPtr != nullptr) - freeOutputInfoPtr (ptr); - } - - void freeCrtcInfo (XRRCrtcInfo* ptr) - { - if (freeCrtcInfoPtr != nullptr) - freeCrtcInfoPtr (ptr); - } - -private: - using tXRRGetScreenResources = XRRScreenResources* (*) (::Display*, ::Window); - using tXRRFreeScreenResources = void (*) (XRRScreenResources*); - using tXRRGetOutputInfo = XRROutputInfo* (*) (::Display*, XRRScreenResources*, RROutput); - using tXRRFreeOutputInfo = void (*) (XRROutputInfo*); - using tXRRGetCrtcInfo = XRRCrtcInfo* (*) (::Display*, XRRScreenResources*, RRCrtc); - using tXRRFreeCrtcInfo = void (*) (XRRCrtcInfo*); - using tXRRGetOutputPrimary = RROutput (*) (::Display*, ::Window); - - void* libXrandr = nullptr; - tXRRGetScreenResources getScreenResourcesPtr = nullptr; - tXRRFreeScreenResources freeScreenResourcesPtr = nullptr; - tXRRGetOutputInfo getOutputInfoPtr = nullptr; - tXRRFreeOutputInfo freeOutputInfoPtr = nullptr; - tXRRGetCrtcInfo getCrtcInfoPtr = nullptr; - tXRRFreeCrtcInfo freeCrtcInfoPtr = nullptr; - tXRRGetOutputPrimary getOutputPrimaryPtr = nullptr; -}; -#endif - - -static double getDisplayDPI (::Display* display, int index) -{ - auto widthMM = DisplayWidthMM (display, index); - auto heightMM = DisplayHeightMM (display, index); - - if (widthMM > 0 && heightMM > 0) - return (((DisplayWidth (display, index) * 25.4) / widthMM) + ((DisplayHeight (display, index) * 25.4) / heightMM)) / 2.0; - - return 96.0; -} - -static double getScaleForDisplay (const String& name, double dpi) -{ - if (name.isNotEmpty()) - { - // Ubuntu and derived distributions now save a per-display scale factor as a configuration - // variable. This can be changed in the Monitor system settings panel. - ChildProcess dconf; - - if (File ("/usr/bin/dconf").existsAsFile() - && dconf.start ("/usr/bin/dconf read /com/ubuntu/user-interface/scale-factor", ChildProcess::wantStdOut)) - { - if (dconf.waitForProcessToFinish (200)) - { - auto jsonOutput = dconf.readAllProcessOutput().replaceCharacter ('\'', '"'); - - if (dconf.getExitCode() == 0 && jsonOutput.isNotEmpty()) - { - auto jsonVar = JSON::parse (jsonOutput); - - if (auto* object = jsonVar.getDynamicObject()) - { - auto scaleFactorVar = object->getProperty (name); - - if (! scaleFactorVar.isVoid()) - { - auto scaleFactor = ((double) scaleFactorVar) / 8.0; - - if (scaleFactor > 0.0) - return scaleFactor; - } - } - } - } - } - } - - { - // Other gnome based distros now use gsettings for a global scale factor - ChildProcess gsettings; - - if (File ("/usr/bin/gsettings").existsAsFile() - && gsettings.start ("/usr/bin/gsettings get org.gnome.desktop.interface scaling-factor", ChildProcess::wantStdOut)) - { - if (gsettings.waitForProcessToFinish (200)) - { - auto gsettingsOutput = StringArray::fromTokens (gsettings.readAllProcessOutput(), true); - - if (gsettingsOutput.size() >= 2 && gsettingsOutput[1].length() > 0) - { - auto scaleFactor = gsettingsOutput[1].getDoubleValue(); - - if (scaleFactor > 0.0) - return scaleFactor; - - return 1.0; - } - } - } - } - - // If no scale factor is set by GNOME or Ubuntu then calculate from monitor dpi - // We use the same approach as chromium which simply divides the dpi by 96 - // and then rounds the result - return round (dpi / 96.0); -} - -//=============================== X11 - Pixmap ================================= - -namespace PixmapHelpers -{ - Pixmap createColourPixmapFromImage (::Display* display, const Image& image) - { - ScopedXLock xlock (display); - - auto width = (unsigned int) image.getWidth(); - auto height = (unsigned int) image.getHeight(); - HeapBlock<uint32> colour (width * height); - int index = 0; - - for (int y = 0; y < (int) height; ++y) - for (int x = 0; x < (int) width; ++x) - colour[index++] = image.getPixelAt (x, y).getARGB(); - - XImage* ximage = XCreateImage (display, CopyFromParent, 24, ZPixmap, - 0, reinterpret_cast<char*> (colour.getData()), - width, height, 32, 0); - - Pixmap pixmap = XCreatePixmap (display, DefaultRootWindow (display), - width, height, 24); - - GC gc = XCreateGC (display, pixmap, 0, nullptr); - XPutImage (display, pixmap, gc, ximage, 0, 0, 0, 0, width, height); - XFreeGC (display, gc); - - return pixmap; - } - - Pixmap createMaskPixmapFromImage (::Display* display, const Image& image) - { - ScopedXLock xlock (display); - - auto width = (unsigned int) image.getWidth(); - auto height = (unsigned int) image.getHeight(); - auto stride = (width + 7) >> 3; - HeapBlock<char> mask; - mask.calloc (stride * height); - const bool msbfirst = (BitmapBitOrder (display) == MSBFirst); - - for (unsigned int y = 0; y < height; ++y) - { - for (unsigned int x = 0; x < width; ++x) - { - auto bit = (char) (1 << (msbfirst ? (7 - (x & 7)) : (x & 7))); - const unsigned int offset = y * stride + (x >> 3); - - if (image.getPixelAt ((int) x, (int) y).getAlpha() >= 128) - mask[offset] |= bit; - } - } - - return XCreatePixmapFromBitmapData (display, DefaultRootWindow (display), - mask.getData(), width, height, 1, 0, 1); - } -} - -static void* createDraggingHandCursor() -{ - static unsigned char dragHandData[] = { 71,73,70,56,57,97,16,0,16,0,145,2,0,0,0,0,255,255,255,0, - 0,0,0,0,0,33,249,4,1,0,0,2,0,44,0,0,0,0,16,0, 16,0,0,2,52,148,47,0,200,185,16,130,90,12,74,139,107,84,123,39, - 132,117,151,116,132,146,248,60,209,138,98,22,203,114,34,236,37,52,77,217, 247,154,191,119,110,240,193,128,193,95,163,56,60,234,98,135,2,0,59 }; - size_t dragHandDataSize = 99; - - return CustomMouseCursorInfo (ImageFileFormat::loadFrom (dragHandData, dragHandDataSize), { 8, 7 }).create(); -} - -//============================================================================== -static int numAlwaysOnTopPeers = 0; - -bool juce_areThereAnyAlwaysOnTopWindows() -{ - return numAlwaysOnTopPeers > 0; -} - -//============================================================================== -class LinuxComponentPeer : public ComponentPeer -{ -public: - LinuxComponentPeer (Component& comp, int windowStyleFlags, Window parentToAddTo) - : ComponentPeer (comp, windowStyleFlags), - isAlwaysOnTop (comp.isAlwaysOnTop()) - { - // it's dangerous to create a window on a thread other than the message thread.. - JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED - - display = XWindowSystem::getInstance()->displayRef(); - - atoms.reset (new Atoms (display)); - dragState.reset (new DragState (display)); - repainter.reset (new LinuxRepaintManager (*this, display)); - - if (isAlwaysOnTop) - ++numAlwaysOnTopPeers; - - createWindow (parentToAddTo); - - setTitle (component.getName()); - - getNativeRealtimeModifiers = [] - { - ScopedXDisplay xDisplay; - - if (auto d = xDisplay.display) - { - Window root, child; - int x, y, winx, winy; - unsigned int mask; - int mouseMods = 0; - - ScopedXLock xlock (d); - - if (XQueryPointer (d, RootWindow (d, DefaultScreen (d)), - &root, &child, &x, &y, &winx, &winy, &mask) != False) - { - if ((mask & Button1Mask) != 0) mouseMods |= ModifierKeys::leftButtonModifier; - if ((mask & Button2Mask) != 0) mouseMods |= ModifierKeys::middleButtonModifier; - if ((mask & Button3Mask) != 0) mouseMods |= ModifierKeys::rightButtonModifier; - } - - ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withoutMouseButtons().withFlags (mouseMods); - } - - return ModifierKeys::currentModifiers; - }; - } - - ~LinuxComponentPeer() override - { - // it's dangerous to delete a window on a thread other than the message thread.. - JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED - - #if JUCE_X11_SUPPORTS_XEMBED - juce_handleXEmbedEvent (this, nullptr); - #endif - - deleteIconPixmaps(); - destroyWindow(); - windowH = 0; - - if (isAlwaysOnTop) - --numAlwaysOnTopPeers; - - // delete before display - repainter = nullptr; - - display = XWindowSystem::getInstance()->displayUnref(); - } - - //============================================================================== - void* getNativeHandle() const override - { - return (void*) windowH; - } - - static LinuxComponentPeer* getPeerFor (Window windowHandle) noexcept - { - XPointer peer = nullptr; - - if (display != nullptr) - { - ScopedXLock xlock (display); - - if (! XFindContext (display, (XID) windowHandle, windowHandleXContext, &peer)) - if (peer != nullptr && ! ComponentPeer::isValidPeer (reinterpret_cast<LinuxComponentPeer*> (peer))) - peer = nullptr; - } - - return reinterpret_cast<LinuxComponentPeer*> (peer); - } - - void setVisible (bool shouldBeVisible) override - { - ScopedXLock xlock (display); - - if (shouldBeVisible) - XMapWindow (display, windowH); - else - XUnmapWindow (display, windowH); - } - - void setTitle (const String& title) override - { - XTextProperty nameProperty; - char* strings[] = { const_cast<char*> (title.toRawUTF8()) }; - ScopedXLock xlock (display); - - if (XStringListToTextProperty (strings, 1, &nameProperty)) - { - XSetWMName (display, windowH, &nameProperty); - XSetWMIconName (display, windowH, &nameProperty); - - XFree (nameProperty.value); - } - } - - void updateScaleFactorFromNewBounds (const Rectangle<int>& newBounds, bool isPhysical) - { - Point<int> translation = (parentWindow != 0 ? getScreenPosition (isPhysical) : Point<int>()); - - auto newScaleFactor = Desktop::getInstance().getDisplays().findDisplayForRect (newBounds.translated (translation.x, translation.y), isPhysical).scale - / Desktop::getInstance().getGlobalScaleFactor(); - - if (! approximatelyEqual (newScaleFactor, currentScaleFactor)) - { - currentScaleFactor = newScaleFactor; - scaleFactorListeners.call ([&] (ScaleFactorListener& l) { l.nativeScaleFactorChanged (currentScaleFactor); }); - } - } - - void setBounds (const Rectangle<int>& newBounds, bool isNowFullScreen) override - { - if (fullScreen && ! isNowFullScreen) - { - // When transitioning back from fullscreen, we might need to remove - // the FULLSCREEN window property - Atom fs = Atoms::getIfExists (display, "_NET_WM_STATE_FULLSCREEN"); - - if (fs != None) - { - Window root = RootWindow (display, DefaultScreen (display)); - - XClientMessageEvent clientMsg; - clientMsg.display = display; - clientMsg.window = windowH; - clientMsg.type = ClientMessage; - clientMsg.format = 32; - clientMsg.message_type = atoms->windowState; - clientMsg.data.l[0] = 0; // Remove - clientMsg.data.l[1] = (long) fs; - clientMsg.data.l[2] = 0; - clientMsg.data.l[3] = 1; // Normal Source - - ScopedXLock xlock (display); - XSendEvent (display, root, false, - SubstructureRedirectMask | SubstructureNotifyMask, - (XEvent*) &clientMsg); - } - } - - fullScreen = isNowFullScreen; - - if (windowH != 0) - { - bounds = newBounds.withSize (jmax (1, newBounds.getWidth()), - jmax (1, newBounds.getHeight())); - - updateScaleFactorFromNewBounds (bounds, false); - - auto physicalBounds = (parentWindow == 0 ? Desktop::getInstance().getDisplays().logicalToPhysical (bounds) - : bounds * currentScaleFactor); - - WeakReference<Component> deletionChecker (&component); - ScopedXLock xlock (display); - - auto* hints = XAllocSizeHints(); - hints->flags = USSize | USPosition; - hints->x = physicalBounds.getX(); - hints->y = physicalBounds.getY(); - hints->width = physicalBounds.getWidth(); - hints->height = physicalBounds.getHeight(); - - if ((getStyleFlags() & windowIsResizable) == 0) - { - hints->min_width = hints->max_width = hints->width; - hints->min_height = hints->max_height = hints->height; - hints->flags |= PMinSize | PMaxSize; - } - - XSetWMNormalHints (display, windowH, hints); - XFree (hints); - - XMoveResizeWindow (display, windowH, - physicalBounds.getX() - windowBorder.getLeft(), - physicalBounds.getY() - windowBorder.getTop(), - (unsigned int) physicalBounds.getWidth(), - (unsigned int) physicalBounds.getHeight()); - - if (deletionChecker != nullptr) - { - updateBorderSize(); - handleMovedOrResized(); - } - } - } - - Point<int> getScreenPosition (bool physical) const - { - auto screenBounds = (parentWindow == 0 ? bounds - : bounds.translated (parentScreenPosition.x, parentScreenPosition.y)); - - if (physical) - return Desktop::getInstance().getDisplays().logicalToPhysical (screenBounds.getTopLeft()); - - return screenBounds.getTopLeft(); - } - - Rectangle<int> getBounds() const override { return bounds; } - - using ComponentPeer::localToGlobal; - Point<float> localToGlobal (Point<float> relativePosition) override { return relativePosition + getScreenPosition (false).toFloat(); } - - using ComponentPeer::globalToLocal; - Point<float> globalToLocal (Point<float> screenPosition) override { return screenPosition - getScreenPosition (false).toFloat(); } - - void setAlpha (float /* newAlpha */) override - { - //xxx todo! - } - - StringArray getAvailableRenderingEngines() override - { - return StringArray ("Software Renderer"); - } - - void setMinimised (bool shouldBeMinimised) override - { - if (shouldBeMinimised) - { - Window root = RootWindow (display, DefaultScreen (display)); - - XClientMessageEvent clientMsg; - clientMsg.display = display; - clientMsg.window = windowH; - clientMsg.type = ClientMessage; - clientMsg.format = 32; - clientMsg.message_type = atoms->changeState; - clientMsg.data.l[0] = IconicState; - - ScopedXLock xlock (display); - XSendEvent (display, root, false, SubstructureRedirectMask | SubstructureNotifyMask, (XEvent*) &clientMsg); - } - else - { - setVisible (true); - } - } - - bool isMinimised() const override - { - ScopedXLock xlock (display); - GetXProperty prop (display, windowH, atoms->state, 0, 64, false, atoms->state); - - if (prop.success && prop.actualType == atoms->state - && prop.actualFormat == 32 && prop.numItems > 0) - { - unsigned long state; - memcpy (&state, prop.data, sizeof (unsigned long)); - - return state == IconicState; - } - - return false; - } - - void setFullScreen (bool shouldBeFullScreen) override - { - auto r = lastNonFullscreenBounds; // (get a copy of this before de-minimising) - - setMinimised (false); - - if (fullScreen != shouldBeFullScreen) - { - if (shouldBeFullScreen) - r = Desktop::getInstance().getDisplays().getMainDisplay().userArea; - - if (! r.isEmpty()) - setBounds (ScalingHelpers::scaledScreenPosToUnscaled (component, r), shouldBeFullScreen); - - component.repaint(); - } - } - - bool isFullScreen() const override - { - return fullScreen; - } - - bool isChildWindowOf (Window possibleParent) const - { - Window* windowList = nullptr; - uint32 windowListSize = 0; - Window parent, root; - - ScopedXLock xlock (display); - if (XQueryTree (display, windowH, &root, &parent, &windowList, &windowListSize) != 0) - { - if (windowList != nullptr) - XFree (windowList); - - return parent == possibleParent; - } - - return false; - } - - bool isParentWindowOf (Window possibleChild) const - { - if (windowH != 0 && possibleChild != 0) - { - if (possibleChild == windowH) - return true; - - Window* windowList = nullptr; - uint32 windowListSize = 0; - Window parent, root; - - ScopedXLock xlock (display); - if (XQueryTree (display, possibleChild, &root, &parent, &windowList, &windowListSize) != 0) - { - if (windowList != nullptr) - XFree (windowList); - - if (parent == root) - return false; - - return isParentWindowOf (parent); - } - } - - return false; - } - - bool isFrontWindow() const - { - Window* windowList = nullptr; - uint32 windowListSize = 0; - bool result = false; - - ScopedXLock xlock (display); - Window parent, root = RootWindow (display, DefaultScreen (display)); - - if (XQueryTree (display, root, &root, &parent, &windowList, &windowListSize) != 0) - { - for (int i = (int) windowListSize; --i >= 0;) - { - if (auto* peer = LinuxComponentPeer::getPeerFor (windowList[i])) - { - result = (peer == this); - break; - } - } - } - - if (windowList != nullptr) - XFree (windowList); - - return result; - } - - bool contains (Point<int> localPos, bool trueIfInAChildWindow) const override - { - if (! bounds.withZeroOrigin().contains (localPos)) - return false; - - for (int i = Desktop::getInstance().getNumComponents(); --i >= 0;) - { - auto* c = Desktop::getInstance().getComponent (i); - - if (c == &component) - break; - - if (! c->isVisible()) - continue; - - if (auto* peer = c->getPeer()) - if (peer->contains (localPos + bounds.getPosition() - peer->getBounds().getPosition(), true)) - return false; - } - - if (trueIfInAChildWindow) - return true; - - ::Window root, child; - int wx, wy; - unsigned int ww, wh, bw, bitDepth; - - ScopedXLock xlock (display); - - localPos *= currentScaleFactor; - - return XGetGeometry (display, (::Drawable) windowH, &root, &wx, &wy, &ww, &wh, &bw, &bitDepth) - && XTranslateCoordinates (display, windowH, windowH, localPos.getX(), localPos.getY(), &wx, &wy, &child) - && child == None; - } - - BorderSize<int> getFrameSize() const override - { - return {}; - } - - bool setAlwaysOnTop (bool /* alwaysOnTop */) override - { - return false; - } - - void toFront (bool makeActive) override - { - if (makeActive) - { - setVisible (true); - grabFocus(); - } - - { - ScopedXLock xlock (display); - XEvent ev; - ev.xclient.type = ClientMessage; - ev.xclient.serial = 0; - ev.xclient.send_event = True; - ev.xclient.message_type = atoms->activeWin; - ev.xclient.window = windowH; - ev.xclient.format = 32; - ev.xclient.data.l[0] = 2; - ev.xclient.data.l[1] = getUserTime(); - ev.xclient.data.l[2] = 0; - ev.xclient.data.l[3] = 0; - ev.xclient.data.l[4] = 0; - - XSendEvent (display, RootWindow (display, DefaultScreen (display)), - False, SubstructureRedirectMask | SubstructureNotifyMask, &ev); - - XSync (display, False); - } - - handleBroughtToFront(); - } - - void toBehind (ComponentPeer* other) override - { - if (auto* otherPeer = dynamic_cast<LinuxComponentPeer*> (other)) - { - if (otherPeer->styleFlags & windowIsTemporary) - return; - - setMinimised (false); - - Window newStack[] = { otherPeer->windowH, windowH }; - - ScopedXLock xlock (display); - XRestackWindows (display, newStack, 2); - } - else - jassertfalse; // wrong type of window? - } - - bool isFocused() const override - { - int revert = 0; - Window focusedWindow = 0; - ScopedXLock xlock (display); - XGetInputFocus (display, &focusedWindow, &revert); - - if (focusedWindow == PointerRoot) - return false; - - return isParentWindowOf (focusedWindow); - } - - Window getFocusWindow() - { - #if JUCE_X11_SUPPORTS_XEMBED - if (Window w = (Window) juce_getCurrentFocusWindow (this)) - return w; - #endif - - return windowH; - } - - void grabFocus() override - { - XWindowAttributes atts; - ScopedXLock xlock (display); - - if (windowH != 0 - && XGetWindowAttributes (display, windowH, &atts) - && atts.map_state == IsViewable - && ! isFocused()) - { - XSetInputFocus (display, getFocusWindow(), RevertToParent, (::Time) getUserTime()); - isActiveApplication = true; - } - } - - void textInputRequired (Point<int>, TextInputTarget&) override {} - - void repaint (const Rectangle<int>& area) override - { - repainter->repaint (area.getIntersection (bounds.withZeroOrigin())); - } - - void performAnyPendingRepaintsNow() override - { - repainter->performAnyPendingRepaintsNow(); - } - - void setIcon (const Image& newIcon) override - { - const int dataSize = newIcon.getWidth() * newIcon.getHeight() + 2; - HeapBlock<unsigned long> data (dataSize); - - int index = 0; - data[index++] = (unsigned long) newIcon.getWidth(); - data[index++] = (unsigned long) newIcon.getHeight(); - - for (int y = 0; y < newIcon.getHeight(); ++y) - for (int x = 0; x < newIcon.getWidth(); ++x) - data[index++] = (unsigned long) newIcon.getPixelAt (x, y).getARGB(); - - ScopedXLock xlock (display); - xchangeProperty (windowH, Atoms::getCreating (display, "_NET_WM_ICON"), XA_CARDINAL, 32, data.getData(), dataSize); - - deleteIconPixmaps(); - - XWMHints* wmHints = XGetWMHints (display, windowH); - - if (wmHints == nullptr) - wmHints = XAllocWMHints(); - - wmHints->flags |= IconPixmapHint | IconMaskHint; - wmHints->icon_pixmap = PixmapHelpers::createColourPixmapFromImage (display, newIcon); - wmHints->icon_mask = PixmapHelpers::createMaskPixmapFromImage (display, newIcon); - - XSetWMHints (display, windowH, wmHints); - XFree (wmHints); - - XSync (display, False); - } - - void deleteIconPixmaps() - { - ScopedXLock xlock (display); - - if (auto* wmHints = XGetWMHints (display, windowH)) - { - if ((wmHints->flags & IconPixmapHint) != 0) - { - wmHints->flags &= ~IconPixmapHint; - XFreePixmap (display, wmHints->icon_pixmap); - } - - if ((wmHints->flags & IconMaskHint) != 0) - { - wmHints->flags &= ~IconMaskHint; - XFreePixmap (display, wmHints->icon_mask); - } - - XSetWMHints (display, windowH, wmHints); - XFree (wmHints); - } - } - - //============================================================================== - void handleWindowMessage (XEvent& event) - { - switch (event.xany.type) - { - case KeyPressEventType: handleKeyPressEvent (event.xkey); break; - case KeyRelease: handleKeyReleaseEvent (event.xkey); break; - case ButtonPress: handleButtonPressEvent (event.xbutton); break; - case ButtonRelease: handleButtonReleaseEvent (event.xbutton); break; - case MotionNotify: handleMotionNotifyEvent (event.xmotion); break; - case EnterNotify: handleEnterNotifyEvent (event.xcrossing); break; - case LeaveNotify: handleLeaveNotifyEvent (event.xcrossing); break; - case FocusIn: handleFocusInEvent(); break; - case FocusOut: handleFocusOutEvent(); break; - case Expose: handleExposeEvent (event.xexpose); break; - case MappingNotify: handleMappingNotify (event.xmapping); break; - case ClientMessage: handleClientMessageEvent (event.xclient, event); break; - case SelectionNotify: handleDragAndDropSelection (event); break; - case ConfigureNotify: handleConfigureNotifyEvent (event.xconfigure); break; - case ReparentNotify: - case GravityNotify: handleGravityNotify(); break; - case SelectionClear: handleExternalSelectionClear(); break; - case SelectionRequest: handleExternalSelectionRequest (event); break; - - case CirculateNotify: - case CreateNotify: - case DestroyNotify: - // Think we can ignore these - break; - - case MapNotify: - mapped = true; - handleBroughtToFront(); - break; - - case UnmapNotify: - mapped = false; - break; - - default: - #if JUCE_USE_XSHM - if (XSHMHelpers::isShmAvailable (display)) - { - ScopedXLock xlock (display); - if (event.xany.type == shmCompletionEvent) - repainter->notifyPaintCompleted(); - } - #endif - break; - } - } - - void handleKeyPressEvent (XKeyEvent& keyEvent) - { - auto oldMods = ModifierKeys::currentModifiers; - - char utf8 [64] = { 0 }; - juce_wchar unicodeChar = 0; - int keyCode = 0; - bool keyDownChange = false; - KeySym sym; - - { - ScopedXLock xlock (display); - updateKeyStates ((int) keyEvent.keycode, true); - - String oldLocale (::setlocale (LC_ALL, nullptr)); - ::setlocale (LC_ALL, ""); - XLookupString (&keyEvent, utf8, sizeof (utf8), &sym, nullptr); - - if (oldLocale.isNotEmpty()) - ::setlocale (LC_ALL, oldLocale.toRawUTF8()); - - unicodeChar = *CharPointer_UTF8 (utf8); - keyCode = (int) unicodeChar; - - if (keyCode < 0x20) - keyCode = (int) XkbKeycodeToKeysym (display, (::KeyCode) keyEvent.keycode, 0, ModifierKeys::currentModifiers.isShiftDown() ? 1 : 0); - - keyDownChange = (sym != NoSymbol) && ! updateKeyModifiersFromSym (sym, true); - } - - bool keyPressed = false; - - if ((sym & 0xff00) == 0xff00 || keyCode == XK_ISO_Left_Tab) - { - switch (sym) // Translate keypad - { - case XK_KP_Add: keyCode = XK_plus; break; - case XK_KP_Subtract: keyCode = XK_hyphen; break; - case XK_KP_Divide: keyCode = XK_slash; break; - case XK_KP_Multiply: keyCode = XK_asterisk; break; - case XK_KP_Enter: keyCode = XK_Return; break; - case XK_KP_Insert: keyCode = XK_Insert; break; - case XK_Delete: - case XK_KP_Delete: keyCode = XK_Delete; break; - case XK_KP_Left: keyCode = XK_Left; break; - case XK_KP_Right: keyCode = XK_Right; break; - case XK_KP_Up: keyCode = XK_Up; break; - case XK_KP_Down: keyCode = XK_Down; break; - case XK_KP_Home: keyCode = XK_Home; break; - case XK_KP_End: keyCode = XK_End; break; - case XK_KP_Page_Down: keyCode = XK_Page_Down; break; - case XK_KP_Page_Up: keyCode = XK_Page_Up; break; - - case XK_KP_0: keyCode = XK_0; break; - case XK_KP_1: keyCode = XK_1; break; - case XK_KP_2: keyCode = XK_2; break; - case XK_KP_3: keyCode = XK_3; break; - case XK_KP_4: keyCode = XK_4; break; - case XK_KP_5: keyCode = XK_5; break; - case XK_KP_6: keyCode = XK_6; break; - case XK_KP_7: keyCode = XK_7; break; - case XK_KP_8: keyCode = XK_8; break; - case XK_KP_9: keyCode = XK_9; break; - - default: break; - } - - switch (keyCode) - { - case XK_Left: - case XK_Right: - case XK_Up: - case XK_Down: - case XK_Page_Up: - case XK_Page_Down: - case XK_End: - case XK_Home: - case XK_Delete: - case XK_Insert: - keyPressed = true; - keyCode = (keyCode & 0xff) | Keys::extendedKeyModifier; - break; - - case XK_Tab: - case XK_Return: - case XK_Escape: - case XK_BackSpace: - keyPressed = true; - keyCode &= 0xff; - break; - - case XK_ISO_Left_Tab: - keyPressed = true; - keyCode = XK_Tab & 0xff; - break; - - default: - if (sym >= XK_F1 && sym <= XK_F35) - { - keyPressed = true; - keyCode = (sym & 0xff) | Keys::extendedKeyModifier; - } - break; - } - } - - if (utf8[0] != 0 || ((sym & 0xff00) == 0 && sym >= 8)) - keyPressed = true; - - if (oldMods != ModifierKeys::currentModifiers) - handleModifierKeysChange(); - - if (keyDownChange) - handleKeyUpOrDown (true); - - if (keyPressed) - handleKeyPress (keyCode, unicodeChar); - } - - static bool isKeyReleasePartOfAutoRepeat (const XKeyEvent& keyReleaseEvent) - { - if (XPending (display)) - { - XEvent e; - XPeekEvent (display, &e); - - // Look for a subsequent key-down event with the same timestamp and keycode - return e.type == KeyPressEventType - && e.xkey.keycode == keyReleaseEvent.keycode - && e.xkey.time == keyReleaseEvent.time; - } - - return false; - } - - void handleKeyReleaseEvent (const XKeyEvent& keyEvent) - { - if (! isKeyReleasePartOfAutoRepeat (keyEvent)) - { - updateKeyStates ((int) keyEvent.keycode, false); - KeySym sym; - - { - ScopedXLock xlock (display); - sym = XkbKeycodeToKeysym (display, (::KeyCode) keyEvent.keycode, 0, 0); - } - - auto oldMods = ModifierKeys::currentModifiers; - const bool keyDownChange = (sym != NoSymbol) && ! updateKeyModifiersFromSym (sym, false); - - if (oldMods != ModifierKeys::currentModifiers) - handleModifierKeysChange(); - - if (keyDownChange) - handleKeyUpOrDown (false); - } - } - - template <typename EventType> - Point<float> getMousePos (const EventType& e) noexcept - { - return Point<float> ((float) e.x, (float) e.y) / currentScaleFactor; - } - - void handleWheelEvent (const XButtonPressedEvent& buttonPressEvent, float amount) - { - MouseWheelDetails wheel; - wheel.deltaX = 0.0f; - wheel.deltaY = amount; - wheel.isReversed = false; - wheel.isSmooth = false; - wheel.isInertial = false; - - handleMouseWheel (MouseInputSource::InputSourceType::mouse, getMousePos (buttonPressEvent), - getEventTime (buttonPressEvent), wheel); - } - - void handleButtonPressEvent (const XButtonPressedEvent& buttonPressEvent, int buttonModifierFlag) - { - ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withFlags (buttonModifierFlag); - toFront (true); - handleMouseEvent (MouseInputSource::InputSourceType::mouse, getMousePos (buttonPressEvent), ModifierKeys::currentModifiers, - MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, getEventTime (buttonPressEvent), {}); - } - - void handleButtonPressEvent (const XButtonPressedEvent& buttonPressEvent) - { - updateKeyModifiers ((int) buttonPressEvent.state); - - auto mapIndex = (uint32) (buttonPressEvent.button - Button1); - - if (mapIndex < (uint32) numElementsInArray (pointerMap)) - { - switch (pointerMap[mapIndex]) - { - case Keys::WheelUp: handleWheelEvent (buttonPressEvent, 50.0f / 256.0f); break; - case Keys::WheelDown: handleWheelEvent (buttonPressEvent, -50.0f / 256.0f); break; - case Keys::LeftButton: handleButtonPressEvent (buttonPressEvent, ModifierKeys::leftButtonModifier); break; - case Keys::RightButton: handleButtonPressEvent (buttonPressEvent, ModifierKeys::rightButtonModifier); break; - case Keys::MiddleButton: handleButtonPressEvent (buttonPressEvent, ModifierKeys::middleButtonModifier); break; - default: break; - } - } - - clearLastMousePos(); - } - - void handleButtonReleaseEvent (const XButtonReleasedEvent& buttonRelEvent) - { - updateKeyModifiers ((int) buttonRelEvent.state); - - if (parentWindow != 0) - updateWindowBounds(); - - auto mapIndex = (uint32) (buttonRelEvent.button - Button1); - - if (mapIndex < (uint32) numElementsInArray (pointerMap)) - { - switch (pointerMap[mapIndex]) - { - case Keys::LeftButton: ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withoutFlags (ModifierKeys::leftButtonModifier); break; - case Keys::RightButton: ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withoutFlags (ModifierKeys::rightButtonModifier); break; - case Keys::MiddleButton: ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withoutFlags (ModifierKeys::middleButtonModifier); break; - default: break; - } - } - - if (dragState->dragging) - handleExternalDragButtonReleaseEvent(); - - handleMouseEvent (MouseInputSource::InputSourceType::mouse, getMousePos (buttonRelEvent), ModifierKeys::currentModifiers, - MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, getEventTime (buttonRelEvent)); - - clearLastMousePos(); - } - - void handleMotionNotifyEvent (const XPointerMovedEvent& movedEvent) - { - updateKeyModifiers ((int) movedEvent.state); - - lastMousePos = Point<int> (movedEvent.x_root, movedEvent.y_root); - - if (dragState->dragging) - handleExternalDragMotionNotify(); - - handleMouseEvent (MouseInputSource::InputSourceType::mouse, getMousePos (movedEvent), ModifierKeys::currentModifiers, - MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, getEventTime (movedEvent)); - } - - void handleEnterNotifyEvent (const XEnterWindowEvent& enterEvent) - { - if (parentWindow != 0) - updateWindowBounds(); - - clearLastMousePos(); - - if (! ModifierKeys::currentModifiers.isAnyMouseButtonDown()) - { - updateKeyModifiers ((int) enterEvent.state); - handleMouseEvent (MouseInputSource::InputSourceType::mouse, getMousePos (enterEvent), ModifierKeys::currentModifiers, - MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, getEventTime (enterEvent)); - } - } - - void handleLeaveNotifyEvent (const XLeaveWindowEvent& leaveEvent) - { - // Suppress the normal leave if we've got a pointer grab, or if - // it's a bogus one caused by clicking a mouse button when running - // in a Window manager - if (((! ModifierKeys::currentModifiers.isAnyMouseButtonDown()) && leaveEvent.mode == NotifyNormal) - || leaveEvent.mode == NotifyUngrab) - { - updateKeyModifiers ((int) leaveEvent.state); - handleMouseEvent (MouseInputSource::InputSourceType::mouse, getMousePos (leaveEvent), ModifierKeys::currentModifiers, - MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, getEventTime (leaveEvent)); - } - } - - void handleFocusInEvent() - { - isActiveApplication = true; - - if (isFocused() && ! focused) - { - focused = true; - handleFocusGain(); - } - } - - void handleFocusOutEvent() - { - if (! isFocused() && focused) - { - focused = false; - isActiveApplication = false; - - handleFocusLoss(); - } - } - - void handleExposeEvent (XExposeEvent& exposeEvent) - { - // Batch together all pending expose events - XEvent nextEvent; - ScopedXLock xlock (display); - - // if we have opengl contexts then just repaint them all - // regardless if this is really necessary - repaintOpenGLContexts(); - - if (exposeEvent.window != windowH) - { - Window child; - XTranslateCoordinates (display, exposeEvent.window, windowH, - exposeEvent.x, exposeEvent.y, &exposeEvent.x, &exposeEvent.y, - &child); - } - - // exposeEvent is in local window local coordinates so do not convert with - // physicalToScaled, but rather use currentScaleFactor - repaint (Rectangle<int> (exposeEvent.x, exposeEvent.y, - exposeEvent.width, exposeEvent.height) / currentScaleFactor); - - while (XEventsQueued (display, QueuedAfterFlush) > 0) - { - XPeekEvent (display, &nextEvent); - - if (nextEvent.type != Expose || nextEvent.xany.window != exposeEvent.window) - break; - - XNextEvent (display, &nextEvent); - auto& nextExposeEvent = (const XExposeEvent&) nextEvent.xexpose; - repaint (Rectangle<int> (nextExposeEvent.x, nextExposeEvent.y, - nextExposeEvent.width, nextExposeEvent.height) / currentScaleFactor); - } - } - - void handleConfigureNotifyEvent (XConfigureEvent& confEvent) - { - updateWindowBounds(); - updateBorderSize(); - handleMovedOrResized(); - - // if the native title bar is dragged, need to tell any active menus, etc. - if ((styleFlags & windowHasTitleBar) != 0 - && component.isCurrentlyBlockedByAnotherModalComponent()) - { - if (auto* currentModalComp = Component::getCurrentlyModalComponent()) - currentModalComp->inputAttemptWhenModal(); - } - - if (confEvent.window == windowH && confEvent.above != 0 && isFrontWindow()) - handleBroughtToFront(); - } - - void handleGravityNotify() - { - updateWindowBounds(); - updateBorderSize(); - handleMovedOrResized(); - } - - void handleMappingNotify (XMappingEvent& mappingEvent) - { - if (mappingEvent.request != MappingPointer) - { - // Deal with modifier/keyboard mapping - ScopedXLock xlock (display); - XRefreshKeyboardMapping (&mappingEvent); - updateModifierMappings(); - } - } - - void handleClientMessageEvent (XClientMessageEvent& clientMsg, XEvent& event) - { - if (clientMsg.message_type == atoms->protocols && clientMsg.format == 32) - { - auto atom = (Atom) clientMsg.data.l[0]; - - if (atom == atoms->protocolList [Atoms::PING]) - { - Window root = RootWindow (display, DefaultScreen (display)); - - clientMsg.window = root; - - XSendEvent (display, root, False, NoEventMask, &event); - XFlush (display); - } - else if (atom == atoms->protocolList [Atoms::TAKE_FOCUS]) - { - if ((getStyleFlags() & juce::ComponentPeer::windowIgnoresKeyPresses) == 0) - { - XWindowAttributes atts; - - ScopedXLock xlock (display); - if (clientMsg.window != 0 - && XGetWindowAttributes (display, clientMsg.window, &atts)) - { - if (atts.map_state == IsViewable) - XSetInputFocus (display, - (clientMsg.window == windowH ? getFocusWindow() - : clientMsg.window), - RevertToParent, - (::Time) clientMsg.data.l[1]); - } - } - } - else if (atom == atoms->protocolList [Atoms::DELETE_WINDOW]) - { - handleUserClosingWindow(); - } - } - else if (clientMsg.message_type == atoms->XdndEnter) - { - handleDragAndDropEnter (clientMsg); - } - else if (clientMsg.message_type == atoms->XdndLeave) - { - handleDragExit (dragInfo); - resetDragAndDrop(); - } - else if (clientMsg.message_type == atoms->XdndPosition) - { - handleDragAndDropPosition (clientMsg); - } - else if (clientMsg.message_type == atoms->XdndDrop) - { - handleDragAndDropDrop (clientMsg); - } - else if (clientMsg.message_type == atoms->XdndStatus) - { - handleExternalDragAndDropStatus (clientMsg); - } - else if (clientMsg.message_type == atoms->XdndFinished) - { - externalResetDragAndDrop(); - } - else if (clientMsg.message_type == atoms->XembedMsgType && clientMsg.format == 32) - { - handleXEmbedMessage (clientMsg); - } - } - - bool externalDragTextInit (const String& text, std::function<void()> cb) - { - if (dragState->dragging) - return false; - - return externalDragInit (true, text, cb); - } - - bool externalDragFileInit (const StringArray& files, bool /*canMoveFiles*/, std::function<void()> cb) - { - if (dragState->dragging) - return false; - - StringArray uriList; - - for (auto& f : files) - { - if (f.matchesWildcard ("?*://*", false)) - uriList.add (f); - else - uriList.add ("file://" + f); - } - - return externalDragInit (false, uriList.joinIntoString ("\r\n"), cb); - } - - void handleXEmbedMessage (XClientMessageEvent& clientMsg) - { - switch (clientMsg.data.l[1]) - { - case XEMBED_EMBEDDED_NOTIFY: - parentWindow = (::Window) clientMsg.data.l[3]; - updateWindowBounds(); - component.setBounds (bounds); - break; - case XEMBED_FOCUS_IN: - handleFocusInEvent(); - break; - case XEMBED_FOCUS_OUT: - handleFocusOutEvent(); - break; - - default: - break; - } - } - - //============================================================================== - void showMouseCursor (Cursor cursor) noexcept - { - ScopedXLock xlock (display); - XDefineCursor (display, windowH, cursor); - } - - //============================================================================== - double getPlatformScaleFactor() const noexcept override - { - return currentScaleFactor; - } - - //============================================================================== - void addOpenGLRepaintListener (Component* dummy) - { - if (dummy != nullptr) - glRepaintListeners.addIfNotAlreadyThere (dummy); - } - - void removeOpenGLRepaintListener (Component* dummy) - { - if (dummy != nullptr) - glRepaintListeners.removeAllInstancesOf (dummy); - } - - void repaintOpenGLContexts() - { - for (int i = 0; i < glRepaintListeners.size(); ++i) - if (auto* c = glRepaintListeners [i]) - c->handleCommandMessage (0); - } - - //============================================================================== - unsigned long createKeyProxy() - { - jassert (keyProxy == 0 && windowH != 0); - - if (keyProxy == 0 && windowH != 0) - { - XSetWindowAttributes swa; - swa.event_mask = KeyPressMask | KeyReleaseMask | FocusChangeMask; - - keyProxy = XCreateWindow (display, windowH, - -1, -1, 1, 1, 0, 0, - InputOnly, CopyFromParent, - CWEventMask, - &swa); - - XMapWindow (display, keyProxy); - XSaveContext (display, (XID) keyProxy, windowHandleXContext, (XPointer) this); - } - - return keyProxy; - } - - void deleteKeyProxy() - { - jassert (keyProxy != 0); - - if (keyProxy != 0) - { - XPointer handlePointer; - - if (! XFindContext (display, (XID) keyProxy, windowHandleXContext, &handlePointer)) - XDeleteContext (display, (XID) keyProxy, windowHandleXContext); - - XDestroyWindow (display, keyProxy); - XSync (display, false); - - XEvent event; - while (XCheckWindowEvent (display, keyProxy, getAllEventsMask(), &event) == True) - {} - - keyProxy = 0; - } - } - - //============================================================================== - bool dontRepaint; - static bool isActiveApplication; - -private: - //============================================================================== - class LinuxRepaintManager : public Timer - { - public: - LinuxRepaintManager (LinuxComponentPeer& p, ::Display* d) - : peer (p), display (d) - { - #if JUCE_USE_XSHM - useARGBImagesForRendering = XSHMHelpers::isShmAvailable (display); - - if (useARGBImagesForRendering) - { - ScopedXLock xlock (display); - XShmSegmentInfo segmentinfo; - - auto testImage = XShmCreateImage (display, DefaultVisual (display, DefaultScreen (display)), - 24, ZPixmap, nullptr, &segmentinfo, 64, 64); - - useARGBImagesForRendering = (testImage->bits_per_pixel == 32); - XDestroyImage (testImage); - } - #endif - } - - void timerCallback() override - { - #if JUCE_USE_XSHM - if (shmPaintsPending != 0) - { - ScopedXLock xlock (display); - - XEvent evt; - while (XCheckTypedWindowEvent (display, peer.windowH, peer.shmCompletionEvent, &evt)) - --shmPaintsPending; - } - - if (shmPaintsPending != 0) - return; - #endif - - if (! regionsNeedingRepaint.isEmpty()) - { - stopTimer(); - performAnyPendingRepaintsNow(); - } - else if (Time::getApproximateMillisecondCounter() > lastTimeImageUsed + 3000) - { - stopTimer(); - image = Image(); - } - } - - void repaint (Rectangle<int> area) - { - if (! isTimerRunning()) - startTimer (repaintTimerPeriod); - - regionsNeedingRepaint.add (area * peer.currentScaleFactor); - } - - void performAnyPendingRepaintsNow() - { - #if JUCE_USE_XSHM - if (shmPaintsPending != 0) - { - startTimer (repaintTimerPeriod); - return; - } - #endif - - auto originalRepaintRegion = regionsNeedingRepaint; - regionsNeedingRepaint.clear(); - auto totalArea = originalRepaintRegion.getBounds(); - - if (! totalArea.isEmpty()) - { - if (image.isNull() || image.getWidth() < totalArea.getWidth() - || image.getHeight() < totalArea.getHeight()) - { - #if JUCE_USE_XSHM - image = Image (new XBitmapImage (display, useARGBImagesForRendering ? Image::ARGB - : Image::RGB, - #else - image = Image (new XBitmapImage (display, Image::RGB, - #endif - (totalArea.getWidth() + 31) & ~31, - (totalArea.getHeight() + 31) & ~31, - false, (unsigned int) peer.depth, peer.visual)); - } - - startTimer (repaintTimerPeriod); - - RectangleList<int> adjustedList (originalRepaintRegion); - adjustedList.offsetAll (-totalArea.getX(), -totalArea.getY()); - - if (peer.depth == 32) - for (auto& i : originalRepaintRegion) - image.clear (i - totalArea.getPosition()); - - { - auto context = peer.getComponent().getLookAndFeel() - .createGraphicsContext (image, -totalArea.getPosition(), adjustedList); - - context->addTransform (AffineTransform::scale ((float) peer.currentScaleFactor)); - peer.handlePaint (*context); - } - - for (auto& i : originalRepaintRegion) - { - auto* xbitmap = static_cast<XBitmapImage*> (image.getPixelData()); - - #if JUCE_USE_XSHM - if (xbitmap->isUsingXShm()) - ++shmPaintsPending; - #endif - - - xbitmap->blitToWindow (peer.windowH, - i.getX(), i.getY(), - (unsigned int) i.getWidth(), - (unsigned int) i.getHeight(), - i.getX() - totalArea.getX(), i.getY() - totalArea.getY()); - } - } - - lastTimeImageUsed = Time::getApproximateMillisecondCounter(); - startTimer (repaintTimerPeriod); - } - - #if JUCE_USE_XSHM - void notifyPaintCompleted() noexcept { --shmPaintsPending; } - #endif - - private: - enum { repaintTimerPeriod = 1000 / 100 }; - - LinuxComponentPeer& peer; - Image image; - uint32 lastTimeImageUsed = 0; - RectangleList<int> regionsNeedingRepaint; - ::Display* display; - - #if JUCE_USE_XSHM - bool useARGBImagesForRendering; - int shmPaintsPending = 0; - #endif - JUCE_DECLARE_NON_COPYABLE (LinuxRepaintManager) - }; - - std::unique_ptr<Atoms> atoms; - std::unique_ptr<LinuxRepaintManager> repainter; - - friend class LinuxRepaintManager; - Window windowH = {}, parentWindow = {}, keyProxy = {}; - Rectangle<int> bounds; - Point<int> parentScreenPosition; - Image taskbarImage; - bool fullScreen = false, mapped = false, focused = false; - Visual* visual = {}; - int depth = 0; - BorderSize<int> windowBorder; - bool isAlwaysOnTop; - double currentScaleFactor = 1.0; - Array<Component*> glRepaintListeners; - enum { KeyPressEventType = 2 }; - static ::Display* display; - - #if JUCE_USE_XSHM - int shmCompletionEvent = 0; - #endif - - struct MotifWmHints - { - unsigned long flags; - unsigned long functions; - unsigned long decorations; - long input_mode; - unsigned long status; - }; - - static void updateKeyStates (int keycode, bool press) noexcept - { - const int keybyte = keycode >> 3; - const int keybit = (1 << (keycode & 7)); - - if (press) - Keys::keyStates [keybyte] |= keybit; - else - Keys::keyStates [keybyte] &= ~keybit; - } - - static void updateKeyModifiers (int status) noexcept - { - int keyMods = 0; - - if ((status & ShiftMask) != 0) keyMods |= ModifierKeys::shiftModifier; - if ((status & ControlMask) != 0) keyMods |= ModifierKeys::ctrlModifier; - if ((status & Keys::AltMask) != 0) keyMods |= ModifierKeys::altModifier; - - ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withOnlyMouseButtons().withFlags (keyMods); - - Keys::numLock = ((status & Keys::NumLockMask) != 0); - Keys::capsLock = ((status & LockMask) != 0); - } - - static bool updateKeyModifiersFromSym (KeySym sym, bool press) noexcept - { - int modifier = 0; - bool isModifier = true; - - switch (sym) - { - case XK_Shift_L: - case XK_Shift_R: modifier = ModifierKeys::shiftModifier; break; - - case XK_Control_L: - case XK_Control_R: modifier = ModifierKeys::ctrlModifier; break; - - case XK_Alt_L: - case XK_Alt_R: modifier = ModifierKeys::altModifier; break; - - case XK_Num_Lock: - if (press) - Keys::numLock = ! Keys::numLock; - - break; - - case XK_Caps_Lock: - if (press) - Keys::capsLock = ! Keys::capsLock; - - break; - - case XK_Scroll_Lock: - break; - - default: - isModifier = false; - break; - } - - ModifierKeys::currentModifiers = press ? ModifierKeys::currentModifiers.withFlags (modifier) - : ModifierKeys::currentModifiers.withoutFlags (modifier); - - return isModifier; - } - - // Alt and Num lock are not defined by standard X - // modifier constants: check what they're mapped to - static void updateModifierMappings() noexcept - { - ScopedXLock xlock (display); - int altLeftCode = XKeysymToKeycode (display, XK_Alt_L); - int numLockCode = XKeysymToKeycode (display, XK_Num_Lock); - - Keys::AltMask = 0; - Keys::NumLockMask = 0; - - if (auto* mapping = XGetModifierMapping (display)) - { - for (int modifierIdx = 0; modifierIdx < 8; ++modifierIdx) - { - for (int keyIndex = 0; keyIndex < mapping->max_keypermod; ++keyIndex) - { - auto key = mapping->modifiermap[(modifierIdx * mapping->max_keypermod) + keyIndex]; - - if (key == altLeftCode) - Keys::AltMask = 1 << modifierIdx; - else if (key == numLockCode) - Keys::NumLockMask = 1 << modifierIdx; - } - } - - XFreeModifiermap (mapping); - } - } - - //============================================================================== - static void xchangeProperty (Window wndH, Atom property, Atom type, int format, const void* data, int numElements) - { - XChangeProperty (display, wndH, property, type, format, PropModeReplace, (const unsigned char*) data, numElements); - } - - void removeWindowDecorations (Window wndH) - { - Atom hints = Atoms::getIfExists (display, "_MOTIF_WM_HINTS"); - - if (hints != None) - { - MotifWmHints motifHints; - zerostruct (motifHints); - - motifHints.flags = 2; /* MWM_HINTS_DECORATIONS */ - motifHints.decorations = 0; - - ScopedXLock xlock (display); - xchangeProperty (wndH, hints, hints, 32, &motifHints, 4); - } - - hints = Atoms::getIfExists (display, "_WIN_HINTS"); - - if (hints != None) - { - long gnomeHints = 0; - - ScopedXLock xlock (display); - xchangeProperty (wndH, hints, hints, 32, &gnomeHints, 1); - } - - hints = Atoms::getIfExists (display, "KWM_WIN_DECORATION"); - - if (hints != None) - { - long kwmHints = 2; /*KDE_tinyDecoration*/ - - ScopedXLock xlock (display); - xchangeProperty (wndH, hints, hints, 32, &kwmHints, 1); - } - - hints = Atoms::getIfExists (display, "_KDE_NET_WM_WINDOW_TYPE_OVERRIDE"); - - if (hints != None) - { - ScopedXLock xlock (display); - xchangeProperty (wndH, atoms->windowType, XA_ATOM, 32, &hints, 1); - } - } - - void addWindowButtons (Window wndH) - { - ScopedXLock xlock (display); - Atom hints = Atoms::getIfExists (display, "_MOTIF_WM_HINTS"); - - if (hints != None) - { - MotifWmHints motifHints; - zerostruct (motifHints); - - motifHints.flags = 1 | 2; /* MWM_HINTS_FUNCTIONS | MWM_HINTS_DECORATIONS */ - motifHints.decorations = 2 /* MWM_DECOR_BORDER */ | 8 /* MWM_DECOR_TITLE */ | 16; /* MWM_DECOR_MENU */ - - motifHints.functions = 4 /* MWM_FUNC_MOVE */; - - if ((styleFlags & windowHasCloseButton) != 0) - motifHints.functions |= 32; /* MWM_FUNC_CLOSE */ - - if ((styleFlags & windowHasMinimiseButton) != 0) - { - motifHints.functions |= 8; /* MWM_FUNC_MINIMIZE */ - motifHints.decorations |= 0x20; /* MWM_DECOR_MINIMIZE */ - } - - if ((styleFlags & windowHasMaximiseButton) != 0) - { - motifHints.functions |= 0x10; /* MWM_FUNC_MAXIMIZE */ - motifHints.decorations |= 0x40; /* MWM_DECOR_MAXIMIZE */ - } - - if ((styleFlags & windowIsResizable) != 0) - { - motifHints.functions |= 2; /* MWM_FUNC_RESIZE */ - motifHints.decorations |= 0x4; /* MWM_DECOR_RESIZEH */ - } - - xchangeProperty (wndH, hints, hints, 32, &motifHints, 5); - } - - hints = Atoms::getIfExists (display, "_NET_WM_ALLOWED_ACTIONS"); - - if (hints != None) - { - Atom netHints [6]; - int num = 0; - - if ((styleFlags & windowIsResizable) != 0) - netHints [num++] = Atoms::getIfExists (display, "_NET_WM_ACTION_RESIZE"); - - if ((styleFlags & windowHasMaximiseButton) != 0) - netHints [num++] = Atoms::getIfExists (display, "_NET_WM_ACTION_FULLSCREEN"); - - if ((styleFlags & windowHasMinimiseButton) != 0) - netHints [num++] = Atoms::getIfExists (display, "_NET_WM_ACTION_MINIMIZE"); - - if ((styleFlags & windowHasCloseButton) != 0) - netHints [num++] = Atoms::getIfExists (display, "_NET_WM_ACTION_CLOSE"); - - xchangeProperty (wndH, hints, XA_ATOM, 32, &netHints, num); - } - } - - void setWindowType() - { - Atom netHints [2]; - - if ((styleFlags & windowIsTemporary) != 0 - || ((styleFlags & windowHasDropShadow) == 0 && Desktop::canUseSemiTransparentWindows())) - netHints [0] = Atoms::getIfExists (display, "_NET_WM_WINDOW_TYPE_COMBO"); - else - netHints [0] = Atoms::getIfExists (display, "_NET_WM_WINDOW_TYPE_NORMAL"); - - xchangeProperty (windowH, atoms->windowType, XA_ATOM, 32, &netHints, 1); - - int numHints = 0; - - if ((styleFlags & windowAppearsOnTaskbar) == 0) - netHints [numHints++] = Atoms::getIfExists (display, "_NET_WM_STATE_SKIP_TASKBAR"); - - if (component.isAlwaysOnTop()) - netHints [numHints++] = Atoms::getIfExists (display, "_NET_WM_STATE_ABOVE"); - - if (numHints > 0) - xchangeProperty (windowH, atoms->windowState, XA_ATOM, 32, &netHints, numHints); - } - - void createWindow (Window parentToAddTo) - { - ScopedXLock xlock (display); - resetDragAndDrop(); - - // Get defaults for various properties - const int screen = DefaultScreen (display); - Window root = RootWindow (display, screen); - - parentWindow = parentToAddTo; - - // Try to obtain a 32-bit visual or fallback to 24 or 16 - visual = Visuals::findVisualFormat (display, (styleFlags & windowIsSemiTransparent) ? 32 : 24, depth); - - if (visual == nullptr) - { - Logger::outputDebugString ("ERROR: System doesn't support 32, 24 or 16 bit RGB display.\n"); - Process::terminate(); - } - - // Create and install a colormap suitable fr our visual - Colormap colormap = XCreateColormap (display, root, visual, AllocNone); - XInstallColormap (display, colormap); - - // Set up the window attributes - XSetWindowAttributes swa; - swa.border_pixel = 0; - swa.background_pixmap = None; - swa.colormap = colormap; - swa.override_redirect = ((styleFlags & windowIsTemporary) != 0) ? True : False; - swa.event_mask = getAllEventsMask(); - - windowH = XCreateWindow (display, parentToAddTo != 0 ? parentToAddTo : root, - 0, 0, 1, 1, - 0, depth, InputOutput, visual, - CWBorderPixel | CWColormap | CWBackPixmap | CWEventMask | CWOverrideRedirect, - &swa); - - // Set the window context to identify the window handle object - if (XSaveContext (display, (XID) windowH, windowHandleXContext, (XPointer) this)) - { - // Failed - jassertfalse; - Logger::outputDebugString ("Failed to create context information for window.\n"); - XDestroyWindow (display, windowH); - windowH = 0; - return; - } - - // Set window manager hints - XWMHints* wmHints = XAllocWMHints(); - wmHints->flags = InputHint | StateHint; - wmHints->input = True; // Locally active input model - wmHints->initial_state = NormalState; - XSetWMHints (display, windowH, wmHints); - XFree (wmHints); - - // Set the window type - setWindowType(); - - // Define decoration - if ((styleFlags & windowHasTitleBar) == 0) - removeWindowDecorations (windowH); - else - addWindowButtons (windowH); - - setTitle (component.getName()); - - // Associate the PID, allowing to be shut down when something goes wrong - unsigned long pid = (unsigned long) getpid(); - xchangeProperty (windowH, atoms->pid, XA_CARDINAL, 32, &pid, 1); - - // Set window manager protocols - xchangeProperty (windowH, atoms->protocols, XA_ATOM, 32, atoms->protocolList, 2); - - // Set drag and drop flags - xchangeProperty (windowH, atoms->XdndTypeList, XA_ATOM, 32, atoms->allowedMimeTypes, numElementsInArray (atoms->allowedMimeTypes)); - xchangeProperty (windowH, atoms->XdndActionList, XA_ATOM, 32, atoms->allowedActions, numElementsInArray (atoms->allowedActions)); - xchangeProperty (windowH, atoms->XdndActionDescription, XA_STRING, 8, "", 0); - xchangeProperty (windowH, atoms->XdndAware, XA_ATOM, 32, &atoms->DndVersion, 1); - - unsigned long info[2] = { 0, 1 }; - xchangeProperty (windowH, atoms->XembedInfo, atoms->XembedInfo, 32, (unsigned char*) info, 2); - - initialisePointerMap(); - updateModifierMappings(); - - #if JUCE_USE_XSHM - if (XSHMHelpers::isShmAvailable (display)) - shmCompletionEvent = XShmGetEventBase (display) + ShmCompletion; - #endif - } - - void destroyWindow() - { - ScopedXLock xlock (display); - - XPointer handlePointer; - - if (keyProxy != 0) - deleteKeyProxy(); - - if (! XFindContext (display, (XID) windowH, windowHandleXContext, &handlePointer)) - XDeleteContext (display, (XID) windowH, windowHandleXContext); - - XDestroyWindow (display, windowH); - - // Wait for it to complete and then remove any events for this - // window from the event queue. - XSync (display, false); - - XEvent event; - while (XCheckWindowEvent (display, windowH, getAllEventsMask(), &event) == True) - {} - } - - int getAllEventsMask() const noexcept - { - return NoEventMask | KeyPressMask | KeyReleaseMask - | EnterWindowMask | LeaveWindowMask | PointerMotionMask | KeymapStateMask - | ExposureMask | StructureNotifyMask | FocusChangeMask - | ((styleFlags & windowIgnoresMouseClicks) != 0 ? 0 : (ButtonPressMask | ButtonReleaseMask)); - } - - template <typename EventType> - static int64 getEventTime (const EventType& t) - { - return getEventTime (t.time); - } - - static int64 getEventTime (::Time t) - { - static int64 eventTimeOffset = 0x12345678; - auto thisMessageTime = (int64) t; - - if (eventTimeOffset == 0x12345678) - eventTimeOffset = Time::currentTimeMillis() - thisMessageTime; - - return eventTimeOffset + thisMessageTime; - } - - long getUserTime() const - { - GetXProperty prop (display, windowH, atoms->userTime, 0, 65536, false, XA_CARDINAL); - - if (! prop.success) - return 0; - - long result; - memcpy (&result, prop.data, sizeof (long)); - - return result; - } - - void updateBorderSize() - { - if ((styleFlags & windowHasTitleBar) == 0) - { - windowBorder = BorderSize<int> (0); - } - else if (windowBorder.getTopAndBottom() == 0 && windowBorder.getLeftAndRight() == 0) - { - ScopedXLock xlock (display); - Atom hints = Atoms::getIfExists (display, "_NET_FRAME_EXTENTS"); - - if (hints != None) - { - GetXProperty prop (display, windowH, hints, 0, 4, false, XA_CARDINAL); - - if (prop.success && prop.actualFormat == 32) - { - auto data = prop.data; - std::array<unsigned long, 4> sizes; - - for (auto& size : sizes) - { - memcpy (&size, data, sizeof (unsigned long)); - data += sizeof (unsigned long); - } - - windowBorder = BorderSize<int> ((int) sizes[2], (int) sizes[0], - (int) sizes[3], (int) sizes[1]); - } - } - } - } - - void updateWindowBounds() - { - jassert (windowH != 0); - if (windowH != 0) - { - Window root, child; - int wx = 0, wy = 0; - unsigned int ww = 0, wh = 0, bw, bitDepth; - - ScopedXLock xlock (display); - - 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<int> (rootX, rootY)); - } - } - - Rectangle<int> physicalBounds (wx, wy, (int) ww, (int) wh); - - updateScaleFactorFromNewBounds (physicalBounds, true); - - bounds = (parentWindow == 0 ? Desktop::getInstance().getDisplays().physicalToLogical (physicalBounds) - : physicalBounds / currentScaleFactor); - } - } - - //============================================================================== - struct DragState - { - DragState (::Display* d) - { - if (isText) - allowedTypes.add (Atoms::getCreating (d, "text/plain")); - else - allowedTypes.add (Atoms::getCreating (d, "text/uri-list")); - } - - bool isText = false; - bool dragging = false; // currently performing outgoing external dnd as Xdnd source, have grabbed mouse - bool expectingStatus = false; // XdndPosition sent, waiting for XdndStatus - bool canDrop = false; // target window signals it will accept the drop - Window targetWindow = None; // potential drop target - int xdndVersion = -1; // negotiated version with target - Rectangle<int> silentRect; - String textOrFiles; - Array<Atom> allowedTypes; - std::function<void()> completionCallback; - }; - - //============================================================================== - void resetDragAndDrop() - { - dragInfo.clear(); - dragInfo.position = Point<int> (-1, -1); - dragAndDropCurrentMimeType = 0; - dragAndDropSourceWindow = 0; - srcMimeTypeAtomList.clear(); - finishAfterDropDataReceived = false; - } - - void resetExternalDragState() - { - dragState.reset (new DragState (display)); - } - - void sendDragAndDropMessage (XClientMessageEvent& msg) - { - msg.type = ClientMessage; - msg.display = display; - msg.window = dragAndDropSourceWindow; - msg.format = 32; - msg.data.l[0] = (long) windowH; - - ScopedXLock xlock (display); - XSendEvent (display, dragAndDropSourceWindow, False, 0, (XEvent*) &msg); - } - - bool sendExternalDragAndDropMessage (XClientMessageEvent& msg, Window targetWindow) - { - msg.type = ClientMessage; - msg.display = display; - msg.window = targetWindow; - msg.format = 32; - msg.data.l[0] = (long) windowH; - - ScopedXLock xlock (display); - return XSendEvent (display, targetWindow, False, 0, (XEvent*) &msg) != 0; - } - - void sendExternalDragAndDropDrop (Window targetWindow) - { - XClientMessageEvent msg; - zerostruct (msg); - - msg.message_type = atoms->XdndDrop; - msg.data.l[2] = CurrentTime; - - sendExternalDragAndDropMessage (msg, targetWindow); - } - - void sendExternalDragAndDropEnter (Window targetWindow) - { - XClientMessageEvent msg; - zerostruct (msg); - - msg.message_type = atoms->XdndEnter; - msg.data.l[1] = (dragState->xdndVersion << 24); - - for (int i = 0; i < 3; ++i) - msg.data.l[i + 2] = (long) dragState->allowedTypes[i]; - - sendExternalDragAndDropMessage (msg, targetWindow); - } - - void sendExternalDragAndDropPosition (Window targetWindow) - { - XClientMessageEvent msg; - zerostruct (msg); - - msg.message_type = atoms->XdndPosition; - - Point<int> mousePos (Desktop::getInstance().getMousePosition()); - - if (dragState->silentRect.contains (mousePos)) // we've been asked to keep silent - return; - - auto& displays = Desktop::getInstance().getDisplays(); - - mousePos = displays.logicalToPhysical (mousePos); - msg.data.l[1] = 0; - msg.data.l[2] = (mousePos.x << 16) | mousePos.y; - msg.data.l[3] = CurrentTime; - msg.data.l[4] = (long) atoms->XdndActionCopy; // this is all JUCE currently supports - - dragState->expectingStatus = sendExternalDragAndDropMessage (msg, targetWindow); - } - - void sendDragAndDropStatus (bool acceptDrop, Atom dropAction) - { - XClientMessageEvent msg; - zerostruct (msg); - - msg.message_type = atoms->XdndStatus; - msg.data.l[1] = (acceptDrop ? 1 : 0) | 2; // 2 indicates that we want to receive position messages - msg.data.l[4] = (long) dropAction; - - sendDragAndDropMessage (msg); - } - - void sendExternalDragAndDropLeave (Window targetWindow) - { - XClientMessageEvent msg; - zerostruct (msg); - - msg.message_type = atoms->XdndLeave; - sendExternalDragAndDropMessage (msg, targetWindow); - } - - void sendDragAndDropFinish() - { - XClientMessageEvent msg; - zerostruct (msg); - - msg.message_type = atoms->XdndFinished; - sendDragAndDropMessage (msg); - } - - void handleExternalSelectionClear() - { - if (dragState->dragging) - externalResetDragAndDrop(); - } - - void handleExternalSelectionRequest (const XEvent& evt) - { - Atom targetType = evt.xselectionrequest.target; - - XEvent s; - s.xselection.type = SelectionNotify; - s.xselection.requestor = evt.xselectionrequest.requestor; - s.xselection.selection = evt.xselectionrequest.selection; - s.xselection.target = targetType; - s.xselection.property = None; - s.xselection.time = evt.xselectionrequest.time; - - if (dragState->allowedTypes.contains (targetType)) - { - s.xselection.property = evt.xselectionrequest.property; - - xchangeProperty (evt.xselectionrequest.requestor, - evt.xselectionrequest.property, - targetType, 8, - dragState->textOrFiles.toRawUTF8(), - (int) dragState->textOrFiles.getNumBytesAsUTF8()); - } - - XSendEvent (display, evt.xselectionrequest.requestor, True, 0, &s); - } - - void handleExternalDragAndDropStatus (const XClientMessageEvent& clientMsg) - { - if (dragState->expectingStatus) - { - dragState->expectingStatus = false; - dragState->canDrop = false; - dragState->silentRect = Rectangle<int>(); - - if ((clientMsg.data.l[1] & 1) != 0 - && ((Atom) clientMsg.data.l[4] == atoms->XdndActionCopy - || (Atom) clientMsg.data.l[4] == atoms->XdndActionPrivate)) - { - if ((clientMsg.data.l[1] & 2) == 0) // target requests silent rectangle - dragState->silentRect.setBounds ((int) clientMsg.data.l[2] >> 16, - (int) clientMsg.data.l[2] & 0xffff, - (int) clientMsg.data.l[3] >> 16, - (int) clientMsg.data.l[3] & 0xffff); - - dragState->canDrop = true; - } - } - } - - void handleExternalDragButtonReleaseEvent() - { - if (dragState->dragging) - XUngrabPointer (display, CurrentTime); - - if (dragState->canDrop) - { - sendExternalDragAndDropDrop (dragState->targetWindow); - } - else - { - sendExternalDragAndDropLeave (dragState->targetWindow); - externalResetDragAndDrop(); - } - } - - void handleExternalDragMotionNotify() - { - Window targetWindow = externalFindDragTargetWindow (RootWindow (display, DefaultScreen (display))); - - if (dragState->targetWindow != targetWindow) - { - if (dragState->targetWindow != None) - sendExternalDragAndDropLeave (dragState->targetWindow); - - dragState->canDrop = false; - dragState->silentRect = Rectangle<int>(); - - if (targetWindow == None) - return; - - dragState->xdndVersion = getDnDVersionForWindow (targetWindow); - - if (dragState->xdndVersion == -1) - return; - - sendExternalDragAndDropEnter (targetWindow); - dragState->targetWindow = targetWindow; - } - - if (! dragState->expectingStatus) - sendExternalDragAndDropPosition (targetWindow); - } - - void handleDragAndDropPosition (const XClientMessageEvent& clientMsg) - { - if (dragAndDropSourceWindow == 0) - return; - - dragAndDropSourceWindow = (::Window) clientMsg.data.l[0]; - - Point<int> dropPos ((int) clientMsg.data.l[2] >> 16, - (int) clientMsg.data.l[2] & 0xffff); - - dropPos = Desktop::getInstance().getDisplays().physicalToLogical (dropPos); - dropPos -= bounds.getPosition(); - - Atom targetAction = atoms->XdndActionCopy; - - for (int i = numElementsInArray (atoms->allowedActions); --i >= 0;) - { - if ((Atom) clientMsg.data.l[4] == atoms->allowedActions[i]) - { - targetAction = atoms->allowedActions[i]; - break; - } - } - - sendDragAndDropStatus (true, targetAction); - - if (dragInfo.position != dropPos) - { - dragInfo.position = dropPos; - - if (dragInfo.isEmpty()) - updateDraggedFileList (clientMsg); - - if (! dragInfo.isEmpty()) - handleDragMove (dragInfo); - } - } - - void handleDragAndDropDrop (const XClientMessageEvent& clientMsg) - { - if (dragInfo.isEmpty()) - { - // no data, transaction finished in handleDragAndDropSelection() - finishAfterDropDataReceived = true; - updateDraggedFileList (clientMsg); - } - else - { - handleDragAndDropDataReceived(); // data was already received - } - } - - void handleDragAndDropDataReceived() - { - DragInfo dragInfoCopy (dragInfo); - - sendDragAndDropFinish(); - resetDragAndDrop(); - - if (! dragInfoCopy.isEmpty()) - handleDragDrop (dragInfoCopy); - } - - void handleDragAndDropEnter (const XClientMessageEvent& clientMsg) - { - dragInfo.clear(); - srcMimeTypeAtomList.clear(); - - dragAndDropCurrentMimeType = 0; - auto dndCurrentVersion = static_cast<unsigned long> (clientMsg.data.l[1] & 0xff000000) >> 24; - - if (dndCurrentVersion < 3 || dndCurrentVersion > Atoms::DndVersion) - { - dragAndDropSourceWindow = 0; - return; - } - - dragAndDropSourceWindow = (::Window) clientMsg.data.l[0]; - - if ((clientMsg.data.l[1] & 1) != 0) - { - ScopedXLock xlock (display); - GetXProperty prop (display, dragAndDropSourceWindow, atoms->XdndTypeList, 0, 0x8000000L, false, XA_ATOM); - - if (prop.success - && prop.actualType == XA_ATOM - && prop.actualFormat == 32 - && prop.numItems != 0) - { - auto* types = prop.data; - - for (unsigned long i = 0; i < prop.numItems; ++i) - { - unsigned long type; - memcpy (&type, types, sizeof (unsigned long)); - - if (type != None) - srcMimeTypeAtomList.add (type); - - types += sizeof (unsigned long); - } - } - } - - if (srcMimeTypeAtomList.isEmpty()) - { - for (int i = 2; i < 5; ++i) - if (clientMsg.data.l[i] != None) - srcMimeTypeAtomList.add ((unsigned long) clientMsg.data.l[i]); - - if (srcMimeTypeAtomList.isEmpty()) - { - dragAndDropSourceWindow = 0; - return; - } - } - - for (int i = 0; i < srcMimeTypeAtomList.size() && dragAndDropCurrentMimeType == 0; ++i) - for (int j = 0; j < numElementsInArray (atoms->allowedMimeTypes); ++j) - if (srcMimeTypeAtomList[i] == atoms->allowedMimeTypes[j]) - dragAndDropCurrentMimeType = atoms->allowedMimeTypes[j]; - - handleDragAndDropPosition (clientMsg); - } - - void handleDragAndDropSelection (const XEvent& evt) - { - dragInfo.clear(); - - if (evt.xselection.property != None) - { - StringArray lines; - - { - MemoryBlock dropData; - - for (;;) - { - GetXProperty prop (display, evt.xany.window, evt.xselection.property, - (long) (dropData.getSize() / 4), 65536, false, AnyPropertyType); - - if (! prop.success) - break; - - dropData.append (prop.data, (size_t) (prop.actualFormat / 8) * prop.numItems); - - if (prop.bytesLeft <= 0) - break; - } - - lines.addLines (dropData.toString()); - } - - if (Atoms::isMimeTypeFile (display, dragAndDropCurrentMimeType)) - { - for (int i = 0; i < lines.size(); ++i) - dragInfo.files.add (URL::removeEscapeChars (lines[i].replace ("file://", String(), true))); - - dragInfo.files.trim(); - dragInfo.files.removeEmptyStrings(); - } - else - { - dragInfo.text = lines.joinIntoString ("\n"); - } - - if (finishAfterDropDataReceived) - handleDragAndDropDataReceived(); - } - } - - void updateDraggedFileList (const XClientMessageEvent& clientMsg) - { - jassert (dragInfo.isEmpty()); - - if (dragAndDropSourceWindow != None - && dragAndDropCurrentMimeType != None) - { - ScopedXLock xlock (display); - XConvertSelection (display, - atoms->XdndSelection, - dragAndDropCurrentMimeType, - Atoms::getCreating (display, "JXSelectionWindowProperty"), - windowH, - (::Time) clientMsg.data.l[2]); - } - } - - bool isWindowDnDAware (Window w) const - { - int numProperties = 0; - auto* properties = XListProperties (display, w, &numProperties); - bool dndAwarePropFound = false; - - for (int i = 0; i < numProperties; ++i) - if (properties[i] == atoms->XdndAware) - dndAwarePropFound = true; - - if (properties != nullptr) - XFree (properties); - - return dndAwarePropFound; - } - - int getDnDVersionForWindow (Window targetWindow) - { - GetXProperty prop (display, targetWindow, atoms->XdndAware, - 0, 2, false, AnyPropertyType); - - if (prop.success && prop.data != None && prop.actualFormat == 32 && prop.numItems == 1) - return jmin ((int) prop.data[0], (int) atoms->DndVersion); - - return -1; - } - - Window externalFindDragTargetWindow (Window targetWindow) - { - if (targetWindow == None) - return None; - - if (isWindowDnDAware (targetWindow)) - return targetWindow; - - Window child, phonyWin; - int phony; - unsigned int uphony; - - XQueryPointer (display, targetWindow, &phonyWin, &child, - &phony, &phony, &phony, &phony, &uphony); - - return externalFindDragTargetWindow (child); - } - - bool externalDragInit (bool isText, const String& textOrFiles, std::function<void()> cb) - { - ScopedXLock xlock (display); - - resetExternalDragState(); - dragState->isText = isText; - dragState->textOrFiles = textOrFiles; - dragState->targetWindow = windowH; - dragState->completionCallback = cb; - - const int pointerGrabMask = Button1MotionMask | ButtonReleaseMask; - - if (XGrabPointer (display, windowH, True, pointerGrabMask, - GrabModeAsync, GrabModeAsync, None, None, CurrentTime) == GrabSuccess) - { - // No other method of changing the pointer seems to work, this call is needed from this very context - XChangeActivePointerGrab (display, pointerGrabMask, (Cursor) createDraggingHandCursor(), CurrentTime); - - XSetSelectionOwner (display, atoms->XdndSelection, windowH, CurrentTime); - - // save the available types to XdndTypeList - xchangeProperty (windowH, atoms->XdndTypeList, XA_ATOM, 32, - dragState->allowedTypes.getRawDataPointer(), - dragState->allowedTypes.size()); - - dragState->dragging = true; - dragState->xdndVersion = getDnDVersionForWindow (dragState->targetWindow); - - sendExternalDragAndDropEnter (dragState->targetWindow); - handleExternalDragMotionNotify(); - - return true; - } - - return false; - } - - void externalResetDragAndDrop() - { - if (dragState->dragging) - { - ScopedXLock xlock (display); - XUngrabPointer (display, CurrentTime); - } - - if (dragState->completionCallback != nullptr) - dragState->completionCallback(); - - resetExternalDragState(); - } - - std::unique_ptr<DragState> dragState; - DragInfo dragInfo; - Atom dragAndDropCurrentMimeType; - Window dragAndDropSourceWindow; - bool finishAfterDropDataReceived; - - Array<Atom> srcMimeTypeAtomList; - - int pointerMap[5] = {}; - - void initialisePointerMap() - { - const int numButtons = XGetPointerMapping (display, nullptr, 0); - pointerMap[2] = pointerMap[3] = pointerMap[4] = Keys::NoButton; - - if (numButtons == 2) - { - pointerMap[0] = Keys::LeftButton; - pointerMap[1] = Keys::RightButton; - } - else if (numButtons >= 3) - { - pointerMap[0] = Keys::LeftButton; - pointerMap[1] = Keys::MiddleButton; - pointerMap[2] = Keys::RightButton; - - if (numButtons >= 5) - { - pointerMap[3] = Keys::WheelUp; - pointerMap[4] = Keys::WheelDown; - } - } - } - - static Point<int> lastMousePos; - - static void clearLastMousePos() noexcept - { - lastMousePos = Point<int> (0x100000, 0x100000); - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LinuxComponentPeer) -}; - -bool LinuxComponentPeer::isActiveApplication = false; -Point<int> LinuxComponentPeer::lastMousePos; -::Display* LinuxComponentPeer::display = nullptr; - -//============================================================================== -namespace WindowingHelpers -{ - static void windowMessageReceive (XEvent& event) - { - if (event.xany.window != None) - { - #if JUCE_X11_SUPPORTS_XEMBED - if (! juce_handleXEmbedEvent (nullptr, &event)) - #endif - { - if (auto* peer = LinuxComponentPeer::getPeerFor (event.xany.window)) - peer->handleWindowMessage (event); - } - } - else if (event.xany.type == KeymapNotify) - { - auto& keymapEvent = (const XKeymapEvent&) event.xkeymap; - memcpy (Keys::keyStates, keymapEvent.key_vector, 32); - } - } -} - -struct WindowingCallbackInitialiser -{ - WindowingCallbackInitialiser() - { - dispatchWindowMessage = WindowingHelpers::windowMessageReceive; - } -}; - -static WindowingCallbackInitialiser windowingInitialiser; - -//============================================================================== -JUCE_API bool JUCE_CALLTYPE Process::isForegroundProcess() -{ - return LinuxComponentPeer::isActiveApplication; -} - -// N/A on Linux as far as I know. -JUCE_API void JUCE_CALLTYPE Process::makeForegroundProcess() {} -JUCE_API void JUCE_CALLTYPE Process::hide() {} - -//============================================================================== -void Desktop::setKioskComponent (Component* comp, bool enableOrDisable, bool /* allowMenusAndBars */) -{ - if (enableOrDisable) - comp->setBounds (getDisplays().getMainDisplay().totalArea); -} - -void Desktop::allowedOrientationsChanged() {} - -//============================================================================== -ComponentPeer* Component::createNewPeer (int styleFlags, void* nativeWindowToAttachTo) -{ - return new LinuxComponentPeer (*this, styleFlags, (Window) nativeWindowToAttachTo); -} - -//============================================================================== -void Displays::findDisplays (float masterScale) -{ - ScopedXDisplay xDisplay; - - if (auto display = xDisplay.display) - { - Atom hints = Atoms::getIfExists (display, "_NET_WORKAREA"); - - auto getWorkAreaPropertyData = [&] (int screenNum) -> unsigned char* - { - if (hints != None) - { - GetXProperty prop (display, RootWindow (display, screenNum), hints, 0, 4, false, XA_CARDINAL); - - if (prop.success && prop.actualType == XA_CARDINAL && prop.actualFormat == 32 && prop.numItems == 4) - return prop.data; - } - - return nullptr; - }; - - #if JUCE_USE_XRANDR - { - int major_opcode, first_event, first_error; - - if (XQueryExtension (display, "RANDR", &major_opcode, &first_event, &first_error)) - { - auto& xrandr = XRandrWrapper::getInstance(); - - auto numMonitors = ScreenCount (display); - auto mainDisplay = xrandr.getOutputPrimary (display, RootWindow (display, 0)); - - for (int i = 0; i < numMonitors; ++i) - { - if (getWorkAreaPropertyData (i) == nullptr) - continue; - - if (auto* screens = xrandr.getScreenResources (display, RootWindow (display, i))) - { - for (int j = 0; j < screens->noutput; ++j) - { - if (screens->outputs[j]) - { - // Xrandr on the raspberry pi fails to determine the main display (mainDisplay == 0)! - // Detect this edge case and make the first found display the main display - if (! mainDisplay) - mainDisplay = screens->outputs[j]; - - if (auto* output = xrandr.getOutputInfo (display, screens, screens->outputs[j])) - { - if (output->crtc) - { - if (auto* crtc = xrandr.getCrtcInfo (display, screens, output->crtc)) - { - Display d; - d.totalArea = Rectangle<int> (crtc->x, crtc->y, - (int) crtc->width, (int) crtc->height); - d.isMain = (mainDisplay == screens->outputs[j]) && (i == 0); - d.dpi = getDisplayDPI (display, 0); - - // The raspberry pi returns a zero sized display, so we need to guard for divide-by-zero - if (output->mm_width > 0 && output->mm_height > 0) - d.dpi = ((static_cast<double> (crtc->width) * 25.4 * 0.5) / static_cast<double> (output->mm_width)) - + ((static_cast<double> (crtc->height) * 25.4 * 0.5) / static_cast<double> (output->mm_height)); - - double scale = getScaleForDisplay (output->name, d.dpi); - scale = (scale <= 0.1 ? 1.0 : scale); - - d.scale = masterScale * scale; - - if (d.isMain) - displays.insert (0, d); - else - displays.add (d); - - xrandr.freeCrtcInfo (crtc); - } - } - - xrandr.freeOutputInfo (output); - } - } - } - - xrandr.freeScreenResources (screens); - } - } - - if (! displays.isEmpty() && ! displays.getReference (0).isMain) - displays.getReference (0).isMain = true; - } - } - - if (displays.isEmpty()) - #endif - #if JUCE_USE_XINERAMA - { - auto screens = XineramaQueryDisplays (display); - int numMonitors = screens.size(); - - for (int index = 0; index < numMonitors; ++index) - { - for (int j = numMonitors; --j >= 0;) - { - if (screens[j].screen_number == index) - { - Display d; - d.totalArea = Rectangle<int> (screens[j].x_org, - screens[j].y_org, - screens[j].width, - screens[j].height); - d.isMain = (index == 0); - d.scale = masterScale; - d.dpi = getDisplayDPI (display, 0); // (all screens share the same DPI) - - displays.add (d); - } - } - } - } - - if (displays.isEmpty()) - #endif - { - if (hints != None) - { - auto numMonitors = ScreenCount (display); - - for (int i = 0; i < numMonitors; ++i) - { - if (auto* positionData = getWorkAreaPropertyData (i)) - { - std::array<long, 4> position; - - for (auto& p : position) - { - memcpy (&p, positionData, sizeof (long)); - positionData += sizeof (long); - } - - Display d; - d.totalArea = Rectangle<int> ((int) position[0], (int) position[1], - (int) position[2], (int) position[3]); - d.isMain = displays.isEmpty(); - d.scale = masterScale; - d.dpi = getDisplayDPI (display, i); - - displays.add (d); - } - } - } - - if (displays.isEmpty()) - { - Display d; - d.totalArea = Rectangle<int> (DisplayWidth (display, DefaultScreen (display)), - DisplayHeight (display, DefaultScreen (display))); - d.isMain = true; - d.scale = masterScale; - d.dpi = getDisplayDPI (display, 0); - - displays.add (d); - } - } - - for (auto& d : displays) - d.userArea = d.totalArea; // JUCE currently does not support requesting the user area on Linux - - updateToLogical(); - } -} - -//============================================================================== -bool MouseInputSource::SourceList::addSource() -{ - if (sources.isEmpty()) - { - addSource (0, MouseInputSource::InputSourceType::mouse); - return true; - } - - return false; -} - -bool MouseInputSource::SourceList::canUseTouch() -{ - return false; -} - -bool Desktop::canUseSemiTransparentWindows() noexcept -{ - #if JUCE_USE_XRENDER - auto display = XWindowSystem::getInstance()->displayRef(); - - if (XRender::hasCompositingWindowManager (display)) - { - int matchedDepth = 0, desiredDepth = 32; - - return Visuals::findVisualFormat (display, desiredDepth, matchedDepth) != 0 - && matchedDepth == desiredDepth; - } - #endif - - return false; -} - -Point<float> MouseInputSource::getCurrentRawMousePosition() -{ - ScopedXDisplay xDisplay; - auto display = xDisplay.display; - - if (display == nullptr) - return {}; - - Window root, child; - int x, y, winx, winy; - unsigned int mask; - - ScopedXLock xlock (display); - - if (XQueryPointer (display, - RootWindow (display, DefaultScreen (display)), - &root, &child, - &x, &y, &winx, &winy, &mask) == False) - { - // Pointer not on the default screen - x = y = -1; - } - - return Desktop::getInstance().getDisplays().physicalToLogical (Point<float> ((float) x, (float) y)); -} - -void MouseInputSource::setRawMousePosition (Point<float> newPosition) -{ - ScopedXDisplay xDisplay; - - if (auto display = xDisplay.display) - { - ScopedXLock xlock (display); - Window root = RootWindow (display, DefaultScreen (display)); - newPosition = Desktop::getInstance().getDisplays().logicalToPhysical (newPosition); - XWarpPointer (display, None, root, 0, 0, 0, 0, roundToInt (newPosition.getX()), roundToInt (newPosition.getY())); - } -} - -double Desktop::getDefaultMasterScale() -{ - return 1.0; -} - -Desktop::DisplayOrientation Desktop::getCurrentOrientation() const -{ - return upright; -} - -//============================================================================== -static bool screenSaverAllowed = true; - -void Desktop::setScreenSaverEnabled (bool isEnabled) -{ - if (screenSaverAllowed != isEnabled) - { - screenSaverAllowed = isEnabled; - - ScopedXDisplay xDisplay; - - if (auto display = xDisplay.display) - { - typedef void (*tXScreenSaverSuspend) (Display*, Bool); - static tXScreenSaverSuspend xScreenSaverSuspend = nullptr; - - if (xScreenSaverSuspend == nullptr) - if (void* h = dlopen ("libXss.so.1", RTLD_GLOBAL | RTLD_NOW)) - xScreenSaverSuspend = (tXScreenSaverSuspend) dlsym (h, "XScreenSaverSuspend"); - - ScopedXLock xlock (display); - if (xScreenSaverSuspend != nullptr) - xScreenSaverSuspend (display, ! isEnabled); - } - } -} - -bool Desktop::isScreenSaverEnabled() -{ - return screenSaverAllowed; -} - -//============================================================================== -Image juce_createIconForFile (const File& /* file */) -{ - return {}; -} - -//============================================================================== -void LookAndFeel::playAlertSound() -{ - std::cout << "\a" << std::flush; -} - -//============================================================================== -Rectangle<int> juce_LinuxScaledToPhysicalBounds (ComponentPeer* peer, Rectangle<int> bounds) -{ - if (auto* linuxPeer = dynamic_cast<LinuxComponentPeer*> (peer)) - bounds *= linuxPeer->getPlatformScaleFactor(); - - return bounds; -} - -void juce_LinuxAddRepaintListener (ComponentPeer* peer, Component* dummy) -{ - if (auto* linuxPeer = dynamic_cast<LinuxComponentPeer*> (peer)) - linuxPeer->addOpenGLRepaintListener (dummy); -} - -void juce_LinuxRemoveRepaintListener (ComponentPeer* peer, Component* dummy) -{ - if (auto* linuxPeer = dynamic_cast<LinuxComponentPeer*> (peer)) - linuxPeer->removeOpenGLRepaintListener (dummy); -} - -unsigned long juce_createKeyProxyWindow (ComponentPeer* peer) -{ - if (auto* linuxPeer = dynamic_cast<LinuxComponentPeer*> (peer)) - return linuxPeer->createKeyProxy(); - - return 0; -} - -void juce_deleteKeyProxyWindow (ComponentPeer* peer) -{ - if (auto* linuxPeer = dynamic_cast<LinuxComponentPeer*> (peer)) - linuxPeer->deleteKeyProxy(); -} - -//============================================================================== -#if JUCE_MODAL_LOOPS_PERMITTED -void JUCE_CALLTYPE NativeMessageBox::showMessageBox (AlertWindow::AlertIconType iconType, - const String& title, const String& message, - Component* /* associatedComponent */) -{ - AlertWindow::showMessageBox (iconType, title, message); -} -#endif - -void JUCE_CALLTYPE NativeMessageBox::showMessageBoxAsync (AlertWindow::AlertIconType iconType, - const String& title, const String& message, - Component* associatedComponent, - ModalComponentManager::Callback* callback) -{ - AlertWindow::showMessageBoxAsync (iconType, title, message, String(), associatedComponent, callback); -} - -bool JUCE_CALLTYPE NativeMessageBox::showOkCancelBox (AlertWindow::AlertIconType iconType, - const String& title, const String& message, - Component* associatedComponent, - ModalComponentManager::Callback* callback) -{ - return AlertWindow::showOkCancelBox (iconType, title, message, String(), String(), - associatedComponent, callback); -} - -int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (AlertWindow::AlertIconType iconType, - const String& title, const String& message, - Component* associatedComponent, - ModalComponentManager::Callback* callback) -{ - return AlertWindow::showYesNoCancelBox (iconType, title, message, - String(), String(), String(), - associatedComponent, callback); -} - -int JUCE_CALLTYPE NativeMessageBox::showYesNoBox (AlertWindow::AlertIconType iconType, - const String& title, const String& message, - Component* associatedComponent, - ModalComponentManager::Callback* callback) -{ - return AlertWindow::showOkCancelBox (iconType, title, message, TRANS ("Yes"), TRANS ("No"), - associatedComponent, callback); -} - -//============================== X11 - MouseCursor ============================= -std::map<Cursor, Display*> cursorMap; - -void* CustomMouseCursorInfo::create() const -{ - ScopedXDisplay xDisplay; - auto display = xDisplay.display; - - if (display == nullptr) - return nullptr; - - ScopedXLock xlock (display); - auto imageW = (unsigned int) image.getWidth(); - auto imageH = (unsigned int) image.getHeight(); - int hotspotX = hotspot.x; - int hotspotY = hotspot.y; - - #if JUCE_USE_XCURSOR - { - using tXcursorSupportsARGB = XcursorBool (*) (Display*); - using tXcursorImageCreate = XcursorImage* (*) (int, int); - using tXcursorImageDestroy = void (*) (XcursorImage*); - using tXcursorImageLoadCursor = Cursor (*) (Display*, const XcursorImage*); - - static tXcursorSupportsARGB xcursorSupportsARGB = nullptr; - static tXcursorImageCreate xcursorImageCreate = nullptr; - static tXcursorImageDestroy xcursorImageDestroy = nullptr; - static tXcursorImageLoadCursor xcursorImageLoadCursor = nullptr; - static bool hasBeenLoaded = false; - - if (! hasBeenLoaded) - { - hasBeenLoaded = true; - - if (void* h = dlopen ("libXcursor.so.1", RTLD_GLOBAL | RTLD_NOW)) - { - xcursorSupportsARGB = (tXcursorSupportsARGB) dlsym (h, "XcursorSupportsARGB"); - xcursorImageCreate = (tXcursorImageCreate) dlsym (h, "XcursorImageCreate"); - xcursorImageLoadCursor = (tXcursorImageLoadCursor) dlsym (h, "XcursorImageLoadCursor"); - xcursorImageDestroy = (tXcursorImageDestroy) dlsym (h, "XcursorImageDestroy"); - - if (xcursorSupportsARGB == nullptr || xcursorImageCreate == nullptr - || xcursorImageLoadCursor == nullptr || xcursorImageDestroy == nullptr - || ! xcursorSupportsARGB (display)) - xcursorSupportsARGB = nullptr; - } - } - - if (xcursorSupportsARGB != nullptr) - { - if (XcursorImage* xcImage = xcursorImageCreate ((int) imageW, (int) imageH)) - { - xcImage->xhot = (XcursorDim) hotspotX; - xcImage->yhot = (XcursorDim) hotspotY; - XcursorPixel* dest = xcImage->pixels; - - for (int y = 0; y < (int) imageH; ++y) - for (int x = 0; x < (int) imageW; ++x) - *dest++ = image.getPixelAt (x, y).getARGB(); - - void* result = (void*) xcursorImageLoadCursor (display, xcImage); - xcursorImageDestroy (xcImage); - - if (result != nullptr) - { - cursorMap[(Cursor) result] = display; - return result; - } - } - } - } - #endif - - Window root = RootWindow (display, DefaultScreen (display)); - unsigned int cursorW, cursorH; - if (! XQueryBestCursor (display, root, imageW, imageH, &cursorW, &cursorH)) - return nullptr; - - Image im (Image::ARGB, (int) cursorW, (int) cursorH, true); - - { - Graphics g (im); - - if (imageW > cursorW || imageH > cursorH) - { - hotspotX = (hotspotX * (int) cursorW) / (int) imageW; - hotspotY = (hotspotY * (int) cursorH) / (int) imageH; - - g.drawImage (image, Rectangle<float> ((float) imageW, (float) imageH), - RectanglePlacement::xLeft | RectanglePlacement::yTop | RectanglePlacement::onlyReduceInSize); - } - else - { - g.drawImageAt (image, 0, 0); - } - } - - const unsigned int stride = (cursorW + 7) >> 3; - HeapBlock<char> maskPlane, sourcePlane; - maskPlane.calloc (stride * cursorH); - sourcePlane.calloc (stride * cursorH); - - const bool msbfirst = (BitmapBitOrder (display) == MSBFirst); - - for (int y = (int) cursorH; --y >= 0;) - { - for (int x = (int) cursorW; --x >= 0;) - { - auto mask = (char) (1 << (msbfirst ? (7 - (x & 7)) : (x & 7))); - auto offset = (unsigned int) y * stride + ((unsigned int) x >> 3); - - auto c = im.getPixelAt (x, y); - - if (c.getAlpha() >= 128) maskPlane[offset] |= mask; - if (c.getBrightness() >= 0.5f) sourcePlane[offset] |= mask; - } - } - - Pixmap sourcePixmap = XCreatePixmapFromBitmapData (display, root, sourcePlane.getData(), cursorW, cursorH, 0xffff, 0, 1); - Pixmap maskPixmap = XCreatePixmapFromBitmapData (display, root, maskPlane.getData(), cursorW, cursorH, 0xffff, 0, 1); - - XColor white, black; - black.red = black.green = black.blue = 0; - white.red = white.green = white.blue = 0xffff; - - void* result = (void*) XCreatePixmapCursor (display, sourcePixmap, maskPixmap, &white, &black, - (unsigned int) hotspotX, (unsigned int) hotspotY); - - XFreePixmap (display, sourcePixmap); - XFreePixmap (display, maskPixmap); - - cursorMap[(Cursor) result] = display; - return result; -} - -void MouseCursor::deleteMouseCursor (void* cursorHandle, bool) -{ - if (cursorHandle != nullptr) - { - ScopedXDisplay xDisplay; - - if (auto display = xDisplay.display) - { - ScopedXLock xlock (display); - XFreeCursor (display, (Cursor) cursorHandle); - } - } -} - -void* MouseCursor::createStandardMouseCursor (MouseCursor::StandardCursorType type) -{ - ScopedXDisplay xDisplay; - auto display = xDisplay.display; - - if (display == nullptr) - return None; - - unsigned int shape; - - switch (type) - { - case NormalCursor: - case ParentCursor: return None; // Use parent cursor - case NoCursor: return CustomMouseCursorInfo (Image (Image::ARGB, 16, 16, true), {}).create(); - - case WaitCursor: shape = XC_watch; break; - case IBeamCursor: shape = XC_xterm; break; - case PointingHandCursor: shape = XC_hand2; break; - case LeftRightResizeCursor: shape = XC_sb_h_double_arrow; break; - case UpDownResizeCursor: shape = XC_sb_v_double_arrow; break; - case UpDownLeftRightResizeCursor: shape = XC_fleur; break; - case TopEdgeResizeCursor: shape = XC_top_side; break; - case BottomEdgeResizeCursor: shape = XC_bottom_side; break; - case LeftEdgeResizeCursor: shape = XC_left_side; break; - case RightEdgeResizeCursor: shape = XC_right_side; break; - case TopLeftCornerResizeCursor: shape = XC_top_left_corner; break; - case TopRightCornerResizeCursor: shape = XC_top_right_corner; break; - case BottomLeftCornerResizeCursor: shape = XC_bottom_left_corner; break; - case BottomRightCornerResizeCursor: shape = XC_bottom_right_corner; break; - case CrosshairCursor: shape = XC_crosshair; break; - case DraggingHandCursor: return createDraggingHandCursor(); - - case CopyingCursor: - { - static unsigned char copyCursorData[] = { 71,73,70,56,57,97,21,0,21,0,145,0,0,0,0,0,255,255,255,0, - 128,128,255,255,255,33,249,4,1,0,0,3,0,44,0,0,0,0,21,0, 21,0,0,2,72,4,134,169,171,16,199,98,11,79,90,71,161,93,56,111, - 78,133,218,215,137,31,82,154,100,200,86,91,202,142,12,108,212,87,235,174, 15,54,214,126,237,226,37,96,59,141,16,37,18,201,142,157,230,204,51,112, - 252,114,147,74,83,5,50,68,147,208,217,16,71,149,252,124,5,0,59,0,0 }; - const int copyCursorSize = 119; - - return CustomMouseCursorInfo (ImageFileFormat::loadFrom (copyCursorData, copyCursorSize), { 1, 3 }).create(); - } - - default: - jassertfalse; - return None; - } - - ScopedXLock xlock (display); - - auto* result = (void*) XCreateFontCursor (display, shape); - cursorMap[(Cursor) result] = display; - - return result; -} - -void MouseCursor::showInWindow (ComponentPeer* peer) const -{ - if (auto* lp = dynamic_cast<LinuxComponentPeer*> (peer)) - { - ScopedXDisplay xDisplay; - - if (cursorHandle != nullptr && xDisplay.display != cursorMap[(Cursor) getHandle()]) - { - auto oldHandle = (Cursor) getHandle(); - - if (auto* customInfo = cursorHandle->getCustomInfo()) - cursorHandle->setHandle (customInfo->create()); - else - cursorHandle->setHandle (createStandardMouseCursor (cursorHandle->getType())); - - cursorMap.erase (oldHandle); - } - - lp->showMouseCursor ((Cursor) getHandle()); - } -} - -//=================================== X11 - DND ================================ -static LinuxComponentPeer* getPeerForDragEvent (Component* sourceComp) -{ - if (sourceComp == nullptr) - if (auto* draggingSource = Desktop::getInstance().getDraggingMouseSource(0)) - sourceComp = draggingSource->getComponentUnderMouse(); - - if (sourceComp != nullptr) - if (auto* lp = dynamic_cast<LinuxComponentPeer*> (sourceComp->getPeer())) - return lp; - - jassertfalse; // This method must be called in response to a component's mouseDown or mouseDrag event! - return nullptr; -} - -bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& files, bool canMoveFiles, - Component* sourceComp, std::function<void()> callback) -{ - if (files.isEmpty()) - return false; - - if (auto* lp = getPeerForDragEvent (sourceComp)) - return lp->externalDragFileInit (files, canMoveFiles, callback); - - // This method must be called in response to a component's mouseDown or mouseDrag event! - jassertfalse; - return false; -} - -bool DragAndDropContainer::performExternalDragDropOfText (const String& text, Component* sourceComp, - std::function<void()> callback) -{ - if (text.isEmpty()) - return false; - - if (auto* lp = getPeerForDragEvent (sourceComp)) - return lp->externalDragTextInit (text, callback); - - // This method must be called in response to a component's mouseDown or mouseDrag event! - jassertfalse; - return false; -} - -} // namespace juce diff --git a/modules/juce_gui_basics/native/juce_mac_FileChooser.mm b/modules/juce_gui_basics/native/juce_mac_FileChooser.mm index 723b3e59..92d66460 100644 --- a/modules/juce_gui_basics/native/juce_mac_FileChooser.mm +++ b/modules/juce_gui_basics/native/juce_mac_FileChooser.mm @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -62,15 +61,19 @@ public: selectsDirectories ((flags & FileBrowserComponent::canSelectDirectories) != 0), selectsFiles ((flags & FileBrowserComponent::canSelectFiles) != 0), isSave ((flags & FileBrowserComponent::saveMode) != 0), - selectMultiple ((flags & FileBrowserComponent::canSelectMultipleItems) != 0), - panel (isSave ? [[NSSavePanel alloc] init] : [[NSOpenPanel alloc] init]) + selectMultiple ((flags & FileBrowserComponent::canSelectMultipleItems) != 0) { setBounds (0, 0, 0, 0); setOpaque (true); - static DelegateClass cls; + static DelegateClass delegateClass; + static SafeSavePanel safeSavePanel; + static SafeOpenPanel safeOpenPanel; - delegate = [cls.createInstance() init]; + panel = isSave ? [safeSavePanel.createInstance() init] + : [safeOpenPanel.createInstance() init]; + + delegate = [delegateClass.createInstance() init]; object_setInstanceVariable (delegate, "cppObject", this); [panel setDelegate: delegate]; @@ -84,7 +87,7 @@ public: if (! isSave) { - NSOpenPanel* openPanel = (NSOpenPanel*) panel; + auto* openPanel = static_cast<NSOpenPanel*> (panel); [openPanel setCanChooseDirectories: selectsDirectories]; [openPanel setCanChooseFiles: selectsFiles]; @@ -98,10 +101,16 @@ public: if (preview != nullptr) { nsViewPreview = [[NSView alloc] initWithFrame: makeNSRect (preview->getLocalBounds())]; + [panel setAccessoryView: nsViewPreview]; + preview->addToDesktop (0, (void*) nsViewPreview); preview->setVisible (true); - [panel setAccessoryView: nsViewPreview]; + if (! isSave) + { + auto* openPanel = static_cast<NSOpenPanel*> (panel); + [openPanel setAccessoryViewDisclosed: YES]; + } } if (isSave || selectsDirectories) @@ -126,6 +135,10 @@ public: ~Native() override { exitModalState (0); + + if (preview != nullptr) + preview->removeFromDesktop(); + removeFromDesktop(); if (panel != nil) @@ -162,15 +175,20 @@ public: enterModalState (true); [panel beginWithCompletionHandler:CreateObjCBlock (this, &Native::finished)]; + + if (preview != nullptr) + preview->toFront (true); } } void runModally() override { + ensurePanelSafe(); + std::unique_ptr<TemporaryMainMenuWithStandardCommands> tempMenu; if (JUCEApplicationBase::isStandaloneApp()) - tempMenu.reset (new TemporaryMainMenuWithStandardCommands()); + tempMenu = std::make_unique<TemporaryMainMenuWithStandardCommands> (preview); jassert (panel != nil); auto result = [panel runModal]; @@ -179,10 +197,7 @@ public: bool canModalEventBeSentToComponent (const Component* targetComponent) override { - if (targetComponent == nullptr) - return false; - - return targetComponent->findParentComponentOfClass<FilePreviewComponent>() != nullptr; + return TemporaryMainMenuWithStandardCommands::checkModalEvent (preview, targetComponent); } private: @@ -219,7 +234,7 @@ private: } else { - auto* openPanel = (NSOpenPanel*) panel; + auto* openPanel = static_cast<NSOpenPanel*> (panel); auto urls = [openPanel URLs]; for (unsigned int i = 0; i < [urls count]; ++i) @@ -245,26 +260,32 @@ private: void panelSelectionDidChange (id sender) { + jassert (sender == panel); + ignoreUnused (sender); + // NB: would need to extend FilePreviewComponent to handle the full list rather than just the first one if (preview != nullptr) - preview->selectedFileChanged (File (getSelectedPaths (sender)[0])); + preview->selectedFileChanged (File (getSelectedPaths()[0])); } - static StringArray getSelectedPaths (id sender) + StringArray getSelectedPaths() const { + if (panel == nullptr) + return {}; + StringArray paths; - if ([sender isKindOfClass: [NSOpenPanel class]]) + if (isSave) { - NSArray* urls = [(NSOpenPanel*) sender URLs]; + paths.add (nsStringToJuce ([[panel URL] path])); + } + else + { + auto* urls = [static_cast<NSOpenPanel*> (panel) URLs]; for (NSUInteger i = 0; i < [urls count]; ++i) paths.add (nsStringToJuce ([[urls objectAtIndex: i] path])); } - else if ([sender isKindOfClass: [NSSavePanel class]]) - { - paths.add (nsStringToJuce ([[(NSSavePanel*) sender URL] path])); - } return paths; } @@ -281,10 +302,47 @@ private: StringArray filters; String startingDirectory, filename; + void ensurePanelSafe() + { + // If you hit this, something (probably the plugin host) has modified the panel, + // allowing the application to terminate while the panel's modal loop is running. + // This is a very bad idea! Quitting from within the panel's modal loop may cause + // your plugin/app destructor to run directly from within `runModally`, which will + // dispose all app resources while they're still in use. + // A safer alternative is to invoke the FileChooser with `launchAsync`, rather than + // using the modal launchers. + jassert ([panel preventsApplicationTerminationWhenModal]); + } + + static BOOL preventsApplicationTerminationWhenModal() { return YES; } + + template <typename Base> + struct SafeModalPanel : public ObjCClass<Base> + { + explicit SafeModalPanel (const char* name) : ObjCClass<Base> (name) + { + this->addMethod (@selector (preventsApplicationTerminationWhenModal), + preventsApplicationTerminationWhenModal, + "c@:"); + + this->registerClass(); + } + }; + + struct SafeSavePanel : SafeModalPanel<NSSavePanel> + { + SafeSavePanel() : SafeModalPanel ("SaveSavePanel_") {} + }; + + struct SafeOpenPanel : SafeModalPanel<NSOpenPanel> + { + SafeOpenPanel() : SafeModalPanel ("SaveOpenPanel_") {} + }; + //============================================================================== - struct DelegateClass : ObjCClass<DelegateType> + struct DelegateClass : public ObjCClass<DelegateType> { - DelegateClass() : ObjCClass <DelegateType> ("JUCEFileChooser_") + DelegateClass() : ObjCClass<DelegateType> ("JUCEFileChooser_") { addIvar<Native*> ("cppObject"); @@ -316,7 +374,7 @@ private: }; FileChooser::Pimpl* FileChooser::showPlatformDialog (FileChooser& owner, int flags, - FilePreviewComponent* preview) + FilePreviewComponent* preview) { return new FileChooser::Native (owner, flags, preview); } diff --git a/modules/juce_gui_basics/native/juce_mac_MainMenu.mm b/modules/juce_gui_basics/native/juce_mac_MainMenu.mm index 53757606..9c147caf 100644 --- a/modules/juce_gui_basics/native/juce_mac_MainMenu.mm +++ b/modules/juce_gui_basics/native/juce_mac_MainMenu.mm @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -535,30 +534,7 @@ private: auto owner = getIvar<JuceMainMenuHandler*> (self, "owner"); if (auto* juceItem = getJuceClassFromNSObject<PopupMenu::Item> ([item representedObject])) - { - // If the menu is being triggered by a keypress, the OS will have picked it up before we had a chance to offer it to - // our own components, which may have wanted to intercept it. So, rather than dispatching directly, we'll feed it back - // into the focused component and let it trigger the menu item indirectly. - NSEvent* e = [NSApp currentEvent]; - - if ([e type] == NSEventTypeKeyDown || [e type] == NSEventTypeKeyUp) - { - if (auto* focused = juce::Component::getCurrentlyFocusedComponent()) - { - if (auto peer = dynamic_cast<juce::NSViewComponentPeer*> (focused->getPeer())) - { - if ([e type] == NSEventTypeKeyDown) - peer->redirectKeyDown (e); - else - peer->redirectKeyUp (e); - - return; - } - } - } - owner->invoke (*juceItem, static_cast<int> ([item tag])); - } } static void menuNeedsUpdate (id self, SEL, NSMenu* menu) @@ -574,8 +550,8 @@ JuceMainMenuHandler* JuceMainMenuHandler::instance = nullptr; class TemporaryMainMenuWithStandardCommands { public: - TemporaryMainMenuWithStandardCommands() - : oldMenu (MenuBarModel::getMacMainMenu()) + explicit TemporaryMainMenuWithStandardCommands (FilePreviewComponent* filePreviewComponent) + : oldMenu (MenuBarModel::getMacMainMenu()), dummyModalComponent (filePreviewComponent) { if (auto* appleMenu = MenuBarModel::getMacExtraAppleItemsMenu()) oldAppleMenu = std::make_unique<PopupMenu> (*appleMenu); @@ -625,8 +601,17 @@ public: MenuBarModel::setMacMainMenu (oldMenu, oldAppleMenu.get(), oldRecentItems); } + static bool checkModalEvent (FilePreviewComponent* preview, const Component* targetComponent) + { + if (targetComponent == nullptr) + return false; + + return (targetComponent == preview + || targetComponent->findParentComponentOfClass<FilePreviewComponent>() != nullptr); + } + private: - MenuBarModel* const oldMenu; + MenuBarModel* const oldMenu = nullptr; std::unique_ptr<PopupMenu> oldAppleMenu; String oldRecentItems; NSInteger editMenuIndex; @@ -639,8 +624,17 @@ private: // recursive when file dialogs are involved struct SilentDummyModalComp : public Component { - SilentDummyModalComp() {} + explicit SilentDummyModalComp (FilePreviewComponent* p) + : preview (p) {} + void inputAttemptWhenModal() override {} + + bool canModalEventBeSentToComponent (const Component* targetComponent) override + { + return checkModalEvent (preview, targetComponent); + } + + FilePreviewComponent* preview = nullptr; }; SilentDummyModalComp dummyModalComponent; diff --git a/modules/juce_gui_basics/native/juce_mac_MouseCursor.mm b/modules/juce_gui_basics/native/juce_mac_MouseCursor.mm index 1f295c60..60d6049f 100644 --- a/modules/juce_gui_basics/native/juce_mac_MouseCursor.mm +++ b/modules/juce_gui_basics/native/juce_mac_MouseCursor.mm @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -144,6 +143,7 @@ void* MouseCursor::createStandardMouseCursor (MouseCursor::StandardCursorType ty case UpDownLeftRightResizeCursor: return MouseCursorHelpers::fromHIServices ("move"); + case NumStandardCursorTypes: default: jassertfalse; break; diff --git a/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm b/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm index 1f89d788..ed74cff7 100644 --- a/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm +++ b/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -24,6 +23,11 @@ ============================================================================== */ +@interface NSEvent (DeviceDelta) +- (float)deviceDeltaX; +- (float)deviceDeltaY; +@end + //============================================================================== #if defined (MAC_OS_X_VERSION_10_8) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_8) \ && USE_COREGRAPHICS_RENDERING && JUCE_COREGRAPHICS_DRAW_ASYNC @@ -681,8 +685,8 @@ public: } else if ([ev respondsToSelector: @selector (deviceDeltaX)]) { - wheel.deltaX = checkDeviceDeltaReturnValue ((float) getMsgSendFPRetFn() (ev, @selector (deviceDeltaX))); - wheel.deltaY = checkDeviceDeltaReturnValue ((float) getMsgSendFPRetFn() (ev, @selector (deviceDeltaY))); + wheel.deltaX = checkDeviceDeltaReturnValue ([ev deviceDeltaX]); + wheel.deltaY = checkDeviceDeltaReturnValue ([ev deviceDeltaY]); } } @catch (...) @@ -706,9 +710,10 @@ public: handleMagnifyGesture (MouseInputSource::InputSourceType::mouse, getMousePos (ev, view), getMouseTime (ev), 1.0f / invScale); } - void redirectCopy (NSObject*) { handleKeyPress (KeyPress ('c', ModifierKeys (ModifierKeys::commandModifier), 'c')); } - void redirectPaste (NSObject*) { handleKeyPress (KeyPress ('v', ModifierKeys (ModifierKeys::commandModifier), 'v')); } - void redirectCut (NSObject*) { handleKeyPress (KeyPress ('x', ModifierKeys (ModifierKeys::commandModifier), 'x')); } + void redirectCopy (NSObject*) { handleKeyPress (KeyPress ('c', ModifierKeys (ModifierKeys::commandModifier), 'c')); } + void redirectPaste (NSObject*) { handleKeyPress (KeyPress ('v', ModifierKeys (ModifierKeys::commandModifier), 'v')); } + void redirectCut (NSObject*) { handleKeyPress (KeyPress ('x', ModifierKeys (ModifierKeys::commandModifier), 'x')); } + void redirectSelectAll (NSObject*) { handleKeyPress (KeyPress ('a', ModifierKeys (ModifierKeys::commandModifier), 'a')); } void redirectWillMoveToWindow (NSWindow* newWindow) { @@ -881,7 +886,7 @@ public: #if USE_COREGRAPHICS_RENDERING if (usingCoreGraphics) { - CoreGraphicsContext context (cg, (float) [view frame].size.height, displayScale); + CoreGraphicsContext context (cg, (float) [view frame].size.height); invokePaint (context); } else @@ -917,7 +922,7 @@ public: invokePaint (*context); } - CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB(); + CGColorSpaceRef colourSpace = CGColorSpaceCreateWithName (kCGColorSpaceSRGB); CGImageRef image = juce_createCoreGraphicsImage (temp, colourSpace, false); CGColorSpaceRelease (colourSpace); CGContextDrawImage (cg, CGRectMake (r.origin.x, r.origin.y, clipW, clipH), image); @@ -1074,11 +1079,13 @@ public: void liveResizingStart() { - if (constrainer != nullptr) - { - constrainer->resizeStart(); - isFirstLiveResize = true; - } + if (constrainer == nullptr) + return; + + constrainer->resizeStart(); + isFirstLiveResize = true; + + setFullScreenSizeConstraints (*constrainer); } void liveResizingEnd() @@ -1087,37 +1094,34 @@ public: constrainer->resizeEnd(); } - NSRect constrainRect (NSRect r) + NSRect constrainRect (const NSRect r) { - if (constrainer != nullptr && ! isKioskMode()) - { - auto scale = getComponent().getDesktopScaleFactor(); + if (constrainer == nullptr || isKioskMode()) + return r; - auto pos = ScalingHelpers::unscaledScreenPosToScaled (scale, convertToRectInt (flippedScreenRect (r))); - auto original = ScalingHelpers::unscaledScreenPosToScaled (scale, convertToRectInt (flippedScreenRect ([window frame]))); + const auto scale = getComponent().getDesktopScaleFactor(); - auto screenBounds = Desktop::getInstance().getDisplays().getTotalBounds (true); + auto pos = ScalingHelpers::unscaledScreenPosToScaled (scale, convertToRectInt (flippedScreenRect (r))); + const auto original = ScalingHelpers::unscaledScreenPosToScaled (scale, convertToRectInt (flippedScreenRect ([window frame]))); - const bool inLiveResize = [window inLiveResize]; + const auto screenBounds = Desktop::getInstance().getDisplays().getTotalBounds (true); - if (! inLiveResize || isFirstLiveResize) - { - isFirstLiveResize = false; - - isStretchingTop = (pos.getY() != original.getY() && pos.getBottom() == original.getBottom()); - isStretchingLeft = (pos.getX() != original.getX() && pos.getRight() == original.getRight()); - isStretchingBottom = (pos.getY() == original.getY() && pos.getBottom() != original.getBottom()); - isStretchingRight = (pos.getX() == original.getX() && pos.getRight() != original.getRight()); - } + const bool inLiveResize = [window inLiveResize]; - constrainer->checkBounds (pos, original, screenBounds, - isStretchingTop, isStretchingLeft, isStretchingBottom, isStretchingRight); + if (! inLiveResize || isFirstLiveResize) + { + isFirstLiveResize = false; - pos = ScalingHelpers::scaledScreenPosToUnscaled (scale, pos); - r = flippedScreenRect (makeNSRect (pos)); + isStretchingTop = (pos.getY() != original.getY() && pos.getBottom() == original.getBottom()); + isStretchingLeft = (pos.getX() != original.getX() && pos.getRight() == original.getRight()); + isStretchingBottom = (pos.getY() == original.getY() && pos.getBottom() != original.getBottom()); + isStretchingRight = (pos.getX() == original.getX() && pos.getRight() != original.getRight()); } - return r; + constrainer->checkBounds (pos, original, screenBounds, + isStretchingTop, isStretchingLeft, isStretchingBottom, isStretchingRight); + + return flippedScreenRect (makeNSRect (ScalingHelpers::scaledScreenPosToUnscaled (scale, pos))); } static void showArrowCursorIfNeeded() @@ -1525,6 +1529,30 @@ private: case NSEventTypeTabletProximity: break; + case NSEventTypeFlagsChanged: + case NSEventTypeAppKitDefined: + case NSEventTypeSystemDefined: + case NSEventTypeApplicationDefined: + case NSEventTypePeriodic: + case NSEventTypeGesture: + case NSEventTypeMagnify: + case NSEventTypeSwipe: + case NSEventTypeRotate: + case NSEventTypeBeginGesture: + case NSEventTypeEndGesture: + case NSEventTypeQuickLook: + #if JUCE_64BIT + case NSEventTypeSmartMagnify: + case NSEventTypePressure: + #endif + #if defined (MAC_OS_X_VERSION_10_12) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_12 + #if JUCE_64BIT + case NSEventTypeDirectTouch: + #endif + #if defined (MAC_OS_X_VERSION_10_15) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_15 + case NSEventTypeChangeMode: + #endif + #endif default: return false; } @@ -1563,6 +1591,13 @@ private: return true; } + void setFullScreenSizeConstraints (const ComponentBoundsConstrainer& c) + { + const auto minSize = NSMakeSize (static_cast<float> (c.getMinimumWidth()), + 0.0f); + [window setMinFullScreenContentSize: minSize]; + } + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NSViewComponentPeer) }; @@ -1631,6 +1666,7 @@ struct JuceNSViewClass : public ObjCClass<NSView> addMethod (@selector (paste:), paste, "v@:@"); addMethod (@selector (copy:), copy, "v@:@"); addMethod (@selector (cut:), cut, "v@:@"); + addMethod (@selector (selectAll:), selectAll, "v@:@"); addMethod (@selector (viewWillMoveToWindow:), willMoveToWindow, "v@:@"); @@ -1682,6 +1718,7 @@ private: static void copy (id self, SEL, NSObject* s) { if (auto* p = getOwner (self)) p->redirectCopy (s); } static void paste (id self, SEL, NSObject* s) { if (auto* p = getOwner (self)) p->redirectPaste (s); } static void cut (id self, SEL, NSObject* s) { if (auto* p = getOwner (self)) p->redirectCut (s); } + static void selectAll (id self, SEL, NSObject* s) { if (auto* p = getOwner (self)) p->redirectSelectAll (s); } static void willMoveToWindow (id self, SEL, NSWindow* w) { if (auto* p = getOwner (self)) p->redirectWillMoveToWindow (w); } static BOOL acceptsFirstMouse (id, SEL, NSEvent*) { return YES; } @@ -1737,10 +1774,7 @@ private: owner->stringBeingComposed.clear(); if (! (owner->textWasInserted || owner->redirectKeyDown (ev))) - { - objc_super s = { self, [NSView class] }; - getMsgSendSuperFn() (&s, @selector (keyDown:), ev); - } + sendSuperclassMessage<void> (self, @selector (keyDown:), ev); } } @@ -1748,11 +1782,8 @@ private: { auto* owner = getOwner (self); - if (owner == nullptr || ! owner->redirectKeyUp (ev)) - { - objc_super s = { self, [NSView class] }; - getMsgSendSuperFn() (&s, @selector (keyUp:), ev); - } + if (! owner->redirectKeyUp (ev)) + sendSuperclassMessage<void> (self, @selector (keyUp:), ev); } //============================================================================== @@ -2002,7 +2033,7 @@ private: static void becomeKeyWindow (id self, SEL) { - sendSuperclassMessage (self, @selector (becomeKeyWindow)); + sendSuperclassMessage<void> (self, @selector (becomeKeyWindow)); if (auto* owner = getOwner (self)) { @@ -2024,10 +2055,15 @@ private: return owner == nullptr || owner->windowShouldClose(); } - static NSRect constrainFrameRect (id self, SEL, NSRect frameRect, NSScreen*) + static NSRect constrainFrameRect (id self, SEL, NSRect frameRect, NSScreen* screen) { if (auto* owner = getOwner (self)) + { + frameRect = sendSuperclassMessage<NSRect, NSRect, NSScreen*> (self, @selector (constrainFrameRect:toScreen:), + frameRect, screen); + frameRect = owner->constrainRect (frameRect); + } return frameRect; } @@ -2071,10 +2107,10 @@ private: { if (auto* owner = getOwner (self)) { - owner->isZooming = true; - objc_super s = { self, [NSWindow class] }; - getMsgSendSuperFn() (&s, @selector (zoom:), sender); - owner->isZooming = false; + { + const ScopedValueSetter<bool> svs (owner->isZooming, true); + sendSuperclassMessage<void> (self, @selector (zoom:), sender); + } owner->redirectMovedOrResized(); } @@ -2192,7 +2228,8 @@ void Desktop::setKioskComponent (Component* kioskComp, bool shouldBeEnabled, boo [NSApp setPresentationOptions: (allowMenusAndBars ? (NSApplicationPresentationAutoHideDock | NSApplicationPresentationAutoHideMenuBar) : (NSApplicationPresentationHideDock | NSApplicationPresentationHideMenuBar))]; - kioskComp->setBounds (Desktop::getInstance().getDisplays().getMainDisplay().totalArea); + + kioskComp->setBounds (getDisplays().getDisplayForRect (kioskComp->getScreenBounds())->totalArea); peer->becomeKeyWindow(); } else diff --git a/modules/juce_gui_basics/native/juce_mac_Windowing.mm b/modules/juce_gui_basics/native/juce_mac_Windowing.mm index ddc082a9..a314ba95 100644 --- a/modules/juce_gui_basics/native/juce_mac_Windowing.mm +++ b/modules/juce_gui_basics/native/juce_mac_Windowing.mm @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -218,7 +217,7 @@ private: delete getIvar<std::function<void()>*> (self, "callback"); delete getIvar<NSDragOperation*> (self, "operation"); - sendSuperclassMessage (self, @selector (dealloc)); + sendSuperclassMessage<void> (self, @selector (dealloc)); } static void provideDataForType (id self, SEL, NSPasteboard* sender, NSPasteboardItem*, NSString* type) diff --git a/modules/juce_gui_basics/native/juce_win32_DragAndDrop.cpp b/modules/juce_gui_basics/native/juce_win32_DragAndDrop.cpp index 1b0ff1e6..10f1b644 100644 --- a/modules/juce_gui_basics/native/juce_win32_DragAndDrop.cpp +++ b/modules/juce_gui_basics/native/juce_win32_DragAndDrop.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -58,7 +57,7 @@ namespace DragAndDropHelpers JUCE_COMRESULT Clone (IEnumFORMATETC** result) override { - if (result == 0) + if (result == nullptr) return E_POINTER; auto newOne = new JuceEnumFormatEtc (format); @@ -74,7 +73,7 @@ namespace DragAndDropHelpers else if (celt != 1) return S_FALSE; - if (index == 0 && celt > 0 && lpFormatEtc != 0) + if (index == 0 && celt > 0 && lpFormatEtc != nullptr) { copyFormatEtc (lpFormatEtc [0], *format); ++index; @@ -93,7 +92,7 @@ namespace DragAndDropHelpers if (index + (int) celt >= 1) return S_FALSE; - index += celt; + index += (int) celt; return S_OK; } @@ -111,7 +110,7 @@ namespace DragAndDropHelpers { dest = source; - if (source.ptd != 0) + if (source.ptd != nullptr) { dest.ptd = (DVTARGETDEVICE*) CoTaskMemAlloc (sizeof (DVTARGETDEVICE)); *(dest.ptd) = *(source.ptd); @@ -142,7 +141,7 @@ namespace DragAndDropHelpers && pFormatEtc->dwAspect == format->dwAspect) { pMedium->tymed = format->tymed; - pMedium->pUnkForRelease = 0; + pMedium->pUnkForRelease = nullptr; if (format->tymed == TYMED_HGLOBAL) { @@ -164,7 +163,7 @@ namespace DragAndDropHelpers JUCE_COMRESULT QueryGetData (FORMATETC* f) { - if (f == 0) + if (f == nullptr) return E_INVALIDARG; if (f->tymed == format->tymed @@ -177,13 +176,13 @@ namespace DragAndDropHelpers JUCE_COMRESULT GetCanonicalFormatEtc (FORMATETC*, FORMATETC* pFormatEtcOut) { - pFormatEtcOut->ptd = 0; + pFormatEtcOut->ptd = nullptr; return E_NOTIMPL; } JUCE_COMRESULT EnumFormatEtc (DWORD direction, IEnumFORMATETC** result) { - if (result == 0) + if (result == nullptr) return E_POINTER; if (direction == DATADIR_GET) @@ -192,7 +191,7 @@ namespace DragAndDropHelpers return S_OK; } - *result = 0; + *result = nullptr; return E_NOTIMPL; } @@ -212,13 +211,13 @@ namespace DragAndDropHelpers //============================================================================== HDROP createHDrop (const StringArray& fileNames) { - int totalBytes = 0; + size_t totalBytes = 0; for (int i = fileNames.size(); --i >= 0;) - totalBytes += (int) CharPointer_UTF16::getBytesRequiredFor (fileNames[i].getCharPointer()) + sizeof (WCHAR); + totalBytes += CharPointer_UTF16::getBytesRequiredFor (fileNames[i].getCharPointer()) + sizeof (WCHAR); HDROP hDrop = (HDROP) GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof (DROPFILES) + totalBytes + 4); - if (hDrop != 0) + if (hDrop != nullptr) { auto pDropFiles = (LPDROPFILES) GlobalLock (hDrop); pDropFiles->pFiles = sizeof (DROPFILES); @@ -251,7 +250,7 @@ namespace DragAndDropHelpers JobStatus runJob() override { - OleInitialize (0); + OleInitialize (nullptr); auto source = new JuceDropSource(); auto data = new JuceDataObject (&format, &medium); @@ -308,8 +307,8 @@ bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& fi if (files.isEmpty()) return false; - FORMATETC format = { CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; - STGMEDIUM medium = { TYMED_HGLOBAL, { 0 }, 0 }; + FORMATETC format = { CF_HDROP, nullptr, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; + STGMEDIUM medium = { TYMED_HGLOBAL, { nullptr }, nullptr }; medium.hGlobal = DragAndDropHelpers::createHDrop (files); @@ -327,8 +326,8 @@ bool DragAndDropContainer::performExternalDragDropOfText (const String& text, Co if (text.isEmpty()) return false; - FORMATETC format = { CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; - STGMEDIUM medium = { TYMED_HGLOBAL, { 0 }, 0 }; + FORMATETC format = { CF_TEXT, nullptr, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; + STGMEDIUM medium = { TYMED_HGLOBAL, { nullptr }, nullptr }; auto numBytes = CharPointer_UTF16::getBytesRequiredFor (text.getCharPointer()); diff --git a/modules/juce_gui_basics/native/juce_win32_FileChooser.cpp b/modules/juce_gui_basics/native/juce_win32_FileChooser.cpp index d708c860..a1a554ef 100644 --- a/modules/juce_gui_basics/native/juce_win32_FileChooser.cpp +++ b/modules/juce_gui_basics/native/juce_win32_FileChooser.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -49,7 +48,6 @@ public: : Thread ("Native Win32 FileChooser"), owner (parent), title (titleToUse), filtersString (filtersToUse), selectsDirectories ((flags & FileBrowserComponent::canSelectDirectories) != 0), - selectsFiles ((flags & FileBrowserComponent::canSelectFiles) != 0), isSave ((flags & FileBrowserComponent::saveMode) != 0), warnAboutOverwrite ((flags & FileBrowserComponent::warnAboutOverwriting) != 0), selectMultiple ((flags & FileBrowserComponent::canSelectMultipleItems) != 0), @@ -60,7 +58,7 @@ public: // Handle nonexistent root directories in the same way as existing ones files.calloc (static_cast<size_t> (charsAvailableForResult) + 1); - if (startingFile.isDirectory() ||startingFile.isRoot()) + if (startingFile.isDirectory() || startingFile.isRoot()) { initialPath = startingFile.getFullPathName(); } @@ -156,12 +154,12 @@ private: Component::SafePointer<Component> owner; String title, filtersString; std::unique_ptr<CustomComponentHolder> customComponent; - String initialPath, returnedString, defaultExtension; + String initialPath, returnedString; WaitableEvent threadHasReference; CriticalSection deletingDialog; - bool selectsDirectories, selectsFiles, isSave, warnAboutOverwrite, selectMultiple; + bool selectsDirectories, isSave, warnAboutOverwrite, selectMultiple; HeapBlock<WCHAR> files; HeapBlock<WCHAR> filters; @@ -169,14 +167,164 @@ private: Atomic<HWND> nativeDialogRef; Atomic<int> shouldCancel; + bool showDialog (IFileDialog& dialog, bool async) const + { + FILEOPENDIALOGOPTIONS flags = {}; + + if (FAILED (dialog.GetOptions (&flags))) + return false; + + const auto setBit = [] (FILEOPENDIALOGOPTIONS& field, bool value, FILEOPENDIALOGOPTIONS option) + { + if (value) + field |= option; + else + field &= ~option; + }; + + setBit (flags, selectsDirectories, FOS_PICKFOLDERS); + setBit (flags, warnAboutOverwrite, FOS_OVERWRITEPROMPT); + setBit (flags, selectMultiple, FOS_ALLOWMULTISELECT); + setBit (flags, customComponent != nullptr, FOS_FORCEPREVIEWPANEON); + + if (FAILED (dialog.SetOptions (flags)) || FAILED (dialog.SetTitle (title.toUTF16()))) + return false; + + PIDLIST_ABSOLUTE pidl = {}; + + if (FAILED (SHParseDisplayName (initialPath.toWideCharPointer(), nullptr, &pidl, SFGAO_FOLDER, nullptr))) + return false; + + const auto item = [&] + { + ComSmartPtr<IShellItem> ptr; + SHCreateShellItem (nullptr, nullptr, pidl, ptr.resetAndGetPointerAddress()); + return ptr; + }(); + + if (item == nullptr || FAILED (dialog.SetFolder (item))) + return false; + + String filename (files.getData()); + + if (FAILED (dialog.SetFileName (filename.toWideCharPointer()))) + return false; + + auto extension = getDefaultFileExtension (filename); + + if (extension.isNotEmpty() && FAILED (dialog.SetDefaultExtension (extension.toWideCharPointer()))) + return false; + + const COMDLG_FILTERSPEC spec[] { { filtersString.toWideCharPointer(), filtersString.toWideCharPointer() } }; + + if (! selectsDirectories && FAILED (dialog.SetFileTypes (numElementsInArray (spec), spec))) + return false; + + return dialog.Show (static_cast<HWND> (async ? nullptr : owner->getWindowHandle())) == S_OK; + } + //============================================================================== - Array<URL> openDialog (bool async) + Array<URL> openDialogVistaAndUp (bool async) + { + const auto getUrl = [] (IShellItem& item) + { + struct Free + { + void operator() (LPWSTR ptr) const noexcept { CoTaskMemFree (ptr); } + }; + + LPWSTR ptr = nullptr; + + if (item.GetDisplayName (SIGDN_FILESYSPATH, &ptr) != S_OK) + return URL(); + + const auto path = std::unique_ptr<WCHAR, Free> { ptr }; + return URL (File (String (path.get()))); + }; + + if (isSave) + { + const auto dialog = [&] + { + ComSmartPtr<IFileDialog> ptr; + ptr.CoCreateInstance (CLSID_FileSaveDialog, CLSCTX_INPROC_SERVER); + return ptr; + }(); + + if (dialog == nullptr) + return {}; + + showDialog (*dialog, async); + + const auto item = [&] + { + ComSmartPtr<IShellItem> ptr; + dialog->GetResult (ptr.resetAndGetPointerAddress()); + return ptr; + }(); + + if (item == nullptr) + return {}; + + const auto url = getUrl (*item); + + if (url.isEmpty()) + return {}; + + return { url }; + } + + const auto dialog = [&] + { + ComSmartPtr<IFileOpenDialog> ptr; + ptr.CoCreateInstance (CLSID_FileOpenDialog, CLSCTX_INPROC_SERVER); + return ptr; + }(); + + if (dialog == nullptr) + return {}; + + showDialog (*dialog, async); + + const auto items = [&] + { + ComSmartPtr<IShellItemArray> ptr; + dialog->GetResults (ptr.resetAndGetPointerAddress()); + return ptr; + }(); + + if (items == nullptr) + return {}; + + Array<URL> result; + + DWORD numItems = 0; + items->GetCount (&numItems); + + for (DWORD i = 0; i < numItems; ++i) + { + ComSmartPtr<IShellItem> scope; + items->GetItemAt (i, scope.resetAndGetPointerAddress()); + + if (scope != nullptr) + { + const auto url = getUrl (*scope); + + if (! url.isEmpty()) + result.add (url); + } + } + + return result; + } + + Array<URL> openDialogPreVista (bool async) { Array<URL> selections; if (selectsDirectories) { - BROWSEINFO bi = { 0 }; + BROWSEINFO bi = {}; bi.hwndOwner = (HWND) (async ? nullptr : owner->getWindowHandle()); bi.pszDisplayName = files; bi.lpszTitle = title.toWideCharPointer(); @@ -213,9 +361,9 @@ private: } else { - OPENFILENAMEW of = { 0 }; + OPENFILENAMEW of = {}; - #ifdef OPENFILENAME_SIZE_VERSION_400W + #ifdef OPENFILENAME_SIZE_VERSION_400W of.lStructSize = OPENFILENAME_SIZE_VERSION_400W; #else of.lStructSize = sizeof (of); @@ -233,16 +381,10 @@ private: if (isSave) { - StringArray tokens; - tokens.addTokens (filtersString, ";,", "\"'"); - tokens.trim(); - tokens.removeEmptyStrings(); + auto extension = getDefaultFileExtension (files.getData()); - if (tokens.size() == 1 && tokens[0].removeCharacters ("*.").isNotEmpty()) - { - defaultExtension = tokens[0].fromFirstOccurrenceOf (".", false, false); - of.lpstrDefExt = defaultExtension.toWideCharPointer(); - } + if (extension.isNotEmpty()) + of.lpstrDefExt = extension.toWideCharPointer(); if (! GetSaveFileName (&of)) return {}; @@ -253,7 +395,7 @@ private: return {}; } - if (selectMultiple && of.nFileOffset > 0 && files [of.nFileOffset - 1] == 0) + if (selectMultiple && of.nFileOffset > 0 && files[of.nFileOffset - 1] == 0) { const WCHAR* filename = files + of.nFileOffset; @@ -269,25 +411,59 @@ private: } } - getNativeDialogList().removeValue (this); - return selections; } + Array<URL> openDialog (bool async) + { + struct Remover + { + explicit Remover (Win32NativeFileChooser& chooser) : item (chooser) {} + ~Remover() { getNativeDialogList().removeValue (&item); } + + Win32NativeFileChooser& item; + }; + + const Remover remover (*this); + + if (SystemStats::getOperatingSystemType() >= SystemStats::WinVista + && customComponent == nullptr) + { + return openDialogVistaAndUp (async); + } + + return openDialogPreVista (async); + } + void run() override { + // We use a functor rather than a lambda here because + // we want to move ownership of the Ptr into the function + // object, and C++11 doesn't support general lambda capture + struct AsyncCallback + { + AsyncCallback (Ptr p, Array<URL> r) + : ptr (std::move (p)), + results (std::move (r)) {} + + void operator()() + { + ptr->results = std::move (results); + + if (ptr->owner != nullptr) + ptr->owner->exitModalState (ptr->results.size() > 0 ? 1 : 0); + } + + Ptr ptr; + Array<URL> results; + }; + // as long as the thread is running, don't delete this class Ptr safeThis (this); threadHasReference.signal(); - Array<URL> r = openDialog (true); - MessageManager::callAsync ([safeThis, r] - { - safeThis->results = r; - - if (safeThis->owner != nullptr) - safeThis->owner->exitModalState (r.size() > 0 ? 1 : 0); - }); + auto r = openDialog (true); + MessageManager::callAsync (AsyncCallback (std::move (safeThis), std::move (r))); } static HashMap<HWND, Win32NativeFileChooser*>& getNativeDialogList() @@ -332,6 +508,23 @@ private: return ofFlags; } + String getDefaultFileExtension (const String& filename) const + { + auto extension = filename.fromLastOccurrenceOf (".", false, false); + + if (extension.isEmpty()) + { + auto tokens = StringArray::fromTokens (filtersString, ";,", "\"'"); + tokens.trim(); + tokens.removeEmptyStrings(); + + if (tokens.size() == 1 && tokens[0].removeCharacters ("*.").isNotEmpty()) + extension = tokens[0].fromFirstOccurrenceOf (".", false, false); + } + + return extension; + } + //============================================================================== void initialised (HWND hWnd) { @@ -368,10 +561,10 @@ private: auto screenRectangle = Rectangle<int>::leftTopRightBottom (dialogScreenRect.left, dialogScreenRect.top, dialogScreenRect.right, dialogScreenRect.bottom); - auto scale = Desktop::getInstance().getDisplays().findDisplayForRect (screenRectangle, true).scale; + auto scale = Desktop::getInstance().getDisplays().getDisplayForRect (screenRectangle, true)->scale; auto physicalComponentWidth = roundToInt (safeCustomComponent->getWidth() * scale); - SetWindowPos (hdlg, 0, screenRectangle.getX(), screenRectangle.getY(), + SetWindowPos (hdlg, nullptr, screenRectangle.getX(), screenRectangle.getY(), physicalComponentWidth + jmax (150, screenRectangle.getWidth()), jmax (150, screenRectangle.getHeight()), SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER); @@ -416,7 +609,7 @@ private: if (customComponent != nullptr && shouldCancel.get() == 0) { - if (FilePreviewComponent* comp = dynamic_cast<FilePreviewComponent*> (customComponent->getChildComponent(0))) + if (FilePreviewComponent* comp = dynamic_cast<FilePreviewComponent*> (customComponent->getChildComponent (0))) { WCHAR path [MAX_PATH * 2] = { 0 }; CommDlg_OpenSave_GetFilePath (hdlg, (LPARAM) &path, MAX_PATH); @@ -502,7 +695,7 @@ private: HWND dialogH = GetParent (hwnd); - if (dialogH == 0) + if (dialogH == nullptr) dialogH = hwnd; return dialogH; @@ -516,13 +709,12 @@ class FileChooser::Native : public Component, public FileChooser::Pimpl { public: - Native (FileChooser& fileChooser, int flags, FilePreviewComponent* previewComp) : owner (fileChooser), nativeFileChooser (new Win32NativeFileChooser (this, flags, previewComp, fileChooser.startingFile, fileChooser.title, fileChooser.filters)) { - auto mainMon = Desktop::getInstance().getDisplays().getMainDisplay().userArea; + auto mainMon = Desktop::getInstance().getDisplays().getPrimaryDisplay()->userArea; setBounds (mainMon.getX() + mainMon.getWidth() / 4, mainMon.getY() + mainMon.getHeight() / 4, @@ -533,7 +725,7 @@ public: addToDesktop (0); } - ~Native() + ~Native() override { exitModalState (0); nativeFileChooser->cancel(); diff --git a/modules/juce_gui_basics/native/juce_win32_Windowing.cpp b/modules/juce_gui_basics/native/juce_win32_Windowing.cpp index 80f15564..6ae0d3dc 100644 --- a/modules/juce_gui_basics/native/juce_win32_Windowing.cpp +++ b/modules/juce_gui_basics/native/juce_win32_Windowing.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -35,6 +34,8 @@ namespace juce { +JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wcast-function-type") + #undef GetSystemMetrics // multimon overrides this for some reason and causes a mess.. // these are in the windows SDK, but need to be repeated here for GCC.. @@ -52,16 +53,15 @@ namespace juce #define WM_APPCOMMAND 0x0319 #endif -extern void juce_repeatLastProcessPriority(); -extern void juce_checkCurrentlyFocusedTopLevelWindow(); // in juce_TopLevelWindow.cpp -extern bool juce_isRunningInWine(); +void juce_repeatLastProcessPriority(); +bool juce_isRunningInWine(); -using CheckEventBlockedByModalComps = bool (*)(const MSG&); +using CheckEventBlockedByModalComps = bool (*) (const MSG&); extern CheckEventBlockedByModalComps isEventBlockedByModalComps; static bool shouldDeactivateTitleBar = true; -extern void* getUser32Function (const char*); +void* getUser32Function (const char*); //============================================================================== #ifndef WM_TOUCH @@ -276,10 +276,10 @@ extern void* getUser32Function (const char*); #endif //============================================================================== -typedef BOOL (WINAPI* RegisterTouchWindowFunc) (HWND, ULONG); -typedef BOOL (WINAPI* GetTouchInputInfoFunc) (HTOUCHINPUT, UINT, TOUCHINPUT*, int); -typedef BOOL (WINAPI* CloseTouchInputHandleFunc) (HTOUCHINPUT); -typedef BOOL (WINAPI* GetGestureInfoFunc) (HGESTUREINFO, GESTUREINFO*); +using RegisterTouchWindowFunc = BOOL (WINAPI*) (HWND, ULONG); +using GetTouchInputInfoFunc = BOOL (WINAPI*) (HTOUCHINPUT, UINT, TOUCHINPUT*, int); +using CloseTouchInputHandleFunc = BOOL (WINAPI*) (HTOUCHINPUT); +using GetGestureInfoFunc = BOOL (WINAPI*) (HGESTUREINFO, GESTUREINFO*); static RegisterTouchWindowFunc registerTouchWindow = nullptr; static GetTouchInputInfoFunc getTouchInputInfo = nullptr; @@ -304,9 +304,9 @@ static bool canUseMultiTouch() } //============================================================================== -typedef BOOL (WINAPI* GetPointerTypeFunc) (UINT32, POINTER_INPUT_TYPE*); -typedef BOOL (WINAPI* GetPointerTouchInfoFunc) (UINT32, POINTER_TOUCH_INFO*); -typedef BOOL (WINAPI* GetPointerPenInfoFunc) (UINT32, POINTER_PEN_INFO*); +using GetPointerTypeFunc = BOOL (WINAPI*) (UINT32, POINTER_INPUT_TYPE*); +using GetPointerTouchInfoFunc = BOOL (WINAPI*) (UINT32, POINTER_TOUCH_INFO*); +using GetPointerPenInfoFunc = BOOL (WINAPI*) (UINT32, POINTER_PEN_INFO*); static GetPointerTypeFunc getPointerTypeFunction = nullptr; static GetPointerTouchInfoFunc getPointerTouchInfo = nullptr; @@ -326,17 +326,17 @@ static void checkForPointerAPI() } //============================================================================== -typedef BOOL (WINAPI* SetProcessDPIAwareFunc) (); -typedef BOOL (WINAPI* SetProcessDPIAwarenessContextFunc) (DPI_AWARENESS_CONTEXT); -typedef BOOL (WINAPI* SetProcessDPIAwarenessFunc) (DPI_Awareness); -typedef DPI_AWARENESS_CONTEXT (WINAPI* SetThreadDPIAwarenessContextFunc) (DPI_AWARENESS_CONTEXT); -typedef HRESULT (WINAPI* GetDPIForMonitorFunc) (HMONITOR, Monitor_DPI_Type, UINT*, UINT*); -typedef UINT (WINAPI* GetDPIForWindowFunc) (HWND); -typedef HRESULT (WINAPI* GetProcessDPIAwarenessFunc) (HANDLE, DPI_Awareness*); -typedef DPI_AWARENESS_CONTEXT (WINAPI* GetWindowDPIAwarenessContextFunc) (HWND); -typedef DPI_AWARENESS_CONTEXT (WINAPI* GetThreadDPIAwarenessContextFunc) (); -typedef DPI_Awareness (WINAPI* GetAwarenessFromDpiAwarenessContextFunc) (DPI_AWARENESS_CONTEXT); -typedef BOOL (WINAPI* EnableNonClientDPIScalingFunc) (HWND); +using SetProcessDPIAwareFunc = BOOL (WINAPI*) (); +using SetProcessDPIAwarenessContextFunc = BOOL (WINAPI*) (DPI_AWARENESS_CONTEXT); +using SetProcessDPIAwarenessFunc = BOOL (WINAPI*) (DPI_Awareness); +using SetThreadDPIAwarenessContextFunc = DPI_AWARENESS_CONTEXT (WINAPI*) (DPI_AWARENESS_CONTEXT); +using GetDPIForWindowFunc = UINT (WINAPI*) (HWND); +using GetDPIForMonitorFunc = HRESULT (WINAPI*) (HMONITOR, Monitor_DPI_Type, UINT*, UINT*); +using GetProcessDPIAwarenessFunc = HRESULT (WINAPI*) (HANDLE, DPI_Awareness*); +using GetWindowDPIAwarenessContextFunc = DPI_AWARENESS_CONTEXT (WINAPI*) (HWND); +using GetThreadDPIAwarenessContextFunc = DPI_AWARENESS_CONTEXT (WINAPI*) (); +using GetAwarenessFromDpiAwarenessContextFunc = DPI_Awareness (WINAPI*) (DPI_AWARENESS_CONTEXT); +using EnableNonClientDPIScalingFunc = BOOL (WINAPI*) (HWND); static SetProcessDPIAwareFunc setProcessDPIAware = nullptr; static SetProcessDPIAwarenessContextFunc setProcessDPIAwarenessContext = nullptr; @@ -359,14 +359,12 @@ static void setDPIAwareness() hasCheckedForDPIAwareness = true; - #if ! JUCE_WIN_PER_MONITOR_DPI_AWARE if (! JUCEApplicationBase::isStandaloneApp()) return; - #endif HMODULE shcoreModule = GetModuleHandleA ("SHCore.dll"); - if (shcoreModule != 0) + if (shcoreModule != nullptr) { getDPIForMonitor = (GetDPIForMonitorFunc) GetProcAddress (shcoreModule, "GetDpiForMonitor"); @@ -374,16 +372,11 @@ static void setDPIAwareness() getDPIForWindow = (GetDPIForWindowFunc) getUser32Function ("GetDpiForWindow"); getProcessDPIAwareness = (GetProcessDPIAwarenessFunc) GetProcAddress (shcoreModule, "GetProcessDpiAwareness"); getWindowDPIAwarenessContext = (GetWindowDPIAwarenessContextFunc) getUser32Function ("GetWindowDpiAwarenessContext"); + setThreadDPIAwarenessContext = (SetThreadDPIAwarenessContextFunc) getUser32Function ("SetThreadDpiAwarenessContext"); getThreadDPIAwarenessContext = (GetThreadDPIAwarenessContextFunc) getUser32Function ("GetThreadDpiAwarenessContext"); getAwarenessFromDPIAwarenessContext = (GetAwarenessFromDpiAwarenessContextFunc) getUser32Function ("GetAwarenessFromDpiAwarenessContext"); - setThreadDPIAwarenessContext = (SetThreadDPIAwarenessContextFunc) getUser32Function ("SetThreadDpiAwarenessContext"); setProcessDPIAwareness = (SetProcessDPIAwarenessFunc) GetProcAddress (shcoreModule, "SetProcessDpiAwareness"); - - // Only set the DPI awareness context of the process if we are a standalone app - if (! JUCEApplicationBase::isStandaloneApp()) - return; - - setProcessDPIAwarenessContext = (SetProcessDPIAwarenessContextFunc) getUser32Function ("SetProcessDpiAwarenessContext"); + setProcessDPIAwarenessContext = (SetProcessDPIAwarenessContextFunc) getUser32Function ("SetProcessDpiAwarenessContext"); if (setProcessDPIAwarenessContext != nullptr && SUCCEEDED (setProcessDPIAwarenessContext (DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2))) @@ -404,9 +397,6 @@ static void setDPIAwareness() return; } - if (! JUCEApplicationBase::isStandaloneApp()) - return; - // fallback for pre Windows 8.1 - equivalent to Process_System_DPI_Aware setProcessDPIAware = (SetProcessDPIAwareFunc) getUser32Function ("SetProcessDPIAware"); @@ -425,7 +415,7 @@ static bool isPerMonitorDPIAwareProcess() return false; DPI_Awareness context; - getProcessDPIAwareness (0, &context); + getProcessDPIAwareness (nullptr, &context); return context == DPI_Awareness::DPI_Awareness_Per_Monitor_Aware; }(); @@ -471,9 +461,9 @@ static double getGlobalDPI() { setDPIAwareness(); - HDC dc = GetDC (0); + HDC dc = GetDC (nullptr); auto dpi = (GetDeviceCaps (dc, LOGPIXELSX) + GetDeviceCaps (dc, LOGPIXELSY)) / 2.0; - ReleaseDC (0, dc); + ReleaseDC (nullptr, dc); return dpi; } @@ -491,7 +481,7 @@ static double getGlobalDPI() ScopedDPIAwarenessDisabler::~ScopedDPIAwarenessDisabler() { if (previousContext != nullptr) - setThreadDPIAwarenessContext ((DPI_AWARENESS_CONTEXT)previousContext); + setThreadDPIAwarenessContext ((DPI_AWARENESS_CONTEXT) previousContext); } #endif @@ -533,13 +523,66 @@ static Point<int> convertPhysicalScreenPointToLogical (const Point<int>& p, HWND return p; } -static double getScaleFactorForWindow (HWND h) +JUCE_API double getScaleFactorForWindow (HWND h) { - if (isPerMonitorDPIAwareWindow (h) && getDPIForWindow != nullptr) - return (double) getDPIForWindow (h) / USER_DEFAULT_SCREEN_DPI; + // NB. Using a local function here because we need to call this method from the plug-in wrappers + // which don't load the DPI-awareness functions on startup + static GetDPIForWindowFunc localGetDPIForWindow = nullptr; + + static bool hasChecked = false; + + if (! hasChecked) + { + hasChecked = true; + + if (localGetDPIForWindow == nullptr) + localGetDPIForWindow = (GetDPIForWindowFunc) getUser32Function ("GetDpiForWindow"); + } + + if (localGetDPIForWindow != nullptr) + return (double) localGetDPIForWindow (h) / USER_DEFAULT_SCREEN_DPI; return 1.0; -} + } + +#if JUCE_WIN_PER_MONITOR_DPI_AWARE + JUCE_API void setThreadDPIAwarenessForWindow (HWND nativeWindow) + { + // NB. Using local functions here because we need to call this method from the plug-in wrappers + // which don't load the DPI-awareness functions on startup + static SetThreadDPIAwarenessContextFunc localSetThreadDPIAwarenessContext = nullptr; + static GetWindowDPIAwarenessContextFunc localGetWindowDPIAwarenessContext = nullptr; + static GetThreadDPIAwarenessContextFunc localGetThreadDPIAwarenessContext = nullptr; + static GetAwarenessFromDpiAwarenessContextFunc localGetAwarenessFromDPIAwarenessContext = nullptr; + + static bool hasChecked = false; + static bool loadedOK = false; + + if (! hasChecked) + { + hasChecked = true; + + localSetThreadDPIAwarenessContext = (SetThreadDPIAwarenessContextFunc) getUser32Function ("SetThreadDpiAwarenessContext"); + localGetWindowDPIAwarenessContext = (GetWindowDPIAwarenessContextFunc) getUser32Function ("GetWindowDpiAwarenessContext"); + localGetThreadDPIAwarenessContext = (GetThreadDPIAwarenessContextFunc) getUser32Function ("GetThreadDpiAwarenessContext"); + localGetAwarenessFromDPIAwarenessContext = (GetAwarenessFromDpiAwarenessContextFunc) getUser32Function ("GetAwarenessFromDpiAwarenessContext"); + + loadedOK = (localSetThreadDPIAwarenessContext != nullptr && localGetWindowDPIAwarenessContext != nullptr + && localGetThreadDPIAwarenessContext != nullptr && localGetAwarenessFromDPIAwarenessContext != nullptr); + } + + if (loadedOK) + { + auto dpiAwareWindow = localGetAwarenessFromDPIAwarenessContext (localGetWindowDPIAwarenessContext (nativeWindow)) == DPI_Awareness::DPI_Awareness_Per_Monitor_Aware; + auto dpiAwareThread = localGetAwarenessFromDPIAwarenessContext (localGetThreadDPIAwarenessContext()) == DPI_Awareness::DPI_Awareness_Per_Monitor_Aware; + + if (dpiAwareWindow && ! dpiAwareThread) + localSetThreadDPIAwarenessContext (DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE); + else if (! dpiAwareWindow && dpiAwareThread) + localSetThreadDPIAwarenessContext (DPI_AWARENESS_CONTEXT_UNAWARE); + } + } +#endif //============================================================================== static void setWindowPos (HWND hwnd, Rectangle<int> bounds, UINT flags, bool adjustTopLeft = false) @@ -553,37 +596,17 @@ static void setWindowPos (HWND hwnd, Rectangle<int> bounds, UINT flags, bool adj bounds = convertLogicalScreenRectangleToPhysical (bounds, hwnd); } - SetWindowPos (hwnd, 0, bounds.getX(), bounds.getY(), bounds.getWidth(), bounds.getHeight(), flags); + SetWindowPos (hwnd, nullptr, bounds.getX(), bounds.getY(), bounds.getWidth(), bounds.getHeight(), flags); } static RECT getWindowRect (HWND hwnd) { - RECT r; - GetWindowRect (hwnd, &r); - #if JUCE_WIN_PER_MONITOR_DPI_AWARE - auto windowDPIAware = isPerMonitorDPIAwareWindow (hwnd); - auto threadDPIAware = isPerMonitorDPIAwareThread(); - - // If these don't match then we need to convert the RECT returned from GetWindowRect() as it depends - // on the DPI awareness of the calling thread - if (windowDPIAware != threadDPIAware) - { - if (! windowDPIAware) - { - // Thread is per-monitor DPI aware so RECT needs to be converted from physical to logical for - // the DPI unaware window - return RECTFromRectangle (Desktop::getInstance().getDisplays().physicalToLogical (rectangleFromRECT (r))); - } - else if (! threadDPIAware) - { - // Thread is DPI unaware so RECT needs to be converted from logical to physical for the per-monitor - // DPI aware window - return RECTFromRectangle (Desktop::getInstance().getDisplays().logicalToPhysical (rectangleFromRECT (r))); - } - } + setThreadDPIAwarenessForWindow (hwnd); #endif + RECT r; + GetWindowRect (hwnd, &r); return r; } @@ -595,13 +618,14 @@ static void setWindowZOrder (HWND hwnd, HWND insertAfter) //============================================================================== double Desktop::getDefaultMasterScale() { - if (! JUCEApplicationBase::isStandaloneApp()) - return 1.0; - - #if JUCE_WIN_PER_MONITOR_DPI_AWARE - if (isPerMonitorDPIAwareProcess()) + if (! JUCEApplicationBase::isStandaloneApp() + #if JUCE_WIN_PER_MONITOR_DPI_AWARE + || isPerMonitorDPIAwareProcess() + #endif + ) + { return 1.0; - #endif + } return getGlobalDPI() / USER_DEFAULT_SCREEN_DPI; } @@ -742,14 +766,14 @@ public: bitmapInfo.bV4V4Compression = BI_RGB; } - HDC dc = GetDC (0); + HDC dc = GetDC (nullptr); hdc = CreateCompatibleDC (dc); - ReleaseDC (0, dc); + ReleaseDC (nullptr, dc); SetMapMode (hdc, MM_TEXT); hBitmap = CreateDIBSection (hdc, (BITMAPINFO*) &(bitmapInfo), DIB_RGB_COLORS, - (void**) &bitmapData, 0, 0); + (void**) &bitmapData, nullptr, 0); previousBitmap = SelectObject (hdc, hBitmap); @@ -814,7 +838,7 @@ public: bf.BlendOp = AC_SRC_OVER; bf.SourceConstantAlpha = updateLayeredWindowAlpha; - UpdateLayeredWindow (hwnd, 0, &pos, &size, hdc, &p, 0, &bf, 2 /*ULW_ALPHA*/); + UpdateLayeredWindow (hwnd, nullptr, &pos, &size, hdc, &p, 0, &bf, 2 /*ULW_ALPHA*/); } else { @@ -837,9 +861,9 @@ public: private: static bool isGraphicsCard32Bit() { - auto dc = GetDC (0); + auto dc = GetDC (nullptr); auto bitsPerPixel = GetDeviceCaps (dc, BITSPIXEL); - ReleaseDC (0, dc); + ReleaseDC (nullptr, dc); return bitsPerPixel > 24; } @@ -924,7 +948,7 @@ namespace IconConverters { if (auto* dc = ::CreateCompatibleDC (tempDC)) { - BITMAPV5HEADER header = { 0 }; + BITMAPV5HEADER header = {}; header.bV5Size = sizeof (BITMAPV5HEADER); header.bV5Width = bm.bmWidth; header.bV5Height = -bm.bmHeight; @@ -946,7 +970,7 @@ namespace IconConverters auto oldObject = ::SelectObject (dc, dib); auto numPixels = bm.bmWidth * bm.bmHeight; - auto numColourComponents = numPixels * 4; + auto numColourComponents = (size_t) numPixels * 4; // Windows icon data comes as two layers, an XOR mask which contains the bulk // of the image data and an AND mask which provides the transparency. Annoyingly @@ -1008,7 +1032,7 @@ namespace IconConverters g.drawImageAt (image, 0, 0); } - auto mask = CreateBitmap (image.getWidth(), image.getHeight(), 1, 1, 0); + auto mask = CreateBitmap (image.getWidth(), image.getHeight(), 1, 1, nullptr); ICONINFO info; info.fIcon = isIcon; @@ -1222,10 +1246,10 @@ private: HMODULE h = {}; }; - typedef HRESULT (WINAPI* RoInitializeFuncPtr) (int); - typedef HRESULT (WINAPI* RoGetActivationFactoryFuncPtr) (HSTRING, REFIID, void**); - typedef HRESULT (WINAPI* WindowsCreateStringFuncPtr) (LPCWSTR,UINT32, HSTRING*); - typedef HRESULT (WINAPI* WindowsDeleteStringFuncPtr) (HSTRING); + using RoInitializeFuncPtr = HRESULT (WINAPI*) (int); + using RoGetActivationFactoryFuncPtr = HRESULT (WINAPI*) (HSTRING, REFIID, void**); + using WindowsCreateStringFuncPtr = HRESULT (WINAPI*) (LPCWSTR,UINT32, HSTRING*); + using WindowsDeleteStringFuncPtr = HRESULT (WINAPI*) (HSTRING); ComBaseModule comBaseDLL; ComSmartPtr<IUIViewSettingsInterop> viewSettingsInterop; @@ -1291,7 +1315,7 @@ public: callFunctionIfNotLocked (&destroyWindowCallback, (void*) hwnd); - if (currentWindowIcon != 0) + if (currentWindowIcon != nullptr) DestroyIcon (currentWindowIcon); if (dropTarget != nullptr) @@ -1314,7 +1338,7 @@ public: ShowWindow (hwnd, shouldBeVisible ? SW_SHOWNA : SW_HIDE); if (shouldBeVisible) - InvalidateRect (hwnd, 0, 0); + InvalidateRect (hwnd, nullptr, 0); else lastPaintTime = 0; } @@ -1415,6 +1439,7 @@ public: Point<float> localToGlobal (Point<float> relativePosition) override { return relativePosition + getScreenPosition().toFloat(); } Point<float> globalToLocal (Point<float> screenPosition) override { return screenPosition - getScreenPosition().toFloat(); } + using ComponentPeer::localToGlobal; using ComponentPeer::globalToLocal; @@ -1432,7 +1457,7 @@ public: else { SetWindowLong (hwnd, GWL_EXSTYLE, GetWindowLong (hwnd, GWL_EXSTYLE) & ~WS_EX_LAYERED); - RedrawWindow (hwnd, 0, 0, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN); + RedrawWindow (hwnd, nullptr, nullptr, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN); } } else @@ -1585,7 +1610,7 @@ public: bool isFocused() const override { - return callFunctionIfNotLocked (&getFocusCallback, 0) == (void*) hwnd; + return callFunctionIfNotLocked (&getFocusCallback, nullptr) == (void*) hwnd; } void grabFocus() override @@ -1629,7 +1654,7 @@ public: // if the calling thread is DPI-aware but we are invalidating a non-DPI aware window RECT, we actually have to // divide the bounds by the scale factor as it will get multiplied for the virtualised paint callback... if (isPerMonitorDPIAwareThread() && ! isPerMonitorDPIAwareWindow (hwnd)) - scale = 1.0 / Desktop::getInstance().getDisplays().getMainDisplay().scale; + scale = 1.0 / Desktop::getInstance().getDisplays().getPrimaryDisplay()->scale; #endif auto scaled = area.toDouble() * scale; @@ -1654,7 +1679,7 @@ public: //============================================================================== static HWNDComponentPeer* getOwnerOfWindow (HWND h) noexcept { - if (h != 0 && JuceWindowIdentifier::isJUCEWindow (h)) + if (h != nullptr && JuceWindowIdentifier::isJUCEWindow (h)) return (HWNDComponentPeer*) GetWindowLongPtr (h, 8); return nullptr; @@ -1755,16 +1780,17 @@ public: private: Point<float> getMousePos (POINTL mousePos) const { - Point<float> screenPos; + auto screenPos = pointFromPOINT ({ mousePos.x, mousePos.y }).toFloat(); #if JUCE_WIN_PER_MONITOR_DPI_AWARE auto h = (HWND) peer.getNativeHandle(); if (isPerMonitorDPIAwareWindow (h)) - screenPos = convertPhysicalScreenPointToLogical (pointFromPOINT ({ mousePos.x, mousePos.y }), h).toFloat(); - else + screenPos = convertPhysicalScreenPointToLogical (screenPos.roundToInt(), h).toFloat(); + #else + if (JUCEApplication::isStandaloneApp()) + screenPos /= static_cast<float> (getGlobalDPI() / USER_DEFAULT_SCREEN_DPI); #endif - screenPos = pointFromPOINT ({ mousePos.x, mousePos.y }).toFloat() / static_cast<float> (getGlobalDPI() / USER_DEFAULT_SCREEN_DPI); return peer.getComponent().getLocalPoint (nullptr, screenPos); } @@ -1791,8 +1817,8 @@ public: { DroppedData (IDataObject* dataObject, CLIPFORMAT type) { - FORMATETC format = { type, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; - STGMEDIUM resetMedium = { TYMED_HGLOBAL, { 0 }, 0 }; + FORMATETC format = { type, nullptr, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; + STGMEDIUM resetMedium = { TYMED_HGLOBAL, { nullptr }, nullptr }; medium = resetMedium; if (SUCCEEDED (error = dataObject->GetData (&format, &medium))) @@ -1897,7 +1923,7 @@ private: bool fullScreen = false, isDragging = false, isMouseOver = false, hasCreatedCaret = false, constrainerIsResizing = false; BorderSize<int> windowBorder; - HICON currentWindowIcon = 0; + HICON currentWindowIcon = nullptr; FileDropTarget* dropTarget = nullptr; uint8 updateLayeredWindowAlpha = 255; UWPUIViewSettings uwpViewSettings; @@ -1954,11 +1980,11 @@ private: auto moduleHandle = (HINSTANCE) Process::getCurrentModuleInstanceHandle(); - TCHAR moduleFile[1024] = { 0 }; + TCHAR moduleFile[1024] = {}; GetModuleFileName (moduleHandle, moduleFile, 1024); WORD iconNum = 0; - WNDCLASSEX wcex = { 0 }; + WNDCLASSEX wcex = {}; wcex.cbSize = sizeof (wcex); wcex.style = CS_OWNDC; wcex.lpfnWndProc = (WNDPROC) windowProc; @@ -2094,7 +2120,7 @@ private: if ((styleFlags & windowIsResizable) != 0) type |= WS_THICKFRAME; } - else if (parentToAddTo != 0) + else if (parentToAddTo != nullptr) { type |= WS_CHILD; } @@ -2114,10 +2140,10 @@ private: if ((styleFlags & windowIsSemiTransparent) != 0) exstyle |= WS_EX_LAYERED; hwnd = CreateWindowEx (exstyle, WindowClassHolder::getInstance()->getWindowClassName(), - L"", type, 0, 0, 0, 0, parentToAddTo, 0, - (HINSTANCE) Process::getCurrentModuleInstanceHandle(), 0); + L"", type, 0, 0, 0, 0, parentToAddTo, nullptr, + (HINSTANCE) Process::getCurrentModuleInstanceHandle(), nullptr); - if (hwnd != 0) + if (hwnd != nullptr) { SetWindowLongPtr (hwnd, 0, 0); SetWindowLongPtr (hwnd, 8, (LONG_PTR) this); @@ -2149,9 +2175,9 @@ private: auto bounds = component.getBounds(); if (bounds.isEmpty()) - scaleFactor = Desktop::getInstance().getDisplays().getMainDisplay().scale; + scaleFactor = Desktop::getInstance().getDisplays().getPrimaryDisplay()->scale; else - scaleFactor = Desktop::getInstance().getDisplays().findDisplayForRect (bounds).scale; + scaleFactor = Desktop::getInstance().getDisplays().getDisplayForRect (bounds)->scale; scaleFactor /= Desktop::getInstance().getGlobalScaleFactor(); } @@ -2248,7 +2274,7 @@ private: SendMessage (hwnd, WM_SETICON, ICON_BIG, (LPARAM) hicon); SendMessage (hwnd, WM_SETICON, ICON_SMALL, (LPARAM) hicon); - if (currentWindowIcon != 0) + if (currentWindowIcon != nullptr) DestroyIcon (currentWindowIcon); currentWindowIcon = hicon; @@ -2257,7 +2283,7 @@ private: void setMessageFilter() { - typedef BOOL (WINAPI* ChangeWindowMessageFilterExFunc) (HWND, UINT, DWORD, PVOID); + using ChangeWindowMessageFilterExFunc = BOOL (WINAPI*) (HWND, UINT, DWORD, PVOID); if (auto changeMessageFilter = (ChangeWindowMessageFilterExFunc) getUser32Function ("ChangeWindowMessageFilterEx")) { @@ -2506,7 +2532,7 @@ private: #endif } - static int getMinTimeBetweenMouseMoves() + static uint32 getMinTimeBetweenMouseMoves() { if (SystemStats::getOperatingSystemType() >= SystemStats::WinVista) return 0; @@ -2764,7 +2790,7 @@ private: HeapBlock<TOUCHINPUT> inputInfo (numInputs); - if (getTouchInputInfo (eventHandle, numInputs, inputInfo, sizeof (TOUCHINPUT))) + if (getTouchInputInfo (eventHandle, (UINT) numInputs, inputInfo, sizeof (TOUCHINPUT))) { for (int i = 0; i < numInputs; ++i) { @@ -3150,10 +3176,7 @@ private: updateKeyModifiers(); if (hwnd == GetActiveWindow()) - { - handleKeyPress (key, 0); - return true; - } + return handleKeyPress (key, 0); } return false; @@ -3275,7 +3298,7 @@ private: ScreenToClient (GetParent (hwnd), &p); auto ratio = *(double*) context; - SetWindowPos (hwnd, 0, roundToInt (p.x * ratio), roundToInt (p.y * ratio), + SetWindowPos (hwnd, nullptr, roundToInt (p.x * ratio), roundToInt (p.y * ratio), roundToInt ((r.right - r.left) * ratio), roundToInt ((r.bottom - r.top) * ratio), SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOOWNERZORDER); @@ -3395,7 +3418,8 @@ private: forceDisplayUpdate(); if (fullScreen && ! isMinimised()) - setWindowPos (hwnd, ScalingHelpers::scaledScreenPosToUnscaled (component, Desktop::getInstance().getDisplays().findDisplayForRect (component.getScreenBounds()).userArea), + setWindowPos (hwnd, ScalingHelpers::scaledScreenPosToUnscaled (component, Desktop::getInstance().getDisplays() + .getDisplayForRect (component.getScreenBounds())->userArea), SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOSENDCHANGING); } @@ -3704,8 +3728,9 @@ private: return 0; case WM_DISPLAYCHANGE: - InvalidateRect (h, 0, 0); + InvalidateRect (h, nullptr, 0); // intentional fall-through... + JUCE_FALLTHROUGH case WM_SETTINGCHANGE: // note the fall-through in the previous case! doSettingChange(); break; @@ -3932,14 +3957,14 @@ private: String getCompositionString (HIMC hImc, const DWORD type) const { - jassert (hImc != 0); + jassert (hImc != nullptr); - const int stringSizeBytes = ImmGetCompositionString (hImc, type, 0, 0); + const auto stringSizeBytes = ImmGetCompositionString (hImc, type, nullptr, 0); if (stringSizeBytes > 0) { HeapBlock<TCHAR> buffer; - buffer.calloc (stringSizeBytes / sizeof (TCHAR) + 1); + buffer.calloc ((size_t) stringSizeBytes / sizeof (TCHAR) + 1); ImmGetCompositionString (hImc, type, buffer, (DWORD) stringSizeBytes); return String (buffer.get()); } @@ -3949,14 +3974,14 @@ private: int getCompositionCaretPos (HIMC hImc, LPARAM lParam, const String& currentIMEString) const { - jassert (hImc != 0); + jassert (hImc != nullptr); if ((lParam & CS_NOMOVECARET) != 0) return compositionRange.getStart(); if ((lParam & GCS_CURSORPOS) != 0) { - const int localCaretPos = ImmGetCompositionString (hImc, GCS_CURSORPOS, 0, 0); + const int localCaretPos = ImmGetCompositionString (hImc, GCS_CURSORPOS, nullptr, 0); return compositionRange.getStart() + jmax (0, localCaretPos); } @@ -3967,14 +3992,14 @@ private: // returned range is relative to beginning of TextInputTarget, not composition string Range<int> getCompositionSelection (HIMC hImc, LPARAM lParam) const { - jassert (hImc != 0); + jassert (hImc != nullptr); int selectionStart = 0; int selectionEnd = 0; if ((lParam & GCS_COMPATTR) != 0) { // Get size of attributes array: - const int attributeSizeBytes = ImmGetCompositionString (hImc, GCS_COMPATTR, 0, 0); + const int attributeSizeBytes = ImmGetCompositionString (hImc, GCS_COMPATTR, nullptr, 0); if (attributeSizeBytes > 0) { @@ -4015,13 +4040,13 @@ private: { Array<Range<int>> result; - if (hImc != 0 && (lParam & GCS_COMPCLAUSE) != 0) + if (hImc != nullptr && (lParam & GCS_COMPCLAUSE) != 0) { - auto clauseDataSizeBytes = ImmGetCompositionString (hImc, GCS_COMPCLAUSE, 0, 0); + auto clauseDataSizeBytes = ImmGetCompositionString (hImc, GCS_COMPCLAUSE, nullptr, 0); if (clauseDataSizeBytes > 0) { - const size_t numItems = clauseDataSizeBytes / sizeof (uint32); + const auto numItems = (size_t) clauseDataSizeBytes / sizeof (uint32); HeapBlock<uint32> clauseData (numItems); if (ImmGetCompositionString (hImc, GCS_COMPCLAUSE, clauseData, (DWORD) clauseDataSizeBytes) > 0) @@ -4073,28 +4098,6 @@ JUCE_API ComponentPeer* createNonRepaintingEmbeddedWindowsPeer (Component& compo (HWND) parentHWND, true); } -JUCE_API bool shouldScaleGLWindow (void* hwnd) -{ - return isPerMonitorDPIAwareWindow ((HWND) hwnd); -} - -#if JUCE_WIN_PER_MONITOR_DPI_AWARE - JUCE_API void setProcessDPIAwarenessIfNecessary (void* hwnd) - { - if (getProcessDPIAwareness == nullptr) - return; - - DPI_Awareness context; - getProcessDPIAwareness (0, &context); - - if (isPerMonitorDPIAwareWindow ((HWND) hwnd) && context != DPI_Awareness::DPI_Awareness_Per_Monitor_Aware - && setProcessDPIAwareness != nullptr) - { - setProcessDPIAwareness (DPI_Awareness::DPI_Awareness_Per_Monitor_Aware); - } - } -#endif - JUCE_IMPLEMENT_SINGLETON (HWNDComponentPeer::WindowClassHolder) //============================================================================== @@ -4231,6 +4234,7 @@ private: case AlertWindow::QuestionIcon: flags |= MB_ICONQUESTION; break; case AlertWindow::WarningIcon: flags |= MB_ICONWARNING; break; case AlertWindow::InfoIcon: flags |= MB_ICONINFORMATION; break; + case AlertWindow::NoIcon: JUCE_FALLTHROUGH default: break; } @@ -4239,7 +4243,7 @@ private: static HWND getWindowForMessageBox (Component* associatedComponent) { - return associatedComponent != nullptr ? (HWND) associatedComponent->getWindowHandle() : 0; + return associatedComponent != nullptr ? (HWND) associatedComponent->getWindowHandle() : nullptr; } }; @@ -4248,7 +4252,7 @@ void JUCE_CALLTYPE NativeMessageBox::showMessageBox (AlertWindow::AlertIconType const String& title, const String& message, Component* associatedComponent) { - WindowsMessageBox box (iconType, title, message, associatedComponent, MB_OK, 0, false); + WindowsMessageBox box (iconType, title, message, associatedComponent, MB_OK, nullptr, false); (void) box.getResult(); } #endif @@ -4365,7 +4369,7 @@ public: { if (Process::isForegroundProcess()) { - INPUT input = { 0 }; + INPUT input = {}; input.type = INPUT_MOUSE; input.mi.mouseData = MOUSEEVENTF_MOVE; @@ -4398,7 +4402,7 @@ void LookAndFeel::playAlertSound() //============================================================================== void SystemClipboard::copyTextToClipboard (const String& text) { - if (OpenClipboard (0) != 0) + if (OpenClipboard (nullptr) != 0) { if (EmptyClipboard() != 0) { @@ -4427,7 +4431,7 @@ String SystemClipboard::getTextFromClipboard() { String result; - if (OpenClipboard (0) != 0) + if (OpenClipboard (nullptr) != 0) { if (auto bufH = GetClipboardData (CF_UNICODETEXT)) { @@ -4451,7 +4455,7 @@ void Desktop::setKioskComponent (Component* kioskModeComp, bool enableOrDisable, tlw->setUsingNativeTitleBar (! enableOrDisable); if (enableOrDisable) - kioskModeComp->setBounds (getDisplays().getMainDisplay().totalArea); + kioskModeComp->setBounds (getDisplays().getDisplayForRect (kioskModeComp->getScreenBounds())->totalArea); } void Desktop::allowedOrientationsChanged() {} @@ -4504,7 +4508,7 @@ static const Displays::Display* getCurrentDisplayFromScaleFactor (HWND hwnd) return retVal; } - return &Desktop::getInstance().getDisplays().getMainDisplay(); + return Desktop::getInstance().getDisplays().getPrimaryDisplay(); } //============================================================================== @@ -4520,7 +4524,7 @@ struct MonitorInfo static BOOL CALLBACK enumMonitorsProc (HMONITOR hm, HDC, LPRECT r, LPARAM userInfo) { - MONITORINFO info = { 0 }; + MONITORINFO info = {}; info.cbSize = sizeof (info); GetMonitorInfo (hm, &info); @@ -4543,18 +4547,8 @@ void Displays::findDisplays (float masterScale) { setDPIAwareness(); - #if JUCE_WIN_PER_MONITOR_DPI_AWARE - DPI_AWARENESS_CONTEXT prevContext = nullptr; - - if (setThreadDPIAwarenessContext != nullptr && getAwarenessFromDPIAwarenessContext != nullptr && getThreadDPIAwarenessContext != nullptr - && getAwarenessFromDPIAwarenessContext (getThreadDPIAwarenessContext()) != DPI_Awareness::DPI_Awareness_Per_Monitor_Aware) - { - prevContext = setThreadDPIAwarenessContext (DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE); - } - #endif - Array<MonitorInfo> monitors; - EnumDisplayMonitors (0, 0, &enumMonitorsProc, (LPARAM) &monitors); + EnumDisplayMonitors (nullptr, nullptr, &enumMonitorsProc, (LPARAM) &monitors); auto globalDPI = getGlobalDPI(); @@ -4600,10 +4594,6 @@ void Displays::findDisplays (float masterScale) #if JUCE_WIN_PER_MONITOR_DPI_AWARE updateToLogical(); - - // Reset the DPI awareness context if it was overridden earlier - if (prevContext != nullptr) - setThreadDPIAwarenessContext (prevContext); #else for (auto& d : displays) { @@ -4651,8 +4641,8 @@ void* CustomMouseCursorInfo::create() const { im = im.rescaled (maxW, maxH); - hotspotX = (hotspotX * maxW) / image.getWidth(); - hotspotY = (hotspotY * maxH) / image.getHeight(); + hotspotX = (hotspotX * maxW) / juce::jmax (1, image.getWidth()); + hotspotY = (hotspotY * maxH) / juce::jmax (1, image.getHeight()); } return IconConverters::createHICONFromImage (im, FALSE, hotspotX, hotspotY); @@ -4722,10 +4712,12 @@ void* MouseCursor::createStandardMouseCursor (const MouseCursor::StandardCursorT if (copyCursor == nullptr) { - static unsigned char copyCursorData[] = { 71,73,70,56,57,97,21,0,21,0,145,0,0,0,0,0,255,255,255,0, - 128,128,255,255,255,33,249,4,1,0,0,3,0,44,0,0,0,0,21,0, 21,0,0,2,72,4,134,169,171,16,199,98,11,79,90,71,161,93,56,111, - 78,133,218,215,137,31,82,154,100,200,86,91,202,142,12,108,212,87,235,174, 15,54,214,126,237,226,37,96,59,141,16,37,18,201,142,157,230,204,51,112, - 252,114,147,74,83,5,50,68,147,208,217,16,71,149,252,124,5,0,59,0,0 }; + static unsigned char copyCursorData[] = { + 71,73,70,56,57,97,21,0,21,0,145,0,0,0,0,0,255,255,255,0,128,128,255,255,255,33,249,4,1,0,0,3,0,44,0,0,0,0,21,0, + 21,0,0,2,72,4,134,169,171,16,199,98,11,79,90,71,161,93,56,111,78,133,218,215,137,31,82,154,100,200,86,91,202,142, + 12,108,212,87,235,174, 15,54,214,126,237,226,37,96,59,141,16,37,18,201,142,157,230,204,51,112,252,114,147,74,83, + 5,50,68,147,208,217,16,71,149,252,124,5,0,59,0,0 + }; const int copyCursorSize = 119; copyCursor = CustomMouseCursorInfo (ImageFileFormat::loadFrom (copyCursorData, copyCursorSize), { 1, 3 }).create(); @@ -4734,14 +4726,15 @@ void* MouseCursor::createStandardMouseCursor (const MouseCursor::StandardCursorT return copyCursor; } + case NumStandardCursorTypes: JUCE_FALLTHROUGH default: jassertfalse; break; } - if (auto cursorH = LoadCursor (0, cursorName)) + if (auto cursorH = LoadCursor (nullptr, cursorName)) return cursorH; - return LoadCursor (0, IDC_ARROW); + return LoadCursor (nullptr, IDC_ARROW); } //============================================================================== @@ -4749,12 +4742,14 @@ void MouseCursor::showInWindow (ComponentPeer*) const { auto c = (HCURSOR) getHandle(); - if (c == 0) - c = LoadCursor (0, IDC_ARROW); + if (c == nullptr) + c = LoadCursor (nullptr, IDC_ARROW); else if (c == (HCURSOR) hiddenMouseCursorHandle) - c = 0; + c = nullptr; SetCursor (c); } +JUCE_END_IGNORE_WARNINGS_GCC_LIKE + } // namespace juce diff --git a/modules/juce_gui_basics/native/x11/juce_linux_X11_DragAndDrop.cpp b/modules/juce_gui_basics/native/x11/juce_linux_X11_DragAndDrop.cpp new file mode 100644 index 00000000..ff523ac4 --- /dev/null +++ b/modules/juce_gui_basics/native/x11/juce_linux_X11_DragAndDrop.cpp @@ -0,0 +1,550 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ + +extern void* createDraggingHandCursor(); +extern ComponentPeer* getPeerFor (::Window); + +//============================================================================== +class X11DragState +{ +public: + X11DragState() = default; + + //============================================================================== + bool isDragging() const noexcept + { + return dragging; + } + + //============================================================================== + void handleExternalSelectionClear() + { + if (dragging) + externalResetDragAndDrop(); + } + + void handleExternalSelectionRequest (const XEvent& evt) + { + auto targetType = evt.xselectionrequest.target; + + XEvent s; + s.xselection.type = SelectionNotify; + s.xselection.requestor = evt.xselectionrequest.requestor; + s.xselection.selection = evt.xselectionrequest.selection; + s.xselection.target = targetType; + s.xselection.property = None; + s.xselection.time = evt.xselectionrequest.time; + + if (allowedTypes.contains (targetType)) + { + s.xselection.property = evt.xselectionrequest.property; + + X11Symbols::getInstance()->xChangeProperty (getDisplay(), evt.xselectionrequest.requestor, evt.xselectionrequest.property, + targetType, 8, PropModeReplace, + reinterpret_cast<const unsigned char*> (textOrFiles.toRawUTF8()), + (int) textOrFiles.getNumBytesAsUTF8()); + } + + X11Symbols::getInstance()->xSendEvent (getDisplay(), evt.xselectionrequest.requestor, True, 0, &s); + } + + void handleExternalDragAndDropStatus (const XClientMessageEvent& clientMsg) + { + if (expectingStatus) + { + expectingStatus = false; + canDrop = false; + silentRect = {}; + + if ((clientMsg.data.l[1] & 1) != 0 + && ((Atom) clientMsg.data.l[4] == getAtoms().XdndActionCopy + || (Atom) clientMsg.data.l[4] == getAtoms().XdndActionPrivate)) + { + if ((clientMsg.data.l[1] & 2) == 0) // target requests silent rectangle + silentRect.setBounds ((int) clientMsg.data.l[2] >> 16, (int) clientMsg.data.l[2] & 0xffff, + (int) clientMsg.data.l[3] >> 16, (int) clientMsg.data.l[3] & 0xffff); + + canDrop = true; + } + } + } + + void handleExternalDragButtonReleaseEvent() + { + if (dragging) + X11Symbols::getInstance()->xUngrabPointer (getDisplay(), CurrentTime); + + if (canDrop) + { + sendExternalDragAndDropDrop(); + } + else + { + sendExternalDragAndDropLeave(); + externalResetDragAndDrop(); + } + } + + void handleExternalDragMotionNotify() + { + auto newTargetWindow = externalFindDragTargetWindow (X11Symbols::getInstance()->xRootWindow (getDisplay(), + X11Symbols::getInstance()->xDefaultScreen (getDisplay()))); + + if (targetWindow != newTargetWindow) + { + if (targetWindow != None) + sendExternalDragAndDropLeave(); + + canDrop = false; + silentRect = {}; + + if (newTargetWindow == None) + return; + + xdndVersion = getDnDVersionForWindow (newTargetWindow); + + if (xdndVersion == -1) + return; + + targetWindow = newTargetWindow; + sendExternalDragAndDropEnter(); + } + + if (! expectingStatus) + sendExternalDragAndDropPosition(); + } + + void handleDragAndDropPosition (const XClientMessageEvent& clientMsg, ComponentPeer* peer) + { + if (dragAndDropSourceWindow == 0) + return; + + dragAndDropSourceWindow = (::Window) clientMsg.data.l[0]; + + if (windowH == 0) + windowH = (::Window) peer->getNativeHandle(); + + auto dropPos = Desktop::getInstance().getDisplays().physicalToLogical (Point<int> ((int) clientMsg.data.l[2] >> 16, + (int) clientMsg.data.l[2] & 0xffff)); + dropPos -= peer->getBounds().getPosition(); + + auto targetAction = getAtoms().XdndActionCopy; + + for (int i = numElementsInArray (getAtoms().allowedActions); --i >= 0;) + { + if ((Atom) clientMsg.data.l[4] == getAtoms().allowedActions[i]) + { + targetAction = getAtoms().allowedActions[i]; + break; + } + } + + sendDragAndDropStatus (true, targetAction); + + if (dragInfo.position != dropPos) + { + dragInfo.position = dropPos; + + if (dragInfo.isEmpty()) + updateDraggedFileList (clientMsg, (::Window) peer->getNativeHandle()); + + if (! dragInfo.isEmpty()) + peer->handleDragMove (dragInfo); + } + } + + void handleDragAndDropDrop (const XClientMessageEvent& clientMsg, ComponentPeer* peer) + { + if (dragInfo.isEmpty()) + { + // no data, transaction finished in handleDragAndDropSelection() + finishAfterDropDataReceived = true; + updateDraggedFileList (clientMsg, (::Window) peer->getNativeHandle()); + } + else + { + handleDragAndDropDataReceived(); // data was already received + } + } + + void handleDragAndDropEnter (const XClientMessageEvent& clientMsg, ComponentPeer* peer) + { + dragInfo.clear(); + srcMimeTypeAtomList.clear(); + + dragAndDropCurrentMimeType = 0; + auto dndCurrentVersion = (static_cast<unsigned long> (clientMsg.data.l[1]) & 0xff000000) >> 24; + + if (dndCurrentVersion < 3 || dndCurrentVersion > XWindowSystemUtilities::Atoms::DndVersion) + { + dragAndDropSourceWindow = 0; + return; + } + + dragAndDropSourceWindow = (::Window) clientMsg.data.l[0]; + + if ((clientMsg.data.l[1] & 1) != 0) + { + XWindowSystemUtilities::ScopedXLock xLock; + XWindowSystemUtilities::GetXProperty prop (dragAndDropSourceWindow, getAtoms().XdndTypeList, 0, 0x8000000L, false, XA_ATOM); + + if (prop.success && prop.actualType == XA_ATOM && prop.actualFormat == 32 && prop.numItems != 0) + { + auto* types = prop.data; + + for (unsigned long i = 0; i < prop.numItems; ++i) + { + unsigned long type; + memcpy (&type, types, sizeof (unsigned long)); + + if (type != None) + srcMimeTypeAtomList.add (type); + + types += sizeof (unsigned long); + } + } + } + + if (srcMimeTypeAtomList.isEmpty()) + { + for (int i = 2; i < 5; ++i) + if (clientMsg.data.l[i] != None) + srcMimeTypeAtomList.add ((unsigned long) clientMsg.data.l[i]); + + if (srcMimeTypeAtomList.isEmpty()) + { + dragAndDropSourceWindow = 0; + return; + } + } + + for (int i = 0; i < srcMimeTypeAtomList.size() && dragAndDropCurrentMimeType == 0; ++i) + for (int j = 0; j < numElementsInArray (getAtoms().allowedMimeTypes); ++j) + if (srcMimeTypeAtomList[i] == getAtoms().allowedMimeTypes[j]) + dragAndDropCurrentMimeType = getAtoms().allowedMimeTypes[j]; + + handleDragAndDropPosition (clientMsg, peer); + } + + void handleDragAndDropExit() + { + if (auto* peer = getPeerFor (windowH)) + peer->handleDragExit (dragInfo); + } + + void handleDragAndDropSelection (const XEvent& evt) + { + dragInfo.clear(); + + if (evt.xselection.property != None) + { + StringArray lines; + + { + MemoryBlock dropData; + + for (;;) + { + XWindowSystemUtilities::GetXProperty prop (evt.xany.window, evt.xselection.property, + (long) (dropData.getSize() / 4), 65536, false, AnyPropertyType); + + if (! prop.success) + break; + + dropData.append (prop.data, (size_t) (prop.actualFormat / 8) * prop.numItems); + + if (prop.bytesLeft <= 0) + break; + } + + lines.addLines (dropData.toString()); + } + + if (XWindowSystemUtilities::Atoms::isMimeTypeFile (getDisplay(), dragAndDropCurrentMimeType)) + { + for (int i = 0; i < lines.size(); ++i) + dragInfo.files.add (URL::removeEscapeChars (lines[i].replace ("file://", String(), true))); + + dragInfo.files.trim(); + dragInfo.files.removeEmptyStrings(); + } + else + { + dragInfo.text = lines.joinIntoString ("\n"); + } + + if (finishAfterDropDataReceived) + handleDragAndDropDataReceived(); + } + } + + void externalResetDragAndDrop() + { + if (dragging) + { + XWindowSystemUtilities::ScopedXLock xLock; + X11Symbols::getInstance()->xUngrabPointer (getDisplay(), CurrentTime); + } + + if (completionCallback != nullptr) + completionCallback(); + } + + bool externalDragInit (::Window window, bool text, const String& str, std::function<void()>&& cb) + { + windowH = window; + isText = text; + textOrFiles = str; + targetWindow = windowH; + completionCallback = std::move (cb); + + allowedTypes.add (XWindowSystemUtilities::Atoms::getCreating (getDisplay(), isText ? "text/plain" : "text/uri-list")); + + auto pointerGrabMask = (unsigned int) (Button1MotionMask | ButtonReleaseMask); + + XWindowSystemUtilities::ScopedXLock xLock; + + if (X11Symbols::getInstance()->xGrabPointer (getDisplay(), windowH, True, pointerGrabMask, + GrabModeAsync, GrabModeAsync, None, None, CurrentTime) == GrabSuccess) + { + // No other method of changing the pointer seems to work, this call is needed from this very context + X11Symbols::getInstance()->xChangeActivePointerGrab (getDisplay(), pointerGrabMask, (Cursor) createDraggingHandCursor(), CurrentTime); + + X11Symbols::getInstance()->xSetSelectionOwner (getDisplay(), getAtoms().XdndSelection, windowH, CurrentTime); + + // save the available types to XdndTypeList + X11Symbols::getInstance()->xChangeProperty (getDisplay(), windowH, getAtoms().XdndTypeList, XA_ATOM, 32, PropModeReplace, + reinterpret_cast<const unsigned char*> (allowedTypes.getRawDataPointer()), allowedTypes.size()); + + dragging = true; + xdndVersion = getDnDVersionForWindow (targetWindow); + + sendExternalDragAndDropEnter(); + handleExternalDragMotionNotify(); + + return true; + } + + return false; + } + +private: + //============================================================================== + XWindowSystemUtilities::Atoms& getAtoms() const { return XWindowSystem::getInstance()->getAtoms(); } + ::Display* getDisplay() const { return XWindowSystem::getInstance()->getDisplay(); } + + //============================================================================== + void sendDragAndDropMessage (XClientMessageEvent& msg) + { + msg.type = ClientMessage; + msg.display = getDisplay(); + msg.window = dragAndDropSourceWindow; + msg.format = 32; + msg.data.l[0] = (long) windowH; + + XWindowSystemUtilities::ScopedXLock xLock; + X11Symbols::getInstance()->xSendEvent (getDisplay(), dragAndDropSourceWindow, False, 0, (XEvent*) &msg); + } + + bool sendExternalDragAndDropMessage (XClientMessageEvent& msg) + { + msg.type = ClientMessage; + msg.display = getDisplay(); + msg.window = targetWindow; + msg.format = 32; + msg.data.l[0] = (long) windowH; + + XWindowSystemUtilities::ScopedXLock xLock; + return X11Symbols::getInstance()->xSendEvent (getDisplay(), targetWindow, False, 0, (XEvent*) &msg) != 0; + } + + void sendExternalDragAndDropDrop() + { + XClientMessageEvent msg; + zerostruct (msg); + + msg.message_type = getAtoms().XdndDrop; + msg.data.l[2] = CurrentTime; + + sendExternalDragAndDropMessage (msg); + } + + void sendExternalDragAndDropEnter() + { + XClientMessageEvent msg; + zerostruct (msg); + + msg.message_type = getAtoms().XdndEnter; + msg.data.l[1] = (xdndVersion << 24); + + for (int i = 0; i < 3; ++i) + msg.data.l[i + 2] = (long) allowedTypes[i]; + + sendExternalDragAndDropMessage (msg); + } + + void sendExternalDragAndDropPosition() + { + XClientMessageEvent msg; + zerostruct (msg); + + msg.message_type = getAtoms().XdndPosition; + + auto mousePos = Desktop::getInstance().getMousePosition(); + + if (silentRect.contains (mousePos)) // we've been asked to keep silent + return; + + mousePos = Desktop::getInstance().getDisplays().logicalToPhysical (mousePos); + + msg.data.l[1] = 0; + msg.data.l[2] = (mousePos.x << 16) | mousePos.y; + msg.data.l[3] = CurrentTime; + msg.data.l[4] = (long) getAtoms().XdndActionCopy; // this is all JUCE currently supports + + expectingStatus = sendExternalDragAndDropMessage (msg); + } + + void sendDragAndDropStatus (bool acceptDrop, Atom dropAction) + { + XClientMessageEvent msg; + zerostruct (msg); + + msg.message_type = getAtoms().XdndStatus; + msg.data.l[1] = (acceptDrop ? 1 : 0) | 2; // 2 indicates that we want to receive position messages + msg.data.l[4] = (long) dropAction; + + sendDragAndDropMessage (msg); + } + + void sendExternalDragAndDropLeave() + { + XClientMessageEvent msg; + zerostruct (msg); + + msg.message_type = getAtoms().XdndLeave; + sendExternalDragAndDropMessage (msg); + } + + void sendDragAndDropFinish() + { + XClientMessageEvent msg; + zerostruct (msg); + + msg.message_type = getAtoms().XdndFinished; + sendDragAndDropMessage (msg); + } + + void updateDraggedFileList (const XClientMessageEvent& clientMsg, ::Window requestor) + { + jassert (dragInfo.isEmpty()); + + if (dragAndDropSourceWindow != None && dragAndDropCurrentMimeType != None) + { + XWindowSystemUtilities::ScopedXLock xLock; + X11Symbols::getInstance()->xConvertSelection (getDisplay(), getAtoms().XdndSelection, dragAndDropCurrentMimeType, + XWindowSystemUtilities::Atoms::getCreating (getDisplay(), "JXSelectionWindowProperty"), + requestor, (::Time) clientMsg.data.l[2]); + } + } + + bool isWindowDnDAware (::Window w) const + { + int numProperties = 0; + auto* properties = X11Symbols::getInstance()->xListProperties (getDisplay(), w, &numProperties); + + bool dndAwarePropFound = false; + + for (int i = 0; i < numProperties; ++i) + if (properties[i] == getAtoms().XdndAware) + dndAwarePropFound = true; + + if (properties != nullptr) + X11Symbols::getInstance()->xFree (properties); + + return dndAwarePropFound; + } + + int getDnDVersionForWindow (::Window target) + { + XWindowSystemUtilities::GetXProperty prop (target, getAtoms().XdndAware, 0, 2, false, AnyPropertyType); + + if (prop.success && prop.data != None && prop.actualFormat == 32 && prop.numItems == 1) + return jmin ((int) prop.data[0], (int) XWindowSystemUtilities::Atoms::DndVersion); + + return -1; + } + + ::Window externalFindDragTargetWindow (::Window target) + { + if (target == None) + return None; + + if (isWindowDnDAware (target)) + return target; + + ::Window child, phonyWin; + int phony; + unsigned int uphony; + + X11Symbols::getInstance()->xQueryPointer (getDisplay(), target, &phonyWin, &child, &phony, &phony, &phony, &phony, &uphony); + + return externalFindDragTargetWindow (child); + } + + void handleDragAndDropDataReceived() + { + ComponentPeer::DragInfo dragInfoCopy (dragInfo); + + sendDragAndDropFinish(); + + if (! dragInfoCopy.isEmpty()) + if (auto* peer = getPeerFor (windowH)) + peer->handleDragDrop (dragInfoCopy); + } + + //============================================================================== + ::Window windowH = 0, targetWindow = 0, dragAndDropSourceWindow = 0; + + int xdndVersion = -1; + bool isText = false, dragging = false, expectingStatus = false, canDrop = false, finishAfterDropDataReceived = false; + + Atom dragAndDropCurrentMimeType; + Array<Atom> allowedTypes, srcMimeTypeAtomList; + + ComponentPeer::DragInfo dragInfo; + Rectangle<int> silentRect; + String textOrFiles; + + std::function<void()> completionCallback = nullptr; + + //============================================================================== + JUCE_LEAK_DETECTOR (X11DragState) +}; + +} // namespace juce diff --git a/modules/juce_gui_basics/native/x11/juce_linux_X11_Symbols.cpp b/modules/juce_gui_basics/native/x11/juce_linux_X11_Symbols.cpp new file mode 100644 index 00000000..3c650291 --- /dev/null +++ b/modules/juce_gui_basics/native/x11/juce_linux_X11_Symbols.cpp @@ -0,0 +1,238 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ + +namespace X11SymbolHelpers +{ + +template<typename FuncPtr> +struct SymbolBinding +{ + FuncPtr& func; + const char* name; +}; + +template<typename FuncPtr> +SymbolBinding<FuncPtr> makeSymbolBinding (FuncPtr& func, const char* name) +{ + return { func, name }; +} + +template <typename FuncPtr> +bool loadSymbols (DynamicLibrary& lib, SymbolBinding<FuncPtr> binding) +{ + if (auto* func = lib.getFunction (binding.name)) + { + binding.func = reinterpret_cast<FuncPtr> (func); + return true; + } + + return false; +} + +template<typename FuncPtr, typename... Args> +bool loadSymbols (DynamicLibrary& lib1, DynamicLibrary& lib2, SymbolBinding<FuncPtr> binding) +{ + return loadSymbols (lib1, binding) || loadSymbols (lib2, binding); +} + +template<typename FuncPtr, typename... Args> +bool loadSymbols (DynamicLibrary& lib, SymbolBinding<FuncPtr> binding, Args... args) +{ + return loadSymbols (lib, binding) && loadSymbols (lib, args...); +} + +template<typename FuncPtr, typename... Args> +bool loadSymbols (DynamicLibrary& lib1, DynamicLibrary& lib2, SymbolBinding<FuncPtr> binding, Args... args) +{ + return loadSymbols (lib1, lib2, binding) && loadSymbols (lib1, lib2, args...); +} + +} + +//============================================================================== +bool X11Symbols::loadAllSymbols() +{ + using namespace X11SymbolHelpers; + + if (! loadSymbols (xLib, xextLib, + makeSymbolBinding (xAllocClassHint, "XAllocClassHint"), + makeSymbolBinding (xAllocSizeHints, "XAllocSizeHints"), + makeSymbolBinding (xAllocWMHints, "XAllocWMHints"), + makeSymbolBinding (xBitmapBitOrder, "XBitmapBitOrder"), + makeSymbolBinding (xBitmapUnit, "XBitmapUnit"), + makeSymbolBinding (xChangeActivePointerGrab, "XChangeActivePointerGrab"), + makeSymbolBinding (xChangeProperty, "XChangeProperty"), + makeSymbolBinding (xCheckTypedWindowEvent, "XCheckTypedWindowEvent"), + makeSymbolBinding (xCheckWindowEvent, "XCheckWindowEvent"), + makeSymbolBinding (xClearArea, "XClearArea"), + makeSymbolBinding (xCloseDisplay, "XCloseDisplay"), + makeSymbolBinding (xConnectionNumber, "XConnectionNumber"), + makeSymbolBinding (xConvertSelection, "XConvertSelection"), + makeSymbolBinding (xCreateColormap, "XCreateColormap"), + makeSymbolBinding (xCreateFontCursor, "XCreateFontCursor"), + makeSymbolBinding (xCreateGC, "XCreateGC"), + makeSymbolBinding (xCreateImage, "XCreateImage"), + makeSymbolBinding (xCreatePixmap, "XCreatePixmap"), + makeSymbolBinding (xCreatePixmapCursor, "XCreatePixmapCursor"), + makeSymbolBinding (xCreatePixmapFromBitmapData, "XCreatePixmapFromBitmapData"), + makeSymbolBinding (xCreateWindow, "XCreateWindow"), + makeSymbolBinding (xDefaultRootWindow, "XDefaultRootWindow"), + makeSymbolBinding (xDefaultScreen, "XDefaultScreen"), + makeSymbolBinding (xDefaultScreenOfDisplay, "XDefaultScreenOfDisplay"), + makeSymbolBinding (xDefaultVisual, "XDefaultVisual"), + makeSymbolBinding (xDefineCursor, "XDefineCursor"), + makeSymbolBinding (xDeleteContext, "XDeleteContext"), + makeSymbolBinding (xDeleteProperty, "XDeleteProperty"), + makeSymbolBinding (xDestroyImage, "XDestroyImage"), + makeSymbolBinding (xDestroyWindow, "XDestroyWindow"), + makeSymbolBinding (xDisplayHeight, "XDisplayHeight"), + makeSymbolBinding (xDisplayHeightMM, "XDisplayHeightMM"), + makeSymbolBinding (xDisplayWidth, "XDisplayWidth"), + makeSymbolBinding (xDisplayWidthMM, "XDisplayWidthMM"), + makeSymbolBinding (xEventsQueued, "XEventsQueued"), + makeSymbolBinding (xFindContext, "XFindContext"), + makeSymbolBinding (xFlush, "XFlush"), + makeSymbolBinding (xFree, "XFree"), + makeSymbolBinding (xFreeCursor, "XFreeCursor"), + makeSymbolBinding (xFreeColormap, "XFreeColormap"), + makeSymbolBinding (xFreeGC, "XFreeGC"), + makeSymbolBinding (xFreeModifiermap, "XFreeModifiermap"), + makeSymbolBinding (xFreePixmap, "XFreePixmap"), + makeSymbolBinding (xGetAtomName, "XGetAtomName"), + makeSymbolBinding (xGetErrorDatabaseText, "XGetErrorDatabaseText"), + makeSymbolBinding (xGetErrorText, "XGetErrorText"), + makeSymbolBinding (xGetGeometry, "XGetGeometry"), + makeSymbolBinding (xGetInputFocus, "XGetInputFocus"), + makeSymbolBinding (xGetModifierMapping, "XGetModifierMapping"), + makeSymbolBinding (xGetPointerMapping, "XGetPointerMapping"), + makeSymbolBinding (xGetSelectionOwner, "XGetSelectionOwner"), + makeSymbolBinding (xGetVisualInfo, "XGetVisualInfo"), + makeSymbolBinding (xGetWMHints, "XGetWMHints"), + makeSymbolBinding (xGetWindowAttributes, "XGetWindowAttributes"), + makeSymbolBinding (xGetWindowProperty, "XGetWindowProperty"), + makeSymbolBinding (xGrabPointer, "XGrabPointer"), + makeSymbolBinding (xGrabServer, "XGrabServer"), + makeSymbolBinding (xImageByteOrder, "XImageByteOrder"), + makeSymbolBinding (xInitImage, "XInitImage"), + makeSymbolBinding (xInitThreads, "XInitThreads"), + makeSymbolBinding (xInstallColormap, "XInstallColormap"), + makeSymbolBinding (xInternAtom, "XInternAtom"), + makeSymbolBinding (xkbKeycodeToKeysym, "XkbKeycodeToKeysym"), + makeSymbolBinding (xKeysymToKeycode, "XKeysymToKeycode"), + makeSymbolBinding (xListProperties, "XListProperties"), + makeSymbolBinding (xLockDisplay, "XLockDisplay"), + makeSymbolBinding (xLookupString, "XLookupString"), + makeSymbolBinding (xMapRaised, "XMapRaised"), + makeSymbolBinding (xMapWindow, "XMapWindow"), + makeSymbolBinding (xMoveResizeWindow, "XMoveResizeWindow"), + makeSymbolBinding (xNextEvent, "XNextEvent"), + makeSymbolBinding (xOpenDisplay, "XOpenDisplay"), + makeSymbolBinding (xPeekEvent, "XPeekEvent"), + makeSymbolBinding (xPending, "XPending"), + makeSymbolBinding (xPutImage, "XPutImage"), + makeSymbolBinding (xPutPixel, "XPutPixel"), + makeSymbolBinding (xQueryBestCursor, "XQueryBestCursor"), + makeSymbolBinding (xQueryExtension, "XQueryExtension"), + makeSymbolBinding (xQueryPointer, "XQueryPointer"), + makeSymbolBinding (xQueryTree, "XQueryTree"), + makeSymbolBinding (xRefreshKeyboardMapping, "XRefreshKeyboardMapping"), + makeSymbolBinding (xReparentWindow, "XReparentWindow"), + makeSymbolBinding (xResizeWindow, "XResizeWindow"), + makeSymbolBinding (xRestackWindows, "XRestackWindows"), + makeSymbolBinding (xRootWindow, "XRootWindow"), + makeSymbolBinding (xSaveContext, "XSaveContext"), + makeSymbolBinding (xScreenCount, "XScreenCount"), + makeSymbolBinding (xScreenNumberOfScreen, "XScreenNumberOfScreen"), + makeSymbolBinding (xSelectInput, "XSelectInput"), + makeSymbolBinding (xSendEvent, "XSendEvent"), + makeSymbolBinding (xSetClassHint, "XSetClassHint"), + makeSymbolBinding (xSetErrorHandler, "XSetErrorHandler"), + makeSymbolBinding (xSetIOErrorHandler, "XSetIOErrorHandler"), + makeSymbolBinding (xSetInputFocus, "XSetInputFocus"), + makeSymbolBinding (xSetSelectionOwner, "XSetSelectionOwner"), + makeSymbolBinding (xSetWMHints, "XSetWMHints"), + makeSymbolBinding (xSetWMIconName, "XSetWMIconName"), + makeSymbolBinding (xSetWMName, "XSetWMName"), + makeSymbolBinding (xSetWMNormalHints, "XSetWMNormalHints"), + makeSymbolBinding (xStringListToTextProperty, "XStringListToTextProperty"), + makeSymbolBinding (xSync, "XSync"), + makeSymbolBinding (xSynchronize, "XSynchronize"), + makeSymbolBinding (xTranslateCoordinates, "XTranslateCoordinates"), + makeSymbolBinding (xrmUniqueQuark, "XrmUniqueQuark"), + makeSymbolBinding (xUngrabPointer, "XUngrabPointer"), + makeSymbolBinding (xUngrabServer, "XUngrabServer"), + makeSymbolBinding (xUnlockDisplay, "XUnlockDisplay"), + makeSymbolBinding (xUnmapWindow, "XUnmapWindow"), + makeSymbolBinding (xWarpPointer, "XWarpPointer"))) + return false; + + #if JUCE_USE_XCURSOR + loadSymbols (xcursorLib, + makeSymbolBinding (xcursorImageCreate, "XcursorImageCreate"), + makeSymbolBinding (xcursorImageLoadCursor, "XcursorImageLoadCursor"), + makeSymbolBinding (xcursorImageDestroy, "XcursorImageDestroy")); + #endif + #if JUCE_USE_XINERAMA + loadSymbols (xineramaLib, + makeSymbolBinding (xineramaIsActive, "XineramaIsActive"), + makeSymbolBinding (xineramaQueryScreens, "XineramaQueryScreens")); + #endif + #if JUCE_USE_XRENDER + loadSymbols (xrenderLib, + makeSymbolBinding (xRenderQueryVersion, "XRenderQueryVersion"), + makeSymbolBinding (xRenderFindStandardFormat, "XRenderFindStandardFormat"), + makeSymbolBinding (xRenderFindFormat, "XRenderFindFormat"), + makeSymbolBinding (xRenderFindVisualFormat, "XRenderFindVisualFormat")); + #endif + #if JUCE_USE_XRANDR + loadSymbols (xrandrLib, + makeSymbolBinding (xRRGetScreenResources, "XRRGetScreenResources"), + makeSymbolBinding (xRRFreeScreenResources, "XRRFreeScreenResources"), + makeSymbolBinding (xRRGetOutputInfo, "XRRGetOutputInfo"), + makeSymbolBinding (xRRFreeOutputInfo, "XRRFreeOutputInfo"), + makeSymbolBinding (xRRGetCrtcInfo, "XRRGetCrtcInfo"), + makeSymbolBinding (xRRFreeCrtcInfo, "XRRFreeCrtcInfo"), + makeSymbolBinding (xRRGetOutputPrimary, "XRRGetOutputPrimary")); + #endif + #if JUCE_USE_XSHM + loadSymbols (xLib, xextLib, + makeSymbolBinding (xShmAttach, "XShmAttach"), + makeSymbolBinding (xShmCreateImage, "XShmCreateImage"), + makeSymbolBinding (xShmDetach, "XShmDetach"), + makeSymbolBinding (xShmGetEventBase, "XShmGetEventBase"), + makeSymbolBinding (xShmPutImage, "XShmPutImage"), + makeSymbolBinding (xShmQueryVersion, "XShmQueryVersion")); + #endif + + return true; +} + +//============================================================================== +JUCE_IMPLEMENT_SINGLETON (X11Symbols) + +} diff --git a/modules/juce_gui_basics/native/x11/juce_linux_X11_Symbols.h b/modules/juce_gui_basics/native/x11/juce_linux_X11_Symbols.h new file mode 100644 index 00000000..d1cb01b3 --- /dev/null +++ b/modules/juce_gui_basics/native/x11/juce_linux_X11_Symbols.h @@ -0,0 +1,612 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ + +//============================================================================== +namespace ReturnHelpers +{ + template<typename Type> + Type returnDefaultConstructedAnyType() { return {}; } + + template<> + inline void returnDefaultConstructedAnyType<void>() {} +} + +#define JUCE_GENERATE_FUNCTION_WITH_DEFAULT(functionName, objectName, args, returnType) \ + using functionName = returnType (*) args; \ + functionName objectName = [] args -> returnType { return ReturnHelpers::returnDefaultConstructedAnyType<returnType>(); }; + + +//============================================================================== +class JUCE_API X11Symbols +{ +public: + //============================================================================== + bool loadAllSymbols(); + + //============================================================================== + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XAllocClassHint, xAllocClassHint, + (), + XClassHint*) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XAllocSizeHints, xAllocSizeHints, + (), + XSizeHints*) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XAllocWMHints, xAllocWMHints, + (), + XWMHints*) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XBitmapBitOrder, xBitmapBitOrder, + (::Display*), + int) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XBitmapUnit, xBitmapUnit, + (::Display*), + int) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XChangeActivePointerGrab, xChangeActivePointerGrab, + (::Display*, unsigned int, Cursor, ::Time), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XChangeProperty, xChangeProperty, + (::Display*, ::Window, Atom, Atom, int, int, const unsigned char*, int), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XCheckTypedWindowEvent, xCheckTypedWindowEvent, + (::Display*, ::Window, int, XEvent*), + Bool) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XCheckWindowEvent, xCheckWindowEvent, + (::Display*, ::Window, long, XEvent*), + Bool) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XClearArea, xClearArea, + (::Display*, ::Window, int, int, unsigned int, unsigned int, Bool), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XCloseDisplay, xCloseDisplay, + (::Display*), + int) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XConnectionNumber, xConnectionNumber, + (::Display*), + int) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XConvertSelection, xConvertSelection, + (::Display*, Atom, Atom, Atom, ::Window, ::Time), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XCreateColormap, xCreateColormap, + (::Display*, ::Window, Visual*, int), + Colormap) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XCreateFontCursor, xCreateFontCursor, + (::Display*, unsigned int), + Cursor) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XCreateGC, xCreateGC, + (::Display*, ::Drawable, unsigned long, XGCValues*), + GC) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XCreateImage, xCreateImage, + (::Display*, Visual*, unsigned int, int, int, const char*, unsigned int, unsigned int, int, int), + XImage*) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XCreatePixmap, xCreatePixmap, + (::Display*, ::Drawable, unsigned int, unsigned int, unsigned int), + Pixmap) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XCreatePixmapCursor, xCreatePixmapCursor, + (::Display*, Pixmap, Pixmap, XColor*, XColor*, unsigned int, unsigned int), + Cursor) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XCreatePixmapFromBitmapData, xCreatePixmapFromBitmapData, + (::Display*, ::Drawable, const char*, unsigned int, unsigned int, unsigned long, unsigned long, unsigned int), + Pixmap) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XCreateWindow, xCreateWindow, + (::Display*, ::Window, int, int, unsigned int, unsigned int, unsigned int, int, unsigned int, Visual*, unsigned long, XSetWindowAttributes*), + ::Window) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XDefaultRootWindow, xDefaultRootWindow, + (::Display*), + ::Window) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XDefaultScreen, xDefaultScreen, + (::Display*), + int) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XDefaultScreenOfDisplay, xDefaultScreenOfDisplay, + (::Display*), + Screen*) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XDefaultVisual, xDefaultVisual, + (::Display*, int), + Visual*) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XDefineCursor, xDefineCursor, + (::Display*, ::Window, Cursor), + int) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XDeleteContext, xDeleteContext, + (::Display*, XID, XContext), + int) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XDeleteProperty, xDeleteProperty, + (::Display*, Window, Atom), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XDestroyImage, xDestroyImage, + (XImage*), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XDestroyWindow, xDestroyWindow, + (::Display*, ::Window), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XDisplayHeight, xDisplayHeight, + (::Display*, int), + int) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XDisplayHeightMM, xDisplayHeightMM, + (::Display*, int), + int) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XDisplayWidth, xDisplayWidth, + (::Display*, int), + int) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XDisplayWidthMM, xDisplayWidthMM, + (::Display*, int), + int) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XEventsQueued, xEventsQueued, + (::Display*, int), + int) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XFindContext, xFindContext, + (::Display*, XID, XContext, XPointer*), + int) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XFlush, xFlush, + (::Display*), + int) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XFree, xFree, + (void*), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XFreeCursor, xFreeCursor, + (::Display*, Cursor), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XFreeColormap ,xFreeColormap, + (::Display*, Colormap), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XFreeGC, xFreeGC, + (::Display*, GC), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XFreeModifiermap, xFreeModifiermap, + (XModifierKeymap*), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XFreePixmap, xFreePixmap, + (::Display*, Pixmap), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XGetAtomName, xGetAtomName, + (::Display*, Atom), + char*) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XGetErrorDatabaseText, xGetErrorDatabaseText, + (::Display*, const char*, const char*, const char*, const char*, int), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XGetErrorText, xGetErrorText, + (::Display*, int, const char*, int), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XGetGeometry, xGetGeometry, + (::Display*, ::Drawable, ::Window*, int*, int*, unsigned int*, unsigned int*, unsigned int*, unsigned int*), + Status) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XGetInputFocus, xGetInputFocus, + (::Display*, ::Window*, int*), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XGetModifierMapping, xGetModifierMapping, + (::Display*), + XModifierKeymap*) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XGetPointerMapping, xGetPointerMapping, + (::Display*, unsigned char[], int), + int) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XGetSelectionOwner, xGetSelectionOwner, + (::Display*, Atom), + ::Window) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XGetVisualInfo, xGetVisualInfo, + (::Display*, long, XVisualInfo*, int*), + XVisualInfo*) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XGetWMHints, xGetWMHints, + (::Display*, ::Window), + XWMHints*) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XGetWindowAttributes, xGetWindowAttributes, + (::Display*, ::Window, XWindowAttributes*), + Status) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XGetWindowProperty, xGetWindowProperty, + (::Display*, ::Window, Atom, long, long, Bool, Atom, Atom*, int*, unsigned long*, unsigned long*, unsigned char**), + int) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XGrabPointer, xGrabPointer, + (::Display*, ::Window, Bool, unsigned int, int, int, ::Window, Cursor, ::Time), + int) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XGrabServer, xGrabServer, + (::Display*), + int) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XImageByteOrder, xImageByteOrder, + (::Display*), + int) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XInitImage, xInitImage, + (XImage*), + Status) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XInitThreads, xInitThreads, + (), + Status) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XInstallColormap, xInstallColormap, + (::Display*, Colormap), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XInternAtom, xInternAtom, + (::Display*, const char*, Bool), + Atom) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XkbKeycodeToKeysym, xkbKeycodeToKeysym, + (::Display*, KeyCode, unsigned int, unsigned int), + KeySym) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XKeysymToKeycode, xKeysymToKeycode, + (::Display*, KeySym), + KeyCode) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XListProperties, xListProperties, + (::Display*, Window, int*), + Atom*) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XLockDisplay, xLockDisplay, + (::Display*), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XLookupString, xLookupString, + (XKeyEvent*, const char*, int, KeySym*, XComposeStatus*), + int) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XMapRaised, xMapRaised, + (::Display*, ::Window), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XMapWindow, xMapWindow, + (::Display*, ::Window), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XMoveResizeWindow, xMoveResizeWindow, + (::Display*, ::Window, int, int, unsigned int, unsigned int), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XNextEvent, xNextEvent, + (::Display*, XEvent*), + int) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XOpenDisplay, xOpenDisplay, + (const char*), + ::Display*) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XPeekEvent, xPeekEvent, + (::Display*, XEvent*), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XPending, xPending, + (::Display*), + int) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XPutImage, xPutImage, + (::Display*, ::Drawable, GC, XImage*, int, int, int, int, unsigned int, unsigned int), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XPutPixel, xPutPixel, + (XImage*, int, int, unsigned long), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XQueryBestCursor, xQueryBestCursor, + (::Display*, ::Drawable, unsigned int, unsigned int, unsigned int*, unsigned int*), + Status) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XQueryExtension, xQueryExtension, + (::Display*, const char*, int*, int*, int*), + Bool) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XQueryPointer, xQueryPointer, + (::Display*, ::Window, ::Window*, ::Window*, int*, int*, int*, int*, unsigned int*), + Bool) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XQueryTree, xQueryTree, + (::Display*, ::Window, ::Window*, ::Window*, ::Window**, unsigned int*), + Status) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XRefreshKeyboardMapping, xRefreshKeyboardMapping, + (XMappingEvent*), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XReparentWindow, xReparentWindow, + (::Display*, ::Window, ::Window, int, int), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XResizeWindow, xResizeWindow, + (::Display*, Window, unsigned int, unsigned int), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XRestackWindows, xRestackWindows, + (::Display*, ::Window[], int), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XRootWindow, xRootWindow, + (::Display*, int), + ::Window) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XSaveContext, xSaveContext, + (::Display*, XID, XContext, XPointer), + int) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XScreenCount, xScreenCount, + (::Display*), + int) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XScreenNumberOfScreen, xScreenNumberOfScreen, + (Screen*), + int) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XSelectInput, xSelectInput, + (::Display*, ::Window, long), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XSendEvent, xSendEvent, + (::Display*, ::Window, Bool, long, XEvent*), + Status) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XSetClassHint, xSetClassHint, + (::Display*, ::Window, XClassHint*), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XSetErrorHandler, xSetErrorHandler, + (XErrorHandler), + XErrorHandler) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XSetIOErrorHandler, xSetIOErrorHandler, + (XIOErrorHandler), + XIOErrorHandler) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XSetInputFocus, xSetInputFocus, + (::Display*, ::Window, int, ::Time), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XSetSelectionOwner, xSetSelectionOwner, + (::Display*, Atom, ::Window, ::Time), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XSetWMHints, xSetWMHints, + (::Display*, ::Window, XWMHints*), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XSetWMIconName, xSetWMIconName, + (::Display*, ::Window, XTextProperty*), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XSetWMName, xSetWMName, + (::Display*, ::Window, XTextProperty*), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XSetWMNormalHints, xSetWMNormalHints, + (::Display*, ::Window, XSizeHints*), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XStringListToTextProperty, xStringListToTextProperty, + (char**, int, XTextProperty*), + Status) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XSync, xSync, + (::Display*, Bool), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XSynchronize, xSynchronize, + (::Display*, Bool), + int) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XTranslateCoordinates, xTranslateCoordinates, + (::Display*, ::Window, ::Window, int, int, int*, int*, ::Window*), + Bool) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XrmUniqueQuark, xrmUniqueQuark, + (), + int) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XUngrabPointer, xUngrabPointer, + (::Display*, ::Time), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XUngrabServer, xUngrabServer, + (::Display*), + int) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XUnlockDisplay, xUnlockDisplay, + (::Display*), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XUnmapWindow, xUnmapWindow, + (::Display*, ::Window), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XWarpPointer, xWarpPointer, + (::Display*, ::Window, ::Window, int, int, unsigned int, unsigned int, int, int), + void) + #if JUCE_USE_XCURSOR + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XcursorImageCreate, xcursorImageCreate, + (int, int), + XcursorImage*) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XcursorImageLoadCursor, xcursorImageLoadCursor, + (::Display*, XcursorImage*), + Cursor) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XcursorImageDestroy, xcursorImageDestroy, + (XcursorImage*), + void) + #endif + #if JUCE_USE_XINERAMA + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XineramaIsActive, xineramaIsActive, + (::Display*), + Bool) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XineramaQueryScreens, xineramaQueryScreens, + (::Display*, int*), + XineramaScreenInfo*) + #endif + #if JUCE_USE_XRENDER + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XRenderQueryVersion, xRenderQueryVersion, + (::Display*, int*, int*), + Status) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XRenderFindStandardFormat, xRenderFindStandardFormat, + (Display*, int), + XRenderPictFormat*) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XRenderFindFormat, xRenderFindFormat, + (Display*, unsigned long, XRenderPictFormat*, int), + XRenderPictFormat*) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XRenderFindVisualFormat, xRenderFindVisualFormat, + (Display*, Visual*), + XRenderPictFormat*) + #endif + #if JUCE_USE_XRANDR + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XRRGetScreenResources, xRRGetScreenResources, + (::Display*, Window), + XRRScreenResources*) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XRRFreeScreenResources, xRRFreeScreenResources, + (XRRScreenResources*), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XRRGetOutputInfo, xRRGetOutputInfo, + (::Display*, XRRScreenResources*, RROutput), + XRROutputInfo*) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XRRFreeOutputInfo, xRRFreeOutputInfo, + (XRROutputInfo*), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XRRGetCrtcInfo, xRRGetCrtcInfo, + (::Display*, XRRScreenResources*, RRCrtc), + XRRCrtcInfo*) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XRRFreeCrtcInfo, xRRFreeCrtcInfo, + (XRRCrtcInfo*), + void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XRRGetOutputPrimary, xRRGetOutputPrimary, + (::Display*, ::Window), + RROutput) + #endif + #if JUCE_USE_XSHM + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XShmAttach, xShmAttach, + (::Display*, XShmSegmentInfo*), + Bool) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XShmCreateImage, xShmCreateImage, + (::Display*, Visual*, unsigned int, int, const char*, XShmSegmentInfo*, unsigned int, unsigned int), + XImage*) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XShmDetach, xShmDetach, + (::Display*, XShmSegmentInfo*), + Bool) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XShmGetEventBase, xShmGetEventBase, + (::Display*), + Status) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XShmPutImage, xShmPutImage, + (::Display*, ::Drawable, GC, XImage*, int, int, int, int, unsigned int, unsigned int, bool), + Bool) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (XShmQueryVersion, xShmQueryVersion, + (::Display*, int*, int*, Bool*), + Bool) + #endif + + //============================================================================== + JUCE_DECLARE_SINGLETON_SINGLETHREADED_MINIMAL (X11Symbols) + +private: + X11Symbols() = default; + + ~X11Symbols() + { + clearSingletonInstance(); + } + + //============================================================================== + DynamicLibrary xLib { "libX11.so.6" }, xextLib { "libXext.so.6" }; + + #if JUCE_USE_XCURSOR + DynamicLibrary xcursorLib { "libXcursor.so.1" }; + #endif + #if JUCE_USE_XINERAMA + DynamicLibrary xineramaLib { "libXinerama.so.1" }; + #endif + #if JUCE_USE_XRENDER + DynamicLibrary xrenderLib { "libXrender.so.1" }; + #endif + #if JUCE_USE_XRANDR + DynamicLibrary xrandrLib { "libXrandr.so.2" }; + #endif + + //============================================================================== + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (X11Symbols) +}; + +} diff --git a/modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.cpp b/modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.cpp new file mode 100644 index 00000000..2c87a471 --- /dev/null +++ b/modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.cpp @@ -0,0 +1,3489 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +#include <unordered_map> + +namespace juce +{ + +#if JUCE_DEBUG && ! defined (JUCE_DEBUG_XERRORS) + #define JUCE_DEBUG_XERRORS 1 + + #if ! defined (JUCE_DEBUG_XERRORS_SYNCHRONOUSLY) + #define JUCE_DEBUG_XERRORS_SYNCHRONOUSLY 1 + #endif +#endif + +#if JUCE_MODULE_AVAILABLE_juce_gui_extra + #define JUCE_X11_SUPPORTS_XEMBED 1 +#else + #define JUCE_X11_SUPPORTS_XEMBED 0 +#endif + +//============================================================================== +XWindowSystemUtilities::ScopedXLock::ScopedXLock() +{ + if (auto* xWindow = XWindowSystem::getInstanceWithoutCreating()) + if (auto* d = xWindow->getDisplay()) + X11Symbols::getInstance()->xLockDisplay (d); +} + +XWindowSystemUtilities::ScopedXLock::~ScopedXLock() +{ + if (auto* xWindow = XWindowSystem::getInstanceWithoutCreating()) + if (auto* d = xWindow->getDisplay()) + X11Symbols::getInstance()->xUnlockDisplay (d); +} + +//============================================================================== +XWindowSystemUtilities::Atoms::Atoms (::Display* display) +{ + protocols = getIfExists (display, "WM_PROTOCOLS"); + protocolList [TAKE_FOCUS] = getIfExists (display, "WM_TAKE_FOCUS"); + protocolList [DELETE_WINDOW] = getIfExists (display, "WM_DELETE_WINDOW"); + protocolList [PING] = getIfExists (display, "_NET_WM_PING"); + changeState = getIfExists (display, "WM_CHANGE_STATE"); + state = getIfExists (display, "WM_STATE"); + userTime = getCreating (display, "_NET_WM_USER_TIME"); + activeWin = getCreating (display, "_NET_ACTIVE_WINDOW"); + pid = getCreating (display, "_NET_WM_PID"); + windowType = getIfExists (display, "_NET_WM_WINDOW_TYPE"); + windowState = getIfExists (display, "_NET_WM_STATE"); + + XdndAware = getCreating (display, "XdndAware"); + XdndEnter = getCreating (display, "XdndEnter"); + XdndLeave = getCreating (display, "XdndLeave"); + XdndPosition = getCreating (display, "XdndPosition"); + XdndStatus = getCreating (display, "XdndStatus"); + XdndDrop = getCreating (display, "XdndDrop"); + XdndFinished = getCreating (display, "XdndFinished"); + XdndSelection = getCreating (display, "XdndSelection"); + + XdndTypeList = getCreating (display, "XdndTypeList"); + XdndActionList = getCreating (display, "XdndActionList"); + XdndActionCopy = getCreating (display, "XdndActionCopy"); + XdndActionPrivate = getCreating (display, "XdndActionPrivate"); + XdndActionDescription = getCreating (display, "XdndActionDescription"); + + XembedMsgType = getCreating (display, "_XEMBED"); + XembedInfo = getCreating (display, "_XEMBED_INFO"); + + allowedMimeTypes[0] = getCreating (display, "UTF8_STRING"); + allowedMimeTypes[1] = getCreating (display, "text/plain;charset=utf-8"); + allowedMimeTypes[2] = getCreating (display, "text/plain"); + allowedMimeTypes[3] = getCreating (display, "text/uri-list"); + + allowedActions[0] = getCreating (display, "XdndActionMove"); + allowedActions[1] = XdndActionCopy; + allowedActions[2] = getCreating (display, "XdndActionLink"); + allowedActions[3] = getCreating (display, "XdndActionAsk"); + allowedActions[4] = XdndActionPrivate; + + utf8String = getCreating (display, "UTF8_STRING"); + clipboard = getCreating (display, "CLIPBOARD"); + targets = getCreating (display, "TARGETS"); +} + +Atom XWindowSystemUtilities::Atoms::getIfExists (::Display* display, const char* name) +{ + return X11Symbols::getInstance()->xInternAtom (display, name, True); +} + +Atom XWindowSystemUtilities::Atoms::getCreating (::Display* display, const char* name) +{ + return X11Symbols::getInstance()->xInternAtom (display, name, False); +} + +String XWindowSystemUtilities::Atoms::getName (::Display* display, Atom atom) +{ + if (atom == None) + return "None"; + + return X11Symbols::getInstance()->xGetAtomName (display, atom); +} + +bool XWindowSystemUtilities::Atoms::isMimeTypeFile (::Display* display, Atom atom) +{ + return getName (display, atom).equalsIgnoreCase ("text/uri-list"); +} + +//============================================================================== +XWindowSystemUtilities::GetXProperty::GetXProperty (Window window, Atom atom, long offset, + long length, bool shouldDelete, Atom requestedType) +{ + success = (X11Symbols::getInstance()->xGetWindowProperty (XWindowSystem::getInstance()->getDisplay(), + window, atom, offset, length, + (Bool) shouldDelete, requestedType, &actualType, + &actualFormat, &numItems, &bytesLeft, &data) == Success) + && data != nullptr; +} + +XWindowSystemUtilities::GetXProperty::~GetXProperty() +{ + if (data != nullptr) + X11Symbols::getInstance()->xFree (data); +} + +//============================================================================== +using WindowMessageReceiveCallback = void (*) (XEvent&); +using SelectionRequestCallback = void (*) (XSelectionRequestEvent&); + +static WindowMessageReceiveCallback dispatchWindowMessage = nullptr; +SelectionRequestCallback handleSelectionRequest = nullptr; + +::Window juce_messageWindowHandle; +XContext windowHandleXContext; + +#if JUCE_X11_SUPPORTS_XEMBED + bool juce_handleXEmbedEvent (ComponentPeer*, void*); + unsigned long juce_getCurrentFocusWindow (ComponentPeer*); +#endif + +struct MotifWmHints +{ + unsigned long flags = 0, functions = 0, decorations = 0, status = 0; + long input_mode = 0; +}; + +//=============================== X11 - Error Handling ========================= +namespace X11ErrorHandling +{ + static XErrorHandler oldErrorHandler = {}; + static XIOErrorHandler oldIOErrorHandler = {}; + + // Usually happens when client-server connection is broken + static int ioErrorHandler (::Display*) + { + DBG ("ERROR: connection to X server broken.. terminating."); + + if (JUCEApplicationBase::isStandaloneApp()) + MessageManager::getInstance()->stopDispatchLoop(); + + return 0; + } + + static int errorHandler (::Display* display, XErrorEvent* event) + { + ignoreUnused (display, event); + + #if JUCE_DEBUG_XERRORS + char errorStr[64] = { 0 }; + char requestStr[64] = { 0 }; + + X11Symbols::getInstance()->xGetErrorText (display, event->error_code, errorStr, 64); + X11Symbols::getInstance()->xGetErrorDatabaseText (display, "XRequest", String (event->request_code).toUTF8(), "Unknown", requestStr, 64); + + DBG ("ERROR: X returned " << errorStr << " for operation " << requestStr); + #endif + + return 0; + } + + static void installXErrorHandlers() + { + oldIOErrorHandler = X11Symbols::getInstance()->xSetIOErrorHandler (ioErrorHandler); + oldErrorHandler = X11Symbols::getInstance()->xSetErrorHandler (errorHandler); + } + + static void removeXErrorHandlers() + { + X11Symbols::getInstance()->xSetIOErrorHandler (oldIOErrorHandler); + oldIOErrorHandler = {}; + + X11Symbols::getInstance()->xSetErrorHandler (oldErrorHandler); + oldErrorHandler = {}; + } +} + +//=============================== X11 - Keys =================================== +namespace Keys +{ + enum MouseButtons + { + NoButton = 0, + LeftButton = 1, + MiddleButton = 2, + RightButton = 3, + WheelUp = 4, + WheelDown = 5 + }; + + static int AltMask = 0; + static int NumLockMask = 0; + static bool numLock = false; + static bool capsLock = false; + static char keyStates [32]; + static constexpr int extendedKeyModifier = 0x10000000; +} + +const int KeyPress::spaceKey = XK_space & 0xff; +const int KeyPress::returnKey = XK_Return & 0xff; +const int KeyPress::escapeKey = XK_Escape & 0xff; +const int KeyPress::backspaceKey = XK_BackSpace & 0xff; +const int KeyPress::leftKey = (XK_Left & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::rightKey = (XK_Right & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::upKey = (XK_Up & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::downKey = (XK_Down & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::pageUpKey = (XK_Page_Up & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::pageDownKey = (XK_Page_Down & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::endKey = (XK_End & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::homeKey = (XK_Home & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::insertKey = (XK_Insert & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::deleteKey = (XK_Delete & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::tabKey = XK_Tab & 0xff; +const int KeyPress::F1Key = (XK_F1 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F2Key = (XK_F2 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F3Key = (XK_F3 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F4Key = (XK_F4 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F5Key = (XK_F5 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F6Key = (XK_F6 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F7Key = (XK_F7 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F8Key = (XK_F8 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F9Key = (XK_F9 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F10Key = (XK_F10 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F11Key = (XK_F11 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F12Key = (XK_F12 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F13Key = (XK_F13 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F14Key = (XK_F14 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F15Key = (XK_F15 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F16Key = (XK_F16 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F17Key = (XK_F17 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F18Key = (XK_F18 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F19Key = (XK_F19 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F20Key = (XK_F20 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F21Key = (XK_F21 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F22Key = (XK_F22 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F23Key = (XK_F23 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F24Key = (XK_F24 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F25Key = (XK_F25 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F26Key = (XK_F26 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F27Key = (XK_F27 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F28Key = (XK_F28 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F29Key = (XK_F29 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F30Key = (XK_F30 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F31Key = (XK_F31 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F32Key = (XK_F32 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F33Key = (XK_F33 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F34Key = (XK_F34 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F35Key = (XK_F35 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::numberPad0 = (XK_KP_0 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::numberPad1 = (XK_KP_1 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::numberPad2 = (XK_KP_2 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::numberPad3 = (XK_KP_3 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::numberPad4 = (XK_KP_4 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::numberPad5 = (XK_KP_5 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::numberPad6 = (XK_KP_6 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::numberPad7 = (XK_KP_7 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::numberPad8 = (XK_KP_8 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::numberPad9 = (XK_KP_9 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::numberPadAdd = (XK_KP_Add & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::numberPadSubtract = (XK_KP_Subtract & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::numberPadMultiply = (XK_KP_Multiply & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::numberPadDivide = (XK_KP_Divide & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::numberPadSeparator = (XK_KP_Separator & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::numberPadDecimalPoint = (XK_KP_Decimal & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::numberPadEquals = (XK_KP_Equal & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::numberPadDelete = (XK_KP_Delete & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::playKey = ((int) 0xffeeff00) | Keys::extendedKeyModifier; +const int KeyPress::stopKey = ((int) 0xffeeff01) | Keys::extendedKeyModifier; +const int KeyPress::fastForwardKey = ((int) 0xffeeff02) | Keys::extendedKeyModifier; +const int KeyPress::rewindKey = ((int) 0xffeeff03) | Keys::extendedKeyModifier; + +static void updateKeyStates (int keycode, bool press) noexcept +{ + auto keybyte = keycode >> 3; + auto keybit = (1 << (keycode & 7)); + + if (press) + Keys::keyStates [keybyte] |= keybit; + else + Keys::keyStates [keybyte] &= ~keybit; +} + +static void updateKeyModifiers (int status) noexcept +{ + int keyMods = 0; + + if ((status & ShiftMask) != 0) keyMods |= ModifierKeys::shiftModifier; + if ((status & ControlMask) != 0) keyMods |= ModifierKeys::ctrlModifier; + if ((status & Keys::AltMask) != 0) keyMods |= ModifierKeys::altModifier; + + ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withOnlyMouseButtons().withFlags (keyMods); + + Keys::numLock = ((status & Keys::NumLockMask) != 0); + Keys::capsLock = ((status & LockMask) != 0); +} + +static bool updateKeyModifiersFromSym (KeySym sym, bool press) noexcept +{ + int modifier = 0; + bool isModifier = true; + + switch (sym) + { + case XK_Shift_L: + case XK_Shift_R: modifier = ModifierKeys::shiftModifier; break; + + case XK_Control_L: + case XK_Control_R: modifier = ModifierKeys::ctrlModifier; break; + + case XK_Alt_L: + case XK_Alt_R: modifier = ModifierKeys::altModifier; break; + + case XK_Num_Lock: + if (press) + Keys::numLock = ! Keys::numLock; + + break; + + case XK_Caps_Lock: + if (press) + Keys::capsLock = ! Keys::capsLock; + + break; + + case XK_Scroll_Lock: + break; + + default: + isModifier = false; + break; + } + + ModifierKeys::currentModifiers = press ? ModifierKeys::currentModifiers.withFlags (modifier) + : ModifierKeys::currentModifiers.withoutFlags (modifier); + + return isModifier; +} + +enum +{ + KeyPressEventType = 2 +}; + +//================================== X11 - Shm ================================= +#if JUCE_USE_XSHM + namespace XSHMHelpers + { + static int trappedErrorCode = 0; + + extern "C" int errorTrapHandler (Display*, XErrorEvent* err) + { + trappedErrorCode = err->error_code; + return 0; + } + + static bool isShmAvailable (::Display* display) + { + static bool isChecked = false; + static bool isAvailable = false; + + if (! isChecked) + { + isChecked = true; + + if (display != nullptr) + { + int major, minor; + Bool pixmaps; + + XWindowSystemUtilities::ScopedXLock xLock; + + if (X11Symbols::getInstance()->xShmQueryVersion (display, &major, &minor, &pixmaps)) + { + trappedErrorCode = 0; + auto oldHandler = X11Symbols::getInstance()->xSetErrorHandler (errorTrapHandler); + + XShmSegmentInfo segmentInfo; + zerostruct (segmentInfo); + + if (auto* xImage = X11Symbols::getInstance()->xShmCreateImage (display, + X11Symbols::getInstance()->xDefaultVisual (display, X11Symbols::getInstance()->xDefaultScreen (display)), + 24, ZPixmap, nullptr, &segmentInfo, 50, 50)) + { + if ((segmentInfo.shmid = shmget (IPC_PRIVATE, + (size_t) (xImage->bytes_per_line * xImage->height), + IPC_CREAT | 0777)) >= 0) + { + segmentInfo.shmaddr = (char*) shmat (segmentInfo.shmid, nullptr, 0); + + if (segmentInfo.shmaddr != (void*) -1) + { + segmentInfo.readOnly = False; + xImage->data = segmentInfo.shmaddr; + X11Symbols::getInstance()->xSync (display, False); + + if (X11Symbols::getInstance()->xShmAttach (display, &segmentInfo) != 0) + { + X11Symbols::getInstance()->xSync (display, False); + X11Symbols::getInstance()->xShmDetach (display, &segmentInfo); + + isAvailable = true; + } + } + + X11Symbols::getInstance()->xFlush (display); + X11Symbols::getInstance()->xDestroyImage (xImage); + + shmdt (segmentInfo.shmaddr); + } + + shmctl (segmentInfo.shmid, IPC_RMID, nullptr); + + X11Symbols::getInstance()->xSetErrorHandler (oldHandler); + + if (trappedErrorCode != 0) + isAvailable = false; + } + } + } + } + + return isAvailable; + } + } +#endif + +//=============================== X11 - Render ================================= +#if JUCE_USE_XRENDER + namespace XRender + { + static bool isAvailable (::Display* display) + { + int major, minor; + return X11Symbols::getInstance()->xRenderQueryVersion (display, &major, &minor); + } + + static bool hasCompositingWindowManager (::Display* display) + { + return display != nullptr + && X11Symbols::getInstance()->xGetSelectionOwner (display, + XWindowSystemUtilities::Atoms::getCreating (display, "_NET_WM_CM_S0")) != 0; + } + + static XRenderPictFormat* findPictureFormat (::Display* display) + { + XWindowSystemUtilities::ScopedXLock xLock; + + if (isAvailable (display)) + { + if (auto* pictFormat = X11Symbols::getInstance()->xRenderFindStandardFormat (display, PictStandardARGB32)) + { + XRenderPictFormat desiredFormat; + desiredFormat.type = PictTypeDirect; + desiredFormat.depth = 32; + + desiredFormat.direct.alphaMask = 0xff; + desiredFormat.direct.redMask = 0xff; + desiredFormat.direct.greenMask = 0xff; + desiredFormat.direct.blueMask = 0xff; + + desiredFormat.direct.alpha = 24; + desiredFormat.direct.red = 16; + desiredFormat.direct.green = 8; + desiredFormat.direct.blue = 0; + + pictFormat = X11Symbols::getInstance()->xRenderFindFormat (display, + PictFormatType | PictFormatDepth + | PictFormatRedMask | PictFormatRed + | PictFormatGreenMask | PictFormatGreen + | PictFormatBlueMask | PictFormatBlue + | PictFormatAlphaMask | PictFormatAlpha, + &desiredFormat, + 0); + + return pictFormat; + } + } + + return nullptr; + } + } +#endif + +//================================ X11 - Visuals =============================== +namespace Visuals +{ + static Visual* findVisualWithDepth (::Display* display, int desiredDepth) + { + XWindowSystemUtilities::ScopedXLock xLock; + + Visual* visual = nullptr; + int numVisuals = 0; + auto desiredMask = VisualNoMask; + XVisualInfo desiredVisual; + + desiredVisual.screen = X11Symbols::getInstance()->xDefaultScreen (display); + desiredVisual.depth = desiredDepth; + + desiredMask = VisualScreenMask | VisualDepthMask; + + if (desiredDepth == 32) + { + desiredVisual.c_class = TrueColor; + desiredVisual.red_mask = 0x00FF0000; + desiredVisual.green_mask = 0x0000FF00; + desiredVisual.blue_mask = 0x000000FF; + desiredVisual.bits_per_rgb = 8; + + desiredMask |= VisualClassMask; + desiredMask |= VisualRedMaskMask; + desiredMask |= VisualGreenMaskMask; + desiredMask |= VisualBlueMaskMask; + desiredMask |= VisualBitsPerRGBMask; + } + + if (auto* xvinfos = X11Symbols::getInstance()->xGetVisualInfo (display, desiredMask, &desiredVisual, &numVisuals)) + { + for (int i = 0; i < numVisuals; i++) + { + if (xvinfos[i].depth == desiredDepth) + { + visual = xvinfos[i].visual; + break; + } + } + + X11Symbols::getInstance()->xFree (xvinfos); + } + + return visual; + } + + static Visual* findVisualFormat (::Display* display, int desiredDepth, int& matchedDepth) + { + Visual* visual = nullptr; + + if (desiredDepth == 32) + { + #if JUCE_USE_XSHM + if (XSHMHelpers::isShmAvailable (display)) + { + #if JUCE_USE_XRENDER + if (XRender::isAvailable (display)) + { + if (XRender::findPictureFormat (display) != nullptr) + { + int numVisuals = 0; + XVisualInfo desiredVisual; + desiredVisual.screen = X11Symbols::getInstance()->xDefaultScreen (display); + desiredVisual.depth = 32; + desiredVisual.bits_per_rgb = 8; + + if (auto xvinfos = X11Symbols::getInstance()->xGetVisualInfo (display, + VisualScreenMask | VisualDepthMask | VisualBitsPerRGBMask, + &desiredVisual, &numVisuals)) + { + for (int i = 0; i < numVisuals; ++i) + { + auto pictVisualFormat = X11Symbols::getInstance()->xRenderFindVisualFormat (display, xvinfos[i].visual); + + if (pictVisualFormat != nullptr + && pictVisualFormat->type == PictTypeDirect + && pictVisualFormat->direct.alphaMask) + { + visual = xvinfos[i].visual; + matchedDepth = 32; + break; + } + } + + X11Symbols::getInstance()->xFree (xvinfos); + } + } + } + #endif + if (visual == nullptr) + { + visual = findVisualWithDepth (display, 32); + + if (visual != nullptr) + matchedDepth = 32; + } + } + #endif + } + + if (visual == nullptr && desiredDepth >= 24) + { + visual = findVisualWithDepth (display, 24); + + if (visual != nullptr) + matchedDepth = 24; + } + + if (visual == nullptr && desiredDepth >= 16) + { + visual = findVisualWithDepth (display, 16); + + if (visual != nullptr) + matchedDepth = 16; + } + + return visual; + } +} + +//================================= X11 - Bitmap =============================== +class XBitmapImage : public ImagePixelData +{ +public: + XBitmapImage (Image::PixelFormat format, int w, int h, + bool clearImage, unsigned int imageDepth_, Visual* visual) + : ImagePixelData (format, w, h), + imageDepth (imageDepth_) + { + jassert (format == Image::RGB || format == Image::ARGB); + + pixelStride = (format == Image::RGB) ? 3 : 4; + lineStride = ((w * pixelStride + 3) & ~3); + + XWindowSystemUtilities::ScopedXLock xLock; + + #if JUCE_USE_XSHM + usingXShm = false; + + if ((imageDepth > 16) && XSHMHelpers::isShmAvailable (display)) + { + zerostruct (segmentInfo); + + segmentInfo.shmid = -1; + segmentInfo.shmaddr = (char *) -1; + segmentInfo.readOnly = False; + + xImage = X11Symbols::getInstance()->xShmCreateImage (display, visual, imageDepth, ZPixmap, nullptr, + &segmentInfo, (unsigned int) w, (unsigned int) h); + + if (xImage != nullptr) + { + if ((segmentInfo.shmid = shmget (IPC_PRIVATE, + (size_t) (xImage->bytes_per_line * xImage->height), + IPC_CREAT | 0777)) >= 0) + { + if (segmentInfo.shmid != -1) + { + segmentInfo.shmaddr = (char*) shmat (segmentInfo.shmid, nullptr, 0); + + if (segmentInfo.shmaddr != (void*) -1) + { + segmentInfo.readOnly = False; + + xImage->data = segmentInfo.shmaddr; + imageData = (uint8*) segmentInfo.shmaddr; + + if (X11Symbols::getInstance()->xShmAttach (display, &segmentInfo) != 0) + usingXShm = true; + else + jassertfalse; + } + else + { + shmctl (segmentInfo.shmid, IPC_RMID, nullptr); + } + } + } + } + } + + if (! isUsingXShm()) + #endif + { + imageDataAllocated.allocate ((size_t) (lineStride * h), format == Image::ARGB && clearImage); + imageData = imageDataAllocated; + + xImage = (XImage*) ::calloc (1, sizeof (XImage)); + + xImage->width = w; + xImage->height = h; + xImage->xoffset = 0; + xImage->format = ZPixmap; + xImage->data = (char*) imageData; + xImage->byte_order = X11Symbols::getInstance()->xImageByteOrder (display); + xImage->bitmap_unit = X11Symbols::getInstance()->xBitmapUnit (display); + xImage->bitmap_bit_order = X11Symbols::getInstance()->xBitmapBitOrder (display); + xImage->bitmap_pad = 32; + xImage->depth = pixelStride * 8; + xImage->bytes_per_line = lineStride; + xImage->bits_per_pixel = pixelStride * 8; + xImage->red_mask = 0x00FF0000; + xImage->green_mask = 0x0000FF00; + xImage->blue_mask = 0x000000FF; + + if (imageDepth == 16) + { + int pixStride = 2; + auto stride = ((w * pixStride + 3) & ~3); + + imageData16Bit.malloc (stride * h); + xImage->data = imageData16Bit; + xImage->bitmap_pad = 16; + xImage->depth = pixStride * 8; + xImage->bytes_per_line = stride; + xImage->bits_per_pixel = pixStride * 8; + xImage->red_mask = visual->red_mask; + xImage->green_mask = visual->green_mask; + xImage->blue_mask = visual->blue_mask; + } + + if (! X11Symbols::getInstance()->xInitImage (xImage)) + jassertfalse; + } + } + + ~XBitmapImage() override + { + XWindowSystemUtilities::ScopedXLock xLock; + + if (gc != None) + X11Symbols::getInstance()->xFreeGC (display, gc); + + #if JUCE_USE_XSHM + if (isUsingXShm()) + { + X11Symbols::getInstance()->xShmDetach (display, &segmentInfo); + + X11Symbols::getInstance()->xFlush (display); + X11Symbols::getInstance()->xDestroyImage (xImage); + + shmdt (segmentInfo.shmaddr); + shmctl (segmentInfo.shmid, IPC_RMID, nullptr); + } + else + #endif + { + xImage->data = nullptr; + X11Symbols::getInstance()->xDestroyImage (xImage); + } + } + + std::unique_ptr<LowLevelGraphicsContext> createLowLevelContext() override + { + sendDataChangeMessage(); + return std::make_unique<LowLevelGraphicsSoftwareRenderer> (Image (this)); + } + + void initialiseBitmapData (Image::BitmapData& bitmap, int x, int y, + Image::BitmapData::ReadWriteMode mode) override + { + bitmap.data = imageData + x * pixelStride + y * lineStride; + bitmap.pixelFormat = pixelFormat; + bitmap.lineStride = lineStride; + bitmap.pixelStride = pixelStride; + + if (mode != Image::BitmapData::readOnly) + sendDataChangeMessage(); + } + + ImagePixelData::Ptr clone() override + { + jassertfalse; + return nullptr; + } + + std::unique_ptr<ImageType> createType() const override { return std::make_unique<NativeImageType>(); } + + void blitToWindow (::Window window, int dx, int dy, unsigned int dw, unsigned int dh, int sx, int sy) + { + XWindowSystemUtilities::ScopedXLock xLock; + + #if JUCE_USE_XSHM + if (isUsingXShm()) + XWindowSystem::getInstance()->addPendingPaintForWindow (window); + #endif + + if (gc == None) + { + XGCValues gcvalues; + gcvalues.foreground = None; + gcvalues.background = None; + gcvalues.function = GXcopy; + gcvalues.plane_mask = AllPlanes; + gcvalues.clip_mask = None; + gcvalues.graphics_exposures = False; + + gc = X11Symbols::getInstance()->xCreateGC (display, window, + GCBackground | GCForeground | GCFunction | GCPlaneMask | GCClipMask | GCGraphicsExposures, + &gcvalues); + } + + if (imageDepth == 16) + { + auto rMask = (uint32) xImage->red_mask; + auto gMask = (uint32) xImage->green_mask; + auto bMask = (uint32) xImage->blue_mask; + auto rShiftL = (uint32) jmax (0, getShiftNeeded (rMask)); + auto rShiftR = (uint32) jmax (0, -getShiftNeeded (rMask)); + auto gShiftL = (uint32) jmax (0, getShiftNeeded (gMask)); + auto gShiftR = (uint32) jmax (0, -getShiftNeeded (gMask)); + auto bShiftL = (uint32) jmax (0, getShiftNeeded (bMask)); + auto bShiftR = (uint32) jmax (0, -getShiftNeeded (bMask)); + + Image::BitmapData srcData (Image (this), Image::BitmapData::readOnly); + + for (int y = sy; y < sy + (int) dh; ++y) + { + auto* p = srcData.getPixelPointer (sx, y); + + for (int x = sx; x < sx + (int) dw; ++x) + { + auto* pixel = (PixelRGB*) p; + p += srcData.pixelStride; + + X11Symbols::getInstance()->xPutPixel (xImage, x, y, + (((((uint32) pixel->getRed()) << rShiftL) >> rShiftR) & rMask) + | (((((uint32) pixel->getGreen()) << gShiftL) >> gShiftR) & gMask) + | (((((uint32) pixel->getBlue()) << bShiftL) >> bShiftR) & bMask)); + } + } + } + + // blit results to screen. + #if JUCE_USE_XSHM + if (isUsingXShm()) + X11Symbols::getInstance()->xShmPutImage (display, (::Drawable) window, gc, xImage, sx, sy, dx, dy, dw, dh, True); + else + #endif + X11Symbols::getInstance()->xPutImage (display, (::Drawable) window, gc, xImage, sx, sy, dx, dy, dw, dh); + } + + #if JUCE_USE_XSHM + bool isUsingXShm() const noexcept { return usingXShm; } + #endif + +private: + //============================================================================== + XImage* xImage = nullptr; + const unsigned int imageDepth; + HeapBlock<uint8> imageDataAllocated; + HeapBlock<char> imageData16Bit; + int pixelStride, lineStride; + uint8* imageData = nullptr; + GC gc = None; + ::Display* display = XWindowSystem::getInstance()->getDisplay(); + + #if JUCE_USE_XSHM + XShmSegmentInfo segmentInfo; + bool usingXShm; + #endif + + static int getShiftNeeded (const uint32 mask) noexcept + { + for (int i = 32; --i >= 0;) + if (((mask >> i) & 1) != 0) + return i - 7; + + jassertfalse; + return 0; + } + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (XBitmapImage) +}; + +//=============================== X11 - Displays =============================== +namespace DisplayHelpers +{ + static double getDisplayDPI (::Display* display, int index) + { + auto widthMM = X11Symbols::getInstance()->xDisplayWidthMM (display, index); + auto heightMM = X11Symbols::getInstance()->xDisplayHeightMM (display, index); + + if (widthMM > 0 && heightMM > 0) + return (((X11Symbols::getInstance()->xDisplayWidth (display, index) * 25.4) / widthMM) + + ((X11Symbols::getInstance()->xDisplayHeight (display, index) * 25.4) / heightMM)) / 2.0; + + return 96.0; + } + + static double getDisplayScale (const String& name, double dpi) + { + if (name.isNotEmpty()) + { + // Ubuntu and derived distributions now save a per-display scale factor as a configuration + // variable. This can be changed in the Monitor system settings panel. + ChildProcess dconf; + + if (File ("/usr/bin/dconf").existsAsFile() + && dconf.start ("/usr/bin/dconf read /com/ubuntu/user-interface/scale-factor", ChildProcess::wantStdOut)) + { + if (dconf.waitForProcessToFinish (200)) + { + auto jsonOutput = dconf.readAllProcessOutput().replaceCharacter ('\'', '"'); + + if (dconf.getExitCode() == 0 && jsonOutput.isNotEmpty()) + { + auto jsonVar = JSON::parse (jsonOutput); + + if (auto* object = jsonVar.getDynamicObject()) + { + auto scaleFactorVar = object->getProperty (name); + + if (! scaleFactorVar.isVoid()) + { + auto scaleFactor = ((double) scaleFactorVar) / 8.0; + + if (scaleFactor > 0.0) + return scaleFactor; + } + } + } + } + } + } + + { + // Other gnome based distros now use gsettings for a global scale factor + ChildProcess gsettings; + + if (File ("/usr/bin/gsettings").existsAsFile() + && gsettings.start ("/usr/bin/gsettings get org.gnome.desktop.interface scaling-factor", ChildProcess::wantStdOut)) + { + if (gsettings.waitForProcessToFinish (200)) + { + auto gsettingsOutput = StringArray::fromTokens (gsettings.readAllProcessOutput(), true); + + if (gsettingsOutput.size() >= 2 && gsettingsOutput[1].length() > 0) + { + auto scaleFactor = gsettingsOutput[1].getDoubleValue(); + + if (scaleFactor > 0.0) + return scaleFactor; + + return 1.0; + } + } + } + } + + // If no scale factor is set by GNOME or Ubuntu then calculate from monitor dpi + // We use the same approach as chromium which simply divides the dpi by 96 + // and then rounds the result + return round (dpi / 96.0); + } + + #if JUCE_USE_XINERAMA + static Array<XineramaScreenInfo> xineramaQueryDisplays (::Display* display) + { + int major_opcode, first_event, first_error; + + if (X11Symbols::getInstance()->xQueryExtension (display, "XINERAMA", &major_opcode, &first_event, &first_error) + && (X11Symbols::getInstance()->xineramaIsActive (display) != 0)) + { + int numScreens; + + if (auto* xinfo = X11Symbols::getInstance()->xineramaQueryScreens (display, &numScreens)) + { + Array<XineramaScreenInfo> infos (xinfo, numScreens); + X11Symbols::getInstance()->xFree (xinfo); + + return infos; + } + } + + return {}; + } + #endif +} + +//=============================== X11 - Pixmap ================================= +namespace PixmapHelpers +{ + static Pixmap createColourPixmapFromImage (::Display* display, const Image& image) + { + XWindowSystemUtilities::ScopedXLock xLock; + + auto width = (unsigned int) image.getWidth(); + auto height = (unsigned int) image.getHeight(); + HeapBlock<uint32> colour (width * height); + int index = 0; + + for (int y = 0; y < (int) height; ++y) + for (int x = 0; x < (int) width; ++x) + colour[index++] = image.getPixelAt (x, y).getARGB(); + + auto* ximage = X11Symbols::getInstance()->xCreateImage (display, (Visual*) CopyFromParent, 24, ZPixmap, + 0, reinterpret_cast<const char*> (colour.getData()), + width, height, 32, 0); + + auto pixmap = X11Symbols::getInstance()->xCreatePixmap (display, + X11Symbols::getInstance()->xDefaultRootWindow (display), + width, height, 24); + + auto gc = X11Symbols::getInstance()->xCreateGC (display, pixmap, 0, nullptr); + + X11Symbols::getInstance()->xPutImage (display, pixmap, gc, ximage, 0, 0, 0, 0, width, height); + X11Symbols::getInstance()->xFreeGC (display, gc); + X11Symbols::getInstance()->xFree (ximage); + + return pixmap; + } + + static Pixmap createMaskPixmapFromImage (::Display* display, const Image& image) + { + XWindowSystemUtilities::ScopedXLock xLock; + + auto width = (unsigned int) image.getWidth(); + auto height = (unsigned int) image.getHeight(); + auto stride = (width + 7) >> 3; + HeapBlock<char> mask; + mask.calloc (stride * height); + + auto msbfirst = (X11Symbols::getInstance()->xBitmapBitOrder (display) == MSBFirst); + + for (unsigned int y = 0; y < height; ++y) + { + for (unsigned int x = 0; x < width; ++x) + { + auto bit = (char) (1 << (msbfirst ? (7 - (x & 7)) : (x & 7))); + auto offset = y * stride + (x >> 3); + + if (image.getPixelAt ((int) x, (int) y).getAlpha() >= 128) + mask[offset] |= bit; + } + } + + return X11Symbols::getInstance()->xCreatePixmapFromBitmapData (display, X11Symbols::getInstance()->xDefaultRootWindow (display), + mask.getData(), width, height, 1, 0, 1); + } +} + +//=============================== X11 - Clipboard ============================== +namespace ClipboardHelpers +{ + //============================================================================== + // Read the content of a window property as either a locale-dependent string or an utf8 string + // works only for strings shorter than 1000000 bytes + static String readWindowProperty (::Display* display, Window window, Atom atom) + { + if (display != nullptr) + { + XWindowSystemUtilities::GetXProperty prop (window, atom, 0L, 100000, false, AnyPropertyType); + + if (prop.success) + { + if (prop.actualType == XWindowSystem::getInstance()->getAtoms().utf8String&& prop.actualFormat == 8) + return String::fromUTF8 ((const char*) prop.data, (int) prop.numItems); + + if (prop.actualType == XA_STRING && prop.actualFormat == 8) + return String ((const char*) prop.data, prop.numItems); + } + } + + return {}; + } + + //============================================================================== + // Send a SelectionRequest to the window owning the selection and waits for its answer (with a timeout) */ + static bool requestSelectionContent (::Display* display, String& selectionContent, Atom selection, Atom requestedFormat) + { + auto property_name = X11Symbols::getInstance()->xInternAtom (display, "JUCE_SEL", false); + + // The selection owner will be asked to set the JUCE_SEL property on the + // juce_messageWindowHandle with the selection content + X11Symbols::getInstance()->xConvertSelection (display, selection, requestedFormat, property_name, + juce_messageWindowHandle, CurrentTime); + + int count = 50; // will wait at most for 200 ms + + while (--count >= 0) + { + XEvent event; + + if (X11Symbols::getInstance()->xCheckTypedWindowEvent (display, juce_messageWindowHandle, SelectionNotify, &event)) + { + if (event.xselection.property == property_name) + { + jassert (event.xselection.requestor == juce_messageWindowHandle); + + selectionContent = readWindowProperty (display, event.xselection.requestor, event.xselection.property); + return true; + } + + return false; // the format we asked for was denied.. (event.xselection.property == None) + } + + // not very elegant.. we could do a select() or something like that... + // however clipboard content requesting is inherently slow on x11, it + // often takes 50ms or more so... + Thread::sleep (4); + } + + return false; + } + + //============================================================================== + // Called from the event loop in juce_linux_Messaging in response to SelectionRequest events + static void handleSelection (XSelectionRequestEvent& evt) + { + // the selection content is sent to the target window as a window property + XSelectionEvent reply; + reply.type = SelectionNotify; + reply.display = evt.display; + reply.requestor = evt.requestor; + reply.selection = evt.selection; + reply.target = evt.target; + reply.property = None; // == "fail" + reply.time = evt.time; + + HeapBlock<char> data; + int propertyFormat = 0; + size_t numDataItems = 0; + + if (evt.selection == XA_PRIMARY || evt.selection == XWindowSystem::getInstance()->getAtoms().clipboard) + { + if (evt.target == XA_STRING || evt.target == XWindowSystem::getInstance()->getAtoms().utf8String) + { + auto localContent = XWindowSystem::getInstance()->getLocalClipboardContent(); + + // translate to utf8 + numDataItems = localContent.getNumBytesAsUTF8() + 1; + data.calloc (numDataItems); + localContent.copyToUTF8 (data, numDataItems); + propertyFormat = 8; // bits/item + } + else if (evt.target == XWindowSystem::getInstance()->getAtoms().targets) + { + // another application wants to know what we are able to send + numDataItems = 2; + propertyFormat = 32; // atoms are 32-bit + data.calloc (numDataItems * 4); + Atom* atoms = unalignedPointerCast<Atom*> (data.getData()); + atoms[0] = XWindowSystem::getInstance()->getAtoms().utf8String; + atoms[1] = XA_STRING; + + evt.target = XA_ATOM; + } + } + else + { + DBG ("requested unsupported clipboard"); + } + + if (data != nullptr) + { + const size_t maxReasonableSelectionSize = 1000000; + + // for very big chunks of data, we should use the "INCR" protocol , which is a pain in the *ss + if (evt.property != None && numDataItems < maxReasonableSelectionSize) + { + X11Symbols::getInstance()->xChangeProperty (evt.display, evt.requestor, + evt.property, evt.target, + propertyFormat /* 8 or 32 */, PropModeReplace, + reinterpret_cast<const unsigned char*> (data.getData()), (int) numDataItems); + reply.property = evt.property; // " == success" + } + } + + X11Symbols::getInstance()->xSendEvent (evt.display, evt.requestor, 0, NoEventMask, (XEvent*) &reply); + } +} + +//============================================================================== +typedef void (*SelectionRequestCallback) (XSelectionRequestEvent&); +extern SelectionRequestCallback handleSelectionRequest; + +struct ClipboardCallbackInitialiser +{ + ClipboardCallbackInitialiser() + { + handleSelectionRequest = ClipboardHelpers::handleSelection; + } +}; + +static ClipboardCallbackInitialiser clipboardInitialiser; + +//============================================================================== +ComponentPeer* getPeerFor (::Window windowH) +{ + if (windowH == 0) + return nullptr; + + XPointer peer = nullptr; + + if (auto* display = XWindowSystem::getInstance()->getDisplay()) + { + XWindowSystemUtilities::ScopedXLock xLock; + X11Symbols::getInstance()->xFindContext (display, (XID) windowH, windowHandleXContext, &peer); + } + + return unalignedPointerCast<ComponentPeer*> (peer); +} + +//============================================================================== +static std::unordered_map<LinuxComponentPeer<::Window>*, X11DragState> dragAndDropStateMap; + +XWindowSystem::XWindowSystem() +{ + xIsAvailable = X11Symbols::getInstance()->loadAllSymbols(); + + if (! xIsAvailable) + return; + + if (JUCEApplicationBase::isStandaloneApp()) + { + // Initialise xlib for multiple thread support + static bool initThreadCalled = false; + + if (! initThreadCalled) + { + if (! X11Symbols::getInstance()->xInitThreads()) + { + // This is fatal! Print error and closedown + Logger::outputDebugString ("Failed to initialise xlib thread support."); + Process::terminate(); + + return; + } + + initThreadCalled = true; + } + + X11ErrorHandling::installXErrorHandlers(); + } + + if (! initialiseXDisplay()) + { + if (JUCEApplicationBase::isStandaloneApp()) + X11ErrorHandling::removeXErrorHandlers(); + + X11Symbols::deleteInstance(); + xIsAvailable = false; + } +} + +XWindowSystem::~XWindowSystem() +{ + if (xIsAvailable) + { + destroyXDisplay(); + + if (JUCEApplicationBase::isStandaloneApp()) + X11ErrorHandling::removeXErrorHandlers(); + } + + X11Symbols::deleteInstance(); + clearSingletonInstance(); +} + +//============================================================================== +static int getAllEventsMask (bool ignoresMouseClicks) +{ + return NoEventMask | KeyPressMask | KeyReleaseMask + | EnterWindowMask | LeaveWindowMask | PointerMotionMask | KeymapStateMask + | ExposureMask | StructureNotifyMask | FocusChangeMask + | (ignoresMouseClicks ? 0 : (ButtonPressMask | ButtonReleaseMask)); +} + +::Window XWindowSystem::createWindow (::Window parentToAddTo, LinuxComponentPeer<::Window>* peer) const +{ + if (! xIsAvailable) + { + // can't open a window on a system that doesn't have X11 installed! + jassertfalse; + return 0; + } + + auto styleFlags = peer->getStyleFlags(); + + XWindowSystemUtilities::ScopedXLock xLock; + + auto root = X11Symbols::getInstance()->xRootWindow (display, X11Symbols::getInstance()->xDefaultScreen (display)); + + auto visualAndDepth = displayVisuals->getBestVisualForWindow ((styleFlags & ComponentPeer::windowIsSemiTransparent) != 0); + + auto colormap = X11Symbols::getInstance()->xCreateColormap (display, root, visualAndDepth.visual, AllocNone); + X11Symbols::getInstance()->xInstallColormap (display, colormap); + + // Set up the window attributes + XSetWindowAttributes swa; + swa.border_pixel = 0; + swa.background_pixmap = None; + swa.colormap = colormap; + swa.override_redirect = ((styleFlags & ComponentPeer::windowIsTemporary) != 0) ? True : False; + swa.event_mask = getAllEventsMask (styleFlags & ComponentPeer::windowIgnoresMouseClicks); + + auto windowH = X11Symbols::getInstance()->xCreateWindow (display, parentToAddTo != 0 ? parentToAddTo : root, + 0, 0, 1, 1, + 0, visualAndDepth.depth, InputOutput, visualAndDepth.visual, + CWBorderPixel | CWColormap | CWBackPixmap | CWEventMask | CWOverrideRedirect, + &swa); + + // Set the window context to identify the window handle object + if (X11Symbols::getInstance()->xSaveContext (display, (XID) windowH, windowHandleXContext, (XPointer) peer)) + { + // Failed + jassertfalse; + + Logger::outputDebugString ("Failed to create context information for window.\n"); + X11Symbols::getInstance()->xDestroyWindow (display, windowH); + + return 0; + } + + // Set window manager hints + if (auto* wmHints = X11Symbols::getInstance()->xAllocWMHints()) + { + wmHints->flags = InputHint | StateHint; + wmHints->input = True; + wmHints->initial_state = NormalState; + X11Symbols::getInstance()->xSetWMHints (display, windowH, wmHints); + X11Symbols::getInstance()->xFree (wmHints); + } + + // Set class hint + if (auto* app = JUCEApplicationBase::getInstance()) + { + if (auto* classHint = X11Symbols::getInstance()->xAllocClassHint()) + { + auto appName = app->getApplicationName(); + classHint->res_name = (char*) appName.getCharPointer().getAddress(); + classHint->res_class = (char*) appName.getCharPointer().getAddress(); + + X11Symbols::getInstance()->xSetClassHint (display, windowH, classHint); + X11Symbols::getInstance()->xFree (classHint); + } + } + + // Set the window type + setWindowType (windowH, styleFlags); + + // Define decoration + if ((styleFlags & ComponentPeer::windowHasTitleBar) == 0) + removeWindowDecorations (windowH); + else + addWindowButtons (windowH, styleFlags); + + // Associate the PID, allowing to be shut down when something goes wrong + auto pid = (unsigned long) getpid(); + xchangeProperty (windowH, atoms.pid, XA_CARDINAL, 32, &pid, 1); + + // Set window manager protocols + xchangeProperty (windowH, atoms.protocols, XA_ATOM, 32, atoms.protocolList, 2); + + // Set drag and drop flags + xchangeProperty (windowH, atoms.XdndTypeList, XA_ATOM, 32, atoms.allowedMimeTypes, numElementsInArray (atoms.allowedMimeTypes)); + xchangeProperty (windowH, atoms.XdndActionList, XA_ATOM, 32, atoms.allowedActions, numElementsInArray (atoms.allowedActions)); + xchangeProperty (windowH, atoms.XdndActionDescription, XA_STRING, 8, "", 0); + + auto dndVersion = XWindowSystemUtilities::Atoms::DndVersion; + xchangeProperty (windowH, atoms.XdndAware, XA_ATOM, 32, &dndVersion, 1); + + unsigned long info[2] = { 0, 1 }; + xchangeProperty (windowH, atoms.XembedInfo, atoms.XembedInfo, 32, (unsigned char*) info, 2); + + return windowH; +} + +void XWindowSystem::destroyWindow (::Window windowH) +{ + auto* peer = dynamic_cast<LinuxComponentPeer<::Window>*> (getPeerFor (windowH)); + + if (peer == nullptr) + { + jassertfalse; + return; + } + + #if JUCE_X11_SUPPORTS_XEMBED + juce_handleXEmbedEvent (peer, nullptr); + #endif + + deleteIconPixmaps (windowH); + dragAndDropStateMap.erase (peer); + + XWindowSystemUtilities::ScopedXLock xLock; + + XPointer handlePointer; + + if (! X11Symbols::getInstance()->xFindContext (display, (XID) windowH, windowHandleXContext, &handlePointer)) + X11Symbols::getInstance()->xDeleteContext (display, (XID) windowH, windowHandleXContext); + + X11Symbols::getInstance()->xDestroyWindow (display, windowH); + + // Wait for it to complete and then remove any events for this + // window from the event queue. + X11Symbols::getInstance()->xSync (display, false); + + XEvent event; + while (X11Symbols::getInstance()->xCheckWindowEvent (display, windowH, + getAllEventsMask (peer->getStyleFlags() & ComponentPeer::windowIgnoresMouseClicks), + &event) == True) + {} + + #if JUCE_USE_XSHM + if (XSHMHelpers::isShmAvailable (display)) + shmPaintsPendingMap.erase (windowH); + #endif +} + +//============================================================================== +void XWindowSystem::setTitle (::Window windowH, const String& title) const +{ + jassert (windowH != 0); + + XTextProperty nameProperty; + char* strings[] = { const_cast<char*> (title.toRawUTF8()) }; + + XWindowSystemUtilities::ScopedXLock xLock; + + if (X11Symbols::getInstance()->xStringListToTextProperty (strings, 1, &nameProperty)) + { + X11Symbols::getInstance()->xSetWMName (display, windowH, &nameProperty); + X11Symbols::getInstance()->xSetWMIconName (display, windowH, &nameProperty); + + X11Symbols::getInstance()->xFree (nameProperty.value); + } +} + + +void XWindowSystem::setIcon (::Window windowH, const Image& newIcon) const +{ + jassert (windowH != 0); + + auto dataSize = newIcon.getWidth() * newIcon.getHeight() + 2; + HeapBlock<unsigned long> data (dataSize); + + int index = 0; + data[index++] = (unsigned long) newIcon.getWidth(); + data[index++] = (unsigned long) newIcon.getHeight(); + + for (int y = 0; y < newIcon.getHeight(); ++y) + for (int x = 0; x < newIcon.getWidth(); ++x) + data[index++] = (unsigned long) newIcon.getPixelAt (x, y).getARGB(); + + XWindowSystemUtilities::ScopedXLock xLock; + xchangeProperty (windowH, XWindowSystemUtilities::Atoms::getCreating (display, "_NET_WM_ICON"), + XA_CARDINAL, 32, data.getData(), dataSize); + + deleteIconPixmaps (windowH); + + auto* wmHints = X11Symbols::getInstance()->xGetWMHints (display, windowH); + + if (wmHints == nullptr) + wmHints = X11Symbols::getInstance()->xAllocWMHints(); + + if (wmHints != nullptr) + { + wmHints->flags |= IconPixmapHint | IconMaskHint; + wmHints->icon_pixmap = PixmapHelpers::createColourPixmapFromImage (display, newIcon); + wmHints->icon_mask = PixmapHelpers::createMaskPixmapFromImage (display, newIcon); + + X11Symbols::getInstance()->xSetWMHints (display, windowH, wmHints); + X11Symbols::getInstance()->xFree (wmHints); + } + + X11Symbols::getInstance()->xSync (display, False); +} + +void XWindowSystem::setVisible (::Window windowH, bool shouldBeVisible) const +{ + jassert (windowH != 0); + + XWindowSystemUtilities::ScopedXLock xLock; + + if (shouldBeVisible) + X11Symbols::getInstance()->xMapWindow (display, windowH); + else + X11Symbols::getInstance()->xUnmapWindow (display, windowH); +} + +void XWindowSystem::setBounds (::Window windowH, Rectangle<int> newBounds, bool isFullScreen) const +{ + jassert (windowH != 0); + + if (auto* peer = getPeerFor (windowH)) + { + if (peer->isFullScreen() && ! isFullScreen) + { + // When transitioning back from fullscreen, we might need to remove + // the FULLSCREEN window property + Atom fs = XWindowSystemUtilities::Atoms::getIfExists (display, "_NET_WM_STATE_FULLSCREEN"); + + if (fs != None) + { + auto root = X11Symbols::getInstance()->xRootWindow (display, X11Symbols::getInstance()->xDefaultScreen (display)); + + XClientMessageEvent clientMsg; + clientMsg.display = display; + clientMsg.window = windowH; + clientMsg.type = ClientMessage; + clientMsg.format = 32; + clientMsg.message_type = atoms.windowState; + clientMsg.data.l[0] = 0; // Remove + clientMsg.data.l[1] = (long) fs; + clientMsg.data.l[2] = 0; + clientMsg.data.l[3] = 1; // Normal Source + + XWindowSystemUtilities::ScopedXLock xLock; + X11Symbols::getInstance()->xSendEvent (display, root, false, + SubstructureRedirectMask | SubstructureNotifyMask, + (XEvent*) &clientMsg); + } + } + + XWindowSystemUtilities::ScopedXLock xLock; + + if (auto* hints = X11Symbols::getInstance()->xAllocSizeHints()) + { + hints->flags = USSize | USPosition; + hints->x = newBounds.getX(); + hints->y = newBounds.getY(); + hints->width = newBounds.getWidth(); + hints->height = newBounds.getHeight(); + + if ((peer->getStyleFlags() & ComponentPeer::windowIsResizable) == 0) + { + hints->min_width = hints->max_width = hints->width; + hints->min_height = hints->max_height = hints->height; + hints->flags |= PMinSize | PMaxSize; + } + + X11Symbols::getInstance()->xSetWMNormalHints (display, windowH, hints); + X11Symbols::getInstance()->xFree (hints); + } + + auto windowBorder = peer->getFrameSize(); + + X11Symbols::getInstance()->xMoveResizeWindow (display, windowH, + newBounds.getX() - windowBorder.getLeft(), + newBounds.getY() - windowBorder.getTop(), + (unsigned int) newBounds.getWidth(), + (unsigned int) newBounds.getHeight()); + } +} + +bool XWindowSystem::contains (::Window windowH, Point<int> localPos) const +{ + ::Window root, child; + int wx, wy; + unsigned int ww, wh, bw, bitDepth; + + XWindowSystemUtilities::ScopedXLock xLock; + + return X11Symbols::getInstance()->xGetGeometry (display, (::Drawable) windowH, &root, &wx, &wy, &ww, &wh, &bw, &bitDepth) + && X11Symbols::getInstance()->xTranslateCoordinates (display, windowH, windowH, localPos.getX(), localPos.getY(), &wx, &wy, &child) + && child == None; +} + +BorderSize<int> XWindowSystem::getBorderSize (::Window windowH) const +{ + jassert (windowH != 0); + + XWindowSystemUtilities::ScopedXLock xLock; + auto hints = XWindowSystemUtilities::Atoms::getIfExists (display, "_NET_FRAME_EXTENTS"); + + if (hints != None) + { + XWindowSystemUtilities::GetXProperty prop (windowH, hints, 0, 4, false, XA_CARDINAL); + + if (prop.success && prop.actualFormat == 32) + { + auto data = prop.data; + std::array<unsigned long, 4> sizes; + + for (auto& size : sizes) + { + memcpy (&size, data, sizeof (unsigned long)); + data += sizeof (unsigned long); + } + + return { (int) sizes[2], (int) sizes[0], (int) sizes[3], (int) sizes[1] }; + } + } + + return {}; +} + +Rectangle<int> XWindowSystem::getWindowBounds (::Window windowH, ::Window parentWindow) +{ + jassert (windowH != 0); + + Window root, child; + int wx = 0, wy = 0; + unsigned int ww = 0, wh = 0, bw, bitDepth; + + XWindowSystemUtilities::ScopedXLock xLock; + + if (X11Symbols::getInstance()->xGetGeometry (display, (::Drawable) windowH, &root, &wx, &wy, &ww, &wh, &bw, &bitDepth)) + { + int rootX = 0, rootY = 0; + + if (! X11Symbols::getInstance()->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<int> (rootX, rootY)); + } + } + + return { wx, wy, (int) ww, (int) wh }; +} + +Point<int> XWindowSystem::getParentScreenPosition() const +{ + return parentScreenPosition; +} + +void XWindowSystem::setMinimised (::Window windowH, bool shouldBeMinimised) const +{ + jassert (windowH != 0); + + if (shouldBeMinimised) + { + auto root = X11Symbols::getInstance()->xRootWindow (display, X11Symbols::getInstance()->xDefaultScreen (display)); + + XClientMessageEvent clientMsg; + clientMsg.display = display; + clientMsg.window = windowH; + clientMsg.type = ClientMessage; + clientMsg.format = 32; + clientMsg.message_type = atoms.changeState; + clientMsg.data.l[0] = IconicState; + + XWindowSystemUtilities::ScopedXLock xLock; + X11Symbols::getInstance()->xSendEvent (display, root, false, SubstructureRedirectMask | SubstructureNotifyMask, (XEvent*) &clientMsg); + } +} + +bool XWindowSystem::isMinimised (::Window windowH) const +{ + jassert (windowH != 0); + + XWindowSystemUtilities::ScopedXLock xLock; + XWindowSystemUtilities::GetXProperty prop (windowH, atoms.state, 0, 64, false, atoms.state); + + if (prop.success && prop.actualType == atoms.state + && prop.actualFormat == 32 && prop.numItems > 0) + { + unsigned long state; + memcpy (&state, prop.data, sizeof (unsigned long)); + + return state == IconicState; + } + + return false; +} + +void XWindowSystem::toFront (::Window windowH, bool) const +{ + jassert (windowH != 0); + + XWindowSystemUtilities::ScopedXLock xLock; + XEvent ev; + ev.xclient.type = ClientMessage; + ev.xclient.serial = 0; + ev.xclient.send_event = True; + ev.xclient.message_type = atoms.activeWin; + ev.xclient.window = windowH; + ev.xclient.format = 32; + ev.xclient.data.l[0] = 2; + ev.xclient.data.l[1] = getUserTime (windowH); + ev.xclient.data.l[2] = 0; + ev.xclient.data.l[3] = 0; + ev.xclient.data.l[4] = 0; + + X11Symbols::getInstance()->xSendEvent (display, X11Symbols::getInstance()->xRootWindow (display, X11Symbols::getInstance()->xDefaultScreen (display)), + False, SubstructureRedirectMask | SubstructureNotifyMask, &ev); + + X11Symbols::getInstance()->xSync (display, False); +} + +void XWindowSystem::toBehind (::Window windowH, ::Window otherWindow) const +{ + jassert (windowH != 0 && otherWindow != 0); + + Window newStack[] = { otherWindow, windowH }; + + XWindowSystemUtilities::ScopedXLock xLock; + X11Symbols::getInstance()->xRestackWindows (display, newStack, 2); +} + +bool XWindowSystem::isFocused (::Window windowH) const +{ + jassert (windowH != 0); + + int revert = 0; + Window focusedWindow = 0; + XWindowSystemUtilities::ScopedXLock xLock; + X11Symbols::getInstance()->xGetInputFocus (display, &focusedWindow, &revert); + + if (focusedWindow == PointerRoot) + return false; + + return isParentWindowOf (windowH, focusedWindow); +} + +::Window XWindowSystem::getFocusWindow (::Window windowH) const +{ + jassert (windowH != 0); + + #if JUCE_X11_SUPPORTS_XEMBED + if (auto w = (::Window) juce_getCurrentFocusWindow (dynamic_cast<LinuxComponentPeer<::Window>*> (getPeerFor (windowH)))) + return w; + #endif + + return windowH; +} + +bool XWindowSystem::grabFocus (::Window windowH) const +{ + jassert (windowH != 0); + + XWindowAttributes atts; + XWindowSystemUtilities::ScopedXLock xLock; + + if (windowH != 0 + && X11Symbols::getInstance()->xGetWindowAttributes (display, windowH, &atts) + && atts.map_state == IsViewable + && ! isFocused (windowH)) + { + X11Symbols::getInstance()->xSetInputFocus (display, getFocusWindow (windowH), RevertToParent, (::Time) getUserTime (windowH)); + return true; + } + + return false; +} + +bool XWindowSystem::canUseSemiTransparentWindows() const +{ + #if JUCE_USE_XRENDER + if (XRender::hasCompositingWindowManager (display)) + { + int matchedDepth = 0, desiredDepth = 32; + + return Visuals::findVisualFormat (display, desiredDepth, matchedDepth) != nullptr + && matchedDepth == desiredDepth; + } + #endif + + return false; +} + +bool XWindowSystem::canUseARGBImages() const +{ + static bool canUseARGB = false; + + #if JUCE_USE_XSHM + static bool checked = false; + + if (! checked) + { + if (XSHMHelpers::isShmAvailable (display)) + { + XWindowSystemUtilities::ScopedXLock xLock; + XShmSegmentInfo segmentinfo; + + auto testImage = X11Symbols::getInstance()->xShmCreateImage (display, + X11Symbols::getInstance()->xDefaultVisual (display, X11Symbols::getInstance()->xDefaultScreen (display)), + 24, ZPixmap, nullptr, &segmentinfo, 64, 64); + + canUseARGB = (testImage->bits_per_pixel == 32); + X11Symbols::getInstance()->xDestroyImage (testImage); + } + else + { + canUseARGB = false; + } + + checked = true; + } + #endif + + return canUseARGB; +} + +Image XWindowSystem::createImage (bool isSemiTransparent, int width, int height, bool argb) const +{ + auto visualAndDepth = displayVisuals->getBestVisualForWindow (isSemiTransparent); + + #if JUCE_USE_XSHM + return Image (new XBitmapImage (argb ? Image::ARGB : Image::RGB, + #else + return Image (new XBitmapImage (Image::RGB, + #endif + (width + 31) & ~31, + (height + 31) & ~31, + false, (unsigned int) visualAndDepth.depth, visualAndDepth.visual)); +} + +void XWindowSystem::blitToWindow (::Window windowH, Image image, Rectangle<int> destinationRect, Rectangle<int> totalRect) const +{ + jassert (windowH != 0); + + auto* xbitmap = static_cast<XBitmapImage*> (image.getPixelData()); + + xbitmap->blitToWindow (windowH, + destinationRect.getX(), destinationRect.getY(), + (unsigned int) destinationRect.getWidth(), + (unsigned int) destinationRect.getHeight(), + destinationRect.getX() - totalRect.getX(), destinationRect.getY() - totalRect.getY()); +} + +void XWindowSystem::processPendingPaintsForWindow (::Window windowH) +{ + #if JUCE_USE_XSHM + if (! XSHMHelpers::isShmAvailable (display)) + return; + + if (getNumPaintsPendingForWindow (windowH) > 0) + { + XWindowSystemUtilities::ScopedXLock xLock; + + XEvent evt; + while (X11Symbols::getInstance()->xCheckTypedWindowEvent (display, windowH, shmCompletionEvent, &evt)) + removePendingPaintForWindow (windowH); + } + #endif +} + +int XWindowSystem::getNumPaintsPendingForWindow (::Window windowH) +{ + #if JUCE_USE_XSHM + if (XSHMHelpers::isShmAvailable (display)) + return shmPaintsPendingMap[windowH]; + #endif + + return 0; +} + +void XWindowSystem::addPendingPaintForWindow (::Window windowH) +{ + #if JUCE_USE_XSHM + if (XSHMHelpers::isShmAvailable (display)) + ++shmPaintsPendingMap[windowH]; + #endif +} + +void XWindowSystem::removePendingPaintForWindow (::Window windowH) +{ + #if JUCE_USE_XSHM + if (XSHMHelpers::isShmAvailable (display)) + --shmPaintsPendingMap[windowH]; + #endif +} + +void XWindowSystem::setScreenSaverEnabled (bool enabled) const +{ + using tXScreenSaverSuspend = void (*) (Display*, Bool); + static tXScreenSaverSuspend xScreenSaverSuspend = nullptr; + + if (xScreenSaverSuspend == nullptr) + if (void* h = dlopen ("libXss.so.1", RTLD_GLOBAL | RTLD_NOW)) + xScreenSaverSuspend = (tXScreenSaverSuspend) dlsym (h, "XScreenSaverSuspend"); + + XWindowSystemUtilities::ScopedXLock xLock; + + if (xScreenSaverSuspend != nullptr) + xScreenSaverSuspend (display, ! enabled); +} + +Point<float> XWindowSystem::getCurrentMousePosition() const +{ + Window root, child; + int x, y, winx, winy; + unsigned int mask; + + XWindowSystemUtilities::ScopedXLock xLock; + + if (X11Symbols::getInstance()->xQueryPointer (display, + X11Symbols::getInstance()->xRootWindow (display, + X11Symbols::getInstance()->xDefaultScreen (display)), + &root, &child, + &x, &y, &winx, &winy, &mask) == False) + { + x = y = -1; + } + + return { (float) x, (float) y }; +} + +void XWindowSystem::setMousePosition (Point<float> pos) const +{ + XWindowSystemUtilities::ScopedXLock xLock; + + auto root = X11Symbols::getInstance()->xRootWindow (display, + X11Symbols::getInstance()->xDefaultScreen (display)); + + X11Symbols::getInstance()->xWarpPointer (display, None, root, 0, 0, 0, 0, + roundToInt (pos.getX()), roundToInt (pos.getY())); +} + +void* XWindowSystem::createCustomMouseCursorInfo (const Image& image, Point<int> hotspot) const +{ + if (display == nullptr) + return nullptr; + + XWindowSystemUtilities::ScopedXLock xLock; + + auto imageW = (unsigned int) image.getWidth(); + auto imageH = (unsigned int) image.getHeight(); + auto hotspotX = hotspot.x; + auto hotspotY = hotspot.y; + + #if JUCE_USE_XCURSOR + if (auto* xcImage = X11Symbols::getInstance()->xcursorImageCreate ((int) imageW, (int) imageH)) + { + xcImage->xhot = (XcursorDim) hotspotX; + xcImage->yhot = (XcursorDim) hotspotY; + auto* dest = xcImage->pixels; + + for (int y = 0; y < (int) imageH; ++y) + for (int x = 0; x < (int) imageW; ++x) + *dest++ = image.getPixelAt (x, y).getARGB(); + + auto* result = (void*) X11Symbols::getInstance()->xcursorImageLoadCursor (display, xcImage); + X11Symbols::getInstance()->xcursorImageDestroy (xcImage); + + if (result != nullptr) + return result; + } + #endif + + auto root = X11Symbols::getInstance()->xRootWindow (display, + X11Symbols::getInstance()->xDefaultScreen (display)); + + unsigned int cursorW, cursorH; + if (! X11Symbols::getInstance()->xQueryBestCursor (display, root, imageW, imageH, &cursorW, &cursorH)) + return nullptr; + + Image im (Image::ARGB, (int) cursorW, (int) cursorH, true); + + { + Graphics g (im); + + if (imageW > cursorW || imageH > cursorH) + { + hotspotX = (hotspotX * (int) cursorW) / (int) imageW; + hotspotY = (hotspotY * (int) cursorH) / (int) imageH; + + g.drawImage (image, Rectangle<float> ((float) imageW, (float) imageH), + RectanglePlacement::xLeft | RectanglePlacement::yTop | RectanglePlacement::onlyReduceInSize); + } + else + { + g.drawImageAt (image, 0, 0); + } + } + + auto stride = (cursorW + 7) >> 3; + HeapBlock<char> maskPlane, sourcePlane; + maskPlane.calloc (stride * cursorH); + sourcePlane.calloc (stride * cursorH); + + auto msbfirst = (X11Symbols::getInstance()->xBitmapBitOrder (display) == MSBFirst); + + for (auto y = (int) cursorH; --y >= 0;) + { + for (auto x = (int) cursorW; --x >= 0;) + { + auto mask = (char) (1 << (msbfirst ? (7 - (x & 7)) : (x & 7))); + auto offset = (unsigned int) y * stride + ((unsigned int) x >> 3); + + auto c = im.getPixelAt (x, y); + + if (c.getAlpha() >= 128) maskPlane[offset] |= mask; + if (c.getBrightness() >= 0.5f) sourcePlane[offset] |= mask; + } + } + + auto sourcePixmap = X11Symbols::getInstance()->xCreatePixmapFromBitmapData (display, root, sourcePlane.getData(), cursorW, cursorH, 0xffff, 0, 1); + auto maskPixmap = X11Symbols::getInstance()->xCreatePixmapFromBitmapData (display, root, maskPlane.getData(), cursorW, cursorH, 0xffff, 0, 1); + + XColor white, black; + black.red = black.green = black.blue = 0; + white.red = white.green = white.blue = 0xffff; + + auto* result = (void*) X11Symbols::getInstance()->xCreatePixmapCursor (display, sourcePixmap, maskPixmap, &white, &black, + (unsigned int) hotspotX, (unsigned int) hotspotY); + + X11Symbols::getInstance()->xFreePixmap (display, sourcePixmap); + X11Symbols::getInstance()->xFreePixmap (display, maskPixmap); + + return result; +} + +void XWindowSystem::deleteMouseCursor (void* cursorHandle) const +{ + if (cursorHandle != nullptr && display != nullptr) + { + XWindowSystemUtilities::ScopedXLock xLock; + X11Symbols::getInstance()->xFreeCursor (display, (Cursor) cursorHandle); + } +} + +void* createDraggingHandCursor() +{ + static unsigned char dragHandData[] = { + 71,73,70,56,57,97,16,0,16,0,145,2,0,0,0,0,255,255,255,0,0,0,0,0,0,33,249,4,1,0,0,2,0,44,0,0,0,0,16,0,16,0, + 0,2,52,148,47,0,200,185,16,130,90,12,74,139,107,84,123,39,132,117,151,116,132,146,248,60,209,138,98,22,203, + 114,34,236,37,52,77,217, 247,154,191,119,110,240,193,128,193,95,163,56,60,234,98,135,2,0,59 + }; + size_t dragHandDataSize = 99; + + return CustomMouseCursorInfo (ImageFileFormat::loadFrom (dragHandData, dragHandDataSize), { 8, 7 }).create(); +} + +void* XWindowSystem::createStandardMouseCursor (MouseCursor::StandardCursorType type) const +{ + if (display == nullptr) + return None; + + unsigned int shape; + + switch (type) + { + case MouseCursor::NormalCursor: + case MouseCursor::ParentCursor: return None; // Use parent cursor + case MouseCursor::NoCursor: return CustomMouseCursorInfo (Image (Image::ARGB, 16, 16, true), {}).create(); + + case MouseCursor::WaitCursor: shape = XC_watch; break; + case MouseCursor::IBeamCursor: shape = XC_xterm; break; + case MouseCursor::PointingHandCursor: shape = XC_hand2; break; + case MouseCursor::LeftRightResizeCursor: shape = XC_sb_h_double_arrow; break; + case MouseCursor::UpDownResizeCursor: shape = XC_sb_v_double_arrow; break; + case MouseCursor::UpDownLeftRightResizeCursor: shape = XC_fleur; break; + case MouseCursor::TopEdgeResizeCursor: shape = XC_top_side; break; + case MouseCursor::BottomEdgeResizeCursor: shape = XC_bottom_side; break; + case MouseCursor::LeftEdgeResizeCursor: shape = XC_left_side; break; + case MouseCursor::RightEdgeResizeCursor: shape = XC_right_side; break; + case MouseCursor::TopLeftCornerResizeCursor: shape = XC_top_left_corner; break; + case MouseCursor::TopRightCornerResizeCursor: shape = XC_top_right_corner; break; + case MouseCursor::BottomLeftCornerResizeCursor: shape = XC_bottom_left_corner; break; + case MouseCursor::BottomRightCornerResizeCursor: shape = XC_bottom_right_corner; break; + case MouseCursor::CrosshairCursor: shape = XC_crosshair; break; + case MouseCursor::DraggingHandCursor: return createDraggingHandCursor(); + + case MouseCursor::CopyingCursor: + { + static unsigned char copyCursorData[] = { + 71,73,70,56,57,97,21,0,21,0,145,0,0,0,0,0,255,255,255,0,128,128,255,255,255,33,249,4,1,0,0,3,0,44,0,0,0,0, + 21,0,21,0,0,2,72,4,134,169,171,16,199,98,11,79,90,71,161,93,56,111,78,133,218,215,137,31,82,154,100,200, + 86,91,202,142,12,108,212,87,235,174,15,54,214,126,237,226,37,96,59,141,16,37,18,201,142,157,230,204,51,112, + 252,114,147,74,83,5,50,68,147,208,217,16,71,149,252,124,5,0,59,0,0 + }; + static constexpr int copyCursorSize = 119; + + return CustomMouseCursorInfo (ImageFileFormat::loadFrom (copyCursorData, copyCursorSize), { 1, 3 }).create(); + } + + case MouseCursor::NumStandardCursorTypes: + default: + { + jassertfalse; + return None; + } + } + + XWindowSystemUtilities::ScopedXLock xLock; + + return (void*) X11Symbols::getInstance()->xCreateFontCursor (display, shape); +} + +void XWindowSystem::showCursor (::Window windowH, void* cursorHandle) const +{ + jassert (windowH != 0); + + XWindowSystemUtilities::ScopedXLock xLock; + X11Symbols::getInstance()->xDefineCursor (display, windowH, (Cursor) cursorHandle); +} + +bool XWindowSystem::isKeyCurrentlyDown (int keyCode) const +{ + int keysym; + + if (keyCode & Keys::extendedKeyModifier) + { + keysym = 0xff00 | (keyCode & 0xff); + } + else + { + keysym = keyCode; + + if (keysym == (XK_Tab & 0xff) + || keysym == (XK_Return & 0xff) + || keysym == (XK_Escape & 0xff) + || keysym == (XK_BackSpace & 0xff)) + { + keysym |= 0xff00; + } + } + + XWindowSystemUtilities::ScopedXLock xLock; + + auto keycode = X11Symbols::getInstance()->xKeysymToKeycode (display, (KeySym) keysym); + auto keybyte = keycode >> 3; + auto keybit = (1 << (keycode & 7)); + + return (Keys::keyStates [keybyte] & keybit) != 0; +} + +ModifierKeys XWindowSystem::getNativeRealtimeModifiers() const +{ + ::Window root, child; + int x, y, winx, winy; + unsigned int mask; + int mouseMods = 0; + + XWindowSystemUtilities::ScopedXLock xLock; + + if (X11Symbols::getInstance()->xQueryPointer (display, + X11Symbols::getInstance()->xRootWindow (display, + X11Symbols::getInstance()->xDefaultScreen (display)), + &root, &child, &x, &y, &winx, &winy, &mask) != False) + { + if ((mask & Button1Mask) != 0) mouseMods |= ModifierKeys::leftButtonModifier; + if ((mask & Button2Mask) != 0) mouseMods |= ModifierKeys::middleButtonModifier; + if ((mask & Button3Mask) != 0) mouseMods |= ModifierKeys::rightButtonModifier; + } + + ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withoutMouseButtons().withFlags (mouseMods); + + return ModifierKeys::currentModifiers; +} + +static bool hasWorkAreaData (const XWindowSystemUtilities::GetXProperty& prop) +{ + return prop.success + && prop.actualType == XA_CARDINAL + && prop.actualFormat == 32 + && prop.numItems == 4 + && prop.data != nullptr; +} + +static Rectangle<int> getWorkArea (const XWindowSystemUtilities::GetXProperty& prop) +{ + if (hasWorkAreaData (prop)) + { + auto* positionData = prop.data; + std::array<long, 4> position; + + for (auto& p : position) + { + memcpy (&p, positionData, sizeof (long)); + positionData += sizeof (long); + } + + return { (int) position[0], (int) position[1], + (int) position[2], (int) position[3] }; + } + + return {}; +} + +Array<Displays::Display> XWindowSystem::findDisplays (float masterScale) const +{ + Array<Displays::Display> displays; + auto workAreaHints = XWindowSystemUtilities::Atoms::getIfExists (display, "_NET_WORKAREA"); + + #if JUCE_USE_XRANDR + { + int major_opcode, first_event, first_error; + + if (X11Symbols::getInstance()->xQueryExtension (display, "RANDR", &major_opcode, &first_event, &first_error)) + { + auto numMonitors = X11Symbols::getInstance()->xScreenCount (display); + auto mainDisplay = X11Symbols::getInstance()->xRRGetOutputPrimary (display, X11Symbols::getInstance()->xRootWindow (display, 0)); + + for (int i = 0; i < numMonitors; ++i) + { + auto rootWindow = X11Symbols::getInstance()->xRootWindow (display, i); + XWindowSystemUtilities::GetXProperty prop (rootWindow, workAreaHints, 0, 4, false, XA_CARDINAL); + + if (! hasWorkAreaData (prop)) + continue; + + if (auto* screens = X11Symbols::getInstance()->xRRGetScreenResources (display, rootWindow)) + { + for (int j = 0; j < screens->noutput; ++j) + { + if (screens->outputs[j]) + { + // Xrandr on the raspberry pi fails to determine the main display (mainDisplay == 0)! + // Detect this edge case and make the first found display the main display + if (! mainDisplay) + mainDisplay = screens->outputs[j]; + + if (auto* output = X11Symbols::getInstance()->xRRGetOutputInfo (display, screens, screens->outputs[j])) + { + if (output->crtc) + { + if (auto* crtc = X11Symbols::getInstance()->xRRGetCrtcInfo (display, screens, output->crtc)) + { + Displays::Display d; + d.totalArea = { crtc->x, crtc->y, (int) crtc->width, (int) crtc->height }; + d.isMain = (mainDisplay == screens->outputs[j]) && (i == 0); + d.dpi = DisplayHelpers::getDisplayDPI (display, 0); + + // The raspberry pi returns a zero sized display, so we need to guard for divide-by-zero + if (output->mm_width > 0 && output->mm_height > 0) + d.dpi = ((static_cast<double> (crtc->width) * 25.4 * 0.5) / static_cast<double> (output->mm_width)) + + ((static_cast<double> (crtc->height) * 25.4 * 0.5) / static_cast<double> (output->mm_height)); + + auto scale = DisplayHelpers::getDisplayScale (output->name, d.dpi); + scale = (scale <= 0.1 ? 1.0 : scale); + + d.scale = masterScale * scale; + + if (d.isMain) + displays.insert (0, d); + else + displays.add (d); + + X11Symbols::getInstance()->xRRFreeCrtcInfo (crtc); + } + } + + X11Symbols::getInstance()->xRRFreeOutputInfo (output); + } + } + } + + X11Symbols::getInstance()->xRRFreeScreenResources (screens); + } + } + + if (! displays.isEmpty() && ! displays.getReference (0).isMain) + displays.getReference (0).isMain = true; + } + } + + if (displays.isEmpty()) + #endif + #if JUCE_USE_XINERAMA + { + auto screens = DisplayHelpers::xineramaQueryDisplays (display); + auto numMonitors = screens.size(); + + for (int index = 0; index < numMonitors; ++index) + { + for (auto j = numMonitors; --j >= 0;) + { + if (screens[j].screen_number == index) + { + Displays::Display d; + d.totalArea = { screens[j].x_org, screens[j].y_org, + screens[j].width, screens[j].height }; + d.isMain = (index == 0); + d.scale = masterScale; + d.dpi = DisplayHelpers::getDisplayDPI (display, 0); // (all screens share the same DPI) + + displays.add (d); + } + } + } + } + + if (displays.isEmpty()) + #endif + { + if (workAreaHints != None) + { + auto numMonitors = X11Symbols::getInstance()->xScreenCount (display); + + for (int i = 0; i < numMonitors; ++i) + { + XWindowSystemUtilities::GetXProperty prop (X11Symbols::getInstance()->xRootWindow (display, i), + workAreaHints, 0, 4, false, XA_CARDINAL); + + auto workArea = getWorkArea (prop); + + if (! workArea.isEmpty()) + { + Displays::Display d; + + d.totalArea = workArea; + d.isMain = displays.isEmpty(); + d.scale = masterScale; + d.dpi = DisplayHelpers::getDisplayDPI (display, i); + + displays.add (d); + } + } + } + + if (displays.isEmpty()) + { + Displays::Display d; + d.totalArea = { X11Symbols::getInstance()->xDisplayWidth (display, X11Symbols::getInstance()->xDefaultScreen (display)), + X11Symbols::getInstance()->xDisplayHeight (display, X11Symbols::getInstance()->xDefaultScreen (display)) }; + d.isMain = true; + d.scale = masterScale; + d.dpi = DisplayHelpers::getDisplayDPI (display, 0); + + displays.add (d); + } + } + + for (auto& d : displays) + d.userArea = d.totalArea; // JUCE currently does not support requesting the user area on Linux + + return displays; +} + +::Window XWindowSystem::createKeyProxy (::Window windowH) const +{ + jassert (windowH != 0); + + XSetWindowAttributes swa; + swa.event_mask = KeyPressMask | KeyReleaseMask | FocusChangeMask; + + auto keyProxy = X11Symbols::getInstance()->xCreateWindow (display, windowH, + -1, -1, 1, 1, 0, 0, + InputOnly, CopyFromParent, + CWEventMask, + &swa); + + X11Symbols::getInstance()->xMapWindow (display, keyProxy); + X11Symbols::getInstance()->xSaveContext (display, (XID) keyProxy, windowHandleXContext, (XPointer) this); + + return keyProxy; +} + +void XWindowSystem::deleteKeyProxy (::Window keyProxy) const +{ + jassert (keyProxy != 0); + + XPointer handlePointer; + + if (! X11Symbols::getInstance()->xFindContext (display, (XID) keyProxy, windowHandleXContext, &handlePointer)) + X11Symbols::getInstance()->xDeleteContext (display, (XID) keyProxy, windowHandleXContext); + + X11Symbols::getInstance()->xDestroyWindow (display, keyProxy); + X11Symbols::getInstance()->xSync (display, false); + + XEvent event; + while (X11Symbols::getInstance()->xCheckWindowEvent (display, keyProxy, getAllEventsMask (false), &event) == True) + {} +} + +bool XWindowSystem::externalDragFileInit (LinuxComponentPeer<::Window>* peer, const StringArray& files, bool, std::function<void()>&& callback) const +{ + auto& dragState = dragAndDropStateMap[peer]; + + if (dragState.isDragging()) + return false; + + StringArray uriList; + + for (auto& f : files) + { + if (f.matchesWildcard ("?*://*", false)) + uriList.add (f); + else + uriList.add ("file://" + f); + } + + return dragState.externalDragInit ((::Window) peer->getNativeHandle(), false, uriList.joinIntoString ("\r\n"), std::move (callback)); +} + +bool XWindowSystem::externalDragTextInit (LinuxComponentPeer<::Window>* peer, const String& text, std::function<void()>&& callback) const +{ + auto& dragState = dragAndDropStateMap[peer]; + + if (dragState.isDragging()) + return false; + + return dragState.externalDragInit ((::Window) peer->getNativeHandle(), true, text, std::move (callback)); +} + +void XWindowSystem::copyTextToClipboard (const String& clipText) +{ + localClipboardContent = clipText; + + X11Symbols::getInstance()->xSetSelectionOwner (display, XA_PRIMARY, juce_messageWindowHandle, CurrentTime); + X11Symbols::getInstance()->xSetSelectionOwner (display, atoms.clipboard, juce_messageWindowHandle, CurrentTime); +} + +String XWindowSystem::getTextFromClipboard() const +{ + String content; + + /* 1) try to read from the "CLIPBOARD" selection first (the "high + level" clipboard that is supposed to be filled by ctrl-C + etc). When a clipboard manager is running, the content of this + selection is preserved even when the original selection owner + exits. + + 2) and then try to read from "PRIMARY" selection (the "legacy" selection + filled by good old x11 apps such as xterm) + */ + auto selection = XA_PRIMARY; + Window selectionOwner = None; + + if ((selectionOwner = X11Symbols::getInstance()->xGetSelectionOwner (display, selection)) == None) + { + selection = atoms.clipboard; + selectionOwner = X11Symbols::getInstance()->xGetSelectionOwner (display, selection); + } + + if (selectionOwner != None) + { + if (selectionOwner == juce_messageWindowHandle) + content = localClipboardContent; + else if (! ClipboardHelpers::requestSelectionContent (display, content, selection, atoms.utf8String)) + ClipboardHelpers::requestSelectionContent (display, content, selection, XA_STRING); + } + + return content; +} + +//============================================================================== +bool XWindowSystem::isParentWindowOf (::Window windowH, ::Window possibleChild) const +{ + if (windowH != 0 && possibleChild != 0) + { + if (possibleChild == windowH) + return true; + + Window* windowList = nullptr; + uint32 windowListSize = 0; + Window parent, root; + + XWindowSystemUtilities::ScopedXLock xLock; + if (X11Symbols::getInstance()->xQueryTree (display, possibleChild, &root, &parent, &windowList, &windowListSize) != 0) + { + if (windowList != nullptr) + X11Symbols::getInstance()->xFree (windowList); + + if (parent == root) + return false; + + return isParentWindowOf (windowH, parent); + } + } + + return false; +} + +bool XWindowSystem::isFrontWindow (::Window windowH) const +{ + jassert (windowH != 0); + + Window* windowList = nullptr; + uint32 windowListSize = 0; + bool result = false; + + XWindowSystemUtilities::ScopedXLock xLock; + Window parent; + auto root = X11Symbols::getInstance()->xRootWindow (display, X11Symbols::getInstance()->xDefaultScreen (display)); + + if (X11Symbols::getInstance()->xQueryTree (display, root, &root, &parent, &windowList, &windowListSize) != 0) + { + for (int i = (int) windowListSize; --i >= 0;) + { + if (auto* peer = dynamic_cast<LinuxComponentPeer<::Window>*> (getPeerFor (windowList[i]))) + { + result = (peer == dynamic_cast<LinuxComponentPeer<::Window>*> (getPeerFor (windowH))); + break; + } + } + } + + if (windowList != nullptr) + X11Symbols::getInstance()->xFree (windowList); + + return result; +} + +void XWindowSystem::xchangeProperty (::Window windowH, Atom property, Atom type, int format, const void* data, int numElements) const +{ + jassert (windowH != 0); + + X11Symbols::getInstance()->xChangeProperty (display, windowH, property, type, format, PropModeReplace, (const unsigned char*) data, numElements); +} + +void XWindowSystem::removeWindowDecorations (::Window windowH) const +{ + jassert (windowH != 0); + + Atom hints = XWindowSystemUtilities::Atoms::getIfExists (display, "_MOTIF_WM_HINTS"); + + if (hints != None) + { + MotifWmHints motifHints; + zerostruct (motifHints); + + motifHints.flags = 2; /* MWM_HINTS_DECORATIONS */ + motifHints.decorations = 0; + + XWindowSystemUtilities::ScopedXLock xLock; + xchangeProperty (windowH, hints, hints, 32, &motifHints, 4); + } + + hints = XWindowSystemUtilities::Atoms::getIfExists (display, "_WIN_HINTS"); + + if (hints != None) + { + long gnomeHints = 0; + + XWindowSystemUtilities::ScopedXLock xLock; + xchangeProperty (windowH, hints, hints, 32, &gnomeHints, 1); + } + + hints = XWindowSystemUtilities::Atoms::getIfExists (display, "KWM_WIN_DECORATION"); + + if (hints != None) + { + long kwmHints = 2; /*KDE_tinyDecoration*/ + + XWindowSystemUtilities::ScopedXLock xLock; + xchangeProperty (windowH, hints, hints, 32, &kwmHints, 1); + } + + hints = XWindowSystemUtilities::Atoms::getIfExists (display, "_KDE_NET_WM_WINDOW_TYPE_OVERRIDE"); + + if (hints != None) + { + XWindowSystemUtilities::ScopedXLock xLock; + xchangeProperty (windowH, atoms.windowType, XA_ATOM, 32, &hints, 1); + } +} + +void XWindowSystem::addWindowButtons (::Window windowH, int styleFlags) const +{ + jassert (windowH != 0); + + XWindowSystemUtilities::ScopedXLock xLock; + Atom hints = XWindowSystemUtilities::Atoms::getIfExists (display, "_MOTIF_WM_HINTS"); + + if (hints != None) + { + MotifWmHints motifHints; + zerostruct (motifHints); + + motifHints.flags = 1 | 2; /* MWM_HINTS_FUNCTIONS | MWM_HINTS_DECORATIONS */ + motifHints.decorations = 2 /* MWM_DECOR_BORDER */ | 8 /* MWM_DECOR_TITLE */ | 16; /* MWM_DECOR_MENU */ + + motifHints.functions = 4 /* MWM_FUNC_MOVE */; + + if ((styleFlags & ComponentPeer::windowHasCloseButton) != 0) + motifHints.functions |= 32; /* MWM_FUNC_CLOSE */ + + if ((styleFlags & ComponentPeer::windowHasMinimiseButton) != 0) + { + motifHints.functions |= 8; /* MWM_FUNC_MINIMIZE */ + motifHints.decorations |= 0x20; /* MWM_DECOR_MINIMIZE */ + } + + if ((styleFlags & ComponentPeer::windowHasMaximiseButton) != 0) + { + motifHints.functions |= 0x10; /* MWM_FUNC_MAXIMIZE */ + motifHints.decorations |= 0x40; /* MWM_DECOR_MAXIMIZE */ + } + + if ((styleFlags & ComponentPeer::windowIsResizable) != 0) + { + motifHints.functions |= 2; /* MWM_FUNC_RESIZE */ + motifHints.decorations |= 0x4; /* MWM_DECOR_RESIZEH */ + } + + xchangeProperty (windowH, hints, hints, 32, &motifHints, 5); + } + + hints = XWindowSystemUtilities::Atoms::getIfExists (display, "_NET_WM_ALLOWED_ACTIONS"); + + if (hints != None) + { + Atom netHints [6]; + int num = 0; + + if ((styleFlags & ComponentPeer::windowIsResizable) != 0) + netHints [num++] = XWindowSystemUtilities::Atoms::getIfExists (display, "_NET_WM_ACTION_RESIZE"); + + if ((styleFlags & ComponentPeer::windowHasMaximiseButton) != 0) + netHints [num++] = XWindowSystemUtilities::Atoms::getIfExists (display, "_NET_WM_ACTION_FULLSCREEN"); + + if ((styleFlags & ComponentPeer::windowHasMinimiseButton) != 0) + netHints [num++] = XWindowSystemUtilities::Atoms::getIfExists (display, "_NET_WM_ACTION_MINIMIZE"); + + if ((styleFlags & ComponentPeer::windowHasCloseButton) != 0) + netHints [num++] = XWindowSystemUtilities::Atoms::getIfExists (display, "_NET_WM_ACTION_CLOSE"); + + xchangeProperty (windowH, hints, XA_ATOM, 32, &netHints, num); + } +} + +void XWindowSystem::setWindowType (::Window windowH, int styleFlags) const +{ + jassert (windowH != 0); + + Atom netHints [2]; + + if ((styleFlags & ComponentPeer::windowIsTemporary) != 0 + || ((styleFlags & ComponentPeer::windowHasDropShadow) == 0 && Desktop::canUseSemiTransparentWindows())) + netHints [0] = XWindowSystemUtilities::Atoms::getIfExists (display, "_NET_WM_WINDOW_TYPE_COMBO"); + else + netHints [0] = XWindowSystemUtilities::Atoms::getIfExists (display, "_NET_WM_WINDOW_TYPE_NORMAL"); + + xchangeProperty (windowH, atoms.windowType, XA_ATOM, 32, &netHints, 1); + + int numHints = 0; + + if ((styleFlags & ComponentPeer::windowAppearsOnTaskbar) == 0) + netHints [numHints++] = XWindowSystemUtilities::Atoms::getIfExists (display, "_NET_WM_STATE_SKIP_TASKBAR"); + + if (getPeerFor (windowH)->getComponent().isAlwaysOnTop()) + netHints [numHints++] = XWindowSystemUtilities::Atoms::getIfExists (display, "_NET_WM_STATE_ABOVE"); + + if (numHints > 0) + xchangeProperty (windowH, atoms.windowState, XA_ATOM, 32, &netHints, numHints); +} + +void XWindowSystem::initialisePointerMap() +{ + auto numButtons = X11Symbols::getInstance()->xGetPointerMapping (display, nullptr, 0); + pointerMap[2] = pointerMap[3] = pointerMap[4] = Keys::NoButton; + + if (numButtons == 2) + { + pointerMap[0] = Keys::LeftButton; + pointerMap[1] = Keys::RightButton; + } + else if (numButtons >= 3) + { + pointerMap[0] = Keys::LeftButton; + pointerMap[1] = Keys::MiddleButton; + pointerMap[2] = Keys::RightButton; + + if (numButtons >= 5) + { + pointerMap[3] = Keys::WheelUp; + pointerMap[4] = Keys::WheelDown; + } + } +} + +void XWindowSystem::deleteIconPixmaps (::Window windowH) const +{ + jassert (windowH != 0); + + XWindowSystemUtilities::ScopedXLock xLock; + + if (auto* wmHints = X11Symbols::getInstance()->xGetWMHints (display, windowH)) + { + if ((wmHints->flags & IconPixmapHint) != 0) + { + wmHints->flags &= ~IconPixmapHint; + X11Symbols::getInstance()->xFreePixmap (display, wmHints->icon_pixmap); + } + + if ((wmHints->flags & IconMaskHint) != 0) + { + wmHints->flags &= ~IconMaskHint; + X11Symbols::getInstance()->xFreePixmap (display, wmHints->icon_mask); + } + + X11Symbols::getInstance()->xSetWMHints (display, windowH, wmHints); + X11Symbols::getInstance()->xFree (wmHints); + } +} + +// Alt and Num lock are not defined by standard X modifier constants: check what they're mapped to +void XWindowSystem::updateModifierMappings() const +{ + XWindowSystemUtilities::ScopedXLock xLock; + auto altLeftCode = X11Symbols::getInstance()->xKeysymToKeycode (display, XK_Alt_L); + auto numLockCode = X11Symbols::getInstance()->xKeysymToKeycode (display, XK_Num_Lock); + + Keys::AltMask = 0; + Keys::NumLockMask = 0; + + if (auto* mapping = X11Symbols::getInstance()->xGetModifierMapping (display)) + { + for (int modifierIdx = 0; modifierIdx < 8; ++modifierIdx) + { + for (int keyIndex = 0; keyIndex < mapping->max_keypermod; ++keyIndex) + { + auto key = mapping->modifiermap[(modifierIdx * mapping->max_keypermod) + keyIndex]; + + if (key == altLeftCode) + Keys::AltMask = 1 << modifierIdx; + else if (key == numLockCode) + Keys::NumLockMask = 1 << modifierIdx; + } + } + + X11Symbols::getInstance()->xFreeModifiermap (mapping); + } +} + +long XWindowSystem::getUserTime (::Window windowH) const +{ + jassert (windowH != 0); + + XWindowSystemUtilities::GetXProperty prop (windowH, atoms.userTime, 0, 65536, false, XA_CARDINAL); + + if (! prop.success) + return 0; + + long result = 0; + memcpy (&result, prop.data, sizeof (long)); + + return result; +} + +XWindowSystem::DisplayVisuals::DisplayVisuals (::Display* xDisplay) +{ + auto findVisualWithDepthOrNull = [&] (int desiredDepth) -> Visual* + { + int matchedDepth = 0; + auto* visual = Visuals::findVisualFormat (xDisplay, desiredDepth, matchedDepth); + + if (desiredDepth == matchedDepth) + return visual; + + return nullptr; + }; + + visual16Bit = findVisualWithDepthOrNull (16); + visual24Bit = findVisualWithDepthOrNull (24); + visual32Bit = findVisualWithDepthOrNull (32); +} + +XWindowSystem::VisualAndDepth XWindowSystem::DisplayVisuals::getBestVisualForWindow (bool isSemiTransparent) const +{ + if (isSemiTransparent && visual32Bit != nullptr) + return { visual32Bit, 32 }; + + if (visual24Bit != nullptr) + return { visual24Bit, 24 }; + + return { visual16Bit, 16 }; +} + +bool XWindowSystem::DisplayVisuals::isValid() const noexcept +{ + return (visual32Bit != nullptr || visual24Bit != nullptr || visual16Bit != nullptr); +} + +//============================================================================== +bool XWindowSystem::initialiseXDisplay() +{ + jassert (display == nullptr); + + String displayName (getenv ("DISPLAY")); + + if (displayName.isEmpty()) + displayName = ":0.0"; + + // it seems that on some systems XOpenDisplay will occasionally + // fail the first time, but succeed on a second attempt.. + for (int retries = 2; --retries >= 0;) + { + display = X11Symbols::getInstance()->xOpenDisplay (displayName.toUTF8()); + + if (display != nullptr) + break; + } + + // No X Server running + if (display == nullptr) + return false; + + #if JUCE_DEBUG_XERRORS_SYNCHRONOUSLY + X11Symbols::getInstance()->xSynchronize (display, True); + #endif + + // Create a context to store user data associated with Windows we create + windowHandleXContext = (XContext) X11Symbols::getInstance()->xrmUniqueQuark(); + + // We're only interested in client messages for this window, which are always sent + XSetWindowAttributes swa; + swa.event_mask = NoEventMask; + + // Create our message window (this will never be mapped) + auto screen = X11Symbols::getInstance()->xDefaultScreen (display); + auto root = X11Symbols::getInstance()->xRootWindow (display, screen); + juce_messageWindowHandle = X11Symbols::getInstance()->xCreateWindow (display, root, + 0, 0, 1, 1, 0, 0, InputOnly, + X11Symbols::getInstance()->xDefaultVisual (display, screen), + CWEventMask, &swa); + + X11Symbols::getInstance()->xSync (display, False); + + atoms = XWindowSystemUtilities::Atoms (display); + + initialisePointerMap(); + updateModifierMappings(); + + #if JUCE_USE_XSHM + if (XSHMHelpers::isShmAvailable (display)) + shmCompletionEvent = X11Symbols::getInstance()->xShmGetEventBase (display) + ShmCompletion; + #endif + + displayVisuals = std::make_unique<DisplayVisuals> (display); + + if (! displayVisuals->isValid()) + { + Logger::outputDebugString ("ERROR: System doesn't support 32, 24 or 16 bit RGB display.\n"); + Process::terminate(); + } + + // Setup input event handler + LinuxEventLoop::registerFdCallback (X11Symbols::getInstance()->xConnectionNumber (display), + [this] (int) + { + do + { + XEvent evt; + + { + XWindowSystemUtilities::ScopedXLock xLock; + + if (! X11Symbols::getInstance()->xPending (display)) + return; + + X11Symbols::getInstance()->xNextEvent (display, &evt); + } + + if (evt.type == SelectionRequest && evt.xany.window == juce_messageWindowHandle + && handleSelectionRequest != nullptr) + { + handleSelectionRequest (evt.xselectionrequest); + } + else if (evt.xany.window != juce_messageWindowHandle + && dispatchWindowMessage != nullptr) + { + dispatchWindowMessage (evt); + } + + } while (display != nullptr); + }); + + return true; +} + +void XWindowSystem::destroyXDisplay() +{ + if (xIsAvailable) + { + jassert (display != nullptr); + + XWindowSystemUtilities::ScopedXLock xLock; + + X11Symbols::getInstance()->xDestroyWindow (display, juce_messageWindowHandle); + juce_messageWindowHandle = 0; + X11Symbols::getInstance()->xSync (display, True); + + LinuxEventLoop::unregisterFdCallback (X11Symbols::getInstance()->xConnectionNumber (display)); + + X11Symbols::getInstance()->xCloseDisplay (display); + display = nullptr; + displayVisuals = nullptr; + } +} + +//============================================================================== +::Window juce_createKeyProxyWindow (ComponentPeer* peer) +{ + return XWindowSystem::getInstance()->createKeyProxy ((::Window) peer->getNativeHandle()); +} + +void juce_deleteKeyProxyWindow (::Window keyProxy) +{ + XWindowSystem::getInstance()->deleteKeyProxy (keyProxy); +} + +//============================================================================== +template <typename EventType> +static Point<float> getLogicalMousePos (const EventType& e, double scaleFactor) noexcept +{ + return Point<float> ((float) e.x, (float) e.y) / scaleFactor; +} + +static int64 getEventTime (::Time t) +{ + static int64 eventTimeOffset = 0x12345678; + auto thisMessageTime = (int64) t; + + if (eventTimeOffset == 0x12345678) + eventTimeOffset = Time::currentTimeMillis() - thisMessageTime; + + return eventTimeOffset + thisMessageTime; +} + +template <typename EventType> +static int64 getEventTime (const EventType& t) +{ + return getEventTime (t.time); +} + +void XWindowSystem::handleWindowMessage (LinuxComponentPeer<::Window>* peer, XEvent& event) const +{ + switch (event.xany.type) + { + case KeyPressEventType: handleKeyPressEvent (peer, event.xkey); break; + case KeyRelease: handleKeyReleaseEvent (peer, event.xkey); break; + case ButtonPress: handleButtonPressEvent (peer, event.xbutton); break; + case ButtonRelease: handleButtonReleaseEvent (peer, event.xbutton); break; + case MotionNotify: handleMotionNotifyEvent (peer, event.xmotion); break; + case EnterNotify: handleEnterNotifyEvent (peer, event.xcrossing); break; + case LeaveNotify: handleLeaveNotifyEvent (peer, event.xcrossing); break; + case FocusIn: handleFocusInEvent (peer); break; + case FocusOut: handleFocusOutEvent (peer); break; + case Expose: handleExposeEvent (peer, event.xexpose); break; + case MappingNotify: handleMappingNotify (event.xmapping); break; + case ClientMessage: handleClientMessageEvent (peer, event.xclient, event); break; + case SelectionNotify: dragAndDropStateMap[peer].handleDragAndDropSelection (event); break; + case ConfigureNotify: handleConfigureNotifyEvent (peer, event.xconfigure); break; + case ReparentNotify: + case GravityNotify: handleGravityNotify (peer); break; + case SelectionClear: dragAndDropStateMap[peer].handleExternalSelectionClear(); break; + case SelectionRequest: dragAndDropStateMap[peer].handleExternalSelectionRequest (event); break; + + case CirculateNotify: + case CreateNotify: + case DestroyNotify: + case UnmapNotify: + break; + + case MapNotify: + peer->handleBroughtToFront(); + break; + + default: + #if JUCE_USE_XSHM + if (XSHMHelpers::isShmAvailable (display)) + { + XWindowSystemUtilities::ScopedXLock xLock; + + if (event.xany.type == shmCompletionEvent) + XWindowSystem::getInstance()->removePendingPaintForWindow ((::Window) peer->getNativeHandle()); + } + #endif + break; + } +} + +void XWindowSystem::handleKeyPressEvent (LinuxComponentPeer<::Window>* peer, XKeyEvent& keyEvent) const +{ + auto oldMods = ModifierKeys::currentModifiers; + + char utf8 [64] = { 0 }; + juce_wchar unicodeChar = 0; + int keyCode = 0; + bool keyDownChange = false; + KeySym sym; + + { + XWindowSystemUtilities::ScopedXLock xLock; + updateKeyStates ((int) keyEvent.keycode, true); + + String oldLocale (::setlocale (LC_ALL, nullptr)); + ::setlocale (LC_ALL, ""); + X11Symbols::getInstance()->xLookupString (&keyEvent, utf8, sizeof (utf8), &sym, nullptr); + + if (oldLocale.isNotEmpty()) + ::setlocale (LC_ALL, oldLocale.toRawUTF8()); + + unicodeChar = *CharPointer_UTF8 (utf8); + keyCode = (int) unicodeChar; + + if (keyCode < 0x20) + keyCode = (int) X11Symbols::getInstance()->xkbKeycodeToKeysym (display, (::KeyCode) keyEvent.keycode, 0, + ModifierKeys::currentModifiers.isShiftDown() ? 1 : 0); + + keyDownChange = (sym != NoSymbol) && ! updateKeyModifiersFromSym (sym, true); + } + + bool keyPressed = false; + + if ((sym & 0xff00) == 0xff00 || keyCode == XK_ISO_Left_Tab) + { + switch (sym) // Translate keypad + { + case XK_KP_Add: keyCode = XK_plus; break; + case XK_KP_Subtract: keyCode = XK_hyphen; break; + case XK_KP_Divide: keyCode = XK_slash; break; + case XK_KP_Multiply: keyCode = XK_asterisk; break; + case XK_KP_Enter: keyCode = XK_Return; break; + case XK_KP_Insert: keyCode = XK_Insert; break; + case XK_Delete: + case XK_KP_Delete: keyCode = XK_Delete; break; + case XK_KP_Left: keyCode = XK_Left; break; + case XK_KP_Right: keyCode = XK_Right; break; + case XK_KP_Up: keyCode = XK_Up; break; + case XK_KP_Down: keyCode = XK_Down; break; + case XK_KP_Home: keyCode = XK_Home; break; + case XK_KP_End: keyCode = XK_End; break; + case XK_KP_Page_Down: keyCode = XK_Page_Down; break; + case XK_KP_Page_Up: keyCode = XK_Page_Up; break; + + case XK_KP_0: keyCode = XK_0; break; + case XK_KP_1: keyCode = XK_1; break; + case XK_KP_2: keyCode = XK_2; break; + case XK_KP_3: keyCode = XK_3; break; + case XK_KP_4: keyCode = XK_4; break; + case XK_KP_5: keyCode = XK_5; break; + case XK_KP_6: keyCode = XK_6; break; + case XK_KP_7: keyCode = XK_7; break; + case XK_KP_8: keyCode = XK_8; break; + case XK_KP_9: keyCode = XK_9; break; + + default: break; + } + + switch (keyCode) + { + case XK_Left: + case XK_Right: + case XK_Up: + case XK_Down: + case XK_Page_Up: + case XK_Page_Down: + case XK_End: + case XK_Home: + case XK_Delete: + case XK_Insert: + keyPressed = true; + keyCode = (keyCode & 0xff) | Keys::extendedKeyModifier; + break; + + case XK_Tab: + case XK_Return: + case XK_Escape: + case XK_BackSpace: + keyPressed = true; + keyCode &= 0xff; + break; + + case XK_ISO_Left_Tab: + keyPressed = true; + keyCode = XK_Tab & 0xff; + break; + + default: + if (sym >= XK_F1 && sym <= XK_F35) + { + keyPressed = true; + keyCode = static_cast<int> ((sym & 0xff) | Keys::extendedKeyModifier); + } + break; + } + } + + if (utf8[0] != 0 || ((sym & 0xff00) == 0 && sym >= 8)) + keyPressed = true; + + if (oldMods != ModifierKeys::currentModifiers) + peer->handleModifierKeysChange(); + + if (keyDownChange) + peer->handleKeyUpOrDown (true); + + if (keyPressed) + peer->handleKeyPress (keyCode, unicodeChar); +} + +void XWindowSystem::handleKeyReleaseEvent (LinuxComponentPeer<::Window>* peer, const XKeyEvent& keyEvent) const +{ + auto isKeyReleasePartOfAutoRepeat = [&]() -> bool + { + if (X11Symbols::getInstance()->xPending (display)) + { + XEvent e; + X11Symbols::getInstance()->xPeekEvent (display, &e); + + // Look for a subsequent key-down event with the same timestamp and keycode + return e.type == KeyPressEventType + && e.xkey.keycode == keyEvent.keycode + && e.xkey.time == keyEvent.time; + } + + return false; + }(); + + if (! isKeyReleasePartOfAutoRepeat) + { + updateKeyStates ((int) keyEvent.keycode, false); + KeySym sym; + + { + XWindowSystemUtilities::ScopedXLock xLock; + sym = X11Symbols::getInstance()->xkbKeycodeToKeysym (display, (::KeyCode) keyEvent.keycode, 0, 0); + } + + auto oldMods = ModifierKeys::currentModifiers; + auto keyDownChange = (sym != NoSymbol) && ! updateKeyModifiersFromSym (sym, false); + + if (oldMods != ModifierKeys::currentModifiers) + peer->handleModifierKeysChange(); + + if (keyDownChange) + peer->handleKeyUpOrDown (false); + } +} + +void XWindowSystem::handleWheelEvent (LinuxComponentPeer<::Window>* peer, const XButtonPressedEvent& buttonPressEvent, float amount) const +{ + MouseWheelDetails wheel; + wheel.deltaX = 0.0f; + wheel.deltaY = amount; + wheel.isReversed = false; + wheel.isSmooth = false; + wheel.isInertial = false; + + peer->handleMouseWheel (MouseInputSource::InputSourceType::mouse, getLogicalMousePos (buttonPressEvent, peer->getPlatformScaleFactor()), + getEventTime (buttonPressEvent), wheel); +} + +void XWindowSystem::handleButtonPressEvent (LinuxComponentPeer<::Window>* peer, const XButtonPressedEvent& buttonPressEvent, int buttonModifierFlag) const +{ + ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withFlags (buttonModifierFlag); + peer->toFront (true); + peer->handleMouseEvent (MouseInputSource::InputSourceType::mouse, getLogicalMousePos (buttonPressEvent, peer->getPlatformScaleFactor()), + ModifierKeys::currentModifiers, MouseInputSource::invalidPressure, + MouseInputSource::invalidOrientation, getEventTime (buttonPressEvent), {}); +} + +void XWindowSystem::handleButtonPressEvent (LinuxComponentPeer<::Window>* peer, const XButtonPressedEvent& buttonPressEvent) const +{ + updateKeyModifiers ((int) buttonPressEvent.state); + + auto mapIndex = (uint32) (buttonPressEvent.button - Button1); + + if (mapIndex < (uint32) numElementsInArray (pointerMap)) + { + switch (pointerMap[mapIndex]) + { + case Keys::WheelUp: handleWheelEvent (peer, buttonPressEvent, 50.0f / 256.0f); break; + case Keys::WheelDown: handleWheelEvent (peer, buttonPressEvent, -50.0f / 256.0f); break; + case Keys::LeftButton: handleButtonPressEvent (peer, buttonPressEvent, ModifierKeys::leftButtonModifier); break; + case Keys::RightButton: handleButtonPressEvent (peer, buttonPressEvent, ModifierKeys::rightButtonModifier); break; + case Keys::MiddleButton: handleButtonPressEvent (peer, buttonPressEvent, ModifierKeys::middleButtonModifier); break; + default: break; + } + } +} + +void XWindowSystem::handleButtonReleaseEvent (LinuxComponentPeer<::Window>* peer, const XButtonReleasedEvent& buttonRelEvent) const +{ + updateKeyModifiers ((int) buttonRelEvent.state); + + if (peer->getParentWindow() != 0) + peer->updateWindowBounds(); + + auto mapIndex = (uint32) (buttonRelEvent.button - Button1); + + if (mapIndex < (uint32) numElementsInArray (pointerMap)) + { + switch (pointerMap[mapIndex]) + { + case Keys::LeftButton: ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withoutFlags (ModifierKeys::leftButtonModifier); break; + case Keys::RightButton: ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withoutFlags (ModifierKeys::rightButtonModifier); break; + case Keys::MiddleButton: ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withoutFlags (ModifierKeys::middleButtonModifier); break; + default: break; + } + } + + auto& dragState = dragAndDropStateMap[peer]; + + if (dragState.isDragging()) + dragState.handleExternalDragButtonReleaseEvent(); + + peer->handleMouseEvent (MouseInputSource::InputSourceType::mouse, getLogicalMousePos (buttonRelEvent, peer->getPlatformScaleFactor()), + ModifierKeys::currentModifiers, MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, getEventTime (buttonRelEvent)); +} + +void XWindowSystem::handleMotionNotifyEvent (LinuxComponentPeer<::Window>* peer, const XPointerMovedEvent& movedEvent) const +{ + updateKeyModifiers ((int) movedEvent.state); + + auto& dragState = dragAndDropStateMap[peer]; + + if (dragState.isDragging()) + dragState.handleExternalDragMotionNotify(); + + peer->handleMouseEvent (MouseInputSource::InputSourceType::mouse, getLogicalMousePos (movedEvent, peer->getPlatformScaleFactor()), + ModifierKeys::currentModifiers, MouseInputSource::invalidPressure, + MouseInputSource::invalidOrientation, getEventTime (movedEvent)); +} + +void XWindowSystem::handleEnterNotifyEvent (LinuxComponentPeer<::Window>* peer, const XEnterWindowEvent& enterEvent) const +{ + if (peer->getParentWindow() != 0) + peer->updateWindowBounds(); + + if (! ModifierKeys::currentModifiers.isAnyMouseButtonDown()) + { + updateKeyModifiers ((int) enterEvent.state); + peer->handleMouseEvent (MouseInputSource::InputSourceType::mouse, getLogicalMousePos (enterEvent, peer->getPlatformScaleFactor()), + ModifierKeys::currentModifiers, MouseInputSource::invalidPressure, + MouseInputSource::invalidOrientation, getEventTime (enterEvent)); + } +} + +void XWindowSystem::handleLeaveNotifyEvent (LinuxComponentPeer<::Window>* peer, const XLeaveWindowEvent& leaveEvent) const +{ + // Suppress the normal leave if we've got a pointer grab, or if + // it's a bogus one caused by clicking a mouse button when running + // in a Window manager + if (((! ModifierKeys::currentModifiers.isAnyMouseButtonDown()) && leaveEvent.mode == NotifyNormal) + || leaveEvent.mode == NotifyUngrab) + { + updateKeyModifiers ((int) leaveEvent.state); + peer->handleMouseEvent (MouseInputSource::InputSourceType::mouse, getLogicalMousePos (leaveEvent, peer->getPlatformScaleFactor()), + ModifierKeys::currentModifiers, MouseInputSource::invalidPressure, + MouseInputSource::invalidOrientation, getEventTime (leaveEvent)); + } +} + +void XWindowSystem::handleFocusInEvent (LinuxComponentPeer<::Window>* peer) const +{ + peer->isActiveApplication = true; + + if (isFocused ((::Window) peer->getNativeHandle()) && ! peer->focused) + { + peer->focused = true; + peer->handleFocusGain(); + } +} + +void XWindowSystem::handleFocusOutEvent (LinuxComponentPeer<::Window>* peer) const +{ + if (! isFocused ((::Window) peer->getNativeHandle()) && peer->focused) + { + peer->focused = false; + peer->isActiveApplication = false; + + peer->handleFocusLoss(); + } +} + +void XWindowSystem::handleExposeEvent (LinuxComponentPeer<::Window>* peer, XExposeEvent& exposeEvent) const +{ + // Batch together all pending expose events + XEvent nextEvent; + XWindowSystemUtilities::ScopedXLock xLock; + + // if we have opengl contexts then just repaint them all + // regardless if this is really necessary + peer->repaintOpenGLContexts(); + + auto windowH = (::Window) peer->getNativeHandle(); + + if (exposeEvent.window != windowH) + { + Window child; + X11Symbols::getInstance()->xTranslateCoordinates (display, exposeEvent.window, windowH, + exposeEvent.x, exposeEvent.y, &exposeEvent.x, &exposeEvent.y, + &child); + } + + // exposeEvent is in local window local coordinates so do not convert with + // physicalToScaled, but rather use currentScaleFactor + auto currentScaleFactor = peer->getPlatformScaleFactor(); + + peer->repaint (Rectangle<int> (exposeEvent.x, exposeEvent.y, + exposeEvent.width, exposeEvent.height) / currentScaleFactor); + + while (X11Symbols::getInstance()->xEventsQueued (display, QueuedAfterFlush) > 0) + { + X11Symbols::getInstance()->xPeekEvent (display, &nextEvent); + + if (nextEvent.type != Expose || nextEvent.xany.window != exposeEvent.window) + break; + + X11Symbols::getInstance()->xNextEvent (display, &nextEvent); + auto& nextExposeEvent = (XExposeEvent&) nextEvent.xexpose; + + peer->repaint (Rectangle<int> (nextExposeEvent.x, nextExposeEvent.y, + nextExposeEvent.width, nextExposeEvent.height) / currentScaleFactor); + } +} + +void XWindowSystem::handleConfigureNotifyEvent (LinuxComponentPeer<::Window>* peer, XConfigureEvent& confEvent) const +{ + peer->updateWindowBounds(); + peer->updateBorderSize(); + peer->handleMovedOrResized(); + + // if the native title bar is dragged, need to tell any active menus, etc. + if ((peer->getStyleFlags() & ComponentPeer::windowHasTitleBar) != 0 + && peer->getComponent().isCurrentlyBlockedByAnotherModalComponent()) + { + if (auto* currentModalComp = Component::getCurrentlyModalComponent()) + currentModalComp->inputAttemptWhenModal(); + } + + auto windowH = (::Window) peer->getNativeHandle(); + + if (confEvent.window == windowH && confEvent.above != 0 && isFrontWindow (windowH)) + peer->handleBroughtToFront(); +} + +void XWindowSystem::handleGravityNotify (LinuxComponentPeer<::Window>* peer) const +{ + peer->updateWindowBounds(); + peer->updateBorderSize(); + peer->handleMovedOrResized(); +} + +void XWindowSystem::handleMappingNotify (XMappingEvent& mappingEvent) const +{ + if (mappingEvent.request != MappingPointer) + { + // Deal with modifier/keyboard mapping + XWindowSystemUtilities::ScopedXLock xLock; + X11Symbols::getInstance()->xRefreshKeyboardMapping (&mappingEvent); + updateModifierMappings(); + } +} + +void XWindowSystem::handleClientMessageEvent (LinuxComponentPeer<::Window>* peer, XClientMessageEvent& clientMsg, XEvent& event) const +{ + if (clientMsg.message_type == atoms.protocols && clientMsg.format == 32) + { + auto atom = (Atom) clientMsg.data.l[0]; + + if (atom == atoms.protocolList [XWindowSystemUtilities::Atoms::PING]) + { + auto root = X11Symbols::getInstance()->xRootWindow (display, X11Symbols::getInstance()->xDefaultScreen (display)); + + clientMsg.window = root; + + X11Symbols::getInstance()->xSendEvent (display, root, False, NoEventMask, &event); + X11Symbols::getInstance()->xFlush (display); + } + else if (atom == atoms.protocolList [XWindowSystemUtilities::Atoms::TAKE_FOCUS]) + { + if ((peer->getStyleFlags() & ComponentPeer::windowIgnoresKeyPresses) == 0) + { + XWindowAttributes atts; + + XWindowSystemUtilities::ScopedXLock xLock; + if (clientMsg.window != 0 + && X11Symbols::getInstance()->xGetWindowAttributes (display, clientMsg.window, &atts)) + { + if (atts.map_state == IsViewable) + { + auto windowH = (::Window) peer->getNativeHandle(); + + X11Symbols::getInstance()->xSetInputFocus (display, (clientMsg.window == windowH ? getFocusWindow (windowH) + : clientMsg.window), + RevertToParent, (::Time) clientMsg.data.l[1]); + } + } + } + } + else if (atom == atoms.protocolList [XWindowSystemUtilities::Atoms::DELETE_WINDOW]) + { + peer->handleUserClosingWindow(); + } + } + else if (clientMsg.message_type == atoms.XdndEnter) + { + dragAndDropStateMap[peer].handleDragAndDropEnter (clientMsg, peer); + } + else if (clientMsg.message_type == atoms.XdndLeave) + { + dragAndDropStateMap[peer].handleDragAndDropExit(); + dragAndDropStateMap.erase (peer); + } + else if (clientMsg.message_type == atoms.XdndPosition) + { + dragAndDropStateMap[peer].handleDragAndDropPosition (clientMsg, peer); + } + else if (clientMsg.message_type == atoms.XdndDrop) + { + dragAndDropStateMap[peer].handleDragAndDropDrop (clientMsg, peer); + } + else if (clientMsg.message_type == atoms.XdndStatus) + { + dragAndDropStateMap[peer].handleExternalDragAndDropStatus (clientMsg); + } + else if (clientMsg.message_type == atoms.XdndFinished) + { + dragAndDropStateMap[peer].externalResetDragAndDrop(); + } + else if (clientMsg.message_type == atoms.XembedMsgType && clientMsg.format == 32) + { + handleXEmbedMessage (peer, clientMsg); + } +} + +void XWindowSystem::handleXEmbedMessage (LinuxComponentPeer<::Window>* peer, XClientMessageEvent& clientMsg) const +{ + switch (clientMsg.data.l[1]) + { + case 0: // XEMBED_EMBEDDED_NOTIFY + peer->setParentWindow ((::Window) clientMsg.data.l[3]); + peer->updateWindowBounds(); + peer->getComponent().setBounds (peer->getBounds()); + break; + case 4: // XEMBED_FOCUS_IN + handleFocusInEvent (peer); + break; + case 5: // XEMBED_FOCUS_OUT + handleFocusOutEvent (peer); + break; + + default: + break; + } +} + +//============================================================================== +namespace WindowingHelpers +{ + static void windowMessageReceive (XEvent& event) + { + if (event.xany.window != None) + { + #if JUCE_X11_SUPPORTS_XEMBED + if (! juce_handleXEmbedEvent (nullptr, &event)) + #endif + { + if (auto* peer = dynamic_cast<LinuxComponentPeer<::Window>*> (getPeerFor (event.xany.window))) + XWindowSystem::getInstance()->handleWindowMessage (peer, event); + } + } + else if (event.xany.type == KeymapNotify) + { + auto& keymapEvent = (const XKeymapEvent&) event.xkeymap; + memcpy (Keys::keyStates, keymapEvent.key_vector, 32); + } + } +} + +struct WindowingCallbackInitialiser +{ + WindowingCallbackInitialiser() + { + dispatchWindowMessage = WindowingHelpers::windowMessageReceive; + } +}; + +static WindowingCallbackInitialiser windowingInitialiser; + + +JUCE_IMPLEMENT_SINGLETON (XWindowSystem) + +} // namespace juce diff --git a/modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.h b/modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.h new file mode 100644 index 00000000..7d20959e --- /dev/null +++ b/modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.h @@ -0,0 +1,257 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ + +//============================================================================== +namespace XWindowSystemUtilities +{ + //============================================================================== + /** A handy struct that uses XLockDisplay and XUnlockDisplay to lock the X server + using RAII. + + @tags{GUI} + */ + struct ScopedXLock + { + ScopedXLock(); + ~ScopedXLock(); + }; + + //============================================================================== + /** Gets a specified window property and stores its associated data, freeing it + on deletion. + + @tags{GUI} + */ + struct GetXProperty + { + GetXProperty (::Window windowH, Atom property, long offset, + long length, bool shouldDelete, Atom requestedType); + ~GetXProperty(); + + bool success = false; + unsigned char* data = nullptr; + unsigned long numItems = 0, bytesLeft = 0; + Atom actualType; + int actualFormat = -1; + }; + + //============================================================================== + /** Initialises and stores some atoms for the display. + + @tags{GUI} + */ + struct Atoms + { + enum ProtocolItems + { + TAKE_FOCUS = 0, + DELETE_WINDOW = 1, + PING = 2 + }; + + Atoms() = default; + explicit Atoms (::Display*); + + static Atom getIfExists (::Display*, const char* name); + static Atom getCreating (::Display*, const char* name); + + static String getName (::Display*, Atom); + static bool isMimeTypeFile (::Display*, Atom); + + static constexpr unsigned long DndVersion = 3; + + Atom protocols, protocolList[3], changeState, state, userTime, activeWin, pid, windowType, windowState, + XdndAware, XdndEnter, XdndLeave, XdndPosition, XdndStatus, XdndDrop, XdndFinished, XdndSelection, + XdndTypeList, XdndActionList, XdndActionDescription, XdndActionCopy, XdndActionPrivate, + XembedMsgType, XembedInfo, allowedActions[5], allowedMimeTypes[4], utf8String, clipboard, targets; + }; +} + +//============================================================================== +template<typename WindowHandle> +class LinuxComponentPeer; + +class XWindowSystem : public DeletedAtShutdown +{ +public: + //============================================================================== + ::Window createWindow (::Window parentWindow, LinuxComponentPeer<::Window>* peer) const; + void destroyWindow (::Window windowH); + + void setTitle (::Window windowH, const String& title) const; + void setIcon (::Window windowH, const Image& newIcon) const; + void setVisible (::Window windowH, bool shouldBeVisible) const; + void setBounds (::Window windowH, Rectangle<int> newBounds, bool fullScreen) const; + + BorderSize<int> getBorderSize (::Window windowH) const; + Rectangle<int> getWindowBounds (::Window windowH, ::Window parentWindow); + Point<int> getParentScreenPosition() const; + + bool contains (::Window windowH, Point<int> localPos) const; + + void setMinimised (::Window windowH, bool shouldBeMinimised) const; + bool isMinimised (::Window windowH) const; + + void toFront (::Window windowH, bool makeActive) const; + void toBehind (::Window windowH, ::Window otherWindow) const; + + bool isFocused (::Window windowH) const; + bool grabFocus (::Window windowH) const; + + bool canUseSemiTransparentWindows() const; + bool canUseARGBImages() const; + + int getNumPaintsPendingForWindow (::Window windowH); + void processPendingPaintsForWindow (::Window windowH); + void addPendingPaintForWindow (::Window windowH); + void removePendingPaintForWindow (::Window windowH); + + Image createImage (bool isSemiTransparentWindow, int width, int height, bool argb) const; + void blitToWindow (::Window windowH, Image image, Rectangle<int> destinationRect, Rectangle<int> totalRect) const; + + void setScreenSaverEnabled (bool enabled) const; + + Point<float> getCurrentMousePosition() const; + void setMousePosition (Point<float> pos) const; + + void* createCustomMouseCursorInfo (const Image& image, Point<int> hotspot) const; + void deleteMouseCursor (void* cursorHandle) const; + void* createStandardMouseCursor (MouseCursor::StandardCursorType type) const; + void showCursor (::Window windowH, void* cursorHandle) const; + + bool isKeyCurrentlyDown (int keyCode) const; + ModifierKeys getNativeRealtimeModifiers() const; + + Array<Displays::Display> findDisplays (float masterScale) const; + + ::Window createKeyProxy (::Window windowH) const; + void deleteKeyProxy (::Window keyProxy) const; + + bool externalDragFileInit (LinuxComponentPeer<::Window>* peer, const StringArray& files, bool canMove, std::function<void()>&& callback) const; + bool externalDragTextInit (LinuxComponentPeer<::Window>* peer, const String& text, std::function<void()>&& callback) const; + + void copyTextToClipboard (const String& clipText); + String getTextFromClipboard() const; + + String getLocalClipboardContent() const { return localClipboardContent; } + + ::Display* getDisplay() { return display; } + XWindowSystemUtilities::Atoms& getAtoms() { return atoms; } + + //============================================================================== + void handleWindowMessage (LinuxComponentPeer<::Window>* peer, XEvent& event) const; + + //============================================================================== + JUCE_DECLARE_SINGLETON (XWindowSystem, false) + +private: + XWindowSystem(); + ~XWindowSystem(); + + //============================================================================== + struct VisualAndDepth + { + Visual* visual; + int depth; + }; + + struct DisplayVisuals + { + explicit DisplayVisuals (::Display* d); + + VisualAndDepth getBestVisualForWindow (bool isSemiTransparent) const; + bool isValid() const noexcept; + + Visual* visual16Bit = nullptr; + Visual* visual24Bit = nullptr; + Visual* visual32Bit = nullptr; + }; + + bool initialiseXDisplay(); + void destroyXDisplay(); + + //============================================================================== + ::Window getFocusWindow (::Window windowH) const; + + bool isParentWindowOf (::Window windowH, ::Window possibleChild) const; + bool isFrontWindow (::Window windowH) const; + + //============================================================================== + void xchangeProperty (::Window windowH, Atom property, Atom type, int format, const void* data, int numElements) const; + + void removeWindowDecorations (::Window windowH) const; + void addWindowButtons (::Window windowH, int styleFlags) const; + void setWindowType (::Window windowH, int styleFlags) const; + + void initialisePointerMap(); + void deleteIconPixmaps (::Window windowH) const; + void updateModifierMappings() const; + + long getUserTime (::Window windowH) const; + + //============================================================================== + void handleKeyPressEvent (LinuxComponentPeer<::Window>*, XKeyEvent&) const; + void handleKeyReleaseEvent (LinuxComponentPeer<::Window>*, const XKeyEvent&) const; + void handleWheelEvent (LinuxComponentPeer<::Window>*, const XButtonPressedEvent&, float) const; + void handleButtonPressEvent (LinuxComponentPeer<::Window>*, const XButtonPressedEvent&, int) const; + void handleButtonPressEvent (LinuxComponentPeer<::Window>*, const XButtonPressedEvent&) const; + void handleButtonReleaseEvent (LinuxComponentPeer<::Window>*, const XButtonReleasedEvent&) const; + void handleMotionNotifyEvent (LinuxComponentPeer<::Window>*, const XPointerMovedEvent&) const; + void handleEnterNotifyEvent (LinuxComponentPeer<::Window>*, const XEnterWindowEvent&) const; + void handleLeaveNotifyEvent (LinuxComponentPeer<::Window>*, const XLeaveWindowEvent&) const; + void handleFocusInEvent (LinuxComponentPeer<::Window>*) const; + void handleFocusOutEvent (LinuxComponentPeer<::Window>*) const; + void handleExposeEvent (LinuxComponentPeer<::Window>*, XExposeEvent&) const; + void handleConfigureNotifyEvent (LinuxComponentPeer<::Window>*, XConfigureEvent&) const; + void handleGravityNotify (LinuxComponentPeer<::Window>*) const; + void handleMappingNotify (XMappingEvent&) const; + void handleClientMessageEvent (LinuxComponentPeer<::Window>*, XClientMessageEvent&, XEvent&) const; + void handleXEmbedMessage (LinuxComponentPeer<::Window>*, XClientMessageEvent&) const; + + //============================================================================== + bool xIsAvailable = false; + + XWindowSystemUtilities::Atoms atoms; + ::Display* display = nullptr; + std::unique_ptr<DisplayVisuals> displayVisuals; + + #if JUCE_USE_XSHM + std::map<::Window, int> shmPaintsPendingMap; + #endif + + int shmCompletionEvent = 0; + int pointerMap[5] = {}; + String localClipboardContent; + + Point<int> parentScreenPosition; + + //============================================================================== + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (XWindowSystem) +}; + +} // namespace juce diff --git a/modules/juce_gui_basics/positioning/juce_MarkerList.cpp b/modules/juce_gui_basics/positioning/juce_MarkerList.cpp index b5b83253..1436bd74 100644 --- a/modules/juce_gui_basics/positioning/juce_MarkerList.cpp +++ b/modules/juce_gui_basics/positioning/juce_MarkerList.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/positioning/juce_MarkerList.h b/modules/juce_gui_basics/positioning/juce_MarkerList.h index 57debbfa..4f6f029b 100644 --- a/modules/juce_gui_basics/positioning/juce_MarkerList.h +++ b/modules/juce_gui_basics/positioning/juce_MarkerList.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/positioning/juce_RelativeCoordinate.cpp b/modules/juce_gui_basics/positioning/juce_RelativeCoordinate.cpp index d7a17910..50637355 100644 --- a/modules/juce_gui_basics/positioning/juce_RelativeCoordinate.cpp +++ b/modules/juce_gui_basics/positioning/juce_RelativeCoordinate.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/positioning/juce_RelativeCoordinate.h b/modules/juce_gui_basics/positioning/juce_RelativeCoordinate.h index 176f6eba..173ac41c 100644 --- a/modules/juce_gui_basics/positioning/juce_RelativeCoordinate.h +++ b/modules/juce_gui_basics/positioning/juce_RelativeCoordinate.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.cpp b/modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.cpp index aacb50bd..1293d643 100644 --- a/modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.cpp +++ b/modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -33,12 +32,10 @@ struct MarkerListScope : public Expression::Scope Expression getSymbolValue (const String& symbol) const override { - switch (RelativeCoordinate::StandardStrings::getTypeOf (symbol)) - { - case RelativeCoordinate::StandardStrings::width: return Expression ((double) component.getWidth()); - case RelativeCoordinate::StandardStrings::height: return Expression ((double) component.getHeight()); - default: break; - } + auto type = RelativeCoordinate::StandardStrings::getTypeOf (symbol); + + if (type == RelativeCoordinate::StandardStrings::width) return Expression ((double) component.getWidth()); + if (type == RelativeCoordinate::StandardStrings::height) return Expression ((double) component.getHeight()); MarkerList* list; @@ -116,6 +113,8 @@ Expression RelativeCoordinatePositionerBase::ComponentScope::getSymbolValue (con case RelativeCoordinate::StandardStrings::height: return Expression ((double) component.getHeight()); case RelativeCoordinate::StandardStrings::right: return Expression ((double) component.getRight()); case RelativeCoordinate::StandardStrings::bottom: return Expression ((double) component.getBottom()); + case RelativeCoordinate::StandardStrings::parent: + case RelativeCoordinate::StandardStrings::unknown: default: break; } @@ -180,6 +179,8 @@ public: positioner.registerComponentListener (component); break; + case RelativeCoordinate::StandardStrings::parent: + case RelativeCoordinate::StandardStrings::unknown: default: if (auto* parent = component.getParentComponent()) { diff --git a/modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.h b/modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.h index 517519be..65a86e3b 100644 --- a/modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.h +++ b/modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/positioning/juce_RelativeParallelogram.cpp b/modules/juce_gui_basics/positioning/juce_RelativeParallelogram.cpp index 0f48090b..ded1936f 100644 --- a/modules/juce_gui_basics/positioning/juce_RelativeParallelogram.cpp +++ b/modules/juce_gui_basics/positioning/juce_RelativeParallelogram.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/positioning/juce_RelativeParallelogram.h b/modules/juce_gui_basics/positioning/juce_RelativeParallelogram.h index 7ba3b383..74a237aa 100644 --- a/modules/juce_gui_basics/positioning/juce_RelativeParallelogram.h +++ b/modules/juce_gui_basics/positioning/juce_RelativeParallelogram.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/positioning/juce_RelativePoint.cpp b/modules/juce_gui_basics/positioning/juce_RelativePoint.cpp index 51895b29..1fa8f4f7 100644 --- a/modules/juce_gui_basics/positioning/juce_RelativePoint.cpp +++ b/modules/juce_gui_basics/positioning/juce_RelativePoint.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/positioning/juce_RelativePoint.h b/modules/juce_gui_basics/positioning/juce_RelativePoint.h index b6da5b2d..7fb0b24c 100644 --- a/modules/juce_gui_basics/positioning/juce_RelativePoint.h +++ b/modules/juce_gui_basics/positioning/juce_RelativePoint.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/positioning/juce_RelativePointPath.cpp b/modules/juce_gui_basics/positioning/juce_RelativePointPath.cpp index ce08c876..93fadc5f 100644 --- a/modules/juce_gui_basics/positioning/juce_RelativePointPath.cpp +++ b/modules/juce_gui_basics/positioning/juce_RelativePointPath.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/positioning/juce_RelativePointPath.h b/modules/juce_gui_basics/positioning/juce_RelativePointPath.h index 83a5b4b7..72f1333b 100644 --- a/modules/juce_gui_basics/positioning/juce_RelativePointPath.h +++ b/modules/juce_gui_basics/positioning/juce_RelativePointPath.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/positioning/juce_RelativeRectangle.cpp b/modules/juce_gui_basics/positioning/juce_RelativeRectangle.cpp index 574be976..ac482ed6 100644 --- a/modules/juce_gui_basics/positioning/juce_RelativeRectangle.cpp +++ b/modules/juce_gui_basics/positioning/juce_RelativeRectangle.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -52,6 +51,11 @@ namespace RelativeRectangleHelpers case RelativeCoordinate::StandardStrings::right: case RelativeCoordinate::StandardStrings::top: case RelativeCoordinate::StandardStrings::bottom: return false; + case RelativeCoordinate::StandardStrings::width: + case RelativeCoordinate::StandardStrings::height: + case RelativeCoordinate::StandardStrings::parent: + case RelativeCoordinate::StandardStrings::unknown: + default: break; } @@ -127,6 +131,10 @@ public: case RelativeCoordinate::StandardStrings::top: return rect.top.getExpression(); case RelativeCoordinate::StandardStrings::right: return rect.right.getExpression(); case RelativeCoordinate::StandardStrings::bottom: return rect.bottom.getExpression(); + case RelativeCoordinate::StandardStrings::width: + case RelativeCoordinate::StandardStrings::height: + case RelativeCoordinate::StandardStrings::parent: + case RelativeCoordinate::StandardStrings::unknown: default: break; } diff --git a/modules/juce_gui_basics/positioning/juce_RelativeRectangle.h b/modules/juce_gui_basics/positioning/juce_RelativeRectangle.h index 08db47fc..b659d146 100644 --- a/modules/juce_gui_basics/positioning/juce_RelativeRectangle.h +++ b/modules/juce_gui_basics/positioning/juce_RelativeRectangle.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/properties/juce_BooleanPropertyComponent.cpp b/modules/juce_gui_basics/properties/juce_BooleanPropertyComponent.cpp index 92a07639..026e9aa4 100644 --- a/modules/juce_gui_basics/properties/juce_BooleanPropertyComponent.cpp +++ b/modules/juce_gui_basics/properties/juce_BooleanPropertyComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/properties/juce_BooleanPropertyComponent.h b/modules/juce_gui_basics/properties/juce_BooleanPropertyComponent.h index a66c0595..1b5721c0 100644 --- a/modules/juce_gui_basics/properties/juce_BooleanPropertyComponent.h +++ b/modules/juce_gui_basics/properties/juce_BooleanPropertyComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.cpp b/modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.cpp index f898d931..55473ea0 100644 --- a/modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.cpp +++ b/modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.h b/modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.h index 6228cfa7..c650f015 100644 --- a/modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.h +++ b/modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.cpp b/modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.cpp index 0e4705a8..6187f2eb 100644 --- a/modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.cpp +++ b/modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.h b/modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.h index 2a06266c..93cb8bbf 100644 --- a/modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.h +++ b/modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/properties/juce_MultiChoicePropertyComponent.cpp b/modules/juce_gui_basics/properties/juce_MultiChoicePropertyComponent.cpp index 35f5ab52..d0a2785f 100644 --- a/modules/juce_gui_basics/properties/juce_MultiChoicePropertyComponent.cpp +++ b/modules/juce_gui_basics/properties/juce_MultiChoicePropertyComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -43,7 +42,7 @@ public: } }; -void updateButtonTickColour (ToggleButton* button, bool usingDefault) +static void updateButtonTickColour (ToggleButton* button, bool usingDefault) { button->setColour (ToggleButton::tickColourId, button->getLookAndFeel().findColour (ToggleButton::tickColourId) .withAlpha (usingDefault ? 0.4f : 1.0f)); @@ -208,32 +207,43 @@ private: }; //============================================================================== +int MultiChoicePropertyComponent::getTotalButtonsHeight (int numButtons) +{ + return numButtons * buttonHeight + 1; +} + MultiChoicePropertyComponent::MultiChoicePropertyComponent (const String& propertyName, const StringArray& choices, const Array<var>& correspondingValues) - : PropertyComponent (propertyName, 70) +: PropertyComponent (propertyName, jmin (getTotalButtonsHeight (choices.size()), collapsedHeight)) { // The array of corresponding values must contain one value for each of the items in // the choices array! jassert (choices.size() == correspondingValues.size()); - ignoreUnused (correspondingValues); for (auto choice : choices) addAndMakeVisible (choiceButtons.add (new ToggleButton (choice))); - maxHeight = (choiceButtons.size() * 25) + 20; - + if (preferredHeight >= collapsedHeight) { - Path expandShape; - expandShape.addTriangle ({ 0, 0 }, { 5, 10 }, { 10, 0}); - expandButton.setShape (expandShape, true, true, false); + expandable = true; + maxHeight = getTotalButtonsHeight (choiceButtons.size()) + expandAreaHeight; } - expandButton.onClick = [this] { setExpanded (! expanded); }; - addAndMakeVisible (expandButton); + if (isExpandable()) + { + { + Path expandShape; + expandShape.addTriangle ({ 0, 0 }, { 5, 10 }, { 10, 0}); + expandButton.setShape (expandShape, true, true, false); + } + + expandButton.onClick = [this] { setExpanded (! expanded); }; + addAndMakeVisible (expandButton); - lookAndFeelChanged(); + lookAndFeelChanged(); + } } MultiChoicePropertyComponent::MultiChoicePropertyComponent (const Value& valueToControl, @@ -284,11 +294,11 @@ void MultiChoicePropertyComponent::paint (Graphics& g) g.setColour (findColour (TextEditor::backgroundColourId)); g.fillRect (getLookAndFeel().getPropertyComponentContentPosition (*this)); - if (! expanded) + if (isExpandable() && ! isExpanded()) { g.setColour (findColour (TextEditor::backgroundColourId).contrasting().withAlpha (0.4f)); g.drawFittedText ("+ " + String (numHidden) + " more", getLookAndFeel().getPropertyComponentContentPosition (*this) - .removeFromBottom (20).withTrimmedLeft (10), + .removeFromBottom (expandAreaHeight).withTrimmedLeft (10), Justification::centredLeft, 1); } @@ -299,20 +309,23 @@ void MultiChoicePropertyComponent::resized() { auto bounds = getLookAndFeel().getPropertyComponentContentPosition (*this); - bounds.removeFromBottom (5); + if (isExpandable()) + { + bounds.removeFromBottom (5); - auto buttonSlice = bounds.removeFromBottom (10); - expandButton.setSize (10, 10); - expandButton.setCentrePosition (buttonSlice.getCentre()); + auto buttonSlice = bounds.removeFromBottom (10); + expandButton.setSize (10, 10); + expandButton.setCentrePosition (buttonSlice.getCentre()); + } numHidden = 0; for (auto* b : choiceButtons) { - if (bounds.getHeight() >= 25) + if (bounds.getHeight() >= buttonHeight) { b->setVisible (true); - b->setBounds (bounds.removeFromTop (25).reduced (5, 2)); + b->setBounds (bounds.removeFromTop (buttonHeight).reduced (5, 2)); } else { @@ -322,13 +335,13 @@ void MultiChoicePropertyComponent::resized() } } -void MultiChoicePropertyComponent::setExpanded (bool isExpanded) noexcept +void MultiChoicePropertyComponent::setExpanded (bool shouldBeExpanded) noexcept { - if (expanded == isExpanded) + if (! isExpandable() || (isExpanded() == shouldBeExpanded)) return; - expanded = isExpanded; - preferredHeight = expanded ? maxHeight : 70; + expanded = shouldBeExpanded; + preferredHeight = expanded ? maxHeight : collapsedHeight; if (auto* propertyPanel = findParentComponentOfClass<PropertyPanel>()) propertyPanel->resized(); diff --git a/modules/juce_gui_basics/properties/juce_MultiChoicePropertyComponent.h b/modules/juce_gui_basics/properties/juce_MultiChoicePropertyComponent.h index b3eeaceb..168ad9b6 100644 --- a/modules/juce_gui_basics/properties/juce_MultiChoicePropertyComponent.h +++ b/modules/juce_gui_basics/properties/juce_MultiChoicePropertyComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -88,7 +87,10 @@ public: /** Returns true if the list of options is expanded. */ bool isExpanded() const noexcept { return expanded; } - /** Expands or shrinks the list of options. + /** Returns true if the list of options has been truncated and can be expanded. */ + bool isExpandable() const noexcept { return expandable; } + + /** Expands or shrinks the list of options if they are not all visible. N.B. This will just set the preferredHeight value of the PropertyComponent and attempt to call PropertyPanel::resized(), so if you are not displaying this object in a PropertyPanel @@ -115,14 +117,18 @@ private: class MultiChoiceRemapperSourceWithDefault; //============================================================================== + static int getTotalButtonsHeight (int); void lookAndFeelChanged() override; //============================================================================== WeakReference<ValueWithDefault> valueWithDefault; - int maxHeight = 0; - int numHidden = 0; - bool expanded = false; + static constexpr int collapsedHeight = 125; + static constexpr int buttonHeight = 25; + static constexpr int expandAreaHeight = 20; + + int maxHeight = 0, numHidden = 0; + bool expandable = false, expanded = false; OwnedArray<ToggleButton> choiceButtons; ShapeButton expandButton { "Expand", Colours::transparentBlack, Colours::transparentBlack, Colours::transparentBlack }; diff --git a/modules/juce_gui_basics/properties/juce_PropertyComponent.cpp b/modules/juce_gui_basics/properties/juce_PropertyComponent.cpp index 54419a95..fd82089a 100644 --- a/modules/juce_gui_basics/properties/juce_PropertyComponent.cpp +++ b/modules/juce_gui_basics/properties/juce_PropertyComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/properties/juce_PropertyComponent.h b/modules/juce_gui_basics/properties/juce_PropertyComponent.h index 55e5e25f..c9e035ce 100644 --- a/modules/juce_gui_basics/properties/juce_PropertyComponent.h +++ b/modules/juce_gui_basics/properties/juce_PropertyComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/properties/juce_PropertyPanel.cpp b/modules/juce_gui_basics/properties/juce_PropertyPanel.cpp index e72e8058..aee1c82e 100644 --- a/modules/juce_gui_basics/properties/juce_PropertyPanel.cpp +++ b/modules/juce_gui_basics/properties/juce_PropertyPanel.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -33,9 +32,10 @@ struct PropertyPanel::SectionComponent : public Component const Array<PropertyComponent*>& newProperties, bool sectionIsOpen) : Component (sectionTitle), - titleHeight (getLookAndFeel().getPropertyPanelSectionHeaderHeight (sectionTitle)), isOpen (sectionIsOpen) { + lookAndFeelChanged(); + propertyComps.addArray (newProperties); for (auto* propertyComponent : propertyComps) @@ -67,6 +67,13 @@ struct PropertyPanel::SectionComponent : public Component } } + void lookAndFeelChanged() override + { + titleHeight = getLookAndFeel().getPropertyPanelSectionHeaderHeight (getName()); + resized(); + repaint(); + } + int getPreferredHeight() const { auto y = titleHeight; diff --git a/modules/juce_gui_basics/properties/juce_PropertyPanel.h b/modules/juce_gui_basics/properties/juce_PropertyPanel.h index eeda9c5d..94bafef8 100644 --- a/modules/juce_gui_basics/properties/juce_PropertyPanel.h +++ b/modules/juce_gui_basics/properties/juce_PropertyPanel.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/properties/juce_SliderPropertyComponent.cpp b/modules/juce_gui_basics/properties/juce_SliderPropertyComponent.cpp index a623cd56..9371e9e2 100644 --- a/modules/juce_gui_basics/properties/juce_SliderPropertyComponent.cpp +++ b/modules/juce_gui_basics/properties/juce_SliderPropertyComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/properties/juce_SliderPropertyComponent.h b/modules/juce_gui_basics/properties/juce_SliderPropertyComponent.h index 31fa228e..be13018e 100644 --- a/modules/juce_gui_basics/properties/juce_SliderPropertyComponent.h +++ b/modules/juce_gui_basics/properties/juce_SliderPropertyComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/properties/juce_TextPropertyComponent.cpp b/modules/juce_gui_basics/properties/juce_TextPropertyComponent.cpp index b1bd6542..fdc99d91 100644 --- a/modules/juce_gui_basics/properties/juce_TextPropertyComponent.cpp +++ b/modules/juce_gui_basics/properties/juce_TextPropertyComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -104,7 +103,7 @@ public: g.setFont (labelFont); g.drawFittedText (textToDisplayWhenEmpty, textArea, getJustificationType(), - jmax (1, (int) (textArea.getHeight() / labelFont.getHeight())), + jmax (1, (int) ((float) textArea.getHeight() / labelFont.getHeight())), getMinimumHorizontalScale()); } } diff --git a/modules/juce_gui_basics/properties/juce_TextPropertyComponent.h b/modules/juce_gui_basics/properties/juce_TextPropertyComponent.h index 9b57cc16..e0b0292f 100644 --- a/modules/juce_gui_basics/properties/juce_TextPropertyComponent.h +++ b/modules/juce_gui_basics/properties/juce_TextPropertyComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/widgets/juce_ComboBox.cpp b/modules/juce_gui_basics/widgets/juce_ComboBox.cpp index d20093a7..923917bf 100644 --- a/modules/juce_gui_basics/widgets/juce_ComboBox.cpp +++ b/modules/juce_gui_basics/widgets/juce_ComboBox.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/widgets/juce_ComboBox.h b/modules/juce_gui_basics/widgets/juce_ComboBox.h index 05876a7c..f6d67cb7 100644 --- a/modules/juce_gui_basics/widgets/juce_ComboBox.h +++ b/modules/juce_gui_basics/widgets/juce_ComboBox.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -273,7 +272,10 @@ public: /** Returns the PopupMenu object associated with the ComboBox. Can be useful for adding sub-menus to the ComboBox standard PopupMenu */ - PopupMenu* getRootMenu() { return &currentMenu; } + PopupMenu* getRootMenu() noexcept { return &currentMenu; } + + /** Returns the PopupMenu object associated with the ComboBox. */ + const PopupMenu* getRootMenu() const noexcept { return &currentMenu; } //============================================================================== /** diff --git a/modules/juce_gui_basics/widgets/juce_ImageComponent.cpp b/modules/juce_gui_basics/widgets/juce_ImageComponent.cpp index 3dac30c5..1f7dc08f 100644 --- a/modules/juce_gui_basics/widgets/juce_ImageComponent.cpp +++ b/modules/juce_gui_basics/widgets/juce_ImageComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/widgets/juce_ImageComponent.h b/modules/juce_gui_basics/widgets/juce_ImageComponent.h index 32cff19a..c4bf106f 100644 --- a/modules/juce_gui_basics/widgets/juce_ImageComponent.h +++ b/modules/juce_gui_basics/widgets/juce_ImageComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/widgets/juce_Label.cpp b/modules/juce_gui_basics/widgets/juce_Label.cpp index 254b47bb..8459d9e9 100644 --- a/modules/juce_gui_basics/widgets/juce_Label.cpp +++ b/modules/juce_gui_basics/widgets/juce_Label.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/widgets/juce_Label.h b/modules/juce_gui_basics/widgets/juce_Label.h index aa258cf5..4fb3753e 100644 --- a/modules/juce_gui_basics/widgets/juce_Label.h +++ b/modules/juce_gui_basics/widgets/juce_Label.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/widgets/juce_ListBox.cpp b/modules/juce_gui_basics/widgets/juce_ListBox.cpp index 7d7a9833..6cd138d3 100644 --- a/modules/juce_gui_basics/widgets/juce_ListBox.cpp +++ b/modules/juce_gui_basics/widgets/juce_ListBox.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -856,14 +855,11 @@ void ListBox::setOutlineThickness (int newThickness) resized(); } -void ListBox::setHeaderComponent (Component* newHeaderComponent) +void ListBox::setHeaderComponent (std::unique_ptr<Component> newHeaderComponent) { - if (headerComponent.get() != newHeaderComponent) - { - headerComponent.reset (newHeaderComponent); - addAndMakeVisible (newHeaderComponent); - ListBox::resized(); - } + headerComponent = std::move (newHeaderComponent); + addAndMakeVisible (headerComponent.get()); + ListBox::resized(); } void ListBox::repaintRow (const int rowNumber) noexcept @@ -894,7 +890,10 @@ Image ListBox::createSnapshotOfRows (const SparseSet<int>& rows, int& imageX, in imageY = imageArea.getY(); auto listScale = Component::getApproximateScaleFactorForComponent (this); - Image snapshot (Image::ARGB, roundToInt (imageArea.getWidth() * listScale), roundToInt (imageArea.getHeight() * listScale), true); + Image snapshot (Image::ARGB, + roundToInt ((float) imageArea.getWidth() * listScale), + roundToInt ((float) imageArea.getHeight() * listScale), + true); for (int i = getNumRowsOnScreen() + 2; --i >= 0;) { diff --git a/modules/juce_gui_basics/widgets/juce_ListBox.h b/modules/juce_gui_basics/widgets/juce_ListBox.h index 70203741..1b1f70a4 100644 --- a/modules/juce_gui_basics/widgets/juce_ListBox.h +++ b/modules/juce_gui_basics/widgets/juce_ListBox.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -492,7 +491,7 @@ public: The component will be deleted when setHeaderComponent() is called with a different component, or when the listbox is deleted. */ - void setHeaderComponent (Component* newHeaderComponent); + void setHeaderComponent (std::unique_ptr<Component> newHeaderComponent); /** Returns whatever header component was set with setHeaderComponent(). */ Component* getHeaderComponent() const noexcept { return headerComponent.get(); } diff --git a/modules/juce_gui_basics/widgets/juce_ProgressBar.cpp b/modules/juce_gui_basics/widgets/juce_ProgressBar.cpp index 67f3e488..1723297e 100644 --- a/modules/juce_gui_basics/widgets/juce_ProgressBar.cpp +++ b/modules/juce_gui_basics/widgets/juce_ProgressBar.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/widgets/juce_ProgressBar.h b/modules/juce_gui_basics/widgets/juce_ProgressBar.h index 79b791d2..e6d9712d 100644 --- a/modules/juce_gui_basics/widgets/juce_ProgressBar.h +++ b/modules/juce_gui_basics/widgets/juce_ProgressBar.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/widgets/juce_Slider.cpp b/modules/juce_gui_basics/widgets/juce_Slider.cpp index 51b70dd4..731193ff 100644 --- a/modules/juce_gui_basics/widgets/juce_Slider.cpp +++ b/modules/juce_gui_basics/widgets/juce_Slider.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -686,8 +685,8 @@ public: //============================================================================== void handleRotaryDrag (const MouseEvent& e) { - auto dx = e.position.x - sliderRect.getCentreX(); - auto dy = e.position.y - sliderRect.getCentreY(); + auto dx = e.position.x - (float) sliderRect.getCentreX(); + auto dy = e.position.y - (float) sliderRect.getCentreY(); if (dx * dx + dy * dy > 25.0f) { @@ -769,7 +768,7 @@ public: } else { - newPos = (mousePos - sliderRegionStart) / (double) sliderRegionSize; + newPos = (mousePos - (float) sliderRegionStart) / (double) sliderRegionSize; if (isVertical()) newPos = 1.0 - newPos; @@ -1141,8 +1140,8 @@ public: { auto pixelPos = (float) getLinearSliderPos (pos); - mousePos = owner.localPointToGlobal (Point<float> (isHorizontal() ? pixelPos : (owner.getWidth() / 2.0f), - isVertical() ? pixelPos : (owner.getHeight() / 2.0f))); + mousePos = owner.localPointToGlobal (Point<float> (isHorizontal() ? pixelPos : ((float) owner.getWidth() / 2.0f), + isVertical() ? pixelPos : ((float) owner.getHeight() / 2.0f))); } const_cast <MouseInputSource&> (ms).setScreenPosition (mousePos); diff --git a/modules/juce_gui_basics/widgets/juce_Slider.h b/modules/juce_gui_basics/widgets/juce_Slider.h index 7a723dbb..5b567935 100644 --- a/modules/juce_gui_basics/widgets/juce_Slider.h +++ b/modules/juce_gui_basics/widgets/juce_Slider.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -606,10 +605,10 @@ public: std::function<void()> onDragEnd; /** You can assign a lambda that will be used to convert textual values to the slider's normalised position. */ - std::function<double(const String&)> valueFromTextFunction; + std::function<double (const String&)> valueFromTextFunction; /** You can assign a lambda that will be used to convert the slider's normalised position to a textual value. */ - std::function<String(double)> textFromValueFunction; + std::function<String (double)> textFromValueFunction; //============================================================================== /** This lets you choose whether double-clicking or single-clicking with a specified diff --git a/modules/juce_gui_basics/widgets/juce_TableHeaderComponent.cpp b/modules/juce_gui_basics/widgets/juce_TableHeaderComponent.cpp index 8785b9d8..0309219f 100644 --- a/modules/juce_gui_basics/widgets/juce_TableHeaderComponent.cpp +++ b/modules/juce_gui_basics/widgets/juce_TableHeaderComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/widgets/juce_TableHeaderComponent.h b/modules/juce_gui_basics/widgets/juce_TableHeaderComponent.h index e9a50b73..5cbf7d1c 100644 --- a/modules/juce_gui_basics/widgets/juce_TableHeaderComponent.h +++ b/modules/juce_gui_basics/widgets/juce_TableHeaderComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/widgets/juce_TableListBox.cpp b/modules/juce_gui_basics/widgets/juce_TableListBox.cpp index f2d4b884..6df55158 100644 --- a/modules/juce_gui_basics/widgets/juce_TableListBox.cpp +++ b/modules/juce_gui_basics/widgets/juce_TableListBox.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -272,7 +271,7 @@ TableListBox::TableListBox (const String& name, TableListBoxModel* const m) { ListBox::model = this; - setHeader (new Header (*this)); + setHeader (std::make_unique<Header> (*this)); } TableListBox::~TableListBox() @@ -288,19 +287,23 @@ void TableListBox::setModel (TableListBoxModel* newModel) } } -void TableListBox::setHeader (TableHeaderComponent* newHeader) +void TableListBox::setHeader (std::unique_ptr<TableHeaderComponent> newHeader) { - jassert (newHeader != nullptr); // you need to supply a real header for a table! + if (newHeader == nullptr) + { + jassertfalse; // you need to supply a real header for a table! + return; + } Rectangle<int> newBounds (100, 28); if (header != nullptr) newBounds = header->getBounds(); - header = newHeader; + header = newHeader.get(); header->setBounds (newBounds); - setHeaderComponent (header); + setHeaderComponent (std::move (newHeader)); header->addListener (this); } diff --git a/modules/juce_gui_basics/widgets/juce_TableListBox.h b/modules/juce_gui_basics/widgets/juce_TableListBox.h index 08ffd742..fe60687c 100644 --- a/modules/juce_gui_basics/widgets/juce_TableListBox.h +++ b/modules/juce_gui_basics/widgets/juce_TableListBox.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -246,7 +245,7 @@ public: when it's no longer needed. The pointer passed in may not be null. */ - void setHeader (TableHeaderComponent* newHeader); + void setHeader (std::unique_ptr<TableHeaderComponent> newHeader); /** Changes the height of the table header component. @see getHeaderHeight diff --git a/modules/juce_gui_basics/widgets/juce_TextEditor.cpp b/modules/juce_gui_basics/widgets/juce_TextEditor.cpp index 9c10ee29..23dc74f4 100644 --- a/modules/juce_gui_basics/widgets/juce_TextEditor.cpp +++ b/modules/juce_gui_basics/widgets/juce_TextEditor.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -279,10 +278,11 @@ struct TextEditor::Iterator Iterator (const TextEditor& ed) : sections (ed.sections), justification (ed.justification), - justificationWidth (ed.getJustificationWidth()), + bottomRight (ed.getMaximumWidth(), ed.getMaximumHeight()), wordWrapWidth (ed.getWordWrapWidth()), passwordCharacter (ed.passwordCharacter), - lineSpacing (ed.lineSpacing) + lineSpacing (ed.lineSpacing), + underlineWhitespace (ed.underlineWhitespace) { jassert (wordWrapWidth > 0); @@ -293,6 +293,8 @@ struct TextEditor::Iterator if (currentSection != nullptr) beginNewLine(); } + + lineHeight = ed.currentFont.getHeight(); } Iterator (const Iterator&) = default; @@ -326,7 +328,7 @@ struct TextEditor::Iterator { tempAtom.numChars = (uint16) split; tempAtom.width = g.getGlyph (split - 1).getRight(); - atomX = getJustificationOffset (tempAtom.width); + atomX = getJustificationOffsetX (tempAtom.width); atomRight = atomX + tempAtom.width; return true; } @@ -428,14 +430,14 @@ struct TextEditor::Iterator tempAtom.numChars = 0; atom = &tempAtom; - if (atomX > justificationOffset) + if (atomX > justificationOffsetX) beginNewLine(); return next(); } beginNewLine(); - atomX = justificationOffset; + atomX = justificationOffsetX; atomRight = atomX + atom->width; return true; } @@ -495,25 +497,22 @@ struct TextEditor::Iterator ++tempAtomIndex; } - justificationOffset = getJustificationOffset (lineWidth); - atomX = justificationOffset; + justificationOffsetX = getJustificationOffsetX (lineWidth); + atomX = justificationOffsetX; } - float getJustificationOffset (float lineWidth) const + float getJustificationOffsetX (float lineWidth) const { - if (justification.getOnlyHorizontalFlags() == Justification::horizontallyCentred) - return jmax (0.0f, (justificationWidth - lineWidth) * 0.5f); - - if (justification.getOnlyHorizontalFlags() == Justification::right) - return jmax (0.0f, justificationWidth - lineWidth); + if (justification.testFlags (Justification::horizontallyCentred)) return jmax (0.0f, (bottomRight.x - lineWidth) * 0.5f); + if (justification.testFlags (Justification::right)) return jmax (0.0f, bottomRight.x - lineWidth); return 0; } //============================================================================== - void draw (Graphics& g, const UniformTextSection*& lastSection) const + void draw (Graphics& g, const UniformTextSection*& lastSection, AffineTransform transform) const { - if (passwordCharacter != 0 || ! atom->isWhitespace()) + if (passwordCharacter != 0 || (underlineWhitespace || ! atom->isWhitespace())) { if (lastSection != currentSection) { @@ -528,7 +527,7 @@ struct TextEditor::Iterator ga.addLineOfText (currentSection->font, atom->getTrimmedText (passwordCharacter), atomX, (float) roundToInt (lineY + lineHeight - maxDescent)); - ga.draw (g); + ga.draw (g, transform); } } @@ -540,18 +539,19 @@ struct TextEditor::Iterator area.add (startX, lineY, endX - startX, lineHeight * lineSpacing); } - void drawUnderline (Graphics& g, Range<int> underline, Colour colour) const + void drawUnderline (Graphics& g, Range<int> underline, Colour colour, AffineTransform transform) const { auto startX = roundToInt (indexToX (underline.getStart())); auto endX = roundToInt (indexToX (underline.getEnd())); auto baselineY = roundToInt (lineY + currentSection->font.getAscent() + 0.5f); Graphics::ScopedSaveState state (g); + g.addTransform (transform); g.reduceClipRegion ({ startX, baselineY, endX - startX, 1 }); - g.fillCheckerBoard ({ (float) endX, baselineY + 1.0f }, 3.0f, 1.0f, colour, Colours::transparentBlack); + g.fillCheckerBoard ({ (float) endX, (float) baselineY + 1.0f }, 3.0f, 1.0f, colour, Colours::transparentBlack); } - void drawSelectedText (Graphics& g, Range<int> selected, Colour selectedTextColour) const + void drawSelectedText (Graphics& g, Range<int> selected, Colour selectedTextColour, AffineTransform transform) const { if (passwordCharacter != 0 || ! atom->isWhitespace()) { @@ -567,7 +567,7 @@ struct TextEditor::Iterator ga.removeRangeOfGlyphs (selected.getEnd() - indexInText, -1); g.setColour (currentSection->colour); - ga2.draw (g); + ga2.draw (g, transform); } if (selected.getStart() > indexInText) @@ -577,11 +577,11 @@ struct TextEditor::Iterator ga.removeRangeOfGlyphs (0, selected.getStart() - indexInText); g.setColour (currentSection->colour); - ga2.draw (g); + ga2.draw (g, transform); } g.setColour (selectedTextColour); - ga.draw (g); + ga.draw (g, transform); } } @@ -650,20 +650,42 @@ struct TextEditor::Iterator return false; } + float getYOffset() + { + if (justification.testFlags (Justification::top) || lineY >= bottomRight.y) + return 0; + + while (next()) + { + if (lineY >= bottomRight.y) + return 0; + } + + auto bottom = jmax (0.0f, bottomRight.y - lineY - lineHeight); + + if (justification.testFlags (Justification::bottom)) + return bottom; + + return bottom * 0.5f; + } + //============================================================================== int indexInText = 0; - float lineY = 0, justificationOffset = 0, lineHeight = 0, maxDescent = 0; + float lineY = 0, lineHeight = 0, maxDescent = 0; float atomX = 0, atomRight = 0; const TextAtom* atom = nullptr; - const UniformTextSection* currentSection = nullptr; private: const OwnedArray<UniformTextSection>& sections; + const UniformTextSection* currentSection = nullptr; int sectionIndex = 0, atomIndex = 0; Justification justification; - const float justificationWidth, wordWrapWidth; + float justificationOffsetX = 0; + const Point<float> bottomRight; + const float wordWrapWidth; const juce_wchar passwordCharacter; const float lineSpacing; + const bool underlineWhitespace; TextAtom tempAtom; void moveToEndOfLastAtom() @@ -674,7 +696,7 @@ private: if (atom->isNewLine()) { - atomX = 0.0f; + atomX = getJustificationOffsetX (0); lineY += lineHeight * lineSpacing; } } @@ -827,8 +849,8 @@ struct TextEditor::TextEditorViewport : public Viewport void visibleAreaChanged (const Rectangle<int>&) override { - if (! rentrant) // it's rare, but possible to get into a feedback loop as the viewport's scrollbars - // appear and disappear, causing the wrap width to change. + if (! reentrant) // it's rare, but possible to get into a feedback loop as the viewport's scrollbars + // appear and disappear, causing the wrap width to change. { auto wordWrapWidth = owner.getWordWrapWidth(); @@ -836,9 +858,8 @@ struct TextEditor::TextEditorViewport : public Viewport { lastWordWrapWidth = wordWrapWidth; - rentrant = true; - owner.updateTextHolderSize(); - rentrant = false; + ScopedValueSetter<bool> svs (reentrant, true); + owner.checkLayout(); } } } @@ -846,7 +867,7 @@ struct TextEditor::TextEditorViewport : public Viewport private: TextEditor& owner; float lastWordWrapWidth = 0; - bool rentrant = false; + bool reentrant = false; JUCE_DECLARE_NON_COPYABLE (TextEditorViewport) }; @@ -937,8 +958,8 @@ void TextEditor::setMultiLine (const bool shouldBeMultiLine, multiline = shouldBeMultiLine; wordWrap = shouldWordWrap && shouldBeMultiLine; - viewport->setScrollBarsShown (scrollbarVisible && multiline, - scrollbarVisible && multiline); + checkLayout(); + viewport->setViewPosition (0, 0); resized(); scrollToMakeSureCursorIsVisible(); @@ -955,8 +976,7 @@ void TextEditor::setScrollbarsShown (bool shown) if (scrollbarVisible != shown) { scrollbarVisible = shown; - shown = shown && isMultiLine(); - viewport->setScrollBarsShown (shown, shown); + checkLayout(); } } @@ -1004,7 +1024,9 @@ void TextEditor::setJustification (Justification j) if (justification != j) { justification = j; + resized(); + repaint(); } } @@ -1029,7 +1051,7 @@ void TextEditor::applyFontToAllText (const Font& newFont, bool changeCurrentFont } coalesceSimilarSections(); - updateTextHolderSize(); + checkLayout(); scrollToMakeSureCursorIsVisible(); repaint(); } @@ -1091,8 +1113,13 @@ void TextEditor::recreateCaret() void TextEditor::updateCaretPosition() { - if (caret != nullptr) - caret->setCaretPosition (getCaretRectangle().translated (leftIndent, topIndent)); + if (caret != nullptr + && getWidth() > 0 && getHeight() > 0) + { + Iterator i (*this); + caret->setCaretPosition (getCaretRectangle().translated (leftIndent, + topIndent + roundToInt (i.getYOffset()))); + } } TextEditor::LengthAndCharacterRestriction::LengthAndCharacterRestriction (int maxLen, const String& chars) @@ -1147,7 +1174,7 @@ void TextEditor::setScrollBarThickness (int newThicknessPixels) void TextEditor::clear() { clearInternal (nullptr); - updateTextHolderSize(); + checkLayout(); undoManager.clearUndoHistory(); } @@ -1182,7 +1209,7 @@ void TextEditor::setText (const String& newText, bool sendTextChangeMessage) else textValue.addListener (textHolder); - updateTextHolderSize(); + checkLayout(); scrollToMakeSureCursorIsVisible(); undoManager.clearUndoHistory(); @@ -1215,7 +1242,7 @@ void TextEditor::textWasChangedByValue() //============================================================================== void TextEditor::textChanged() { - updateTextHolderSize(); + checkLayout(); if (listeners.size() != 0 || onTextChange != nullptr) postCommandMessage (TextEditorDefs::textChangeMessageId); @@ -1260,30 +1287,33 @@ void TextEditor::repaintText (Range<int> range) { if (! range.isEmpty()) { - auto lh = currentFont.getHeight(); - auto wordWrapWidth = getWordWrapWidth(); - - if (wordWrapWidth > 0) + if (range.getEnd() >= getTotalNumChars()) { - Point<float> anchor; - Iterator i (*this); - i.getCharPosition (range.getStart(), anchor, lh); + textHolder->repaint(); + return; + } - auto y1 = (int) anchor.y; - int y2; + Iterator i (*this); - if (range.getEnd() >= getTotalNumChars()) - { - y2 = textHolder->getHeight(); - } - else - { - i.getCharPosition (range.getEnd(), anchor, lh); - y2 = (int) (anchor.y + lh * 2.0f); - } + Point<float> anchor; + auto lh = currentFont.getHeight(); + i.getCharPosition (range.getStart(), anchor, lh); + + auto y1 = std::trunc (anchor.y); + int y2 = 0; - textHolder->repaint (0, y1, textHolder->getWidth(), y2 - y1); + if (range.getEnd() >= getTotalNumChars()) + { + y2 = textHolder->getHeight(); } + else + { + i.getCharPosition (range.getEnd(), anchor, lh); + y2 = (int) (anchor.y + lh * 2.0f); + } + + auto offset = i.getYOffset(); + textHolder->repaint (0, roundToInt (y1 + offset), textHolder->getWidth(), roundToInt ((float) y2 - y1 + offset)); } } @@ -1368,33 +1398,66 @@ Rectangle<float> TextEditor::getCaretRectangleFloat() const } //============================================================================== -enum { rightEdgeSpace = 2 }; +// Extra space for the cursor at the right-hand-edge +constexpr int rightEdgeSpace = 2; float TextEditor::getWordWrapWidth() const { - return wordWrap ? getJustificationWidth() + return wordWrap ? getMaximumWidth() : std::numeric_limits<float>::max(); } -float TextEditor::getJustificationWidth() const +float TextEditor::getMaximumWidth() const { return (float) (viewport->getMaximumVisibleWidth() - (leftIndent + rightEdgeSpace + 1)); } -void TextEditor::updateTextHolderSize() +float TextEditor::getMaximumHeight() const +{ + return (float) (viewport->getMaximumVisibleHeight() - topIndent); +} + +void TextEditor::checkLayout() { if (getWordWrapWidth() > 0) { - float maxWidth = getJustificationWidth(); + auto maxWidth = getMaximumWidth(); Iterator i (*this); while (i.next()) maxWidth = jmax (maxWidth, i.atomRight); - auto w = leftIndent + roundToInt (maxWidth); - auto h = topIndent + roundToInt (jmax (i.lineY + i.lineHeight, currentFont.getHeight())); + auto textRight = roundToInt (maxWidth); + auto textBottom = roundToInt (i.lineY + i.lineHeight + i.getYOffset()); + + if (i.atom != nullptr && i.atom->isNewLine()) + textBottom += (int) i.lineHeight; - textHolder->setSize (w + rightEdgeSpace, h + 1); // (allows a bit of space for the cursor to be at the right-hand-edge) + updateTextHolderSize (textRight, textBottom); + updateScrollbarVisibility (textRight, textBottom); + } +} + +void TextEditor::updateTextHolderSize (int textRight, int textBottom) +{ + auto w = leftIndent + jmax (roundToInt (getMaximumWidth()), textRight); + auto h = topIndent + textBottom; + + textHolder->setSize (w + rightEdgeSpace, h + 1); +} + +void TextEditor::updateScrollbarVisibility (int textRight, int textBottom) +{ + if (scrollbarVisible && multiline) + { + auto horizontalVisible = (leftIndent + textRight) > (viewport->getMaximumVisibleWidth() - viewport->getScrollBarThickness()); + auto verticalVisible = (topIndent + textBottom) > (viewport->getMaximumVisibleHeight() + 1); + + viewport->setScrollBarsShown (verticalVisible, horizontalVisible); + } + else + { + viewport->setScrollBarsShown (false, false); } } @@ -1403,8 +1466,14 @@ int TextEditor::getTextHeight() const { return textHolder->getHeight(); } void TextEditor::setIndents (int newLeftIndent, int newTopIndent) { - leftIndent = newLeftIndent; - topIndent = newTopIndent; + if (leftIndent != newLeftIndent || topIndent != newTopIndent) + { + leftIndent = newLeftIndent; + topIndent = newTopIndent; + + resized(); + repaint(); + } } void TextEditor::setBorder (BorderSize<int> border) @@ -1507,8 +1576,10 @@ void TextEditor::moveCaretTo (const int newPosition, const bool isSelecting) int TextEditor::getTextIndexAt (const int x, const int y) { + Iterator i (*this); + return indexAtPosition ((float) (x + viewport->getViewPositionX() - leftIndent - borderSize.getLeft()), - (float) (y + viewport->getViewPositionY() - topIndent - borderSize.getTop())); + (float) (y + viewport->getViewPositionY() - topIndent - borderSize.getTop()) - i.getYOffset()); } void TextEditor::insertTextAtCaret (const String& t) @@ -1577,43 +1648,54 @@ void TextEditor::drawContent (Graphics& g) { g.setOrigin (leftIndent, topIndent); auto clip = g.getClipBounds(); - Colour selectedTextColour; + + auto yOffset = Iterator (*this).getYOffset(); + + AffineTransform transform; + + if (yOffset > 0) + { + transform = AffineTransform::translation (0.0f, yOffset); + clip.setY (roundToInt ((float) clip.getY() - yOffset)); + } + Iterator i (*this); + Colour selectedTextColour; if (! selection.isEmpty()) { Iterator i2 (i); RectangleList<float> selectionArea; - while (i2.next() && i2.lineY < clip.getBottom()) + while (i2.next() && i2.lineY < (float) clip.getBottom()) { - if (i2.lineY + i2.lineHeight >= clip.getY() + if (i2.lineY + i2.lineHeight >= (float) clip.getY() && selection.intersects ({ i2.indexInText, i2.indexInText + i2.atom->numChars })) { i2.addSelection (selectionArea, selection); } } - g.setColour (findColour (highlightColourId).withMultipliedAlpha (hasKeyboardFocus (true) ? 1.0f : 0.5f)); - g.fillRectList (selectionArea); - selectedTextColour = findColour (highlightedTextColourId); + + g.setColour (findColour (highlightColourId).withMultipliedAlpha (hasKeyboardFocus (true) ? 1.0f : 0.5f)); + g.fillPath (selectionArea.toPath(), transform); } const UniformTextSection* lastSection = nullptr; - while (i.next() && i.lineY < clip.getBottom()) + while (i.next() && i.lineY < (float) clip.getBottom()) { - if (i.lineY + i.lineHeight >= clip.getY()) + if (i.lineY + i.lineHeight >= (float) clip.getY()) { if (selection.intersects ({ i.indexInText, i.indexInText + i.atom->numChars })) { - i.drawSelectedText (g, selection, selectedTextColour); + i.drawSelectedText (g, selection, selectedTextColour, transform); lastSection = nullptr; } else { - i.draw (g, lastSection); + i.draw (g, lastSection, transform); } } } @@ -1622,12 +1704,12 @@ void TextEditor::drawContent (Graphics& g) { Iterator i2 (*this); - while (i2.next() && i2.lineY < clip.getBottom()) + while (i2.next() && i2.lineY < (float) clip.getBottom()) { - if (i2.lineY + i2.lineHeight >= clip.getY() + if (i2.lineY + i2.lineHeight >= (float) clip.getY() && underlinedSection.intersects ({ i2.indexInText, i2.indexInText + i2.atom->numChars })) { - i2.drawUnderline (g, underlinedSection, findColour (textColourId)); + i2.drawUnderline (g, underlinedSection, findColour (textColourId), transform); } } } @@ -1648,13 +1730,13 @@ void TextEditor::paintOverChildren (Graphics& g) g.setColour (colourForTextWhenEmpty); g.setFont (getFont()); - if (isMultiLine()) - g.drawText (textToShowWhenEmpty, getLocalBounds(), - Justification::centred, true); - else - g.drawText (textToShowWhenEmpty, - leftIndent, 0, viewport->getWidth() - leftIndent, getHeight(), - Justification::centredLeft, true); + Rectangle<int> textBounds (leftIndent, + topIndent, + viewport->getWidth() - leftIndent, + getHeight() - topIndent); + + if (! textBounds.isEmpty()) + g.drawText (textToShowWhenEmpty, textBounds, justification, true); } getLookAndFeel().drawTextEditorOutline (g, getWidth(), getHeight(), *this); @@ -1884,7 +1966,7 @@ bool TextEditor::pageUp (bool selecting) return moveCaretToStartOfLine (selecting); auto caretPos = getCaretRectangleFloat(); - return moveCaretWithTransaction (indexAtPosition (caretPos.getX(), caretPos.getY() - viewport->getViewHeight()), selecting); + return moveCaretWithTransaction (indexAtPosition (caretPos.getX(), caretPos.getY() - (float) viewport->getViewHeight()), selecting); } bool TextEditor::pageDown (bool selecting) @@ -1893,7 +1975,7 @@ bool TextEditor::pageDown (bool selecting) return moveCaretToEndOfLine (selecting); auto caretPos = getCaretRectangleFloat(); - return moveCaretWithTransaction (indexAtPosition (caretPos.getX(), caretPos.getBottom() + viewport->getViewHeight()), selecting); + return moveCaretWithTransaction (indexAtPosition (caretPos.getX(), caretPos.getBottom() + (float) viewport->getViewHeight()), selecting); } void TextEditor::scrollByLines (int deltaLines) @@ -2056,7 +2138,7 @@ bool TextEditor::keyStateChanged (const bool isKeyDown) } //============================================================================== -void TextEditor::focusGained (FocusChangeType) +void TextEditor::focusGained (FocusChangeType cause) { newTransaction(); @@ -2068,6 +2150,9 @@ void TextEditor::focusGained (FocusChangeType) checkFocus(); + if (cause == FocusChangeType::focusChangedByMouseClick && selectAllTextWhenFocused) + wasFocused = false; + repaint(); updateCaretPosition(); } @@ -2096,7 +2181,7 @@ void TextEditor::resized() viewport->setBoundsInset (borderSize); viewport->setSingleStepSizes (16, roundToInt (currentFont.getHeight())); - updateTextHolderSize(); + checkLayout(); if (isMultiLine()) updateCaretPosition(); @@ -2214,7 +2299,7 @@ void TextEditor::insert (const String& text, int insertIndex, const Font& font, totalNumChars = -1; valueTextNeedsUpdating = true; - updateTextHolderSize(); + checkLayout(); moveCaretTo (caretPositionToMoveTo, false); repaintText ({ insertIndex, getTotalNumChars() }); @@ -2427,7 +2512,7 @@ void TextEditor::getCharPosition (int index, Point<float>& anchor, float& lineHe if (sections.isEmpty()) { - anchor = { i.getJustificationOffset (0), 0 }; + anchor = { i.getJustificationOffsetX (0), 0 }; lineHeight = currentFont.getHeight(); } else diff --git a/modules/juce_gui_basics/widgets/juce_TextEditor.h b/modules/juce_gui_basics/widgets/juce_TextEditor.h index be44cc47..1ce56c66 100644 --- a/modules/juce_gui_basics/widgets/juce_TextEditor.h +++ b/modules/juce_gui_basics/widgets/juce_TextEditor.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -156,7 +155,6 @@ public: */ bool areScrollbarsShown() const noexcept { return scrollbarVisible; } - /** Changes the password character used to disguise the text. @param passwordCharacter if this is not zero, this character will be used as a replacement @@ -173,7 +171,6 @@ public: */ juce_wchar getPasswordCharacter() const noexcept { return passwordCharacter; } - //============================================================================== /** Allows a right-click menu to appear for the editor. @@ -252,7 +249,7 @@ public: @see setFont */ - const Font& getFont() const noexcept { return currentFont; } + const Font& getFont() const noexcept { return currentFont; } /** Applies a colour to all the text in the editor. @@ -261,6 +258,18 @@ public: */ void applyColourToAllText (const Colour& newColour, bool changeCurrentTextColour = true); + /** Sets whether whitespace should be underlined when the editor font is underlined. + + @see isWhitespaceUnderlined + */ + void setWhitespaceUnderlined (bool shouldUnderlineWhitespace) noexcept { underlineWhitespace = shouldUnderlineWhitespace; } + + /** Returns true if whitespace is underlined for underlined fonts. + + @see setWhitespaceIsUnderlined + */ + bool isWhitespaceUnderlined() const noexcept { return underlineWhitespace; } + //============================================================================== /** If set to true, focusing on the editor will highlight all its text. @@ -496,9 +505,12 @@ public: */ void setScrollToShowCursor (bool shouldScrollToShowCaret); - /** Modifies the horizontal justification of the text within the editor window. */ + /** Modifies the justification of the text within the editor window. */ void setJustification (Justification newJustification); + /** Returns the type of justification, as set in setJustification(). */ + Justification getJustificationType() const noexcept { return justification; } + /** Sets the line spacing of the TextEditor. The default (and minimum) value is 1.0 and values > 1.0 will increase the line spacing as a multiple of the line height e.g. for double-spacing call this method with an argument of 2.0. @@ -713,7 +725,7 @@ private: std::unique_ptr<Viewport> viewport; TextHolderComponent* textHolder; BorderSize<int> borderSize { 1, 1, 1, 3 }; - Justification justification { Justification::left }; + Justification justification { Justification::topLeft }; bool readOnly = false; bool caretVisible = true; @@ -729,6 +741,7 @@ private: bool menuActive = false; bool valueTextNeedsUpdating = false; bool consumeEscAndReturnKeys = true; + bool underlineWhitespace = true; UndoManager undoManager; std::unique_ptr<CaretComponent> caret; @@ -779,9 +792,12 @@ private: int findWordBreakBefore (int position) const; bool moveCaretWithTransaction (int newPos, bool selecting); void drawContent (Graphics&); - void updateTextHolderSize(); + void checkLayout(); + void updateTextHolderSize (int, int); + void updateScrollbarVisibility (int, int); float getWordWrapWidth() const; - float getJustificationWidth() const; + float getMaximumWidth() const; + float getMaximumHeight() const; void timerCallbackInt(); void checkFocus(); void repaintText (Range<int>); diff --git a/modules/juce_gui_basics/widgets/juce_Toolbar.cpp b/modules/juce_gui_basics/widgets/juce_Toolbar.cpp index 1049dbe4..d16b0c17 100644 --- a/modules/juce_gui_basics/widgets/juce_Toolbar.cpp +++ b/modules/juce_gui_basics/widgets/juce_Toolbar.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -52,7 +51,7 @@ public: } else { - maxSize = roundToInt (toolbarThickness * fixedSize); + maxSize = roundToInt ((float) toolbarThickness * fixedSize); minSize = drawBar ? maxSize : jmin (4, maxSize); preferredSize = maxSize; @@ -88,9 +87,9 @@ public: auto thickness = 0.2f; if (isToolbarVertical()) - g.fillRect (w * 0.1f, h * (0.5f - thickness * 0.5f), w * 0.8f, h * thickness); + g.fillRect ((float) w * 0.1f, (float) h * (0.5f - thickness * 0.5f), (float) w * 0.8f, (float) h * thickness); else - g.fillRect (w * (0.5f - thickness * 0.5f), h * 0.1f, w * thickness, h * 0.8f); + g.fillRect ((float) w * (0.5f - thickness * 0.5f), (float) h * 0.1f, (float) w * thickness, (float) h * 0.8f); } if (getEditingMode() != normalMode && ! drawBar) @@ -107,33 +106,33 @@ public: if (isToolbarVertical()) { - x1 = w * 0.5f; - y1 = h * 0.4f; + x1 = (float) w * 0.5f; + y1 = (float) h * 0.4f; x2 = x1; - y2 = indentX * 2.0f; + y2 = (float) indentX * 2.0f; x3 = x1; - y3 = h * 0.6f; + y3 = (float) h * 0.6f; x4 = x1; - y4 = h - y2; + y4 = (float) h - y2; - hw = w * 0.15f; - hl = w * 0.2f; + hw = (float) w * 0.15f; + hl = (float) w * 0.2f; } else { - x1 = w * 0.4f; - y1 = h * 0.5f; - x2 = indentX * 2.0f; + x1 = (float) w * 0.4f; + y1 = (float) h * 0.5f; + x2 = (float) indentX * 2.0f; y2 = y1; - x3 = w * 0.6f; + x3 = (float) w * 0.6f; y3 = y1; - x4 = w - x2; + x4 = (float) w - x2; y4 = y1; - hw = h * 0.15f; - hl = h * 0.2f; + hw = (float) h * 0.15f; + hl = (float) h * 0.2f; } Path p; @@ -243,7 +242,7 @@ private: //============================================================================== Toolbar::Toolbar() { - missingItemsButton.reset (getLookAndFeel().createToolbarMissingItemsButton (*this)); + lookAndFeelChanged(); addChildComponent (missingItemsButton.get()); missingItemsButton->setAlwaysOnTop (true); @@ -641,6 +640,11 @@ void Toolbar::itemDropped (const SourceDetails& dragSourceDetails) tc->setState (Button::buttonNormal); } +void Toolbar::lookAndFeelChanged() +{ + missingItemsButton.reset (getLookAndFeel().createToolbarMissingItemsButton (*this)); +} + void Toolbar::mouseDown (const MouseEvent&) {} //============================================================================== @@ -728,9 +732,10 @@ private: int selectedStyle = 0; switch (bar.getStyle()) { - case Toolbar::iconsOnly: selectedStyle = 1; break; - case Toolbar::iconsWithText: selectedStyle = 2; break; - case Toolbar::textOnly: selectedStyle = 3; break; + case Toolbar::iconsOnly: selectedStyle = 1; break; + case Toolbar::iconsWithText: selectedStyle = 2; break; + case Toolbar::textOnly: selectedStyle = 3; break; + default: break; } styleBox.setSelectedId (selectedStyle); @@ -757,6 +762,7 @@ private: case 1: toolbar.setStyle (Toolbar::iconsOnly); break; case 2: toolbar.setStyle (Toolbar::iconsWithText); break; case 3: toolbar.setStyle (Toolbar::textOnly); break; + default: break; } palette.resized(); // to make it update the styles diff --git a/modules/juce_gui_basics/widgets/juce_Toolbar.h b/modules/juce_gui_basics/widgets/juce_Toolbar.h index c21b7067..dd096ac5 100644 --- a/modules/juce_gui_basics/widgets/juce_Toolbar.h +++ b/modules/juce_gui_basics/widgets/juce_Toolbar.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -304,6 +303,8 @@ public: /** @internal */ void itemDropped (const SourceDetails&) override; /** @internal */ + void lookAndFeelChanged() override; + /** @internal */ void updateAllItemPositions (bool animate); /** @internal */ static ToolbarItemComponent* createItem (ToolbarItemFactory&, int itemId); diff --git a/modules/juce_gui_basics/widgets/juce_ToolbarItemComponent.cpp b/modules/juce_gui_basics/widgets/juce_ToolbarItemComponent.cpp index d6e792ad..2026a115 100644 --- a/modules/juce_gui_basics/widgets/juce_ToolbarItemComponent.cpp +++ b/modules/juce_gui_basics/widgets/juce_ToolbarItemComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/widgets/juce_ToolbarItemComponent.h b/modules/juce_gui_basics/widgets/juce_ToolbarItemComponent.h index 4a000fdb..5be4e85c 100644 --- a/modules/juce_gui_basics/widgets/juce_ToolbarItemComponent.h +++ b/modules/juce_gui_basics/widgets/juce_ToolbarItemComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/widgets/juce_ToolbarItemFactory.h b/modules/juce_gui_basics/widgets/juce_ToolbarItemFactory.h index 887ae080..92ff4eff 100644 --- a/modules/juce_gui_basics/widgets/juce_ToolbarItemFactory.h +++ b/modules/juce_gui_basics/widgets/juce_ToolbarItemFactory.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/widgets/juce_ToolbarItemPalette.cpp b/modules/juce_gui_basics/widgets/juce_ToolbarItemPalette.cpp index 7ea946f4..d4c36fc6 100644 --- a/modules/juce_gui_basics/widgets/juce_ToolbarItemPalette.cpp +++ b/modules/juce_gui_basics/widgets/juce_ToolbarItemPalette.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/widgets/juce_ToolbarItemPalette.h b/modules/juce_gui_basics/widgets/juce_ToolbarItemPalette.h index c93b8d79..c029ed2e 100644 --- a/modules/juce_gui_basics/widgets/juce_ToolbarItemPalette.h +++ b/modules/juce_gui_basics/widgets/juce_ToolbarItemPalette.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/widgets/juce_TreeView.cpp b/modules/juce_gui_basics/widgets/juce_TreeView.cpp index 8e42d846..b6d4d1cc 100644 --- a/modules/juce_gui_basics/widgets/juce_TreeView.cpp +++ b/modules/juce_gui_basics/widgets/juce_TreeView.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -994,7 +993,7 @@ public: void paint (Graphics& g) override { g.setColour (findColour (TreeView::dragAndDropIndicatorColourId, true)); - g.drawRoundedRectangle (1.0f, 1.0f, getWidth() - 2.0f, getHeight() - 2.0f, 3.0f, 2.0f); + g.drawRoundedRectangle (1.0f, 1.0f, (float) getWidth() - 2.0f, (float) getHeight() - 2.0f, 3.0f, 2.0f); } private: @@ -1553,13 +1552,13 @@ void TreeViewItem::paintRecursively (Graphics& g, int width) } } - auto halfH = itemHeight * 0.5f; + auto halfH = (float) itemHeight * 0.5f; auto indentWidth = ownerView->getIndentSize(); auto depth = TreeViewHelpers::calculateDepth (this, ownerView->rootItemVisible); if (depth >= 0 && ownerView->openCloseButtonsVisible) { - auto x = (depth + 0.5f) * indentWidth; + auto x = ((float) depth + 0.5f) * (float) indentWidth; const bool parentLinesDrawn = parentItem != nullptr && parentItem->areLinesDrawn(); @@ -1567,7 +1566,7 @@ void TreeViewItem::paintRecursively (Graphics& g, int width) paintVerticalConnectingLine (g, Line<float> (x, 0, x, isLastOfSiblings() ? halfH : (float) itemHeight)); if (parentLinesDrawn || (parentItem == nullptr && areLinesDrawn())) - paintHorizontalConnectingLine (g, Line<float> (x, halfH, x + indentWidth / 2, halfH)); + paintHorizontalConnectingLine (g, Line<float> (x, halfH, x + (float) indentWidth * 0.5f, halfH)); { auto* p = parentItem; diff --git a/modules/juce_gui_basics/widgets/juce_TreeView.h b/modules/juce_gui_basics/widgets/juce_TreeView.h index 3c113a7d..0d8055ce 100644 --- a/modules/juce_gui_basics/widgets/juce_TreeView.h +++ b/modules/juce_gui_basics/widgets/juce_TreeView.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -507,8 +506,6 @@ public: for a specific item, but this can be handy if you need to briefly save the state for a section of the tree. - The caller is responsible for deleting the object that is returned. - Note that if all nodes of the tree are in their default state, then this may return a nullptr. @@ -804,8 +801,6 @@ public: completely different instance of the tree, as long as it contains nodes whose unique names are the same. - The caller is responsible for deleting the object that is returned. - @param alsoIncludeScrollPosition if this is true, the state will also include information about where the tree has been scrolled to vertically, diff --git a/modules/juce_gui_basics/windows/juce_AlertWindow.cpp b/modules/juce_gui_basics/windows/juce_AlertWindow.cpp index a4376f7e..f45630f0 100644 --- a/modules/juce_gui_basics/windows/juce_AlertWindow.cpp +++ b/modules/juce_gui_basics/windows/juce_AlertWindow.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -240,7 +239,7 @@ public: setFont (font); setText (message, false); - bestWidth = 2 * (int) std::sqrt (font.getHeight() * font.getStringWidth (message)); + bestWidth = 2 * (int) std::sqrt (font.getHeight() * (float) font.getStringWidth (message)); } void updateLayout (const int width) @@ -250,7 +249,7 @@ public: s.append (getText(), getFont()); TextLayout text; - text.createLayoutWithBalancedLineLengths (s, width - 8.0f); + text.createLayoutWithBalancedLineLengths (s, (float) width - 8.0f); setSize (width, jmin (width, (int) (text.getHeight() + getFont().getHeight()))); } @@ -356,8 +355,8 @@ void AlertWindow::updateLayout (const bool onlyIncreaseSize) auto wid = jmax (messageFont.getStringWidth (text), messageFont.getStringWidth (getName())); - auto sw = (int) std::sqrt (messageFont.getHeight() * wid); - auto w = jmin (300 + sw * 2, (int) (getParentWidth() * 0.7f)); + auto sw = (int) std::sqrt (messageFont.getHeight() * (float) wid); + auto w = jmin (300 + sw * 2, (int) ((float) getParentWidth() * 0.7f)); const int edgeGap = 10; const int labelHeight = 18; int iconSpace = 0; @@ -383,7 +382,7 @@ void AlertWindow::updateLayout (const bool onlyIncreaseSize) } w = jmax (350, (int) textLayout.getWidth() + iconSpace + edgeGap * 4); - w = jmin (w, (int) (getParentWidth() * 0.7f)); + w = jmin (w, (int) ((float) getParentWidth() * 0.7f)); auto textLayoutH = (int) textLayout.getHeight(); auto textBottom = 16 + titleH + textLayoutH; @@ -413,12 +412,12 @@ void AlertWindow::updateLayout (const bool onlyIncreaseSize) for (auto* tb : textBlocks) w = jmax (w, static_cast<const AlertTextComp*> (tb)->bestWidth); - w = jmin (w, (int) (getParentWidth() * 0.7f)); + w = jmin (w, (int) ((float) getParentWidth() * 0.7f)); for (auto* tb : textBlocks) { auto* ac = static_cast<AlertTextComp*> (tb); - ac->updateLayout ((int) (w * 0.8f)); + ac->updateLayout ((int) ((float) w * 0.8f)); h += ac->getHeight() + 10; } @@ -444,7 +443,7 @@ void AlertWindow::updateLayout (const bool onlyIncreaseSize) totalWidth += b->getWidth() + spacer; auto x = (w - totalWidth) / 2; - auto y = (int) (getHeight() * 0.95f); + auto y = (int) ((float) getHeight() * 0.95f); for (auto* c : buttons) { diff --git a/modules/juce_gui_basics/windows/juce_AlertWindow.h b/modules/juce_gui_basics/windows/juce_AlertWindow.h index 32823397..1b234c43 100644 --- a/modules/juce_gui_basics/windows/juce_AlertWindow.h +++ b/modules/juce_gui_basics/windows/juce_AlertWindow.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/windows/juce_CallOutBox.cpp b/modules/juce_gui_basics/windows/juce_CallOutBox.cpp index a1018163..bab4c696 100644 --- a/modules/juce_gui_basics/windows/juce_CallOutBox.cpp +++ b/modules/juce_gui_basics/windows/juce_CallOutBox.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -41,9 +40,7 @@ CallOutBox::CallOutBox (Component& c, Rectangle<int> area, Component* const pare else { setAlwaysOnTop (juce_areThereAnyAlwaysOnTopWindows()); - - updatePosition (area, Desktop::getInstance().getDisplays().findDisplayForRect (area).userArea); - + updatePosition (area, Desktop::getInstance().getDisplays().getDisplayForRect (area)->userArea); addToDesktop (ComponentPeer::windowIsTemporary); startTimer (100); @@ -52,17 +49,14 @@ CallOutBox::CallOutBox (Component& c, Rectangle<int> area, Component* const pare creationTime = Time::getCurrentTime(); } -CallOutBox::~CallOutBox() -{ -} - //============================================================================== class CallOutBoxCallback : public ModalComponentManager::Callback, private Timer { public: - CallOutBoxCallback (Component* c, const Rectangle<int>& area, Component* parent) - : content (c), callout (*c, area, parent) + CallOutBoxCallback (std::unique_ptr<Component> c, const Rectangle<int>& area, Component* parent) + : content (std::move (c)), + callout (*content, area, parent) { callout.setVisible (true); callout.enterModalState (true, this); @@ -83,11 +77,11 @@ public: JUCE_DECLARE_NON_COPYABLE (CallOutBoxCallback) }; -CallOutBox& CallOutBox::launchAsynchronously (Component* content, Rectangle<int> area, Component* parent) +CallOutBox& CallOutBox::launchAsynchronously (std::unique_ptr<Component> content, Rectangle<int> area, Component* parent) { jassert (content != nullptr); // must be a valid content component! - return (new CallOutBoxCallback (content, area, parent))->callout; + return (new CallOutBoxCallback (std::move (content), area, parent))->callout; } //============================================================================== @@ -102,6 +96,12 @@ int CallOutBox::getBorderSize() const noexcept return jmax (getLookAndFeel().getCallOutBoxBorderSize (*this), (int) arrowSize); } +void CallOutBox::lookAndFeelChanged() +{ + resized(); + repaint(); +} + void CallOutBox::paint (Graphics& g) { getLookAndFeel().drawCallOutBoxBackground (*this, g, outline, background); @@ -159,7 +159,7 @@ void CallOutBox::setDismissalMouseClicksAreAlwaysConsumed (bool b) noexcept dismissalMouseClicksAreAlwaysConsumed = b; } -enum { callOutBoxDismissCommandId = 0x4f83a04b }; +static constexpr int callOutBoxDismissCommandId = 0x4f83a04b; void CallOutBox::handleCommandMessage (int commandId) { @@ -194,15 +194,14 @@ void CallOutBox::updatePosition (const Rectangle<int>& newAreaToPointTo, const R availableArea = newAreaToFitIn; auto borderSpace = getBorderSize(); - - Rectangle<int> newBounds (content.getWidth() + borderSpace * 2, - content.getHeight() + borderSpace * 2); + auto newBounds = getLocalArea (&content, Rectangle<int> (content.getWidth() + borderSpace * 2, + content.getHeight() + borderSpace * 2)); auto hw = newBounds.getWidth() / 2; auto hh = newBounds.getHeight() / 2; auto hwReduced = (float) (hw - borderSpace * 2); auto hhReduced = (float) (hh - borderSpace * 2); - auto arrowIndent = borderSpace - arrowSize; + auto arrowIndent = (float) borderSpace - arrowSize; Point<float> targets[4] = { { (float) targetArea.getCentreX(), (float) targetArea.getBottom() }, { (float) targetArea.getRight(), (float) targetArea.getCentreY() }, @@ -235,8 +234,8 @@ void CallOutBox::updatePosition (const Rectangle<int>& newAreaToPointTo, const R nearest = distanceFromCentre; targetPoint = targets[i]; - newBounds.setPosition ((int) (centre.x - hw), - (int) (centre.y - hh)); + newBounds.setPosition ((int) (centre.x - (float) hw), + (int) (centre.y - (float) hh)); } } @@ -251,7 +250,7 @@ void CallOutBox::refreshPath() const float gap = 4.5f; - outline.addBubble (content.getBounds().toFloat().expanded (gap, gap), + outline.addBubble (getLocalArea (&content, content.getLocalBounds().toFloat()).expanded (gap, gap), getLocalBounds().toFloat(), targetPoint - getPosition().toFloat(), getLookAndFeel().getCallOutBoxCornerSize (*this), arrowSize * 0.7f); diff --git a/modules/juce_gui_basics/windows/juce_CallOutBox.h b/modules/juce_gui_basics/windows/juce_CallOutBox.h index c4572b83..eaa46992 100644 --- a/modules/juce_gui_basics/windows/juce_CallOutBox.h +++ b/modules/juce_gui_basics/windows/juce_CallOutBox.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -44,11 +43,12 @@ namespace juce @code void mouseUp (const MouseEvent&) { - FoobarContentComp* content = new FoobarContentComp(); + auto content = std::make_unique<FoobarContentComp>(); content->setSize (300, 300); - CallOutBox& myBox - = CallOutBox::launchAsynchronously (content, getScreenBounds(), nullptr); + auto& myBox = CallOutBox::launchAsynchronously (std::move (content), + getScreenBounds(), + nullptr); } @endcode @@ -78,9 +78,6 @@ public: Rectangle<int> areaToPointTo, Component* parentComponent); - /** Destructor. */ - ~CallOutBox() override; - //============================================================================== /** Changes the base width of the arrow. */ void setArrowSize (float newSize); @@ -110,15 +107,13 @@ public: @param contentComponent the component to display inside the call-out. This should already have a size set (although the call-out will also update itself when the component's size is changed later). - This component will be owned by the callout box and deleted - later when the box is dismissed. @param areaToPointTo the area that the call-out's arrow should point towards. If a parentComponent is supplied, then this is relative to that parent; otherwise, it's a global screen coord. @param parentComponent if not a nullptr, this is the component to add the call-out to. If this is a nullptr, the call-out will be added to the desktop. */ - static CallOutBox& launchAsynchronously (Component* contentComponent, + static CallOutBox& launchAsynchronously (std::unique_ptr<Component> contentComponent, Rectangle<int> areaToPointTo, Component* parentComponent); @@ -167,6 +162,8 @@ public: void handleCommandMessage (int) override; /** @internal */ int getBorderSize() const noexcept; + /** @internal */ + void lookAndFeelChanged() override; private: //============================================================================== diff --git a/modules/juce_gui_basics/windows/juce_ComponentPeer.cpp b/modules/juce_gui_basics/windows/juce_ComponentPeer.cpp index d6540444..90ad1b05 100644 --- a/modules/juce_gui_basics/windows/juce_ComponentPeer.cpp +++ b/modules/juce_gui_basics/windows/juce_ComponentPeer.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -116,8 +115,8 @@ void ComponentPeer::handlePaint (LowLevelGraphicsContext& contextToPaintTo) if (peerBounds.getWidth() != componentBounds.getWidth() || peerBounds.getHeight() != componentBounds.getHeight()) // Tweak the scaling so that the component's integer size exactly aligns with the peer's scaled size - g.addTransform (AffineTransform::scale (peerBounds.getWidth() / (float) componentBounds.getWidth(), - peerBounds.getHeight() / (float) componentBounds.getHeight())); + g.addTransform (AffineTransform::scale ((float) peerBounds.getWidth() / (float) componentBounds.getWidth(), + (float) peerBounds.getHeight() / (float) componentBounds.getHeight())); #if JUCE_ENABLE_REPAINT_DEBUGGING #ifdef JUCE_IS_REPAINT_DEBUGGING_ACTIVE @@ -403,6 +402,16 @@ Rectangle<int> ComponentPeer::globalToLocal (const Rectangle<int>& screenPositio return screenPosition.withPosition (globalToLocal (screenPosition.getPosition())); } +Rectangle<float> ComponentPeer::localToGlobal (const Rectangle<float>& relativePosition) +{ + return relativePosition.withPosition (localToGlobal (relativePosition.getPosition())); +} + +Rectangle<float> ComponentPeer::globalToLocal (const Rectangle<float>& screenPosition) +{ + return screenPosition.withPosition (globalToLocal (screenPosition.getPosition())); +} + Rectangle<int> ComponentPeer::getAreaCoveredBy (Component& subComponent) const { return ScalingHelpers::scaledScreenPosToUnscaled diff --git a/modules/juce_gui_basics/windows/juce_ComponentPeer.h b/modules/juce_gui_basics/windows/juce_ComponentPeer.h index 28748ef8..b41716ab 100644 --- a/modules/juce_gui_basics/windows/juce_ComponentPeer.h +++ b/modules/juce_gui_basics/windows/juce_ComponentPeer.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -168,6 +167,12 @@ public: /** Converts a screen area to a position relative to the top-left of this component. */ virtual Rectangle<int> globalToLocal (const Rectangle<int>& screenPosition); + /** Converts a rectangle relative to the top-left of this component to screen coordinates. */ + Rectangle<float> localToGlobal (const Rectangle<float>& relativePosition); + + /** Converts a screen area to a position relative to the top-left of this component. */ + Rectangle<float> globalToLocal (const Rectangle<float>& screenPosition); + /** Returns the area in peer coordinates that is covered by the given sub-comp (which may be at any depth) */ diff --git a/modules/juce_gui_basics/windows/juce_DialogWindow.cpp b/modules/juce_gui_basics/windows/juce_DialogWindow.cpp index 9f99b66f..ea2675d5 100644 --- a/modules/juce_gui_basics/windows/juce_DialogWindow.cpp +++ b/modules/juce_gui_basics/windows/juce_DialogWindow.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/windows/juce_DialogWindow.h b/modules/juce_gui_basics/windows/juce_DialogWindow.h index 92583f74..a1021152 100644 --- a/modules/juce_gui_basics/windows/juce_DialogWindow.h +++ b/modules/juce_gui_basics/windows/juce_DialogWindow.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/windows/juce_DocumentWindow.cpp b/modules/juce_gui_basics/windows/juce_DocumentWindow.cpp index 2a3bcf84..d5d434e0 100644 --- a/modules/juce_gui_basics/windows/juce_DocumentWindow.cpp +++ b/modules/juce_gui_basics/windows/juce_DocumentWindow.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/windows/juce_DocumentWindow.h b/modules/juce_gui_basics/windows/juce_DocumentWindow.h index 0d2ba3c8..4fc4d076 100644 --- a/modules/juce_gui_basics/windows/juce_DocumentWindow.h +++ b/modules/juce_gui_basics/windows/juce_DocumentWindow.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/windows/juce_NativeMessageBox.h b/modules/juce_gui_basics/windows/juce_NativeMessageBox.h index 21776255..70b097a5 100644 --- a/modules/juce_gui_basics/windows/juce_NativeMessageBox.h +++ b/modules/juce_gui_basics/windows/juce_NativeMessageBox.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/windows/juce_ResizableWindow.cpp b/modules/juce_gui_basics/windows/juce_ResizableWindow.cpp index dc46a229..d2360e5f 100644 --- a/modules/juce_gui_basics/windows/juce_ResizableWindow.cpp +++ b/modules/juce_gui_basics/windows/juce_ResizableWindow.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -64,12 +63,12 @@ void ResizableWindow::initialise (const bool shouldAddToDesktop) /* ========================================================================== - In accordance with the terms of the JUCE 5 End-Use License Agreement, the + In accordance with the terms of the JUCE 6 End-Use License Agreement, the JUCE Code in SECTION A cannot be removed, changed or otherwise rendered ineffective unless you have a JUCE Indie or Pro license, or are using JUCE under the GPL v3 license. - End User License Agreement: www.juce.com/juce-5-licence + End User License Agreement: www.juce.com/juce-6-licence ========================================================================== */ @@ -565,7 +564,7 @@ bool ResizableWindow::restoreWindowStateFromString (const String& s) if (onScreenArea.getWidth() * onScreenArea.getHeight() < 32 * 32) { - auto screen = desktop.getDisplays().findDisplayForRect (newPos).userArea; + auto screen = desktop.getDisplays().getDisplayForRect (newPos)->userArea; newPos.setSize (jmin (newPos.getWidth(), screen.getWidth()), jmin (newPos.getHeight(), screen.getHeight())); diff --git a/modules/juce_gui_basics/windows/juce_ResizableWindow.h b/modules/juce_gui_basics/windows/juce_ResizableWindow.h index cf1ab85a..d6730359 100644 --- a/modules/juce_gui_basics/windows/juce_ResizableWindow.h +++ b/modules/juce_gui_basics/windows/juce_ResizableWindow.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/windows/juce_ThreadWithProgressWindow.cpp b/modules/juce_gui_basics/windows/juce_ThreadWithProgressWindow.cpp index 346ae7d4..b2d0d497 100644 --- a/modules/juce_gui_basics/windows/juce_ThreadWithProgressWindow.cpp +++ b/modules/juce_gui_basics/windows/juce_ThreadWithProgressWindow.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/windows/juce_ThreadWithProgressWindow.h b/modules/juce_gui_basics/windows/juce_ThreadWithProgressWindow.h index 2927b14f..91664e0c 100644 --- a/modules/juce_gui_basics/windows/juce_ThreadWithProgressWindow.h +++ b/modules/juce_gui_basics/windows/juce_ThreadWithProgressWindow.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/windows/juce_TooltipWindow.cpp b/modules/juce_gui_basics/windows/juce_TooltipWindow.cpp index b1b6519f..c893c8d9 100644 --- a/modules/juce_gui_basics/windows/juce_TooltipWindow.cpp +++ b/modules/juce_gui_basics/windows/juce_TooltipWindow.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -92,7 +91,7 @@ void TooltipWindow::displayTip (Point<int> screenPos, const String& tip) } else { - updatePosition (tip, screenPos, Desktop::getInstance().getDisplays().findDisplayForPoint (screenPos).userArea); + updatePosition (tip, screenPos, Desktop::getInstance().getDisplays().getDisplayForPoint (screenPos)->userArea); addToDesktop (ComponentPeer::windowHasDropShadow | ComponentPeer::windowIsTemporary diff --git a/modules/juce_gui_basics/windows/juce_TooltipWindow.h b/modules/juce_gui_basics/windows/juce_TooltipWindow.h index e668c8ed..f82cbf6a 100644 --- a/modules/juce_gui_basics/windows/juce_TooltipWindow.h +++ b/modules/juce_gui_basics/windows/juce_TooltipWindow.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/windows/juce_TopLevelWindow.cpp b/modules/juce_gui_basics/windows/juce_TopLevelWindow.cpp index 7f0f271b..75fe2f91 100644 --- a/modules/juce_gui_basics/windows/juce_TopLevelWindow.cpp +++ b/modules/juce_gui_basics/windows/juce_TopLevelWindow.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_basics/windows/juce_TopLevelWindow.h b/modules/juce_gui_basics/windows/juce_TopLevelWindow.h index 0bc0fa7b..b11d90b2 100644 --- a/modules/juce_gui_basics/windows/juce_TopLevelWindow.h +++ b/modules/juce_gui_basics/windows/juce_TopLevelWindow.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniser.cpp b/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniser.cpp index 81a067c8..e6a7dcf0 100644 --- a/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniser.cpp +++ b/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniser.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniser.h b/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniser.h index 84cf9305..784bc2d5 100644 --- a/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniser.h +++ b/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniser.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniserFunctions.h b/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniserFunctions.h index 6fce1baa..896dc9e2 100644 --- a/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniserFunctions.h +++ b/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniserFunctions.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -616,8 +615,8 @@ struct CppTokeniserFunctions charsOnLine += 2; break; } - // deliberate fall-through... + JUCE_FALLTHROUGH default: if (c >= 32 && c < 127 && ! (lastWasHexEscapeCode // (have to avoid following a hex escape sequence with a valid hex digit) diff --git a/modules/juce_gui_extra/code_editor/juce_CodeDocument.cpp b/modules/juce_gui_extra/code_editor/juce_CodeDocument.cpp index 6db2143d..c4e32fbe 100644 --- a/modules/juce_gui_extra/code_editor/juce_CodeDocument.cpp +++ b/modules/juce_gui_extra/code_editor/juce_CodeDocument.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -751,7 +750,7 @@ bool CodeDocument::hasChangedSinceSavePoint() const noexcept } //============================================================================== -static inline int getCharacterType (juce_wchar character) noexcept +static int getCharacterType (juce_wchar character) noexcept { return (CharacterFunctions::isLetterOrDigit (character) || character == '_') ? 2 : (CharacterFunctions::isWhitespace (character) ? 0 : 1); diff --git a/modules/juce_gui_extra/code_editor/juce_CodeDocument.h b/modules/juce_gui_extra/code_editor/juce_CodeDocument.h index e9b5fde8..21eda641 100644 --- a/modules/juce_gui_extra/code_editor/juce_CodeDocument.h +++ b/modules/juce_gui_extra/code_editor/juce_CodeDocument.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.cpp b/modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.cpp index 30817dba..0ac45323 100644 --- a/modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.cpp +++ b/modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -86,8 +85,8 @@ public: void getHighlightArea (RectangleList<float>& area, float x, int y, int lineH, float characterWidth) const { if (highlightColumnStart < highlightColumnEnd) - area.add (Rectangle<float> (x + highlightColumnStart * characterWidth - 1.0f, y - 0.5f, - (highlightColumnEnd - highlightColumnStart) * characterWidth + 1.5f, lineH + 1.0f)); + area.add (Rectangle<float> (x + (float) highlightColumnStart * characterWidth - 1.0f, (float) y - 0.5f, + (float) (highlightColumnEnd - highlightColumnStart) * characterWidth + 1.5f, (float) lineH + 1.0f)); } void draw (CodeEditorComponent& owner, Graphics& g, const Font& fontToUse, @@ -101,7 +100,7 @@ public: for (auto& token : tokens) { - const float tokenX = x + column * characterWidth; + const float tokenX = x + (float) column * characterWidth; if (tokenX > rightClip) break; @@ -109,7 +108,7 @@ public: column += token.length; } - as.draw (g, { x, (float) y, column * characterWidth + 10.0f, (float) lineH }); + as.draw (g, { x, (float) y, (float) column * characterWidth + 10.0f, (float) lineH }); } private: @@ -302,7 +301,7 @@ public: lastNumLines - editor.firstLineOnScreen); auto lineNumberFont = editor.getFont().withHeight (jmin (13.0f, lineHeightFloat * 0.8f)); - auto w = getWidth() - 2.0f; + auto w = (float) getWidth() - 2.0f; GlyphArrangement ga; for (int i = firstLineToDraw; i < lastLineToDraw; ++i) @@ -349,7 +348,7 @@ CodeEditorComponent::CodeEditorComponent (CodeDocument& doc, CodeTokeniser* cons setMouseCursor (MouseCursor::IBeamCursor); setWantsKeyboardFocus (true); - caret.reset (getLookAndFeel().createCaretComponent (this)); + lookAndFeelChanged(); addAndMakeVisible (caret.get()); addAndMakeVisible (verticalScrollBar); @@ -444,7 +443,7 @@ void CodeEditorComponent::resized() { auto visibleWidth = getWidth() - scrollbarThickness - getGutterSize(); linesOnScreen = jmax (1, (getHeight() - scrollbarThickness) / lineHeight); - columnsOnScreen = jmax (1, (int) (visibleWidth / charWidth)); + columnsOnScreen = jmax (1, (int) ((float) visibleWidth / charWidth)); lines.clear(); rebuildLineTokens(); updateCaretPosition(); @@ -738,7 +737,7 @@ void CodeEditorComponent::scrollToKeepCaretOnScreen() Rectangle<int> CodeEditorComponent::getCharacterBounds (const CodeDocument::Position& pos) const { - return { roundToInt ((getGutterSize() - xOffset * charWidth) + indexToColumn (pos.getLineNumber(), pos.getIndexInLine()) * charWidth), + return { roundToInt ((getGutterSize() - xOffset * charWidth) + (float) indexToColumn (pos.getLineNumber(), pos.getIndexInLine()) * charWidth), (pos.getLineNumber() - firstLineOnScreen) * lineHeight, roundToInt (charWidth), lineHeight }; @@ -1316,6 +1315,11 @@ bool CodeEditorComponent::perform (const InvocationInfo& info) return performCommand (info.commandID); } +void CodeEditorComponent::lookAndFeelChanged() +{ + caret.reset (getLookAndFeel().createCaretComponent (this)); +} + bool CodeEditorComponent::performCommand (const CommandID commandID) { switch (commandID) diff --git a/modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.h b/modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.h index bde97610..29617a15 100644 --- a/modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.h +++ b/modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -379,6 +378,8 @@ public: void getCommandInfo (CommandID, ApplicationCommandInfo&) override; /** @internal */ bool perform (const InvocationInfo&) override; + /** @internal */ + void lookAndFeelChanged() override; private: //============================================================================== diff --git a/modules/juce_gui_extra/code_editor/juce_CodeTokeniser.h b/modules/juce_gui_extra/code_editor/juce_CodeTokeniser.h index 75bdea6c..c398ae67 100644 --- a/modules/juce_gui_extra/code_editor/juce_CodeTokeniser.h +++ b/modules/juce_gui_extra/code_editor/juce_CodeTokeniser.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.cpp b/modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.cpp index b8e7d0b2..99a3dada 100644 --- a/modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.cpp +++ b/modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.h b/modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.h index 6657b8b2..8e1f39a6 100644 --- a/modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.h +++ b/modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.cpp b/modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.cpp index a30a1612..be04178f 100644 --- a/modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.cpp +++ b/modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.h b/modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.h index f577efbb..0025c2b4 100644 --- a/modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.h +++ b/modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_extra/documents/juce_FileBasedDocument.cpp b/modules/juce_gui_extra/documents/juce_FileBasedDocument.cpp index 2edffd32..aa4f64a6 100644 --- a/modules/juce_gui_extra/documents/juce_FileBasedDocument.cpp +++ b/modules/juce_gui_extra/documents/juce_FileBasedDocument.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -31,8 +30,7 @@ FileBasedDocument::FileBasedDocument (const String& fileExtension_, const String& fileWildcard_, const String& openFileDialogTitle_, const String& saveFileDialogTitle_) - : changedSinceSave (false), - fileExtension (fileExtension_), + : fileExtension (fileExtension_), fileWildcard (fileWildcard_), openFileDialogTitle (openFileDialogTitle_), saveFileDialogTitle (saveFileDialogTitle_) @@ -44,7 +42,7 @@ FileBasedDocument::~FileBasedDocument() } //============================================================================== -void FileBasedDocument::setChangedFlag (const bool hasChanged) +void FileBasedDocument::setChangedFlag (bool hasChanged) { if (changedSinceSave != hasChanged) { @@ -70,14 +68,15 @@ void FileBasedDocument::setFile (const File& newFile) } //============================================================================== -Result FileBasedDocument::loadFrom (const File& newFile, const bool showMessageOnFailure) +Result FileBasedDocument::loadFrom (const File& newFile, bool showMessageOnFailure, bool showWaitCursor) { - MouseCursor::showWaitCursor(); + if (showWaitCursor) + MouseCursor::showWaitCursor(); - const File oldFile (documentFile); + auto oldFile = documentFile; documentFile = newFile; - Result result (Result::fail (TRANS("The file doesn't exist"))); + auto result = Result::fail (TRANS("The file doesn't exist")); if (newFile.existsAsFile()) { @@ -86,7 +85,9 @@ Result FileBasedDocument::loadFrom (const File& newFile, const bool showMessageO if (result.wasOk()) { setChangedFlag (false); - MouseCursor::hideWaitCursor(); + + if (showWaitCursor) + MouseCursor::hideWaitCursor(); setLastDocumentOpened (newFile); return result; @@ -94,7 +95,9 @@ Result FileBasedDocument::loadFrom (const File& newFile, const bool showMessageO } documentFile = oldFile; - MouseCursor::hideWaitCursor(); + + if (showWaitCursor) + MouseCursor::hideWaitCursor(); if (showMessageOnFailure) AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon, @@ -133,8 +136,8 @@ static bool askToOverwriteFile (const File& newFile) } //============================================================================== -FileBasedDocument::SaveResult FileBasedDocument::save (const bool askUserForFileIfNotSpecified, - const bool showMessageOnFailure) +FileBasedDocument::SaveResult FileBasedDocument::save (bool askUserForFileIfNotSpecified, + bool showMessageOnFailure) { return saveAs (documentFile, false, @@ -143,9 +146,10 @@ FileBasedDocument::SaveResult FileBasedDocument::save (const bool askUserForFile } FileBasedDocument::SaveResult FileBasedDocument::saveAs (const File& newFile, - const bool warnAboutOverwritingExistingFiles, - const bool askUserForFileIfNotSpecified, - const bool showMessageOnFailure) + bool warnAboutOverwritingExistingFiles, + bool askUserForFileIfNotSpecified, + bool showMessageOnFailure, + bool showWaitCursor) { if (newFile == File()) { @@ -162,24 +166,29 @@ FileBasedDocument::SaveResult FileBasedDocument::saveAs (const File& newFile, && ! askToOverwriteFile (newFile)) return userCancelledSave; - MouseCursor::showWaitCursor(); + if (showWaitCursor) + MouseCursor::showWaitCursor(); - const File oldFile (documentFile); + auto oldFile = documentFile; documentFile = newFile; - const Result result (saveDocument (newFile)); + auto result = saveDocument (newFile); if (result.wasOk()) { setChangedFlag (false); - MouseCursor::hideWaitCursor(); + + if (showWaitCursor) + MouseCursor::hideWaitCursor(); sendChangeMessage(); // because the filename may have changed return savedOk; } documentFile = oldFile; - MouseCursor::hideWaitCursor(); + + if (showWaitCursor) + MouseCursor::hideWaitCursor(); if (showMessageOnFailure) AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon, @@ -199,13 +208,13 @@ FileBasedDocument::SaveResult FileBasedDocument::saveIfNeededAndUserAgrees() if (! hasChangedSinceSaved()) return savedOk; - const int r = AlertWindow::showYesNoCancelBox (AlertWindow::QuestionIcon, - TRANS("Closing document..."), - TRANS("Do you want to save the changes to \"DCNM\"?") - .replace ("DCNM", getDocumentTitle()), - TRANS("Save"), - TRANS("Discard changes"), - TRANS("Cancel")); + auto r = AlertWindow::showYesNoCancelBox (AlertWindow::QuestionIcon, + TRANS("Closing document..."), + TRANS("Do you want to save the changes to \"DCNM\"?") + .replace ("DCNM", getDocumentTitle()), + TRANS("Save"), + TRANS("Discard changes"), + TRANS("Cancel")); if (r == 1) // save changes return save (true, true); @@ -221,16 +230,11 @@ File FileBasedDocument::getSuggestedSaveAsFile (const File& defaultFile) return defaultFile.withFileExtension (fileExtension).getNonexistentSibling (true); } -FileBasedDocument::SaveResult FileBasedDocument::saveAsInteractive (const bool warnAboutOverwritingExistingFiles) +FileBasedDocument::SaveResult FileBasedDocument::saveAsInteractive (bool warnAboutOverwritingExistingFiles) { - File f; + auto f = documentFile.existsAsFile() ? documentFile : getLastDocumentOpened(); - if (documentFile.existsAsFile()) - f = documentFile; - else - f = getLastDocumentOpened(); - - String legalFilename (File::createLegalFileName (getDocumentTitle())); + auto legalFilename = File::createLegalFileName (getDocumentTitle()); if (legalFilename.isEmpty()) legalFilename = "unnamed"; @@ -246,7 +250,8 @@ FileBasedDocument::SaveResult FileBasedDocument::saveAsInteractive (const bool w if (fc.browseForFileToSave (warnAboutOverwritingExistingFiles)) { - File chosen (fc.getResult()); + auto chosen = fc.getResult(); + if (chosen.getFileExtension().isEmpty()) { chosen = chosen.withFileExtension (fileExtension); diff --git a/modules/juce_gui_extra/documents/juce_FileBasedDocument.h b/modules/juce_gui_extra/documents/juce_FileBasedDocument.h index 05428d80..8e929c76 100644 --- a/modules/juce_gui_extra/documents/juce_FileBasedDocument.h +++ b/modules/juce_gui_extra/documents/juce_FileBasedDocument.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -108,7 +107,8 @@ public: @see loadDocument, loadFromUserSpecifiedFile */ Result loadFrom (const File& fileToLoadFrom, - bool showMessageOnFailure); + bool showMessageOnFailure, + bool showWaitCursor = true); /** Asks the user for a file and tries to load it. @@ -183,12 +183,15 @@ public: filename @param showMessageOnFailure if true and the write operation fails, it'll show a message box to warn the user + @param showWaitCursor if true, the 'wait' mouse cursor will be showin during + saving @see saveIfNeededAndUserAgrees, save, saveAsInteractive */ SaveResult saveAs (const File& newFile, bool warnAboutOverwritingExistingFiles, bool askUserForFileIfNotSpecified, - bool showMessageOnFailure); + bool showMessageOnFailure, + bool showWaitCursor = true); /** Prompts the user for a filename and tries to save to it. @@ -287,7 +290,7 @@ protected: private: //============================================================================== File documentFile; - bool changedSinceSave; + bool changedSinceSave = false; String fileExtension, fileWildcard, openFileDialogTitle, saveFileDialogTitle; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FileBasedDocument) diff --git a/modules/juce_gui_extra/embedding/juce_ActiveXControlComponent.h b/modules/juce_gui_extra/embedding/juce_ActiveXControlComponent.h index 89d53723..9e240e13 100644 --- a/modules/juce_gui_extra/embedding/juce_ActiveXControlComponent.h +++ b/modules/juce_gui_extra/embedding/juce_ActiveXControlComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_extra/embedding/juce_AndroidViewComponent.h b/modules/juce_gui_extra/embedding/juce_AndroidViewComponent.h index 440b5a66..3de06939 100644 --- a/modules/juce_gui_extra/embedding/juce_AndroidViewComponent.h +++ b/modules/juce_gui_extra/embedding/juce_AndroidViewComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -38,7 +37,7 @@ namespace juce moved and resized to follow the movements of this component. Of course, since the view is a native object, it'll obliterate any - juce components that may overlap this component, but that's life. + JUCE components that may overlap this component, but that's life. @tags{GUI} */ diff --git a/modules/juce_gui_extra/embedding/juce_HWNDComponent.h b/modules/juce_gui_extra/embedding/juce_HWNDComponent.h new file mode 100644 index 00000000..34761652 --- /dev/null +++ b/modules/juce_gui_extra/embedding/juce_HWNDComponent.h @@ -0,0 +1,83 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ + +#if JUCE_WINDOWS || DOXYGEN + +//============================================================================== +/** + A Windows-specific class that can create and embed a HWND inside itself. + + To use it, create one of these, put it in place and make sure it's visible in a + window, then use setHWND() to assign a HWND to it. The window will then be + moved and resized to follow the movements of this component. + + Of course, since the window is a native object, it'll obliterate any + JUCE components that may overlap this component, but that's life. + + @tags{GUI} +*/ +class JUCE_API HWNDComponent : public Component +{ +public: + //============================================================================== + /** Create an initially-empty container. */ + HWNDComponent(); + + /** Destructor. */ + ~HWNDComponent() override; + + /** Assigns a HWND to this peer. + + The window will be retained and released by this component for as long as + it is needed. To remove the current HWND, just call setHWND (nullptr). + + Note: A void* is used here to avoid including the Windows headers as + part of JuceHeader.h, but the method expects a HWND. + */ + void setHWND (void* hwnd); + + /** Returns the current HWND. + + Note: A void* is returned here to avoid the needing to include the Windows + headers, so you should just cast the return value to a HWND. + */ + void* getHWND() const; + + /** Resizes this component to fit the HWND that it contains. */ + void resizeToFit(); + +private: + class Pimpl; + std::unique_ptr<Pimpl> pimpl; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (HWNDComponent) +}; + +#endif + +} // namespace juce diff --git a/modules/juce_gui_extra/embedding/juce_NSViewComponent.h b/modules/juce_gui_extra/embedding/juce_NSViewComponent.h index 4664a55b..897cc5e6 100644 --- a/modules/juce_gui_extra/embedding/juce_NSViewComponent.h +++ b/modules/juce_gui_extra/embedding/juce_NSViewComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -38,7 +37,7 @@ namespace juce moved and resized to follow the movements of this component. Of course, since the view is a native object, it'll obliterate any - juce components that may overlap this component, but that's life. + JUCE components that may overlap this component, but that's life. @tags{GUI} */ @@ -58,7 +57,7 @@ public: it is needed. To remove the current view, just call setView (nullptr). Note: A void* is used here to avoid including the cocoa headers as - part of the juce.h, but the method expects an NSView*. + part of JuceHeader.h, but the method expects an NSView*. */ void setView (void* nsView); @@ -69,7 +68,6 @@ public: */ void* getView() const; - /** Resizes this component to fit the view that it contains. */ void resizeToFitView(); diff --git a/modules/juce_gui_extra/embedding/juce_ScopedDPIAwarenessDisabler.h b/modules/juce_gui_extra/embedding/juce_ScopedDPIAwarenessDisabler.h index 4894cb13..cb9644b7 100644 --- a/modules/juce_gui_extra/embedding/juce_ScopedDPIAwarenessDisabler.h +++ b/modules/juce_gui_extra/embedding/juce_ScopedDPIAwarenessDisabler.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_extra/embedding/juce_UIViewComponent.h b/modules/juce_gui_extra/embedding/juce_UIViewComponent.h index 90c4bc60..357551b3 100644 --- a/modules/juce_gui_extra/embedding/juce_UIViewComponent.h +++ b/modules/juce_gui_extra/embedding/juce_UIViewComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -38,7 +37,7 @@ namespace juce moved and resized to follow the movements of this component. Of course, since the view is a native object, it'll obliterate any - juce components that may overlap this component, but that's life. + JUCE components that may overlap this component, but that's life. @tags{GUI} */ @@ -58,7 +57,7 @@ public: it is needed. To remove the current view, just call setView (nullptr). Note: A void* is used here to avoid including the cocoa headers as - part of the juce.h, but the method expects an UIView*. + part of JuceHeader.h, but the method expects an UIView*. */ void setView (void* uiView); @@ -69,7 +68,6 @@ public: */ void* getView() const; - /** Resizes this component to fit the view that it contains. */ void resizeToFitView(); diff --git a/modules/juce_gui_extra/embedding/juce_XEmbedComponent.h b/modules/juce_gui_extra/embedding/juce_XEmbedComponent.h index 9d431c65..9eb8e97b 100644 --- a/modules/juce_gui_extra/embedding/juce_XEmbedComponent.h +++ b/modules/juce_gui_extra/embedding/juce_XEmbedComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -94,6 +93,9 @@ public: */ unsigned long getHostWindowID(); + /** Removes the client window from the host. */ + void removeClient(); + protected: //============================================================================== /** @internal */ diff --git a/modules/juce_gui_extra/juce_gui_extra.cpp b/modules/juce_gui_extra/juce_gui_extra.cpp index 3be2cad4..d4ebed7f 100644 --- a/modules/juce_gui_extra/juce_gui_extra.cpp +++ b/modules/juce_gui_extra/juce_gui_extra.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -39,6 +38,11 @@ #define JUCE_CORE_INCLUDE_NATIVE_HEADERS 1 #define JUCE_EVENTS_INCLUDE_WIN32_MESSAGE_WINDOW 1 #define JUCE_GRAPHICS_INCLUDE_COREGRAPHICS_HELPERS 1 +#define JUCE_GUI_BASICS_INCLUDE_XHEADERS 1 + +#if JUCE_USE_WIN_WEBVIEW2 + #define JUCE_EVENTS_INCLUDE_WINRT_WRAPPER 1 +#endif #ifndef JUCE_PUSH_NOTIFICATIONS #define JUCE_PUSH_NOTIFICATIONS 0 @@ -63,6 +67,8 @@ //============================================================================== #elif JUCE_IOS + #import <WebKit/WebKit.h> + #if JUCE_PUSH_NOTIFICATIONS #if defined (__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 #import <UserNotifications/UserNotifications.h> @@ -86,52 +92,40 @@ #if JUCE_WEB_BROWSER #include <exdisp.h> #include <exdispid.h> - #endif -//============================================================================== -#elif JUCE_LINUX - #include <X11/Xlib.h> - #include <X11/Xatom.h> - #include <X11/Xutil.h> - #undef SIZEOF - #undef KeyPress + #if JUCE_USE_WIN_WEBVIEW2 + #include <windows.foundation.h> + #include <windows.foundation.collections.h> - #if JUCE_WEB_BROWSER - #include <unistd.h> - #include <fcntl.h> - #include <sys/wait.h> - - #if JUCE_GCC - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - #if __GNUC__ > 7 - #pragma GCC diagnostic ignored "-Wparentheses" - #endif - #endif + #pragma warning (push) + #pragma warning (disable: 4265) + #include <wrl.h> + #include <wrl/wrappers/corewrappers.h> + #pragma warning (pop) - #if JUCE_CLANG - #if __has_warning("-Wzero-as-null-pointer-constant") - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" - #endif + #include "WebView2.h" + + #pragma warning (push) + #pragma warning (disable: 4458) + #include "WebView2EnvironmentOptions.h" + #pragma warning (pop) #endif - #include <gtk/gtk.h> + #endif + +//============================================================================== +#elif JUCE_LINUX && JUCE_WEB_BROWSER + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wzero-as-null-pointer-constant", "-Wparentheses") - #if JUCE_GCC - #pragma GCC diagnostic pop - #endif + // If you're missing this header, you need to install the webkit2gtk-4.0 package + #include <gtk/gtk.h> - #if JUCE_CLANG - #if __has_warning("-Wzero-as-null-pointer-constant") - #pragma clang diagnostic pop - #endif - #endif + JUCE_END_IGNORE_WARNINGS_GCC_LIKE - #include <gtk/gtkx.h> - #include <glib-unix.h> - #include <webkit2/webkit2.h> - #endif + // If you're missing these headers, you need to install the webkit2gtk-4.0 package + #include <gtk/gtkx.h> + #include <glib-unix.h> + #include <webkit2/webkit2.h> #endif //============================================================================== @@ -155,10 +149,7 @@ //============================================================================== #if JUCE_MAC || JUCE_IOS - #if JUCE_CLANG - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wundeclared-selector" - #endif + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wundeclared-selector") #if JUCE_MAC #include "native/juce_mac_NSViewComponent.mm" @@ -174,13 +165,12 @@ #include "native/juce_mac_WebBrowserComponent.mm" #endif - #if JUCE_CLANG - #pragma clang diagnostic pop - #endif + JUCE_END_IGNORE_WARNINGS_GCC_LIKE //============================================================================== #elif JUCE_WINDOWS #include "native/juce_win32_ActiveXComponent.cpp" + #include "native/juce_win32_HWNDComponent.cpp" #if JUCE_WEB_BROWSER #include "native/juce_win32_WebBrowserComponent.cpp" #endif @@ -188,10 +178,7 @@ //============================================================================== #elif JUCE_LINUX - #if JUCE_GCC - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - #endif + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wzero-as-null-pointer-constant") #include "native/juce_linux_XEmbedComponent.cpp" @@ -199,9 +186,7 @@ #include "native/juce_linux_X11_WebBrowserComponent.cpp" #endif - #if JUCE_GCC - #pragma GCC diagnostic pop - #endif + JUCE_END_IGNORE_WARNINGS_GCC_LIKE #include "native/juce_linux_X11_SystemTrayIcon.cpp" @@ -213,14 +198,3 @@ #include "native/juce_android_WebBrowserComponent.cpp" #endif #endif - -#if JUCE_WEB_BROWSER -namespace juce -{ - bool WebBrowserComponent::pageAboutToLoad (const String&) { return true; } - void WebBrowserComponent::pageFinishedLoading (const String&) {} - bool WebBrowserComponent::pageLoadHadNetworkError (const String&) { return true; } - void WebBrowserComponent::windowCloseRequest() {} - void WebBrowserComponent::newWindowAttemptingToLoad (const String&) {} -} -#endif diff --git a/modules/juce_gui_extra/juce_gui_extra.h b/modules/juce_gui_extra/juce_gui_extra.h index 7aaf5555..8808aa98 100644 --- a/modules/juce_gui_extra/juce_gui_extra.h +++ b/modules/juce_gui_extra/juce_gui_extra.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -29,14 +28,14 @@ The block below describes the properties of this module, and is read by the Projucer to automatically generate project code that uses it. For details about the syntax and how to create or use a module, see the - JUCE Module Format.txt file. + JUCE Module Format.md file. BEGIN_JUCE_MODULE_DECLARATION ID: juce_gui_extra vendor: juce - version: 5.4.7 + version: 6.0.5 name: JUCE extended GUI classes description: Miscellaneous GUI classes for specialised tasks. website: http://www.juce.com/juce @@ -44,6 +43,7 @@ dependencies: juce_gui_basics OSXFrameworks: WebKit + iOSFrameworks: WebKit END_JUCE_MODULE_DECLARATION @@ -57,13 +57,29 @@ //============================================================================== /** Config: JUCE_WEB_BROWSER - This lets you disable the WebBrowserComponent class (Mac and Windows). + This lets you disable the WebBrowserComponent class. If you're not using any embedded web-pages, turning this off may reduce your code size. */ #ifndef JUCE_WEB_BROWSER #define JUCE_WEB_BROWSER 1 #endif +/** Config: JUCE_USE_WIN_WEBVIEW2 + Enables the use of the Microsoft Edge (Chromium) WebView2 browser on Windows, + currently in developer preview. + + If using the Projucer, the Microsoft.Web.WebView2 package will be added to the + project solution if this flag is enabled. If you are building using CMake you + will need to manually add the package via the Visual Studio package manager. + + In addition to enabling this macro, you will need to use the + WindowsWebView2WebBrowserComponent wrapper - see the documentation of that + class for more details. +*/ +#ifndef JUCE_USE_WIN_WEBVIEW2 + #define JUCE_USE_WIN_WEBVIEW2 0 +#endif + /** Config: JUCE_ENABLE_LIVE_CONSTANT_EDITOR This lets you turn on the JUCE_ENABLE_LIVE_CONSTANT_EDITOR support (desktop only). By default this will be enabled for debug builds and disabled for release builds. See the documentation @@ -90,6 +106,7 @@ #include "embedding/juce_UIViewComponent.h" #include "embedding/juce_XEmbedComponent.h" #include "embedding/juce_ScopedDPIAwarenessDisabler.h" +#include "embedding/juce_HWNDComponent.h" #include "misc/juce_AppleRemote.h" #include "misc/juce_BubbleMessageComponent.h" #include "misc/juce_ColourSelector.h" diff --git a/modules/juce_gui_extra/juce_gui_extra.mm b/modules/juce_gui_extra/juce_gui_extra.mm index 5a7f8635..5a580dc0 100644 --- a/modules/juce_gui_extra/juce_gui_extra.mm +++ b/modules/juce_gui_extra/juce_gui_extra.mm @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_extra/misc/juce_AnimatedAppComponent.cpp b/modules/juce_gui_extra/misc/juce_AnimatedAppComponent.cpp index 424b9731..70ea8557 100644 --- a/modules/juce_gui_extra/misc/juce_AnimatedAppComponent.cpp +++ b/modules/juce_gui_extra/misc/juce_AnimatedAppComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_extra/misc/juce_AnimatedAppComponent.h b/modules/juce_gui_extra/misc/juce_AnimatedAppComponent.h index 0872e7ca..34f63e1c 100644 --- a/modules/juce_gui_extra/misc/juce_AnimatedAppComponent.h +++ b/modules/juce_gui_extra/misc/juce_AnimatedAppComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_extra/misc/juce_AppleRemote.h b/modules/juce_gui_extra/misc/juce_AppleRemote.h index 08be5dd8..41f22cc7 100644 --- a/modules/juce_gui_extra/misc/juce_AppleRemote.h +++ b/modules/juce_gui_extra/misc/juce_AppleRemote.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_extra/misc/juce_BubbleMessageComponent.cpp b/modules/juce_gui_extra/misc/juce_BubbleMessageComponent.cpp index a3aa0740..520e6e73 100644 --- a/modules/juce_gui_extra/misc/juce_BubbleMessageComponent.cpp +++ b/modules/juce_gui_extra/misc/juce_BubbleMessageComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -98,7 +97,7 @@ void BubbleMessageComponent::paintContent (Graphics& g, int w, int h) g.setColour (findColour (TooltipWindow::textColourId)); textLayout.draw (g, Rectangle<float> (bubblePaddingX / 2.0f, bubblePaddingY / 2.0f, - w - bubblePaddingX, h - bubblePaddingY)); + (float) w - bubblePaddingX, (float) h - bubblePaddingY)); } void BubbleMessageComponent::timerCallback() diff --git a/modules/juce_gui_extra/misc/juce_BubbleMessageComponent.h b/modules/juce_gui_extra/misc/juce_BubbleMessageComponent.h index a3ad36aa..437db81b 100644 --- a/modules/juce_gui_extra/misc/juce_BubbleMessageComponent.h +++ b/modules/juce_gui_extra/misc/juce_BubbleMessageComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -64,9 +63,6 @@ public: This shows the bubble with its stem pointing to the given location (coordinates being relative to its parent component). - For details about exactly how it decides where to position itself, see - BubbleComponent::updatePosition(). - @param position the coords of the object to point to @param message the text to display @param numMillisecondsBeforeRemoving how long to leave it on the screen before removing itself @@ -87,9 +83,6 @@ public: This shows the bubble with its stem pointing at the given component. - For details about exactly how it decides where to position itself, see - BubbleComponent::updatePosition(). - @param component the component that you want to point at @param message the text to display @param numMillisecondsBeforeRemoving how long to leave it on the screen before removing itself diff --git a/modules/juce_gui_extra/misc/juce_ColourSelector.cpp b/modules/juce_gui_extra/misc/juce_ColourSelector.cpp index 5c98a4e6..faa1a73d 100644 --- a/modules/juce_gui_extra/misc/juce_ColourSelector.cpp +++ b/modules/juce_gui_extra/misc/juce_ColourSelector.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -68,11 +67,11 @@ public: for (int y = 0; y < height; ++y) { - auto val = 1.0f - y / (float) height; + auto val = 1.0f - (float) y / (float) height; for (int x = 0; x < width; ++x) { - auto sat = x / (float) width; + auto sat = (float) x / (float) width; pixels.setPixelColour (x, y, Colour (h, sat, val, 1.0f)); } } @@ -93,8 +92,8 @@ public: void mouseDrag (const MouseEvent& e) override { - auto sat = (e.x - edge) / (float) (getWidth() - edge * 2); - auto val = 1.0f - (e.y - edge) / (float) (getHeight() - edge * 2); + auto sat = (float) (e.x - edge) / (float) (getWidth() - edge * 2); + auto val = 1.0f - (float) (e.y - edge) / (float) (getHeight() - edge * 2); owner.setSV (sat, val); } @@ -136,9 +135,9 @@ private: void paint (Graphics& g) override { g.setColour (Colour::greyLevel (0.1f)); - g.drawEllipse (1.0f, 1.0f, getWidth() - 2.0f, getHeight() - 2.0f, 1.0f); + g.drawEllipse (1.0f, 1.0f, (float) getWidth() - 2.0f, (float) getHeight() - 2.0f, 1.0f); g.setColour (Colour::greyLevel (0.9f)); - g.drawEllipse (2.0f, 2.0f, getWidth() - 4.0f, getHeight() - 4.0f, 1.0f); + g.drawEllipse (2.0f, 2.0f, (float) getWidth() - 4.0f, (float) getHeight() - 4.0f, 1.0f); } }; @@ -196,7 +195,7 @@ public: void mouseDrag (const MouseEvent& e) override { - owner.setHue ((e.y - edge) / (float) (getHeight() - edge * 2)); + owner.setHue ((float) (e.y - edge) / (float) (getHeight() - edge * 2)); } void updateIfNeeded() diff --git a/modules/juce_gui_extra/misc/juce_ColourSelector.h b/modules/juce_gui_extra/misc/juce_ColourSelector.h index a7c62fe0..5804c94a 100644 --- a/modules/juce_gui_extra/misc/juce_ColourSelector.h +++ b/modules/juce_gui_extra/misc/juce_ColourSelector.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_extra/misc/juce_KeyMappingEditorComponent.cpp b/modules/juce_gui_extra/misc/juce_KeyMappingEditorComponent.cpp index 70390eb0..4b8088c5 100644 --- a/modules/juce_gui_extra/misc/juce_KeyMappingEditorComponent.cpp +++ b/modules/juce_gui_extra/misc/juce_KeyMappingEditorComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -89,7 +88,7 @@ public: if (keyNum < 0) setSize (h, h); else - setSize (jlimit (h * 4, h * 8, 6 + Font (h * 0.6f).getStringWidth (getName())), h); + setSize (jlimit (h * 4, h * 8, 6 + Font ((float) h * 0.6f).getStringWidth (getName())), h); } //============================================================================== @@ -241,7 +240,7 @@ public: void paint (Graphics& g) override { - g.setFont (getHeight() * 0.7f); + g.setFont ((float) getHeight() * 0.7f); g.setColour (owner.findColour (KeyMappingEditorComponent::textColourId)); g.drawFittedText (TRANS (owner.getCommandManager().getNameOfCommand (commandID)), @@ -308,7 +307,7 @@ public: void paintItem (Graphics& g, int width, int height) override { - g.setFont (Font (height * 0.7f, Font::bold)); + g.setFont (Font ((float) height * 0.7f, Font::bold)); g.setColour (owner.findColour (KeyMappingEditorComponent::textColourId)); g.drawText (TRANS (categoryName), 2, 0, width - 2, height, Justification::centredLeft, true); diff --git a/modules/juce_gui_extra/misc/juce_KeyMappingEditorComponent.h b/modules/juce_gui_extra/misc/juce_KeyMappingEditorComponent.h index 49c21562..a9d80081 100644 --- a/modules/juce_gui_extra/misc/juce_KeyMappingEditorComponent.h +++ b/modules/juce_gui_extra/misc/juce_KeyMappingEditorComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_extra/misc/juce_LiveConstantEditor.cpp b/modules/juce_gui_extra/misc/juce_LiveConstantEditor.cpp index 08d9055b..ce6ea14f 100644 --- a/modules/juce_gui_extra/misc/juce_LiveConstantEditor.cpp +++ b/modules/juce_gui_extra/misc/juce_LiveConstantEditor.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -407,14 +406,14 @@ struct ColourEditorComp : public Component, void mouseDown (const MouseEvent&) override { - auto* colourSelector = new ColourSelector(); + auto colourSelector = std::make_unique<ColourSelector>(); colourSelector->setName ("Colour"); colourSelector->setCurrentColour (getColour()); colourSelector->addChangeListener (this); colourSelector->setColour (ColourSelector::backgroundColourId, Colours::transparentBlack); colourSelector->setSize (300, 400); - CallOutBox::launchAsynchronously (colourSelector, getScreenBounds(), nullptr); + CallOutBox::launchAsynchronously (std::move (colourSelector), getScreenBounds(), nullptr); } void changeListenerCallback (ChangeBroadcaster* source) override diff --git a/modules/juce_gui_extra/misc/juce_LiveConstantEditor.h b/modules/juce_gui_extra/misc/juce_LiveConstantEditor.h index 3230616b..a49bc01c 100644 --- a/modules/juce_gui_extra/misc/juce_LiveConstantEditor.h +++ b/modules/juce_gui_extra/misc/juce_LiveConstantEditor.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_extra/misc/juce_PreferencesPanel.cpp b/modules/juce_gui_extra/misc/juce_PreferencesPanel.cpp index 27f35c7f..f3efdc34 100644 --- a/modules/juce_gui_extra/misc/juce_PreferencesPanel.cpp +++ b/modules/juce_gui_extra/misc/juce_PreferencesPanel.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_extra/misc/juce_PreferencesPanel.h b/modules/juce_gui_extra/misc/juce_PreferencesPanel.h index 3f6db220..4ce8ab1e 100644 --- a/modules/juce_gui_extra/misc/juce_PreferencesPanel.h +++ b/modules/juce_gui_extra/misc/juce_PreferencesPanel.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_extra/misc/juce_PushNotifications.cpp b/modules/juce_gui_extra/misc/juce_PushNotifications.cpp index 4dbee0f8..04b682e2 100644 --- a/modules/juce_gui_extra/misc/juce_PushNotifications.cpp +++ b/modules/juce_gui_extra/misc/juce_PushNotifications.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_extra/misc/juce_PushNotifications.h b/modules/juce_gui_extra/misc/juce_PushNotifications.h index 4b39f2c8..f7f276f6 100644 --- a/modules/juce_gui_extra/misc/juce_PushNotifications.h +++ b/modules/juce_gui_extra/misc/juce_PushNotifications.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_extra/misc/juce_RecentlyOpenedFilesList.cpp b/modules/juce_gui_extra/misc/juce_RecentlyOpenedFilesList.cpp index 9fd53d9c..9786c087 100644 --- a/modules/juce_gui_extra/misc/juce_RecentlyOpenedFilesList.cpp +++ b/modules/juce_gui_extra/misc/juce_RecentlyOpenedFilesList.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_extra/misc/juce_RecentlyOpenedFilesList.h b/modules/juce_gui_extra/misc/juce_RecentlyOpenedFilesList.h index a56949dd..7d220858 100644 --- a/modules/juce_gui_extra/misc/juce_RecentlyOpenedFilesList.h +++ b/modules/juce_gui_extra/misc/juce_RecentlyOpenedFilesList.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_extra/misc/juce_SplashScreen.cpp b/modules/juce_gui_extra/misc/juce_SplashScreen.cpp index a33477d8..9169cfb1 100644 --- a/modules/juce_gui_extra/misc/juce_SplashScreen.cpp +++ b/modules/juce_gui_extra/misc/juce_SplashScreen.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -58,7 +57,7 @@ void SplashScreen::makeVisible (int w, int h, bool useDropShadow, bool fullscree clickCountToDelete = Desktop::getInstance().getMouseButtonClickCounter(); creationTime = Time::getCurrentTime(); - const Rectangle<int> screenSize = Desktop::getInstance().getDisplays().getMainDisplay().userArea; + const Rectangle<int> screenSize = Desktop::getInstance().getDisplays().getPrimaryDisplay()->userArea; const int width = (fullscreen ? screenSize.getWidth() : w); const int height = (fullscreen ? screenSize.getHeight() : h); diff --git a/modules/juce_gui_extra/misc/juce_SplashScreen.h b/modules/juce_gui_extra/misc/juce_SplashScreen.h index aa96a2a9..ccff70b7 100644 --- a/modules/juce_gui_extra/misc/juce_SplashScreen.h +++ b/modules/juce_gui_extra/misc/juce_SplashScreen.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.cpp b/modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.cpp index 72c6c983..52cbf28b 100644 --- a/modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.cpp +++ b/modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.h b/modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.h index c905c6f1..b5241d5b 100644 --- a/modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.h +++ b/modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_extra/misc/juce_WebBrowserComponent.h b/modules/juce_gui_extra/misc/juce_WebBrowserComponent.h index 912d87e8..4d355251 100644 --- a/modules/juce_gui_extra/misc/juce_WebBrowserComponent.h +++ b/modules/juce_gui_extra/misc/juce_WebBrowserComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -33,13 +32,17 @@ namespace juce /** A component that displays an embedded web browser. - The browser itself will be platform-dependent. On the Mac, probably Safari, on - Windows, probably IE. + The browser itself will be platform-dependent. On Mac and iOS it will be + WebKit, on Android it will be Chrome, and on Linux it will be WebKit. + On Windows it will be IE, but if JUCE_USE_WIN_WEBVIEW2 is enabled then using + the WindowsWebView2WebBrowserComponent wrapper instead of this class directly + will attempt to use the Microsoft Edge (Chromium) WebView2. See the documentation + of that class for more information about its requirements. @tags{GUI} */ -class JUCE_API WebBrowserComponent : public Component +class JUCE_API WebBrowserComponent : public Component { public: //============================================================================== @@ -95,10 +98,10 @@ public: tries to go to a particular URL. To allow the operation to carry on, return true, or return false to stop the navigation happening. */ - virtual bool pageAboutToLoad (const String& newURL); + virtual bool pageAboutToLoad (const String& newURL) { ignoreUnused (newURL); return true; } /** This callback happens when the browser has finished loading a page. */ - virtual void pageFinishedLoading (const String& url); + virtual void pageFinishedLoading (const String& url) { ignoreUnused (url); } /** This callback happens when a network error was encountered while trying to load a page. @@ -110,18 +113,18 @@ public: The errorInfo contains some platform dependent string describing the error. */ - virtual bool pageLoadHadNetworkError (const String& errorInfo); + virtual bool pageLoadHadNetworkError (const String& errorInfo) { ignoreUnused (errorInfo); return true; } /** This callback occurs when a script or other activity in the browser asks for the window to be closed. */ - virtual void windowCloseRequest(); + virtual void windowCloseRequest() {} /** This callback occurs when the browser attempts to load a URL in a new window. This won't actually load the window but gives you a chance to either launch a new window yourself or just load the URL into the current window with goToURL(). */ - virtual void newWindowAttemptingToLoad (const String& newURL); + virtual void newWindowAttemptingToLoad (const String& newURL) { ignoreUnused (newURL); } //============================================================================== /** @internal */ @@ -134,9 +137,18 @@ public: void visibilityChanged() override; /** @internal */ void focusGained (FocusChangeType) override; + /** @internal */ class Pimpl; + private: + //============================================================================== + friend class WindowsWebView2WebBrowserComponent; + + explicit WebBrowserComponent (bool unloadPageWhenBrowserIsHidden, + const File& dllLocation, + const File& userDataFolder); + //============================================================================== std::unique_ptr<Pimpl> browser; bool blankPageShown = false, unloadPageWhenBrowserIsHidden; @@ -150,6 +162,51 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WebBrowserComponent) }; +//============================================================================== +/** + If you have enabled the JUCE_USE_WIN_WEBVIEW2 flag then this wrapper will attempt to + use the Microsoft Edge (Chromium) WebView2 control instead of IE on Windows. It will + behave the same as WebBrowserComponent on all other platforms and will fall back to + IE on Windows if the WebView2 requirements are not met. + + This requires Microsoft Edge (minimum version 82.0.488.0) to be installed at runtime. + + Currently this also requires that WebView2Loader.dll, which can be found in the + Microsoft.Web.WebView package, is installed at runtime. As this is not a standard + system DLL, we can't rely on it being found via the normal system DLL search paths. + Therefore in order to use WebView2 you need to ensure that WebView2Loader.dll is + installed either to a location covered by the Windows DLL system search paths or + to the folder specified in the constructor of this class. + + @tags{GUI} +*/ +class WindowsWebView2WebBrowserComponent : public WebBrowserComponent +{ +public: + /** Creates a WebBrowserComponent that is compatible with the WebView2 control + on Windows. + + This allows you to specify a custom location for the WebView2Loader.dll as + well as a non-default location for storing user data for the browser instance. + + @param unloadPageWhenBrowserIsHidden if this is true, then when the browser + component is taken offscreen, it'll clear the current page + and replace it with a blank page - this can be handy to stop + the browser using resources in the background when it's not + actually being used. + @param dllLocation the path to WebView2Loader.dll, if this is empty then the default + system DLL search paths will be used + @param userDataFolder a directory in which the WebView2 user data will be stored, if + this is empty then a directory will be created next to the + executable + */ + explicit WindowsWebView2WebBrowserComponent (bool unloadPageWhenBrowserIsHidden = true, + const File& dllLocation = {}, + const File& userDataFolder = {}) + : WebBrowserComponent (unloadPageWhenBrowserIsHidden, dllLocation, userDataFolder) + { + } +}; #endif diff --git a/modules/juce_gui_extra/native/java/app/com/roli/juce/JuceWebView.java b/modules/juce_gui_extra/native/java/app/com/rmsl/juce/JuceWebView.java similarity index 74% rename from modules/juce_gui_extra/native/java/app/com/roli/juce/JuceWebView.java rename to modules/juce_gui_extra/native/java/app/com/rmsl/juce/JuceWebView.java index a9481572..8e3eb55e 100644 --- a/modules/juce_gui_extra/native/java/app/com/roli/juce/JuceWebView.java +++ b/modules/juce_gui_extra/native/java/app/com/rmsl/juce/JuceWebView.java @@ -1,4 +1,29 @@ -package com.roli.juce; +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +package com.rmsl.juce; import android.graphics.Bitmap; import android.net.http.SslError; diff --git a/modules/juce_gui_extra/native/java/app/com/rmsl/juce/JuceWebView21.java b/modules/juce_gui_extra/native/java/app/com/rmsl/juce/JuceWebView21.java new file mode 100644 index 00000000..9f8cfa69 --- /dev/null +++ b/modules/juce_gui_extra/native/java/app/com/rmsl/juce/JuceWebView21.java @@ -0,0 +1,132 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +package com.rmsl.juce; + +import android.graphics.Bitmap; +import android.net.http.SslError; +import android.os.Message; +import android.webkit.WebResourceResponse; +import android.webkit.WebView; +import android.webkit.WebViewClient; +import android.webkit.SslErrorHandler; +import android.webkit.WebChromeClient; + + +//============================================================================== +public class JuceWebView21 +{ + static public class Client extends WebViewClient + { + public Client (long hostToUse) + { + host = hostToUse; + } + + public void hostDeleted () + { + synchronized (hostLock) + { + host = 0; + } + } + + public void onPageFinished (WebView view, String url) + { + if (host == 0) + return; + + webViewPageLoadFinished (host, view, url); + } + + public void onReceivedSslError (WebView view, SslErrorHandler handler, SslError error) + { + if (host == 0) + return; + + webViewReceivedSslError (host, view, handler, error); + } + + public void onPageStarted (WebView view, String url, Bitmap favicon) + { + if (host != 0) + webViewPageLoadStarted (host, view, url); + } + + public WebResourceResponse shouldInterceptRequest (WebView view, String url) + { + synchronized (hostLock) + { + if (host != 0) + { + boolean shouldLoad = webViewPageLoadStarted (host, view, url); + + if (shouldLoad) + return null; + } + } + + return new WebResourceResponse ("text/html", null, null); + } + + private native boolean webViewPageLoadStarted (long host, WebView view, String url); + + private native void webViewPageLoadFinished (long host, WebView view, String url); + + private native void webViewReceivedSslError (long host, WebView view, SslErrorHandler handler, SslError error); + + private long host; + private final Object hostLock = new Object (); + } + + static public class ChromeClient extends WebChromeClient + { + public ChromeClient (long hostToUse) + { + host = hostToUse; + } + + @Override + public void onCloseWindow (WebView window) + { + webViewCloseWindowRequest (host, window); + } + + @Override + public boolean onCreateWindow (WebView view, boolean isDialog, + boolean isUserGesture, Message resultMsg) + { + webViewCreateWindowRequest (host, view); + return false; + } + + private native void webViewCloseWindowRequest (long host, WebView view); + + private native void webViewCreateWindowRequest (long host, WebView view); + + private long host; + private final Object hostLock = new Object (); + } +} diff --git a/modules/juce_gui_extra/native/javaopt/app/com/rmsl/juce/JuceFirebaseInstanceIdService.java b/modules/juce_gui_extra/native/javaopt/app/com/rmsl/juce/JuceFirebaseInstanceIdService.java new file mode 100644 index 00000000..f1656a7d --- /dev/null +++ b/modules/juce_gui_extra/native/javaopt/app/com/rmsl/juce/JuceFirebaseInstanceIdService.java @@ -0,0 +1,41 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +package com.rmsl.juce; + +import com.google.firebase.iid.*; + +public final class JuceFirebaseInstanceIdService extends FirebaseInstanceIdService +{ + private native void firebaseInstanceIdTokenRefreshed (String token); + + @Override + public void onTokenRefresh() + { + String token = FirebaseInstanceId.getInstance().getToken(); + + firebaseInstanceIdTokenRefreshed (token); + } +} diff --git a/modules/juce_gui_extra/native/javaopt/app/com/rmsl/juce/JuceFirebaseMessagingService.java b/modules/juce_gui_extra/native/javaopt/app/com/rmsl/juce/JuceFirebaseMessagingService.java new file mode 100644 index 00000000..13e8323e --- /dev/null +++ b/modules/juce_gui_extra/native/javaopt/app/com/rmsl/juce/JuceFirebaseMessagingService.java @@ -0,0 +1,60 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +package com.rmsl.juce; + +import com.google.firebase.messaging.*; + +public final class JuceFirebaseMessagingService extends FirebaseMessagingService +{ + private native void firebaseRemoteMessageReceived (RemoteMessage message); + private native void firebaseRemoteMessagesDeleted(); + private native void firebaseRemoteMessageSent (String messageId); + private native void firebaseRemoteMessageSendError (String messageId, String error); + + @Override + public void onMessageReceived (RemoteMessage message) + { + firebaseRemoteMessageReceived (message); + } + + @Override + public void onDeletedMessages() + { + firebaseRemoteMessagesDeleted(); + } + + @Override + public void onMessageSent (String messageId) + { + firebaseRemoteMessageSent (messageId); + } + + @Override + public void onSendError (String messageId, Exception e) + { + firebaseRemoteMessageSendError (messageId, e.toString()); + } +} diff --git a/modules/juce_gui_extra/native/javaopt/app/com/roli/juce/JuceFirebaseInstanceIdService.java b/modules/juce_gui_extra/native/javaopt/app/com/roli/juce/JuceFirebaseInstanceIdService.java deleted file mode 100644 index 9988249d..00000000 --- a/modules/juce_gui_extra/native/javaopt/app/com/roli/juce/JuceFirebaseInstanceIdService.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.roli.juce; - -import com.google.firebase.iid.*; - -public final class JuceFirebaseInstanceIdService extends FirebaseInstanceIdService -{ - private native void firebaseInstanceIdTokenRefreshed (String token); - - @Override - public void onTokenRefresh() - { - String token = FirebaseInstanceId.getInstance().getToken(); - - firebaseInstanceIdTokenRefreshed (token); - } -} diff --git a/modules/juce_gui_extra/native/javaopt/app/com/roli/juce/JuceFirebaseMessagingService.java b/modules/juce_gui_extra/native/javaopt/app/com/roli/juce/JuceFirebaseMessagingService.java deleted file mode 100644 index 945440e5..00000000 --- a/modules/juce_gui_extra/native/javaopt/app/com/roli/juce/JuceFirebaseMessagingService.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.roli.juce; - -import com.google.firebase.messaging.*; - -public final class JuceFirebaseMessagingService extends FirebaseMessagingService -{ - private native void firebaseRemoteMessageReceived (RemoteMessage message); - private native void firebaseRemoteMessagesDeleted(); - private native void firebaseRemoteMessageSent (String messageId); - private native void firebaseRemoteMessageSendError (String messageId, String error); - - @Override - public void onMessageReceived (RemoteMessage message) - { - firebaseRemoteMessageReceived (message); - } - - @Override - public void onDeletedMessages() - { - firebaseRemoteMessagesDeleted(); - } - - @Override - public void onMessageSent (String messageId) - { - firebaseRemoteMessageSent (messageId); - } - - @Override - public void onSendError (String messageId, Exception e) - { - firebaseRemoteMessageSendError (messageId, e.toString()); - } -} diff --git a/modules/juce_gui_extra/native/juce_AndroidViewComponent.cpp b/modules/juce_gui_extra/native/juce_AndroidViewComponent.cpp index 6f51d2ab..8f80566a 100644 --- a/modules/juce_gui_extra/native/juce_AndroidViewComponent.cpp +++ b/modules/juce_gui_extra/native/juce_AndroidViewComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -53,7 +52,7 @@ public: auto pos = topComp->getLocalPoint (&owner, Point<int>()); Rectangle<int> r (pos.x, pos.y, owner.getWidth(), owner.getHeight()); - r *= Desktop::getInstance().getDisplays().getMainDisplay().scale; + r *= Desktop::getInstance().getDisplays().getPrimaryDisplay()->scale; getEnv()->CallVoidMethod (view, AndroidView.layout, r.getX(), r.getY(), r.getRight(), r.getBottom()); diff --git a/modules/juce_gui_extra/native/juce_android_PushNotifications.cpp b/modules/juce_gui_extra/native/juce_android_PushNotifications.cpp index 69c65003..e108081e 100644 --- a/modules/juce_gui_extra/native/juce_android_PushNotifications.cpp +++ b/modules/juce_gui_extra/native/juce_android_PushNotifications.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -1558,7 +1557,7 @@ struct JuceFirebaseInstanceIdService #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ CALLBACK (tokenRefreshed, "firebaseInstanceIdTokenRefreshed", "(Ljava/lang/String;)V") - DECLARE_JNI_CLASS (InstanceIdService, "com/roli/juce/JuceFirebaseInstanceIdService") + DECLARE_JNI_CLASS (InstanceIdService, "com/rmsl/juce/JuceFirebaseInstanceIdService") #undef JNI_CLASS_MEMBERS static void JNICALL tokenRefreshed (JNIEnv*, jobject /*instanceIdService*/, void* token) @@ -1581,7 +1580,7 @@ struct JuceFirebaseMessagingService CALLBACK (remoteMessageSent, "firebaseRemoteMessageSent", "(Ljava/lang/String;)V") \ CALLBACK (remoteMessageSendError, "firebaseRemoteMessageSendError", "(Ljava/lang/String;Ljava/lang/String;)V") - DECLARE_JNI_CLASS (MessagingService, "com/roli/juce/JuceFirebaseMessagingService") + DECLARE_JNI_CLASS (MessagingService, "com/rmsl/juce/JuceFirebaseMessagingService") #undef JNI_CLASS_MEMBERS static void JNICALL remoteNotificationReceived (JNIEnv*, jobject /*messagingService*/, void* remoteMessage) diff --git a/modules/juce_gui_extra/native/juce_android_WebBrowserComponent.cpp b/modules/juce_gui_extra/native/juce_android_WebBrowserComponent.cpp index 4661ff36..3f6236c4 100644 --- a/modules/juce_gui_extra/native/juce_android_WebBrowserComponent.cpp +++ b/modules/juce_gui_extra/native/juce_android_WebBrowserComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -28,118 +27,113 @@ namespace juce { //============================================================================== -// This byte-code is generated from native/java/com/roli/juce/JuceWebView.java with min sdk version 16 +// This byte-code is generated from native/java/com/rmsl/juce/JuceWebView.java with min sdk version 16 // See juce_core/native/java/README.txt on how to generate this byte-code. static const unsigned char JuceWebView16ByteCode[] = -{31,139,8,8,167,106,229,91,0,3,74,117,99,101,87,101,98,86,105,101,119,49,54,46,100,101,120,0,125,150,93,108,84,69,20,199, -207,253,216,189,187,183,237,178,109,161,31,20,74,91,177,84,164,44,88,145,210,5,172,124,83,22,63,186,80,100,53,145,219, -221,177,189,101,123,239,114,239,221,182,38,68,81,155,168,4,19,99,225,141,23,19,36,38,248,136,9,15,62,16,35,209,24,141,47, -70,125,224,193,23,141,15,62,136,49,132,104,31,252,207,157,217,101,129,98,55,191,61,103,206,57,51,115,102,230,116,118,10, -108,206,220,52,176,133,222,95,60,244,253,183,71,91,94,92,240,223,75,222,186,115,227,231,111,110,221,252,44,186,176,245, -181,235,117,68,37,34,154,27,123,178,137,228,223,162,73,52,76,194,190,156,75,133,168,1,242,58,164,14,249,178,74,212,12, -121,26,82,227,49,248,202,196,136,2,200,250,40,218,160,7,172,7,253,224,105,176,7,188,2,78,131,15,193,85,240,35,88,4,45,6, -209,83,224,4,152,7,31,129,27,224,87,16,195,184,107,192,0,216,15,70,192,179,32,11,142,131,19,160,0,108,224,2,15,204,129, -55,192,57,176,0,46,130,143,193,21,112,13,124,1,190,3,63,129,223,192,31,224,95,80,23,39,234,0,235,193,78,112,16,88,96,26, -204,129,215,193,219,224,44,248,0,92,1,95,129,95,192,29,208,104,138,253,192,146,8,169,19,134,36,152,9,102,194,54,83,61, -137,125,76,128,101,32,9,26,1,223,248,102,185,215,43,64,11,104,5,107,64,68,142,119,41,34,108,149,67,106,147,250,167,176, -183,75,253,42,244,14,169,127,14,125,165,212,191,134,190,74,234,63,64,239,148,250,77,232,171,165,126,169,198,254,123,141, -254,55,244,46,153,31,31,167,91,234,60,41,190,182,222,112,141,73,234,147,235,236,13,165,104,71,72,33,17,106,134,50,38,219, -113,82,165,140,82,127,40,235,105,99,40,53,26,146,50,29,142,35,226,76,244,91,23,202,24,165,66,25,167,77,161,52,104,179, -156,119,32,148,17,218,30,202,58,218,17,74,157,118,134,123,47,230,77,86,231,167,80,139,200,189,228,53,29,160,113,89,164, -25,142,167,200,243,171,248,231,225,255,82,250,235,164,63,89,227,63,15,255,95,210,207,179,158,135,126,214,188,171,47,152, -162,207,69,147,199,107,161,222,110,138,122,40,37,185,175,7,227,149,146,124,207,95,74,42,148,107,18,117,162,99,4,62,126, -175,41,234,32,139,195,40,13,71,73,221,156,192,234,35,161,175,223,20,245,38,124,6,124,77,97,125,85,230,217,90,157,71,189, -111,30,13,243,168,225,60,226,172,20,218,99,138,58,61,242,140,70,171,149,22,164,159,219,165,82,167,146,192,8,157,202,58, -89,143,10,62,113,204,169,133,237,195,166,168,231,236,176,74,188,7,206,68,221,6,95,34,180,148,198,18,164,191,208,247,15, -223,79,61,140,31,51,197,218,106,227,7,49,154,136,94,134,232,4,246,88,15,215,123,194,20,245,150,45,61,48,182,167,146,113, -202,152,55,46,24,151,103,162,252,108,251,110,243,179,225,57,169,52,133,126,143,240,26,86,142,188,133,149,168,217,121,244, -199,128,155,53,61,58,168,213,19,111,151,114,203,232,192,5,147,6,49,87,167,218,168,116,170,61,106,148,86,106,91,176,139, -10,61,209,104,116,247,221,110,128,117,157,188,247,154,49,71,119,184,75,252,211,37,37,238,26,83,248,197,174,38,194,123, -176,246,239,204,125,237,115,247,181,121,141,24,184,9,148,154,54,183,232,85,169,146,38,245,70,89,123,252,188,181,170,183, -162,139,49,184,222,136,207,50,89,155,6,50,111,134,53,186,221,118,236,96,39,213,239,158,244,220,105,182,187,104,51,39,160, -168,148,202,8,37,71,202,121,118,140,141,143,217,108,118,227,148,53,99,145,150,201,100,168,61,99,57,5,207,181,11,169,9, -207,42,77,218,121,63,181,203,14,166,173,82,154,58,170,46,135,5,169,201,32,40,165,178,126,113,175,231,185,94,154,150,87, -157,174,159,58,204,124,223,154,96,105,234,170,90,103,217,248,73,59,168,118,56,0,123,145,121,75,68,32,165,218,148,211,180, -118,137,136,81,230,187,101,47,207,32,75,174,227,99,166,182,37,162,248,210,210,212,249,16,79,101,252,190,76,222,157,78, -121,110,209,78,77,97,75,82,53,251,178,246,222,76,122,254,47,82,198,116,60,60,134,15,80,176,138,51,246,201,148,229,56,110, -96,5,182,235,164,246,58,249,162,235,219,206,196,238,162,229,251,60,221,7,99,14,58,14,243,164,191,123,9,255,97,54,61,46,3, -24,66,86,100,248,121,166,108,23,29,75,229,32,27,120,204,154,78,83,147,48,23,45,103,34,245,220,248,20,203,7,247,218,16, -135,52,210,164,140,145,58,54,66,218,216,72,134,116,124,101,40,194,191,51,176,102,96,205,112,43,111,42,57,210,115,161,59, -151,201,229,50,84,103,229,243,56,248,125,69,107,194,167,8,227,199,76,198,171,214,140,157,119,29,50,38,197,137,147,62,233, -250,1,213,241,239,61,172,200,2,86,160,24,111,100,220,252,73,138,115,237,136,123,212,103,20,179,253,61,182,85,116,39,168, -193,246,97,240,246,51,63,40,123,140,116,199,154,102,212,224,58,187,177,111,236,152,237,20,220,89,74,160,137,85,6,53,237, -231,81,129,251,240,79,224,79,98,138,6,209,206,6,150,199,103,108,114,157,81,150,103,246,12,43,84,42,146,226,30,243,203, -197,224,176,63,65,45,254,164,91,46,22,14,58,1,67,145,149,130,81,118,170,140,217,201,20,246,140,107,21,40,30,176,57,254, -95,48,93,36,61,152,180,125,210,202,94,145,34,51,86,177,140,28,103,112,222,212,62,91,169,180,106,162,149,145,86,86,92,53, -73,87,124,173,210,199,19,230,83,85,23,209,114,159,163,178,154,74,135,7,150,20,157,21,187,49,170,172,55,18,106,107,90,157, -154,237,167,227,202,176,145,200,209,9,125,232,241,13,3,92,107,14,189,219,210,234,1,120,219,201,72,236,56,212,185,138,186, -213,161,65,35,113,118,21,110,209,161,193,71,141,196,59,57,122,76,27,234,93,27,218,182,114,231,234,29,239,78,105,180,101, -121,127,119,132,58,214,44,224,50,52,18,164,214,43,131,109,117,106,131,218,163,199,55,180,42,21,69,85,19,202,224,42,181, -45,222,134,31,122,77,37,85,105,210,222,60,163,159,55,180,183,240,59,5,116,229,186,161,40,55,241,131,166,71,84,120,99,240, -46,26,81,233,229,196,149,79,98,136,0,231,226,138,114,13,252,25,231,247,99,35,34,111,154,149,223,103,165,70,14,147,120, -215,242,59,179,242,182,229,247,101,237,251,182,242,198,141,208,221,119,110,148,238,190,117,181,164,208,249,61,175,116, -137,247,194,121,232,209,46,105,71,71,37,41,236,252,93,165,118,137,121,249,219,88,147,241,252,183,95,239,146,111,11,110, -144,125,195,55,72,82,228,202,223,225,255,1,121,75,63,47,192,11,0,0}; +{31,139,8,8,150,114,161,94,0,3,74,117,99,101,87,101,98,86,105,101,119,49,54,66,121,116,101,67,111,100,101,46,100,101,120,0,125, +150,93,108,20,85,20,199,207,124,236,78,119,218,110,183,5,74,191,40,109,69,168,72,89,176,162,165,11,88,40,159,101,81,161,88,226, +106,34,211,221,107,59,101,118,102,153,153,109,27,67,16,161,137,134,240,96,4,222,72,140,9,18,35,62,18,195,131,15,4,53,250,226,155, +209,23,30,212,4,195,131,15,198,24,98,20,19,255,119,238,221,101,129,226,110,126,123,206,61,231,220,123,207,189,247,236,204, +45,176,121,115,195,224,38,242,254,253,180,235,204,157,47,183,223,188,240,115,199,231,119,79,174,251,240,23,243,246,209,206,219, +79,221,168,39,42,17,209,252,196,179,45,36,63,247,76,162,17,18,246,165,92,42,68,141,144,55,32,117,200,215,85,162,37,144,39,32, +53,30,131,159,108,29,81,8,217,16,71,27,244,129,181,96,0,188,0,118,130,55,192,9,240,1,184,6,126,0,247,64,171,65,244,28,56,10,22, +192,71,224,107,112,27,212,97,220,149,96,16,236,1,99,224,69,48,14,94,5,71,65,1,216,192,3,62,152,7,111,131,115,224,60,184,4,62, +6,87,193,117,112,19,124,7,126,4,191,130,223,192,63,160,62,65,212,9,214,130,109,96,31,176,64,17,204,131,147,224,12,56,11,222,7,87, +193,55,224,39,240,23,104,54,197,126,96,73,132,212,9,67,18,204,4,51,97,155,169,129,196,62,38,65,19,72,129,102,192,55,126,137, +220,235,101,160,21,44,7,43,65,76,142,119,57,38,108,149,67,106,147,250,103,176,183,75,253,26,244,78,169,127,1,189,67,234,223,66, +239,146,250,247,208,187,165,126,11,250,10,169,95,174,177,223,169,209,255,132,222,35,243,227,227,244,74,157,39,197,215,182,58, +90,99,138,250,229,58,87,71,82,180,99,164,144,8,53,35,89,39,219,9,82,165,140,211,64,36,27,104,125,36,53,26,150,50,19,141,35,226, +76,244,91,19,201,58,74,71,50,65,27,34,105,208,70,57,239,96,36,99,180,37,146,245,180,53,146,58,109,139,246,94,204,155,170,206, +79,145,22,147,123,201,107,58,68,227,138,72,51,26,79,145,231,87,241,47,192,255,149,244,215,75,127,170,198,127,1,254,63,164,159, +103,189,0,253,172,121,95,63,111,138,62,151,76,30,175,69,122,187,41,234,161,148,226,190,62,140,87,74,241,61,127,45,165,80,174, +69,212,137,142,17,248,248,171,77,81,7,227,56,140,210,72,156,212,141,73,172,62,22,249,6,76,81,111,194,103,192,215,18,213,87,101, +158,231,171,243,168,15,205,163,97,30,53,154,71,156,149,66,59,77,81,167,135,183,107,180,66,105,69,250,185,29,42,117,43,73,140, +208,173,172,145,245,168,224,155,192,156,90,212,62,96,138,122,30,31,81,137,247,192,153,168,155,225,75,70,150,210,68,146,244,131, +253,127,243,253,212,163,248,9,83,172,173,54,126,8,163,137,232,38,68,39,177,199,122,180,222,163,166,168,183,241,210,35,99,251, +42,25,199,141,5,227,162,113,101,54,206,207,182,255,46,63,27,158,147,74,51,232,247,4,175,97,229,240,105,172,68,29,95,64,127,12, +184,81,211,227,67,90,3,241,118,41,215,68,123,47,154,52,132,185,186,213,102,165,91,237,83,227,212,161,109,194,46,42,244,76,179, +209,219,127,183,17,214,53,242,185,183,4,115,244,70,187,196,191,61,82,226,89,99,10,191,216,213,100,244,28,172,253,156,122,168,125, +238,161,54,175,17,3,79,2,165,166,205,45,122,85,170,164,73,189,89,214,30,63,111,173,234,173,232,98,12,174,55,227,219,36,107, +211,64,230,75,96,141,111,177,93,59,220,70,13,163,211,190,87,100,163,142,205,220,144,226,82,42,99,148,26,43,231,217,17,54,57,97, +179,185,245,51,214,172,69,90,54,155,165,246,172,229,22,124,207,46,164,167,124,171,52,109,231,131,244,14,59,44,90,165,12,117, +86,93,46,11,211,211,97,88,74,143,7,206,46,223,247,252,12,45,173,58,189,32,125,128,5,129,53,197,50,212,83,181,206,177,201,99,118, +88,237,176,23,118,135,249,139,68,32,165,218,148,51,180,106,145,136,67,44,240,202,126,158,65,150,60,55,192,76,109,139,68,241, +165,101,168,251,49,158,202,248,253,217,188,87,76,251,197,192,73,207,96,75,210,53,251,178,234,193,76,250,254,47,82,198,116,62,62, +134,15,80,176,156,89,251,88,218,114,93,47,180,66,219,115,211,187,220,188,227,5,182,59,53,234,88,65,192,211,125,52,102,159, +235,50,95,250,123,23,241,31,96,197,73,25,192,16,178,44,203,207,51,109,123,232,88,42,135,227,161,207,172,98,134,90,132,217,177, +220,169,244,75,147,51,44,31,62,104,67,28,210,200,144,50,65,234,196,24,105,19,99,89,210,241,147,165,24,255,205,194,154,133,53, +203,173,188,169,228,72,207,69,238,92,54,151,203,82,189,149,207,227,224,119,59,214,84,64,49,198,143,153,140,55,173,89,59,239,185, +100,76,139,19,39,125,218,11,66,170,231,191,59,153,195,66,86,160,58,222,200,122,249,99,148,224,218,97,239,149,128,81,157,29, +236,180,45,199,155,162,70,59,128,193,223,195,130,176,236,51,210,93,171,200,168,209,115,71,177,111,236,136,237,22,188,57,74,162, +137,85,134,53,237,151,81,129,187,241,39,8,166,49,69,163,104,143,135,150,207,103,108,241,220,67,44,207,236,89,86,168,84,36,37, +124,22,148,157,240,64,48,69,173,193,180,87,118,10,251,220,144,161,200,74,225,33,118,188,140,217,201,20,246,172,103,21,40,17,178, +121,254,47,40,58,164,135,211,118,64,90,217,119,40,54,107,57,101,228,56,139,243,166,246,185,74,165,85,19,173,140,212,81,113, +213,36,93,241,45,151,62,158,48,159,170,186,136,214,135,28,149,213,84,58,60,178,164,248,156,216,13,71,89,107,36,213,229,25,117, +102,110,128,2,101,196,72,230,232,45,125,248,233,117,131,92,27,136,188,155,51,234,94,120,7,201,72,110,221,223,221,69,25,117,120, +200,72,158,237,162,253,218,240,208,147,70,242,221,28,141,106,195,171,87,69,182,131,220,185,98,235,123,51,26,109,90,58,208,27,163, +206,149,231,113,13,48,146,164,54,40,67,109,245,106,163,218,167,39,214,45,87,42,138,170,38,149,161,46,181,45,209,134,23,189, +166,146,170,180,104,239,156,210,47,24,218,105,188,167,128,174,220,48,20,229,22,94,104,122,76,133,183,14,222,123,70,92,122,57,9, +229,147,58,68,128,115,9,69,185,14,126,79,240,231,99,51,34,111,153,149,247,179,82,35,71,72,220,107,249,51,179,114,183,229,207, +203,218,251,109,229,142,27,163,251,247,220,56,221,191,235,106,41,161,243,231,188,210,35,238,11,23,160,199,123,164,29,29,149,148, +176,243,123,149,218,35,230,229,119,99,77,198,243,119,191,222,35,239,22,220,32,251,70,119,144,148,200,149,223,195,255,3,213, +111,243,3,192,11,0,0,0,0}; //============================================================================== -// This byte-code is generated from native/javacore/app/com/roli/juce/JuceWebView21.java with min sdk version 21 +// This byte-code is generated from native/javacore/app/com/rmsl/juce/JuceWebView21.java with min sdk version 21 // See juce_core/native/java/README.txt on how to generate this byte-code. static const unsigned char JuceWebView21ByteCode[] = -{31,139,8,8,20,250,226,91,0,3,74,117,99,101,87,101,98,86,105,101,119,50,49,46,100,101,120,0,149,151,93,108,28,87,21,199, -207,124,236,206,174,119,118,179,222,117,28,219,113,236,181,235,54,78,147,116,227,36,37,78,54,169,204,58,113,237,48,81, -193,78,220,104,145,144,198,187,131,61,206,122,102,51,51,187,142,196,3,161,141,0,209,10,169,130,190,81,41,15,41,170,10,21, -66,66,34,60,240,134,74,16,47,149,120,160,128,84,1,2,169,15,17,42,15,84,81,37,36,254,247,99,54,27,199,68,176,171,223,158, -115,207,57,115,239,61,247,158,153,189,211,112,110,244,29,59,241,60,93,89,253,237,71,111,149,22,172,113,253,199,127,126, -238,195,175,252,238,212,236,173,175,189,250,151,87,111,127,146,37,106,17,209,141,213,147,5,146,159,35,176,45,145,176,15, -130,239,43,68,204,121,31,82,135,252,149,74,52,4,249,55,72,13,242,14,126,238,167,225,131,179,101,160,47,240,77,240,93,240, -6,120,27,188,3,222,3,247,192,159,192,3,144,75,17,29,3,203,96,27,188,5,126,14,126,15,52,244,119,8,44,130,38,120,29,252,4, -188,15,254,8,254,1,254,9,254,5,62,3,212,71,100,128,12,200,131,65,48,12,198,193,51,224,4,56,3,150,192,50,168,129,58,112, -65,7,220,4,175,129,55,193,29,240,46,248,5,248,13,248,3,248,24,252,27,244,103,136,70,192,211,224,28,88,2,151,65,13,52,128, -11,90,160,3,222,0,239,129,247,193,71,224,1,232,55,197,154,33,125,66,154,36,167,78,112,17,92,132,165,167,28,216,3,242,160, -159,196,218,23,193,0,216,43,247,100,31,137,61,24,6,35,96,18,36,128,42,247,48,41,251,255,56,249,80,255,36,41,98,138,50, -102,68,246,201,62,251,165,254,0,49,163,177,29,147,28,147,122,170,71,31,128,126,64,234,37,232,227,82,63,2,125,66,234,39, -123,244,57,232,37,169,179,57,196,118,171,39,230,42,244,167,100,126,172,207,41,169,55,12,177,54,135,249,26,21,232,168,92, -167,195,92,138,182,138,21,125,129,231,172,147,156,54,29,226,57,239,225,237,62,105,207,240,236,153,236,163,227,92,246,211, -9,46,147,84,149,114,158,247,43,226,76,92,119,132,203,44,157,228,50,71,207,115,105,210,231,184,204,208,41,46,21,58,195, -165,42,101,154,206,115,153,167,11,92,166,104,129,75,131,94,228,123,44,230,83,232,206,139,208,131,216,39,246,97,214,187, -104,252,218,36,57,15,225,239,235,241,223,131,255,239,210,159,149,254,66,143,255,67,248,199,179,162,205,106,226,109,196, -254,200,124,168,255,204,20,215,252,210,100,241,26,215,135,77,209,87,43,175,160,61,137,254,90,121,86,103,95,70,187,86,16, -117,169,163,7,214,255,51,166,152,239,10,54,182,53,151,34,117,38,135,236,18,220,119,212,20,123,32,124,105,248,10,124,39, -226,113,78,117,199,209,119,140,163,97,28,149,143,147,224,145,10,45,152,34,255,203,159,215,232,128,50,136,233,215,170,42, -141,41,57,244,48,166,28,228,59,149,36,54,223,52,198,212,120,251,37,83,220,63,43,115,42,177,43,102,144,246,105,248,114, -220,210,90,197,186,127,105,250,51,86,31,58,143,191,106,138,220,122,227,103,209,155,136,46,34,58,135,61,210,121,190,107, -166,184,127,86,90,143,245,29,168,100,92,55,110,25,111,26,63,236,36,7,48,163,233,79,169,123,93,243,127,188,110,111,247,58, -150,139,74,29,83,212,122,65,185,252,10,86,64,93,185,133,235,209,225,140,166,39,103,181,1,98,237,32,175,162,54,76,205,203, -179,103,139,169,181,86,138,180,136,7,217,44,198,30,83,251,149,49,117,82,77,209,136,118,22,187,161,209,241,126,99,98,250, -211,44,172,7,229,243,124,63,198,60,196,87,155,125,167,187,99,191,102,138,123,114,247,177,77,62,118,171,246,255,141,85, -196,8,19,221,177,74,82,18,221,54,133,95,84,66,142,255,151,244,126,242,59,218,163,59,218,172,174,89,5,8,89,228,125,198, -118,102,209,165,76,32,183,88,55,80,1,154,212,139,242,30,98,207,99,173,27,25,235,6,127,126,106,61,125,107,60,151,34,127, -62,235,220,190,23,95,236,245,89,215,115,163,23,200,156,223,8,252,45,103,190,233,58,94,68,73,41,149,139,84,184,216,174,59, -47,59,107,171,174,179,125,124,230,185,77,187,99,147,98,145,102,89,22,13,91,182,215,8,124,183,81,94,15,236,214,134,91,15, -203,85,55,218,178,91,21,234,239,186,60,39,42,95,9,220,10,237,127,196,180,17,69,173,242,74,216,188,16,4,126,80,161,129, -174,211,15,203,151,156,48,180,215,157,10,149,186,214,109,103,237,154,27,117,47,88,132,189,233,4,187,68,96,170,189,169,84, -232,169,93,34,150,157,208,111,7,117,103,217,185,222,118,66,4,77,61,49,40,108,249,94,136,233,12,237,18,197,214,165,66,99, -255,197,19,79,226,89,171,238,111,149,3,191,233,150,55,177,158,229,71,22,117,234,209,9,79,61,57,86,70,29,120,82,84,133,38, -173,134,221,236,184,215,202,182,231,249,145,29,185,190,87,190,224,213,155,126,232,122,235,243,77,59,12,217,164,31,143,89, -242,60,39,144,254,137,93,252,151,156,173,53,25,224,32,100,175,197,10,162,236,250,184,176,213,142,86,162,192,177,183,42, -84,16,230,166,237,173,151,95,90,219,116,234,209,163,54,196,97,26,21,82,86,73,93,189,72,218,234,69,139,116,252,88,148,96, -191,22,172,40,177,85,139,89,89,83,169,145,94,227,238,154,85,171,89,148,177,235,117,212,200,66,211,94,15,41,225,176,138, -160,44,23,241,102,145,241,85,187,227,214,125,143,146,235,78,116,37,104,146,177,33,106,134,244,13,63,140,40,195,126,207, -59,77,39,114,26,148,98,13,203,175,95,163,52,211,46,251,87,208,67,202,13,207,187,118,211,95,167,172,27,194,16,188,136,82, -105,7,14,233,158,189,229,80,214,247,230,177,156,206,203,174,215,240,183,41,135,38,146,143,122,218,95,68,13,47,224,246,10, -55,48,68,86,180,87,34,59,96,35,22,125,111,217,169,59,110,199,105,44,226,78,224,69,77,133,135,198,184,208,201,8,68,141,82, -58,112,194,118,51,186,20,174,211,96,184,225,183,155,141,37,47,114,80,159,173,72,150,49,245,9,187,229,219,13,74,71,206,13, -118,151,109,53,73,143,54,220,144,82,145,47,150,157,180,54,150,35,209,177,155,109,228,210,65,193,208,240,118,92,174,221, -132,226,62,71,98,87,79,114,177,111,159,244,177,196,216,160,221,100,7,119,56,226,172,135,164,253,241,212,247,237,240,116, -243,79,110,139,245,220,84,202,70,78,29,172,168,215,182,143,210,117,101,201,200,213,232,134,94,61,54,115,134,105,3,220, -251,1,85,212,159,126,29,254,17,50,114,231,190,48,54,74,147,106,117,206,200,125,103,148,142,107,213,185,67,70,238,91,53, -186,170,85,79,79,115,219,179,90,245,240,65,174,45,170,213,211,198,129,115,223,254,171,70,103,7,143,78,36,104,255,248,247, -104,150,93,11,227,102,175,113,15,122,38,53,167,204,13,101,213,61,234,211,122,122,102,159,18,43,170,154,87,230,70,213,161, -204,16,78,86,154,74,170,82,72,124,227,166,126,39,165,189,162,146,2,146,202,7,41,69,185,143,211,71,194,80,225,237,131,247, -245,116,74,122,99,50,202,221,52,162,192,15,250,20,229,30,184,153,81,148,187,64,28,130,6,113,213,109,118,30,201,203,255, -12,165,71,198,239,65,236,127,36,126,23,98,207,254,222,247,161,248,157,136,157,37,226,247,162,36,61,124,55,210,242,66,103, -255,105,74,73,156,103,166,160,39,75,194,206,206,122,74,94,156,137,216,121,93,45,201,113,113,136,210,100,60,59,155,233,37, -49,22,59,191,145,188,150,159,17,243,98,174,236,189,237,63,5,143,187,196,240,13,0,0}; +{31,139,8,8,45,103,161,94,0,3,74,117,99,101,87,101,98,86,105,101,119,50,49,46,100,101,120,0,141,151,93,140,27,87,21,199,207, +204,216,30,219,99,59,182,55,251,145,143,221,110,210,173,178,105,154,186,155,164,52,169,211,106,241,38,219,221,48,41,52,155,108, +138,43,85,154,181,47,235,73,188,51,206,204,120,119,65,162,132,80,148,138,34,148,168,20,181,125,129,135,16,129,4,18,168,125,136, +42,224,133,207,74,60,160,138,135,208,71,210,151,162,128,242,148,86,136,7,254,247,99,28,111,18,34,108,253,124,206,61,231,220, +143,115,239,153,241,76,147,173,103,159,216,255,36,253,228,121,251,31,197,127,189,252,251,226,31,94,89,242,217,87,31,123,227, +151,175,95,184,28,222,168,188,152,39,234,16,209,250,226,129,50,169,207,247,115,68,243,36,237,67,188,173,17,149,32,111,66,38,32, +175,233,68,195,144,215,33,13,200,75,248,105,101,136,110,65,222,74,17,125,6,82,38,81,1,148,192,35,96,18,236,5,115,224,37,176,14, +190,7,126,1,62,4,159,130,209,52,209,83,224,52,248,22,248,41,248,19,184,9,114,24,191,2,102,65,29,120,224,28,232,130,175,129, +243,224,34,120,29,92,2,63,0,111,131,31,130,171,224,93,240,62,248,0,124,8,62,2,55,192,39,224,54,160,44,145,5,6,193,4,120,20,28, +2,243,224,203,160,5,190,14,46,131,119,192,143,193,175,193,7,224,175,224,35,240,49,248,4,220,2,183,65,201,66,206,96,22,188,12, +214,193,101,75,238,25,210,37,164,69,106,106,130,153,176,237,132,227,160,2,216,4,138,36,247,157,31,204,0,216,12,6,213,153,240, +253,31,1,91,192,86,176,19,36,129,174,206,48,165,198,111,165,164,125,64,217,183,170,113,248,103,155,210,59,136,217,174,244,117, +232,99,74,63,223,167,127,23,250,168,210,223,130,254,144,210,175,64,223,161,244,159,245,233,215,160,143,43,253,119,125,246,63, +247,233,215,161,63,172,114,226,99,78,40,253,227,148,220,143,61,98,95,202,180,87,237,205,30,33,101,91,199,247,89,145,167,33,114, +225,251,185,91,228,92,16,237,172,178,91,162,98,185,204,208,62,33,139,180,95,200,36,213,148,156,17,227,202,184,28,250,61,38,100, +142,14,8,153,167,39,133,180,232,115,66,102,233,41,33,53,122,90,200,52,29,17,114,19,29,21,210,164,89,33,83,244,156,56,79,185, +142,114,111,61,132,158,242,124,248,135,207,122,16,141,253,57,82,243,75,127,182,207,63,7,255,11,202,159,87,254,114,159,255,69, +248,47,42,63,63,255,18,244,225,220,29,125,60,39,251,236,206,241,120,67,232,111,91,114,172,78,81,67,123,39,198,235,20,121,93,189, +132,118,189,44,107,48,129,17,248,248,87,45,185,222,5,28,104,103,58,77,250,84,1,89,38,133,239,231,150,220,123,233,203,192,87,22, +181,27,207,115,173,55,79,226,174,121,12,204,163,139,121,146,34,82,163,63,90,50,255,147,159,55,104,84,27,194,242,235,53,157, +198,180,2,70,24,211,118,137,58,78,17,95,111,6,115,26,162,253,23,75,94,43,11,211,58,241,30,83,72,251,16,124,5,97,233,44,150,40, +241,194,228,191,121,93,36,68,252,223,44,153,91,127,252,65,140,38,163,203,136,46,136,154,225,249,222,176,228,117,179,208,185, +103,236,64,39,243,156,249,170,249,166,121,117,53,53,128,21,77,222,166,94,191,127,254,159,253,54,247,250,241,92,116,250,212,146, +53,94,214,78,94,192,14,232,11,175,162,63,6,156,50,18,169,131,198,102,226,237,160,168,163,54,114,134,87,228,247,145,156,209, +89,40,211,220,155,89,58,136,185,199,244,146,54,166,239,212,211,180,213,56,140,211,48,104,95,201,220,49,121,59,15,235,46,117, +239,222,134,57,119,139,221,230,223,73,37,177,239,57,233,151,167,83,16,247,242,254,207,127,238,106,167,19,27,219,188,214,248,169, +104,125,109,110,73,40,153,196,106,99,221,196,105,24,74,31,80,245,204,239,131,70,47,50,214,77,113,15,211,85,164,161,164,166,252, +3,248,150,212,53,144,193,157,99,144,239,255,97,215,115,163,103,41,55,211,10,252,21,54,211,118,153,23,81,74,73,237,24,149,143, +117,27,236,52,91,90,116,217,218,190,169,199,207,56,171,14,105,54,25,182,109,211,22,219,241,154,129,239,54,43,203,129,211,105, +185,141,176,82,115,163,21,167,83,165,82,207,229,177,168,114,42,112,171,180,109,131,169,21,69,157,202,66,216,62,26,4,126,80,165, +205,61,167,31,86,142,179,48,116,150,89,149,198,123,214,53,182,116,214,141,122,29,230,96,111,179,224,62,17,88,106,127,42,85,122, +248,62,17,39,88,232,119,131,6,59,193,206,117,89,136,160,137,7,6,133,29,223,11,177,156,145,251,68,241,125,169,210,216,255,240, +196,139,120,212,110,248,43,149,96,37,108,87,206,96,63,43,27,54,117,98,227,130,39,30,28,171,162,70,31,20,85,165,157,118,211,105, +175,186,103,43,142,231,249,145,19,185,190,87,57,234,53,218,126,232,122,203,51,109,39,12,249,162,239,141,153,247,60,22,40,255, +142,251,248,143,179,149,37,21,192,16,50,104,243,130,168,184,62,58,118,186,209,66,20,48,103,165,74,101,105,110,59,222,114,229, +139,75,103,88,35,218,104,67,28,150,81,37,109,145,244,197,99,100,44,30,179,41,129,31,155,146,252,215,134,21,37,182,104,115,43, +111,106,117,74,212,133,187,110,215,235,54,89,78,163,129,26,153,109,59,203,33,37,25,175,8,202,11,17,31,22,153,95,113,86,221,134, +239,81,106,153,69,167,130,54,153,45,89,51,148,104,249,97,68,22,255,61,194,218,44,98,77,74,243,134,237,55,206,82,134,107,39, +253,83,24,33,237,134,71,92,167,237,47,83,222,13,97,8,158,67,169,116,3,70,9,207,89,97,148,247,189,25,108,39,59,237,122,77,127, +141,10,104,34,249,168,175,253,37,212,240,44,46,175,176,133,41,242,178,189,16,57,1,159,113,192,247,78,176,6,115,87,89,115,14,87, +130,40,106,42,223,49,198,133,78,102,32,107,148,50,1,11,187,237,232,120,184,76,67,97,203,239,182,155,243,94,196,80,159,157,72, +149,49,101,165,221,246,157,38,101,34,182,206,175,178,149,54,37,162,150,27,82,58,242,229,182,147,209,197,118,36,87,157,118,23, +185,172,162,96,104,203,90,92,174,189,132,226,49,183,198,174,190,228,98,223,176,242,241,196,248,164,189,100,135,238,114,196,89, +143,40,251,189,169,15,223,229,233,229,159,90,147,251,185,166,85,204,130,62,92,213,207,172,237,165,87,180,121,179,80,167,111, +107,137,218,19,83,79,115,245,113,225,254,45,85,245,223,124,3,1,7,200,44,60,243,133,177,237,116,88,175,77,155,133,239,108,39, +219,168,77,239,54,11,23,235,116,194,168,29,154,20,182,35,70,109,207,46,161,213,245,218,33,115,244,153,215,254,110,208,225,161, +189,59,146,180,237,161,55,112,223,55,11,164,23,180,233,145,188,190,73,127,36,145,153,26,214,98,69,215,139,218,244,118,125,196, +26,201,145,110,224,233,74,43,39,191,121,62,113,41,109,92,208,73,3,41,237,87,105,77,187,142,127,255,100,74,135,55,11,239,103, +105,83,121,99,44,237,74,6,81,224,181,172,166,189,7,110,130,43,22,191,201,15,162,199,143,248,255,123,81,253,71,104,125,50,126, +223,224,247,250,248,157,131,223,227,251,223,59,226,119,15,254,63,30,191,127,164,232,206,59,136,81,148,58,255,239,210,198,229, +179,22,30,59,40,53,46,237,252,57,75,43,202,231,17,254,92,172,143,203,121,249,59,139,161,226,249,115,81,98,92,206,197,159,157,72, +245,221,175,22,206,215,202,223,143,254,11,250,146,74,12,88,13,0,0,0,0}; #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ @@ -486,7 +480,7 @@ private: CALLBACK (webViewPageLoadFinished, "webViewPageLoadFinished", "(JLandroid/webkit/WebView;Ljava/lang/String;)V") \ CALLBACK (webViewReceivedSslError, "webViewReceivedSslError", "(JLandroid/webkit/WebView;Landroid/webkit/SslErrorHandler;Landroid/net/http/SslError;)V") \ - DECLARE_JNI_CLASS_WITH_BYTECODE (JuceWebViewClient21, "com/roli/juce/JuceWebView21$Client", 21, JuceWebView21ByteCode, sizeof (JuceWebView21ByteCode)) + DECLARE_JNI_CLASS_WITH_BYTECODE (JuceWebViewClient21, "com/rmsl/juce/JuceWebView21$Client", 21, JuceWebView21ByteCode, sizeof (JuceWebView21ByteCode)) #undef JNI_CLASS_MEMBERS #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ @@ -496,7 +490,7 @@ private: CALLBACK (webViewPageLoadFinished, "webViewPageLoadFinished", "(JLandroid/webkit/WebView;Ljava/lang/String;)V") \ CALLBACK (webViewReceivedSslError, "webViewReceivedSslError", "(JLandroid/webkit/WebView;Landroid/webkit/SslErrorHandler;Landroid/net/http/SslError;)V") \ - DECLARE_JNI_CLASS_WITH_BYTECODE (JuceWebViewClient16, "com/roli/juce/JuceWebView$Client", 16, JuceWebView16ByteCode, sizeof (JuceWebView16ByteCode)) + DECLARE_JNI_CLASS_WITH_BYTECODE (JuceWebViewClient16, "com/rmsl/juce/JuceWebView$Client", 16, JuceWebView16ByteCode, sizeof (JuceWebView16ByteCode)) #undef JNI_CLASS_MEMBERS static jboolean JNICALL webViewPageLoadStarted (JNIEnv*, jobject /*activity*/, jlong host, jobject /*webView*/, jstring url) @@ -537,7 +531,7 @@ private: CALLBACK (webViewCloseWindowRequest, "webViewCloseWindowRequest", "(JLandroid/webkit/WebView;)V") \ CALLBACK (webViewCreateWindowRequest, "webViewCreateWindowRequest", "(JLandroid/webkit/WebView;)V") \ - DECLARE_JNI_CLASS (JuceWebChromeClient, "com/roli/juce/JuceWebView$ChromeClient") + DECLARE_JNI_CLASS (JuceWebChromeClient, "com/rmsl/juce/JuceWebView$ChromeClient") #undef JNI_CLASS_MEMBERS static void JNICALL webViewCloseWindowRequest (JNIEnv*, jobject /*activity*/, jlong host, jobject /*webView*/) @@ -598,6 +592,13 @@ WebBrowserComponent::WebBrowserComponent (const bool unloadWhenHidden) addAndMakeVisible (browser.get()); } +WebBrowserComponent::WebBrowserComponent (bool unloadWhenHidden, + const File&, + const File&) + : WebBrowserComponent (unloadWhenHidden) +{ +} + WebBrowserComponent::~WebBrowserComponent() { } diff --git a/modules/juce_gui_extra/native/juce_ios_PushNotifications.cpp b/modules/juce_gui_extra/native/juce_ios_PushNotifications.cpp index 5f0aee26..5255d835 100644 --- a/modules/juce_gui_extra/native/juce_ios_PushNotifications.cpp +++ b/modules/juce_gui_extra/native/juce_ios_PushNotifications.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_extra/native/juce_ios_UIViewComponent.mm b/modules/juce_gui_extra/native/juce_ios_UIViewComponent.mm index 7053ed6a..c606cd3c 100644 --- a/modules/juce_gui_extra/native/juce_ios_UIViewComponent.mm +++ b/modules/juce_gui_extra/native/juce_ios_UIViewComponent.mm @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_extra/native/juce_linux_X11_SystemTrayIcon.cpp b/modules/juce_gui_extra/native/juce_linux_X11_SystemTrayIcon.cpp index e9c6145f..d18a0c49 100644 --- a/modules/juce_gui_extra/native/juce_linux_X11_SystemTrayIcon.cpp +++ b/modules/juce_gui_extra/native/juce_linux_X11_SystemTrayIcon.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -32,33 +31,32 @@ class SystemTrayIconComponent::Pimpl public: Pimpl (const Image& im, Window windowH) : image (im) { - ScopedXDisplay xDisplay; - auto display = xDisplay.display; + XWindowSystemUtilities::ScopedXLock xLock; - ScopedXLock xlock (display); + auto* display = XWindowSystem::getInstance()->getDisplay(); - Screen* const screen = XDefaultScreenOfDisplay (display); - const int screenNumber = XScreenNumberOfScreen (screen); + auto* screen = X11Symbols::getInstance()->xDefaultScreenOfDisplay (display); + auto screenNumber = X11Symbols::getInstance()->xScreenNumberOfScreen (screen); String screenAtom ("_NET_SYSTEM_TRAY_S"); screenAtom << screenNumber; - Atom selectionAtom = Atoms::getCreating (display, screenAtom.toUTF8()); + Atom selectionAtom = XWindowSystemUtilities::Atoms::getCreating (display, screenAtom.toUTF8()); - XGrabServer (display); - Window managerWin = XGetSelectionOwner (display, selectionAtom); + X11Symbols::getInstance()->xGrabServer (display); + auto managerWin = X11Symbols::getInstance()->xGetSelectionOwner (display, selectionAtom); if (managerWin != None) - XSelectInput (display, managerWin, StructureNotifyMask); + X11Symbols::getInstance()->xSelectInput (display, managerWin, StructureNotifyMask); - XUngrabServer (display); - XFlush (display); + X11Symbols::getInstance()->xUngrabServer (display); + X11Symbols::getInstance()->xFlush (display); if (managerWin != None) { XEvent ev = { 0 }; ev.xclient.type = ClientMessage; ev.xclient.window = managerWin; - ev.xclient.message_type = Atoms::getCreating (display, "_NET_SYSTEM_TRAY_OPCODE"); + ev.xclient.message_type = XWindowSystemUtilities::Atoms::getCreating (display, "_NET_SYSTEM_TRAY_OPCODE"); ev.xclient.format = 32; ev.xclient.data.l[0] = CurrentTime; ev.xclient.data.l[1] = 0 /*SYSTEM_TRAY_REQUEST_DOCK*/; @@ -66,26 +64,30 @@ public: ev.xclient.data.l[3] = 0; ev.xclient.data.l[4] = 0; - XSendEvent (display, managerWin, False, NoEventMask, &ev); - XSync (display, False); + X11Symbols::getInstance()->xSendEvent (display, managerWin, False, NoEventMask, &ev); + X11Symbols::getInstance()->xSync (display, False); } // For older KDE's ... long atomData = 1; - Atom trayAtom = Atoms::getCreating (display, "KWM_DOCKWINDOW"); - XChangeProperty (display, windowH, trayAtom, trayAtom, 32, PropModeReplace, (unsigned char*) &atomData, 1); + Atom trayAtom = XWindowSystemUtilities::Atoms::getCreating (display, "KWM_DOCKWINDOW"); + X11Symbols::getInstance()->xChangeProperty (display, windowH, trayAtom, trayAtom, + 32, PropModeReplace, (unsigned char*) &atomData, 1); // For more recent KDE's... - trayAtom = Atoms::getCreating (display, "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR"); - XChangeProperty (display, windowH, trayAtom, XA_WINDOW, 32, PropModeReplace, (unsigned char*) &windowH, 1); + trayAtom = XWindowSystemUtilities::Atoms::getCreating (display, "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR"); + X11Symbols::getInstance()->xChangeProperty (display, windowH, trayAtom, XA_WINDOW, + 32, PropModeReplace, (unsigned char*) &windowH, 1); // A minimum size must be specified for GNOME and Xfce, otherwise the icon is displayed with a width of 1 - XSizeHints* hints = XAllocSizeHints(); - hints->flags = PMinSize; - hints->min_width = 22; - hints->min_height = 22; - XSetWMNormalHints (display, windowH, hints); - XFree (hints); + if (auto* hints = X11Symbols::getInstance()->xAllocSizeHints()) + { + hints->flags = PMinSize; + hints->min_width = 22; + hints->min_height = 22; + X11Symbols::getInstance()->xSetWMNormalHints (display, windowH, hints); + X11Symbols::getInstance()->xFree (hints); + } } Image image; 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 f6d3253a..eee4c210 100644 --- a/modules/juce_gui_extra/native/juce_linux_X11_WebBrowserComponent.cpp +++ b/modules/juce_gui_extra/native/juce_linux_X11_WebBrowserComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -27,6 +26,186 @@ namespace juce { +//============================================================================== +class WebKitSymbols : public DeletedAtShutdown +{ +public: + //============================================================================== + bool isWebKitAvailable() const noexcept { return webKitIsAvailable; } + + //============================================================================== + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (webkit_settings_new, juce_webkit_settings_new, + (), WebKitSettings*) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (webkit_settings_set_hardware_acceleration_policy, juce_webkit_settings_set_hardware_acceleration_policy, + (WebKitSettings*, int), void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (webkit_web_view_new_with_settings, juce_webkit_web_view_new_with_settings, + (WebKitSettings*), GtkWidget*) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (webkit_web_view_load_uri, juce_webkit_web_view_load_uri, + (WebKitWebView*, const gchar*), void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (webkit_policy_decision_use, juce_webkit_policy_decision_use, + (WebKitPolicyDecision*), void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (webkit_policy_decision_ignore, juce_webkit_policy_decision_ignore, + (WebKitPolicyDecision*), void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (webkit_web_view_go_back, juce_webkit_web_view_go_back, + (WebKitWebView*), void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (webkit_web_view_go_forward, juce_webkit_web_view_go_forward, + (WebKitWebView*), void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (webkit_web_view_reload, juce_webkit_web_view_reload, + (WebKitWebView*), void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (webkit_web_view_stop_loading, juce_webkit_web_view_stop_loading, + (WebKitWebView*), void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (webkit_uri_request_get_uri, juce_webkit_uri_request_get_uri, + (WebKitURIRequest*), const gchar*) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (webkit_navigation_action_get_request, juce_webkit_navigation_action_get_request, + (WebKitNavigationAction*), WebKitURIRequest*) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (webkit_navigation_policy_decision_get_frame_name, juce_webkit_navigation_policy_decision_get_frame_name, + (WebKitNavigationPolicyDecision*), const gchar*) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (webkit_navigation_policy_decision_get_navigation_action, juce_webkit_navigation_policy_decision_get_navigation_action, + (WebKitNavigationPolicyDecision*), WebKitNavigationAction*) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (webkit_web_view_get_uri, juce_webkit_web_view_get_uri, + (WebKitWebView*), const gchar*) + + //============================================================================== + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (gtk_init, juce_gtk_init, + (int*, char***), void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (gtk_plug_new, juce_gtk_plug_new, + (::Window), GtkWidget*) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (gtk_scrolled_window_new, juce_gtk_scrolled_window_new, + (GtkAdjustment*, GtkAdjustment*), GtkWidget*) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (gtk_container_add, juce_gtk_container_add, + (GtkContainer*, GtkWidget*), void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (gtk_widget_show_all, juce_gtk_widget_show_all, + (GtkWidget*), void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (gtk_plug_get_id, juce_gtk_plug_get_id, + (GtkPlug*), ::Window) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (gtk_main, juce_gtk_main, + (), void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (gtk_main_quit, juce_gtk_main_quit, + (), void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (g_unix_fd_add, juce_g_unix_fd_add, + (gint, GIOCondition, GUnixFDSourceFunc, gpointer), guint) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (g_object_ref, juce_g_object_ref, + (gpointer), gpointer) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (g_object_unref, juce_g_object_unref, + (gpointer), void) + + JUCE_GENERATE_FUNCTION_WITH_DEFAULT (g_signal_connect_data, juce_g_signal_connect_data, + (gpointer, const gchar*, GCallback, gpointer, GClosureNotify, GConnectFlags), gulong) + + //============================================================================== + JUCE_DECLARE_SINGLETON_SINGLETHREADED_MINIMAL (WebKitSymbols) + +private: + WebKitSymbols() = default; + + ~WebKitSymbols() + { + clearSingletonInstance(); + } + + template<typename FuncPtr> + struct SymbolBinding + { + FuncPtr& func; + const char* name; + }; + + template<typename FuncPtr> + SymbolBinding<FuncPtr> makeSymbolBinding (FuncPtr& func, const char* name) + { + return { func, name }; + } + + template <typename FuncPtr> + bool loadSymbols (DynamicLibrary& lib, SymbolBinding<FuncPtr> binding) + { + if (auto* func = lib.getFunction (binding.name)) + { + binding.func = reinterpret_cast<FuncPtr> (func); + return true; + } + + return false; + } + + template<typename FuncPtr, typename... Args> + bool loadSymbols (DynamicLibrary& lib, SymbolBinding<FuncPtr> binding, Args... args) + { + return loadSymbols (lib, binding) && loadSymbols (lib, args...); + } + + //============================================================================== + bool loadWebkitSymbols() + { + return loadSymbols (webkitLib, + makeSymbolBinding (juce_webkit_settings_new, "webkit_settings_new"), + makeSymbolBinding (juce_webkit_settings_set_hardware_acceleration_policy, "webkit_settings_set_hardware_acceleration_policy"), + makeSymbolBinding (juce_webkit_web_view_new_with_settings, "webkit_web_view_new_with_settings"), + makeSymbolBinding (juce_webkit_policy_decision_use, "webkit_policy_decision_use"), + makeSymbolBinding (juce_webkit_policy_decision_ignore, "webkit_policy_decision_ignore"), + makeSymbolBinding (juce_webkit_web_view_go_back, "webkit_web_view_go_back"), + makeSymbolBinding (juce_webkit_web_view_go_forward, "webkit_web_view_go_forward"), + makeSymbolBinding (juce_webkit_web_view_reload, "webkit_web_view_reload"), + makeSymbolBinding (juce_webkit_web_view_stop_loading, "webkit_web_view_stop_loading"), + makeSymbolBinding (juce_webkit_uri_request_get_uri, "webkit_uri_request_get_uri"), + makeSymbolBinding (juce_webkit_web_view_load_uri, "webkit_web_view_load_uri"), + makeSymbolBinding (juce_webkit_navigation_action_get_request, "webkit_navigation_action_get_request"), + makeSymbolBinding (juce_webkit_navigation_policy_decision_get_frame_name, "webkit_navigation_policy_decision_get_frame_name"), + makeSymbolBinding (juce_webkit_navigation_policy_decision_get_navigation_action, "webkit_navigation_policy_decision_get_navigation_action"), + makeSymbolBinding (juce_webkit_web_view_get_uri, "webkit_web_view_get_uri")); + } + + bool loadGtkSymbols() + { + return loadSymbols (gtkLib, + makeSymbolBinding (juce_gtk_init, "gtk_init"), + makeSymbolBinding (juce_gtk_plug_new, "gtk_plug_new"), + makeSymbolBinding (juce_gtk_scrolled_window_new, "gtk_scrolled_window_new"), + makeSymbolBinding (juce_gtk_container_add, "gtk_container_add"), + makeSymbolBinding (juce_gtk_widget_show_all, "gtk_widget_show_all"), + makeSymbolBinding (juce_gtk_plug_get_id, "gtk_plug_get_id"), + makeSymbolBinding (juce_gtk_main, "gtk_main"), + makeSymbolBinding (juce_gtk_main_quit, "gtk_main_quit"), + makeSymbolBinding (juce_g_unix_fd_add, "g_unix_fd_add"), + makeSymbolBinding (juce_g_object_ref, "g_object_ref"), + makeSymbolBinding (juce_g_object_unref, "g_object_unref"), + makeSymbolBinding (juce_g_signal_connect_data, "g_signal_connect_data")); + } + + //============================================================================== + DynamicLibrary gtkLib { "libgtk-3.so" }, webkitLib { "libwebkit2gtk-4.0.so" }; + const bool webKitIsAvailable = loadWebkitSymbols() && loadGtkSymbols(); + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WebKitSymbols) +}; + +JUCE_IMPLEMENT_SINGLETON (WebKitSymbols) + +//============================================================================== extern int juce_gtkWebkitMain (int argc, const char* argv[]); class CommandReceiver @@ -48,9 +227,9 @@ public: static void setBlocking (int fd, bool shouldBlock) { - int flags = fcntl (fd, F_GETFL); + auto flags = fcntl (fd, F_GETFL); fcntl (fd, F_SETFL, (shouldBlock ? (flags & ~O_NONBLOCK) - : (flags | O_NONBLOCK))); + : (flags | O_NONBLOCK))); } int getFd() const { return inChannel; } @@ -59,14 +238,14 @@ public: { for (;;) { - size_t len = (receivingLength ? sizeof (size_t) : bufferLength.len); + auto len = (receivingLength ? sizeof (size_t) : bufferLength.len); if (! receivingLength) buffer.realloc (len); - char* dst = (receivingLength ? bufferLength.data : buffer.getData()); + auto* dst = (receivingLength ? bufferLength.data : buffer.getData()); - ssize_t actual = read (inChannel, &dst[pos], static_cast<size_t> (len - pos)); + auto actual = read (inChannel, &dst[pos], static_cast<size_t> (len - pos)); if (actual < 0) { @@ -102,13 +281,13 @@ public: if (! params.isVoid()) obj->setProperty (getParamIdentifier(), params); - String json (JSON::toString (var (obj.get()))); + auto json = JSON::toString (var (obj.get())); - size_t jsonLength = static_cast<size_t> (json.length()); - size_t len = sizeof (size_t) + jsonLength; + auto jsonLength = static_cast<size_t> (json.length()); + auto len = sizeof (size_t) + jsonLength; HeapBlock<char> buffer (len); - char* dst = buffer.getData(); + auto* dst = buffer.getData(); memcpy (dst, &jsonLength, sizeof (size_t)); dst += sizeof (size_t); @@ -117,21 +296,24 @@ public: ssize_t ret; - do + for (;;) { ret = write (outChannel, buffer.getData(), len); - } while (ret == -1 && errno == EINTR); + + if (ret != -1 || errno != EINTR) + break; + } } private: void parseJSON (const String& json) { - var object (JSON::fromString (json)); + auto object = JSON::fromString (json); if (! object.isVoid()) { - String cmd (object.getProperty (getCmdIdentifier(), var()).toString()); - var params (object.getProperty (getParamIdentifier(), var())); + auto cmd = object.getProperty (getCmdIdentifier(), {}).toString(); + auto params = object.getProperty (getParamIdentifier(), {}); if (responder != nullptr) responder->handleCommand (cmd, params); @@ -141,105 +323,101 @@ private: static Identifier getCmdIdentifier() { static Identifier Id ("cmd"); return Id; } static Identifier getParamIdentifier() { static Identifier Id ("params"); return Id; } - Responder* responder; - int inChannel; + Responder* responder = nullptr; + int inChannel = 0; size_t pos = 0; bool receivingLength = true; union { char data [sizeof (size_t)]; size_t len; } bufferLength; HeapBlock<char> buffer; }; +#define juce_g_signal_connect(instance, detailed_signal, c_handler, data) \ + WebKitSymbols::getInstance()->juce_g_signal_connect_data (instance, detailed_signal, c_handler, data, nullptr, (GConnectFlags) 0) + //============================================================================== class GtkChildProcess : private CommandReceiver::Responder { public: //============================================================================== GtkChildProcess (int inChannel, int outChannelToUse) - : outChannel (outChannelToUse), receiver (this, inChannel) + : outChannel (outChannelToUse), + receiver (this, inChannel) {} - typedef void (*SetHardwareAcclPolicyFunctionPtr) (WebKitSettings*, int); - int entry() { - CommandReceiver::setBlocking (outChannel, true); + CommandReceiver::setBlocking (outChannel, true); - gtk_init (nullptr, nullptr); + WebKitSymbols::getInstance()->juce_gtk_init (nullptr, nullptr); - WebKitSettings* settings = webkit_settings_new(); + auto* settings = WebKitSymbols::getInstance()->juce_webkit_settings_new(); + WebKitSymbols::getInstance()->juce_webkit_settings_set_hardware_acceleration_policy (settings, + /* WEBKIT_HARDWARE_ACCELERATION_POLICY_NEVER */ 2); - // webkit_settings_set_hardware_acceleration_policy was only added recently to webkit2 - // but is needed when running a WebBrowserComponent in a Parallels VM with 3D acceleration enabled - auto setHardwarePolicy - = reinterpret_cast<SetHardwareAcclPolicyFunctionPtr> (dlsym (RTLD_DEFAULT, "webkit_settings_set_hardware_acceleration_policy")); + auto* plug = WebKitSymbols::getInstance()->juce_gtk_plug_new (0); + auto* container = WebKitSymbols::getInstance()->juce_gtk_scrolled_window_new (nullptr, nullptr); - if (setHardwarePolicy != nullptr) - setHardwarePolicy (settings, 2 /*WEBKIT_HARDWARE_ACCELERATION_POLICY_NEVER*/); + auto* webviewWidget = WebKitSymbols::getInstance()->juce_webkit_web_view_new_with_settings (settings); + webview = (WebKitWebView*) webviewWidget; - GtkWidget *plug; + WebKitSymbols::getInstance()->juce_gtk_container_add ((GtkContainer*) container, webviewWidget); + WebKitSymbols::getInstance()->juce_gtk_container_add ((GtkContainer*) plug, container); - plug = gtk_plug_new(0); - GtkWidget* container; - container = gtk_scrolled_window_new (nullptr, nullptr); + WebKitSymbols::getInstance()->juce_webkit_web_view_load_uri (webview, "about:blank"); - GtkWidget* webviewWidget = webkit_web_view_new_with_settings (settings); - webview = WEBKIT_WEB_VIEW (webviewWidget); + juce_g_signal_connect (webview, "decide-policy", + (GCallback) decidePolicyCallback, this); + juce_g_signal_connect (webview, "load-changed", + (GCallback) loadChangedCallback, this); - gtk_container_add (GTK_CONTAINER (container), webviewWidget); - gtk_container_add (GTK_CONTAINER (plug), container); - - webkit_web_view_load_uri (webview, "about:blank"); - - g_signal_connect (webview, "decide-policy", - G_CALLBACK (decidePolicyCallback), this); - - g_signal_connect (webview, "load-changed", - G_CALLBACK (loadChangedCallback), this); - - g_signal_connect (webview, "load-failed", - G_CALLBACK (loadFailedCallback), this); - - gtk_widget_show_all (plug); - unsigned long wID = (unsigned long) gtk_plug_get_id (GTK_PLUG (plug)); + juce_g_signal_connect (webview, "load-failed", + (GCallback) loadFailedCallback, this); + WebKitSymbols::getInstance()->juce_gtk_widget_show_all (plug); + auto wID = (unsigned long) WebKitSymbols::getInstance()->juce_gtk_plug_get_id ((GtkPlug*) plug); ssize_t ret; - do { + for (;;) + { ret = write (outChannel, &wID, sizeof (wID)); - } while (ret == -1 && errno == EINTR); - g_unix_fd_add (receiver.getFd(), G_IO_IN, pipeReadyStatic, this); + if (ret != -1 || errno != EINTR) + break; + } + + WebKitSymbols::getInstance()->juce_g_unix_fd_add (receiver.getFd(), G_IO_IN, pipeReadyStatic, this); receiver.tryNextRead(); - gtk_main(); + WebKitSymbols::getInstance()->juce_gtk_main(); + + WebKitSymbols::getInstance()->deleteInstance(); return 0; } void goToURL (const var& params) { static Identifier urlIdentifier ("url"); - String url (params.getProperty (urlIdentifier, var()).toString()); + auto url = params.getProperty (urlIdentifier, var()).toString(); - webkit_web_view_load_uri (webview, url.toRawUTF8()); + WebKitSymbols::getInstance()->juce_webkit_web_view_load_uri (webview, url.toRawUTF8()); } void handleDecisionResponse (const var& params) { - WebKitPolicyDecision* decision - = (WebKitPolicyDecision*) ((int64) params.getProperty ("decision_id", var (0))); + auto* decision = (WebKitPolicyDecision*) ((int64) params.getProperty ("decision_id", var (0))); bool allow = params.getProperty ("allow", var (false)); if (decision != nullptr && decisions.contains (decision)) { if (allow) - webkit_policy_decision_use (decision); + WebKitSymbols::getInstance()->juce_webkit_policy_decision_use (decision); else - webkit_policy_decision_ignore (decision); + WebKitSymbols::getInstance()->juce_webkit_policy_decision_ignore (decision); decisions.removeAllInstancesOf (decision); - g_object_unref (decision); + WebKitSymbols::getInstance()->juce_g_object_unref (decision); } } @@ -248,10 +426,10 @@ public: { if (cmd == "quit") quit(); else if (cmd == "goToURL") goToURL (params); - else if (cmd == "goBack") webkit_web_view_go_back (webview); - else if (cmd == "goForward") webkit_web_view_go_forward (webview); - else if (cmd == "refresh") webkit_web_view_reload (webview); - else if (cmd == "stop") webkit_web_view_stop_loading (webview); + else if (cmd == "goBack") WebKitSymbols::getInstance()->juce_webkit_web_view_go_back (webview); + else if (cmd == "goForward") WebKitSymbols::getInstance()->juce_webkit_web_view_go_forward (webview); + else if (cmd == "refresh") WebKitSymbols::getInstance()->juce_webkit_web_view_reload (webview); + else if (cmd == "stop") WebKitSymbols::getInstance()->juce_webkit_web_view_stop_loading (webview); else if (cmd == "decision") handleDecisionResponse (params); } @@ -274,7 +452,13 @@ public: void quit() { - gtk_main_quit(); + WebKitSymbols::getInstance()->juce_gtk_main_quit(); + } + + String getURIStringForAction (WebKitNavigationAction* action) + { + auto* request = WebKitSymbols::getInstance()->juce_webkit_navigation_action_get_request (action); + return WebKitSymbols::getInstance()->juce_webkit_uri_request_get_uri (request); } bool onNavigation (String frameName, @@ -283,12 +467,12 @@ public: { if (decision != nullptr && frameName.isEmpty()) { - g_object_ref (decision); + WebKitSymbols::getInstance()->juce_g_object_ref (decision); decisions.add (decision); DynamicObject::Ptr params = new DynamicObject; - params->setProperty ("url", String (webkit_uri_request_get_uri (webkit_navigation_action_get_request (action)))); + params->setProperty ("url", getURIStringForAction (action)); params->setProperty ("decision_id", (int64) decision); CommandReceiver::sendCommand (outChannel, "pageAboutToLoad", var (params.get())); @@ -306,11 +490,11 @@ public: { DynamicObject::Ptr params = new DynamicObject; - params->setProperty ("url", String (webkit_uri_request_get_uri (webkit_navigation_action_get_request (action)))); + params->setProperty ("url", getURIStringForAction (action)); CommandReceiver::sendCommand (outChannel, "newWindowAttemptingToLoad", var (params.get())); // never allow new windows - webkit_policy_decision_ignore (decision); + WebKitSymbols::getInstance()->juce_webkit_policy_decision_ignore (decision); return true; } @@ -324,7 +508,7 @@ public: { DynamicObject::Ptr params = new DynamicObject; - params->setProperty ("url", String (webkit_web_view_get_uri (webview))); + params->setProperty ("url", String (WebKitSymbols::getInstance()->juce_webkit_web_view_get_uri (webview))); CommandReceiver::sendCommand (outChannel, "pageFinishedLoading", var (params.get())); } } @@ -336,31 +520,31 @@ public: { case WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION: { - WebKitNavigationPolicyDecision* navigationDecision = WEBKIT_NAVIGATION_POLICY_DECISION (decision); - const char* frameName = webkit_navigation_policy_decision_get_frame_name (navigationDecision); + auto* navigationDecision = (WebKitNavigationPolicyDecision*) decision; + auto* frameName = WebKitSymbols::getInstance()->juce_webkit_navigation_policy_decision_get_frame_name (navigationDecision); return onNavigation (String (frameName != nullptr ? frameName : ""), - webkit_navigation_policy_decision_get_navigation_action (navigationDecision), + WebKitSymbols::getInstance()->juce_webkit_navigation_policy_decision_get_navigation_action (navigationDecision), decision); } break; case WEBKIT_POLICY_DECISION_TYPE_NEW_WINDOW_ACTION: { - WebKitNavigationPolicyDecision* navigationDecision = WEBKIT_NAVIGATION_POLICY_DECISION (decision); - const char* frameName = webkit_navigation_policy_decision_get_frame_name (navigationDecision); + auto* navigationDecision = (WebKitNavigationPolicyDecision*) decision; + auto* frameName = WebKitSymbols::getInstance()->juce_webkit_navigation_policy_decision_get_frame_name (navigationDecision); return onNewWindow (String (frameName != nullptr ? frameName : ""), - webkit_navigation_policy_decision_get_navigation_action (navigationDecision), + WebKitSymbols::getInstance()->juce_webkit_navigation_policy_decision_get_navigation_action (navigationDecision), decision); } break; case WEBKIT_POLICY_DECISION_TYPE_RESPONSE: { - WebKitResponsePolicyDecision *response = WEBKIT_RESPONSE_POLICY_DECISION (decision); + auto* response = (WebKitNavigationPolicyDecision*) decision; // for now just always allow response requests ignoreUnused (response); - webkit_policy_decision_use (decision); + WebKitSymbols::getInstance()->juce_webkit_policy_decision_use (decision); return true; } break; @@ -390,7 +574,7 @@ private: WebKitPolicyDecisionType decisionType, gpointer user) { - GtkChildProcess& owner = *reinterpret_cast<GtkChildProcess*> (user); + auto& owner = *reinterpret_cast<GtkChildProcess*> (user); return (owner.onDecidePolicy (decision, decisionType) ? TRUE : FALSE); } @@ -398,7 +582,7 @@ private: WebKitLoadEvent loadEvent, gpointer user) { - GtkChildProcess& owner = *reinterpret_cast<GtkChildProcess*> (user); + auto& owner = *reinterpret_cast<GtkChildProcess*> (user); owner.onLoadChanged (loadEvent); } @@ -408,11 +592,11 @@ private: GError* error, gpointer user) { - GtkChildProcess& owner = *reinterpret_cast<GtkChildProcess*> (user); + auto& owner = *reinterpret_cast<GtkChildProcess*> (user); owner.onLoadFailed (error); } - int outChannel; + int outChannel = 0; CommandReceiver receiver; WebKitWebView* webview = nullptr; Array<WebKitPolicyDecision*> decisions; @@ -425,7 +609,9 @@ class WebBrowserComponent::Pimpl : private Thread, public: Pimpl (WebBrowserComponent& parent) : Thread ("Webview"), owner (parent) - {} + { + webKitIsAvailable = WebKitSymbols::getInstance()->isWebKitAvailable(); + } ~Pimpl() override { @@ -435,9 +621,12 @@ public: //============================================================================== void init() { + if (! webKitIsAvailable) + return; + launchChild(); - int ret = pipe (threadControl); + auto ret = pipe (threadControl); ignoreUnused (ret); jassert (ret == 0); @@ -448,7 +637,7 @@ public: CommandReceiver::setBlocking (threadControl[1], true); unsigned long windowHandle; - ssize_t actual = read (inChannel, &windowHandle, sizeof (windowHandle)); + auto actual = read (inChannel, &windowHandle, sizeof (windowHandle)); if (actual != (ssize_t) sizeof (windowHandle)) { @@ -469,6 +658,9 @@ public: void quit() { + if (! webKitIsAvailable) + return; + if (isThreadRunning()) { signalThreadShouldExit(); @@ -476,10 +668,13 @@ public: char ignore = 0; ssize_t ret; - do + for (;;) { ret = write (threadControl[1], &ignore, 1); - } while (ret == -1 && errno == EINTR); + + if (ret != -1 || errno != EINTR) + break; + } waitForThreadToExit (-1); receiver = nullptr; @@ -487,7 +682,7 @@ public: if (childProcess != 0) { - CommandReceiver::sendCommand (outChannel, "quit", var()); + CommandReceiver::sendCommand (outChannel, "quit", {}); killChild(); } } @@ -495,6 +690,9 @@ public: //============================================================================== void goToURL (const String& url, const StringArray* headers, const MemoryBlock* postData) { + if (! webKitIsAvailable) + return; + DynamicObject::Ptr params = new DynamicObject; params->setProperty ("url", url); @@ -508,16 +706,17 @@ public: CommandReceiver::sendCommand (outChannel, "goToURL", var (params.get())); } - void goBack() { CommandReceiver::sendCommand (outChannel, "goBack", var()); } - void goForward() { CommandReceiver::sendCommand (outChannel, "goForward", var()); } - void refresh() { CommandReceiver::sendCommand (outChannel, "refresh", var()); } - void stop() { CommandReceiver::sendCommand (outChannel, "stop", var()); } + void goBack() { if (webKitIsAvailable) CommandReceiver::sendCommand (outChannel, "goBack", {}); } + void goForward() { if (webKitIsAvailable) CommandReceiver::sendCommand (outChannel, "goForward", {}); } + void refresh() { if (webKitIsAvailable) CommandReceiver::sendCommand (outChannel, "refresh", {}); } + void stop() { if (webKitIsAvailable) CommandReceiver::sendCommand (outChannel, "stop", {}); } void resized() { if (xembed != nullptr) xembed->setBounds (owner.getLocalBounds()); } + private: //============================================================================== void killChild() @@ -526,7 +725,7 @@ private: { xembed = nullptr; - int status = 0, result; + int status = 0, result = 0; result = waitpid (childProcess, &status, WNOHANG); for (int i = 0; i < 15 && (! WIFEXITED(status) || result != childProcess); ++i) @@ -539,11 +738,14 @@ private: status = 0; if (! WIFEXITED(status) || result != childProcess) { - do + for (;;) { kill (childProcess, SIGTERM); waitpid (childProcess, &status, 0); - } while (! WIFEXITED(status)); + + if (WIFEXITED (status)) + break; + } } childProcess = 0; @@ -552,16 +754,15 @@ private: void launchChild() { - int ret; int inPipe[2], outPipe[2]; - ret = pipe (inPipe); + auto ret = pipe (inPipe); ignoreUnused (ret); jassert (ret == 0); ret = pipe (outPipe); ignoreUnused (ret); jassert (ret == 0); - int pid = fork(); + auto pid = fork(); if (pid == 0) { close (inPipe[0]); @@ -619,7 +820,7 @@ private: bool shouldExit() { char ignore; - ssize_t result = read (threadControl[0], &ignore, 1); + auto result = read (threadControl[0], &ignore, 1); return (result != -1 || (errno != EAGAIN && errno != EWOULDBLOCK)); } @@ -627,7 +828,7 @@ private: //============================================================================== void handleCommandOnMessageThread (const String& cmd, const var& params) { - String url (params.getProperty ("url", var()).toString()); + auto url = params.getProperty ("url", var()).toString(); if (cmd == "pageAboutToLoad") handlePageAboutToLoad (url, params); else if (cmd == "pageFinishedLoading") owner.pageFinishedLoading (url); @@ -687,12 +888,13 @@ private: owner->handleCommandOnMessageThread (cmdToSend, paramsToSend); } - Pimpl* owner; + Pimpl* owner = nullptr; String cmdToSend; var paramsToSend; }; -private: + bool webKitIsAvailable = false; + WebBrowserComponent& owner; std::unique_ptr<CommandReceiver> receiver; int childProcess = 0, inChannel = 0, outChannel = 0; @@ -703,9 +905,9 @@ private: }; //============================================================================== -WebBrowserComponent::WebBrowserComponent (const bool unloadPageWhenBrowserIsHidden_) +WebBrowserComponent::WebBrowserComponent (const bool unloadWhenHidden) : browser (new Pimpl (*this)), - unloadPageWhenBrowserIsHidden (unloadPageWhenBrowserIsHidden_) + unloadPageWhenBrowserIsHidden (unloadWhenHidden) { ignoreUnused (blankPageShown); ignoreUnused (unloadPageWhenBrowserIsHidden); @@ -715,6 +917,13 @@ WebBrowserComponent::WebBrowserComponent (const bool unloadPageWhenBrowserIsHidd browser->init(); } +WebBrowserComponent::WebBrowserComponent (bool unloadWhenHidden, + const File&, + const File&) + : WebBrowserComponent (unloadWhenHidden) +{ +} + WebBrowserComponent::~WebBrowserComponent() { } @@ -810,11 +1019,12 @@ void WebBrowserComponent::clearCookies() int juce_gtkWebkitMain (int argc, const char* argv[]) { - if (argc != 4) return -1; - + if (argc != 4) + return -1; GtkChildProcess child (String (argv[2]).getIntValue(), String (argv[3]).getIntValue()); + return child.entry(); } diff --git a/modules/juce_gui_extra/native/juce_linux_XEmbedComponent.cpp b/modules/juce_gui_extra/native/juce_linux_XEmbedComponent.cpp index d1c0ae71..3cc7a8e3 100644 --- a/modules/juce_gui_extra/native/juce_linux_XEmbedComponent.cpp +++ b/modules/juce_gui_extra/native/juce_linux_XEmbedComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -31,8 +30,43 @@ bool juce_handleXEmbedEvent (ComponentPeer*, void*); Window juce_getCurrentFocusWindow (ComponentPeer*); //============================================================================== -unsigned long juce_createKeyProxyWindow (ComponentPeer*); -void juce_deleteKeyProxyWindow (ComponentPeer*); +::Window juce_createKeyProxyWindow (ComponentPeer*); +void juce_deleteKeyProxyWindow (::Window); + +//============================================================================== +enum +{ + maxXEmbedVersionToSupport = 0 +}; + +enum +{ + XEMBED_MAPPED = (1<<0) +}; + +enum +{ + XEMBED_EMBEDDED_NOTIFY = 0, + XEMBED_WINDOW_ACTIVATE = 1, + XEMBED_WINDOW_DEACTIVATE = 2, + XEMBED_REQUEST_FOCUS = 3, + XEMBED_FOCUS_IN = 4, + XEMBED_FOCUS_OUT = 5, + XEMBED_FOCUS_NEXT = 6, + XEMBED_FOCUS_PREV = 7, + XEMBED_MODALITY_ON = 10, + XEMBED_MODALITY_OFF = 11, + XEMBED_REGISTER_ACCELERATOR = 12, + XEMBED_UNREGISTER_ACCELERATOR = 13, + XEMBED_ACTIVATE_ACCELERATOR = 14 +}; + +enum +{ + XEMBED_FOCUS_CURRENT = 0, + XEMBED_FOCUS_FIRST = 1, + XEMBED_FOCUS_LAST = 2 +}; //============================================================================== class XEmbedComponent::Pimpl : private ComponentListener @@ -48,7 +82,7 @@ public: ~SharedKeyWindow() { - juce_deleteKeyProxyWindow (keyPeer); + juce_deleteKeyProxyWindow (keyProxy); auto& keyWindows = getKeyWindows(); keyWindows.remove (keyPeer); @@ -103,8 +137,12 @@ public: //============================================================================== Pimpl (XEmbedComponent& parent, Window x11Window, bool wantsKeyboardFocus, bool isClientInitiated, bool shouldAllowResize) - : owner (parent), atoms (x11display.display), clientInitiated (isClientInitiated), - wantsFocus (wantsKeyboardFocus), allowResize (shouldAllowResize) + : owner (parent), + infoAtom (XWindowSystem::getInstance()->getAtoms().XembedInfo), + messageTypeAtom (XWindowSystem::getInstance()->getAtoms().XembedMsgType), + clientInitiated (isClientInitiated), + wantsFocus (wantsKeyboardFocus), + allowResize (shouldAllowResize) { getWidgets().add (this); @@ -125,16 +163,17 @@ public: if (host != 0) { auto dpy = getDisplay(); - XDestroyWindow (dpy, host); - XSync (dpy, false); - const long mask = NoEventMask | KeyPressMask | KeyReleaseMask - | EnterWindowMask | LeaveWindowMask | PointerMotionMask - | KeymapStateMask | ExposureMask | StructureNotifyMask - | FocusChangeMask; + X11Symbols::getInstance()->xDestroyWindow (dpy, host); + X11Symbols::getInstance()->xSync (dpy, false); + + auto mask = NoEventMask | KeyPressMask | KeyReleaseMask + | EnterWindowMask | LeaveWindowMask | PointerMotionMask + | KeymapStateMask | ExposureMask | StructureNotifyMask + | FocusChangeMask; XEvent event; - while (XCheckWindowEvent (dpy, host, mask, &event) == True) + while (X11Symbols::getInstance()->xCheckWindowEvent (dpy, host, mask, &event) == True) {} host = 0; @@ -163,22 +202,22 @@ public: else { auto newBounds = getX11BoundsFromJuce(); - XResizeWindow (dpy, client, static_cast<unsigned int> (newBounds.getWidth()), - static_cast<unsigned int> (newBounds.getHeight())); + X11Symbols::getInstance()->xResizeWindow (dpy, client, static_cast<unsigned int> (newBounds.getWidth()), + static_cast<unsigned int> (newBounds.getHeight())); } auto eventMask = StructureNotifyMask | PropertyChangeMask | FocusChangeMask; XWindowAttributes clientAttr; - XGetWindowAttributes (dpy, client, &clientAttr); + X11Symbols::getInstance()->xGetWindowAttributes (dpy, client, &clientAttr); if ((eventMask & clientAttr.your_event_mask) != eventMask) - XSelectInput (dpy, client, clientAttr.your_event_mask | eventMask); + X11Symbols::getInstance()->xSelectInput (dpy, client, clientAttr.your_event_mask | eventMask); getXEmbedMappedFlag(); if (shouldReparent) - XReparentWindow (dpy, client, host, 0, 0); + X11Symbols::getInstance()->xReparentWindow (dpy, client, host, 0, 0); if (supportsXembed) sendXEmbedEvent (CurrentTime, XEMBED_EMBEDDED_NOTIFY, 0, (long) host, xembedVersion); @@ -226,9 +265,7 @@ private: //============================================================================== XEmbedComponent& owner; Window client = 0, host = 0; - - ScopedXDisplay x11display; - Atoms atoms; + Atom infoAtom, messageTypeAtom; bool clientInitiated; bool wantsFocus = false; @@ -250,27 +287,27 @@ private: auto newBounds = getX11BoundsFromJuce(); XWindowAttributes attr; - if (XGetWindowAttributes (dpy, host, &attr)) + if (X11Symbols::getInstance()->xGetWindowAttributes (dpy, host, &attr)) { Rectangle<int> currentBounds (attr.x, attr.y, attr.width, attr.height); if (currentBounds != newBounds) { - XMoveResizeWindow (dpy, host, newBounds.getX(), newBounds.getY(), - static_cast<unsigned int> (newBounds.getWidth()), - static_cast<unsigned int> (newBounds.getHeight())); + X11Symbols::getInstance()->xMoveResizeWindow (dpy, host, newBounds.getX(), newBounds.getY(), + static_cast<unsigned int> (newBounds.getWidth()), + static_cast<unsigned int> (newBounds.getHeight())); } } - if (client != 0 && XGetWindowAttributes (dpy, client, &attr)) + if (client != 0 && X11Symbols::getInstance()->xGetWindowAttributes (dpy, client, &attr)) { Rectangle<int> currentBounds (attr.x, attr.y, attr.width, attr.height); if ((currentBounds.getWidth() != newBounds.getWidth() || currentBounds.getHeight() != newBounds.getHeight())) { - XMoveResizeWindow (dpy, client, 0, 0, - static_cast<unsigned int> (newBounds.getWidth()), - static_cast<unsigned int> (newBounds.getHeight())); + X11Symbols::getInstance()->xMoveResizeWindow (dpy, client, 0, 0, + static_cast<unsigned int> (newBounds.getWidth()), + static_cast<unsigned int> (newBounds.getHeight())); } } } @@ -280,8 +317,8 @@ private: void createHostWindow() { auto dpy = getDisplay(); - int defaultScreen = XDefaultScreen (dpy); - Window root = RootWindow (dpy, defaultScreen); + int defaultScreen = X11Symbols::getInstance()->xDefaultScreen (dpy); + Window root = X11Symbols::getInstance()->xRootWindow (dpy, defaultScreen); XSetWindowAttributes swa; swa.border_pixel = 0; @@ -289,10 +326,10 @@ private: swa.override_redirect = True; swa.event_mask = SubstructureNotifyMask | StructureNotifyMask | FocusChangeMask; - host = XCreateWindow (dpy, root, 0, 0, 1, 1, 0, CopyFromParent, - InputOutput, CopyFromParent, - CWEventMask | CWBorderPixel | CWBackPixmap | CWOverrideRedirect, - &swa); + host = X11Symbols::getInstance()->xCreateWindow (dpy, root, 0, 0, 1, 1, 0, CopyFromParent, + InputOutput, CopyFromParent, + CWEventMask | CWBorderPixel | CWBackPixmap | CWOverrideRedirect, + &swa); } void removeClient() @@ -300,21 +337,23 @@ private: if (client != 0) { auto dpy = getDisplay(); - XSelectInput (dpy, client, 0); + X11Symbols::getInstance()->xSelectInput (dpy, client, 0); keyWindow = nullptr; - int defaultScreen = XDefaultScreen (dpy); - Window root = RootWindow (dpy, defaultScreen); + int defaultScreen = X11Symbols::getInstance()->xDefaultScreen (dpy); + Window root = X11Symbols::getInstance()->xRootWindow (dpy, defaultScreen); if (hasBeenMapped) { - XUnmapWindow (dpy, client); + X11Symbols::getInstance()->xUnmapWindow (dpy, client); hasBeenMapped = false; } - XReparentWindow (dpy, client, root, 0, 0); + X11Symbols::getInstance()->xReparentWindow (dpy, client, root, 0, 0); client = 0; + + X11Symbols::getInstance()->xSync (dpy, False); } } @@ -329,9 +368,9 @@ private: hasBeenMapped = shouldBeMapped; if (shouldBeMapped) - XMapWindow (getDisplay(), client); + X11Symbols::getInstance()->xMapWindow (getDisplay(), client); else - XUnmapWindow (getDisplay(), client); + X11Symbols::getInstance()->xUnmapWindow (getDisplay(), client); } } } @@ -344,12 +383,12 @@ private: return {}; } - Display* getDisplay() { return reinterpret_cast<Display*> (x11display.display); } + Display* getDisplay() { return XWindowSystem::getInstance()->getDisplay(); } //============================================================================== bool getXEmbedMappedFlag() { - GetXProperty embedInfo (x11display.display, client, atoms.XembedInfo, 0, 2, false, atoms.XembedInfo); + XWindowSystemUtilities::GetXProperty embedInfo (client, infoAtom, 0, 2, false, infoAtom); if (embedInfo.success && embedInfo.actualFormat == 32 && embedInfo.numItems >= 2 && embedInfo.data != nullptr) @@ -377,7 +416,7 @@ private: //============================================================================== void propertyChanged (const Atom& a) { - if (a == atoms.XembedInfo) + if (a == infoAtom) updateMapping(); } @@ -386,20 +425,20 @@ private: XWindowAttributes attr; auto dpy = getDisplay(); - if (XGetWindowAttributes (dpy, client, &attr)) + if (X11Symbols::getInstance()->xGetWindowAttributes (dpy, client, &attr)) { XWindowAttributes hostAttr; - if (XGetWindowAttributes (dpy, host, &hostAttr)) + if (X11Symbols::getInstance()->xGetWindowAttributes (dpy, host, &hostAttr)) if (attr.width != hostAttr.width || attr.height != hostAttr.height) - XResizeWindow (dpy, host, (unsigned int) attr.width, (unsigned int) attr.height); + X11Symbols::getInstance()->xResizeWindow (dpy, host, (unsigned int) attr.width, (unsigned int) attr.height); // as the client window is not on any screen yet, we need to guess // on which screen it might appear to get a scaling factor :-( auto& displays = Desktop::getInstance().getDisplays(); auto* peer = owner.getPeer(); const double scale = (peer != nullptr ? peer->getPlatformScaleFactor() - : displays.getMainDisplay().scale); + : displays.getPrimaryDisplay()->scale); Point<int> topLeftInPeer = (peer != nullptr ? peer->getComponent().getLocalPoint (&owner, Point<int> (0, 0)) @@ -428,14 +467,14 @@ private: keyWindow = nullptr; auto dpy = getDisplay(); - Window rootWindow = RootWindow (dpy, DefaultScreen (dpy)); + Window rootWindow = X11Symbols::getInstance()->xRootWindow (dpy, DefaultScreen (dpy)); Rectangle<int> newBounds = getX11BoundsFromJuce(); if (newPeer == nullptr) - XUnmapWindow (dpy, host); + X11Symbols::getInstance()->xUnmapWindow (dpy, host); Window newParent = (newPeer != nullptr ? getParentX11Window() : rootWindow); - XReparentWindow (dpy, host, newParent, newBounds.getX(), newBounds.getY()); + X11Symbols::getInstance()->xReparentWindow (dpy, host, newParent, newBounds.getX(), newBounds.getY()); lastPeer = newPeer; @@ -448,7 +487,7 @@ private: } componentMovedOrResized (owner, true, true); - XMapWindow (dpy, host); + X11Symbols::getInstance()->xMapWindow (dpy, host); broughtToFront(); } @@ -458,7 +497,7 @@ private: void updateKeyFocus() { if (lastPeer != nullptr && lastPeer->isFocused()) - XSetInputFocus (getDisplay(), getCurrentFocusWindow (lastPeer), RevertToParent, CurrentTime); + X11Symbols::getInstance()->xSetInputFocus (getDisplay(), getCurrentFocusWindow (lastPeer), RevertToParent, CurrentTime); } //============================================================================== @@ -480,6 +519,9 @@ private: if (wantsFocus) owner.moveKeyboardFocusToSibling (false); break; + + default: + break; } } @@ -500,6 +542,9 @@ private: MessageManager::callAsync ([this] {componentMovedOrResized (owner, true, true);}); return true; + + default: + break; } } else if (e.xany.window == host && host != 0) @@ -527,7 +572,7 @@ private: return true; case ClientMessage: - if (e.xclient.message_type == atoms.XembedMsgType && e.xclient.format == 32) + if (e.xclient.message_type == messageTypeAtom && e.xclient.format == 32) { handleXembedCmd ((::Time) e.xclient.data.l[0], e.xclient.data.l[1], e.xclient.data.l[2], e.xclient.data.l[3], @@ -536,6 +581,9 @@ private: return true; } break; + + default: + break; } } @@ -551,7 +599,7 @@ private: ::memset (&msg, 0, sizeof (XClientMessageEvent)); msg.window = client; msg.type = ClientMessage; - msg.message_type = atoms.XembedMsgType; + msg.message_type = messageTypeAtom; msg.format = 32; msg.data.l[0] = (long) xTime; msg.data.l[1] = opcode; @@ -559,8 +607,8 @@ private: msg.data.l[3] = data1; msg.data.l[4] = data2; - XSendEvent (dpy, client, False, NoEventMask, (XEvent*) &msg); - XSync (dpy, False); + X11Symbols::getInstance()->xSendEvent (dpy, client, False, NoEventMask, (XEvent*) &msg); + X11Symbols::getInstance()->xSync (dpy, False); } Rectangle<int> getX11BoundsFromJuce() @@ -642,6 +690,7 @@ void XEmbedComponent::focusGained (FocusChangeType changeType) { pimpl->focu void XEmbedComponent::focusLost (FocusChangeType changeType) { pimpl->focusLost (changeType); } void XEmbedComponent::broughtToFront() { pimpl->broughtToFront(); } unsigned long XEmbedComponent::getHostWindowID() { return pimpl->getHostWindowID(); } +void XEmbedComponent::removeClient() { pimpl->setClient (0, true); } //============================================================================== bool juce_handleXEmbedEvent (ComponentPeer* p, void* e) diff --git a/modules/juce_gui_extra/native/juce_mac_AppleRemote.mm b/modules/juce_gui_extra/native/juce_mac_AppleRemote.mm index 78550f6f..6aef8435 100644 --- a/modules/juce_gui_extra/native/juce_mac_AppleRemote.mm +++ b/modules/juce_gui_extra/native/juce_mac_AppleRemote.mm @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_extra/native/juce_mac_CarbonViewWrapperComponent.h b/modules/juce_gui_extra/native/juce_mac_CarbonViewWrapperComponent.h index 41ddde60..0e48ae84 100644 --- a/modules/juce_gui_extra/native/juce_mac_CarbonViewWrapperComponent.h +++ b/modules/juce_gui_extra/native/juce_mac_CarbonViewWrapperComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_extra/native/juce_mac_NSViewComponent.mm b/modules/juce_gui_extra/native/juce_mac_NSViewComponent.mm index daf3ad3a..a4d997a8 100644 --- a/modules/juce_gui_extra/native/juce_mac_NSViewComponent.mm +++ b/modules/juce_gui_extra/native/juce_mac_NSViewComponent.mm @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_extra/native/juce_mac_PushNotifications.cpp b/modules/juce_gui_extra/native/juce_mac_PushNotifications.cpp index 3d017be1..17880e77 100644 --- a/modules/juce_gui_extra/native/juce_mac_PushNotifications.cpp +++ b/modules/juce_gui_extra/native/juce_mac_PushNotifications.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -24,6 +23,8 @@ ============================================================================== */ +JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wdeprecated-declarations") + namespace juce { @@ -563,3 +564,5 @@ private: }; } // namespace juce + +JUCE_END_IGNORE_WARNINGS_GCC_LIKE diff --git a/modules/juce_gui_extra/native/juce_mac_SystemTrayIcon.cpp b/modules/juce_gui_extra/native/juce_mac_SystemTrayIcon.cpp index 3086162b..b92b3b37 100644 --- a/modules/juce_gui_extra/native/juce_mac_SystemTrayIcon.cpp +++ b/modules/juce_gui_extra/native/juce_mac_SystemTrayIcon.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -27,11 +26,7 @@ namespace juce { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunguarded-availability" -#if JUCE_CLANG && defined (MAC_OS_X_VERSION_10_14) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_14 - #pragma clang diagnostic ignored "-Wdeprecated-declarations" -#endif +JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wunguarded-availability", "-Wdeprecated-declarations") extern NSMenu* createNSMenu (const PopupMenu&, const String& name, int topLevelMenuId, int topLevelIndex, bool addDelegate); @@ -439,6 +434,6 @@ void SystemTrayIconComponent::showDropdownMenu (const PopupMenu& menu) pimpl->statusItemHolder->showMenu (menu); } -#pragma clang diagnostic pop +JUCE_END_IGNORE_WARNINGS_GCC_LIKE } // namespace juce diff --git a/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm b/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm index 6e3371f1..bb76b4fd 100644 --- a/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm +++ b/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -24,47 +23,306 @@ ============================================================================== */ -#if JUCE_CLANG && ! (defined (MAC_OS_X_VERSION_10_16) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_16) - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wdeprecated-declarations" - #define JUCE_DEPRECATION_IGNORED 1 +namespace juce +{ + +#if JUCE_IOS || (defined (MAC_OS_X_VERSION_10_10) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10) + + #define JUCE_USE_WKWEBVIEW 1 + + #if (defined (MAC_OS_X_VERSION_10_12) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12) + #define WKWEBVIEW_OPENPANEL_SUPPORTED 1 + #endif + #endif +static NSMutableURLRequest* getRequestForURL (const String& url, const StringArray* headers, const MemoryBlock* postData) +{ + NSString* urlString = juceStringToNS (url); + + #if JUCE_IOS || (defined (MAC_OS_X_VERSION_10_9) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9) + urlString = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]; + #else + urlString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; + #endif + + if (NSURL* nsURL = [NSURL URLWithString: urlString]) + { + NSMutableURLRequest* r + = [NSMutableURLRequest requestWithURL: nsURL + cachePolicy: NSURLRequestUseProtocolCachePolicy + timeoutInterval: 30.0]; + + if (postData != nullptr && postData->getSize() > 0) + { + [r setHTTPMethod: nsStringLiteral ("POST")]; + [r setHTTPBody: [NSData dataWithBytes: postData->getData() + length: postData->getSize()]]; + } + + if (headers != nullptr) + { + for (int i = 0; i < headers->size(); ++i) + { + auto headerName = (*headers)[i].upToFirstOccurrenceOf (":", false, false).trim(); + auto headerValue = (*headers)[i].fromFirstOccurrenceOf (":", false, false).trim(); + + [r setValue: juceStringToNS (headerValue) + forHTTPHeaderField: juceStringToNS (headerName)]; + } + } + + return r; + } + + return nullptr; +} + #if JUCE_MAC -namespace juce -{ +#if JUCE_USE_WKWEBVIEW + using WebViewBase = ObjCClass<WKWebView>; +#else + using WebViewBase = ObjCClass<WebView>; +#endif -struct WebViewKeyEquivalentResponder : public ObjCClass<WebView> +struct WebViewKeyEquivalentResponder : public WebViewBase { - WebViewKeyEquivalentResponder() : ObjCClass<WebView> ("WebViewKeyEquivalentResponder_") + WebViewKeyEquivalentResponder() + : WebViewBase ("WebViewKeyEquivalentResponder_") { + addIvar<WebViewKeyEquivalentResponder*> ("owner"); addMethod (@selector (performKeyEquivalent:), performKeyEquivalent, @encode (BOOL), "@:@"); registerClass(); } private: + static WebViewKeyEquivalentResponder* getOwner (id self) + { + return getIvar<WebViewKeyEquivalentResponder*> (self, "owner"); + } + static BOOL performKeyEquivalent (id self, SEL selector, NSEvent* event) { NSResponder* first = [[self window] firstResponder]; - #if (defined (MAC_OS_X_VERSION_10_12) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12) - if (([event modifierFlags] & NSEventModifierFlagDeviceIndependentFlagsMask) == NSEventModifierFlagCommand) - #else if (([event modifierFlags] & NSDeviceIndependentModifierFlagsMask) == NSCommandKeyMask) + { + auto sendAction = [&] (SEL actionSelector) -> BOOL + { + return [NSApp sendAction: actionSelector + to: first + from: self]; + }; + + if ([[event charactersIgnoringModifiers] isEqualToString: @"x"]) return sendAction (@selector (cut:)); + if ([[event charactersIgnoringModifiers] isEqualToString: @"c"]) return sendAction (@selector (copy:)); + if ([[event charactersIgnoringModifiers] isEqualToString: @"v"]) return sendAction (@selector (paste:)); + if ([[event charactersIgnoringModifiers] isEqualToString: @"a"]) return sendAction (@selector (selectAll:)); + } + + return sendSuperclassMessage<BOOL> (self, selector, event); + } +}; + +#endif + +#if JUCE_USE_WKWEBVIEW + +struct WebViewDelegateClass : public ObjCClass<NSObject> +{ + WebViewDelegateClass() : ObjCClass<NSObject> ("JUCEWebViewDelegate_") + { + addIvar<WebBrowserComponent*> ("owner"); + + addMethod (@selector (webView:decidePolicyForNavigationAction:decisionHandler:), decidePolicyForNavigationAction, "v@:@@@"); + addMethod (@selector (webView:didFinishNavigation:), didFinishNavigation, "v@:@@"); + addMethod (@selector (webView:didFailNavigation:withError:), didFailNavigation, "v@:@@@"); + addMethod (@selector (webView:didFailProvisionalNavigation:withError:), didFailProvisionalNavigation, "v@:@@@"); + + addMethod (@selector (webView:webViewDidClose:), webViewDidClose, "v@:@"); + addMethod (@selector (webView:createWebViewWithConfiguration:forNavigationAction: + windowFeatures:), createWebView, "@@:@@@@"); + + #if WKWEBVIEW_OPENPANEL_SUPPORTED + addMethod (@selector (webView:runOpenPanelWithParameters:initiatedByFrame:completionHandler:), runOpenPanel, "v@:@@@@"); #endif + + registerClass(); + } + + static void setOwner (id self, WebBrowserComponent* owner) { object_setInstanceVariable (self, "owner", owner); } + static WebBrowserComponent* getOwner (id self) { return getIvar<WebBrowserComponent*> (self, "owner"); } + +private: + static void decidePolicyForNavigationAction (id self, SEL, WKWebView*, WKNavigationAction* navigationAction, + void (^decisionHandler)(WKNavigationActionPolicy)) + { + if (getOwner (self)->pageAboutToLoad (nsStringToJuce ([[[navigationAction request] URL] absoluteString]))) + decisionHandler (WKNavigationActionPolicyAllow); + else + decisionHandler (WKNavigationActionPolicyCancel); + } + + static void didFinishNavigation (id self, SEL, WKWebView* webview, WKNavigation*) + { + getOwner (self)->pageFinishedLoading (nsStringToJuce ([[webview URL] absoluteString])); + } + + static void displayError (WebBrowserComponent* owner, NSError* error) + { + if ([error code] != NSURLErrorCancelled) { - if ([[event charactersIgnoringModifiers] isEqualToString:@"x"]) return [NSApp sendAction:@selector(cut:) to:first from:self]; - if ([[event charactersIgnoringModifiers] isEqualToString:@"c"]) return [NSApp sendAction:@selector(copy:) to:first from:self]; - if ([[event charactersIgnoringModifiers] isEqualToString:@"v"]) return [NSApp sendAction:@selector(paste:) to:first from:self]; - if ([[event charactersIgnoringModifiers] isEqualToString:@"a"]) return [NSApp sendAction:@selector(selectAll:) to:first from:self]; + auto errorString = nsStringToJuce ([error localizedDescription]); + bool proceedToErrorPage = owner->pageLoadHadNetworkError (errorString); + + // WKWebView doesn't have an internal error page, so make a really simple one ourselves + if (proceedToErrorPage) + owner->goToURL ("data:text/plain;charset=UTF-8," + errorString); } + } + + static void didFailNavigation (id self, SEL, WKWebView*, WKNavigation*, NSError* error) + { + displayError (getOwner (self), error); + } + + static void didFailProvisionalNavigation (id self, SEL, WKWebView*, WKNavigation*, NSError* error) + { + displayError (getOwner (self), error); + } + + static void webViewDidClose (id self, SEL, WKWebView*) + { + getOwner (self)->windowCloseRequest(); + } - objc_super s = { self, [WebView class] }; - return ObjCMsgSendSuper<BOOL, NSEvent*> (&s, selector, event); + static WKWebView* createWebView (id self, SEL, WKWebView*, WKWebViewConfiguration*, + WKNavigationAction* navigationAction, WKWindowFeatures*) + { + getOwner (self)->newWindowAttemptingToLoad (nsStringToJuce ([[[navigationAction request] URL] absoluteString])); + return nil; } + + #if WKWEBVIEW_OPENPANEL_SUPPORTED + static void runOpenPanel (id, SEL, WKWebView*, WKOpenPanelParameters* parameters, WKFrameInfo*, + void (^completionHandler)(NSArray<NSURL*>*)) + { + #if JUCE_MODAL_LOOPS_PERMITTED + FileChooser chooser (TRANS("Select the file you want to upload..."), + File::getSpecialLocation (File::userHomeDirectory), "*"); + + auto flags = FileBrowserComponent::openMode | FileBrowserComponent::canSelectFiles + | ([parameters allowsMultipleSelection] ? FileBrowserComponent::canSelectMultipleItems : 0); + + #if (defined (MAC_OS_X_VERSION_10_14) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_14) + if ([parameters allowsDirectories]) + flags |= FileBrowserComponent::canSelectDirectories; + #endif + + if (chooser.showDialog (flags, nullptr)) + { + auto results = chooser.getResults(); + auto urls = [NSMutableArray arrayWithCapacity: (NSUInteger) results.size()]; + + for (auto& f : results) + [urls addObject: [NSURL fileURLWithPath: juceStringToNS (f.getFullPathName())]]; + + completionHandler (urls); + } + else + { + completionHandler (nil); + } + #else + ignoreUnused (parameters, completionHandler); + jassertfalse; // Can't use this without modal loops being enabled! + #endif + } + #endif }; +//============================================================================== +class WebBrowserComponent::Pimpl + #if JUCE_MAC + : public NSViewComponent + #else + : public UIViewComponent + #endif +{ +public: + Pimpl (WebBrowserComponent* owner) + { + ignoreUnused (owner); + + WKWebViewConfiguration* config = [[WKWebViewConfiguration alloc] init]; + + #if JUCE_MAC + auto frame = NSMakeRect (0, 0, 100.0f, 100.0f); + + static WebViewKeyEquivalentResponder webviewClass; + webView = (WKWebView*) webviewClass.createInstance(); + + webView = [webView initWithFrame: frame + configuration: config]; + #else + auto frame = CGRectMake (0, 0, 100.0f, 100.0f); + webView = [[WKWebView alloc] initWithFrame: frame + configuration: config]; + #endif + + static WebViewDelegateClass cls; + webViewDelegate = [cls.createInstance() init]; + WebViewDelegateClass::setOwner (webViewDelegate, owner); + + [webView setNavigationDelegate: webViewDelegate]; + [webView setUIDelegate: webViewDelegate]; + + setView (webView); + } + + ~Pimpl() + { + [webView setNavigationDelegate: nil]; + [webView setUIDelegate: nil]; + + [webViewDelegate release]; + + setView (nil); + } + + void goToURL (const String& url, + const StringArray* headers, + const MemoryBlock* postData) + { + stop(); + + if (url.trimStart().startsWithIgnoreCase ("javascript:")) + { + [webView evaluateJavaScript: juceStringToNS (url.fromFirstOccurrenceOf (":", false, false)) + completionHandler: nil]; + } + else if (NSMutableURLRequest* request = getRequestForURL (url, headers, postData)) + { + [webView loadRequest: request]; + } + } + + void goBack() { [webView goBack]; } + void goForward() { [webView goForward]; } + + void stop() { [webView stopLoading]; } + void refresh() { [webView reload]; } + +private: + WKWebView* webView = nil; + id webViewDelegate; +}; + +#else + +#if JUCE_MAC + struct DownloadClickDetectorClass : public ObjCClass<NSObject> { DownloadClickDetectorClass() : ObjCClass<NSObject> ("JUCEWebClickDetector_") @@ -160,62 +418,40 @@ private: #else -//============================================================================== -@interface WebViewTapDetector : NSObject<UIGestureRecognizerDelegate> -{ -} - -- (BOOL) gestureRecognizer: (UIGestureRecognizer*) gestureRecognizer - shouldRecognizeSimultaneouslyWithGestureRecognizer: (UIGestureRecognizer*) otherGestureRecognizer; -@end - -@implementation WebViewTapDetector - -- (BOOL) gestureRecognizer: (UIGestureRecognizer*) gestureRecognizer - shouldRecognizeSimultaneouslyWithGestureRecognizer: (UIGestureRecognizer*) otherGestureRecognizer +struct WebViewDelegateClass : public ObjCClass<NSObject> { - juce::ignoreUnused (gestureRecognizer, otherGestureRecognizer); - return YES; -} - -@end + WebViewDelegateClass() : ObjCClass<NSObject> ("JUCEWebViewDelegate_") + { + addIvar<WebBrowserComponent*> ("owner"); -//============================================================================== -@interface WebViewURLChangeDetector : NSObject<UIWebViewDelegate> -{ - juce::WebBrowserComponent* ownerComponent; -} + addMethod (@selector (gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:), + shouldRecognizeSimultaneouslyWithGestureRecognizer, "c@:@@"); -- (WebViewURLChangeDetector*) initWithWebBrowserOwner: (juce::WebBrowserComponent*) ownerComponent; -- (BOOL) webView: (UIWebView*) webView shouldStartLoadWithRequest: (NSURLRequest*) request - navigationType: (UIWebViewNavigationType) navigationType; -- (void) webViewDidFinishLoad: (UIWebView*) webView; -@end + addMethod (@selector (webView:shouldStartLoadWithRequest:navigationType:), shouldStartLoadWithRequest, "c@:@@@"); + addMethod (@selector (webViewDidFinishLoad:), webViewDidFinishLoad, "v@:@"); -@implementation WebViewURLChangeDetector + registerClass(); + } -- (WebViewURLChangeDetector*) initWithWebBrowserOwner: (juce::WebBrowserComponent*) ownerComp -{ - [super init]; - ownerComponent = ownerComp; - return self; -} + static void setOwner (id self, WebBrowserComponent* owner) { object_setInstanceVariable (self, "owner", owner); } + static WebBrowserComponent* getOwner (id self) { return getIvar<WebBrowserComponent*> (self, "owner"); } -- (BOOL) webView: (UIWebView*) webView shouldStartLoadWithRequest: (NSURLRequest*) request - navigationType: (UIWebViewNavigationType) navigationType -{ - juce::ignoreUnused (webView, navigationType); - return ownerComponent->pageAboutToLoad (juce::nsStringToJuce (request.URL.absoluteString)); -} +private: + static BOOL shouldRecognizeSimultaneouslyWithGestureRecognizer (id, SEL, UIGestureRecognizer*, UIGestureRecognizer*) + { + return YES; + } -- (void) webViewDidFinishLoad: (UIWebView*) webView -{ - ownerComponent->pageFinishedLoading (juce::nsStringToJuce (webView.request.URL.absoluteString)); -} -@end + static BOOL shouldStartLoadWithRequest (id self, SEL, UIWebView*, NSURLRequest* request, UIWebViewNavigationType) + { + return getOwner (self)->pageAboutToLoad (nsStringToJuce ([[request URL] absoluteString])); + } -namespace juce -{ + static void webViewDidFinishLoad (id self, SEL, UIWebView* webView) + { + getOwner (self)->pageFinishedLoading (nsStringToJuce ([[[webView request] URL] absoluteString])); + } +}; #endif @@ -237,38 +473,38 @@ public: webView = [webView initWithFrame: NSMakeRect (0, 0, 100.0f, 100.0f) frameName: nsEmptyString() groupName: nsEmptyString()]; - setView (webView); static DownloadClickDetectorClass cls; clickListener = [cls.createInstance() init]; DownloadClickDetectorClass::setOwner (clickListener, owner); - [webView setPolicyDelegate: clickListener]; + + [webView setPolicyDelegate: clickListener]; [webView setFrameLoadDelegate: clickListener]; - [webView setUIDelegate: clickListener]; + [webView setUIDelegate: clickListener]; #else webView = [[UIWebView alloc] initWithFrame: CGRectMake (0, 0, 1.0f, 1.0f)]; - setView (webView); - tapDetector = [[WebViewTapDetector alloc] init]; - urlDetector = [[WebViewURLChangeDetector alloc] initWithWebBrowserOwner: owner]; - gestureRecogniser = nil; - webView.delegate = urlDetector; + static WebViewDelegateClass cls; + webViewDelegate = [cls.createInstance() init]; + WebViewDelegateClass::setOwner (webViewDelegate, owner); + + [webView setDelegate: webViewDelegate]; #endif + + setView (webView); } ~Pimpl() { #if JUCE_MAC - [webView setPolicyDelegate: nil]; + [webView setPolicyDelegate: nil]; [webView setFrameLoadDelegate: nil]; - [webView setUIDelegate: nil]; + [webView setUIDelegate: nil]; + [clickListener release]; #else - webView.delegate = nil; - [webView removeGestureRecognizer: gestureRecogniser]; - [gestureRecogniser release]; - [tapDetector release]; - [urlDetector release]; + [webView setDelegate: nil]; + [webViewDelegate release]; #endif setView (nil); @@ -285,52 +521,17 @@ public: [webView stringByEvaluatingJavaScriptFromString: juceStringToNS (url.fromFirstOccurrenceOf (":", false, false))]; } - else + else if (NSMutableURLRequest* request = getRequestForURL (url, headers, postData)) { - NSString* urlString = juceStringToNS (url); - - #if (JUCE_MAC && (defined (MAC_OS_X_VERSION_10_9) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9)) || (JUCE_IOS && (defined (__IPHONE_7_0) && __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_7_0)) - urlString = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]; + #if JUCE_MAC + [[webView mainFrame] loadRequest: request]; #else - urlString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; + [webView loadRequest: request]; #endif - if (NSURL* nsURL = [NSURL URLWithString: urlString]) - { - NSMutableURLRequest* r - = [NSMutableURLRequest requestWithURL: nsURL - cachePolicy: NSURLRequestUseProtocolCachePolicy - timeoutInterval: 30.0]; - - if (postData != nullptr && postData->getSize() > 0) - { - [r setHTTPMethod: nsStringLiteral ("POST")]; - [r setHTTPBody: [NSData dataWithBytes: postData->getData() - length: postData->getSize()]]; - } - - if (headers != nullptr) - { - for (int i = 0; i < headers->size(); ++i) - { - auto headerName = (*headers)[i].upToFirstOccurrenceOf (":", false, false).trim(); - auto headerValue = (*headers)[i].fromFirstOccurrenceOf (":", false, false).trim(); - - [r setValue: juceStringToNS (headerValue) - forHTTPHeaderField: juceStringToNS (headerName)]; - } - } - - #if JUCE_MAC - [[webView mainFrame] loadRequest: r]; - #else - [webView loadRequest: r]; - #endif - - #if JUCE_IOS - [webView setScalesPageToFit:YES]; - #endif - } + #if JUCE_IOS + [webView setScalesPageToFit: YES]; + #endif } } @@ -355,19 +556,14 @@ public: private: #if JUCE_MAC - WebView* webView; + WebView* webView = nil; id clickListener; #else - UIWebView* webView; - WebViewTapDetector* tapDetector; - WebViewURLChangeDetector* urlDetector; - UITapGestureRecognizer* gestureRecogniser; + UIWebView* webView = nil; + id webViewDelegate; #endif }; -#if JUCE_DEPRECATION_IGNORED - #pragma clang diagnostic pop - #undef JUCE_DEPRECATION_IGNORED #endif //============================================================================== @@ -379,6 +575,13 @@ WebBrowserComponent::WebBrowserComponent (bool unloadWhenHidden) addAndMakeVisible (browser.get()); } +WebBrowserComponent::WebBrowserComponent (bool unloadWhenHidden, + const File&, + const File&) + : WebBrowserComponent (unloadWhenHidden) +{ +} + WebBrowserComponent::~WebBrowserComponent() { } diff --git a/modules/juce_gui_extra/native/juce_win32_ActiveXComponent.cpp b/modules/juce_gui_extra/native/juce_win32_ActiveXComponent.cpp index a359e93e..c5aacd48 100644 --- a/modules/juce_gui_extra/native/juce_win32_ActiveXComponent.cpp +++ b/modules/juce_gui_extra/native/juce_win32_ActiveXComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -115,7 +114,7 @@ namespace ActiveXHelpers if (lplpDoc != nullptr) *lplpDoc = nullptr; lpFrameInfo->fMDIApp = FALSE; lpFrameInfo->hwndFrame = window; - lpFrameInfo->haccel = 0; + lpFrameInfo->haccel = nullptr; lpFrameInfo->cAccelEntries = 0; return S_OK; } @@ -183,7 +182,7 @@ namespace ActiveXHelpers //============================================================================== static Array<ActiveXControlComponent*> activeXComps; - static inline HWND getHWND (const ActiveXControlComponent* const component) + static HWND getHWND (const ActiveXControlComponent* const component) { HWND hwnd = {}; const IID iid = __uuidof (IOleWindow); @@ -197,7 +196,7 @@ namespace ActiveXHelpers return hwnd; } - static inline void offerActiveXMouseEventToPeer (ComponentPeer* peer, HWND hwnd, UINT message, LPARAM lParam) + static void offerActiveXMouseEventToPeer (ComponentPeer* peer, HWND hwnd, UINT message, LPARAM lParam) { switch (message) { @@ -264,7 +263,7 @@ public: void setControlBounds (Rectangle<int> newBounds) const { - if (controlHWND != 0) + if (controlHWND != nullptr) { #if JUCE_WIN_PER_MONITOR_DPI_AWARE if (auto* peer = owner.getTopLevelComponent()->getPeer()) @@ -278,11 +277,13 @@ public: void setControlVisible (bool shouldBeVisible) const { - if (controlHWND != 0) + if (controlHWND != nullptr) ShowWindow (controlHWND, shouldBeVisible ? SW_SHOWNA : SW_HIDE); } //============================================================================== + using ComponentMovementWatcher::componentMovedOrResized; + void componentMovedOrResized (bool /*wasMoved*/, bool /*wasResized*/) override { if (auto* peer = owner.getTopLevelComponent()->getPeer()) @@ -299,6 +300,8 @@ public: #endif } + using ComponentMovementWatcher::componentVisibilityChanged; + void componentVisibilityChanged() override { setControlVisible (owner.isShowing()); @@ -359,7 +362,7 @@ public: IStorage* storage = nullptr; ActiveXHelpers::JuceIOleClientSite* clientSite = nullptr; IOleObject* control = nullptr; - WNDPROC originalWndProc = 0; + WNDPROC originalWndProc = nullptr; }; //============================================================================== @@ -391,13 +394,13 @@ bool ActiveXControlComponent::createControl (const void* controlIID) std::unique_ptr<Pimpl> newControl (new Pimpl (hwnd, *this)); - HRESULT hr = OleCreate (*(const IID*) controlIID, __uuidof (IOleObject), 1 /*OLERENDER_DRAW*/, 0, + HRESULT hr = OleCreate (*(const IID*) controlIID, __uuidof (IOleObject), 1 /*OLERENDER_DRAW*/, nullptr, newControl->clientSite, newControl->storage, (void**) &(newControl->control)); if (hr == S_OK) { - newControl->control->SetHostNames (L"JUCE", 0); + newControl->control->SetHostNames (L"JUCE", nullptr); if (OleSetContainedObject (newControl->control, TRUE) == S_OK) { @@ -407,12 +410,12 @@ bool ActiveXControlComponent::createControl (const void* controlIID) rect.right = controlBounds.getRight(); rect.bottom = controlBounds.getBottom(); - if (newControl->control->DoVerb (OLEIVERB_SHOW, 0, newControl->clientSite, 0, hwnd, &rect) == S_OK) + if (newControl->control->DoVerb (OLEIVERB_SHOW, nullptr, newControl->clientSite, 0, hwnd, &rect) == S_OK) { control.reset (newControl.release()); control->controlHWND = ActiveXHelpers::getHWND (this); - if (control->controlHWND != 0) + if (control->controlHWND != nullptr) { control->setControlBounds (controlBounds); diff --git a/modules/juce_gui_extra/native/juce_win32_HWNDComponent.cpp b/modules/juce_gui_extra/native/juce_win32_HWNDComponent.cpp new file mode 100644 index 00000000..c4d6ef77 --- /dev/null +++ b/modules/juce_gui_extra/native/juce_win32_HWNDComponent.cpp @@ -0,0 +1,172 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ + +class HWNDComponent::Pimpl : public ComponentMovementWatcher +{ +public: + Pimpl (HWND h, Component& comp) + : ComponentMovementWatcher (&comp), + hwnd (h), + owner (comp) + { + if (owner.isShowing()) + componentPeerChanged(); + } + + ~Pimpl() override + { + removeFromParent(); + DestroyWindow (hwnd); + } + + using ComponentMovementWatcher::componentMovedOrResized; + + void componentMovedOrResized (bool wasMoved, bool wasResized) override + { + auto* topComponent = owner.getTopLevelComponent(); + + if (auto* peer = owner.getPeer()) + { + auto pos = topComponent->getLocalPoint (&owner, Point<int>()); + + auto scaled = (Rectangle<int> (pos.x, pos.y, owner.getWidth(), owner.getHeight()).toDouble() + * peer->getPlatformScaleFactor()).getSmallestIntegerContainer(); + + DWORD windowFlags = SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOOWNERZORDER; + if (! wasMoved) windowFlags |= SWP_NOMOVE; + if (! wasResized) windowFlags |= SWP_NOSIZE; + + SetWindowPos (hwnd, nullptr, scaled.getX(), scaled.getY(), scaled.getWidth(), scaled.getHeight(), windowFlags); + } + } + + void componentPeerChanged() override + { + auto* peer = owner.getPeer(); + + if (currentPeer != peer) + { + removeFromParent(); + currentPeer = peer; + + addToParent(); + } + + auto isShowing = owner.isShowing(); + + ShowWindow (hwnd, isShowing ? SW_SHOWNA : SW_HIDE); + + if (isShowing) + InvalidateRect (hwnd, nullptr, 0); + } + + using ComponentMovementWatcher::componentVisibilityChanged; + + void componentVisibilityChanged() override + { + componentPeerChanged(); + } + + void componentBroughtToFront (Component& comp) override + { + ComponentMovementWatcher::componentBroughtToFront (comp); + } + + Rectangle<int> getHWNDBounds() const + { + if (auto* peer = owner.getPeer()) + { + RECT r; + GetWindowRect (hwnd, &r); + + return (Rectangle<int>::leftTopRightBottom (r.left, r.top, r.right, r.bottom).toDouble() + / peer->getPlatformScaleFactor()).getSmallestIntegerContainer(); + } + + return {}; + } + + HWND hwnd; + +private: + void addToParent() + { + if (currentPeer != nullptr) + { + auto windowFlags = GetWindowLongPtr (hwnd, -16); + + windowFlags &= ~(WS_POPUP | WS_CHILD); + + SetWindowLongPtr (hwnd, -16, windowFlags); + SetParent (hwnd, (HWND) currentPeer->getNativeHandle()); + + componentMovedOrResized (true, true); + } + } + + void removeFromParent() + { + SetParent (hwnd, NULL); + } + + Component& owner; + ComponentPeer* currentPeer = nullptr; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Pimpl) +}; + +//============================================================================== +HWNDComponent::HWNDComponent() +{ +} + +HWNDComponent::~HWNDComponent() {} + +void HWNDComponent::setHWND (void* hwnd) +{ + if (hwnd != getHWND()) + { + pimpl.reset(); + + if (hwnd != nullptr) + pimpl.reset (new Pimpl ((HWND) hwnd, *this)); + } +} + +void* HWNDComponent::getHWND() const +{ + return pimpl == nullptr ? nullptr : (void*) pimpl->hwnd; +} + +void HWNDComponent::resizeToFit() +{ + if (pimpl != nullptr) + setBounds (pimpl->getHWNDBounds()); +} + +} // namespace juce diff --git a/modules/juce_gui_extra/native/juce_win32_SystemTrayIcon.cpp b/modules/juce_gui_extra/native/juce_win32_SystemTrayIcon.cpp index 061bc1de..629d958a 100644 --- a/modules/juce_gui_extra/native/juce_win32_SystemTrayIcon.cpp +++ b/modules/juce_gui_extra/native/juce_win32_SystemTrayIcon.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_gui_extra/native/juce_win32_WebBrowserComponent.cpp b/modules/juce_gui_extra/native/juce_win32_WebBrowserComponent.cpp index 8e01c696..630cac0b 100644 --- a/modules/juce_gui_extra/native/juce_win32_WebBrowserComponent.cpp +++ b/modules/juce_gui_extra/native/juce_win32_WebBrowserComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -27,6 +26,27 @@ namespace juce { +struct InternalWebViewType +{ + InternalWebViewType() {} + virtual ~InternalWebViewType() {} + + virtual void createBrowser() = 0; + virtual bool hasBrowserBeenCreated() = 0; + + virtual void goToURL (const String&, const StringArray*, const MemoryBlock*) = 0; + + virtual void stop() = 0; + virtual void goBack() = 0; + virtual void goForward() = 0; + virtual void refresh() = 0; + + virtual void focusGained() {} + virtual void setWebViewSize (int, int) = 0; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (InternalWebViewType) +}; + #if JUCE_MINGW JUCE_DECLARE_UUID_GETTER (IOleClientSite, "00000118-0000-0000-c000-000000000046") JUCE_DECLARE_UUID_GETTER (IDispatch, "00020400-0000-0000-c000-000000000046") @@ -41,12 +61,17 @@ JUCE_DECLARE_UUID_GETTER (IConnectionPointContainer, "B196B284-BAB4-101A-B69C-00 JUCE_DECLARE_UUID_GETTER (IWebBrowser2, "D30C1661-CDAF-11D0-8A3E-00C04FC9E26E") JUCE_DECLARE_UUID_GETTER (WebBrowser, "8856F961-340A-11D0-A96B-00C04FD705A2") -class WebBrowserComponent::Pimpl : public ActiveXControlComponent +//============================================================================== +class Win32WebView : public InternalWebViewType, + public ActiveXControlComponent { public: - Pimpl() {} + Win32WebView (WebBrowserComponent& owner) + { + owner.addAndMakeVisible (this); + } - ~Pimpl() + ~Win32WebView() override { if (connectionPoint != nullptr) connectionPoint->Unadvise (adviseCookie); @@ -55,7 +80,7 @@ public: browser->Release(); } - void createBrowser() + void createBrowser() override { auto webCLSID = __uuidof (WebBrowser); createControl (&webCLSID); @@ -71,7 +96,7 @@ public: if (connectionPoint != nullptr) { - auto* owner = dynamic_cast<WebBrowserComponent*> (getParentComponent()); + auto* owner = dynamic_cast<WebBrowserComponent*> (Component::getParentComponent()); jassert (owner != nullptr); auto handler = new EventHandler (*owner); @@ -81,9 +106,12 @@ public: } } - void goToURL (const String& url, - const StringArray* headers, - const MemoryBlock* postData) + bool hasBrowserBeenCreated() override + { + return browser != nullptr; + } + + void goToURL (const String& url, const StringArray* headers, const MemoryBlock* postData) override { if (browser != nullptr) { @@ -140,10 +168,65 @@ public: } } - //============================================================================== - IWebBrowser2* browser = nullptr; + void stop() override + { + if (browser != nullptr) + browser->Stop(); + } + + void goBack() override + { + if (browser != nullptr) + browser->GoBack(); + } + + void goForward() override + { + if (browser != nullptr) + browser->GoForward(); + } + + void refresh() override + { + if (browser != nullptr) + browser->Refresh(); + } + + void focusGained() override + { + auto iidOleObject = __uuidof (IOleObject); + auto iidOleWindow = __uuidof (IOleWindow); + + if (auto oleObject = (IOleObject*) queryInterface (&iidOleObject)) + { + if (auto oleWindow = (IOleWindow*) queryInterface (&iidOleWindow)) + { + IOleClientSite* oleClientSite = nullptr; + + if (SUCCEEDED (oleObject->GetClientSite (&oleClientSite))) + { + HWND hwnd; + oleWindow->GetWindow (&hwnd); + oleObject->DoVerb (OLEIVERB_UIACTIVATE, nullptr, oleClientSite, 0, hwnd, nullptr); + oleClientSite->Release(); + } + + oleWindow->Release(); + } + + oleObject->Release(); + } + } + + using ActiveXControlComponent::focusGained; + + void setWebViewSize (int width, int height) override + { + setSize (width, height); + } private: + IWebBrowser2* browser = nullptr; IConnectionPoint* connectionPoint = nullptr; DWORD adviseCookie = 0; @@ -235,18 +318,473 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (EventHandler) }; - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Pimpl) + //============================================================================== + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Win32WebView) }; +#if JUCE_USE_WIN_WEBVIEW2 + +using namespace Microsoft::WRL; + +class WebView2 : public InternalWebViewType, + public Component, + public ComponentMovementWatcher +{ +public: + WebView2 (WebBrowserComponent& o, const File& dllLocation, const File& userDataFolder) + : ComponentMovementWatcher (&o), + owner (o) + { + if (! WinRTWrapper::getInstance()->isInitialised()) + throw std::runtime_error ("Failed to initialise the WinRT wrapper"); + + if (! createWebViewEnvironment (dllLocation, userDataFolder)) + throw std::runtime_error ("Failed to create the CoreWebView2Environemnt"); + + owner.addAndMakeVisible (this); + } + + ~WebView2() override + { + removeEventHandlers(); + closeWebView(); + + if (webView2LoaderHandle != nullptr) + ::FreeLibrary (webView2LoaderHandle); + } + + void createBrowser() override + { + if (webView == nullptr) + { + jassert (webViewEnvironment != nullptr); + createWebView(); + } + } + + bool hasBrowserBeenCreated() override + { + return webView != nullptr || isCreating; + } + + void goToURL (const String& url, const StringArray* headers, const MemoryBlock* postData) override + { + urlRequest = { url, + headers != nullptr ? *headers : StringArray(), + postData != nullptr && postData->getSize() > 0 ? *postData : MemoryBlock() }; + + if (webView != nullptr) + webView->Navigate (urlRequest.url.toWideCharPointer()); + } + + void stop() override + { + if (webView != nullptr) + webView->Stop(); + } + + void goBack() override + { + if (webView != nullptr) + { + BOOL canGoBack = false; + webView->get_CanGoBack (&canGoBack); + + if (canGoBack) + webView->GoBack(); + } + } + + void goForward() override + { + if (webView != nullptr) + { + BOOL canGoForward = false; + webView->get_CanGoForward (&canGoForward); + + if (canGoForward) + webView->GoForward(); + } + } + + void refresh() override + { + if (webView != nullptr) + webView->Reload(); + } + + void setWebViewSize (int width, int height) override + { + setSize (width, height); + } + + void componentMovedOrResized (bool /*wasMoved*/, bool /*wasResized*/) override + { + if (auto* peer = owner.getTopLevelComponent()->getPeer()) + setControlBounds (peer->getAreaCoveredBy (owner)); + } + + void componentPeerChanged() override + { + componentMovedOrResized (true, true); + } + + void componentVisibilityChanged() override + { + setControlVisible (owner.isShowing()); + + componentPeerChanged(); + owner.visibilityChanged(); + } + +private: + //============================================================================== + template<class ArgType> + static String getUriStringFromArgs (ArgType* args) + { + if (args != nullptr) + { + LPWSTR uri; + args->get_Uri (&uri); + + return uri; + } + + return {}; + } + + //============================================================================== + void addEventHandlers() + { + if (webView != nullptr) + { + webView->add_NavigationStarting (Callback<ICoreWebView2NavigationStartingEventHandler> ( + [this] (ICoreWebView2*, ICoreWebView2NavigationStartingEventArgs* args) -> HRESULT + { + auto uriString = getUriStringFromArgs (args); + + if (uriString.isNotEmpty() && ! owner.pageAboutToLoad (uriString)) + args->put_Cancel (true); + + return S_OK; + }).Get(), &navigationStartingToken); + + webView->add_NewWindowRequested (Callback<ICoreWebView2NewWindowRequestedEventHandler> ( + [this] (ICoreWebView2*, ICoreWebView2NewWindowRequestedEventArgs* args) -> HRESULT + { + auto uriString = getUriStringFromArgs (args); + + if (uriString.isNotEmpty()) + { + owner.newWindowAttemptingToLoad (uriString); + args->put_Handled (true); + } + + return S_OK; + }).Get(), &newWindowRequestedToken); + + webView->add_WindowCloseRequested (Callback<ICoreWebView2WindowCloseRequestedEventHandler> ( + [this] (ICoreWebView2*, IUnknown*) -> HRESULT + { + owner.windowCloseRequest(); + return S_OK; + }).Get(), &windowCloseRequestedToken); + + webView->add_NavigationCompleted (Callback<ICoreWebView2NavigationCompletedEventHandler> ( + [this] (ICoreWebView2* sender, ICoreWebView2NavigationCompletedEventArgs* args) -> HRESULT + { + LPWSTR uri; + sender->get_Source (&uri); + + String uriString (uri); + + if (uriString.isNotEmpty()) + { + BOOL success = false; + args->get_IsSuccess (&success); + + COREWEBVIEW2_WEB_ERROR_STATUS errorStatus; + args->get_WebErrorStatus (&errorStatus); + + if (success + || errorStatus == COREWEBVIEW2_WEB_ERROR_STATUS_OPERATION_CANCELED) // this error seems to happen erroneously so ignore + { + owner.pageFinishedLoading (uriString); + } + else + { + auto errorString = "Error code: " + String (errorStatus); + + if (owner.pageLoadHadNetworkError (errorString)) + owner.goToURL ("data:text/plain;charset=UTF-8," + errorString); + } + } + + return S_OK; + }).Get(), &navigationCompletedToken); + + webView->AddWebResourceRequestedFilter (L"*", COREWEBVIEW2_WEB_RESOURCE_CONTEXT_DOCUMENT); + + webView->add_WebResourceRequested (Callback<ICoreWebView2WebResourceRequestedEventHandler> ( + [this] (ICoreWebView2*, ICoreWebView2WebResourceRequestedEventArgs* args) -> HRESULT + { + if (urlRequest.url.isEmpty()) + return S_OK; + + WinRTWrapper::ComPtr<ICoreWebView2WebResourceRequest> request; + args->get_Request (request.resetAndGetPointerAddress()); + + auto uriString = getUriStringFromArgs (request.get()); + + if (uriString == urlRequest.url + || (uriString.endsWith ("/") && uriString.upToLastOccurrenceOf ("/", false, false) == urlRequest.url)) + { + String method ("GET"); + + if (urlRequest.postData.getSize() > 0) + { + method = "POST"; + + WinRTWrapper::ComPtr<IStream> content (SHCreateMemStream ((BYTE*) urlRequest.postData.getData(), + (UINT) urlRequest.postData.getSize())); + request->put_Content (content.get()); + } + + if (! urlRequest.headers.isEmpty()) + { + WinRTWrapper::ComPtr<ICoreWebView2HttpRequestHeaders> headers; + request->get_Headers (headers.resetAndGetPointerAddress()); + + for (auto& header : urlRequest.headers) + { + headers->SetHeader (header.upToFirstOccurrenceOf (":", false, false).trim().toWideCharPointer(), + header.fromFirstOccurrenceOf (":", false, false).trim().toWideCharPointer()); + } + } + + request->put_Method (method.toWideCharPointer()); + + urlRequest = {}; + } + + return S_OK; + }).Get(), &webResourceRequestedToken); + } + } + + void removeEventHandlers() + { + if (webView != nullptr) + { + if (navigationStartingToken.value != 0) + webView->remove_NavigationStarting (navigationStartingToken); + + if (newWindowRequestedToken.value != 0) + webView->remove_NewWindowRequested (newWindowRequestedToken); + + if (windowCloseRequestedToken.value != 0) + webView->remove_WindowCloseRequested (windowCloseRequestedToken); + + if (navigationCompletedToken.value != 0) + webView->remove_NavigationCompleted (navigationCompletedToken); + + if (webResourceRequestedToken.value != 0) + { + webView->RemoveWebResourceRequestedFilter (L"*", COREWEBVIEW2_WEB_RESOURCE_CONTEXT_DOCUMENT); + webView->remove_WebResourceRequested (webResourceRequestedToken); + } + } + } + + bool createWebViewEnvironment (const File& dllLocation, const File& userDataFolder) + { + using CreateWebViewEnvironmentWithOptionsFunc = HRESULT (*) (PCWSTR, PCWSTR, + ICoreWebView2EnvironmentOptions*, + ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler*); + + auto dllPath = dllLocation.getFullPathName(); + + if (dllPath.isEmpty()) + dllPath = "WebView2Loader.dll"; + + webView2LoaderHandle = LoadLibraryA (dllPath.toUTF8()); + + if (webView2LoaderHandle == nullptr) + return false; + + auto* createWebViewEnvironmentWithOptions = (CreateWebViewEnvironmentWithOptionsFunc) GetProcAddress (webView2LoaderHandle, + "CreateCoreWebView2EnvironmentWithOptions"); + if (createWebViewEnvironmentWithOptions == nullptr) + { + // failed to load WebView2Loader.dll + jassertfalse; + return false; + } + + auto options = Microsoft::WRL::Make<CoreWebView2EnvironmentOptions>(); + + WeakReference<WebView2> weakThis (this); + auto hr = createWebViewEnvironmentWithOptions (nullptr, + userDataFolder != File() ? userDataFolder.getFullPathName().toWideCharPointer() : nullptr, + options.Get(), + Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>( + [this, weakThis] (HRESULT, ICoreWebView2Environment* env) -> HRESULT + { + if (weakThis != nullptr) + webViewEnvironment = env; + + return S_OK; + }).Get()); + + return SUCCEEDED (hr); + } + + void createWebView() + { + if (auto* peer = getPeer()) + { + isCreating = true; + + WeakReference<WebView2> weakThis (this); + + webViewEnvironment->CreateCoreWebView2Controller ((HWND) peer->getNativeHandle(), + Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler> ( + [this, weakThis] (HRESULT, ICoreWebView2Controller* controller) -> HRESULT + { + if (weakThis != nullptr) + { + isCreating = false; + + if (controller != nullptr) + { + webViewController = controller; + controller->get_CoreWebView2 (webView.resetAndGetPointerAddress()); + + addEventHandlers(); + componentMovedOrResized (true, true); + + if (webView != nullptr && urlRequest.url.isNotEmpty()) + webView->Navigate (urlRequest.url.toWideCharPointer()); + } + } + + return S_OK; + }).Get()); + } + } + + void closeWebView() + { + if (webViewController.get() != nullptr) + { + webViewController->Close(); + webViewController = nullptr; + webView = nullptr; + } + + webViewEnvironment = nullptr; + } + + //============================================================================== + void setControlBounds (Rectangle<int> newBounds) const + { + if (webViewController != nullptr) + { + #if JUCE_WIN_PER_MONITOR_DPI_AWARE + if (auto* peer = owner.getTopLevelComponent()->getPeer()) + newBounds = (newBounds.toDouble() * peer->getPlatformScaleFactor()).toNearestInt(); + #endif + + webViewController->put_Bounds({ newBounds.getX(), newBounds.getY(), + newBounds.getRight(), newBounds.getBottom() }); + } + } + + void setControlVisible (bool shouldBeVisible) const + { + if (webViewController != nullptr) + webViewController->put_IsVisible (shouldBeVisible); + } + + //============================================================================== + WebBrowserComponent& owner; + + HMODULE webView2LoaderHandle = nullptr; + + WinRTWrapper::ComPtr<ICoreWebView2Environment> webViewEnvironment; + WinRTWrapper::ComPtr<ICoreWebView2Controller> webViewController; + WinRTWrapper::ComPtr<ICoreWebView2> webView; + + EventRegistrationToken navigationStartingToken { 0 }, + newWindowRequestedToken { 0 }, + windowCloseRequestedToken { 0 }, + navigationCompletedToken { 0 }, + webResourceRequestedToken { 0 }; + + struct URLRequest + { + String url; + StringArray headers; + MemoryBlock postData; + }; + URLRequest urlRequest; + + bool isCreating = false; + + //============================================================================== + JUCE_DECLARE_WEAK_REFERENCEABLE (WebView2) + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WebView2) +}; + +#endif //============================================================================== -WebBrowserComponent::WebBrowserComponent (const bool unloadPageWhenBrowserIsHidden_) - : browser (new Pimpl()), - blankPageShown (false), - unloadPageWhenBrowserIsHidden (unloadPageWhenBrowserIsHidden_) +class WebBrowserComponent::Pimpl +{ +public: + Pimpl (WebBrowserComponent& owner, const File& dllLocation, const File& userDataFolder, bool useWebView2) + { + if (useWebView2) + { + #if JUCE_USE_WIN_WEBVIEW2 + try + { + internal.reset (new WebView2 (owner, dllLocation, userDataFolder)); + } + catch (std::runtime_error&) {} + #endif + } + + ignoreUnused (dllLocation, userDataFolder); + + if (internal == nullptr) + internal.reset (new Win32WebView (owner)); + } + + InternalWebViewType& getInternalWebView() + { + return *internal; + } + +private: + std::unique_ptr<InternalWebViewType> internal; +}; + +//============================================================================== +WebBrowserComponent::WebBrowserComponent (bool unloadWhenHidden) + : browser (new Pimpl (*this, {}, {}, false)), + unloadPageWhenBrowserIsHidden (unloadWhenHidden) +{ + setOpaque (true); +} + +WebBrowserComponent::WebBrowserComponent (bool unloadWhenHidden, + const File& dllLocation, + const File& userDataFolder) + : browser (new Pimpl (*this, dllLocation, userDataFolder, true)), + unloadPageWhenBrowserIsHidden (unloadWhenHidden) { setOpaque (true); - addAndMakeVisible (browser.get()); } WebBrowserComponent::~WebBrowserComponent() @@ -272,16 +810,15 @@ void WebBrowserComponent::goToURL (const String& url, blankPageShown = false; - if (browser->browser == nullptr) + if (! browser->getInternalWebView().hasBrowserBeenCreated()) checkWindowAssociation(); - browser->goToURL (url, headers, postData); + browser->getInternalWebView().goToURL (url, headers, postData); } void WebBrowserComponent::stop() { - if (browser->browser != nullptr) - browser->browser->Stop(); + browser->getInternalWebView().stop(); } void WebBrowserComponent::goBack() @@ -289,28 +826,25 @@ void WebBrowserComponent::goBack() lastURL.clear(); blankPageShown = false; - if (browser->browser != nullptr) - browser->browser->GoBack(); + browser->getInternalWebView().goBack(); } void WebBrowserComponent::goForward() { lastURL.clear(); - if (browser->browser != nullptr) - browser->browser->GoForward(); + browser->getInternalWebView().goForward(); } void WebBrowserComponent::refresh() { - if (browser->browser != nullptr) - browser->browser->Refresh(); + browser->getInternalWebView().refresh(); } //============================================================================== void WebBrowserComponent::paint (Graphics& g) { - if (browser->browser == nullptr) + if (! browser->getInternalWebView().hasBrowserBeenCreated()) { g.fillAll (Colours::white); checkWindowAssociation(); @@ -321,9 +855,9 @@ void WebBrowserComponent::checkWindowAssociation() { if (isShowing()) { - if (browser->browser == nullptr && getPeer() != nullptr) + if (! browser->getInternalWebView().hasBrowserBeenCreated() && getPeer() != nullptr) { - browser->createBrowser(); + browser->getInternalWebView().createBrowser(); reloadLastURL(); } else @@ -341,7 +875,7 @@ void WebBrowserComponent::checkWindowAssociation() // page to avoid this.. blankPageShown = true; - browser->goToURL ("about:blank", 0, 0); + browser->getInternalWebView().goToURL ("about:blank", 0, 0); } } } @@ -362,7 +896,7 @@ void WebBrowserComponent::parentHierarchyChanged() void WebBrowserComponent::resized() { - browser->setSize (getWidth(), getHeight()); + browser->getInternalWebView().setWebViewSize (getWidth(), getHeight()); } void WebBrowserComponent::visibilityChanged() @@ -372,28 +906,7 @@ void WebBrowserComponent::visibilityChanged() void WebBrowserComponent::focusGained (FocusChangeType) { - auto iidOleObject = __uuidof (IOleObject); - auto iidOleWindow = __uuidof (IOleWindow); - - if (auto oleObject = (IOleObject*) browser->queryInterface (&iidOleObject)) - { - if (auto oleWindow = (IOleWindow*) browser->queryInterface (&iidOleWindow)) - { - IOleClientSite* oleClientSite = nullptr; - - if (SUCCEEDED (oleObject->GetClientSite (&oleClientSite))) - { - HWND hwnd; - oleWindow->GetWindow (&hwnd); - oleObject->DoVerb (OLEIVERB_UIACTIVATE, nullptr, oleClientSite, 0, hwnd, nullptr); - oleClientSite->Release(); - } - - oleWindow->Release(); - } - - oleObject->Release(); - } + browser->getInternalWebView().focusGained(); } void WebBrowserComponent::clearCookies() diff --git a/modules/juce_opengl/geometry/juce_Draggable3DOrientation.h b/modules/juce_opengl/geometry/juce_Draggable3DOrientation.h index 9869b2bd..dacf7be7 100644 --- a/modules/juce_opengl/geometry/juce_Draggable3DOrientation.h +++ b/modules/juce_opengl/geometry/juce_Draggable3DOrientation.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_opengl/geometry/juce_Matrix3D.h b/modules/juce_opengl/geometry/juce_Matrix3D.h index 56cd4c4a..e796cd14 100644 --- a/modules/juce_opengl/geometry/juce_Matrix3D.h +++ b/modules/juce_opengl/geometry/juce_Matrix3D.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_opengl/geometry/juce_Quaternion.h b/modules/juce_opengl/geometry/juce_Quaternion.h index b1887974..bf21a9c0 100644 --- a/modules/juce_opengl/geometry/juce_Quaternion.h +++ b/modules/juce_opengl/geometry/juce_Quaternion.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_opengl/geometry/juce_Vector3D.h b/modules/juce_opengl/geometry/juce_Vector3D.h index 8842662d..13a6bb70 100644 --- a/modules/juce_opengl/geometry/juce_Vector3D.h +++ b/modules/juce_opengl/geometry/juce_Vector3D.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_opengl/juce_opengl.cpp b/modules/juce_opengl/juce_opengl.cpp index b9ad3502..78beeee9 100644 --- a/modules/juce_opengl/juce_opengl.cpp +++ b/modules/juce_opengl/juce_opengl.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -37,6 +36,7 @@ #define JUCE_CORE_INCLUDE_JNI_HELPERS 1 #define JUCE_CORE_INCLUDE_NATIVE_HEADERS 1 #define JUCE_GRAPHICS_INCLUDE_COREGRAPHICS_HELPERS 1 +#define JUCE_GUI_BASICS_INCLUDE_XHEADERS 1 #include "juce_opengl.h" @@ -263,10 +263,7 @@ private: //============================================================================== #if JUCE_MAC || JUCE_IOS - #if JUCE_CLANG - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wundeclared-selector" - #endif + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wundeclared-selector") #if JUCE_MAC #include "native/juce_OpenGL_osx.h" @@ -274,9 +271,7 @@ private: #include "native/juce_OpenGL_ios.h" #endif - #if JUCE_CLANG - #pragma clang diagnostic pop - #endif + JUCE_END_IGNORE_WARNINGS_GCC_LIKE #elif JUCE_WINDOWS #include "native/juce_OpenGL_win32.h" diff --git a/modules/juce_opengl/juce_opengl.h b/modules/juce_opengl/juce_opengl.h index f056ceb8..eebdf67f 100644 --- a/modules/juce_opengl/juce_opengl.h +++ b/modules/juce_opengl/juce_opengl.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -29,14 +28,14 @@ The block below describes the properties of this module, and is read by the Projucer to automatically generate project code that uses it. For details about the syntax and how to create or use a module, see the - JUCE Module Format.txt file. + JUCE Module Format.md file. BEGIN_JUCE_MODULE_DECLARATION ID: juce_opengl vendor: juce - version: 5.4.7 + version: 6.0.5 name: JUCE OpenGL classes description: Classes for rendering OpenGL in a JUCE window. website: http://www.juce.com/juce @@ -93,14 +92,10 @@ #include <GL/gl.h> #undef KeyPress #elif JUCE_IOS - #if defined (__IPHONE_7_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_7_0 - #if defined (__IPHONE_12_0) && __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_12_0 - #define GLES_SILENCE_DEPRECATION 1 - #endif - #include <OpenGLES/ES3/gl.h> - #else - #include <OpenGLES/ES2/gl.h> + #if defined (__IPHONE_12_0) && __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_12_0 + #define GLES_SILENCE_DEPRECATION 1 #endif + #include <OpenGLES/ES3/gl.h> #elif JUCE_MAC #define JUCE_OPENGL3 1 #if defined (MAC_OS_X_VERSION_10_14) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_14 diff --git a/modules/juce_opengl/juce_opengl.mm b/modules/juce_opengl/juce_opengl.mm index c1c2dd3b..7f12aac6 100644 --- a/modules/juce_opengl/juce_opengl.mm +++ b/modules/juce_opengl/juce_opengl.mm @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_opengl/native/java/app/com/roli/juce/JuceOpenGLView.java b/modules/juce_opengl/native/java/app/com/rmsl/juce/JuceOpenGLView.java similarity index 55% rename from modules/juce_opengl/native/java/app/com/roli/juce/JuceOpenGLView.java rename to modules/juce_opengl/native/java/app/com/rmsl/juce/JuceOpenGLView.java index 727c97e2..bd07caae 100644 --- a/modules/juce_opengl/native/java/app/com/roli/juce/JuceOpenGLView.java +++ b/modules/juce_opengl/native/java/app/com/rmsl/juce/JuceOpenGLView.java @@ -1,4 +1,29 @@ -package com.roli.juce; +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +package com.rmsl.juce; import android.content.Context; import android.graphics.Canvas; diff --git a/modules/juce_opengl/native/juce_MissingGLDefinitions.h b/modules/juce_opengl/native/juce_MissingGLDefinitions.h index 07ce6ecf..c23ec097 100644 --- a/modules/juce_opengl/native/juce_MissingGLDefinitions.h +++ b/modules/juce_opengl/native/juce_MissingGLDefinitions.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_opengl/native/juce_OpenGLExtensions.h b/modules/juce_opengl/native/juce_OpenGLExtensions.h index 3738af95..e7eab9db 100644 --- a/modules/juce_opengl/native/juce_OpenGLExtensions.h +++ b/modules/juce_opengl/native/juce_OpenGLExtensions.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -137,19 +136,19 @@ struct OpenGLExtensionFunctions //============================================================================== #else - #define JUCE_DECLARE_GL_FUNCTION(name, returnType, params, callparams) inline static returnType name params noexcept { return ::name callparams; } + #define JUCE_DECLARE_GL_FUNCTION(name, returnType, params, callparams) static returnType name params noexcept { return ::name callparams; } JUCE_GL_BASE_FUNCTIONS (JUCE_DECLARE_GL_FUNCTION) #ifndef GL3_PROTOTYPES #undef JUCE_DECLARE_GL_FUNCTION - #define JUCE_DECLARE_GL_FUNCTION(name, returnType, params, callparams) inline static returnType name params noexcept { return ::name ## EXT callparams; } + #define JUCE_DECLARE_GL_FUNCTION(name, returnType, params, callparams) static returnType name params noexcept { return ::name ## EXT callparams; } #endif JUCE_GL_EXTENSION_FUNCTIONS (JUCE_DECLARE_GL_FUNCTION) #if JUCE_OPENGL3 #ifndef GL3_PROTOTYPES #undef JUCE_DECLARE_GL_FUNCTION - #define JUCE_DECLARE_GL_FUNCTION(name, returnType, params, callparams) inline static returnType name params noexcept { return ::name ## APPLE callparams; } + #define JUCE_DECLARE_GL_FUNCTION(name, returnType, params, callparams) static returnType name params noexcept { return ::name ## APPLE callparams; } #endif JUCE_GL_VERTEXBUFFER_FUNCTIONS (JUCE_DECLARE_GL_FUNCTION) #endif diff --git a/modules/juce_opengl/native/juce_OpenGL_android.h b/modules/juce_opengl/native/juce_OpenGL_android.h index 9265fa01..91e44111 100644 --- a/modules/juce_opengl/native/juce_OpenGL_android.h +++ b/modules/juce_opengl/native/juce_OpenGL_android.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -28,31 +27,30 @@ namespace juce { //============================================================================== -// This byte-code is generated from native/java/com/roli/juce/JuceOpenGLView.java with min sdk version 16 +// This byte-code is generated from native/java/com/rmsl/juce/JuceOpenGLView.java with min sdk version 16 // See juce_core/native/java/README.txt on how to generate this byte-code. static const uint8 javaJuceOpenGLView[] = -{31,139,8,8,110,106,229,91,0,3,74,117,99,101,79,112,101,110,71,76,86,105,101,119,46,100,101,120,0,109,84,63,104,19,81,24, -255,222,221,75,82,211,244,26,211,70,180,130,68,172,160,80,189,170,21,11,169,82,105,169,16,15,139,180,164,90,187,28,151, -211,92,105,239,98,114,77,139,56,20,151,58,185,40,34,34,184,56,22,167,14,213,77,165,187,179,58,56,58,43,82,7,7,127,239,79, -76,10,61,248,189,223,247,190,255,119,247,222,87,241,215,210,195,23,46,210,241,45,159,207,157,188,253,250,215,169,241,167, -83,63,159,111,216,239,78,127,114,30,230,63,252,229,68,53,34,90,43,143,228,72,63,11,208,29,38,165,79,2,159,53,255,0,24,48, -140,37,3,30,101,106,255,2,203,164,73,180,13,126,111,16,125,4,118,128,47,192,111,32,11,219,16,224,0,211,192,12,112,11,88, -0,92,32,0,238,3,15,128,199,192,19,224,37,240,22,216,1,190,2,187,64,130,171,122,16,9,34,37,116,95,41,141,132,238,191,75, -203,207,80,251,128,150,95,65,78,107,249,13,228,110,45,111,118,232,183,12,149,55,43,107,152,50,151,9,75,175,174,153,211, -220,47,235,115,105,23,107,70,178,242,227,218,143,163,211,62,189,239,215,251,188,100,131,14,105,125,235,93,196,99,104,30, -81,105,241,94,92,234,186,185,234,175,86,32,58,47,35,231,33,205,15,18,89,136,101,210,55,207,85,255,45,171,37,227,13,89, -227,40,150,131,224,168,192,104,150,102,198,225,133,180,231,80,112,20,223,76,236,107,227,221,196,111,90,242,27,48,217,207, -96,43,38,43,114,236,27,51,220,69,156,117,198,12,233,152,253,189,211,240,142,112,12,184,236,141,237,121,103,67,238,153, -222,183,229,228,88,16,6,241,21,98,37,234,43,173,120,254,116,205,15,175,57,229,192,95,61,187,232,54,93,58,226,184,97,165, -30,5,21,219,139,194,216,15,99,123,66,240,90,92,236,48,221,171,187,181,106,224,53,236,9,55,108,186,141,34,13,252,55,53, -145,201,158,89,169,223,117,61,95,100,45,210,49,199,139,150,237,122,180,20,216,139,40,104,239,173,90,36,86,38,163,92,34, -179,92,114,32,56,16,156,18,37,61,55,244,252,37,201,168,64,41,79,117,65,153,74,208,168,185,177,87,157,172,187,171,196,171, -81,35,166,116,232,198,65,211,159,173,6,13,202,69,225,213,56,118,189,170,95,153,141,230,130,176,18,173,82,94,234,132,74, -41,110,72,119,234,143,194,73,95,185,78,213,163,101,237,60,176,159,86,71,100,96,67,89,189,227,177,40,216,99,244,230,82, -214,165,233,51,56,152,41,235,58,13,49,43,101,93,222,152,167,1,82,124,2,188,113,103,12,63,128,227,240,241,245,117,190,109, -242,71,6,25,0,3,18,236,155,201,248,31,96,147,27,252,59,239,209,255,145,117,112,107,110,24,29,179,195,236,152,31,173,115, -47,102,72,130,218,115,36,73,237,89,194,10,202,38,230,9,203,182,239,178,81,80,249,197,140,49,181,143,184,31,84,80,177,35, -250,242,10,89,204,176,127,191,250,1,66,252,4,0,0}; +{31,139,8,8,95,114,161,94,0,3,74,117,99,101,79,112,101,110,71,76,86,105,101,119,83,117,114,102,97,99,101,46,100,101,120,0,109, +84,75,107,19,81,20,62,119,230,38,169,105,76,99,218,138,86,144,32,5,55,173,83,53,98,33,173,86,90,170,196,193,34,173,81,106,93, +12,147,169,153,210,204,196,100,154,22,65,40,110,234,170,43,23,34,46,93,22,87,62,138,27,65,168,235,174,213,133,11,23,254,129, +162,136,130,223,125,196,164,208,129,239,126,231,125,206,188,78,217,91,75,142,156,191,64,151,223,190,187,182,183,251,251,212,240, +247,216,223,197,205,174,170,255,233,209,230,135,123,183,222,252,225,68,53,34,90,43,229,179,164,175,5,216,142,145,178,199,129, +93,205,63,0,6,140,224,72,129,71,153,210,159,225,152,50,137,182,193,239,13,162,143,192,14,240,25,216,3,50,240,13,1,54,48,3,204, +2,119,128,5,192,1,124,224,1,240,16,120,2,108,2,207,129,87,192,14,240,5,248,9,196,184,234,7,145,32,82,76,207,149,208,136,233, +249,187,180,252,20,189,15,105,249,5,228,164,150,95,66,238,214,242,86,135,253,181,161,234,102,100,15,83,214,50,225,233,209,61,179, +154,251,100,127,46,253,226,76,73,86,113,92,199,113,76,218,171,245,62,173,247,75,54,232,168,182,183,238,69,92,134,230,188,42,139, +251,226,210,214,205,213,124,181,28,209,57,153,57,15,105,126,144,40,141,92,38,99,251,185,154,191,229,77,203,124,67,246,56,129, +227,8,56,204,49,154,163,217,9,68,161,236,89,52,28,197,51,19,122,109,162,155,248,205,180,124,6,76,206,51,216,202,201,136,26,7, +230,140,116,17,103,157,57,67,58,231,224,232,36,162,67,124,6,92,206,198,246,221,179,33,117,166,245,182,28,31,243,3,63,186,68,172, +72,189,197,21,215,155,169,121,193,85,187,228,123,171,103,150,156,166,67,199,109,39,40,215,67,191,108,185,97,16,121,65,100,77, +10,94,139,10,29,174,251,117,167,86,241,221,134,53,233,4,77,167,81,160,129,255,174,38,42,89,179,43,245,69,199,245,68,213,2,157, +180,221,176,106,213,171,141,101,107,9,13,173,253,93,11,196,74,100,148,138,100,150,138,54,4,27,130,93,164,184,235,4,174,183,44, +25,29,40,225,170,41,40,85,246,27,53,39,114,43,83,117,103,149,120,37,108,68,148,12,156,200,111,122,115,21,191,65,217,48,184,18, +69,142,91,241,202,115,225,109,63,40,135,171,212,47,109,194,164,12,55,100,56,245,133,193,148,167,66,167,235,97,85,7,15,28,100, +213,25,41,248,208,86,107,60,18,13,79,27,61,217,68,250,226,204,48,13,83,34,125,157,166,89,58,145,30,223,152,167,60,41,30,7,111, +220,29,195,11,224,248,248,248,250,58,223,54,249,99,131,12,128,1,49,246,213,100,252,23,176,197,13,254,141,31,214,239,145,117, +112,107,111,24,29,187,195,236,216,31,173,239,94,236,144,24,181,247,72,156,218,187,132,229,148,79,236,19,150,105,255,203,70,78, +213,23,59,198,212,49,226,255,160,156,202,205,235,159,87,200,98,135,253,3,40,26,5,36,252,4,0,0,0,0}; //============================================================================== struct AndroidGLCallbacks @@ -72,7 +70,7 @@ struct AndroidGLCallbacks CALLBACK (AndroidGLCallbacks::detachedFromWindow, "onDetachedFromWindowNative", "(J)V") \ CALLBACK (AndroidGLCallbacks::dispatchDraw, "onDrawNative", "(JLandroid/graphics/Canvas;)V") -DECLARE_JNI_CLASS_WITH_BYTECODE (JuceOpenGLViewSurface, "com/roli/juce/JuceOpenGLView", 16, javaJuceOpenGLView, sizeof(javaJuceOpenGLView)) +DECLARE_JNI_CLASS_WITH_BYTECODE (JuceOpenGLViewSurface, "com/rmsl/juce/JuceOpenGLView", 16, javaJuceOpenGLView, sizeof(javaJuceOpenGLView)) #undef JNI_CLASS_MEMBERS //============================================================================== @@ -233,7 +231,7 @@ public: auto env = getEnv(); lastBounds = bounds; - auto r = bounds * Desktop::getInstance().getDisplays().getMainDisplay().scale; + auto r = bounds * Desktop::getInstance().getDisplays().getPrimaryDisplay()->scale; env->CallVoidMethod (surfaceView.get(), JuceOpenGLViewSurface.layout, (jint) r.getX(), (jint) r.getY(), (jint) r.getRight(), (jint) r.getBottom()); diff --git a/modules/juce_opengl/native/juce_OpenGL_ios.h b/modules/juce_opengl/native/juce_OpenGL_ios.h index c4fb799c..ae58579b 100644 --- a/modules/juce_opengl/native/juce_OpenGL_ios.h +++ b/modules/juce_opengl/native/juce_OpenGL_ios.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -155,9 +154,13 @@ public: if (openGLversion >= openGL3_2) { - glBlitFramebuffer (0, 0, lastBounds.getWidth(), lastBounds.getHeight(), - 0, 0, lastBounds.getWidth(), lastBounds.getHeight(), - GL_COLOR_BUFFER_BIT, GL_NEAREST); + auto w = roundToInt (lastBounds.getWidth() * glLayer.contentsScale); + auto h = roundToInt (lastBounds.getHeight() * glLayer.contentsScale); + + glBlitFramebuffer (0, 0, w, h, + 0, 0, w, h, + GL_COLOR_BUFFER_BIT, + GL_NEAREST); } else { @@ -181,7 +184,7 @@ public: void updateWindowPosition (Rectangle<int> bounds) { view.frame = convertToCGRect (bounds); - glLayer.contentsScale = (CGFloat) (Desktop::getInstance().getDisplays().getMainDisplay().scale + glLayer.contentsScale = (CGFloat) (Desktop::getInstance().getDisplays().getPrimaryDisplay()->scale / component.getDesktopScaleFactor()); if (lastBounds != bounds) diff --git a/modules/juce_opengl/native/juce_OpenGL_linux_X11.h b/modules/juce_opengl/native/juce_OpenGL_linux_X11.h index 410a7568..c3301846 100644 --- a/modules/juce_opengl/native/juce_OpenGL_linux_X11.h +++ b/modules/juce_opengl/native/juce_OpenGL_linux_X11.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -31,7 +30,6 @@ extern XContext windowHandleXContext; //============================================================================== // Defined juce_linux_Windowing.cpp -Rectangle<int> juce_LinuxScaledToPhysicalBounds (ComponentPeer*, Rectangle<int>); void juce_LinuxAddRepaintListener (ComponentPeer*, Component* dummy); void juce_LinuxRemoveRepaintListener (ComponentPeer*, Component* dummy); @@ -63,10 +61,11 @@ public: OpenGLVersion) : component (comp), contextToShareWith (shareContext), dummy (*this) { - display = XWindowSystem::getInstance()->displayRef(); + display = XWindowSystem::getInstance()->getDisplay(); - ScopedXLock xlock (display); - XSync (display, False); + XWindowSystemUtilities::ScopedXLock xLock; + + X11Symbols::getInstance()->xSync (display, False); GLint attribs[] = { @@ -85,7 +84,7 @@ public: None }; - bestVisual = glXChooseVisual (display, DefaultScreen (display), attribs); + bestVisual = glXChooseVisual (display, X11Symbols::getInstance()->xDefaultScreen (display), attribs); if (bestVisual == nullptr) return; @@ -93,7 +92,7 @@ public: jassert (peer != nullptr); auto windowH = (Window) peer->getNativeHandle(); - auto colourMap = XCreateColormap (display, windowH, bestVisual->visual, AllocNone); + auto colourMap = X11Symbols::getInstance()->xCreateColormap (display, windowH, bestVisual->visual, AllocNone); XSetWindowAttributes swa; swa.colormap = colourMap; @@ -103,48 +102,50 @@ public: auto glBounds = component.getTopLevelComponent() ->getLocalArea (&component, component.getLocalBounds()); - glBounds = juce_LinuxScaledToPhysicalBounds (peer, glBounds); + glBounds = Desktop::getInstance().getDisplays().logicalToPhysical (glBounds); - embeddedWindow = XCreateWindow (display, windowH, - glBounds.getX(), glBounds.getY(), - (unsigned int) jmax (1, glBounds.getWidth()), - (unsigned int) jmax (1, glBounds.getHeight()), - 0, bestVisual->depth, - InputOutput, - bestVisual->visual, - CWBorderPixel | CWColormap | CWEventMask, - &swa); + embeddedWindow = X11Symbols::getInstance()->xCreateWindow (display, windowH, + glBounds.getX(), glBounds.getY(), + (unsigned int) jmax (1, glBounds.getWidth()), + (unsigned int) jmax (1, glBounds.getHeight()), + 0, bestVisual->depth, + InputOutput, + bestVisual->visual, + CWBorderPixel | CWColormap | CWEventMask, + &swa); - XSaveContext (display, (XID) embeddedWindow, windowHandleXContext, (XPointer) peer); + X11Symbols::getInstance()->xSaveContext (display, (XID) embeddedWindow, windowHandleXContext, (XPointer) peer); - XMapWindow (display, embeddedWindow); - XFreeColormap (display, colourMap); + X11Symbols::getInstance()->xMapWindow (display, embeddedWindow); + X11Symbols::getInstance()->xFreeColormap (display, colourMap); - XSync (display, False); + X11Symbols::getInstance()->xSync (display, False); juce_LinuxAddRepaintListener (peer, &dummy); } ~NativeContext() { - juce_LinuxRemoveRepaintListener (component.getPeer(), &dummy); - - if (embeddedWindow != 0) + if (auto* peer = component.getPeer()) { - ScopedXLock xlock (display); - XUnmapWindow (display, embeddedWindow); - XDestroyWindow (display, embeddedWindow); + juce_LinuxRemoveRepaintListener (peer, &dummy); + + if (embeddedWindow != 0) + { + XWindowSystemUtilities::ScopedXLock xLock; + X11Symbols::getInstance()->xUnmapWindow (display, embeddedWindow); + X11Symbols::getInstance()->xDestroyWindow (display, embeddedWindow); + X11Symbols::getInstance()->xSync (display, True); + } } if (bestVisual != nullptr) - XFree (bestVisual); - - XWindowSystem::getInstance()->displayUnref(); + X11Symbols::getInstance()->xFree (bestVisual); } bool initialiseOnRenderThread (OpenGLContext& c) { - ScopedXLock xlock (display); + XWindowSystemUtilities::ScopedXLock xLock; renderContext = glXCreateContext (display, bestVisual, (GLXContext) contextToShareWith, GL_TRUE); c.makeActive(); context = &c; @@ -154,7 +155,7 @@ public: void shutdownOnRenderThread() { - ScopedXLock xlock (display); + XWindowSystemUtilities::ScopedXLock xLock; context = nullptr; deactivateCurrentContext(); glXDestroyContext (display, renderContext); @@ -163,40 +164,42 @@ public: bool makeActive() const noexcept { - ScopedXLock xlock (display); + XWindowSystemUtilities::ScopedXLock xLock; return renderContext != nullptr && glXMakeCurrent (display, embeddedWindow, renderContext); } bool isActive() const noexcept { - ScopedXLock xlock (display); + XWindowSystemUtilities::ScopedXLock xLock; return glXGetCurrentContext() == renderContext && renderContext != nullptr; } static void deactivateCurrentContext() { - ScopedXDisplay xDisplay; - ScopedXLock xlock (xDisplay.display); - glXMakeCurrent (xDisplay.display, None, nullptr); + if (auto* display = XWindowSystem::getInstance()->getDisplay()) + { + XWindowSystemUtilities::ScopedXLock xLock; + glXMakeCurrent (display, None, nullptr); + } } void swapBuffers() { - ScopedXLock xlock (display); + XWindowSystemUtilities::ScopedXLock xLock; glXSwapBuffers (display, embeddedWindow); } void updateWindowPosition (Rectangle<int> newBounds) { bounds = newBounds; - auto physicalBounds = juce_LinuxScaledToPhysicalBounds (component.getPeer(), bounds); + auto physicalBounds = Desktop::getInstance().getDisplays().logicalToPhysical (bounds); - ScopedXLock xlock (display); - XMoveResizeWindow (display, embeddedWindow, - physicalBounds.getX(), physicalBounds.getY(), - (unsigned int) jmax (1, physicalBounds.getWidth()), - (unsigned int) jmax (1, physicalBounds.getHeight())); + XWindowSystemUtilities::ScopedXLock xLock; + X11Symbols::getInstance()->xMoveResizeWindow (display, embeddedWindow, + physicalBounds.getX(), physicalBounds.getY(), + (unsigned int) jmax (1, physicalBounds.getWidth()), + (unsigned int) jmax (1, physicalBounds.getHeight())); } bool setSwapInterval (int numFramesPerSwap) @@ -207,7 +210,7 @@ public: if (auto GLXSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC) OpenGLHelpers::getExtensionFunction ("glXSwapIntervalSGI")) { - ScopedXLock xlock (display); + XWindowSystemUtilities::ScopedXLock xLock; swapFrames = numFramesPerSwap; GLXSwapIntervalSGI (numFramesPerSwap); return true; @@ -234,15 +237,15 @@ private: GLXContext renderContext = {}; Window embeddedWindow = {}; - int swapFrames = 0; + int swapFrames = 1; Rectangle<int> bounds; - XVisualInfo* bestVisual = {}; + XVisualInfo* bestVisual = nullptr; void* contextToShareWith; - OpenGLContext* context = {}; + OpenGLContext* context = nullptr; DummyComponent dummy; - ::Display* display = {}; + ::Display* display = nullptr; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NativeContext) }; @@ -250,15 +253,8 @@ private: //============================================================================== bool OpenGLHelpers::isContextActive() { - ScopedXDisplay xDisplay; - - if (xDisplay.display) - { - ScopedXLock xlock (xDisplay.display); - return glXGetCurrentContext() != nullptr; - } - - return false; + XWindowSystemUtilities::ScopedXLock xLock; + return glXGetCurrentContext() != nullptr; } } // namespace juce diff --git a/modules/juce_opengl/native/juce_OpenGL_osx.h b/modules/juce_opengl/native/juce_OpenGL_osx.h index f5805fde..3a7686bf 100644 --- a/modules/juce_opengl/native/juce_OpenGL_osx.h +++ b/modules/juce_opengl/native/juce_OpenGL_osx.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -27,11 +26,7 @@ namespace juce { -#if JUCE_CLANG && ! (defined (MAC_OS_X_VERSION_10_16) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_16) - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wdeprecated-declarations" - #define JUCE_DEPRECATION_IGNORED 1 -#endif +JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wdeprecated-declarations") class OpenGLContext::NativeContext { @@ -266,9 +261,6 @@ bool OpenGLHelpers::isContextActive() return CGLGetCurrentContext() != CGLContextObj(); } -#if JUCE_DEPRECATION_IGNORED - #pragma clang diagnostic pop - #undef JUCE_DEPRECATION_IGNORED -#endif +JUCE_END_IGNORE_WARNINGS_GCC_LIKE } // namespace juce diff --git a/modules/juce_opengl/native/juce_OpenGL_win32.h b/modules/juce_opengl/native/juce_OpenGL_win32.h index 95c2dd68..6106fce5 100644 --- a/modules/juce_opengl/native/juce_OpenGL_win32.h +++ b/modules/juce_opengl/native/juce_OpenGL_win32.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -28,16 +27,9 @@ namespace juce { extern ComponentPeer* createNonRepaintingEmbeddedWindowsPeer (Component&, void* parent); -extern bool shouldScaleGLWindow (void* hwnd); - -#if JUCE_MODULE_AVAILABLE_juce_audio_plugin_client && JucePlugin_Build_VST - bool juce_shouldDoubleScaleNativeGLWindow(); -#else - bool juce_shouldDoubleScaleNativeGLWindow() { return false; } -#endif #if JUCE_WIN_PER_MONITOR_DPI_AWARE - void setProcessDPIAwarenessIfNecessary (void*); + extern void setThreadDPIAwarenessForWindow (HWND); #endif //============================================================================== @@ -66,7 +58,7 @@ public: renderContext = wglCreateContext (dc); - if (renderContext != 0) + if (renderContext != nullptr) { makeActive(); initialiseGLExtensions(); @@ -106,7 +98,7 @@ public: bool initialiseOnRenderThread (OpenGLContext& c) { #if JUCE_WIN_PER_MONITOR_DPI_AWARE - setProcessDPIAwarenessIfNecessary (nativeWindow->getNativeHandle()); + setThreadDPIAwarenessForWindow ((HWND) nativeWindow->getNativeHandle()); #endif context = &c; @@ -115,7 +107,7 @@ public: void shutdownOnRenderThread() { deactivateCurrentContext(); context = nullptr; } - static void deactivateCurrentContext() { wglMakeCurrent (0, 0); } + static void deactivateCurrentContext() { wglMakeCurrent (nullptr, nullptr); } bool makeActive() const noexcept { return isActive() || wglMakeCurrent (dc, renderContext) != FALSE; } bool isActive() const noexcept { return wglGetCurrentContext() == renderContext; } void swapBuffers() const noexcept { SwapBuffers (dc); } @@ -139,7 +131,7 @@ public: if (! approximatelyEqual (nativeScaleFactor, 1.0)) bounds = (bounds.toDouble() * nativeScaleFactor).toNearestInt(); - SetWindowPos ((HWND) nativeWindow->getNativeHandle(), 0, + SetWindowPos ((HWND) nativeWindow->getNativeHandle(), nullptr, bounds.getX(), bounds.getY(), bounds.getWidth(), bounds.getHeight(), SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOOWNERZORDER); } @@ -157,12 +149,12 @@ public: struct Locker { Locker (NativeContext&) {} }; - double getWindowScaleFactor (const Rectangle<int>& screenBounds) + HWND getNativeHandle() { - if (nativeWindow != nullptr && shouldScaleGLWindow (nativeWindow->getNativeHandle())) - return Desktop::getInstance().getDisplays().findDisplayForRect (screenBounds).scale; + if (nativeWindow != nullptr) + return (HWND) nativeWindow->getNativeHandle(); - return Desktop::getInstance().getGlobalScaleFactor(); + return nullptr; } private: @@ -205,9 +197,6 @@ private: { auto newScale = peer->getPlatformScaleFactor(); - if (juce_shouldDoubleScaleNativeGLWindow()) - newScale *= newScale; - if (! approximatelyEqual (newScale, nativeScaleFactor)) { nativeScaleFactor = newScale; @@ -238,9 +227,6 @@ private: safeComponent = Component::SafePointer<Component> (&component); nativeScaleFactor = peer->getPlatformScaleFactor(); - if (juce_shouldDoubleScaleNativeGLWindow()) - nativeScaleFactor *= nativeScaleFactor; - startTimer (50); #endif @@ -253,10 +239,10 @@ private: void deleteRenderContext() { - if (renderContext != 0) + if (renderContext != nullptr) { wglDeleteContext (renderContext); - renderContext = 0; + renderContext = nullptr; } } @@ -343,7 +329,7 @@ private: //============================================================================== bool OpenGLHelpers::isContextActive() { - return wglGetCurrentContext() != 0; + return wglGetCurrentContext() != nullptr; } } // namespace juce diff --git a/modules/juce_opengl/opengl/juce_OpenGLContext.cpp b/modules/juce_opengl/opengl/juce_OpenGLContext.cpp index b6257456..0cc2a611 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLContext.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLContext.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -66,6 +65,10 @@ private: #endif +#if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE + extern JUCE_API double getScaleFactorForWindow (HWND); +#endif + //============================================================================== class OpenGLContext::CachedImage : public CachedComponentImage, private ThreadPoolJob @@ -142,16 +145,6 @@ public: renderThread->addJob (this, false); } - #if JUCE_MAC - static CVReturn displayLinkCallback (CVDisplayLinkRef, const CVTimeStamp*, const CVTimeStamp*, - CVOptionFlags, CVOptionFlags*, void* displayLinkContext) - { - auto* self = (CachedImage*) displayLinkContext; - self->renderFrame(); - return kCVReturnSuccess; - } - #endif - //============================================================================== void paint (Graphics&) override { @@ -292,15 +285,21 @@ public: { if (auto* peer = component.getPeer()) { - #if JUCE_WINDOWS - auto newScale = nativeContext->getWindowScaleFactor (component.getTopLevelComponent()->getScreenBounds()); + auto localBounds = component.getLocalBounds(); + auto displayScale = Desktop::getInstance().getDisplays().getDisplayForRect (component.getTopLevelComponent()->getScreenBounds())->scale; + + auto newArea = peer->getComponent().getLocalArea (&component, localBounds).withZeroOrigin() * displayScale; + + #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE + auto newScale = getScaleFactorForWindow (nativeContext->getNativeHandle()); + auto desktopScale = Desktop::getInstance().getGlobalScaleFactor(); + + if (! approximatelyEqual (1.0f, desktopScale)) + newScale *= desktopScale; #else - auto newScale = Desktop::getInstance().getDisplays().findDisplayForRect (component.getTopLevelComponent()->getScreenBounds()).scale; + auto newScale = displayScale; #endif - auto localBounds = component.getLocalBounds(); - auto newArea = peer->getComponent().getLocalArea (&component, localBounds).withZeroOrigin() * newScale; - if (scale != newScale || viewportArea != newArea) { scale = newScale; @@ -477,13 +476,17 @@ public: break; #if JUCE_MAC - repaintEvent.wait (1000); - #else + if (cvDisplayLinkWrapper != nullptr) + { + repaintEvent.wait (-1); + renderFrame(); + } + else + #endif if (! renderFrame()) repaintEvent.wait (5); // failed to render, so avoid a tight fail-loop. else if (! context.continuousRepaint && ! shouldExit()) repaintEvent.wait (-1); - #endif } hasInitialised = false; @@ -536,9 +539,8 @@ public: context.renderer->newOpenGLContextCreated(); #if JUCE_MAC - CVDisplayLinkCreateWithActiveCGDisplays (&displayLink); - CVDisplayLinkSetOutputCallback (displayLink, &displayLinkCallback, this); - CVDisplayLinkStart (displayLink); + if (context.continuousRepaint) + cvDisplayLinkWrapper = std::make_unique<CVDisplayLinkWrapper> (this); #endif return true; @@ -547,8 +549,7 @@ public: void shutdownOnThread() { #if JUCE_MAC - CVDisplayLinkStop (displayLink); - CVDisplayLinkRelease (displayLink); + cvDisplayLinkWrapper = nullptr; #endif if (context.renderer != nullptr) @@ -677,8 +678,35 @@ public: uint32 lastMMLockReleaseTime = 0; #if JUCE_MAC - CVDisplayLinkRef displayLink; + struct CVDisplayLinkWrapper + { + CVDisplayLinkWrapper (CachedImage* im) + { + CVDisplayLinkCreateWithActiveCGDisplays (&displayLink); + CVDisplayLinkSetOutputCallback (displayLink, &displayLinkCallback, im); + CVDisplayLinkStart (displayLink); + } + + ~CVDisplayLinkWrapper() + { + CVDisplayLinkStop (displayLink); + CVDisplayLinkRelease (displayLink); + } + + static CVReturn displayLinkCallback (CVDisplayLinkRef, const CVTimeStamp*, const CVTimeStamp*, + CVOptionFlags, CVOptionFlags*, void* displayLinkContext) + { + auto* self = (CachedImage*) displayLinkContext; + self->repaintEvent.signal(); + return kCVReturnSuccess; + } + + CVDisplayLinkRef displayLink; + }; + + std::unique_ptr<CVDisplayLinkWrapper> cvDisplayLinkWrapper; #endif + std::unique_ptr<ThreadPool> renderThread; ReferenceCountedArray<OpenGLContext::AsyncWorker, CriticalSection> workQueue; MessageManager::Lock messageManagerLock; @@ -882,6 +910,15 @@ void OpenGLContext::setComponentPaintingEnabled (bool shouldPaintComponent) noex void OpenGLContext::setContinuousRepainting (bool shouldContinuouslyRepaint) noexcept { continuousRepaint = shouldContinuouslyRepaint; + + #if JUCE_MAC + if (auto* component = getTargetComponent()) + { + detach(); + attachment.reset (new Attachment (*this, *component)); + } + #endif + triggerRepaint(); } diff --git a/modules/juce_opengl/opengl/juce_OpenGLContext.h b/modules/juce_opengl/opengl/juce_OpenGLContext.h index c3fda19a..f4ffd125 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLContext.h +++ b/modules/juce_opengl/opengl/juce_OpenGLContext.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -328,7 +327,8 @@ private: void* contextToShareWith = nullptr; OpenGLVersion versionRequired = defaultGLVersion; size_t imageCacheMaxSize = 8 * 1024 * 1024; - bool renderComponents = true, useMultisampling = false, continuousRepaint = false, overrideCanAttach = false; + bool renderComponents = true, useMultisampling = false, overrideCanAttach = false; + std::atomic<bool> continuousRepaint { false }; TextureMagnificationFilter texMagFilter = linear; //============================================================================== diff --git a/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.cpp b/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.cpp index e92f7a82..2e5e3a06 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.h b/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.h index ee740bc2..14e0b6f1 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.h +++ b/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp b/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp index 68d614b6..7cb4a200 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -120,8 +119,8 @@ struct CachedImageList : public ReferenceCountedObject, t.textureID = texture.getTextureID(); t.imageWidth = pixelData->width; t.imageHeight = pixelData->height; - t.fullWidthProportion = t.imageWidth / (float) texture.getWidth(); - t.fullHeightProportion = t.imageHeight / (float) texture.getHeight(); + t.fullWidthProportion = (float) t.imageWidth / (float) texture.getWidth(); + t.fullHeightProportion = (float) t.imageHeight / (float) texture.getHeight(); lastUsed = Time::getCurrentTime(); return t; @@ -436,7 +435,7 @@ struct ShaderPrograms : public ReferenceCountedObject OpenGLShaderProgram::Attribute positionAttribute, colourAttribute; OpenGLShaderProgram::Uniform screenBounds; - std::function<void(OpenGLShaderProgram&)> onShaderActivated; + std::function<void (OpenGLShaderProgram&)> onShaderActivated; }; struct MaskedShaderParams @@ -647,16 +646,16 @@ struct ShaderPrograms : public ReferenceCountedObject float targetX, float targetY, bool isForTiling) const { auto t = trans.translated (-targetX, -targetY) - .inverted().scaled (fullWidthProportion / imageWidth, - fullHeightProportion / imageHeight); + .inverted().scaled (fullWidthProportion / (float) imageWidth, + fullHeightProportion / (float) imageHeight); const GLfloat m[] = { t.mat00, t.mat01, t.mat02, t.mat10, t.mat11, t.mat12 }; matrix.set (m, 6); if (isForTiling) { - fullWidthProportion -= 0.5f / imageWidth; - fullHeightProportion -= 0.5f / imageHeight; + fullWidthProportion -= 0.5f / (float) imageWidth; + fullHeightProportion -= 0.5f / (float) imageHeight; } imageLimits.set (fullWidthProportion, fullHeightProportion); @@ -1423,8 +1422,8 @@ struct GLState textureCache.bindTextureForGradient (activeTextures, g); } - auto t = transform.translated (0.5f - target.bounds.getX(), - 0.5f - target.bounds.getY()); + auto t = transform.translated (0.5f - (float) target.bounds.getX(), + 0.5f - (float) target.bounds.getY()); auto p1 = g.point1.transformedBy (t); auto p2 = g.point2.transformedBy (t); auto p3 = Point<float> (g.point1.x + (g.point2.y - g.point1.y), diff --git a/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.h b/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.h index f4317beb..8e3123ad 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.h +++ b/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -27,19 +26,14 @@ namespace juce { -/** Creates a graphics context object that will render into the given OpenGL target. - The caller is responsible for deleting this object when no longer needed. -*/ +/** Creates a graphics context object that will render into the given OpenGL target. */ std::unique_ptr<LowLevelGraphicsContext> createOpenGLGraphicsContext (OpenGLContext&, int width, int height); -/** Creates a graphics context object that will render into the given OpenGL framebuffer. - The caller is responsible for deleting this object when no longer needed. -*/ +/** Creates a graphics context object that will render into the given OpenGL framebuffer. */ std::unique_ptr<LowLevelGraphicsContext> createOpenGLGraphicsContext (OpenGLContext&, OpenGLFrameBuffer&); /** Creates a graphics context object that will render into the given OpenGL framebuffer, with the given size. - The caller is responsible for deleting this object when no longer needed. */ std::unique_ptr<LowLevelGraphicsContext> createOpenGLGraphicsContext (OpenGLContext&, unsigned int frameBufferID, @@ -91,7 +85,7 @@ struct JUCE_API OpenGLGraphicsContextCustomShader /** Optional lambda that will be called when the shader is activated, to allow user code to do setup tasks. */ - std::function<void(OpenGLShaderProgram&)> onShaderActivated; + std::function<void (OpenGLShaderProgram&)> onShaderActivated; private: String code, hashName; diff --git a/modules/juce_opengl/opengl/juce_OpenGLHelpers.cpp b/modules/juce_opengl/opengl/juce_OpenGLHelpers.cpp index 2d379203..97dc1f0b 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLHelpers.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLHelpers.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_opengl/opengl/juce_OpenGLHelpers.h b/modules/juce_opengl/opengl/juce_OpenGLHelpers.h index 641d7e0c..cef11c2e 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLHelpers.h +++ b/modules/juce_opengl/opengl/juce_OpenGLHelpers.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_opengl/opengl/juce_OpenGLImage.cpp b/modules/juce_opengl/opengl/juce_OpenGLImage.cpp index 23235a68..716cec64 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLImage.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLImage.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_opengl/opengl/juce_OpenGLImage.h b/modules/juce_opengl/opengl/juce_OpenGLImage.h index 006662ff..1c4b5074 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLImage.h +++ b/modules/juce_opengl/opengl/juce_OpenGLImage.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_opengl/opengl/juce_OpenGLPixelFormat.cpp b/modules/juce_opengl/opengl/juce_OpenGLPixelFormat.cpp index 56746043..168e09ab 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLPixelFormat.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLPixelFormat.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_opengl/opengl/juce_OpenGLPixelFormat.h b/modules/juce_opengl/opengl/juce_OpenGLPixelFormat.h index 0ddc3401..22028049 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLPixelFormat.h +++ b/modules/juce_opengl/opengl/juce_OpenGLPixelFormat.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_opengl/opengl/juce_OpenGLRenderer.h b/modules/juce_opengl/opengl/juce_OpenGLRenderer.h index ff4def7c..88ce6484 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLRenderer.h +++ b/modules/juce_opengl/opengl/juce_OpenGLRenderer.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_opengl/opengl/juce_OpenGLShaderProgram.cpp b/modules/juce_opengl/opengl/juce_OpenGLShaderProgram.cpp index 17992fed..c9734242 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLShaderProgram.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLShaderProgram.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_opengl/opengl/juce_OpenGLShaderProgram.h b/modules/juce_opengl/opengl/juce_OpenGLShaderProgram.h index e60ce060..de482014 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLShaderProgram.h +++ b/modules/juce_opengl/opengl/juce_OpenGLShaderProgram.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_opengl/opengl/juce_OpenGLTexture.cpp b/modules/juce_opengl/opengl/juce_OpenGLTexture.cpp index 8cc0acf5..67ebf218 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLTexture.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLTexture.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -137,6 +136,7 @@ void OpenGLTexture::loadImage (const Image& image) case Image::ARGB: Flipper<PixelARGB> ::flip (dataCopy, srcData.data, srcData.lineStride, imageW, imageH); break; case Image::RGB: Flipper<PixelRGB> ::flip (dataCopy, srcData.data, srcData.lineStride, imageW, imageH); break; case Image::SingleChannel: Flipper<PixelAlpha>::flip (dataCopy, srcData.data, srcData.lineStride, imageW, imageH); break; + case Image::UnknownFormat: default: break; } diff --git a/modules/juce_opengl/opengl/juce_OpenGLTexture.h b/modules/juce_opengl/opengl/juce_OpenGLTexture.h index caecccba..1a2916dd 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLTexture.h +++ b/modules/juce_opengl/opengl/juce_OpenGLTexture.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_opengl/utils/juce_OpenGLAppComponent.cpp b/modules/juce_opengl/utils/juce_OpenGLAppComponent.cpp index 752c43e1..d3fae9e2 100644 --- a/modules/juce_opengl/utils/juce_OpenGLAppComponent.cpp +++ b/modules/juce_opengl/utils/juce_OpenGLAppComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_opengl/utils/juce_OpenGLAppComponent.h b/modules/juce_opengl/utils/juce_OpenGLAppComponent.h index dafaa688..5dd877c6 100644 --- a/modules/juce_opengl/utils/juce_OpenGLAppComponent.h +++ b/modules/juce_opengl/utils/juce_OpenGLAppComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_osc/juce_osc.cpp b/modules/juce_osc/juce_osc.cpp index 6e026de4..0e7060e2 100644 --- a/modules/juce_osc/juce_osc.cpp +++ b/modules/juce_osc/juce_osc.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_osc/juce_osc.h b/modules/juce_osc/juce_osc.h index 4372e1ec..faeecada 100644 --- a/modules/juce_osc/juce_osc.h +++ b/modules/juce_osc/juce_osc.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -29,20 +28,20 @@ The block below describes the properties of this module, and is read by the Projucer to automatically generate project code that uses it. For details about the syntax and how to create or use a module, see the - JUCE Module Format.txt file. + JUCE Module Format.md file. BEGIN_JUCE_MODULE_DECLARATION ID: juce_osc vendor: juce - version: 5.4.7 + version: 6.0.5 name: JUCE OSC classes description: Open Sound Control implementation. website: http://www.juce.com/juce license: GPL/Commercial - dependencies: juce_core, juce_events + dependencies: juce_events END_JUCE_MODULE_DECLARATION diff --git a/modules/juce_osc/osc/juce_OSCAddress.cpp b/modules/juce_osc/osc/juce_OSCAddress.cpp index f9c17ea9..79efc422 100644 --- a/modules/juce_osc/osc/juce_OSCAddress.cpp +++ b/modules/juce_osc/osc/juce_OSCAddress.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -175,6 +174,7 @@ namespace break; } // else = special case: fall through to default and treat '!' as a non-special character. + JUCE_FALLTHROUGH default: set.add (c); diff --git a/modules/juce_osc/osc/juce_OSCAddress.h b/modules/juce_osc/osc/juce_OSCAddress.h index e24f2d5e..e9ba7eff 100644 --- a/modules/juce_osc/osc/juce_OSCAddress.h +++ b/modules/juce_osc/osc/juce_OSCAddress.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_osc/osc/juce_OSCArgument.cpp b/modules/juce_osc/osc/juce_OSCArgument.cpp index a9ad4e3a..442b9eaa 100644 --- a/modules/juce_osc/osc/juce_OSCArgument.cpp +++ b/modules/juce_osc/osc/juce_OSCArgument.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_osc/osc/juce_OSCArgument.h b/modules/juce_osc/osc/juce_OSCArgument.h index 222054cd..20b9248b 100644 --- a/modules/juce_osc/osc/juce_OSCArgument.h +++ b/modules/juce_osc/osc/juce_OSCArgument.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_osc/osc/juce_OSCBundle.cpp b/modules/juce_osc/osc/juce_OSCBundle.cpp index 75ab3e97..56485de5 100644 --- a/modules/juce_osc/osc/juce_OSCBundle.cpp +++ b/modules/juce_osc/osc/juce_OSCBundle.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_osc/osc/juce_OSCBundle.h b/modules/juce_osc/osc/juce_OSCBundle.h index 23ed8d04..42ca2ee6 100644 --- a/modules/juce_osc/osc/juce_OSCBundle.h +++ b/modules/juce_osc/osc/juce_OSCBundle.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_osc/osc/juce_OSCMessage.cpp b/modules/juce_osc/osc/juce_OSCMessage.cpp index 69334276..b6de5e13 100644 --- a/modules/juce_osc/osc/juce_OSCMessage.cpp +++ b/modules/juce_osc/osc/juce_OSCMessage.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_osc/osc/juce_OSCMessage.h b/modules/juce_osc/osc/juce_OSCMessage.h index 99357111..de335478 100644 --- a/modules/juce_osc/osc/juce_OSCMessage.h +++ b/modules/juce_osc/osc/juce_OSCMessage.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_osc/osc/juce_OSCReceiver.cpp b/modules/juce_osc/osc/juce_OSCReceiver.cpp index 11481945..e9426385 100644 --- a/modules/juce_osc/osc/juce_OSCReceiver.cpp +++ b/modules/juce_osc/osc/juce_OSCReceiver.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_osc/osc/juce_OSCReceiver.h b/modules/juce_osc/osc/juce_OSCReceiver.h index 71648710..2f6ff9e9 100644 --- a/modules/juce_osc/osc/juce_OSCReceiver.h +++ b/modules/juce_osc/osc/juce_OSCReceiver.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -203,7 +202,7 @@ public: The arguments passed are the pointer to and the data of the buffer that the OSCReceiver has failed to parse. */ - using FormatErrorHandler = std::function<void(const char* data, int dataSize)>; + using FormatErrorHandler = std::function<void (const char* data, int dataSize)>; /** Installs a custom error handler which is called in case the receiver encounters a stream it cannot parse as an OSC bundle or OSC message. diff --git a/modules/juce_osc/osc/juce_OSCSender.cpp b/modules/juce_osc/osc/juce_OSCSender.cpp index fa75b063..527a3290 100644 --- a/modules/juce_osc/osc/juce_OSCSender.cpp +++ b/modules/juce_osc/osc/juce_OSCSender.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_osc/osc/juce_OSCSender.h b/modules/juce_osc/osc/juce_OSCSender.h index b9d04cc2..e118028c 100644 --- a/modules/juce_osc/osc/juce_OSCSender.h +++ b/modules/juce_osc/osc/juce_OSCSender.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_osc/osc/juce_OSCTimeTag.cpp b/modules/juce_osc/osc/juce_OSCTimeTag.cpp index e374e04c..c9d22b5e 100644 --- a/modules/juce_osc/osc/juce_OSCTimeTag.cpp +++ b/modules/juce_osc/osc/juce_OSCTimeTag.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -133,8 +132,8 @@ public: uint64 diff = laterTimeTagRaw - currentTimeTagRaw; double acceptableErrorInSeconds = 0.000001; // definitely not audible anymore. - expect (diff / float (1ULL << 32) < deltaInSeconds + acceptableErrorInSeconds ); - expect (diff / float (1ULL << 32) > deltaInSeconds - acceptableErrorInSeconds ); + expect ((float) diff / float (1ULL << 32) < deltaInSeconds + acceptableErrorInSeconds ); + expect ((float) diff / float (1ULL << 32) > deltaInSeconds - acceptableErrorInSeconds ); // round trip: diff --git a/modules/juce_osc/osc/juce_OSCTimeTag.h b/modules/juce_osc/osc/juce_OSCTimeTag.h index a1e0d3b6..e00f72f9 100644 --- a/modules/juce_osc/osc/juce_OSCTimeTag.h +++ b/modules/juce_osc/osc/juce_OSCTimeTag.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_osc/osc/juce_OSCTypes.cpp b/modules/juce_osc/osc/juce_OSCTypes.cpp index 2a74f15e..beeed492 100644 --- a/modules/juce_osc/osc/juce_OSCTypes.cpp +++ b/modules/juce_osc/osc/juce_OSCTypes.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_osc/osc/juce_OSCTypes.h b/modules/juce_osc/osc/juce_OSCTypes.h index 2b767410..759793d5 100644 --- a/modules/juce_osc/osc/juce_OSCTypes.h +++ b/modules/juce_osc/osc/juce_OSCTypes.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_product_unlocking/in_app_purchases/juce_InAppPurchases.cpp b/modules/juce_product_unlocking/in_app_purchases/juce_InAppPurchases.cpp index 8609cd58..b58a89ef 100644 --- a/modules/juce_product_unlocking/in_app_purchases/juce_InAppPurchases.cpp +++ b/modules/juce_product_unlocking/in_app_purchases/juce_InAppPurchases.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -70,7 +69,7 @@ void InAppPurchases::purchaseProduct (const String& productIdentifier, Listener::PurchaseInfo purchaseInfo { Purchase { "", productIdentifier, {}, {}, {} }, {} }; listeners.call ([&] (Listener& l) { l.productPurchaseFinished (purchaseInfo, false, "In-app purchases unavailable"); }); - ignoreUnused (isSubscription, upgradeProductIdentifiers, creditForUnusedSubscription); + ignoreUnused (upgradeProductIdentifier, creditForUnusedSubscription); #endif } diff --git a/modules/juce_product_unlocking/in_app_purchases/juce_InAppPurchases.h b/modules/juce_product_unlocking/in_app_purchases/juce_InAppPurchases.h index 38d21767..6dcaa09b 100644 --- a/modules/juce_product_unlocking/in_app_purchases/juce_InAppPurchases.h +++ b/modules/juce_product_unlocking/in_app_purchases/juce_InAppPurchases.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -200,9 +199,9 @@ public: @param productIdentifier The product identifier. - @param upgradeOrDowngradeFromSubscriptionsWithProductIdentifier (Android only) specifies the subscription that will be replaced by - the one being purchased now. Used only when buying a subscription - that is an upgrade or downgrade from another. + @param upgradeOrDowngradeFromSubscriptionWithProductIdentifier (Android only) specifies the subscription that will be replaced by + the one being purchased now. Used only when buying a subscription + that is an upgrade or downgrade from another. @param creditForUnusedSubscription (Android only) controls whether a user should be credited for any unused subscription time on the product that is being upgraded or downgraded. diff --git a/modules/juce_product_unlocking/juce_product_unlocking.cpp b/modules/juce_product_unlocking/juce_product_unlocking.cpp index 55a5344f..27b2d3a3 100644 --- a/modules/juce_product_unlocking/juce_product_unlocking.cpp +++ b/modules/juce_product_unlocking/juce_product_unlocking.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_product_unlocking/juce_product_unlocking.h b/modules/juce_product_unlocking/juce_product_unlocking.h index 9de31516..decb5e34 100644 --- a/modules/juce_product_unlocking/juce_product_unlocking.h +++ b/modules/juce_product_unlocking/juce_product_unlocking.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -29,20 +28,20 @@ The block below describes the properties of this module, and is read by the Projucer to automatically generate project code that uses it. For details about the syntax and how to create or use a module, see the - JUCE Module Format.txt file. + JUCE Module Format.md file. BEGIN_JUCE_MODULE_DECLARATION ID: juce_product_unlocking vendor: juce - version: 5.4.7 + version: 6.0.5 name: JUCE Online marketplace support description: Classes for online product authentication website: http://www.juce.com/juce license: GPL/Commercial - dependencies: juce_cryptography juce_core, juce_events + dependencies: juce_cryptography END_JUCE_MODULE_DECLARATION diff --git a/modules/juce_product_unlocking/juce_product_unlocking.mm b/modules/juce_product_unlocking/juce_product_unlocking.mm index 2f1f3c98..1a88d06b 100644 --- a/modules/juce_product_unlocking/juce_product_unlocking.mm +++ b/modules/juce_product_unlocking/juce_product_unlocking.mm @@ -2,16 +2,19 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - The code included in this file is provided under the terms of the ISC license - http://www.isc.org/downloads/software-support-policy/isc-license. Permission - To use, copy, modify, and/or distribute this software for any purpose with or - without fee is hereby granted provided that the above copyright notice and - this permission notice appear in all copies. + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE diff --git a/modules/juce_product_unlocking/marketplace/juce_KeyFileGeneration.h b/modules/juce_product_unlocking/marketplace/juce_KeyFileGeneration.h index 4b860384..abe0e241 100644 --- a/modules/juce_product_unlocking/marketplace/juce_KeyFileGeneration.h +++ b/modules/juce_product_unlocking/marketplace/juce_KeyFileGeneration.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -83,7 +82,7 @@ public: unlocker MyGreatApp Joe_Bloggs joebloggs@foobar.com 1234abcd,95432ff 22d9aec92d986dd1,923ad49e9e7ff294c */ - static inline int keyGenerationAppMain (int argc, char* argv[]) + static int keyGenerationAppMain (int argc, char* argv[]) { StringArray args; for (int i = 1; i < argc; ++i) diff --git a/modules/juce_product_unlocking/marketplace/juce_OnlineUnlockForm.cpp b/modules/juce_product_unlocking/marketplace/juce_OnlineUnlockForm.cpp index 19cc0887..8060740a 100644 --- a/modules/juce_product_unlocking/marketplace/juce_OnlineUnlockForm.cpp +++ b/modules/juce_product_unlocking/marketplace/juce_OnlineUnlockForm.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_product_unlocking/marketplace/juce_OnlineUnlockForm.h b/modules/juce_product_unlocking/marketplace/juce_OnlineUnlockForm.h index 33a677f7..97d31d13 100644 --- a/modules/juce_product_unlocking/marketplace/juce_OnlineUnlockForm.h +++ b/modules/juce_product_unlocking/marketplace/juce_OnlineUnlockForm.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_product_unlocking/marketplace/juce_OnlineUnlockStatus.cpp b/modules/juce_product_unlocking/marketplace/juce_OnlineUnlockStatus.cpp index cc39c9f2..4fb324ba 100644 --- a/modules/juce_product_unlocking/marketplace/juce_OnlineUnlockStatus.cpp +++ b/modules/juce_product_unlocking/marketplace/juce_OnlineUnlockStatus.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_product_unlocking/marketplace/juce_OnlineUnlockStatus.h b/modules/juce_product_unlocking/marketplace/juce_OnlineUnlockStatus.h index 702df5a1..aa6853cd 100644 --- a/modules/juce_product_unlocking/marketplace/juce_OnlineUnlockStatus.h +++ b/modules/juce_product_unlocking/marketplace/juce_OnlineUnlockStatus.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_product_unlocking/marketplace/juce_TracktionMarketplaceStatus.cpp b/modules/juce_product_unlocking/marketplace/juce_TracktionMarketplaceStatus.cpp index 79d77e34..e003fe3c 100644 --- a/modules/juce_product_unlocking/marketplace/juce_TracktionMarketplaceStatus.cpp +++ b/modules/juce_product_unlocking/marketplace/juce_TracktionMarketplaceStatus.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_product_unlocking/marketplace/juce_TracktionMarketplaceStatus.h b/modules/juce_product_unlocking/marketplace/juce_TracktionMarketplaceStatus.h index 14a7e682..9535131a 100644 --- a/modules/juce_product_unlocking/marketplace/juce_TracktionMarketplaceStatus.h +++ b/modules/juce_product_unlocking/marketplace/juce_TracktionMarketplaceStatus.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_product_unlocking/native/javaopt/app/com/roli/juce/JuceBillingClient.java b/modules/juce_product_unlocking/native/javaopt/app/com/rmsl/juce/JuceBillingClient.java similarity index 87% rename from modules/juce_product_unlocking/native/javaopt/app/com/roli/juce/JuceBillingClient.java rename to modules/juce_product_unlocking/native/javaopt/app/com/rmsl/juce/JuceBillingClient.java index c3e13454..656d783b 100644 --- a/modules/juce_product_unlocking/native/javaopt/app/com/roli/juce/JuceBillingClient.java +++ b/modules/juce_product_unlocking/native/javaopt/app/com/rmsl/juce/JuceBillingClient.java @@ -1,4 +1,29 @@ -package com.roli.juce; +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +package com.rmsl.juce; import com.android.billingclient.api.*; diff --git a/modules/juce_product_unlocking/native/juce_android_InAppPurchases.cpp b/modules/juce_product_unlocking/native/juce_android_InAppPurchases.cpp index 9d2ee8ac..d2c63591 100644 --- a/modules/juce_product_unlocking/native/juce_android_InAppPurchases.cpp +++ b/modules/juce_product_unlocking/native/juce_android_InAppPurchases.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -233,7 +232,7 @@ private: CALLBACK (purchaseCompletedCallback, "purchaseCompletedCallback", "(JLcom/android/billingclient/api/Purchase;I)V") \ CALLBACK (purchaseConsumedCallback, "purchaseConsumedCallback", "(JLjava/lang/String;I)V") - DECLARE_JNI_CLASS (JuceBillingClient, "com/roli/juce/JuceBillingClient") + DECLARE_JNI_CLASS (JuceBillingClient, "com/rmsl/juce/JuceBillingClient") #undef JNI_CLASS_MEMBERS static void JNICALL skuDetailsQueryCallback (JNIEnv*, jobject, jlong host, jobject skuDetailsList) @@ -509,8 +508,8 @@ private: InAppPurchases& owner; GlobalRef billingClient; - std::queue<std::function<void(LocalRef<jobject>)>> skuDetailsQueryCallbackQueue, - purchasesListQueryCallbackQueue; + std::queue<std::function<void (LocalRef<jobject>)>> skuDetailsQueryCallbackQueue, + purchasesListQueryCallbackQueue; //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Pimpl) diff --git a/modules/juce_product_unlocking/native/juce_ios_InAppPurchases.cpp b/modules/juce_product_unlocking/native/juce_ios_InAppPurchases.cpp index 3d66bd06..ca6fffb5 100644 --- a/modules/juce_product_unlocking/native/juce_ios_InAppPurchases.cpp +++ b/modules/juce_product_unlocking/native/juce_ios_InAppPurchases.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -100,7 +99,7 @@ struct InAppPurchases::Pimpl : public SKDelegateAndPaymentObserver [download retain]; } - ~DownloadImpl() + ~DownloadImpl() override { [download release]; } @@ -112,7 +111,7 @@ struct InAppPurchases::Pimpl : public SKDelegateAndPaymentObserver int64 getContentLength() const override { return download.contentLength; } Status getStatus() const override { return SKDownloadStateToDownloadStatus (download.downloadState); } #else - int64 getContentLength() const override { return [download.contentLength longLongValue]; } + int64 getContentLength() const override { return download.expectedContentLength; } Status getStatus() const override { return SKDownloadStateToDownloadStatus (download.state); } #endif @@ -180,7 +179,7 @@ struct InAppPurchases::Pimpl : public SKDelegateAndPaymentObserver //============================================================================== Pimpl (InAppPurchases& p) : owner (p) { [[SKPaymentQueue defaultQueue] addTransactionObserver: delegate.get()]; } - ~Pimpl() noexcept { [[SKPaymentQueue defaultQueue] removeTransactionObserver: delegate.get()]; } + ~Pimpl() noexcept override { [[SKPaymentQueue defaultQueue] removeTransactionObserver: delegate.get()]; } //============================================================================== bool isInAppPurchasesSupported() const { return true; } @@ -567,7 +566,8 @@ struct InAppPurchases::Pimpl : public SKDelegateAndPaymentObserver #endif // TODO: use juce URL here - auto storeRequest = [NSMutableURLRequest requestWithURL: [NSURL URLWithString: nsStringLiteral (storeURL)]]; + auto* urlPtr = [NSURL URLWithString: nsStringLiteral (storeURL)]; + auto storeRequest = [NSMutableURLRequest requestWithURL: urlPtr]; [storeRequest setHTTPMethod: nsStringLiteral ("POST")]; [storeRequest setHTTPBody: requestData]; diff --git a/modules/juce_video/capture/juce_CameraDevice.cpp b/modules/juce_video/capture/juce_CameraDevice.cpp index 023a200d..a9d76008 100644 --- a/modules/juce_video/capture/juce_CameraDevice.cpp +++ b/modules/juce_video/capture/juce_CameraDevice.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -32,16 +31,11 @@ namespace juce #elif JUCE_WINDOWS #include "../native/juce_win32_CameraDevice.h" #elif JUCE_IOS - #if JUCE_CLANG - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wunguarded-availability-new" - #endif + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wunguarded-availability-new") #include "../native/juce_ios_CameraDevice.h" - #if JUCE_CLANG - #pragma clang diagnostic pop - #endif + JUCE_END_IGNORE_WARNINGS_GCC_LIKE #elif JUCE_ANDROID #include "../native/juce_android_CameraDevice.h" #endif @@ -79,7 +73,7 @@ public: auto& pendingOpen = camerasToOpen.getReference (camerasToOpen.size() - 1); - pendingOpen.device->pimpl->open ([this](const String& deviceId, const String& error) + pendingOpen.device->pimpl->open ([this] (const String& deviceId, const String& error) { int cIndex = getCameraIndex (deviceId); @@ -159,7 +153,7 @@ Component* CameraDevice::createViewerComponent() return new ViewerComponent (*this); } -void CameraDevice::takeStillPicture (std::function<void(const Image&)> pictureTakenCallback) +void CameraDevice::takeStillPicture (std::function<void (const Image&)> pictureTakenCallback) { pimpl->takeStillPicture (pictureTakenCallback); } diff --git a/modules/juce_video/capture/juce_CameraDevice.h b/modules/juce_video/capture/juce_CameraDevice.h index 030a9330..302b01ac 100644 --- a/modules/juce_video/capture/juce_CameraDevice.h +++ b/modules/juce_video/capture/juce_CameraDevice.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -73,7 +72,7 @@ public: int maxWidth = 1024, int maxHeight = 768, bool highQuality = true); - using OpenCameraResultCallback = std::function<void(CameraDevice*, const String& /*error*/)>; + using OpenCameraResultCallback = std::function<void (CameraDevice*, const String& /*error*/)>; /** Asynchronously opens a camera device on iOS (iOS 7+) or Android (API 21+). On other platforms, the function will simply call openDevice(). Upon completion, @@ -127,7 +126,7 @@ public: Android does not support simultaneous video recording and still picture capture. */ - void takeStillPicture (std::function<void(const Image&)> pictureTakenCallback); + void takeStillPicture (std::function<void (const Image&)> pictureTakenCallback); /** Starts recording video to the specified file. @@ -172,7 +171,7 @@ public: /** Set this callback to be notified whenever an error occurs. You may need to close and reopen the device to be able to use it further. */ - std::function<void(const String& /*error*/)> onErrorOccurred; + std::function<void (const String& /*error*/)> onErrorOccurred; //============================================================================== /** diff --git a/modules/juce_video/juce_video.cpp b/modules/juce_video/juce_video.cpp index c3f89fc1..f7df267d 100644 --- a/modules/juce_video/juce_video.cpp +++ b/modules/juce_video/juce_video.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_video/juce_video.h b/modules/juce_video/juce_video.h index a8711013..90b4cbf7 100644 --- a/modules/juce_video/juce_video.h +++ b/modules/juce_video/juce_video.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -29,14 +28,14 @@ The block below describes the properties of this module, and is read by the Projucer to automatically generate project code that uses it. For details about the syntax and how to create or use a module, see the - JUCE Module Format.txt file. + JUCE Module Format.md file. BEGIN_JUCE_MODULE_DECLARATION ID: juce_video vendor: juce - version: 5.4.7 + version: 6.0.5 name: JUCE video playback and capture classes description: Classes for playing video and capturing camera input. website: http://www.juce.com/juce diff --git a/modules/juce_video/juce_video.mm b/modules/juce_video/juce_video.mm index 5cb5627c..0903e8b6 100644 --- a/modules/juce_video/juce_video.mm +++ b/modules/juce_video/juce_video.mm @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). diff --git a/modules/juce_video/native/java/app/com/roli/juce/CameraCaptureSessionCaptureCallback.java b/modules/juce_video/native/java/app/com/rmsl/juce/CameraCaptureSessionCaptureCallback.java similarity index 75% rename from modules/juce_video/native/java/app/com/roli/juce/CameraCaptureSessionCaptureCallback.java rename to modules/juce_video/native/java/app/com/rmsl/juce/CameraCaptureSessionCaptureCallback.java index 8fdd9d67..5d3fff65 100644 --- a/modules/juce_video/native/java/app/com/roli/juce/CameraCaptureSessionCaptureCallback.java +++ b/modules/juce_video/native/java/app/com/rmsl/juce/CameraCaptureSessionCaptureCallback.java @@ -1,4 +1,29 @@ -package com.roli.juce; +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +package com.rmsl.juce; import android.hardware.camera2.CameraCaptureSession; import android.hardware.camera2.CaptureRequest; diff --git a/modules/juce_video/native/java/app/com/roli/juce/CameraCaptureSessionStateCallback.java b/modules/juce_video/native/java/app/com/rmsl/juce/CameraCaptureSessionStateCallback.java similarity index 59% rename from modules/juce_video/native/java/app/com/roli/juce/CameraCaptureSessionStateCallback.java rename to modules/juce_video/native/java/app/com/rmsl/juce/CameraCaptureSessionStateCallback.java index b800f602..e6cbe28f 100644 --- a/modules/juce_video/native/java/app/com/roli/juce/CameraCaptureSessionStateCallback.java +++ b/modules/juce_video/native/java/app/com/rmsl/juce/CameraCaptureSessionStateCallback.java @@ -1,4 +1,29 @@ -package com.roli.juce; +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +package com.rmsl.juce; import android.hardware.camera2.CameraCaptureSession; diff --git a/modules/juce_video/native/java/app/com/roli/juce/CameraDeviceStateCallback.java b/modules/juce_video/native/java/app/com/rmsl/juce/CameraDeviceStateCallback.java similarity index 52% rename from modules/juce_video/native/java/app/com/roli/juce/CameraDeviceStateCallback.java rename to modules/juce_video/native/java/app/com/rmsl/juce/CameraDeviceStateCallback.java index 49cb45b7..b3493e5f 100644 --- a/modules/juce_video/native/java/app/com/roli/juce/CameraDeviceStateCallback.java +++ b/modules/juce_video/native/java/app/com/rmsl/juce/CameraDeviceStateCallback.java @@ -1,4 +1,29 @@ -package com.roli.juce; +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +package com.rmsl.juce; import android.hardware.camera2.CameraDevice; diff --git a/modules/juce_video/native/java/app/com/rmsl/juce/JuceOrientationEventListener.java b/modules/juce_video/native/java/app/com/rmsl/juce/JuceOrientationEventListener.java new file mode 100644 index 00000000..6b4de807 --- /dev/null +++ b/modules/juce_video/native/java/app/com/rmsl/juce/JuceOrientationEventListener.java @@ -0,0 +1,49 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +package com.rmsl.juce; + +import android.view.OrientationEventListener; +import android.content.Context; + +public class JuceOrientationEventListener extends OrientationEventListener +{ + private native void deviceOrientationChanged (long host, int orientation); + + public JuceOrientationEventListener (long hostToUse, Context context, int rate) + { + super (context, rate); + + host = hostToUse; + } + + @Override + public void onOrientationChanged (int orientation) + { + deviceOrientationChanged (host, orientation); + } + + private long host; +} diff --git a/modules/juce_video/native/java/app/com/roli/juce/MediaControllerCallback.java b/modules/juce_video/native/java/app/com/rmsl/juce/MediaControllerCallback.java similarity index 59% rename from modules/juce_video/native/java/app/com/roli/juce/MediaControllerCallback.java rename to modules/juce_video/native/java/app/com/rmsl/juce/MediaControllerCallback.java index a0f8ce37..f8a39508 100644 --- a/modules/juce_video/native/java/app/com/roli/juce/MediaControllerCallback.java +++ b/modules/juce_video/native/java/app/com/rmsl/juce/MediaControllerCallback.java @@ -1,4 +1,29 @@ -package com.roli.juce; +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +package com.rmsl.juce; import android.media.session.MediaController; import android.media.session.MediaSession; diff --git a/modules/juce_video/native/java/app/com/roli/juce/MediaSessionCallback.java b/modules/juce_video/native/java/app/com/rmsl/juce/MediaSessionCallback.java similarity index 61% rename from modules/juce_video/native/java/app/com/roli/juce/MediaSessionCallback.java rename to modules/juce_video/native/java/app/com/rmsl/juce/MediaSessionCallback.java index 882ae071..f5ba7dd9 100644 --- a/modules/juce_video/native/java/app/com/roli/juce/MediaSessionCallback.java +++ b/modules/juce_video/native/java/app/com/rmsl/juce/MediaSessionCallback.java @@ -1,4 +1,29 @@ -package com.roli.juce; +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +package com.rmsl.juce; import android.media.session.MediaSession; diff --git a/modules/juce_video/native/java/app/com/roli/juce/SystemVolumeObserver.java b/modules/juce_video/native/java/app/com/rmsl/juce/SystemVolumeObserver.java similarity index 52% rename from modules/juce_video/native/java/app/com/roli/juce/SystemVolumeObserver.java rename to modules/juce_video/native/java/app/com/rmsl/juce/SystemVolumeObserver.java index 86df1a9f..5e509f4b 100644 --- a/modules/juce_video/native/java/app/com/roli/juce/SystemVolumeObserver.java +++ b/modules/juce_video/native/java/app/com/rmsl/juce/SystemVolumeObserver.java @@ -1,4 +1,29 @@ -package com.roli.juce; +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). + + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +package com.rmsl.juce; import android.database.ContentObserver; import android.app.Activity; diff --git a/modules/juce_video/native/java/app/com/roli/juce/JuceOrientationEventListener.java b/modules/juce_video/native/java/app/com/roli/juce/JuceOrientationEventListener.java deleted file mode 100644 index 3d0c3967..00000000 --- a/modules/juce_video/native/java/app/com/roli/juce/JuceOrientationEventListener.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.roli.juce; - -import android.view.OrientationEventListener; -import android.content.Context; - -public class JuceOrientationEventListener extends OrientationEventListener -{ - private native void deviceOrientationChanged (long host, int orientation); - - public JuceOrientationEventListener (long hostToUse, Context context, int rate) - { - super (context, rate); - - host = hostToUse; - } - - @Override - public void onOrientationChanged (int orientation) - { - deviceOrientationChanged (host, orientation); - } - - private long host; -} diff --git a/modules/juce_video/native/juce_android_CameraDevice.h b/modules/juce_video/native/juce_android_CameraDevice.h index ae1aa9e5..f46f248f 100644 --- a/modules/juce_video/native/juce_android_CameraDevice.h +++ b/modules/juce_video/native/juce_android_CameraDevice.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -27,72 +26,70 @@ //============================================================================== // This byte-code is generated from: // -// native/java/com/roli/juce/CameraCaptureSessionCaptureCallback.java -// native/java/com/roli/juce/CameraCaptureSessionStateCallback.java -// native/java/com/roli/juce/CameraDeviceStateCallback.java -// native/java/com/roli/juce/JuceOrientationEventListener.java +// native/java/com/rmsl/juce/CameraCaptureSessionCaptureCallback.java +// native/java/com/rmsl/juce/CameraCaptureSessionStateCallback.java +// native/java/com/rmsl/juce/CameraDeviceStateCallback.java +// native/java/com/rmsl/juce/JuceOrientationEventListener.java // // files with min sdk version 21 // See juce_core/native/java/README.txt on how to generate this byte-code. -static const uint8 CameraSupportByteCode[] = { -31,139,8,8,45,45,227,91,0,3,67,97,109,101,114,97,83,117,112,112,111,114,116,46,100,101,120,0,149,152,93,108,28,213,21, -199,207,157,157,221,89,239,174,215,227,181,243,73,18,236,124,216,14,196,108,190,140,162,174,227,196,56,9,216,93,197,169, -215,118,35,3,45,147,221,73,60,116,189,179,204,174,151,84,173,74,136,168,8,47,85,80,105,1,9,33,16,1,209,7,36,183,4,194,3, -15,169,138,10,85,133,148,34,170,246,33,149,120,40,60,180,84,138,80,133,242,192,67,255,247,99,236,217,245,218,53,150,126, -251,63,51,231,220,115,239,61,247,206,120,102,10,246,249,216,222,3,3,244,159,203,87,222,62,245,197,223,255,124,233,193,91, -39,95,59,122,248,179,137,191,189,250,253,83,157,191,127,189,47,69,84,38,162,243,211,7,97,201,191,75,237,68,167,73,158, -239,0,55,24,209,38,232,22,141,40,12,125,32,68,212,199,253,80,29,186,128,159,219,9,162,189,112,190,23,37,186,14,254,5,82, -45,68,251,193,0,56,4,30,4,53,112,13,124,13,122,99,68,63,0,79,131,223,129,127,0,35,78,116,47,248,33,120,14,124,8,190,2,93, -200,191,3,244,130,187,121,95,96,0,100,192,81,112,63,24,7,167,193,35,160,0,28,224,130,26,248,41,120,2,60,13,94,3,127,2,95, -130,142,86,162,35,96,14,60,11,222,2,159,128,175,64,107,146,168,7,28,7,15,131,26,120,2,188,8,94,1,191,1,239,130,247,193, -135,224,47,224,115,240,53,136,183,17,237,2,195,32,7,30,6,101,240,51,240,11,240,60,120,21,92,3,215,193,199,224,38,248,28, -252,27,252,23,124,3,162,38,81,59,216,14,250,76,89,111,190,6,6,64,137,9,101,36,148,141,80,34,194,116,8,195,38,116,79,104, -74,8,39,44,37,165,212,58,118,130,117,96,61,232,81,218,174,214,124,131,178,23,144,120,163,178,223,51,228,186,115,251,58, -236,59,148,253,17,236,205,202,254,52,96,223,12,196,252,19,246,22,101,223,130,189,85,217,183,97,111,83,182,142,9,220,169, -236,78,216,93,202,222,25,176,15,6,236,99,176,183,43,123,18,118,183,178,31,10,156,47,192,222,161,236,34,236,157,202,62,15, -123,151,178,159,10,216,151,3,246,75,129,156,111,6,114,46,68,121,93,25,13,138,250,166,104,92,212,88,30,183,41,53,149,134, -84,61,117,165,17,165,9,177,34,188,125,84,105,146,118,11,77,208,93,66,91,233,110,161,45,180,71,104,140,250,133,198,233,30, -161,235,233,136,208,78,58,42,116,29,13,11,109,167,251,212,184,70,132,118,208,49,49,62,77,244,147,196,110,233,83,154,86, -186,87,233,62,165,251,133,154,52,164,244,184,210,19,74,239,87,154,21,243,149,121,219,48,179,3,74,15,10,53,104,64,29,223, -43,116,131,200,195,245,1,161,27,105,84,29,143,137,122,201,10,153,168,216,33,85,191,239,146,220,191,44,80,71,166,244,83, -147,212,124,228,57,191,190,154,210,148,218,200,109,202,239,215,221,207,115,66,249,77,229,79,52,172,143,167,252,97,100, -230,254,3,166,188,190,202,38,143,159,193,37,244,80,39,67,239,9,248,249,181,119,216,148,57,114,23,137,166,158,98,100,60, -105,252,202,120,195,184,86,51,194,20,140,59,177,98,92,164,46,110,124,197,56,67,196,197,48,19,62,214,211,166,188,214,115, -30,226,170,136,123,204,248,57,251,117,45,18,21,81,114,61,249,184,31,241,243,61,139,184,95,34,238,178,113,133,189,163,255, -177,22,109,17,81,41,244,202,239,27,142,41,107,154,251,45,226,222,70,220,130,241,129,241,87,253,139,48,110,60,181,88,76, -196,234,232,155,215,164,98,202,122,149,77,38,106,162,9,159,38,214,226,39,202,151,235,210,168,124,52,69,218,190,37,223, -197,58,95,71,157,239,153,58,95,103,157,239,114,157,111,93,157,239,249,58,223,122,229,147,227,124,121,113,156,154,24,103, -40,48,206,55,22,219,133,208,110,107,93,206,183,234,124,219,132,47,140,156,252,126,123,53,232,155,188,179,174,221,251,117, -237,186,132,47,34,90,18,253,193,31,203,222,16,13,135,103,82,122,96,44,31,47,182,211,209,174,71,180,243,247,59,83,104,129, -235,129,169,221,46,207,133,149,26,202,103,4,124,41,145,159,107,152,228,255,11,223,246,175,13,121,220,66,76,100,90,58,142, -214,197,183,136,61,18,60,142,171,62,252,113,133,149,29,86,99,244,251,144,255,167,100,254,144,178,163,139,49,50,175,111, -199,85,27,67,229,226,26,25,116,74,78,117,136,250,70,172,57,219,179,70,172,114,117,222,179,115,118,165,226,184,37,117,52, -98,21,139,103,172,252,143,238,121,212,170,89,212,211,44,50,87,181,170,13,113,219,100,220,49,187,230,228,237,38,126,54,74, -108,140,186,199,230,243,246,184,231,216,37,68,32,209,241,26,172,172,83,169,218,37,219,147,129,155,178,86,169,224,185,78, -33,157,119,75,56,95,77,143,112,61,95,205,208,145,69,215,172,229,21,30,183,60,59,157,23,189,238,79,55,27,229,206,134,9, -101,232,240,183,76,80,55,143,12,165,191,93,243,12,13,252,191,6,178,92,141,253,244,174,173,89,134,118,175,22,40,134,114, -194,114,138,144,181,132,78,216,143,205,219,21,148,185,111,13,161,149,249,34,34,251,87,142,156,116,171,86,177,33,124,105, -94,53,199,126,60,189,210,62,200,208,129,108,222,157,75,123,110,209,73,63,138,13,211,180,186,203,22,119,223,26,26,53,20, -122,119,211,38,77,246,112,134,246,52,132,174,182,145,51,196,166,73,155,30,5,99,20,154,30,27,229,63,89,210,241,35,204,25, -10,227,7,118,68,200,24,25,92,179,99,99,242,68,54,139,134,89,4,34,66,159,230,254,240,180,240,226,0,62,54,67,17,89,101,218, -156,111,50,199,225,124,213,169,217,180,179,153,207,47,154,59,87,46,218,85,187,64,221,171,68,241,189,131,144,93,171,132, -156,242,220,115,30,206,32,236,174,85,194,114,124,107,149,242,246,240,25,215,227,189,238,89,67,236,210,24,183,175,22,93, -181,68,198,166,149,24,41,186,124,100,59,154,250,220,210,89,231,220,210,44,183,173,26,84,160,77,205,252,19,182,85,248,49, -109,200,47,219,54,178,227,173,203,28,199,156,10,238,106,37,59,207,199,188,126,153,251,184,231,185,94,147,124,227,101,108, -171,2,25,121,121,39,164,141,5,225,11,236,191,145,89,171,116,14,33,97,91,164,48,206,202,235,158,226,103,61,36,59,57,63, -119,198,246,72,159,117,43,85,106,225,191,147,238,84,197,166,232,226,110,73,53,217,27,109,141,59,161,163,217,186,111,92, -113,149,55,175,178,166,230,178,21,140,46,174,87,251,242,213,73,212,173,69,210,45,213,21,210,192,245,39,166,141,28,170,84, -157,176,150,87,199,240,151,44,238,46,57,169,181,140,17,56,86,81,222,166,200,40,123,54,191,63,145,238,161,244,100,120,242, -190,72,17,79,250,99,21,53,155,81,36,172,200,141,64,109,149,89,119,190,88,184,15,149,81,141,171,179,78,133,90,170,206,28, -218,90,115,101,234,208,134,166,141,228,96,127,63,109,9,77,77,228,140,228,85,218,14,35,195,141,221,48,198,185,145,214,166, -38,141,228,235,52,16,154,154,28,228,39,6,245,169,137,211,176,62,161,36,27,226,205,105,29,155,50,146,51,116,135,148,110, -41,189,82,250,165,180,170,208,78,214,199,15,55,75,233,210,250,190,195,181,71,30,38,66,67,135,190,103,36,15,243,176,147, -252,4,105,120,120,214,152,166,95,184,160,47,196,216,69,60,229,53,33,206,110,196,24,187,13,94,137,51,246,17,184,5,94,72, -16,139,132,53,173,29,109,63,72,52,107,183,129,125,150,96,236,27,240,66,43,99,87,193,13,188,252,133,245,144,182,5,109,190, -108,109,140,239,102,151,146,140,93,1,215,193,77,60,194,105,76,215,118,61,121,65,191,157,228,254,94,246,92,155,124,175, -241,159,235,124,245,191,177,240,103,30,255,59,11,127,38,242,191,181,248,239,250,252,123,11,87,255,155,75,132,150,190,187, -176,46,249,94,207,191,189,48,83,190,187,243,119,120,173,75,230,231,223,99,66,42,134,191,211,240,151,105,222,86,188,79, -153,114,28,252,123,207,255,0,68,14,12,167,40,18,0,0}; +static const uint8 CameraSupportByteCode[] = +{31,139,8,8,187,110,161,94,0,3,67,97,109,101,114,97,83,117,112,112,111,114,116,66,121,116,101,67,111,100,101,46,100,101,120,0, +149,152,93,108,28,213,21,199,207,157,157,221,89,239,174,215,227,181,243,217,36,56,95,182,3,113,54,137,227,40,101,29,59,198,113, +192,102,133,169,215,182,34,3,45,147,221,73,188,176,222,89,102,215,139,171,86,37,68,84,208,151,42,80,90,168,4,136,170,20,181,15, +84,110,9,132,7,30,82,21,149,240,0,10,136,190,165,18,84,133,7,154,7,132,42,20,85,60,244,127,63,198,158,93,175,93,99,233,183, +255,51,115,206,61,247,222,115,239,140,103,38,103,47,68,14,246,246,209,213,103,22,174,255,247,133,96,249,25,246,233,195,151,255, +18,189,241,193,31,255,57,248,226,196,252,238,238,4,81,137,136,22,166,143,192,146,127,79,181,18,157,38,121,190,13,92,99,68,91, +160,219,52,162,32,244,174,0,81,55,247,67,117,232,34,126,110,198,136,14,194,249,86,152,232,10,248,2,36,154,136,14,131,62,112,12, +220,7,170,224,50,248,26,116,69,136,190,15,158,4,127,6,255,0,70,148,232,40,248,1,120,22,188,11,190,2,29,200,191,27,116,129,219, +120,95,160,15,164,192,9,112,39,24,7,167,193,131,32,7,242,192,1,85,240,99,240,24,120,18,252,22,188,7,110,128,182,102,162,65,48,7, +158,6,175,129,143,192,87,160,57,78,212,9,70,192,3,160,10,30,3,191,6,47,131,63,128,55,193,219,224,93,240,33,248,12,124,13,162, +45,68,123,193,16,200,128,7,64,9,252,4,252,28,60,7,126,3,46,131,43,224,125,112,29,124,6,254,13,254,3,190,1,97,147,168,21,236,2, +221,166,172,55,95,3,3,160,196,132,50,18,202,70,40,17,97,58,132,97,19,186,39,52,37,132,19,150,146,18,106,29,219,193,6,176,17, +116,42,109,85,107,190,73,217,139,72,188,89,217,111,25,114,221,185,125,5,246,119,148,125,21,246,86,101,127,236,179,175,251,98, +254,5,123,155,178,191,132,189,93,217,55,97,239,80,182,142,9,220,162,236,118,216,29,202,222,227,179,143,248,236,147,176,119,41, +123,18,246,78,101,223,239,59,159,131,189,91,217,5,216,123,148,189,0,123,175,178,159,240,217,23,125,246,11,190,156,191,247,229, +92,12,243,186,50,234,23,245,77,208,184,168,177,60,110,81,106,42,13,168,122,234,74,67,74,99,98,69,120,251,176,210,56,237,19,26, +163,91,133,54,211,109,66,155,104,191,208,8,245,8,141,210,1,161,27,105,80,104,59,157,16,186,129,134,132,182,210,29,106,92,195,66, +219,232,164,24,159,38,250,137,99,183,116,43,77,42,61,168,244,144,210,195,66,77,26,80,58,162,244,148,210,59,149,166,197,124, +101,222,22,204,172,87,233,17,161,6,245,169,227,163,66,55,137,60,92,239,18,186,153,70,213,241,152,168,151,172,144,137,138,29,83, +245,187,155,228,254,101,190,58,50,165,31,155,164,230,35,207,121,245,213,148,38,212,70,110,81,126,175,238,94,158,83,202,111, +42,127,172,110,125,92,229,15,34,51,247,247,154,242,250,42,153,60,126,6,151,208,253,237,12,189,199,224,231,215,222,113,83,230, +200,92,32,154,122,130,145,241,184,241,75,227,85,227,114,213,8,146,63,238,212,170,113,161,154,184,241,85,227,12,17,23,193,76,248, +88,79,155,242,90,207,184,136,171,32,238,17,227,167,236,87,213,80,88,68,201,245,228,227,126,208,203,247,52,226,126,129,184,139, +198,43,236,13,253,111,213,112,147,136,74,160,87,126,223,200,155,178,166,153,63,33,238,117,196,45,26,239,24,127,215,63,15,226, +198,83,141,68,68,172,142,190,121,77,202,166,172,87,201,100,162,38,154,240,105,98,45,126,164,124,153,14,141,74,39,18,164,29,90, +246,93,168,241,181,213,248,126,86,227,107,175,241,93,172,241,109,168,241,61,87,227,219,168,124,114,156,47,45,141,83,19,227,12, +248,198,249,234,82,187,0,218,109,175,201,249,90,141,111,135,240,5,145,147,223,111,47,249,125,147,183,212,180,123,187,166,93, +135,240,133,68,75,162,191,122,99,57,24,160,161,224,76,66,247,141,229,253,165,118,58,218,117,138,118,222,126,103,10,205,119,61, +48,181,219,229,185,160,82,67,249,12,159,47,33,242,115,13,146,252,127,225,217,222,181,33,143,155,136,137,76,203,199,225,154,248, +38,177,71,252,199,81,213,135,55,174,160,178,131,106,140,94,31,242,255,148,204,31,80,118,120,41,70,230,245,236,168,106,99,168, +92,92,67,253,249,98,190,50,64,221,195,214,156,237,90,195,86,169,50,239,218,25,187,92,206,59,69,117,52,108,21,10,103,172,236,195, +7,30,178,170,22,117,54,138,204,84,172,74,93,220,14,25,119,210,174,230,179,118,3,63,27,37,54,70,59,199,230,179,246,184,155, +183,139,136,64,162,145,42,172,116,190,92,177,139,182,43,3,183,164,173,98,206,117,242,185,100,214,41,226,124,37,57,204,117,161, +146,162,193,37,215,172,229,230,30,181,92,59,153,21,189,30,78,54,26,229,158,186,9,165,232,248,183,76,80,51,143,20,37,191,93,243, +20,245,253,191,6,178,92,245,253,116,173,175,89,138,246,173,21,40,134,114,202,202,23,32,235,9,157,176,31,153,183,203,40,115,247, +58,66,203,243,5,68,246,172,30,57,233,84,172,66,93,248,242,188,170,121,251,209,228,106,251,32,69,189,233,172,51,151,116,231, +202,133,228,67,216,48,13,171,187,98,113,15,173,163,81,93,161,247,53,108,210,96,15,167,104,127,93,232,90,27,57,69,108,154,180, +233,81,48,70,129,233,177,81,254,147,38,29,63,194,156,161,32,126,96,135,132,140,145,193,53,61,54,38,79,164,211,104,152,70,32,34, +244,105,238,15,78,11,47,14,224,99,51,20,146,85,166,173,217,6,115,28,202,86,242,85,155,246,52,242,121,69,115,230,74,5,187,98,231, +104,231,26,81,124,239,32,100,239,26,33,247,186,206,57,23,103,16,118,235,26,97,25,190,181,138,89,123,232,140,227,242,94,247, +175,35,118,121,140,187,214,138,174,88,34,99,195,74,12,23,28,62,178,221,13,125,78,241,108,254,220,242,44,119,172,25,148,163,45, +141,252,19,182,149,251,33,109,202,174,216,54,178,227,237,43,28,39,243,101,220,213,138,118,150,143,121,227,10,247,136,235,58, +110,131,124,227,37,108,171,28,25,89,121,39,164,205,57,225,243,237,191,225,89,171,120,14,33,65,91,164,48,206,202,235,158,162,103, +93,36,187,103,126,238,140,237,146,62,235,148,43,212,196,127,39,157,169,178,77,225,165,221,146,104,176,55,90,234,119,66,91, +163,117,223,188,234,42,111,93,99,77,205,21,43,24,94,90,175,214,149,171,19,171,89,139,184,83,172,41,164,129,235,79,76,27,57,84, +169,218,97,173,172,142,225,45,89,212,89,118,82,115,9,35,200,91,5,121,155,34,163,228,218,252,254,68,186,139,210,147,225,202,251, +34,133,92,233,143,148,213,108,70,145,176,44,55,2,181,148,103,157,249,66,238,14,84,70,53,174,204,230,203,212,84,201,207,161,173, +53,87,162,30,109,96,218,136,247,247,244,208,209,192,212,68,198,136,95,162,126,24,41,110,12,195,24,231,198,168,54,53,105,196, +127,71,227,129,169,201,126,126,98,90,159,154,56,13,235,35,218,207,6,120,115,234,101,83,70,124,134,190,43,101,80,202,136,148,187, +165,116,169,208,3,172,155,31,30,145,114,187,214,125,59,215,19,242,176,51,48,112,236,123,70,252,56,15,187,135,159,32,13,15, +207,26,211,244,243,231,245,197,8,187,128,167,188,6,68,217,181,8,99,55,193,203,81,198,174,130,47,193,243,49,98,161,160,166,181, +162,237,59,177,70,237,54,177,79,98,140,125,3,158,111,102,236,18,184,134,151,191,160,30,208,182,161,205,141,230,250,248,157,236, +169,56,99,175,128,43,224,58,30,225,52,166,107,123,31,63,175,223,140,115,127,23,123,182,69,190,215,120,207,117,158,122,223,88, +248,51,143,247,157,133,63,19,121,223,90,188,119,125,254,189,133,171,247,205,37,68,203,223,93,88,135,124,175,231,223,94,152,41, +223,221,249,59,188,214,33,243,243,239,49,1,21,195,223,105,248,203,52,111,43,222,167,76,57,14,254,189,231,127,249,28,121,55,40,18, +0,0,0,0}; #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ STATICMETHOD (valueOf, "valueOf", "(Ljava/lang/String;)Landroid/graphics/Bitmap$CompressFormat;") @@ -487,7 +484,7 @@ private: struct CameraDevice::Pimpl : private ActivityLifecycleCallbacks { - using InternalOpenCameraResultCallback = std::function<void(const String& /*cameraId*/, const String& /*error*/)>; + using InternalOpenCameraResultCallback = std::function<void (const String& /*cameraId*/, const String& /*error*/)>; Pimpl (CameraDevice& ownerToUse, const String& cameraIdToUse, int /*index*/, int minWidthToUse, int minHeightToUse, int maxWidthToUse, int maxHeightToUse, @@ -563,7 +560,7 @@ struct CameraDevice::Pimpl bool openedOk() const noexcept { return scopedCameraDevice->openedOk(); } - void takeStillPicture (std::function<void(const Image&)> pictureTakenCallbackToUse) + void takeStillPicture (std::function<void (const Image&)> pictureTakenCallbackToUse) { if (pictureTakenCallbackToUse == nullptr || currentCaptureSessionMode == nullptr) { @@ -1325,6 +1322,7 @@ private: return (cameraSensorOrientation + 180) % 360; } break; + case Desktop::allOrientations: default: return 0; } @@ -1729,7 +1727,7 @@ private: CALLBACK (cameraCaptureSessionCaptureSequenceAbortedCallback, "cameraCaptureSessionCaptureSequenceAborted", "(JZLandroid/hardware/camera2/CameraCaptureSession;I)V") \ CALLBACK (cameraCaptureSessionCaptureSequenceCompletedCallback, "cameraCaptureSessionCaptureSequenceCompleted", "(JZLandroid/hardware/camera2/CameraCaptureSession;IJ)V") - DECLARE_JNI_CLASS_WITH_BYTECODE (CameraCaptureSessionCaptureCallback, "com/roli/juce/CameraCaptureSessionCaptureCallback", 21, CameraSupportByteCode, sizeof(CameraSupportByteCode)) + DECLARE_JNI_CLASS_WITH_BYTECODE (CameraCaptureSessionCaptureCallback, "com/rmsl/juce/CameraCaptureSessionCaptureCallback", 21, CameraSupportByteCode, sizeof(CameraSupportByteCode)) #undef JNI_CLASS_MEMBERS LocalRef<jobject> createCaptureSessionCallback (bool createPreviewSession) @@ -2126,7 +2124,7 @@ private: CALLBACK(cameraCaptureSessionConfiguredCallback, "cameraCaptureSessionConfigured", "(JLandroid/hardware/camera2/CameraCaptureSession;)V") \ CALLBACK(cameraCaptureSessionReadyCallback, "cameraCaptureSessionReady", "(JLandroid/hardware/camera2/CameraCaptureSession;)V") - DECLARE_JNI_CLASS_WITH_MIN_SDK (CameraCaptureSessionStateCallback, "com/roli/juce/CameraCaptureSessionStateCallback", 21) + DECLARE_JNI_CLASS_WITH_MIN_SDK (CameraCaptureSessionStateCallback, "com/rmsl/juce/CameraCaptureSessionStateCallback", 21) #undef JNI_CLASS_MEMBERS @@ -2391,7 +2389,7 @@ private: CALLBACK (cameraDeviceStateErrorCallback, "cameraDeviceStateError", "(JLandroid/hardware/camera2/CameraDevice;I)V") \ CALLBACK (cameraDeviceStateOpenedCallback, "cameraDeviceStateOpened", "(JLandroid/hardware/camera2/CameraDevice;)V") - DECLARE_JNI_CLASS_WITH_MIN_SDK (CameraDeviceStateCallback, "com/roli/juce/CameraDeviceStateCallback", 21) + DECLARE_JNI_CLASS_WITH_MIN_SDK (CameraDeviceStateCallback, "com/rmsl/juce/CameraDeviceStateCallback", 21) #undef JNI_CLASS_MEMBERS LocalRef<jobject> createCameraStateCallbackObject() @@ -2836,7 +2834,7 @@ private: METHOD (enable, "enable", "()V") \ CALLBACK (deviceOrientationChanged, "deviceOrientationChanged", "(JI)V") - DECLARE_JNI_CLASS_WITH_MIN_SDK (OrientationEventListener, "com/roli/juce/JuceOrientationEventListener", 21) + DECLARE_JNI_CLASS_WITH_MIN_SDK (OrientationEventListener, "com/rmsl/juce/JuceOrientationEventListener", 21) #undef JNI_CLASS_MEMBERS LocalRef<jobject> createOrientationEventListener() @@ -2935,7 +2933,7 @@ private: CriticalSection listenerLock; ListenerList<Listener> listeners; - std::function<void(const Image&)> pictureTakenCallback; + std::function<void (const Image&)> pictureTakenCallback; Time firstRecordedFrameTimeMs; bool notifiedOfCameraOpening = false; diff --git a/modules/juce_video/native/juce_android_Video.h b/modules/juce_video/native/juce_android_Video.h index 5b64a881..925eb9ef 100644 --- a/modules/juce_video/native/juce_android_Video.h +++ b/modules/juce_video/native/juce_android_Video.h @@ -2,22 +2,23 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2018 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy - ------------------------------------------------------------------------------ + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -25,76 +26,74 @@ //============================================================================== // This byte-code is generated from: // -// native/java/com/roli/juce/MediaControllerCallback.java -// native/java/com/roli/juce/MediaSessionCallback.java -// native/java/com/roli/juce/SystemVolumeObserver.java +// native/java/com/rmsl/juce/MediaControllerCallback.java +// native/java/com/rmsl/juce/MediaSessionCallback.java +// native/java/com/rmsl/juce/SystemVolumeObserver.java // // files with min sdk version 21 // See juce_core/native/java/README.txt on how to generate this byte-code. static const unsigned char MediaSessionByteCode[] = -{31,139,8,8,235,44,227,91,0,3,77,101,100,105,97,83,101,115,115,105,111,110,46,100,101,120,0,149,152,127,108,28,71,21,199, -223,236,253,244,157,125,183,119,254,21,55,110,226,52,206,15,151,218,119,36,129,58,57,215,248,7,54,113,56,59,110,206,118, -131,41,13,107,223,214,222,228,188,123,236,238,185,177,80,69,85,165,82,145,250,7,34,32,85,72,69,65,2,137,72,1,84,250,15, -63,42,26,9,81,33,129,10,149,42,17,4,130,34,1,165,168,18,63,148,72,21,164,130,239,204,206,158,247,46,14,42,151,124,246, -189,121,239,205,236,155,55,51,231,219,45,235,23,19,249,163,31,162,82,113,228,219,95,188,252,253,171,127,206,39,23,143, -254,97,228,234,196,107,173,223,121,242,213,183,126,120,41,67,84,37,162,139,75,199,178,36,63,215,85,162,85,242,236,221, -224,54,243,228,89,133,40,2,89,9,17,29,134,252,18,36,254,211,27,97,162,249,86,162,99,112,62,22,39,210,64,25,84,128,13,62, -7,158,6,207,128,23,192,117,240,27,112,11,244,180,16,13,131,243,224,10,248,5,248,15,56,152,32,58,14,230,64,25,60,11,94,4, -191,2,239,129,222,36,81,30,140,131,18,248,50,120,9,188,6,222,6,239,128,191,131,91,224,95,128,144,95,24,180,128,20,232,0, -187,192,189,160,15,244,131,33,240,16,208,193,6,184,4,158,7,95,5,87,193,183,192,75,224,85,240,22,136,181,17,61,0,102,193, -18,48,192,103,193,243,224,26,248,17,248,61,120,27,188,7,98,41,162,46,112,63,120,8,76,131,57,160,129,45,240,121,112,25, -188,0,94,4,175,128,215,193,31,193,59,224,31,224,93,144,73,35,111,48,0,78,128,105,48,11,74,224,83,224,34,120,50,237,173, -85,12,160,204,132,146,18,202,70,178,20,132,116,8,67,17,194,8,91,128,248,226,183,131,14,208,9,186,228,218,239,2,61,224,30, -208,11,246,129,7,64,20,40,114,191,112,61,20,208,219,165,190,79,142,197,63,247,73,253,58,18,218,47,245,159,66,239,151,250, -47,3,250,141,128,254,38,244,3,82,255,11,244,67,82,191,9,253,160,212,111,7,244,112,124,91,111,13,232,29,208,7,164,222,27, -176,31,142,123,123,153,235,249,128,125,24,250,253,82,31,131,254,1,169,159,132,62,40,235,51,31,208,207,198,121,61,147,20, -150,53,61,6,84,41,51,196,104,72,214,153,183,25,254,29,17,245,75,211,89,33,147,244,105,89,195,163,196,215,77,21,181,141, -193,162,136,181,243,100,18,215,115,98,252,176,104,167,17,113,92,200,40,157,16,50,78,5,233,31,17,178,141,166,132,108,165, -25,33,83,52,43,100,150,230,132,12,209,195,34,79,111,60,46,71,165,252,136,144,45,52,38,100,132,198,165,125,66,200,16,125, -76,200,78,58,41,219,167,164,252,184,144,25,42,202,246,105,217,111,94,182,207,72,89,146,246,5,217,94,20,245,73,136,60,50, -176,79,10,217,65,211,66,182,211,178,216,87,93,244,168,172,47,35,111,111,243,207,30,240,77,52,6,84,175,173,74,127,139,244, -239,149,242,19,210,159,145,254,136,180,247,73,249,13,233,231,190,30,232,97,228,197,245,75,105,111,95,87,213,8,218,203,89, -134,58,242,138,241,181,126,78,250,74,125,140,170,99,45,164,124,112,219,119,185,193,151,104,240,125,165,193,151,20,62,69, -158,168,175,165,189,28,82,98,79,48,177,47,174,5,227,243,173,164,176,84,61,191,239,214,243,139,138,252,20,244,100,194,67, -244,131,134,177,188,241,95,73,123,103,55,171,166,235,227,255,164,62,190,130,241,219,197,248,190,239,103,13,190,14,225, -139,192,195,235,247,122,208,183,208,41,230,225,223,251,215,129,123,71,101,252,239,252,248,60,226,23,187,40,52,190,29,255, -167,64,188,111,251,107,67,254,222,183,204,223,118,168,207,173,134,28,187,69,142,81,185,175,255,157,246,246,66,150,170, -125,220,242,201,253,33,90,238,15,139,254,17,57,106,68,245,190,3,77,53,134,94,173,116,15,203,147,217,119,8,123,41,65,195, -216,105,37,244,172,230,251,229,220,189,53,76,169,222,119,220,112,184,157,22,242,33,244,229,217,181,66,134,132,92,65,146, -217,172,57,198,72,61,146,218,49,194,68,182,121,58,252,79,170,127,24,109,239,97,254,247,212,111,43,13,50,42,101,92,202, -132,172,76,187,248,110,87,228,56,254,30,103,228,213,134,145,247,183,128,145,247,183,128,247,73,226,76,249,49,109,178,47, -31,133,183,59,164,189,75,218,187,16,205,219,97,105,111,39,118,152,216,8,69,71,12,211,112,71,41,60,90,24,88,162,228,228, -233,185,133,169,185,133,115,139,103,102,136,157,34,86,164,174,162,102,150,109,203,40,231,180,106,53,55,190,234,26,155, -134,187,85,160,125,117,251,170,101,186,186,233,230,38,61,121,70,119,172,202,166,110,23,168,103,231,144,139,110,129,118, -221,225,154,17,162,64,247,213,61,101,205,213,86,52,71,247,7,62,189,226,232,182,24,248,222,122,204,134,94,54,180,220,44, -191,206,234,174,198,187,20,40,223,228,118,116,199,49,44,211,11,227,131,217,86,165,162,219,253,147,90,165,178,162,173,94, -40,208,177,247,217,99,190,162,109,241,30,51,230,227,86,129,6,255,87,175,146,215,8,220,100,232,253,132,63,92,211,107,250, -140,171,111,20,232,192,93,226,253,36,74,174,230,234,5,202,212,195,76,221,205,45,218,70,129,218,235,38,203,201,77,212,204, -114,5,113,29,65,227,73,141,27,237,96,185,171,182,181,105,148,117,59,87,210,93,215,48,215,156,254,210,150,35,18,57,84,92, -181,54,114,40,129,145,59,95,91,213,155,171,178,61,195,254,157,2,229,204,238,30,229,221,102,201,170,212,54,244,224,26,151, -181,202,166,113,33,167,153,166,133,153,242,153,151,140,53,83,115,107,54,102,147,45,158,215,54,181,92,69,51,215,114,37, -215,70,190,5,74,123,182,154,107,84,114,69,195,113,73,109,50,20,104,172,201,50,242,255,173,201,104,129,122,239,50,251,33, -62,48,245,236,52,101,233,218,105,158,158,139,45,145,178,116,138,66,75,167,196,165,72,97,92,138,176,21,209,44,114,91,145, -219,138,203,220,182,140,38,20,182,76,10,68,92,147,39,146,218,124,109,193,90,116,116,58,40,15,214,137,28,38,229,45,104, -206,17,25,228,54,69,10,231,54,106,142,177,74,81,156,71,91,115,168,115,77,119,199,171,213,138,177,42,106,45,79,42,101,97, -110,58,216,20,94,183,80,220,22,126,245,238,165,24,101,10,27,56,19,148,17,101,156,168,185,174,101,122,39,154,246,110,52, -22,108,188,86,54,44,126,128,38,215,177,120,122,153,246,52,5,248,7,217,247,239,111,242,55,236,127,63,168,249,46,114,9,62, -170,59,48,108,33,32,38,2,102,202,50,69,233,159,215,106,200,95,109,48,97,120,218,221,108,153,182,173,141,89,57,66,54,232, -44,233,250,133,5,171,113,136,146,107,85,101,70,190,37,176,246,126,202,241,13,57,81,202,90,230,29,85,137,99,13,132,74,109, -150,57,173,57,238,180,101,63,161,217,101,30,60,187,93,228,169,77,94,227,12,183,53,86,45,230,79,46,42,167,148,185,115,34, -93,158,233,142,98,166,44,83,236,249,64,46,103,244,39,12,83,104,114,194,89,174,53,213,184,21,182,11,70,117,193,154,227,91, -71,245,91,243,182,190,105,88,53,135,167,224,89,234,39,138,103,39,170,21,170,90,14,69,62,195,237,212,109,235,107,56,155, -56,91,141,95,252,148,112,244,202,227,178,42,208,221,41,83,91,169,224,190,105,103,221,170,85,202,19,186,111,72,56,174,102, -187,206,35,134,187,78,17,135,79,141,194,238,186,225,80,220,181,188,111,11,234,169,153,119,187,77,168,102,27,20,217,212, -42,200,37,203,62,28,75,141,12,82,15,27,142,165,150,105,47,155,226,226,0,123,140,139,1,70,97,118,182,115,15,30,14,135,136, -27,58,100,244,131,252,121,113,132,29,199,117,183,112,236,19,215,67,202,232,17,46,199,184,123,144,61,194,245,73,174,79, -243,203,12,123,16,215,163,34,50,165,228,49,82,113,112,144,246,42,203,43,177,212,143,151,169,139,61,26,75,13,50,53,211,75, -74,150,173,244,70,186,169,123,119,55,235,86,187,241,59,42,18,97,74,252,169,167,194,47,39,216,211,10,5,105,99,55,18,140, -221,4,95,72,50,118,13,92,199,47,129,104,82,81,178,136,255,109,178,57,158,179,139,189,139,184,231,90,25,187,2,94,6,55,192, -77,240,108,27,99,95,7,223,3,63,7,111,182,145,162,40,33,133,41,251,49,218,237,54,222,251,0,187,146,98,244,70,138,212,166, -223,69,92,250,239,38,248,111,18,255,253,68,136,182,223,81,132,105,251,61,5,151,254,187,10,255,57,149,191,175,8,169,222, -88,226,55,86,159,247,108,55,2,61,218,231,217,249,243,4,83,189,103,89,254,204,170,244,121,247,229,239,55,66,50,158,63,23, -132,251,182,159,23,248,131,4,31,95,60,135,200,241,249,187,148,255,2,145,38,223,176,132,17,0,0}; +{ 31,139,8,8,247,108,161,94,0,3,77,101,100,105,97,83,101,115,115,105,111,110,66,121,116,101,67,111,100,101,46,100,101,120,0,149, +152,127,108,28,71,21,199,223,236,253,180,207,190,95,254,221,186,169,211,56,137,19,234,220,145,26,226,228,28,99,199,216,196,233, +249,71,125,182,107,76,168,187,246,109,236,77,238,118,143,221,189,171,45,132,168,170,32,21,209,63,144,74,165,170,82,81,144,64, +128,20,36,74,37,132,80,69,35,126,75,32,160,82,36,130,64,80,16,8,138,42,126,41,17,21,164,130,239,204,206,158,239,46,14,42,151, +124,246,189,121,239,205,236,155,55,51,231,219,205,107,219,205,233,135,222,67,219,115,149,223,125,253,83,63,120,252,139,71,187, +47,68,78,252,118,237,250,194,183,191,251,151,175,254,243,214,229,4,81,137,136,182,151,135,146,36,63,215,226,68,27,228,218,187, +192,109,230,202,21,133,40,0,89,240,17,13,64,126,6,18,255,233,186,159,104,190,133,104,8,206,199,194,68,42,200,131,2,176,192,199, +193,83,224,19,224,69,112,13,252,18,220,2,61,77,68,195,224,34,184,2,126,10,254,3,14,53,19,157,4,179,32,15,158,6,47,129,159,131, +183,65,111,132,40,13,198,65,14,60,7,94,6,63,1,111,128,55,193,223,192,45,240,47,64,200,207,15,154,64,20,180,131,110,112,31,232, +3,253,224,24,56,13,52,80,4,151,193,243,224,179,224,203,224,43,224,101,240,125,240,71,16,106,37,122,16,204,128,101,160,131,143, +130,231,193,85,240,45,240,27,240,6,120,27,132,162,68,157,224,40,56,13,166,192,44,80,193,14,248,36,120,22,188,8,94,2,175,130, +215,192,239,193,155,224,239,224,45,144,136,33,111,112,4,156,2,83,96,6,228,192,135,193,54,248,88,204,93,171,16,64,153,9,37,37,148, +141,100,41,8,233,16,134,34,132,17,182,0,241,197,111,3,237,160,3,116,202,181,239,6,61,224,30,208,11,246,131,7,65,16,40,114,191, +112,221,87,163,183,73,125,191,28,139,127,30,144,250,53,36,116,64,234,63,132,222,47,245,159,213,232,55,106,244,215,161,31,148, +250,159,160,31,150,250,77,232,135,164,126,187,70,247,135,119,245,150,26,189,29,250,17,169,247,214,216,7,194,238,94,230,122,186, +198,62,12,253,168,212,199,160,191,75,234,103,161,15,202,250,204,215,232,43,97,94,207,8,249,101,77,135,64,92,202,4,49,58,38, +235,204,219,12,255,142,139,250,197,104,69,200,8,61,46,107,248,16,241,117,139,139,218,134,96,81,196,218,185,50,130,235,154,24, +223,47,218,49,68,156,20,50,72,167,132,12,83,70,250,71,132,108,165,73,33,91,104,90,200,40,205,8,153,164,89,33,125,244,136,200, +211,29,143,203,81,41,223,39,100,19,141,9,25,160,113,105,63,35,164,143,62,32,100,7,157,149,237,115,82,62,44,100,130,178,178,61, +39,251,205,203,246,130,148,57,105,95,148,237,37,81,159,102,145,71,2,246,9,33,219,105,74,200,54,90,21,251,170,147,206,203,250, +50,114,247,54,255,236,3,95,66,227,72,220,109,199,165,191,73,250,239,151,242,131,210,159,144,254,128,180,247,73,249,5,233,231, +190,30,232,126,228,197,245,203,49,119,95,151,226,1,180,87,147,12,117,228,21,227,107,253,140,244,229,250,24,149,198,154,72,121, +247,174,239,217,58,95,115,157,239,133,58,95,68,248,20,121,162,62,23,115,115,136,138,61,193,196,190,184,90,27,159,110,33,133,69, +171,249,125,173,154,95,80,228,167,160,39,19,30,162,111,214,141,229,142,255,106,204,61,187,201,120,172,58,254,247,170,227,43, +24,191,77,140,239,249,126,84,231,107,23,190,0,60,188,126,175,213,250,22,59,196,60,188,123,255,162,230,222,65,25,255,107,47,62, +141,248,165,78,242,141,239,198,255,161,38,222,179,253,185,46,127,247,91,230,175,123,212,231,86,93,142,93,34,199,160,220,215, +255,142,185,123,33,73,165,62,110,249,208,1,31,173,246,251,69,255,128,28,53,16,119,191,3,141,120,8,189,90,232,30,150,38,163,239, +48,246,82,51,13,99,167,229,208,179,148,238,151,115,119,215,48,26,119,191,227,134,253,109,180,152,246,161,47,207,174,5,210,39, +228,58,146,76,38,141,49,70,241,227,209,61,35,12,100,155,166,129,127,80,245,195,104,119,15,243,191,167,94,91,169,147,65,41,195, +82,54,203,202,180,137,239,118,69,142,227,237,113,70,110,109,24,185,127,11,24,185,127,11,120,159,8,206,148,23,211,42,251,242, +81,120,187,93,218,59,165,189,19,209,188,237,151,246,54,98,3,196,70,40,56,162,27,186,51,74,254,209,204,145,101,138,76,204,205, +46,78,206,46,174,45,45,76,19,59,71,44,75,157,89,213,200,91,166,158,79,169,165,82,106,124,195,209,43,186,179,147,161,253,85,251, +134,105,56,154,225,164,38,92,185,160,217,102,161,162,89,25,234,217,59,100,219,201,80,247,29,174,105,33,50,244,64,213,147,87,29, +117,93,181,53,111,224,185,117,91,179,196,192,247,85,99,138,90,94,87,83,51,252,58,163,57,42,239,146,161,116,131,219,214,108, +91,55,13,55,140,15,102,153,133,130,102,245,79,168,133,194,186,186,113,41,67,67,239,176,199,124,65,221,225,61,166,141,11,102, +134,6,255,87,175,156,219,168,185,201,177,119,18,254,72,89,43,107,211,142,86,204,208,193,187,196,123,73,228,28,213,209,50,148,168, +134,25,154,147,90,178,244,12,181,85,77,166,157,58,83,54,242,5,196,181,215,26,207,170,220,104,213,150,187,100,153,21,61,175,89, +169,156,230,56,186,177,105,247,231,118,108,145,200,225,236,134,89,76,89,69,187,144,186,88,222,208,26,171,178,59,195,254,189, +2,229,204,238,30,229,222,102,217,44,148,139,90,237,26,231,213,66,69,191,148,82,13,195,196,76,249,204,115,250,166,161,58,101, +11,179,73,102,47,170,21,53,85,80,141,205,84,206,177,144,111,134,98,174,173,236,232,133,84,86,183,29,138,55,24,50,52,214,96,25, +249,255,214,100,52,67,189,119,153,253,49,62,48,245,236,53,101,233,218,107,158,174,139,45,147,178,124,142,124,203,231,196,37,75, +126,92,178,176,101,209,204,114,91,150,219,178,171,220,182,138,38,20,182,74,10,68,88,149,39,146,90,61,109,209,92,178,53,58,36, +15,214,169,20,38,229,46,104,202,22,25,164,42,34,133,181,98,217,214,55,40,136,243,104,169,54,117,108,106,206,120,169,84,208,55, +68,173,229,73,165,36,204,13,7,155,252,91,38,138,219,196,175,238,189,20,61,79,126,29,103,130,18,162,140,103,202,142,99,26,238, +137,166,251,139,245,5,27,47,231,117,147,31,160,137,45,44,158,150,167,125,13,1,222,65,246,252,7,26,252,117,251,223,11,106,188, +139,92,130,247,107,54,12,59,8,8,137,128,233,188,76,81,250,231,213,50,242,143,215,153,48,60,221,219,104,153,178,204,226,140,28, +33,89,235,204,105,218,165,69,179,126,136,156,99,150,100,70,158,165,102,237,189,148,195,69,57,81,74,154,198,29,85,9,99,13,132, +74,173,166,49,165,218,206,148,105,61,161,90,121,30,60,179,91,228,201,10,175,113,130,219,234,171,22,242,38,23,148,83,74,220,57, +145,78,215,116,71,49,163,166,33,246,124,77,46,11,218,19,186,33,52,57,225,36,215,26,106,220,2,219,37,189,180,104,206,242,173,19, +247,90,243,150,86,209,205,178,205,83,112,45,213,19,197,179,19,213,242,149,76,155,2,31,225,118,234,178,180,77,156,77,156,173, +250,47,126,106,182,181,194,5,89,21,232,206,164,161,174,23,112,223,152,189,101,150,11,249,51,154,103,104,182,29,213,114,236,71, +117,103,139,2,54,159,26,249,157,45,221,166,176,99,186,223,22,212,83,54,238,118,27,95,217,210,41,80,81,11,200,101,144,189,55, +20,29,25,164,33,54,28,138,174,210,41,54,201,197,24,123,140,139,41,70,126,182,210,177,15,15,135,15,19,55,164,101,116,142,63,47, +174,176,147,184,158,16,142,211,226,58,161,140,30,231,242,60,119,79,179,71,185,190,198,245,117,126,209,216,9,92,231,68,228,128, +146,198,72,217,193,65,58,169,172,174,135,162,223,225,99,159,15,69,7,89,60,209,75,74,146,173,247,6,186,168,235,222,46,214,21,239, +194,239,168,64,128,41,225,39,159,244,191,210,204,158,82,168,150,86,118,163,153,177,155,224,211,17,198,174,130,107,248,37,16, +140,40,74,18,241,191,138,52,198,115,186,217,91,136,123,166,133,177,43,224,21,112,3,220,4,79,183,50,246,121,240,13,240,99,240, +122,43,41,138,226,83,152,114,0,163,221,110,229,189,15,178,43,81,70,215,163,20,111,248,93,196,165,247,110,130,255,38,241,222,79, +248,104,247,29,133,159,118,223,83,112,233,189,171,240,158,83,249,251,10,95,220,29,75,252,198,234,115,159,237,70,160,7,251,92,59, +127,158,96,113,247,89,150,63,179,42,125,238,125,249,251,13,159,140,231,207,5,254,190,221,231,5,254,32,193,199,23,207,33,114, +124,254,46,229,191,60,5,16,96,132,17,0,0,0,0 }; #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ METHOD (getPlaybackInfo, "getPlaybackInfo", "()Landroid/media/session/MediaController$PlaybackInfo;") \ @@ -401,7 +400,7 @@ struct VideoComponent::Pimpl } } - void loadAsync (const URL& url, std::function<void(const URL&, Result)> callback) + void loadAsync (const URL& url, std::function<void (const URL&, Result)> callback) { close(); wasOpen = false; @@ -763,7 +762,7 @@ private: CALLBACK (playbackStateChanged, "mediaControllerPlaybackStateChanged", "(JLandroid/media/session/PlaybackState;)V") \ CALLBACK (sessionDestroyed, "mediaControllerSessionDestroyed", "(J)V") - DECLARE_JNI_CLASS_WITH_BYTECODE (AndroidMediaControllerCallback, "com/roli/juce/MediaControllerCallback", 21, MediaSessionByteCode, sizeof(MediaSessionByteCode)) + DECLARE_JNI_CLASS_WITH_BYTECODE (AndroidMediaControllerCallback, "com/rmsl/juce/MediaControllerCallback", 21, MediaSessionByteCode, sizeof (MediaSessionByteCode)) #undef JNI_CLASS_MEMBERS LocalRef<jobject> createControllerCallbacks() @@ -1302,7 +1301,7 @@ private: CALLBACK (seekToCallback, "mediaSessionSeekTo", "(JJ)V") \ CALLBACK (stopCallback, "mediaSessionStop", "(J)V") - DECLARE_JNI_CLASS_WITH_MIN_SDK (AndroidMediaSessionCallback, "com/roli/juce/MediaSessionCallback", 21) + DECLARE_JNI_CLASS_WITH_MIN_SDK (AndroidMediaSessionCallback, "com/rmsl/juce/MediaSessionCallback", 21) #undef JNI_CLASS_MEMBERS LocalRef<jobject> createCallbackObject() @@ -1692,7 +1691,7 @@ private: METHOD (setEnabled, "setEnabled", "(Z)V") \ CALLBACK (systemVolumeChangedCallback, "mediaSessionSystemVolumeChanged", "(J)V") - DECLARE_JNI_CLASS_WITH_MIN_SDK (SystemVolumeObserver, "com/roli/juce/SystemVolumeObserver", 21) + DECLARE_JNI_CLASS_WITH_MIN_SDK (SystemVolumeObserver, "com/rmsl/juce/SystemVolumeObserver", 21) #undef JNI_CLASS_MEMBERS @@ -1750,7 +1749,7 @@ private: #endif GlobalRef surfaceHolderCallback; - std::function<void(const URL&, Result)> loadFinishedCallback; + std::function<void (const URL&, Result)> loadFinishedCallback; bool wasOpen = false; @@ -1829,7 +1828,7 @@ private: JUCE_VIDEO_LOG ("App resumed, restoring media player..."); - loadAsync (currentURL, [this](const URL&, Result r) + loadAsync (currentURL, [this] (const URL&, Result r) { if (r.wasOk()) mediaSession.restoreState(); diff --git a/modules/juce_video/native/juce_ios_CameraDevice.h b/modules/juce_video/native/juce_ios_CameraDevice.h index 18a881cf..0c086453 100644 --- a/modules/juce_video/native/juce_ios_CameraDevice.h +++ b/modules/juce_video/native/juce_ios_CameraDevice.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -24,9 +23,14 @@ ============================================================================== */ +#if (defined (__IPHONE_10_0) && __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_10_0) + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wdeprecated-declarations") + #define JUCE_DEPRECATION_IGNORED 1 +#endif + struct CameraDevice::Pimpl { - using InternalOpenCameraResultCallback = std::function<void(const String& /*cameraId*/, const String& /*error*/)>; + using InternalOpenCameraResultCallback = std::function<void (const String& /*cameraId*/, const String& /*error*/)>; Pimpl (CameraDevice& ownerToUse, const String& cameraIdToUse, int /*index*/, int /*minWidth*/, int /*minHeight*/, int /*maxWidth*/, int /*maxHeight*/, @@ -75,7 +79,7 @@ struct CameraDevice::Pimpl bool openedOk() const noexcept { return captureSession.openedOk(); } - void takeStillPicture (std::function<void(const Image&)> pictureTakenCallbackToUse) + void takeStillPicture (std::function<void (const Image&)> pictureTakenCallbackToUse) { if (pictureTakenCallbackToUse == nullptr) { @@ -262,31 +266,27 @@ private: videoFrameRateRangesString << frameRateRangeToString (range); JUCE_CAMERA_LOG (videoFrameRateRangesString); - JUCE_CAMERA_LOG ("Video binned: " + String (int(format.videoBinned))); + JUCE_CAMERA_LOG ("Video binned: " + String (int (format.videoBinned))); - #if defined (__IPHONE_8_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_8_0 - if (iosVersion.major >= 8) - { - JUCE_CAMERA_LOG ("Video HDR supported: " + String (int (format.videoHDRSupported))); - JUCE_CAMERA_LOG ("High resolution still image dimensions: " + getHighResStillImgDimensionsString (format.highResolutionStillImageDimensions)); - JUCE_CAMERA_LOG ("Min ISO: " + String (format.minISO)); - JUCE_CAMERA_LOG ("Max ISO: " + String (format.maxISO)); - JUCE_CAMERA_LOG ("Min exposure duration: " + cmTimeToString (format.minExposureDuration)); - - String autoFocusSystemString; - switch (format.autoFocusSystem) - { - case AVCaptureAutoFocusSystemPhaseDetection: autoFocusSystemString = "PhaseDetection"; break; - case AVCaptureAutoFocusSystemContrastDetection: autoFocusSystemString = "ContrastDetection"; break; - default: autoFocusSystemString = "None"; - } - JUCE_CAMERA_LOG ("Auto focus system: " + autoFocusSystemString); + JUCE_CAMERA_LOG ("Video HDR supported: " + String (int (format.videoHDRSupported))); + JUCE_CAMERA_LOG ("High resolution still image dimensions: " + getHighResStillImgDimensionsString (format.highResolutionStillImageDimensions)); + JUCE_CAMERA_LOG ("Min ISO: " + String (format.minISO)); + JUCE_CAMERA_LOG ("Max ISO: " + String (format.maxISO)); + JUCE_CAMERA_LOG ("Min exposure duration: " + cmTimeToString (format.minExposureDuration)); - JUCE_CAMERA_LOG ("Standard (iOS 5.0) video stabilization supported: " + String ((int) [format isVideoStabilizationModeSupported: AVCaptureVideoStabilizationModeStandard])); - JUCE_CAMERA_LOG ("Cinematic video stabilization supported: " + String ((int) [format isVideoStabilizationModeSupported: AVCaptureVideoStabilizationModeCinematic])); - JUCE_CAMERA_LOG ("Auto video stabilization supported: " + String ((int) [format isVideoStabilizationModeSupported: AVCaptureVideoStabilizationModeAuto])); + String autoFocusSystemString; + switch (format.autoFocusSystem) + { + case AVCaptureAutoFocusSystemPhaseDetection: autoFocusSystemString = "PhaseDetection"; break; + case AVCaptureAutoFocusSystemContrastDetection: autoFocusSystemString = "ContrastDetection"; break; + case AVCaptureAutoFocusSystemNone: + default: autoFocusSystemString = "None"; } - #endif + JUCE_CAMERA_LOG ("Auto focus system: " + autoFocusSystemString); + + JUCE_CAMERA_LOG ("Standard (iOS 5.0) video stabilization supported: " + String ((int) [format isVideoStabilizationModeSupported: AVCaptureVideoStabilizationModeStandard])); + JUCE_CAMERA_LOG ("Cinematic video stabilization supported: " + String ((int) [format isVideoStabilizationModeSupported: AVCaptureVideoStabilizationModeCinematic])); + JUCE_CAMERA_LOG ("Auto video stabilization supported: " + String ((int) [format isVideoStabilizationModeSupported: AVCaptureVideoStabilizationModeAuto])); #if defined (__IPHONE_11_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0 if (iosVersion.major >= 11) @@ -338,8 +338,7 @@ private: delegate.reset ([cls.createInstance() init]); SessionDelegateClass::setOwner (delegate.get(), this); - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wundeclared-selector" + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wundeclared-selector") [[NSNotificationCenter defaultCenter] addObserver: delegate.get() selector: @selector (sessionDidStartRunning:) name: AVCaptureSessionDidStartRunningNotification @@ -364,7 +363,7 @@ private: selector: @selector (sessionInterruptionEnded:) name: AVCaptureSessionInterruptionEndedNotification object: captureSession.get()]; - #pragma clang diagnostic pop + JUCE_END_IGNORE_WARNINGS_GCC_LIKE dispatch_async (captureSessionQueue,^ { @@ -525,14 +524,13 @@ private: { SessionDelegateClass() : ObjCClass<NSObject> ("SessionDelegateClass_") { - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wundeclared-selector" + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wundeclared-selector") addMethod (@selector (sessionDidStartRunning:), started, "v@:@"); addMethod (@selector (sessionDidStopRunning:), stopped, "v@:@"); addMethod (@selector (sessionRuntimeError:), runtimeError, "v@:@"); addMethod (@selector (sessionWasInterrupted:), interrupted, "v@:@"); addMethod (@selector (sessionInterruptionEnded:), interruptionEnded, "v@:@"); - #pragma clang diagnostic pop + JUCE_END_IGNORE_WARNINGS_GCC_LIKE addIvar<CaptureSession*> ("owner"); @@ -646,6 +644,8 @@ private: [stillImageOutput captureStillImageAsynchronouslyFromConnection: connection completionHandler: ^(CMSampleBufferRef imageSampleBuffer, NSError* error) { + takingPicture = false; + if (error != nil) { JUCE_CAMERA_LOG ("Still picture capture failed, error: " + nsStringToJuce (error.localizedDescription)); @@ -659,7 +659,7 @@ private: callListeners (image); - MessageManager::callAsync ([this, image]() { notifyPictureTaken (image); }); + MessageManager::callAsync ([this, image] { notifyPictureTaken (image); }); }]; } else @@ -813,6 +813,8 @@ private: static void didFinishProcessingPhoto (id self, SEL, AVCapturePhotoOutput*, AVCapturePhoto* capturePhoto, NSError* error) { + getOwner (self).takingPicture = false; + String errorString = error != nil ? nsStringToJuce (error.localizedDescription) : String(); ignoreUnused (errorString); @@ -869,6 +871,10 @@ private: CGContextScaleCTM (context, targetSize.height / origHeight, -targetSize.width / origWidth); CGContextTranslateCTM (context, -targetSize.width, -targetSize.height); break; + case kCGImagePropertyOrientationUpMirrored: + case kCGImagePropertyOrientationDownMirrored: + case kCGImagePropertyOrientationLeftMirrored: + case kCGImagePropertyOrientationRightMirrored: default: // Not implemented. jassertfalse; @@ -912,6 +918,8 @@ private: AVCaptureResolvedPhotoSettings*, AVCaptureBracketedStillImageSettings*, NSError* error) { + getOwner (self).takingPicture = false; + String errorString = error != nil ? nsStringToJuce (error.localizedDescription) : String(); ignoreUnused (errorString); @@ -963,8 +971,6 @@ private: void notifyPictureTaken (const Image& image) { - takingPicture = false; - captureSession.notifyPictureTaken (image); } @@ -1190,6 +1196,9 @@ private: { const ScopedLock sl (listenerLock); listeners.call ([=] (Listener& l) { l.imageReceived (image); }); + + if (listeners.size() == 1) + triggerStillPictureCapture(); } void notifyPictureTaken (const Image& image) @@ -1214,7 +1223,7 @@ private: CriticalSection listenerLock; ListenerList<Listener> listeners; - std::function<void(const Image&)> pictureTakenCallback; + std::function<void (const Image&)> pictureTakenCallback; CaptureSession captureSession; @@ -1264,7 +1273,7 @@ struct CameraDevice::ViewerComponent : public UIViewComponent private: static void layoutSubviews (id self, SEL) { - sendSuperclassMessage (self, @selector (layoutSubviews)); + sendSuperclassMessage<void> (self, @selector (layoutSubviews)); UIView* asUIView = (UIView*) self; @@ -1329,3 +1338,7 @@ String CameraDevice::getFileExtension() { return ".mov"; } + +#if JUCE_DEPRECATION_IGNORED + JUCE_END_IGNORE_WARNINGS_GCC_LIKE +#endif diff --git a/modules/juce_video/native/juce_mac_CameraDevice.h b/modules/juce_video/native/juce_mac_CameraDevice.h index 9fcfec84..30e69328 100644 --- a/modules/juce_video/native/juce_mac_CameraDevice.h +++ b/modules/juce_video/native/juce_mac_CameraDevice.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -24,112 +23,226 @@ ============================================================================== */ -#if JUCE_CLANG && ! (defined (MAC_OS_X_VERSION_10_16) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_16) - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wdeprecated-declarations" - #define JUCE_DEPRECATION_IGNORED 1 -#endif - struct CameraDevice::Pimpl { - Pimpl (CameraDevice& ownerToUse, const String&, int /*index*/, int /*minWidth*/, int /*minHeight*/, - int /*maxWidth*/, int /*maxHeight*/, bool useHighQuality) - : owner (ownerToUse) + #if defined (MAC_OS_X_VERSION_10_15) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_15 + #define JUCE_USE_NEW_APPLE_CAMERA_API 1 + #else + #define JUCE_USE_NEW_APPLE_CAMERA_API 0 + #endif + + #if JUCE_USE_NEW_APPLE_CAMERA_API + class PostCatalinaPhotoOutput { - JUCE_AUTORELEASEPOOL + public: + PostCatalinaPhotoOutput() { - captureView = [[AVCaptureView alloc] init]; - session = captureView.session; + static PhotoOutputDelegateClass cls; + delegate.reset ([cls.createInstance() init]); + } - session.sessionPreset = useHighQuality ? AVCaptureSessionPresetHigh - : AVCaptureSessionPresetMedium; + void addImageCapture (AVCaptureSession* s) + { + if (imageOutput != nil) + return; - refreshConnections(); + imageOutput = [[AVCapturePhotoOutput alloc] init]; + [s addOutput: imageOutput]; + } - static DelegateClass cls; - callbackDelegate = (id<AVCaptureFileOutputRecordingDelegate>) [cls.createInstance() init]; - DelegateClass::setOwner (callbackDelegate, this); + void removeImageCapture (AVCaptureSession* s) + { + if (imageOutput == nil) + return; - SEL runtimeErrorSel = NSSelectorFromString (nsStringLiteral ("captureSessionRuntimeError:")); + [s removeOutput: imageOutput]; + [imageOutput release]; + imageOutput = nil; + } - [[NSNotificationCenter defaultCenter] addObserver: callbackDelegate - selector: runtimeErrorSel - name: AVCaptureSessionRuntimeErrorNotification - object: session]; + NSArray<AVCaptureConnection*>* getConnections() const + { + if (imageOutput != nil) + return imageOutput.connections; + + return nil; } - } - ~Pimpl() - { - [[NSNotificationCenter defaultCenter] removeObserver: callbackDelegate]; + void triggerImageCapture (Pimpl& p) + { + if (imageOutput == nil) + return; - [session stopRunning]; - removeImageCapture(); - removeMovieCapture(); - [session release]; - [callbackDelegate release]; - } + PhotoOutputDelegateClass::setOwner (delegate.get(), &p); - bool openedOk() const noexcept { return openingError.isEmpty(); } + [imageOutput capturePhotoWithSettings: [AVCapturePhotoSettings photoSettings] + delegate: id<AVCapturePhotoCaptureDelegate> (delegate.get())]; + } - void addImageCapture() + static NSArray* getAvailableDevices() + { + auto* discovery = [AVCaptureDeviceDiscoverySession discoverySessionWithDeviceTypes: @[AVCaptureDeviceTypeBuiltInWideAngleCamera, + AVCaptureDeviceTypeExternalUnknown] + mediaType: AVMediaTypeVideo + position: AVCaptureDevicePositionUnspecified]; + return [discovery devices]; + } + + private: + class PhotoOutputDelegateClass : public ObjCClass<NSObject> + { + public: + PhotoOutputDelegateClass() : ObjCClass<NSObject> ("PhotoOutputDelegateClass_") + { + addMethod (@selector (captureOutput:didFinishProcessingPhoto:error:), didFinishProcessingPhoto, "v@:@@@"); + addIvar<Pimpl*> ("owner"); + registerClass(); + } + + static void didFinishProcessingPhoto (id self, SEL, AVCapturePhotoOutput*, AVCapturePhoto* photo, NSError* error) + { + if (error != nil) + { + String errorString = error != nil ? nsStringToJuce (error.localizedDescription) : String(); + ignoreUnused (errorString); + + JUCE_CAMERA_LOG ("Still picture capture failed, error: " + errorString); + jassertfalse; + + return; + } + + auto* imageData = [photo fileDataRepresentation]; + auto image = ImageFileFormat::loadFrom (imageData.bytes, (size_t) imageData.length); + + getOwner (self).imageCaptureFinished (image); + } + + static Pimpl& getOwner (id self) { return *getIvar<Pimpl*> (self, "owner"); } + static void setOwner (id self, Pimpl* t) { object_setInstanceVariable (self, "owner", t); } + }; + + AVCapturePhotoOutput* imageOutput = nil; + std::unique_ptr<NSObject, NSObjectDeleter> delegate; + }; + #else + struct PreCatalinaStillImageOutput { - if (imageOutput == nil) + public: + void addImageCapture (AVCaptureSession* s) { + if (imageOutput != nil) + return; + + const auto codecType = + #if defined (MAC_OS_X_VERSION_10_13) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_13 + AVVideoCodecTypeJPEG; + #else + AVVideoCodecJPEG; + #endif + imageOutput = [[AVCaptureStillImageOutput alloc] init]; - auto imageSettings = [[NSDictionary alloc] initWithObjectsAndKeys: AVVideoCodecJPEG, AVVideoCodecKey, nil]; + auto imageSettings = [[NSDictionary alloc] initWithObjectsAndKeys: codecType, AVVideoCodecKey, nil]; [imageOutput setOutputSettings: imageSettings]; [imageSettings release]; - [session addOutput: imageOutput]; + [s addOutput: imageOutput]; } - } - void addMovieCapture() - { - if (fileOutput == nil) + void removeImageCapture (AVCaptureSession* s) { - fileOutput = [[AVCaptureMovieFileOutput alloc] init]; - [session addOutput: fileOutput]; - } - } + if (imageOutput == nil) + return; - void removeImageCapture() - { - if (imageOutput != nil) - { - [session removeOutput: imageOutput]; + [s removeOutput: imageOutput]; [imageOutput release]; imageOutput = nil; } - } - void removeMovieCapture() - { - if (fileOutput != nil) + NSArray<AVCaptureConnection*>* getConnections() const { - [session removeOutput: fileOutput]; - [fileOutput release]; - fileOutput = nil; + if (imageOutput != nil) + return imageOutput.connections; + + return nil; } + + void triggerImageCapture (Pimpl& p) + { + if (auto* videoConnection = p.getVideoConnection()) + { + [imageOutput captureStillImageAsynchronouslyFromConnection: videoConnection + completionHandler: ^(CMSampleBufferRef sampleBuffer, NSError* error) + { + if (error != nil) + { + JUCE_CAMERA_LOG ("Still picture capture failed, error: " + nsStringToJuce (error.localizedDescription)); + jassertfalse; + return; + } + + auto* imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation: sampleBuffer]; + auto image = ImageFileFormat::loadFrom (imageData.bytes, (size_t) imageData.length); + p.imageCaptureFinished (image); + }]; + } + } + + static NSArray* getAvailableDevices() + { + return [AVCaptureDevice devicesWithMediaType: AVMediaTypeVideo]; + } + + private: + AVCaptureStillImageOutput* imageOutput = nil; + }; + #endif + + Pimpl (CameraDevice& ownerToUse, const String& deviceNameToUse, int /*index*/, + int /*minWidth*/, int /*minHeight*/, + int /*maxWidth*/, int /*maxHeight*/, + bool useHighQuality) + : owner (ownerToUse), + deviceName (deviceNameToUse) + { + session = [[AVCaptureSession alloc] init]; + + session.sessionPreset = useHighQuality ? AVCaptureSessionPresetHigh + : AVCaptureSessionPresetMedium; + + refreshConnections(); + + static DelegateClass cls; + callbackDelegate = (id<AVCaptureFileOutputRecordingDelegate>) [cls.createInstance() init]; + DelegateClass::setOwner (callbackDelegate, this); + + [[NSNotificationCenter defaultCenter] addObserver: callbackDelegate + selector: DelegateClass::runtimeErrorSel() + name: AVCaptureSessionRuntimeErrorNotification + object: session]; } - void refreshConnections() + ~Pimpl() { - [session beginConfiguration]; + [[NSNotificationCenter defaultCenter] removeObserver: callbackDelegate]; + + [session stopRunning]; + removeInput(); removeImageCapture(); removeMovieCapture(); - addImageCapture(); - addMovieCapture(); - [session commitConfiguration]; + [session release]; + [callbackDelegate release]; } - void refreshIfNeeded() + //============================================================================== + bool openedOk() const noexcept { return openingError.isEmpty(); } + + void startSession() { - if (getVideoConnection() == nullptr) - refreshConnections(); + if (! [session isRunning]) + [session startRunning]; } - void takeStillPicture (std::function<void(const Image&)> pictureTakenCallbackToUse) + void takeStillPicture (std::function<void (const Image&)> pictureTakenCallbackToUse) { if (pictureTakenCallbackToUse == nullptr) { @@ -149,6 +262,7 @@ struct CameraDevice::Pimpl firstPresentationTime = Time::getCurrentTime(); file.deleteFile(); + startSession(); isRecording = true; [fileOutput startRecordingToOutputFileURL: createNSURLFromFile (file) recordingDelegate: callbackDelegate]; @@ -168,59 +282,6 @@ struct CameraDevice::Pimpl return firstPresentationTime; } - AVCaptureConnection* getVideoConnection() const - { - if (imageOutput != nil) - for (AVCaptureConnection* connection in imageOutput.connections) - if ([connection isActive] && [connection isEnabled]) - for (AVCaptureInputPort* port in [connection inputPorts]) - if ([[port mediaType] isEqual: AVMediaTypeVideo]) - return connection; - - return nil; - } - - void handleImageCapture (const Image& image) - { - const ScopedLock sl (listenerLock); - listeners.call ([=] (Listener& l) { l.imageReceived (image); }); - - if (! listeners.isEmpty()) - triggerImageCapture(); - } - - void triggerImageCapture() - { - refreshIfNeeded(); - - if (auto* videoConnection = getVideoConnection()) - { - [imageOutput captureStillImageAsynchronouslyFromConnection: videoConnection - completionHandler: ^(CMSampleBufferRef sampleBuffer, NSError* error) - { - if (error != nil) - { - JUCE_CAMERA_LOG ("Still picture capture failed, error: " + nsStringToJuce (error.localizedDescription)); - jassertfalse; - return; - } - - NSData* imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation: sampleBuffer]; - - auto image = ImageFileFormat::loadFrom (imageData.bytes, (size_t) imageData.length); - - handleImageCapture (image); - - WeakReference<Pimpl> weakRef (this); - MessageManager::callAsync ([weakRef, image]() mutable - { - if (weakRef != nullptr && weakRef->pictureTakenCallback != nullptr) - weakRef->pictureTakenCallback (image); - }); - }]; - } - } - void addListener (CameraDevice::Listener* listenerToAdd) { const ScopedLock sl (listenerLock); @@ -238,36 +299,37 @@ struct CameraDevice::Pimpl static StringArray getAvailableDevices() { + auto* devices = decltype (imageOutput)::getAvailableDevices(); + StringArray results; - results.add ("default"); + + for (AVCaptureDevice* device : devices) + results.add (nsStringToJuce ([device localizedName])); + return results; } - void cameraSessionRuntimeError (const String& error) + AVCaptureSession* getCaptureSession() { - JUCE_CAMERA_LOG ("cameraSessionRuntimeError(), error = " + error); - - if (owner.onErrorOccurred != nullptr) - owner.onErrorOccurred (error); + return session; } - CameraDevice& owner; - AVCaptureView* captureView = nil; - AVCaptureSession* session = nil; - AVCaptureMovieFileOutput* fileOutput = nil; - AVCaptureStillImageOutput* imageOutput = nil; - - id<AVCaptureFileOutputRecordingDelegate> callbackDelegate = nil; - String openingError; - Time firstPresentationTime; - bool isRecording = false; - - CriticalSection listenerLock; - ListenerList<Listener> listeners; - - std::function<void(const Image&)> pictureTakenCallback; + NSView* createVideoCapturePreview() + { + // The video preview must be created before the capture session is + // started. Make sure you haven't called `addListener`, + // `startRecordingToFile`, or `takeStillPicture` before calling this + // function. + jassert (! [session isRunning]); + startSession(); - JUCE_DECLARE_WEAK_REFERENCEABLE (Pimpl) + JUCE_AUTORELEASEPOOL + { + NSView* view = [[NSView alloc] init]; + [view setLayer: [AVCaptureVideoPreviewLayer layerWithSession: getCaptureSession()]]; + return view; + } + } private: //============================================================================== @@ -283,8 +345,7 @@ private: addMethod (@selector (captureOutput:didResumeRecordingToOutputFileAtURL: fromConnections:), didResumeRecordingToOutputFileAtURL, "v@:@@@"); addMethod (@selector (captureOutput:willFinishRecordingToOutputFileAtURL:fromConnections:error:), willFinishRecordingToOutputFileAtURL, "v@:@@@@"); - SEL runtimeErrorSel = NSSelectorFromString (nsStringLiteral ("captureSessionRuntimeError:")); - addMethod (runtimeErrorSel, sessionRuntimeError, "v@:@"); + addMethod (runtimeErrorSel(), sessionRuntimeError, "v@:@"); registerClass(); } @@ -292,6 +353,8 @@ private: static void setOwner (id self, Pimpl* owner) { object_setInstanceVariable (self, "owner", owner); } static Pimpl& getOwner (id self) { return *getIvar<Pimpl*> (self, "owner"); } + static SEL runtimeErrorSel() { return NSSelectorFromString (nsStringLiteral ("captureSessionRuntimeError:")); } + private: static void didStartRecordingToOutputFileAtURL (id, SEL, AVCaptureFileOutput*, NSURL*, NSArray*) {} static void didPauseRecordingToOutputFileAtURL (id, SEL, AVCaptureFileOutput*, NSURL*, NSArray*) {} @@ -308,18 +371,198 @@ private: } }; - JUCE_DECLARE_NON_COPYABLE (Pimpl) + //============================================================================== + void addImageCapture() + { + imageOutput.addImageCapture (session); + } + + void addMovieCapture() + { + if (fileOutput == nil) + { + fileOutput = [[AVCaptureMovieFileOutput alloc] init]; + [session addOutput: fileOutput]; + } + } + + void removeImageCapture() + { + imageOutput.removeImageCapture (session); + } + + void removeMovieCapture() + { + if (fileOutput != nil) + { + [session removeOutput: fileOutput]; + [fileOutput release]; + fileOutput = nil; + } + } + + void removeCurrentSessionVideoInputs() + { + if (session != nil) + { + NSArray<AVCaptureDeviceInput*>* inputs = session.inputs; + + for (AVCaptureDeviceInput* input : inputs) + if ([input.device hasMediaType: AVMediaTypeVideo]) + [session removeInput:input]; + } + } + + void addInput() + { + if (currentInput == nil) + { + auto* availableDevices = decltype (imageOutput)::getAvailableDevices(); + + for (AVCaptureDevice* device : availableDevices) + { + if (deviceName == nsStringToJuce ([device localizedName])) + { + removeCurrentSessionVideoInputs(); + + NSError* err = nil; + AVCaptureDeviceInput* inputDevice = [[AVCaptureDeviceInput alloc] initWithDevice: device + error: &err]; + + jassert (err == nil); + + if ([session canAddInput: inputDevice]) + { + [session addInput: inputDevice]; + currentInput = inputDevice; + } + else + { + jassertfalse; + [inputDevice release]; + } + + return; + } + } + } + } + + void removeInput() + { + if (currentInput != nil) + { + [session removeInput: currentInput]; + [currentInput release]; + currentInput = nil; + } + } + + void refreshConnections() + { + [session beginConfiguration]; + removeInput(); + removeImageCapture(); + removeMovieCapture(); + addInput(); + addImageCapture(); + addMovieCapture(); + [session commitConfiguration]; + } + + void refreshIfNeeded() + { + if (getVideoConnection() == nullptr) + refreshConnections(); + } + + AVCaptureConnection* getVideoConnection() const + { + auto* connections = imageOutput.getConnections(); + + if (connections != nil) + for (AVCaptureConnection* connection in connections) + if ([connection isActive] && [connection isEnabled]) + for (AVCaptureInputPort* port in [connection inputPorts]) + if ([[port mediaType] isEqual: AVMediaTypeVideo]) + return connection; + + return nil; + } + + void imageCaptureFinished (const Image& image) + { + handleImageCapture (image); + + WeakReference<Pimpl> weakRef (this); + MessageManager::callAsync ([weakRef, image]() mutable + { + if (weakRef != nullptr && weakRef->pictureTakenCallback != nullptr) + weakRef->pictureTakenCallback (image); + }); + } + + void handleImageCapture (const Image& image) + { + const ScopedLock sl (listenerLock); + listeners.call ([=] (Listener& l) { l.imageReceived (image); }); + + if (! listeners.isEmpty()) + triggerImageCapture(); + } + + void triggerImageCapture() + { + refreshIfNeeded(); + + startSession(); + + if (auto* videoConnection = getVideoConnection()) + imageOutput.triggerImageCapture (*this); + } + + void cameraSessionRuntimeError (const String& error) + { + JUCE_CAMERA_LOG ("cameraSessionRuntimeError(), error = " + error); + + if (owner.onErrorOccurred != nullptr) + owner.onErrorOccurred (error); + } + + //============================================================================== + CameraDevice& owner; + String deviceName; + + AVCaptureSession* session = nil; + AVCaptureMovieFileOutput* fileOutput = nil; + #if JUCE_USE_NEW_APPLE_CAMERA_API + PostCatalinaPhotoOutput imageOutput; + #else + PreCatalinaStillImageOutput imageOutput; + #endif + AVCaptureDeviceInput* currentInput = nil; + + id<AVCaptureFileOutputRecordingDelegate> callbackDelegate = nil; + String openingError; + Time firstPresentationTime; + bool isRecording = false; + + CriticalSection listenerLock; + ListenerList<Listener> listeners; + + std::function<void (const Image&)> pictureTakenCallback = nullptr; + + //============================================================================== + JUCE_DECLARE_WEAK_REFERENCEABLE (Pimpl) + JUCE_DECLARE_NON_COPYABLE (Pimpl) }; +//============================================================================== struct CameraDevice::ViewerComponent : public NSViewComponent { - ViewerComponent (CameraDevice& d) + ViewerComponent (CameraDevice& device) { - JUCE_AUTORELEASEPOOL - { - setSize (640, 480); - setView (d.pimpl->captureView); - } + setView (device.pimpl->createVideoCapturePreview()); } ~ViewerComponent() @@ -335,7 +578,4 @@ String CameraDevice::getFileExtension() return ".mov"; } -#if JUCE_DEPRECATION_IGNORED - #pragma clang diagnostic pop - #undef JUCE_DEPRECATION_IGNORED -#endif +#undef JUCE_USE_NEW_APPLE_CAMERA_API diff --git a/modules/juce_video/native/juce_mac_Video.h b/modules/juce_video/native/juce_mac_Video.h index 0d2d771e..9e82bd5b 100644 --- a/modules/juce_video/native/juce_mac_Video.h +++ b/modules/juce_video/native/juce_mac_Video.h @@ -2,22 +2,23 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2018 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy - ------------------------------------------------------------------------------ + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -82,7 +83,7 @@ struct VideoComponent::Pimpl : public Base return Result::fail ("Couldn't open movie"); } - void loadAsync (const URL& url, std::function<void(const URL&, Result)> callback) + void loadAsync (const URL& url, std::function<void (const URL&, Result)> callback) { if (url.isEmpty()) { @@ -204,10 +205,9 @@ private: { JucePlayerStatusObserverClass() : ObjCClass<NSObject> ("JucePlayerStatusObserverClass_") { - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wundeclared-selector" + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wundeclared-selector") addMethod (@selector (observeValueForKeyPath:ofObject:change:context:), valueChanged, "v@:@@@?"); - #pragma clang diagnostic pop + JUCE_END_IGNORE_WARNINGS_GCC_LIKE addIvar<PlayerAsyncInitialiser*> ("owner"); @@ -249,10 +249,9 @@ private: { JucePlayerItemPlaybackStatusObserverClass() : ObjCClass<NSObject> ("JucePlayerItemPlaybackStatusObserverClass_") { - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wundeclared-selector" + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wundeclared-selector") addMethod (@selector (processNotification:), notificationReceived, "v@:@"); - #pragma clang diagnostic pop + JUCE_END_IGNORE_WARNINGS_GCC_LIKE addIvar<PlayerControllerBase*> ("owner"); @@ -305,10 +304,9 @@ private: { JucePlayerItemPreparationStatusObserverClass() : ObjCClass<NSObject> ("JucePlayerItemStatusObserverClass_") { - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wundeclared-selector" + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wundeclared-selector") addMethod (@selector (observeValueForKeyPath:ofObject:change:context:), valueChanged, "v@:@@@?"); - #pragma clang diagnostic pop + JUCE_END_IGNORE_WARNINGS_GCC_LIKE addIvar<PlayerAsyncInitialiser*> ("owner"); @@ -348,7 +346,7 @@ private: } else if (newStatus == AVPlayerItemStatusReadyToPlay) { - owner.notifyOwnerPreparationFinished (url, Result::ok(), owner.player.release()); + owner.notifyOwnerPreparationFinished (url, Result::ok(), owner.player.get()); } else { @@ -394,8 +392,11 @@ private: notifyOwnerPreparationFinished (url, Result::fail (errorMessage), nullptr); return; } + + case AVKeyValueStatusUnknown: + case AVKeyValueStatusLoading: default: - {} + break; } } @@ -499,21 +500,19 @@ private: void attachPlaybackObserver() { - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wundeclared-selector" + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wundeclared-selector") [[NSNotificationCenter defaultCenter] addObserver: playerItemPlaybackStatusObserver.get() selector: @selector (processNotification:) name: AVPlayerItemDidPlayToEndTimeNotification object: [crtp().getPlayer() currentItem]]; - #pragma clang diagnostic pop + JUCE_END_IGNORE_WARNINGS_GCC_LIKE } void detachPlaybackObserver() { - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wundeclared-selector" + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wundeclared-selector") [[NSNotificationCenter defaultCenter] removeObserver: playerItemPlaybackStatusObserver.get()]; - #pragma clang diagnostic pop + JUCE_END_IGNORE_WARNINGS_GCC_LIKE } private: @@ -745,7 +744,7 @@ private: private: static void layoutSubviews (id self, SEL) { - sendSuperclassMessage (self, @selector (layoutSubviews)); + sendSuperclassMessage<void> (self, @selector (layoutSubviews)); UIView* asUIView = (UIView*) self; @@ -778,7 +777,7 @@ private: PlayerController playerController; - std::function<void(const URL&, Result)> loadFinishedCallback; + std::function<void (const URL&, Result)> loadFinishedCallback; double playSpeedMult = 1.0; diff --git a/modules/juce_video/native/juce_win32_CameraDevice.h b/modules/juce_video/native/juce_win32_CameraDevice.h index 28b0d47a..fac85c80 100644 --- a/modules/juce_video/native/juce_win32_CameraDevice.h +++ b/modules/juce_video/native/juce_win32_CameraDevice.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -70,8 +69,8 @@ struct CameraDevice::Pimpl : public ChangeBroadcaster if (FAILED (hr)) return; - hr = graphBuilder.QueryInterface (mediaControl); - if (FAILED (hr)) + mediaControl = graphBuilder.getInterface<IMediaControl>(); + if (mediaControl == nullptr) return; { @@ -114,7 +113,7 @@ struct CameraDevice::Pimpl : public ChangeBroadcaster return; { - AM_MEDIA_TYPE mt = { 0 }; + AM_MEDIA_TYPE mt = {}; mt.majortype = MEDIATYPE_Video; mt.subtype = MEDIASUBTYPE_RGB24; mt.formattype = FORMAT_VideoInfo; @@ -138,7 +137,7 @@ struct CameraDevice::Pimpl : public ChangeBroadcaster if (FAILED (hr)) return; - AM_MEDIA_TYPE mt = { 0 }; + AM_MEDIA_TYPE mt = {}; hr = sampleGrabber->GetConnectedMediaType (&mt); VIDEOINFOHEADER* pVih = (VIDEOINFOHEADER*) (mt.pbFormat); width = pVih->bmiHeader.biWidth; @@ -185,7 +184,7 @@ struct CameraDevice::Pimpl : public ChangeBroadcaster bool openedOk() const noexcept { return openedSuccessfully; } - void takeStillPicture (std::function<void(const Image&)> pictureTakenCallbackToUse) + void takeStillPicture (std::function<void (const Image&)> pictureTakenCallbackToUse) { { const ScopedLock sl (pictureTakenCallbackLock); @@ -293,13 +292,10 @@ struct CameraDevice::Pimpl : public ChangeBroadcaster ComSmartPtr<IPin> pin; if (getPin (filter, PINDIR_OUTPUT, pin)) { - ComSmartPtr<IAMPushSource> pushSource; - HRESULT hr = pin.QueryInterface (pushSource); - - if (pushSource != nullptr) + if (auto pushSource = pin.getInterface<IAMPushSource>()) { REFERENCE_TIME latency = 0; - hr = pushSource->GetLatency (&latency); + pushSource->GetLatency (&latency); firstRecordedTime = firstRecordedTime - RelativeTime ((double) latency); } @@ -365,10 +361,7 @@ struct CameraDevice::Pimpl : public ChangeBroadcaster if (SUCCEEDED (hr)) { - ComSmartPtr<IFileSinkFilter> fileSink; - hr = asfWriter.QueryInterface (fileSink); - - if (SUCCEEDED (hr)) + if (auto fileSink = asfWriter.getInterface<IFileSinkFilter>()) { hr = fileSink->SetFileName (file.getFullPathName().toWideCharPointer(), 0); @@ -378,62 +371,63 @@ struct CameraDevice::Pimpl : public ChangeBroadcaster if (SUCCEEDED (hr)) { - ComSmartPtr<IConfigAsfWriter> asfConfig; - hr = asfWriter.QueryInterface (asfConfig); - asfConfig->SetIndexMode (true); - ComSmartPtr<IWMProfileManager> profileManager; - hr = WMCreateProfileManager (profileManager.resetAndGetPointerAddress()); - - // This gibberish is the DirectShow profile for a video-only wmv file. - String prof ("<profile version=\"589824\" storageformat=\"1\" name=\"Quality\" description=\"Quality type for output.\">" - "<streamconfig majortype=\"{73646976-0000-0010-8000-00AA00389B71}\" streamnumber=\"1\" " - "streamname=\"Video Stream\" inputname=\"Video409\" bitrate=\"894960\" " - "bufferwindow=\"0\" reliabletransport=\"1\" decodercomplexity=\"AU\" rfc1766langid=\"en-us\">" - "<videomediaprops maxkeyframespacing=\"50000000\" quality=\"90\"/>" - "<wmmediatype subtype=\"{33564D57-0000-0010-8000-00AA00389B71}\" bfixedsizesamples=\"0\" " - "btemporalcompression=\"1\" lsamplesize=\"0\">" - "<videoinfoheader dwbitrate=\"894960\" dwbiterrorrate=\"0\" avgtimeperframe=\"$AVGTIMEPERFRAME\">" - "<rcsource left=\"0\" top=\"0\" right=\"$WIDTH\" bottom=\"$HEIGHT\"/>" - "<rctarget left=\"0\" top=\"0\" right=\"$WIDTH\" bottom=\"$HEIGHT\"/>" - "<bitmapinfoheader biwidth=\"$WIDTH\" biheight=\"$HEIGHT\" biplanes=\"1\" bibitcount=\"24\" " - "bicompression=\"WMV3\" bisizeimage=\"0\" bixpelspermeter=\"0\" biypelspermeter=\"0\" " - "biclrused=\"0\" biclrimportant=\"0\"/>" - "</videoinfoheader>" - "</wmmediatype>" - "</streamconfig>" - "</profile>"); - - const int fps[] = { 10, 15, 30 }; - int maxFramesPerSecond = fps [jlimit (0, numElementsInArray (fps) - 1, quality & 0xff)]; - - if ((quality & 0xff000000) != 0) // (internal hacky way to pass explicit frame rates for testing) - maxFramesPerSecond = (quality >> 24) & 0xff; - - prof = prof.replace ("$WIDTH", String (width)) - .replace ("$HEIGHT", String (height)) - .replace ("$AVGTIMEPERFRAME", String (10000000 / maxFramesPerSecond)); - - ComSmartPtr<IWMProfile> currentProfile; - hr = profileManager->LoadProfileByData (prof.toWideCharPointer(), currentProfile.resetAndGetPointerAddress()); - hr = asfConfig->ConfigureFilterUsingProfile (currentProfile); - - if (SUCCEEDED (hr)) + if (auto asfConfig = asfWriter.getInterface<IConfigAsfWriter>()) { - ComSmartPtr<IPin> asfWriterInputPin; + asfConfig->SetIndexMode (true); + ComSmartPtr<IWMProfileManager> profileManager; + hr = WMCreateProfileManager (profileManager.resetAndGetPointerAddress()); + + // This gibberish is the DirectShow profile for a video-only wmv file. + String prof ("<profile version=\"589824\" storageformat=\"1\" name=\"Quality\" description=\"Quality type for output.\">" + "<streamconfig majortype=\"{73646976-0000-0010-8000-00AA00389B71}\" streamnumber=\"1\" " + "streamname=\"Video Stream\" inputname=\"Video409\" bitrate=\"894960\" " + "bufferwindow=\"0\" reliabletransport=\"1\" decodercomplexity=\"AU\" rfc1766langid=\"en-us\">" + "<videomediaprops maxkeyframespacing=\"50000000\" quality=\"90\"/>" + "<wmmediatype subtype=\"{33564D57-0000-0010-8000-00AA00389B71}\" bfixedsizesamples=\"0\" " + "btemporalcompression=\"1\" lsamplesize=\"0\">" + "<videoinfoheader dwbitrate=\"894960\" dwbiterrorrate=\"0\" avgtimeperframe=\"$AVGTIMEPERFRAME\">" + "<rcsource left=\"0\" top=\"0\" right=\"$WIDTH\" bottom=\"$HEIGHT\"/>" + "<rctarget left=\"0\" top=\"0\" right=\"$WIDTH\" bottom=\"$HEIGHT\"/>" + "<bitmapinfoheader biwidth=\"$WIDTH\" biheight=\"$HEIGHT\" biplanes=\"1\" bibitcount=\"24\" " + "bicompression=\"WMV3\" bisizeimage=\"0\" bixpelspermeter=\"0\" biypelspermeter=\"0\" " + "biclrused=\"0\" biclrimportant=\"0\"/>" + "</videoinfoheader>" + "</wmmediatype>" + "</streamconfig>" + "</profile>"); + + const int fps[] = { 10, 15, 30 }; + int maxFramesPerSecond = fps[jlimit (0, numElementsInArray (fps) - 1, quality & 0xff)]; + + if ((quality & 0xff000000) != 0) // (internal hacky way to pass explicit frame rates for testing) + maxFramesPerSecond = (quality >> 24) & 0xff; + + prof = prof.replace ("$WIDTH", String (width)) + .replace ("$HEIGHT", String (height)) + .replace ("$AVGTIMEPERFRAME", String (10000000 / maxFramesPerSecond)); + + ComSmartPtr<IWMProfile> currentProfile; + hr = profileManager->LoadProfileByData (prof.toWideCharPointer(), currentProfile.resetAndGetPointerAddress()); + hr = asfConfig->ConfigureFilterUsingProfile (currentProfile); - if (getPin (asfWriter, PINDIR_INPUT, asfWriterInputPin, "Video Input 01")) + if (SUCCEEDED (hr)) { - hr = graphBuilder->Connect (smartTeeCaptureOutputPin, asfWriterInputPin); + ComSmartPtr<IPin> asfWriterInputPin; - if (SUCCEEDED (hr) && openedSuccessfully && activeUsers > 0 - && SUCCEEDED (mediaControl->Run())) + if (getPin (asfWriter, PINDIR_INPUT, asfWriterInputPin, "Video Input 01")) { - previewMaxFPS = (quality < 2) ? 15 : 25; // throttle back the preview comps to try to leave the cpu free for encoding + hr = graphBuilder->Connect (smartTeeCaptureOutputPin, asfWriterInputPin); + + if (SUCCEEDED (hr) && openedSuccessfully && activeUsers > 0 + && SUCCEEDED (mediaControl->Run())) + { + previewMaxFPS = (quality < 2) ? 15 : 25; // throttle back the preview comps to try to leave the cpu free for encoding - if ((quality & 0x00ff0000) != 0) // (internal hacky way to pass explicit frame rates for testing) - previewMaxFPS = (quality >> 16) & 0xff; + if ((quality & 0x00ff0000) != 0) // (internal hacky way to pass explicit frame rates for testing) + previewMaxFPS = (quality >> 16) & 0xff; - return true; + return true; + } } } } @@ -559,7 +553,7 @@ struct CameraDevice::Pimpl : public ChangeBroadcaster ListenerList<Listener> listeners; CriticalSection pictureTakenCallbackLock; - std::function<void(const Image&)> pictureTakenCallback; + std::function<void (const Image&)> pictureTakenCallback; bool isRecording = false, openedSuccessfully = false; int width = 0, height = 0; @@ -695,7 +689,7 @@ private: if (wantedDirection == dir) { - PIN_INFO info = { 0 }; + PIN_INFO info = {}; pin->QueryPinInfo (&info); if (pinName == nullptr || String (pinName).equalsIgnoreCase (String (info.achName))) diff --git a/modules/juce_video/native/juce_win32_Video.h b/modules/juce_video/native/juce_win32_Video.h index b162ba29..fab72585 100644 --- a/modules/juce_video/native/juce_win32_Video.h +++ b/modules/juce_video/native/juce_win32_Video.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -855,10 +854,10 @@ private: HINSTANCE moduleHandle = (HINSTANCE) Process::getCurrentModuleInstanceHandle(); - TCHAR moduleFile [1024] = { 0 }; + TCHAR moduleFile [1024] = {}; GetModuleFileName (moduleHandle, moduleFile, 1024); - WNDCLASSEX wcex = { 0 }; + WNDCLASSEX wcex = {}; wcex.cbSize = sizeof (wcex); wcex.style = CS_OWNDC; wcex.lpfnWndProc = (WNDPROC) wndProc; diff --git a/modules/juce_video/playback/juce_VideoComponent.cpp b/modules/juce_video/playback/juce_VideoComponent.cpp index 8d01e1b5..39065938 100644 --- a/modules/juce_video/playback/juce_VideoComponent.cpp +++ b/modules/juce_video/playback/juce_VideoComponent.cpp @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -59,7 +58,7 @@ Result VideoComponent::load (const URL& url) return loadInternal (url, false); } -void VideoComponent::loadAsync (const URL& url, std::function<void(const URL&, Result)> callback) +void VideoComponent::loadAsync (const URL& url, std::function<void (const URL&, Result)> callback) { if (callback == nullptr) { diff --git a/modules/juce_video/playback/juce_VideoComponent.h b/modules/juce_video/playback/juce_VideoComponent.h index 99f0a147..d325aa17 100644 --- a/modules/juce_video/playback/juce_VideoComponent.h +++ b/modules/juce_video/playback/juce_VideoComponent.h @@ -2,17 +2,16 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). + By using JUCE, you agree to the terms of both the JUCE 6 End-User License + Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy + End User License Agreement: www.juce.com/juce-6-licence + Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). @@ -93,7 +92,7 @@ public: @see load */ - void loadAsync (const URL& url, std::function<void(const URL&, Result)> loadFinishedCallback); + void loadAsync (const URL& url, std::function<void (const URL&, Result)> loadFinishedCallback); /** Closes the video and resets the component. */ void closeVideo(); @@ -169,7 +168,7 @@ public: /** Set this callback to be notified whenever an error occurs. Upon error, you may need to load the video again. */ - std::function<void(const String& /*error*/)> onErrorOccurred; + std::function<void (const String& /*error*/)> onErrorOccurred; private: //============================================================================== -- 2.30.2

;6r*{C_+>IW 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 F{|5))HK70i literal 0 HcmV?d00001 diff --git a/examples/Audio/AudioAppDemo.h b/examples/Audio/AudioAppDemo.h index fa3eb203..17dfcb22 100644 --- a/examples/Audio/AudioAppDemo.h +++ b/examples/Audio/AudioAppDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -114,7 +114,7 @@ public: // (Our component is opaque, so we must completely fill the background with a solid colour) g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId)); - auto centreY = getHeight() / 2.0f; + auto centreY = (float) getHeight() / 2.0f; auto radius = amplitude * 200.0f; if (radius >= 0.0f) @@ -131,8 +131,8 @@ public: Path wavePath; wavePath.startNewSubPath (0, centreY); - for (auto x = 1.0f; x < getWidth(); ++x) - wavePath.lineTo (x, centreY + amplitude * getHeight() * 2.0f + for (auto x = 1.0f; x < (float) getWidth(); ++x) + wavePath.lineTo (x, centreY + amplitude * (float) getHeight() * 2.0f * std::sin (x * frequency * 0.0001f)); g.setColour (getLookAndFeel().findColour (Slider::thumbColourId)); @@ -149,8 +149,8 @@ public: { lastMousePosition = e.position; - frequency = (getHeight() - e.y) * 10.0f; - amplitude = jmin (0.9f, 0.2f * e.position.x / getWidth()); + frequency = (float) (getHeight() - e.y) * 10.0f; + amplitude = jmin (0.9f, 0.2f * e.position.x / (float) getWidth()); phaseDelta = (float) (MathConstants::twoPi * frequency / sampleRate); diff --git a/examples/Audio/AudioLatencyDemo.h b/examples/Audio/AudioLatencyDemo.h index b7e16ea6..8e7e4e7c 100644 --- a/examples/Audio/AudioLatencyDemo.h +++ b/examples/Audio/AudioLatencyDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 diff --git a/examples/Audio/AudioPlaybackDemo.h b/examples/Audio/AudioPlaybackDemo.h index 33d48f36..8837cea5 100644 --- a/examples/Audio/AudioPlaybackDemo.h +++ b/examples/Audio/AudioPlaybackDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -116,7 +116,7 @@ public: if (thumbnail.getTotalLength() > 0) { auto newScale = jmax (0.001, thumbnail.getTotalLength() * (1.0 - jlimit (0.0, 0.99, amount))); - auto timeAtCentre = xToTime (getWidth() / 2.0f); + auto timeAtCentre = xToTime ((float) getWidth() / 2.0f); setRange ({ timeAtCentre - newScale * 0.5, timeAtCentre + newScale * 0.5 }); } @@ -229,12 +229,12 @@ private: if (visibleRange.getLength() <= 0) return 0; - return getWidth() * (float) ((time - visibleRange.getStart()) / visibleRange.getLength()); + return (float) getWidth() * (float) ((time - visibleRange.getStart()) / visibleRange.getLength()); } double xToTime (const float x) const { - return (x / getWidth()) * (visibleRange.getLength()) + visibleRange.getStart(); + return (x / (float) getWidth()) * (visibleRange.getLength()) + visibleRange.getStart(); } bool canMoveTransport() const noexcept diff --git a/examples/Audio/AudioRecordingDemo.h b/examples/Audio/AudioRecordingDemo.h index ceaecba3..b6265c74 100644 --- a/examples/Audio/AudioRecordingDemo.h +++ b/examples/Audio/AudioRecordingDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -348,7 +348,7 @@ private: { recorder.stop(); - #if (JUCE_ANDROID || JUCE_IOS) + #if JUCE_CONTENT_SHARING SafePointer safeThis (this); File fileToShare = lastRecording; diff --git a/examples/Audio/AudioSettingsDemo.h b/examples/Audio/AudioSettingsDemo.h index 9bd5f330..8c587b92 100644 --- a/examples/Audio/AudioSettingsDemo.h +++ b/examples/Audio/AudioSettingsDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 diff --git a/examples/Audio/AudioSynthesiserDemo.h b/examples/Audio/AudioSynthesiserDemo.h index 644f061f..30040997 100644 --- a/examples/Audio/AudioSynthesiserDemo.h +++ b/examples/Audio/AudioSynthesiserDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -182,7 +182,7 @@ struct SynthAudioSource : public AudioSource { WavAudioFormat wavFormat; - std::unique_ptr audioReader (wavFormat.createReaderFor (createAssetInputStream ("cello.wav"), true)); + std::unique_ptr audioReader (wavFormat.createReaderFor (createAssetInputStream ("cello.wav").release(), true)); BigInteger allNotes; allNotes.setRange (0, 128, true); diff --git a/examples/Audio/CMakeLists.txt b/examples/Audio/CMakeLists.txt new file mode 100644 index 00000000..272e8475 --- /dev/null +++ b/examples/Audio/CMakeLists.txt @@ -0,0 +1,24 @@ +# ============================================================================== +# +# This file is part of the JUCE library. +# Copyright (c) 2020 - Raw Material Software Limited +# +# JUCE is an open source library subject to commercial or open-source +# licensing. +# +# By using JUCE, you agree to the terms of both the JUCE 6 End-User License +# Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). +# +# End User License Agreement: www.juce.com/juce-6-licence +# Privacy Policy: www.juce.com/juce-privacy-policy +# +# Or: You may also use this code under the terms of the GPL v3 (see +# www.gnu.org/licenses). +# +# JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER +# EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE +# DISCLAIMED. +# +# ============================================================================== + +_juce_add_pips() diff --git a/examples/Audio/MPEDemo.h b/examples/Audio/MPEDemo.h index 0987328d..1962e56b 100644 --- a/examples/Audio/MPEDemo.h +++ b/examples/Audio/MPEDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -209,7 +209,7 @@ public: auto noteDistance = float (getWidth()) / 128; for (auto i = 0; i < 128; ++i) { - auto x = noteDistance * i; + auto x = noteDistance * (float) i; auto noteHeight = int (MidiMessage::isMidiNoteBlack (i) ? 0.7 * getHeight() : getHeight()); g.setColour (MidiMessage::isMidiNoteBlack (i) ? Colours::white : Colours::grey); @@ -302,8 +302,8 @@ private: Point getCentrePositionForNote (MPENote note) const { auto n = float (note.initialNote) + float (note.totalPitchbendInSemitones); - auto x = getWidth() * n / 128; - auto y = getHeight() * (1 - note.timbre.asUnsignedFloat()); + auto x = (float) getWidth() * n / 128; + auto y = (float) getHeight() * (1 - note.timbre.asUnsignedFloat()); return { x, y }; } @@ -656,8 +656,8 @@ private: auto xPos = zone.isLowerZone() ? 0 : zone.getLastMemberChannel() - 1; - Rectangle zoneRect { int (channelWidth * (xPos)), 20, - int (channelWidth * (zone.numMemberChannels + 1)), getHeight() - 20 }; + Rectangle zoneRect { int (channelWidth * (float) xPos), 20, + int (channelWidth * (float) (zone.numMemberChannels + 1)), getHeight() - 20 }; g.setColour (zoneColour); g.drawRect (zoneRect, 3); @@ -680,8 +680,8 @@ private: auto numChannels = legacyModeChannelRange.getEnd() - startChannel - 1; - Rectangle zoneRect (int (getChannelRectangleWidth() * startChannel), 0, - int (getChannelRectangleWidth() * numChannels), getHeight()); + Rectangle zoneRect (int (getChannelRectangleWidth() * (float) startChannel), 0, + int (getChannelRectangleWidth() * (float) numChannels), getHeight()); zoneRect.removeFromTop (20); @@ -694,7 +694,7 @@ private: //============================================================================== float getChannelRectangleWidth() const noexcept { - return float (getWidth()) / numMidiChannels; + return (float) getWidth() / (float) numMidiChannels; } //============================================================================== diff --git a/examples/Audio/MidiDemo.h b/examples/Audio/MidiDemo.h index b871fd55..5581d1f2 100644 --- a/examples/Audio/MidiDemo.h +++ b/examples/Audio/MidiDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -65,7 +65,7 @@ struct MidiDeviceListEntry : ReferenceCountedObject //============================================================================== class MidiDemo : public Component, private Timer, - private MidiKeyboardStateListener, + private MidiKeyboardState::Listener, private MidiInputCallback, private AsyncUpdater { @@ -273,7 +273,7 @@ private: g.setColour (textColour); - g.setFont (height * 0.7f); + g.setFont ((float) height * 0.7f); if (isInput) { diff --git a/examples/Audio/PluckedStringsDemo.h b/examples/Audio/PluckedStringsDemo.h index 00349109..11ec4c1f 100644 --- a/examples/Audio/PluckedStringsDemo.h +++ b/examples/Audio/PluckedStringsDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -201,11 +201,11 @@ public: Path generateStringPath() const { - auto y = height / 2.0f; + auto y = (float) height / 2.0f; Path stringPath; stringPath.startNewSubPath (0, y); - stringPath.quadraticTo (length / 2.0f, y + (std::sin (phase) * amplitude), (float) length, y); + stringPath.quadraticTo ((float) length / 2.0f, y + (std::sin (phase) * amplitude), (float) length, y); return stringPath; } @@ -227,7 +227,7 @@ public: { // this determines the visible vibration frequency. // just an arbitrary number chosen to look OK: - auto phaseStep = 400.0f / length; + auto phaseStep = 400.0f / (float) length; phase += phaseStep; @@ -337,7 +337,7 @@ private: if (stringLine->getBounds().contains (e.getPosition())) { - auto position = (e.position.x - stringLine->getX()) / stringLine->getWidth(); + auto position = (e.position.x - (float) stringLine->getX()) / (float) stringLine->getWidth(); stringLine->stringPlucked (position); stringSynths.getUnchecked (i)->stringPlucked (position); diff --git a/examples/Audio/SimpleFFTDemo.h b/examples/Audio/SimpleFFTDemo.h index 81609017..fdc4c256 100644 --- a/examples/Audio/SimpleFFTDemo.h +++ b/examples/Audio/SimpleFFTDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -162,7 +162,7 @@ public: for (auto y = 1; y < imageHeight; ++y) { - auto skewedProportionY = 1.0f - std::exp (std::log (y / (float) imageHeight) * 0.2f); + auto skewedProportionY = 1.0f - std::exp (std::log ((float) y / (float) imageHeight) * 0.2f); auto fftDataIndex = jlimit (0, fftSize / 2, (int) (skewedProportionY * (int) fftSize / 2)); auto level = jmap (fftData[fftDataIndex], 0.0f, jmax (maxLevel.getEnd(), 1e-5f), 0.0f, 1.0f); diff --git a/examples/BLOCKS/BlocksDrawingDemo.h b/examples/BLOCKS/BlocksDrawingDemo.h index d3539397..c072c9bb 100644 --- a/examples/BLOCKS/BlocksDrawingDemo.h +++ b/examples/BLOCKS/BlocksDrawingDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -403,8 +403,8 @@ public: if (auto grid = activeBlock->getLEDGrid()) { // Work out scale factors to translate X and Y touches to LED indexes - scaleX = (float) (grid->getNumColumns() - 1) / activeBlock->getWidth(); - scaleY = (float) (grid->getNumRows() - 1) / activeBlock->getHeight(); + scaleX = (float) (grid->getNumColumns() - 1) / (float) activeBlock->getWidth(); + scaleY = (float) (grid->getNumRows() - 1) / (float) activeBlock->getHeight(); setLEDProgram (*activeBlock); } @@ -511,14 +511,14 @@ private: { if (currentMode == canvas) { - block.setProgram (new BitmapLEDProgram (block)); + block.setProgram (std::make_unique(block)); // Redraw any previously drawn LEDs redrawLEDs(); } else if (currentMode == colourPalette) { - block.setProgram (new DrumPadGridProgram (block)); + block.setProgram (std::make_unique (block)); // Setup the grid layout if (auto* program = getPaletteProgram()) diff --git a/examples/BLOCKS/BlocksMonitorDemo.h b/examples/BLOCKS/BlocksMonitorDemo.h index c92c0e63..c1ca368e 100644 --- a/examples/BLOCKS/BlocksMonitorDemo.h +++ b/examples/BLOCKS/BlocksMonitorDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -75,7 +75,7 @@ public: // If this is a Lightpad then set the grid program to be blank if (block->getLEDGrid() != nullptr) - block->setProgram (new BitmapLEDProgram (*block)); + block->setProgram (std::make_unique(*block)); // If this is a Lightpad then redraw it at 25Hz if (block->getType() == Block::lightPadBlock) @@ -175,7 +175,11 @@ public: return { static_cast (port.index), static_cast (block->getHeight()) }; case e::west: return { 0.0f, static_cast (port.index) }; + default: + break; } + + break; } case 90: { @@ -184,41 +188,56 @@ public: case e::north: return { 0.0f, static_cast (port.index) }; case e::east: - return { static_cast (-1.0f - port.index), static_cast (block->getWidth()) }; + return { static_cast (-1.0f - (float) port.index), static_cast (block->getWidth()) }; case e::south: - return { static_cast (0.0f - block->getHeight()), static_cast (port.index) }; + return { static_cast (0.0f - (float) block->getHeight()), static_cast (port.index) }; case e::west: - return { static_cast (-1.0f - port.index), 0.0f }; + return { static_cast (-1.0f - (float) port.index), 0.0f }; + default: + break; } + + break; } case 180: { switch (port.edge) { case e::north: - return { static_cast (-1.0f - port.index), 0.0f }; + return { static_cast (-1.0f - (float) port.index), 0.0f }; case e::east: - return { static_cast (0.0f - block->getWidth()), static_cast (-1.0f - port.index) }; + return { static_cast (0.0f - (float) block->getWidth()), static_cast (-1.0f - (float) port.index) }; case e::south: - return { static_cast (-1.0f - port.index), static_cast (0.0f - block->getHeight()) }; + return { static_cast (-1.0f - (float) port.index), static_cast (0.0f - (float) block->getHeight()) }; case e::west: - return { 0.0f, static_cast (-1.0f - port.index) }; + return { 0.0f, static_cast (-1.0f - (float) port.index) }; + default: + break; } + + break; } case 270: { switch (port.edge) { case e::north: - return { 0.0f, static_cast (-1.0f - port.index) }; + return { 0.0f, static_cast (-1.0f - (float) port.index) }; case e::east: - return { static_cast (port.index), static_cast (0 - block->getWidth()) }; + return { static_cast (port.index), static_cast (0 - (float) block->getWidth()) }; case e::south: - return { static_cast (block->getHeight()), static_cast (-1.0f - port.index) }; + return { static_cast (block->getHeight()), static_cast (-1.0f - (float) port.index) }; case e::west: return { static_cast (port.index), 0.0f }; + default: + break; } + + break; } + + default: + break; } return {}; @@ -290,10 +309,10 @@ public: g.fillAll (Colours::black); // size ration between physical and on-screen blocks - Point ratio (r.getWidth() / block->getWidth(), - r.getHeight() / block->getHeight()); + Point ratio (r.getWidth() / (float) block->getWidth(), + r.getHeight() / (float) block->getHeight()); - auto maxCircleSize = block->getWidth() / 3.0f; + auto maxCircleSize = (float) block->getWidth() / 3.0f; // iterate over the list of current touches and draw them on the onscreen Block for (auto touch : touches) @@ -348,7 +367,7 @@ public: addAndMakeVisible (roundedRectangleButton); // Display the battery level on the LEDRow - auto numLedsToTurnOn = static_cast (numLeds * block->getBatteryLevel()); + auto numLedsToTurnOn = static_cast ((float) numLeds * block->getBatteryLevel()); // add LEDs for (auto i = 0; i < numLeds; ++i) @@ -423,7 +442,7 @@ public: void handleBatteryLevelUpdate (float batteryLevel) override { // Update the number of LEDs that are on to represent the battery level - auto numLedsOn = static_cast (numLeds * batteryLevel); + auto numLedsOn = static_cast ((float) numLeds * batteryLevel); if (numLedsOn != previousNumLedsOn) for (auto i = 0; i < numLeds; ++i) @@ -581,11 +600,11 @@ public: noBlocksLabel.setJustificationType (Justification::centred); zoomOutButton.setButtonText ("+"); - zoomOutButton.onClick = [this] { blockUnitInPixels = (int) (blockUnitInPixels * 1.05f); resized(); }; + zoomOutButton.onClick = [this] { blockUnitInPixels = (int) ((float) blockUnitInPixels * 1.05f); resized(); }; zoomOutButton.setAlwaysOnTop (true); zoomInButton.setButtonText ("-"); - zoomInButton.onClick = [this] { blockUnitInPixels = (int) (blockUnitInPixels * 0.95f); resized(); }; + zoomInButton.onClick = [this] { blockUnitInPixels = (int) ((float) blockUnitInPixels * 0.95f); resized(); }; zoomInButton.setAlwaysOnTop (true); // Register BlocksMonitorDemo as a listener to the PhysicalTopologySource object @@ -626,7 +645,7 @@ public: auto numBlockComponents = blockComponents.size(); // If there are no currently connected Blocks then display some text on the screen - if (numBlockComponents == 0) + if (masterBlockComponent == nullptr || numBlockComponents == 0) { noBlocksLabel.setVisible (true); noBlocksLabel.setBounds (0, (getHeight() / 2) - 50, getWidth(), 100); @@ -651,8 +670,8 @@ public: else if (rotation == 90) blockSize = blockComponent->block->getHeight(); - if (topLeft.x - blockSize < maxArea.getX()) - maxArea.setX (topLeft.x - blockSize); + if (topLeft.x - (float) blockSize < maxArea.getX()) + maxArea.setX (topLeft.x - (float) blockSize); blockSize = 0; if (rotation == 0) @@ -660,8 +679,8 @@ public: else if (rotation == 270) blockSize = blockComponent->block->getHeight(); - if (topLeft.x + blockSize > maxArea.getRight()) - maxArea.setWidth (topLeft.x + blockSize); + if (topLeft.x + (float) blockSize > maxArea.getRight()) + maxArea.setWidth (topLeft.x + (float) blockSize); blockSize = 0; if (rotation == 180) @@ -669,8 +688,8 @@ public: else if (rotation == 270) blockSize = blockComponent->block->getWidth(); - if (topLeft.y - blockSize < maxArea.getY()) - maxArea.setY (topLeft.y - blockSize); + if (topLeft.y - (float) blockSize < maxArea.getY()) + maxArea.setY (topLeft.y - (float) blockSize); blockSize = 0; if (rotation == 0) @@ -678,14 +697,14 @@ public: else if (rotation == 90) blockSize = blockComponent->block->getWidth(); - if (topLeft.y + blockSize > maxArea.getBottom()) - maxArea.setHeight (topLeft.y + blockSize); + if (topLeft.y + (float) blockSize > maxArea.getBottom()) + maxArea.setHeight (topLeft.y + (float) blockSize); } auto totalWidth = std::abs (maxArea.getX()) + maxArea.getWidth(); auto totalHeight = std::abs (maxArea.getY()) + maxArea.getHeight(); - blockUnitInPixels = static_cast (jmin ((getHeight() / totalHeight) - 50, (getWidth() / totalWidth) - 50)); + blockUnitInPixels = static_cast (jmin (((float) getHeight() / totalHeight) - 50, ((float) getWidth() / totalWidth) - 50)); masterBlockComponent->centreWithSize (masterBlockComponent->block->getWidth() * blockUnitInPixels, masterBlockComponent->block->getHeight() * blockUnitInPixels); @@ -702,8 +721,8 @@ public: if (blockComponent == masterBlockComponent) continue; - blockComponent->setBounds (masterBlockComponent->getX() + static_cast (blockComponent->topLeft.x * blockUnitInPixels), - masterBlockComponent->getY() + static_cast (blockComponent->topLeft.y * blockUnitInPixels), + blockComponent->setBounds (masterBlockComponent->getX() + static_cast (blockComponent->topLeft.x * (float) blockUnitInPixels), + masterBlockComponent->getY() + static_cast (blockComponent->topLeft.y * (float) blockUnitInPixels), blockComponent->block->getWidth() * blockUnitInPixels, blockComponent->block->getHeight() * blockUnitInPixels); @@ -776,6 +795,9 @@ private: /** Calculates the position and rotation of each connected Block relative to the master Block */ void positionBlocks (BlockTopology topology) { + if (masterBlockComponent == nullptr) + return; + Array blocksConnectedToMaster; auto maxDelta = std::numeric_limits::max(); @@ -921,7 +943,11 @@ private: return 90; case edge::west: return 270; + default: + break; } + + break; } case edge::south: { @@ -935,7 +961,11 @@ private: return 270; case edge::west: return 90; + default: + break; } + + break; } case edge::east: { @@ -949,7 +979,11 @@ private: return 180; case edge::west: return 0; + default: + break; } + + break; } case edge::west: @@ -964,8 +998,15 @@ private: return 0; case edge::west: return 180; + default: + break; } + + break; } + + default: + break; } return 0; diff --git a/examples/BLOCKS/BlocksSynthDemo.h b/examples/BLOCKS/BlocksSynthDemo.h index aa34dc12..99541038 100644 --- a/examples/BLOCKS/BlocksSynthDemo.h +++ b/examples/BLOCKS/BlocksSynthDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -411,7 +411,7 @@ public: } else { - if (squareWaveY[x - 1] == 1) + if (x > 0 && squareWaveY[x - 1] == 1) squareWaveY[x - 1] = 255; squareWaveY[x] = 13; @@ -643,7 +643,7 @@ public: detachActiveBlock(); // Get the array of currently connected Block objects from the PhysicalTopologySource - auto blocks = topologySource.getCurrentTopology().blocks; + auto blocks = topologySource.getBlocks(); // Iterate over the array of Block objects for (auto b : blocks) @@ -665,8 +665,8 @@ public: if (auto grid = activeBlock->getLEDGrid()) { // Work out scale factors to translate X and Y touches to LED indexes - scaleX = static_cast (grid->getNumColumns() - 1) / activeBlock->getWidth(); - scaleY = static_cast (grid->getNumRows() - 1) / activeBlock->getHeight(); + scaleX = static_cast (grid->getNumColumns() - 1) / (float) activeBlock->getWidth(); + scaleY = static_cast (grid->getNumRows() - 1) / (float) activeBlock->getHeight(); setLEDProgram (*activeBlock); } @@ -731,7 +731,7 @@ private: layout.touchColour); // Send pitch change and pressure values to the Audio class - audio.pitchChange (midiChannel, (touch.x - touch.startX) / activeBlock->getWidth()); + audio.pitchChange (midiChannel, (touch.x - touch.startX) / (float) activeBlock->getWidth()); audio.pressureChange (midiChannel, touch.z); } @@ -785,7 +785,7 @@ private: if (currentMode == waveformSelectionMode) { // Set the LEDGrid program - block.setProgram (new WaveshapeProgram (block)); + block.setProgram (std::make_unique(block)); // Initialise the program if (auto* waveshapeProgram = getWaveshapeProgram()) @@ -797,7 +797,7 @@ private: else if (currentMode == playMode) { // Set the LEDGrid program - auto error = block.setProgram (new DrumPadGridProgram (block)); + auto error = block.setProgram (std::make_unique(block)); if (error.failed()) { diff --git a/examples/BLOCKS/CMakeLists.txt b/examples/BLOCKS/CMakeLists.txt new file mode 100644 index 00000000..272e8475 --- /dev/null +++ b/examples/BLOCKS/CMakeLists.txt @@ -0,0 +1,24 @@ +# ============================================================================== +# +# This file is part of the JUCE library. +# Copyright (c) 2020 - Raw Material Software Limited +# +# JUCE is an open source library subject to commercial or open-source +# licensing. +# +# By using JUCE, you agree to the terms of both the JUCE 6 End-User License +# Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). +# +# End User License Agreement: www.juce.com/juce-6-licence +# Privacy Policy: www.juce.com/juce-privacy-policy +# +# Or: You may also use this code under the terms of the GPL v3 (see +# www.gnu.org/licenses). +# +# JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER +# EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE +# DISCLAIMED. +# +# ============================================================================== + +_juce_add_pips() diff --git a/examples/CMake/AudioPlugin/CMakeLists.txt b/examples/CMake/AudioPlugin/CMakeLists.txt new file mode 100644 index 00000000..645d5ece --- /dev/null +++ b/examples/CMake/AudioPlugin/CMakeLists.txt @@ -0,0 +1,110 @@ +# Example Audio Plugin CMakeLists.txt + +# To get started on a new plugin, copy this entire folder (containing this file and C++ sources) to +# a convenient location, and then start making modifications. + +# The first line of any CMake project should be a call to `cmake_minimum_required`, which checks +# that the installed CMake will be able to understand the following CMakeLists, and ensures that +# CMake's behaviour is compatible with the named version. This is a standard CMake command, so more +# information can be found in the CMake docs. + +cmake_minimum_required(VERSION 3.15) + +# The top-level CMakeLists.txt file for a project must contain a literal, direct call to the +# `project()` command. `project()` sets up some helpful variables that describe source/binary +# directories, and the current project version. This is a standard CMake command. + +project(AUDIO_PLUGIN_EXAMPLE VERSION 0.0.1) + +# If you've installed JUCE somehow (via a package manager, or directly using the CMake install +# target), you'll need to tell this project that it depends on the installed copy of JUCE. If you've +# included JUCE directly in your source tree (perhaps as a submodule), you'll need to tell CMake to +# include that subdirectory as part of the build. + +# find_package(JUCE CONFIG REQUIRED) # If you've installed JUCE to your system +# or +# add_subdirectory(JUCE) # If you've put JUCE in a subdirectory called JUCE + +# If you are building a VST2 or AAX plugin, CMake needs to be told where to find these SDKs on your +# system. This setup should be done before calling `juce_add_plugin`. + +# juce_set_vst2_sdk_path(...) +# juce_set_aax_sdk_path(...) + +# `juce_add_plugin` adds a static library target with the name passed as the first argument +# (AudioPluginExample here). This target is a normal CMake target, but has a lot of extra properties set +# up by default. As well as this shared code static library, this function adds targets for each of +# the formats specified by the FORMATS arguments. This function accepts many optional arguments. +# Check the readme at `docs/CMake API.md` in the JUCE repo for the full list. + +juce_add_plugin(AudioPluginExample + # VERSION ... # Set this if the plugin version is different to the project version + # ICON_BIG ... # ICON_* arguments specify a path to an image file to use as an icon for the Standalone + # ICON_SMALL ... + # COMPANY_NAME ... # Specify the name of the plugin's author + # IS_SYNTH TRUE/FALSE # Is this a synth or an effect? + # NEEDS_MIDI_INPUT TRUE/FALSE # Does the plugin need midi input? + # NEEDS_MIDI_OUTPUT TRUE/FALSE # Does the plugin need midi output? + # IS_MIDI_EFFECT TRUE/FALSE # Is this plugin a MIDI effect? + # EDITOR_WANTS_KEYBOARD_FOCUS TRUE/FALSE # Does the editor need keyboard focus? + # COPY_PLUGIN_AFTER_BUILD TRUE/FALSE # Should the plugin be installed to a default location after building? + PLUGIN_MANUFACTURER_CODE Juce # A four-character manufacturer id with at least one upper-case character + PLUGIN_CODE Dem0 # A unique four-character plugin id with at least one upper-case character + FORMATS AU VST3 Standalone # The formats to build. Other valid formats are: AAX Unity VST AU AUv3 + PRODUCT_NAME "Audio Plugin Example") # The name of the final executable, which can differ from the target name + +# `juce_generate_juce_header` will create a JuceHeader.h for a given target, which will be generated +# into your build tree. This should be included with `#include `. The include path for +# this header will be automatically added to the target. The main function of the JuceHeader is to +# include all your JUCE module headers; if you're happy to include module headers directly, you +# probably don't need to call this. + +# juce_generate_juce_header(AudioPluginExample) + +# `target_sources` adds source files to a target. We pass the target that needs the sources as the +# first argument, then a visibility parameter for the sources which should normally be PRIVATE. +# Finally, we supply a list of source files that will be built into the target. This is a standard +# CMake command. + +target_sources(AudioPluginExample + PRIVATE + PluginEditor.cpp + PluginProcessor.cpp) + +# `target_compile_definitions` adds some preprocessor definitions to our target. In a Projucer +# project, these might be passed in the 'Preprocessor Definitions' field. JUCE modules also make use +# of compile definitions to switch certain features on/off, so if there's a particular feature you +# need that's not on by default, check the module header for the correct flag to set here. These +# definitions will be visible both to your code, and also the JUCE module code, so for new +# definitions, pick unique names that are unlikely to collide! This is a standard CMake command. + +target_compile_definitions(AudioPluginExample + PUBLIC + # JUCE_WEB_BROWSER and JUCE_USE_CURL would be on by default, but you might not need them. + JUCE_WEB_BROWSER=0 # If you remove this, add `NEEDS_WEB_BROWSER TRUE` to the `juce_add_plugin` call + JUCE_USE_CURL=0 # If you remove this, add `NEEDS_CURL TRUE` to the `juce_add_plugin` call + JUCE_VST3_CAN_REPLACE_VST2=0) + +# If your target needs extra binary assets, you can add them here. The first argument is the name of +# a new static library target that will include all the binary resources. There is an optional +# `NAMESPACE` argument that can specify the namespace of the generated binary data class. Finally, +# the SOURCES argument should be followed by a list of source files that should be built into the +# static library. These source files can be of any kind (wav data, images, fonts, icons etc.). +# Conversion to binary-data will happen when your target is built. + +# juce_add_binary_data(AudioPluginData SOURCES ...) + +# `target_link_libraries` links libraries and JUCE modules to other libraries or executables. Here, +# we're linking our executable target to the `juce::juce_audio_utils` module. Inter-module +# dependencies are resolved automatically, so `juce_core`, `juce_events` and so on will also be +# linked automatically. If we'd generated a binary data target above, we would need to link to it +# here too. This is a standard CMake command. + +target_link_libraries(AudioPluginExample + PRIVATE + # AudioPluginData # If we'd created a binary data target, we'd link to it here + juce::juce_audio_utils + PUBLIC + juce::juce_recommended_config_flags + juce::juce_recommended_lto_flags + juce::juce_recommended_warning_flags) diff --git a/examples/CMake/AudioPlugin/PluginEditor.cpp b/examples/CMake/AudioPlugin/PluginEditor.cpp new file mode 100644 index 00000000..50f8eb44 --- /dev/null +++ b/examples/CMake/AudioPlugin/PluginEditor.cpp @@ -0,0 +1,33 @@ +#include "PluginProcessor.h" +#include "PluginEditor.h" + +//============================================================================== +AudioPluginAudioProcessorEditor::AudioPluginAudioProcessorEditor (AudioPluginAudioProcessor& p) + : AudioProcessorEditor (&p), processorRef (p) +{ + juce::ignoreUnused (processorRef); + // Make sure that before the constructor has finished, you've set the + // editor's size to whatever you need it to be. + setSize (400, 300); +} + +AudioPluginAudioProcessorEditor::~AudioPluginAudioProcessorEditor() +{ +} + +//============================================================================== +void AudioPluginAudioProcessorEditor::paint (juce::Graphics& g) +{ + // (Our component is opaque, so we must completely fill the background with a solid colour) + g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId)); + + g.setColour (juce::Colours::white); + g.setFont (15.0f); + g.drawFittedText ("Hello World!", getLocalBounds(), juce::Justification::centred, 1); +} + +void AudioPluginAudioProcessorEditor::resized() +{ + // This is generally where you'll want to lay out the positions of any + // subcomponents in your editor.. +} diff --git a/examples/CMake/AudioPlugin/PluginEditor.h b/examples/CMake/AudioPlugin/PluginEditor.h new file mode 100644 index 00000000..ef96e04a --- /dev/null +++ b/examples/CMake/AudioPlugin/PluginEditor.h @@ -0,0 +1,22 @@ +#pragma once + +#include "PluginProcessor.h" + +//============================================================================== +class AudioPluginAudioProcessorEditor : public juce::AudioProcessorEditor +{ +public: + explicit AudioPluginAudioProcessorEditor (AudioPluginAudioProcessor&); + ~AudioPluginAudioProcessorEditor() override; + + //============================================================================== + void paint (juce::Graphics&) override; + void resized() override; + +private: + // This reference is provided as a quick way for your editor to + // access the processor object that created it. + AudioPluginAudioProcessor& processorRef; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioPluginAudioProcessorEditor) +}; diff --git a/examples/CMake/AudioPlugin/PluginProcessor.cpp b/examples/CMake/AudioPlugin/PluginProcessor.cpp new file mode 100644 index 00000000..31394624 --- /dev/null +++ b/examples/CMake/AudioPlugin/PluginProcessor.cpp @@ -0,0 +1,186 @@ +#include "PluginProcessor.h" +#include "PluginEditor.h" + +//============================================================================== +AudioPluginAudioProcessor::AudioPluginAudioProcessor() + : AudioProcessor (BusesProperties() + #if ! JucePlugin_IsMidiEffect + #if ! JucePlugin_IsSynth + .withInput ("Input", juce::AudioChannelSet::stereo(), true) + #endif + .withOutput ("Output", juce::AudioChannelSet::stereo(), true) + #endif + ) +{ +} + +AudioPluginAudioProcessor::~AudioPluginAudioProcessor() +{ +} + +//============================================================================== +const juce::String AudioPluginAudioProcessor::getName() const +{ + return JucePlugin_Name; +} + +bool AudioPluginAudioProcessor::acceptsMidi() const +{ + #if JucePlugin_WantsMidiInput + return true; + #else + return false; + #endif +} + +bool AudioPluginAudioProcessor::producesMidi() const +{ + #if JucePlugin_ProducesMidiOutput + return true; + #else + return false; + #endif +} + +bool AudioPluginAudioProcessor::isMidiEffect() const +{ + #if JucePlugin_IsMidiEffect + return true; + #else + return false; + #endif +} + +double AudioPluginAudioProcessor::getTailLengthSeconds() const +{ + return 0.0; +} + +int AudioPluginAudioProcessor::getNumPrograms() +{ + return 1; // NB: some hosts don't cope very well if you tell them there are 0 programs, + // so this should be at least 1, even if you're not really implementing programs. +} + +int AudioPluginAudioProcessor::getCurrentProgram() +{ + return 0; +} + +void AudioPluginAudioProcessor::setCurrentProgram (int index) +{ + juce::ignoreUnused (index); +} + +const juce::String AudioPluginAudioProcessor::getProgramName (int index) +{ + juce::ignoreUnused (index); + return {}; +} + +void AudioPluginAudioProcessor::changeProgramName (int index, const juce::String& newName) +{ + juce::ignoreUnused (index, newName); +} + +//============================================================================== +void AudioPluginAudioProcessor::prepareToPlay (double sampleRate, int samplesPerBlock) +{ + // Use this method as the place to do any pre-playback + // initialisation that you need.. + juce::ignoreUnused (sampleRate, samplesPerBlock); +} + +void AudioPluginAudioProcessor::releaseResources() +{ + // When playback stops, you can use this as an opportunity to free up any + // spare memory, etc. +} + +bool AudioPluginAudioProcessor::isBusesLayoutSupported (const BusesLayout& layouts) const +{ + #if JucePlugin_IsMidiEffect + juce::ignoreUnused (layouts); + return true; + #else + // This is the place where you check if the layout is supported. + // In this template code we only support mono or stereo. + if (layouts.getMainOutputChannelSet() != juce::AudioChannelSet::mono() + && layouts.getMainOutputChannelSet() != juce::AudioChannelSet::stereo()) + return false; + + // This checks if the input layout matches the output layout + #if ! JucePlugin_IsSynth + if (layouts.getMainOutputChannelSet() != layouts.getMainInputChannelSet()) + return false; + #endif + + return true; + #endif +} + +void AudioPluginAudioProcessor::processBlock (juce::AudioBuffer& buffer, + juce::MidiBuffer& midiMessages) +{ + juce::ignoreUnused (midiMessages); + + juce::ScopedNoDenormals noDenormals; + auto totalNumInputChannels = getTotalNumInputChannels(); + auto totalNumOutputChannels = getTotalNumOutputChannels(); + + // In case we have more outputs than inputs, this code clears any output + // channels that didn't contain input data, (because these aren't + // guaranteed to be empty - they may contain garbage). + // This is here to avoid people getting screaming feedback + // when they first compile a plugin, but obviously you don't need to keep + // this code if your algorithm always overwrites all the output channels. + for (auto i = totalNumInputChannels; i < totalNumOutputChannels; ++i) + buffer.clear (i, 0, buffer.getNumSamples()); + + // This is the place where you'd normally do the guts of your plugin's + // audio processing... + // Make sure to reset the state if your inner loop is processing + // the samples and the outer loop is handling the channels. + // Alternatively, you can process the samples with the channels + // interleaved by keeping the same state. + for (int channel = 0; channel < totalNumInputChannels; ++channel) + { + auto* channelData = buffer.getWritePointer (channel); + juce::ignoreUnused (channelData); + // ..do something to the data... + } +} + +//============================================================================== +bool AudioPluginAudioProcessor::hasEditor() const +{ + return true; // (change this to false if you choose to not supply an editor) +} + +juce::AudioProcessorEditor* AudioPluginAudioProcessor::createEditor() +{ + return new AudioPluginAudioProcessorEditor (*this); +} + +//============================================================================== +void AudioPluginAudioProcessor::getStateInformation (juce::MemoryBlock& destData) +{ + // You should use this method to store your parameters in the memory block. + // You could do that either as raw data, or use the XML or ValueTree classes + // as intermediaries to make it easy to save and load complex data. + juce::ignoreUnused (destData); +} + +void AudioPluginAudioProcessor::setStateInformation (const void* data, int sizeInBytes) +{ + // You should use this method to restore your parameters from this memory block, + // whose contents will have been created by the getStateInformation() call. + juce::ignoreUnused (data, sizeInBytes); +} + +//============================================================================== +// This creates new instances of the plugin.. +juce::AudioProcessor* JUCE_CALLTYPE createPluginFilter() +{ + return new AudioPluginAudioProcessor(); +} diff --git a/examples/CMake/AudioPlugin/PluginProcessor.h b/examples/CMake/AudioPlugin/PluginProcessor.h new file mode 100644 index 00000000..61413bb1 --- /dev/null +++ b/examples/CMake/AudioPlugin/PluginProcessor.h @@ -0,0 +1,48 @@ +#pragma once + +#include + +//============================================================================== +class AudioPluginAudioProcessor : public juce::AudioProcessor +{ +public: + //============================================================================== + AudioPluginAudioProcessor(); + ~AudioPluginAudioProcessor() override; + + //============================================================================== + void prepareToPlay (double sampleRate, int samplesPerBlock) override; + void releaseResources() override; + + bool isBusesLayoutSupported (const BusesLayout& layouts) const override; + + void processBlock (juce::AudioBuffer&, juce::MidiBuffer&) override; + using AudioProcessor::processBlock; + + //============================================================================== + juce::AudioProcessorEditor* createEditor() override; + bool hasEditor() const override; + + //============================================================================== + const juce::String getName() const override; + + bool acceptsMidi() const override; + bool producesMidi() const override; + bool isMidiEffect() const override; + double getTailLengthSeconds() const override; + + //============================================================================== + int getNumPrograms() override; + int getCurrentProgram() override; + void setCurrentProgram (int index) override; + const juce::String getProgramName (int index) override; + void changeProgramName (int index, const juce::String& newName) override; + + //============================================================================== + void getStateInformation (juce::MemoryBlock& destData) override; + void setStateInformation (const void* data, int sizeInBytes) override; + +private: + //============================================================================== + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioPluginAudioProcessor) +}; diff --git a/examples/CMake/CMakeLists.txt b/examples/CMake/CMakeLists.txt new file mode 100644 index 00000000..c9aabdc3 --- /dev/null +++ b/examples/CMake/CMakeLists.txt @@ -0,0 +1,26 @@ +# ============================================================================== +# +# This file is part of the JUCE library. +# Copyright (c) 2020 - Raw Material Software Limited +# +# JUCE is an open source library subject to commercial or open-source +# licensing. +# +# By using JUCE, you agree to the terms of both the JUCE 6 End-User License +# Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). +# +# End User License Agreement: www.juce.com/juce-6-licence +# Privacy Policy: www.juce.com/juce-privacy-policy +# +# Or: You may also use this code under the terms of the GPL v3 (see +# www.gnu.org/licenses). +# +# JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER +# EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE +# DISCLAIMED. +# +# ============================================================================== + +add_subdirectory(AudioPlugin) +add_subdirectory(ConsoleApp) +add_subdirectory(GuiApp) diff --git a/examples/CMake/ConsoleApp/CMakeLists.txt b/examples/CMake/ConsoleApp/CMakeLists.txt new file mode 100644 index 00000000..7d5564bc --- /dev/null +++ b/examples/CMake/ConsoleApp/CMakeLists.txt @@ -0,0 +1,88 @@ +# Example Console App CMakeLists.txt + +# To get started on a new console app, copy this entire folder (containing this file and C++ +# sources) to a convenient location, and then start making modifications. For other examples of +# CMakeLists for console apps, check `extras/BinaryBuilder` and `extras/UnitTestRunner` in the JUCE +# repo. + +# The first line of any CMake project should be a call to `cmake_minimum_required`, which checks +# that the installed CMake will be able to understand the following CMakeLists, and ensures that +# CMake's behaviour is compatible with the named version. This is a standard CMake command, so more +# information can be found in the CMake docs. + +cmake_minimum_required(VERSION 3.12) + +# The top-level CMakeLists.txt file for a project must contain a literal, direct call to the +# `project()` command. `project()` sets up some helpful variables that describe source/binary +# directories, and the current project version. This is a standard CMake command. + +project(CONSOLE_APP_EXAMPLE VERSION 0.0.1) + +# If you've installed JUCE somehow (via a package manager, or directly using the CMake install +# target), you'll need to tell this project that it depends on the installed copy of JUCE. If you've +# included JUCE directly in your source tree (perhaps as a submodule), you'll need to tell CMake to +# include that subdirectory as part of the build. + +# find_package(JUCE CONFIG REQUIRED) # If you've installed JUCE to your system +# or +# add_subdirectory(JUCE) # If you've put JUCE in a subdirectory called JUCE + +# `juce_add_console_app` adds an executable target with the name passed as the first argument +# (ConsoleAppExample here). This target is a normal CMake target, but has a lot of extra properties +# set up by default. This function accepts many optional arguments. Check the readme at +# `docs/CMake API.md` in the JUCE repo for the full list. + +juce_add_console_app(ConsoleAppExample + PRODUCT_NAME "Console App Example") # The name of the final executable, which can differ from the target name + +# `juce_generate_juce_header` will create a JuceHeader.h for a given target, which will be generated +# into the build tree. This header should be included with `#include `. The include +# path for this header will be automatically added to the target. The main function of the +# JuceHeader is to include all the JUCE module headers for a particular target; if you're happy to +# include module headers directly, you probably don't need to call this. + +# juce_generate_juce_header(ConsoleAppExample) + +# `target_sources` adds source files to a target. We pass the target that needs the sources as the +# first argument, then a visibility parameter for the sources which should normally be PRIVATE. +# Finally, we supply a list of source files that will be built into the target. This is a standard +# CMake command. + +target_sources(ConsoleAppExample + PRIVATE + Main.cpp) + +# `target_compile_definitions` adds some preprocessor definitions to our target. In a Projucer +# project, these might be passed in the 'Preprocessor Definitions' field. JUCE modules also make use +# of compile definitions to switch certain features on/off, so if there's a particular feature you +# need that's not on by default, check the module header for the correct flag to set here. These +# definitions will be visible both to your code, and also the JUCE module code, so for new +# definitions, pick unique names that are unlikely to collide! This is a standard CMake command. + +target_compile_definitions(ConsoleAppExample + PRIVATE + # JUCE_WEB_BROWSER and JUCE_USE_CURL would be on by default, but you might not need them. + JUCE_WEB_BROWSER=0 # If you remove this, add `NEEDS_WEB_BROWSER TRUE` to the `juce_add_console_app` call + JUCE_USE_CURL=0) # If you remove this, add `NEEDS_CURL TRUE` to the `juce_add_console_app` call + +# If the target needs extra binary assets, they can be added here. The first argument is the name of +# a new static library target that will include all the binary resources. There is an optional +# `NAMESPACE` argument that can specify the namespace of the generated binary data class. Finally, +# the SOURCES argument should be followed by a list of source files that should be built into the +# static library. These source files can be of any kind (wav data, images, fonts, icons etc.). +# Conversion to binary-data will happen when the target is built. + +# juce_add_binary_data(ConsoleAppData SOURCES ...) + +# `target_link_libraries` links libraries and JUCE modules to other libraries or executables. Here, +# we're linking our executable target to the `juce::juce_core` module. Inter-module dependencies are +# resolved automatically. If you'd generated a binary data target above, you would need to link to +# it here too. This is a standard CMake command. + +target_link_libraries(ConsoleAppExample + PRIVATE + # ConsoleAppData # If you'd created a binary data target, you'd link to it here + juce::juce_core + PUBLIC + juce::juce_recommended_config_flags + juce::juce_recommended_warning_flags) diff --git a/examples/CMake/ConsoleApp/Main.cpp b/examples/CMake/ConsoleApp/Main.cpp new file mode 100644 index 00000000..7663abd0 --- /dev/null +++ b/examples/CMake/ConsoleApp/Main.cpp @@ -0,0 +1,10 @@ +#include + +int main (int argc, char* argv[]) +{ + + // Your code goes here! + juce::ignoreUnused (argc, argv); + + return 0; +} diff --git a/examples/CMake/GuiApp/CMakeLists.txt b/examples/CMake/GuiApp/CMakeLists.txt new file mode 100644 index 00000000..e449f8c0 --- /dev/null +++ b/examples/CMake/GuiApp/CMakeLists.txt @@ -0,0 +1,102 @@ +# Example GUI App CMakeLists.txt + +# To get started on a new GUI app, copy this entire folder (containing this file and C++ sources) to +# a convenient location, and then start making modifications. For other examples of CMakeLists for +# GUI apps, check `extras/Projucer` and `examples/DemoRunner` in the JUCE repo. + +# The first line of any CMake project should be a call to `cmake_minimum_required`, which checks +# that the installed CMake will be able to understand the following CMakeLists, and ensures that +# CMake's behaviour is compatible with the named version. This is a standard CMake command, so more +# information can be found in the CMake docs. + +cmake_minimum_required(VERSION 3.12) + +# The top-level CMakeLists.txt file for a project must contain a literal, direct call to the +# `project()` command. `project()` sets up some helpful variables that describe source/binary +# directories, and the current project version. This is a standard CMake command. + +project(GUI_APP_EXAMPLE VERSION 0.0.1) + +# If you've installed JUCE somehow (via a package manager, or directly using the CMake install +# target), you'll need to tell this project that it depends on the installed copy of JUCE. If you've +# included JUCE directly in your source tree (perhaps as a submodule), you'll need to tell CMake to +# include that subdirectory as part of the build. + +# find_package(JUCE CONFIG REQUIRED) # If you've installed JUCE to your system +# or +# add_subdirectory(JUCE) # If you've put JUCE in a subdirectory called JUCE + +# If your app depends the VST2 SDK, perhaps to host VST2 plugins, CMake needs to be told where +# to find the SDK on your system. This setup should be done before calling `juce_add_gui_app`. + +# juce_set_vst2_sdk_path(...) + +# `juce_add_gui_app` adds an executable target with the name passed as the first argument +# (GuiAppExample here). This target is a normal CMake target, but has a lot of extra properties set +# up by default. This function accepts many optional arguments. Check the readme at +# `docs/CMake API.md` in the JUCE repo for the full list. + +juce_add_gui_app(GuiAppExample + # VERSION ... # Set this if the app version is different to the project version + # ICON_BIG ... # ICON_* arguments specify a path to an image file to use as an icon + # ICON_SMALL ... + # DOCUMENT_EXTENSIONS ... # Specify file extensions that should be associated with this app + # COMPANY_NAME ... # Specify the name of the app's author + PRODUCT_NAME "Gui App Example") # The name of the final executable, which can differ from the target name + +# `juce_generate_juce_header` will create a JuceHeader.h for a given target, which will be generated +# into your build tree. This should be included with `#include `. The include path for +# this header will be automatically added to the target. The main function of the JuceHeader is to +# include all your JUCE module headers; if you're happy to include module headers directly, you +# probably don't need to call this. + +# juce_generate_juce_header(GuiAppExample) + +# `target_sources` adds source files to a target. We pass the target that needs the sources as the +# first argument, then a visibility parameter for the sources which should normally be PRIVATE. +# Finally, we supply a list of source files that will be built into the target. This is a standard +# CMake command. + +target_sources(GuiAppExample + PRIVATE + Main.cpp + MainComponent.cpp) + +# `target_compile_definitions` adds some preprocessor definitions to our target. In a Projucer +# project, these might be passed in the 'Preprocessor Definitions' field. JUCE modules also make use +# of compile definitions to switch certain features on/off, so if there's a particular feature you +# need that's not on by default, check the module header for the correct flag to set here. These +# definitions will be visible both to your code, and also the JUCE module code, so for new +# definitions, pick unique names that are unlikely to collide! This is a standard CMake command. + +target_compile_definitions(GuiAppExample + PRIVATE + # JUCE_WEB_BROWSER and JUCE_USE_CURL would be on by default, but you might not need them. + JUCE_WEB_BROWSER=0 # If you remove this, add `NEEDS_WEB_BROWSER TRUE` to the `juce_add_gui_app` call + JUCE_USE_CURL=0 # If you remove this, add `NEEDS_CURL TRUE` to the `juce_add_gui_app` call + JUCE_APPLICATION_NAME_STRING="$" + JUCE_APPLICATION_VERSION_STRING="$") + +# If your target needs extra binary assets, you can add them here. The first argument is the name of +# a new static library target that will include all the binary resources. There is an optional +# `NAMESPACE` argument that can specify the namespace of the generated binary data class. Finally, +# the SOURCES argument should be followed by a list of source files that should be built into the +# static library. These source files can be of any kind (wav data, images, fonts, icons etc.). +# Conversion to binary-data will happen when your target is built. + +# juce_add_binary_data(GuiAppData SOURCES ...) + +# `target_link_libraries` links libraries and JUCE modules to other libraries or executables. Here, +# we're linking our executable target to the `juce::juce_gui_extra` module. Inter-module +# dependencies are resolved automatically, so `juce_core`, `juce_events` and so on will also be +# linked automatically. If we'd generated a binary data target above, we would need to link to it +# here too. This is a standard CMake command. + +target_link_libraries(GuiAppExample + PRIVATE + # GuiAppData # If we'd created a binary data target, we'd link to it here + juce::juce_gui_extra + PUBLIC + juce::juce_recommended_config_flags + juce::juce_recommended_lto_flags + juce::juce_recommended_warning_flags) diff --git a/extras/Projucer/Source/BinaryData/Templates/jucer_MainTemplate_SimpleWindow.cpp b/examples/CMake/GuiApp/Main.cpp similarity index 64% rename from extras/Projucer/Source/BinaryData/Templates/jucer_MainTemplate_SimpleWindow.cpp rename to examples/CMake/GuiApp/Main.cpp index 926eb48a..72aa7bbd 100644 --- a/extras/Projucer/Source/BinaryData/Templates/jucer_MainTemplate_SimpleWindow.cpp +++ b/examples/CMake/GuiApp/Main.cpp @@ -1,30 +1,24 @@ -/* - ============================================================================== - - This file was auto-generated! - - It contains the basic startup code for a JUCE application. - - ============================================================================== -*/ - -%%app_headers%% +#include "MainComponent.h" //============================================================================== -class %%app_class_name%% : public JUCEApplication +class GuiAppApplication : public juce::JUCEApplication { public: //============================================================================== - %%app_class_name%%() {} + GuiAppApplication() {} - const String getApplicationName() override { return ProjectInfo::projectName; } - const String getApplicationVersion() override { return ProjectInfo::versionString; } - bool moreThanOneInstanceAllowed() override { return %%allow_more_than_one_instance%%; } + // We inject these as compile definitions from the CMakeLists.txt + // If you've enabled the juce header with `juce_generate_juce_header()` + // you could `#include ` and use `ProjectInfo::projectName` etc. instead. + const juce::String getApplicationName() override { return JUCE_APPLICATION_NAME_STRING; } + const juce::String getApplicationVersion() override { return JUCE_APPLICATION_VERSION_STRING; } + bool moreThanOneInstanceAllowed() override { return true; } //============================================================================== - void initialise (const String& commandLine) override + void initialise (const juce::String& commandLine) override { // This method is where you should put your application's initialisation code.. + juce::ignoreUnused (commandLine); mainWindow.reset (new MainWindow (getApplicationName())); } @@ -44,28 +38,30 @@ public: quit(); } - void anotherInstanceStarted (const String& commandLine) override + void anotherInstanceStarted (const juce::String& commandLine) override { // When another instance of the app is launched while this one is running, // this method is invoked, and the commandLine parameter tells you what // the other instance's command-line arguments were. + juce::ignoreUnused (commandLine); } //============================================================================== /* This class implements the desktop window that contains an instance of - our %%content_component_class%% class. + our MainComponent class. */ - class MainWindow : public DocumentWindow + class MainWindow : public juce::DocumentWindow { public: - MainWindow (String name) : DocumentWindow (name, - Desktop::getInstance().getDefaultLookAndFeel() - .findColour (ResizableWindow::backgroundColourId), - DocumentWindow::allButtons) + explicit MainWindow (juce::String name) + : DocumentWindow (name, + juce::Desktop::getInstance().getDefaultLookAndFeel() + .findColour (ResizableWindow::backgroundColourId), + DocumentWindow::allButtons) { setUsingNativeTitleBar (true); - setContentOwned (new %%content_component_class%%(), true); + setContentOwned (new MainComponent(), true); #if JUCE_IOS || JUCE_ANDROID setFullScreen (true); @@ -102,4 +98,4 @@ private: //============================================================================== // This macro generates the main() routine that launches the app. -START_JUCE_APPLICATION (%%app_class_name%%) +START_JUCE_APPLICATION (GuiAppApplication) diff --git a/examples/CMake/GuiApp/MainComponent.cpp b/examples/CMake/GuiApp/MainComponent.cpp new file mode 100644 index 00000000..82fee61a --- /dev/null +++ b/examples/CMake/GuiApp/MainComponent.cpp @@ -0,0 +1,25 @@ +#include "MainComponent.h" + +//============================================================================== +MainComponent::MainComponent() +{ + setSize (600, 400); +} + +//============================================================================== +void MainComponent::paint (juce::Graphics& g) +{ + // (Our component is opaque, so we must completely fill the background with a solid colour) + g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId)); + + g.setFont (juce::Font (16.0f)); + g.setColour (juce::Colours::white); + g.drawText ("Hello World!", getLocalBounds(), juce::Justification::centred, true); +} + +void MainComponent::resized() +{ + // This is called when the MainComponent is resized. + // If you add any child components, this is where you should + // update their positions. +} diff --git a/examples/CMake/GuiApp/MainComponent.h b/examples/CMake/GuiApp/MainComponent.h new file mode 100644 index 00000000..042c8cb6 --- /dev/null +++ b/examples/CMake/GuiApp/MainComponent.h @@ -0,0 +1,29 @@ +#pragma once + +// CMake builds don't use an AppConfig.h, so it's safe to include juce module headers +// directly. If you need to remain compatible with Projucer-generated builds, and +// have called `juce_generate_juce_header()` in your CMakeLists.txt, +// you could `#include ` here instead, to make all your module headers visible. +#include + +//============================================================================== +/* + This component lives inside our window, and this is where you should put all + your controls and content. +*/ +class MainComponent : public juce::Component +{ +public: + //============================================================================== + MainComponent(); + + //============================================================================== + void paint (juce::Graphics&) override; + void resized() override; + +private: + //============================================================================== + // Your private member variables go here... + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainComponent) +}; diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt new file mode 100644 index 00000000..fbbbbe78 --- /dev/null +++ b/examples/CMakeLists.txt @@ -0,0 +1,58 @@ +# ============================================================================== +# +# This file is part of the JUCE library. +# Copyright (c) 2020 - Raw Material Software Limited +# +# JUCE is an open source library subject to commercial or open-source +# licensing. +# +# By using JUCE, you agree to the terms of both the JUCE 6 End-User License +# Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). +# +# End User License Agreement: www.juce.com/juce-6-licence +# Privacy Policy: www.juce.com/juce-privacy-policy +# +# Or: You may also use this code under the terms of the GPL v3 (see +# www.gnu.org/licenses). +# +# JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER +# EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE +# DISCLAIMED. +# +# ============================================================================== + +set(CMAKE_FOLDER examples) + +add_subdirectory(CMake) +add_subdirectory(DemoRunner) + +function(_juce_add_pips) + file(GLOB headers + CONFIGURE_DEPENDS LIST_DIRECTORIES false + "${CMAKE_CURRENT_SOURCE_DIR}/*.h") + + if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + list(REMOVE_ITEM headers + "${CMAKE_CURRENT_SOURCE_DIR}/CameraDemo.h" + "${CMAKE_CURRENT_SOURCE_DIR}/PushNotificationsDemo.h" + "${CMAKE_CURRENT_SOURCE_DIR}/VideoDemo.h") + elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows") + list(REMOVE_ITEM headers + "${CMAKE_CURRENT_SOURCE_DIR}/PushNotificationsDemo.h") + endif() + + foreach(header IN ITEMS ${headers}) + juce_add_pip(${header} added_target) + target_link_libraries(${added_target} PUBLIC + juce::juce_recommended_config_flags + juce::juce_recommended_lto_flags + juce::juce_recommended_warning_flags) + endforeach() +endfunction() + +add_subdirectory(Audio) +add_subdirectory(BLOCKS) +add_subdirectory(DSP) +add_subdirectory(GUI) +add_subdirectory(Plugins) +add_subdirectory(Utilities) diff --git a/examples/DSP/CMakeLists.txt b/examples/DSP/CMakeLists.txt new file mode 100644 index 00000000..272e8475 --- /dev/null +++ b/examples/DSP/CMakeLists.txt @@ -0,0 +1,24 @@ +# ============================================================================== +# +# This file is part of the JUCE library. +# Copyright (c) 2020 - Raw Material Software Limited +# +# JUCE is an open source library subject to commercial or open-source +# licensing. +# +# By using JUCE, you agree to the terms of both the JUCE 6 End-User License +# Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). +# +# End User License Agreement: www.juce.com/juce-6-licence +# Privacy Policy: www.juce.com/juce-privacy-policy +# +# Or: You may also use this code under the terms of the GPL v3 (see +# www.gnu.org/licenses). +# +# JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER +# EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE +# DISCLAIMED. +# +# ============================================================================== + +_juce_add_pips() diff --git a/examples/DSP/ConvolutionDemo.h b/examples/DSP/ConvolutionDemo.h index c27773b1..5aa84409 100644 --- a/examples/DSP/ConvolutionDemo.h +++ b/examples/DSP/ConvolutionDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -66,6 +66,17 @@ struct ConvolutionDemoDSP void process (ProcessContextReplacing context) { context.isBypassed = bypass; + + // Load a new IR if there's one available. Note that this doesn't lock or allocate! + bufferTransfer.get ([this] (BufferWithSampleRate& buf) + { + convolution.loadImpulseResponse (std::move (buf.buffer), + buf.sampleRate, + Convolution::Stereo::yes, + Convolution::Trim::yes, + Convolution::Normalise::yes); + }); + convolution.process (context); } @@ -76,40 +87,100 @@ struct ConvolutionDemoDSP void updateParameters() { - if (auto* cabinetTypeParameter = dynamic_cast (parameters[0])) + auto* cabinetTypeParameter = dynamic_cast (parameters[0]); + + if (cabinetTypeParameter == nullptr) + { + jassertfalse; + return; + } + + if (cabinetTypeParameter->getCurrentSelectedID() == 1) + { + bypass = true; + } + else { - if (cabinetTypeParameter->getCurrentSelectedID() == 1) + bypass = false; + + auto selectedType = cabinetTypeParameter->getCurrentSelectedID(); + auto assetName = (selectedType == 2 ? "guitar_amp.wav" : "cassette_recorder.wav"); + + auto assetInputStream = createAssetInputStream (assetName); + + if (assetInputStream == nullptr) { - bypass = true; + jassertfalse; + return; } - else - { - bypass = false; - auto maxSize = static_cast (roundToInt (sampleRate * (8192.0 / 44100.0))); - auto selectedType = cabinetTypeParameter->getCurrentSelectedID(); - auto assetName = (selectedType == 2 ? "guitar_amp.wav" : "cassette_recorder.wav"); + AudioFormatManager manager; + manager.registerBasicFormats(); + std::unique_ptr reader { manager.createReaderFor (std::move (assetInputStream)) }; - std::unique_ptr assetInputStream (createAssetInputStream (assetName)); - if (assetInputStream != nullptr) - { - currentCabinetData.reset(); - assetInputStream->readIntoMemoryBlock (currentCabinetData); - - convolution.loadImpulseResponse (currentCabinetData.getData(), currentCabinetData.getSize(), - false, true, maxSize); - } + if (reader == nullptr) + { + jassertfalse; + return; } + + AudioBuffer buffer (static_cast (reader->numChannels), + static_cast (reader->lengthInSamples)); + reader->read (buffer.getArrayOfWritePointers(), buffer.getNumChannels(), 0, buffer.getNumSamples()); + + bufferTransfer.set (BufferWithSampleRate { std::move (buffer), reader->sampleRate }); } } //============================================================================== + struct BufferWithSampleRate + { + BufferWithSampleRate() = default; + + BufferWithSampleRate (AudioBuffer&& bufferIn, double sampleRateIn) + : buffer (std::move (bufferIn)), sampleRate (sampleRateIn) {} + + AudioBuffer buffer; + double sampleRate = 0.0; + }; + + class BufferTransfer + { + public: + void set (BufferWithSampleRate&& p) + { + const SpinLock::ScopedLockType lock (mutex); + buffer = std::move (p); + newBuffer = true; + } + + // Call `fn` passing the new buffer, if there's one available + template + void get (Fn&& fn) + { + const SpinLock::ScopedTryLockType lock (mutex); + + if (lock.isLocked() && newBuffer) + { + fn (buffer); + newBuffer = false; + } + } + + private: + BufferWithSampleRate buffer; + bool newBuffer = false; + SpinLock mutex; + }; + double sampleRate = 0.0; bool bypass = false; MemoryBlock currentCabinetData; Convolution convolution; + BufferTransfer bufferTransfer; + ChoiceParameter cabinetParam { { "Bypass", "Guitar amplifier 8''", "Cassette recorder" }, 1, "Cabinet Type" }; std::vector parameters { &cabinetParam }; diff --git a/examples/DSP/FIRFilterDemo.h b/examples/DSP/FIRFilterDemo.h index 3350454b..fbe1e117 100644 --- a/examples/DSP/FIRFilterDemo.h +++ b/examples/DSP/FIRFilterDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 diff --git a/examples/DSP/GainDemo.h b/examples/DSP/GainDemo.h index a888800c..fec0b5c9 100644 --- a/examples/DSP/GainDemo.h +++ b/examples/DSP/GainDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 diff --git a/examples/DSP/IIRFilterDemo.h b/examples/DSP/IIRFilterDemo.h index 73bc3230..1234b3a0 100644 --- a/examples/DSP/IIRFilterDemo.h +++ b/examples/DSP/IIRFilterDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 diff --git a/examples/DSP/OscillatorDemo.h b/examples/DSP/OscillatorDemo.h index a564337e..9c6be00c 100644 --- a/examples/DSP/OscillatorDemo.h +++ b/examples/DSP/OscillatorDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 diff --git a/examples/DSP/OverdriveDemo.h b/examples/DSP/OverdriveDemo.h index 0c9b3d0e..c2f039aa 100644 --- a/examples/DSP/OverdriveDemo.h +++ b/examples/DSP/OverdriveDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 diff --git a/examples/DSP/SIMDRegisterDemo.h b/examples/DSP/SIMDRegisterDemo.h index 82f6c963..c327b61b 100644 --- a/examples/DSP/SIMDRegisterDemo.h +++ b/examples/DSP/SIMDRegisterDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 diff --git a/examples/DSP/StateVariableFilterDemo.h b/examples/DSP/StateVariableFilterDemo.h index 599c8bbb..db40e304 100644 --- a/examples/DSP/StateVariableFilterDemo.h +++ b/examples/DSP/StateVariableFilterDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -59,8 +59,6 @@ struct StateVariableFilterDemoDSP void prepare (const ProcessSpec& spec) { sampleRate = spec.sampleRate; - - filter.state = new StateVariableFilter::Parameters; filter.prepare (spec); } @@ -78,18 +76,21 @@ struct StateVariableFilterDemoDSP { if (sampleRate != 0.0) { - auto cutoff = static_cast (cutoffParam.getCurrentValue()); - auto resonance = static_cast (qParam.getCurrentValue()); - auto type = static_cast::Type> (typeParam.getCurrentSelectedID() - 1); - - filter.state->type = type; - filter.state->setCutOffFrequency (sampleRate, cutoff, resonance); + filter.setCutoffFrequency (static_cast (cutoffParam.getCurrentValue())); + filter.setResonance (static_cast (qParam.getCurrentValue())); + + switch (typeParam.getCurrentSelectedID() - 1) + { + case 0: filter.setType (StateVariableTPTFilterType::lowpass); break; + case 1: filter.setType (StateVariableTPTFilterType::bandpass); break; + case 2: filter.setType (StateVariableTPTFilterType::highpass); break; + default: jassertfalse; break; + }; } } //============================================================================== - ProcessorDuplicator, - StateVariableFilter::Parameters> filter; + StateVariableTPTFilter filter; ChoiceParameter typeParam {{ "Low-pass", "Band-pass", "High-pass" }, 1, "Type" }; SliderParameter cutoffParam {{ 20.0, 20000.0 }, 0.5, 440.0f, "Cutoff", "Hz" }; diff --git a/examples/DSP/WaveShaperTanhDemo.h b/examples/DSP/WaveShaperTanhDemo.h index 8c866270..5f5df793 100644 --- a/examples/DSP/WaveShaperTanhDemo.h +++ b/examples/DSP/WaveShaperTanhDemo.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 diff --git a/examples/DemoRunner/Builds/Android/app/CMakeLists.txt b/examples/DemoRunner/Builds/Android/app/CMakeLists.txt index 9f79a9c3..c3fb7461 100644 --- a/examples/DemoRunner/Builds/Android/app/CMakeLists.txt +++ b/examples/DemoRunner/Builds/Android/app/CMakeLists.txt @@ -3,12 +3,16 @@ cmake_minimum_required(VERSION 3.4.1) -SET(BINARY_NAME "juce_jni") +set(BINARY_NAME "juce_jni") + +set(OBOE_DIR "../../../../../modules/juce_audio_devices/native/oboe") + +add_subdirectory (${OBOE_DIR} ./oboe) 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.7" "-DJUCE_APP_VERSION_HEX=0x50407") +add_definitions("-DJUCE_ANDROID=1" "-DJUCE_ANDROID_API_VERSION=23" "-DJUCE_PUSH_NOTIFICATIONS=1" "-DJUCE_PUSH_NOTIFICATIONS_ACTIVITY=\"com/rmsl/juce/JuceActivity\"" "-DJUCE_CONTENT_SHARING=1" "-DJUCE_ANDROID_GL_ES_VERSION_3_0=1" "-DJUCE_DEMO_RUNNER=1" "-DJUCE_UNIT_TESTS=1" "-DJUCER_ANDROIDSTUDIO_7F0E4A25=1" "-DJUCE_APP_VERSION=6.0.5" "-DJUCE_APP_VERSION_HEX=0x60005") include_directories( AFTER "../../../JuceLibraryCode" @@ -18,13 +22,13 @@ include_directories( AFTER enable_language(ASM) -IF(JUCE_BUILD_CONFIGURATION MATCHES "DEBUG") - add_definitions("-DDEBUG=1" "-D_DEBUG=1") -ELSEIF(JUCE_BUILD_CONFIGURATION MATCHES "RELEASE") - add_definitions("-DNDEBUG=1") -ELSE(JUCE_BUILD_CONFIGURATION MATCHES "DEBUG") - MESSAGE( FATAL_ERROR "No matching build-configuration found." ) -ENDIF(JUCE_BUILD_CONFIGURATION MATCHES "DEBUG") +if(JUCE_BUILD_CONFIGURATION MATCHES "DEBUG") + add_definitions("-DJUCE_DISPLAY_SPLASH_SCREEN=0" "-DJUCE_USE_DARK_SPLASH_SCREEN=1" "-DJUCE_PROJUCER_VERSION=0x60005" "-DJUCE_MODULE_AVAILABLE_juce_analytics=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_devices=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_formats=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_processors=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_utils=1" "-DJUCE_MODULE_AVAILABLE_juce_blocks_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_box2d=1" "-DJUCE_MODULE_AVAILABLE_juce_core=1" "-DJUCE_MODULE_AVAILABLE_juce_cryptography=1" "-DJUCE_MODULE_AVAILABLE_juce_data_structures=1" "-DJUCE_MODULE_AVAILABLE_juce_dsp=1" "-DJUCE_MODULE_AVAILABLE_juce_events=1" "-DJUCE_MODULE_AVAILABLE_juce_graphics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_extra=1" "-DJUCE_MODULE_AVAILABLE_juce_opengl=1" "-DJUCE_MODULE_AVAILABLE_juce_osc=1" "-DJUCE_MODULE_AVAILABLE_juce_product_unlocking=1" "-DJUCE_MODULE_AVAILABLE_juce_video=1" "-DJUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1" "-DJUCE_USE_MP3AUDIOFORMAT=1" "-DJUCE_ALLOW_STATIC_NULL_VARIABLES=0" "-DJUCE_STRICT_REFCOUNTEDPOINTER=1" "-DJUCE_USE_CAMERA=1" "-DJUCE_STANDALONE_APPLICATION=1" "-DJUCE_DEMO_RUNNER=1" "-DJUCE_UNIT_TESTS=1" "-DJUCER_ANDROIDSTUDIO_7F0E4A25=1" "-DJUCE_APP_VERSION=6.0.5" "-DJUCE_APP_VERSION_HEX=0x60005" "-DDEBUG=1" "-D_DEBUG=1") +elseif(JUCE_BUILD_CONFIGURATION MATCHES "RELEASE") + add_definitions("-DJUCE_DISPLAY_SPLASH_SCREEN=0" "-DJUCE_USE_DARK_SPLASH_SCREEN=1" "-DJUCE_PROJUCER_VERSION=0x60005" "-DJUCE_MODULE_AVAILABLE_juce_analytics=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_devices=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_formats=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_processors=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_utils=1" "-DJUCE_MODULE_AVAILABLE_juce_blocks_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_box2d=1" "-DJUCE_MODULE_AVAILABLE_juce_core=1" "-DJUCE_MODULE_AVAILABLE_juce_cryptography=1" "-DJUCE_MODULE_AVAILABLE_juce_data_structures=1" "-DJUCE_MODULE_AVAILABLE_juce_dsp=1" "-DJUCE_MODULE_AVAILABLE_juce_events=1" "-DJUCE_MODULE_AVAILABLE_juce_graphics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_extra=1" "-DJUCE_MODULE_AVAILABLE_juce_opengl=1" "-DJUCE_MODULE_AVAILABLE_juce_osc=1" "-DJUCE_MODULE_AVAILABLE_juce_product_unlocking=1" "-DJUCE_MODULE_AVAILABLE_juce_video=1" "-DJUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1" "-DJUCE_USE_MP3AUDIOFORMAT=1" "-DJUCE_ALLOW_STATIC_NULL_VARIABLES=0" "-DJUCE_STRICT_REFCOUNTEDPOINTER=1" "-DJUCE_USE_CAMERA=1" "-DJUCE_STANDALONE_APPLICATION=1" "-DJUCE_DEMO_RUNNER=1" "-DJUCE_UNIT_TESTS=1" "-DJUCER_ANDROIDSTUDIO_7F0E4A25=1" "-DJUCE_APP_VERSION=6.0.5" "-DJUCE_APP_VERSION_HEX=0x60005" "-DNDEBUG=1") +else() + message( FATAL_ERROR "No matching build-configuration found." ) +endif() add_library( ${BINARY_NAME} @@ -113,16 +117,17 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp" "../../../../../modules/juce_audio_basics/synthesisers/juce_Synthesiser.h" "../../../../../modules/juce_audio_basics/utilities/juce_ADSR.h" - "../../../../../modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.cpp" - "../../../../../modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.h" "../../../../../modules/juce_audio_basics/utilities/juce_Decibels.h" + "../../../../../modules/juce_audio_basics/utilities/juce_GenericInterpolator.h" "../../../../../modules/juce_audio_basics/utilities/juce_IIRFilter.cpp" "../../../../../modules/juce_audio_basics/utilities/juce_IIRFilter.h" + "../../../../../modules/juce_audio_basics/utilities/juce_Interpolators.cpp" + "../../../../../modules/juce_audio_basics/utilities/juce_Interpolators.h" "../../../../../modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.cpp" - "../../../../../modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.h" "../../../../../modules/juce_audio_basics/utilities/juce_Reverb.h" "../../../../../modules/juce_audio_basics/utilities/juce_SmoothedValue.cpp" "../../../../../modules/juce_audio_basics/utilities/juce_SmoothedValue.h" + "../../../../../modules/juce_audio_basics/utilities/juce_WindowedSincInterpolator.cpp" "../../../../../modules/juce_audio_basics/juce_audio_basics.cpp" "../../../../../modules/juce_audio_basics/juce_audio_basics.mm" "../../../../../modules/juce_audio_basics/juce_audio_basics.h" @@ -137,7 +142,118 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_devices/midi_io/juce_MidiDevices.h" "../../../../../modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.cpp" "../../../../../modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStream.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamBase.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamBuilder.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamCallback.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Definitions.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/LatencyTuner.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Oboe.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/ResultWithValue.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/StabilizedCallback.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Utilities.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Version.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AAudioLoader.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AAudioLoader.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioClock.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioSourceCaller.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioSourceCaller.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioStream.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioStreamBuilder.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/DataConversionFlowGraph.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/DataConversionFlowGraph.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/FilterAudioStream.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/FilterAudioStream.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockAdapter.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockAdapter.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockReader.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockReader.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockWriter.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockWriter.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/LatencyTuner.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/MonotonicCounter.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/OboeDebug.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/QuirksManager.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/QuirksManager.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceFloatCaller.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceFloatCaller.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceI16Caller.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceI16Caller.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/StabilizedCallback.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/Trace.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/Trace.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/Utilities.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/Version.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoController.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoController.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/HyperbolicCosineWindow.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/IntegerRatio.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/IntegerRatio.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/KaiserWindow.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/LinearResampler.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/LinearResampler.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/MultiChannelResampler.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/MultiChannelResampler.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResampler.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResampler.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResamplerStereo.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResamplerStereo.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ClipToRange.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ClipToRange.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/RampLinear.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/RampLinear.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SampleRateConverter.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SampleRateConverter.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkFloat.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkFloat.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI16.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI16.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI24.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI24.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceFloat.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceFloat.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI16.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI16.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI24.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI24.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioInputStreamOpenSLES.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioInputStreamOpenSLES.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioOutputStreamOpenSLES.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioOutputStreamOpenSLES.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamBuffered.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamBuffered.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamOpenSLES.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamOpenSLES.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/EngineOpenSLES.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/EngineOpenSLES.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/OpenSLESUtilities.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/OpenSLESUtilities.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/OutputMixerOpenSLES.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/opensles/OutputMixerOpenSLES.h" + "../../../../../modules/juce_audio_devices/native/oboe/CMakeLists.txt" + "../../../../../modules/juce_audio_devices/native/oboe/readme.md" "../../../../../modules/juce_audio_devices/native/juce_android_Audio.cpp" + "../../../../../modules/juce_audio_devices/native/juce_android_HighPerformanceAudioHelpers.h" "../../../../../modules/juce_audio_devices/native/juce_android_Midi.cpp" "../../../../../modules/juce_audio_devices/native/juce_android_Oboe.cpp" "../../../../../modules/juce_audio_devices/native/juce_android_OpenSL.cpp" @@ -209,73 +325,76 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_formats/codecs/flac/stream_decoder.h" "../../../../../modules/juce_audio_formats/codecs/flac/stream_encoder.h" "../../../../../modules/juce_audio_formats/codecs/flac/win_utf8_io.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/books/coupled/res_books_51.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/books/coupled/res_books_stereo.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/books/floor/floor_books.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/books/uncoupled/res_books_uncoupled.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/floor_all.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/psych_8.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/psych_11.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/psych_16.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/psych_44.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_8.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_16.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_44.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_44p51.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_44u.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_8.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_11.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_16.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_22.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_32.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_44.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_44p51.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_44u.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_X.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/analysis.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/backends.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/bitrate.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/bitrate.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/block.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/codebook.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/codebook.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/codec_internal.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/envelope.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/envelope.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/floor0.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/floor1.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/highlevel.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/info.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lookup.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lookup.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lookup_data.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lpc.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lpc.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lsp.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lsp.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/mapping0.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/masking.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/mdct.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/mdct.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/misc.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/os.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/psy.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/psy.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/registry.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/registry.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/res0.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/scales.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/sharedbook.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/smallft.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/smallft.h" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/synthesis.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/vorbisenc.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/vorbisfile.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/window.c" - "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/window.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/books/coupled/res_books_51.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/books/coupled/res_books_stereo.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/books/floor/floor_books.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/books/uncoupled/res_books_uncoupled.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/floor_all.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/psych_8.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/psych_11.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/psych_16.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/psych_44.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/residue_8.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/residue_16.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/residue_44.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/residue_44p51.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/residue_44u.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_8.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_11.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_16.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_22.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_32.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_44.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_44p51.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_44u.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_X.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/analysis.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/backends.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/bitrate.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/bitrate.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/block.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/codebook.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/codebook.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/codec_internal.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/envelope.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/envelope.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/floor0.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/floor1.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/highlevel.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/info.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lookup.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lookup.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lookup_data.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lpc.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lpc.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lsp.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lsp.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/mapping0.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/masking.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/mdct.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/mdct.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/misc.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/misc.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/os.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/psy.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/psy.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/registry.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/registry.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/res0.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/scales.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/sharedbook.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/smallft.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/smallft.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/synthesis.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/vorbisenc.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/vorbisfile.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/window.c" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/window.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/README.md" "../../../../../modules/juce_audio_formats/codecs/oggvorbis/bitwise.c" "../../../../../modules/juce_audio_formats/codecs/oggvorbis/codec.h" "../../../../../modules/juce_audio_formats/codecs/oggvorbis/config_types.h" + "../../../../../modules/juce_audio_formats/codecs/oggvorbis/crctable.h" "../../../../../modules/juce_audio_formats/codecs/oggvorbis/framing.c" "../../../../../modules/juce_audio_formats/codecs/oggvorbis/Ogg Vorbis Licence.txt" "../../../../../modules/juce_audio_formats/codecs/oggvorbis/ogg.h" @@ -465,6 +584,8 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.h" "../../../../../modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp" "../../../../../modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h" + "../../../../../modules/juce_audio_processors/utilities/juce_ParameterAttachments.cpp" + "../../../../../modules/juce_audio_processors/utilities/juce_ParameterAttachments.h" "../../../../../modules/juce_audio_processors/utilities/juce_RangedAudioParameter.cpp" "../../../../../modules/juce_audio_processors/utilities/juce_RangedAudioParameter.h" "../../../../../modules/juce_audio_processors/juce_audio_processors.cpp" @@ -686,6 +807,8 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_core/files/juce_FileSearchPath.cpp" "../../../../../modules/juce_core/files/juce_FileSearchPath.h" "../../../../../modules/juce_core/files/juce_MemoryMappedFile.h" + "../../../../../modules/juce_core/files/juce_RangedDirectoryIterator.cpp" + "../../../../../modules/juce_core/files/juce_RangedDirectoryIterator.h" "../../../../../modules/juce_core/files/juce_TemporaryFile.cpp" "../../../../../modules/juce_core/files/juce_TemporaryFile.h" "../../../../../modules/juce_core/files/juce_WildcardFileFilter.cpp" @@ -708,6 +831,8 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_core/maths/juce_Random.h" "../../../../../modules/juce_core/maths/juce_Range.h" "../../../../../modules/juce_core/maths/juce_StatisticsAccumulator.h" + "../../../../../modules/juce_core/memory/juce_AllocationHooks.cpp" + "../../../../../modules/juce_core/memory/juce_AllocationHooks.h" "../../../../../modules/juce_core/memory/juce_Atomic.h" "../../../../../modules/juce_core/memory/juce_ByteOrder.h" "../../../../../modules/juce_core/memory/juce_ContainerDeletePolicy.h" @@ -794,6 +919,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_core/streams/juce_URLInputSource.cpp" "../../../../../modules/juce_core/streams/juce_URLInputSource.h" "../../../../../modules/juce_core/system/juce_CompilerSupport.h" + "../../../../../modules/juce_core/system/juce_CompilerWarnings.h" "../../../../../modules/juce_core/system/juce_PlatformDefs.h" "../../../../../modules/juce_core/system/juce_StandardHeader.h" "../../../../../modules/juce_core/system/juce_SystemStats.cpp" @@ -927,6 +1053,8 @@ add_library( ${BINARY_NAME} "../../../../../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_FixedSizeFunction.h" + "../../../../../modules/juce_dsp/containers/juce_FixedSizeFunction_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" @@ -934,6 +1062,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_dsp/filter_design/juce_FilterDesign.h" "../../../../../modules/juce_dsp/frequency/juce_Convolution.cpp" "../../../../../modules/juce_dsp/frequency/juce_Convolution.h" + "../../../../../modules/juce_dsp/frequency/juce_Convolution_test.cpp" "../../../../../modules/juce_dsp/frequency/juce_FFT.cpp" "../../../../../modules/juce_dsp/frequency/juce_FFT.h" "../../../../../modules/juce_dsp/frequency/juce_FFT_test.cpp" @@ -958,26 +1087,51 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_dsp/native/juce_neon_SIMDNativeOps.h" "../../../../../modules/juce_dsp/native/juce_sse_SIMDNativeOps.cpp" "../../../../../modules/juce_dsp/native/juce_sse_SIMDNativeOps.h" - "../../../../../modules/juce_dsp/processors/juce_Bias.h" + "../../../../../modules/juce_dsp/processors/juce_BallisticsFilter.cpp" + "../../../../../modules/juce_dsp/processors/juce_BallisticsFilter.h" + "../../../../../modules/juce_dsp/processors/juce_DelayLine.cpp" + "../../../../../modules/juce_dsp/processors/juce_DelayLine.h" + "../../../../../modules/juce_dsp/processors/juce_DryWetMixer.cpp" + "../../../../../modules/juce_dsp/processors/juce_DryWetMixer.h" "../../../../../modules/juce_dsp/processors/juce_FIRFilter.cpp" "../../../../../modules/juce_dsp/processors/juce_FIRFilter.h" "../../../../../modules/juce_dsp/processors/juce_FIRFilter_test.cpp" - "../../../../../modules/juce_dsp/processors/juce_Gain.h" + "../../../../../modules/juce_dsp/processors/juce_FirstOrderTPTFilter.cpp" + "../../../../../modules/juce_dsp/processors/juce_FirstOrderTPTFilter.h" "../../../../../modules/juce_dsp/processors/juce_IIRFilter.cpp" "../../../../../modules/juce_dsp/processors/juce_IIRFilter.h" "../../../../../modules/juce_dsp/processors/juce_IIRFilter_Impl.h" - "../../../../../modules/juce_dsp/processors/juce_LadderFilter.cpp" - "../../../../../modules/juce_dsp/processors/juce_LadderFilter.h" - "../../../../../modules/juce_dsp/processors/juce_Oscillator.h" + "../../../../../modules/juce_dsp/processors/juce_LinkwitzRileyFilter.cpp" + "../../../../../modules/juce_dsp/processors/juce_LinkwitzRileyFilter.h" "../../../../../modules/juce_dsp/processors/juce_Oversampling.cpp" "../../../../../modules/juce_dsp/processors/juce_Oversampling.h" + "../../../../../modules/juce_dsp/processors/juce_Panner.cpp" + "../../../../../modules/juce_dsp/processors/juce_Panner.h" "../../../../../modules/juce_dsp/processors/juce_ProcessContext.h" "../../../../../modules/juce_dsp/processors/juce_ProcessorChain.h" + "../../../../../modules/juce_dsp/processors/juce_ProcessorChain_test.cpp" "../../../../../modules/juce_dsp/processors/juce_ProcessorDuplicator.h" "../../../../../modules/juce_dsp/processors/juce_ProcessorWrapper.h" - "../../../../../modules/juce_dsp/processors/juce_Reverb.h" "../../../../../modules/juce_dsp/processors/juce_StateVariableFilter.h" - "../../../../../modules/juce_dsp/processors/juce_WaveShaper.h" + "../../../../../modules/juce_dsp/processors/juce_StateVariableTPTFilter.cpp" + "../../../../../modules/juce_dsp/processors/juce_StateVariableTPTFilter.h" + "../../../../../modules/juce_dsp/widgets/juce_Bias.h" + "../../../../../modules/juce_dsp/widgets/juce_Chorus.cpp" + "../../../../../modules/juce_dsp/widgets/juce_Chorus.h" + "../../../../../modules/juce_dsp/widgets/juce_Compressor.cpp" + "../../../../../modules/juce_dsp/widgets/juce_Compressor.h" + "../../../../../modules/juce_dsp/widgets/juce_Gain.h" + "../../../../../modules/juce_dsp/widgets/juce_LadderFilter.cpp" + "../../../../../modules/juce_dsp/widgets/juce_LadderFilter.h" + "../../../../../modules/juce_dsp/widgets/juce_Limiter.cpp" + "../../../../../modules/juce_dsp/widgets/juce_Limiter.h" + "../../../../../modules/juce_dsp/widgets/juce_NoiseGate.cpp" + "../../../../../modules/juce_dsp/widgets/juce_NoiseGate.h" + "../../../../../modules/juce_dsp/widgets/juce_Oscillator.h" + "../../../../../modules/juce_dsp/widgets/juce_Phaser.cpp" + "../../../../../modules/juce_dsp/widgets/juce_Phaser.h" + "../../../../../modules/juce_dsp/widgets/juce_Reverb.h" + "../../../../../modules/juce_dsp/widgets/juce_WaveShaper.h" "../../../../../modules/juce_dsp/juce_dsp.cpp" "../../../../../modules/juce_dsp/juce_dsp.mm" "../../../../../modules/juce_dsp/juce_dsp.h" @@ -1374,6 +1528,11 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_gui_basics/mouse/juce_SelectedItemSet.h" "../../../../../modules/juce_gui_basics/mouse/juce_TextDragAndDropTarget.h" "../../../../../modules/juce_gui_basics/mouse/juce_TooltipClient.h" + "../../../../../modules/juce_gui_basics/native/x11/juce_linux_X11_DragAndDrop.cpp" + "../../../../../modules/juce_gui_basics/native/x11/juce_linux_X11_Symbols.cpp" + "../../../../../modules/juce_gui_basics/native/x11/juce_linux_X11_Symbols.h" + "../../../../../modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.cpp" + "../../../../../modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.h" "../../../../../modules/juce_gui_basics/native/juce_android_ContentSharer.cpp" "../../../../../modules/juce_gui_basics/native/juce_android_FileChooser.cpp" "../../../../../modules/juce_gui_basics/native/juce_android_Windowing.cpp" @@ -1383,10 +1542,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm" "../../../../../modules/juce_gui_basics/native/juce_ios_Windowing.mm" "../../../../../modules/juce_gui_basics/native/juce_linux_FileChooser.cpp" - "../../../../../modules/juce_gui_basics/native/juce_linux_X11.cpp" - "../../../../../modules/juce_gui_basics/native/juce_linux_X11.h" - "../../../../../modules/juce_gui_basics/native/juce_linux_X11_Clipboard.cpp" - "../../../../../modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp" + "../../../../../modules/juce_gui_basics/native/juce_linux_Windowing.cpp" "../../../../../modules/juce_gui_basics/native/juce_mac_FileChooser.mm" "../../../../../modules/juce_gui_basics/native/juce_mac_MainMenu.mm" "../../../../../modules/juce_gui_basics/native/juce_mac_MouseCursor.mm" @@ -1491,6 +1647,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.h" "../../../../../modules/juce_gui_extra/embedding/juce_ActiveXControlComponent.h" "../../../../../modules/juce_gui_extra/embedding/juce_AndroidViewComponent.h" + "../../../../../modules/juce_gui_extra/embedding/juce_HWNDComponent.h" "../../../../../modules/juce_gui_extra/embedding/juce_NSViewComponent.h" "../../../../../modules/juce_gui_extra/embedding/juce_ScopedDPIAwarenessDisabler.h" "../../../../../modules/juce_gui_extra/embedding/juce_UIViewComponent.h" @@ -1532,6 +1689,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_gui_extra/native/juce_mac_SystemTrayIcon.cpp" "../../../../../modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm" "../../../../../modules/juce_gui_extra/native/juce_win32_ActiveXComponent.cpp" + "../../../../../modules/juce_gui_extra/native/juce_win32_HWNDComponent.cpp" "../../../../../modules/juce_gui_extra/native/juce_win32_SystemTrayIcon.cpp" "../../../../../modules/juce_gui_extra/native/juce_win32_WebBrowserComponent.cpp" "../../../../../modules/juce_gui_extra/juce_gui_extra.cpp" @@ -1616,7 +1774,6 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_video/juce_video.cpp" "../../../../../modules/juce_video/juce_video.mm" "../../../../../modules/juce_video/juce_video.h" - "../../../JuceLibraryCode/AppConfig.h" "../../../JuceLibraryCode/include_juce_analytics.cpp" "../../../JuceLibraryCode/include_juce_audio_basics.cpp" "../../../JuceLibraryCode/include_juce_audio_devices.cpp" @@ -1717,16 +1874,17 @@ set_source_files_properties("../../../../../modules/juce_audio_basics/sources/ju set_source_files_properties("../../../../../modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/synthesisers/juce_Synthesiser.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_ADSR.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_CatmullRomInterpolator.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_Decibels.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_GenericInterpolator.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_IIRFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_IIRFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_Interpolators.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_Interpolators.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_LagrangeInterpolator.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_Reverb.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_SmoothedValue.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_SmoothedValue.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_basics/utilities/juce_WindowedSincInterpolator.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/juce_audio_basics.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/juce_audio_basics.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_basics/juce_audio_basics.h" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -1741,7 +1899,118 @@ set_source_files_properties("../../../../../modules/juce_audio_devices/midi_io/j set_source_files_properties("../../../../../modules/juce_audio_devices/midi_io/juce_MidiDevices.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStream.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamBase.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamBuilder.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamCallback.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Definitions.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/LatencyTuner.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Oboe.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/ResultWithValue.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/StabilizedCallback.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Utilities.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Version.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AAudioLoader.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AAudioLoader.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioClock.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioSourceCaller.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioSourceCaller.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioStream.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioStreamBuilder.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/DataConversionFlowGraph.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/DataConversionFlowGraph.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/FilterAudioStream.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/FilterAudioStream.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockAdapter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockAdapter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockReader.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockReader.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockWriter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/FixedBlockWriter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/LatencyTuner.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/MonotonicCounter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/OboeDebug.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/QuirksManager.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/QuirksManager.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceFloatCaller.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceFloatCaller.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceI16Caller.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceI16Caller.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/StabilizedCallback.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/Trace.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/Trace.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/Utilities.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/common/Version.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoController.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoController.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/HyperbolicCosineWindow.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/IntegerRatio.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/IntegerRatio.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/KaiserWindow.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/LinearResampler.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/LinearResampler.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/MultiChannelResampler.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/MultiChannelResampler.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResampler.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResampler.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResamplerStereo.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResamplerStereo.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ClipToRange.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ClipToRange.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/RampLinear.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/RampLinear.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SampleRateConverter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SampleRateConverter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkFloat.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkFloat.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI16.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI16.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI24.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI24.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceFloat.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceFloat.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI16.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI16.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI24.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI24.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioInputStreamOpenSLES.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioInputStreamOpenSLES.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioOutputStreamOpenSLES.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioOutputStreamOpenSLES.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamBuffered.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamBuffered.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamOpenSLES.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamOpenSLES.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/EngineOpenSLES.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/EngineOpenSLES.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/OpenSLESUtilities.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/OpenSLESUtilities.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/OutputMixerOpenSLES.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/src/opensles/OutputMixerOpenSLES.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/CMakeLists.txt" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/oboe/readme.md" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_android_Audio.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_android_HighPerformanceAudioHelpers.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_android_Midi.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_android_Oboe.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_devices/native/juce_android_OpenSL.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -1813,73 +2082,76 @@ set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/fl set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/stream_decoder.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/stream_encoder.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/flac/win_utf8_io.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/books/coupled/res_books_51.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/books/coupled/res_books_stereo.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/books/floor/floor_books.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/books/uncoupled/res_books_uncoupled.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/floor_all.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/psych_8.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/psych_11.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/psych_16.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/psych_44.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_8.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_16.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_44.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_44p51.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/residue_44u.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_8.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_11.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_16.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_22.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_32.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_44.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_44p51.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_44u.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/modes/setup_X.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/analysis.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/backends.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/bitrate.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/bitrate.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/block.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/codebook.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/codebook.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/codec_internal.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/envelope.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/envelope.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/floor0.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/floor1.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/highlevel.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/info.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lookup.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lookup.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lookup_data.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lpc.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lpc.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lsp.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/lsp.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/mapping0.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/masking.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/mdct.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/mdct.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/misc.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/os.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/psy.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/psy.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/registry.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/registry.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/res0.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/scales.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/sharedbook.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/smallft.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/smallft.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/synthesis.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/vorbisenc.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/vorbisfile.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/window.c" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/window.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/books/coupled/res_books_51.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/books/coupled/res_books_stereo.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/books/floor/floor_books.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/books/uncoupled/res_books_uncoupled.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/floor_all.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/psych_8.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/psych_11.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/psych_16.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/psych_44.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/residue_8.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/residue_16.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/residue_44.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/residue_44p51.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/residue_44u.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_8.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_11.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_16.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_22.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_32.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_44.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_44p51.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_44u.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/modes/setup_X.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/analysis.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/backends.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/bitrate.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/bitrate.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/block.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/codebook.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/codebook.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/codec_internal.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/envelope.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/envelope.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/floor0.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/floor1.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/highlevel.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/info.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lookup.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lookup.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lookup_data.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lpc.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lpc.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lsp.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/lsp.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/mapping0.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/masking.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/mdct.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/mdct.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/misc.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/misc.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/os.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/psy.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/psy.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/registry.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/registry.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/res0.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/scales.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/sharedbook.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/smallft.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/smallft.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/synthesis.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/vorbisenc.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/vorbisfile.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/window.c" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/window.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/README.md" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/bitwise.c" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/codec.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/config_types.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/crctable.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/framing.c" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/Ogg Vorbis Licence.txt" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_formats/codecs/oggvorbis/ogg.h" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -2069,6 +2341,8 @@ set_source_files_properties("../../../../../modules/juce_audio_processors/utilit set_source_files_properties("../../../../../modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_processors/utilities/juce_ParameterAttachments.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_audio_processors/utilities/juce_ParameterAttachments.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_processors/utilities/juce_RangedAudioParameter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_processors/utilities/juce_RangedAudioParameter.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_audio_processors/juce_audio_processors.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -2290,6 +2564,8 @@ set_source_files_properties("../../../../../modules/juce_core/files/juce_FileOut set_source_files_properties("../../../../../modules/juce_core/files/juce_FileSearchPath.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/files/juce_FileSearchPath.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/files/juce_MemoryMappedFile.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_core/files/juce_RangedDirectoryIterator.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_core/files/juce_RangedDirectoryIterator.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/files/juce_TemporaryFile.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/files/juce_TemporaryFile.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/files/juce_WildcardFileFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -2312,6 +2588,8 @@ set_source_files_properties("../../../../../modules/juce_core/maths/juce_Random. set_source_files_properties("../../../../../modules/juce_core/maths/juce_Random.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/maths/juce_Range.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/maths/juce_StatisticsAccumulator.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_core/memory/juce_AllocationHooks.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_core/memory/juce_AllocationHooks.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/memory/juce_Atomic.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/memory/juce_ByteOrder.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/memory/juce_ContainerDeletePolicy.h" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -2398,6 +2676,7 @@ set_source_files_properties("../../../../../modules/juce_core/streams/juce_Subre set_source_files_properties("../../../../../modules/juce_core/streams/juce_URLInputSource.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/streams/juce_URLInputSource.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/system/juce_CompilerSupport.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_core/system/juce_CompilerWarnings.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/system/juce_PlatformDefs.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/system/juce_StandardHeader.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_core/system/juce_SystemStats.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -2531,6 +2810,8 @@ set_source_files_properties("../../../../../modules/juce_data_structures/juce_da 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_FixedSizeFunction.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/containers/juce_FixedSizeFunction_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) @@ -2538,6 +2819,7 @@ set_source_files_properties("../../../../../modules/juce_dsp/filter_design/juce_ set_source_files_properties("../../../../../modules/juce_dsp/filter_design/juce_FilterDesign.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/frequency/juce_Convolution.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/frequency/juce_Convolution.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/frequency/juce_Convolution_test.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/frequency/juce_FFT.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/frequency/juce_FFT.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/frequency/juce_FFT_test.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -2562,26 +2844,51 @@ set_source_files_properties("../../../../../modules/juce_dsp/native/juce_neon_SI set_source_files_properties("../../../../../modules/juce_dsp/native/juce_neon_SIMDNativeOps.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/native/juce_sse_SIMDNativeOps.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/native/juce_sse_SIMDNativeOps.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_Bias.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_BallisticsFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_BallisticsFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_DelayLine.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_DelayLine.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_DryWetMixer.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_DryWetMixer.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_FIRFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_FIRFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_FIRFilter_test.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_Gain.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_FirstOrderTPTFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_FirstOrderTPTFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_IIRFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_IIRFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_IIRFilter_Impl.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_LadderFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_LadderFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_Oscillator.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_LinkwitzRileyFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_LinkwitzRileyFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_Oversampling.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_Oversampling.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_Panner.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_Panner.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_ProcessContext.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_ProcessorChain.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_ProcessorChain_test.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_ProcessorDuplicator.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_ProcessorWrapper.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_Reverb.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_StateVariableFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_WaveShaper.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_StateVariableTPTFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/processors/juce_StateVariableTPTFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Bias.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Chorus.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Chorus.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Compressor.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Compressor.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Gain.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_LadderFilter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_LadderFilter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Limiter.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Limiter.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_NoiseGate.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_NoiseGate.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Oscillator.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Phaser.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Phaser.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_Reverb.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_dsp/widgets/juce_WaveShaper.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/juce_dsp.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/juce_dsp.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_dsp/juce_dsp.h" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -2978,6 +3285,11 @@ set_source_files_properties("../../../../../modules/juce_gui_basics/mouse/juce_M set_source_files_properties("../../../../../modules/juce_gui_basics/mouse/juce_SelectedItemSet.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/mouse/juce_TextDragAndDropTarget.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/mouse/juce_TooltipClient.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_gui_basics/native/x11/juce_linux_X11_DragAndDrop.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_gui_basics/native/x11/juce_linux_X11_Symbols.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_gui_basics/native/x11/juce_linux_X11_Symbols.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_android_ContentSharer.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_android_FileChooser.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_android_Windowing.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -2987,10 +3299,7 @@ set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_ set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_ios_Windowing.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_linux_FileChooser.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_linux_X11.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_linux_X11.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_linux_X11_Clipboard.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_linux_Windowing.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_mac_FileChooser.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_mac_MainMenu.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_mac_MouseCursor.mm" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -3095,6 +3404,7 @@ set_source_files_properties("../../../../../modules/juce_gui_extra/documents/juc set_source_files_properties("../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/embedding/juce_ActiveXControlComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/embedding/juce_AndroidViewComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_gui_extra/embedding/juce_HWNDComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/embedding/juce_NSViewComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/embedding/juce_ScopedDPIAwarenessDisabler.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/embedding/juce_UIViewComponent.h" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -3136,6 +3446,7 @@ set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_m set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_mac_SystemTrayIcon.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_win32_ActiveXComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_win32_HWNDComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_win32_SystemTrayIcon.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/native/juce_win32_WebBrowserComponent.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_extra/juce_gui_extra.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) @@ -3220,9 +3531,18 @@ set_source_files_properties("../../../../../modules/juce_video/playback/juce_Vid set_source_files_properties("../../../../../modules/juce_video/juce_video.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_video/juce_video.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_video/juce_video.h" PROPERTIES HEADER_FILE_ONLY TRUE) -set_source_files_properties("../../../JuceLibraryCode/AppConfig.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../JuceLibraryCode/JuceHeader.h" PROPERTIES HEADER_FILE_ONLY TRUE) +target_compile_options( ${BINARY_NAME} PRIVATE "-fsigned-char" ) + +if( JUCE_BUILD_CONFIGURATION MATCHES "DEBUG" ) + target_compile_options( ${BINARY_NAME} PRIVATE -Wall -Wshadow-all -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wunreachable-code -Wzero-as-null-pointer-constant -Wcast-align -Winconsistent-missing-destructor-override -Wshift-sign-overflow -Wnullable-to-nonnull-conversion -Wno-missing-field-initializers -Wno-ignored-qualifiers -Wswitch-enum) +endif() + +if( JUCE_BUILD_CONFIGURATION MATCHES "RELEASE" ) + target_compile_options( ${BINARY_NAME} PRIVATE -Wall -Wshadow-all -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wunreachable-code -Wzero-as-null-pointer-constant -Wcast-align -Winconsistent-missing-destructor-override -Wshift-sign-overflow -Wnullable-to-nonnull-conversion -Wno-missing-field-initializers -Wno-ignored-qualifiers -Wswitch-enum) +endif() + find_library(log "log") find_library(android "android") find_library(glesv3 "GLESv3") @@ -3235,4 +3555,5 @@ target_link_libraries( ${BINARY_NAME} ${glesv3} ${egl} "cpufeatures" + "oboe" ) diff --git a/examples/DemoRunner/Builds/Android/app/build.gradle b/examples/DemoRunner/Builds/Android/app/build.gradle index 0081e10b..555995ee 100644 --- a/examples/DemoRunner/Builds/Android/app/build.gradle +++ b/examples/DemoRunner/Builds/Android/app/build.gradle @@ -1,7 +1,7 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 28 + compileSdkVersion 29 externalNativeBuild { cmake { path "CMakeLists.txt" @@ -18,14 +18,12 @@ android { } defaultConfig { - applicationId "com.juce.demorunner" + applicationId "com.rmsl.juce.demorunner" minSdkVersion 23 - targetSdkVersion 28 + targetSdkVersion 29 externalNativeBuild { cmake { - arguments "-DANDROID_TOOLCHAIN=clang", "-DANDROID_PLATFORM=android-23", "-DANDROID_STL=c++_static", "-DANDROID_CPP_FEATURES=exceptions rtti", "-DANDROID_ARM_MODE=arm", "-DANDROID_ARM_NEON=TRUE" - cFlags "-fsigned-char" - cppFlags "-fsigned-char", "-std=c++14" + arguments "-DANDROID_TOOLCHAIN=clang", "-DANDROID_PLATFORM=android-23", "-DANDROID_STL=c++_static", "-DANDROID_CPP_FEATURES=exceptions rtti", "-DANDROID_ARM_MODE=arm", "-DANDROID_ARM_NEON=TRUE", "-DCMAKE_CXX_STANDARD=14", "-DCMAKE_CXX_EXTENSIONS=OFF" } } } @@ -49,11 +47,11 @@ android { productFlavors { debug_ { ndk { - abiFilters "armeabi-v7a", "x86" + abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64" } externalNativeBuild { cmake { - arguments "-DJUCE_BUILD_CONFIGURATION=DEBUG", "-DCMAKE_CXX_FLAGS_DEBUG=-O0 -Wall -Wshadow-all -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wunreachable-code -Wzero-as-null-pointer-constant -Wcast-align -Winconsistent-missing-destructor-override -Wshift-sign-overflow -Wnullable-to-nonnull-conversion -Wno-missing-field-initializers -Wno-ignored-qualifiers", "-DCMAKE_C_FLAGS_DEBUG=-O0" + arguments "-DJUCE_BUILD_CONFIGURATION=DEBUG", "-DCMAKE_CXX_FLAGS_DEBUG=-O0", "-DCMAKE_C_FLAGS_DEBUG=-O0" } } @@ -62,7 +60,7 @@ android { release_ { externalNativeBuild { cmake { - arguments "-DJUCE_BUILD_CONFIGURATION=RELEASE", "-DCMAKE_CXX_FLAGS_RELEASE=-O3 -Wall -Wshadow-all -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion -Wconditional-uninitialized -Woverloaded-virtual -Wreorder -Wconstant-conversion -Wsign-conversion -Wunused-private-field -Wbool-conversion -Wextra-semi -Wunreachable-code -Wzero-as-null-pointer-constant -Wcast-align -Winconsistent-missing-destructor-override -Wshift-sign-overflow -Wnullable-to-nonnull-conversion -Wno-missing-field-initializers -Wno-ignored-qualifiers", "-DCMAKE_C_FLAGS_RELEASE=-O3" + arguments "-DJUCE_BUILD_CONFIGURATION=RELEASE", "-DCMAKE_CXX_FLAGS_RELEASE=-O3", "-DCMAKE_C_FLAGS_RELEASE=-O3" } } @@ -86,7 +84,6 @@ android { main.java.srcDirs += ["../../../../../modules/juce_core/native/javacore/init", "../../../../../modules/juce_core/native/javacore/app", - "../../../../../modules/juce_gui_basics/native/javacore/app", "../../../../../modules/juce_gui_basics/native/javaopt/app"] main.res.srcDirs += diff --git a/examples/DemoRunner/Builds/Android/app/src/main/AndroidManifest.xml b/examples/DemoRunner/Builds/Android/app/src/main/AndroidManifest.xml index e4a88718..0400955b 100644 --- a/examples/DemoRunner/Builds/Android/app/src/main/AndroidManifest.xml +++ b/examples/DemoRunner/Builds/Android/app/src/main/AndroidManifest.xml @@ -1,11 +1,12 @@ - - + + - + @@ -13,15 +14,15 @@ - - + - + diff --git a/examples/DemoRunner/Builds/Android/app/src/main/assets/AudioLiveScrollingDisplay.h b/examples/DemoRunner/Builds/Android/app/src/main/assets/AudioLiveScrollingDisplay.h index c68f062e..463dfc85 100644 --- a/examples/DemoRunner/Builds/Android/app/src/main/assets/AudioLiveScrollingDisplay.h +++ b/examples/DemoRunner/Builds/Android/app/src/main/assets/AudioLiveScrollingDisplay.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 diff --git a/examples/DemoRunner/Builds/Android/app/src/main/assets/Box2DTests/ApplyForce.h b/examples/DemoRunner/Builds/Android/app/src/main/assets/Box2DTests/ApplyForce.h index 5b5cd25d..57b90260 100644 --- a/examples/DemoRunner/Builds/Android/app/src/main/assets/Box2DTests/ApplyForce.h +++ b/examples/DemoRunner/Builds/Android/app/src/main/assets/Box2DTests/ApplyForce.h @@ -166,6 +166,9 @@ public: m_body->ApplyTorque(-50.0f); } break; + + default: + break; } } diff --git a/examples/DemoRunner/Builds/Android/app/src/main/assets/DSPDemos_Common.h b/examples/DemoRunner/Builds/Android/app/src/main/assets/DSPDemos_Common.h index 33a54ea6..589d597b 100644 --- a/examples/DemoRunner/Builds/Android/app/src/main/assets/DSPDemos_Common.h +++ b/examples/DemoRunner/Builds/Android/app/src/main/assets/DSPDemos_Common.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -312,8 +312,8 @@ struct DSPDemo : public AudioSource, inputSource->getNextAudioBlock (bufferToFill); - dsp::AudioBlock block (*bufferToFill.buffer, - (size_t) bufferToFill.startSample); + AudioBlock block (*bufferToFill.buffer, + (size_t) bufferToFill.startSample); ScopedLock audioLock (audioCallbackLock); this->process (ProcessContextReplacing (block)); diff --git a/examples/DemoRunner/Builds/Android/app/src/main/assets/DemoUtilities.h b/examples/DemoRunner/Builds/Android/app/src/main/assets/DemoUtilities.h index 0893cfc0..2901ac4d 100644 --- a/examples/DemoRunner/Builds/Android/app/src/main/assets/DemoUtilities.h +++ b/examples/DemoRunner/Builds/Android/app/src/main/assets/DemoUtilities.h @@ -2,7 +2,7 @@ ============================================================================== This file is part of the JUCE examples. - Copyright (c) 2017 - ROLI Ltd. + Copyright (c) 2020 - Raw Material Software Limited 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 @@ -58,6 +58,8 @@ inline File getExamplesDirectory() noexcept jassert (success); return mo.toString(); + #elif defined PIP_JUCE_EXAMPLES_DIRECTORY_STRING + return File { PIP_JUCE_EXAMPLES_DIRECTORY_STRING }; #else auto currentFile = File::getSpecialLocation (File::SpecialLocationType::currentApplicationFile); auto exampleDir = currentFile.getParentDirectory().getChildFile ("examples"); @@ -65,20 +67,29 @@ inline File getExamplesDirectory() noexcept if (exampleDir.exists()) return exampleDir; - int numTries = 0; // keep track of the number of parent directories so we don't go on endlessly + // keep track of the number of parent directories so we don't go on endlessly + for (int numTries = 0; numTries < 15; ++numTries) + { + if (currentFile.getFileName() == "examples") + return currentFile; + + const auto sibling = currentFile.getSiblingFile ("examples"); + + if (sibling.exists()) + return sibling; - while (currentFile.getFileName() != "examples" && numTries++ < 15) currentFile = currentFile.getParentDirectory(); + } return currentFile; #endif } -inline InputStream* createAssetInputStream (const char* resourcePath) +inline std::unique_ptr createAssetInputStream (const char* resourcePath) { #if JUCE_ANDROID ZipFile apkZip (File::getSpecialLocation (File::invokedExecutableFile)); - return apkZip.createStreamForEntry (apkZip.getIndexOfFileName ("assets/" + String (resourcePath))); + return std::unique_ptr (apkZip.createStreamForEntry (apkZip.getIndexOfFileName ("assets/" + String (resourcePath)))); #else #if JUCE_IOS auto assetsDir = File::getSpecialLocation (File::currentExecutableFile) diff --git a/examples/DemoRunner/Builds/Android/app/src/main/assets/Impulse1.wav b/examples/DemoRunner/Builds/Android/app/src/main/assets/Impulse1.wav deleted file mode 100644 index 98d402cd04dacc98ae3386075de99995f3bf9c37..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 90246 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 diff --git a/examples/DemoRunner/Builds/Android/app/src/main/assets/Impulse2.wav b/examples/DemoRunner/Builds/Android/app/src/main/assets/Impulse2.wav deleted file mode 100644 index c548b22cdde8c51043aaf157de895583ff985847..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37902 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≻ynz0_3y9-O!1pgZY8eITJD(qbh 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 z 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� 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�g{YiUUku$z%$IEd+t`<|QE%>S}G~<9`&At?a3bgMA-1%D*aEilE zt(Q)-EYOUNc9r~+E;CyA={K_{VMTzv1a1H6UADWI^1tY^Y(md z#5&HrZ^4z$Y*(2>I}D+(jGc3b)mV#PL;!JlmdT6JOnCN!MG zyPav}!99-rHkmUz@zP9I6C3y>w(P~!S$yNlu?sj}>R^i*(}N;RxiFa5rnA=&cAd`w zqnNgZ-3PPt3fWk(`)XQ`rF5UKOWoL$b3NF{Q!n%sh0qu`#;&H(B6i)tl=0MgvSiGrDSz#4&*o={+L87 zPoAB~PCIEjkA8>wZz_LnWTpAEKEeDMJnO^D9_-=G1Izf|X(>oD`T_?pW7CUlvYs9x zOj^&HxAZ^q?FK*WVf0P*-Nfzs&!7fhQ%kX_{;K#N;^f=97``KG0P8-g)_~}iu9@j2da^1=$>AL{^wBu6CVG8kL*e4)^HD8GX1=*CyuPwY1O1;Yu7x&P zv@yfXKkR0O?YZ=>gqOc)VW%g_&#Z~PKiJX^lYTJH46CI-Wr3|Cqc_uk-u4wcx40J`8_Ar`@*G{-L7OpMPd>Wcc*2@EH`(yPYRBZ*fsp#1k zpWT73s6QMlI^*3mJZpyDll6+jdc!ePK(!-rz9NU z$If>8!QUu*IF5k46kj?at}@p2#3y^$_P}N*r1r*RYq<5p=K4q z9m3u9ox#8fSRp9mA<$Z5!Zd`nK+rgpw8XecSl$-z-7u{Urn}-@M;K1QzaF?U7RhZz zaEZA`S)WBp1{OSlN2i$81 zpPC5nAf{1NZH=o9FwO~?HYlzGgWAYwBAN-Tv_+?eINAWsY*5DnW2>XCEvyB?Z!N_x z^e&4qIXyN(Nfq?4!We5@v%nQYVG-c20Y?9$U^HI;VV7d|$mOr!H2uoKMf@(^Lu1tZ zL+MJqd&@idH2B18-?&5yv!8hN3%zrB_Z|CxX4g+#p3m|U4a(wgF_ei}_$|FZ(Dez2 z7tkS*Gqc$EF&Dh0C}2)}V4Ebpe#`d_*JtT#ygpx8>y4gQDG_l&TSTU^Uk=wjW6SqU zPvey$+NN{iclP*$t35|uQY;wFiFSgullc9A33^&ZPGaO zFWnz-NIA5)$qZY#rEqr<>s;lT-=eT&ZfPtEV@e*cU*bt&4g^!6C1V4G#mTL~JouT# zXIbSf%N%9KSDro3bJ^T_iQ&Ka{y0QlT~z{OI9$l%$rv-dEf+{-m=pHN`Cu-KkI&=lqR%fZj~d%SDdkzR>Dx)&9zTBa2q?k zqP;g4W^jWykG|zVFMbpJ+6ne~#qfi?pC!f+PJhj`)BGd&tOzP`Ox$DoTkgHd_-wwr zMr(HKw&PZBw71DmIE=t2E;626;vUo(6Qy+6})8{cP1hh5(Uw>rt-4F1~7 zjS5otn3l(ZCwTA|Ctqd$FJ8XJj2t>i&0k@}dG;}b6ms)*{BwbYIV82_x>Zb`=bMz_xa{ z^@Q7-py(0f>Y#oyXVpT$11_{cU>s8gdoI;8YfO31|4Dq>C&BaGn`%I;M#^*RU3yZ$E6{-xm=+R79ufFBfQc#}pL zd4QAt>g|U`Uud|MON;di#r4JPzm|Tvtg@NiB@elPzkbkv4gdXR=5k#X645pz$*O{iMZWhUT+qJ-d9Q>wi3*!K7In z^oI7c*#AA}E#|SO^jXJ^DQvk+FBWXElDUbz>cQ`~DWS3*aa0TVE|Hs7@bP`Va_71@ zR-4NOlAj;JmoY4Ir~GGK9!$y4pLgSl2W&B%tDbP$Alk=C+=#87P~u_NZm~m49=b(s z2=|C)q8}UHXO(`e8p)|+c_fnMDV9O zi!Si{3_g(-$sBrLMb@K#GyyozXQh! zZ>=8}UgW{P?0l1%?zF$e##4Fi8kY~{stB$g!x0f&IGv3jFy5V(VKSrSt~=a4hw|2Ol^^$!p-k{& zsW7%VPX8->yMuGC^2<(63FoE#bckh15F;XZEQmG2IsP2g1KzmCZGt2{$<2w3y~xaG zG?I*#xMI&TDS=Ba&^4Ju&hktGYe>0OFr+6aO(LH&^mt9vL%f;8@4htn#g@leB>jGHRMfduz>-lE6lB3^F4@KY5zOAgjYoND z3kA7pe1Ov~Q>tycz3k@2=3aDK%VlTiu$O}m@z^$U3j_aS!ZG2uaL`T`Z{dqW9K4^y zd?}UTv-_C1j!}MGa)h6bFx7_>k2CEUopv$(5I2ZVZ9gTK7;}azPjkjT{cW@H0Y38L z!_)kFj<2t=>j^fH^M|wSevWOf&^wg9&g$3LBQJ4F24EHhnCU0kD~OFl7;&8MF7k~(Z+o-U8OC|>>S`aNdN7`mM0{)c=gPP$~ixWa8u zXmOK{i998Q-WPNV=D1XPTw}R(zLmk~Yp%J;bu!14sb4gIUSdzdmB@QROgBPNPUP-` zj26$)Zv9Qn$)Dfv^O0U+k2R7xVGBDwWA{T$jb^+TKRo5!qcoHokvDHW zWLdeGZ_v`80pYAER=eBGzQRP=tpu^~8s}Z2{R1vI$BTEkFOv7~aB4Wuq%hrM(cV7=P$$!dzqKA%T$qOEj9hy13+U9Oamj|k>{;@*cG^qoU*b7VH>-DOy=o<=US=_XhB z@&gxLrZ^6q!=>j%%Rm+oY9eEs6nF^`rMuR@lbY zQkGxOp8FWEj$OQHA~s$h&J-r6KZkGNzmq)U!?(W7^#xV z@6YDf`23oFh8}g5+d{-E!IjrpHdMTvbiT<(_nCB$<+50KmxhTP7tdxHye}@ocXUdl z&2PSxducvPKWC#a-2I%H1FW}PGy!?wX1%edPuUexD1i#6q z6)^WFKO5l$xu=GVEIFzcd?{-MFAOvmw7}O&c-#q-%fP2Snp(hY5cXEa&A#|0Yp3qmTp26-z)z0T zhayH;E<>@pF1`-I&<3y=4UaZ3oT>-Q3?GH0_AvAS`{2uD+>(Bi$Nw{mOVNHDq#4&} zG2!EY~PMgvr*y?(+w!Q72aO3ISZ#va65@M>o74GK3gFp*HJ>x z3qrl!=n;&NgZOwCjvG)u9JRdBDhxjVxbJRKC^ZnfSb-mx=(7Ool zeK5+zvTg9akEszDdk+>ki}IWq5``I1e&bMfG4ATlx5{bM56v(>&DYW9T?;^Uzz%duW zk$7}h`TlLr;nPuMrQ&W35;E}qAXJH{JPNyTd`ZBBFibvz;Qi1%faak{NJqXu&W2;P z?2Hny(H}#Tuzfc=#Ua!OZ<3L`4MUE@?*N7+6amSALg!yT_`+!@ii2e0&qP< z@E1^r!*dUEBe41qBEnG>fO%=ScNpUjVO%gipGJd3RHY~npz1XGMI$;HyN^OM9etv3 zCm-pT(Yyd{Bp2}%fmt|Ih`<#1-$2@NynT%4$8hBqOyg1WBKDj>ay~>LQsXg>MPY6( zX6?uNd)O%%+FX?RVP`g`Z$+&<pr?Aci_l_gN z1zPf3UWBoy(7^>q_hZm_bV|a(shA<#_66`bfRz)WaS+#C1S^5;nHaervu2=O5KfOq zhiKGW1cyU-AYTu~okge+Ps%F%7mHylku9Ot@vzUppZQ2nM7b-1PUEHrx~IWNqQCLz zwhBug02}Zz4gTve;3l@NMUog^R>3|82N$5T$dM)C9FL##aXK5?F1Vboq@zb=;@kw_ zBwkEKNCZr$!RI8-JE6r<6b{4vW0*P#%}zsmG@ixasdyOEaCrzEGSFrijE=%u8mz~0 zVw&=-SU5x2DX4H$BDIAwQ%Xg!8yrsIz9)|6VwEr2pToHAn0^(Vx8U3vBuO+PQ`va- z%Ec8wC5X}{0H3n3U^~<|Fl3h~UEnQzgeem@ZF04U|ObqqJu3Y@^g~>$}Z$sY`h}(dxm$AYh zK9{i77ptzoAqXGxF(3@l*Ps)P2DdOc9;6RmVFnKV#e+D^glhLmd=|m(Y3MdqMV$wmsZ4Xxt+vV`5oa2y z4qQV|V#9G1YN^iOKyd?Av+J;Ir82z_O9R!%2a+LFoi0XVW7W&&c-u^s_8yLAs*WGv z*je@b1yWn7EI%QwpDM8upL?n1{KOo4Rdodhc2sTshsAcPfSRgygH_KOsA@Q>?p45j znCe;;oE=oY@1Z?Sl~jp^qg7Vl;X6p>QHFeb)!!lva8`{dL5I<*M^9nfU1gk)O(RtX zuQA9;RdOE#>{aHsQPfrS<{EM=RP8Urva>3+03S_ME6<>17gg+4Y;3Ozx(*!!Rn7&p zF;gASM4#@eB6+z97C@Lb9aS0E5ZFeQdI>3Js?Ikt*hn=X2dl+4m4|NKM2QOrOV#x} zob03ecnwB9RZFhpuZ8O9O}JUB^a~-V0gK0&X|0<62uCbbABqrTp<49>iw3BY?jxtS z>boQX%v5%F(9%RDSAcuQsvW5~Vy2oLhr6b#L1_?p$m2K|v{ns>#lTLg#rtr>ST%MZ zPHC$o->YY+3h+U&7|OPwPixijy-07a+T(@P+NyODN@=L-v>OlVsp8h+V?C9xH;M_{ z07%EHW)LP<3#J~2E3jlM22>zF5Y_+CUoK*5xCDs@77arrld0Mifsjwi^KEJsy6ncC zDr^tOy0?frh(F&jC=wmSlD1oTS%`?li}%94#NwN%wH2yjTz5zDEqqyn?M1k;1zOi} zYzgeI;ovHCERc>5>~0Bi9K-T)bRtUAk>>)>D;P2gS&7iIM@kCnkHV%C7-ENR={WCz zjYn{;J4_-_*c0315hK&i7_<<;?=gHZg3bj@vk(9d7WBl#c&xBP!AaN;hE)s#2IF+R z@LC}zrlh`j5s%@+F)j+fr-0`$V-fBhLF{aNh`~~4!Ir{eF6zbM=N#n3V#X8b{5}pNb)Y*M z=Ncn%JXUJs&p1TtLOl}wYT*2Q6zM2cl;Q^1vQ8-6XyS=xjnQ`oOlu-!Hte;reJ+X` z;mty5ih{{Ss<8@wO-o>^^OTP=sn#szf$^vzgHtEWeaNf5u&RLFy9kAw)2y-WE@hrP z>=K1#z38Us(UFwSg?i|e$r?@3U8{ET_F>`y^ia!tX~}DJ$|Q z7MIc_ifx3xDBY{~92HB8=RAFYojxgN#>!HTKEj|9hMr~4duGOP=PM2niOFYnKdWq2 z><;nBD_TY{tdiv?xbGwTOXXAi#TgtWu9?%E{)ZQ`Xe$BT%iQyo{*l!CP1iW4ykO@D z)+*;j@l%x2F@zUiD2LgYLeZPDb}@bTv;KV^4rW9yTW#Sv;rz%n^)}6;*{zUM*K^Jd zo>Q$A<6U%rvg_)CB5y4ZFmA~34aZMhe&2n-#!-jBr6k|ql z&p~efkKVyN^q+Eko<4?G4$#esufn-(I)4Xp>JY){bIu614`lv0dPZ~HAg($pW0SurJ;Mm=~Xh{rl{us3r|l%1Me2ZrqA4r4Cg%tsBWwSqHr=sjCz z-He*UM5=#`V_up1s56_^V6A?9@In2H(bfSq*DG`Jhg*;*A$-i{5PWQLWpZ zHqX>cthwsB`ne%*JW-!F=J=cHIxYFrQF zV*g6@%pSZ{u9nrmU!}U?VCpvH!2UF-$=>}L^i8dDWJn{fvtvXZcIeGiE&31Q!wU6t zC*G<@PYY`NR_FKUV72;2KhD$O3p+Yjs7LnYM=jnmm9`VDEE!avvDP$Dt8bgJ6V-J) zu&gQD8*@NIwrtC#jrqldW(F*1D=Zog))96DlbeXBi2qs$zlALgSzV8rUAWd*fJIYacgyA=ak^Giz}5FJbp#+b3Y5k2%d z!HWL%m0##gZNBP7H+^>R%E$VwWx~`}^zO->#_ZCQKict|HRS>K=|y8R>h)xQNlo$=<47Z}w&y4-{_e?$-ijmRh7F5tSnod`vZiD$9u4HPf$V6{8FrjEj5dR~bp&_! z?-7HuD9f?p^Waqd&3xQ#7CoPV#Rq5w6tJ@5!`RWCBs=yn-AD zy0d;e2DjyEElzCD`=*>|$hG?1rz3)99&S$Uc0AvdKTO!8CB3_HqBeIm=kS(X){F}p zGfIbn&3Rv+_O1A@0c$m&Q6u^_V^l-x>e54(dD@&>sqU)FPnxuE!-Z<~Tzy{A;9^}F z$g8_HQu?j)T5`8qJ+=iGXi`Uqu2t$=HF)@~+OjsUR;XRIdE~X)LH^Zy^)4+A{j65i zOS|>p(5&fq3-iTt$kN5f-s8$b@4}a zn{2hlC-tbi>a$4^-}FDiHlF_tS@TeX=hRWU$uIxS{?FL{h$eR zeycS!Sze|dqs!9I>V0|)|DrB7r1md$O;hQT)3qIIsd!j?H##)6<`Nw_@KUcfbdI1ift#{!C$8`GsmyX>*#z#N#vXGxW;T0@lw>?F%wy14 zx~*a8G!9(M>@gg>jEl#!uOvE#^MD&)jZn;A4x{;Z6HCW&z%mvM=eKoi>CBBAnLUaL z?p!>WnJdL1$U1IJ9?W^mxZh65c&r}HniaDc z;J|>Dd}7VIQs}nj$AxU%Q!F-2l=Q+PE*Z=hl8YF|ZLaJ&ktseLx{%eOTs@w@_Q^XM z%l7le0uI~9m+q`DJGiB6AI)X%%D{QF7t7Cb%W^to^ZZ7>y~Ju?zPLeScecAnll_#a z+qE#Zmv_Aob}FVSoJ~s@9>wg}w2x%tLXOzV-gjuWpLdHmFp$Tdb50Ni8#R9?bp%=! z%DzQ3*~t-i=^Mi8$83CnyYBJ&VFeewW;+uK=`P>lE+6?a?J>{nVQwYG6W8fG148)d z2|fI2_k#zbsZGA$q5z6D4>7cYr;kzYI@%nSU=j;ODMg-HoMqm*sVoW$^7K0n#wEDhCkIYx60+zn&BI&j#|TEF?>5WRl0RwSK&@>~dgektL!DK${{ zD7V$Yff#OR0C_9d(MMz=y;@>i9P1h4O)MX^L!a~PWCW8;&h3fw*)-~gs_Q~ULyK!X zU=8g%Y(Eh5^SHzwZXY?x4vG2P>wxPo`D6gj7t`7acT1@f-t22e+2Zs|`dDM|Yu0tb z!Vua3#~LHwP(2V)ANX`Ax|dUH41USGzmuR= zY3l^rVqO@G#3HVkhOxIeWEkGQ;DVWuJ!aDdnDmVEofT=gDoj4HH&-Tu-tG; z6yZAq`$EQg+s*N(ginUz$1PsA$GJzmBW3nCJUs?M1&kbzz&DE6dfpRCwY=j4#ToSC z4dw3L?+#s-!|gdcZi35O9@!)LXG$dARo07sIQxk?Vel^HsU6r|PS0Q|;d0h?{P@J& z9jN}x%|V#|Q#kgRUC#bN==YX&{NWWC>CIb_tbuc0`23H7Zdmx8G3${mimvTI6NnFM{vYmjhfpiC zx4=#dPQGZVrj0keYGLkXRNZHZ2iD2s+=<~;{Id()zO(s8eErLryRlV9(7~|!$iaI= z*~1M7A^Yox31Vud%w$}@@%w)0f9Je|kiwTsEc*Q6l~bbEksUXpBpYxQvsIXujUsK_ zla@*&Fa;Uf7=1;7NBz2h4ozW@4=Jn_C8MG~zD4446MRiWb_EZGLo&Lj!*D}|QD-1P zP?rR}5fWxNuF3Z52-f`L!x-HA%=|;BQxomv@S^6|6FBypqvByNOyDRiYz&W+5L)K8 zIDGrc1{ruHw9HhL*2K146jZT!Hs%8{1$fc`-!c`IVebbB(!!QPSk%MAyGl!_PZ8ef zVD&>pnj`uhKI`MnbJ&_8>JL7N-L(QH7D#@N8@*7!8cqWQ*M_MUs98r9Fc532Q8ECd ztMH%~7JkKe8{F1ZeRYDWhU!FbrKJ*Vg^Uk4HvqriVV)!Qf5xAFsP_f~x?|oOtm}t{ zk1$~%Mweox)Bx|otsmBZgjs(ydWod==voL#V{|Ejjbw+Uz1tm^-r`hGXq73`+M}h& zw?@KCH0pz&ui!Tn<0}!>3&n*>K3piyO9rF(jlvAKlRs;XtKZ;gfxl&FXa|E2nA!(n zuh7pL>#DG;Hyl4G*zoN4=+q1Ii_pUoe#Cz^c&x^op6LAw2fD!T2Q)45t5ixcaQTW$ zJrVs8Gdn{VdQsNc`30SNVpat-?NRX=W;TMD##b@tmLSgtE8gOE2b_8aLqp8ULw5)C ze~w~X#5~6OF8Fs7309Em&3H4U=VG0OGBI{(i|NNP&lox>h;N4$$CZHhzF1Ut!nl(# zXpBZ-kez1jA35>pqlGT9_}m`8C(u9}qES909nX`PW{8IuQLiDo zoW?mFBwt0b4t6GEUqg6bz^A4dlZ=M7FzF;(XklA2H0$DbA`%;-<1vMpz2_KiXkuU( z(!`gPgf$}HJOnd+=JqF+5m@W8L#L5kjh&9SpOY}O6G@$KklBC`>Nr=)ov0WsfO1 z@SbcSfKr ztOw%GSzhk|cEPaoyl9FKNt|biu2*=) z404=r+Y#nxIHn!)ljzzC`;$4m1?Hr%tv*Jd<2HTtJV}eja7gAL9sD@KFE!zQhSfD8 zyy&T#%IBr^uuE*GjjvZ`yTD(%@W|q7!TO!%R24Ea*h>dPW7t^ed2tN=$EU{_P)VQTw0)<94f0>} z_b$GE$`N5)Q^N87jJ?fYflL%U*Jkdx$B2!5k=nO{KXt(=uj)iw^ez#uTiEw^Q|Y^UM?tr5mA$#nKnq8d|ovrQaxMYny5lY=-bOUc28B{6gpixcQ31BWC& z^XBm|in;P(D(`M)X%bg#;jAdeyK}(>-dLyXGy^wKE0vdgc<>^%{TP$Y=PS5PI62;2 zeUAQO3^~n$4Q!atE*`W!L2D28N@Mt1dR$P{6%Y~#xAhnO>yXG7U!IWNZY%u=CF5mRXx%P6@~Kf#F$=^n}+tJ(564JRtqgP=uB zi=p964vyrQ#dM9J&M1zQMfObI6p+_+w%o_TbJ!xD-Igd4+cisRdz1$^i3px{%c&R3 zw{D_|=PnO6xWEqn$~X8t+FBWqc3iuSv>@g%>b>fd%(z6OqjXB({4nlMWWiAeMsrRu8zeF#fVGY@CxA!d zxNMoc+j5Gqza*gI%Qs0Z@Zxd72zw}>CwQ@G2IDt5G8ml2 zZ|7)zmZgcblh}jw)6ekY31z?U9LJlPoNb+pQA%MRoOh4#&uU&c9!=qa_wn;zC?-7RpoPG3VY^oYcAVg=I%V|-r}S} z&bZEV!p)XteI5g@^2$qoxXoL)**A+~ps*8c?>n}axYtY0%VGQ{&dlcRw;Xwq*8kWf zmvg^UeU*M{8p?Y57me?7U>#^aWu6NCUo%|`d+sw_pX9%reesi^ag{b~yWn9hxJmf@2yY{w*W4@ZWPj{>jY8{I3p5 z9y6dm?h0J@54)e{wR)JI%fYpwdzH)oDAMgJHG5}r?N<&v&Ex+lP&?;;N(@7@k|Pso zEL_9{<-iq}!Pp->b%yQ#(lLtxKdC;>3d!ajV_7YnI?f^qxTdn8CORGE?YfX(@ghyA zk0^gOCYA1Almh#VZ#_hZ#g}U3xwK6KYh|+fkFkloqY0l2%=$$O$>*yefui1k z(>eP6U{*Z!$&B+fm3wso<<-T>1O`^q<_!1NMq!5Xvz2VgeIYBJVH+t)pW#qBqbG20 zQ#6Zb2VsE3QtsFVGVt~v=bz%o8nBI`h9e`FyjIP} zhpAc4s8DIyP=utdBo7=)#}XothbkE+z=XHl=gZ#3obAQh?^t&UkKCf~at7RH`V1a; z!0<(ky30*-XnKzsD_QkKX!czFl)aa6L=nX_*X9-d7IVNO`mJErBkC^Zl$&ho!O1sx zc`frLfwqt#&l$XiS6}kWQU;Z>!*XhhDA1EF1>v=o#vg@LsRX@Fu3_v4_SnQBuld)D z|9xU}Pil$ca1~E{<=M?_UCJ)r9Q25PUHMz2iXvI~!FL4M7Rsa`!ma*y+AG!0|SN5OGd)1t@kgLl0 zWda9(W9mXq6B@uA_N|~G`2Lmg$wJP0%X5-H{LKbyx$ZF|R@3#X_`+!RnFe!+FZ{8F zZ-4NiC*_|L`x#!YTmXlCW!F9YCdQTx{QiT3L%8%S+Xb+rP(4HWxtw#4@r;_D5&Wu& z1PPnfQx5n=-xzv`cS)x>PN<1JNy>9W5`ASVq@9o$DK;Hfo+sKzSgT5egN)RKg`}Np z2s(@(KC$aa4e{~-Em~q$1j`Iz5zN}A*bprvO2met{ z3M(@>Ovo?^v}l7NH+ZNOuAk+GmRNCxU&XC(nVuam^B&!MqWl@1#Q1ra`C_QXu!;toaTY6wkCF5;iQbEswaQw{hQP}mHvz^dOP*9=Xo$w^QOg8RMJ;Lyl^2$@!KckQWr{>k zENFyQ9w;=yzI9M_hMwGHc1GbwoN9xw{y1O=?7(4T+;qjL26*m{2Q6T-22NV2UWRwo ztnfsiM$mDEmRyKdV6g_C$>Lsxj3o;0W~nPOezJ5PjL23C5%-5_OHo=IZRQ}cDH?m= zomv(jDAYui8zgKzbS2LG<8{HN{be0@NbLEO7vvYzbQLDmg{2oB)y8W9uQi6#QpEq^ z$pyHof!tNN3+TF>;+k4ArKH(Sy5-k*X=mE1QKpTDzm8ZMUd@d)&NO^*rCuVDFb zJp06uX?Rw_-wt^8Q1lRxCgz55U^O3%#@63lIuY+g>NE>#HOEiHP(XVHvdJ_Td~T$0 zrPfulz*Qk950zDBO-x^k2ih387`h#Q2B^THJ`>k5b%uWBR0UHSapOsv*I@j`U0 zt01g>0-z048DmF(hx z%r6|?6}?`t%>WGh#6Eq|@ioWU!1N8}{OI+T?sh2s#esuh@|hE)BU4IKdpvm0yrIgG z-)s~%SJ81a{*+S`u|{tNT!|Lnd1g4;mNRx5zRE<=L1l$-xbp+#l$RAXdbWV8^5 z3z(#j2Dh2i3Wu-qV;$(9qgfl6Kj0xTAKjrCmU~E^ur{LZ(Xu7d1=!vcS@QUs;mT|7 z>x9tHtnLciGOF!_B*xjI!4-w;gwrO2$`R?>Sef`2QYp95;nL0=6tnumqj zSh^6u1u*W7#VrsrOU%odwjQ0tit7oN4lr7SM{No7&qs+4suv?p4{ztfs6LDrVn;oAPC;c8rSRTf2hS(qvN>bS6gxCf zH4^$7s2m5cDkcq4#$vs!@#q~t4TQlHF0{upHIr@7UIa$H(BL=O52+=bXpK|vxvdMd zUT|ewrPwvGGh$xyiXBG&XB<`*Lff$feH-;RZ+@2cKs6 zHy#Vxpw&Edw?*1)yfnwB=~&!Pl&M%?uQ1tU;IM5O#t%o<2DBWCvhCO~6Ym8$HX2o% zv464>dNFdt@$Gma{KG(OcTr+p6^k*@M~Sz^9)#U|{PcuMq_jb(T7*TLVY~pAewaEO z{vK#H5lyxrcNG44!rlRio1xhY%U5Hn4P=OC+zJ0&anb;5mtbKBm`y>7K0Ie&WfLSg zBjh&&MxvX5)5k)q76$dfjRwf*huSr8ydQk(BF7Q~v{BCj%^IMrzjF9}VT$j9SnrJT znuutR)quCmWU5%&6IwLJP>v^B*lpOXam_kq>f(7W9sDO#wo-Hjc^SYhM~(WT+3XWwLlD zdna*+2mQ{`eKQ+Mv^$XF^~uWsSG6y~hsurwa^VOxpEyVE<2h4VP{2pjm) z>ktb)xIC14%lTs!n78M1&<3t^qhSCOUFhq>MI$(3Dbq$Pi=K0i$}Pm2e$1Z3 zYu%VPiPeKSa|T2Ea_lsI>cirR4Cu|o2^=f_-07U;zTPVbgHF;_-^qy^`R@Re*K=M7 zH+XY!GM{f|b{HFba?CNF2x4#uT{m!G49hoh;vr7-XXhAN1n}a1My=uWFdo^W99;)` zvYCY2eW<>Hny}OTDG66-0Y4c3a2T`E0(KFIMrhoJ`l!%8Q{(S+tSgT)BG_Q{}I` zh7KN#^WirS&RxWrZcO!}%_{17({mHQZesRk-V9RUSN+|1bgQz*@4SZ!EAPh-C}q$oAtwaGmLjm zuw4Rs9^<-XUOviomz0jc8_5YLvfd?noZzfH+N3ftmwrhckjIVZxkFwx$5`(nf1l*R zI~;tD@ekSe0&5m>`5FGpVQwmyU*Y{M*1pb}8PvPWIcXeugX2@_^PF2UxTAnekJIa> zQg+*%L${;+e2$gJ=zW1x(-@t>F|oXr%743PkjR$Xlxc=^Z-=DNNp2c5SYrz_qd9D+ zQV00FU5+1Y98Sk&)hDX;RFiy)Q4%XMsOQ%6uT0Ni#V*gx1S={TM6OaP|S7S}SgLNUpxo0e22J`nYwoc+u2c9`1@I#vKpn5bPAK==l3=83~DJC@bDmFOUO2ac?9AC$e=vC%ob8Al`gIuV^NHW04#rE7&lG zfko_}K$m~~9?7|%Sa^(bU$iuxrsZ@0s(LKG%iA zBZ~f@`~inFh71E`IdxOee|523`U_$V$)lTyU!PL92_o+BO#>J`qo+#QBo=GJwn(Yd zKD^D^Dn;-9MJlC_m`avNg+v9b$KrLu(>n}Qp{$5+wV?ZeH*4TqF+H@={t?x(#CgII zvid1v?Rsca&Uq5VddEOrta;C4CXln_JbhHF5GZej;$rBIcU4^26|);)>>#A;q1qaP zsnK)75`7FGh~(zDH3E~gVdI2oSu&15xjwpz{?!=nqLl59WJe6{fUt{83mgXrF&Zh;udx3|a@Jj{@#hN5A^C#?clNvX8IGt{{ z=pu!?OVm2Yu#2*N;~4RponqG$^iAX(86u_8>NMjL`8$IH1rjJ_%rqKi(I$?A#IY66 zd18PH{d+E55`rCMX150hIblCb zVt7^hbf=W=$)PlEjAZJ0r7E~Ok6luED}x=5@cMN|p5Uz_dYos5-0-Jy>RY|Z zNWShf^>gX|j_q=la`(8)6zk%qEbe^AIoCL!rMEb&oHYw5n_sCQ#Z@plpFgVJLh>)-UrR`^q)W(QvhMVGdZAkdRsv(B8!XjPV=!s4(mD~H?jbLen@J8s+8RPX) zZiL+}(XbQ#c2`2A7dyk+7INgVA0kXV?6HNh6$TDLgZ{YUh$DmW%@WTC?N<>lWJp;$Wo5U{3&i;*c&G`%}pC$MHx!+>572 z@p2pH$HVzBtd8O8Av{Zk|1r3wD3I!7>B>f1by8GT=zbBWlc7$*vsg^LtWd!ZUqN{) zdZ)rB3Uvw)n+un#s2_`j>oAPR<~)2jsigGtP9iKDO%qUEfZ!BVT!&i{3@_nt0?uZ` zFdFr*V0i?JE@AUAc%8+77`(_qcm_-}aZg%2HwF+h3)Cs9F6f;a4!a*&g1zBEVzK1Q3%aJL?ZMb zVNp8V?qXvM+FpV4UfA4%Z2~6epqP>)2 z&Rs!Xd%}7l47Mo@D4LhiyACX)_w{!~FoX zkA=p56bSQwJ^JrL<2`5`jD0)s`ViI}LSPJrZ9&JwD3Qic7+luFVLyu2W8ESA+yQGJ z*sMU=W`xO!bteX{LkmA_TBfY9hX_~S2gPo<;*Xn4(aj$_-EeFJZqLEMjrbz4^yP4z ziwPUyybRh)(SJEQu0_|iXy$>T%i$LQM?pdQ;QB^n`(VUY?An4Un=rx$mptI)jozEk zO(tnum2EGH0R-{3k(-w>uS`KpYs}2Z9wdN)Y*b}E0teF;&O}$fcGLy4ut=5cyGdz z1=xN7c^lIo1qBXfoVH1c^~o*V{Radf)znPW(ax(<3T8@LNGrX8+~DY2wp+R z48>a@ZJZjwko94P1B(_5$2Lant;s$3>=RcE=pNo z*%)lGhGenI>`*;H$xgJlhlku|3{?m)X``^H1DwVnN*|Bx(7F|7_C#S@7}+AZGcMWS zxlk7*d}54iq7-S3x-!CQh@2Kk>Hzb$()hsGuFx{a21DGFp-^iSbU;fp1b0**iimJ>A(E`^sKs|F@Y6=ZAY-)$!-7v8OPMV;|0R4Mlu3&sjQKPdGaXH@{ z8#^Jm6~?#4x|Voi3_Tqws=%-V?wes>E2W9Br<3v^{aPZZ9b61Cz7?9cf~O8*wP9|g zBtQhK?qh)G&2iQU8BMXp1RGl-xE(fj!GFe(o%m@}eCvXFt>9vcT`e)t2)B%|#RB8> zFv$p(#>g^)%hr&Sk{|qE(U^~<`Ql2oD+BjkgLnB0)BTp76rl_b5 z+qRG)rN1`1{NbcV*!_psDdO&I61 z*!`Xc|9I~$7gf{g4zp@t?IT|NL9^#<-vAdLFkb`jOX=~4LvPSmg-(U6RZZ7dTwez% z_qgyEy&tnjHG`kfyPWkda`|^gKINUay!e0y@3{6Zy-R3too!@Qk;hlh8D2|L48(bu^sks;~yKf<+-`7D`FZg4^hM@x?ABv(q0TTmW? ze2?JeldK`llw1~{WZD&0MexWC79Z!eboPs3;Vu5VC^~pXOSDFQFITzXF;8FPpnF_< zm0CBc&Z6%-4wK#Y0|ku|U&y>{=9Dn_1{-}>9$x!mHoruj7i@TiJ&Gvd8PyHe7EQBQ zLF33=zB$2aai_*J=RB83a(0fAEjfFZ+hb{Yj?3ve!U~ag;W71Ow zCONbg{D|aLQka`X0S7fb%dd~wLGnV^m~(=E9&lnFpFZT$D|C8FuNypmm*LM?>j_nl z>GYQ7r7Zlyhb0{Fh5IB6^su8H@*xvd#||4^Xu6RQ|(gif_^sUd}RkL{*d zVu?Qe5ZVo&&C$si7cJpriC|N>c0@!66m`NrQ=yupW^1(SgCqkbwE5f;jr$-(4?8SS z&k~V+aIq6y6W-}j*)g4(G>-~;NpPT;i&9}<^5sX57&m^ZZDi2i|O{bJrS!0 zqkJ$%JK)V|NZ{Pl9*Op-9)rdMaCH#0#v@@8c20#z#|+2AXAH_m!)7#k4O5o9&z;~i z3^!e1GZF^luwG7!)6r`Ru1vy~Dd;*I2d7}|JUp3)gQBdOih=X7dE z;gIl|7r|wIdGCfZk}OOE_X2(x%{0 zKb#whh9mLU8GA-yixavJMf?=B7!HFG*gX>K$6?_#^c#g^BOrT5*RkMW{2Pbeldxwd zevVg`Q&scuQ?TueaCj9O%m>$?%OcG8L(^pl_s2RfIPHS|D$L)H96?6!gSe~iA5c7E zM-Br!@i!cOH={|ILb-2z7+tnu-7X|-!j@o+^~S6XIJq5-{NWjZGXe1MSM*-~-q2Z# z#$Kp52X@o3X(6soL)a(`oQ$9Uq3JZ34MF4Cm}Ltcp*{4(v{5MOD}7{yo1tVdY^>nz zj0j_d4MczmKKDg~b}+O=u^whxVVN1`b-^rsY&D0W-0E~gNPXD!!3bRhcfil4P<26* z`pB@vD4z{ASapL@JIuAl+U|JV1C3gv zh8Y?epy428cPYEYi9Imh9Pdq#)*T70@n0WQb;iqqij={7ATG5+zu}nLQF%7@F@Tl> z!VEFb4r~ezLP-;x9ja^(zdOLY6>1Mv5ROL&;kz!LI$(7R{IZ2(T|DfkfE?2$$y^5( zeXv#=(`D$_1othl`X42yJ)PX%8DsxZZcZ%!^0VB5e4=Gf%>Bub_K5z@6cg|hubRT= z2jh(4P{C0~m{Q5d2AE#X^u{py!a?T9`OA|HkROEJy-S#<14jMg@|Gz0K)W6= z*FaQf6j$?0XUwUAR*o>Kk5Ro5tBKZ@h}S}%HQMUpQ%{)6A*CPub>Lu&+WL59i-)bT zsv`!-UAGmswuj0NFANanfXJ@O9dgfpxIGA;O)+jf9+_kM2$Xflp)okx0eyyGdRy4e zM>7irW)d%4?)fO_iQ%r8AiLlN*gpjB^I&I)^OIrG86#H0v?t1D;+KHqL{Vf4>jk(g zsO@FYkqhr4jF-{YEWGZBi7txfL$wT1@?)QkS~jqrtIU3l=3|1~UM@h{5d1d}c_T4$ zHIl|)>ujiPacd1$PeJSw+;l<>(HqHS!BwGL`gkfAJ*TzEb4*wiv>pjYdI;jL4$eF?}D9^F~2X`EX7U>j1`cD zbaQ55uO&{eg!4c+EJs*h?2)UwJhmlJSt*P4E)ukujV2w?bOMrkBf%XPEOBreQsj}$ z!t~w{*U94c_;0pA3~+2F>Qn?@;L895emgY6{8s2?0V3isdf)CgpJXYT>n@tT(7v9pxHPSAhC zTs!=fJ$oPNWiYZQl8gAQ4Q%f5T07jn%R164dCc)fxPG5Enqg2Ljavv2g^mqz^D6xt z!{8!&*20O4tX&5~PHgFiF#w;x?$)uhnQXX(k zbM%vuertr@XM<+Q&Q(4}p5;b8)I7_vP0{Hx<8*N~lifNa>k{>Ka3_gTdKh$#1v;?5 z%!AGGK9L(+pm8?eX+xl7k}A?yWZ#SFFbIGe=8}0c43No zWz(jL=~oz67kwV^X)V0D$$1+!R9fYu=mF#E3gkD&2dctxfZDF0X=gRg`ljrxu|j7i&b&zY-d0QikxsF1!H<5qyRJfp-usOe33R1-Mw%{CgeV_n1-{V7%>?K zgOM-;Lm~xYiJ_smI~`?yu%3ZJH#D7z=Fa#r9qf(P)3DG6J!ax|7d$G$(AIb)^%gpa z%toWmn3WFQX2{A$K?AHvL2OOzh(r$gISQR?!zCVGRnVb7I=000KT80s{}sXn@uI(Y^zQgsH=sHj$X#4m17K*KV;0>3}GA z=rlxbIId~qO%x7wKs#>?X@K(su%bDv2cS`FT#r({PeESlz+poSdKw|2KdLr{b2xt1 z#+)!1)1Sqr^*%N?fBdBM7}4*AQjMzFps zPS(WZiZ z4UqheYuX|}SQ*Cf_`{vCyP-Fvc5$JEL(3Hkv|-fSB>#rmMrQ z*YS`WbY%vPxS&QR3Qm%?l>LgjGJXI&U5sw*B zIG^sozTM`F1>I;77RhEtL>&AhV;Qf7g)HdlqWYYjO~v~ zUj&4rC;`R(i11T;hZhFmc`gnIgUJYuM#Tv98VFlqj-_GSBqV3UZ#p*T;o1U}6aX`@ zd?FStL&j8e*ax#IDA1bCHmbse*=+dsjN%<)SDbCRwOa4Eq8c$i0lcm5ngj!W7^`xccpD#gdng#1ym{hn2~Qn2p>pj4Q&&c-)?$4nmWs zqxEpi*bI+2%w2+Ckh7%A}%n zJ}!<%k4acL3RT8pS_TS7V3>H1v+-mIlnhv9VY1|W6VQ1QYNeoL7}9c8iDY#&&gY{% z9EZl>Q-Hb@yy=X@RNN7HG#~e5J)ZHJ%T)j+$_}XbF2eu%4W7Ng0hg@8-Th#rp5;v3J$e?4G1L0wp0$U&kT{!PWVo;X{8RnGW07L(;l9D}w};XMK7A&8lW z^nR*9mK1_TqcJBC1B=kq9UqI)AP`Q|urC<-lab+vshOy zSUD6&k6=k5bdI8O8fITm9jBYl;)ld451@Rc#QHEJ3l|ros>sUQ5Hc4J*Whz52Cm0L z5vf;TW*nMMz_L8tUxw%`w44ru2vvjr9gFJI5afq{BM{(;2O}`p1CvK0#sT9JvCj== zqfjZk-Av3gf?qb=j8rTBNelFh!!ZLm#lWEpM#rJI0qVuTr320eK)VwTN2*|@WG4(2 zYk@n8YG8sB#??fj3)WRZUwwR(%zIz-kcYk@y8oo?%Ex@=DIFAjqfra^Npz?^oaB+( zQ0kbuT-qOAaIgk9O4+0)zCL3cElj<`-Je9hv6t8&i)AV@3 zN&EQk6?HcA%462qLEkrOdaJ+8{Ui+ap08K%(_>29=D`haTS)H*Z*l)72HxYo4Sao(1(Nr?#X6_y z@Q{+4oOzo`+xX-zn+aY+%3=2~;yL$jg+`W!k_t;i5nrOWtHS7tB`S=VRxxdNlvcQ3`w`Z}}UNCrr!Pd>}cxNIcHbz?~?t<2OvtZI99iDOq= zW{2>+8S5ppvlI2DJ;#D8V%X4@)`>i4$B|-pv|*Ql^!MiOMBcPvW+FTL@p=p|1anvc z&HJ-`rsNU0bp)-#`D7#=!|9*PkpuW@1ltba>=|qmLW^Qv3ZZ!cT|;O+n@xPVe-^Jq z@;_;@$El5e)F-gHU!H!1w-i59NQ}oFB@c zo?PV4<9&EY+O^!d)SEZl81KpyOX@kYvkC9?VWB_0tXOHug?7~M$d5hw#gH32bA4Af z>c%Y=)au0#27J_x8w_dDjmBn-lsYOyf#|Zb6RWr9(5`H+Lwj?{Ez-Id4cl{#KHoNH zL?`aiWg}BY)MURV5|rlSw!GdzXfW*5g!`M&Qc+sh@oaaiTYOL~6DXl?0 zDwY3~df${rf0URD~5F$`AHe{ zQ!%el+Eyy2pOt-Yl#{=dZB(M3Do1}Qtv)GbKa@|;m6Es0!`I6B_e%ZhO!}y_`mB6^ zp+vq^Y+fk!Unxlsl-j?P)$f!pZJa__BD@<|!`R(XD3$#|edy;h#SQyTwK zCjL;?d{8ERQ%c?|o^O=vf0SjvlsX?3qqoYy&&q=zO22Yt^Lyp;Yo*&aW%W&E>{G?Q zOquyyx&27#{#My|Pw8@B34N%fJXRjuP<(DGZ*M45N|oMMl*jj!tV>GHGiB*PrPgi5 z`J%G4R9SOJ`6xg6oKp3^;&?`>_CTq1Oj&(LalN6OeXOJ%Q*M?kmbVn=a^=TuH>&Jb12{TvpD#R@~1hes2|rGs=ZBWzh}g%~!?nuHy7e zDZHWdd98%pR=QLuYcDI4UMc@>D)x7kg%6c(rOM9-N|#s4j55Xhk#hdIGVYyHaYqR$ zSC*G5+sl=4SCy}~l;6)4i$_ZHJ4)saWz1`(@nhx4b4B~PVpFcH{GLFikCl8y`EWz2tWb7cS1c=)eTS5G zUzM}hlz-opBe#@YzZL&8%Ddmn*Rx9h?@H)JWs`>E&nu69DVEn1&q}3kxuXA5>3B=2 zsKE=DlwU%AyP(uol#dsb^6!e%ZKW%?>7p{Y7Jbeso9goSQ{{UN9=)Yld{lJqDY~_J z?y|D=k5ccR@~Q#7pD8bDP!793l{WVkhu_N4H%geI)Gt?7YnWN4lqkyMa%Ji-CH9hX z54`_Ql1yB2Q`xR47au7@s_^$cWpzDvE>jjX6*X3A*oyD2DwDPN^t{rwB~33Vf7|l( zL*<Kac6p_v4sg!htt?t ztq!bf%ooMH-iI~kaiK82X4BY>Mw_VR%*{eF_v3^;Ebd2>o!sNg;Dh`SLan_VlgRFu zX)%BcPjgK)Ezj~-1YNJI?sWY#e37MAKdeq-{%O`srn@B5lUa6$Qzesfov%_=n%0!z zRIac`EZd4pJe&7QS+9U`H+X-fTHStqI4>XLv2?Z)*>ohk-{j$3ZY|@rB-Ro*c?>N| zs9VTBWmFP4{62LDa`Q><8BFU#tQx~w5;+f}?+KoY<=wM%i(xD?)hhF>CqqO@1M|#ru1h?35t}NKx`FpoYGECacOKxf}e3B(s@8()(ZaK#8 z_PltQ*=DT2lmA@!Rq8w}Ib7OgyxDyZ-x+iLA&#|Yl^a|mRUilW#-7q3)4eZ!uThbw z@O@77V!ykr45!s|#)hz01wRg;uk^o%bM9+C4`cEV{>tRqN@j<0&tE!3afL?qk6c?@wxGG^8 zS9Hu)Ba_>68POLGbLl3VsW~bT_4agzdqP+WBf_w9DlbM0?uN1v_TJ2eIj~tpn-pla z(pq@AJ6KpCHclo@g+mET$EehiM^iEWEDz1Y*2}EA3~O$)>q7Lu$kY`mIZmx5sP=#c zYw_=<%4pIRq}u^VCETjLcyWVHTX0`IDhF|{j5Zta^#fNQ#;jL7cnW$?`S>V0Kj-&z zaC^(WC0OvDMe_L{bUTGE?qN+` z>G8q+W?1kHA0+-(s#bJmJXPg@6QA&>Aq-!laTPSLKtsxTi2e;Fu?td)w_se!s$Vgu z3ZA`(e@*0m!p>@N`J(=ogaa8!{Fg_c;emt;-l3ujuD-{`nz;WE6KZ1bTb0L^ z^Z*Bc^2H?x2cWr-H?Y1MCO?2~RUA2si&e1g zI+S{7bpy-(uty2%Rz>$KaBqgxyQr*>Emv{*AGe)@`5$gQhqblw>o|;nrN>YVtUaZQ zWo744Ruvgr)R18IQ78@Y^QbC8HrS4ks#t#%A(c!%hWp=GcmNB&F?k!TDp`3R24CrO z7=OO8Y%3-|_Og3#&5)%N7Sr?FOq>$2aky*u=q-u zCXG=j7GH-?tak{qQCfExpI(dJfh9j_b_MOeb4v*(y`}bcHCyrWAYO~Oa~Si49&ij% zf7tFA3chh>36A_^`~~!X!BzX={+4NHVgE|%d(id`>+Ztz7u>NMhEF(q4{E&RzP*U3 zpxCWnh&Zwt!=4J>7G1v5=m_H9apo@gykORD6%M?8FK&L8h7rto%4VxEy^h_uT>i4zetfEj;1WC*yy1GBt_JN> z>but8k1usl`vh{U;{JM+YaxCER{rC%V>nh9+qdCzRkU7*(#Ght1%feLwHdo>L4Okx zrNCkvwpUZ9c`K@-crV)gq~12Eo2ScK=+saf+x`El??~e9qmSZXLv%W={w0?$s92A- z2jMHS_-#zp!i?iM+!_V@;M7{Rm)~fOtcx&ii^{WTq>T>;@lI6i5;!$N>26%of&D%# zYmDpS0~c%ML1ebXqAmE`6uQfirw6ND=+GLwSHjEy#v36{%ML5hT?cD7VOwjQSqVc! z3|)^Iy7;>RRXU+)6P%54V;8i9PqH3$+9PQb*a1KG;ADHOmE&)Wq+_aaROdLVS)k%1 zo_9j%4YV{?(eWLP@vIcPx}eDwZ0wGr+c+et>PuK?fRAU;(j4u|)sOGogN=AyuHv*9 zWv`%WKWHvuj};2eqqr~bU&SLAn3f^c4co8bML$GeQVkx{Z(*J%T=!#}BOac{83zQN zM64r9_Nv|7HO?T(2ak`Vg)M^5;jt%bpTkQJEWV&xU)~8w-ydEVVC(|j%dig=MGqyB zsPzzk24MR+1jNI=6c0nt@&W#f!t7EwC*k~c{2hk5uW&mVKOVy*6UjGK4d~1%s>?)gu`vsgrm8N`7tOy2OAH#?nSU0inn8VFm~-lh6ge?BhL$~x1v!m#H~QM z_#!64(?+GHSM|WT`RLULH^-r^1eqtnwKuwsRTIjmMyN9)nOJVI#^fyM+M?kwtm%ah z$uJf6-B?U8gIyk~O3BDv^zMoo!||^lRxbql;M^1hh-NwsAA6yzRDlR1PC7CiRNwVf zH+(5TmEIUT4l~@*eHdyx<3bURn5omh96K}}fsK~1%7$e(R7-=dJxqt8UQd)}Bd8lX z55gTgbVxzDi7L8nx4?-I)atFu+|h=Z=@09Us%>?6cLca%hdFed@xC<*eekUl>bb+M zr`nJ*)CgVuvAz|~dtyrmJaC1uGRB9Yc5D3dhOrSAJ3*2)-2$<$9aee3zzk(RnB5s; zeQ{mPrQWFDN$uH;=!(m7z{N0Q2M--p!kga`b{;t1LDe$8=wd`C`0A=B#)*#5vx2#R zxw@gE4ThRPPaC#fFufVNh|bs^yF_+r1H;Zp)51VwbQB@13wqZ9nj@_po>{`9A-?v& z(k4jJL$j7JvP3sM^>tkbq`RV|t$J97w!(f#>}i9vKz!?nO3@UWW0NILwZmi|EbWMK zeK5Z>ihJW%E7i0-%@X0}nBNFHJL9z}x)@+kXS6ZFnfhqa9-Z{jxHWQh5!41BjWD$> zn(E?gJLKy?(Z-pM$oM5a#fYy4t;RTB2Rn4I=LbvLp~^R=3x}jCsx(He-zq@$zdyWM zA3G}8^&gKsr?lbJ_{^yqbQge(!VgbXy?fRUzw8IQQU8mhfwR3o%_$xV&0LmdH$d=X?x=#3 zQV0K+y&h1j0kleavI*LiF`^N^ycB3Q9*T*vHiVp(BKX-ioFX3b*Xq}Ne@HRUkCZ~& zM$r34F}H}v#@h~uWWivAb^p=E67&Di(* zCG69Ih&M*pFr)~Seh4l(V0R+^nBqbP+^yi84qr$79)$(AurJ0FA4C+P+za=Hp_MBl zi;>a~$HuA3@8TkuyW`j>m|LlF2{G{R7>6g_;hl$D=4d@i)m62M@md?+!{K0rTZ6D) z3qb{#{*w;};pTt56bbM5{FDN_e|#SW*T+1cf%u0s4S?N!dPd{x8#?&m)m2vQkAN3! z8-OmK$d6{h$h;2O`mBkUQ^1gd(yP%o0NQ7Uew5OYZ%tf}B_PZ$a?&>gQz`OXz> zA5td(-gmh>M2bi_!3!^?N5CD;%9!ql?c%%e!+&Mm>5nJ3IK@L^M06d1z8AUL4`=W4 zx<5Qlb6zlG~P=uAR#1pU9aDg}eZs#ly z?Ap!&PH4KAMWRj2vE5W^jsSsQ3^D)2j)74&Y?r0tIqd6$k}dx||#X*{mK~c=2y-)CyKZ zvS$V`g1j5fBh@f7o$G$Fb^-_e;G+Nzs|DKtzLV{V2faS?z7PM?h>3`$mDGu2&z~yI z;9Nu4#?nX(W5G<3-{r?EO)x!@cGdB90L7ZM){mE4p*(_q&0!bC^BwU%l+E=J9>V|h zkRQXTTdAOR72f%GLqhlbs@_XS}E<^qRL~i7- za7v%mDjW+W_JZ@}aACbV;aaWvl+;D$7B)6_f$H8rUmJYWytdkD?1C#<3NEN1Z zHl1RXEJPno_wW)ef+FJZ7%s z#Q}J=11 z!{7j~PnOav{+fgyCwOBlrtT8H0Uobo&P245zjhLu?Vt#AMhAF$8bo?9F2E>hy_|!D z-Ml>->2iF=;qMA27eKHc$cFtf4k*UZbrh#-txfzk7AN*{<`^7Y%S|(3CjgLq1WN1r zB&-(K&~j+bvEd?oJjPnHG4mGhO~-=k6rH#KIchC}Ux_dfaN;zzCg61mr%P7!GWQf< zLkWi#o%I6jMo zIQH8n!Mcb`BcVH->m$)9PXq{T8OQVpG#$-468ss;%xI+MvuPTBA+zZci%o*E zj6hKepQoUH46UOvB$kO@SQbh@FF3lg+yQyM9P9?Ka2hxv(~SYncpX49;Sa}BUBiSh z)Dj7D<@P{fxQa-v=gxh4u#hWVAKvb)V~({koFMB)4;jm2h(GfzuqcY-bfM=$b6Y5Z ztZsq>mba9+YE8YT$&)T%7HgbF}*Jrn@F0E8++ibGcQ`Ag9pdh-{(p*&@Zmw8OILZzG` zT~ITRoy=jIPqC(4k7BVSS`@K{HMXU4MOSrffH-sQ*iZkQNL zJ6WLxaEA#3BRR(gcOtmg9`}=Ywg(o(@|F!uDVNfJzcf&;y z+FGMRT9rFuVK~RM#NsFpX^XM|K5K?gKJ;pYR-PQ%3~@3nm7na&$5mnO!<-rz-;W#r z(Yp)V{h+%LhknVW!AJjC$AJ$%(bb%{HBbzwEj9E#DJuDUGamawFEcf7HKsRrKH+v# zE`H3;MqKxh&QbzW%5ojrJm73&n%&_O3)NN(5xd-Ce=FX-#m`+C zdy2dCI91rE2D~g#L0x)D{;MlZPqVHe!}f81Cp988O`o5SbC@BAoaI6@&OFY=2JCo) zzS7%rk=5<#e33VMux1H+n6TAt)-mIvo2+8Q8dtgBl|;)?{c1CH`!n?F$xWB|z7P8!=0F>E zJ;7X82A^YM5B3o*ial4zySAduQ|k32@37FBP0G2%odL2C?Z+Cg=p9bym#pQZk|Z0% z()lgNhjH9X&I(f#Og>38eMgr#7QE*5K@@zV)=<{}!UkDP7UO*$OUgNU6x+Sxok?8w zj8n#{M}D#3ZXVIPSS>1b8pB2vd_0rZ65N|hnQ?tvK>OzmTtG4SdCp?hAKb8>0#tI>giy}8$L9{#ve@XilQ$xH%DL{cy)&IgD`|_ z=vM3EUIp*yj^o)fqQRg{Nn&DFg511nFGp)O-bV_uG z*gzXD@fSKR@x70l4jwJ{YHghF zj`eMj+!s5vQO_0&+QYdYj?0*$3oIOjXM( zixco{7#_+(ZW!K51U?-dhrmMyI0c9wiKt9$$j8&+sGNjBVrvwnKn^~RKqpxuPD1xM zNR{60e2mY-n<3a*fRjnsJOT}}RA9oDY?SAyGnvm3gGV%~ zq$4o{cjM756rH7QQ|3|LNQuPKFcb!>ZFk-Y2oA>ZXv_`9AYU|d$6RL^xkKL;eFBl} zj6>FF?}&9)ch8~CePp69`8o=BFgTO@QAtj^Qg_lJcmLR~Sz9S!|(%oVL9YVD}D zXGYkok#^aEdRXGVB~m5a-52ZHqI-8(8RN4B%sb<*DOTxVxFPDa#1FA|c13e}j_YB! zHZnRP+7z1Z_|XPpti5WX2BR|CqmLn88N$j5I}KoIu13_u95A>8UI^f^4NUsNyc-^b zqHh;$^u{W2SoMWGg}=q1qfD6uqG*VcAY7H-n1m*h<4ea(37aRV?=dR_+stq$Ud_== zN<$a=W!^8eDx4pNMynDnda9L7x(ET~4HIT=zxkFf0$khAgCp zp$n$RCT3>9~`J-2zd`$F)3sort@|NEn47dDuK09vS#B z8nX%zR*a%ycr+Ldr7$HA^Kx->Fq$O8Kw3+pv2hUe1l5uavrw!a0>?1aNx|SS^ptQ- zuu5{U2tubEgoGhB7t{UFumH(HxHK4D2cRSeZduqp4P8QUYb?wLD)4 zSuk0T9;0N>h!<0^cM)WTUpQ60UbM%mLA*~RF?b9n=3u&5g)?A34#ru~9tqP}>=~}M zzUGfd(^NbwRza_;im^5k7e}dA(3?Wk$i|9d)yryFh^}eaH42~dkz0haX?U289fH?L z$B7AepN{|X;T()Vgh?DK!l0Lg(a~s|4XYruO+;b{mgk{~J66ZS zIT9UmFhH^oDR2+O!C`pji9N~i_d$&OgJgy?46oc!KNCZ(u`wK*9n=WtRk5K8Y@{!; zVliKk0@1K`$H7P}48qq$_xObj*zp+y2ZM&Mc` z^rO{p93Bdz7&RraeIQKa*hV8lhOsgDVvpotR5ycu2(CK7!5yb8QQ?M>CU_f&``y&H zDRJOu{+QkkGVFS2h!2AxS%X4pG}eQA5{zxIBn_+dkX4LJW|%e_eJrtZ3^tfUcN$hW zpwSEraz?97Sl%1Ha{*@G`)nE8OS=T zvTe05VqPKYJ;B6raJh$w;kb2El`5{kMDzJr@Cp6`nfVRRnb@zRftjWb`Fjy_&XkrKVZrVWGV<-kIE_y~7a|Na0VU{S zr71lL?@pTedvUjoChHVBn`+*igT_|V;)MABHBo0VxVPrSX|%S}e7k^{UYd-Hu(i^x zzJ#;(noXDS&Q>$xJU&`#?w!FtD^2waP+T=bq$H?^=J-XJbkj^J!PK6b+U3aZqtTQg z*h#afT#AG=&KF_ts`0;qV(j+zcPv7wKq?R7B#YfLZWxT9v}9r*ca zW?VyaJ5BjrJno|zdI{0;nKSrkr!kQ_U~A3YW2oq**?bib>^0hlvCBkbvmf&fG{y%7 z|D`#x1LF)eMQgCVm8Q)q=+@V0EylKnnnO$RzM*F39PIu9mpRy5P4i>~*8hOBVN{NSiy{HUanjQGAW)DK#fJRgggN_Lax-%rev!T1|WnB~b!ZVp1zR~+hxogdl1 zKjJ@ebriNfvoHca4{7FuA$QqU!sGWj-xH4KnI^Zd zGhFC_A7?n$1Q!ld5@f+A`N$6LJJm3ba3LmIA#gRn^u_@pMd;(k8pHrg2w2 zd>_S^+Nd>+17v$UhE6R}yNDuqJ&2e`sFE>J`8GPLdCj=;Jgry^x)lL=<)RM!V z%a#&En$P)$kn)1-tx0-Fd94$U&tSDSuo=VZx>&f7 zWhPiLT8$kYn$Gb;{u#^39nf|PyR}BZ1bVi?Nf`@wLdbX?5Y9{<_h}0afCpM*KsxKU zz{nhSkY!skOPXSTB0orPj*RH*A~Bk}e|SEbZN=1)!&%ZYoXd{?m=wprFLaY?#jlKy z=eRfg9L5H3xgwFCA9yE`7w&UPBCo#X;biG%<+v=4lw@cmKmO&@B=-Ew1CdO7%MRiE z_mP)8DY-CLKRW-U4AZhca#tjO3REP5SAKGXGe>;n(-0Q@N9}O_{Kp$Z_*!93EIq2> zWEvmU#H|Ewt$|^KIJYKr1~aZPp60MtE&Lk67tOFYm!GO*Yz~jq7Ze^})yJzb>Hxoa zHfIY6VkFC2;&&D=N>(nP&Dz1EfCn0*P9ev%!NajUZ3H(lA&XpCz|A`F7)F;y*dk-h z&Vm%6OI>tdNZXF6Hj-)DxH^-XR`@c4ejO25%wtW^ax@c~qV5>J(ZcmP?A;z|v$$5; zs~7Qn2f6w4T^nqj#E-4t5~ONb9(jwoOA^*XHF3h?HEiAw125y0OTHEi5Es~=hzTez|DTgO> z%452wGV&f51QtGK+f4Sl$0?B< zc#AIaY^xc@n|(%D3S zO9lM)f+a<4FNNCUSn^Rd&+ES6x_lL{bY&{HedfA3#A|Myz$O3De+iS`@yJRByyTX( z^eb0;f-2;ezKKDv8MuvkKRKa<;cwV}BZs}>&h?a~YjwW34PkUZL$!wbDf|gG)+TCrf2RO&g~AMek+v z{vmEk<`C(w8p@v1=sJu?k8nyB&5p9}SROh+w-FTGGgqMByLfa0d+lNLXg1r(d$Wm+ z>^g!Awz6U@v7XkG7`K5QlU0cN+{s+Lot>ttRM`0GYP-|(2`XgxU^9IwW3)V%k?qrDWQf4YLeMezBiM)(%U6XF`+b0hrO`2r{@L6*nC=OjkVSbU9ZzFKG8bghKaC?(I6RT9 z^SC~biwChpZr5QfAILUxZ_nU>eEKD@ER{#1xGRyr51R9wJB^IE*oO)2Ip3Mx z^tr&9sRq=wrc)Q5>&v|z7+}MnQuA%avpVX4x=fEp4cSzW)l7M;F%PxlH>t)p;5uz) zw&G`P{?p;)W;D`cU2%r%@Oop$w&6uBZfnTd4LPs9jQ;qeJtwr_SOa?NaF!A4bz-QU z3=-Mbo(tRYQEzVPz~MIBZlyMWAMeQ@AtI*mwjT#u@{9GK}=c32Zd}lkJ^(tWG*d> z7_pY&k&C$OJR2Nf!Ug_Y!%4!0KERNxJR(KL zciH(6cgfA_uo@5>x{DKTiMN)`O4;=|zm&4)89F_nv=D6-%l8FFm9yDhR(Z*7Pigg< z%Wm?*bHR2b1=B9Yr0qdHfX%}1+ zc!el&1}N!{c7`etIM);H+*R|HunV+$swv%jA$SylW&Riug`4dznMsHWQ-Q->lc1LghfM4q zjHoo!F2I9Sm?hz63RTR84GsLe-W za!}1d3~g zZVA|Dg4>d=?Sdf#P*se10=LmY#{}s2!l*b{8zD3RHTCc=7E>&+R&-|zwCfLjN8FEr zz9|?4DVdfGgjt~&?|^I{HDy1$zv^XbBVQ@jK1bX&$4ei47XdL6C-u?X4eMHC zizmujE7CQvvcZMleBugO9~tyjOM&}1qD}+oTf?@2>Q}7V9#d^G zUmLZ(;iZjv{m?>Io}S3nM@=`Jwnsfbgqvb%9~?GTL7L|r@Yf6DoKz~s;l60>iK>n$ z6N;vv>UBIS_!@U)Im6Be9mR6+=+2S0p4JG2SM z4L3OXs&Bu&5Axhm5P(GFi+q@Vu^IYZ!h$8#X>(syJKA>)&!wd zl=^BDjSw$2eSgv$k7X|8h{Z{&9I$W*xwQNfiv(^=4=Vb?vHsRRnT{XI0%YIx~`Cj zc|%pKkbNF3Q(%&c!c+_!g2U0MOhfx27?+PngH)>9VnGTI!_QRc7NLEi%7qx33X?o_ zu0CQaw6gGiD0au8Q$CKQA-zDo9;Fv)j1cDrV_71`kHe;Dn53zOy6N#ylHi{Nvou^A zjH&}MOaze_#H3qM*(uA2Oi9;#jw(i6i%(NRzXK3HM}O)w@KV~o60OUOjb$Q&aAv8D@z z>r%rEJCbq75bFbRtT%GqVboJBWO&#S+wE{wN2TKU^ib`xopn*l#-mjSz38mOig_z>AjH(GS{Epll7@TF`ZYzZ4$HguE@{Oi|GQ zx9qXC9a5~}RTVGn)EIkLD_p9F3JbVbMdog8*?~T#U(p5tc`!3SXl!u#&}82b3#kN*9LW(9oO^vhVhGx%#Q348OhGdib5hvlxP_(g~}*p7e$#78QBzt6sag9 zB@r^qCZmj$m8@|6?&tTdiBDOhRZW^)|>$IG47-%{Kj((tM54hitA>4N6Jxw-{LeN~CU?JrrRi{uhE zXoKoSbZ(8$_ZZs(5;-_2ZtlCxX{yp+RU6^jY32*}Mhf`an3PH@ZA?v~{x1bhohpvb zlf3<#PqMhT3gS<&Oan2pGpdSjNBHF%o5!mIpXG71f5&;pm1)#W9K__PUB;Qv2!OLn9qzh9OcR6*0k~DnU1U}+pFfh@5;i4beTc>Cd{A223pK^qNJpL*)m3x zODq{wi-#myQ;k#2n50EBQ%3yxH_3=~G-y16j=%qfn{XKay)vPDP5v_FWleS&z}A>_lyl%#r+FW2xTWy+3 z-@GbYS+ct}`-`PZlUi0Zs>3$s;;G?td&X!hUr)}#gE_-Pa5^$GFPVdVpV_69Lpu{Y$)3( zCpI?Z3J>}W=S*)tvEx}k?v$$g41PCeEnl8BVwx)xjhXGitRXb<<-;LdKZAa~*~5!_ zjXA)MHM;WDR4z7RyGbgka&R0=+c3_BEBo>26n5!KGe?%SlY?a@^kTt84mV)5i-g4Z z%axl3u-Y`54`x*l_B3YYEE-cf4VnJA~roO04H#71i z^-uEaNfsaE_6r<)jMI|&MUFVmGT;;&UZ?3)R~M=BsCPx=h=*T>X#--YZ$N<3lFp^Y#a>dC8;ixceSU^V$18&wr-tD{gy0 zt$cPAMdMxSKBM)0E_}j9xg2<(-ySg~k79@Xc9;8;IqDj9bCt4LzSg?Ruxv&?Vqp&7 zUE+xUQ>g{+(Jzg|lGrPQO){95%lqf)agjD@w38#6D;#-;-_J1MIvWcE{1#0v@V^3j zW$@W6Y4FkUF;{2N@);Z5V$lnhKTg;-*WCb^U;+=99RdA#HwomE)hG$>0 zQhudZ{8GsH=bZY3Ue6f%mJi-j_Z=rb<$_PtDP(R5-JjFx4bK$O?GrVgvetKozh?V# z4wPuwCl);9u|gJ>@!BV5J?E}3>{7xtWnA-_&pvXd+?77j;VbKX<%%zC@QV}WyuFfl zKJ(`no~xh-Q1=siSI4hHUTB7#Pux@k1#g-2hjmM6S_?si99k6@UQo9wcD&^X$W%%qf?e{s=shh&YgoqITkKq+C@cTo@#a~s5(ry9XO*&E9vc<0 z+9OWL=h++l?+$C-rsE9`&7_eOAB3!OpWCwd>Gz#Fd944JMh|)CJDWaXdL@0t^sRv|Z}{ae56JWUgN4tyxjtHoaa9X@ z$~meA_LR|4lCBke@r&F4@TmqIr9@d3!^-)yCXD{jyBdNuu}@&F_25$n^Q6(!61kda zTpxW~<3U3>N?gAqF1Eu=iOn>?T(KK;L0nJhbbzk`el^DuL-gs5gtnN_2CasH9dNt9 zT8V8m#F91`V~n^?$nTD<*4UtrW{n_;ua;898U;Tg{7c%u4b}m1ijTh>oESWi#+?K(_ zul$d5}CbZLvLp=J~G{l~XDsP~hV@?dLWVngKp<@Gk$A{C@o7%M-p zHEvXcbVkbl@@_q#Om2&q^plqwpp6)otHJ6eYu7@lR8z%tc9(?J;vg8U^;$>Zq@{BoO5lhgnr`U3mk zVvlSZyrPUC_uitk4E$fRWj5R9aYX^|$$MBNardOL%Z7K^?g`g_P@01}pH%d5^JgX( zv;BLf-{RS~eDZ`T-EN@ z=2MpcWxOoME7W;covM(D-kRzd_?nsDl>A-$pTI7-Oaq=mGycQx;#94QZr`|Bki|ue z_{pK~=pa(OD(GDY?>};2O_)ltSK4awmZ*tNl{~9~Y8CXZiNas%x~lVA{e<%+yi-Gc z-%tZ4QrT_@`SX)1dGrJI%h{uZF`_3H?xGmXKXBGB?*G9+c>}y>csXB-+McWMQ1iz+2xyApR_N9k z(8KB)7}6BE%}~}Hu{AKcHYRA}d}~~*3nAo>ZHDNMkOo|TT{LKkfxYmzg>s|3*8w`g zwmKa8Vz>D9h9OoD0li_-6kP^mqCVUW(Y-ke2I7T$oXxPe8Jv6JXe&4hNwpb{3u(DE z{_BqjX%I_uvjf}*!LB=M8N*lhZUgYB6J8F*>aN(_2ZrJrmg1@bM#?Ff=xAWKI1Z~Dnq9bvA496|3kK--q6tBEEp z;9C>j+rXs}idsWPjlRwBrGf{wutWo6+8~ph(iAUi;8S~;*FZ=E)UJ-jjWMPUhPFjv zB@46^&&|9QN~`0TR3mF+jy9aCVMQ$^A73F@hW{YBf-GQBBSck2^Xjm!g4KWN_JcW9 zk*KN6<{N&~Pgu%7+3ydVm#W&@ijTDY&b_7FQA~|OKKQKsAU8_X*NfjUF^}5MdFw6{ zq@I739Un01F`wUK`c<0cv)^6%+~CPOEPTYgEP4x*XDe+gV%;Arh+$t7Dsr(l( z`w_q1q+ubCX3^vU2W6;xcZjU|?sI)2ZSz>3#C}f%BR~!L{tkXh=A*+tFcyc)@ISsc5Y zg&EwN!b0IBAK>+Kyn9ToGev_Ef0aE>bK6rsO;f~`;v8=>9g%4?ek>h2t zn#Qy%JQGjryS$#tGkJ8#qhc~B?$IgM3L@Xk5zKEe^lIp6@}W9fC6 z1J1Mg5!xrKWzVS#^onOeGIL{jMCdLjxb6aL#PeMSYa}r88f%#aZjwOLFN)Sa^c-c5+23H}2u0lf1m0ITtxFg2OY|br0{# zdOMom?y1?U##JtkWmqoTr*p;)e#lXbzTsy$TijpBbMk8x@!SLIJm7-6 zymgcR<@4?fHYsGvGcJ9>{a4i5Z}V+ssL?E><{jGQ(e4Qi3m9^bZr8c-Hml!c>Uox4 zqD3xGo#B@gEJ;$Z8i!QYjHmMvmLKEmOj?~}gLLlSO`9aX-^Jv!3_VJnGprr2p4A7( zgb_jC3rx69|8x#J$?#Jgn90yfEIG%H*H}M?<*EF2MZFCc6mWh9tuAp(CbMra_O2>) zI0|AYkA^vldhIRyI1zx};>}xZEuPRUw!6fox7qj%b#HTtJiXcUy2Sq;b65&jT;un% z+;~|nT*cAjn$49WbrrLA26L`3Oj7h0=ya9Mu2P!L`*ZjzU+sXtKINNS`h4Ks2OR#H z&vRHLK_+=(D;a#1o4=~=Npua!W})yWJzubD6+D;S1eA2Z=MQI>Q>QV4K2WCyG-XTD z8m+$3wGRAiAVwPps$iZ5MpnV5YRIjIH{yb?i@`NevjHw@qNpa$)y0X%$k#-bW;oXj z*^OZ%>(V+{+X3dav8k0(ca3eY(p(i?q1_U%1@YYmJNqgj%g6y})IputH_*p-6NKxb zVLzC5g2oV>>x`Xal<`64HAnPS3{pz&t;V8NF9eN8h=Iz8{^CM_GsVYFXkdxm zts#Sh6FMq%y}AK98{vlzIvQhnb2Yq>uj}{2?p7E%7#0oia3HkA2s>3~#$yV@w9i~e}DwZ_g#*ldTtc6c@! ziM9xmTCRh_vrlkCxHGCdpi-cz&X_n|P3RnEqM^IOxzC-YGPj?7@X-zKZm2IZ7jLBd zBGd8zkXU!La7L#Y3d*{4Do%Uhmpim(!$Alh^YPsenPDnSzIHyEdf}%JqNl@W5f*!6 zxP)VUv1T#O&P9xt2ekiGaCdE+2$f6gI`dF9ZP_(RvfE>_qlnm`38p8g$+bovnDe4hKW9 zJrws><>qBDBcI->tbX{0mmO13-D(SE-XW>Km-P=)#-Mbh&f~DBJ}gZ zdM`xHLkkbgn2S47^q7f05;~oM3)3;rUrlD4y5q@oMM_C`LGBV12}fc%W{Q-=7x^<_ z6oh({aAP6vdthiNC@A$s(3pms!Wf^5k`)-~fi|Hq4#b>LOj{sPL%a+|Ko}N=sNeHm z2gW3GIBaYbsVQKp!`hE{3l)#xFpgD?Y7&ktnf( z&|@5$_@mfa$zFYIFj(YPlkqhW|4qX_DaAbuI7&qf-uD! zU4!u05fg(^Fb+~+msE!P0*rM*M?dVGgBgPF5G|KK+}u?dTf-NFT_ks^Y?8Wi_45QI z|33p0CnMVxdY(udgMZd&WeG2-A;^T+5}U12+X2VNpxFdyTcGMF>@vfw;ffA@e-s9d z!@glyVutY}uw)pr`s0TsCXI!gcq#{=(`eP3ljw-|c)Xf}G-K3o#bO)9sWubB!y=KZVvhmqkT4$Fp)hhly42z(p#2hTor07V z$g;ztmB^WiI$_x4p{~i_r{a*jX+72Dw1#{N=Hu8jRoL0@hQ@QSXdY_LRiezZGgZ;1 zzFaLGFlo9HqP28a83_#uY1m`61O8g!xh3))u*wm8rsAIz{N=9agqhOfpMn7vNS}y% zBT-_5>K4$NhCHE*OhAP>E_uRwJQBxZw~e|1^%|{iH&3h)?WSl*qO165twcOp(wBF@ z(!rSQgq>FE&Q*H^QtZ*u5iKX8x}%fw>9J z$OE*(W2wLlh0_p7tNOSNW}9Hw7=#T%#Tfh;0#mVp^j8I+rhU+07@8SixG^HyqOmC| zyWpt-PIW=Yekg2&q0KP*KdjYLY&uB-zixuTP4KWGu4`gqT{!(?&ENbfi|2o=5A2g* zGx_l!UFF2}r#iV^Qw7Ois9#E-`)vD@CJzPKN4K{${=l6NsaMFKdHi@wB_X3PF+7>) z9)%vj5x)v zvW-gSmRM#bv&%uQjc3w!>L;;WV#x>Su%APZvPA?N9pdS292?E2k!&Lqx2@Da%%aT< z*w3sjJQ+jBaIW0VZR>b{BO3(sY&fg?@pKfchw$Vo&J`5rN*)X1?v1P$$bO-WTcCuD zdW$(Rgh}(+a1O`#vS=Aim+;4YF7acy`knK|>AFC4n0sQO93*PjeO`|#LsaQRY{xf;nji+YvzZrZn zgWKKtVm3cb=TtAA_hPU=eP%G)n=Rc`mbk!z)u*ug1Qxn*yEDH}B;1%}$=r!dwW8f* zYE0s5YnDw=BSHfc7L4aD;Z%EZ&;-t($QstH>q)JVJZI10jx3cJs^mpI7&C#cE_^hT zP3Ez_H=~1?FpX>Ha;86<&7;md4i96-d^TCf2LX%|UWa50*YMLq_TI>}*_;~1zjOF> z2dgaO==DtXVPYh!gtF}+F7%`EW`37Pv5f~LaUH_V{?rL!*>rwg&j0)w7{nUW>AFaD z4IBfwK+p#PeDBGPeu^3U&6(Aw@|zQ1P3BSI8wm4!7M%jP!ISPDJmSOkGr7r|DJ~p2 zoiR@I7W$A2o6qOF1?)AOH|DclFny*_%a`MqQ3@2f{(QBX?|oP|lwU%)DV%TiI?s8f#MmjwwcB}D-LvGFB_hl%DWR;;mDhoT$CqPls4<yD`&>lWo{!2*0}U`v~ezX1C!y z&oWAcKpJ%-j)Xh^t{SCRwJ8pi&qi@;hJ`+E2iwrT}vGgsA%31Q72R`%o zYu@{%Jjf0HF!BRKszJaJ!)oL3X9m|%bBCP`u;MoN*TS$nTwW7~FZrYP8(@YQgvquXToP3+VO0G%XYi!VqckbVgJ& z%#h<^T?`nAPaT!KwQo;^55_EAoHxaCL);sMlYLNNt^9_GW3a^#-5gMDFg{ygxFH@- z!r#ug;e^ViNg=`bRHG{(2UdC8S^$2dofkRY)w zI2ymD+TR}y?4dUTBgY}%1Qs^fI|8$<;Wr42>|kt$>9ReyRvq@BUP`Fi+YH5aupO+J zc!h&h?C@GO5daRPPUM*<267r!Z_E zp|%5GMyi5#Puc#5EvQ^Sxl84Xvf|E2CKgh&E#6~bJgw;o2$s%^S+9)@p2 zHE98dAj%V0BM=vW#~bi>3A(ID%h{;81tGF44;EGrW(FbA1LxPm$VqK&+DXVW2<9^o zHx~mXNhpbEFNDv*56Khysm`)r0NT$(o;$`*My)w2hrG`PwH)z&whD#%IN->51bJbd zCC0ibS4;k6{AVwaH(Zro^9{h^Uy2+ z*E~>VCEojEbr8PDW^f&bFT|Ktun5G^6>wdHAsdmg7A;o8CJ+bKV0RcAZcv;0?y{{2 z#H^(_y9xWkuzoRSEXRW-s+7HQ6?QI!{yKCI!?*Q_+KAdaFn1k31Y>9rw3g!TLVVwV zi*wlAr0!&NoQY*F zI5-QvT%kE#x%pk>rhBOHaHtQqdn)zhN*9&?eBpss3t%C~DI0Ot3%!=( z=X_L=UAYhZLebX`CEFD?L8`tD<@_WHFD9!q2RS_Hxd&V4fzhy-jdM|mpN|jwU^Nfr z+t9!rhjwB1OeF8Xw^>p~!;)FB+JO{7H|#~jC9ph%yGt-M76azv<0THcee=m0dGV761qrzRXn2Y2*1gpkQN5GhC~3_FA~ zlI=eXSFxMzMl&b$j6s$y^0%O~J$`S6y(O;h##(`s2jk!nOkNGo5qKPkC?jM`etr;M z$c}h0^!y>LrM(iF5SW%zh>EMqTQSeEdf9coJQ#2a7V^OT$`epJvue@W#{LyIrm z>xTJXIKmBqU-)ST-UxA8E+D@thlkNskmCYd%JKtktDvs9x9VZx6g>P(2WwRMM~S%i zYJh5!Vb>6C?cl8gXNhS3he?+3Y>J3cSg3`gV{t(XQC7ICg^-czPktSZCfe||gndnX zG{?D`s4^Nqs$!KTM*WjK7*_sJsLA$n2eE{SoPHbQOa(t%Vtt9QhVZR|U*zgn!nWpc zeyqfT@_&^~gvN7jG{>(}UbMlVchnw^YM+^5gI{ksXDnnE+`|cf%hmT zc(6k$OWkm|f|=9t<0H@b;M5mhn}bo`SSi`#avq8z^cexk64;N1Uzy_AUwzM;2AEOI!9!s4iCuc&mki3gWBV88bi$9< zEFOTLA2>*^#!{5)gOCTL9&SD1#&$?6=D+?hy2F$XnEsNP21*H;=C zKOXHQrDFl>vr4BZ%Y%qvaJ$UvGBrNW*#i{1P}(J$skJc({@| zJ1IWH^e`5_qs9(ie$R!$)ceFbJ2~_lJ;HfXg0&I!e$OKt*jGLj+i6g$a;+~u@Yn`U zeaGor7$Hs7NOmsc;c!~L;iTE68df8@M1=7WRgUAgLwW8 z^Mg6!6T7bBumYy6VAmo}S;w=5+!VoXMMAUW!q;3E%Kx5Fdnvy@W{F_99&`F!8a|+5 zC`+GkR1m!i=p4r9c^oE9F-a<}=DEAHTBf2h6N6}yN0Ws#xy?gC9G*{Uc6Z5T(IPgx z$9Nyr^t71GQFp27#1%3Sm+jAG9-PROEV{Yy?HLL*@5gyowdLt7#@j06#%D(cT%)-u z51yo+1&=4N(uAQgJT`z=chkt4{f}{%B_k4eY79+}DKpfX6zYvr4vy`Pe3HXZC)N`i zh&x}OReKp@S&%!@>jF(Y+28`Jd9w3uE}F^Jnbh&+fm})h{cyG_Hg3~*|Bvzpe1uTZ8!i97oM(;TiUtL*uh*i*z=P^B2)Yvbzg-I)lMt21(?QSyXIQ zfykX=z(S5pW4!?WI>{FSOgT)$Wi(0Pyk)$X$tC`Lc9JWX^ZHR5tfAgn>aOE}3+%du zhb3IGl`X_iy_<5$JrT#91>CudeV*{>5zc$cK8HBs73T@44@g}8F+R>Q(ioUMsPHE^{7dWgfi9wfImu`SwGMNlIoYoS+b ze5{YRx)`X97CO+@MNWIH7OGfB*fht%rueS|=Co8By-!Whp);!L;!=}iFGM+YtX-`y< z>e(Rm!*32n{b3l?4Pz`|I1ui7INAg8gYjM$w*6t*R`o}!w1%OKwq>W;OD!FByZt|n z)(Ovb5!@E5bP?SHubZiD;Gw2S>kI#S&=dV`UCb9DZ#`rgAhU^LueH)tj!PF!n3!N| z8+iA}$Tp}s4EaqIdhU}hjtxX{3(Ox3r;bSLhnel+HX0ei>K_SF&P%h;S@8Q7DD8=R zMmVbnJ7XAiMT9w0x~o>8elL8KU2`8;m|}MqJTgOm4@I7N-x|h}1QTh6?6TXSo~e56 zQuf$ zzS2KopOP!a;A|}vjeuWO*p9`{nrJr+_FDKl3LhHdnIv`p!>EzCs*Scr2x_H{0*V`8 z%>cA%jb;*r&_eid_4ST%&=3*4v=mzkEC@lhG28~Gtzcw@>n+hnmgV(San-jaj3%P8 zAqu@wtu0=ZeL8bLmgKv33zb%062wV(NZPwAt zutSCyYY=LQi5t`bMfXrlu)*jJYFc!9IW)}RzZQ2b@K)xhli(PH0Ba16#5xD)uEt6k zA?-%86C%Sg+zypXG0z+!YZdo?eH4n_5VsE<#-QeQY#W6)8-zNGti5P$g}>YJWjwa+ zMh{C2h{NHr=o~NHa;%NPm=Rcg3?5@}=$Lw;8|=Xb8_Yk1z82VU6u$?G6*Y8+FiE8`+e8(gFq%!0VIF7&8*s~9z)(DD2sU?OS z!_MK*jaRh5t_k>Sfs_nfHAlBIxYQR1&cMYOBNK6Q6waT)VKYQ0T&p6!aEtB z<~W(6w$l6eMcch-DJaWm3>t+C z`_OR^%=W;)JFE|&PA}BnkAXd)zaND>>KN_6Ei8-CT$$OU))(KtY*=%+2k&PH$#P>JHS<(MuvtRVEN zjScG&-59Ue;-EIJY`_8?wA%vnwy@fRrtNU_AQHQxY9yv~KvD!2OT2$Q3Yy~jKAi81 zA3N~7172)GRu^oFK+}%6Ct-=Un6woIUGZ!)@;jsZRz&v2)a?p#7#@PAqRH5xlCD2C zLom(_Hb8GA9xOwXPH^3d2Ypd>FSZ)NA`*Z5AbJbd8XG}cc;lE!lAQDlI- z$MK~D?aD3^6tTk|Jg*RgBsE5-VaHbA4!qC4q zeyxUY4Lk`&ThdGpSgPUW5hm9&KZwr`_ReJ|$@ zfoy?44Z_r|9MV+|S9w+&erx!;sVGJ0+8l*JO#crSQ|MY3v*z-I227`O^>0-(bot5J z?#z3~N3%FzPIX*(_#x-m@xe1rcA)(u9yI0$Ayk`*N0K`&>7B#G(Yz&^LKEUH&H8b{ zbp;F=f0^t1aiQcJyQ&qYp%I5~C!c1k&itLlbvm4o!6BVhpUb){yPcs% z4;mcdl8!udl3#kWAcM~bs8ZW^J(fz=w;y$*Sk#e&4>PV0f9~d-Zfv@Ti@VcgCreuM z_-0OO$BYBaZm*K7-um=7#O2)>eVA{Xvb*#&b@^g9r|9$eQQpvH`5|WM(`*k$1F+hcH@^cUg^&FXLw9Hn+Y7CN6jQI8pP)r^fcnx1or4h_v0Mg znRQO^hXFe!ajOCCQ-m7FISCBYqhl(64xr(2-sr(E$Jw)+0{&$6=JsUX5teu~jruS! zmR$@uM1&FjXn%+=hjY*o_Up+m`?$)Gv*iUfX6qxoI*e&2x!;V-k8y}OO%BQ%iT)=! zYnWmjB@W}`1e)3LVH97P^4Kw+x8w3t)OY5qGo0eXzOr?iN{7?b@#M4Pd??P%SPt>v zsT3ZX!#l~G;lk6G`OcMZbC~bJFxf)-v-~ojdh^jeTDfvnF5_I;`vMES*zgiZx-&_d zcdpFK;nyjQ&F0bRtWrQ5Th6+|b{>p)#(1f<-c_p2#2X5^=5bdcl_I37HjiUo^MWrE zpVL%uMz86zOhtb?FJhC2tiF}6p3*XeWAa&LBZuAPkZ`uU&+WUJ^O*XP)PK&l;k;JB z(ij#$W~XiZp2zC@*yIW8#&GmCPTkL?1#A?@MNcTsk!c0|9mC5n)YCrZnrad)ddi{6 z9Qufj$jF5#<0?k?i>Wa72jQ|~KdUM7n_@Wv$umeVqYnr~Q`%5$IC z;uyPrptHPipBR*?5O&Yyg?`KX$JnZvl_z-M1+ONt_iGM6z=m(Q>I4_Q;;K{hf5W#) zD&ah0D{V`u8Lb*m&jg$HkVp4&mzeAXjsA?`B2^cVT{O47rp0DnE9L3EG`^uc;PTBU-EG*LtnD`2|keHnzOuhhwV>r@gr(U*!Vur zq|@gv?`LztJr<{M*bSaP#zEKk_5!cu&@zdqFL6ZzJKUuCagNVm%{X2?&wdBECX;&d z944`PJY&yr;Ry~sMGrxEoo3ESjyS>G1TH*kWbIePncRGKk)8rzvFLFVi zGNd0q&m+lfpG*5pPPnFMW4&+E=??ebXXs7F6w_7Oj-R=!kk#L@=X*|h$3G>^7mMNt zhQ49D@ANOC{TAtfVs3GezV?vRh4@EfU^aq{(=?S(0{}u|H1GXPiVtIn(rN8SWHP)M}1&K zFZ}$=<+4Hh#dqeo-vj}+7z7nn`uZP!%)xyvMGkq_5!3x~tqqne#-_eFzZAMX;VMbF zZrBrrvnH_J3a_Ei+l>AajgCRD0q}`|m+a1VV}%7C9K&7L4uKk6t#o zcnp^Z!*xF@N5bK_qV=vjgvUbsPDG3unw}6f12)IwpbaLTLY6Rxk7AY`9;G61G-jTJ zr8~UN;p-IaNme_WCTW;HP5e7Bn2hdXQJjc^bToE=c@`=rpnfK%kHOF!EU>`%vuHjJ z6SFbJ3Da`X%N|J&v2QfGp2tK7Xx)UbeMJi6nfsQQ-uA`eZ`rU=mD4fevS?l{*YKmI-E|yuzK{wKe zV)G636}b9kj1aNcIe40)Q?BBm7F_S8<1Vy2;F0vv~SOXJQ;jiGK!jbZW z4iN~fgZewsR0A1N_%5cZt&lWV%TRd!;FMrhnzLMoHXnI=1Jb{-Y#A>7=5s;Qi!5LR z9{ppL^~fVvFGRg}bPk40qX9I;c83&mp2(Es6eHRrGn$TCc(R)ZI^)X#4S-z&|8zxC40{^jX*_ogz@}IZ zH58>RuSsj*F#imIw0@osLvkuRnZx}kg~c>8j@ELR&arhbY&p(fk|l`e?hd$dnt2^?F_F>)OittOrYJee z&7H9SB!{#{R6Ju^Vb4MC?102rW;DW`LzI)B7Afk#N+M->6I@Q@JUw}Hsz=v<5BK#z z?KrkDM3p%H>Lnsn?i!2^hgoX`^b%-fg6Z)*J^+Ic@y%$&ou@#_zNOR98qLp8a8mbg zDT&gjJYIJ~v6Q?#mH2P42ksTK-F!H_W&MSs{iSpOwZBoO#;LzJ!3$N&*)9YrRd8=H z>eYru5V}`~PY8Bss#FJ89aVdFAPJaTN;8SY11#np`XkY2)6iw7op7$ z?hMAy@6?zJi@$s$==f?_wHWxx!^;r}+zi3Rx+>nkttzZSV55u7<#1^Yt@Y^N9uvb5 zpog~WalQjugkVPxjNYua5-r!jNf+1GC@o;w0d&zt>Ke77s2h${L(JHP_dW4191{%T zw+(d+Fh5-3q_o2ks|&6{nhxy!@UAV|%Oh%o=0RA|3@rn(u077r#|(kVEJgdKY8L;k zKEC_lurB^BMAbHGJiT6yhU9psF+%-O+6EVV(W*JtdZS54!O7xj3nizRu7@FuU?^$Q zO?c8mZ3cUbOKvS@_Q3IN7;S*8a5#3urmYCoN3T$ zwTv2}(gi8n$e#fFKiqAORdvu)g0la?eH2RmL)<8&HoyTB#5KgWv6xyPmcy_?8^g?0 zFLM4MY;TNq(h1VURAbz)hyKRM(L$vh;#E@zj7I-KWK3@xs47jHy13dO^{S&yS4hQa zUQcYSiRS&Ws|G51K(ij!bV3>s(+l$d=5o@dB%>c*>uw@Sz)l!k&h#L6U6H>)W?TV+> z@MAdq>*9z3cGptJm~!>LG!UM${Lsf4acK63_b;|@iQr29>!>6wUOMPpRS7Jr{^4(Z zHTiYwg)*5n_r&ej!hwOsJ7zaWrxMnZeX9)Abnz&ko!Vh_0X3VV(L+9N3mKnn>4Ym% zqtn5q=ajR-VhR1W!h{Ou>foVtoP`nnol9DvdNsW7kM0#rF~H(V-t2&ZP|UaFe;nBX z26b_C05&v4KtJqns2FR;O%T!>bvt4AV61Mc+FLtX;-VfxwPCG`BMqV55NlhZT_bq5 zM$6`~YJ{(~u~6JG|Cm-E`c?2u3#p`2J+vS{3jyOByUOSKJu6F1_% z^^6POGx0SSz2@ha3@+vK=bZC~=On&W%q`E@T`FvEnEjH^-ZK6pQ}46yC(e9H?@9$~ z(0s>!uXy?cbze{-(BV(nu$&8Cv%^Pby`$y$gOc~dYd(qSomdHWH2 z6Kxa!$I*Gm_1v~$_@rcolFX7(*$K%?MzYGNluDWuQ3=^XWR%j@ z)Dn^{BP)Ak&y2_3d(Y^6ulxPS=lM`Qzkc(3U)Oma#}`kYOJJlAXUFr>MD|_H@Ue7S z#fy$y97!L^8%s!d5O*%+V>_Oh&LczlXgN;~Vykd^*{B`yjS;-Nlo~@gCz{WlsIyX~ zMvJ5Q!;RBdvh^r-kzaNUZKG)G#2#_vNDi0r$S@9wpz&aSTE(p4jFrf)GhfeO)KC@K zy)c?sDAHIuhVk1V)?Gxip&T}uSGuv)R5tF(+kre|$+8Kw>&Q;t)alIElhxV3NaE9N zSbH1~bYY(n3bJZ2n$w!F=SWsjs?d%ClAY zdo;JzVzLBZHMx2?Z~v?`aOO}A*7D$*-<6vj`R`k$q+9bfm?g3E>WZL#t+wJRnX*!D z{HuSJ)!gY^ohybhwHBjC@I-YUwBz|&Y&3``G-R^G7xj64F#YO@*^@u2u!j6JZ5obY zjappn!mYKq(ve-7a=JTH>T;kH_toYH7e;BZt0x0>sP81~dQKY0qfI%`j%S)N+K(}f zc+{89_1V;uwx;YZ_m3_c2wS)jL&np*7T-?hvzk2M%-Xtq@0DMM@WT7b+x=PNWu=Yiz+P8oTXXl5N*OeDe_L5@$uHL`*IDw~^~xQ+X#Sv5 zuM7L$sXW$&vDYfiJ2C%$3Z9R(|RtLx##? zOOCu>xwt!DKB{!@MxE!C=lV)>xpLzW=DwOku#4(rT8YZ%y;6)V`zoNjB_qd&K=;)mXx5Y0}b zn32Fv!?{fOg!o^!yqc=;pim;NCHqx{=9X4@Fd#>0+ z-2sfw;qqSWo+oJ{KFH84$-|wrrS8+up1b$rpV&IhF=? zoVl3Z4ty>6XdC7%Wa2OyM{@Qs^~UmNIHOjwp96cX;4^uOMlyC3d#~co;T*Y&8(mnm znmNOHHIAoU>A8}*_I$LKUj+o6$0{-ni{o#9T4XaQge|tyAdpD~{5gevxASr+Uv6gA zVBXlqqf@wLKg*}FqX4@krhb?uUUWIawSnBdj~afQSi)PO{8!Aco}6-sT>_cBg`cN# zeW9v*nCxbk@%)~ph|^L|*B{R#n_2F~lpT!n$waU$XEfJ&tkKU^q9*nsk|_cn{(JXj19BcVLH#PMpC)Pir1W-%&iif*)mKxj@A#?k(h9A7ZYE zS=la(@s4~JLQg-woXLOV=rc=Bg1kMKrV|g9cLxU)9%W@4>%e z^z~-bg5`^IFGG@ST%A2XWggSS&qKX?4vyUfVIz4?<0#&F!P0?qUi_$>>+Et z;tbIT{8X0&6|Xq_G0Q&Fv0UM3dOu@la?ulN{ba;*W>rxCJ{tnxK5z+e<1Lp|L)r@( zRYmwuE+?1$pk_6NoeZvqz%Lw72LoTJpHQa?)@!2GFE;(lGynLgg0FDwsd`XYUAS{7S_a&hNxNx7A?^AFY_AVv>tA^K(r1%G=jZ= zB~4WTW0I*_Y?XAu<+?EKhGBZpv{8S)ksWJuSd75N|7SZTjc+stJKCY#0~L+1OqjHd z@niyyG(%l?)M$&5Q&3@wvHl3?iV0#0>w#Q9WcNavk6P@O2jahe*yn}01JKk5M|&#S znL%Hb$3F6ZLhO-#h;oCT*t?`bIRrZHm^l>JoN(F!X)gHKAH$u{)D|no;P+6tiTZp9 z26-TRAil_L7z!T`#K@msD7L|c@i@?3yso%39RB{eGZe#vkvvqD#|;Ky$2i<^MQ8}p zhrrug)&Fbz;bb3JNRN1svinsXiuwY@bwHz;s51@~;m{Zf|45XIcWeQs$<32VjtdIb zC_k6%IZDPiJyms+rxfC{H;xpcvsixC;eG(> z=Yqi)orOnJFlrO}Op~DpOv4bdMYY#8i_v$ck}=I)h@|cKu^4|g;OjipI0T33=vaiZ zMQ|)ZxmXd4pfw9Y0x(^P=wfV`k3QSrGY1}$Y!g08I3WRkcA!kX>=2lX?L*b_PG)X_ zk*F~oBV*w|08ONC+ZT2#amyX=647lKwud9#0j|j~v&GP8)DjR-6xNJHk5w2j5%GzT zuyNrUI88+7L}X8dO*Z-k!)p^_#eTIO<)P~L-7_C!ig6+seKuplQiPSjZ7E)z$K;h5 zeHe}7(BcCAEQZNdES-zHm(Xq*`d!8Ig_v^{7K>nb5i;PKd;}Wtuq(sOMQTDAy8;hS z;7T~!AH<2-=&=JD!Qe(136Y=x{rs?hE!O$LI$4D8D!u>D9a>Qc^Hz_q;{;SL!ze$D zO2iR2B*(*NEVLHk(|Fj5pH94fD=~R2ESJO6Pqn=Fcw@*acn9EqG`2gdo^@#eZe=3a z5B^!$;)={I80ChKd3fN4n>koKUdCCdaKpN7xay298*#`EIfeM*j;fn*&jY=3@p=O8 z7vYU7Vsr6#96~eTJRWnB(A*R4ve4caZ{lI=j9V+vc??js8Vyn!UF{2PA zy7K`DUxLXtXdVu;?wBc$bw{iWMWQuqLea+@Z$j{{JBnuFeOpvcMg5K{7!%YJ*CycQ z07&k-xdp-};Iu} zu}UhyJ~%l9eS^?_loB#F5cQQmOoRsSk7Z*pIvC%5m7CJv3-*(-YYa4nrsaW!ez@z6 z_91Ze!}S1c8wE$H8;n+{kP(BBA|MVYv~$4%Ck*w)i=h}ZOpRskONxFF=75NGjEL;~)^tVPx04DW7p*{BYgy}>DwRU#K`+m@xfU2GF#S11q zG20cl+T-LH^y`D;6L9qZrKBrX(DTBw{z!4h^bu$niuJ=W)kmeRB!$w=1}0Onsvpj~ zA$tVA1>lbpv?k%U1NQskvkh8!VZSR9{op+Wb;gQT8#ew5?IN199kv)T9CHWb(on<= z#hnpKit1qnTMK-*!kmFv+ZXv(7}OOTtzq03T|25s+lKC_X^GjwaJGO~Pt-C~p@?1G zRaMHPJ1T_E-5rB%u)qvWBq7!x>5}E^h2xg+?SRjg%5Zwk2mxl0k?gbfXltT~G=|3L z+e}3!0`(Q0%-Il~nxd~UJ{V)E@EBVlO&=Fq;eBTeX^u8cQPKhP8sJ!CBV?t{L|D{b!wExScatoXyD`ndK@$+OD; zvSl6I|4!fPc>0>1YQkRZT^f*er;)T#M8T|$372?I3qJpGn=a-);8zWJ-KDt}E?i^J zS}4Cr^Pik~jMf@(y~@QOSb9)7zPnvevG$*(EECa~@MGUFu#7<;SX)dzPZ@rcW{)_3 z8$bMD=vlsf#_8MmTYS*R*g~$acCy)XKH9_br@VEFCeImvPRWcG3hDYQ6U%7$gGa9M z$v1|U)Abz-?$F_vS_G$l=aRcz^#6t9L{0R6$DTqUe8wl_>dy?QhO=K83WQ6Nzdp8p zpn+hQK65}d)R%9sg5~d-Rs}nraaK)y_{BMzsQQhEeshsb&uZYExT~tb@)KJLfc-lc z*1^(G^wY}ZPuJIrYZBU>DlFLO{o z{EHwOY!x%`dMBK8#S66L3~7W_BcLILQ~8vsWI+!|E;_w47FU5uC**#oaUbaa;t?}E`l3{TM}P9C z5n`S*+XB{tcs0U;4{D?w{FZX*+vX)NH%HcQ_Un#m-?&Tm2ygjYGR74Y0OP&y?AaC# zWRm%Rvig+PNPf%O9dPwMx0~S1GitTLsVD4Vj^m%y5~}|bO0+5ZDl1#y^DQ=Njy^Xj z`i$9U*vA0HWxUu3KaR3{J=uy=qc@UYZ94zNpY{3@fHK3>bNzb=-`d88JWU7?Xa zwmjw2W+;EfsKyZdZx3A@`Nw;DnEsV}8eo?OvRWanlA{`8WF?y!;H(b5v{#h)xHkCJ zMDb&HHivCjbZUf$*3dM>&fy4d3!}d1ZiE`Wkzt5Uc3363EPE7~Vuzhtpm^BhmOefW zgP-6i2V=b*Z@|8k!OgFVutO6>$do3j76f8YlUbjwY5W* z9Xdb%c6@O&f6P83}Ws;-Uk zK>aXv`WUkmo?gnutnG^Nvv9}}y%%7^cxW%i(=j+d0~+?2IUU~|QFR71MSwdQ)f_P` z9C`LCCp<&~;S*86H>QUnyuUI~JnfAaQ;^d~T|YePfks})m#nN0_FKSTl-cd!HX5?W z{OhO^xqc34+zSpaNVY;fxf<+)5a|~WR23_q?X@o*~6*t9b zNBA{H!~nR|M<-k8H-df-IP0KHtnqs2-x)dDIM^B54dG-C106Im!}r=SkQJ>y?g|M< zQk1b%( z9=&>DmNRAzg0CZ52z6%^I`@K=v&!)Q9)tc};X4+mx+B`j1yZ{FzhUQeH{7$wE=zd2;8GuD@t7z(cLzLaqaxn}+8}lihIarYC)pqG24Y8d zoR(iuy6yci)DmL`;9^JYlDc|NjPI-7yJF;S?1K(N@wqc9>`*iSf5hEvg~Wj<=!h=^ z(8dZ=>|kiE{MTs~NE3$A07Qy=r7t4IoYE6#1^U-pxr7c`VfrxCvOojD>UKwbOtNbF8!ykxhPAb-0 zIRgJ|FncuaSSwNZqHZX0K)0dra)Y}qt~slxkfbuUbjNEEsrORi7?1WiGX~{t;cbm2 z9dLO7JOqy*5XD~j&0atX{6lv7&k{m8)&t}ATz9Jr0(rcHPk}v&}fI*n%HfIqJQk$4WqOmAIH^xGPofQXrPuMTKs1F+L-Z| zn<{wwC0A8)?F+WiK$<8=|FP&ZPt=5kBo7~O&VAax=FdAk_L83WnEiyVQcHZox=(oS zHT7OHQ^JiGnDCNaZ?ohsx0O@tIVawr-Yq^C#QimT+~B(>478ta_msOwA@F~n6iKFHy>Sx}^mpJPhY|9bikj=IljJ2~_oC+4wS{HNQw z?k;_|bJ#t0*vk2G8w6(im0z}r6NL+M=_nwqjcogfMum)iN2@}9d#b91&tI`(6Gy#b zqs_edjQ8`n=QCgLq~mkWEM~h;Dob4bI|pa-_icu6WtS&R%4bIbEN@}TGeseO_LSYS z+4v=kauwh`HIG6;@0O!14AYZTthz}mjUVt!9GBmqZZ=<@VAo8ho~Bijs@;8xVcZe+ zPh-JJl}0ufVNI5b=EkpOzL*EIxZo^rWm0256XLjGFST>n;Rw$rvdsbBh~mG!v|Pm} zd-z}(pA~aO3^R8!X(0!1VQvINw{x;IUbnDH7z-q-G>Q+ zz1bAcN>??aU+c=}$(%BtuVQ$|n^ogDN(S$7EcfH#1h#YIp>&4Jb}X6S#&V5FfnAur zl4D2nS|W$Kvp9o`TsTPo{%BBJmh8ZJ}}sI=+);ZLVE%=Mt}3MNcsaV#H9VV#vcIDz9IF&V1*kUq|$I@~V*JUv|h@rVG7hYC6_xW%|4ohdLvUc`lmM1aE zM?H=)Gij4b%^)^QX0vImzn&vP_-O}I!+0=7V=jZJqze9C^HfAhO$CZ z$B{g>fg$0nmd^*XI3SBZ=g@Z>zlXEKdR|(_gx%a5!Jhft5yi9}{2IkpySX@m_cw6R zGB%L!3g;vWGcS&wOWP1t$Xz{-Cl)ei5#G)Ct}__0lAhk2 zyI679UPSQQbcRGyR|r%q*klg>Mbh4%SyDY-z#Y-_n8~s@wwb{PNz|Cl*O}}%j|10o zy&&LHXdcNQYk6OOU=H1vu{59c#KT^|rpuVIks9Ij$m63pI!l01diq<`!yTN@mk}&m z&ku`&nGdu>BlK%v{5a3=XIvQ{oZ#*=JW$G37dhrQZ=dDS!)$q)=KEB-rlUk$ z&a&+hc0R^Pfwx~^kYMD`&`Ju?7rAS{f`@j5$h@JLT~2e_5r&`QEV(5o_@RV#&#~+f_lT_I zG!4$P`w7;)!jHm!Kg=oz*-6wMmssmOQ?IkpX?DEH+2!hg*ZV2g-R5tR;5=mAPwF$G z%S&E-&&Hp4|Z{IOyA>Uwv3Mz)pQUXpXs!5z+=n^?=r@ z6a7-^x3bieYdq=v8Y4y*{X3yj6AMjH@Ru*Tz^pd9bj33r-0TGFdgx=OL>O`vI!zb% zx+t%oG_2d|s9JGx9d)e!S{H1r{x!5MUN%;Y@!`72F;O?Kvk6j~;$~-@lYi=n-KGfc ziW8QYVucS~aIgy;+F((4)DdpUKpgF_Xj;DZ*gqUz!;v=<4ec>wJU-atgFhg%VjsMb zsJSo3y24@#_WQwfJcf8Hj%(yNLjK%iBFn7h6emFcB@n?nWeHErbsWZKbm)k zy&eARqPpA9Ebzt-_F^3!h*VSL4o5q=EFXfIX6go;c2tvjIp4K)M$=#pr#$>3VvrOW(2}uwA#w`cR?Lbl#a!9 zsgAnC!5iD1kTnepCgS)E1@wLrg2_Rs<*AtAQR48OgndC+6pWu^;q8K6LMn4ayFjG+ z;IT7uCZLBm4tXL{mLsm%>VglB$o0S{4_tG>YeAm{s`Z?kAB= z^*Vvdt(a4S2Ak3102&pd+decafK~~-3-PTKnOT@|3})+LbppHB;rj{Lt;5$6Sggm^ z1GussIj8VqKXgje4_sRcw;c%Cp*ErQPvXi3gdRfId~`2G+pYM13NsGDYLD8%6&=8k z{lH-~Ie;<8@n;|Y9)ME`N{=G37#&OTVHdU>#)@M6+Ji;%8y!ZSgLt_aVTHI~f~;J8 z-GTa>vHS@1HX?94JW}9QjJa8`JA#!tSSdFn8@k2t%7^22^e#a3MqFA4^CDH&_E?X4 za@+E8D+%#gc)tN{Gw>n@A5x*c31`>iy8K3I$SFqhMhx1CHboeB1fvV!TZGtRbSZ?( zW;EY}Eh#vkqZY)WML4zr%QoOiA^K&(As+)Xk-7_a3b3d^(Vi=0<+>bk1&Xz`A_ohi zV3LWH*=mt3OW2ZRY?b}Ev~fe>xDIRPz$y_gfyhcyJF@P}@nsUWEyvX`jE}_U5Nuz7 zvLGa{z@5o>84gR?35KG03hbBT-)xi#QCYTN{&*IO{vjAN3r_+tZ>E|^{FsOTyzolC zz#rA;BH0u3XP{8H>x*&E2Mrga_6Yo(j;dbp3sNJ9H^K1r#Gz@}EHe{-_&6&nTBQK( zgOTKdpsBd$iwIu@;eYRg0x!jgyY7YhJ!*MdfT1PC-LI)DJ+#B-jXV*-Me7 zEqs+F{M=Zya>e=axGF^$NBnXJWR5xp!M0dF40i^@Wf)+MG;6Gu`h0&hvqp`PXx#x# z`>MAre_KR!gH9iHa84bl#9`ZIVA~1jZ85BynpX8T$9)?d=!lUr7_mgy0EI?eJxGlg zWGdy}3)`*W)Dhzc!$!at15m>TuLfbDY!U~kD)+VCs=h4?xZ`#h+#j8~Ds}9AbG$Xf z;m$bR8(D_%lv!>E3>M8qDq((TZ zi$^jN*G7Oo{OcmUDZXo)xbkN9Ik>CBh;;fTg_0RgTmHWQWsW@kyjm| zGK$f{Iuk6Zg=ePdQ(gJj&NjmG_AqLK6P>VJJWVZe!2ta`AWB3|hIpU@8QtG)hB~eA zq$P%RfN@i38^gr}w_72y4LWu~8$+}<#Ny^^pIF%p_Zy*75BfT|tcQ$7@X|x~Itu%| zswOViLu3t<)PP1+^!cYaDx0gIp(bQKG~^9?eq*nfT>6GBzR~al*FNR9Cw%i-5n5Wl z~K$J}$7Qy$Xs7E4|z1kIc`41LV4UpV9mO~3Q&WA6PyugC0E1xKGL=9SMY zuKCNZAJj_D{3*S((CQhJwXyxPT1jYpQnV=BPqf!UlV`m5i-*4u6>2vpfq6OFKi0&j za?bzC3)h+ZmECTz;vqH9(CINlZgT8rg=`w~A7_dk<{tgaSbmLX&#}f`nwHY4jDrrU z;e*jh&N|DuJ$!YX!%wiZoPk2bDrLo1rGmYBn%>gaE@9Q9+%G7kQeG*hWij_0ruBMW zImWY_X|aokrP!OJ6f>ba*+crC`Ap1WWftEQvgLOA<#T8buWe)hBARDVD~r?Db4n`X z3b|d5QQ{;@+jDc_fo#^B7UcWjpvNkFSrg zN)~NI_mj`{yP3XDQJ9K1GF^nHc^q(@CvsW1ojo=&tVn^!yYFCLA|GsH$U54~tRtV( z3Td~F=6U>(&IMcO7sqD>id6P3i|3bddNQ{zrFA?#7f~~rE96AHlx>&MY$3hosWV;c z#eBYmgJ#os67L7oZ!VMP(NGnxt0+H zEZWSt6n0%sn=A$-(kn|1cHXREV?n`Zv-&EIN?>3jgEHtHqd4%T(VU&iX{)(2j#pzi zFoU(0QZtjk;%J!4@MYsK^9YTk-voivV5Ur)IL*3YI4;F1JY%-$t-XEbC5WR2t7tVp$?P`>|jN zHC@&4A#^N{F6GN1tg)O2+~^}zx^WDXp^z7~7V+m;K3l-6PF%8x^(WJK1{(&l=3Ev` zpe(|DD6gviS@^Th?ao-X~PUOdMCi-#4EJl0tLOA1n*>V<3Cn*&FBdI^k z=QdAvo6qmwJR7M-D|^DZ$d9+9)J@fmRFf8~C|;hz;uy9J1HkzSfWtT;?+BOO?ji($>RxZv4wV-Dt}%irOW-iCKIjwtlY=cL#$U!J5dSmXt2IA)`qyG;+7f-HK$j|fr8&15!74P}} zGS~g!oBw$DC%;@|y9$=y=Bau7l#GO)eL>RnRXTNp)!V#%*mZ8;rD?I46tLhWOGI{(4y61G9uAW`UYUIMog9 z^>M5v)>Kgj+i$w4(jL8Qpqik=L@O@^w;F0iyRe$tXU(Y&`!+Zr(oahatE9gv=Ktl$ zws8MW!QH&C3pW#J{pRlusuumA4f3jBj0Hrl5o8LHnR*$+UIZLgsM!EbP0_v@_IAdo zx`;DFRs;O&haw}z{<Ohk$qJjUQ`6Lb&66GKG0psyje*`Z}URGk2GNo(7~L>CbbXsQpx zp?Fmvqr|q^41#aXu8HT?_)`;G2I8VAE)T{76Ic#Kv4;9ifS(7kuX;{3_+wn8hb%&DjcU^vM6{aqC^Z?AutHUKX2GB!7gDA zFT+TG>3Y4OQYudW$;-;$aJD zOI)D=vW7yhDUyfbWmEMlNO&M?BvyAos52t^DB8J*N3;Fm-VfX4tmlaHp@%S^n9M0PBE=EF7v^Wu@5 zgr=+TG#`uO;IkGNmcu1a3Cm99s}}IPY$QkEc?z`VqFl&V3lX^ix59BqYRHT6a~;y= z2+hP*59lVs(+%TO)NwT_4&BGXD*@U*IJ6wU+|(m-!&?!{C4~}@i=ES8 zor;!Im3r)H5E9bSD-=)C&@&wSk`;A)t(^Dg<4-mWS0E=BljdW02C7HmU?J=y(0)C3 zEWoi`Tw4hg;@ARw&rueko8tV6!0aqohT%sMB4V&%1Fp};G#Ot^#+U?TEynarjF^em zY52DgHW-BwQNY$T7EURItJ;rOn-3DK) zsH{S66|@#)!FSsA$LF7{7y$DhyfhFm#aKNI|9zvxX)ONms^IkhF|mijS%2@2UBB3Q zAnyO;n1KkYi~Ukb)1|HafyrHVr#jzVu7U0M*qXGs$-_0E`;-@};b%ELt3m3( zU8_U(+RuQ~4=ISY0nhkP1kl$wtO{H%F-rpvZZoGkdS6msv+oIIV1D@uBYv{!DYp8@ z>5!h>LIW#6I@E$2NPo<^$W8@ZST@I?QP=xn@5dp78T=#y{roQl{MIg=75jh#zFP za+jA*@XP~-?qJ9>R^Lne7wnS7=a1Q-h(V9|Wh;9>=d1$NiI(269L%M2^z1$dZDxb3 zoR`c)x7ag}iJ~Qqr_oUcujW;udB<|=InGK`jH6hQh8$(+YU-Te$XLc6;rwWRKTgYV zE-dBX)vR`q@8)v8pl-!hbDU>abJkH-uH>GB^jks4QkurHYcahNcyTA&&f)Z(9KVY1 z_Ni<2k-PY51zXDbcQOAv$ni_KuY?ztQhO5{F5}JhjFg4)4z;%utk9L^?7x$HS21ZH zk1SP(!MUsHy^hw4csrjC3yICV7S033ER0r-wiZ#GR>a6CHrT@R^SFEuM@A~#Zk>f3 zy^m`b(D5KgEoMfEI=;=47IU~tJE+~|QT~ad*KuCWr1yE|CUDRxX39BtFCT2=W(n?Y z+?vh<*Eqg_C0Dp1i~6!HTF3oI7%a!MQ|c&Pdp|>B*<32y zS*&xK?NWL12)o8}*(LPQn;_hwC+{DKR)ecUpl(lv! zzi`hztbUQnyLsj^Hy&Zrll)V{^_RHm1dVShd{ec2IyM4u|P=h%1GPT*NnL z>3x{3&hm;NsxHvwIK8eh^&sDtaoBG4NG0y%j4O;ip}x^@2Ok_#3GhjWxo($gvu1DS z-kn^uo*N7KMV|IWe3e0;0{+S3whUTsrb)JX^gqcFdp$K%IXaWaR)8yR<2jjjHkXGH(IJhw>sc?3^-|RNy>vVC)~NH>kOW3=rE?U&7jR}0XKd#AaO&=1 z_;PAXUows7j;fu0>^8Ps%`A~jaMcBFO5yfW-WKE1UJCPn`3_!8rR8?cS-}bGnGvO) z)n<#>ejT+}@}G#4R`bY4B8JIZc|C<$C5(?`njm05YZ_vhddt3Etroo$Hs#oW~hlHh97 z1hQv;*a)~q{U)e?iG58`^9-lxW7cJc8DQ>3Zf}V?7r4v}i!XDe8Dylq(-IReb8lDN zyvdM$FnZ1}R(N=k>Am24S0sA4@qm;2KnAnd24nAC>W)I>Gd3QGb>;LPfP1f$V?r(% z-1;H#K3DX^xF-VGN23P}7>Ey#+201WUoprIvtKhp{2*`XITWEU`N$Sht~e?ePOm7D z?495F#SR&7ID8}wWvc9s!Cz@G1l=BT_z0YN&Q}gF7tp%sm0wXubjk0SX%7(%SPsUb zXLR*|&1>3^#q9h1B;L$7O!LO|HxwpqkGK3h2_A2$?TeNl*wG8J#NX$E$O=yIL+?-2 z9gpn4+~|+uKN6b4m+xFT2`)dRcZ}~++6_YMKg2DO1^7TsAnh5QGTsu$MSZdBj z^iPhSt~@3KS3p+_pB7c?HzG8?yMObSLb6MV*U_p@zz1Ppj%1+SChK?bw2$5y;$RGFbU{!u z>bAw71T<)m70DQ9j^Z^q-WKhXF;{vMYt&9(H&r!xw~5rr5MD{JF+|4&_|y?s<1otz zGoxW(rgpWiCU8%}zSdZ`S^;2x=U`_`EJ{!)@{}a>Z;QuSaA}FtYgI4FAp?_J;Bp2A zH${jTilrEmgV}BHC>i4o(JT)drs{hawZZEogczvZXjmJ(%7Tp?7`MRA1T!-b-Ugcz zP~HiB)3I9m8mV~I6$ZID))OH)$nJ_}35wz7vK(J~qjo;ZdcZdYod&`_66XZ%m5!C& zkP(H#?y!l$mtIIrK%L$=ACG(Ty=$?y19B7b%>;|%(Zd+FvFbX!C?0H!1u6L47+JBH zY>ExB=-L>Wu{fm%!&O)%RQU`PnxI1>R_UT55zY;;Iu!?6Vrn|dWcL(}PYv*Wg(~vY z2*+eS7|3>27u)6_uOX%_!ki|!y8t28aWD*@wO}kRDsA|S@K+NqepsaqO+RGl;CBFK z)`YlFt!rY{IP}-SG*6i6z}X**YM{acSDN7TIJJaY>x3(sI3VRjnFx(WU`;G@QkC%B zVYvT?$2@RX16J+`CPzCU>I)Y-!--t$j8>nR;DniiI z#>qzS2{#GK?+H)!gN)}1&KB+3B~EAu*;2W6#iOf2e+91aL}x@@=es7DQ%>K8 z_;HqY4RHG$1B{Sxn}XPyev4z9;@B0oY>K=))M^L;;brO|?LH--qIZt*EwK6muju09 zWo9)(>$^Ov4UHT8Sp!S1vTl7WxUP;f375D52)o6(^-%2w%{4LbG*8xrov2*txgPLR26^6Dz>;L$-0fK~XYJh)bJYfL0Gn^)nt2;c@4Az(UTNiEa zv6D9DU10QY^|Agy1D2N<`kgwL+4vVdPgCO=yI$d9|o3k|8@kTcY&;HR@(r-4po4Ae%&F?H|ly~qZ2G5Qh*iJ$Hg@5y~~ zn>!6LL+(9e2*D}O2p7Kby9tiJq@`3HrEO=TTuW~9xPMajh8&HXwFQ1~LmQ0y$dcBu z`OI%^k^6~a$9wmV677EWg-si)cUsd%nEjEr4DhoW9?A)~Dl%IDzj;gt&ud_TKE6UN zaN7u)yB^%N@VXg3RKpp875t)oLpT5r$u&TcJS+ZjWp%}=E2)R%3d-(v$1iTzK#-^? zs=@gk+gF9fH~y!A0c4e05K`-ndf4-f6}2IA;2!dlk+5_Vh})vC^jSVLvM#QErAZUK z`$3u4wf@NxW1I#`+Mu?SG`rwyeFZcqsEu!3;8qXWLr}FgCW-+{a_o*cW}qraGNN>F zK)MX^q}*YIlQwwR9MTPGqK^|c&})R@1MsprhFB?1SEC;IVSxH=Alyf?%pL)HG1?3q_>=xX4Rtg!Xa<{xdU<8*cC*TQfuoUela z0IixhQU%|u$xe^nmHhgNmjI6n))UIvFOI7Q<4Ot;%u*9os-kNR46BAJHSzfuWs&^` zm{}dY{*p$psEaeLFsKS!D*s=aM!_^W^kwliSQX}tEO#bRdf;znkJ6cL9`%Y|ET+Cd<{H;de9?(Fa)^w zlXTJH_i1A4H}$gW_nYs@?C<?xRKe5d%+!S8|2R6&KrH(>Rq)aBeCGR?_DK#fKmo$~@`Wi>I;lHzsg~8uH$;P!%VV`B)X^AGlBr z1qm#uX3Q7b3asioJFBAEC)Ss%GFgFPZT-yQDoD#SCrjdYR&%HEJ4QuMs@uDbNfT^>E$> zMaFP$iU@54+n}8qhBtwiq(tozs|7n-_|(NFOYB#LZ4=m#ZOl=xhGR@&QAjg$9I0VP zU6e{Qo)O||*v}l{Rn(AP$5N)&N7pirYM>zAB6JY@mvywEnal3lQ2oIN8gTka9XZnH zQCbt-vpA4Eo5+84QSUovYC`)PpKD;P@UUvQTMCM`k@cRP%GfZH^HuO)q>^-&4ZxUM zZjNPHi9)}cQ%zk_l=AsIjuujt{GLOzI4P2if&0;%Q^_5#xjCP;GCvm4?jz5Y(^Y&F ze;5(PgdE;VQeqTE3A|Lo{qahy!}T-6{xaYb%L*xj!14@fY~K7p9~$H;$QqxHy^rWiV7UvSMycV%uE0exg+& zuZgdNO#aH>S?un+k8IepBu)!+^m-0l45}z3n&J8(Ck0)eC zc)_e(>b#`EFX}&KZaTXN%qWM)p40O^TZb|^jklgK?ISbpD!qR)LBCE=im$t;v+^17 zNl9U}NaLjUe3nGKrqw%EJ>>9@bbCgh_q2M!Z;3qce*lyJYdT6_?kftVs6!mXe$hLY z*&^XZal{Wc|H^@R{G7^ph4f5itKXbgK+i0G%;d4(O6TFdWQP3a@-p6$6=el8e{+2q z2mR)@LaxYTl30Sv6jgDrd>DW~zv*7hOMkf)I49^pVG9;hPX#Z2a}jw>uIM@#n!)cH zsFP3Y1~{0`Srx38%@g%;KE#_jmN&e+TV|0*1V?zW9 z6G{_9>!7EE!OJMAvu0Xi_zLW}`+ z*T*^&#hmPF1v7aLHpHPua4{ZnrjKwFG;4^d4Kdybdv)=q32vAx$fOAdFfoRa zxl%P?qmNFFa9AIi+RCJ}MGs**C~N|YCh!(%QeM0PS~kWeEi^L21Qpzrmy&z3vr@R) z(FP9<5M~AW2O70TqAs>HhLr)%NES>Fjjge;5pFg|sW$Xl!AuvX)_5U}+zwcvjn{U_ zQiVe+1lGkWD>PDtpFO&fQPKokAFQ9))KuND8CcmTHa`Z^HsDq zM7S!1!mv+Q=}Bm+i=n1iUJu*NpskKO1}N9TETLN(D*&kmdZ-o|w64-g+p8f48Df$J z3Qd*zh0;bCYm6{k?6gx<+9WePlS$1C?oN<8g%p`wtWajFq^$?EhO>-^ZJ}?2GB<42 zM{0ZAHpUAp)Yn3pD7KApy9JCJBFX_ZqV!4quL*9-ET#@sA%|)puqzzpa%*_X9;3zaC3ZV;u(wp;o?XQ0t*aQ@~=;CRij>Ok+g1LoY)#Xop{Nt(0fOAHwIQn9 zVQ&JTt_lY#x;uI_g^CmU%A3^4^v-!mx0cAYof&(=)7x7m_itcDsM?p2M*Tp31Ef=nt2QG+t z*+cn+>>r2?2Jjk!r`l*g9q)x;H4wQ*@biL%_d89)7aKeohE;mFHUaCTB48Y(UL$@4 zlJ)UuDnfN}Z#X(O#3C;|HpH=!P;Y>?0vMN6?_Dsm ziuUaho<|FNy!*=vM|>0GK^ufs(O3-X#XR30E`MktGkytsnB!^@XFI^5n6q0c;m6q$ zQvM;8gLqz`R8PB}bQ7BSTYJ8?^pwEBs2O3EGRz0OVLcZ#I!CeJWNAX)QrI8D$0BJ4Cv5LaW#DCul$X>2jfdICw0fud>-tH!P)%R4L36=4rJ$_9Nr(H zpLtQz_ky|@fCu8@kWcRy1@?OIJu|x@^cC3|`LSHq9#LX_?24_4-0uca&9d6#LKG#$ zx+RwN`$B*PrS0(SGw-#*rMmby12HvBn};W|Fqw-ws<=EC^9xzC z8XgtAG!sGP44$J@rY~HAR(aI;4{LIHa55~?d3-M93?Dxgx>?*Z6&EByJQ5?NW`82O zrqWZeW$}FJh1*}au{XSvIC&I4$ysY4f{RR9da0MFs=carqYxTFcqr_+SmY7qHbj z*8N3`^&Fkg-MbZ2S=1`-NmX8_B#Ry!c|DJ}eR(UJ*}Ex+1eM(!T*TnRJW;}PyIB7( z`)r}3bYgE~-BMoO&aVahbAUd76g%tbGNvD8%Q7}N$4hcbKgF4~e07PkTey9JFaL7< z2_F5+`)8;sQR|abucX0wHvL6M@pfj@|2W5H@cALeec{c+bSU7g)3i^emOnqFu{MBm znXKE-cwspOu-R8O+s3wU_}rIoKJe^u+JrHB6NkK}>khVf&K>ewx~WK7O~d$OKMNky zcPIBhpv`{vddL&UIQ%|W`t#a-b~?y~516`(vx7NeH!bdSq~M!xP-`dsp3=gPfl)N@ z<>v@a^Ccp9Mikz+^zo%i3|s8vtuOTPW|uE)wwoy*7`TD^5}CV^kT20$K9I%|%uCrzZmpoyd zyk9{ySjF?ArmbMBtE^hZg~3Ydw)!HsPv@!2Y_pC$L*04odyekQc=93#dDG<#PcBq? zSx>HG;XT?eX8lXtvyc<6Fl7^s&T{e^4!pu?n;7?yshe1Ik#BvuB}l<2cfFh1eQXoL<_CHA9B*&uh6g-wlrEwC8K7u?^Y?MkZF(Hw$q-iU zqs3F6Kg@=qymOqLpYh%~8og#C$;Qgw?;Ib-(I`k!IlCWIh)B1B6&w6T;q$(xLl9So zv*mfd6T`+c4vyfqi~JD7cb9nZ5iJ6#9meeQio3v5q_ijWzsJ{C6-oE!BX&B;k`RW7 zK!26fPLo&Yewq5W*ykc2+~*+?97P1Y&U24hcvA6djuxp-B=`&bc9)*lI9D{y8!V8P z;0G)YXX1T6c*OoMc`k$ppYcElZ$G4gWbL2PQ^;KLoEX9>?>H-lJ4Nh%%*9VQ@fjK$rKrGji@D|v zldE|wfq$x5oXSi!OiH8pZFY$!F6);p#_D3@Val9r)!lNn7dj z|6u~*LxpN!P%-^v_xqQ=s<=|dYa;X%GVdQ-=2Dj7|9&$_14-X0-CSpd%w9(4Vt%M( zbP|^qaCthXRB_@rdX#hY2c_S2OB8QQ%WDMl1&RBDPsyF(ykE-a513KL)KLB?=lW2N zt!7{dElL#w$vYLCzr|hxaeK*8b+PUq11ot;@~~C3h~ix>{0isO23Q);t6DJp&fSLC z_)#fRa~1lP8JeYVo(WQux!MBtGMLr`b+S3EF{D>^q!sR`a;rUzlDSFv0za7QfQxDT zEf3;ChIYi3O!jp^iljN3!y}L7Qdc4&5jW_{_O%syeP^v5K4o&2EjnZ=?2^r?d?rIp zGWCRzn@ric87I=g1cD^qXb1lPS%QBgpHF0d9WZzsg%)8AF;(Y0!iJ-L+jlH?q&6_Bg2b=+~ZhzDHI zTAmIa;P{vO+TvF}MG^{-$8l%O$>dHslKp00cNpaGTnA`Ly_*~Q|7LJEglF)vE1roO z=!%M5?&|`(T%M7-+BA-F!H!Zc?}4{}xUPe87{2We|6)ptv!1w;{(~NHeGF>;apVNp z08Y{~Sxa>Zb?T#ZE<&o9GXX);STY~^K-v^6lQOsQ*ez{x)3K|HsdLa*9apBJrj#}l zF{qG(M?;=^9s_VZliT}ZU>1*d#f)DRhue+}<~u;jE9AWsG5v=nR?7Cn0&-72X@>n# z^p~%p9MlBjvdA?MoG(yc&UNc6Er>wF- zQkbGCUy4?0(0<19uNg#T_-u=o(Ol37eO^)0Sb{;62`k|%MXK8y&F}U&{E?E4Z5Ypn z7E;8@?-mgIv`lULU-C#3I6miALj;G?tRXBT_}CZ|UNNYV1UzXVoAyw;8)5A|-jeMM-+pqE8%lrhW^2q73tS6DXK&mJkCT|$3T|Jh(E`UlGocw4 zy`iUU@1wZf2Bxu`(GFVS{A7if5max1Ij`x|24+z_-2r89*`y;LM>Dn~LO#$+6!wqo z?u09EC^_Z8x3qM}m=6MWM~^ht?~lw+Y&i&<5*a2VNgAJdLMMr4(!!L(!jXv20 zcP&TXT3Ro`ty*R*MXhWdm!Z2Xw0*Ismhb1|jwZ~PiO9nzOQ2dG;}_$sCdMqs12v@0 zhfg_!CZjQVU=B=5Suq}M%lT<8S`>4K40NT8odCN(%%6yE1$3H*tH0?y39Emx(-iOr z)x@=%K}mMI7SM7c=B0C<7sh3%M?nY(?sePC2N_^z5*9T#e+~2Ka_B-su4J(Y=h{Y|?dLRBYL$)stTEfj2ldSM* z7hap;)pqojO`5+#Z0RNFXEVecQo2S1c43_?+z!IY7)_31vzSP?D9e`42VifBqXC%J z5ElM0F-Oq>bZQQ@qfoJi=`MtcU3@!^G(yNurSwm2H)Pg}^Tu6EJl%<=vfuN@I9W#d zqoy&E)*;&*37hcS23K~XjRkJ)z&$&B-ii@Tl#1yXYjiq@Kr5Wuh9|ZtJFLKbbjF{O4(d0c*9@})m9O^$ zAzoJ3bFgiR;YZNb7;X09k{xRNak3eD?Sx3it9B_elmAX!7FWXo+%$%{H@cW3coP!k zR&xO3#2hXhJ*gnrg!K)va1W+6M(!4LF+#JgDAY&RR!nIElOsxRYGwcotReeZdDP~e zfNE<@Jq^QV@Hm0C7U&p&(S~?<3ghh%e-;6<_&NpqrWk%2qwI0!G_$=}j5`DoMo0RigAMGqBfKdtp2Tu9^bLTo9W+m)g(ad+z@r)FNWR_?&m}=G5TfJw z-WnR`amf*117YcejX_xFf@Rlmy)9l{L7z7Gc^Y{R7BTcRwAV#p3jC>Qykxn zTZX8!0>8|0XAZ9DV4ycV^pU<2t)wk>KE`V!Vkx$2qre-#HF05$vX*SS0s|YMhYw;5 zF<=oK#mOw!uQ77Hp`xlp65ch2wK(}3p=2%W%&>12W;Vvq)e5G0)CPE(VE9UOu)^tm z_}&E9*5IWT3Z+_H9~~rt-Uw>Tu*C%5=A+gG{pRAYDJmBz%O(9GXxR{LhC#g{;>JO( zhQ>qjsva73$Dc}$?*lDaUI|E%d@va4#eCQektIqEX`eC<>4s(5Tp{U_Jl1r?kH0)6 z5t3p`TZL+&kYTY?mS%%tEsVeZ=vu`FgK(^ZZ^z(66>p5j?MhaT!K*q72JvB);AUX0 z1CCXC&uS(iMjwkt;gP6yqY7LrYaOe8V-h>@2k{I#>|N=YQErEaJsH^p+ZB zEO^c8TK;&+6@Uy5_JN(W&?kYunwXnFRgp)(QC&x=RNbnEtFa8PgB2g? zuL-Mf>{B0Kzw@3J#49`52r@4$t5LX1B38yq3k{XY!bug!Z*z4TJBKl&n15c;F^7Hb zaY8!FLzyNWVlSxulOtl7{DWa)Qk8nQF!sox?qfQB;dpUkr*ZNN_LQVp7@LU=^`!!J zJsL*YZe0lHjT=I~cqgfuz`yt$a zQz59HyUDOf&biOhk92v$Ug0dc!|#bqy3gSs6sz;Cbbbuu(M;xtaYGuTLKv3A4zDTu zvD=S0GntOBx$+ld1v#Cdd`*4J4{!N2P03bkd}90?8hzu)2-+oZU=(-1VWZbdqV4{B z)_X^7M@|jt{f-DC9=Fk!ztzw0EVw1_{#P_OLn@366 zzxcz0(s8W&0|V@ojxl+(H)#+I;|4k~|87<62xytu!FJ!U?Mieq! zAN2*;YJgE`oL3hI)99>ss z*8&=vVPzieEs*$&f6UNS^ix;-{>R}h;8;noCMf*F$!>`MLn{Yd{>y9!XczIm3;cfb zf)m_i{nZt#qz}*rktv)l`M!M4ZwK9M8nniN6h3T$+@BoKR5>CJcf%psj@sbd*Z+@i zALu2V#6)UZW77w2HpYn8%6KSp>a6DY@|t}tAcCp5+T^n>cR!2IT-pShaeUnfci*t2 z36^|fZ(}_8%DYl}@QxR(u``Lz7U=hu9U7yXjDfcB|IR;+VfvZPEm8fQqRlNxiYmDo{Vc#&xmJpCNV8Za1ITFm^v1R&w(uu2;iXU;fs` zz&*-$p4&`!QtJTM*T`=|>b$n8yFnWHMvh_y3uH*%8-mBos^&FN@<7Lz>;{KIX z&1avr?3=}?g*4Bmr|hP3Xt9*d(|AKDMMB4$qL_rG(rxE2dd}izxd3NU?v~dV(>jC4 zX7N`77cb+0?=)G&`0wn$l zz+xWu=J9NHT}W>M_O0QY3Wl!Y^h%!d=Bs?}T*JBlm^_ygYn8uowOmL4akmcUuj9*d zo>{=l|EN8i1L~l)@ZB_EwSX6^m_LONsu(e!&iRa<$y;RjI*!d%>iD9osJfg{S!_Rt zj(>Q04*%uw@GQoZapxjl61?(iIu&yFY-LH}yqJ0UY_^E8xqP#XB_$jzzs~|T6ChL; zTP>qV*sYfERSs)s(7cGRmMWO$9}C#CoHJ(7xR_%XP=cJFm+)By=PqSrDHly;b}6UK z=ZAb&&18NV`%a|@xFwURC&}Mwyk0^5SzJ)We^WWOjHmyji;!_W1<7rpP-bS-wR+wQ$!!<6cc#v zp;cpi4CHJPSWmFNiFjzKErnoLI7t`(ZgY`7r1fHi7S7+NMU~b`hV)xp?~Xh7`Kbqf zKjcv1Ur0Tv2Lw&nr5EDksO}-fN6Z<3p)nlWA11JGr0Xcl)yQUrq}DjUtt zZb%E`=`JXXq7)`Oi$3LoQ4bl@9tR&Xuq_rpV5?S$z0Xr^Fd&qD+M?hthxdegIQ82@ za7)ixpkXktNFXmhkOAhjYJowtR#q@XF_yJrEJp$kINX-OTl+OamP@JlJ!R8e17VQf7z6_ z`DLk!(fx9&vhYb1SB&U`(ly!W66w z3?2yg&wS7Wt0i6D8@=Asun&g6qtQ?_e$U_Cur!u&{c-FarK(qcZ*!zP=Ph@4Lqa4E zb;6KW?9m3#LiolF^1L>;Mr|19S)%VNt`OV*Q+k*{>pm-Wp>c=no4`MUk!rBL!5l3N zy2*>RbiKo6s(2jCBbxaAfb+=Oi`-KOv3Gb%9U&KZwH~T(@?b6P&hWDul5VnX4X<9N zY>N$Vb6^E$-Qlo0=zURHJWjc#wAMEaQSLljZZK3Ax6aeGE_R(EHSqTWn+rDL0+-Z9 z$ph-jed#Tx(Vstgv9_Ozr>IAT11LPmz zNZCScXI2@5eQ8z)6Zi00DXVu-P1x~1G%DcJ?OY}mI(zvvgW4O}PtGJ;*jws!4sh%z zUfaRYRAL*0vKe-eABz-9=8#0D`fzcE(wdT&#woj$|C)M~Q{>?&=)Gj7`Y|?{6ZbMI zMJZjJl0mGNu1)3F<8(}6)6+Ce;d$ve{l)JWxmnCSr;y z;wO9DV(L$-o@JkG4!qBSzv=Ljn$>*pkak(rd(LjKIhbO zet*V~Qhpnwn0w2f^5$QTisq&=t`=MGUv`P6a~XfXQZkIUW9auoIh~IB%~f%X%%tgS z?#iI0)GB6k;%Dyp%jd5-q=K8}(3rzcAL(4hvB}(B!6{js{+EO0SXjwxKY5~x{c?D+ zR=e=&Z+gGE)QIF{LY|N4ejKsHdR0YiXC)y78_~6tB~Tz9r=THYOpWl$$IEr#KQ)VQ0jV3+!eK= zKJqFRE4ynsrTXA}1)uA}BbT%5<7owlnB#;zs_J2U6~zISCD36VgveW_rFaxSYU95u zCW`S%Q17bfT}|;h-z($NIw+DyUMz~{4p344uiJv0E2m~H zGs`)>g4_No-}ypv{Du5is{Dy}4g1O|x{7tl#d7)oV-7i;++WJmVj}v>o3$KP&R?pC zQcb5+1DN z?;mVb#wNe{8F0u{Jg7lw9G}fW>AY0L+i5(U&Jo{uND8TP*d>emavAqiDd0LInr|l4 zf6zOJ-SVlL!Ki$uNsm?zYciPimo0Mn^AByasZ*-R#IBN($Wf4gO)?pl#l$@NR&v)L z+Sh|mKE*t6Mog6@yzq-l>cII2dx zfQKqrBZ9j+=1c#o3O?7efePeEykC5kTPQab4%tdwK*A?m+x1GLHKB{ghF=MGWmWKs~XoLu}ARr~x)uqev5n#GhG1QzON+EFG;ig%k}mrh>-R zd{|3cHM|jyWHHP0Df9BqVqPp`nmm7haa0cL%40tnB$Rep!q@OZ79;Ywtc(X_ zikG3FhFO2OsEp#HyIREotESP z%-CPqvxX;rP&1#A8BDBHd?^bBUjLH|YnYeEnequNV2L{F{^V|8mE5s)kXFFxN*?)3 z2P1s^#|GLMS;;T@$_?MwK%sNql1z=@jqG49zir7zso=CDo~YxjEk-oNGiQ7<#MKsv zl|sdCkZIl95q2hsYz1Reyz{_(D{SeCo3i2Th79q_c30p&Vwjw22VG}uZiS!S5pM>` zV|rUbvm3Onv9$*dJ3^>4KJ=ZxzUu%b0= zy^zob1yV%Z1`nsAswK=vqp}5#kHDmMXgdz6EnqPo!7WfGw2tPm^F*0FHi|LK3EM{E zo}g_;p?O7gUf=yF-eq%~Atmq2srU>f`h)&^#L5&d81-at&?V+S6W_Lo4Ib=jS zXNntLFy9D+h2LR_BOX}S5No=^MOUeWx-Qv}&giIx&`!7|iKO0muYqe_@X-Wz9vG>E zZITFD1cUN}xqOE_^P#`Hn-&o~>#s=uu8jp2wUrs0b@NvOm zE%@8RzyRkR5MYF4I~3^SfIYfM+)40}I!fQNwH}6A!AB3<9T201i`HnQkL@jBBc~=8 zsA*zYGxU-9*AX`~aM=!D>f&^BT+%|UU`OODdug#*UDelP1<22%=>)4%uLLCuBO|tk{y9LT5M}+rV2;Zf!AsJd6a$HBeFIzDSF8bENe{ zfCI#iIHf6Od7#Kjp~bm2g(%ejj4`pJlH}d%gzpV;%L)4C7~qU@V+@ze#0thOa8=mB z?igZ?_aa(JIZp?Sv_xWeh?h0Q19w^@s+&T|iRy!uPPjf4vBGl{tYm*Qm7k{d=K*oO&XrKFh3&C=5bCrq|8}7DLUSy{YG+h+{+2Ag)k^GwQgB(%d1{)hBbV8vy#z_m7IWoIpmkH|j!WvUd z>j9Y;h73lgc($dd*H}?uf=v|AC(PhA95T_glm&|&JO)E{w%YQJx5UM3+y;B< z;;|D>7qOEisAyqVT~McnT5S}!jE%E0IwiYekrrf0 zVy&&*qgvK5tOGLYLRRAa>S0PpG}c0WK?DLiJ<#_b1*Igf_Iwz+XhCm)5|C^q*M-n3 z1%0TAYr`=~e4afKriP(Iu(6gteGqSqKb|H$7Y^b2+5HSTY=Fg|`!N*BT?HD)6s+6Chii?D5EU!K8^w%A;}+jGWMD zHpF?`c^1;zA!P>gIw(cf;+t)`0M6a;U=C)t#q2pqbAENO;`-B8pFZ9LGy78Gl7bA)$8Gh4)W#zHGh zcZY{HyxK$5jYEBL#uS^~;cbIkUGdfsUcFG&7y<$olUvum=&6fy;)>D3-R|&egfks6 zM+@kVU)svGIbIKXeX&OcH zxT|7Ee??|G+6$4j>@Kzc)m-I)Od#I_lA;yUxV)NEe|XhFi7Ub@=+^}&H4)wqc7kV> zHJ}#E+oQc2=mg^`%Jq_?ik~fzRz?*YSPD?m7RUZ^v^~rU`Kt+v3Mf{M3qQEj6!}@q z)I)-}>>A^AIt>ibRwT9t82yz^8bkXthic<^91Uc;dB?N{@Qvf+8ifp%tP9Ur-m7A? z1ijU;IErN|NR*>&9Ymxn!*9(y-j*DtU?{6OCZ30D8T*c_)gh%TXKMc6L8L0kY&z8N z(Ff)GhrMB#NbPSKTSM=UJXTHr=j>m>@rjB+@ZhcT`f9H^u9#JCSy9S)F^Y<+8$m;{ zJ%@8`0b7RC_y>)`6eLzfs1l}I9n9q)`1S?ceq@jo%fwLoHs`+Ni97rpOZ!{@uYkTu zi`VqOK;Ku)InVmx%)7(iA89T&=?~m_Mgde!4`ln#+~Lolm-Ii$edHoS>Zm~ej)#5{r;G)aC^Fnb8KZs_+ZH{Y?l9>x>poGMnP)#@oj~?`%A^xY zYt8XP3h3&}q|+)o&0&|N3hbuOOomM2nzfw2lvPW3 zU=trLpw%p%69msv8(yU zo153N)Rza>vDa4a+Dv~xZr)6j?VP!ZTt|B!_T9=$8+mC5H*RItMjqbCBYsM&u-8^L z-9~KS$bIxVpirnvwlP#b30swZq`o`&)t@)~IA=Q}eYo-@b^Yjdmx$F#a$*FX4c#JidVAcXHqqrAlkiJTCBNuZb*LOZ7<%7BbWn zK3~g6lj*pQP3ADlhj~+&Fdp+rU zmLt5Va*jU-v*8u~=}WU?ydZ$5bKLC7Z)X`cfwsXsFo^B0({QBXvM!lPw;+C>#%5=D zXO2?X{$vq{N^##Zp1nc!_55;`yCntioUIQiO>se+dHyj|b}OFz+5S8qqqI!#ea`43 z^ay9dL0*5%tq0iR0sY12AH_XKdFd7J?&X(fys?eFp788$YQNyW0R9r!w>S5`V%=3N zx=yPlJRV7xHN5naVRQH=mi{YwAdGdTnK_bA7V^qV{#(MqZ<)84m*bhUkghSTFKT8i zz2|V8I7#L+{51`hP=xQX>sS!SZu2-ikxkb#`zM$9ajJAN`LRt3FKnm&N51vrp$w)T z<6epUAL8j$ez?TA@7#V(S?n~trs%Lz{U;mU9XEJFDg{C~;xB7L*i;3*9y10Q_l#Sr z82?<^^p1?=eKm;11=@<5U#$oCZ(O8_zOR+^@y>YqXkvR3+lf0%S{!w7I*u?$ix?J5 zS3?5N>7rjWhc&?|u>qT5rzloN$c?9o9-hQ7)fhu%jbnvr5gcz0l{mgKhLj>sF~#I? zNnaCS7qp115}g^q6-F7)R(j<&(OFKj0#r4$Ypqj(CNw}gE< zqwP`ji2-e~SM0$Z(La;kJ#bm}#`gFxoif6V%VB59l!?p56*c)>10TAPVX5Ia^=|n;HihM3sGZ?s|(TH09JEh zB%G#sN(IpJ`7k!Xf>p@V#f2pp&;+}dDT|$Hi!t9ETH9eMRZ;7(P^y`>L8mQrw%}Ap zbl-x2?(o}$;nL-G0Jn$1Yd78x#o1lhKLMuxC>)PBhtO^u%FbfdER>x@lkxa=6c5Is zVUW@cJoPNr%tq-oOrL{Y_n|few=cnb26|jWiC|5xV)X=UxR1CQA|2wx7)-y9>oXC2 z8dHa3#ThJ^fV>M>G!}-(Q7(Lw8#p*v0oGU#LHlDkKNzP@RWR1W&Y?y^xJML>^^2ppJ{&twKyN4xpTr0++}MLfgHR<6w1eT!TmbxN+75rKub0y@1 z+Ic=Ywm|VhtZs=l3(&hMCe1@rJ6v6a#!Z#6VumFOWIm zXCv1XzOus7$LncILe_sOY^Ba+oU*3=>Isz+)=tKJb*!3*1OI3`8MDiHa13Tw^UWZ< zFQ@Ntq=>{kLg^&$Jpm3P_zFW@8_Og?DYEhygx15AQ3z;=1;eqZ9zG05h&sH-;l2^Z zPEyRScZMm2X$L1@q7K%1qK+OSdSjIaj`c?S|kPZ~%rTl&=pDvI9fAxO?-o#9GT$5~HEUg=afXeQFK3x2%gPdB`b=BPH% zh+=O`Y>Q-n2h@qAk0oA5(YrBDJmvlt*e76CT`asy`^Ji&!QBF%9&%?xEPutFOn#obTF>0T(w?1lb^0d?m-er;| z+;8%gOxBlasfW2&7%G!d5K$Kk?r@y&?}E5gln$w>R6~!eTu~Q;u5fEz{JF(DvX_2D z7Yzj5XImYl-=$sy6iN=%1TRB*Oap5|Dcs(Ai z<#LT5L(@5FJr90kqYb=}$|n0+Cy~ax*&vytw{mAXZ8kD9f$g?&!+Un{ra=-XZ=_>9 zo2*tyyB2cxd&iK?N>XpT4J;bX~K zuI1sE4Dz8(9B-{*yBH4M#9t2?Hk0!r7_o#6qIhsV%bwF|7R_Gr+gvVwsn9E&1#viw zdm`CjIA?@0Xe@kS%&T_*PrUi41 z7k^yfkjGwe5l{V#F!Sbh|A>|{FJXOVC&F41f{he#ptM5S%mdM@|eW9w-Y zE775eY<`zTqj}>AUrnZ5j49)}?;amdWSHa`r!waWpN~=UjM3xS@eX^8;E!A6WO_g2 z%@G`bhfSui>vayCOq*c-9L@8AlEh)lo7^&jjUKb_WF9-i`NR0)G>1%8vZ#Ni()SW` zCsT|u1{26*^c>9usS6gT+$H|En8~-fc{PXMWV8>9q%wB{0SMYEZ)Gq z4>@Rqa{d(XP}fLC3Yj;OWBqtNf+x2t@3^`j_ltvfpF+pT-^%9F@VSlmQn~7oavGc= zV4!dG+r#1%n(boy?|dOhon#)|&agCgInK6U8GVumq+$3l2c+`P5ib2s&kGDrqM-mj z;uw68Itg_3XU8O^>GxYS^$xN$k}m@I@C_RrU~w$F>}OAj`3p-(K8=SdJBp~I?EO-q z1MdICLYowxdCtl=tbM|(avl!j+ho>%#>6z{ z#Ic_swqI~<1}8qIZmLqT`!J0sp7V)hMV~1s?IAb$>xY**Ss5LCpThKQ}o43-4d!vk0c0WIq9U1o7Z&zP`dfkz9I?qhGLY5F3Ya&}Hg8 z&h6_Axs%P z?kCXY_dXw z6xs89ulxO{&-;0wU#Z{x-q&@W$3d^xDt&aLm}j2x-cx25Fz=b_l~*n1m}1(!VcSww zmX|E+qqht#3h=6ef8H?n1y4%n{T+9{q{AoX zl(17JU%aDUg-UXct>BUO>?8)UQd&uBrIO2kaY+dyHDLON5C5^Na9QO|{u{@OGW9E8 zHp2A^4zB@?cbwl4A>Ucl3>#&jq=S~#FuxNle{j3F+y3!q7X-_otQTTQm%fUy_tH=) z;f`6Lv>}X4ks?$v6P&J#zk`*g?TIbMN_xiz`?WF94f3ffG|L5=`0Ihs+PF6w|JowO zPto=&N1;R$(*xio8OUk4+!?|kgeImq8j45um_8TB2O)1UMh;Squ;Z54G!N~ZkundpZ4kT=Ud|Xg4~-o0 zWicvkaUcvW9N-a-uU1N75GK{m#i;F!uvxJ5K-dz@kUh>4{B^^#S<1BXHB_ll(-)zR zDH_hjLwhWmg=i~mT#1@iaG8TUX0QrFV@LQ$C<;yNa<~csV-d;*p-~JPnIR|~Z7tDf zElyj&XD#-*A|wTO9blP^A0BWM5vL0r4#3|OhvkxcD6~)Dt`pWA#=Bv7kd9z8j6ROz zt{9e%rXHwu1%rfFlcAOrb#q}i9*(y#-w)~8>gsOMLuidd`|G&vjn}u-n7UmqMh0N} zb@-0KpDRcmkBJ#rCHBK~t=q3eaUSFphej%TsT7k6?H zJ_K(rq4O~0U&9kGJkP{CSEQz+x})$Y;Aw~9*I;Oc4L1>Li|e=4SN$BEFhkorIP4%C z5(t#|VK&SIVDJj9hrsVOoPF{7IWz+>;S>4>A?G7TOhc`5C7?9@0D}+&mqC9iZhl0v zNIkxwQ8>1J#GDAc{Ein35&sG0(HQd!o=b4?4LUACw{r9i!<+Z&dyD0k!FXG&bdd8) zac?|aOW`#fyYC~^7w;b9i5tcipr->8A7P~|(Qf0Z16Jq5L>BQmDC`f1EO-xwRyL|x zq4O>5l=81gPED}u68w83>N0$cP;w3}4dHYV_C^?b8vDEBYZ^*><4qc#bVc4-Eba$$ zxt}{>Pa67k!MHQ{)D_oGVv8m=r(vyZD$nDtHhNydo6e|p7P|$nbRLCTm~j;y`y%oV zeEMPMb-4AxyQ^5*6+<%dN49}?aLouu?&Ewv_~)W@0Cb;Whg54HqMbbgi*eovyPu-I z6Z9*w%L+r@;h&|{PSM*IXW!$J13DDpsSDbEK-Zy|`5ck%cvGVAn7a2+$5m>f_#s8t z*Z5;2*;+i4SJ_kK*dw(N!|W0L2*%bJ`x3d9a4E!dsqvPebRfDsR|mu0g^)T`^A`%a z>G>W{oN>KeIdOUxLs&gV@8Ky0t6yqCcCiEnUI>7O(J=TyBgzN&exlb1xD&hGQ1%x+ zWg${iW26&;H8iwGAQ>8V?&wri% z%t|;oV)WB!es|+EL7_}&G(2k#_1w> zSfkfxjFDB#djt$Yas?!xTv3UsgV63h;_QH57~+6K|1iY^_o30&3n~9F%L7GqG?HA= z_%9lc7vQkQl|T$`rZIIioSJAX8U?>L8g&IG+(x5H5E``5hzY_;9Sy6oNcm4gL^+q* zXzUq>i|sWeP|>xMMlX?^Hr22bQA=x$#R0-l(pcz=%MCPcilnBUM&(GnsH2fB&-2Lsf>XiP+LJ&ml}8slXG zZb}MtJ&xB>tmzRoP$LeqG|^lS{Gg0h@RJ+YA?i1OuSDKEP7$?DIX|sZEq?jD2zpDa zS*TLR^%2;Ak6esj@A+>D>J_o)G8JW)exjbx&cm=y!sj7q@sgXTssrGnIgkcQ-?^xG zM8k2A>oB*`VRC6xomQX&knwPO~2`0Q^=5!1yXS3NTd(Uo5As^P) z=c8IVA1uUjftN1BiZ7hH0!c-5S%Ry7*(L(+#caM1+LfHN92sBOcOg2yW&SLTE9co2 zs3>NS5V(q&Wh#;dAT|}k@fZ_;Zg;3P0?Py+>VuB?)E=Uu`;rcNokM#Y1YV?QWOJ`D z&JvF<(8dA3&$Fc!_MPW+YsBWz%N|XSP#ewLsiGWqckP2a_A7Wxyj8V;GE4-!?7%b9|fm&nf-^N*Hzw;m+DnIn4{!2 zFF8UdoAP1plh3s_kRY^wf0*Vl-x@FT>1d2>L1hlaojYtY5b3fbGeb%)zY1JEm(GT` zFJbIH=#|UrgAjU)gGK9;&(DLf;|?p+thb5k5u$d7wFYtx2y7%-9VVgnMu5iuao$koaWI`uw z$l`6Ocb(^19h6?m;s8(9M~^hFt&Ie!gtWw)BPyEfvy&TudHeYKA2m}{ zz0PbOchrP^3U^h5kbheK;lXWeQ3LHZ^An^3%zCx)eLKesB3Sg1fB7|*-|E9^yYd<& z?%~Ti2v6jmI{2Q%I(6Z`mrd$m&u$J7PuUKBZHYt?dWx}26q79wagf*QAbKAyn&Ipr zu4;&t`&cSNgZ&haV$Z{Ls*PDYnJ;C8?L1H&R}b-PHJBu^##heRM=OCmr_l5(qc-wd zAyc=qQz1J_NWMY=ZC3tZ;3m%apzI9Oi-W*w(V*lP`H^f!m<;e=4W2n ztb(;k+bER0jCdMU(qbP6{$|~+{4Qj?6cxAbpTtg|`D_<;zB68=vGTOv&b2?-@c=7- z@>G(lV#yxu(|e}wX4yw&-rOMMy&Wv5Py``2Y5(n^?RW0m&Df7@uz{JS+_;s3Pj3^? z`=Z&6V-E?+N=4!mJ8j^&cPtQ3YZ*5s^3n(TujNEB04B4x6reWn${W_($Yrm&K8ck@ zT(OO9q#JmEs|8=PRmCYQQm7|a`+Hd91=}6s#S(rx%!*PL?qii_+}*z(^q_S{JC$9%k*p3hk)o@)!)DT$^}c~`6=_m$XmRRPQ7#9hp_Yq_I<4YpJJ zky~nx0 zLRe)pTh3SOp2cBYC3o)}F51oFP?~P#?b-akQMoMZuVcs@{z+ikJjN#S=`;pxpo z5?D5ypQOz(mwxed2<6%}G@41RC^ntXU-4=M_Ib6!c~yyJ=^Q$2qV6J&kQ4DLeoy9p z*)wkE`@+A#FHC%9ngBCI;m1CFDV;_B&bE>#3S11Qi{a9W&#;?n`crVYy@Y{CvC|4fh!*zUn zgaL6Jx03@R*(zBXZv#@4JGk{;eoEwmWUfi1&VJe^a{FQWrSid1h9=WImAm#TPj2`T z9#5t1F?K!2c4@qQk^4_E{W3cr;B;wuq_f}#Zu2OHn=gbqADP`i`*dbJ0pO4wKy8K2olqAa8&58r;GbHt8g9N#o8mr^>Lo3DMR0*ZOEVM^xHMm)*c&B`g0h&3%wF+E@U{w{&l&}z4+XEk} zA;}H4Rj|?>$-g+<881W;Fa(ojFW`o8wa{n?CJLB+C~PIJ=?a}H=qyCgW=OGzQw^jK z$H)dS@PKAx=-K175S86=yDGfh;3NcKXSt%Lr#*W8#uwq5KEu>*4!XE;oW?xh02LByM!^ zm59~7H)2be+Z%Zm+^CP5<$NgY+#)^_+e;w_YGKD~j?+fpVjk#Zg>mShXiS&>yMK_}CmW+gWUgzojhh zi$iyL!366cb95h!y2noj==zGYdgGgLzjcxIm@d-0e6F4+_a1VZ9%dHMM6z2i)vMsa zJxa3cc>%Yz!?%ZYmi*f@{%eL;57=E3?;mlJCSE>Pm?`sTT+<3`pEE_Yvo9H?g;z2Z z>VkY>EQnb4J@q=t*_q2EGxn8Ry20xQ#m4gSGtZb}@h_GL2lb1(;Q39qwv!AUYPz9c z3#57}Bz5p`1ZpC51m4QRB3Kz(mk(E==u091GQb7dPYuMk0Q~5!R4F>L5*md-K{|UQ zyf@a5LhW8S8H6AM92*6f?r1g|IRg;sk4Gj59}P-kEeMm%VLAc(EpS0xs4~WxqG%iE zX5gh0GG`##6_InW!U=!oLHHZmGf~?WHA7K20=1?i*$uBkVLc2cb5QCD-MNVIN2QeC zyfI8Jyd~Wofo~&_8G;i-kQatrXKa{-u8t@bq=_SH%|)CmFjEb4ET_TEN+FfPOkgt| ztL5oB4mN$^Ib7}g5~f4X7~eZIvV;0nCpk`#yIMSgud7oj2i~n;D?fd zI30kl7HB;d2VJpd6s|g8`8aG8ajK7!!(JZ?V@sF^LzqjeM#J0#B|{P8g(|+-KNJhb zUv!udWp=ZgY;+!E1eXDs$Y?LMgPi4p_6a6@cItd!I1AQdKGEx4GW zIM*E$U684Vq4tm$POdHFiTc+ZW}RUmcby?7n_+QBg!RW|U5v5>dmzLFp&dX2w9>?$ z-U!yh9wVITfJTN$Xb;EkNNSErV*hE4Bm=aOTC2Q|wO2oCnMfjx;Mz(x4x|>bx*uk? zMy#-oTVtRphP1{d8x(efoiTRlBF7r5n37JnDn~5{2!KJ2r^3P;mkhDP z1fz|x*9rsVap{eI{bAN01>G>!1T_XAr!OSZS*VBhJ+QGq8jIPgAO17M**?m071je2 z4WXllZ+);*5AMD2tQ#zapxz!Qgy}7QA_GM0s9?WcTkPzM*)sT*Z%yrUPIN^#$@J=Cvn~pBa9A5-d!Vc{0`<|f3+(lft&c$lkiBY(Ae#FqVf2U| zDzZLlkb1T+)2G$zyZ_*+i-xW7tOG8zf?azg*F)XTh-!*s^3L1}FNM6(4F7dj(6Gu@ zFsKQ6f9_Hji`t-iEts}aUAZ=`AwZJdZDCvwe$v3Lj_OTO+z@kw$RS3aCK8y&uzIkp zhjA_7(*iGALBBZ`3;(2{($^X`fldp|kP1T!IM>H8>0i`EOjE3Dsy?g(>)>g9xYfqj z<}edUOGkkRs{na;hWSj<#<>Xy?`gAy)-Poa71KgYJTDUmWUv=o8Zznde%h2FV2)b^PoaN{o)wYvN+NqOVm`~5s%*f;5G^RXYkN-P5Tc)$?HO@ZFyVqEF zjx#T)7~a~e)Htc&u`7c1tfG(Y zj^%c-|ZZM~bMu=Wyu-p7Y>%1dIKa4y_N>re)5;`JH)lC1XN6U!#(WW-B=}l|@n1Nl}r`8i%H8IO;zq)yJMUj$GlV( zRL&9#ZVcDR-h36q5A(PfW<^cAo*jf;8Odd-e6^h6$5e9fWio3n;fKA9UdHo#S++zw99vvs)tF!e}Q@g%IkCsB{5e?d7BS>S(zvgmGIqekPYl>Uag)@8QYG{3Mf> z`5Y~R-PwGzksao;>P}W!%<^cSUdTGXUu}zU z<)kRSUd20eSVLw7iv~cKABs>*mf&@7tJGgQgy|>bSKC311cqq+xsyxZlP3$#;=eII!9)koPK9Av%ObuaK z1P{*Tn0b6Kp7sm4b2^VLp~-AIgfS(M>9crx96v8-Vjz#m%w!@h7O8~l?IoNwg|!y& z*<^N{L+wf29l^bGIeH}v=5ym3wpc>rCF%x0*Dxu9*Vl7$INv66^9nUxiQA|^*#i=p zCcl*sbvE*C65l1UPf z<-4f2omnY-wU1BssGEuZ_r)GQ+rcY4`EQ5H^G9xF#CCp^7w=v+-Kt^?Au=A6XX8fN zuji+D<@1e?VtG8&EK(n zzKymCDys2!2XAjoxx)_S>vXvcz4WY>Q(Ax@Qe(XuJUCb&-ktUdW1C&@p=l&PqNlN z4nM;!lIS~4tAkv2gp&?(uRJs|rasD%8@Vq})rBfO=N*L(^Ez|kw27RtFIg=3?oSv=%OA^U@lSQ4&+X@~r@yB8Lq^L$?jbD8Cfjc#jAuRDf3@V_WtjR=PS;>yY94_C13JGHw_*2Je*Vj14fxhmqqfi0FsC}|H^riVoLnEi_BXm+ilE!Y{fC^zR!N z2~oL{|4La^=24%xTKZFEtookAzO(L6b<1~ucZ4x+OcS+MO9j`JKzNOAsMZz>1|Y5#%KE`u z2i*swcmUGOl^aWJq4_1K+VN6APA-X@ZJkZS!2E(z_0&R!jid6L_ z$~y?Jow36L@1=n&rBN3wbb`M>ehx-AXRNSCo~!D}pYp&r8%QX(r5PH^Xil;vez;|g z2NHT03y;J$9MISwGv!q1jXY=24+a+4Bhd>xtPjS18ypZLvj;{8LxAd)fhc#v-x+9V zgQ?>Y;)J)8kzkF&>9}bJ1tJcCc3=xUwKNrs1FiwI)TQPGw*6qZ(RrtIGVe{b{j}AhG zID}hEVRs4}5)gJ6&l3=M2#$$}KY@SiVSEbxwxJ*mWd{+LjVIf&=^`5L7FHXo?1xtd zY8}9tJfxnIB___Ef!9?89l-soh&+T@x3TajzTSe}X(Z+%VFzyC!ILBCn~kq05p!FG zKxX9Qa2CGb!+=Xjdx$z0aPU4F+{Ay+Q9nZ#o%nkJnYWRbju}tzBwLI&7;_u<3UKrq zydGoB6?A-tlryOJ3ZF7C>M^dK#g2E_e**XNQTME%)G_oh#@2(wA~nZ3L(efaRS%2BJ>=N>_T!18Xds76a*!}ZyzqNRT}Fy zOVK6~_2Mxj7JZ{(wE@P_=&~9XD-a%suF(o&?70+g!!c+L>My|SRcN^cI?Hin1>P@4 zpLOtCuAXeQmcTR?;gZ*iL24+r#9~1VVx!S99Lr*{IRZ|}*cA<*WSrc9QOTIS77<&Z zw+>;OVH*SeB)m_+H0eIX;@Eoi1M4T@P6Xb@EBbd_ys9v~TnC>Oa9xc?v$1|XR)isP z6IVBzoU=p5JS978I1TBpu$YUlVsf8?t6r!&9ZADbG!ENFp#4nz9IiSnmZOk4 z6RW*2cr5z4V(K)^a)r-0JaUIu5Np2S$y+CW*>>;j}iYd*QvvJx9Sq7w^1OV>jOm zmF?i=io1eu^+XlPC_2JYW*W|zSR3ZHklplFOH8Yaakela+nFj|>;W0~)yDB25K>m} zu6Xm0GrC~T-+b7d3wf8@M+&=Zc6c)CkyTtz9QAN*F-wXWpY z3#?zkYNzP)o&yfB#~0Q)!cu`2p5o#+^w~kbXPmy3hWD7ina_&&Y8Tf%RjX~vpgw^C z&s1U7^EFL&(fJ8~Zs+ZL9K4Im9`fi87Qa%wzI6qxd5E$&D@cd6SXXfe_zmK8&AGx^=(Su8N7yzpD-eZEg!OJBn$3w8zYMv)#C97yH|Bvmp3Pxor#Im{KoF z@P@n;!=r&D%sG30Xz^%y8(<{O-)PQk7Ru-c9dYh1H;yE-4MoY;9YkW@=x^R z)?_;Rb6hf`yy+y};mN$eld~stND4Kk@n9NPOkkH|9J7?Guc%(9~DIL8$ep<+s8*DI>f`9xsm9w*WW;#oyH$9PYw-_;-Bc$0kk$ShNKZdVz`D-*^ zNJe@DW6trKH&fMzAd~!f?f?e`^4&rD%-{|=Sp?Dg9RG!?dCRS-^cMj2Dn67+Q6!J&ar`14&1L8+ z+UL_GmPZBQyM|#8*<%yiaC{O0zaw3V# z{_%udq6_)<0A~o0{1m?mx9v19{NlHxDzt2Jh`GPmVlSnRwC*B1R7b}%G^q!PWc#*6 z&rAg&Z+V2Q4~z5kXo9n+xc5K2%~109@n<=p6|CgsqJ>>~%xjL`B9zxg$wPK+g{ikV zQPvIjC{}{Q_t{4|x;LXKPaf4I3;Z!yqI?Bf`$9F~WWwkNfb&ItHO>mt*bTBZRvE6Yj zS20C9USk_g{L5$aZZON@!rnN4g?&3C<0dROkuZb;lWi3 zv!%gJ*3yK;`_Hz)B;l0mVD%+sZOgw!y_QJ5%=Qhj=R7m(;O;HPH-iiqBgK50$@y(i zFOQ~;G3hD?)xxw(ywhB{3+0wavQ!{k&RnnS$aM=p%ar&WeVSliIzwwg#)I*VvHlX% zT0>rpMGcfr#kdK2=kRSC7zm5CHCEr_)aG!^XHq9lbX2Q1KX>>s22+AAh0jG*M(yrENYFQt83DDRg?{?|0VrT5J!LIJuIT$aDkYbD7 zz0kn{ul3;Rit3_VT+G;_+o?Ij`%F+2xrW*#yR=xY*EJ$4a~5%zuNb? z86w{VCPrvviTy_SV}Qr~u)q@M`(nso7z(q;DvTr@zA7n<~j;SiYg#nT~(F~Au=X!gWpNmLGml@F4{syQ4mfvc!9`(djm?)8Sd z8(t4Yr43f;W05U{2rWy=`UW`CA7lGsyfDi8s7>WceT3+vPe0^$#(Etz(Z=&0h}B2F zHU?msi$UNpo} zEnI7XkoM56hky>aRSyS*EL0ES+M<<(rZ!I3#|M#O*TIr57+VJ?dSG=Uyzc<%Eza(S zh#Gh(f|a^htB18Ulx%u(J-7`(mp_c`hp|<$-2_d=-`!sYd&Wx`Lz<6rw+pb;5Z2## zw=a_9x~?|{3L(=FjuP7GqLxS1j3Juuf4$*S!Mi%jAl6=D#-$8ugc<^FZHwz4Szn~~ zZ#lIE`n+dCJv4u#Ix-TUxFWDoYx+~pBSizEcxWsg;3v(3?NA@cWq27 z4yzmSSez47H>VM(tlRTyY{o_3Ug?CP~7kTC^XZ_^BGt?3w z@HrM#!KG6Suc>@t3u{3DERhoDmX9`JhUYN;51mi3op~Sg2)9f=VHmPdW!OaYo4%cRmlZo6` zwwHOGL?z`SKc0u*vF|J>o8 z4a|7Jv$CYP%?ayx_8D78@mnr?#j=^0CKmJ0Ew)(3jn}w)9bIlRZV{(sbHWm~zRNMf zJjv$EaB5s&;%WxmWNIkA@;Q1guim7^Qg+CvaVT?d@_|$!Zz-4z?o%tAF;c}{#@5%^ zHCj=ChDUJzUA5UMxyk#>>He5)mQaG+FQT|Om+w}v^KCwfV5b85N3(w(+lABXF0q8e zviM#uCi9f^Vajz*i(&@}I<8U(j?$&Nq|)LARM4bD3*r@>>=SrgB?4{iZQp6f;w~{3QE~SCpaRASPxo zW+K;Tu_TZg=Qt~fqps1&S1pBa`}5c(o*GY)%?W%a@Fr`I6SqvUe zuRPWm%lp~%HzEmYFK?@Hg}4aG>{27 zJU5n|<$5oKNl&?V8k6N7o2(M2^T#sv#{cWdISPu><}RK66v6euIO^wf!z6}3=avbK zdQPnn?tIL|ST$X9QDuh1-t)^+6&BqcsQ}Be z!`dPON=fJbQ)HwmWSnf-1n8Z}{Ga?6!^71PyqQD4FmWSIBy|==Tk=gZ=lx-79QA+k zL=0`d&^4OopXeOVu`+aBK|P_4M=|v``^9iz8Qqrf^fOj2;^9x+GoR(fOpoH$BDElv zV{(Hfl zmSvB*Jc^NGh+fUDZ`d@N6N@-rs6;||Udzr?Yu zoVu%7RlxYM^nI_$PMV*1K^8p~?3%zqpLk;_@5nv2mNh_zDlX(F*?1OmYXk>9W2+Sme#jl`=v%-o%eh$w z_42B}uhwA(cNLnZ^gi>Ka8*9@qLeAgH;Vc9X|Pn)cx5Fm)d{CaHqPbL<=l`>_l0!3 z%^RUizr%HNxH_LB!qic{*%Xy9AG%P9nHnu*o2xuKn+u&JXvfJD+1Rxio@~ne<;xy-aQmr9lSk&ZqM&KA)#b!3C4~?G!J} zW@H9G%;K5TT)RjaqvFFEeTDt!t2NX2g%q9Et+}+xU{N?ruG4H0SKi`Hp+e>IXE=jp zi5A0l;)z(ty&_*;%sSb86~STGshP~)cX>CC0r`Befsb>!aRX~SB2A^JWB3-e6ETT~0D;8AC2Je<{sR^I`(CFH(C2#e9*m zfzPwqJBFVwaL{^ciES#5zc2IEdLF*QAF*6`QOOjx9cOf`66u<*WxwMpGmw6qz1Q&k zS^kM(tzFz6OOHeR5Y5SH92U+~Dg3pO`e}R_!;SK|NAl`P{#wWDXZSjX`_Hic29CeR z$w}-X+4v27be*=Fc|U_;@pR3j@pcZo&9z&&_%3-`vCt>WTKOqQ9$?%nHr>zfPuSu( z-6d6Nj)V|D*U-a`Z=76KpWRody^w z0qI8gZI1o*6wT(ktkO*Jt%EwYY-)!_avs!#h6y}6p`itObb_@lyxW6v%IJvA<~XdS zu9@oz{dh3u3SD*}yd}?OfdSnydN2lP!Mi`IYNFWyShT>`Ubxi;-TPu?3)Js|YC=ls zg{DmuL^`4l{`A0f>3R!VS&*c<_##Mo;g_}m1|Yc^ZuG&%dNA#c_*R(I7tyWZGZ-OK zEjPiPPN*=1uQo=Q;gU8U7~@Fi{~y-=L(~4y)P$`WV!C6PDgH0oeg6bTAa3sKt8?*{j_xT%Y8E%2z9BI54sj%C{L(Z?3?NDjdHHW(n0 zNG;qLfQee@H4rbfkY=0y$JbNs4!8bECf0$|d{|%`VdfTb(lBj3weLEZK>caJR=7IeMF_jO&yESZjgk0eC85 zT5J4t!X+z|4M6uncwwq)yf3XWT29|~NEwc|!Yg)%nTQ~VVS_C)J@8OE#Q`dq?J*2O zUV7n&HbXIY7}j{BZy>gfM6NGd`QqznXa(TlBwY2!m=U<(k2j;SHApeW?Sm8&YJ{L- z{b4yCXGdY{Xv`job7RzVV98iK_Qvzc@btm;iFog(CN`a&F@7RmyJE^@SUF+fM8vuy z)Enc4#_W&J9=PR;U>Cd{1p{~Zc;l8MhIpg5BYgc)>V)^6cq-W2(Ma(`TX)>DM~9Jc zbwm6JWXb*PgLqd=@>Vyy9*p|_SQdaBPuv}im4R3=4o04E48SF!)Xsu+Ff68_{Rn7G z!p2|(O@hTp44#APL25>H#2?>-aBwIx1eM?i|0%F>1BHqffV9c@IRd{%!p0LilhI^| zN})G%RIuE)4(REFHs(0!kFSHV(HFmDxh!M@BRq0d@aOSv_^XG0_L$HG$Lv%p*wO)- zx|nZ|o*fk*-cSeTX873`I~`#ouU{8LO1#_}Mfz|yhj||~mC~#5(gSea5^INIhzG6= z!EzfI`r(Nu9ERedH{t`ZXBZmE1L2Dw;}JCtgU3T#R>_kPGag+h!h1R<%)yp%7&;4X zlQ4Y->WstOP*_Za%~T`|$LHBNF#&rgqK_}yj8V0SrW4`fhcP4J?1^?hIO2)UKG2r; z0pV`B!^s=F>~Lu)=9?p11~}Ge>528mSR%lAJJhhn>jC)Si4;@SWY4t5bYIkW$MO*h zWDztJ-R%F5sdvC*H=LI`ypIBWnR#HjGxm)@O_>h);i)HV$6%R1mii*q2j9nF$QZo# zLkC~<@>gu+N&Z;mj|pSoJ{psQ@OcCtOh5GH@c6;9$!=o#&vIu4915sSR900 zFEkj58bc609@~dvhX|ux5HJ+S+|Ws$hmLsS3x7-e^n|7rEIcq=ni1}Zwm`YN!UAZy zV6}llBFhW^s1sK8$37=q83aQQxSOEF1*v_NZlKTvpPf_)|DZE^o50xt^9^y_Neu=~ zJ=M5O#~BqSXyb)U3!HSo0b?xpQgwjIlVBr*L|@diLasl&hrlWb&m7?EhpB>Y7^i5` zmg8V=i-?iPbU>{DtQLsbXe{=@py3dtK#6qTJy9_XZ>&*00K;XR>y8~_eh)-fCl$k3 zVvET`)f-EZE8+$t!5$7~$Z$Zvp3rbs>~x_b*!Mz^Ob(@JHUzD@V!R7Xd!UY;`rn(} zFi+%?uCVTkD^_sQLF1vg)D;OrP}f$Jk1Zlcb5z-Q^~(=XX!_)V3eDF_(Db9=EK!Z2 zcsl?U(#-0MGH(?NX&H>PK}w5YZ4L%O%T(zY8XBRlH}>>Fpgcx{)s8i@51#s>MqkA! zI5kk+C+%eZJY4k`Rt!ai0X&^iwL3anAyZS01fhlL=7?yA#d4X^8YL$9q6H62xHX5a z^qAVCb$_htpx%gjbWj}lhMh3SOzEe;*x`*1`VK&<4*Hv+sSZY1sDJmJBj$);VlX1Q zJHe# zQ}FM0uoCh2PF}9oGM_V);gsfIL zY=%#*(Q}{@4c{|{dm{`pKzcL06Kki)H1%OoAE$d_emzhh*$rT6gz3#Oyq9X&{WHe1 zhA`-XSG7J2BV~Ht%(XzjCDliN4{we ztrB*qiEVEwWcdG{^P0e@i&*O~W1rEu7BpY7Tr8;fc%nXTzvS^6$j;!O-^|Zo_AhqI zpyy|%onp~n`ds3#3f{k<43eg4H2kC{8?%eJFpUpISd+zLZ#XHP;@Oc&Nav^QdxZ7{ zY@N>HXY`TK^?ml(%UREO@+du?vv51#=Ck`gdgriFB4w(1G?52yvUCUMUuFM9zPdo; zjp|q=d+kReg^A|jvpf>TcIixuP_^aO>y^XzsxXIBxiXZqPcv)@2dA_1Vif{35r*4I zcAdbA18g^iWB2grc-rix=Oper#+AW*dVmv0vDQu&_;B@3jv39^?FWl`R%C(39y) zso}_^a1QgLQ3PY1XcocFUThME9^Fc=QpcciWUM)7 znxoE~qk@`}-<~Q8!ddE2e{wckrBWw^VP|+IoZnBgBwQJp`$TfaDY~zs&IwMBWu!nC z*HGg;2dt#UX)apN6PI~+4SO8tbOB$V<=IH~yUOD+3_Q*2D_QR>Z$~>j}pkp;-|FPO#Qne%`HK9RV5a`Ie23 zbHWE2on))me6*YUN~v>LvE97)^UZVC+e`gdoRFv}Z5?+|mY$)BY<^$;wlhTCo5Txu zd3FPjJm=*^;*J8UAH7Y_^$fd1oej*-VbW%{dqJ;l{C9`d)+v9qUleU_G9ii0a`&;GeDeR&DL_ukL;1kgE@JQaVkK@qC7| zY0ODv;68qr&AJm@`-CUYP`b{k7kD_2jn`S0&gbXpnZqCMQ?EdIOkR{Q`~j^?)E6Fo z&N<1v*2tC7tZd?{c$LF@K91Ac*y|qCTWBiA_P1&}QPN7C7_|a$jNus#9F!02JANSa z_+~|NYiQ@s5uDyazc|{x<=VSU?qo|G4>U6&f-jmWBYk}dX1dSZT8@vU=1Vq4^U51i zz=?19Wej(>(<_eGnwb{Imm1h9S;lWw#`mCh&P?HFZH!8#7?zzLtK7h8Pbo=c??2&m z9XLyVx3OsI*w+TfiWp{rIR(5UeX#%`jc`{cfn8xBX=`1uxSZXc6v$gu`317TGRbHT&std$g!Dz0}#$xEKM#P}+Xuv4;C zUkgl?L}^FVJ?Gcf*!_zA9B^3lw`TBr&Ogntx01^wdHDrvt#Gr7cbySZ%vDC%U&39+ z7*fU0E%5Ctp6QCaB93*!>zAD9sGQM{ZISqb-??C8BYnGLMhjCsu;LA8x?}x2E|o%B z6Ei(g`kY5F;Z6g^HaM-B=Di?u z)P+v4lu*1bsHj)o|4d;E$n~#etsSCjdC>;T1+V7{?>e5dMR66^SRk&Lubh#c$9y}u zh$g`d+2!g{=DKHXVNl5QE*Mk7o?Y>@Lg@`g7x0A*)(B(40Y8-}J%;Rq4!gmxo*9lR zXMBZ}9Iuqd!}=ZnbU`>UxEp>0#&lPF-ARtPXn-YB;OQW(o2zs`# z9)@6B7=~cW06ZUs1*n*e#mjJdA{-W@*BEqLj_1LcvUSHW>pxh2MA_T(0``u4{29OvSZ` zIQi;QOb)@pWw;W8j;XL7g>_3&H(K>&?jkK%i95l_Sb`Su{4T~JS#~c~)ph;~d?6sU zWw<&Je=di%FMfRw=Y8<|GH3*0?^2}rVA2Xq_CxRoSmlKkA7IEZrG(TBK;R0v1>utq z;T-_G_b^8+uJ0pZBz#3#Aw!-;IPQyYmm|d&Vbk$L09MaMa0nhQMt?CWFTi4f1TMqv z5S(6uu0g6F%$3*WQ#gep`aSd>36BN;Ng5U+Mk1dU;mRQVu~O+koJB|Bje|>-byvQR z%Rq#$#dN{btwduV%wB`31JJk}_I=eWexVOOT&mO&&hH_10QP?XpJDKshhIfgu~2o~ z9&_=V7^`O~UBt3kI30kP>Dby2$0y*FFQ&}HNnfm5fSQq*DP4v?T<5|!7}uw%q^*;4 z;T?padGPSV-x9Sp7BglkwzmBW7>!ZA|6hUFwG2~(v41s|N#FV@qUAMR4bSPwT%q#0 zrmR5tY+PH3eG2 z#@02sI15Wx!+$P}zfgd<+pExZDl)|XJ`G1#;lfm0U8E@GGDUei5zpR-L{u+%4=Y2V z^#Lw~jUxG6$kTFq-{|8M%^*mIE;@}5(5{BuEVG^nc3?er=Hyy@7$eoGTqmVB{zfrgs zj{|B#g$MAVde_-cY2ChN;ZH zgRyleD*RPnY!{%s=ide3dJwvb$vqhU!qOD#mkhW96?f4%0CE1RMZFuO9P5rlksW|J z!!T?Vz8Q{~4Sx*A-QM_h5JChg*#~1hRZ?U(FH{Uh>o7c$ zXg>*b^T6ZY2zN(_7dG`o_aTt`VA=qD?uJS~EOCU5C+ZzBVF0pB5!M^G%wgIOTINWT z&~pRm_JgeW1Mm07*)~q>4n1AWcgIu> z6^>T)n%lbKYA3hYAx;zZ&TtoPrwgP`53@l@8>`Hb3H)S%V;w5#br|VjhB;(6BW!4A zxF+UEg0>zG2pmisQh$bOVR0juiQwlAPaEJ}4L9k+x{(Wv(YK!O>nWItgg$2!(@#Q{ zMW3Sq8&Sv@!lsmV8u%oS?JXQs&Ql%yx`KOjFt?0ZojmlEYdbhSo9SeE7JW$X6k4{j z;t|)ju`z{>?Oaw!16}+oWk9>Kza_M*1)onVM`UwT8y!Sl^MO4LlRUl4fOK zlsxx^zyoPLh_6`Xrf(TopV>9zzdN>uw+d3$TVZT-u-B*OYo>3gtLB{YxEoa{0iB^Uu@SqkJ#WPb2@po0`tT^<) zY30X438+_(fvvR8;MsQ7iz#JM78i9YA<`nsx}@?<`$t*<+88DtY=c9 z^!(D^c)<{r@jPjXuq^H{#Dff0NZff6FIwR0eLgjTEW7uZW5WZ+NbLIq#u;Hr zyoyS%6E`W z>(cR*7FXz)!^t=4T*x<9=vu%xXZfOlM{jXs1rMFz*$iI3%H_Ene3vo#9CeQObEtb& z0rsV5-(Ae@5sZ4O^keJFm4CmnoPL)T)_dN0`WEx@WeP}BY{FNc(?ATldF*|jpBK~M zv_fZhoM+#1`dp-58K;R$w3s!Qly1sJ?4M#Yyv6%vTqh{+0*<@K$ft^^KdOjE_xb7t zvu|-*5xvT3nmJM5~XPZYySc={&4 zt>#JzI4D!EwMVfM{J2&yEt;hze0q-mRPf_lDxG}C4GtCJ(-m$l0QfzZZV{R**ED>%75=Dvj8Lc zxSTT+c%hu5?r?mzIyVmGu}>U#mUF83UbCooi}@9dzD(^R_D|xeJi6RcpTwuvSuI%9 z2yQD?LI~lLC&=^j84|&^5)O{0NF|@#<;O*|yv`+M>@Vj`Da~&(AeTLFGOmojMN+4N zKipEM+>5KMc+5$+8T3pgJ!up%KZ-{Rl<~IxDW^%&Qx@HB@`Ci~mpQSBzuaYAB_~9) zqmmCKekh-R3(Gx^FK%*-SX^WHXCcjn%3i@2ci2+F|H*Gs$$m+!Ddz~0k<@WYG<}LW z<*EvW|M@O|E$5;bPA{S7Eqavlp9^fyq2(3z9+r34%%{v0SNJ1VU*bwpzg$*Rh2f{z zki@+gc|MsYXBjMq_66R($8M*2Qf?B5Q~*TjS;d4ub%MK7XnmTxNvt@eK>c4{X3%3U zyU2eYDu>I_Eakp={)AqVcTmdE+k9EbGomgiV~*$+O86$3E+tHU#5)p`@sJl@^2-b! zd&6NFocl`MUw(Z}JmsDax(fJ_v?}G3Chja^MXSoQC~T!~K65k?`iKwO6mWi16Mrt| zMMD&ee5jWFGPzCC1D~+Cjyh>fdd7?C^m)#ANnBY?>ok5)LZ3tqFXE|K^&Z}m#Ic1u ze~$%4imqRorzW=x@~L~DjurgiE;WmpoIsguSVc3VM2(fq%T?0W9?>a9((oD2-&Ohz zx$+0)lOkHs0>cmJ*V!sN8C2*9up;H)H z#^=eLQNj1bjh@T2c)l)TRy^BFRNhCXXfmJjONkmOVxKmi$Ya?{CcjX3fi3maYvqu++Ne$6*O|+)=;Db0U^*3($sjhX_6|se<12dBW3`OO~AWB=rvx|^9v^_ z4TH;g_>IQT(r^t?ErW~{s%D`e2wL+nZ8*LaSeYzO=b<$iVRO)5a*LM0XA+(-!t&7= zEC95zn6wzaJ|?IocvL73jm3ru@RAB&Hddo?cnoZ0?>|_9`acOr;&Al$Ril`m z194b}SKfH-jnaN_=!@e12=IVicci=GWnX-4j|*;iWQg^BvEBtwB^urlXM5tlHGYuP zRAY4Z#+xqa;*La#*p{4SGtd?;))?)CFZJoI^sYr3FTLQ%bTy^lp1|#OG)<;e5p$k!LM59L>5#|BWWLR2 z$rBFEW?G7pQs0sZ^HZgrTO|VNbOt?SQJg|soJry5DU6bUzo+~&fnPo0&HKEO#RC%h zlgH)^jus?u9y78j{KoT{{6n>Q{k8VZWAb+mom@=*r z6}niT%G9iT%PS5Pbc4(iE4aIw)8zb-GyfF_Rj{ar%PML3oCiv1+d%(Z>Xa!p@5vX8 zdP1w`YRF$#!;W~$FmpgOhn4W(SjJaybqo_rxakgMAvoR zpP}w;Mjzm&C>}hm1kbj+x$P!f4l_))GyAC>$<%G!6Up@BJSfpohq&`PHIDPm9mXBu zrWlS9sa_Pfo#c)vx}E2wd;I-8w@ZBCRql-9!u|XpjS+iU5wF&ETLg+L305KnzraD6 z47$%>{Wg3JwP zm>TB$=om-?z`5)JwV(eE8 zyvn5;{-gVf%VP^W2o1BJw{&*KBpo ze~zcwDFrM3S@yYixcE57#1E<|zq z4(45>?=IepP{8dk;<@o4Z${E<8}shaVV@GXK03rr_ta0+iQwQ}939V={dAGEuLJCT zpBHv9IFUpCV8;X2Z)bfxPw(J+_jva&PPxk?0>8S=*uQyLAU3->G@ifz#ruiMT{}IU zhYxY3V6^{K@4y#l`5;=YYmde=>nsPysZ#&vG@d+9`(%C|p=8OguCOeb{iFG1IxorR zPFO3E>{G(cF?{bi(*$%c%}X4e^B8c0W_fJAsWL+gAFz8d-S1Mekn$t>Q7(_1XKoD( z#PCv0$E%Dl;Ot8Z68_^AHk9$rIljuH<$3-s_Qoshp2G|0`AZsI&#_aGv%;p6ChH8- zGw3fgxh$?fOkGKuKE^$dS$>=g^SJO7jkEdnc}_2&%O(CM@tRlZA)cm-bSmYo7>=k? zQ-sPSbG`&arGX5OHA+=)0)0&l;^ zSGD~69=q4E`yG}yaZemKNwFG1w>BEB&dY2hZToTDH&Gb!D#-(+!e7}xgMR4m&?w6d_W{we^c{S%s zq29pb2|VzEW-%OI&jD%tseuN$oYKNL(Mz|`TZrN<3@qarT~y`rdtF@4q0HjMvYn!> zOk`%dkeiE*IVwtMMV>3;NFDTluI}Yz2)%9-+xzdz~d1{oHe8e&(*=7^&BI*=td6E!#{N#u7jUmQ9O?_k6P8qPg;3O18XE5-V7HzxJL9m zjr`RNwypHiL{UAv8AIzer&{2%x7=%hkI5hteAmcGaZuJVR2TPaxVw|?&(!Z6SYA4p`U~%Pdi2j~Z)q zx523{_{kpc_r%BUSknbtWw7ju8b@5|hXcLQzZZ7(#4#VG;j|CH9Vw@WLu&{I1>+ZQ zILWea7@S69v@aS$)E2-s2y=t6WSlYxPn@6@5Lwd@CR6&!2pX&KwuMtsH3j#*nNJ!#FcQKg7qIDa~^trg=A6pEyvhJN@V-jTpaxfPiCNT z2_`JSyA>!~hRF9}y9k$;qIMzrt-!sRFnJHZ%*FB*@K}P9CCcD@WueMQ`g}Py%)>t- zkzI(|PnCSyeigQg;%*IQ&%w>Ls9gl>FHo}pNgqLT88&=^#t-ntdfZx$!|U<00F>5a z(OwSsFbCjO-6Gd5<}1<1gmG@>Im$gsAPmfj5!tzi|N?YA2k! zyEE`p5H?N0q7f*YjZ?CVnTppV6(sy{sJh6elhCK-upEV7$<_2P4rRdA%@K zI%R*H_C=RINa&3!A7BW&_e4V<)sZdo#l&7%HwZ61u*MS`da6~sYftFN3dtGaK{((7 z`yn{%4p-SgIjQwcgfqSxi3AtbPDa|`p)dA3pw;beH-5K)z8}UrNJ161 zm@9y=uQ~R4VPzMz^~ZT#Y;(nQ*@-wKP7k|nk*SZbg^B%+d1i>y!aaMKH*rB1h^%sZ zS2%TYgar(mc;8H-mr!R9>45g>V1yQm1Q9IH=>i{Jw0A|Zq_x^&i5X1gyUDoN4%c+> zv4}=w*&+LSEf{pgZf*Q)hZ#E9-5t(ySUX_59#S2kqlH(lkh@YhF)V1RpuP0BoFdUn zQ3f9ieZy(gpSPoZ1Z^i=Ic~`Cjp0 zFUZLHmJ8O_)7ulb+Ueh2MM8Yn1)dFj?FyYHKCy&u11}2JxS5k&u}}($V|+dyXDpRx1YM9c4ev~mIS%*CR1EqW zdlm1s%o;`_&o)F#IN~jFZYFH(Q9Kj#%@k2;jTP3h;4UGOdpCr!{k z271Og5TXznF8(mp#aM5wFhruC`t#y}_&~y=dtmCHO-FtyMg%kGVCRX@JH`ey)XrTJ{n$b}{obVO30BQ`pvWw-z23a)mAq z3fZO$R+X^I0FTAKYKQ@1@zzD3JnHG=O##n|n5Ts2O)(~gj#}`E=V&85e#lQ`aFNB| z#jXF8`W85v#1D)yA&IF1BFN%w3oL&`LqqsH=6Av*e8lYrn4G~N1N@Q7Up28fgR?X- zL#Rahh?c%d58<-%FvQVpnrb3ClTBLid&IZxG?P3~F>__GrIQz)aNAq1%4XCX)rn7N zX0{|=)idTX^WSjF6Rs2YdOB~3a87(=+W1)XdySm&fS=Sc^FHTRGd_-)^^~7j-N>^E zyjRP)*Lk>xRtcQh#N83>(L}>&MQePTz+=t)@E&*8b6OHFiAVl6e{NP;x;Gk?S@MTw zhTrEm4ICE7who?R%x)FO?)qoI+FQvUrnALiuLaW6B1e8sOXfE zB5^yK%j;PZ$Bi%8?Y`ntN}p~f`ARADt>OJ>W=pVItlE|Q6wOstOpqOyLO%nQbdkiZUWoKEF01~?f>tXZDZeb?ve28 zBz9;bC04adlEy2q>1(lRzol~`vl{4`M4M`w#Pi2;WeYv?oQ0XptE2p^$QtgHsY?U@ ze8^38Y65evmAX%PUjxatoG!qM0_L_;M|RWN_(+EHM);tTUz;QSHIvNnKUw-nJa-GH znPdNJ4zo}Kzu&szc^hY#DR8=M`a0{?Is8H{sR@jPbfF8kW^N-di$$@Sg_TT_Blo}1 zpK~G|Z|0P8_G#d}|8jx?A2Yp5B^GV3=DcjRxsHqHf^sfM&z()YC7TQRUl;Lq1xxZ6UdMe! zDiN%-l27ZoAz#rFVr5n@V2uLKmz{D6x5!v5i|eYWFH4_lZYZG7Yc+h6>!$aVtrD@9 z!Sj`Dl&MIm8s8l#=hqqhFpvLc^7{f-rgBOdYg1{J&#VM~luD;Kj>uxYm|h<%BCAoH z@@!5iWR@fyKjQZ(tPy8!2J^Dmn8xsQJ`%`)WU|XVFpEx^ocfd-(v^qT<00$gln?a9 zBhE{w#Z&(KkeR89OXizMK})qJad-xAq|!D`4Gk7#@cUFwlr>PA;w+mFHiq-k*BYa;%044k-o2x4+@Q_@w+Y4c-mOqxNq^BM=eAB@3 zuPC885=P7>ii6;BD~FVD{2N-8a8@(NJyYvo>Cuh}y(C{Piy8D}|l%jEAZfv_GMgatjzF zM*B*-)bTILeQV&BGCphJ%hwEV;``6()W)C&PHLltj9xpGMnV84e^v9hMjmXYUK?-M zut}gwWo*!b_;zK)ZCK2e&D>kaXH9gLopL)bJ?EZwE-B=aX0DR1QvwJpLoa}+sPB%kfQ}H zH}ud^EnaIgKkuQAotZA!ARHK1{QaD7ys^7UshzcDFCeR~4rY1ccsqCZg1itf`@lp8 zpSZ)3{L}@XX(-t5HZ7z{)`pq-|Bf`rM?G=Z8dp8=y%kLRtFCjWCw56}^iX)YqQMvW z&bZW91#tW`2z}k~TOVAuRW?uYUe)-crVCd3W1IyFywPq99WhLqLVE}r4dLmFvHB{I zXn-Luc&j|JNMW+QWn*8+Juy;ZO2ok}-?p8nBt5E;|9Ii(YdUvFk&JolH2Ptu5qfz*s(LX*A2Pw;K4|WOt^+aL9;fs_5P&f7_WnZq1a`JE8=X@L}37OO(CG9 zahk~X$7*ft5DBX>W(-7`A^Hx2mefD}0m%@N*1!N82SKFumELGFMRh;i(n9G#bTLBq zAnXt%R38*u;l>br=A@c>*|fF~Mjt2C`5~|?w7n$R77?OGlMz86zU=`+v4lHgY!Eg& zAb%8soRsnn&PefxO&2Wk$JY)>^2IVcz!!$r*gFi6l64>!n&E44F6&}*0H#>NaTKOH z;mK%NJHmcAdfQ=+Yze!$G^SR?r)!1vBsmS7cdDnKJfgHQ2I+4 zCI%ueSP7U>G+1!ie@)vfGdm$^pHpuOdYkdE&1L_{SRy0ukB^|C7{m0TqTQB0+IJcXT@Qo~K%OV!20~91 z%aSWJ05?Q4*$a<{VYn-P>#vTQTiy_;-~?~PI^nb4_)@wC$-?V~6=KO31HK2|bVa9| zN`tyAE`HJViMHPePbFF221X88Y9#^6IA;J!DjaK~B6Z$rtNrFY9c-{hh9N#S!PQ0% zl@FI#g=BJQf+!=ZX=xvWp zhIrEhmyO|X3n4MCw8TeNh?Z{M2uGap*bH8F*yxO>?zm_KZ5tev-_sRWtYO<7Z)E0R zj6+tq=Y)lZh%v&KT8d|QLr+qw5vYd`jZr7zi6)3A&9z~zBV;DNd&_^#@JlD(87dB& z2tj8^ickkDfR&xA_8Wwbbb+Ijm8M@Z^lGwr4P5aGmITD0*_Gu>PHpp}nW zxlJ@1m6YJ)*BU8rW&HGw~D6>>VX>;*xMb0E!3aS zX(HVXp?cWti5+IJ@q&k-+q_g9Rcl{_n_~S?tm=a2e)!f2Ge+T+9r}wr!$FY^wCu5C zqB43sAEz_}%g5oi3pyrYN;ee)H@G|YgdxiriIdem`k$%L?t#5y(Afv+v+=}P={>6Y z;E2!*&paG*#MdIOaKp?oh!TpR%r`u6Dj0{I5ilN;9Wibcnw(Wm z*+6&f8;+&+=sg@YmiTuB-dd?~-_)*H+8-jPSt^V>L#*l#LDGf0!b%UJp7`BCl`+9O z810PZx(Kzyd-`Z{!rgb&7ORe24ViMdKF=DzjEB1g_Jv@$gVM>5vqV-HBIL6ifK$S2 z9fNQ)mGzdQkI?~;maQOIOizn~6qA#|-rOZnwzGF8Z#Au^mZ}_$= zB4Td|T9vz@cnL*3^NtI9;EX1c#iIoE_7k9=O*f>r@v;M6HB%0J@g#PU48hkFh57R) zes7ITNwc*_R2^41D7fqQmY7>lBOA!RvZpD0WqK*Xm<9^0a=MUqjIghfQ!MbWTn!sI zRMEu*e~R?N0#C}=D2&7!YIeotm-KLgUoG9;m8@l!HT*jGxjWu#qZG;3a#(dkRvRN- zaI}TX-0)gXvtBUKzJ{Au_z9#Gj;*=3?4?~C^ z5(9Cq3$~4huMRW@;*J#th}TBsK*B3rHe;#wh&dj2)pk zV2>{(iO)rmC5(HB-wg8|@xO7cL$H8D%*vKr@0Z#&9Vh6vW z2(?0LAWZ)&v`o5UNFbcdQR<61y7*b{;9U^mh542^C7%l$BnrDg2W@?@+XQ<3a6%vU z{Sj}0e+GjV(Cv$nCV1-xeMhVvsAB2ddSZw$Li?lM0?+GX4*y=N6KrLee2O$L6?Ww~fYq)U|<$Wu;CW!f|9Cv#60Ym<~RXLuZqvp7M# z?T;Cd#G;4Pmk{SnY6(6uhyM3f+?#luU#Bqco)W!OJY;bOhdoeI&(eEJa>-0KCNuvY zjS^}8h^4t4@tA8;RQlWPES`MGA<5L2FHhlyG`eK-LIw?T_*SN8k5%r>=q#4UvqwIU zr_#58mMJuRNXJClr*mPn%8$MlMUyOEyQ%Eb+IKlflui+xn837a)RIu?Se7TKpzT3X z47j3%7U#s~e2?oR=oQbTJG8#7ghS6I9_~7=?s8~^%E$4#$w5~cB2Iye9C)0W$2s6O zH(g`gG0wb1vy&WliPz8ahvR%MM0AnaU*W}z{PPOqFYxb6Tq3zV=lS?3BQNv&%N%!> zgHE#74QgJb{(0gu|Gm!nSNP~W?JjbNxDT%Iv~bri^Tio{c!g*0aA^#?NAUeW7;$~;Siiu>ZMWRF&BvcJzGUJEzah)G{p#&sd7m%6EkR;$?=a^kjwE|JouFH$vp8` z@#k|2)SFYtnU@}MYYw+2@=c-29=cM*X=$8X#4lsn{FqS!!OLNX$m%k9E{;c@a#`pMCR{&&4W(-U)n^$!m!W$m9?46lF!sU4EaKF?K}e-R9H(Dd@694Dd`8M*ONO6&q{r7rqY%8`@rDTkJ1GVE3RyQu@2m~m z4z7@8w`5++_Fqpu(+fBuBUxR1*iJuVCDFWOjFdLY#Dk<1-Yp#*ZjARjxJMJ7y0~hJ z5^c;ggV;R|8Y&6pWJCNU2ayRZWwWLSxi-@OmY8CLCHl#^CuNK-PUynkR6S>s6;2uB zFJ0U+Rkmn9eOMZy$Q=H%>ik<1;%faY0m9^mM`q8`Uoh#>B@3KK3XV zZg5v@c0=zznB$Ef9T3nLAIM(?SKun$g4N_D6j8T~RGU7c{*7iV4JG8C?MI3~}R zhBpZHuF5AHY7g5Ww0J6g_wIWO0lm~{gLW}fuY#$tq9wjhG54S=ng}HAYz25HU{y5_$3_C zAxN99B9?5&DkEx&MCgViaE1aX`HaEaaAjI73WTSCq@)uM$M>UE$jC8inMbJ%rpp2F z@<)51`ffR6Rfx&j5x6u0p;Dm*1Q4Mv%_a^o%;fQMs|C$i)qm=02p_r0-m6z2B9i9mGr z$0k3xdSR+R9?I=?D6IP6=}7F6shVKJ`(UXg1$(0?K&ixKG%-gOzQa)46PNw5*AwG} zs?;6Fy|Bj(mj)|v_t^m`_C$*hE=dXPhsizhy+4jS;pbks?2dy{k&4+o6p}68GzlP%O5ar?3^v3Zau$E}%feK9I=>y*(7&b&1 z?W6jsYyNWp9Nl0n@$tfW@IiS$ybC~$tkK0I*$o>9p~5QIi&m`i=z14cg3cfoGC zN)9;UjWTz9JrrNsVfGM=az>yRth*snC`{6i4^%3G=RWXp!s&j{vBLv@jI~GMVDxfA zR&QjRDM`7^bKt?;8G45h(z!Kkh{Wrr*?%yojh z0j71u8Icw^!a%;t4hedYp`~O8x7Z@N3#=?K%@EzJ5#AL!@@NK;7_BmclfB9^6Bea> zhg?U@F@$WL&dXld5$)Re(E>@jYN`F14#wERSQ|@ZAZ(6bT`^u8`{m87gJ3uOr2$QA z{A#GEN*1Qr+YOUVF|9WmjB(NiKg**#0`;+4VveoQY^O98Cf$%}f=xXz+z5Y|Bi0aq zNVJ3@Zd&0w@QoQPb@7QIx@+RAP9}8nS1t5vp{2;ko0!~4gF2pRQfY3h#XBiB#s>ac z%QG*jRYG0yZM~pFnM$b}P)YkrdRDPZ9v|f^$oAz*jx6MyXUamgxrFC(8JNx9B0tMw ztK3oxn4H5Y1^hmT6P~M0O4Bn|mMJfoC_F!?WmGN)3U~CSnq6EFOWF%&$m-z**U1*9 zg{87YYvq$S)P2LI3T|nn?6v#W@uy;1R;yH$+0~q1$jLQ~E9F;}{I^gs#;YE)sEp?l z`Fjx$QCywKVfPeq1k#;O`-Ya|0tbMGB)y~+!Bxmj{*uJgue)?Z=l85&>Zt0SCwg_b9|{sy;Spzl?V zxyW9T3_i`JSNZ308rd#Ht|0FC)0-B6kUO_8JZEak2cYyPR~1 zBkw4|sw~hu5TuE}g&ZUx2e4h=`{3Dj(F*J_n zyen!c{LdZklvI(+YH$s?{d)-CP$Kq930C+p>W^lZz3v|UoV9*F>JfXt|>hGh@U-Ra2mf& z;j?s}kKyoix(b9mjnkr(VslyyeG+)D)_3J-w9JlHn}D2EZ{Q%(bp;K*{OWakd>bh+T|0G!QWr-(=w$7-&U+< zapQ`4uaawpBV9(9VlFJC=VKmvt}wPIO1UzdOJwbp!*Ath<*=nd8Pkg7^AgX_Vg-Gg z{zy@ST(dYXl@=Kc720_wM@DgPs$z~w-S|jU(5XBf$8SnmZzDPP zhI)y&+*ZJ!E4R5ng-&OAGL4I(xiX2}q`wgQ?ltaDX7V+5dC1mC^@f>qk*)Czzs=22 z^g7O;?(nO#{O%rKUgZ8*{vdIpF?2u4!blD~NvGSiKgHZ=?hvQL4URucUE%khRw<!%cojnGA^{L} zlmLiH*|bUGXRnku{O@P{_8~=?{8Cbrs#Kvqwpw+>Zgnh4<>-1^q=_eNc*BtedbL*JUqQ>vbMBt%;5DhgVPL%Px5R>%O8lut?DYjT8f+ZWw zw!=9mjFdQ)E|}a4nRW>B!a)zP2bT6gilpP&V~jWA-QnL`ZChS=p}#qHyW>||^z?$K z44phsXMqLX;qC}mH}sONpF6a>;+6vz%lg9|rCrqiWrYQLyWqMd;+^of>?OOQ(ExL- zp<{+RQ#c#pls)=eVX_mPWbt7QeFL1aQcaDmGX#FMt_PY;RRq#TiKeo~PCYDl$3jz7 zxZ|b?COV+Z97mk6wJZ8|!vZ^u>JAG>9CE-GN7TE+w+H@kL7pQbJkaTkkz#*yhps0~ zWi8$Z`()ibP(|CA`6zD2w|>g@=sp5Fyc84oYhH#1?a84`qXI zv>@ZnFay}xVVMqEU2#BybCWHbbOvs;zL`9j%rSj7Gd3{06{UUYg#jBwOeT z5yQuN`l|~&s}Dk)RSz|{JFm zsP2YhKSlY_3`ClzLS9?;RCMTX``{;un{me%gR!qCHhJN+lUfw|JE2Q|jI~9WV0$HQ z%n>Q_n|Q&d2e!LosEvBF2_`GpR;{<9Yki=T~z5Ud}I>4RW17JUZ6K)j{?*e$)@Fq{j6 zYaq5v#mx|SO~IVOcsw3chA5r(h7tJR6a;x9Yc}=|!r@8y)(4K^=-mr(VVErv&GC5A z6AP!{x9*rT4re`-+|jiU9*u%)FO?qU=74cyA!3I7(a0VMeL*S>!iXWr@j;m^VTF-C z0^xmN5e)kQ_`(+}1@t`{odeM@8g727(H1Q+?m1NywKkk;hSZG!>hNqDc@~f$$DNy4YzaE5)+WbX*<* z<5Bom81I6`9){Fl3=G1g(dubc!Kz>GH$t^bZT|RuEY=3%Q~;Kaz{XMdKSyU7R%O~n z;bqb(NP~(BqJrIuVt03Uck4LDjNLu9V>`Bpfr5e#4ZI%e!FBFih)-p5hoEqDqOoNI8#4=K~c_s*wz;)A4FB z$|s<+2+iZL+70^BGA(v-d5{BCE%1VoXgUfXM#FIoR*%7`acC_=_Xt&4EEQ?>$0?`! zyJ@QSHgyuhCScHbT$qI58JM;dVH5FwHXcvG{i*Prf%)UGYATvcLFFhIPgUK;D<@#V zd|(3ZjKG6&7&{4Pha*UmzXR0cl*X+PH>`KVh`yNA0XwAtsy8-uQ!VsCJ>b+vLDm*^ zMs-iDYpVu2>BEu9T12iZT@mB}Undov9^{OX_UPk`77kb^mAtJny*mbURf2d#Q!H(T zWe)hS9okE$R!222>vh6eX`F6@UF|TdJ6iRCSv#EUh;i*;&;u7csd;>qB$`Dnaz!oa z=V_~|hiT ztdzz|Dplb$+J$y>nQ7TL|zg!sA{PBq4MTf8yC zI|qyqFOAqy46)J)?PZ{|R6<+*Mkvt3I2Y(@;k!My=p()f>~+!63UNB>UU1bAt88#Z zS6x`V46s2TLp5;I9!K=?rZH@EFi{$cM7*=c2}>Mkf(&bRh(8Ejv`Lg#yqJW z60dkE^JQ@-QllOYl(SX?{3D(jQ`D-5L;AQUgSH_C)L&RyKm9##JvEKsC z4Ui;OuDZCPi>_i<*MYtk%0;mS&WkOlnw#rkBal}YcZ$`T(Yl(iMRqUbyE6LZ@}Q*2 z3YcHU>BamAh|YetjI(7s`v2_DTR;*()$)*%SzOBgDcoPB2IT(=)ydzXn!eKZ@QWT{ zJete&P!1G0V+eZ*6qBO;@JRT!+>KAe`R!1q_95MB>t!(TiW%vDi5 z;=|b~Jn7HqIIe$3<0MvprcErne&UiS27Y0fq*K3eN~k&!$=Ph`7oL?S;Q*FI@rF=% zg4skQj~|Mvh?-gEmsMhN{@&|2OsILqnp>2`+OpE3A6dw4SAFq=K%mwi0& zoF0dm_mGG8FzW%^?Bc}hG~LdfSNV7o{Vwy56&!VgZky?JmUGu}!3A1uhn^-!NlQ;6zTpDg>`w8s2k)E?SZ3}x$rv9I7 zJC#?ra?@1y+{o9{*kTuTC-Cu~yfBTw)^pi79^FjSX{@z@_h+(b6Q@mMx3zSi#qpb| zKbQMAaq3jg+`z+Axoa~U%%bgDPF={kYq@1M)7P@iWcsdD+}i`2ICc)Xi6&ziwT87P zan1&g8^J$UQ*$66uH%hCd@Z%i!W3T0(t*6NoRz(Jdoizer(~%q))U!O)c)I*i4O`Fb$t z&S$T2yu6tH{rP+ydrxNWBK{iB;#F)olXW(6@gzE|rSBY$`;*-lbNM!|S;28z*mRvD zXSpn+-+JaRq|Z9OU(6djnZ1I49pI1kyt|8K%Xvzk)jzpvJ1bXm-cD++<%a`wUBbV2 zGjFNlA7w5jg@(L@u8-ck2hf-rdJtwkqJ3Ys8!A`as z%a;e}GMUah*l`wX_R(TChaceHWpq2jkY${_n;y&Qxu4(Ga`#b&2}$`MYVKmg3taFQ zz1@q`N~1pX)MNUci#4;*CUP(q~TK*No&?4Zk5ZF6gtK7;2TE#q`SK^ z6+iQ3|7ga%;_(O`{lKJHX1-T-4MtztKb{AD_$`@^VKhzV$}g-*WN;w&3zaxRnTL-D zQzuRJDSgXfrL^?qa#oar3N=jQr3x12u&+eTQu#yxXCflk@L0C87!Ci$55ScYULpJE zia^A9d8!HdTRtKFpKNX<2WN3+2@j`mS3NWo8LKv~Cvj?-%11~>##)^A)f^%Y=Sr@P zRsoarH1;N!ix0Urmc+0bDgR|`9Yw|UsHRb_O31!WXO}vVtVc*ajFQ9zAco|JI?5KJ zrHR!gd{;-swd_RLD&kHdf)=r{J}yYIL&oSFHq%3FAsf}kq8v&QeN_Q7wDDHF)Aezx zgu`VR$)}7b8re!-mq9gJ6V*aJs}J%2_t!*r8VBj)ejZ_<@RUx*=qLO{4O|rCv>~#q z*jo#B!r`rtNfqp@hb=;LlZ0$O&9u~=H$xNKDrqh0Hleg@p-wsNjBo|8u8-5C=vh1J zD<7T6{Yx~^y*`2(;!qvj(!x+uK97^|vLQY}dGn;xPwMo0lEuatQ$igBXce))6~@;= z3v*nr;E1MpTEZ|3G$^K-o$?_MFoJ6aH=Cm}n}%XK%~p(fqawPQqs?z#(?oI(-)Z4w z292~awvfwoa3-4`wQ((t6~N6xHW0&MDbLozIk`pF#=An^t6@zE7uG^VC7o&*QNx$@ zaiWAh>tlB%57oxsg*;ggKS^;f+^=T01{hi!bL(MxEf^Z&rW9oxVvIcD1}LebzA?1w ztMt|$u_0NaUp?Gxh=0Y}WC=O0c-Y{&5p+!8qovfe)rP9GMavX@ZBcECUUJG3_JPFc ztktu0(_GP!BrUkyTFq;1?UC9XPWBku7zK@SvxzzxikW1jl{%prG(w8F1e>Y|q@5$q z3L#XKJ1e*gS=$K4);MH>`7-o1fP+027^@RtKLc!OikpV&k+d?ybz5aZo7x;>8o;W2=-7IpIuC zobI4PrcOetazlnQlHKsQEmC_U&JB@6(W)~>4T5_&WDG|)agdI{{DF8mNjYx^On^sk zY@G$cV~w7M7%3x~jdi2pHyy@f;WHC6N2AFMqz=cdsVWiNaWQUA#L|f8m*9EV$3f0Tdel1!r#@h9;Uxw86II#xDR^sPslWw-jusasIK9@(34?k@yx#lbD;xEVM8#EkXO+=4}$Fn$HX zSK+`KyjX#p4bWVL+gs3j6Mk<&@*ilj2~#%W`6k4z$Hxu$XC3OUK;cGcZp47?SiBBi zn~}B=R_n2EGurLKmd$v)0nIj|VkdN0BJodnuEoedFkuUF{>GZsxVaZ!H)GjW+*}Wb z9f;VBuG?{BD-5@zTprstL~TTaKjFO`&$r;d{0kdluo8}|uy{3|tU=r&lq`qCBFtK$ zct#OxU^Ex!*W%tH9A1Z@Nx&+kPKDuG%$jqt{^EEc9N5Rde9583FS!b|b3g z^L2=ui7nf3ax%Qv;O0`~uEh~?TyKH*L~uLqEkN(>I6fOox1wemj%-BHOw8GZsM+|s z1qDJ}+KFVzhX0KgbJ6AxjGhj^ZP+^>tN+5D>Co7OuqEiY9ZeQNdjn3cfbnXiE>geI zg~jS6Gc+?c5lKl7)f-XiQ<1oKTeI|W0R`|#|mMTuTglNpk=r{471iM3;mu|Xg3~9R-@x6=&VNHsp{)@O;kO` zQ%53jF(QXykp{{Pj@)1}aR9{!x8{w{4sW8ECQoQ2KHp*apO<|AF?doj0< zMd?hGjm5B;csT;+Cc|3rSQ9Z~94cm`$8gn4HcAZqBXM+~!U??-lmAHkH53`6ak?9l zWwGO`va15hsn-h|yWqO;fI48TIAA3W(GO{D@ozsRqs!7`TX(e-YSmrI%@LA?7r4*= z@!}%dy7q@|dvxiK4?W>93cEWfrn!a`4i8e|{>(vG*#V`aRhkC!6WgO+f9&avE@N=I z9kPbOwhK!7C{EeULAWgD|B=|&6-5$==%#={cRQ;^kbXCe9)JryaA^d-cR|PgSk)f$ zhhcUbg!M&GR|Otw(Gs=YVAxLO0#=BeEv>>X@aqj<2W;<#L(No+a_eTwwD3$Sg4>{* z6bL)xT@z?`#d=#D5gdT6TD!^TdmZsnk~qzfV5eHncG*L>1^f&#S8Vp;O|`>wQ)Jpg z%#g-5c(0FU@+~F^wZc;Iw438!J%pMm>&s6wyf#FL6&!RFIVeb9<=MCEVU`){X6MJ5Su9ry!Ib#b*e9vk3wJr$*om4GL?o%Ghg zX({WdjlSiKs;k_6_o_JLH^oBpy@pS#RiWjyLdtRFK|Zgf^K&63DI8eB#To3I#eJbn z&EnuB?#NWJKCMKq2vvTn3H}@r%fp}4Fq;(2z&H+j$F)L<4Q59XUjjKgoZg=)5#Zua zoE*-lLa_ z&q$-@TaJFg+*iE#oO|5q@=D3RS8nmjeeV62Sr<9zjuLa{pQFQ7jy%pGS9$UnZ7(qE z64zg%|0!;}#4Bfc^cqK>;^qt7agfF5X?~oquJOTfy4>USbNt}WC;#w|r*u8fAurkb z8k;}m>AP(1MLuAXH=Etz)^FT)hnu`rEs~$O2L%=6&pl7r?VHl9wLftGOE&td3WAyk zQb*cZMHPC1=D$?_!#rQM zaA&U%T=RgxJ^Awq?LX4!6{AJD_TT_-c6mlSKbqa*sMoB1rgW&Y&pGv@@-)iALB^0X z{%qn-`(XOH(=LpIqz5>ZTV69XoQ;HO9zs6mr*P#4jE_>LN0EbF-!MyF57HZ!#vbq3 zDvFUG7?i>UKV=EHEX`Ch!UV8`Fg|>FA(^rM?3TtqK5}b@LPE<((&Ia;)0p^)F@-8& zDpJw&@60XdhcM2l;>jPXr+Px1I+_lNU|tQgB3W9*_p!WR&M}f`kl;ongDaKJxJnvb z;@PB1iMi7H(kY53ig+}V4s~!bj$iAcRV=5}Lux#2^64ZoTMbA`-L9Np;+a%Vg9J(^ zOhSsvu6S ze{F7nrupotjbN#+6?#Y#=hkpzp2}z-QI#x7?QMc|5=!JegO6k=%jfST_LhMzlW(%w zNw}*i+!LpA#NU%RCY~7)e3QbuF$#B8kx0J``X;OP;2VkDlS$o3E-9pKA~P!(6UwX- z^+%sk&R6p6N#kxPub1(>vNoM$(aSlnRk)$qcPjySQ$Z z^vdLA$xeoGaV4XEvTGGH6Bu00!3p#$r)fOx%V{qGq?*_oyF#6SSz6U z+9*z99c@UzVp}6DPU1QZbj##%LsS&2|NdQ^@K(xQpJ)ijJRWZVpKMC}q(>_M(M8lR zY8$HI(N_lx3;3U89!q#r7mM>L*YMuOjFOVBVvdmvX)#^v<7_c|=tHNN3-q8@%KDnv zOWNyUe}LH zOY(%6;Z_A#n5zcY+ZNEQ;_*gUAw3~h_+HK))(9!%$R^51lxB}pWIt25)kl&YlH_L5 z7$0gV+vyuMd~Ac0n%H26qqSh$4F2_S-4Rm-LnC<#1I%cSaziy12?Zuz$dVGaYK^+O z@E29c2q#-2$^fTZDVuG`}0tOwi92 zkp_tEjPIss(F1o4aJDDv3rJ-s4#;;2c*R=Pla4gUI5*T7qfEed(gY%KSStn8vzGdo zKGJsv!_j!rP{}>}q%vg~x>#Y|P}H$PkSp9}%iR}=qR9@#MH$D2Aw^;igVjfIW9~FZ z=OL)l!z;leh@{&amL~9Z!%|%w>x(_QFzJa*T{P^269$+jvY-%fT-5L0vJ=wlAX9(~ zR(RYATC#KKj1mK^alvN!-P@w68KOJjg)x>p}tS`gmrWDYk)JY(Ax_3PMBhdYa&PLAhqpF^hbGJ%pd-Z~ zcKBQuwe7Lz|4uodx|nYdd7Gy-K~xnTtl(7#&UV;Z58rIiy*920Tcuqns-7=J!E!7BCy>B<+T(c;*CJJ zIzz&>a~<#$80MsYu0%DLm-CJ=9f~=wHJmG`BesD;wy?Wiz2rc%8J_46q&23bn@ z>cg;{Ka8*|Pj%^cmS#K)>@MXFZN$}ri3tKFHzYcB1rM5Ij}~Uisjn`YTf(7=W~Ok} zN3|8C@oc!I!e9+GQt+wHO;PllY=l)+j1%3elJT;Fs9=dR)>U$RE7U6GV+RZ>q6o)w zyD4>n&Tr~CLT*E)t+7D%bPSeF*-rg$Ymx5!7{>KvkSkJqB8>Q8pfZx?s@+7`0J7 zTAjM8&Z2v574dm#X9Nzz+YUHC1bL!MjzEY+vHGG*E10_?x;gH5$8!fYJ7_fhKOfvl zX_13lsFYBkDVny&I!BCl!`H?**;B1+_V<8}1uh7s#Tq8PF-CfZd#G#RK3BC|I@=%9 zOmW=}t%XxL1dU|}H3Uu;xHJ^OW@ytNLd%*p3K|ke6_~H3qGR`M2wj=B%yGCcnR8K>>>S*R#>INb$D&6Q7Mzb#^f)YAkfq@uYo z9K?n#<^-`o*q}i-6(x>ri(E(L7Fg^E?Y78kj(MFB-W1JRp;KerX$!p;_*d9Wwy6<3%JRuO2X_m$aca{bKGl!G9z4WiN|K@4+~tX|Dh)_QGMY!?Vul*b=MTV5>bYi&wb?Hg&*k z+5XALra0bN@ybVZR>qjI;*My6KE3d#9SY?7EH%+xkkbsKdP84$qpsL&gJV7L&_)T? z&FxU$5p_+FDMVVKuDf8h4f;Fb9}5-s9N9=&gBsglsS_;4++wK;%KnjuZKGbs5=_pr z#A;huNy&pLV&vx76bl;SY-9L{2c|Ku=&RC$Px@GAsshpR4Ph${Hkzsh!bKPQR0jjm zRZnXmPZGhE^sZod4Yfq~tY%UfC&@y)jE>c`l`4-?&MD1>nDl1$D|X0WsyrEqW#Uu3es za9)x*FNM0PtSMrACSwxVHlI5ZI6a0F!#P?!nQ_caVqb5)So29uE_3~qDrzLTAulHT zC@@EwbW^`!TWNFhpueYrdQ`mOO%FwK@ph-a51nL4e90A0+3_`P?{SJhv+wh(A3YvX z{|i&3v(%669`fQRmA#T?Y&{Q}`18~YuJ&U78ybI9wZ?A0GT>P1j{AumSw%?SAw~;^BdUJmeKl<>?XVr}}B$&A$sr7}&UUE?=f4<_*531Ex zGD<^VG1H$XUT{<(-#(|s2mbqnQ6ChJVZsO1VcYyY7vE&34?HG)#h%*IqpQly|&1@d@#g!v!1hf|-w)_=?&0_{D=>0xOXe*bAC?andstZF~5h zTVK)i75l$s^gG(iMD~e$KQjIe{eqOM(8G^<0?rVFUw{hDX?k(%S6-2DRxtfPa#Ap( ze0VF8`#s~{{ZWrTmoKm0iD5p{jo{}$8U6Zd(; zhlbaw8^r3z9Q}dUo~jAg@&-qIW$PDjXZ!Ng z1%7$Y@i!Rc$>&%3{0(0nXUkXo;|kZk~?c=8V9JpQ4Wb_Zv=`mOT#pNC}J4Dy}{P!SNdT{({>c8W?v%L3` z6Hid%74IKsi8pO7v&xsh{-xGyE<8swFP^!?cD^jS&H{<}-JzW)D{r&CFZbMKqxbCm zRH061K2`6pnrHm@LGfF~^uFsMt-f>p3wj1Al#KX?KMI896K_3Y(=T*#XUq?_eL}Mc z#<(*)n0ucyD2%ZlD(|qugLlQw@sh6bd@Qf$L|%EK9OE}$&?tp-U$Y>YpC8j9hGvgB zPUx{-%#K!#@x5}S9gN?_F8-XZSqu=jzsQv0VV3LO8yfv0-zr)2-W!#?TP7PAiB9nxI&Zvu>Lb=k0w@AsF;FU<(i^}+KC!mKP6yI!lB*iQ$zvi+A(9GbD2C$Cj0~4H0 zRGdJWE;~fCsU;G`iqi59TEsWjD3;x6bDS$@OX*gU3eDzdS`X%J zP$t5t3wA?!P5r8v-dV+V^t<4(G^h-~A6n=vHbrgZ3W8G`dOek6*}fZI)Q0{*Jg zT_7EIav<4TR~0_As0Hs1@Rc&~E_fm50T)axp@u8Wa~RkL$l{oeimQ9B4eq6?$Iw8i zG0hO2%t`hLj;2hM{Ufu@e+-d=%C{B@|7)>b^F_+blWbq;?A=B<(xlIRVfefgN1K*jf zi@*TxtBX#O!4V7bTRxG>nhy-AVW=N#S5VKBz00WY&1KS7Eh&cDNb}{wDr$Y?dGRXv z@?x1vuWJYdB#1+WEFYwr(8hn|`C6D3&F5u29mVsqpN~**y;aFPp@;EVyxR~tznCQ% z(mcAEVwUty+aR!*Lz-Ywg{qlNuj0fO@Tlac0+{?`nKzDVk0U}udL166a{n(?Z4mxB=}faZaam&%%71;+G4j|R~0qht;d zuO}MgOn+RHMwb!TVUL-Uu-pbtW8mzFW)o551lw_{L#fV03~r6%bFsS}#?8hkiBC>O zRu^<$g15b~U>OXD;_e1zitf5vVR7nhR+HM2jbMMY*o7uzF>MzbjX>@Wbe4y`4cdL- zxeKR;V%Fa{ITRPSsmNsX9;_RP)1v?O$3I&Yr_yRGPIN%#24%1xw+S6Pqrn-+WypN*{!XfYpU&5=3<-7TNv8v zQsTF1G;=|xWKMKcP4YvVAuN*pnqhtvJIJ&c!5i{Y2~k&=zyyA5geH-^+ZZ}O=w*+N z!ITN~Lp;wnherap+hLF}(aez@%U}!04XB$f=1Le))|j!B{gUjEr`h0U5?5HjM;5SF z`1On8(CCuGcv)cP^0>@{MQkUP&bb_AgyX*{0nF=FtZj(}r934&oP0)G;Zw09S#OZr zu{A2nDLq#cesQI>VuJUTFlH`$G{OkU#Y-biJo^dwzD5RBDSpbG$YV`Eg%;=)U5?IuMP?)d1BmR0Zx#LB&b= z(o-cRtbNKSl?tUN#-6&bXj#C`uPGbg!OvMx#MZBAQoxI^)wx2>Co5$Zdq=AxZhOn? z!srnOeJb-_(ln2|yjhZ=3RI7$a)UQdWvjYTiD&wFFf5;=eCZ>Wp?4f5)rfC+uYmof z4mX=A@7XVpw?Fbjf$F9xmO{(d6tm43!O|75w?Jxs(OBRtxg7eG5!vdX>n~gAXS`CP zIvI2`>GACU6{D{hFFW>^e4ECGk7-mwE1`I#DLRI>;M!lR3DHOpbwyk*02&!8-}6x> zZ+xWdZ}xh}wz94INVyLjl?Yo2i$Yktll*%r zC$rR%yL%B^1@l@iR|N62y->Z9I^QQ6q#%Pm2)-XV6XFO&K&c#2j(xS)yJ6+iAiji6^ub z8{(@TF3YJ^2kvr!6c@KJ=IX*WK?zmsQ+TKzq{&uC+$dRA~j4C~~wgYYW_tRPQ#35SGna|IhoM@J`{g!yoBgp$8^1kvsjn|)ENmc`%s`!jPtGyD_1zAMsJz8qJARO|BN z0G5Way__q8*!71xfd_nNtPq6)*dvB=%~_qGLYe{b+!e%S;i{*lc?g&KQ#XYUf!r9+ zDZ=fNqLKi1NoGVKy+mYx%R%AfJ6Z(u(p#2(Q3%es5T?GQ^%tId!@zI+_>46&4ZYwF z;SzePI+22>43NXgWA>GJ?^{L&P}h_Cer)=Nx$o8NF!2M2dolDQn|@-HKZE=g32Sl? z$9?4XPkiy73qq9Cdqb*wTcs>a<>$$XZ~IZ2dcuC&{&mm1zQ)=Oh7JX1iY82%LZrWhX5=n%)l zd0Z{j$ZYkOa?hn}8h7T=DozbGL2;Z>$jd*~%R4NI4{F#TMlI;R2~|q0uu=4op(cq- zq)shKsiLttj4V}~x9O#AWl?;uNk;VtyhgCDI{{a=IQCu5|XbGC!vA zb-a4B%!pH(1j_2}hj>+Yt-~2C& zJ|bfNqFFhw$k!Aqfawmof#y*tFuw5|oJ&u65=uBWh0n6sB7^CL>JpTh!{t%*%jKRV zZpx!;5+KIj~3D_nJs^-*Q&5-j>NEQIR)!eQ>tR)a#Jo#V&B>b zN#V~*H8uOnN<5v~b+90rj{te7y(<_k7rIJ5Dpd{Y&%|0>!Ju@mEoVi6B50qMeL^LB zW^iI5JIYL5%?&ABT}b0BeitcSn0F=oE0y&`K2G4d5;lotgWtRu&#PrD&tQK+RK&7z z1xv;4P{gIlTvN!TNLGt4_XksQxGR)x^VA#ADVr|AT$;~~5$f_Q0T%hk<^3xT0k04m z%JMdXUou!2rm$A>3K3`TlP`Rg!70*So});A?ekgrlOiE47qDqLYsa&84Q2Q;08GO; zRa(&F=vEKOF$^nJ&?T!H{)*%0G7gEOkG%WhxK(;7WwV#YLfK2_vtfgpO*ah#nFI`&`O02h1*GgGLCgV2WT_r1e^q zO%2s&5-wQw&JbL?qpQMPj+cs8J=hM$5_8P#i{oZ!J{k}7v2Y~pEnp!Hljd-qio&Ld z6FXuvpidLAh1QYEsV4e!zVl}Qw_-h%WS}IHD{8pH>0>_-uaSiUeAY>h? zT#zvvby}l*9%edX`y4EFz_S^6;iQs-$xi4z9?R{~VZ8ewuzG%|sgE54g649!$)#7G>tfznTR8K9uMLb@#Li{kq5>aN;X77c{t z#Y($DPi$;mVW9<=Zg6UdR^mT2#FTz$Bcsp&+-rc4VHj?RH=_|_st`O<8#`hUrWh!u z#(q=m8i7WJ_^Tge58ymp)j>}jj5F3?PefYaj+74zqQVVYCUEG6S7un#4_?~H=!Ah{ zy66H!W4Lufr4F*%swNh;!D~6yI6*K6ADv++&|4?e7Qlq0dh08L-vKSfPsyl*Sw?w-&DoYr$3Mbn_e;tOl z#jp!*bpv_8%-1R5wcZJPPG;D_pe;}bVHttguLmGb|s3W%gjh_;> zJ&ePyxc4`V`e5cEoazSO{c!6F-|euFlAph@Qc6A#VYMr^?Z@>_=(`_hyCMAq)(^tL zqv$vYXO1G#6}pFUV+bA{LH00=KBl0$hfko_Xf!(klaX*Zrqa#N&tTtVJUfr!b6|BI zyC&h|ajcq)78h`Q3XIReeHPCCgMa5@-c>xAhV7TpXeIJ*A%7Ms&Z5pTT)BXL;t;-! zgn6jE3Zn)1;}(n;cudEX-FP|? zZu0p|G(U)}u~@SM;S;fG2kMQ*vh6S$i;oAfXdLYJA#FJF_o3M&JlLZESW$;CWdf`Y z;_*N%+lPp;ICu~_BVhM8+6=+pdog_`ZXZ;ul7@Tnehh3+z;_IC_v6O|l>G%0!3ytE zg8S87SUe8HcA>2Rl>bE0XiV9L-cz8n6+vTgYXhQZVA~e;*j8=Cf3S4{O#4J>{g6~x1bcDq?gm%WC zLt!i3+LLh28EKNLZjH*JsA#MBKKTx?8VzeltQ&!??J;_cN*_z$UDFZA#^E1lcu&AG z2^UX*y$dp@;%Y~@&qR;T7&Aq|wtmjQp?26f5uRwOjK`7cZT~A z9Bc`@K{zW{Z|Nd#iRptd)DhkTRsUFJf7se1qc@s2LUDKe6hd(q*Pvu`)*cG+xu(~gnG{Kk7SZ9wq(qY>QuUyf$38FiyJ5F#1SUTZFJB)7u&GuN| zS}n|TUGS?3#%riBrLX3$X0tG3#hW2kDw z=Qlw6GIrO;V~K|8;y^W1>MBmeD%sYS@`@mD%4sFTQx%{7rhXN3aw*1`{2T`TrhTE3 zS7f5BUk|%8`A3P;dK}7lAx$pCjL4*;d`xFvIol_4v}D<2>I4qu@GD^ciy!O4{Wl-$ zC{L!?kc8$b4?~tzQQEjv#WW!mg7Nf^*ud ziSzZ)vJRd|EruS38KIptcx&Krl>+fJtK^nixLLxTm9(p5hkA%DS7l$`CG04!@87f* zQdj|BV+RrD;5rvlCR6>*7>8if=iS7GJq6gSUd!m>|RNkaWuN z$yv}OF>EO_b)cH6`pUeP!Kq<1NmiI4cX61@keg0(f!e3?udk}<>&#c?#4}gWz0v>{ zNaJuG^ycSy`pc~SodR8Y`HlU3x#&B0iJU5I8c((l=JYq*^_|bWX)8fRFZT1}y8Fxw zpr*M03zF=)Bq7gk;ct+3Z=*xqzIq)qVy*cC?pTA|?8#RMlyr-6Y%UebW#Z~On zQq|?lke4iwj;yDuam)4{hX>H*4V!*sx91%2meZbbtRJ)P@#9FH^*L9^|N-DxX7JDPO-KpdtKqPr#yR#DZ&vx!J#jC_9QhP@br16 z-r>yCTymE-=XmWpi_h`+EykYZ8i6ApXX~rV@qYAQt~<`Y|Iqs|N1b5BL4~63aDqoq z@#`TzI?tRFYrxNGCy45nJbLA%$Apx z!v5wmC*0)8E404B@EdG@i(a?sd7B^aG3*A9Jml27Ja~(acUVv0*Y`O8k*bOnr+UC+ z?tV%0M=ZautP6!tdHoG{KIEO(^zx*;AKyIZU*6R85a44H_f+!0Z#L3GSw6$-Vu`R0YvDsGSBcX*j~{iQEc6=K zlE?U37+pZCddMx{j(Rv;%tmAb36N?bMSP6f(5T`OU98bSYpH(}x1=mHYdBR0y#O;~ zj21?%&=u=rrXf6qG0{}Hk()PHnVLHGxN8jEW|(WF6d9w27}*qshIrHpd19w;gOUbV zBS1`h9F)1t1h%5rG{m#6s1UqGd$iQWidGn}1DDn~s0kxy*y*9EBSdN6U;{DgPZUB# zEkv1OJ*i=Vm|D;?$8AY|7-GDXQ;Dssl&1}`rLMzit93C|>JW`l zS2`Ol;8;RkOSp)MOKgzUs*_)ySTlKS;`DaH`%1QLi&bTu;(#OdF`^A}fHv(EYom21 z80cb1N9EuCEj27cr0s)^+Hh$P*(yhO#R>zA=m`sBT$WBAQkM{6p6Hh zy)n|9vAn)Ibv)F@f%f>VfoARCq>cG4v8O(yKVQ1dO}fCu2)Z)YXuzz4azvl$imife z>I!2qwD*RO9=7*Jh%U1FtIDI#L-4``@q;n2i6TFCvsXvcK2j1T-cBbpoq^eoxHTOE zo5OjUGW!KA!?|uMh5EfK;uoq1uy#JqbVT7Y9PbXhwdm6u*2{5Qnt#^9t2h2yj4=W- zScPXjP`n1|uE-NyY!9qmj#E9cdLcABVcA4n>Wql#SkoEDCgXtMY-VC(C%m4fir>#q zfS;psRyS&b{et3cjX`~(-wJbwL$?WL4}?!M+#ZXba{d_(cY&V{hG#Q`OEr_Vl0IKG zMM7VUw@1lX9FpkqAbb({$Y@pJGI#=ZIN|mL9Fp#uN$UKwdz4}TmCjMIwG(quTa2AE zF~1Y)&qan1e5PTh8y3%lo+N+gqe!&WIZDIzTZXM&aC{aPN#)TZJnfHma}*-;!Yr7& z;^`tR>wz9qVL1>dr=fi}m`+7tZv;()M@Nff!Pq%`gPk4)g917YLtYU)LWhO;(Owhbm|J1wk78GN3I3>NWrWvvO3_775qBk zvl$k)#|2ANwTC!2OxxjTLo9T`8eL3l4o`D6gjxw!sX1Kg7C?weOpCwAm*~A?C zfUy?vucQPVy8q?`TimXNG;4gQjlp(kSHt{wNR@emes>U zOLaaBlq%viAoJ3=QR+8ksVO`$42gphWWzf1tc}@K_peLYAV4B!X>*93*2Lkhd(Y-ESloFbVDxy(c%q?eZ zee5l!oZjVEYbSYssbY{r`~MHL+p^hO1NF<9B%-RIIe$~DfXPMlDdO1*&Ji&;o!hfm zozC83?8)Xbsgg+HOu6gH@iLRklUb6@E@_NTqP8eaF>IH}f&}(SVML-TGwc(=(@A8! zDhur{Vsr}Aq;I5MiKlsqUM6v;JT}Z{R4N56 zVVlEQWo#r%V6nkeP+SL1WmPMHq*DI=&ERs5tApJ|9Q>OD1qbB|BooA%Q-TOT?^?bbo)%!r0_!y zZ^rXpIu|D@4Mk*#yGgYA$-sEJg>y}k>T#+U%1fb~A43CKm4`FHo28Nb^pz_=^S&Q{ zg{c(e#!&8g%PWEm_{#Ai{KsE4+>U#vpctj^I3a`;ekuWXTKaoqcuY*Z5lZQk_noMI zO$15sgY{xnMe4>FWfiuIP}A9g7*4b9#L`;KhHvnDv6o z9;+^$=Fj=hGq!ui2~W8GDF-}MNBz$?7-4m8QWh-~4-J`L1 zIBzR!_ra&+bN2R7k=Tvy>f_y)9Qjrmo(p9pe8r=mdD~k}0hNBdEFZtHFq9`hs!+3h zf#{fPzVcI)N+pZwalY8z!q_8_vGLp##EZh{jAGVLwvxd?MuQ-(7O3ubMt$Q$F&Tz( zS`f2?)L*tiC`|*^vn_u0NAe_us%qJka4wf;TNte0c_~;CQoO~G7S606Tqgd;pA?~C zWSBCyumArSN5yh(jHMBg>a|gtz-OWCB(jTmw&S>5I4OyoF9GdvuJYsgNbZbadJrFp<2p!@T&e@P zD@qO5mqU44Uc(|i`*Za-ZuDbf7&l2laS(ld)&HvH&st(udBrwj((qwt9~Qk;?L#S_ z`DXxsNki;srhHYl@T33Z=&a+ay#FYE=oWum# zCg0+}ce!5F@axo$rNv$KDfkl0-H+7XtyK!+K2iKfZ-EHrl=n0Baiv>3kIg~VX{)aKczDDh4RK%zhKj3 zK1^r*L!M6NnMcZ_;x4_n&sAz**)!&)@L?v+UvP@Fv81seonG=#$@ENP`xmN1CtEHi zVpK?{!($$l_wGKcQ#mG%T2IuA^33GMWNyu%ST5y+S)WSr#CksApj=g(8-GF(Q`$HmlJ097hcX#i1m))c) zrATGQCl&I}7dFV{Rk^1N@mMOrB>7v$UC-4{xoy50f8}PeX9+Kh?k@u|fnSyITrRUD z4wK0>xtyQD1mTcpbN&aG%9222XqkN#(^mSa3%E<*3DVXrhU6mdl(h0Ib=7VDp4K^B zS;ReA{30d?DSUayTiJ{*WQbHOec{MV`isV$#noSVUTTcW)E#`mXS%*+8`)I8W>zWR zii-V3LGl}k)+rjdsK$~I|3QZmZms3`B95)(PoKH6mePfNLI<6sq*WK`pE*zqF>))H zJ81=_y|l|$>Kmc&S1y&xD%tYuL;iG;E^dF}08Qw9WVI#^eWvuS%=t>GM{M#*O(0)< zrgjwfTO%Wfq+BjZ+iN>Wf*$#oKkEThX0<`*&c6SbtFtb%jD@^T@icWiVC z+kNBwO8S&>Y&~PY(6NNSR#19l_f#`j12^jFE>J1Ct!pTZ)mS}fYNE~r4YYCD5~d>N zTB~wNzXouyR8^xy0fTpIfY=YrU@lHCwM3rlze58^l z8zNFyQ)QrC?4(*s4>~|Y^0{ts5hkrns#~fmnMp07(Fhy8FuMVMZ3zQA=t~OBPHofN zt>NT_IH`|pfrMDT*H7kYW%oDVum<)|yt{P34A*7;+Sw9K?q=uv4@ zk?>uYwkVRmk08ABLvA1<+F?U?Soy=gD_*yTM<}NIVr*B8>Hyt7ss`n4Z>0%-?GGt?BKJ+)zlHa8M6Kcq?wq&jHZyfx(jW?2HY5xY`e$ zJkYxn9{ZztUkE4kT#y3)j_wI9KWGh7q_^%IM zh2nL0bm@adA-ENar=d902a9{)ODOjCLg#@93`NdBI1Gi|0HpQ7SW$NR!?Q0s2f<0q z(tR*}2#kk7uMdKy8gdYvhT-oq_}Ux0h9bTntOmoXKlFxU#1M?0hO|MrI0l;s;OHRq z7>6q(5Hb{FCScz<^qz(}!_aUR`VE8SY_u7Mi0Me3jEQp*D`e&c(3$}6CHOi9vwsFg zcrisOcWZ`X>tytr zhMz}a=mc0z#_HJ^HW7O!D?Zrk>F^&5``PfCg#Tv4W;{;J#1VNpKV#86nEishad`R@ z9Ohy2N_1EZ%jGz-5LxRm;wOy!4IWF;Y%Mx1K)2P{vlxZH;mArXT!#B=Q6W65-!Xor zqGo+q4$Tdiyc%IEF?5}xT4ntPyR{g(7M4r#WEC7%;LlaCU51Hkkh~NV*1&ohHf}(p zU(jzEHm$|DRhY9B8p}{G1D};Ry9!)_*o7!ugsio&S&r!|pt%fF*WkZZ*!C-umZHlt zTw8?0zruVOZZAg2Tr~R)4OhZ{DdK)b$ZAD}TJRepf5rJV$o?HIR^ikNd{~VQs}a2t z+t#6EF&eFb**c{Bfqz$`(I5D*7Ol6U$Di>23w7&Jw+RXBaBn+wS77lb=&ghIf2iJ! z=KB$`1)cZ7WjibmAYTOZqiFvxUL1tcKC}!+_i zj0bzr>tD<{fRgRlx*HR=;?h4b-G-;z(04O>?#7$H@Ol@T|Avj5v1B8T|B1nWC;|G_ zDhytOOTVM(MvU2jVM}pmnPRUcuEWN47`GIsmf`AryWe`S=LUuoBk5gBYizBgRAQlY3#je;h0Ai2N>w^{@RCwGn1o!&DScnHb z)Le8(cii;GumNb-b0oWt}^Iq`i0>>VB(*be4R4?|a5P14SYOkw& zaU%dv-LXM_SaRa+@VW(NbwsoqBK>f>siIhaw8Ld726a@|%*H~$_g8m{wk>hf9yVTh z;0(u>=qpm7;h-`@)=J1foq$#ciV3atQTEa?9$W8IP zmYSnZk?@O$8rybjfv$$w=7B9x-B{5;jXl8PhHl;JWUDx{AVwiR%r4w@Dz=BHmV_tdE=)*gA1`D~+) z5|JnBI7kYEY8myKzi2}y9)2=T5yNM>YGbLapk)prv%XBu62o&QFBK@jvbU^%o-@3F z-yX7K4!b;JKpx`~Rgk%10?+2F)T-%g9(}~L&EbUW?DCmCBycJo z*Bd`}lL(Y)}H+itTcm-#W=E$QiaHZA75M_lzmbyoiIiK`wfH~Tp0 z<|yQ8*}&$ri|pfaX`aL@1#}Z{Z8n>w@w1rKpE61ioiF%n4&TTgGm~x8>7B!+FKL*~ z1)0pu=B#vOzwh>x4%wXZjF|%LddBavpUvd`9Bxiy7um5&zfTr-#WO93M<3EUgHICq zE{8D>=$Xp6yJ}c*BbHmz)IL#SjJqP4mCB}<7$UjgGn|`D!;6f0$kekOAbZl2Jo$hl z!k8yp#Uso}V&qZ&lfue_EWJzZa1Kf4+c4^-@mM%(61gveL5Y;uskC_}USw#hs^*+2 zbCqi>e8sG2Zp>!!T?VJAHkqT@G*99FH|#6#-3LaeahnwPq%l}h49QIX#6i#amv~1r z7$cU*cf43mw+!C?tQPZ2D;b|FWo-7GMb*j%Y+Aw1 z(qmG}g>l>22n%iYZd4lm-Y;l_B zrL*QB8;Ym;99zb7-vJItQ)=(`r?fak_XPI*Pt9z*{--k6-n&>D$Dj5Rw;8vO8>A}e z0EgdWxBawV5ca*yxa@rn#NTa2w#_7Cwgz?GD*v;M&XWOodS{m=+-_mQjQ{lhb z|IOt$IrVQ2jN_fZ8Fzy&n^=0CkJhW1K>Su(U#Hc2c9cd@0YqQt`wjejlOs3LU4CYx z`rXj=)Q{xwm0WO()*Bgqp8u?3`8hgmpzBQ<{lQb$*mW~AFVS*4k6mKSKU@{V?^|gQ z&u)kLI)-8UIsXPH9aGNsvM@&6;$J6Kj`+rLwtJ|K>WRB5A^!JMb~;DRH13Sz(o}Z7 ztR&jTQLN2o@OeHJv$WK5r8E7KnsG_JY0NtXF}sz?u~FReiqYrkDm_FIT=Sask$jxP zvUAGInsl1tFHMM`V+t+8nJWZ?<2?U@)5F!M`RiH!knA2azZFQqZ>496zZG>q#X@y^Q@K&g;di%QG+ag^iZXdlJ@ z?(^TXoc4e<;q(+H_9@;@U`81Kk+gUu*TnHd1ikLC>?B_#a^7ine#ovTS#g~XCun|` zOOGly$m3%i7fbU4TouRsgZwRtKKuAbJWuT8_4_=3jF01ZbRSnF^29NQCa7$_Ln3`o z&`}ci2l?P0PoChwBu+R)t3-Z2z#TGyIi-r3bdT^(0v{fx{UdrF<%9$dJk4RT92dsK zSO$dieG31+#AQj0I?M7zR$k@JBpy4*J5L#KP7xG8oTbNOPC3o=RJOTD1F^~+;~z3$ zj8Jx+USWKnz^wBe|BT)d^nA({XW01(bx&}?Glf7rBU9ybjC;yQr&*c7pDs|QG$|MP zO`2q**iWvOSNLx>C&bV#msZi-ox{noY@I{71o({HAHD-A@{F9~4qc;^ze_mC)e} zS7uSdN`l}kEaDPjKb9zmLv|r+3h7@=D`|Wy;jRKst>C#&99YJ~#XSC%k?(ls8zrCE zN~RDW==_zjdFrc-%B_m|{xjQt=aoE8m*`WTg3d`i#I=OoC(;kWl3UCPxT z>0hqkCp$$&ddCkHoGp34QXc$B?+Rvr;u6yTJC{^*V=0eSa@kip|KQXTX4SE@f{!$C z=Lhd=!>oog#T#73gZjv<;#V;Z7k@{|)e265sl& zT**S3h^=v3A5F}0Mi=AEFx3DSR(Mj)lR~c3!$Lh&h^<0|S`Ew+h<6q(m3f$Vp6eREI z<5zuUpZG~It&)AN;}&D+>LJJqwj3t;b&IU(xal#Bu>S!iFIWv4R!+a4> zC5fO7eI2Ybz&vABk~LXMPEGMm8$)bhuZ1DTxT}RF=2)hKefp62p`1Sl$icd3rHKxD z@U5noK04QMzP4(J{vt!RY6bIj%D(8*YTVPeDz$dtNNhD{qjmALSfZb zt2u4D7A6S%R+58awh>p45xi??YmR;O%+bfA8a6S;@8SZIwrCCPGQdx=5;KOGE;d=C zuLg#j;)Vfw%Rb0Z?VGO42h9i(`f!$EpcV@CRZKoj7fS?|UQCZf?BV6X;qwD4CQyBT4+91RI;)GJz}%ufH%$E^yk z0e-KihbHDrz()t&e=tuB3H5BEi|Tr=)5i2V%4b%dReODe)~OJsJi-b+xM-oNA&!vk z>o`ZIprj-Mg0)*LoPUcUF|0z2D4jo8w zLuEaMVk()Skk8c7!h`oLt7XTpOseDVV!@QsvY0j1JoA+`fN07;X`p$f%G}NU!PE6h z9B)?6DHYry*{g5#E91s*9RHmX#T_X)&{Abi@Rvb!0rysL%6sm}XT&FUVNc0r-Y3Qv zvEVf~$zrUK<7LbCM#TmlU#q_Ot2vx6h^j2E%w*vk7G!bDTNdZ?S6K(HNiqYje*;NBx+URVAWflChUY$z^#kBT~ze?Iz8Wrm}x0;ES z6tCJ)4a}%!fCg-({k5qjPE)M_;yzpy{z$v7Um0i74T_*&mwjhAXMBz20~IqyeV2$aHKYF zRWb~CCpjPuY%AeXx!}lWt(yMTbkRg`HNVuWK&ZLgS<0Cv(Q*x#X)16*3u*T#rQCC$ z)i75V)8yy%@T8Xd=19>(D-%qpW+x*>yj&_blse@gnxvsnlM?zHud95C4NcIrnsNup zt7ND?&ivp}OC0{emAbeiHVkXb|IX=#SSlYGV;EF&i;)6Kh=EX+0dAJ~t%9A6VO35m zGj;XeWdgk)jIhDeN;Rk{5|5&_di*-UmR8cu7LUL3wjsnXxvjW_D}dmXoG;U`Hrk{fGylblw^ zrsA=$q%5c$Yq&@k$IICkaI4{;VyV)^7MWRTW3UYptJqku48TxZq)J+$Auj8oR>n=h z8B3ICL(+M(b0^inl@xgHq-=zG?AgB zN?T+#8zy{U`AC-WED&46T}BvQ#q&CNAhmH8kQvAWLu3Mfo8o>o?@Gg6F|Syla~V5G zi+VX-jB%-gO)OyjgHNm=vlMF^d@kqShIsRhI<^>F!$JX0YM`AR>S`&UxcE9gky$9P zuo0X^j?a&0+ZGl)#1nQt;J-dsqSO=qZ6b<#2To`}wXELXn z->R9bf$`OprCRSQF8sm1-`KR2F{PX?7 z{J}%-dB2QbJ}8gY{sMlNJ&0_1ikXwkQ(yV#N0o7oD&(vG-+G3MpSgnCrJPl!I38mw zC?imxA50KTL@5j88e7MWpIG#r<0VKd$N{;{fjnUs|S*Cj4bBpLMv`M);morm>-nHuRj<4m%Z0@x<^}#X$hSG zobkezPFU`PUV&)hi4PqyI6x6-d$(6;uN;46#1-MdqYqXFV~aR@J7LxUxP)T!NHpw> zfI+Gw_1H+<55<9jm>L3~kt(F=GY)A&MjDFL9_TU=8r^YfjM6KOhT(8mln(-fFlq=U zbw`LOl08x0A5VLt?*L2?BvBvO1VU>tru9J2L8uDB?xCm;f!h!?2*$br3b8wB5FQ4> zt3Sqv;=*wB@2yIILObGUFU;wSg#&R{9=SIT24PMg>5Ueha7HLeUEtdV?(J}(11x=UvAvRA90Jj=m5TRD zJyWGC^qnx+9q$_9nJZjP@yHopMM)7-w<)r%(O6I?4G=882w8ZD^dOFRU1VCq*%1En ze@!q%K6FwysgEOuif)~#k5V(NkZYr*+ELo*VY*lp%+xNvn*qGcFvtk9&bN})hyjKP z@l1low%9ExFcWOG!Db;NnW!Y)cYBnZsvT>EJtD0zs39I%U~NNmGe?{ab~eBOsjhAS zQBMral*eFj19Y}S|3>KPgk^#UZwO6O1!^*STyM=PS*QnD0#)fl<{lUIkfDWeaaqfP(+Wk}SRgfL2I|E&1~Tlh zSRYsHRbDS%fW{UW?}{xA5ao%k4OG|FQfJI+h0}J};fkeAF|M`31-EF4hVH2H#DrGZ zpQiZN2*UrlXo*Eqfo%hC zSqK@y!dit;>`d{(1S70aC5KMnX@+~wCkL>$o*{lf{ zYgFr~T5~bJ-nYVSBUL_oNsy8zD5`SW+C0g^CO<{Qu=05Jlnr!ahvEPFX;Q351vz_kl9apSEhgI z41di5&lFT-?PEs2qu(>7PdTNq>nM!#XC90D+12dQ>1g9*HxvzfZR2+L{apwa@ixDo4k1{y#K7SQ|;|=b8 z#aTBMvT5=)ZV@ly4IX)}e4#&*$hF7yrK@aZw5vhV%Pf4m!%$3H-X3 zL3cUvKlZy$$K5=7oB!=$%NyLWL!q&({-a40$8F{0OKh->f1hRWR{ET#!B+a7ruAR^ z=@cJr;npxt*~lp;*l!&>oZ-{I77JYOH+=<_r<#h1~nJHVF_ zd~}5Sq&p^@ffqRP6sMl2aTvQ^F$e-f+NX|d0P@nB0 z`0BhO)_y-jos-PHpk~(xE^yB&mY(O%BRmtu?#H<@oU?Z+*&^uxpI)P*)?Usy z$KiW9{S*UsG2#TvcdRscs1I&x!>6084$v5%>FL2EXuDQyyCwcHHr=Mr)W#&cj z!Ue8B&d3{Fd6KO!^VUHI%gFjT{}7+>G42lMr9Jlf3Dsh(CCpbTn3CEdn znWm@ca*^XA+2TA$hjGOPRz=YE5`)eusO%m&+A>-{#-TS^7|9b?*(-`A*VP*|`3g5m z0d5REFRpx-f$iQ=AsZ$Mr|~<2=_11v-k7wG547@009x zng>L)xIn#QjJd(XNBQ(D4<1qCNb+&Uoo9&j8J*{i6GSAB98uWke~+p6$mcK{UEug5 z{4J7t$GJ0-HTxABT2$I9VF*Vs{|uL(WQ!~8b4tPDVvlo8IK$2=n|Jjo7T@B7quh9r zn~w8P3_qS#WaBl0R=&pOVYH3r`m@}3o97}KCUTo-K==6e3b)JAi=f?A&ONUj!Wrk7 zah(q?vWc`3U*g1A#$RBhczPxHd5d8;IrtJ6hzUHJMM4a|#s0UM9Yx>UDi&IISrMM4 z{#Y89{*C2`ODgP%7aS5HUIWSdAVa{ zQ1+aXf)P*h+Cu*JLg9mYWYDBgS&oI3XYqu#`AX)~6C#k9`3smTQc=Fr^p{CXm(aJe z8G4T$@^~v*8IMOMaqttS$1*01*1{wd2lxXDOf^1EIY^}dt2jkPkJE)z_L!Rzc|L`S zLNJq9v?yz-9G=0?FSzLmyC?E$Hgg{<%ki;H>ZPhsz=CvM7B<>bI%P6eoV{6W`HC|n z8uLOG`g|A8PdYbbs-RH2T$+h6Bq~xSKV>jdkU@Ejkt_LYWj)C2FvF^t%EH`WAER53c>fn=)Fd=0eH-e`9hvSIaK; z2aU?9UCTx_)cL`zDo)gZwk9TO;k72xsfKT|-IEPT~sH6pfUqx@YN6r z(%EW`UY1zvrX&E%23Tqd6BERlqP;cprANjZ73TOZQi7>MIxM$Vg)bvy(`|)tYh;_L zzKP?uNVI~h9rUc>+W;0)5@d~$4sdh9P2up^W08ZJm~q5_7p#`rBLO})$18h0aKNfY=-3RS9C1yI$Bod^8Rsk!-yFMbFvJZbtuVhS zdKsXTi<&Gc=CBbuHN+rU8yhP@=d=}G8DNJYzL`SX3_1GH*1~cTCUh}TAj}e@lX@C0 z{3j?#4MYnNTLY_1Ap^7n)@ZMz6uqx9x3orx4B4#E-4ud%&M?PI3zY~yX@$ks*zAOC zE1YsbzAK(JgS8~1MQd|FffMZQp=*PG95KleRjvxz6y=UlE?Cn93!KodF@AQyIuAT> zLVY95b%w2-I+(JX9%zX+j_Txj&;)S~sBerSC*)g0&jGhBRAjhXc&&}$)d+t!!VDV- zg7S#GadxUlwp! zDw{Pa8G z2y2ffZP3;q@xJKM21h;6rUNFn#^M0{>xpUY@T)i60?{e}rd{x<6>KC7+YT|Ekm-xZ zZ4vB+Drrh;hZ-rqlpf5^cqQA4Kpg9Up55`HBbxNWk2d%yEEFNV^n_6`8cT|~1AKa; zTURXZi@u#Q?3(JDx+8qgjn9~gt0H;h9oG9J&KGY3Ftn{oD;M~wnC+K#&~1n70oWLfk!{gLSWGgh=!hBt zgNq}&3l?|966xRRgLyshq$kdFM@4`9)*mbTz-%Bc^}@G4&>4(XBe178&JDq)QFt~M zZ${(JNYsu+<4Jfj3RzR}%V-RqgT~VLIvy!QuwgP>N8-^ecuO36va({c`<1MQCZ$p>bV<8FtBQi9`!BLS%M#65r2kNlwxYCX^;P!+z| zwnL&jCitO!GX%88Fb~AH#a(w?@1T7Ci&`T?<^%r7^FeldXt#x3TU_=+3ptp9sx7o* zJM0X=#SYlg78kqWPJ1MF!^8G?9Sp5@c-kGC#OOW%@4LV(RLv{K3%0#I()+5J&$3fMn+jdwTX2f{Q26T2%b`;|aA2CJz>=U#Xzgfs!ZiG8#O0s>Lk9UdLAs29>Z zV@EKY{4uU82DL?x5NrxSepf{MU_f^~Zw0>~q(~^cJ?=C|RTq3~g$Z3Sy)|}A7m^#U zw1b(9v)r-K6ZgH~+5*}EXeEH1W{8qYbSsz$GR^}}o8qioy_@2TGh76)(@Ysh!`x8j zikDK&(_DoVWanGxpgxag?zq$peY{cM1eG4@PLwX6AYr4qVY^sB-SDSe+=Lh=3QG%I z5)zsxzBk7%cbsj4kXD$}6p76c*c^{qVyP=iJmKaJZFdZm0v!+3yQ#GMug+L6S@;(C z+g;W4oNtCydvtQbe|D<1lVF|3$-Ob*aF9`aoPbbEOAl#o9t2Vh=ZjIcvm z6ZLwnE!7QTc602P@Q5QcZQ(D^zX`gyp}&KgTefmQr3)t8!=M>vIpU=U^6ha~5*!YA zCwEVIke2w|1p7U3M=FQBF|RpR2H<%!M6`mYp#NH_!(Qiufz8q09e;XaUI*;*hI1Pg z{}%{eybnsf@X=S5NwxCFGjD}NXz8ok>)0N5g{s#D3;hw%9y>b0PjVmaRI!?-%vjoC zSbMw+zyfc)>VSc*@vtM@y5OOtKm74timL(;-4PC6*zJcF0v_~7kUKK{Fs3O=y;X75 z8y`iiI_0VE2vJ^`=Zc)x>b#xdqhN!zeh3t6v^VZI1KTK4y)fv4-O;ThiaivVy}Aiz z`JjgjHh080A;!0Zy&GElBiIdo?J>(0fdQBy2S?BoZt(X*WK;Yh)m>8iE(1(gv}=PF z&GA}H-EL~q>n_)jHn4EUV-IX>jEybv#t{!?+3^3fYrRw?xG9vu#O7FIk5oqlS!1E( zi7XWNpuZW;+F^_-hDs-t6bQRvjILZDk8Rb9|Oo3u72rLKM0$ zmTH9%X@goR$dgtJ9aOtwjv{!lp0zv4G{NEGp#A$JG3w!q=?} zIrIsqW;5Usn+ojr5v^Zw=3_R>XZ17wDR8Ps{5^+9Bo~~iXjipa^h+Z$RnzYM=d66l z{?b7c&v8$9Bbm=LSTB7pj}`yfI+a}#*)WAY@2lWy<9jSirDqP)vb7kKR+H(z4HQ`TLeX%fxP@LoJOo>M8&j+a;%rwV)* zByvL}ngiF{TE4$r11q6F00fDESk#!3-mRQM>F{&m)e;M?;t;Xr%y`Z84}L9 z_u2Xs{qHmJJeSe?IdJCo;qwNhoJI(St9JhywH`#t4d&pEord48i-mB8_^JHjw zgM;^~za=xACzp8qFukvG#(6ayTXmREBlzEcd=Nq3Bb4ve=_&Tz&o-BN>?G6AlE>Nd0?otNE0VnrvEe0tI>q}@YMj{fIyVWt zOIpQc^cqXuXr7czcQmaYF#85KJmT0Gc8%kL+YFaD#%$9nXxL92&>=G0cAO|C+5tRct1e<%~=o`oK=o^Zt>MIW#Zere`X?9W570vE63!n6OQraix&1vl;V>!-SYo zsDjebAL*6PSs&>0l81yM_?FRMnfs0>bGclQEP@J`rz#Qe&ph>oao;()ic#g9QOOs= zGa<|CxSrf!%c<225lW0MEX3`grR4s-hVawD-zFHWiLnA_mdYM8<#m+rC&*aF7)wOS zGC_*mB@M7aY^z52qJcay^65c(4Z`a9#TahlmoQM~u^MxPYAeld80oBsN~-@WCRH&j z`U;CoSGuy9uaDmP$}}i+$6^8X2$I(j|L9?ph0@WS%uuC;k(Ov>ssy-85=Sz_Lwz+I zkVo(|hKmlKH^6Bl)lmFV7hiO-NC&&E(ODleER|VhnjJ0~pwI$mv|w(G`TBS$lAo+F zZBeF;FV^U7gvSk)2>!+tCB_g5%|#ErE#W0I~I) zyyfL+LZp1Lk(`odNwLIK(q9KvkP?em2-t&s~PfueHwN<-||#U!zNX+r!e#bSBY!)y5}?~8%*&>E3(7T9fw>Gl|BqGlt-qKh?x zy(Q8emA!eY8@#1jNCsI}_~48}F`hZ2j|HUtR;;8~n!>~i)=eQ0Z^srGE{rKRgfztF zW*8<`B6rltSg(aLAryPVr4gn!M}{+W1kBX{uVjbS7<#@KBu!g_Q*Mk7t&~o8U7C>_ z<7EpBa7Iuw%(TOj|96I7Y=tetXLeU@r@uAB24`fsqm?s;d*hY^N?T!`47l8})fEGL zVDEyBtuR$4Gu~JwYNj80x}(TX4LSz2SN*NGywKbm!9FVMtu3#mIUcvcWp}Lg$FkOH zGdRKrYdhniuUe(2`(c=r2l*l(6rFwWcX#9jD75m&4p==JOQb_;5FYfv@zEI79_xo8 zy9?$HgK;RLrr}+0?31niK(raFHo0z7uzE21O^59W)ck~n17JP}1|#rg4o(lpih0Nx zinHUebSQ4jLg)zO%|-bz^q-Aqf=8Q(pGa28;!+Hifjl#N#2%iF{sfZh` zcxxD{m~WYVVK)p(gOqoozPn=TF6xcvgK(iM<_ti35b*zTfur>Kc0qb5oP+S8tEz&^ z2~kzH!JSYnZCSwx3xG}!+?MQiPgJ(U?XGHKklYO=KBx%7K_6V~sj9{gc1LUwx(`4v zadCv=P7pfw#pWP<9SZ9ZxD0?r5NySL(H)D&Vo4~bjR8Y3Xfo#Z#`4*i+zY*C;&3QV zPr&3*+@Fr*KIkwN#l2BA8^Z@7VLHtFqii(p4?@a##P-7Q35e{4@8htzJKB#%X-}*g zheLf~HUg)6VC)DK_rm582n|KI5$G3!zs6x?XB-%g^*zyah>Fi28;Ulvy&8e(9pK&{ z{W_`VJih~uN&|8yx`=2_+7}xV%zA5) zI^{fj!qEpCyTeE(EkT&!jp3otZv%rqYRh)5GrZi9B+tqTPdcN{8G8a%J=P6j!aHDV zfZ_qxw1J-sq_}F7HSV-V8*xOqK>&$~-WXz!)y);r-P8^5tQ3c##sv%o#t2vKAQvlnD8XC=x?!Id23X;%4(#nPKzi*P;<-~tAWv!m9a&|!pTzHEc zQWd4P;2D?PDw*hKj~ao!eO$?`pVTWxK3mnn1J8IYpUOKP#K=TME1SS1czBt4B(;UMt#dR-W2- z3@zXY*{KQ8<_>?)X5+i;{Zf@CM?PnE9G^=y%oTcN^7b7SZuKRrXH z?kJ_NlN6gut?EtAdqwA1j(W=6dn`>=abw3UHWD~kHt*h2MvfbajC;$$iERH$?SIA8 zvF5&lr}et4dUhH-;qQ_`NKn-?EgvZ|UfDyw&*q2}zLB_=93LqTd&t|RJo|{dr5-Vn z>0cC&tKbvcCUZkE&7X1icg20m{lu6gelO+-q4i2y;gLeuu6Rtmqk#yZA87bcdG$Tx z+43XZ?$hiuH6(^CQMLPA|B+{sxV?x6A2Q}6JtY(RUezv36V~)3eiTYinu6N>BB{Cx zK6}KlA1WXHvP|VVJ;lGBNm;*rPiAl}S7g&#s<73DnzR_b0BiM`0Oc zerN<=@spdYWB9`a^UL{*6~xzks3G(v*=G(dEoHY8$NLJwuBnTPPObRSp#h~ZuKV@IHN%BBhBHa4LRmBHDD^O_eSW^Ou-40yp^F#%xUF@ zaQ4JoBlPiALt`OJG}6UxZ=@OHZ3mRe|80Y><}j9#rgWotW2Yrn2u9UTwb+MSphCuv zR=Cg_{tZyq8q!OzDgTNjR&f&5G)FaB`jKDqFAFn z5n~I%HM|y~&=)-gVd{y6w$SlJe+xWv$6i}BZKFnxD?PE=9L4_dF~eJ>xjfrm_@e>7hN_{cUw5@hcRL*GgO@Vd4pln1kThzY6ghT>Ju8QMXucctuL3Pu-a)eSlt%=8e>yO>=YhyAZ9kkPyP@aGdsdtKF$Gfv_y^%^vw|C3xfvO z)dsz7VB7|k=D6stte%rvBS(UMeuy_wf^xhx(MVmUP%E8OW+%-JJ@ioHf^<#9xhSV) zADK4mV4`4|^>E8xk!-&^B8e1(fuvp9H^CMSr5YU6g_S)%)Y41-tp`0pUFqRx(O$LC zTxvS2xl8I8G;zZjAAkkTa9<039dS+v^)0bk&Q+0Y>e#)7+Bkc)gf#jMb5j`#Lw}Wpt^mkMh9yyILTNaHC5Ze)3T+zD+hBky#5Mmp{Tbfm!aU}%*xZrvZG;fJ* z1JTkGcYCWX*t;G$&z71ol8{(U1DTswFi0C&1iYp_V%MNNtTjXQ7K9 zau(ryTeO?4x@>gjqI-L6n~&5$1v1hKR$w1_QTg*QG#EaMF|`Y>|AO3}*s%!nLg6(V ze%%l@A0ge~GY2DjVCv6!)JN^4;=194^fz_Iy6H&i2G1!<=bbbT&${BqNURD{yRh-y z;4losr6Ot&zJ*|*xW~Jo|6thlfa?fs>jKLWnA#aR!>~9IqlRKu03MCPtWNke3JrrW za59ntkszfofe4#}cA_KCL`4^LnhBo{Xg?c=+u_wbcd>Dsd$|5w9zp?^nf^h9; z?A8xkgBmGG{I<9t^v8jXWpF>xdYiJ^BOEZf3EYGVALHv*IW(0m9s`Xa7B!hQe8 z(OJiJeScs4(A}*xSYTlQCU)y|cF&k|<cZOW+1)X_8x>HbK_sQ51f=8q z?sb3oVDQQJ=lyxTU-#Z~o=1?g8Fqk}ampI&Xa)bHXLwZNTgiVqBMyNt^vz*PJx zWJ57U315)S?+vi$H6IJd_$8+|@V5fC7l()dr6oQ!kHta>&g5!I=6%K=3)u9Wg}Hp5 z%x|76VRC&6Yho1<>F|U$BD8zL`Hxw9ht~JG@iA}Q;RllIafO*T`REeE&U3{%MqT3y z3Cp;|ey8}(HI|;_mzU^zR@=qXF40rsYcFugMZSNDYtJ#@0#}};#|3_Mk^L^RyFADh zuDimsH@WnJX50_I#;og%zRDX9`0fq9cUSkiQ)MeC*&orIc!xLd>(16QnltWjUo;m- z(e05cjekzyXHsEB^YEO_%tLIkEgDm9kj-rSsRPY?e&qCv+7{ zX^etBvtszWL?}K{9bKB-GMDd0X^dmKkYIB-E}5~}{9TA5X?&2tsaf1B6j>qt#`B@z zSsrnI1}DgbC57oRw29|{C(IXVU!(?Weiq5yiM$x8&Ezrncp!%F3X3&Xb12p)>aKWR z3`fTB;uB@1DxdZV$BPy*mZ1Wakm@W+hagdj{9iPCB(hbk&gPmQGa-&o;*}26S~5MK za90cuC2KdkDVBCo9R8f+9`Qh|a$^w7F0sr?)VTB1$DDYNBceG?CQ$KAy2nyETz7dm zl2O~jEBELPw&A`Jvc!rL<8GT&yM}*W-u#f#uG5#n!omAvY-7#7nR895E z16*~CUPrj}JP+;R5|QH`;_@>*a*XLG=y!-Qhk5M?OOCVlgig~c4|CTs6*)H@=Cs3n zeS|&-x#b9pcCbv8z*{->0QYX?lij?vm)XLQ*{UHa)w|hC_&n=4ej~5#(O8zMoy^+F zp4%9{OA}QdZfBOHv`9|MI<7d(EgSgP0iM{TD&;{N*=|4mHq&`8*REsJ0Tyki=Wb3C z$+ygLw(aNJx1WPf zGI&2X?d5l(pgzQ-|FZTh7l=rBhmvPr9B0*Dh92a~Bl@w5m_K+A-#N;tQ|xt`;d}Ve z85)RK{W3crX8dJJD}2U(>~M?@a$4@^&u4l56mMVQ0ErN~LgN!Oyu*xReEYhp(2M_L z^)b3$Rqg%rs~miS_Azuo}nz6k`0@Wo@&xx=51;{Oh`s zwU*v|1JI6UR228zqkjxLih&}U=Y_%)%Y;X)cutd8Zc63SCyb2OT+W?oJR3)w3?@I} ztaP4}Ric15W4Jz@H{}5RL@A=*=mL&T=9(JrNagMlZ8tSnX=d@A0=7=% z52dV5Wu<`Y^Vq6})tL$?n3=^+RTRA2PZfNS%}Pl%&E{;u`{%P)DT7{cXDNs0Q+z8G zFO;G`Hea~}lK&f0$Z-W4uDVL%am(mYpct7Ya<5|UFXV>;qAy}xIrkLvgJM+${8-4_ zFKI1={1WySIYF6bc8jUg{-tKz+$p1lfMW7^x0nY@D7mG%lD3n@LphwCp{@_ZWSfAKquuHBPywm~_4TUE%(#TrK1KSblY%A3UJV zBb6~kKhP6n>;q*%FBE2bf;OXiCh%31T5>kVFf>I!eWBCWC-IAP4i%TpQ(C5Q;xo2Q zRV;kBEKLDek;ObAC(AV`TaV=A=L}2XJ86n>JN=BQSv;DovDZx!MU+a@RF*%ZXS#x+ zz7}kFrcU7nc;%GL)&j+f)j)(v$#i|j7mxKiC<$5X$l?!4eEnSY`Kj6bGh4%jTO}~iy=8oN~f1#E+mO5O(|jT#dCHV$0TYl zhG-0&lT{v&AEy`Pdnx=*L;@*1^oV{b>?BuMdF6t_PT&|Jmdj-^hNmC1A&T3csuchK z}AjZQc_H)B!(!v>Cgu2igkw*C5 z6*t8$EoxyatZIcoJM5G$x)WCV!QUN!`J<~02YvCj173Qo?)|3@_(^{6iyr=H*BSf7 zE$D|j0W1fhtrxZgVwr~u#p|SY>y8axI)M^#`^ENHE^NupaBGXJJ#n!O{_KJ^{+e2N zx(z<>rn)|dUO43on{N2qAC|rG)C2E!$8vwH55;|NO)R?RiHZGnV3*qu3_yoLINc6o z2cb`U3=lDAXLKKivM{V4ie(*PTH5HpDW6XOP z^R}k^_)NsEnfP!zPR~Hmbl5Jyf$``%15>7A$~&-`j=?h!GZRzi;qFA7o{gQ8adZZn zC8%fyZppitqNSqoY|I^xzH<;g4yPvJ_IRwAg%8GIL!a6yaF4*OvDhQAQzK#87aK;QW;l*dfNunb zjE6u|R}Mt=FochXPaj+xi4FY_IR-NZ!+#9?B|i8q*!4r^TL>D2iisFE8b>GMr(u{o z0gL+K+9dRqx^f~8NQlxL92kY^)6jXa9)y6=7&;fhQZ3HLu@P{e1*>rwI3ItG#p!wY zVkFMaRT}e>S+E(0Ki*8m~ttdlX&`QT6hP;V2x9V!>Gt#{B`X zi9l(DiiA7$Lw0|h?T@?RddreN*w!0A41z&8hV??LerSTv>9Y_a`oFno8U)u_I6e$b^UzCLD+@4jFhdF&jf?S_Sh7$@s?j@qED{F8W;j|R z5H?Upnac;^?}6ys2Ym+M%YF#&g)xKhbsxMJs^$6OfjH6+`F-$le--o3l(^wAI1NV6 zQ0$d3Vwp=yn<5ND`=YKR9`{B-4_ySZB9Jx=)&1~%6uR|8-f-l|5uT!U{-wh)t~X*Q zVoNvtFiFqD=i?9_p^kgIKKN)nwur!6!fHq0i_w~dl|L3O{m^<0KI;#I5m?+0eWkI} zSI5K>f%@K1_=F)*V8XqyWe{eCBDo)4cfrvJM0J9DIF5$lWN#Ss!pA*yM(-hRA1vQl_!y_|+9(y`jB@2(7{zDJB?c4HxMxSVNjdV@z;aAY&FdV1^#ed?u`+7QRnz zZ=i!IuGI5ea>r}VmHePuMi?Tskq3;Gv@^p3V$?Db`icN#$XiDE%LIYVl#y;MDQ=oo zA{Vg$1*T^PcT)^7MX@D*5U`s>2im9ryPusZUK&lX%p9k!m4_zd-6>+Q5-+xcYIU|b z;Hf=+kYR@{<~m`XopRnh?Xc1g7v-U>G_>8!0h!iVAt*M1#)wVK9$#C*=Z$v7UnW6T zD6vGI8HPBjj^!s4xR~HK8+=cWlh-2@GDEy&fTJdGHdY8yUqM$H;TQ3#wGgivEeOHa zydto{X6`Y>DdEbRVRIGF%3xafgz{)j{K5#G8#%=SS8F*$urmVdYhgw`lbTsu$7Zs= zg_oPy%?Me|?B2-bEgU2k@;W9}@UEmV)G)c8F->$8791H}&mm2$sHce#MPv{BnnC3} zRjy#v(!panDY;nmL?~AC(7%PM_WDPfS3^P`( zl$<>K4X{xDHN*;1-~+20*xd+c4D|$%!~T^a&Ptd?6VJ8qw|eEMyx+{e&2$mUpFkaj zbXTM4W6lN;=b$BUzljd@{9Mv_8&s$!UH1S{slCbSDi)^G8|I9B;(0)W7;?hffQ1Q4%rgDN3_W!e_8WAy6x*0V+LPKIJ=B z_|6cM%yH64sdOU1TVRaCz>@~9YM}svLPZYHEbT-5Ozso;Rs%l(ZVKlL5aQpAMj`!S zuXOq9d96vqKo5&1LAU{poL$GZg1xF?X&rC2C^1atjFnAqBw40`T`FlpE`P-ZqG2m01e7NXoLYWT zs(#OJUvX$Ht6p+XlU9p$)jB(t8R*qK{$9ftK{pHIG>;Kw3@T(}DXTIWn8VCWCW=}( zg})bTI#_Won_`%g#ptKJn8RBM{J$)oe@NpDE`Pvsft^0owAM#=xjCI?H|U+DsYX&f z+TCMZI-~E=FpiV&aC0IpZgFV>Ka!x~I1aq35o4l0JsPL|0g=szN~~})H{IvFBrc8O z1ktPCSK-kH4M5$zu48SB&kz1dhC`{krL*ER|{XWe!ZD*B!PJ(Yq+RpYqWa z?KEDz$O)ntxyUmyOh2o=M5i-+H(J|Po{zcb3={A1*Hhg0n4YIKZ)p56K8j?i82O`U zxlg+gr;oAM1G=2y{W~l_M7K!p7kEMxKR(5;qUn1?Z~x^Hc6!Wzk1NMm7~nl_v*r+Q zJYvazob-V0&+u9d_nhbKN3=fA;5(cnk1tVBS9m0jyU(dKWsWp*Mdf~u1EgZQr}bCg zyDGz2FNtF!lMrEpL{3L?ayAR)m}K%32^!1fr?)wvfK`!iJP3E_C;8M5`6`pKq9;%1 znyU&m5`jTaDTnVdG?USHX)TKJ2Ml~pH+fU3^cS(NaG~$2{G;;&E>BgN{Rh%!xvgnm zQp>xgsuWp-vZCf)lFWT~X`9GJ37in8W!>|5{t?TLnQR-!Ino@K{_1l@98XQAqaezk zaYGW_B%DzIgISDxrXZ<-&-it|c7rp@n4HUmdP;Nt?^-UAWzz&6`TU`dM@8Y#q$Jy~ z%^(dBLvt)FVHZ;vzvR2-__$QTeShUEpLSgqdzm6Ii_1+QZ}YqHnJFBv39!eX=x~$0msxwOpOXk0p{Rg_#oan8g1p$t9pm#gV1v75luCXNNZHb%NJjGNeChG}mu zpvPrFHq_sUNY%83W8MUP%KBMfPr=>HZKUisBr@SY(IIWt?fFXtmp> zSS~6fV+7@KrzJdu+$cG=MKrP2Ab1}$?0Lz3<~Ur!yJqO~QsaqVyr9T*ZOSQgmhlo~ zY>FNNjkmx@l1*s?(^`(VL$0iNHdrjnyXZ)bVETsH(pBUNHYk_5xfRBGAkG=Td*FQ! zd@GwPM=X@dvOA{vsno4&2b6n34pf&aY`4T+Z$YGv{tY8Nhgp~7{GZJ2LoB$+W(p+eVx%|Ki)_Igku0tlxY!IGB zOG_Ne<5t_CdR*aG`XIK>>3izw=dzonZYS-=$(rS6#5l&IET z^;{}S;0l#|yxYV_0xJeCxkDt+b3`5k+;&2mA-YKy!Uj(6im($sgD@?h`{1Gp?mOw= zd#e`?Tce97E*c@*86`%D^20n!l(a@AIa7A6);Q{btqpYYP~7n~53C0Uc%V-`e|OQy zS2>2|a+=9!)Wi+)3QKw09t$OV%K;{3{K)}rU(($PvhC^Z0@1U*YYVSRo|9uJumW)c z7Aw~5mXHc;(YAu(;d&&Y+k!@{rf82hR`aDRW*8|cX!#ofVT2G+?IGfJ!7Bb_jD5m< zHbRiN*UfR$RRPH3JQUft%vUka|B5uo8p9<&*AgH3;ix(Gw#KJ+xY-J+@&bJH=RaFv zq)Y}yB;yEEaR>@s&=(V(u-_L=A_eioSFW%Kz+6Y{4n(yJ*7&Nt;Yxd02yChimbhcL zKhj;XR7|!0_((#ayzyCQ{OyBjQonfPv@~ZtwG8ReT4730eNiH1g4oP^AW++H74DQ` zjgLZ9?*4W=%$8H7gC_Rob;4N-^yvgE*{iohgc(|OMU*3|I$@WCcBQ%q6s{9GIH0&I z4vY7*Gq$-RAsC&U;nhi52djIk4*Zi|sPl(oPt0-C*sMRiVbu$s?Qys-iX`+z$Wd+J zE1q0&yNi}M5N@J3_Q%*hI*@(VA5+A;IsnlDNEwKZK05Iq*cufw>28l}gD}t+PX^$c zJ3TW@z0JL+rHS_Mxc#+u)8^{{1k=63ay=V~Mx@brZNT zK+p3-?NDrsGwm>6mLqR;w!kA_9I!%%HY(M4DIw;PG8_a02Yk{2nKpPQ2>)k~iyajg zaJ-FHI;%uXZjTOKaM%q7LHNa9xmy+vxD$e62TTaXE@wpaz+)#o6fTwsheF}ugik^c z?T9?7qg@rxW$cKE-Z<-`w-@2Zy`J#!#AFfS_~6f;peM%lgecj*>xOr{u)7yJxS?%V zY<9-+j;gcG>xiMw*dC1aPUzYLHX<_VfUaT#3Bn@_H4)cY!Mq*BZ=2apyb*X1fR{#k z&UhN&w>BE2E+3N=4nG88pb*i0@WcRNfr^$b^4H+_ZKCrr$9jL9HbQ6{%(sMrKUzs# zbr6o);#d%VbVQMm2LkYESGda8rw6j-p}N9BsAVB&6M}{?EDFK*129=MRJ~Co`EH_E z=z^^N_`Mfudtz}%d@>lzdnn&eocpE&v@bfiAM6BWCa6F$?evU5#VJQRA%Yxbi|!5FEqbkbhPc9z+~bTLja=x3 zw|0H{XA~X#C5dS!=Sv!F9gSoHQpdZ(18?Ep=R91`u`=&y;P4DaHS)5A7Bw?Ol9dc$ zpR2zKmaxcXzAU42BdY`+Udf(?eAY;V7qqG3C&fHe%A6M*A*tW_>?a%4d_E{)eJ)>1 zDJKrHGR*_+Ur3`Yep#$uvvGx*qB~2baxzcJp|yloX62{57|+MmG?OL zg+>LPmpRupzWs!MpJz}!FJ037+}`Ijz&Gt8OCB)gDEHr`(+Q0n3O}GRteuWB{|b{N zb>$)_3A*h(x9{N}mo)Wb&Kvrf*J<|I&2wj1yhV{;QJc8x3{C&$;^Um~FC&if+wJUd ziVfR2>o|>ea_Vu`?d9q-+l}H4!ME8* z5|FQO`B6?46XG#upJC>13IV6Dx zB}gcn&5`PczAPau*_@Hcb!l7?&n?e5D3Q-o_%uzEN$bT4m`Q^~HFWn&(ZKOI>CVWk zFj>VU-=_21XPgns*4bPgrzu)BPx*^XA;n^uqSe+v&*(3;a1#4Jreg{XA~`cr1GSq| zc=#sYOJ>+z&8{`S$9l1QKje^ft=h_xG?~{bi8mi9mA%_jorIoz$ah5g@`&9NIs6HK z7CKg{4kZi3J}hafX_{KqC4uwO_>&C&(lrzLw{!+Qi?Wy~--vAPmBPQ69Sb!s+^m>wU(vOIzloPTmp>M9TrLYmy%po!i+pNNOXHH{}HNH4!^JB;g`H$#*u|w`I?)HxVer!C5YrTr{UC>U2jIZMC5`I=m zk*pVq-L;hW%Xv+9)QxngVJk^+tK@@H&adLcN-nGB?OM&9?=P#6B+p9M&JbaB6au!C zKOqhXs@IYyMgj<|(ZLjlMIC33t)7T8gsAJ~;4E*gn~Jvt>g5RQHrQf=Z`?7%4SoS= z?}h^5#!Hl*zizrjOJ6CdYJYeL6G@hOS4jC_EAlyEE44yaYrOA>`;O>fgB^CLlI@u@ z#5)=;=1?0nTcf*Ne9e(#icRM5l2)WCstgch1PfDKHbJn3?o}jNOqzi&4RPEQN9E#W zpl!Xc4fL;KcNH^Ht|1c5G2IHko8Y+#zLqPRg*Mp5WcrIW9IUX@2Ek%(vOu{N@}x2D zfR6ANRV8?__P%+2cx_-qTAq0f4Bu zP^EITTVqH7rpVP_B5Pfd6@V?C8kpNI0EHbP^5s49*EUG#q=>5Ywu;1YYKIB!5ZO_K zZVNi&u*fMx(XAa0h*m!sLuH`T2`2rpq%)#>D_6>0JZ`;}Icyt>6{05X4YTpE8v@%g z_+wrJQV-T!ptGqFh_@6qh{zHuX!4#jl`F8@b?I8oP#Z+(Qz79 zk4ErRgb7`FBKnNPxE4`O5t+7m0rVooUb4@Ghq77W4ho=6*n9bx!u6h_MCa|mAbL+}XLi+Xve zj?N25puC5U2nYAa)o}{KJv0pc2V$s<|Kv9#v2Qq9kH)uy@#P3?9*%cM>0OSF!TbSu zJXRUb5n^&2h;u^`EF-5Om@@dyKz1P34ug4rd^i{vWXLrP>-*rz5PT4U&j;e)2$c21 zA3|aoh|WE9H2-%`3=78>-7zX0UyDLp0*D0`6b{F(I2eYJU9{jD;H@mC_XXW1RG9#r z4MTna{tMT=<+Z+8+W{K{kR|k+K1gea?fr1x2dm@-bVjQI2yBDD2BE19F7;K`+}1vd zIr588>QNVwOn1>kaiR^z^uTSYEc)Po!MNTBvpQk1aKAgExF>$;fVG{ls-1G`YTDtC zwi*~MB$;;u@J~B*Y6G{{hzo?LYzW)pEAbopV23+yxZtEM;#%VmMx7qfXlexmC+zf967`<8SSZm9?QzH+T?NzUis4=0 z<*wCkS9zAUF!Mm0U>(&BX{TA$i#ubE3-+|fZ!Q{0I?o+j1p(&_qW}eB7yBaJ1A%QJ zrk-!wYUwf52lloI4A6DvMr(CX-)IHt$o=Gk3l3Nz*gY%kc0i&fmN+Trxk$e3fRVY?+FobazB!rrit-WU6Z1H1#^vny>wq zv;x{w%8tkscjG| z^Q?2D1!I3Tg(f-UmL9DzW3V}maq2q@1BD?IR_ z2Y&E^w-1`6j1p6lA0BxjRX~MOyNPZ`_=jyYF?MVR>wQ{_Oz2HW=SS zEkZx{&`QlbNRQRqB6<%7yD35Id1p1x`gO$EZkXK>6~Q|A+0X%HLT(H}kB&GHg4lLg z+7(@73GIN_LI@N)QajC%4fn&H4%&3`3&a68n6<|#Nlx)Ws5}1gg0vsS;O5;*TH8jTLp4TNLfb*)Jo6F8j%7wutunyhqkb^Lu)xRt+3r1m(3AlgE+agStC}u zN%9mn=prC=J4}yFfJ#tLSyl#mVsOtsMX4534a5`K;ecF9EBToGP_rJy#) zS`!%CD!}1?WLtAQl>arsT@y?P9-Clw3t!dqm=P`-;B*TujqswL+4b~oqK)jz8aYHF zHps{(E|%tJ3+*L+LwXc7yjjEII_|I4j3p8(j85d_H{kaHE>}IQzf0J zhKs5gS53h&Topi*)NwVG)Sj6w3^l~^TJCM(nPv@QSY5B-K1W+b&Pl;FNF36|*OW5< z?JAbnbE|A1Wy&Us$_AFb;^GRn&FAwnj?U)vQgw+gC{l4|$qPACUSsGYEt8*O;Aeh-)TBB6VYHw0?(weO$yIvaJHn`rn5Ym$E5s>*O5ehDnmrO zn8-^a-ixPM3in3ymlXQP(<7C4lGu>J&SF_jrr{&S3MGlG@hMM5YI^3vD4tB>@F<<8 zb&b^I-_S^XF@0|Ho~Zk7s&c;UG6U{WxJG9m(Ec)ah=~0XTcj2{!>zaY_hrp^efy-Q zH{L$S|E{qAfBfJQ_Z?)xC4P2PUB)6dZoJ5O`)G8IMWReT!n=EU_7bc1@rP5&$L@Wa zQ+Dvz(@GF>I77o-{Qf`29N~Lsn0}DLu?;%NX{XtKKMODMoG70~#(a>m|0%R*&jqeO z!Vk`K?g_5BOvl5@wO)0WmH)9>$k=CjO9EI$X@8t%r?~V02VP|CaZWzV2?u%UsG`oL z3jSxGO5!^l;^#;CY@e#EyGyd_9|2ENo z1*_Kb@y{$=&)Og9`ZquNmIF4kn|-v6UjK5@7JjmY z!#A?`Ue?JQ+|T%RY`>T7Hn6tk2DOWl6B7?4R<$wHHVp65~bAvmtap_fB3pU|0y9>_i zD%YLWfbW<8spsgxS^C}N#B;oSgSW2G@-FSqD#N_$6u)>#L0z4UBJT6#eRjOTwoy!s z)T~=E8I4Tf%sBRWM)P>4K4)+uf6b!fGuCEurG&J;U~n!6=5a_St%ZJ;!%mXjQ^MGM zjw@wgA&ppUPV=*g1`kS#(R{!RIPI7uHisGP~r`GLfeST6Hfy{AH;I^GyW?$i08U&{+7h)VlT?ouAnTxl}|Y$lM99Nm#M6Sm?XAM4IV?I0Q@WBfu6JE~c&1Y%a;+;XGb1;5Io#MO;(F(idD@ z#5wuOC%i8)7Wv%yg3iUS&+~5^2vY0%U2e9r6dyOGQCid z4q|L?m(Pj{R^(Bn-TPjM-bhgiB1bt_!tG^hvXCMEh)TXy#h@xKuH^tx&!mbK-!|yzho8K$H(1T}fg)vWjlS)$K>F%Z%6VyF zcuM@j?eV}{cb@(I6}BmN$!L#O0T|N`-2(8Hzea|gm+%x%9QVR#3B_~7e{T5F1+})Y zkPf_q&ZMN`km*~66%NU8-%2YrX`Xo7V~~v|=XzTq-%{U2rWN+sV!n;C#n#*4hzm~G zVyipa+9TN+lO(`b#*4PfOJC=z%<4(4I0O;lD)M9)vIT$~j%`xth2h&aibVcc>RAzmw!wiQ zd>5=^R<{mV6Ra~q>5Uu}(|3@LIFAbHy)70AE;s;Z+F(ap><`58_V8eN?2Pi>*cqe->Z8F})Dsz9 zRl4jVw$?r<499naF|i|V_QZt&a2yJk{`h4G`VLS*^6mjRKT=b%MvOsq1nNiQ*U|WN zEWR3x_eLRWG@L~+FNlD#a2u}lrvhn=j6|1VC>Wz`sM^s88Hm*3uok#JzyXQEfleWgBIm&h$@F~c2x-NEK%5Yhr95##M|BtgF^9r z7gTk}55Zb&wge$29Nt}&M}4O|wud31E4oV!*cpey5!g}3xafw_p@{3M!t7mLF+L3S z-E}M;9fqWC*w_}L|E{gFmOz)2kVOTCw`Ebo33+@Nw!7z-#wvl)d z3YVeEvkDc&bbpK;ir2l7Aad(I_;~>Q1amzEPs3q6L^Hnx6`tQ)5nC(!;_*nl?5PK^ zLwAKc#r8vaU;GrJ`DoYW>WhCmY2?$^5aa~lUT6H`uVrcT8y&(| zZS^zyx)X}KX;HtchYn|B<(54$AXK65@>zt2qopeb^i=HmaZ8L3meQgJi}9VZT4B1lk}(;z0d*fw#_xr4zMOmL^}+d+PV=Q%`gXz%qAacwo4r z{wd!D%Y1a@=@*1+_PU^DNm#R&vZsaw!qyqz`fC3~7R)GTJy0TCvGm6#X}|`6UV6}e z^T0>aaq_^gl0_x7d`U5I!G0f=VIOzL@zyA7rFWDl?IG@%D~)SUMP13*v{0J8E-;tD zs|&u9fqN??`k|k2q`k1v9ck|9PGYN^1>_s2Vx!Bzf<&Mbr z#A}i0bcB%$p86xi9mm?d0agd0vnMvc31YYyfK)e3YNxp4*kHU8w3jdb=Y@X)kS57x zLD(x}=m7NfhCzG8dTR4(ODm1=lZ*!Gs8o1jiLmc{l;+{)iG9+9Z>1S$bsqSnjb=fP zZG-8K$}OiiX2@dO3X}XX%mtZ#+AWb;f4VhB1*)Q;r$2UEB3T+K=D6Nkv!{K$wRt{J zQoSS&+Y6R5dzA*1p-NWP7~_-+zHOw)VE!=CcmiQ?4RXg#k=I(INytC$2m}ILu^QS} z-`_~#HvdZ|OHOw)$2wuL5sq47YMrXi3|iPrd{r%+Zi9C9bQKPBBTvh;x`|De7+24% zH}?{5m^_Y-=_StC8se99l2CF{!ATFlm?DPRS)$>g77`+C4F6(AS>ekf<``gQuBf^( ztAL)3Y*$E&1}5ckiXpO!SyHWRs1+jl7T@A)ewD?VDyF3CG^$@Z$ClIh8AA$KBIdO` zno0&uCJ#h2Kb`3h6{&PLmTN^P8N3G3^SCR4>G}L1MRRbH z;x#(cFoCwObT~L)C`nSV7qKNtrGQ=;Tvo===gbiRS~f?OstPx-j8z%B9h#ZO@-lv% zP9Nb&Cu;JJyzD*&yq?6QeEu1ylRNRYFMPp(hfIIYyOH$HCL|Q>IjwK;aS|uoZ|IvI{JF!ZYXCK9+kg@Occg{$tO0KDxk+7^Mo2iet+a-cRK1 zyK0=@a+`Ky8@xsLr|fl?N0L~2n-8*h;vqAWX&c3*$;`ONY{9RIQ(pGl57|DI?lSDo zV8{b~7h%`v|4hfq;}f{_h6WY&yUu6NXmFpUaV!ybZYpnFWuFxKT<3g23S3plz>ym) zOk>M+g>MhJuTIH`X!c2Buba$z%BQ#0Dfz=g?iU2vQ+7;I9M+mRPLE-LyarJf$Q(A7 zKMN`?o=>wmCW)1TAWP&lNfnoDpe#O0;*l~|KIi5fc2DQB0{$+6;Kj7h;MhEN%i!8l zHsx?{DIJRVO({2LaAq|-=kr<>dx za~qX3E1Gbb+ddTGdKOnn{-DfW>o_?>lka|b!Qy&8&0$j`$LDcP12+`#MzcoL#Wm9+ zlP2~2?uBa0W%ECzp6)s9Abh7H?v;&kiK^fKDyDSyN?&ugcmYcIkpb>X%&`eBG;*zY zNnUZP3HgawIPnW=+C*X=pYUedt7Ltm{ZmoXo|`{ z5%D@Ivh{mQgvzAY7TJ}ob%e)jzO=>}q3zkizFf7Sv&$K3563e8XNtNKieSvPjP-`F zEubuw#s#VjsmkRo15C)Hyx{v%D>bvL06i=)G>3OuI9vn(!g0;!N$E)@aBm}1q>a|7 z!F=~#(^BB%<%|~EcB$5_hf3I2ntml(GgiOSMwwVyPYL%!)}KTUEaoCPukvY^LU-}E zia@%EC)4;p~uh=F1|Q$8lFa=SFKHp?xC1$kX#sBHiCfQdjuABqnER zpxBKZwu<8xk)u3PzjI2IVhI_=U$eO@if3N3Z z@q|~Oaeor~WHURNE3+9S9YtAGli9VHGtxLsx*D%)@$C^3bOvdB9B#Fk2 z%r}5|UM8BVmT9B`-jWb-Gl&4-kOA5>ahEYtBrw_(J)3z@EHKg;HocW#F-ghz zSem*`T>6?xjTAd@PqF{hQbg3!0Z4A)!)jhIM!$M}G}C5&V}R-P6tQ$nE%zBCx`k6( z*iy}n##mLuzs0Xq%@I-w*08(qkj24af-&_x_$H*dy(QK)Q^JO1fG%oYH!gEvWGrr_%&0^sTy)1p$+QyDlsQ(}sh~?7 zWL|by<%$-2%?x_vg!!&$>!^_mpV(l&2c8J5*in-ahB{%4g$g6Z^&@|ku6v{nJ|`_5 zVIsB~844I_(F%FxwwT$(WNX|5ez1mj6IaJ1nq9um^71!Bw(Et?{87ZdfQI`nEL|dtkNfg&Z-*26M#FEnsJfnQ*{42dp;7 zOE=83#}r4bcEWNOJyzpg@ujuO(rRq5M#di&_(VeOEpW*Zn=Mo|CxKJ4J{&N{SJqf< zqyo_{&CIcaNH0Q+VI++OGk6-I#00yIFvk>jEj%fkB0+f@U|XY(6*5E~R?X`*9NVbj zYr^-Aub@i}9fi+O#qd&oT*0+PTw2DI3QiL*KrySTxU`5Kd3|#u>HhI};vYKsIkya&0l+6UB(gY0BCBQlI)^5m#0)v5XFt z{JTOQq+=z&sn;0m-7-%R2T(bOzGiF{XH{|ZEB;W$>^gPH35;T98S84etCk}F-ujB^ zl5$(k$_k#SVoVheH1KXMgT>xe&&+zhTcd$=$0hl_S^Z*TO)5O*BWxQ9*BjPU*BVH+oR`Woa#)TJ_F}#V9(z~nF#@etdc6~`n62DW-fn|(% z)4{t@$c!T1Ez(!}uITE;k@t#D`Mgrd#pMhr=fZN9S97x@3CixVigoq8{)&t0__q)g z>r_|szzDr+c)W#C%``Q@5ebbIykQF^5pR=xWCBY!)Nf*-5pD@Z+z4Tk2rt4FaoE}7 z6DJhNIq8A-Tvfj<-_x_w43X2%4aYpR(uweZt)#cRBEwZ#wxLJ`&6lgXVq#+ty_7IHTFm?6$s2iEJ&VQY;e=9p=L1UdQ5@KjbRab?=$JBjSE z#Gk^Dmv?84L1qw+<#G#{+GDyo#5^M3;yuzMGDWUDuSBjppr0x1MSCoQYC#a&U|1l= zJ7Kby(!xb#D+bsPy>;y>64|GyWCM}xi=;p#wML*ni~_N|EynmM*{|3Oy}YsB6RDCG z=ZU|)@SY#iMHlS>A!J_nRx(3d4=k4nX)6emGu|HWOO%@%B4s&sK)m#?%=G1nAMmBb z3X`rj5J!)_g)-GwSs@6z>su9v!;-pPfult)NqFvBYoU_gvKiAtGHC7M-@FZ*e;euN&rCqO~oY zthB`^tH*xXw8#OsP;BxAQ(d4OOjV>UTZRA3@J!@hV)AWJFH-kfhKYr7z;a#D=R4_J|Ar*|sXLc!5U(m2Zjd-VuIXs(d zsyXu|KP~0|vNeVC$9!#^F3!^y_rVw3o5ScFRpq@SKB;^T&F0QRCFowwq)WQCk>}=f zX_hjF_hz#+mrpb4Et`-$ev_|LKanz;r!!LO2$?FrV0aQEve}eHr#xPhpEKF<8C^0N zDZSim7RT|k44x8*M=l>`@LV2!bGaptMVY*xt$CMQGSt|0Fkkn^KNqr70axa!#?t!* ztF!fH`_ni>NMBiG9y?@dtN&4s#z6dG$V|;;&PipfWd5DSq&U7#=eB1w zi(#)PJe_=S1<{WClhnrRT55d>F^L7)|#4B!(}ZaF`_WB=YTOBAQns`6`+* z(L5TfM!(hK5PZsilG!<)Lu2Xqlt<&)PM#})pC+*?Ud?U?68Nz^brOG;LL-eE#pEc$ zU6~_Dctk#(1jCY}b;sd+#WMdX@SJRJE97rkd{5k7sfva>oz8jBnU}-nJkAtLS_c1? z432D`Nas&kw9DW}nXHcE3@IKH*ci`g&-i5y&j>bIW&~-BdB(}9oSUW!(jG7PXF8+O zXexHL96m~CSS~-!;G#UvN$0(6juyLF9wSn?IGfK?xhRW^ll4=0BqN4b{JDUa^L6lX z=OvwA@QV`8$mWOwM(1<`f^%xPzl4h#m{7(!;&pvRpC)z^P||Cb zSE`wG!)sosZHg_jjUm@UT~WWty5WHH&AcfolXa8@ zP-=veb}Bv>ZDhO|mb)Rig|fwx3h0J|4gv;BbfX!Twnjhk%K2;dnV?X=HbifGIGdxL z7ve0@-xakYym!QhW_aL&`{wXJ0_o@|@RZ^&{Zc(iaK zlqc|(DJp>i;D1sl8tZ*wrlNh(TV@%<%?ddphcLtVdakg8T(#q@L^g;Hb_yjBhg~=F zXFGHv|7VM%#>jBP5F<3%W4!E^9kIX);V$T9hHVnlWUSQbJxyHNR@+;(A_aR;K#X2L4#7a*-VsEUf2o3BzsB{mc_tKWpjqnrmeS z)WE`ON`cU?mWSj4n<=Da`JhGl-?^FPuX(VE#~ZoE5Y19BT3~V`@0np=BWGD-RWm<^ z(j%vcue^ytW+)_OXZ}K}5(fk{bGQXY%0}G+FMt`AXm5_cEbt{DxBT1`bIh^QNb_0h zWV>sGzT}@R>>>sv%z7hm@MHXb0sSk(Iwhw#J~ni*h)j#0fo-^*;?~z|Fu)~ zlzS`WIxC(+YW)A~bRQ+IE7^67wZlmf0XkreYb-eC##ry6WrZd+af7{@O>>O4G%z!)2>yUy>t z_=m^$D{Q;>?%vPm{d%2qo(E5R;T|>Ic>s<$;%+sIM;!5D4+lGAniJN$;gU!W-bhx` z(+$Ee=v4EI8+Hqu;DuxUxW>n-kP`#3QvE@SZTiAn2Ni#86V)WZ9N>$B@NFdS2*KxZ zSQ>@u7%RY?9&MeBX>s^kuSOi!Y3hu^ib%6lj@JAYjUU9wio$qNj-#;AA9>1JhM_AA zz5%wb8L#Qd-y)D-`(UZIJ-+x}fk$^+^$c=Fi5J}5@Pw~r{oV`0v#$8a4Zc3;4!}0O zdjsI6A=(Eg15Lr)8j20RI2nT#0k|sEv`C@C8^f_V%8D{yh&EB+!8rUFg*oa;j74q= z{;waR644wF2UQ2gm<#%Kp<|Men20XJLU4yahJ@g=0J!>DJEz>^ zFR4W_8i@)}N8-3YHpZD9RQ(_)bT^S*JlsUssUp=!pd$hkV-547TFl@OoDRp0p_mtj z6b&E|cu^nHNXsFsq}5We3*cET_5_QH3m;7nAA7=lJwXYre3@XA=!O~BBhc>N0W zAB(wH;px$ExElL~=AMMl$6=y0)+_Mp4Y)8KCvUK}n%M#|U5CG}#rW$nL2bM$zPSaP zuEO4l2I(rh30s9(n`A!lL)T!%IJ|N-)~ju2BKBX2@2^7AD6_KPJ{qn12g8v(9;XMR zdL*_hdpi_C!_BSz(m>O!d!*bA!mb<)9*T`p`bJ}3Ha-}Rdj{aC!I+(kjNzzI@8>Y& zW#jJ=*xTO6rJ*_pw_TPs!(>HB$LK^nmWka-W}W>d6CbH0{c^=^Twgq%3J-NKrDI+nL)Fbm z#*L}CudkVS=c$Z44!QC8qA#*#)lNWd0tgejT|6Y*9YwyBa^17@Om ziGS;hg?-Q?%S0Uhi?N)0P^?{irRPi zSZUV}p7@_PqJ8XqI5Pn8p4hAoGIzTayLsS7AKWBzg6h?jmkP#9Tn*L8j1s|+eaNY+9LAWpSBcO`0j0mWb&_RqI42-hOf^2F4)*=-95Lr@(UM8iHmTs4xsPJMMB&N!e7gR zUW3(iI^cUzkI0EC&FQw~*i;An(!?JX+N$L{UEJTyISu?&NL8^B8f}`0sO9`l=GEAe z?V4(iY~k)|HneeKjWwi%XpJv?M-4}6(R7|qH1p^M=GC#d%D%~{T1GZ8^dcu-FU-U&+oRfx18Pn71S3%sw}hUmODI#hCE zn^}(YTKUQa{@%hD&-1oc&N#<4%@%8Yq=`ez*ig%jr#MJjjHc!mc1kg1+U~BmL1)iukO>l8NeJ=8kHpVvabM>~!MkTpNwSzr|t6JU7u3BE(&L5iC=8VQm ztP?Avp6_a0s^y*9#-Hb1+6oHhP|L67qiZrB*UB1xUt!oE9ml_|xH zTheyk0s0^2vxm6mph+8IoQka5zLWWT_={>~b~9rK{REcT#T)msZ95$|ar1ght-iF) z{%?n`lG`6hm?cFsaNtmBf+{CpL^+QRDu>M3N^8mp3=xX~H?!%6VIjI_tHOo%_vuJimmWZfD8?Htpny!+fZa_3GOdi~AUt?BEN> zcf+gCrjQgx}M-2dzgNRE_>Mb7$XXJx2h_)vE-0pbIJr4 z+Q_T+a^5B@71BE+Y$p$|=e;|5?Fy^N%w55Wn>cip>5sct@MM9p*>|tz#AVFb%sW@` z?G3zZ318dDuU7N_HuF7UmbdfsH5TLj_CG@g9Vp;e`&hYxSC#Vf^?b90KW?yq@Ph@M zeUfF{_<9-pZ{=;}w%jPMG^tl^!1z**yg-K{&Xt68jGtUCf!%(A_n)Mva)rk^@B-(R zF`$~i9cTMl)*rXTrSoCFUCob9(7V=1^;<64*B&{?e3=i=^RttD_7Y1@m^>XXAG`MNhQlFJf>*B0R&g-rv{2EfF%8toYC$`f`Qd+UoT~k83mg0)tuQ6TP&r!azR<(TVMa*%L)UFJ z^+aJ%8^@_EyMsex(9p#%V$HiaG6qAHLJdb&2bbz=HQ);rpti>_?C7BO&u6>%k3U|M zs1%3m6g~~Zmre+d#O_|c5Q(Rh-B4S-BYum)D-P%m!45YQPsjC8r%g?@zXT$U{MsMS zcJaJFb~z(XQdA53y5W8?;=&Nu%PQqW$TS%_1TJ$ySSRHnsgN+|3MtX4uGsEk%ah!8 zzUB$HF6*`Yy_a6HAUax*>b5TS>OM$5A7z*qVHM@>(6f8q38NCMl(RA!1s;}~obF@r zik1H8O+kVOYO;}|jcXdxv@OrXxgg|b*p@XQ9XI>n{(g8U0OL|{qdQ(s#C%N$@la{q zgaqvMFjmQAf6R%raeJjYq_i*zg*HEDgAn0}jxgMKd6pm7!9;l=JK5|5q1d!ZKGeYr zTFbQ4&D-STKp(u>OrZ&WXr#77e>F0}8&&oELa9}~qeQfm!XAW{7S0dE_u7C3B2M@< zwM(?|3+=I$T@5j0!M#C7ER-$t0cU&?jcH_H6k2*2D8i(p9f~A84NJmqH#{9@-88SK zL5gR13LbUG!4&lB=%N}IZ(Nyz#ld(m$%gvKe)v2HiAhi?RY4yF1;J0ljz5Z$u*C-r zk@z$a??+&%C+>_yg@7kPwvk>gERPpj)lBM&n-#2+$6pcM4!Szy+a4Zqg|gK%diZA> z7r+i zAr=KskSoByfmf3g8Yo5esXE4Ynh>1l08y}(bQ%=>Ehp>knyv3pPqF*D8+b=2k6q%{ zZhqZJy}|yi7cK=em6BF#Z3nx1IJJ)Z9S|;jq6;2wp-e|>FEYdt6RP;16WZ$-DHCtK z3B<{bT%(3oDMZ@RUj`QGETLo4>&?727{RTSGSb@4_kHa%`)mNBo7pA0jF8c0i}&n^*M4tSRlT0!yQ3bEHtGT zvYe5smM%vG1mFdC6f48!ii!~1B8JIDCMh!pv-Eikv(Z?du6x`N77h`mBvy8~!6zK! zB>jY8q}1wgjPZi526e7@BN)D}m@lq~tK|)kX!iHRX-9k@>a`b^1tHWKQQA2;8oF~o zZ1iq(!4-js^1%PJcpxbo2eaL=XmmuiwkyJhB-$r^Ydr1~>N5?uX-^erkK8>L@^LAw zr&h{?@wm$g*U5hi9E`zY7aWVkgYE`PksrHUjyPA`E#QfpMfN^$F3E~M(IHT|2YOAeReUKk&UT&>@uJ*vUVo1u@5rm&T%(mUC18pF# zbc3FeM-Nl{ZBHUc_cTXr_Ocq{H~meyejpf6=xy(fc6kH*F-b5<4-`7$eGlV928(AR zE~_J!ckvY$1od#P6J`oae)-&cmoprj*x-Wg7uo58tXliuk|xh;AKSod9Z+1$N?^Z$ zpDvg#keWNbtK~FLOmF4KzIdRXA@T;)@_HBSZskxvT-nBDKG@vDrGB`&jVZo({qo-O zLwVjrpzWqK@oMb`gUodIL;&vT=6^nz?|@CJ02cOBkTk6t!cpsvnUc%3dkM!w`pASr z>Dm?1R^qJp%uSk!gn#izSPY81t#b4sUkna4LZqy!0ZcINbMBAzlj%wFD zk*XY`yE!LUY7-uYH$0FPg4guE^)*n8w#Q?=(GrSZ-A(<}4E1dg#=DzU{-hXay6fq) z5Qsm0ag&x0{^n!cwwR@4vGywi8 z>I%RgeGHs6JPKdM{W+=+wrEWki}yVd9)qux1xP})HgADQ_lA>zLLNvD z!fYAogKen=odMi&ukxNAc*Dmu))L*dT`(XB@3>-$s=8fFSd6cPI})Wb zv1s0OLP8|&^{^VgzZ{@5%od58A$ULz5P!Qyd52)NKy4w2^})wMxK%sw5JNinN;G%D zCe5>sD3|o?gf2%5htAS3)ESdxgK>dSfkC?4y5es~i)IS}p?mQQ&Unbn8r=NEfOW*J z9(G;YsY>o1&X$lZ1cVRtfpYVM0v)e=VY?&N>XEqPqY$jxeIUtDlAl|RMHwupcGV3|LD^u(GdoA(c@J<}7vDiQ3Dz5({-M|4i}!$UfQ`C?`? zuF_jY3uG@W5f91-|0(9|ZguJ>T;LvvFFo+NHjVN`1tCM(UM=3`lGTUW32NG%;A&FE zM3|PerQM*H{X02DUffRV82Op}ew~yNsHcO|nwiyRlFIOA>R*aLE9XghE#2x&t-i65 zQ(L)Pr6j^yUgW?=rq^+LGw-hD)50BBv+0u6l9ttQS2dkv($Lu0%B=zkHrW|qMms&k zZ@I)BO+4Mm)H<`t`HFC&;>!lZESFSs#YL{xUAvYJwVYbdS&gi3V(}%8ZZ<$lTLa@; zZ1zvC=R|d>hJ+1|)|8mXhWXFW%>(50TfdJL^xr5dj~KGwZ6q;6_;-8|Q=!J0$mNbKQ%4oGmu zTP~RBfFVwp=73IbqiXwj*uTF`8+#X2$UEd>dXP@$y8Fo0cG?}U>)<5!qs{;xIO%{l zU2#ZvXC2XA7Yx>8xcu+$b%v)i{_!wkcBMW_PB7XOVdEs{t{GdyUCv+Ou`S~6nJNsSmvE7ttd$0Ops#FpQp!$S*n78WM z0KBV5?uiS&&~0VBt2tXX>6q;c2QT!|N6!)0y4%`nlspWgJ$KNzhrK<<*?y~os#YxN z;G|woZDvicRojG%sMczmgiLj?w(#aQYBeNcxko!St-R66=L9B|_ggZqb|yN)$?``& z+{?l3#^RQXHNJ;qIvLi@JiTHqNege2v!anRFY(1j zgZ9+6vFaRO?qXGy(VmB2-~(L@tmn(!jHu$24p!FDr=6$Ib9f`47yhV&B zfy-*ma}`|AWet3yjFrQG^`%JB(PG4RVD?uFi}^PHshyxHnK%q!4?*3XV}bl^zzE7E0w>A5!+yqg;2I-p9>J5-ZRDSu=jWui~B~EIP?;3h$q0{YmDZ;?m2mk`K$6c#=tn zxm9>r;j_w(blrW*V9R%(;+~V7c7ow@be}Wp#kVIp>M)op&Ko}(@o|GjpCGcOo4z^j6X&vENni!?q_V{W&nFY-aTcdCt=m0M{Z?;33$ zs;P-a7ggD4Q|fp{JzuQjTBRN9nV{`Ny{%Tfnr%vwLu21X!xyNgs-Tq>O?;?@A@zJ# zZ)tr7^&W2F;!YN}@+QgLE#`E+p^?R~&+;EYdKcYkmwg=_E4!_4y-oLe2Z-%(wWAqg z=jkTvg3m4!=69>)-4(0cako4S&dBkwPvvZR$vkjM8*h0AG<_>CslIqITRd^KI+5MX z2{6DDampS#;AXj`WR8^qRVQ;dtd{@E-Pr8;E_U&8Q9Hcum2PnG#e+Hyd10oT$%qTx zt*w5ZyP4Vg$yKf+kQ=Ub!wl^oJnT?01$fud>=RQ|PwbBWyzES+L)R&Hysd+%BZ^!x z)WvkSm9psySRqy20W*Ez>||Do)xwCmBTPpKcl2o9R6nx*BU#w_*P zdTOrN?P&fDjYXRsP%2cQBN96;d-9xvojv~O8OF1`f}>EX^^4%a=!5njFKJl92XpF1AxVu%Y)byFZpeb1|84$*be9kX0f=YmWP zWe$+tNKx`+8X*UtBM9J@Kx(0Nn9wFQ1eE0Xx54?4+PrS`x>}e%wM4 zLNa@7r6aF(s1s7V__HhelF^=~BbPgxDPoX|d4?A_!J(5URm}jDN&6u0b-*Pcql?vg zcp_}{7?E4Qm(6;Gb!>CMB;Y<58-d?)MX`>H4p{GmT$y-X5Uro+foONcx?}a_PKx(} z@tL>nG2ZsJBUXbrB>v{ok*8Nq5~pB9`5;6?s6T#?PVI$R!VPJHh{O$nI30|Ee#U~9 zslZW!tfz_c+DBDJ+7R(T6y|CgibjV{M-gc7gO+LX2mUEKs6R4eF)PsA0%bu+P(&*f zYa?)bB;Jk26&ea+(X2pOtZ68D!rqD!mWsJa`0=u89G3tBT+4=P6Q^a#WmCn4BrGIMGCAh<|m^hz(o1s z0eG_y9tg70=@Bo}(PF)DgGM18V#Cagr1V^vAO4NOV;%^Kf{QC$WAKT)9YPMNURksm zy{jV-Dy~{6%5`H6GSkayfBXew!M(4KKp?b(?Glc-i{ZjOiAEj(PY1N?IHC8p#O_{d z1}y32u>fdeh6M4o7V2|A{_<5QhiJ9%xDIm(V+ z56$;Pwgn>r8co zUtKhMX9LBcE-&G0&e5}!QRggKcJcye7jc&Q(e_*2+qfMT@M$UH zFeTbb*(0#|4n~|~%yvec;=yg)tMvU|wwCd!eSBFDV;eV#30cG{g~)cY^*Bp+^7B(% zyO-7F^ev)GIVYD|itWh~`d0DXeOy~@`i|tew8Na;z=w`-tRfzV*`z{>5@X#@R6MGI z(@)rKeLjx`{-HA+yh)D!J?S= zR9lVRMqwxA$-KakMSSOi={wUd(Ek84YM6P5doFT&5$|YV<5APd()M#w4QCuTp&>~s zRV~+_;6oRArF4@jZamJ2I^I{om96a5lWOM2XE|0!*0b#B;Jk9?XeudVM+;Y<;l2*5 zOOUiT+%Jk$0DkIVj27%|lsa%S14iy8MEF)If z&O+(+nh?n|P1M%?P#ZOiZB_Gvi>}2wg1N{APZ#RGRz)e!1{P15VKlR2W4W7Puk$fx^88C|1|0Lyj z!C&|(Deuj^S7Un{yS*R{S69L%m#k+&3AMz_@1i$=mn$hHMSp56y1jzei*8XtX*Zwf z)anSChwD^^c!F=WamR6f(#oHuRMzpk!=~{5dVqIpT0h85H5^i6)Q+2rc~uRA4^R=> z{gOM+a@#HrKEq4f>03$HUFH)1bPG!=`PFs?pJD7S`jqkQLM~DF;x=PpDG>UA4z#;0 zPx{0@9y`r3yN!qyu${+_S{bMyE&WPaDX;herk>(c(lN!PD&~aCCTj0vtT@Q0PV%P` zI+n4wlpQDObb$K=582D#D)@AXAxE;Lw925qhpXjw-p1cgal{_;JP%SDx6Ept!%uL? zc0MT{m&!(uS#kEjQ~Y%^cZmd;!j7oYzwE# z@4b$x`6 zal84*3O4Ov<4U&gWzljr3z@Z=f%`dXH8*dk$8vtW!@8Kew)5rXynP41U(SQOdGtT- z6p?tD0f(KJ^7mbQbQz;mm$`zI_wtIRyk{2|uH!c)ynh34-otm-v8%|kt2Z2A^%j1# zhc|BH`%>h0^VY+x*va+MeE0Ez{H6wm0VuTX@dP0GqTFEtN!OWy@-QP@jbnsXSjVAhm>)|c54d_-(kO(z(NaF z4=psL_Ur}R`RL zZXm(L)^Yw$vjluyVtMMjB%p8RaQ%uU)0gn|o$T4o@@;G^VxK}LsxfC9zu(EYU7Vp_ z(LH=aV6;7)aFFls|1ISx)&3sg%u`}d%BpdZ4=XHI%b-Ti(E#3LfnVjbR%u;!nfby$3!28*e>wDS4}cDM3u18-^JFO8ht#0&MjvDI#oDXq3D9No_9I_hZm zSR1oD%#5ui&(bz)VN1|GrI)XCabg#ziqG7^?eh6MAf7hhye$-SCktQ!%vV&>+QV(+ zKfTH;a(Oq0YI^PDcb!~J+sxEEz@?jOJMDISM1rHPkS#nWUw6Aj$(D5U;|@bE3oUqU zE2nqTy^a4~{@-U*=+nT!W?s?E>)IKiTL!RKmL4tfnt0%H&zGi>9c_HD*VZ^m3MrHC zsxMDUx`x?yKJ14a-AaN{rQMP8gR<*~p}z}~!pu%z6ODuZm?30@!b-8YCJ@qdJ3_4N zbxt^1)FB&!tufZ*@`cn2IWwcNB@SYWw)Dlj@z849E6zxsEBcvqd#1fO`yWP8kv8E5+&Bs?_ zZw`f5Kir#-9)-5lEh}))NIaE>W8(}xG<7tJ(yU4Ln^e?~#N>25ILgMB(O2NBG^`ne zZ1>n@$3MyVA{W`R<_^U38D>QMSWx9W z{FI8MTq}8edN7!VH#5;U3!8HBr06u_j;7$sOzcU<@=T=k!^{-Cmxy6$DC&#X#Bq(Y zl9$eYC`++l!KGwe*B6PY7#xK^RGATrpjmq;rL%7J_tAC;+!aCrJBR` z({zjsgHy5*U*$&F9f{K!W{!POEt9eE$-z}|xGNn4)Ttr@l zj?GWidMs{9Hiq_rzYs%l7@m(gDL6U8NX6F-!gmQs8i?2W+B@g{6kI2ID$kF8jUTfcv0TkLGZcKeu*!QLdzg58H1!jXwkbp4>4o$eLkKZfvH2W zT4k~WaX^J8L-6tl>>7kMSK@!d4PAkEMp-Fpa~{@RiJ%e23xYaOu0~V7ftV`BpkV?| zk3#b#{H3I^Kpj0mpDMMWlJ(r`W*$Fngv&#*<}+?JM`OzV%8 zS?I{deVOLa{wNc_rQ?}YGj9(`MQ$pNq+mrRCM98FDjrM54H@vwLa>mz3HV1Q@P2TT zizxxyQ_Q#$mjTayxV0a4#p8hVym$=hgB#=x?u*3|WaIEkByQ^iHHPH&!#k01R?&8Z zePra|y*m_JBe5kM5B9+)ari&QuOi?b4F%iph{8M3_#zU|M;pOrLl|yOFuhVh;AL{H zN1-AL^W~q9u>O&8f|XtVvrimK6W}JwkQ@uK_%adsvG`H6=V-gw=7~$34xdDnW#YSJ zEKIe4Kx8u3CgIUEY)QaS;j)vAAvP)@KFCTIFN(q4 zdfnvPkG5>uC-D|=7#4%qBJGys5M&AEEX8V~EzEmMG`4A17KIH`9(6?uKtcrec%V;| zVxJJrFhd*Oc9b&HypuiMs=ET!O5o!U#-PPm}O; zUdUDoNg|G_sobn+;AbV>!tky_AHJ9kGe3JfTJq)9PCn~l`=Xz4A-Nw-Z2y5AXmT$N6ic9>woxfIF zGJSU?Z)oPr)eP-mSCt*BPMqf)o!n~8e5+oJ37zKn{j|;O%`d1tqKb>Ov9C5;?|^EC zHS>uotCNuMF|LsX=jmI+WvBRXGiRQsyA~0ZyijMH$-H{A8JAac`)P*MS-?~5L;)2S z$&poN49xa2i_V3dVf;m_hWuHNd_f>LQDRZiscZfUB)3ewfz?>Zh zZ#=u7lh1JU7B-)w|1M^o<~KWRofWl}`4{-XPTq8aA8j^li0eAOpoUPfk&l^K_l9zQ zyq?+Wg)xX&2_uU`-eHEYok!6I(j&Ynd!&Xg|Zjavxvn>j3ImY z=1O*H6kWj?T0*Y2V$l9;xI$C*YFkJyS!aZ$BddAfAg|hNZLpQ=twpr5fX5GWV;RwI$SDW;(?H}5OwAN!1bdUUrjU&Z(hM|`xv*(+G&4Y z&2Ng>Zzao0EI8nQkdd3Yrj)H4c}fZWP0SIKZKrLePF^OoC-3C%r#Y#VH%XZ-;+tpq z)BzTrVeLugR57ZIx76|tz4$d8QN~Hl1|NR(k}UxqZ{YTGT&FJbI-@t7xx_cSSt6rL z4`+#6EACAlXY|s&+6K~;2D&PIq2RnDPAI*8nM^Ck^@w)sTI~`hMZPJO9JxTZkF3kV z;b2cxb(vb%(#bDf(9y|%yevel+vpSrbh%@+qV6&m$x5Lv3@0l9JuC~B7iLSI^Tiu7 zh`OOpfn_(yJtZ+{jRST`lGCQw51+soBiA`%h8I@IuP6YQ3rf84q>NG?Sk!Bl_)lH& zSs-3hNswq-ju@+=OgBskzy@ct1%|m=+rn#NafD%lI2++s#{Fx8b>6)u`=7sQaPrVD zjO(rydgJTU*v@1 zwLYj-wlo2^gcwjaQ885&;>g(*gHV;@#9>K{rN)Y+-(7Aexk(vMmFwxG6pb(ySt`vc zTX-}A(%{_>(=xCo9@k{RyDvi0F(L&|reUF`m0aAEj)mE%(CCqi`b=DxhZoXub^u<= z!OA=Y53-ieH-$6Jv*Y@V9E1(QzQK595SrEJIKZ-dPY%YF+4wLYyR%K>8#Wl{2II8> zXw}@OsU#N@`eUa~*V%APL#i03**KAb`MD@p3rq(7>Tmc^5oqtrKuRXQ&%~5u^rqut zKirs!S5o1Yh#|>f2KJ<4MXEJpCW!+akBDR()~K6_6-tKo!SXnqNu|jWyY+M&-ONPJu8dzAP%HRQ5nPT-Hx2EHiCanH= zdK7Z?n;m97q%V!Zl2l9_iHC;RT)B2QZXAoCA$V*omJi3ZqYyC)QDbq-2n-vG{2^!_ zV_limqp@`u&X2_hL-FKr?9IpX1M!re;4o|z_Ew{xBC$j8+yHzy7&qo&%otQ=VTZuT zSyqVocskx1WYso_DiYODmXD-C!i}2 zldi(MgOE8E({k-GKb2>g<(Pa79Ao+1FUR23eEZ$KlZ(!gm^%Q8L-AK0{u*UaU+)n} zQMc3xH1|1 zTXY5cSUUvmrbbwQas5~t)>iZL@N6<>4YEfyE*G=( z8yq3V2c8^dGpt`OCZ=KYP#fe$guXu6KEemm?D4;vfFc!aX+R!^Icky`VvRpPjIlt? z+e2-~ICQXm?wW=nT5Udq@l*=tJP<# zQnHQ8>o5SnMIv1bgh<;g9SML_BF4+|+7JDL41`|jiFL8K(bE=6&xjlnZSKTdBkkt$ zuo3|>36M5SeOvDXXNzWd_LGz4QyhCI!cY+k!=C zXZBLmmv5br<6|OVo~QY`%e`>M3Df0amgE?rHi>bIn+z%Oa zT`^226a64L^u#W!r`$~!tGU1v<5i8SyMGB?e5<5i^A(=LPFs*~~h-&@b*AFKexWf%sbg(E8lRFs~AetbD`=Y(g z{v6V2KV@?}WuCvXhwFUtO)F1$7(-@>7lLH3)!Mv^ZR+-F=OQm0Z{h}=<_F#Ie5HxTlao>suTn<^_juFl73xHwq`O$3$HXm~lI zSpWntI7T7e6;DRONmj8K9CI-avnZ4?5lD4HdL(`YrfA)yl80b?)k`^!uIy!dAU=@# zAXjY{4=cLT#!iXs;;BlE7J^dIvqsJrImS4b6S2W zG-WxzQVgxqlpWbuPBro5afXZOS8eR0Q969qaP&#DeSUS!fM8c1=I#bAEVszjHDz>a z=K50%Y2i(0c(9po2pcO#Um2&jaM%f3IDB}l}HTp+1tzHrLS8v{?1i{*^j$v^+&pDN^C&bXb#GA8ckk~RFFMB7!oqm+v`7#O*16Hk`%6YVZaY#CB` zh$R9Sm-4<1+*M+`g^okaD&%I-#x`@FN@llN8^{~#_C3Obn;CPIYgTjkVfHPwpzh># zTz`;m%dMX2-j)3O0PkNze}$}9uOZs4HJ3|-4t3Yfi)C0jYXz!YAkw)JP94IEa; z+m-k(VAm!N-pArid~65HH&{dNL2WJea>_;%7(r#ugh?@7-nuxhHnB z&v7PgXW>B>ZR4@yJhFwykJ!s{{V{IX$ERc%-p2b5^J5LFhq=CxQx4hK=zfsFdS{k$ zC65fVUJ{rB~5b zHXPxv3auYDNbf(Vn4uj}86Vxlmg6igVtxfTD8Mdp`4HEiVc8L@RtY-5QB}4vlWHv9 z-Hp}UBYt%?x0D$Ov`Fp1)vS@LS(%74R>J#E1@BbMS^D)wE;+Wv(NL}6I9r9)iL%v$AgFX>S?}sfL>*MveXJ? zoR0Cc3g#6V32?l4cW3y1Da*<^vxFy36D9Ofby_LoⓈ0oyshj|L_@pdVuX>Q0w1U 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